#include #include #include typedef struct state { int started; int stopped; char path[256]; no no no :-) non usare *mai* un array a dimensione fissa per una stringa inserita dall'utente: rischi memory corruption e buffer overflow. Usa cahr *path e allocalo dinamicamente GladeXML *main_window; questo va bene, io personalemente di solito pero non tengo in memoria tutto l'oggetto GladeXML ma estraggo direttamente (nel tuo caso in main()) i puntatori alle widget che mi interessano e tengo quelli nella struct. In questo modo posso fare l'unref di GladeXML e non tenere in memoria tutto l'oggetto che parsifica l'xml. } t_state; t_state e' un po' troppo generico come nome, rischi problemi di conflitto (C non ha i namespace) inoltre la convenzione in gtk e' di usare CamelCase per i tipi void on_start_clicked(GtkButton *button, gpointer user_data); void on_browse_clicked(GtkButton *button, gpointer user_data); void on_save_clicked(GtkButton *button, gpointer user_data); void on_clear_clicked(GtkButton *button, gpointer user_data); void on_help_clicked(GtkButton *button, gpointer user_data); void t_state_set_started(int started); void t_state_set_stopped(int stopped); void t_state_set_path(t_state *data, char *path); int t_state_get_started(); int t_state_get_stopped(); char *t_state_get_path(); GladeXML *t_state_get_glade_xml(t_state *data); notazione di stile: io preferisco evitare i prototipi di tutte le funzioni all'inizio del file, sono inutili e significa solo che devi cambiare il codice in due posti... ordinando le funzioni in modo sensato li puoi evitare void t_state_set_path(t_state *data, char *path) { strcpy(data->path, path); } come dicevo, alloca la stringa: g_free (data->path); data->path = g_strdup (path); inoltre la funzione deve essere marcata static, dato che e' un metodo interno, privato a questo file. GladeXML *t_state_get_glade_xml(t_state *data) { return data->main_window; } se non ti serve al di fuori di questo filem, questa getter e' eccessiva (e comunque dovrebber essere static). All'interno del file, usare semplicemente data->main_window va bene. Se invece ti servisse all'esterno di questo file, io non credo che esporre questa getter sia una buona idea: GladeXML e' un dettaglio implementativo privato a questo file... se ad esempio all'esterno avessero bisogno di accedere al bottone Clear, la getter dovrebbe essere get_clear_button () { GtkWidget *button = glade_xml_get_widget(data->main_window, "clear"); return button; } oppure se fai come ti consiglio e nello stato metti direttamente le widgets { return data->clear_button; } in questo modo dall'esterno non si ha accesso all'oggetto GladeXML void on_browse_clicked(GtkButton *button, gpointer data) { GladeXML *main_window = t_state_get_glade_xml(data); GtkWidget *window1 = glade_xml_get_widget(main_window, "window1"); GtkWidget *dialog = gtk_file_chooser_dialog_new("Seleziona directory...", GTK_WINDOW(window1), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) ^^^ usare gli spazi e' gratis ;-) { char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); t_state_set_path(data, filename); GtkWidget *start = glade_xml_get_widget(main_window, "start"); GtkWidget *save = glade_xml_get_widget(main_window, "save"); GtkWidget *clear = glade_xml_get_widget(main_window, "clear"); gtk_widget_set_sensitive(start, TRUE); gtk_widget_set_sensitive(save, TRUE); gtk_widget_set_sensitive(clear, TRUE); } gtk_widget_destroy(dialog); } void on_clear_clicked(GtkButton *button, gpointer main_window) { GtkWidget *textview1 = glade_xml_get_widget(main_window, "textview1"); GtkTextBuffer *buffer; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview1)); gtk_text_buffer_set_text(buffer, "", -1); } int main(int argc, char *argv[]) { GladeXML *main_window; GtkWidget *widget; static t_state data = {FALSE, FALSE, "\0", main_window}; io allocherei dinamicamente: g_new0 (t_state, 1)... non e' il caso qui, ma la struct puo diventare un po troppo grossa per essere messa sulla stack gtk_init(&argc, &argv); main_window = glade_xml_new("gdso.glade", NULL, NULL); widget = glade_xml_get_widget(main_window, "window1"); g_signal_connect(G_OBJECT(widget), "delete_event", G_CALLBACK(gtk_main_quit), NULL); non c'e' bisogno di fare il cast G_OBJECT() in connect widget = glade_xml_get_widget(main_window, "clear"); g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(on_clear_clicked), main_window); gtk_widget_set_sensitive(widget, FALSE); widget = glade_xml_get_widget(main_window, "browse"); g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(on_browse_clicked), &data); gtk_main(); non e' molto importante qui visto che la app sta uscendo, ma visto che vieni dal java, ricordati che in C devi liberare la memoria allocata... quindi il free delle cose che ti ho indicato di allocare e l'unref di GladeXML. return 0; } /////////////////////////////////////////////////////////////// cc -o gdso main.c `pkg-config --cflags --libs libglade-2.0` main.c: In function 'main': main.c:82: error: initializer element is not constant main.c:82: error: (near initialization for 'data.main_window')