/* $Id: gtkextcmd.c,v 1.7 2003/12/28 18:43:40 j_ali Exp $ */ /* GTK+ NetHack Copyright (c) Issei Numata 1999-2000 Modifications Copyright (c) J. Ali Harlow 2000 GTK+ NetHack may be freely redistributed. See license for details. */ #include #include #include #include #include "winGTK.h" #include "proxycb.h" #ifndef GTK_PROXY #include "func_tab.h" extern struct ext_func_tab extcmdlist[]; #endif static int n_extcmds = 0; static const char **extcmds = NULL; /* * These must agree with the list in winGTK.h -ALI */ struct ext_cmd_map { char *txt; } extcmdmap[NO_EXT_CMD_MAPS] = { { "adjust" }, { "borrow" }, { "chat" }, { "conduct" }, { "dip" }, { "enhance" }, { "explore" }, { "force" }, { "invoke" }, { "jump" }, { "loot" }, { "monster" }, { "name" }, { "offer" }, { "pray" }, { "quit" }, { "ride" }, { "rub" }, { "sit" }, { "technique" }, { "turn" }, { "twoweapon" }, { "untrap" }, { "version" }, { "wipe" }, { "youpoly" }, }; static int extcmd = 0; static void extcmd_init(boolean init) { int i; #ifdef GTK_PROXY struct proxycb_get_extended_commands_res *list; #endif if (!init) { /* Exit */ for(i = 0; i < n_extcmds; i++) free((char *)extcmds[i]); free(extcmds); extcmds = NULL; n_extcmds = 0; } #ifdef GTK_PROXY list = proxy_cb_get_extended_commands(); n_extcmds = list->n_commands; extcmds = (const char **)malloc(n_extcmds * sizeof(const char *)); for(i = 0; i < n_extcmds; i++) extcmds[i] = strdup(list->commands[i]); proxy_cb_free_extended_commands(list); #else for(n_extcmds = 0; extcmdlist[n_extcmds].ef_txt; n_extcmds++) ; extcmds = (const char **)malloc(n_extcmds * sizeof(const char *)); for(i = 0; i < n_extcmds; i++) extcmds[i] = strdup(extcmdlist[i].ef_txt); #endif } void GTK_extcmd_set(int cmd) { int j; if (!extcmds) extcmd_init(TRUE); extcmd = -1; if (cmd < 0 || cmd >= NO_EXT_CMD_MAPS) return; else { for(j = 0; j < n_extcmds; j++) if (!nh_strncmpi(extcmdmap[cmd].txt, extcmds[j], -1)) { extcmd = j; return; } } } static void extcmd_clicked(GtkWidget *widget, gpointer data) { extcmd = (int)data; gtk_main_quit(); } static gint extcmd_destroy(GtkWidget *widget, gpointer data) { guint *hid = (guint *)data; *hid = 0; extcmd = -1; gtk_main_quit(); return FALSE; } /* * This is not ideal since you can't choose between extended commands * that start with the same letter from the keyboard, but it will do * for now. --- ALI */ static gint extcmd_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data) { int i, keysym; keysym = nh_keysym(event); if (keysym) { extcmd = -1; for (i = 0; i < n_extcmds; i++) if (extcmds[i][0] == keysym) extcmd = i; if (extcmd >= 0 || keysym == '\033') gtk_main_quit(); } return FALSE; } int GTK_get_ext_cmd() { guint hid; GtkWidget *window; GtkWidget *frame; GtkWidget *vbox; GtkWidget *hbox; GtkWidget *table = NULL; GtkWidget *d; int i, col, data; const char *label; if (!extcmds) extcmd_init(TRUE); if (extcmd) { i = extcmd; extcmd = 0; return i; } window = nh_gtk_window_dialog(TRUE); nh_position_popup_dialog(GTK_WIDGET(window)); nh_gtk_focus_set_master(GTK_WINDOW(window), GTK_SIGNAL_FUNC(extcmd_key_press), 0, TRUE); hid = gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(extcmd_destroy), &hid); frame = nh_gtk_new_and_add(gtk_frame_new(NULL), window, ""); vbox = nh_gtk_new_and_add(gtk_vbox_new(FALSE, 0), frame, ""); hbox = nh_gtk_new_and_pack(gtk_hbox_new(FALSE, 0), vbox, "", FALSE, FALSE, NH_PAD); table = nh_gtk_new_and_pack(gtk_table_new((n_extcmds+2)/3, 3, TRUE), hbox, "", FALSE, FALSE, NH_PAD); gtk_table_set_row_spacings(GTK_TABLE(table), NH_PAD); gtk_table_set_col_spacings(GTK_TABLE(table), NH_PAD); for(i = 0; i < n_extcmds; i++) { if (!strcmp(extcmds[i], "?")) { /* * Rather more useful than '?' in these circumstances -ALI */ d = gtk_button_new_from_stock(GTK_STOCK_CANCEL); col = (i == n_extcmds - 1 && i%3 == 0) ? 1 : i%3; data = -1; } else { d = gtk_button_new_with_label(extcmds[i]); col = i%3; data = i; } d = nh_gtk_new_and_attach(d, table, "", col, col+1, i/3, i/3+1); gtk_signal_connect(GTK_OBJECT(d), "clicked", GTK_SIGNAL_FUNC(extcmd_clicked), (gpointer)data); } gtk_grab_add(window); gtk_widget_show_all(window); gtk_main(); if (hid > 0) { gtk_widget_unmap(window); gtk_signal_disconnect(GTK_OBJECT(window), hid); gtk_widget_destroy(vbox); gtk_widget_destroy(frame); gtk_widget_destroy(window); } i = extcmd; extcmd = 0; return i; }