changeset 14:176cee043f1b

Lots of Windows and Unix bug fixes.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 11 Jul 2001 21:57:56 +0000
parents 156281539fb3
children 81833f25b1aa
files dw.def dw.h dww.def gtk/dw.c os2/dw.c win/dw.c
diffstat 6 files changed, 322 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/dw.def	Fri Jul 06 13:36:38 2001 +0000
+++ b/dw.def	Wed Jul 11 21:57:56 2001 +0000
@@ -28,6 +28,7 @@
   dw_box_pack_end                        @43
   dw_box_pack_splitbar_start             @44
   dw_box_pack_splitbar_end               @45
+  dw_mdi_new                             @46
 
   dw_window_new                          @50
   dw_window_show                         @51
@@ -52,6 +53,7 @@
   dw_window_function                     @70
   dw_window_from_id                      @71
   dw_window_set_border                   @72
+  dw_window_minimize                     @73
 
   dw_bitmap_new                          @80
 
--- a/dw.h	Fri Jul 06 13:36:38 2001 +0000
+++ b/dw.h	Wed Jul 11 21:57:56 2001 +0000
@@ -542,21 +542,23 @@
 void dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad);
 void dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad);
 #if !defined(__OS2__) && !defined(__WIN32__)
-int dw_int_init(DWResources *res, int newthread);
-#define dw_init(a) dw_int_init(&_resources, a)
+int dw_int_init(DWResources *res, int newthread, int argc, char *argv[]);
+#define dw_init(a, b, c) dw_int_init(&_resources, a, b, c)
 #else
-int dw_init(int newthread);
+int dw_init(int newthread, int argc, char *argv[]);
 #endif
 void dw_main(HAB currenthab, void *filterfunc);
 void dw_free(void *ptr);
 int dw_window_show(HWND handle);
 int dw_window_hide(HWND handle);
+int dw_window_minimize(HWND handle);
 int dw_window_destroy(HWND handle);
 int dw_window_set_font(HWND handle, char *fontname);
 int dw_window_set_color(HWND handle, unsigned long fore, unsigned long back);
 HWND dw_window_new(HWND hwndOwner, char *title, unsigned long flStyle);
 HWND dw_box_new(int type, int pad);
 HWND dw_groupbox_new(int type, int pad, char *title);
+HWND dw_mdi_new(unsigned long id);
 HWND dw_bitmap_new(unsigned long id);
 HWND dw_bitmapbutton_new(char *text, unsigned long id);
 HWND dw_container_new(unsigned long id);
--- a/dww.def	Fri Jul 06 13:36:38 2001 +0000
+++ b/dww.def	Wed Jul 11 21:57:56 2001 +0000
@@ -25,6 +25,7 @@
   dw_box_pack_end                        @43
   dw_box_pack_splitbar_start             @44
   dw_box_pack_splitbar_end               @45
+  dw_mdi_new                             @46
 
   dw_window_new                          @50
   dw_window_show                         @51
@@ -49,6 +50,7 @@
   dw_window_function                     @70
   dw_window_from_id                      @71
   dw_window_set_border                   @72
+  dw_window_minimize                     @73
 
   dw_bitmap_new                          @80
 
--- a/gtk/dw.c	Fri Jul 06 13:36:38 2001 +0000
+++ b/gtk/dw.c	Wed Jul 11 21:57:56 2001 +0000
@@ -51,7 +51,7 @@
 GdkColor _background = { 0, 0xaaaa, 0xaaaa, 0xaaaa };
 
 char *_dw_browse_file = NULL;
-int _dw_file_active = 0, _dw_file_ready = 0;
+int _dw_file_active = 0, _dw_file_ready = 0, _dw_ignore_click = 0;
 pthread_t _dw_thread = (pthread_t)-1;
 int _dw_mutex_locked = FALSE;
 
@@ -63,6 +63,10 @@
 #define USE_IMLIB
 #endif
 
+#define DEFAULT_SIZE_WIDTH 12
+#define DEFAULT_SIZE_HEIGHT 6
+#define DEFAULT_TITLEBAR_HEIGHT 22
+
 GdkColormap *_dw_cmap = NULL;
 
 /* Signal forwarder prototypes */
@@ -78,6 +82,7 @@
 void _container_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data);
 void _item_select_event(GtkWidget *widget, GtkWidget *child, gpointer data);
 void _expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data);
