| 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 |
| git clone git://src.adamsgaard.dk/vaccinewars |
| Log |
| Files |
| Refs |
| README |
| LICENSE |
| --- |
| commit ef90a6dc064a2a31b8bdbc0c52a215da6d058623 |
| parent a449a445fedb565c9b1096a5622b3e4fb33351c3 |
| Author: Ben Webb |
| 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(-)
--- |
| 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//`; \ |
| 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 , 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 , 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 , 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])
+ |
| 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 <&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 <
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 <
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 <&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 <&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 <&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 <
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 <
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 <
#include
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 <&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 <&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 <
#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 <
#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 <
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 <&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 <&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 <&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 <&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
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 <&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 <
#include
+#if HAVE_SYS_TYPES_H
+# include
+#endif
+
+#if HAVE_STDLIB_H
+# include
+#endif
+
+#if HAVE_SYS_STAT_H
+# include
+#endif
+
+#if HAVE_UNISTD_H
+# include
+#endif
+
/* This mess was copied from the GNU getpagesize.h. */
#ifndef HAVE_GETPAGESIZE
-# ifdef HAVE_UNISTD_H
-# include
-# 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 <
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
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 <&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 <
#include
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 <
#include
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 <
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 <
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 <
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
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 <
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 <
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 <&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 <
-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 <&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 <
/* 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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 < "$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
;; |
| 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], |
| 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} |
| 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 |
| 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
|
| 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
-#endif
-
-#ifdef CURSES_CLIENT
-
-#include
-#include
-#include
-#ifdef HAVE_UNISTD_H
-#include
-#endif
-#include
-#include
-#include
-#include
-#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
-#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 */ |
| 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}\" |
| 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: |
| 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
+#endif
+
+#include
+#include
+#include
+#ifdef HAVE_UNISTD_H
+#include
+#endif
+#include
+#include
+#include
+#include
+#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();
+} |
| diff --git a/src/curses_client.h b/src/curses_client/curses_client.h |
| diff --git a/src/dopewars.c b/src/dopewars.c |
| t@@ -43,9 +43,7 @@
#include
#include
#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
*/ |
| 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 |
| 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
-#endif
-
-#ifdef GUI_CLIENT
-
-#include
-#include
-#include
-
-#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, ""},
- {N_("/Game/_New..."), "N", NewGame, 0, NULL},
- {N_("/Game/_Quit..."), "Q", QuitGame, 0, NULL},
- {N_("/_Talk"), NULL, NULL, 0, ""},
- {N_("/Talk/To _All..."), NULL, TalkToAll, 0, NULL},
- {N_("/Talk/To _Player..."), NULL, TalkToPlayers, 0, NULL},
- {N_("/_List"), NULL, NULL, 0, ""},
- {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, ""},
- {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, ""},
- {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,
- "/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,
- "/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,
- "/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,
- "/Talk"),
- InGame && Network);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
- (ClientData.Menu, "/List"), InGame);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
- (ClientData.Menu, "/List/Players..."),
- InGame && Network);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
- (ClientData.Menu, "/Errands"), InGame);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
- (ClientData.Menu, "/Errands/Spy..."),
- InGame && MultiPlayer);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
- (ClientData.Menu, "/Errands/Tipoff..."),
- InGame && MultiPlayer);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
- (ClientData.Menu,
- "/Errands/Sack Bitch..."), Bitches > 0);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
- (ClientData.Menu,
- "/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,
- "",
- 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, "");
-
- 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
-#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 */ |
| 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
-#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 |
| 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}\" |
| 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: |
| diff --git a/src/gtkport.c b/src/gtkport/gtkport.c |
| diff --git a/src/gtkport.h b/src/gtkport/gtkport.h |
| 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}\" |
| 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: |
| 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
+#endif
+
+#include
+#include
+#include
+
+#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, ""},
+ {N_("/Game/_New..."), "N", NewGame, 0, NULL},
+ {N_("/Game/_Quit..."), "Q", QuitGame, 0, NULL},
+ {N_("/_Talk"), NULL, NULL, 0, ""},
+ {N_("/Talk/To _All..."), NULL, TalkToAll, 0, NULL},
+ {N_("/Talk/To _Player..."), NULL, TalkToPlayers, 0, NULL},
+ {N_("/_List"), NULL, NULL, 0, ""},
+ {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, ""},
+ {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, ""},
+ {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,
+ "/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,
+ "/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,
+ "/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,
+ "/Talk"),
+ InGame && Network);
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ (ClientData.Menu, "/List"), InGame);
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ (ClientData.Menu, "/List/Players..."),
+ InGame && Network);
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ (ClientData.Menu, "/Errands"), InGame);
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ (ClientData.Menu, "/Errands/Spy..."),
+ InGame && MultiPlayer);
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ (ClientData.Menu, "/Errands/Tipoff..."),
+ InGame && MultiPlayer);
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ (ClientData.Menu,
+ "/Errands/Sack Bitch..."), Bitches > 0);
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ (ClientData.Menu,
+ "/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,
+ "",
+ 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, "");
+
+ 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 */ |
| 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
+#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 |
| 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(); |