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 mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gtk-list