changeset 278:df0665ba147f

Initial code for dw_bitmapbutton_new_from_file and added filename parameter to dw_window_set_bitmap().
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Fri, 14 Mar 2003 18:03:35 +0000
parents d706e0dbb0cb
children 984db8aefd7f
files dw.def dw.h dww.def gtk/dw.c os2/dw.c win/dw.c
diffstat 6 files changed, 451 insertions(+), 153 deletions(-) [+]
line wrap: on
line diff
--- a/dw.def	Fri Mar 07 20:25:18 2003 +0000
+++ b/dw.def	Fri Mar 14 18:03:35 2003 +0000
@@ -65,6 +65,7 @@
 
   dw_button_new                          @90
   dw_bitmapbutton_new                    @91
+  dw_bitmapbutton_new_from_file          @92
 
   dw_text_new                            @100
   dw_status_text_new                     @101
--- a/dw.h	Fri Mar 07 20:25:18 2003 +0000
+++ b/dw.h	Fri Mar 14 18:03:35 2003 +0000
@@ -712,6 +712,7 @@
 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_container_new(unsigned long id);
 HWND API dw_tree_new(unsigned long id);
 HWND API dw_text_new(char *text, unsigned long id);
@@ -751,7 +752,7 @@
 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_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_bitmap(HWND handle, unsigned long id);
+void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename);
 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);
--- a/dww.def	Fri Mar 07 20:25:18 2003 +0000
+++ b/dww.def	Fri Mar 14 18:03:35 2003 +0000
@@ -62,6 +62,7 @@
 
   dw_button_new                          @90
   dw_bitmapbutton_new                    @91
+  dw_bitmapbutton_new_from_file          @92
 
   dw_text_new                            @100
   dw_status_text_new                     @101