+void _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data);
 
 typedef struct
 {
@@ -94,7 +99,7 @@
 
 } SignalHandler;
 
-#define SIGNALMAX 12
+#define SIGNALMAX 13
 
 /* A list of signal forwarders, to account for paramater differences. */
 SignalList SignalTranslate[SIGNALMAX] = {
@@ -109,7 +114,8 @@
 	{ _generic_event, "clicked" },
 	{ _container_select_event, "container-select" },
 	{ _container_context_event, "container-context" },
-	{ _item_select_event, "item-select" }
+	{ _item_select_event, "item-select" },
+	{ _set_focus_event, "set-focus" }
 };
 
 /* Finds the translation function for a given signal name */
@@ -125,6 +131,18 @@
 	return NULL;
 }
 
+void _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data)
+{
+	SignalHandler *work = (SignalHandler *)data;
+
+	if(work)
+	{
+		int (*setfocusfunc)(HWND, void *) = work->func;
+
+		setfocusfunc((HWND)window, work->data);
+	}
+}
+
 gint _button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
 {
 	SignalHandler *work = (SignalHandler *)data;
@@ -188,7 +206,7 @@
 			keys |= DW_BUTTON2_MASK;
 		if (state & GDK_BUTTON2_MASK)
 			keys |= DW_BUTTON3_MASK;
-   
+
 		motionfunc(widget, x, y, keys, work->data);
 	}
 	return TRUE;
@@ -237,7 +255,7 @@
 {
 	SignalHandler *work = (SignalHandler *)data;
 
-	if(work)
+	if(work && !_dw_ignore_click)
 	{
 		void (*activatefunc)(HWND, void *) = work->func;
 
@@ -429,7 +447,7 @@
  *           newthread: True if this is the only thread.
  *                      False if there is already a message loop running.
  */
-int dw_int_init(DWResources *res, int newthread)
+int dw_int_init(DWResources *res, int newthread, int argc, char *argv[])
 {
 	int z;
 
@@ -441,7 +459,8 @@
 	}
 	gtk_set_locale();
 	g_thread_init(NULL);
-	gtk_init(0, NULL);
+
+	gtk_init(&argc, &argv);
 #ifdef USE_IMLIB
 	gdk_imlib_init();
 #endif
@@ -604,6 +623,26 @@
 }
 
 /*
+ * Minimizes or Iconifies a top-level window.
+ * Parameters:
+ *           handle: The window handle to minimize.
+ */
+int dw_window_minimize(HWND handle)
+{
+	int _locked_by_me = FALSE;
+
+	if(!handle)
+		return 0;
+
+	DW_MUTEX_LOCK;
+	XIconifyWindow(GDK_WINDOW_XDISPLAY(GTK_WIDGET(handle)->window),
+				   GDK_WINDOW_XWINDOW(GTK_WIDGET(handle)->window),
+				   DefaultScreen (GDK_DISPLAY ()));
+	DW_MUTEX_UNLOCK;
+	return 0;
+}
+
+/*
  * Makes the window visible.
  * Parameters:
  *           handle: The window handle to make visible.
@@ -617,6 +656,10 @@
 
 	DW_MUTEX_LOCK;
 	gtk_widget_show(handle);
+	gdk_window_raise(GTK_WIDGET(handle)->window);
+	gdk_flush();
+	gdk_window_show(GTK_WIDGET(handle)->window);
+	gdk_flush();
 	DW_MUTEX_UNLOCK;
 	return 0;
 }
@@ -665,7 +708,11 @@
  */
 void dw_window_reparent(HWND handle, HWND newparent)
 {
-	gtk_widget_reparent(handle, newparent);
+	int _locked_by_me = FALSE;
+
+	DW_MUTEX_LOCK;
+	gdk_window_reparent(GTK_WIDGET(handle)->window, newparent ? GTK_WIDGET(newparent)->window : GDK_ROOT_PARENT(), 0, 0);
+	DW_MUTEX_UNLOCK;
 }
 
 int _set_font(HWND handle, char *fontname)
@@ -719,29 +766,86 @@
 	return TRUE;
 }
 
