gtk_object bad signal



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 ...)





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