window coloring problems with gtk



Below is a slightly hacked-on version of the GtkColorSelection test code taken from
sec. 7.9 (color selection) of the gtk tutorial.  I'm trying to set the background color
of the main window to "wheat" inside main(), *before* the main eventloop starts, so that
instead of a gray background, I will see the wheat background, before I click in the drawing
area to start the color-sel widget.
I seem to be misunderstanding something pretty basic, but I can't figure out what it is...
Near as I can figure out from looking at the example code, there's no instances
where a window part is just set to some arbitrary non-default color, which is what I want
to do.  Do I have to trigger this with an artificial event of some kind, or do some other
kind of mysterious wierd magic?

It seems astonishingly hard to get anything done with gtk that isn't *already* sensibly
defaulted.  I've been able to draw into pixmaps, create windows and the like, but I can't
get any control over color.  All I see is whatever the current background/foreground
happens to be, usually gray/black (white/back before hax).

Also, why doesn't the GTK_WINDOW() cast of gtk_window_get_color_map()'s first arg work here?
It's the same "window" as above, with the same cast.  Is there some broken object-oriented
compile-time magic going on here?  At compile time we get:
	gcc -DHAVE_CONFIG_H -I./gtk -I. -I./glib -I/usr/X11R6/include   -g -O2 -DGTK_NO_CHECK_CASTS -Wall -DUSE_XIM -c gtkcolorseltest.c
	gtkcolorseltest.c: In function `main':
	gtkcolorseltest.c:114: warning: passing arg 1 of `gdk_window_get_colormap' from incompatible pointer type
	gtkcolorseltest.c:116: warning: passing arg 1 of `gdk_window_set_background' from incompatible pointer type
	gtkcolorseltest.c:117: warning: passing arg 1 of `gdk_window_clear' from incompatible pointer type
	gcc -g -O2 -DGTK_NO_CHECK_CASTS -Wall -DUSE_XIM -o gtkcolorseltest gtkcolorseltest.o -Wl,--rpath -Wl,/usr/local/lib ./gtk/.libs/libgtk.so -Wl,--rpath -Wl,/usr/local/lib ./gdk/.libs/libgdk.so -L/usr/X11R6/lib -lXext -lX11 -L/usr/X11R6/lib -lXext -lX11 -Wl,--rpath -Wl,/usr/local/lib ./glib/.libs/libglib.so -lm

At run-time I get
	** WARNING **: file gdkcolor.c: line 451 (gdk_color_alloc): "colormap != NULL"
which apparently refers to the gdk_color_alloc() call in main() below.  Why would it be
NULL, anyway?  And when does the gdk_color_alloc() function *ever* work?  I know it does
some places and not in others, but I haven't figured that out, either.  But anyway, the
desired color never appears.

You may need to tweak paths in the gcc line above to get it to work.  Paths are relative
to the source root directory /usr/local/src/gtk+-1.0.0/ .  The code, by the way, isn't
really part of the distribution per se; it was snarfed from the contents of
docs/gtk_tut.sgml .

/* ------ snip, snip ------- */
#include <glib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>

GtkWidget *colorseldlg = NULL;
GtkWidget *drawingarea = NULL;
	GtkWidget *hbox;

/* Color changed handler */

void color_changed_cb (GtkWidget *widget, GtkColorSelection *colorsel)
{
  gdouble color[3];
  GdkColor gdk_color;
  GdkColormap *colormap;

  /* Get drawingarea colormap */

  colormap = gdk_window_get_colormap (drawingarea->window);

  /* Get current color */

  gtk_color_selection_get_color (colorsel,color);

  /* Fit to a unsigned 16 bit integer (0..65535) and insert into the GdkColor structure */

  gdk_color.red = (guint16)(color[0]*65535.0);
  gdk_color.green = (guint16)(color[1]*65535.0);
  gdk_color.blue = (guint16)(color[2]*65535.0);

  /* Allocate color */

  gdk_color_alloc (colormap, &gdk_color);

  /* Set window background color */

  gdk_window_set_background (drawingarea->window, &gdk_color);

  /* Clear window */

  gdk_window_clear (drawingarea->window);
}

