hi, you are connecting the expose and configure events after you have created and shown the widgets. meaning that your expose and configure events will not get called until you, the user, do something to make these events get called. (or programmatically: if you were to gtk_widget_queue_resize() the drawing area widget after connecting the signals, you would automatically generate a configure event.) but in the meantime, you have executed your drawing thread. since the configure event hasn't been called, your drawing code has no pixmap to draw on and gtk balks (rightly so). try setting the expose and configure events before you gtk_widget_show_all() the app. and then what you'll find is that your expose event may get called sooner than you want during startup, and then this will fail too. i have dealt with startup timing issues by checking for the pixmap in the expose handler before attempting to draw it, thus: if (!draw_code_cache_pixmap) return TRUE; simply preventing the code from executing if there's no pixmap yet to draw. and, i don't see it, but i assume your drawing area widget is actually created in the code somewhere? because i don't see where it would be made, i.e., no routine is called to make it in your main program either? since your signal connections seem to work, i assume this is not a problem. but even if you connect the events before the widget_show_all() call, there's another potential problem in that you don't enter the main loop until after the thread has executed. the configure and expose events occur as part of the main loop itself (i.e., after the thread has started), and so you still will not have a pixmap ready for drawing on when the thread is called. since i'm assuming that you will ultimately want to call the drawing thread as part of normal app behaviour, i.e., more than just at startup, i would suggest you rework the logic to make the thread called automatically when you want something drawn. try instantiating the thread from inside the configure event. this way, as well, you get around your original problem by guaranteeing that the thread won't ever be called until after a pixmap exists. (as well, inside the drawing thread, you will need to programmatically force the expose event by calling gtk_widget_queue_draw_area() on the drawing area widget.) this gives you the following logical program flow for your drawing area widget: EE1 -> ->CE3 -> DT4 -> EX5 IE2 -> where: EE1 - any external user event causing a redraw IE2 - any internal application event causing a redraw, force the configure event to be called with gtk_widget_queue_resize() CE3 - your configure event DT4 - your drawing thread EX5 - your expose event to finally render to the screen don't know what your intent is with making the drawing functionality a separate thread, but be very careful if you wish to be creating more than one of these to work at the same time; X is old and not so multi-thread aware as it should be, executing drawing commands simultaneously from multiple threads will definitely get you into trouble without due care. good luck, richard > Hi all: > My env. is GTK+2.0 with Glade-2. > I'm trying to draw a drawingarea with a background gthread...I have > connected the signal expose and configure with the correspond event > handler > in callbacks.c > My main.c looks like... > .... > 1 /* > 2 * Initial main.c file generated by Glade. Edit as required. > 3 * Glade will not overwrite this file. > 4 */ > 5 > 6 #ifdef HAVE_CONFIG_H > 7 # include <config.h> > 8 #endif > 9 > 10 #include <gtk/gtk.h> > 11 > 12 #include <glib.h> > 13 > 14 #include "interface.h" > 15 #include "support.h" > 16 #include " callbacks.h" > 17 #include "my_draw.h" > 18 > 19 gpointer drawing_thread(gpointer data); > 20 > 21 int > 22 main (int argc, char *argv[]) > 23 { > 24 GtkWidget *window1; > 25 GtkWidget *aboutdialog1; > 26 > 27 gtk_set_locale (); > 28 > 29 if(!g_thread_supported()) g_thread_init(NULL); > 30 gdk_threads_init(); > 31 > 32 GtkWidget *drawingarea1 = lookup_widget(window1,"drawingarea1"); > 33 > 34 gtk_init (&argc, &argv); > 35 > 36 add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps"); > 37 > 38 /* > 39 * The following code was added by Glade to create one of each > component > 40 * (except popup menus), just so that you see something after > building > 41 * the project. Delete any components that you don't want shown > initially. > 42 */ > 43 window1 = create_window1 (); > 44 gtk_widget_show (window1); > 45 aboutdialog1 = create_aboutdialog1 (); > 46 gtk_widget_show (aboutdialog1); > 47 > 48 g_signal_connect(G_OBJECT(drawingarea1), > "expose-event",G_CALLBACK(on_drawingarea1_expose_event), NULL); > 49 g_signal_connect(G_OBJECT(drawingarea1), > "configure-event",G_CALLBACK(on_drawingarea1_configure_event), NULL); > 50 > 51 // drawing_thread > 52 g_thread_create(drawing_thread, window1 , TRUE, NULL); > 53 > 54 gdk_threads_enter(); > 55 gtk_main (); > 56 gdk_threads_leave(); > 57 return 0; > 58 } > 59 > > > and in the callbacks.c > 92 gboolean > 93 on_drawingarea1_expose_event (GtkWidget *widget, > 94 GdkEventExpose *event, > 95 gpointer user_data) > 96 { > 97 > 98 gdk_draw_drawable(widget->window, > 99 widget->style->fg_gc[GTK_WIDGET_STATE (widget)], > 100 draw_code_cache_pixmap, > 101 event->area.x, event->area.y, > 102 event->area.x, event->area.y, > 103 event->area.width , event->area.height); > 104 return FALSE; > 105 } > 106 > > 140 gboolean > 141 on_drawingarea1_configure_event (GtkWidget *widget, > 142 GdkEventConfigure *event, > 143 gpointer user_data) > 144 { > 145 if(draw_code_cache_pixmap) > 146 g_object_unref(draw_code_cache_pixmap); > 147 > 148 draw_code_cache_pixmap = gdk_pixmap_new(widget->window, > 149 widget->allocation.width, > 150 widget->allocation.height, > 151 -1); > 152 > 153 return FALSE; > 154 } > > and my draeing thread is > 6 gpointer drawing_thread(gpointer data){ > 7 gint x_aix; > 8 gint y_aix; > 9 gint trace_len=0; > 10 GtkWidget* sim_drawing_area = (GtkWidget*)data; > 11 > 12 for(;;){ > 13 if(trace_len >= 50) > 14 trace_len = 0; > 15 > 16 gdk_threads_enter(); > 17 > 18 > //gdk_draw_rectangle(_sim_drawing_data->sim_drawing_area->window, > 19 gdk_draw_rectangle(draw_code_cache_pixmap, > 20 > sim_drawing_area->style->fg_gc[GTK_WIDGET_STATE (sim_drawing_area)], > 21 TRUE, > 22 0, > 23 0, > 24 trace_len, > 25 20); > 26 gdk_flush(); > 27 gdk_threads_leave(); > 28 > 29 trace_len++; > 30 } > 31 } > > I'm created a pixmap in the on_drawingarea1_configure_event function, and > connect this envnt handler with the corresponded signal. > But, as I execute the program, I got the following error msg... > > (gui2:27742): Gdk-CRITICAL **: gdk_draw_rectangle: assertion > `GDK_IS_DRAWABLE (drawable)' failed > > (gui2:27742): Gdk-CRITICAL **: gdk_draw_rectangle: assertion > `GDK_IS_DRAWABLE (drawable)' failed > > (gui2:27742): Gdk-CRITICAL **: gdk_draw_rectangle: assertion > `GDK_IS_DRAWABLE (drawable)' failed > > > Does any idea? > > ThankX!!!! > > Dave. > > > > -- > System on Chip Design Lab. > Dept. of Computer Science and Information Engineering, > National Chung Cheng University > E-mail : s88.tw@xxxxxxx > _______________________________________________ > gtk-list mailing list > gtk-list@xxxxxxxxx > http://mail.gnome.org/mailman/listinfo/gtk-list > _______________________________________________ gtk-list mailing list gtk-list@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gtk-list