- fix destruction of primary game windows - One, it makes the color of the cursor box dynamic (these are the gnmap.c changes), based on hp/hpmax (continuous colors white -> yellow -> red -> magenta rather than discrete like in Qt). - Two, it adds a new window, NHW_WORN (all the other changes and new files gnworn.[ch]), placed at the end of the first row, to the right of the status, with tiles of all the items currently equiped. I had to change the spacing of the first row (no longer homogeneous) to accomodate this, but I think it still looks okay. It's mostly like the Qt version but the equiped items are in slightly different places, and a bit more compactly (added quiver, ball/chain, monster skin armor; see the definition in gnworn.c for the layout).
834 lines
25 KiB
C
834 lines
25 KiB
C
/* SCCS Id: @(#)gnmain.c 3.4 2000/07/16 */
|
|
/* Copyright (C) 1998 by Erik Andersen <andersee@debian.org> */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
#include "gnmain.h"
|
|
#include "gnsignal.h"
|
|
#include "gnbind.h"
|
|
#include "gnopts.h"
|
|
#include <gnome.h>
|
|
#include <getopt.h>
|
|
#include <gdk/gdk.h>
|
|
#include <sys/time.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
#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) );
|
|
}
|