+void _free_gdk_colors(HWND handle)
+{
+	GdkColor *old = (GdkColor *)gtk_object_get_data(GTK_OBJECT(handle), "foregdk");
+
+	if(old)
+		free(old);
+
+	old = (GdkColor *)gtk_object_get_data(GTK_OBJECT(handle), "backgdk");
+
+	if(old)
+		free(old);
+}
+
+/* Free old color pointers and allocate new ones */
+void _save_gdk_colors(HWND handle, GdkColor fore, GdkColor back)
+{
+	GdkColor *foregdk = malloc(sizeof(GdkColor));
+	GdkColor *backgdk = malloc(sizeof(GdkColor));
+
+	_free_gdk_colors(handle);
+
+	*foregdk = fore;
+	*backgdk = back;
+
+	gtk_object_set_data(GTK_OBJECT(handle), "foregdk", (gpointer)foregdk);
+	gtk_object_set_data(GTK_OBJECT(handle), "backgdk", (gpointer)backgdk);
+}
+
 int _set_color(HWND handle, unsigned long fore, unsigned long back)
 {
 	GtkStyle *style;
 
 	if(fore & DW_RGB_COLOR || back & DW_RGB_COLOR)
 	{
+		/* Remember that each color component in X11 use 16 bit no matter
+		 * what the destination display supports. (and thus GDK)
+		 */
 		GdkColor forecolor = { 0, DW_RED_VALUE(fore) << 8, DW_GREEN_VALUE(fore) << 8, DW_BLUE_VALUE(fore) << 8 };
 		GdkColor backcolor = { 0, DW_RED_VALUE(back) << 8, DW_GREEN_VALUE(back) << 8, DW_BLUE_VALUE(back) << 8 };
 
 		gdk_color_alloc(_dw_cmap, &forecolor);
 		gdk_color_alloc(_dw_cmap, &backcolor);
 
-		style = gtk_widget_get_style(handle);
-		style->fg[1] = style->fg[0] = forecolor;
+		style = gtk_style_copy(gtk_widget_get_style(handle));
+		style->text[0] = style->text[1] = style->fg[0] = style->fg[1] = forecolor;
 		style->base[0] = style->base[1] = style->bg[0] = style->bg[1] = backcolor;
 		gtk_widget_set_style(handle, style);
+
+		_save_gdk_colors(handle, forecolor, backcolor);
+
+		if(GTK_IS_CLIST(handle))
+		{
+			int z, rowcount = (int)gtk_object_get_data(GTK_OBJECT(handle), "rowcount");
+
+			for(z=0;z<rowcount;z++)
+			{
+				gtk_clist_set_foreground(GTK_CLIST(handle), z, &forecolor);
+				gtk_clist_set_background(GTK_CLIST(handle), z, &backcolor);
+			}
+		}
 	}
 	else
 	{
-		style = gtk_widget_get_style(handle);
-		style->fg[1] = style->fg[0] = _colors[fore];
+		style = gtk_style_copy(gtk_widget_get_style(handle));
+		style->text[0] = style->text[1] = style->fg[0] = style->fg[1] = _colors[fore];
 		style->base[0] = style->base[1] = style->bg[0] = style->bg[1] = _colors[back];
 		gtk_widget_set_style(handle, style);
+
+		_save_gdk_colors(handle, _colors[fore], _colors[back]);
+
+		if(GTK_IS_CLIST(handle))
+		{
+			int z, rowcount = (int)gtk_object_get_data(GTK_OBJECT(handle), "rowcount");
+
+			for(z=0;z<rowcount;z++)
+			{
+				gtk_clist_set_foreground(GTK_CLIST(handle), z, &_colors[fore]);
+				gtk_clist_set_background(GTK_CLIST(handle), z, &_colors[back]);
+			}
+		}
 	}
 
 	return TRUE;
@@ -773,10 +877,6 @@
 			handle2 = tmp;
 	}
 
-
-	gtk_object_set_data(GTK_OBJECT(handle2), "fore", (gpointer)fore);
-	gtk_object_set_data(GTK_OBJECT(handle2), "back", (gpointer)back);
-
 	_set_color(handle2, fore, back);
 
 	DW_MUTEX_UNLOCK;
