hi all I'm new of GTK+ pogramming. I'm tring to develp an application in linux written in C with GTK 2.8 libraries. This app is interfaced with a database, reads data from it and create a GUI. I made a GTK object for detection of database UPDATEs, I mean: when the DBmanager receives an UPDATE command from a connection it starts a RULE that emits a signal. My object has a p_thread looping over a SELECT that checks for DBmanager signals. After detection of DB signal emission my object emits an own gtk-signal (named disp-signal). This last gtk-signal is connected to a function for GUI updating by a g_signal_connect(). Same function is also called by one other g_signal_connect() activted by a button_press_event. This two connections are because the user can change values shown in GUI but s/he is allowed to comeback to batabase settings. If the user saves some new values all other clients programs have to update their GUI. The problem is here: if I click te button the GUI is updated correctly but when the "updateGUIfunction" is called by my object signal the program crashes after a few updates. The crash comes with an Xlib error shown into stderr. After that the program objects not updated appears to work fine but all the widget areas destroyed and newed comes hidden. Sometimes I get a GTK_DRAWABLE failed error like following: (prova_gnome2:10237): Gdk-CRITICAL **: gdk_drawable_get_size: assertion `GDK_IS_DRAWABLE (drawable)' failed (prova_gnome2:10237): Gdk-CRITICAL **: gdk_window_invalidate_rect: assertion `window != NULL' failed It could be due to my signal interface not well initialized: it don't return user_data like a gtk-button (I don't know why, I followed on-line gtk examples) but I tried to use the gtk button signal included in child field of my object with same results. Please help me! thanks, Daniele B. The following code is my object for database signal detection and usage into the program: /*************************************************************************** * pgmonitorr.h ****************************************************************************/ #ifdef HAVE_CONFIG_H # include <config.h> #endif #ifndef __PGMONITORR_H__ #define __PGMONITORR_H__ #include <gdk/gdk.h> #include "libpq-fe.h" G_BEGIN_DECLS #define PGMONITORR_TYPE (pgmonitorr_get_type ()) #define PGMONITORR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PGMONITORR_TYPE, Pgmonitorr)) #define PGMONITORR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PGMONITORR_TYPE, PgmonitorrClass)) #define IS_PGMONITORR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PGMONITORR_TYPE)) #define IS_PGMONITORR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PGMONITORR_TYPE)) #define PGMONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PGMONITORR, PgmonitorrClass)) typedef struct _Pgmonitorr Pgmonitorr; typedef struct _PgmonitorrClass PgmonitorrClass; struct _Pgmonitorr { GtkBin parent; GtkWidget *child; gchar conninfo[500]; gchar segnale[50]; PGconn *async_conn; pthread_t monitor_t; //GThread *monitor_t; }; struct _PgmonitorrClass { GtkBinClass parent_class; void (* pgmonitorr) (Pgmonitorr *pgm); }; GType pgmonitorr_get_type (void); GtkWidget* pgmonitorr_new (char * conninfo, char * segnale); void pgmonitorr_clear (Pgmonitorr *pgm); G_END_DECLS #endif /* __PGMONITORR_H__ */ /*************************************************************************** * pgmonitorr.c ****************************************************************************/ #ifdef HAVE_CONFIG_H # include <config.h> #endif #include <config.h> #include <gnome.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <gtk/gtksignal.h> #include <gtk/gtkobject.h> #include <pthread.h> #include <string.h> #include "pgmonitorr.h" #include "libpq-fe.h" // libreria di intergaccia col postgres enum { DISP_SIGNAL, LAST_SIGNAL }; static guint pgmonitorr_signals[LAST_SIGNAL] = { 0 }; static void pgmonitorr_class_init (PgmonitorrClass *klass); static void pgmonitorr_init (Pgmonitorr *pgm); static void enable_pgmonitor (Pgmonitorr *pgm); GType pgmonitorr_get_type (void) { static GtkType pgm_type = 0; if (!pgm_type) { static const GtkTypeInfo pgm_info = { "PGmonitorr", sizeof (Pgmonitorr), sizeof (PgmonitorrClass), (GtkClassInitFunc) pgmonitorr_class_init, (GtkObjectInitFunc) pgmonitorr_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) NULL, }; pgm_type = gtk_type_unique (GTK_TYPE_BIN, &pgm_info); } fprintf (stderr,"pgmonitorr: gettype\n"); return pgm_type; } static void pgmonitorr_class_init (PgmonitorrClass *class) { GtkObjectClass *object_class; object_class = (GtkObjectClass*) class; pgmonitorr_signals[DISP_SIGNAL] = g_signal_new ("disp_signal", G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (PgmonitorrClass, pgmonitorr), NULL, NULL, g_cclosure_marshal_VOID__VOID, /*gtk_signal_default_marshaller,*/ GTK_TYPE_NONE, 0); fprintf (stderr,"pgmonitorr: class_init\n"); } static void pgmonitorr_init (Pgmonitorr *pgm) { pgm->child = NULL; g_snprintf (pgm->conninfo,500, "%s",""); g_snprintf (pgm->segnale,50, "%s",""); fprintf (stderr, "pgmonitorr: init\n"); } GtkWidget* pgmonitorr_new (char * rconninfo, char * rsegnale) { Pgmonitorr * pgm = g_object_new (pgmonitorr_get_type (), NULL); pgm->child = GTK_WIDGET(gtk_button_new()); gtk_container_add(GTK_CONTAINER(pgm),GTK_WIDGET(pgm->child)); g_snprintf (pgm->conninfo, 500, "%s",rconninfo); g_snprintf (pgm->segnale, 50, "%s",rsegnale); pthread_create (&(pgm->monitor_t), NULL, (gpointer)enable_pgmonitor, (gpointer)pgm); fprintf (stderr,"pgmonitorr: new OK!\n"); return GTK_WIDGET (pgm); } void pgmonitorr_clear (Pgmonitorr *pgm) { printf ("eseguo chiudi_conn Pgmonitor2\n"); pthread_cancel(pgm->monitor_t); pthread_join (pgm->monitor_t,0); PQfinish(pgm->async_conn); } static void enable_pgmonitor(Pgmonitorr *pgm) { int sock; fd_set input_mask; gchar nome[30]; PGresult *res; PGnotify *notify; gchar comando[50]; fprintf (stderr, "pgmonitorr: pthread 1 \n"); pgm->async_conn = PQconnectdb(pgm->conninfo); g_snprintf (comando,50, "LISTEN %s;", pgm->segnale); res = PQexec(pgm->async_conn, comando); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(pgm->async_conn)); PQclear(res); PQfinish (pgm->async_conn); exit (1); } PQclear(res); fprintf (stderr, "pgmonitorr: pthread 2 \n"); sock = PQsocket(pgm->async_conn); for (;;) { fprintf (stderr,"for pgmonitor enable\n"); FD_ZERO(&input_mask); FD_SET(sock, &input_mask); if (sock < 0) { fprintf (stderr, "socket error\n"); break; // shouldn't happen } if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0) { fprintf(stderr, "select() failed: %s\n", strerror(errno)); PQfinish (pgm->async_conn); } // Now check for input PQconsumeInput(pgm->async_conn); while ((notify = PQnotifies(pgm->async_conn)) != NULL) { g_snprintf (nome,30, "%s", notify->relname); fprintf(stderr,"ASYNC NOTIFY of '%s' received from backend pid %d\n",nome, notify->be_pid); PQfreemem(notify); g_signal_emit (pgm,pgmonitorr_signals[DISP_SIGNAL], 0); } } fprintf (stderr, "errore pgmonitorr\n"); pgmonitorr_clear (pgm); } /************************************************ *callback.c ***********************/ GtkWidget *monitor_disp=NULL; monitor_disp = pgmonitorr_new(conninfo->str, "disponibile"); gtk_widget_set_name(monitor_disp,"monitor_disp"); gtk_box_pack_start(GTK_BOX (hbox_generale1),monitor_disp,FALSE,FALSE,0); g_signal_connect(G_OBJECT(annulla_button),"button_press_event", G_CALLBACK(ins_piatti_modifica_listino), (int*)id_rep); g_signal_connect(G_OBJECT(monitor_disp), "disp_signal", G_CALLBACK(aux_ins_piatti_modifica_listino), id_rep); void aux_ins_piatti_modifica_listino (GtkWidget *elemento, int id_rep) { ins_piatti_modifica_listino(elemento,NULL,id_rep); } void ins_piatti_modifica_listino executes some lookups, destroy a part of gui and remake it (gtk_vbox_new() ... gtk_spinbutton_new ... gtk_entry_new ...) _______________________________________________ gtk-list@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gtk-list