--- a/gtk/dw.c	Fri Mar 07 20:25:18 2003 +0000
+++ b/gtk/dw.c	Fri Mar 14 18:03:35 2003 +0000
@@ -1693,7 +1693,7 @@
 /*
  * 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(unsigned long id)
 {
@@ -2143,7 +2143,7 @@
  * Create a new static text window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       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_text_new(char *text, unsigned long id)
 {
@@ -2166,7 +2166,7 @@
  * Create a new status text window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       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_status_text_new(char *text, ULONG id)
 {
@@ -2192,7 +2192,7 @@
 /*
  * Create a new Multiline Editbox window (widget) 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_mle_new(unsigned long id)
 {
@@ -2232,7 +2232,7 @@
  * Create a new Entryfield window (widget) to be packed.
  * Parameters:
  *       text: The default text to be in the entryfield widget.
- *       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_entryfield_new(char *text, unsigned long id)
 {
@@ -2255,7 +2255,7 @@
  * Create a new Entryfield (password) window (widget) to be packed.
  * Parameters:
  *       text: The default text to be in the entryfield widget.
- *       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_entryfield_password_new(char *text, ULONG id)
 {
@@ -2279,7 +2279,7 @@
  * Create a new Combobox window (widget) to be packed.
  * Parameters:
  *       text: The default text to be in the combpbox widget.
- *       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_combobox_new(char *text, unsigned long id)
 {
@@ -2308,7 +2308,7 @@
  * Create a new button window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       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_button_new(char *text, unsigned long id)
 {
@@ -2342,7 +2342,44 @@
 
 	if(bitmap)
 	{
-		dw_window_set_bitmap(bitmap, id);
+		dw_window_set_bitmap(bitmap, id, NULL);
+		gtk_container_add (GTK_CONTAINER(tmp), bitmap);
+	}
+	gtk_widget_show(tmp);
+	if(text)
+	{
+		tooltips = gtk_tooltips_new();
+		gtk_tooltips_set_tip(tooltips, tmp, text, NULL);
+		gtk_object_set_data(GTK_OBJECT(tmp), "tooltip", (gpointer)tooltips);
+	}
+	gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
+	DW_MUTEX_UNLOCK;
+	return tmp;
+}
+
+/*
+ * Create a new bitmap button window (widget) to be packed from a file.
+ * Parameters:
+ *       text: Bubble help text to be displayed.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ *       filename: Name of the file, omit extention to have
+ *                 DW pick the appropriate file extension.
+ *                 (BMP on OS/2 or Windows, XPM on Unix)
+ */
+HWND dw_bitmapbutton_new_from_file(char *text, unsigned long id, char filename)
+{
+	GtkWidget *tmp;
+	GtkWidget *bitmap;
+    GtkTooltips *tooltips;
+	int _locked_by_me = FALSE;
+
+	DW_MUTEX_LOCK;
+	tmp = gtk_button_new();
+	bitmap = dw_bitmap_new(id);
+
+	if(bitmap)
+	{
+		dw_window_set_bitmap(bitmap, 0, filename);
 		gtk_container_add (GTK_CONTAINER(tmp), bitmap);
 	}
 	gtk_widget_show(tmp);
@@ -2361,7 +2398,7 @@
  * Create a new spinbutton window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       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_spinbutton_new(char *text, unsigned long id)
 {
@@ -2384,7 +2421,7 @@
  * Create a new radiobutton window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       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_radiobutton_new(char *text, ULONG id)
 {
@@ -2406,7 +2443,7 @@
  * Parameters:
  *       vertical: TRUE or FALSE if slider is vertical.
  *       increments: Number of increments available.
- *       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_slider_new(int vertical, int increments, ULONG id)
 {
@@ -2435,7 +2472,7 @@
  * Parameters:
  *       vertical: TRUE or FALSE if scrollbar is vertical.
  *       increments: Number of increments available.
- *       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_scrollbar_new(int vertical, int increments, ULONG id)
 {
@@ -2461,7 +2498,7 @@
 /*
  * Create a new percent bar window (widget) 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_percent_new(unsigned long id)
 {
@@ -2480,7 +2517,7 @@
  * Create a new checkbox window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       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_checkbox_new(char *text, unsigned long id)
 {
@@ -2498,7 +2535,7 @@
 /*
  * Create a new listbox window (widget) 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.
  *       multi: Multiple select TRUE or FALSE.
  */
 HWND dw_listbox_new(unsigned long id, int multi)
@@ -2546,20 +2583,128 @@
 	DW_MUTEX_UNLOCK;
 }
 
+HPIXMAP dw_pixmap_new_from_file(HWND handle, char *filename)
+{
+	int _locked_by_me = FALSE;
+	HPIXMAP pixmap;
+#ifndef USE_IMLIB
+	GdkBitmap *bitmap = NULL;
+#endif
+#if GTK_MAJOR_VERSION > 1
+	GdkPixbuf *pixbuf;
+#elif defined(USE_IMLIB)
+	GdkImlibImage *image;
+#endif
+	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 .xpm extention */
+		strcat(file, ".xpm");
+		if(access(file, 04) != 0)
+		{
+			free(pixmap);
+			return NULL;
+		}
+	}
+
+	DW_MUTEX_LOCK;
+#if GTK_MAJOR_VERSION > 1
+	pixbuf = gdk_pixbuf_new_from_file(file, NULL);
+
+	pixmap->width = gdk_pixbuf_get_width(pixbuf);
+	pixmap->height = gdk_pixbuf_get_height(pixbuf);
+
+	gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap->pixmap, &bitmap, 1);
+	g_object_unref(pixbuf);
+#elif defined(USE_IMLIB)
+	image = gdk_imlib_load_image(file);
+
+	pixmap->width = image->rgb_width;
+	pixmap->height = image->rgb_height;
+
+	gdk_imlib_render(image, pixmap->width, pixmap->height);
+	pixmap->pixmap = gdk_imlib_copy_image(image);
+	gdk_imlib_destroy_image(image);
+#else
+	pixmap->pixmap = gdk_pixmap_create_from_xpm(handle->window, &bitmap, &_colors[DW_CLR_PALEGRAY], file);
+#endif
+	pixmap->handle = handle;
+	DW_MUTEX_UNLOCK;
+	return pixmap;
+}
 /*
  * 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.
- */
-void dw_window_set_bitmap(HWND handle, unsigned long id)
+ *       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 dw_window_set_bitmap(HWND handle, unsigned long id, char *filename)
 {
 	GdkBitmap *bitmap = NULL;
 	GdkPixmap *tmp;
 	int _locked_by_me = FALSE;
 
-	DW_MUTEX_LOCK;
-	tmp = _find_pixmap(&bitmap, id, handle, NULL, NULL);
+	if(!id && !filename)
+		return;
+
+	DW_MUTEX_LOCK;
+	if(id)
+		tmp = _find_pixmap(&bitmap, id, handle, NULL, NULL);
+	else
+	{
+		char *file = alloca(strlen(filename) + 5);
+#if GTK_MAJOR_VERSION > 1
+		GdkPixbuf *pixbuf;
+#elif defined(USE_IMLIB)
+		GdkImlibImage *image;
+#endif
+
+		if (!file)
+		{
+			DW_MUTEX_UNLOCK;
+			return;
+		}
+
+		strcpy(file, filename);
+
+		/* check if we can read from this file (it exists and read permission) */
+		if(access(file, 04) != 0)
+		{
+			/* Try with .xpm extention */
+			strcat(file, ".xpm");
+			if(access(file, 04) != 0)
+			{
+				DW_MUTEX_UNLOCK;
+				return NULL;
+			}
+		}
+#if GTK_MAJOR_VERSION > 1
+		pixbuf = gdk_pixbuf_new_from_file(file, NULL);
+
+		gdk_pixbuf_render_pixmap_and_mask(pixbuf, &tmp, &bitmap, 1);
+		g_object_unref(pixbuf);
+#elif defined(USE_IMLIB)
+		image = gdk_imlib_load_image(file);
+
+		gdk_imlib_render(image, image->rgb_width, image->rgb_height);
+		tmp = gdk_imlib_copy_image(image);
+		gdk_imlib_destroy_image(image);
+#else
+		tmp = gdk_pixmap_create_from_xpm(handle->window, &bitmap, &_colors[DW_CLR_PALEGRAY], file);
+#endif
+	}
+
 	if(tmp)
 #if GTK_MAJOR_VERSION > 1
 		gtk_image_set_from_pixmap(GTK_IMAGE(handle), tmp, bitmap);
--- a/os2/dw.c	Fri Mar 07 20:25:18 2003 +0000
+++ b/os2/dw.c	Fri Mar 14 18:03:35 2003 +0000
@@ -246,6 +246,28 @@
 	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");
+
+	if(hps)
+	{
+		GpiSetBitmap(hps, NULLHANDLE);
+		GpiAssociate(hps, NULLHANDLE);
+		GpiDestroyPS(hps);
+	}
+
+	if(hdc)
+		DevCloseDC(hdc);
+
+	if(hbm)
+		GpiDeleteBitmap(hbm);
+
+}
+
 /* This function removes and handlers on windows and frees
  * the user memory allocated to it.
  */
@@ -275,11 +297,9 @@
 	{
 		WindowData *wd = (WindowData *)ptr;
 		char tmpbuf[100];
-		HBITMAP hbm = (HBITMAP)dw_window_get_data(handle, "_dw_bitmap");
 
 		/* If this window has an associate bitmap destroy it. */
-		if(hbm)
-			GpiDeleteBitmap(hbm);
+		_free_bitmap(handle);
 
 		WinQueryClassName(handle, 99, tmpbuf);
 
@@ -3790,7 +3810,7 @@
 /*
  * 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 API dw_bitmap_new(ULONG id)
 {
@@ -4068,7 +4088,7 @@
  * Create a new static text window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_text_new(char *text, ULONG id)
 {
@@ -4091,7 +4111,7 @@
  * Create a new status text window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_status_text_new(char *text, ULONG id)
 {
@@ -4120,7 +4140,7 @@
 /*
  * Create a new Multiline Editbox window (widget) 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 API dw_mle_new(ULONG id)
 {
@@ -4148,7 +4168,7 @@
  * Create a new Entryfield window (widget) to be packed.
  * Parameters:
  *       text: The default text to be in the entryfield widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_entryfield_new(char *text, ULONG id)
 {
@@ -4176,7 +4196,7 @@
  * Create a new Entryfield (password) window (widget) to be packed.
  * Parameters:
  *       text: The default text to be in the entryfield widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_entryfield_password_new(char *text, ULONG id)
 {
@@ -4203,7 +4223,7 @@
  * Create a new Combobox window (widget) to be packed.
  * Parameters:
  *       text: The default text to be in the combpbox widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_combobox_new(char *text, ULONG id)
 {
@@ -4240,7 +4260,7 @@
  * Create a new button window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_button_new(char *text, ULONG id)
 {
@@ -4337,10 +4357,45 @@
 }
 
 /*
+ * Create a new bitmap button window (widget) to be packed from a file.
+ * Parameters:
+ *       text: Bubble help text to be displayed.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ *       filename: Name of the file, omit extention to have
+ *                 DW pick the appropriate file extension.
+ *                 (BMP on OS/2 or Windows, XPM on Unix)
+ */
+HWND dw_bitmapbutton_new_from_file(char *text, unsigned long id, char filename)
+{
+	/* TODO: Actually get it to draw the bitmap */
+	BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+	HWND tmp = WinCreateWindow(HWND_OBJECT,
+							   WC_BUTTON,
+							   "",
+							   WS_VISIBLE | BS_PUSHBUTTON |
+							   BS_BITMAP | BS_AUTOSIZE |
+							   BS_NOPOINTERFOCUS,
+							   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);
+	return tmp;
+}
+
+/*
  * Create a new spinbutton window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_spinbutton_new(char *text, ULONG id)
 {
@@ -4370,7 +4425,7 @@
  * Create a new radiobutton window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_radiobutton_new(char *text, ULONG id)
 {
@@ -4399,7 +4454,7 @@
  * Parameters:
  *       vertical: TRUE or FALSE if slider is vertical.
  *       increments: Number of increments available.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_slider_new(int vertical, int increments, ULONG id)
 {
@@ -4432,7 +4487,7 @@
  * Parameters:
  *       vertical: TRUE or FALSE if scrollbar is vertical.
  *       increments: Number of increments available.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_scrollbar_new(int vertical, int increments, ULONG id)
 {
@@ -4452,7 +4507,7 @@
 /*
  * Create a new percent bar window (widget) 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 API dw_percent_new(ULONG id)
 {
@@ -4478,7 +4533,7 @@
  * Create a new checkbox window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_checkbox_new(char *text, ULONG id)
 {
@@ -4505,7 +4560,7 @@
 /*
  * Create a new listbox window (widget) 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.
  *       multi: Multiple select TRUE or FALSE.
  */
 HWND API dw_listbox_new(ULONG id, int multi)
@@ -4543,21 +4598,167 @@
 	WinSendMsg(handle, WM_SETICON, (MPARAM)icon, 0);
 }
 
+/* Internal function to load a bitmap from a file and return handles
+ * to the bitmap, presentation space etc.
+ */
+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))
+		ScanLines = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cy;
+	else
+		ScanLines = pBitmapInfoHeader->cy;
+
+	/* 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);
+
+	*width = pBitmapInfoHeader->cx; *height = pBitmapInfoHeader->cy;
+
+	/* 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;
+}
+
 /*
  * 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.
- */
-void API dw_window_set_bitmap(HWND handle, ULONG id)
+ *       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(HWND handle, unsigned long id, char *filename)
 {
 	HBITMAP hbm;
-	HPS     hps = WinGetPS(handle);
-
-	hbm = GpiLoadBitmap(hps, NULLHANDLE, id, 0, 0);
+	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 );
-	WinReleasePS(hps);
+	if(id)
+		WinReleasePS(hps);
 	dw_window_set_data(handle, "_dw_bitmap", (void *)hbm);
 }
 