@@ -832,7 +932,7 @@
 {
 	GtkWidget *tmp;
 	int _locked_by_me = FALSE;
-	int flags = 0;
+	int flags = 0, cx = 0, cy = 0;
 
 	DW_MUTEX_LOCK;
 	tmp = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@@ -844,18 +944,30 @@
 	gtk_widget_realize(tmp);
 
 	if(flStyle & DW_FCF_TITLEBAR)
+	{
+		cy += DEFAULT_TITLEBAR_HEIGHT;
 		flags |= GDK_DECOR_TITLE;
+	}
 
 	if(flStyle & DW_FCF_MINMAX)
 		flags |= GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE;
 
 	if(flStyle & DW_FCF_SIZEBORDER)
+	{
+		cy += DEFAULT_SIZE_HEIGHT;
+		cx += DEFAULT_SIZE_WIDTH;
 		flags |= GDK_DECOR_RESIZEH;
+	}
 
 	if(flStyle & DW_FCF_BORDER)
 		flags |= GDK_DECOR_BORDER;
 
 	gdk_window_set_decorations(tmp->window, flags);
+	gtk_object_set_data(GTK_OBJECT(tmp), "cx", (gpointer)cx);
+	gtk_object_set_data(GTK_OBJECT(tmp), "cy", (gpointer)cy);
+
+	if(hwndOwner)
+		gdk_window_reparent(GTK_WIDGET(tmp)->window, GTK_WIDGET(hwndOwner)->window, 0, 0);
 
 	DW_MUTEX_UNLOCK;
 	return tmp;
@@ -895,6 +1007,16 @@
 }
 
 /*
+ * Create a new MDI Frame to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id or 0L.
+ */
+HWND dw_mdi_new(unsigned long id)
+{
+	return gtk_vbox_new(FALSE, 0);
+}
+
+/*
  * Create a bitmap object to be packed.
  * Parameters:
  *       id: An ID to be used with WinWindowFromID() or 0L.
@@ -1180,8 +1302,10 @@
 
 	if(tmphandle)
 	{
+		_dw_ignore_click = 1;
 		if(GTK_CHECK_MENU_ITEM(tmphandle)->active != check)
 			gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tmphandle), check);
+		_dw_ignore_click = 0;
 	}
 	DW_MUTEX_UNLOCK;
 }
@@ -1287,16 +1411,21 @@
  */
 HWND dw_status_text_new(char *text, ULONG id)
 {
-	GtkWidget *tmp;
+	GtkWidget *tmp, *frame;
 	int _locked_by_me = FALSE;
 
 	DW_MUTEX_LOCK;
+	frame = gtk_frame_new(NULL);
+	gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
 	tmp = gtk_label_new(text);
-	gtk_label_set_justify(GTK_LABEL(tmp), GTK_JUSTIFY_LEFT);
+	gtk_container_add(GTK_CONTAINER(frame), tmp);
 	gtk_widget_show(tmp);
-	gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
+	gtk_widget_show(frame);
+	gtk_label_set_justify(GTK_LABEL(tmp), GTK_JUSTIFY_LEFT);
+	gtk_object_set_data(GTK_OBJECT(frame), "id", (gpointer)id);
+	gtk_object_set_data(GTK_OBJECT(frame), "label", (gpointer)tmp);
 	DW_MUTEX_UNLOCK;
-	return tmp;
+	return frame;
 }
 
 /*
@@ -1537,7 +1666,7 @@
  *       id: An ID to be used with WinWindowFromID() or 0L.
  *       multi: Multiple select TRUE or FALSE.
  */
-HWND dw_listbox_new(unsigned long id, int multi)
+HWND dw_listbox_new(unsigned long id, int multi)
 {
 	GtkWidget *tmp, *list;
 	int _locked_by_me = FALSE;
@@ -1618,6 +1747,12 @@
 		gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(handle)->entry), text);
 	else if(GTK_IS_LABEL(handle))
 		gtk_label_set_text(GTK_LABEL(handle), text);
+	else if(GTK_IS_FRAME(handle))
+	{
+		GtkWidget *tmp = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "label");
+		if(tmp && GTK_IS_LABEL(tmp))
+			gtk_label_set_text(GTK_LABEL(tmp), text);
+	}
 	DW_MUTEX_UNLOCK;
 }
 
