Passing pointer to structure of pointers to callback function




	Hello, all --

	I am running a stock RedHat 6.0 system with Gnome 1.0 and GTK+ 1.2.1
	installed.
	I have applied all of the updates available in the updates/6.0/i386
	directory from wuarchive.

	Here is the problem that I am seeing...
	Once I create a few widgets (window, windowbox, and button), I set
	elements in a structure equal to them so that I can pass them to
	callback functions for later manipulation.  If I pass that structure
	from main() to the callback, everything works as expected.
	However, if I call a function from main() (e.g. to create another 
	window), create the structure from within the second function
	(window), and pass the structure to a callback function connected
	to a button within this second window, the contents of the structure
	are incorrect when printed from the callback function (and my program
	segfaults when I try to manipulate one of those elements ;).

	I have attached a small program that illustrates this below (sorry
	for the size...).  I compiled this with the following command:
    gcc -g `gtk-config --cflags` clientwindow.c -o a.out `gtk-config --libs`


	What am I doing wrong?

	Any help is greatly appreciated,

	gordon




/*
 * clientwindow.c
 */

#include <gtk/gtk.h>

/* Struct used to manipulate window widgets */

typedef struct ScriptWindowData {
  GtkWidget *window; 
  GtkWidget *windowbox;
  GtkWidget *donebutton;
}ScriptWindowData;


/* function declarations */
void delete_event (GtkWidget*, GdkEvent*, gpointer);
int done(GtkWidget*, gpointer);
int callgenwindow();
void clientwindow();


/* function definitions */
void delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {
  gtk_main_quit();
}

/* function bound to the button in the second window */
int done(GtkWidget *widget, gpointer data) {
  ScriptWindowData *SWD;
  SWD = (ScriptWindowData*) data;
  printf("\nSWD is %u\n", SWD);
  printf("SWD->window is %u\n", SWD->window);
  printf("SWD->windowbox is %u\n", SWD->windowbox);
  printf("SWD->donebutton is %u\n", SWD->donebutton);
  gtk_widget_destroy(SWD->window);
  return(0);
}


/* build second window (child) */
int callgenwindow() {
  GtkWidget *window;
  GtkWidget *windowbox;
  GtkWidget *donebutton;
  struct ScriptWindowData call_gen_data;


  /* Create the child window */
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "Call Generator");
  

  /* Create a box to contain everything in the child window */
  windowbox = gtk_hbox_new(FALSE, 0);
  gtk_container_set_border_width(GTK_CONTAINER(windowbox), 5);
  gtk_widget_show(windowbox);


  /* build button for second window */
  donebutton = gtk_button_new_with_label("Done");
  gtk_widget_show(donebutton);

  /* bind callback function to button in second window */
  gtk_signal_connect(GTK_OBJECT(donebutton), "clicked",
	GTK_SIGNAL_FUNC(done), &call_gen_data);

  /* Populate the ScriptWindowData struct */
  call_gen_data.window = window;
  call_gen_data.windowbox = windowbox;
  call_gen_data.donebutton = donebutton;

  /* Print out the values of widget pointers and structure elements */
  printf("\nwindow is %u\n", window);
  printf("windowbox is %u\n", windowbox);
  printf("donebutton is %u\n", donebutton);
 
  printf("\n\ncall_gen_data is %u\n", &call_gen_data);
  printf("call_gen_data.window is %u\n", call_gen_data.window);
  printf("call_gen_data.windowbox is %u\n", call_gen_data.windowbox);
  printf("call_gen_data.donebutton is %u\n", call_gen_data.donebutton);


  /* Pack everything and display */
  gtk_box_pack_start(GTK_BOX(windowbox), donebutton, FALSE, TRUE, 10);
  gtk_container_add(GTK_CONTAINER(window), windowbox);

  gtk_widget_show(window);

  return(0);
}


/* main window (parent) */
int main(int argc, char *argv[]) {
  GtkWidget *clientwindow;
  GtkWidget *clientwindowbox;
  GtkWidget *clientcallgenbutton;
  char buffer[32];

  /* Initialize GTK */
  gtk_init(&argc, &argv);

  /* Create the first window */
  clientwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(clientwindow), "ANTS Client");

  /* Create a box to contain everything in the first window */
  clientwindowbox = gtk_hbox_new(FALSE, 0);
  gtk_container_set_border_width(GTK_CONTAINER(clientwindowbox), 5);
  gtk_widget_show(clientwindowbox);

  /* Our only button in first window*/
  clientcallgenbutton = gtk_button_new_with_label("Call Generator");
  gtk_widget_show(clientcallgenbutton);

  /* connect something to it so it does stuff */
  gtk_signal_connect(GTK_OBJECT(clientcallgenbutton), "clicked",
	GTK_SIGNAL_FUNC(callgenwindow), (gpointer) "Call Gen Button");

  /* Pack things together */
  gtk_container_add(GTK_CONTAINER(clientwindowbox), clientcallgenbutton);
  gtk_container_add(GTK_CONTAINER(clientwindow), clientwindowbox);

  /* Display the first window */
  gtk_widget_show(clientwindow);

  gtk_main();

  return(0);
}


Gordon M. Taylor		    gordon@cmf.nrl.navy.mil
Washington, D.C.	   Naval Research Lab Connecton Machine Facility

"There was nothing like an appeal to honor.  It was a virtue that all craved,
even those who lacked it.  Fundamentally, honor was itself a debt, a code of
behavior, a promise, something inside yourself that you owed to the others 
who saw it in you."				-- Thomas L. Clancy, Jr.



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