@@ -6797,17 +6998,6 @@
  */
 HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename)
 {
-	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 hps;
-	HDC hdc;
-	SIZEL sizl = { 0, 0 };
 	HPIXMAP pixmap;
 	char *file = alloca(strlen(filename) + 5);
 
@@ -6828,88 +7018,15 @@
 		}
 	}
 
-	/* open bitmap file */
-	DosOpen(filename, &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)
+	/* 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;
 	}
 
-	/* 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 NULL;
-	}
-
-	/* 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))
-		ScanLines = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cy;
-	else
-		ScanLines = pBitmapInfoHeader->cy;
-
-	/* now we need a presentation space, get it from static control */
-	hps = WinGetPS(handle);
-
-	hdc     = GpiQueryDevice(hps);
-	ulFlags = GpiQueryPS(hps, &sizl);
-
+	/* Success fill in other values */
 	pixmap->handle = handle;
-	pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc);
-	pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC);
-
-	pixmap->width = pBitmapInfoHeader->cx; pixmap->height = pBitmapInfoHeader->cy;
-
-	/* create bitmap now using the parameters from the info block */
-	pixmap->hbm = GpiCreateBitmap(pixmap->hps, pBitmapInfoHeader, 0L, NULL, NULL);
-
-	/* select the new bitmap into presentation space */
-	GpiSetBitmap(pixmap->hps, pixmap->hbm);
-
-	/* now copy the bitmap data into the bitmap */
-	GpiSetBitmapBits(pixmap->hps, 0L, ScanLines,
-					 BitmapFileBegin + pBitmapFileHeader->offBits,
-					 (PBITMAPINFO2)pBitmapInfoHeader);
-
-	/* free memory of bitmap file buffer */
-	DosFreeMem(BitmapFileBegin);
-	/* close the bitmap file */
-	DosClose(BitmapFileHandle);
 
 	return pixmap;
 }