@@ -2271,6 +2406,7 @@
 {
 	int z, count = 0;
 	GtkWidget *clist;
+	GdkColor *fore, *back;
 	char **blah;
 	int _locked_by_me = FALSE;
 
@@ -2293,11 +2429,18 @@
 	blah = malloc(sizeof(char *) * count);
 	memset(blah, 0, sizeof(char *) * count);
 
+	fore = (GdkColor *)gtk_object_get_data(GTK_OBJECT(clist), "foregdk");
+	back = (GdkColor *)gtk_object_get_data(GTK_OBJECT(clist), "backgdk");
 	gtk_clist_freeze(GTK_CLIST(clist));
 	for(z=0;z<rowcount;z++)
 	{
 		gtk_clist_append(GTK_CLIST(clist), blah);
+		if(fore)
+			gtk_clist_set_foreground(GTK_CLIST(clist), z, fore);
+		if(back)
+			gtk_clist_set_background(GTK_CLIST(clist), z, back);
 	}
+	gtk_object_set_data(GTK_OBJECT(clist), "rowcount", (gpointer)rowcount);
 	free(blah);
 	DW_MUTEX_UNLOCK;
 	return (void *)handle;
@@ -2460,6 +2603,7 @@
 		g_list_free(list);
 		gtk_object_set_data(GTK_OBJECT(clist), "selectlist", NULL);
 		gtk_clist_clear(GTK_CLIST(clist));
+		gtk_object_set_data(GTK_OBJECT(clist), "rowcount", (gpointer)0);
 	}
 	DW_MUTEX_UNLOCK;
 }
@@ -3224,7 +3368,7 @@
 	int _locked_by_me = FALSE;
 
 	DW_MUTEX_LOCK;
-	if(handle->window)
+	if(handle && handle->window)
 		gdk_window_move(handle->window, x, y);
 	DW_MUTEX_UNLOCK;
 }
@@ -3243,13 +3387,27 @@
 	int _locked_by_me = FALSE;
 
 	DW_MUTEX_LOCK;
-	if(GTK_IS_WINDOW(handle))
+	if(handle && GTK_IS_WINDOW(handle))
 	{
+		GdkWindow *parent = gdk_window_get_parent(handle->window);
+		int cx = (int)gtk_object_get_data(GTK_OBJECT(handle), "cx");
+		int cy = (int)gtk_object_get_data(GTK_OBJECT(handle), "cy");
+
 		_size_allocate(GTK_WINDOW(handle));
-		gtk_widget_set_uposition(handle, x, y);
-		gtk_window_set_default_size(GTK_WINDOW(handle), width, height);
+#if 0
+		if(parent)
+		{
+			gdk_window_resize(parent, width, height);
+			gdk_window_move(parent, x, y);
+		}
+		else
+#endif
+		{
+			gtk_widget_set_uposition(handle, x, y);
+			gtk_window_set_default_size(GTK_WINDOW(handle), width - cx, height - cy);
+		}
 	}
-	else if(handle->window)
+	else if(handle && handle->window)
 	{
 		gdk_window_resize(handle->window, width, height);
 		gdk_window_move(handle->window, x, y);
@@ -3273,7 +3431,13 @@
 
 	if(handle && handle->window)
 	{
+		int cx, cy;
+
 		DW_MUTEX_LOCK;
+
+		cx = (int)gtk_object_get_data(GTK_OBJECT(handle), "cx");
+		cy = (int)gtk_object_get_data(GTK_OBJECT(handle), "cy");
+
 		gdk_window_get_geometry(handle->window, &gx, &gy, &gwidth, &gheight, &gdepth);
 		gdk_window_get_root_origin(handle->window, &gx, &gy);
 		if(x)
@@ -3281,9 +3445,9 @@
 		if(y)
 			*y = gy;
 		if(width)
-			*width = gwidth;
+			*width = gwidth - cx;
 		if(height)
-			*height = gheight;
+			*height = gheight - cy;
 		DW_MUTEX_UNLOCK;
 	}
 }
@@ -3463,15 +3627,17 @@
 		GtkWidget *list_item;
 		GList *tmp;
 		char *font = (char *)gtk_object_get_data(GTK_OBJECT(handle), "font");
-		unsigned long fore = (unsigned long)gtk_object_get_data(GTK_OBJECT(handle), "fore");
-		unsigned long back = (unsigned long)gtk_object_get_data(GTK_OBJECT(handle), "back");
+		GdkColor *fore = (GdkColor *)gtk_object_get_data(GTK_OBJECT(handle2), "foregdk");
+		GdkColor *back = (GdkColor *)gtk_object_get_data(GTK_OBJECT(handle2), "backgdk");
 
 		list_item=gtk_list_item_new_with_label(text);
 
 		if(font)
 			_set_font(GTK_LIST_ITEM(list_item)->item.bin.child, font);
 		if(fore && back)
