/* SCCS Id: @(#)gnmain.c 3.4 2000/07/16 */ /* Copyright (C) 1998 by Erik Andersen */ /* NetHack may be freely redistributed. See license for details. */ #include "gnmain.h" #include "gnsignal.h" #include "gnbind.h" #include "gnopts.h" #include #include #include #include #include #include #include "hack.h" #include "date.h" static GtkWidget* mainWindow=NULL; static GtkWidget *about=NULL; static GtkWidget* hBoxFirstRow; static GtkWidget* vBoxMain; int restarted = 0; int os_x = 0, os_y = 0, os_w = 0, os_h = 0; static GnomeClient *session_id; static void ghack_quit_game(GtkWidget *widget, int button) { gtk_widget_hide(widget); if (button == 0) { gnome_exit_nhwindows(0); gtk_object_unref(GTK_OBJECT(session_id)); } } static void ghack_quit_game_cb(GtkWidget *widget, gpointer data) { GtkWidget *box; box = gnome_message_box_new(_("Do you really want to quit?"), GNOME_MESSAGE_BOX_QUESTION, GNOME_STOCK_BUTTON_YES, GNOME_STOCK_BUTTON_NO, NULL); gnome_dialog_set_default( GNOME_DIALOG(box), 1); gnome_dialog_set_parent (GNOME_DIALOG (box), GTK_WINDOW (ghack_get_main_window ()) ); gnome_dialog_set_accelerator (GNOME_DIALOG(box), 1, 'n', 0); gnome_dialog_set_accelerator (GNOME_DIALOG(box), 0, 'y', 0); gtk_window_set_modal( GTK_WINDOW(box), TRUE); gtk_signal_connect( GTK_OBJECT(box), "clicked", (GtkSignalFunc)ghack_quit_game, NULL); gtk_widget_show(box); } static void ghack_save_game(GtkWidget *widget, int button) { gtk_widget_hide(widget); if (button == 0) { if(dosave0()) { /* make sure they see the Saving message */ display_nhwindow(WIN_MESSAGE, TRUE); gnome_exit_nhwindows("Be seeing you..."); } else (void)doredraw(); } } void ghack_save_game_cb(GtkWidget *widget, gpointer data) { GtkWidget *box; box = gnome_message_box_new(_("Quit and save the current game?"), GNOME_MESSAGE_BOX_QUESTION, GNOME_STOCK_BUTTON_YES, GNOME_STOCK_BUTTON_NO, NULL); gnome_dialog_set_default( GNOME_DIALOG(box), 1); gnome_dialog_set_parent (GNOME_DIALOG (box), GTK_WINDOW (ghack_get_main_window ()) ); gnome_dialog_set_accelerator (GNOME_DIALOG(box), 1, 'n', 0); gnome_dialog_set_accelerator (GNOME_DIALOG(box), 0, 'y', 0); gtk_window_set_modal( GTK_WINDOW(box), TRUE); gtk_signal_connect( GTK_OBJECT(box), "clicked", (GtkSignalFunc)ghack_save_game, NULL); gtk_widget_show(box); } static void ghack_new_game(GtkWidget *widget, int button) { if (button == 0) { g_message("This feature is not yet implemented. Sorry."); } } static void ghack_new_game_cb(GtkWidget *widget, gpointer data) { GtkWidget *box; box = gnome_message_box_new(_("Start a new game?"), GNOME_MESSAGE_BOX_QUESTION, GNOME_STOCK_BUTTON_YES, GNOME_STOCK_BUTTON_NO, NULL); gnome_dialog_set_default( GNOME_DIALOG(box), 1); gnome_dialog_set_parent (GNOME_DIALOG (box), GTK_WINDOW (ghack_get_main_window ()) ); gnome_dialog_set_accelerator (GNOME_DIALOG(box), 1, 'n', 0); gnome_dialog_set_accelerator (GNOME_DIALOG(box), 0, 'y', 0); gtk_window_set_modal( GTK_WINDOW(box), TRUE); gtk_signal_connect( GTK_OBJECT(box), "clicked", (GtkSignalFunc)ghack_new_game, NULL); gtk_widget_show(box); } static void about_destroy_callback (void) { about = NULL; } static void ghack_about_cb(GtkWidget *widget, gpointer data) { char buf[BUFSZ]="\0"; char buf1[BUFSZ]="\0"; const gchar *authors[] = {"Erik Andersen", "Anthony Taylor", "Jeff Garzik", "The Nethack Dev Team", NULL}; if (about) { gdk_window_raise (about->window); return; } getversionstring(buf); strcat( buf1, VERSION_STRING); strcat( buf, _("\nSend comments and bug reports to: nethack-bugs@nethack.org\n" "This game is free software. See License for details.")); about = gnome_about_new(_("Nethack"), buf1, "Copyright (C) 1985-2002 Mike Stephenson", (const char **)authors, buf, NULL); gtk_signal_connect (GTK_OBJECT (about), "destroy", (GtkSignalFunc) about_destroy_callback, NULL); gtk_widget_show(about); } static void ghack_settings_cb(GtkWidget *widget, gpointer data) { ghack_settings_dialog(); } static void ghack_accelerator_selected (GtkWidget *widget, gpointer data) { GdkEventKey event; int key = GPOINTER_TO_INT( data); /* g_message("An accelerator for \"%c\" was selected", key); */ /* stuff a key directly into the keybuffer */ event.state=0; event.keyval=key; ghack_handle_key_press(NULL, &event, NULL); } #ifndef M # ifndef NHSTDC # define M(c) (0x80 | (c)) # else # define M(c) ((c) - 128) # endif /* NHSTDC */ #endif #ifndef C #define C(c) (0x1f & (c)) #endif GnomeUIInfo game_tree[] = { { GNOME_APP_UI_ITEM, N_ ("_Change Settings..."), N_("Change Game Settings"), ghack_settings_cb, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL, 0,0, NULL }, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("Version"), NULL, ghack_accelerator_selected, GINT_TO_POINTER('v'), NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT, 'v',0 }, { GNOME_APP_UI_ITEM, N_("History..."), NULL, ghack_accelerator_selected, GINT_TO_POINTER('V'), NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT, 'V',GDK_SHIFT_MASK }, { GNOME_APP_UI_ITEM, N_("Compilation..."), NULL, ghack_accelerator_selected, GINT_TO_POINTER(M('v')), NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT,'v',GDK_MOD1_MASK }, { GNOME_APP_UI_ITEM, N_("Options..."), NULL, ghack_accelerator_selected, GINT_TO_POINTER('O'), NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PREF, 'O', GDK_SHIFT_MASK }, { GNOME_APP_UI_ITEM, N_("Explore Mode..."), NULL, ghack_accelerator_selected, GINT_TO_POINTER('X'), NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_QUIT, 'X', GDK_SHIFT_MASK }, GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_MENU_NEW_GAME_ITEM(ghack_new_game_cb, NULL), GNOMEUIINFO_MENU_SAVE_ITEM(ghack_save_game_cb, NULL), { GNOME_APP_UI_ITEM, N_("Exit"), NULL, ghack_quit_game_cb, GINT_TO_POINTER('Q'), NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT, 'Q', GDK_SHIFT_MASK }, GNOMEUIINFO_END }; GnomeUIInfo edit_menu[] = { { GNOME_APP_UI_ITEM, N_("Inventory"), N_("Edit/View your Inventory"), ghack_accelerator_selected, GINT_TO_POINTER('i'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'i', 0 }, { GNOME_APP_UI_ITEM, N_("Discoveries"), N_("Edit/View your Discoveries"), ghack_accelerator_selected, GINT_TO_POINTER('\\'), NULL, GNOME_APP_PIXMAP_NONE, NULL, '\\',0 }, { GNOME_APP_UI_ITEM, N_("List/reorder your spells"), N_("List/reorder your spells"), ghack_accelerator_selected, GINT_TO_POINTER('x'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'x', 0 }, { GNOME_APP_UI_ITEM, N_("Adjust letters"), N_("Adjust letter for items in your Inventory"), ghack_accelerator_selected, GINT_TO_POINTER(M('a')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'a', GDK_MOD1_MASK }, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("Name object"), N_("Assign a name to an object"), ghack_accelerator_selected, GINT_TO_POINTER(M('n')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'n', GDK_MOD1_MASK }, { GNOME_APP_UI_ITEM, N_("Name creature"), N_("Assign a name to a creature"), ghack_accelerator_selected, GINT_TO_POINTER('C'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'C', GDK_SHIFT_MASK }, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("Qualifications"), N_("Edit your Qualifications"), ghack_accelerator_selected, GINT_TO_POINTER(M('e')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'e',GDK_MOD1_MASK }, GNOMEUIINFO_END }; GnomeUIInfo apparel_menu[] = { { GNOME_APP_UI_ITEM, N_("Wield Weapon"), N_("Select a weapon to fight with"), ghack_accelerator_selected, GINT_TO_POINTER('w'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'w',0 }, { GNOME_APP_UI_ITEM, N_("Remove Apparel..."), N_("Remove apparel dialog bog"), ghack_accelerator_selected, GINT_TO_POINTER('A'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'A',GDK_SHIFT_MASK }, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("Wear Armor"), N_("Put on armor"), ghack_accelerator_selected, GINT_TO_POINTER('W'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'W',GDK_SHIFT_MASK }, { GNOME_APP_UI_ITEM, N_("Take off Armor"), N_("Take off armor you are wearing"), ghack_accelerator_selected, GINT_TO_POINTER('T'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'T',GDK_SHIFT_MASK }, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("Put on non-armor"), N_("Put on non-armor apparel"), ghack_accelerator_selected, GINT_TO_POINTER('P'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'P',GDK_SHIFT_MASK }, { GNOME_APP_UI_ITEM, N_("Remove non-armor"), N_("Remove non-armor apparel you are wearing"), ghack_accelerator_selected, GINT_TO_POINTER('R'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'R',GDK_SHIFT_MASK }, GNOMEUIINFO_END }; GnomeUIInfo action_menu[] = { { GNOME_APP_UI_ITEM, N_("Get"), N_("Pick up things at the current location"), ghack_accelerator_selected, GINT_TO_POINTER(','), NULL, GNOME_APP_PIXMAP_NONE, NULL, ',',0 }, { GNOME_APP_UI_ITEM, N_("Loot"), N_("loot a box on the floor"), ghack_accelerator_selected, GINT_TO_POINTER(M('l')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'l',GDK_MOD1_MASK }, { GNOME_APP_UI_ITEM, N_("Sit"), N_("sit down"), ghack_accelerator_selected, GINT_TO_POINTER(M('s')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 's',GDK_MOD1_MASK }, { GNOME_APP_UI_ITEM, N_("Force"), N_("force a lock"), ghack_accelerator_selected, GINT_TO_POINTER(M('f')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'f',GDK_MOD1_MASK }, { GNOME_APP_UI_ITEM, N_("Kick"), N_("kick something (usually a door)"), ghack_accelerator_selected, GINT_TO_POINTER(C('d')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'd',GDK_CONTROL_MASK }, { GNOME_APP_UI_ITEM, N_("Jump"), N_("jump to another location"), ghack_accelerator_selected, GINT_TO_POINTER(M('j')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'j',GDK_MOD1_MASK }, #ifdef STEED { GNOME_APP_UI_ITEM, N_("Ride"), N_("Ride (or stop riding) a monster"), doride, GINT_TO_POINTER(M('r')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'R',GDK_MOD1_MASK }, #endif { GNOME_APP_UI_ITEM, N_("Wipe face"), N_("wipe off your face"), ghack_accelerator_selected, GINT_TO_POINTER(M('w')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'w',GDK_MOD1_MASK }, { GNOME_APP_UI_ITEM, N_("Throw/Shoot"), N_("throw or shoot a weapon"), ghack_accelerator_selected, GINT_TO_POINTER('t'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 't',0 }, { GNOME_APP_UI_ITEM, N_("Open Door"), N_("open a door"), ghack_accelerator_selected, GINT_TO_POINTER('o'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'o',0 }, { GNOME_APP_UI_ITEM, N_("Close Door"), N_("open a door"), ghack_accelerator_selected, GINT_TO_POINTER('c'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'c',0 }, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("Drop"), N_("drop an object"), ghack_accelerator_selected, GINT_TO_POINTER('d'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'd',0 }, { GNOME_APP_UI_ITEM, N_("Drop Many"), N_("drop selected types of objects"), ghack_accelerator_selected, GINT_TO_POINTER('D'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'D',GDK_SHIFT_MASK }, { GNOME_APP_UI_ITEM, N_("Eat"), N_("eat something"), ghack_accelerator_selected, GINT_TO_POINTER('e'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'e',0 }, { GNOME_APP_UI_ITEM, N_("Engrave"), N_("write a message in the dust on the floor"), ghack_accelerator_selected, GINT_TO_POINTER('E'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'E',GDK_SHIFT_MASK }, { GNOME_APP_UI_ITEM, N_("Apply"), N_("apply or use a tool (pick-axe, key, camera, etc.)"), ghack_accelerator_selected, GINT_TO_POINTER('a'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'a',0 }, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("Up"), N_("go up the stairs"), ghack_accelerator_selected, GINT_TO_POINTER('<'), NULL, GNOME_APP_PIXMAP_NONE, NULL, '<',0 }, { GNOME_APP_UI_ITEM, N_("Down"), N_("go down the stairs"), ghack_accelerator_selected, GINT_TO_POINTER('>'), NULL, GNOME_APP_PIXMAP_NONE, NULL, '>',0 }, { GNOME_APP_UI_ITEM, N_("Rest"), N_("wait for a moment"), ghack_accelerator_selected, GINT_TO_POINTER('.'), NULL, GNOME_APP_PIXMAP_NONE, NULL, '.',0 }, { GNOME_APP_UI_ITEM, N_("Search"), N_("search for secret doors, hidden traps and monsters"), ghack_accelerator_selected, GINT_TO_POINTER('s'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 's',0 }, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("Chat"), N_("talk to someone"), ghack_accelerator_selected, GINT_TO_POINTER(M('c')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'c',GDK_MOD1_MASK }, { GNOME_APP_UI_ITEM, N_("Pay"), N_("pay your bill to the shopkeeper"), ghack_accelerator_selected, GINT_TO_POINTER('p'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'p',0 }, GNOMEUIINFO_END }; GnomeUIInfo magic_menu[] = { { GNOME_APP_UI_ITEM, N_("Quaff potion"), N_("drink a potion"), ghack_accelerator_selected, GINT_TO_POINTER('q'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'q',0 }, { GNOME_APP_UI_ITEM, N_("Read Book/Scroll"), N_("read a spell book or a scroll"), ghack_accelerator_selected, GINT_TO_POINTER('r'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'r',0 }, { GNOME_APP_UI_ITEM, N_("Zap Wand"), N_("zap a wand"), ghack_accelerator_selected, GINT_TO_POINTER('z'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'z',0 }, { GNOME_APP_UI_ITEM, N_("Zap Spell"), N_("cast a spell"), ghack_accelerator_selected, GINT_TO_POINTER('Z'), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'Z',GDK_SHIFT_MASK }, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("Dip"), N_("dip an object into something"), ghack_accelerator_selected, GINT_TO_POINTER(M('d')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'd',GDK_MOD1_MASK }, { GNOME_APP_UI_ITEM, N_("Rub"), N_("Rub something (i.e. a lamp)"), ghack_accelerator_selected, GINT_TO_POINTER(M('r')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'r',GDK_MOD1_MASK }, { GNOME_APP_UI_ITEM, N_("Invoke"), N_("invoke an object's special powers"), ghack_accelerator_selected, GINT_TO_POINTER(M('i')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'i',GDK_MOD1_MASK }, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("Offer"), N_("offer a sacrifice to the gods"), ghack_accelerator_selected, GINT_TO_POINTER(M('o')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'o',GDK_MOD1_MASK }, { GNOME_APP_UI_ITEM, N_("Pray"), N_("pray to the gods for help"), ghack_accelerator_selected, GINT_TO_POINTER(M('p')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'p',GDK_MOD1_MASK }, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("Teleport"), N_("teleport (if you can)"), ghack_accelerator_selected, GINT_TO_POINTER(C('t')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 't',GDK_CONTROL_MASK }, { GNOME_APP_UI_ITEM, N_("Monster Action"), N_("use a monster's special ability"), ghack_accelerator_selected, GINT_TO_POINTER(M('m')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 'm',GDK_MOD1_MASK }, { GNOME_APP_UI_ITEM, N_("Turn Undead"), N_("turn undead"), ghack_accelerator_selected, GINT_TO_POINTER(M('t')), NULL, GNOME_APP_PIXMAP_NONE, NULL, 't',GDK_MOD1_MASK }, GNOMEUIINFO_END }; GnomeUIInfo help_menu[] = { { GNOME_APP_UI_ITEM, N_("About..."), N_("About GnomeHack"), ghack_about_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT, 0, 0, NULL }, { GNOME_APP_UI_ITEM, N_("Help"), NULL, ghack_accelerator_selected, GINT_TO_POINTER('?'), NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT, '?', 0 }, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("What is here"), N_("Check what items occupy the current location"), ghack_accelerator_selected, GINT_TO_POINTER(':'), NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT, ':',0 }, { GNOME_APP_UI_ITEM, N_("What is that"), N_("Identify an object"), ghack_accelerator_selected, GINT_TO_POINTER(';'), NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT, ';',0 }, { GNOME_APP_UI_ITEM, N_("Identify a map symbol"), N_("Identify a map symbol"), ghack_accelerator_selected, GINT_TO_POINTER('/'), NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT, '/',0 }, GNOMEUIINFO_END }; GnomeUIInfo mainmenu[] = { GNOMEUIINFO_MENU_GAME_TREE(game_tree), GNOMEUIINFO_MENU_EDIT_TREE(edit_menu), { GNOME_APP_UI_SUBTREE, N_("Apparel"), NULL, apparel_menu, NULL, NULL, 0, NULL, 0, 0, NULL }, { GNOME_APP_UI_SUBTREE, N_("Action"), NULL, action_menu, NULL, NULL, 0, NULL, 0, 0, NULL }, { GNOME_APP_UI_SUBTREE, N_("Magic"), NULL, magic_menu, NULL, NULL, 0, NULL, 0, 0, NULL }, GNOMEUIINFO_MENU_HELP_TREE(help_menu), GNOMEUIINFO_END }; static void ghack_main_window_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data) { /* First, turn off the key press propogation. We've got the * key, but we don't wan't the underlying Gtk widgets to get it, * since they do the wrong thing with the arrow keys (shift focus)... */ gtk_signal_emit_stop_by_name( GTK_OBJECT(mainWindow), "key_press_event"); /* stuff the key event into the keybuffer */ ghack_handle_key_press(widget, event, data); } /* parsing args */ void parse_args (int argc, char *argv[]) { gint ch; struct option options[] = { /* Default args */ { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } }; gchar *id = NULL; /* initialize getopt */ optarg = NULL; optind = 0; optopt = 0; while( (ch = getopt_long(argc, argv, "hv", options, NULL)) != EOF ) { switch(ch) { case 'h': g_print ( _("%s: A gnomified 'Hello World' program\n\n" "Usage: %s [--help] [--version]\n\n" "Options:\n" " --help display this help and exit\n" " --version output version information and exit\n"), argv[0], argv[0]); exit(0); break; case 'v': g_print (_("NetHack %s.\n"), VERSION_STRING); exit(0); break; case ':': case '?': g_print (_("Options error\n")); exit(0); break; } } /* SM stuff */ session_id = gnome_client_new (); #if 0 session_id = gnome_client_new ( /* callback to save the state and parameter for it */ save_state, argv[0], /* callback to die and parameter for it */ NULL, NULL, /* id from the previous session if restarted, NULL otherwise */ id); #endif /* set the program name */ gnome_client_set_program (session_id, argv[0]); g_free(id); return; } /* * [ALI] Gnome installs its own handler(s) for SIGBUS, SIGFPE and SIGSEGV. * These handlers will fork and exec a helper program. When that helper * comes to initialize GTK+, it may fail if setuid/setgid. We solve this * by dropping privileges before passing the signal along the chain. * Note: We don't need to either drop or mask the saved ID since this * will be reset when the child process performs the execve() anyway. */ static struct { int signum; void (*handler)(int); } ghack_chain[] = { {SIGBUS}, {SIGFPE}, {SIGSEGV}, {SIGILL} /* Not currently handled by Gnome */ }; static void ghack_sig_handler(int signum) { int i; uid_t uid, euid; gid_t gid, egid; uid = getuid(); euid = geteuid(); gid = getgid(); egid = getegid(); if (gid != egid) setgid(gid); if (uid != euid) setuid(uid); for(i = SIZE(ghack_chain) - 1; i >= 0; i--) if (ghack_chain[i].signum == signum) { ghack_chain[i].handler(signum); break; } if (i < 0) impossible("Unhandled ghack signal"); if (uid != euid) setuid(euid); if (gid != egid) setgid(egid); } /* initialize gnome and fir up the main window */ void ghack_init_main_window( int argc, char** argv) { int i; struct timeval tv; uid_t uid, euid; /* It seems that the authors of gnome_score_init() drop group * priveledges. We need group priveledges, so until we change the * way we save games to do things the gnome way(???), this stays * commented out. (after hours of frusteration...) * -Erik */ /* gnome_score_init("gnomehack"); */ gettimeofday(&tv, NULL); srand(tv.tv_usec); uid = getuid(); euid = geteuid(); if (uid != euid) setuid(uid); hide_privileges(TRUE); /* XXX gnome_init must print nethack options for --help, but does not */ gnome_init ("nethack", VERSION_STRING, argc, argv); hide_privileges(FALSE); parse_args (argc, argv); /* Initialize the i18n stuff (not that gnomehack supperts it yet...) */ #if 0 textdomain (PACKAGE); #endif gdk_imlib_init(); /* Main window */ mainWindow = gnome_app_new((char *) "nethack", (char *) N_("Nethack for Gnome")); gtk_widget_realize(mainWindow); if (restarted) { gtk_widget_set_uposition (mainWindow, os_x, os_y); gtk_widget_set_usize (mainWindow, os_w, os_h); } gtk_window_set_default_size( GTK_WINDOW(mainWindow), 800, 600); gtk_window_set_policy(GTK_WINDOW(mainWindow), FALSE, TRUE, TRUE); gnome_app_create_menus(GNOME_APP(mainWindow), mainmenu); gtk_signal_connect(GTK_OBJECT(mainWindow), "key_press_event", GTK_SIGNAL_FUNC(ghack_main_window_key_press), NULL); gtk_signal_connect(GTK_OBJECT(mainWindow), "delete_event", GTK_SIGNAL_FUNC(ghack_quit_game_cb), NULL); /* Put some stuff into our main window */ vBoxMain = gtk_vbox_new (FALSE, 0); hBoxFirstRow = gtk_hbox_new (FALSE, 0); /* pack Boxes into other boxes to produce the right structure */ gtk_box_pack_start (GTK_BOX (vBoxMain), hBoxFirstRow, FALSE, TRUE, 0); /* pack vBoxMain which contains all our widgets into the main window. */ gnome_app_set_contents(GNOME_APP(mainWindow), vBoxMain); /* DONT show the main window yet, due to a Gtk bug that causes it * to not refresh the window when adding widgets after the window * has already been shown */ if (uid != euid) setuid(euid); for(i = 0; i < SIZE(ghack_chain); i++) ghack_chain[i].handler = signal(ghack_chain[i].signum, ghack_sig_handler); } void ghack_main_window_add_map_window(GtkWidget* win) { GtkWidget *vBox; vBox= gtk_vbox_new (TRUE, 0); gtk_box_pack_start (GTK_BOX (vBox), win, TRUE, TRUE, 2); gtk_box_pack_start (GTK_BOX (vBoxMain), vBox, TRUE, TRUE, 2); gtk_widget_show_all(vBox); /* Ok, now show the main window -- now that we have added in * all the windows (relys on nethack displaying the map window last * (This is an ugly kludge, BTW) */ gtk_widget_show_all(mainWindow); } void ghack_main_window_add_message_window(GtkWidget* win) { gtk_box_pack_start (GTK_BOX (hBoxFirstRow), win, TRUE, TRUE, 2); gtk_widget_show_all(win); } void ghack_main_window_add_status_window(GtkWidget* win) { gtk_box_pack_start (GTK_BOX (hBoxFirstRow), win, FALSE, TRUE, 2); gtk_widget_show_all(win); } void ghack_main_window_add_worn_window(GtkWidget* win) { gtk_box_pack_end (GTK_BOX (hBoxFirstRow), win, FALSE, TRUE, 2); gtk_widget_show_all(win); } void ghack_main_window_add_text_window(GtkWidget *win) { g_warning("Fixme!!! AddTextWindow is not yet implemented"); } void ghack_main_window_remove_window(GtkWidget *win) { g_warning("Fixme!!! RemoveWindow is not yet implemented"); } void ghack_main_window_update_inventory() { /* For now, do very little. Eventually we may allow the inv. window to stay active. When we do this, we'll need to implement this... g_warning("Fixme!!! updateInventory is not yet implemented"); */ gnome_display_nhwindow(WIN_WORN, FALSE); } GtkWidget* ghack_get_main_window() { return( GTK_WIDGET(mainWindow) ); }