--- a/win/dw.c	Fri Mar 07 20:25:18 2003 +0000
+++ b/win/dw.c	Fri Mar 14 18:03:35 2003 +0000
@@ -3943,7 +3943,7 @@
  * Create a new static text window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_text_new(char *text, ULONG id)
 {
@@ -3964,7 +3964,7 @@
  * Create a new status text window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_status_text_new(char *text, ULONG id)
 {
@@ -3985,7 +3985,7 @@
 /*
  * Create a new Multiline Editbox window (widget) 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 API dw_mle_new(ULONG id)
 {
@@ -4022,7 +4022,7 @@
  * Create a new Entryfield window (widget) to be packed.
  * Parameters:
  *       text: The default text to be in the entryfield widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_entryfield_new(char *text, ULONG id)
 {
@@ -4051,7 +4051,7 @@
  * Create a new Entryfield passwird window (widget) to be packed.
  * Parameters:
  *       text: The default text to be in the entryfield widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_entryfield_password_new(char *text, ULONG id)
 {
@@ -4093,7 +4093,7 @@
  * Create a new Combobox window (widget) to be packed.
  * Parameters:
  *       text: The default text to be in the combpbox widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_combobox_new(char *text, ULONG id)
 {
@@ -4133,7 +4133,7 @@
  * Create a new button window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_button_new(char *text, ULONG id)
 {
@@ -4198,7 +4198,7 @@
  * Create a new spinbutton window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_spinbutton_new(char *text, ULONG id)
 {
@@ -4246,7 +4246,7 @@
  * Create a new radiobutton window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_radiobutton_new(char *text, ULONG id)
 {
@@ -4275,7 +4275,7 @@
  * Parameters:
  *       vertical: TRUE or FALSE if slider is vertical.
  *       increments: Number of increments available.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_slider_new(int vertical, int increments, ULONG id)
 {
@@ -4303,7 +4303,7 @@
  * Parameters:
  *       vertical: TRUE or FALSE if scrollbar is vertical.
  *       increments: Number of increments available.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_scrollbar_new(int vertical, int increments, ULONG id)
 {
@@ -4329,7 +4329,7 @@
 /*
  * Create a new percent bar window (widget) 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 API dw_percent_new(ULONG id)
 {
@@ -4347,7 +4347,7 @@
  * Create a new checkbox window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
- *       id: An ID to be used with WinWindowFromID() or 0L.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
  */
 HWND API dw_checkbox_new(char *text, ULONG id)
 {
@@ -4374,7 +4374,7 @@
 /*
  * Create a new listbox window (widget) 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.
  *       multi: Multiple select TRUE or FALSE.
  */
 HWND API dw_listbox_new(ULONG id, int multi)
@@ -4427,13 +4427,46 @@
  * 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.
- */
-void API dw_window_set_bitmap(HWND handle, ULONG id)
-{
-	HBITMAP hbitmap = LoadBitmap(DWInstance, MAKEINTRESOURCE(id));
+ *       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(HWND handle, unsigned long id, char *filename)
+{
+	HBITMAP hbitmap;
 	HBITMAP oldbitmap = (HBITMAP)SendMessage(handle, STM_GETIMAGE, IMAGE_BITMAP, 0);
 
+	if(id)
+		hbitmap = LoadBitmap(DWInstance, MAKEINTRESOURCE(id));
+	else if(filename)
+	{
+		char *file = malloc(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)
+			{
+				free(file);
+				return;
+			}
+		}
+
+		hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+		free(file);
+	}
+	else
+		return;
+
 	SendMessage(handle, STM_SETIMAGE,
 				(WPARAM) IMAGE_BITMAP,
 				(LPARAM) hbitmap);