-			_set_color(GTK_LIST_ITEM(list_item)->item.bin.child, fore, back);
+			_set_color(GTK_LIST_ITEM(list_item)->item.bin.child,
+					   DW_RGB(fore->red, fore->green, fore->blue),
+					   DW_RGB(back->red, back->green, back->blue));
 
 		tmp  = g_list_append(NULL, list_item);
 		gtk_widget_show(list_item);
@@ -4196,6 +4362,10 @@
 	{
 		thisname = "select_child";
 	}
+	else if(GTK_IS_WINDOW(thiswindow) && strcmp(signame, "set-focus") == 0)
+	{
+		thisname = "focus-in-event";
+	}
 
 	if(!thisfunc || !thiswindow)
 	{
--- a/os2/dw.c	Fri Jul 06 13:36:38 2001 +0000
+++ b/os2/dw.c	Wed Jul 11 21:57:56 2001 +0000
@@ -86,7 +86,7 @@
 } SignalList;
 
 /* List of signals and their equivilent OS/2 message */
-#define SIGNALMAX 11
+#define SIGNALMAX 12
 
 SignalList SignalTranslate[SIGNALMAX] = {
 	{ WM_SIZE, "configure_event" },
@@ -99,7 +99,8 @@
 	{ WM_COMMAND, "clicked" },
 	{ CN_ENTER, "container-select" },
 	{ CN_CONTEXTMENU, "container-context" },
-	{ LN_SELECT, "item-select" }
+	{ LN_SELECT, "item-select" },
+	{ WM_SETFOCUS, "set-focus" }
 };
 
 /* This function adds a signal handler callback into the linked list.
@@ -371,7 +372,7 @@
  */
 void _initial_focus(HWND handle)
 {
-	Box *thisbox;
+	Box *thisbox = NULL;
 	HWND box;
 
 	box = WinWindowFromID(handle, FID_CLIENT);
@@ -398,13 +399,12 @@
 		lastbox = box;
 	}
 
