So, I have some c code that saves an svalue:
struct signal_data {
struct svalue cb;
struct svalue args;
int signal_id;
};
struct signal_data *sv;
sv= /* allocated structure */
assign_svalue_no_free(&sv->cb,from_svalue);
assign_svalue_no_free(&sv->args,arg_svalue);
that is sent to a function as the data for a callback, and the callback is
something like this:
int pgtk2_action_callback(GtkAction *action, struct signal_data *d) {
int res;
push_gobject(action);
push_svalue(&d->args);
apply_svalue(&d->cb,2);
res=Pike_sp[-1].u.integer;
pop_stack();
return res;
}
I have in my pike code something like this:
string filedata="test data";
int main(...) {
/* init gtk, set up stuff, including something that uses filedata which gets
passed to a function that assigns it, above */
return -1; // start backend
}
Now, the gtk main loop runs (through the backend). I have a load routine that
loads the contents of a file into filedata. Then I use the menu to select the
menu option, that had filedata as an argument to be passed to the callback.
The problem is that the callback seems to get the original value of the svalue
that filedata was, not the new value:
string filedat="this is a string",filename;
array menu_actions=({
([ "name": "FileMenu", "label": "_File" ]),
([ "name": "FileOpen", "label": "_Open D64",
"callback": file_open_menu, "data": 0]),
([ "name": "FileQuit", "label": "_Quit",
"callback": file_quit_menu, "data": 0 ]),
([ "name": "ViewMenu", "label": "_View" ]),
([ "name": "ShowBAM", "label": "Show _BAM",
"callback": show_bam_menu, "data": filedat ]),
([ "name": "ShowDir", "label": "Show _Directory",
"callback": show_dir_menu, "data": filedat ]),
});
int show_bam_menu(object o, mixed ... args) {
write("o==%O\n",o);
write("args==%O\n",args);
}
int show_dir_menu(object o, mixed ... args) {
write("o==%O\n",o);
write("args==%O\n",args);
}
int file_quit_menu(mixed ... args) {
write("args==%O\n",args);
exit(0);
}
int file_open_menu(mixed ... args) {
write("args==%O\n",args);
array a=({ ([ "text": GTK2.STOCK_CANCEL, "id": GTK2.RESPONSE_CANCEL ]), ([
"text": GTK2.STOCK_OPEN, "id": GTK2.RESPONSE_ACCEPT ]) });
object o=GTK2.FileChooserDialog("Open D64",w,0,a);
o->set_action(GTK2.FILE_CHOOSE_ACTION_OPEN);
o->run();
filename=o->get_filename();
write("filename==%s\n",filename);
filedat=Stdio.read_bytes(filename);
o->destroy();
}
object ui,gt1,ui1;
int main(int argc, array argv) {
GTK2.setup_gtk(argv);
w=GTK2.Window(GTK2.WindowToplevel);
w->signal_connect("destroy",lambda() { exit(0); },0);
ui=GTK2.UiManager();
gt1=GTK2.ActionGroup("mainmenu");
gt1->add_actions(menu_actions);
ui->insert_action_group(gt1,0);
ui1=ui->add_ui_from_file("menu.xml");
w->add(ui->get_widget("/MenuBar"));
w->show_all();
write("actions==%O\n",gt1->list_actions());
return -1;
}
gt1->add_actions(menu_actions) adds the actions, using filedat as the data. But
when the callback is actually called (show_bam_menu()), filedat is still "this
is a string), rather than what I set filedat to in file_open_menu(). I put
debug statements in the relevant code (GTK2/source/gtkactiongroup.pre), and it
shows that the arg is still the previous value, not what I set it to. It seems
that when I originally set up the callback...
Hmm, I now see why, I did assign_svalue_no_free(). I don't want to get get a
copy of the svalue, I actually want to reference the svalue. Or, if needed, get
an indirect reference that I can deal with in the c-code to put the current,
proper value in at the time.
I hope I am clear. Does anybody have an idea of what I need to do? Maybe save
a reference to the proper svalue, and not a copy, and indirectly reference it
later? Although I'm not sure how I would do that. Maybe use a name of a
variable in the menu_actions above, have the code do a lookup on the name at the
time of the callback, and get the current value instead?
-lsd