diff gtk/dw.c @ 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 26e2130135b9
children 81833f25b1aa
line wrap: on
line diff
--- 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)
 	{