]> granicus.if.org Git - nethack/commitdiff
*** empty log message ***
authorjwalz <jwalz>
Sat, 5 Jan 2002 21:06:01 +0000 (21:06 +0000)
committerjwalz <jwalz>
Sat, 5 Jan 2002 21:06:01 +0000 (21:06 +0000)
win/gnome/gnbind.c [new file with mode: 0644]

diff --git a/win/gnome/gnbind.c b/win/gnome/gnbind.c
new file mode 100644 (file)
index 0000000..3fed89b
--- /dev/null
@@ -0,0 +1,1011 @@
+/*     SCCS Id: @(#)gnbind.c   3.3     2000/07/16      */
+/* Copyright (C) 1998 by Erik Andersen <andersee@debian.org> */
+/* NetHack may be freely redistributed.  See license for details. */
+
+/*
+ * This file implements the interface between the window port specific
+ * code in the Gnome port and the rest of the nethack game engine. 
+*/
+
+#include "gnbind.h"
+#include "gnmain.h"
+#include "gnaskstr.h"
+#include "gnyesno.h"
+
+GNHWinData gnome_windowlist[MAXWINDOWS];
+
+extern void tty_raw_print(const char *);
+extern void tty_raw_print_bold(const char *);
+
+
+/* Interface definition, for windows.c */
+struct window_procs Gnome_procs = {
+    "Gnome",
+    gnome_init_nhwindows,
+    gnome_player_selection,
+    gnome_askname,
+    gnome_get_nh_event,
+    gnome_exit_nhwindows,
+    gnome_suspend_nhwindows,
+    gnome_resume_nhwindows,
+    gnome_create_nhwindow,
+    gnome_clear_nhwindow,
+    gnome_display_nhwindow,
+    gnome_destroy_nhwindow,
+    gnome_curs,
+    gnome_putstr,
+    gnome_display_file,
+    gnome_start_menu,
+    gnome_add_menu,
+    gnome_end_menu,
+    gnome_select_menu,
+    genl_message_menu,         /* no need for X-specific handling */
+    gnome_update_inventory,
+    gnome_mark_synch,
+    gnome_wait_synch,
+#ifdef CLIPPING
+    gnome_cliparound,
+#endif
+#ifdef POSITIONBAR
+    donull,
+#endif
+    gnome_print_glyph,
+    gnome_raw_print,
+    gnome_raw_print_bold,
+    gnome_nhgetch,
+    gnome_nh_poskey,
+    gnome_nhbell,
+    gnome_doprev_message,
+    gnome_yn_function,
+    gnome_getlin,
+    gnome_get_ext_cmd,
+    gnome_number_pad,
+    gnome_delay_output,
+#ifdef CHANGE_COLOR    /* only a Mac option currently */
+    donull,
+    donull,
+#endif
+    /* other defs that really should go away (they're tty specific) */
+    gnome_start_screen,
+    gnome_end_screen,
+    gnome_outrip,
+};
+
+/*  
+init_nhwindows(int* argcp, char** argv)
+                -- Initialize the windows used by NetHack.  This can also
+                   create the standard windows listed at the top, but does
+                   not display them.
+                -- Any commandline arguments relevant to the windowport
+                   should be interpreted, and *argcp and *argv should
+                   be changed to remove those arguments.
+                -- When the message window is created, the variable
+                   iflags.window_inited needs to be set to TRUE.  Otherwise
+                   all plines() will be done via raw_print().
+                ** Why not have init_nhwindows() create all of the "standard"
+                ** windows?  Or at least all but WIN_INFO?      -dean
+*/
+void gnome_init_nhwindows(int* argc, char** argv)
+{
+    /* Main window */
+    ghack_init_main_window( *argc, argv);
+    ghack_init_signals( );
+
+#ifdef HACKDIR
+    //if (ghack_init_glyphs(HACKDIR "/t32-1024.xpm"))
+    if (ghack_init_glyphs(HACKDIR "/x11tiles"))
+      g_error ("ERROR:  Could not initialize glyphs.\n");
+#else
+#   error HACKDIR is not defined!
+#endif
+  
+    /* Force wizard mode on for debugging */
+    //wizard = TRUE;
+    
+    iflags.window_inited = TRUE;
+}
+
+
+/* Do a window-port specific player type selection. If player_selection()
+   offers a Quit option, it is its responsibility to clean up and terminate
+   the process. You need to fill in pl_character[0].
+*/
+void gnome_player_selection()
+{
+  int num_roles, availcount, i, nRole;
+  const char** choices;
+
+  /* select a role */
+  for (num_roles = 0; roles[num_roles].name.m; ++num_roles) continue;
+  choices = (const char **)alloc(sizeof(char *) * (num_roles+1));
+  for (;;) {
+    availcount = 0;
+    for (i = 0; i < num_roles; i++) {
+      choices[i] = 0;
+      if (ok_role(i, flags.initrace,
+                 flags.initgend, flags.initalign)) {
+       choices[i] = roles[i].name.m;
+       if (flags.initgend >= 0 && flags.female && roles[i].name.f)
+         choices[i] = roles[i].name.f;
+       ++availcount;
+      }
+    }
+    if (availcount > 0) break;
+    else if (flags.initalign >= 0) flags.initalign = -1;    /* reset */
+    else if (flags.initgend >= 0) flags.initgend = -1;
+    else if (flags.initrace >= 0) flags.initrace = -1;
+    else panic("no available ROLE+race+gender+alignment combinations");
+  }
+  choices[num_roles] = (const char *) 0;
+  nRole=ghack_player_sel_dialog(choices);
+  
+  /* Quit */
+  if ( nRole == -1 )
+    {
+      clearlocks();
+      gnome_exit_nhwindows(0);
+    }
+  /* Random role */
+  if ( nRole == -2)
+    {
+      nRole = rn2(num_roles);
+      pline("This game you will be %s", an(choices[nRole]));
+    }
+  
+  flags.initrole = nRole;
+}
+
+
+/* Ask the user for a player name. */
+void gnome_askname()
+{
+    int ret;
+
+    g_message("Asking name....");
+
+    /* Ask for a name and stuff the response into plname, a nethack global */
+    ret = ghack_ask_string_dialog("What is your name?", "gandalf", 
+           "GnomeHack", plname);
+
+    /* Quit if they want to quit... */
+    if (ret==-1)
+      {
+        gnome_exit_nhwindows(0);
+      }
+}
+
+
+/* Does window event processing (e.g. exposure events).
+   A noop for the tty and X window-ports.
+*/
+void gnome_get_nh_event()
+{
+       /* We handle our own events. */
+       return;
+}
+
+/* Exits the window system.  This should dismiss all windows,
+   except the "window" used for raw_print().  str is printed if possible.
+*/
+void gnome_exit_nhwindows(const char *str)
+{
+       gtk_exit (0);
+       terminate(EXIT_SUCCESS);
+}
+
+/* Prepare the window to be suspended. */
+void gnome_suspend_nhwindows(const char *str)
+{
+       /* I don't think we need to do anything here... */
+       return;
+}
+
+
+/* Restore the windows after being suspended. */
+void gnome_resume_nhwindows()
+{
+       /* Do Nothing.  Un-necessary since the GUI will refresh itself. */
+       return;
+}
+
+/*  Create a window of type "type" which can be 
+        NHW_MESSAGE     (top line)
+        NHW_STATUS      (bottom lines)
+        NHW_MAP         (main dungeon)
+        NHW_MENU        (inventory or other "corner" windows)
+        NHW_TEXT        (help/text, full screen paged window)
+*/
+winid 
+gnome_create_nhwindow(int type)
+{
+
+  winid i = 0;
+
+/* Return the next available winid
+ */
+
+  for (i=0; i<MAXWINDOWS; i++)
+      if (gnome_windowlist[i].win == NULL)
+          break;
+  if (i == MAXWINDOWS)
+      g_error ("ERROR:  No windows available...\n");
+  gnome_create_nhwindow_by_id( type, i);
+  return i;
+}
+
+void
+gnome_create_nhwindow_by_id( int type, winid i)
+{
+    switch (type)
+      {
+      case NHW_MAP:
+       {
+         gnome_windowlist[i].win = ghack_init_map_window( );
+         gnome_windowlist[i].type = NHW_MAP;
+         ghack_main_window_add_map_window( gnome_windowlist[i].win);
+         break;
+       }
+      case NHW_MESSAGE:
+       {
+         gnome_windowlist[i].win = ghack_init_message_window( );
+         gnome_windowlist[i].type = NHW_MESSAGE;
+         ghack_main_window_add_message_window( gnome_windowlist[i].win);
+         break; 
+       }
+      case NHW_STATUS:
+       {
+         gnome_windowlist[i].win = ghack_init_status_window( );
+         gnome_windowlist[i].type = NHW_STATUS;
+         ghack_main_window_add_status_window( gnome_windowlist[i].win);
+         break;
+       }    
+      case NHW_MENU:
+       {
+         gnome_windowlist[i].type = NHW_MENU;
+         gnome_windowlist[i].win = ghack_init_menu_window( );
+         break;
+       } 
+      case NHW_TEXT:
+       {
+         gnome_windowlist[i].win = ghack_init_text_window( );
+         gnome_windowlist[i].type = NHW_TEXT;
+         break;
+       }
+      }
+}
+
+/* This widget is being destroyed before its time--
+ * clear its entry from the windowlist.
+*/
+void gnome_delete_nhwindow_by_reference( GtkWidget *menuWin)
+{
+  int i;
+
+  for (i = 0; i < MAXWINDOWS; i++) {
+    if (gnome_windowlist[i].win == menuWin) {
+      gnome_windowlist[i].win = NULL;
+      gnome_windowlist[i].type = 0;
+      break;
+    }
+  }
+}
+
+/* Clear the given window, when asked to. */
+void gnome_clear_nhwindow(winid wid)
+{
+  if (gnome_windowlist[wid].win != NULL)
+    {
+      gtk_signal_emit (GTK_OBJECT (gnome_windowlist[wid].win),
+                      ghack_signals[GHSIG_CLEAR]);
+    }
+}
+
+/* -- Display the window on the screen.  If there is data
+                   pending for output in that window, it should be sent.
+                   If blocking is TRUE, display_nhwindow() will not
+                   return until the data has been displayed on the screen,
+                   and acknowledged by the user where appropriate.
+                -- All calls are blocking in the tty window-port.
+                -- Calling display_nhwindow(WIN_MESSAGE,???) will do a
+                   --more--, if necessary, in the tty window-port.
+*/
+void gnome_display_nhwindow(winid wid, BOOLEAN_P block)
+{
+  if (gnome_windowlist[wid].win != NULL)
+    {
+      gtk_signal_emit( GTK_OBJECT (gnome_windowlist[wid].win),
+                      ghack_signals[GHSIG_DISPLAY],
+                      block);
+      if (block && (gnome_windowlist[wid].type == NHW_MAP))
+       (void) gnome_nhgetch();
+    }
+}
+
+
+/* Destroy will dismiss the window if the window has not 
+ * already been dismissed.
+*/
+void gnome_destroy_nhwindow(winid wid)
+{
+    if ((wid == NHW_MAP) || 
+        (wid == NHW_MESSAGE) || 
+        (wid == NHW_STATUS)) {
+       /* no thanks, I'll do these myself */
+       return;
+    }
+    if (wid != -1 && gnome_windowlist[wid].win != NULL)
+      {
+       gtk_widget_destroy(gnome_windowlist[wid].win);
+       gnome_windowlist[wid].win = NULL;
+       gnome_windowlist[wid].type = 0;
+      }
+}
+
+/* Next output to window will start at (x,y), also moves
+ displayable cursor to (x,y).  For backward compatibility,
+ 1 <= x < cols, 0 <= y < rows, where cols and rows are
+ the size of window.
+*/
+void gnome_curs(winid wid, int x, int y)
+{
+  if (wid != -1 && gnome_windowlist[wid].win != NULL)
+    {
+      gtk_signal_emit( GTK_OBJECT (gnome_windowlist[wid].win), 
+                      ghack_signals[GHSIG_CURS], x, y);
+    }
+}
+
+/*
+putstr(window, attr, str)
+                -- Print str on the window with the given attribute.  Only
+                   printable ASCII characters (040-0126) must be supported.
+                   Multiple putstr()s are output on separate lines.
+Attributes
+                   can be one of
+                        ATR_NONE (or 0)
+                        ATR_ULINE
+                        ATR_BOLD
+                        ATR_BLINK
+                        ATR_INVERSE
+                   If a window-port does not support all of these, it may map
+                   unsupported attributes to a supported one (e.g. map them
+                   all to ATR_INVERSE).  putstr() may compress spaces out of
+                   str, break str, or truncate str, if necessary for the
+                   display.  Where putstr() breaks a line, it has to clear
+                   to end-of-line.
+                -- putstr should be implemented such that if two putstr()s
+                   are done consecutively the user will see the first and
+                   then the second.  In the tty port, pline() achieves this
+                   by calling more() or displaying both on the same line.
+*/
+void gnome_putstr(winid wid, int attr, const char *text)
+{
+    if ((wid >= 0) && 
+        (wid < MAXWINDOWS) &&
+        (gnome_windowlist[wid].win != NULL))
+    {
+      gtk_signal_emit( GTK_OBJECT (gnome_windowlist[wid].win),
+                      ghack_signals[GHSIG_PUTSTR],
+                      (guint) attr,
+                      text);
+    }
+}
+
+/* Display the file named str.  Complain about missing files
+                   iff complain is TRUE.
+*/
+void gnome_display_file(const char *filename,BOOLEAN_P must_exist)
+{
+       /* Strange -- for some reason it makes us create a new text window
+        * instead of reusing any existing ones -- perhaps we can work out
+        * some way to reuse stuff -- but for now just make and destroy new
+        * ones each time */
+        
+       dlb *f;
+       
+        f = dlb_fopen(filename, "r");
+        if (!f) {
+         if (must_exist) {
+           GtkWidget *box;
+            char message[90];
+            sprintf(message, "Warning! Could not find file: %s\n",filename);
+
+           box = gnome_message_box_new (_(message),
+                   GNOME_MESSAGE_BOX_ERROR,
+                   GNOME_STOCK_BUTTON_OK,
+                   NULL);
+           gnome_dialog_set_default( GNOME_DIALOG(box), 0);
+           gnome_dialog_set_parent (GNOME_DIALOG (box), 
+                   GTK_WINDOW (ghack_get_main_window ()) );
+           gtk_window_set_modal( GTK_WINDOW(box), TRUE);
+           gtk_widget_show (box);
+         }
+        }
+       else {
+         GtkWidget *txtwin, *gless, *frametxt;
+#define LLEN 128
+         char line[LLEN], *textlines;
+         int num_lines, charcount;
+
+         txtwin = gnome_dialog_new("Text Window", GNOME_STOCK_BUTTON_OK,
+                                   NULL);
+          gtk_widget_set_usize(GTK_WIDGET(txtwin), 500, 400);
+          gtk_window_set_policy(GTK_WINDOW(txtwin), TRUE, TRUE, FALSE);
+          gtk_window_set_title(GTK_WINDOW(txtwin), "Text Window");
+         gnome_dialog_set_default( GNOME_DIALOG(txtwin), 0);
+         gtk_window_set_modal( GTK_WINDOW(txtwin), TRUE);
+         frametxt = gtk_frame_new ("");
+         gtk_widget_show (frametxt);
+
+         /*
+          * Count the number of lines and characters in the file.
+          */
+         num_lines = 0;
+         charcount = 1;
+         while (dlb_fgets(line, LLEN, f)) {
+           num_lines++;
+           charcount += strlen(line);
+         }
+         (void) dlb_fclose(f);
+         
+         /* Ignore empty files */
+         if (num_lines == 0) return;
+
+         /*
+          * Re-open the file and read the data into a buffer.  
+          */
+         textlines = (char *) alloc((unsigned int) charcount);
+         textlines[0] = '\0';
+         f = dlb_fopen( filename, RDTMODE);
+
+         while (dlb_fgets(line, LLEN, f)) {
+           (void) strcat(textlines, line);
+         }
+         (void) dlb_fclose(f);
+
+         gless = gnome_less_new ();
+         gnome_less_show_string (GNOME_LESS (gless), textlines);
+         gtk_container_add (GTK_CONTAINER (frametxt), gless);
+          gtk_box_pack_start(GTK_BOX (GNOME_DIALOG (txtwin)->vbox), frametxt,
+                             TRUE, TRUE, 0);
+         gtk_widget_show_all( txtwin);
+         gtk_window_set_modal( GTK_WINDOW(txtwin), TRUE);
+         gnome_dialog_set_parent (GNOME_DIALOG (txtwin), 
+                 GTK_WINDOW (ghack_get_main_window ()) );
+         gnome_dialog_run_and_close (GNOME_DIALOG (txtwin));
+         free(textlines);
+        }
+}
+
+/* Start using window as a menu.  You must call start_menu()
+   before add_menu().  After calling start_menu() you may not
+   putstr() to the window.  Only windows of type NHW_MENU may
+   be used for menus.
+*/
+void gnome_start_menu(winid wid)
+{
+  if (wid != -1)
+    {
+      if (gnome_windowlist[wid].win == NULL && gnome_windowlist[wid].type != 0)
+       {
+         gnome_create_nhwindow_by_id(gnome_windowlist[wid].type, wid);
+       }
+        gtk_signal_emit( GTK_OBJECT (gnome_windowlist[wid].win),
+                      ghack_signals[GHSIG_START_MENU]);
+    }
+}
+
+/*
+add_menu(windid window, int glyph, const anything identifier,
+                                char accelerator, char groupacc,
+                                int attr, char *str, boolean preselected)
+                -- Add a text line str to the given menu window.  If identifier
+                   is 0, then the line cannot be selected (e.g. a title).
+                   Otherwise, identifier is the value returned if the line is
+                   selected.  Accelerator is a keyboard key that can be used
+                   to select the line.  If the accelerator of a selectable
+                   item is 0, the window system is free to select its own
+                   accelerator.  It is up to the window-port to make the
+                   accelerator visible to the user (e.g. put "a - " in front
+                   of str).  The value attr is the same as in putstr().
+                   Glyph is an optional glyph to accompany the line.  If
+                   window port cannot or does not want to display it, this
+                   is OK.  If there is no glyph applicable, then this
+                   value will be NO_GLYPH.
+                -- All accelerators should be in the range [A-Za-z].
+                -- It is expected that callers do not mix accelerator
+                   choices.  Either all selectable items have an accelerator
+                   or let the window system pick them.  Don't do both.
+                -- Groupacc is a group accelerator.  It may be any character
+                   outside of the standard accelerator (see above) or a
+                   number.  If 0, the item is unaffected by any group
+                   accelerator.  If this accelerator conflicts with
+                   the menu command (or their user defined alises), it loses.
+                   The menu commands and aliases take care not to interfere
+                   with the default object class symbols.
+                -- If you want this choice to be preselected when the
+                   menu is displayed, set preselected to TRUE.
+*/
+void gnome_add_menu(winid wid, int glyph, const ANY_P * identifier,
+               CHAR_P accelerator, CHAR_P group_accel, int attr, 
+               const char *str, BOOLEAN_P presel)
+{
+  GHackMenuItem item;
+  item.glyph =  glyph;
+  item.identifier = identifier;
+  item.accelerator = accelerator;
+  item.group_accel = group_accel;
+  item.attr = attr;
+  item.str = str;
+  item.presel = presel;
+
+  if (wid != -1 && gnome_windowlist[wid].win != NULL)
+    {
+      gtk_signal_emit( GTK_OBJECT (gnome_windowlist[wid].win),
+                      ghack_signals[GHSIG_ADD_MENU],
+                      &item);
+    }
+}
+
+/*
+end_menu(window, prompt)
+                -- Stop adding entries to the menu and flushes the window
+                   to the screen (brings to front?).  Prompt is a prompt
+                   to give the user.  If prompt is NULL, no prompt will
+                   be printed.
+                ** This probably shouldn't flush the window any more (if
+                ** it ever did).  That should be select_menu's job.  -dean
+*/
+void gnome_end_menu(winid wid, const char *prompt)
+{
+    if (wid != -1 && gnome_windowlist[wid].win != NULL)
+      {
+       gtk_signal_emit( GTK_OBJECT (gnome_windowlist[wid].win),
+                        ghack_signals[GHSIG_END_MENU],
+                        prompt);
+      }
+}
+
+/*
+int select_menu(windid window, int how, menu_item **selected)
+                -- Return the number of items selected; 0 if none were chosen,
+                   -1 when explicitly cancelled.  If items were selected, then
+                   selected is filled in with an allocated array of menu_item
+                   structures, one for each selected line.  The caller must
+                   free this array when done with it.  The "count" field
+                   of selected is a user supplied count.  If the user did
+                   not supply a count, then the count field is filled with
+                   -1 (meaning all).  A count of zero is equivalent to not
+                   being selected and should not be in the list.  If no items
+                   were selected, then selected is NULL'ed out.  How is the
+                   mode of the menu.  Three valid values are PICK_NONE,
+                   PICK_ONE, and PICK_N, meaning: nothing is selectable,
+                   only one thing is selectable, and any number valid items
+                   may selected.  If how is PICK_NONE, this function should
+                   never return anything but 0 or -1.
+                -- You may call select_menu() on a window multiple times --
+                   the menu is saved until start_menu() or destroy_nhwindow()
+                   is called on the window.
+                -- Note that NHW_MENU windows need not have select_menu()
+                   called for them. There is no way of knowing whether
+                   select_menu() will be called for the window at
+                   create_nhwindow() time.
+*/
+int gnome_select_menu(winid wid, int how, MENU_ITEM_P **selected)
+{
+    int nReturned = -1;
+
+    if (wid != -1 && gnome_windowlist[wid].win != NULL &&
+        gnome_windowlist[wid].type == NHW_MENU)
+      {
+       nReturned=ghack_menu_window_select_menu (gnome_windowlist[wid].win,
+                                      selected, how);
+      }
+
+    return nReturned;
+}
+
+/*
+    -- Indicate to the window port that the inventory has been changed.
+    -- Merely calls display_inventory() for window-ports that leave the 
+       window up, otherwise empty.
+*/
+void gnome_update_inventory()
+{
+    ghack_main_window_update_inventory();
+}
+
+/*
+mark_synch()    -- Don't go beyond this point in I/O on any channel until
+                   all channels are caught up to here.  Can be an empty call
+                   for the moment
+*/
+void gnome_mark_synch()
+{
+       /* Do nothing */
+}
+
+/*
+wait_synch()    -- Wait until all pending output is complete (*flush*() for
+                   streams goes here).
+                -- May also deal with exposure events etc. so that the
+                   display is OK when return from wait_synch().
+*/
+void gnome_wait_synch()
+{
+       /* Do nothing */
+}
+
+/*
+cliparound(x, y)-- Make sure that the user is more-or-less centered on the
+                   screen if the playing area is larger than the screen.
+                -- This function is only defined if CLIPPING is defined.
+*/
+void gnome_cliparound(int x, int y)
+{
+  /* FIXME!!!  winid should be a parameter!!!
+   * Call a function that Does The Right Thing(tm).
+  */
+    gnome_cliparound_proper(WIN_MAP,x,y);
+}
+
+void gnome_cliparound_proper(winid wid, int x, int y)
+{
+    if (wid != -1 && gnome_windowlist[wid].win != NULL)
+      {
+       gtk_signal_emit( GTK_OBJECT (gnome_windowlist[wid].win),
+                        ghack_signals[GHSIG_CLIPAROUND],
+                        (guint) x, 
+                        (guint) y);
+      }
+}
+
+/*
+print_glyph(window, x, y, glyph)
+                -- Print the glyph at (x,y) on the given window.  Glyphs are
+                   integers at the interface, mapped to whatever the window-
+                   port wants (symbol, font, color, attributes, ...there's
+                   a 1-1 map between glyphs and distinct things on the map).
+*/
+void gnome_print_glyph(winid wid,XCHAR_P x,XCHAR_P y,int glyph)
+{
+    if (wid != -1 && gnome_windowlist[wid].win != NULL)
+      {
+       GdkImlibImage *im;
+
+       im = ghack_image_from_glyph( glyph, FALSE);
+
+       gtk_signal_emit (GTK_OBJECT (gnome_windowlist[wid].win),
+                        ghack_signals[GHSIG_PRINT_GLYPH],
+                        (guint) x,
+                        (guint) y,
+                        im,
+                        NULL);
+    }
+}
+
+/*
+raw_print(str)  -- Print directly to a screen, or otherwise guarantee that
+                   the user sees str.  raw_print() appends a newline to str.
+                   It need not recognize ASCII control characters.  This is
+                   used during startup (before windowing system initialization
+                   -- maybe this means only error startup messages are raw),
+                   for error messages, and maybe other "msg" uses.  E.g.
+                   updating status for micros (i.e, "saving").
+*/
+void gnome_raw_print(const char *str)
+{
+    tty_raw_print(str);
+}
+
+/*
+raw_print_bold(str)
+                -- Like raw_print(), but prints in bold/standout (if
+possible).
+*/
+void gnome_raw_print_bold(const char *str)
+{
+    tty_raw_print_bold(str);
+}
+
+/*
+int nhgetch()   -- Returns a single character input from the user.
+                -- In the tty window-port, nhgetch() assumes that tgetch()
+                   will be the routine the OS provides to read a character.
+                   Returned character _must_ be non-zero.
+*/
+int gnome_nhgetch()
+{
+    int key;
+    GList *theFirst;
+    gtk_signal_emit (GTK_OBJECT (gnome_windowlist[WIN_STATUS].win),
+                      ghack_signals[GHSIG_FADE_HIGHLIGHT]);
+
+    g_askingQuestion = 1;
+    /* Process events until a key press event arrives. */
+    while ( g_numKeys == 0 ) 
+       gtk_main_iteration();
+    
+    theFirst = g_list_first( g_keyBuffer);
+    g_keyBuffer = g_list_remove_link(g_keyBuffer, theFirst);
+    key = GPOINTER_TO_INT( theFirst->data);
+    g_list_free_1( theFirst);
+    g_numKeys--;
+    g_askingQuestion = 0;
+    return ( key);
+}
+
+/*
+int nh_poskey(int *x, int *y, int *mod)
+                -- Returns a single character input from the user or a
+                   a positioning event (perhaps from a mouse).  If the
+                   return value is non-zero, a character was typed, else,
+                   a position in the MAP window is returned in x, y and mod.
+                   mod may be one of
+
+                        CLICK_1         -- mouse click type 1 
+                        CLICK_2         -- mouse click type 2 
+
+                   The different click types can map to whatever the
+                   hardware supports.  If no mouse is supported, this
+                   routine always returns a non-zero character.
+*/
+int gnome_nh_poskey(int *x, int *y, int *mod)
+{
+    gtk_signal_emit (GTK_OBJECT (gnome_windowlist[WIN_STATUS].win),
+                      ghack_signals[GHSIG_FADE_HIGHLIGHT]);
+    
+    g_askingQuestion = 0;
+    /* Process events until a key or map-click arrives. */
+    while ( g_numKeys == 0 && g_numClicks == 0 )
+       gtk_main_iteration();
+    
+    if (g_numKeys > 0) {
+       int key;
+       GList *theFirst;
+       
+       theFirst = g_list_first( g_keyBuffer);
+       g_keyBuffer = g_list_remove_link(g_keyBuffer, theFirst);
+       key = GPOINTER_TO_INT( theFirst->data);
+       g_list_free_1( theFirst);
+       g_numKeys--;
+       return ( key);
+    }
+    else {
+       GHClick *click;
+       GList *theFirst;
+       
+       theFirst = g_list_first( g_clickBuffer);
+       g_clickBuffer = g_list_remove_link(g_clickBuffer, theFirst);
+       click = (GHClick*) theFirst->data;
+       *x=click->x;
+        *y=click->y;
+        *mod=click->mod;
+       g_free( click);
+       g_list_free_1( theFirst);
+       g_numClicks--;
+       return ( 0);
+    }
+}
+
+/*
+nhbell()        -- Beep at user.  [This will exist at least until sounds are
+                   redone, since sounds aren't attributable to windows anyway.]
+*/
+void gnome_nhbell()
+{
+    /* FIXME!!! Play a cool GNOME sound instead */
+    gdk_beep();
+}
+
+/*
+doprev_message()
+                -- Display previous messages.  Used by the ^P command.
+                -- On the tty-port this scrolls WIN_MESSAGE back one line.
+*/
+int gnome_doprev_message()
+{
+    /* Do Nothing.  They can read old messages using the scrollbar. */
+    return 0;
+}
+
+/*
+char yn_function(const char *ques, const char *choices, char default)
+                -- Print a prompt made up of ques, choices and default.
+                   Read a single character response that is contained in
+                   choices or default.  If choices is NULL, all possible
+                   inputs are accepted and returned.  This overrides
+                   everything else.  The choices are expected to be in
+                   lower case.  Entering ESC always maps to 'q', or 'n',
+                   in that order, if present in choices, otherwise it maps
+                   to default.  Entering any other quit character (SPACE,
+                   RETURN, NEWLINE) maps to default.
+                -- If the choices string contains ESC, then anything after
+                   it is an acceptable response, but the ESC and whatever
+                   follows is not included in the prompt.
+                -- If the choices string contains a '#' then accept a count.
+                   Place this value in the global "yn_number" and return '#'.
+                -- This uses the top line in the tty window-port, other
+                   ports might use a popup.
+*/
+char gnome_yn_function(const char *question, const char *choices,
+               CHAR_P def)
+{
+    char ch;
+    int result=-1;
+    char message[BUFSZ];
+    char yn_esc_map='\033';
+    GtkWidget *mainWnd = ghack_get_main_window();
+    
+    
+    if (choices) {
+       char *cb, choicebuf[QBUFSZ];
+       Strcpy(choicebuf, choices);
+       if ((cb = index(choicebuf, '\033')) != 0) {
+           /* anything beyond <esc> is hidden */
+           *cb = '\0';
+       }
+       sprintf(message, "%s [%s] ", question, choicebuf);
+       if (def) sprintf(eos(message), "(%c) ", def);
+       /* escape maps to 'q' or 'n' or default, in that order */
+       yn_esc_map = (index(choices, 'q') ? 'q' :
+                (index(choices, 'n') ? 'n' : def));
+    } else {
+       Strcpy(message, question);
+    }
+    
+    
+    gnome_putstr(WIN_MESSAGE, ATR_BOLD, message);
+    if (mainWnd != NULL && choices && !index(choices,ch)) {
+       return(ghack_yes_no_dialog( question, choices, def));
+    }
+
+    /* Only here if main window is not present */
+    while (result<0) {
+       ch=gnome_nhgetch();
+       if (ch=='\033') {
+           result=yn_esc_map;
+       } else if (choices && !index(choices,ch)) {
+           /* FYI: ch==-115 is for KP_ENTER */
+           if (def && (ch==' ' || ch=='\r' || ch=='\n' || ch==-115)) {
+               result=def;
+           } else {
+               gnome_nhbell();
+               /* and try again... */
+           }
+       } else {
+           result=ch;
+       }
+    }
+    return result;
+}
+
+/*
+getlin(const char *ques, char *input)
+           -- Prints ques as a prompt and reads a single line of text,
+              up to a newline.  The string entered is returned without the
+              newline.  ESC is used to cancel, in which case the string
+              "\033\000" is returned.
+           -- getlin() must call flush_screen(1) before doing anything.
+           -- This uses the top line in the tty window-port, other
+              ports might use a popup.
+*/
+void gnome_getlin(const char *question, char *input)
+{
+    int ret;
+
+    ret = ghack_ask_string_dialog(question, "", "nethack", input);
+
+    if (ret == -1)
+       input[0] = 0;
+}
+
+/*
+int get_ext_cmd(void)
+           -- Get an extended command in a window-port specific way.
+              An index into extcmdlist[] is returned on a successful
+              selection, -1 otherwise.
+*/
+int gnome_get_ext_cmd()
+{
+    return -1;
+}
+
+
+/*
+number_pad(state)
+           -- Initialize the number pad to the given state.
+*/
+void gnome_number_pad(int state)
+{
+    /* Do Nothing */
+}
+
+/*
+delay_output()  -- Causes a visible delay of 50ms in the output.
+              Conceptually, this is similar to wait_synch() followed
+              by a nap(50ms), but allows asynchronous operation.
+*/
+void gnome_delay_output()
+{
+    if (gnome_windowlist[WIN_MESSAGE].win != NULL) {
+       gtk_signal_emit( GTK_OBJECT (gnome_windowlist[WIN_MESSAGE].win),
+       ghack_signals[GHSIG_DELAY],
+       (guint) 50);
+    }
+}
+
+/*
+start_screen()  -- Only used on Unix tty ports, but must be declared for
+              completeness.  Sets up the tty to work in full-screen
+              graphics mode.  Look at win/tty/termcap.c for an
+              example.  If your window-port does not need this function
+              just declare an empty function.
+*/
+void gnome_start_screen()
+{
+    /* Do Nothing */
+}
+
+/*
+end_screen()    -- Only used on Unix tty ports, but must be declared for
+              completeness.  The complement of start_screen().
+*/
+void gnome_end_screen()
+{
+    /* Do Nothing */
+}
+
+/*
+outrip(winid, int)
+           -- The tombstone code.  If you want the traditional code use
+              genl_outrip for the value and check the #if in rip.c.
+*/
+void gnome_outrip(winid wid, int how)
+{
+    /* Follows roughly the same algorithm as genl_outrip() */
+    char buf[BUFSZ];
+    char ripString[BUFSZ]="\0";
+    extern const char *killed_by_prefix[];
+    
+    /* Put name on stone */
+    Sprintf(buf, "%s\n", plname);
+    Strcat(ripString, buf);
+    
+    /* Put $ on stone */
+    Sprintf(buf, "%ld Au\n",
+#ifndef GOLDOBJ
+               u.ugold);
+#else
+               money_cnt(invent));
+#endif
+    Strcat(ripString, buf);
+
+    /* Put together death description */
+    switch (killer_format) {
+           default: impossible("bad killer format?");
+           case KILLED_BY_AN:
+                   Strcpy(buf, killed_by_prefix[how]);
+                   Strcat(buf, an(killer));
+                   break;
+           case KILLED_BY:
+                   Strcpy(buf, killed_by_prefix[how]);
+                   Strcat(buf, killer);
+                   break;
+           case NO_KILLER_PREFIX:
+                   Strcpy(buf, killer);
+                   break;
+    }
+    /* Put death type on stone */
+    Strcat(ripString, buf);
+    Strcat(ripString, "\n");
+
+    /* Put year on stone */
+    Sprintf(buf, "%4d\n", getyear());
+    Strcat(ripString, buf);
+
+    ghack_text_window_rip_string( ripString);
+}
+
+
+