-	thisbox = WinQueryWindowPtr(lastbox, QWP_USER);
-	if(!thisbox)
-	{
-		box = WinWindowFromID(lastbox, FID_CLIENT);
-		if(box)
-			thisbox = WinQueryWindowPtr(box, QWP_USER);
-	}
+	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)
@@ -1162,6 +1162,20 @@
 		{
 			switch(msg)
 			{
+			case WM_SETFOCUS:
+				{
+					if(mp2)
+					{
+						int (*setfocusfunc)(HWND, void *) = (int (*)(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_SIZE:
 				{
 					int (*sizefunc)(HWND, int, int, void *) = (int (*)(HWND, int, int, void *))tmp->signalfunction;
@@ -2102,7 +2116,7 @@
  *           newthread: True if this is the only thread.
  *                      False if there is already a message loop running.
  */
-int dw_init(int newthread)
+int dw_init(int newthread, int argc, char *argv[])
 {
 	APIRET rc;
 
@@ -2288,6 +2302,16 @@
 }
 
 /*
+ * Minimizes or Iconifies a top-level window.
+ * Parameters:
+ *           handle: The window handle to minimize.
+ */
+int dw_window_minimize(HWND handle)
+{
+	return WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_MINIMIZE);
+}
+
+/*
  * Makes the window invisible.
  * Parameters:
  *           handle: The window handle to make visible.
@@ -2539,6 +2563,28 @@
 }
 
 /*
+ * Create a new MDI Frame to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id or 0L.
+ */
+HWND dw_mdi_new(unsigned long id)
+{
+	HWND hwndframe;
+
+	hwndframe = WinCreateWindow(HWND_OBJECT,
+								WC_FRAME,
+								NULL,
+								WS_VISIBLE | WS_CLIPCHILDREN,
+								0,0,2000,1000,
+								NULLHANDLE,
+								HWND_TOP,
+								0L,
+								NULL,
+								NULL);
+	return hwndframe;
+}
+
+/*
  * Create a bitmap object to be packed.
  * Parameters:
  *       id: An ID to be used with WinWindowFromID() or 0L.
--- a/win/dw.c	Fri Jul 06 13:36:38 2001 +0000
+++ b/win/dw.c	Wed Jul 11 21:57:56 2001 +0000
@@ -16,12 +16,6 @@
 #include <process.h>
 #include "dw.h"
 
-/* Get around apparent bugs in the
- * Microsoft runtime when in the debugger.
- * You can set this value to 0 when releasing.
- */
-#define DEBUG_MALLOC 100
-
 /* this is the callback handle for the window procedure */
 /* make sure you always match the calling convention! */
 int (*filterfunc)(HWND, UINT, WPARAM, LPARAM) = 0L;
@@ -103,7 +97,7 @@
 } SignalList;
 
 /* List of signals and their equivilent Win32 message */
-#define SIGNALMAX 11
+#define SIGNALMAX 12
 
 SignalList SignalTranslate[SIGNALMAX] = {
 	{ WM_SIZE, "configure_event" },
@@ -116,7 +110,8 @@
 	{ WM_COMMAND, "clicked" },
 	{ NM_DBLCLK, "container-select" },
 	{ NM_RCLICK, "container-context" },
-	{ LBN_SELCHANGE, "item-select" }
+	{ LBN_SELCHANGE, "item-select" },
+	{ WM_SETFOCUS, "set-focus" }
 };
 
 #ifdef BUILD_DLL
@@ -979,6 +974,17 @@
 			{
 				switch(msg)
 				{
+				case WM_SETFOCUS:
+					{
+						int (*setfocusfunc)(HWND, void *) = (int (*)(HWND, void *))tmp->signalfunction;
+
+						if(hWnd == tmp->window)
+						{
+							result = setfocusfunc(tmp->window, tmp->data);
+							tmp = NULL;
+						}
+					}
+					break;
 				case WM_SIZE:
 					{
 						int (*sizefunc)(HWND, int, int, void *) = tmp->signalfunction;
@@ -2055,7 +2061,7 @@
  *           newthread: True if this is the only thread.
  *                      False if there is already a message loop running.
  */
-int dw_init(int newthread)
+int dw_init(int newthread, int argc, char *argv[])
 {
 	WNDCLASS wc;
 	int z;
@@ -2279,6 +2285,16 @@
 }
 
 /*
+ * Minimizes or Iconifies a top-level window.
+ * Parameters:
+ *           handle: The window handle to minimize.
+ */
+int dw_window_minimize(HWND handle)
+{
+	return ShowWindow(handle, SW_MINIMIZE);
+}
+
+/*
  * Makes the window visible.
  * Parameters:
  *           handle: The window handle to make visible.
@@ -2516,8 +2532,10 @@
 	}
 	SetWindowLong(hwndframe, GWL_USERDATA, (ULONG)newbox);
 
+#if 0
 	if(hwndOwner)
 		SetParent(hwndframe, hwndOwner);
+#endif
 
 	return hwndframe;
 }
@@ -2530,7 +2548,7 @@
  */
 HWND dw_box_new(int type, int pad)
 {
-	Box *newbox = malloc(sizeof(Box)+DEBUG_MALLOC);
+	Box *newbox = malloc(sizeof(Box));
 	HWND hwndframe;
 
 	newbox->pad = pad;
@@ -2595,9 +2613,33 @@
 }
 
 /*
+ * Create a new MDI Frame to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id or 0L.
+ */
+HWND dw_mdi_new(unsigned long id)
+{
+	CLIENTCREATESTRUCT ccs;
+	HWND hwndframe;
+
+	ccs.hWindowMenu = NULL;
+	ccs.idFirstChild = 0;
+
+	hwndframe = CreateWindow("MDICLIENT",
+							 "",
+							 WS_CHILD | WS_CLIPSIBLINGS,
+							 0,0,2000,1000,
+							 DW_HWND_OBJECT,
+							 NULL,
+							 DWInstance,
+							 &ccs);
+	return hwndframe;
+}
+
+/*
  * Create a bitmap object to be packed.
  * Parameters:
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id or 0L.
  */
 HWND dw_bitmap_new(ULONG id)
 {
@@ -3341,7 +3383,7 @@
 		Item *tmpitem, *thisitem = thisbox->items;
 		char tmpbuf[100];
 
-		tmpitem = malloc(sizeof(Item)*(thisbox->count+1)+DEBUG_MALLOC);
+		tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
 
 		for(z=0;z<thisbox->count;z++)
 		{