/* Drawingarea event handler */

gint area_event (GtkWidget *widget, GdkEvent *event, gpointer client_data)
{
  gint handled = FALSE;
  GtkWidget *colorsel;

  /* Check if we've received a button pressed event */

  if (event->type == GDK_BUTTON_PRESS && colorseldlg == NULL)
    {
      /* Yes, we have an event and there's no colorseldlg yet! */

      handled = TRUE;

      /* Create color selection dialog */

      colorseldlg = gtk_color_selection_dialog_new("Select background color");

      /* Get the GtkColorSelection widget */

      colorsel = GTK_COLOR_SELECTION_DIALOG(colorseldlg)->colorsel;

      /* Connect to the "color_changed" signal, set the client-data to the colorsel widget */

      gtk_signal_connect(GTK_OBJECT(colorsel), "color_changed",
        (GtkSignalFunc)color_changed_cb, (gpointer)colorsel);

      /* Show the dialog */

      gtk_widget_show(colorseldlg);
    }

  return handled;
}

/* Close down and exit handler */

void destroy_window (GtkWidget *widget, gpointer client_data)
{
  gtk_main_quit ();
}

/* Main */

gint main (gint argc, gchar *argv[])
{
  GdkColor mycolor;
  GtkWidget *window;
  GdkColormap *mycolormap = NULL;

  /* Initialize the toolkit, remove gtk-related commandline stuff */

  gtk_init (&argc,&argv);
	(void) gdk_color_parse("wheat", &mycolor);	/* get gtk's idea of what the color is */

  /* Create toplevel window, set title and policies */

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW(window), "Color selection test");
  gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, TRUE);

  /* Attach to the "delete" and "destroy" events so we can exit */

  gtk_signal_connect (GTK_OBJECT(window), "delete_event",
    (GtkSignalFunc)destroy_window, (gpointer)window);

  gtk_signal_connect (GTK_OBJECT(window), "destroy",
    (GtkSignalFunc)destroy_window, (gpointer)window);

  mycolormap = gdk_window_get_colormap(GTK_WINDOW(window));
  gdk_color_alloc(mycolormap, &mycolor);
  gdk_window_set_background(GTK_WINDOW(window), &mycolor);
  gdk_window_clear(GTK_WINDOW(window));
  
	hbox = gtk_hbox_new(1, 1);
  /* Create drawingarea, set size and catch button events */

  drawingarea = gtk_drawing_area_new ();

  gtk_drawing_area_size (GTK_DRAWING_AREA(drawingarea), 200, 200);

  gtk_widget_set_events (drawingarea, GDK_BUTTON_PRESS_MASK);

  gtk_signal_connect (GTK_OBJECT(drawingarea), "event", 
    (GtkSignalFunc)area_event, (gpointer)drawingarea);
  
  /* Add drawingarea to window, then show them both */

#if 0	/*{KDEBUG*/
  gtk_container_add (GTK_CONTAINER(window), drawingarea);
#else	/*}{KDEBUG*/
  gtk_container_add (GTK_CONTAINER(window), hbox);
	/* here I was trying to see whether there would be difficulties with
	 * [hv]boxes and windows.  The signals seem to be going to the right
	 * place unchanged from when there was no hbox, just the main window and the
	 * drawing area.  The tutorial sec. 5.3 "Widgets Without Windows" sez
	 * events for hboxes & other random critters need to be captured with an event-box
	 * that contains the windowless widgets.
	 * I see no sign of an event-box (I didn't use any :) , and events appear
	 * to be being captured by the drawing area just fine.  Does the tutorial lie?
	 */
  gtk_container_add (GTK_CONTAINER(hbox), drawingarea);
  gtk_widget_show (hbox);
#endif	/*}KDEBUG*/

  gtk_widget_show (drawingarea);
  gtk_widget_show (window);
  
  /* Enter the gtk main loop (this never returns) */

  gtk_main ();

  /* Satisfy grumpy compilers */

  return 0;
}
/* ------ end snip, snip ------- */

--kurt
  Please reply to <kurt@scn.org>, as the e-mail address
  <kurt@grogatch.seaslug.org> is unreliable.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]