tThe directory structure is now reorganised; the separate clients, and the gtkport stuff, have their own directories. Stub functions for missing clients have been added to dopewars.c. - vaccinewars - be a doctor and try to vaccinate the world
 (HTM) git clone git://src.adamsgaard.dk/vaccinewars
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit ef90a6dc064a2a31b8bdbc0c52a215da6d058623
 (DIR) parent a449a445fedb565c9b1096a5622b3e4fb33351c3
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Mon, 25 Feb 2002 19:32:03 +0000
       
       The directory structure is now reorganised; the separate clients, and the
       gtkport stuff, have their own directories. Stub functions for missing clients
       have been added to dopewars.c.
       
       
       Diffstat:
         M Makefile.in                         |       8 +++-----
         M aclocal.m4                          |     101 +++++++++++++------------------
         M configure                           |     466 +++++++++++++++++--------------
         M configure.in                        |      74 ++++++++++++++++++++-----------
         M doc/Makefile.in                     |      11 ++++++-----
         M src/Makefile.am                     |      30 ++++++++++++++++++++++++------
         M src/Makefile.in                     |     163 ++++++++++++++++++++++++-------
         D src/curses_client.c                 |    2425 -------------------------------
         A src/curses_client/Makefile.am       |       6 ++++++
         A src/curses_client/Makefile.in       |     325 +++++++++++++++++++++++++++++++
         A src/curses_client/curses_client.c   |    2409 +++++++++++++++++++++++++++++++
         R src/curses_client.h -> src/curses_… |       0 
         M src/dopewars.c                      |      46 +++++++++++++++++++++++++++++--
         M src/dopewars.h                      |      14 ++++++++++++++
         D src/gtk_client.c                    |    3930 -------------------------------
         D src/gtk_client.h                    |      40 -------------------------------
         A src/gtkport/Makefile.am             |       6 ++++++
         A src/gtkport/Makefile.in             |     325 +++++++++++++++++++++++++++++++
         R src/gtkport.c -> src/gtkport/gtkpo… |       0 
         R src/gtkport.h -> src/gtkport/gtkpo… |       0 
         A src/gui_client/Makefile.am          |       6 ++++++
         A src/gui_client/Makefile.in          |     325 +++++++++++++++++++++++++++++++
         A src/gui_client/gtk_client.c         |    3910 +++++++++++++++++++++++++++++++
         A src/gui_client/gtk_client.h         |      41 +++++++++++++++++++++++++++++++
         M src/winmain.c                       |      43 +++++++++++++++++++++----------
       
       25 files changed, 7948 insertions(+), 6756 deletions(-)
       ---
 (DIR) diff --git a/Makefile.in b/Makefile.in
       t@@ -1,6 +1,6 @@
       -# Makefile.in generated automatically by automake 1.4 from Makefile.am
       +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
        
       -# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
       +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
        # This Makefile.in is free software; the Free Software Foundation
        # gives unlimited permission to copy and/or distribute it,
        # with or without modifications, as long as this notice is preserved.
       t@@ -71,8 +71,6 @@ GLIB_CONFIG = @GLIB_CONFIG@
        GLIB_LIBS = @GLIB_LIBS@
        GMOFILES = @GMOFILES@
        GMSGFMT = @GMSGFMT@
       -GTKPORT_C = @GTKPORT_C@
       -GTKPORT_O = @GTKPORT_O@
        GTK_CFLAGS = @GTK_CFLAGS@
        GTK_CONFIG = @GTK_CONFIG@
        GTK_LIBS = @GTK_LIBS@
       t@@ -194,7 +192,7 @@ maintainer-clean-recursive:
                dot_seen=no; \
                rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
                  rev="$$subdir $$rev"; \
       -          test "$$subdir" = "." && dot_seen=yes; \
       +          test "$$subdir" != "." || dot_seen=yes; \
                done; \
                test "$$dot_seen" = "no" && rev=". $$rev"; \
                target=`echo $@ | sed s/-recursive//`; \
 (DIR) diff --git a/aclocal.m4 b/aclocal.m4
       t@@ -1,6 +1,6 @@
       -dnl aclocal.m4 generated automatically by aclocal 1.4
       +dnl aclocal.m4 generated automatically by aclocal 1.4-p5
        
       -dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
       +dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
        dnl This file is free software; the Free Software Foundation
        dnl gives unlimited permission to copy and/or distribute it,
        dnl with or without modifications, as long as this notice is preserved.
       t@@ -19,7 +19,7 @@ dnl PARTICULAR PURPOSE.
        dnl Usage:
        dnl AM_INIT_AUTOMAKE(package,version, [no-define])
        
       -AC_DEFUN(AM_INIT_AUTOMAKE,
       +AC_DEFUN([AM_INIT_AUTOMAKE],
        [AC_REQUIRE([AC_PROG_INSTALL])
        PACKAGE=[$1]
        AC_SUBST(PACKAGE)
       t@@ -47,7 +47,7 @@ AC_REQUIRE([AC_PROG_MAKE_SET])])
        # Check to make sure that the build environment is sane.
        #
        
       -AC_DEFUN(AM_SANITY_CHECK,
       +AC_DEFUN([AM_SANITY_CHECK],
        [AC_MSG_CHECKING([whether build environment is sane])
        # Just in case
        sleep 1
       t@@ -88,7 +88,7 @@ AC_MSG_RESULT(yes)])
        
        dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
        dnl The program must properly implement --version.
       -AC_DEFUN(AM_MISSING_PROG,
       +AC_DEFUN([AM_MISSING_PROG],
        [AC_MSG_CHECKING(for working $2)
        # Run test in a subshell; some versions of sh will print an error if
        # an executable is not found, even if stderr is redirected.
       t@@ -104,7 +104,7 @@ AC_SUBST($1)])
        
        # Like AC_CONFIG_HEADER, but automatically create stamp file.
        
       -AC_DEFUN(AM_CONFIG_HEADER,
       +AC_DEFUN([AM_CONFIG_HEADER],
        [AC_PREREQ([2.12])
        AC_CONFIG_HEADER([$1])
        dnl When config.status generates a header, we must update the stamp-h file.
       t@@ -539,15 +539,11 @@ main ()
        # Ulrich Drepper <drepper@cygnus.com>, 1995.
        #
        # This file can be copied and used freely without restrictions.  It can
       -# be used in projects which are not available under the GNU General Public
       -# License or the GNU Library General Public License but which still want
       -# to provide support for the GNU gettext functionality.
       -# Please note that the actual code of the GNU gettext library is covered
       -# by the GNU Library General Public License, and the rest of the GNU
       -# gettext package package is covered by the GNU General Public License.
       -# They are *not* in the public domain.
       +# be used in projects which are not available under the GNU Public License
       +# but which still want to provide support for the GNU gettext functionality.
       +# Please note that the actual code is *not* freely available.
        
       -# serial 10
       +# serial 9
        
        dnl Usage: AM_WITH_NLS([TOOLSYMBOL], [NEEDSYMBOL], [LIBDIR]).
        dnl If TOOLSYMBOL is specified and is 'use-libtool', then a libtool library
       t@@ -658,14 +654,14 @@ return (int) gettext ("")]ifelse([$2], need-ngettext, [ + (int) ngettext ("", ""
                     AC_CHECK_FUNCS(dcgettext)
                     LIBS="$gt_save_LIBS"
        
       -             dnl Search for GNU msgfmt in the PATH.
                     AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
       -               [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1], :)
       -             AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
       +               [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
       +             if test "$MSGFMT" != "no"; then
       +               AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
       +             fi
        
       -             dnl Search for GNU xgettext in the PATH.
                     AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
       -               [$ac_dir/$ac_word --omit-header /dev/null >/dev/null 2>&1], :)
       +               [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
        
                     CATOBJEXT=.gmo
                   fi
       t@@ -682,10 +678,10 @@ return (int) gettext ("")]ifelse([$2], need-ngettext, [ + (int) ngettext ("", ""
                dnl Mark actions used to generate GNU NLS library.
                INTLOBJS="\$(GETTOBJS)"
                AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
       -          [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1], :)
       +          [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
                AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
                AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
       -          [$ac_dir/$ac_word --omit-header /dev/null >/dev/null 2>&1], :)
       +          [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
                AC_SUBST(MSGFMT)
                BUILD_INCLUDED_LIBINTL=yes
                USE_INCLUDED_LIBINTL=yes
       t@@ -694,26 +690,11 @@ return (int) gettext ("")]ifelse([$2], need-ngettext, [ + (int) ngettext ("", ""
                LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
              fi
        
       -      dnl This could go away some day; the PATH_PROG_WITH_TEST already does it.
       -      dnl Test whether we really found GNU msgfmt.
       -      if test "$GMSGFMT" != ":"; then
       -        dnl If it is no GNU msgfmt we define it as : so that the
       -        dnl Makefiles still can work.
       -        if $GMSGFMT --statistics /dev/null >/dev/null 2>&1; then
       -          : ;
       -        else
       -          AC_MSG_RESULT(
       -            [found msgfmt program is not GNU msgfmt; ignore it])
       -          GMSGFMT=":"
       -        fi
       -      fi
       -
       -      dnl This could go away some day; the PATH_PROG_WITH_TEST already does it.
              dnl Test whether we really found GNU xgettext.
              if test "$XGETTEXT" != ":"; then
                dnl If it is no GNU xgettext we define it as : so that the
                dnl Makefiles still can work.
       -        if $XGETTEXT --omit-header /dev/null >/dev/null 2>&1; then
       +        if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
                  : ;
                else
                  AC_MSG_RESULT(
       t@@ -737,9 +718,6 @@ return (int) gettext ("")]ifelse([$2], need-ngettext, [ + (int) ngettext ("", ""
                  ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
                  ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
                  ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
       -          # In autoconf-2.13 it is called $ac_given_srcdir.
       -          # In autoconf-2.50 it is called $srcdir.
       -          test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
                  case "$ac_given_srcdir" in
                    .)  top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
                    /*) top_srcdir="$ac_given_srcdir" ;;
       t@@ -747,9 +725,9 @@ return (int) gettext ("")]ifelse([$2], need-ngettext, [ + (int) ngettext ("", ""
                  esac
                  if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
                    rm -f "$ac_dir/POTFILES"
       -            test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
       +            echo creating "$ac_dir/POTFILES"
                    sed -e "/^#/d" -e "/^[         ]*\$/d" -e "s,.*,     $top_srcdir/& \\\\," -e "\$s/\(.*\) \\\\/\1/" < "$ac_given_srcdir/$ac_dir/POTFILES.in" > "$ac_dir/POTFILES"
       -            test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
       +            echo creating "$ac_dir/Makefile"
                    sed -e "/POTFILES =/r $ac_dir/POTFILES" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
                  fi
                  ;;
       t@@ -780,7 +758,7 @@ return (int) gettext ("")]ifelse([$2], need-ngettext, [ + (int) ngettext ("", ""
              dnl Found it, now check the version.
              AC_MSG_CHECKING([version of bison])
        changequote(<<,>>)dnl
       -      ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'`
       +      ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison .* \([0-9]*\.[0-9.]*\).*$/\1/p'`
              case $ac_prog_version in
                '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
                1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*)
       t@@ -910,15 +888,11 @@ strdup strtoul tsearch __argz_count __argz_stringify __argz_next])
        # Ulrich Drepper <drepper@cygnus.com>, 1996.
        #
        # This file can be copied and used freely without restrictions.  It can
       -# be used in projects which are not available under the GNU General Public
       -# License or the GNU Library General Public License but which still want
       -# to provide support for the GNU gettext functionality.
       -# Please note that the actual code of the GNU gettext library is covered
       -# by the GNU Library General Public License, and the rest of the GNU
       -# gettext package package is covered by the GNU General Public License.
       -# They are *not* in the public domain.
       +# be used in projects which are not available under the GNU Public License
       +# but which still want to provide support for the GNU gettext functionality.
       +# Please note that the actual code is *not* freely available.
        
       -# serial 2
       +# serial 1
        
        dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
        dnl   TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
       t@@ -950,7 +924,7 @@ ifelse([$4], , , [  test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
          ;;
        esac])dnl
        $1="$ac_cv_path_$1"
       -if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
       +if test -n "[$]$1"; then
          AC_MSG_RESULT([$]$1)
        else
          AC_MSG_RESULT(no)
       t@@ -1077,13 +1051,9 @@ AC_DEFUN([AM_LANGINFO_CODESET],
        # Ulrich Drepper <drepper@cygnus.com>, 1995.
        #
        # This file can be copied and used freely without restrictions.  It can
       -# be used in projects which are not available under the GNU General Public
       -# License or the GNU Library General Public License but which still want
       -# to provide support for the GNU gettext functionality.
       -# Please note that the actual code of the GNU gettext library is covered
       -# by the GNU Library General Public License, and the rest of the GNU
       -# gettext package package is covered by the GNU General Public License.
       -# They are *not* in the public domain.
       +# be used in projects which are not available under the GNU Public License
       +# but which still want to provide support for the GNU gettext functionality.
       +# Please note that the actual code is *not* freely available.
        
        # serial 2
        
       t@@ -1098,3 +1068,16 @@ AC_DEFUN([AM_LC_MESSAGES],
            fi
          fi])
        
       +# Define a conditional.
       +
       +AC_DEFUN([AM_CONDITIONAL],
       +[AC_SUBST($1_TRUE)
       +AC_SUBST($1_FALSE)
       +if $2; then
       +  $1_TRUE=
       +  $1_FALSE='#'
       +else
       +  $1_TRUE='#'
       +  $1_FALSE=
       +fi])
       +
 (DIR) diff --git a/configure b/configure
       t@@ -16,6 +16,8 @@ ac_help="$ac_help
        ac_help="$ac_help
          --enable-curses-client  include curses client"
        ac_help="$ac_help
       +  --enable-gui-server     use a simple GTK+/Win32 GUI for the server"
       +ac_help="$ac_help
          --enable-nativewin32    build a native Win32 binary under Cygwin"
        ac_help="$ac_help
          --with-glib-prefix=PFX   Prefix where GLIB is installed (optional)"
       t@@ -36,8 +38,6 @@ ac_help="$ac_help
        ac_help="$ac_help
          --with-included-gettext use the GNU gettext library included here"
        ac_help="$ac_help
       -  --enable-gui-server     use a simple GTK+/Win32 GUI for the server"
       -ac_help="$ac_help
          --enable-networking     dopewars will use TCP/IP to connect to servers"
        ac_help="$ac_help
          --enable-strict         if using gcc, enable extra warnings above -Wall"
       t@@ -1542,7 +1542,7 @@ if test "${enable_gui_client+set}" = set; then
          enableval="$enable_gui_client"
           GUI_CLIENT="$enableval" 
        else
       -   GUI_CLIENT="yes" 
       +   GUI_CLIENT="probe" 
        fi
        
        
       t@@ -1551,17 +1551,26 @@ if test "${enable_curses_client+set}" = set; then
          enableval="$enable_curses_client"
           CURSES_CLIENT="$enableval" 
        else
       -   CURSES_CLIENT="yes" 
       +   CURSES_CLIENT="probe" 
       +fi
       +
       +
       +# Check whether --enable-gui-server or --disable-gui-server was given.
       +if test "${enable_gui_server+set}" = set; then
       +  enableval="$enable_gui_server"
       +   GUI_SERVER="$enableval" 
       +else
       +   GUI_SERVER="probe" 
        fi
        
        
        echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
       -echo "configure:1560: checking for Cygwin environment" >&5
       +echo "configure:1569: checking for Cygwin environment" >&5
        if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 1565 "configure"
       +#line 1574 "configure"
        #include "confdefs.h"
        
        int main() {
       t@@ -1572,7 +1581,7 @@ int main() {
        return __CYGWIN__;
        ; return 0; }
        EOF
       -if { (eval echo configure:1576: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
       +if { (eval echo configure:1585: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
          rm -rf conftest*
          ac_cv_cygwin=yes
        else
       t@@ -1613,7 +1622,9 @@ EOF
        
                 HAVE_FIXED_GTK="yes"
        
       -      GUI_SERVER="yes"
       +      if test "$GUI_SERVER" = "probe"; then
       +     GUI_SERVER="yes"
       +   fi
        else
           echo "$ac_t"""Configuring for Unix binary"" 1>&6
        
       t@@ -1670,7 +1681,7 @@ fi
          # Extract the first word of "glib-config", so it can be a program name with args.
        set dummy glib-config; ac_word=$2
        echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
       -echo "configure:1674: checking for $ac_word" >&5
       +echo "configure:1685: checking for $ac_word" >&5
        if eval "test \"`echo '$''{'ac_cv_path_GLIB_CONFIG'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -1705,7 +1716,7 @@ fi
        
          min_glib_version=1.2.0
          echo $ac_n "checking for GLIB - version >= $min_glib_version""... $ac_c" 1>&6
       -echo "configure:1709: checking for GLIB - version >= $min_glib_version" >&5
       +echo "configure:1720: checking for GLIB - version >= $min_glib_version" >&5
          no_glib=""
          if test "$GLIB_CONFIG" = "no" ; then
            no_glib=yes
       t@@ -1728,7 +1739,7 @@ echo "configure:1709: checking for GLIB - version >= $min_glib_version" >&5
          echo $ac_n "cross compiling; assumed OK... $ac_c"
        else
          cat > conftest.$ac_ext <<EOF
       -#line 1732 "configure"
       +#line 1743 "configure"
        #include "confdefs.h"
        
        #include <glib.h>
       t@@ -1804,7 +1815,7 @@ main ()
        }
        
        EOF
       -if { (eval echo configure:1808: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
       +if { (eval echo configure:1819: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
        then
          :
        else
       t@@ -1838,7 +1849,7 @@ fi
                  CFLAGS="$CFLAGS $GLIB_CFLAGS"
                  LIBS="$LIBS $GLIB_LIBS"
                  cat > conftest.$ac_ext <<EOF
       -#line 1842 "configure"
       +#line 1853 "configure"
        #include "confdefs.h"
        
        #include <glib.h>
       t@@ -1848,7 +1859,7 @@ int main() {
         return ((glib_major_version) || (glib_minor_version) || (glib_micro_version)); 
        ; return 0; }
        EOF
       -if { (eval echo configure:1852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:1863: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
           echo "*** The test program compiled, but did not run. This usually means"
                  echo "*** that the run-time linker is not finding GLIB or finding the wrong"
       t@@ -1887,9 +1898,9 @@ rm -f conftest*
          rm -f conf.glibtest
        
        
       -      if test "$CURSES_CLIENT" = "yes" ; then
       +      if test "$CURSES_CLIENT" != "no" ; then
              echo $ac_n "checking for newterm in -lncurses""... $ac_c" 1>&6
       -echo "configure:1893: checking for newterm in -lncurses" >&5
       +echo "configure:1904: checking for newterm in -lncurses" >&5
        ac_lib_var=`echo ncurses'_'newterm | sed 'y%./+-%__p_%'`
        if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
       t@@ -1897,7 +1908,7 @@ else
          ac_save_LIBS="$LIBS"
        LIBS="-lncurses  $LIBS"
        cat > conftest.$ac_ext <<EOF
       -#line 1901 "configure"
       +#line 1912 "configure"
        #include "confdefs.h"
        /* Override any gcc2 internal prototype to avoid an error.  */
        /* We use char because int might match the return type of a gcc2
       t@@ -1908,7 +1919,7 @@ int main() {
        newterm()
        ; return 0; }
        EOF
       -if { (eval echo configure:1912: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:1923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          eval "ac_cv_lib_$ac_lib_var=yes"
        else
       t@@ -1937,7 +1948,7 @@ fi
        
              if test "$ac_cv_lib_ncurses_newterm" = "no" ; then
                 echo $ac_n "checking for newterm in -lcurses""... $ac_c" 1>&6
       -echo "configure:1941: checking for newterm in -lcurses" >&5
       +echo "configure:1952: checking for newterm in -lcurses" >&5
        ac_lib_var=`echo curses'_'newterm | sed 'y%./+-%__p_%'`
        if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
       t@@ -1945,7 +1956,7 @@ else
          ac_save_LIBS="$LIBS"
        LIBS="-lcurses  $LIBS"
        cat > conftest.$ac_ext <<EOF
       -#line 1949 "configure"
       +#line 1960 "configure"
        #include "confdefs.h"
        /* Override any gcc2 internal prototype to avoid an error.  */
        /* We use char because int might match the return type of a gcc2
       t@@ -1956,7 +1967,7 @@ int main() {
        newterm()
        ; return 0; }
        EOF
       -if { (eval echo configure:1960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:1971: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          eval "ac_cv_lib_$ac_lib_var=yes"
        else
       t@@ -1985,7 +1996,7 @@ fi
        
                 if test "$ac_cv_lib_curses_newterm" = "no" ; then
                    echo $ac_n "checking for newterm in -lcur_colr""... $ac_c" 1>&6
       -echo "configure:1989: checking for newterm in -lcur_colr" >&5
       +echo "configure:2000: checking for newterm in -lcur_colr" >&5
        ac_lib_var=`echo cur_colr'_'newterm | sed 'y%./+-%__p_%'`
        if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
       t@@ -1993,7 +2004,7 @@ else
          ac_save_LIBS="$LIBS"
        LIBS="-lcur_colr  $LIBS"
        cat > conftest.$ac_ext <<EOF
       -#line 1997 "configure"
       +#line 2008 "configure"
        #include "confdefs.h"
        /* Override any gcc2 internal prototype to avoid an error.  */
        /* We use char because int might match the return type of a gcc2
       t@@ -2004,7 +2015,7 @@ int main() {
        newterm()
        ; return 0; }
        EOF
       -if { (eval echo configure:2008: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:2019: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          eval "ac_cv_lib_$ac_lib_var=yes"
        else
       t@@ -2032,14 +2043,18 @@ else
        fi
        
                    if test "$ac_cv_lib_cur_colr_newterm" = "no" ; then
       -               echo "configure: warning: Cannot find any curses-type library" 1>&2
       -               CURSES_CLIENT="no"
       +               if test "$CURSES_CLIENT" = "yes" ; then
       +                 { echo "configure: error: Cannot find any curses-type library" 1>&2; exit 1; }
       +               else
       +                 echo "configure: warning: Cannot find any curses-type library" 1>&2
       +                 CURSES_CLIENT="no"
       +               fi
                    fi
                 fi
              fi
           fi
        
       -   if test "$GUI_CLIENT" = "yes" ; then
       +   if test "$GUI_CLIENT" != "no" -o "$GUI_SERVER" != "no"; then
                    # Check whether --with-gtk-prefix or --without-gtk-prefix was given.
        if test "${with_gtk_prefix+set}" = set; then
          withval="$with_gtk_prefix"
       t@@ -2090,7 +2105,7 @@ fi
          # Extract the first word of "gtk-config", so it can be a program name with args.
        set dummy gtk-config; ac_word=$2
        echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
       -echo "configure:2094: checking for $ac_word" >&5
       +echo "configure:2109: checking for $ac_word" >&5
        if eval "test \"`echo '$''{'ac_cv_path_GTK_CONFIG'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -2125,7 +2140,7 @@ fi
        
          min_gtk_version=1.2.0
          echo $ac_n "checking for GTK - version >= $min_gtk_version""... $ac_c" 1>&6
       -echo "configure:2129: checking for GTK - version >= $min_gtk_version" >&5
       +echo "configure:2144: checking for GTK - version >= $min_gtk_version" >&5
          no_gtk=""
          if test "$GTK_CONFIG" = "no" ; then
            no_gtk=yes
       t@@ -2148,7 +2163,7 @@ echo "configure:2129: checking for GTK - version >= $min_gtk_version" >&5
          echo $ac_n "cross compiling; assumed OK... $ac_c"
        else
          cat > conftest.$ac_ext <<EOF
       -#line 2152 "configure"
       +#line 2167 "configure"
        #include "confdefs.h"
        
        #include <gtk/gtk.h>
       t@@ -2226,7 +2241,7 @@ main ()
        }
        
        EOF
       -if { (eval echo configure:2230: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
       +if { (eval echo configure:2245: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
        then
          :
        else
       t@@ -2260,7 +2275,7 @@ fi
                  CFLAGS="$CFLAGS $GTK_CFLAGS"
                  LIBS="$LIBS $GTK_LIBS"
                  cat > conftest.$ac_ext <<EOF
       -#line 2264 "configure"
       +#line 2279 "configure"
        #include "confdefs.h"
        
        #include <gtk/gtk.h>
       t@@ -2270,7 +2285,7 @@ int main() {
         return ((gtk_major_version) || (gtk_minor_version) || (gtk_micro_version)); 
        ; return 0; }
        EOF
       -if { (eval echo configure:2274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:2289: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
           echo "*** The test program compiled, but did not run. This usually means"
                  echo "*** that the run-time linker is not finding GTK or finding the wrong"
       t@@ -2309,11 +2324,16 @@ rm -f conftest*
          rm -f conf.gtktest
        
              if test "$gtk_found" = "no" ; then
       -         echo "configure: warning: Cannot find GTK+" 1>&2
       -         GUI_CLIENT="no"
       +         if test "$GUI_CLIENT" = "yes" -o "$GUI_SERVER" = "yes" ; then
       +           { echo "configure: error: Cannot find GTK+" 1>&2; exit 1; }
       +         else
       +           echo "configure: warning: Cannot find GTK+" 1>&2
       +           GUI_CLIENT="no"
       +           GUI_SERVER="no"
       +         fi
              else
                 echo $ac_n "checking for non-buggy GTK+ ( >= 1.2.10 )""... $ac_c" 1>&6
       -echo "configure:2317: checking for non-buggy GTK+ ( >= 1.2.10 )" >&5
       +echo "configure:2337: checking for non-buggy GTK+ ( >= 1.2.10 )" >&5
                          if test "$gtk_config_major_version" -gt 1 ; then
                    HAVE_FIXED_GTK="yes"
                 elif test "$gtk_config_major_version" -eq 1 ; then
       t@@ -2331,12 +2351,14 @@ echo "configure:2317: checking for non-buggy GTK+ ( >= 1.2.10 )" >&5
              CFLAGS="$CFLAGS `glib-config --cflags`"
           LDFLAGS="$LDFLAGS `glib-config --libs`"
        
       -      GUI_SERVER="no"
       +      if test "$GUI_SERVER" = "probe"; then
       +     GUI_SERVER="no"
       +   fi
        
              echo $ac_n "checking for socklen_t data type""... $ac_c" 1>&6
       -echo "configure:2338: checking for socklen_t data type" >&5
       +echo "configure:2360: checking for socklen_t data type" >&5
           cat > conftest.$ac_ext <<EOF
       -#line 2340 "configure"
       +#line 2362 "configure"
        #include "confdefs.h"
        #include <sys/types.h>
                           #include <sys/socket.h>
       t@@ -2344,7 +2366,7 @@ int main() {
        socklen_t val
        ; return 0; }
        EOF
       -if { (eval echo configure:2348: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
       +if { (eval echo configure:2370: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
          rm -rf conftest*
          echo "$ac_t""yes" 1>&6
                           cat >> confdefs.h <<\EOF
       t@@ -2360,11 +2382,18 @@ fi
        rm -f conftest*
        fi
        
       +if test "$GUI_CLIENT" = "probe"; then
       +  GUI_CLIENT="yes"
       +fi
       +if test "$CURSES_CLIENT" = "probe"; then
       +  CURSES_CLIENT="yes"
       +fi
       +
        ALL_LINGUAS="de pl pt_BR fr"
        # Extract the first word of "ranlib", so it can be a program name with args.
        set dummy ranlib; ac_word=$2
        echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
       -echo "configure:2368: checking for $ac_word" >&5
       +echo "configure:2397: checking for $ac_word" >&5
        if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -2392,12 +2421,12 @@ else
        fi
        
        echo $ac_n "checking for working const""... $ac_c" 1>&6
       -echo "configure:2396: checking for working const" >&5
       +echo "configure:2425: checking for working const" >&5
        if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 2401 "configure"
       +#line 2430 "configure"
        #include "confdefs.h"
        
        int main() {
       t@@ -2446,7 +2475,7 @@ ccp = (char const *const *) p;
        
        ; return 0; }
        EOF
       -if { (eval echo configure:2450: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
       +if { (eval echo configure:2479: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
          rm -rf conftest*
          ac_cv_c_const=yes
        else
       t@@ -2467,21 +2496,21 @@ EOF
        fi
        
        echo $ac_n "checking for inline""... $ac_c" 1>&6
       -echo "configure:2471: checking for inline" >&5
       +echo "configure:2500: checking for inline" >&5
        if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          ac_cv_c_inline=no
        for ac_kw in inline __inline__ __inline; do
          cat > conftest.$ac_ext <<EOF
       -#line 2478 "configure"
       +#line 2507 "configure"
        #include "confdefs.h"
        
        int main() {
        } $ac_kw foo() {
        ; return 0; }
        EOF
       -if { (eval echo configure:2485: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
       +if { (eval echo configure:2514: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
          rm -rf conftest*
          ac_cv_c_inline=$ac_kw; break
        else
       t@@ -2507,12 +2536,12 @@ EOF
        esac
        
        echo $ac_n "checking for off_t""... $ac_c" 1>&6
       -echo "configure:2511: checking for off_t" >&5
       +echo "configure:2540: checking for off_t" >&5
        if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 2516 "configure"
       +#line 2545 "configure"
        #include "confdefs.h"
        #include <sys/types.h>
        #if STDC_HEADERS
       t@@ -2540,12 +2569,12 @@ EOF
        fi
        
        echo $ac_n "checking for size_t""... $ac_c" 1>&6
       -echo "configure:2544: checking for size_t" >&5
       +echo "configure:2573: checking for size_t" >&5
        if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 2549 "configure"
       +#line 2578 "configure"
        #include "confdefs.h"
        #include <sys/types.h>
        #if STDC_HEADERS
       t@@ -2575,19 +2604,19 @@ fi
        # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
        # for constant arguments.  Useless!
        echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
       -echo "configure:2579: checking for working alloca.h" >&5
       +echo "configure:2608: checking for working alloca.h" >&5
        if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 2584 "configure"
       +#line 2613 "configure"
        #include "confdefs.h"
        #include <alloca.h>
        int main() {
        char *p = alloca(2 * sizeof(int));
        ; return 0; }
        EOF
       -if { (eval echo configure:2591: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:2620: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          ac_cv_header_alloca_h=yes
        else
       t@@ -2608,12 +2637,12 @@ EOF
        fi
        
        echo $ac_n "checking for alloca""... $ac_c" 1>&6
       -echo "configure:2612: checking for alloca" >&5
       +echo "configure:2641: checking for alloca" >&5
        if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 2617 "configure"
       +#line 2646 "configure"
        #include "confdefs.h"
        
        #ifdef __GNUC__
       t@@ -2641,7 +2670,7 @@ int main() {
        char *p = (char *) alloca(1);
        ; return 0; }
        EOF
       -if { (eval echo configure:2645: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:2674: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          ac_cv_func_alloca_works=yes
        else
       t@@ -2673,12 +2702,12 @@ EOF
        
        
        echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
       -echo "configure:2677: checking whether alloca needs Cray hooks" >&5
       +echo "configure:2706: checking whether alloca needs Cray hooks" >&5
        if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 2682 "configure"
       +#line 2711 "configure"
        #include "confdefs.h"
        #if defined(CRAY) && ! defined(CRAY2)
        webecray
       t@@ -2703,12 +2732,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6
        if test $ac_cv_os_cray = yes; then
        for ac_func in _getb67 GETB67 getb67; do
          echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
       -echo "configure:2707: checking for $ac_func" >&5
       +echo "configure:2736: checking for $ac_func" >&5
        if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 2712 "configure"
       +#line 2741 "configure"
        #include "confdefs.h"
        /* System header to define __stub macros and hopefully few prototypes,
            which can conflict with char $ac_func(); below.  */
       t@@ -2731,7 +2760,7 @@ $ac_func();
        
        ; return 0; }
        EOF
       -if { (eval echo configure:2735: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:2764: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          eval "ac_cv_func_$ac_func=yes"
        else
       t@@ -2758,7 +2787,7 @@ done
        fi
        
        echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
       -echo "configure:2762: checking stack direction for C alloca" >&5
       +echo "configure:2791: checking stack direction for C alloca" >&5
        if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -2766,7 +2795,7 @@ else
          ac_cv_c_stack_direction=0
        else
          cat > conftest.$ac_ext <<EOF
       -#line 2770 "configure"
       +#line 2799 "configure"
        #include "confdefs.h"
        find_stack_direction ()
        {
       t@@ -2785,7 +2814,7 @@ main ()
          exit (find_stack_direction() < 0);
        }
        EOF
       -if { (eval echo configure:2789: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
       +if { (eval echo configure:2818: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
        then
          ac_cv_c_stack_direction=1
        else
       t@@ -2806,21 +2835,21 @@ EOF
        
        fi
        
       -for ac_hdr in unistd.h
       +for ac_hdr in stdlib.h unistd.h sys/stat.h sys/types.h
        do
        ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
        echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
       -echo "configure:2814: checking for $ac_hdr" >&5
       +echo "configure:2843: checking for $ac_hdr" >&5
        if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 2819 "configure"
       +#line 2848 "configure"
        #include "confdefs.h"
        #include <$ac_hdr>
        EOF
        ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
       -{ (eval echo configure:2824: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
       +{ (eval echo configure:2853: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
        ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
        if test -z "$ac_err"; then
          rm -rf conftest*
       t@@ -2849,12 +2878,12 @@ done
        for ac_func in getpagesize
        do
        echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
       -echo "configure:2853: checking for $ac_func" >&5
       +echo "configure:2882: checking for $ac_func" >&5
        if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 2858 "configure"
       +#line 2887 "configure"
        #include "confdefs.h"
        /* System header to define __stub macros and hopefully few prototypes,
            which can conflict with char $ac_func(); below.  */
       t@@ -2877,7 +2906,7 @@ $ac_func();
        
        ; return 0; }
        EOF
       -if { (eval echo configure:2881: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:2910: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          eval "ac_cv_func_$ac_func=yes"
        else
       t@@ -2902,7 +2931,7 @@ fi
        done
        
        echo $ac_n "checking for working mmap""... $ac_c" 1>&6
       -echo "configure:2906: checking for working mmap" >&5
       +echo "configure:2935: checking for working mmap" >&5
        if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -2910,7 +2939,7 @@ else
          ac_cv_func_mmap_fixed_mapped=no
        else
          cat > conftest.$ac_ext <<EOF
       -#line 2914 "configure"
       +#line 2943 "configure"
        #include "confdefs.h"
        
        /* Thanks to Mike Haertel and Jim Avera for this test.
       t@@ -2938,11 +2967,24 @@ else
        #include <fcntl.h>
        #include <sys/mman.h>
        
       +#if HAVE_SYS_TYPES_H
       +# include <sys/types.h>
       +#endif
       +
       +#if HAVE_STDLIB_H
       +# include <stdlib.h>
       +#endif
       +
       +#if HAVE_SYS_STAT_H
       +# include <sys/stat.h>
       +#endif
       +
       +#if HAVE_UNISTD_H
       +# include <unistd.h>
       +#endif
       +
        /* This mess was copied from the GNU getpagesize.h.  */
        #ifndef HAVE_GETPAGESIZE
       -# ifdef HAVE_UNISTD_H
       -#  include <unistd.h>
       -# endif
        
        /* Assume that all systems that can run configure have sys/param.h.  */
        # ifndef HAVE_SYS_PARAM_H
       t@@ -3050,7 +3092,7 @@ main()
        }
        
        EOF
       -if { (eval echo configure:3054: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
       +if { (eval echo configure:3096: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
        then
          ac_cv_func_mmap_fixed_mapped=yes
        else
       t@@ -3074,12 +3116,12 @@ fi
        
        
            echo $ac_n "checking whether we are using the GNU C Library 2.1 or newer""... $ac_c" 1>&6
       -echo "configure:3078: checking whether we are using the GNU C Library 2.1 or newer" >&5
       +echo "configure:3120: checking whether we are using the GNU C Library 2.1 or newer" >&5
        if eval "test \"`echo '$''{'ac_cv_gnu_library_2_1'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 3083 "configure"
       +#line 3125 "configure"
        #include "confdefs.h"
        
        #include <features.h>
       t@@ -3115,17 +3157,17 @@ stdlib.h string.h unistd.h sys/param.h
        do
        ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
        echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
       -echo "configure:3119: checking for $ac_hdr" >&5
       +echo "configure:3161: checking for $ac_hdr" >&5
        if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 3124 "configure"
       +#line 3166 "configure"
        #include "confdefs.h"
        #include <$ac_hdr>
        EOF
        ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
       -{ (eval echo configure:3129: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
       +{ (eval echo configure:3171: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
        ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
        if test -z "$ac_err"; then
          rm -rf conftest*
       t@@ -3156,12 +3198,12 @@ getgid getuid mempcpy munmap putenv setenv setlocale stpcpy strchr strcasecmp \
        strdup strtoul tsearch __argz_count __argz_stringify __argz_next
        do
        echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
       -echo "configure:3160: checking for $ac_func" >&5
       +echo "configure:3202: checking for $ac_func" >&5
        if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 3165 "configure"
       +#line 3207 "configure"
        #include "confdefs.h"
        /* System header to define __stub macros and hopefully few prototypes,
            which can conflict with char $ac_func(); below.  */
       t@@ -3184,7 +3226,7 @@ $ac_func();
        
        ; return 0; }
        EOF
       -if { (eval echo configure:3188: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:3230: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          eval "ac_cv_func_$ac_func=yes"
        else
       t@@ -3224,7 +3266,7 @@ fi
        
        
          echo $ac_n "checking for iconv""... $ac_c" 1>&6
       -echo "configure:3228: checking for iconv" >&5
       +echo "configure:3270: checking for iconv" >&5
        if eval "test \"`echo '$''{'am_cv_func_iconv'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -3232,7 +3274,7 @@ else
            am_cv_func_iconv="no, consider installing GNU libiconv"
            am_cv_lib_iconv=no
            cat > conftest.$ac_ext <<EOF
       -#line 3236 "configure"
       +#line 3278 "configure"
        #include "confdefs.h"
        #include <stdlib.h>
        #include <iconv.h>
       t@@ -3242,7 +3284,7 @@ iconv_t cd = iconv_open("","");
               iconv_close(cd);
        ; return 0; }
        EOF
       -if { (eval echo configure:3246: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:3288: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          am_cv_func_iconv=yes
        else
       t@@ -3254,7 +3296,7 @@ rm -f conftest*
              am_save_LIBS="$LIBS"
              LIBS="$LIBS -liconv"
              cat > conftest.$ac_ext <<EOF
       -#line 3258 "configure"
       +#line 3300 "configure"
        #include "confdefs.h"
        #include <stdlib.h>
        #include <iconv.h>
       t@@ -3264,7 +3306,7 @@ iconv_t cd = iconv_open("","");
                 iconv_close(cd);
        ; return 0; }
        EOF
       -if { (eval echo configure:3268: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:3310: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          am_cv_lib_iconv=yes
                am_cv_func_iconv=yes
       t@@ -3285,13 +3327,13 @@ echo "$ac_t""$am_cv_func_iconv" 1>&6
        EOF
        
            echo $ac_n "checking for iconv declaration""... $ac_c" 1>&6
       -echo "configure:3289: checking for iconv declaration" >&5
       +echo "configure:3331: checking for iconv declaration" >&5
            if eval "test \"`echo '$''{'am_cv_proto_iconv'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          
              cat > conftest.$ac_ext <<EOF
       -#line 3295 "configure"
       +#line 3337 "configure"
        #include "confdefs.h"
        
        #include <stdlib.h>
       t@@ -3310,7 +3352,7 @@ int main() {
        
        ; return 0; }
        EOF
       -if { (eval echo configure:3314: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
       +if { (eval echo configure:3356: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
          rm -rf conftest*
          am_cv_proto_iconv_arg1=""
        else
       t@@ -3339,19 +3381,19 @@ EOF
        
           
          echo $ac_n "checking for nl_langinfo and CODESET""... $ac_c" 1>&6
       -echo "configure:3343: checking for nl_langinfo and CODESET" >&5
       +echo "configure:3385: checking for nl_langinfo and CODESET" >&5
        if eval "test \"`echo '$''{'am_cv_langinfo_codeset'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 3348 "configure"
       +#line 3390 "configure"
        #include "confdefs.h"
        #include <langinfo.h>
        int main() {
        char* cs = nl_langinfo(CODESET);
        ; return 0; }
        EOF
       -if { (eval echo configure:3355: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:3397: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          am_cv_langinfo_codeset=yes
        else
       t@@ -3374,19 +3416,19 @@ EOF
        
           if test $ac_cv_header_locale_h = yes; then
            echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
       -echo "configure:3378: checking for LC_MESSAGES" >&5
       +echo "configure:3420: checking for LC_MESSAGES" >&5
        if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 3383 "configure"
       +#line 3425 "configure"
        #include "confdefs.h"
        #include <locale.h>
        int main() {
        return LC_MESSAGES
        ; return 0; }
        EOF
       -if { (eval echo configure:3390: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:3432: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          am_cv_val_LC_MESSAGES=yes
        else
       t@@ -3407,7 +3449,7 @@ EOF
            fi
          fi
           echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
       -echo "configure:3411: checking whether NLS is requested" >&5
       +echo "configure:3453: checking whether NLS is requested" >&5
                # Check whether --enable-nls or --disable-nls was given.
        if test "${enable_nls+set}" = set; then
          enableval="$enable_nls"
       t@@ -3429,7 +3471,7 @@ fi
        EOF
        
              echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
       -echo "configure:3433: checking whether included gettext is requested" >&5
       +echo "configure:3475: checking whether included gettext is requested" >&5
              # Check whether --with-included-gettext or --without-included-gettext was given.
        if test "${with_included_gettext+set}" = set; then
          withval="$with_included_gettext"
       t@@ -3449,17 +3491,17 @@ fi
        
                ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
        echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
       -echo "configure:3453: checking for libintl.h" >&5
       +echo "configure:3495: checking for libintl.h" >&5
        if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 3458 "configure"
       +#line 3500 "configure"
        #include "confdefs.h"
        #include <libintl.h>
        EOF
        ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
       -{ (eval echo configure:3463: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
       +{ (eval echo configure:3505: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
        ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
        if test -z "$ac_err"; then
          rm -rf conftest*
       t@@ -3476,12 +3518,12 @@ fi
        if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
          echo "$ac_t""yes" 1>&6
          echo $ac_n "checking for GNU gettext in libc""... $ac_c" 1>&6
       -echo "configure:3480: checking for GNU gettext in libc" >&5
       +echo "configure:3522: checking for GNU gettext in libc" >&5
        if eval "test \"`echo '$''{'gt_cv_func_gnugettext1_libc'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 3485 "configure"
       +#line 3527 "configure"
        #include "confdefs.h"
        #include <libintl.h>
        extern int _nl_msg_cat_cntr;
       t@@ -3490,7 +3532,7 @@ bindtextdomain ("", "");
        return (int) gettext ("") + _nl_msg_cat_cntr
        ; return 0; }
        EOF
       -if { (eval echo configure:3494: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:3536: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          gt_cv_func_gnugettext1_libc=yes
        else
       t@@ -3506,14 +3548,14 @@ echo "$ac_t""$gt_cv_func_gnugettext1_libc" 1>&6
        
                   if test "$gt_cv_func_gnugettext1_libc" != "yes"; then
                     echo $ac_n "checking for GNU gettext in libintl""... $ac_c" 1>&6
       -echo "configure:3510: checking for GNU gettext in libintl" >&5
       +echo "configure:3552: checking for GNU gettext in libintl" >&5
        if eval "test \"`echo '$''{'gt_cv_func_gnugettext1_libintl'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          gt_save_LIBS="$LIBS"
                        LIBS="$LIBS -lintl $LIBICONV"
                        cat > conftest.$ac_ext <<EOF
       -#line 3517 "configure"
       +#line 3559 "configure"
        #include "confdefs.h"
        #include <libintl.h>
        extern int _nl_msg_cat_cntr;
       t@@ -3522,7 +3564,7 @@ bindtextdomain ("", "");
        return (int) gettext ("") + _nl_msg_cat_cntr
        ; return 0; }
        EOF
       -if { (eval echo configure:3526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:3568: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          gt_cv_func_gnugettext1_libintl=yes
        else
       t@@ -3555,12 +3597,12 @@ EOF
                     for ac_func in dcgettext
        do
        echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
       -echo "configure:3559: checking for $ac_func" >&5
       +echo "configure:3601: checking for $ac_func" >&5
        if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 3564 "configure"
       +#line 3606 "configure"
        #include "confdefs.h"
        /* System header to define __stub macros and hopefully few prototypes,
            which can conflict with char $ac_func(); below.  */
       t@@ -3583,7 +3625,7 @@ $ac_func();
        
        ; return 0; }
        EOF
       -if { (eval echo configure:3587: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:3629: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          eval "ac_cv_func_$ac_func=yes"
        else
       t@@ -3609,10 +3651,10 @@ done
        
                     LIBS="$gt_save_LIBS"
        
       -                          # Extract the first word of "msgfmt", so it can be a program name with args.
       +             # Extract the first word of "msgfmt", so it can be a program name with args.
        set dummy msgfmt; ac_word=$2
        echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
       -echo "configure:3616: checking for $ac_word" >&5
       +echo "configure:3658: checking for $ac_word" >&5
        if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -3625,28 +3667,28 @@ else
          for ac_dir in $PATH; do
            test -z "$ac_dir" && ac_dir=.
            if test -f $ac_dir/$ac_word; then
       -      if $ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1; then
       +      if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
                ac_cv_path_MSGFMT="$ac_dir/$ac_word"
                break
              fi
            fi
          done
          IFS="$ac_save_ifs"
       -  test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":"
       +  test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
          ;;
        esac
        fi
        MSGFMT="$ac_cv_path_MSGFMT"
       -if test "$MSGFMT" != ":"; then
       +if test -n "$MSGFMT"; then
          echo "$ac_t""$MSGFMT" 1>&6
        else
          echo "$ac_t""no" 1>&6
        fi
       -
       -             # Extract the first word of "gmsgfmt", so it can be a program name with args.
       +             if test "$MSGFMT" != "no"; then
       +               # Extract the first word of "gmsgfmt", so it can be a program name with args.
        set dummy gmsgfmt; ac_word=$2
        echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
       -echo "configure:3650: checking for $ac_word" >&5
       +echo "configure:3692: checking for $ac_word" >&5
        if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -3679,11 +3721,12 @@ else
          echo "$ac_t""no" 1>&6
        fi
        
       +             fi
        
       -                          # Extract the first word of "xgettext", so it can be a program name with args.
       +             # Extract the first word of "xgettext", so it can be a program name with args.
        set dummy xgettext; ac_word=$2
        echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
       -echo "configure:3687: checking for $ac_word" >&5
       +echo "configure:3730: checking for $ac_word" >&5
        if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -3696,7 +3739,7 @@ else
          for ac_dir in $PATH; do
            test -z "$ac_dir" && ac_dir=.
            if test -f $ac_dir/$ac_word; then
       -      if $ac_dir/$ac_word --omit-header /dev/null >/dev/null 2>&1; then
       +      if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
                ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
                break
              fi
       t@@ -3708,7 +3751,7 @@ else
        esac
        fi
        XGETTEXT="$ac_cv_path_XGETTEXT"
       -if test "$XGETTEXT" != ":"; then
       +if test -n "$XGETTEXT"; then
          echo "$ac_t""$XGETTEXT" 1>&6
        else
          echo "$ac_t""no" 1>&6
       t@@ -3733,7 +3776,7 @@ fi
                # Extract the first word of "msgfmt", so it can be a program name with args.
        set dummy msgfmt; ac_word=$2
        echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
       -echo "configure:3737: checking for $ac_word" >&5
       +echo "configure:3780: checking for $ac_word" >&5
        if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -3746,19 +3789,19 @@ else
          for ac_dir in $PATH; do
            test -z "$ac_dir" && ac_dir=.
            if test -f $ac_dir/$ac_word; then
       -      if $ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1; then
       +      if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
                ac_cv_path_MSGFMT="$ac_dir/$ac_word"
                break
              fi
            fi
          done
          IFS="$ac_save_ifs"
       -  test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":"
       +  test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
          ;;
        esac
        fi
        MSGFMT="$ac_cv_path_MSGFMT"
       -if test "$MSGFMT" != ":"; then
       +if test -n "$MSGFMT"; then
          echo "$ac_t""$MSGFMT" 1>&6
        else
          echo "$ac_t""no" 1>&6
       t@@ -3767,7 +3810,7 @@ fi
                # Extract the first word of "gmsgfmt", so it can be a program name with args.
        set dummy gmsgfmt; ac_word=$2
        echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
       -echo "configure:3771: checking for $ac_word" >&5
       +echo "configure:3814: checking for $ac_word" >&5
        if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -3803,7 +3846,7 @@ fi
                # Extract the first word of "xgettext", so it can be a program name with args.
        set dummy xgettext; ac_word=$2
        echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
       -echo "configure:3807: checking for $ac_word" >&5
       +echo "configure:3850: checking for $ac_word" >&5
        if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -3816,7 +3859,7 @@ else
          for ac_dir in $PATH; do
            test -z "$ac_dir" && ac_dir=.
            if test -f $ac_dir/$ac_word; then
       -      if $ac_dir/$ac_word --omit-header /dev/null >/dev/null 2>&1; then
       +      if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
                ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
                break
              fi
       t@@ -3828,7 +3871,7 @@ else
        esac
        fi
        XGETTEXT="$ac_cv_path_XGETTEXT"
       -if test "$XGETTEXT" != ":"; then
       +if test -n "$XGETTEXT"; then
          echo "$ac_t""$XGETTEXT" 1>&6
        else
          echo "$ac_t""no" 1>&6
       t@@ -3842,17 +3885,8 @@ fi
                LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
              fi
        
       -                  if test "$GMSGFMT" != ":"; then
       -                        if $GMSGFMT --statistics /dev/null >/dev/null 2>&1; then
       -          : ;
       -        else
       -          echo "$ac_t""found msgfmt program is not GNU msgfmt; ignore it" 1>&6
       -          GMSGFMT=":"
       -        fi
       -      fi
       -
       -                  if test "$XGETTEXT" != ":"; then
       -                        if $XGETTEXT --omit-header /dev/null >/dev/null 2>&1; then
       +            if test "$XGETTEXT" != ":"; then
       +                        if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
                  : ;
                else
                  echo "$ac_t""found xgettext program is not GNU xgettext; ignore it" 1>&6
       t@@ -3874,7 +3908,7 @@ do
        # Extract the first word of "$ac_prog", so it can be a program name with args.
        set dummy $ac_prog; ac_word=$2
        echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
       -echo "configure:3878: checking for $ac_word" >&5
       +echo "configure:3912: checking for $ac_word" >&5
        if eval "test \"`echo '$''{'ac_cv_prog_INTLBISON'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -3907,8 +3941,8 @@ done
              ac_verc_fail=yes
            else
                    echo $ac_n "checking version of bison""... $ac_c" 1>&6
       -echo "configure:3911: checking version of bison" >&5
       -      ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'`
       +echo "configure:3945: checking version of bison" >&5
       +      ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison .* \([0-9]*\.[0-9.]*\).*$/\1/p'`
              case $ac_prog_version in
                '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
                1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*)
       t@@ -3954,7 +3988,7 @@ echo "configure:3911: checking version of bison" >&5
               LINGUAS=
             else
               echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
       -echo "configure:3958: checking for catalogs to be installed" >&5
       +echo "configure:3992: checking for catalogs to be installed" >&5
               NEW_LINGUAS=
               for presentlang in $ALL_LINGUAS; do
                 useit=no
       t@@ -3994,7 +4028,7 @@ echo "configure:3958: checking for catalogs to be installed" >&5
           
          
        if test "$gt_cv_func_gettext_libintl" = "yes"; then
       -    LIBS="-lintl  $LIBS"
       +    LIBS="-lintl $LIBS"
        fi
        
        localedir=${datadir}/locale
       t@@ -4014,13 +4048,6 @@ EOF
        
        fi
        
       -# Check whether --enable-gui-server or --disable-gui-server was given.
       -if test "${enable_gui_server+set}" = set; then
       -  enableval="$enable_gui_server"
       -   GUI_SERVER="$enableval" 
       -fi
       -
       -
        if test "$GUI_SERVER" = "yes" ; then
           cat >> confdefs.h <<\EOF
        #define GUI_SERVER 1
       t@@ -4035,15 +4062,8 @@ EOF
        
        fi
        
       -if test "$GUI_CLIENT" = "yes" -o "$GUI_SERVER" = "yes" ; then
       -      GTKPORT_C="gtkport.c"
       -   GTKPORT_O="gtkport.o"
       -   
       -   
       -fi
       -
        echo $ac_n "checking size of long long""... $ac_c" 1>&6
       -echo "configure:4047: checking size of long long" >&5
       +echo "configure:4067: checking size of long long" >&5
        if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -4051,18 +4071,18 @@ else
            { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
        else
          cat > conftest.$ac_ext <<EOF
       -#line 4055 "configure"
       +#line 4075 "configure"
        #include "confdefs.h"
        #include <stdio.h>
       -main()
       +int main()
        {
          FILE *f=fopen("conftestval", "w");
       -  if (!f) exit(1);
       +  if (!f) return(1);
          fprintf(f, "%d\n", sizeof(long long));
       -  exit(0);
       +  return(0);
        }
        EOF
       -if { (eval echo configure:4066: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
       +if { (eval echo configure:4086: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
        then
          ac_cv_sizeof_long_long=`cat conftestval`
        else
       t@@ -4083,7 +4103,7 @@ EOF
        
        
        echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
       -echo "configure:4087: checking for 8-bit clean memcmp" >&5
       +echo "configure:4107: checking for 8-bit clean memcmp" >&5
        if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -4091,7 +4111,7 @@ else
          ac_cv_func_memcmp_clean=no
        else
          cat > conftest.$ac_ext <<EOF
       -#line 4095 "configure"
       +#line 4115 "configure"
        #include "confdefs.h"
        
        main()
       t@@ -4101,7 +4121,7 @@ main()
        }
        
        EOF
       -if { (eval echo configure:4105: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
       +if { (eval echo configure:4125: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
        then
          ac_cv_func_memcmp_clean=yes
        else
       t@@ -4119,7 +4139,7 @@ echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6
        test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}"
        
        echo $ac_n "checking whether setvbuf arguments are reversed""... $ac_c" 1>&6
       -echo "configure:4123: checking whether setvbuf arguments are reversed" >&5
       +echo "configure:4143: checking whether setvbuf arguments are reversed" >&5
        if eval "test \"`echo '$''{'ac_cv_func_setvbuf_reversed'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
       t@@ -4127,7 +4147,7 @@ else
            { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
        else
          cat > conftest.$ac_ext <<EOF
       -#line 4131 "configure"
       +#line 4151 "configure"
        #include "confdefs.h"
        #include <stdio.h>
        /* If setvbuf has the reversed format, exit 0. */
       t@@ -4141,7 +4161,7 @@ main () {
          exit(0);                        /* Non-reversed systems segv here.  */
        }
        EOF
       -if { (eval echo configure:4145: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
       +if { (eval echo configure:4165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
        then
          ac_cv_func_setvbuf_reversed=yes
        else
       t@@ -4165,12 +4185,12 @@ EOF
        fi
        
        echo $ac_n "checking for strftime""... $ac_c" 1>&6
       -echo "configure:4169: checking for strftime" >&5
       +echo "configure:4189: checking for strftime" >&5
        if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 4174 "configure"
       +#line 4194 "configure"
        #include "confdefs.h"
        /* System header to define __stub macros and hopefully few prototypes,
            which can conflict with char strftime(); below.  */
       t@@ -4193,7 +4213,7 @@ strftime();
        
        ; return 0; }
        EOF
       -if { (eval echo configure:4197: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:4217: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          eval "ac_cv_func_strftime=yes"
        else
       t@@ -4215,7 +4235,7 @@ else
          echo "$ac_t""no" 1>&6
        # strftime is in -lintl on SCO UNIX.
        echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6
       -echo "configure:4219: checking for strftime in -lintl" >&5
       +echo "configure:4239: checking for strftime in -lintl" >&5
        ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'`
        if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
       t@@ -4223,7 +4243,7 @@ else
          ac_save_LIBS="$LIBS"
        LIBS="-lintl  $LIBS"
        cat > conftest.$ac_ext <<EOF
       -#line 4227 "configure"
       +#line 4247 "configure"
        #include "confdefs.h"
        /* Override any gcc2 internal prototype to avoid an error.  */
        /* We use char because int might match the return type of a gcc2
       t@@ -4234,7 +4254,7 @@ int main() {
        strftime()
        ; return 0; }
        EOF
       -if { (eval echo configure:4238: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:4258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          eval "ac_cv_lib_$ac_lib_var=yes"
        else
       t@@ -4263,12 +4283,12 @@ fi
        for ac_func in strdup strstr getopt_long fork
        do
        echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
       -echo "configure:4267: checking for $ac_func" >&5
       +echo "configure:4287: checking for $ac_func" >&5
        if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 4272 "configure"
       +#line 4292 "configure"
        #include "confdefs.h"
        /* System header to define __stub macros and hopefully few prototypes,
            which can conflict with char $ac_func(); below.  */
       t@@ -4291,7 +4311,7 @@ $ac_func();
        
        ; return 0; }
        EOF
       -if { (eval echo configure:4295: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:4315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          eval "ac_cv_func_$ac_func=yes"
        else
       t@@ -4322,14 +4342,14 @@ if test "$CYGWIN" = "yes" ; then
        else
                    
        echo $ac_n "checking for library containing socket""... $ac_c" 1>&6
       -echo "configure:4326: checking for library containing socket" >&5
       +echo "configure:4346: checking for library containing socket" >&5
        if eval "test \"`echo '$''{'ac_cv_search_socket'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          ac_func_search_save_LIBS="$LIBS"
        ac_cv_search_socket="no"
        cat > conftest.$ac_ext <<EOF
       -#line 4333 "configure"
       +#line 4353 "configure"
        #include "confdefs.h"
        /* Override any gcc2 internal prototype to avoid an error.  */
        /* We use char because int might match the return type of a gcc2
       t@@ -4340,7 +4360,7 @@ int main() {
        socket()
        ; return 0; }
        EOF
       -if { (eval echo configure:4344: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:4364: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          ac_cv_search_socket="none required"
        else
       t@@ -4351,7 +4371,7 @@ rm -f conftest*
        test "$ac_cv_search_socket" = "no" && for i in socket; do
        LIBS="-l$i  $ac_func_search_save_LIBS"
        cat > conftest.$ac_ext <<EOF
       -#line 4355 "configure"
       +#line 4375 "configure"
        #include "confdefs.h"
        /* Override any gcc2 internal prototype to avoid an error.  */
        /* We use char because int might match the return type of a gcc2
       t@@ -4362,7 +4382,7 @@ int main() {
        socket()
        ; return 0; }
        EOF
       -if { (eval echo configure:4366: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:4386: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          ac_cv_search_socket="-l$i"
        break
       t@@ -4384,14 +4404,14 @@ else :
        fi
           
        echo $ac_n "checking for library containing gethostbyname""... $ac_c" 1>&6
       -echo "configure:4388: checking for library containing gethostbyname" >&5
       +echo "configure:4408: checking for library containing gethostbyname" >&5
        if eval "test \"`echo '$''{'ac_cv_search_gethostbyname'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          ac_func_search_save_LIBS="$LIBS"
        ac_cv_search_gethostbyname="no"
        cat > conftest.$ac_ext <<EOF
       -#line 4395 "configure"
       +#line 4415 "configure"
        #include "confdefs.h"
        /* Override any gcc2 internal prototype to avoid an error.  */
        /* We use char because int might match the return type of a gcc2
       t@@ -4402,7 +4422,7 @@ int main() {
        gethostbyname()
        ; return 0; }
        EOF
       -if { (eval echo configure:4406: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:4426: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          ac_cv_search_gethostbyname="none required"
        else
       t@@ -4413,7 +4433,7 @@ rm -f conftest*
        test "$ac_cv_search_gethostbyname" = "no" && for i in nsl socket; do
        LIBS="-l$i  $ac_func_search_save_LIBS"
        cat > conftest.$ac_ext <<EOF
       -#line 4417 "configure"
       +#line 4437 "configure"
        #include "confdefs.h"
        /* Override any gcc2 internal prototype to avoid an error.  */
        /* We use char because int might match the return type of a gcc2
       t@@ -4424,7 +4444,7 @@ int main() {
        gethostbyname()
        ; return 0; }
        EOF
       -if { (eval echo configure:4428: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:4448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          ac_cv_search_gethostbyname="-l$i"
        break
       t@@ -4447,12 +4467,12 @@ fi
           for ac_func in socket gethostbyname select
        do
        echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
       -echo "configure:4451: checking for $ac_func" >&5
       +echo "configure:4471: checking for $ac_func" >&5
        if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
          echo $ac_n "(cached) $ac_c" 1>&6
        else
          cat > conftest.$ac_ext <<EOF
       -#line 4456 "configure"
       +#line 4476 "configure"
        #include "confdefs.h"
        /* System header to define __stub macros and hopefully few prototypes,
            which can conflict with char $ac_func(); below.  */
       t@@ -4475,7 +4495,7 @@ $ac_func();
        
        ; return 0; }
        EOF
       -if { (eval echo configure:4479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
       +if { (eval echo configure:4499: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
          rm -rf conftest*
          eval "ac_cv_func_$ac_func=yes"
        else
       t@@ -4539,6 +4559,35 @@ fi
        
        CFLAGS="$CFLAGS -DDATADIR=\\\"${datadir}\\\""
        
       +
       +
       +if test "$GUI_CLIENT" = "yes"; then
       +  GUI_CLIENT_TRUE=
       +  GUI_CLIENT_FALSE='#'
       +else
       +  GUI_CLIENT_TRUE='#'
       +  GUI_CLIENT_FALSE=
       +fi
       +
       +
       +if test "$CURSES_CLIENT" = "yes"; then
       +  CURSES_CLIENT_TRUE=
       +  CURSES_CLIENT_FALSE='#'
       +else
       +  CURSES_CLIENT_TRUE='#'
       +  CURSES_CLIENT_FALSE=
       +fi
       +
       +
       +
       +if test "$GUI_CLIENT" = "yes" -o "$GUI_SERVER" = "yes"; then
       +  GTKPORT_TRUE=
       +  GTKPORT_FALSE='#'
       +else
       +  GTKPORT_TRUE='#'
       +  GTKPORT_FALSE=
       +fi
       +
        trap '' 1 2 15
        cat > confcache <<\EOF
        # This file is a shell script that caches the results of configure
       t@@ -4643,6 +4692,9 @@ ac_given_INSTALL="$INSTALL"
        trap 'rm -fr `echo "
        Makefile
        src/Makefile
       +src/gui_client/Makefile
       +src/curses_client/Makefile
       +src/gtkport/Makefile
        doc/Makefile
        intl/Makefile
        po/Makefile.in config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
       t@@ -4726,9 +4778,13 @@ s%@GENCAT@%$GENCAT%g
        s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
        s%@INTL_LIBTOOL_SUFFIX_PREFIX@%$INTL_LIBTOOL_SUFFIX_PREFIX%g
        s%@localedir@%$localedir%g
       -s%@GTKPORT_C@%$GTKPORT_C%g
       -s%@GTKPORT_O@%$GTKPORT_O%g
        s%@LIBOBJS@%$LIBOBJS%g
       +s%@GUI_CLIENT_TRUE@%$GUI_CLIENT_TRUE%g
       +s%@GUI_CLIENT_FALSE@%$GUI_CLIENT_FALSE%g
       +s%@CURSES_CLIENT_TRUE@%$CURSES_CLIENT_TRUE%g
       +s%@CURSES_CLIENT_FALSE@%$CURSES_CLIENT_FALSE%g
       +s%@GTKPORT_TRUE@%$GTKPORT_TRUE%g
       +s%@GTKPORT_FALSE@%$GTKPORT_FALSE%g
        
        CEOF
        EOF
       t@@ -4772,6 +4828,9 @@ cat >> $CONFIG_STATUS <<EOF
        
        CONFIG_FILES=\${CONFIG_FILES-"Makefile
        src/Makefile
       +src/gui_client/Makefile
       +src/curses_client/Makefile
       +src/gtkport/Makefile
        doc/Makefile
        intl/Makefile
        po/Makefile.in"}
       t@@ -4959,9 +5018,6 @@ for ac_file in $CONFIG_FILES; do
                  ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
                  ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
                  ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
       -          # In autoconf-2.13 it is called $ac_given_srcdir.
       -          # In autoconf-2.50 it is called $srcdir.
       -          test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
                  case "$ac_given_srcdir" in
                    .)  top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
                    /*) top_srcdir="$ac_given_srcdir" ;;
       t@@ -4969,9 +5025,9 @@ for ac_file in $CONFIG_FILES; do
                  esac
                  if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
                    rm -f "$ac_dir/POTFILES"
       -            test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
       +            echo creating "$ac_dir/POTFILES"
                    sed -e "/^#/d" -e "/^[         ]*\$/d" -e "s,.*,     $top_srcdir/& \\\\," -e "\$s/\(.*\) \\\\/\1/" < "$ac_given_srcdir/$ac_dir/POTFILES.in" > "$ac_dir/POTFILES"
       -            test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
       +            echo creating "$ac_dir/Makefile"
                    sed -e "/POTFILES =/r $ac_dir/POTFILES" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
                  fi
                  ;;
 (DIR) diff --git a/configure.in b/configure.in
       t@@ -35,11 +35,15 @@ HAVE_FIXED_GTK="no"
        dnl Process client options
        AC_ARG_ENABLE(gui-client,
        [  --enable-gui-client     include graphical client (GTK+/Win32)],
       -[ GUI_CLIENT="$enableval" ],[ GUI_CLIENT="yes" ])
       +[ GUI_CLIENT="$enableval" ],[ GUI_CLIENT="probe" ])
        
        AC_ARG_ENABLE(curses-client,
        [  --enable-curses-client  include curses client],
       -[ CURSES_CLIENT="$enableval" ],[ CURSES_CLIENT="yes" ])
       +[ CURSES_CLIENT="$enableval" ],[ CURSES_CLIENT="probe" ])
       +
       +AC_ARG_ENABLE(gui-server,
       +[  --enable-gui-server     use a simple GTK+/Win32 GUI for the server],
       +[ GUI_SERVER="$enableval" ],[ GUI_SERVER="probe" ])
        
        dnl Test for Cygwin environment
        AC_CYGWIN
       t@@ -74,7 +78,9 @@ if test "$CYGWIN" = "yes" ; then
           HAVE_FIXED_GTK="yes"
        
           dnl Use graphical server by default
       -   GUI_SERVER="yes"
       +   if test "$GUI_SERVER" = "probe"; then
       +     GUI_SERVER="yes"
       +   fi
        else
           AC_MSG_RESULT("Configuring for Unix binary")
        
       t@@ -82,26 +88,35 @@ else
           AM_PATH_GLIB(1.2.0,,[AC_MSG_ERROR(Cannot find glib - aborting)])
        
           dnl On true Unix systems, test for valid curses-like libraries
       -   if test "$CURSES_CLIENT" = "yes" ; then
       +   if test "$CURSES_CLIENT" != "no" ; then
              AC_CHECK_LIB(ncurses,newterm)
              if test "$ac_cv_lib_ncurses_newterm" = "no" ; then
                 AC_CHECK_LIB(curses,newterm)
                 if test "$ac_cv_lib_curses_newterm" = "no" ; then
                    AC_CHECK_LIB(cur_colr,newterm)
                    if test "$ac_cv_lib_cur_colr_newterm" = "no" ; then
       -               AC_MSG_WARN(Cannot find any curses-type library)
       -               CURSES_CLIENT="no"
       +               if test "$CURSES_CLIENT" = "yes" ; then
       +                 AC_MSG_ERROR(Cannot find any curses-type library)
       +               else
       +                 AC_MSG_WARN(Cannot find any curses-type library)
       +                 CURSES_CLIENT="no"
       +               fi
                    fi
                 fi
              fi
           fi
        
       -   if test "$GUI_CLIENT" = "yes" ; then
       +   if test "$GUI_CLIENT" != "no" -o "$GUI_SERVER" != "no"; then
              dnl Tests for GTK
              AM_PATH_GTK(1.2.0,gtk_found="yes",gtk_found="no")
              if test "$gtk_found" = "no" ; then
       -         AC_MSG_WARN(Cannot find GTK+)
       -         GUI_CLIENT="no"
       +         if test "$GUI_CLIENT" = "yes" -o "$GUI_SERVER" = "yes" ; then
       +           AC_MSG_ERROR(Cannot find GTK+)
       +         else
       +           AC_MSG_WARN(Cannot find GTK+)
       +           GUI_CLIENT="no"
       +           GUI_SERVER="no"
       +         fi
              else
                 AC_MSG_CHECKING([for non-buggy GTK+ ( >= 1.2.10 )])
                 dnl Versions older than 1.2.10 are buggy
       t@@ -125,7 +140,9 @@ else
           LDFLAGS="$LDFLAGS `glib-config --libs`"
        
           dnl Use console server by default
       -   GUI_SERVER="no"
       +   if test "$GUI_SERVER" = "probe"; then
       +     GUI_SERVER="no"
       +   fi
        
           dnl Some systems use int rather than socklen_t as an argument to getsockopt
           AC_MSG_CHECKING([for socklen_t data type])
       t@@ -136,11 +153,20 @@ else
                          [AC_MSG_RESULT([no])])
        fi
        
       +dnl If probing was unsuccessful, these will be set to "no"; therefore,
       +dnl if still set to "probe" then everything worked, so set to "yes"
       +if test "$GUI_CLIENT" = "probe"; then
       +  GUI_CLIENT="yes"
       +fi
       +if test "$CURSES_CLIENT" = "probe"; then
       +  CURSES_CLIENT="yes"
       +fi
       +
        dnl Do i18n stuff
        ALL_LINGUAS="de pl pt_BR fr"
        AM_GNU_GETTEXT
        if test "$gt_cv_func_gettext_libintl" = "yes"; then
       -    LIBS="-lintl  $LIBS"
       +    LIBS="-lintl $LIBS"
        fi
        
        localedir=${datadir}/locale
       t@@ -154,12 +180,6 @@ if test "$CURSES_CLIENT" = "yes" ; then
           AC_DEFINE(CURSES_CLIENT)
        fi
        
       -dnl Let the user override the server interface with the
       -dnl --enable-gui-server option
       -AC_ARG_ENABLE(gui-server,
       -[  --enable-gui-server     use a simple GTK+/Win32 GUI for the server],
       -[ GUI_SERVER="$enableval" ])
       -
        if test "$GUI_SERVER" = "yes" ; then
           AC_DEFINE(GUI_SERVER)
        fi
       t@@ -168,14 +188,6 @@ if test "$HAVE_FIXED_GTK" = "yes" ; then
           AC_DEFINE(HAVE_FIXED_GTK)
        fi
        
       -if test "$GUI_CLIENT" = "yes" -o "$GUI_SERVER" = "yes" ; then
       -   dnl Compile in the gtkport stuff for any kind of GUI
       -   GTKPORT_C="gtkport.c"
       -   GTKPORT_O="gtkport.o"
       -   AC_SUBST(GTKPORT_C)
       -   AC_SUBST(GTKPORT_O)
       -fi
       -
        dnl Can we use a long long datatype for price_t ?
        AC_CHECK_SIZEOF(long long)
        
       t@@ -230,12 +242,22 @@ if test -n "$GCC"; then
        fi
        
        dnl Pass the data directory to the compiler so the program knows
       -dnl where the high score file is
       +dnl where the high scores and docs are
        CFLAGS="$CFLAGS -DDATADIR=\\\"${datadir}\\\""
        
       +dnl Add in the required clients
       +AM_CONDITIONAL(GUI_CLIENT, test "$GUI_CLIENT" = "yes")
       +AM_CONDITIONAL(CURSES_CLIENT, test "$CURSES_CLIENT" = "yes")
       +
       +dnl Compile in the gtkport stuff for any kind of GUI
       +AM_CONDITIONAL(GTKPORT, test "$GUI_CLIENT" = "yes" -o "$GUI_SERVER" = "yes")
       +
        AC_OUTPUT([
        Makefile
        src/Makefile
       +src/gui_client/Makefile
       +src/curses_client/Makefile
       +src/gtkport/Makefile
        doc/Makefile
        intl/Makefile
        po/Makefile.in],
 (DIR) diff --git a/doc/Makefile.in b/doc/Makefile.in
       t@@ -1,6 +1,6 @@
       -# Makefile.in generated automatically by automake 1.4 from Makefile.am
       +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
        
       -# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
       +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
        # This Makefile.in is free software; the Free Software Foundation
        # gives unlimited permission to copy and/or distribute it,
        # with or without modifications, as long as this notice is preserved.
       t@@ -71,8 +71,6 @@ GLIB_CONFIG = @GLIB_CONFIG@
        GLIB_LIBS = @GLIB_LIBS@
        GMOFILES = @GMOFILES@
        GMSGFMT = @GMSGFMT@
       -GTKPORT_C = @GTKPORT_C@
       -GTKPORT_O = @GTKPORT_O@
        GTK_CFLAGS = @GTK_CFLAGS@
        GTK_CONFIG = @GTK_CONFIG@
        GTK_LIBS = @GTK_LIBS@
       t@@ -96,7 +94,10 @@ WNDRES = @WNDRES@
        localedir = @localedir@
        
        DOCPATH = ${DESTDIR}${datadir}/doc/${PACKAGE}-${VERSION}/
       -DOCS = aiplayer.html configfile.html index.html i18n.html server.html       clientplay.html credits.html installation.html       servercommands.html commandline.html developer.html       metaserver.html protocol.html windows.html
       +DOCS = aiplayer.html configfile.html index.html i18n.html server.html \
       +      clientplay.html credits.html installation.html \
       +      servercommands.html commandline.html developer.html \
       +      metaserver.html protocol.html windows.html
        
        man_MANS = dopewars.6
        EXTRA_DIST = ${man_MANS}
 (DIR) diff --git a/src/Makefile.am b/src/Makefile.am
       t@@ -1,10 +1,28 @@
       +if GUI_CLIENT
       +GUISUBDIR = gui_client
       +GUIDEP = gui_client/libguiclient.a
       +endif
       +
       +if CURSES_CLIENT
       +CURSESSUBDIR = curses_client
       +CURSESDEP = curses_client/libcursesclient.a
       +endif
       +
       +if GTKPORT
       +GTKPORTSUBDIR = gtkport
       +GTKPORTDEP = gtkport/libgtkport.a
       +endif
       +
       +SUBDIRS = $(GUISUBDIR) $(CURSESSUBDIR) $(GTKPORTSUBDIR)
       +dopewars_DEPENDENCIES = @INTLLIBS@ @WNDRES@ $(GUIDEP) $(CURSESDEP) $(GTKPORTDEP)
       +dopewars_LDADD = $(GUIDEP) $(CURSESDEP) $(GTKPORTDEP) @GTK_LIBS@ @INTLLIBS@ @WNDRES@
       +
        bin_PROGRAMS = dopewars
       -dopewars_SOURCES = admin.c AIPlayer.c curses_client.c dopeos.c dopewars.c \
       -                   error.c gtk_client.c message.c network.c serverside.c \
       -                   tstring.c winmain.c @GTKPORT_C@
       -dopewars_DEPENDENCIES = @INTLLIBS@ @GTKPORT_O@ @WNDRES@
       -INCLUDES   = @GTK_CFLAGS@ -I.. -I.
       -LDADD      = @GTKPORT_O@ @GTK_LIBS@ @INTLLIBS@ @WNDRES@
       +dopewars_SOURCES = admin.c AIPlayer.c dopeos.c dopewars.c \
       +                   error.c message.c network.c serverside.c \
       +                   tstring.c winmain.c
       +
       +INCLUDES   = -I.. -I. @GTK_CFLAGS@
        DEFS       = @DEFS@ -DLOCALEDIR=\"${localedir}\"
        PIXDIR     = ${DESTDIR}${datadir}/pixmaps
        PIXMAPS    = dopewars-pill.png dopewars-shot.png dopewars-weed.png
 (DIR) diff --git a/src/Makefile.in b/src/Makefile.in
       t@@ -1,6 +1,6 @@
       -# Makefile.in generated automatically by automake 1.4 from Makefile.am
       +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
        
       -# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
       +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
        # This Makefile.in is free software; the Free Software Foundation
        # gives unlimited permission to copy and/or distribute it,
        # with or without modifications, as long as this notice is preserved.
       t@@ -71,8 +71,6 @@ GLIB_CONFIG = @GLIB_CONFIG@
        GLIB_LIBS = @GLIB_LIBS@
        GMOFILES = @GMOFILES@
        GMSGFMT = @GMSGFMT@
       -GTKPORT_C = @GTKPORT_C@
       -GTKPORT_O = @GTKPORT_O@
        GTK_CFLAGS = @GTK_CFLAGS@
        GTK_CONFIG = @GTK_CONFIG@
        GTK_LIBS = @GTK_LIBS@
       t@@ -95,12 +93,26 @@ VERSION = @VERSION@
        WNDRES = @WNDRES@
        localedir = @localedir@
        
       +@GUI_CLIENT_TRUE@GUISUBDIR = @GUI_CLIENT_TRUE@gui_client
       +@GUI_CLIENT_TRUE@GUIDEP = @GUI_CLIENT_TRUE@gui_client/libguiclient.a
       +
       +@CURSES_CLIENT_TRUE@CURSESSUBDIR = @CURSES_CLIENT_TRUE@curses_client
       +@CURSES_CLIENT_TRUE@CURSESDEP = @CURSES_CLIENT_TRUE@curses_client/libcursesclient.a
       +
       +@GTKPORT_TRUE@GTKPORTSUBDIR = @GTKPORT_TRUE@gtkport
       +@GTKPORT_TRUE@GTKPORTDEP = @GTKPORT_TRUE@gtkport/libgtkport.a
       +
       +SUBDIRS = $(GUISUBDIR) $(CURSESSUBDIR) $(GTKPORTSUBDIR)
       +dopewars_DEPENDENCIES = @INTLLIBS@ @WNDRES@ $(GUIDEP) $(CURSESDEP) $(GTKPORTDEP)
       +dopewars_LDADD = $(GUIDEP) $(CURSESDEP) $(GTKPORTDEP) @GTK_LIBS@ @INTLLIBS@ @WNDRES@
       +
        bin_PROGRAMS = dopewars
       -dopewars_SOURCES = admin.c AIPlayer.c curses_client.c dopeos.c dopewars.c                    error.c gtk_client.c message.c network.c serverside.c                    tstring.c winmain.c @GTKPORT_C@
       +dopewars_SOURCES = admin.c AIPlayer.c dopeos.c dopewars.c \
       +                   error.c message.c network.c serverside.c \
       +                   tstring.c winmain.c
        
       -dopewars_DEPENDENCIES = @INTLLIBS@ @GTKPORT_O@ @WNDRES@
       -INCLUDES = @GTK_CFLAGS@ -I.. -I.
       -LDADD = @GTKPORT_O@ @GTK_LIBS@ @INTLLIBS@ @WNDRES@
       +
       +INCLUDES = -I.. -I. @GTK_CFLAGS@
        DEFS = @DEFS@ -DLOCALEDIR=\"${localedir}\"
        PIXDIR = ${DESTDIR}${datadir}/pixmaps
        PIXMAPS = dopewars-pill.png dopewars-shot.png dopewars-weed.png
       t@@ -114,10 +126,8 @@ PROGRAMS =  $(bin_PROGRAMS)
        CPPFLAGS = @CPPFLAGS@
        LDFLAGS = @LDFLAGS@
        LIBS = @LIBS@
       -dopewars_OBJECTS =  admin.o AIPlayer.o curses_client.o dopeos.o \
       -dopewars.o error.o gtk_client.o message.o network.o serverside.o \
       -tstring.o winmain.o
       -dopewars_LDADD = $(LDADD)
       +dopewars_OBJECTS =  admin.o AIPlayer.o dopeos.o dopewars.o error.o \
       +message.o network.o serverside.o tstring.o winmain.o
        dopewars_LDFLAGS = 
        CFLAGS = @CFLAGS@
        COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
       t@@ -130,10 +140,10 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
        
        TAR = gtar
        GZIP_ENV = --best
       -DEP_FILES =  .deps/AIPlayer.P .deps/admin.P .deps/curses_client.P \
       -.deps/dopeos.P .deps/dopewars.P .deps/error.P .deps/gtk_client.P \
       -.deps/message.P .deps/network.P .deps/serverside.P .deps/tstring.P \
       -.deps/winmain.P
       +DIST_SUBDIRS =  gui_client curses_client gtkport
       +DEP_FILES =  .deps/AIPlayer.P .deps/admin.P .deps/dopeos.P \
       +.deps/dopewars.P .deps/error.P .deps/message.P .deps/network.P \
       +.deps/serverside.P .deps/tstring.P .deps/winmain.P
        SOURCES = $(dopewars_SOURCES)
        OBJECTS = $(dopewars_OBJECTS)
        
       t@@ -193,6 +203,61 @@ dopewars: $(dopewars_OBJECTS) $(dopewars_DEPENDENCIES)
                @rm -f dopewars
                $(LINK) $(dopewars_LDFLAGS) $(dopewars_OBJECTS) $(dopewars_LDADD) $(LIBS)
        
       +# This directory's subdirectories are mostly independent; you can cd
       +# into them and run `make' without going through this Makefile.
       +# To change the values of `make' variables: instead of editing Makefiles,
       +# (1) if the variable is set in `config.status', edit `config.status'
       +#     (which will cause the Makefiles to be regenerated when you run `make');
       +# (2) otherwise, pass the desired values on the `make' command line.
       +
       +@SET_MAKE@
       +
       +all-recursive install-data-recursive install-exec-recursive \
       +installdirs-recursive install-recursive uninstall-recursive  \
       +check-recursive installcheck-recursive info-recursive dvi-recursive:
       +        @set fnord $(MAKEFLAGS); amf=$$2; \
       +        dot_seen=no; \
       +        target=`echo $@ | sed s/-recursive//`; \
       +        list='$(SUBDIRS)'; for subdir in $$list; do \
       +          echo "Making $$target in $$subdir"; \
       +          if test "$$subdir" = "."; then \
       +            dot_seen=yes; \
       +            local_target="$$target-am"; \
       +          else \
       +            local_target="$$target"; \
       +          fi; \
       +          (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
       +           || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
       +        done; \
       +        if test "$$dot_seen" = "no"; then \
       +          $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
       +        fi; test -z "$$fail"
       +
       +mostlyclean-recursive clean-recursive distclean-recursive \
       +maintainer-clean-recursive:
       +        @set fnord $(MAKEFLAGS); amf=$$2; \
       +        dot_seen=no; \
       +        rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
       +          rev="$$subdir $$rev"; \
       +          test "$$subdir" != "." || dot_seen=yes; \
       +        done; \
       +        test "$$dot_seen" = "no" && rev=". $$rev"; \
       +        target=`echo $@ | sed s/-recursive//`; \
       +        for subdir in $$rev; do \
       +          echo "Making $$target in $$subdir"; \
       +          if test "$$subdir" = "."; then \
       +            local_target="$$target-am"; \
       +          else \
       +            local_target="$$target"; \
       +          fi; \
       +          (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
       +           || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
       +        done && test -z "$$fail"
       +tags-recursive:
       +        list='$(SUBDIRS)'; for subdir in $$list; do \
       +          test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
       +        done
       +
        tags: TAGS
        
        ID: $(HEADERS) $(SOURCES) $(LISP)
       t@@ -203,9 +268,14 @@ ID: $(HEADERS) $(SOURCES) $(LISP)
                here=`pwd` && cd $(srcdir) \
                  && mkid -f$$here/ID $$unique $(LISP)
        
       -TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
       +TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
                tags=; \
                here=`pwd`; \
       +        list='$(SUBDIRS)'; for subdir in $$list; do \
       +   if test "$$subdir" = .; then :; else \
       +            test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
       +   fi; \
       +        done; \
                list='$(SOURCES) $(HEADERS)'; \
                unique=`for i in $$list; do echo $$i; done | \
                  awk '    { files[$$0] = 1; } \
       t@@ -242,6 +312,16 @@ distdir: $(DISTFILES)
                    || cp -p $$d/$$file $(distdir)/$$file || :; \
                  fi; \
                done
       +        for subdir in $(DIST_SUBDIRS); do \
       +          if test "$$subdir" = .; then :; else \
       +            test -d $(distdir)/$$subdir \
       +            || mkdir $(distdir)/$$subdir \
       +            || exit 1; \
       +            chmod 777 $(distdir)/$$subdir; \
       +            (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
       +              || exit 1; \
       +          fi; \
       +        done
        
        DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
        
       t@@ -275,31 +355,32 @@ maintainer-clean-depend:
                    >> .deps/$(*F).P; \
                rm -f .deps/$(*F).pp
        info-am:
       -info: info-am
       +info: info-recursive
        dvi-am:
       -dvi: dvi-am
       +dvi: dvi-recursive
        check-am: all-am
       -check: check-am
       +check: check-recursive
        installcheck-am:
       -installcheck: installcheck-am
       +installcheck: installcheck-recursive
        install-exec-am: install-binPROGRAMS
                @$(NORMAL_INSTALL)
                $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
       -install-exec: install-exec-am
       +install-exec: install-exec-recursive
        
        install-data-am: install-data-local
       -install-data: install-data-am
       +install-data: install-data-recursive
        
        install-am: all-am
                @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
       -install: install-am
       +install: install-recursive
        uninstall-am: uninstall-binPROGRAMS
       -uninstall: uninstall-am
       +uninstall: uninstall-recursive
        all-am: Makefile $(PROGRAMS)
       -all-redirect: all-am
       +all-redirect: all-recursive
        install-strip:
                $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
       -installdirs:
       +installdirs: installdirs-recursive
       +installdirs-am:
                $(mkinstalldirs)  $(DESTDIR)$(bindir)
        
        
       t@@ -315,17 +396,17 @@ maintainer-clean-generic:
        mostlyclean-am:  mostlyclean-binPROGRAMS mostlyclean-compile \
                        mostlyclean-tags mostlyclean-depend mostlyclean-generic
        
       -mostlyclean: mostlyclean-am
       +mostlyclean: mostlyclean-recursive
        
        clean-am:  clean-binPROGRAMS clean-compile clean-tags clean-depend \
                        clean-generic mostlyclean-am
        
       -clean: clean-am
       +clean: clean-recursive
        
        distclean-am:  distclean-binPROGRAMS distclean-compile distclean-tags \
                        distclean-depend distclean-generic clean-am
        
       -distclean: distclean-am
       +distclean: distclean-recursive
        
        maintainer-clean-am:  maintainer-clean-binPROGRAMS \
                        maintainer-clean-compile maintainer-clean-tags \
       t@@ -334,18 +415,24 @@ maintainer-clean-am:  maintainer-clean-binPROGRAMS \
                @echo "This command is intended for maintainers to use;"
                @echo "it deletes files that may require special tools to rebuild."
        
       -maintainer-clean: maintainer-clean-am
       +maintainer-clean: maintainer-clean-recursive
        
        .PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
        maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
        mostlyclean-compile distclean-compile clean-compile \
       -maintainer-clean-compile tags mostlyclean-tags distclean-tags \
       -clean-tags maintainer-clean-tags distdir mostlyclean-depend \
       -distclean-depend clean-depend maintainer-clean-depend info-am info \
       -dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
       -install-exec install-data-local install-data-am install-data install-am \
       -install uninstall-am uninstall all-redirect all-am all installdirs \
       -mostlyclean-generic distclean-generic clean-generic \
       +maintainer-clean-compile install-data-recursive \
       +uninstall-data-recursive install-exec-recursive \
       +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
       +all-recursive check-recursive installcheck-recursive info-recursive \
       +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
       +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
       +distclean-tags clean-tags maintainer-clean-tags distdir \
       +mostlyclean-depend distclean-depend clean-depend \
       +maintainer-clean-depend info-am info dvi-am dvi check check-am \
       +installcheck-am installcheck install-exec-am install-exec \
       +install-data-local install-data-am install-data install-am install \
       +uninstall-am uninstall all-redirect all-am all installdirs-am \
       +installdirs mostlyclean-generic distclean-generic clean-generic \
        maintainer-clean-generic clean mostlyclean distclean maintainer-clean
        
        
 (DIR) diff --git a/src/curses_client.c b/src/curses_client.c
       t@@ -1,2425 +0,0 @@
       -/************************************************************************
       - * curses_client.c  dopewars client using the (n)curses console library *
       - * Copyright (C)  1998-2002  Ben Webb                                   *
       - *                Email: ben@bellatrix.pcl.ox.ac.uk                     *
       - *                WWW: http://dopewars.sourceforge.net/                 *
       - *                                                                      *
       - * This program is free software; you can redistribute it and/or        *
       - * modify it under the terms of the GNU General Public License          *
       - * as published by the Free Software Foundation; either version 2       *
       - * of the License, or (at your option) any later version.               *
       - *                                                                      *
       - * This program is distributed in the hope that it will be useful,      *
       - * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
       - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
       - * GNU General Public License for more details.                         *
       - *                                                                      *
       - * You should have received a copy of the GNU General Public License    *
       - * along with this program; if not, write to the Free Software          *
       - * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
       - *                   MA  02111-1307, USA.                               *
       - ************************************************************************/
       -
       -#ifdef HAVE_CONFIG_H
       -#include <config.h>
       -#endif
       -
       -#ifdef CURSES_CLIENT
       -
       -#include <string.h>
       -#include <stdlib.h>
       -#include <sys/types.h>
       -#ifdef HAVE_UNISTD_H
       -#include <unistd.h>
       -#endif
       -#include <ctype.h>
       -#include <signal.h>
       -#include <errno.h>
       -#include <glib.h>
       -#include "curses_client.h"
       -#include "dopeos.h"
       -#include "dopewars.h"
       -#include "message.h"
       -#include "nls.h"
       -#include "serverside.h"
       -#include "tstring.h"
       -
       -static void PrepareHighScoreScreen(void);
       -static void PrintHighScore(char *Data);
       -
       -static int ResizedFlag;
       -static SCREEN *cur_screen;
       -
       -#ifdef NETWORKING
       -static enum {
       -  CM_SERVER, CM_PROMPT, CM_META, CM_SINGLE
       -} ConnectMethod = CM_SERVER;
       -#endif
       -
       -static gboolean CanFire = FALSE, RunHere = FALSE;
       -static FightPoint fp;
       -
       -/* Function definitions; make them static so as not to clash with
       - * functions of the same name in different clients */
       -static void display_intro(void);
       -static void ResizeHandle(int sig);
       -static void CheckForResize(Player *Play);
       -static int GetKey(char *allowed, char *orig_allowed, gboolean AllowOther,
       -                  gboolean PrintAllowed, gboolean ExpandOut);
       -static void clear_bottom(void), clear_screen(void);
       -static void clear_line(int line), clear_exceptfor(int skip);
       -static void nice_wait(void);
       -static void DisplayFightMessage(Player *Play, char *text);
       -static void DisplaySpyReports(char *Data, Player *From, Player *To);
       -static void display_message(char *buf);
       -static void print_location(char *text);
       -static void print_status(Player *Play, gboolean DispDrug);
       -static char *nice_input(char *prompt, int sy, int sx, gboolean digitsonly,
       -                        char *displaystr, char passwdchar);
       -static Player *ListPlayers(Player *Play, gboolean Select, char *Prompt);
       -static void HandleClientMessage(char *buf, Player *Play);
       -static void PrintMessage(const gchar *text);
       -static void GunShop(Player *Play);
       -static void LoanShark(Player *Play);
       -static void Bank(Player *Play);
       -
       -#ifdef NETWORKING
       -static void HttpAuthFunc(HttpConnection *conn, gboolean proxyauth,
       -                         gchar *realm, gpointer data);
       -static void SocksAuthFunc(NetworkBuffer *netbuf, gpointer data);
       -#endif
       -
       -static DispMode DisplayMode;
       -static gboolean QuitRequest;
       -
       -/* 
       - * Initialises the curses library for accessing the screen.
       - */
       -static void start_curses(void)
       -{
       -  cur_screen = newterm(NULL, stdout, stdin);
       -  if (WantColour) {
       -    start_color();
       -    init_pair(1, COLOR_MAGENTA, COLOR_WHITE);
       -    init_pair(2, COLOR_BLACK, COLOR_WHITE);
       -    init_pair(3, COLOR_BLACK, COLOR_WHITE);
       -    init_pair(4, COLOR_BLUE, COLOR_WHITE);
       -    init_pair(5, COLOR_WHITE, COLOR_BLUE);
       -    init_pair(6, COLOR_RED, COLOR_WHITE);
       -  }
       -  cbreak();
       -  noecho();
       -  nodelay(stdscr, FALSE);
       -  keypad(stdscr, TRUE);
       -  curs_set(0);
       -}
       -
       -/* 
       - * Shuts down the curses screen library.
       - */
       -static void end_curses(void)
       -{
       -  keypad(stdscr, FALSE);
       -  curs_set(1);
       -  erase();
       -  refresh();
       -  endwin();
       -}
       -
       -/* 
       - * Handles a SIGWINCH signal, which is sent to indicate that the
       - * size of the curses screen has changed.
       - */
       -void ResizeHandle(int sig)
       -{
       -  ResizedFlag = 1;
       -}
       -
       -/* 
       - * Checks to see if the curses window needs to be resized - i.e. if a
       - * SIGWINCH signal has been received.
       - */
       -void CheckForResize(Player *Play)
       -{
       -  sigset_t sigset;
       -
       -  sigemptyset(&sigset);
       -  sigaddset(&sigset, SIGWINCH);
       -  sigprocmask(SIG_BLOCK, &sigset, NULL);
       -  if (ResizedFlag) {
       -    ResizedFlag = 0;
       -    end_curses();
       -    start_curses();
       -    Width = COLS;
       -    Depth = LINES;
       -    attrset(TextAttr);
       -    clear_screen();
       -    display_message("");
       -    DisplayFightMessage(Play, "");
       -    print_status(Play, TRUE);
       -  }
       -  sigprocmask(SIG_UNBLOCK, &sigset, NULL);
       -}
       -
       -static void LogMessage(const gchar *log_domain, GLogLevelFlags log_level,
       -                       const gchar *message, gpointer user_data)
       -{
       -  attrset(TextAttr);
       -  clear_bottom();
       -  PrintMessage(message);
       -  nice_wait();
       -  attrset(TextAttr);
       -  clear_bottom();
       -}
       -
       -/* 
       - * Displays a dopewars introduction screen.
       - */
       -void display_intro(void)
       -{
       -  GString *text;
       -
       -  attrset(TextAttr);
       -  clear_screen();
       -  attrset(TitleAttr);
       -
       -  /* Curses client introduction screen */
       -  text = g_string_new(_("D O P E W A R S"));
       -  mvaddstr(1, (Width - text->len) / 2, text->str);
       -
       -  attrset(TextAttr);
       -
       -  mvaddstr(3, 1, _("Based on John E. Dell's old Drug Wars game, dopewars "
       -                   "is a simulation of an"));
       -  mvaddstr(4, 1, _("imaginary drug market.  dopewars is an All-American "
       -                   "game which features"));
       -  mvaddstr(5, 1, _("buying, selling, and trying to get past the cops!"));
       -
       -  mvaddstr(7, 1, _("The first thing you need to do is pay off your "
       -                   "debt to the Loan Shark. After"));
       -  mvaddstr(8, 1, _("that, your goal is to make as much money as "
       -                   "possible (and stay alive)! You"));
       -  mvaddstr(9, 1, _("have one month of game time to make your fortune."));
       -
       -  mvaddstr(11, 18, _("Copyright (C) 1998-2002  Ben Webb "
       -                     "ben@bellatrix.pcl.ox.ac.uk"));
       -  g_string_sprintf(text, _("Version %s"), VERSION);
       -  mvaddstr(11, 2, text->str);
       -  g_string_assign(text, _("dopewars is released under the GNU "
       -                          "General Public Licence"));
       -  mvaddstr(12, (Width - text->len) / 2, text->str);
       -
       -  mvaddstr(14, 7, _("Icons and Graphics            Ocelot Mantis"));
       -  mvaddstr(15, 7, _("Drug Dealing and Research     Dan Wolf"));
       -  mvaddstr(16, 7, _("Play Testing                  Phil Davis           "
       -                    "Owen Walsh"));
       -  mvaddstr(17, 7, _("Extensive Play Testing        Katherine Holt       "
       -                    "Caroline Moore"));
       -  mvaddstr(18, 7, _("Constructive Criticism        Andrea Elliot-Smith  "
       -                    "Pete Winn"));
       -  mvaddstr(19, 7, _("Unconstructive Criticism      James Matthews"));
       -
       -  mvaddstr(21, 3, _("For information on the command line options, type "
       -                    "dopewars -h at your"));
       -  mvaddstr(22, 1,
       -           _("Unix prompt. This will display a help screen, listing "
       -             "the available options."));
       -
       -  g_string_free(text, TRUE);
       -  nice_wait();
       -  attrset(TextAttr);
       -  clear_screen();
       -  refresh();
       -}
       -
       -#ifdef NETWORKING
       -/* 
       - * Prompts the user to enter a server name and port to connect to.
       - */
       -static void SelectServerManually(void)
       -{
       -  gchar *text, *PortText;
       -
       -  if (ServerName[0] == '(')
       -    AssignName(&ServerName, "localhost");
       -  attrset(TextAttr);
       -  clear_bottom();
       -  mvaddstr(17, 1,
       -           /* Prompts for hostname and port when selecting a server
       -            * manually */
       -           _("Please enter the hostname and port of a dopewars server:-"));
       -  text = nice_input(_("Hostname: "), 18, 1, FALSE, ServerName, '\0');
       -  AssignName(&ServerName, text);
       -  g_free(text);
       -  PortText = g_strdup_printf("%d", Port);
       -  text = nice_input(_("Port: "), 19, 1, TRUE, PortText, '\0');
       -  Port = atoi(text);
       -  g_free(text);
       -  g_free(PortText);
       -}
       -
       -/* 
       - * Contacts the dopewars metaserver, and obtains a list of valid
       - * server/port pairs, one of which the user should select.
       - * Returns TRUE on success; on failure FALSE is returned, and
       - * errstr is assigned an error message.
       - */
       -static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr)
       -{
       -  int c;
       -  GSList *ListPt;
       -  ServerData *ThisServer;
       -  GString *text;
       -  gint index;
       -  fd_set readfds, writefds;
       -  int maxsock;
       -  gboolean DoneOK;
       -  HttpConnection *MetaConn;
       -
       -  attrset(TextAttr);
       -  clear_bottom();
       -  mvaddstr(17, 1, _("Please wait... attempting to contact metaserver..."));
       -  refresh();
       -
       -  if (OpenMetaHttpConnection(&MetaConn)) {
       -    SetHttpAuthFunc(MetaConn, HttpAuthFunc, NULL);
       -    SetNetworkBufferUserPasswdFunc(&MetaConn->NetBuf, SocksAuthFunc, NULL);
       -  } else {
       -    g_string_assign_error(errstr, MetaConn->NetBuf.error);
       -    CloseHttpConnection(MetaConn);
       -    return FALSE;
       -  }
       -
       -  ClearServerList(&ServerList);
       -
       -  do {
       -    FD_ZERO(&readfds);
       -    FD_ZERO(&writefds);
       -    FD_SET(0, &readfds);
       -    maxsock = 1;
       -    SetSelectForNetworkBuffer(&MetaConn->NetBuf, &readfds, &writefds,
       -                              NULL, &maxsock);
       -    if (bselect(maxsock, &readfds, &writefds, NULL, NULL) == -1) {
       -      if (errno == EINTR) {
       -        CheckForResize(Play);
       -        continue;
       -      }
       -      perror("bselect");
       -      exit(1);
       -    }
       -    if (FD_ISSET(0, &readfds)) {
       -      /* So that Ctrl-L works */
       -      c = getch();
       -#ifndef CYGWIN
       -      if (c == '\f')
       -        wrefresh(curscr);
       -#endif
       -    }
       -    if (RespondToSelect
       -        (&MetaConn->NetBuf, &readfds, &writefds, NULL, &DoneOK)) {
       -      while (HandleWaitingMetaServerData(MetaConn, &ServerList, &DoneOK)) {
       -      }
       -    }
       -    if (!DoneOK && HandleHttpCompletion(MetaConn)) {
       -      if (IsHttpError(MetaConn)) {
       -        g_string_assign_error(errstr, MetaConn->NetBuf.error);
       -        CloseHttpConnection(MetaConn);
       -        return FALSE;
       -      }
       -    }
       -  } while (DoneOK);
       -  CloseHttpConnection(MetaConn);
       -
       -  text = g_string_new("");
       -
       -  ListPt = ServerList;
       -  while (ListPt) {
       -    ThisServer = (ServerData *)(ListPt->data);
       -    attrset(TextAttr);
       -    clear_bottom();
       -    /* Printout of metaserver information in curses client */
       -    g_string_sprintf(text, _("Server : %s"), ThisServer->Name);
       -    mvaddstr(17, 1, text->str);
       -    g_string_sprintf(text, _("Port   : %d"), ThisServer->Port);
       -    mvaddstr(18, 1, text->str);
       -    g_string_sprintf(text, _("Version    : %s"), ThisServer->Version);
       -    mvaddstr(18, 40, text->str);
       -    if (ThisServer->CurPlayers == -1) {
       -      g_string_sprintf(text, _("Players: -unknown- (maximum %d)"),
       -                       ThisServer->MaxPlayers);
       -    } else {
       -      g_string_sprintf(text, _("Players: %d (maximum %d)"),
       -                       ThisServer->CurPlayers, ThisServer->MaxPlayers);
       -    }
       -    mvaddstr(19, 1, text->str);
       -    g_string_sprintf(text, _("Up since   : %s"), ThisServer->UpSince);
       -    mvaddstr(19, 40, text->str);
       -    g_string_sprintf(text, _("Comment: %s"), ThisServer->Comment);
       -    mvaddstr(20, 1, text->str);
       -    attrset(PromptAttr);
       -    mvaddstr(23, 1,
       -             _("N>ext server; P>revious server; S>elect this server... "));
       -
       -    /* The three keys that are valid responses to the previous question -
       -     * if you translate them, keep the keys in the same order (N>ext,
       -     * P>revious, S>elect) as they are here, otherwise they'll do the
       -     * wrong things. */
       -    c = GetKey(_("NPS"), "NPS", FALSE, FALSE, FALSE);
       -    switch (c) {
       -    case 'S':
       -      AssignName(&ServerName, ThisServer->Name);
       -      Port = ThisServer->Port;
       -      ListPt = NULL;
       -      break;
       -    case 'N':
       -      ListPt = g_slist_next(ListPt);
       -      if (!ListPt)
       -        ListPt = ServerList;
       -      break;
       -    case 'P':
       -      index = g_slist_position(ServerList, ListPt) - 1;
       -      if (index >= 0)
       -        ListPt = g_slist_nth(ServerList, (guint)index);
       -      else
       -        ListPt = g_slist_last(ListPt);
       -      break;
       -    }
       -  }
       -  if (!ServerList) {
       -    g_string_assign(errstr, "No servers listed on metaserver");
       -    return FALSE;
       -  }
       -  clear_line(17);
       -  refresh();
       -  g_string_free(text, TRUE);
       -  return TRUE;
       -}
       -
       -static void DisplayConnectStatus(NetworkBuffer *netbuf,
       -                                 NBStatus oldstatus,
       -                                 NBSocksStatus oldsocks)
       -{
       -  NBStatus status;
       -  NBSocksStatus sockstat;
       -  GString *text;
       -
       -  status = netbuf->status;
       -  sockstat = netbuf->sockstat;
       -
       -  if (oldstatus == status && oldsocks == sockstat)
       -    return;
       -
       -  text = g_string_new("");
       -
       -  switch (status) {
       -  case NBS_PRECONNECT:
       -    break;
       -  case NBS_SOCKSCONNECT:
       -    switch (sockstat) {
       -    case NBSS_METHODS:
       -      g_string_sprintf(text, _("Connected to SOCKS server %s..."),
       -                       Socks.name);
       -      break;
       -    case NBSS_USERPASSWD:
       -      g_string_assign(text, _("Authenticating with SOCKS server"));
       -      break;
       -    case NBSS_CONNECT:
       -      g_string_sprintf(text, _("Asking SOCKS for connect to %s..."),
       -                       ServerName);
       -      break;
       -    }
       -    break;
       -  case NBS_CONNECTED:
       -    break;
       -  }
       -  if (text->str[0]) {
       -    mvaddstr(17, 1, text->str);
       -    refresh();
       -  }
       -  g_string_free(text, TRUE);
       -}
       -
       -void HttpAuthFunc(HttpConnection *conn, gboolean proxyauth,
       -                  gchar *realm, gpointer data)
       -{
       -  gchar *text, *user, *password = NULL;
       -
       -  attrset(TextAttr);
       -  clear_bottom();
       -  if (proxyauth) {
       -    text = g_strdup_printf(_("Proxy authentication required for realm %s"),
       -                           realm);
       -  } else {
       -    text =
       -        g_strdup_printf(_("Authentication required for realm %s"), realm);
       -  }
       -  mvaddstr(17, 1, text);
       -  mvaddstr(18, 1, _("(Enter a blank username to cancel)"));
       -  g_free(text);
       -
       -  user = nice_input(_("User name: "), 19, 1, FALSE, NULL, '\0');
       -  if (user && user[0]) {
       -    password = nice_input(_("Password: "), 20, 1, FALSE, NULL, '*');
       -  }
       -
       -  SetHttpAuthentication(conn, proxyauth, user, password);
       -  g_free(user);
       -  g_free(password);
       -}
       -
       -void SocksAuthFunc(NetworkBuffer *netbuf, gpointer data)
       -{
       -  gchar *user, *password = NULL;
       -
       -  attrset(TextAttr);
       -  clear_bottom();
       -  mvaddstr(17, 1, _("SOCKS authentication required (enter a blank "
       -                    "username to cancel)"));
       -
       -  user = nice_input(_("User name: "), 18, 1, FALSE, NULL, '\0');
       -  if (user && user[0]) {
       -    password = nice_input(_("Password: "), 19, 1, FALSE, NULL, '*');
       -  }
       -
       -  SendSocks5UserPasswd(netbuf, user, password);
       -  g_free(user);
       -  g_free(password);
       -}
       -
       -static gboolean DoConnect(Player *Play, GString *errstr)
       -{
       -  NetworkBuffer *netbuf;
       -  fd_set readfds, writefds;
       -  int maxsock, c;
       -  gboolean doneOK = TRUE;
       -  NBStatus oldstatus;
       -  NBSocksStatus oldsocks;
       -
       -  netbuf = &Play->NetBuf;
       -  oldstatus = netbuf->status;
       -  oldsocks = netbuf->sockstat;
       -
       -  if (!StartNetworkBufferConnect(netbuf, ServerName, Port)) {
       -    doneOK = FALSE;
       -  } else {
       -    SetNetworkBufferUserPasswdFunc(netbuf, SocksAuthFunc, NULL);
       -    while (netbuf->status != NBS_CONNECTED) {
       -      DisplayConnectStatus(netbuf, oldstatus, oldsocks);
       -      oldstatus = netbuf->status;
       -      oldsocks = netbuf->sockstat;
       -      FD_ZERO(&readfds);
       -      FD_ZERO(&writefds);
       -      FD_SET(0, &readfds);
       -      maxsock = 1;
       -      SetSelectForNetworkBuffer(netbuf, &readfds, &writefds, NULL,
       -                                &maxsock);
       -      if (bselect(maxsock, &readfds, &writefds, NULL, NULL) == -1) {
       -        if (errno == EINTR) {
       -          CheckForResize(Play);
       -          continue;
       -        }
       -        perror("bselect");
       -        exit(1);
       -      }
       -      if (FD_ISSET(0, &readfds)) {
       -        /* So that Ctrl-L works */
       -        c = getch();
       -#ifndef CYGWIN
       -        if (c == '\f')
       -          wrefresh(curscr);
       -#endif
       -      }
       -      RespondToSelect(netbuf, &readfds, &writefds, NULL, &doneOK);
       -    }
       -  }
       -
       -  if (!doneOK)
       -    g_string_assign_error(errstr, netbuf->error);
       -  return doneOK;
       -}
       -
       -/* 
       - * Connects to a dopewars server. Prompts the user to select a server
       - * if necessary. Returns TRUE, unless the user elected to quit the
       - * program rather than choose a valid server.
       - */
       -static gboolean ConnectToServer(Player *Play)
       -{
       -  gboolean MetaOK = TRUE, NetOK = TRUE, firstrun = FALSE;
       -  GString *errstr;
       -  gchar *text;
       -  int c;
       -
       -  errstr = g_string_new("");
       -
       -  if (g_strcasecmp(ServerName, SN_META) == 0 || ConnectMethod == CM_META) {
       -    ConnectMethod = CM_META;
       -    MetaOK = SelectServerFromMetaServer(Play, errstr);
       -  } else if (g_strcasecmp(ServerName, SN_PROMPT) == 0 ||
       -             ConnectMethod == CM_PROMPT) {
       -    ConnectMethod = CM_PROMPT;
       -    SelectServerManually();
       -  } else if (g_strcasecmp(ServerName, SN_SINGLE) == 0 ||
       -             ConnectMethod == CM_SINGLE) {
       -    ConnectMethod = CM_SINGLE;
       -    g_string_free(errstr, TRUE);
       -    return TRUE;
       -  } else
       -    firstrun = TRUE;
       -
       -  while (1) {
       -    attrset(TextAttr);
       -    clear_bottom();
       -    if (MetaOK && !firstrun) {
       -      mvaddstr(17, 1, _("Please wait... attempting to contact "
       -                        "dopewars server..."));
       -      refresh();
       -      NetOK = DoConnect(Play, errstr);
       -    }
       -    if (!NetOK || !MetaOK || firstrun) {
       -      firstrun = FALSE;
       -      clear_line(16);
       -      clear_line(17);
       -      if (!MetaOK) {
       -        /* Display of an error while contacting the metaserver */
       -        mvaddstr(16, 1, _("Cannot get metaserver details"));
       -        text = g_strdup_printf("   (%s)", errstr->str);
       -        mvaddstr(17, 1, text);
       -        g_free(text);
       -      } else if (!NetOK) {
       -        /* Display of an error message while trying to contact a dopewars
       -         * server (the error message itself is displayed on the next
       -         * screen line) */
       -        mvaddstr(16, 1, _("Could not start multiplayer dopewars"));
       -        text = g_strdup_printf("   (%s)", errstr->str);
       -        mvaddstr(17, 1, text);
       -        g_free(text);
       -      }
       -      MetaOK = NetOK = TRUE;
       -      attrset(PromptAttr);
       -      mvaddstr(18, 1,
       -               _("Will you... C>onnect to a named dopewars server"));
       -      mvaddstr(19, 1,
       -               _("            L>ist the servers on the metaserver, and "
       -                 "select one"));
       -      mvaddstr(20, 1,
       -               _("            Q>uit (where you can start a server "
       -                 "by typing \"dopewars -s\")"));
       -      mvaddstr(21, 1, _("         or P>lay single-player ? "));
       -      attrset(TextAttr);
       -
       -      /* Translate these 4 keys in line with the above options, keeping
       -       * the order the same (C>onnect, L>ist, Q>uit, P>lay single-player) */
       -      c = GetKey(_("CLQP"), "CLQP", FALSE, FALSE, FALSE);
       -      switch (c) {
       -      case 'Q':
       -        g_string_free(errstr, TRUE);
       -        return FALSE;
       -      case 'P':
       -        g_string_free(errstr, TRUE);
       -        return TRUE;
       -      case 'L':
       -        MetaOK = SelectServerFromMetaServer(Play, errstr);
       -        break;
       -      case 'C':
       -        SelectServerManually();
       -        break;
       -      }
       -    } else
       -      break;
       -  }
       -  g_string_free(errstr, TRUE);
       -  Client = Network = TRUE;
       -  return TRUE;
       -}
       -#endif /* NETWORKING */
       -
       -/* 
       - * Displays the list of locations and prompts the user to select one.
       - * If "AllowReturn" is TRUE, then if the current location is selected
       - * simply drop back to the main game loop, otherwise send a request
       - * to the server to move to the new location. If FALSE, the user MUST
       - * choose a new location to move to. The active client player is
       - * passed in "Play".
       - * N.B. May set the global variable DisplayMode.
       - * Returns: TRUE if the user chose to jet to a new location,
       - *          FALSE if the action was cancelled instead.
       - */
       -static gboolean jet(Player *Play, gboolean AllowReturn)
       -{
       -  int i, c;
       -  char text[80];
       -
       -  attrset(TextAttr);
       -  clear_bottom();
       -  for (i = 0; i < NumLocation; i++) {
       -    sprintf(text, "%d. %s", i + 1, Location[i].Name);
       -    mvaddstr(17 + i / 3, (i % 3) * 20 + 12, text);
       -  }
       -  attrset(PromptAttr);
       -
       -  /* Prompt when the player chooses to "jet" to a new location */
       -  mvaddstr(22, 22, _("Where to, dude ? "));
       -  attrset(TextAttr);
       -  curs_set(1);
       -  do {
       -    c = bgetch();
       -    if (c >= '1' && c < '1' + NumLocation) {
       -      addstr(Location[c - '1'].Name);
       -      if (Play->IsAt != c - '1') {
       -        sprintf(text, "%d", c - '1');
       -        DisplayMode = DM_NONE;
       -        SendClientMessage(Play, C_NONE, C_REQUESTJET, NULL, text);
       -      } else
       -        c = 0;
       -    } else
       -      c = 0;
       -  } while (c == 0 && !AllowReturn);
       -
       -  curs_set(0);
       -  return (c != 0);
       -}
       -
       -/* 
       - * Prompts the user "Play" to drop some of the currently carried drugs.
       - */
       -static void DropDrugs(Player *Play)
       -{
       -  int i, c, num, NumDrugs;
       -  GString *text;
       -  gchar *buf;
       -
       -  attrset(TextAttr);
       -  clear_bottom();
       -  text = g_string_new("");
       -  dpg_string_sprintf(text,
       -                     /* List of drugs that you can drop (%tde = "drugs" by 
       -                      * default) */
       -                     _("You can\'t get any cash for the following "
       -                       "carried %tde :"), Names.Drugs);
       -  mvaddstr(16, 1, text->str);
       -  NumDrugs = 0;
       -  for (i = 0; i < NumDrug; i++) {
       -    if (Play->Drugs[i].Carried > 0 && Play->Drugs[i].Price == 0) {
       -      g_string_sprintf(text, "%c. %-10s %-8d", NumDrugs + 'A',
       -                       Drug[i].Name, Play->Drugs[i].Carried);
       -      mvaddstr(17 + NumDrugs / 3, (NumDrugs % 3) * 25 + 4, text->str);
       -      NumDrugs++;
       -    }
       -  }
       -  attrset(PromptAttr);
       -  mvaddstr(22, 20, _("What do you want to drop? "));
       -  curs_set(1);
       -  attrset(TextAttr);
       -  c = bgetch();
       -  c = toupper(c);
       -  for (i = 0; c >= 'A' && c < 'A' + NumDrugs && i < NumDrug; i++) {
       -    if (Play->Drugs[i].Carried > 0 && Play->Drugs[i].Price == 0) {
       -      c--;
       -      if (c < 'A') {
       -        addstr(Drug[i].Name);
       -        buf =
       -            nice_input(_("How many do you drop? "), 23, 8, TRUE, NULL,
       -                       '\0');
       -        num = atoi(buf);
       -        g_free(buf);
       -        if (num > 0) {
       -          g_string_sprintf(text, "drug^%d^%d", i, -num);
       -          SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text->str);
       -        }
       -      }
       -    }
       -  }
       -  g_string_free(text, TRUE);
       -}
       -
       -/* 
       - * Prompts the user (i.e. the owner of client "Play") to buy drugs if
       - * "Buy" is TRUE, or to sell drugs otherwise. A list of available drugs
       - * is displayed, and on receiving the selection, the user is prompted
       - * for the number of drugs desired. Finally a message is sent to the
       - * server to buy or sell the required quantity.
       - */
       -static void DealDrugs(Player *Play, gboolean Buy)
       -{
       -  int i, c, NumDrugsHere;
       -  gchar *text, *input;
       -  int DrugNum, CanCarry, CanAfford;
       -
       -  NumDrugsHere = 0;
       -  for (c = 0; c < NumDrug; c++)
       -    if (Play->Drugs[c].Price > 0)
       -      NumDrugsHere++;
       -
       -  clear_line(22);
       -  attrset(PromptAttr);
       -  if (Buy) {
       -    /* Buy and sell prompts for dealing drugs or guns */
       -    mvaddstr(22, 20, _("What do you wish to buy? "));
       -  } else {
       -    mvaddstr(22, 20, _("What do you wish to sell? "));
       -  }
       -  curs_set(1);
       -  attrset(TextAttr);
       -  c = bgetch();
       -  c = toupper(c);
       -  if (c >= 'A' && c < 'A' + NumDrugsHere) {
       -    DrugNum = -1;
       -    c -= 'A';
       -    for (i = 0; i <= c; i++)
       -      DrugNum = GetNextDrugIndex(DrugNum, Play);
       -    addstr(Drug[DrugNum].Name);
       -    CanCarry = Play->CoatSize;
       -    CanAfford = Play->Cash / Play->Drugs[DrugNum].Price;
       -
       -    if (Buy) {
       -      /* Display of number of drugs you could buy and/or carry, when
       -       * buying drugs */
       -      text = g_strdup_printf(_("You can afford %d, and can carry %d. "),
       -                             CanAfford, CanCarry);
       -      mvaddstr(23, 2, text);
       -      input = nice_input(_("How many do you buy? "), 23, 2 + strlen(text),
       -                         TRUE, NULL, '\0');
       -      c = atoi(input);
       -      g_free(input);
       -      g_free(text);
       -      if (c >= 0) {
       -        text = g_strdup_printf("drug^%d^%d", DrugNum, c);
       -        SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text);
       -        g_free(text);
       -      }
       -    } else {
       -      /* Display of number of drugs you have, when selling drugs */
       -      text =
       -          g_strdup_printf(_("You have %d. "),
       -                          Play->Drugs[DrugNum].Carried);
       -      mvaddstr(23, 2, text);
       -      input = nice_input(_("How many do you sell? "), 23, 2 + strlen(text),
       -                         TRUE, NULL, '\0');
       -      c = atoi(input);
       -      g_free(input);
       -      g_free(text);
       -      if (c >= 0) {
       -        text = g_strdup_printf("drug^%d^%d", DrugNum, -c);
       -        SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text);
       -        g_free(text);
       -      }
       -    }
       -  }
       -  curs_set(0);
       -}
       -
       -/* 
       - * Prompts the user (player "Play") to give an errand to one of his/her
       - * bitches. The decision is relayed to the server for implementation.
       - */
       -static void GiveErrand(Player *Play)
       -{
       -  int c, y;
       -  GString *text;
       -  Player *To;
       -
       -  text = g_string_new("");
       -  attrset(TextAttr);
       -  clear_bottom();
       -  y = 17;
       -
       -  /* Prompt for sending your bitches out to spy etc. (%tde = "bitches" by
       -   * default) */
       -  dpg_string_sprintf(text,
       -                     _("Choose an errand to give one of your %tde..."),
       -                     Names.Bitches);
       -  mvaddstr(y++, 1, text->str);
       -  attrset(PromptAttr);
       -  if (Play->Bitches.Carried > 0) {
       -    dpg_string_sprintf(text,
       -                       _("   S>py on another dealer                  "
       -                         "(cost: %P)"), Prices.Spy);
       -    mvaddstr(y++, 2, text->str);
       -    dpg_string_sprintf(text,
       -                       _("   T>ip off the cops to another dealer     "
       -                         "(cost: %P)"), Prices.Tipoff);
       -    mvaddstr(y++, 2, text->str);
       -    mvaddstr(y++, 2, _("   G>et stuffed"));
       -  }
       -  if (Play->Flags & SPYINGON) {
       -    mvaddstr(y++, 2, _("or C>ontact your spies and receive reports"));
       -  }
       -  mvaddstr(y++, 2, _("or N>o errand ? "));
       -  curs_set(1);
       -  attrset(TextAttr);
       -
       -  /* Translate these 5 keys to match the above options, keeping the
       -   * original order the same (S>py, T>ip off, G>et stuffed, C>ontact spy,
       -   * N>o errand) */
       -  c = GetKey(_("STGCN"), "STGCN", TRUE, FALSE, FALSE);
       -
       -  if (Play->Bitches.Carried > 0 || c == 'C')
       -    switch (c) {
       -    case 'S':
       -      To = ListPlayers(Play, TRUE, _("Whom do you want to spy on? "));
       -      if (To)
       -        SendClientMessage(Play, C_NONE, C_SPYON, To, NULL);
       -      break;
       -    case 'T':
       -      To = ListPlayers(Play, TRUE,
       -                       _("Whom do you want to tip the cops off to? "));
       -      if (To)
       -        SendClientMessage(Play, C_NONE, C_TIPOFF, To, NULL);
       -      break;
       -    case 'G':
       -      attrset(PromptAttr);
       -      /* Prompt for confirmation of sacking a bitch */
       -      addstr(_(" Are you sure? "));
       -
       -      /* The two keys that are valid for answering Yes/No - if you
       -       * translate them, keep them in the same order - i.e. "Yes" before
       -       * "No" */
       -      c = GetKey(_("YN"), "YN", FALSE, TRUE, FALSE);
       -
       -      if (c == 'Y')
       -        SendClientMessage(Play, C_NONE, C_SACKBITCH, NULL, NULL);
       -      break;
       -    case 'C':
       -      if (Play->Flags & SPYINGON) {
       -        SendClientMessage(Play, C_NONE, C_CONTACTSPY, NULL, NULL);
       -      }
       -      break;
       -    }
       -}
       -
       -/* 
       - * Asks the user if he/she _really_ wants to quit dopewars.
       - */
       -static int want_to_quit(void)
       -{
       -  attrset(TextAttr);
       -  clear_line(22);
       -  attrset(PromptAttr);
       -  mvaddstr(22, 1, _("Are you sure you want to quit? "));
       -  attrset(TextAttr);
       -  return (GetKey(_("YN"), "YN", FALSE, TRUE, FALSE) != 'N');
       -}
       -
       -/* 
       - * Prompts the user to change his or her name, and notifies the server.
       - */
       -static void change_name(Player *Play, gboolean nullname)
       -{
       -  gchar *NewName;
       -
       -  /* Prompt for player to change his/her name */
       -  NewName = nice_input(_("New name: "), 23, 0, FALSE, NULL, '\0');
       -
       -  if (NewName[0]) {
       -    if (nullname) {
       -      SendNullClientMessage(Play, C_NONE, C_NAME, NULL, NewName);
       -    } else {
       -      SendClientMessage(Play, C_NONE, C_NAME, NULL, NewName);
       -    }
       -    SetPlayerName(Play, NewName);
       -  }
       -  g_free(NewName);
       -}
       -
       -/* 
       - * Given a message "Message" coming in for player "Play", performs
       - * processing and reacts properly; if a message indicates the end of the
       - * game, the global variable QuitRequest is set. The global variable
       - * DisplayMode may also be changed by this routine as a result of network
       - * traffic.
       - */
       -void HandleClientMessage(char *Message, Player *Play)
       -{
       -  char *pt, *Data, *wrd;
       -  AICode AI;
       -  MsgCode Code;
       -  Player *From, *tmp;
       -  GSList *list;
       -  gchar *text;
       -  int i;
       -  gboolean Handled;
       -
       -  /* Ignore To: field - all messages will be for Player "Play" */
       -  if (ProcessMessage(Message, Play, &From, &AI, &Code, &Data, FirstClient)
       -      == -1) {
       -    return;
       -  }
       -
       -  Handled =
       -      HandleGenericClientMessage(From, AI, Code, Play, Data, &DisplayMode);
       -  switch (Code) {
       -  case C_ENDLIST:
       -    if (FirstClient && g_slist_next(FirstClient)) {
       -      ListPlayers(Play, FALSE, NULL);
       -    }
       -    break;
       -  case C_STARTHISCORE:
       -    PrepareHighScoreScreen();
       -    break;
       -  case C_HISCORE:
       -    PrintHighScore(Data);
       -    break;
       -  case C_ENDHISCORE:
       -    if (strcmp(Data, "end") == 0) {
       -      QuitRequest = TRUE;
       -    } else {
       -      nice_wait();
       -      clear_screen();
       -      display_message("");
       -      print_status(Play, TRUE);
       -      refresh();
       -    }
       -    break;
       -  case C_PUSH:
       -    attrset(TextAttr);
       -    clear_line(22);
       -    mvaddstr(22, 0, _("You have been pushed from the server. "
       -                      "Reverting to single player mode."));
       -    nice_wait();
       -    SwitchToSinglePlayer(Play);
       -    print_status(Play, TRUE);
       -    break;
       -  case C_QUIT:
       -    attrset(TextAttr);
       -    clear_line(22);
       -    mvaddstr(22, 0,
       -             _("The server has terminated. Reverting to "
       -               "single player mode."));
       -    nice_wait();
       -    SwitchToSinglePlayer(Play);
       -    print_status(Play, TRUE);
       -    break;
       -  case C_MSG:
       -    text = g_strdup_printf("%s: %s", GetPlayerName(From), Data);
       -    display_message(text);
       -    g_free(text);
       -    break;
       -  case C_MSGTO:
       -    text = g_strdup_printf("%s->%s: %s", GetPlayerName(From),
       -                           GetPlayerName(Play), Data);
       -    display_message(text);
       -    g_free(text);
       -    break;
       -  case C_JOIN:
       -    text = g_strdup_printf(_("%s joins the game!"), Data);
       -    display_message(text);
       -    g_free(text);
       -    break;
       -  case C_LEAVE:
       -    if (From != &Noone) {
       -      text = g_strdup_printf(_("%s has left the game."), Data);
       -      display_message(text);
       -      g_free(text);
       -    }
       -    break;
       -  case C_RENAME:
       -    /* Displayed when a player changes his/her name */
       -    text = g_strdup_printf(_("%s will now be known as %s."),
       -                           GetPlayerName(From), Data);
       -    SetPlayerName(From, Data);
       -    mvaddstr(22, 0, text);
       -    g_free(text);
       -    nice_wait();
       -    break;
       -  case C_PRINTMESSAGE:
       -    PrintMessage(Data);
       -    nice_wait();
       -    break;
       -  case C_FIGHTPRINT:
       -    DisplayFightMessage(Play, Data);
       -    break;
       -  case C_SUBWAYFLASH:
       -    DisplayFightMessage(Play, NULL);
       -    for (list = FirstClient; list; list = g_slist_next(list)) {
       -      tmp = (Player *)list->data;
       -      tmp->Flags &= ~FIGHTING;
       -    }
       -    for (i = 0; i < 4; i++) {
       -      print_location(_("S U B W A Y"));
       -      refresh();
       -      MicroSleep(100000);
       -      print_location("");
       -      refresh();
       -      MicroSleep(100000);
       -    }
       -    print_location(Location[(int)Play->IsAt].Name);
       -    break;
       -  case C_QUESTION:
       -    pt = Data;
       -    wrd = GetNextWord(&pt, "");
       -    PrintMessage(pt);
       -    addch(' ');
       -    i = GetKey(_(wrd), wrd, FALSE, TRUE, TRUE);
       -    wrd = g_strdup_printf("%c", i);
       -    SendClientMessage(Play, C_NONE, C_ANSWER,
       -                      From == &Noone ? NULL : From, wrd);
       -    g_free(wrd);
       -    break;
       -  case C_LOANSHARK:
       -    LoanShark(Play);
       -    SendClientMessage(Play, C_NONE, C_DONE, NULL, NULL);
       -    break;
       -  case C_BANK:
       -    Bank(Play);
       -    SendClientMessage(Play, C_NONE, C_DONE, NULL, NULL);
       -    break;
       -  case C_GUNSHOP:
       -    GunShop(Play);
       -    SendClientMessage(Play, C_NONE, C_DONE, NULL, NULL);
       -    break;
       -  case C_UPDATE:
       -    if (From == &Noone) {
       -      ReceivePlayerData(Play, Data, Play);
       -      print_status(Play, TRUE);
       -      refresh();
       -    } else {
       -      DisplaySpyReports(Data, From, Play);
       -    }
       -    break;
       -  case C_NEWNAME:
       -    clear_line(22);
       -    clear_line(23);
       -    attrset(TextAttr);
       -    mvaddstr(22, 0, _("Unfortunately, somebody else is already "
       -                      "using \"your\" name. Please change it."));
       -    change_name(Play, TRUE);
       -    break;
       -  default:
       -    if (!Handled) {
       -      text = g_strdup_printf("%s^%c^%s^%s", GetPlayerName(From), Code,
       -                             GetPlayerName(Play), Data);
       -      mvaddstr(22, 0, text);
       -      g_free(text);
       -      nice_wait();
       -    }
       -    break;
       -  }
       -}
       -
       -/* 
       - * Responds to a "starthiscore" message by clearing the screen and
       - * displaying the title for the high scores screen.
       - */
       -void PrepareHighScoreScreen(void)
       -{
       -  char *text;
       -
       -  attrset(TextAttr);
       -  clear_screen();
       -  attrset(TitleAttr);
       -  text = _("H I G H   S C O R E S");
       -  mvaddstr(0, (Width - strlen(text)) / 2, text);
       -  attrset(TextAttr);
       -}
       -
       -/* 
       - * Prints a high score coded in "Data"; first word is the index of the
       - * score (i.e. y screen coordinate), second word is the text, the first
       - * letter of which identifies whether it's to be printed bold or not.
       - */
       -void PrintHighScore(char *Data)
       -{
       -  char *cp;
       -  int index;
       -
       -  cp = Data;
       -  index = GetNextInt(&cp, 0);
       -  if (!cp || strlen(cp) < 2)
       -    return;
       -  move(index + 2, 0);
       -  attrset(TextAttr);
       -  if (cp[0] == 'B')
       -    standout();
       -  addstr(&cp[1]);
       -  if (cp[0] == 'B')
       -    standend();
       -}
       -
       -/* 
       - * Prints a message "text" received via. a "printmessage" message in the
       - * bottom part of the screen.
       - */
       -void PrintMessage(const gchar *text)
       -{
       -  guint i, line;
       -
       -  attrset(TextAttr);
       -  clear_line(16);
       -
       -  line = 1;
       -  for (i = 0; i < strlen(text) && (text[i] == '^' || text[i] == '\n'); i++)
       -    line++;
       -  clear_exceptfor(line);
       -
       -  line = 17;
       -  move(line, 1);
       -  for (i = 0; i < strlen(text); i++) {
       -    if (text[i] == '^' || text[i] == '\n') {
       -      line++;
       -      move(line, 1);
       -    } else if (text[i] != '\r')
       -      addch((guchar)text[i]);
       -  }
       -}
       -
       -static void SellGun(Player *Play)
       -{
       -  gchar *text;
       -  gint gunind;
       -
       -  clear_line(22);
       -  if (TotalGunsCarried(Play) == 0) {
       -    /* Error - player tried to sell guns that he/she doesn't have
       -     * (%tde="guns" by default) */
       -    text = dpg_strdup_printf(_("You don't have any %tde to sell!"),
       -                             Names.Guns);
       -    mvaddstr(22, (Width - strlen(text)) / 2, text);
       -    g_free(text);
       -    nice_wait();
       -    clear_line(23);
       -  } else {
       -    attrset(PromptAttr);
       -    mvaddstr(22, 20, _("What do you wish to sell? "));
       -    curs_set(1);
       -    attrset(TextAttr);
       -    gunind = bgetch();
       -    gunind = toupper(gunind);
       -    if (gunind >= 'A' && gunind < 'A' + NumGun) {
       -      gunind -= 'A';
       -      addstr(Gun[gunind].Name);
       -      if (Play->Guns[gunind].Carried == 0) {
       -        clear_line(22);
       -        /* Error - player tried to sell some guns that he/she doesn't have */
       -        mvaddstr(22, 10, _("You don't have any to sell!"));
       -        nice_wait();
       -        clear_line(23);
       -      } else {
       -        Play->Cash += Gun[gunind].Price;
       -        Play->CoatSize += Gun[gunind].Space;
       -        Play->Guns[gunind].Carried--;
       -        text = g_strdup_printf("gun^%d^-1", gunind);
       -        SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text);
       -        g_free(text);
       -        print_status(Play, FALSE);
       -      }
       -    }
       -  }
       -}
       -
       -static void BuyGun(Player *Play)
       -{
       -  gchar *text;
       -  gint gunind;
       -
       -  clear_line(22);
       -  if (TotalGunsCarried(Play) >= Play->Bitches.Carried + 2) {
       -    text = dpg_strdup_printf(
       -                              /* Error - player tried to buy more guns
       -                               * than his/her bitches can carry (1st
       -                               * %tde="bitches", 2nd %tde="guns" by
       -                               * default) */
       -                              _("You'll need more %tde to carry "
       -                                "any more %tde!"),
       -                              Names.Bitches, Names.Guns);
       -    mvaddstr(22, (Width - strlen(text)) / 2, text);
       -    g_free(text);
       -    nice_wait();
       -    clear_line(23);
       -  } else {
       -    attrset(PromptAttr);
       -    mvaddstr(22, 20, _("What do you wish to buy? "));
       -    curs_set(1);
       -    attrset(TextAttr);
       -    gunind = bgetch();
       -    gunind = toupper(gunind);
       -    if (gunind >= 'A' && gunind < 'A' + NumGun) {
       -      gunind -= 'A';
       -      addstr(Gun[gunind].Name);
       -      if (Gun[gunind].Space > Play->CoatSize) {
       -        clear_line(22);
       -        /* Error - player tried to buy a gun that he/she doesn't have
       -         * space for (%tde="gun" by default) */
       -        text = dpg_strdup_printf(_("You don't have enough space to "
       -                                   "carry that %tde!"), Names.Gun);
       -        mvaddstr(22, (Width - strlen(text)) / 2, text);
       -        g_free(text);
       -        nice_wait();
       -        clear_line(23);
       -      } else if (Gun[gunind].Price > Play->Cash) {
       -        clear_line(22);
       -        /* Error - player tried to buy a gun that he/she can't afford
       -         * (%tde="gun" by default) */
       -        text = dpg_strdup_printf(_("You don't have enough cash to buy "
       -                                   "that %tde!"), Names.Gun);
       -        mvaddstr(22, (Width - strlen(text)) / 2, text);
       -        g_free(text);
       -        nice_wait();
       -        clear_line(23);
       -      } else {
       -        Play->Cash -= Gun[gunind].Price;
       -        Play->CoatSize -= Gun[gunind].Space;
       -        Play->Guns[gunind].Carried++;
       -        text = g_strdup_printf("gun^%d^1", gunind);
       -        SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text);
       -        g_free(text);
       -        print_status(Play, FALSE);
       -      }
       -    }
       -  }
       -}
       -
       -/* 
       - * Allows player "Play" to buy and sell guns interactively. Passes the
       - * decisions on to the server for sanity checking and implementation.
       - */
       -void GunShop(Player *Play)
       -{
       -  int i, action;
       -  gchar *text;
       -
       -  print_status(Play, FALSE);
       -  attrset(TextAttr);
       -  clear_bottom();
       -  for (i = 0; i < NumGun; i++) {
       -    text =
       -        dpg_strdup_printf("%c. %-22tde %12P", 'A' + i, Gun[i].Name,
       -                          Gun[i].Price);
       -    mvaddstr(17 + i / 2, (i % 2) * 40 + 1, text);
       -    g_free(text);
       -  }
       -  do {
       -    /* Prompt for actions in the gun shop */
       -    text = _("Will you B>uy, S>ell, or L>eave? ");
       -    attrset(PromptAttr);
       -    clear_line(22);
       -    mvaddstr(22, 40 - strlen(text) / 2, text);
       -    attrset(TextAttr);
       -
       -    /* Translate these three keys in line with the above options, keeping
       -     * the order (B>uy, S>ell, L>eave) the same - you can change the
       -     * wording of the prompt, but if you change the order in this key
       -     * list, the keys will do the wrong things! */
       -    action = GetKey(_("BSL"), "BSL", FALSE, FALSE, FALSE);
       -    if (action == 'S')
       -      SellGun(Play);
       -    else if (action == 'B')
       -      BuyGun(Play);
       -  } while (action != 'L');
       -  print_status(Play, TRUE);
       -}
       -
       -/* 
       - * Allows player "Play" to pay off loans interactively.
       - */
       -void LoanShark(Player *Play)
       -{
       -  gchar *text, *prstr;
       -  price_t money;
       -
       -  do {
       -    clear_bottom();
       -    attrset(PromptAttr);
       -
       -    /* Prompt for paying back loans from the loan shark */
       -    text =
       -        nice_input(_("How much money do you pay back? "), 19, 1, TRUE,
       -                   NULL, '\0');
       -    attrset(TextAttr);
       -    money = strtoprice(text);
       -    g_free(text);
       -    if (money < 0)
       -      money = 0;
       -    if (money > Play->Debt)
       -      money = Play->Debt;
       -    if (money > Play->Cash) {
       -      /* Error - player doesn't have enough money to pay back the loan */
       -      mvaddstr(20, 1, _("You don't have that much money!"));
       -      nice_wait();
       -    } else {
       -      SendClientMessage(Play, C_NONE, C_PAYLOAN, NULL,
       -                        (prstr = pricetostr(money)));
       -      g_free(prstr);
       -      money = 0;
       -    }
       -  } while (money != 0);
       -}
       -
       -/* 
       - * Allows player "Play" to pay in or withdraw money from the bank
       - * interactively.
       - */
       -void Bank(Player *Play)
       -{
       -  gchar *text, *prstr;
       -  price_t money = 0;
       -  int action;
       -
       -  do {
       -    clear_bottom();
       -    attrset(PromptAttr);
       -    /* Prompt for dealing with the bank in the curses client */
       -    mvaddstr(18, 1, _("Do you want to D>eposit money, W>ithdraw money, "
       -                      "or L>eave ? "));
       -    attrset(TextAttr);
       -
       -    /* Make sure you keep the order the same if you translate these keys!
       -     * (D>eposit, W>ithdraw, L>eave) */
       -    action = GetKey(_("DWL"), "DWL", FALSE, FALSE, FALSE);
       -
       -    if (action == 'D' || action == 'W') {
       -      /* Prompt for putting money in or taking money out of the bank */
       -      text = nice_input(_("How much money? "), 19, 1, TRUE, NULL, '\0');
       -
       -      money = strtoprice(text);
       -      g_free(text);
       -      if (money < 0)
       -        money = 0;
       -      if (action == 'W')
       -        money = -money;
       -      if (money > Play->Cash) {
       -        /* Error - player has tried to put more money into the bank than
       -         * he/she has */
       -        mvaddstr(20, 1, _("You don't have that much money!"));
       -        nice_wait();
       -      } else if (-money > Play->Bank) {
       -        /* Error - player has tried to withdraw more money from the bank
       -         * than there is in the account */
       -        mvaddstr(20, 1, _("There isn't that much money in the bank..."));
       -        nice_wait();
       -      } else if (money != 0) {
       -        SendClientMessage(Play, C_NONE, C_DEPOSIT, NULL,
       -                          (prstr = pricetostr(money)));
       -        g_free(prstr);
       -        money = 0;
       -      }
       -    }
       -  } while (action != 'L' && money != 0);
       -}
       -
       -/* 
       - * Waits for keyboard input; will only accept a key listed in the
       - * "allowed" string. This string may have been translated; thus
       - * the "orig_allowed" string contains the untranslated keys.
       - * Returns the untranslated key corresponding to the key pressed
       - * (e.g. if allowed[2] is pressed, orig_allowed[2] is returned)
       - * Case insensitive. If "AllowOther" is TRUE, keys other than the
       - * given selection are allowed, and cause a zero return value.
       - * If "PrintAllowed" is TRUE, the allowed keys are printed after
       - * the prompt. If "ExpandOut" is also TRUE, the full words for
       - * the commands, rather than just their first letters, are displayed.
       - */
       -int GetKey(char *allowed, char *orig_allowed, gboolean AllowOther,
       -           gboolean PrintAllowed, gboolean ExpandOut)
       -{
       -  int ch;
       -  guint AllowInd, WordInd, i;
       -
       -  /* Expansions of the single-letter keypresses for the benefit of the
       -   * user. i.e. "Yes" is printed for the key "Y" etc. You should indicate
       -   * to the user which letter in the word corresponds to the keypress, by
       -   * capitalising it or similar. */
       -  gchar *Words[] = { N_("Y:Yes"), N_("N:No"), N_("R:Run"),
       -    N_("F:Fight"), N_("A:Attack"), N_("E:Evade")
       -  };
       -  guint numWords = sizeof(Words) / sizeof(Words[0]);
       -  gchar *trWord;
       -
       -  curs_set(1);
       -  ch = '\0';
       -
       -  if (!allowed || strlen(allowed) == 0)
       -    return 0;
       -
       -  if (PrintAllowed) {
       -    addch('[' | TextAttr);
       -    for (AllowInd = 0; AllowInd < strlen(allowed); AllowInd++) {
       -      if (AllowInd > 0)
       -        addch('/' | TextAttr);
       -      WordInd = 0;
       -      while (WordInd < numWords &&
       -             orig_allowed[AllowInd] != Words[WordInd][0])
       -        WordInd++;
       -
       -      if (ExpandOut && WordInd < numWords) {
       -        trWord = _(Words[WordInd]);
       -        for (i = 2; i < strlen(trWord); i++)
       -          addch((guchar)trWord[i] | TextAttr);
       -      } else
       -        addch((guchar)allowed[AllowInd] | TextAttr);
       -    }
       -    addch(']' | TextAttr);
       -    addch(' ' | TextAttr);
       -  }
       -
       -  do {
       -    ch = bgetch();
       -    ch = toupper(ch);
       -    for (AllowInd = 0; AllowInd < strlen(allowed); AllowInd++) {
       -      if (allowed[AllowInd] == ch) {
       -        addch((guint)ch | TextAttr);
       -        curs_set(0);
       -        return orig_allowed[AllowInd];
       -      }
       -    }
       -  } while (!AllowOther);
       -
       -  curs_set(0);
       -  return 0;
       -}
       -
       -/* 
       - * Clears one whole line on the curses screen.
       - */
       -void clear_line(int line)
       -{
       -  int i;
       -
       -  move(line, 0);
       -  for (i = 0; i < Width; i++)
       -    addch(' ');
       -}
       -
       -/* 
       - * Clears the bottom of the screen (i.e. from line 16 to line 23)
       - * except for the top "skip" lines.
       - */
       -void clear_exceptfor(int skip)
       -{
       -  int i;
       -
       -  for (i = 16 + skip; i <= 23; i++)
       -    clear_line(i);
       -}
       -
       -
       -/* 
       - * Clears screen lines 16 to 23.
       - */
       -void clear_bottom(void)
       -{
       -  int i;
       -
       -  for (i = 16; i <= 23; i++)
       -    clear_line(i);
       -}
       -
       -/* 
       - * Clears the entire screen; 24 lines of 80 characters each.
       - */
       -void clear_screen(void)
       -{
       -  int i;
       -
       -  for (i = 0; i < Depth; i++)
       -    clear_line(i);
       -}
       -
       -/* 
       - * Displays a prompt on the bottom screen line and waits for the user
       - * to press a key.
       - */
       -void nice_wait()
       -{
       -  gchar *text;
       -
       -  attrset(PromptAttr);
       -  text = _("Press any key...");
       -  mvaddstr(23, (Width - strlen(text)) / 2, text);
       -  bgetch();
       -  attrset(TextAttr);
       -}
       -
       -/* 
       - * Handles the display of messages pertaining to player-player fights
       - * in the lower part of screen (fighting sub-screen). Adds the new line
       - * of text in "text" and scrolls up previous messages if necessary
       - * If "text" is NULL, initialises the area
       - * If "text" is a blank string, redisplays the message area
       - * Messages are displayed from lines 16 to 20; line 22 is used for
       - * the prompt for the user.
       - */
       -void DisplayFightMessage(Player *Play, char *text)
       -{
       -  static char Messages[5][79];
       -  static int x, y;
       -  gchar *textpt;
       -  gchar *AttackName, *DefendName, *BitchName;
       -  gint i, DefendHealth, DefendBitches, BitchesKilled, ArmPercent;
       -  gboolean Loot;
       -
       -  if (text == NULL) {
       -    x = 0;
       -    y = 15;
       -    for (i = 0; i < 5; i++)
       -      Messages[i][0] = '\0';
       -  } else if (!text[0]) {
       -    attrset(TextAttr);
       -    clear_bottom();
       -    for (i = 16; i <= 20; i++)
       -      mvaddstr(i, 1, Messages[i - 16]);
       -  } else {
       -    if (HaveAbility(Play, A_NEWFIGHT)) {
       -      ReceiveFightMessage(text, &AttackName, &DefendName, &DefendHealth,
       -                          &DefendBitches, &BitchName, &BitchesKilled,
       -                          &ArmPercent, &fp, &RunHere, &Loot, &CanFire,
       -                          &textpt);
       -    } else {
       -      textpt = text;
       -      if (Play->Flags & FIGHTING)
       -        fp = F_MSG;
       -      else
       -        fp = F_LASTLEAVE;
       -      CanFire = (Play->Flags & CANSHOOT);
       -      RunHere = FALSE;
       -    }
       -    while (textpt[0]) {
       -      if (y < 20)
       -        y++;
       -      else
       -        for (i = 0; i < 4; i++)
       -          strcpy(Messages[i], Messages[i + 1]);
       -
       -      strncpy(Messages[y - 16], textpt, 78);
       -      Messages[y - 16][78] = '\0';
       -      textpt += MIN(strlen(textpt), 78);
       -    }
       -  }
       -}
       -
       -/* 
       - * Displays a network message "buf" in the message area (lines
       - * 10 to 14) scrolling previous messages up.
       - * If "buf" is NULL, clears the message area
       - * If "buf" is a blank string, redisplays the message area
       - */
       -void display_message(char *buf)
       -{
       -  guint x, y;
       -  guint wid;
       -  static gchar Messages[5][200];
       -  gchar *bufpt;
       -
       -  if (Width <= 4)
       -    return;
       -
       -  wid = MIN(Width - 4, 200);
       -
       -  if (!buf) {
       -    for (y = 0; y < 5; y++) {
       -      memset(Messages[y], ' ', 200);
       -      if (Network) {
       -        mvaddch(y + 10, 0, ' ' | TextAttr);
       -        addch(ACS_VLINE | StatsAttr);
       -        for (x = 0; x < wid; x++)
       -          addch(' ' | StatsAttr);
       -        addch(ACS_VLINE | StatsAttr);
       -        addch(' ' | TextAttr);
       -      }
       -    }
       -  } else if (Network) {
       -    bufpt = buf;
       -    while (bufpt[0] != 0) {
       -      memmove(Messages[0], Messages[1], 200 * 4);
       -      memset(Messages[4], ' ', 200);
       -      memcpy(Messages[4], bufpt,
       -             strlen(bufpt) > wid ? wid : strlen(bufpt));
       -      bufpt += MIN(strlen(bufpt), wid);
       -    }
       -    for (y = 0; y < 5; y++)
       -      for (x = 0; x < wid; x++) {
       -        mvaddch(y + 10, x + 2, (guchar)Messages[y][x] | StatsAttr);
       -      }
       -    refresh();
       -  }
       -}
       -
       -/* 
       - * Displays the string "text" at the top of the screen. Usually used for
       - * displaying the current location or the "Subway" flash.
       - */
       -void print_location(char *text)
       -{
       -  int i;
       -
       -  if (!text)
       -    return;
       -  attrset(LocationAttr);
       -  move(0, Width / 2 - 9);
       -  for (i = 0; i < 18; i++)
       -    addch(' ');
       -  mvaddstr(0, (Width - strlen(text)) / 2, text);
       -  attrset(TextAttr);
       -}
       -
       -/* 
       - * Displays the status of player "Play" - i.e. the current turn, the
       - * location, bitches, available space, cash, guns, health and bank
       - * details. If "DispDrugs" is TRUE, displays the carried drugs on the
       - * right hand side of the screen; if FALSE, displays the carried guns.
       - */
       -void print_status(Player *Play, gboolean DispDrug)
       -{
       -  int i, c;
       -  GString *text;
       -
       -  text = g_string_new(NULL);
       -  attrset(TitleAttr);
       -  clear_line(0);
       -  g_string_sprintf(text, "%s%02d%s", Names.Month, Play->Turn, Names.Year);
       -  mvaddstr(0, 3, text->str);
       -
       -  attrset(StatsAttr);
       -  for (i = 2; i <= 14; i++) {
       -    mvaddch(i, 1, ACS_VLINE);
       -    mvaddch(i, Width - 2, ACS_VLINE);
       -  }
       -  mvaddch(1, 1, ACS_ULCORNER);
       -  for (i = 0; i < Width - 4; i++)
       -    addch(ACS_HLINE);
       -  addch(ACS_URCORNER);
       -
       -  mvaddch(1, Width / 2, ACS_TTEE);
       -  for (i = 2; i <= (Network ? 8 : 13); i++) {
       -    move(i, 2);
       -    for (c = 2; c < Width / 2; c++)
       -      addch(' ');
       -    addch(ACS_VLINE);
       -    for (c = Width / 2 + 1; c < Width - 2; c++)
       -      addch(' ');
       -  }
       -  if (!Network) {
       -    mvaddch(14, 1, ACS_LLCORNER);
       -    for (i = 0; i < Width - 4; i++)
       -      addch(ACS_HLINE);
       -    addch(ACS_LRCORNER);
       -    mvaddch(14, Width / 2, ACS_BTEE);
       -  } else {
       -    mvaddch(9, 1, ACS_LTEE);
       -    for (i = 0; i < Width - 4; i++)
       -      addch(ACS_HLINE);
       -    addch(ACS_RTEE);
       -
       -    /* Title of the "Messages" window in the curses client */
       -    mvaddstr(9, 15, _("Messages"));
       -
       -    mvaddch(9, Width / 2, ACS_BTEE);
       -    mvaddch(15, 1, ACS_LLCORNER);
       -    for (i = 0; i < Width - 4; i++)
       -      addch(ACS_HLINE);
       -    addch(ACS_LRCORNER);
       -  }
       -
       -  /* Title of the "Stats" window in the curses client */
       -  mvaddstr(1, Width / 4 - 2, _("Stats"));
       -
       -  attrset(StatsAttr);
       -
       -  /* Display of the player's cash in the stats window (careful to keep the
       -   * formatting if you change the length of the "Cash" word) */
       -  dpg_string_sprintf(text, _("Cash %17P"), Play->Cash);
       -  mvaddstr(3, 9, text->str);
       -
       -  /* Display of the total number of guns carried (%Tde="Guns" by default) */
       -  dpg_string_sprintf(text, _("%-19Tde%3d"), Names.Guns,
       -                     TotalGunsCarried(Play));
       -  mvaddstr(Network ? 4 : 5, 9, text->str);
       -
       -  /* Display of the player's health */
       -  g_string_sprintf(text, _("Health             %3d"), Play->Health);
       -  mvaddstr(Network ? 5 : 7, 9, text->str);
       -
       -  /* Display of the player's bank balance */
       -  dpg_string_sprintf(text, _("Bank %17P"), Play->Bank);
       -  mvaddstr(Network ? 6 : 9, 9, text->str);
       -
       -  if (Play->Debt > 0)
       -    attrset(DebtAttr);
       -  /* Display of the player's debt */
       -  dpg_string_sprintf(text, _("Debt %17P"), Play->Debt);
       -  mvaddstr(Network ? 7 : 11, 9, text->str);
       -  attrset(TitleAttr);
       -
       -  /* Display of the player's trenchcoat size (antique mode only) */
       -  if (WantAntique)
       -    g_string_sprintf(text, _("Space %6d"), Play->CoatSize);
       -  else {
       -    /* Display of the player's number of bitches, and available space
       -     * (%Tde="Bitches" by default) */
       -    dpg_string_sprintf(text, _("%Tde %3d  Space %6d"), Names.Bitches,
       -                       Play->Bitches.Carried, Play->CoatSize);
       -  }
       -  mvaddstr(0, Width - 2 - strlen(text->str), text->str);
       -  print_location(Location[(int)Play->IsAt].Name);
       -  attrset(StatsAttr);
       -
       -  c = 0;
       -  if (DispDrug) {
       -    /* Title of the "trenchcoat" window (antique mode only) */
       -    if (WantAntique)
       -      mvaddstr(1, Width * 3 / 4 - 5, _("Trenchcoat"));
       -    else {
       -      /* Title of the "drugs" window (the only important bit in this
       -       * string is the "%Tde" which is "Drugs" by default; the %/.../ part 
       -       * is ignored, so you don't need to translate it; see doc/i18n.html) 
       -       */
       -      dpg_string_sprintf(text, _("%/Stats: Drugs/%Tde"), Names.Drugs);
       -      mvaddstr(1, Width * 3 / 4 - strlen(text->str) / 2, text->str);
       -    }
       -    for (i = 0; i < NumDrug; i++) {
       -      if (Play->Drugs[i].Carried > 0) {
       -        /* Display of carried drugs with price (%tde="Opium", etc. by
       -         * default) */
       -        if (HaveAbility(Play, A_DRUGVALUE)) {
       -          dpg_string_sprintf(text, _("%-7tde  %3d @ %P"), Drug[i].Name,
       -                             Play->Drugs[i].Carried,
       -                             Play->Drugs[i].TotalValue /
       -                             Play->Drugs[i].Carried);
       -          mvaddstr(3 + c, Width / 2 + 3, text->str);
       -        } else {
       -          /* Display of carried drugs (%tde="Opium", etc. by default) */
       -          dpg_string_sprintf(text, _("%-7tde  %3d"), Drug[i].Name,
       -                             Play->Drugs[i].Carried);
       -          mvaddstr(3 + c / 2, Width / 2 + 3 + (c % 2) * 17, text->str);
       -        }
       -        c++;
       -      }
       -    }
       -  } else {
       -    /* Title of the "guns" window (the only important bit in this string
       -     * is the "%Tde" which is "Guns" by default) */
       -    dpg_string_sprintf(text, _("%/Stats: Guns/%Tde"), Names.Guns);
       -    mvaddstr(1, Width * 3 / 4 - strlen(text->str) / 2, text->str);
       -    for (i = 0; i < NumGun; i++) {
       -      if (Play->Guns[i].Carried > 0) {
       -        /* Display of carried guns (%tde="Baretta", etc. by default) */
       -        dpg_string_sprintf(text, _("%-22tde %3d"), Gun[i].Name,
       -                           Play->Guns[i].Carried);
       -        mvaddstr(3 + c, Width / 2 + 3, text->str);
       -        c++;
       -      }
       -    }
       -  }
       -  attrset(TextAttr);
       -  if (!Network)
       -    clear_line(15);
       -  refresh();
       -  g_string_free(text, TRUE);
       -}
       -
       -/* 
       - * Parses details about player "From" from string "Data" and then
       - * displays the lot, drugs and guns.
       - */
       -void DisplaySpyReports(char *Data, Player *From, Player *To)
       -{
       -  gchar *text;
       -
       -  ReceivePlayerData(To, Data, From);
       -
       -  clear_bottom();
       -  text = g_strdup_printf(_("Spy reports for %s"), GetPlayerName(From));
       -  mvaddstr(17, 1, text);
       -  g_free(text);
       -
       -  /* Message displayed with a spy's list of drugs (%Tde="Drugs" by
       -   * default) */
       -  text = dpg_strdup_printf(_("%/Spy: Drugs/%Tde..."), Names.Drugs);
       -  mvaddstr(19, 20, text);
       -  g_free(text);
       -  print_status(From, TRUE);
       -  nice_wait();
       -  clear_line(19);
       -
       -  /* Message displayed with a spy's list of guns (%Tde="Guns" by default) */
       -  text = dpg_strdup_printf(_("%/Spy: Guns/%Tde..."), Names.Guns);
       -  mvaddstr(19, 20, text);
       -  g_free(text);
       -  print_status(From, FALSE);
       -  nice_wait();
       -
       -  print_status(To, TRUE);
       -  refresh();
       -}
       -
       -/* 
       - * Displays the "Prompt" if non-NULL, and then lists all clients
       - * currently playing dopewars, other than the current player "Play".
       - * If "Select" is TRUE, gives each player a letter and asks the user
       - * to select one, which is returned by the function.
       - */
       -Player *ListPlayers(Player *Play, gboolean Select, char *Prompt)
       -{
       -  Player *tmp = NULL;
       -  GSList *list;
       -  int i, c;
       -  gchar *text;
       -
       -  attrset(TextAttr);
       -  clear_bottom();
       -  if (!FirstClient || (!g_slist_next(FirstClient) &&
       -                       FirstClient->data == Play)) {
       -    text = _("No other players are currently logged on!");
       -    mvaddstr(18, (Width - strlen(text)) / 2, text);
       -    nice_wait();
       -    return 0;
       -  }
       -  mvaddstr(16, 1, _("Players currently logged on:-"));
       -
       -  i = 0;
       -  for (list = FirstClient; list; list = g_slist_next(list)) {
       -    tmp = (Player *)list->data;
       -    if (strcmp(GetPlayerName(tmp), GetPlayerName(Play)) == 0)
       -      continue;
       -    if (Select)
       -      text = g_strdup_printf("%c. %s", 'A' + i, GetPlayerName(tmp));
       -    else
       -      text = g_strdup(GetPlayerName(tmp));
       -    mvaddstr(17 + i / 2, (i % 2) * 40 + 1, text);
       -    g_free(text);
       -    i++;
       -  }
       -
       -  if (Prompt) {
       -    attrset(PromptAttr);
       -    mvaddstr(22, 10, Prompt);
       -    attrset(TextAttr);
       -  }
       -  if (Select) {
       -    curs_set(1);
       -    attrset(TextAttr);
       -    c = 0;
       -    while (c < 'A' || c >= 'A' + i) {
       -      c = bgetch();
       -      c = toupper(c);
       -    }
       -    if (Prompt)
       -      addch((guint)c);
       -    list = FirstClient;
       -    while (c >= 'A') {
       -      if (list != FirstClient)
       -        list = g_slist_next(list);
       -      tmp = (Player *)list->data;
       -      while (strcmp(GetPlayerName(tmp), GetPlayerName(Play)) == 0) {
       -        list = g_slist_next(list);
       -        tmp = (Player *)list->data;
       -      }
       -      c--;
       -    }
       -    return tmp;
       -  } else {
       -    nice_wait();
       -  }
       -  return NULL;
       -}
       -
       -/* 
       - * Displays the given "prompt" (if non-NULL) at coordinates sx,sy and
       - * allows the user to input a string, which is returned. This is a
       - * dynamically allocated string, and so must be freed by the calling
       - * routine. If "digitsonly" is TRUE, the user will be permitted only to
       - * input numbers, although the suffixes m and k are allowed (the
       - * strtoprice routine understands this notation for a 1000000 or 1000
       - * multiplier) as well as a decimal point (. or ,)
       - * If "displaystr" is non-NULL, it is taken as a default response.
       - * If "passwdchar" is non-zero, it is displayed instead of the user's
       - * keypresses (e.g. for entering passwords)
       - */
       -char *nice_input(char *prompt, int sy, int sx, gboolean digitsonly,
       -                 char *displaystr, char passwdchar)
       -{
       -  int i, c, x;
       -  gboolean DecimalPoint, Suffix;
       -  GString *text;
       -  gchar *ReturnString;
       -
       -  DecimalPoint = Suffix = FALSE;
       -
       -  x = sx;
       -  move(sy, x);
       -  if (prompt) {
       -    attrset(PromptAttr);
       -    addstr(prompt);
       -    x += strlen(prompt);
       -  }
       -  attrset(TextAttr);
       -  if (displaystr) {
       -    if (passwdchar) {
       -      for (i = strlen(displaystr); i; i--)
       -        addch((guint)passwdchar);
       -    } else {
       -      addstr(displaystr);
       -    }
       -    i = strlen(displaystr);
       -    text = g_string_new(displaystr);
       -  } else {
       -    i = 0;
       -    text = g_string_new("");
       -  }
       -
       -  curs_set(1);
       -  do {
       -    move(sy + (x + i) / Width, (x + i) % Width);
       -    c = bgetch();
       -    if ((c == 8 || c == KEY_BACKSPACE || c == 127) && i > 0) {
       -      move(sy + (x + i - 1) / Width, (x + i - 1) % Width);
       -      addch(' ');
       -      i--;
       -      if (DecimalPoint && text->str[i] == '.')
       -        DecimalPoint = FALSE;
       -      if (Suffix)
       -        Suffix = FALSE;
       -      g_string_truncate(text, i);
       -    } else if (!Suffix) {
       -      if ((digitsonly && c >= '0' && c <= '9') ||
       -          (!digitsonly && c >= 32 && c != '^' && c < 127)) {
       -        g_string_append_c(text, c);
       -        i++;
       -        addch((guint)passwdchar ? passwdchar : c);
       -      } else if (digitsonly && (c == '.' || c == ',') && !DecimalPoint) {
       -        g_string_append_c(text, '.');
       -        i++;
       -        addch((guint)passwdchar ? passwdchar : c);
       -        DecimalPoint = TRUE;
       -      } else if (digitsonly
       -                 && (c == 'M' || c == 'm' || c == 'k' || c == 'K')
       -                 && !Suffix) {
       -        g_string_append_c(text, c);
       -        i++;
       -        addch((guint)passwdchar ? passwdchar : c);
       -        Suffix = TRUE;
       -      }
       -    }
       -  } while (c != '\n' && c != KEY_ENTER);
       -  curs_set(0);
       -  move(sy, x);
       -  ReturnString = text->str;
       -  g_string_free(text, FALSE);   /* Leave the buffer to return */
       -  return ReturnString;
       -}
       -
       -/* 
       - * Loop which handles the user playing an interactive game (i.e. "Play"
       - * is a client connected to a server, either locally or remotely)
       - * dopewars is essentially server-driven, so this loop simply has to
       - * make the screen look pretty, respond to user keypresses, and react
       - * to messages from the server.
       - */
       -static void Curses_DoGame(Player *Play)
       -{
       -  gchar *buf, *OldName, *TalkMsg;
       -  GString *text;
       -  int i, c;
       -  char IsCarrying;
       -
       -#if NETWORKING || HAVE_SELECT
       -  fd_set readfs;
       -#endif
       -#ifdef NETWORKING
       -  fd_set writefs;
       -  gboolean DoneOK;
       -  gchar *pt;
       -  gboolean justconnected = FALSE;
       -#endif
       -  int NumDrugsHere;
       -  int MaxSock;
       -  char HaveWorthless;
       -  Player *tmp;
       -  struct sigaction sact;
       -
       -  DisplayMode = DM_NONE;
       -  QuitRequest = FALSE;
       -
       -  ResizedFlag = 0;
       -  sact.sa_handler = ResizeHandle;
       -  sact.sa_flags = 0;
       -  sigemptyset(&sact.sa_mask);
       -  if (sigaction(SIGWINCH, &sact, NULL) == -1) {
       -    g_warning(_("Cannot install SIGWINCH interrupt handler!"));
       -  }
       -  OldName = g_strdup(GetPlayerName(Play));
       -  attrset(TextAttr);
       -  clear_screen();
       -  display_message(NULL);
       -  DisplayFightMessage(Play, NULL);
       -  print_status(Play, TRUE);
       -
       -  attrset(TextAttr);
       -  clear_bottom();
       -  buf = NULL;
       -  do {
       -    g_free(buf);
       -    buf =
       -        nice_input(_("Hey dude, what's your name? "), 17, 1, FALSE,
       -                   OldName, '\0');
       -  } while (buf[0] == 0);
       -#if NETWORKING
       -  if (WantNetwork) {
       -    if (!ConnectToServer(Play)) {
       -      end_curses();
       -      exit(1);
       -    }
       -    justconnected = TRUE;
       -  }
       -#endif /* NETWORKING */
       -  print_status(Play, TRUE);
       -  display_message("");
       -
       -  InitAbilities(Play);
       -  SendAbilities(Play);
       -  SetPlayerName(Play, buf);
       -  SendNullClientMessage(Play, C_NONE, C_NAME, NULL, buf);
       -  g_free(buf);
       -  g_free(OldName);
       -
       -  text = g_string_new("");
       -
       -  while (1) {
       -    if (Play->Health == 0)
       -      DisplayMode = DM_NONE;
       -    HaveWorthless = 0;
       -    IsCarrying = 0;
       -    for (i = 0; i < NumDrug; i++) {
       -      if (Play->Drugs[i].Carried > 0) {
       -        IsCarrying = 1;
       -        if (Play->Drugs[i].Price == 0)
       -          HaveWorthless = 1;
       -      }
       -    }
       -    switch (DisplayMode) {
       -    case DM_STREET:
       -      attrset(TextAttr);
       -      NumDrugsHere = 0;
       -      for (i = 0; i < NumDrug; i++)
       -        if (Play->Drugs[i].Price > 0)
       -          NumDrugsHere++;
       -      clear_bottom();
       -      /* Display of drug prices (%tde="drugs" by default) */
       -      dpg_string_sprintf(text, _("Hey dude, the prices of %tde here are:"),
       -                         Names.Drugs);
       -      mvaddstr(16, 1, text->str);
       -      for (c = 0, i = GetNextDrugIndex(-1, Play);
       -           c < NumDrugsHere && i != -1;
       -           c++, i = GetNextDrugIndex(i, Play)) {
       -        /* List of individual drug names for selection (%tde="Opium" etc.
       -         * by default) */
       -        dpg_string_sprintf(text, _("%c. %-10tde %8P"), 'A' + c,
       -                           Drug[i].Name, Play->Drugs[i].Price);
       -        mvaddstr(17 + c / 3, (c % 3) * 25 + 4, text->str);
       -      }
       -      attrset(PromptAttr);
       -      /* Prompts for "normal" actions in curses client */
       -      g_string_assign(text, _("Will you B>uy"));
       -      if (IsCarrying)
       -        g_string_append(text, _(", S>ell"));
       -      if (HaveWorthless && !WantAntique)
       -        g_string_append(text, _(", D>rop"));
       -      if (Network)
       -        g_string_append(text, _(", T>alk, P>age, L>ist"));
       -      if (!WantAntique && (Play->Bitches.Carried > 0 ||
       -                           Play->Flags & SPYINGON)) {
       -        g_string_append(text, _(", G>ive"));
       -      }
       -      if (Play->Flags & FIGHTING) {
       -        g_string_append(text, _(", F>ight"));
       -      } else {
       -        g_string_append(text, _(", J>et"));
       -      }
       -      g_string_append(text, _(", or Q>uit? "));
       -      mvaddstr(22, 40 - strlen(text->str) / 2, text->str);
       -      attrset(TextAttr);
       -      curs_set(1);
       -      break;
       -    case DM_FIGHT:
       -      DisplayFightMessage(Play, "");
       -      attrset(PromptAttr);
       -      /* Prompts for actions during fights in curses client */
       -      g_string_assign(text, _("Do you "));
       -      if (CanFire) {
       -        if (TotalGunsCarried(Play) > 0) {
       -          g_string_append(text, _("F>ight, "));
       -        } else {
       -          g_string_append(text, _("S>tand, "));
       -        }
       -      }
       -      if (fp != F_LASTLEAVE)
       -        g_string_append(text, _("R>un, "));
       -      if (!RunHere || fp == F_LASTLEAVE)
       -        /* (%tde = "drugs" by default here) */
       -        dpg_string_sprintfa(text, _("D>eal %tde, "), Names.Drugs);
       -      g_string_append(text, _("or Q>uit? "));
       -      mvaddstr(22, 40 - strlen(text->str) / 2, text->str);
       -      attrset(TextAttr);
       -      curs_set(1);
       -      break;
       -    case DM_DEAL:
       -      attrset(TextAttr);
       -      clear_bottom();
       -      mvaddstr(16, 1, "Your trade:-");
       -      mvaddstr(19, 1, "His trade:-");
       -      g_string_assign(text, "Do you A>dd, R>emove, O>K, D>eal ");
       -      g_string_append(text, Names.Drugs);
       -      g_string_append(text, ", or Q>uit? ");
       -      attrset(PromptAttr);
       -      mvaddstr(22, 40 - strlen(text->str) / 2, text->str);
       -      attrset(TextAttr);
       -      curs_set(1);
       -      break;
       -    case DM_NONE:
       -      break;
       -    }
       -    refresh();
       -
       -    if (QuitRequest)
       -      return;
       -#if NETWORKING
       -    FD_ZERO(&readfs);
       -    FD_ZERO(&writefs);
       -    FD_SET(0, &readfs);
       -    MaxSock = 1;
       -    if (Client) {
       -      if (justconnected) {
       -        /* Deal with any messages that came in while we were connect()ing */
       -        justconnected = FALSE;
       -        while ((pt = GetWaitingPlayerMessage(Play)) != NULL) {
       -          HandleClientMessage(pt, Play);
       -          g_free(pt);
       -        }
       -        if (QuitRequest)
       -          return;
       -      }
       -      SetSelectForNetworkBuffer(&Play->NetBuf, &readfs, &writefs,
       -                                NULL, &MaxSock);
       -    }
       -    if (bselect(MaxSock, &readfs, &writefs, NULL, NULL) == -1) {
       -      if (errno == EINTR) {
       -        CheckForResize(Play);
       -        continue;
       -      }
       -      perror("bselect");
       -      exit(1);
       -    }
       -    if (Client) {
       -      if (RespondToSelect(&Play->NetBuf, &readfs, &writefs, NULL, &DoneOK)) {
       -        while ((pt = GetWaitingPlayerMessage(Play)) != NULL) {
       -          HandleClientMessage(pt, Play);
       -          g_free(pt);
       -        }
       -        if (QuitRequest)
       -          return;
       -      }
       -      if (!DoneOK) {
       -        attrset(TextAttr);
       -        clear_line(22);
       -        mvaddstr(22, 0, _("Connection to server lost! "
       -                          "Reverting to single player mode"));
       -        nice_wait();
       -        SwitchToSinglePlayer(Play);
       -        print_status(Play, TRUE);
       -      }
       -    }
       -    if (FD_ISSET(0, &readfs)) {
       -#elif HAVE_SELECT
       -    FD_ZERO(&readfs);
       -    FD_SET(0, &readfs);
       -    MaxSock = 1;
       -    if (bselect(MaxSock, &readfs, NULL, NULL, NULL) == -1) {
       -      if (errno == EINTR) {
       -        CheckForResize(Play);
       -        continue;
       -      }
       -      perror("bselect");
       -      exit(1);
       -    }
       -#endif /* NETWORKING */
       -    if (DisplayMode == DM_STREET) {
       -      /* N.B. You must keep the order of these keys the same as the
       -       * original when you translate (B>uy, S>ell, D>rop, T>alk, P>age,
       -       * L>ist, G>ive errand, F>ight, J>et, Q>uit) */
       -      c = GetKey(_("BSDTPLGFJQ"), "BSDTPLGFJQ", TRUE, FALSE, FALSE);
       -
       -    } else if (DisplayMode == DM_FIGHT) {
       -      /* N.B. You must keep the order of these keys the same as the
       -       * original when you translate (D>eal drugs, R>un, F>ight, S>tand,
       -       * Q>uit) */
       -      c = GetKey(_("DRFSQ"), "DRFSQ", TRUE, FALSE, FALSE);
       -
       -    } else
       -      c = 0;
       -#if ! (NETWORKING || HAVE_SELECT)
       -    CheckForResize(Play);
       -#endif
       -    if (DisplayMode == DM_STREET) {
       -      if (c == 'J' && !(Play->Flags & FIGHTING)) {
       -        jet(Play, TRUE);
       -      } else if (c == 'F' && Play->Flags & FIGHTING) {
       -        DisplayMode = DM_FIGHT;
       -      } else if (c == 'T' && Play->Flags & TRADING) {
       -        DisplayMode = DM_DEAL;
       -      } else if (c == 'B') {
       -        DealDrugs(Play, TRUE);
       -      } else if (c == 'S' && IsCarrying) {
       -        DealDrugs(Play, FALSE);
       -      } else if (c == 'D' && HaveWorthless && !WantAntique) {
       -        DropDrugs(Play);
       -      } else if (c == 'G' && !WantAntique && Play->Bitches.Carried > 0) {
       -        GiveErrand(Play);
       -      } else if (c == 'Q') {
       -        if (want_to_quit() == 1) {
       -          DisplayMode = DM_NONE;
       -          clear_bottom();
       -          SendClientMessage(Play, C_NONE, C_WANTQUIT, NULL, NULL);
       -        }
       -      } else if (c == 'L' && Network) {
       -        attrset(PromptAttr);
       -        mvaddstr(23, 20, _("List what? P>layers or S>cores? "));
       -        /* P>layers, S>cores */
       -        i = GetKey(_("PS"), "PS", TRUE, FALSE, FALSE);
       -        if (i == 'P') {
       -          ListPlayers(Play, FALSE, NULL);
       -        } else if (i == 'S') {
       -          DisplayMode = DM_NONE;
       -          SendClientMessage(Play, C_NONE, C_REQUESTSCORE, NULL, NULL);
       -        }
       -      } else if (c == 'P' && Network) {
       -        tmp = ListPlayers(Play, TRUE,
       -                          _("Whom do you want to page "
       -                            "(talk privately to) ? "));
       -        if (tmp) {
       -          attrset(TextAttr);
       -          clear_line(22);
       -          /* Prompt for sending player-player messages */
       -          TalkMsg = nice_input(_("Talk: "), 22, 0, FALSE, NULL, '\0');
       -          if (TalkMsg[0]) {
       -            SendClientMessage(Play, C_NONE, C_MSGTO, tmp, TalkMsg);
       -            buf = g_strdup_printf("%s->%s: %s", GetPlayerName(Play),
       -                                  GetPlayerName(tmp), TalkMsg);
       -            display_message(buf);
       -            g_free(buf);
       -          }
       -          g_free(TalkMsg);
       -        }
       -      } else if (c == 'T' && Client) {
       -        attrset(TextAttr);
       -        clear_line(22);
       -        TalkMsg = nice_input(_("Talk: "), 22, 0, FALSE, NULL, '\0');
       -        if (TalkMsg[0]) {
       -          SendClientMessage(Play, C_NONE, C_MSG, NULL, TalkMsg);
       -          buf = g_strdup_printf("%s: %s", GetPlayerName(Play), TalkMsg);
       -          display_message(buf);
       -          g_free(buf);
       -        }
       -        g_free(TalkMsg);
       -      }
       -    } else if (DisplayMode == DM_FIGHT) {
       -      switch (c) {
       -      case 'D':
       -        DisplayMode = DM_STREET;
       -        break;
       -      case 'R':
       -        if (RunHere) {
       -          SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, "R");
       -        } else {
       -          jet(Play, TRUE);
       -        }
       -        break;
       -      case 'F':
       -        if (TotalGunsCarried(Play) > 0 && CanFire) {
       -          buf = g_strdup_printf("%c", c);
       -          Play->Flags &= ~CANSHOOT;
       -          SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, buf);
       -          g_free(buf);
       -        }
       -        break;
       -      case 'S':
       -        if (TotalGunsCarried(Play) == 0 && CanFire) {
       -          buf = g_strdup_printf("%c", c);
       -          Play->Flags &= ~CANSHOOT;
       -          SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, buf);
       -          g_free(buf);
       -        }
       -        break;
       -      case 'Q':
       -        if (want_to_quit() == 1) {
       -          DisplayMode = DM_NONE;
       -          clear_bottom();
       -          SendClientMessage(Play, C_NONE, C_WANTQUIT, NULL, NULL);
       -        }
       -        break;
       -      }
       -    } else if (DisplayMode == DM_DEAL) {
       -      switch (c) {
       -      case 'D':
       -        DisplayMode = DM_STREET;
       -        break;
       -      case 'Q':
       -        if (want_to_quit() == 1) {
       -          DisplayMode = DM_NONE;
       -          clear_bottom();
       -          SendClientMessage(Play, C_NONE, C_WANTQUIT, NULL, NULL);
       -        }
       -        break;
       -      }
       -    }
       -#if NETWORKING
       -    }
       -#endif
       -    curs_set(0);
       -  }
       -  g_string_free(text, TRUE);
       -}
       -
       -void CursesLoop(void)
       -{
       -  char c;
       -  Player *Play;
       -
       -  if (!CheckHighScoreFileConfig())
       -    return;
       -
       -  /* Save the configuration, so we can restore those elements that get
       -   * overwritten when we connect to a dopewars server */
       -  BackupConfig();
       -
       -  start_curses();
       -  Width = COLS;
       -  Depth = LINES;
       -
       -  /* Set up message handlers */
       -  ClientMessageHandlerPt = HandleClientMessage;
       -
       -  /* Make the GLib log messages display nicely */
       -  g_log_set_handler(NULL,
       -                    LogMask() | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING,
       -                    LogMessage, NULL);
       -
       -  display_intro();
       -
       -  Play = g_new(Player, 1);
       -  FirstClient = AddPlayer(0, Play, FirstClient);
       -  do {
       -    Curses_DoGame(Play);
       -    ShutdownNetwork(Play);
       -    CleanUpServer();
       -    RestoreConfig();
       -    attrset(TextAttr);
       -    mvaddstr(23, 20, _("Play again? "));
       -    c = GetKey(_("YN"), "YN", TRUE, TRUE, FALSE);
       -  } while (c == 'Y');
       -  FirstClient = RemovePlayer(Play, FirstClient);
       -  end_curses();
       -}
       -
       -#else
       -
       -#include <glib.h>
       -#include "nls.h"                /* We need this for the definition of '_' */
       -
       -void CursesLoop(void)
       -{
       -  g_print(_("No curses client available - rebuild the binary passing the\n"
       -            "--enable-curses-client option to configure, or use a windowed\n"
       -            "client (if available) instead!\n"));
       -}
       -
       -#endif /* CURSES_CLIENT */
 (DIR) diff --git a/src/curses_client/Makefile.am b/src/curses_client/Makefile.am
       t@@ -0,0 +1,6 @@
       +noinst_LIBRARIES = libcursesclient.a
       +libcursesclient_a_SOURCES = curses_client.c
       +libcursesclient_a_DEPENDENCIES = @INTLLIBS@
       +INCLUDES   = -I.. -I../.. -I.
       +LDADD      = @INTLLIBS@
       +DEFS       = @DEFS@ -DLOCALEDIR=\"${localedir}\"
 (DIR) diff --git a/src/curses_client/Makefile.in b/src/curses_client/Makefile.in
       t@@ -0,0 +1,325 @@
       +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
       +
       +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
       +# This Makefile.in is free software; the Free Software Foundation
       +# gives unlimited permission to copy and/or distribute it,
       +# with or without modifications, as long as this notice is preserved.
       +
       +# This program is distributed in the hope that it will be useful,
       +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
       +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
       +# PARTICULAR PURPOSE.
       +
       +
       +SHELL = @SHELL@
       +
       +srcdir = @srcdir@
       +top_srcdir = @top_srcdir@
       +VPATH = @srcdir@
       +prefix = @prefix@
       +exec_prefix = @exec_prefix@
       +
       +bindir = @bindir@
       +sbindir = @sbindir@
       +libexecdir = @libexecdir@
       +datadir = @datadir@
       +sysconfdir = @sysconfdir@
       +sharedstatedir = @sharedstatedir@
       +localstatedir = @localstatedir@
       +libdir = @libdir@
       +infodir = @infodir@
       +mandir = @mandir@
       +includedir = @includedir@
       +oldincludedir = /usr/include
       +
       +DESTDIR =
       +
       +pkgdatadir = $(datadir)/@PACKAGE@
       +pkglibdir = $(libdir)/@PACKAGE@
       +pkgincludedir = $(includedir)/@PACKAGE@
       +
       +top_builddir = ../..
       +
       +ACLOCAL = @ACLOCAL@
       +AUTOCONF = @AUTOCONF@
       +AUTOMAKE = @AUTOMAKE@
       +AUTOHEADER = @AUTOHEADER@
       +
       +INSTALL = @INSTALL@
       +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
       +INSTALL_DATA = @INSTALL_DATA@
       +INSTALL_SCRIPT = @INSTALL_SCRIPT@
       +transform = @program_transform_name@
       +
       +NORMAL_INSTALL = :
       +PRE_INSTALL = :
       +POST_INSTALL = :
       +NORMAL_UNINSTALL = :
       +PRE_UNINSTALL = :
       +POST_UNINSTALL = :
       +host_alias = @host_alias@
       +host_triplet = @host@
       +BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
       +CATALOGS = @CATALOGS@
       +CATOBJEXT = @CATOBJEXT@
       +CC = @CC@
       +DATADIRNAME = @DATADIRNAME@
       +GENCAT = @GENCAT@
       +GLIBC21 = @GLIBC21@
       +GLIB_CFLAGS = @GLIB_CFLAGS@
       +GLIB_CONFIG = @GLIB_CONFIG@
       +GLIB_LIBS = @GLIB_LIBS@
       +GMOFILES = @GMOFILES@
       +GMSGFMT = @GMSGFMT@
       +GTK_CFLAGS = @GTK_CFLAGS@
       +GTK_CONFIG = @GTK_CONFIG@
       +GTK_LIBS = @GTK_LIBS@
       +INSTOBJEXT = @INSTOBJEXT@
       +INTLBISON = @INTLBISON@
       +INTLLIBS = @INTLLIBS@
       +INTLOBJS = @INTLOBJS@
       +INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
       +LIBICONV = @LIBICONV@
       +MAKEINFO = @MAKEINFO@
       +MKINSTALLDIRS = @MKINSTALLDIRS@
       +MSGFMT = @MSGFMT@
       +PACKAGE = @PACKAGE@
       +POFILES = @POFILES@
       +POSUB = @POSUB@
       +RANLIB = @RANLIB@
       +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
       +USE_NLS = @USE_NLS@
       +VERSION = @VERSION@
       +WNDRES = @WNDRES@
       +localedir = @localedir@
       +
       +noinst_LIBRARIES = libcursesclient.a
       +libcursesclient_a_SOURCES = curses_client.c
       +libcursesclient_a_DEPENDENCIES = @INTLLIBS@
       +INCLUDES = -I.. -I../.. -I.
       +LDADD = @INTLLIBS@
       +DEFS = @DEFS@ -DLOCALEDIR=\"${localedir}\"
       +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
       +CONFIG_HEADER = ../../config.h
       +CONFIG_CLEAN_FILES = 
       +LIBRARIES =  $(noinst_LIBRARIES)
       +
       +CPPFLAGS = @CPPFLAGS@
       +LDFLAGS = @LDFLAGS@
       +LIBS = @LIBS@
       +libcursesclient_a_LIBADD = 
       +libcursesclient_a_OBJECTS =  curses_client.o
       +AR = ar
       +CFLAGS = @CFLAGS@
       +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
       +CCLD = $(CC)
       +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
       +DIST_COMMON =  Makefile.am Makefile.in
       +
       +
       +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
       +
       +TAR = gtar
       +GZIP_ENV = --best
       +DEP_FILES =  .deps/curses_client.P
       +SOURCES = $(libcursesclient_a_SOURCES)
       +OBJECTS = $(libcursesclient_a_OBJECTS)
       +
       +all: all-redirect
       +.SUFFIXES:
       +.SUFFIXES: .S .c .o .s
       +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
       +        cd $(top_srcdir) && $(AUTOMAKE) --gnu src/curses_client/Makefile
       +
       +Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
       +        cd $(top_builddir) \
       +          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
       +
       +
       +mostlyclean-noinstLIBRARIES:
       +
       +clean-noinstLIBRARIES:
       +        -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
       +
       +distclean-noinstLIBRARIES:
       +
       +maintainer-clean-noinstLIBRARIES:
       +
       +.s.o:
       +        $(COMPILE) -c $<
       +
       +.S.o:
       +        $(COMPILE) -c $<
       +
       +mostlyclean-compile:
       +        -rm -f *.o core *.core
       +
       +clean-compile:
       +
       +distclean-compile:
       +        -rm -f *.tab.c
       +
       +maintainer-clean-compile:
       +
       +libcursesclient.a: $(libcursesclient_a_OBJECTS) $(libcursesclient_a_DEPENDENCIES)
       +        -rm -f libcursesclient.a
       +        $(AR) cru libcursesclient.a $(libcursesclient_a_OBJECTS) $(libcursesclient_a_LIBADD)
       +        $(RANLIB) libcursesclient.a
       +
       +tags: TAGS
       +
       +ID: $(HEADERS) $(SOURCES) $(LISP)
       +        list='$(SOURCES) $(HEADERS)'; \
       +        unique=`for i in $$list; do echo $$i; done | \
       +          awk '    { files[$$0] = 1; } \
       +               END { for (i in files) print i; }'`; \
       +        here=`pwd` && cd $(srcdir) \
       +          && mkid -f$$here/ID $$unique $(LISP)
       +
       +TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
       +        tags=; \
       +        here=`pwd`; \
       +        list='$(SOURCES) $(HEADERS)'; \
       +        unique=`for i in $$list; do echo $$i; done | \
       +          awk '    { files[$$0] = 1; } \
       +               END { for (i in files) print i; }'`; \
       +        test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
       +          || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
       +
       +mostlyclean-tags:
       +
       +clean-tags:
       +
       +distclean-tags:
       +        -rm -f TAGS ID
       +
       +maintainer-clean-tags:
       +
       +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
       +
       +subdir = src/curses_client
       +
       +distdir: $(DISTFILES)
       +        here=`cd $(top_builddir) && pwd`; \
       +        top_distdir=`cd $(top_distdir) && pwd`; \
       +        distdir=`cd $(distdir) && pwd`; \
       +        cd $(top_srcdir) \
       +          && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu src/curses_client/Makefile
       +        @for file in $(DISTFILES); do \
       +          d=$(srcdir); \
       +          if test -d $$d/$$file; then \
       +            cp -pr $$d/$$file $(distdir)/$$file; \
       +          else \
       +            test -f $(distdir)/$$file \
       +            || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
       +            || cp -p $$d/$$file $(distdir)/$$file || :; \
       +          fi; \
       +        done
       +
       +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
       +
       +-include $(DEP_FILES)
       +
       +mostlyclean-depend:
       +
       +clean-depend:
       +
       +distclean-depend:
       +        -rm -rf .deps
       +
       +maintainer-clean-depend:
       +
       +%.o: %.c
       +        @echo '$(COMPILE) -c $<'; \
       +        $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
       +        @-cp .deps/$(*F).pp .deps/$(*F).P; \
       +        tr ' ' '\012' < .deps/$(*F).pp \
       +          | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
       +            >> .deps/$(*F).P; \
       +        rm .deps/$(*F).pp
       +
       +%.lo: %.c
       +        @echo '$(LTCOMPILE) -c $<'; \
       +        $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
       +        @-sed -e 's/^\([^:]*\)\.o[         ]*:/\1.lo \1.o :/' \
       +          < .deps/$(*F).pp > .deps/$(*F).P; \
       +        tr ' ' '\012' < .deps/$(*F).pp \
       +          | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
       +            >> .deps/$(*F).P; \
       +        rm -f .deps/$(*F).pp
       +info-am:
       +info: info-am
       +dvi-am:
       +dvi: dvi-am
       +check-am: all-am
       +check: check-am
       +installcheck-am:
       +installcheck: installcheck-am
       +install-exec-am:
       +install-exec: install-exec-am
       +
       +install-data-am:
       +install-data: install-data-am
       +
       +install-am: all-am
       +        @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
       +install: install-am
       +uninstall-am:
       +uninstall: uninstall-am
       +all-am: Makefile $(LIBRARIES)
       +all-redirect: all-am
       +install-strip:
       +        $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
       +installdirs:
       +
       +
       +mostlyclean-generic:
       +
       +clean-generic:
       +
       +distclean-generic:
       +        -rm -f Makefile $(CONFIG_CLEAN_FILES)
       +        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
       +
       +maintainer-clean-generic:
       +mostlyclean-am:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
       +                mostlyclean-tags mostlyclean-depend mostlyclean-generic
       +
       +mostlyclean: mostlyclean-am
       +
       +clean-am:  clean-noinstLIBRARIES clean-compile clean-tags clean-depend \
       +                clean-generic mostlyclean-am
       +
       +clean: clean-am
       +
       +distclean-am:  distclean-noinstLIBRARIES distclean-compile \
       +                distclean-tags distclean-depend distclean-generic \
       +                clean-am
       +
       +distclean: distclean-am
       +
       +maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \
       +                maintainer-clean-compile maintainer-clean-tags \
       +                maintainer-clean-depend maintainer-clean-generic \
       +                distclean-am
       +        @echo "This command is intended for maintainers to use;"
       +        @echo "it deletes files that may require special tools to rebuild."
       +
       +maintainer-clean: maintainer-clean-am
       +
       +.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
       +clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
       +mostlyclean-compile distclean-compile clean-compile \
       +maintainer-clean-compile tags mostlyclean-tags distclean-tags \
       +clean-tags maintainer-clean-tags distdir mostlyclean-depend \
       +distclean-depend clean-depend maintainer-clean-depend info-am info \
       +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
       +install-exec install-data-am install-data install-am install \
       +uninstall-am uninstall all-redirect all-am all installdirs \
       +mostlyclean-generic distclean-generic clean-generic \
       +maintainer-clean-generic clean mostlyclean distclean maintainer-clean
       +
       +
       +# Tell versions [3.59,3.63) of GNU make to not export all variables.
       +# Otherwise a system limit (for SysV at least) may be exceeded.
       +.NOEXPORT:
 (DIR) diff --git a/src/curses_client/curses_client.c b/src/curses_client/curses_client.c
       t@@ -0,0 +1,2409 @@
       +/************************************************************************
       + * curses_client.c  dopewars client using the (n)curses console library *
       + * Copyright (C)  1998-2002  Ben Webb                                   *
       + *                Email: ben@bellatrix.pcl.ox.ac.uk                     *
       + *                WWW: http://dopewars.sourceforge.net/                 *
       + *                                                                      *
       + * This program is free software; you can redistribute it and/or        *
       + * modify it under the terms of the GNU General Public License          *
       + * as published by the Free Software Foundation; either version 2       *
       + * of the License, or (at your option) any later version.               *
       + *                                                                      *
       + * This program is distributed in the hope that it will be useful,      *
       + * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
       + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
       + * GNU General Public License for more details.                         *
       + *                                                                      *
       + * You should have received a copy of the GNU General Public License    *
       + * along with this program; if not, write to the Free Software          *
       + * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
       + *                   MA  02111-1307, USA.                               *
       + ************************************************************************/
       +
       +#ifdef HAVE_CONFIG_H
       +#include <config.h>
       +#endif
       +
       +#include <string.h>
       +#include <stdlib.h>
       +#include <sys/types.h>
       +#ifdef HAVE_UNISTD_H
       +#include <unistd.h>
       +#endif
       +#include <ctype.h>
       +#include <signal.h>
       +#include <errno.h>
       +#include <glib.h>
       +#include "curses_client.h"
       +#include "dopeos.h"
       +#include "dopewars.h"
       +#include "message.h"
       +#include "nls.h"
       +#include "serverside.h"
       +#include "tstring.h"
       +
       +static void PrepareHighScoreScreen(void);
       +static void PrintHighScore(char *Data);
       +
       +static int ResizedFlag;
       +static SCREEN *cur_screen;
       +
       +#ifdef NETWORKING
       +static enum {
       +  CM_SERVER, CM_PROMPT, CM_META, CM_SINGLE
       +} ConnectMethod = CM_SERVER;
       +#endif
       +
       +static gboolean CanFire = FALSE, RunHere = FALSE;
       +static FightPoint fp;
       +
       +/* Function definitions; make them static so as not to clash with
       + * functions of the same name in different clients */
       +static void display_intro(void);
       +static void ResizeHandle(int sig);
       +static void CheckForResize(Player *Play);
       +static int GetKey(char *allowed, char *orig_allowed, gboolean AllowOther,
       +                  gboolean PrintAllowed, gboolean ExpandOut);
       +static void clear_bottom(void), clear_screen(void);
       +static void clear_line(int line), clear_exceptfor(int skip);
       +static void nice_wait(void);
       +static void DisplayFightMessage(Player *Play, char *text);
       +static void DisplaySpyReports(char *Data, Player *From, Player *To);
       +static void display_message(char *buf);
       +static void print_location(char *text);
       +static void print_status(Player *Play, gboolean DispDrug);
       +static char *nice_input(char *prompt, int sy, int sx, gboolean digitsonly,
       +                        char *displaystr, char passwdchar);
       +static Player *ListPlayers(Player *Play, gboolean Select, char *Prompt);
       +static void HandleClientMessage(char *buf, Player *Play);
       +static void PrintMessage(const gchar *text);
       +static void GunShop(Player *Play);
       +static void LoanShark(Player *Play);
       +static void Bank(Player *Play);
       +
       +#ifdef NETWORKING
       +static void HttpAuthFunc(HttpConnection *conn, gboolean proxyauth,
       +                         gchar *realm, gpointer data);
       +static void SocksAuthFunc(NetworkBuffer *netbuf, gpointer data);
       +#endif
       +
       +static DispMode DisplayMode;
       +static gboolean QuitRequest;
       +
       +/* 
       + * Initialises the curses library for accessing the screen.
       + */
       +static void start_curses(void)
       +{
       +  cur_screen = newterm(NULL, stdout, stdin);
       +  if (WantColour) {
       +    start_color();
       +    init_pair(1, COLOR_MAGENTA, COLOR_WHITE);
       +    init_pair(2, COLOR_BLACK, COLOR_WHITE);
       +    init_pair(3, COLOR_BLACK, COLOR_WHITE);
       +    init_pair(4, COLOR_BLUE, COLOR_WHITE);
       +    init_pair(5, COLOR_WHITE, COLOR_BLUE);
       +    init_pair(6, COLOR_RED, COLOR_WHITE);
       +  }
       +  cbreak();
       +  noecho();
       +  nodelay(stdscr, FALSE);
       +  keypad(stdscr, TRUE);
       +  curs_set(0);
       +}
       +
       +/* 
       + * Shuts down the curses screen library.
       + */
       +static void end_curses(void)
       +{
       +  keypad(stdscr, FALSE);
       +  curs_set(1);
       +  erase();
       +  refresh();
       +  endwin();
       +}
       +
       +/* 
       + * Handles a SIGWINCH signal, which is sent to indicate that the
       + * size of the curses screen has changed.
       + */
       +void ResizeHandle(int sig)
       +{
       +  ResizedFlag = 1;
       +}
       +
       +/* 
       + * Checks to see if the curses window needs to be resized - i.e. if a
       + * SIGWINCH signal has been received.
       + */
       +void CheckForResize(Player *Play)
       +{
       +  sigset_t sigset;
       +
       +  sigemptyset(&sigset);
       +  sigaddset(&sigset, SIGWINCH);
       +  sigprocmask(SIG_BLOCK, &sigset, NULL);
       +  if (ResizedFlag) {
       +    ResizedFlag = 0;
       +    end_curses();
       +    start_curses();
       +    Width = COLS;
       +    Depth = LINES;
       +    attrset(TextAttr);
       +    clear_screen();
       +    display_message("");
       +    DisplayFightMessage(Play, "");
       +    print_status(Play, TRUE);
       +  }
       +  sigprocmask(SIG_UNBLOCK, &sigset, NULL);
       +}
       +
       +static void LogMessage(const gchar *log_domain, GLogLevelFlags log_level,
       +                       const gchar *message, gpointer user_data)
       +{
       +  attrset(TextAttr);
       +  clear_bottom();
       +  PrintMessage(message);
       +  nice_wait();
       +  attrset(TextAttr);
       +  clear_bottom();
       +}
       +
       +/* 
       + * Displays a dopewars introduction screen.
       + */
       +void display_intro(void)
       +{
       +  GString *text;
       +
       +  attrset(TextAttr);
       +  clear_screen();
       +  attrset(TitleAttr);
       +
       +  /* Curses client introduction screen */
       +  text = g_string_new(_("D O P E W A R S"));
       +  mvaddstr(1, (Width - text->len) / 2, text->str);
       +
       +  attrset(TextAttr);
       +
       +  mvaddstr(3, 1, _("Based on John E. Dell's old Drug Wars game, dopewars "
       +                   "is a simulation of an"));
       +  mvaddstr(4, 1, _("imaginary drug market.  dopewars is an All-American "
       +                   "game which features"));
       +  mvaddstr(5, 1, _("buying, selling, and trying to get past the cops!"));
       +
       +  mvaddstr(7, 1, _("The first thing you need to do is pay off your "
       +                   "debt to the Loan Shark. After"));
       +  mvaddstr(8, 1, _("that, your goal is to make as much money as "
       +                   "possible (and stay alive)! You"));
       +  mvaddstr(9, 1, _("have one month of game time to make your fortune."));
       +
       +  mvaddstr(11, 18, _("Copyright (C) 1998-2002  Ben Webb "
       +                     "ben@bellatrix.pcl.ox.ac.uk"));
       +  g_string_sprintf(text, _("Version %s"), VERSION);
       +  mvaddstr(11, 2, text->str);
       +  g_string_assign(text, _("dopewars is released under the GNU "
       +                          "General Public Licence"));
       +  mvaddstr(12, (Width - text->len) / 2, text->str);
       +
       +  mvaddstr(14, 7, _("Icons and Graphics            Ocelot Mantis"));
       +  mvaddstr(15, 7, _("Drug Dealing and Research     Dan Wolf"));
       +  mvaddstr(16, 7, _("Play Testing                  Phil Davis           "
       +                    "Owen Walsh"));
       +  mvaddstr(17, 7, _("Extensive Play Testing        Katherine Holt       "
       +                    "Caroline Moore"));
       +  mvaddstr(18, 7, _("Constructive Criticism        Andrea Elliot-Smith  "
       +                    "Pete Winn"));
       +  mvaddstr(19, 7, _("Unconstructive Criticism      James Matthews"));
       +
       +  mvaddstr(21, 3, _("For information on the command line options, type "
       +                    "dopewars -h at your"));
       +  mvaddstr(22, 1,
       +           _("Unix prompt. This will display a help screen, listing "
       +             "the available options."));
       +
       +  g_string_free(text, TRUE);
       +  nice_wait();
       +  attrset(TextAttr);
       +  clear_screen();
       +  refresh();
       +}
       +
       +#ifdef NETWORKING
       +/* 
       + * Prompts the user to enter a server name and port to connect to.
       + */
       +static void SelectServerManually(void)
       +{
       +  gchar *text, *PortText;
       +
       +  if (ServerName[0] == '(')
       +    AssignName(&ServerName, "localhost");
       +  attrset(TextAttr);
       +  clear_bottom();
       +  mvaddstr(17, 1,
       +           /* Prompts for hostname and port when selecting a server
       +            * manually */
       +           _("Please enter the hostname and port of a dopewars server:-"));
       +  text = nice_input(_("Hostname: "), 18, 1, FALSE, ServerName, '\0');
       +  AssignName(&ServerName, text);
       +  g_free(text);
       +  PortText = g_strdup_printf("%d", Port);
       +  text = nice_input(_("Port: "), 19, 1, TRUE, PortText, '\0');
       +  Port = atoi(text);
       +  g_free(text);
       +  g_free(PortText);
       +}
       +
       +/* 
       + * Contacts the dopewars metaserver, and obtains a list of valid
       + * server/port pairs, one of which the user should select.
       + * Returns TRUE on success; on failure FALSE is returned, and
       + * errstr is assigned an error message.
       + */
       +static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr)
       +{
       +  int c;
       +  GSList *ListPt;
       +  ServerData *ThisServer;
       +  GString *text;
       +  gint index;
       +  fd_set readfds, writefds;
       +  int maxsock;
       +  gboolean DoneOK;
       +  HttpConnection *MetaConn;
       +
       +  attrset(TextAttr);
       +  clear_bottom();
       +  mvaddstr(17, 1, _("Please wait... attempting to contact metaserver..."));
       +  refresh();
       +
       +  if (OpenMetaHttpConnection(&MetaConn)) {
       +    SetHttpAuthFunc(MetaConn, HttpAuthFunc, NULL);
       +    SetNetworkBufferUserPasswdFunc(&MetaConn->NetBuf, SocksAuthFunc, NULL);
       +  } else {
       +    g_string_assign_error(errstr, MetaConn->NetBuf.error);
       +    CloseHttpConnection(MetaConn);
       +    return FALSE;
       +  }
       +
       +  ClearServerList(&ServerList);
       +
       +  do {
       +    FD_ZERO(&readfds);
       +    FD_ZERO(&writefds);
       +    FD_SET(0, &readfds);
       +    maxsock = 1;
       +    SetSelectForNetworkBuffer(&MetaConn->NetBuf, &readfds, &writefds,
       +                              NULL, &maxsock);
       +    if (bselect(maxsock, &readfds, &writefds, NULL, NULL) == -1) {
       +      if (errno == EINTR) {
       +        CheckForResize(Play);
       +        continue;
       +      }
       +      perror("bselect");
       +      exit(1);
       +    }
       +    if (FD_ISSET(0, &readfds)) {
       +      /* So that Ctrl-L works */
       +      c = getch();
       +#ifndef CYGWIN
       +      if (c == '\f')
       +        wrefresh(curscr);
       +#endif
       +    }
       +    if (RespondToSelect
       +        (&MetaConn->NetBuf, &readfds, &writefds, NULL, &DoneOK)) {
       +      while (HandleWaitingMetaServerData(MetaConn, &ServerList, &DoneOK)) {
       +      }
       +    }
       +    if (!DoneOK && HandleHttpCompletion(MetaConn)) {
       +      if (IsHttpError(MetaConn)) {
       +        g_string_assign_error(errstr, MetaConn->NetBuf.error);
       +        CloseHttpConnection(MetaConn);
       +        return FALSE;
       +      }
       +    }
       +  } while (DoneOK);
       +  CloseHttpConnection(MetaConn);
       +
       +  text = g_string_new("");
       +
       +  ListPt = ServerList;
       +  while (ListPt) {
       +    ThisServer = (ServerData *)(ListPt->data);
       +    attrset(TextAttr);
       +    clear_bottom();
       +    /* Printout of metaserver information in curses client */
       +    g_string_sprintf(text, _("Server : %s"), ThisServer->Name);
       +    mvaddstr(17, 1, text->str);
       +    g_string_sprintf(text, _("Port   : %d"), ThisServer->Port);
       +    mvaddstr(18, 1, text->str);
       +    g_string_sprintf(text, _("Version    : %s"), ThisServer->Version);
       +    mvaddstr(18, 40, text->str);
       +    if (ThisServer->CurPlayers == -1) {
       +      g_string_sprintf(text, _("Players: -unknown- (maximum %d)"),
       +                       ThisServer->MaxPlayers);
       +    } else {
       +      g_string_sprintf(text, _("Players: %d (maximum %d)"),
       +                       ThisServer->CurPlayers, ThisServer->MaxPlayers);
       +    }
       +    mvaddstr(19, 1, text->str);
       +    g_string_sprintf(text, _("Up since   : %s"), ThisServer->UpSince);
       +    mvaddstr(19, 40, text->str);
       +    g_string_sprintf(text, _("Comment: %s"), ThisServer->Comment);
       +    mvaddstr(20, 1, text->str);
       +    attrset(PromptAttr);
       +    mvaddstr(23, 1,
       +             _("N>ext server; P>revious server; S>elect this server... "));
       +
       +    /* The three keys that are valid responses to the previous question -
       +     * if you translate them, keep the keys in the same order (N>ext,
       +     * P>revious, S>elect) as they are here, otherwise they'll do the
       +     * wrong things. */
       +    c = GetKey(_("NPS"), "NPS", FALSE, FALSE, FALSE);
       +    switch (c) {
       +    case 'S':
       +      AssignName(&ServerName, ThisServer->Name);
       +      Port = ThisServer->Port;
       +      ListPt = NULL;
       +      break;
       +    case 'N':
       +      ListPt = g_slist_next(ListPt);
       +      if (!ListPt)
       +        ListPt = ServerList;
       +      break;
       +    case 'P':
       +      index = g_slist_position(ServerList, ListPt) - 1;
       +      if (index >= 0)
       +        ListPt = g_slist_nth(ServerList, (guint)index);
       +      else
       +        ListPt = g_slist_last(ListPt);
       +      break;
       +    }
       +  }
       +  if (!ServerList) {
       +    g_string_assign(errstr, "No servers listed on metaserver");
       +    return FALSE;
       +  }
       +  clear_line(17);
       +  refresh();
       +  g_string_free(text, TRUE);
       +  return TRUE;
       +}
       +
       +static void DisplayConnectStatus(NetworkBuffer *netbuf,
       +                                 NBStatus oldstatus,
       +                                 NBSocksStatus oldsocks)
       +{
       +  NBStatus status;
       +  NBSocksStatus sockstat;
       +  GString *text;
       +
       +  status = netbuf->status;
       +  sockstat = netbuf->sockstat;
       +
       +  if (oldstatus == status && oldsocks == sockstat)
       +    return;
       +
       +  text = g_string_new("");
       +
       +  switch (status) {
       +  case NBS_PRECONNECT:
       +    break;
       +  case NBS_SOCKSCONNECT:
       +    switch (sockstat) {
       +    case NBSS_METHODS:
       +      g_string_sprintf(text, _("Connected to SOCKS server %s..."),
       +                       Socks.name);
       +      break;
       +    case NBSS_USERPASSWD:
       +      g_string_assign(text, _("Authenticating with SOCKS server"));
       +      break;
       +    case NBSS_CONNECT:
       +      g_string_sprintf(text, _("Asking SOCKS for connect to %s..."),
       +                       ServerName);
       +      break;
       +    }
       +    break;
       +  case NBS_CONNECTED:
       +    break;
       +  }
       +  if (text->str[0]) {
       +    mvaddstr(17, 1, text->str);
       +    refresh();
       +  }
       +  g_string_free(text, TRUE);
       +}
       +
       +void HttpAuthFunc(HttpConnection *conn, gboolean proxyauth,
       +                  gchar *realm, gpointer data)
       +{
       +  gchar *text, *user, *password = NULL;
       +
       +  attrset(TextAttr);
       +  clear_bottom();
       +  if (proxyauth) {
       +    text = g_strdup_printf(_("Proxy authentication required for realm %s"),
       +                           realm);
       +  } else {
       +    text =
       +        g_strdup_printf(_("Authentication required for realm %s"), realm);
       +  }
       +  mvaddstr(17, 1, text);
       +  mvaddstr(18, 1, _("(Enter a blank username to cancel)"));
       +  g_free(text);
       +
       +  user = nice_input(_("User name: "), 19, 1, FALSE, NULL, '\0');
       +  if (user && user[0]) {
       +    password = nice_input(_("Password: "), 20, 1, FALSE, NULL, '*');
       +  }
       +
       +  SetHttpAuthentication(conn, proxyauth, user, password);
       +  g_free(user);
       +  g_free(password);
       +}
       +
       +void SocksAuthFunc(NetworkBuffer *netbuf, gpointer data)
       +{
       +  gchar *user, *password = NULL;
       +
       +  attrset(TextAttr);
       +  clear_bottom();
       +  mvaddstr(17, 1, _("SOCKS authentication required (enter a blank "
       +                    "username to cancel)"));
       +
       +  user = nice_input(_("User name: "), 18, 1, FALSE, NULL, '\0');
       +  if (user && user[0]) {
       +    password = nice_input(_("Password: "), 19, 1, FALSE, NULL, '*');
       +  }
       +
       +  SendSocks5UserPasswd(netbuf, user, password);
       +  g_free(user);
       +  g_free(password);
       +}
       +
       +static gboolean DoConnect(Player *Play, GString *errstr)
       +{
       +  NetworkBuffer *netbuf;
       +  fd_set readfds, writefds;
       +  int maxsock, c;
       +  gboolean doneOK = TRUE;
       +  NBStatus oldstatus;
       +  NBSocksStatus oldsocks;
       +
       +  netbuf = &Play->NetBuf;
       +  oldstatus = netbuf->status;
       +  oldsocks = netbuf->sockstat;
       +
       +  if (!StartNetworkBufferConnect(netbuf, ServerName, Port)) {
       +    doneOK = FALSE;
       +  } else {
       +    SetNetworkBufferUserPasswdFunc(netbuf, SocksAuthFunc, NULL);
       +    while (netbuf->status != NBS_CONNECTED) {
       +      DisplayConnectStatus(netbuf, oldstatus, oldsocks);
       +      oldstatus = netbuf->status;
       +      oldsocks = netbuf->sockstat;
       +      FD_ZERO(&readfds);
       +      FD_ZERO(&writefds);
       +      FD_SET(0, &readfds);
       +      maxsock = 1;
       +      SetSelectForNetworkBuffer(netbuf, &readfds, &writefds, NULL,
       +                                &maxsock);
       +      if (bselect(maxsock, &readfds, &writefds, NULL, NULL) == -1) {
       +        if (errno == EINTR) {
       +          CheckForResize(Play);
       +          continue;
       +        }
       +        perror("bselect");
       +        exit(1);
       +      }
       +      if (FD_ISSET(0, &readfds)) {
       +        /* So that Ctrl-L works */
       +        c = getch();
       +#ifndef CYGWIN
       +        if (c == '\f')
       +          wrefresh(curscr);
       +#endif
       +      }
       +      RespondToSelect(netbuf, &readfds, &writefds, NULL, &doneOK);
       +    }
       +  }
       +
       +  if (!doneOK)
       +    g_string_assign_error(errstr, netbuf->error);
       +  return doneOK;
       +}
       +
       +/* 
       + * Connects to a dopewars server. Prompts the user to select a server
       + * if necessary. Returns TRUE, unless the user elected to quit the
       + * program rather than choose a valid server.
       + */
       +static gboolean ConnectToServer(Player *Play)
       +{
       +  gboolean MetaOK = TRUE, NetOK = TRUE, firstrun = FALSE;
       +  GString *errstr;
       +  gchar *text;
       +  int c;
       +
       +  errstr = g_string_new("");
       +
       +  if (g_strcasecmp(ServerName, SN_META) == 0 || ConnectMethod == CM_META) {
       +    ConnectMethod = CM_META;
       +    MetaOK = SelectServerFromMetaServer(Play, errstr);
       +  } else if (g_strcasecmp(ServerName, SN_PROMPT) == 0 ||
       +             ConnectMethod == CM_PROMPT) {
       +    ConnectMethod = CM_PROMPT;
       +    SelectServerManually();
       +  } else if (g_strcasecmp(ServerName, SN_SINGLE) == 0 ||
       +             ConnectMethod == CM_SINGLE) {
       +    ConnectMethod = CM_SINGLE;
       +    g_string_free(errstr, TRUE);
       +    return TRUE;
       +  } else
       +    firstrun = TRUE;
       +
       +  while (1) {
       +    attrset(TextAttr);
       +    clear_bottom();
       +    if (MetaOK && !firstrun) {
       +      mvaddstr(17, 1, _("Please wait... attempting to contact "
       +                        "dopewars server..."));
       +      refresh();
       +      NetOK = DoConnect(Play, errstr);
       +    }
       +    if (!NetOK || !MetaOK || firstrun) {
       +      firstrun = FALSE;
       +      clear_line(16);
       +      clear_line(17);
       +      if (!MetaOK) {
       +        /* Display of an error while contacting the metaserver */
       +        mvaddstr(16, 1, _("Cannot get metaserver details"));
       +        text = g_strdup_printf("   (%s)", errstr->str);
       +        mvaddstr(17, 1, text);
       +        g_free(text);
       +      } else if (!NetOK) {
       +        /* Display of an error message while trying to contact a dopewars
       +         * server (the error message itself is displayed on the next
       +         * screen line) */
       +        mvaddstr(16, 1, _("Could not start multiplayer dopewars"));
       +        text = g_strdup_printf("   (%s)", errstr->str);
       +        mvaddstr(17, 1, text);
       +        g_free(text);
       +      }
       +      MetaOK = NetOK = TRUE;
       +      attrset(PromptAttr);
       +      mvaddstr(18, 1,
       +               _("Will you... C>onnect to a named dopewars server"));
       +      mvaddstr(19, 1,
       +               _("            L>ist the servers on the metaserver, and "
       +                 "select one"));
       +      mvaddstr(20, 1,
       +               _("            Q>uit (where you can start a server "
       +                 "by typing \"dopewars -s\")"));
       +      mvaddstr(21, 1, _("         or P>lay single-player ? "));
       +      attrset(TextAttr);
       +
       +      /* Translate these 4 keys in line with the above options, keeping
       +       * the order the same (C>onnect, L>ist, Q>uit, P>lay single-player) */
       +      c = GetKey(_("CLQP"), "CLQP", FALSE, FALSE, FALSE);
       +      switch (c) {
       +      case 'Q':
       +        g_string_free(errstr, TRUE);
       +        return FALSE;
       +      case 'P':
       +        g_string_free(errstr, TRUE);
       +        return TRUE;
       +      case 'L':
       +        MetaOK = SelectServerFromMetaServer(Play, errstr);
       +        break;
       +      case 'C':
       +        SelectServerManually();
       +        break;
       +      }
       +    } else
       +      break;
       +  }
       +  g_string_free(errstr, TRUE);
       +  Client = Network = TRUE;
       +  return TRUE;
       +}
       +#endif /* NETWORKING */
       +
       +/* 
       + * Displays the list of locations and prompts the user to select one.
       + * If "AllowReturn" is TRUE, then if the current location is selected
       + * simply drop back to the main game loop, otherwise send a request
       + * to the server to move to the new location. If FALSE, the user MUST
       + * choose a new location to move to. The active client player is
       + * passed in "Play".
       + * N.B. May set the global variable DisplayMode.
       + * Returns: TRUE if the user chose to jet to a new location,
       + *          FALSE if the action was cancelled instead.
       + */
       +static gboolean jet(Player *Play, gboolean AllowReturn)
       +{
       +  int i, c;
       +  char text[80];
       +
       +  attrset(TextAttr);
       +  clear_bottom();
       +  for (i = 0; i < NumLocation; i++) {
       +    sprintf(text, "%d. %s", i + 1, Location[i].Name);
       +    mvaddstr(17 + i / 3, (i % 3) * 20 + 12, text);
       +  }
       +  attrset(PromptAttr);
       +
       +  /* Prompt when the player chooses to "jet" to a new location */
       +  mvaddstr(22, 22, _("Where to, dude ? "));
       +  attrset(TextAttr);
       +  curs_set(1);
       +  do {
       +    c = bgetch();
       +    if (c >= '1' && c < '1' + NumLocation) {
       +      addstr(Location[c - '1'].Name);
       +      if (Play->IsAt != c - '1') {
       +        sprintf(text, "%d", c - '1');
       +        DisplayMode = DM_NONE;
       +        SendClientMessage(Play, C_NONE, C_REQUESTJET, NULL, text);
       +      } else
       +        c = 0;
       +    } else
       +      c = 0;
       +  } while (c == 0 && !AllowReturn);
       +
       +  curs_set(0);
       +  return (c != 0);
       +}
       +
       +/* 
       + * Prompts the user "Play" to drop some of the currently carried drugs.
       + */
       +static void DropDrugs(Player *Play)
       +{
       +  int i, c, num, NumDrugs;
       +  GString *text;
       +  gchar *buf;
       +
       +  attrset(TextAttr);
       +  clear_bottom();
       +  text = g_string_new("");
       +  dpg_string_sprintf(text,
       +                     /* List of drugs that you can drop (%tde = "drugs" by 
       +                      * default) */
       +                     _("You can\'t get any cash for the following "
       +                       "carried %tde :"), Names.Drugs);
       +  mvaddstr(16, 1, text->str);
       +  NumDrugs = 0;
       +  for (i = 0; i < NumDrug; i++) {
       +    if (Play->Drugs[i].Carried > 0 && Play->Drugs[i].Price == 0) {
       +      g_string_sprintf(text, "%c. %-10s %-8d", NumDrugs + 'A',
       +                       Drug[i].Name, Play->Drugs[i].Carried);
       +      mvaddstr(17 + NumDrugs / 3, (NumDrugs % 3) * 25 + 4, text->str);
       +      NumDrugs++;
       +    }
       +  }
       +  attrset(PromptAttr);
       +  mvaddstr(22, 20, _("What do you want to drop? "));
       +  curs_set(1);
       +  attrset(TextAttr);
       +  c = bgetch();
       +  c = toupper(c);
       +  for (i = 0; c >= 'A' && c < 'A' + NumDrugs && i < NumDrug; i++) {
       +    if (Play->Drugs[i].Carried > 0 && Play->Drugs[i].Price == 0) {
       +      c--;
       +      if (c < 'A') {
       +        addstr(Drug[i].Name);
       +        buf =
       +            nice_input(_("How many do you drop? "), 23, 8, TRUE, NULL,
       +                       '\0');
       +        num = atoi(buf);
       +        g_free(buf);
       +        if (num > 0) {
       +          g_string_sprintf(text, "drug^%d^%d", i, -num);
       +          SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text->str);
       +        }
       +      }
       +    }
       +  }
       +  g_string_free(text, TRUE);
       +}
       +
       +/* 
       + * Prompts the user (i.e. the owner of client "Play") to buy drugs if
       + * "Buy" is TRUE, or to sell drugs otherwise. A list of available drugs
       + * is displayed, and on receiving the selection, the user is prompted
       + * for the number of drugs desired. Finally a message is sent to the
       + * server to buy or sell the required quantity.
       + */
       +static void DealDrugs(Player *Play, gboolean Buy)
       +{
       +  int i, c, NumDrugsHere;
       +  gchar *text, *input;
       +  int DrugNum, CanCarry, CanAfford;
       +
       +  NumDrugsHere = 0;
       +  for (c = 0; c < NumDrug; c++)
       +    if (Play->Drugs[c].Price > 0)
       +      NumDrugsHere++;
       +
       +  clear_line(22);
       +  attrset(PromptAttr);
       +  if (Buy) {
       +    /* Buy and sell prompts for dealing drugs or guns */
       +    mvaddstr(22, 20, _("What do you wish to buy? "));
       +  } else {
       +    mvaddstr(22, 20, _("What do you wish to sell? "));
       +  }
       +  curs_set(1);
       +  attrset(TextAttr);
       +  c = bgetch();
       +  c = toupper(c);
       +  if (c >= 'A' && c < 'A' + NumDrugsHere) {
       +    DrugNum = -1;
       +    c -= 'A';
       +    for (i = 0; i <= c; i++)
       +      DrugNum = GetNextDrugIndex(DrugNum, Play);
       +    addstr(Drug[DrugNum].Name);
       +    CanCarry = Play->CoatSize;
       +    CanAfford = Play->Cash / Play->Drugs[DrugNum].Price;
       +
       +    if (Buy) {
       +      /* Display of number of drugs you could buy and/or carry, when
       +       * buying drugs */
       +      text = g_strdup_printf(_("You can afford %d, and can carry %d. "),
       +                             CanAfford, CanCarry);
       +      mvaddstr(23, 2, text);
       +      input = nice_input(_("How many do you buy? "), 23, 2 + strlen(text),
       +                         TRUE, NULL, '\0');
       +      c = atoi(input);
       +      g_free(input);
       +      g_free(text);
       +      if (c >= 0) {
       +        text = g_strdup_printf("drug^%d^%d", DrugNum, c);
       +        SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text);
       +        g_free(text);
       +      }
       +    } else {
       +      /* Display of number of drugs you have, when selling drugs */
       +      text =
       +          g_strdup_printf(_("You have %d. "),
       +                          Play->Drugs[DrugNum].Carried);
       +      mvaddstr(23, 2, text);
       +      input = nice_input(_("How many do you sell? "), 23, 2 + strlen(text),
       +                         TRUE, NULL, '\0');
       +      c = atoi(input);
       +      g_free(input);
       +      g_free(text);
       +      if (c >= 0) {
       +        text = g_strdup_printf("drug^%d^%d", DrugNum, -c);
       +        SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text);
       +        g_free(text);
       +      }
       +    }
       +  }
       +  curs_set(0);
       +}
       +
       +/* 
       + * Prompts the user (player "Play") to give an errand to one of his/her
       + * bitches. The decision is relayed to the server for implementation.
       + */
       +static void GiveErrand(Player *Play)
       +{
       +  int c, y;
       +  GString *text;
       +  Player *To;
       +
       +  text = g_string_new("");
       +  attrset(TextAttr);
       +  clear_bottom();
       +  y = 17;
       +
       +  /* Prompt for sending your bitches out to spy etc. (%tde = "bitches" by
       +   * default) */
       +  dpg_string_sprintf(text,
       +                     _("Choose an errand to give one of your %tde..."),
       +                     Names.Bitches);
       +  mvaddstr(y++, 1, text->str);
       +  attrset(PromptAttr);
       +  if (Play->Bitches.Carried > 0) {
       +    dpg_string_sprintf(text,
       +                       _("   S>py on another dealer                  "
       +                         "(cost: %P)"), Prices.Spy);
       +    mvaddstr(y++, 2, text->str);
       +    dpg_string_sprintf(text,
       +                       _("   T>ip off the cops to another dealer     "
       +                         "(cost: %P)"), Prices.Tipoff);
       +    mvaddstr(y++, 2, text->str);
       +    mvaddstr(y++, 2, _("   G>et stuffed"));
       +  }
       +  if (Play->Flags & SPYINGON) {
       +    mvaddstr(y++, 2, _("or C>ontact your spies and receive reports"));
       +  }
       +  mvaddstr(y++, 2, _("or N>o errand ? "));
       +  curs_set(1);
       +  attrset(TextAttr);
       +
       +  /* Translate these 5 keys to match the above options, keeping the
       +   * original order the same (S>py, T>ip off, G>et stuffed, C>ontact spy,
       +   * N>o errand) */
       +  c = GetKey(_("STGCN"), "STGCN", TRUE, FALSE, FALSE);
       +
       +  if (Play->Bitches.Carried > 0 || c == 'C')
       +    switch (c) {
       +    case 'S':
       +      To = ListPlayers(Play, TRUE, _("Whom do you want to spy on? "));
       +      if (To)
       +        SendClientMessage(Play, C_NONE, C_SPYON, To, NULL);
       +      break;
       +    case 'T':
       +      To = ListPlayers(Play, TRUE,
       +                       _("Whom do you want to tip the cops off to? "));
       +      if (To)
       +        SendClientMessage(Play, C_NONE, C_TIPOFF, To, NULL);
       +      break;
       +    case 'G':
       +      attrset(PromptAttr);
       +      /* Prompt for confirmation of sacking a bitch */
       +      addstr(_(" Are you sure? "));
       +
       +      /* The two keys that are valid for answering Yes/No - if you
       +       * translate them, keep them in the same order - i.e. "Yes" before
       +       * "No" */
       +      c = GetKey(_("YN"), "YN", FALSE, TRUE, FALSE);
       +
       +      if (c == 'Y')
       +        SendClientMessage(Play, C_NONE, C_SACKBITCH, NULL, NULL);
       +      break;
       +    case 'C':
       +      if (Play->Flags & SPYINGON) {
       +        SendClientMessage(Play, C_NONE, C_CONTACTSPY, NULL, NULL);
       +      }
       +      break;
       +    }
       +}
       +
       +/* 
       + * Asks the user if he/she _really_ wants to quit dopewars.
       + */
       +static int want_to_quit(void)
       +{
       +  attrset(TextAttr);
       +  clear_line(22);
       +  attrset(PromptAttr);
       +  mvaddstr(22, 1, _("Are you sure you want to quit? "));
       +  attrset(TextAttr);
       +  return (GetKey(_("YN"), "YN", FALSE, TRUE, FALSE) != 'N');
       +}
       +
       +/* 
       + * Prompts the user to change his or her name, and notifies the server.
       + */
       +static void change_name(Player *Play, gboolean nullname)
       +{
       +  gchar *NewName;
       +
       +  /* Prompt for player to change his/her name */
       +  NewName = nice_input(_("New name: "), 23, 0, FALSE, NULL, '\0');
       +
       +  if (NewName[0]) {
       +    if (nullname) {
       +      SendNullClientMessage(Play, C_NONE, C_NAME, NULL, NewName);
       +    } else {
       +      SendClientMessage(Play, C_NONE, C_NAME, NULL, NewName);
       +    }
       +    SetPlayerName(Play, NewName);
       +  }
       +  g_free(NewName);
       +}
       +
       +/* 
       + * Given a message "Message" coming in for player "Play", performs
       + * processing and reacts properly; if a message indicates the end of the
       + * game, the global variable QuitRequest is set. The global variable
       + * DisplayMode may also be changed by this routine as a result of network
       + * traffic.
       + */
       +void HandleClientMessage(char *Message, Player *Play)
       +{
       +  char *pt, *Data, *wrd;
       +  AICode AI;
       +  MsgCode Code;
       +  Player *From, *tmp;
       +  GSList *list;
       +  gchar *text;
       +  int i;
       +  gboolean Handled;
       +
       +  /* Ignore To: field - all messages will be for Player "Play" */
       +  if (ProcessMessage(Message, Play, &From, &AI, &Code, &Data, FirstClient)
       +      == -1) {
       +    return;
       +  }
       +
       +  Handled =
       +      HandleGenericClientMessage(From, AI, Code, Play, Data, &DisplayMode);
       +  switch (Code) {
       +  case C_ENDLIST:
       +    if (FirstClient && g_slist_next(FirstClient)) {
       +      ListPlayers(Play, FALSE, NULL);
       +    }
       +    break;
       +  case C_STARTHISCORE:
       +    PrepareHighScoreScreen();
       +    break;
       +  case C_HISCORE:
       +    PrintHighScore(Data);
       +    break;
       +  case C_ENDHISCORE:
       +    if (strcmp(Data, "end") == 0) {
       +      QuitRequest = TRUE;
       +    } else {
       +      nice_wait();
       +      clear_screen();
       +      display_message("");
       +      print_status(Play, TRUE);
       +      refresh();
       +    }
       +    break;
       +  case C_PUSH:
       +    attrset(TextAttr);
       +    clear_line(22);
       +    mvaddstr(22, 0, _("You have been pushed from the server. "
       +                      "Reverting to single player mode."));
       +    nice_wait();
       +    SwitchToSinglePlayer(Play);
       +    print_status(Play, TRUE);
       +    break;
       +  case C_QUIT:
       +    attrset(TextAttr);
       +    clear_line(22);
       +    mvaddstr(22, 0,
       +             _("The server has terminated. Reverting to "
       +               "single player mode."));
       +    nice_wait();
       +    SwitchToSinglePlayer(Play);
       +    print_status(Play, TRUE);
       +    break;
       +  case C_MSG:
       +    text = g_strdup_printf("%s: %s", GetPlayerName(From), Data);
       +    display_message(text);
       +    g_free(text);
       +    break;
       +  case C_MSGTO:
       +    text = g_strdup_printf("%s->%s: %s", GetPlayerName(From),
       +                           GetPlayerName(Play), Data);
       +    display_message(text);
       +    g_free(text);
       +    break;
       +  case C_JOIN:
       +    text = g_strdup_printf(_("%s joins the game!"), Data);
       +    display_message(text);
       +    g_free(text);
       +    break;
       +  case C_LEAVE:
       +    if (From != &Noone) {
       +      text = g_strdup_printf(_("%s has left the game."), Data);
       +      display_message(text);
       +      g_free(text);
       +    }
       +    break;
       +  case C_RENAME:
       +    /* Displayed when a player changes his/her name */
       +    text = g_strdup_printf(_("%s will now be known as %s."),
       +                           GetPlayerName(From), Data);
       +    SetPlayerName(From, Data);
       +    mvaddstr(22, 0, text);
       +    g_free(text);
       +    nice_wait();
       +    break;
       +  case C_PRINTMESSAGE:
       +    PrintMessage(Data);
       +    nice_wait();
       +    break;
       +  case C_FIGHTPRINT:
       +    DisplayFightMessage(Play, Data);
       +    break;
       +  case C_SUBWAYFLASH:
       +    DisplayFightMessage(Play, NULL);
       +    for (list = FirstClient; list; list = g_slist_next(list)) {
       +      tmp = (Player *)list->data;
       +      tmp->Flags &= ~FIGHTING;
       +    }
       +    for (i = 0; i < 4; i++) {
       +      print_location(_("S U B W A Y"));
       +      refresh();
       +      MicroSleep(100000);
       +      print_location("");
       +      refresh();
       +      MicroSleep(100000);
       +    }
       +    print_location(Location[(int)Play->IsAt].Name);
       +    break;
       +  case C_QUESTION:
       +    pt = Data;
       +    wrd = GetNextWord(&pt, "");
       +    PrintMessage(pt);
       +    addch(' ');
       +    i = GetKey(_(wrd), wrd, FALSE, TRUE, TRUE);
       +    wrd = g_strdup_printf("%c", i);
       +    SendClientMessage(Play, C_NONE, C_ANSWER,
       +                      From == &Noone ? NULL : From, wrd);
       +    g_free(wrd);
       +    break;
       +  case C_LOANSHARK:
       +    LoanShark(Play);
       +    SendClientMessage(Play, C_NONE, C_DONE, NULL, NULL);
       +    break;
       +  case C_BANK:
       +    Bank(Play);
       +    SendClientMessage(Play, C_NONE, C_DONE, NULL, NULL);
       +    break;
       +  case C_GUNSHOP:
       +    GunShop(Play);
       +    SendClientMessage(Play, C_NONE, C_DONE, NULL, NULL);
       +    break;
       +  case C_UPDATE:
       +    if (From == &Noone) {
       +      ReceivePlayerData(Play, Data, Play);
       +      print_status(Play, TRUE);
       +      refresh();
       +    } else {
       +      DisplaySpyReports(Data, From, Play);
       +    }
       +    break;
       +  case C_NEWNAME:
       +    clear_line(22);
       +    clear_line(23);
       +    attrset(TextAttr);
       +    mvaddstr(22, 0, _("Unfortunately, somebody else is already "
       +                      "using \"your\" name. Please change it."));
       +    change_name(Play, TRUE);
       +    break;
       +  default:
       +    if (!Handled) {
       +      text = g_strdup_printf("%s^%c^%s^%s", GetPlayerName(From), Code,
       +                             GetPlayerName(Play), Data);
       +      mvaddstr(22, 0, text);
       +      g_free(text);
       +      nice_wait();
       +    }
       +    break;
       +  }
       +}
       +
       +/* 
       + * Responds to a "starthiscore" message by clearing the screen and
       + * displaying the title for the high scores screen.
       + */
       +void PrepareHighScoreScreen(void)
       +{
       +  char *text;
       +
       +  attrset(TextAttr);
       +  clear_screen();
       +  attrset(TitleAttr);
       +  text = _("H I G H   S C O R E S");
       +  mvaddstr(0, (Width - strlen(text)) / 2, text);
       +  attrset(TextAttr);
       +}
       +
       +/* 
       + * Prints a high score coded in "Data"; first word is the index of the
       + * score (i.e. y screen coordinate), second word is the text, the first
       + * letter of which identifies whether it's to be printed bold or not.
       + */
       +void PrintHighScore(char *Data)
       +{
       +  char *cp;
       +  int index;
       +
       +  cp = Data;
       +  index = GetNextInt(&cp, 0);
       +  if (!cp || strlen(cp) < 2)
       +    return;
       +  move(index + 2, 0);
       +  attrset(TextAttr);
       +  if (cp[0] == 'B')
       +    standout();
       +  addstr(&cp[1]);
       +  if (cp[0] == 'B')
       +    standend();
       +}
       +
       +/* 
       + * Prints a message "text" received via. a "printmessage" message in the
       + * bottom part of the screen.
       + */
       +void PrintMessage(const gchar *text)
       +{
       +  guint i, line;
       +
       +  attrset(TextAttr);
       +  clear_line(16);
       +
       +  line = 1;
       +  for (i = 0; i < strlen(text) && (text[i] == '^' || text[i] == '\n'); i++)
       +    line++;
       +  clear_exceptfor(line);
       +
       +  line = 17;
       +  move(line, 1);
       +  for (i = 0; i < strlen(text); i++) {
       +    if (text[i] == '^' || text[i] == '\n') {
       +      line++;
       +      move(line, 1);
       +    } else if (text[i] != '\r')
       +      addch((guchar)text[i]);
       +  }
       +}
       +
       +static void SellGun(Player *Play)
       +{
       +  gchar *text;
       +  gint gunind;
       +
       +  clear_line(22);
       +  if (TotalGunsCarried(Play) == 0) {
       +    /* Error - player tried to sell guns that he/she doesn't have
       +     * (%tde="guns" by default) */
       +    text = dpg_strdup_printf(_("You don't have any %tde to sell!"),
       +                             Names.Guns);
       +    mvaddstr(22, (Width - strlen(text)) / 2, text);
       +    g_free(text);
       +    nice_wait();
       +    clear_line(23);
       +  } else {
       +    attrset(PromptAttr);
       +    mvaddstr(22, 20, _("What do you wish to sell? "));
       +    curs_set(1);
       +    attrset(TextAttr);
       +    gunind = bgetch();
       +    gunind = toupper(gunind);
       +    if (gunind >= 'A' && gunind < 'A' + NumGun) {
       +      gunind -= 'A';
       +      addstr(Gun[gunind].Name);
       +      if (Play->Guns[gunind].Carried == 0) {
       +        clear_line(22);
       +        /* Error - player tried to sell some guns that he/she doesn't have */
       +        mvaddstr(22, 10, _("You don't have any to sell!"));
       +        nice_wait();
       +        clear_line(23);
       +      } else {
       +        Play->Cash += Gun[gunind].Price;
       +        Play->CoatSize += Gun[gunind].Space;
       +        Play->Guns[gunind].Carried--;
       +        text = g_strdup_printf("gun^%d^-1", gunind);
       +        SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text);
       +        g_free(text);
       +        print_status(Play, FALSE);
       +      }
       +    }
       +  }
       +}
       +
       +static void BuyGun(Player *Play)
       +{
       +  gchar *text;
       +  gint gunind;
       +
       +  clear_line(22);
       +  if (TotalGunsCarried(Play) >= Play->Bitches.Carried + 2) {
       +    text = dpg_strdup_printf(
       +                              /* Error - player tried to buy more guns
       +                               * than his/her bitches can carry (1st
       +                               * %tde="bitches", 2nd %tde="guns" by
       +                               * default) */
       +                              _("You'll need more %tde to carry "
       +                                "any more %tde!"),
       +                              Names.Bitches, Names.Guns);
       +    mvaddstr(22, (Width - strlen(text)) / 2, text);
       +    g_free(text);
       +    nice_wait();
       +    clear_line(23);
       +  } else {
       +    attrset(PromptAttr);
       +    mvaddstr(22, 20, _("What do you wish to buy? "));
       +    curs_set(1);
       +    attrset(TextAttr);
       +    gunind = bgetch();
       +    gunind = toupper(gunind);
       +    if (gunind >= 'A' && gunind < 'A' + NumGun) {
       +      gunind -= 'A';
       +      addstr(Gun[gunind].Name);
       +      if (Gun[gunind].Space > Play->CoatSize) {
       +        clear_line(22);
       +        /* Error - player tried to buy a gun that he/she doesn't have
       +         * space for (%tde="gun" by default) */
       +        text = dpg_strdup_printf(_("You don't have enough space to "
       +                                   "carry that %tde!"), Names.Gun);
       +        mvaddstr(22, (Width - strlen(text)) / 2, text);
       +        g_free(text);
       +        nice_wait();
       +        clear_line(23);
       +      } else if (Gun[gunind].Price > Play->Cash) {
       +        clear_line(22);
       +        /* Error - player tried to buy a gun that he/she can't afford
       +         * (%tde="gun" by default) */
       +        text = dpg_strdup_printf(_("You don't have enough cash to buy "
       +                                   "that %tde!"), Names.Gun);
       +        mvaddstr(22, (Width - strlen(text)) / 2, text);
       +        g_free(text);
       +        nice_wait();
       +        clear_line(23);
       +      } else {
       +        Play->Cash -= Gun[gunind].Price;
       +        Play->CoatSize -= Gun[gunind].Space;
       +        Play->Guns[gunind].Carried++;
       +        text = g_strdup_printf("gun^%d^1", gunind);
       +        SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text);
       +        g_free(text);
       +        print_status(Play, FALSE);
       +      }
       +    }
       +  }
       +}
       +
       +/* 
       + * Allows player "Play" to buy and sell guns interactively. Passes the
       + * decisions on to the server for sanity checking and implementation.
       + */
       +void GunShop(Player *Play)
       +{
       +  int i, action;
       +  gchar *text;
       +
       +  print_status(Play, FALSE);
       +  attrset(TextAttr);
       +  clear_bottom();
       +  for (i = 0; i < NumGun; i++) {
       +    text =
       +        dpg_strdup_printf("%c. %-22tde %12P", 'A' + i, Gun[i].Name,
       +                          Gun[i].Price);
       +    mvaddstr(17 + i / 2, (i % 2) * 40 + 1, text);
       +    g_free(text);
       +  }
       +  do {
       +    /* Prompt for actions in the gun shop */
       +    text = _("Will you B>uy, S>ell, or L>eave? ");
       +    attrset(PromptAttr);
       +    clear_line(22);
       +    mvaddstr(22, 40 - strlen(text) / 2, text);
       +    attrset(TextAttr);
       +
       +    /* Translate these three keys in line with the above options, keeping
       +     * the order (B>uy, S>ell, L>eave) the same - you can change the
       +     * wording of the prompt, but if you change the order in this key
       +     * list, the keys will do the wrong things! */
       +    action = GetKey(_("BSL"), "BSL", FALSE, FALSE, FALSE);
       +    if (action == 'S')
       +      SellGun(Play);
       +    else if (action == 'B')
       +      BuyGun(Play);
       +  } while (action != 'L');
       +  print_status(Play, TRUE);
       +}
       +
       +/* 
       + * Allows player "Play" to pay off loans interactively.
       + */
       +void LoanShark(Player *Play)
       +{
       +  gchar *text, *prstr;
       +  price_t money;
       +
       +  do {
       +    clear_bottom();
       +    attrset(PromptAttr);
       +
       +    /* Prompt for paying back loans from the loan shark */
       +    text =
       +        nice_input(_("How much money do you pay back? "), 19, 1, TRUE,
       +                   NULL, '\0');
       +    attrset(TextAttr);
       +    money = strtoprice(text);
       +    g_free(text);
       +    if (money < 0)
       +      money = 0;
       +    if (money > Play->Debt)
       +      money = Play->Debt;
       +    if (money > Play->Cash) {
       +      /* Error - player doesn't have enough money to pay back the loan */
       +      mvaddstr(20, 1, _("You don't have that much money!"));
       +      nice_wait();
       +    } else {
       +      SendClientMessage(Play, C_NONE, C_PAYLOAN, NULL,
       +                        (prstr = pricetostr(money)));
       +      g_free(prstr);
       +      money = 0;
       +    }
       +  } while (money != 0);
       +}
       +
       +/* 
       + * Allows player "Play" to pay in or withdraw money from the bank
       + * interactively.
       + */
       +void Bank(Player *Play)
       +{
       +  gchar *text, *prstr;
       +  price_t money = 0;
       +  int action;
       +
       +  do {
       +    clear_bottom();
       +    attrset(PromptAttr);
       +    /* Prompt for dealing with the bank in the curses client */
       +    mvaddstr(18, 1, _("Do you want to D>eposit money, W>ithdraw money, "
       +                      "or L>eave ? "));
       +    attrset(TextAttr);
       +
       +    /* Make sure you keep the order the same if you translate these keys!
       +     * (D>eposit, W>ithdraw, L>eave) */
       +    action = GetKey(_("DWL"), "DWL", FALSE, FALSE, FALSE);
       +
       +    if (action == 'D' || action == 'W') {
       +      /* Prompt for putting money in or taking money out of the bank */
       +      text = nice_input(_("How much money? "), 19, 1, TRUE, NULL, '\0');
       +
       +      money = strtoprice(text);
       +      g_free(text);
       +      if (money < 0)
       +        money = 0;
       +      if (action == 'W')
       +        money = -money;
       +      if (money > Play->Cash) {
       +        /* Error - player has tried to put more money into the bank than
       +         * he/she has */
       +        mvaddstr(20, 1, _("You don't have that much money!"));
       +        nice_wait();
       +      } else if (-money > Play->Bank) {
       +        /* Error - player has tried to withdraw more money from the bank
       +         * than there is in the account */
       +        mvaddstr(20, 1, _("There isn't that much money in the bank..."));
       +        nice_wait();
       +      } else if (money != 0) {
       +        SendClientMessage(Play, C_NONE, C_DEPOSIT, NULL,
       +                          (prstr = pricetostr(money)));
       +        g_free(prstr);
       +        money = 0;
       +      }
       +    }
       +  } while (action != 'L' && money != 0);
       +}
       +
       +/* 
       + * Waits for keyboard input; will only accept a key listed in the
       + * "allowed" string. This string may have been translated; thus
       + * the "orig_allowed" string contains the untranslated keys.
       + * Returns the untranslated key corresponding to the key pressed
       + * (e.g. if allowed[2] is pressed, orig_allowed[2] is returned)
       + * Case insensitive. If "AllowOther" is TRUE, keys other than the
       + * given selection are allowed, and cause a zero return value.
       + * If "PrintAllowed" is TRUE, the allowed keys are printed after
       + * the prompt. If "ExpandOut" is also TRUE, the full words for
       + * the commands, rather than just their first letters, are displayed.
       + */
       +int GetKey(char *allowed, char *orig_allowed, gboolean AllowOther,
       +           gboolean PrintAllowed, gboolean ExpandOut)
       +{
       +  int ch;
       +  guint AllowInd, WordInd, i;
       +
       +  /* Expansions of the single-letter keypresses for the benefit of the
       +   * user. i.e. "Yes" is printed for the key "Y" etc. You should indicate
       +   * to the user which letter in the word corresponds to the keypress, by
       +   * capitalising it or similar. */
       +  gchar *Words[] = { N_("Y:Yes"), N_("N:No"), N_("R:Run"),
       +    N_("F:Fight"), N_("A:Attack"), N_("E:Evade")
       +  };
       +  guint numWords = sizeof(Words) / sizeof(Words[0]);
       +  gchar *trWord;
       +
       +  curs_set(1);
       +  ch = '\0';
       +
       +  if (!allowed || strlen(allowed) == 0)
       +    return 0;
       +
       +  if (PrintAllowed) {
       +    addch('[' | TextAttr);
       +    for (AllowInd = 0; AllowInd < strlen(allowed); AllowInd++) {
       +      if (AllowInd > 0)
       +        addch('/' | TextAttr);
       +      WordInd = 0;
       +      while (WordInd < numWords &&
       +             orig_allowed[AllowInd] != Words[WordInd][0])
       +        WordInd++;
       +
       +      if (ExpandOut && WordInd < numWords) {
       +        trWord = _(Words[WordInd]);
       +        for (i = 2; i < strlen(trWord); i++)
       +          addch((guchar)trWord[i] | TextAttr);
       +      } else
       +        addch((guchar)allowed[AllowInd] | TextAttr);
       +    }
       +    addch(']' | TextAttr);
       +    addch(' ' | TextAttr);
       +  }
       +
       +  do {
       +    ch = bgetch();
       +    ch = toupper(ch);
       +    for (AllowInd = 0; AllowInd < strlen(allowed); AllowInd++) {
       +      if (allowed[AllowInd] == ch) {
       +        addch((guint)ch | TextAttr);
       +        curs_set(0);
       +        return orig_allowed[AllowInd];
       +      }
       +    }
       +  } while (!AllowOther);
       +
       +  curs_set(0);
       +  return 0;
       +}
       +
       +/* 
       + * Clears one whole line on the curses screen.
       + */
       +void clear_line(int line)
       +{
       +  int i;
       +
       +  move(line, 0);
       +  for (i = 0; i < Width; i++)
       +    addch(' ');
       +}
       +
       +/* 
       + * Clears the bottom of the screen (i.e. from line 16 to line 23)
       + * except for the top "skip" lines.
       + */
       +void clear_exceptfor(int skip)
       +{
       +  int i;
       +
       +  for (i = 16 + skip; i <= 23; i++)
       +    clear_line(i);
       +}
       +
       +
       +/* 
       + * Clears screen lines 16 to 23.
       + */
       +void clear_bottom(void)
       +{
       +  int i;
       +
       +  for (i = 16; i <= 23; i++)
       +    clear_line(i);
       +}
       +
       +/* 
       + * Clears the entire screen; 24 lines of 80 characters each.
       + */
       +void clear_screen(void)
       +{
       +  int i;
       +
       +  for (i = 0; i < Depth; i++)
       +    clear_line(i);
       +}
       +
       +/* 
       + * Displays a prompt on the bottom screen line and waits for the user
       + * to press a key.
       + */
       +void nice_wait()
       +{
       +  gchar *text;
       +
       +  attrset(PromptAttr);
       +  text = _("Press any key...");
       +  mvaddstr(23, (Width - strlen(text)) / 2, text);
       +  bgetch();
       +  attrset(TextAttr);
       +}
       +
       +/* 
       + * Handles the display of messages pertaining to player-player fights
       + * in the lower part of screen (fighting sub-screen). Adds the new line
       + * of text in "text" and scrolls up previous messages if necessary
       + * If "text" is NULL, initialises the area
       + * If "text" is a blank string, redisplays the message area
       + * Messages are displayed from lines 16 to 20; line 22 is used for
       + * the prompt for the user.
       + */
       +void DisplayFightMessage(Player *Play, char *text)
       +{
       +  static char Messages[5][79];
       +  static int x, y;
       +  gchar *textpt;
       +  gchar *AttackName, *DefendName, *BitchName;
       +  gint i, DefendHealth, DefendBitches, BitchesKilled, ArmPercent;
       +  gboolean Loot;
       +
       +  if (text == NULL) {
       +    x = 0;
       +    y = 15;
       +    for (i = 0; i < 5; i++)
       +      Messages[i][0] = '\0';
       +  } else if (!text[0]) {
       +    attrset(TextAttr);
       +    clear_bottom();
       +    for (i = 16; i <= 20; i++)
       +      mvaddstr(i, 1, Messages[i - 16]);
       +  } else {
       +    if (HaveAbility(Play, A_NEWFIGHT)) {
       +      ReceiveFightMessage(text, &AttackName, &DefendName, &DefendHealth,
       +                          &DefendBitches, &BitchName, &BitchesKilled,
       +                          &ArmPercent, &fp, &RunHere, &Loot, &CanFire,
       +                          &textpt);
       +    } else {
       +      textpt = text;
       +      if (Play->Flags & FIGHTING)
       +        fp = F_MSG;
       +      else
       +        fp = F_LASTLEAVE;
       +      CanFire = (Play->Flags & CANSHOOT);
       +      RunHere = FALSE;
       +    }
       +    while (textpt[0]) {
       +      if (y < 20)
       +        y++;
       +      else
       +        for (i = 0; i < 4; i++)
       +          strcpy(Messages[i], Messages[i + 1]);
       +
       +      strncpy(Messages[y - 16], textpt, 78);
       +      Messages[y - 16][78] = '\0';
       +      textpt += MIN(strlen(textpt), 78);
       +    }
       +  }
       +}
       +
       +/* 
       + * Displays a network message "buf" in the message area (lines
       + * 10 to 14) scrolling previous messages up.
       + * If "buf" is NULL, clears the message area
       + * If "buf" is a blank string, redisplays the message area
       + */
       +void display_message(char *buf)
       +{
       +  guint x, y;
       +  guint wid;
       +  static gchar Messages[5][200];
       +  gchar *bufpt;
       +
       +  if (Width <= 4)
       +    return;
       +
       +  wid = MIN(Width - 4, 200);
       +
       +  if (!buf) {
       +    for (y = 0; y < 5; y++) {
       +      memset(Messages[y], ' ', 200);
       +      if (Network) {
       +        mvaddch(y + 10, 0, ' ' | TextAttr);
       +        addch(ACS_VLINE | StatsAttr);
       +        for (x = 0; x < wid; x++)
       +          addch(' ' | StatsAttr);
       +        addch(ACS_VLINE | StatsAttr);
       +        addch(' ' | TextAttr);
       +      }
       +    }
       +  } else if (Network) {
       +    bufpt = buf;
       +    while (bufpt[0] != 0) {
       +      memmove(Messages[0], Messages[1], 200 * 4);
       +      memset(Messages[4], ' ', 200);
       +      memcpy(Messages[4], bufpt,
       +             strlen(bufpt) > wid ? wid : strlen(bufpt));
       +      bufpt += MIN(strlen(bufpt), wid);
       +    }
       +    for (y = 0; y < 5; y++)
       +      for (x = 0; x < wid; x++) {
       +        mvaddch(y + 10, x + 2, (guchar)Messages[y][x] | StatsAttr);
       +      }
       +    refresh();
       +  }
       +}
       +
       +/* 
       + * Displays the string "text" at the top of the screen. Usually used for
       + * displaying the current location or the "Subway" flash.
       + */
       +void print_location(char *text)
       +{
       +  int i;
       +
       +  if (!text)
       +    return;
       +  attrset(LocationAttr);
       +  move(0, Width / 2 - 9);
       +  for (i = 0; i < 18; i++)
       +    addch(' ');
       +  mvaddstr(0, (Width - strlen(text)) / 2, text);
       +  attrset(TextAttr);
       +}
       +
       +/* 
       + * Displays the status of player "Play" - i.e. the current turn, the
       + * location, bitches, available space, cash, guns, health and bank
       + * details. If "DispDrugs" is TRUE, displays the carried drugs on the
       + * right hand side of the screen; if FALSE, displays the carried guns.
       + */
       +void print_status(Player *Play, gboolean DispDrug)
       +{
       +  int i, c;
       +  GString *text;
       +
       +  text = g_string_new(NULL);
       +  attrset(TitleAttr);
       +  clear_line(0);
       +  g_string_sprintf(text, "%s%02d%s", Names.Month, Play->Turn, Names.Year);
       +  mvaddstr(0, 3, text->str);
       +
       +  attrset(StatsAttr);
       +  for (i = 2; i <= 14; i++) {
       +    mvaddch(i, 1, ACS_VLINE);
       +    mvaddch(i, Width - 2, ACS_VLINE);
       +  }
       +  mvaddch(1, 1, ACS_ULCORNER);
       +  for (i = 0; i < Width - 4; i++)
       +    addch(ACS_HLINE);
       +  addch(ACS_URCORNER);
       +
       +  mvaddch(1, Width / 2, ACS_TTEE);
       +  for (i = 2; i <= (Network ? 8 : 13); i++) {
       +    move(i, 2);
       +    for (c = 2; c < Width / 2; c++)
       +      addch(' ');
       +    addch(ACS_VLINE);
       +    for (c = Width / 2 + 1; c < Width - 2; c++)
       +      addch(' ');
       +  }
       +  if (!Network) {
       +    mvaddch(14, 1, ACS_LLCORNER);
       +    for (i = 0; i < Width - 4; i++)
       +      addch(ACS_HLINE);
       +    addch(ACS_LRCORNER);
       +    mvaddch(14, Width / 2, ACS_BTEE);
       +  } else {
       +    mvaddch(9, 1, ACS_LTEE);
       +    for (i = 0; i < Width - 4; i++)
       +      addch(ACS_HLINE);
       +    addch(ACS_RTEE);
       +
       +    /* Title of the "Messages" window in the curses client */
       +    mvaddstr(9, 15, _("Messages"));
       +
       +    mvaddch(9, Width / 2, ACS_BTEE);
       +    mvaddch(15, 1, ACS_LLCORNER);
       +    for (i = 0; i < Width - 4; i++)
       +      addch(ACS_HLINE);
       +    addch(ACS_LRCORNER);
       +  }
       +
       +  /* Title of the "Stats" window in the curses client */
       +  mvaddstr(1, Width / 4 - 2, _("Stats"));
       +
       +  attrset(StatsAttr);
       +
       +  /* Display of the player's cash in the stats window (careful to keep the
       +   * formatting if you change the length of the "Cash" word) */
       +  dpg_string_sprintf(text, _("Cash %17P"), Play->Cash);
       +  mvaddstr(3, 9, text->str);
       +
       +  /* Display of the total number of guns carried (%Tde="Guns" by default) */
       +  dpg_string_sprintf(text, _("%-19Tde%3d"), Names.Guns,
       +                     TotalGunsCarried(Play));
       +  mvaddstr(Network ? 4 : 5, 9, text->str);
       +
       +  /* Display of the player's health */
       +  g_string_sprintf(text, _("Health             %3d"), Play->Health);
       +  mvaddstr(Network ? 5 : 7, 9, text->str);
       +
       +  /* Display of the player's bank balance */
       +  dpg_string_sprintf(text, _("Bank %17P"), Play->Bank);
       +  mvaddstr(Network ? 6 : 9, 9, text->str);
       +
       +  if (Play->Debt > 0)
       +    attrset(DebtAttr);
       +  /* Display of the player's debt */
       +  dpg_string_sprintf(text, _("Debt %17P"), Play->Debt);
       +  mvaddstr(Network ? 7 : 11, 9, text->str);
       +  attrset(TitleAttr);
       +
       +  /* Display of the player's trenchcoat size (antique mode only) */
       +  if (WantAntique)
       +    g_string_sprintf(text, _("Space %6d"), Play->CoatSize);
       +  else {
       +    /* Display of the player's number of bitches, and available space
       +     * (%Tde="Bitches" by default) */
       +    dpg_string_sprintf(text, _("%Tde %3d  Space %6d"), Names.Bitches,
       +                       Play->Bitches.Carried, Play->CoatSize);
       +  }
       +  mvaddstr(0, Width - 2 - strlen(text->str), text->str);
       +  print_location(Location[(int)Play->IsAt].Name);
       +  attrset(StatsAttr);
       +
       +  c = 0;
       +  if (DispDrug) {
       +    /* Title of the "trenchcoat" window (antique mode only) */
       +    if (WantAntique)
       +      mvaddstr(1, Width * 3 / 4 - 5, _("Trenchcoat"));
       +    else {
       +      /* Title of the "drugs" window (the only important bit in this
       +       * string is the "%Tde" which is "Drugs" by default; the %/.../ part 
       +       * is ignored, so you don't need to translate it; see doc/i18n.html) 
       +       */
       +      dpg_string_sprintf(text, _("%/Stats: Drugs/%Tde"), Names.Drugs);
       +      mvaddstr(1, Width * 3 / 4 - strlen(text->str) / 2, text->str);
       +    }
       +    for (i = 0; i < NumDrug; i++) {
       +      if (Play->Drugs[i].Carried > 0) {
       +        /* Display of carried drugs with price (%tde="Opium", etc. by
       +         * default) */
       +        if (HaveAbility(Play, A_DRUGVALUE)) {
       +          dpg_string_sprintf(text, _("%-7tde  %3d @ %P"), Drug[i].Name,
       +                             Play->Drugs[i].Carried,
       +                             Play->Drugs[i].TotalValue /
       +                             Play->Drugs[i].Carried);
       +          mvaddstr(3 + c, Width / 2 + 3, text->str);
       +        } else {
       +          /* Display of carried drugs (%tde="Opium", etc. by default) */
       +          dpg_string_sprintf(text, _("%-7tde  %3d"), Drug[i].Name,
       +                             Play->Drugs[i].Carried);
       +          mvaddstr(3 + c / 2, Width / 2 + 3 + (c % 2) * 17, text->str);
       +        }
       +        c++;
       +      }
       +    }
       +  } else {
       +    /* Title of the "guns" window (the only important bit in this string
       +     * is the "%Tde" which is "Guns" by default) */
       +    dpg_string_sprintf(text, _("%/Stats: Guns/%Tde"), Names.Guns);
       +    mvaddstr(1, Width * 3 / 4 - strlen(text->str) / 2, text->str);
       +    for (i = 0; i < NumGun; i++) {
       +      if (Play->Guns[i].Carried > 0) {
       +        /* Display of carried guns (%tde="Baretta", etc. by default) */
       +        dpg_string_sprintf(text, _("%-22tde %3d"), Gun[i].Name,
       +                           Play->Guns[i].Carried);
       +        mvaddstr(3 + c, Width / 2 + 3, text->str);
       +        c++;
       +      }
       +    }
       +  }
       +  attrset(TextAttr);
       +  if (!Network)
       +    clear_line(15);
       +  refresh();
       +  g_string_free(text, TRUE);
       +}
       +
       +/* 
       + * Parses details about player "From" from string "Data" and then
       + * displays the lot, drugs and guns.
       + */
       +void DisplaySpyReports(char *Data, Player *From, Player *To)
       +{
       +  gchar *text;
       +
       +  ReceivePlayerData(To, Data, From);
       +
       +  clear_bottom();
       +  text = g_strdup_printf(_("Spy reports for %s"), GetPlayerName(From));
       +  mvaddstr(17, 1, text);
       +  g_free(text);
       +
       +  /* Message displayed with a spy's list of drugs (%Tde="Drugs" by
       +   * default) */
       +  text = dpg_strdup_printf(_("%/Spy: Drugs/%Tde..."), Names.Drugs);
       +  mvaddstr(19, 20, text);
       +  g_free(text);
       +  print_status(From, TRUE);
       +  nice_wait();
       +  clear_line(19);
       +
       +  /* Message displayed with a spy's list of guns (%Tde="Guns" by default) */
       +  text = dpg_strdup_printf(_("%/Spy: Guns/%Tde..."), Names.Guns);
       +  mvaddstr(19, 20, text);
       +  g_free(text);
       +  print_status(From, FALSE);
       +  nice_wait();
       +
       +  print_status(To, TRUE);
       +  refresh();
       +}
       +
       +/* 
       + * Displays the "Prompt" if non-NULL, and then lists all clients
       + * currently playing dopewars, other than the current player "Play".
       + * If "Select" is TRUE, gives each player a letter and asks the user
       + * to select one, which is returned by the function.
       + */
       +Player *ListPlayers(Player *Play, gboolean Select, char *Prompt)
       +{
       +  Player *tmp = NULL;
       +  GSList *list;
       +  int i, c;
       +  gchar *text;
       +
       +  attrset(TextAttr);
       +  clear_bottom();
       +  if (!FirstClient || (!g_slist_next(FirstClient) &&
       +                       FirstClient->data == Play)) {
       +    text = _("No other players are currently logged on!");
       +    mvaddstr(18, (Width - strlen(text)) / 2, text);
       +    nice_wait();
       +    return 0;
       +  }
       +  mvaddstr(16, 1, _("Players currently logged on:-"));
       +
       +  i = 0;
       +  for (list = FirstClient; list; list = g_slist_next(list)) {
       +    tmp = (Player *)list->data;
       +    if (strcmp(GetPlayerName(tmp), GetPlayerName(Play)) == 0)
       +      continue;
       +    if (Select)
       +      text = g_strdup_printf("%c. %s", 'A' + i, GetPlayerName(tmp));
       +    else
       +      text = g_strdup(GetPlayerName(tmp));
       +    mvaddstr(17 + i / 2, (i % 2) * 40 + 1, text);
       +    g_free(text);
       +    i++;
       +  }
       +
       +  if (Prompt) {
       +    attrset(PromptAttr);
       +    mvaddstr(22, 10, Prompt);
       +    attrset(TextAttr);
       +  }
       +  if (Select) {
       +    curs_set(1);
       +    attrset(TextAttr);
       +    c = 0;
       +    while (c < 'A' || c >= 'A' + i) {
       +      c = bgetch();
       +      c = toupper(c);
       +    }
       +    if (Prompt)
       +      addch((guint)c);
       +    list = FirstClient;
       +    while (c >= 'A') {
       +      if (list != FirstClient)
       +        list = g_slist_next(list);
       +      tmp = (Player *)list->data;
       +      while (strcmp(GetPlayerName(tmp), GetPlayerName(Play)) == 0) {
       +        list = g_slist_next(list);
       +        tmp = (Player *)list->data;
       +      }
       +      c--;
       +    }
       +    return tmp;
       +  } else {
       +    nice_wait();
       +  }
       +  return NULL;
       +}
       +
       +/* 
       + * Displays the given "prompt" (if non-NULL) at coordinates sx,sy and
       + * allows the user to input a string, which is returned. This is a
       + * dynamically allocated string, and so must be freed by the calling
       + * routine. If "digitsonly" is TRUE, the user will be permitted only to
       + * input numbers, although the suffixes m and k are allowed (the
       + * strtoprice routine understands this notation for a 1000000 or 1000
       + * multiplier) as well as a decimal point (. or ,)
       + * If "displaystr" is non-NULL, it is taken as a default response.
       + * If "passwdchar" is non-zero, it is displayed instead of the user's
       + * keypresses (e.g. for entering passwords)
       + */
       +char *nice_input(char *prompt, int sy, int sx, gboolean digitsonly,
       +                 char *displaystr, char passwdchar)
       +{
       +  int i, c, x;
       +  gboolean DecimalPoint, Suffix;
       +  GString *text;
       +  gchar *ReturnString;
       +
       +  DecimalPoint = Suffix = FALSE;
       +
       +  x = sx;
       +  move(sy, x);
       +  if (prompt) {
       +    attrset(PromptAttr);
       +    addstr(prompt);
       +    x += strlen(prompt);
       +  }
       +  attrset(TextAttr);
       +  if (displaystr) {
       +    if (passwdchar) {
       +      for (i = strlen(displaystr); i; i--)
       +        addch((guint)passwdchar);
       +    } else {
       +      addstr(displaystr);
       +    }
       +    i = strlen(displaystr);
       +    text = g_string_new(displaystr);
       +  } else {
       +    i = 0;
       +    text = g_string_new("");
       +  }
       +
       +  curs_set(1);
       +  do {
       +    move(sy + (x + i) / Width, (x + i) % Width);
       +    c = bgetch();
       +    if ((c == 8 || c == KEY_BACKSPACE || c == 127) && i > 0) {
       +      move(sy + (x + i - 1) / Width, (x + i - 1) % Width);
       +      addch(' ');
       +      i--;
       +      if (DecimalPoint && text->str[i] == '.')
       +        DecimalPoint = FALSE;
       +      if (Suffix)
       +        Suffix = FALSE;
       +      g_string_truncate(text, i);
       +    } else if (!Suffix) {
       +      if ((digitsonly && c >= '0' && c <= '9') ||
       +          (!digitsonly && c >= 32 && c != '^' && c < 127)) {
       +        g_string_append_c(text, c);
       +        i++;
       +        addch((guint)passwdchar ? passwdchar : c);
       +      } else if (digitsonly && (c == '.' || c == ',') && !DecimalPoint) {
       +        g_string_append_c(text, '.');
       +        i++;
       +        addch((guint)passwdchar ? passwdchar : c);
       +        DecimalPoint = TRUE;
       +      } else if (digitsonly
       +                 && (c == 'M' || c == 'm' || c == 'k' || c == 'K')
       +                 && !Suffix) {
       +        g_string_append_c(text, c);
       +        i++;
       +        addch((guint)passwdchar ? passwdchar : c);
       +        Suffix = TRUE;
       +      }
       +    }
       +  } while (c != '\n' && c != KEY_ENTER);
       +  curs_set(0);
       +  move(sy, x);
       +  ReturnString = text->str;
       +  g_string_free(text, FALSE);   /* Leave the buffer to return */
       +  return ReturnString;
       +}
       +
       +/* 
       + * Loop which handles the user playing an interactive game (i.e. "Play"
       + * is a client connected to a server, either locally or remotely)
       + * dopewars is essentially server-driven, so this loop simply has to
       + * make the screen look pretty, respond to user keypresses, and react
       + * to messages from the server.
       + */
       +static void Curses_DoGame(Player *Play)
       +{
       +  gchar *buf, *OldName, *TalkMsg;
       +  GString *text;
       +  int i, c;
       +  char IsCarrying;
       +
       +#if NETWORKING || HAVE_SELECT
       +  fd_set readfs;
       +#endif
       +#ifdef NETWORKING
       +  fd_set writefs;
       +  gboolean DoneOK;
       +  gchar *pt;
       +  gboolean justconnected = FALSE;
       +#endif
       +  int NumDrugsHere;
       +  int MaxSock;
       +  char HaveWorthless;
       +  Player *tmp;
       +  struct sigaction sact;
       +
       +  DisplayMode = DM_NONE;
       +  QuitRequest = FALSE;
       +
       +  ResizedFlag = 0;
       +  sact.sa_handler = ResizeHandle;
       +  sact.sa_flags = 0;
       +  sigemptyset(&sact.sa_mask);
       +  if (sigaction(SIGWINCH, &sact, NULL) == -1) {
       +    g_warning(_("Cannot install SIGWINCH interrupt handler!"));
       +  }
       +  OldName = g_strdup(GetPlayerName(Play));
       +  attrset(TextAttr);
       +  clear_screen();
       +  display_message(NULL);
       +  DisplayFightMessage(Play, NULL);
       +  print_status(Play, TRUE);
       +
       +  attrset(TextAttr);
       +  clear_bottom();
       +  buf = NULL;
       +  do {
       +    g_free(buf);
       +    buf =
       +        nice_input(_("Hey dude, what's your name? "), 17, 1, FALSE,
       +                   OldName, '\0');
       +  } while (buf[0] == 0);
       +#if NETWORKING
       +  if (WantNetwork) {
       +    if (!ConnectToServer(Play)) {
       +      end_curses();
       +      exit(1);
       +    }
       +    justconnected = TRUE;
       +  }
       +#endif /* NETWORKING */
       +  print_status(Play, TRUE);
       +  display_message("");
       +
       +  InitAbilities(Play);
       +  SendAbilities(Play);
       +  SetPlayerName(Play, buf);
       +  SendNullClientMessage(Play, C_NONE, C_NAME, NULL, buf);
       +  g_free(buf);
       +  g_free(OldName);
       +
       +  text = g_string_new("");
       +
       +  while (1) {
       +    if (Play->Health == 0)
       +      DisplayMode = DM_NONE;
       +    HaveWorthless = 0;
       +    IsCarrying = 0;
       +    for (i = 0; i < NumDrug; i++) {
       +      if (Play->Drugs[i].Carried > 0) {
       +        IsCarrying = 1;
       +        if (Play->Drugs[i].Price == 0)
       +          HaveWorthless = 1;
       +      }
       +    }
       +    switch (DisplayMode) {
       +    case DM_STREET:
       +      attrset(TextAttr);
       +      NumDrugsHere = 0;
       +      for (i = 0; i < NumDrug; i++)
       +        if (Play->Drugs[i].Price > 0)
       +          NumDrugsHere++;
       +      clear_bottom();
       +      /* Display of drug prices (%tde="drugs" by default) */
       +      dpg_string_sprintf(text, _("Hey dude, the prices of %tde here are:"),
       +                         Names.Drugs);
       +      mvaddstr(16, 1, text->str);
       +      for (c = 0, i = GetNextDrugIndex(-1, Play);
       +           c < NumDrugsHere && i != -1;
       +           c++, i = GetNextDrugIndex(i, Play)) {
       +        /* List of individual drug names for selection (%tde="Opium" etc.
       +         * by default) */
       +        dpg_string_sprintf(text, _("%c. %-10tde %8P"), 'A' + c,
       +                           Drug[i].Name, Play->Drugs[i].Price);
       +        mvaddstr(17 + c / 3, (c % 3) * 25 + 4, text->str);
       +      }
       +      attrset(PromptAttr);
       +      /* Prompts for "normal" actions in curses client */
       +      g_string_assign(text, _("Will you B>uy"));
       +      if (IsCarrying)
       +        g_string_append(text, _(", S>ell"));
       +      if (HaveWorthless && !WantAntique)
       +        g_string_append(text, _(", D>rop"));
       +      if (Network)
       +        g_string_append(text, _(", T>alk, P>age, L>ist"));
       +      if (!WantAntique && (Play->Bitches.Carried > 0 ||
       +                           Play->Flags & SPYINGON)) {
       +        g_string_append(text, _(", G>ive"));
       +      }
       +      if (Play->Flags & FIGHTING) {
       +        g_string_append(text, _(", F>ight"));
       +      } else {
       +        g_string_append(text, _(", J>et"));
       +      }
       +      g_string_append(text, _(", or Q>uit? "));
       +      mvaddstr(22, 40 - strlen(text->str) / 2, text->str);
       +      attrset(TextAttr);
       +      curs_set(1);
       +      break;
       +    case DM_FIGHT:
       +      DisplayFightMessage(Play, "");
       +      attrset(PromptAttr);
       +      /* Prompts for actions during fights in curses client */
       +      g_string_assign(text, _("Do you "));
       +      if (CanFire) {
       +        if (TotalGunsCarried(Play) > 0) {
       +          g_string_append(text, _("F>ight, "));
       +        } else {
       +          g_string_append(text, _("S>tand, "));
       +        }
       +      }
       +      if (fp != F_LASTLEAVE)
       +        g_string_append(text, _("R>un, "));
       +      if (!RunHere || fp == F_LASTLEAVE)
       +        /* (%tde = "drugs" by default here) */
       +        dpg_string_sprintfa(text, _("D>eal %tde, "), Names.Drugs);
       +      g_string_append(text, _("or Q>uit? "));
       +      mvaddstr(22, 40 - strlen(text->str) / 2, text->str);
       +      attrset(TextAttr);
       +      curs_set(1);
       +      break;
       +    case DM_DEAL:
       +      attrset(TextAttr);
       +      clear_bottom();
       +      mvaddstr(16, 1, "Your trade:-");
       +      mvaddstr(19, 1, "His trade:-");
       +      g_string_assign(text, "Do you A>dd, R>emove, O>K, D>eal ");
       +      g_string_append(text, Names.Drugs);
       +      g_string_append(text, ", or Q>uit? ");
       +      attrset(PromptAttr);
       +      mvaddstr(22, 40 - strlen(text->str) / 2, text->str);
       +      attrset(TextAttr);
       +      curs_set(1);
       +      break;
       +    case DM_NONE:
       +      break;
       +    }
       +    refresh();
       +
       +    if (QuitRequest)
       +      return;
       +#if NETWORKING
       +    FD_ZERO(&readfs);
       +    FD_ZERO(&writefs);
       +    FD_SET(0, &readfs);
       +    MaxSock = 1;
       +    if (Client) {
       +      if (justconnected) {
       +        /* Deal with any messages that came in while we were connect()ing */
       +        justconnected = FALSE;
       +        while ((pt = GetWaitingPlayerMessage(Play)) != NULL) {
       +          HandleClientMessage(pt, Play);
       +          g_free(pt);
       +        }
       +        if (QuitRequest)
       +          return;
       +      }
       +      SetSelectForNetworkBuffer(&Play->NetBuf, &readfs, &writefs,
       +                                NULL, &MaxSock);
       +    }
       +    if (bselect(MaxSock, &readfs, &writefs, NULL, NULL) == -1) {
       +      if (errno == EINTR) {
       +        CheckForResize(Play);
       +        continue;
       +      }
       +      perror("bselect");
       +      exit(1);
       +    }
       +    if (Client) {
       +      if (RespondToSelect(&Play->NetBuf, &readfs, &writefs, NULL, &DoneOK)) {
       +        while ((pt = GetWaitingPlayerMessage(Play)) != NULL) {
       +          HandleClientMessage(pt, Play);
       +          g_free(pt);
       +        }
       +        if (QuitRequest)
       +          return;
       +      }
       +      if (!DoneOK) {
       +        attrset(TextAttr);
       +        clear_line(22);
       +        mvaddstr(22, 0, _("Connection to server lost! "
       +                          "Reverting to single player mode"));
       +        nice_wait();
       +        SwitchToSinglePlayer(Play);
       +        print_status(Play, TRUE);
       +      }
       +    }
       +    if (FD_ISSET(0, &readfs)) {
       +#elif HAVE_SELECT
       +    FD_ZERO(&readfs);
       +    FD_SET(0, &readfs);
       +    MaxSock = 1;
       +    if (bselect(MaxSock, &readfs, NULL, NULL, NULL) == -1) {
       +      if (errno == EINTR) {
       +        CheckForResize(Play);
       +        continue;
       +      }
       +      perror("bselect");
       +      exit(1);
       +    }
       +#endif /* NETWORKING */
       +    if (DisplayMode == DM_STREET) {
       +      /* N.B. You must keep the order of these keys the same as the
       +       * original when you translate (B>uy, S>ell, D>rop, T>alk, P>age,
       +       * L>ist, G>ive errand, F>ight, J>et, Q>uit) */
       +      c = GetKey(_("BSDTPLGFJQ"), "BSDTPLGFJQ", TRUE, FALSE, FALSE);
       +
       +    } else if (DisplayMode == DM_FIGHT) {
       +      /* N.B. You must keep the order of these keys the same as the
       +       * original when you translate (D>eal drugs, R>un, F>ight, S>tand,
       +       * Q>uit) */
       +      c = GetKey(_("DRFSQ"), "DRFSQ", TRUE, FALSE, FALSE);
       +
       +    } else
       +      c = 0;
       +#if ! (NETWORKING || HAVE_SELECT)
       +    CheckForResize(Play);
       +#endif
       +    if (DisplayMode == DM_STREET) {
       +      if (c == 'J' && !(Play->Flags & FIGHTING)) {
       +        jet(Play, TRUE);
       +      } else if (c == 'F' && Play->Flags & FIGHTING) {
       +        DisplayMode = DM_FIGHT;
       +      } else if (c == 'T' && Play->Flags & TRADING) {
       +        DisplayMode = DM_DEAL;
       +      } else if (c == 'B') {
       +        DealDrugs(Play, TRUE);
       +      } else if (c == 'S' && IsCarrying) {
       +        DealDrugs(Play, FALSE);
       +      } else if (c == 'D' && HaveWorthless && !WantAntique) {
       +        DropDrugs(Play);
       +      } else if (c == 'G' && !WantAntique && Play->Bitches.Carried > 0) {
       +        GiveErrand(Play);
       +      } else if (c == 'Q') {
       +        if (want_to_quit() == 1) {
       +          DisplayMode = DM_NONE;
       +          clear_bottom();
       +          SendClientMessage(Play, C_NONE, C_WANTQUIT, NULL, NULL);
       +        }
       +      } else if (c == 'L' && Network) {
       +        attrset(PromptAttr);
       +        mvaddstr(23, 20, _("List what? P>layers or S>cores? "));
       +        /* P>layers, S>cores */
       +        i = GetKey(_("PS"), "PS", TRUE, FALSE, FALSE);
       +        if (i == 'P') {
       +          ListPlayers(Play, FALSE, NULL);
       +        } else if (i == 'S') {
       +          DisplayMode = DM_NONE;
       +          SendClientMessage(Play, C_NONE, C_REQUESTSCORE, NULL, NULL);
       +        }
       +      } else if (c == 'P' && Network) {
       +        tmp = ListPlayers(Play, TRUE,
       +                          _("Whom do you want to page "
       +                            "(talk privately to) ? "));
       +        if (tmp) {
       +          attrset(TextAttr);
       +          clear_line(22);
       +          /* Prompt for sending player-player messages */
       +          TalkMsg = nice_input(_("Talk: "), 22, 0, FALSE, NULL, '\0');
       +          if (TalkMsg[0]) {
       +            SendClientMessage(Play, C_NONE, C_MSGTO, tmp, TalkMsg);
       +            buf = g_strdup_printf("%s->%s: %s", GetPlayerName(Play),
       +                                  GetPlayerName(tmp), TalkMsg);
       +            display_message(buf);
       +            g_free(buf);
       +          }
       +          g_free(TalkMsg);
       +        }
       +      } else if (c == 'T' && Client) {
       +        attrset(TextAttr);
       +        clear_line(22);
       +        TalkMsg = nice_input(_("Talk: "), 22, 0, FALSE, NULL, '\0');
       +        if (TalkMsg[0]) {
       +          SendClientMessage(Play, C_NONE, C_MSG, NULL, TalkMsg);
       +          buf = g_strdup_printf("%s: %s", GetPlayerName(Play), TalkMsg);
       +          display_message(buf);
       +          g_free(buf);
       +        }
       +        g_free(TalkMsg);
       +      }
       +    } else if (DisplayMode == DM_FIGHT) {
       +      switch (c) {
       +      case 'D':
       +        DisplayMode = DM_STREET;
       +        break;
       +      case 'R':
       +        if (RunHere) {
       +          SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, "R");
       +        } else {
       +          jet(Play, TRUE);
       +        }
       +        break;
       +      case 'F':
       +        if (TotalGunsCarried(Play) > 0 && CanFire) {
       +          buf = g_strdup_printf("%c", c);
       +          Play->Flags &= ~CANSHOOT;
       +          SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, buf);
       +          g_free(buf);
       +        }
       +        break;
       +      case 'S':
       +        if (TotalGunsCarried(Play) == 0 && CanFire) {
       +          buf = g_strdup_printf("%c", c);
       +          Play->Flags &= ~CANSHOOT;
       +          SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, buf);
       +          g_free(buf);
       +        }
       +        break;
       +      case 'Q':
       +        if (want_to_quit() == 1) {
       +          DisplayMode = DM_NONE;
       +          clear_bottom();
       +          SendClientMessage(Play, C_NONE, C_WANTQUIT, NULL, NULL);
       +        }
       +        break;
       +      }
       +    } else if (DisplayMode == DM_DEAL) {
       +      switch (c) {
       +      case 'D':
       +        DisplayMode = DM_STREET;
       +        break;
       +      case 'Q':
       +        if (want_to_quit() == 1) {
       +          DisplayMode = DM_NONE;
       +          clear_bottom();
       +          SendClientMessage(Play, C_NONE, C_WANTQUIT, NULL, NULL);
       +        }
       +        break;
       +      }
       +    }
       +#if NETWORKING
       +    }
       +#endif
       +    curs_set(0);
       +  }
       +  g_string_free(text, TRUE);
       +}
       +
       +void CursesLoop(void)
       +{
       +  char c;
       +  Player *Play;
       +
       +  if (!CheckHighScoreFileConfig())
       +    return;
       +
       +  /* Save the configuration, so we can restore those elements that get
       +   * overwritten when we connect to a dopewars server */
       +  BackupConfig();
       +
       +  start_curses();
       +  Width = COLS;
       +  Depth = LINES;
       +
       +  /* Set up message handlers */
       +  ClientMessageHandlerPt = HandleClientMessage;
       +
       +  /* Make the GLib log messages display nicely */
       +  g_log_set_handler(NULL,
       +                    LogMask() | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING,
       +                    LogMessage, NULL);
       +
       +  display_intro();
       +
       +  Play = g_new(Player, 1);
       +  FirstClient = AddPlayer(0, Play, FirstClient);
       +  do {
       +    Curses_DoGame(Play);
       +    ShutdownNetwork(Play);
       +    CleanUpServer();
       +    RestoreConfig();
       +    attrset(TextAttr);
       +    mvaddstr(23, 20, _("Play again? "));
       +    c = GetKey(_("YN"), "YN", TRUE, TRUE, FALSE);
       +  } while (c == 'Y');
       +  FirstClient = RemovePlayer(Play, FirstClient);
       +  end_curses();
       +}
 (DIR) diff --git a/src/curses_client.h b/src/curses_client/curses_client.h
 (DIR) diff --git a/src/dopewars.c b/src/dopewars.c
       t@@ -43,9 +43,7 @@
        #include <glib.h>
        #include <stdarg.h>
        #include "admin.h"
       -#include "curses_client.h"
        #include "dopeos.h"
       -#include "gtk_client.h"
        #include "message.h"
        #include "nls.h"
        #include "serverside.h"
       t@@ -53,8 +51,16 @@
        #include "AIPlayer.h"
        #include "winmain.h"
        
       +#ifdef CURSES_CLIENT
       +#include "curses_client/curses_client.h"
       +#endif
       +
       +#ifdef GUI_CLIENT
       +#include "gui_client/gtk_client.h"
       +#endif
       +
        #ifdef GUI_SERVER
       -#include "gtkport.h"
       +#include "gtkport/gtkport.h"
        #endif
        
        int ClientSock, ListenSock;
       t@@ -2651,6 +2657,40 @@ static void ServerLogMessage(const gchar *log_domain,
        }
        #endif
        
       +#ifndef CURSES_CLIENT
       +/*
       + * Stub function to report an error if the Curses client is requested and
       + * it isn't compiled in.
       + */
       +void CursesLoop(void)
       +{
       +  g_print(_("No curses client available - rebuild the binary passing the\n"
       +            "--enable-curses-client option to configure, or use a windowed\n"
       +            "client (if available) instead!\n"));
       +}
       +#endif
       +
       +#ifndef GUI_CLIENT
       +/*
       + * Stub function to report an error if the GTK+ client is requested and
       + * it isn't compiled in.
       + */
       +#ifdef CYGWIN
       +gboolean GtkLoop(HINSTANCE hInstance, HINSTANCE hPrevInstance,
       +                 gboolean ReturnOnFail)
       +#else
       +gboolean GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail)
       +#endif
       +{
       +  if (!ReturnOnFail) {
       +    g_print(_("No graphical client available - rebuild the binary\n"
       +              "passing the --enable-gui-client option to configure, or\n"
       +              "use the curses client (if available) instead!\n"));
       +  }
       +  return FALSE;
       +}
       +#endif
       +
        /* 
         * Standard program entry - Win32 uses WinMain() instead, in winmain.c
         */
 (DIR) diff --git a/src/dopewars.h b/src/dopewars.h
       t@@ -422,4 +422,18 @@ gboolean IsConnectedPlayer(Player *play);
        void BackupConfig(void);
        void WriteConfigFile(void);
        gchar *GetDocIndex(void);
       +
       +#ifndef CURSES_CLIENT
       +void CursesLoop(void);
       +#endif
       +
       +#ifndef GUI_CLIENT
       +#ifdef CYGWIN
       +gboolean GtkLoop(HINSTANCE hInstance, HINSTANCE hPrevInstance,
       +                 gboolean ReturnOnFail);
       +#else
       +gboolean GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail);
       +#endif
       +#endif
       +
        #endif
 (DIR) diff --git a/src/gtk_client.c b/src/gtk_client.c
       t@@ -1,3930 +0,0 @@
       -/************************************************************************
       - * gtk_client.c   dopewars client using the GTK+ toolkit                *
       - * Copyright (C)  1998-2002  Ben Webb                                   *
       - *                Email: ben@bellatrix.pcl.ox.ac.uk                     *
       - *                WWW: http://dopewars.sourceforge.net/                 *
       - *                                                                      *
       - * This program is free software; you can redistribute it and/or        *
       - * modify it under the terms of the GNU General Public License          *
       - * as published by the Free Software Foundation; either version 2       *
       - * of the License, or (at your option) any later version.               *
       - *                                                                      *
       - * This program is distributed in the hope that it will be useful,      *
       - * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
       - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
       - * GNU General Public License for more details.                         *
       - *                                                                      *
       - * You should have received a copy of the GNU General Public License    *
       - * along with this program; if not, write to the Free Software          *
       - * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
       - *                   MA  02111-1307, USA.                               *
       - ************************************************************************/
       -
       -#ifdef HAVE_CONFIG_H
       -#include <config.h>
       -#endif
       -
       -#ifdef GUI_CLIENT
       -
       -#include <stdlib.h>
       -#include <ctype.h>
       -#include <string.h>
       -
       -#include "dopeos.h"
       -#include "dopewars.h"
       -#include "gtk_client.h"
       -#include "message.h"
       -#include "nls.h"
       -#include "serverside.h"
       -#include "tstring.h"
       -#include "gtkport.h"
       -#include "dopewars-pill.xpm"
       -
       -#define BT_BUY  (GINT_TO_POINTER(1))
       -#define BT_SELL (GINT_TO_POINTER(2))
       -#define BT_DROP (GINT_TO_POINTER(3))
       -
       -#define ET_SPY    0
       -#define ET_TIPOFF 1
       -
       -/* Which notebook page to display in the New Game dialog */
       -static gint NewGameType = 0;
       -
       -struct InventoryWidgets {
       -  GtkWidget *HereList, *CarriedList;
       -  GtkWidget *HereFrame, *CarriedFrame;
       -  GtkWidget *BuyButton, *SellButton, *DropButton;
       -  GtkWidget *vbbox;
       -};
       -
       -struct StatusWidgets {
       -  GtkWidget *Location, *Date, *SpaceName, *SpaceValue, *CashName;
       -  GtkWidget *CashValue, *DebtName, *DebtValue, *BankName, *BankValue;
       -  GtkWidget *GunsName, *GunsValue, *BitchesName, *BitchesValue;
       -  GtkWidget *HealthName, *HealthValue;
       -};
       -
       -struct ClientDataStruct {
       -  GtkWidget *window, *messages;
       -  Player *Play;
       -  GtkItemFactory *Menu;
       -  struct StatusWidgets Status;
       -  struct InventoryWidgets Drug, Gun, InvenDrug, InvenGun;
       -  GtkWidget *JetButton, *vbox, *PlayerList, *TalkList;
       -  guint JetAccel;
       -};
       -
       -GtkWidget *MainWindow;
       -
       -struct StartGameStruct {
       -  GtkWidget *dialog, *name, *hostname, *port, *antique, *status, *metaserv;
       -#ifdef NETWORKING
       -  HttpConnection *MetaConn;
       -  GSList *NewMetaList;
       -#endif
       -};
       -
       -static struct ClientDataStruct ClientData;
       -static gboolean InGame = FALSE;
       -
       -static GtkWidget *FightDialog = NULL, *SpyReportsDialog;
       -static gboolean IsShowingPlayerList = FALSE, IsShowingTalkList = FALSE;
       -static gboolean IsShowingInventory = FALSE, IsShowingGunShop = FALSE;
       -
       -static void display_intro(GtkWidget *widget, gpointer data);
       -static void QuitGame(GtkWidget *widget, gpointer data);
       -static void DestroyGtk(GtkWidget *widget, gpointer data);
       -static void NewGame(GtkWidget *widget, gpointer data);
       -static void ListScores(GtkWidget *widget, gpointer data);
       -static void ListInventory(GtkWidget *widget, gpointer data);
       -static void NewGameDialog(void);
       -static void StartGame(void);
       -static void EndGame(void);
       -static void Jet(GtkWidget *parent);
       -static void UpdateMenus(void);
       -
       -#ifdef NETWORKING
       -static void DisplayConnectStatus(struct StartGameStruct *widgets,
       -                                 gboolean meta, NBStatus oldstatus,
       -                                 NBSocksStatus oldsocks);
       -static void AuthDialog(HttpConnection *conn, gboolean proxyauth,
       -                       gchar *realm, gpointer data);
       -static void MetaSocksAuthDialog(NetworkBuffer *netbuf, gpointer data);
       -static void SocksAuthDialog(NetworkBuffer *netbuf, gpointer data);
       -static void GetClientMessage(gpointer data, gint socket,
       -                             GdkInputCondition condition);
       -static void SocketStatus(NetworkBuffer *NetBuf, gboolean Read,
       -                         gboolean Write, gboolean CallNow);
       -static void MetaSocketStatus(NetworkBuffer *NetBuf, gboolean Read,
       -                             gboolean Write, gboolean CallNow);
       -static void FinishServerConnect(struct StartGameStruct *widgets,
       -                                gboolean ConnectOK);
       -
       -/* List of servers on the metaserver */
       -static GSList *MetaList = NULL;
       -
       -#endif /* NETWORKING */
       -
       -static void HandleClientMessage(char *buf, Player *Play);
       -static void PrepareHighScoreDialog(void);
       -static void AddScoreToDialog(char *Data);
       -static void CompleteHighScoreDialog(gboolean AtEnd);
       -static void PrintMessage(char *Data);
       -static void DisplayFightMessage(char *Data);
       -static GtkWidget *CreateStatusWidgets(struct StatusWidgets *Status);
       -static void DisplayStats(Player *Play, struct StatusWidgets *Status);
       -static void UpdateStatus(Player *Play);
       -static void SetJetButtonTitle(GtkAccelGroup *accel_group);
       -static void UpdateInventory(struct InventoryWidgets *Inven,
       -                            Inventory *Objects, int NumObjects,
       -                            gboolean AreDrugs);
       -static void JetButtonPressed(GtkWidget *widget, gpointer data);
       -static void DealDrugs(GtkWidget *widget, gpointer data);
       -static void DealGuns(GtkWidget *widget, gpointer data);
       -static void QuestionDialog(char *Data, Player *From);
       -static void TransferDialog(gboolean Debt);
       -static void ListPlayers(GtkWidget *widget, gpointer data);
       -static void TalkToAll(GtkWidget *widget, gpointer data);
       -static void TalkToPlayers(GtkWidget *widget, gpointer data);
       -static void TalkDialog(gboolean TalkToAll);
       -static GtkWidget *CreatePlayerList(void);
       -static void UpdatePlayerList(GtkWidget *clist, gboolean IncludeSelf);
       -static void TipOff(GtkWidget *widget, gpointer data);
       -static void SpyOnPlayer(GtkWidget *widget, gpointer data);
       -static void ErrandDialog(gint ErrandType);
       -static void SackBitch(GtkWidget *widget, gpointer data);
       -static void DestroyShowing(GtkWidget *widget, gpointer data);
       -static gint DisallowDelete(GtkWidget *widget, GdkEvent * event,
       -                           gpointer data);
       -static void GunShopDialog(void);
       -static void NewNameDialog(void);
       -static void UpdatePlayerLists(void);
       -static void CreateInventory(GtkWidget *hbox, gchar *Objects,
       -                            GtkAccelGroup *accel_group,
       -                            gboolean CreateButtons, gboolean CreateHere,
       -                            struct InventoryWidgets *widgets,
       -                            GtkSignalFunc CallBack);
       -static void GetSpyReports(GtkWidget *widget, gpointer data);
       -static void DisplaySpyReports(Player *Play);
       -
       -static GtkItemFactoryEntry menu_items[] = {
       -  /* The names of the the menus and their items in the GTK+ client */
       -  {N_("/_Game"), NULL, NULL, 0, "<Branch>"},
       -  {N_("/Game/_New..."), "<control>N", NewGame, 0, NULL},
       -  {N_("/Game/_Quit..."), "<control>Q", QuitGame, 0, NULL},
       -  {N_("/_Talk"), NULL, NULL, 0, "<Branch>"},
       -  {N_("/Talk/To _All..."), NULL, TalkToAll, 0, NULL},
       -  {N_("/Talk/To _Player..."), NULL, TalkToPlayers, 0, NULL},
       -  {N_("/_List"), NULL, NULL, 0, "<Branch>"},
       -  {N_("/List/_Players..."), NULL, ListPlayers, 0, NULL},
       -  {N_("/List/_Scores..."), NULL, ListScores, 0, NULL},
       -  {N_("/List/_Inventory..."), NULL, ListInventory, 0, NULL},
       -  {N_("/_Errands"), NULL, NULL, 0, "<Branch>"},
       -  {N_("/Errands/_Spy..."), NULL, SpyOnPlayer, 0, NULL},
       -  {N_("/Errands/_Tipoff..."), NULL, TipOff, 0, NULL},
       -  /* N.B. "Sack Bitch" has to be recreated (and thus translated) at the
       -   * start of each game, below, so is not marked for gettext here */
       -  {"/Errands/S_ack Bitch...", NULL, SackBitch, 0, NULL},
       -  {N_("/Errands/_Get spy reports..."), NULL, GetSpyReports, 0, NULL},
       -  {N_("/_Help"), NULL, NULL, 0, "<LastBranch>"},
       -  {N_("/Help/_About..."), "F1", display_intro, 0, NULL}
       -};
       -
       -static gchar *MenuTranslate(const gchar *path, gpointer func_data)
       -{
       -  /* Translate menu items, using gettext */
       -  return _(path);
       -}
       -
       -static void LogMessage(const gchar *log_domain, GLogLevelFlags log_level,
       -                       const gchar *message, gpointer user_data)
       -{
       -  GtkMessageBox(NULL, message,
       -                /* Titles of the message boxes for warnings and errors */
       -                log_level & G_LOG_LEVEL_WARNING ? _("Warning") :
       -                log_level & G_LOG_LEVEL_CRITICAL ? _("Error") :
       -                _("Message"),
       -                MB_OK | (gtk_main_level() > 0 ? MB_IMMRETURN : 0));
       -}
       -
       -void QuitGame(GtkWidget *widget, gpointer data)
       -{
       -  if (!InGame || GtkMessageBox(ClientData.window,
       -                               /* Prompt in 'quit game' dialog */
       -                               _("Abandon current game?"),
       -                               /* Title of 'quit game' dialog */
       -                               _("Quit Game"), MB_YESNO) == IDYES) {
       -    gtk_main_quit();
       -  }
       -}
       -
       -void DestroyGtk(GtkWidget *widget, gpointer data)
       -{
       -  gtk_main_quit();
       -}
       -
       -gint MainDelete(GtkWidget *widget, GdkEvent * event, gpointer data)
       -{
       -  return (InGame
       -          && GtkMessageBox(ClientData.window, _("Abandon current game?"),
       -                           _("Quit Game"), MB_YESNO) == IDNO);
       -}
       -
       -
       -void NewGame(GtkWidget *widget, gpointer data)
       -{
       -  if (InGame) {
       -    if (GtkMessageBox(ClientData.window, _("Abandon current game?"),
       -                      /* Title of 'stop game to start a new game' dialog */
       -                      _("Start new game"), MB_YESNO) == IDYES)
       -      EndGame();
       -    else
       -      return;
       -  }
       -
       -  /* Save the configuration, so we can restore those elements that get
       -   * overwritten when we connect to a dopewars server */
       -  BackupConfig();
       -
       -  NewGameDialog();
       -}
       -
       -void ListScores(GtkWidget *widget, gpointer data)
       -{
       -  SendClientMessage(ClientData.Play, C_NONE, C_REQUESTSCORE, NULL, NULL);
       -}
       -
       -void ListInventory(GtkWidget *widget, gpointer data)
       -{
       -  GtkWidget *window, *button, *hsep, *vbox, *hbox;
       -  GtkAccelGroup *accel_group;
       -
       -  if (IsShowingInventory)
       -    return;
       -  window = gtk_window_new(GTK_WINDOW_DIALOG);
       -  gtk_window_set_default_size(GTK_WINDOW(window), 550, 120);
       -  accel_group = gtk_accel_group_new();
       -  gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
       -
       -  /* Title of inventory window */
       -  gtk_window_set_title(GTK_WINDOW(window), _("Inventory"));
       -
       -  IsShowingInventory = TRUE;
       -  gtk_window_set_modal(GTK_WINDOW(window), FALSE);
       -  gtk_object_set_data(GTK_OBJECT(window), "IsShowing",
       -                      (gpointer)&IsShowingInventory);
       -  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       -                     GTK_SIGNAL_FUNC(DestroyShowing), NULL);
       -
       -  gtk_window_set_transient_for(GTK_WINDOW(window),
       -                               GTK_WINDOW(ClientData.window));
       -  gtk_container_set_border_width(GTK_CONTAINER(window), 7);
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -
       -  hbox = gtk_hbox_new(FALSE, 7);
       -  CreateInventory(hbox, Names.Drugs, accel_group, FALSE, FALSE,
       -                  &ClientData.InvenDrug, NULL);
       -  CreateInventory(hbox, Names.Guns, accel_group, FALSE, FALSE,
       -                  &ClientData.InvenGun, NULL);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -
       -  /* Caption of the button to close a dialog */
       -  button = gtk_button_new_with_label(_("Close"));
       -  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       -                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       -                            (gpointer)window);
       -  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
       -
       -  gtk_container_add(GTK_CONTAINER(window), vbox);
       -
       -  UpdateInventory(&ClientData.InvenDrug, ClientData.Play->Drugs, NumDrug,
       -                  TRUE);
       -  UpdateInventory(&ClientData.InvenGun, ClientData.Play->Guns, NumGun,
       -                  FALSE);
       -
       -  gtk_widget_show_all(window);
       -}
       -
       -#ifdef NETWORKING
       -void GetClientMessage(gpointer data, gint socket,
       -                      GdkInputCondition condition)
       -{
       -  gchar *pt;
       -  NetworkBuffer *NetBuf;
       -  gboolean DoneOK, datawaiting;
       -  NBStatus status, oldstatus;
       -  NBSocksStatus oldsocks;
       -
       -  NetBuf = &ClientData.Play->NetBuf;
       -
       -  oldstatus = NetBuf->status;
       -  oldsocks = NetBuf->sockstat;
       -
       -  datawaiting =
       -      PlayerHandleNetwork(ClientData.Play, condition & GDK_INPUT_READ,
       -                          condition & GDK_INPUT_WRITE, &DoneOK);
       -
       -  status = NetBuf->status;
       -
       -  if (status != NBS_CONNECTED) {
       -    /* The start game dialog isn't visible once we're connected... */
       -    DisplayConnectStatus((struct StartGameStruct *)data, FALSE,
       -                         oldstatus, oldsocks);
       -  }
       -
       -  if (oldstatus != NBS_CONNECTED && (status == NBS_CONNECTED || !DoneOK)) {
       -    FinishServerConnect(data, DoneOK);
       -  }
       -  if (status == NBS_CONNECTED && datawaiting) {
       -    while ((pt = GetWaitingPlayerMessage(ClientData.Play)) != NULL) {
       -      HandleClientMessage(pt, ClientData.Play);
       -      g_free(pt);
       -    }
       -  }
       -  if (!DoneOK) {
       -    if (status == NBS_CONNECTED) {
       -      /* The network connection to the server was dropped unexpectedly */
       -      g_warning(_("Connection to server lost - switching to "
       -                  "single player mode"));
       -      SwitchToSinglePlayer(ClientData.Play);
       -      UpdatePlayerLists();
       -      UpdateMenus();
       -    } else {
       -      ShutdownNetworkBuffer(&ClientData.Play->NetBuf);
       -    }
       -  }
       -}
       -
       -void SocketStatus(NetworkBuffer *NetBuf, gboolean Read, gboolean Write,
       -                  gboolean CallNow)
       -{
       -  if (NetBuf->InputTag)
       -    gdk_input_remove(NetBuf->InputTag);
       -  NetBuf->InputTag = 0;
       -  if (Read || Write) {
       -    NetBuf->InputTag = gdk_input_add(NetBuf->fd,
       -                                     (Read ? GDK_INPUT_READ : 0) |
       -                                     (Write ? GDK_INPUT_WRITE : 0),
       -                                     GetClientMessage,
       -                                     NetBuf->CallBackData);
       -  }
       -  if (CallNow)
       -    GetClientMessage(NetBuf->CallBackData, NetBuf->fd, 0);
       -}
       -#endif /* NETWORKING */
       -
       -void HandleClientMessage(char *pt, Player *Play)
       -{
       -  char *Data;
       -  DispMode DisplayMode;
       -  AICode AI;
       -  MsgCode Code;
       -  Player *From, *tmp;
       -  gchar *text;
       -  gboolean Handled;
       -  GtkWidget *MenuItem;
       -  GSList *list;
       -
       -  if (ProcessMessage(pt, Play, &From, &AI, &Code,
       -                     &Data, FirstClient) == -1) {
       -    return;
       -  }
       -
       -  Handled =
       -      HandleGenericClientMessage(From, AI, Code, Play, Data, &DisplayMode);
       -  switch (Code) {
       -  case C_STARTHISCORE:
       -    PrepareHighScoreDialog();
       -    break;
       -  case C_HISCORE:
       -    AddScoreToDialog(Data);
       -    break;
       -  case C_ENDHISCORE:
       -    CompleteHighScoreDialog((strcmp(Data, "end") == 0));
       -    break;
       -  case C_PRINTMESSAGE:
       -    PrintMessage(Data);
       -    break;
       -  case C_FIGHTPRINT:
       -    DisplayFightMessage(Data);
       -    break;
       -  case C_PUSH:
       -    /* The server admin has asked us to leave - so warn the user, and do
       -     * so */
       -    g_warning(_("You have been pushed from the server.\n"
       -                "Switching to single player mode."));
       -    SwitchToSinglePlayer(Play);
       -    UpdatePlayerLists();
       -    UpdateMenus();
       -    break;
       -  case C_QUIT:
       -    /* The server has sent us notice that it is shutting down */
       -    g_warning(_("The server has terminated.\n"
       -                "Switching to single player mode."));
       -    SwitchToSinglePlayer(Play);
       -    UpdatePlayerLists();
       -    UpdateMenus();
       -    break;
       -  case C_NEWNAME:
       -    NewNameDialog();
       -    break;
       -  case C_BANK:
       -    TransferDialog(FALSE);
       -    break;
       -  case C_LOANSHARK:
       -    TransferDialog(TRUE);
       -    break;
       -  case C_GUNSHOP:
       -    GunShopDialog();
       -    break;
       -  case C_MSG:
       -    text = g_strdup_printf("%s: %s", GetPlayerName(From), Data);
       -    PrintMessage(text);
       -    g_free(text);
       -    break;
       -  case C_MSGTO:
       -    text = g_strdup_printf("%s->%s: %s", GetPlayerName(From),
       -                           GetPlayerName(Play), Data);
       -    PrintMessage(text);
       -    g_free(text);
       -    break;
       -  case C_JOIN:
       -    text = g_strdup_printf(_("%s joins the game!"), Data);
       -    PrintMessage(text);
       -    g_free(text);
       -    UpdatePlayerLists();
       -    UpdateMenus();
       -    break;
       -  case C_LEAVE:
       -    if (From != &Noone) {
       -      text = g_strdup_printf(_("%s has left the game."), Data);
       -      PrintMessage(text);
       -      g_free(text);
       -      UpdatePlayerLists();
       -      UpdateMenus();
       -    }
       -    break;
       -  case C_QUESTION:
       -    QuestionDialog(Data, From == &Noone ? NULL : From);
       -    break;
       -  case C_SUBWAYFLASH:
       -    DisplayFightMessage(NULL);
       -    for (list = FirstClient; list; list = g_slist_next(list)) {
       -      tmp = (Player *)list->data;
       -      tmp->Flags &= ~FIGHTING;
       -    }
       -    /* Message displayed when the player "jets" to a new location */
       -    text = dpg_strdup_printf(_("Jetting to %tde"),
       -                             Location[(int)Play->IsAt].Name);
       -    PrintMessage(text);
       -    g_free(text);
       -    break;
       -  case C_ENDLIST:
       -    MenuItem = gtk_item_factory_get_widget(ClientData.Menu,
       -                                           "<main>/Errands/Sack Bitch...");
       -
       -    /* Text for the Errands/Sack Bitch menu item */
       -    text = dpg_strdup_printf(_("%/Sack Bitch menu item/S_ack %Tde..."),
       -                             Names.Bitch);
       -    SetAccelerator(MenuItem, text, NULL, NULL, NULL);
       -    g_free(text);
       -
       -    MenuItem = gtk_item_factory_get_widget(ClientData.Menu,
       -                                           "<main>/Errands/Spy...");
       -
       -    /* Text to update the Errands/Spy menu item with the price for spying */
       -    text = dpg_strdup_printf(_("_Spy (%P)"), Prices.Spy);
       -    SetAccelerator(MenuItem, text, NULL, NULL, NULL);
       -    g_free(text);
       -
       -    /* Text to update the Errands/Tipoff menu item with the price for a
       -     * tipoff */
       -    text = dpg_strdup_printf(_("_Tipoff (%P)"), Prices.Tipoff);
       -    MenuItem = gtk_item_factory_get_widget(ClientData.Menu,
       -                                           "<main>/Errands/Tipoff...");
       -    SetAccelerator(MenuItem, text, NULL, NULL, NULL);
       -    g_free(text);
       -    if (FirstClient->next)
       -      ListPlayers(NULL, NULL);
       -    UpdateMenus();
       -    break;
       -  case C_UPDATE:
       -    if (From == &Noone) {
       -      ReceivePlayerData(Play, Data, Play);
       -      UpdateStatus(Play);
       -    } else {
       -      ReceivePlayerData(Play, Data, From);
       -      DisplaySpyReports(From);
       -    }
       -    break;
       -  case C_DRUGHERE:
       -    UpdateInventory(&ClientData.Drug, Play->Drugs, NumDrug, TRUE);
       -    gtk_clist_sort(GTK_CLIST(ClientData.Drug.HereList));
       -    if (IsShowingInventory) {
       -      UpdateInventory(&ClientData.InvenDrug, Play->Drugs, NumDrug, TRUE);
       -    }
       -    break;
       -  default:
       -    if (!Handled) {
       -      g_print("Unknown network message received: %s^%c^%s^%s",
       -              GetPlayerName(From), Code, GetPlayerName(Play), Data);
       -    }
       -    break;
       -  }
       -}
       -
       -struct HiScoreDiaStruct {
       -  GtkWidget *dialog, *table, *vbox;
       -};
       -static struct HiScoreDiaStruct HiScoreDialog = { NULL, NULL, NULL };
       -
       -/* 
       - * Creates an empty dialog to display high scores.
       - */
       -void PrepareHighScoreDialog(void)
       -{
       -  GtkWidget *dialog, *vbox, *hsep, *table;
       -
       -  /* Make sure the server doesn't fool us into creating multiple dialogs */
       -  if (HiScoreDialog.dialog)
       -    return;
       -
       -  HiScoreDialog.dialog = dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       -
       -  /* Title of the GTK+ high score dialog */
       -  gtk_window_set_title(GTK_WINDOW(dialog), _("High Scores"));
       -
       -  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       -  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       -                               GTK_WINDOW(ClientData.window));
       -
       -  HiScoreDialog.vbox = vbox = gtk_vbox_new(FALSE, 7);
       -  HiScoreDialog.table = table = gtk_table_new(NUMHISCORE, 4, FALSE);
       -  gtk_table_set_row_spacings(GTK_TABLE(table), 5);
       -  gtk_table_set_col_spacings(GTK_TABLE(table), 30);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       -  gtk_widget_show_all(dialog);
       -}
       -
       -/* 
       - * Adds a single high score (coded in "Data", which is the information
       - * received in the relevant network message) to the dialog created by
       - * PrepareHighScoreDialog(), above.
       - */
       -void AddScoreToDialog(char *Data)
       -{
       -  GtkWidget *label;
       -  char *cp;
       -  gchar **spl1, **spl2;
       -  int index, slen;
       -  gboolean bold;
       -
       -  if (!HiScoreDialog.dialog)
       -    return;
       -
       -  cp = Data;
       -  index = GetNextInt(&cp, 0);
       -  if (!cp || strlen(cp) < 3)
       -    return;
       -
       -  bold = (*cp == 'B');          /* Is this score "our" score? (Currently
       -                                 * ignored) */
       -
       -  /* Step past the 'bold' character, and the initial '>' (if present) */
       -  cp += 2;
       -  g_strchug(cp);
       -
       -  /* Get the first word - the score */
       -  spl1 = g_strsplit(cp, " ", 1);
       -  if (!spl1 || !spl1[0] || !spl1[1]) {
       -    /* Error - the high score from the server is invalid */
       -    g_warning(_("Corrupt high score!"));
       -    g_strfreev(spl1);
       -    return;
       -  }
       -  label = gtk_label_new(spl1[0]);
       -  gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
       -  gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label,
       -                            0, 1, index, index + 1);
       -  gtk_widget_show(label);
       -
       -  /* Remove any leading whitespace from the remainder, since g_strsplit
       -   * will split at every space character, not at a run of them */
       -  g_strchug(spl1[1]);
       -
       -  /* Get the second word - the date */
       -  spl2 = g_strsplit(spl1[1], " ", 1);
       -  if (!spl2 || !spl2[0] || !spl2[1]) {
       -    g_warning(_("Corrupt high score!"));
       -    g_strfreev(spl2);
       -    return;
       -  }
       -  label = gtk_label_new(spl2[0]);
       -  gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
       -  gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label,
       -                            1, 2, index, index + 1);
       -  gtk_widget_show(label);
       -
       -  /* The remainder is the name, terminated with (R.I.P.) if the player
       -   * died, and '<' for the 'current' score */
       -  g_strchug(spl2[1]);
       -
       -  /* Remove '<' suffix if present */
       -  slen = strlen(spl2[1]);
       -  if (slen >= 1 && spl2[1][slen - 1] == '<') {
       -    spl2[1][slen - 1] = '\0';
       -  }
       -  slen--;
       -
       -  /* Check for (R.I.P.) suffix, and add it to the 4th column if found */
       -  if (slen > 8 && spl2[1][slen - 1] == ')' && spl2[1][slen - 8] == '(') {
       -    label = gtk_label_new(&spl2[1][slen - 8]);
       -    gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
       -    gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label,
       -                              3, 4, index, index + 1);
       -    gtk_widget_show(label);
       -    spl2[1][slen - 8] = '\0';   /* Remove suffix from the player name */
       -  }
       -
       -  /* Finally, add in what's left of the player name */
       -  g_strchomp(spl2[1]);
       -  label = gtk_label_new(spl2[1]);
       -  gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
       -  gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label,
       -                            2, 3, index, index + 1);
       -  gtk_widget_show(label);
       -
       -  g_strfreev(spl1);
       -  g_strfreev(spl2);
       -}
       -
       -/* 
       - * If the high scores are being displayed at the end of the game,
       - * this function is used to end the game when the high score dialog's
       - * "OK" button is pressed.
       - */
       -static void EndHighScore(GtkWidget *widget)
       -{
       -  EndGame();
       -}
       -
       -/* 
       - * Called when all high scores have been received. Finishes off the
       - * high score dialog by adding an "OK" button. If the game has ended,
       - * then "AtEnd" is TRUE, and clicking this button will end the game.
       - */
       -void CompleteHighScoreDialog(gboolean AtEnd)
       -{
       -  GtkWidget *OKButton, *dialog;
       -
       -  dialog = HiScoreDialog.dialog;
       -
       -  if (!HiScoreDialog.dialog)
       -    return;
       -
       -  /* Caption of the "OK" button in dialogs */
       -  OKButton = gtk_button_new_with_label(_("OK"));
       -  gtk_signal_connect_object(GTK_OBJECT(OKButton), "clicked",
       -                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       -                            (gpointer)dialog);
       -  if (AtEnd) {
       -    InGame = FALSE;
       -    gtk_signal_connect_object(GTK_OBJECT(dialog), "destroy",
       -                              GTK_SIGNAL_FUNC(EndHighScore), NULL);
       -  }
       -  gtk_box_pack_start(GTK_BOX(HiScoreDialog.vbox), OKButton, TRUE, TRUE, 0);
       -
       -  GTK_WIDGET_SET_FLAGS(OKButton, GTK_CAN_DEFAULT);
       -  gtk_widget_grab_default(OKButton);
       -  gtk_widget_show(OKButton);
       -
       -  /* OK, we're done - allow the creation of new high score dialogs */
       -  HiScoreDialog.dialog = NULL;
       -}
       -
       -/* 
       - * Prints an information message in the display area of the GTK+ client.
       - * This area is used for displaying drug busts, messages from other
       - * players, etc. The message is passed in as the string "text".
       - */
       -void PrintMessage(char *text)
       -{
       -  gint EditPos;
       -  char *cr = "\n";
       -  GtkEditable *messages;
       -
       -  messages = GTK_EDITABLE(ClientData.messages);
       -
       -  gtk_text_freeze(GTK_TEXT(messages));
       -  g_strdelimit(text, "^", '\n');
       -  EditPos = gtk_text_get_length(GTK_TEXT(ClientData.messages));
       -  while (*text == '\n')
       -    text++;
       -  gtk_editable_insert_text(messages, text, strlen(text), &EditPos);
       -  if (text[strlen(text) - 1] != '\n') {
       -    gtk_editable_insert_text(messages, cr, strlen(cr), &EditPos);
       -  }
       -  gtk_text_thaw(GTK_TEXT(messages));
       -  gtk_editable_set_position(messages, EditPos);
       -}
       -
       -/* 
       - * Called when one of the action buttons in the Fight dialog is clicked.
       - * "data" specifies which button (Deal Drugs/Run/Fight/Stand) was pressed.
       - */
       -static void FightCallback(GtkWidget *widget, gpointer data)
       -{
       -  gint Answer;
       -  Player *Play;
       -  gchar text[4];
       -  GtkWidget *window;
       -  gpointer CanRunHere = NULL;
       -
       -  window = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
       -  if (window)
       -    CanRunHere = gtk_object_get_data(GTK_OBJECT(window), "CanRunHere");
       -
       -  Answer = GPOINTER_TO_INT(data);
       -  Play = ClientData.Play;
       -  switch (Answer) {
       -  case 'D':
       -    gtk_widget_hide(FightDialog);
       -    break;
       -  case 'R':
       -    if (CanRunHere) {
       -      SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, "R");
       -    } else {
       -      Jet(FightDialog);
       -    }
       -    break;
       -  case 'F':
       -  case 'S':
       -    text[0] = Answer;
       -    text[1] = '\0';
       -    SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, text);
       -    break;
       -  }
       -}
       -
       -/* 
       - * Adds an action button to the hbox at the base of the Fight dialog.
       - * The button's caption is given by "Text", and the keyboard shortcut
       - * (if any) is added to "accel_group". "Answer" gives the identifier
       - * passed to FightCallback, above.
       - */
       -static GtkWidget *AddFightButton(gchar *Text, GtkAccelGroup *accel_group,
       -                                 GtkBox *box, gint Answer)
       -{
       -  GtkWidget *button;
       -
       -  button = gtk_button_new_with_label("");
       -  SetAccelerator(button, Text, button, "clicked", accel_group);
       -  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                     GTK_SIGNAL_FUNC(FightCallback),
       -                     GINT_TO_POINTER(Answer));
       -  gtk_box_pack_start(box, button, TRUE, TRUE, 0);
       -  return button;
       -}
       -
       -/* Data used to keep track of the widgets giving the information about a
       - * player/cop involved in a fight */
       -struct combatant {
       -  GtkWidget *name, *bitches, *healthprog, *healthlabel;
       -};
       -
       -/* 
       - * Creates an empty Fight dialog. Usually this only needs to be done once,
       - * as when the user "closes" it, it is only hidden, ready to be reshown
       - * later. Buttons for all actions are added here, and are hidden/shown
       - * as necessary.
       - */
       -static void CreateFightDialog(void)
       -{
       -  GtkWidget *dialog, *vbox, *button, *hbox, *hbbox, *hsep, *text, *table;
       -  GtkAccelGroup *accel_group;
       -  GArray *combatants;
       -  gchar *buf;
       -
       -  FightDialog = dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       -  gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
       -  gtk_signal_connect(GTK_OBJECT(dialog), "delete_event",
       -                     GTK_SIGNAL_FUNC(DisallowDelete), NULL);
       -  gtk_window_set_default_size(GTK_WINDOW(dialog), 240, 130);
       -  accel_group = gtk_accel_group_new();
       -  gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group);
       -  gtk_window_set_title(GTK_WINDOW(dialog), _("Fight"));
       -  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       -
       -  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       -                               GTK_WINDOW(ClientData.window));
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -
       -  table = gtk_table_new(2, 4, FALSE);
       -  gtk_table_set_row_spacings(GTK_TABLE(table), 5);
       -  gtk_table_set_col_spacings(GTK_TABLE(table), 5);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_table_attach_defaults(GTK_TABLE(table), hsep, 0, 4, 1, 2);
       -  gtk_widget_show_all(table);
       -  gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
       -  gtk_object_set_data(GTK_OBJECT(dialog), "table", table);
       -
       -  combatants = g_array_new(FALSE, TRUE, sizeof(struct combatant));
       -  g_array_set_size(combatants, 1);
       -  gtk_object_set_data(GTK_OBJECT(dialog), "combatants", combatants);
       -
       -  text = gtk_scrolled_text_new(NULL, NULL, &hbox);
       -  gtk_widget_set_usize(text, 150, 120);
       -
       -  gtk_text_set_editable(GTK_TEXT(text), FALSE);
       -  gtk_text_set_word_wrap(GTK_TEXT(text), TRUE);
       -  gtk_object_set_data(GTK_OBJECT(dialog), "text", text);
       -  gtk_widget_show_all(hbox);
       -  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -  gtk_widget_show(hsep);
       -
       -  hbbox = gtk_hbutton_box_new();
       -
       -  /* Button for closing the "Fight" dialog and going back to dealing drugs
       -   * (%Tde = "Drugs" by default) */
       -  buf = dpg_strdup_printf(_("_Deal %Tde"), Names.Drugs);
       -  button = AddFightButton(buf, accel_group, GTK_BOX(hbbox), 'D');
       -  gtk_object_set_data(GTK_OBJECT(dialog), "deal", button);
       -  g_free(buf);
       -
       -  /* Button for shooting at other players in the "Fight" dialog, or for
       -   * popping up the "Fight" dialog from the main window */
       -  button = AddFightButton(_("_Fight"), accel_group, GTK_BOX(hbbox), 'F');
       -  gtk_object_set_data(GTK_OBJECT(dialog), "fight", button);
       -
       -  /* Button to stand and take it in the "Fight" dialog */
       -  button = AddFightButton(_("_Stand"), accel_group, GTK_BOX(hbbox), 'S');
       -  gtk_object_set_data(GTK_OBJECT(dialog), "stand", button);
       -
       -  /* Button to run from combat in the "Fight" dialog */
       -  button = AddFightButton(_("_Run"), accel_group, GTK_BOX(hbbox), 'R');
       -  gtk_object_set_data(GTK_OBJECT(dialog), "run", button);
       -
       -  gtk_widget_show(hsep);
       -  gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
       -  gtk_widget_show(hbbox);
       -  gtk_widget_show(vbox);
       -  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       -  gtk_widget_show(dialog);
       -}
       -
       -/* 
       - * Updates the display of information for a player/cop in the Fight dialog.
       - * If the player's name (DefendName) already exists, updates the display of
       - * total health and number of bitches - otherwise, adds a new entry. If
       - * DefendBitches is -1, then the player has left.
       - */
       -static void UpdateCombatant(gchar *DefendName, int DefendBitches,
       -                            gchar *BitchName, int DefendHealth)
       -{
       -  guint i, RowIndex;
       -  gchar *name;
       -  struct combatant *compt;
       -  GArray *combatants;
       -  GtkWidget *table;
       -  gchar *BitchText, *HealthText;
       -  gfloat ProgPercent;
       -
       -  combatants = (GArray *)gtk_object_get_data(GTK_OBJECT(FightDialog),
       -                                             "combatants");
       -  table = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "table"));
       -  if (!combatants)
       -    return;
       -
       -  if (DefendName[0]) {
       -    compt = NULL;
       -    for (i = 1, RowIndex = 2; i < combatants->len; i++, RowIndex++) {
       -      compt = &g_array_index(combatants, struct combatant, i);
       -
       -      if (!compt || !compt->name) {
       -        compt = NULL;
       -        continue;
       -      }
       -      gtk_label_get(GTK_LABEL(compt->name), &name);
       -      if (name && strcmp(name, DefendName) == 0)
       -        break;
       -      compt = NULL;
       -    }
       -    if (!compt) {
       -      i = combatants->len;
       -      g_array_set_size(combatants, i + 1);
       -      compt = &g_array_index(combatants, struct combatant, i);
       -
       -      gtk_table_resize(GTK_TABLE(table), i + 2, 4);
       -      RowIndex = i + 1;
       -    }
       -  } else {
       -    compt = &g_array_index(combatants, struct combatant, 0);
       -
       -    RowIndex = 0;
       -  }
       -
       -  /* Display of number of bitches or deputies during combat
       -   * (%tde="bitches" or "deputies" (etc.) by default) */
       -  BitchText = dpg_strdup_printf(_("%/Combat: Bitches/%d %tde"),
       -                                DefendBitches, BitchName);
       -
       -  /* Display of health during combat */
       -  if (DefendBitches == -1) {
       -    HealthText = g_strdup(_("(Left)"));
       -  } else if (DefendHealth == 0 && DefendBitches == 0) {
       -    HealthText = g_strdup(_("(Dead)"));
       -  } else {
       -    HealthText = g_strdup_printf(_("Health: %d"), DefendHealth);
       -  }
       -
       -  ProgPercent = (gfloat)DefendHealth / 100.0;
       -
       -  if (compt->name) {
       -    if (DefendName[0]) {
       -      gtk_label_set_text(GTK_LABEL(compt->name), DefendName);
       -    }
       -    if (DefendBitches >= 0) {
       -      gtk_label_set_text(GTK_LABEL(compt->bitches), BitchText);
       -    }
       -    gtk_label_set_text(GTK_LABEL(compt->healthlabel), HealthText);
       -    gtk_progress_bar_update(GTK_PROGRESS_BAR(compt->healthprog),
       -                            ProgPercent);
       -  } else {
       -    /* Display of the current player's name during combat */
       -    compt->name = gtk_label_new(DefendName[0] ? DefendName : _("You"));
       -
       -    gtk_table_attach_defaults(GTK_TABLE(table), compt->name, 0, 1,
       -                              RowIndex, RowIndex + 1);
       -    compt->bitches = gtk_label_new(DefendBitches >= 0 ? BitchText : "");
       -    gtk_table_attach_defaults(GTK_TABLE(table), compt->bitches, 1, 2,
       -                              RowIndex, RowIndex + 1);
       -    compt->healthprog = gtk_progress_bar_new();
       -    gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(compt->healthprog),
       -                                     GTK_PROGRESS_LEFT_TO_RIGHT);
       -    gtk_progress_bar_update(GTK_PROGRESS_BAR(compt->healthprog),
       -                            ProgPercent);
       -    gtk_table_attach_defaults(GTK_TABLE(table), compt->healthprog, 2, 3,
       -                              RowIndex, RowIndex + 1);
       -    compt->healthlabel = gtk_label_new(HealthText);
       -    gtk_table_attach_defaults(GTK_TABLE(table), compt->healthlabel, 3, 4,
       -                              RowIndex, RowIndex + 1);
       -    gtk_widget_show(compt->name);
       -    gtk_widget_show(compt->bitches);
       -    gtk_widget_show(compt->healthprog);
       -    gtk_widget_show(compt->healthlabel);
       -  }
       -
       -  g_free(BitchText);
       -  g_free(HealthText);
       -}
       -
       -/* 
       - * Cleans up the list of all players/cops involved in a fight.
       - */
       -static void FreeCombatants(void)
       -{
       -  GArray *combatants;
       -
       -  combatants = (GArray *)gtk_object_get_data(GTK_OBJECT(FightDialog),
       -                                             "combatants");
       -  if (!combatants)
       -    return;
       -
       -  g_array_free(combatants, TRUE);
       -}
       -
       -/* 
       - * Given the network message "Data" concerning some happening during
       - * combat, extracts the relevant data and updates the Fight dialog,
       - * creating and/or showing it if necessary.
       - * If "Data" is NULL, then closes the dialog. If "Data" is a blank
       - * string, then just shows the dialog, displaying no new messages.
       - */
       -void DisplayFightMessage(char *Data)
       -{
       -  Player *Play;
       -  gint EditPos;
       -  GtkAccelGroup *accel_group;
       -  GtkWidget *Deal, *Fight, *Stand, *Run, *Text;
       -  char cr[] = "\n";
       -  gchar *AttackName, *DefendName, *BitchName, *Message;
       -  FightPoint fp;
       -  int DefendHealth, DefendBitches, BitchesKilled, ArmPercent;
       -  gboolean CanRunHere, Loot, CanFire;
       -
       -  if (!Data) {
       -    if (FightDialog) {
       -      FreeCombatants();
       -      gtk_widget_destroy(FightDialog);
       -      FightDialog = NULL;
       -    }
       -    return;
       -  }
       -  if (FightDialog) {
       -    if (!GTK_WIDGET_VISIBLE(FightDialog))
       -      gtk_widget_show(FightDialog);
       -  } else {
       -    CreateFightDialog();
       -  }
       -  if (!FightDialog || !Data[0])
       -    return;
       -
       -  Deal = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "deal"));
       -  Fight = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "fight"));
       -  Stand = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "stand"));
       -  Run = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "run"));
       -  Text = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "text"));
       -
       -  Play = ClientData.Play;
       -
       -  if (HaveAbility(Play, A_NEWFIGHT)) {
       -    ReceiveFightMessage(Data, &AttackName, &DefendName, &DefendHealth,
       -                        &DefendBitches, &BitchName, &BitchesKilled,
       -                        &ArmPercent, &fp, &CanRunHere, &Loot, &CanFire,
       -                        &Message);
       -    Play->Flags |= FIGHTING;
       -    switch (fp) {
       -    case F_HIT:
       -    case F_ARRIVED:
       -    case F_MISS:
       -      UpdateCombatant(DefendName, DefendBitches, BitchName, DefendHealth);
       -      break;
       -    case F_LEAVE:
       -      if (AttackName[0]) {
       -        UpdateCombatant(AttackName, -1, BitchName, 0);
       -      }
       -      break;
       -    case F_LASTLEAVE:
       -      Play->Flags &= ~FIGHTING;
       -      break;
       -    default:
       -    }
       -    accel_group = (GtkAccelGroup *)
       -        gtk_object_get_data(GTK_OBJECT(ClientData.window), "accel_group");
       -    SetJetButtonTitle(accel_group);
       -  } else {
       -    Message = Data;
       -    if (Play->Flags & FIGHTING)
       -      fp = F_MSG;
       -    else
       -      fp = F_LASTLEAVE;
       -    CanFire = (Play->Flags & CANSHOOT);
       -    CanRunHere = FALSE;
       -  }
       -  gtk_object_set_data(GTK_OBJECT(FightDialog), "CanRunHere",
       -                      GINT_TO_POINTER(CanRunHere));
       -
       -  g_strdelimit(Message, "^", '\n');
       -  if (strlen(Message) > 0) {
       -    EditPos = gtk_text_get_length(GTK_TEXT(Text));
       -    gtk_editable_insert_text(GTK_EDITABLE(Text), Message,
       -                             strlen(Message), &EditPos);
       -    gtk_editable_insert_text(GTK_EDITABLE(Text), cr, strlen(cr), &EditPos);
       -  }
       -
       -  if (!CanRunHere || fp == F_LASTLEAVE)
       -    gtk_widget_show(Deal);
       -  else
       -    gtk_widget_hide(Deal);
       -  if (CanFire && TotalGunsCarried(Play) > 0)
       -    gtk_widget_show(Fight);
       -  else
       -    gtk_widget_hide(Fight);
       -  if (CanFire && TotalGunsCarried(Play) == 0)
       -    gtk_widget_show(Stand);
       -  else
       -    gtk_widget_hide(Stand);
       -  if (fp != F_LASTLEAVE)
       -    gtk_widget_show(Run);
       -  else
       -    gtk_widget_hide(Run);
       -}
       -
       -/* 
       - * Updates the display of pertinent data about player "Play" (location,
       - * health, etc. in the status widgets given by "Status". This can point
       - * to the widgets at the top of the main window, or those in a Spy
       - * Reports dialog.
       - */
       -void DisplayStats(Player *Play, struct StatusWidgets *Status)
       -{
       -  gchar *prstr;
       -  GString *text;
       -
       -  text = g_string_new(NULL);
       -
       -  gtk_label_set_text(GTK_LABEL(Status->Location),
       -                     Location[(int)Play->IsAt].Name);
       -
       -  g_string_sprintf(text, "%s%02d%s", Names.Month, Play->Turn, Names.Year);
       -  gtk_label_set_text(GTK_LABEL(Status->Date), text->str);
       -
       -  g_string_sprintf(text, "%d", Play->CoatSize);
       -  gtk_label_set_text(GTK_LABEL(Status->SpaceValue), text->str);
       -
       -  prstr = FormatPrice(Play->Cash);
       -  gtk_label_set_text(GTK_LABEL(Status->CashValue), prstr);
       -  g_free(prstr);
       -
       -  prstr = FormatPrice(Play->Bank);
       -  gtk_label_set_text(GTK_LABEL(Status->BankValue), prstr);
       -  g_free(prstr);
       -
       -  prstr = FormatPrice(Play->Debt);
       -  gtk_label_set_text(GTK_LABEL(Status->DebtValue), prstr);
       -  g_free(prstr);
       -
       -  /* Display of carried guns in GTK+ client status window (%Tde="Guns" by
       -   * default) */
       -  dpg_string_sprintf(text, _("%/GTK Stats: Guns/%Tde"), Names.Guns);
       -  gtk_label_set_text(GTK_LABEL(Status->GunsName), text->str);
       -  g_string_sprintf(text, "%d", TotalGunsCarried(Play));
       -  gtk_label_set_text(GTK_LABEL(Status->GunsValue), text->str);
       -
       -  if (!WantAntique) {
       -    /* Display of number of bitches in GTK+ client status window
       -     * (%Tde="Bitches" by default) */
       -    dpg_string_sprintf(text, _("%/GTK Stats: Bitches/%Tde"),
       -                       Names.Bitches);
       -    gtk_label_set_text(GTK_LABEL(Status->BitchesName), text->str);
       -    g_string_sprintf(text, "%d", Play->Bitches.Carried);
       -    gtk_label_set_text(GTK_LABEL(Status->BitchesValue), text->str);
       -  } else {
       -    gtk_label_set_text(GTK_LABEL(Status->BitchesName), NULL);
       -    gtk_label_set_text(GTK_LABEL(Status->BitchesValue), NULL);
       -  }
       -
       -  g_string_sprintf(text, "%d", Play->Health);
       -  gtk_label_set_text(GTK_LABEL(Status->HealthValue), text->str);
       -
       -  g_string_free(text, TRUE);
       -}
       -
       -/* 
       - * Updates all of the player status in response to a message from the
       - * server. This includes the main window display, the gun shop (if
       - * displayed) and the inventory (if displayed).
       - */
       -void UpdateStatus(Player *Play)
       -{
       -  GtkAccelGroup *accel_group;
       -
       -  DisplayStats(Play, &ClientData.Status);
       -  UpdateInventory(&ClientData.Drug, ClientData.Play->Drugs, NumDrug, TRUE);
       -  gtk_clist_sort(GTK_CLIST(ClientData.Drug.HereList));
       -  accel_group = (GtkAccelGroup *)
       -      gtk_object_get_data(GTK_OBJECT(ClientData.window), "accel_group");
       -  SetJetButtonTitle(accel_group);
       -  if (IsShowingGunShop) {
       -    UpdateInventory(&ClientData.Gun, ClientData.Play->Guns, NumGun, FALSE);
       -  }
       -  if (IsShowingInventory) {
       -    UpdateInventory(&ClientData.InvenDrug, ClientData.Play->Drugs,
       -                    NumDrug, TRUE);
       -    UpdateInventory(&ClientData.InvenGun, ClientData.Play->Guns,
       -                    NumGun, FALSE);
       -  }
       -}
       -
       -void UpdateInventory(struct InventoryWidgets *Inven,
       -                     Inventory *Objects, int NumObjects, gboolean AreDrugs)
       -{
       -  GtkWidget *herelist, *carrylist;
       -  Player *Play;
       -  gint i, row, selectrow[2];
       -  gpointer rowdata;
       -  price_t price;
       -  gchar *titles[2];
       -  gboolean CanBuy = FALSE, CanSell = FALSE, CanDrop = FALSE;
       -  GList *glist[2], *selection;
       -  GtkCList *clist[2];
       -  int numlist;
       -
       -  Play = ClientData.Play;
       -  herelist = Inven->HereList;
       -  carrylist = Inven->CarriedList;
       -
       -  if (herelist)
       -    numlist = 2;
       -  else
       -    numlist = 1;
       -
       -  /* Make lists of the current selections */
       -  clist[0] = GTK_CLIST(carrylist);
       -  if (herelist)
       -    clist[1] = GTK_CLIST(herelist);
       -  else
       -    clist[1] = NULL;
       -
       -  for (i = 0; i < numlist; i++) {
       -    glist[i] = NULL;
       -    selectrow[i] = -1;
       -    for (selection = clist[i]->selection; selection;
       -         selection = g_list_next(selection)) {
       -      row = GPOINTER_TO_INT(selection->data);
       -      rowdata = gtk_clist_get_row_data(clist[i], row);
       -      glist[i] = g_list_append(glist[i], rowdata);
       -    }
       -  }
       -
       -  gtk_clist_freeze(GTK_CLIST(carrylist));
       -  gtk_clist_clear(GTK_CLIST(carrylist));
       -
       -  if (herelist) {
       -    gtk_clist_freeze(GTK_CLIST(herelist));
       -    gtk_clist_clear(GTK_CLIST(herelist));
       -  }
       -
       -  for (i = 0; i < NumObjects; i++) {
       -    if (AreDrugs) {
       -      titles[0] = Drug[i].Name;
       -      price = Objects[i].Price;
       -    } else {
       -      titles[0] = Gun[i].Name;
       -      price = Gun[i].Price;
       -    }
       -
       -    if (herelist && price > 0) {
       -      CanBuy = TRUE;
       -      titles[1] = FormatPrice(price);
       -      row = gtk_clist_append(GTK_CLIST(herelist), titles);
       -      g_free(titles[1]);
       -      gtk_clist_set_row_data(GTK_CLIST(herelist), row, GINT_TO_POINTER(i));
       -      if (g_list_find(glist[1], GINT_TO_POINTER(i))) {
       -        selectrow[1] = row;
       -        gtk_clist_select_row(GTK_CLIST(herelist), row, 0);
       -      }
       -    }
       -
       -    if (Objects[i].Carried > 0) {
       -      if (price > 0)
       -        CanSell = TRUE;
       -      else
       -        CanDrop = TRUE;
       -      if (HaveAbility(ClientData.Play, A_DRUGVALUE) && AreDrugs) {
       -        titles[1] = dpg_strdup_printf("%d @ %P", Objects[i].Carried,
       -                                      Objects[i].TotalValue /
       -                                      Objects[i].Carried);
       -      } else {
       -        titles[1] = g_strdup_printf("%d", Objects[i].Carried);
       -      }
       -      row = gtk_clist_append(GTK_CLIST(carrylist), titles);
       -      g_free(titles[1]);
       -      gtk_clist_set_row_data(GTK_CLIST(carrylist), row,
       -                             GINT_TO_POINTER(i));
       -      if (g_list_find(glist[0], GINT_TO_POINTER(i))) {
       -        selectrow[0] = row;
       -        gtk_clist_select_row(GTK_CLIST(carrylist), row, 0);
       -      }
       -    }
       -  }
       -
       -  for (i = 0; i < numlist; i++) {
       -    if (selectrow[i] != -1 && gtk_clist_row_is_visible(clist[i],
       -                                                       selectrow[i]) !=
       -        GTK_VISIBILITY_FULL) {
       -      gtk_clist_moveto(clist[i], selectrow[i], 0, 0.0, 0.0);
       -    }
       -    g_list_free(glist[i]);
       -  }
       -
       -  gtk_clist_thaw(GTK_CLIST(carrylist));
       -  if (herelist)
       -    gtk_clist_thaw(GTK_CLIST(herelist));
       -
       -  if (Inven->vbbox) {
       -    gtk_widget_set_sensitive(Inven->BuyButton, CanBuy);
       -    gtk_widget_set_sensitive(Inven->SellButton, CanSell);
       -    gtk_widget_set_sensitive(Inven->DropButton, CanDrop);
       -  }
       -}
       -
       -static void JetCallback(GtkWidget *widget, gpointer data)
       -{
       -  int NewLocation;
       -  gchar *text;
       -  GtkWidget *JetDialog;
       -
       -  JetDialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "dialog"));
       -  NewLocation = GPOINTER_TO_INT(data);
       -  gtk_widget_destroy(JetDialog);
       -  text = g_strdup_printf("%d", NewLocation);
       -  SendClientMessage(ClientData.Play, C_NONE, C_REQUESTJET, NULL, text);
       -  g_free(text);
       -}
       -
       -void JetButtonPressed(GtkWidget *widget, gpointer data)
       -{
       -  if (InGame) {
       -    if (ClientData.Play->Flags & FIGHTING) {
       -      DisplayFightMessage(NULL);
       -    } else {
       -      Jet(NULL);
       -    }
       -  }
       -}
       -
       -void Jet(GtkWidget *parent)
       -{
       -  GtkWidget *dialog, *table, *button, *label, *vbox;
       -  GtkAccelGroup *accel_group;
       -  gint boxsize, i, row, col;
       -  gchar *name, AccelChar;
       -
       -  accel_group = gtk_accel_group_new();
       -
       -  dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       -  /* Title of 'Jet' dialog */
       -  gtk_window_set_title(GTK_WINDOW(dialog), _("Jet to location"));
       -
       -  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       -  gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group);
       -  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       -                               parent ? GTK_WINDOW(parent)
       -                               : GTK_WINDOW(ClientData.window));
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -
       -  /* Prompt in 'Jet' dialog */
       -  label = gtk_label_new(_("Where to, dude ? "));
       -  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       -
       -  /* Generate a square box of buttons for all locations */
       -  boxsize = 1;
       -  while (boxsize * boxsize < NumLocation)
       -    boxsize++;
       -  col = boxsize;
       -  row = 1;
       -
       -  /* Avoid creating a box with an entire row empty at the bottom */
       -  while (row * col < NumLocation)
       -    row++;
       -
       -  table = gtk_table_new(row, col, TRUE);
       -
       -  for (i = 0; i < NumLocation; i++) {
       -    if (i < 9)
       -      AccelChar = '1' + i;
       -    else if (i < 35)
       -      AccelChar = 'A' + i - 9;
       -    else
       -      AccelChar = '\0';
       -
       -    row = i / boxsize;
       -    col = i % boxsize;
       -    if (AccelChar == '\0') {
       -      button = gtk_button_new_with_label(Location[i].Name);
       -    } else {
       -      button = gtk_button_new_with_label("");
       -
       -      /* Display of locations in 'Jet' window (%tde="The Bronx" etc. by
       -       * default) */
       -      name = dpg_strdup_printf(_("_%c. %tde"), AccelChar, Location[i].Name);
       -      SetAccelerator(button, name, button, "clicked", accel_group);
       -      /* Add keypad shortcuts as well */
       -      if (i < 9) {
       -        gtk_widget_add_accelerator(button, "clicked", accel_group,
       -                                   GDK_KP_1 + i, 0,
       -                                   GTK_ACCEL_VISIBLE |
       -                                   GTK_ACCEL_SIGNAL_VISIBLE);
       -      }
       -      g_free(name);
       -    }
       -    gtk_widget_set_sensitive(button, i != ClientData.Play->IsAt);
       -    gtk_object_set_data(GTK_OBJECT(button), "dialog", dialog);
       -    gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                       GTK_SIGNAL_FUNC(JetCallback), GINT_TO_POINTER(i));
       -    gtk_table_attach_defaults(GTK_TABLE(table), button, col, col + 1, row,
       -                              row + 1);
       -  }
       -  gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
       -
       -  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       -  gtk_widget_show_all(dialog);
       -}
       -
       -struct DealDiaStruct {
       -  GtkWidget *dialog, *cost, *carrying, *space, *afford, *amount;
       -  gint DrugInd;
       -  gpointer Type;
       -};
       -static struct DealDiaStruct DealDialog;
       -
       -static void UpdateDealDialog(void)
       -{
       -  GString *text;
       -  GtkAdjustment *spin_adj;
       -  gint DrugInd, CanDrop, CanCarry, CanAfford, MaxDrug;
       -  Player *Play;
       -
       -  text = g_string_new(NULL);
       -  DrugInd = DealDialog.DrugInd;
       -  Play = ClientData.Play;
       -
       -  /* Display of the current price of the selected drug in 'Deal Drugs'
       -   * dialog */
       -  dpg_string_sprintf(text, _("at %P"), Play->Drugs[DrugInd].Price);
       -  gtk_label_set_text(GTK_LABEL(DealDialog.cost), text->str);
       -
       -  CanDrop = Play->Drugs[DrugInd].Carried;
       -
       -  /* Display of current inventory of the selected drug in 'Deal Drugs'
       -   * dialog (%tde="Opium" etc. by default) */
       -  dpg_string_sprintf(text, _("You are currently carrying %d %tde"),
       -                     CanDrop, Drug[DrugInd].Name);
       -  gtk_label_set_text(GTK_LABEL(DealDialog.carrying), text->str);
       -
       -  CanCarry = Play->CoatSize;
       -
       -  /* Available space for drugs in 'Deal Drugs' dialog */
       -  g_string_sprintf(text, _("Available space: %d"), CanCarry);
       -  gtk_label_set_text(GTK_LABEL(DealDialog.space), text->str);
       -
       -  if (DealDialog.Type == BT_BUY) {
       -    CanAfford = Play->Cash / Play->Drugs[DrugInd].Price;
       -
       -    /* Number of the selected drug that you can afford in 'Deal Drugs'
       -     * dialog */
       -    g_string_sprintf(text, _("You can afford %d"), CanAfford);
       -    gtk_label_set_text(GTK_LABEL(DealDialog.afford), text->str);
       -    MaxDrug = MIN(CanCarry, CanAfford);
       -  } else
       -    MaxDrug = CanDrop;
       -
       -  spin_adj = (GtkAdjustment *)gtk_adjustment_new(MaxDrug, 1.0, MaxDrug,
       -                                                 1.0, 10.0, 10.0);
       -  gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(DealDialog.amount),
       -                                 spin_adj);
       -  gtk_spin_button_set_value(GTK_SPIN_BUTTON(DealDialog.amount), MaxDrug);
       -
       -  g_string_free(text, TRUE);
       -}
       -
       -static void DealSelectCallback(GtkWidget *widget, gpointer data)
       -{
       -  DealDialog.DrugInd = GPOINTER_TO_INT(data);
       -  UpdateDealDialog();
       -}
       -
       -static void DealOKCallback(GtkWidget *widget, gpointer data)
       -{
       -  GtkWidget *spinner;
       -  gint amount;
       -  gchar *text;
       -
       -  spinner = DealDialog.amount;
       -
       -  gtk_spin_button_update(GTK_SPIN_BUTTON(spinner));
       -  amount = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner));
       -
       -  text = g_strdup_printf("drug^%d^%d", DealDialog.DrugInd,
       -                         data == BT_BUY ? amount : -amount);
       -  SendClientMessage(ClientData.Play, C_NONE, C_BUYOBJECT, NULL, text);
       -  g_free(text);
       -
       -  gtk_widget_destroy(DealDialog.dialog);
       -}
       -
       -void DealDrugs(GtkWidget *widget, gpointer data)
       -{
       -  GtkWidget *dialog, *label, *hbox, *hbbox, *button, *spinner, *menu,
       -      *optionmenu, *menuitem, *vbox, *hsep;
       -  GtkAdjustment *spin_adj;
       -  GtkAccelGroup *accel_group;
       -  GtkWidget *clist;
       -  gchar *Action;
       -  GString *text;
       -  GList *selection;
       -  gint row;
       -  Player *Play;
       -  gint DrugInd, i, SelIndex, FirstInd;
       -  gboolean DrugIndOK;
       -
       -  /* Action in 'Deal Drugs' dialog - "Buy/Sell/Drop Drugs" */
       -  if (data == BT_BUY)
       -    Action = _("Buy");
       -  else if (data == BT_SELL)
       -    Action = _("Sell");
       -  else if (data == BT_DROP)
       -    Action = _("Drop");
       -  else {
       -    g_warning("Bad DealDrug type");
       -    return;
       -  }
       -
       -  DealDialog.Type = data;
       -  Play = ClientData.Play;
       -
       -  if (data == BT_BUY)
       -    clist = ClientData.Drug.HereList;
       -  else
       -    clist = ClientData.Drug.CarriedList;
       -  selection = GTK_CLIST(clist)->selection;
       -  if (selection) {
       -    row = GPOINTER_TO_INT(selection->data);
       -    DrugInd =
       -        GPOINTER_TO_INT(gtk_clist_get_row_data(GTK_CLIST(clist), row));
       -  } else
       -    DrugInd = -1;
       -
       -  DrugIndOK = FALSE;
       -  FirstInd = -1;
       -  for (i = 0; i < NumDrug; i++) {
       -    if ((data == BT_DROP && Play->Drugs[i].Carried > 0
       -         && Play->Drugs[i].Price == 0)
       -        || (data == BT_SELL && Play->Drugs[i].Carried > 0
       -         && Play->Drugs[i].Price != 0)
       -        || (data == BT_BUY && Play->Drugs[i].Price != 0)) {
       -      if (FirstInd == -1)
       -        FirstInd = i;
       -      if (DrugInd == i)
       -        DrugIndOK = TRUE;
       -    }
       -  }
       -  if (!DrugIndOK) {
       -    if (FirstInd == -1)
       -      return;
       -    else
       -      DrugInd = FirstInd;
       -  }
       -
       -  text = g_string_new(NULL);
       -  accel_group = gtk_accel_group_new();
       -  dialog = DealDialog.dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       -  gtk_window_set_title(GTK_WINDOW(dialog), Action);
       -  gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group);
       -  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       -  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       -                               GTK_WINDOW(ClientData.window));
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -
       -  hbox = gtk_hbox_new(FALSE, 7);
       -
       -  label = gtk_label_new(Action);
       -  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
       -
       -  optionmenu = gtk_option_menu_new();
       -  menu = gtk_menu_new();
       -  SelIndex = -1;
       -  for (i = 0; i < NumDrug; i++) {
       -    if ((data == BT_DROP && Play->Drugs[i].Carried > 0
       -         && Play->Drugs[i].Price == 0)
       -        || (data == BT_SELL && Play->Drugs[i].Carried > 0
       -         && Play->Drugs[i].Price != 0)
       -        || (data == BT_BUY && Play->Drugs[i].Price != 0)) {
       -      menuitem = gtk_menu_item_new_with_label(Drug[i].Name);
       -      gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
       -                         GTK_SIGNAL_FUNC(DealSelectCallback),
       -                         GINT_TO_POINTER(i));
       -      gtk_menu_append(GTK_MENU(menu), menuitem);
       -      if (DrugInd >= i)
       -        SelIndex++;
       -    }
       -  }
       -  gtk_menu_set_active(GTK_MENU(menu), SelIndex);
       -  gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu), menu);
       -  gtk_box_pack_start(GTK_BOX(hbox), optionmenu, TRUE, TRUE, 0);
       -
       -  DealDialog.DrugInd = DrugInd;
       -
       -  label = DealDialog.cost = gtk_label_new(NULL);
       -  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
       -  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
       -
       -  label = DealDialog.carrying = gtk_label_new(NULL);
       -  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       -
       -  label = DealDialog.space = gtk_label_new(NULL);
       -  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       -
       -  if (data == BT_BUY) {
       -    label = DealDialog.afford = gtk_label_new(NULL);
       -    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       -  }
       -  hbox = gtk_hbox_new(FALSE, 7);
       -  if (data == BT_BUY) {
       -    /* Prompts for action in the "deal drugs" dialog */
       -    g_string_sprintf(text, _("Buy how many?"));
       -  } else if (data == BT_SELL) {
       -    g_string_sprintf(text, _("Sell how many?"));
       -  } else {
       -    g_string_sprintf(text, _("Drop how many?"));
       -  }
       -  label = gtk_label_new(text->str);
       -  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
       -  spin_adj = (GtkAdjustment *)gtk_adjustment_new(1.0, 1.0, 2.0,
       -                                                 1.0, 10.0, 10.0);
       -  spinner = DealDialog.amount = gtk_spin_button_new(spin_adj, 1.0, 0);
       -  gtk_signal_connect(GTK_OBJECT(spinner), "activate",
       -                     GTK_SIGNAL_FUNC(DealOKCallback), data);
       -  gtk_box_pack_start(GTK_BOX(hbox), spinner, FALSE, FALSE, 0);
       -  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -
       -  hbbox = gtk_hbutton_box_new();
       -  button = gtk_button_new_with_label(_("OK"));
       -  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                     GTK_SIGNAL_FUNC(DealOKCallback), data);
       -  GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
       -  gtk_widget_grab_default(button);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -
       -  /* Caption of "Cancel" button for GTK+ client dialogs */
       -  button = gtk_button_new_with_label(_("Cancel"));
       -  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       -                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       -                            (gpointer)dialog);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
       -  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       -
       -  g_string_free(text, TRUE);
       -  UpdateDealDialog();
       -
       -  gtk_widget_show_all(dialog);
       -}
       -
       -void DealGuns(GtkWidget *widget, gpointer data)
       -{
       -  GtkWidget *clist, *dialog;
       -  GList *selection;
       -  gint row, GunInd;
       -  gchar *Action, *Title;
       -  GString *text;
       -
       -  dialog = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
       -  if (data == BT_BUY)
       -    Action = _("Buy");
       -  else if (data == BT_SELL)
       -    Action = _("Sell");
       -  else
       -    Action = _("Drop");
       -
       -  if (data == BT_BUY)
       -    clist = ClientData.Gun.HereList;
       -  else
       -    clist = ClientData.Gun.CarriedList;
       -  selection = GTK_CLIST(clist)->selection;
       -  if (selection) {
       -    row = GPOINTER_TO_INT(selection->data);
       -    GunInd =
       -        GPOINTER_TO_INT(gtk_clist_get_row_data(GTK_CLIST(clist), row));
       -  } else
       -    return;
       -
       -
       -  /* Title of 'gun shop' dialog (%tde="guns" by default) "Buy/Sell/Drop
       -   * Guns" */
       -  if (data == BT_BUY)
       -    Title = dpg_strdup_printf(_("Buy %tde"), Names.Guns);
       -  else if (data == BT_SELL)
       -    Title = dpg_strdup_printf(_("Sell %tde"), Names.Guns);
       -  else
       -    Title = dpg_strdup_printf(_("Drop %tde"), Names.Guns);
       -
       -  text = g_string_new("");
       -
       -  if (data != BT_BUY && TotalGunsCarried(ClientData.Play) == 0) {
       -    dpg_string_sprintf(text, _("You don't have any %tde to sell!"),
       -                       Names.Guns);
       -    GtkMessageBox(dialog, text->str, Title, MB_OK);
       -  } else if (data == BT_BUY && TotalGunsCarried(ClientData.Play) >=
       -             ClientData.Play->Bitches.Carried + 2) {
       -    dpg_string_sprintf(text,
       -                       _("You'll need more %tde to carry any more %tde!"),
       -                       Names.Bitches, Names.Guns);
       -    GtkMessageBox(dialog, text->str, Title, MB_OK);
       -  } else if (data == BT_BUY
       -             && Gun[GunInd].Space > ClientData.Play->CoatSize) {
       -    dpg_string_sprintf(text,
       -                       _("You don't have enough space to carry that %tde!"),
       -                       Names.Gun);
       -    GtkMessageBox(dialog, text->str, Title, MB_OK);
       -  } else if (data == BT_BUY && Gun[GunInd].Price > ClientData.Play->Cash) {
       -    dpg_string_sprintf(text,
       -                       _("You don't have enough cash to buy that %tde!"),
       -                       Names.Gun);
       -    GtkMessageBox(dialog, text->str, Title, MB_OK);
       -  } else if (data == BT_SELL && ClientData.Play->Guns[GunInd].Carried == 0) {
       -    GtkMessageBox(dialog, _("You don't have any to sell!"), Title, MB_OK);
       -  } else {
       -    g_string_sprintf(text, "gun^%d^%d", GunInd, data == BT_BUY ? 1 : -1);
       -    SendClientMessage(ClientData.Play, C_NONE, C_BUYOBJECT, NULL,
       -                      text->str);
       -  }
       -  g_free(Title);
       -  g_string_free(text, TRUE);
       -}
       -
       -static void QuestionCallback(GtkWidget *widget, gpointer data)
       -{
       -  gint Answer;
       -  gchar text[5];
       -  GtkWidget *dialog;
       -  Player *To;
       -
       -  dialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "dialog"));
       -  To = (Player *)gtk_object_get_data(GTK_OBJECT(dialog), "From");
       -  Answer = GPOINTER_TO_INT(data);
       -
       -  text[0] = (gchar)Answer;
       -  text[1] = '\0';
       -  SendClientMessage(ClientData.Play, C_NONE, C_ANSWER, To, text);
       -
       -  gtk_widget_destroy(dialog);
       -}
       -
       -void QuestionDialog(char *Data, Player *From)
       -{
       -  GtkWidget *dialog, *label, *vbox, *hsep, *hbbox, *button;
       -  GtkAccelGroup *accel_group;
       -  gchar *Responses, **split, *LabelText, *trword, *underline;
       -
       -  /* Button titles that correspond to the single-keypress options provided
       -   * by the curses client (e.g. _Yes corresponds to 'Y' etc.) */
       -  gchar *Words[] = { N_("_Yes"), N_("_No"), N_("_Run"),
       -    N_("_Fight"), N_("_Attack"), N_("_Evade")
       -  };
       -  gint numWords = sizeof(Words) / sizeof(Words[0]);
       -  gint i, j;
       -
       -  split = g_strsplit(Data, "^", 1);
       -  if (!split[0] || !split[1]) {
       -    g_warning("Bad QUESTION message %s", Data);
       -    return;
       -  }
       -
       -  g_strdelimit(split[1], "^", '\n');
       -
       -  Responses = split[0];
       -  LabelText = split[1];
       -
       -  dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       -  accel_group = gtk_accel_group_new();
       -  gtk_signal_connect(GTK_OBJECT(dialog), "delete_event",
       -                     GTK_SIGNAL_FUNC(DisallowDelete), NULL);
       -  gtk_object_set_data(GTK_OBJECT(dialog), "From", (gpointer)From);
       -
       -  /* Title of the 'ask player a question' dialog */
       -  gtk_window_set_title(GTK_WINDOW(dialog), _("Question"));
       -
       -  gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group);
       -  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       -  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       -                               GTK_WINDOW(ClientData.window));
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -  while (*LabelText == '\n')
       -    LabelText++;
       -  label = gtk_label_new(LabelText);
       -  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -
       -  hbbox = gtk_hbutton_box_new();
       -
       -  for (i = 0; i < strlen(Responses); i++) {
       -    for (j = 0, trword = NULL; j < numWords && !trword; j++) {
       -      underline = strchr(Words[j], '_');
       -      if (underline && toupper(underline[1]) == Responses[i]) {
       -        trword = _(Words[j]);
       -      }
       -    }
       -    button = gtk_button_new_with_label("");
       -    if (trword) {
       -      SetAccelerator(button, trword, button, "clicked", accel_group);
       -    } else {
       -      trword = g_strdup_printf("_%c", Responses[i]);
       -      SetAccelerator(button, trword, button, "clicked", accel_group);
       -      g_free(trword);
       -    }
       -    gtk_object_set_data(GTK_OBJECT(button), "dialog", (gpointer)dialog);
       -    gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                       GTK_SIGNAL_FUNC(QuestionCallback),
       -                       GINT_TO_POINTER((gint)Responses[i]));
       -    gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -  }
       -  gtk_box_pack_start(GTK_BOX(vbox), hbbox, TRUE, TRUE, 0);
       -  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       -  gtk_widget_show_all(dialog);
       -
       -  g_strfreev(split);
       -}
       -
       -void StartGame(void)
       -{
       -  Player *Play = ClientData.Play;
       -
       -  InitAbilities(Play);
       -  SendAbilities(Play);
       -  SendNullClientMessage(Play, C_NONE, C_NAME, NULL, GetPlayerName(Play));
       -  InGame = TRUE;
       -  UpdateMenus();
       -  gtk_widget_show_all(ClientData.vbox);
       -  UpdatePlayerLists();
       -}
       -
       -void EndGame(void)
       -{
       -  DisplayFightMessage(NULL);
       -  gtk_widget_hide_all(ClientData.vbox);
       -  gtk_editable_delete_text(GTK_EDITABLE(ClientData.messages), 0, -1);
       -  ShutdownNetwork(ClientData.Play);
       -  UpdatePlayerLists();
       -  CleanUpServer();
       -  RestoreConfig();
       -  InGame = FALSE;
       -  UpdateMenus();
       -}
       -
       -static void ChangeDrugSort(GtkCList *clist, gint column,
       -                           gpointer user_data)
       -{
       -  if (column == 0) {
       -    DrugSortMethod = (DrugSortMethod == DS_ATOZ ? DS_ZTOA : DS_ATOZ);
       -  } else {
       -    DrugSortMethod = (DrugSortMethod == DS_CHEAPFIRST ? DS_CHEAPLAST :
       -                      DS_CHEAPFIRST);
       -  }
       -  gtk_clist_sort(clist);
       -}
       -
       -static gint DrugSortFunc(GtkCList *clist, gconstpointer ptr1,
       -                         gconstpointer ptr2)
       -{
       -  int index1, index2;
       -  price_t pricediff;
       -
       -  index1 = GPOINTER_TO_INT(((const GtkCListRow *)ptr1)->data);
       -  index2 = GPOINTER_TO_INT(((const GtkCListRow *)ptr2)->data);
       -  if (index1 < 0 || index1 >= NumDrug || index2 < 0 || index2 >= NumDrug)
       -    return 0;
       -
       -  switch (DrugSortMethod) {
       -  case DS_ATOZ:
       -    return g_strcasecmp(Drug[index1].Name, Drug[index2].Name);
       -  case DS_ZTOA:
       -    return g_strcasecmp(Drug[index2].Name, Drug[index1].Name);
       -  case DS_CHEAPFIRST:
       -    pricediff = ClientData.Play->Drugs[index1].Price -
       -                ClientData.Play->Drugs[index2].Price;
       -    return pricediff == 0 ? 0 : pricediff < 0 ? -1 : 1;
       -  case DS_CHEAPLAST:
       -    pricediff = ClientData.Play->Drugs[index2].Price -
       -                ClientData.Play->Drugs[index1].Price;
       -    return pricediff == 0 ? 0 : pricediff < 0 ? -1 : 1;
       -  }
       -  return 0;
       -}
       -
       -void UpdateMenus(void)
       -{
       -  gboolean MultiPlayer;
       -  gint Bitches;
       -
       -  MultiPlayer = (FirstClient && FirstClient->next != NULL);
       -  Bitches = InGame
       -      && ClientData.Play ? ClientData.Play->Bitches.Carried : 0;
       -
       -  gtk_widget_set_sensitive(gtk_item_factory_get_widget(ClientData.Menu,
       -                                                       "<main>/Talk"),
       -                           InGame && Network);
       -  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       -                           (ClientData.Menu, "<main>/List"), InGame);
       -  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       -                           (ClientData.Menu, "<main>/List/Players..."),
       -                           InGame && Network);
       -  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       -                           (ClientData.Menu, "<main>/Errands"), InGame);
       -  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       -                           (ClientData.Menu, "<main>/Errands/Spy..."),
       -                           InGame && MultiPlayer);
       -  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       -                           (ClientData.Menu, "<main>/Errands/Tipoff..."),
       -                           InGame && MultiPlayer);
       -  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       -                           (ClientData.Menu,
       -                            "<main>/Errands/Sack Bitch..."), Bitches > 0);
       -  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       -                           (ClientData.Menu,
       -                            "<main>/Errands/Get spy reports..."), InGame
       -                           && MultiPlayer);
       -}
       -
       -GtkWidget *CreateStatusWidgets(struct StatusWidgets *Status)
       -{
       -  GtkWidget *table, *label;
       -
       -  table = gtk_table_new(3, 6, FALSE);
       -  gtk_table_set_row_spacings(GTK_TABLE(table), 3);
       -  gtk_table_set_col_spacings(GTK_TABLE(table), 3);
       -
       -  label = Status->Location = gtk_label_new(NULL);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 2, 0, 1);
       -
       -  label = Status->Date = gtk_label_new(NULL);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 4, 0, 1);
       -
       -  /* Available space label in GTK+ client status display */
       -  label = Status->SpaceName = gtk_label_new(_("Space"));
       -
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 4, 5, 0, 1);
       -  label = Status->SpaceValue = gtk_label_new(NULL);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 0, 1);
       -
       -  /* Player's cash label in GTK+ client status display */
       -  label = Status->CashName = gtk_label_new(_("Cash"));
       -
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
       -  label = Status->CashValue = gtk_label_new(NULL);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 1, 2);
       -
       -  /* Player's debt label in GTK+ client status display */
       -  label = Status->DebtName = gtk_label_new(_("Debt"));
       -
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 1, 2);
       -  label = Status->DebtValue = gtk_label_new(NULL);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, 1, 2);
       -
       -  /* Player's bank balance label in GTK+ client status display */
       -  label = Status->BankName = gtk_label_new(_("Bank"));
       -
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 4, 5, 1, 2);
       -  label = Status->BankValue = gtk_label_new(NULL);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 1, 2);
       -
       -  label = Status->GunsName = gtk_label_new(NULL);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3);
       -  label = Status->GunsValue = gtk_label_new(NULL);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 2, 3);
       -
       -  label = Status->BitchesName = gtk_label_new(NULL);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 2, 3);
       -  label = Status->BitchesValue = gtk_label_new(NULL);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, 2, 3);
       -
       -  /* Player's health label in GTK+ client status display */
       -  label = Status->HealthName = gtk_label_new(_("Health"));
       -
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 4, 5, 2, 3);
       -  label = Status->HealthValue = gtk_label_new(NULL);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 2, 3);
       -  return table;
       -}
       -
       -void SetJetButtonTitle(GtkAccelGroup *accel_group)
       -{
       -  GtkWidget *button;
       -  guint accel_key;
       -
       -  button = ClientData.JetButton;
       -  accel_key = ClientData.JetAccel;
       -
       -  if (accel_key) {
       -    gtk_widget_remove_accelerator(button, accel_group, accel_key, 0);
       -  }
       -
       -  ClientData.JetAccel = SetAccelerator(button,
       -                                       (ClientData.Play
       -                                        && ClientData.Play->
       -                                        Flags & FIGHTING) ? _("_Fight") :
       -                                       /* Caption of 'Jet' button in main
       -                                        * window */
       -                                       _("_Jet!"), button, "clicked",
       -                                       accel_group);
       -}
       -
       -static void SetIcon(GtkWidget *window, gchar **xpmdata)
       -{
       -#ifndef CYGWIN
       -  GdkBitmap *mask;
       -  GdkPixmap *icon;
       -  GtkStyle *style;
       -
       -  style = gtk_widget_get_style(window);
       -  icon = gdk_pixmap_create_from_xpm_d(window->window, &mask,
       -                                      &style->bg[GTK_STATE_NORMAL],
       -                                      xpmdata);
       -  gdk_window_set_icon(window->window, NULL, icon, mask);
       -#endif
       -}
       -
       -#ifdef CYGWIN
       -char GtkLoop(HINSTANCE hInstance, HINSTANCE hPrevInstance)
       -{
       -#else
       -char GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail)
       -{
       -#endif
       -  GtkWidget *window, *vbox, *vbox2, *hbox, *frame, *table, *menubar, *text,
       -      *vpaned, *button, *clist;
       -  GtkAccelGroup *accel_group;
       -  GtkItemFactory *item_factory;
       -  GtkAdjustment *adj;
       -  gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
       -
       -#ifdef CYGWIN
       -  win32_init(hInstance, hPrevInstance, "mainicon");
       -#else
       -  gtk_set_locale();
       -  if (ReturnOnFail && !gtk_init_check(argc, argv))
       -    return FALSE;
       -  else if (!ReturnOnFail)
       -    gtk_init(argc, argv);
       -#endif
       -
       -  /* Set up message handlers */
       -  ClientMessageHandlerPt = HandleClientMessage;
       -
       -  /* Have the GLib log messages pop up in a nice dialog box */
       -  g_log_set_handler(NULL,
       -                    LogMask() | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING |
       -                    G_LOG_LEVEL_CRITICAL, LogMessage, NULL);
       -
       -  if (!CheckHighScoreFileConfig())
       -    return TRUE;
       -
       -  /* Create the main player */
       -  ClientData.Play = g_new(Player, 1);
       -  FirstClient = AddPlayer(0, ClientData.Play, FirstClient);
       -
       -  window = MainWindow = ClientData.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
       -
       -  /* Title of main window in GTK+ client */
       -  gtk_window_set_title(GTK_WINDOW(window), _("dopewars"));
       -  gtk_window_set_default_size(GTK_WINDOW(window), 450, 390);
       -  gtk_signal_connect(GTK_OBJECT(window), "delete_event",
       -                     GTK_SIGNAL_FUNC(MainDelete), NULL);
       -  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       -                     GTK_SIGNAL_FUNC(DestroyGtk), NULL);
       -
       -  accel_group = gtk_accel_group_new();
       -  gtk_object_set_data(GTK_OBJECT(window), "accel_group", accel_group);
       -  item_factory = ClientData.Menu = gtk_item_factory_new(GTK_TYPE_MENU_BAR,
       -                                                        "<main>",
       -                                                        accel_group);
       -  gtk_item_factory_set_translate_func(item_factory, MenuTranslate, NULL,
       -                                      NULL);
       -
       -  gtk_item_factory_create_items(item_factory, nmenu_items, menu_items,
       -                                NULL);
       -  gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
       -  menubar = gtk_item_factory_get_widget(item_factory, "<main>");
       -
       -  vbox2 = gtk_vbox_new(FALSE, 0);
       -  gtk_box_pack_start(GTK_BOX(vbox2), menubar, FALSE, FALSE, 0);
       -  gtk_widget_show_all(menubar);
       -  UpdateMenus();
       -
       -  vbox = ClientData.vbox = gtk_vbox_new(FALSE, 5);
       -  frame = gtk_frame_new(_("Stats"));
       -
       -  table = CreateStatusWidgets(&ClientData.Status);
       -
       -  gtk_container_add(GTK_CONTAINER(frame), table);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
       -
       -  vpaned = gtk_vpaned_new();
       -
       -  adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 100.0,
       -                                            1.0, 10.0, 10.0);
       -  text = ClientData.messages = gtk_scrolled_text_new(NULL, adj, &hbox);
       -  gtk_widget_set_usize(text, 100, 80);
       -  gtk_text_set_point(GTK_TEXT(text), 0);
       -  gtk_text_set_editable(GTK_TEXT(text), FALSE);
       -  gtk_text_set_word_wrap(GTK_TEXT(text), TRUE);
       -  gtk_paned_pack1(GTK_PANED(vpaned), hbox, TRUE, TRUE);
       -
       -  hbox = gtk_hbox_new(FALSE, 7);
       -  CreateInventory(hbox, Names.Drugs, accel_group, TRUE, TRUE,
       -                  &ClientData.Drug, DealDrugs);
       -  clist = ClientData.Drug.HereList;
       -  gtk_clist_column_titles_active(GTK_CLIST(clist));
       -  gtk_clist_set_compare_func(GTK_CLIST(clist), DrugSortFunc);
       -  gtk_signal_connect(GTK_OBJECT(clist), "click-column",
       -                     GTK_SIGNAL_FUNC(ChangeDrugSort), NULL);
       -
       -  button = ClientData.JetButton = gtk_button_new_with_label("");
       -  ClientData.JetAccel = 0;
       -  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                     GTK_SIGNAL_FUNC(JetButtonPressed), NULL);
       -  gtk_box_pack_start(GTK_BOX(ClientData.Drug.vbbox), button, TRUE, TRUE, 0);
       -  SetJetButtonTitle(accel_group);
       -
       -  gtk_paned_pack2(GTK_PANED(vpaned), hbox, TRUE, TRUE);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), vpaned, TRUE, TRUE, 0);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox2), vbox, TRUE, TRUE, 0);
       -  gtk_container_add(GTK_CONTAINER(window), vbox2);
       -
       -  /* Just show the window, not the vbox - we'll do that when the game
       -   * starts */
       -  gtk_widget_show(vbox2);
       -  gtk_widget_show(window);
       -
       -  gtk_widget_realize(window);
       -
       -  SetIcon(window, dopewars_pill_xpm);
       -
       -  gtk_main();
       -
       -  /* Free the main player */
       -  FirstClient = RemovePlayer(ClientData.Play, FirstClient);
       -
       -  return TRUE;
       -}
       -
       -static void PackCentredURL(GtkWidget *vbox, gchar *title, gchar *target,
       -                           gchar *browser)
       -{
       -  GtkWidget *hbox, *label, *url;
       -
       -  /* There must surely be a nicer way of making the URL centred - but I
       -   * can't think of one... */
       -  hbox = gtk_hbox_new(FALSE, 0);
       -  label = gtk_label_new("");
       -  gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
       -
       -  url = gtk_url_new(title, target, browser);
       -  gtk_box_pack_start(GTK_BOX(hbox), url, FALSE, FALSE, 0);
       -    
       -  label = gtk_label_new("");
       -  gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, FALSE, 0);
       -  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
       -}
       -
       -void display_intro(GtkWidget *widget, gpointer data)
       -{
       -  GtkWidget *dialog, *label, *table, *OKButton, *vbox, *hsep;
       -  gchar *VersionStr, *docindex;
       -  const int rows = 6, cols = 3;
       -  int i, j;
       -  gchar *table_data[6][3] = {
       -    /* Credits labels in GTK+ 'about' dialog */
       -    {N_("Icons and graphics"), "Ocelot Mantis", NULL},
       -    {N_("Drug Dealing and Research"), "Dan Wolf", NULL},
       -    {N_("Play Testing"), "Phil Davis", "Owen Walsh"},
       -    {N_("Extensive Play Testing"), "Katherine Holt",
       -     "Caroline Moore"},
       -    {N_("Constructive Criticism"), "Andrea Elliot-Smith",
       -     "Pete Winn"},
       -    {N_("Unconstructive Criticism"), "James Matthews", NULL}
       -  };
       -
       -  dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       -
       -  /* Title of GTK+ 'about' dialog */
       -  gtk_window_set_title(GTK_WINDOW(dialog), _("About dopewars"));
       -
       -  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       -                               GTK_WINDOW(ClientData.window));
       -  gtk_container_border_width(GTK_CONTAINER(dialog), 10);
       -
       -  vbox = gtk_vbox_new(FALSE, 5);
       -
       -  /* Main content of GTK+ 'about' dialog */
       -  label = gtk_label_new(_("Based on John E. Dell's old Drug Wars game, "
       -                          "dopewars is a simulation of an\nimaginary drug "
       -                          "market.  dopewars is an All-American game which "
       -                          "features\nbuying, selling, and trying to get "
       -                          "past the cops!\n\nThe first thing you need to "
       -                          "do is pay off your debt to the Loan Shark. "
       -                          "After\nthat, your goal is to make as much "
       -                          "money as possible (and stay alive)! You\n"
       -                          "have one month of game time to make "
       -                          "your fortune.\n"));
       -  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       -
       -  /* Version and copyright notice in GTK+ 'about' dialog */
       -  VersionStr = g_strdup_printf(_("Version %s     "
       -                                 "Copyright (C) 1998-2002  "
       -                                 "Ben Webb ben@bellatrix.pcl.ox.ac.uk\n"
       -                                 "dopewars is released under the "
       -                                 "GNU General Public Licence\n"), VERSION);
       -  label = gtk_label_new(VersionStr);
       -  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       -  g_free(VersionStr);
       -
       -  table = gtk_table_new(rows, cols, FALSE);
       -  gtk_table_set_row_spacings(GTK_TABLE(table), 3);
       -  gtk_table_set_col_spacings(GTK_TABLE(table), 3);
       -  for (i = 0; i < rows; i++)
       -    for (j = 0; j < cols; j++)
       -      if (table_data[i][j]) {
       -        if (j == 0)
       -          label = gtk_label_new(_(table_data[i][j]));
       -        else
       -          label = gtk_label_new(table_data[i][j]);
       -        gtk_table_attach_defaults(GTK_TABLE(table), label, j, j + 1, i,
       -                                  i + 1);
       -      }
       -  gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
       -
       -  /* Label at the bottom of GTK+ 'about' dialog */
       -  label = gtk_label_new(_("\nFor information on the command line "
       -                          "options, type dopewars -h at your\n"
       -                          "Unix prompt. This will display a help "
       -                          "screen, listing the available options.\n"));
       -  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       -
       -  docindex = GetDocIndex();
       -  PackCentredURL(vbox, "Local HTML documentation", docindex, WebBrowser);
       -  g_free(docindex);
       -
       -  PackCentredURL(vbox, "http://dopewars.sourceforge.net/",
       -                 "http://dopewars.sourceforge.net/", WebBrowser);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -
       -  OKButton = gtk_button_new_with_label(_("OK"));
       -  gtk_signal_connect_object(GTK_OBJECT(OKButton), "clicked",
       -                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       -                            (gpointer)dialog);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), OKButton, FALSE, FALSE, 0);
       -  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       -
       -  GTK_WIDGET_SET_FLAGS(OKButton, GTK_CAN_DEFAULT);
       -  gtk_widget_grab_default(OKButton);
       -
       -  gtk_widget_show_all(dialog);
       -}
       -
       -static gboolean GetStartGamePlayerName(struct StartGameStruct *widgets,
       -                                       gchar **PlayerName)
       -{
       -  g_free(*PlayerName);
       -  *PlayerName = gtk_editable_get_chars(GTK_EDITABLE(widgets->name), 0, -1);
       -  if (*PlayerName && (*PlayerName)[0])
       -    return TRUE;
       -  else {
       -    GtkMessageBox(widgets->dialog,
       -                  _("You can't start the game without giving a name first!"),
       -                  _("New Game"), MB_OK);
       -    return FALSE;
       -  }
       -}
       -
       -static void SetStartGameStatus(struct StartGameStruct *widgets, gchar *msg)
       -{
       -  gtk_label_set_text(GTK_LABEL(widgets->status),
       -                     msg ? msg : _("Status: Waiting for user input"));
       -}
       -
       -#ifdef NETWORKING
       -static void ConnectError(struct StartGameStruct *widgets, gboolean meta)
       -{
       -  GString *neterr;
       -  gchar *text;
       -  LastError *error;
       -
       -  if (meta)
       -    error = widgets->MetaConn->NetBuf.error;
       -  else
       -    error = ClientData.Play->NetBuf.error;
       -
       -  neterr = g_string_new("");
       -
       -  if (error) {
       -    g_string_assign_error(neterr, error);
       -  } else {
       -    g_string_assign(neterr, _("Connection closed by remote host"));
       -  }
       -
       -  if (meta) {
       -    /* Error: GTK+ client could not connect to the metaserver */
       -    text =
       -        g_strdup_printf(_("Status: Could not connect to metaserver (%s)"),
       -                        neterr->str);
       -  } else {
       -    /* Error: GTK+ client could not connect to the given dopewars server */
       -    text =
       -        g_strdup_printf(_("Status: Could not connect (%s)"), neterr->str);
       -  }
       -
       -  SetStartGameStatus(widgets, text);
       -  g_free(text);
       -  g_string_free(neterr, TRUE);
       -}
       -
       -void FinishServerConnect(struct StartGameStruct *widgets,
       -                         gboolean ConnectOK)
       -{
       -  if (ConnectOK) {
       -    Client = Network = TRUE;
       -    gtk_widget_destroy(widgets->dialog);
       -    StartGame();
       -  } else {
       -    ConnectError(widgets, FALSE);
       -  }
       -}
       -
       -static void DoConnect(struct StartGameStruct *widgets)
       -{
       -  gchar *text;
       -  NetworkBuffer *NetBuf;
       -  NBStatus oldstatus;
       -  NBSocksStatus oldsocks;
       -
       -  NetBuf = &ClientData.Play->NetBuf;
       -
       -  /* Message displayed during the attempted connect to a dopewars server */
       -  text = g_strdup_printf(_("Status: Attempting to contact %s..."),
       -                         ServerName);
       -  SetStartGameStatus(widgets, text);
       -  g_free(text);
       -
       -  /* Terminate any existing connection attempts */
       -  ShutdownNetworkBuffer(NetBuf);
       -  if (widgets->MetaConn) {
       -    CloseHttpConnection(widgets->MetaConn);
       -    widgets->MetaConn = NULL;
       -  }
       -
       -  oldstatus = NetBuf->status;
       -  oldsocks = NetBuf->sockstat;
       -  if (StartNetworkBufferConnect(NetBuf, ServerName, Port)) {
       -    DisplayConnectStatus(widgets, FALSE, oldstatus, oldsocks);
       -    SetNetworkBufferUserPasswdFunc(NetBuf, SocksAuthDialog, NULL);
       -    SetNetworkBufferCallBack(NetBuf, SocketStatus, (gpointer)widgets);
       -  } else {
       -    ConnectError(widgets, FALSE);
       -  }
       -}
       -
       -static void ConnectToServer(GtkWidget *widget,
       -                            struct StartGameStruct *widgets)
       -{
       -  gchar *text;
       -
       -  g_free(ServerName);
       -  ServerName = gtk_editable_get_chars(GTK_EDITABLE(widgets->hostname),
       -                                      0, -1);
       -  text = gtk_editable_get_chars(GTK_EDITABLE(widgets->port), 0, -1);
       -  Port = atoi(text);
       -  g_free(text);
       -
       -  if (!GetStartGamePlayerName(widgets, &ClientData.Play->Name))
       -    return;
       -  DoConnect(widgets);
       -}
       -
       -static void FillMetaServerList(struct StartGameStruct *widgets,
       -                               gboolean UseNewList)
       -{
       -  GtkWidget *metaserv;
       -  ServerData *ThisServer;
       -  gchar *titles[5];
       -  GSList *ListPt;
       -  gint row;
       -
       -  if (UseNewList && !widgets->NewMetaList)
       -    return;
       -
       -  metaserv = widgets->metaserv;
       -  gtk_clist_freeze(GTK_CLIST(metaserv));
       -  gtk_clist_clear(GTK_CLIST(metaserv));
       -
       -  if (UseNewList) {
       -    ClearServerList(&MetaList);
       -    MetaList = widgets->NewMetaList;
       -    widgets->NewMetaList = NULL;
       -  }
       -
       -  for (ListPt = MetaList; ListPt; ListPt = g_slist_next(ListPt)) {
       -    ThisServer = (ServerData *)(ListPt->data);
       -    titles[0] = ThisServer->Name;
       -    titles[1] = g_strdup_printf("%d", ThisServer->Port);
       -    titles[2] = ThisServer->Version;
       -    if (ThisServer->CurPlayers == -1) {
       -      /* Displayed if we don't know how many players are logged on to a
       -       * server */
       -      titles[3] = _("Unknown");
       -    } else {
       -      /* e.g. "5 of 20" means 5 players are logged on to a server, out of
       -       * a maximum of 20 */
       -      titles[3] = g_strdup_printf(_("%d of %d"), ThisServer->CurPlayers,
       -                                  ThisServer->MaxPlayers);
       -    }
       -    titles[4] = ThisServer->Comment;
       -    row = gtk_clist_append(GTK_CLIST(metaserv), titles);
       -    gtk_clist_set_row_data(GTK_CLIST(metaserv), row, (gpointer)ThisServer);
       -    g_free(titles[1]);
       -    if (ThisServer->CurPlayers != -1)
       -      g_free(titles[3]);
       -  }
       -  gtk_clist_thaw(GTK_CLIST(metaserv));
       -}
       -
       -void DisplayConnectStatus(struct StartGameStruct *widgets, gboolean meta,
       -                          NBStatus oldstatus, NBSocksStatus oldsocks)
       -{
       -  NBStatus status;
       -  NBSocksStatus sockstat;
       -  gchar *text;
       -
       -  if (meta) {
       -    status = widgets->MetaConn->NetBuf.status;
       -    sockstat = widgets->MetaConn->NetBuf.sockstat;
       -  } else {
       -    status = ClientData.Play->NetBuf.status;
       -    sockstat = ClientData.Play->NetBuf.sockstat;
       -  }
       -  if (oldstatus == status && sockstat == oldsocks)
       -    return;
       -
       -  switch (status) {
       -  case NBS_PRECONNECT:
       -    break;
       -  case NBS_SOCKSCONNECT:
       -    switch (sockstat) {
       -    case NBSS_METHODS:
       -      text = g_strdup_printf(_("Status: Connected to SOCKS server %s..."),
       -                             Socks.name);
       -      SetStartGameStatus(widgets, text);
       -      g_free(text);
       -      break;
       -    case NBSS_USERPASSWD:
       -      SetStartGameStatus(widgets,
       -                         _("Status: Authenticating with SOCKS server"));
       -      break;
       -    case NBSS_CONNECT:
       -      text =
       -          g_strdup_printf(_("Status: Asking SOCKS for connect to %s..."),
       -                          meta ? MetaServer.Name : ServerName);
       -      SetStartGameStatus(widgets, text);
       -      g_free(text);
       -      break;
       -    }
       -    break;
       -  case NBS_CONNECTED:
       -    if (meta) {
       -      SetStartGameStatus(widgets,
       -                         _("Status: Obtaining server information "
       -                           "from metaserver..."));
       -    }
       -    break;
       -  }
       -}
       -
       -static void MetaDone(struct StartGameStruct *widgets)
       -{
       -  if (IsHttpError(widgets->MetaConn)) {
       -    ConnectError(widgets, TRUE);
       -  } else {
       -    SetStartGameStatus(widgets, NULL);
       -  }
       -  CloseHttpConnection(widgets->MetaConn);
       -  widgets->MetaConn = NULL;
       -  FillMetaServerList(widgets, TRUE);
       -}
       -
       -static void HandleMetaSock(gpointer data, gint socket,
       -                           GdkInputCondition condition)
       -{
       -  struct StartGameStruct *widgets;
       -  gboolean DoneOK;
       -  NBStatus oldstatus;
       -  NBSocksStatus oldsocks;
       -
       -  widgets = (struct StartGameStruct *)data;
       -  if (!widgets->MetaConn)
       -    return;
       -
       -  oldstatus = widgets->MetaConn->NetBuf.status;
       -  oldsocks = widgets->MetaConn->NetBuf.sockstat;
       -
       -  if (NetBufHandleNetwork
       -      (&widgets->MetaConn->NetBuf, condition & GDK_INPUT_READ,
       -       condition & GDK_INPUT_WRITE, &DoneOK)) {
       -    while (HandleWaitingMetaServerData
       -           (widgets->MetaConn, &widgets->NewMetaList, &DoneOK)) {
       -    }
       -  }
       -
       -  if (!DoneOK && HandleHttpCompletion(widgets->MetaConn)) {
       -    MetaDone(widgets);
       -  } else {
       -    DisplayConnectStatus(widgets, TRUE, oldstatus, oldsocks);
       -  }
       -}
       -
       -void MetaSocketStatus(NetworkBuffer *NetBuf, gboolean Read, gboolean Write,
       -                      gboolean CallNow)
       -{
       -  if (NetBuf->InputTag)
       -    gdk_input_remove(NetBuf->InputTag);
       -  NetBuf->InputTag = 0;
       -  if (Read || Write) {
       -    NetBuf->InputTag = gdk_input_add(NetBuf->fd,
       -                                     (Read ? GDK_INPUT_READ : 0) |
       -                                     (Write ? GDK_INPUT_WRITE : 0),
       -                                     HandleMetaSock, NetBuf->CallBackData);
       -  }
       -  if (CallNow)
       -    HandleMetaSock(NetBuf->CallBackData, NetBuf->fd, 0);
       -}
       -
       -static void UpdateMetaServerList(GtkWidget *widget,
       -                                 struct StartGameStruct *widgets)
       -{
       -  GtkWidget *metaserv;
       -  gchar *text;
       -
       -  /* Terminate any existing connection attempts */
       -  ShutdownNetworkBuffer(&ClientData.Play->NetBuf);
       -  if (widgets->MetaConn) {
       -    CloseHttpConnection(widgets->MetaConn);
       -    widgets->MetaConn = NULL;
       -  }
       -
       -  ClearServerList(&widgets->NewMetaList);
       -
       -  /* Message displayed during the attempted connect to the metaserver */
       -  text = g_strdup_printf(_("Status: Attempting to contact %s..."),
       -                         MetaServer.Name);
       -  SetStartGameStatus(widgets, text);
       -  g_free(text);
       -
       -  if (OpenMetaHttpConnection(&widgets->MetaConn)) {
       -    metaserv = widgets->metaserv;
       -    SetHttpAuthFunc(widgets->MetaConn, AuthDialog, NULL);
       -    SetNetworkBufferUserPasswdFunc(&widgets->MetaConn->NetBuf,
       -                                   MetaSocksAuthDialog, NULL);
       -    SetNetworkBufferCallBack(&widgets->MetaConn->NetBuf,
       -                             MetaSocketStatus, (gpointer)widgets);
       -  } else {
       -    ConnectError(widgets, TRUE);
       -    CloseHttpConnection(widgets->MetaConn);
       -    widgets->MetaConn = NULL;
       -  }
       -}
       -
       -static void MetaServerConnect(GtkWidget *widget,
       -                              struct StartGameStruct *widgets)
       -{
       -  GList *selection;
       -  gint row;
       -  GtkWidget *clist;
       -  ServerData *ThisServer;
       -
       -  clist = widgets->metaserv;
       -  selection = GTK_CLIST(clist)->selection;
       -  if (selection) {
       -    row = GPOINTER_TO_INT(selection->data);
       -    ThisServer = (ServerData *)gtk_clist_get_row_data(GTK_CLIST(clist), row);
       -    AssignName(&ServerName, ThisServer->Name);
       -    Port = ThisServer->Port;
       -
       -    if (!GetStartGamePlayerName(widgets, &ClientData.Play->Name))
       -      return;
       -    DoConnect(widgets);
       -  }
       -}
       -#endif /* NETWORKING */
       -
       -static void StartSinglePlayer(GtkWidget *widget,
       -                              struct StartGameStruct *widgets)
       -{
       -  WantAntique =
       -      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widgets->antique));
       -  if (!GetStartGamePlayerName(widgets, &ClientData.Play->Name))
       -    return;
       -  StartGame();
       -  gtk_widget_destroy(widgets->dialog);
       -}
       -
       -static void CloseNewGameDia(GtkWidget *widget,
       -                            struct StartGameStruct *widgets)
       -{
       -#ifdef NETWORKING
       -  /* Terminate any existing connection attempts */
       -  if (ClientData.Play->NetBuf.status != NBS_CONNECTED) {
       -    ShutdownNetworkBuffer(&ClientData.Play->NetBuf);
       -  }
       -  if (widgets->MetaConn) {
       -    CloseHttpConnection(widgets->MetaConn);
       -    widgets->MetaConn = NULL;
       -  }
       -  ClearServerList(&widgets->NewMetaList);
       -#endif
       -}
       -
       -void NewGameDialog(void)
       -{
       -  GtkWidget *vbox, *vbox2, *hbox, *label, *entry, *notebook;
       -  GtkWidget *frame, *button, *dialog;
       -  GtkAccelGroup *accel_group;
       -  static struct StartGameStruct widgets;
       -  guint AccelKey;
       -
       -#ifdef NETWORKING
       -  GtkWidget *clist, *scrollwin, *table, *hbbox;
       -  gchar *server_titles[5], *ServerEntry, *text;
       -  gboolean UpdateMeta = FALSE;
       -
       -  /* Column titles of metaserver information */
       -  server_titles[0] = _("Server");
       -  server_titles[1] = _("Port");
       -  server_titles[2] = _("Version");
       -  server_titles[3] = _("Players");
       -  server_titles[4] = _("Comment");
       -
       -  widgets.MetaConn = NULL;
       -  widgets.NewMetaList = NULL;
       -
       -#endif /* NETWORKING */
       -
       -  widgets.dialog = dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       -  gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
       -                     GTK_SIGNAL_FUNC(CloseNewGameDia), (gpointer)&widgets);
       -
       -  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       -                               GTK_WINDOW(ClientData.window));
       -#ifdef NETWORKING
       -  gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
       -#endif
       -  accel_group = gtk_accel_group_new();
       -
       -  /* Title of 'New Game' dialog */
       -  gtk_window_set_title(GTK_WINDOW(widgets.dialog), _("New Game"));
       -  gtk_container_set_border_width(GTK_CONTAINER(widgets.dialog), 7);
       -  gtk_window_add_accel_group(GTK_WINDOW(widgets.dialog), accel_group);
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -  hbox = gtk_hbox_new(FALSE, 7);
       -
       -  label = gtk_label_new("");
       -
       -  AccelKey = gtk_label_parse_uline(GTK_LABEL(label),
       -                                   /* Prompt for player's name in 'New
       -                                    * Game' dialog */
       -                                   _("Hey dude, what's your _name?"));
       -  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
       -
       -  entry = widgets.name = gtk_entry_new();
       -  gtk_widget_add_accelerator(entry, "grab-focus", accel_group, AccelKey, 0,
       -                             GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE);
       -  gtk_entry_set_text(GTK_ENTRY(entry), GetPlayerName(ClientData.Play));
       -  gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
       -
       -  notebook = gtk_notebook_new();
       -
       -#ifdef NETWORKING
       -  frame = gtk_frame_new(_("Server"));
       -  gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
       -  vbox2 = gtk_vbox_new(FALSE, 7);
       -  gtk_container_set_border_width(GTK_CONTAINER(vbox2), 4);
       -  table = gtk_table_new(2, 2, FALSE);
       -  gtk_table_set_row_spacings(GTK_TABLE(table), 4);
       -  gtk_table_set_col_spacings(GTK_TABLE(table), 4);
       -
       -  /* Prompt for hostname to connect to in GTK+ new game dialog */
       -  label = gtk_label_new(_("Host name"));
       -
       -  gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
       -                   GTK_SHRINK, GTK_SHRINK, 0, 0);
       -  entry = widgets.hostname = gtk_entry_new();
       -
       -  ServerEntry = "localhost";
       -  if (g_strcasecmp(ServerName, SN_META) == 0) {
       -    NewGameType = 2;
       -    UpdateMeta = TRUE;
       -  } else if (g_strcasecmp(ServerName, SN_PROMPT) == 0)
       -    NewGameType = 0;
       -  else if (g_strcasecmp(ServerName, SN_SINGLE) == 0)
       -    NewGameType = 1;
       -  else
       -    ServerEntry = ServerName;
       -
       -  gtk_entry_set_text(GTK_ENTRY(entry), ServerEntry);
       -  gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 0, 1,
       -                   GTK_EXPAND | GTK_SHRINK | GTK_FILL,
       -                   GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
       -  label = gtk_label_new(_("Port"));
       -  gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
       -                   GTK_SHRINK, GTK_SHRINK, 0, 0);
       -  entry = widgets.port = gtk_entry_new();
       -  text = g_strdup_printf("%d", Port);
       -  gtk_entry_set_text(GTK_ENTRY(entry), text);
       -  g_free(text);
       -  gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 1, 2,
       -                   GTK_EXPAND | GTK_SHRINK | GTK_FILL,
       -                   GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox2), table, FALSE, FALSE, 0);
       -
       -  button = gtk_button_new_with_label("");
       -  /* Button to connect to a named dopewars server */
       -  SetAccelerator(button, _("_Connect"), button, "clicked", accel_group);
       -  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                     GTK_SIGNAL_FUNC(ConnectToServer), (gpointer)&widgets);
       -  gtk_box_pack_start(GTK_BOX(vbox2), button, FALSE, FALSE, 0);
       -  gtk_container_add(GTK_CONTAINER(frame), vbox2);
       -  GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
       -  gtk_widget_grab_default(button);
       -
       -  label = gtk_label_new(_("Server"));
       -  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
       -#endif /* NETWORKING */
       -
       -  /* Title of 'New Game' dialog notebook tab for single-player mode */
       -  frame = gtk_frame_new(_("Single player"));
       -  gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
       -  vbox2 = gtk_vbox_new(FALSE, 7);
       -  gtk_container_set_border_width(GTK_CONTAINER(vbox2), 4);
       -  widgets.antique = gtk_check_button_new_with_label("");
       -
       -  /* Checkbox to activate 'antique mode' in single-player games */
       -  SetAccelerator(widgets.antique, _("_Antique mode"), widgets.antique,
       -                 "clicked", accel_group);
       -  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widgets.antique),
       -                               WantAntique);
       -  gtk_box_pack_start(GTK_BOX(vbox2), widgets.antique, FALSE, FALSE, 0);
       -  button = gtk_button_new_with_label("");
       -
       -  /* Button to start a new single-player (standalone, non-network) game */
       -  SetAccelerator(button, _("_Start single-player game"), button,
       -                 "clicked", accel_group);
       -
       -  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                     GTK_SIGNAL_FUNC(StartSinglePlayer),
       -                     (gpointer)&widgets);
       -  gtk_box_pack_start(GTK_BOX(vbox2), button, FALSE, FALSE, 0);
       -  gtk_container_add(GTK_CONTAINER(frame), vbox2);
       -  label = gtk_label_new(_("Single player"));
       -  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
       -
       -#ifdef NETWORKING
       -  /* Title of Metaserver frame in New Game dialog */
       -  frame = gtk_frame_new(_("Metaserver"));
       -  gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
       -
       -  vbox2 = gtk_vbox_new(FALSE, 7);
       -  gtk_container_set_border_width(GTK_CONTAINER(vbox2), 4);
       -
       -  clist = widgets.metaserv =
       -      gtk_scrolled_clist_new_with_titles(5, server_titles, &scrollwin);
       -  gtk_clist_column_titles_passive(GTK_CLIST(clist));
       -  gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_SINGLE);
       -  gtk_clist_set_column_width(GTK_CLIST(clist), 0, 130);
       -  gtk_clist_set_column_width(GTK_CLIST(clist), 1, 35);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox2), scrollwin, TRUE, TRUE, 0);
       -
       -  hbbox = gtk_hbutton_box_new();
       -  button = gtk_button_new_with_label("");
       -
       -  /* Button to update metaserver information */
       -  SetAccelerator(button, _("_Update"), button, "clicked", accel_group);
       -  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                     GTK_SIGNAL_FUNC(UpdateMetaServerList),
       -                     (gpointer)&widgets);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -
       -  button = gtk_button_new_with_label("");
       -  SetAccelerator(button, _("_Connect"), button, "clicked", accel_group);
       -  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                     GTK_SIGNAL_FUNC(MetaServerConnect),
       -                     (gpointer)&widgets);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox2), hbbox, FALSE, FALSE, 0);
       -  gtk_container_add(GTK_CONTAINER(frame), vbox2);
       -
       -  label = gtk_label_new(_("Metaserver"));
       -  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
       -#endif /* NETWORKING */
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
       -
       -  /* Caption of status label in New Game dialog before anything has
       -   * happened */
       -  label = widgets.status = gtk_label_new("");
       -  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       -
       -  gtk_container_add(GTK_CONTAINER(widgets.dialog), vbox);
       -
       -  gtk_widget_grab_focus(widgets.name);
       -#ifdef NETWORKING
       -  if (UpdateMeta) {
       -    UpdateMetaServerList(NULL, &widgets);
       -  } else {
       -    FillMetaServerList(&widgets, FALSE);
       -  }
       -#endif
       -
       -  SetStartGameStatus(&widgets, NULL);
       -  gtk_widget_show_all(widgets.dialog);
       -  gtk_notebook_set_page(GTK_NOTEBOOK(notebook), NewGameType);
       -}
       -
       -static void SendDoneMessage(GtkWidget *widget, gpointer data)
       -{
       -  SendClientMessage(ClientData.Play, C_NONE, C_DONE, NULL, NULL);
       -}
       -
       -static void TransferPayAll(GtkWidget *widget, GtkWidget *dialog)
       -{
       -  gchar *text;
       -
       -  text = pricetostr(ClientData.Play->Debt);
       -  SendClientMessage(ClientData.Play, C_NONE, C_PAYLOAN, NULL, text);
       -  g_free(text);
       -  gtk_widget_destroy(dialog);
       -}
       -
       -static void TransferOK(GtkWidget *widget, GtkWidget *dialog)
       -{
       -  gpointer Debt;
       -  GtkWidget *deposit, *entry;
       -  gchar *text, *title;
       -  price_t money;
       -  gboolean withdraw = FALSE;
       -
       -  Debt = gtk_object_get_data(GTK_OBJECT(dialog), "debt");
       -  entry = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(dialog), "entry"));
       -  text = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
       -  money = strtoprice(text);
       -  g_free(text);
       -
       -  if (Debt) {
       -    /* Title of loan shark dialog - (%Tde="The Loan Shark" by default) */
       -    title = dpg_strdup_printf(_("%/LoanShark window title/%Tde"),
       -                              Names.LoanSharkName);
       -    if (money > ClientData.Play->Debt)
       -      money = ClientData.Play->Debt;
       -  } else {
       -    /* Title of bank dialog - (%Tde="The Bank" by default) */
       -    title = dpg_strdup_printf(_("%/BankName window title/%Tde"),
       -                              Names.BankName);
       -    deposit = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(dialog), "deposit"));
       -    if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(deposit))) {
       -      withdraw = TRUE;
       -    }
       -  }
       -
       -  if (money < 0) {
       -    GtkMessageBox(dialog, _("You must enter a positive amount of money!"),
       -                  title, MB_OK);
       -  } else if (!Debt && withdraw && money > ClientData.Play->Bank) {
       -    GtkMessageBox(dialog, _("There isn't that much money available..."),
       -                  title, MB_OK);
       -  } else if (!withdraw && money > ClientData.Play->Cash) {
       -    GtkMessageBox(dialog, _("You don't have that much money!"),
       -                  title, MB_OK);
       -  } else {
       -    text = pricetostr(withdraw ? -money : money);
       -    SendClientMessage(ClientData.Play, C_NONE,
       -                      Debt ? C_PAYLOAN : C_DEPOSIT, NULL, text);
       -    g_free(text);
       -    gtk_widget_destroy(dialog);
       -  }
       -  g_free(title);
       -}
       -
       -void TransferDialog(gboolean Debt)
       -{
       -  GtkWidget *dialog, *button, *label, *radio, *table, *vbox;
       -  GtkWidget *hbbox, *hsep, *entry;
       -  GSList *group;
       -  GString *text;
       -
       -  text = g_string_new("");
       -
       -  dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       -  gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
       -                     GTK_SIGNAL_FUNC(SendDoneMessage), NULL);
       -  if (Debt) {
       -    /* Title of loan shark dialog - (%Tde="The Loan Shark" by default) */
       -    dpg_string_sprintf(text, _("%/LoanShark window title/%Tde"),
       -                       Names.LoanSharkName);
       -  } else {
       -    /* Title of bank dialog - (%Tde="The Bank" by default) */
       -    dpg_string_sprintf(text, _("%/BankName window title/%Tde"),
       -                       Names.BankName);
       -  }
       -  gtk_window_set_title(GTK_WINDOW(dialog), text->str);
       -  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       -  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       -                               GTK_WINDOW(ClientData.window));
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -  table = gtk_table_new(4, 3, FALSE);
       -  gtk_table_set_row_spacings(GTK_TABLE(table), 4);
       -  gtk_table_set_col_spacings(GTK_TABLE(table), 4);
       -
       -  /* Display of player's cash in bank or loan shark dialog */
       -  dpg_string_sprintf(text, _("Cash: %P"), ClientData.Play->Cash);
       -  label = gtk_label_new(text->str);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 3, 0, 1);
       -
       -  if (Debt) {
       -    /* Display of player's debt in loan shark dialog */
       -    dpg_string_sprintf(text, _("Debt: %P"), ClientData.Play->Debt);
       -  } else {
       -    /* Display of player's bank balance in bank dialog */
       -    dpg_string_sprintf(text, _("Bank: %P"), ClientData.Play->Bank);
       -  }
       -  label = gtk_label_new(text->str);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 3, 1, 2);
       -
       -  gtk_object_set_data(GTK_OBJECT(dialog), "debt", GINT_TO_POINTER(Debt));
       -  if (Debt) {
       -    /* Prompt for paying back a loan */
       -    label = gtk_label_new(_("Pay back:"));
       -    gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 4);
       -  } else {
       -    /* Radio button selected if you want to pay money into the bank */
       -    radio = gtk_radio_button_new_with_label(NULL, _("Deposit"));
       -    gtk_object_set_data(GTK_OBJECT(dialog), "deposit", radio);
       -    group = gtk_radio_button_group(GTK_RADIO_BUTTON(radio));
       -    gtk_table_attach_defaults(GTK_TABLE(table), radio, 0, 1, 2, 3);
       -
       -    /* Radio button selected if you want to withdraw money from the bank */
       -    radio = gtk_radio_button_new_with_label(group, _("Withdraw"));
       -    gtk_table_attach_defaults(GTK_TABLE(table), radio, 0, 1, 3, 4);
       -  }
       -  label = gtk_label_new(Currency.Symbol);
       -  entry = gtk_entry_new();
       -  gtk_entry_set_text(GTK_ENTRY(entry), "0");
       -  gtk_object_set_data(GTK_OBJECT(dialog), "entry", entry);
       -  gtk_signal_connect(GTK_OBJECT(entry), "activate",
       -                     GTK_SIGNAL_FUNC(TransferOK), dialog);
       -
       -  if (Currency.Prefix) {
       -    gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 2, 4);
       -    gtk_table_attach_defaults(GTK_TABLE(table), entry, 2, 3, 2, 4);
       -  } else {
       -    gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 2, 4);
       -    gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 2, 4);
       -  }
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -
       -  hbbox = gtk_hbutton_box_new();
       -  button = gtk_button_new_with_label(_("OK"));
       -  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                     GTK_SIGNAL_FUNC(TransferOK), dialog);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -
       -  if (Debt && ClientData.Play->Cash >= ClientData.Play->Debt) {
       -    /* Button to pay back the entire loan/debt */
       -    button = gtk_button_new_with_label(_("Pay all"));
       -    gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                       GTK_SIGNAL_FUNC(TransferPayAll), dialog);
       -    gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -  }
       -  button = gtk_button_new_with_label(_("Cancel"));
       -  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       -                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       -                            (gpointer)dialog);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -  gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
       -
       -  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       -
       -  gtk_widget_show_all(dialog);
       -
       -  g_string_free(text, TRUE);
       -}
       -
       -void ListPlayers(GtkWidget *widget, gpointer data)
       -{
       -  GtkWidget *dialog, *clist, *button, *vbox, *hsep;
       -
       -  if (IsShowingPlayerList)
       -    return;
       -  dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       -
       -  /* Title of player list dialog */
       -  gtk_window_set_title(GTK_WINDOW(dialog), _("Player List"));
       -
       -  gtk_window_set_default_size(GTK_WINDOW(dialog), 200, 180);
       -  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       -
       -  IsShowingPlayerList = TRUE;
       -  gtk_window_set_modal(GTK_WINDOW(dialog), FALSE);
       -  gtk_object_set_data(GTK_OBJECT(dialog), "IsShowing",
       -                      (gpointer)&IsShowingPlayerList);
       -  gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
       -                     GTK_SIGNAL_FUNC(DestroyShowing), NULL);
       -
       -  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       -                               GTK_WINDOW(ClientData.window));
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -
       -  clist = ClientData.PlayerList = CreatePlayerList();
       -  UpdatePlayerList(clist, FALSE);
       -  gtk_box_pack_start(GTK_BOX(vbox), clist, TRUE, TRUE, 0);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -
       -  button = gtk_button_new_with_label(_("OK"));
       -  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       -                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       -                            (gpointer)dialog);
       -  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
       -  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       -  gtk_widget_show_all(dialog);
       -}
       -
       -struct TalkStruct {
       -  GtkWidget *dialog, *clist, *entry, *checkbutton;
       -};
       -
       -static void TalkSend(GtkWidget *widget, struct TalkStruct *TalkData)
       -{
       -  gboolean AllPlayers;
       -  gchar *text;
       -  GString *msg;
       -  GList *selection;
       -  gint row;
       -  Player *Play;
       -
       -  AllPlayers =
       -      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
       -                                   (TalkData->checkbutton));
       -  text = gtk_editable_get_chars(GTK_EDITABLE(TalkData->entry), 0, -1);
       -  gtk_editable_delete_text(GTK_EDITABLE(TalkData->entry), 0, -1);
       -  if (!text)
       -    return;
       -
       -  msg = g_string_new("");
       -
       -  if (AllPlayers) {
       -    SendClientMessage(ClientData.Play, C_NONE, C_MSG, NULL, text);
       -    g_string_sprintf(msg, "%s: %s", GetPlayerName(ClientData.Play), text);
       -    PrintMessage(msg->str);
       -  } else {
       -    for (selection = GTK_CLIST(TalkData->clist)->selection; selection;
       -         selection = g_list_next(selection)) {
       -      row = GPOINTER_TO_INT(selection->data);
       -      Play =
       -          (Player *)gtk_clist_get_row_data(GTK_CLIST(TalkData->clist),
       -                                           row);
       -      if (Play) {
       -        SendClientMessage(ClientData.Play, C_NONE, C_MSGTO, Play, text);
       -        g_string_sprintf(msg, "%s->%s: %s", GetPlayerName(ClientData.Play),
       -                         GetPlayerName(Play), text);
       -        PrintMessage(msg->str);
       -      }
       -    }
       -  }
       -  g_free(text);
       -  g_string_free(msg, TRUE);
       -}
       -
       -void TalkToAll(GtkWidget *widget, gpointer data)
       -{
       -  TalkDialog(TRUE);
       -}
       -
       -void TalkToPlayers(GtkWidget *widget, gpointer data)
       -{
       -  TalkDialog(FALSE);
       -}
       -
       -void TalkDialog(gboolean TalkToAll)
       -{
       -  GtkWidget *dialog, *clist, *button, *entry, *label, *vbox, *hsep,
       -      *checkbutton, *hbbox;
       -  static struct TalkStruct TalkData;
       -
       -  if (IsShowingTalkList)
       -    return;
       -  dialog = TalkData.dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       -
       -  /* Title of talk dialog */
       -  gtk_window_set_title(GTK_WINDOW(dialog), _("Talk to player(s)"));
       -
       -  gtk_window_set_default_size(GTK_WINDOW(dialog), 200, 190);
       -  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       -
       -  IsShowingTalkList = TRUE;
       -  gtk_window_set_modal(GTK_WINDOW(dialog), FALSE);
       -  gtk_object_set_data(GTK_OBJECT(dialog), "IsShowing",
       -                      (gpointer)&IsShowingTalkList);
       -  gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
       -                     GTK_SIGNAL_FUNC(DestroyShowing), NULL);
       -
       -  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       -                               GTK_WINDOW(ClientData.window));
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -
       -  clist = TalkData.clist = ClientData.TalkList = CreatePlayerList();
       -  UpdatePlayerList(clist, FALSE);
       -  gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_MULTIPLE);
       -  gtk_box_pack_start(GTK_BOX(vbox), clist, TRUE, TRUE, 0);
       -
       -  checkbutton = TalkData.checkbutton =
       -      /* Checkbutton set if you want to talk to all players */
       -      gtk_check_button_new_with_label(_("Talk to all players"));
       -
       -  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TalkToAll);
       -  gtk_box_pack_start(GTK_BOX(vbox), checkbutton, FALSE, FALSE, 0);
       -
       -  /* Prompt for you to enter the message to be sent to other players */
       -  label = gtk_label_new(_("Message:-"));
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       -
       -  entry = TalkData.entry = gtk_entry_new();
       -  gtk_signal_connect(GTK_OBJECT(entry), "activate",
       -                     GTK_SIGNAL_FUNC(TalkSend), (gpointer)&TalkData);
       -  gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -
       -  hbbox = gtk_hbutton_box_new();
       -
       -  /* Button to send a message to other players */
       -  button = gtk_button_new_with_label(_("Send"));
       -
       -  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                     GTK_SIGNAL_FUNC(TalkSend), (gpointer)&TalkData);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -
       -  button = gtk_button_new_with_label(_("Close"));
       -  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       -                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       -                            (gpointer)dialog);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
       -
       -  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       -  gtk_widget_show_all(dialog);
       -}
       -
       -GtkWidget *CreatePlayerList(void)
       -{
       -  GtkWidget *clist;
       -  gchar *text[1];
       -
       -  text[0] = "Name";
       -  clist = gtk_clist_new_with_titles(1, text);
       -  gtk_clist_column_titles_passive(GTK_CLIST(clist));
       -  gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 0, TRUE);
       -  return clist;
       -}
       -
       -void UpdatePlayerList(GtkWidget *clist, gboolean IncludeSelf)
       -{
       -  GSList *list;
       -  gchar *text[1];
       -  gint row;
       -  Player *Play;
       -
       -  gtk_clist_freeze(GTK_CLIST(clist));
       -  gtk_clist_clear(GTK_CLIST(clist));
       -  for (list = FirstClient; list; list = g_slist_next(list)) {
       -    Play = (Player *)list->data;
       -    if (IncludeSelf || Play != ClientData.Play) {
       -      text[0] = GetPlayerName(Play);
       -      row = gtk_clist_append(GTK_CLIST(clist), text);
       -      gtk_clist_set_row_data(GTK_CLIST(clist), row, Play);
       -    }
       -  }
       -  gtk_clist_thaw(GTK_CLIST(clist));
       -}
       -
       -static void ErrandOK(GtkWidget *widget, GtkWidget *clist)
       -{
       -  GList *selection;
       -  Player *Play;
       -  gint row;
       -  GtkWidget *dialog;
       -  gint ErrandType;
       -
       -  dialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "dialog"));
       -  ErrandType = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget),
       -                                                   "errandtype"));
       -  selection = GTK_CLIST(clist)->selection;
       -  if (selection) {
       -    row = GPOINTER_TO_INT(selection->data);
       -    Play = (Player *)gtk_clist_get_row_data(GTK_CLIST(clist), row);
       -    if (ErrandType == ET_SPY) {
       -      SendClientMessage(ClientData.Play, C_NONE, C_SPYON, Play, NULL);
       -    } else {
       -      SendClientMessage(ClientData.Play, C_NONE, C_TIPOFF, Play, NULL);
       -    }
       -    gtk_widget_destroy(dialog);
       -  }
       -}
       -
       -void SpyOnPlayer(GtkWidget *widget, gpointer data)
       -{
       -  ErrandDialog(ET_SPY);
       -}
       -
       -void TipOff(GtkWidget *widget, gpointer data)
       -{
       -  ErrandDialog(ET_TIPOFF);
       -}
       -
       -void ErrandDialog(gint ErrandType)
       -{
       -  GtkWidget *dialog, *clist, *button, *vbox, *hbbox, *hsep, *label;
       -  gchar *text;
       -
       -  dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       -  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       -
       -  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       -                               GTK_WINDOW(ClientData.window));
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -
       -  if (ErrandType == ET_SPY) {
       -    /* Title of dialog to select a player to spy on */
       -    gtk_window_set_title(GTK_WINDOW(dialog), _("Spy On Player"));
       -
       -    /* Informative text for "spy on player" dialog. (%tde = "bitch",
       -     * "bitch", "guns", "drugs", respectively, by default) */
       -    text = dpg_strdup_printf(_("Please choose the player to spy on. "
       -                               "Your %tde will\nthen offer his "
       -                               "services to the player, and if "
       -                               "successful,\nyou will be able to "
       -                               "view the player's stats with the\n"
       -                               "\"Get spy reports\" menu. Remember "
       -                               "that the %tde will leave\nyou, so "
       -                               "any %tde or %tde that he's "
       -                               "carrying may be lost!"), Names.Bitch,
       -                             Names.Bitch, Names.Guns, Names.Drugs);
       -    label = gtk_label_new(text);
       -    g_free(text);
       -  } else {
       -
       -    /* Title of dialog to select a player to tip the cops off to */
       -    gtk_window_set_title(GTK_WINDOW(dialog), _("Tip Off The Cops"));
       -
       -    /* Informative text for "tip off cops" dialog. (%tde = "bitch",
       -     * "bitch", "guns", "drugs", respectively, by default) */
       -    text = dpg_strdup_printf(_("Please choose the player to tip off "
       -                               "the cops to. Your %tde will\nhelp "
       -                               "the cops to attack that player, "
       -                               "and then report back to you\non "
       -                               "the encounter. Remember that the "
       -                               "%tde will leave you temporarily,\n"
       -                               "so any %tde or %tde that he's "
       -                               "carrying may be lost!"), Names.Bitch,
       -                             Names.Bitch, Names.Guns, Names.Drugs);
       -    label = gtk_label_new(text);
       -    g_free(text);
       -  }
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       -
       -  clist = ClientData.PlayerList = CreatePlayerList();
       -  UpdatePlayerList(clist, FALSE);
       -  gtk_box_pack_start(GTK_BOX(vbox), clist, TRUE, TRUE, 0);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -
       -  hbbox = gtk_hbutton_box_new();
       -  button = gtk_button_new_with_label(_("OK"));
       -  gtk_object_set_data(GTK_OBJECT(button), "dialog", dialog);
       -  gtk_object_set_data(GTK_OBJECT(button), "errandtype",
       -                      GINT_TO_POINTER(ErrandType));
       -  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                     GTK_SIGNAL_FUNC(ErrandOK), (gpointer)clist);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -  button = gtk_button_new_with_label(_("Cancel"));
       -  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       -                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       -                            (gpointer)dialog);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
       -  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       -  gtk_widget_show_all(dialog);
       -}
       -
       -void SackBitch(GtkWidget *widget, gpointer data)
       -{
       -  char *title, *text;
       -
       -  /* Cannot sack bitches if you don't have any! */
       -  if (ClientData.Play->Bitches.Carried <= 0)
       -    return;
       -
       -  /* Title of dialog to sack a bitch (%Tde = "Bitch" by default) */
       -  title = dpg_strdup_printf(_("%/Sack Bitch dialog title/Sack %Tde"),
       -                            Names.Bitch);
       -
       -  /* Confirmation message for sacking a bitch. (%tde = "guns", "drugs",
       -   * "bitch", respectively, by default) */
       -  text = dpg_strdup_printf(_("Are you sure? (Any %tde or %tde carried\n"
       -                             "by this %tde may be lost!)"), Names.Guns,
       -                           Names.Drugs, Names.Bitch);
       -
       -  if (GtkMessageBox(ClientData.window, text, title, MB_YESNO) == IDYES) {
       -    ClientData.Play->Bitches.Carried--;
       -    UpdateMenus();
       -    SendClientMessage(ClientData.Play, C_NONE, C_SACKBITCH, NULL, NULL);
       -  }
       -  g_free(text);
       -  g_free(title);
       -}
       -
       -void CreateInventory(GtkWidget *hbox, gchar *Objects,
       -                     GtkAccelGroup *accel_group, gboolean CreateButtons,
       -                     gboolean CreateHere, struct InventoryWidgets *widgets,
       -                     GtkSignalFunc CallBack)
       -{
       -  GtkWidget *scrollwin, *clist, *vbbox, *frame[2], *button[3];
       -  gint i, mini;
       -  GString *text;
       -  gchar *titles[2][2];
       -  gchar *button_text[3];
       -  gpointer button_type[3] = { BT_BUY, BT_SELL, BT_DROP };
       -
       -  /* Column titles for display of drugs/guns carried or available for
       -   * purchase */
       -  titles[0][0] = titles[1][0] = _("Name");
       -  titles[0][1] = _("Price");
       -  titles[1][1] = _("Number");
       -
       -  /* Button titles for buying/selling/dropping guns or drugs */
       -  button_text[0] = _("_Buy ->");
       -  button_text[1] = _("<- _Sell");
       -  button_text[2] = _("_Drop <-");
       -
       -  text = g_string_new("");
       -
       -  if (CreateHere) {
       -    /* Title of the display of available drugs/guns (%Tde = "Guns" or
       -     * "Drugs" by default) */
       -    dpg_string_sprintf(text, _("%Tde here"), Objects);
       -    widgets->HereFrame = frame[0] = gtk_frame_new(text->str);
       -  }
       -
       -  /* Title of the display of carried drugs/guns (%Tde = "Guns" or "Drugs"
       -   * by default) */
       -  dpg_string_sprintf(text, _("%Tde carried"), Objects);
       -
       -  widgets->CarriedFrame = frame[1] = gtk_frame_new(text->str);
       -
       -  widgets->HereList = widgets->CarriedList = NULL;
       -  if (CreateHere)
       -    mini = 0;
       -  else
       -    mini = 1;
       -  for (i = mini; i < 2; i++) {
       -    gtk_container_set_border_width(GTK_CONTAINER(frame[i]), 5);
       -
       -    clist = gtk_scrolled_clist_new_with_titles(2, titles[i], &scrollwin);
       -    gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 0, TRUE);
       -    gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 1, TRUE);
       -    gtk_clist_column_titles_passive(GTK_CLIST(clist));
       -    gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_SINGLE);
       -    gtk_clist_set_auto_sort(GTK_CLIST(clist), FALSE);
       -    gtk_container_add(GTK_CONTAINER(frame[i]), scrollwin);
       -    if (i == 0)
       -      widgets->HereList = clist;
       -    else
       -      widgets->CarriedList = clist;
       -  }
       -  if (CreateHere)
       -    gtk_box_pack_start(GTK_BOX(hbox), frame[0], TRUE, TRUE, 0);
       -
       -  if (CreateButtons) {
       -    widgets->vbbox = vbbox = gtk_vbutton_box_new();
       -
       -    for (i = 0; i < 3; i++) {
       -      button[i] = gtk_button_new_with_label("");
       -      SetAccelerator(button[i], _(button_text[i]), button[i],
       -                     "clicked", accel_group);
       -      if (CallBack)
       -        gtk_signal_connect(GTK_OBJECT(button[i]), "clicked",
       -                           GTK_SIGNAL_FUNC(CallBack), button_type[i]);
       -      gtk_box_pack_start(GTK_BOX(vbbox), button[i], TRUE, TRUE, 0);
       -    }
       -    widgets->BuyButton = button[0];
       -    widgets->SellButton = button[1];
       -    widgets->DropButton = button[2];
       -    gtk_box_pack_start(GTK_BOX(hbox), vbbox, FALSE, FALSE, 0);
       -  } else
       -    widgets->vbbox = NULL;
       -
       -  gtk_box_pack_start(GTK_BOX(hbox), frame[1], TRUE, TRUE, 0);
       -  g_string_free(text, TRUE);
       -}
       -
       -void DestroyShowing(GtkWidget *widget, gpointer data)
       -{
       -  gboolean *IsShowing;
       -
       -  IsShowing =
       -      (gboolean *)gtk_object_get_data(GTK_OBJECT(widget), "IsShowing");
       -  if (IsShowing)
       -    *IsShowing = FALSE;
       -}
       -
       -static void NewNameOK(GtkWidget *widget, GtkWidget *window)
       -{
       -  GtkWidget *entry;
       -  gchar *text;
       -
       -  entry = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(window), "entry"));
       -  text = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
       -  if (text[0]) {
       -    SetPlayerName(ClientData.Play, text);
       -    SendNullClientMessage(ClientData.Play, C_NONE, C_NAME, NULL, text);
       -    gtk_widget_destroy(window);
       -  }
       -  g_free(text);
       -}
       -
       -void NewNameDialog(void)
       -{
       -  GtkWidget *window, *button, *hsep, *vbox, *label, *entry;
       -
       -  window = gtk_window_new(GTK_WINDOW_DIALOG);
       -
       -  /* Title of dialog for changing a player's name */
       -  gtk_window_set_title(GTK_WINDOW(window), _("Change Name"));
       -
       -  gtk_window_set_modal(GTK_WINDOW(window), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(window),
       -                               GTK_WINDOW(ClientData.window));
       -  gtk_container_set_border_width(GTK_CONTAINER(window), 7);
       -  gtk_signal_connect(GTK_OBJECT(window), "delete_event",
       -                     GTK_SIGNAL_FUNC(DisallowDelete), NULL);
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -
       -  /* Informational text to prompt the player to change his/her name */
       -  label = gtk_label_new(_("Unfortunately, somebody else is already "
       -                          "using \"your\" name. Please change it:-"));
       -  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       -
       -  entry = gtk_entry_new();
       -  gtk_object_set_data(GTK_OBJECT(window), "entry", entry);
       -  gtk_signal_connect(GTK_OBJECT(entry), "activate",
       -                     GTK_SIGNAL_FUNC(NewNameOK), window);
       -  gtk_entry_set_text(GTK_ENTRY(entry), GetPlayerName(ClientData.Play));
       -  gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -
       -  button = gtk_button_new_with_label(_("OK"));
       -  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                     GTK_SIGNAL_FUNC(NewNameOK), window);
       -  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
       -  GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
       -  gtk_widget_grab_default(button);
       -
       -  gtk_container_add(GTK_CONTAINER(window), vbox);
       -  gtk_widget_show_all(window);
       -}
       -
       -gint DisallowDelete(GtkWidget *widget, GdkEvent *event, gpointer data)
       -{
       -  return (TRUE);
       -}
       -
       -void GunShopDialog(void)
       -{
       -  GtkWidget *window, *button, *hsep, *vbox, *hbox;
       -  GtkAccelGroup *accel_group;
       -  gchar *text;
       -
       -  window = gtk_window_new(GTK_WINDOW_DIALOG);
       -  gtk_window_set_default_size(GTK_WINDOW(window), 600, 190);
       -  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       -                     GTK_SIGNAL_FUNC(SendDoneMessage), NULL);
       -  accel_group = gtk_accel_group_new();
       -  gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
       -
       -  /* Title of 'gun shop' dialog in GTK+ client (%Tde="Dan's House of Guns"
       -   * by default) */
       -  text = dpg_strdup_printf(_("%/GTK GunShop window title/%Tde"),
       -                           Names.GunShopName);
       -  gtk_window_set_title(GTK_WINDOW(window), text);
       -  g_free(text);
       -  gtk_window_set_modal(GTK_WINDOW(window), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(window),
       -                               GTK_WINDOW(ClientData.window));
       -  gtk_container_set_border_width(GTK_CONTAINER(window), 7);
       -  IsShowingGunShop = TRUE;
       -  gtk_object_set_data(GTK_OBJECT(window), "IsShowing",
       -                      (gpointer)&IsShowingGunShop);
       -  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       -                     GTK_SIGNAL_FUNC(DestroyShowing), NULL);
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -
       -  hbox = gtk_hbox_new(FALSE, 7);
       -  CreateInventory(hbox, Names.Guns, accel_group, TRUE, TRUE,
       -                  &ClientData.Gun, DealGuns);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -
       -  /* Button to finish buying/selling guns in the gun shop */
       -  button = gtk_button_new_with_label(_("Done"));
       -
       -  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       -                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       -                            (gpointer)window);
       -  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
       -
       -  gtk_container_add(GTK_CONTAINER(window), vbox);
       -
       -  UpdateInventory(&ClientData.Gun, ClientData.Play->Guns, NumGun, FALSE);
       -  gtk_widget_show_all(window);
       -}
       -
       -void UpdatePlayerLists(void)
       -{
       -  if (IsShowingPlayerList)
       -    UpdatePlayerList(ClientData.PlayerList, FALSE);
       -  if (IsShowingTalkList)
       -    UpdatePlayerList(ClientData.TalkList, FALSE);
       -}
       -
       -void GetSpyReports(GtkWidget *Widget, gpointer data)
       -{
       -  SendClientMessage(ClientData.Play, C_NONE, C_CONTACTSPY, NULL, NULL);
       -}
       -
       -static void DestroySpyReports(GtkWidget *widget, gpointer data)
       -{
       -  SpyReportsDialog = NULL;
       -}
       -
       -static void CreateSpyReports(void)
       -{
       -  GtkWidget *window, *button, *vbox, *notebook;
       -  GtkAccelGroup *accel_group;
       -
       -  SpyReportsDialog = window = gtk_window_new(GTK_WINDOW_DIALOG);
       -  accel_group = gtk_accel_group_new();
       -  gtk_object_set_data(GTK_OBJECT(window), "accel_group", accel_group);
       -  gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
       -
       -  /* Title of window to display reports from spies with other players */
       -  gtk_window_set_title(GTK_WINDOW(window), _("Spy reports"));
       -
       -  gtk_window_set_modal(GTK_WINDOW(window), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(window),
       -                               GTK_WINDOW(ClientData.window));
       -  gtk_container_set_border_width(GTK_CONTAINER(window), 7);
       -  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       -                     GTK_SIGNAL_FUNC(DestroySpyReports), NULL);
       -
       -  vbox = gtk_vbox_new(FALSE, 5);
       -  notebook = gtk_notebook_new();
       -  gtk_object_set_data(GTK_OBJECT(window), "notebook", notebook);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
       -
       -  button = gtk_button_new_with_label(_("Close"));
       -  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       -                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       -                            (gpointer)window);
       -  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
       -
       -  gtk_container_add(GTK_CONTAINER(window), vbox);
       -
       -  gtk_widget_show_all(window);
       -}
       -
       -void DisplaySpyReports(Player *Play)
       -{
       -  GtkWidget *dialog, *notebook, *vbox, *hbox, *frame, *label, *table;
       -  GtkAccelGroup *accel_group;
       -  struct StatusWidgets Status;
       -  struct InventoryWidgets SpyDrugs, SpyGuns;
       -
       -  if (!SpyReportsDialog)
       -    CreateSpyReports();
       -  dialog = SpyReportsDialog;
       -  notebook =
       -      GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(dialog), "notebook"));
       -  accel_group =
       -      (GtkAccelGroup
       -       *)(gtk_object_get_data(GTK_OBJECT(dialog), "accel_group"));
       -  vbox = gtk_vbox_new(FALSE, 5);
       -  frame = gtk_frame_new("Stats");
       -  gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
       -  table = CreateStatusWidgets(&Status);
       -  gtk_container_add(GTK_CONTAINER(frame), table);
       -  gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
       -
       -  hbox = gtk_hbox_new(FALSE, 5);
       -  CreateInventory(hbox, Names.Drugs, accel_group, FALSE, FALSE, &SpyDrugs,
       -                  NULL);
       -  CreateInventory(hbox, Names.Guns, accel_group, FALSE, FALSE, &SpyGuns,
       -                  NULL);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
       -  label = gtk_label_new(GetPlayerName(Play));
       -
       -  DisplayStats(Play, &Status);
       -  UpdateInventory(&SpyDrugs, Play->Drugs, NumDrug, TRUE);
       -  UpdateInventory(&SpyGuns, Play->Guns, NumGun, FALSE);
       -
       -  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
       -
       -  gtk_widget_show_all(notebook);
       -}
       -
       -#ifdef NETWORKING
       -static void OKAuthDialog(GtkWidget *widget, GtkWidget *window)
       -{
       -  gtk_object_set_data(GTK_OBJECT(window), "authok", GINT_TO_POINTER(TRUE));
       -  gtk_widget_destroy(window);
       -}
       -
       -static void DestroyAuthDialog(GtkWidget *window, gpointer data)
       -{
       -  GtkWidget *userentry, *passwdentry;
       -  gchar *username = NULL, *password = NULL;
       -  gpointer proxy, authok;
       -  HttpConnection *conn;
       -
       -  authok = gtk_object_get_data(GTK_OBJECT(window), "authok");
       -  proxy = gtk_object_get_data(GTK_OBJECT(window), "proxy");
       -  userentry =
       -      (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), "username");
       -  passwdentry =
       -      (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), "password");
       -  conn =
       -      (HttpConnection *)gtk_object_get_data(GTK_OBJECT(window),
       -                                            "httpconn");
       -  g_assert(userentry && passwdentry && conn);
       -
       -  if (authok) {
       -    username = gtk_editable_get_chars(GTK_EDITABLE(userentry), 0, -1);
       -    password = gtk_editable_get_chars(GTK_EDITABLE(passwdentry), 0, -1);
       -  }
       -
       -  SetHttpAuthentication(conn, GPOINTER_TO_INT(proxy), username, password);
       -
       -  g_free(username);
       -  g_free(password);
       -}
       -
       -void AuthDialog(HttpConnection *conn, gboolean proxy, gchar *realm,
       -                gpointer data)
       -{
       -  GtkWidget *window, *button, *hsep, *vbox, *label, *entry, *table, *hbbox;
       -
       -  window = gtk_window_new(GTK_WINDOW_DIALOG);
       -  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       -                     GTK_SIGNAL_FUNC(DestroyAuthDialog), NULL);
       -  gtk_object_set_data(GTK_OBJECT(window), "proxy", GINT_TO_POINTER(proxy));
       -  gtk_object_set_data(GTK_OBJECT(window), "httpconn", (gpointer)conn);
       -
       -  if (proxy) {
       -    gtk_window_set_title(GTK_WINDOW(window),
       -                         /* Title of dialog for authenticating with a
       -                          * proxy server */
       -                         _("Proxy Authentication Required"));
       -  } else {
       -    /* Title of dialog for authenticating with a web server */
       -    gtk_window_set_title(GTK_WINDOW(window), _("Authentication Required"));
       -  }
       -
       -  gtk_window_set_modal(GTK_WINDOW(window), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(window),
       -                               GTK_WINDOW(ClientData.window));
       -  gtk_container_set_border_width(GTK_CONTAINER(window), 7);
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -
       -  table = gtk_table_new(3, 2, FALSE);
       -  gtk_table_set_row_spacings(GTK_TABLE(table), 10);
       -  gtk_table_set_col_spacings(GTK_TABLE(table), 5);
       -
       -  label = gtk_label_new("Realm:");
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
       -
       -  label = gtk_label_new(realm);
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 0, 1);
       -
       -  label = gtk_label_new("User name:");
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
       -
       -  entry = gtk_entry_new();
       -  gtk_object_set_data(GTK_OBJECT(window), "username", (gpointer)entry);
       -  gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 1, 2);
       -
       -  label = gtk_label_new("Password:");
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3);
       -
       -  entry = gtk_entry_new();
       -  gtk_object_set_data(GTK_OBJECT(window), "password", (gpointer)entry);
       -
       -#ifdef HAVE_FIXED_GTK
       -  /* GTK+ versions earlier than 1.2.10 do bad things with this */
       -  gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
       -#endif
       -
       -  gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 2, 3);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -
       -  hbbox = gtk_hbutton_box_new();
       -
       -  button = gtk_button_new_with_label(_("OK"));
       -  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                     GTK_SIGNAL_FUNC(OKAuthDialog), (gpointer)window);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -
       -  button = gtk_button_new_with_label(_("Cancel"));
       -  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       -                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       -                            (gpointer)window);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), hbbox, TRUE, TRUE, 0);
       -
       -  gtk_container_add(GTK_CONTAINER(window), vbox);
       -  gtk_widget_show_all(window);
       -}
       -
       -static void OKSocksAuth(GtkWidget *widget, GtkWidget *window)
       -{
       -  gtk_object_set_data(GTK_OBJECT(window), "authok", GINT_TO_POINTER(TRUE));
       -  gtk_widget_destroy(window);
       -}
       -
       -static void DestroySocksAuth(GtkWidget *window, gpointer data)
       -{
       -  GtkWidget *userentry, *passwdentry;
       -  gchar *username = NULL, *password = NULL;
       -  gpointer authok, meta;
       -  NetworkBuffer *netbuf;
       -
       -  authok = gtk_object_get_data(GTK_OBJECT(window), "authok");
       -  meta = gtk_object_get_data(GTK_OBJECT(window), "meta");
       -  userentry =
       -      (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), "username");
       -  passwdentry =
       -      (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), "password");
       -  netbuf =
       -      (NetworkBuffer *)gtk_object_get_data(GTK_OBJECT(window), "netbuf");
       -
       -  g_assert(userentry && passwdentry && netbuf);
       -
       -  if (authok) {
       -    username = gtk_editable_get_chars(GTK_EDITABLE(userentry), 0, -1);
       -    password = gtk_editable_get_chars(GTK_EDITABLE(passwdentry), 0, -1);
       -  }
       -
       -  SendSocks5UserPasswd(netbuf, username, password);
       -  g_free(username);
       -  g_free(password);
       -}
       -
       -static void RealSocksAuthDialog(NetworkBuffer *netbuf, gboolean meta,
       -                                gpointer data)
       -{
       -  GtkWidget *window, *button, *hsep, *vbox, *label, *entry, *table, *hbbox;
       -
       -  window = gtk_window_new(GTK_WINDOW_DIALOG);
       -  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       -                     GTK_SIGNAL_FUNC(DestroySocksAuth), NULL);
       -  gtk_object_set_data(GTK_OBJECT(window), "netbuf", (gpointer)netbuf);
       -  gtk_object_set_data(GTK_OBJECT(window), "meta", GINT_TO_POINTER(meta));
       -
       -  /* Title of dialog for authenticating with a SOCKS server */
       -  gtk_window_set_title(GTK_WINDOW(window),
       -                       _("SOCKS Authentication Required"));
       -
       -  gtk_window_set_modal(GTK_WINDOW(window), TRUE);
       -  gtk_window_set_transient_for(GTK_WINDOW(window),
       -                               GTK_WINDOW(ClientData.window));
       -  gtk_container_set_border_width(GTK_CONTAINER(window), 7);
       -
       -  vbox = gtk_vbox_new(FALSE, 7);
       -
       -  table = gtk_table_new(2, 2, FALSE);
       -  gtk_table_set_row_spacings(GTK_TABLE(table), 10);
       -  gtk_table_set_col_spacings(GTK_TABLE(table), 5);
       -
       -  label = gtk_label_new("User name:");
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
       -
       -  entry = gtk_entry_new();
       -  gtk_object_set_data(GTK_OBJECT(window), "username", (gpointer)entry);
       -  gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 0, 1);
       -
       -  label = gtk_label_new("Password:");
       -  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
       -
       -  entry = gtk_entry_new();
       -  gtk_object_set_data(GTK_OBJECT(window), "password", (gpointer)entry);
       -
       -#ifdef HAVE_FIXED_GTK
       -  /* GTK+ versions earlier than 1.2.10 do bad things with this */
       -  gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
       -#endif
       -
       -  gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 1, 2);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
       -
       -  hsep = gtk_hseparator_new();
       -  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       -
       -  hbbox = gtk_hbutton_box_new();
       -
       -  button = gtk_button_new_with_label(_("OK"));
       -  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       -                     GTK_SIGNAL_FUNC(OKSocksAuth), (gpointer)window);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -
       -  button = gtk_button_new_with_label(_("Cancel"));
       -  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       -                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       -                            (gpointer)window);
       -  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       -
       -  gtk_box_pack_start(GTK_BOX(vbox), hbbox, TRUE, TRUE, 0);
       -
       -  gtk_container_add(GTK_CONTAINER(window), vbox);
       -  gtk_widget_show_all(window);
       -}
       -
       -void MetaSocksAuthDialog(NetworkBuffer *netbuf, gpointer data)
       -{
       -  RealSocksAuthDialog(netbuf, TRUE, data);
       -}
       -
       -void SocksAuthDialog(NetworkBuffer *netbuf, gpointer data)
       -{
       -  RealSocksAuthDialog(netbuf, FALSE, data);
       -}
       -
       -#endif /* NETWORKING */
       -
       -#else
       -
       -#include <glib.h>
       -#include "nls.h"                /* We need this for the definition of '_' */
       -
       -char GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail)
       -{
       -  if (!ReturnOnFail) {
       -    /* Error message displayed if the user tries to run the graphical
       -     * client when none is compiled into the dopewars binary. */
       -    g_print(_("No graphical client available - rebuild the binary\n"
       -              "passing the --enable-gui-client option to configure, or\n"
       -              "use the curses client (if available) instead!\n"));
       -  }
       -  return FALSE;
       -}
       -
       -#endif /* GUI_CLIENT */
 (DIR) diff --git a/src/gtk_client.h b/src/gtk_client.h
       t@@ -1,40 +0,0 @@
       -/************************************************************************
       - * gtk_client.h   dopewars client using the GTK+ toolkit                *
       - * Copyright (C)  1998-2002  Ben Webb                                   *
       - *                Email: ben@bellatrix.pcl.ox.ac.uk                     *
       - *                WWW: http://dopewars.sourceforge.net/                 *
       - *                                                                      *
       - * This program is free software; you can redistribute it and/or        *
       - * modify it under the terms of the GNU General Public License          *
       - * as published by the Free Software Foundation; either version 2       *
       - * of the License, or (at your option) any later version.               *
       - *                                                                      *
       - * This program is distributed in the hope that it will be useful,      *
       - * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
       - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
       - * GNU General Public License for more details.                         *
       - *                                                                      *
       - * You should have received a copy of the GNU General Public License    *
       - * along with this program; if not, write to the Free Software          *
       - * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
       - *                   MA  02111-1307, USA.                               *
       - ************************************************************************/
       -
       -#ifndef __GTK_CLIENT_H__
       -#define __GTK_CLIENT_H__
       -
       -#ifdef HAVE_CONFIG_H
       -#include <config.h>
       -#endif
       -
       -#include "gtkport.h"
       -
       -extern GtkWidget *MainWindow;
       -
       -#ifdef CYGWIN
       -char GtkLoop(HINSTANCE hInstance, HINSTANCE hPrevInstance);
       -#else
       -char GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail);
       -#endif
       -
       -#endif
 (DIR) diff --git a/src/gtkport/Makefile.am b/src/gtkport/Makefile.am
       t@@ -0,0 +1,6 @@
       +noinst_LIBRARIES = libgtkport.a
       +libgtkport_a_SOURCES = gtkport.c gtkport.h
       +libgtkport_a_DEPENDENCIES = @INTLLIBS@
       +INCLUDES   = @GTK_CFLAGS@ -I.. -I../.. -I.
       +LDADD      = @GTK_LIBS@ @INTLLIBS@
       +DEFS       = @DEFS@ -DLOCALEDIR=\"${localedir}\"
 (DIR) diff --git a/src/gtkport/Makefile.in b/src/gtkport/Makefile.in
       t@@ -0,0 +1,325 @@
       +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
       +
       +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
       +# This Makefile.in is free software; the Free Software Foundation
       +# gives unlimited permission to copy and/or distribute it,
       +# with or without modifications, as long as this notice is preserved.
       +
       +# This program is distributed in the hope that it will be useful,
       +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
       +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
       +# PARTICULAR PURPOSE.
       +
       +
       +SHELL = @SHELL@
       +
       +srcdir = @srcdir@
       +top_srcdir = @top_srcdir@
       +VPATH = @srcdir@
       +prefix = @prefix@
       +exec_prefix = @exec_prefix@
       +
       +bindir = @bindir@
       +sbindir = @sbindir@
       +libexecdir = @libexecdir@
       +datadir = @datadir@
       +sysconfdir = @sysconfdir@
       +sharedstatedir = @sharedstatedir@
       +localstatedir = @localstatedir@
       +libdir = @libdir@
       +infodir = @infodir@
       +mandir = @mandir@
       +includedir = @includedir@
       +oldincludedir = /usr/include
       +
       +DESTDIR =
       +
       +pkgdatadir = $(datadir)/@PACKAGE@
       +pkglibdir = $(libdir)/@PACKAGE@
       +pkgincludedir = $(includedir)/@PACKAGE@
       +
       +top_builddir = ../..
       +
       +ACLOCAL = @ACLOCAL@
       +AUTOCONF = @AUTOCONF@
       +AUTOMAKE = @AUTOMAKE@
       +AUTOHEADER = @AUTOHEADER@
       +
       +INSTALL = @INSTALL@
       +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
       +INSTALL_DATA = @INSTALL_DATA@
       +INSTALL_SCRIPT = @INSTALL_SCRIPT@
       +transform = @program_transform_name@
       +
       +NORMAL_INSTALL = :
       +PRE_INSTALL = :
       +POST_INSTALL = :
       +NORMAL_UNINSTALL = :
       +PRE_UNINSTALL = :
       +POST_UNINSTALL = :
       +host_alias = @host_alias@
       +host_triplet = @host@
       +BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
       +CATALOGS = @CATALOGS@
       +CATOBJEXT = @CATOBJEXT@
       +CC = @CC@
       +DATADIRNAME = @DATADIRNAME@
       +GENCAT = @GENCAT@
       +GLIBC21 = @GLIBC21@
       +GLIB_CFLAGS = @GLIB_CFLAGS@
       +GLIB_CONFIG = @GLIB_CONFIG@
       +GLIB_LIBS = @GLIB_LIBS@
       +GMOFILES = @GMOFILES@
       +GMSGFMT = @GMSGFMT@
       +GTK_CFLAGS = @GTK_CFLAGS@
       +GTK_CONFIG = @GTK_CONFIG@
       +GTK_LIBS = @GTK_LIBS@
       +INSTOBJEXT = @INSTOBJEXT@
       +INTLBISON = @INTLBISON@
       +INTLLIBS = @INTLLIBS@
       +INTLOBJS = @INTLOBJS@
       +INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
       +LIBICONV = @LIBICONV@
       +MAKEINFO = @MAKEINFO@
       +MKINSTALLDIRS = @MKINSTALLDIRS@
       +MSGFMT = @MSGFMT@
       +PACKAGE = @PACKAGE@
       +POFILES = @POFILES@
       +POSUB = @POSUB@
       +RANLIB = @RANLIB@
       +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
       +USE_NLS = @USE_NLS@
       +VERSION = @VERSION@
       +WNDRES = @WNDRES@
       +localedir = @localedir@
       +
       +noinst_LIBRARIES = libgtkport.a
       +libgtkport_a_SOURCES = gtkport.c gtkport.h
       +libgtkport_a_DEPENDENCIES = @INTLLIBS@
       +INCLUDES = @GTK_CFLAGS@ -I.. -I../.. -I.
       +LDADD = @GTK_LIBS@ @INTLLIBS@
       +DEFS = @DEFS@ -DLOCALEDIR=\"${localedir}\"
       +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
       +CONFIG_HEADER = ../../config.h
       +CONFIG_CLEAN_FILES = 
       +LIBRARIES =  $(noinst_LIBRARIES)
       +
       +CPPFLAGS = @CPPFLAGS@
       +LDFLAGS = @LDFLAGS@
       +LIBS = @LIBS@
       +libgtkport_a_LIBADD = 
       +libgtkport_a_OBJECTS =  gtkport.o
       +AR = ar
       +CFLAGS = @CFLAGS@
       +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
       +CCLD = $(CC)
       +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
       +DIST_COMMON =  Makefile.am Makefile.in
       +
       +
       +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
       +
       +TAR = gtar
       +GZIP_ENV = --best
       +DEP_FILES =  .deps/gtkport.P
       +SOURCES = $(libgtkport_a_SOURCES)
       +OBJECTS = $(libgtkport_a_OBJECTS)
       +
       +all: all-redirect
       +.SUFFIXES:
       +.SUFFIXES: .S .c .o .s
       +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
       +        cd $(top_srcdir) && $(AUTOMAKE) --gnu src/gtkport/Makefile
       +
       +Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
       +        cd $(top_builddir) \
       +          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
       +
       +
       +mostlyclean-noinstLIBRARIES:
       +
       +clean-noinstLIBRARIES:
       +        -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
       +
       +distclean-noinstLIBRARIES:
       +
       +maintainer-clean-noinstLIBRARIES:
       +
       +.s.o:
       +        $(COMPILE) -c $<
       +
       +.S.o:
       +        $(COMPILE) -c $<
       +
       +mostlyclean-compile:
       +        -rm -f *.o core *.core
       +
       +clean-compile:
       +
       +distclean-compile:
       +        -rm -f *.tab.c
       +
       +maintainer-clean-compile:
       +
       +libgtkport.a: $(libgtkport_a_OBJECTS) $(libgtkport_a_DEPENDENCIES)
       +        -rm -f libgtkport.a
       +        $(AR) cru libgtkport.a $(libgtkport_a_OBJECTS) $(libgtkport_a_LIBADD)
       +        $(RANLIB) libgtkport.a
       +
       +tags: TAGS
       +
       +ID: $(HEADERS) $(SOURCES) $(LISP)
       +        list='$(SOURCES) $(HEADERS)'; \
       +        unique=`for i in $$list; do echo $$i; done | \
       +          awk '    { files[$$0] = 1; } \
       +               END { for (i in files) print i; }'`; \
       +        here=`pwd` && cd $(srcdir) \
       +          && mkid -f$$here/ID $$unique $(LISP)
       +
       +TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
       +        tags=; \
       +        here=`pwd`; \
       +        list='$(SOURCES) $(HEADERS)'; \
       +        unique=`for i in $$list; do echo $$i; done | \
       +          awk '    { files[$$0] = 1; } \
       +               END { for (i in files) print i; }'`; \
       +        test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
       +          || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
       +
       +mostlyclean-tags:
       +
       +clean-tags:
       +
       +distclean-tags:
       +        -rm -f TAGS ID
       +
       +maintainer-clean-tags:
       +
       +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
       +
       +subdir = src/gtkport
       +
       +distdir: $(DISTFILES)
       +        here=`cd $(top_builddir) && pwd`; \
       +        top_distdir=`cd $(top_distdir) && pwd`; \
       +        distdir=`cd $(distdir) && pwd`; \
       +        cd $(top_srcdir) \
       +          && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu src/gtkport/Makefile
       +        @for file in $(DISTFILES); do \
       +          d=$(srcdir); \
       +          if test -d $$d/$$file; then \
       +            cp -pr $$d/$$file $(distdir)/$$file; \
       +          else \
       +            test -f $(distdir)/$$file \
       +            || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
       +            || cp -p $$d/$$file $(distdir)/$$file || :; \
       +          fi; \
       +        done
       +
       +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
       +
       +-include $(DEP_FILES)
       +
       +mostlyclean-depend:
       +
       +clean-depend:
       +
       +distclean-depend:
       +        -rm -rf .deps
       +
       +maintainer-clean-depend:
       +
       +%.o: %.c
       +        @echo '$(COMPILE) -c $<'; \
       +        $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
       +        @-cp .deps/$(*F).pp .deps/$(*F).P; \
       +        tr ' ' '\012' < .deps/$(*F).pp \
       +          | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
       +            >> .deps/$(*F).P; \
       +        rm .deps/$(*F).pp
       +
       +%.lo: %.c
       +        @echo '$(LTCOMPILE) -c $<'; \
       +        $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
       +        @-sed -e 's/^\([^:]*\)\.o[         ]*:/\1.lo \1.o :/' \
       +          < .deps/$(*F).pp > .deps/$(*F).P; \
       +        tr ' ' '\012' < .deps/$(*F).pp \
       +          | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
       +            >> .deps/$(*F).P; \
       +        rm -f .deps/$(*F).pp
       +info-am:
       +info: info-am
       +dvi-am:
       +dvi: dvi-am
       +check-am: all-am
       +check: check-am
       +installcheck-am:
       +installcheck: installcheck-am
       +install-exec-am:
       +install-exec: install-exec-am
       +
       +install-data-am:
       +install-data: install-data-am
       +
       +install-am: all-am
       +        @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
       +install: install-am
       +uninstall-am:
       +uninstall: uninstall-am
       +all-am: Makefile $(LIBRARIES)
       +all-redirect: all-am
       +install-strip:
       +        $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
       +installdirs:
       +
       +
       +mostlyclean-generic:
       +
       +clean-generic:
       +
       +distclean-generic:
       +        -rm -f Makefile $(CONFIG_CLEAN_FILES)
       +        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
       +
       +maintainer-clean-generic:
       +mostlyclean-am:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
       +                mostlyclean-tags mostlyclean-depend mostlyclean-generic
       +
       +mostlyclean: mostlyclean-am
       +
       +clean-am:  clean-noinstLIBRARIES clean-compile clean-tags clean-depend \
       +                clean-generic mostlyclean-am
       +
       +clean: clean-am
       +
       +distclean-am:  distclean-noinstLIBRARIES distclean-compile \
       +                distclean-tags distclean-depend distclean-generic \
       +                clean-am
       +
       +distclean: distclean-am
       +
       +maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \
       +                maintainer-clean-compile maintainer-clean-tags \
       +                maintainer-clean-depend maintainer-clean-generic \
       +                distclean-am
       +        @echo "This command is intended for maintainers to use;"
       +        @echo "it deletes files that may require special tools to rebuild."
       +
       +maintainer-clean: maintainer-clean-am
       +
       +.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
       +clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
       +mostlyclean-compile distclean-compile clean-compile \
       +maintainer-clean-compile tags mostlyclean-tags distclean-tags \
       +clean-tags maintainer-clean-tags distdir mostlyclean-depend \
       +distclean-depend clean-depend maintainer-clean-depend info-am info \
       +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
       +install-exec install-data-am install-data install-am install \
       +uninstall-am uninstall all-redirect all-am all installdirs \
       +mostlyclean-generic distclean-generic clean-generic \
       +maintainer-clean-generic clean mostlyclean distclean maintainer-clean
       +
       +
       +# Tell versions [3.59,3.63) of GNU make to not export all variables.
       +# Otherwise a system limit (for SysV at least) may be exceeded.
       +.NOEXPORT:
 (DIR) diff --git a/src/gtkport.c b/src/gtkport/gtkport.c
 (DIR) diff --git a/src/gtkport.h b/src/gtkport/gtkport.h
 (DIR) diff --git a/src/gui_client/Makefile.am b/src/gui_client/Makefile.am
       t@@ -0,0 +1,6 @@
       +noinst_LIBRARIES = libguiclient.a
       +libguiclient_a_SOURCES = gtk_client.c
       +libguiclient_a_DEPENDENCIES = @INTLLIBS@
       +INCLUDES   = @GTK_CFLAGS@ -I.. -I../.. -I.
       +LDADD      = @GTK_LIBS@ @INTLLIBS@
       +DEFS       = @DEFS@ -DLOCALEDIR=\"${localedir}\"
 (DIR) diff --git a/src/gui_client/Makefile.in b/src/gui_client/Makefile.in
       t@@ -0,0 +1,325 @@
       +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
       +
       +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
       +# This Makefile.in is free software; the Free Software Foundation
       +# gives unlimited permission to copy and/or distribute it,
       +# with or without modifications, as long as this notice is preserved.
       +
       +# This program is distributed in the hope that it will be useful,
       +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
       +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
       +# PARTICULAR PURPOSE.
       +
       +
       +SHELL = @SHELL@
       +
       +srcdir = @srcdir@
       +top_srcdir = @top_srcdir@
       +VPATH = @srcdir@
       +prefix = @prefix@
       +exec_prefix = @exec_prefix@
       +
       +bindir = @bindir@
       +sbindir = @sbindir@
       +libexecdir = @libexecdir@
       +datadir = @datadir@
       +sysconfdir = @sysconfdir@
       +sharedstatedir = @sharedstatedir@
       +localstatedir = @localstatedir@
       +libdir = @libdir@
       +infodir = @infodir@
       +mandir = @mandir@
       +includedir = @includedir@
       +oldincludedir = /usr/include
       +
       +DESTDIR =
       +
       +pkgdatadir = $(datadir)/@PACKAGE@
       +pkglibdir = $(libdir)/@PACKAGE@
       +pkgincludedir = $(includedir)/@PACKAGE@
       +
       +top_builddir = ../..
       +
       +ACLOCAL = @ACLOCAL@
       +AUTOCONF = @AUTOCONF@
       +AUTOMAKE = @AUTOMAKE@
       +AUTOHEADER = @AUTOHEADER@
       +
       +INSTALL = @INSTALL@
       +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
       +INSTALL_DATA = @INSTALL_DATA@
       +INSTALL_SCRIPT = @INSTALL_SCRIPT@
       +transform = @program_transform_name@
       +
       +NORMAL_INSTALL = :
       +PRE_INSTALL = :
       +POST_INSTALL = :
       +NORMAL_UNINSTALL = :
       +PRE_UNINSTALL = :
       +POST_UNINSTALL = :
       +host_alias = @host_alias@
       +host_triplet = @host@
       +BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
       +CATALOGS = @CATALOGS@
       +CATOBJEXT = @CATOBJEXT@
       +CC = @CC@
       +DATADIRNAME = @DATADIRNAME@
       +GENCAT = @GENCAT@
       +GLIBC21 = @GLIBC21@
       +GLIB_CFLAGS = @GLIB_CFLAGS@
       +GLIB_CONFIG = @GLIB_CONFIG@
       +GLIB_LIBS = @GLIB_LIBS@
       +GMOFILES = @GMOFILES@
       +GMSGFMT = @GMSGFMT@
       +GTK_CFLAGS = @GTK_CFLAGS@
       +GTK_CONFIG = @GTK_CONFIG@
       +GTK_LIBS = @GTK_LIBS@
       +INSTOBJEXT = @INSTOBJEXT@
       +INTLBISON = @INTLBISON@
       +INTLLIBS = @INTLLIBS@
       +INTLOBJS = @INTLOBJS@
       +INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
       +LIBICONV = @LIBICONV@
       +MAKEINFO = @MAKEINFO@
       +MKINSTALLDIRS = @MKINSTALLDIRS@
       +MSGFMT = @MSGFMT@
       +PACKAGE = @PACKAGE@
       +POFILES = @POFILES@
       +POSUB = @POSUB@
       +RANLIB = @RANLIB@
       +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
       +USE_NLS = @USE_NLS@
       +VERSION = @VERSION@
       +WNDRES = @WNDRES@
       +localedir = @localedir@
       +
       +noinst_LIBRARIES = libguiclient.a
       +libguiclient_a_SOURCES = gtk_client.c
       +libguiclient_a_DEPENDENCIES = @INTLLIBS@
       +INCLUDES = @GTK_CFLAGS@ -I.. -I../.. -I.
       +LDADD = @GTK_LIBS@ @INTLLIBS@
       +DEFS = @DEFS@ -DLOCALEDIR=\"${localedir}\"
       +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
       +CONFIG_HEADER = ../../config.h
       +CONFIG_CLEAN_FILES = 
       +LIBRARIES =  $(noinst_LIBRARIES)
       +
       +CPPFLAGS = @CPPFLAGS@
       +LDFLAGS = @LDFLAGS@
       +LIBS = @LIBS@
       +libguiclient_a_LIBADD = 
       +libguiclient_a_OBJECTS =  gtk_client.o
       +AR = ar
       +CFLAGS = @CFLAGS@
       +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
       +CCLD = $(CC)
       +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
       +DIST_COMMON =  Makefile.am Makefile.in
       +
       +
       +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
       +
       +TAR = gtar
       +GZIP_ENV = --best
       +DEP_FILES =  .deps/gtk_client.P
       +SOURCES = $(libguiclient_a_SOURCES)
       +OBJECTS = $(libguiclient_a_OBJECTS)
       +
       +all: all-redirect
       +.SUFFIXES:
       +.SUFFIXES: .S .c .o .s
       +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
       +        cd $(top_srcdir) && $(AUTOMAKE) --gnu src/gui_client/Makefile
       +
       +Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
       +        cd $(top_builddir) \
       +          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
       +
       +
       +mostlyclean-noinstLIBRARIES:
       +
       +clean-noinstLIBRARIES:
       +        -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
       +
       +distclean-noinstLIBRARIES:
       +
       +maintainer-clean-noinstLIBRARIES:
       +
       +.s.o:
       +        $(COMPILE) -c $<
       +
       +.S.o:
       +        $(COMPILE) -c $<
       +
       +mostlyclean-compile:
       +        -rm -f *.o core *.core
       +
       +clean-compile:
       +
       +distclean-compile:
       +        -rm -f *.tab.c
       +
       +maintainer-clean-compile:
       +
       +libguiclient.a: $(libguiclient_a_OBJECTS) $(libguiclient_a_DEPENDENCIES)
       +        -rm -f libguiclient.a
       +        $(AR) cru libguiclient.a $(libguiclient_a_OBJECTS) $(libguiclient_a_LIBADD)
       +        $(RANLIB) libguiclient.a
       +
       +tags: TAGS
       +
       +ID: $(HEADERS) $(SOURCES) $(LISP)
       +        list='$(SOURCES) $(HEADERS)'; \
       +        unique=`for i in $$list; do echo $$i; done | \
       +          awk '    { files[$$0] = 1; } \
       +               END { for (i in files) print i; }'`; \
       +        here=`pwd` && cd $(srcdir) \
       +          && mkid -f$$here/ID $$unique $(LISP)
       +
       +TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
       +        tags=; \
       +        here=`pwd`; \
       +        list='$(SOURCES) $(HEADERS)'; \
       +        unique=`for i in $$list; do echo $$i; done | \
       +          awk '    { files[$$0] = 1; } \
       +               END { for (i in files) print i; }'`; \
       +        test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
       +          || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
       +
       +mostlyclean-tags:
       +
       +clean-tags:
       +
       +distclean-tags:
       +        -rm -f TAGS ID
       +
       +maintainer-clean-tags:
       +
       +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
       +
       +subdir = src/gui_client
       +
       +distdir: $(DISTFILES)
       +        here=`cd $(top_builddir) && pwd`; \
       +        top_distdir=`cd $(top_distdir) && pwd`; \
       +        distdir=`cd $(distdir) && pwd`; \
       +        cd $(top_srcdir) \
       +          && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu src/gui_client/Makefile
       +        @for file in $(DISTFILES); do \
       +          d=$(srcdir); \
       +          if test -d $$d/$$file; then \
       +            cp -pr $$d/$$file $(distdir)/$$file; \
       +          else \
       +            test -f $(distdir)/$$file \
       +            || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
       +            || cp -p $$d/$$file $(distdir)/$$file || :; \
       +          fi; \
       +        done
       +
       +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
       +
       +-include $(DEP_FILES)
       +
       +mostlyclean-depend:
       +
       +clean-depend:
       +
       +distclean-depend:
       +        -rm -rf .deps
       +
       +maintainer-clean-depend:
       +
       +%.o: %.c
       +        @echo '$(COMPILE) -c $<'; \
       +        $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
       +        @-cp .deps/$(*F).pp .deps/$(*F).P; \
       +        tr ' ' '\012' < .deps/$(*F).pp \
       +          | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
       +            >> .deps/$(*F).P; \
       +        rm .deps/$(*F).pp
       +
       +%.lo: %.c
       +        @echo '$(LTCOMPILE) -c $<'; \
       +        $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
       +        @-sed -e 's/^\([^:]*\)\.o[         ]*:/\1.lo \1.o :/' \
       +          < .deps/$(*F).pp > .deps/$(*F).P; \
       +        tr ' ' '\012' < .deps/$(*F).pp \
       +          | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
       +            >> .deps/$(*F).P; \
       +        rm -f .deps/$(*F).pp
       +info-am:
       +info: info-am
       +dvi-am:
       +dvi: dvi-am
       +check-am: all-am
       +check: check-am
       +installcheck-am:
       +installcheck: installcheck-am
       +install-exec-am:
       +install-exec: install-exec-am
       +
       +install-data-am:
       +install-data: install-data-am
       +
       +install-am: all-am
       +        @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
       +install: install-am
       +uninstall-am:
       +uninstall: uninstall-am
       +all-am: Makefile $(LIBRARIES)
       +all-redirect: all-am
       +install-strip:
       +        $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
       +installdirs:
       +
       +
       +mostlyclean-generic:
       +
       +clean-generic:
       +
       +distclean-generic:
       +        -rm -f Makefile $(CONFIG_CLEAN_FILES)
       +        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
       +
       +maintainer-clean-generic:
       +mostlyclean-am:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
       +                mostlyclean-tags mostlyclean-depend mostlyclean-generic
       +
       +mostlyclean: mostlyclean-am
       +
       +clean-am:  clean-noinstLIBRARIES clean-compile clean-tags clean-depend \
       +                clean-generic mostlyclean-am
       +
       +clean: clean-am
       +
       +distclean-am:  distclean-noinstLIBRARIES distclean-compile \
       +                distclean-tags distclean-depend distclean-generic \
       +                clean-am
       +
       +distclean: distclean-am
       +
       +maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \
       +                maintainer-clean-compile maintainer-clean-tags \
       +                maintainer-clean-depend maintainer-clean-generic \
       +                distclean-am
       +        @echo "This command is intended for maintainers to use;"
       +        @echo "it deletes files that may require special tools to rebuild."
       +
       +maintainer-clean: maintainer-clean-am
       +
       +.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
       +clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
       +mostlyclean-compile distclean-compile clean-compile \
       +maintainer-clean-compile tags mostlyclean-tags distclean-tags \
       +clean-tags maintainer-clean-tags distdir mostlyclean-depend \
       +distclean-depend clean-depend maintainer-clean-depend info-am info \
       +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
       +install-exec install-data-am install-data install-am install \
       +uninstall-am uninstall all-redirect all-am all installdirs \
       +mostlyclean-generic distclean-generic clean-generic \
       +maintainer-clean-generic clean mostlyclean distclean maintainer-clean
       +
       +
       +# Tell versions [3.59,3.63) of GNU make to not export all variables.
       +# Otherwise a system limit (for SysV at least) may be exceeded.
       +.NOEXPORT:
 (DIR) diff --git a/src/gui_client/gtk_client.c b/src/gui_client/gtk_client.c
       t@@ -0,0 +1,3910 @@
       +/************************************************************************
       + * gtk_client.c   dopewars client using the GTK+ toolkit                *
       + * Copyright (C)  1998-2002  Ben Webb                                   *
       + *                Email: ben@bellatrix.pcl.ox.ac.uk                     *
       + *                WWW: http://dopewars.sourceforge.net/                 *
       + *                                                                      *
       + * This program is free software; you can redistribute it and/or        *
       + * modify it under the terms of the GNU General Public License          *
       + * as published by the Free Software Foundation; either version 2       *
       + * of the License, or (at your option) any later version.               *
       + *                                                                      *
       + * This program is distributed in the hope that it will be useful,      *
       + * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
       + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
       + * GNU General Public License for more details.                         *
       + *                                                                      *
       + * You should have received a copy of the GNU General Public License    *
       + * along with this program; if not, write to the Free Software          *
       + * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
       + *                   MA  02111-1307, USA.                               *
       + ************************************************************************/
       +
       +#ifdef HAVE_CONFIG_H
       +#include <config.h>
       +#endif
       +
       +#include <stdlib.h>
       +#include <ctype.h>
       +#include <string.h>
       +
       +#include "dopeos.h"
       +#include "dopewars.h"
       +#include "gtk_client.h"
       +#include "message.h"
       +#include "nls.h"
       +#include "serverside.h"
       +#include "tstring.h"
       +#include "gtkport/gtkport.h"
       +#include "dopewars-pill.xpm"
       +
       +#define BT_BUY  (GINT_TO_POINTER(1))
       +#define BT_SELL (GINT_TO_POINTER(2))
       +#define BT_DROP (GINT_TO_POINTER(3))
       +
       +#define ET_SPY    0
       +#define ET_TIPOFF 1
       +
       +/* Which notebook page to display in the New Game dialog */
       +static gint NewGameType = 0;
       +
       +struct InventoryWidgets {
       +  GtkWidget *HereList, *CarriedList;
       +  GtkWidget *HereFrame, *CarriedFrame;
       +  GtkWidget *BuyButton, *SellButton, *DropButton;
       +  GtkWidget *vbbox;
       +};
       +
       +struct StatusWidgets {
       +  GtkWidget *Location, *Date, *SpaceName, *SpaceValue, *CashName;
       +  GtkWidget *CashValue, *DebtName, *DebtValue, *BankName, *BankValue;
       +  GtkWidget *GunsName, *GunsValue, *BitchesName, *BitchesValue;
       +  GtkWidget *HealthName, *HealthValue;
       +};
       +
       +struct ClientDataStruct {
       +  GtkWidget *window, *messages;
       +  Player *Play;
       +  GtkItemFactory *Menu;
       +  struct StatusWidgets Status;
       +  struct InventoryWidgets Drug, Gun, InvenDrug, InvenGun;
       +  GtkWidget *JetButton, *vbox, *PlayerList, *TalkList;
       +  guint JetAccel;
       +};
       +
       +GtkWidget *MainWindow;
       +
       +struct StartGameStruct {
       +  GtkWidget *dialog, *name, *hostname, *port, *antique, *status, *metaserv;
       +#ifdef NETWORKING
       +  HttpConnection *MetaConn;
       +  GSList *NewMetaList;
       +#endif
       +};
       +
       +static struct ClientDataStruct ClientData;
       +static gboolean InGame = FALSE;
       +
       +static GtkWidget *FightDialog = NULL, *SpyReportsDialog;
       +static gboolean IsShowingPlayerList = FALSE, IsShowingTalkList = FALSE;
       +static gboolean IsShowingInventory = FALSE, IsShowingGunShop = FALSE;
       +
       +static void display_intro(GtkWidget *widget, gpointer data);
       +static void QuitGame(GtkWidget *widget, gpointer data);
       +static void DestroyGtk(GtkWidget *widget, gpointer data);
       +static void NewGame(GtkWidget *widget, gpointer data);
       +static void ListScores(GtkWidget *widget, gpointer data);
       +static void ListInventory(GtkWidget *widget, gpointer data);
       +static void NewGameDialog(void);
       +static void StartGame(void);
       +static void EndGame(void);
       +static void Jet(GtkWidget *parent);
       +static void UpdateMenus(void);
       +
       +#ifdef NETWORKING
       +static void DisplayConnectStatus(struct StartGameStruct *widgets,
       +                                 gboolean meta, NBStatus oldstatus,
       +                                 NBSocksStatus oldsocks);
       +static void AuthDialog(HttpConnection *conn, gboolean proxyauth,
       +                       gchar *realm, gpointer data);
       +static void MetaSocksAuthDialog(NetworkBuffer *netbuf, gpointer data);
       +static void SocksAuthDialog(NetworkBuffer *netbuf, gpointer data);
       +static void GetClientMessage(gpointer data, gint socket,
       +                             GdkInputCondition condition);
       +static void SocketStatus(NetworkBuffer *NetBuf, gboolean Read,
       +                         gboolean Write, gboolean CallNow);
       +static void MetaSocketStatus(NetworkBuffer *NetBuf, gboolean Read,
       +                             gboolean Write, gboolean CallNow);
       +static void FinishServerConnect(struct StartGameStruct *widgets,
       +                                gboolean ConnectOK);
       +
       +/* List of servers on the metaserver */
       +static GSList *MetaList = NULL;
       +
       +#endif /* NETWORKING */
       +
       +static void HandleClientMessage(char *buf, Player *Play);
       +static void PrepareHighScoreDialog(void);
       +static void AddScoreToDialog(char *Data);
       +static void CompleteHighScoreDialog(gboolean AtEnd);
       +static void PrintMessage(char *Data);
       +static void DisplayFightMessage(char *Data);
       +static GtkWidget *CreateStatusWidgets(struct StatusWidgets *Status);
       +static void DisplayStats(Player *Play, struct StatusWidgets *Status);
       +static void UpdateStatus(Player *Play);
       +static void SetJetButtonTitle(GtkAccelGroup *accel_group);
       +static void UpdateInventory(struct InventoryWidgets *Inven,
       +                            Inventory *Objects, int NumObjects,
       +                            gboolean AreDrugs);
       +static void JetButtonPressed(GtkWidget *widget, gpointer data);
       +static void DealDrugs(GtkWidget *widget, gpointer data);
       +static void DealGuns(GtkWidget *widget, gpointer data);
       +static void QuestionDialog(char *Data, Player *From);
       +static void TransferDialog(gboolean Debt);
       +static void ListPlayers(GtkWidget *widget, gpointer data);
       +static void TalkToAll(GtkWidget *widget, gpointer data);
       +static void TalkToPlayers(GtkWidget *widget, gpointer data);
       +static void TalkDialog(gboolean TalkToAll);
       +static GtkWidget *CreatePlayerList(void);
       +static void UpdatePlayerList(GtkWidget *clist, gboolean IncludeSelf);
       +static void TipOff(GtkWidget *widget, gpointer data);
       +static void SpyOnPlayer(GtkWidget *widget, gpointer data);
       +static void ErrandDialog(gint ErrandType);
       +static void SackBitch(GtkWidget *widget, gpointer data);
       +static void DestroyShowing(GtkWidget *widget, gpointer data);
       +static gint DisallowDelete(GtkWidget *widget, GdkEvent * event,
       +                           gpointer data);
       +static void GunShopDialog(void);
       +static void NewNameDialog(void);
       +static void UpdatePlayerLists(void);
       +static void CreateInventory(GtkWidget *hbox, gchar *Objects,
       +                            GtkAccelGroup *accel_group,
       +                            gboolean CreateButtons, gboolean CreateHere,
       +                            struct InventoryWidgets *widgets,
       +                            GtkSignalFunc CallBack);
       +static void GetSpyReports(GtkWidget *widget, gpointer data);
       +static void DisplaySpyReports(Player *Play);
       +
       +static GtkItemFactoryEntry menu_items[] = {
       +  /* The names of the the menus and their items in the GTK+ client */
       +  {N_("/_Game"), NULL, NULL, 0, "<Branch>"},
       +  {N_("/Game/_New..."), "<control>N", NewGame, 0, NULL},
       +  {N_("/Game/_Quit..."), "<control>Q", QuitGame, 0, NULL},
       +  {N_("/_Talk"), NULL, NULL, 0, "<Branch>"},
       +  {N_("/Talk/To _All..."), NULL, TalkToAll, 0, NULL},
       +  {N_("/Talk/To _Player..."), NULL, TalkToPlayers, 0, NULL},
       +  {N_("/_List"), NULL, NULL, 0, "<Branch>"},
       +  {N_("/List/_Players..."), NULL, ListPlayers, 0, NULL},
       +  {N_("/List/_Scores..."), NULL, ListScores, 0, NULL},
       +  {N_("/List/_Inventory..."), NULL, ListInventory, 0, NULL},
       +  {N_("/_Errands"), NULL, NULL, 0, "<Branch>"},
       +  {N_("/Errands/_Spy..."), NULL, SpyOnPlayer, 0, NULL},
       +  {N_("/Errands/_Tipoff..."), NULL, TipOff, 0, NULL},
       +  /* N.B. "Sack Bitch" has to be recreated (and thus translated) at the
       +   * start of each game, below, so is not marked for gettext here */
       +  {"/Errands/S_ack Bitch...", NULL, SackBitch, 0, NULL},
       +  {N_("/Errands/_Get spy reports..."), NULL, GetSpyReports, 0, NULL},
       +  {N_("/_Help"), NULL, NULL, 0, "<LastBranch>"},
       +  {N_("/Help/_About..."), "F1", display_intro, 0, NULL}
       +};
       +
       +static gchar *MenuTranslate(const gchar *path, gpointer func_data)
       +{
       +  /* Translate menu items, using gettext */
       +  return _(path);
       +}
       +
       +static void LogMessage(const gchar *log_domain, GLogLevelFlags log_level,
       +                       const gchar *message, gpointer user_data)
       +{
       +  GtkMessageBox(NULL, message,
       +                /* Titles of the message boxes for warnings and errors */
       +                log_level & G_LOG_LEVEL_WARNING ? _("Warning") :
       +                log_level & G_LOG_LEVEL_CRITICAL ? _("Error") :
       +                _("Message"),
       +                MB_OK | (gtk_main_level() > 0 ? MB_IMMRETURN : 0));
       +}
       +
       +void QuitGame(GtkWidget *widget, gpointer data)
       +{
       +  if (!InGame || GtkMessageBox(ClientData.window,
       +                               /* Prompt in 'quit game' dialog */
       +                               _("Abandon current game?"),
       +                               /* Title of 'quit game' dialog */
       +                               _("Quit Game"), MB_YESNO) == IDYES) {
       +    gtk_main_quit();
       +  }
       +}
       +
       +void DestroyGtk(GtkWidget *widget, gpointer data)
       +{
       +  gtk_main_quit();
       +}
       +
       +gint MainDelete(GtkWidget *widget, GdkEvent * event, gpointer data)
       +{
       +  return (InGame
       +          && GtkMessageBox(ClientData.window, _("Abandon current game?"),
       +                           _("Quit Game"), MB_YESNO) == IDNO);
       +}
       +
       +
       +void NewGame(GtkWidget *widget, gpointer data)
       +{
       +  if (InGame) {
       +    if (GtkMessageBox(ClientData.window, _("Abandon current game?"),
       +                      /* Title of 'stop game to start a new game' dialog */
       +                      _("Start new game"), MB_YESNO) == IDYES)
       +      EndGame();
       +    else
       +      return;
       +  }
       +
       +  /* Save the configuration, so we can restore those elements that get
       +   * overwritten when we connect to a dopewars server */
       +  BackupConfig();
       +
       +  NewGameDialog();
       +}
       +
       +void ListScores(GtkWidget *widget, gpointer data)
       +{
       +  SendClientMessage(ClientData.Play, C_NONE, C_REQUESTSCORE, NULL, NULL);
       +}
       +
       +void ListInventory(GtkWidget *widget, gpointer data)
       +{
       +  GtkWidget *window, *button, *hsep, *vbox, *hbox;
       +  GtkAccelGroup *accel_group;
       +
       +  if (IsShowingInventory)
       +    return;
       +  window = gtk_window_new(GTK_WINDOW_DIALOG);
       +  gtk_window_set_default_size(GTK_WINDOW(window), 550, 120);
       +  accel_group = gtk_accel_group_new();
       +  gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
       +
       +  /* Title of inventory window */
       +  gtk_window_set_title(GTK_WINDOW(window), _("Inventory"));
       +
       +  IsShowingInventory = TRUE;
       +  gtk_window_set_modal(GTK_WINDOW(window), FALSE);
       +  gtk_object_set_data(GTK_OBJECT(window), "IsShowing",
       +                      (gpointer)&IsShowingInventory);
       +  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       +                     GTK_SIGNAL_FUNC(DestroyShowing), NULL);
       +
       +  gtk_window_set_transient_for(GTK_WINDOW(window),
       +                               GTK_WINDOW(ClientData.window));
       +  gtk_container_set_border_width(GTK_CONTAINER(window), 7);
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +
       +  hbox = gtk_hbox_new(FALSE, 7);
       +  CreateInventory(hbox, Names.Drugs, accel_group, FALSE, FALSE,
       +                  &ClientData.InvenDrug, NULL);
       +  CreateInventory(hbox, Names.Guns, accel_group, FALSE, FALSE,
       +                  &ClientData.InvenGun, NULL);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +
       +  /* Caption of the button to close a dialog */
       +  button = gtk_button_new_with_label(_("Close"));
       +  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       +                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                            (gpointer)window);
       +  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
       +
       +  gtk_container_add(GTK_CONTAINER(window), vbox);
       +
       +  UpdateInventory(&ClientData.InvenDrug, ClientData.Play->Drugs, NumDrug,
       +                  TRUE);
       +  UpdateInventory(&ClientData.InvenGun, ClientData.Play->Guns, NumGun,
       +                  FALSE);
       +
       +  gtk_widget_show_all(window);
       +}
       +
       +#ifdef NETWORKING
       +void GetClientMessage(gpointer data, gint socket,
       +                      GdkInputCondition condition)
       +{
       +  gchar *pt;
       +  NetworkBuffer *NetBuf;
       +  gboolean DoneOK, datawaiting;
       +  NBStatus status, oldstatus;
       +  NBSocksStatus oldsocks;
       +
       +  NetBuf = &ClientData.Play->NetBuf;
       +
       +  oldstatus = NetBuf->status;
       +  oldsocks = NetBuf->sockstat;
       +
       +  datawaiting =
       +      PlayerHandleNetwork(ClientData.Play, condition & GDK_INPUT_READ,
       +                          condition & GDK_INPUT_WRITE, &DoneOK);
       +
       +  status = NetBuf->status;
       +
       +  if (status != NBS_CONNECTED) {
       +    /* The start game dialog isn't visible once we're connected... */
       +    DisplayConnectStatus((struct StartGameStruct *)data, FALSE,
       +                         oldstatus, oldsocks);
       +  }
       +
       +  if (oldstatus != NBS_CONNECTED && (status == NBS_CONNECTED || !DoneOK)) {
       +    FinishServerConnect(data, DoneOK);
       +  }
       +  if (status == NBS_CONNECTED && datawaiting) {
       +    while ((pt = GetWaitingPlayerMessage(ClientData.Play)) != NULL) {
       +      HandleClientMessage(pt, ClientData.Play);
       +      g_free(pt);
       +    }
       +  }
       +  if (!DoneOK) {
       +    if (status == NBS_CONNECTED) {
       +      /* The network connection to the server was dropped unexpectedly */
       +      g_warning(_("Connection to server lost - switching to "
       +                  "single player mode"));
       +      SwitchToSinglePlayer(ClientData.Play);
       +      UpdatePlayerLists();
       +      UpdateMenus();
       +    } else {
       +      ShutdownNetworkBuffer(&ClientData.Play->NetBuf);
       +    }
       +  }
       +}
       +
       +void SocketStatus(NetworkBuffer *NetBuf, gboolean Read, gboolean Write,
       +                  gboolean CallNow)
       +{
       +  if (NetBuf->InputTag)
       +    gdk_input_remove(NetBuf->InputTag);
       +  NetBuf->InputTag = 0;
       +  if (Read || Write) {
       +    NetBuf->InputTag = gdk_input_add(NetBuf->fd,
       +                                     (Read ? GDK_INPUT_READ : 0) |
       +                                     (Write ? GDK_INPUT_WRITE : 0),
       +                                     GetClientMessage,
       +                                     NetBuf->CallBackData);
       +  }
       +  if (CallNow)
       +    GetClientMessage(NetBuf->CallBackData, NetBuf->fd, 0);
       +}
       +#endif /* NETWORKING */
       +
       +void HandleClientMessage(char *pt, Player *Play)
       +{
       +  char *Data;
       +  DispMode DisplayMode;
       +  AICode AI;
       +  MsgCode Code;
       +  Player *From, *tmp;
       +  gchar *text;
       +  gboolean Handled;
       +  GtkWidget *MenuItem;
       +  GSList *list;
       +
       +  if (ProcessMessage(pt, Play, &From, &AI, &Code,
       +                     &Data, FirstClient) == -1) {
       +    return;
       +  }
       +
       +  Handled =
       +      HandleGenericClientMessage(From, AI, Code, Play, Data, &DisplayMode);
       +  switch (Code) {
       +  case C_STARTHISCORE:
       +    PrepareHighScoreDialog();
       +    break;
       +  case C_HISCORE:
       +    AddScoreToDialog(Data);
       +    break;
       +  case C_ENDHISCORE:
       +    CompleteHighScoreDialog((strcmp(Data, "end") == 0));
       +    break;
       +  case C_PRINTMESSAGE:
       +    PrintMessage(Data);
       +    break;
       +  case C_FIGHTPRINT:
       +    DisplayFightMessage(Data);
       +    break;
       +  case C_PUSH:
       +    /* The server admin has asked us to leave - so warn the user, and do
       +     * so */
       +    g_warning(_("You have been pushed from the server.\n"
       +                "Switching to single player mode."));
       +    SwitchToSinglePlayer(Play);
       +    UpdatePlayerLists();
       +    UpdateMenus();
       +    break;
       +  case C_QUIT:
       +    /* The server has sent us notice that it is shutting down */
       +    g_warning(_("The server has terminated.\n"
       +                "Switching to single player mode."));
       +    SwitchToSinglePlayer(Play);
       +    UpdatePlayerLists();
       +    UpdateMenus();
       +    break;
       +  case C_NEWNAME:
       +    NewNameDialog();
       +    break;
       +  case C_BANK:
       +    TransferDialog(FALSE);
       +    break;
       +  case C_LOANSHARK:
       +    TransferDialog(TRUE);
       +    break;
       +  case C_GUNSHOP:
       +    GunShopDialog();
       +    break;
       +  case C_MSG:
       +    text = g_strdup_printf("%s: %s", GetPlayerName(From), Data);
       +    PrintMessage(text);
       +    g_free(text);
       +    break;
       +  case C_MSGTO:
       +    text = g_strdup_printf("%s->%s: %s", GetPlayerName(From),
       +                           GetPlayerName(Play), Data);
       +    PrintMessage(text);
       +    g_free(text);
       +    break;
       +  case C_JOIN:
       +    text = g_strdup_printf(_("%s joins the game!"), Data);
       +    PrintMessage(text);
       +    g_free(text);
       +    UpdatePlayerLists();
       +    UpdateMenus();
       +    break;
       +  case C_LEAVE:
       +    if (From != &Noone) {
       +      text = g_strdup_printf(_("%s has left the game."), Data);
       +      PrintMessage(text);
       +      g_free(text);
       +      UpdatePlayerLists();
       +      UpdateMenus();
       +    }
       +    break;
       +  case C_QUESTION:
       +    QuestionDialog(Data, From == &Noone ? NULL : From);
       +    break;
       +  case C_SUBWAYFLASH:
       +    DisplayFightMessage(NULL);
       +    for (list = FirstClient; list; list = g_slist_next(list)) {
       +      tmp = (Player *)list->data;
       +      tmp->Flags &= ~FIGHTING;
       +    }
       +    /* Message displayed when the player "jets" to a new location */
       +    text = dpg_strdup_printf(_("Jetting to %tde"),
       +                             Location[(int)Play->IsAt].Name);
       +    PrintMessage(text);
       +    g_free(text);
       +    break;
       +  case C_ENDLIST:
       +    MenuItem = gtk_item_factory_get_widget(ClientData.Menu,
       +                                           "<main>/Errands/Sack Bitch...");
       +
       +    /* Text for the Errands/Sack Bitch menu item */
       +    text = dpg_strdup_printf(_("%/Sack Bitch menu item/S_ack %Tde..."),
       +                             Names.Bitch);
       +    SetAccelerator(MenuItem, text, NULL, NULL, NULL);
       +    g_free(text);
       +
       +    MenuItem = gtk_item_factory_get_widget(ClientData.Menu,
       +                                           "<main>/Errands/Spy...");
       +
       +    /* Text to update the Errands/Spy menu item with the price for spying */
       +    text = dpg_strdup_printf(_("_Spy (%P)"), Prices.Spy);
       +    SetAccelerator(MenuItem, text, NULL, NULL, NULL);
       +    g_free(text);
       +
       +    /* Text to update the Errands/Tipoff menu item with the price for a
       +     * tipoff */
       +    text = dpg_strdup_printf(_("_Tipoff (%P)"), Prices.Tipoff);
       +    MenuItem = gtk_item_factory_get_widget(ClientData.Menu,
       +                                           "<main>/Errands/Tipoff...");
       +    SetAccelerator(MenuItem, text, NULL, NULL, NULL);
       +    g_free(text);
       +    if (FirstClient->next)
       +      ListPlayers(NULL, NULL);
       +    UpdateMenus();
       +    break;
       +  case C_UPDATE:
       +    if (From == &Noone) {
       +      ReceivePlayerData(Play, Data, Play);
       +      UpdateStatus(Play);
       +    } else {
       +      ReceivePlayerData(Play, Data, From);
       +      DisplaySpyReports(From);
       +    }
       +    break;
       +  case C_DRUGHERE:
       +    UpdateInventory(&ClientData.Drug, Play->Drugs, NumDrug, TRUE);
       +    gtk_clist_sort(GTK_CLIST(ClientData.Drug.HereList));
       +    if (IsShowingInventory) {
       +      UpdateInventory(&ClientData.InvenDrug, Play->Drugs, NumDrug, TRUE);
       +    }
       +    break;
       +  default:
       +    if (!Handled) {
       +      g_print("Unknown network message received: %s^%c^%s^%s",
       +              GetPlayerName(From), Code, GetPlayerName(Play), Data);
       +    }
       +    break;
       +  }
       +}
       +
       +struct HiScoreDiaStruct {
       +  GtkWidget *dialog, *table, *vbox;
       +};
       +static struct HiScoreDiaStruct HiScoreDialog = { NULL, NULL, NULL };
       +
       +/* 
       + * Creates an empty dialog to display high scores.
       + */
       +void PrepareHighScoreDialog(void)
       +{
       +  GtkWidget *dialog, *vbox, *hsep, *table;
       +
       +  /* Make sure the server doesn't fool us into creating multiple dialogs */
       +  if (HiScoreDialog.dialog)
       +    return;
       +
       +  HiScoreDialog.dialog = dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       +
       +  /* Title of the GTK+ high score dialog */
       +  gtk_window_set_title(GTK_WINDOW(dialog), _("High Scores"));
       +
       +  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       +  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       +                               GTK_WINDOW(ClientData.window));
       +
       +  HiScoreDialog.vbox = vbox = gtk_vbox_new(FALSE, 7);
       +  HiScoreDialog.table = table = gtk_table_new(NUMHISCORE, 4, FALSE);
       +  gtk_table_set_row_spacings(GTK_TABLE(table), 5);
       +  gtk_table_set_col_spacings(GTK_TABLE(table), 30);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       +  gtk_widget_show_all(dialog);
       +}
       +
       +/* 
       + * Adds a single high score (coded in "Data", which is the information
       + * received in the relevant network message) to the dialog created by
       + * PrepareHighScoreDialog(), above.
       + */
       +void AddScoreToDialog(char *Data)
       +{
       +  GtkWidget *label;
       +  char *cp;
       +  gchar **spl1, **spl2;
       +  int index, slen;
       +  gboolean bold;
       +
       +  if (!HiScoreDialog.dialog)
       +    return;
       +
       +  cp = Data;
       +  index = GetNextInt(&cp, 0);
       +  if (!cp || strlen(cp) < 3)
       +    return;
       +
       +  bold = (*cp == 'B');          /* Is this score "our" score? (Currently
       +                                 * ignored) */
       +
       +  /* Step past the 'bold' character, and the initial '>' (if present) */
       +  cp += 2;
       +  g_strchug(cp);
       +
       +  /* Get the first word - the score */
       +  spl1 = g_strsplit(cp, " ", 1);
       +  if (!spl1 || !spl1[0] || !spl1[1]) {
       +    /* Error - the high score from the server is invalid */
       +    g_warning(_("Corrupt high score!"));
       +    g_strfreev(spl1);
       +    return;
       +  }
       +  label = gtk_label_new(spl1[0]);
       +  gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
       +  gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label,
       +                            0, 1, index, index + 1);
       +  gtk_widget_show(label);
       +
       +  /* Remove any leading whitespace from the remainder, since g_strsplit
       +   * will split at every space character, not at a run of them */
       +  g_strchug(spl1[1]);
       +
       +  /* Get the second word - the date */
       +  spl2 = g_strsplit(spl1[1], " ", 1);
       +  if (!spl2 || !spl2[0] || !spl2[1]) {
       +    g_warning(_("Corrupt high score!"));
       +    g_strfreev(spl2);
       +    return;
       +  }
       +  label = gtk_label_new(spl2[0]);
       +  gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
       +  gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label,
       +                            1, 2, index, index + 1);
       +  gtk_widget_show(label);
       +
       +  /* The remainder is the name, terminated with (R.I.P.) if the player
       +   * died, and '<' for the 'current' score */
       +  g_strchug(spl2[1]);
       +
       +  /* Remove '<' suffix if present */
       +  slen = strlen(spl2[1]);
       +  if (slen >= 1 && spl2[1][slen - 1] == '<') {
       +    spl2[1][slen - 1] = '\0';
       +  }
       +  slen--;
       +
       +  /* Check for (R.I.P.) suffix, and add it to the 4th column if found */
       +  if (slen > 8 && spl2[1][slen - 1] == ')' && spl2[1][slen - 8] == '(') {
       +    label = gtk_label_new(&spl2[1][slen - 8]);
       +    gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
       +    gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label,
       +                              3, 4, index, index + 1);
       +    gtk_widget_show(label);
       +    spl2[1][slen - 8] = '\0';   /* Remove suffix from the player name */
       +  }
       +
       +  /* Finally, add in what's left of the player name */
       +  g_strchomp(spl2[1]);
       +  label = gtk_label_new(spl2[1]);
       +  gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
       +  gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label,
       +                            2, 3, index, index + 1);
       +  gtk_widget_show(label);
       +
       +  g_strfreev(spl1);
       +  g_strfreev(spl2);
       +}
       +
       +/* 
       + * If the high scores are being displayed at the end of the game,
       + * this function is used to end the game when the high score dialog's
       + * "OK" button is pressed.
       + */
       +static void EndHighScore(GtkWidget *widget)
       +{
       +  EndGame();
       +}
       +
       +/* 
       + * Called when all high scores have been received. Finishes off the
       + * high score dialog by adding an "OK" button. If the game has ended,
       + * then "AtEnd" is TRUE, and clicking this button will end the game.
       + */
       +void CompleteHighScoreDialog(gboolean AtEnd)
       +{
       +  GtkWidget *OKButton, *dialog;
       +
       +  dialog = HiScoreDialog.dialog;
       +
       +  if (!HiScoreDialog.dialog)
       +    return;
       +
       +  /* Caption of the "OK" button in dialogs */
       +  OKButton = gtk_button_new_with_label(_("OK"));
       +  gtk_signal_connect_object(GTK_OBJECT(OKButton), "clicked",
       +                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                            (gpointer)dialog);
       +  if (AtEnd) {
       +    InGame = FALSE;
       +    gtk_signal_connect_object(GTK_OBJECT(dialog), "destroy",
       +                              GTK_SIGNAL_FUNC(EndHighScore), NULL);
       +  }
       +  gtk_box_pack_start(GTK_BOX(HiScoreDialog.vbox), OKButton, TRUE, TRUE, 0);
       +
       +  GTK_WIDGET_SET_FLAGS(OKButton, GTK_CAN_DEFAULT);
       +  gtk_widget_grab_default(OKButton);
       +  gtk_widget_show(OKButton);
       +
       +  /* OK, we're done - allow the creation of new high score dialogs */
       +  HiScoreDialog.dialog = NULL;
       +}
       +
       +/* 
       + * Prints an information message in the display area of the GTK+ client.
       + * This area is used for displaying drug busts, messages from other
       + * players, etc. The message is passed in as the string "text".
       + */
       +void PrintMessage(char *text)
       +{
       +  gint EditPos;
       +  char *cr = "\n";
       +  GtkEditable *messages;
       +
       +  messages = GTK_EDITABLE(ClientData.messages);
       +
       +  gtk_text_freeze(GTK_TEXT(messages));
       +  g_strdelimit(text, "^", '\n');
       +  EditPos = gtk_text_get_length(GTK_TEXT(ClientData.messages));
       +  while (*text == '\n')
       +    text++;
       +  gtk_editable_insert_text(messages, text, strlen(text), &EditPos);
       +  if (text[strlen(text) - 1] != '\n') {
       +    gtk_editable_insert_text(messages, cr, strlen(cr), &EditPos);
       +  }
       +  gtk_text_thaw(GTK_TEXT(messages));
       +  gtk_editable_set_position(messages, EditPos);
       +}
       +
       +/* 
       + * Called when one of the action buttons in the Fight dialog is clicked.
       + * "data" specifies which button (Deal Drugs/Run/Fight/Stand) was pressed.
       + */
       +static void FightCallback(GtkWidget *widget, gpointer data)
       +{
       +  gint Answer;
       +  Player *Play;
       +  gchar text[4];
       +  GtkWidget *window;
       +  gpointer CanRunHere = NULL;
       +
       +  window = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
       +  if (window)
       +    CanRunHere = gtk_object_get_data(GTK_OBJECT(window), "CanRunHere");
       +
       +  Answer = GPOINTER_TO_INT(data);
       +  Play = ClientData.Play;
       +  switch (Answer) {
       +  case 'D':
       +    gtk_widget_hide(FightDialog);
       +    break;
       +  case 'R':
       +    if (CanRunHere) {
       +      SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, "R");
       +    } else {
       +      Jet(FightDialog);
       +    }
       +    break;
       +  case 'F':
       +  case 'S':
       +    text[0] = Answer;
       +    text[1] = '\0';
       +    SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, text);
       +    break;
       +  }
       +}
       +
       +/* 
       + * Adds an action button to the hbox at the base of the Fight dialog.
       + * The button's caption is given by "Text", and the keyboard shortcut
       + * (if any) is added to "accel_group". "Answer" gives the identifier
       + * passed to FightCallback, above.
       + */
       +static GtkWidget *AddFightButton(gchar *Text, GtkAccelGroup *accel_group,
       +                                 GtkBox *box, gint Answer)
       +{
       +  GtkWidget *button;
       +
       +  button = gtk_button_new_with_label("");
       +  SetAccelerator(button, Text, button, "clicked", accel_group);
       +  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                     GTK_SIGNAL_FUNC(FightCallback),
       +                     GINT_TO_POINTER(Answer));
       +  gtk_box_pack_start(box, button, TRUE, TRUE, 0);
       +  return button;
       +}
       +
       +/* Data used to keep track of the widgets giving the information about a
       + * player/cop involved in a fight */
       +struct combatant {
       +  GtkWidget *name, *bitches, *healthprog, *healthlabel;
       +};
       +
       +/* 
       + * Creates an empty Fight dialog. Usually this only needs to be done once,
       + * as when the user "closes" it, it is only hidden, ready to be reshown
       + * later. Buttons for all actions are added here, and are hidden/shown
       + * as necessary.
       + */
       +static void CreateFightDialog(void)
       +{
       +  GtkWidget *dialog, *vbox, *button, *hbox, *hbbox, *hsep, *text, *table;
       +  GtkAccelGroup *accel_group;
       +  GArray *combatants;
       +  gchar *buf;
       +
       +  FightDialog = dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       +  gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
       +  gtk_signal_connect(GTK_OBJECT(dialog), "delete_event",
       +                     GTK_SIGNAL_FUNC(DisallowDelete), NULL);
       +  gtk_window_set_default_size(GTK_WINDOW(dialog), 240, 130);
       +  accel_group = gtk_accel_group_new();
       +  gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group);
       +  gtk_window_set_title(GTK_WINDOW(dialog), _("Fight"));
       +  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       +
       +  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       +                               GTK_WINDOW(ClientData.window));
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +
       +  table = gtk_table_new(2, 4, FALSE);
       +  gtk_table_set_row_spacings(GTK_TABLE(table), 5);
       +  gtk_table_set_col_spacings(GTK_TABLE(table), 5);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_table_attach_defaults(GTK_TABLE(table), hsep, 0, 4, 1, 2);
       +  gtk_widget_show_all(table);
       +  gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
       +  gtk_object_set_data(GTK_OBJECT(dialog), "table", table);
       +
       +  combatants = g_array_new(FALSE, TRUE, sizeof(struct combatant));
       +  g_array_set_size(combatants, 1);
       +  gtk_object_set_data(GTK_OBJECT(dialog), "combatants", combatants);
       +
       +  text = gtk_scrolled_text_new(NULL, NULL, &hbox);
       +  gtk_widget_set_usize(text, 150, 120);
       +
       +  gtk_text_set_editable(GTK_TEXT(text), FALSE);
       +  gtk_text_set_word_wrap(GTK_TEXT(text), TRUE);
       +  gtk_object_set_data(GTK_OBJECT(dialog), "text", text);
       +  gtk_widget_show_all(hbox);
       +  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +  gtk_widget_show(hsep);
       +
       +  hbbox = gtk_hbutton_box_new();
       +
       +  /* Button for closing the "Fight" dialog and going back to dealing drugs
       +   * (%Tde = "Drugs" by default) */
       +  buf = dpg_strdup_printf(_("_Deal %Tde"), Names.Drugs);
       +  button = AddFightButton(buf, accel_group, GTK_BOX(hbbox), 'D');
       +  gtk_object_set_data(GTK_OBJECT(dialog), "deal", button);
       +  g_free(buf);
       +
       +  /* Button for shooting at other players in the "Fight" dialog, or for
       +   * popping up the "Fight" dialog from the main window */
       +  button = AddFightButton(_("_Fight"), accel_group, GTK_BOX(hbbox), 'F');
       +  gtk_object_set_data(GTK_OBJECT(dialog), "fight", button);
       +
       +  /* Button to stand and take it in the "Fight" dialog */
       +  button = AddFightButton(_("_Stand"), accel_group, GTK_BOX(hbbox), 'S');
       +  gtk_object_set_data(GTK_OBJECT(dialog), "stand", button);
       +
       +  /* Button to run from combat in the "Fight" dialog */
       +  button = AddFightButton(_("_Run"), accel_group, GTK_BOX(hbbox), 'R');
       +  gtk_object_set_data(GTK_OBJECT(dialog), "run", button);
       +
       +  gtk_widget_show(hsep);
       +  gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
       +  gtk_widget_show(hbbox);
       +  gtk_widget_show(vbox);
       +  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       +  gtk_widget_show(dialog);
       +}
       +
       +/* 
       + * Updates the display of information for a player/cop in the Fight dialog.
       + * If the player's name (DefendName) already exists, updates the display of
       + * total health and number of bitches - otherwise, adds a new entry. If
       + * DefendBitches is -1, then the player has left.
       + */
       +static void UpdateCombatant(gchar *DefendName, int DefendBitches,
       +                            gchar *BitchName, int DefendHealth)
       +{
       +  guint i, RowIndex;
       +  gchar *name;
       +  struct combatant *compt;
       +  GArray *combatants;
       +  GtkWidget *table;
       +  gchar *BitchText, *HealthText;
       +  gfloat ProgPercent;
       +
       +  combatants = (GArray *)gtk_object_get_data(GTK_OBJECT(FightDialog),
       +                                             "combatants");
       +  table = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "table"));
       +  if (!combatants)
       +    return;
       +
       +  if (DefendName[0]) {
       +    compt = NULL;
       +    for (i = 1, RowIndex = 2; i < combatants->len; i++, RowIndex++) {
       +      compt = &g_array_index(combatants, struct combatant, i);
       +
       +      if (!compt || !compt->name) {
       +        compt = NULL;
       +        continue;
       +      }
       +      gtk_label_get(GTK_LABEL(compt->name), &name);
       +      if (name && strcmp(name, DefendName) == 0)
       +        break;
       +      compt = NULL;
       +    }
       +    if (!compt) {
       +      i = combatants->len;
       +      g_array_set_size(combatants, i + 1);
       +      compt = &g_array_index(combatants, struct combatant, i);
       +
       +      gtk_table_resize(GTK_TABLE(table), i + 2, 4);
       +      RowIndex = i + 1;
       +    }
       +  } else {
       +    compt = &g_array_index(combatants, struct combatant, 0);
       +
       +    RowIndex = 0;
       +  }
       +
       +  /* Display of number of bitches or deputies during combat
       +   * (%tde="bitches" or "deputies" (etc.) by default) */
       +  BitchText = dpg_strdup_printf(_("%/Combat: Bitches/%d %tde"),
       +                                DefendBitches, BitchName);
       +
       +  /* Display of health during combat */
       +  if (DefendBitches == -1) {
       +    HealthText = g_strdup(_("(Left)"));
       +  } else if (DefendHealth == 0 && DefendBitches == 0) {
       +    HealthText = g_strdup(_("(Dead)"));
       +  } else {
       +    HealthText = g_strdup_printf(_("Health: %d"), DefendHealth);
       +  }
       +
       +  ProgPercent = (gfloat)DefendHealth / 100.0;
       +
       +  if (compt->name) {
       +    if (DefendName[0]) {
       +      gtk_label_set_text(GTK_LABEL(compt->name), DefendName);
       +    }
       +    if (DefendBitches >= 0) {
       +      gtk_label_set_text(GTK_LABEL(compt->bitches), BitchText);
       +    }
       +    gtk_label_set_text(GTK_LABEL(compt->healthlabel), HealthText);
       +    gtk_progress_bar_update(GTK_PROGRESS_BAR(compt->healthprog),
       +                            ProgPercent);
       +  } else {
       +    /* Display of the current player's name during combat */
       +    compt->name = gtk_label_new(DefendName[0] ? DefendName : _("You"));
       +
       +    gtk_table_attach_defaults(GTK_TABLE(table), compt->name, 0, 1,
       +                              RowIndex, RowIndex + 1);
       +    compt->bitches = gtk_label_new(DefendBitches >= 0 ? BitchText : "");
       +    gtk_table_attach_defaults(GTK_TABLE(table), compt->bitches, 1, 2,
       +                              RowIndex, RowIndex + 1);
       +    compt->healthprog = gtk_progress_bar_new();
       +    gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(compt->healthprog),
       +                                     GTK_PROGRESS_LEFT_TO_RIGHT);
       +    gtk_progress_bar_update(GTK_PROGRESS_BAR(compt->healthprog),
       +                            ProgPercent);
       +    gtk_table_attach_defaults(GTK_TABLE(table), compt->healthprog, 2, 3,
       +                              RowIndex, RowIndex + 1);
       +    compt->healthlabel = gtk_label_new(HealthText);
       +    gtk_table_attach_defaults(GTK_TABLE(table), compt->healthlabel, 3, 4,
       +                              RowIndex, RowIndex + 1);
       +    gtk_widget_show(compt->name);
       +    gtk_widget_show(compt->bitches);
       +    gtk_widget_show(compt->healthprog);
       +    gtk_widget_show(compt->healthlabel);
       +  }
       +
       +  g_free(BitchText);
       +  g_free(HealthText);
       +}
       +
       +/* 
       + * Cleans up the list of all players/cops involved in a fight.
       + */
       +static void FreeCombatants(void)
       +{
       +  GArray *combatants;
       +
       +  combatants = (GArray *)gtk_object_get_data(GTK_OBJECT(FightDialog),
       +                                             "combatants");
       +  if (!combatants)
       +    return;
       +
       +  g_array_free(combatants, TRUE);
       +}
       +
       +/* 
       + * Given the network message "Data" concerning some happening during
       + * combat, extracts the relevant data and updates the Fight dialog,
       + * creating and/or showing it if necessary.
       + * If "Data" is NULL, then closes the dialog. If "Data" is a blank
       + * string, then just shows the dialog, displaying no new messages.
       + */
       +void DisplayFightMessage(char *Data)
       +{
       +  Player *Play;
       +  gint EditPos;
       +  GtkAccelGroup *accel_group;
       +  GtkWidget *Deal, *Fight, *Stand, *Run, *Text;
       +  char cr[] = "\n";
       +  gchar *AttackName, *DefendName, *BitchName, *Message;
       +  FightPoint fp;
       +  int DefendHealth, DefendBitches, BitchesKilled, ArmPercent;
       +  gboolean CanRunHere, Loot, CanFire;
       +
       +  if (!Data) {
       +    if (FightDialog) {
       +      FreeCombatants();
       +      gtk_widget_destroy(FightDialog);
       +      FightDialog = NULL;
       +    }
       +    return;
       +  }
       +  if (FightDialog) {
       +    if (!GTK_WIDGET_VISIBLE(FightDialog))
       +      gtk_widget_show(FightDialog);
       +  } else {
       +    CreateFightDialog();
       +  }
       +  if (!FightDialog || !Data[0])
       +    return;
       +
       +  Deal = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "deal"));
       +  Fight = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "fight"));
       +  Stand = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "stand"));
       +  Run = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "run"));
       +  Text = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "text"));
       +
       +  Play = ClientData.Play;
       +
       +  if (HaveAbility(Play, A_NEWFIGHT)) {
       +    ReceiveFightMessage(Data, &AttackName, &DefendName, &DefendHealth,
       +                        &DefendBitches, &BitchName, &BitchesKilled,
       +                        &ArmPercent, &fp, &CanRunHere, &Loot, &CanFire,
       +                        &Message);
       +    Play->Flags |= FIGHTING;
       +    switch (fp) {
       +    case F_HIT:
       +    case F_ARRIVED:
       +    case F_MISS:
       +      UpdateCombatant(DefendName, DefendBitches, BitchName, DefendHealth);
       +      break;
       +    case F_LEAVE:
       +      if (AttackName[0]) {
       +        UpdateCombatant(AttackName, -1, BitchName, 0);
       +      }
       +      break;
       +    case F_LASTLEAVE:
       +      Play->Flags &= ~FIGHTING;
       +      break;
       +    default:
       +    }
       +    accel_group = (GtkAccelGroup *)
       +        gtk_object_get_data(GTK_OBJECT(ClientData.window), "accel_group");
       +    SetJetButtonTitle(accel_group);
       +  } else {
       +    Message = Data;
       +    if (Play->Flags & FIGHTING)
       +      fp = F_MSG;
       +    else
       +      fp = F_LASTLEAVE;
       +    CanFire = (Play->Flags & CANSHOOT);
       +    CanRunHere = FALSE;
       +  }
       +  gtk_object_set_data(GTK_OBJECT(FightDialog), "CanRunHere",
       +                      GINT_TO_POINTER(CanRunHere));
       +
       +  g_strdelimit(Message, "^", '\n');
       +  if (strlen(Message) > 0) {
       +    EditPos = gtk_text_get_length(GTK_TEXT(Text));
       +    gtk_editable_insert_text(GTK_EDITABLE(Text), Message,
       +                             strlen(Message), &EditPos);
       +    gtk_editable_insert_text(GTK_EDITABLE(Text), cr, strlen(cr), &EditPos);
       +  }
       +
       +  if (!CanRunHere || fp == F_LASTLEAVE)
       +    gtk_widget_show(Deal);
       +  else
       +    gtk_widget_hide(Deal);
       +  if (CanFire && TotalGunsCarried(Play) > 0)
       +    gtk_widget_show(Fight);
       +  else
       +    gtk_widget_hide(Fight);
       +  if (CanFire && TotalGunsCarried(Play) == 0)
       +    gtk_widget_show(Stand);
       +  else
       +    gtk_widget_hide(Stand);
       +  if (fp != F_LASTLEAVE)
       +    gtk_widget_show(Run);
       +  else
       +    gtk_widget_hide(Run);
       +}
       +
       +/* 
       + * Updates the display of pertinent data about player "Play" (location,
       + * health, etc. in the status widgets given by "Status". This can point
       + * to the widgets at the top of the main window, or those in a Spy
       + * Reports dialog.
       + */
       +void DisplayStats(Player *Play, struct StatusWidgets *Status)
       +{
       +  gchar *prstr;
       +  GString *text;
       +
       +  text = g_string_new(NULL);
       +
       +  gtk_label_set_text(GTK_LABEL(Status->Location),
       +                     Location[(int)Play->IsAt].Name);
       +
       +  g_string_sprintf(text, "%s%02d%s", Names.Month, Play->Turn, Names.Year);
       +  gtk_label_set_text(GTK_LABEL(Status->Date), text->str);
       +
       +  g_string_sprintf(text, "%d", Play->CoatSize);
       +  gtk_label_set_text(GTK_LABEL(Status->SpaceValue), text->str);
       +
       +  prstr = FormatPrice(Play->Cash);
       +  gtk_label_set_text(GTK_LABEL(Status->CashValue), prstr);
       +  g_free(prstr);
       +
       +  prstr = FormatPrice(Play->Bank);
       +  gtk_label_set_text(GTK_LABEL(Status->BankValue), prstr);
       +  g_free(prstr);
       +
       +  prstr = FormatPrice(Play->Debt);
       +  gtk_label_set_text(GTK_LABEL(Status->DebtValue), prstr);
       +  g_free(prstr);
       +
       +  /* Display of carried guns in GTK+ client status window (%Tde="Guns" by
       +   * default) */
       +  dpg_string_sprintf(text, _("%/GTK Stats: Guns/%Tde"), Names.Guns);
       +  gtk_label_set_text(GTK_LABEL(Status->GunsName), text->str);
       +  g_string_sprintf(text, "%d", TotalGunsCarried(Play));
       +  gtk_label_set_text(GTK_LABEL(Status->GunsValue), text->str);
       +
       +  if (!WantAntique) {
       +    /* Display of number of bitches in GTK+ client status window
       +     * (%Tde="Bitches" by default) */
       +    dpg_string_sprintf(text, _("%/GTK Stats: Bitches/%Tde"),
       +                       Names.Bitches);
       +    gtk_label_set_text(GTK_LABEL(Status->BitchesName), text->str);
       +    g_string_sprintf(text, "%d", Play->Bitches.Carried);
       +    gtk_label_set_text(GTK_LABEL(Status->BitchesValue), text->str);
       +  } else {
       +    gtk_label_set_text(GTK_LABEL(Status->BitchesName), NULL);
       +    gtk_label_set_text(GTK_LABEL(Status->BitchesValue), NULL);
       +  }
       +
       +  g_string_sprintf(text, "%d", Play->Health);
       +  gtk_label_set_text(GTK_LABEL(Status->HealthValue), text->str);
       +
       +  g_string_free(text, TRUE);
       +}
       +
       +/* 
       + * Updates all of the player status in response to a message from the
       + * server. This includes the main window display, the gun shop (if
       + * displayed) and the inventory (if displayed).
       + */
       +void UpdateStatus(Player *Play)
       +{
       +  GtkAccelGroup *accel_group;
       +
       +  DisplayStats(Play, &ClientData.Status);
       +  UpdateInventory(&ClientData.Drug, ClientData.Play->Drugs, NumDrug, TRUE);
       +  gtk_clist_sort(GTK_CLIST(ClientData.Drug.HereList));
       +  accel_group = (GtkAccelGroup *)
       +      gtk_object_get_data(GTK_OBJECT(ClientData.window), "accel_group");
       +  SetJetButtonTitle(accel_group);
       +  if (IsShowingGunShop) {
       +    UpdateInventory(&ClientData.Gun, ClientData.Play->Guns, NumGun, FALSE);
       +  }
       +  if (IsShowingInventory) {
       +    UpdateInventory(&ClientData.InvenDrug, ClientData.Play->Drugs,
       +                    NumDrug, TRUE);
       +    UpdateInventory(&ClientData.InvenGun, ClientData.Play->Guns,
       +                    NumGun, FALSE);
       +  }
       +}
       +
       +void UpdateInventory(struct InventoryWidgets *Inven,
       +                     Inventory *Objects, int NumObjects, gboolean AreDrugs)
       +{
       +  GtkWidget *herelist, *carrylist;
       +  Player *Play;
       +  gint i, row, selectrow[2];
       +  gpointer rowdata;
       +  price_t price;
       +  gchar *titles[2];
       +  gboolean CanBuy = FALSE, CanSell = FALSE, CanDrop = FALSE;
       +  GList *glist[2], *selection;
       +  GtkCList *clist[2];
       +  int numlist;
       +
       +  Play = ClientData.Play;
       +  herelist = Inven->HereList;
       +  carrylist = Inven->CarriedList;
       +
       +  if (herelist)
       +    numlist = 2;
       +  else
       +    numlist = 1;
       +
       +  /* Make lists of the current selections */
       +  clist[0] = GTK_CLIST(carrylist);
       +  if (herelist)
       +    clist[1] = GTK_CLIST(herelist);
       +  else
       +    clist[1] = NULL;
       +
       +  for (i = 0; i < numlist; i++) {
       +    glist[i] = NULL;
       +    selectrow[i] = -1;
       +    for (selection = clist[i]->selection; selection;
       +         selection = g_list_next(selection)) {
       +      row = GPOINTER_TO_INT(selection->data);
       +      rowdata = gtk_clist_get_row_data(clist[i], row);
       +      glist[i] = g_list_append(glist[i], rowdata);
       +    }
       +  }
       +
       +  gtk_clist_freeze(GTK_CLIST(carrylist));
       +  gtk_clist_clear(GTK_CLIST(carrylist));
       +
       +  if (herelist) {
       +    gtk_clist_freeze(GTK_CLIST(herelist));
       +    gtk_clist_clear(GTK_CLIST(herelist));
       +  }
       +
       +  for (i = 0; i < NumObjects; i++) {
       +    if (AreDrugs) {
       +      titles[0] = Drug[i].Name;
       +      price = Objects[i].Price;
       +    } else {
       +      titles[0] = Gun[i].Name;
       +      price = Gun[i].Price;
       +    }
       +
       +    if (herelist && price > 0) {
       +      CanBuy = TRUE;
       +      titles[1] = FormatPrice(price);
       +      row = gtk_clist_append(GTK_CLIST(herelist), titles);
       +      g_free(titles[1]);
       +      gtk_clist_set_row_data(GTK_CLIST(herelist), row, GINT_TO_POINTER(i));
       +      if (g_list_find(glist[1], GINT_TO_POINTER(i))) {
       +        selectrow[1] = row;
       +        gtk_clist_select_row(GTK_CLIST(herelist), row, 0);
       +      }
       +    }
       +
       +    if (Objects[i].Carried > 0) {
       +      if (price > 0)
       +        CanSell = TRUE;
       +      else
       +        CanDrop = TRUE;
       +      if (HaveAbility(ClientData.Play, A_DRUGVALUE) && AreDrugs) {
       +        titles[1] = dpg_strdup_printf("%d @ %P", Objects[i].Carried,
       +                                      Objects[i].TotalValue /
       +                                      Objects[i].Carried);
       +      } else {
       +        titles[1] = g_strdup_printf("%d", Objects[i].Carried);
       +      }
       +      row = gtk_clist_append(GTK_CLIST(carrylist), titles);
       +      g_free(titles[1]);
       +      gtk_clist_set_row_data(GTK_CLIST(carrylist), row,
       +                             GINT_TO_POINTER(i));
       +      if (g_list_find(glist[0], GINT_TO_POINTER(i))) {
       +        selectrow[0] = row;
       +        gtk_clist_select_row(GTK_CLIST(carrylist), row, 0);
       +      }
       +    }
       +  }
       +
       +  for (i = 0; i < numlist; i++) {
       +    if (selectrow[i] != -1 && gtk_clist_row_is_visible(clist[i],
       +                                                       selectrow[i]) !=
       +        GTK_VISIBILITY_FULL) {
       +      gtk_clist_moveto(clist[i], selectrow[i], 0, 0.0, 0.0);
       +    }
       +    g_list_free(glist[i]);
       +  }
       +
       +  gtk_clist_thaw(GTK_CLIST(carrylist));
       +  if (herelist)
       +    gtk_clist_thaw(GTK_CLIST(herelist));
       +
       +  if (Inven->vbbox) {
       +    gtk_widget_set_sensitive(Inven->BuyButton, CanBuy);
       +    gtk_widget_set_sensitive(Inven->SellButton, CanSell);
       +    gtk_widget_set_sensitive(Inven->DropButton, CanDrop);
       +  }
       +}
       +
       +static void JetCallback(GtkWidget *widget, gpointer data)
       +{
       +  int NewLocation;
       +  gchar *text;
       +  GtkWidget *JetDialog;
       +
       +  JetDialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "dialog"));
       +  NewLocation = GPOINTER_TO_INT(data);
       +  gtk_widget_destroy(JetDialog);
       +  text = g_strdup_printf("%d", NewLocation);
       +  SendClientMessage(ClientData.Play, C_NONE, C_REQUESTJET, NULL, text);
       +  g_free(text);
       +}
       +
       +void JetButtonPressed(GtkWidget *widget, gpointer data)
       +{
       +  if (InGame) {
       +    if (ClientData.Play->Flags & FIGHTING) {
       +      DisplayFightMessage(NULL);
       +    } else {
       +      Jet(NULL);
       +    }
       +  }
       +}
       +
       +void Jet(GtkWidget *parent)
       +{
       +  GtkWidget *dialog, *table, *button, *label, *vbox;
       +  GtkAccelGroup *accel_group;
       +  gint boxsize, i, row, col;
       +  gchar *name, AccelChar;
       +
       +  accel_group = gtk_accel_group_new();
       +
       +  dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       +  /* Title of 'Jet' dialog */
       +  gtk_window_set_title(GTK_WINDOW(dialog), _("Jet to location"));
       +
       +  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       +  gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group);
       +  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       +                               parent ? GTK_WINDOW(parent)
       +                               : GTK_WINDOW(ClientData.window));
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +
       +  /* Prompt in 'Jet' dialog */
       +  label = gtk_label_new(_("Where to, dude ? "));
       +  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       +
       +  /* Generate a square box of buttons for all locations */
       +  boxsize = 1;
       +  while (boxsize * boxsize < NumLocation)
       +    boxsize++;
       +  col = boxsize;
       +  row = 1;
       +
       +  /* Avoid creating a box with an entire row empty at the bottom */
       +  while (row * col < NumLocation)
       +    row++;
       +
       +  table = gtk_table_new(row, col, TRUE);
       +
       +  for (i = 0; i < NumLocation; i++) {
       +    if (i < 9)
       +      AccelChar = '1' + i;
       +    else if (i < 35)
       +      AccelChar = 'A' + i - 9;
       +    else
       +      AccelChar = '\0';
       +
       +    row = i / boxsize;
       +    col = i % boxsize;
       +    if (AccelChar == '\0') {
       +      button = gtk_button_new_with_label(Location[i].Name);
       +    } else {
       +      button = gtk_button_new_with_label("");
       +
       +      /* Display of locations in 'Jet' window (%tde="The Bronx" etc. by
       +       * default) */
       +      name = dpg_strdup_printf(_("_%c. %tde"), AccelChar, Location[i].Name);
       +      SetAccelerator(button, name, button, "clicked", accel_group);
       +      /* Add keypad shortcuts as well */
       +      if (i < 9) {
       +        gtk_widget_add_accelerator(button, "clicked", accel_group,
       +                                   GDK_KP_1 + i, 0,
       +                                   GTK_ACCEL_VISIBLE |
       +                                   GTK_ACCEL_SIGNAL_VISIBLE);
       +      }
       +      g_free(name);
       +    }
       +    gtk_widget_set_sensitive(button, i != ClientData.Play->IsAt);
       +    gtk_object_set_data(GTK_OBJECT(button), "dialog", dialog);
       +    gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                       GTK_SIGNAL_FUNC(JetCallback), GINT_TO_POINTER(i));
       +    gtk_table_attach_defaults(GTK_TABLE(table), button, col, col + 1, row,
       +                              row + 1);
       +  }
       +  gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
       +
       +  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       +  gtk_widget_show_all(dialog);
       +}
       +
       +struct DealDiaStruct {
       +  GtkWidget *dialog, *cost, *carrying, *space, *afford, *amount;
       +  gint DrugInd;
       +  gpointer Type;
       +};
       +static struct DealDiaStruct DealDialog;
       +
       +static void UpdateDealDialog(void)
       +{
       +  GString *text;
       +  GtkAdjustment *spin_adj;
       +  gint DrugInd, CanDrop, CanCarry, CanAfford, MaxDrug;
       +  Player *Play;
       +
       +  text = g_string_new(NULL);
       +  DrugInd = DealDialog.DrugInd;
       +  Play = ClientData.Play;
       +
       +  /* Display of the current price of the selected drug in 'Deal Drugs'
       +   * dialog */
       +  dpg_string_sprintf(text, _("at %P"), Play->Drugs[DrugInd].Price);
       +  gtk_label_set_text(GTK_LABEL(DealDialog.cost), text->str);
       +
       +  CanDrop = Play->Drugs[DrugInd].Carried;
       +
       +  /* Display of current inventory of the selected drug in 'Deal Drugs'
       +   * dialog (%tde="Opium" etc. by default) */
       +  dpg_string_sprintf(text, _("You are currently carrying %d %tde"),
       +                     CanDrop, Drug[DrugInd].Name);
       +  gtk_label_set_text(GTK_LABEL(DealDialog.carrying), text->str);
       +
       +  CanCarry = Play->CoatSize;
       +
       +  /* Available space for drugs in 'Deal Drugs' dialog */
       +  g_string_sprintf(text, _("Available space: %d"), CanCarry);
       +  gtk_label_set_text(GTK_LABEL(DealDialog.space), text->str);
       +
       +  if (DealDialog.Type == BT_BUY) {
       +    CanAfford = Play->Cash / Play->Drugs[DrugInd].Price;
       +
       +    /* Number of the selected drug that you can afford in 'Deal Drugs'
       +     * dialog */
       +    g_string_sprintf(text, _("You can afford %d"), CanAfford);
       +    gtk_label_set_text(GTK_LABEL(DealDialog.afford), text->str);
       +    MaxDrug = MIN(CanCarry, CanAfford);
       +  } else
       +    MaxDrug = CanDrop;
       +
       +  spin_adj = (GtkAdjustment *)gtk_adjustment_new(MaxDrug, 1.0, MaxDrug,
       +                                                 1.0, 10.0, 10.0);
       +  gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(DealDialog.amount),
       +                                 spin_adj);
       +  gtk_spin_button_set_value(GTK_SPIN_BUTTON(DealDialog.amount), MaxDrug);
       +
       +  g_string_free(text, TRUE);
       +}
       +
       +static void DealSelectCallback(GtkWidget *widget, gpointer data)
       +{
       +  DealDialog.DrugInd = GPOINTER_TO_INT(data);
       +  UpdateDealDialog();
       +}
       +
       +static void DealOKCallback(GtkWidget *widget, gpointer data)
       +{
       +  GtkWidget *spinner;
       +  gint amount;
       +  gchar *text;
       +
       +  spinner = DealDialog.amount;
       +
       +  gtk_spin_button_update(GTK_SPIN_BUTTON(spinner));
       +  amount = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner));
       +
       +  text = g_strdup_printf("drug^%d^%d", DealDialog.DrugInd,
       +                         data == BT_BUY ? amount : -amount);
       +  SendClientMessage(ClientData.Play, C_NONE, C_BUYOBJECT, NULL, text);
       +  g_free(text);
       +
       +  gtk_widget_destroy(DealDialog.dialog);
       +}
       +
       +void DealDrugs(GtkWidget *widget, gpointer data)
       +{
       +  GtkWidget *dialog, *label, *hbox, *hbbox, *button, *spinner, *menu,
       +      *optionmenu, *menuitem, *vbox, *hsep;
       +  GtkAdjustment *spin_adj;
       +  GtkAccelGroup *accel_group;
       +  GtkWidget *clist;
       +  gchar *Action;
       +  GString *text;
       +  GList *selection;
       +  gint row;
       +  Player *Play;
       +  gint DrugInd, i, SelIndex, FirstInd;
       +  gboolean DrugIndOK;
       +
       +  /* Action in 'Deal Drugs' dialog - "Buy/Sell/Drop Drugs" */
       +  if (data == BT_BUY)
       +    Action = _("Buy");
       +  else if (data == BT_SELL)
       +    Action = _("Sell");
       +  else if (data == BT_DROP)
       +    Action = _("Drop");
       +  else {
       +    g_warning("Bad DealDrug type");
       +    return;
       +  }
       +
       +  DealDialog.Type = data;
       +  Play = ClientData.Play;
       +
       +  if (data == BT_BUY)
       +    clist = ClientData.Drug.HereList;
       +  else
       +    clist = ClientData.Drug.CarriedList;
       +  selection = GTK_CLIST(clist)->selection;
       +  if (selection) {
       +    row = GPOINTER_TO_INT(selection->data);
       +    DrugInd =
       +        GPOINTER_TO_INT(gtk_clist_get_row_data(GTK_CLIST(clist), row));
       +  } else
       +    DrugInd = -1;
       +
       +  DrugIndOK = FALSE;
       +  FirstInd = -1;
       +  for (i = 0; i < NumDrug; i++) {
       +    if ((data == BT_DROP && Play->Drugs[i].Carried > 0
       +         && Play->Drugs[i].Price == 0)
       +        || (data == BT_SELL && Play->Drugs[i].Carried > 0
       +         && Play->Drugs[i].Price != 0)
       +        || (data == BT_BUY && Play->Drugs[i].Price != 0)) {
       +      if (FirstInd == -1)
       +        FirstInd = i;
       +      if (DrugInd == i)
       +        DrugIndOK = TRUE;
       +    }
       +  }
       +  if (!DrugIndOK) {
       +    if (FirstInd == -1)
       +      return;
       +    else
       +      DrugInd = FirstInd;
       +  }
       +
       +  text = g_string_new(NULL);
       +  accel_group = gtk_accel_group_new();
       +  dialog = DealDialog.dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       +  gtk_window_set_title(GTK_WINDOW(dialog), Action);
       +  gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group);
       +  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       +  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       +                               GTK_WINDOW(ClientData.window));
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +
       +  hbox = gtk_hbox_new(FALSE, 7);
       +
       +  label = gtk_label_new(Action);
       +  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
       +
       +  optionmenu = gtk_option_menu_new();
       +  menu = gtk_menu_new();
       +  SelIndex = -1;
       +  for (i = 0; i < NumDrug; i++) {
       +    if ((data == BT_DROP && Play->Drugs[i].Carried > 0
       +         && Play->Drugs[i].Price == 0)
       +        || (data == BT_SELL && Play->Drugs[i].Carried > 0
       +         && Play->Drugs[i].Price != 0)
       +        || (data == BT_BUY && Play->Drugs[i].Price != 0)) {
       +      menuitem = gtk_menu_item_new_with_label(Drug[i].Name);
       +      gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
       +                         GTK_SIGNAL_FUNC(DealSelectCallback),
       +                         GINT_TO_POINTER(i));
       +      gtk_menu_append(GTK_MENU(menu), menuitem);
       +      if (DrugInd >= i)
       +        SelIndex++;
       +    }
       +  }
       +  gtk_menu_set_active(GTK_MENU(menu), SelIndex);
       +  gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu), menu);
       +  gtk_box_pack_start(GTK_BOX(hbox), optionmenu, TRUE, TRUE, 0);
       +
       +  DealDialog.DrugInd = DrugInd;
       +
       +  label = DealDialog.cost = gtk_label_new(NULL);
       +  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
       +  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
       +
       +  label = DealDialog.carrying = gtk_label_new(NULL);
       +  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       +
       +  label = DealDialog.space = gtk_label_new(NULL);
       +  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       +
       +  if (data == BT_BUY) {
       +    label = DealDialog.afford = gtk_label_new(NULL);
       +    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       +  }
       +  hbox = gtk_hbox_new(FALSE, 7);
       +  if (data == BT_BUY) {
       +    /* Prompts for action in the "deal drugs" dialog */
       +    g_string_sprintf(text, _("Buy how many?"));
       +  } else if (data == BT_SELL) {
       +    g_string_sprintf(text, _("Sell how many?"));
       +  } else {
       +    g_string_sprintf(text, _("Drop how many?"));
       +  }
       +  label = gtk_label_new(text->str);
       +  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
       +  spin_adj = (GtkAdjustment *)gtk_adjustment_new(1.0, 1.0, 2.0,
       +                                                 1.0, 10.0, 10.0);
       +  spinner = DealDialog.amount = gtk_spin_button_new(spin_adj, 1.0, 0);
       +  gtk_signal_connect(GTK_OBJECT(spinner), "activate",
       +                     GTK_SIGNAL_FUNC(DealOKCallback), data);
       +  gtk_box_pack_start(GTK_BOX(hbox), spinner, FALSE, FALSE, 0);
       +  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +
       +  hbbox = gtk_hbutton_box_new();
       +  button = gtk_button_new_with_label(_("OK"));
       +  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                     GTK_SIGNAL_FUNC(DealOKCallback), data);
       +  GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
       +  gtk_widget_grab_default(button);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +
       +  /* Caption of "Cancel" button for GTK+ client dialogs */
       +  button = gtk_button_new_with_label(_("Cancel"));
       +  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       +                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                            (gpointer)dialog);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
       +  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       +
       +  g_string_free(text, TRUE);
       +  UpdateDealDialog();
       +
       +  gtk_widget_show_all(dialog);
       +}
       +
       +void DealGuns(GtkWidget *widget, gpointer data)
       +{
       +  GtkWidget *clist, *dialog;
       +  GList *selection;
       +  gint row, GunInd;
       +  gchar *Action, *Title;
       +  GString *text;
       +
       +  dialog = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
       +  if (data == BT_BUY)
       +    Action = _("Buy");
       +  else if (data == BT_SELL)
       +    Action = _("Sell");
       +  else
       +    Action = _("Drop");
       +
       +  if (data == BT_BUY)
       +    clist = ClientData.Gun.HereList;
       +  else
       +    clist = ClientData.Gun.CarriedList;
       +  selection = GTK_CLIST(clist)->selection;
       +  if (selection) {
       +    row = GPOINTER_TO_INT(selection->data);
       +    GunInd =
       +        GPOINTER_TO_INT(gtk_clist_get_row_data(GTK_CLIST(clist), row));
       +  } else
       +    return;
       +
       +
       +  /* Title of 'gun shop' dialog (%tde="guns" by default) "Buy/Sell/Drop
       +   * Guns" */
       +  if (data == BT_BUY)
       +    Title = dpg_strdup_printf(_("Buy %tde"), Names.Guns);
       +  else if (data == BT_SELL)
       +    Title = dpg_strdup_printf(_("Sell %tde"), Names.Guns);
       +  else
       +    Title = dpg_strdup_printf(_("Drop %tde"), Names.Guns);
       +
       +  text = g_string_new("");
       +
       +  if (data != BT_BUY && TotalGunsCarried(ClientData.Play) == 0) {
       +    dpg_string_sprintf(text, _("You don't have any %tde to sell!"),
       +                       Names.Guns);
       +    GtkMessageBox(dialog, text->str, Title, MB_OK);
       +  } else if (data == BT_BUY && TotalGunsCarried(ClientData.Play) >=
       +             ClientData.Play->Bitches.Carried + 2) {
       +    dpg_string_sprintf(text,
       +                       _("You'll need more %tde to carry any more %tde!"),
       +                       Names.Bitches, Names.Guns);
       +    GtkMessageBox(dialog, text->str, Title, MB_OK);
       +  } else if (data == BT_BUY
       +             && Gun[GunInd].Space > ClientData.Play->CoatSize) {
       +    dpg_string_sprintf(text,
       +                       _("You don't have enough space to carry that %tde!"),
       +                       Names.Gun);
       +    GtkMessageBox(dialog, text->str, Title, MB_OK);
       +  } else if (data == BT_BUY && Gun[GunInd].Price > ClientData.Play->Cash) {
       +    dpg_string_sprintf(text,
       +                       _("You don't have enough cash to buy that %tde!"),
       +                       Names.Gun);
       +    GtkMessageBox(dialog, text->str, Title, MB_OK);
       +  } else if (data == BT_SELL && ClientData.Play->Guns[GunInd].Carried == 0) {
       +    GtkMessageBox(dialog, _("You don't have any to sell!"), Title, MB_OK);
       +  } else {
       +    g_string_sprintf(text, "gun^%d^%d", GunInd, data == BT_BUY ? 1 : -1);
       +    SendClientMessage(ClientData.Play, C_NONE, C_BUYOBJECT, NULL,
       +                      text->str);
       +  }
       +  g_free(Title);
       +  g_string_free(text, TRUE);
       +}
       +
       +static void QuestionCallback(GtkWidget *widget, gpointer data)
       +{
       +  gint Answer;
       +  gchar text[5];
       +  GtkWidget *dialog;
       +  Player *To;
       +
       +  dialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "dialog"));
       +  To = (Player *)gtk_object_get_data(GTK_OBJECT(dialog), "From");
       +  Answer = GPOINTER_TO_INT(data);
       +
       +  text[0] = (gchar)Answer;
       +  text[1] = '\0';
       +  SendClientMessage(ClientData.Play, C_NONE, C_ANSWER, To, text);
       +
       +  gtk_widget_destroy(dialog);
       +}
       +
       +void QuestionDialog(char *Data, Player *From)
       +{
       +  GtkWidget *dialog, *label, *vbox, *hsep, *hbbox, *button;
       +  GtkAccelGroup *accel_group;
       +  gchar *Responses, **split, *LabelText, *trword, *underline;
       +
       +  /* Button titles that correspond to the single-keypress options provided
       +   * by the curses client (e.g. _Yes corresponds to 'Y' etc.) */
       +  gchar *Words[] = { N_("_Yes"), N_("_No"), N_("_Run"),
       +    N_("_Fight"), N_("_Attack"), N_("_Evade")
       +  };
       +  gint numWords = sizeof(Words) / sizeof(Words[0]);
       +  gint i, j;
       +
       +  split = g_strsplit(Data, "^", 1);
       +  if (!split[0] || !split[1]) {
       +    g_warning("Bad QUESTION message %s", Data);
       +    return;
       +  }
       +
       +  g_strdelimit(split[1], "^", '\n');
       +
       +  Responses = split[0];
       +  LabelText = split[1];
       +
       +  dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       +  accel_group = gtk_accel_group_new();
       +  gtk_signal_connect(GTK_OBJECT(dialog), "delete_event",
       +                     GTK_SIGNAL_FUNC(DisallowDelete), NULL);
       +  gtk_object_set_data(GTK_OBJECT(dialog), "From", (gpointer)From);
       +
       +  /* Title of the 'ask player a question' dialog */
       +  gtk_window_set_title(GTK_WINDOW(dialog), _("Question"));
       +
       +  gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group);
       +  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       +  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       +                               GTK_WINDOW(ClientData.window));
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +  while (*LabelText == '\n')
       +    LabelText++;
       +  label = gtk_label_new(LabelText);
       +  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +
       +  hbbox = gtk_hbutton_box_new();
       +
       +  for (i = 0; i < strlen(Responses); i++) {
       +    for (j = 0, trword = NULL; j < numWords && !trword; j++) {
       +      underline = strchr(Words[j], '_');
       +      if (underline && toupper(underline[1]) == Responses[i]) {
       +        trword = _(Words[j]);
       +      }
       +    }
       +    button = gtk_button_new_with_label("");
       +    if (trword) {
       +      SetAccelerator(button, trword, button, "clicked", accel_group);
       +    } else {
       +      trword = g_strdup_printf("_%c", Responses[i]);
       +      SetAccelerator(button, trword, button, "clicked", accel_group);
       +      g_free(trword);
       +    }
       +    gtk_object_set_data(GTK_OBJECT(button), "dialog", (gpointer)dialog);
       +    gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                       GTK_SIGNAL_FUNC(QuestionCallback),
       +                       GINT_TO_POINTER((gint)Responses[i]));
       +    gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +  }
       +  gtk_box_pack_start(GTK_BOX(vbox), hbbox, TRUE, TRUE, 0);
       +  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       +  gtk_widget_show_all(dialog);
       +
       +  g_strfreev(split);
       +}
       +
       +void StartGame(void)
       +{
       +  Player *Play = ClientData.Play;
       +
       +  InitAbilities(Play);
       +  SendAbilities(Play);
       +  SendNullClientMessage(Play, C_NONE, C_NAME, NULL, GetPlayerName(Play));
       +  InGame = TRUE;
       +  UpdateMenus();
       +  gtk_widget_show_all(ClientData.vbox);
       +  UpdatePlayerLists();
       +}
       +
       +void EndGame(void)
       +{
       +  DisplayFightMessage(NULL);
       +  gtk_widget_hide_all(ClientData.vbox);
       +  gtk_editable_delete_text(GTK_EDITABLE(ClientData.messages), 0, -1);
       +  ShutdownNetwork(ClientData.Play);
       +  UpdatePlayerLists();
       +  CleanUpServer();
       +  RestoreConfig();
       +  InGame = FALSE;
       +  UpdateMenus();
       +}
       +
       +static void ChangeDrugSort(GtkCList *clist, gint column,
       +                           gpointer user_data)
       +{
       +  if (column == 0) {
       +    DrugSortMethod = (DrugSortMethod == DS_ATOZ ? DS_ZTOA : DS_ATOZ);
       +  } else {
       +    DrugSortMethod = (DrugSortMethod == DS_CHEAPFIRST ? DS_CHEAPLAST :
       +                      DS_CHEAPFIRST);
       +  }
       +  gtk_clist_sort(clist);
       +}
       +
       +static gint DrugSortFunc(GtkCList *clist, gconstpointer ptr1,
       +                         gconstpointer ptr2)
       +{
       +  int index1, index2;
       +  price_t pricediff;
       +
       +  index1 = GPOINTER_TO_INT(((const GtkCListRow *)ptr1)->data);
       +  index2 = GPOINTER_TO_INT(((const GtkCListRow *)ptr2)->data);
       +  if (index1 < 0 || index1 >= NumDrug || index2 < 0 || index2 >= NumDrug)
       +    return 0;
       +
       +  switch (DrugSortMethod) {
       +  case DS_ATOZ:
       +    return g_strcasecmp(Drug[index1].Name, Drug[index2].Name);
       +  case DS_ZTOA:
       +    return g_strcasecmp(Drug[index2].Name, Drug[index1].Name);
       +  case DS_CHEAPFIRST:
       +    pricediff = ClientData.Play->Drugs[index1].Price -
       +                ClientData.Play->Drugs[index2].Price;
       +    return pricediff == 0 ? 0 : pricediff < 0 ? -1 : 1;
       +  case DS_CHEAPLAST:
       +    pricediff = ClientData.Play->Drugs[index2].Price -
       +                ClientData.Play->Drugs[index1].Price;
       +    return pricediff == 0 ? 0 : pricediff < 0 ? -1 : 1;
       +  }
       +  return 0;
       +}
       +
       +void UpdateMenus(void)
       +{
       +  gboolean MultiPlayer;
       +  gint Bitches;
       +
       +  MultiPlayer = (FirstClient && FirstClient->next != NULL);
       +  Bitches = InGame
       +      && ClientData.Play ? ClientData.Play->Bitches.Carried : 0;
       +
       +  gtk_widget_set_sensitive(gtk_item_factory_get_widget(ClientData.Menu,
       +                                                       "<main>/Talk"),
       +                           InGame && Network);
       +  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       +                           (ClientData.Menu, "<main>/List"), InGame);
       +  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       +                           (ClientData.Menu, "<main>/List/Players..."),
       +                           InGame && Network);
       +  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       +                           (ClientData.Menu, "<main>/Errands"), InGame);
       +  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       +                           (ClientData.Menu, "<main>/Errands/Spy..."),
       +                           InGame && MultiPlayer);
       +  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       +                           (ClientData.Menu, "<main>/Errands/Tipoff..."),
       +                           InGame && MultiPlayer);
       +  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       +                           (ClientData.Menu,
       +                            "<main>/Errands/Sack Bitch..."), Bitches > 0);
       +  gtk_widget_set_sensitive(gtk_item_factory_get_widget
       +                           (ClientData.Menu,
       +                            "<main>/Errands/Get spy reports..."), InGame
       +                           && MultiPlayer);
       +}
       +
       +GtkWidget *CreateStatusWidgets(struct StatusWidgets *Status)
       +{
       +  GtkWidget *table, *label;
       +
       +  table = gtk_table_new(3, 6, FALSE);
       +  gtk_table_set_row_spacings(GTK_TABLE(table), 3);
       +  gtk_table_set_col_spacings(GTK_TABLE(table), 3);
       +
       +  label = Status->Location = gtk_label_new(NULL);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 2, 0, 1);
       +
       +  label = Status->Date = gtk_label_new(NULL);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 4, 0, 1);
       +
       +  /* Available space label in GTK+ client status display */
       +  label = Status->SpaceName = gtk_label_new(_("Space"));
       +
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 4, 5, 0, 1);
       +  label = Status->SpaceValue = gtk_label_new(NULL);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 0, 1);
       +
       +  /* Player's cash label in GTK+ client status display */
       +  label = Status->CashName = gtk_label_new(_("Cash"));
       +
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
       +  label = Status->CashValue = gtk_label_new(NULL);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 1, 2);
       +
       +  /* Player's debt label in GTK+ client status display */
       +  label = Status->DebtName = gtk_label_new(_("Debt"));
       +
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 1, 2);
       +  label = Status->DebtValue = gtk_label_new(NULL);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, 1, 2);
       +
       +  /* Player's bank balance label in GTK+ client status display */
       +  label = Status->BankName = gtk_label_new(_("Bank"));
       +
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 4, 5, 1, 2);
       +  label = Status->BankValue = gtk_label_new(NULL);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 1, 2);
       +
       +  label = Status->GunsName = gtk_label_new(NULL);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3);
       +  label = Status->GunsValue = gtk_label_new(NULL);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 2, 3);
       +
       +  label = Status->BitchesName = gtk_label_new(NULL);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 2, 3);
       +  label = Status->BitchesValue = gtk_label_new(NULL);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, 2, 3);
       +
       +  /* Player's health label in GTK+ client status display */
       +  label = Status->HealthName = gtk_label_new(_("Health"));
       +
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 4, 5, 2, 3);
       +  label = Status->HealthValue = gtk_label_new(NULL);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 2, 3);
       +  return table;
       +}
       +
       +void SetJetButtonTitle(GtkAccelGroup *accel_group)
       +{
       +  GtkWidget *button;
       +  guint accel_key;
       +
       +  button = ClientData.JetButton;
       +  accel_key = ClientData.JetAccel;
       +
       +  if (accel_key) {
       +    gtk_widget_remove_accelerator(button, accel_group, accel_key, 0);
       +  }
       +
       +  ClientData.JetAccel = SetAccelerator(button,
       +                                       (ClientData.Play
       +                                        && ClientData.Play->
       +                                        Flags & FIGHTING) ? _("_Fight") :
       +                                       /* Caption of 'Jet' button in main
       +                                        * window */
       +                                       _("_Jet!"), button, "clicked",
       +                                       accel_group);
       +}
       +
       +static void SetIcon(GtkWidget *window, gchar **xpmdata)
       +{
       +#ifndef CYGWIN
       +  GdkBitmap *mask;
       +  GdkPixmap *icon;
       +  GtkStyle *style;
       +
       +  style = gtk_widget_get_style(window);
       +  icon = gdk_pixmap_create_from_xpm_d(window->window, &mask,
       +                                      &style->bg[GTK_STATE_NORMAL],
       +                                      xpmdata);
       +  gdk_window_set_icon(window->window, NULL, icon, mask);
       +#endif
       +}
       +
       +#ifdef CYGWIN
       +gboolean GtkLoop(HINSTANCE hInstance, HINSTANCE hPrevInstance,
       +                 gboolean ReturnOnFail)
       +{
       +#else
       +gboolean GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail)
       +{
       +#endif
       +  GtkWidget *window, *vbox, *vbox2, *hbox, *frame, *table, *menubar, *text,
       +      *vpaned, *button, *clist;
       +  GtkAccelGroup *accel_group;
       +  GtkItemFactory *item_factory;
       +  GtkAdjustment *adj;
       +  gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
       +
       +#ifdef CYGWIN
       +  win32_init(hInstance, hPrevInstance, "mainicon");
       +#else
       +  gtk_set_locale();
       +  if (ReturnOnFail && !gtk_init_check(argc, argv))
       +    return FALSE;
       +  else if (!ReturnOnFail)
       +    gtk_init(argc, argv);
       +#endif
       +
       +  /* Set up message handlers */
       +  ClientMessageHandlerPt = HandleClientMessage;
       +
       +  /* Have the GLib log messages pop up in a nice dialog box */
       +  g_log_set_handler(NULL,
       +                    LogMask() | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING |
       +                    G_LOG_LEVEL_CRITICAL, LogMessage, NULL);
       +
       +  if (!CheckHighScoreFileConfig())
       +    return TRUE;
       +
       +  /* Create the main player */
       +  ClientData.Play = g_new(Player, 1);
       +  FirstClient = AddPlayer(0, ClientData.Play, FirstClient);
       +
       +  window = MainWindow = ClientData.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
       +
       +  /* Title of main window in GTK+ client */
       +  gtk_window_set_title(GTK_WINDOW(window), _("dopewars"));
       +  gtk_window_set_default_size(GTK_WINDOW(window), 450, 390);
       +  gtk_signal_connect(GTK_OBJECT(window), "delete_event",
       +                     GTK_SIGNAL_FUNC(MainDelete), NULL);
       +  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       +                     GTK_SIGNAL_FUNC(DestroyGtk), NULL);
       +
       +  accel_group = gtk_accel_group_new();
       +  gtk_object_set_data(GTK_OBJECT(window), "accel_group", accel_group);
       +  item_factory = ClientData.Menu = gtk_item_factory_new(GTK_TYPE_MENU_BAR,
       +                                                        "<main>",
       +                                                        accel_group);
       +  gtk_item_factory_set_translate_func(item_factory, MenuTranslate, NULL,
       +                                      NULL);
       +
       +  gtk_item_factory_create_items(item_factory, nmenu_items, menu_items,
       +                                NULL);
       +  gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
       +  menubar = gtk_item_factory_get_widget(item_factory, "<main>");
       +
       +  vbox2 = gtk_vbox_new(FALSE, 0);
       +  gtk_box_pack_start(GTK_BOX(vbox2), menubar, FALSE, FALSE, 0);
       +  gtk_widget_show_all(menubar);
       +  UpdateMenus();
       +
       +  vbox = ClientData.vbox = gtk_vbox_new(FALSE, 5);
       +  frame = gtk_frame_new(_("Stats"));
       +
       +  table = CreateStatusWidgets(&ClientData.Status);
       +
       +  gtk_container_add(GTK_CONTAINER(frame), table);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
       +
       +  vpaned = gtk_vpaned_new();
       +
       +  adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 100.0,
       +                                            1.0, 10.0, 10.0);
       +  text = ClientData.messages = gtk_scrolled_text_new(NULL, adj, &hbox);
       +  gtk_widget_set_usize(text, 100, 80);
       +  gtk_text_set_point(GTK_TEXT(text), 0);
       +  gtk_text_set_editable(GTK_TEXT(text), FALSE);
       +  gtk_text_set_word_wrap(GTK_TEXT(text), TRUE);
       +  gtk_paned_pack1(GTK_PANED(vpaned), hbox, TRUE, TRUE);
       +
       +  hbox = gtk_hbox_new(FALSE, 7);
       +  CreateInventory(hbox, Names.Drugs, accel_group, TRUE, TRUE,
       +                  &ClientData.Drug, DealDrugs);
       +  clist = ClientData.Drug.HereList;
       +  gtk_clist_column_titles_active(GTK_CLIST(clist));
       +  gtk_clist_set_compare_func(GTK_CLIST(clist), DrugSortFunc);
       +  gtk_signal_connect(GTK_OBJECT(clist), "click-column",
       +                     GTK_SIGNAL_FUNC(ChangeDrugSort), NULL);
       +
       +  button = ClientData.JetButton = gtk_button_new_with_label("");
       +  ClientData.JetAccel = 0;
       +  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                     GTK_SIGNAL_FUNC(JetButtonPressed), NULL);
       +  gtk_box_pack_start(GTK_BOX(ClientData.Drug.vbbox), button, TRUE, TRUE, 0);
       +  SetJetButtonTitle(accel_group);
       +
       +  gtk_paned_pack2(GTK_PANED(vpaned), hbox, TRUE, TRUE);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), vpaned, TRUE, TRUE, 0);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox2), vbox, TRUE, TRUE, 0);
       +  gtk_container_add(GTK_CONTAINER(window), vbox2);
       +
       +  /* Just show the window, not the vbox - we'll do that when the game
       +   * starts */
       +  gtk_widget_show(vbox2);
       +  gtk_widget_show(window);
       +
       +  gtk_widget_realize(window);
       +
       +  SetIcon(window, dopewars_pill_xpm);
       +
       +  gtk_main();
       +
       +  /* Free the main player */
       +  FirstClient = RemovePlayer(ClientData.Play, FirstClient);
       +
       +  return TRUE;
       +}
       +
       +static void PackCentredURL(GtkWidget *vbox, gchar *title, gchar *target,
       +                           gchar *browser)
       +{
       +  GtkWidget *hbox, *label, *url;
       +
       +  /* There must surely be a nicer way of making the URL centred - but I
       +   * can't think of one... */
       +  hbox = gtk_hbox_new(FALSE, 0);
       +  label = gtk_label_new("");
       +  gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
       +
       +  url = gtk_url_new(title, target, browser);
       +  gtk_box_pack_start(GTK_BOX(hbox), url, FALSE, FALSE, 0);
       +    
       +  label = gtk_label_new("");
       +  gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, FALSE, 0);
       +  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
       +}
       +
       +void display_intro(GtkWidget *widget, gpointer data)
       +{
       +  GtkWidget *dialog, *label, *table, *OKButton, *vbox, *hsep;
       +  gchar *VersionStr, *docindex;
       +  const int rows = 6, cols = 3;
       +  int i, j;
       +  gchar *table_data[6][3] = {
       +    /* Credits labels in GTK+ 'about' dialog */
       +    {N_("Icons and graphics"), "Ocelot Mantis", NULL},
       +    {N_("Drug Dealing and Research"), "Dan Wolf", NULL},
       +    {N_("Play Testing"), "Phil Davis", "Owen Walsh"},
       +    {N_("Extensive Play Testing"), "Katherine Holt",
       +     "Caroline Moore"},
       +    {N_("Constructive Criticism"), "Andrea Elliot-Smith",
       +     "Pete Winn"},
       +    {N_("Unconstructive Criticism"), "James Matthews", NULL}
       +  };
       +
       +  dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       +
       +  /* Title of GTK+ 'about' dialog */
       +  gtk_window_set_title(GTK_WINDOW(dialog), _("About dopewars"));
       +
       +  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       +                               GTK_WINDOW(ClientData.window));
       +  gtk_container_border_width(GTK_CONTAINER(dialog), 10);
       +
       +  vbox = gtk_vbox_new(FALSE, 5);
       +
       +  /* Main content of GTK+ 'about' dialog */
       +  label = gtk_label_new(_("Based on John E. Dell's old Drug Wars game, "
       +                          "dopewars is a simulation of an\nimaginary drug "
       +                          "market.  dopewars is an All-American game which "
       +                          "features\nbuying, selling, and trying to get "
       +                          "past the cops!\n\nThe first thing you need to "
       +                          "do is pay off your debt to the Loan Shark. "
       +                          "After\nthat, your goal is to make as much "
       +                          "money as possible (and stay alive)! You\n"
       +                          "have one month of game time to make "
       +                          "your fortune.\n"));
       +  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       +
       +  /* Version and copyright notice in GTK+ 'about' dialog */
       +  VersionStr = g_strdup_printf(_("Version %s     "
       +                                 "Copyright (C) 1998-2002  "
       +                                 "Ben Webb ben@bellatrix.pcl.ox.ac.uk\n"
       +                                 "dopewars is released under the "
       +                                 "GNU General Public Licence\n"), VERSION);
       +  label = gtk_label_new(VersionStr);
       +  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       +  g_free(VersionStr);
       +
       +  table = gtk_table_new(rows, cols, FALSE);
       +  gtk_table_set_row_spacings(GTK_TABLE(table), 3);
       +  gtk_table_set_col_spacings(GTK_TABLE(table), 3);
       +  for (i = 0; i < rows; i++)
       +    for (j = 0; j < cols; j++)
       +      if (table_data[i][j]) {
       +        if (j == 0)
       +          label = gtk_label_new(_(table_data[i][j]));
       +        else
       +          label = gtk_label_new(table_data[i][j]);
       +        gtk_table_attach_defaults(GTK_TABLE(table), label, j, j + 1, i,
       +                                  i + 1);
       +      }
       +  gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
       +
       +  /* Label at the bottom of GTK+ 'about' dialog */
       +  label = gtk_label_new(_("\nFor information on the command line "
       +                          "options, type dopewars -h at your\n"
       +                          "Unix prompt. This will display a help "
       +                          "screen, listing the available options.\n"));
       +  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       +
       +  docindex = GetDocIndex();
       +  PackCentredURL(vbox, "Local HTML documentation", docindex, WebBrowser);
       +  g_free(docindex);
       +
       +  PackCentredURL(vbox, "http://dopewars.sourceforge.net/",
       +                 "http://dopewars.sourceforge.net/", WebBrowser);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +
       +  OKButton = gtk_button_new_with_label(_("OK"));
       +  gtk_signal_connect_object(GTK_OBJECT(OKButton), "clicked",
       +                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                            (gpointer)dialog);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), OKButton, FALSE, FALSE, 0);
       +  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       +
       +  GTK_WIDGET_SET_FLAGS(OKButton, GTK_CAN_DEFAULT);
       +  gtk_widget_grab_default(OKButton);
       +
       +  gtk_widget_show_all(dialog);
       +}
       +
       +static gboolean GetStartGamePlayerName(struct StartGameStruct *widgets,
       +                                       gchar **PlayerName)
       +{
       +  g_free(*PlayerName);
       +  *PlayerName = gtk_editable_get_chars(GTK_EDITABLE(widgets->name), 0, -1);
       +  if (*PlayerName && (*PlayerName)[0])
       +    return TRUE;
       +  else {
       +    GtkMessageBox(widgets->dialog,
       +                  _("You can't start the game without giving a name first!"),
       +                  _("New Game"), MB_OK);
       +    return FALSE;
       +  }
       +}
       +
       +static void SetStartGameStatus(struct StartGameStruct *widgets, gchar *msg)
       +{
       +  gtk_label_set_text(GTK_LABEL(widgets->status),
       +                     msg ? msg : _("Status: Waiting for user input"));
       +}
       +
       +#ifdef NETWORKING
       +static void ConnectError(struct StartGameStruct *widgets, gboolean meta)
       +{
       +  GString *neterr;
       +  gchar *text;
       +  LastError *error;
       +
       +  if (meta)
       +    error = widgets->MetaConn->NetBuf.error;
       +  else
       +    error = ClientData.Play->NetBuf.error;
       +
       +  neterr = g_string_new("");
       +
       +  if (error) {
       +    g_string_assign_error(neterr, error);
       +  } else {
       +    g_string_assign(neterr, _("Connection closed by remote host"));
       +  }
       +
       +  if (meta) {
       +    /* Error: GTK+ client could not connect to the metaserver */
       +    text =
       +        g_strdup_printf(_("Status: Could not connect to metaserver (%s)"),
       +                        neterr->str);
       +  } else {
       +    /* Error: GTK+ client could not connect to the given dopewars server */
       +    text =
       +        g_strdup_printf(_("Status: Could not connect (%s)"), neterr->str);
       +  }
       +
       +  SetStartGameStatus(widgets, text);
       +  g_free(text);
       +  g_string_free(neterr, TRUE);
       +}
       +
       +void FinishServerConnect(struct StartGameStruct *widgets,
       +                         gboolean ConnectOK)
       +{
       +  if (ConnectOK) {
       +    Client = Network = TRUE;
       +    gtk_widget_destroy(widgets->dialog);
       +    StartGame();
       +  } else {
       +    ConnectError(widgets, FALSE);
       +  }
       +}
       +
       +static void DoConnect(struct StartGameStruct *widgets)
       +{
       +  gchar *text;
       +  NetworkBuffer *NetBuf;
       +  NBStatus oldstatus;
       +  NBSocksStatus oldsocks;
       +
       +  NetBuf = &ClientData.Play->NetBuf;
       +
       +  /* Message displayed during the attempted connect to a dopewars server */
       +  text = g_strdup_printf(_("Status: Attempting to contact %s..."),
       +                         ServerName);
       +  SetStartGameStatus(widgets, text);
       +  g_free(text);
       +
       +  /* Terminate any existing connection attempts */
       +  ShutdownNetworkBuffer(NetBuf);
       +  if (widgets->MetaConn) {
       +    CloseHttpConnection(widgets->MetaConn);
       +    widgets->MetaConn = NULL;
       +  }
       +
       +  oldstatus = NetBuf->status;
       +  oldsocks = NetBuf->sockstat;
       +  if (StartNetworkBufferConnect(NetBuf, ServerName, Port)) {
       +    DisplayConnectStatus(widgets, FALSE, oldstatus, oldsocks);
       +    SetNetworkBufferUserPasswdFunc(NetBuf, SocksAuthDialog, NULL);
       +    SetNetworkBufferCallBack(NetBuf, SocketStatus, (gpointer)widgets);
       +  } else {
       +    ConnectError(widgets, FALSE);
       +  }
       +}
       +
       +static void ConnectToServer(GtkWidget *widget,
       +                            struct StartGameStruct *widgets)
       +{
       +  gchar *text;
       +
       +  g_free(ServerName);
       +  ServerName = gtk_editable_get_chars(GTK_EDITABLE(widgets->hostname),
       +                                      0, -1);
       +  text = gtk_editable_get_chars(GTK_EDITABLE(widgets->port), 0, -1);
       +  Port = atoi(text);
       +  g_free(text);
       +
       +  if (!GetStartGamePlayerName(widgets, &ClientData.Play->Name))
       +    return;
       +  DoConnect(widgets);
       +}
       +
       +static void FillMetaServerList(struct StartGameStruct *widgets,
       +                               gboolean UseNewList)
       +{
       +  GtkWidget *metaserv;
       +  ServerData *ThisServer;
       +  gchar *titles[5];
       +  GSList *ListPt;
       +  gint row;
       +
       +  if (UseNewList && !widgets->NewMetaList)
       +    return;
       +
       +  metaserv = widgets->metaserv;
       +  gtk_clist_freeze(GTK_CLIST(metaserv));
       +  gtk_clist_clear(GTK_CLIST(metaserv));
       +
       +  if (UseNewList) {
       +    ClearServerList(&MetaList);
       +    MetaList = widgets->NewMetaList;
       +    widgets->NewMetaList = NULL;
       +  }
       +
       +  for (ListPt = MetaList; ListPt; ListPt = g_slist_next(ListPt)) {
       +    ThisServer = (ServerData *)(ListPt->data);
       +    titles[0] = ThisServer->Name;
       +    titles[1] = g_strdup_printf("%d", ThisServer->Port);
       +    titles[2] = ThisServer->Version;
       +    if (ThisServer->CurPlayers == -1) {
       +      /* Displayed if we don't know how many players are logged on to a
       +       * server */
       +      titles[3] = _("Unknown");
       +    } else {
       +      /* e.g. "5 of 20" means 5 players are logged on to a server, out of
       +       * a maximum of 20 */
       +      titles[3] = g_strdup_printf(_("%d of %d"), ThisServer->CurPlayers,
       +                                  ThisServer->MaxPlayers);
       +    }
       +    titles[4] = ThisServer->Comment;
       +    row = gtk_clist_append(GTK_CLIST(metaserv), titles);
       +    gtk_clist_set_row_data(GTK_CLIST(metaserv), row, (gpointer)ThisServer);
       +    g_free(titles[1]);
       +    if (ThisServer->CurPlayers != -1)
       +      g_free(titles[3]);
       +  }
       +  gtk_clist_thaw(GTK_CLIST(metaserv));
       +}
       +
       +void DisplayConnectStatus(struct StartGameStruct *widgets, gboolean meta,
       +                          NBStatus oldstatus, NBSocksStatus oldsocks)
       +{
       +  NBStatus status;
       +  NBSocksStatus sockstat;
       +  gchar *text;
       +
       +  if (meta) {
       +    status = widgets->MetaConn->NetBuf.status;
       +    sockstat = widgets->MetaConn->NetBuf.sockstat;
       +  } else {
       +    status = ClientData.Play->NetBuf.status;
       +    sockstat = ClientData.Play->NetBuf.sockstat;
       +  }
       +  if (oldstatus == status && sockstat == oldsocks)
       +    return;
       +
       +  switch (status) {
       +  case NBS_PRECONNECT:
       +    break;
       +  case NBS_SOCKSCONNECT:
       +    switch (sockstat) {
       +    case NBSS_METHODS:
       +      text = g_strdup_printf(_("Status: Connected to SOCKS server %s..."),
       +                             Socks.name);
       +      SetStartGameStatus(widgets, text);
       +      g_free(text);
       +      break;
       +    case NBSS_USERPASSWD:
       +      SetStartGameStatus(widgets,
       +                         _("Status: Authenticating with SOCKS server"));
       +      break;
       +    case NBSS_CONNECT:
       +      text =
       +          g_strdup_printf(_("Status: Asking SOCKS for connect to %s..."),
       +                          meta ? MetaServer.Name : ServerName);
       +      SetStartGameStatus(widgets, text);
       +      g_free(text);
       +      break;
       +    }
       +    break;
       +  case NBS_CONNECTED:
       +    if (meta) {
       +      SetStartGameStatus(widgets,
       +                         _("Status: Obtaining server information "
       +                           "from metaserver..."));
       +    }
       +    break;
       +  }
       +}
       +
       +static void MetaDone(struct StartGameStruct *widgets)
       +{
       +  if (IsHttpError(widgets->MetaConn)) {
       +    ConnectError(widgets, TRUE);
       +  } else {
       +    SetStartGameStatus(widgets, NULL);
       +  }
       +  CloseHttpConnection(widgets->MetaConn);
       +  widgets->MetaConn = NULL;
       +  FillMetaServerList(widgets, TRUE);
       +}
       +
       +static void HandleMetaSock(gpointer data, gint socket,
       +                           GdkInputCondition condition)
       +{
       +  struct StartGameStruct *widgets;
       +  gboolean DoneOK;
       +  NBStatus oldstatus;
       +  NBSocksStatus oldsocks;
       +
       +  widgets = (struct StartGameStruct *)data;
       +  if (!widgets->MetaConn)
       +    return;
       +
       +  oldstatus = widgets->MetaConn->NetBuf.status;
       +  oldsocks = widgets->MetaConn->NetBuf.sockstat;
       +
       +  if (NetBufHandleNetwork
       +      (&widgets->MetaConn->NetBuf, condition & GDK_INPUT_READ,
       +       condition & GDK_INPUT_WRITE, &DoneOK)) {
       +    while (HandleWaitingMetaServerData
       +           (widgets->MetaConn, &widgets->NewMetaList, &DoneOK)) {
       +    }
       +  }
       +
       +  if (!DoneOK && HandleHttpCompletion(widgets->MetaConn)) {
       +    MetaDone(widgets);
       +  } else {
       +    DisplayConnectStatus(widgets, TRUE, oldstatus, oldsocks);
       +  }
       +}
       +
       +void MetaSocketStatus(NetworkBuffer *NetBuf, gboolean Read, gboolean Write,
       +                      gboolean CallNow)
       +{
       +  if (NetBuf->InputTag)
       +    gdk_input_remove(NetBuf->InputTag);
       +  NetBuf->InputTag = 0;
       +  if (Read || Write) {
       +    NetBuf->InputTag = gdk_input_add(NetBuf->fd,
       +                                     (Read ? GDK_INPUT_READ : 0) |
       +                                     (Write ? GDK_INPUT_WRITE : 0),
       +                                     HandleMetaSock, NetBuf->CallBackData);
       +  }
       +  if (CallNow)
       +    HandleMetaSock(NetBuf->CallBackData, NetBuf->fd, 0);
       +}
       +
       +static void UpdateMetaServerList(GtkWidget *widget,
       +                                 struct StartGameStruct *widgets)
       +{
       +  GtkWidget *metaserv;
       +  gchar *text;
       +
       +  /* Terminate any existing connection attempts */
       +  ShutdownNetworkBuffer(&ClientData.Play->NetBuf);
       +  if (widgets->MetaConn) {
       +    CloseHttpConnection(widgets->MetaConn);
       +    widgets->MetaConn = NULL;
       +  }
       +
       +  ClearServerList(&widgets->NewMetaList);
       +
       +  /* Message displayed during the attempted connect to the metaserver */
       +  text = g_strdup_printf(_("Status: Attempting to contact %s..."),
       +                         MetaServer.Name);
       +  SetStartGameStatus(widgets, text);
       +  g_free(text);
       +
       +  if (OpenMetaHttpConnection(&widgets->MetaConn)) {
       +    metaserv = widgets->metaserv;
       +    SetHttpAuthFunc(widgets->MetaConn, AuthDialog, NULL);
       +    SetNetworkBufferUserPasswdFunc(&widgets->MetaConn->NetBuf,
       +                                   MetaSocksAuthDialog, NULL);
       +    SetNetworkBufferCallBack(&widgets->MetaConn->NetBuf,
       +                             MetaSocketStatus, (gpointer)widgets);
       +  } else {
       +    ConnectError(widgets, TRUE);
       +    CloseHttpConnection(widgets->MetaConn);
       +    widgets->MetaConn = NULL;
       +  }
       +}
       +
       +static void MetaServerConnect(GtkWidget *widget,
       +                              struct StartGameStruct *widgets)
       +{
       +  GList *selection;
       +  gint row;
       +  GtkWidget *clist;
       +  ServerData *ThisServer;
       +
       +  clist = widgets->metaserv;
       +  selection = GTK_CLIST(clist)->selection;
       +  if (selection) {
       +    row = GPOINTER_TO_INT(selection->data);
       +    ThisServer = (ServerData *)gtk_clist_get_row_data(GTK_CLIST(clist), row);
       +    AssignName(&ServerName, ThisServer->Name);
       +    Port = ThisServer->Port;
       +
       +    if (!GetStartGamePlayerName(widgets, &ClientData.Play->Name))
       +      return;
       +    DoConnect(widgets);
       +  }
       +}
       +#endif /* NETWORKING */
       +
       +static void StartSinglePlayer(GtkWidget *widget,
       +                              struct StartGameStruct *widgets)
       +{
       +  WantAntique =
       +      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widgets->antique));
       +  if (!GetStartGamePlayerName(widgets, &ClientData.Play->Name))
       +    return;
       +  StartGame();
       +  gtk_widget_destroy(widgets->dialog);
       +}
       +
       +static void CloseNewGameDia(GtkWidget *widget,
       +                            struct StartGameStruct *widgets)
       +{
       +#ifdef NETWORKING
       +  /* Terminate any existing connection attempts */
       +  if (ClientData.Play->NetBuf.status != NBS_CONNECTED) {
       +    ShutdownNetworkBuffer(&ClientData.Play->NetBuf);
       +  }
       +  if (widgets->MetaConn) {
       +    CloseHttpConnection(widgets->MetaConn);
       +    widgets->MetaConn = NULL;
       +  }
       +  ClearServerList(&widgets->NewMetaList);
       +#endif
       +}
       +
       +void NewGameDialog(void)
       +{
       +  GtkWidget *vbox, *vbox2, *hbox, *label, *entry, *notebook;
       +  GtkWidget *frame, *button, *dialog;
       +  GtkAccelGroup *accel_group;
       +  static struct StartGameStruct widgets;
       +  guint AccelKey;
       +
       +#ifdef NETWORKING
       +  GtkWidget *clist, *scrollwin, *table, *hbbox;
       +  gchar *server_titles[5], *ServerEntry, *text;
       +  gboolean UpdateMeta = FALSE;
       +
       +  /* Column titles of metaserver information */
       +  server_titles[0] = _("Server");
       +  server_titles[1] = _("Port");
       +  server_titles[2] = _("Version");
       +  server_titles[3] = _("Players");
       +  server_titles[4] = _("Comment");
       +
       +  widgets.MetaConn = NULL;
       +  widgets.NewMetaList = NULL;
       +
       +#endif /* NETWORKING */
       +
       +  widgets.dialog = dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       +  gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
       +                     GTK_SIGNAL_FUNC(CloseNewGameDia), (gpointer)&widgets);
       +
       +  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       +                               GTK_WINDOW(ClientData.window));
       +#ifdef NETWORKING
       +  gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
       +#endif
       +  accel_group = gtk_accel_group_new();
       +
       +  /* Title of 'New Game' dialog */
       +  gtk_window_set_title(GTK_WINDOW(widgets.dialog), _("New Game"));
       +  gtk_container_set_border_width(GTK_CONTAINER(widgets.dialog), 7);
       +  gtk_window_add_accel_group(GTK_WINDOW(widgets.dialog), accel_group);
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +  hbox = gtk_hbox_new(FALSE, 7);
       +
       +  label = gtk_label_new("");
       +
       +  AccelKey = gtk_label_parse_uline(GTK_LABEL(label),
       +                                   /* Prompt for player's name in 'New
       +                                    * Game' dialog */
       +                                   _("Hey dude, what's your _name?"));
       +  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
       +
       +  entry = widgets.name = gtk_entry_new();
       +  gtk_widget_add_accelerator(entry, "grab-focus", accel_group, AccelKey, 0,
       +                             GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE);
       +  gtk_entry_set_text(GTK_ENTRY(entry), GetPlayerName(ClientData.Play));
       +  gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
       +
       +  notebook = gtk_notebook_new();
       +
       +#ifdef NETWORKING
       +  frame = gtk_frame_new(_("Server"));
       +  gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
       +  vbox2 = gtk_vbox_new(FALSE, 7);
       +  gtk_container_set_border_width(GTK_CONTAINER(vbox2), 4);
       +  table = gtk_table_new(2, 2, FALSE);
       +  gtk_table_set_row_spacings(GTK_TABLE(table), 4);
       +  gtk_table_set_col_spacings(GTK_TABLE(table), 4);
       +
       +  /* Prompt for hostname to connect to in GTK+ new game dialog */
       +  label = gtk_label_new(_("Host name"));
       +
       +  gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
       +                   GTK_SHRINK, GTK_SHRINK, 0, 0);
       +  entry = widgets.hostname = gtk_entry_new();
       +
       +  ServerEntry = "localhost";
       +  if (g_strcasecmp(ServerName, SN_META) == 0) {
       +    NewGameType = 2;
       +    UpdateMeta = TRUE;
       +  } else if (g_strcasecmp(ServerName, SN_PROMPT) == 0)
       +    NewGameType = 0;
       +  else if (g_strcasecmp(ServerName, SN_SINGLE) == 0)
       +    NewGameType = 1;
       +  else
       +    ServerEntry = ServerName;
       +
       +  gtk_entry_set_text(GTK_ENTRY(entry), ServerEntry);
       +  gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 0, 1,
       +                   GTK_EXPAND | GTK_SHRINK | GTK_FILL,
       +                   GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
       +  label = gtk_label_new(_("Port"));
       +  gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
       +                   GTK_SHRINK, GTK_SHRINK, 0, 0);
       +  entry = widgets.port = gtk_entry_new();
       +  text = g_strdup_printf("%d", Port);
       +  gtk_entry_set_text(GTK_ENTRY(entry), text);
       +  g_free(text);
       +  gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 1, 2,
       +                   GTK_EXPAND | GTK_SHRINK | GTK_FILL,
       +                   GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox2), table, FALSE, FALSE, 0);
       +
       +  button = gtk_button_new_with_label("");
       +  /* Button to connect to a named dopewars server */
       +  SetAccelerator(button, _("_Connect"), button, "clicked", accel_group);
       +  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                     GTK_SIGNAL_FUNC(ConnectToServer), (gpointer)&widgets);
       +  gtk_box_pack_start(GTK_BOX(vbox2), button, FALSE, FALSE, 0);
       +  gtk_container_add(GTK_CONTAINER(frame), vbox2);
       +  GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
       +  gtk_widget_grab_default(button);
       +
       +  label = gtk_label_new(_("Server"));
       +  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
       +#endif /* NETWORKING */
       +
       +  /* Title of 'New Game' dialog notebook tab for single-player mode */
       +  frame = gtk_frame_new(_("Single player"));
       +  gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
       +  vbox2 = gtk_vbox_new(FALSE, 7);
       +  gtk_container_set_border_width(GTK_CONTAINER(vbox2), 4);
       +  widgets.antique = gtk_check_button_new_with_label("");
       +
       +  /* Checkbox to activate 'antique mode' in single-player games */
       +  SetAccelerator(widgets.antique, _("_Antique mode"), widgets.antique,
       +                 "clicked", accel_group);
       +  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widgets.antique),
       +                               WantAntique);
       +  gtk_box_pack_start(GTK_BOX(vbox2), widgets.antique, FALSE, FALSE, 0);
       +  button = gtk_button_new_with_label("");
       +
       +  /* Button to start a new single-player (standalone, non-network) game */
       +  SetAccelerator(button, _("_Start single-player game"), button,
       +                 "clicked", accel_group);
       +
       +  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                     GTK_SIGNAL_FUNC(StartSinglePlayer),
       +                     (gpointer)&widgets);
       +  gtk_box_pack_start(GTK_BOX(vbox2), button, FALSE, FALSE, 0);
       +  gtk_container_add(GTK_CONTAINER(frame), vbox2);
       +  label = gtk_label_new(_("Single player"));
       +  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
       +
       +#ifdef NETWORKING
       +  /* Title of Metaserver frame in New Game dialog */
       +  frame = gtk_frame_new(_("Metaserver"));
       +  gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
       +
       +  vbox2 = gtk_vbox_new(FALSE, 7);
       +  gtk_container_set_border_width(GTK_CONTAINER(vbox2), 4);
       +
       +  clist = widgets.metaserv =
       +      gtk_scrolled_clist_new_with_titles(5, server_titles, &scrollwin);
       +  gtk_clist_column_titles_passive(GTK_CLIST(clist));
       +  gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_SINGLE);
       +  gtk_clist_set_column_width(GTK_CLIST(clist), 0, 130);
       +  gtk_clist_set_column_width(GTK_CLIST(clist), 1, 35);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox2), scrollwin, TRUE, TRUE, 0);
       +
       +  hbbox = gtk_hbutton_box_new();
       +  button = gtk_button_new_with_label("");
       +
       +  /* Button to update metaserver information */
       +  SetAccelerator(button, _("_Update"), button, "clicked", accel_group);
       +  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                     GTK_SIGNAL_FUNC(UpdateMetaServerList),
       +                     (gpointer)&widgets);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +
       +  button = gtk_button_new_with_label("");
       +  SetAccelerator(button, _("_Connect"), button, "clicked", accel_group);
       +  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                     GTK_SIGNAL_FUNC(MetaServerConnect),
       +                     (gpointer)&widgets);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox2), hbbox, FALSE, FALSE, 0);
       +  gtk_container_add(GTK_CONTAINER(frame), vbox2);
       +
       +  label = gtk_label_new(_("Metaserver"));
       +  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
       +#endif /* NETWORKING */
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
       +
       +  /* Caption of status label in New Game dialog before anything has
       +   * happened */
       +  label = widgets.status = gtk_label_new("");
       +  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       +
       +  gtk_container_add(GTK_CONTAINER(widgets.dialog), vbox);
       +
       +  gtk_widget_grab_focus(widgets.name);
       +#ifdef NETWORKING
       +  if (UpdateMeta) {
       +    UpdateMetaServerList(NULL, &widgets);
       +  } else {
       +    FillMetaServerList(&widgets, FALSE);
       +  }
       +#endif
       +
       +  SetStartGameStatus(&widgets, NULL);
       +  gtk_widget_show_all(widgets.dialog);
       +  gtk_notebook_set_page(GTK_NOTEBOOK(notebook), NewGameType);
       +}
       +
       +static void SendDoneMessage(GtkWidget *widget, gpointer data)
       +{
       +  SendClientMessage(ClientData.Play, C_NONE, C_DONE, NULL, NULL);
       +}
       +
       +static void TransferPayAll(GtkWidget *widget, GtkWidget *dialog)
       +{
       +  gchar *text;
       +
       +  text = pricetostr(ClientData.Play->Debt);
       +  SendClientMessage(ClientData.Play, C_NONE, C_PAYLOAN, NULL, text);
       +  g_free(text);
       +  gtk_widget_destroy(dialog);
       +}
       +
       +static void TransferOK(GtkWidget *widget, GtkWidget *dialog)
       +{
       +  gpointer Debt;
       +  GtkWidget *deposit, *entry;
       +  gchar *text, *title;
       +  price_t money;
       +  gboolean withdraw = FALSE;
       +
       +  Debt = gtk_object_get_data(GTK_OBJECT(dialog), "debt");
       +  entry = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(dialog), "entry"));
       +  text = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
       +  money = strtoprice(text);
       +  g_free(text);
       +
       +  if (Debt) {
       +    /* Title of loan shark dialog - (%Tde="The Loan Shark" by default) */
       +    title = dpg_strdup_printf(_("%/LoanShark window title/%Tde"),
       +                              Names.LoanSharkName);
       +    if (money > ClientData.Play->Debt)
       +      money = ClientData.Play->Debt;
       +  } else {
       +    /* Title of bank dialog - (%Tde="The Bank" by default) */
       +    title = dpg_strdup_printf(_("%/BankName window title/%Tde"),
       +                              Names.BankName);
       +    deposit = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(dialog), "deposit"));
       +    if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(deposit))) {
       +      withdraw = TRUE;
       +    }
       +  }
       +
       +  if (money < 0) {
       +    GtkMessageBox(dialog, _("You must enter a positive amount of money!"),
       +                  title, MB_OK);
       +  } else if (!Debt && withdraw && money > ClientData.Play->Bank) {
       +    GtkMessageBox(dialog, _("There isn't that much money available..."),
       +                  title, MB_OK);
       +  } else if (!withdraw && money > ClientData.Play->Cash) {
       +    GtkMessageBox(dialog, _("You don't have that much money!"),
       +                  title, MB_OK);
       +  } else {
       +    text = pricetostr(withdraw ? -money : money);
       +    SendClientMessage(ClientData.Play, C_NONE,
       +                      Debt ? C_PAYLOAN : C_DEPOSIT, NULL, text);
       +    g_free(text);
       +    gtk_widget_destroy(dialog);
       +  }
       +  g_free(title);
       +}
       +
       +void TransferDialog(gboolean Debt)
       +{
       +  GtkWidget *dialog, *button, *label, *radio, *table, *vbox;
       +  GtkWidget *hbbox, *hsep, *entry;
       +  GSList *group;
       +  GString *text;
       +
       +  text = g_string_new("");
       +
       +  dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       +  gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
       +                     GTK_SIGNAL_FUNC(SendDoneMessage), NULL);
       +  if (Debt) {
       +    /* Title of loan shark dialog - (%Tde="The Loan Shark" by default) */
       +    dpg_string_sprintf(text, _("%/LoanShark window title/%Tde"),
       +                       Names.LoanSharkName);
       +  } else {
       +    /* Title of bank dialog - (%Tde="The Bank" by default) */
       +    dpg_string_sprintf(text, _("%/BankName window title/%Tde"),
       +                       Names.BankName);
       +  }
       +  gtk_window_set_title(GTK_WINDOW(dialog), text->str);
       +  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       +  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       +                               GTK_WINDOW(ClientData.window));
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +  table = gtk_table_new(4, 3, FALSE);
       +  gtk_table_set_row_spacings(GTK_TABLE(table), 4);
       +  gtk_table_set_col_spacings(GTK_TABLE(table), 4);
       +
       +  /* Display of player's cash in bank or loan shark dialog */
       +  dpg_string_sprintf(text, _("Cash: %P"), ClientData.Play->Cash);
       +  label = gtk_label_new(text->str);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 3, 0, 1);
       +
       +  if (Debt) {
       +    /* Display of player's debt in loan shark dialog */
       +    dpg_string_sprintf(text, _("Debt: %P"), ClientData.Play->Debt);
       +  } else {
       +    /* Display of player's bank balance in bank dialog */
       +    dpg_string_sprintf(text, _("Bank: %P"), ClientData.Play->Bank);
       +  }
       +  label = gtk_label_new(text->str);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 3, 1, 2);
       +
       +  gtk_object_set_data(GTK_OBJECT(dialog), "debt", GINT_TO_POINTER(Debt));
       +  if (Debt) {
       +    /* Prompt for paying back a loan */
       +    label = gtk_label_new(_("Pay back:"));
       +    gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 4);
       +  } else {
       +    /* Radio button selected if you want to pay money into the bank */
       +    radio = gtk_radio_button_new_with_label(NULL, _("Deposit"));
       +    gtk_object_set_data(GTK_OBJECT(dialog), "deposit", radio);
       +    group = gtk_radio_button_group(GTK_RADIO_BUTTON(radio));
       +    gtk_table_attach_defaults(GTK_TABLE(table), radio, 0, 1, 2, 3);
       +
       +    /* Radio button selected if you want to withdraw money from the bank */
       +    radio = gtk_radio_button_new_with_label(group, _("Withdraw"));
       +    gtk_table_attach_defaults(GTK_TABLE(table), radio, 0, 1, 3, 4);
       +  }
       +  label = gtk_label_new(Currency.Symbol);
       +  entry = gtk_entry_new();
       +  gtk_entry_set_text(GTK_ENTRY(entry), "0");
       +  gtk_object_set_data(GTK_OBJECT(dialog), "entry", entry);
       +  gtk_signal_connect(GTK_OBJECT(entry), "activate",
       +                     GTK_SIGNAL_FUNC(TransferOK), dialog);
       +
       +  if (Currency.Prefix) {
       +    gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 2, 4);
       +    gtk_table_attach_defaults(GTK_TABLE(table), entry, 2, 3, 2, 4);
       +  } else {
       +    gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 2, 4);
       +    gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 2, 4);
       +  }
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +
       +  hbbox = gtk_hbutton_box_new();
       +  button = gtk_button_new_with_label(_("OK"));
       +  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                     GTK_SIGNAL_FUNC(TransferOK), dialog);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +
       +  if (Debt && ClientData.Play->Cash >= ClientData.Play->Debt) {
       +    /* Button to pay back the entire loan/debt */
       +    button = gtk_button_new_with_label(_("Pay all"));
       +    gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                       GTK_SIGNAL_FUNC(TransferPayAll), dialog);
       +    gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +  }
       +  button = gtk_button_new_with_label(_("Cancel"));
       +  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       +                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                            (gpointer)dialog);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +  gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
       +
       +  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       +
       +  gtk_widget_show_all(dialog);
       +
       +  g_string_free(text, TRUE);
       +}
       +
       +void ListPlayers(GtkWidget *widget, gpointer data)
       +{
       +  GtkWidget *dialog, *clist, *button, *vbox, *hsep;
       +
       +  if (IsShowingPlayerList)
       +    return;
       +  dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       +
       +  /* Title of player list dialog */
       +  gtk_window_set_title(GTK_WINDOW(dialog), _("Player List"));
       +
       +  gtk_window_set_default_size(GTK_WINDOW(dialog), 200, 180);
       +  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       +
       +  IsShowingPlayerList = TRUE;
       +  gtk_window_set_modal(GTK_WINDOW(dialog), FALSE);
       +  gtk_object_set_data(GTK_OBJECT(dialog), "IsShowing",
       +                      (gpointer)&IsShowingPlayerList);
       +  gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
       +                     GTK_SIGNAL_FUNC(DestroyShowing), NULL);
       +
       +  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       +                               GTK_WINDOW(ClientData.window));
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +
       +  clist = ClientData.PlayerList = CreatePlayerList();
       +  UpdatePlayerList(clist, FALSE);
       +  gtk_box_pack_start(GTK_BOX(vbox), clist, TRUE, TRUE, 0);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +
       +  button = gtk_button_new_with_label(_("OK"));
       +  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       +                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                            (gpointer)dialog);
       +  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
       +  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       +  gtk_widget_show_all(dialog);
       +}
       +
       +struct TalkStruct {
       +  GtkWidget *dialog, *clist, *entry, *checkbutton;
       +};
       +
       +static void TalkSend(GtkWidget *widget, struct TalkStruct *TalkData)
       +{
       +  gboolean AllPlayers;
       +  gchar *text;
       +  GString *msg;
       +  GList *selection;
       +  gint row;
       +  Player *Play;
       +
       +  AllPlayers =
       +      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
       +                                   (TalkData->checkbutton));
       +  text = gtk_editable_get_chars(GTK_EDITABLE(TalkData->entry), 0, -1);
       +  gtk_editable_delete_text(GTK_EDITABLE(TalkData->entry), 0, -1);
       +  if (!text)
       +    return;
       +
       +  msg = g_string_new("");
       +
       +  if (AllPlayers) {
       +    SendClientMessage(ClientData.Play, C_NONE, C_MSG, NULL, text);
       +    g_string_sprintf(msg, "%s: %s", GetPlayerName(ClientData.Play), text);
       +    PrintMessage(msg->str);
       +  } else {
       +    for (selection = GTK_CLIST(TalkData->clist)->selection; selection;
       +         selection = g_list_next(selection)) {
       +      row = GPOINTER_TO_INT(selection->data);
       +      Play =
       +          (Player *)gtk_clist_get_row_data(GTK_CLIST(TalkData->clist),
       +                                           row);
       +      if (Play) {
       +        SendClientMessage(ClientData.Play, C_NONE, C_MSGTO, Play, text);
       +        g_string_sprintf(msg, "%s->%s: %s", GetPlayerName(ClientData.Play),
       +                         GetPlayerName(Play), text);
       +        PrintMessage(msg->str);
       +      }
       +    }
       +  }
       +  g_free(text);
       +  g_string_free(msg, TRUE);
       +}
       +
       +void TalkToAll(GtkWidget *widget, gpointer data)
       +{
       +  TalkDialog(TRUE);
       +}
       +
       +void TalkToPlayers(GtkWidget *widget, gpointer data)
       +{
       +  TalkDialog(FALSE);
       +}
       +
       +void TalkDialog(gboolean TalkToAll)
       +{
       +  GtkWidget *dialog, *clist, *button, *entry, *label, *vbox, *hsep,
       +      *checkbutton, *hbbox;
       +  static struct TalkStruct TalkData;
       +
       +  if (IsShowingTalkList)
       +    return;
       +  dialog = TalkData.dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       +
       +  /* Title of talk dialog */
       +  gtk_window_set_title(GTK_WINDOW(dialog), _("Talk to player(s)"));
       +
       +  gtk_window_set_default_size(GTK_WINDOW(dialog), 200, 190);
       +  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       +
       +  IsShowingTalkList = TRUE;
       +  gtk_window_set_modal(GTK_WINDOW(dialog), FALSE);
       +  gtk_object_set_data(GTK_OBJECT(dialog), "IsShowing",
       +                      (gpointer)&IsShowingTalkList);
       +  gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
       +                     GTK_SIGNAL_FUNC(DestroyShowing), NULL);
       +
       +  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       +                               GTK_WINDOW(ClientData.window));
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +
       +  clist = TalkData.clist = ClientData.TalkList = CreatePlayerList();
       +  UpdatePlayerList(clist, FALSE);
       +  gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_MULTIPLE);
       +  gtk_box_pack_start(GTK_BOX(vbox), clist, TRUE, TRUE, 0);
       +
       +  checkbutton = TalkData.checkbutton =
       +      /* Checkbutton set if you want to talk to all players */
       +      gtk_check_button_new_with_label(_("Talk to all players"));
       +
       +  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TalkToAll);
       +  gtk_box_pack_start(GTK_BOX(vbox), checkbutton, FALSE, FALSE, 0);
       +
       +  /* Prompt for you to enter the message to be sent to other players */
       +  label = gtk_label_new(_("Message:-"));
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       +
       +  entry = TalkData.entry = gtk_entry_new();
       +  gtk_signal_connect(GTK_OBJECT(entry), "activate",
       +                     GTK_SIGNAL_FUNC(TalkSend), (gpointer)&TalkData);
       +  gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +
       +  hbbox = gtk_hbutton_box_new();
       +
       +  /* Button to send a message to other players */
       +  button = gtk_button_new_with_label(_("Send"));
       +
       +  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                     GTK_SIGNAL_FUNC(TalkSend), (gpointer)&TalkData);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +
       +  button = gtk_button_new_with_label(_("Close"));
       +  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       +                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                            (gpointer)dialog);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
       +
       +  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       +  gtk_widget_show_all(dialog);
       +}
       +
       +GtkWidget *CreatePlayerList(void)
       +{
       +  GtkWidget *clist;
       +  gchar *text[1];
       +
       +  text[0] = "Name";
       +  clist = gtk_clist_new_with_titles(1, text);
       +  gtk_clist_column_titles_passive(GTK_CLIST(clist));
       +  gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 0, TRUE);
       +  return clist;
       +}
       +
       +void UpdatePlayerList(GtkWidget *clist, gboolean IncludeSelf)
       +{
       +  GSList *list;
       +  gchar *text[1];
       +  gint row;
       +  Player *Play;
       +
       +  gtk_clist_freeze(GTK_CLIST(clist));
       +  gtk_clist_clear(GTK_CLIST(clist));
       +  for (list = FirstClient; list; list = g_slist_next(list)) {
       +    Play = (Player *)list->data;
       +    if (IncludeSelf || Play != ClientData.Play) {
       +      text[0] = GetPlayerName(Play);
       +      row = gtk_clist_append(GTK_CLIST(clist), text);
       +      gtk_clist_set_row_data(GTK_CLIST(clist), row, Play);
       +    }
       +  }
       +  gtk_clist_thaw(GTK_CLIST(clist));
       +}
       +
       +static void ErrandOK(GtkWidget *widget, GtkWidget *clist)
       +{
       +  GList *selection;
       +  Player *Play;
       +  gint row;
       +  GtkWidget *dialog;
       +  gint ErrandType;
       +
       +  dialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "dialog"));
       +  ErrandType = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget),
       +                                                   "errandtype"));
       +  selection = GTK_CLIST(clist)->selection;
       +  if (selection) {
       +    row = GPOINTER_TO_INT(selection->data);
       +    Play = (Player *)gtk_clist_get_row_data(GTK_CLIST(clist), row);
       +    if (ErrandType == ET_SPY) {
       +      SendClientMessage(ClientData.Play, C_NONE, C_SPYON, Play, NULL);
       +    } else {
       +      SendClientMessage(ClientData.Play, C_NONE, C_TIPOFF, Play, NULL);
       +    }
       +    gtk_widget_destroy(dialog);
       +  }
       +}
       +
       +void SpyOnPlayer(GtkWidget *widget, gpointer data)
       +{
       +  ErrandDialog(ET_SPY);
       +}
       +
       +void TipOff(GtkWidget *widget, gpointer data)
       +{
       +  ErrandDialog(ET_TIPOFF);
       +}
       +
       +void ErrandDialog(gint ErrandType)
       +{
       +  GtkWidget *dialog, *clist, *button, *vbox, *hbbox, *hsep, *label;
       +  gchar *text;
       +
       +  dialog = gtk_window_new(GTK_WINDOW_DIALOG);
       +  gtk_container_set_border_width(GTK_CONTAINER(dialog), 7);
       +
       +  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(dialog),
       +                               GTK_WINDOW(ClientData.window));
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +
       +  if (ErrandType == ET_SPY) {
       +    /* Title of dialog to select a player to spy on */
       +    gtk_window_set_title(GTK_WINDOW(dialog), _("Spy On Player"));
       +
       +    /* Informative text for "spy on player" dialog. (%tde = "bitch",
       +     * "bitch", "guns", "drugs", respectively, by default) */
       +    text = dpg_strdup_printf(_("Please choose the player to spy on. "
       +                               "Your %tde will\nthen offer his "
       +                               "services to the player, and if "
       +                               "successful,\nyou will be able to "
       +                               "view the player's stats with the\n"
       +                               "\"Get spy reports\" menu. Remember "
       +                               "that the %tde will leave\nyou, so "
       +                               "any %tde or %tde that he's "
       +                               "carrying may be lost!"), Names.Bitch,
       +                             Names.Bitch, Names.Guns, Names.Drugs);
       +    label = gtk_label_new(text);
       +    g_free(text);
       +  } else {
       +
       +    /* Title of dialog to select a player to tip the cops off to */
       +    gtk_window_set_title(GTK_WINDOW(dialog), _("Tip Off The Cops"));
       +
       +    /* Informative text for "tip off cops" dialog. (%tde = "bitch",
       +     * "bitch", "guns", "drugs", respectively, by default) */
       +    text = dpg_strdup_printf(_("Please choose the player to tip off "
       +                               "the cops to. Your %tde will\nhelp "
       +                               "the cops to attack that player, "
       +                               "and then report back to you\non "
       +                               "the encounter. Remember that the "
       +                               "%tde will leave you temporarily,\n"
       +                               "so any %tde or %tde that he's "
       +                               "carrying may be lost!"), Names.Bitch,
       +                             Names.Bitch, Names.Guns, Names.Drugs);
       +    label = gtk_label_new(text);
       +    g_free(text);
       +  }
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       +
       +  clist = ClientData.PlayerList = CreatePlayerList();
       +  UpdatePlayerList(clist, FALSE);
       +  gtk_box_pack_start(GTK_BOX(vbox), clist, TRUE, TRUE, 0);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +
       +  hbbox = gtk_hbutton_box_new();
       +  button = gtk_button_new_with_label(_("OK"));
       +  gtk_object_set_data(GTK_OBJECT(button), "dialog", dialog);
       +  gtk_object_set_data(GTK_OBJECT(button), "errandtype",
       +                      GINT_TO_POINTER(ErrandType));
       +  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                     GTK_SIGNAL_FUNC(ErrandOK), (gpointer)clist);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +  button = gtk_button_new_with_label(_("Cancel"));
       +  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       +                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                            (gpointer)dialog);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
       +  gtk_container_add(GTK_CONTAINER(dialog), vbox);
       +  gtk_widget_show_all(dialog);
       +}
       +
       +void SackBitch(GtkWidget *widget, gpointer data)
       +{
       +  char *title, *text;
       +
       +  /* Cannot sack bitches if you don't have any! */
       +  if (ClientData.Play->Bitches.Carried <= 0)
       +    return;
       +
       +  /* Title of dialog to sack a bitch (%Tde = "Bitch" by default) */
       +  title = dpg_strdup_printf(_("%/Sack Bitch dialog title/Sack %Tde"),
       +                            Names.Bitch);
       +
       +  /* Confirmation message for sacking a bitch. (%tde = "guns", "drugs",
       +   * "bitch", respectively, by default) */
       +  text = dpg_strdup_printf(_("Are you sure? (Any %tde or %tde carried\n"
       +                             "by this %tde may be lost!)"), Names.Guns,
       +                           Names.Drugs, Names.Bitch);
       +
       +  if (GtkMessageBox(ClientData.window, text, title, MB_YESNO) == IDYES) {
       +    ClientData.Play->Bitches.Carried--;
       +    UpdateMenus();
       +    SendClientMessage(ClientData.Play, C_NONE, C_SACKBITCH, NULL, NULL);
       +  }
       +  g_free(text);
       +  g_free(title);
       +}
       +
       +void CreateInventory(GtkWidget *hbox, gchar *Objects,
       +                     GtkAccelGroup *accel_group, gboolean CreateButtons,
       +                     gboolean CreateHere, struct InventoryWidgets *widgets,
       +                     GtkSignalFunc CallBack)
       +{
       +  GtkWidget *scrollwin, *clist, *vbbox, *frame[2], *button[3];
       +  gint i, mini;
       +  GString *text;
       +  gchar *titles[2][2];
       +  gchar *button_text[3];
       +  gpointer button_type[3] = { BT_BUY, BT_SELL, BT_DROP };
       +
       +  /* Column titles for display of drugs/guns carried or available for
       +   * purchase */
       +  titles[0][0] = titles[1][0] = _("Name");
       +  titles[0][1] = _("Price");
       +  titles[1][1] = _("Number");
       +
       +  /* Button titles for buying/selling/dropping guns or drugs */
       +  button_text[0] = _("_Buy ->");
       +  button_text[1] = _("<- _Sell");
       +  button_text[2] = _("_Drop <-");
       +
       +  text = g_string_new("");
       +
       +  if (CreateHere) {
       +    /* Title of the display of available drugs/guns (%Tde = "Guns" or
       +     * "Drugs" by default) */
       +    dpg_string_sprintf(text, _("%Tde here"), Objects);
       +    widgets->HereFrame = frame[0] = gtk_frame_new(text->str);
       +  }
       +
       +  /* Title of the display of carried drugs/guns (%Tde = "Guns" or "Drugs"
       +   * by default) */
       +  dpg_string_sprintf(text, _("%Tde carried"), Objects);
       +
       +  widgets->CarriedFrame = frame[1] = gtk_frame_new(text->str);
       +
       +  widgets->HereList = widgets->CarriedList = NULL;
       +  if (CreateHere)
       +    mini = 0;
       +  else
       +    mini = 1;
       +  for (i = mini; i < 2; i++) {
       +    gtk_container_set_border_width(GTK_CONTAINER(frame[i]), 5);
       +
       +    clist = gtk_scrolled_clist_new_with_titles(2, titles[i], &scrollwin);
       +    gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 0, TRUE);
       +    gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 1, TRUE);
       +    gtk_clist_column_titles_passive(GTK_CLIST(clist));
       +    gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_SINGLE);
       +    gtk_clist_set_auto_sort(GTK_CLIST(clist), FALSE);
       +    gtk_container_add(GTK_CONTAINER(frame[i]), scrollwin);
       +    if (i == 0)
       +      widgets->HereList = clist;
       +    else
       +      widgets->CarriedList = clist;
       +  }
       +  if (CreateHere)
       +    gtk_box_pack_start(GTK_BOX(hbox), frame[0], TRUE, TRUE, 0);
       +
       +  if (CreateButtons) {
       +    widgets->vbbox = vbbox = gtk_vbutton_box_new();
       +
       +    for (i = 0; i < 3; i++) {
       +      button[i] = gtk_button_new_with_label("");
       +      SetAccelerator(button[i], _(button_text[i]), button[i],
       +                     "clicked", accel_group);
       +      if (CallBack)
       +        gtk_signal_connect(GTK_OBJECT(button[i]), "clicked",
       +                           GTK_SIGNAL_FUNC(CallBack), button_type[i]);
       +      gtk_box_pack_start(GTK_BOX(vbbox), button[i], TRUE, TRUE, 0);
       +    }
       +    widgets->BuyButton = button[0];
       +    widgets->SellButton = button[1];
       +    widgets->DropButton = button[2];
       +    gtk_box_pack_start(GTK_BOX(hbox), vbbox, FALSE, FALSE, 0);
       +  } else
       +    widgets->vbbox = NULL;
       +
       +  gtk_box_pack_start(GTK_BOX(hbox), frame[1], TRUE, TRUE, 0);
       +  g_string_free(text, TRUE);
       +}
       +
       +void DestroyShowing(GtkWidget *widget, gpointer data)
       +{
       +  gboolean *IsShowing;
       +
       +  IsShowing =
       +      (gboolean *)gtk_object_get_data(GTK_OBJECT(widget), "IsShowing");
       +  if (IsShowing)
       +    *IsShowing = FALSE;
       +}
       +
       +static void NewNameOK(GtkWidget *widget, GtkWidget *window)
       +{
       +  GtkWidget *entry;
       +  gchar *text;
       +
       +  entry = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(window), "entry"));
       +  text = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
       +  if (text[0]) {
       +    SetPlayerName(ClientData.Play, text);
       +    SendNullClientMessage(ClientData.Play, C_NONE, C_NAME, NULL, text);
       +    gtk_widget_destroy(window);
       +  }
       +  g_free(text);
       +}
       +
       +void NewNameDialog(void)
       +{
       +  GtkWidget *window, *button, *hsep, *vbox, *label, *entry;
       +
       +  window = gtk_window_new(GTK_WINDOW_DIALOG);
       +
       +  /* Title of dialog for changing a player's name */
       +  gtk_window_set_title(GTK_WINDOW(window), _("Change Name"));
       +
       +  gtk_window_set_modal(GTK_WINDOW(window), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(window),
       +                               GTK_WINDOW(ClientData.window));
       +  gtk_container_set_border_width(GTK_CONTAINER(window), 7);
       +  gtk_signal_connect(GTK_OBJECT(window), "delete_event",
       +                     GTK_SIGNAL_FUNC(DisallowDelete), NULL);
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +
       +  /* Informational text to prompt the player to change his/her name */
       +  label = gtk_label_new(_("Unfortunately, somebody else is already "
       +                          "using \"your\" name. Please change it:-"));
       +  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
       +
       +  entry = gtk_entry_new();
       +  gtk_object_set_data(GTK_OBJECT(window), "entry", entry);
       +  gtk_signal_connect(GTK_OBJECT(entry), "activate",
       +                     GTK_SIGNAL_FUNC(NewNameOK), window);
       +  gtk_entry_set_text(GTK_ENTRY(entry), GetPlayerName(ClientData.Play));
       +  gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +
       +  button = gtk_button_new_with_label(_("OK"));
       +  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                     GTK_SIGNAL_FUNC(NewNameOK), window);
       +  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
       +  GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
       +  gtk_widget_grab_default(button);
       +
       +  gtk_container_add(GTK_CONTAINER(window), vbox);
       +  gtk_widget_show_all(window);
       +}
       +
       +gint DisallowDelete(GtkWidget *widget, GdkEvent *event, gpointer data)
       +{
       +  return (TRUE);
       +}
       +
       +void GunShopDialog(void)
       +{
       +  GtkWidget *window, *button, *hsep, *vbox, *hbox;
       +  GtkAccelGroup *accel_group;
       +  gchar *text;
       +
       +  window = gtk_window_new(GTK_WINDOW_DIALOG);
       +  gtk_window_set_default_size(GTK_WINDOW(window), 600, 190);
       +  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       +                     GTK_SIGNAL_FUNC(SendDoneMessage), NULL);
       +  accel_group = gtk_accel_group_new();
       +  gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
       +
       +  /* Title of 'gun shop' dialog in GTK+ client (%Tde="Dan's House of Guns"
       +   * by default) */
       +  text = dpg_strdup_printf(_("%/GTK GunShop window title/%Tde"),
       +                           Names.GunShopName);
       +  gtk_window_set_title(GTK_WINDOW(window), text);
       +  g_free(text);
       +  gtk_window_set_modal(GTK_WINDOW(window), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(window),
       +                               GTK_WINDOW(ClientData.window));
       +  gtk_container_set_border_width(GTK_CONTAINER(window), 7);
       +  IsShowingGunShop = TRUE;
       +  gtk_object_set_data(GTK_OBJECT(window), "IsShowing",
       +                      (gpointer)&IsShowingGunShop);
       +  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       +                     GTK_SIGNAL_FUNC(DestroyShowing), NULL);
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +
       +  hbox = gtk_hbox_new(FALSE, 7);
       +  CreateInventory(hbox, Names.Guns, accel_group, TRUE, TRUE,
       +                  &ClientData.Gun, DealGuns);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +
       +  /* Button to finish buying/selling guns in the gun shop */
       +  button = gtk_button_new_with_label(_("Done"));
       +
       +  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       +                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                            (gpointer)window);
       +  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
       +
       +  gtk_container_add(GTK_CONTAINER(window), vbox);
       +
       +  UpdateInventory(&ClientData.Gun, ClientData.Play->Guns, NumGun, FALSE);
       +  gtk_widget_show_all(window);
       +}
       +
       +void UpdatePlayerLists(void)
       +{
       +  if (IsShowingPlayerList)
       +    UpdatePlayerList(ClientData.PlayerList, FALSE);
       +  if (IsShowingTalkList)
       +    UpdatePlayerList(ClientData.TalkList, FALSE);
       +}
       +
       +void GetSpyReports(GtkWidget *Widget, gpointer data)
       +{
       +  SendClientMessage(ClientData.Play, C_NONE, C_CONTACTSPY, NULL, NULL);
       +}
       +
       +static void DestroySpyReports(GtkWidget *widget, gpointer data)
       +{
       +  SpyReportsDialog = NULL;
       +}
       +
       +static void CreateSpyReports(void)
       +{
       +  GtkWidget *window, *button, *vbox, *notebook;
       +  GtkAccelGroup *accel_group;
       +
       +  SpyReportsDialog = window = gtk_window_new(GTK_WINDOW_DIALOG);
       +  accel_group = gtk_accel_group_new();
       +  gtk_object_set_data(GTK_OBJECT(window), "accel_group", accel_group);
       +  gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
       +
       +  /* Title of window to display reports from spies with other players */
       +  gtk_window_set_title(GTK_WINDOW(window), _("Spy reports"));
       +
       +  gtk_window_set_modal(GTK_WINDOW(window), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(window),
       +                               GTK_WINDOW(ClientData.window));
       +  gtk_container_set_border_width(GTK_CONTAINER(window), 7);
       +  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       +                     GTK_SIGNAL_FUNC(DestroySpyReports), NULL);
       +
       +  vbox = gtk_vbox_new(FALSE, 5);
       +  notebook = gtk_notebook_new();
       +  gtk_object_set_data(GTK_OBJECT(window), "notebook", notebook);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
       +
       +  button = gtk_button_new_with_label(_("Close"));
       +  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       +                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                            (gpointer)window);
       +  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
       +
       +  gtk_container_add(GTK_CONTAINER(window), vbox);
       +
       +  gtk_widget_show_all(window);
       +}
       +
       +void DisplaySpyReports(Player *Play)
       +{
       +  GtkWidget *dialog, *notebook, *vbox, *hbox, *frame, *label, *table;
       +  GtkAccelGroup *accel_group;
       +  struct StatusWidgets Status;
       +  struct InventoryWidgets SpyDrugs, SpyGuns;
       +
       +  if (!SpyReportsDialog)
       +    CreateSpyReports();
       +  dialog = SpyReportsDialog;
       +  notebook =
       +      GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(dialog), "notebook"));
       +  accel_group =
       +      (GtkAccelGroup
       +       *)(gtk_object_get_data(GTK_OBJECT(dialog), "accel_group"));
       +  vbox = gtk_vbox_new(FALSE, 5);
       +  frame = gtk_frame_new("Stats");
       +  gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
       +  table = CreateStatusWidgets(&Status);
       +  gtk_container_add(GTK_CONTAINER(frame), table);
       +  gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
       +
       +  hbox = gtk_hbox_new(FALSE, 5);
       +  CreateInventory(hbox, Names.Drugs, accel_group, FALSE, FALSE, &SpyDrugs,
       +                  NULL);
       +  CreateInventory(hbox, Names.Guns, accel_group, FALSE, FALSE, &SpyGuns,
       +                  NULL);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
       +  label = gtk_label_new(GetPlayerName(Play));
       +
       +  DisplayStats(Play, &Status);
       +  UpdateInventory(&SpyDrugs, Play->Drugs, NumDrug, TRUE);
       +  UpdateInventory(&SpyGuns, Play->Guns, NumGun, FALSE);
       +
       +  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
       +
       +  gtk_widget_show_all(notebook);
       +}
       +
       +#ifdef NETWORKING
       +static void OKAuthDialog(GtkWidget *widget, GtkWidget *window)
       +{
       +  gtk_object_set_data(GTK_OBJECT(window), "authok", GINT_TO_POINTER(TRUE));
       +  gtk_widget_destroy(window);
       +}
       +
       +static void DestroyAuthDialog(GtkWidget *window, gpointer data)
       +{
       +  GtkWidget *userentry, *passwdentry;
       +  gchar *username = NULL, *password = NULL;
       +  gpointer proxy, authok;
       +  HttpConnection *conn;
       +
       +  authok = gtk_object_get_data(GTK_OBJECT(window), "authok");
       +  proxy = gtk_object_get_data(GTK_OBJECT(window), "proxy");
       +  userentry =
       +      (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), "username");
       +  passwdentry =
       +      (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), "password");
       +  conn =
       +      (HttpConnection *)gtk_object_get_data(GTK_OBJECT(window),
       +                                            "httpconn");
       +  g_assert(userentry && passwdentry && conn);
       +
       +  if (authok) {
       +    username = gtk_editable_get_chars(GTK_EDITABLE(userentry), 0, -1);
       +    password = gtk_editable_get_chars(GTK_EDITABLE(passwdentry), 0, -1);
       +  }
       +
       +  SetHttpAuthentication(conn, GPOINTER_TO_INT(proxy), username, password);
       +
       +  g_free(username);
       +  g_free(password);
       +}
       +
       +void AuthDialog(HttpConnection *conn, gboolean proxy, gchar *realm,
       +                gpointer data)
       +{
       +  GtkWidget *window, *button, *hsep, *vbox, *label, *entry, *table, *hbbox;
       +
       +  window = gtk_window_new(GTK_WINDOW_DIALOG);
       +  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       +                     GTK_SIGNAL_FUNC(DestroyAuthDialog), NULL);
       +  gtk_object_set_data(GTK_OBJECT(window), "proxy", GINT_TO_POINTER(proxy));
       +  gtk_object_set_data(GTK_OBJECT(window), "httpconn", (gpointer)conn);
       +
       +  if (proxy) {
       +    gtk_window_set_title(GTK_WINDOW(window),
       +                         /* Title of dialog for authenticating with a
       +                          * proxy server */
       +                         _("Proxy Authentication Required"));
       +  } else {
       +    /* Title of dialog for authenticating with a web server */
       +    gtk_window_set_title(GTK_WINDOW(window), _("Authentication Required"));
       +  }
       +
       +  gtk_window_set_modal(GTK_WINDOW(window), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(window),
       +                               GTK_WINDOW(ClientData.window));
       +  gtk_container_set_border_width(GTK_CONTAINER(window), 7);
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +
       +  table = gtk_table_new(3, 2, FALSE);
       +  gtk_table_set_row_spacings(GTK_TABLE(table), 10);
       +  gtk_table_set_col_spacings(GTK_TABLE(table), 5);
       +
       +  label = gtk_label_new("Realm:");
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
       +
       +  label = gtk_label_new(realm);
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 0, 1);
       +
       +  label = gtk_label_new("User name:");
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
       +
       +  entry = gtk_entry_new();
       +  gtk_object_set_data(GTK_OBJECT(window), "username", (gpointer)entry);
       +  gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 1, 2);
       +
       +  label = gtk_label_new("Password:");
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3);
       +
       +  entry = gtk_entry_new();
       +  gtk_object_set_data(GTK_OBJECT(window), "password", (gpointer)entry);
       +
       +#ifdef HAVE_FIXED_GTK
       +  /* GTK+ versions earlier than 1.2.10 do bad things with this */
       +  gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
       +#endif
       +
       +  gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 2, 3);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +
       +  hbbox = gtk_hbutton_box_new();
       +
       +  button = gtk_button_new_with_label(_("OK"));
       +  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                     GTK_SIGNAL_FUNC(OKAuthDialog), (gpointer)window);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +
       +  button = gtk_button_new_with_label(_("Cancel"));
       +  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       +                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                            (gpointer)window);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), hbbox, TRUE, TRUE, 0);
       +
       +  gtk_container_add(GTK_CONTAINER(window), vbox);
       +  gtk_widget_show_all(window);
       +}
       +
       +static void OKSocksAuth(GtkWidget *widget, GtkWidget *window)
       +{
       +  gtk_object_set_data(GTK_OBJECT(window), "authok", GINT_TO_POINTER(TRUE));
       +  gtk_widget_destroy(window);
       +}
       +
       +static void DestroySocksAuth(GtkWidget *window, gpointer data)
       +{
       +  GtkWidget *userentry, *passwdentry;
       +  gchar *username = NULL, *password = NULL;
       +  gpointer authok, meta;
       +  NetworkBuffer *netbuf;
       +
       +  authok = gtk_object_get_data(GTK_OBJECT(window), "authok");
       +  meta = gtk_object_get_data(GTK_OBJECT(window), "meta");
       +  userentry =
       +      (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), "username");
       +  passwdentry =
       +      (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), "password");
       +  netbuf =
       +      (NetworkBuffer *)gtk_object_get_data(GTK_OBJECT(window), "netbuf");
       +
       +  g_assert(userentry && passwdentry && netbuf);
       +
       +  if (authok) {
       +    username = gtk_editable_get_chars(GTK_EDITABLE(userentry), 0, -1);
       +    password = gtk_editable_get_chars(GTK_EDITABLE(passwdentry), 0, -1);
       +  }
       +
       +  SendSocks5UserPasswd(netbuf, username, password);
       +  g_free(username);
       +  g_free(password);
       +}
       +
       +static void RealSocksAuthDialog(NetworkBuffer *netbuf, gboolean meta,
       +                                gpointer data)
       +{
       +  GtkWidget *window, *button, *hsep, *vbox, *label, *entry, *table, *hbbox;
       +
       +  window = gtk_window_new(GTK_WINDOW_DIALOG);
       +  gtk_signal_connect(GTK_OBJECT(window), "destroy",
       +                     GTK_SIGNAL_FUNC(DestroySocksAuth), NULL);
       +  gtk_object_set_data(GTK_OBJECT(window), "netbuf", (gpointer)netbuf);
       +  gtk_object_set_data(GTK_OBJECT(window), "meta", GINT_TO_POINTER(meta));
       +
       +  /* Title of dialog for authenticating with a SOCKS server */
       +  gtk_window_set_title(GTK_WINDOW(window),
       +                       _("SOCKS Authentication Required"));
       +
       +  gtk_window_set_modal(GTK_WINDOW(window), TRUE);
       +  gtk_window_set_transient_for(GTK_WINDOW(window),
       +                               GTK_WINDOW(ClientData.window));
       +  gtk_container_set_border_width(GTK_CONTAINER(window), 7);
       +
       +  vbox = gtk_vbox_new(FALSE, 7);
       +
       +  table = gtk_table_new(2, 2, FALSE);
       +  gtk_table_set_row_spacings(GTK_TABLE(table), 10);
       +  gtk_table_set_col_spacings(GTK_TABLE(table), 5);
       +
       +  label = gtk_label_new("User name:");
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
       +
       +  entry = gtk_entry_new();
       +  gtk_object_set_data(GTK_OBJECT(window), "username", (gpointer)entry);
       +  gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 0, 1);
       +
       +  label = gtk_label_new("Password:");
       +  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
       +
       +  entry = gtk_entry_new();
       +  gtk_object_set_data(GTK_OBJECT(window), "password", (gpointer)entry);
       +
       +#ifdef HAVE_FIXED_GTK
       +  /* GTK+ versions earlier than 1.2.10 do bad things with this */
       +  gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
       +#endif
       +
       +  gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 1, 2);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
       +
       +  hsep = gtk_hseparator_new();
       +  gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
       +
       +  hbbox = gtk_hbutton_box_new();
       +
       +  button = gtk_button_new_with_label(_("OK"));
       +  gtk_signal_connect(GTK_OBJECT(button), "clicked",
       +                     GTK_SIGNAL_FUNC(OKSocksAuth), (gpointer)window);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +
       +  button = gtk_button_new_with_label(_("Cancel"));
       +  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
       +                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                            (gpointer)window);
       +  gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0);
       +
       +  gtk_box_pack_start(GTK_BOX(vbox), hbbox, TRUE, TRUE, 0);
       +
       +  gtk_container_add(GTK_CONTAINER(window), vbox);
       +  gtk_widget_show_all(window);
       +}
       +
       +void MetaSocksAuthDialog(NetworkBuffer *netbuf, gpointer data)
       +{
       +  RealSocksAuthDialog(netbuf, TRUE, data);
       +}
       +
       +void SocksAuthDialog(NetworkBuffer *netbuf, gpointer data)
       +{
       +  RealSocksAuthDialog(netbuf, FALSE, data);
       +}
       +
       +#endif /* NETWORKING */
 (DIR) diff --git a/src/gui_client/gtk_client.h b/src/gui_client/gtk_client.h
       t@@ -0,0 +1,41 @@
       +/************************************************************************
       + * gtk_client.h   dopewars client using the GTK+ toolkit                *
       + * Copyright (C)  1998-2002  Ben Webb                                   *
       + *                Email: ben@bellatrix.pcl.ox.ac.uk                     *
       + *                WWW: http://dopewars.sourceforge.net/                 *
       + *                                                                      *
       + * This program is free software; you can redistribute it and/or        *
       + * modify it under the terms of the GNU General Public License          *
       + * as published by the Free Software Foundation; either version 2       *
       + * of the License, or (at your option) any later version.               *
       + *                                                                      *
       + * This program is distributed in the hope that it will be useful,      *
       + * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
       + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
       + * GNU General Public License for more details.                         *
       + *                                                                      *
       + * You should have received a copy of the GNU General Public License    *
       + * along with this program; if not, write to the Free Software          *
       + * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
       + *                   MA  02111-1307, USA.                               *
       + ************************************************************************/
       +
       +#ifndef __GTK_CLIENT_H__
       +#define __GTK_CLIENT_H__
       +
       +#ifdef HAVE_CONFIG_H
       +#include <config.h>
       +#endif
       +
       +#include "gtkport/gtkport.h"
       +
       +extern GtkWidget *MainWindow;
       +
       +#ifdef CYGWIN
       +gboolean GtkLoop(HINSTANCE hInstance, HINSTANCE hPrevInstance,
       +                 gboolean ReturnOnFail);
       +#else
       +gboolean GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail);
       +#endif
       +
       +#endif
 (DIR) diff --git a/src/winmain.c b/src/winmain.c
       t@@ -36,13 +36,22 @@
        #include "nls.h"
        #include "tstring.h"
        #include "AIPlayer.h"
       -#include "curses_client.h"
       -#include "gtk_client.h"
        #include "message.h"
        #include "serverside.h"
       -#include "gtkport.h"
        #include "winmain.h"
        
       +#ifdef CURSES_CLIENT
       +#include "curses_client/curses_client.h"
       +#endif
       +
       +#ifdef GUI_CLIENT
       +#include "gui_client/gtk_client.h"
       +#endif
       +
       +#ifdef GUI_SERVER
       +#include "gtkport/gtkport.h"
       +#endif
       +
        static void ServerLogMessage(const gchar *log_domain,
                                     GLogLevelFlags log_level,
                                     const gchar *message, gpointer user_data)
       t@@ -310,18 +319,24 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
              g_set_print_handler(ServerPrintFunc);
              newterm(NULL, NULL, NULL);
              AIPlayerLoop();
       -    } else if (WantedClient == CLIENT_CURSES) {
       -      AllocConsole();
       -      SetConsoleTitle(_("dopewars"));
       -      CursesLoop();
            } else {
       -#if GUI_CLIENT
       -      GtkLoop(hInstance, hPrevInstance);
       -#else
       -      g_print(_("No graphical client available - rebuild the binary\n"
       -                "passing the --enable-gui-client option to configure, or\n"
       -                "use the curses client (if available) instead!\n"));
       -#endif
       +      switch (WantedClient) {
       +      case CLIENT_AUTO:
       +        if (!GtkLoop(hInstance, hPrevInstance, TRUE)) {
       +          AllocConsole();
       +          SetConsoleTitle(_("dopewars"));
       +          CursesLoop();
       +        }
       +        break;
       +      case CLIENT_WINDOW:
       +        GtkLoop(hInstance, hPrevInstance, FALSE);
       +        break;
       +      case CLIENT_CURSES:
       +        AllocConsole();
       +        SetConsoleTitle(_("dopewars"));
       +        CursesLoop();
       +        break;
       +      }
            }
        #ifdef NETWORKING
            StopNetworking();