changeset 1:43def5d33575

Update to DW 2.2 and PM123 files to 1.33... 1.33 completely changed the plugin system and it is still broken right now.
author Brian Smith <brian@dbsoft.org>
date Thu, 24 Nov 2011 03:45:48 -0600
parents f840ca9a1a98
children e6f7d2d80b81
files decoder_plug.h dw.c dw.h filter_plug.h format.h nuclear.c output_plug.h plugin.h
diffstat 8 files changed, 9951 insertions(+), 7127 deletions(-) [+]
line wrap: on
line diff
--- a/decoder_plug.h	Fri Feb 18 02:50:18 2011 -0600
+++ b/decoder_plug.h	Thu Nov 24 03:45:48 2011 -0600
@@ -1,164 +1,238 @@
-#if __cplusplus
+#ifndef PM123_DECODER_PLUG_H
+#define PM123_DECODER_PLUG_H
+
+#include "format.h"
+
+#ifdef __cplusplus
 extern "C" {
 #endif
 
-#define WM_PLAYSTOP           WM_USER+69
-#define WM_PLAYERROR          WM_USER+100
-#define WM_SEEKSTOP           WM_USER+666
+#pragma pack(4)
 
-
-int  _System decoder_init(void **w);
-BOOL _System decoder_uninit(void *w);
+int  DLLENTRY decoder_init  ( void** w );
+BOOL DLLENTRY decoder_uninit( void*  w );
 
-#define DECODER_PLAY    1 /* returns 101 -> already playing
-                                     102 -> error, decoder killed */
-#define DECODER_STOP    2 /* returns 101 -> already stopped
-                                     102 -> error, decoder killed (and stopped) */
-#define DECODER_FFWD    3
-#define DECODER_REW     4
-#define DECODER_JUMPTO  5
-#define DECODER_SETUP   6
-#define DECODER_EQ      7
-#define DECODER_BUFFER  8
+/* return value:                                               */
+/* PLUGIN_OK          -> ok.                                   */
+/* PLUGIN_UNSUPPORTED -> command unsupported.                  */
+/*                                                             */
+/* DECODER_PLAY can return also:                               */
+/* PLUGIN_GO_ALREADY  -> already playing.                      */
+/* PLUGIN_GO_ERROR    -> error, decoder killed and restarted.  */
+/*                                                             */
+/* DECODER_STOP can return also:                               */
+/* PLUGIN_GO_ALREADY  -> already stopped.                      */
+/* PLUGIN_GO_ERROR    -> error, decoder killed and stopped.    */
 
-typedef struct {
+#define DECODER_PLAY      1
+#define DECODER_STOP      2
+#define DECODER_FFWD      3
+#define DECODER_REW       4
+#define DECODER_JUMPTO    5
+#define DECODER_SETUP     6
+#define DECODER_EQ        7 /* obsolete, don't used anymore */
+#define DECODER_BUFFER    8 /* obsolete, don't used anymore */
+#define DECODER_SAVEDATA  9
+
+typedef struct _DECODER_PARAMS
+{
    int size;
 
    /* --- DECODER_PLAY, STOP */
 
-   char *filename;
-   char *URL;
-   char *drive; /* for CD ie.: "X:" */
-   int  track;
-   int sectors[2];  /* play from sector x to sector y */
-   char *other;
+   char* filename;
+   void* unused1;     /* obsolete, must be NULL */
+   char* drive;       /* for CD ie.: "X:" */
+   int   track;
+   int   sectors[2];  /* play from sector x to sector y */
+   void* unused2;     /* obsolete, must be NULL */
 
    /* --- DECODER_REW, FFWD and JUMPTO */
 
-   int jumpto;     /* absolute positioning in milliseconds */
-   int ffwd;       /* 1 = start ffwd, 0 = end ffwd */
-   int rew;        /* 1 = start rew, 0 = end rew */
+   int   jumpto;      /* absolute positioning in milliseconds */
+   int   ffwd;        /* 1 = start ffwd, 0 = end ffwd */
+   int   rew;         /* 1 = start rew,  0 = end rew  */
 
    /* --- DECODER_SETUP */
 
    /* specify a function which the decoder should use for output */
-   int (* _System output_play_samples)(void *a, FORMAT_INFO *format, char *buf, int len, int posmarker);
-   void *a; /* only to be used with the precedent function */
-   int audio_buffersize;
+   int  (DLLENTRYP output_play_samples)( void* a, FORMAT_INFO* format, char* buf, int len, int posmarker );
+   void* a;           /* only to be used with the precedent function */
+   int   audio_buffersize;
 
-   char *proxyurl; /* NULL = none */
-   char *httpauth; /* NULL = none */
+   char* proxyurl;    /* NULL = none */
+   char* httpauth;    /* NULL = none */
 
    /* error message function the decoder should use */
-   void (* _System error_display)(char *);
+   void (DLLENTRYP error_display)( char* );
 
-   HEV playsem;  /* this semaphore is reseted when DECODER_PLAY is requested
-                    and is posted on stop */
+   /* info message function the decoder should use */
+   /* this information is always displayed to the user right away */
+   void (DLLENTRYP info_display)( char* );
 
-   HWND hwnd; // commodity for PM interface, decoder must send a few messages to this handle
+   void* unused3;     /* obsolete, must be NULL */
+   HWND  hwnd;        /* commodity for PM interface, decoder must send a few
+                         messages to this handle */
 
    /* values used for streaming inputs by the decoder */
-   int buffersize; /* read ahead buffer in bytes, 0 = disabled */
-   int bufferwait; /* block the first read until the buffer is filled */
+   int   buffersize;  /* read ahead buffer in bytes, 0 = disabled */
+   int   bufferwait;  /* block the first read until the buffer is filled */
 
-   /* -- DECODER_BUFFER */
+   char* metadata_buffer; /* the decoder will put streaming metadata in this  */
+   int   metadata_size;   /* buffer before posting WM_METADATA */
 
-   int bufferstatus; /* reports how many bytes there are available in the buffer */
-
-   /* --- DECODER_EQ */
+   int   unused4;     /* obsolete, must be 0 */
+   int   unused5;     /* obsolete, must be 0 */
+   int   unused6;     /* obsolete, must be 0 */
 
-   /* usually only useful with MP3 decoder */
-   int equalizer;    /* TRUE or FALSE */
-   float *bandgain;  /* point to an array like this bandgain[#channels][10] */
+   /* --- DECODER_SAVEDATA */
+
+   char*  save_filename;
 
 } DECODER_PARAMS;
 
-/* returns 0 -> ok
-           1 -> command unsupported
-           1xx -> msg specific */
-ULONG _System decoder_command(void *w, ULONG msg, DECODER_PARAMS *params);
+ULONG DLLENTRY decoder_command( void* w, ULONG msg, DECODER_PARAMS* params );
 
 #define DECODER_STOPPED  0
 #define DECODER_PLAYING  1
 #define DECODER_STARTING 2
-ULONG _System decoder_status(void *w);
+#define DECODER_PAUSED   3
+#define DECODER_ERROR    200
+
+ULONG DLLENTRY decoder_status( void* w );
 
 /* WARNING!! this _can_ change in time!!! returns stream length in ms */
 /* the decoder should keep in memory a last valid length so the call  */
 /* remains valid even if decoder_status() == DECODER_STOPPED          */
-ULONG _System decoder_length(void *w);
+ULONG DLLENTRY decoder_length( void* w );
+
+#define DECODER_MODE_STEREO         0
+#define DECODER_MODE_JOINT_STEREO   1
+#define DECODER_MODE_DUAL_CHANNEL   2
+#define DECODER_MODE_SINGLE_CHANNEL 3
+
+#define modes(i) ( i == 0 ? "Stereo"         : \
+                 ( i == 1 ? "Joint-Stereo"   : \
+                 ( i == 2 ? "Dual-Channel"   : \
+                 ( i == 3 ? "Single-Channel" : "" ))))
 
-static char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" };
+/* See haveinfo field of the DECODER_INFO structure. */
+#define DECODER_HAVE_TITLE      0x0001
+#define DECODER_HAVE_ARTIST     0x0002
+#define DECODER_HAVE_ALBUM      0x0004
+#define DECODER_HAVE_YEAR       0x0008
+#define DECODER_HAVE_COMMENT    0x0010
+#define DECODER_HAVE_GENRE      0x0020
+#define DECODER_HAVE_TRACK      0x0040
+#define DECODER_HAVE_COPYRIGHT  0x0080
+#define DECODER_HAVE_TRACK_GAIN 0x0100
+#define DECODER_HAVE_TRACK_PEAK 0x0200
+#define DECODER_HAVE_ALBUM_GAIN 0x0400
+#define DECODER_HAVE_ALBUM_PEAK 0x0800
+
+#define INFO_SIZE_1  976  /* size of the DECODER_INFO structure prior PM123 1.32 */
+#define INFO_SIZE_2 1264  /* size of the DECODER_INFO structure since PM123 1.32 */
 
 /* NOTE: the information returned is only based on the FIRST header */
-typedef struct {
-   int size;
+typedef struct _DECODER_INFO
+{
+   int   size;            /* see INFO_SIZE definitions */
 
-   FORMAT_INFO format; /* stream format after decoding */
+   FORMAT_INFO format;    /* stream format after decoding */
 
-   int songlength; /* in milliseconds, smaller than 0 -> unknown */
-   int junklength; /* bytes of junk before stream start, if < 0 -> unknown */
+   int   songlength;      /* in milliseconds, smaller than 0 -> unknown */
+   int   junklength;      /* bytes of junk before stream start, if < 0 -> unknown */
 
    /* mpeg stuff */
-   int mpeg; /* 25 = MPEG 2.5, 10 = MPEG 1.0, 20 = MPEG 2.0, 0 = not an MPEG */
-   int layer; /* 0 = unknown */
-   int mode; /* use it on modes[4] */
-   int modext; /* didn't check what this one does */
-   int bpf; /* bytes in the mpeg frame including header */
-   int bitrate; /* in kbit/s */
-   int extention; /* didn't check what this one does */
+   int   mpeg;            /* 25 = MPEG 2.5, 10 = MPEG 1.0, 20 = MPEG 2.0, 0 = not an MPEG */
+   int   layer;           /* 0 = unknown */
+   int   mode;            /* use it on modes(i) */
+   int   modext;          /* didn't check what this one does */
+   int   bpf;             /* bytes in the mpeg frame including header */
+   int   bitrate;         /* in kbit/s */
+   int   extention;       /* didn't check what this one does */
 
    /* track stuff */
-   int startsector;
-   int endsector;
+   int   startsector;
+   int   endsector;
 
-   /* module stuff */
-   int numchannels;  /* 0 = not a MODule */
-   int numpatterns;
-   int numpositions;
+   /* obsolete stuff */
+   int   unused1;         /* obsolete, must be 0 */
+   int   unused2;         /* obsolete, must be 0 */
+   int   unused3;         /* obsolete, must be 0 */
 
    /* general technical information string */
-   char tech_info[128];
+   char  tech_info[128];
+
+   /* meta information */
+   char  title    [128];
+   char  artist   [128];
+   char  album    [128];
+   char  year     [128];
+   char  comment  [128];
+   char  genre    [128];
 
-   /* song information */
-   char title[80];
-   char artist[80];
-   char album[80];
-   char year[80];
-   char comment[80];
-   char genre[80];
+   /* added since PM123 1.32 */
+   char  track    [128];
+   char  copyright[128];
+   int   codepage;        /* Code page of the meta info. Must be 0 if the
+                             code page is unknown. Don't place here any another
+                             value if it is not provided by meta info. */
+   int   haveinfo;        /* This flags define what of fields of the block of the
+                             meta information are supported by the decoder. Can
+                             be 0 if the decoder supports all fields. */
+   int   saveinfo;        /* Must be 1 if the decoder can update meta info of
+                             this file. Otherwise, must be 0. */
+   int   filesize;        /* Size of the file. */
+
+   float track_gain;      /* Defines Replay Gain values as specified at */
+   float track_peak;      /* http://www.replaygain.org/ */
+   float album_gain;
+   float album_peak;
 
 } DECODER_INFO;
 
 /* returns
-      0 = everything's perfect, structure is set
-      100 = error reading file (too small?)
-      200 = decoder can't play that
-      1001 = http error occured, check http_strerror() for string;
-      other values = errno */
-ULONG _System decoder_fileinfo(char *filename, DECODER_INFO *info);
-ULONG _System decoder_trackinfo(char *drive, int track, DECODER_INFO *info);
+      PLUGIN_OK      = everything's perfect, structure is set,
+      PLUGIN_NO_READ = error reading file (too small?),
+      PLUGIN_NO_PLAY = decoder can't play that,
+      other values   = errno, check xio_strerror() for string. */
+ULONG DLLENTRY decoder_fileinfo( char* filename, DECODER_INFO* info );
+ULONG DLLENTRY decoder_trackinfo( char* drive, int track, DECODER_INFO* info );
 
-typedef struct
+/* returns
+      PLUGIN_OK      = everything's perfect, structure is saved to filename,
+      other values   = errno, check xio_strerror() for string. */
+ULONG DLLENTRY decoder_saveinfo( char* filename, DECODER_INFO* info );
+
+typedef struct _DECODER_CDINFO
 {
    int sectors;
    int firsttrack;
    int lasttrack;
+
 } DECODER_CDINFO;
 
-ULONG _System decoder_cdinfo(char *drive, DECODER_CDINFO *info);
-
+/* returns
+      PLUGIN_OK      = everything's perfect, structure is set,
+      PLUGIN_NO_READ = error reading required info,
+      other values   = errno, check xio_strerror() for string. */
+ULONG DLLENTRY decoder_cdinfo( const char* drive, DECODER_CDINFO* info );
 
 /* returns ORed values */
-#define DECODER_FILENAME  0x1
-#define DECODER_URL       0x2
-#define DECODER_TRACK     0x4
-#define DECODER_OTHER     0x8
+#define DECODER_FILENAME  0x0001 /* Decoder can play a regular file. */
+#define DECODER_URL       0x0002 /* Decoder can play a internet stream or file. */
+#define DECODER_TRACK     0x0004 /* Decoder can play a CD track. */
+#define DECODER_OTHER     0x0008 /* Decoder can play something. */
+#define DECODER_METAINFO  0x8000 /* Decoder can save a meta info. */
 /* size is i/o and is the size of the array.
    each ext should not be bigger than 8bytes */
-ULONG _System decoder_support(char *fileext[], int *size);
+ULONG DLLENTRY decoder_support( char* fileext[], int* size );
 
+#pragma pack()
 
-#if __cplusplus
+#ifdef __cplusplus
 }
 #endif
+#endif /* PM123_DECODER_PLUG_H */
+
--- a/dw.c	Fri Feb 18 02:50:18 2011 -0600
+++ b/dw.c	Thu Nov 24 03:45:48 2011 -0600
@@ -1,10 +1,9 @@
-/*
 /*
  * Dynamic Windows:
  *          A GTK like implementation of the PM GUI
  *
- * (C) 2000-2004 Brian Smith <dbsoft@technologist.com>
- * (C) 2003-2004 Mark Hessling <m.hessling@qut.edu.au>
+ * (C) 2000-2011 Brian Smith <brian@dbsoft.org>
+ * (C) 2003-2008 Mark Hessling <m.hessling@qut.edu.au>
  * (C) 2000 Achim Hasenmueller <achimha@innotek.de>
  * (C) 2000 Peter Nielsen <peter@pmview.com>
  * (C) 1998 Sergey I. Yevtushenko (some code borrowed from cell toolkit)
@@ -14,6 +13,10 @@
 #define INCL_DOSERRORS
 #define INCL_WIN
 #define INCL_GPI
+#define INCL_DEV
+#define INCL_SPL
+#define INCL_SPLDOSPRINT
+#define INCL_SPLERRORS
 
 #include <os2.h>
 #include <stdlib.h>
@@ -25,10 +28,15 @@
 #include <process.h>
 #include <time.h>
 #include <io.h>
+#include <math.h>
 #ifndef __EMX__
 #include <direct.h>
 #endif
 #include <sys/time.h>
+#include <sys/stat.h>
+#ifdef __WATCOMC__
+#include <alloca.h>
+#endif
 #include "dw.h"
 
 #define QWP_USER 0
@@ -38,15 +46,18 @@
 
 MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
 MRESULT EXPENTRY _wndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
+MRESULT EXPENTRY _scrollwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
 void _do_resize(Box *thisbox, int x, int y);
 void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y);
 int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height);
 void _dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname);
 void _dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname);
 void _free_menu_data(HWND menu);
+ULONG (* _System _PmPrintfString)(char *String) = 0;
 
 char ClassName[] = "dynamicwindows";
 char SplitbarClassName[] = "dwsplitbar";
+char ScrollClassName[] = "dwscroll";
 char *DefaultFont = "9.WarpSans";
 
 HAB dwhab = 0;
@@ -55,28 +66,30 @@
 LONG _foreground = 0xAAAAAA, _background = DW_CLR_DEFAULT;
 
 HWND hwndApp = NULLHANDLE, hwndBubble = NULLHANDLE, hwndBubbleLast = NULLHANDLE, hwndEmph = NULLHANDLE;
+HWND hwndTrayServer = NULLHANDLE, hwndTaskBar = NULLHANDLE;
+;
 PRECORDCORE pCoreEmph = NULL;
-ULONG aulBuffer[4], GlobalID = 10000;
+ULONG aulBuffer[4];
 HWND lasthcnr = 0, lastitem = 0, popup = 0, desktop;
-HMOD wpconfig = 0;
+HMOD wpconfig = 0, pmprintf = 0;
 
 unsigned long _colors[] = {
-	CLR_BLACK,
-	CLR_DARKRED,
-	CLR_DARKGREEN,
-	CLR_BROWN,
-	CLR_DARKBLUE,
-	CLR_DARKPINK,
-	CLR_DARKCYAN,
-	CLR_PALEGRAY,
-	CLR_DARKGRAY,
-	CLR_RED,
-	CLR_GREEN,
-	CLR_YELLOW,
-	CLR_BLUE,
-	CLR_PINK,
-	CLR_CYAN,
-	CLR_WHITE
+   CLR_BLACK,
+   CLR_DARKRED,
+   CLR_DARKGREEN,
+   CLR_BROWN,
+   CLR_DARKBLUE,
+   CLR_DARKPINK,
+   CLR_DARKCYAN,
+   CLR_PALEGRAY,
+   CLR_DARKGRAY,
+   CLR_RED,
+   CLR_GREEN,
+   CLR_YELLOW,
+   CLR_BLUE,
+   CLR_PINK,
+   CLR_CYAN,
+   CLR_WHITE
 };
 
 #define IS_WARP4() (aulBuffer[0] == 20 && aulBuffer[1] >= 40)
@@ -87,12 +100,12 @@
 
 typedef struct _sighandler
 {
-	struct _sighandler	*next;
-	ULONG message;
-	HWND window;
-	int id;
-	void *signalfunction;
-	void *data;
+   struct _sighandler   *next;
+   ULONG message;
+   HWND window;
+   int id;
+   void *signalfunction;
+   void *data;
 
 } SignalHandler;
 
@@ -100,8 +113,8 @@
 
 typedef struct
 {
-	ULONG message;
-	char name[30];
+   ULONG message;
+   char name[30];
 
 } SignalList;
 
@@ -109,131 +122,144 @@
 #define SIGNALMAX 16
 
 SignalList SignalTranslate[SIGNALMAX] = {
-	{ WM_SIZE,         DW_SIGNAL_CONFIGURE },
-	{ WM_CHAR,         DW_SIGNAL_KEY_PRESS },
-	{ WM_BUTTON1DOWN,  DW_SIGNAL_BUTTON_PRESS },
-	{ WM_BUTTON1UP,    DW_SIGNAL_BUTTON_RELEASE },
-	{ WM_MOUSEMOVE,    DW_SIGNAL_MOTION_NOTIFY },
-	{ WM_CLOSE,        DW_SIGNAL_DELETE },
-	{ WM_PAINT,        DW_SIGNAL_EXPOSE },
-	{ WM_COMMAND,      DW_SIGNAL_CLICKED },
-	{ CN_ENTER,        DW_SIGNAL_ITEM_ENTER },
-	{ CN_CONTEXTMENU,  DW_SIGNAL_ITEM_CONTEXT },
-	{ LN_SELECT,       DW_SIGNAL_LIST_SELECT },
-	{ CN_EMPHASIS,     DW_SIGNAL_ITEM_SELECT },
-	{ WM_SETFOCUS,     DW_SIGNAL_SET_FOCUS },
-	{ SLN_SLIDERTRACK, DW_SIGNAL_VALUE_CHANGED },
-	{ BKN_PAGESELECTED,DW_SIGNAL_SWITCH_PAGE },
-	{ CN_EXPANDTREE,   DW_SIGNAL_TREE_EXPAND }
+   { WM_SIZE,         DW_SIGNAL_CONFIGURE },
+   { WM_CHAR,         DW_SIGNAL_KEY_PRESS },
+   { WM_BUTTON1DOWN,  DW_SIGNAL_BUTTON_PRESS },
+   { WM_BUTTON1UP,    DW_SIGNAL_BUTTON_RELEASE },
+   { WM_MOUSEMOVE,    DW_SIGNAL_MOTION_NOTIFY },
+   { WM_CLOSE,        DW_SIGNAL_DELETE },
+   { WM_PAINT,        DW_SIGNAL_EXPOSE },
+   { WM_COMMAND,      DW_SIGNAL_CLICKED },
+   { CN_ENTER,        DW_SIGNAL_ITEM_ENTER },
+   { CN_CONTEXTMENU,  DW_SIGNAL_ITEM_CONTEXT },
+   { LN_SELECT,       DW_SIGNAL_LIST_SELECT },
+   { CN_EMPHASIS,     DW_SIGNAL_ITEM_SELECT },
+   { WM_SETFOCUS,     DW_SIGNAL_SET_FOCUS },
+   { SLN_SLIDERTRACK, DW_SIGNAL_VALUE_CHANGED },
+   { BKN_PAGESELECTED,DW_SIGNAL_SWITCH_PAGE },
+   { CN_EXPANDTREE,   DW_SIGNAL_TREE_EXPAND }
 };
 
+/* Internal function to keep a semi-unique ID within valid range */
+USHORT _GlobalID(void)
+{
+    static USHORT GlobalID = 9999;
+
+    GlobalID++;
+    if(GlobalID >= 65534)
+    {
+        GlobalID = 10000;
+    }
+    return GlobalID;
+}
+
 /* This function adds a signal handler callback into the linked list.
  */
 void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data)
 {
-	SignalHandler *new = malloc(sizeof(SignalHandler));
-
-	new->message = message;
-	new->window = window;
-	new->id = id;
-	new->signalfunction = signalfunction;
-	new->data = data;
-	new->next = NULL;
-
-	if (!Root)
-		Root = new;
-	else
-	{
-		SignalHandler *prev = NULL, *tmp = Root;
-		while(tmp)
-		{
-			if(tmp->message == message &&
-			   tmp->window == window &&
-			   tmp->id == id &&
-			   tmp->signalfunction == signalfunction)
-			{
-				tmp->data = data;
-				free(new);
-				return;
-			}
-			prev = tmp;
-			tmp = tmp->next;
-		}
-		if(prev)
-			prev->next = new;
-		else
-			Root = new;
-	}
+   SignalHandler *new = malloc(sizeof(SignalHandler));
+
+   new->message = message;
+   new->window = window;
+   new->id = id;
+   new->signalfunction = signalfunction;
+   new->data = data;
+   new->next = NULL;
+
+   if (!Root)
+      Root = new;
+   else
+   {
+      SignalHandler *prev = NULL, *tmp = Root;
+      while(tmp)
+      {
+         if(tmp->message == message &&
+            tmp->window == window &&
+            tmp->id == id &&
+            tmp->signalfunction == signalfunction)
+         {
+            tmp->data = data;
+            free(new);
+            return;
+         }
+         prev = tmp;
+         tmp = tmp->next;
+      }
+      if(prev)
+         prev->next = new;
+      else
+         Root = new;
+   }
 }
 
 /* Finds the message number for a given signal name */
 ULONG _findsigmessage(char *signame)
 {
-	int z;
-
-	for(z=0;z<SIGNALMAX;z++)
-	{
-		if(stricmp(signame, SignalTranslate[z].name) == 0)
-			return SignalTranslate[z].message;
-	}
-	return 0L;
+   int z;
+
+   for(z=0;z<SIGNALMAX;z++)
+   {
+      if(stricmp(signame, SignalTranslate[z].name) == 0)
+         return SignalTranslate[z].message;
+   }
+   return 0L;
 }
 
 typedef struct _CNRITEM
 {
-	MINIRECORDCORE rc;
-	HPOINTER       hptrIcon;
-	PVOID          user;
-	HTREEITEM      parent;
+   MINIRECORDCORE rc;
+   HPOINTER       hptrIcon;
+   PVOID          user;
+   HTREEITEM      parent;
 
 } CNRITEM, *PCNRITEM;
 
 
 int _null_key(HWND window, int key, void *data)
 {
-	window = window; /* keep compiler happy */
-	key = key; /* keep compiler happy */
-	data = data; /* keep compiler happy */
-	return TRUE;
+   window = window; /* keep compiler happy */
+   key = key; /* keep compiler happy */
+   data = data; /* keep compiler happy */
+   return TRUE;
 }
 
 /* Find the desktop window handle */
 HWND _toplevel_window(HWND handle)
 {
-	HWND box, lastbox = WinQueryWindow(handle, QW_PARENT);
-
-	/* Find the toplevel window */
-	while((box = WinQueryWindow(lastbox, QW_PARENT)) != desktop && box > 0)
-	{
-		lastbox = box;
-	}
-	if(box > 0)
-		return lastbox;
-	return handle;
+   HWND box, lastbox = WinQueryWindow(handle, QW_PARENT);
+
+   /* Find the toplevel window */
+   while((box = WinQueryWindow(lastbox, QW_PARENT)) != desktop && box > 0)
+   {
+      lastbox = box;
+   }
+   if(box > 0)
+      return lastbox;
+   return handle;
 }
 
 
 /* Returns height of specified window. */
 int _get_height(HWND handle)
 {
-	unsigned long height;
-	dw_window_get_pos_size(handle, NULL, NULL, NULL, &height);
-	return (int)height;
+   unsigned long height;
+   dw_window_get_pos_size(handle, NULL, NULL, NULL, &height);
+   return (int)height;
 }
 
 /* Find the height of the frame a desktop style window is sitting on */
 int _get_frame_height(HWND handle)
 {
-	while(handle)
-	{
-		HWND client;
-		if((client = WinWindowFromID(handle, FID_CLIENT)) != NULLHANDLE)
-		{
+   while(handle)
+   {
+      HWND client;
+      if((client = WinWindowFromID(handle, FID_CLIENT)) != NULLHANDLE)
+      {
             return _get_height(WinQueryWindow(handle, QW_PARENT));
-		}
+      }
         handle = WinQueryWindow(handle, QW_PARENT);
-	}
-	return dw_screen_height();
+   }
+   return dw_screen_height();
 }
 
 /* A "safe" WinSendMsg() that tries multiple times in case the
@@ -241,46 +267,46 @@
  */
 MRESULT _dw_send_msg(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2, int failure)
 {
-	MRESULT res;
-	int z = 0;
-
-	while((int)(res = WinSendMsg(hwnd, msg, mp1, mp2)) == failure)
-	{
-		z++;
-		if(z > 5000000)
-			return (MRESULT)failure;
-		dw_main_sleep(1);
-	}
-	return res;
+   MRESULT res;
+   int z = 0;
+
+   while((int)(res = WinSendMsg(hwnd, msg, mp1, mp2)) == failure)
+   {
+      z++;
+      if(z > 5000000)
+         return (MRESULT)failure;
+      dw_main_sleep(1);
+   }
+   return res;
 }
 
 /* Used in the slider and percent classes internally */
 unsigned int _dw_percent_get_range(HWND handle)
 {
-	return SHORT2FROMMP(WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0));
+   return SHORT2FROMMP(WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0));
 }
 
 /* Return the entryfield child of a window */
 HWND _find_entryfield(HWND handle)
 {
-	HENUM henum;
-	HWND child, entry = 0;
-
-	henum = WinBeginEnumWindows(handle);
-	while((child = WinGetNextWindow(henum)) != NULLHANDLE)
-	{
-		char tmpbuf[100];
-
-		WinQueryClassName(child, 99, tmpbuf);
-
-		if(strncmp(tmpbuf, "#6", 3)==0)  /* Entryfield */
-		{
-			entry = child;
-			break;
-		}
-	}
-	WinEndEnumWindows(henum);
-	return entry;
+   HENUM henum;
+   HWND child, entry = 0;
+
+   henum = WinBeginEnumWindows(handle);
+   while((child = WinGetNextWindow(henum)) != NULLHANDLE)
+   {
+      char tmpbuf[100];
+
+      WinQueryClassName(child, 99, (PCH)tmpbuf);
+
+      if(strncmp(tmpbuf, "#6", 3)==0)  /* Entryfield */
+      {
+         entry = child;
+         break;
+      }
+   }
+   WinEndEnumWindows(henum);
+   return entry;
 }
 
 /* This function changes the owner of buttons in to the
@@ -288,58 +314,58 @@
  */
 void _fix_button_owner(HWND handle, HWND dw)
 {
-	HENUM henum;
-	HWND child;
-
-	henum = WinBeginEnumWindows(handle);
-	while((child = WinGetNextWindow(henum)) != NULLHANDLE)
-	{
-		char tmpbuf[100];
-
-		WinQueryClassName(child, 99, tmpbuf);
-
-		if(strncmp(tmpbuf, "#3", 3)==0 && dw)  /* Button */
-			WinSetOwner(child, dw);
-		else if(strncmp(tmpbuf, "dynamicwindows", 14) == 0)
-			dw = child;
-
-		_fix_button_owner(child, dw);
-	}
-	WinEndEnumWindows(henum);
-	return;
+   HENUM henum;
+   HWND child;
+
+   henum = WinBeginEnumWindows(handle);
+   while((child = WinGetNextWindow(henum)) != NULLHANDLE)
+   {
+      char tmpbuf[100];
+
+      WinQueryClassName(child, 99, (PCH)tmpbuf);
+
+      if(strncmp(tmpbuf, "#3", 3)==0 && dw)  /* Button */
+         WinSetOwner(child, dw);
+      else if(strncmp(tmpbuf, "dynamicwindows", 14) == 0)
+         dw = child;
+
+      _fix_button_owner(child, dw);
+   }
+   WinEndEnumWindows(henum);
+   return;
 }
 
 /* Free bitmap data associated with a window */
 void _free_bitmap(HWND handle)
 {
-	HBITMAP hbm = (HBITMAP)dw_window_get_data(handle, "_dw_bitmap");
-	HPS hps = (HPS)dw_window_get_data(handle, "_dw_hps");
-	HDC hdc = (HDC)dw_window_get_data(handle, "_dw_hdc");
-	HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap");
-	HPIXMAP disable = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap_disabled");
-	HPOINTER icon = (HPOINTER)dw_window_get_data(handle, "_dw_button_icon");
-
-	if(icon)
-		WinDestroyPointer(icon);
-
-	if(pixmap)
-		dw_pixmap_destroy(pixmap);
-
-	if(disable)
-		dw_pixmap_destroy(disable);
-
-	if(hps)
-	{
-		GpiSetBitmap(hps, NULLHANDLE);
-		GpiAssociate(hps, NULLHANDLE);
-		GpiDestroyPS(hps);
-	}
-
-	if(hdc)
-		DevCloseDC(hdc);
-
-	if(hbm)
-		GpiDeleteBitmap(hbm);
+   HBITMAP hbm = (HBITMAP)dw_window_get_data(handle, "_dw_bitmap");
+   HPS hps = (HPS)dw_window_get_data(handle, "_dw_hps");
+   HDC hdc = (HDC)dw_window_get_data(handle, "_dw_hdc");
+   HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap");
+   HPIXMAP disable = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap_disabled");
+   HPOINTER icon = (HPOINTER)dw_window_get_data(handle, "_dw_button_icon");
+
+   if(icon)
+      WinDestroyPointer(icon);
+
+   if(pixmap)
+      dw_pixmap_destroy(pixmap);
+
+   if(disable)
+      dw_pixmap_destroy(disable);
+
+   if(hps)
+   {
+      GpiSetBitmap(hps, NULLHANDLE);
+      GpiAssociate(hps, NULLHANDLE);
+      GpiDestroyPS(hps);
+   }
+
+   if(hdc)
+      DevCloseDC(hdc);
+
+   if(hbm)
+      GpiDeleteBitmap(hbm);
 }
 
 /* This function removes any handlers on windows and frees
@@ -347,100 +373,116 @@
  */
 void _free_window_memory(HWND handle)
 {
-	HENUM henum;
-	HWND child;
-	void *ptr = (void *)WinQueryWindowPtr(handle, QWP_USER);
-
-	dw_signal_disconnect_by_window(handle);
-
-	if((child = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE)
-		_free_menu_data(child);
-
-	if((child = WinWindowFromID(handle, FID_CLIENT)) != NULLHANDLE)
-	{
-		Box *box = (Box *)WinQueryWindowPtr(child, QWP_USER);
-
-		if(box)
-		{
-			if(box->count && box->items)
-				free(box->items);
-
-			WinSetWindowPtr(child, QWP_USER, 0);
-			free(box);
-		}
-	}
-
-	if(ptr)
-	{
-		WindowData *wd = (WindowData *)ptr;
-		char tmpbuf[100];
-
-		WinQueryClassName(handle, 99, tmpbuf);
-
-		if(strncmp(tmpbuf, "ColorSelectClass", 17)!=0)
-		{
-			/* If this window has an associate bitmap destroy it. */
-			_free_bitmap(handle);
-
-			if(strncmp(tmpbuf, "#1", 3)==0 && !WinWindowFromID(handle, FID_CLIENT))
-			{
-				Box *box = (Box *)ptr;
-
-				if(box->count && box->items)
-					free(box->items);
-			}
-			else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
-			{
-				void *data = dw_window_get_data(handle, "_dw_percent");
-
-				if(data)
-					free(data);
-			}
-			else if(strncmp(tmpbuf, "#37", 4)==0)
-			{
-				dw_container_clear(handle, FALSE);
-				if(wd && dw_window_get_data(handle, "_dw_container"))
-				{
-					void *oldflags = wd->data;
-
-					wd->data = NULL;
-					free(oldflags);
-				}
-			}
-
-			if(wd->oldproc)
-				WinSubclassWindow(handle, wd->oldproc);
-
-			dw_window_set_data(handle, NULL, NULL);
-			WinSetWindowPtr(handle, QWP_USER, 0);
-			free(ptr);
-		}
-	}
-
-	henum = WinBeginEnumWindows(handle);
-	while((child = WinGetNextWindow(henum)) != NULLHANDLE)
-		_free_window_memory(child);
-
-	WinEndEnumWindows(henum);
-	return;
+   HENUM henum;
+   HWND child;
+   void *ptr = (void *)WinQueryWindowPtr(handle, QWP_USER);
+
+   dw_signal_disconnect_by_window(handle);
+
+   if((child = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE)
+      _free_menu_data(child);
+
+   if((child = WinWindowFromID(handle, FID_CLIENT)) != NULLHANDLE)
+   {
+      Box *box = (Box *)WinQueryWindowPtr(child, QWP_USER);
+
+      if(box && !dw_window_get_data(handle, "_dw_box"))
+      {
+         if(box->count && box->items)
+            free(box->items);
+
+         WinSetWindowPtr(child, QWP_USER, 0);
+         free(box);
+      }
+   }
+
+   if(ptr)
+   {
+      WindowData *wd = (WindowData *)ptr;
+      char tmpbuf[100];
+
+      WinQueryClassName(handle, 99, (PCH)tmpbuf);
+
+      if(strncmp(tmpbuf, "ColorSelectClass", 17)!=0)
+      {
+         /* If this window has an associate bitmap destroy it. */
+         _free_bitmap(handle);
+
+         if(strncmp(tmpbuf, "#1", 3)==0 && !WinWindowFromID(handle, FID_CLIENT))
+         {
+            Box *box = (Box *)ptr;
+
+            if(box->count && box->items)
+               free(box->items);
+         }
+         else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
+         {
+            void *data = dw_window_get_data(handle, "_dw_percent");
+
+            if(data)
+               free(data);
+         }
+         else if(strncmp(tmpbuf, "#37", 4)==0)
+         {
+            dw_container_clear(handle, FALSE);
+            if(wd && dw_window_get_data(handle, "_dw_container"))
+            {
+               void *oldflags = wd->data;
+
+               wd->data = NULL;
+               free(oldflags);
+            }
+         }
+
+         if(wd->oldproc)
+            WinSubclassWindow(handle, wd->oldproc);
+
+         dw_window_set_data(handle, NULL, NULL);
+         WinSetWindowPtr(handle, QWP_USER, 0);
+         free(ptr);
+      }
+   }
+
+   henum = WinBeginEnumWindows(handle);
+   while((child = WinGetNextWindow(henum)) != NULLHANDLE)
+      _free_window_memory(child);
+
+   WinEndEnumWindows(henum);
+   return;
 }
 
 void _free_menu_data(HWND menu)
 {
-	int i, count = (int)WinSendMsg(menu, MM_QUERYITEMCOUNT, 0, 0);
-
-	dw_signal_disconnect_by_name(menu, DW_SIGNAL_CLICKED);
-	_free_window_memory(menu);
-
-	for(i=0;i<count;i++)
-	{
-		SHORT menuid = (SHORT)WinSendMsg(menu, MM_ITEMIDFROMPOSITION, MPFROMSHORT(i), 0);
-		MENUITEM mi;
-
-		if(WinSendMsg(menu, MM_QUERYITEM, MPFROMSHORT(menuid), MPFROMP(&mi))
-		   && mi.hwndSubMenu)
-			_free_menu_data(mi.hwndSubMenu);
-	}
+   int i, count = (int)WinSendMsg(menu, MM_QUERYITEMCOUNT, 0, 0);
+
+   dw_signal_disconnect_by_name(menu, DW_SIGNAL_CLICKED);
+   _free_window_memory(menu);
+
+   for(i=0;i<count;i++)
+   {
+      SHORT menuid = (SHORT)(LONG)WinSendMsg(menu, MM_ITEMIDFROMPOSITION, MPFROMSHORT(i), 0);
+      MENUITEM mi;
+
+      /* Free the data associated with the ID */
+      if(menuid >= 30000)
+      {
+         char buffer[31] = {0};
+       
+         sprintf(buffer, "_dw_id%d", menuid);
+         dw_window_set_data( hwndApp, buffer, NULL );
+         sprintf(buffer, "_dw_checkable%d", menuid);
+         dw_window_set_data( hwndApp, buffer, NULL );
+         sprintf(buffer, "_dw_ischecked%d", menuid);
+         dw_window_set_data( hwndApp, buffer, NULL );
+         sprintf(buffer, "_dw_isdisabled%d", menuid);
+         dw_window_set_data( hwndApp, buffer, NULL );
+      }
+      
+      /* Check any submenus */
+      if(WinSendMsg(menu, MM_QUERYITEM, MPFROMSHORT(menuid), MPFROMP(&mi))
+         && mi.hwndSubMenu)
+         _free_menu_data(mi.hwndSubMenu);
+   }
 }
 
 /* This function returns 1 if the window (widget) handle
@@ -448,274 +490,300 @@
  */
 int _validate_focus(HWND handle)
 {
-	char tmpbuf[100];
-
-	if(!handle)
-		return 0;
-
-	WinQueryClassName(handle, 99, tmpbuf);
-
-	if(!WinIsWindowEnabled(handle) ||
-	   (strncmp(tmpbuf, "ColorSelectClass", 17) && dw_window_get_data(handle, "_dw_disabled")))
-		return 0;
-
-	/* These are the window classes which can
-	 * obtain input focus.
-	 */
-	if(strncmp(tmpbuf, "#2", 3)==0 ||  /* Combobox */
-	   strncmp(tmpbuf, "#3", 3)==0 ||  /* Button */
-	   strncmp(tmpbuf, "#6", 3)==0 ||  /* Entryfield */
-	   strncmp(tmpbuf, "#7", 3)==0 ||  /* List box */
-	   strncmp(tmpbuf, "#10", 4)==0 || /* MLE */
-	   strncmp(tmpbuf, "#32", 4)==0 || /* Spinbutton */
-	   strncmp(tmpbuf, "#37", 4)==0 || /* Container */
-	   strncmp(tmpbuf, "#38", 4)== 0)  /* Slider */
-		return 1;
-	return 0;
+   char tmpbuf[100];
+
+   if(!handle)
+      return 0;
+
+   WinQueryClassName(handle, 99, (PCH)tmpbuf);
+
+   if(!WinIsWindowEnabled(handle) ||
+      (strncmp(tmpbuf, "ColorSelectClass", 17) && dw_window_get_data(handle, "_dw_disabled")))
+      return 0;
+
+   /* These are the window classes which can
+    * obtain input focus.
+    */
+   if(strncmp(tmpbuf, "#2", 3)==0 ||  /* Combobox */
+      strncmp(tmpbuf, "#3", 3)==0 ||  /* Button */
+      strncmp(tmpbuf, "#6", 3)==0 ||  /* Entryfield */
+      strncmp(tmpbuf, "#7", 3)==0 ||  /* List box */
+      strncmp(tmpbuf, "#10", 4)==0 || /* MLE */
+      strncmp(tmpbuf, "#32", 4)==0 || /* Spinbutton */
+      strncmp(tmpbuf, "#37", 4)==0 || /* Container */
+      strncmp(tmpbuf, "#38", 4)== 0)  /* Slider */
+      return 1;
+   return 0;
 }
 
 int _focus_check_box(Box *box, HWND handle, int start, HWND defaultitem)
 {
-	int z;
-	static HWND lasthwnd, firsthwnd;
-    static int finish_searching;
-
-	/* Start is 2 when we have cycled completely and
-	 * need to set the focus to the last widget we found
-	 * that was valid.
-	 */
-	if(start == 2)
-	{
-		if(lasthwnd)
-			WinSetFocus(HWND_DESKTOP, lasthwnd);
-		return 0;
-	}
-
-	/* Start is 1 when we are entering the function
-	 * for the first time, it is zero when entering
-	 * the function recursively.
-	 */
-	if(start == 1)
-	{
-		lasthwnd = handle;
-		finish_searching = 0;
-		firsthwnd = 0;
-	}
-
-	for(z=box->count-1;z>-1;z--)
-	{
-		if(box->items[z].type == TYPEBOX)
-		{
-			Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER);
-
-			if(thisbox && _focus_check_box(thisbox, handle, start == 3 ? 3 : 0, defaultitem))
-				return 1;
-		}
-		else
-		{
-			if(box->items[z].hwnd == handle)
-			{
-				if(lasthwnd == handle && firsthwnd)
-					WinSetFocus(HWND_DESKTOP, firsthwnd);
-				else if(lasthwnd == handle && !firsthwnd)
-					finish_searching = 1;
-				else
-					WinSetFocus(HWND_DESKTOP, lasthwnd);
-
-				/* If we aren't looking for the last handle,
-				 * return immediately.
-				 */
-				if(!finish_searching)
-					return 1;
-			}
-			if(_validate_focus(box->items[z].hwnd))
-			{
-				/* Start is 3 when we are looking for the
-				 * first valid item in the layout.
-				 */
-				if(start == 3)
-				{
-					if(!defaultitem || (defaultitem && defaultitem == box->items[z].hwnd))
-					{
-						WinSetFocus(HWND_DESKTOP, box->items[z].hwnd);
-						return 1;
-					}
-				}
-
-				if(!firsthwnd)
-					firsthwnd = box->items[z].hwnd;
-
-				lasthwnd = box->items[z].hwnd;
-			}
-			else
-			{
-				char tmpbuf[100] = "";
-
-				WinQueryClassName(box->items[z].hwnd, 99, tmpbuf);
-				if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
-				{
-					/* Then try the bottom or right box */
-					HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_bottomright");
-
-					if(mybox)
-					{
-						Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
-
-						if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
-							return 1;
-					}
-
-					/* Try the top or left box */
-					mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_topleft");
-
-					if(mybox)
-					{
-						Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
-
-						if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
-							return 1;
-					}
-				}
-				else if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */
-				{
-					Box *notebox;
-					HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND,
-												 (MPARAM)dw_notebook_page_get(box->items[z].hwnd), 0);
-
-					if(page)
-					{
-						notebox = (Box *)WinQueryWindowPtr(page, QWP_USER);
-
-						if(notebox && _focus_check_box(notebox, handle, start == 3 ? 3 : 0, defaultitem))
-							return 1;
-					}
-				}
-			}
-		}
-	}
-	return 0;
+   int z;
+   static HWND lasthwnd, firsthwnd;
+   static int finish_searching;
+
+   /* Start is 2 when we have cycled completely and
+    * need to set the focus to the last widget we found
+    * that was valid.
+    */
+   if(start == 2)
+   {
+      if(lasthwnd)
+         WinSetFocus(HWND_DESKTOP, lasthwnd);
+      return 0;
+   }
+
+   /* Start is 1 when we are entering the function
+    * for the first time, it is zero when entering
+    * the function recursively.
+    */
+   if(start == 1)
+   {
+      lasthwnd = handle;
+      finish_searching = 0;
+      firsthwnd = 0;
+   }
+
+   for(z=box->count-1;z>-1;z--)
+   {
+      if(box->items[z].type == TYPEBOX)
+      {
+         Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER);
+
+         if(thisbox && _focus_check_box(thisbox, handle, start == 3 ? 3 : 0, defaultitem))
+            return 1;
+      }
+      else
+      {
+         if(box->items[z].hwnd == handle)
+         {
+            if(lasthwnd == handle && firsthwnd)
+               WinSetFocus(HWND_DESKTOP, firsthwnd);
+            else if(lasthwnd == handle && !firsthwnd)
+               finish_searching = 1;
+            else
+               WinSetFocus(HWND_DESKTOP, lasthwnd);
+
+            /* If we aren't looking for the last handle,
+             * return immediately.
+             */
+            if(!finish_searching)
+               return 1;
+         }
+         if(_validate_focus(box->items[z].hwnd))
+         {
+            /* Start is 3 when we are looking for the
+             * first valid item in the layout.
+             */
+            if(start == 3)
+            {
+               if(!defaultitem || (defaultitem && defaultitem == box->items[z].hwnd))
+               {
+                  WinSetFocus(HWND_DESKTOP, box->items[z].hwnd);
+                  return 1;
+               }
+            }
+
+            if(!firsthwnd)
+               firsthwnd = box->items[z].hwnd;
+
+            lasthwnd = box->items[z].hwnd;
+         }
+         else
+         {
+            char tmpbuf[100] = "";
+
+            WinQueryClassName(box->items[z].hwnd, 99, (PCH)tmpbuf);
+            if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
+            {
+               /* Then try the bottom or right box */
+               HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_bottomright");
+
+               if(mybox)
+               {
+                  Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
+
+                  if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
+                     return 1;
+               }
+
+               /* Try the top or left box */
+               mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_topleft");
+
+               if(mybox)
+               {
+                  Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
+
+                  if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
+                     return 1;
+               }
+            }
+            else if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */
+            {
+               Box *notebox;
+               HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND,
+                                     (MPARAM)dw_notebook_page_get(box->items[z].hwnd), 0);
+
+               if(page)
+               {
+                  notebox = (Box *)WinQueryWindowPtr(page, QWP_USER);
+
+                  if(notebox && _focus_check_box(notebox, handle, start == 3 ? 3 : 0, defaultitem))
+                     return 1;
+               }
+            }
+            else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0) /* Scrollbox */
+            {
+                /* Get the box window handle */
+                HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_box");
+
+                if(mybox)
+                {
+                    Box *scrollbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
+
+                    if(scrollbox && _focus_check_box(scrollbox, handle, start == 3 ? 3 : 0, defaultitem))
+                        return 1;
+                }
+            }
+         }
+      }
+   }
+   return 0;
 }
 
 int _focus_check_box_back(Box *box, HWND handle, int start, HWND defaultitem)
 {
-	int z;
-	static HWND lasthwnd, firsthwnd;
+   int z;
+   static HWND lasthwnd, firsthwnd;
     static int finish_searching;
 
-	/* Start is 2 when we have cycled completely and
-	 * need to set the focus to the last widget we found
-	 * that was valid.
-	 */
-	if(start == 2)
-	{
-		if(lasthwnd)
-			WinSetFocus(HWND_DESKTOP, lasthwnd);
-		return 0;
-	}
-
-	/* Start is 1 when we are entering the function
-	 * for the first time, it is zero when entering
-	 * the function recursively.
-	 */
-	if(start == 1)
-	{
-		lasthwnd = handle;
-		finish_searching = 0;
-		firsthwnd = 0;
-	}
-
-	for(z=0;z<box->count;z++)
-	{
-		if(box->items[z].type == TYPEBOX)
-		{
-			Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER);
-
-			if(thisbox && _focus_check_box_back(thisbox, handle, start == 3 ? 3 : 0, defaultitem))
-				return 1;
-		}
-		else
-		{
-			if(box->items[z].hwnd == handle)
-			{
-				if(lasthwnd == handle && firsthwnd)
-					WinSetFocus(HWND_DESKTOP, firsthwnd);
-				else if(lasthwnd == handle && !firsthwnd)
-					finish_searching = 1;
-				else
-					WinSetFocus(HWND_DESKTOP, lasthwnd);
-
-				/* If we aren't looking for the last handle,
-				 * return immediately.
-				 */
-				if(!finish_searching)
-					return 1;
-			}
-			if(_validate_focus(box->items[z].hwnd))
-			{
-				/* Start is 3 when we are looking for the
-				 * first valid item in the layout.
-				 */
-				if(start == 3)
-				{
-					if(!defaultitem || (defaultitem && defaultitem == box->items[z].hwnd))
-					{
-						WinSetFocus(HWND_DESKTOP, box->items[z].hwnd);
-						return 1;
-					}
-				}
-
-				if(!firsthwnd)
-					firsthwnd = box->items[z].hwnd;
-
-				lasthwnd = box->items[z].hwnd;
-			}
-			else
-			{
-				char tmpbuf[100] = "";
-
-				WinQueryClassName(box->items[z].hwnd, 99, tmpbuf);
-				if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
-				{
-					/* Try the top or left box */
-					HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_topleft");
-
-					if(mybox)
-					{
-						Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
-
-						if(splitbox && _focus_check_box_back(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
-							return 1;
-					}
-
-					/* Then try the bottom or right box */
-					mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_bottomright");
-
-					if(mybox)
-					{
-						Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
-
-						if(splitbox && _focus_check_box_back(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
-							return 1;
-					}
-				}
-				else if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */
-				{
-					Box *notebox;
-					HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND,
-												 (MPARAM)dw_notebook_page_get(box->items[z].hwnd), 0);
-
-					if(page)
-					{
-						notebox = (Box *)WinQueryWindowPtr(page, QWP_USER);
-
-						if(notebox && _focus_check_box_back(notebox, handle, start == 3 ? 3 : 0, defaultitem))
-							return 1;
-					}
-				}
-			}
-		}
-	}
-	return 0;
+   /* Start is 2 when we have cycled completely and
+    * need to set the focus to the last widget we found
+    * that was valid.
+    */
+   if(start == 2)
+   {
+      if(lasthwnd)
+         WinSetFocus(HWND_DESKTOP, lasthwnd);
+      return 0;
+   }
+
+   /* Start is 1 when we are entering the function
+    * for the first time, it is zero when entering
+    * the function recursively.
+    */
+   if(start == 1)
+   {
+      lasthwnd = handle;
+      finish_searching = 0;
+      firsthwnd = 0;
+   }
+
+   for(z=0;z<box->count;z++)
+   {
+      if(box->items[z].type == TYPEBOX)
+      {
+         Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER);
+
+         if(thisbox && _focus_check_box_back(thisbox, handle, start == 3 ? 3 : 0, defaultitem))
+            return 1;
+      }
+      else
+      {
+         if(box->items[z].hwnd == handle)
+         {
+            if(lasthwnd == handle && firsthwnd)
+               WinSetFocus(HWND_DESKTOP, firsthwnd);
+            else if(lasthwnd == handle && !firsthwnd)
+               finish_searching = 1;
+            else
+               WinSetFocus(HWND_DESKTOP, lasthwnd);
+
+            /* If we aren't looking for the last handle,
+             * return immediately.
+             */
+            if(!finish_searching)
+               return 1;
+         }
+         if(_validate_focus(box->items[z].hwnd))
+         {
+            /* Start is 3 when we are looking for the
+             * first valid item in the layout.
+             */
+            if(start == 3)
+            {
+               if(!defaultitem || (defaultitem && defaultitem == box->items[z].hwnd))
+               {
+                  WinSetFocus(HWND_DESKTOP, box->items[z].hwnd);
+                  return 1;
+               }
+            }
+
+            if(!firsthwnd)
+               firsthwnd = box->items[z].hwnd;
+
+            lasthwnd = box->items[z].hwnd;
+         }
+         else
+         {
+            char tmpbuf[100] = "";
+
+            WinQueryClassName(box->items[z].hwnd, 99, (PCH)tmpbuf);
+            if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
+            {
+               /* Try the top or left box */
+               HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_topleft");
+
+               if(mybox)
+               {
+                  Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
+
+                  if(splitbox && _focus_check_box_back(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
+                     return 1;
+               }
+
+               /* Then try the bottom or right box */
+               mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_bottomright");
+
+               if(mybox)
+               {
+                  Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
+
+                  if(splitbox && _focus_check_box_back(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
+                     return 1;
+               }
+            }
+            else if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */
+            {
+               Box *notebox;
+               HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND,
+                                     (MPARAM)dw_notebook_page_get(box->items[z].hwnd), 0);
+
+               if(page)
+               {
+                  notebox = (Box *)WinQueryWindowPtr(page, QWP_USER);
+
+                  if(notebox && _focus_check_box_back(notebox, handle, start == 3 ? 3 : 0, defaultitem))
+                     return 1;
+               }
+            }
+            else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0) /* Scrollbox */
+            {
+                /* Get the box window handle */
+                HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_box");
+
+                if(mybox)
+                {
+                    Box *scrollbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
+
+                    if(scrollbox && _focus_check_box_back(scrollbox, handle, start == 3 ? 3 : 0, defaultitem))
+                        return 1;
+                }
+            }
+         }
+      }
+   }
+   return 0;
 }
 
 /* This function finds the first widget in the
@@ -723,18 +791,18 @@
  */
 int _initial_focus(HWND handle)
 {
-	Box *thisbox = NULL;
-	HWND box;
-
-	box = WinWindowFromID(handle, FID_CLIENT);
-	if(box)
-		thisbox = WinQueryWindowPtr(box, QWP_USER);
-	else
-		return 1;
-
-	if(thisbox)
-		_focus_check_box(thisbox, handle, 3, thisbox->defaultitem);
-	return 0;
+   Box *thisbox = NULL;
+   HWND box;
+
+   box = WinWindowFromID(handle, FID_CLIENT);
+   if(box)
+      thisbox = WinQueryWindowPtr(box, QWP_USER);
+   else
+      return 1;
+
+   if(thisbox)
+      _focus_check_box(thisbox, handle, 3, thisbox->defaultitem);
+   return 0;
 }
 
 /* This function finds the current widget in the
@@ -742,20 +810,20 @@
  */
 void _shift_focus(HWND handle)
 {
-	Box *thisbox;
-	HWND box, lastbox = _toplevel_window(handle);
-
-	box = WinWindowFromID(lastbox, FID_CLIENT);
-	if(box)
-		thisbox = WinQueryWindowPtr(box, QWP_USER);
-	else
-		thisbox = WinQueryWindowPtr(lastbox, QWP_USER);
-
-	if(thisbox)
-	{
-		if(_focus_check_box(thisbox, handle, 1, 0)  == 0)
-			_focus_check_box(thisbox, handle, 2, 0);
-	}
+   Box *thisbox;
+   HWND box, lastbox = _toplevel_window(handle);
+
+   box = WinWindowFromID(lastbox, FID_CLIENT);
+   if(box)
+      thisbox = WinQueryWindowPtr(box, QWP_USER);
+   else
+      thisbox = WinQueryWindowPtr(lastbox, QWP_USER);
+
+   if(thisbox)
+   {
+      if(_focus_check_box(thisbox, handle, 1, 0)  == 0)
+         _focus_check_box(thisbox, handle, 2, 0);
+   }
 }
 
 /* This function finds the current widget in the
@@ -763,80 +831,80 @@
  */
 void _shift_focus_back(HWND handle)
 {
-	Box *thisbox;
-	HWND box, lastbox = _toplevel_window(handle);
-
-	box = WinWindowFromID(lastbox, FID_CLIENT);
-	if(box)
-		thisbox = WinQueryWindowPtr(box, QWP_USER);
-	else
-		thisbox = WinQueryWindowPtr(lastbox, QWP_USER);
-
-	if(thisbox)
-	{
-		if(_focus_check_box_back(thisbox, handle, 1, 0)  == 0)
-			_focus_check_box_back(thisbox, handle, 2, 0);
-	}
+   Box *thisbox;
+   HWND box, lastbox = _toplevel_window(handle);
+
+   box = WinWindowFromID(lastbox, FID_CLIENT);
+   if(box)
+      thisbox = WinQueryWindowPtr(box, QWP_USER);
+   else
+      thisbox = WinQueryWindowPtr(lastbox, QWP_USER);
+
+   if(thisbox)
+   {
+      if(_focus_check_box_back(thisbox, handle, 1, 0)  == 0)
+         _focus_check_box_back(thisbox, handle, 2, 0);
+   }
 }
 
 /* This function will recursively search a box and add up the total height of it */
 void _count_size(HWND box, int type, int *xsize, int *xorigsize)
 {
-	int size = 0, origsize = 0, z;
-	Box *tmp = WinQueryWindowPtr(box, QWP_USER);
-
-	if(!tmp)
-	{
-		*xsize = *xorigsize = 0;
-		return;
-	}
-
-	if(type == tmp->type)
-	{
-		/* If the box is going in the direction we want, then we
-		 * return the entire sum of the items.
-		 */
-		for(z=0;z<tmp->count;z++)
-		{
-			if(tmp->items[z].type == TYPEBOX)
-			{
-				int s, os;
-
-				_count_size(tmp->items[z].hwnd, type, &s, &os);
-				size += s;
-				origsize += os;
-			}
-			else
-			{
-				size += (type == DW_HORZ ? tmp->items[z].width : tmp->items[z].height);
-				origsize += (type == DW_HORZ ? tmp->items[z].origwidth : tmp->items[z].origheight);
-			}
-		}
-	}
-	else
-	{
-		/* If the box is not going in the direction we want, then we only
-		 * want to return the maximum value.
-		 */
-		int tmpsize = 0, tmporigsize = 0;
-
-		for(z=0;z<tmp->count;z++)
-		{
-			if(tmp->items[z].type == TYPEBOX)
-				_count_size(tmp->items[z].hwnd, type, &tmpsize, &tmporigsize);
-			else
-			{
-				tmpsize = (type == DW_HORZ ? tmp->items[z].width : tmp->items[z].height);
-				tmporigsize = (type == DW_HORZ ? tmp->items[z].origwidth : tmp->items[z].origheight);
-			}
-
-			if(tmpsize > size)
-				size = tmpsize;
-		}
-	}
-
-	*xsize = size;
-	*xorigsize = origsize;
+   int size = 0, origsize = 0, z;
+   Box *tmp = WinQueryWindowPtr(box, QWP_USER);
+
+   if(!tmp)
+   {
+      *xsize = *xorigsize = 0;
+      return;
+   }
+
+   if(type == tmp->type)
+   {
+      /* If the box is going in the direction we want, then we
+       * return the entire sum of the items.
+       */
+      for(z=0;z<tmp->count;z++)
+      {
+         if(tmp->items[z].type == TYPEBOX)
+         {
+            int s, os;
+
+            _count_size(tmp->items[z].hwnd, type, &s, &os);
+            size += s;
+            origsize += os;
+         }
+         else
+         {
+            size += (type == DW_HORZ ? tmp->items[z].width : tmp->items[z].height);
+            origsize += (type == DW_HORZ ? tmp->items[z].origwidth : tmp->items[z].origheight);
+         }
+      }
+   }
+   else
+   {
+      /* If the box is not going in the direction we want, then we only
+       * want to return the maximum value.
+       */
+      int tmpsize = 0, tmporigsize = 0;
+
+      for(z=0;z<tmp->count;z++)
+      {
+         if(tmp->items[z].type == TYPEBOX)
+            _count_size(tmp->items[z].hwnd, type, &tmpsize, &tmporigsize);
+         else
+         {
+            tmpsize = (type == DW_HORZ ? tmp->items[z].width : tmp->items[z].height);
+            tmporigsize = (type == DW_HORZ ? tmp->items[z].origwidth : tmp->items[z].origheight);
+         }
+
+         if(tmpsize > size)
+            size = tmpsize;
+      }
+   }
+
+   *xsize = size;
+   *xorigsize = origsize;
 }
 
 
@@ -850,1032 +918,1454 @@
 
 BOOL _TrackRectangle(HWND hwndBase, RECTL* rclTrack, RECTL* rclBounds)
 {
-	TRACKINFO track;
-	APIRET rc;
-
-	track.cxBorder = 1;
-	track.cyBorder = 1;
-	track.cxGrid   = 1;
-	track.cyGrid   = 1;
-	track.cxKeyboard = 8;
-	track.cyKeyboard = 8;
-
-	if(!rclTrack)
-		return FALSE;
-
-	if(rclBounds)
-	{
-		track.rclBoundary = *rclBounds;
-	}
-	else
-	{
-		track.rclBoundary.yTop    =
-			track.rclBoundary.xRight  = 3000;
-		track.rclBoundary.yBottom =
-			track.rclBoundary.xLeft   = -3000;
-	}
-
-	track.rclTrack = *rclTrack;
-
-	WinMapWindowPoints(hwndBase,
-					   HWND_DESKTOP,
-					   (PPOINTL)&track.rclTrack,
-					   2);
-
-	track.ptlMinTrackSize.x = track.rclTrack.xRight
-		- track.rclTrack.xLeft;
-	track.ptlMinTrackSize.y = track.rclTrack.yTop
-		- track.rclTrack.yBottom;
-	track.ptlMaxTrackSize.x = track.rclTrack.xRight
-		- track.rclTrack.xLeft;
-	track.ptlMaxTrackSize.y = track.rclTrack.yTop
-		- track.rclTrack.yBottom;
-
-	track.fs = TF_MOVE | TF_ALLINBOUNDARY;
-
-	rc = WinTrackRect(HWND_DESKTOP, 0, &track);
-
-	if(rc)
-		*rclTrack = track.rclTrack;
-
-	return rc;
+   TRACKINFO track;
+   APIRET rc;
+
+   track.cxBorder = 1;
+   track.cyBorder = 1;
+   track.cxGrid   = 1;
+   track.cyGrid   = 1;
+   track.cxKeyboard = 8;
+   track.cyKeyboard = 8;
+
+   if(!rclTrack)
+      return FALSE;
+
+   if(rclBounds)
+   {
+      track.rclBoundary = *rclBounds;
+   }
+   else
+   {
+      track.rclBoundary.yTop    =
+         track.rclBoundary.xRight  = 3000;
+      track.rclBoundary.yBottom =
+         track.rclBoundary.xLeft   = -3000;
+   }
+
+   track.rclTrack = *rclTrack;
+
+   WinMapWindowPoints(hwndBase,
+                  HWND_DESKTOP,
+                  (PPOINTL)&track.rclTrack,
+                  2);
+
+   track.ptlMinTrackSize.x = track.rclTrack.xRight
+      - track.rclTrack.xLeft;
+   track.ptlMinTrackSize.y = track.rclTrack.yTop
+      - track.rclTrack.yBottom;
+   track.ptlMaxTrackSize.x = track.rclTrack.xRight
+      - track.rclTrack.xLeft;
+   track.ptlMaxTrackSize.y = track.rclTrack.yTop
+      - track.rclTrack.yBottom;
+
+   track.fs = TF_MOVE | TF_ALLINBOUNDARY;
+
+   rc = WinTrackRect(HWND_DESKTOP, 0, &track);
+
+   if(rc)
+      *rclTrack = track.rclTrack;
+
+   return rc;
 }
 
 void _check_resize_notebook(HWND hwnd)
 {
-	char tmpbuf[100];
-
-	WinQueryClassName(hwnd, 99, tmpbuf);
-
-	/* If we have a notebook we resize the page again. */
-	if(strncmp(tmpbuf, "#40", 4)==0)
-	{
-		unsigned long x, y, width, height;
-		ULONG page = (ULONG)WinSendMsg(hwnd, BKM_QUERYPAGEID, 0, MPFROM2SHORT(BKA_FIRST, BKA_MAJOR));
-
-		while(page)
-		{
-			HWND pagehwnd = (HWND)WinSendMsg(hwnd, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(page), 0);
-			RECTL rc;
-
-			Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER);
-			if(pagebox)
-			{
-				dw_window_get_pos_size(hwnd, &x, &y, &width, &height);
-
-				rc.xLeft = x;
-				rc.yBottom = y;
-				rc.xRight = x + width;
-				rc.yTop = y + height;
-
-				WinSendMsg(hwnd, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE);
-
-				_do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom);
-			}
-			page = (ULONG)WinSendMsg(hwnd, BKM_QUERYPAGEID, (MPARAM)page, MPFROM2SHORT(BKA_NEXT, BKA_MAJOR));
-		}
-
-	}
+   char tmpbuf[100];
+
+   WinQueryClassName(hwnd, 99, (PCH)tmpbuf);
+
+   /* If we have a notebook we resize the page again. */
+   if(strncmp(tmpbuf, "#40", 4)==0)
+   {
+      long x, y;
+      unsigned long width, height;
+      ULONG page = (ULONG)WinSendMsg(hwnd, BKM_QUERYPAGEID, 0, MPFROM2SHORT(BKA_FIRST, BKA_MAJOR));
+
+      while(page)
+      {
+         HWND pagehwnd = (HWND)WinSendMsg(hwnd, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(page), 0);
+         RECTL rc;
+
+         Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER);
+         if(pagebox)
+         {
+            dw_window_get_pos_size(hwnd, &x, &y, &width, &height);
+
+            rc.xLeft = x;
+            rc.yBottom = y;
+            rc.xRight = x + width;
+            rc.yTop = y + height;
+
+            WinSendMsg(hwnd, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE);
+
+            _do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom);
+         }
+         page = (ULONG)WinSendMsg(hwnd, BKM_QUERYPAGEID, (MPARAM)page, MPFROM2SHORT(BKA_NEXT, BKA_MAJOR));
+      }
+
+   }
 }
 
 /* Return the OS/2 color from the DW color */
 unsigned long _internal_color(unsigned long color)
 {
-	if(color < 16)
-		return _colors[color];
-	return color;
+   if(color < 16)
+      return _colors[color];
+   return color;
 }
 
 unsigned long _os2_color(unsigned long color)
 {
-	return DW_RED_VALUE(color) << 16 | DW_GREEN_VALUE(color) << 8 | DW_BLUE_VALUE(color);
+   return DW_RED_VALUE(color) << 16 | DW_GREEN_VALUE(color) << 8 | DW_BLUE_VALUE(color);
 }
 
 BOOL _MySetWindowPos(HWND hwnd, HWND parent, HWND behind, LONG x, LONG y, LONG cx, LONG cy, ULONG fl)
 {
-	int height = _get_height(parent);
-
-	return WinSetWindowPos(hwnd, behind, x, height - y - cy, cx, cy, fl);
-}
+   int height = _get_height(parent);
+
+   return WinSetWindowPos(hwnd, behind, x, height - y - cy, cx, cy, fl);
+}
+
+#define _DW_DEFAULT_SCROLLBAR_WIDTH 16
 
 /* This function calculates how much space the widgets and boxes require
  * and does expansion as necessary.
  */
 int _resize_box(Box *thisbox, int *depth, int x, int y, int *usedx, int *usedy,
-				int pass, int *usedpadx, int *usedpady)
-{
-	int z, currentx = 0, currenty = 0;
-	int uymax = 0, uxmax = 0;
-	int upymax = 0, upxmax = 0;
-	/* Used for the SIZEEXPAND */
-	int nux = *usedx, nuy = *usedy;
-	int nupx = *usedpadx, nupy = *usedpady;
-
-	(*usedx) += (thisbox->pad * 2);
-	(*usedy) += (thisbox->pad * 2);
-
-	if(thisbox->grouphwnd)
-	{
-		char *text = dw_window_get_text(thisbox->grouphwnd);
-
-		thisbox->grouppady = 0;
-
-		if(text)
-		{
-			dw_font_text_extents_get(thisbox->grouphwnd, 0, text, NULL, &thisbox->grouppady);
-			dw_free(text);
-		}
-
-		if(thisbox->grouppady)
-			thisbox->grouppady += 3;
-		else
-			thisbox->grouppady = 6;
-
-		thisbox->grouppadx = 6;
-
-		(*usedx) += thisbox->grouppadx;
-		(*usedpadx) += thisbox->grouppadx;
-		(*usedy) += thisbox->grouppady;
-		(*usedpady) += thisbox->grouppady;
-	}
-
-	for(z=0;z<thisbox->count;z++)
-	{
-		if(thisbox->items[z].type == TYPEBOX)
-		{
-			int initialx, initialy;
-			Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
-
-			initialx = x - (*usedx);
-			initialy = y - (*usedy);
-
-			if(tmp)
-			{
-				int newx, newy;
-				int nux = *usedx, nuy = *usedy;
-				int upx = *usedpadx + (tmp->pad*2), upy = *usedpady + (tmp->pad*2);
-
-				/* On the second pass we know how big the box needs to be and how
-				 * much space we have, so we can calculate a ratio for the new box.
-				 */
-				if(pass == 2)
-				{
-					int deep = *depth + 1;
-
-					_resize_box(tmp, &deep, x, y, &nux, &nuy, 1, &upx, &upy);
-
-					tmp->upx = upx - *usedpadx;
-					tmp->upy = upy - *usedpady;
-
-					newx = x - nux;
-					newy = y - nuy;
-
-					tmp->width = thisbox->items[z].width = initialx - newx;
-					tmp->height = thisbox->items[z].height = initialy - newy;
-
-					tmp->parentxratio = thisbox->xratio;
-					tmp->parentyratio = thisbox->yratio;
-
-					tmp->parentpad = tmp->pad;
-
-					/* Just in case */
-					tmp->xratio = thisbox->xratio;
-					tmp->yratio = thisbox->yratio;
-
-					if(thisbox->type == DW_VERT)
-					{
-						int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppady;
-
-						if((thisbox->items[z].width - tmppad)!=0)
-							tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmppad))/((float)(thisbox->items[z].width-tmppad));
-					}
-					else
-					{
-						if((thisbox->items[z].width-tmp->upx)!=0)
-							tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx))/((float)(thisbox->items[z].width-tmp->upx));
-					}
-					if(thisbox->type == DW_HORZ)
-					{
-						int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppadx;
-
-						if((thisbox->items[z].height-tmppad)!=0)
-							tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmppad))/((float)(thisbox->items[z].height-tmppad));
-					}
-					else
-					{
-						if((thisbox->items[z].height-tmp->upy)!=0)
-							tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(thisbox->items[z].height-tmp->upy));
-					}
-
-					nux = *usedx; nuy = *usedy;
-					upx = *usedpadx + (tmp->pad*2); upy = *usedpady + (tmp->pad*2);
-				}
-
-				(*depth)++;
-
-				_resize_box(tmp, depth, x, y, &nux, &nuy, pass, &upx, &upy);
-
-				(*depth)--;
-
-				newx = x - nux;
-				newy = y - nuy;
-
-				tmp->minwidth = thisbox->items[z].width = initialx - newx;
-				tmp->minheight = thisbox->items[z].height = initialy - newy;
-			}
-		}
-
-		if(pass > 1 && *depth > 0)
-		{
-			if(thisbox->type == DW_VERT)
-			{
-				int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppadx;
-
-				if((thisbox->minwidth-tmppad) == 0)
-					thisbox->items[z].xratio = 1.0;
-				else
-					thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-tmppad))/((float)(thisbox->minwidth-tmppad));
-			}
-			else
-			{
-				if(thisbox->minwidth-thisbox->upx == 0)
-					thisbox->items[z].xratio = 1.0;
-				else
-					thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-thisbox->upx))/((float)(thisbox->minwidth-thisbox->upx));
-			}
-
-			if(thisbox->type == DW_HORZ)
-			{
-				int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppady;
-
-				if((thisbox->minheight-tmppad) == 0)
-					thisbox->items[z].yratio = 1.0;
-				else
-					thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-tmppad))/((float)(thisbox->minheight-tmppad));
-			}
-			else
-			{
-				if(thisbox->minheight-thisbox->upy == 0)
-					thisbox->items[z].yratio = 1.0;
-				else
-					thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy));
-			}
-
-			if(thisbox->items[z].type == TYPEBOX)
-			{
-				Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
-
-				if(tmp)
-				{
-					tmp->parentxratio = thisbox->items[z].xratio;
-					tmp->parentyratio = thisbox->items[z].yratio;
-				}
-			}
-		}
-		else
-		{
-			thisbox->items[z].xratio = thisbox->xratio;
-			thisbox->items[z].yratio = thisbox->yratio;
-		}
-
-		if(thisbox->type == DW_VERT)
-		{
-			int itemwidth = thisbox->items[z].width + (thisbox->items[z].pad*2);
-
-			if(itemwidth > uxmax)
-				uxmax = itemwidth;
-			if(thisbox->items[z].hsize != SIZEEXPAND)
-			{
-				if(itemwidth > upxmax)
-					upxmax = itemwidth;
-			}
-			else
-			{
-				if(thisbox->items[z].pad*2 > upxmax)
-					upxmax = thisbox->items[z].pad*2;
-			}
-		}
-		else
-		{
-			if(thisbox->items[z].width == -1)
-			{
-				/* figure out how much space this item requires */
-				/* thisbox->items[z].width = */
-			}
-			else
-			{
-				(*usedx) += thisbox->items[z].width + (thisbox->items[z].pad*2);
-				if(thisbox->items[z].hsize != SIZEEXPAND)
-					(*usedpadx) += (thisbox->items[z].pad*2) + thisbox->items[z].width;
-				else
-					(*usedpadx) += thisbox->items[z].pad*2;
-			}
-		}
-		if(thisbox->type == DW_HORZ)
-		{
-			int itemheight = thisbox->items[z].height + (thisbox->items[z].pad*2);
-
-			if(itemheight > uymax)
-				uymax = itemheight;
-			if(thisbox->items[z].vsize != SIZEEXPAND)
-			{
-				if(itemheight > upymax)
-					upymax = itemheight;
-			}
-			else
-			{
-				if(thisbox->items[z].pad*2 > upymax)
-					upymax = thisbox->items[z].pad*2;
-			}
-		}
-		else
-		{
-			if(thisbox->items[z].height == -1)
-			{
-				/* figure out how much space this item requires */
-				/* thisbox->items[z].height = */
-			}
-			else
-			{
-				(*usedy) += thisbox->items[z].height + (thisbox->items[z].pad*2);
-				if(thisbox->items[z].vsize != SIZEEXPAND)
-					(*usedpady) += (thisbox->items[z].pad*2) + thisbox->items[z].height;
-				else
-					(*usedpady) += thisbox->items[z].pad*2;
-			}
-		}
-	}
-
-	(*usedx) += uxmax;
-	(*usedy) += uymax;
-	(*usedpadx) += upxmax;
-	(*usedpady) += upymax;
-
-	currentx += thisbox->pad;
-	currenty += thisbox->pad;
-
-	if(thisbox->grouphwnd)
-	{
-		currentx += 3;
-		currenty += thisbox->grouppady - 3;
-	}
-
-	/* The second pass is for expansion and actual placement. */
-	if(pass > 1)
-	{
-		/* Any SIZEEXPAND items should be set to uxmax/uymax */
-		for(z=0;z<thisbox->count;z++)
-		{
-			if(thisbox->items[z].hsize == SIZEEXPAND && thisbox->type == DW_VERT)
-				thisbox->items[z].width = uxmax-(thisbox->items[z].pad*2);
-			if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == DW_HORZ)
-				thisbox->items[z].height = uymax-(thisbox->items[z].pad*2);
-			/* Run this code segment again to finalize the sized after setting uxmax/uymax values. */
-			if(thisbox->items[z].type == TYPEBOX)
-			{
-				Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
-
-				if(tmp)
-				{
-					if(*depth > 0)
-					{
-						float calcval;
-
-						if(thisbox->type == DW_VERT)
-						{
-							calcval = (float)(tmp->minwidth-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
-							if(calcval == 0.0)
-								tmp->xratio = thisbox->xratio;
-							else
-								tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
-							tmp->width = thisbox->items[z].width;
-						}
-						if(thisbox->type == DW_HORZ)
-						{
-							calcval = (float)(tmp->minheight-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
-							if(calcval == 0.0)
-								tmp->yratio = thisbox->yratio;
-							else
-								tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
-							tmp->height = thisbox->items[z].height;
-						}
-					}
-
-					(*depth)++;
-
-					_resize_box(tmp, depth, x, y, &nux, &nuy, 3, &nupx, &nupy);
-
-					(*depth)--;
-
-				}
-			}
-		}
-
-		for(z=0;z<(thisbox->count);z++)
-		{
-			int height = thisbox->items[z].height;
-			int width = thisbox->items[z].width;
-			int pad = thisbox->items[z].pad;
-			HWND handle = thisbox->items[z].hwnd;
-			int vectorx, vectory;
-
-			/* When upxmax != pad*2 then ratios are incorrect. */
-			vectorx = (int)((width*thisbox->items[z].xratio)-width);
-			vectory = (int)((height*thisbox->items[z].yratio)-height);
-
-			if(width > 0 && height > 0)
-			{
-				char tmpbuf[100];
-				/* This is a hack to fix rounding of the sizing */
-				if(*depth == 0)
-				{
-					vectorx++;
-					vectory++;
-				}
-
-				/* If this item isn't going to expand... reset the vectors to 0 */
-				if(thisbox->items[z].vsize != SIZEEXPAND)
-					vectory = 0;
-				if(thisbox->items[z].hsize != SIZEEXPAND)
-					vectorx = 0;
-
-				WinQueryClassName(handle, 99, tmpbuf);
-
-				if(strncmp(tmpbuf, "#2", 3)==0)
-				{
-					HWND frame = (HWND)dw_window_get_data(handle, "_dw_combo_box");
-					/* Make the combobox big enough to drop down. :) */
-					WinSetWindowPos(handle, HWND_TOP, 0, -100,
-									width + vectorx, (height + vectory) + 100, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-					_MySetWindowPos(frame, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
-									width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-				}
-				else if(strncmp(tmpbuf, "#6", 3)==0)
-				{
-					/* Entryfields on OS/2 have a thick border that isn't on Windows and GTK */
-					_MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, (currentx + pad) + 3, (currenty + pad) + 3,
-									(width + vectorx) - 6, (height + vectory) - 6, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-				}
-				else if(strncmp(tmpbuf, "#40", 5)==0)
-				{
-					_MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
-									width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-					_check_resize_notebook(handle);
-				}
-				else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
-				{
-					/* Then try the bottom or right box */
-					float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
-					int type = (int)dw_window_get_data(handle, "_dw_type");
-					int cx = width + vectorx;
-					int cy = height + vectory;
-
-					_MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
-									cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-
-					if(cx > 0 && cy > 0 && percent)
-						_handle_splitbar_resize(handle, *percent, type, cx, cy);
-				}
-				else
-				{
-					_MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
-									width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-					if(thisbox->items[z].type == TYPEBOX)
-					{
-						Box *boxinfo = WinQueryWindowPtr(handle, QWP_USER);
-
-						if(boxinfo && boxinfo->grouphwnd)
-							WinSetWindowPos(boxinfo->grouphwnd, HWND_TOP, 0, 0,
-											width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE);
-
-					}
-
-				}
-
-				if(thisbox->type == DW_HORZ)
-					currentx += width + vectorx + (pad * 2);
-				if(thisbox->type == DW_VERT)
-					currenty += height + vectory + (pad * 2);
-			}
-		}
-	}
-	return 0;
+            int pass, int *usedpadx, int *usedpady)
+{
+   int z, currentx = 0, currenty = 0;
+   int uymax = 0, uxmax = 0;
+   int upymax = 0, upxmax = 0;
+   /* Used for the SIZEEXPAND */
+   int nux = *usedx, nuy = *usedy;
+   int nupx = *usedpadx, nupy = *usedpady;
+
+   (*usedx) += (thisbox->pad * 2);
+   (*usedy) += (thisbox->pad * 2);
+
+   if(thisbox->grouphwnd)
+   {
+      char *text = dw_window_get_text(thisbox->grouphwnd);
+
+      thisbox->grouppady = 0;
+
+      if(text)
+      {
+         dw_font_text_extents_get(thisbox->grouphwnd, 0, text, NULL, &thisbox->grouppady);
+         dw_free(text);
+      }
+
+      if(thisbox->grouppady)
+         thisbox->grouppady += 3;
+      else
+         thisbox->grouppady = 6;
+
+      thisbox->grouppadx = 6;
+
+      (*usedx) += thisbox->grouppadx;
+      (*usedpadx) += thisbox->grouppadx;
+      (*usedy) += thisbox->grouppady;
+      (*usedpady) += thisbox->grouppady;
+   }
+
+   for(z=0;z<thisbox->count;z++)
+   {
+      if(thisbox->items[z].type == TYPEBOX)
+      {
+         int initialx, initialy;
+         Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
+
+         initialx = x - (*usedx);
+         initialy = y - (*usedy);
+
+         if(tmp)
+         {
+            int newx, newy;
+            int nux = *usedx, nuy = *usedy;
+            int upx = *usedpadx + (tmp->pad*2), upy = *usedpady + (tmp->pad*2);
+
+            /* On the second pass we know how big the box needs to be and how
+             * much space we have, so we can calculate a ratio for the new box.
+             */
+            if(pass == 2)
+            {
+               int deep = *depth + 1;
+
+               _resize_box(tmp, &deep, x, y, &nux, &nuy, 1, &upx, &upy);
+
+               tmp->upx = upx - *usedpadx;
+               tmp->upy = upy - *usedpady;
+
+               newx = x - nux;
+               newy = y - nuy;
+
+               tmp->width = thisbox->items[z].width = initialx - newx;
+               tmp->height = thisbox->items[z].height = initialy - newy;
+
+               tmp->parentxratio = thisbox->xratio;
+               tmp->parentyratio = thisbox->yratio;
+
+               tmp->parentpad = tmp->pad;
+
+               /* Just in case */
+               tmp->xratio = thisbox->xratio;
+               tmp->yratio = thisbox->yratio;
+
+               if(thisbox->type == DW_VERT)
+               {
+                  int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppady;
+
+                  if((thisbox->items[z].width - tmppad)!=0)
+                     tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmppad))/((float)(thisbox->items[z].width-tmppad));
+               }
+               else
+               {
+                  if((thisbox->items[z].width-tmp->upx)!=0)
+                     tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx))/((float)(thisbox->items[z].width-tmp->upx));
+               }
+               if(thisbox->type == DW_HORZ)
+               {
+                  int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppadx;
+
+                  if((thisbox->items[z].height-tmppad)!=0)
+                     tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmppad))/((float)(thisbox->items[z].height-tmppad));
+               }
+               else
+               {
+                  if((thisbox->items[z].height-tmp->upy)!=0)
+                     tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(thisbox->items[z].height-tmp->upy));
+               }
+
+               nux = *usedx; nuy = *usedy;
+               upx = *usedpadx + (tmp->pad*2); upy = *usedpady + (tmp->pad*2);
+            }
+
+            (*depth)++;
+
+            _resize_box(tmp, depth, x, y, &nux, &nuy, pass, &upx, &upy);
+
+            (*depth)--;
+
+            newx = x - nux;
+            newy = y - nuy;
+
+            tmp->minwidth = thisbox->items[z].width = initialx - newx;
+            tmp->minheight = thisbox->items[z].height = initialy - newy;
+         }
+      }
+
+      if(pass > 1 && *depth > 0)
+      {
+         if(thisbox->type == DW_VERT)
+         {
+            int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppadx;
+
+            if((thisbox->minwidth-tmppad) == 0)
+               thisbox->items[z].xratio = 1.0;
+            else
+               thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-tmppad))/((float)(thisbox->minwidth-tmppad));
+         }
+         else
+         {
+            if(thisbox->minwidth-thisbox->upx == 0)
+               thisbox->items[z].xratio = 1.0;
+            else
+               thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-thisbox->upx))/((float)(thisbox->minwidth-thisbox->upx));
+         }
+
+         if(thisbox->type == DW_HORZ)
+         {
+            int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppady;
+
+            if((thisbox->minheight-tmppad) == 0)
+               thisbox->items[z].yratio = 1.0;
+            else
+               thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-tmppad))/((float)(thisbox->minheight-tmppad));
+         }
+         else
+         {
+            if(thisbox->minheight-thisbox->upy == 0)
+               thisbox->items[z].yratio = 1.0;
+            else
+               thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy));
+         }
+
+         if(thisbox->items[z].type == TYPEBOX)
+         {
+            Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
+
+            if(tmp)
+            {
+               tmp->parentxratio = thisbox->items[z].xratio;
+               tmp->parentyratio = thisbox->items[z].yratio;
+            }
+         }
+      }
+      else
+      {
+         thisbox->items[z].xratio = thisbox->xratio;
+         thisbox->items[z].yratio = thisbox->yratio;
+      }
+
+      if(thisbox->type == DW_VERT)
+      {
+         int itemwidth = thisbox->items[z].width + (thisbox->items[z].pad*2);
+
+         if(itemwidth > uxmax)
+            uxmax = itemwidth;
+         if(thisbox->items[z].hsize != SIZEEXPAND)
+         {
+            if(itemwidth > upxmax)
+               upxmax = itemwidth;
+         }
+         else
+         {
+            if(thisbox->items[z].pad*2 > upxmax)
+               upxmax = thisbox->items[z].pad*2;
+         }
+      }
+      else
+      {
+         if(thisbox->items[z].width == -1)
+         {
+            /* figure out how much space this item requires */
+            /* thisbox->items[z].width = */
+         }
+         else
+         {
+            (*usedx) += thisbox->items[z].width + (thisbox->items[z].pad*2);
+            if(thisbox->items[z].hsize != SIZEEXPAND)
+               (*usedpadx) += (thisbox->items[z].pad*2) + thisbox->items[z].width;
+            else
+               (*usedpadx) += thisbox->items[z].pad*2;
+         }
+      }
+      if(thisbox->type == DW_HORZ)
+      {
+         int itemheight = thisbox->items[z].height + (thisbox->items[z].pad*2);
+
+         if(itemheight > uymax)
+            uymax = itemheight;
+         if(thisbox->items[z].vsize != SIZEEXPAND)
+         {
+            if(itemheight > upymax)
+               upymax = itemheight;
+         }
+         else
+         {
+            if(thisbox->items[z].pad*2 > upymax)
+               upymax = thisbox->items[z].pad*2;
+         }
+      }
+      else
+      {
+         if(thisbox->items[z].height == -1)
+         {
+            /* figure out how much space this item requires */
+            /* thisbox->items[z].height = */
+         }
+         else
+         {
+            (*usedy) += thisbox->items[z].height + (thisbox->items[z].pad*2);
+            if(thisbox->items[z].vsize != SIZEEXPAND)
+               (*usedpady) += (thisbox->items[z].pad*2) + thisbox->items[z].height;
+            else
+               (*usedpady) += thisbox->items[z].pad*2;
+         }
+      }
+   }
+
+   (*usedx) += uxmax;
+   (*usedy) += uymax;
+   (*usedpadx) += upxmax;
+   (*usedpady) += upymax;
+
+   currentx += thisbox->pad;
+   currenty += thisbox->pad;
+
+   if(thisbox->grouphwnd)
+   {
+      currentx += 3;
+      currenty += thisbox->grouppady - 3;
+   }
+
+   /* The second pass is for expansion and actual placement. */
+   if(pass > 1)
+   {
+      /* Any SIZEEXPAND items should be set to uxmax/uymax */
+      for(z=0;z<thisbox->count;z++)
+      {
+         if(thisbox->items[z].hsize == SIZEEXPAND && thisbox->type == DW_VERT)
+            thisbox->items[z].width = uxmax-(thisbox->items[z].pad*2);
+         if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == DW_HORZ)
+            thisbox->items[z].height = uymax-(thisbox->items[z].pad*2);
+         /* Run this code segment again to finalize the sized after setting uxmax/uymax values. */
+         if(thisbox->items[z].type == TYPEBOX)
+         {
+            Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
+
+            if(tmp)
+            {
+               if(*depth > 0)
+               {
+                  float calcval;
+
+                  if(thisbox->type == DW_VERT)
+                  {
+                     calcval = (float)(tmp->minwidth-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
+                     if(calcval == 0.0)
+                        tmp->xratio = thisbox->xratio;
+                     else
+                        tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
+                     tmp->width = thisbox->items[z].width;
+                  }
+                  if(thisbox->type == DW_HORZ)
+                  {
+                     calcval = (float)(tmp->minheight-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
+                     if(calcval == 0.0)
+                        tmp->yratio = thisbox->yratio;
+                     else
+                        tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
+                     tmp->height = thisbox->items[z].height;
+                  }
+               }
+
+               (*depth)++;
+
+               _resize_box(tmp, depth, x, y, &nux, &nuy, 3, &nupx, &nupy);
+
+               (*depth)--;
+
+            }
+         }
+      }
+
+      for(z=0;z<(thisbox->count);z++)
+      {
+         int height = thisbox->items[z].height;
+         int width = thisbox->items[z].width;
+         int pad = thisbox->items[z].pad;
+         HWND handle = thisbox->items[z].hwnd;
+         int vectorx, vectory;
+
+         /* When upxmax != pad*2 then ratios are incorrect. */
+         vectorx = (int)((width*thisbox->items[z].xratio)-width);
+         vectory = (int)((height*thisbox->items[z].yratio)-height);
+
+         if(width > 0 && height > 0)
+         {
+            char tmpbuf[100];
+            /* This is a hack to fix rounding of the sizing */
+            if(*depth == 0)
+            {
+               vectorx++;
+               vectory++;
+            }
+
+            /* If this item isn't going to expand... reset the vectors to 0 */
+            if(thisbox->items[z].vsize != SIZEEXPAND)
+               vectory = 0;
+            if(thisbox->items[z].hsize != SIZEEXPAND)
+               vectorx = 0;
+
+            WinQueryClassName(handle, 99, (PCH)tmpbuf);
+
+            if(strncmp(tmpbuf, "#2", 3)==0)
+            {
+               HWND frame = (HWND)dw_window_get_data(handle, "_dw_combo_box");
+               /* Make the combobox big enough to drop down. :) */
+               WinSetWindowPos(handle, HWND_TOP, 0, -100,
+                           width + vectorx, (height + vectory) + 100, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+               _MySetWindowPos(frame, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
+                           width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+            }
+            else if(strncmp(tmpbuf, "#6", 3)==0)
+            {
+               /* Entryfields on OS/2 have a thick border that isn't on Windows and GTK */
+               _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, (currentx + pad) + 3, (currenty + pad) + 3,
+                           (width + vectorx) - 6, (height + vectory) - 6, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+            }
+            else if(strncmp(tmpbuf, "#40", 5)==0)
+            {
+               _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
+                           width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+               _check_resize_notebook(handle);
+            }
+            else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
+            {
+                /* Handle special case of scrollbox */
+                int cx = width + vectorx;
+                int cy = height + vectory;
+                int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
+                HWND box = (HWND)dw_window_get_data(handle, "_dw_resizebox");
+                HWND client = WinWindowFromID(handle, FID_CLIENT);
+                HWND vscroll = WinWindowFromID(handle, FID_VERTSCROLL);
+                HWND hscroll = WinWindowFromID(handle, FID_HORZSCROLL);
+                Box *contentbox = (Box *)WinQueryWindowPtr(box, QWP_USER);
+                int origx, origy;
+                unsigned int hpos = (unsigned int)WinSendMsg(hscroll, SBM_QUERYPOS, 0, 0);
+                unsigned int vpos = (unsigned int)WinSendMsg(vscroll, SBM_QUERYPOS, 0, 0);
+
+                /* Position the scrollbox parts */
+                _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                WinSetWindowPos(client, HWND_TOP, 0, _DW_DEFAULT_SCROLLBAR_WIDTH, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, cy - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                WinSetWindowPos(hscroll, HWND_TOP, 0, 0, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                WinSetWindowPos(vscroll, HWND_TOP, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, cy - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+
+                origx = cx = cx - _DW_DEFAULT_SCROLLBAR_WIDTH;
+                origy = cy = cy - _DW_DEFAULT_SCROLLBAR_WIDTH;
+
+                /* Get the required space for the box */
+                _resize_box(contentbox, &depth, cx, cy, &usedx, &usedy, 1, &usedpadx, &usedpady);
+
+                if(cx < usedx)
+                {
+                    cx = usedx;
+                }
+                if(cy < usedy)
+                {
+                    cy = usedy;
+                }
+
+                /* Setup vertical scroller */
+                WinSendMsg(vscroll, SBM_SETSCROLLBAR, (MPARAM)vpos, MPFROM2SHORT(0, (unsigned short)usedy - origy));
+                WinSendMsg(vscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origy, usedy), 0);
+                if(vpos > usedy)
+                {
+                    vpos = usedy;
+                    WinSendMsg(vscroll, SBM_SETPOS, (MPARAM)vpos, 0);
+                }
+
+                /* Setup horizontal scroller */
+                WinSendMsg(hscroll, SBM_SETSCROLLBAR, (MPARAM)hpos, MPFROM2SHORT(0, (unsigned short)usedx - origx));
+                WinSendMsg(hscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origx, usedx), 0);
+                if(hpos > usedx)
+                {
+                    hpos = usedx;
+                    WinSendMsg(hscroll, SBM_SETPOS, (MPARAM)hpos, 0);
+                }
+
+                /* Position the scrolled box */
+                WinSetWindowPos(box, HWND_TOP, 0, -(cy - origy), cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+
+                dw_window_set_data(handle, "_dw_cy", (void *)(cy - origy));
+
+                /* Layout the content of the scrollbox */
+                _do_resize(contentbox, cx, cy);
+            }
+            else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
+            {
+               /* Then try the bottom or right box */
+               float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
+               int type = (int)dw_window_get_data(handle, "_dw_type");
+               int cx = width + vectorx;
+               int cy = height + vectory;
+
+               _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
+                           cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+
+               if(cx > 0 && cy > 0 && percent)
+                  _handle_splitbar_resize(handle, *percent, type, cx, cy);
+            }
+            else
+            {
+               _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
+                           width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+               if(thisbox->items[z].type == TYPEBOX)
+               {
+                  Box *boxinfo = WinQueryWindowPtr(handle, QWP_USER);
+
+                  if(boxinfo && boxinfo->grouphwnd)
+                     WinSetWindowPos(boxinfo->grouphwnd, HWND_TOP, 0, 0,
+                                 width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE);
+
+               }
+
+            }
+
+            if(thisbox->type == DW_HORZ)
+               currentx += width + vectorx + (pad * 2);
+            if(thisbox->type == DW_VERT)
+               currenty += height + vectory + (pad * 2);
+         }
+      }
+   }
+   return 0;
 }
 
 void _do_resize(Box *thisbox, int x, int y)
 {
-	if(x != 0 && y != 0)
-	{
-		if(thisbox)
-		{
-			int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
-
-			_resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady);
-
-			if(usedx-usedpadx == 0 || usedy-usedpady == 0)
-				return;
-
-			thisbox->xratio = ((float)(x-usedpadx))/((float)(usedx-usedpadx));
-			thisbox->yratio = ((float)(y-usedpady))/((float)(usedy-usedpady));
-
-			usedx = usedy = usedpadx = usedpady = depth = 0;
-
-			_resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady);
-		}
-	}
+   if(x != 0 && y != 0)
+   {
+      if(thisbox)
+      {
+         int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
+
+         _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady);
+
+         if(usedx-usedpadx == 0 || usedy-usedpady == 0)
+            return;
+
+         thisbox->xratio = ((float)(x-usedpadx))/((float)(usedx-usedpadx));
+         thisbox->yratio = ((float)(y-usedpady))/((float)(usedy-usedpady));
+
+         usedx = usedy = usedpadx = usedpady = depth = 0;
+
+         _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady);
+      }
+   }
 }
 
 /* This procedure handles WM_QUERYTRACKINFO requests from the frame */
 MRESULT EXPENTRY _sizeproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
-	Box *thisbox = NULL;
-	HWND box;
-
-	box = WinWindowFromID(hWnd, FID_CLIENT);
-	if(box)
-		thisbox = WinQueryWindowPtr(box, QWP_USER);
-
-	if(thisbox && !thisbox->titlebar)
-	{
-		switch(msg)
-		{
-		case WM_QUERYTRACKINFO:
-			{
-				if(blah && *blah)
-				{
-					PTRACKINFO ptInfo;
-					int res;
-					PFNWP myfunc = *blah;
-					res = (int)myfunc(hWnd, msg, mp1, mp2);
-
-					ptInfo = (PTRACKINFO)(mp2);
-
-					ptInfo->ptlMinTrackSize.y = 8;
-					ptInfo->ptlMinTrackSize.x = 8;
-
-					return (MRESULT)res;
-				}
-			}
-		}
-	}
-
-	if(blah && *blah)
-	{
-		PFNWP myfunc = *blah;
-		return myfunc(hWnd, msg, mp1, mp2);
-	}
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
+   PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
+   Box *thisbox = NULL;
+   HWND box;
+
+   box = WinWindowFromID(hWnd, FID_CLIENT);
+   if(box)
+      thisbox = WinQueryWindowPtr(box, QWP_USER);
+
+   if(thisbox && !thisbox->titlebar)
+   {
+      switch(msg)
+      {
+      case WM_QUERYTRACKINFO:
+         {
+            if(blah && *blah)
+            {
+               PTRACKINFO ptInfo;
+               int res;
+               PFNWP myfunc = *blah;
+               res = (int)myfunc(hWnd, msg, mp1, mp2);
+
+               ptInfo = (PTRACKINFO)(mp2);
+
+               ptInfo->ptlMinTrackSize.y = 8;
+               ptInfo->ptlMinTrackSize.x = 8;
+
+               return (MRESULT)res;
+            }
+         }
+      }
+   }
+
+   if(blah && *blah)
+   {
+      PFNWP myfunc = *blah;
+      return myfunc(hWnd, msg, mp1, mp2);
+   }
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
 }
 
 void _Top(HPS hpsPaint, RECTL rclPaint)
 {
-	POINTL ptl1, ptl2;
-
-	ptl1.x = rclPaint.xLeft;
-	ptl2.y = ptl1.y = rclPaint.yTop - 1;
-	ptl2.x = rclPaint.xRight - 1;
-	GpiMove(hpsPaint, &ptl1);
-	GpiLine(hpsPaint, &ptl2);
+   POINTL ptl1, ptl2;
+
+   ptl1.x = rclPaint.xLeft;
+   ptl2.y = ptl1.y = rclPaint.yTop - 1;
+   ptl2.x = rclPaint.xRight - 1;
+   GpiMove(hpsPaint, &ptl1);
+   GpiLine(hpsPaint, &ptl2);
 }
 
 /* Left hits the bottom */
 void _Left(HPS hpsPaint, RECTL rclPaint)
 {
-	POINTL ptl1, ptl2;
-
-	ptl2.x = ptl1.x = rclPaint.xLeft;
-	ptl1.y = rclPaint.yTop - 1;
-	ptl2.y = rclPaint.yBottom;
-	GpiMove(hpsPaint, &ptl1);
-	GpiLine(hpsPaint, &ptl2);
+   POINTL ptl1, ptl2;
+
+   ptl2.x = ptl1.x = rclPaint.xLeft;
+   ptl1.y = rclPaint.yTop - 1;
+   ptl2.y = rclPaint.yBottom;
+   GpiMove(hpsPaint, &ptl1);
+   GpiLine(hpsPaint, &ptl2);
 }
 
 void _Bottom(HPS hpsPaint, RECTL rclPaint)
 {
-	POINTL ptl1, ptl2;
-
-	ptl1.x = rclPaint.xRight - 1;
-	ptl1.y = ptl2.y = rclPaint.yBottom;
-	ptl2.x = rclPaint.xLeft;
-	GpiMove(hpsPaint, &ptl1);
-	GpiLine(hpsPaint, &ptl2);
+   POINTL ptl1, ptl2;
+
+   ptl1.x = rclPaint.xRight - 1;
+   ptl1.y = ptl2.y = rclPaint.yBottom;
+   ptl2.x = rclPaint.xLeft;
+   GpiMove(hpsPaint, &ptl1);
+   GpiLine(hpsPaint, &ptl2);
 }
 
 /* Right hits the top */
 void _Right(HPS hpsPaint, RECTL rclPaint)
 {
-	POINTL ptl1, ptl2;
-
-	ptl2.x = ptl1.x = rclPaint.xRight - 1;
-	ptl1.y = rclPaint.yBottom + 1;
-	ptl2.y = rclPaint.yTop - 1;
-	GpiMove(hpsPaint, &ptl1);
-	GpiLine(hpsPaint, &ptl2);
-}
+   POINTL ptl1, ptl2;
+
+   ptl2.x = ptl1.x = rclPaint.xRight - 1;
+   ptl1.y = rclPaint.yBottom + 1;
+   ptl2.y = rclPaint.yTop - 1;
+   GpiMove(hpsPaint, &ptl1);
+   GpiLine(hpsPaint, &ptl2);
+}
+
+
+#define CALENDAR_BORDER 3
+#define CALENDAR_ARROW 8
+
+/* Returns a rectangle for a single day on the calendar */
+RECTL _CalendarDayRect(int position, RECTL rclPaint)
+{
+    int height = rclPaint.yTop - rclPaint.yBottom - (CALENDAR_BORDER*2);
+    int width = rclPaint.xRight - rclPaint.xLeft - (CALENDAR_BORDER*2);
+    /* There are 7 rows... 5 for the day numbers...
+     * 1 for the Month/Year and 1 for the day names.
+     */
+    int row = position / 7;
+    int col = position % 7;
+    int cellwidth = width / 7;
+    int cellheight = height / 8;
+
+    /* Create a new box */
+    rclPaint.xLeft = (cellwidth * col) + CALENDAR_BORDER;
+    rclPaint.xRight = rclPaint.xLeft + cellwidth;
+    /* We only handle 6 of the 7 rows */
+    rclPaint.yBottom = (cellheight * (6-row)) + CALENDAR_BORDER;
+    rclPaint.yTop = rclPaint.yBottom + cellheight;
+    return rclPaint;
+}
+
+/* This procedure handles drawing of a status border */
+MRESULT EXPENTRY _calendarproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   /* How many days are in each month usually (not including leap years) */
+   static int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+   static char *months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
+   static char *daysofweek[] = { "Sunday", "Monday", "Tuesday","Wednesday", "Thursday", "Friday", "Saturday" };
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
+   PFNWP oldproc = 0;
+
+   if(blah)
+   {
+      oldproc = blah->oldproc;
+
+      switch(msg)
+      {
+      case WM_BUTTON1DOWN:
+      case WM_BUTTON2DOWN:
+      case WM_BUTTON3DOWN:
+          {
+              POINTS pts = (*((POINTS*)&mp1));
+              int day = DW_POINTER_TO_INT(dw_window_get_data(hWnd, "_dw_day"));
+              int month = DW_POINTER_TO_INT(dw_window_get_data(hWnd, "_dw_month"));
+              int year = DW_POINTER_TO_INT(dw_window_get_data(hWnd, "_dw_year"));
+              int dayofweek = 1, x, height, isleapyear = ((year+1) % 4 == 0);
+              int daysthismonth = days[month] + (isleapyear && month == 1);
+              RECTL rclArea;
+
+              /* Figure out what day of the week the first day of the month falls on */
+              for(x=0;x<month;x++)
+                  dayofweek += days[x] + (isleapyear && x == 1);
+              dayofweek += (year/4) + year - 1;
+              dayofweek = dayofweek % 7;
+
+              WinQueryWindowRect(hWnd, &rclArea);
+              height = ((rclArea.yTop - (CALENDAR_BORDER*2))/7);
+
+              /* Check for the left arrow */
+              if(pts.x > rclArea.xLeft + CALENDAR_BORDER && pts.x < rclArea.xLeft + CALENDAR_BORDER + CALENDAR_ARROW &&
+                 pts.y > rclArea.yTop - (CALENDAR_BORDER + height) && pts.y < rclArea.yTop - CALENDAR_BORDER)
+              {
+                  int daysthismonth;
+
+                  if(month == 0)
+                  {
+                      month = 11;
+                      year--;
+                      dw_window_set_data(hWnd, "_dw_year", DW_INT_TO_POINTER(year));
+                  }
+                  else if(month > 0)
+                  {
+                      month--;
+                  }
+                  dw_window_set_data(hWnd, "_dw_month", DW_INT_TO_POINTER(month));
+                  /* Make sure we aren't higher than the number of days
+                   * in our new month... keeping track of leap years.
+                   */
+                  daysthismonth = days[month] + (isleapyear && month == 1);
+                  if(day >= daysthismonth)
+                  {
+                      day = daysthismonth - 1;
+                      dw_window_set_data(hWnd, "_dw_day", DW_INT_TO_POINTER(day));
+                  }
+                  WinInvalidateRect(hWnd, &rclArea, FALSE);
+                  WinPostMsg(hWnd, WM_PAINT, 0, 0);
+                  return (MRESULT)TRUE;
+              }
+
+              /* Check for the right arrow */
+              if(pts.x < rclArea.xRight - CALENDAR_BORDER && pts.x > rclArea.xRight - CALENDAR_BORDER - CALENDAR_ARROW &&
+                 pts.y > rclArea.yTop - (CALENDAR_BORDER + height) && pts.y < rclArea.yTop - CALENDAR_BORDER)
+              {
+                  int daysthismonth;
+
+                  if(month == 11)
+                  {
+                      month = 0;
+                      year++;
+                      dw_window_set_data(hWnd, "_dw_year", DW_INT_TO_POINTER(year));
+                  }
+                  else if(month < 11)
+                  {
+                      month++;
+                  }
+                  dw_window_set_data(hWnd, "_dw_month", DW_INT_TO_POINTER(month));
+                  /* Make sure we aren't higher than the number of days
+                   * in our new month... keeping track of leap years.
+                   */
+                  daysthismonth = days[month] + (isleapyear && month == 1);
+                  if(day >= daysthismonth)
+                  {
+                      day = daysthismonth - 1;
+                      dw_window_set_data(hWnd, "_dw_day", DW_INT_TO_POINTER(day));
+                  }
+                  WinInvalidateRect(hWnd, &rclArea, FALSE);
+                  WinPostMsg(hWnd, WM_PAINT, 0, 0);
+                  return (MRESULT)TRUE;
+              }
+
+              /* Check all the valid days of the month */
+              for(x=dayofweek+7;x<(daysthismonth+dayofweek+7);x++)
+              {
+                  RECTL rclThis = _CalendarDayRect(x, rclArea);
+                  if(pts.x < rclThis.xRight && pts.x > rclThis.xLeft && pts.y < rclThis.yTop && pts.y > rclThis.yBottom)
+                  {
+                      dw_window_set_data(hWnd, "_dw_day", DW_INT_TO_POINTER((x-(dayofweek+7))));
+                      WinInvalidateRect(hWnd, &rclArea, FALSE);
+                      WinPostMsg(hWnd, WM_PAINT, 0, 0);
+                      return (MRESULT)TRUE;
+                  }
+              }
+          }
+          break;
+      case WM_PAINT:
+         {
+            HPS hpsPaint;
+            RECTL rclPaint, rclDraw;
+            char buf[100];
+            int day = DW_POINTER_TO_INT(dw_window_get_data(hWnd, "_dw_day"));
+            int month = DW_POINTER_TO_INT(dw_window_get_data(hWnd, "_dw_month"));
+            int year = DW_POINTER_TO_INT(dw_window_get_data(hWnd, "_dw_year"));
+            int dayofweek = 1, x, lastmonth = 11, height, isleapyear = ((year+1) % 4 == 0);
+            POINTL pptl[3];
+
+            /* Figure out the previous month for later use */
+            if(month > 0)
+                lastmonth = month - 1;
+
+            /* Make the title */
+            sprintf(buf, "%s, %d", months[month], year + 1);
+
+            /* Figure out what day of the week the first day of the month falls on */
+            for(x=0;x<month;x++)
+                dayofweek += days[x] + (isleapyear && x == 1);
+            dayofweek += (year/4) + year - 1;
+            dayofweek = dayofweek % 7;
+
+            /* Actually draw the control */
+            hpsPaint = WinBeginPaint(hWnd, 0, 0);
+            WinQueryWindowRect(hWnd, &rclPaint);
+            WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY);
+            height = ((rclPaint.yTop - (CALENDAR_BORDER*2))/7);
+
+            /* Draw the Month and Year at the top */
+            GpiSetColor(hpsPaint, CLR_BLACK);
+            rclDraw = rclPaint;
+            rclDraw.yBottom = height * 6;
+            WinDrawText(hpsPaint, -1, (PCH)buf, &rclDraw, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_CENTER | DT_TEXTATTRS);
+
+            /* Draw the left arrow */
+            GpiSetColor(hpsPaint, CLR_DARKGRAY);
+            GpiBeginArea(hpsPaint, 0);
+            pptl[2].x = rclDraw.xLeft + CALENDAR_BORDER + CALENDAR_ARROW;
+            pptl[2].y = rclDraw.yTop - CALENDAR_BORDER;
+            GpiMove(hpsPaint, &pptl[2]);
+            pptl[0].x = rclDraw.xLeft + CALENDAR_BORDER;
+            pptl[0].y = rclDraw.yTop - (CALENDAR_BORDER+ (height/2));
+            pptl[1].x = rclDraw.xLeft + CALENDAR_BORDER + CALENDAR_ARROW;
+            pptl[1].y = rclDraw.yTop - CALENDAR_BORDER - height;
+            GpiPolyLine(hpsPaint, 3, pptl);
+            GpiEndArea(hpsPaint);
+
+            /* Draw the left arrow */
+            GpiBeginArea(hpsPaint, 0);
+            pptl[2].x = rclDraw.xRight - CALENDAR_BORDER - CALENDAR_ARROW;
+            pptl[2].y = rclDraw.yTop - CALENDAR_BORDER;
+            GpiMove(hpsPaint, &pptl[2]);
+            pptl[0].x = rclDraw.xRight - CALENDAR_BORDER;
+            pptl[0].y = rclDraw.yTop - (CALENDAR_BORDER + (height/2));
+            pptl[1].x = rclDraw.xRight - CALENDAR_BORDER - CALENDAR_ARROW;
+            pptl[1].y = rclDraw.yTop - CALENDAR_BORDER - height;
+            GpiPolyLine(hpsPaint, 3, pptl);
+            GpiEndArea(hpsPaint);
+
+            /* Draw a border around control */
+            _Top(hpsPaint, rclPaint);
+            _Left(hpsPaint, rclPaint);
+            /* With shadow */
+            GpiSetColor(hpsPaint, CLR_WHITE);
+            _Right(hpsPaint, rclPaint);
+            _Bottom(hpsPaint, rclPaint);
+
+            /* Draw the days of the week */
+            GpiSetColor(hpsPaint, CLR_BLACK);
+            for(x=0;x<7;x++)
+            {
+                char *title = daysofweek[x];
+
+                rclDraw = _CalendarDayRect(x, rclPaint);
+
+                if(rclDraw.xRight - rclDraw.xLeft < 60)
+                {
+                    buf[0] = daysofweek[x][0]; buf[1] = daysofweek[x][1]; buf[2] = 0;
+                    title = buf;
+                }
+                WinDrawText(hpsPaint, -1, (PCH)title, &rclDraw, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_CENTER | DT_TEXTATTRS);
+            }
+
+            /* Go through all the days */
+            for(x=0;x<42;x++)
+            {
+                int daysthismonth = days[month] + (isleapyear && month == 1);
+                int dayslastmonth = days[lastmonth] + (isleapyear && lastmonth == 1);
+
+                rclDraw = _CalendarDayRect(x+7, rclPaint);
+                if(x < dayofweek)
+                {
+                    GpiSetColor(hpsPaint, CLR_DARKGRAY);
+                    sprintf(buf, "%d", dayslastmonth - (dayofweek - x - 1));
+                }
+                else if(x - dayofweek + 1 > daysthismonth)
+                {
+                    GpiSetColor(hpsPaint, CLR_DARKGRAY);
+                    sprintf(buf, "%d", x - dayofweek - daysthismonth + 1);
+                }
+                else
+                {
+                    GpiSetColor(hpsPaint, CLR_DARKBLUE);
+                    sprintf(buf, "%d", x - dayofweek + 1);
+                }
+                WinDrawText(hpsPaint, -1, (PCH)buf, &rclDraw, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_CENTER | DT_TEXTATTRS);
+            }
+
+            /* Draw a border around selected day */
+            rclPaint = _CalendarDayRect(day + dayofweek + 7, rclPaint);
+            GpiSetColor(hpsPaint, CLR_DARKGRAY);
+            _Top(hpsPaint, rclPaint);
+            _Left(hpsPaint, rclPaint);
+            /* With shadow */
+            GpiSetColor(hpsPaint, CLR_WHITE);
+            _Right(hpsPaint, rclPaint);
+            _Bottom(hpsPaint, rclPaint);
+
+            WinEndPaint(hpsPaint);
+
+            return (MRESULT)TRUE;
+         }
+      }
+      if(oldproc)
+          return oldproc(hWnd, msg, mp1, mp2);
+   }
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
+}
+
 
 /* This procedure handles drawing of a status border */
 MRESULT EXPENTRY _statusproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
-
-	if(msg == WM_MOUSEMOVE && _wndproc(hWnd, msg, mp1, mp2))
-		return MPFROMSHORT(FALSE);
-
-	if(blah && *blah)
-	{
-		PFNWP myfunc = *blah;
-
-		switch(msg)
-		{
-		case WM_PAINT:
-			{
-				HPS hpsPaint;
-				RECTL rclPaint;
-				char buf[1024];
-
-				hpsPaint = WinBeginPaint(hWnd, 0, 0);
-				WinQueryWindowRect(hWnd, &rclPaint);
-				WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY);
-
-				GpiSetColor(hpsPaint, CLR_DARKGRAY);
-				_Top(hpsPaint, rclPaint);
-				_Left(hpsPaint, rclPaint);
-
-				GpiSetColor(hpsPaint, CLR_WHITE);
-				_Right(hpsPaint, rclPaint);
-				_Bottom(hpsPaint, rclPaint);
-
-				WinQueryWindowText(hWnd, 1024, buf);
-				rclPaint.xLeft += 3;
-				rclPaint.xRight--;
-				rclPaint.yTop--;
-				rclPaint.yBottom++;
-
-				GpiSetColor(hpsPaint, CLR_BLACK);
-				WinDrawText(hpsPaint, -1, buf, &rclPaint, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS);
-				WinEndPaint(hpsPaint);
-
-				return (MRESULT)TRUE;
-			}
-		}
-		return myfunc(hWnd, msg, mp1, mp2);
-	}
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
+   PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
+
+   if(msg == WM_MOUSEMOVE && _wndproc(hWnd, msg, mp1, mp2))
+      return MPFROMSHORT(FALSE);
+
+   if(blah && *blah)
+   {
+      PFNWP myfunc = *blah;
+
+      switch(msg)
+      {
+      case WM_PAINT:
+         {
+            HPS hpsPaint;
+            RECTL rclPaint;
+            char buf[1024];
+
+            hpsPaint = WinBeginPaint(hWnd, 0, 0);
+            WinQueryWindowRect(hWnd, &rclPaint);
+            WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY);
+
+            GpiSetColor(hpsPaint, CLR_DARKGRAY);
+            _Top(hpsPaint, rclPaint);
+            _Left(hpsPaint, rclPaint);
+
+            GpiSetColor(hpsPaint, CLR_WHITE);
+            _Right(hpsPaint, rclPaint);
+            _Bottom(hpsPaint, rclPaint);
+
+            WinQueryWindowText(hWnd, 1024, (PSZ)buf);
+            rclPaint.xLeft += 3;
+            rclPaint.xRight--;
+            rclPaint.yTop--;
+            rclPaint.yBottom++;
+
+            GpiSetColor(hpsPaint, CLR_BLACK);
+            WinDrawText(hpsPaint, -1, (PCH)buf, &rclPaint, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS);
+            WinEndPaint(hpsPaint);
+
+            return (MRESULT)TRUE;
+         }
+      }
+      return myfunc(hWnd, msg, mp1, mp2);
+   }
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
 }
 
 /* This procedure handles pointer changes */
 MRESULT EXPENTRY _textproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
-
-	if(msg == WM_MOUSEMOVE &&_wndproc(hWnd, msg, mp1, mp2))
-		return MPFROMSHORT(FALSE);
-
-	if(blah && *blah)
-	{
-		PFNWP myfunc = *blah;
-
-		return myfunc(hWnd, msg, mp1, mp2);
-	}
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
+   PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
+
+   if(msg == WM_MOUSEMOVE &&_wndproc(hWnd, msg, mp1, mp2))
+      return MPFROMSHORT(FALSE);
+
+   if(blah && *blah)
+   {
+      PFNWP myfunc = *blah;
+
+      return myfunc(hWnd, msg, mp1, mp2);
+   }
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
+}
+
+/* This procedure handles scrollbox */
+MRESULT EXPENTRY _scrollwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   switch(msg)
+   {
+      case WM_PAINT:
+         {
+            HPS hpsPaint;
+            RECTL rclPaint;
+
+            hpsPaint = WinBeginPaint(hWnd, 0, 0);
+            WinQueryWindowRect(hWnd, &rclPaint);
+            WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY);
+            WinEndPaint(hpsPaint);
+
+            break;
+         }
+   case WM_HSCROLL:
+   case WM_VSCROLL:
+      {
+         MPARAM res;
+         int *pos, min, max, page, which = SHORT2FROMMP(mp2);
+         HWND handle, client = WinWindowFromID(hWnd, FID_CLIENT);
+         HWND box = (HWND)dw_window_get_data(hWnd, "_dw_resizebox");
+         HWND hscroll = WinWindowFromID(hWnd, FID_HORZSCROLL);
+         HWND vscroll = WinWindowFromID(hWnd, FID_VERTSCROLL);
+            int hpos = dw_scrollbar_get_pos(hscroll);
+            int vpos = dw_scrollbar_get_pos(vscroll);
+         int cy = (int)dw_window_get_data(hWnd, "_dw_cy");
+            RECTL rect;
+
+         WinQueryWindowRect(client, &rect);
+
+         if(msg == WM_VSCROLL)
+         {
+            page = rect.yTop - rect.yBottom;
+            handle = vscroll;
+                pos = &vpos;
+         }
+         else
+         {
+            page = rect.xRight - rect.xLeft;
+            handle = hscroll;
+                pos = &hpos;
+         }
+
+         res = WinSendMsg(handle, SBM_QUERYRANGE, 0, 0);
+         min = SHORT1FROMMP(res);
+         max = SHORT2FROMMP(res);
+
+         switch(which)
+         {
+         case SB_SLIDERTRACK:
+                *pos = SHORT1FROMMP(mp2);
+                break;
+         case SB_LINEUP:
+            (*pos)--;
+            if(*pos < min)
+               *pos = min;
+                break;
+         case SB_LINEDOWN:
+            (*pos)++;
+            if(*pos > max)
+               *pos = max;
+                break;
+         case SB_PAGEUP:
+            (*pos) -= page;
+            if(*pos < min)
+               *pos = min;
+                break;
+         case SB_PAGEDOWN:
+            (*pos) += page;
+            if(*pos > max)
+               *pos = max;
+            break;
+         }
+            WinSendMsg(handle, SBM_SETPOS, (MPARAM)*pos, 0);
+            /* Position the scrolled box */
+            WinSetWindowPos(box, HWND_TOP, -hpos, -(cy - vpos), 0, 0, SWP_MOVE);
+         break;
+      }
+   }
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
 }
 
 void _click_default(HWND handle)
 {
-	char tmpbuf[100];
-
-	WinQueryClassName(handle, 99, tmpbuf);
-
-	/* These are the window classes which can
-	 * obtain input focus.
-	 */
-	if(strncmp(tmpbuf, "#3", 3)==0)
-	{
-		/* Generate click on default item */
-		SignalHandler *tmp = Root;
-
-		/* Find any callbacks for this function */
-		while(tmp)
-		{
-			if(tmp->message == WM_COMMAND)
-			{
-				int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
-
-				/* Make sure it's the right window, and the right ID */
-				if(tmp->window == handle)
-				{
-					clickfunc(tmp->window, tmp->data);
-					tmp = NULL;
-				}
-			}
-			if(tmp)
-				tmp= tmp->next;
-		}
-	}
-	else
-		WinSetFocus(HWND_DESKTOP, handle);
-}
-
-#define ENTRY_CUT   1001
-#define ENTRY_COPY  1002
-#define ENTRY_PASTE 1003
-#define ENTRY_UNDO  1004
-#define ENTRY_SALL  1005
+   char tmpbuf[100];
+
+   WinQueryClassName(handle, 99, (PCH)tmpbuf);
+
+   /* These are the window classes which can
+    * obtain input focus.
+    */
+   if(strncmp(tmpbuf, "#3", 3)==0)
+   {
+      /* Generate click on default item */
+      SignalHandler *tmp = Root;
+
+      /* Find any callbacks for this function */
+      while(tmp)
+      {
+         if(tmp->message == WM_COMMAND)
+         {
+            int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
+
+            /* Make sure it's the right window, and the right ID */
+            if(tmp->window == handle)
+            {
+               clickfunc(tmp->window, tmp->data);
+               tmp = NULL;
+            }
+         }
+         if(tmp)
+            tmp= tmp->next;
+      }
+   }
+   else
+      WinSetFocus(HWND_DESKTOP, handle);
+}
+
+#define ENTRY_CUT   60901
+#define ENTRY_COPY  60902
+#define ENTRY_PASTE 60903
+#define ENTRY_UNDO  60904
+#define ENTRY_SALL  60905
 
 /* Originally just intended for entryfields, it now serves as a generic
  * procedure for handling TAB presses to change input focus on controls.
  */
 MRESULT EXPENTRY _entryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
-	PFNWP oldproc = 0;
-	char tmpbuf[100];
-
-	if(blah)
-		oldproc = blah->oldproc;
-
-	WinQueryClassName(hWnd, 99, tmpbuf);
-
-	/* These are the window classes which should get a menu */
-	if(strncmp(tmpbuf, "#2", 3)==0 ||  /* Combobox */
-	   strncmp(tmpbuf, "#6", 3)==0 ||  /* Entryfield */
-	   strncmp(tmpbuf, "#10", 4)==0 || /* MLE */
-	   strncmp(tmpbuf, "#32", 4)==0)   /* Spinbutton */
-	{
-		switch(msg)
-		{
-		case WM_CONTEXTMENU:
-			{
-				HMENUI hwndMenu = dw_menu_new(0L);
-				long x, y;
-
-				if(strncmp(tmpbuf, "#10", 4)==0 && !WinSendMsg(hWnd, MLM_QUERYREADONLY, 0, 0))
-				{
-					dw_menu_append_item(hwndMenu, "Undo", ENTRY_UNDO, 0L, TRUE, FALSE, 0L);
-					dw_menu_append_item(hwndMenu, "", 0L, 0L, TRUE, FALSE, 0L);
-				}
-				dw_menu_append_item(hwndMenu, "Copy", ENTRY_COPY, 0L, TRUE, FALSE, 0L);
-				if((strncmp(tmpbuf, "#10", 4)!=0  && !dw_window_get_data(hWnd, "_dw_disabled")) || (strncmp(tmpbuf, "#10", 4)==0 && !WinSendMsg(hWnd, MLM_QUERYREADONLY, 0, 0)))
-				{
-					dw_menu_append_item(hwndMenu, "Cut", ENTRY_CUT, 0L, TRUE, FALSE, 0L);
-					dw_menu_append_item(hwndMenu, "Paste", ENTRY_PASTE, 0L, TRUE, FALSE, 0L);
-				}
-				dw_menu_append_item(hwndMenu, "", 0L, 0L, TRUE, FALSE, 0L);
-				dw_menu_append_item(hwndMenu, "Select All", ENTRY_SALL, 0L, TRUE, FALSE, 0L);
-
-				WinSetFocus(HWND_DESKTOP, hWnd);
-				dw_pointer_query_pos(&x, &y);
-				dw_menu_popup(&hwndMenu, hWnd, x, y);
-			}
-			break;
-		case WM_COMMAND:
-			{
-				ULONG command = COMMANDMSG(&msg)->cmd;
-
-				/* MLE */
-				if(strncmp(tmpbuf, "#10", 4)==0)
-				{
-					switch(command)
-					{
-					case ENTRY_CUT:
-						return WinSendMsg(hWnd, MLM_CUT, 0, 0);
-					case ENTRY_COPY:
-						return WinSendMsg(hWnd, MLM_COPY, 0, 0);
-					case ENTRY_PASTE:
-						return WinSendMsg(hWnd, MLM_PASTE, 0, 0);
-					case ENTRY_UNDO:
-						return WinSendMsg(hWnd, MLM_UNDO, 0, 0);
-					case ENTRY_SALL:
-						{
-							ULONG len = (ULONG)WinSendMsg(hWnd, MLM_QUERYTEXTLENGTH, 0, 0);
-							return WinSendMsg(hWnd, MLM_SETSEL, 0, (MPARAM)len);
-						}
-					}
-				}
-				else /* Other */
-				{
-					HWND handle = hWnd;
-
-					/* Get the entryfield handle from multi window controls */
-					if(strncmp(tmpbuf, "#2", 3)==0)
-						handle = WinWindowFromID(hWnd, 667);
-
-					if(handle)
-					{
-						switch(command)
-						{
-						case ENTRY_CUT:
-							return WinSendMsg(handle, EM_CUT, 0, 0);
-						case ENTRY_COPY:
-							return WinSendMsg(handle, EM_COPY, 0, 0);
-						case ENTRY_PASTE:
-							return WinSendMsg(handle, EM_PASTE, 0, 0);
-						case ENTRY_SALL:
-							{
-								LONG len = WinQueryWindowTextLength(hWnd);
-								return WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT(0, (SHORT)len), 0);
-							}
-						}
-					}
-				}
-			}
-			break;
-		}
-	}
-
-	switch(msg)
-	{
-	case WM_BUTTON1DOWN:
-	case WM_BUTTON2DOWN:
-	case WM_BUTTON3DOWN:
-		{
-			if(strncmp(tmpbuf, "#32", 4)==0)
-				_run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE);
-		}
-		break;
-	case WM_CONTROL:
-		{
-			if(strncmp(tmpbuf, "#38", 4)==0)
-				_run_event(hWnd, msg, mp1, mp2);
-		}
-		break;
-	case WM_SETFOCUS:
-		_run_event(hWnd, msg, mp1, mp2);
-		break;
-	case WM_CHAR:
-		if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
-			return (MRESULT)TRUE;
-		if(SHORT1FROMMP(mp2) == '\t')
-		{
-			if(CHARMSG(&msg)->fs & KC_SHIFT)
-				_shift_focus_back(hWnd);
-			else
-				_shift_focus(hWnd);
-			return FALSE;
-		}
-		else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault)
-			_click_default(blah->clickdefault);
-		/* When you hit escape we get this value and the
-		 * window hangs for reasons unknown. (in an MLE)
-		 */
-		else if(SHORT1FROMMP(mp2) == 283)
-			return (MRESULT)TRUE;
-
-		break;
-	case WM_SIZE:
-		{
-			/* If it's a slider... make sure it shows the correct value */
-			if(strncmp(tmpbuf, "#38", 4)==0)
-				WinPostMsg(hWnd, WM_USER+7, 0, 0);
-		}
-		break;
-	case WM_USER+7:
-		{
-			int pos = (int)dw_window_get_data(hWnd, "_dw_slider_value");
-			WinSendMsg(hWnd, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)pos);
-		}
-		break;
-	case WM_MOUSEMOVE:
-		if(_wndproc(hWnd, msg, mp1, mp2))
-			return MPFROMSHORT(FALSE);
-		break;
-	}
-
-	if(oldproc)
-		return oldproc(hWnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
+   PFNWP oldproc = 0;
+   char tmpbuf[100];
+
+   if(blah)
+      oldproc = blah->oldproc;
+
+   WinQueryClassName(hWnd, 99, (PCH)tmpbuf);
+
+   /* These are the window classes which should get a menu */
+   if(strncmp(tmpbuf, "#2", 3)==0 ||  /* Combobox */
+      strncmp(tmpbuf, "#6", 3)==0 ||  /* Entryfield */
+      strncmp(tmpbuf, "#10", 4)==0 || /* MLE */
+      strncmp(tmpbuf, "#32", 4)==0)   /* Spinbutton */
+   {
+      switch(msg)
+      {
+      case WM_CONTEXTMENU:
+         {
+            HMENUI hwndMenu = dw_menu_new(0L);
+            long x, y;
+
+            if(strncmp(tmpbuf, "#10", 4)==0 && !WinSendMsg(hWnd, MLM_QUERYREADONLY, 0, 0))
+            {
+               dw_menu_append_item(hwndMenu, "Undo", ENTRY_UNDO, 0L, TRUE, -1, 0L);
+               dw_menu_append_item(hwndMenu, "", 0L, 0L, TRUE, -1, 0L);
+            }
+            dw_menu_append_item(hwndMenu, "Copy", ENTRY_COPY, 0L, TRUE, -1, 0L);
+            if((strncmp(tmpbuf, "#10", 4)!=0  && !dw_window_get_data(hWnd, "_dw_disabled")) || (strncmp(tmpbuf, "#10", 4)==0 && !WinSendMsg(hWnd, MLM_QUERYREADONLY, 0, 0)))
+            {
+               dw_menu_append_item(hwndMenu, "Cut", ENTRY_CUT, 0L, TRUE, -1, 0L);
+               dw_menu_append_item(hwndMenu, "Paste", ENTRY_PASTE, 0L, TRUE, -1, 0L);
+            }
+            dw_menu_append_item(hwndMenu, "", 0L, 0L, TRUE, -1, 0L);
+            dw_menu_append_item(hwndMenu, "Select All", ENTRY_SALL, 0L, TRUE, -1, 0L);
+
+            WinSetFocus(HWND_DESKTOP, hWnd);
+            dw_pointer_query_pos(&x, &y);
+            dw_menu_popup(&hwndMenu, hWnd, x, y);
+         }
+         break;
+      case WM_COMMAND:
+         {
+            ULONG command = COMMANDMSG(&msg)->cmd;
+
+            /* MLE */
+            if(strncmp(tmpbuf, "#10", 4)==0)
+            {
+               switch(command)
+               {
+               case ENTRY_CUT:
+                  return WinSendMsg(hWnd, MLM_CUT, 0, 0);
+               case ENTRY_COPY:
+                  return WinSendMsg(hWnd, MLM_COPY, 0, 0);
+               case ENTRY_PASTE:
+                  return WinSendMsg(hWnd, MLM_PASTE, 0, 0);
+               case ENTRY_UNDO:
+                  return WinSendMsg(hWnd, MLM_UNDO, 0, 0);
+               case ENTRY_SALL:
+                  {
+                     ULONG len = (ULONG)WinSendMsg(hWnd, MLM_QUERYTEXTLENGTH, 0, 0);
+                     return WinSendMsg(hWnd, MLM_SETSEL, 0, (MPARAM)len);
+                  }
+               }
+            }
+            else /* Other */
+            {
+               HWND handle = hWnd;
+
+               /* Get the entryfield handle from multi window controls */
+               if(strncmp(tmpbuf, "#2", 3)==0)
+                  handle = WinWindowFromID(hWnd, 667);
+
+               if(handle)
+               {
+                  switch(command)
+                  {
+                  case ENTRY_CUT:
+                     return WinSendMsg(handle, EM_CUT, 0, 0);
+                  case ENTRY_COPY:
+                     return WinSendMsg(handle, EM_COPY, 0, 0);
+                  case ENTRY_PASTE:
+                     return WinSendMsg(handle, EM_PASTE, 0, 0);
+                  case ENTRY_SALL:
+                     {
+                        LONG len = WinQueryWindowTextLength(hWnd);
+                        return WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT(0, (SHORT)len), 0);
+                     }
+                  }
+               }
+            }
+         }
+         break;
+      }
+   }
+
+   switch(msg)
+   {
+   case WM_BUTTON1DOWN:
+   case WM_BUTTON2DOWN:
+   case WM_BUTTON3DOWN:
+      {
+         if(strncmp(tmpbuf, "#32", 4)==0)
+            _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE);
+      }
+      break;
+   case WM_CONTROL:
+      {
+         if(strncmp(tmpbuf, "#38", 4)==0)
+            _run_event(hWnd, msg, mp1, mp2);
+      }
+      break;
+   case WM_SETFOCUS:
+      _run_event(hWnd, msg, mp1, mp2);
+      break;
+   case WM_CHAR:
+      if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
+         return (MRESULT)TRUE;
+      if(SHORT1FROMMP(mp2) == '\t')
+      {
+         if(CHARMSG(&msg)->fs & KC_SHIFT)
+            _shift_focus_back(hWnd);
+         else
+            _shift_focus(hWnd);
+         return FALSE;
+      }
+      else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault)
+         _click_default(blah->clickdefault);
+      /* When you hit escape we get this value and the
+       * window hangs for reasons unknown. (in an MLE)
+       */
+      else if(SHORT1FROMMP(mp2) == 283)
+         return (MRESULT)TRUE;
+
+      break;
+   case WM_SIZE:
+      {
+         /* If it's a slider... make sure it shows the correct value */
+         if(strncmp(tmpbuf, "#38", 4)==0)
+            WinPostMsg(hWnd, WM_USER+7, 0, 0);
+      }
+      break;
+   case WM_USER+7:
+      {
+         int pos = (int)dw_window_get_data(hWnd, "_dw_slider_value");
+         WinSendMsg(hWnd, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)pos);
+      }
+      break;
+   case WM_MOUSEMOVE:
+      if(_wndproc(hWnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   }
+
+   if(oldproc)
+      return oldproc(hWnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
 }
 
 /*  Deal with combobox specifics and enhancements */
 MRESULT EXPENTRY _comboentryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
-
-	switch(msg)
-	{
-	case WM_MOUSEMOVE:
-		if(_wndproc(hWnd, msg, mp1, mp2))
-			return MPFROMSHORT(FALSE);
-		break;
-	case WM_CONTEXTMENU:
-	case WM_COMMAND:
-		return _entryproc(hWnd, msg, mp1, mp2);
-	case WM_SETFOCUS:
-		_run_event(hWnd, msg, mp1, mp2);
-		break;
-	case WM_CHAR:
-		if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
-			return (MRESULT)TRUE;
-		/* A Similar problem to the MLE, if ESC just return */
-		if(SHORT1FROMMP(mp2) == 283)
-			return (MRESULT)TRUE;
-		break;
-	}
-
-	if(blah && blah->oldproc)
-		return blah->oldproc(hWnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
+
+   switch(msg)
+   {
+   case WM_MOUSEMOVE:
+      if(_wndproc(hWnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_CONTEXTMENU:
+   case WM_COMMAND:
+      return _entryproc(hWnd, msg, mp1, mp2);
+   case WM_SETFOCUS:
+      _run_event(hWnd, msg, mp1, mp2);
+      break;
+   case WM_CHAR:
+      if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
+         return (MRESULT)TRUE;
+      /* A Similar problem to the MLE, if ESC just return */
+      if(SHORT1FROMMP(mp2) == 283)
+         return (MRESULT)TRUE;
+      break;
+   }
+
+   if(blah && blah->oldproc)
+      return blah->oldproc(hWnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
 }
 
 /* Enhance the standard OS/2 MLE control */
 MRESULT EXPENTRY _mleproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	switch(msg)
-	{
-	case WM_VSCROLL:
-		if(SHORT2FROMMP(mp2) == SB_SLIDERTRACK)
-		{
-			USHORT pos = SHORT1FROMMP(mp2);
-
-			WinSendMsg(hWnd, msg, mp1, MPFROM2SHORT(pos, SB_SLIDERPOSITION));
-		}
-		break;
-	}
-	return _entryproc(hWnd, msg, mp1, mp2);
+   switch(msg)
+   {
+   case WM_VSCROLL:
+      if(SHORT2FROMMP(mp2) == SB_SLIDERTRACK)
+      {
+         USHORT pos = SHORT1FROMMP(mp2);
+
+         WinSendMsg(hWnd, msg, mp1, MPFROM2SHORT(pos, SB_SLIDERPOSITION));
+      }
+      break;
+   }
+   return _entryproc(hWnd, msg, mp1, mp2);
 }
 
 /* Handle special messages for the spinbutton's entryfield */
 MRESULT EXPENTRY _spinentryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
-	PFNWP oldproc = 0;
-
-	if(blah)
-		oldproc = blah->oldproc;
-
-	switch(msg)
-	{
-	case WM_MOUSEMOVE:
-		if(_wndproc(hWnd, msg, mp1, mp2))
-			return MPFROMSHORT(FALSE);
-		break;
-	case WM_CONTEXTMENU:
-	case WM_COMMAND:
-		return _entryproc(hWnd, msg, mp1, mp2);
-	}
-
-	if(oldproc)
-		return oldproc(hWnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
+   PFNWP oldproc = 0;
+
+   if(blah)
+      oldproc = blah->oldproc;
+
+   switch(msg)
+   {
+   case WM_MOUSEMOVE:
+      if(_wndproc(hWnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_CONTEXTMENU:
+   case WM_COMMAND:
+      return _entryproc(hWnd, msg, mp1, mp2);
+   }
+
+   if(oldproc)
+      return oldproc(hWnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
 }
 
 int _dw_int_pos(HWND hwnd)
 {
-	int pos = (int)dw_window_get_data(hwnd, "_dw_percent_value");
-	int range = _dw_percent_get_range(hwnd);
-	float fpos = (float)pos;
-	float frange = (float)range;
-	float fnew = (fpos/1000.0)*frange;
-	return (int)fnew;
+   int pos = (int)dw_window_get_data(hwnd, "_dw_percent_value");
+   int range = _dw_percent_get_range(hwnd);
+   float fpos = (float)pos;
+   float frange = (float)range;
+   float fnew = (fpos/1000.0)*frange;
+   return (int)fnew;
 }
 
 void _dw_int_set(HWND hwnd, int pos)
 {
-	int inew, range = _dw_percent_get_range(hwnd);
-	if(range)
-	{
-		float fpos = (float)pos;
-		float frange = (float)range;
-		float fnew = (fpos/frange)*1000.0;
-		inew = (int)fnew;
-		dw_window_set_data(hwnd, "_dw_percent_value", (void *)inew);
-	}
+   int inew, range = _dw_percent_get_range(hwnd);
+   if(range)
+   {
+      float fpos = (float)pos;
+      float frange = (float)range;
+      float fnew = (fpos/frange)*1000.0;
+      inew = (int)fnew;
+      dw_window_set_data(hwnd, "_dw_percent_value", (void *)inew);
+   }
 }
 
 /* Handle size changes in the percent class */
 MRESULT EXPENTRY _percentproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
-	PFNWP oldproc = 0;
-
-	if(blah)
-		oldproc = blah->oldproc;
-
-	switch(msg)
-	{
-	case WM_MOUSEMOVE:
-		if(_wndproc(hWnd, msg, mp1, mp2))
-			return MPFROMSHORT(FALSE);
-		break;
-	case WM_SIZE:
-		WinPostMsg(hWnd, WM_USER+7, 0, 0);
-		break;
-	case WM_USER+7:
-		WinSendMsg(hWnd, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)_dw_int_pos(hWnd));
-		break;
-	}
-
-	if(oldproc)
-		return oldproc(hWnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
+   PFNWP oldproc = 0;
+
+   if(blah)
+      oldproc = blah->oldproc;
+
+   switch(msg)
+   {
+   case WM_MOUSEMOVE:
+      if(_wndproc(hWnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_SIZE:
+      WinPostMsg(hWnd, WM_USER+7, 0, 0);
+      break;
+   case WM_USER+7:
+      WinSendMsg(hWnd, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)_dw_int_pos(hWnd));
+      break;
+   }
+
+   if(oldproc)
+      return oldproc(hWnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
 }
 
 /* Handle correct painting of a combobox with the WS_CLIPCHILDREN
@@ -1883,90 +2373,90 @@
  */
 MRESULT EXPENTRY _comboproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	WindowData *blah = WinQueryWindowPtr(hWnd, QWP_USER);
-	PFNWP oldproc = 0;
-
-	if(blah)
-		oldproc = blah->oldproc;
-
-	switch(msg)
-	{
-	case WM_MOUSEMOVE:
-		if(_wndproc(hWnd, msg, mp1, mp2))
-			return MPFROMSHORT(FALSE);
-		break;
-	case WM_CHAR:
-		if(SHORT1FROMMP(mp2) == '\t')
-		{
-			if(CHARMSG(&msg)->fs & KC_SHIFT)
-				_shift_focus_back(hWnd);
-			else
-				_shift_focus(hWnd);
-			return FALSE;
-		}
-		else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault)
-			_click_default(blah->clickdefault);
-		break;
-	case WM_BUTTON1DBLCLK:
-	case WM_BUTTON2DBLCLK:
-	case WM_BUTTON3DBLCLK:
-		if(dw_window_get_data(hWnd, "_dw_disabled"))
-			return (MRESULT)TRUE;
-		break;
-	case WM_BUTTON1DOWN:
-	case WM_BUTTON2DOWN:
-	case WM_BUTTON3DOWN:
-		if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
-			return (MRESULT)TRUE;
-		_run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE);
-		break;
-	case WM_SETFOCUS:
-		_run_event(hWnd, msg, mp1, mp2);
-		break;
-	case WM_PAINT:
-		{
-			HWND entry, frame = (HWND)dw_window_get_data(hWnd, "_dw_combo_box"), parent = WinQueryWindow(frame, QW_PARENT);
-			HPS hpsPaint;
-			POINTL ptl;
-			unsigned long width, height, thumbheight = 0;
-			ULONG color;
-
-			if((entry = (HWND)dw_window_get_data(hWnd, "_dw_comboentry")) != NULLHANDLE)
-				dw_window_get_pos_size(entry, 0, 0, 0, &thumbheight);
-
-			if(!thumbheight)
-				thumbheight = WinQuerySysValue(HWND_DESKTOP, SV_CYVSCROLLARROW);
-
-			/* Add 6 because it has a thick border like the entryfield */
-			thumbheight += 6;
-
-			color = (ULONG)dw_window_get_data(parent, "_dw_fore");
-			dw_window_get_pos_size(hWnd, 0, 0, &width, &height);
-
-			if(height > thumbheight)
-			{
-				hpsPaint = WinGetPS(hWnd);
-				if(color)
-					GpiSetColor(hpsPaint, _internal_color(color-1));
-				else
-					GpiSetColor(hpsPaint, CLR_PALEGRAY);
-
-				ptl.x = ptl.y = 0;
-				GpiMove(hpsPaint, &ptl);
-
-				ptl.x = width;
-				ptl.y = height - thumbheight;
-				GpiBox(hpsPaint, DRO_FILL, &ptl, 0, 0);
-
-				WinReleasePS(hpsPaint);
-			}
-		}
-		break;
-	}
-	if(oldproc)
-		return oldproc(hWnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
+   WindowData *blah = WinQueryWindowPtr(hWnd, QWP_USER);
+   PFNWP oldproc = 0;
+
+   if(blah)
+      oldproc = blah->oldproc;
+
+   switch(msg)
+   {
+   case WM_MOUSEMOVE:
+      if(_wndproc(hWnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_CHAR:
+      if(SHORT1FROMMP(mp2) == '\t')
+      {
+         if(CHARMSG(&msg)->fs & KC_SHIFT)
+            _shift_focus_back(hWnd);
+         else
+            _shift_focus(hWnd);
+         return FALSE;
+      }
+      else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault)
+         _click_default(blah->clickdefault);
+      break;
+   case WM_BUTTON1DBLCLK:
+   case WM_BUTTON2DBLCLK:
+   case WM_BUTTON3DBLCLK:
+      if(dw_window_get_data(hWnd, "_dw_disabled"))
+         return (MRESULT)TRUE;
+      break;
+   case WM_BUTTON1DOWN:
+   case WM_BUTTON2DOWN:
+   case WM_BUTTON3DOWN:
+      if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
+         return (MRESULT)TRUE;
+      _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE);
+      break;
+   case WM_SETFOCUS:
+      _run_event(hWnd, msg, mp1, mp2);
+      break;
+   case WM_PAINT:
+      {
+         HWND entry, frame = (HWND)dw_window_get_data(hWnd, "_dw_combo_box"), parent = WinQueryWindow(frame, QW_PARENT);
+         HPS hpsPaint;
+         POINTL ptl;
+         unsigned long width, height, thumbheight = 0;
+         ULONG color;
+
+         if((entry = (HWND)dw_window_get_data(hWnd, "_dw_comboentry")) != NULLHANDLE)
+            dw_window_get_pos_size(entry, 0, 0, 0, &thumbheight);
+
+         if(!thumbheight)
+            thumbheight = WinQuerySysValue(HWND_DESKTOP, SV_CYVSCROLLARROW);
+
+         /* Add 6 because it has a thick border like the entryfield */
+         thumbheight += 6;
+
+         color = (ULONG)dw_window_get_data(parent, "_dw_fore");
+         dw_window_get_pos_size(hWnd, 0, 0, &width, &height);
+
+         if(height > thumbheight)
+         {
+            hpsPaint = WinGetPS(hWnd);
+            if(color)
+               GpiSetColor(hpsPaint, _internal_color(color-1));
+            else
+               GpiSetColor(hpsPaint, CLR_PALEGRAY);
+
+            ptl.x = ptl.y = 0;
+            GpiMove(hpsPaint, &ptl);
+
+            ptl.x = width;
+            ptl.y = height - thumbheight;
+            GpiBox(hpsPaint, DRO_FILL, &ptl, 0, 0);
+
+            WinReleasePS(hpsPaint);
+         }
+      }
+      break;
+   }
+   if(oldproc)
+      return oldproc(hWnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
 }
 
 void _GetPPFont(HWND hwnd, char *buff)
@@ -1991,1044 +2481,1056 @@
 
 int _HandleScroller(HWND handle, int pos, int which)
 {
-	MPARAM res;
-	int min, max, page;
-
-	if(which == SB_SLIDERTRACK)
-		return pos;
-
-	pos = dw_scrollbar_get_pos(handle);
-	res = WinSendMsg(handle, SBM_QUERYRANGE, 0, 0);
-
-	min = SHORT1FROMMP(res);
-	max = SHORT2FROMMP(res);
-	page = (int)dw_window_get_data(handle, "_dw_scrollbar_visible");
-
-	switch(which)
-	{
-	case SB_LINEUP:
-		pos = pos - 1;
-		if(pos < min)
-			pos = min;
-		dw_scrollbar_set_pos(handle, pos);
-		return pos;
-	case SB_LINEDOWN:
-		pos = pos + 1;
-		if(pos > max)
-			pos = max;
-		dw_scrollbar_set_pos(handle, pos);
-		return pos;
-	case SB_PAGEUP:
-		pos = pos - page;
-		if(pos < min)
-			pos = min;
-		dw_scrollbar_set_pos(handle, pos);
-		return pos;
-	case SB_PAGEDOWN:
-		pos = pos + page;
-		if(pos > max)
-			pos = max;
-		dw_scrollbar_set_pos(handle, pos);
-		return pos;
-	}
-	return -1;
+   MPARAM res;
+   int min, max, page;
+
+   if(which == SB_SLIDERTRACK)
+      return pos;
+
+   pos = dw_scrollbar_get_pos(handle);
+   res = WinSendMsg(handle, SBM_QUERYRANGE, 0, 0);
+
+   min = SHORT1FROMMP(res);
+   max = SHORT2FROMMP(res);
+   page = (int)dw_window_get_data(handle, "_dw_scrollbar_visible");
+
+   switch(which)
+   {
+   case SB_LINEUP:
+      pos = pos - 1;
+      if(pos < min)
+         pos = min;
+      dw_scrollbar_set_pos(handle, pos);
+      return pos;
+   case SB_LINEDOWN:
+      pos = pos + 1;
+      if(pos > max)
+         pos = max;
+      dw_scrollbar_set_pos(handle, pos);
+      return pos;
+   case SB_PAGEUP:
+      pos = pos - page;
+      if(pos < min)
+         pos = min;
+      dw_scrollbar_set_pos(handle, pos);
+      return pos;
+   case SB_PAGEDOWN:
+      pos = pos + page;
+      if(pos > max)
+         pos = max;
+      dw_scrollbar_set_pos(handle, pos);
+      return pos;
+   }
+   return -1;
 }
 
 void _clear_emphasis(void)
 {
-	if(hwndEmph && WinIsWindow(dwhab, hwndEmph) && pCoreEmph)
-		WinSendMsg(hwndEmph, CM_SETRECORDEMPHASIS, pCoreEmph, MPFROM2SHORT(FALSE, CRA_SOURCE));
-	hwndEmph = NULLHANDLE;
-	pCoreEmph = NULL;
+   if(hwndEmph && WinIsWindow(dwhab, hwndEmph) && pCoreEmph)
+      WinSendMsg(hwndEmph, CM_SETRECORDEMPHASIS, pCoreEmph, MPFROM2SHORT(FALSE, CRA_SOURCE));
+   hwndEmph = NULLHANDLE;
+   pCoreEmph = NULL;
 }
 
 /* Find the desktop window handle */
 HWND _menu_owner(HWND handle)
 {
-	HWND menuowner = NULLHANDLE, lastowner = (HWND)dw_window_get_data(handle, "_dw_owner");
-	int menubar = (int)dw_window_get_data(handle, "_dw_menubar");
-
-	/* Find the toplevel window */
-	while(!menubar && (menuowner = (HWND)dw_window_get_data(lastowner, "_dw_owner")) != NULLHANDLE)
-	{
-		menubar = (int)dw_window_get_data(lastowner, "_dw_menubar");
-		lastowner = menuowner;
-	}
-	if(menuowner && menubar)
-	{
-		HWND client = WinWindowFromID(menuowner, FID_CLIENT);
-
-		return client ? client : menuowner;
-	}
-	return NULLHANDLE;
+   HWND menuowner = NULLHANDLE, lastowner = (HWND)dw_window_get_data(handle, "_dw_owner");
+   int menubar = (int)dw_window_get_data(handle, "_dw_menubar");
+
+   /* Find the toplevel window */
+   while(!menubar && (menuowner = (HWND)dw_window_get_data(lastowner, "_dw_owner")) != NULLHANDLE)
+   {
+      menubar = (int)dw_window_get_data(lastowner, "_dw_menubar");
+      lastowner = menuowner;
+   }
+   if(menuowner && menubar)
+   {
+      HWND client = WinWindowFromID(menuowner, FID_CLIENT);
+
+      return client ? client : menuowner;
+   }
+   return NULLHANDLE;
 }
 
 MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	int result = -1;
-	SignalHandler *tmp = Root;
-	ULONG origmsg = msg;
-
-	if(msg == WM_BUTTON2DOWN || msg == WM_BUTTON3DOWN)
-		msg = WM_BUTTON1DOWN;
-	if(msg == WM_BUTTON2UP || msg == WM_BUTTON3UP)
-		msg = WM_BUTTON1UP;
-	if(msg == WM_VSCROLL || msg == WM_HSCROLL)
-		msg = WM_CONTROL;
-
-	/* Find any callbacks for this function */
-	while(tmp)
-	{
-		if(tmp->message == msg || msg == WM_CONTROL || tmp->message == WM_USER+1)
-		{
-			switch(msg)
-			{
-			case WM_SETFOCUS:
-				{
-					if((mp2 && tmp->message == WM_SETFOCUS) || (!mp2 && tmp->message == WM_USER+1))
-					{
-						int (* API setfocusfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
-
-						if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd)
-						{
-							result = setfocusfunc(tmp->window, tmp->data);
-							tmp = NULL;
-						}
-					}
-				}
-				break;
-			case WM_TIMER:
-				{
-					int (* API timerfunc)(void *) = (int (* API)(void *))tmp->signalfunction;
-					if(tmp->id == (int)mp1)
-					{
-						if(!timerfunc(tmp->data))
-							dw_timer_disconnect(tmp->id);
-						tmp = NULL;
-					}
-					result = 0;
-				}
-				break;
-			case WM_SIZE:
-				{
-					int (* API sizefunc)(HWND, int, int, void *) = (int (* API)(HWND, int, int, void *))tmp->signalfunction;
-
-					if((hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd) && SHORT1FROMMP(mp2) && SHORT2FROMMP(mp2))
-					{
-						result = sizefunc(tmp->window, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), tmp->data);
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_BUTTON1DOWN:
-				{
-					POINTS pts = (*((POINTS*)&mp1));
-					int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
-
-					if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
-					{
-						int button = 0;
-
-						switch(origmsg)
-						{
-						case WM_BUTTON1DOWN:
-							button = 1;
-							break;
-						case WM_BUTTON2DOWN:
-							button = 2;
-							break;
-						case WM_BUTTON3DOWN:
-							button = 3;
-							break;
-						}
-
-						result = buttonfunc(tmp->window, pts.x, _get_frame_height(tmp->window) - pts.y, button, tmp->data);
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_BUTTON1UP:
-				{
-					POINTS pts = (*((POINTS*)&mp1));
-					int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
-
-					if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
-					{
-						int button = 0;
-
-						switch(origmsg)
-						{
-						case WM_BUTTON1UP:
-							button = 1;
-							break;
-						case WM_BUTTON2UP:
-							button = 2;
-							break;
-						case WM_BUTTON3UP:
-							button = 3;
-							break;
-						}
-
-						result = buttonfunc(tmp->window, pts.x, WinQueryWindow(tmp->window, QW_PARENT) == HWND_DESKTOP ? dw_screen_height() - pts.y : _get_height(tmp->window) - pts.y, button, tmp->data);
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_MOUSEMOVE:
-				{
-					int (* API motionfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
-
-					if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
-					{
-						int keys = 0;
-						SHORT x = SHORT1FROMMP(mp1), y = SHORT2FROMMP(mp1);
-
-						if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)
-							keys = DW_BUTTON1_MASK;
-						if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000)
-							keys |= DW_BUTTON2_MASK;
-						if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000)
-							keys |= DW_BUTTON3_MASK;
-
-						result = motionfunc(tmp->window, x, _get_frame_height(tmp->window) - y, keys, tmp->data);
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_CHAR:
-				{
-					int (* API keypressfunc)(HWND, char, int, int, void *) = (int (* API)(HWND, char, int, int, void *))tmp->signalfunction;
-
-					if((hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window) && !(SHORT1FROMMP(mp1) & KC_KEYUP))
-					{
-						int vk;
-						char ch = 0;
-
-						if(SHORT1FROMMP(mp1) & KC_CHAR)
-							ch = (char)SHORT1FROMMP(mp2);
-						if(SHORT1FROMMP(mp1) & KC_VIRTUALKEY)
-							vk = SHORT2FROMMP(mp2);
-						else
-							vk = SHORT1FROMMP(mp2) + 128;
-
-						/* This is a hack to fix shift presses showing
-						 * up as tabs!
-						 */
-						if(ch == '\t' && !(SHORT1FROMMP(mp1) & KC_CHAR))
-						{
-							ch = 0;
-							vk = VK_SHIFT;
-						}
-
-						result = keypressfunc(tmp->window, ch, vk,
-											  SHORT1FROMMP(mp1) & (KC_ALT | KC_SHIFT | KC_CTRL), tmp->data);
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_CLOSE:
-				{
-					int (* API closefunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
-
-					if(hWnd == tmp->window || hWnd == WinWindowFromID(tmp->window, FID_CLIENT))
-					{
-						result = closefunc(tmp->window, tmp->data);
-						if(result)
-							result = FALSE;
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_PAINT:
-				{
-					HPS hps;
-					DWExpose exp;
-					int (* API exposefunc)(HWND, DWExpose *, void *) = (int (* API)(HWND, DWExpose *, void *))tmp->signalfunction;
-					RECTL  rc;
-
-					if(hWnd == tmp->window)
-					{
-						int height = _get_height(hWnd);
-
-						hps = WinBeginPaint(hWnd, 0L, &rc);
-						exp.x = rc.xLeft;
-						exp.y = height - rc.yTop - 1;
-						exp.width = rc.xRight - rc. xLeft;
-						exp.height = rc.yTop - rc.yBottom;
-						result = exposefunc(hWnd, &exp, tmp->data);
-						WinEndPaint(hps);
-					}
-				}
-				break;
-			case WM_COMMAND:
-				{
-					int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
-					ULONG command = COMMANDMSG(&msg)->cmd;
-
-					if(tmp->id && command == tmp->id)
-					{
-						HWND menuowner = _menu_owner(tmp->window);
-
-						if(menuowner == hWnd || menuowner == NULLHANDLE)
-						{
-							result = clickfunc(tmp->window, tmp->data);
-							tmp = NULL;
-						}
-					}
-					else if(tmp->window < 65536 && command == tmp->window)
-					{
-						result = clickfunc(popup ?  popup : tmp->window, tmp->data);
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_CONTROL:
-				if(origmsg == WM_VSCROLL || origmsg == WM_HSCROLL || tmp->message == SHORT2FROMMP(mp1) ||
-				   (tmp->message == SLN_SLIDERTRACK && SHORT2FROMMP(mp1) == SLN_CHANGE))
-				{
-					int svar = SLN_SLIDERTRACK;
-					if(origmsg == WM_CONTROL)
-						svar = SHORT2FROMMP(mp1);
-
-					switch(svar)
-					{
-					case CN_ENTER:
-						{
-							int (* API containerselectfunc)(HWND, char *, void *) = (int (* API)(HWND, char *, void *))tmp->signalfunction;
-							int id = SHORT1FROMMP(mp1);
-							HWND conthwnd = dw_window_from_id(hWnd, id);
-							char *text = NULL;
-
-							if(mp2)
-							{
-								PRECORDCORE pre;
-
-								pre = ((PNOTIFYRECORDENTER)mp2)->pRecord;
-								if(pre)
-									text = pre->pszIcon;
-							}
-
-							if(tmp->window == conthwnd)
-							{
-								result = containerselectfunc(tmp->window, text, tmp->data);
-								tmp = NULL;
-							}
-						}
-						break;
-					case CN_EXPANDTREE:
-						{
-							int (* API treeexpandfunc)(HWND, HTREEITEM, void *) = (int (* API)(HWND, HTREEITEM, void *))tmp->signalfunction;
-							int id = SHORT1FROMMP(mp1);
-							HWND conthwnd = dw_window_from_id(hWnd, id);
-
-							if(tmp->window == conthwnd)
-							{
-								result = treeexpandfunc(tmp->window, (HTREEITEM)mp2, tmp->data);
-								tmp = NULL;
-							}
-						}
-						break;
-					case CN_CONTEXTMENU:
-						{
-							int (* API containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (* API)(HWND, char *, int, int, void *, void *))tmp->signalfunction;
-							int id = SHORT1FROMMP(mp1);
-							HWND conthwnd = dw_window_from_id(hWnd, id);
-							char *text = NULL;
-							void *user = NULL;
-							LONG x,y;
-
-							if(mp2)
-							{
-								PCNRITEM pci;
-
-								pci = (PCNRITEM)mp2;
-
-								text = pci->rc.pszIcon;
-								user = pci->user;
-							}
-
-							dw_pointer_query_pos(&x, &y);
-
-							if(tmp->window == conthwnd)
-							{
-								int container = (int)dw_window_get_data(tmp->window, "_dw_container");
-
-								if(mp2)
-								{
-									if(!container)
-									{
-										NOTIFYRECORDEMPHASIS pre;
-
-										dw_tree_item_select(tmp->window, (HTREEITEM)mp2);
-										pre.pRecord = mp2;
-										pre.fEmphasisMask = CRA_CURSORED;
-										pre.hwndCnr = tmp->window;
-										_run_event(hWnd, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre);
-										pre.pRecord->flRecordAttr |= CRA_CURSORED;
-									}
-									else
-									{
-										if(pCoreEmph)
-											_clear_emphasis();
-										hwndEmph = tmp->window;
-										pCoreEmph = mp2;
-										WinSendMsg(tmp->window, CM_SETRECORDEMPHASIS, mp2, MPFROM2SHORT(TRUE, CRA_SOURCE));
-									}
-								}
-								result = containercontextfunc(tmp->window, text, x, y, tmp->data, user);
-								tmp = NULL;
-							}
-						}
-						break;
-					case CN_EMPHASIS:
-						{
-							PNOTIFYRECORDEMPHASIS pre = (PNOTIFYRECORDEMPHASIS)mp2;
-							static int emph_recurse = 0;
-
-							if(!emph_recurse)
-							{
-								emph_recurse = 1;
-
-								if(mp2)
-								{
-									if(tmp->window == pre->hwndCnr)
-									{
-										PCNRITEM pci = (PCNRITEM)pre->pRecord;
-
-										if(pci && pre->fEmphasisMask & CRA_CURSORED && (pci->rc.flRecordAttr & CRA_CURSORED))
-										{
-											int (* API treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = (int (* API)(HWND, HTREEITEM, char *, void *, void *))tmp->signalfunction;
-
-											if(dw_window_get_data(tmp->window, "_dw_container"))
-												result = treeselectfunc(tmp->window, 0, pci->rc.pszIcon, tmp->data, 0);
-											else
-											{
-												if(lasthcnr == tmp->window && lastitem == (HWND)pci)
-												{
-													lasthcnr = 0;
-													lastitem = 0;
-												}
-												else
-												{
-													lasthcnr = tmp->window;
-													lastitem = (HWND)pci;
-													result = treeselectfunc(tmp->window, (HTREEITEM)pci, pci->rc.pszIcon, tmp->data, pci->user);
-												}
-											}
-											tmp = NULL;
-										}
-									}
-								}
-								emph_recurse = 0;
-							}
-						}
-						break;
-					case LN_SELECT:
-						{
-							char classbuf[100];
-
-							WinQueryClassName(tmp->window, 99, classbuf);
-
-							if(strncmp(classbuf, "#38", 4) == 0)
-							{
-								int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction;
-
-								if(tmp->window == hWnd || WinQueryWindow(tmp->window, QW_PARENT) == hWnd)
-								{
-									static int lastvalue = -1;
-									static HWND lasthwnd = NULLHANDLE;
-									int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
-									if(lastvalue != ulValue || lasthwnd != tmp->window)
-									{
-										result = valuechangedfunc(tmp->window, ulValue, tmp->data);
-										lastvalue = ulValue;
-										lasthwnd = tmp->window;
-									}
-									tmp = NULL;
-								}
-							}
-							else
-							{
-								int (* API listboxselectfunc)(HWND, int, void *) = (int (* API )(HWND, int, void *))tmp->signalfunction;
-								int id = SHORT1FROMMP(mp1);
-								HWND conthwnd = dw_window_from_id(hWnd, id);
-								static int _recursing = 0;
-
-								if(_recursing == 0 && (tmp->window == conthwnd || (!id && tmp->window == (HWND)mp2)))
-								{
-									char buf1[500];
-									unsigned int index = dw_listbox_selected(tmp->window);
-
-									dw_listbox_get_text(tmp->window, index, buf1, 500);
-
-									_recursing = 1;
-
-									if(id && strncmp(classbuf, "#2", 3)==0)
-									{
-										char *buf2;
-
-										buf2 = dw_window_get_text(tmp->window);
-
-										/* This is to make sure the listboxselect function doesn't
-										 * get called if the user is modifying the entry text.
-										 */
-										if(buf2 && *buf2 && *buf1 && strncmp(buf1, buf2, 500) == 0)
-											result = listboxselectfunc(tmp->window, index, tmp->data);
-
-										if(buf2)
-											free(buf2);
-									}
-									else
-										result = listboxselectfunc(tmp->window, index, tmp->data);
-
-									_recursing = 0;
-									tmp = NULL;
-								}
-							}
-						}
-						break;
-					case SLN_SLIDERTRACK:
-						{
-							int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction;
-
-							if(origmsg == WM_CONTROL)
-							{
-								/* Handle Slider control */
-								if(tmp->window == hWnd || WinQueryWindow(tmp->window, QW_PARENT) == hWnd)
-								{
-									static int lastvalue = -1;
-									static HWND lasthwnd = NULLHANDLE;
-									int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
-									if(lastvalue != ulValue || lasthwnd != tmp->window)
-									{
-										dw_window_set_data(tmp->window, "_dw_slider_value", (void *)ulValue);
-										result = valuechangedfunc(tmp->window, ulValue, tmp->data);
-										lastvalue = ulValue;
-										lasthwnd = tmp->window;
-									}
-									tmp = NULL;
-								}
-							}
-							else
-							{
-								/* Handle scrollbar control */
-								if(tmp->window > 65535 && tmp->window == WinWindowFromID(hWnd, (ULONG)mp1))
-								{
-									int pos = _HandleScroller(tmp->window, (int)SHORT1FROMMP(mp2), (int)SHORT2FROMMP(mp2));;
-
-									if(pos > -1)
-									{
-										dw_window_set_data(tmp->window, "_dw_scrollbar_value", (void *)pos);
-										result = valuechangedfunc(tmp->window, pos, tmp->data);
-									}
-									result = 0;
-									tmp = NULL;
-								}
-							}
-						}
-						break;
-					case BKN_PAGESELECTED:
-						{
-							PAGESELECTNOTIFY *psn = (PAGESELECTNOTIFY *)mp2;
-
-							if(psn && tmp->window == psn->hwndBook)
-							{
-								int (* API switchpagefunc)(HWND, unsigned long, void *) = (int (* API)(HWND, unsigned long, void *))tmp->signalfunction;
-
-								result = switchpagefunc(tmp->window, psn->ulPageIdNew, tmp->data);
-								tmp = NULL;
-							}
-						}
-						break;
-					}
-				}
-				break;
-			}
-		}
-
-		if(tmp)
-			tmp = tmp->next;
-
-	}
-	return (MRESULT)result;
+   int result = -1;
+   SignalHandler *tmp = Root;
+   ULONG origmsg = msg;
+
+   if(msg == WM_BUTTON2DOWN || msg == WM_BUTTON3DOWN)
+      msg = WM_BUTTON1DOWN;
+   if(msg == WM_BUTTON2UP || msg == WM_BUTTON3UP)
+      msg = WM_BUTTON1UP;
+   if(msg == WM_VSCROLL || msg == WM_HSCROLL)
+      msg = WM_CONTROL;
+
+   /* Find any callbacks for this function */
+   while(tmp)
+   {
+      if(tmp->message == msg || msg == WM_CONTROL || tmp->message == WM_USER+1)
+      {
+         switch(msg)
+         {
+         case WM_SETFOCUS:
+            {
+               if((mp2 && tmp->message == WM_SETFOCUS) || (!mp2 && tmp->message == WM_USER+1))
+               {
+                  int (* API setfocusfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
+
+                  if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd)
+                  {
+                     result = setfocusfunc(tmp->window, tmp->data);
+                     tmp = NULL;
+                  }
+               }
+            }
+            break;
+         case WM_TIMER:
+            {
+               int (* API timerfunc)(void *) = (int (* API)(void *))tmp->signalfunction;
+               if(tmp->id == (int)mp1)
+               {
+                  if(!timerfunc(tmp->data))
+                     dw_timer_disconnect(tmp->id);
+                  tmp = NULL;
+               }
+               result = 0;
+            }
+            break;
+         case WM_SIZE:
+            {
+               int (* API sizefunc)(HWND, int, int, void *) = (int (* API)(HWND, int, int, void *))tmp->signalfunction;
+
+               if((hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd) && SHORT1FROMMP(mp2) && SHORT2FROMMP(mp2))
+               {
+                  result = sizefunc(tmp->window, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), tmp->data);
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_BUTTON1DOWN:
+            {
+               POINTS pts = (*((POINTS*)&mp1));
+               int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
+
+               if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
+               {
+                  int button = 0;
+
+                  switch(origmsg)
+                  {
+                  case WM_BUTTON1DOWN:
+                     button = 1;
+                     break;
+                  case WM_BUTTON2DOWN:
+                     button = 2;
+                     break;
+                  case WM_BUTTON3DOWN:
+                     button = 3;
+                     break;
+                  }
+
+                  result = buttonfunc(tmp->window, pts.x, WinQueryWindow(tmp->window, QW_PARENT) == HWND_DESKTOP ? dw_screen_height() - pts.y : _get_height(tmp->window) - pts.y, button, tmp->data);
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_BUTTON1UP:
+            {
+               POINTS pts = (*((POINTS*)&mp1));
+               int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
+
+               if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
+               {
+                  int button = 0;
+
+                  switch(origmsg)
+                  {
+                  case WM_BUTTON1UP:
+                     button = 1;
+                     break;
+                  case WM_BUTTON2UP:
+                     button = 2;
+                     break;
+                  case WM_BUTTON3UP:
+                     button = 3;
+                     break;
+                  }
+
+                  result = buttonfunc(tmp->window, pts.x, WinQueryWindow(tmp->window, QW_PARENT) == HWND_DESKTOP ? dw_screen_height() - pts.y : _get_height(tmp->window) - pts.y, button, tmp->data);
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_MOUSEMOVE:
+            {
+               int (* API motionfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
+
+               if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
+               {
+                  int keys = 0;
+                  SHORT x = SHORT1FROMMP(mp1), y = SHORT2FROMMP(mp1);
+
+                  if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)
+                     keys = DW_BUTTON1_MASK;
+                  if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000)
+                     keys |= DW_BUTTON2_MASK;
+                  if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000)
+                     keys |= DW_BUTTON3_MASK;
+
+                  result = motionfunc(tmp->window, x, _get_height(hWnd) - y, keys, tmp->data);
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_CHAR:
+            {
+               int (* API keypressfunc)(HWND, char, int, int, void *) = (int (* API)(HWND, char, int, int, void *))tmp->signalfunction;
+
+               if((hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window) && !(SHORT1FROMMP(mp1) & KC_KEYUP))
+               {
+                  int vk;
+                  char ch = 0;
+
+                  if(SHORT1FROMMP(mp1) & KC_CHAR)
+                     ch = (char)SHORT1FROMMP(mp2);
+                  if(SHORT1FROMMP(mp1) & KC_VIRTUALKEY)
+                     vk = SHORT2FROMMP(mp2);
+                  else
+                     vk = SHORT1FROMMP(mp2) + 128;
+
+                  /* This is a hack to fix shift presses showing
+                   * up as tabs!
+                   */
+                  if(ch == '\t' && !(SHORT1FROMMP(mp1) & KC_CHAR))
+                  {
+                     ch = 0;
+                     vk = VK_SHIFT;
+                  }
+
+                  result = keypressfunc(tmp->window, ch, vk,
+                                   SHORT1FROMMP(mp1) & (KC_ALT | KC_SHIFT | KC_CTRL), tmp->data);
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_CLOSE:
+            {
+               int (* API closefunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
+
+               if(hWnd == tmp->window || hWnd == WinWindowFromID(tmp->window, FID_CLIENT))
+               {
+                  result = closefunc(tmp->window, tmp->data);
+                  if(result)
+                     result = FALSE;
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_PAINT:
+            {
+               HPS hps;
+               DWExpose exp;
+               int (* API exposefunc)(HWND, DWExpose *, void *) = (int (* API)(HWND, DWExpose *, void *))tmp->signalfunction;
+               RECTL  rc;
+
+               if(hWnd == tmp->window)
+               {
+                  int height = _get_height(hWnd);
+
+                  hps = WinBeginPaint(hWnd, 0L, &rc);
+                  exp.x = rc.xLeft;
+                  exp.y = height - rc.yTop - 1;
+                  exp.width = rc.xRight - rc. xLeft;
+                  exp.height = rc.yTop - rc.yBottom;
+                  result = exposefunc(hWnd, &exp, tmp->data);
+                  WinEndPaint(hps);
+               }
+            }
+            break;
+         case WM_COMMAND:
+            {
+               int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
+               ULONG command = COMMANDMSG(&msg)->cmd;
+
+               if(tmp->id && command == tmp->id)
+               {
+                  HWND menuowner = _menu_owner(tmp->window);
+
+                  if(menuowner == hWnd || menuowner == NULLHANDLE)
+                  {
+                     result = clickfunc((HWND)tmp->id, tmp->data);
+                     tmp = NULL;
+                  }
+               }
+               else if(tmp->window < 65536 && command == tmp->window)
+               {
+                  result = clickfunc(popup ?  popup : tmp->window, tmp->data);
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_CONTROL:
+            if(origmsg == WM_VSCROLL || origmsg == WM_HSCROLL || tmp->message == SHORT2FROMMP(mp1) ||
+               (tmp->message == SLN_SLIDERTRACK && SHORT2FROMMP(mp1) == SLN_CHANGE))
+            {
+               int svar = SLN_SLIDERTRACK;
+               int id = SHORT1FROMMP(mp1);
+               HWND notifyhwnd = dw_window_from_id(hWnd, id);
+
+               if(origmsg == WM_CONTROL)
+                  svar = SHORT2FROMMP(mp1);
+
+               switch(svar)
+               {
+               case CN_ENTER:
+                  {
+                     int (* API containerselectfunc)(HWND, char *, void *) = (int (* API)(HWND, char *, void *))tmp->signalfunction;
+                     char *text = NULL;
+
+                     if(mp2)
+                     {
+                        PRECORDCORE pre;
+
+                        pre = ((PNOTIFYRECORDENTER)mp2)->pRecord;
+                        if(pre)
+                           text = (char *)pre->pszIcon;
+                     }
+
+                     if(tmp->window == notifyhwnd)
+                     {
+                        result = containerselectfunc(tmp->window, text, tmp->data);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case CN_EXPANDTREE:
+                  {
+                     int (* API treeexpandfunc)(HWND, HTREEITEM, void *) = (int (* API)(HWND, HTREEITEM, void *))tmp->signalfunction;
+
+                     if(tmp->window == notifyhwnd)
+                     {
+                        result = treeexpandfunc(tmp->window, (HTREEITEM)mp2, tmp->data);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case CN_CONTEXTMENU:
+                  {
+                     int (* API containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (* API)(HWND, char *, int, int, void *, void *))tmp->signalfunction;
+                     char *text = NULL;
+                     void *user = NULL;
+                     LONG x,y;
+
+                     if(mp2)
+                     {
+                        PCNRITEM pci;
+
+                        pci = (PCNRITEM)mp2;
+
+                        text = (char *)pci->rc.pszIcon;
+                        user = pci->user;
+                     }
+
+                     dw_pointer_query_pos(&x, &y);
+
+                     if(tmp->window == notifyhwnd)
+                     {
+                        int container = (int)dw_window_get_data(tmp->window, "_dw_container");
+
+                        if(mp2)
+                        {
+                           if(!container)
+                           {
+                              NOTIFYRECORDEMPHASIS pre;
+
+                              dw_tree_item_select(tmp->window, (HTREEITEM)mp2);
+                              pre.pRecord = mp2;
+                              pre.fEmphasisMask = CRA_CURSORED;
+                              pre.hwndCnr = tmp->window;
+                              _run_event(hWnd, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre);
+                              pre.pRecord->flRecordAttr |= CRA_CURSORED;
+                           }
+                           else
+                           {
+                              if(pCoreEmph)
+                                 _clear_emphasis();
+                              hwndEmph = tmp->window;
+                              pCoreEmph = mp2;
+                              WinSendMsg(tmp->window, CM_SETRECORDEMPHASIS, mp2, MPFROM2SHORT(TRUE, CRA_SOURCE));
+                           }
+                        }
+                        result = containercontextfunc(tmp->window, text, x, y, tmp->data, user);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case CN_EMPHASIS:
+                  {
+                     PNOTIFYRECORDEMPHASIS pre = (PNOTIFYRECORDEMPHASIS)mp2;
+                     static int emph_recurse = 0;
+
+                     if(!emph_recurse)
+                     {
+                        emph_recurse = 1;
+
+                        if(mp2)
+                        {
+                           if(tmp->window == pre->hwndCnr)
+                           {
+                              PCNRITEM pci = (PCNRITEM)pre->pRecord;
+
+                              if(pci && pre->fEmphasisMask & CRA_CURSORED && (pci->rc.flRecordAttr & CRA_CURSORED))
+                              {
+                                 int (* API treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = (int (* API)(HWND, HTREEITEM, char *, void *, void *))tmp->signalfunction;
+
+                                 if(dw_window_get_data(tmp->window, "_dw_container"))
+                                    result = treeselectfunc(tmp->window, 0, (char *)pci->rc.pszIcon, tmp->data, 0);
+                                 else
+                                 {
+                                    if(lasthcnr == tmp->window && lastitem == (HWND)pci)
+                                    {
+                                       lasthcnr = 0;
+                                       lastitem = 0;
+                                    }
+                                    else
+                                    {
+                                       lasthcnr = tmp->window;
+                                       lastitem = (HWND)pci;
+                                       result = treeselectfunc(tmp->window, (HTREEITEM)pci, (char *)pci->rc.pszIcon, tmp->data, pci->user);
+                                    }
+                                 }
+                                 tmp = NULL;
+                              }
+                           }
+                        }
+                        emph_recurse = 0;
+                     }
+                  }
+                  break;
+               case LN_SELECT:
+                  {
+                     char classbuf[100];
+
+                     WinQueryClassName(tmp->window, 99, (PCH)classbuf);
+
+                     if(strncmp(classbuf, "#38", 4) == 0)
+                     {
+                        int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction;
+
+                        if(tmp->window == hWnd || tmp->window == notifyhwnd)
+                        {
+                           static int lastvalue = -1;
+                           static HWND lasthwnd = NULLHANDLE;
+                           int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
+                           if(lastvalue != ulValue || lasthwnd != tmp->window)
+                           {
+                              result = valuechangedfunc(tmp->window, ulValue, tmp->data);
+                              lastvalue = ulValue;
+                              lasthwnd = tmp->window;
+                           }
+                           tmp = NULL;
+                        }
+                     }
+                     else
+                     {
+                        int (* API listboxselectfunc)(HWND, int, void *) = (int (* API )(HWND, int, void *))tmp->signalfunction;
+                        static int _recursing = 0;
+
+                        if(_recursing == 0 && (tmp->window == notifyhwnd || (!id && tmp->window == (HWND)mp2)))
+                        {
+                           char buf1[500];
+                           int index = dw_listbox_selected(tmp->window);
+
+                           dw_listbox_get_text(tmp->window, index, buf1, 500);
+
+                           _recursing = 1;
+
+                           if(id && strncmp(classbuf, "#2", 3)==0)
+                           {
+                              char *buf2;
+
+                              buf2 = dw_window_get_text(tmp->window);
+
+                              /* This is to make sure the listboxselect function doesn't
+                               * get called if the user is modifying the entry text.
+                               */
+                              if(buf2 && *buf2 && *buf1 && strncmp(buf1, buf2, 500) == 0)
+                                 result = listboxselectfunc(tmp->window, index, tmp->data);
+
+                              if(buf2)
+                                 free(buf2);
+                           }
+                           else
+                              result = listboxselectfunc(tmp->window, index, tmp->data);
+
+                           _recursing = 0;
+                           tmp = NULL;
+                        }
+                     }
+                  }
+                  break;
+               case SLN_SLIDERTRACK:
+                  {
+                     int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction;
+
+                     if(origmsg == WM_CONTROL)
+                     {
+                        /* Handle Slider control */
+                        if(tmp->window == hWnd || tmp->window == notifyhwnd)
+                        {
+                           static int lastvalue = -1;
+                           static HWND lasthwnd = NULLHANDLE;
+                           int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
+                           if(lastvalue != ulValue || lasthwnd != tmp->window)
+                           {
+                              dw_window_set_data(tmp->window, "_dw_slider_value", (void *)ulValue);
+                              result = valuechangedfunc(tmp->window, ulValue, tmp->data);
+                              lastvalue = ulValue;
+                              lasthwnd = tmp->window;
+                           }
+                           tmp = NULL;
+                        }
+                     }
+                     else
+                     {
+                        /* Handle scrollbar control */
+                        if(tmp->window > 65535 && tmp->window == notifyhwnd)
+                        {
+                           int pos = _HandleScroller(tmp->window, (int)SHORT1FROMMP(mp2), (int)SHORT2FROMMP(mp2));;
+
+                           if(pos > -1)
+                           {
+                              dw_window_set_data(tmp->window, "_dw_scrollbar_value", (void *)pos);
+                              result = valuechangedfunc(tmp->window, pos, tmp->data);
+                           }
+                           result = 0;
+                           tmp = NULL;
+                        }
+                     }
+                  }
+                  break;
+               case BKN_PAGESELECTED:
+                  {
+                     PAGESELECTNOTIFY *psn = (PAGESELECTNOTIFY *)mp2;
+
+                     if(psn && tmp->window == psn->hwndBook)
+                     {
+                        int (* API switchpagefunc)(HWND, unsigned long, void *) = (int (* API)(HWND, unsigned long, void *))tmp->signalfunction;
+
+                        result = switchpagefunc(tmp->window, psn->ulPageIdNew, tmp->data);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               }
+            }
+            break;
+         }
+      }
+
+      if(tmp)
+         tmp = tmp->next;
+
+   }
+   return (MRESULT)result;
 }
 
 /* Gets a DW_RGB value from the three spinbuttons */
 unsigned long _dw_color_spin_get(HWND window)
 {
-	HWND button = (HWND)dw_window_get_data(window, "_dw_red_spin");
-	long red, green, blue;
-
-	red = dw_spinbutton_get_pos(button);
-	button = (HWND)dw_window_get_data(window, "_dw_green_spin");
-	green = dw_spinbutton_get_pos(button);
-	button = (HWND)dw_window_get_data(window, "_dw_blue_spin");
-	blue = dw_spinbutton_get_pos(button);
-
-	return DW_RGB(red, green, blue);
+   HWND button = (HWND)dw_window_get_data(window, "_dw_red_spin");
+   long red, green, blue;
+
+   red = dw_spinbutton_get_pos(button);
+   button = (HWND)dw_window_get_data(window, "_dw_green_spin");
+   green = dw_spinbutton_get_pos(button);
+   button = (HWND)dw_window_get_data(window, "_dw_blue_spin");
+   blue = dw_spinbutton_get_pos(button);
+
+   return DW_RGB(red, green, blue);
 }
 
 /* Set the three spinbuttons from a DW_RGB value */
 void _dw_color_spin_set(HWND window, unsigned long value)
 {
-	HWND button = (HWND)dw_window_get_data(window, "_dw_red_spin");
-	dw_window_set_data(window, "_dw_updating", (void *)1);
-	dw_spinbutton_set_pos(button, DW_RED_VALUE(value));
-	button = (HWND)dw_window_get_data(window, "_dw_green_spin");
-	dw_spinbutton_set_pos(button, DW_GREEN_VALUE(value));
-	button = (HWND)dw_window_get_data(window, "_dw_blue_spin");
-	dw_spinbutton_set_pos(button, DW_BLUE_VALUE(value));
-	dw_window_set_data(window, "_dw_updating", NULL);
+   HWND button = (HWND)dw_window_get_data(window, "_dw_red_spin");
+   dw_window_set_data(window, "_dw_updating", (void *)1);
+   dw_spinbutton_set_pos(button, DW_RED_VALUE(value));
+   button = (HWND)dw_window_get_data(window, "_dw_green_spin");
+   dw_spinbutton_set_pos(button, DW_GREEN_VALUE(value));
+   button = (HWND)dw_window_get_data(window, "_dw_blue_spin");
+   dw_spinbutton_set_pos(button, DW_BLUE_VALUE(value));
+   dw_window_set_data(window, "_dw_updating", NULL);
 }
 
 /* Sets the color selection control to be a DW_RGB value */
 void _dw_col_set(HWND col, unsigned long value)
 {
-	WinSendMsg(col, 0x0602, MPFROMLONG(_os2_color(value)), 0);
-	if(!IS_WARP4())
-		WinSendMsg(col, 0x1384, MPFROMLONG(_os2_color(value)), 0);
+   WinSendMsg(col, 0x0602, MPFROMLONG(_os2_color(value)), 0);
+   if(!IS_WARP4())
+      WinSendMsg(col, 0x1384, MPFROMLONG(_os2_color(value)), 0);
 }
 
 /* Handles control messages sent to the box (owner). */
 MRESULT EXPENTRY _controlproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	Box *blah = WinQueryWindowPtr(hWnd, QWP_USER);
-
-	switch(msg)
-	{
-	case WM_MOUSEMOVE:
-		if(_wndproc(hWnd, msg, mp1, mp2))
-			return MPFROMSHORT(FALSE);
-		break;
-	case WM_VSCROLL:
-	case WM_HSCROLL:
-		if(_run_event(hWnd, msg, mp1, mp2))
-		{
-			HWND window = WinWindowFromID(hWnd, (ULONG)mp1);
-			_HandleScroller(window, (int)SHORT1FROMMP(mp2), (int)SHORT2FROMMP(mp2));
-		}
-		break;
-		/* Handles Color Selection control messages */
-	case 0x0601:
-	case 0x130C:
-		{
-			HWND window = (HWND)dw_window_get_data(hWnd, "_dw_window");
-			unsigned long val = (unsigned long)mp1;
-
-			if(window)
-				_dw_color_spin_set(window, DW_RGB((val & 0xFF0000) >> 16, (val & 0xFF00) >> 8, val & 0xFF));
-		}
-		break;
-	case WM_CONTROL:
-		if((SHORT2FROMMP(mp1) == SPBN_CHANGE || SHORT2FROMMP(mp1) == SPBN_ENDSPIN))
-		{
-			HWND window = (HWND)dw_window_get_data(hWnd, "_dw_window");
-
-			if(window && !dw_window_get_data(window, "_dw_updating"))
-			{
-				unsigned long val = _dw_color_spin_get(window);
-				HWND col = (HWND)dw_window_get_data(window, "_dw_col");
-
-				_dw_col_set(col, val);
-			}
-		}
-		_run_event(hWnd, msg, mp1, mp2);
-		break;
-	}
-
-	if(blah && blah->oldproc)
-		return blah->oldproc(hWnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
+   Box *blah = WinQueryWindowPtr(hWnd, QWP_USER);
+
+   switch(msg)
+   {
+   case WM_MOUSEMOVE:
+      if(_wndproc(hWnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_VSCROLL:
+   case WM_HSCROLL:
+      if(_run_event(hWnd, msg, mp1, mp2))
+      {
+         HWND window = WinWindowFromID(hWnd, (ULONG)mp1);
+         _HandleScroller(window, (int)SHORT1FROMMP(mp2), (int)SHORT2FROMMP(mp2));
+      }
+      break;
+      /* Handles Color Selection control messages */
+   case 0x0601:
+   case 0x130C:
+      {
+         HWND window = (HWND)dw_window_get_data(hWnd, "_dw_window");
+         unsigned long val = (unsigned long)mp1;
+
+         if(window)
+            _dw_color_spin_set(window, DW_RGB((val & 0xFF0000) >> 16, (val & 0xFF00) >> 8, val & 0xFF));
+      }
+      break;
+   case WM_CONTROL:
+      if((SHORT2FROMMP(mp1) == SPBN_CHANGE || SHORT2FROMMP(mp1) == SPBN_ENDSPIN))
+      {
+         HWND window = (HWND)dw_window_get_data(hWnd, "_dw_window");
+
+         if(window && !dw_window_get_data(window, "_dw_updating"))
+         {
+            unsigned long val = _dw_color_spin_get(window);
+            HWND col = (HWND)dw_window_get_data(window, "_dw_col");
+
+            _dw_col_set(col, val);
+         }
+      }
+      _run_event(hWnd, msg, mp1, mp2);
+      break;
+   }
+
+   if(blah && blah->oldproc)
+      return blah->oldproc(hWnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
 }
 
 /* The main window procedure for Dynamic Windows, all the resizing code is done here. */
 MRESULT EXPENTRY _wndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	int result = -1;
-	static int command_active = 0;
-	void (* API windowfunc)(PVOID) = 0L;
-
-	if(!command_active)
-	{
+   int result = -1;
+   static int command_active = 0;
+   void (* API windowfunc)(PVOID) = 0L;
+
+   if(!command_active)
+   {
         /* Make sure we don't end up in infinite recursion */
-		command_active = 1;
-
-		result = (int)_run_event(hWnd, msg, mp1, mp2);
-
-		command_active = 0;
-	}
-
-	/* Now that any handlers are done... do normal processing */
-	switch( msg )
-	{
+      command_active = 1;
+
+      if(msg == WM_ACTIVATE)
+          result = (int)_run_event((HWND)mp2, WM_SETFOCUS, 0, mp1);
+      else
+          result = (int)_run_event(hWnd, msg, mp1, mp2);
+
+      command_active = 0;
+   }
+
+   /* Now that any handlers are done... do normal processing */
+   switch( msg )
+   {
    case WM_ERASEBACKGROUND:
       return 0;
 
-	case WM_PAINT:
-		{
-		HPS    hps;
-		RECTL  rc;
-
-		hps = WinBeginPaint( hWnd, 0L, &rc );
-		WinEndPaint( hps );
-		break;
-		}
-
-	case WM_SIZE:
-		{
-			Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER);
-
-			if(!SHORT1FROMMP(mp2) && !SHORT2FROMMP(mp2))
-				return (MPARAM)TRUE;
-
-			if(mybox && mybox->flags != DW_MINIMIZED)
-			{
-				/* Hide the window when recalculating to reduce
-				 * CPU load.
-				 */
-				WinShowWindow(hWnd, FALSE);
-
-                if(mybox->items)
-					WinSetWindowPos(mybox->items[0].hwnd, HWND_TOP, 0, 0, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SWP_MOVE | SWP_SIZE);
-
-				_do_resize(mybox, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));
-
-				WinShowWindow(hWnd, TRUE);
-			}
-		}
-		break;
-	case WM_MINMAXFRAME:
-		{
-			Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER);
-			SWP *swp = (SWP *)mp1;
-
-			if(mybox && (swp->fl & SWP_MINIMIZE))
-				mybox->flags = DW_MINIMIZED;
-
-			if(mybox && (swp->fl & SWP_RESTORE))
-			{
-				if(!mybox->titlebar && mybox->hwndtitle)
-					WinSetParent(mybox->hwndtitle, HWND_OBJECT, FALSE);
-				mybox->flags = 0;
-			}
-
-			if(mybox && (swp->fl & (SWP_MAXIMIZE | SWP_RESTORE)))
-			{
-				int z;
-				SWP swp2;
-
-				WinQueryWindowPos(swp->hwnd, &swp2);
-
-				if(swp2.cx == swp->cx && swp2.cy == swp->cy)
-					return FALSE;
-
-				mybox->flags = 0;
-
-				/* Hide the window when recalculating to reduce
-				 * CPU load.
-				 */
-				WinShowWindow(hWnd, FALSE);
-
-				_do_resize(mybox, swp->cx, swp->cy);
-
-				if(mybox->count == 1 && mybox->items[0].type == TYPEBOX)
-				{
-					mybox = (Box *)WinQueryWindowPtr(mybox->items[0].hwnd, QWP_USER);
-
-					for(z=0;z<mybox->count;z++)
-						_check_resize_notebook(mybox->items[z].hwnd);
-
-				}
-
-				WinShowWindow(hWnd, TRUE);
-			}
-		}
-		break;
-	case WM_CONTROL:
-		switch(SHORT2FROMMP(mp1))
-		{
-		case BKN_PAGESELECTEDPENDING:
-			{
-				PAGESELECTNOTIFY *psn = (PAGESELECTNOTIFY *)mp2;
-				HWND pagehwnd = (HWND)WinSendMsg(psn->hwndBook, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(psn->ulPageIdNew), 0);
-				Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER);
-				unsigned long x, y, width, height;
-				RECTL rc;
-
-				if(pagebox && psn->ulPageIdNew != psn->ulPageIdCur)
-				{
-					dw_window_get_pos_size(psn->hwndBook, &x, &y, &width, &height);
-
-					rc.xLeft = x;
-					rc.yBottom = y;
-					rc.xRight = x + width;
-					rc.yTop = y + height;
-
-					WinSendMsg(psn->hwndBook, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE);
-
-					_do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom);
-				}
-			}
-			break;
-		}
-		break;
-	case WM_CLOSE:
-		if(result == -1)
-		{
-			dw_window_destroy(WinQueryWindow(hWnd, QW_PARENT));
-			return (MRESULT)TRUE;
-		}
-		break;
-	case WM_MOUSEMOVE:
-		{
-			HPOINTER pointer;
-
-			if((pointer = (HPOINTER)dw_window_get_data(hWnd, "_dw_pointer")) ||
-			   (pointer = (HPOINTER)dw_window_get_data(_toplevel_window(hWnd), "_dw_pointer")))
-			{
-				WinSetPointer(HWND_DESKTOP, pointer);
-				return MRFROMSHORT(TRUE);
-			}
-		}
-		return MRFROMSHORT(FALSE);
-	case WM_USER:
-		windowfunc = (void (* API)(void *))mp1;
-
-		if(windowfunc)
-			windowfunc((void *)mp2);
-		break;
-	case WM_CHAR:
-		if(SHORT1FROMMP(mp2) == '\t')
-		{
-			if(CHARMSG(&msg)->fs & KC_SHIFT)
-				_shift_focus_back(hWnd);
-			else
-				_shift_focus(hWnd);
-			return FALSE;
-		}
-		break;
-	case WM_DESTROY:
-		{
-			HWND parent = WinQueryWindow(hWnd, QW_PARENT);
-
-			/* Free memory before destroying */
-			if(parent && WinWindowFromID(parent, FID_CLIENT) == hWnd)
-				_free_window_memory(parent);
-			else
-				_free_window_memory(hWnd);
-		}
-		break;
-	case WM_MENUEND:
-		/* Delay removing the signal until we've executed
-		 * the signal handler.
-		 */
-		WinPostMsg(hWnd, WM_USER+2, mp1, mp2);
-		break;
-	case WM_USER+2:
-		_clear_emphasis();
-		if(dw_window_get_data((HWND)mp2, "_dw_popup"))
-			_free_menu_data((HWND)mp2);
-		break;
-	}
-
-	if(result != -1)
-		return (MRESULT)result;
-	else
-		return WinDefWindowProc(hWnd, msg, mp1, mp2);
+   case WM_PAINT:
+      {
+      HPS    hps;
+      RECTL  rc;
+
+      hps = WinBeginPaint( hWnd, 0L, &rc );
+      WinEndPaint( hps );
+      break;
+      }
+
+   case WM_SIZE:
+      {
+         Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER);
+
+         if(!SHORT1FROMMP(mp2) && !SHORT2FROMMP(mp2))
+            return (MPARAM)TRUE;
+
+         if(mybox && mybox->flags != DW_MINIMIZED)
+         {
+            /* Hide the window when recalculating to reduce
+             * CPU load.
+             */
+            WinShowWindow(hWnd, FALSE);
+
+            if(mybox->items)
+                WinSetWindowPos(mybox->items[0].hwnd, HWND_TOP, 0, 0, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SWP_MOVE | SWP_SIZE);
+
+            _do_resize(mybox, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));
+
+            WinShowWindow(hWnd, TRUE);
+         }
+      }
+      break;
+   case WM_MINMAXFRAME:
+      {
+         Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER);
+         SWP *swp = (SWP *)mp1;
+
+         if(mybox && (swp->fl & SWP_MINIMIZE))
+            mybox->flags = DW_MINIMIZED;
+
+         if(mybox && (swp->fl & SWP_RESTORE))
+         {
+            if(!mybox->titlebar && mybox->hwndtitle)
+               WinSetParent(mybox->hwndtitle, HWND_OBJECT, FALSE);
+            mybox->flags = 0;
+         }
+
+         if(mybox && (swp->fl & (SWP_MAXIMIZE | SWP_RESTORE)))
+         {
+            int z;
+            SWP swp2;
+
+            WinQueryWindowPos(swp->hwnd, &swp2);
+
+            if(swp2.cx == swp->cx && swp2.cy == swp->cy)
+               return FALSE;
+
+            mybox->flags = 0;
+
+            /* Hide the window when recalculating to reduce
+             * CPU load.
+             */
+            WinShowWindow(hWnd, FALSE);
+
+            _do_resize(mybox, swp->cx, swp->cy);
+
+            if(mybox->count == 1 && mybox->items[0].type == TYPEBOX)
+            {
+               mybox = (Box *)WinQueryWindowPtr(mybox->items[0].hwnd, QWP_USER);
+
+               for(z=0;z<mybox->count;z++)
+                  _check_resize_notebook(mybox->items[z].hwnd);
+
+            }
+
+            WinShowWindow(hWnd, TRUE);
+         }
+      }
+      break;
+   case WM_CONTROL:
+      switch(SHORT2FROMMP(mp1))
+      {
+      case BKN_PAGESELECTEDPENDING:
+         {
+            PAGESELECTNOTIFY *psn = (PAGESELECTNOTIFY *)mp2;
+            HWND pagehwnd = (HWND)WinSendMsg(psn->hwndBook, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(psn->ulPageIdNew), 0);
+            Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER);
+            long x, y;
+            unsigned long width, height;
+            RECTL rc;
+
+            if(pagebox && psn->ulPageIdNew != psn->ulPageIdCur)
+            {
+               dw_window_get_pos_size(psn->hwndBook, &x, &y, &width, &height);
+
+               rc.xLeft = x;
+               rc.yBottom = y;
+               rc.xRight = x + width;
+               rc.yTop = y + height;
+
+               WinSendMsg(psn->hwndBook, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE);
+
+               _do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom);
+            }
+         }
+         break;
+      }
+      break;
+   case WM_CLOSE:
+      if(result == -1)
+      {
+         dw_window_destroy(WinQueryWindow(hWnd, QW_PARENT));
+         return (MRESULT)TRUE;
+      }
+      break;
+   case WM_MOUSEMOVE:
+      {
+         HPOINTER pointer;
+
+         if((pointer = (HPOINTER)dw_window_get_data(hWnd, "_dw_pointer")) ||
+            (pointer = (HPOINTER)dw_window_get_data(_toplevel_window(hWnd), "_dw_pointer")))
+         {
+            WinSetPointer(HWND_DESKTOP, pointer);
+            return MRFROMSHORT(TRUE);
+         }
+      }
+      return MRFROMSHORT(FALSE);
+   case WM_USER:
+      windowfunc = (void (* API)(void *))mp1;
+
+      if(windowfunc)
+         windowfunc((void *)mp2);
+      break;
+   case WM_CHAR:
+      if(SHORT1FROMMP(mp2) == '\t')
+      {
+         if(CHARMSG(&msg)->fs & KC_SHIFT)
+            _shift_focus_back(hWnd);
+         else
+            _shift_focus(hWnd);
+         return FALSE;
+      }
+      break;
+   case WM_DESTROY:
+      {
+         HWND parent = WinQueryWindow(hWnd, QW_PARENT);
+
+         /* Free memory before destroying */
+         if(parent && WinWindowFromID(parent, FID_CLIENT) == hWnd)
+            _free_window_memory(parent);
+         else
+            _free_window_memory(hWnd);
+      }
+      break;
+   case WM_MENUEND:
+      /* Delay removing the signal until we've executed
+       * the signal handler.
+       */
+      WinPostMsg(hWnd, WM_USER+2, mp1, mp2);
+      break;
+   case WM_DDE_INITIATEACK:
+       /* aswer dde server */
+       hwndTrayServer = (HWND)mp1;
+       break;
+   case WM_BUTTON1DOWN | 0x2000:
+   case WM_BUTTON2DOWN | 0x2000:
+   case WM_BUTTON3DOWN | 0x2000:
+   case WM_BUTTON1UP | 0x2000:
+   case WM_BUTTON2UP | 0x2000:
+   case WM_BUTTON3UP | 0x2000:
+       if(hwndTaskBar)
+           result = (int)_run_event(hwndTaskBar, msg & ~0x2000, mp1, mp2);
+       break;
+   case WM_USER+2:
+      _clear_emphasis();
+      if(dw_window_get_data((HWND)mp2, "_dw_popup"))
+         _free_menu_data((HWND)mp2);
+      break;
+   }
+
+   if(result != -1)
+      return (MRESULT)result;
+   else
+      return WinDefWindowProc(hWnd, msg, mp1, mp2);
 }
 
 void _changebox(Box *thisbox, int percent, int type)
 {
-	int z;
-
-	for(z=0;z<thisbox->count;z++)
-	{
-		if(thisbox->items[z].type == TYPEBOX)
-		{
-			Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
-			_changebox(tmp, percent, type);
-		}
-		else
-		{
-			if(type == DW_HORZ)
-			{
-				if(thisbox->items[z].hsize == SIZEEXPAND)
-					thisbox->items[z].width = (int)(((float)thisbox->items[z].origwidth) * (((float)percent)/((float)100.0)));
-			}
-			else
-			{
-				if(thisbox->items[z].vsize == SIZEEXPAND)
-					thisbox->items[z].height = (int)(((float)thisbox->items[z].origheight) * (((float)percent)/((float)100.0)));
-			}
-		}
-	}
+   int z;
+
+   for(z=0;z<thisbox->count;z++)
+   {
+      if(thisbox->items[z].type == TYPEBOX)
+      {
+         Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
+         _changebox(tmp, percent, type);
+      }
+      else
+      {
+         if(type == DW_HORZ)
+         {
+            if(thisbox->items[z].hsize == SIZEEXPAND)
+               thisbox->items[z].width = (int)(((float)thisbox->items[z].origwidth) * (((float)percent)/((float)100.0)));
+         }
+         else
+         {
+            if(thisbox->items[z].vsize == SIZEEXPAND)
+               thisbox->items[z].height = (int)(((float)thisbox->items[z].origheight) * (((float)percent)/((float)100.0)));
+         }
+      }
+   }
 }
 
 void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y)
 {
-	float ratio = (float)percent/(float)100.0;
-	HWND handle1 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
-	HWND handle2 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
-	Box *tmp = WinQueryWindowPtr(handle1, QWP_USER);
-
-	WinShowWindow(handle1, FALSE);
-	WinShowWindow(handle2, FALSE);
-
-	if(type == DW_HORZ)
-	{
-		int newx = (int)((float)x * ratio) - (SPLITBAR_WIDTH/2);
-
-		WinSetWindowPos(handle1, NULLHANDLE, 0, 0, newx, y, SWP_MOVE | SWP_SIZE);
-		_do_resize(tmp, newx - 1, y - 1);
-
-		dw_window_set_data(hwnd, "_dw_start", (void *)newx);
-
-		tmp = WinQueryWindowPtr(handle2, QWP_USER);
-
-		newx = x - newx - SPLITBAR_WIDTH;
-
-		WinSetWindowPos(handle2, NULLHANDLE, x - newx, 0, newx, y, SWP_MOVE | SWP_SIZE);
-		_do_resize(tmp, newx - 1, y - 1);
-	}
-	else
-	{
-		int newy = (int)((float)y * ratio) - (SPLITBAR_WIDTH/2);
-
-		WinSetWindowPos(handle1, NULLHANDLE, 0, y - newy, x, newy, SWP_MOVE | SWP_SIZE);
-		_do_resize(tmp, x - 1, newy - 1);
-
-		tmp = WinQueryWindowPtr(handle2, QWP_USER);
-
-		newy = y - newy - SPLITBAR_WIDTH;
-
-		WinSetWindowPos(handle2, NULLHANDLE, 0, 0, x, newy, SWP_MOVE | SWP_SIZE);
-		_do_resize(tmp, x - 1, newy - 1);
-
-		dw_window_set_data(hwnd, "_dw_start", (void *)newy);
-	}
-
-	WinShowWindow(handle1, TRUE);
-	WinShowWindow(handle2, TRUE);
+   float ratio = (float)percent/(float)100.0;
+   HWND handle1 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
+   HWND handle2 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
+   Box *tmp = WinQueryWindowPtr(handle1, QWP_USER);
+
+   WinShowWindow(handle1, FALSE);
+   WinShowWindow(handle2, FALSE);
+
+   if(type == DW_HORZ)
+   {
+      int newx = (int)((float)x * ratio) - (SPLITBAR_WIDTH/2);
+
+      WinSetWindowPos(handle1, NULLHANDLE, 0, 0, newx, y, SWP_MOVE | SWP_SIZE);
+      _do_resize(tmp, newx - 1, y - 1);
+
+      dw_window_set_data(hwnd, "_dw_start", (void *)newx);
+
+      tmp = WinQueryWindowPtr(handle2, QWP_USER);
+
+      newx = x - newx - SPLITBAR_WIDTH;
+
+      WinSetWindowPos(handle2, NULLHANDLE, x - newx, 0, newx, y, SWP_MOVE | SWP_SIZE);
+      _do_resize(tmp, newx - 1, y - 1);
+   }
+   else
+   {
+      int newy = (int)((float)y * ratio) - (SPLITBAR_WIDTH/2);
+
+      WinSetWindowPos(handle1, NULLHANDLE, 0, y - newy, x, newy, SWP_MOVE | SWP_SIZE);
+      _do_resize(tmp, x - 1, newy - 1);
+
+      tmp = WinQueryWindowPtr(handle2, QWP_USER);
+
+      newy = y - newy - SPLITBAR_WIDTH;
+
+      WinSetWindowPos(handle2, NULLHANDLE, 0, 0, x, newy, SWP_MOVE | SWP_SIZE);
+      _do_resize(tmp, x - 1, newy - 1);
+
+      dw_window_set_data(hwnd, "_dw_start", (void *)newy);
+   }
+
+   WinShowWindow(handle1, TRUE);
+   WinShowWindow(handle2, TRUE);
 }
 
 
 /* This handles any activity on the splitbars (sizers) */
 MRESULT EXPENTRY _splitwndproc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	switch (msg)
-	{
-	case WM_ACTIVATE:
-	case WM_SETFOCUS:
-		return (MRESULT)(FALSE);
-
-	case WM_PAINT:
-		{
-			HPS hps;
-			POINTL ptl[2];
-			RECTL rcl;
-			int type = (int)dw_window_get_data(hwnd, "_dw_type");
-			int start = (int)dw_window_get_data(hwnd, "_dw_start");
-
-			hps = WinBeginPaint(hwnd, 0, 0);
-
-			WinQueryWindowRect(hwnd, &rcl);
-
-			if(type == DW_HORZ)
-			{
-				ptl[0].x = rcl.xLeft + start;
-				ptl[0].y = rcl.yBottom;
-				ptl[1].x = rcl.xRight + start + 3;
-				ptl[1].y = rcl.yTop;
-			}
-			else
-			{
-				ptl[0].x = rcl.xLeft;
-				ptl[0].y = rcl.yBottom + start;
-				ptl[1].x = rcl.xRight;
-				ptl[1].y = rcl.yTop + start + 3;
-			}
-
-
-			GpiSetColor(hps, CLR_PALEGRAY);
-			GpiMove(hps, &ptl[0]);
-			GpiBox(hps, DRO_OUTLINEFILL, &ptl[1], 0, 0);
-			WinEndPaint(hps);
-		}
-		return MRFROMSHORT(FALSE);
-
-	case WM_MOUSEMOVE:
-		{
-			int type = (int)dw_window_get_data(hwnd, "_dw_type");
-
-			if(type == DW_HORZ)
-				WinSetPointer(HWND_DESKTOP,
-							  WinQuerySysPointer(HWND_DESKTOP,
-												 SPTR_SIZEWE,
-												 FALSE));
-			else
-				WinSetPointer(HWND_DESKTOP,
-							  WinQuerySysPointer(HWND_DESKTOP,
-												 SPTR_SIZENS,
-												 FALSE));
-		}
-		return MRFROMSHORT(FALSE);
-	case WM_BUTTON1DOWN:
-		{
-			APIRET rc;
-			RECTL  rclFrame;
-			RECTL  rclBounds;
-			float *percent = (float *)dw_window_get_data(hwnd, "_dw_percent");
-			int type = (int)dw_window_get_data(hwnd, "_dw_type");
-			int start = (int)dw_window_get_data(hwnd, "_dw_start");
-
-			WinQueryWindowRect(hwnd, &rclFrame);
-			WinQueryWindowRect(hwnd, &rclBounds);
-
-			WinMapWindowPoints(hwnd, HWND_DESKTOP,
-							   (PPOINTL)&rclBounds, 2);
-
-
-			if(type == DW_HORZ)
-			{
-				rclFrame.xLeft = start;
-				rclFrame.xRight = start + SPLITBAR_WIDTH;
-			}
-			else
-			{
-				rclFrame.yBottom = start;
-				rclFrame.yTop = start + SPLITBAR_WIDTH;
-			}
-
-			if(percent)
-			{
-				rc = _TrackRectangle(hwnd, &rclFrame, &rclBounds);
-
-				if(rc == TRUE)
-				{
-					int width = (rclBounds.xRight - rclBounds.xLeft);
-					int height = (rclBounds.yTop - rclBounds.yBottom);
-
-					if(type == DW_HORZ)
-					{
-						start = rclFrame.xLeft - rclBounds.xLeft;
-						if(width - SPLITBAR_WIDTH > 1 && start < width - SPLITBAR_WIDTH)
-							*percent = ((float)start / (float)(width - SPLITBAR_WIDTH)) * 100.0;
-					}
-					else
-					{
-						start = rclFrame.yBottom - rclBounds.yBottom;
-						if(height - SPLITBAR_WIDTH > 1 && start < height - SPLITBAR_WIDTH)
-							*percent = 100.0 - (((float)start / (float)(height - SPLITBAR_WIDTH)) * 100.0);
-					}
-					_handle_splitbar_resize(hwnd, *percent, type, width, height);
-					_handle_splitbar_resize(hwnd, *percent, type, width, height);
-				}
-			}
-		}
-		return MRFROMSHORT(FALSE);
-	}
-	return WinDefWindowProc(hwnd, msg, mp1, mp2);
+   switch (msg)
+   {
+   case WM_ACTIVATE:
+   case WM_SETFOCUS:
+      return (MRESULT)(FALSE);
+
+   case WM_PAINT:
+      {
+         HPS hps;
+         POINTL ptl[2];
+         RECTL rcl;
+         int type = (int)dw_window_get_data(hwnd, "_dw_type");
+         int start = (int)dw_window_get_data(hwnd, "_dw_start");
+
+         hps = WinBeginPaint(hwnd, 0, 0);
+
+         WinQueryWindowRect(hwnd, &rcl);
+
+         if(type == DW_HORZ)
+         {
+            ptl[0].x = rcl.xLeft + start;
+            ptl[0].y = rcl.yBottom;
+            ptl[1].x = rcl.xRight + start + 3;
+            ptl[1].y = rcl.yTop;
+         }
+         else
+         {
+            ptl[0].x = rcl.xLeft;
+            ptl[0].y = rcl.yBottom + start;
+            ptl[1].x = rcl.xRight;
+            ptl[1].y = rcl.yTop + start + 3;
+         }
+
+
+         GpiSetColor(hps, CLR_PALEGRAY);
+         GpiMove(hps, &ptl[0]);
+         GpiBox(hps, DRO_OUTLINEFILL, &ptl[1], 0, 0);
+         WinEndPaint(hps);
+      }
+      return MRFROMSHORT(FALSE);
+
+   case WM_MOUSEMOVE:
+      {
+         int type = (int)dw_window_get_data(hwnd, "_dw_type");
+
+         if(type == DW_HORZ)
+            WinSetPointer(HWND_DESKTOP,
+                       WinQuerySysPointer(HWND_DESKTOP,
+                                     SPTR_SIZEWE,
+                                     FALSE));
+         else
+            WinSetPointer(HWND_DESKTOP,
+                       WinQuerySysPointer(HWND_DESKTOP,
+                                     SPTR_SIZENS,
+                                     FALSE));
+      }
+      return MRFROMSHORT(FALSE);
+   case WM_BUTTON1DOWN:
+      {
+         APIRET rc;
+         RECTL  rclFrame;
+         RECTL  rclBounds;
+         float *percent = (float *)dw_window_get_data(hwnd, "_dw_percent");
+         int type = (int)dw_window_get_data(hwnd, "_dw_type");
+         int start = (int)dw_window_get_data(hwnd, "_dw_start");
+
+         WinQueryWindowRect(hwnd, &rclFrame);
+         WinQueryWindowRect(hwnd, &rclBounds);
+
+         WinMapWindowPoints(hwnd, HWND_DESKTOP,
+                        (PPOINTL)&rclBounds, 2);
+
+
+         if(type == DW_HORZ)
+         {
+            rclFrame.xLeft = start;
+            rclFrame.xRight = start + SPLITBAR_WIDTH;
+         }
+         else
+         {
+            rclFrame.yBottom = start;
+            rclFrame.yTop = start + SPLITBAR_WIDTH;
+         }
+
+         if(percent)
+         {
+            rc = _TrackRectangle(hwnd, &rclFrame, &rclBounds);
+
+            if(rc == TRUE)
+            {
+               int width = (rclBounds.xRight - rclBounds.xLeft);
+               int height = (rclBounds.yTop - rclBounds.yBottom);
+
+               if(type == DW_HORZ)
+               {
+                  start = rclFrame.xLeft - rclBounds.xLeft;
+                  if(width - SPLITBAR_WIDTH > 1 && start < width - SPLITBAR_WIDTH)
+                     *percent = ((float)start / (float)(width - SPLITBAR_WIDTH)) * 100.0;
+               }
+               else
+               {
+                  start = rclFrame.yBottom - rclBounds.yBottom;
+                  if(height - SPLITBAR_WIDTH > 1 && start < height - SPLITBAR_WIDTH)
+                     *percent = 100.0 - (((float)start / (float)(height - SPLITBAR_WIDTH)) * 100.0);
+               }
+               _handle_splitbar_resize(hwnd, *percent, type, width, height);
+               _handle_splitbar_resize(hwnd, *percent, type, width, height);
+            }
+         }
+      }
+      return MRFROMSHORT(FALSE);
+   }
+   return WinDefWindowProc(hwnd, msg, mp1, mp2);
 }
 
 /* Function: BubbleProc
@@ -3036,124 +3538,124 @@
  */
 MRESULT EXPENTRY _BubbleProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	MRESULT res;
-	PFNWP proc = (PFNWP)WinQueryWindowPtr(hwnd, QWL_USER);
-
-	if(proc)
-		res = proc(hwnd, msg, mp1, mp2);
-	else
-		res = WinDefWindowProc(hwnd, msg, mp1, mp2);
-
-	if(msg == WM_PAINT)
-	{
-		POINTL ptl;
-		HPS hpsTemp;
-		RECTL rcl;
-		int height, width;
-
-		WinQueryWindowRect(hwnd, &rcl);
-		height = rcl.yTop - rcl.yBottom - 1;
-		width = rcl.xRight - rcl.xLeft - 1;
-
-		/* Draw a border around the bubble help */
-		hpsTemp = WinGetPS(hwnd);
-		GpiSetColor(hpsTemp, CLR_BLACK);
-		ptl.x = ptl.y = 0;
-		GpiMove(hpsTemp, &ptl);
-		ptl.x = 0;
-		ptl.y = height;
-		GpiLine(hpsTemp, &ptl);
-		ptl.x = ptl.y = 0;
-		GpiMove(hpsTemp, &ptl);
-		ptl.y = 0;
-		ptl.x = width;
-		GpiLine(hpsTemp, &ptl);
-		ptl.x = width;
-		ptl.y = height;
-		GpiMove(hpsTemp, &ptl);
-		ptl.x = 0;
-		ptl.y = height;
-		GpiLine(hpsTemp, &ptl);
-		ptl.x = width;
-		ptl.y = height;
-		GpiMove(hpsTemp, &ptl);
-		ptl.y = 0;
-		ptl.x = width;
-		GpiLine(hpsTemp, &ptl);
-		WinReleasePS(hpsTemp);
-	}
-	return res;
+   MRESULT res;
+   PFNWP proc = (PFNWP)WinQueryWindowPtr(hwnd, QWL_USER);
+
+   if(proc)
+      res = proc(hwnd, msg, mp1, mp2);
+   else
+      res = WinDefWindowProc(hwnd, msg, mp1, mp2);
+
+   if(msg == WM_PAINT)
+   {
+      POINTL ptl;
+      HPS hpsTemp;
+      RECTL rcl;
+      int height, width;
+
+      WinQueryWindowRect(hwnd, &rcl);
+      height = rcl.yTop - rcl.yBottom - 1;
+      width = rcl.xRight - rcl.xLeft - 1;
+
+      /* Draw a border around the bubble help */
+      hpsTemp = WinGetPS(hwnd);
+      GpiSetColor(hpsTemp, CLR_BLACK);
+      ptl.x = ptl.y = 0;
+      GpiMove(hpsTemp, &ptl);
+      ptl.x = 0;
+      ptl.y = height;
+      GpiLine(hpsTemp, &ptl);
+      ptl.x = ptl.y = 0;
+      GpiMove(hpsTemp, &ptl);
+      ptl.y = 0;
+      ptl.x = width;
+      GpiLine(hpsTemp, &ptl);
+      ptl.x = width;
+      ptl.y = height;
+      GpiMove(hpsTemp, &ptl);
+      ptl.x = 0;
+      ptl.y = height;
+      GpiLine(hpsTemp, &ptl);
+      ptl.x = width;
+      ptl.y = height;
+      GpiMove(hpsTemp, &ptl);
+      ptl.y = 0;
+      ptl.x = width;
+      GpiLine(hpsTemp, &ptl);
+      WinReleasePS(hpsTemp);
+   }
+   return res;
 }
 
 MRESULT EXPENTRY _button_draw(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2, PFNWP oldproc, int indent)
 {
-	HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(hwnd, "_dw_hpixmap");
-	HPIXMAP disable = (HPIXMAP)dw_window_get_data(hwnd, "_dw_hpixmap_disabled");
-	HPOINTER icon = (HPOINTER)dw_window_get_data(hwnd, "_dw_button_icon");
-	MRESULT res;
-	unsigned long width, height;
-	int x = 5, y = 5;
-
-	dw_window_get_pos_size(hwnd, NULL, NULL, &width, &height);
-
-	if(!oldproc)
-		res = WinDefWindowProc(hwnd, msg, mp1, mp2);
-	res = oldproc(hwnd, msg, mp1, mp2);
-
-	if(icon)
-	{
-		ULONG halftone = DP_NORMAL;
-		HPS hps = WinGetPS(hwnd);
-		POINTERINFO pi;
-		int cx, cy;
-
-		if(dw_window_get_data(hwnd, "_dw_disabled"))
-			halftone = DP_HALFTONED;
-
-		cx = width - 10;
-		cy = height - 10;
-
-		if(WinQueryPointerInfo(icon, &pi))
-		{
-			BITMAPINFOHEADER sl;
-			int newcx = cx, newcy = cy;
-
-			/* Check the mini icon first */
-			if(GpiQueryBitmapParameters(pi.hbmMiniColor, &sl))
-			{
-				if(sl.cx && sl.cy && cx > sl.cx && cy > sl.cy)
-				{
-					newcx = sl.cx;
-					newcy = sl.cy;
-				}
-			}
-			/* Check the normal icon second */
-			if(GpiQueryBitmapParameters(pi.hbmColor, &sl))
-			{
-				if(sl.cx && sl.cy && cx > sl.cx && cy > sl.cy)
-				{
-					newcx = sl.cx;
-					newcy = sl.cy;
-				}
-			}
-			cx = newcx; cy = newcy;
-			x = (width - cx)/2;
-			y = (height - cy)/2;
-		}
-		WinStretchPointer(hps, x + indent, y - indent, cx, cy, icon, halftone);
-		WinReleasePS(hps);
-	}
-	else if(pixmap)
-	{
-		x = (width - pixmap->width)/2;
-		y = (height - pixmap->height)/2;
-
-		if(disable && dw_window_get_data(hwnd, "_dw_disabled"))
-			dw_pixmap_bitblt(hwnd, 0, x + indent, y + indent, pixmap->width, pixmap->height, 0, disable, 0, 0);
-		else
-			dw_pixmap_bitblt(hwnd, 0, x + indent, y + indent, pixmap->width, pixmap->height, 0, pixmap, 0, 0);
-	}
-	return res;
+   HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(hwnd, "_dw_hpixmap");
+   HPIXMAP disable = (HPIXMAP)dw_window_get_data(hwnd, "_dw_hpixmap_disabled");
+   HPOINTER icon = (HPOINTER)dw_window_get_data(hwnd, "_dw_button_icon");
+   MRESULT res;
+   unsigned long width, height;
+   int x = 5, y = 5;
+
+   dw_window_get_pos_size(hwnd, NULL, NULL, &width, &height);
+
+   if(!oldproc)
+      res = WinDefWindowProc(hwnd, msg, mp1, mp2);
+   res = oldproc(hwnd, msg, mp1, mp2);
+
+   if(icon)
+   {
+      ULONG halftone = DP_NORMAL;
+      HPS hps = WinGetPS(hwnd);
+      POINTERINFO pi;
+      int cx, cy;
+
+      if(dw_window_get_data(hwnd, "_dw_disabled"))
+         halftone = DP_HALFTONED;
+
+      cx = width - 10;
+      cy = height - 10;
+
+      if(WinQueryPointerInfo(icon, &pi))
+      {
+         BITMAPINFOHEADER sl;
+         int newcx = cx, newcy = cy;
+
+         /* Check the mini icon first */
+         if(GpiQueryBitmapParameters(pi.hbmMiniColor, &sl))
+         {
+            if(sl.cx && sl.cy && cx > sl.cx && cy > sl.cy)
+            {
+               newcx = sl.cx;
+               newcy = sl.cy;
+            }
+         }
+         /* Check the normal icon second */
+         if(GpiQueryBitmapParameters(pi.hbmColor, &sl))
+         {
+            if(sl.cx && sl.cy && cx > sl.cx && cy > sl.cy)
+            {
+               newcx = sl.cx;
+               newcy = sl.cy;
+            }
+         }
+         cx = newcx; cy = newcy;
+         x = (width - cx)/2;
+         y = (height - cy)/2;
+      }
+      WinStretchPointer(hps, x + indent, y - indent, cx, cy, icon, halftone);
+      WinReleasePS(hps);
+   }
+   else if(pixmap)
+   {
+      x = (width - pixmap->width)/2;
+      y = (height - pixmap->height)/2;
+
+      if(disable && dw_window_get_data(hwnd, "_dw_disabled"))
+         dw_pixmap_bitblt(hwnd, 0, x + indent, y + indent, pixmap->width, pixmap->height, 0, disable, 0, 0);
+      else
+         dw_pixmap_bitblt(hwnd, 0, x + indent, y + indent, pixmap->width, pixmap->height, 0, pixmap, 0, 0);
+   }
+   return res;
 }
 
 /* Function: BtProc
@@ -3162,304 +3664,314 @@
 
 MRESULT EXPENTRY _BtProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	BubbleButton *bubble;
-	PFNWP oldproc;
-
-	bubble = (BubbleButton *)WinQueryWindowPtr(hwnd, QWL_USER);
-
-	if(!bubble)
-		return WinDefWindowProc(hwnd, msg, mp1, mp2);
-
-	oldproc = bubble->pOldProc;
-
-	switch(msg)
-	{
-	case WM_MOUSEMOVE:
-		if(_wndproc(hwnd, msg, mp1, mp2))
-			return MPFROMSHORT(FALSE);
-		break;
-	case WM_PAINT:
-		return _button_draw(hwnd, msg, mp1, mp2, oldproc, 0);
-	case BM_SETHILITE:
-		return _button_draw(hwnd, msg, mp1, mp2, oldproc, (int)mp1);
-	case WM_SETFOCUS:
-		if(mp2)
-			_run_event(hwnd, msg, mp1, mp2);
-		else
-			WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0);
-		break;
-	case WM_BUTTON1DOWN:
-	case WM_BUTTON2DOWN:
-	case WM_BUTTON3DOWN:
-	case WM_BUTTON1DBLCLK:
-	case WM_BUTTON2DBLCLK:
-	case WM_BUTTON3DBLCLK:
-		if(dw_window_get_data(hwnd, "_dw_disabled"))
-			return (MRESULT)FALSE;
-		break;
-	case WM_BUTTON1UP:
-		{
-			SignalHandler *tmp = Root;
-
-			if(WinIsWindowEnabled(hwnd) && !dw_window_get_data(hwnd, "_dw_disabled"))
-			{
-				/* Find any callbacks for this function */
-				while(tmp)
-				{
-					if(tmp->message == WM_COMMAND)
-					{
-						/* Make sure it's the right window, and the right ID */
-						if(tmp->window == hwnd)
-						{
-							/* Due to the fact that if we run the function
-							 * here, finishing actions on the button will occur
-							 * after we run the signal handler.  So we post the
-							 * message so the button can finish what it needs to
-							 * do before we run our handler.
-							 */
-							WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0);
-							tmp = NULL;
-						}
-					}
-					if(tmp)
-						tmp= tmp->next;
-				}
-			}
-		}
-		break;
-	case WM_USER:
-		{
+   BubbleButton *bubble;
+   PFNWP oldproc;
+
+   bubble = (BubbleButton *)WinQueryWindowPtr(hwnd, QWL_USER);
+
+   if(!bubble)
+      return WinDefWindowProc(hwnd, msg, mp1, mp2);
+
+   oldproc = bubble->pOldProc;
+
+   switch(msg)
+   {
+   case WM_MOUSEMOVE:
+      if(_wndproc(hwnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_PAINT:
+      return _button_draw(hwnd, msg, mp1, mp2, oldproc, 0);
+   case BM_SETHILITE:
+      return _button_draw(hwnd, msg, mp1, mp2, oldproc, (int)mp1);
+   case WM_SETFOCUS:
+      if(mp2)
+         _run_event(hwnd, msg, mp1, mp2);
+      else
+          WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0);
+      /*  FIX: Borderless buttons not displaying properly after gaining focus */
+      if((WinQueryWindowULong(hwnd, QWL_STYLE) & BS_NOBORDER))
+      {
+          RECTL rcl;
+
+          WinQueryWindowRect(hwnd, &rcl);
+
+          WinInvalidateRect(hwnd, &rcl, FALSE);
+          WinPostMsg(hwnd, WM_PAINT, 0, 0);
+      }
+      break;
+   case WM_BUTTON1DOWN:
+   case WM_BUTTON2DOWN:
+   case WM_BUTTON3DOWN:
+   case WM_BUTTON1DBLCLK:
+   case WM_BUTTON2DBLCLK:
+   case WM_BUTTON3DBLCLK:
+      if(dw_window_get_data(hwnd, "_dw_disabled"))
+         return (MRESULT)FALSE;
+      break;
+   case WM_BUTTON1UP:
+      {
+         SignalHandler *tmp = Root;
+
+         if(WinIsWindowEnabled(hwnd) && !dw_window_get_data(hwnd, "_dw_disabled"))
+         {
+            /* Find any callbacks for this function */
+            while(tmp)
+            {
+               if(tmp->message == WM_COMMAND)
+               {
+                  /* Make sure it's the right window, and the right ID */
+                  if(tmp->window == hwnd)
+                  {
+                     /* Due to the fact that if we run the function
+                      * here, finishing actions on the button will occur
+                      * after we run the signal handler.  So we post the
+                      * message so the button can finish what it needs to
+                      * do before we run our handler.
+                      */
+                     WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0);
+                     tmp = NULL;
+                  }
+               }
+               if(tmp)
+                  tmp= tmp->next;
+            }
+         }
+      }
+      break;
+   case WM_USER:
+      {
             SignalHandler *tmp = (SignalHandler *)mp1;
-			int (* API clickfunc)(HWND, void *) = NULL;
-
-			if(tmp)
-			{
-				clickfunc = (int (* API)(HWND, void *))tmp->signalfunction;
-
-				clickfunc(tmp->window, tmp->data);
-			}
-		}
+         int (* API clickfunc)(HWND, void *) = NULL;
+
+         if(tmp)
+         {
+            clickfunc = (int (* API)(HWND, void *))tmp->signalfunction;
+
+            clickfunc(tmp->window, tmp->data);
+         }
+      }
         break;
-	case WM_CHAR:
-		{
-			/* A button press should also occur for an ENTER or SPACE press
-			 * while the button has the active input focus.
-			 */
-			if(SHORT1FROMMP(mp2) == '\r' || SHORT1FROMMP(mp2) == ' ')
-			{
-				SignalHandler *tmp = Root;
-
-				/* Find any callbacks for this function */
-				while(tmp)
-				{
-					if(tmp->message == WM_COMMAND)
-					{
-						/* Make sure it's the right window, and the right ID */
-						if(tmp->window == hwnd)
-						{
-							WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0);
-							tmp = NULL;
-						}
-					}
-					if(tmp)
-						tmp= tmp->next;
-				}
-			}
-			if(SHORT1FROMMP(mp2) == '\t')
-			{
-				if(CHARMSG(&msg)->fs & KC_SHIFT)
-					_shift_focus_back(hwnd);
-				else
-					_shift_focus(hwnd);
-				WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0);
-				return FALSE;
-			}
-			else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_LEFT || CHARMSG(&msg)->vkey == VK_UP))
-			{
-				_shift_focus_back(hwnd);
-				return FALSE;
-			}
-			else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_RIGHT || CHARMSG(&msg)->vkey == VK_DOWN))
-			{
-				_shift_focus(hwnd);
-				return FALSE;
-			}
-		}
-		break;
-	case 0x041f:
-		if (hwndBubble)
-		{
-			WinDestroyWindow(hwndBubble);
-			hwndBubble = 0;
-		}
-		break;
-
-	case 0x041e:
-
-		if(!*bubble->bubbletext)
-			break;
-
-		if(hwndBubble)
-		{
-			WinDestroyWindow(hwndBubble);
-			hwndBubble = 0;
-		}
-
-		if(!hwndBubble)
-		{
-			HPS   hpsTemp = 0;
-			LONG  lHight;
-			LONG  lWidth;
-			POINTL txtPointl[TXTBOX_COUNT];
-			POINTL ptlWork = {0,0};
-			ULONG ulColor = CLR_YELLOW;
-			void *blah;
-
-			hwndBubbleLast   = hwnd;
-			hwndBubble = WinCreateWindow(HWND_DESKTOP,
-										 WC_STATIC,
-										 "",
-										 SS_TEXT |
-										 DT_CENTER |
-										 DT_VCENTER,
+   case WM_CHAR:
+      {
+         /* A button press should also occur for an ENTER or SPACE press
+          * while the button has the active input focus.
+          */
+         if(SHORT1FROMMP(mp2) == '\r' || SHORT1FROMMP(mp2) == ' ')
+         {
+            SignalHandler *tmp = Root;
+
+            /* Find any callbacks for this function */
+            while(tmp)
+            {
+               if(tmp->message == WM_COMMAND)
+               {
+                  /* Make sure it's the right window, and the right ID */
+                  if(tmp->window == hwnd)
+                  {
+                     WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0);
+                     tmp = NULL;
+                  }
+               }
+               if(tmp)
+                  tmp= tmp->next;
+            }
+         }
+         if(SHORT1FROMMP(mp2) == '\t')
+         {
+            if(CHARMSG(&msg)->fs & KC_SHIFT)
+               _shift_focus_back(hwnd);
+            else
+               _shift_focus(hwnd);
+            WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0);
+            return FALSE;
+         }
+         else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_LEFT || CHARMSG(&msg)->vkey == VK_UP))
+         {
+            _shift_focus_back(hwnd);
+            return FALSE;
+         }
+         else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_RIGHT || CHARMSG(&msg)->vkey == VK_DOWN))
+         {
+            _shift_focus(hwnd);
+            return FALSE;
+         }
+      }
+      break;
+   case 0x041f:
+      if (hwndBubble)
+      {
+         WinDestroyWindow(hwndBubble);
+         hwndBubble = 0;
+      }
+      break;
+
+   case 0x041e:
+
+      if(!*bubble->bubbletext)
+         break;
+
+      if(hwndBubble)
+      {
+         WinDestroyWindow(hwndBubble);
+         hwndBubble = 0;
+      }
+
+      if(!hwndBubble)
+      {
+         HPS   hpsTemp = 0;
+         LONG  lHight;
+         LONG  lWidth;
+         POINTL txtPointl[TXTBOX_COUNT];
+         POINTL ptlWork = {0,0};
+         ULONG ulColor = CLR_YELLOW;
+         void *blah;
+
+         hwndBubbleLast   = hwnd;
+         hwndBubble = WinCreateWindow(HWND_DESKTOP,
+                               WC_STATIC,
+                               NULL,
+                               SS_TEXT |
+                               DT_CENTER |
+                               DT_VCENTER,
                                          0,0,0,0,
-										 HWND_DESKTOP,
-										 HWND_TOP,
-										 0,
-										 NULL,
-										 NULL);
-
-			WinSetPresParam(hwndBubble,
-							PP_FONTNAMESIZE,
-							strlen(DefaultFont)+1,
-							DefaultFont);
-
-
-			WinSetPresParam(hwndBubble,
-							PP_BACKGROUNDCOLORINDEX,
-							sizeof(ulColor),
-							&ulColor);
-
-			WinSetWindowText(hwndBubble,
-							 bubble->bubbletext);
-
-			WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptlWork, 1);
-
-			hpsTemp = WinGetPS(hwndBubble);
-			GpiQueryTextBox(hpsTemp,
-							strlen(bubble->bubbletext),
-							bubble->bubbletext,
-							TXTBOX_COUNT,
-							txtPointl);
-			WinReleasePS(hpsTemp);
-
-			lWidth = txtPointl[TXTBOX_TOPRIGHT].x -
-				txtPointl[TXTBOX_TOPLEFT ].x + 8;
-
-			lHight = txtPointl[TXTBOX_TOPLEFT].y -
-				txtPointl[TXTBOX_BOTTOMLEFT].y + 8;
-
-			ptlWork.y -= lHight;
-
-			blah = (void *)WinSubclassWindow(hwndBubble, _BubbleProc);
-
-			if(blah)
-				WinSetWindowPtr(hwndBubble, QWP_USER, blah);
-
-			WinSetWindowPos(hwndBubble,
-							HWND_TOP,
-							ptlWork.x,
-							ptlWork.y,
-							lWidth,
-							lHight,
-							SWP_SIZE | SWP_MOVE | SWP_SHOW);
-		}
-		break;
-	}
-
-	if(!oldproc)
-		return WinDefWindowProc(hwnd, msg, mp1, mp2);
-	return oldproc(hwnd, msg, mp1, mp2);
+                               HWND_DESKTOP,
+                               HWND_TOP,
+                               0,
+                               NULL,
+                               NULL);
+
+         WinSetPresParam(hwndBubble,
+                     PP_FONTNAMESIZE,
+                     strlen(DefaultFont)+1,
+                     DefaultFont);
+
+
+         WinSetPresParam(hwndBubble,
+                     PP_BACKGROUNDCOLORINDEX,
+                     sizeof(ulColor),
+                     &ulColor);
+
+         WinSetWindowText(hwndBubble,
+                      (PSZ)bubble->bubbletext);
+
+         WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptlWork, 1);
+
+         hpsTemp = WinGetPS(hwndBubble);
+         GpiQueryTextBox(hpsTemp,
+                     strlen(bubble->bubbletext),
+                     (PCH)bubble->bubbletext,
+                     TXTBOX_COUNT,
+                     txtPointl);
+         WinReleasePS(hpsTemp);
+
+         lWidth = txtPointl[TXTBOX_TOPRIGHT].x -
+            txtPointl[TXTBOX_TOPLEFT ].x + 8;
+
+         lHight = txtPointl[TXTBOX_TOPLEFT].y -
+            txtPointl[TXTBOX_BOTTOMLEFT].y + 8;
+
+         ptlWork.y -= lHight;
+
+         blah = (void *)WinSubclassWindow(hwndBubble, _BubbleProc);
+
+         if(blah)
+            WinSetWindowPtr(hwndBubble, QWP_USER, blah);
+
+         WinSetWindowPos(hwndBubble,
+                     HWND_TOP,
+                     ptlWork.x,
+                     ptlWork.y,
+                     lWidth,
+                     lHight,
+                     SWP_SIZE | SWP_MOVE | SWP_SHOW);
+      }
+      break;
+   }
+
+   if(!oldproc)
+      return WinDefWindowProc(hwnd, msg, mp1, mp2);
+   return oldproc(hwnd, msg, mp1, mp2);
 }
 
 MRESULT EXPENTRY _RendProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	int res = 0;
-	res = (int)_run_event(hwnd, msg, mp1, mp2);
-	switch(msg)
-	{
-	case WM_MOUSEMOVE:
-		if(_wndproc(hwnd, msg, mp1, mp2))
-			return MPFROMSHORT(FALSE);
-		break;
-	case WM_BUTTON1DOWN:
-	case WM_BUTTON2DOWN:
-	case WM_BUTTON3DOWN:
-		if(res == -1)
-			WinSetFocus(HWND_DESKTOP, hwnd);
-		else if(res)
-			return (MPARAM)TRUE;
-	}
-	return WinDefWindowProc(hwnd, msg, mp1, mp2);
+   int res = 0;
+   res = (int)_run_event(hwnd, msg, mp1, mp2);
+   switch(msg)
+   {
+   case WM_MOUSEMOVE:
+      if(_wndproc(hwnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_BUTTON1DOWN:
+   case WM_BUTTON2DOWN:
+   case WM_BUTTON3DOWN:
+      if(res == -1)
+          WinSetFocus(HWND_DESKTOP, hwnd);
+      else if(res)
+         return (MPARAM)TRUE;
+   }
+   return WinDefWindowProc(hwnd, msg, mp1, mp2);
 }
 
 MRESULT EXPENTRY _TreeProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(hwnd, QWP_USER);
-	PFNWP oldproc = 0;
-
-	if(blah)
-		oldproc = blah->oldproc;
-
-	switch(msg)
-	{
-	case WM_MOUSEMOVE:
-		if(_wndproc(hwnd, msg, mp1, mp2))
-			return MPFROMSHORT(FALSE);
-		break;
-	case WM_PAINT:
-		{
-			HPS hps;
-			RECTL rcl;
-			POINTL ptl[2];
-
-			if(oldproc)
-				oldproc(hwnd, msg, mp1, mp2);
-
-			hps = WinBeginPaint(hwnd, 0, 0);
-			WinQueryWindowRect(hwnd, &rcl);
-			ptl[0].x = rcl.xLeft + 1;
-			ptl[0].y = rcl.yBottom + 1;
-			ptl[1].x = rcl.xRight - 1;
-			ptl[1].y = rcl.yTop - 1;
-
-			GpiSetColor(hps, CLR_BLACK);
-			GpiMove(hps, &ptl[0]);
-			GpiBox(hps, DRO_OUTLINE, &ptl[1], 0, 0);
-			WinEndPaint(hps);
-		}
-		return MRFROMSHORT(FALSE);
-	case WM_SETFOCUS:
-		_run_event(hwnd, msg, mp1, mp2);
-		break;
-	case WM_CHAR:
-		if(SHORT1FROMMP(mp2) == '\t')
-		{
-			if(CHARMSG(&msg)->fs & KC_SHIFT)
-				_shift_focus_back(hwnd);
-			else
-				_shift_focus(hwnd);
-			return FALSE;
-		}
-		break;
-	}
-
-	_run_event(hwnd, msg, mp1, mp2);
-
-	if(oldproc)
-		return oldproc(hwnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hwnd, msg, mp1, mp2);
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(hwnd, QWP_USER);
+   PFNWP oldproc = 0;
+
+   if(blah)
+      oldproc = blah->oldproc;
+
+   switch(msg)
+   {
+   case WM_MOUSEMOVE:
+      if(_wndproc(hwnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_PAINT:
+      {
+         HPS hps;
+         RECTL rcl;
+         POINTL ptl[2];
+
+         if(oldproc)
+            oldproc(hwnd, msg, mp1, mp2);
+
+         hps = WinBeginPaint(hwnd, 0, 0);
+         WinQueryWindowRect(hwnd, &rcl);
+         ptl[0].x = rcl.xLeft + 1;
+         ptl[0].y = rcl.yBottom + 1;
+         ptl[1].x = rcl.xRight - 1;
+         ptl[1].y = rcl.yTop - 1;
+
+         GpiSetColor(hps, CLR_BLACK);
+         GpiMove(hps, &ptl[0]);
+         GpiBox(hps, DRO_OUTLINE, &ptl[1], 0, 0);
+         WinEndPaint(hps);
+      }
+      return MRFROMSHORT(FALSE);
+   case WM_SETFOCUS:
+      _run_event(hwnd, msg, mp1, mp2);
+      break;
+   case WM_CHAR:
+      if(SHORT1FROMMP(mp2) == '\t')
+      {
+         if(CHARMSG(&msg)->fs & KC_SHIFT)
+            _shift_focus_back(hwnd);
+         else
+            _shift_focus(hwnd);
+         return FALSE;
+      }
+      break;
+   }
+
+   _run_event(hwnd, msg, mp1, mp2);
+
+   if(oldproc)
+      return oldproc(hwnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hwnd, msg, mp1, mp2);
 }
 
 /*
@@ -3470,35 +3982,43 @@
  */
 int API dw_init(int newthread, int argc, char *argv[])
 {
-	APIRET rc;
-	char objnamebuf[300] = "";
-
-	argc = argc; /* keep compiler happy */
-	argv = argv; /* keep compiler happy */
-	if(newthread)
-	{
-		dwhab = WinInitialize(0);
-		dwhmq = WinCreateMsgQueue(dwhab, 0);
-	}
-
-	rc = WinRegisterClass(dwhab, ClassName, _wndproc, CS_SIZEREDRAW | CS_CLIPCHILDREN, 32);
-	rc = WinRegisterClass(dwhab, SplitbarClassName, _splitwndproc, 0L, 32);
-
-	/* Get the OS/2 version. */
-	DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_MS_COUNT,(void *)aulBuffer, 4*sizeof(ULONG));
-
-	desktop = WinQueryDesktopWindow(dwhab, NULLHANDLE);
-
-	if(!IS_WARP4())
-		DefaultFont = "8.Helv";
-
-	/* This is a window that hangs around as long as the
-	 * application does and handles menu messages.
-	 */
-	hwndApp = dw_window_new(HWND_OBJECT, "", 0);
-	DosLoadModule(objnamebuf, sizeof(objnamebuf), "WPCONFIG", &wpconfig);
-
-	return rc;
+   APIRET rc;
+   char objnamebuf[300] = "";
+
+   argc = argc; /* keep compiler happy */
+   argv = argv; /* keep compiler happy */
+   if(newthread)
+   {
+      dwhab = WinInitialize(0);
+      dwhmq = WinCreateMsgQueue(dwhab, 0);
+   }
+
+   rc = WinRegisterClass(dwhab, (PSZ)ClassName, _wndproc, CS_SIZEREDRAW | CS_CLIPCHILDREN, 32);
+   rc = WinRegisterClass(dwhab, (PSZ)SplitbarClassName, _splitwndproc, 0L, 32);
+   rc = WinRegisterClass(dwhab, (PSZ)ScrollClassName, _scrollwndproc, 0L, 32);
+
+   /* Get the OS/2 version. */
+   DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_MS_COUNT,(void *)aulBuffer, 4*sizeof(ULONG));
+
+   desktop = WinQueryDesktopWindow(dwhab, NULLHANDLE);
+
+   if(!IS_WARP4())
+      DefaultFont = strdup("8.Helv");
+   else
+      DefaultFont = strdup(DefaultFont);
+
+   /* This is a window that hangs around as long as the
+    * application does and handles menu messages.
+    */
+   hwndApp = dw_window_new(HWND_OBJECT, "", 0);
+   /* Attempt to locate a tray server */
+   WinDdeInitiate(hwndApp, (PSZ)"SystrayServer", (PSZ)"TRAY", NULL);
+
+   /* Load DLLs for providing extra functionality if available */
+   DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"WPCONFIG", &wpconfig);
+   if(!DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"PMPRINTF", &pmprintf))
+       DosQueryProcAddr(pmprintf, 0, (PSZ)"PmPrintfString", (PFN*)&_PmPrintfString);
+   return rc;
 }
 
 /*
@@ -3506,19 +4026,19 @@
  */
 void API dw_main(void)
 {
-	QMSG qmsg;
-
-	_dwtid = dw_thread_id();
-
-	while(WinGetMsg(dwhab, &qmsg, 0, 0, 0))
-	{
-		if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
-			_run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
-		WinDispatchMsg(dwhab, &qmsg);
-	}
-
-	WinDestroyMsgQueue(dwhmq);
-	WinTerminate(dwhab);
+   QMSG qmsg;
+
+   _dwtid = dw_thread_id();
+
+   while(WinGetMsg(dwhab, &qmsg, 0, 0, 0))
+   {
+      if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
+         _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
+      WinDispatchMsg(dwhab, &qmsg);
+   }
+
+   WinDestroyMsgQueue(dwhmq);
+   WinTerminate(dwhab);
 }
 
 /*
@@ -3528,41 +4048,41 @@
  */
 void API dw_main_sleep(int milliseconds)
 {
-	QMSG qmsg;
+   QMSG qmsg;
 #ifdef __EMX__
-	struct timeval tv, start;
-
-	gettimeofday(&start, NULL);
-	gettimeofday(&tv, NULL);
-
-	while(((tv.tv_sec - start.tv_sec)*1000) + ((tv.tv_usec - start.tv_usec)/1000) <= milliseconds)
-	{
-		if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE))
-		{
-			WinGetMsg(dwhab, &qmsg, 0, 0, 0);
-			if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
-				_run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
-			WinDispatchMsg(dwhab, &qmsg);
-		}
-		else
-			DosSleep(1);
-		gettimeofday(&tv, NULL);
-	}
+   struct timeval tv, start;
+
+   gettimeofday(&start, NULL);
+   gettimeofday(&tv, NULL);
+
+   while(((tv.tv_sec - start.tv_sec)*1000) + ((tv.tv_usec - start.tv_usec)/1000) <= milliseconds)
+   {
+      if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE))
+      {
+         WinGetMsg(dwhab, &qmsg, 0, 0, 0);
+         if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
+            _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
+         WinDispatchMsg(dwhab, &qmsg);
+      }
+      else
+         DosSleep(1);
+      gettimeofday(&tv, NULL);
+   }
 #else
-	double start = (double)clock();
-
-	while(((clock() - start) / (CLOCKS_PER_SEC/1000)) <= milliseconds)
-	{
-		if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE))
-		{
-			WinGetMsg(dwhab, &qmsg, 0, 0, 0);
-			if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
-				_run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
-			WinDispatchMsg(dwhab, &qmsg);
-		}
-		else
-			DosSleep(1);
-	}
+   double start = (double)clock();
+
+   while(((clock() - start) / (CLOCKS_PER_SEC/1000)) <= milliseconds)
+   {
+      if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE))
+      {
+         WinGetMsg(dwhab, &qmsg, 0, 0, 0);
+         if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
+            _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
+         WinDispatchMsg(dwhab, &qmsg);
+      }
+      else
+         DosSleep(1);
+   }
 #endif
 }
 
@@ -3571,16 +4091,16 @@
  */
 void API dw_main_iteration(void)
 {
-	QMSG qmsg;
-
-	_dwtid = dw_thread_id();
-
-	if(WinGetMsg(dwhab, &qmsg, 0, 0, 0))
-	{
-		if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
-			_run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
-		WinDispatchMsg(dwhab, &qmsg);
-	}
+   QMSG qmsg;
+
+   _dwtid = dw_thread_id();
+
+   if(WinGetMsg(dwhab, &qmsg, 0, 0, 0))
+   {
+      if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
+         _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
+      WinDispatchMsg(dwhab, &qmsg);
+   }
 }
 
 /*
@@ -3591,7 +4111,7 @@
  */
 void API dw_free(void *ptr)
 {
-	free(ptr);
+   free(ptr);
 }
 
 /*
@@ -3601,13 +4121,13 @@
  */
 DWDialog * API dw_dialog_new(void *data)
 {
-	DWDialog *tmp = malloc(sizeof(DWDialog));
-
-	tmp->eve = dw_event_new();
-	dw_event_reset(tmp->eve);
-	tmp->data = data;
-	tmp->done = FALSE;
-	tmp->result = NULL;
+   DWDialog *tmp = malloc(sizeof(DWDialog));
+
+   tmp->eve = dw_event_new();
+   dw_event_reset(tmp->eve);
+   tmp->data = data;
+   tmp->done = FALSE;
+   tmp->result = NULL;
 
     return tmp;
 }
@@ -3621,10 +4141,10 @@
  */
 int API dw_dialog_dismiss(DWDialog *dialog, void *result)
 {
-	dialog->result = result;
-	dw_event_post(dialog->eve);
-	dialog->done = TRUE;
-	return 0;
+   dialog->result = result;
+   dw_event_post(dialog->eve);
+   dialog->done = TRUE;
+   return 0;
 }
 
 /*
@@ -3635,23 +4155,43 @@
  */
 void * API dw_dialog_wait(DWDialog *dialog)
 {
-	QMSG qmsg;
-	void *tmp;
-
-	while (WinGetMsg(dwhab, &qmsg, 0, 0, 0))
-	{
-		if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
-			_run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
-		WinDispatchMsg(dwhab, &qmsg);
-		if(dialog->done)
-			break;
-	}
-	dw_event_close(&dialog->eve);
-	tmp = dialog->result;
-	free(dialog);
-	return tmp;
-}
-
+   QMSG qmsg;
+   void *tmp;
+
+   while (WinGetMsg(dwhab, &qmsg, 0, 0, 0))
+   {
+      if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
+         _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
+      WinDispatchMsg(dwhab, &qmsg);
+      if(dialog->done)
+         break;
+   }
+   dw_event_close(&dialog->eve);
+   tmp = dialog->result;
+   free(dialog);
+   return tmp;
+}
+
+/*
+ * Displays a debug message on the console...
+ * Parameters:
+ *           format: printf style format string.
+ *           ...: Additional variables for use in the format.
+ */
+void API dw_debug(char *format, ...)
+{
+   va_list args;
+   char outbuf[1024];
+
+   va_start(args, format);
+   vsprintf(outbuf, format, args);
+   va_end(args);
+
+   if(_PmPrintfString)
+       _PmPrintfString(outbuf);
+   else
+       fprintf(stderr, "%s", outbuf);
+}
 
 /*
  * Displays a Message Box with given text and title..
@@ -3663,24 +4203,24 @@
  */
 int API dw_messagebox(char *title, int flags, char *format, ...)
 {
-	va_list args;
-	char outbuf[1024];
-	int rc;
-
-	va_start(args, format);
-	vsprintf(outbuf, format, args);
-	va_end(args);
-
-	rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, outbuf, title, 0, flags | MB_MOVEABLE);
-	if(rc == MBID_OK)
-		return DW_MB_RETURN_OK;
-	else if(rc == MBID_YES)
-		return DW_MB_RETURN_YES;
-	else if(rc == MBID_NO)
-		return DW_MB_RETURN_NO;
-	else if(rc == MBID_CANCEL)
-		return DW_MB_RETURN_CANCEL;
-	else return 0;
+   va_list args;
+   char outbuf[1024];
+   int rc;
+
+   va_start(args, format);
+   vsprintf(outbuf, format, args);
+   va_end(args);
+
+   rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, (PSZ)outbuf, (PSZ)title, 0, flags | MB_MOVEABLE);
+   if(rc == MBID_OK)
+      return DW_MB_RETURN_OK;
+   else if(rc == MBID_YES)
+      return DW_MB_RETURN_YES;
+   else if(rc == MBID_NO)
+      return DW_MB_RETURN_NO;
+   else if(rc == MBID_CANCEL)
+      return DW_MB_RETURN_CANCEL;
+   else return 0;
 }
 
 /*
@@ -3690,7 +4230,7 @@
  */
 int API dw_window_raise(HWND handle)
 {
-	return WinSetWindowPos(handle, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
+   return WinSetWindowPos(handle, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
 }
 
 /*
@@ -3700,7 +4240,7 @@
  */
 int API dw_window_lower(HWND handle)
 {
-	return WinSetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER);
+   return WinSetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER);
 }
 
 /*
@@ -3710,54 +4250,54 @@
  */
 int API dw_window_show(HWND handle)
 {
-	int rc = WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_SHOW);
-	HSWITCH hswitch;
-	SWCNTRL swcntrl;
-
-	_fix_button_owner(_toplevel_window(handle), 0);
-	WinSetFocus(HWND_DESKTOP, handle);
-	_initial_focus(handle);
-
-	/* If this window has a  switch list entry make sure it is visible */
-	hswitch = WinQuerySwitchHandle(handle, 0);
-	if(hswitch)
-	{
-		WinQuerySwitchEntry(hswitch, &swcntrl);
-		swcntrl.uchVisibility = SWL_VISIBLE;
-		WinChangeSwitchEntry(hswitch, &swcntrl);
-	}
-	if(WinWindowFromID(handle, FID_CLIENT))
-	{
-		WindowData *blah = WinQueryWindowPtr(handle, QWP_USER);
-
-		if(blah && !(blah->flags & DW_OS2_NEW_WINDOW))
-		{
-			ULONG cx = dw_screen_width(), cy = dw_screen_height();
-			int newx, newy, changed = 0;
-			SWP swp;
-
-			blah->flags |= DW_OS2_NEW_WINDOW;
-
-			WinQueryWindowPos(handle, &swp);
-
-			newx = swp.x;
-			newy = swp.y;
-
-			if((swp.x+swp.cx) > cx)
-			{
-				newx = (cx - swp.cx)/2;
-				changed = 1;
-			}
-			if((swp.y+swp.cy) > cy)
-			{
-				newy = (cy - swp.cy)/2;
-				changed = 1;
-			}
-			if(changed)
-				WinSetWindowPos(handle, NULLHANDLE, newx, newy, 0, 0, SWP_MOVE);
-		}
-	}
-	return rc;
+   int rc = WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_SHOW);
+   HSWITCH hswitch;
+   SWCNTRL swcntrl;
+
+   _fix_button_owner(_toplevel_window(handle), 0);
+   WinSetFocus(HWND_DESKTOP, handle);
+   _initial_focus(handle);
+
+   /* If this window has a  switch list entry make sure it is visible */
+   hswitch = WinQuerySwitchHandle(handle, 0);
+   if(hswitch)
+   {
+      WinQuerySwitchEntry(hswitch, &swcntrl);
+      swcntrl.uchVisibility = SWL_VISIBLE;
+      WinChangeSwitchEntry(hswitch, &swcntrl);
+   }
+   if(WinWindowFromID(handle, FID_CLIENT))
+   {
+      WindowData *blah = WinQueryWindowPtr(handle, QWP_USER);
+
+      if(blah && !(blah->flags & DW_OS2_NEW_WINDOW))
+      {
+         ULONG cx = dw_screen_width(), cy = dw_screen_height();
+         int newx, newy, changed = 0;
+         SWP swp;
+
+         blah->flags |= DW_OS2_NEW_WINDOW;
+
+         WinQueryWindowPos(handle, &swp);
+
+         newx = swp.x;
+         newy = swp.y;
+
+         if((swp.x+swp.cx) > cx)
+         {
+            newx = (cx - swp.cx)/2;
+            changed = 1;
+         }
+         if((swp.y+swp.cy) > cy)
+         {
+            newy = (cy - swp.cy)/2;
+            changed = 1;
+         }
+         if(changed)
+            WinSetWindowPos(handle, NULLHANDLE, newx, newy, 0, 0, SWP_MOVE);
+      }
+   }
+   return rc;
 }
 
 /*
@@ -3767,20 +4307,20 @@
  */
 int API dw_window_minimize(HWND handle)
 {
-	HWND hwndclient = WinWindowFromID(handle, FID_CLIENT);
-
-	if(hwndclient)
-	{
-		Box *box = (Box *)WinQueryWindowPtr(hwndclient, QWP_USER);
-
-		if(box)
-		{
-			if(!box->titlebar && box->hwndtitle)
-				WinSetParent(box->hwndtitle, handle, FALSE);
-		}
-	}
-
-	return WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_MINIMIZE);
+   HWND hwndclient = WinWindowFromID(handle, FID_CLIENT);
+
+   if(hwndclient)
+   {
+      Box *box = (Box *)WinQueryWindowPtr(hwndclient, QWP_USER);
+
+      if(box)
+      {
+         if(!box->titlebar && box->hwndtitle)
+            WinSetParent(box->hwndtitle, handle, FALSE);
+      }
+   }
+
+   return WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_MINIMIZE);
 }
 
 /*
@@ -3790,18 +4330,18 @@
  */
 int API dw_window_hide(HWND handle)
 {
-	HSWITCH hswitch;
-	SWCNTRL swcntrl;
-
-	/* If this window has a  switch list entry make sure it is invisible */
-	hswitch = WinQuerySwitchHandle(handle, 0);
-	if(hswitch)
-	{
-		WinQuerySwitchEntry(hswitch, &swcntrl);
-		swcntrl.uchVisibility = SWL_INVISIBLE;
-		WinChangeSwitchEntry(hswitch, &swcntrl);
-	}
-	return WinShowWindow(handle, FALSE);
+   HSWITCH hswitch;
+   SWCNTRL swcntrl;
+
+   /* If this window has a  switch list entry make sure it is invisible */
+   hswitch = WinQuerySwitchHandle(handle, 0);
+   if(hswitch)
+   {
+      WinQuerySwitchEntry(hswitch, &swcntrl);
+      swcntrl.uchVisibility = SWL_INVISIBLE;
+      WinChangeSwitchEntry(hswitch, &swcntrl);
+   }
+   return WinShowWindow(handle, FALSE);
 }
 
 /*
@@ -3811,49 +4351,71 @@
  */
 int API dw_window_destroy(HWND handle)
 {
-	HWND frame, menu, parent = WinQueryWindow(handle, QW_PARENT);
-	Box *thisbox = WinQueryWindowPtr(parent, QWP_USER);
-
-	if(!handle)
-		return -1;
-
-	frame = (HWND)dw_window_get_data(handle, "_dw_combo_box");
-
-	if((menu = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE)
-		_free_menu_data(menu);
-
-	if(parent != desktop && thisbox && thisbox->count)
-	{
-		int z, index = -1;
-		Item *tmpitem, *thisitem = thisbox->items;
-
-		for(z=0;z<thisbox->count;z++)
-		{
-			if(thisitem[z].hwnd == handle)
-				index = z;
-		}
-
-		if(index == -1)
-			return 0;
-
-		tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
-
-		/* Copy all but the current entry to the new list */
-		for(z=0;z<index;z++)
-		{
-			tmpitem[z] = thisitem[z];
-		}
-		for(z=index+1;z<thisbox->count;z++)
-		{
-			tmpitem[z-1] = thisitem[z];
-		}
-
-		thisbox->items = tmpitem;
-		free(thisitem);
-		thisbox->count--;
-		_free_window_memory(frame ? frame : handle);
-	}
-	return WinDestroyWindow(frame ? frame : handle);
+   HWND frame, menu, parent;
+   Box *thisbox;
+
+   if(!handle)
+      return DW_ERROR_UNKNOWN;
+
+   /* Handle special case for menu handle */
+   if(handle < 65536)
+   {
+      char buffer[30];
+
+      sprintf(buffer, "_dw_id%ld", handle);
+      menu = (HWND)dw_window_get_data(hwndApp, buffer);
+
+      if(menu && WinIsWindow(dwhab, menu))
+          return dw_menu_delete_item((HMENUI)menu, handle);
+      return DW_ERROR_UNKNOWN;
+   }
+   
+   parent = WinQueryWindow(handle, QW_PARENT);
+   thisbox = WinQueryWindowPtr(parent, QWP_USER);
+   frame = (HWND)dw_window_get_data(handle, "_dw_combo_box");
+
+   if((menu = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE)
+      _free_menu_data(menu);
+
+   /* If it is a desktop window let WM_DESTROY handle it */
+   if(parent != desktop)
+   {
+      /* If the parent box has items... 
+       * try to remove it from the layout 
+       */
+     if(thisbox && thisbox->count)
+      {
+         int z, index = -1;
+         Item *tmpitem, *thisitem = thisbox->items;
+
+         for(z=0;z<thisbox->count;z++)
+         {
+            if(thisitem[z].hwnd == handle)
+               index = z;
+         }
+
+         if(index == -1)
+            return 0;
+
+         tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
+
+         /* Copy all but the current entry to the new list */
+         for(z=0;z<index;z++)
+         {
+            tmpitem[z] = thisitem[z];
+         }
+         for(z=index+1;z<thisbox->count;z++)
+         {
+            tmpitem[z-1] = thisitem[z];
+         }
+
+         thisbox->items = tmpitem;
+         free(thisitem);
+         thisbox->count--;
+      }
+      _free_window_memory(frame ? frame : handle);
+   }
+   return WinDestroyWindow(frame ? frame : handle);
 }
 
 /* Causes entire window to be invalidated and redrawn.
@@ -3862,21 +4424,24 @@
  */
 void API dw_window_redraw(HWND handle)
 {
-	HWND client = WinWindowFromID(handle, FID_CLIENT);
-	HWND window = client ? client : handle;
-	Box *mybox = (Box *)WinQueryWindowPtr(window, QWP_USER);
-
-	_fix_button_owner(_toplevel_window(handle), 0);
-	if(window && mybox)
-	{
-		unsigned long width, height;
-
-		dw_window_get_pos_size(window, NULL, NULL, &width, &height);
-
-		WinShowWindow(client ? mybox->items[0].hwnd : handle, FALSE);
-		_do_resize(mybox, width, height);
-		WinShowWindow(client ? mybox->items[0].hwnd : handle, TRUE);
-	}
+   HWND client = WinWindowFromID(handle, FID_CLIENT);
+   HWND window = client ? client : handle;
+   Box *mybox = (Box *)WinQueryWindowPtr(window, QWP_USER);
+
+   _fix_button_owner(_toplevel_window(handle), 0);
+   if(window && mybox)
+   {
+      unsigned long width, height;
+
+      dw_window_get_pos_size(window, NULL, NULL, &width, &height);
+
+      if(mybox->items)
+          WinSetWindowPos(mybox->items[0].hwnd, HWND_TOP, 0, 0, width, height, SWP_MOVE | SWP_SIZE);
+
+      WinShowWindow(client && mybox->items ? mybox->items[0].hwnd : handle, FALSE);
+      _do_resize(mybox, width, height);
+      WinShowWindow(client && mybox->items ? mybox->items[0].hwnd : handle, TRUE);
+   }
 }
 
 /*
@@ -3887,8 +4452,78 @@
  */
 void API dw_window_reparent(HWND handle, HWND newparent)
 {
-	HWND blah = WinWindowFromID(newparent, FID_CLIENT);
-	WinSetParent(handle, blah ? blah : newparent, TRUE);
+   HWND blah = WinWindowFromID(newparent, FID_CLIENT);
+   WinSetParent(handle, blah ? blah : newparent, TRUE);
+}
+
+/* Allows the user to choose a font using the system's font chooser dialog.
+ * Parameters:
+ *       currfont: current font
+ * Returns:
+ *       A malloced buffer with the selected font or NULL on error.
+ */
+char * API dw_font_choose(char *currfont)
+{
+    FONTDLG fd = { 0 };
+    char *buf = calloc(1,100);
+    int size = 9;
+
+    /* Fill in the family name if possible */
+    if(currfont)
+    {
+        char *name = strchr(currfont, '.');
+        if(name)
+        {
+            int newsize = atoi(currfont);
+            if(newsize > 0)
+                size = newsize;
+            name++;
+            strcpy(buf, name);
+            strcpy(fd.fAttrs.szFacename, name);
+        }
+        else
+        {
+            strcpy(buf, currfont);
+            strcpy(fd.fAttrs.szFacename, currfont);
+        }
+    }
+
+    /* Fill in the font dialog struct */
+    fd.cbSize = sizeof(fd);
+    fd.hpsScreen = WinGetScreenPS(HWND_DESKTOP);
+    fd.pszTitle = (PSZ)"Choose Font";
+    fd.clrFore = CLR_BLACK;
+    fd.clrBack = CLR_WHITE;
+    fd.pszFamilyname = (PSZ)buf;
+    fd.usFamilyBufLen = 100;
+    fd.fxPointSize = MAKEFIXED(size,0);
+    fd.fl = FNTS_INITFROMFATTRS;
+
+    /* Show the dialog and wait for a response */
+    if(!WinFontDlg(HWND_DESKTOP, HWND_OBJECT, &fd) || fd.lReturn != DID_OK)
+    {
+        WinReleasePS(fd.hpsScreen);
+        free(buf);
+        return NULL;
+    }
+    WinReleasePS(fd.hpsScreen);
+    /* Figure out what the user selected and return that */
+    size = FIXEDINT(fd.fxPointSize);
+    sprintf(buf, "%d.%s", size, fd.fAttrs.szFacename);
+    return buf;
+}
+
+/*
+ * Sets the default font used on text based widgets.
+ * Parameters:
+ *           fontname: Font name in Dynamic Windows format.
+ */
+void API dw_font_set_default(char *fontname)
+{
+    char *oldfont = DefaultFont;
+    
+    DefaultFont = strdup(fontname);
+    free(oldfont);
 }
 
 /*
@@ -3899,49 +4534,65 @@
  */
 int API dw_window_set_font(HWND handle, char *fontname)
 {
-	return WinSetPresParam(handle, PP_FONTNAMESIZE, strlen(fontname)+1, fontname);
+   HWND group = (HWND)dw_window_get_data(handle, "_dw_buddy");
+   return WinSetPresParam(group ? group : handle, PP_FONTNAMESIZE, strlen(fontname)+1, fontname);
+}
+
+/*
+ * Gets the font used by a specified window (widget) handle.
+ * Parameters:
+ *          handle: The window (widget) handle.
+ *          fontname: Name and size of the font in the form "size.fontname"
+ */
+char * API dw_window_get_font(HWND handle)
+{
+   char *str = (char *)alloca(50);
+   HWND group = (HWND)dw_window_get_data(handle, "_dw_buddy");
+   if(str && WinQueryPresParam(group ? group : handle, PP_FONTNAMESIZE, 0, NULL, 50, str, QPF_NOINHERIT))
+      return strdup(str);
+   return NULL;
 }
 
 /* Internal version */
 int _dw_window_set_color(HWND handle, ULONG fore, ULONG back)
 {
-	if((fore & DW_RGB_COLOR) == DW_RGB_COLOR)
-	{
-		RGB2 rgb2;
-
-		rgb2.bBlue = DW_BLUE_VALUE(fore);
-		rgb2.bGreen = DW_GREEN_VALUE(fore);
-		rgb2.bRed = DW_RED_VALUE(fore);
-		rgb2.fcOptions = 0;
-
-		WinSetPresParam(handle, PP_FOREGROUNDCOLOR, sizeof(RGB2), &rgb2);
-
-	}
-	else if(fore != DW_CLR_DEFAULT)
-	{
-		fore = _internal_color(fore);
-
-		WinSetPresParam(handle, PP_FOREGROUNDCOLORINDEX, sizeof(ULONG), &fore);
-	}
-	if((back & DW_RGB_COLOR) == DW_RGB_COLOR)
-	{
-		RGB2 rgb2;
-
-		rgb2.bBlue = DW_BLUE_VALUE(back);
-		rgb2.bGreen = DW_GREEN_VALUE(back);
-		rgb2.bRed = DW_RED_VALUE(back);
-		rgb2.fcOptions = 0;
-
-		WinSetPresParam(handle, PP_BACKGROUNDCOLOR, sizeof(RGB2), &rgb2);
-		return 0;
-	}
-	else if(back != DW_CLR_DEFAULT)
-	{
-		back = _internal_color(back);
-
-		WinSetPresParam(handle, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back);
-	}
-	return 0;
+   if((fore & DW_RGB_COLOR) == DW_RGB_COLOR)
+   {
+      RGB2 rgb2;
+
+      rgb2.bBlue = DW_BLUE_VALUE(fore);
+      rgb2.bGreen = DW_GREEN_VALUE(fore);
+      rgb2.bRed = DW_RED_VALUE(fore);
+      rgb2.fcOptions = 0;
+
+      WinSetPresParam(handle, PP_FOREGROUNDCOLOR, sizeof(RGB2), &rgb2);
+
+   }
+   else if(fore != DW_CLR_DEFAULT)
+   {
+      fore = _internal_color(fore);
+
+      WinSetPresParam(handle, PP_FOREGROUNDCOLORINDEX, sizeof(ULONG), &fore);
+   }
+   if((back & DW_RGB_COLOR) == DW_RGB_COLOR)
+   {
+      RGB2 rgb2;
+
+      rgb2.bBlue = DW_BLUE_VALUE(back);
+      rgb2.bGreen = DW_GREEN_VALUE(back);
+      rgb2.bRed = DW_RED_VALUE(back);
+      rgb2.fcOptions = 0;
+
+      WinSetPresParam(handle, PP_BACKGROUNDCOLOR, sizeof(RGB2), &rgb2);
+      return 0;
+   }
+   else if(back != DW_CLR_DEFAULT)
+   {
+      back = _internal_color(back);
+
+      WinSetPresParam(handle, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back);
+   }
+   return 0;
 }
 /*
  * Sets the colors used by a specified window (widget) handle.
@@ -3952,10 +4603,10 @@
  */
 int API dw_window_set_color(HWND handle, ULONG fore, ULONG back)
 {
-	dw_window_set_data(handle, "_dw_fore", (void *)(fore+1));
-	dw_window_set_data(handle, "_dw_back", (void *)(back+1));
-
-	return _dw_window_set_color(handle, fore, back);
+   dw_window_set_data(handle, "_dw_fore", (void *)(fore+1));
+   dw_window_set_data(handle, "_dw_back", (void *)(back+1));
+
+   return _dw_window_set_color(handle, fore, back);
 }
 
 /*
@@ -3966,8 +4617,8 @@
  */
 int API dw_window_set_border(HWND handle, int border)
 {
-	WinSendMsg(handle, WM_SETBORDERSIZE, MPFROMSHORT(border), MPFROMSHORT(border));
-	return 0;
+   WinSendMsg(handle, WM_SETBORDERSIZE, MPFROMSHORT(border), MPFROMSHORT(border));
+   return 0;
 }
 
 /*
@@ -3977,7 +4628,7 @@
  */
 void API dw_window_capture(HWND handle)
 {
-	WinSetCapture(HWND_DESKTOP, handle);
+   WinSetCapture(HWND_DESKTOP, handle);
 }
 
 /*
@@ -3985,7 +4636,7 @@
  */
 void API dw_window_release(void)
 {
-	WinSetCapture(HWND_DESKTOP, NULLHANDLE);
+   WinSetCapture(HWND_DESKTOP, NULLHANDLE);
 }
 
 /*
@@ -3995,7 +4646,7 @@
  */
 void API dw_window_track(HWND handle)
 {
-	WinSendMsg(handle, WM_TRACKFRAME, MPFROMSHORT(TF_MOVE), 0);
+   WinSendMsg(handle, WM_TRACKFRAME, MPFROMSHORT(TF_MOVE), 0);
 }
 
 /*
@@ -4006,19 +4657,19 @@
  */
 void API dw_window_set_pointer(HWND handle, int pointertype)
 {
-	HPOINTER pointer = pointertype < 65535 ?
-		WinQuerySysPointer(HWND_DESKTOP, pointertype, FALSE)
-		: (HPOINTER)pointertype;
-
-	if(!pointertype)
-		dw_window_set_data(handle, "_dw_pointer", 0);
-	else
-	{
-		WinSetPointer(HWND_DESKTOP, pointer);
-
-		if(handle != HWND_DESKTOP)
-			dw_window_set_data(handle, "_dw_pointer", (void *)pointer);
-	}
+   HPOINTER pointer = pointertype < 65535 ?
+      WinQuerySysPointer(HWND_DESKTOP, pointertype, FALSE)
+      : (HPOINTER)pointertype;
+
+   if(!pointertype)
+      dw_window_set_data(handle, "_dw_pointer", 0);
+   else
+   {
+      WinSetPointer(HWND_DESKTOP, pointer);
+
+      if(handle != HWND_DESKTOP)
+         dw_window_set_data(handle, "_dw_pointer", (void *)pointer);
+   }
 }
 
 /*
@@ -4030,45 +4681,45 @@
  */
 HWND API dw_window_new(HWND hwndOwner, char *title, ULONG flStyle)
 {
-	HWND hwndframe;
-	Box *newbox = calloc(1, sizeof(Box));
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	ULONG winStyle = 0L;
-
-	newbox->pad = 0;
-	newbox->type = DW_VERT;
-	newbox->count = 0;
-
-	flStyle |= FCF_NOBYTEALIGN;
-
-	if(flStyle & DW_FCF_TITLEBAR)
-		newbox->titlebar = 1;
-	else
-		flStyle |= FCF_TITLEBAR;
-
-	if(!(flStyle & FCF_SHELLPOSITION))
-		blah->flags |= DW_OS2_NEW_WINDOW;
-
-	if(flStyle & WS_MAXIMIZED)
-	{
-		winStyle |= WS_MAXIMIZED;
-		flStyle &= ~WS_MAXIMIZED;
-	}
-	if(flStyle & WS_MINIMIZED)
-	{
-		winStyle |= WS_MINIMIZED;
-		flStyle &= ~WS_MINIMIZED;
-	}
-
-	hwndframe = WinCreateStdWindow(hwndOwner, winStyle, &flStyle, ClassName, title, 0L, NULLHANDLE, 0L, &newbox->hwnd);
-	newbox->hwndtitle = WinWindowFromID(hwndframe, FID_TITLEBAR);
-	if(!newbox->titlebar && newbox->hwndtitle)
-		WinSetParent(newbox->hwndtitle, HWND_OBJECT, FALSE);
-	blah->oldproc = WinSubclassWindow(hwndframe, _sizeproc);
-	WinSetWindowPtr(hwndframe, QWP_USER, blah);
-	WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox);
-
-	return hwndframe;
+   HWND hwndframe;
+   Box *newbox = calloc(1, sizeof(Box));
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   ULONG winStyle = 0L;
+
+   newbox->pad = 0;
+   newbox->type = DW_VERT;
+   newbox->count = 0;
+
+   flStyle |= FCF_NOBYTEALIGN;
+
+   if(flStyle & DW_FCF_TITLEBAR)
+      newbox->titlebar = 1;
+   else
+      flStyle |= FCF_TITLEBAR;
+
+   if(!(flStyle & FCF_SHELLPOSITION))
+      blah->flags |= DW_OS2_NEW_WINDOW;
+
+   if(flStyle & WS_MAXIMIZED)
+   {
+      winStyle |= WS_MAXIMIZED;
+      flStyle &= ~WS_MAXIMIZED;
+   }
+   if(flStyle & WS_MINIMIZED)
+   {
+      winStyle |= WS_MINIMIZED;
+      flStyle &= ~WS_MINIMIZED;
+   }
+
+   hwndframe = WinCreateStdWindow(hwndOwner, winStyle, &flStyle, (PSZ)ClassName, (PSZ)title, 0L, NULLHANDLE, 0L, &newbox->hwnd);
+   newbox->hwndtitle = WinWindowFromID(hwndframe, FID_TITLEBAR);
+   if(!newbox->titlebar && newbox->hwndtitle)
+      WinSetParent(newbox->hwndtitle, HWND_OBJECT, FALSE);
+   blah->oldproc = WinSubclassWindow(hwndframe, _sizeproc);
+   WinSetWindowPtr(hwndframe, QWP_USER, blah);
+   WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox);
+
+   return hwndframe;
 }
 
 /*
@@ -4079,29 +4730,100 @@
  */
 HWND API dw_box_new(int type, int pad)
 {
-	Box *newbox = calloc(1, sizeof(Box));
-
-	newbox->pad = pad;
-	newbox->type = type;
-	newbox->count = 0;
-    newbox->grouphwnd = NULLHANDLE;
-
-	newbox->hwnd = WinCreateWindow(HWND_OBJECT,
-								   WC_FRAME,
-								   NULL,
-								   WS_VISIBLE | WS_CLIPCHILDREN |
-								   FS_NOBYTEALIGN,
-								   0,0,2000,1000,
-								   NULLHANDLE,
-								   HWND_TOP,
-								   0L,
-								   NULL,
-								   NULL);
-
-	newbox->oldproc = WinSubclassWindow(newbox->hwnd, _controlproc);
-	WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox);
-	dw_window_set_color(newbox->hwnd, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
-	return newbox->hwnd;
+   Box *newbox = calloc(1, sizeof(Box));
+
+   newbox->pad = pad;
+   newbox->type = type;
+   newbox->count = 0;
+   newbox->grouphwnd = NULLHANDLE;
+
+   newbox->hwnd = WinCreateWindow(HWND_OBJECT,
+                           WC_FRAME,
+                           NULL,
+                           WS_VISIBLE | WS_CLIPCHILDREN |
+                           FS_NOBYTEALIGN,
+                           0,0,2000,1000,
+                           NULLHANDLE,
+                           HWND_TOP,
+                           0L,
+                           NULL,
+                           NULL);
+
+   newbox->oldproc = WinSubclassWindow(newbox->hwnd, _controlproc);
+   WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox);
+   dw_window_set_color(newbox->hwnd, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
+   return newbox->hwnd;
+}
+
+/*
+ * Create a new scroll Box to be packed.
+ * Parameters:
+ *       type: Either DW_VERT (vertical) or DW_HORZ (horizontal).
+ *       pad: Number of pixels to pad around the box.
+ */
+HWND API dw_scrollbox_new(int type, int pad)
+{
+   HWND hwndframe, box = dw_box_new(type, pad);
+   HWND client, tmpbox = dw_box_new(DW_VERT, 0);
+   Box *blah = calloc(sizeof(Box), 1);
+   dw_box_pack_start(tmpbox, box, 1, 1, TRUE, TRUE, 0);
+   hwndframe = WinCreateWindow(HWND_OBJECT, (PSZ)ScrollClassName, NULL, WS_VISIBLE | WS_CLIPCHILDREN,
+                               0, 0, 2000, 1000, NULLHANDLE, HWND_TOP, 0, NULL, NULL);
+   WinCreateWindow(hwndframe, WC_SCROLLBAR, NULL, WS_VISIBLE | SBS_AUTOTRACK | SBS_VERT,
+                   0,0,2000,1000, hwndframe, HWND_TOP, FID_VERTSCROLL, NULL, NULL);
+   WinCreateWindow(hwndframe, WC_SCROLLBAR, NULL, WS_VISIBLE | SBS_AUTOTRACK | SBS_HORZ,
+                   0,0,2000,1000, hwndframe, HWND_TOP, FID_HORZSCROLL, NULL, NULL);
+   client = WinCreateWindow(hwndframe, WC_FRAME, NULL, WS_VISIBLE | WS_CLIPCHILDREN,
+                      0,0,2000,1000, NULLHANDLE, HWND_TOP, FID_CLIENT, NULL, NULL);
+   WinSetParent(tmpbox, client, FALSE);
+   WinSetWindowPtr(client, QWP_USER, blah);
+   dw_window_set_data(hwndframe, "_dw_resizebox", (void *)tmpbox);
+   dw_window_set_data(hwndframe, "_dw_box", (void *)box);
+   dw_window_set_color(hwndframe, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
+   dw_window_set_color(client, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
+   return hwndframe;
+}
+
+/*
+ * Returns the position of the scrollbar in the scrollbox
+ * Parameters:
+ *          handle: Handle to the scrollbox to be queried.
+ *          orient: The vertical or horizontal scrollbar.
+ */
+int API dw_scrollbox_get_pos( HWND handle, int orient )
+{
+   HWND scroll;
+
+   if(orient == DW_VERT)
+   {
+      scroll = WinWindowFromID(handle, FID_VERTSCROLL);
+   }
+   else
+   {
+      scroll = WinWindowFromID(handle, FID_HORZSCROLL);
+   }
+   return (int)WinSendMsg(scroll, SBM_QUERYPOS, 0, 0);
+}
+
+/*
+ * Gets the range for the scrollbar in the scrollbox.
+ * Parameters:
+ *          handle: Handle to the scrollbox to be queried.
+ *          orient: The vertical or horizontal scrollbar.
+ */
+int API dw_scrollbox_get_range( HWND handle, int orient )
+{
+   HWND scroll;
+
+   if(orient == DW_VERT)
+   {
+      scroll = WinWindowFromID(handle, FID_VERTSCROLL);
+   }
+   else
+   {
+      scroll = WinWindowFromID(handle, FID_HORZSCROLL);
+   }
+   return SHORT2FROMMP(WinSendMsg(scroll, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0));
 }
 
 /*
@@ -4113,40 +4835,41 @@
  */
 HWND API dw_groupbox_new(int type, int pad, char *title)
 {
-	Box *newbox = calloc(1, sizeof(Box));
-	newbox->pad = pad;
-	newbox->type = type;
-	newbox->count = 0;
-
-	newbox->hwnd = WinCreateWindow(HWND_OBJECT,
-								   WC_FRAME,
-								   NULL,
-								   WS_VISIBLE |
-								   FS_NOBYTEALIGN,
-								   0,0,2000,1000,
-								   NULLHANDLE,
-								   HWND_TOP,
-								   0L,
-								   NULL,
-								   NULL);
-
-	newbox->grouphwnd = WinCreateWindow(newbox->hwnd,
-										WC_STATIC,
-										title,
-										WS_VISIBLE | SS_GROUPBOX |
-										WS_GROUP,
-										0,0,2000,1000,
-										NULLHANDLE,
-										HWND_TOP,
-										0L,
-										NULL,
-										NULL);
-
-	WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox);
-	dw_window_set_color(newbox->hwnd, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
-	dw_window_set_color(newbox->grouphwnd, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-	dw_window_set_font(newbox->grouphwnd, DefaultFont);
-	return newbox->hwnd;
+   Box *newbox = calloc(1, sizeof(Box));
+   newbox->pad = pad;
+   newbox->type = type;
+   newbox->count = 0;
+
+   newbox->hwnd = WinCreateWindow(HWND_OBJECT,
+                           WC_FRAME,
+                           NULL,
+                           WS_VISIBLE |
+                           FS_NOBYTEALIGN,
+                           0,0,2000,1000,
+                           NULLHANDLE,
+                           HWND_TOP,
+                           0L,
+                           NULL,
+                           NULL);
+
+   newbox->grouphwnd = WinCreateWindow(newbox->hwnd,
+                              WC_STATIC,
+                              (PSZ)title,
+                              WS_VISIBLE | SS_GROUPBOX |
+                              WS_GROUP,
+                              0,0,2000,1000,
+                              NULLHANDLE,
+                              HWND_TOP,
+                              0L,
+                              NULL,
+                              NULL);
+
+   WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox);
+   dw_window_set_color(newbox->hwnd, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
+   dw_window_set_color(newbox->grouphwnd, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   dw_window_set_font(newbox->grouphwnd, DefaultFont);
+   dw_window_set_data(newbox->hwnd, "_dw_buddy", (void *)newbox->grouphwnd);
+   return newbox->hwnd;
 }
 
 /*
@@ -4156,23 +4879,23 @@
  */
 HWND API dw_mdi_new(unsigned long id)
 {
-	HWND hwndframe;
-	ULONG back = CLR_DARKGRAY;
-
-	hwndframe = WinCreateWindow(HWND_OBJECT,
-								WC_FRAME,
-								NULL,
-								WS_VISIBLE | WS_CLIPCHILDREN |
-								FS_NOBYTEALIGN,
-								0,0,2000,1000,
-								NULLHANDLE,
-								HWND_TOP,
-								id,
-								NULL,
-								NULL);
-	/* Make the MDI Client area the same color as Windows and Unix */
-	WinSetPresParam(hwndframe, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back);
-	return hwndframe;
+   HWND hwndframe;
+   ULONG back = CLR_DARKGRAY;
+
+   hwndframe = WinCreateWindow(HWND_OBJECT,
+                        WC_FRAME,
+                        NULL,
+                        WS_VISIBLE | WS_CLIPCHILDREN |
+                        FS_NOBYTEALIGN,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   /* Make the MDI Client area the same color as Windows and Unix */
+   WinSetPresParam(hwndframe, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back);
+   return hwndframe;
 }
 
 /*
@@ -4182,16 +4905,16 @@
  */
 HWND API dw_bitmap_new(ULONG id)
 {
-	return WinCreateWindow(HWND_OBJECT,
-						   WC_STATIC,
-						   NULL,
-						   WS_VISIBLE | SS_TEXT,
-						   0,0,2000,1000,
-						   NULLHANDLE,
-						   HWND_TOP,
-						   id,
-						   NULL,
-						   NULL);
+   return WinCreateWindow(HWND_OBJECT,
+                     WC_STATIC,
+                     NULL,
+                     WS_VISIBLE | SS_TEXT,
+                     0,0,2000,1000,
+                     NULLHANDLE,
+                     HWND_TOP,
+                     id,
+                     NULL,
+                     NULL);
 }
 
 /*
@@ -4202,38 +4925,38 @@
  */
 HWND API dw_notebook_new(ULONG id, int top)
 {
-	ULONG flags;
-	HWND tmp;
-
-	if(top)
-		flags = BKS_MAJORTABTOP;
-	else
-		flags = BKS_MAJORTABBOTTOM;
-
-	tmp = WinCreateWindow(HWND_OBJECT,
-						  WC_NOTEBOOK,
-						  NULL,
-						  WS_VISIBLE |
+   ULONG flags;
+   HWND tmp;
+
+   if(top)
+      flags = BKS_MAJORTABTOP;
+   else
+      flags = BKS_MAJORTABBOTTOM;
+
+   tmp = WinCreateWindow(HWND_OBJECT,
+                    WC_NOTEBOOK,
+                    NULL,
+                    WS_VISIBLE |
 #ifdef BKS_TABBEDDIALOG
-						  BKS_TABBEDDIALOG |
+                    BKS_TABBEDDIALOG |
 #endif
-						  flags,
-						  0,0,2000,1000,
-						  NULLHANDLE,
-						  HWND_TOP,
-						  id,
-						  NULL,
-						  NULL);
-
-	/* Fix tab sizes on Warp 3 */
-	if(!IS_WARP4())
-	{
-		/* best sizes to be determined by trial and error */
-		WinSendMsg(tmp, BKM_SETDIMENSIONS,MPFROM2SHORT(102, 28), MPFROMSHORT( BKA_MAJORTAB));
-	}
-
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
+                    flags,
+                    0,0,2000,1000,
+                    NULLHANDLE,
+                    HWND_TOP,
+                    id,
+                    NULL,
+                    NULL);
+
+   /* Fix tab sizes on Warp 3 */
+   if(!IS_WARP4())
+   {
+      /* best sizes to be determined by trial and error */
+      WinSendMsg(tmp, BKM_SETDIMENSIONS,MPFROM2SHORT(102, 28), MPFROMSHORT( BKA_MAJORTAB));
+   }
+
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
 }
 
 /*
@@ -4244,17 +4967,17 @@
  */
 HMENUI API dw_menu_new(ULONG id)
 {
-	HMENUI tmp = WinCreateWindow(HWND_OBJECT,
-								 WC_MENU,
-								 NULL,
-								 WS_VISIBLE,
-								 0,0,2000,1000,
-								 NULLHANDLE,
-								 HWND_TOP,
-								 id,
-								 NULL,
-								 NULL);
-	return tmp;
+   HMENUI tmp = WinCreateWindow(HWND_OBJECT,
+                         WC_MENU,
+                         NULL,
+                         WS_VISIBLE,
+                         0,0,2000,1000,
+                         NULLHANDLE,
+                         HWND_TOP,
+                         id,
+                         NULL,
+                         NULL);
+   return tmp;
 }
 
 /*
@@ -4264,19 +4987,19 @@
  */
 HMENUI API dw_menubar_new(HWND location)
 {
-	HMENUI tmp = WinCreateWindow(location,
-								 WC_MENU,
-								 NULL,
-								 WS_VISIBLE | MS_ACTIONBAR,
-								 0,0,2000,1000,
-								 location,
-								 HWND_TOP,
-								 FID_MENU,
-								 NULL,
-								 NULL);
-	dw_window_set_data(tmp, "_dw_owner", (void *)location);
-	dw_window_set_data(tmp, "_dw_menubar", (void *)location);
-	return tmp;
+   HMENUI tmp = WinCreateWindow(location,
+                         WC_MENU,
+                         NULL,
+                         WS_VISIBLE | MS_ACTIONBAR,
+                         0,0,2000,1000,
+                         location,
+                         HWND_TOP,
+                         FID_MENU,
+                         NULL,
+                         NULL);
+   dw_window_set_data(tmp, "_dw_owner", (void *)location);
+   dw_window_set_data(tmp, "_dw_menubar", (void *)location);
+   return tmp;
 }
 
 /*
@@ -4286,8 +5009,22 @@
  */
 void API dw_menu_destroy(HMENUI *menu)
 {
-	if(menu)
-		WinDestroyWindow(*menu);
+   if(menu)
+      WinDestroyWindow(*menu);
+}
+
+/* Internal function to make sure menu ID isn't in use */
+int _menuid_allocated(int id)
+{
+   SignalHandler *tmp = Root;
+
+   while(tmp)
+   {
+     if(tmp->id == id)
+        return TRUE;   
+     tmp = tmp->next;
+   }
+   return FALSE;
 }
 
 /*
@@ -4299,46 +5036,94 @@
  *       flags: Extended attributes to set on the menu.
  *       end: If TRUE memu is positioned at the end of the menu.
  *       check: If TRUE menu is "check"able.
+ *       flags: Extended attributes to set on the menu.
  *       submenu: Handle to an existing menu to be a submenu or NULL.
  */
 HWND API dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu)
 {
-	MENUITEM miSubMenu;
-	char buffer[15];
-
-	check = check; /* keep compiler happy */
-	if(!menux || id > 65536)
-		return NULLHANDLE;
-
-	if(end)
-		miSubMenu.iPosition=MIT_END;
-	else
-		miSubMenu.iPosition=0;
-
-	if(strlen(title) == 0)
-		miSubMenu.afStyle=MIS_SEPARATOR | flags;
-	else
-		miSubMenu.afStyle=MIS_TEXT | flags;
-	miSubMenu.afAttribute=0;
-	miSubMenu.id=id;
-	miSubMenu.hwndSubMenu = submenu;
-	miSubMenu.hItem=NULLHANDLE;
-
-	WinSendMsg(menux,
-			   MM_INSERTITEM,
-			   MPFROMP(&miSubMenu),
-			   MPFROMP(title));
-
-	sprintf(buffer, "_dw_id%d", (int)id);
-	dw_window_set_data(hwndApp, buffer, (void *)menux);
-
-	if(submenu)
-		dw_window_set_data(submenu, "_dw_owner", (void *)menux);
-	return (HWND)id;
+   MENUITEM miSubMenu;
+   char buffer[30];
+   int is_checked, is_disabled;
+
+   if ( !menux || !WinIsWindow(dwhab, menux) )
+      return NULLHANDLE;
+
+   if ( end )
+      miSubMenu.iPosition=MIT_END;
+   else
+      miSubMenu.iPosition=0;
+   /*
+    * Handle flags
+   */
+   miSubMenu.afAttribute = 0;
+   is_checked = (flags & DW_MIS_CHECKED) ? 1 : 0;
+   if ( is_checked )
+      miSubMenu.afAttribute |= MIA_CHECKED;
+   is_disabled = (flags & DW_MIS_DISABLED) ? 1 : 0;
+   if ( is_disabled )
+      miSubMenu.afAttribute |= MIA_DISABLED;
+
+   if (title && *title)
+   {
+      /* Code to autogenerate a menu ID if not specified or invalid
+       * First pool is smaller for transient popup menus 
+       */
+      if(id == (ULONG)-1)
+      {
+         static ULONG tempid = 61000;
+         
+         tempid++;
+         id = tempid;
+         
+         if(tempid > 65500)
+            tempid = 61000;
+      }
+      /* Special internal case */
+      else if(id > 60000 && check == -1)
+      {
+          check = 0;
+      }
+      /* Second pool is larger for more static windows */
+      else if(!id || id >= 30000)
+      {
+         static ULONG menuid = 30000;
+         
+         do
+         {
+            menuid++;
+            if(menuid > 60000)
+               menuid = 30000;
+         }
+         while(_menuid_allocated(menuid));
+         id = menuid;
+      }
+      miSubMenu.afStyle = MIS_TEXT;
+   }
+   else
+      miSubMenu.afStyle = MIS_SEPARATOR;
+   miSubMenu.id=id;
+   miSubMenu.hwndSubMenu = submenu;
+   miSubMenu.hItem=NULLHANDLE;
+
+   WinSendMsg(menux, MM_INSERTITEM, MPFROMP(&miSubMenu), MPFROMP(title));
+
+   sprintf(buffer, "_dw_id%d", (int)id);
+   dw_window_set_data(hwndApp, buffer, (void *)menux);
+   sprintf(buffer, "_dw_checkable%ld", id);
+   dw_window_set_data( hwndApp, buffer, (void *)check );
+   sprintf(buffer, "_dw_ischecked%ld", id);
+   dw_window_set_data( hwndApp, buffer, (void *)is_checked );
+   sprintf(buffer, "_dw_isdisabled%ld", id);
+   dw_window_set_data( hwndApp, buffer, (void *)is_disabled );
+
+   if ( submenu )
+      dw_window_set_data(submenu, "_dw_owner", (void *)menux);
+   return (HWND)id;
 }
 
 /*
  * Sets the state of a menu item check.
+ * Deprecated; use dw_menu_item_set_state()
  * Parameters:
  *       menu: The handle the the existing menu.
  *       id: Menuitem id.
@@ -4346,12 +5131,106 @@
  */
 void API dw_menu_item_set_check(HMENUI menux, unsigned long id, int check)
 {
-	if(check)
-		WinSendMsg(menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE),
-				   MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
-	else
-		WinSendMsg(menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE),
-				   MPFROM2SHORT(MIA_CHECKED, 0));
+   if ( check )
+      WinSendMsg(menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE),MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
+   else
+      WinSendMsg(menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE),MPFROM2SHORT(MIA_CHECKED, 0));
+}
+
+/*
+ * Sets the state of a menu item.
+ * Parameters:
+ *       menu: The handle to the existing menu.
+ *       id: Menuitem id.
+ *       flags: DW_MIS_ENABLED/DW_MIS_DISABLED
+ *              DW_MIS_CHECKED/DW_MIS_UNCHECKED
+ */
+void API dw_menu_item_set_state( HMENUI menux, unsigned long id, unsigned long state)
+{
+   char buffer1[30],buffer2[30];
+   int check;
+   int disabled;
+   USHORT fAttribute=0;
+
+   sprintf( buffer1, "_dw_ischecked%ld", id );
+   check = (int)dw_window_get_data( hwndApp, buffer1 );
+   sprintf( buffer2, "_dw_isdisabled%ld", id );
+   disabled = (int)dw_window_get_data( hwndApp, buffer2 );
+
+   if ( (state & DW_MIS_CHECKED) || (state & DW_MIS_UNCHECKED) )
+   {
+      /*
+       * If we are changing state of "checked" base our setting on the passed flag...
+       */
+      if ( state & DW_MIS_CHECKED )
+      {
+         fAttribute |= MIA_CHECKED;
+         check = 1;
+      }
+      else
+      {
+         check = 0;
+      }
+   }
+   else
+   {
+      /*
+       * ...otherwise base our setting on the current "checked" state.
+       */
+      if ( check )
+      {
+         fAttribute |= MIA_CHECKED;
+      }
+   }
+   if ( (state & DW_MIS_ENABLED) || (state & DW_MIS_DISABLED) )
+   {
+      if ( state & DW_MIS_DISABLED )
+      {
+         fAttribute |= MIA_DISABLED;
+         disabled = 1;
+      }
+      else
+      {
+         disabled = 0;
+      }
+   }
+   else
+   {
+      /*
+       * ...otherwise base our setting on the current "disabled" state.
+       */
+      if ( disabled )
+      {
+         fAttribute |= MIA_DISABLED;
+      }
+   }
+   WinSendMsg( menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), MPFROM2SHORT( MIA_CHECKED|MIA_DISABLED, fAttribute ) );
+   /*
+    * Keep our internal checked state consistent
+    */
+   dw_window_set_data( hwndApp, buffer1, (void *)check );
+   dw_window_set_data( hwndApp, buffer2, (void *)disabled );
+}
+
+/*
+ * Deletes the menu item specified
+ * Parameters:
+ *       menu: The handle to the  menu in which the item was appended.
+ *       id: Menuitem id.
+ * Returns: 
+ *       DW_ERROR_NONE (0) on success or DW_ERROR_UNKNOWN on failure.
+ */
+int API dw_menu_delete_item(HMENUI menux, unsigned long id)
+{
+   if(id < 65536 && menux)
+   {
+      WinSendMsg(menux, MM_DELETEITEM, MPFROM2SHORT(id, FALSE), 0);
+      /* If the ID was autogenerated it is safe to remove it */
+      if(id >= 30000)
+         dw_signal_disconnect_by_window((HWND)id);
+      return DW_ERROR_NONE;
+   }
+   return DW_ERROR_UNKNOWN;
 }
 
 /*
@@ -4364,12 +5243,12 @@
  */
 void API dw_menu_popup(HMENUI *menu, HWND parent, int x, int y)
 {
-	if(menu)
-	{
-		popup = parent;
-		dw_window_set_data(*menu, "_dw_popup", (void *)1);
-		WinPopupMenu(HWND_DESKTOP, parent, *menu, x, dw_screen_height() - y, 0, PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_VCONSTRAIN | PU_HCONSTRAIN);
-	}
+   if(menu)
+   {
+      popup = parent;
+      dw_window_set_data(*menu, "_dw_popup", (void *)1);
+      WinPopupMenu(HWND_DESKTOP, parent, *menu, x, dw_screen_height() - y, 0, PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_VCONSTRAIN | PU_HCONSTRAIN);
+   }
 }
 
 /*
@@ -4380,14 +5259,14 @@
  */
 void API dw_pointer_query_pos(long *x, long *y)
 {
-	POINTL ptl;
-
-	WinQueryPointerPos(HWND_DESKTOP, &ptl);
-	if(x && y)
-	{
-		*x = ptl.x;
-		*y = dw_screen_height() - ptl.y;
-	}
+   POINTL ptl;
+
+   WinQueryPointerPos(HWND_DESKTOP, &ptl);
+   if(x && y)
+   {
+      *x = ptl.x;
+      *y = dw_screen_height() - ptl.y;
+   }
 }
 
 /*
@@ -4398,7 +5277,7 @@
  */
 void API dw_pointer_set_pos(long x, long y)
 {
-	WinSetPointerPos(HWND_DESKTOP, x, dw_screen_height() - y);
+   WinSetPointerPos(HWND_DESKTOP, x, dw_screen_height() - y);
 }
 
 
@@ -4410,24 +5289,24 @@
  */
 HWND API dw_container_new(ULONG id, int multi)
 {
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_CONTAINER,
-							   NULL,
-							   WS_VISIBLE | CCS_READONLY |
-							   (multi ? CCS_EXTENDSEL : CCS_SINGLESEL) |
-							   CCS_AUTOPOSITION,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id ? id : (GlobalID++),
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _TreeProc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_data(tmp, "_dw_container", (void *)1);
-	return tmp;
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_CONTAINER,
+                        NULL,
+                        WS_VISIBLE | CCS_READONLY |
+                        (multi ? CCS_EXTENDSEL : CCS_SINGLESEL) |
+                        CCS_AUTOPOSITION,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id ? id : _GlobalID(),
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _TreeProc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_data(tmp, "_dw_container", (void *)1);
+   return tmp;
 }
 
 /*
@@ -4438,33 +5317,33 @@
  */
 HWND API dw_tree_new(ULONG id)
 {
-	CNRINFO cnrinfo;
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_CONTAINER,
-							   NULL,
-							   WS_VISIBLE | CCS_READONLY |
-							   CCS_SINGLESEL | CCS_AUTOPOSITION,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id ? id : (GlobalID++),
-							   NULL,
-							   NULL);
-
-	cnrinfo.flWindowAttr = CV_TREE | CA_TREELINE;
-	cnrinfo.slBitmapOrIcon.cx = 16;
-	cnrinfo.slBitmapOrIcon.cy = 16;
-	cnrinfo.cyLineSpacing = 0;
-	cnrinfo.cxTreeIndent = 16;
-	cnrinfo.cxTreeLine = 1;
-
-	WinSendMsg(tmp, CM_SETCNRINFO, &cnrinfo, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON |
-														CMA_LINESPACING | CMA_CXTREEINDENT | CMA_CXTREELINE));
-	blah->oldproc = WinSubclassWindow(tmp, _TreeProc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
+   CNRINFO cnrinfo;
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_CONTAINER,
+                        NULL,
+                        WS_VISIBLE | CCS_READONLY |
+                        CCS_SINGLESEL | CCS_AUTOPOSITION,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id ? id : _GlobalID(),
+                        NULL,
+                        NULL);
+
+   cnrinfo.flWindowAttr = CV_TREE | CA_TREELINE;
+   cnrinfo.slBitmapOrIcon.cx = 16;
+   cnrinfo.slBitmapOrIcon.cy = 16;
+   cnrinfo.cyLineSpacing = 0;
+   cnrinfo.cxTreeIndent = 16;
+   cnrinfo.cxTreeLine = 1;
+
+   WinSendMsg(tmp, CM_SETCNRINFO, &cnrinfo, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON |
+                                          CMA_LINESPACING | CMA_CXTREEINDENT | CMA_CXTREELINE));
+   blah->oldproc = WinSubclassWindow(tmp, _TreeProc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
 }
 
 /*
@@ -4475,22 +5354,22 @@
  */
 HWND API dw_text_new(char *text, ULONG id)
 {
-	WindowData *blah = calloc(sizeof(WindowData), 1);
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_STATIC,
-							   text,
-							   WS_VISIBLE | SS_TEXT,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _textproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-	return tmp;
+   WindowData *blah = calloc(sizeof(WindowData), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_STATIC,
+                        (PSZ)text,
+                        WS_VISIBLE | SS_TEXT,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _textproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   return tmp;
 }
 
 /*
@@ -4501,22 +5380,22 @@
  */
 HWND API dw_status_text_new(char *text, ULONG id)
 {
-	WindowData *blah = calloc(sizeof(WindowData), 1);
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_STATIC,
-							   text,
-							   WS_VISIBLE | SS_TEXT,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _statusproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-	return tmp;
+   WindowData *blah = calloc(sizeof(WindowData), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_STATIC,
+                        (PSZ)text,
+                        WS_VISIBLE | SS_TEXT,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _statusproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   return tmp;
 }
 
 #ifndef MLS_LIMITVSCROLL
@@ -4530,24 +5409,25 @@
  */
 HWND API dw_mle_new(ULONG id)
 {
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_MLE,
-							   "",
-							   WS_VISIBLE |
-							   MLS_BORDER | MLS_IGNORETAB |
-							   MLS_READONLY | MLS_VSCROLL |
-							   MLS_LIMITVSCROLL,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _mleproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_MLE,
+                        NULL,
+                        WS_VISIBLE |
+                        MLS_BORDER | MLS_IGNORETAB |
+                        MLS_VSCROLL |
+                        MLS_LIMITVSCROLL,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   WinSendMsg(tmp, MLM_FORMAT, (MPARAM)MLFIE_NOTRANS, 0);
+   blah->oldproc = WinSubclassWindow(tmp, _mleproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
 }
 
 /*
@@ -4559,23 +5439,23 @@
 HWND API dw_entryfield_new(char *text, ULONG id)
 {
 
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_ENTRYFIELD,
-							   text,
-							   WS_VISIBLE | ES_MARGIN |
-							   ES_AUTOSCROLL | WS_TABSTOP,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _entryproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
-	return tmp;
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_ENTRYFIELD,
+                        (PSZ)text,
+                        WS_VISIBLE | ES_MARGIN |
+                        ES_AUTOSCROLL | WS_TABSTOP,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _entryproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
+   return tmp;
 }
 
 /*
@@ -4586,23 +5466,23 @@
  */
 HWND API dw_entryfield_password_new(char *text, ULONG id)
 {
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_ENTRYFIELD,
-							   text,
-							   WS_VISIBLE | ES_MARGIN | ES_UNREADABLE |
-							   ES_AUTOSCROLL | WS_TABSTOP,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _entryproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
-	return tmp;
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_ENTRYFIELD,
+                        (PSZ)text,
+                        WS_VISIBLE | ES_MARGIN | ES_UNREADABLE |
+                        ES_AUTOSCROLL | WS_TABSTOP,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _entryproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
+   return tmp;
 }
 
 /*
@@ -4613,38 +5493,38 @@
  */
 HWND API dw_combobox_new(char *text, ULONG id)
 {
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND frame = dw_box_new(DW_HORZ, 0);
-	HWND tmp = WinCreateWindow(frame,
-							   WC_COMBOBOX,
-							   text,
-							   WS_VISIBLE | CBS_DROPDOWN | WS_GROUP,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	HENUM henum = WinBeginEnumWindows(tmp);
-	HWND child, last = NULLHANDLE;
-	
-	while((child = WinGetNextWindow(henum)) != NULLHANDLE)
-	{
-		WindowData *moreblah = calloc(1, sizeof(WindowData));
-		moreblah->oldproc = WinSubclassWindow(child, _comboentryproc);
-		WinSetWindowPtr(child, QWP_USER, moreblah);
-		dw_window_set_color(child, DW_CLR_BLACK, DW_CLR_WHITE);
-		last = child;
-	}
-	WinEndEnumWindows(henum);
-	blah->oldproc = WinSubclassWindow(tmp, _comboproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
-	dw_window_set_data(tmp, "_dw_comboentry", (void *)last);
-	dw_window_set_data(tmp, "_dw_combo_box", (void *)frame);
-	WinSetOwner(tmp, frame);
-	return tmp;
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND frame = dw_box_new(DW_HORZ, 0);
+   HWND tmp = WinCreateWindow(frame,
+                        WC_COMBOBOX,
+                        (PSZ)text,
+                        WS_VISIBLE | CBS_DROPDOWN | WS_GROUP,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id ? id : _GlobalID(),
+                        NULL,
+                        NULL);
+   HENUM henum = WinBeginEnumWindows(tmp);
+   HWND child, last = NULLHANDLE;
+
+   while((child = WinGetNextWindow(henum)) != NULLHANDLE)
+   {
+      WindowData *moreblah = calloc(1, sizeof(WindowData));
+      moreblah->oldproc = WinSubclassWindow(child, _comboentryproc);
+      WinSetWindowPtr(child, QWP_USER, moreblah);
+      dw_window_set_color(child, DW_CLR_BLACK, DW_CLR_WHITE);
+      last = child;
+   }
+   WinEndEnumWindows(henum);
+   blah->oldproc = WinSubclassWindow(tmp, _comboproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
+   dw_window_set_data(tmp, "_dw_comboentry", (void *)last);
+   dw_window_set_data(tmp, "_dw_combo_box", (void *)frame);
+   WinSetOwner(tmp, frame);
+   return tmp;
 }
 
 /*
@@ -4655,27 +5535,27 @@
  */
 HWND API dw_button_new(char *text, ULONG id)
 {
-	BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
-
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_BUTTON,
-							   text,
-							   WS_VISIBLE,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-
-	bubble->id = id;
-	bubble->bubbletext[0] = '\0';
-	bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
-
-	WinSetWindowPtr(tmp, QWP_USER, bubble);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-	return tmp;
+   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_BUTTON,
+                        (PSZ)text,
+                        WS_VISIBLE,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+
+   bubble->id = id;
+   bubble->bubbletext[0] = '\0';
+   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
+
+   WinSetWindowPtr(tmp, QWP_USER, bubble);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   return tmp;
 }
 
 /* Function: GenResIDStr
@@ -4685,29 +5565,29 @@
 
 void _GenResIDStr(CHAR *buff, ULONG ulID)
 {
-	char *str;
-	int  slen = 0;
-
-	*buff++ = '#';
-
-	str = buff;
-
-	do
-	{
-		*str++ = (ulID % 10) + '0';
-		ulID /= 10;
-		slen++;
-	}
-	while(ulID);
-
-	*str-- = 0;
-
-	for(; str > buff; str--, buff++)
-	{
-		*buff ^= *str;
-		*str  ^= *buff;
-		*buff ^= *str;
-	}
+   char *str;
+   int  slen = 0;
+
+   *buff++ = '#';
+
+   str = buff;
+
+   do
+   {
+      *str++ = (ulID % 10) + '0';
+      ulID /= 10;
+      slen++;
+   }
+   while(ulID);
+
+   *str-- = 0;
+
+   for(; str > buff; str--, buff++)
+   {
+      *buff ^= *str;
+      *str  ^= *buff;
+      *buff ^= *str;
+   }
 }
 
 
@@ -4719,41 +5599,41 @@
  */
 HWND API dw_bitmapbutton_new(char *text, ULONG id)
 {
-	char idbuf[256], *name = NULL;
-	HWND tmp;
-	BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
-	HPOINTER icon = WinLoadPointer(HWND_DESKTOP, 0L, id);
-
-	if(!icon)
-	{
-		name = idbuf;
-		_GenResIDStr(idbuf, id);
-	}
-
-	tmp = WinCreateWindow(HWND_OBJECT,
-						  WC_BUTTON,
-						  name,
-						  WS_VISIBLE | BS_PUSHBUTTON |
-						  BS_NOPOINTERFOCUS | BS_AUTOSIZE |
-						  (icon ? 0 : BS_BITMAP),
-						  0,0,2000,1000,
-						  NULLHANDLE,
-						  HWND_TOP,
-						  id,
-						  NULL,
-						  NULL);
-
-	bubble->id = id;
-	strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
-	bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
-	bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
-
-	WinSetWindowPtr(tmp, QWP_USER, bubble);
-
-	if(icon)
-		dw_window_set_data(tmp, "_dw_button_icon", (void *)icon);
-	dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1);
-	return tmp;
+   char idbuf[256], *name = NULL;
+   HWND tmp;
+   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+   HPOINTER icon = WinLoadPointer(HWND_DESKTOP, 0L, id);
+
+   if(!icon)
+   {
+      name = idbuf;
+      _GenResIDStr(idbuf, id);
+   }
+
+   tmp = WinCreateWindow(HWND_OBJECT,
+                    WC_BUTTON,
+                    (PSZ)name,
+                    WS_VISIBLE | BS_PUSHBUTTON |
+                    BS_NOPOINTERFOCUS | BS_AUTOSIZE |
+                    (icon ? 0 : BS_BITMAP),
+                    0,0,2000,1000,
+                    NULLHANDLE,
+                    HWND_TOP,
+                    id,
+                    NULL,
+                    NULL);
+
+   bubble->id = id;
+   strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
+   bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
+   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
+
+   WinSetWindowPtr(tmp, QWP_USER, bubble);
+
+   if(icon)
+      dw_window_set_data(tmp, "_dw_button_icon", (void *)icon);
+   dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1);
+   return tmp;
 }
 
 /*
@@ -4767,97 +5647,197 @@
  */
 HWND API dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename)
 {
-	BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_BUTTON,
-							   "",
-							   WS_VISIBLE | BS_PUSHBUTTON |
-							   BS_AUTOSIZE | BS_NOPOINTERFOCUS,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	char *file = alloca(strlen(filename) + 5);
-	HPIXMAP pixmap = NULL, disabled = NULL;
-	HPOINTER icon = 0;
-
-	if(file && (pixmap = calloc(1,sizeof(struct _hpixmap))))
-	{
-		int z, j, lim, len;
-		LONG fore;
-
-		strcpy(file, filename);
-
-		/* check if we can read from this file (it exists and read permission) */
-		if(access(file, 04) == 0)
-		{
-			len = strlen( file );
-			if(len > 4)
-			{
-				if(stricmp(file + len - 4, ".ico") == 0)
-					icon = WinLoadFileIcon(file, FALSE);
-				else
-					_load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height);
-			}
-		}
-		else
-		{
-			/* Try with .ico extension first...*/
-			strcat(file, ".ico");
-			if(access(file, 04) == 0)
-				icon = WinLoadFileIcon(file, FALSE);
-			else
-			{
-				strcpy(file, filename);
-				strcat(file, ".bmp");
-				if(access(file, 04) == 0)
-					_load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height);
-			}
-		}
-
-		if(icon)
-		{
-			free(pixmap);
-			pixmap = NULL;
-		}
-		else
-		{
-			/* Create a disabled style pixmap */
-			disabled = dw_pixmap_new(tmp, pixmap->width, pixmap->height, dw_color_depth_get());
-			dw_pixmap_bitblt(0, disabled, 0, 0, pixmap->width, pixmap->height, 0, pixmap, 0, 0);
-
-			fore = _foreground;
-			dw_color_foreground_set(DW_CLR_PALEGRAY);
-			lim = pixmap->width/2;
-			for(j=0;j<pixmap->height;j++)
-			{
-				int mod = j%2;
-
-				for(z=0;z<lim;z++)
-					dw_draw_point(0, disabled, (z*2)+mod, j);
-			}
-			_foreground = fore;
-		}
-	}
-
-	bubble->id = id;
-	strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
-	bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
-	bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
-
-	WinSetWindowPtr(tmp, QWP_USER, bubble);
-
-	if(icon)
-		dw_window_set_data(tmp, "_dw_button_icon", (void *)icon);
-	else
-	{
-		dw_window_set_data(tmp, "_dw_hpixmap", (void *)pixmap);
-		dw_window_set_data(tmp, "_dw_hpixmap_disabled", (void *)disabled);
-	}
-	dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1);
-	return tmp;
+   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_BUTTON,
+                        NULL,
+                        WS_VISIBLE | BS_PUSHBUTTON |
+                        BS_AUTOSIZE | BS_NOPOINTERFOCUS,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   char *file = alloca(strlen(filename) + 5);
+   HPIXMAP pixmap = NULL, disabled = NULL;
+   HPOINTER icon = 0;
+
+   if(file && (pixmap = calloc(1,sizeof(struct _hpixmap))))
+   {
+      int z, j, lim, len;
+      LONG fore;
+
+      strcpy(file, filename);
+
+      /* check if we can read from this file (it exists and read permission) */
+      if(access(file, 04) == 0)
+      {
+         len = strlen( file );
+         if(len > 4)
+         {
+            if(stricmp(file + len - 4, ".ico") == 0)
+               icon = WinLoadFileIcon((PSZ)file, FALSE);
+            else
+               _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height);
+         }
+      }
+      else
+      {
+         /* Try with .ico extension first...*/
+         strcat(file, ".ico");
+         if(access(file, 04) == 0)
+            icon = WinLoadFileIcon((PSZ)file, FALSE);
+         else
+         {
+            strcpy(file, filename);
+            strcat(file, ".bmp");
+            if(access(file, 04) == 0)
+               _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height);
+         }
+      }
+
+      if(icon)
+      {
+         free(pixmap);
+         pixmap = NULL;
+      }
+      else
+      {
+         /* Create a disabled style pixmap */
+         disabled = dw_pixmap_new(tmp, pixmap->width, pixmap->height, dw_color_depth_get());
+         dw_pixmap_bitblt(0, disabled, 0, 0, pixmap->width, pixmap->height, 0, pixmap, 0, 0);
+
+         fore = _foreground;
+         dw_color_foreground_set(DW_CLR_PALEGRAY);
+         lim = pixmap->width/2;
+         for(j=0;j<pixmap->height;j++)
+         {
+            int mod = j%2;
+
+            for(z=0;z<lim;z++)
+               dw_draw_point(0, disabled, (z*2)+mod, j);
+         }
+         _foreground = fore;
+      }
+   }
+
+   bubble->id = id;
+   strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
+   bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
+   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
+
+   WinSetWindowPtr(tmp, QWP_USER, bubble);
+
+   if(icon)
+      dw_window_set_data(tmp, "_dw_button_icon", (void *)icon);
+   else
+   {
+      dw_window_set_data(tmp, "_dw_hpixmap", (void *)pixmap);
+      dw_window_set_data(tmp, "_dw_hpixmap_disabled", (void *)disabled);
+   }
+   dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1);
+   return tmp;
+}
+
+/*
+ * Create a new bitmap button window (widget) to be packed from data.
+ * Parameters:
+ *       text: Bubble help text to be displayed.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ *       data: The contents of the image
+ *            (BMP or ICO on OS/2 or Windows, XPM on Unix)
+ *       len: length of str
+ */
+HWND API dw_bitmapbutton_new_from_data(char *text, unsigned long id, char *data, int len)
+{
+   FILE *fp;
+   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_BUTTON,
+                        NULL,
+                        WS_VISIBLE | BS_PUSHBUTTON |
+                        BS_AUTOSIZE | BS_NOPOINTERFOCUS,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   char *file;
+   HPIXMAP pixmap = NULL, disabled = NULL;
+   HPOINTER icon = 0;
+
+   if ( ( pixmap = calloc( 1, sizeof(struct _hpixmap) ) ) )
+   {
+      int z, j, lim;
+      LONG fore;
+      file = tmpnam( NULL );
+      if ( file != NULL )
+      {
+         fp = fopen( file, "wb" );
+         if ( fp != NULL )
+         {
+            fwrite( data, 1, len, fp );
+            fclose( fp );
+            if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
+            {
+               _load_bitmap_file( file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height );
+            }
+            else /* otherwise its assumed to be an ico */
+            {
+               icon = WinLoadFileIcon((PSZ)file, FALSE);
+            }
+         }
+         else
+         {
+            unlink( file );
+            return 0;
+         }
+         unlink( file );
+      }
+
+      if ( icon )
+      {
+         free(pixmap);
+         pixmap = NULL;
+      }
+      else
+      {
+         /* Create a disabled style pixmap */
+         disabled = dw_pixmap_new(tmp, pixmap->width, pixmap->height, dw_color_depth_get());
+         dw_pixmap_bitblt(0, disabled, 0, 0, pixmap->width, pixmap->height, 0, pixmap, 0, 0);
+
+         fore = _foreground;
+         dw_color_foreground_set(DW_CLR_PALEGRAY);
+         lim = pixmap->width/2;
+         for(j=0;j<pixmap->height;j++)
+         {
+            int mod = j%2;
+
+            for(z=0;z<lim;z++)
+               dw_draw_point(0, disabled, (z*2)+mod, j);
+         }
+         _foreground = fore;
+      }
+   }
+
+   bubble->id = id;
+   strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
+   bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
+   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
+
+   WinSetWindowPtr(tmp, QWP_USER, bubble);
+
+   if(icon)
+      dw_window_set_data(tmp, "_dw_button_icon", (void *)icon);
+   else
+   {
+      dw_window_set_data(tmp, "_dw_hpixmap", (void *)pixmap);
+      dw_window_set_data(tmp, "_dw_hpixmap_disabled", (void *)disabled);
+   }
+   dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1);
+   return tmp;
 }
 
 /*
@@ -4868,26 +5848,29 @@
  */
 HWND API dw_spinbutton_new(char *text, ULONG id)
 {
-	WindowData *blah = calloc(sizeof(WindowData), 1);
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_SPINBUTTON,
-							   text,
-							   WS_VISIBLE | SPBS_MASTER,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	HWND entry = _find_entryfield(tmp);
-	blah->oldproc = WinSubclassWindow(tmp, _entryproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	blah = calloc(sizeof(WindowData), 1);
-	blah->oldproc = WinSubclassWindow(entry, _spinentryproc);
-	WinSetWindowPtr(entry, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(entry, DW_CLR_BLACK, DW_CLR_WHITE);
-	return tmp;
+   WindowData *blah = calloc(sizeof(WindowData), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_SPINBUTTON,
+                        (PSZ)text,
+                        WS_VISIBLE | SPBS_MASTER,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   HWND entry = _find_entryfield(tmp);
+   WinSendMsg(tmp, SPBM_SETLIMITS, MPFROMLONG(65536), MPFROMLONG(-65536));
+   WinSendMsg(tmp, SPBM_SETCURRENTVALUE, MPFROMLONG(atoi(text)), 0L);
+   blah->oldproc = WinSubclassWindow(tmp, _entryproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   blah = calloc(sizeof(WindowData), 1);
+   blah->oldproc = WinSubclassWindow(entry, _spinentryproc);
+   WinSetWindowPtr(entry, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(entry, DW_CLR_BLACK, DW_CLR_WHITE);
+   dw_window_set_data(tmp, "_dw_buddy", (void *)entry);
+   return tmp;
 }
 
 /*
@@ -4898,23 +5881,23 @@
  */
 HWND API dw_radiobutton_new(char *text, ULONG id)
 {
-	WindowData *blah = calloc(sizeof(WindowData), 1);
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_BUTTON,
-							   text,
-							   WS_VISIBLE |
-							   BS_AUTORADIOBUTTON,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _entryproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-	return tmp;
+   WindowData *blah = calloc(sizeof(WindowData), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_BUTTON,
+                        (PSZ)text,
+                        WS_VISIBLE |
+                        BS_AUTORADIOBUTTON,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _entryproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   return tmp;
 }
 
 
@@ -4927,28 +5910,28 @@
  */
 HWND API dw_slider_new(int vertical, int increments, ULONG id)
 {
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	SLDCDATA sldcData = { 0, 0, 0, 0, 0 };
-	HWND tmp;
-
-	sldcData.cbSize = sizeof(SLDCDATA);
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   SLDCDATA sldcData = { 0, 0, 0, 0, 0 };
+   HWND tmp;
+
+   sldcData.cbSize = sizeof(SLDCDATA);
     sldcData.usScale1Increments = increments;
 
-	tmp = WinCreateWindow(HWND_OBJECT,
-						  WC_SLIDER,
-						  "",
-						  WS_VISIBLE | SLS_SNAPTOINCREMENT |
-						  (vertical ? SLS_VERTICAL : SLS_HORIZONTAL),
-						  0,0,2000,1000,
-						  NULLHANDLE,
-						  HWND_TOP,
-						  id,
-						  &sldcData,
-						  NULL);
-
-	blah->oldproc = WinSubclassWindow(tmp, _entryproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	return tmp;
+   tmp = WinCreateWindow(HWND_OBJECT,
+                    WC_SLIDER,
+                    NULL,
+                    WS_VISIBLE | SLS_SNAPTOINCREMENT |
+                    (vertical ? SLS_VERTICAL : SLS_HORIZONTAL),
+                    0,0,2000,1000,
+                    NULLHANDLE,
+                    HWND_TOP,
+                    id ? id : _GlobalID(),
+                    &sldcData,
+                    NULL);
+
+   blah->oldproc = WinSubclassWindow(tmp, _entryproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   return tmp;
 }
 
 /*
@@ -4960,17 +5943,17 @@
  */
 HWND API dw_scrollbar_new(int vertical, ULONG id)
 {
-	return WinCreateWindow(HWND_OBJECT,
-						   WC_SCROLLBAR,
-						   "",
-						   WS_VISIBLE | SBS_AUTOTRACK |
-						   (vertical ? SBS_VERT : SBS_HORZ),
-						   0,0,2000,1000,
-						   NULLHANDLE,
-						   HWND_TOP,
-						   id ? id : (GlobalID++),
-						   NULL,
-						   NULL);
+   return WinCreateWindow(HWND_OBJECT,
+                     WC_SCROLLBAR,
+                     NULL,
+                     WS_VISIBLE | SBS_AUTOTRACK |
+                     (vertical ? SBS_VERT : SBS_HORZ),
+                     0,0,2000,1000,
+                     NULLHANDLE,
+                     HWND_TOP,
+                     id ? id : _GlobalID(),
+                     NULL,
+                     NULL);
 }
 
 /*
@@ -4980,22 +5963,22 @@
  */
 HWND API dw_percent_new(ULONG id)
 {
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_SLIDER,
-							   "",
-							   WS_VISIBLE | SLS_READONLY
-							   | SLS_RIBBONSTRIP,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _percentproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_disable(tmp);
-	return tmp;
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_SLIDER,
+                        NULL,
+                        WS_VISIBLE | SLS_READONLY
+                        | SLS_RIBBONSTRIP,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id ? id : _GlobalID(),
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _percentproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_disable(tmp);
+   return tmp;
 }
 
 /*
@@ -5006,24 +5989,24 @@
  */
 HWND API dw_checkbox_new(char *text, ULONG id)
 {
-	BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_BUTTON,
-							   text,
-							   WS_VISIBLE | BS_AUTOCHECKBOX,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	bubble->id = id;
-	bubble->bubbletext[0] = '\0';
-	bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
-	WinSetWindowPtr(tmp, QWP_USER, bubble);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-	return tmp;
+   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_BUTTON,
+                        (PSZ)text,
+                        WS_VISIBLE | BS_AUTOCHECKBOX,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   bubble->id = id;
+   bubble->bubbletext[0] = '\0';
+   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
+   WinSetWindowPtr(tmp, QWP_USER, bubble);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   return tmp;
 }
 
 /*
@@ -5034,23 +6017,23 @@
  */
 HWND API dw_listbox_new(ULONG id, int multi)
 {
-	WindowData *blah = calloc(sizeof(WindowData), 1);
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_LISTBOX,
-							   NULL,
-							   WS_VISIBLE | LS_NOADJUSTPOS |
-							   (multi ? LS_MULTIPLESEL : 0),
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id ? id : (GlobalID++),
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _entryproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
-	return tmp;
+   WindowData *blah = calloc(sizeof(WindowData), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_LISTBOX,
+                        NULL,
+                        WS_VISIBLE | LS_NOADJUSTPOS |
+                        (multi ? LS_MULTIPLESEL : 0),
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id ? id : _GlobalID(),
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _entryproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
+   return tmp;
 }
 
 /*
@@ -5059,10 +6042,10 @@
  *       handle: Handle to the window.
  *       id: An ID to be used to specify the icon.
  */
-void API dw_window_set_icon(HWND handle, ULONG id)
-{
-	HPOINTER icon = id < 65536 ? WinLoadPointer(HWND_DESKTOP,NULLHANDLE,id) : (HPOINTER)id;
-	WinSendMsg(handle, WM_SETICON, (MPARAM)icon, 0);
+void API dw_window_set_icon(HWND handle, HICN icon)
+{
+   HPOINTER hptr = icon < 65536 ? WinLoadPointer(HWND_DESKTOP,NULLHANDLE,icon) : (HPOINTER)icon;
+   WinSendMsg(handle, WM_SETICON, (MPARAM)hptr, 0);
 }
 
 /* Internal function to load a bitmap from a file and return handles
@@ -5070,104 +6053,104 @@
  */
 int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height)
 {
-	HFILE BitmapFileHandle = NULLHANDLE; /* handle for the file */
-	ULONG OpenAction = 0;
-	PBYTE BitmapFileBegin; /* pointer to the first byte of bitmap data  */
-	FILESTATUS BitmapStatus;
-	ULONG cbRead;
-	PBITMAPFILEHEADER2 pBitmapFileHeader;
-	PBITMAPINFOHEADER2 pBitmapInfoHeader;
-	ULONG ScanLines, ulFlags;
-	HPS hps1;
-	HDC hdc1;
-	SIZEL sizl = { 0, 0 };
-
-	/* open bitmap file */
-	DosOpen(file, &BitmapFileHandle, &OpenAction, 0L,
-			FILE_ARCHIVED | FILE_NORMAL | FILE_READONLY,
-			OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
-			OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY |
-			OPEN_FLAGS_NOINHERIT, 0L);
-
-	if(!BitmapFileHandle)
-		return 0;
-
-	/* find out how big the file is  */
-	DosQueryFileInfo(BitmapFileHandle, 1, &BitmapStatus,
-					 sizeof(BitmapStatus));
-
-	/* allocate memory to load the bitmap */
-	DosAllocMem((PPVOID)&BitmapFileBegin, (ULONG)BitmapStatus.cbFile,
-				PAG_READ | PAG_WRITE | PAG_COMMIT);
-
-	/* read bitmap file into memory buffer */
-	DosRead(BitmapFileHandle, (PVOID)BitmapFileBegin,
-			BitmapStatus.cbFile, &cbRead);
-
-	/* access first bytes as bitmap header */
-	pBitmapFileHeader = (PBITMAPFILEHEADER2)BitmapFileBegin;
-
-	/* check if it's a valid bitmap data file */
-	if((pBitmapFileHeader->usType != BFT_BITMAPARRAY) &&
-	   (pBitmapFileHeader->usType != BFT_BMAP))
-	{
-		/* free memory of bitmap file buffer */
-		DosFreeMem(BitmapFileBegin);
-		/* close the bitmap file */
-		DosClose(BitmapFileHandle);
-		return 0;
-	}
-
-	/* check if it's a file with multiple bitmaps */
-	if(pBitmapFileHeader->usType == BFT_BITMAPARRAY)
-	{
-		/* we'll just use the first bitmap and ignore the others */
-		pBitmapFileHeader = &(((PBITMAPARRAYFILEHEADER2)BitmapFileBegin)->bfh2);
-	}
-
-	/* set pointer to bitmap information block */
-	pBitmapInfoHeader = &pBitmapFileHeader->bmp2;
-
-	/* find out if it's the new 2.0 format or the old format */
-	/* and query number of lines */
-	if(pBitmapInfoHeader->cbFix == sizeof(BITMAPINFOHEADER))
-	{
-		*height = ScanLines = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cy;
-		*width = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cx;
-	}
-	else
-	{
-		*height = ScanLines = pBitmapInfoHeader->cy;
-		*width = pBitmapInfoHeader->cx;
-	}
-
-	/* now we need a presentation space, get it from static control */
-	hps1 = WinGetPS(handle);
-
-	hdc1    = GpiQueryDevice(hps1);
-	ulFlags = GpiQueryPS(hps1, &sizl);
-
-	*hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc1);
-	*hps = GpiCreatePS (dwhab, *hdc, &sizl, ulFlags | GPIA_ASSOC);
-
-	/* create bitmap now using the parameters from the info block */
-	*hbm = GpiCreateBitmap(*hps, pBitmapInfoHeader, 0L, NULL, NULL);
-
-	/* select the new bitmap into presentation space */
-	GpiSetBitmap(*hps, *hbm);
-
-	/* now copy the bitmap data into the bitmap */
-	GpiSetBitmapBits(*hps, 0L, ScanLines,
-					 BitmapFileBegin + pBitmapFileHeader->offBits,
-					 (PBITMAPINFO2)pBitmapInfoHeader);
-
-	WinReleasePS(hps1);
-
-	/* free memory of bitmap file buffer */
-	DosFreeMem(BitmapFileBegin);
-	/* close the bitmap file */
-	DosClose(BitmapFileHandle);
-	return 1;
+   HFILE BitmapFileHandle = NULLHANDLE; /* handle for the file */
+   ULONG OpenAction = 0;
+   PBYTE BitmapFileBegin; /* pointer to the first byte of bitmap data  */
+   FILESTATUS BitmapStatus;
+   ULONG cbRead;
+   PBITMAPFILEHEADER2 pBitmapFileHeader;
+   PBITMAPINFOHEADER2 pBitmapInfoHeader;
+   ULONG ScanLines, ulFlags;
+   HPS hps1;
+   HDC hdc1;
+   SIZEL sizl = { 0, 0 };
+
+   /* open bitmap file */
+   DosOpen((PSZ)file, &BitmapFileHandle, &OpenAction, 0L,
+         FILE_ARCHIVED | FILE_NORMAL | FILE_READONLY,
+         OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
+         OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY |
+         OPEN_FLAGS_NOINHERIT, 0L);
+
+   if(!BitmapFileHandle)
+      return 0;
+
+   /* find out how big the file is  */
+   DosQueryFileInfo(BitmapFileHandle, 1, &BitmapStatus,
+                sizeof(BitmapStatus));
+
+   /* allocate memory to load the bitmap */
+   DosAllocMem((PPVOID)&BitmapFileBegin, (ULONG)BitmapStatus.cbFile,
+            PAG_READ | PAG_WRITE | PAG_COMMIT);
+
+   /* read bitmap file into memory buffer */
+   DosRead(BitmapFileHandle, (PVOID)BitmapFileBegin,
+         BitmapStatus.cbFile, &cbRead);
+
+   /* access first bytes as bitmap header */
+   pBitmapFileHeader = (PBITMAPFILEHEADER2)BitmapFileBegin;
+
+   /* check if it's a valid bitmap data file */
+   if((pBitmapFileHeader->usType != BFT_BITMAPARRAY) &&
+      (pBitmapFileHeader->usType != BFT_BMAP))
+   {
+      /* free memory of bitmap file buffer */
+      DosFreeMem(BitmapFileBegin);
+      /* close the bitmap file */
+      DosClose(BitmapFileHandle);
+      return 0;
+   }
+
+   /* check if it's a file with multiple bitmaps */
+   if(pBitmapFileHeader->usType == BFT_BITMAPARRAY)
+   {
+      /* we'll just use the first bitmap and ignore the others */
+      pBitmapFileHeader = &(((PBITMAPARRAYFILEHEADER2)BitmapFileBegin)->bfh2);
+   }
+
+   /* set pointer to bitmap information block */
+   pBitmapInfoHeader = &pBitmapFileHeader->bmp2;
+
+   /* find out if it's the new 2.0 format or the old format */
+   /* and query number of lines */
+   if(pBitmapInfoHeader->cbFix == sizeof(BITMAPINFOHEADER))
+   {
+      *height = ScanLines = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cy;
+      *width = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cx;
+   }
+   else
+   {
+      *height = ScanLines = pBitmapInfoHeader->cy;
+      *width = pBitmapInfoHeader->cx;
+   }
+
+   /* now we need a presentation space, get it from static control */
+   hps1 = WinGetPS(handle);
+
+   hdc1    = GpiQueryDevice(hps1);
+   ulFlags = GpiQueryPS(hps1, &sizl);
+
+   *hdc = DevOpenDC(dwhab, OD_MEMORY, (PSZ)"*", 0L, NULL, hdc1);
+   *hps = GpiCreatePS (dwhab, *hdc, &sizl, ulFlags | GPIA_ASSOC);
+
+   /* create bitmap now using the parameters from the info block */
+   *hbm = GpiCreateBitmap(*hps, pBitmapInfoHeader, 0L, NULL, NULL);
+
+   /* select the new bitmap into presentation space */
+   GpiSetBitmap(*hps, *hbm);
+
+   /* now copy the bitmap data into the bitmap */
+   GpiSetBitmapBits(*hps, 0L, ScanLines,
+                BitmapFileBegin + pBitmapFileHeader->offBits,
+                (PBITMAPINFO2)pBitmapInfoHeader);
+
+   WinReleasePS(hps1);
+
+   /* free memory of bitmap file buffer */
+   DosFreeMem(BitmapFileBegin);
+   /* close the bitmap file */
+   DosClose(BitmapFileHandle);
+   return 1;
 }
 
 /*
@@ -5182,55 +6165,124 @@
  */
 void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename)
 {
-	HBITMAP hbm;
-	HPS     hps;
-
-	/* Destroy any old bitmap data */
-	_free_bitmap(handle);
-
-	/* If id is non-zero use the resource */
-	if(id)
-	{
-		hps = WinGetPS(handle);
-
-		hbm = GpiLoadBitmap(hps, NULLHANDLE, id, 0, 0);
-	}
-	else if(filename)
-	{
-		HDC hdc;
-		unsigned long width, height;
-		char *file = alloca(strlen(filename) + 5);
-
-		if(!file)
-			return;
-
-		strcpy(file, filename);
-
-		/* check if we can read from this file (it exists and read permission) */
-		if(access(file, 04) != 0)
-		{
-			/* Try with .bmp extention */
-			strcat(file, ".bmp");
-			if(access(file, 04) != 0)
-				return;
-		}
-
-		if(!_load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height))
-			return;
-
-		dw_window_set_data(handle, "_dw_hps", (void *)hps);
-		dw_window_set_data(handle, "_dw_hdc", (void *)hdc);
-		dw_window_set_data(handle, "_dw_width", (void *)width);
-		dw_window_set_data(handle, "_dw_height", (void *)height);
-	}
-	else
-		return;
-
-	WinSetWindowBits(handle,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f);
-	WinSendMsg( handle, SM_SETHANDLE, MPFROMP(hbm), NULL );
-	if(id)
-		WinReleasePS(hps);
-	dw_window_set_data(handle, "_dw_bitmap", (void *)hbm);
+   HBITMAP hbm;
+   HPS     hps;
+
+   /* Destroy any old bitmap data */
+   _free_bitmap(handle);
+
+   /* If id is non-zero use the resource */
+   if ( id )
+   {
+      hps = WinGetPS( handle );
+      hbm = GpiLoadBitmap( hps, NULLHANDLE, id, 0, 0 );
+   }
+   else if ( filename )
+   {
+      HDC hdc;
+      unsigned long width, height;
+      char *file = alloca(strlen(filename) + 5);
+
+      if(!file)
+         return;
+
+      strcpy(file, filename);
+
+      /* check if we can read from this file (it exists and read permission) */
+      if(access(file, 04) != 0)
+      {
+         /* Try with .bmp extention */
+         strcat(file, ".bmp");
+         if(access(file, 04) != 0)
+            return;
+      }
+
+      if(!_load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height))
+         return;
+
+      dw_window_set_data(handle, "_dw_hps", (void *)hps);
+      dw_window_set_data(handle, "_dw_hdc", (void *)hdc);
+      dw_window_set_data(handle, "_dw_width", (void *)width);
+      dw_window_set_data(handle, "_dw_height", (void *)height);
+   }
+   else
+      return;
+
+   WinSetWindowBits(handle,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f);
+   WinSendMsg( handle, SM_SETHANDLE, MPFROMP(hbm), NULL );
+   if ( id )
+      WinReleasePS(hps);
+   dw_window_set_data(handle, "_dw_bitmap", (void *)hbm);
+}
+
+/*
+ * Sets the bitmap used for a given static window.
+ * Parameters:
+ *       handle: Handle to the window.
+ *       id: An ID to be used to specify the icon,
+ *           (pass 0 if you use the filename param)
+ *       filename: a path to a file (Bitmap on OS/2 or
+ *                 Windows and a pixmap on Unix, pass
+ *                 NULL if you use the id param)
+ */
+void API dw_window_set_bitmap_from_data(HWND handle, unsigned long id, char *data, int len)
+{
+   HBITMAP hbm;
+   HPS     hps;
+   HDC hdc;
+   unsigned long width, height;
+   char *file;
+   FILE *fp;
+
+   /* Destroy any old bitmap data */
+   _free_bitmap(handle);
+
+   /* If id is non-zero use the resource */
+   if ( id )
+   {
+      hps = WinGetPS( handle );
+      hbm = GpiLoadBitmap( hps, NULLHANDLE, id, 0, 0 );
+   }
+   else if ( data )
+   {
+      file = tmpnam( NULL );
+      if ( file != NULL )
+      {
+         fp = fopen( file, "wb" );
+         if ( fp != NULL )
+         {
+            fwrite( data, 1, len, fp );
+            fclose( fp );
+            if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
+               _load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height);
+            else /* otherwise its assumed to be an ico */
+            {
+               /* con't use ICO ? */
+               unlink( file );
+               return;
+            }
+         }
+         else
+         {
+            unlink( file );
+            return;
+         }
+         unlink( file );
+      }
+
+      dw_window_set_data(handle, "_dw_hps", (void *)hps);
+      dw_window_set_data(handle, "_dw_hdc", (void *)hdc);
+      dw_window_set_data(handle, "_dw_width", (void *)width);
+      dw_window_set_data(handle, "_dw_height", (void *)height);
+   }
+   else
+      return;
+
+   WinSetWindowBits(handle,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f);
+   WinSendMsg( handle, SM_SETHANDLE, MPFROMP(hbm), NULL );
+   if ( id )
+      WinReleasePS(hps);
+   dw_window_set_data(handle, "_dw_bitmap", (void *)hbm);
 }
 
 /*
@@ -5241,7 +6293,8 @@
  */
 void API dw_window_set_text(HWND handle, char *text)
 {
-	WinSetWindowText(handle, text);
+   HWND entryfield = (HWND)dw_window_get_data(handle, "_dw_buddy");
+   WinSetWindowText(entryfield ? entryfield : handle, (PSZ)text);
 }
 
 /*
@@ -5253,12 +6306,13 @@
  */
 char * API dw_window_get_text(HWND handle)
 {
-	int len = WinQueryWindowTextLength(handle);
-	char *tempbuf = calloc(1, len + 2);
-
-	WinQueryWindowText(handle, len + 1, tempbuf);
-
-	return tempbuf;
+   HWND entryfield = (HWND)dw_window_get_data(handle, "_dw_buddy");
+   int len = WinQueryWindowTextLength(entryfield ? entryfield : handle);
+   char *tempbuf = calloc(1, len + 2);
+
+   WinQueryWindowText(entryfield ? entryfield : handle, len + 1, (PSZ)tempbuf);
+
+   return tempbuf;
 }
 
 /*
@@ -5268,47 +6322,60 @@
  */
 void API dw_window_disable(HWND handle)
 {
-	char tmpbuf[100];
-
-	if(dw_window_get_data(handle, "_dw_disabled"))
-		return;
-
-	WinQueryClassName(handle, 99, tmpbuf);
-	dw_window_set_data(handle, "_dw_disabled", (void *)1);
-
-	if(tmpbuf[0] == '#')
-	{
-		int val = atoi(&tmpbuf[1]);
-		HWND hwnd;
-
-		switch(val)
-		{
-		case 2:
-		case 6:
-		case 10:
-		case 32:
-		case 7:
-			hwnd = _find_entryfield(handle);
-			_dw_window_set_color(hwnd ? hwnd : handle, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-			dw_signal_connect(hwnd ? hwnd : handle, DW_SIGNAL_KEY_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
+   char tmpbuf[100];
+
+   if(handle < 65536)
+   {
+      char buffer[30];
+      HMENUI mymenu;
+      
+      sprintf(buffer, "_dw_id%ld", handle);
+      mymenu = (HMENUI)dw_window_get_data(hwndApp, buffer);
+      
+      if(mymenu && WinIsWindow(dwhab, mymenu))
+          dw_menu_item_set_state(mymenu, handle, DW_MIS_DISABLED);
+      return;
+   }
+
+   if(dw_window_get_data(handle, "_dw_disabled"))
+      return;
+
+   WinQueryClassName(handle, 99, (PCH)tmpbuf);
+   dw_window_set_data(handle, "_dw_disabled", (void *)1);
+
+   if(tmpbuf[0] == '#')
+   {
+      int val = atoi(&tmpbuf[1]);
+      HWND hwnd;
+
+      switch(val)
+      {
+      case 2:
+      case 6:
+      case 10:
+      case 32:
+      case 7:
+         hwnd = _find_entryfield(handle);
+         _dw_window_set_color(hwnd ? hwnd : handle, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+         dw_signal_connect(hwnd ? hwnd : handle, DW_SIGNAL_KEY_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
             if(val == 2)
-				dw_signal_connect(handle, DW_SIGNAL_BUTTON_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
-			if(hwnd)
-				dw_window_set_data(hwnd, "_dw_disabled", (void *)1);
-			return;
-		case 3:
-			if(dw_window_get_data(handle, "_dw_bitmapbutton") && !dw_window_get_data(handle, "_dw_hpixmap"))
-				WinEnableWindow(handle, FALSE);
-			else if(dw_window_get_data(handle, "_dw_bitmapbutton") && dw_window_get_data(handle, "_dw_hpixmap_disabled"))
-				WinInvalidateRect(handle, NULL, FALSE);
-			else
-				_dw_window_set_color(handle, DW_CLR_DARKGRAY, DW_CLR_PALEGRAY);
-			dw_signal_connect(handle, DW_SIGNAL_KEY_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
-			dw_signal_connect(handle, DW_SIGNAL_BUTTON_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
-			return;
-		}
-	}
-	WinEnableWindow(handle, FALSE);
+            dw_signal_connect(handle, DW_SIGNAL_BUTTON_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
+         if(hwnd)
+            dw_window_set_data(hwnd, "_dw_disabled", (void *)1);
+         return;
+      case 3:
+         if(dw_window_get_data(handle, "_dw_bitmapbutton") && !dw_window_get_data(handle, "_dw_hpixmap"))
+            WinEnableWindow(handle, FALSE);
+         else if(dw_window_get_data(handle, "_dw_bitmapbutton") && dw_window_get_data(handle, "_dw_hpixmap_disabled"))
+            WinInvalidateRect(handle, NULL, FALSE);
+         else
+            _dw_window_set_color(handle, DW_CLR_DARKGRAY, DW_CLR_PALEGRAY);
+         dw_signal_connect(handle, DW_SIGNAL_KEY_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
+         dw_signal_connect(handle, DW_SIGNAL_BUTTON_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
+         return;
+      }
+   }
+   WinEnableWindow(handle, FALSE);
 }
 
 /*
@@ -5318,19 +6385,32 @@
  */
 void API dw_window_enable(HWND handle)
 {
-	ULONG fore = (ULONG)dw_window_get_data(handle, "_dw_fore");
-	ULONG back = (ULONG)dw_window_get_data(handle, "_dw_back");
-	HWND hwnd = _find_entryfield(handle);
-
-	dw_window_set_data(handle, "_dw_disabled", 0);
-	if(hwnd)
-		dw_window_set_data(hwnd, "_dw_disabled", 0);
-	if(fore && back)
-		_dw_window_set_color(hwnd ? hwnd : handle, fore-1, back-1);
-	dw_signal_disconnect_by_data(handle, (void *)100);
-	WinEnableWindow(handle, TRUE);
-	if(dw_window_get_data(handle, "_dw_bitmapbutton") && dw_window_get_data(handle, "_dw_hpixmap_disabled"))
-		WinInvalidateRect(handle, NULL, FALSE);
+   ULONG fore = (ULONG)dw_window_get_data(handle, "_dw_fore");
+   ULONG back = (ULONG)dw_window_get_data(handle, "_dw_back");
+   HWND hwnd = _find_entryfield(handle);
+
+   if(handle < 65536)
+   {
+      char buffer[30];
+      HMENUI mymenu;
+      
+      sprintf(buffer, "_dw_id%ld", handle);
+      mymenu = (HMENUI)dw_window_get_data(hwndApp, buffer);
+      
+      if(mymenu && WinIsWindow(dwhab, mymenu))
+          dw_menu_item_set_state(mymenu, handle, DW_MIS_ENABLED);
+      return;
+   }
+
+   dw_window_set_data(handle, "_dw_disabled", 0);
+   if(hwnd)
+      dw_window_set_data(hwnd, "_dw_disabled", 0);
+   if(fore && back)
+      _dw_window_set_color(hwnd ? hwnd : handle, fore-1, back-1);
+   dw_signal_disconnect_by_data(handle, (void *)100);
+   WinEnableWindow(handle, TRUE);
+   if(dw_window_get_data(handle, "_dw_bitmapbutton") && dw_window_get_data(handle, "_dw_hpixmap_disabled"))
+      WinInvalidateRect(handle, NULL, FALSE);
 }
 
 /*
@@ -5341,31 +6421,170 @@
  */
 HWND API dw_window_from_id(HWND handle, int id)
 {
-	HENUM henum;
-	HWND child;
-	char tmpbuf[100];
-
-	henum = WinBeginEnumWindows(handle);
-	while((child = WinGetNextWindow(henum)) != NULLHANDLE)
-	{
-		int windowid = WinQueryWindowUShort(child, QWS_ID);
-		HWND found;
-
-		WinQueryClassName(child, 99, tmpbuf);
-
-		/* If the child is a box (frame) then recurse into it */
-		if(strncmp(tmpbuf, "#1", 3)==0)
-			if((found = dw_window_from_id(child, id)) != NULLHANDLE)
-				return found;
-
-		if(windowid && windowid == id)
-		{
-			WinEndEnumWindows(henum);
-			return child;
-		}
-	}
-	WinEndEnumWindows(henum);
-	return NULLHANDLE;
+   HENUM henum;
+   HWND child;
+   char tmpbuf[100];
+
+   henum = WinBeginEnumWindows(handle);
+   while((child = WinGetNextWindow(henum)) != NULLHANDLE)
+   {
+      int windowid = WinQueryWindowUShort(child, QWS_ID);
+      HWND found;
+
+      WinQueryClassName(child, 99, (PCH)tmpbuf);
+
+      /* If the child is a box (frame) then recurse into it */
+      if(strncmp(tmpbuf, "#1", 3)==0)
+         if((found = dw_window_from_id(child, id)) != NULLHANDLE)
+            return found;
+
+      if(windowid && windowid == id)
+      {
+         WinEndEnumWindows(henum);
+         return child;
+      }
+   }
+   WinEndEnumWindows(henum);
+   return NULLHANDLE;
+}
+
+/* Internal box packing function called by the other 3 functions */
+void _dw_box_pack(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad, char *funcname)
+{
+   Box *thisbox;
+   
+      /*
+       * If you try and pack an item into itself VERY bad things can happen; like at least an
+       * infinite loop on GTK! Lets be safe!
+       */
+   if(box == item)
+   {
+      dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!");
+      return;
+   }
+
+   if(WinWindowFromID(box, FID_CLIENT))
+   {
+      HWND intbox = (HWND)dw_window_get_data(box, "_dw_box");
+      if(intbox)
+      {
+         box = intbox;
+      }
+      else
+      {
+         box = WinWindowFromID(box, FID_CLIENT);
+         hsize = vsize = TRUE;
+      }
+   }
+   
+   thisbox = WinQueryWindowPtr(box, QWP_USER);
+
+   if(thisbox)
+   {
+      int z, x = 0;
+      Item *tmpitem, *thisitem = thisbox->items;
+      char tmpbuf[100];
+      HWND frame = (HWND)dw_window_get_data(item, "_dw_combo_box");
+
+      /* Do some sanity bounds checking */
+      if(index < 0)
+        index = 0;
+      if(index > thisbox->count)
+        index = thisbox->count;
+        
+      tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
+
+      for(z=0;z<thisbox->count;z++)
+      {
+         if(z == index)
+            x++;
+         tmpitem[x] = thisitem[z];
+         x++;
+      }
+
+
+      WinQueryClassName(item, 99, (PCH)tmpbuf);
+
+      if(vsize && !height)
+         height = 1;
+      if(hsize && !width)
+         width = 1;
+
+      if(strncmp(tmpbuf, "#1", 3)==0)
+         tmpitem[index].type = TYPEBOX;
+      else
+      {
+         if ( width == 0 && hsize == FALSE )
+            dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item);
+         if ( height == 0 && vsize == FALSE )
+            dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item);
+
+         tmpitem[index].type = TYPEITEM;
+      }
+
+      tmpitem[index].hwnd = item;
+      tmpitem[index].origwidth = tmpitem[index].width = width;
+      tmpitem[index].origheight = tmpitem[index].height = height;
+      tmpitem[index].pad = pad;
+      if(hsize)
+         tmpitem[index].hsize = SIZEEXPAND;
+      else
+         tmpitem[index].hsize = SIZESTATIC;
+
+      if(vsize)
+         tmpitem[index].vsize = SIZEEXPAND;
+      else
+         tmpitem[index].vsize = SIZESTATIC;
+
+      thisbox->items = tmpitem;
+
+      if(thisbox->count)
+         free(thisitem);
+
+      thisbox->count++;
+
+      WinQueryClassName(item, 99, (PCH)tmpbuf);
+      /* Don't set the ownership if it's an entryfield or spinbutton */
+      if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0 && strncmp(tmpbuf, "#2", 3)!=0)
+         WinSetOwner(item, box);
+      WinSetParent(frame ? frame : item, box, FALSE);
+   }
+}
+
+/*
+ * Pack windows (widgets) into a box at an arbitrary location.
+ * Parameters:
+ *       box: Window handle of the box to be packed into.
+ *       item: Window handle of the item to be back.
+ *       index: 0 based index of packed items. 
+ *       width: Width in pixels of the item or -1 to be self determined.
+ *       height: Height in pixels of the item or -1 to be self determined.
+ *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
+ *       vsize: TRUE if the window (widget) should expand vertically to fill space given.
+ *       pad: Number of pixels of padding around the item.
+ */
+void API dw_box_pack_at_index(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad)
+{
+    _dw_box_pack(box, item, index, width, height, hsize, vsize, pad, "dw_box_pack_at_index()");
+}
+
+/*
+ * Pack windows (widgets) into a box from the start (or top).
+ * Parameters:
+ *       box: Window handle of the box to be packed into.
+ *       item: Window handle of the item to be back.
+ *       width: Width in pixels of the item or -1 to be self determined.
+ *       height: Height in pixels of the item or -1 to be self determined.
+ *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
+ *       vsize: TRUE if the window (widget) should expand vertically to fill space given.
+ *       pad: Number of pixels of padding around the item.
+ */
+void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
+{
+    /* 65536 is the table limit on GTK... 
+     * seems like a high enough value we will never hit it here either.
+     */
+    _dw_box_pack(box, item, 65536, width, height, hsize, vsize, pad, "dw_box_pack_start()");
 }
 
 /*
@@ -5381,91 +6600,7 @@
  */
 void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
 {
-	char *funcname = "dw_box_pack_end()";
-
-		/*
-		 * If you try and pack an item into itself VERY bad things can happen; like at least an
-		 * infinite loop on GTK! Lets be safe!
-		 */
-	if(box == item)
-	{
-		dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!");
-		return;
-	}
-
-	if(WinWindowFromID(box, FID_CLIENT))
-	{
-		box = WinWindowFromID(box, FID_CLIENT);
-		hsize = TRUE;
-		vsize = TRUE;
-	}
-	_dw_box_pack_end(box, item, width, height, hsize, vsize, pad, funcname);
-}
-
-void _dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname)
-{
-	Box *thisbox = WinQueryWindowPtr(box, QWP_USER);
-
-	if(thisbox)
-	{
-		int z;
-		Item *tmpitem, *thisitem = thisbox->items;
-		char tmpbuf[100];
-		HWND frame = (HWND)dw_window_get_data(item, "_dw_combo_box");
-
-		tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
-
-		for(z=0;z<thisbox->count;z++)
-		{
-			tmpitem[z+1] = thisitem[z];
-		}
-
-		WinQueryClassName(item, 99, tmpbuf);
-
-		if(vsize && !height)
-			height = 1;
-		if(hsize && !width)
-			width = 1;
-
-		if(strncmp(tmpbuf, "#1", 3)==0)
-			tmpitem[0].type = TYPEBOX;
-		else
-		{
-			if ( width == 0 && hsize == FALSE )
-				dw_messagebox(functionname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item);
-			if ( height == 0 && vsize == FALSE )
-				dw_messagebox(functionname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item);
-
-			tmpitem[0].type = TYPEITEM;
-		}
-
-		tmpitem[0].hwnd = item;
-		tmpitem[0].origwidth = tmpitem[0].width = width;
-		tmpitem[0].origheight = tmpitem[0].height = height;
-		tmpitem[0].pad = pad;
-		if(hsize)
-			tmpitem[0].hsize = SIZEEXPAND;
-		else
-			tmpitem[0].hsize = SIZESTATIC;
-
-		if(vsize)
-			tmpitem[0].vsize = SIZEEXPAND;
-		else
-			tmpitem[0].vsize = SIZESTATIC;
-
-		thisbox->items = tmpitem;
-
-		if(thisbox->count)
-			free(thisitem);
-
-		thisbox->count++;
-
-		WinQueryClassName(item, 99, tmpbuf);
-		/* Don't set the ownership if it's an entryfield or spinbutton */
-		if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0 && strncmp(tmpbuf, "#2", 3)!=0)
-			WinSetOwner(item, box);
-		WinSetParent(frame ? frame : item, box, FALSE);
-	}
+    _dw_box_pack(box, item, 0, width, height, hsize, vsize, pad, "dw_box_pack_end()");
 }
 
 /*
@@ -5477,7 +6612,7 @@
  */
 void API dw_window_set_size(HWND handle, ULONG width, ULONG height)
 {
-	WinSetWindowPos(handle, NULLHANDLE, 0, 0, width, height, SWP_SHOW | SWP_SIZE);
+   WinSetWindowPos(handle, NULLHANDLE, 0, 0, width, height, SWP_SHOW | SWP_SIZE);
 }
 
 /*
@@ -5485,7 +6620,7 @@
  */
 int API dw_screen_width(void)
 {
-	return WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN);
+   return WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN);
 }
 
 /*
@@ -5493,18 +6628,18 @@
  */
 int API dw_screen_height(void)
 {
-	return WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN);
+   return WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN);
 }
 
 /* This should return the current color depth */
 unsigned long API dw_color_depth_get(void)
 {
-	HDC hdc = WinOpenWindowDC(HWND_DESKTOP);
-	long colors;
-
-	DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, &colors);
-	DevCloseDC(hdc);
-	return colors;
+   HDC hdc = WinOpenWindowDC(HWND_DESKTOP);
+   long colors;
+
+   DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, &colors);
+   DevCloseDC(hdc);
+   return colors;
 }
 
 
@@ -5515,11 +6650,11 @@
  *          x: X location from the bottom left.
  *          y: Y location from the bottom left.
  */
-void API dw_window_set_pos(HWND handle, ULONG x, ULONG y)
-{
-	int myy = _get_frame_height(handle) - (y + _get_height(handle));
-
-	WinSetWindowPos(handle, NULLHANDLE, x, myy, 0, 0, SWP_MOVE);
+void API dw_window_set_pos(HWND handle, LONG x, LONG y)
+{
+   int myy = _get_frame_height(handle) - (y + _get_height(handle));
+
+   WinSetWindowPos(handle, NULLHANDLE, x, myy, 0, 0, SWP_MOVE);
 }
 
 /*
@@ -5531,11 +6666,11 @@
  *          width: Width of the widget.
  *          height: Height of the widget.
  */
-void API dw_window_set_pos_size(HWND handle, ULONG x, ULONG y, ULONG width, ULONG height)
-{
-	int myy = _get_frame_height(handle) - (y + height);
-
-	WinSetWindowPos(handle, NULLHANDLE, x, myy, width, height, SWP_MOVE | SWP_SIZE | SWP_SHOW);
+void API dw_window_set_pos_size(HWND handle, LONG x, LONG y, ULONG width, ULONG height)
+{
+   int myy = _get_frame_height(handle) - (y + height);
+
+   WinSetWindowPos(handle, NULLHANDLE, x, myy, width, height, SWP_MOVE | SWP_SIZE | SWP_SHOW);
 }
 
 /*
@@ -5547,18 +6682,18 @@
  *          width: Width of the widget.
  *          height: Height of the widget.
  */
-void API dw_window_get_pos_size(HWND handle, ULONG *x, ULONG *y, ULONG *width, ULONG *height)
-{
-	SWP swp;
-	WinQueryWindowPos(handle, &swp);
-	if(x)
-		*x = swp.x;
-	if(y)
-		*y = _get_frame_height(handle) - (swp.y + swp.cy);
-	if(width)
-		*width = swp.cx;
-	if(height)
-		*height = swp.cy;
+void API dw_window_get_pos_size(HWND handle, LONG *x, LONG *y, ULONG *width, ULONG *height)
+{
+   SWP swp;
+   WinQueryWindowPos(handle, &swp);
+   if(x)
+      *x = swp.x;
+   if(y)
+      *y = _get_frame_height(handle) - (swp.y + swp.cy);
+   if(width)
+      *width = swp.cx;
+   if(height)
+      *height = swp.cy;
 }
 
 /*
@@ -5570,7 +6705,19 @@
  */
 void API dw_window_set_style(HWND handle, ULONG style, ULONG mask)
 {
-	WinSetWindowBits(handle, QWL_STYLE, style, mask);
+   if(handle < 65536)
+   {
+      char buffer[30];
+      HMENUI mymenu;
+      
+      sprintf(buffer, "_dw_id%ld", handle);
+      mymenu = (HMENUI)dw_window_get_data(hwndApp, buffer);
+      
+      if(mymenu && WinIsWindow(dwhab, mymenu))
+          dw_menu_item_set_state(mymenu, handle, style & mask);
+   }
+   else
+      WinSetWindowBits(handle, QWL_STYLE, style, mask);
 }
 
 /*
@@ -5582,8 +6729,8 @@
  */
 unsigned long API dw_notebook_page_new(HWND handle, ULONG flags, int front)
 {
-	return (ULONG)WinSendMsg(handle, BKM_INSERTPAGE, 0L,
-							 MPFROM2SHORT((BKA_STATUSTEXTON | BKA_AUTOPAGESIZE | BKA_MAJOR | flags), front ? BKA_FIRST : BKA_LAST));
+   return (ULONG)WinSendMsg(handle, BKM_INSERTPAGE, 0L,
+                      MPFROM2SHORT((BKA_STATUSTEXTON | BKA_AUTOPAGESIZE | BKA_MAJOR | flags), front ? BKA_FIRST : BKA_LAST));
 }
 
 /*
@@ -5594,8 +6741,12 @@
  */
 void API dw_notebook_page_destroy(HWND handle, unsigned int pageid)
 {
-	WinSendMsg(handle, BKM_DELETEPAGE,
-			   MPFROMLONG(pageid),	(MPARAM)BKA_SINGLE);
+   HWND pagehwnd = (HWND)WinSendMsg(handle, BKM_QUERYPAGEWINDOWHWND,
+                                    MPFROMLONG(pageid), 0L);
+   WinSendMsg(handle, BKM_DELETEPAGE,
+            MPFROMLONG(pageid),  (MPARAM)BKA_SINGLE);
+   if(pagehwnd)
+      dw_window_destroy(pagehwnd);
 }
 
 /*
@@ -5605,7 +6756,7 @@
  */
 unsigned long API dw_notebook_page_get(HWND handle)
 {
-	return (unsigned long)WinSendMsg(handle, BKM_QUERYPAGEID,0L, MPFROM2SHORT(BKA_TOP, BKA_MAJOR));
+   return (unsigned long)WinSendMsg(handle, BKM_QUERYPAGEID,0L, MPFROM2SHORT(BKA_TOP, BKA_MAJOR));
 }
 
 /*
@@ -5616,7 +6767,7 @@
  */
 void API dw_notebook_page_set(HWND handle, unsigned int pageid)
 {
-	WinSendMsg(handle, BKM_TURNTOPAGE, MPFROMLONG(pageid), 0L);
+   WinSendMsg(handle, BKM_TURNTOPAGE, MPFROMLONG(pageid), 0L);
 }
 
 /*
@@ -5628,8 +6779,8 @@
  */
 void API dw_notebook_page_set_text(HWND handle, ULONG pageid, char *text)
 {
-	WinSendMsg(handle, BKM_SETTABTEXT,
-			   MPFROMLONG(pageid),	MPFROMP(text));
+   WinSendMsg(handle, BKM_SETTABTEXT,
+            MPFROMLONG(pageid),  MPFROMP(text));
 }
 
 /*
@@ -5641,8 +6792,8 @@
  */
 void API dw_notebook_page_set_status_text(HWND handle, ULONG pageid, char *text)
 {
-	WinSendMsg(handle, BKM_SETSTATUSLINETEXT,
-			   MPFROMLONG(pageid),	MPFROMP(text));
+   WinSendMsg(handle, BKM_SETSTATUSLINETEXT,
+            MPFROMLONG(pageid),  MPFROMP(text));
 }
 
 /*
@@ -5654,12 +6805,12 @@
  */
 void API dw_notebook_pack(HWND handle, ULONG pageid, HWND page)
 {
-	HWND tmpbox = dw_box_new(DW_VERT, 0);
-
-	dw_box_pack_start(tmpbox, page, 0, 0, TRUE, TRUE, 0);
-	WinSubclassWindow(tmpbox, _wndproc);
-	WinSendMsg(handle, BKM_SETPAGEWINDOWHWND,
-			   MPFROMLONG(pageid),	MPFROMHWND(tmpbox));
+   HWND tmpbox = dw_box_new(DW_VERT, 0);
+
+   dw_box_pack_start(tmpbox, page, 0, 0, TRUE, TRUE, 0);
+   WinSubclassWindow(tmpbox, _wndproc);
+   WinSendMsg(handle, BKM_SETPAGEWINDOWHWND,
+            MPFROMLONG(pageid),  MPFROMHWND(tmpbox));
 }
 
 /*
@@ -5670,10 +6821,25 @@
  */
 void API dw_listbox_append(HWND handle, char *text)
 {
-	WinSendMsg(handle,
-			   LM_INSERTITEM,
-			   MPFROMSHORT(LIT_END),
-			   MPFROMP(text));
+   WinSendMsg(handle,
+            LM_INSERTITEM,
+            MPFROMSHORT(LIT_END),
+            MPFROMP(text));
+}
+
+/*
+ * Inserts the specified text into the listbox's (or combobox) entry list.
+ * Parameters:
+ *          handle: Handle to the listbox to be inserted into.
+ *          text: Text to insert into listbox.
+ *          pos: 0-based position to insert text
+ */
+void API dw_listbox_insert(HWND handle, char *text, int pos)
+{
+   WinSendMsg(handle,
+            LM_INSERTITEM,
+            MPFROMSHORT(pos),
+            MPFROMP(text));
 }
 
 /*
@@ -5685,12 +6851,12 @@
  */
 void API dw_listbox_list_append(HWND handle, char **text, int count)
 {
-	int i;
-	for(i=0;i<count;i++)
-		WinSendMsg(handle,
-				   LM_INSERTITEM,
-				   MPFROMSHORT(LIT_END),
-				   MPFROMP(text[i]));
+   int i;
+   for(i=0;i<count;i++)
+      WinSendMsg(handle,
+               LM_INSERTITEM,
+               MPFROMSHORT(LIT_END),
+               MPFROMP(text[i]));
 }
 
 /*
@@ -5700,8 +6866,8 @@
  */
 void API dw_listbox_clear(HWND handle)
 {
-	WinSendMsg(handle,
-			   LM_DELETEALL, 0L, 0L);
+   WinSendMsg(handle,
+            LM_DELETEALL, 0L, 0L);
 }
 
 /*
@@ -5711,8 +6877,8 @@
  */
 int API dw_listbox_count(HWND handle)
 {
-	return (int)WinSendMsg(handle,
-						   LM_QUERYITEMCOUNT,0L, 0L);
+   return (int)WinSendMsg(handle,
+                     LM_QUERYITEMCOUNT,0L, 0L);
 }
 
 /*
@@ -5723,10 +6889,10 @@
  */
 void API dw_listbox_set_top(HWND handle, int top)
 {
-	WinSendMsg(handle,
-			   LM_SETTOPINDEX,
-			   MPFROMSHORT(top),
-			   0L);
+   WinSendMsg(handle,
+            LM_SETTOPINDEX,
+            MPFROMSHORT(top),
+            0L);
 }
 
 /*
@@ -5739,7 +6905,7 @@
  */
 void API dw_listbox_get_text(HWND handle, unsigned int index, char *buffer, unsigned int length)
 {
-	WinSendMsg(handle, LM_QUERYITEMTEXT, MPFROM2SHORT(index, length), (MPARAM)buffer);
+   WinSendMsg(handle, LM_QUERYITEMTEXT, MPFROM2SHORT(index, length), (MPARAM)buffer);
 }
 
 /*
@@ -5751,7 +6917,7 @@
  */
 void API dw_listbox_set_text(HWND handle, unsigned int index, char *buffer)
 {
-	WinSendMsg(handle, LM_SETITEMTEXT, MPFROMSHORT(index), (MPARAM)buffer);
+   WinSendMsg(handle, LM_SETITEMTEXT, MPFROMSHORT(index), (MPARAM)buffer);
 }
 
 /*
@@ -5759,12 +6925,12 @@
  * Parameters:
  *          handle: Handle to the listbox to be queried.
  */
-unsigned int API dw_listbox_selected(HWND handle)
-{
-		return (unsigned int)WinSendMsg(handle,
-										LM_QUERYSELECTION,
-										MPFROMSHORT(LIT_CURSOR),
-										0);
+int API dw_listbox_selected(HWND handle)
+{
+      return (unsigned int)WinSendMsg(handle,
+                              LM_QUERYSELECTION,
+                              MPFROMSHORT(LIT_CURSOR),
+                              0);
 }
 
 /*
@@ -5775,17 +6941,17 @@
  */
 int API dw_listbox_selected_multi(HWND handle, int where)
 {
-	int place = where;
-
-	if(where == -1)
-		place = LIT_FIRST;
-
-	place = (int)WinSendMsg(handle,
-							LM_QUERYSELECTION,
-							MPFROMSHORT(place),0L);
-	if(place == LIT_NONE)
-		return -1;
-	return place;
+   int place = where;
+
+   if(where == -1)
+      place = LIT_FIRST;
+
+   place = (int)WinSendMsg(handle,
+                     LM_QUERYSELECTION,
+                     MPFROMSHORT(place),0L);
+   if(place == LIT_NONE)
+      return -1;
+   return place;
 }
 
 /*
@@ -5797,15 +6963,15 @@
  */
 void API dw_listbox_select(HWND handle, int index, int state)
 {
-	char tmpbuf[100];
-
-	WinSendMsg(handle, LM_SELECTITEM, MPFROMSHORT(index), (MPARAM)state);
-
-	WinQueryClassName(handle, 99, tmpbuf);
-
-	/* If we are setting a combobox call the event handler manually */
-	if(strncmp(tmpbuf, "#6", 3)==0)
-		_run_event(handle, WM_CONTROL, MPFROM2SHORT(0, LN_SELECT), (MPARAM)handle);
+   char tmpbuf[100];
+
+   WinSendMsg(handle, LM_SELECTITEM, MPFROMSHORT(index), (MPARAM)state);
+
+   WinQueryClassName(handle, 99, (PCH)tmpbuf);
+
+   /* If we are setting a combobox call the event handler manually */
+   if(strncmp(tmpbuf, "#6", 3)==0)
+      _run_event(handle, WM_CONTROL, MPFROM2SHORT(0, LN_SELECT), (MPARAM)handle);
 }
 
 /*
@@ -5816,7 +6982,7 @@
  */
 void API dw_listbox_delete(HWND handle, int index)
 {
-	WinSendMsg(handle, LM_DELETEITEM, MPFROMSHORT(index), 0);
+   WinSendMsg(handle, LM_DELETEITEM, MPFROMSHORT(index), 0);
 }
 
 /*
@@ -5828,33 +6994,43 @@
  */
 unsigned int API dw_mle_import(HWND handle, char *buffer, int startpoint)
 {
-	unsigned long point = startpoint;
-	PBYTE mlebuf;
-
-	/* Work around 64K limit */
-	if(!DosAllocMem((PPVOID) &mlebuf, 65536, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE))
-	{
-		int amount, len = strlen(buffer), written = 0;
-
-		while(written < len)
-		{
-			if((len - written) > 65535)
-				amount = 65535;
-			else
-				amount = len - written;
-
-			memcpy(mlebuf, &buffer[written], amount);
-			mlebuf[amount] = '\0';
-
-			WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(amount+1));
-			WinSendMsg(handle, MLM_IMPORT, MPFROMP(&point), MPFROMLONG(amount + 1));
-			dw_mle_delete(handle, point, 1);
-
-			written += amount;
-		}
-		DosFreeMem(mlebuf);
-	}
-	return point - 1;
+   long point = startpoint < 0 ? 0 : startpoint;
+   PBYTE mlebuf;
+
+   /* Work around 64K limit */
+   if(!DosAllocMem((PPVOID) &mlebuf, 65536, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE))
+   {
+      int amount, len = strlen(buffer), written = 0;
+
+      while(written < len)
+      {
+         int z, x = 0;
+
+         if((len - written) > 65535)
+            amount = 65535;
+         else
+            amount = len - written;
+
+         /* Remove Carriage Returns \r */
+         for(z=0;z<amount;z++)
+         {
+             if(buffer[z] != '\r')
+             {
+                 mlebuf[x] = buffer[z];
+                 x++;
+             }
+         }
+
+         if(point < 0)
+             point = 0;
+         WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(x));
+         WinSendMsg(handle, MLM_IMPORT, MPFROMP(&point), MPFROMLONG(x));
+
+         written += amount;
+      }
+      DosFreeMem(mlebuf);
+   }
+   return point;
 }
 
 /*
@@ -5867,34 +7043,34 @@
  */
 void API dw_mle_export(HWND handle, char *buffer, int startpoint, int length)
 {
-	PBYTE mlebuf;
-
-	/* Work around 64K limit */
-	if(!DosAllocMem((PPVOID) &mlebuf, 65535, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE))
-	{
-		int amount, copied, written = 0;
-
-		while(written < length)
-		{
-			if((length - written) > 65535)
-				amount = 65535;
-			else
-				amount = length - written;
-
-			WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(amount));
-			copied = (int)WinSendMsg(handle, MLM_EXPORT, MPFROMP(&startpoint), MPFROMLONG(&amount));
-
-			if(copied)
-			{
-				memcpy(&buffer[written], mlebuf, copied);
-
-				written += copied;
-			}
-			else
-				break;
-		}
-		DosFreeMem(mlebuf);
-	}
+   PBYTE mlebuf;
+
+   /* Work around 64K limit */
+   if(!DosAllocMem((PPVOID) &mlebuf, 65535, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE))
+   {
+      int amount, copied, written = 0;
+
+      while(written < length)
+      {
+         if((length - written) > 65535)
+            amount = 65535;
+         else
+            amount = length - written;
+
+         WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(amount));
+         copied = (int)WinSendMsg(handle, MLM_EXPORT, MPFROMP(&startpoint), MPFROMLONG(&amount));
+
+         if(copied)
+         {
+            memcpy(&buffer[written], mlebuf, copied);
+
+            written += copied;
+         }
+         else
+            break;
+      }
+      DosFreeMem(mlebuf);
+   }
 }
 
 /*
@@ -5906,10 +7082,10 @@
  */
 void API dw_mle_get_size(HWND handle, unsigned long *bytes, unsigned long *lines)
 {
-	if(bytes)
-		*bytes = (unsigned long)WinSendMsg(handle, MLM_QUERYTEXTLENGTH, 0, 0);
-	if(lines)
-		*lines = (unsigned long)WinSendMsg(handle, MLM_QUERYLINECOUNT, 0, 0);
+   if(bytes)
+      *bytes = (unsigned long)WinSendMsg(handle, MLM_QUERYTEXTLENGTH, 0, 0);
+   if(lines)
+      *lines = (unsigned long)WinSendMsg(handle, MLM_QUERYLINECOUNT, 0, 0);
 }
 
 /*
@@ -5921,18 +7097,7 @@
  */
 void API dw_mle_delete(HWND handle, int startpoint, int length)
 {
-	char *buf = malloc(length+1);
-	int z, dellen = length;
-
-	dw_mle_export(handle, buf, startpoint, length);
-
-	for(z=0;z<length-1;z++)
-	{
-		if(strncmp(&buf[z], "\r\n", 2) == 0)
-			dellen--;
-	}
-	WinSendMsg(handle, MLM_DELETE, MPFROMLONG(startpoint), MPFROMLONG(dellen));
-	free(buf);
+   WinSendMsg(handle, MLM_DELETE, MPFROMLONG(startpoint), MPFROMLONG(length));
 }
 
 /*
@@ -5942,11 +7107,11 @@
  */
 void API dw_mle_clear(HWND handle)
 {
-	unsigned long bytes;
-
-	dw_mle_get_size(handle, &bytes, NULL);
-
-	WinSendMsg(handle, MLM_DELETE, MPFROMLONG(0), MPFROMLONG(bytes));
+   unsigned long bytes;
+
+   dw_mle_get_size(handle, &bytes, NULL);
+
+   WinSendMsg(handle, MLM_DELETE, MPFROMLONG(0), MPFROMLONG(bytes));
 }
 
 /*
@@ -5957,8 +7122,8 @@
  */
 void API dw_mle_set_visible(HWND handle, int line)
 {
-	int tmppnt = (int)WinSendMsg(handle, MLM_CHARFROMLINE, MPFROMLONG(line), 0);
-	WinSendMsg(handle, MLM_SETSEL, MPFROMLONG(tmppnt), MPFROMLONG(tmppnt));
+   int tmppnt = (int)WinSendMsg(handle, MLM_CHARFROMLINE, MPFROMLONG(line), 0);
+   WinSendMsg(handle, MLM_SETSEL, MPFROMLONG(tmppnt), MPFROMLONG(tmppnt));
 }
 
 /*
@@ -5969,7 +7134,7 @@
  */
 void API dw_mle_set_editable(HWND handle, int state)
 {
-	WinSendMsg(handle, MLM_SETREADONLY, MPFROMLONG(state ? FALSE : TRUE), 0);
+   WinSendMsg(handle, MLM_SETREADONLY, MPFROMLONG(state ? FALSE : TRUE), 0);
 }
 
 /*
@@ -5980,7 +7145,7 @@
  */
 void API dw_mle_set_word_wrap(HWND handle, int state)
 {
-	WinSendMsg(handle, MLM_SETWRAP, MPFROMLONG(state), 0);
+   WinSendMsg(handle, MLM_SETWRAP, MPFROMLONG(state), 0);
 }
 
 /*
@@ -5991,7 +7156,7 @@
  */
 void API dw_mle_set_cursor(HWND handle, int point)
 {
-	WinSendMsg(handle, MLM_SETSEL, MPFROMLONG(point), MPFROMLONG(point));
+   WinSendMsg(handle, MLM_SETSEL, MPFROMLONG(point), MPFROMLONG(point));
 }
 
 /*
@@ -6004,22 +7169,22 @@
  */
 int API dw_mle_search(HWND handle, char *text, int point, unsigned long flags)
 {
-	MLE_SEARCHDATA msd;
-
-	/* This code breaks with structure packing set to 1 (/Sp1 in VAC)
-	 * if this is needed we need to add a pragma here.
-	 */
-	msd.cb = sizeof(msd);
-	msd.pchFind = text;
-	msd.pchReplace = NULL;
-	msd.cchFind = strlen(text);
-	msd.cchReplace = 0;
-	msd.iptStart = point;
-	msd.iptStop = -1;
-
-	if(WinSendMsg(handle, MLM_SEARCH, MPFROMLONG(MLFSEARCH_SELECTMATCH | flags), (MPARAM)&msd))
-		return (int)WinSendMsg(handle, MLM_QUERYSEL,(MPARAM)MLFQS_MAXSEL, 0);
-	return 0;
+   MLE_SEARCHDATA msd;
+
+   /* This code breaks with structure packing set to 1 (/Sp1 in VAC)
+    * if this is needed we need to add a pragma here.
+    */
+   msd.cb = sizeof(msd);
+   msd.pchFind = text;
+   msd.pchReplace = NULL;
+   msd.cchFind = strlen(text);
+   msd.cchReplace = 0;
+   msd.iptStart = point;
+   msd.iptStop = -1;
+
+   if(WinSendMsg(handle, MLM_SEARCH, MPFROMLONG(MLFSEARCH_SELECTMATCH | flags), (MPARAM)&msd))
+      return (int)WinSendMsg(handle, MLM_QUERYSEL,(MPARAM)MLFQS_MAXSEL, 0);
+   return 0;
 }
 
 /*
@@ -6029,7 +7194,7 @@
  */
 void API dw_mle_freeze(HWND handle)
 {
-	WinSendMsg(handle, MLM_DISABLEREFRESH, 0, 0);
+   WinSendMsg(handle, MLM_DISABLEREFRESH, 0, 0);
 }
 
 /*
@@ -6039,7 +7204,51 @@
  */
 void API dw_mle_thaw(HWND handle)
 {
-	WinSendMsg(handle, MLM_ENABLEREFRESH, 0, 0);
+   WinSendMsg(handle, MLM_ENABLEREFRESH, 0, 0);
+}
+
+/* Internal version that can be called from _percentthread */
+void _dw_percent_set_pos(HWND handle, unsigned int position)
+{
+   int range = _dw_percent_get_range(handle);
+
+   if(range)
+   {
+      int mypos = (((float)position)/100)*range;
+
+      if(mypos >= range)
+          mypos = range - 1;
+  
+      _dw_int_set(handle, mypos);
+      WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)mypos);
+   }
+}
+
+/* Move the percentage bar backwards to simulate indeterminate */
+void _percentthread(void *data)
+{
+   HWND percent = (HWND)data;
+
+   if(percent)
+   {
+       HAB thishab = WinInitialize(0);
+       HMQ thishmq = WinCreateMsgQueue(dwhab, 0);
+
+       int pos = 100;
+
+       do
+       {
+           pos--;
+           if(pos < 1)
+               pos = 100;
+           _dw_percent_set_pos(percent, pos);
+           DosSleep(100);
+       }
+       while(dw_window_get_data(percent, "_dw_ind"));
+
+       WinDestroyMsgQueue(thishmq);
+       WinTerminate(thishab);
+   }
 }
 
 /*
@@ -6050,14 +7259,23 @@
  */
 void API dw_percent_set_pos(HWND handle, unsigned int position)
 {
-	int range = _dw_percent_get_range(handle);
-	int mypos = ((float)position/100)*range;
-
-	if(range)
-	{
-		_dw_int_set(handle, mypos);
-		WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)mypos);
-	}
+   /* OS/2 doesn't really support indeterminate... */
+   if(position == DW_PERCENT_INDETERMINATE)
+   {
+       if(!dw_window_get_data(handle, "_dw_ind"))
+       {
+           /* So we fake it with a thread */
+           dw_window_set_data(handle, "_dw_ind", (void *)1);
+           _beginthread(_percentthread, NULL, 100, (void *)handle);
+       }
+   }
+   else
+   {
+       /* Make sure we are no longer indeterminate */
+       dw_window_set_data(handle, "_dw_ind", NULL);
+      /* Otherwise set the position as usual */
+       _dw_percent_set_pos(handle, position);
+   }
 }
 
 /*
@@ -6067,7 +7285,7 @@
  */
 unsigned int API dw_slider_get_pos(HWND handle)
 {
-	return (unsigned int)WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
+   return (unsigned int)WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
 }
 
 /*
@@ -6078,8 +7296,8 @@
  */
 void API dw_slider_set_pos(HWND handle, unsigned int position)
 {
-	dw_window_set_data(handle, "_dw_slider_value", (void *)position);
-	WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)position);
+   dw_window_set_data(handle, "_dw_slider_value", (void *)position);
+   WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)position);
 }
 
 /*
@@ -6089,7 +7307,7 @@
  */
 unsigned int API dw_scrollbar_get_pos(HWND handle)
 {
-	return (unsigned int)WinSendMsg(handle, SBM_QUERYPOS, 0, 0);
+   return (unsigned int)WinSendMsg(handle, SBM_QUERYPOS, 0, 0);
 }
 
 /*
@@ -6100,8 +7318,8 @@
  */
 void API dw_scrollbar_set_pos(HWND handle, unsigned int position)
 {
-	dw_window_set_data(handle, "_dw_scrollbar_value", (void *)position);
-	WinSendMsg(handle, SBM_SETPOS, (MPARAM)position, 0);
+   dw_window_set_data(handle, "_dw_scrollbar_value", (void *)position);
+   WinSendMsg(handle, SBM_SETPOS, (MPARAM)position, 0);
 }
 
 /*
@@ -6113,10 +7331,10 @@
  */
 void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible)
 {
-	unsigned int pos = (unsigned int)dw_window_get_data(handle, "_dw_scrollbar_value");
-	WinSendMsg(handle, SBM_SETSCROLLBAR, (MPARAM)pos, MPFROM2SHORT(0, (unsigned short)range - visible));
-	WinSendMsg(handle, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)visible, range), 0);
-	dw_window_set_data(handle, "_dw_scrollbar_visible", (void *)visible);
+   unsigned int pos = (unsigned int)dw_window_get_data(handle, "_dw_scrollbar_value");
+   WinSendMsg(handle, SBM_SETSCROLLBAR, (MPARAM)pos, MPFROM2SHORT(0, (unsigned short)range - visible));
+   WinSendMsg(handle, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)visible, range), 0);
+   dw_window_set_data(handle, "_dw_scrollbar_visible", (void *)visible);
 }
 
 /*
@@ -6127,7 +7345,7 @@
  */
 void API dw_spinbutton_set_pos(HWND handle, long position)
 {
-	WinSendMsg(handle, SPBM_SETCURRENTVALUE, MPFROMLONG((long)position), 0L);
+   WinSendMsg(handle, SPBM_SETCURRENTVALUE, MPFROMLONG((long)position), 0L);
 }
 
 /*
@@ -6139,7 +7357,7 @@
  */
 void API dw_spinbutton_set_limits(HWND handle, long upper, long lower)
 {
-	WinSendMsg(handle, SPBM_SETLIMITS, MPFROMLONG(upper), MPFROMLONG(lower));
+   WinSendMsg(handle, SPBM_SETLIMITS, MPFROMLONG(upper), MPFROMLONG(lower));
 }
 
 /*
@@ -6150,7 +7368,7 @@
  */
 void API dw_entryfield_set_limit(HWND handle, ULONG limit)
 {
-	WinSendMsg(handle, EM_SETTEXTLIMIT, (MPARAM)limit, (MPARAM)0);
+   WinSendMsg(handle, EM_SETTEXTLIMIT, (MPARAM)limit, (MPARAM)0);
 }
 
 
@@ -6161,10 +7379,10 @@
  */
 long API dw_spinbutton_get_pos(HWND handle)
 {
-	long tmpval = 0L;
-
-	WinSendMsg(handle, SPBM_QUERYVALUE, (MPARAM)&tmpval,0L);
-    return tmpval;
+   long tmpval = 0L;
+
+   WinSendMsg(handle, SPBM_QUERYVALUE, (MPARAM)&tmpval,0L);
+   return tmpval;
 }
 
 /*
@@ -6174,7 +7392,7 @@
  */
 int API dw_checkbox_get(HWND handle)
 {
-	return (int)WinSendMsg(handle,BM_QUERYCHECK,0,0);
+   return (int)WinSendMsg(handle,BM_QUERYCHECK,0,0);
 }
 
 /*
@@ -6185,7 +7403,7 @@
  */
 void API dw_checkbox_set(HWND handle, int value)
 {
-	WinSendMsg(handle,BM_SETCHECK,MPFROMSHORT(value),0);
+   WinSendMsg(handle,BM_SETCHECK,MPFROMSHORT(value),0);
 }
 
 /*
@@ -6198,53 +7416,53 @@
  *          parent: Parent handle or 0 if root.
  *          itemdata: Item specific data.
  */
-HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, unsigned long icon, HTREEITEM parent, void *itemdata)
-{
-	ULONG        cbExtra;
-	PCNRITEM     pci;
-	RECORDINSERT ri;
-
-	if(!item)
-		item = (HTREEITEM)CMA_FIRST;
-
-	/* Calculate extra bytes needed for each record besides that needed for the
-	 * MINIRECORDCORE structure
-	 */
-
-	cbExtra = sizeof(CNRITEM) - sizeof(MINIRECORDCORE);
-
-	/* Allocate memory for the parent record */
-
-	if((pci = (PCNRITEM)_dw_send_msg(handle, CM_ALLOCRECORD, MPFROMLONG(cbExtra), MPFROMSHORT(1), 0)) == 0)
-		return 0;
-
-	/* Fill in the parent record data */
-
-	pci->rc.cb          = sizeof(MINIRECORDCORE);
-	pci->rc.pszIcon     = strdup(title);
-	pci->rc.hptrIcon    = icon;
-
-	pci->hptrIcon       = icon;
-	pci->user           = itemdata;
-	pci->parent         = parent;
-
-	memset(&ri, 0, sizeof(RECORDINSERT));
-
-	ri.cb                 = sizeof(RECORDINSERT);
-	ri.pRecordOrder       = (PRECORDCORE)item;
-	ri.zOrder             = (USHORT)CMA_TOP;
-	ri.cRecordsInsert     = 1;
-	ri.fInvalidateRecord  = TRUE;
-
-	/* We are about to insert the child records. Set the parent record to be
-	 * the one we just inserted.
-	 */
-	ri.pRecordParent = (PRECORDCORE)parent;
-
-	/* Insert the record */
-	WinSendMsg(handle, CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri));
-
-	return (HTREEITEM)pci;
+HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, HICN icon, HTREEITEM parent, void *itemdata)
+{
+   ULONG        cbExtra;
+   PCNRITEM     pci;
+   RECORDINSERT ri;
+
+   if(!item)
+      item = (HTREEITEM)CMA_FIRST;
+
+   /* Calculate extra bytes needed for each record besides that needed for the
+    * MINIRECORDCORE structure
+    */
+
+   cbExtra = sizeof(CNRITEM) - sizeof(MINIRECORDCORE);
+
+   /* Allocate memory for the parent record */
+
+   if((pci = (PCNRITEM)_dw_send_msg(handle, CM_ALLOCRECORD, MPFROMLONG(cbExtra), MPFROMSHORT(1), 0)) == 0)
+      return 0;
+
+   /* Fill in the parent record data */
+
+   pci->rc.cb          = sizeof(MINIRECORDCORE);
+   pci->rc.pszIcon     = (PSZ)strdup(title);
+   pci->rc.hptrIcon    = icon;
+
+   pci->hptrIcon       = icon;
+   pci->user           = itemdata;
+   pci->parent         = parent;
+
+   memset(&ri, 0, sizeof(RECORDINSERT));
+
+   ri.cb                 = sizeof(RECORDINSERT);
+   ri.pRecordOrder       = (PRECORDCORE)item;
+   ri.zOrder             = (USHORT)CMA_TOP;
+   ri.cRecordsInsert     = 1;
+   ri.fInvalidateRecord  = TRUE;
+
+   /* We are about to insert the child records. Set the parent record to be
+    * the one we just inserted.
+    */
+   ri.pRecordParent = (PRECORDCORE)parent;
+
+   /* Insert the record */
+   WinSendMsg(handle, CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri));
+
+   return (HTREEITEM)pci;
 }
 
 /*
@@ -6256,9 +7474,9 @@
  *          parent: Parent handle or 0 if root.
  *          itemdata: Item specific data.
  */
-HTREEITEM API dw_tree_insert(HWND handle, char *title, unsigned long icon, HTREEITEM parent, void *itemdata)
-{
-	return dw_tree_insert_after(handle, (HTREEITEM)CMA_END, title, icon, parent, itemdata);
+HTREEITEM API dw_tree_insert(HWND handle, char *title, HICN icon, HTREEITEM parent, void *itemdata)
+{
+   return dw_tree_insert_after(handle, (HTREEITEM)CMA_END, title, icon, parent, itemdata);
 }
 
 /*
@@ -6269,22 +7487,22 @@
  *          title: The text title of the entry.
  *          icon: Handle to coresponding icon.
  */
-void API dw_tree_item_change(HWND handle, HTREEITEM item, char *title, unsigned long icon)
-{
-	PCNRITEM pci = (PCNRITEM)item;
-
-	if(!pci)
-		return;
-
-	if(pci->rc.pszIcon)
-		free(pci->rc.pszIcon);
-
-	pci->rc.pszIcon     = strdup(title);
-	pci->rc.hptrIcon    = icon;
-
-	pci->hptrIcon       = icon;
-
-	WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_TEXTCHANGED));
+void API dw_tree_item_change(HWND handle, HTREEITEM item, char *title, HICN icon)
+{
+   PCNRITEM pci = (PCNRITEM)item;
+
+   if(!pci)
+      return;
+
+   if(pci->rc.pszIcon)
+      free(pci->rc.pszIcon);
+
+   pci->rc.pszIcon     = (PSZ)strdup(title);
+   pci->rc.hptrIcon    = icon;
+
+   pci->hptrIcon       = icon;
+
+   WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_TEXTCHANGED));
 }
 
 /*
@@ -6295,12 +7513,12 @@
  */
 char * API dw_tree_get_title(HWND handle, HTREEITEM item)
 {
-	PCNRITEM pci = (PCNRITEM)item;
-
-	handle = handle; /* keep compiler happy */
-	if(pci)
-		return pci->rc.pszIcon;
-	return NULL;
+   PCNRITEM pci = (PCNRITEM)item;
+
+   handle = handle; /* keep compiler happy */
+   if(pci)
+      return (char *)pci->rc.pszIcon;
+   return NULL;
 }
 
 /*
@@ -6311,12 +7529,12 @@
  */
 HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item)
 {
-	PCNRITEM pci = (PCNRITEM)item;
-
-	handle = handle; /* keep compiler happy */
-	if(pci)
-		return pci->parent;
-	return (HTREEITEM)0;
+   PCNRITEM pci = (PCNRITEM)item;
+
+   handle = handle; /* keep compiler happy */
+   if(pci)
+      return pci->parent;
+   return (HTREEITEM)0;
 }
 
 /*
@@ -6328,13 +7546,13 @@
  */
 void API dw_tree_item_set_data(HWND handle, HTREEITEM item, void *itemdata)
 {
-	PCNRITEM pci = (PCNRITEM)item;
-
-	handle = handle; /* keep compiler happy */
-	if(!pci)
-		return;
-
-	pci->user = itemdata;
+   PCNRITEM pci = (PCNRITEM)item;
+
+   handle = handle; /* keep compiler happy */
+   if(!pci)
+      return;
+
+   pci->user = itemdata;
 }
 
 /*
@@ -6345,12 +7563,12 @@
  */
 void * API dw_tree_item_get_data(HWND handle, HTREEITEM item)
 {
-	PCNRITEM pci = (PCNRITEM)item;
-
-	handle = handle; /* keep compiler happy */
-	if(!pci)
-		return NULL;
-	return pci->user;
+   PCNRITEM pci = (PCNRITEM)item;
+
+   handle = handle; /* keep compiler happy */
+   if(!pci)
+      return NULL;
+   return pci->user;
 }
 
 /*
@@ -6361,17 +7579,17 @@
  */
 void API dw_tree_item_select(HWND handle, HTREEITEM item)
 {
-	PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-
-	while(pCore)
-	{
-		if(pCore->flRecordAttr & CRA_SELECTED)
-			WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(FALSE, CRA_SELECTED | CRA_CURSORED));
-		pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-	}
-	WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)item, MPFROM2SHORT(TRUE, CRA_SELECTED | CRA_CURSORED));
-	lastitem = 0;
-	lasthcnr = 0;
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+
+   while(pCore)
+   {
+      if(pCore->flRecordAttr & CRA_SELECTED)
+         WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(FALSE, CRA_SELECTED | CRA_CURSORED));
+      pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+   }
+   WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)item, MPFROM2SHORT(TRUE, CRA_SELECTED | CRA_CURSORED));
+   lastitem = 0;
+   lasthcnr = 0;
 }
 
 /*
@@ -6381,7 +7599,7 @@
  */
 void API dw_tree_clear(HWND handle)
 {
-	dw_container_clear(handle, TRUE);
+   dw_container_clear(handle, TRUE);
 }
 
 /*
@@ -6392,7 +7610,7 @@
  */
 void API dw_tree_item_expand(HWND handle, HTREEITEM item)
 {
-	WinSendMsg(handle, CM_EXPANDTREE, MPFROMP(item), 0);
+   WinSendMsg(handle, CM_EXPANDTREE, MPFROMP(item), 0);
 }
 
 /*
@@ -6403,7 +7621,7 @@
  */
 void API dw_tree_item_collapse(HWND handle, HTREEITEM item)
 {
-	WinSendMsg(handle, CM_COLLAPSETREE, MPFROMP(item), 0);
+   WinSendMsg(handle, CM_COLLAPSETREE, MPFROMP(item), 0);
 }
 
 /*
@@ -6414,25 +7632,25 @@
  */
 void API dw_tree_item_delete(HWND handle, HTREEITEM item)
 {
-	PCNRITEM     pci = (PCNRITEM)item;
-
-	if(!item)
-		return;
-
-	if(pci->rc.pszIcon)
-	{
-		free(pci->rc.pszIcon);
-		pci->rc.pszIcon = 0;
-	}
-
-	WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_INVALIDATE | CMA_FREE));
+   PCNRITEM     pci = (PCNRITEM)item;
+
+   if(!item)
+      return;
+
+   if(pci->rc.pszIcon)
+   {
+      free(pci->rc.pszIcon);
+      pci->rc.pszIcon = 0;
+   }
+
+   WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_INVALIDATE | CMA_FREE));
 }
 
 /* Some OS/2 specific container structs */
 typedef struct _containerinfo {
-	int count;
-	void *data;
-	HWND handle;
+   int count;
+   void *data;
+   HWND handle;
 } ContainerInfo;
 
 /*
@@ -6447,93 +7665,93 @@
  */
 int API dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator)
 {
-	PFIELDINFO details, first, left = NULL;
-	FIELDINFOINSERT detin;
-	CNRINFO cnri;
-	int z;
-	ULONG size = sizeof(RECORDCORE);
-	ULONG *offStruct = malloc(count * sizeof(ULONG));
-	ULONG *tempflags = malloc((count+1) * sizeof(ULONG));
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
-	ULONG *oldflags = blah ? blah->data : 0;
-
-	if(!offStruct || !tempflags)
-		return FALSE;
-
-	memcpy(tempflags, flags, count * sizeof(ULONG));
-	tempflags[count] = 0;
-
-	blah->data = tempflags;
-	blah->flags = separator;
-
-	if(oldflags)
-		free(oldflags);
-
-	while((first = (PFIELDINFO)WinSendMsg(handle, CM_QUERYDETAILFIELDINFO,  0, MPFROMSHORT(CMA_FIRST))) != NULL)
-	{
-		WinSendMsg(handle, CM_REMOVEDETAILFIELDINFO, (MPARAM)&first, MPFROM2SHORT(1, CMA_FREE));
-	}
-
-	/* Figure out the offsets to the items in the struct */
-	for(z=0;z<count;z++)
-	{
-		offStruct[z] = size;
-		if(flags[z] & DW_CFA_BITMAPORICON)
-			size += sizeof(HPOINTER);
-		else if(flags[z] & DW_CFA_STRING)
-			size += sizeof(char *);
-		else if(flags[z] & DW_CFA_ULONG)
-			size += sizeof(ULONG);
-		else if(flags[z] & DW_CFA_DATE)
-			size += sizeof(CDATE);
-		else if(flags[z] & DW_CFA_TIME)
-			size += sizeof(CTIME);
-	}
-
-	first = details = (PFIELDINFO)WinSendMsg(handle, CM_ALLOCDETAILFIELDINFO, MPFROMLONG(count), 0L);
-
-	if(!first)
-	{
-		free(offStruct);
-		return FALSE;
-	}
-
-	for(z=0;z<count;z++)
-	{
-		if(z==separator-1)
-			left=details;
-		details->cb = sizeof(FIELDINFO);
-		details->flData = flags[z];
-		details->flTitle = CFA_FITITLEREADONLY;
-		details->pTitleData = titles[z];
-		details->offStruct = offStruct[z];
-		details = details->pNextFieldInfo;
-	}
-
-	detin.cb = sizeof(FIELDINFOINSERT);
-	detin.fInvalidateFieldInfo = FALSE;
-	detin.pFieldInfoOrder = (PFIELDINFO) CMA_FIRST;
-	detin.cFieldInfoInsert = (ULONG)count;
-
-	WinSendMsg(handle, CM_INSERTDETAILFIELDINFO, MPFROMP(first), MPFROMP(&detin));
-
-	if(count > separator && separator > 0)
-	{
-		cnri.cb = sizeof(CNRINFO);
-		cnri.pFieldInfoLast = left;
-		cnri.xVertSplitbar  = 150;
-
-		WinSendMsg(handle, CM_SETCNRINFO, MPFROMP(&cnri),  MPFROMLONG(CMA_PFIELDINFOLAST | CMA_XVERTSPLITBAR));
-	}
-
-	cnri.flWindowAttr = CV_DETAIL | CV_MINI | CA_DETAILSVIEWTITLES;
-	cnri.slBitmapOrIcon.cx = 16;
-	cnri.slBitmapOrIcon.cy = 16;
-
-	WinSendMsg(handle, CM_SETCNRINFO, &cnri, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON));
-
-	free(offStruct);
-	return TRUE;
+   PFIELDINFO details, first, left = NULL;
+   FIELDINFOINSERT detin;
+   CNRINFO cnri;
+   int z;
+   ULONG size = sizeof(RECORDCORE);
+   ULONG *offStruct = malloc(count * sizeof(ULONG));
+   ULONG *tempflags = malloc((count+1) * sizeof(ULONG));
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
+   ULONG *oldflags = blah ? blah->data : 0;
+
+   if(!offStruct || !tempflags)
+      return FALSE;
+
+   memcpy(tempflags, flags, count * sizeof(ULONG));
+   tempflags[count] = 0;
+
+   blah->data = tempflags;
+   blah->flags = separator;
+
+   if(oldflags)
+      free(oldflags);
+
+   while((first = (PFIELDINFO)WinSendMsg(handle, CM_QUERYDETAILFIELDINFO,  0, MPFROMSHORT(CMA_FIRST))) != NULL)
+   {
+      WinSendMsg(handle, CM_REMOVEDETAILFIELDINFO, (MPARAM)&first, MPFROM2SHORT(1, CMA_FREE));
+   }
+
+   /* Figure out the offsets to the items in the struct */
+   for(z=0;z<count;z++)
+   {
+      offStruct[z] = size;
+      if(flags[z] & DW_CFA_BITMAPORICON)
+         size += sizeof(HPOINTER);
+      else if(flags[z] & DW_CFA_STRING)
+         size += sizeof(char *);
+      else if(flags[z] & DW_CFA_ULONG)
+         size += sizeof(ULONG);
+      else if(flags[z] & DW_CFA_DATE)
+         size += sizeof(CDATE);
+      else if(flags[z] & DW_CFA_TIME)
+         size += sizeof(CTIME);
+   }
+
+   first = details = (PFIELDINFO)WinSendMsg(handle, CM_ALLOCDETAILFIELDINFO, MPFROMLONG(count), 0L);
+
+   if(!first)
+   {
+      free(offStruct);
+      return FALSE;
+   }
+
+   for(z=0;z<count;z++)
+   {
+      if(z==separator-1)
+         left=details;
+      details->cb = sizeof(FIELDINFO);
+      details->flData = flags[z];
+      details->flTitle = CFA_FITITLEREADONLY;
+      details->pTitleData = titles[z];
+      details->offStruct = offStruct[z];
+      details = details->pNextFieldInfo;
+   }
+
+   detin.cb = sizeof(FIELDINFOINSERT);
+   detin.fInvalidateFieldInfo = FALSE;
+   detin.pFieldInfoOrder = (PFIELDINFO) CMA_FIRST;
+   detin.cFieldInfoInsert = (ULONG)count;
+
+   WinSendMsg(handle, CM_INSERTDETAILFIELDINFO, MPFROMP(first), MPFROMP(&detin));
+
+   if(count > separator && separator > 0)
+   {
+      cnri.cb = sizeof(CNRINFO);
+      cnri.pFieldInfoLast = left;
+      cnri.xVertSplitbar  = 150;
+
+      WinSendMsg(handle, CM_SETCNRINFO, MPFROMP(&cnri),  MPFROMLONG(CMA_PFIELDINFOLAST | CMA_XVERTSPLITBAR));
+   }
+
+   cnri.flWindowAttr = CV_DETAIL | CV_MINI | CA_DETAILSVIEWTITLES;
+   cnri.slBitmapOrIcon.cx = 16;
+   cnri.slBitmapOrIcon.cy = 16;
+
+   WinSendMsg(handle, CM_SETCNRINFO, &cnri, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON));
+
+   free(offStruct);
+   return DW_ERROR_NONE;
 }
 
 /*
@@ -6546,23 +7764,23 @@
  */
 int API dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count)
 {
-	char **newtitles = malloc(sizeof(char *) * (count + 2));
-	unsigned long *newflags = malloc(sizeof(unsigned long) * (count + 2));
-
-	newtitles[0] = "Icon";
-	newtitles[1] = "Filename";
-
-	newflags[0] = DW_CFA_BITMAPORICON | DW_CFA_CENTER | DW_CFA_HORZSEPARATOR | DW_CFA_SEPARATOR;
-	newflags[1] = DW_CFA_STRING | DW_CFA_LEFT | DW_CFA_HORZSEPARATOR;
-
-	memcpy(&newtitles[2], titles, sizeof(char *) * count);
-	memcpy(&newflags[2], flags, sizeof(unsigned long) * count);
-
-	dw_container_setup(handle, newflags, newtitles, count + 2, count ? 2 : 0);
-
-	free(newtitles);
-	free(newflags);
-	return TRUE;
+   char **newtitles = malloc(sizeof(char *) * (count + 2));
+   unsigned long *newflags = malloc(sizeof(unsigned long) * (count + 2));
+
+   newtitles[0] = "Icon";
+   newtitles[1] = "Filename";
+
+   newflags[0] = DW_CFA_BITMAPORICON | DW_CFA_CENTER | DW_CFA_HORZSEPARATOR | DW_CFA_SEPARATOR;
+   newflags[1] = DW_CFA_STRING | DW_CFA_LEFT | DW_CFA_HORZSEPARATOR;
+
+   memcpy(&newtitles[2], titles, sizeof(char *) * count);
+   memcpy(&newflags[2], flags, sizeof(unsigned long) * count);
+
+   dw_container_setup(handle, newflags, newtitles, count + 2, count ? 2 : 0);
+
+   free(newtitles);
+   free(newflags);
+   return DW_ERROR_NONE;
 }
 
 /*
@@ -6573,9 +7791,9 @@
  *              Windows, on GTK this is converted to a pointer
  *              to an embedded XPM.
  */
-unsigned long API dw_icon_load(unsigned long module, unsigned long id)
-{
-	return WinLoadPointer(HWND_DESKTOP,module,id);
+HICN API dw_icon_load(unsigned long module, unsigned long id)
+{
+   return WinLoadPointer(HWND_DESKTOP,module,id);
 }
 
 /*
@@ -6585,24 +7803,59 @@
  *                 DW pick the appropriate file extension.
  *                 (ICO on OS/2 or Windows, XPM on Unix)
  */
-unsigned long API dw_icon_load_from_file(char *filename)
-{
-	char *file = alloca(strlen(filename) + 5);
-
-	if(!file)
-		return 0;
-
-	strcpy(file, filename);
-
-	/* check if we can read from this file (it exists and read permission) */
-	if(access(file, 04) != 0)
-	{
-		/* Try with .bmp extention */
-		strcat(file, ".ico");
-		if(access(file, 04) != 0)
-			return 0;
-	}
-	return WinLoadFileIcon(file, FALSE);
+HICN API dw_icon_load_from_file(char *filename)
+{
+   char *file = alloca(strlen(filename) + 5);
+
+   if(!file)
+      return 0;
+
+   strcpy(file, filename);
+
+   /* check if we can read from this file (it exists and read permission) */
+   if(access(file, 04) != 0)
+   {
+      /* Try with .bmp extention */
+      strcat(file, ".ico");
+      if(access(file, 04) != 0)
+         return 0;
+   }
+   return WinLoadFileIcon((PSZ)file, FALSE);
+}
+
+/*
+ * Obtains an icon from data
+ * Parameters:
+ *       filename: Name of the file, omit extention to have
+ *                 DW pick the appropriate file extension.
+ *                 (ICO on OS/2 or Windows, XPM on Unix)
+ */
+HICN API dw_icon_load_from_data(char *data, int len)
+{
+   HICN icon=0;
+   char *file;
+   FILE *fp;
+
+   if ( !data )
+      return 0;
+   file = tmpnam( NULL );
+   if ( file != NULL )
+   {
+      fp = fopen( file, "wb" );
+      if ( fp != NULL )
+      {
+         fwrite( data, 1, len, fp );
+         fclose( fp );
+         icon = WinLoadFileIcon( (PSZ)file, FALSE );
+      }
+      else
+      {
+         unlink( file );
+         return 0;
+      }
+      unlink( file );
+   }
+   return icon;
 }
 
 /*
@@ -6610,9 +7863,9 @@
  * Parameters:
  *          handle: Handle to icon returned by dw_icon_load().
  */
-void API dw_icon_free(unsigned long handle)
-{
-	WinDestroyPointer(handle);
+void API dw_icon_free(HICN handle)
+{
+   WinDestroyPointer(handle);
 }
 
 /*
@@ -6623,159 +7876,159 @@
  */
 void * API dw_container_alloc(HWND handle, int rowcount)
 {
-	WindowData *wd = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
-	ULONG *flags = wd ? wd->data : 0;
-	int z, size = 0, totalsize, count = 0;
-	PRECORDCORE temp;
-	ContainerInfo *ci;
-	void *blah = NULL;
-
-	if(!flags || rowcount < 1)
-		return NULL;
-
-	while(flags[count])
-		count++;
-
-	/* Figure out the offsets to the items in the struct */
-	for(z=0;z<count;z++)
-	{
-		if(flags[z] & DW_CFA_BITMAPORICON)
-			size += sizeof(HPOINTER);
-		else if(flags[z] & DW_CFA_STRING)
-			size += sizeof(char *);
-		else if(flags[z] & DW_CFA_ULONG)
-			size += sizeof(ULONG);
-		else if(flags[z] & DW_CFA_DATE)
-			size += sizeof(CDATE);
-		else if(flags[z] & DW_CFA_TIME)
-			size += sizeof(CTIME);
-	}
-
-	totalsize = size + sizeof(RECORDCORE);
-
-	z = 0;
-
-	if(!(blah = (void *)_dw_send_msg(handle, CM_ALLOCRECORD, MPFROMLONG(size), MPFROMLONG(rowcount), 0)))
-		return NULL;
-
-	temp = (PRECORDCORE)blah;
-
-	for(z=0;z<rowcount;z++)
-	{
-		temp->cb = totalsize;
-		temp = temp->preccNextRecord;
-	}
-
-	ci = malloc(sizeof(struct _containerinfo));
-
-	ci->count = rowcount;
-	ci->data = blah;
-	ci->handle = handle;
-
-	return (void *)ci;
+   WindowData *wd = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
+   ULONG *flags = wd ? wd->data : 0;
+   int z, size = 0, totalsize, count = 0;
+   PRECORDCORE temp;
+   ContainerInfo *ci;
+   void *blah = NULL;
+
+   if(!flags || rowcount < 1)
+      return NULL;
+
+   while(flags[count])
+      count++;
+
+   /* Figure out the offsets to the items in the struct */
+   for(z=0;z<count;z++)
+   {
+      if(flags[z] & DW_CFA_BITMAPORICON)
+         size += sizeof(HPOINTER);
+      else if(flags[z] & DW_CFA_STRING)
+         size += sizeof(char *);
+      else if(flags[z] & DW_CFA_ULONG)
+         size += sizeof(ULONG);
+      else if(flags[z] & DW_CFA_DATE)
+         size += sizeof(CDATE);
+      else if(flags[z] & DW_CFA_TIME)
+         size += sizeof(CTIME);
+   }
+
+   totalsize = size + sizeof(RECORDCORE);
+
+   z = 0;
+
+   if(!(blah = (void *)_dw_send_msg(handle, CM_ALLOCRECORD, MPFROMLONG(size), MPFROMLONG(rowcount), 0)))
+      return NULL;
+
+   temp = (PRECORDCORE)blah;
+
+   for(z=0;z<rowcount;z++)
+   {
+      temp->cb = totalsize;
+      temp = temp->preccNextRecord;
+   }
+
+   ci = malloc(sizeof(struct _containerinfo));
+
+   ci->count = rowcount;
+   ci->data = blah;
+   ci->handle = handle;
+
+   return (void *)ci;
 }
 
 /* Internal function that does the work for set_item and change_item */
 void _dw_container_set_item(HWND handle, PRECORDCORE temp, int column, int row, void *data)
 {
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
-	ULONG totalsize, size = 0, *flags = blah ? blah->data : 0;
-	int z, currentcount;
-	CNRINFO cnr;
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
+   ULONG totalsize, size = 0, *flags = blah ? blah->data : 0;
+   int z, currentcount;
+   CNRINFO cnr;
     void *dest;
 
-	if(!flags)
-		return;
-
-	if(!_dw_send_msg(handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO)), 0))
-		return;
-
-	currentcount = cnr.cRecords;
-
-	/* Figure out the offsets to the items in the struct */
-	for(z=0;z<column;z++)
-	{
-		if(flags[z] & DW_CFA_BITMAPORICON)
-			size += sizeof(HPOINTER);
-		else if(flags[z] & DW_CFA_STRING)
-			size += sizeof(char *);
-		else if(flags[z] & DW_CFA_ULONG)
-			size += sizeof(ULONG);
-		else if(flags[z] & DW_CFA_DATE)
-			size += sizeof(CDATE);
-		else if(flags[z] & DW_CFA_TIME)
-			size += sizeof(CTIME);
-	}
-
-	totalsize = size + sizeof(RECORDCORE);
-
-	for(z=0;z<(row-currentcount);z++)
-		temp = temp->preccNextRecord;
-
-	dest = (void *)(((ULONG)temp)+((ULONG)totalsize));
-
-	if(flags[column] & DW_CFA_BITMAPORICON)
-		memcpy(dest, data, sizeof(HPOINTER));
-	else if(flags[column] & DW_CFA_STRING)
-	{
-		char **newstr = (char **)data, **str = dest;
-
-		if(*str)
-			free(*str);
-
-		if(newstr && *newstr)
-			*str = strdup(*newstr);
-		else
-			*str = NULL;
-	}
-	else if(flags[column] & DW_CFA_ULONG)
-		memcpy(dest, data, sizeof(ULONG));
-	else if(flags[column] & DW_CFA_DATE)
-		memcpy(dest, data, sizeof(CDATE));
-	else if(flags[column] & DW_CFA_TIME)
-		memcpy(dest, data, sizeof(CTIME));
+   if(!flags)
+      return;
+
+   if(!_dw_send_msg(handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO)), 0))
+      return;
+
+   currentcount = cnr.cRecords;
+
+   /* Figure out the offsets to the items in the struct */
+   for(z=0;z<column;z++)
+   {
+      if(flags[z] & DW_CFA_BITMAPORICON)
+         size += sizeof(HPOINTER);
+      else if(flags[z] & DW_CFA_STRING)
+         size += sizeof(char *);
+      else if(flags[z] & DW_CFA_ULONG)
+         size += sizeof(ULONG);
+      else if(flags[z] & DW_CFA_DATE)
+         size += sizeof(CDATE);
+      else if(flags[z] & DW_CFA_TIME)
+         size += sizeof(CTIME);
+   }
+
+   totalsize = size + sizeof(RECORDCORE);
+
+   for(z=0;z<(row-currentcount);z++)
+      temp = temp->preccNextRecord;
+
+   dest = (void *)(((ULONG)temp)+((ULONG)totalsize));
+
+   if(flags[column] & DW_CFA_BITMAPORICON)
+      memcpy(dest, data, sizeof(HPOINTER));
+   else if(flags[column] & DW_CFA_STRING)
+   {
+      char **newstr = (char **)data, **str = dest;
+
+      if(*str)
+         free(*str);
+
+      if(newstr && *newstr)
+         *str = strdup(*newstr);
+      else
+         *str = NULL;
+   }
+   else if(flags[column] & DW_CFA_ULONG)
+      memcpy(dest, data, sizeof(ULONG));
+   else if(flags[column] & DW_CFA_DATE)
+      memcpy(dest, data, sizeof(CDATE));
+   else if(flags[column] & DW_CFA_TIME)
+      memcpy(dest, data, sizeof(CTIME));
 }
 
 /* Internal function that free()s any strings allocated for a container item */
 void _dw_container_free_strings(HWND handle, PRECORDCORE temp)
 {
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
-	ULONG totalsize, size = 0, *flags = blah ? blah->data : 0;
-	int z, count = 0;
-
-	if(!flags)
-		return;
-
-	while(flags[count])
-		count++;
-
-	/* Figure out the offsets to the items in the struct */
-	for(z=0;z<count;z++)
-	{
-		if(flags[z] & DW_CFA_BITMAPORICON)
-			size += sizeof(HPOINTER);
-		else if(flags[z] & DW_CFA_STRING)
-		{
-			char **str;
-
-			totalsize = size + sizeof(RECORDCORE);
-
-			str = (char **)(((ULONG)temp)+((ULONG)totalsize));
-
-			if(*str)
-			{
-				free(*str);
-				*str = NULL;
-			}
-			size += sizeof(char *);
-		}
-		else if(flags[z] & DW_CFA_ULONG)
-			size += sizeof(ULONG);
-		else if(flags[z] & DW_CFA_DATE)
-			size += sizeof(CDATE);
-		else if(flags[z] & DW_CFA_TIME)
-			size += sizeof(CTIME);
-	}
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
+   ULONG totalsize, size = 0, *flags = blah ? blah->data : 0;
+   int z, count = 0;
+
+   if(!flags)
+      return;
+
+   while(flags[count])
+      count++;
+
+   /* Figure out the offsets to the items in the struct */
+   for(z=0;z<count;z++)
+   {
+      if(flags[z] & DW_CFA_BITMAPORICON)
+         size += sizeof(HPOINTER);
+      else if(flags[z] & DW_CFA_STRING)
+      {
+         char **str;
+
+         totalsize = size + sizeof(RECORDCORE);
+
+         str = (char **)(((ULONG)temp)+((ULONG)totalsize));
+
+         if(*str)
+         {
+            free(*str);
+            *str = NULL;
+         }
+         size += sizeof(char *);
+      }
+      else if(flags[z] & DW_CFA_ULONG)
+         size += sizeof(ULONG);
+      else if(flags[z] & DW_CFA_DATE)
+         size += sizeof(CDATE);
+      else if(flags[z] & DW_CFA_TIME)
+         size += sizeof(CTIME);
+   }
 }
 
 /*
@@ -6789,12 +8042,12 @@
  */
 void API dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data)
 {
-	ContainerInfo *ci = (ContainerInfo *)pointer;
-
-	if(!ci)
-		return;
-
-	_dw_container_set_item(handle, (PRECORDCORE)ci->data, column, row, data);
+   ContainerInfo *ci = (ContainerInfo *)pointer;
+
+   if(!ci)
+      return;
+
+   _dw_container_set_item(handle, (PRECORDCORE)ci->data, column, row, data);
 }
 
 /*
@@ -6807,20 +8060,20 @@
  */
 void API dw_container_change_item(HWND handle, int column, int row, void *data)
 {
-	PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-	int count = 0;
-
-	while(pCore)
-	{
-		if(count == row)
-		{
-			_dw_container_set_item(handle, pCore, column, 0, data);
-			WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_NOREPOSITION | CMA_TEXTCHANGED));
-			return;
-		}
-		pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-		count++;
-	}
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+   int count = 0;
+
+   while(pCore)
+   {
+      if(count == row)
+      {
+         _dw_container_set_item(handle, pCore, column, 0, data);
+         WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_NOREPOSITION | CMA_TEXTCHANGED));
+         return;
+      }
+      pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+      count++;
+   }
 }
 
 /*
@@ -6833,7 +8086,7 @@
  */
 void API dw_filesystem_change_item(HWND handle, int column, int row, void *data)
 {
-	dw_container_change_item(handle, column + 2, row, data);
+   dw_container_change_item(handle, column + 2, row, data);
 }
 
 /*
@@ -6845,10 +8098,10 @@
  *          row: Zero based row of data being set.
  *          data: Pointer to the data to be added.
  */
-void API dw_filesystem_change_file(HWND handle, int row, char *filename, unsigned long icon)
-{
-	dw_container_change_item(handle, 0, row, (void *)&icon);
-	dw_container_change_item(handle, 1, row, (void *)&filename);
+void API dw_filesystem_change_file(HWND handle, int row, char *filename, HICN icon)
+{
+   dw_container_change_item(handle, 0, row, (void *)&icon);
+   dw_container_change_item(handle, 1, row, (void *)&filename);
 }
 
 /*
@@ -6860,10 +8113,10 @@
  *          row: Zero based row of data being set.
  *          data: Pointer to the data to be added.
  */
-void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, unsigned long icon)
-{
-	dw_container_set_item(handle, pointer, 0, row, (void *)&icon);
-	dw_container_set_item(handle, pointer, 1, row, (void *)&filename);
+void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, HICN icon)
+{
+   dw_container_set_item(handle, pointer, 0, row, (void *)&icon);
+   dw_container_set_item(handle, pointer, 1, row, (void *)&filename);
 }
 
 /*
@@ -6877,7 +8130,7 @@
  */
 void API dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data)
 {
-	dw_container_set_item(handle, pointer, column + 2, row, data);
+   dw_container_set_item(handle, pointer, column + 2, row, data);
 }
 
 /*
@@ -6888,26 +8141,26 @@
  */
 int API dw_container_get_column_type(HWND handle, int column)
 {
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
-	ULONG *flags = blah ? blah->data : 0;
-	int rc;
-
-	if(!flags)
-		return 0;
-
-	if(flags[column] & DW_CFA_BITMAPORICON)
-		rc = DW_CFA_BITMAPORICON;
-	else if(flags[column] & DW_CFA_STRING)
-		rc = DW_CFA_STRING;
-	else if(flags[column] & DW_CFA_ULONG)
-		rc = DW_CFA_ULONG;
-	else if(flags[column] & DW_CFA_DATE)
-		rc = DW_CFA_DATE;
-	else if(flags[column] & DW_CFA_TIME)
-		rc = DW_CFA_TIME;
-	else
-		rc = 0;
-	return rc;
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
+   ULONG *flags = blah ? blah->data : 0;
+   int rc;
+
+   if(!flags)
+      return 0;
+
+   if(flags[column] & DW_CFA_BITMAPORICON)
+      rc = DW_CFA_BITMAPORICON;
+   else if(flags[column] & DW_CFA_STRING)
+      rc = DW_CFA_STRING;
+   else if(flags[column] & DW_CFA_ULONG)
+      rc = DW_CFA_ULONG;
+   else if(flags[column] & DW_CFA_DATE)
+      rc = DW_CFA_DATE;
+   else if(flags[column] & DW_CFA_TIME)
+      rc = DW_CFA_TIME;
+   else
+      rc = 0;
+   return rc;
 }
 
 /*
@@ -6918,7 +8171,21 @@
  */
 int API dw_filesystem_get_column_type(HWND handle, int column)
 {
-	return dw_container_get_column_type( handle, column + 2 );
+   return dw_container_get_column_type( handle, column + 2 );
+}
+
+/*
+ * Sets the alternating row colors for container window (widget) handle.
+ * Parameters:
+ *          handle: The window (widget) handle.
+ *          oddcolor: Odd row background color in DW_RGB format or a default color index.
+ *          evencolor: Even row background color in DW_RGB format or a default color index.
+ *                    DW_RGB_TRANSPARENT will disable coloring rows.
+ *                    DW_CLR_DEFAULT will use the system default alternating row colors.
+ */
+void API dw_container_set_stripe(HWND handle, unsigned long oddcolor, unsigned long evencolor)
+{
+    /* Don't think this is possible on OS/2 */
 }
 
 /*
@@ -6930,9 +8197,9 @@
  */
 void API dw_container_set_column_width(HWND handle, int column, int width)
 {
-	handle = handle; /* keep compiler happy */
-	column = column; /* keep compiler happy */
-	width = width; /* keep compiler happy */
+   handle = handle; /* keep compiler happy */
+   column = column; /* keep compiler happy */
+   width = width; /* keep compiler happy */
 }
 
 /*
@@ -6944,29 +8211,76 @@
  */
 void API dw_container_set_row_title(void *pointer, int row, char *title)
 {
-	ContainerInfo *ci = (ContainerInfo *)pointer;
-	PRECORDCORE temp;
-	int z, currentcount;
-	CNRINFO cnr;
-
-	if(!ci)
-		return;
-
-	temp = (PRECORDCORE)ci->data;
-
-	z = 0;
-
-	if(!_dw_send_msg(ci->handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO)), 0))
-		return;
-
-	currentcount = cnr.cRecords;
-
-	for(z=0;z<(row-currentcount);z++)
-		temp = temp->preccNextRecord;
-
-	temp->pszIcon = title;
-	temp->pszName = title;
-	temp->pszText = title;
+   ContainerInfo *ci = (ContainerInfo *)pointer;
+   PRECORDCORE temp;
+   int z, currentcount;
+   CNRINFO cnr;
+
+   if(!ci)
+      return;
+
+   temp = (PRECORDCORE)ci->data;
+
+   z = 0;
+
+   if(!_dw_send_msg(ci->handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO)), 0))
+      return;
+
+   currentcount = cnr.cRecords;
+
+   for(z=0;z<(row-currentcount);z++)
+      temp = temp->preccNextRecord;
+
+   temp->pszIcon = (PSZ)title;
+   temp->pszName = (PSZ)title;
+   temp->pszText = (PSZ)title;
+}
+
+/*
+ * Changes the title of a row already inserted in the container.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          row: Zero based row of data being set.
+ *          title: String title of the item.
+ */
+void API dw_container_change_row_title(HWND handle, int row, char *title)
+{
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+   int count = 0;
+
+   while(pCore)
+   {
+      if(count == row)
+      {
+         pCore->pszIcon = (PSZ)title;
+         pCore->pszName = (PSZ)title;
+         pCore->pszText = (PSZ)title;
+
+         WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_NOREPOSITION | CMA_TEXTCHANGED));
+         return;
+      }
+      pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+      count++;
+   }
+}
+
+/* Internal function to get the first item with given flags */
+PRECORDCORE _dw_container_start(HWND handle, unsigned long flags)
+{
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+
+   if(pCore)
+   {
+       while(pCore)
+       {
+           if(pCore->flRecordAttr & flags)
+           {
+               return pCore;
+           }
+           pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+       }
+   }
+   return NULL;
 }
 
 /*
@@ -6978,22 +8292,34 @@
  */
 void API dw_container_insert(HWND handle, void *pointer, int rowcount)
 {
-	RECORDINSERT recin;
-	ContainerInfo *ci = (ContainerInfo *)pointer;
-
-	if(!ci)
-		return;
-
-	recin.cb = sizeof(RECORDINSERT);
-	recin.pRecordOrder = (PRECORDCORE)CMA_END;
-	recin.pRecordParent = NULL;
-	recin.zOrder = CMA_TOP;
-	recin.fInvalidateRecord = TRUE;
-	recin.cRecordsInsert = rowcount;
-
-	_dw_send_msg(handle, CM_INSERTRECORD, MPFROMP(ci->data), MPFROMP(&recin), 0);
-
-	free(ci);
+   RECORDINSERT recin;
+   ContainerInfo *ci = (ContainerInfo *)pointer;
+   PRECORDCORE pCore;
+
+   if(!ci)
+      return;
+
+   recin.cb = sizeof(RECORDINSERT);
+   recin.pRecordOrder = (PRECORDCORE)CMA_END;
+   recin.pRecordParent = NULL;
+   recin.zOrder = CMA_TOP;
+   recin.fInvalidateRecord = TRUE;
+   recin.cRecordsInsert = rowcount;
+
+   _dw_send_msg(handle, CM_INSERTRECORD, MPFROMP(ci->data), MPFROMP(&recin), 0);
+
+   free(ci);
+
+   if((pCore = _dw_container_start(handle, CRA_CURSORED)))
+   {
+       NOTIFYRECORDEMPHASIS pre;
+
+       pre.pRecord = pCore;
+       pre.fEmphasisMask = CRA_CURSORED;
+       pre.hwndCnr = handle;
+       _run_event(handle, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre);
+       pre.pRecord->flRecordAttr |= CRA_CURSORED;
+   }
 }
 
 /*
@@ -7004,30 +8330,30 @@
  */
 void API dw_container_clear(HWND handle, int redraw)
 {
-	PCNRITEM pCore;
-	int container = (int)dw_window_get_data(handle, "_dw_container");
-
-	if(hwndEmph == handle)
-		_clear_emphasis();
-
-	pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-
-	while(pCore)
-	{
-		if(container)
-			_dw_container_free_strings(handle, (PRECORDCORE)pCore);
-		else
-		{
-			/* Free icon text */
-			if(pCore->rc.pszIcon)
-			{
-				free(pCore->rc.pszIcon);
-				pCore->rc.pszIcon = 0;
-			}
-		}
-		pCore = (PCNRITEM)pCore->rc.preccNextRecord;/*WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));*/
-	}
-	_dw_send_msg(handle, CM_REMOVERECORD, (MPARAM)0L, MPFROM2SHORT(0, (redraw ? CMA_INVALIDATE : 0) | CMA_FREE), -1);
+   PCNRITEM pCore;
+   int container = (int)dw_window_get_data(handle, "_dw_container");
+
+   if(hwndEmph == handle)
+      _clear_emphasis();
+
+   pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+
+   while(pCore)
+   {
+      if(container)
+         _dw_container_free_strings(handle, (PRECORDCORE)pCore);
+      else
+      {
+         /* Free icon text */
+         if(pCore->rc.pszIcon)
+         {
+            free(pCore->rc.pszIcon);
+            pCore->rc.pszIcon = 0;
+         }
+      }
+      pCore = (PCNRITEM)pCore->rc.preccNextRecord;/*WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));*/
+   }
+   _dw_send_msg(handle, CM_REMOVERECORD, (MPARAM)0L, MPFROM2SHORT(0, (redraw ? CMA_INVALIDATE : 0) | CMA_FREE), -1);
 }
 
 /*
@@ -7038,21 +8364,21 @@
  */
 void API dw_container_delete(HWND handle, int rowcount)
 {
-	RECORDCORE *last, **prc = malloc(sizeof(RECORDCORE *) * rowcount);
-	int current = 1;
-
-	prc[0] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-
-	while(last && current < rowcount)
-	{
-		_dw_container_free_strings(handle, last);
-		prc[current] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)last, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-		current++;
-	}
-
-	_dw_send_msg(handle, CM_REMOVERECORD, (MPARAM)prc, MPFROM2SHORT(current, CMA_INVALIDATE | CMA_FREE), -1);
-	
-	free(prc);
+   RECORDCORE *last, **prc = malloc(sizeof(RECORDCORE *) * rowcount);
+   int current = 1;
+
+   prc[0] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+
+   while(last && current < rowcount)
+   {
+      _dw_container_free_strings(handle, last);
+      prc[current] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)last, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+      current++;
+   }
+
+   _dw_send_msg(handle, CM_REMOVERECORD, (MPARAM)prc, MPFROM2SHORT(current, CMA_INVALIDATE | CMA_FREE), -1);
+
+   free(prc);
 }
 
 /*
@@ -7065,16 +8391,16 @@
  */
 void API dw_container_scroll(HWND handle, int direction, long rows)
 {
-	rows = rows; /* keep compiler happy */
-	switch(direction)
-	{
-	case DW_SCROLL_TOP:
-		WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(-10000000));
+   rows = rows; /* keep compiler happy */
+   switch(direction)
+   {
+   case DW_SCROLL_TOP:
+      WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(-10000000));
         break;
-	case DW_SCROLL_BOTTOM:
-		WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(10000000));
-		break;
-	}
+   case DW_SCROLL_BOTTOM:
+      WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(10000000));
+      break;
+   }
 }
 
 /*
@@ -7087,29 +8413,29 @@
  */
 char * API dw_container_query_start(HWND handle, unsigned long flags)
 {
-	PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-
-	if(pCore)
-	{
-		if(flags)
-		{
-			while(pCore)
-			{
-				if(pCore->flRecordAttr & flags)
-				{
-					dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
-					return pCore->pszIcon;
-				}
-				pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-			}
-		}
-		else
-		{
-			dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
-			return pCore->pszIcon;
-		}
-	}
-    return NULL;
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+
+   if(pCore)
+   {
+      if(flags)
+      {
+         while(pCore)
+         {
+            if(pCore->flRecordAttr & flags)
+            {
+               dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
+               return (char *)pCore->pszIcon;
+            }
+            pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+         }
+      }
+      else
+      {
+         dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
+         return (char *)pCore->pszIcon;
+      }
+   }
+   return NULL;
 }
 
 /*
@@ -7122,31 +8448,31 @@
  */
 char * API dw_container_query_next(HWND handle, unsigned long flags)
 {
-	PRECORDCORE pCore = (PRECORDCORE)dw_window_get_data(handle, "_dw_pcore");
-
-	pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-
-	if(pCore)
-	{
-		if(flags)
-		{
-			while(pCore)
-			{
-				if(pCore->flRecordAttr & flags)
-				{
-					dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
-					return pCore->pszIcon;
-				}
-
-				pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-			}
-		}
-		else
-		{
-			dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
-			return pCore->pszIcon;
-		}
-	}
+   PRECORDCORE pCore = (PRECORDCORE)dw_window_get_data(handle, "_dw_pcore");
+
+   pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+
+   if(pCore)
+   {
+      if(flags)
+      {
+         while(pCore)
+         {
+            if(pCore->flRecordAttr & flags)
+            {
+               dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
+               return (char *)pCore->pszIcon;
+            }
+
+            pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+         }
+      }
+      else
+      {
+         dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
+         return (char *)pCore->pszIcon;
+      }
+   }
     return NULL;
 }
 
@@ -7158,34 +8484,35 @@
  */
 void API dw_container_cursor(HWND handle, char *text)
 {
-	RECTL viewport, item;
-	PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-
-	while(pCore)
-	{
-		if((char *)pCore->pszIcon == text)
-		{
-			QUERYRECORDRECT qrr;
-			int scrollpixels = 0, midway;
-
-			qrr.cb = sizeof(QUERYRECORDRECT);
-			qrr.pRecord = pCore;
-			qrr.fRightSplitWindow = 0;
-			qrr.fsExtent = CMA_TEXT;
-
-			WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(TRUE, CRA_CURSORED));
-			WinSendMsg(handle, CM_QUERYVIEWPORTRECT, (MPARAM)&viewport, MPFROM2SHORT(CMA_WORKSPACE, FALSE));
-			WinSendMsg(handle, CM_QUERYRECORDRECT, (MPARAM)&item, (MPARAM)&qrr);
-
-			midway = (viewport.yTop - viewport.yBottom)/2;
-			scrollpixels = viewport.yTop - (item.yTop + midway);
-
-			WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL),  MPFROMLONG(scrollpixels));
-			return;
-		}
-
-		pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-	}
+   RECTL viewport, item;
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+   int textcomp = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_textcomp"));
+
+   while(pCore)
+   {
+      if((textcomp && pCore->pszIcon && strcmp((char *)pCore->pszIcon, text) == 0) || (!textcomp && (char *)pCore->pszIcon == text))
+      {
+         QUERYRECORDRECT qrr;
+         int scrollpixels = 0, midway;
+
+         qrr.cb = sizeof(QUERYRECORDRECT);
+         qrr.pRecord = pCore;
+         qrr.fRightSplitWindow = 0;
+         qrr.fsExtent = CMA_TEXT;
+
+         WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(TRUE, CRA_CURSORED));
+         WinSendMsg(handle, CM_QUERYVIEWPORTRECT, (MPARAM)&viewport, MPFROM2SHORT(CMA_WORKSPACE, FALSE));
+         WinSendMsg(handle, CM_QUERYRECORDRECT, (MPARAM)&item, (MPARAM)&qrr);
+
+         midway = (viewport.yTop - viewport.yBottom)/2;
+         scrollpixels = viewport.yTop - (item.yTop + midway);
+
+         WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL),  MPFROMLONG(scrollpixels));
+         return;
+      }
+
+      pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+   }
 }
 
 /*
@@ -7196,17 +8523,18 @@
  */
 void API dw_container_delete_row(HWND handle, char *text)
 {
-	PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-
-	while(pCore)
-	{
-		if((char *)pCore->pszIcon == text)
-		{
-			WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_FREE | CMA_INVALIDATE));
-			return;
-		}
-		pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-	}
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+   int textcomp = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_textcomp"));
+
+   while(pCore)
+   {
+      if((textcomp && pCore->pszIcon && strcmp((char *)pCore->pszIcon, text) == 0) || (!textcomp && (char *)pCore->pszIcon == text))
+      {
+         WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_FREE | CMA_INVALIDATE));
+         return;
+      }
+      pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+   }
 }
 
 /*
@@ -7216,44 +8544,44 @@
  */
 void API dw_container_optimize(HWND handle)
 {
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
-	RECTL item;
-	PRECORDCORE pCore = NULL;
-	int max = 0;
-
-	if(blah && !blah->flags)
-		return;
-
-	pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-	while(pCore)
-	{
-		QUERYRECORDRECT qrr;
-		int vector;
-
-		qrr.cb = sizeof(QUERYRECORDRECT);
-		qrr.pRecord = pCore;
-		qrr.fRightSplitWindow = 0;
-		qrr.fsExtent = CMA_TEXT;
-
-		WinSendMsg(handle, CM_QUERYRECORDRECT, (MPARAM)&item, (MPARAM)&qrr);
-
-		vector = item.xRight - item.xLeft;
-
-		if(vector > max)
-			max = vector;
-
-		pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-	}
-
-	if(max)
-	{
-		CNRINFO cnri;
-
-		cnri.cb = sizeof(CNRINFO);
-		cnri.xVertSplitbar  = max;
-
-		WinSendMsg(handle, CM_SETCNRINFO, MPFROMP(&cnri),  MPFROMLONG(CMA_XVERTSPLITBAR));
-	}
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
+   RECTL item;
+   PRECORDCORE pCore = NULL;
+   int max = 0;
+
+   if(blah && !blah->flags)
+      return;
+
+   pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+   while(pCore)
+   {
+      QUERYRECORDRECT qrr;
+      int vector;
+
+      qrr.cb = sizeof(QUERYRECORDRECT);
+      qrr.pRecord = pCore;
+      qrr.fRightSplitWindow = 0;
+      qrr.fsExtent = CMA_TEXT;
+
+      WinSendMsg(handle, CM_QUERYRECORDRECT, (MPARAM)&item, (MPARAM)&qrr);
+
+      vector = item.xRight - item.xLeft;
+
+      if(vector > max)
+         max = vector;
+
+      pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+   }
+
+   if(max)
+   {
+      CNRINFO cnri;
+
+      cnri.cb = sizeof(CNRINFO);
+      cnri.xVertSplitbar  = max;
+
+      WinSendMsg(handle, CM_SETCNRINFO, MPFROMP(&cnri),  MPFROMLONG(CMA_XVERTSPLITBAR));
+   }
 }
 
 /*
@@ -7263,12 +8591,15 @@
  *       icon: Icon handle to display in the taskbar.
  *       bubbletext: Text to show when the mouse is above the icon.
  */
-void API dw_taskbar_insert(HWND handle, unsigned long icon, char *bubbletext)
-{
-	handle = handle;
-	icon = icon;
-	bubbletext = bubbletext;
-	/* TODO */
+void API dw_taskbar_insert(HWND handle, HICN icon, char *bubbletext)
+{
+    /* Make sure we have our server */
+    if(!hwndTrayServer)
+        return;
+
+    WinSendMsg(hwndApp, WM_SETICON, (MPARAM)icon, 0);
+    hwndTaskBar = handle;
+    WinPostMsg(hwndTrayServer, WM_USER+1, (MPARAM)hwndApp, (MPARAM)icon);
 }
 
 /*
@@ -7277,11 +8608,14 @@
  *       handle: Window handle that was used with dw_taskbar_insert().
  *       icon: Icon handle that was used with dw_taskbar_insert().
  */
-void API dw_taskbar_delete(HWND handle, unsigned long icon)
-{
-	handle = handle;
-	icon = icon;
-	/* TODO */
+void API dw_taskbar_delete(HWND handle, HICN icon)
+{
+    /* Make sure we have our server */
+    if(!hwndTrayServer)
+        return;
+
+    WinPostMsg(hwndTrayServer, WM_USER+2, (MPARAM)hwndApp, (MPARAM)0);
+    hwndTaskBar = NULLHANDLE;
 }
 
 /*
@@ -7293,19 +8627,19 @@
  */
 HWND API dw_render_new(unsigned long id)
 {
-	HWND hwndframe = WinCreateWindow(HWND_OBJECT,
-									 WC_FRAME,
-									 NULL,
-									 WS_VISIBLE |
-									 FS_NOBYTEALIGN,
-									 0,0,2000,1000,
-									 NULLHANDLE,
-									 HWND_TOP,
-									 id,
-									 NULL,
-									 NULL);
-	WinSubclassWindow(hwndframe, _RendProc);
-	return hwndframe;
+   HWND hwndframe = WinCreateWindow(HWND_OBJECT,
+                            WC_FRAME,
+                            NULL,
+                            WS_VISIBLE |
+                            FS_NOBYTEALIGN,
+                            0,0,2000,1000,
+                            NULLHANDLE,
+                            HWND_TOP,
+                            id,
+                            NULL,
+                            NULL);
+   WinSubclassWindow(hwndframe, _RendProc);
+   return hwndframe;
 }
 
 /* Sets the current foreground drawing color.
@@ -7316,7 +8650,7 @@
  */
 void API dw_color_foreground_set(unsigned long value)
 {
-	_foreground = value;
+   _foreground = value;
 }
 
 /* Sets the current background drawing color.
@@ -7327,39 +8661,39 @@
  */
 void API dw_color_background_set(unsigned long value)
 {
-	_background = value;
+   _background = value;
 }
 
 int DWSIGNAL _dw_color_cancel_func(HWND window, void *data)
 {
-	DWDialog *dwwait = (DWDialog *)data;
-	HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
-	void *val;
-
-	window = (HWND)dwwait->data;
-	val = dw_window_get_data(window, "_dw_val");
-
-	dw_mutex_lock(mtx);
-	dw_mutex_close(mtx);
-	dw_window_destroy(window);
-	dw_dialog_dismiss((DWDialog *)data, val);
-	return FALSE;
+   DWDialog *dwwait = (DWDialog *)data;
+   HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
+   void *val;
+
+   window = (HWND)dwwait->data;
+   val = dw_window_get_data(window, "_dw_val");
+
+   dw_mutex_lock(mtx);
+   dw_mutex_close(mtx);
+   dw_window_destroy(window);
+   dw_dialog_dismiss((DWDialog *)data, val);
+   return FALSE;
 }
 
 int DWSIGNAL _dw_color_ok_func(HWND window, void *data)
 {
-	DWDialog *dwwait = (DWDialog *)data;
-	HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
-	unsigned long val;
-
-	window = (HWND)dwwait->data;
-	val = _dw_color_spin_get(window);
-
-	dw_mutex_lock(mtx);
-	dw_mutex_close(mtx);
-	dw_window_destroy(window);
-	dw_dialog_dismiss((DWDialog *)data, (void *)val);
-	return FALSE;
+   DWDialog *dwwait = (DWDialog *)data;
+   HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
+   unsigned long val;
+
+   window = (HWND)dwwait->data;
+   val = _dw_color_spin_get(window);
+
+   dw_mutex_lock(mtx);
+   dw_mutex_close(mtx);
+   dw_window_destroy(window);
+   dw_dialog_dismiss((DWDialog *)data, (void *)val);
+   return FALSE;
 }
 
 /* Allows the user to choose a color using the system's color chooser dialog.
@@ -7370,122 +8704,122 @@
  */
 unsigned long API dw_color_choose(unsigned long value)
 {
-	HWND window, hbox, vbox, col, button, text;
-	DWDialog *dwwait;
-	HMTX mtx = dw_mutex_new();
-
-	window = dw_window_new( HWND_DESKTOP, "Choose Color", FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_DLGBORDER | FCF_CLOSEBUTTON | FCF_SYSMENU);
-
-	vbox = dw_box_new(DW_VERT, 5);
-
-	dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0);
-
-	hbox = dw_box_new(DW_HORZ, 0);
-
-	dw_box_pack_start(vbox, hbox, 0, 0, FALSE, FALSE, 0);
-	dw_window_set_style(hbox, 0, WS_CLIPCHILDREN);
-
-	col = WinCreateWindow(vbox, "ColorSelectClass", "", WS_VISIBLE | WS_GROUP, 0, 0, 390, 300, vbox, HWND_TOP, 266, NULL,NULL);
-	dw_box_pack_start(hbox, col, 390, 300, FALSE, FALSE, 0);
-
-	dw_window_set_data(hbox, "_dw_window", (void *)window);
-	dw_window_set_data(window, "_dw_mutex", (void *)mtx);
-	dw_window_set_data(window, "_dw_col", (void *)col);
-	dw_window_set_data(window, "_dw_val", (void *)value);
-
-	hbox = dw_box_new(DW_HORZ, 0);
-	dw_window_set_data(hbox, "_dw_window", (void *)window);
-
-	dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
-
-	text = dw_text_new("Red:", 0);
-	dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER);
-	dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3);
-
-	button = dw_spinbutton_new("", 1001L);
-	dw_spinbutton_set_limits(button, 255, 0);
-	dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3);
-	WinSetOwner(button, hbox);
-	dw_window_set_data(window, "_dw_red_spin", (void *)button);
-
-	text = dw_text_new("Green:", 0);
-	dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER);
-	dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3);
-
-	button = dw_spinbutton_new("", 1002L);
-	dw_spinbutton_set_limits(button, 255, 0);
-	dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3);
-	WinSetOwner(button, hbox);
-	dw_window_set_data(window, "_dw_green_spin", (void *)button);
-
-	text = dw_text_new("Blue:", 0);
-	dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER);
-	dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3);
-
-	button = dw_spinbutton_new("", 1003L);
-	dw_spinbutton_set_limits(button, 255, 0);
-	dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3);
-	WinSetOwner(button, hbox);
-	dw_window_set_data(window, "_dw_blue_spin", (void *)button);
-
-	hbox = dw_box_new(DW_HORZ, 0);
-
-	dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
-	dw_box_pack_start(hbox, 0, 100, 1, TRUE, FALSE, 0);
-
-	button = dw_button_new("Ok", 1001L);
-	dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
-
-	dwwait = dw_dialog_new((void *)window);
-
-	dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_color_ok_func), (void *)dwwait);
-
-	button = dw_button_new("Cancel", 1002L);
-	dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
-
-	dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_color_cancel_func), (void *)dwwait);
-	dw_signal_connect(window, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_dw_color_cancel_func), (void *)dwwait);
-
-	dw_window_set_size(window, 400, 400);
-
-	_dw_col_set(col, value);
-	_dw_color_spin_set(window, value);
-
-	dw_window_show(window);
-
-	return (unsigned long)dw_dialog_wait(dwwait);
+   HWND window, hbox, vbox, col, button, text;
+   DWDialog *dwwait;
+   HMTX mtx = dw_mutex_new();
+
+   window = dw_window_new( HWND_DESKTOP, "Choose Color", FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_DLGBORDER | FCF_CLOSEBUTTON | FCF_SYSMENU);
+
+   vbox = dw_box_new(DW_VERT, 5);
+
+   dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0);
+
+   hbox = dw_box_new(DW_HORZ, 0);
+
+   dw_box_pack_start(vbox, hbox, 0, 0, FALSE, FALSE, 0);
+   dw_window_set_style(hbox, 0, WS_CLIPCHILDREN);
+
+   col = WinCreateWindow(vbox, (PSZ)"ColorSelectClass", NULL, WS_VISIBLE | WS_GROUP, 0, 0, 390, 300, vbox, HWND_TOP, 266, NULL,NULL);
+   dw_box_pack_start(hbox, col, 390, 300, FALSE, FALSE, 0);
+
+   dw_window_set_data(hbox, "_dw_window", (void *)window);
+   dw_window_set_data(window, "_dw_mutex", (void *)mtx);
+   dw_window_set_data(window, "_dw_col", (void *)col);
+   dw_window_set_data(window, "_dw_val", (void *)value);
+
+   hbox = dw_box_new(DW_HORZ, 0);
+   dw_window_set_data(hbox, "_dw_window", (void *)window);
+
+   dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
+
+   text = dw_text_new("Red:", 0);
+   dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER);
+   dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3);
+
+   button = dw_spinbutton_new("", 1001L);
+   dw_spinbutton_set_limits(button, 255, 0);
+   dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3);
+   WinSetOwner(button, hbox);
+   dw_window_set_data(window, "_dw_red_spin", (void *)button);
+
+   text = dw_text_new("Green:", 0);
+   dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER);
+   dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3);
+
+   button = dw_spinbutton_new("", 1002L);
+   dw_spinbutton_set_limits(button, 255, 0);
+   dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3);
+   WinSetOwner(button, hbox);
+   dw_window_set_data(window, "_dw_green_spin", (void *)button);
+
+   text = dw_text_new("Blue:", 0);
+   dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER);
+   dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3);
+
+   button = dw_spinbutton_new("", 1003L);
+   dw_spinbutton_set_limits(button, 255, 0);
+   dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3);
+   WinSetOwner(button, hbox);
+   dw_window_set_data(window, "_dw_blue_spin", (void *)button);
+
+   hbox = dw_box_new(DW_HORZ, 0);
+
+   dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
+   dw_box_pack_start(hbox, 0, 100, 1, TRUE, FALSE, 0);
+
+   button = dw_button_new("Ok", 1001L);
+   dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
+
+   dwwait = dw_dialog_new((void *)window);
+
+   dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_color_ok_func), (void *)dwwait);
+
+   button = dw_button_new("Cancel", 1002L);
+   dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
+
+   dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_color_cancel_func), (void *)dwwait);
+   dw_signal_connect(window, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_dw_color_cancel_func), (void *)dwwait);
+
+   dw_window_set_size(window, 400, 400);
+
+   _dw_col_set(col, value);
+   _dw_color_spin_set(window, value);
+
+   dw_window_show(window);
+
+   return (unsigned long)dw_dialog_wait(dwwait);
 }
 
 HPS _set_hps(HPS hps)
 {
-	LONG alTable[2];
-
-	alTable[0] = DW_RED_VALUE(_foreground) << 16 | DW_GREEN_VALUE(_foreground) << 8 | DW_BLUE_VALUE(_foreground);
-	alTable[1] = DW_RED_VALUE(_background) << 16 | DW_GREEN_VALUE(_background) << 8 | DW_BLUE_VALUE(_background);
-
-	GpiCreateLogColorTable(hps,
-						   LCOL_RESET,
-						   LCOLF_CONSECRGB,
-						   16,
-						   2,
-						   alTable);
-	if(_foreground & DW_RGB_COLOR)
-		GpiSetColor(hps, 16);
-	else
-		GpiSetColor(hps, _internal_color(_foreground));
-	if(_background & DW_RGB_COLOR)
-		GpiSetBackColor(hps, 17);
-	else
-		GpiSetBackColor(hps, _internal_color(_background));
-	return hps;
+   LONG alTable[2];
+
+   alTable[0] = DW_RED_VALUE(_foreground) << 16 | DW_GREEN_VALUE(_foreground) << 8 | DW_BLUE_VALUE(_foreground);
+   alTable[1] = DW_RED_VALUE(_background) << 16 | DW_GREEN_VALUE(_background) << 8 | DW_BLUE_VALUE(_background);
+
+   GpiCreateLogColorTable(hps,
+                     LCOL_RESET,
+                     LCOLF_CONSECRGB,
+                     16,
+                     2,
+                     alTable);
+   if(_foreground & DW_RGB_COLOR)
+      GpiSetColor(hps, 16);
+   else
+      GpiSetColor(hps, _internal_color(_foreground));
+   if(_background & DW_RGB_COLOR)
+      GpiSetBackColor(hps, 17);
+   else
+      GpiSetBackColor(hps, _internal_color(_background));
+   return hps;
 }
 
 HPS _set_colors(HWND handle)
 {
-	HPS hps = WinGetPS(handle);
-
-	_set_hps(hps);
-	return hps;
+   HPS hps = WinGetPS(handle);
+
+   _set_hps(hps);
+   return hps;
 }
 
 /* Draw a point on a window (preferably a render window).
@@ -7497,29 +8831,29 @@
  */
 void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y)
 {
-	HPS hps;
-	int height;
-	POINTL ptl;
-
-	if(handle)
-	{
-		hps = _set_colors(handle);
+   HPS hps;
+   int height;
+   POINTL ptl;
+
+   if(handle)
+   {
+      hps = _set_colors(handle);
         height = _get_height(handle);
-	}
-	else if(pixmap)
-	{
-		hps = _set_hps(pixmap->hps);
-		height = pixmap->height;
-	}
-	else
-		return;
-
-	ptl.x = x;
-	ptl.y = height - y - 1;
-
-	GpiSetPel(hps, &ptl);
-	if(!pixmap)
-		WinReleasePS(hps);
+   }
+   else if(pixmap)
+   {
+      hps = _set_hps(pixmap->hps);
+      height = pixmap->height;
+   }
+   else
+      return;
+
+   ptl.x = x;
+   ptl.y = height - y - 1;
+
+   GpiSetPel(hps, &ptl);
+   if(!pixmap)
+      WinReleasePS(hps);
 }
 
 /* Draw a line on a window (preferably a render window).
@@ -7533,56 +8867,56 @@
  */
 void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2)
 {
-	HPS hps;
-	int height;
-	POINTL ptl[2];
-
-	if(handle)
-	{
-		hps = _set_colors(handle);
+   HPS hps;
+   int height;
+   POINTL ptl[2];
+
+   if(handle)
+   {
+      hps = _set_colors(handle);
         height = _get_height(handle);
-	}
-	else if(pixmap)
-	{
-		hps = _set_hps(pixmap->hps);
-		height = pixmap->height;
-	}
-	else
-		return;
-
-	ptl[0].x = x1;
-	ptl[0].y = height - y1 - 1;
-	ptl[1].x = x2;
-	ptl[1].y = height - y2 - 1;
-
-	GpiMove(hps, &ptl[0]);
-	GpiLine(hps, &ptl[1]);
-	
-	if(!pixmap)
-		WinReleasePS(hps);
+   }
+   else if(pixmap)
+   {
+      hps = _set_hps(pixmap->hps);
+      height = pixmap->height;
+   }
+   else
+      return;
+
+   ptl[0].x = x1;
+   ptl[0].y = height - y1 - 1;
+   ptl[1].x = x2;
+   ptl[1].y = height - y2 - 1;
+
+   GpiMove(hps, &ptl[0]);
+   GpiLine(hps, &ptl[1]);
+
+   if(!pixmap)
+      WinReleasePS(hps);
 }
 
 
 void _CopyFontSettings(HPS hpsSrc, HPS hpsDst)
 {
-	FONTMETRICS fm;
-	FATTRS fat;
-	SIZEF sizf;
-
-	GpiQueryFontMetrics(hpsSrc, sizeof(FONTMETRICS), &fm);
-
-    memset(&fat, 0, sizeof(fat));
-
-	fat.usRecordLength  = sizeof(FATTRS);
-	fat.lMatch          = fm.lMatch;
-	strcpy(fat.szFacename, fm.szFacename);
-
-	GpiCreateLogFont(hpsDst, 0, 1L, &fat);
-	GpiSetCharSet(hpsDst, 1L);
-
-	sizf.cx = MAKEFIXED(fm.lEmInc,0);
-	sizf.cy = MAKEFIXED(fm.lMaxBaselineExt,0);
-	GpiSetCharBox(hpsDst, &sizf );
+   FONTMETRICS fm;
+   FATTRS fat;
+   SIZEF sizf;
+
+   GpiQueryFontMetrics(hpsSrc, sizeof(FONTMETRICS), &fm);
+
+   memset(&fat, 0, sizeof(fat));
+
+   fat.usRecordLength  = sizeof(FATTRS);
+   fat.lMatch          = fm.lMatch;
+   strcpy(fat.szFacename, fm.szFacename);
+
+   GpiCreateLogFont(hpsDst, 0, 1L, &fat);
+   GpiSetCharSet(hpsDst, 1L);
+
+   sizf.cx = MAKEFIXED(fm.lEmInc,0);
+   sizf.cy = MAKEFIXED(fm.lMaxBaselineExt,0);
+   GpiSetCharBox(hpsDst, &sizf );
 }
 
 /* Draw text on a window (preferably a render window).
@@ -7595,51 +8929,51 @@
  */
 void API dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text)
 {
-	HPS hps;
-	int z, height;
-	RECTL rcl;
-	char fontname[128];
-	POINTL aptl[TXTBOX_COUNT];
-
-	if(handle)
-	{
-		hps = _set_colors(handle);
-		height = _get_height(handle);
-		_GetPPFont(handle, fontname);
-	}
-	else if(pixmap)
-	{
-		HPS pixmaphps = WinGetPS(pixmap->handle);
-
-		hps = _set_hps(pixmap->hps);
-		height = pixmap->height;
-		_GetPPFont(pixmap->handle, fontname);
-		_CopyFontSettings(pixmaphps, hps);
-		WinReleasePS(pixmaphps);
-	}
-	else
-		return;
-
-	for(z=0;z<strlen(fontname);z++)
-	{
-		if(fontname[z]=='.')
-			break;
-	}
-
-	GpiQueryTextBox(hps, strlen(text), text, TXTBOX_COUNT, aptl);
-
-	rcl.xLeft = x;
-	rcl.yTop = height - y;
-	rcl.yBottom = rcl.yTop - (aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y);
-	rcl.xRight = rcl.xLeft + (aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x);
-
-	if(_background == DW_CLR_DEFAULT)
-		WinDrawText(hps, -1, text, &rcl, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS);
-	else
-		WinDrawText(hps, -1, text, &rcl, _internal_color(_foreground), _internal_color(_background), DT_VCENTER | DT_LEFT | DT_ERASERECT);
-
-	if(!pixmap)
-		WinReleasePS(hps);
+    HPS hps;
+    int z, height;
+    RECTL rcl;
+    char fontname[128];
+    POINTL aptl[TXTBOX_COUNT];
+
+    if(handle)
+    {
+        hps = _set_colors(handle);
+        height = _get_height(handle);
+        _GetPPFont(handle, fontname);
+    }
+    else if(pixmap)
+    {
+        HPS pixmaphps = WinGetPS(pixmap->font ? pixmap->font : pixmap->handle);
+
+        hps = _set_hps(pixmap->hps);
+        height = pixmap->height;
+        _GetPPFont(pixmap->font ? pixmap->font : pixmap->handle, fontname);
+        _CopyFontSettings(pixmaphps, hps);
+        WinReleasePS(pixmaphps);
+    }
+    else
+        return;
+
+    for(z=0;z<strlen(fontname);z++)
+    {
+        if(fontname[z]=='.')
+            break;
+    }
+
+    GpiQueryTextBox(hps, strlen(text), (PCH)text, TXTBOX_COUNT, aptl);
+
+    rcl.xLeft = x;
+    rcl.yTop = height - y;
+    rcl.yBottom = rcl.yTop - (aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y);
+    rcl.xRight = rcl.xLeft + (aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x);
+
+    if(_background == DW_CLR_DEFAULT)
+        WinDrawText(hps, -1, (PCH)text, &rcl, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS);
+    else
+        WinDrawText(hps, -1, (PCH)text, &rcl, _internal_color(_foreground), _internal_color(_background), DT_VCENTER | DT_LEFT | DT_ERASERECT);
+
+    if(!pixmap)
+        WinReleasePS(hps);
 }
 
 /* Query the width and height of a text string.
@@ -7652,75 +8986,227 @@
  */
 void API dw_font_text_extents_get(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height)
 {
-	HPS hps;
-	POINTL aptl[TXTBOX_COUNT];
-
-	if(handle)
-	{
-		hps = _set_colors(handle);
-	}
-	else if(pixmap)
-	{
-		HPS pixmaphps = WinGetPS(pixmap->handle);
-
-		hps = _set_hps(pixmap->hps);
-		_CopyFontSettings(pixmaphps, hps);
-		WinReleasePS(pixmaphps);
-	}
-	else
-		return;
-
-	GpiQueryTextBox(hps, strlen(text), text, TXTBOX_COUNT, aptl);
-
-	if(width)
-		*width = aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x;
-
-	if(height)
-		*height = aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y;
-
-	if(!pixmap)
-		WinReleasePS(hps);
+   HPS hps;
+   POINTL aptl[TXTBOX_COUNT];
+
+   if(handle)
+   {
+      hps = _set_colors(handle);
+   }
+   else if(pixmap)
+   {
+      HPS pixmaphps = WinGetPS(pixmap->font ? pixmap->font : pixmap->handle);
+
+      hps = _set_hps(pixmap->hps);
+      _CopyFontSettings(pixmaphps, hps);
+      WinReleasePS(pixmaphps);
+   }
+   else
+      return;
+
+   GpiQueryTextBox(hps, strlen(text), (PCH)text, TXTBOX_COUNT, aptl);
+
+   if(width)
+      *width = aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x;
+
+   if(height)
+      *height = aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y;
+
+   if(!pixmap)
+      WinReleasePS(hps);
+}
+
+/* Draw a polygon on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       flags: DW_DRAW_FILL (1) to fill the polygon or DW_DRAW_DEFAULT (0).
+ *       x: X coordinate.
+ *       y: Y coordinate.
+ *       width: Width of rectangle.
+ *       height: Height of rectangle.
+ */
+void API dw_draw_polygon( HWND handle, HPIXMAP pixmap, int flags, int npoints, int *x, int *y )
+{
+   HPS hps;
+   int thisheight;
+   POINTL *pptl;
+   POINTL start;
+   int i;
+
+   if(handle)
+   {
+      hps = _set_colors(handle);
+      thisheight = _get_height(handle);
+   }
+   else if(pixmap)
+   {
+      hps = _set_hps(pixmap->hps);
+      thisheight = pixmap->height;
+   }
+   else
+      return;
+   if ( npoints == 0 )
+      return;
+   pptl = (POINTL *)malloc(sizeof(POINTL)*npoints);
+   if ( pptl == NULL )
+      return;
+   /*
+    * For a filled polygon we need to start an area
+    */
+   if ( flags & DW_DRAW_FILL )
+      GpiBeginArea( hps, 0L );
+   if ( npoints )
+   {
+      /*
+       * Move to the first point of the polygon
+       */
+      start.x = x[0];
+      start.y = thisheight - y[0] - 1;
+      GpiMove( hps, &start );
+      /*
+       * Convert the remainder of the x and y points
+       */
+      for ( i = 1; i < npoints; i++ )
+      {
+         pptl[i-1].x = x[i];
+         pptl[i-1].y = thisheight - y[i] - 1;
+      }
+      GpiPolyLine( hps, npoints-1, pptl );
+
+      if ( flags & DW_DRAW_FILL )
+         GpiEndArea( hps );
+   }
+   if ( !pixmap )
+      WinReleasePS(hps);
+   free( pptl );
 }
 
 /* Draw a rectangle on a window (preferably a render window).
  * Parameters:
  *       handle: Handle to the window.
  *       pixmap: Handle to the pixmap. (choose only one of these)
- *       fill: Fill box TRUE or FALSE.
+ *       flags: DW_DRAW_FILL (1) to fill the box or DW_DRAW_DEFAULT (0).
  *       x: X coordinate.
  *       y: Y coordinate.
  *       width: Width of rectangle.
  *       height: Height of rectangle.
  */
-void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height)
-{
-	HPS hps;
-	int thisheight;
-	POINTL ptl[2];
-
-	if(handle)
-	{
-		hps = _set_colors(handle);
+void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int flags, int x, int y, int width, int height)
+{
+   HPS hps;
+   int thisheight;
+   POINTL ptl[2];
+
+   if(handle)
+   {
+      hps = _set_colors(handle);
         thisheight = _get_height(handle);
-	}
-	else if(pixmap)
-	{
-		hps = _set_hps(pixmap->hps);
-		thisheight = pixmap->height;
-	}
-	else
-		return;
-
-	ptl[0].x = x;
-	ptl[0].y = thisheight - y - 1;
-	ptl[1].x = x + width - 1;
-	ptl[1].y = thisheight - y - height;
-
-	GpiMove(hps, &ptl[0]);
-	GpiBox(hps, fill ? DRO_OUTLINEFILL : DRO_OUTLINE, &ptl[1], 0, 0);
-	
-	if(!pixmap)
-		WinReleasePS(hps);
+   }
+   else if(pixmap)
+   {
+      hps = _set_hps(pixmap->hps);
+      thisheight = pixmap->height;
+   }
+   else
+      return;
+
+   ptl[0].x = x;
+   ptl[0].y = thisheight - y - 1;
+   ptl[1].x = x + width - 1;
+   ptl[1].y = thisheight - y - height;
+
+   GpiMove(hps, &ptl[0]);
+   GpiBox(hps, (flags & DW_DRAW_FILL) ? DRO_OUTLINEFILL : DRO_OUTLINE, &ptl[1], 0, 0);
+
+   if(!pixmap)
+      WinReleasePS(hps);
+}
+
+/* VisualAge doesn't seem to have this */
+#ifndef M_PI
+#define M_PI            3.14159265358979323846
+#endif
+
+/* Draw an arc on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       flags: DW_DRAW_FILL (1) to fill the arc or DW_DRAW_DEFAULT (0).
+ *              DW_DRAW_FULL will draw a complete circle/elipse.
+ *       xorigin: X coordinate of center of arc.
+ *       yorigin: Y coordinate of center of arc.
+ *       x1: X coordinate of first segment of arc.
+ *       y1: Y coordinate of first segment of arc.
+ *       x2: X coordinate of second segment of arc.
+ *       y2: Y coordinate of second segment of arc.
+ */
+void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2)
+{
+   HPS hps;
+   int thisheight;
+   ARCPARAMS ap = { 1, 1, 0, 0 };
+   POINTL pts[2];
+   double r, a1, a2, a;
+
+   if(handle)
+   {
+      hps = _set_colors(handle);
+      thisheight = _get_height(handle);
+   }
+   else if(pixmap)
+   {
+      hps = _set_hps(pixmap->hps);
+      thisheight = pixmap->height;
+   }
+   else
+      return;
+
+   /* Handle full circle/ellipse */
+   if(flags & DW_DRAW_FULL)
+   {
+       pts[0].x = xorigin;
+       pts[0].y = thisheight - yorigin - 1;
+       GpiMove(hps, pts);
+       ap.lP = (x2 - x1)/2;
+       ap.lQ = (y2 - y1)/2;
+       /* Setup the arc info on the presentation space */
+       GpiSetArcParams(hps, &ap);
+       GpiFullArc(hps, (flags & DW_DRAW_FILL) ? DRO_OUTLINEFILL : DRO_OUTLINE, MAKEFIXED(1, 1));
+   }
+   else
+   {
+       /* For a filled arc we need to start an area */
+       if(flags & DW_DRAW_FILL)
+           GpiBeginArea(hps, 0L);
+
+       /* Setup the default arc info on the presentation space */
+       GpiSetArcParams(hps, &ap);
+       pts[0].x = x1;
+       pts[0].y = thisheight - y1 - 1;
+       /* Move to the initial position */
+       GpiMove(hps, pts);
+       /* Calculate the midpoint */
+       r = 0.5 * (hypot((double)(y1 - yorigin), (double)(x1 - xorigin)) +
+                  hypot((double)(y2 - yorigin), (double)(x2 - xorigin)));
+       a1 = atan2((double)(y1 - yorigin), (double)(x1 - xorigin));
+       a2 = atan2((double)(y2 - yorigin), (double)(x2 - xorigin));
+       if(a2 < a1)
+           a2 += M_PI * 2;
+       a = (a1 + a2) / 2.;
+       /* Prepare to draw */
+       pts[0].x = (int)(xorigin + r * cos(a));
+       pts[0].y = thisheight - (int)(yorigin + r * sin(a)) - 1;
+       pts[1].x = x2;
+       pts[1].y = thisheight - y2 - 1;
+       /* Actually draw the arc */
+       GpiPointArc(hps, pts);
+       if(flags & DW_DRAW_FILL)
+           GpiEndArea(hps);
+   }
+
+   if(!pixmap)
+      WinReleasePS(hps);
 }
 
 /* Call this after drawing to the screen to make sure
@@ -7742,52 +9228,53 @@
  */
 HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth)
 {
-	BITMAPINFOHEADER bmih;
-	SIZEL sizl = { 0, 0 };
-	HPIXMAP pixmap;
-	HDC hdc;
-	HPS hps;
-	ULONG ulFlags;
+   BITMAPINFOHEADER bmih;
+   SIZEL sizl = { 0, 0 };
+   HPIXMAP pixmap;
+   HDC hdc;
+   HPS hps;
+   ULONG ulFlags;
     LONG cPlanes, cBitCount;
 
-	if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
-		return NULL;
-
-	hps = WinGetPS(handle);
-
-	hdc     = GpiQueryDevice(hps);
-	ulFlags = GpiQueryPS(hps, &sizl);
-
-	pixmap->handle = handle;
-	pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc);
-	pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC);
-
-	DevQueryCaps(hdc, CAPS_COLOR_PLANES  , 1L, &cPlanes);
-	if (!depth)
-	{
-		DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1L, &cBitCount);
-		depth = cBitCount;
-	}
-
-	memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
-	bmih.cbFix     = sizeof(BITMAPINFOHEADER);
-	bmih.cx        = (SHORT)width;
-	bmih.cy        = (SHORT)height;
-	bmih.cPlanes   = (SHORT)cPlanes;
-	bmih.cBitCount = (SHORT)depth;
-
-	pixmap->width = width; pixmap->height = height;
-
-	pixmap->hbm = GpiCreateBitmap(pixmap->hps, (PBITMAPINFOHEADER2)&bmih, 0L, NULL, NULL);
-
-	GpiSetBitmap(pixmap->hps, pixmap->hbm);
-
-	if (depth>8)
-		GpiCreateLogColorTable(pixmap->hps, LCOL_PURECOLOR, LCOLF_RGB, 0, 0, NULL );
-
-	WinReleasePS(hps);
-
-	return pixmap;
+   if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
+      return NULL;
+
+   hps = WinGetPS(handle);
+
+   hdc     = GpiQueryDevice(hps);
+   ulFlags = GpiQueryPS(hps, &sizl);
+
+   pixmap->handle = handle;
+   pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, (PSZ)"*", 0L, NULL, hdc);
+   pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC);
+
+   DevQueryCaps(hdc, CAPS_COLOR_PLANES  , 1L, &cPlanes);
+   if (!depth)
+   {
+      DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1L, &cBitCount);
+      depth = cBitCount;
+   }
+
+   memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
+   bmih.cbFix     = sizeof(BITMAPINFOHEADER);
+   bmih.cx        = (SHORT)width;
+   bmih.cy        = (SHORT)height;
+   bmih.cPlanes   = (SHORT)cPlanes;
+   bmih.cBitCount = (SHORT)depth;
+
+   pixmap->width = width; pixmap->height = height;
+   pixmap->transcolor = DW_CLR_DEFAULT;
+
+   pixmap->hbm = GpiCreateBitmap(pixmap->hps, (PBITMAPINFOHEADER2)&bmih, 0L, NULL, NULL);
+
+   GpiSetBitmap(pixmap->hps, pixmap->hbm);
+
+   if (depth>8)
+      GpiCreateLogColorTable(pixmap->hps, LCOL_PURECOLOR, LCOLF_RGB, 0, 0, NULL );
+
+   WinReleasePS(hps);
+
+   return pixmap;
 }
 
 /*
@@ -7802,37 +9289,107 @@
  */
 HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename)
 {
-	HPIXMAP pixmap;
-	char *file = alloca(strlen(filename) + 5);
-
-	if(!file || !(pixmap = calloc(1,sizeof(struct _hpixmap))))
-		return NULL;
-
-	strcpy(file, filename);
-
-	/* check if we can read from this file (it exists and read permission) */
-	if(access(file, 04) != 0)
-	{
-		/* Try with .bmp extention */
-		strcat(file, ".bmp");
-		if(access(file, 04) != 0)
-		{
-			free(pixmap);
-			return NULL;
-		}
-	}
-
-	/* Try to load the bitmap from file */
-	if(!_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height))
-	{
-		free(pixmap);
-		return NULL;
-	}
-
-	/* Success fill in other values */
-	pixmap->handle = handle;
-
-	return pixmap;
+   HPIXMAP pixmap;
+   char *file = alloca(strlen(filename) + 5);
+
+   if ( !file || !(pixmap = calloc(1,sizeof(struct _hpixmap))) )
+      return NULL;
+
+   strcpy(file, filename);
+
+   /* check if we can read from this file (it exists and read permission) */
+   if ( access(file, 04) != 0 )
+   {
+      /* Try with .bmp extention */
+      strcat(file, ".bmp");
+      if ( access(file, 04) != 0 )
+      {
+         free(pixmap);
+         return NULL;
+      }
+   }
+
+   /* Try to load the bitmap from file */
+   if ( !_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height) )
+   {
+      free(pixmap);
+      return NULL;
+   }
+
+   /* Success fill in other values */
+   pixmap->handle = handle;
+   pixmap->transcolor = DW_CLR_DEFAULT;
+
+   return pixmap;
+}
+
+/*
+ * Creates a pixmap from memory.
+ * Parameters:
+ *       handle: Window handle the pixmap is associated with.
+ *       data: Source of the image data
+ *                 (BMP on OS/2 or Windows, XPM on Unix)
+ *       le: length of data
+ * Returns:
+ *       A handle to a pixmap or NULL on failure.
+ */
+HPIXMAP API dw_pixmap_new_from_data(HWND handle, char *data, int len)
+{
+   HPIXMAP pixmap;
+   char *file;
+   FILE *fp;
+
+   if ( !(pixmap = calloc(1,sizeof(struct _hpixmap))) )
+      return NULL;
+
+   file = tmpnam( NULL );
+   if ( file != NULL )
+   {
+      fp = fopen( file, "wb" );
+      if ( fp != NULL )
+      {
+         fwrite( data, 1, len, fp );
+         fclose( fp );
+         if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
+         {
+            /* Try to load the bitmap from file */
+            if ( !_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height) )
+            {
+               free(pixmap);
+               return NULL;
+            }
+         }
+         else /* otherwise its assumed to be an ico */
+         {
+            /* con't use ICO ? */
+            unlink( file );
+            return NULL;
+         }
+      }
+      else
+      {
+         unlink( file );
+         return NULL;
+      }
+      unlink( file );
+   }
+
+   /* Success fill in other values */
+   pixmap->handle = handle;
+   pixmap->transcolor = DW_CLR_DEFAULT;
+
+   return pixmap;
+}
+
+/*
+ * Creates a bitmap mask for rendering bitmaps with transparent backgrounds
+ */
+void API dw_pixmap_set_transparent_color( HPIXMAP pixmap, ULONG color )
+{
+   if ( pixmap )
+   {
+      pixmap->transcolor = _internal_color(color);
+   }
 }
 
 /*
@@ -7845,35 +9402,59 @@
  */
 HPIXMAP API dw_pixmap_grab(HWND handle, ULONG id)
 {
-	BITMAPINFOHEADER bmih;
-	SIZEL sizl = { 0, 0 };
-	HPIXMAP pixmap;
-	HDC hdc;
-	HPS hps;
-	ULONG ulFlags;
-
-	if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
-		return NULL;
-
-	hps = WinGetPS(handle);
-
-	hdc     = GpiQueryDevice(hps);
-	ulFlags = GpiQueryPS(hps, &sizl);
-
-	pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc);
-	pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC);
-
-	pixmap->hbm = GpiLoadBitmap(pixmap->hps, NULLHANDLE, id, 0, 0);
-
-	GpiQueryBitmapParameters(pixmap->hbm, &bmih);
-
-	GpiSetBitmap(pixmap->hps, pixmap->hbm);
-
-	pixmap->width = bmih.cx; pixmap->height = bmih.cy;
-
-	WinReleasePS(hps);
-
-	return pixmap;
+   BITMAPINFOHEADER bmih;
+   SIZEL sizl = { 0, 0 };
+   HPIXMAP pixmap;
+   HDC hdc;
+   HPS hps;
+   ULONG ulFlags;
+
+   if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
+      return NULL;
+
+   hps = WinGetPS(handle);
+
+   hdc     = GpiQueryDevice(hps);
+   ulFlags = GpiQueryPS(hps, &sizl);
+
+   pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, (PSZ)"*", 0L, NULL, hdc);
+   pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC);
+
+   pixmap->hbm = GpiLoadBitmap(pixmap->hps, NULLHANDLE, id, 0, 0);
+
+   GpiQueryBitmapParameters(pixmap->hbm, &bmih);
+
+   GpiSetBitmap(pixmap->hps, pixmap->hbm);
+
+   pixmap->width = bmih.cx; pixmap->height = bmih.cy;
+   pixmap->transcolor = DW_CLR_DEFAULT;
+
+   WinReleasePS(hps);
+
+   return pixmap;
+}
+
+/*
+ * Sets the font used by a specified pixmap.
+ * Normally the pixmap font is obtained from the associated window handle.
+ * However this can be used to override that, or for pixmaps with no window.
+ * Parameters:
+ *          pixmap: Handle to a pixmap returned by dw_pixmap_new() or
+ *                  passed to the application via a callback.
+ *          fontname: Name and size of the font in the form "size.fontname"
+ * Returns:
+ *       DW_ERROR_NONE on success and DW_ERROR_GENERAL on failure.
+ */
+int API dw_pixmap_set_font(HPIXMAP pixmap, char *fontname)
+{
+    if(pixmap && fontname && *fontname)
+    {
+        if(!pixmap->font)
+            pixmap->font = WinCreateWindow(HWND_OBJECT, WC_FRAME, NULL, 0,0,0,1,1, NULLHANDLE, HWND_TOP,0, NULL, NULL);
+        WinSetPresParam(pixmap->font, PP_FONTNAMESIZE, strlen(fontname)+1, fontname);
+        return DW_ERROR_NONE;
+    }
+    return DW_ERROR_GENERAL;
 }
 
 /*
@@ -7884,12 +9465,14 @@
  */
 void API dw_pixmap_destroy(HPIXMAP pixmap)
 {
-	GpiSetBitmap(pixmap->hps, NULLHANDLE);
-	GpiDeleteBitmap(pixmap->hbm);
-	GpiAssociate(pixmap->hps, NULLHANDLE);
-	GpiDestroyPS(pixmap->hps);
-	DevCloseDC(pixmap->hdc);
-	free(pixmap);
+    if(pixmap->font)
+        WinDestroyWindow(pixmap->font);
+    GpiSetBitmap(pixmap->hps, NULLHANDLE);
+    GpiDeleteBitmap(pixmap->hbm);
+    GpiAssociate(pixmap->hps, NULLHANDLE);
+    GpiDestroyPS(pixmap->hps);
+    DevCloseDC(pixmap->hdc);
+    free(pixmap);
 }
 
 /*
@@ -7908,68 +9491,117 @@
  */
 void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc)
 {
-	HPS hpsdest;
-	HPS hpssrc;
-	POINTL ptl[4];
-    int destheight, srcheight;
-
-	if(dest)
-	{
-		hpsdest = WinGetPS(dest);
-		destheight = _get_height(dest);
-	}
-	else if(destp)
-	{
-		hpsdest = destp->hps;
-		destheight = destp->height;
-	}
-	else
-		return;
-
-	if(src)
-	{
-		hpssrc = WinGetPS(src);
-		srcheight = _get_height(src);
-	}
-	else if(srcp)
-	{
-		hpssrc = srcp->hps;
-		srcheight = srcp->height;
-	}
-	else
-	{
-		if(!destp)
-			WinReleasePS(hpsdest);
-		return;
-	}
-
-	ptl[0].x = xdest;
-	ptl[0].y = (destheight - ydest) - height;
-	ptl[1].x = ptl[0].x + width;
-	ptl[1].y = destheight - ydest;
-	ptl[2].x = xsrc;
-	ptl[2].y = srcheight - (ysrc + height);
-	ptl[3].x = ptl[2].x + width;
-	ptl[3].y = ptl[2].y + height;
-
-	GpiBitBlt(hpsdest, hpssrc, 4, ptl, ROP_SRCCOPY, BBO_IGNORE);
-
-	if(!destp)
-		WinReleasePS(hpsdest);
-	if(!srcp)
-		WinReleasePS(hpssrc);
+    dw_pixmap_stretch_bitblt(dest, destp, xdest, ydest, width, height, src, srcp, xsrc, ysrc, -1, -1);
+}
+
+/*
+ * Copies from one surface to another allowing for stretching.
+ * Parameters:
+ *       dest: Destination window handle.
+ *       destp: Destination pixmap. (choose only one).
+ *       xdest: X coordinate of destination.
+ *       ydest: Y coordinate of destination.
+ *       width: Width of the target area.
+ *       height: Height of the target area.
+ *       src: Source window handle.
+ *       srcp: Source pixmap. (choose only one).
+ *       xsrc: X coordinate of source.
+ *       ysrc: Y coordinate of source.
+ *       srcwidth: Width of area to copy.
+ *       srcheight: Height of area to copy.
+ * Returns:
+ *       DW_ERROR_NONE on success and DW_ERROR_GENERAL on failure.
+ */
+int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight)
+{
+   HPS hpsdest;
+   HPS hpssrc;
+   POINTL ptl[4];
+   int dheight, sheight;
+   int count = 3;
+   
+   /* Do some sanity checks */
+   if((srcheight == -1 || srcwidth == -1) && srcheight != srcwidth)
+      return DW_ERROR_GENERAL;
+
+   if(dest)
+   {
+      hpsdest = WinGetPS(dest);
+      dheight = _get_height(dest);
+   }
+   else if(destp)
+   {
+      hpsdest = destp->hps;
+      dheight = destp->height;
+   }
+   else
+      return DW_ERROR_GENERAL;
+
+   if(src)
+   {
+      hpssrc = WinGetPS(src);
+      sheight = _get_height(src);
+   }
+   else if(srcp)
+   {
+      hpssrc = srcp->hps;
+      sheight = srcp->height;
+   }
+   else
+   {
+      if(!destp)
+         WinReleasePS(hpsdest);
+      return DW_ERROR_GENERAL;
+   }
+
+   ptl[0].x = xdest;
+   ptl[0].y = dheight - (ydest + height);
+   ptl[1].x = xdest + width;
+   ptl[1].y = dheight - ydest;
+   ptl[2].x = xsrc;
+   ptl[2].y = sheight - (ysrc + (srcheight != -1 ? srcheight : height));
+   if(srcwidth != -1 && srcheight != -1)
+   {
+      count = 4;
+      ptl[3].x = xsrc + srcwidth;
+      ptl[3].y = sheight - ysrc;
+   }
+
+   /* Handle transparency if requested */
+   if(srcp && srcp->transcolor != DW_CLR_DEFAULT)
+   {
+       IMAGEBUNDLE newIb, oldIb;
+       /* Transparent color is put into the background color */
+       GpiSetBackColor(hpsdest, srcp->transcolor);
+       GpiQueryAttrs(hpsdest, PRIM_IMAGE, IBB_BACK_MIX_MODE, (PBUNDLE)&oldIb);
+       newIb.usBackMixMode = BM_SRCTRANSPARENT;
+       GpiSetAttrs(hpsdest, PRIM_IMAGE, IBB_BACK_MIX_MODE, 0, (PBUNDLE)&newIb);
+       GpiBitBlt(hpsdest, hpssrc, count, ptl, ROP_SRCCOPY, BBO_IGNORE);
+       GpiSetAttrs(hpsdest, PRIM_IMAGE, IBB_BACK_MIX_MODE, 0, (PBUNDLE)&oldIb);
+   }
+   else
+   {
+       /* Otherwise use the regular BitBlt call */
+       GpiBitBlt(hpsdest, hpssrc, count, ptl, ROP_SRCCOPY, BBO_IGNORE);
+   }
+
+   if(!destp)
+      WinReleasePS(hpsdest);
+   if(!srcp)
+      WinReleasePS(hpssrc);
+   return DW_ERROR_NONE;
 }
 
 /* Run DosBeep() in a separate thread so it doesn't block */
 void _beepthread(void *data)
 {
-	int *info = (int *)data;
-
-	if(data)
-	{
-		DosBeep(info[0], info[1]);
-		free(data);
-	}
+   int *info = (int *)data;
+
+   if(data)
+   {
+      DosBeep(info[0], info[1]);
+      free(data);
+   }
 }
 
 /*
@@ -7980,15 +9612,15 @@
  */
 void API dw_beep(int freq, int dur)
 {
-	int *info = malloc(sizeof(int) * 2);
-
-	if(info)
-	{
-		info[0] = freq;
-		info[1] = dur;
-
-		_beginthread(_beepthread, NULL, 100, (void *)info);
-	}
+   int *info = malloc(sizeof(int) * 2);
+
+   if(info)
+   {
+      info[0] = freq;
+      info[1] = dur;
+
+      _beginthread(_beepthread, NULL, 100, (void *)info);
+   }
 }
 
 /* Open a shared library and return a handle.
@@ -7999,9 +9631,9 @@
  */
 int API dw_module_load(char *name, HMOD *handle)
 {
-	char objnamebuf[300] = "";
-
-	return DosLoadModule(objnamebuf, sizeof(objnamebuf), name, handle);
+   char objnamebuf[300] = "";
+
+   return DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)name, handle);
 }
 
 /* Queries the address of a symbol within open handle.
@@ -8013,7 +9645,7 @@
  */
 int API dw_module_symbol(HMOD handle, char *name, void**func)
 {
-	return DosQueryProcAddr(handle, 0, name, (PFN*)func);
+   return DosQueryProcAddr(handle, 0, (PSZ)name, (PFN*)func);
 }
 
 /* Frees the shared library previously opened.
@@ -8022,8 +9654,8 @@
  */
 int API dw_module_close(HMOD handle)
 {
-	DosFreeModule(handle);
-	return 0;
+   DosFreeModule(handle);
+   return 0;
 }
 
 /*
@@ -8031,10 +9663,10 @@
  */
 HMTX API dw_mutex_new(void)
 {
-	HMTX mutex;
-
-	DosCreateMutexSem(NULL, &mutex, 0, FALSE);
-	return mutex;
+   HMTX mutex;
+
+   DosCreateMutexSem(NULL, &mutex, 0, FALSE);
+   return mutex;
 }
 
 /*
@@ -8044,7 +9676,7 @@
  */
 void API dw_mutex_close(HMTX mutex)
 {
-	DosCloseMutexSem(mutex);
+   DosCloseMutexSem(mutex);
 }
 
 /*
@@ -8056,18 +9688,32 @@
  */
 void API dw_mutex_lock(HMTX mutex)
 {
-	if(_dwtid == dw_thread_id())
-	{
-		int rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN);
-
-		while(rc == ERROR_TIMEOUT)
-		{
-			dw_main_sleep(10);
-			rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN);
-		}
-	}
+   if(_dwtid == dw_thread_id())
+   {
+      int rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN);
+
+      while(rc == ERROR_TIMEOUT)
+      {
+         dw_main_sleep(10);
+         rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN);
+      }
+   }
     else
-		DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT);
+      DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT);
+}
+
+/*
+ * Tries to gain access to the semaphore.
+ * Parameters:
+ *       mutex: The handle to the mutex returned by dw_mutex_new().
+ * Returns:
+ *       DW_ERROR_NONE on success, DW_ERROR_TIMEOUT if it is already locked.
+ */
+int API dw_mutex_trylock(HMTX mutex)
+{
+    if(DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR)
+        return DW_ERROR_NONE;
+    return DW_ERROR_TIMEOUT;
 }
 
 /*
@@ -8077,7 +9723,7 @@
  */
 void API dw_mutex_unlock(HMTX mutex)
 {
-	DosReleaseMutexSem(mutex);
+   DosReleaseMutexSem(mutex);
 }
 
 /*
@@ -8085,12 +9731,12 @@
  */
 HEV API dw_event_new(void)
 {
-	HEV blah;
-
-	if(DosCreateEventSem (NULL, &blah, 0L, FALSE))
-		return 0;
-
-	return blah;
+   HEV blah;
+
+   if(DosCreateEventSem (NULL, &blah, 0L, FALSE))
+      return 0;
+
+   return blah;
 }
 
 /*
@@ -8100,11 +9746,11 @@
  */
 int API dw_event_reset(HEV eve)
 {
-	ULONG count;
-
-	if(DosResetEventSem(eve, &count))
-		return FALSE;
-	return TRUE;
+   ULONG count;
+
+   if(DosResetEventSem(eve, &count))
+      return DW_ERROR_GENERAL;
+   return DW_ERROR_NONE;
 }
 
 /*
@@ -8115,9 +9761,9 @@
  */
 int API dw_event_post(HEV eve)
 {
-	if(DosPostEventSem(eve))
-		return FALSE;
-	return TRUE;
+   if(DosPostEventSem(eve))
+      return DW_ERROR_GENERAL;
+   return DW_ERROR_NONE;
 }
 
 
@@ -8129,12 +9775,12 @@
  */
 int API dw_event_wait(HEV eve, unsigned long timeout)
 {
-	int rc = DosWaitEventSem(eve, timeout);
-	if(!rc)
-		return 1;
-	if(rc == ERROR_TIMEOUT)
-		return -1;
-	return 0;
+   int rc = DosWaitEventSem(eve, timeout);
+   if(!rc)
+      return DW_ERROR_NONE;
+   if(rc == ERROR_TIMEOUT)
+      return DW_ERROR_TIMEOUT;
+   return DW_ERROR_GENERAL;
 }
 
 /*
@@ -8144,9 +9790,9 @@
  */
 int API dw_event_close(HEV *eve)
 {
-	if(!eve || ~DosCloseEventSem(*eve))
-		return FALSE;
-	return TRUE;
+   if(!eve || ~DosCloseEventSem(*eve))
+      return DW_ERROR_GENERAL;
+   return DW_ERROR_NONE;
 }
 
 /* Create a named event semaphore which can be
@@ -8158,19 +9804,19 @@
  */
 HEV API dw_named_event_new(char *name)
 {
-	char *semname = malloc(strlen(name)+8);
-	HEV ev = 0;
-
-	if(!semname)
-		return 0;
-
-	strcpy(semname, "\\sem32\\");
-	strcat(semname, name);
-
-	DosCreateEventSem(semname, &ev, 0L, FALSE);
-
-	free(semname);
-	return ev;
+   char *semname = malloc(strlen(name)+8);
+   HEV ev = 0;
+
+   if(!semname)
+      return 0;
+
+   strcpy(semname, "\\sem32\\");
+   strcat(semname, name);
+
+   DosCreateEventSem((PSZ)semname, &ev, 0L, FALSE);
+
+   free(semname);
+   return ev;
 }
 
 /* Open an already existing named event semaphore.
@@ -8181,19 +9827,19 @@
  */
 HEV API dw_named_event_get(char *name)
 {
-	char *semname = malloc(strlen(name)+8);
-	HEV ev;
-
-	if(!semname)
-		return 0;
-
-	strcpy(semname, "\\sem32\\");
-	strcat(semname, name);
-
-	DosOpenEventSem(semname, &ev);
-
-	free(semname);
-	return ev;
+   char *semname = malloc(strlen(name)+8);
+   HEV ev;
+
+   if(!semname)
+      return 0;
+
+   strcpy(semname, "\\sem32\\");
+   strcat(semname, name);
+
+   DosOpenEventSem((PSZ)semname, &ev);
+
+   free(semname);
+   return ev;
 }
 
 /* Resets the event semaphore so threads who call wait
@@ -8204,9 +9850,9 @@
  */
 int API dw_named_event_reset(HEV eve)
 {
-	ULONG count;
-
-	return DosResetEventSem(eve, &count);
+   ULONG count;
+
+   return DosResetEventSem(eve, &count);
 }
 
 /* Sets the posted state of an event semaphore, any threads
@@ -8217,7 +9863,7 @@
  */
 int API dw_named_event_post(HEV eve)
 {
-	return DosPostEventSem(eve);
+   return DosPostEventSem(eve);
 }
 
 
@@ -8231,26 +9877,26 @@
  */
 int API dw_named_event_wait(HEV eve, unsigned long timeout)
 {
-	int rc;
-
-	rc = DosWaitEventSem(eve, timeout);
-	switch (rc)
-	{
-	case ERROR_INVALID_HANDLE:
-		rc = DW_ERROR_NON_INIT;
-		break;
-	case ERROR_NOT_ENOUGH_MEMORY:
-		rc = DW_ERROR_NO_MEM;
-		break;
-	case ERROR_INTERRUPT:
-		rc = DW_ERROR_INTERRUPT;
-		break;
-	case ERROR_TIMEOUT:
-		rc = DW_ERROR_TIMEOUT;
-		break;
-	}
-
-	return rc;
+   int rc;
+
+   rc = DosWaitEventSem(eve, timeout);
+   switch (rc)
+   {
+   case ERROR_INVALID_HANDLE:
+      rc = DW_ERROR_NON_INIT;
+      break;
+   case ERROR_NOT_ENOUGH_MEMORY:
+      rc = DW_ERROR_NO_MEM;
+      break;
+   case ERROR_INTERRUPT:
+      rc = DW_ERROR_INTERRUPT;
+      break;
+   case ERROR_TIMEOUT:
+      rc = DW_ERROR_TIMEOUT;
+      break;
+   }
+
+   return rc;
 }
 
 /* Release this semaphore, if there are no more open
@@ -8261,21 +9907,21 @@
  */
 int API dw_named_event_close(HEV eve)
 {
-	int rc;
-
-	rc = DosCloseEventSem(eve);
-	switch (rc)
-	{
-	case ERROR_INVALID_HANDLE:
-		rc = DW_ERROR_NON_INIT;
-		break;
-
-	case ERROR_SEM_BUSY:
-		rc = DW_ERROR_INTERRUPT;
-		break;
-	}
-
-	return rc;
+   int rc;
+
+   rc = DosCloseEventSem(eve);
+   switch (rc)
+   {
+   case ERROR_INVALID_HANDLE:
+      rc = DW_ERROR_NON_INIT;
+      break;
+
+   case ERROR_SEM_BUSY:
+      rc = DW_ERROR_INTERRUPT;
+      break;
+   }
+
+   return rc;
 }
 
 /*
@@ -8288,14 +9934,14 @@
  */
 HSHM API dw_named_memory_new(void **dest, int size, char *name)
 {
-	char namebuf[1024];
-
-	sprintf(namebuf, "\\sharemem\\%s", name);
-
-	if(DosAllocSharedMem((void *)dest, namebuf, size, PAG_COMMIT | PAG_WRITE | PAG_READ) != NO_ERROR)
-		return 0;
-
-	return 1;
+   char namebuf[1024];
+
+   sprintf(namebuf, "\\sharemem\\%s", name);
+
+   if(DosAllocSharedMem((void *)dest, (PSZ)namebuf, size, PAG_COMMIT | PAG_WRITE | PAG_READ) != NO_ERROR)
+      return 0;
+
+   return 1;
 }
 
 /*
@@ -8307,15 +9953,15 @@
  */
 HSHM API dw_named_memory_get(void **dest, int size, char *name)
 {
-	char namebuf[1024];
-
-	size = size;
-	sprintf(namebuf, "\\sharemem\\%s", name);
-
-	if(DosGetNamedSharedMem((void *)dest, namebuf, PAG_READ | PAG_WRITE) != NO_ERROR)
-		return 0;
-
-	return 1;
+   char namebuf[1024];
+
+   size = size;
+   sprintf(namebuf, "\\sharemem\\%s", name);
+
+   if(DosGetNamedSharedMem((void *)dest, (PSZ)namebuf, PAG_READ | PAG_WRITE) != NO_ERROR)
+      return 0;
+
+   return 1;
 }
 
 /*
@@ -8326,11 +9972,11 @@
  */
 int API dw_named_memory_free(HSHM handle, void *ptr)
 {
-	handle = handle;
-
-	if(DosFreeMem(ptr) != NO_ERROR)
-		return -1;
-	return 0;
+   handle = handle;
+
+   if(DosFreeMem(ptr) != NO_ERROR)
+      return -1;
+   return 0;
 }
 
 /*
@@ -8338,18 +9984,18 @@
  */
 void _dwthreadstart(void *data)
 {
-	HAB thishab = WinInitialize(0);
-	HMQ thishmq = WinCreateMsgQueue(dwhab, 0);
-	void (* API threadfunc)(void *) = NULL;
-	void **tmp = (void **)data;
-
-	threadfunc = (void (*)(void *))tmp[0];
-	threadfunc(tmp[1]);
-
-	free(tmp);
-
-	WinDestroyMsgQueue(thishmq);
-	WinTerminate(thishab);
+   HAB thishab = WinInitialize(0);
+   HMQ thishmq = WinCreateMsgQueue(dwhab, 0);
+   void (* API threadfunc)(void *) = NULL;
+   void **tmp = (void **)data;
+
+   threadfunc = (void (* API)(void *))tmp[0];
+   threadfunc(tmp[1]);
+
+   free(tmp);
+
+   WinDestroyMsgQueue(thishmq);
+   WinTerminate(thishab);
 }
 
 /*
@@ -8361,12 +10007,12 @@
  */
 DWTID API dw_thread_new(void *func, void *data, int stack)
 {
-	void **tmp = malloc(sizeof(void *) * 2);
-
-	tmp[0] = func;
-	tmp[1] = data;
-
-	return (DWTID)_beginthread((void (*)(void *))_dwthreadstart, NULL, stack, (void *)tmp);
+   void **tmp = malloc(sizeof(void *) * 2);
+
+   tmp[0] = func;
+   tmp[1] = data;
+
+   return (DWTID)_beginthread((void (*)(void *))_dwthreadstart, NULL, stack, (void *)tmp);
 }
 
 /*
@@ -8374,7 +10020,7 @@
  */
 void API dw_thread_end(void)
 {
-	_endthread();
+   _endthread();
 }
 
 /*
@@ -8382,7 +10028,7 @@
  */
 DWTID API dw_thread_id(void)
 {
-	return (DWTID)_threadid;
+   return (DWTID)_threadid;
 }
 
 /*
@@ -8392,17 +10038,17 @@
  */
 void API dw_exit(int exitcode)
 {
-	/* Destroy the menu message window */
-	dw_window_destroy(hwndApp);
-
-	/* In case we are in a signal handler, don't
-	 * try to free memory that could possibly be
-	 * free()'d by the runtime already.
-	 */
-	Root = NULL;
-
-	DosFreeModule(wpconfig);
-	exit(exitcode);
+   /* Destroy the menu message window */
+   dw_window_destroy(hwndApp);
+
+   /* In case we are in a signal handler, don't
+    * try to free memory that could possibly be
+    * free()'d by the runtime already.
+    */
+   Root = NULL;
+
+   DosFreeModule(wpconfig);
+   exit(exitcode);
 }
 
 /*
@@ -8416,34 +10062,34 @@
  */
 HWND API dw_splitbar_new(int type, HWND topleft, HWND bottomright, unsigned long id)
 {
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   SplitbarClassName,
-							   NULL,
-							   WS_VISIBLE | WS_CLIPCHILDREN,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	if(tmp)
-	{
-		HWND tmpbox = dw_box_new(DW_VERT, 0);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        (PSZ)SplitbarClassName,
+                        NULL,
+                        WS_VISIBLE | WS_CLIPCHILDREN,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   if(tmp)
+   {
+      HWND tmpbox = dw_box_new(DW_VERT, 0);
         float *percent = malloc(sizeof(float));
 
-		dw_box_pack_start(tmpbox, topleft, 1, 1, TRUE, TRUE, 0);
-		WinSetParent(tmpbox, tmp, FALSE);
-		dw_window_set_data(tmp, "_dw_topleft", (void *)tmpbox);
-
-		tmpbox = dw_box_new(DW_VERT, 0);
-		dw_box_pack_start(tmpbox, bottomright, 1, 1, TRUE, TRUE, 0);
-		WinSetParent(tmpbox, tmp, FALSE);
-		*percent = 50.0;
-		dw_window_set_data(tmp, "_dw_bottomright", (void *)tmpbox);
-		dw_window_set_data(tmp, "_dw_percent", (void *)percent);
-		dw_window_set_data(tmp, "_dw_type", (void *)type);
-	}
-	return tmp;
+      dw_box_pack_start(tmpbox, topleft, 1, 1, TRUE, TRUE, 0);
+      WinSetParent(tmpbox, tmp, FALSE);
+      dw_window_set_data(tmp, "_dw_topleft", (void *)tmpbox);
+
+      tmpbox = dw_box_new(DW_VERT, 0);
+      dw_box_pack_start(tmpbox, bottomright, 1, 1, TRUE, TRUE, 0);
+      WinSetParent(tmpbox, tmp, FALSE);
+      *percent = 50.0;
+      dw_window_set_data(tmp, "_dw_bottomright", (void *)tmpbox);
+      dw_window_set_data(tmp, "_dw_percent", (void *)percent);
+      dw_window_set_data(tmp, "_dw_type", (void *)type);
+   }
+   return tmp;
 }
 
 /*
@@ -8453,16 +10099,16 @@
  */
 void API dw_splitbar_set(HWND handle, float percent)
 {
-	float *mypercent = (float *)dw_window_get_data(handle, "_dw_percent");
-	int type = (int)dw_window_get_data(handle, "_dw_type");
+   float *mypercent = (float *)dw_window_get_data(handle, "_dw_percent");
+   int type = (int)dw_window_get_data(handle, "_dw_type");
     unsigned long width, height;
 
-	if(mypercent)
-		*mypercent = percent;
-
-	dw_window_get_pos_size(handle, NULL, NULL, &width, &height);
-
-	_handle_splitbar_resize(handle, percent, type, width, height);
+   if(mypercent)
+      *mypercent = percent;
+
+   dw_window_get_pos_size(handle, NULL, NULL, &width, &height);
+
+   _handle_splitbar_resize(handle, percent, type, width, height);
 }
 
 /*
@@ -8472,197 +10118,97 @@
  */
 float API dw_splitbar_get(HWND handle)
 {
-	float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
-
-	if(percent)
-		return *percent;
-	return 0.0;
-}
-
-/*
- * Pack windows (widgets) into a box from the start (or top).
- * Parameters:
- *       box: Window handle of the box to be packed into.
- *       item: Window handle of the item to be back.
- *       width: Width in pixels of the item or -1 to be self determined.
- *       height: Height in pixels of the item or -1 to be self determined.
- *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
- *       vsize: TRUE if the window (widget) should expand vertically to fill space given.
- *       pad: Number of pixels of padding around the item.
- */
-void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
-{
-	char *funcname = "dw_box_pack_start()";
-
-	/*
-	 * If you try and pack an item into itself VERY bad things can happen; like at least an
-	 * infinite loop on GTK! Lets be safe!
-	 */
-	if(box == item)
-	{
-		dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!");
-		return;
-	}
-
-	if(WinWindowFromID(box, FID_CLIENT))
-	{
-		box = WinWindowFromID(box, FID_CLIENT);
-		hsize = TRUE;
-		vsize = TRUE;
-	}
-	_dw_box_pack_start(box, item, width, height, hsize, vsize, pad, funcname);
-}
-
-void _dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname)
-{
-	Box *thisbox = WinQueryWindowPtr(box, QWP_USER);
-
-	if(thisbox)
-	{
-		int z;
-		Item *tmpitem, *thisitem = thisbox->items;
-		char tmpbuf[100];
-		HWND frame = (HWND)dw_window_get_data(item, "_dw_combo_box");
-
-		tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
-
-		for(z=0;z<thisbox->count;z++)
-		{
-			tmpitem[z] = thisitem[z];
-		}
-
-		WinQueryClassName(item, 99, tmpbuf);
-
-		if(vsize && !height)
-			height = 1;
-		if(hsize && !width)
-			width = 1;
-
-		if(strncmp(tmpbuf, "#1", 3)==0)
-			tmpitem[thisbox->count].type = TYPEBOX;
-		else
-		{
-			if ( width == 0 && hsize == FALSE )
-				dw_messagebox(functionname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item);
-			if ( height == 0 && vsize == FALSE )
-				dw_messagebox(functionname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item);
-
-			tmpitem[thisbox->count].type = TYPEITEM;
-		}
-
-		tmpitem[thisbox->count].hwnd = item;
-		tmpitem[thisbox->count].origwidth = tmpitem[thisbox->count].width = width;
-		tmpitem[thisbox->count].origheight = tmpitem[thisbox->count].height = height;
-		tmpitem[thisbox->count].pad = pad;
-		if(hsize)
-			tmpitem[thisbox->count].hsize = SIZEEXPAND;
-		else
-			tmpitem[thisbox->count].hsize = SIZESTATIC;
-
-		if(vsize)
-			tmpitem[thisbox->count].vsize = SIZEEXPAND;
-		else
-			tmpitem[thisbox->count].vsize = SIZESTATIC;
-
-		thisbox->items = tmpitem;
-
-		if(thisbox->count)
-			free(thisitem);
-
-		thisbox->count++;
-
-        /* Don't set the ownership if it's an entryfield  or spinbutton */
-		WinQueryClassName(item, 99, tmpbuf);
-		if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0 && strncmp(tmpbuf, "#2", 3)!=0)
-			WinSetOwner(item, box);
-		WinSetParent(frame ? frame : item, box, FALSE);
-	}
+   float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
+
+   if(percent)
+      return *percent;
+   return 0.0;
 }
 
 /* The following two functions graciously contributed by Peter Nielsen. */
 static ULONG _ParseBuildLevel (char* pchBuffer, ULONG ulSize) {
-	char* pchStart = pchBuffer;
-	char* pchEnd = pchStart + ulSize - 2;
-
-	while (pchEnd >= pchStart)
-	{
-		if ((pchEnd[0] == '#') && (pchEnd[1] == '@'))
-		{
-			*pchEnd-- = '\0';
-			while (pchEnd >= pchStart)
-			{
-				if ((pchEnd[0] == '@') && (pchEnd[1] == '#'))
-				{
-					ULONG ulMajor = 0;
-					ULONG ulMinor = 0;
-
-					char* pch = pchEnd + 2;
-					while (!isdigit ((int)*pch) && *pch)
-						pch++;
-
-					while (isdigit ((int)*pch))
-						ulMajor = ulMajor * 10 + *pch++ - '0';
-
-					if (*pch == '.')
-					{
-						while (isdigit ((int)*++pch))
-							ulMinor = ulMinor * 10 + *pch - '0';
-					}
-					return ((ulMajor << 16) | ulMinor);
-				}
-				pchEnd--;
-			}
-		}
-		pchEnd--;
-	}
-	return (0);
+   char* pchStart = pchBuffer;
+   char* pchEnd = pchStart + ulSize - 2;
+
+   while (pchEnd >= pchStart)
+   {
+      if ((pchEnd[0] == '#') && (pchEnd[1] == '@'))
+      {
+         *pchEnd-- = '\0';
+         while (pchEnd >= pchStart)
+         {
+            if ((pchEnd[0] == '@') && (pchEnd[1] == '#'))
+            {
+               ULONG ulMajor = 0;
+               ULONG ulMinor = 0;
+
+               char* pch = pchEnd + 2;
+               while (!isdigit ((int)*pch) && *pch)
+                  pch++;
+
+               while (isdigit ((int)*pch))
+                  ulMajor = ulMajor * 10 + *pch++ - '0';
+
+               if (*pch == '.')
+               {
+                  while (isdigit ((int)*++pch))
+                     ulMinor = ulMinor * 10 + *pch - '0';
+               }
+               return ((ulMajor << 16) | ulMinor);
+            }
+            pchEnd--;
+         }
+      }
+      pchEnd--;
+   }
+   return (0);
 }
 
 ULONG _GetSystemBuildLevel(void) {
-	/* The build level info is normally available in the end of the OS2KRNL file. However, this is not the case in some beta versions of OS/2.
-	 * We first try to find the info in the 256 last bytes of the file. If that fails, we load the entire file and search it completely.
-	 */
-	ULONG ulBootDrive = 0;
-	ULONG ulBuild = 0;
-	if (DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulBootDrive, sizeof (ulBootDrive)) == NO_ERROR)
-	{
-		char achFileName[11] = "C:\\OS2KRNL";
-		HFILE hfile;
-		ULONG ulResult;
+   /* The build level info is normally available in the end of the OS2KRNL file. However, this is not the case in some beta versions of OS/2.
+    * We first try to find the info in the 256 last bytes of the file. If that fails, we load the entire file and search it completely.
+    */
+   ULONG ulBootDrive = 0;
+   ULONG ulBuild = 0;
+   if (DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulBootDrive, sizeof (ulBootDrive)) == NO_ERROR)
+   {
+      char achFileName[11] = "C:\\OS2KRNL";
+      HFILE hfile;
+      ULONG ulResult;
 
         achFileName[0] = (char)('A'+ulBootDrive-1);
 
-		if (DosOpen (achFileName, &hfile, &ulResult, 0, 0, OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL) == NO_ERROR)
-		{
-			ULONG ulFileSize = 0;
-			if (DosSetFilePtr (hfile, 0, FILE_END, &ulFileSize) == NO_ERROR)
-			{
-				const ULONG ulFirstTry = min (256, ulFileSize);
-				if (DosSetFilePtr (hfile, -(LONG)ulFirstTry, FILE_END, &ulResult) == NO_ERROR)
-				{
-					char *pchBuffer = malloc(ulFirstTry);
-					if (DosRead (hfile, pchBuffer, ulFirstTry, &ulResult) == NO_ERROR)
-					{
-						ulBuild = _ParseBuildLevel (pchBuffer, ulFirstTry);
-						if (ulBuild == 0)
-						{
-							if (DosSetFilePtr (hfile, 0, FILE_BEGIN, &ulResult) == NO_ERROR)
-							{
-								free(pchBuffer);
-								pchBuffer = malloc(ulFileSize);
-
-								if (DosRead (hfile, pchBuffer, ulFileSize, &ulResult) == NO_ERROR)
-									ulBuild = _ParseBuildLevel (pchBuffer, ulFileSize);
-							}
-						}
-					}
-					free(pchBuffer);
-				}
-			}
-			DosClose (hfile);
-		}
-	}
-	return (ulBuild);
+      if (DosOpen ((PSZ)achFileName, &hfile, &ulResult, 0, 0, OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL) == NO_ERROR)
+      {
+         ULONG ulFileSize = 0;
+         if (DosSetFilePtr (hfile, 0, FILE_END, &ulFileSize) == NO_ERROR)
+         {
+            const ULONG ulFirstTry = min (256, ulFileSize);
+            if (DosSetFilePtr (hfile, -(LONG)ulFirstTry, FILE_END, &ulResult) == NO_ERROR)
+            {
+               char *pchBuffer = malloc(ulFirstTry);
+               if (DosRead (hfile, pchBuffer, ulFirstTry, &ulResult) == NO_ERROR)
+               {
+                  ulBuild = _ParseBuildLevel (pchBuffer, ulFirstTry);
+                  if (ulBuild == 0)
+                  {
+                     if (DosSetFilePtr (hfile, 0, FILE_BEGIN, &ulResult) == NO_ERROR)
+                     {
+                        free(pchBuffer);
+                        pchBuffer = malloc(ulFileSize);
+
+                        if (DosRead (hfile, pchBuffer, ulFileSize, &ulResult) == NO_ERROR)
+                           ulBuild = _ParseBuildLevel (pchBuffer, ulFileSize);
+                     }
+                  }
+               }
+               free(pchBuffer);
+            }
+         }
+         DosClose (hfile);
+      }
+   }
+   return (ulBuild);
 }
 
 /*
@@ -8673,15 +10219,15 @@
  */
 void API dw_window_default(HWND window, HWND defaultitem)
 {
-	Box *thisbox = NULL;
-	HWND box;
-
-	box = WinWindowFromID(window, FID_CLIENT);
-	if(box)
-		thisbox = WinQueryWindowPtr(box, QWP_USER);
-
-	if(thisbox)
-		thisbox->defaultitem = defaultitem;
+   Box *thisbox = NULL;
+   HWND box;
+
+   box = WinWindowFromID(window, FID_CLIENT);
+   if(box)
+      thisbox = WinQueryWindowPtr(box, QWP_USER);
+
+   if(thisbox)
+      thisbox->defaultitem = defaultitem;
 }
 
 /*
@@ -8692,10 +10238,65 @@
  */
 void API dw_window_click_default(HWND window, HWND next)
 {
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER);
-
-	if(blah)
-		blah->clickdefault = next;
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER);
+
+   if(blah)
+      blah->clickdefault = next;
+}
+
+/*
+ * Gets the contents of the default clipboard as text.
+ * Parameters:
+ *       None.
+ * Returns:
+ *       Pointer to an allocated string of text or NULL if clipboard empty or contents could not
+ *       be converted to text.
+ */
+char *dw_clipboard_get_text()
+{
+    APIRET rc;
+    char *retbuf = NULL;
+    ULONG fmtInfo;
+
+    WinOpenClipbrd(dwhab);
+
+    rc = WinQueryClipbrdFmtInfo(dwhab, CF_TEXT, &fmtInfo);
+    if (rc) /* Text data in clipboard */
+    {
+        PSZ pszClipText = (PSZ)WinQueryClipbrdData(dwhab, CF_TEXT); /* Query data handle */
+        retbuf = strdup((char *)pszClipText);
+    }
+    WinCloseClipbrd(dwhab);
+    return retbuf;
+}
+
+/*
+ * Sets the contents of the default clipboard to the supplied text.
+ * Parameters:
+ *       Text.
+ */
+void dw_clipboard_set_text( char *str, int len )
+{
+    APIRET rc;
+    static PVOID shared;
+
+    WinOpenClipbrd(dwhab); /* Open clipboard */
+    WinEmptyClipbrd(dwhab); /* Empty clipboard */
+
+    /* Ok, clipboard wants giveable unnamed shared memory */
+
+    shared = NULL;
+    rc = DosAllocSharedMem(&shared, NULL, len, OBJ_GIVEABLE | PAG_COMMIT | PAG_READ | PAG_WRITE);
+
+    if (rc == 0)
+    {
+        memcpy(shared, str, len);
+
+        WinSetClipbrdData(dwhab, (ULONG)shared, CF_TEXT, CFI_POINTER);
+    }
+
+    WinCloseClipbrd(dwhab); /* Close clipboard */
+    return;
 }
 
 /*
@@ -8705,198 +10306,202 @@
  */
 void API dw_environment_query(DWEnv *env)
 {
-	ULONG Build;
-
-	if(!env)
-		return;
-
-	/* The default is OS/2 2.0 */
-	strcpy(env->osName,"OS/2");
-	env->MajorVersion = 2;
-	env->MinorVersion = 0;
-
-	Build = _GetSystemBuildLevel();
-	env->MinorBuild =  Build & 0xFFFF;
-	env->MajorBuild =  Build >> 16;
-
-	if (aulBuffer[0] == 20)
-	{
-		int i = (unsigned int)aulBuffer[1];
-		if (i > 20)
-		{
-			strcpy(env->osName,"Warp");
-			env->MajorVersion = (int)i/10;
-			env->MinorVersion = i-(((int)i/10)*10);
-		}
-		else if (i == 10)
-			env->MinorVersion = 1;
-	}
-	strcpy(env->buildDate, __DATE__);
-	strcpy(env->buildTime, __TIME__);
-	env->DWMajorVersion = DW_MAJOR_VERSION;
-	env->DWMinorVersion = DW_MINOR_VERSION;
-	env->DWSubVersion = DW_SUB_VERSION;
+   ULONG Build;
+
+   if(!env)
+      return;
+
+   /* The default is OS/2 2.0 */
+   strcpy(env->osName,"OS/2");
+   env->MajorVersion = 2;
+   env->MinorVersion = 0;
+
+   Build = _GetSystemBuildLevel();
+   env->MinorBuild =  Build & 0xFFFF;
+   env->MajorBuild =  Build >> 16;
+
+   if (aulBuffer[0] == 20)
+   {
+      int i = (unsigned int)aulBuffer[1];
+      if (i > 20)
+      {
+         strcpy(env->osName,"Warp");
+         env->MajorVersion = (int)i/10;
+         env->MinorVersion = i-(((int)i/10)*10);
+      }
+      else if (i == 10)
+         env->MinorVersion = 1;
+   }
+   strcpy(env->buildDate, __DATE__);
+   strcpy(env->buildTime, __TIME__);
+   env->DWMajorVersion = DW_MAJOR_VERSION;
+   env->DWMinorVersion = DW_MINOR_VERSION;
+#ifdef VER_REV
+   env->DWSubVersion = VER_REV;
+#else
+   env->DWSubVersion = DW_SUB_VERSION;
+#endif
 }
 
 /* The next few functions are support functions for the OS/2 folder browser */
 void _populate_directory(HWND tree, HTREEITEM parent, char *path)
 {
-	FILEFINDBUF3 ffbuf;
-	HTREEITEM item;
-	ULONG count = 1;
-	HDIR hdir = HDIR_CREATE;
-
-	if(DosFindFirst(path, &hdir, FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_ARCHIVED | MUST_HAVE_DIRECTORY,
-					&ffbuf, sizeof(FILEFINDBUF3), &count, FIL_STANDARD) == NO_ERROR)
-	{
-		while(DosFindNext(hdir, &ffbuf, sizeof(FILEFINDBUF3), &count) == NO_ERROR)
-		{
-			if(strcmp(ffbuf.achName, ".") && strcmp(ffbuf.achName, ".."))
-			{
-				int len = strlen(path);
-				char *folder = malloc(len + ffbuf.cchName + 2);
-				HTREEITEM tempitem;
-
-				strcpy(folder, path);
-				strcpy(&folder[len-1], ffbuf.achName);
-
-				item = dw_tree_insert(tree, ffbuf.achName, WinLoadFileIcon(folder, TRUE), parent, (void *)parent);
-				tempitem = dw_tree_insert(tree, "", 0, item, 0);
-				dw_tree_item_set_data(tree, item, (void *)tempitem);
-			}
-		}
-		DosFindClose(hdir);
-	}
-}
-
-void _populate_tree_thread(void *data)
-{
-	HWND window = (HWND)data, tree = (HWND)dw_window_get_data(window, "_dw_tree");
-	HMTX mtx = (HMTX)dw_window_get_data(window, "_dw_mutex");
-	int drive;
-	HTREEITEM items[26];
-	FSINFO  volinfo;
-
-	DosError(FERR_DISABLEHARDERR);
-
-	dw_mutex_lock(mtx);
-	for(drive=0;drive<26;drive++)
-	{
-		if(DosQueryFSInfo(drive+1, FSIL_VOLSER,(PVOID)&volinfo, sizeof(FSINFO)) == NO_ERROR)
-		{
-			char folder[5] = "C:\\", name[9] = "Drive C:";
-			HTREEITEM tempitem;
-
-			folder[0] = name[6] = 'A' + drive;
-
-			items[drive] = dw_tree_insert(tree, name, WinLoadFileIcon(folder, TRUE), NULL, 0);
-			tempitem = dw_tree_insert(tree, "", 0, items[drive], 0);
-			dw_tree_item_set_data(tree, items[drive], (void *)tempitem);
-		}
-		else
-			items[drive] = 0;
-	}
-	dw_mutex_unlock(mtx);
-
-	DosError(FERR_ENABLEHARDERR);
+   FILEFINDBUF3 ffbuf;
+   HTREEITEM item;
+   ULONG count = 1;
+   HDIR hdir = HDIR_CREATE;
+
+   if(DosFindFirst((PSZ)path, &hdir, FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_ARCHIVED | MUST_HAVE_DIRECTORY,
+               &ffbuf, sizeof(FILEFINDBUF3), &count, FIL_STANDARD) == NO_ERROR)
+   {
+      while(DosFindNext(hdir, &ffbuf, sizeof(FILEFINDBUF3), &count) == NO_ERROR)
+      {
+         if(strcmp(ffbuf.achName, ".") && strcmp(ffbuf.achName, ".."))
+         {
+            int len = strlen(path);
+            char *folder = malloc(len + ffbuf.cchName + 2);
+            HTREEITEM tempitem;
+
+            strcpy(folder, path);
+            strcpy(&folder[len-1], ffbuf.achName);
+
+            item = dw_tree_insert(tree, ffbuf.achName, WinLoadFileIcon((PSZ)folder, TRUE), parent, (void *)parent);
+            tempitem = dw_tree_insert(tree, "", 0, item, 0);
+            dw_tree_item_set_data(tree, item, (void *)tempitem);
+         }
+      }
+      DosFindClose(hdir);
+   }
+}
+
+void API _populate_tree_thread(void *data)
+{
+   HWND window = (HWND)data, tree = (HWND)dw_window_get_data(window, "_dw_tree");
+   HMTX mtx = (HMTX)dw_window_get_data(window, "_dw_mutex");
+   int drive;
+   HTREEITEM items[26];
+   FSINFO  volinfo;
+
+   DosError(FERR_DISABLEHARDERR);
+
+   dw_mutex_lock(mtx);
+   for(drive=0;drive<26;drive++)
+   {
+      if(DosQueryFSInfo(drive+1, FSIL_VOLSER,(PVOID)&volinfo, sizeof(FSINFO)) == NO_ERROR)
+      {
+         char folder[5] = "C:\\", name[9] = "Drive C:";
+         HTREEITEM tempitem;
+
+         folder[0] = name[6] = 'A' + drive;
+
+         items[drive] = dw_tree_insert(tree, name, WinLoadFileIcon((PSZ)folder, TRUE), NULL, 0);
+         tempitem = dw_tree_insert(tree, "", 0, items[drive], 0);
+         dw_tree_item_set_data(tree, items[drive], (void *)tempitem);
+      }
+      else
+         items[drive] = 0;
+   }
+   dw_mutex_unlock(mtx);
+
+   DosError(FERR_ENABLEHARDERR);
 }
 
 int DWSIGNAL _dw_ok_func(HWND window, void *data)
 {
-	DWDialog *dwwait = (DWDialog *)data;
-	HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
-	void *treedata;
-
-	window = window;
-	if(!dwwait)
-		return FALSE;
-
-	dw_mutex_lock(mtx);
-	treedata = dw_window_get_data((HWND)dwwait->data, "_dw_tree_selected");
-	dw_mutex_close(mtx);
-	dw_window_destroy((HWND)dwwait->data);
-	dw_dialog_dismiss((DWDialog *)data, treedata);
-	return FALSE;
+   DWDialog *dwwait = (DWDialog *)data;
+   HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
+   void *treedata;
+
+   window = window;
+   if(!dwwait)
+      return FALSE;
+
+   dw_mutex_lock(mtx);
+   treedata = dw_window_get_data((HWND)dwwait->data, "_dw_tree_selected");
+   dw_mutex_close(mtx);
+   dw_window_destroy((HWND)dwwait->data);
+   dw_dialog_dismiss((DWDialog *)data, treedata);
+   return FALSE;
 }
 
 int DWSIGNAL _dw_cancel_func(HWND window, void *data)
 {
-	DWDialog *dwwait = (DWDialog *)data;
-	HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
-
-	window = window;
-	if(!dwwait)
-		return FALSE;
-
-	dw_mutex_lock(mtx);
-	dw_mutex_close(mtx);
-	dw_window_destroy((HWND)dwwait->data);
-	dw_dialog_dismiss((DWDialog *)data, NULL);
-	return FALSE;
+   DWDialog *dwwait = (DWDialog *)data;
+   HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
+
+   window = window;
+   if(!dwwait)
+      return FALSE;
+
+   dw_mutex_lock(mtx);
+   dw_mutex_close(mtx);
+   dw_window_destroy((HWND)dwwait->data);
+   dw_dialog_dismiss((DWDialog *)data, NULL);
+   return FALSE;
 }
 
 char *_tree_folder(HWND tree, HTREEITEM item)
 {
-	char *folder=strdup("");
-	HTREEITEM parent = item;
-
-	while(parent)
-	{
-		char *temp, *text = dw_tree_get_title(tree, parent);
-
-		if(text)
-		{
-			if(strncmp(text, "Drive ", 6) == 0)
-				text = &text[6];
-
-			temp = malloc(strlen(text) + strlen(folder) + 3);
-			strcpy(temp, text);
-			strcat(temp, "\\");
-			strcat(temp, folder);
-			free(folder);
-			folder = temp;
-		}
-		parent = dw_tree_get_parent(tree, parent);
-	}
-	return folder;
+   char *folder=strdup("");
+   HTREEITEM parent = item;
+
+   while(parent)
+   {
+      char *temp, *text = dw_tree_get_title(tree, parent);
+
+      if(text)
+      {
+         if(strncmp(text, "Drive ", 6) == 0)
+            text = &text[6];
+
+         temp = malloc(strlen(text) + strlen(folder) + 3);
+         strcpy(temp, text);
+         strcat(temp, "\\");
+         strcat(temp, folder);
+         free(folder);
+         folder = temp;
+      }
+      parent = dw_tree_get_parent(tree, parent);
+   }
+   return folder;
 }
 
 int DWSIGNAL _item_select(HWND window, HTREEITEM item, char *text, void *data, void *itemdata)
 {
-	DWDialog *dwwait = (DWDialog *)data;
-	char *treedata = (char *)dw_window_get_data((HWND)dwwait->data, "_dw_tree_selected");
-
-	text = text; itemdata = itemdata;
-	if(treedata)
-		free(treedata);
-
-	treedata = _tree_folder(window, item);
-	dw_window_set_data((HWND)dwwait->data, "_dw_tree_selected", (void *)treedata);
-
-	return FALSE;
+   DWDialog *dwwait = (DWDialog *)data;
+   char *treedata = (char *)dw_window_get_data((HWND)dwwait->data, "_dw_tree_selected");
+
+   text = text; itemdata = itemdata;
+   if(treedata)
+      free(treedata);
+
+   treedata = _tree_folder(window, item);
+   dw_window_set_data((HWND)dwwait->data, "_dw_tree_selected", (void *)treedata);
+
+   return FALSE;
 }
 
 int DWSIGNAL _tree_expand(HWND window, HTREEITEM item, void *data)
 {
-	HTREEITEM tempitem = (HTREEITEM)dw_tree_item_get_data(window, item);
-
-	data = data;
-	if(tempitem)
-	{
-		char *folder = _tree_folder(window, item);
-
-		dw_tree_item_set_data(window, item, 0);
-		dw_tree_item_delete(window, tempitem);
-
-		if(*folder)
-		{
-			strcat(folder, "*");
-			_populate_directory(window, item, folder);
-		}
-		free(folder);
-	}
-
-	return FALSE;
+   HTREEITEM tempitem = (HTREEITEM)dw_tree_item_get_data(window, item);
+
+   data = data;
+   if(tempitem)
+   {
+      char *folder = _tree_folder(window, item);
+
+      dw_tree_item_set_data(window, item, 0);
+      dw_tree_item_delete(window, tempitem);
+
+      if(*folder)
+      {
+         strcat(folder, "*");
+         _populate_directory(window, item, folder);
+      }
+      free(folder);
+   }
+
+   return FALSE;
 }
 
 /*
@@ -8913,110 +10518,131 @@
  */
 char * API dw_file_browse(char *title, char *defpath, char *ext, int flags)
 {
-	if(flags == DW_DIRECTORY_OPEN)
-	{
-		HWND window, hbox, vbox, tree, button;
-		DWDialog *dwwait;
-		HMTX mtx = dw_mutex_new();
-
-		window = dw_window_new( HWND_DESKTOP, title, FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_SIZEBORDER | FCF_MINMAX);
-
-		vbox = dw_box_new(DW_VERT, 5);
-
-		dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0);
-
-		tree = dw_tree_new(60);
-
-		dw_box_pack_start(vbox, tree, 1, 1, TRUE, TRUE, 0);
-		dw_window_set_data(window, "_dw_mutex", (void *)mtx);
-		dw_window_set_data(window, "_dw_tree", (void *)tree);
-
-		hbox = dw_box_new(DW_HORZ, 0);
-
-		dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
-
-		dwwait = dw_dialog_new((void *)window);
-
-		dw_signal_connect(tree, DW_SIGNAL_ITEM_SELECT, DW_SIGNAL_FUNC(_item_select), (void *)dwwait);
-		dw_signal_connect(tree, DW_SIGNAL_TREE_EXPAND, DW_SIGNAL_FUNC(_tree_expand), (void *)dwwait);
-
-		button = dw_button_new("Ok", 1001L);
-		dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
-		dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_ok_func), (void *)dwwait);
-
-		button = dw_button_new("Cancel", 1002L);
-		dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
-		dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_cancel_func), (void *)dwwait);
-		dw_signal_connect(window, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_dw_cancel_func), (void *)dwwait);
-
-		dw_window_set_size(window, 225, 300);
-		dw_window_show(window);
-
-		dw_thread_new((void *)_populate_tree_thread, (void *)window, 0xff);
-		return (char *)dw_dialog_wait(dwwait);
-	}
-	else
-	{
-		FILEDLG fild;
-		HWND hwndFile;
-		int len;
-
-		if(defpath)
-			strcpy(fild.szFullFile, defpath);
-		else
-			strcpy(fild.szFullFile, "");
-
-		len = strlen(fild.szFullFile);
-
-		if(len)
-		{
-			if(fild.szFullFile[len-1] != '\\')
-				strcat(fild.szFullFile, "\\");
-		}
-		strcat(fild.szFullFile, "*");
-
-		if(ext)
-		{
-			strcat(fild.szFullFile, ".");
-			strcat(fild.szFullFile, ext);
-		}
-
-		memset(&fild, 0, sizeof(FILEDLG));
-		fild.cbSize = sizeof(FILEDLG);
-		fild.fl = FDS_CENTER | FDS_OPEN_DIALOG;
-		fild.pszTitle = title;
-		fild.pszOKButton = ((flags & DW_FILE_SAVE) ? "Save" : "Open");
-		fild.pfnDlgProc = (PFNWP)WinDefFileDlgProc;
-
-		hwndFile = WinFileDlg(HWND_DESKTOP, HWND_DESKTOP, &fild);
-		if(hwndFile)
-		{
-			switch(fild.lReturn)
-			{
-			case DID_OK:
-				return strdup(fild.szFullFile);
-			case DID_CANCEL:
-				return NULL;
-			}
-		}
-	}
-	return NULL;
+   if(flags == DW_DIRECTORY_OPEN)
+   {
+      HWND window, hbox, vbox, tree, button;
+      DWDialog *dwwait;
+      HMTX mtx = dw_mutex_new();
+
+      window = dw_window_new( HWND_DESKTOP, title, FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_SIZEBORDER | FCF_MINMAX);
+
+      vbox = dw_box_new(DW_VERT, 5);
+
+      dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0);
+
+      tree = dw_tree_new(60);
+
+      dw_box_pack_start(vbox, tree, 1, 1, TRUE, TRUE, 0);
+      dw_window_set_data(window, "_dw_mutex", (void *)mtx);
+      dw_window_set_data(window, "_dw_tree", (void *)tree);
+
+      hbox = dw_box_new(DW_HORZ, 0);
+
+      dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
+
+      dwwait = dw_dialog_new((void *)window);
+
+      dw_signal_connect(tree, DW_SIGNAL_ITEM_SELECT, DW_SIGNAL_FUNC(_item_select), (void *)dwwait);
+      dw_signal_connect(tree, DW_SIGNAL_TREE_EXPAND, DW_SIGNAL_FUNC(_tree_expand), (void *)dwwait);
+
+      button = dw_button_new("Ok", 1001L);
+      dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
+      dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_ok_func), (void *)dwwait);
+
+      button = dw_button_new("Cancel", 1002L);
+      dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
+      dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_cancel_func), (void *)dwwait);
+      dw_signal_connect(window, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_dw_cancel_func), (void *)dwwait);
+
+      dw_window_set_size(window, 225, 300);
+      dw_window_show(window);
+
+      dw_thread_new((void *)_populate_tree_thread, (void *)window, 0xff);
+      return (char *)dw_dialog_wait(dwwait);
+   }
+   else
+   {
+      FILEDLG fild = { 0 };
+      HWND hwndFile;
+      int len;
+      struct stat buf;
+
+      if(defpath)
+      {
+          if(DosQueryPathInfo((PSZ)defpath, FIL_QUERYFULLNAME, fild.szFullFile, sizeof(fild.szFullFile)))
+              strcpy(fild.szFullFile, defpath);
+      };
+
+      len = strlen(fild.szFullFile);
+
+      /* If we have a defpath */
+      if(len)
+      {
+          /* Check to see if it exists */
+          if(stat(fild.szFullFile, &buf) == 0)
+          {
+              /* If it is a directory... make sure there is a trailing \ */
+              if(buf.st_mode & S_IFDIR)
+              {
+                  if(fild.szFullFile[len-1] != '\\')
+                      strcat(fild.szFullFile, "\\");
+                  /* Set len to 0 so the wildcard gets added below */
+                  len = 0;
+              }
+          }
+      }
+
+      /* If we need a wildcard (defpath isn't a file) */
+      if(!len)
+      {
+          /* Add a * to get all files... */
+          strcat(fild.szFullFile, "*");
+
+          /* If an extension was requested... */
+          if(ext)
+          {
+              /* Limit the results further */
+              strcat(fild.szFullFile, ".");
+              strcat(fild.szFullFile, ext);
+          }
+      }
+
+      /* Setup the structure */
+      fild.cbSize = sizeof(FILEDLG);
+      fild.fl = FDS_CENTER | FDS_OPEN_DIALOG;
+      fild.pszTitle = (PSZ)title;
+      fild.pszOKButton = (PSZ)((flags & DW_FILE_SAVE) ? "Save" : "Open");
+      fild.pfnDlgProc = (PFNWP)WinDefFileDlgProc;
+
+      hwndFile = WinFileDlg(HWND_DESKTOP, HWND_DESKTOP, &fild);
+      if(hwndFile)
+      {
+         switch(fild.lReturn)
+         {
+         case DID_OK:
+            return strdup(fild.szFullFile);
+         case DID_CANCEL:
+            return NULL;
+         }
+      }
+   }
+   return NULL;
 }
 
 /* Internal function to set drive and directory */
 int _SetPath(char *path)
 {
 #ifndef __WATCOMC__
-	if(strlen(path)	> 2)
-	{
-		if(path[1] == ':')
-		{
-			char drive = toupper(path[0]);
-			_chdrive((drive - 'A')+1);
-		}
-	}
+   if(strlen(path)   > 2)
+   {
+      if(path[1] == ':')
+      {
+         char drive = toupper(path[0]);
+         _chdrive((drive - 'A')+1);
+      }
+   }
 #endif
-	return chdir(path);
+   return chdir(path);
 }
 
 /*
@@ -9030,8 +10656,8 @@
  */
 int API dw_exec(char *program, int type, char **params)
 {
-	type = type; /* keep compiler happy */
-	return spawnvp(P_NOWAIT, program, (const char **)params);
+   type = type; /* keep compiler happy */
+   return spawnvp(P_NOWAIT, program, (char * const *)params);
 }
 
 /*
@@ -9041,58 +10667,465 @@
  */
 int API dw_browse(char *url)
 {
-	char *execargs[3], browser[1024], *olddir, *newurl = NULL;
-	int len, ret;
-
-	olddir = _getcwd(NULL, 1024);
-
-	PrfQueryProfileString(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS",
-						  "DefaultWorkingDir", NULL, browser, 1024);
-
-	if(browser[0])
-		_SetPath(browser);
-
-	PrfQueryProfileString(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS",
-						  "DefaultBrowserExe", NULL, browser, 1024);
-
-	len = strlen(browser) - strlen("explore.exe");
-
-	execargs[0] = browser;
-	execargs[1] = url;
-	execargs[2] = NULL;
-
-	/* Special case for Web Explorer, it requires file:/// instead
-	 * of file:// so I am handling it here.
-	 */
-	if(len > 0)
-	{
-		if(stricmp(&browser[len], "explore.exe") == 0 && stricmp(url, "file://") == 0)
-		{
-			int newlen, z;
-			newurl = malloc(strlen(url) + 2);
-			sprintf(newurl, "file:///%s", &url[7]);
-			newlen = strlen(newurl);
-			for(z=8;z<(newlen-8);z++)
-			{
-				if(newurl[z] == '|')
-					newurl[z] = ':';
-				if(newurl[z] == '/')
-					newurl[z] = '\\';
-			}
-			execargs[1] = newurl;
-		}
-	}
-
-	ret = dw_exec(browser, DW_EXEC_GUI, execargs);
-
-	if(olddir)
-	{
-		_SetPath(olddir);
-		free(olddir);
-	}
-	if(newurl)
-		free(newurl);
-	return ret;
+   char *execargs[3], browser[1024], *olddir, *newurl = NULL;
+   int len, ret;
+
+   olddir = _getcwd(NULL, 1024);
+
+   PrfQueryProfileString(HINI_USERPROFILE, (PSZ)"WPURLDEFAULTSETTINGS",
+                    (PSZ)"DefaultWorkingDir", NULL, (PSZ)browser, 1024);
+
+   if(browser[0])
+      _SetPath(browser);
+
+   PrfQueryProfileString(HINI_USERPROFILE, (PSZ)"WPURLDEFAULTSETTINGS",
+                    (PSZ)"DefaultBrowserExe", NULL, (PSZ)browser, 1024);
+
+   len = strlen(browser) - strlen("explore.exe");
+
+   execargs[0] = browser;
+   execargs[1] = url;
+   execargs[2] = NULL;
+
+   /* Special case for Web Explorer, it requires file:/// instead
+    * of file:// so I am handling it here.
+    */
+   if(len > 0)
+   {
+      if(stricmp(&browser[len], "explore.exe") == 0 && stricmp(url, "file://") == 0)
+      {
+         int newlen, z;
+         newurl = malloc(strlen(url) + 2);
+         sprintf(newurl, "file:///%s", &url[7]);
+         newlen = strlen(newurl);
+         for(z=8;z<(newlen-8);z++)
+         {
+            if(newurl[z] == '|')
+               newurl[z] = ':';
+            if(newurl[z] == '/')
+               newurl[z] = '\\';
+         }
+         execargs[1] = newurl;
+      }
+   }
+
+   ret = dw_exec(browser, DW_EXEC_GUI, execargs);
+
+   if(olddir)
+   {
+      _SetPath(olddir);
+      free(olddir);
+   }
+   if(newurl)
+      free(newurl);
+   return ret;
+}
+
+/*
+ * Causes the embedded HTML widget to take action.
+ * Parameters:
+ *       handle: Handle to the window.
+ *       action: One of the DW_HTML_* constants.
+ */
+void API dw_html_action(HWND handle, int action)
+{
+   handle = handle;
+   action = action;
+}
+
+/*
+ * Render raw HTML code in the embedded HTML widget..
+ * Parameters:
+ *       handle: Handle to the window.
+ *       string: String buffer containt HTML code to
+ *               be rendered.
+ * Returns:
+ *       0 on success.
+ */
+int API dw_html_raw(HWND handle, char *string)
+{
+   handle = handle;
+   string = string;
+   return -1;
+}
+
+/*
+ * Render file or web page in the embedded HTML widget..
+ * Parameters:
+ *       handle: Handle to the window.
+ *       url: Universal Resource Locator of the web or
+ *               file object to be rendered.
+ * Returns:
+ *       0 on success.
+ */
+int API dw_html_url(HWND handle, char *url)
+{
+   handle = handle;
+   url = url;
+   return -1;
+}
+
+/*
+ * Create a new HTML window (widget) to be packed.
+ * Not available under OS/2, eCS
+ * Parameters:
+ *       text: The default text to be in the entryfield widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_html_new(unsigned long id)
+{
+   id = id;
+   dw_debug("HTML widget not available; OS/2 currently does not support it.\n");
+   return 0;
+}
+
+typedef struct _dwprint 
+{
+    HDC hdc;
+    char *printername;
+    int (* API drawfunc)(HPRINT, HPIXMAP, int, void *);
+    void *drawdata;
+    unsigned long flags;
+    unsigned int startpage, endpage;
+    char *jobname;
+} DWPrint;
+
+/* Internal functions to handle the print dialog */
+int DWSIGNAL _dw_printer_cancel_func(HWND window, void *data)
+{
+    DWPrint *print = (DWPrint *)data;
+    DWDialog *dwwait = (DWDialog *)print->printername;
+
+    window = (HWND)dwwait->data;
+
+    dw_window_destroy(window);
+    dw_dialog_dismiss(dwwait, NULL);
+    return FALSE;
+}
+
+int DWSIGNAL _dw_printer_ok_func(HWND window, void *data)
+{
+    DWPrint *print = (DWPrint *)data;
+    DWDialog *dwwait = (DWDialog *)print->printername;
+    HWND printerlist, startspin, endspin;
+    char *result = NULL;
+
+    window = (HWND)dwwait->data;
+    printerlist = (HWND)dw_window_get_data(window, "_dw_list");
+    startspin = (HWND)dw_window_get_data(window, "_dw_start_spin");
+    endspin = (HWND)dw_window_get_data(window, "_dw_end_spin");
+    if(printerlist)
+    {
+        char printername[32] = "";
+        int selected = dw_listbox_selected(printerlist);
+
+        /* Get the name of the selected printer */
+        if(selected != DW_ERROR_UNKNOWN)
+        {
+            dw_listbox_get_text(printerlist, selected, printername, 32);
+            if(printername[0])
+                print->printername = result = strdup(printername);
+        }
+        /* Get the start and end positions */
+        print->startpage = (unsigned int)dw_spinbutton_get_pos(startspin);
+        print->endpage = (unsigned int)dw_spinbutton_get_pos(endspin);
+
+        /* If the start is bigger than end... swap them */
+        if(print->startpage > print->endpage)
+        {
+            print->endpage = print->startpage;
+            print->startpage = (unsigned int)dw_spinbutton_get_pos(endspin);
+        }
+    }
+
+    dw_window_destroy(window);
+    dw_dialog_dismiss(dwwait, (void *)result);
+    return FALSE;
+}
+
+/* Borrowed functions which should probably be rewritten */
+BOOL _ExtractLogAddress(char * LogAddress, char * DetailStr)
+{
+    char *p;
+
+    p = DetailStr;
+    while(*p++ != ';'); /* Gets to first ';' and one char beyond */
+    while(*p++ != ';'); /* Gets to second ';' and one char beyond */
+    while(*p != ';') *LogAddress++ = *p++;
+    *LogAddress = '\0';
+    return TRUE;
+}
+
+BOOL _ExtractDriverName(char * DriverName, char * DetailStr)
+{
+    char *p;
+
+    p = DetailStr;
+    while(*p++ != ';'); /* Gets to first ';' and one char beyond */
+    while(*p != '.' && *p != ';' && *p != ',')
+        *DriverName++ = *p++;
+    *DriverName = '\0';
+    return TRUE;
+}
+
+/* EMX Doesn't seem to define this? */
+#ifndef NERR_BufTooSmall
+#define NERR_BufTooSmall 2123
+#endif
+
+/*
+ * Creates a new print object.
+ * Parameters:
+ *       jobname: Name of the print job to show in the queue.
+ *       flags: Flags to initially configure the print object.
+ *       pages: Number of pages to print.
+ *       drawfunc: The pointer to the function to be used as the callback.
+ *       drawdata: User data to be passed to the handler function.
+ * Returns:
+ *       A handle to the print object or NULL on failure.
+ */
+HPRINT API dw_print_new(char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata)
+{
+    char printername[32], tmpbuf[20];
+    HWND window, hbox, vbox, printerlist, button, text;
+    DWDialog *dwwait;
+    DWPrint *print;
+    PVOID pBuf = NULL;
+    ULONG fsType = SPL_PR_QUEUE;
+    ULONG cbBuf, cRes, cTotal, cbNeeded;
+    SPLERR splerr = 0 ;
+    PPRINTERINFO pRes ;    /* Check the default printer for now... want a printer list in the future */
+    int cb = PrfQueryProfileString(HINI_PROFILE, (PSZ)"PM_SPOOLER", (PSZ)"PRINTER", (PSZ)"", printername, 32);
+
+    if(!drawfunc || !(print = calloc(1, sizeof(DWPrint))))
+        return NULL;
+    
+    print->drawfunc = drawfunc;
+    print->drawdata = drawdata;
+    print->jobname = jobname ? jobname : "Dynamic Windows Print Job";
+    print->startpage = 1;
+    print->endpage = pages;
+    print->flags = flags;
+
+    /* Check to see how much space we need for the printer list */
+    splerr = SplEnumPrinter(NULL, 0, fsType, NULL, 0, &cRes, &cTotal, &cbNeeded ,NULL);
+
+    if(splerr == ERROR_MORE_DATA || splerr == NERR_BufTooSmall)
+    {
+        /* Allocate memory for the buffer using the count of bytes that were returned in cbNeeded. */
+        DosAllocMem(&pBuf, cbNeeded, PAG_READ|PAG_WRITE|PAG_COMMIT);
+
+        /* Set count of bytes in buffer to value used to allocate buffer. */
+        cbBuf = cbNeeded;
+
+        /* Call function again with the correct buffer size. */
+        splerr = SplEnumPrinter(NULL, 0, fsType, pBuf, cbBuf, &cRes, &cTotal, &cbNeeded, NULL);
+    }
+
+    /* Make sure we got a valid result */
+    if(cb > 2)
+        printername[cb-2] = '\0';
+    else
+        printername[0] = '\0';
+
+    /* If we didnt' get a printer list or default printer abort */
+    if(!cRes && !printername[0])
+    {
+        /* Show an error and return failure */
+        dw_messagebox("Printing", DW_MB_ERROR | DW_MB_OK, "No printers detected.");
+        free(print);
+        return NULL;
+    }
+
+    /* Create the print dialog */
+    window = dw_window_new(HWND_DESKTOP, "Choose Printer", FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_DLGBORDER | FCF_CLOSEBUTTON | FCF_SYSMENU);
+
+    vbox = dw_box_new(DW_VERT, 5);
+
+    dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0);
+
+    printerlist = dw_listbox_new(0, FALSE);
+    dw_box_pack_start(vbox, printerlist, 1, 1, TRUE, TRUE, 0);
+
+    /* If there are any returned structures in the buffer... */
+    if(pBuf && cRes)
+    {
+        int count = 0;
+
+        pRes = (PPRINTERINFO)pBuf ;
+        while(cRes--)
+        {
+            dw_listbox_append(printerlist, (char *)pRes[cRes].pszPrintDestinationName);
+            /* If this is the default printer... select it by default */
+            if(strcmp((char *)pRes[cRes].pszPrintDestinationName, printername) == 0)
+                dw_listbox_select(printerlist, count, TRUE);
+            count++;
+        }
+    }
+    else
+    {
+        /* Otherwise just add the default */
+        dw_listbox_append(printerlist, printername);
+        dw_listbox_select(printerlist, 0, TRUE);
+    }
+
+    /* Free any unneeded memory */
+    if(pBuf)
+        DosFreeMem(pBuf);
+
+    dw_window_set_data(window, "_dw_list", (void *)printerlist);
+
+    /* Start spinbutton */
+    hbox = dw_box_new(DW_HORZ, 0);
+
+    dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
+
+    text = dw_text_new("Start page:", 0);
+    dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER);
+    dw_box_pack_start(hbox, text, 70, 20, FALSE, FALSE, 3);
+
+    button = dw_spinbutton_new("1", 0);
+    dw_spinbutton_set_limits(button, 1, pages);
+    dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3);
+    dw_window_set_data(window, "_dw_start_spin", (void *)button);
+
+    /* End spinbutton */
+    hbox = dw_box_new(DW_HORZ, 0);
+
+    dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
+
+    text = dw_text_new("End page:", 0);
+    dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER);
+    dw_box_pack_start(hbox, text, 70, 20, FALSE, FALSE, 3);
+
+    sprintf(tmpbuf, "%d", pages);
+    button = dw_spinbutton_new(tmpbuf, 0);
+    dw_spinbutton_set_limits(button, 1, pages);
+    dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3);
+    dw_window_set_data(window, "_dw_end_spin", (void *)button);
+
+    /* Ok and Cancel buttons */
+    hbox = dw_box_new(DW_HORZ, 0);
+
+    dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
+    dw_box_pack_start(hbox, 0, 100, 1, TRUE, FALSE, 0);
+
+    button = dw_button_new("Ok", 0);
+    dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
+
+    dwwait = dw_dialog_new((void *)window);
+    /* Save it temporarily there until we need it */
+    print->printername = (char *)dwwait;
+
+    dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_printer_ok_func), (void *)print);
+
+    button = dw_button_new("Cancel", 0);
+    dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
+
+    dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_printer_cancel_func), (void *)print);
+    dw_signal_connect(window, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_dw_printer_cancel_func), (void *)print);
+
+    dw_window_set_size(window, 300, 400);
+
+    dw_window_show(window);
+
+    print->printername = dw_dialog_wait(dwwait);
+
+    /* The user picked a printer */
+    if(print->printername)
+    {
+        char PrintDetails[256];
+        char DriverName[32];
+        char LogAddress[32];
+        DEVOPENSTRUC dop;
+
+        /* Get the printer information string */
+        cb = PrfQueryProfileString(HINI_PROFILE, (PSZ)"PM_SPOOLER_PRINTER", (PSZ)print->printername, (PSZ)"", PrintDetails, 256);
+        _ExtractLogAddress(LogAddress, PrintDetails);
+        _ExtractDriverName(DriverName, PrintDetails);
+        dop.pszDriverName = (PSZ)DriverName;
+        dop.pszLogAddress = (PSZ)LogAddress;
+        dop.pdriv = NULL;
+        dop.pszDataType = (PSZ)"PM_Q_STD";
+        /* Attempt to open a device context and return a handle to it */
+        print->hdc = DevOpenDC(dwhab, OD_QUEUED, (PSZ)"*", 4L, (PDEVOPENDATA) &dop, (HDC)NULL);
+        if(print->hdc)
+            return print;
+    }
+    /* The user canceled */
+    if(print->printername)
+        free(print->printername);
+    free(print);
+    return NULL;
+}
+
+/*
+ * Runs the print job, causing the draw page callbacks to fire.
+ * Parameters:
+ *       print: Handle to the print object returned by dw_print_new().
+ *       flags: Flags to run the print job.
+ * Returns:
+ *       DW_ERROR_UNKNOWN on error or DW_ERROR_NONE on success.
+ */
+int API dw_print_run(HPRINT print, unsigned long flags)
+{
+    DWPrint *p = print;
+    HPIXMAP pixmap;
+    int x, result = DW_ERROR_UNKNOWN;
+    SIZEL sizl = { 0, 0 };
+    
+    if(!p)
+        return result;
+        
+    if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
+        return result;
+
+    /* Start the job */
+    DevEscape(p->hdc, DEVESC_STARTDOC, strlen(p->jobname), (PBYTE)p->jobname, NULL, NULL);
+
+    pixmap->font = WinCreateWindow(HWND_OBJECT, WC_FRAME, NULL, 0,0,0,1,1, NULLHANDLE, HWND_TOP,0, NULL, NULL);
+    pixmap->hdc = p->hdc;
+    pixmap->hps = GpiCreatePS(dwhab, p->hdc, &sizl, PU_PELS | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC);
+    pixmap->transcolor = DW_RGB_TRANSPARENT;
+    pixmap->width = sizl.cx;
+    pixmap->height = sizl.cy;
+    dw_pixmap_set_font(pixmap, DefaultFont);
+
+    /* Cycle through each page */
+    for(x=p->startpage-1; x<p->endpage && p->drawfunc; x++)
+    {
+        p->drawfunc(print, pixmap, x, p->drawdata);
+        /* Next page */
+        DevEscape(p->hdc, DEVESC_NEWFRAME, 0, NULL, NULL, NULL);
+    }
+    /* Determine the completion code */
+    if(p->drawfunc)
+    {
+        result = DW_ERROR_NONE;
+        /* Signal that we are done */
+        DevEscape(p->hdc, DEVESC_ENDDOC, 0, NULL, NULL, NULL);
+    }
+    else
+        DevEscape(p->hdc, DEVESC_ABORTDOC, 0, NULL, NULL, NULL);
+    /* Free memory */
+    dw_pixmap_destroy(pixmap);
+    if(p->printername)
+        free(p->printername);
+    free(p);
+    return result;
+}
+
+/*
+ * Cancels the print job, typically called from a draw page callback.
+ * Parameters:
+ *       print: Handle to the print object returned by dw_print_new().
+ */
+void API dw_print_cancel(HPRINT print)
+{
+    DWPrint *p = print;
+    
+    if(p)
+        p->drawfunc = NULL;
 }
 
 /*
@@ -9102,18 +11135,18 @@
  */
 char * API dw_user_dir(void)
 {
-	static char _user_dir[1024] = "";
-
-	if(!_user_dir[0])
-	{
-		char *home = getenv("HOME");
-
-		if(home)
-			strcpy(_user_dir, home);
-		else
-			strcpy(_user_dir, "C:\\");
-	}
-	return _user_dir;
+   static char _user_dir[1024] = "";
+
+   if(!_user_dir[0])
+   {
+      char *home = getenv("HOME");
+
+      if(home)
+         strcpy(_user_dir, home);
+      else
+         strcpy(_user_dir, "C:\\");
+   }
+   return _user_dir;
 }
 
 /*
@@ -9125,7 +11158,7 @@
  */
 void API dw_window_function(HWND handle, void *function, void *data)
 {
-	WinSendMsg(handle, WM_USER, (MPARAM)function, (MPARAM)data);
+   WinSendMsg(handle, WM_USER, (MPARAM)function, (MPARAM)data);
 }
 
 /* Functions for managing the user data lists that are associated with
@@ -9134,92 +11167,90 @@
  */
 UserData *_find_userdata(UserData **root, char *varname)
 {
-	UserData *tmp = *root;
-
-	while(tmp)
-	{
-		if(stricmp(tmp->varname, varname) == 0)
-			return tmp;
-		tmp = tmp->next;
-	}
-	return NULL;
+   UserData *tmp = *root;
+
+   while(tmp)
+   {
+      if(stricmp(tmp->varname, varname) == 0)
+         return tmp;
+      tmp = tmp->next;
+   }
+   return NULL;
 }
 
 int _new_userdata(UserData **root, char *varname, void *data)
 {
-	UserData *new = _find_userdata(root, varname);
-
-	if(new)
-	{
-		new->data = data;
-		return TRUE;
-	}
-	else
-	{
-		new = malloc(sizeof(UserData));
-		if(new)
-		{
-			new->varname = strdup(varname);
-			new->data = data;
-
-			new->next = NULL;
-
-			if (!*root)
-				*root = new;
-			else
-			{
-				UserData *prev = NULL, *tmp = *root;
-				while(tmp)
-				{
-					prev = tmp;
-					tmp = tmp->next;
-				}
-				if(prev)
-					prev->next = new;
-				else
-					*root = new;
-			}
-			return TRUE;
-		}
-	}
-	return FALSE;
+   UserData *new = _find_userdata(root, varname);
+
+   if(new)
+   {
+      new->data = data;
+      return TRUE;
+   }
+   else
+   {
+      new = malloc(sizeof(UserData));
+      if(new)
+      {
+         new->varname = strdup(varname);
+         new->data = data;
+
+         new->next = NULL;
+
+         if (!*root)
+            *root = new;
+         else
+         {
+            UserData *prev = *root, *tmp = prev->next;
+
+            while(tmp)
+            {
+               prev = tmp;
+               tmp = tmp->next;
+            }
+            prev->next = new;
+         }
+         return TRUE;
+      }
+   }
+   return FALSE;
 }
 
 int _remove_userdata(UserData **root, char *varname, int all)
 {
-	UserData *prev = NULL, *tmp = *root;
-
-	while(tmp)
-	{
-		if(all || stricmp(tmp->varname, varname) == 0)
-		{
-			if(!prev)
-			{
-				*root = tmp->next;
-				free(tmp->varname);
-				free(tmp);
-				if(!all)
-					return 0;
-				tmp = *root;
-			}
-			else
-			{
-				/* If all is true we should
-				 * never get here.
-				 */
-				prev->next = tmp->next;
-				free(tmp->varname);
-				free(tmp);
-				return 0;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
-	return 0;
+   UserData *prev = NULL, *tmp = *root;
+
+   while(tmp)
+   {
+      if(all || stricmp(tmp->varname, varname) == 0)
+      {
+         if(!prev)
+         {
+            *root = tmp->next;
+            free(tmp->varname);
+            free(tmp);
+            if(!all)
+               return 0;
+            tmp = *root;
+         }
+         else
+         {
+            /* If all is true we should
+             * never get here.
+             */
+            prev->next = tmp->next;
+            free(tmp->varname);
+            free(tmp);
+            return 0;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
+   return 0;
 }
 
 /*
@@ -9231,26 +11262,26 @@
  */
 void API dw_window_set_data(HWND window, char *dataname, void *data)
 {
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER);
-
-	if(!blah)
-	{
-		if(!dataname)
-			return;
-
-		blah = calloc(1, sizeof(WindowData));
-		WinSetWindowPtr(window, QWP_USER, blah);
-	}
-
-	if(data)
-		_new_userdata(&(blah->root), dataname, data);
-	else
-	{
-		if(dataname)
-			_remove_userdata(&(blah->root), dataname, FALSE);
-		else
-			_remove_userdata(&(blah->root), NULL, TRUE);
-	}
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER);
+
+   if(!blah)
+   {
+      if(!dataname)
+         return;
+
+      blah = calloc(1, sizeof(WindowData));
+      WinSetWindowPtr(window, QWP_USER, blah);
+   }
+
+   if(data)
+      _new_userdata(&(blah->root), dataname, data);
+   else
+   {
+      if(dataname)
+         _remove_userdata(&(blah->root), dataname, FALSE);
+      else
+         _remove_userdata(&(blah->root), NULL, TRUE);
+   }
 }
 
 /*
@@ -9262,15 +11293,15 @@
  */
 void * API dw_window_get_data(HWND window, char *dataname)
 {
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER);
-
-	if(blah && blah->root && dataname)
-	{
-		UserData *ud = _find_userdata(&(blah->root), dataname);
-		if(ud)
-			return ud->data;
-	}
-	return NULL;
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER);
+
+   if(blah && blah->root && dataname)
+   {
+      UserData *ud = _find_userdata(&(blah->root), dataname);
+      if(ud)
+         return ud->data;
+   }
+   return NULL;
 }
 
 /*
@@ -9284,17 +11315,17 @@
  */
 int API dw_timer_connect(int interval, void *sigfunc, void *data)
 {
-	if(sigfunc)
-	{
-		int timerid = WinStartTimer(dwhab, NULLHANDLE, 0, interval);
-
-		if(timerid)
-		{
-			_new_signal(WM_TIMER, NULLHANDLE, timerid, sigfunc, data);
-			return timerid;
-		}
-	}
-	return 0;
+   if(sigfunc)
+   {
+      int timerid = WinStartTimer(dwhab, NULLHANDLE, 0, interval);
+
+      if(timerid)
+      {
+         _new_signal(WM_TIMER, NULLHANDLE, timerid, sigfunc, data);
+         return timerid;
+      }
+   }
+   return 0;
 }
 
 /*
@@ -9304,37 +11335,37 @@
  */
 void API dw_timer_disconnect(int id)
 {
-	SignalHandler *prev = NULL, *tmp = Root;
-
-	/* 0 is an invalid timer ID */
-	if(!id)
-		return;
-
-	WinStopTimer(dwhab, NULLHANDLE, id);
-
-	while(tmp)
-	{
-		if(tmp->id == id)
-		{
-			if(prev)
-			{
-				prev->next = tmp->next;
-				free(tmp);
-				tmp = prev->next;
-			}
-			else
-			{
-				Root = tmp->next;
-				free(tmp);
-				tmp = Root;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
+   SignalHandler *prev = NULL, *tmp = Root;
+
+   /* 0 is an invalid timer ID */
+   if(!id)
+      return;
+
+   WinStopTimer(dwhab, NULLHANDLE, id);
+
+   while(tmp)
+   {
+      if(tmp->id == id)
+      {
+         if(prev)
+         {
+            prev->next = tmp->next;
+            free(tmp);
+            tmp = prev->next;
+         }
+         else
+         {
+            Root = tmp->next;
+            free(tmp);
+            tmp = Root;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
 }
 
 /*
@@ -9347,36 +11378,33 @@
  */
 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
 {
-	ULONG message = 0, id = 0;
-
-	if(window && signame && sigfunc)
-	{
-		if((message = _findsigmessage(signame)) != 0)
-		{
-			/* Handle special case of the menu item */
-			if(message == WM_COMMAND && window < 65536)
-			{
-				char buffer[15];
-				HWND owner;
-
-				sprintf(buffer, "_dw_id%d", (int)window);
-				owner = (HWND)dw_window_get_data(hwndApp, buffer);
-
-				if(owner)
-				{
-					id = window;
-					window = owner;
-					dw_window_set_data(hwndApp, buffer, 0);
-				}
-				else
-				{
-					/* If it is a popup menu clear all entries */
-					dw_signal_disconnect_by_window(window);
-				}
-			}
-			_new_signal(message, window, id, sigfunc, data);
-		}
-	}
+   ULONG message = 0, id = 0;
+
+   if(window && signame && sigfunc)
+   {
+      if((message = _findsigmessage(signame)) != 0)
+      {
+         /* Handle special case of the menu item */
+         if(message == WM_COMMAND && window < 65536)
+         {
+            char buffer[15];
+            HWND owner;
+
+            sprintf(buffer, "_dw_id%d", (int)window);
+            owner = (HWND)dw_window_get_data(hwndApp, buffer);
+
+            /* Make sure there are no dupes from popups */
+            dw_signal_disconnect_by_window(window);
+
+            if(owner)
+            {
+               id = window;
+               window = owner;
+            }
+         }
+         _new_signal(message, window, id, sigfunc, data);
+      }
+   }
 }
 
 /*
@@ -9386,35 +11414,35 @@
  */
 void API dw_signal_disconnect_by_name(HWND window, char *signame)
 {
-	SignalHandler *prev = NULL, *tmp = Root;
-	ULONG message;
-
-	if(!window || !signame || (message = _findsigmessage(signame)) == 0)
-		return;
-
-	while(tmp)
-	{
-		if(tmp->window == window && tmp->message == message)
-		{
-			if(prev)
-			{
-				prev->next = tmp->next;
-				free(tmp);
-				tmp = prev->next;
-			}
-			else
-			{
-				Root = tmp->next;
-				free(tmp);
-				tmp = Root;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
+   SignalHandler *prev = NULL, *tmp = Root;
+   ULONG message;
+
+   if(!window || !signame || (message = _findsigmessage(signame)) == 0)
+      return;
+
+   while(tmp)
+   {
+      if(((window < 65536 && tmp->id == window) || tmp->window == window) && tmp->message == message)
+      {
+         if(prev)
+         {
+            prev->next = tmp->next;
+            free(tmp);
+            tmp = prev->next;
+         }
+         else
+         {
+            Root = tmp->next;
+            free(tmp);
+            tmp = Root;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
 }
 
 /*
@@ -9424,31 +11452,31 @@
  */
 void API dw_signal_disconnect_by_window(HWND window)
 {
-	SignalHandler *prev = NULL, *tmp = Root;
-
-	while(tmp)
-	{
-		if(tmp->window == window)
-		{
-			if(prev)
-			{
-				prev->next = tmp->next;
-				free(tmp);
-				tmp = prev->next;
-			}
-			else
-			{
-				Root = tmp->next;
-				free(tmp);
-				tmp = Root;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
+   SignalHandler *prev = NULL, *tmp = Root;
+
+   while(tmp)
+   {
+      if((window < 65536 && tmp->id == window) || tmp->window == window)
+      {
+         if(prev)
+         {
+            prev->next = tmp->next;
+            free(tmp);
+            tmp = prev->next;
+         }
+         else
+         {
+            Root = tmp->next;
+            free(tmp);
+            tmp = Root;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
 }
 
 /*
@@ -9459,31 +11487,99 @@
  */
 void API dw_signal_disconnect_by_data(HWND window, void *data)
 {
-	SignalHandler *prev = NULL, *tmp = Root;
-
-	while(tmp)
-	{
-		if(tmp->window == window && tmp->data == data)
-		{
-			if(prev)
-			{
-				prev->next = tmp->next;
-				free(tmp);
-				tmp = prev->next;
-			}
-			else
-			{
-				Root = tmp->next;
-				free(tmp);
-				tmp = Root;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
-}
-
-
+   SignalHandler *prev = NULL, *tmp = Root;
+
+   while(tmp)
+   {
+      if(((window < 65536 && tmp->id == window) || tmp->window == window) && tmp->data == data)
+      {
+         if(prev)
+         {
+            prev->next = tmp->next;
+            free(tmp);
+            tmp = prev->next;
+         }
+         else
+         {
+            Root = tmp->next;
+            free(tmp);
+            tmp = Root;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
+}
+
+/*
+ * Create a new calendar window (widget) to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ * Returns:
+ *       Handle to the created calendar or NULL on error.
+ */
+HWND API dw_calendar_new(ULONG id)
+{
+    WindowData *blah = calloc(sizeof(WindowData), 1);
+    DATETIME dt;
+    HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_STATIC,
+                        NULL,
+                        WS_VISIBLE | SS_TEXT,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+    blah->oldproc = WinSubclassWindow(tmp, _calendarproc);
+    WinSetWindowPtr(tmp, QWP_USER, blah);
+    dw_window_set_font(tmp, DefaultFont);
+    if(!DosGetDateTime(&dt))
+        dw_calendar_set_date(tmp, dt.year, dt.month, dt.day);
+    return tmp;
+}
+
+/*
+ * Sets the current date of a calendar.
+ * Parameters:
+ *       handle: The handle to the calendar returned by dw_calendar_new().
+ *       year, month, day: To set the calendar to display.
+ */
+void API dw_calendar_set_date( HWND window, unsigned int year, unsigned int month, unsigned int day )
+{
+    /* Need to be 0 based */
+    if(year > 0)
+        year--;
+    if(month > 0)
+        month--;
+    if(day > 0)
+        day--;
+
+    dw_window_set_data(window, "_dw_year", DW_INT_TO_POINTER(year));
+    dw_window_set_data(window, "_dw_month", DW_INT_TO_POINTER(month));
+    dw_window_set_data(window, "_dw_day", DW_INT_TO_POINTER(day));
+    /* Make it redraw */
+    WinPostMsg(window, WM_PAINT, 0, 0);
+}
+
+/*
+ * Gets the year, month and day set in the calendar widget.
+ * Parameters:
+ *       handle: The handle to the calendar returned by dw_calendar_new().
+ *       year: Variable to store the year or NULL.
+ *       month: Variable to store the month or NULL.
+ *       day: Variable to store the day or NULL.
+ */
+void API dw_calendar_get_date( HWND window, unsigned int *year, unsigned int *month, unsigned int *day )
+{
+    if(year)
+        *year = DW_POINTER_TO_UINT(dw_window_get_data(window, "_dw_year")) + 1;
+    if(month)
+        *month = DW_POINTER_TO_UINT(dw_window_get_data(window, "_dw_month")) + 1;
+    if(day)
+        *day = DW_POINTER_TO_UINT(dw_window_get_data(window, "_dw_day")) + 1;
+}
--- a/dw.h	Fri Feb 18 02:50:18 2011 -0600
+++ b/dw.h	Thu Nov 24 03:45:48 2011 -0600
@@ -1,13 +1,14 @@
-/* $Id: dw.h,v 1.1 2005/05/09 19:21:08 nuke Exp $ */
+/* $Id: dw.h 1377 2011-11-22 20:46:37Z bsmith $ */
 
 #ifndef _H_DW
 #define _H_DW
 
 /* Dynamic Windows version numbers */
-#define DW_MAJOR_VERSION 0
-#define DW_MINOR_VERSION 9
+#define DW_MAJOR_VERSION 2
+#define DW_MINOR_VERSION 2
 #define DW_SUB_VERSION 0
 
+#if !defined(__PHOTON__)
 /* These corespond to the entries in the color
  * arrays in the Win32 dw.c, they are also the
  * same as DOS ANSI colors.
@@ -29,6 +30,7 @@
 #define DW_CLR_CYAN              14
 #define DW_CLR_WHITE             15
 #define DW_CLR_DEFAULT           16
+#endif
 
 /* Signal handler defines */
 #define DW_SIGNAL_CONFIGURE      "configure_event"
@@ -49,7 +51,20 @@
 #define DW_SIGNAL_COLUMN_CLICK   "click-column"
 #define DW_SIGNAL_TREE_EXPAND    "tree-expand"
 
-#if defined(__OS2__) || defined(__WIN32__) || defined(__MAC__) || defined(WINNT) || defined(__EMX__)
+/* status of menu items */
+#define DW_MIS_ENABLED           1
+#define DW_MIS_DISABLED          (1 << 1)
+#define DW_MIS_CHECKED           (1 << 2)
+#define DW_MIS_UNCHECKED         (1 << 3)
+
+/* ensure we can build the Gtk port with MingW on Windows */
+#if defined(DW_USE_GTK) && defined(__MINGW32__)
+# ifndef GDK_WINDOWING_WIN32
+#   define GDK_WINDOWING_WIN32
+# endif
+#endif
+
+#if defined(__OS2__) || (defined(__WIN32__) && !defined(GDK_WINDOWING_WIN32)) || defined(__MAC__) || (defined(WINNT) && !defined(GDK_WINDOWING_WIN32)) || defined(__EMX__)
 /* OS/2, Windows or MacOS */
 
 #if (defined(__IBMC__) || defined(_System)) && !defined(API)
@@ -68,9 +83,9 @@
 
 typedef struct _user_data
 {
-	struct _user_data *next;
-	void              *data;
-	char              *varname;
+   struct _user_data *next;
+   void              *data;
+   char              *varname;
 } UserData;
 
 /* OS/2 Specific section */
@@ -101,6 +116,7 @@
 #define FCF_CLOSEBUTTON            0x04000000L
 #endif
 
+#define DW_FCF_CLOSEBUTTON       0
 #define DW_FCF_TITLEBAR          FCF_TITLEBAR
 #define DW_FCF_SYSMENU           (FCF_SYSMENU | FCF_CLOSEBUTTON)
 #define DW_FCF_MENU              FCF_MENU
@@ -147,6 +163,9 @@
 #define DW_POINTER_DEFAULT       0
 #define DW_POINTER_ARROW         SPTR_ARROW
 #define DW_POINTER_CLOCK         SPTR_WAIT
+#define DW_POINTER_QUESTION      SPTR_ICONQUESTION
+
+#define DW_BS_NOBORDER           BS_NOBORDER
 
 #define DW_OS2_NEW_WINDOW        1
 
@@ -204,19 +223,20 @@
 #define VK_RMENU             VK_MENU
 
 typedef struct _window_data {
-	PFNWP oldproc;
-	UserData *root;
-	HWND clickdefault;
-	ULONG flags;
-	void *data;
+   PFNWP oldproc;
+   UserData *root;
+   HWND clickdefault;
+   ULONG flags;
+   void *data;
 } WindowData;
 
 typedef struct _hpixmap {
-	unsigned long width, height;
-	HDC hdc;
-	HPS hps;
-	HBITMAP hbm;
-	HWND handle;
+   unsigned long width, height;
+   HDC hdc;
+   HPS hps;
+   HBITMAP hbm;
+   HWND handle, font;
+   unsigned long transcolor;
 } *HPIXMAP;
 
 typedef void *HTREEITEM;
@@ -224,6 +244,7 @@
 typedef HMODULE HMOD;
 typedef unsigned short UWORD;
 typedef unsigned long HSHM;
+typedef unsigned long HICN;
 
 extern HAB dwhab;
 extern HMQ dwhmq;
@@ -231,10 +252,21 @@
 
 #if defined(__MAC__)
 /* MacOS specific section */
-#include <Carbon/Carbon.h>
+#include <pthread.h>
+#include <dlfcn.h>
 
-typedef ControlRef HWND;
-typedef ThreadID DWTID;
+/* Unfortunately using Cocoa we can't include
+ * Cocoa.h from C code, so we have to instead
+ * use opaque types and use the values from
+ * Cocoa.h in the header here directly without
+ * using the symbolic names.
+ */
+
+#define TRUE 1
+#define FALSE 0
+
+typedef void *HWND;
+typedef void *HSHM;
 typedef unsigned long ULONG;
 typedef long LONG;
 typedef unsigned short USHORT;
@@ -245,44 +277,65 @@
 typedef char CHAR;
 typedef unsigned UINT;
 typedef int INT;
-typedef void *HMTX;
-typedef void *HEV;
-typedef void *HSHM;
-typedef void *HMOD;
-typedef void *HPIXMAP;
+typedef pthread_mutex_t *HMTX;
+typedef struct _dw_unix_event {
+   pthread_mutex_t mutex;
+   pthread_cond_t event;
+   pthread_t thread;
+   int alive;
+   int posted;
+} *HEV;
+typedef pthread_t DWTID;
+typedef void * HMOD;
+struct _dw_unix_shm {
+   int fd;
+   char *path;
+   int sid;
+   int size;
+};
 typedef void *HTREEITEM;
-typedef MenuRef HMENUI;
+typedef void *HMENUI;
+typedef void *HICN;
 
 typedef struct _window_data {
-	UserData *root;
-	HWND clickdefault;
-	ULONG flags;
-	void *data;
+   UserData *root;
+   HWND clickdefault;
+   ULONG flags;
+   void *data;
 } WindowData;
 
-#define DW_DT_LEFT               0
+typedef struct _hpixmap {
+    unsigned long width, height;
+    void *image, *font;
+    HWND handle;
+} *HPIXMAP;
+
+void _dw_pool_drain(void);
+
+#define DW_DT_LEFT               0 /* NSLeftTextAlignment */
 #define DW_DT_QUERYEXTENT        0
 #define DW_DT_UNDERSCORE         0
 #define DW_DT_STRIKEOUT          0
 #define DW_DT_TEXTATTRS          0
 #define DW_DT_EXTERNALLEADING    0
-#define DW_DT_CENTER             0
-#define DW_DT_RIGHT              0
+#define DW_DT_CENTER             2 /* NSCenterTextAlignment */
+#define DW_DT_RIGHT              1 /* NSRightTextAlignment */
 #define DW_DT_TOP                0
-#define DW_DT_VCENTER            0
+#define DW_DT_VCENTER            (1 << 10)
 #define DW_DT_BOTTOM             0
 #define DW_DT_HALFTONE           0
 #define DW_DT_MNEMONIC           0
 #define DW_DT_WORDBREAK          0
 #define DW_DT_ERASERECT          0
 
-#define DW_FCF_TITLEBAR          0
-#define DW_FCF_SYSMENU           kWindowCloseBoxAttribute
+#define DW_FCF_CLOSEBUTTON       (1 << 1) /* NSClosableWindowMask */
+#define DW_FCF_TITLEBAR          (1 << 0) /* NSTitledWindowMask */
+#define DW_FCF_SYSMENU           (1 << 1) /* NSClosableWindowMask */
 #define DW_FCF_MENU              0
-#define DW_FCF_SIZEBORDER        (kWindowResizableAttribute|kWindowLiveResizeAttribute)
-#define DW_FCF_MINBUTTON         kWindowCollapseBoxAttribute
-#define DW_FCF_MAXBUTTON         kWindowFullZoomAttribute
-#define DW_FCF_MINMAX            (kWindowCollapseBoxAttribute|kWindowFullZoomAttribute)
+#define DW_FCF_SIZEBORDER        (1 << 3) /* NSResizableWindowMask */
+#define DW_FCF_MINBUTTON         (1 << 2) /* NSMiniaturizableWindowMask */
+#define DW_FCF_MAXBUTTON         0
+#define DW_FCF_MINMAX            (1 << 2) /* NSMiniaturizableWindowMask */
 #define DW_FCF_VERTSCROLL        0
 #define DW_FCF_HORZSCROLL        0
 #define DW_FCF_DLGBORDER         0
@@ -292,7 +345,7 @@
 #define DW_FCF_NOBYTEALIGN       0
 #define DW_FCF_NOMOVEWITHOWNER   0
 #define DW_FCF_SYSMODAL          0
-#define DW_FCF_HIDEBUTTON        kWindowCollapseAttribute
+#define DW_FCF_HIDEBUTTON        0
 #define DW_FCF_HIDEMAX           0
 #define DW_FCF_AUTOICON          0
 #define DW_FCF_MAXIMIZE          0
@@ -317,13 +370,16 @@
 
 #define DW_LIT_NONE              -1
 
-#define DW_MLE_CASESENSITIVE     MLFSEARCH_CASESENSITIVE
+#define DW_MLE_CASESENSITIVE     2 /* NSLiteralSearch */
+
+#define DW_BS_NOBORDER           1
 
 #define DW_POINTER_DEFAULT       0
-#define DW_POINTER_ARROW         0
-#define DW_POINTER_CLOCK         watchCursor
+#define DW_POINTER_ARROW         1
+#define DW_POINTER_CLOCK         2
+#define DW_POINTER_QUESTION      3
 
-#define HWND_DESKTOP		 ((HWND)0)
+#define HWND_DESKTOP     ((HWND)0)
 
 /* flag values for dw_messagebox() */
 #define DW_MB_OK                 (1 << 1)
@@ -336,7 +392,90 @@
 #define DW_MB_INFORMATION        (1 << 12)
 #define DW_MB_QUESTION           (1 << 13)
 
+/* Virtual Key Codes */
+#define VK_LBUTTON               0xFF10 /* TODO */
+#define VK_RBUTTON               0xFF11 /* TODO */
+#define VK_CANCEL                0xFF12 /* TODO */
+#define VK_MBUTTON               0xFF13 /* TODO */
+#define VK_BACK                  0x7F
+#define VK_TAB                   0x09
+#define VK_CLEAR                 71
+#define VK_RETURN                13
+#define VK_MENU                  0xF735 /* NSMenuFunctionKey */
+#define VK_PAUSE                 0xF730 /* NSPauseFunctionKey */
+#define VK_CAPITAL               57
+#define VK_ESCAPE                0x1B
+#define VK_SPACE                 ' '
+#define VK_PRIOR                 0xF72C /* NSPageUpFunctionKey */
+#define VK_NEXT                  0xF72D /* NSPageDownFunctionKey */
+#define VK_END                   0xF72B /* NSEndFunctionKey */
+#define VK_HOME                  0xF729 /* NSHomeFunctionKey */
+#define VK_LEFT                  0xF702 /* NSLeftArrowFunctionKey */
+#define VK_UP                    0xF700 /* NSUpArrowFunctionKey */
+#define VK_RIGHT                 0xF703 /* NSRightArrowFunctionKey */
+#define VK_DOWN                  0xF701 /* NSDownArrowFunctionKey */
+#define VK_SELECT                0xF741 /* NSSelectFunctionKey */
+#define VK_PRINT                 0xF738 /* NSPrintFunctionKey */
+#define VK_EXECUTE               0xF742 /* NSExecuteFunctionKey */
+#define VK_SNAPSHOT              0xF72E /* NSPrintScreenFunctionKey */
+#define VK_INSERT                0xF727 /* NSInsertFunctionKey */
+#define VK_DELETE                0xF728 /* NSDeleteFunctionKey */
+#define VK_HELP                  0xF746 /* NSHelpFunctionKey */
+#define VK_LWIN                  55
+#define VK_RWIN                  0xFF14 /* TODO */
+#define VK_NUMPAD0               82
+#define VK_NUMPAD1               83
+#define VK_NUMPAD2               84
+#define VK_NUMPAD3               85
+#define VK_NUMPAD4               86
+#define VK_NUMPAD5               87
+#define VK_NUMPAD6               88
+#define VK_NUMPAD7               89
+#define VK_NUMPAD8               91
+#define VK_NUMPAD9               92
+#define VK_MULTIPLY              67
+#define VK_ADD                   69
+#define VK_SEPARATOR             0xFF15 /* TODO */
+#define VK_SUBTRACT              78
+#define VK_DECIMAL               65
+#define VK_DIVIDE                75
+#define VK_F1                    0xF704 /* NSF1FunctionKey */
+#define VK_F2                    0xF705 /* NSF2FunctionKey */
+#define VK_F3                    0xF706 /* NSF3FunctionKey */
+#define VK_F4                    0xF707 /* NSF4FunctionKey */
+#define VK_F5                    0xF708 /* NSF5FunctionKey */
+#define VK_F6                    0xF709 /* NSF6FunctionKey */
+#define VK_F7                    0xF70A /* NSF7FunctionKey */
+#define VK_F8                    0xF70B /* NSF8FunctionKey */
+#define VK_F9                    0xF70C /* NSF9FunctionKey */
+#define VK_F10                   0xF70D /* NSF10FunctionKey */
+#define VK_F11                   0xF70E /* NSF11FunctionKey */
+#define VK_F12                   0xF70F /* NSF12FunctionKey */
+#define VK_F13                   0xF710 /* NSF13FunctionKey */
+#define VK_F14                   0xF711 /* NSF14FunctionKey */
+#define VK_F15                   0xF712 /* NSF15FunctionKey */
+#define VK_F16                   0xF713 /* NSF16FunctionKey */
+#define VK_F17                   0xF714 /* NSF17FunctionKey */
+#define VK_F18                   0xF715 /* NSF18FunctionKey */
+#define VK_F19                   0xF716 /* NSF19FunctionKey */
+#define VK_F20                   0xF717 /* NSF20FunctionKey */
+#define VK_F21                   0xF718 /* NSF21FunctionKey */
+#define VK_F22                   0xF719 /* NSF22FunctionKey */
+#define VK_F23                   0xF71A /* NSF23FunctionKey */
+#define VK_F24                   0xF71B /* NSF24FunctionKey */
+#define VK_NUMLOCK               0xFF16 /* TODO */
+#define VK_SCROLL                0xF72F /* NSScrollLockFunctionKey */
+#define VK_LSHIFT                56
+#define VK_RSHIFT                60
+#define VK_LCONTROL              59
+#define VK_RCONTROL              62
+#define VK_LMENU                 0xF735 /* NSMenuFunctionKey */
+#define VK_RMENU                 0xF735 /* NSMenuFunctionKey */
 
+/* Key Modifiers */
+#define KC_CTRL                  (1 << 18) /* NSControlKeyMask */
+#define KC_SHIFT                 (1 << 17) /* NSShiftKeyMask */
+#define KC_ALT                   (1 << 19) /* NSAlternateKeyMask */
 #endif
 
 /* Windows specific section */
@@ -372,6 +511,7 @@
 #define DW_DT_WORDBREAK          0
 #define DW_DT_ERASERECT          0
 
+#define DW_FCF_CLOSEBUTTON       0
 #define DW_FCF_TITLEBAR          WS_CAPTION
 #define DW_FCF_SYSMENU           WS_SYSMENU
 #define DW_FCF_MENU              0
@@ -389,7 +529,7 @@
 #define DW_FCF_NOMOVEWITHOWNER   0
 #define DW_FCF_SYSMODAL          0
 #define DW_FCF_HIDEBUTTON        WS_MINIMIZEBOX
-#define DW_FCF_HIDEMAX           0
+#define DW_FCF_HIDEMAX           (WS_MINIMIZEBOX|WS_MAXIMIZEBOX)
 #define DW_FCF_AUTOICON          0
 #define DW_FCF_MAXIMIZE          WS_MAXIMIZE
 #define DW_FCF_MINIMIZE          WS_MINIMIZE
@@ -415,9 +555,12 @@
 
 #define DW_MLE_CASESENSITIVE     1
 
+#define DW_BS_NOBORDER           BS_FLAT
+
 #define DW_POINTER_DEFAULT       0
 #define DW_POINTER_ARROW         32512
 #define DW_POINTER_CLOCK         32514
+#define DW_POINTER_QUESTION      32651
 
 /* flag values for dw_messagebox() */
 #define DW_MB_OK                 MB_OK
@@ -447,120 +590,392 @@
 #define ClassName "dynamicwindows"
 #define SplitbarClassName "dwsplitbar"
 #define ObjectClassName "dwobjectclass"
+#define BrowserClassName "dwbrowserclass"
+#define ScrollClassName "dwscrollclass"
 #define DefaultFont NULL
 
 typedef struct _color {
-	int fore;
-	int back;
-	HWND combo, buddy;
-	int user;
-	int vcenter;
-	HWND clickdefault;
-	HBRUSH hbrush;
-	HFONT hfont;
-	char fontname[128];
-	WNDPROC pOldProc;
-	UserData *root;
+   int fore;
+   int back;
+   HWND combo, buddy;
+   int user;
+   int vcenter;
+   HWND clickdefault;
+   HBRUSH hbrush;
+   HFONT hfont;
+   char fontname[128];
+   WNDPROC pOldProc;
+   UserData *root;
 } ColorInfo;
 
 typedef struct _notebookpage {
-	ColorInfo cinfo;
-	TC_ITEM item;
-	HWND hwnd;
-	int realid;
+   ColorInfo cinfo;
+   TC_ITEM item;
+   HWND hwnd;
+   int realid;
 } NotebookPage;
 
 typedef HANDLE HMTX;
 typedef HANDLE HEV;
 typedef HANDLE HMOD;
 typedef HANDLE HSHM;
+typedef HANDLE HICN;
 
 typedef struct _container {
-	ColorInfo cinfo;
-	ULONG *flags;
-	WNDPROC pOldProc;
-	ULONG columns;
+   ColorInfo cinfo;
+   ULONG *flags;
+   ULONG columns;
+   COLORREF odd, even;
 } ContainerInfo;
 
 typedef struct _hpixmap {
-	unsigned long width, height;
-	HBITMAP hbm;
-	HDC hdc;
-	HWND handle;
-	void *bits;
+   unsigned long width, height;
+   HBITMAP hbm;
+   HDC hdc;
+   unsigned long transcolor;
+   HWND handle;
+   void *bits;
+   unsigned long depth;
+   HFONT font;
 } *HPIXMAP;
 
 typedef HWND HMENUI;
 #endif
 
 typedef struct _item {
-	/* Item type - Box or Item */
-	int type;
-	/* Handle to Frame or Window */
-	HWND hwnd;
-	/* Width and Height of static size */
-	int width, height, origwidth, origheight;
-	/* Size Type - Static or Expand */
-	int hsize, vsize;
-	/* Padding */
-	int pad;
-	/* Ratio of current item */
-	float xratio, yratio;
+   /* Item type - Box or Item */
+   int type;
+   /* Handle to Frame or Window */
+   HWND hwnd;
+   /* Width and Height of static size */
+   int width, height, origwidth, origheight;
+   /* Size Type - Static or Expand */
+   int hsize, vsize;
+   /* Padding */
+   int pad;
+   /* Ratio of current item */
+   float xratio, yratio;
 } Item;
 
 typedef struct _box {
 #if defined(__WIN32__) || defined(WINNT)
-	ColorInfo cinfo;
+   ColorInfo cinfo;
 #elif defined(__OS2__) || defined(__EMX__)
-	PFNWP oldproc;
-	UserData *root;
-	HWND hwndtitle, hwnd;
-	int titlebar;
+   PFNWP oldproc;
+   UserData *root;
+   HWND hwndtitle, hwnd;
+   int titlebar;
 #endif
-	/* Number of items in the box */
-	int count;
-	/* Box type - horizontal or vertical */
-	int type;
-	/* Padding */
-	int pad, parentpad, grouppadx, grouppady;
-	/* Groupbox */
-	HWND grouphwnd;
-	/* Default item */
-	HWND defaultitem;
-	/* Used as temporary storage in the calculation stage */
-	int upx, upy, minheight, minwidth;
-	/* Ratio in this box */
-	float xratio, yratio, parentxratio, parentyratio;
-	/* Used for calculating individual item ratios */
-	int width, height;
-	/* Any combinations of flags describing the box */
-	unsigned long flags;
-	/* Array of item structures */
-	struct _item *items;
+   /* Number of items in the box */
+   int count;
+   /* Box type - horizontal or vertical */
+   int type;
+   /* Padding */
+   int pad, parentpad, grouppadx, grouppady;
+   /* Groupbox */
+   HWND grouphwnd;
+   /* Default item */
+   HWND defaultitem;
+   /* Used as temporary storage in the calculation stage */
+   int upx, upy, minheight, minwidth;
+   /* Ratio in this box */
+   float xratio, yratio, parentxratio, parentyratio;
+   /* Used for calculating individual item ratios */
+   int width, height;
+   /* Any combinations of flags describing the box */
+   unsigned long flags;
+   /* Array of item structures */
+   struct _item *items;
 } Box;
 
 typedef struct _bubblebutton {
 #if defined(__WIN32__) || defined(WINNT)
-	ColorInfo cinfo;
-	int checkbox;
-	WNDPROC pOldProc;
+   ColorInfo cinfo;
+   int checkbox;
+   WNDPROC pOldProc;
 #endif
 #if defined(__OS2__) || defined(__EMX__)
-	PFNWP pOldProc;
-	UserData *root;
+   PFNWP pOldProc;
+   UserData *root;
+   unsigned long id;
+   char bubbletext[BUBBLE_HELP_MAX];
 #endif
-	unsigned long id;
-	char bubbletext[BUBBLE_HELP_MAX];
 } BubbleButton;
 
+#elif defined(__PHOTON__)
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+/* Photon specific section */
+#include <Pt.h>
+#include <Ph.h>
+/* which image formats supported */
+#define PX_IMAGE_MODULES
+#define PX_GIF_SUPPORT
+#define PX_JPG_SUPPORT
+#define PX_BMP_SUPPORT
+#define PX_PND_SUPPORT
+#include <photon/PxImage.h>
+
+#define TRUE  1
+#define FALSE 0
+
+typedef PtWidget_t *pPtWidget_t;
+typedef pPtWidget_t HWND;
+
+typedef unsigned long ULONG;
+typedef long LONG;
+typedef unsigned short USHORT;
+typedef short SHORT;
+typedef unsigned short UWORD;
+typedef short WORD ;
+typedef unsigned char UCHAR;
+typedef char CHAR;
+typedef unsigned UINT;
+typedef int INT;
+typedef void *HMTX;
+typedef void *HEV;
+typedef void *HSHM;
+typedef void *HMOD;
+typedef PtTreeItem_t *HTREEITEM;
+typedef HWND HMENUI;
+typedef int DWTID;
+typedef unsigned long HICN;
+
+typedef struct _user_data
+{
+   struct _user_data *next;
+   void              *data;
+   char              *varname;
+} UserData;
+
+typedef struct _window_data {
+   UserData *root;
+   HWND clickdefault;
+   ULONG flags;
+   void *data;
+} WindowData;
+
+typedef struct _hpixmap {
+   unsigned long width, height;
+   /* ?? *pixmap; */
+   HWND handle;
+} *HPIXMAP;
+
+/* colors matching Photon Graphics colors */
+#define DW_CLR_BLACK             Pg_BLACK
+#define DW_CLR_DARKRED           Pg_DRED
+#define DW_CLR_DARKGREEN         Pg_DGREEN
+#define DW_CLR_BROWN             Pg_BROWN
+#define DW_CLR_DARKBLUE          Pg_DBLUE
+#define DW_CLR_DARKPINK          Pg_PURPLE
+#define DW_CLR_DARKCYAN          Pg_DCYAN
+#define DW_CLR_PALEGRAY          Pg_GRAY
+#define DW_CLR_DARKGRAY          Pg_MGRAY
+#define DW_CLR_RED               Pg_RED
+#define DW_CLR_GREEN             Pg_GREEN
+#define DW_CLR_YELLOW            Pg_YELLOW
+#define DW_CLR_BLUE              Pg_BLUE
+#define DW_CLR_PINK              Pg_MAGENTA
+#define DW_CLR_CYAN              Pg_CYAN
+#define DW_CLR_WHITE             Pg_WHITE
+#define DW_CLR_DEFAULT           Pg_GRAY
+/* color manipulation macros */
+#define DW_RGB_COLOR (0xF0000000)
+#define DW_RGB_TRANSPARENT (0x0F000000)
+#define DW_RGB_MASK (0x00FFFFFF)
+#define DW_RED_MASK (0x00FF0000)
+#define DW_GREEN_MASK (0x0000FF00)
+#define DW_BLUE_MASK (0x000000FF)
+#define DW_RED_VALUE(a) PgRedValue(a)
+#define DW_GREEN_VALUE(a) PgGreenValue(a)
+#define DW_BLUE_VALUE(a) PgBluValue(a)
+#define DW_RGB(a, b, c) PgRGB( a, b, c )
+
+#define DW_DT_LEFT               0
+#define DW_DT_QUERYEXTENT        0
+#define DW_DT_UNDERSCORE         0
+#define DW_DT_STRIKEOUT          0
+#define DW_DT_TEXTATTRS          0
+#define DW_DT_EXTERNALLEADING    0
+#define DW_DT_CENTER             0
+#define DW_DT_RIGHT              0
+#define DW_DT_TOP                0
+#define DW_DT_VCENTER            0
+#define DW_DT_BOTTOM             0
+#define DW_DT_HALFTONE           0
+#define DW_DT_MNEMONIC           0
+#define DW_DT_WORDBREAK          0
+#define DW_DT_ERASERECT          0
+
+#define DW_FCF_CLOSEBUTTON       Ph_WM_RENDER_CLOSE
+#define DW_FCF_TITLEBAR          Ph_WM_RENDER_TITLE
+#define DW_FCF_SYSMENU           0
+#define DW_FCF_MENU              Ph_WM_RENDER_MENU
+#define DW_FCF_SIZEBORDER        Ph_WM_RENDER_RESIZE
+#define DW_FCF_MINBUTTON         Ph_WM_RENDER_MIN
+#define DW_FCF_MAXBUTTON         Ph_WM_RENDER_MAX
+#define DW_FCF_MINMAX            (Ph_WM_RENDER_MIN|Ph_WM_RENDER_MAX)
+#define DW_FCF_VERTSCROLL        0
+#define DW_FCF_HORZSCROLL        0
+#define DW_FCF_DLGBORDER         0
+#define DW_FCF_BORDER            Ph_WM_RENDER_BORDER
+#define DW_FCF_SHELLPOSITION     0
+#define DW_FCF_TASKLIST          0
+#define DW_FCF_NOBYTEALIGN       0
+#define DW_FCF_NOMOVEWITHOWNER   0
+#define DW_FCF_SYSMODAL          0
+#define DW_FCF_HIDEBUTTON        0
+#define DW_FCF_HIDEMAX           0
+#define DW_FCF_AUTOICON          (Ph_WM_RENDER_ASICON | ~Ph_WM_RENDER_ASAPP)
+#define DW_FCF_MAXIMIZE          0
+#define DW_FCF_MINIMIZE          0
+
+#define DW_CFA_BITMAPORICON      1
+#define DW_CFA_STRING            (1 << 1)
+#define DW_CFA_ULONG             (1 << 2)
+#define DW_CFA_TIME              (1 << 3)
+#define DW_CFA_DATE              (1 << 4)
+#define DW_CFA_CENTER            (1 << 5)
+#define DW_CFA_LEFT              (1 << 6)
+#define DW_CFA_RIGHT             (1 << 7)
+#define DW_CFA_STRINGANDICON     (1 << 8)
+#define DW_CFA_HORZSEPARATOR     0
+#define DW_CFA_SEPARATOR         0
+
+#define DW_CRA_SELECTED          1
+#define DW_CRA_CURSORED          (1 << 1)
+
+#define DW_LS_MULTIPLESEL        1
+
+#define DW_LIT_NONE              -1
+
+#ifdef MLFSEARCH_CASESENSITIVE
+# define DW_MLE_CASESENSITIVE    MLFSEARCH_CASESENSITIVE
+#else
+# define DW_MLE_CASESENSITIVE    0
+#endif
+
+#define DW_BS_NOBORDER           1
+
+#define DW_POINTER_DEFAULT       0
+#define DW_POINTER_ARROW         0
+#define DW_POINTER_CLOCK         0
+#define DW_POINTER_QUESTION      0
+
+#define HWND_DESKTOP     ((HWND)0)
+
+/* flag values for dw_messagebox() */
+#define DW_MB_OK                 (1 << 1)
+#define DW_MB_OKCANCEL           (1 << 2)
+#define DW_MB_YESNO              (1 << 3)
+#define DW_MB_YESNOCANCEL        (1 << 4)
+
+#define DW_MB_WARNING            (1 << 10)
+#define DW_MB_ERROR              (1 << 11)
+#define DW_MB_INFORMATION        (1 << 12)
+#define DW_MB_QUESTION           (1 << 13)
+
+/* Virtual Key Codes */
+#define VK_LBUTTON               0
+#define VK_RBUTTON               0
+#define VK_CANCEL                0
+#define VK_MBUTTON               0
+#define VK_BACK                  0
+#define VK_TAB                   0
+#define VK_CLEAR                 0
+#define VK_RETURN                0
+#define VK_MENU                  0
+#define VK_PAUSE                 0
+#define VK_CAPITAL               0
+#define VK_ESCAPE                0
+#define VK_SPACE                 0
+#define VK_PRIOR                 0
+#define VK_NEXT                  0
+#define VK_END                   0
+#define VK_HOME                  0
+#define VK_LEFT                  0
+#define VK_UP                    0
+#define VK_RIGHT                 0
+#define VK_DOWN                  0
+#define VK_SELECT                0
+#define VK_PRINT                 0
+#define VK_EXECUTE               0
+#define VK_SNAPSHOT              0
+#define VK_INSERT                0
+#define VK_DELETE                0
+#define VK_HELP                  0
+#define VK_LWIN                  0
+#define VK_RWIN                  0
+#define VK_NUMPAD0               0
+#define VK_NUMPAD1               0
+#define VK_NUMPAD2               0
+#define VK_NUMPAD3               0
+#define VK_NUMPAD4               0
+#define VK_NUMPAD5               0
+#define VK_NUMPAD6               0
+#define VK_NUMPAD7               0
+#define VK_NUMPAD8               0
+#define VK_NUMPAD9               0
+#define VK_MULTIPLY              0
+#define VK_ADD                   0
+#define VK_SEPARATOR             0
+#define VK_SUBTRACT              0
+#define VK_DECIMAL               0
+#define VK_DIVIDE                0
+#define VK_F1                    0
+#define VK_F2                    0
+#define VK_F3                    0
+#define VK_F4                    0
+#define VK_F5                    0
+#define VK_F6                    0
+#define VK_F7                    0
+#define VK_F8                    0
+#define VK_F9                    0
+#define VK_F10                   0
+#define VK_F11                   0
+#define VK_F12                   0
+#define VK_F13                   0
+#define VK_F14                   0
+#define VK_F15                   0
+#define VK_F16                   0
+#define VK_F17                   0
+#define VK_F18                   0
+#define VK_F19                   0
+#define VK_F20                   0
+#define VK_F21                   0
+#define VK_F22                   0
+#define VK_F23                   0
+#define VK_F24                   0
+#define VK_NUMLOCK               0
+#define VK_SCROLL                0
+#define VK_LSHIFT                0
+#define VK_RSHIFT                0
+#define VK_LCONTROL              0
+#define VK_RCONTROL              0
+#define VK_LMENU                 0
+#define VK_RMENU                 0
+
+/* Key Modifiers */
+#define KC_CTRL                  (1)
+#define KC_SHIFT                 (1 << 1)
+#define KC_ALT                   (1 << 2)
+
 #else
 /* GTK Specific section */
 #include <gtk/gtk.h>
-#include <gdk/gdkx.h>
+#ifdef GDK_WINDOWING_X11
+# include <gdk/gdkx.h>
+#else
+# include <gdk/gdk.h>
+#endif
 #include <gdk/gdkprivate.h>
 #include <gdk/gdkkeysyms.h>
 #include <pthread.h>
-#include <dlfcn.h>
+#if !defined(GDK_WINDOWING_WIN32)
+# include <dlfcn.h>
+#endif
 
 #define DW_DT_LEFT               1
 #define DW_DT_UNDERSCORE         (1 << 1)
@@ -601,6 +1016,7 @@
 #define DW_FCF_AUTOICON          (1 << 18)
 #define DW_FCF_MAXIMIZE          (1 << 19)
 #define DW_FCF_MINIMIZE          (1 << 20)
+#define DW_FCF_CLOSEBUTTON       (1 << 21)
 
 #define DW_CFA_BITMAPORICON      1
 #define DW_CFA_STRING            (1 << 1)
@@ -623,9 +1039,12 @@
 
 #define DW_MLE_CASESENSITIVE     1
 
+#define DW_BS_NOBORDER           1
+
 #define DW_POINTER_DEFAULT       0
 #define DW_POINTER_ARROW         GDK_TOP_LEFT_ARROW
 #define DW_POINTER_CLOCK         GDK_WATCH
+#define DW_POINTER_QUESTION      GDK_QUESTION_ARROW
 
 #define HWND_DESKTOP             ((HWND)0)
 
@@ -641,6 +1060,87 @@
 #define DW_MB_QUESTION           (1 << 13)
 
 /* Virtual Key Codes */
+#if GTK_MAJOR_VERSION > 2
+#define VK_LBUTTON           GDK_KEY_Pointer_Button1
+#define VK_RBUTTON           GDK_KEY_Pointer_Button3
+#define VK_CANCEL            GDK_KEY_Cancel
+#define VK_MBUTTON           GDK_KEY_Pointer_Button2
+#define VK_BACK              GDK_KEY_BackSpace
+#define VK_TAB               GDK_KEY_Tab
+#define VK_CLEAR             GDK_KEY_Clear
+#define VK_RETURN            GDK_KEY_Return
+#define VK_MENU              GDK_KEY_Menu
+#define VK_PAUSE             GDK_KEY_Pause
+#define VK_CAPITAL           GDK_KEY_Caps_Lock
+#define VK_ESCAPE            GDK_KEY_Escape
+#define VK_SPACE             GDK_KEY_space
+#define VK_PRIOR             GDK_KEY_Page_Up
+#define VK_NEXT              GDK_KEY_Page_Down
+#define VK_END               GDK_KEY_End
+#define VK_HOME              GDK_KEY_Home
+#define VK_LEFT              GDK_KEY_Left
+#define VK_UP                GDK_KEY_Up
+#define VK_RIGHT             GDK_KEY_Right
+#define VK_DOWN              GDK_KEY_Down
+#define VK_SELECT            GDK_KEY_Select
+#define VK_PRINT             GDK_KEY_Sys_Req
+#define VK_EXECUTE           GDK_KEY_Execute
+#define VK_SNAPSHOT          GDK_KEY_Print
+#define VK_INSERT            GDK_KEY_Insert
+#define VK_DELETE            GDK_KEY_Delete
+#define VK_HELP              GDK_KEY_Help
+#define VK_LWIN              GDK_KEY_Super_L
+#define VK_RWIN              GDK_KEY_Super_R
+#define VK_NUMPAD0           GDK_KEY_KP_0
+#define VK_NUMPAD1           GDK_KEY_KP_1
+#define VK_NUMPAD2           GDK_KEY_KP_2
+#define VK_NUMPAD3           GDK_KEY_KP_3
+#define VK_NUMPAD4           GDK_KEY_KP_4
+#define VK_NUMPAD5           GDK_KEY_KP_5
+#define VK_NUMPAD6           GDK_KEY_KP_6
+#define VK_NUMPAD7           GDK_KEY_KP_7
+#define VK_NUMPAD8           GDK_KEY_KP_8
+#define VK_NUMPAD9           GDK_KEY_KP_9
+#define VK_MULTIPLY          GDK_KEY_KP_Multiply
+#define VK_ADD               GDK_KEY_KP_Add
+#define VK_SEPARATOR         GDK_KEY_KP_Separator
+#define VK_SUBTRACT          GDK_KEY_KP_Subtract
+#define VK_DECIMAL           GDK_KEY_KP_Decimal
+#define VK_DIVIDE            GDK_KEY_KP_Divide
+#define VK_F1                GDK_KEY_F1
+#define VK_F2                GDK_KEY_F2
+#define VK_F3                GDK_KEY_F3
+#define VK_F4                GDK_KEY_F4
+#define VK_F5                GDK_KEY_F5
+#define VK_F6                GDK_KEY_F6
+#define VK_F7                GDK_KEY_F7
+#define VK_F8                GDK_KEY_F8
+#define VK_F9                GDK_KEY_F9
+#define VK_F10               GDK_KEY_F10
+#define VK_F11               GDK_KEY_F11
+#define VK_F12               GDK_KEY_F12
+#define VK_F13               GDK_KEY_F13
+#define VK_F14               GDK_KEY_F14
+#define VK_F15               GDK_KEY_F15
+#define VK_F16               GDK_KEY_F16
+#define VK_F17               GDK_KEY_F17
+#define VK_F18               GDK_KEY_F18
+#define VK_F19               GDK_KEY_F19
+#define VK_F20               GDK_KEY_F20
+#define VK_F21               GDK_KEY_F21
+#define VK_F22               GDK_KEY_F22
+#define VK_F23               GDK_KEY_F23
+#define VK_F24               GDK_KEY_F24
+#define VK_NUMLOCK           GDK_KEY_Num_Lock
+#define VK_SCROLL            GDK_KEY_Scroll_Lock
+#define VK_LSHIFT            GDK_KEY_Shift_L
+#define VK_RSHIFT            GDK_KEY_Shift_R
+#define VK_LCONTROL          GDK_KEY_Control_L
+#define VK_RCONTROL          GDK_KEY_Control_R
+#define VK_LMENU             GDK_KEY_Menu
+#define VK_RMENU             GDK_KEY_Menu
+
+#else
 #define VK_LBUTTON           GDK_Pointer_Button1
 #define VK_RBUTTON           GDK_Pointer_Button3
 #define VK_CANCEL            GDK_Cancel
@@ -719,6 +1219,7 @@
 #define VK_RCONTROL          GDK_Control_R
 #define VK_LMENU             GDK_Menu
 #define VK_RMENU             GDK_Menu
+#endif
 
 /* Key Modifiers */
 #define KC_CTRL              GDK_CONTROL_MASK
@@ -740,34 +1241,45 @@
 typedef int INT;
 typedef pthread_mutex_t *HMTX;
 typedef struct _dw_unix_event {
-	pthread_mutex_t mutex;
-	pthread_cond_t event;
-	pthread_t thread;
-	int alive;
-	int posted;
+   pthread_mutex_t mutex;
+   pthread_cond_t event;
+   pthread_t thread;
+   int alive;
+   int posted;
 } *HEV;
 typedef pthread_t DWTID;
 typedef void * HMOD;
 struct _dw_unix_shm {
-	int fd;
-	char *path;
-	int sid;
-	int size;
+   int fd;
+   char *path;
+   int sid;
+   int size;
 };
 
 typedef struct _hpixmap {
-	unsigned long width, height;
-	GdkPixmap *pixmap;
-	HWND handle;
+   unsigned long width, height;
+   HWND handle;
+   char *font;
+#if GTK_MAJOR_VERSION > 1
+   GdkPixbuf *pixbuf;  /* the actual image */
+#endif
+#if GTK_MAJOR_VERSION > 2
+   cairo_surface_t *image; /* Going to have dual storage for now */
+#else
+   GdkPixmap *pixmap;  /* the actual image */
+   GdkBitmap *bitmap;  /* if not null, the image mask representing the transparency mask */
+   void *image;        /* Opaque handle to a cairo_surface_t for printing */
+#endif
 } *HPIXMAP;
 
 typedef GtkWidget *HMENUI;
 typedef void *HTREEITEM;
 typedef void *HSHM;
+typedef void *HICN;
 
 typedef struct _resource_struct {
-	long resource_max, *resource_id;
-	char **resource_data;
+   long resource_max, *resource_id;
+   char **resource_data;
 } DWResources;
 
 #if !defined(DW_RESOURCES) || defined(BUILD_DLL)
@@ -781,48 +1293,50 @@
 #if !defined(__OS2__) && !defined(__EMX__)
 typedef struct _CDATE
 {
-	UCHAR  day;
-	UCHAR  month;
-	USHORT year;
+   UCHAR  day;
+   UCHAR  month;
+   USHORT year;
 } CDATE;
 typedef CDATE *PCDATE;
 
 typedef struct _CTIME
 {
-	UCHAR hours;
-	UCHAR minutes;
-	UCHAR seconds;
-	UCHAR ucReserved;
+   UCHAR hours;
+   UCHAR minutes;
+   UCHAR seconds;
+   UCHAR ucReserved;
 } CTIME;
 typedef CTIME *PCTIME;
 #endif
 
-#if defined(__OS2__) || defined(__WIN32__) || defined(WINNT) || defined(__EMX__)
+#if defined(__OS2__) || (defined(__WIN32__) && !defined(GDK_WINDOWING_WIN32)) || (defined(WINNT) && !defined(GDK_WINDOWING_WIN32)) || defined(__EMX__)
 typedef unsigned long DWTID;
 #endif
 
 typedef struct _dwenv {
-	/* Operating System Name and DW Build Date/Time */
-	char osName[30], buildDate[30], buildTime[30];
-	/* Versions and builds */
-	short MajorVersion, MinorVersion, MajorBuild, MinorBuild;
-	/* Dynamic Window version */
-	short DWMajorVersion, DWMinorVersion, DWSubVersion;
+   /* Operating System Name and DW Build Date/Time */
+   char osName[30], buildDate[30], buildTime[30];
+   /* Versions and builds */
+   short MajorVersion, MinorVersion, MajorBuild, MinorBuild;
+   /* Dynamic Window version */
+   short DWMajorVersion, DWMinorVersion, DWSubVersion;
 } DWEnv;
 
 
 typedef struct _dwexpose {
-	int x, y;
-	int width, height;
+   int x, y;
+   int width, height;
 } DWExpose;
 
 typedef struct _dwdialog {
-	HEV eve;
-	int done;
-	int method;
-	void *data, *result;
+   HEV eve;
+   int done;
+   int method;
+   void *data, *result;
 } DWDialog;
 
+typedef void *HPRINT;
+
 #define DW_SIGNAL_FUNC(a) ((void *)a)
 
 #define DW_DESKTOP               HWND_DESKTOP
@@ -842,6 +1356,8 @@
 #define DW_HORZ 0
 #define DW_VERT 1
 
+#define DW_TIMEOUT_INFINITE ((unsigned long)-1)
+
 /* Obsolete, should disappear sometime */
 #define BOXHORZ DW_HORZ
 #define BOXVERT DW_VERT
@@ -860,6 +1376,7 @@
 #define DW_PIXMAP_WIDTH(x) (x ? x->width : 0)
 #define DW_PIXMAP_HEIGHT(x) (x ? x->height : 0)
 
+#if !defined(__PHOTON__)
 #define DW_RGB_COLOR (0xF0000000)
 #define DW_RGB_TRANSPARENT (0x0F000000)
 #define DW_RGB_MASK (0x00FFFFFF)
@@ -869,10 +1386,15 @@
 #define DW_RED_VALUE(a) (a & DW_RED_MASK)
 #define DW_GREEN_VALUE(a) ((a & DW_GREEN_MASK) >> 8)
 #define DW_BLUE_VALUE(a) ((a & DW_BLUE_MASK) >> 16)
-#define DW_RGB(a, b, c) (0xF0000000 | a | b << 8 | c << 16)
+#define DW_RGB(a, b, c) (0xF0000000 | (a) | (b) << 8 | (c) << 16)
+#endif
 
 #define DW_MENU_SEPARATOR ""
 #define DW_NOMENU 0
+#define DW_MENU_AUTO 0
+#define DW_MENU_POPUP (unsigned long)-1
+
+#define DW_PERCENT_INDETERMINATE ((unsigned int)-1)
 
 /* Return value error codes */
 #define DW_ERROR_NONE      0
@@ -881,6 +1403,39 @@
 #define DW_ERROR_NON_INIT  3
 #define DW_ERROR_NO_MEM    4
 #define DW_ERROR_INTERRUPT 5
+#define DW_ERROR_UNKNOWN   -1
+
+/* Embedded HTML actions */
+#define DW_HTML_GOBACK     0
+#define DW_HTML_GOFORWARD  1
+#define DW_HTML_GOHOME     2
+#define DW_HTML_SEARCH     3
+#define DW_HTML_RELOAD     4
+#define DW_HTML_STOP       5
+#define DW_HTML_PRINT      6
+
+/* Drawing flags... used for Arc currently */
+#define DW_DRAW_DEFAULT    0
+#define DW_DRAW_FILL       1
+#define DW_DRAW_FULL       (1 << 1)
+
+
+/* Macro for casting resource IDs to HICN */
+#define DW_RESOURCE(a) (a < 65536 ? (HICN)a : (HICN)0)
+
+#include <limits.h>
+/* Macros for converting from INT/UINT to and from POINTER without compiler warnings */
+#if LONG_MAX > INT_MAX
+#define DW_INT_TO_POINTER(a) ((void *)(long)a)
+#define DW_POINTER_TO_INT(a) ((int)(long)a)
+#define DW_UINT_TO_POINTER(a) ((void *)(unsigned long)a)
+#define DW_POINTER_TO_UINT(a) ((unsigned int)(unsigned long)a)
+#else
+#define DW_INT_TO_POINTER(a) ((void *)a)
+#define DW_POINTER_TO_INT(a) ((int)a)
+#define DW_UINT_TO_POINTER(a) ((void *)a)
+#define DW_POINTER_TO_UINT(a) ((unsigned int)a)
+#endif
 
 #ifndef API
 #define API
@@ -905,6 +1460,7 @@
 /* Public function prototypes */
 void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad);
 void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad);
+void API dw_box_pack_at_index(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad);
 #if !defined(__OS2__) && !defined(__WIN32__) && !defined(__EMX__) && !defined(__MAC__)
 int API dw_int_init(DWResources *res, int newthread, int *argc, char **argv[]);
 #define dw_init(a, b, c) dw_int_init(&_resources, a, &b, &c)
@@ -923,14 +1479,19 @@
 int API dw_window_destroy(HWND handle);
 void API dw_window_redraw(HWND handle);
 int API dw_window_set_font(HWND handle, char *fontname);
+char * API dw_window_get_font(HWND handle);
 int API dw_window_set_color(HWND handle, unsigned long fore, unsigned long back);
 HWND API dw_window_new(HWND hwndOwner, char *title, unsigned long flStyle);
 HWND API dw_box_new(int type, int pad);
+HWND API dw_scrollbox_new(int type, int pad);
+int API dw_scrollbox_get_pos( HWND handle, int orient );
+int API dw_scrollbox_get_range( HWND handle, int orient );
 HWND API dw_groupbox_new(int type, int pad, char *title);
 HWND API dw_mdi_new(unsigned long id);
 HWND API dw_bitmap_new(unsigned long id);
 HWND API dw_bitmapbutton_new(char *text, unsigned long id);
 HWND API dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename);
+HWND API dw_bitmapbutton_new_from_data(char *text, unsigned long id, char *str, int len);
 HWND API dw_container_new(unsigned long id, int multi);
 HWND API dw_tree_new(unsigned long id);
 HWND API dw_text_new(char *text, unsigned long id);
@@ -948,6 +1509,7 @@
 HWND API dw_checkbox_new(char *text, unsigned long id);
 HWND API dw_listbox_new(unsigned long id, int multi);
 void API dw_listbox_append(HWND handle, char *text);
+void API dw_listbox_insert(HWND handle, char *text, int pos);
 void API dw_listbox_list_append(HWND handle, char **text, int count);
 void API dw_listbox_clear(HWND handle);
 int API dw_listbox_count(HWND handle);
@@ -956,7 +1518,7 @@
 void API dw_listbox_delete(HWND handle, int index);
 void API dw_listbox_get_text(HWND handle, unsigned int index, char *buffer, unsigned int length);
 void API dw_listbox_set_text(HWND handle, unsigned int index, char *buffer);
-unsigned int API dw_listbox_selected(HWND handle);
+int API dw_listbox_selected(HWND handle);
 int API dw_listbox_selected_multi(HWND handle, int where);
 void API dw_percent_set_pos(HWND handle, unsigned int position);
 unsigned int API dw_slider_get_pos(HWND handle);
@@ -964,13 +1526,14 @@
 unsigned int API dw_scrollbar_get_pos(HWND handle);
 void API dw_scrollbar_set_pos(HWND handle, unsigned int position);
 void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible);
-void API dw_window_set_pos(HWND handle, unsigned long x, unsigned long y);
+void API dw_window_set_pos(HWND handle, long x, long y);
 void API dw_window_set_size(HWND handle, unsigned long width, unsigned long height);
-void API dw_window_set_pos_size(HWND handle, unsigned long x, unsigned long y, unsigned long width, unsigned long height);
-void API dw_window_get_pos_size(HWND handle, unsigned long *x, unsigned long *y, unsigned long *width, unsigned long *height);
+void API dw_window_set_pos_size(HWND handle, long x, long y, unsigned long width, unsigned long height);
+void API dw_window_get_pos_size(HWND handle, long *x, long *y, unsigned long *width, unsigned long *height);
 void API dw_window_set_style(HWND handle, unsigned long style, unsigned long mask);
-void API dw_window_set_icon(HWND handle, unsigned long id);
+void API dw_window_set_icon(HWND handle, HICN icon);
 void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename);
+void API dw_window_set_bitmap_from_data(HWND handle, unsigned long id, char *data, int len);
 char * API dw_window_get_text(HWND handle);
 void API dw_window_set_text(HWND handle, char *text);
 int API dw_window_set_border(HWND handle, int border);
@@ -1000,11 +1563,11 @@
 long API dw_spinbutton_get_pos(HWND handle);
 int API dw_checkbox_get(HWND handle);
 void API dw_checkbox_set(HWND handle, int value);
-HTREEITEM API dw_tree_insert(HWND handle, char *title, unsigned long icon, HTREEITEM parent, void *itemdata);
-HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, unsigned long icon, HTREEITEM parent, void *itemdata);
+HTREEITEM API dw_tree_insert(HWND handle, char *title, HICN icon, HTREEITEM parent, void *itemdata);
+HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, HICN icon, HTREEITEM parent, void *itemdata);
 void API dw_tree_clear(HWND handle);
 void API dw_tree_item_delete(HWND handle, HTREEITEM item);
-void API dw_tree_item_change(HWND handle, HTREEITEM item, char *title, unsigned long icon);
+void API dw_tree_item_change(HWND handle, HTREEITEM item, char *title, HICN icon);
 void API dw_tree_item_expand(HWND handle, HTREEITEM item);
 void API dw_tree_item_collapse(HWND handle, HTREEITEM item);
 void API dw_tree_item_select(HWND handle, HTREEITEM item);
@@ -1013,14 +1576,18 @@
 char * API dw_tree_get_title(HWND handle, HTREEITEM item);
 HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item);
 int API dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator);
-unsigned long API dw_icon_load(unsigned long module, unsigned long id);
-unsigned long API dw_icon_load_from_file(char *filename);
-void API dw_icon_free(unsigned long handle);
+HICN API dw_icon_load(unsigned long module, unsigned long id);
+HICN API dw_icon_load_from_file(char *filename);
+HICN API dw_icon_load_from_data(char *data, int len);
+void API dw_icon_free(HICN handle);
 void * API dw_container_alloc(HWND handle, int rowcount);
 void API dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data);
 void API dw_container_change_item(HWND handle, int column, int row, void *data);
 void API dw_container_set_column_width(HWND handle, int column, int width);
 void API dw_container_set_row_title(void *pointer, int row, char *title);
+void API dw_container_change_row_title(HWND handle, int row, char *title);
+#define dw_container_set_row_data(a, b, c) dw_container_set_row_title(a, b, (char *)c)
+#define dw_container_change_row_data(a, b, c) dw_container_change_row_title(a, b, (char *)c)
 void API dw_container_insert(HWND handle, void *pointer, int rowcount);
 void API dw_container_clear(HWND handle, int redraw);
 void API dw_container_delete(HWND handle, int rowcount);
@@ -1030,15 +1597,16 @@
 void API dw_container_cursor(HWND handle, char *text);
 void API dw_container_delete_row(HWND handle, char *text);
 void API dw_container_optimize(HWND handle);
+void API dw_container_set_stripe(HWND handle, unsigned long oddcolor, unsigned long evencolor);
 int API dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count);
 void API dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data);
-void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, unsigned long icon);
+void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, HICN icon);
 void API dw_filesystem_change_item(HWND handle, int column, int row, void *data);
-void API dw_filesystem_change_file(HWND handle, int row, char *filename, unsigned long icon);
+void API dw_filesystem_change_file(HWND handle, int row, char *filename, HICN icon);
 int API dw_container_get_column_type(HWND handle, int column);
 int API dw_filesystem_get_column_type(HWND handle, int column);
-void API dw_taskbar_insert(HWND handle, unsigned long icon, char *bubbletext);
-void API dw_taskbar_delete(HWND handle, unsigned long icon);
+void API dw_taskbar_insert(HWND handle, HICN icon, char *bubbletext);
+void API dw_taskbar_delete(HWND handle, HICN icon);
 int API dw_screen_width(void);
 int API dw_screen_height(void);
 unsigned long API dw_color_depth_get(void);
@@ -1056,7 +1624,9 @@
 HMENUI API dw_menu_new(unsigned long id);
 HMENUI API dw_menubar_new(HWND location);
 HWND API dw_menu_append_item(HMENUI menu, char *title, unsigned long id, unsigned long flags, int end, int check, HMENUI submenu);
+int API dw_menu_delete_item(HMENUI menu, unsigned long id);
 void API dw_menu_item_set_check(HMENUI menu, unsigned long id, int check);
+void API dw_menu_item_set_state( HMENUI menux, unsigned long id, unsigned long state);
 void API dw_menu_popup(HMENUI *menu, HWND parent, int x, int y);
 void API dw_menu_destroy(HMENUI *menu);
 void API dw_pointer_query_pos(long *x, long *y);
@@ -1066,6 +1636,7 @@
 HMTX API dw_mutex_new(void);
 void API dw_mutex_close(HMTX mutex);
 void API dw_mutex_lock(HMTX mutex);
+int API dw_mutex_trylock(HMTX mutex);
 void API dw_mutex_unlock(HMTX mutex);
 HEV API dw_event_new(void);
 int API dw_event_reset(HEV eve);
@@ -1080,18 +1651,27 @@
 void API dw_color_foreground_set(unsigned long value);
 void API dw_color_background_set(unsigned long value);
 unsigned long API dw_color_choose(unsigned long value);
+char * API dw_font_choose(char *currfont);
 void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y);
 void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2);
 void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height);
+void API dw_draw_polygon(HWND handle, HPIXMAP pixmap, int fill, int npoints, int *x, int *y);
+void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2);
 void API dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text);
 void API dw_font_text_extents_get(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height);
+void API dw_font_set_default(char *fontname);
 void API dw_flush(void);
 void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc);
+int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight);
 HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth);
 HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename);
+HPIXMAP API dw_pixmap_new_from_data(HWND handle, char *data, int len);
 HPIXMAP API dw_pixmap_grab(HWND handle, ULONG id);
+void API dw_pixmap_set_transparent_color( HPIXMAP pixmap, ULONG color );
+int API dw_pixmap_set_font(HPIXMAP pixmap, char *fontname);
 void API dw_pixmap_destroy(HPIXMAP pixmap);
 void API dw_beep(int freq, int dur);
+void API dw_debug(char *format, ...);
 int API dw_messagebox(char *title, int flags, char *format, ...);
 void API dw_environment_query(DWEnv *env);
 int API dw_exec(char *program, int type, char **params);
@@ -1121,5 +1701,17 @@
 HSHM API dw_named_memory_new(void **dest, int size, char *name);
 HSHM API dw_named_memory_get(void **dest, int size, char *name);
 int API dw_named_memory_free(HSHM handle, void *ptr);
+void API dw_html_action(HWND hwnd, int action);
+int API dw_html_raw(HWND hwnd, char *string);
+int API dw_html_url(HWND hwnd, char *url);
+HWND API dw_html_new(unsigned long id);
+char * API dw_clipboard_get_text(void);
+void API dw_clipboard_set_text( char *str, int len );
+HWND API dw_calendar_new(unsigned long id);
+void API dw_calendar_set_date( HWND window, unsigned int year, unsigned int month, unsigned int day );
+void API dw_calendar_get_date( HWND window, unsigned int *year, unsigned int *month, unsigned int *day );
+HPRINT API dw_print_new(char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata);
+int API dw_print_run(HPRINT print, unsigned long flags);
+void API dw_print_cancel(HPRINT print);
 
 #endif
--- a/filter_plug.h	Fri Feb 18 02:50:18 2011 -0600
+++ b/filter_plug.h	Thu Nov 24 03:45:48 2011 -0600
@@ -1,23 +1,42 @@
-#if __cplusplus
+#ifndef PM123_FILTER_PLUG_H
+#define PM123_FILTER_PLUG_H
+
+#include "format.h"
+
+#ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef struct {
-   int size;
+#pragma pack(4)
+
+#define PARAMS_SIZE_1 24  /* size of the FILTER_PARAMS structure prior PM123 1.32 */
+#define PARAMS_SIZE_2 32  /* size of the FILTER_PARAMS structure since PM123 1.32 */
+
+typedef struct _FILTER_PARAMS
+{
+  int size;
 
-   /* specify a function which the filter should use for output */
-   int (* _System output_play_samples)(void *a, FORMAT_INFO *format, char *buf, int len, int posmarker);
-   void *a; /* only to be used with the precedent function */
-   int audio_buffersize;
+  /* specify a function which the filter should use for output */
+  int  (DLLENTRYP output_play_samples)( void* a, FORMAT_INFO* format, char* buf, int len, int posmarker );
+  void* a;  /* only to be used with the precedent function */
+  int   audio_buffersize;
+
+  /* error message function the filter plug-in should use */
+  void (DLLENTRYP error_display)( char* );
 
-   /* error message function the filter plug-in should use */
-   void (* _System error_display)(char *);
+  /* info message function the filter plug-in should use */
+  /* this information is always displayed to the user right away */
+  void (DLLENTRYP info_display)( char* );
+
+  /* added since PM123 1.32 */
+  int   (DLLENTRYP pm123_getstring)( int index, int subindex, int bufsize, char* buf );
+  void  (DLLENTRYP pm123_control)( int index, void* param );
 
 } FILTER_PARAMS;
 
 /* returns 0 -> ok */
-ULONG _System filter_init(void **f, FILTER_PARAMS *params);
-BOOL _System filter_uninit(void *f);
+ULONG DLLENTRY filter_init  ( void** f, FILTER_PARAMS* params );
+BOOL  DLLENTRY filter_uninit( void*  f );
 
 
 /* Notice it is the same parameters as output_play_samples()  */
@@ -25,9 +44,11 @@
 /* a filter plug-in or directly in an output plug-in          */
 /* BUT you will have to pass void *a from above to the next   */
 /* stage which will be either a filter or output              */
-int _System filter_play_samples(void *f, FORMAT_INFO *format, char *buf,int len, int posmarker);
+int  DLLENTRY filter_play_samples( void* f, FORMAT_INFO* format, char* buf, int len, int posmarker );
 
+#pragma pack()
 
-#if __cplusplus
+#ifdef __cplusplus
 }
 #endif
+#endif /* PM123_FILTER_PLUG_H */
--- a/format.h	Fri Feb 18 02:50:18 2011 -0600
+++ b/format.h	Thu Nov 24 03:45:48 2011 -0600
@@ -1,22 +1,47 @@
-/* AFAIK, all of those also have BitsPerSample as format specific */
-#define WAVE_FORMAT_PCM       0x0001
-#define WAVE_FORMAT_ADPCM     0x0002
-#define WAVE_FORMAT_ALAW      0x0006
-#define WAVE_FORMAT_MULAW     0x0007
-#define WAVE_FORMAT_OKI_ADPCM 0x0010
-#define WAVE_FORMAT_DIGISTD   0x0015
-#define WAVE_FORMAT_DIGIFIX   0x0016
-#define IBM_FORMAT_MULAW      0x0101
-#define IBM_FORMAT_ALAW       0x0102
-#define IBM_FORMAT_ADPCM      0x0103
+#ifndef  PM123_FORMAT_H
+#define  PM123_FORMAT_H
+
+#include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma pack(4)
 
-typedef struct
+#define WM_PLAYSTOP         (WM_USER +  69)
+#define WM_PLAYERROR        (WM_USER + 100)
+#define WM_SEEKSTOP         (WM_USER + 666)
+#define WM_METADATA         (WM_USER +  42)
+#define WM_CHANGEBR         (WM_USER +  43)
+#define WM_OUTPUT_OUTOFDATA (WM_USER + 667)
+#define WM_PLUGIN_CONTROL   (WM_USER + 668) /* Plugin notify message */
+
+/*
+ * WM_PLUGIN_CONTROL
+ *   LONGFROMMP(mp1) = notify code
+ *   LONGFROMMP(mp2) = additional information
+ *
+ * Notify codes:
+*/
+
+#define PN_TEXTCHANGED  1   /* Display text changed */
+
+#define WAVE_FORMAT_PCM 0x0001
+
+typedef struct _FORMAT_INFO
 {
   int size;
-
   int samplerate;
   int channels;
   int bits;
-  int format; // PCM = 1
+  int format; /* WAVE_FORMAT_PCM = 1 */
+
 } FORMAT_INFO;
 
+#pragma pack()
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* PM123_FORMAT_H */
--- a/nuclear.c	Fri Feb 18 02:50:18 2011 -0600
+++ b/nuclear.c	Thu Nov 24 03:45:48 2011 -0600
@@ -15,8 +15,11 @@
 #include <stdio.h>
 #include <math.h>
 #include <stdlib.h>
+
+#include "config.h"
 #include "format.h"
 #include "decoder_plug.h"
+#include "visual_plug.h"
 #include "plugin.h"
 
 #define FULL_CLEAR
@@ -25,9 +28,9 @@
 
 #define strcasecmp stricmp
 
-PLUGIN_PROCS procs;
-int (* _System specana_init)(int setnumsamples);
-int (* _System specana_dobands)(float bands[]);
+VISPLUGININIT plug;
+static  ULONG (DLLENTRYP decoderPlayingSamples)( FORMAT_INFO *info, char *buf, int len );
+static  BOOL  (DLLENTRYP decoderPlaying)( void );
 
 void DiveInit(void);
 void DiveShutdown(void);
@@ -70,7 +73,7 @@
 HDC hdcClient;
 HPS hpsDive;
 
-int _System plugin_query(PPLUGIN_QUERYPARAM param)
+void DLLENTRY plugin_query(PPLUGIN_QUERYPARAM param)
 {
 	param->type         = PLUGIN_VISUAL; /* Identify the plugin as visual */
 
@@ -82,8 +85,6 @@
 
 	param->configurable = TRUE;
 	/* Toggles plugin configurability via PM123 Properties dialog */
-
-	return 0;
 }
 
 /* Write the nuclear.ini file with all of the current settings */
@@ -321,7 +322,7 @@
 	/* Find the ideal number of bars (bands) for our analyzer */
 	while(bands < wantedsamples)
 	{
-		bands = specana_init(z);
+		bands = init_bands(z);
 		z++;
 		if(z < 1 || z > 4097)
 		{
@@ -381,7 +382,7 @@
 		update_analyzer(handles);
 }
 
-int _System plugin_configure(HWND hwnd, HMODULE module)
+void DLLENTRY plugin_configure(HWND hwnd, HMODULE module)
 {
 	HWND entrywindow, mainbox, vbox, cancelbutton, okbutton, buttonbox,
 	applybutton, xbox, stext, winbox, groupbox, notebook,
@@ -619,7 +620,7 @@
     return 0;
 }
 
-int _System plugin_deinit(int unload)
+int DLLENTRY plugin_deinit(void)
 {
 	if(usedive)
 		DiveShutdown();
@@ -741,7 +742,7 @@
 	float scale;
 	HPS hps = WinGetPS(hwnd);
 
-	max = specana_dobands(current);
+	max = do_bands();
 
 	if(boost)
 		scale = (float)max/(cy*boostval);
@@ -996,7 +997,7 @@
 	int z, max;
 	float scale;
 
-	max = specana_dobands(current);
+	max = do_bands();
 
 	if(boost)
 		scale = (float)max/(cy*boostval);
@@ -1145,7 +1146,7 @@
 		break;
 
 	case WM_TIMER:
-		if(procs.decoder_playing())
+		if(decoderPlaying())
 		{
 			if(usedive)
 				DiveRender(hwnd);
@@ -1224,7 +1225,7 @@
 	return WinDefWindowProc (hwnd, msg, mp1, mp2);
 }
 
-HWND _System vis_init(PVISPLUGININIT initdata)
+HWND DLLENTRY vis_init(PVISPLUGININIT initdata)
 {
 	int z = 1, wantedsamples;
 	SIZEL sizl;
@@ -1258,9 +1259,9 @@
 	hwndPM123 = initdata->hwnd;
 
 	/* Save copies of the function pointers for our use */
-	memcpy(&procs, initdata->procs, sizeof(PLUGIN_PROCS));
-	specana_init = initdata->procs->specana_init;
-	specana_dobands = initdata->procs->specana_dobands;
+	memcpy(&plug, initdata, sizeof( VISPLUGININIT));
+	decoderPlayingSamples = initdata->procs->output_playing_samples;
+	decoderPlaying        = initdata->procs->decoder_playing;
 
 	cx = initdata->cx;
 	cy = initdata->cy;
@@ -1274,7 +1275,7 @@
 	/* Find the ideal number of bars (bands) for our analyzer */
 	while(bands < wantedsamples)
 	{
-		bands = specana_init(z);
+		bands = init_bands(z);
 		z++;
 		if(z < 1 || z > 4097)
 		{
--- a/output_plug.h	Fri Feb 18 02:50:18 2011 -0600
+++ b/output_plug.h	Thu Nov 24 03:45:48 2011 -0600
@@ -1,56 +1,94 @@
+#ifndef PM123_OUTPUT_PLUG_H
+#define PM123_OUTPUT_PLUG_H
 
-#define WM_PLAYERROR          WM_USER+100
-#define WM_OUTPUT_OUTOFDATA   WM_USER+667
+#include "format.h"
+#include "decoder_plug.h"
 
-ULONG _System output_init(void **a);
-ULONG _System output_uninit(void *a);
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-#define OUTPUT_OPEN          1 // may not be necessary!
+#pragma pack(4)
+
+ULONG DLLENTRY output_init  ( void** a );
+ULONG DLLENTRY output_uninit( void*  a );
+
+#define OUTPUT_OPEN          1 /* may not be necessary! */
 #define OUTPUT_CLOSE         2
 #define OUTPUT_VOLUME        3
 #define OUTPUT_PAUSE         4
 #define OUTPUT_SETUP         5
 #define OUTPUT_TRASH_BUFFERS 6
-#define OUTPUT_NOBUFFERMODE  7
+#define OUTPUT_NOBUFFERMODE  7 /* obsolete, don't used anymore */
 
-typedef struct
+#define OUTPUT_SIZE_1       76 /* size of the OUTPUT_PARAMS structure prior PM123 1.32 */
+#define OUTPUT_SIZE_2       80 /* size of the OUTPUT_PARAMS structure since PM123 1.32 */
+#define OUTPUT_SIZE_3       84 /* size of the OUTPUT_PARAMS structure since PM123 1.33 */
+
+typedef struct _OUTPUT_PARAMS
 {
-   int size;
+  /* --- see OUTPUT_SIZE definitions */
+  int size;
 
   /* --- OUTPUT_SETUP */
 
-   FORMAT_INFO formatinfo;
+  FORMAT_INFO formatinfo;
 
-   int buffersize;
+  int buffersize;
+
+  unsigned short boostclass, normalclass;
+  signed   short boostdelta, normaldelta;
 
-   unsigned short boostclass, normalclass;
-   signed   short boostdelta, normaldelta;
+  void (DLLENTRYP error_display)( char* );
 
-   void (* _System error_display)(char *);
+  /* info message function the output plug-in should use */
+  /* this information is always displayed to the user right away */
+  void (DLLENTRYP info_display)( char* );
 
-   HWND hwnd; // commodity for PM interface, sends a few messages to this handle
+  HWND hwnd; /* commodity for PM interface, sends a few messages to this handle. */
 
   /* --- OUTPUT_VOLUME */
 
-   char volume;
-   float amplifier;
+  unsigned char volume;
+  float amplifier;
 
   /* --- OUTPUT_PAUSE */
 
-   BOOL pause;
-
-  /* --- OUTPUT_NOBUFFERMODE */
-
-   BOOL nobuffermode;
+  BOOL  pause;
+  BOOL  unused1;          /* obsolete, must be NULL */
 
   /* --- OUTPUT_TRASH_BUFFERS */
 
-   ULONG temp_playingpos; // used until new buffers come in
+  ULONG temp_playingpos;  /* used until new buffers come in */
+
+  /* --- OUTPUT_OPEN */
+
+  char* filename;         /* filename, URL or track now being played,
+                             useful for disk output */
+
+  /* --- OUTPUT_SETUP */
+
+  BOOL  always_hungry;    /* *OUTPUT* the output plug-in imposes no time restraint
+                             it is always WM_OUTPUT_OUTOFDATA */
+
+  DECODER_INFO* info;     /* added since PM123 1.32 */
+
+  /* Added since PM123 1.33. Output plug-in should call this
+     function for sound equalization. */
+
+  int (DLLENTRYP equalize_samples)( FORMAT_INFO*, char* buf, int len );
 
 } OUTPUT_PARAMS;
-ULONG _System output_command(void *a, ULONG msg, OUTPUT_PARAMS *info);
+
+ULONG DLLENTRY output_command( void* a, ULONG msg, OUTPUT_PARAMS* info );
+ULONG DLLENTRY output_playing_samples( void* a, FORMAT_INFO* info, char* buf, int len );
+int   DLLENTRY output_play_samples( void* a, FORMAT_INFO* format, char* buf, int len, int posmarker );
+ULONG DLLENTRY output_playing_pos( void* a );
+BOOL  DLLENTRY output_playing_data( void* a );
 
-ULONG _System output_playing_samples(void *a, FORMAT_INFO *info, char *buf, int len);
-int _System output_play_samples(void *a, FORMAT_INFO *format, char *buf,int len, int posmarker);
-ULONG _System output_playing_pos(void *a);
-BOOL _System output_playing_data(void *a);
+#pragma pack()
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* PM123_OUTPUT_PLUG_H */
--- a/plugin.h	Fri Feb 18 02:50:18 2011 -0600
+++ b/plugin.h	Thu Nov 24 03:45:48 2011 -0600
@@ -1,9 +1,7 @@
+#ifndef PM123_PLUGIN_H
+#define PM123_PLUGIN_H
 
-/*
-   PM123 Plugin Definitions
-   Copyright (C) 1998 Taneli Lepp„ <rosmo@kalja.com>
-                      Samuel Audet <guardia@cam.org>
-*/
+#include "format.h"
 
 #define PLUGIN_NULL    0x000
 #define PLUGIN_VISUAL  0x001
@@ -11,82 +9,61 @@
 #define PLUGIN_DECODER 0x004
 #define PLUGIN_OUTPUT  0x008
 
-/* see decoder_plug.h and output_plug.h for more information
-   on some of these functions */
-typedef struct {
-  ULONG (* _System output_playing_samples)(FORMAT_INFO *info, char *buf, int len);
-  BOOL  (* _System decoder_playing)();
-  ULONG (* _System output_playing_pos)();
-  ULONG (* _System decoder_status)();
-  ULONG (* _System decoder_command)(ULONG msg, DECODER_PARAMS *params);
-  /* name is the DLL filename of the decoder that can play that file */
-  ULONG (* _System decoder_fileinfo)(char *filename, DECODER_INFO *info, char *name);
+#define PLUGIN_OK           0
+#define PLUGIN_UNSUPPORTED  1
+#define PLUGIN_NO_READ      100
+#define PLUGIN_NO_PLAY      200
+#define PLUGIN_GO_ALREADY   101
+#define PLUGIN_GO_FAILED    102
+#define PLUGIN_FAILED      -1
+#define PLUGIN_NO_USABLE   -2
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-  PFN specana_init;
-  /* int specana_init(int setnumsamples);
-     Returns the number of bands in return (setnumsamples/2+1).
-  */
-  PFN specana_dobands;
-  /*
-     int specana_dobands(float bands[]);
-     Returns the max value.
-  */
-  PFN pm123_getstring;
-  PFN pm123_control;
+#pragma pack(4)
 
-  /* name is the DLL filename of the decoder that can play that track */
-  ULONG (* _System decoder_trackinfo)(char *drive, int track, DECODER_INFO *info, char *name);
-  ULONG (* _System decoder_cdinfo)(char *drive, DECODER_CDINFO *info);
-  ULONG (* _System decoder_length)();
+typedef struct _PLUGIN_QUERYPARAM
+{
+  int   type;         /* null, visual, filter, input. values can be ORed */
+  char* author;       /* Author of the plugin                            */
+  char* desc;         /* Description of the plugin                       */
+  int   configurable; /* Is the plugin configurable                      */
 
-} PLUGIN_PROCS, *PPLUGIN_PROCS;
+} PLUGIN_QUERYPARAM, *PPLUGIN_QUERYPARAM;
+
+void DLLENTRY plugin_query( PLUGIN_QUERYPARAM* param );
+void DLLENTRY plugin_configure( HWND hwnd, HMODULE module );
+
+#pragma pack()
 
 /*
-  int pm123_getstring(int index, int subindex, int bufsize, char *buf)
-
-    index    - which string (see STR_* defines below)
-    subindex - not currently used
-    bufsize  - bytes in buf
-    buf      - buffer for the string
-*/
+ * int pm123_getstring( int index, int subindex, int bufsize, char* buf )
+ *
+ *  index    - which string (see STR_* defines below)
+ *  subindex - not currently used
+ *  bufsize  - bytes in buf
+ *  buf      - buffer for the string
+ */
 
 #define STR_NULL         0
 #define STR_VERSION      1 /* PM123 version          */
-#define STR_DISPLAY_TEXT 2 /* Display text           */
+#define STR_DISPLAY_TEXT 2 /* Displayed text         */
 #define STR_FILENAME     3 /* Currently loaded file  */
+#define STR_DISPLAY_TAG  4 /* Displayed song info    */
+#define STR_DISPLAY_INFO 5 /* Displayed tech info    */
 
 /*
-  int pm123_control(int index, void *param);
-
-    index - operation
-    param - parameter for the operation
-*/
-#define CONTROL_NEXTMODE 1  /* Next display mode */
-
-typedef struct {
-  int           x, y, cx, cy;   /* Input        */
-  HWND          hwnd;           /* Input/Output */
-  PPLUGIN_PROCS procs;          /* Input        */
-  int           id;             /* Input        */
-  char          *param;         /* Input        */
-  HAB           hab;            /* Input        */
-} VISPLUGININIT, *PVISPLUGININIT;
+ * int pm123_control( int index, void* param );
+ *
+ *  index - operation
+ *  param - parameter for the operation
+ */
 
-typedef struct
-{
- int  type;         /* null, visual, filter, input. values can be ORred */
- char *author;      /* Author of the plugin                             */
- char *desc;        /* Description of the plugin                        */
- int  configurable; /* Is the plugin configurable                       */
-} PLUGIN_QUERYPARAM, *PPLUGIN_QUERYPARAM;
-
+#define CONTROL_NEXTMODE 1 /* Next display mode */
 
-/* Plugin notify message */
-#define WM_PLUGIN_CONTROL (WM_USER + 666)
-/*
-   WM_PLUGIN_CONTROL
-     LONGFROMMP(mp1) = notify code
-     LONGFROMMP(mp2) = additional information
-*/
-/* Notify codes */
-#define PN_TEXTCHANGED  1   /* Display text changed */
+#ifdef __cplusplus
+}
+#endif
+#endif /* PM123_PLUGIN_H */