tThe directory structure is now reorganised; the separate clients, and the gtkp… | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit ef90a6dc064a2a31b8bdbc0c52a215da6d058623 | |
parent a449a445fedb565c9b1096a5622b3e4fb33351c3 | |
Author: Ben Webb <[email protected]> | |
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 <[email protected]>, 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, [ … | |
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, [ … | |
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, [ … | |
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, [ + … | |
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, [ + … | |
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" || ec… | |
+ echo creating "$ac_dir/POTFILES" | |
sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/&… | |
- test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || ec… | |
+ echo creating "$ac_dir/Makefile" | |
sed -e "/POTFILES =/r $ac_dir/POTFILES" "$ac_dir/Makefile.in" > "$… | |
fi | |
;; | |
t@@ -780,7 +758,7 @@ return (int) gettext ("")]ifelse([$2], need-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.* \(… | |
+ ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison .* \… | |
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 __a… | |
# Ulrich Drepper <[email protected]>, 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_pa… | |
;; | |
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 <[email protected]>, 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 <<EOF | |
-#line 1565 "configure" | |
+#line 1574 "configure" | |
#include "confdefs.h" | |
int main() { | |
t@@ -1572,7 +1581,7 @@ int main() { | |
return __CYGWIN__; | |
; return 0; } | |
EOF | |
-if { (eval echo configure:1576: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
+if { (eval echo configure:1585: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
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 … | |
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 >= $mi… | |
echo $ac_n "cross compiling; assumed OK... $ac_c" | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 1732 "configure" | |
+#line 1743 "configure" | |
#include "confdefs.h" | |
#include <glib.h> | |
t@@ -1804,7 +1815,7 @@ main () | |
} | |
EOF | |
-if { (eval echo configure:1808: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:1819: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
then | |
: | |
else | |
t@@ -1838,7 +1849,7 @@ fi | |
CFLAGS="$CFLAGS $GLIB_CFLAGS" | |
LIBS="$LIBS $GLIB_LIBS" | |
cat > conftest.$ac_ext <<EOF | |
-#line 1842 "configure" | |
+#line 1853 "configure" | |
#include "confdefs.h" | |
#include <glib.h> | |
t@@ -1848,7 +1859,7 @@ int main() { | |
return ((glib_major_version) || (glib_minor_version) || (glib_micro_version))… | |
; return 0; } | |
EOF | |
-if { (eval echo configure:1852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:1863: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
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 th… | |
t@@ -1887,9 +1898,9 @@ rm -f conftest* | |
rm -f conf.glibtest | |
- if test "$CURSES_CLIENT" = "yes" ; then | |
+ if test "$CURSES_CLIENT" != "no" ; then | |
echo $ac_n "checking for newterm in -lncurses""... $ac_c" 1>&6 | |
-echo "configure:1893: checking for newterm in -lncurses" >&5 | |
+echo "configure:1904: checking for newterm in -lncurses" >&5 | |
ac_lib_var=`echo ncurses'_'newterm | sed 'y%./+-%__p_%'` | |
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
t@@ -1897,7 +1908,7 @@ else | |
ac_save_LIBS="$LIBS" | |
LIBS="-lncurses $LIBS" | |
cat > conftest.$ac_ext <<EOF | |
-#line 1901 "configure" | |
+#line 1912 "configure" | |
#include "confdefs.h" | |
/* Override any gcc2 internal prototype to avoid an error. */ | |
/* We use char because int might match the return type of a gcc2 | |
t@@ -1908,7 +1919,7 @@ int main() { | |
newterm() | |
; return 0; } | |
EOF | |
-if { (eval echo configure:1912: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:1923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
eval "ac_cv_lib_$ac_lib_var=yes" | |
else | |
t@@ -1937,7 +1948,7 @@ fi | |
if test "$ac_cv_lib_ncurses_newterm" = "no" ; then | |
echo $ac_n "checking for newterm in -lcurses""... $ac_c" 1>&6 | |
-echo "configure:1941: checking for newterm in -lcurses" >&5 | |
+echo "configure:1952: checking for newterm in -lcurses" >&5 | |
ac_lib_var=`echo curses'_'newterm | sed 'y%./+-%__p_%'` | |
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
t@@ -1945,7 +1956,7 @@ else | |
ac_save_LIBS="$LIBS" | |
LIBS="-lcurses $LIBS" | |
cat > conftest.$ac_ext <<EOF | |
-#line 1949 "configure" | |
+#line 1960 "configure" | |
#include "confdefs.h" | |
/* Override any gcc2 internal prototype to avoid an error. */ | |
/* We use char because int might match the return type of a gcc2 | |
t@@ -1956,7 +1967,7 @@ int main() { | |
newterm() | |
; return 0; } | |
EOF | |
-if { (eval echo configure:1960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:1971: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
eval "ac_cv_lib_$ac_lib_var=yes" | |
else | |
t@@ -1985,7 +1996,7 @@ fi | |
if test "$ac_cv_lib_curses_newterm" = "no" ; then | |
echo $ac_n "checking for newterm in -lcur_colr""... $ac_c" 1>&6 | |
-echo "configure:1989: checking for newterm in -lcur_colr" >&5 | |
+echo "configure:2000: checking for newterm in -lcur_colr" >&5 | |
ac_lib_var=`echo cur_colr'_'newterm | sed 'y%./+-%__p_%'` | |
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
t@@ -1993,7 +2004,7 @@ else | |
ac_save_LIBS="$LIBS" | |
LIBS="-lcur_colr $LIBS" | |
cat > conftest.$ac_ext <<EOF | |
-#line 1997 "configure" | |
+#line 2008 "configure" | |
#include "confdefs.h" | |
/* Override any gcc2 internal prototype to avoid an error. */ | |
/* We use char because int might match the return type of a gcc2 | |
t@@ -2004,7 +2015,7 @@ int main() { | |
newterm() | |
; return 0; } | |
EOF | |
-if { (eval echo configure:2008: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:2019: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
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" … | |
- CURSES_CLIENT="no" | |
+ if test "$CURSES_CLIENT" = "yes" ; then | |
+ { echo "configure: error: Cannot find any curses-type library… | |
+ else | |
+ echo "configure: warning: 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 | |
# Check whether --with-gtk-prefix or --without-gtk-prefix was give… | |
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 a… | |
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… | |
echo $ac_n "cross compiling; assumed OK... $ac_c" | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 2152 "configure" | |
+#line 2167 "configure" | |
#include "confdefs.h" | |
#include <gtk/gtk.h> | |
t@@ -2226,7 +2241,7 @@ main () | |
} | |
EOF | |
-if { (eval echo configure:2230: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:2245: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
then | |
: | |
else | |
t@@ -2260,7 +2275,7 @@ fi | |
CFLAGS="$CFLAGS $GTK_CFLAGS" | |
LIBS="$LIBS $GTK_LIBS" | |
cat > conftest.$ac_ext <<EOF | |
-#line 2264 "configure" | |
+#line 2279 "configure" | |
#include "confdefs.h" | |
#include <gtk/gtk.h> | |
t@@ -2270,7 +2285,7 @@ int main() { | |
return ((gtk_major_version) || (gtk_minor_version) || (gtk_micro_version)); | |
; return 0; } | |
EOF | |
-if { (eval echo configure:2274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:2289: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
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… | |
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+ ( >=… | |
CFLAGS="$CFLAGS `glib-config --cflags`" | |
LDFLAGS="$LDFLAGS `glib-config --libs`" | |
- GUI_SERVER="no" | |
+ if test "$GUI_SERVER" = "probe"; then | |
+ GUI_SERVER="no" | |
+ fi | |
echo $ac_n "checking for socklen_t data type""... $ac_c" 1>&6 | |
-echo "configure:2338: checking for socklen_t data type" >&5 | |
+echo "configure:2360: checking for socklen_t data type" >&5 | |
cat > conftest.$ac_ext <<EOF | |
-#line 2340 "configure" | |
+#line 2362 "configure" | |
#include "confdefs.h" | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
t@@ -2344,7 +2366,7 @@ int main() { | |
socklen_t val | |
; return 0; } | |
EOF | |
-if { (eval echo configure:2348: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
+if { (eval echo configure:2370: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
rm -rf conftest* | |
echo "$ac_t""yes" 1>&6 | |
cat >> confdefs.h <<\EOF | |
t@@ -2360,11 +2382,18 @@ fi | |
rm -f conftest* | |
fi | |
+if test "$GUI_CLIENT" = "probe"; then | |
+ GUI_CLIENT="yes" | |
+fi | |
+if test "$CURSES_CLIENT" = "probe"; then | |
+ CURSES_CLIENT="yes" | |
+fi | |
+ | |
ALL_LINGUAS="de pl pt_BR fr" | |
# Extract the first word of "ranlib", so it can be a program name with args. | |
set dummy ranlib; ac_word=$2 | |
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
-echo "configure:2368: checking for $ac_word" >&5 | |
+echo "configure:2397: checking for $ac_word" >&5 | |
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
t@@ -2392,12 +2421,12 @@ else | |
fi | |
echo $ac_n "checking for working const""... $ac_c" 1>&6 | |
-echo "configure:2396: checking for working const" >&5 | |
+echo "configure:2425: checking for working const" >&5 | |
if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 2401 "configure" | |
+#line 2430 "configure" | |
#include "confdefs.h" | |
int main() { | |
t@@ -2446,7 +2475,7 @@ ccp = (char const *const *) p; | |
; return 0; } | |
EOF | |
-if { (eval echo configure:2450: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
+if { (eval echo configure:2479: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
rm -rf conftest* | |
ac_cv_c_const=yes | |
else | |
t@@ -2467,21 +2496,21 @@ EOF | |
fi | |
echo $ac_n "checking for inline""... $ac_c" 1>&6 | |
-echo "configure:2471: checking for inline" >&5 | |
+echo "configure:2500: checking for inline" >&5 | |
if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
ac_cv_c_inline=no | |
for ac_kw in inline __inline__ __inline; do | |
cat > conftest.$ac_ext <<EOF | |
-#line 2478 "configure" | |
+#line 2507 "configure" | |
#include "confdefs.h" | |
int main() { | |
} $ac_kw foo() { | |
; return 0; } | |
EOF | |
-if { (eval echo configure:2485: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
+if { (eval echo configure:2514: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
rm -rf conftest* | |
ac_cv_c_inline=$ac_kw; break | |
else | |
t@@ -2507,12 +2536,12 @@ EOF | |
esac | |
echo $ac_n "checking for off_t""... $ac_c" 1>&6 | |
-echo "configure:2511: checking for off_t" >&5 | |
+echo "configure:2540: checking for off_t" >&5 | |
if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 2516 "configure" | |
+#line 2545 "configure" | |
#include "confdefs.h" | |
#include <sys/types.h> | |
#if STDC_HEADERS | |
t@@ -2540,12 +2569,12 @@ EOF | |
fi | |
echo $ac_n "checking for size_t""... $ac_c" 1>&6 | |
-echo "configure:2544: checking for size_t" >&5 | |
+echo "configure:2573: checking for size_t" >&5 | |
if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 2549 "configure" | |
+#line 2578 "configure" | |
#include "confdefs.h" | |
#include <sys/types.h> | |
#if STDC_HEADERS | |
t@@ -2575,19 +2604,19 @@ fi | |
# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works | |
# for constant arguments. Useless! | |
echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 | |
-echo "configure:2579: checking for working alloca.h" >&5 | |
+echo "configure:2608: checking for working alloca.h" >&5 | |
if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 2584 "configure" | |
+#line 2613 "configure" | |
#include "confdefs.h" | |
#include <alloca.h> | |
int main() { | |
char *p = alloca(2 * sizeof(int)); | |
; return 0; } | |
EOF | |
-if { (eval echo configure:2591: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:2620: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
ac_cv_header_alloca_h=yes | |
else | |
t@@ -2608,12 +2637,12 @@ EOF | |
fi | |
echo $ac_n "checking for alloca""... $ac_c" 1>&6 | |
-echo "configure:2612: checking for alloca" >&5 | |
+echo "configure:2641: checking for alloca" >&5 | |
if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 2617 "configure" | |
+#line 2646 "configure" | |
#include "confdefs.h" | |
#ifdef __GNUC__ | |
t@@ -2641,7 +2670,7 @@ int main() { | |
char *p = (char *) alloca(1); | |
; return 0; } | |
EOF | |
-if { (eval echo configure:2645: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:2674: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
ac_cv_func_alloca_works=yes | |
else | |
t@@ -2673,12 +2702,12 @@ EOF | |
echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 | |
-echo "configure:2677: checking whether alloca needs Cray hooks" >&5 | |
+echo "configure:2706: checking whether alloca needs Cray hooks" >&5 | |
if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 2682 "configure" | |
+#line 2711 "configure" | |
#include "confdefs.h" | |
#if defined(CRAY) && ! defined(CRAY2) | |
webecray | |
t@@ -2703,12 +2732,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6 | |
if test $ac_cv_os_cray = yes; then | |
for ac_func in _getb67 GETB67 getb67; do | |
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | |
-echo "configure:2707: checking for $ac_func" >&5 | |
+echo "configure:2736: checking for $ac_func" >&5 | |
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 2712 "configure" | |
+#line 2741 "configure" | |
#include "confdefs.h" | |
/* System header to define __stub macros and hopefully few prototypes, | |
which can conflict with char $ac_func(); below. */ | |
t@@ -2731,7 +2760,7 @@ $ac_func(); | |
; return 0; } | |
EOF | |
-if { (eval echo configure:2735: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:2764: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
eval "ac_cv_func_$ac_func=yes" | |
else | |
t@@ -2758,7 +2787,7 @@ done | |
fi | |
echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 | |
-echo "configure:2762: checking stack direction for C alloca" >&5 | |
+echo "configure:2791: checking stack direction for C alloca" >&5 | |
if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
t@@ -2766,7 +2795,7 @@ else | |
ac_cv_c_stack_direction=0 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 2770 "configure" | |
+#line 2799 "configure" | |
#include "confdefs.h" | |
find_stack_direction () | |
{ | |
t@@ -2785,7 +2814,7 @@ main () | |
exit (find_stack_direction() < 0); | |
} | |
EOF | |
-if { (eval echo configure:2789: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:2818: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
then | |
ac_cv_c_stack_direction=1 | |
else | |
t@@ -2806,21 +2835,21 @@ EOF | |
fi | |
-for ac_hdr in unistd.h | |
+for ac_hdr in stdlib.h unistd.h sys/stat.h sys/types.h | |
do | |
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` | |
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 | |
-echo "configure:2814: checking for $ac_hdr" >&5 | |
+echo "configure:2843: checking for $ac_hdr" >&5 | |
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 2819 "configure" | |
+#line 2848 "configure" | |
#include "confdefs.h" | |
#include <$ac_hdr> | |
EOF | |
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" | |
-{ (eval echo configure:2824: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
+{ (eval echo configure:2853: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` | |
if test -z "$ac_err"; then | |
rm -rf conftest* | |
t@@ -2849,12 +2878,12 @@ done | |
for ac_func in getpagesize | |
do | |
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | |
-echo "configure:2853: checking for $ac_func" >&5 | |
+echo "configure:2882: checking for $ac_func" >&5 | |
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 2858 "configure" | |
+#line 2887 "configure" | |
#include "confdefs.h" | |
/* System header to define __stub macros and hopefully few prototypes, | |
which can conflict with char $ac_func(); below. */ | |
t@@ -2877,7 +2906,7 @@ $ac_func(); | |
; return 0; } | |
EOF | |
-if { (eval echo configure:2881: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:2910: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
eval "ac_cv_func_$ac_func=yes" | |
else | |
t@@ -2902,7 +2931,7 @@ fi | |
done | |
echo $ac_n "checking for working mmap""... $ac_c" 1>&6 | |
-echo "configure:2906: checking for working mmap" >&5 | |
+echo "configure:2935: checking for working mmap" >&5 | |
if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
t@@ -2910,7 +2939,7 @@ else | |
ac_cv_func_mmap_fixed_mapped=no | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 2914 "configure" | |
+#line 2943 "configure" | |
#include "confdefs.h" | |
/* Thanks to Mike Haertel and Jim Avera for this test. | |
t@@ -2938,11 +2967,24 @@ else | |
#include <fcntl.h> | |
#include <sys/mman.h> | |
+#if HAVE_SYS_TYPES_H | |
+# include <sys/types.h> | |
+#endif | |
+ | |
+#if HAVE_STDLIB_H | |
+# include <stdlib.h> | |
+#endif | |
+ | |
+#if HAVE_SYS_STAT_H | |
+# include <sys/stat.h> | |
+#endif | |
+ | |
+#if HAVE_UNISTD_H | |
+# include <unistd.h> | |
+#endif | |
+ | |
/* This mess was copied from the GNU getpagesize.h. */ | |
#ifndef HAVE_GETPAGESIZE | |
-# ifdef HAVE_UNISTD_H | |
-# include <unistd.h> | |
-# endif | |
/* Assume that all systems that can run configure have sys/param.h. */ | |
# ifndef HAVE_SYS_PARAM_H | |
t@@ -3050,7 +3092,7 @@ main() | |
} | |
EOF | |
-if { (eval echo configure:3054: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:3096: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
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""… | |
-echo "configure:3078: checking whether we are using the GNU C Library 2.1 or n… | |
+echo "configure:3120: checking whether we are using the GNU C Library 2.1 or n… | |
if eval "test \"`echo '$''{'ac_cv_gnu_library_2_1'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 3083 "configure" | |
+#line 3125 "configure" | |
#include "confdefs.h" | |
#include <features.h> | |
t@@ -3115,17 +3157,17 @@ stdlib.h string.h unistd.h sys/param.h | |
do | |
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` | |
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 | |
-echo "configure:3119: checking for $ac_hdr" >&5 | |
+echo "configure:3161: checking for $ac_hdr" >&5 | |
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 3124 "configure" | |
+#line 3166 "configure" | |
#include "confdefs.h" | |
#include <$ac_hdr> | |
EOF | |
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" | |
-{ (eval echo configure:3129: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
+{ (eval echo configure:3171: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` | |
if test -z "$ac_err"; then | |
rm -rf conftest* | |
t@@ -3156,12 +3198,12 @@ getgid getuid mempcpy munmap putenv setenv setlocale s… | |
strdup strtoul tsearch __argz_count __argz_stringify __argz_next | |
do | |
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | |
-echo "configure:3160: checking for $ac_func" >&5 | |
+echo "configure:3202: checking for $ac_func" >&5 | |
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 3165 "configure" | |
+#line 3207 "configure" | |
#include "confdefs.h" | |
/* System header to define __stub macros and hopefully few prototypes, | |
which can conflict with char $ac_func(); below. */ | |
t@@ -3184,7 +3226,7 @@ $ac_func(); | |
; return 0; } | |
EOF | |
-if { (eval echo configure:3188: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:3230: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
eval "ac_cv_func_$ac_func=yes" | |
else | |
t@@ -3224,7 +3266,7 @@ fi | |
echo $ac_n "checking for iconv""... $ac_c" 1>&6 | |
-echo "configure:3228: checking for iconv" >&5 | |
+echo "configure:3270: checking for iconv" >&5 | |
if eval "test \"`echo '$''{'am_cv_func_iconv'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
t@@ -3232,7 +3274,7 @@ else | |
am_cv_func_iconv="no, consider installing GNU libiconv" | |
am_cv_lib_iconv=no | |
cat > conftest.$ac_ext <<EOF | |
-#line 3236 "configure" | |
+#line 3278 "configure" | |
#include "confdefs.h" | |
#include <stdlib.h> | |
#include <iconv.h> | |
t@@ -3242,7 +3284,7 @@ iconv_t cd = iconv_open("",""); | |
iconv_close(cd); | |
; return 0; } | |
EOF | |
-if { (eval echo configure:3246: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:3288: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
am_cv_func_iconv=yes | |
else | |
t@@ -3254,7 +3296,7 @@ rm -f conftest* | |
am_save_LIBS="$LIBS" | |
LIBS="$LIBS -liconv" | |
cat > conftest.$ac_ext <<EOF | |
-#line 3258 "configure" | |
+#line 3300 "configure" | |
#include "confdefs.h" | |
#include <stdlib.h> | |
#include <iconv.h> | |
t@@ -3264,7 +3306,7 @@ iconv_t cd = iconv_open("",""); | |
iconv_close(cd); | |
; return 0; } | |
EOF | |
-if { (eval echo configure:3268: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:3310: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
am_cv_lib_iconv=yes | |
am_cv_func_iconv=yes | |
t@@ -3285,13 +3327,13 @@ echo "$ac_t""$am_cv_func_iconv" 1>&6 | |
EOF | |
echo $ac_n "checking for iconv declaration""... $ac_c" 1>&6 | |
-echo "configure:3289: checking for iconv declaration" >&5 | |
+echo "configure:3331: checking for iconv declaration" >&5 | |
if eval "test \"`echo '$''{'am_cv_proto_iconv'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 3295 "configure" | |
+#line 3337 "configure" | |
#include "confdefs.h" | |
#include <stdlib.h> | |
t@@ -3310,7 +3352,7 @@ int main() { | |
; return 0; } | |
EOF | |
-if { (eval echo configure:3314: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
+if { (eval echo configure:3356: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
rm -rf conftest* | |
am_cv_proto_iconv_arg1="" | |
else | |
t@@ -3339,19 +3381,19 @@ EOF | |
echo $ac_n "checking for nl_langinfo and CODESET""... $ac_c" 1>&6 | |
-echo "configure:3343: checking for nl_langinfo and CODESET" >&5 | |
+echo "configure:3385: checking for nl_langinfo and CODESET" >&5 | |
if eval "test \"`echo '$''{'am_cv_langinfo_codeset'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 3348 "configure" | |
+#line 3390 "configure" | |
#include "confdefs.h" | |
#include <langinfo.h> | |
int main() { | |
char* cs = nl_langinfo(CODESET); | |
; return 0; } | |
EOF | |
-if { (eval echo configure:3355: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:3397: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
am_cv_langinfo_codeset=yes | |
else | |
t@@ -3374,19 +3416,19 @@ EOF | |
if test $ac_cv_header_locale_h = yes; then | |
echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6 | |
-echo "configure:3378: checking for LC_MESSAGES" >&5 | |
+echo "configure:3420: checking for LC_MESSAGES" >&5 | |
if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 3383 "configure" | |
+#line 3425 "configure" | |
#include "confdefs.h" | |
#include <locale.h> | |
int main() { | |
return LC_MESSAGES | |
; return 0; } | |
EOF | |
-if { (eval echo configure:3390: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:3432: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
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… | |
-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 wa… | |
if test "${with_included_gettext+set}" = set; then | |
withval="$with_included_gettext" | |
t@@ -3449,17 +3491,17 @@ fi | |
ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'` | |
echo $ac_n "checking for libintl.h""... $ac_c" 1>&6 | |
-echo "configure:3453: checking for libintl.h" >&5 | |
+echo "configure:3495: checking for libintl.h" >&5 | |
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 3458 "configure" | |
+#line 3500 "configure" | |
#include "confdefs.h" | |
#include <libintl.h> | |
EOF | |
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" | |
-{ (eval echo configure:3463: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
+{ (eval echo configure:3505: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` | |
if test -z "$ac_err"; then | |
rm -rf conftest* | |
t@@ -3476,12 +3518,12 @@ fi | |
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then | |
echo "$ac_t""yes" 1>&6 | |
echo $ac_n "checking for GNU gettext in libc""... $ac_c" 1>&6 | |
-echo "configure:3480: checking for GNU gettext in libc" >&5 | |
+echo "configure:3522: checking for GNU gettext in libc" >&5 | |
if eval "test \"`echo '$''{'gt_cv_func_gnugettext1_libc'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 3485 "configure" | |
+#line 3527 "configure" | |
#include "confdefs.h" | |
#include <libintl.h> | |
extern int _nl_msg_cat_cntr; | |
t@@ -3490,7 +3532,7 @@ bindtextdomain ("", ""); | |
return (int) gettext ("") + _nl_msg_cat_cntr | |
; return 0; } | |
EOF | |
-if { (eval echo configure:3494: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:3536: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
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"; t… | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
gt_save_LIBS="$LIBS" | |
LIBS="$LIBS -lintl $LIBICONV" | |
cat > conftest.$ac_ext <<EOF | |
-#line 3517 "configure" | |
+#line 3559 "configure" | |
#include "confdefs.h" | |
#include <libintl.h> | |
extern int _nl_msg_cat_cntr; | |
t@@ -3522,7 +3564,7 @@ bindtextdomain ("", ""); | |
return (int) gettext ("") + _nl_msg_cat_cntr | |
; return 0; } | |
EOF | |
-if { (eval echo configure:3526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:3568: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
gt_cv_func_gnugettext1_libintl=yes | |
else | |
t@@ -3555,12 +3597,12 @@ EOF | |
for ac_func in dcgettext | |
do | |
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | |
-echo "configure:3559: checking for $ac_func" >&5 | |
+echo "configure:3601: checking for $ac_func" >&5 | |
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 3564 "configure" | |
+#line 3606 "configure" | |
#include "confdefs.h" | |
/* System header to define __stub macros and hopefully few prototypes, | |
which can conflict with char $ac_func(); below. */ | |
t@@ -3583,7 +3625,7 @@ $ac_func(); | |
; return 0; } | |
EOF | |
-if { (eval echo configure:3587: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:3629: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
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… | |
+ # Extract the first word of "msgfmt", so it can be a program name… | |
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 nam… | |
+ if test "$MSGFMT" != "no"; then | |
+ # Extract the first word of "gmsgfmt", so it can be a program n… | |
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… | |
+ # Extract the first word of "xgettext", so it can be a program na… | |
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… | |
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 wit… | |
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 wi… | |
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; th… | |
- : ; | |
- 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; … | |
+ 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" … | |
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.* \(… | |
+echo "configure:3945: checking version of bison" >&5 | |
+ ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison .* \… | |
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 instal… | |
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" … | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 4055 "configure" | |
+#line 4075 "configure" | |
#include "confdefs.h" | |
#include <stdio.h> | |
-main() | |
+int main() | |
{ | |
FILE *f=fopen("conftestval", "w"); | |
- if (!f) exit(1); | |
+ if (!f) return(1); | |
fprintf(f, "%d\n", sizeof(long long)); | |
- exit(0); | |
+ return(0); | |
} | |
EOF | |
-if { (eval echo configure:4066: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:4086: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
then | |
ac_cv_sizeof_long_long=`cat conftestval` | |
else | |
t@@ -4083,7 +4103,7 @@ EOF | |
echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 | |
-echo "configure:4087: checking for 8-bit clean memcmp" >&5 | |
+echo "configure:4107: checking for 8-bit clean memcmp" >&5 | |
if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
t@@ -4091,7 +4111,7 @@ else | |
ac_cv_func_memcmp_clean=no | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 4095 "configure" | |
+#line 4115 "configure" | |
#include "confdefs.h" | |
main() | |
t@@ -4101,7 +4121,7 @@ main() | |
} | |
EOF | |
-if { (eval echo configure:4105: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:4125: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
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" … | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 4131 "configure" | |
+#line 4151 "configure" | |
#include "confdefs.h" | |
#include <stdio.h> | |
/* If setvbuf has the reversed format, exit 0. */ | |
t@@ -4141,7 +4161,7 @@ main () { | |
exit(0); /* Non-reversed systems segv here. */ | |
} | |
EOF | |
-if { (eval echo configure:4145: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:4165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
then | |
ac_cv_func_setvbuf_reversed=yes | |
else | |
t@@ -4165,12 +4185,12 @@ EOF | |
fi | |
echo $ac_n "checking for strftime""... $ac_c" 1>&6 | |
-echo "configure:4169: checking for strftime" >&5 | |
+echo "configure:4189: checking for strftime" >&5 | |
if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 4174 "configure" | |
+#line 4194 "configure" | |
#include "confdefs.h" | |
/* System header to define __stub macros and hopefully few prototypes, | |
which can conflict with char strftime(); below. */ | |
t@@ -4193,7 +4213,7 @@ strftime(); | |
; return 0; } | |
EOF | |
-if { (eval echo configure:4197: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:4217: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
eval "ac_cv_func_strftime=yes" | |
else | |
t@@ -4215,7 +4235,7 @@ else | |
echo "$ac_t""no" 1>&6 | |
# strftime is in -lintl on SCO UNIX. | |
echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6 | |
-echo "configure:4219: checking for strftime in -lintl" >&5 | |
+echo "configure:4239: checking for strftime in -lintl" >&5 | |
ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'` | |
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
t@@ -4223,7 +4243,7 @@ else | |
ac_save_LIBS="$LIBS" | |
LIBS="-lintl $LIBS" | |
cat > conftest.$ac_ext <<EOF | |
-#line 4227 "configure" | |
+#line 4247 "configure" | |
#include "confdefs.h" | |
/* Override any gcc2 internal prototype to avoid an error. */ | |
/* We use char because int might match the return type of a gcc2 | |
t@@ -4234,7 +4254,7 @@ int main() { | |
strftime() | |
; return 0; } | |
EOF | |
-if { (eval echo configure:4238: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:4258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
eval "ac_cv_lib_$ac_lib_var=yes" | |
else | |
t@@ -4263,12 +4283,12 @@ fi | |
for ac_func in strdup strstr getopt_long fork | |
do | |
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | |
-echo "configure:4267: checking for $ac_func" >&5 | |
+echo "configure:4287: checking for $ac_func" >&5 | |
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 4272 "configure" | |
+#line 4292 "configure" | |
#include "confdefs.h" | |
/* System header to define __stub macros and hopefully few prototypes, | |
which can conflict with char $ac_func(); below. */ | |
t@@ -4291,7 +4311,7 @@ $ac_func(); | |
; return 0; } | |
EOF | |
-if { (eval echo configure:4295: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:4315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
eval "ac_cv_func_$ac_func=yes" | |
else | |
t@@ -4322,14 +4342,14 @@ if test "$CYGWIN" = "yes" ; then | |
else | |
echo $ac_n "checking for library containing socket""... $ac_c" 1>&6 | |
-echo "configure:4326: checking for library containing socket" >&5 | |
+echo "configure:4346: checking for library containing socket" >&5 | |
if eval "test \"`echo '$''{'ac_cv_search_socket'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
ac_func_search_save_LIBS="$LIBS" | |
ac_cv_search_socket="no" | |
cat > conftest.$ac_ext <<EOF | |
-#line 4333 "configure" | |
+#line 4353 "configure" | |
#include "confdefs.h" | |
/* Override any gcc2 internal prototype to avoid an error. */ | |
/* We use char because int might match the return type of a gcc2 | |
t@@ -4340,7 +4360,7 @@ int main() { | |
socket() | |
; return 0; } | |
EOF | |
-if { (eval echo configure:4344: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:4364: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
ac_cv_search_socket="none required" | |
else | |
t@@ -4351,7 +4371,7 @@ rm -f conftest* | |
test "$ac_cv_search_socket" = "no" && for i in socket; do | |
LIBS="-l$i $ac_func_search_save_LIBS" | |
cat > conftest.$ac_ext <<EOF | |
-#line 4355 "configure" | |
+#line 4375 "configure" | |
#include "confdefs.h" | |
/* Override any gcc2 internal prototype to avoid an error. */ | |
/* We use char because int might match the return type of a gcc2 | |
t@@ -4362,7 +4382,7 @@ int main() { | |
socket() | |
; return 0; } | |
EOF | |
-if { (eval echo configure:4366: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:4386: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
ac_cv_search_socket="-l$i" | |
break | |
t@@ -4384,14 +4404,14 @@ else : | |
fi | |
echo $ac_n "checking for library containing gethostbyname""... $ac_c" 1>&6 | |
-echo "configure:4388: checking for library containing gethostbyname" >&5 | |
+echo "configure:4408: checking for library containing gethostbyname" >&5 | |
if eval "test \"`echo '$''{'ac_cv_search_gethostbyname'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
ac_func_search_save_LIBS="$LIBS" | |
ac_cv_search_gethostbyname="no" | |
cat > conftest.$ac_ext <<EOF | |
-#line 4395 "configure" | |
+#line 4415 "configure" | |
#include "confdefs.h" | |
/* Override any gcc2 internal prototype to avoid an error. */ | |
/* We use char because int might match the return type of a gcc2 | |
t@@ -4402,7 +4422,7 @@ int main() { | |
gethostbyname() | |
; return 0; } | |
EOF | |
-if { (eval echo configure:4406: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:4426: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
ac_cv_search_gethostbyname="none required" | |
else | |
t@@ -4413,7 +4433,7 @@ rm -f conftest* | |
test "$ac_cv_search_gethostbyname" = "no" && for i in nsl socket; do | |
LIBS="-l$i $ac_func_search_save_LIBS" | |
cat > conftest.$ac_ext <<EOF | |
-#line 4417 "configure" | |
+#line 4437 "configure" | |
#include "confdefs.h" | |
/* Override any gcc2 internal prototype to avoid an error. */ | |
/* We use char because int might match the return type of a gcc2 | |
t@@ -4424,7 +4444,7 @@ int main() { | |
gethostbyname() | |
; return 0; } | |
EOF | |
-if { (eval echo configure:4428: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:4448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
ac_cv_search_gethostbyname="-l$i" | |
break | |
t@@ -4447,12 +4467,12 @@ fi | |
for ac_func in socket gethostbyname select | |
do | |
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | |
-echo "configure:4451: checking for $ac_func" >&5 | |
+echo "configure:4471: checking for $ac_func" >&5 | |
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then | |
echo $ac_n "(cached) $ac_c" 1>&6 | |
else | |
cat > conftest.$ac_ext <<EOF | |
-#line 4456 "configure" | |
+#line 4476 "configure" | |
#include "confdefs.h" | |
/* System header to define __stub macros and hopefully few prototypes, | |
which can conflict with char $ac_func(); below. */ | |
t@@ -4475,7 +4495,7 @@ $ac_func(); | |
; return 0; } | |
EOF | |
-if { (eval echo configure:4479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+if { (eval echo configure:4499: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
rm -rf conftest* | |
eval "ac_cv_func_$ac_func=yes" | |
else | |
t@@ -4539,6 +4559,35 @@ fi | |
CFLAGS="$CFLAGS -DDATADIR=\\\"${datadir}\\\"" | |
+ | |
+ | |
+if test "$GUI_CLIENT" = "yes"; then | |
+ GUI_CLIENT_TRUE= | |
+ GUI_CLIENT_FALSE='#' | |
+else | |
+ GUI_CLIENT_TRUE='#' | |
+ GUI_CLIENT_FALSE= | |
+fi | |
+ | |
+ | |
+if test "$CURSES_CLIENT" = "yes"; then | |
+ CURSES_CLIENT_TRUE= | |
+ CURSES_CLIENT_FALSE='#' | |
+else | |
+ CURSES_CLIENT_TRUE='#' | |
+ CURSES_CLIENT_FALSE= | |
+fi | |
+ | |
+ | |
+ | |
+if test "$GUI_CLIENT" = "yes" -o "$GUI_SERVER" = "yes"; then | |
+ GTKPORT_TRUE= | |
+ GTKPORT_FALSE='#' | |
+else | |
+ GTKPORT_TRUE='#' | |
+ GTKPORT_FALSE= | |
+fi | |
+ | |
trap '' 1 2 15 | |
cat > confcache <<\EOF | |
# This file is a shell script that caches the results of configure | |
t@@ -4643,6 +4692,9 @@ ac_given_INSTALL="$INSTALL" | |
trap 'rm -fr `echo " | |
Makefile | |
src/Makefile | |
+src/gui_client/Makefile | |
+src/curses_client/Makefile | |
+src/gtkport/Makefile | |
doc/Makefile | |
intl/Makefile | |
po/Makefile.in config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 | |
t@@ -4726,9 +4778,13 @@ s%@GENCAT@%$GENCAT%g | |
s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g | |
s%@INTL_LIBTOOL_SUFFIX_PREFIX@%$INTL_LIBTOOL_SUFFIX_PREFIX%g | |
s%@localedir@%$localedir%g | |
-s%@GTKPORT_C@%$GTKPORT_C%g | |
-s%@GTKPORT_O@%$GTKPORT_O%g | |
s%@LIBOBJS@%$LIBOBJS%g | |
+s%@GUI_CLIENT_TRUE@%$GUI_CLIENT_TRUE%g | |
+s%@GUI_CLIENT_FALSE@%$GUI_CLIENT_FALSE%g | |
+s%@CURSES_CLIENT_TRUE@%$CURSES_CLIENT_TRUE%g | |
+s%@CURSES_CLIENT_FALSE@%$CURSES_CLIENT_FALSE%g | |
+s%@GTKPORT_TRUE@%$GTKPORT_TRUE%g | |
+s%@GTKPORT_FALSE@%$GTKPORT_FALSE%g | |
CEOF | |
EOF | |
t@@ -4772,6 +4828,9 @@ cat >> $CONFIG_STATUS <<EOF | |
CONFIG_FILES=\${CONFIG_FILES-"Makefile | |
src/Makefile | |
+src/gui_client/Makefile | |
+src/curses_client/Makefile | |
+src/gtkport/Makefile | |
doc/Makefile | |
intl/Makefile | |
po/Makefile.in"} | |
t@@ -4959,9 +5018,6 @@ for ac_file in $CONFIG_FILES; do | |
ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` | |
ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" | |
ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` | |
- # In autoconf-2.13 it is called $ac_given_srcdir. | |
- # In autoconf-2.50 it is called $srcdir. | |
- test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" | |
case "$ac_given_srcdir" in | |
.) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; | |
/*) top_srcdir="$ac_given_srcdir" ;; | |
t@@ -4969,9 +5025,9 @@ for ac_file in $CONFIG_FILES; do | |
esac | |
if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then | |
rm -f "$ac_dir/POTFILES" | |
- test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || ec… | |
+ echo creating "$ac_dir/POTFILES" | |
sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/&… | |
- test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || ec… | |
+ echo creating "$ac_dir/Makefile" | |
sed -e "/POTFILES =/r $ac_dir/POTFILES" "$ac_dir/Makefile.in" > "$… | |
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 cl… | |
+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) $(GTKPORTDE… | |
+dopewars_LDADD = $(GUIDEP) $(CURSESDEP) $(GTKPORTDEP) @GTK_LIBS@ @INTLLIBS@ @W… | |
+ | |
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/libcursescli… | |
+ | |
+@GTKPORT_TRUE@GTKPORTSUBDIR = @GTKPORT_TRUE@gtkport | |
+@GTKPORT_TRUE@GTKPORTDEP = @GTKPORT_TRUE@gtkport/libgtkport.a | |
+ | |
+SUBDIRS = $(GUISUBDIR) $(CURSESSUBDIR) $(GTKPORTSUBDIR) | |
+dopewars_DEPENDENCIES = @INTLLIBS@ @WNDRES@ $(GUIDEP) $(CURSESDEP) $(GTKPORTDE… | |
+dopewars_LDADD = $(GUIDEP) $(CURSESDEP) $(GTKPORTDEP) @GTK_LIBS@ @INTLLIBS@ @W… | |
+ | |
bin_PROGRAMS = dopewars | |
-dopewars_SOURCES = admin.c AIPlayer.c curses_client.c dopeos.c dopewars.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) $(… | |
t@@ -130,10 +140,10 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXIN… | |
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) $(LI… | |
+# 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_distd… | |
+ || 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: [email protected] * | |
- * WWW: http://dopewars.sourceforge.net/ * | |
- * * | |
- * This program is free software; you can redistribute it and/or * | |
- * modify it under the terms of the GNU General Public License * | |
- * as published by the Free Software Foundation; either version 2 * | |
- * of the License, or (at your option) any later version. * | |
- * * | |
- * This program is distributed in the hope that it will be useful, * | |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
- * GNU General Public License for more details. * | |
- * * | |
- * You should have received a copy of the GNU General Public License * | |
- * along with this program; if not, write to the Free Software * | |
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * | |
- * MA 02111-1307, USA. * | |
- ************************************************************************/ | |
- | |
-#ifdef HAVE_CONFIG_H | |
-#include <config.h> | |
-#endif | |
- | |
-#ifdef CURSES_CLIENT | |
- | |
-#include <string.h> | |
-#include <stdlib.h> | |
-#include <sys/types.h> | |
-#ifdef HAVE_UNISTD_H | |
-#include <unistd.h> | |
-#endif | |
-#include <ctype.h> | |
-#include <signal.h> | |
-#include <errno.h> | |
-#include <glib.h> | |
-#include "curses_client.h" | |
-#include "dopeos.h" | |
-#include "dopewars.h" | |
-#include "message.h" | |
-#include "nls.h" | |
-#include "serverside.h" | |
-#include "tstring.h" | |
- | |
-static void PrepareHighScoreScreen(void); | |
-static void PrintHighScore(char *Data); | |
- | |
-static int ResizedFlag; | |
-static SCREEN *cur_screen; | |
- | |
-#ifdef NETWORKING | |
-static enum { | |
- CM_SERVER, CM_PROMPT, CM_META, CM_SINGLE | |
-} ConnectMethod = CM_SERVER; | |
-#endif | |
- | |
-static gboolean CanFire = FALSE, RunHere = FALSE; | |
-static FightPoint fp; | |
- | |
-/* Function definitions; make them static so as not to clash with | |
- * functions of the same name in different clients */ | |
-static void display_intro(void); | |
-static void ResizeHandle(int sig); | |
-static void CheckForResize(Player *Play); | |
-static int GetKey(char *allowed, char *orig_allowed, gboolean AllowOther, | |
- gboolean PrintAllowed, gboolean ExpandOut); | |
-static void clear_bottom(void), clear_screen(void); | |
-static void clear_line(int line), clear_exceptfor(int skip); | |
-static void nice_wait(void); | |
-static void DisplayFightMessage(Player *Play, char *text); | |
-static void DisplaySpyReports(char *Data, Player *From, Player *To); | |
-static void display_message(char *buf); | |
-static void print_location(char *text); | |
-static void print_status(Player *Play, gboolean DispDrug); | |
-static char *nice_input(char *prompt, int sy, int sx, gboolean digitsonly, | |
- char *displaystr, char passwdchar); | |
-static Player *ListPlayers(Player *Play, gboolean Select, char *Prompt); | |
-static void HandleClientMessage(char *buf, Player *Play); | |
-static void PrintMessage(const gchar *text); | |
-static void GunShop(Player *Play); | |
-static void LoanShark(Player *Play); | |
-static void Bank(Player *Play); | |
- | |
-#ifdef NETWORKING | |
-static void HttpAuthFunc(HttpConnection *conn, gboolean proxyauth, | |
- gchar *realm, gpointer data); | |
-static void SocksAuthFunc(NetworkBuffer *netbuf, gpointer data); | |
-#endif | |
- | |
-static DispMode DisplayMode; | |
-static gboolean QuitRequest; | |
- | |
-/* | |
- * Initialises the curses library for accessing the screen. | |
- */ | |
-static void start_curses(void) | |
-{ | |
- cur_screen = newterm(NULL, stdout, stdin); | |
- if (WantColour) { | |
- start_color(); | |
- init_pair(1, COLOR_MAGENTA, COLOR_WHITE); | |
- init_pair(2, COLOR_BLACK, COLOR_WHITE); | |
- init_pair(3, COLOR_BLACK, COLOR_WHITE); | |
- init_pair(4, COLOR_BLUE, COLOR_WHITE); | |
- init_pair(5, COLOR_WHITE, COLOR_BLUE); | |
- init_pair(6, COLOR_RED, COLOR_WHITE); | |
- } | |
- cbreak(); | |
- noecho(); | |
- nodelay(stdscr, FALSE); | |
- keypad(stdscr, TRUE); | |
- curs_set(0); | |
-} | |
- | |
-/* | |
- * Shuts down the curses screen library. | |
- */ | |
-static void end_curses(void) | |
-{ | |
- keypad(stdscr, FALSE); | |
- curs_set(1); | |
- erase(); | |
- refresh(); | |
- endwin(); | |
-} | |
- | |
-/* | |
- * Handles a SIGWINCH signal, which is sent to indicate that the | |
- * size of the curses screen has changed. | |
- */ | |
-void ResizeHandle(int sig) | |
-{ | |
- ResizedFlag = 1; | |
-} | |
- | |
-/* | |
- * Checks to see if the curses window needs to be resized - i.e. if a | |
- * SIGWINCH signal has been received. | |
- */ | |
-void CheckForResize(Player *Play) | |
-{ | |
- sigset_t sigset; | |
- | |
- sigemptyset(&sigset); | |
- sigaddset(&sigset, SIGWINCH); | |
- sigprocmask(SIG_BLOCK, &sigset, NULL); | |
- if (ResizedFlag) { | |
- ResizedFlag = 0; | |
- end_curses(); | |
- start_curses(); | |
- Width = COLS; | |
- Depth = LINES; | |
- attrset(TextAttr); | |
- clear_screen(); | |
- display_message(""); | |
- DisplayFightMessage(Play, ""); | |
- print_status(Play, TRUE); | |
- } | |
- sigprocmask(SIG_UNBLOCK, &sigset, NULL); | |
-} | |
- | |
-static void LogMessage(const gchar *log_domain, GLogLevelFlags log_level, | |
- const gchar *message, gpointer user_data) | |
-{ | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- PrintMessage(message); | |
- nice_wait(); | |
- attrset(TextAttr); | |
- clear_bottom(); | |
-} | |
- | |
-/* | |
- * Displays a dopewars introduction screen. | |
- */ | |
-void display_intro(void) | |
-{ | |
- GString *text; | |
- | |
- attrset(TextAttr); | |
- clear_screen(); | |
- attrset(TitleAttr); | |
- | |
- /* Curses client introduction screen */ | |
- text = g_string_new(_("D O P E W A R S")); | |
- mvaddstr(1, (Width - text->len) / 2, text->str); | |
- | |
- attrset(TextAttr); | |
- | |
- mvaddstr(3, 1, _("Based on John E. Dell's old Drug Wars game, dopewars " | |
- "is a simulation of an")); | |
- mvaddstr(4, 1, _("imaginary drug market. dopewars is an All-American " | |
- "game which features")); | |
- mvaddstr(5, 1, _("buying, selling, and trying to get past the cops!")); | |
- | |
- mvaddstr(7, 1, _("The first thing you need to do is pay off your " | |
- "debt to the Loan Shark. After")); | |
- mvaddstr(8, 1, _("that, your goal is to make as much money as " | |
- "possible (and stay alive)! You")); | |
- mvaddstr(9, 1, _("have one month of game time to make your fortune.")); | |
- | |
- mvaddstr(11, 18, _("Copyright (C) 1998-2002 Ben Webb " | |
- "[email protected]")); | |
- g_string_sprintf(text, _("Version %s"), VERSION); | |
- mvaddstr(11, 2, text->str); | |
- g_string_assign(text, _("dopewars is released under the GNU " | |
- "General Public Licence")); | |
- mvaddstr(12, (Width - text->len) / 2, text->str); | |
- | |
- mvaddstr(14, 7, _("Icons and Graphics Ocelot Mantis")); | |
- mvaddstr(15, 7, _("Drug Dealing and Research Dan Wolf")); | |
- mvaddstr(16, 7, _("Play Testing Phil Davis " | |
- "Owen Walsh")); | |
- mvaddstr(17, 7, _("Extensive Play Testing Katherine Holt " | |
- "Caroline Moore")); | |
- mvaddstr(18, 7, _("Constructive Criticism Andrea Elliot-Smith " | |
- "Pete Winn")); | |
- mvaddstr(19, 7, _("Unconstructive Criticism James Matthews")); | |
- | |
- mvaddstr(21, 3, _("For information on the command line options, type " | |
- "dopewars -h at your")); | |
- mvaddstr(22, 1, | |
- _("Unix prompt. This will display a help screen, listing " | |
- "the available options.")); | |
- | |
- g_string_free(text, TRUE); | |
- nice_wait(); | |
- attrset(TextAttr); | |
- clear_screen(); | |
- refresh(); | |
-} | |
- | |
-#ifdef NETWORKING | |
-/* | |
- * Prompts the user to enter a server name and port to connect to. | |
- */ | |
-static void SelectServerManually(void) | |
-{ | |
- gchar *text, *PortText; | |
- | |
- if (ServerName[0] == '(') | |
- AssignName(&ServerName, "localhost"); | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- mvaddstr(17, 1, | |
- /* Prompts for hostname and port when selecting a server | |
- * manually */ | |
- _("Please enter the hostname and port of a dopewars server:-")); | |
- text = nice_input(_("Hostname: "), 18, 1, FALSE, ServerName, '\0'); | |
- AssignName(&ServerName, text); | |
- g_free(text); | |
- PortText = g_strdup_printf("%d", Port); | |
- text = nice_input(_("Port: "), 19, 1, TRUE, PortText, '\0'); | |
- Port = atoi(text); | |
- g_free(text); | |
- g_free(PortText); | |
-} | |
- | |
-/* | |
- * Contacts the dopewars metaserver, and obtains a list of valid | |
- * server/port pairs, one of which the user should select. | |
- * Returns TRUE on success; on failure FALSE is returned, and | |
- * errstr is assigned an error message. | |
- */ | |
-static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr) | |
-{ | |
- int c; | |
- GSList *ListPt; | |
- ServerData *ThisServer; | |
- GString *text; | |
- gint index; | |
- fd_set readfds, writefds; | |
- int maxsock; | |
- gboolean DoneOK; | |
- HttpConnection *MetaConn; | |
- | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- mvaddstr(17, 1, _("Please wait... attempting to contact metaserver...")); | |
- refresh(); | |
- | |
- if (OpenMetaHttpConnection(&MetaConn)) { | |
- SetHttpAuthFunc(MetaConn, HttpAuthFunc, NULL); | |
- SetNetworkBufferUserPasswdFunc(&MetaConn->NetBuf, SocksAuthFunc, NULL); | |
- } else { | |
- g_string_assign_error(errstr, MetaConn->NetBuf.error); | |
- CloseHttpConnection(MetaConn); | |
- return FALSE; | |
- } | |
- | |
- ClearServerList(&ServerList); | |
- | |
- do { | |
- FD_ZERO(&readfds); | |
- FD_ZERO(&writefds); | |
- FD_SET(0, &readfds); | |
- maxsock = 1; | |
- SetSelectForNetworkBuffer(&MetaConn->NetBuf, &readfds, &writefds, | |
- NULL, &maxsock); | |
- if (bselect(maxsock, &readfds, &writefds, NULL, NULL) == -1) { | |
- if (errno == EINTR) { | |
- CheckForResize(Play); | |
- continue; | |
- } | |
- perror("bselect"); | |
- exit(1); | |
- } | |
- if (FD_ISSET(0, &readfds)) { | |
- /* So that Ctrl-L works */ | |
- c = getch(); | |
-#ifndef CYGWIN | |
- if (c == '\f') | |
- wrefresh(curscr); | |
-#endif | |
- } | |
- if (RespondToSelect | |
- (&MetaConn->NetBuf, &readfds, &writefds, NULL, &DoneOK)) { | |
- while (HandleWaitingMetaServerData(MetaConn, &ServerList, &DoneOK)) { | |
- } | |
- } | |
- if (!DoneOK && HandleHttpCompletion(MetaConn)) { | |
- if (IsHttpError(MetaConn)) { | |
- g_string_assign_error(errstr, MetaConn->NetBuf.error); | |
- CloseHttpConnection(MetaConn); | |
- return FALSE; | |
- } | |
- } | |
- } while (DoneOK); | |
- CloseHttpConnection(MetaConn); | |
- | |
- text = g_string_new(""); | |
- | |
- ListPt = ServerList; | |
- while (ListPt) { | |
- ThisServer = (ServerData *)(ListPt->data); | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- /* Printout of metaserver information in curses client */ | |
- g_string_sprintf(text, _("Server : %s"), ThisServer->Name); | |
- mvaddstr(17, 1, text->str); | |
- g_string_sprintf(text, _("Port : %d"), ThisServer->Port); | |
- mvaddstr(18, 1, text->str); | |
- g_string_sprintf(text, _("Version : %s"), ThisServer->Version); | |
- mvaddstr(18, 40, text->str); | |
- if (ThisServer->CurPlayers == -1) { | |
- g_string_sprintf(text, _("Players: -unknown- (maximum %d)"), | |
- ThisServer->MaxPlayers); | |
- } else { | |
- g_string_sprintf(text, _("Players: %d (maximum %d)"), | |
- ThisServer->CurPlayers, ThisServer->MaxPlayers); | |
- } | |
- mvaddstr(19, 1, text->str); | |
- g_string_sprintf(text, _("Up since : %s"), ThisServer->UpSince); | |
- mvaddstr(19, 40, text->str); | |
- g_string_sprintf(text, _("Comment: %s"), ThisServer->Comment); | |
- mvaddstr(20, 1, text->str); | |
- attrset(PromptAttr); | |
- mvaddstr(23, 1, | |
- _("N>ext server; P>revious server; S>elect this server... ")); | |
- | |
- /* The three keys that are valid responses to the previous question - | |
- * if you translate them, keep the keys in the same order (N>ext, | |
- * P>revious, S>elect) as they are here, otherwise they'll do the | |
- * wrong things. */ | |
- c = GetKey(_("NPS"), "NPS", FALSE, FALSE, FALSE); | |
- switch (c) { | |
- case 'S': | |
- AssignName(&ServerName, ThisServer->Name); | |
- Port = ThisServer->Port; | |
- ListPt = NULL; | |
- break; | |
- case 'N': | |
- ListPt = g_slist_next(ListPt); | |
- if (!ListPt) | |
- ListPt = ServerList; | |
- break; | |
- case 'P': | |
- index = g_slist_position(ServerList, ListPt) - 1; | |
- if (index >= 0) | |
- ListPt = g_slist_nth(ServerList, (guint)index); | |
- else | |
- ListPt = g_slist_last(ListPt); | |
- break; | |
- } | |
- } | |
- if (!ServerList) { | |
- g_string_assign(errstr, "No servers listed on metaserver"); | |
- return FALSE; | |
- } | |
- clear_line(17); | |
- refresh(); | |
- g_string_free(text, TRUE); | |
- return TRUE; | |
-} | |
- | |
-static void DisplayConnectStatus(NetworkBuffer *netbuf, | |
- NBStatus oldstatus, | |
- NBSocksStatus oldsocks) | |
-{ | |
- NBStatus status; | |
- NBSocksStatus sockstat; | |
- GString *text; | |
- | |
- status = netbuf->status; | |
- sockstat = netbuf->sockstat; | |
- | |
- if (oldstatus == status && oldsocks == sockstat) | |
- return; | |
- | |
- text = g_string_new(""); | |
- | |
- switch (status) { | |
- case NBS_PRECONNECT: | |
- break; | |
- case NBS_SOCKSCONNECT: | |
- switch (sockstat) { | |
- case NBSS_METHODS: | |
- g_string_sprintf(text, _("Connected to SOCKS server %s..."), | |
- Socks.name); | |
- break; | |
- case NBSS_USERPASSWD: | |
- g_string_assign(text, _("Authenticating with SOCKS server")); | |
- break; | |
- case NBSS_CONNECT: | |
- g_string_sprintf(text, _("Asking SOCKS for connect to %s..."), | |
- ServerName); | |
- break; | |
- } | |
- break; | |
- case NBS_CONNECTED: | |
- break; | |
- } | |
- if (text->str[0]) { | |
- mvaddstr(17, 1, text->str); | |
- refresh(); | |
- } | |
- g_string_free(text, TRUE); | |
-} | |
- | |
-void HttpAuthFunc(HttpConnection *conn, gboolean proxyauth, | |
- gchar *realm, gpointer data) | |
-{ | |
- gchar *text, *user, *password = NULL; | |
- | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- if (proxyauth) { | |
- text = g_strdup_printf(_("Proxy authentication required for realm %s"), | |
- realm); | |
- } else { | |
- text = | |
- g_strdup_printf(_("Authentication required for realm %s"), realm); | |
- } | |
- mvaddstr(17, 1, text); | |
- mvaddstr(18, 1, _("(Enter a blank username to cancel)")); | |
- g_free(text); | |
- | |
- user = nice_input(_("User name: "), 19, 1, FALSE, NULL, '\0'); | |
- if (user && user[0]) { | |
- password = nice_input(_("Password: "), 20, 1, FALSE, NULL, '*'); | |
- } | |
- | |
- SetHttpAuthentication(conn, proxyauth, user, password); | |
- g_free(user); | |
- g_free(password); | |
-} | |
- | |
-void SocksAuthFunc(NetworkBuffer *netbuf, gpointer data) | |
-{ | |
- gchar *user, *password = NULL; | |
- | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- mvaddstr(17, 1, _("SOCKS authentication required (enter a blank " | |
- "username to cancel)")); | |
- | |
- user = nice_input(_("User name: "), 18, 1, FALSE, NULL, '\0'); | |
- if (user && user[0]) { | |
- password = nice_input(_("Password: "), 19, 1, FALSE, NULL, '*'); | |
- } | |
- | |
- SendSocks5UserPasswd(netbuf, user, password); | |
- g_free(user); | |
- g_free(password); | |
-} | |
- | |
-static gboolean DoConnect(Player *Play, GString *errstr) | |
-{ | |
- NetworkBuffer *netbuf; | |
- fd_set readfds, writefds; | |
- int maxsock, c; | |
- gboolean doneOK = TRUE; | |
- NBStatus oldstatus; | |
- NBSocksStatus oldsocks; | |
- | |
- netbuf = &Play->NetBuf; | |
- oldstatus = netbuf->status; | |
- oldsocks = netbuf->sockstat; | |
- | |
- if (!StartNetworkBufferConnect(netbuf, ServerName, Port)) { | |
- doneOK = FALSE; | |
- } else { | |
- SetNetworkBufferUserPasswdFunc(netbuf, SocksAuthFunc, NULL); | |
- while (netbuf->status != NBS_CONNECTED) { | |
- DisplayConnectStatus(netbuf, oldstatus, oldsocks); | |
- oldstatus = netbuf->status; | |
- oldsocks = netbuf->sockstat; | |
- FD_ZERO(&readfds); | |
- FD_ZERO(&writefds); | |
- FD_SET(0, &readfds); | |
- maxsock = 1; | |
- SetSelectForNetworkBuffer(netbuf, &readfds, &writefds, NULL, | |
- &maxsock); | |
- if (bselect(maxsock, &readfds, &writefds, NULL, NULL) == -1) { | |
- if (errno == EINTR) { | |
- CheckForResize(Play); | |
- continue; | |
- } | |
- perror("bselect"); | |
- exit(1); | |
- } | |
- if (FD_ISSET(0, &readfds)) { | |
- /* So that Ctrl-L works */ | |
- c = getch(); | |
-#ifndef CYGWIN | |
- if (c == '\f') | |
- wrefresh(curscr); | |
-#endif | |
- } | |
- RespondToSelect(netbuf, &readfds, &writefds, NULL, &doneOK); | |
- } | |
- } | |
- | |
- if (!doneOK) | |
- g_string_assign_error(errstr, netbuf->error); | |
- return doneOK; | |
-} | |
- | |
-/* | |
- * Connects to a dopewars server. Prompts the user to select a server | |
- * if necessary. Returns TRUE, unless the user elected to quit the | |
- * program rather than choose a valid server. | |
- */ | |
-static gboolean ConnectToServer(Player *Play) | |
-{ | |
- gboolean MetaOK = TRUE, NetOK = TRUE, firstrun = FALSE; | |
- GString *errstr; | |
- gchar *text; | |
- int c; | |
- | |
- errstr = g_string_new(""); | |
- | |
- if (g_strcasecmp(ServerName, SN_META) == 0 || ConnectMethod == CM_META) { | |
- ConnectMethod = CM_META; | |
- MetaOK = SelectServerFromMetaServer(Play, errstr); | |
- } else if (g_strcasecmp(ServerName, SN_PROMPT) == 0 || | |
- ConnectMethod == CM_PROMPT) { | |
- ConnectMethod = CM_PROMPT; | |
- SelectServerManually(); | |
- } else if (g_strcasecmp(ServerName, SN_SINGLE) == 0 || | |
- ConnectMethod == CM_SINGLE) { | |
- ConnectMethod = CM_SINGLE; | |
- g_string_free(errstr, TRUE); | |
- return TRUE; | |
- } else | |
- firstrun = TRUE; | |
- | |
- while (1) { | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- if (MetaOK && !firstrun) { | |
- mvaddstr(17, 1, _("Please wait... attempting to contact " | |
- "dopewars server...")); | |
- refresh(); | |
- NetOK = DoConnect(Play, errstr); | |
- } | |
- if (!NetOK || !MetaOK || firstrun) { | |
- firstrun = FALSE; | |
- clear_line(16); | |
- clear_line(17); | |
- if (!MetaOK) { | |
- /* Display of an error while contacting the metaserver */ | |
- mvaddstr(16, 1, _("Cannot get metaserver details")); | |
- text = g_strdup_printf(" (%s)", errstr->str); | |
- mvaddstr(17, 1, text); | |
- g_free(text); | |
- } else if (!NetOK) { | |
- /* Display of an error message while trying to contact a dopewars | |
- * server (the error message itself is displayed on the next | |
- * screen line) */ | |
- mvaddstr(16, 1, _("Could not start multiplayer dopewars")); | |
- text = g_strdup_printf(" (%s)", errstr->str); | |
- mvaddstr(17, 1, text); | |
- g_free(text); | |
- } | |
- MetaOK = NetOK = TRUE; | |
- attrset(PromptAttr); | |
- mvaddstr(18, 1, | |
- _("Will you... C>onnect to a named dopewars server")); | |
- mvaddstr(19, 1, | |
- _(" L>ist the servers on the metaserver, and " | |
- "select one")); | |
- mvaddstr(20, 1, | |
- _(" Q>uit (where you can start a server " | |
- "by typing \"dopewars -s\")")); | |
- mvaddstr(21, 1, _(" or P>lay single-player ? ")); | |
- attrset(TextAttr); | |
- | |
- /* Translate these 4 keys in line with the above options, keeping | |
- * the order the same (C>onnect, L>ist, Q>uit, P>lay single-player) */ | |
- c = GetKey(_("CLQP"), "CLQP", FALSE, FALSE, FALSE); | |
- switch (c) { | |
- case 'Q': | |
- g_string_free(errstr, TRUE); | |
- return FALSE; | |
- case 'P': | |
- g_string_free(errstr, TRUE); | |
- return TRUE; | |
- case 'L': | |
- MetaOK = SelectServerFromMetaServer(Play, errstr); | |
- break; | |
- case 'C': | |
- SelectServerManually(); | |
- break; | |
- } | |
- } else | |
- break; | |
- } | |
- g_string_free(errstr, TRUE); | |
- Client = Network = TRUE; | |
- return TRUE; | |
-} | |
-#endif /* NETWORKING */ | |
- | |
-/* | |
- * Displays the list of locations and prompts the user to select one. | |
- * If "AllowReturn" is TRUE, then if the current location is selected | |
- * simply drop back to the main game loop, otherwise send a request | |
- * to the server to move to the new location. If FALSE, the user MUST | |
- * choose a new location to move to. The active client player is | |
- * passed in "Play". | |
- * N.B. May set the global variable DisplayMode. | |
- * Returns: TRUE if the user chose to jet to a new location, | |
- * FALSE if the action was cancelled instead. | |
- */ | |
-static gboolean jet(Player *Play, gboolean AllowReturn) | |
-{ | |
- int i, c; | |
- char text[80]; | |
- | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- for (i = 0; i < NumLocation; i++) { | |
- sprintf(text, "%d. %s", i + 1, Location[i].Name); | |
- mvaddstr(17 + i / 3, (i % 3) * 20 + 12, text); | |
- } | |
- attrset(PromptAttr); | |
- | |
- /* Prompt when the player chooses to "jet" to a new location */ | |
- mvaddstr(22, 22, _("Where to, dude ? ")); | |
- attrset(TextAttr); | |
- curs_set(1); | |
- do { | |
- c = bgetch(); | |
- if (c >= '1' && c < '1' + NumLocation) { | |
- addstr(Location[c - '1'].Name); | |
- if (Play->IsAt != c - '1') { | |
- sprintf(text, "%d", c - '1'); | |
- DisplayMode = DM_NONE; | |
- SendClientMessage(Play, C_NONE, C_REQUESTJET, NULL, text); | |
- } else | |
- c = 0; | |
- } else | |
- c = 0; | |
- } while (c == 0 && !AllowReturn); | |
- | |
- curs_set(0); | |
- return (c != 0); | |
-} | |
- | |
-/* | |
- * Prompts the user "Play" to drop some of the currently carried drugs. | |
- */ | |
-static void DropDrugs(Player *Play) | |
-{ | |
- int i, c, num, NumDrugs; | |
- GString *text; | |
- gchar *buf; | |
- | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- text = g_string_new(""); | |
- dpg_string_sprintf(text, | |
- /* List of drugs that you can drop (%tde = "drugs" by | |
- * default) */ | |
- _("You can\'t get any cash for the following " | |
- "carried %tde :"), Names.Drugs); | |
- mvaddstr(16, 1, text->str); | |
- NumDrugs = 0; | |
- for (i = 0; i < NumDrug; i++) { | |
- if (Play->Drugs[i].Carried > 0 && Play->Drugs[i].Price == 0) { | |
- g_string_sprintf(text, "%c. %-10s %-8d", NumDrugs + 'A', | |
- Drug[i].Name, Play->Drugs[i].Carried); | |
- mvaddstr(17 + NumDrugs / 3, (NumDrugs % 3) * 25 + 4, text->str); | |
- NumDrugs++; | |
- } | |
- } | |
- attrset(PromptAttr); | |
- mvaddstr(22, 20, _("What do you want to drop? ")); | |
- curs_set(1); | |
- attrset(TextAttr); | |
- c = bgetch(); | |
- c = toupper(c); | |
- for (i = 0; c >= 'A' && c < 'A' + NumDrugs && i < NumDrug; i++) { | |
- if (Play->Drugs[i].Carried > 0 && Play->Drugs[i].Price == 0) { | |
- c--; | |
- if (c < 'A') { | |
- addstr(Drug[i].Name); | |
- buf = | |
- nice_input(_("How many do you drop? "), 23, 8, TRUE, NULL, | |
- '\0'); | |
- num = atoi(buf); | |
- g_free(buf); | |
- if (num > 0) { | |
- g_string_sprintf(text, "drug^%d^%d", i, -num); | |
- SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text->str); | |
- } | |
- } | |
- } | |
- } | |
- g_string_free(text, TRUE); | |
-} | |
- | |
-/* | |
- * Prompts the user (i.e. the owner of client "Play") to buy drugs if | |
- * "Buy" is TRUE, or to sell drugs otherwise. A list of available drugs | |
- * is displayed, and on receiving the selection, the user is prompted | |
- * for the number of drugs desired. Finally a message is sent to the | |
- * server to buy or sell the required quantity. | |
- */ | |
-static void DealDrugs(Player *Play, gboolean Buy) | |
-{ | |
- int i, c, NumDrugsHere; | |
- gchar *text, *input; | |
- int DrugNum, CanCarry, CanAfford; | |
- | |
- NumDrugsHere = 0; | |
- for (c = 0; c < NumDrug; c++) | |
- if (Play->Drugs[c].Price > 0) | |
- NumDrugsHere++; | |
- | |
- clear_line(22); | |
- attrset(PromptAttr); | |
- if (Buy) { | |
- /* Buy and sell prompts for dealing drugs or guns */ | |
- mvaddstr(22, 20, _("What do you wish to buy? ")); | |
- } else { | |
- mvaddstr(22, 20, _("What do you wish to sell? ")); | |
- } | |
- curs_set(1); | |
- attrset(TextAttr); | |
- c = bgetch(); | |
- c = toupper(c); | |
- if (c >= 'A' && c < 'A' + NumDrugsHere) { | |
- DrugNum = -1; | |
- c -= 'A'; | |
- for (i = 0; i <= c; i++) | |
- DrugNum = GetNextDrugIndex(DrugNum, Play); | |
- addstr(Drug[DrugNum].Name); | |
- CanCarry = Play->CoatSize; | |
- CanAfford = Play->Cash / Play->Drugs[DrugNum].Price; | |
- | |
- if (Buy) { | |
- /* Display of number of drugs you could buy and/or carry, when | |
- * buying drugs */ | |
- text = g_strdup_printf(_("You can afford %d, and can carry %d. "), | |
- CanAfford, CanCarry); | |
- mvaddstr(23, 2, text); | |
- input = nice_input(_("How many do you buy? "), 23, 2 + strlen(text), | |
- TRUE, NULL, '\0'); | |
- c = atoi(input); | |
- g_free(input); | |
- g_free(text); | |
- if (c >= 0) { | |
- text = g_strdup_printf("drug^%d^%d", DrugNum, c); | |
- SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text); | |
- g_free(text); | |
- } | |
- } else { | |
- /* Display of number of drugs you have, when selling drugs */ | |
- text = | |
- g_strdup_printf(_("You have %d. "), | |
- Play->Drugs[DrugNum].Carried); | |
- mvaddstr(23, 2, text); | |
- input = nice_input(_("How many do you sell? "), 23, 2 + strlen(text), | |
- TRUE, NULL, '\0'); | |
- c = atoi(input); | |
- g_free(input); | |
- g_free(text); | |
- if (c >= 0) { | |
- text = g_strdup_printf("drug^%d^%d", DrugNum, -c); | |
- SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text); | |
- g_free(text); | |
- } | |
- } | |
- } | |
- curs_set(0); | |
-} | |
- | |
-/* | |
- * Prompts the user (player "Play") to give an errand to one of his/her | |
- * bitches. The decision is relayed to the server for implementation. | |
- */ | |
-static void GiveErrand(Player *Play) | |
-{ | |
- int c, y; | |
- GString *text; | |
- Player *To; | |
- | |
- text = g_string_new(""); | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- y = 17; | |
- | |
- /* Prompt for sending your bitches out to spy etc. (%tde = "bitches" by | |
- * default) */ | |
- dpg_string_sprintf(text, | |
- _("Choose an errand to give one of your %tde..."), | |
- Names.Bitches); | |
- mvaddstr(y++, 1, text->str); | |
- attrset(PromptAttr); | |
- if (Play->Bitches.Carried > 0) { | |
- dpg_string_sprintf(text, | |
- _(" S>py on another dealer " | |
- "(cost: %P)"), Prices.Spy); | |
- mvaddstr(y++, 2, text->str); | |
- dpg_string_sprintf(text, | |
- _(" T>ip off the cops to another dealer " | |
- "(cost: %P)"), Prices.Tipoff); | |
- mvaddstr(y++, 2, text->str); | |
- mvaddstr(y++, 2, _(" G>et stuffed")); | |
- } | |
- if (Play->Flags & SPYINGON) { | |
- mvaddstr(y++, 2, _("or C>ontact your spies and receive reports")); | |
- } | |
- mvaddstr(y++, 2, _("or N>o errand ? ")); | |
- curs_set(1); | |
- attrset(TextAttr); | |
- | |
- /* Translate these 5 keys to match the above options, keeping the | |
- * original order the same (S>py, T>ip off, G>et stuffed, C>ontact spy, | |
- * N>o errand) */ | |
- c = GetKey(_("STGCN"), "STGCN", TRUE, FALSE, FALSE); | |
- | |
- if (Play->Bitches.Carried > 0 || c == 'C') | |
- switch (c) { | |
- case 'S': | |
- To = ListPlayers(Play, TRUE, _("Whom do you want to spy on? ")); | |
- if (To) | |
- SendClientMessage(Play, C_NONE, C_SPYON, To, NULL); | |
- break; | |
- case 'T': | |
- To = ListPlayers(Play, TRUE, | |
- _("Whom do you want to tip the cops off to? ")); | |
- if (To) | |
- SendClientMessage(Play, C_NONE, C_TIPOFF, To, NULL); | |
- break; | |
- case 'G': | |
- attrset(PromptAttr); | |
- /* Prompt for confirmation of sacking a bitch */ | |
- addstr(_(" Are you sure? ")); | |
- | |
- /* The two keys that are valid for answering Yes/No - if you | |
- * translate them, keep them in the same order - i.e. "Yes" before | |
- * "No" */ | |
- c = GetKey(_("YN"), "YN", FALSE, TRUE, FALSE); | |
- | |
- if (c == 'Y') | |
- SendClientMessage(Play, C_NONE, C_SACKBITCH, NULL, NULL); | |
- break; | |
- case 'C': | |
- if (Play->Flags & SPYINGON) { | |
- SendClientMessage(Play, C_NONE, C_CONTACTSPY, NULL, NULL); | |
- } | |
- break; | |
- } | |
-} | |
- | |
-/* | |
- * Asks the user if he/she _really_ wants to quit dopewars. | |
- */ | |
-static int want_to_quit(void) | |
-{ | |
- attrset(TextAttr); | |
- clear_line(22); | |
- attrset(PromptAttr); | |
- mvaddstr(22, 1, _("Are you sure you want to quit? ")); | |
- attrset(TextAttr); | |
- return (GetKey(_("YN"), "YN", FALSE, TRUE, FALSE) != 'N'); | |
-} | |
- | |
-/* | |
- * Prompts the user to change his or her name, and notifies the server. | |
- */ | |
-static void change_name(Player *Play, gboolean nullname) | |
-{ | |
- gchar *NewName; | |
- | |
- /* Prompt for player to change his/her name */ | |
- NewName = nice_input(_("New name: "), 23, 0, FALSE, NULL, '\0'); | |
- | |
- if (NewName[0]) { | |
- if (nullname) { | |
- SendNullClientMessage(Play, C_NONE, C_NAME, NULL, NewName); | |
- } else { | |
- SendClientMessage(Play, C_NONE, C_NAME, NULL, NewName); | |
- } | |
- SetPlayerName(Play, NewName); | |
- } | |
- g_free(NewName); | |
-} | |
- | |
-/* | |
- * Given a message "Message" coming in for player "Play", performs | |
- * processing and reacts properly; if a message indicates the end of the | |
- * game, the global variable QuitRequest is set. The global variable | |
- * DisplayMode may also be changed by this routine as a result of network | |
- * traffic. | |
- */ | |
-void HandleClientMessage(char *Message, Player *Play) | |
-{ | |
- char *pt, *Data, *wrd; | |
- AICode AI; | |
- MsgCode Code; | |
- Player *From, *tmp; | |
- GSList *list; | |
- gchar *text; | |
- int i; | |
- gboolean Handled; | |
- | |
- /* Ignore To: field - all messages will be for Player "Play" */ | |
- if (ProcessMessage(Message, Play, &From, &AI, &Code, &Data, FirstClient) | |
- == -1) { | |
- return; | |
- } | |
- | |
- Handled = | |
- HandleGenericClientMessage(From, AI, Code, Play, Data, &DisplayMode); | |
- switch (Code) { | |
- case C_ENDLIST: | |
- if (FirstClient && g_slist_next(FirstClient)) { | |
- ListPlayers(Play, FALSE, NULL); | |
- } | |
- break; | |
- case C_STARTHISCORE: | |
- PrepareHighScoreScreen(); | |
- break; | |
- case C_HISCORE: | |
- PrintHighScore(Data); | |
- break; | |
- case C_ENDHISCORE: | |
- if (strcmp(Data, "end") == 0) { | |
- QuitRequest = TRUE; | |
- } else { | |
- nice_wait(); | |
- clear_screen(); | |
- display_message(""); | |
- print_status(Play, TRUE); | |
- refresh(); | |
- } | |
- break; | |
- case C_PUSH: | |
- attrset(TextAttr); | |
- clear_line(22); | |
- mvaddstr(22, 0, _("You have been pushed from the server. " | |
- "Reverting to single player mode.")); | |
- nice_wait(); | |
- SwitchToSinglePlayer(Play); | |
- print_status(Play, TRUE); | |
- break; | |
- case C_QUIT: | |
- attrset(TextAttr); | |
- clear_line(22); | |
- mvaddstr(22, 0, | |
- _("The server has terminated. Reverting to " | |
- "single player mode.")); | |
- nice_wait(); | |
- SwitchToSinglePlayer(Play); | |
- print_status(Play, TRUE); | |
- break; | |
- case C_MSG: | |
- text = g_strdup_printf("%s: %s", GetPlayerName(From), Data); | |
- display_message(text); | |
- g_free(text); | |
- break; | |
- case C_MSGTO: | |
- text = g_strdup_printf("%s->%s: %s", GetPlayerName(From), | |
- GetPlayerName(Play), Data); | |
- display_message(text); | |
- g_free(text); | |
- break; | |
- case C_JOIN: | |
- text = g_strdup_printf(_("%s joins the game!"), Data); | |
- display_message(text); | |
- g_free(text); | |
- break; | |
- case C_LEAVE: | |
- if (From != &Noone) { | |
- text = g_strdup_printf(_("%s has left the game."), Data); | |
- display_message(text); | |
- g_free(text); | |
- } | |
- break; | |
- case C_RENAME: | |
- /* Displayed when a player changes his/her name */ | |
- text = g_strdup_printf(_("%s will now be known as %s."), | |
- GetPlayerName(From), Data); | |
- SetPlayerName(From, Data); | |
- mvaddstr(22, 0, text); | |
- g_free(text); | |
- nice_wait(); | |
- break; | |
- case C_PRINTMESSAGE: | |
- PrintMessage(Data); | |
- nice_wait(); | |
- break; | |
- case C_FIGHTPRINT: | |
- DisplayFightMessage(Play, Data); | |
- break; | |
- case C_SUBWAYFLASH: | |
- DisplayFightMessage(Play, NULL); | |
- for (list = FirstClient; list; list = g_slist_next(list)) { | |
- tmp = (Player *)list->data; | |
- tmp->Flags &= ~FIGHTING; | |
- } | |
- for (i = 0; i < 4; i++) { | |
- print_location(_("S U B W A Y")); | |
- refresh(); | |
- MicroSleep(100000); | |
- print_location(""); | |
- refresh(); | |
- MicroSleep(100000); | |
- } | |
- print_location(Location[(int)Play->IsAt].Name); | |
- break; | |
- case C_QUESTION: | |
- pt = Data; | |
- wrd = GetNextWord(&pt, ""); | |
- PrintMessage(pt); | |
- addch(' '); | |
- i = GetKey(_(wrd), wrd, FALSE, TRUE, TRUE); | |
- wrd = g_strdup_printf("%c", i); | |
- SendClientMessage(Play, C_NONE, C_ANSWER, | |
- From == &Noone ? NULL : From, wrd); | |
- g_free(wrd); | |
- break; | |
- case C_LOANSHARK: | |
- LoanShark(Play); | |
- SendClientMessage(Play, C_NONE, C_DONE, NULL, NULL); | |
- break; | |
- case C_BANK: | |
- Bank(Play); | |
- SendClientMessage(Play, C_NONE, C_DONE, NULL, NULL); | |
- break; | |
- case C_GUNSHOP: | |
- GunShop(Play); | |
- SendClientMessage(Play, C_NONE, C_DONE, NULL, NULL); | |
- break; | |
- case C_UPDATE: | |
- if (From == &Noone) { | |
- ReceivePlayerData(Play, Data, Play); | |
- print_status(Play, TRUE); | |
- refresh(); | |
- } else { | |
- DisplaySpyReports(Data, From, Play); | |
- } | |
- break; | |
- case C_NEWNAME: | |
- clear_line(22); | |
- clear_line(23); | |
- attrset(TextAttr); | |
- mvaddstr(22, 0, _("Unfortunately, somebody else is already " | |
- "using \"your\" name. Please change it.")); | |
- change_name(Play, TRUE); | |
- break; | |
- default: | |
- if (!Handled) { | |
- text = g_strdup_printf("%s^%c^%s^%s", GetPlayerName(From), Code, | |
- GetPlayerName(Play), Data); | |
- mvaddstr(22, 0, text); | |
- g_free(text); | |
- nice_wait(); | |
- } | |
- break; | |
- } | |
-} | |
- | |
-/* | |
- * Responds to a "starthiscore" message by clearing the screen and | |
- * displaying the title for the high scores screen. | |
- */ | |
-void PrepareHighScoreScreen(void) | |
-{ | |
- char *text; | |
- | |
- attrset(TextAttr); | |
- clear_screen(); | |
- attrset(TitleAttr); | |
- text = _("H I G H S C O R E S"); | |
- mvaddstr(0, (Width - strlen(text)) / 2, text); | |
- attrset(TextAttr); | |
-} | |
- | |
-/* | |
- * Prints a high score coded in "Data"; first word is the index of the | |
- * score (i.e. y screen coordinate), second word is the text, the first | |
- * letter of which identifies whether it's to be printed bold or not. | |
- */ | |
-void PrintHighScore(char *Data) | |
-{ | |
- char *cp; | |
- int index; | |
- | |
- cp = Data; | |
- index = GetNextInt(&cp, 0); | |
- if (!cp || strlen(cp) < 2) | |
- return; | |
- move(index + 2, 0); | |
- attrset(TextAttr); | |
- if (cp[0] == 'B') | |
- standout(); | |
- addstr(&cp[1]); | |
- if (cp[0] == 'B') | |
- standend(); | |
-} | |
- | |
-/* | |
- * Prints a message "text" received via. a "printmessage" message in the | |
- * bottom part of the screen. | |
- */ | |
-void PrintMessage(const gchar *text) | |
-{ | |
- guint i, line; | |
- | |
- attrset(TextAttr); | |
- clear_line(16); | |
- | |
- line = 1; | |
- for (i = 0; i < strlen(text) && (text[i] == '^' || text[i] == '\n'); i++) | |
- line++; | |
- clear_exceptfor(line); | |
- | |
- line = 17; | |
- move(line, 1); | |
- for (i = 0; i < strlen(text); i++) { | |
- if (text[i] == '^' || text[i] == '\n') { | |
- line++; | |
- move(line, 1); | |
- } else if (text[i] != '\r') | |
- addch((guchar)text[i]); | |
- } | |
-} | |
- | |
-static void SellGun(Player *Play) | |
-{ | |
- gchar *text; | |
- gint gunind; | |
- | |
- clear_line(22); | |
- if (TotalGunsCarried(Play) == 0) { | |
- /* Error - player tried to sell guns that he/she doesn't have | |
- * (%tde="guns" by default) */ | |
- text = dpg_strdup_printf(_("You don't have any %tde to sell!"), | |
- Names.Guns); | |
- mvaddstr(22, (Width - strlen(text)) / 2, text); | |
- g_free(text); | |
- nice_wait(); | |
- clear_line(23); | |
- } else { | |
- attrset(PromptAttr); | |
- mvaddstr(22, 20, _("What do you wish to sell? ")); | |
- curs_set(1); | |
- attrset(TextAttr); | |
- gunind = bgetch(); | |
- gunind = toupper(gunind); | |
- if (gunind >= 'A' && gunind < 'A' + NumGun) { | |
- gunind -= 'A'; | |
- addstr(Gun[gunind].Name); | |
- if (Play->Guns[gunind].Carried == 0) { | |
- clear_line(22); | |
- /* Error - player tried to sell some guns that he/she doesn't have */ | |
- mvaddstr(22, 10, _("You don't have any to sell!")); | |
- nice_wait(); | |
- clear_line(23); | |
- } else { | |
- Play->Cash += Gun[gunind].Price; | |
- Play->CoatSize += Gun[gunind].Space; | |
- Play->Guns[gunind].Carried--; | |
- text = g_strdup_printf("gun^%d^-1", gunind); | |
- SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text); | |
- g_free(text); | |
- print_status(Play, FALSE); | |
- } | |
- } | |
- } | |
-} | |
- | |
-static void BuyGun(Player *Play) | |
-{ | |
- gchar *text; | |
- gint gunind; | |
- | |
- clear_line(22); | |
- if (TotalGunsCarried(Play) >= Play->Bitches.Carried + 2) { | |
- text = dpg_strdup_printf( | |
- /* Error - player tried to buy more guns | |
- * than his/her bitches can carry (1st | |
- * %tde="bitches", 2nd %tde="guns" by | |
- * default) */ | |
- _("You'll need more %tde to carry " | |
- "any more %tde!"), | |
- Names.Bitches, Names.Guns); | |
- mvaddstr(22, (Width - strlen(text)) / 2, text); | |
- g_free(text); | |
- nice_wait(); | |
- clear_line(23); | |
- } else { | |
- attrset(PromptAttr); | |
- mvaddstr(22, 20, _("What do you wish to buy? ")); | |
- curs_set(1); | |
- attrset(TextAttr); | |
- gunind = bgetch(); | |
- gunind = toupper(gunind); | |
- if (gunind >= 'A' && gunind < 'A' + NumGun) { | |
- gunind -= 'A'; | |
- addstr(Gun[gunind].Name); | |
- if (Gun[gunind].Space > Play->CoatSize) { | |
- clear_line(22); | |
- /* Error - player tried to buy a gun that he/she doesn't have | |
- * space for (%tde="gun" by default) */ | |
- text = dpg_strdup_printf(_("You don't have enough space to " | |
- "carry that %tde!"), Names.Gun); | |
- mvaddstr(22, (Width - strlen(text)) / 2, text); | |
- g_free(text); | |
- nice_wait(); | |
- clear_line(23); | |
- } else if (Gun[gunind].Price > Play->Cash) { | |
- clear_line(22); | |
- /* Error - player tried to buy a gun that he/she can't afford | |
- * (%tde="gun" by default) */ | |
- text = dpg_strdup_printf(_("You don't have enough cash to buy " | |
- "that %tde!"), Names.Gun); | |
- mvaddstr(22, (Width - strlen(text)) / 2, text); | |
- g_free(text); | |
- nice_wait(); | |
- clear_line(23); | |
- } else { | |
- Play->Cash -= Gun[gunind].Price; | |
- Play->CoatSize -= Gun[gunind].Space; | |
- Play->Guns[gunind].Carried++; | |
- text = g_strdup_printf("gun^%d^1", gunind); | |
- SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text); | |
- g_free(text); | |
- print_status(Play, FALSE); | |
- } | |
- } | |
- } | |
-} | |
- | |
-/* | |
- * Allows player "Play" to buy and sell guns interactively. Passes the | |
- * decisions on to the server for sanity checking and implementation. | |
- */ | |
-void GunShop(Player *Play) | |
-{ | |
- int i, action; | |
- gchar *text; | |
- | |
- print_status(Play, FALSE); | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- for (i = 0; i < NumGun; i++) { | |
- text = | |
- dpg_strdup_printf("%c. %-22tde %12P", 'A' + i, Gun[i].Name, | |
- Gun[i].Price); | |
- mvaddstr(17 + i / 2, (i % 2) * 40 + 1, text); | |
- g_free(text); | |
- } | |
- do { | |
- /* Prompt for actions in the gun shop */ | |
- text = _("Will you B>uy, S>ell, or L>eave? "); | |
- attrset(PromptAttr); | |
- clear_line(22); | |
- mvaddstr(22, 40 - strlen(text) / 2, text); | |
- attrset(TextAttr); | |
- | |
- /* Translate these three keys in line with the above options, keeping | |
- * the order (B>uy, S>ell, L>eave) the same - you can change the | |
- * wording of the prompt, but if you change the order in this key | |
- * list, the keys will do the wrong things! */ | |
- action = GetKey(_("BSL"), "BSL", FALSE, FALSE, FALSE); | |
- if (action == 'S') | |
- SellGun(Play); | |
- else if (action == 'B') | |
- BuyGun(Play); | |
- } while (action != 'L'); | |
- print_status(Play, TRUE); | |
-} | |
- | |
-/* | |
- * Allows player "Play" to pay off loans interactively. | |
- */ | |
-void LoanShark(Player *Play) | |
-{ | |
- gchar *text, *prstr; | |
- price_t money; | |
- | |
- do { | |
- clear_bottom(); | |
- attrset(PromptAttr); | |
- | |
- /* Prompt for paying back loans from the loan shark */ | |
- text = | |
- nice_input(_("How much money do you pay back? "), 19, 1, TRUE, | |
- NULL, '\0'); | |
- attrset(TextAttr); | |
- money = strtoprice(text); | |
- g_free(text); | |
- if (money < 0) | |
- money = 0; | |
- if (money > Play->Debt) | |
- money = Play->Debt; | |
- if (money > Play->Cash) { | |
- /* Error - player doesn't have enough money to pay back the loan */ | |
- mvaddstr(20, 1, _("You don't have that much money!")); | |
- nice_wait(); | |
- } else { | |
- SendClientMessage(Play, C_NONE, C_PAYLOAN, NULL, | |
- (prstr = pricetostr(money))); | |
- g_free(prstr); | |
- money = 0; | |
- } | |
- } while (money != 0); | |
-} | |
- | |
-/* | |
- * Allows player "Play" to pay in or withdraw money from the bank | |
- * interactively. | |
- */ | |
-void Bank(Player *Play) | |
-{ | |
- gchar *text, *prstr; | |
- price_t money = 0; | |
- int action; | |
- | |
- do { | |
- clear_bottom(); | |
- attrset(PromptAttr); | |
- /* Prompt for dealing with the bank in the curses client */ | |
- mvaddstr(18, 1, _("Do you want to D>eposit money, W>ithdraw money, " | |
- "or L>eave ? ")); | |
- attrset(TextAttr); | |
- | |
- /* Make sure you keep the order the same if you translate these keys! | |
- * (D>eposit, W>ithdraw, L>eave) */ | |
- action = GetKey(_("DWL"), "DWL", FALSE, FALSE, FALSE); | |
- | |
- if (action == 'D' || action == 'W') { | |
- /* Prompt for putting money in or taking money out of the bank */ | |
- text = nice_input(_("How much money? "), 19, 1, TRUE, NULL, '\0'); | |
- | |
- money = strtoprice(text); | |
- g_free(text); | |
- if (money < 0) | |
- money = 0; | |
- if (action == 'W') | |
- money = -money; | |
- if (money > Play->Cash) { | |
- /* Error - player has tried to put more money into the bank than | |
- * he/she has */ | |
- mvaddstr(20, 1, _("You don't have that much money!")); | |
- nice_wait(); | |
- } else if (-money > Play->Bank) { | |
- /* Error - player has tried to withdraw more money from the bank | |
- * than there is in the account */ | |
- mvaddstr(20, 1, _("There isn't that much money in the bank...")); | |
- nice_wait(); | |
- } else if (money != 0) { | |
- SendClientMessage(Play, C_NONE, C_DEPOSIT, NULL, | |
- (prstr = pricetostr(money))); | |
- g_free(prstr); | |
- money = 0; | |
- } | |
- } | |
- } while (action != 'L' && money != 0); | |
-} | |
- | |
-/* | |
- * Waits for keyboard input; will only accept a key listed in the | |
- * "allowed" string. This string may have been translated; thus | |
- * the "orig_allowed" string contains the untranslated keys. | |
- * Returns the untranslated key corresponding to the key pressed | |
- * (e.g. if allowed[2] is pressed, orig_allowed[2] is returned) | |
- * Case insensitive. If "AllowOther" is TRUE, keys other than the | |
- * given selection are allowed, and cause a zero return value. | |
- * If "PrintAllowed" is TRUE, the allowed keys are printed after | |
- * the prompt. If "ExpandOut" is also TRUE, the full words for | |
- * the commands, rather than just their first letters, are displayed. | |
- */ | |
-int GetKey(char *allowed, char *orig_allowed, gboolean AllowOther, | |
- gboolean PrintAllowed, gboolean ExpandOut) | |
-{ | |
- int ch; | |
- guint AllowInd, WordInd, i; | |
- | |
- /* Expansions of the single-letter keypresses for the benefit of the | |
- * user. i.e. "Yes" is printed for the key "Y" etc. You should indicate | |
- * to the user which letter in the word corresponds to the keypress, by | |
- * capitalising it or similar. */ | |
- gchar *Words[] = { N_("Y:Yes"), N_("N:No"), N_("R:Run"), | |
- N_("F:Fight"), N_("A:Attack"), N_("E:Evade") | |
- }; | |
- guint numWords = sizeof(Words) / sizeof(Words[0]); | |
- gchar *trWord; | |
- | |
- curs_set(1); | |
- ch = '\0'; | |
- | |
- if (!allowed || strlen(allowed) == 0) | |
- return 0; | |
- | |
- if (PrintAllowed) { | |
- addch('[' | TextAttr); | |
- for (AllowInd = 0; AllowInd < strlen(allowed); AllowInd++) { | |
- if (AllowInd > 0) | |
- addch('/' | TextAttr); | |
- WordInd = 0; | |
- while (WordInd < numWords && | |
- orig_allowed[AllowInd] != Words[WordInd][0]) | |
- WordInd++; | |
- | |
- if (ExpandOut && WordInd < numWords) { | |
- trWord = _(Words[WordInd]); | |
- for (i = 2; i < strlen(trWord); i++) | |
- addch((guchar)trWord[i] | TextAttr); | |
- } else | |
- addch((guchar)allowed[AllowInd] | TextAttr); | |
- } | |
- addch(']' | TextAttr); | |
- addch(' ' | TextAttr); | |
- } | |
- | |
- do { | |
- ch = bgetch(); | |
- ch = toupper(ch); | |
- for (AllowInd = 0; AllowInd < strlen(allowed); AllowInd++) { | |
- if (allowed[AllowInd] == ch) { | |
- addch((guint)ch | TextAttr); | |
- curs_set(0); | |
- return orig_allowed[AllowInd]; | |
- } | |
- } | |
- } while (!AllowOther); | |
- | |
- curs_set(0); | |
- return 0; | |
-} | |
- | |
-/* | |
- * Clears one whole line on the curses screen. | |
- */ | |
-void clear_line(int line) | |
-{ | |
- int i; | |
- | |
- move(line, 0); | |
- for (i = 0; i < Width; i++) | |
- addch(' '); | |
-} | |
- | |
-/* | |
- * Clears the bottom of the screen (i.e. from line 16 to line 23) | |
- * except for the top "skip" lines. | |
- */ | |
-void clear_exceptfor(int skip) | |
-{ | |
- int i; | |
- | |
- for (i = 16 + skip; i <= 23; i++) | |
- clear_line(i); | |
-} | |
- | |
- | |
-/* | |
- * Clears screen lines 16 to 23. | |
- */ | |
-void clear_bottom(void) | |
-{ | |
- int i; | |
- | |
- for (i = 16; i <= 23; i++) | |
- clear_line(i); | |
-} | |
- | |
-/* | |
- * Clears the entire screen; 24 lines of 80 characters each. | |
- */ | |
-void clear_screen(void) | |
-{ | |
- int i; | |
- | |
- for (i = 0; i < Depth; i++) | |
- clear_line(i); | |
-} | |
- | |
-/* | |
- * Displays a prompt on the bottom screen line and waits for the user | |
- * to press a key. | |
- */ | |
-void nice_wait() | |
-{ | |
- gchar *text; | |
- | |
- attrset(PromptAttr); | |
- text = _("Press any key..."); | |
- mvaddstr(23, (Width - strlen(text)) / 2, text); | |
- bgetch(); | |
- attrset(TextAttr); | |
-} | |
- | |
-/* | |
- * Handles the display of messages pertaining to player-player fights | |
- * in the lower part of screen (fighting sub-screen). Adds the new line | |
- * of text in "text" and scrolls up previous messages if necessary | |
- * If "text" is NULL, initialises the area | |
- * If "text" is a blank string, redisplays the message area | |
- * Messages are displayed from lines 16 to 20; line 22 is used for | |
- * the prompt for the user. | |
- */ | |
-void DisplayFightMessage(Player *Play, char *text) | |
-{ | |
- static char Messages[5][79]; | |
- static int x, y; | |
- gchar *textpt; | |
- gchar *AttackName, *DefendName, *BitchName; | |
- gint i, DefendHealth, DefendBitches, BitchesKilled, ArmPercent; | |
- gboolean Loot; | |
- | |
- if (text == NULL) { | |
- x = 0; | |
- y = 15; | |
- for (i = 0; i < 5; i++) | |
- Messages[i][0] = '\0'; | |
- } else if (!text[0]) { | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- for (i = 16; i <= 20; i++) | |
- mvaddstr(i, 1, Messages[i - 16]); | |
- } else { | |
- if (HaveAbility(Play, A_NEWFIGHT)) { | |
- ReceiveFightMessage(text, &AttackName, &DefendName, &DefendHealth, | |
- &DefendBitches, &BitchName, &BitchesKilled, | |
- &ArmPercent, &fp, &RunHere, &Loot, &CanFire, | |
- &textpt); | |
- } else { | |
- textpt = text; | |
- if (Play->Flags & FIGHTING) | |
- fp = F_MSG; | |
- else | |
- fp = F_LASTLEAVE; | |
- CanFire = (Play->Flags & CANSHOOT); | |
- RunHere = FALSE; | |
- } | |
- while (textpt[0]) { | |
- if (y < 20) | |
- y++; | |
- else | |
- for (i = 0; i < 4; i++) | |
- strcpy(Messages[i], Messages[i + 1]); | |
- | |
- strncpy(Messages[y - 16], textpt, 78); | |
- Messages[y - 16][78] = '\0'; | |
- textpt += MIN(strlen(textpt), 78); | |
- } | |
- } | |
-} | |
- | |
-/* | |
- * Displays a network message "buf" in the message area (lines | |
- * 10 to 14) scrolling previous messages up. | |
- * If "buf" is NULL, clears the message area | |
- * If "buf" is a blank string, redisplays the message area | |
- */ | |
-void display_message(char *buf) | |
-{ | |
- guint x, y; | |
- guint wid; | |
- static gchar Messages[5][200]; | |
- gchar *bufpt; | |
- | |
- if (Width <= 4) | |
- return; | |
- | |
- wid = MIN(Width - 4, 200); | |
- | |
- if (!buf) { | |
- for (y = 0; y < 5; y++) { | |
- memset(Messages[y], ' ', 200); | |
- if (Network) { | |
- mvaddch(y + 10, 0, ' ' | TextAttr); | |
- addch(ACS_VLINE | StatsAttr); | |
- for (x = 0; x < wid; x++) | |
- addch(' ' | StatsAttr); | |
- addch(ACS_VLINE | StatsAttr); | |
- addch(' ' | TextAttr); | |
- } | |
- } | |
- } else if (Network) { | |
- bufpt = buf; | |
- while (bufpt[0] != 0) { | |
- memmove(Messages[0], Messages[1], 200 * 4); | |
- memset(Messages[4], ' ', 200); | |
- memcpy(Messages[4], bufpt, | |
- strlen(bufpt) > wid ? wid : strlen(bufpt)); | |
- bufpt += MIN(strlen(bufpt), wid); | |
- } | |
- for (y = 0; y < 5; y++) | |
- for (x = 0; x < wid; x++) { | |
- mvaddch(y + 10, x + 2, (guchar)Messages[y][x] | StatsAttr); | |
- } | |
- refresh(); | |
- } | |
-} | |
- | |
-/* | |
- * Displays the string "text" at the top of the screen. Usually used for | |
- * displaying the current location or the "Subway" flash. | |
- */ | |
-void print_location(char *text) | |
-{ | |
- int i; | |
- | |
- if (!text) | |
- return; | |
- attrset(LocationAttr); | |
- move(0, Width / 2 - 9); | |
- for (i = 0; i < 18; i++) | |
- addch(' '); | |
- mvaddstr(0, (Width - strlen(text)) / 2, text); | |
- attrset(TextAttr); | |
-} | |
- | |
-/* | |
- * Displays the status of player "Play" - i.e. the current turn, the | |
- * location, bitches, available space, cash, guns, health and bank | |
- * details. If "DispDrugs" is TRUE, displays the carried drugs on the | |
- * right hand side of the screen; if FALSE, displays the carried guns. | |
- */ | |
-void print_status(Player *Play, gboolean DispDrug) | |
-{ | |
- int i, c; | |
- GString *text; | |
- | |
- text = g_string_new(NULL); | |
- attrset(TitleAttr); | |
- clear_line(0); | |
- g_string_sprintf(text, "%s%02d%s", Names.Month, Play->Turn, Names.Year); | |
- mvaddstr(0, 3, text->str); | |
- | |
- attrset(StatsAttr); | |
- for (i = 2; i <= 14; i++) { | |
- mvaddch(i, 1, ACS_VLINE); | |
- mvaddch(i, Width - 2, ACS_VLINE); | |
- } | |
- mvaddch(1, 1, ACS_ULCORNER); | |
- for (i = 0; i < Width - 4; i++) | |
- addch(ACS_HLINE); | |
- addch(ACS_URCORNER); | |
- | |
- mvaddch(1, Width / 2, ACS_TTEE); | |
- for (i = 2; i <= (Network ? 8 : 13); i++) { | |
- move(i, 2); | |
- for (c = 2; c < Width / 2; c++) | |
- addch(' '); | |
- addch(ACS_VLINE); | |
- for (c = Width / 2 + 1; c < Width - 2; c++) | |
- addch(' '); | |
- } | |
- if (!Network) { | |
- mvaddch(14, 1, ACS_LLCORNER); | |
- for (i = 0; i < Width - 4; i++) | |
- addch(ACS_HLINE); | |
- addch(ACS_LRCORNER); | |
- mvaddch(14, Width / 2, ACS_BTEE); | |
- } else { | |
- mvaddch(9, 1, ACS_LTEE); | |
- for (i = 0; i < Width - 4; i++) | |
- addch(ACS_HLINE); | |
- addch(ACS_RTEE); | |
- | |
- /* Title of the "Messages" window in the curses client */ | |
- mvaddstr(9, 15, _("Messages")); | |
- | |
- mvaddch(9, Width / 2, ACS_BTEE); | |
- mvaddch(15, 1, ACS_LLCORNER); | |
- for (i = 0; i < Width - 4; i++) | |
- addch(ACS_HLINE); | |
- addch(ACS_LRCORNER); | |
- } | |
- | |
- /* Title of the "Stats" window in the curses client */ | |
- mvaddstr(1, Width / 4 - 2, _("Stats")); | |
- | |
- attrset(StatsAttr); | |
- | |
- /* Display of the player's cash in the stats window (careful to keep the | |
- * formatting if you change the length of the "Cash" word) */ | |
- dpg_string_sprintf(text, _("Cash %17P"), Play->Cash); | |
- mvaddstr(3, 9, text->str); | |
- | |
- /* Display of the total number of guns carried (%Tde="Guns" by default) */ | |
- dpg_string_sprintf(text, _("%-19Tde%3d"), Names.Guns, | |
- TotalGunsCarried(Play)); | |
- mvaddstr(Network ? 4 : 5, 9, text->str); | |
- | |
- /* Display of the player's health */ | |
- g_string_sprintf(text, _("Health %3d"), Play->Health); | |
- mvaddstr(Network ? 5 : 7, 9, text->str); | |
- | |
- /* Display of the player's bank balance */ | |
- dpg_string_sprintf(text, _("Bank %17P"), Play->Bank); | |
- mvaddstr(Network ? 6 : 9, 9, text->str); | |
- | |
- if (Play->Debt > 0) | |
- attrset(DebtAttr); | |
- /* Display of the player's debt */ | |
- dpg_string_sprintf(text, _("Debt %17P"), Play->Debt); | |
- mvaddstr(Network ? 7 : 11, 9, text->str); | |
- attrset(TitleAttr); | |
- | |
- /* Display of the player's trenchcoat size (antique mode only) */ | |
- if (WantAntique) | |
- g_string_sprintf(text, _("Space %6d"), Play->CoatSize); | |
- else { | |
- /* Display of the player's number of bitches, and available space | |
- * (%Tde="Bitches" by default) */ | |
- dpg_string_sprintf(text, _("%Tde %3d Space %6d"), Names.Bitches, | |
- Play->Bitches.Carried, Play->CoatSize); | |
- } | |
- mvaddstr(0, Width - 2 - strlen(text->str), text->str); | |
- print_location(Location[(int)Play->IsAt].Name); | |
- attrset(StatsAttr); | |
- | |
- c = 0; | |
- if (DispDrug) { | |
- /* Title of the "trenchcoat" window (antique mode only) */ | |
- if (WantAntique) | |
- mvaddstr(1, Width * 3 / 4 - 5, _("Trenchcoat")); | |
- else { | |
- /* Title of the "drugs" window (the only important bit in this | |
- * string is the "%Tde" which is "Drugs" by default; the %/.../ part | |
- * is ignored, so you don't need to translate it; see doc/i18n.html) | |
- */ | |
- dpg_string_sprintf(text, _("%/Stats: Drugs/%Tde"), Names.Drugs); | |
- mvaddstr(1, Width * 3 / 4 - strlen(text->str) / 2, text->str); | |
- } | |
- for (i = 0; i < NumDrug; i++) { | |
- if (Play->Drugs[i].Carried > 0) { | |
- /* Display of carried drugs with price (%tde="Opium", etc. by | |
- * default) */ | |
- if (HaveAbility(Play, A_DRUGVALUE)) { | |
- dpg_string_sprintf(text, _("%-7tde %3d @ %P"), Drug[i].Name, | |
- Play->Drugs[i].Carried, | |
- Play->Drugs[i].TotalValue / | |
- Play->Drugs[i].Carried); | |
- mvaddstr(3 + c, Width / 2 + 3, text->str); | |
- } else { | |
- /* Display of carried drugs (%tde="Opium", etc. by default) */ | |
- dpg_string_sprintf(text, _("%-7tde %3d"), Drug[i].Name, | |
- Play->Drugs[i].Carried); | |
- mvaddstr(3 + c / 2, Width / 2 + 3 + (c % 2) * 17, text->str); | |
- } | |
- c++; | |
- } | |
- } | |
- } else { | |
- /* Title of the "guns" window (the only important bit in this string | |
- * is the "%Tde" which is "Guns" by default) */ | |
- dpg_string_sprintf(text, _("%/Stats: Guns/%Tde"), Names.Guns); | |
- mvaddstr(1, Width * 3 / 4 - strlen(text->str) / 2, text->str); | |
- for (i = 0; i < NumGun; i++) { | |
- if (Play->Guns[i].Carried > 0) { | |
- /* Display of carried guns (%tde="Baretta", etc. by default) */ | |
- dpg_string_sprintf(text, _("%-22tde %3d"), Gun[i].Name, | |
- Play->Guns[i].Carried); | |
- mvaddstr(3 + c, Width / 2 + 3, text->str); | |
- c++; | |
- } | |
- } | |
- } | |
- attrset(TextAttr); | |
- if (!Network) | |
- clear_line(15); | |
- refresh(); | |
- g_string_free(text, TRUE); | |
-} | |
- | |
-/* | |
- * Parses details about player "From" from string "Data" and then | |
- * displays the lot, drugs and guns. | |
- */ | |
-void DisplaySpyReports(char *Data, Player *From, Player *To) | |
-{ | |
- gchar *text; | |
- | |
- ReceivePlayerData(To, Data, From); | |
- | |
- clear_bottom(); | |
- text = g_strdup_printf(_("Spy reports for %s"), GetPlayerName(From)); | |
- mvaddstr(17, 1, text); | |
- g_free(text); | |
- | |
- /* Message displayed with a spy's list of drugs (%Tde="Drugs" by | |
- * default) */ | |
- text = dpg_strdup_printf(_("%/Spy: Drugs/%Tde..."), Names.Drugs); | |
- mvaddstr(19, 20, text); | |
- g_free(text); | |
- print_status(From, TRUE); | |
- nice_wait(); | |
- clear_line(19); | |
- | |
- /* Message displayed with a spy's list of guns (%Tde="Guns" by default) */ | |
- text = dpg_strdup_printf(_("%/Spy: Guns/%Tde..."), Names.Guns); | |
- mvaddstr(19, 20, text); | |
- g_free(text); | |
- print_status(From, FALSE); | |
- nice_wait(); | |
- | |
- print_status(To, TRUE); | |
- refresh(); | |
-} | |
- | |
-/* | |
- * Displays the "Prompt" if non-NULL, and then lists all clients | |
- * currently playing dopewars, other than the current player "Play". | |
- * If "Select" is TRUE, gives each player a letter and asks the user | |
- * to select one, which is returned by the function. | |
- */ | |
-Player *ListPlayers(Player *Play, gboolean Select, char *Prompt) | |
-{ | |
- Player *tmp = NULL; | |
- GSList *list; | |
- int i, c; | |
- gchar *text; | |
- | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- if (!FirstClient || (!g_slist_next(FirstClient) && | |
- FirstClient->data == Play)) { | |
- text = _("No other players are currently logged on!"); | |
- mvaddstr(18, (Width - strlen(text)) / 2, text); | |
- nice_wait(); | |
- return 0; | |
- } | |
- mvaddstr(16, 1, _("Players currently logged on:-")); | |
- | |
- i = 0; | |
- for (list = FirstClient; list; list = g_slist_next(list)) { | |
- tmp = (Player *)list->data; | |
- if (strcmp(GetPlayerName(tmp), GetPlayerName(Play)) == 0) | |
- continue; | |
- if (Select) | |
- text = g_strdup_printf("%c. %s", 'A' + i, GetPlayerName(tmp)); | |
- else | |
- text = g_strdup(GetPlayerName(tmp)); | |
- mvaddstr(17 + i / 2, (i % 2) * 40 + 1, text); | |
- g_free(text); | |
- i++; | |
- } | |
- | |
- if (Prompt) { | |
- attrset(PromptAttr); | |
- mvaddstr(22, 10, Prompt); | |
- attrset(TextAttr); | |
- } | |
- if (Select) { | |
- curs_set(1); | |
- attrset(TextAttr); | |
- c = 0; | |
- while (c < 'A' || c >= 'A' + i) { | |
- c = bgetch(); | |
- c = toupper(c); | |
- } | |
- if (Prompt) | |
- addch((guint)c); | |
- list = FirstClient; | |
- while (c >= 'A') { | |
- if (list != FirstClient) | |
- list = g_slist_next(list); | |
- tmp = (Player *)list->data; | |
- while (strcmp(GetPlayerName(tmp), GetPlayerName(Play)) == 0) { | |
- list = g_slist_next(list); | |
- tmp = (Player *)list->data; | |
- } | |
- c--; | |
- } | |
- return tmp; | |
- } else { | |
- nice_wait(); | |
- } | |
- return NULL; | |
-} | |
- | |
-/* | |
- * Displays the given "prompt" (if non-NULL) at coordinates sx,sy and | |
- * allows the user to input a string, which is returned. This is a | |
- * dynamically allocated string, and so must be freed by the calling | |
- * routine. If "digitsonly" is TRUE, the user will be permitted only to | |
- * input numbers, although the suffixes m and k are allowed (the | |
- * strtoprice routine understands this notation for a 1000000 or 1000 | |
- * multiplier) as well as a decimal point (. or ,) | |
- * If "displaystr" is non-NULL, it is taken as a default response. | |
- * If "passwdchar" is non-zero, it is displayed instead of the user's | |
- * keypresses (e.g. for entering passwords) | |
- */ | |
-char *nice_input(char *prompt, int sy, int sx, gboolean digitsonly, | |
- char *displaystr, char passwdchar) | |
-{ | |
- int i, c, x; | |
- gboolean DecimalPoint, Suffix; | |
- GString *text; | |
- gchar *ReturnString; | |
- | |
- DecimalPoint = Suffix = FALSE; | |
- | |
- x = sx; | |
- move(sy, x); | |
- if (prompt) { | |
- attrset(PromptAttr); | |
- addstr(prompt); | |
- x += strlen(prompt); | |
- } | |
- attrset(TextAttr); | |
- if (displaystr) { | |
- if (passwdchar) { | |
- for (i = strlen(displaystr); i; i--) | |
- addch((guint)passwdchar); | |
- } else { | |
- addstr(displaystr); | |
- } | |
- i = strlen(displaystr); | |
- text = g_string_new(displaystr); | |
- } else { | |
- i = 0; | |
- text = g_string_new(""); | |
- } | |
- | |
- curs_set(1); | |
- do { | |
- move(sy + (x + i) / Width, (x + i) % Width); | |
- c = bgetch(); | |
- if ((c == 8 || c == KEY_BACKSPACE || c == 127) && i > 0) { | |
- move(sy + (x + i - 1) / Width, (x + i - 1) % Width); | |
- addch(' '); | |
- i--; | |
- if (DecimalPoint && text->str[i] == '.') | |
- DecimalPoint = FALSE; | |
- if (Suffix) | |
- Suffix = FALSE; | |
- g_string_truncate(text, i); | |
- } else if (!Suffix) { | |
- if ((digitsonly && c >= '0' && c <= '9') || | |
- (!digitsonly && c >= 32 && c != '^' && c < 127)) { | |
- g_string_append_c(text, c); | |
- i++; | |
- addch((guint)passwdchar ? passwdchar : c); | |
- } else if (digitsonly && (c == '.' || c == ',') && !DecimalPoint) { | |
- g_string_append_c(text, '.'); | |
- i++; | |
- addch((guint)passwdchar ? passwdchar : c); | |
- DecimalPoint = TRUE; | |
- } else if (digitsonly | |
- && (c == 'M' || c == 'm' || c == 'k' || c == 'K') | |
- && !Suffix) { | |
- g_string_append_c(text, c); | |
- i++; | |
- addch((guint)passwdchar ? passwdchar : c); | |
- Suffix = TRUE; | |
- } | |
- } | |
- } while (c != '\n' && c != KEY_ENTER); | |
- curs_set(0); | |
- move(sy, x); | |
- ReturnString = text->str; | |
- g_string_free(text, FALSE); /* Leave the buffer to return */ | |
- return ReturnString; | |
-} | |
- | |
-/* | |
- * Loop which handles the user playing an interactive game (i.e. "Play" | |
- * is a client connected to a server, either locally or remotely) | |
- * dopewars is essentially server-driven, so this loop simply has to | |
- * make the screen look pretty, respond to user keypresses, and react | |
- * to messages from the server. | |
- */ | |
-static void Curses_DoGame(Player *Play) | |
-{ | |
- gchar *buf, *OldName, *TalkMsg; | |
- GString *text; | |
- int i, c; | |
- char IsCarrying; | |
- | |
-#if NETWORKING || HAVE_SELECT | |
- fd_set readfs; | |
-#endif | |
-#ifdef NETWORKING | |
- fd_set writefs; | |
- gboolean DoneOK; | |
- gchar *pt; | |
- gboolean justconnected = FALSE; | |
-#endif | |
- int NumDrugsHere; | |
- int MaxSock; | |
- char HaveWorthless; | |
- Player *tmp; | |
- struct sigaction sact; | |
- | |
- DisplayMode = DM_NONE; | |
- QuitRequest = FALSE; | |
- | |
- ResizedFlag = 0; | |
- sact.sa_handler = ResizeHandle; | |
- sact.sa_flags = 0; | |
- sigemptyset(&sact.sa_mask); | |
- if (sigaction(SIGWINCH, &sact, NULL) == -1) { | |
- g_warning(_("Cannot install SIGWINCH interrupt handler!")); | |
- } | |
- OldName = g_strdup(GetPlayerName(Play)); | |
- attrset(TextAttr); | |
- clear_screen(); | |
- display_message(NULL); | |
- DisplayFightMessage(Play, NULL); | |
- print_status(Play, TRUE); | |
- | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- buf = NULL; | |
- do { | |
- g_free(buf); | |
- buf = | |
- nice_input(_("Hey dude, what's your name? "), 17, 1, FALSE, | |
- OldName, '\0'); | |
- } while (buf[0] == 0); | |
-#if NETWORKING | |
- if (WantNetwork) { | |
- if (!ConnectToServer(Play)) { | |
- end_curses(); | |
- exit(1); | |
- } | |
- justconnected = TRUE; | |
- } | |
-#endif /* NETWORKING */ | |
- print_status(Play, TRUE); | |
- display_message(""); | |
- | |
- InitAbilities(Play); | |
- SendAbilities(Play); | |
- SetPlayerName(Play, buf); | |
- SendNullClientMessage(Play, C_NONE, C_NAME, NULL, buf); | |
- g_free(buf); | |
- g_free(OldName); | |
- | |
- text = g_string_new(""); | |
- | |
- while (1) { | |
- if (Play->Health == 0) | |
- DisplayMode = DM_NONE; | |
- HaveWorthless = 0; | |
- IsCarrying = 0; | |
- for (i = 0; i < NumDrug; i++) { | |
- if (Play->Drugs[i].Carried > 0) { | |
- IsCarrying = 1; | |
- if (Play->Drugs[i].Price == 0) | |
- HaveWorthless = 1; | |
- } | |
- } | |
- switch (DisplayMode) { | |
- case DM_STREET: | |
- attrset(TextAttr); | |
- NumDrugsHere = 0; | |
- for (i = 0; i < NumDrug; i++) | |
- if (Play->Drugs[i].Price > 0) | |
- NumDrugsHere++; | |
- clear_bottom(); | |
- /* Display of drug prices (%tde="drugs" by default) */ | |
- dpg_string_sprintf(text, _("Hey dude, the prices of %tde here are:"), | |
- Names.Drugs); | |
- mvaddstr(16, 1, text->str); | |
- for (c = 0, i = GetNextDrugIndex(-1, Play); | |
- c < NumDrugsHere && i != -1; | |
- c++, i = GetNextDrugIndex(i, Play)) { | |
- /* List of individual drug names for selection (%tde="Opium" etc. | |
- * by default) */ | |
- dpg_string_sprintf(text, _("%c. %-10tde %8P"), 'A' + c, | |
- Drug[i].Name, Play->Drugs[i].Price); | |
- mvaddstr(17 + c / 3, (c % 3) * 25 + 4, text->str); | |
- } | |
- attrset(PromptAttr); | |
- /* Prompts for "normal" actions in curses client */ | |
- g_string_assign(text, _("Will you B>uy")); | |
- if (IsCarrying) | |
- g_string_append(text, _(", S>ell")); | |
- if (HaveWorthless && !WantAntique) | |
- g_string_append(text, _(", D>rop")); | |
- if (Network) | |
- g_string_append(text, _(", T>alk, P>age, L>ist")); | |
- if (!WantAntique && (Play->Bitches.Carried > 0 || | |
- Play->Flags & SPYINGON)) { | |
- g_string_append(text, _(", G>ive")); | |
- } | |
- if (Play->Flags & FIGHTING) { | |
- g_string_append(text, _(", F>ight")); | |
- } else { | |
- g_string_append(text, _(", J>et")); | |
- } | |
- g_string_append(text, _(", or Q>uit? ")); | |
- mvaddstr(22, 40 - strlen(text->str) / 2, text->str); | |
- attrset(TextAttr); | |
- curs_set(1); | |
- break; | |
- case DM_FIGHT: | |
- DisplayFightMessage(Play, ""); | |
- attrset(PromptAttr); | |
- /* Prompts for actions during fights in curses client */ | |
- g_string_assign(text, _("Do you ")); | |
- if (CanFire) { | |
- if (TotalGunsCarried(Play) > 0) { | |
- g_string_append(text, _("F>ight, ")); | |
- } else { | |
- g_string_append(text, _("S>tand, ")); | |
- } | |
- } | |
- if (fp != F_LASTLEAVE) | |
- g_string_append(text, _("R>un, ")); | |
- if (!RunHere || fp == F_LASTLEAVE) | |
- /* (%tde = "drugs" by default here) */ | |
- dpg_string_sprintfa(text, _("D>eal %tde, "), Names.Drugs); | |
- g_string_append(text, _("or Q>uit? ")); | |
- mvaddstr(22, 40 - strlen(text->str) / 2, text->str); | |
- attrset(TextAttr); | |
- curs_set(1); | |
- break; | |
- case DM_DEAL: | |
- attrset(TextAttr); | |
- clear_bottom(); | |
- mvaddstr(16, 1, "Your trade:-"); | |
- mvaddstr(19, 1, "His trade:-"); | |
- g_string_assign(text, "Do you A>dd, R>emove, O>K, D>eal "); | |
- g_string_append(text, Names.Drugs); | |
- g_string_append(text, ", or Q>uit? "); | |
- attrset(PromptAttr); | |
- mvaddstr(22, 40 - strlen(text->str) / 2, text->str); | |
- attrset(TextAttr); | |
- curs_set(1); | |
- break; | |
- case DM_NONE: | |
- break; | |
- } | |
- refresh(); | |
- | |
- if (QuitRequest) | |
- return; | |
-#if NETWORKING | |
- FD_ZERO(&readfs); | |
- FD_ZERO(&writefs); | |
- FD_SET(0, &readfs); | |
- MaxSock = 1; | |
- if (Client) { | |
- if (justconnected) { | |
- /* Deal with any messages that came in while we were connect()ing */ | |
- justconnected = FALSE; | |
- while ((pt = GetWaitingPlayerMessage(Play)) != NULL) { | |
- HandleClientMessage(pt, Play); | |
- g_free(pt); | |
- } | |
- if (QuitRequest) | |
- return; | |
- } | |
- SetSelectForNetworkBuffer(&Play->NetBuf, &readfs, &writefs, | |
- NULL, &MaxSock); | |
- } | |
- if (bselect(MaxSock, &readfs, &writefs, NULL, NULL) == -1) { | |
- if (errno == EINTR) { | |
- CheckForResize(Play); | |
- continue; | |
- } | |
- perror("bselect"); | |
- exit(1); | |
- } | |
- if (Client) { | |
- if (RespondToSelect(&Play->NetBuf, &readfs, &writefs, NULL, &DoneOK)) { | |
- while ((pt = GetWaitingPlayerMessage(Play)) != NULL) { | |
- HandleClientMessage(pt, Play); | |
- g_free(pt); | |
- } | |
- if (QuitRequest) | |
- return; | |
- } | |
- if (!DoneOK) { | |
- attrset(TextAttr); | |
- clear_line(22); | |
- mvaddstr(22, 0, _("Connection to server lost! " | |
- "Reverting to single player mode")); | |
- nice_wait(); | |
- SwitchToSinglePlayer(Play); | |
- print_status(Play, TRUE); | |
- } | |
- } | |
- if (FD_ISSET(0, &readfs)) { | |
-#elif HAVE_SELECT | |
- FD_ZERO(&readfs); | |
- FD_SET(0, &readfs); | |
- MaxSock = 1; | |
- if (bselect(MaxSock, &readfs, NULL, NULL, NULL) == -1) { | |
- if (errno == EINTR) { | |
- CheckForResize(Play); | |
- continue; | |
- } | |
- perror("bselect"); | |
- exit(1); | |
- } | |
-#endif /* NETWORKING */ | |
- if (DisplayMode == DM_STREET) { | |
- /* N.B. You must keep the order of these keys the same as the | |
- * original when you translate (B>uy, S>ell, D>rop, T>alk, P>age, | |
- * L>ist, G>ive errand, F>ight, J>et, Q>uit) */ | |
- c = GetKey(_("BSDTPLGFJQ"), "BSDTPLGFJQ", TRUE, FALSE, FALSE); | |
- | |
- } else if (DisplayMode == DM_FIGHT) { | |
- /* N.B. You must keep the order of these keys the same as the | |
- * original when you translate (D>eal drugs, R>un, F>ight, S>tand, | |
- * Q>uit) */ | |
- c = GetKey(_("DRFSQ"), "DRFSQ", TRUE, FALSE, FALSE); | |
- | |
- } else | |
- c = 0; | |
-#if ! (NETWORKING || HAVE_SELECT) | |
- CheckForResize(Play); | |
-#endif | |
- if (DisplayMode == DM_STREET) { | |
- if (c == 'J' && !(Play->Flags & FIGHTING)) { | |
- jet(Play, TRUE); | |
- } else if (c == 'F' && Play->Flags & FIGHTING) { | |
- DisplayMode = DM_FIGHT; | |
- } else if (c == 'T' && Play->Flags & TRADING) { | |
- DisplayMode = DM_DEAL; | |
- } else if (c == 'B') { | |
- DealDrugs(Play, TRUE); | |
- } else if (c == 'S' && IsCarrying) { | |
- DealDrugs(Play, FALSE); | |
- } else if (c == 'D' && HaveWorthless && !WantAntique) { | |
- DropDrugs(Play); | |
- } else if (c == 'G' && !WantAntique && Play->Bitches.Carried > 0) { | |
- GiveErrand(Play); | |
- } else if (c == 'Q') { | |
- if (want_to_quit() == 1) { | |
- DisplayMode = DM_NONE; | |
- clear_bottom(); | |
- SendClientMessage(Play, C_NONE, C_WANTQUIT, NULL, NULL); | |
- } | |
- } else if (c == 'L' && Network) { | |
- attrset(PromptAttr); | |
- mvaddstr(23, 20, _("List what? P>layers or S>cores? ")); | |
- /* P>layers, S>cores */ | |
- i = GetKey(_("PS"), "PS", TRUE, FALSE, FALSE); | |
- if (i == 'P') { | |
- ListPlayers(Play, FALSE, NULL); | |
- } else if (i == 'S') { | |
- DisplayMode = DM_NONE; | |
- SendClientMessage(Play, C_NONE, C_REQUESTSCORE, NULL, NULL); | |
- } | |
- } else if (c == 'P' && Network) { | |
- tmp = ListPlayers(Play, TRUE, | |
- _("Whom do you want to page " | |
- "(talk privately to) ? ")); | |
- if (tmp) { | |
- attrset(TextAttr); | |
- clear_line(22); | |
- /* Prompt for sending player-player messages */ | |
- TalkMsg = nice_input(_("Talk: "), 22, 0, FALSE, NULL, '\0'); | |
- if (TalkMsg[0]) { | |
- SendClientMessage(Play, C_NONE, C_MSGTO, tmp, TalkMsg); | |
- buf = g_strdup_printf("%s->%s: %s", GetPlayerName(Play), | |
- GetPlayerName(tmp), TalkMsg); | |
- display_message(buf); | |
- g_free(buf); | |
- } | |
- g_free(TalkMsg); | |
- } | |
- } else if (c == 'T' && Client) { | |
- attrset(TextAttr); | |
- clear_line(22); | |
- TalkMsg = nice_input(_("Talk: "), 22, 0, FALSE, NULL, '\0'); | |
- if (TalkMsg[0]) { | |
- SendClientMessage(Play, C_NONE, C_MSG, NULL, TalkMsg); | |
- buf = g_strdup_printf("%s: %s", GetPlayerName(Play), TalkMsg); | |
- display_message(buf); | |
- g_free(buf); | |
- } | |
- g_free(TalkMsg); | |
- } | |
- } else if (DisplayMode == DM_FIGHT) { | |
- switch (c) { | |
- case 'D': | |
- DisplayMode = DM_STREET; | |
- break; | |
- case 'R': | |
- if (RunHere) { | |
- SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, "R"); | |
- } else { | |
- jet(Play, TRUE); | |
- } | |
- break; | |
- case 'F': | |
- if (TotalGunsCarried(Play) > 0 && CanFire) { | |
- buf = g_strdup_printf("%c", c); | |
- Play->Flags &= ~CANSHOOT; | |
- SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, buf); | |
- g_free(buf); | |
- } | |
- break; | |
- case 'S': | |
- if (TotalGunsCarried(Play) == 0 && CanFire) { | |
- buf = g_strdup_printf("%c", c); | |
- Play->Flags &= ~CANSHOOT; | |
- SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, buf); | |
- g_free(buf); | |
- } | |
- break; | |
- case 'Q': | |
- if (want_to_quit() == 1) { | |
- DisplayMode = DM_NONE; | |
- clear_bottom(); | |
- SendClientMessage(Play, C_NONE, C_WANTQUIT, NULL, NULL); | |
- } | |
- break; | |
- } | |
- } else if (DisplayMode == DM_DEAL) { | |
- switch (c) { | |
- case 'D': | |
- DisplayMode = DM_STREET; | |
- break; | |
- case 'Q': | |
- if (want_to_quit() == 1) { | |
- DisplayMode = DM_NONE; | |
- clear_bottom(); | |
- SendClientMessage(Play, C_NONE, C_WANTQUIT, NULL, NULL); | |
- } | |
- break; | |
- } | |
- } | |
-#if NETWORKING | |
- } | |
-#endif | |
- curs_set(0); | |
- } | |
- g_string_free(text, TRUE); | |
-} | |
- | |
-void CursesLoop(void) | |
-{ | |
- char c; | |
- Player *Play; | |
- | |
- if (!CheckHighScoreFileConfig()) | |
- return; | |
- | |
- /* Save the configuration, so we can restore those elements that get | |
- * overwritten when we connect to a dopewars server */ | |
- BackupConfig(); | |
- | |
- start_curses(); | |
- Width = COLS; | |
- Depth = LINES; | |
- | |
- /* Set up message handlers */ | |
- ClientMessageHandlerPt = HandleClientMessage; | |
- | |
- /* Make the GLib log messages display nicely */ | |
- g_log_set_handler(NULL, | |
- LogMask() | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING, | |
- LogMessage, NULL); | |
- | |
- display_intro(); | |
- | |
- Play = g_new(Player, 1); | |
- FirstClient = AddPlayer(0, Play, FirstClient); | |
- do { | |
- Curses_DoGame(Play); | |
- ShutdownNetwork(Play); | |
- CleanUpServer(); | |
- RestoreConfig(); | |
- attrset(TextAttr); | |
- mvaddstr(23, 20, _("Play again? ")); | |
- c = GetKey(_("YN"), "YN", TRUE, TRUE, FALSE); | |
- } while (c == 'Y'); | |
- FirstClient = RemovePlayer(Play, FirstClient); | |
- end_curses(); | |
-} | |
- | |
-#else | |
- | |
-#include <glib.h> | |
-#include "nls.h" /* We need this for the definition of '_' */ | |
- | |
-void CursesLoop(void) | |
-{ | |
- g_print(_("No curses client available - rebuild the binary passing the\n" | |
- "--enable-curses-client option to configure, or use a windowed\n" | |
- "client (if available) instead!\n")); | |
-} | |
- | |
-#endif /* CURSES_CLIENT */ | |
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) $(… | |
+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_DEPENDENCI… | |
+ -rm -f libcursesclient.a | |
+ $(AR) cru libcursesclient.a $(libcursesclient_a_OBJECTS) $(libcursescl… | |
+ $(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 … | |
+ | |
+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… | |
+ @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_clien… | |
t@@ -0,0 +1,2409 @@ | |
+/************************************************************************ | |
+ * curses_client.c dopewars client using the (n)curses console library * | |
+ * Copyright (C) 1998-2002 Ben Webb * | |
+ * Email: [email protected] * | |
+ * WWW: http://dopewars.sourceforge.net/ * | |
+ * * | |
+ * This program is free software; you can redistribute it and/or * | |
+ * modify it under the terms of the GNU General Public License * | |
+ * as published by the Free Software Foundation; either version 2 * | |
+ * of the License, or (at your option) any later version. * | |
+ * * | |
+ * This program is distributed in the hope that it will be useful, * | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
+ * GNU General Public License for more details. * | |
+ * * | |
+ * You should have received a copy of the GNU General Public License * | |
+ * along with this program; if not, write to the Free Software * | |
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * | |
+ * MA 02111-1307, USA. * | |
+ ************************************************************************/ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#include <string.h> | |
+#include <stdlib.h> | |
+#include <sys/types.h> | |
+#ifdef HAVE_UNISTD_H | |
+#include <unistd.h> | |
+#endif | |
+#include <ctype.h> | |
+#include <signal.h> | |
+#include <errno.h> | |
+#include <glib.h> | |
+#include "curses_client.h" | |
+#include "dopeos.h" | |
+#include "dopewars.h" | |
+#include "message.h" | |
+#include "nls.h" | |
+#include "serverside.h" | |
+#include "tstring.h" | |
+ | |
+static void PrepareHighScoreScreen(void); | |
+static void PrintHighScore(char *Data); | |
+ | |
+static int ResizedFlag; | |
+static SCREEN *cur_screen; | |
+ | |
+#ifdef NETWORKING | |
+static enum { | |
+ CM_SERVER, CM_PROMPT, CM_META, CM_SINGLE | |
+} ConnectMethod = CM_SERVER; | |
+#endif | |
+ | |
+static gboolean CanFire = FALSE, RunHere = FALSE; | |
+static FightPoint fp; | |
+ | |
+/* Function definitions; make them static so as not to clash with | |
+ * functions of the same name in different clients */ | |
+static void display_intro(void); | |
+static void ResizeHandle(int sig); | |
+static void CheckForResize(Player *Play); | |
+static int GetKey(char *allowed, char *orig_allowed, gboolean AllowOther, | |
+ gboolean PrintAllowed, gboolean ExpandOut); | |
+static void clear_bottom(void), clear_screen(void); | |
+static void clear_line(int line), clear_exceptfor(int skip); | |
+static void nice_wait(void); | |
+static void DisplayFightMessage(Player *Play, char *text); | |
+static void DisplaySpyReports(char *Data, Player *From, Player *To); | |
+static void display_message(char *buf); | |
+static void print_location(char *text); | |
+static void print_status(Player *Play, gboolean DispDrug); | |
+static char *nice_input(char *prompt, int sy, int sx, gboolean digitsonly, | |
+ char *displaystr, char passwdchar); | |
+static Player *ListPlayers(Player *Play, gboolean Select, char *Prompt); | |
+static void HandleClientMessage(char *buf, Player *Play); | |
+static void PrintMessage(const gchar *text); | |
+static void GunShop(Player *Play); | |
+static void LoanShark(Player *Play); | |
+static void Bank(Player *Play); | |
+ | |
+#ifdef NETWORKING | |
+static void HttpAuthFunc(HttpConnection *conn, gboolean proxyauth, | |
+ gchar *realm, gpointer data); | |
+static void SocksAuthFunc(NetworkBuffer *netbuf, gpointer data); | |
+#endif | |
+ | |
+static DispMode DisplayMode; | |
+static gboolean QuitRequest; | |
+ | |
+/* | |
+ * Initialises the curses library for accessing the screen. | |
+ */ | |
+static void start_curses(void) | |
+{ | |
+ cur_screen = newterm(NULL, stdout, stdin); | |
+ if (WantColour) { | |
+ start_color(); | |
+ init_pair(1, COLOR_MAGENTA, COLOR_WHITE); | |
+ init_pair(2, COLOR_BLACK, COLOR_WHITE); | |
+ init_pair(3, COLOR_BLACK, COLOR_WHITE); | |
+ init_pair(4, COLOR_BLUE, COLOR_WHITE); | |
+ init_pair(5, COLOR_WHITE, COLOR_BLUE); | |
+ init_pair(6, COLOR_RED, COLOR_WHITE); | |
+ } | |
+ cbreak(); | |
+ noecho(); | |
+ nodelay(stdscr, FALSE); | |
+ keypad(stdscr, TRUE); | |
+ curs_set(0); | |
+} | |
+ | |
+/* | |
+ * Shuts down the curses screen library. | |
+ */ | |
+static void end_curses(void) | |
+{ | |
+ keypad(stdscr, FALSE); | |
+ curs_set(1); | |
+ erase(); | |
+ refresh(); | |
+ endwin(); | |
+} | |
+ | |
+/* | |
+ * Handles a SIGWINCH signal, which is sent to indicate that the | |
+ * size of the curses screen has changed. | |
+ */ | |
+void ResizeHandle(int sig) | |
+{ | |
+ ResizedFlag = 1; | |
+} | |
+ | |
+/* | |
+ * Checks to see if the curses window needs to be resized - i.e. if a | |
+ * SIGWINCH signal has been received. | |
+ */ | |
+void CheckForResize(Player *Play) | |
+{ | |
+ sigset_t sigset; | |
+ | |
+ sigemptyset(&sigset); | |
+ sigaddset(&sigset, SIGWINCH); | |
+ sigprocmask(SIG_BLOCK, &sigset, NULL); | |
+ if (ResizedFlag) { | |
+ ResizedFlag = 0; | |
+ end_curses(); | |
+ start_curses(); | |
+ Width = COLS; | |
+ Depth = LINES; | |
+ attrset(TextAttr); | |
+ clear_screen(); | |
+ display_message(""); | |
+ DisplayFightMessage(Play, ""); | |
+ print_status(Play, TRUE); | |
+ } | |
+ sigprocmask(SIG_UNBLOCK, &sigset, NULL); | |
+} | |
+ | |
+static void LogMessage(const gchar *log_domain, GLogLevelFlags log_level, | |
+ const gchar *message, gpointer user_data) | |
+{ | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+ PrintMessage(message); | |
+ nice_wait(); | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+} | |
+ | |
+/* | |
+ * Displays a dopewars introduction screen. | |
+ */ | |
+void display_intro(void) | |
+{ | |
+ GString *text; | |
+ | |
+ attrset(TextAttr); | |
+ clear_screen(); | |
+ attrset(TitleAttr); | |
+ | |
+ /* Curses client introduction screen */ | |
+ text = g_string_new(_("D O P E W A R S")); | |
+ mvaddstr(1, (Width - text->len) / 2, text->str); | |
+ | |
+ attrset(TextAttr); | |
+ | |
+ mvaddstr(3, 1, _("Based on John E. Dell's old Drug Wars game, dopewars " | |
+ "is a simulation of an")); | |
+ mvaddstr(4, 1, _("imaginary drug market. dopewars is an All-American " | |
+ "game which features")); | |
+ mvaddstr(5, 1, _("buying, selling, and trying to get past the cops!")); | |
+ | |
+ mvaddstr(7, 1, _("The first thing you need to do is pay off your " | |
+ "debt to the Loan Shark. After")); | |
+ mvaddstr(8, 1, _("that, your goal is to make as much money as " | |
+ "possible (and stay alive)! You")); | |
+ mvaddstr(9, 1, _("have one month of game time to make your fortune.")); | |
+ | |
+ mvaddstr(11, 18, _("Copyright (C) 1998-2002 Ben Webb " | |
+ "[email protected]")); | |
+ 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 <glib.h> | |
#include <stdarg.h> | |
#include "admin.h" | |
-#include "curses_client.h" | |
#include "dopeos.h" | |
-#include "gtk_client.h" | |
#include "message.h" | |
#include "nls.h" | |
#include "serverside.h" | |
t@@ -53,8 +51,16 @@ | |
#include "AIPlayer.h" | |
#include "winmain.h" | |
+#ifdef CURSES_CLIENT | |
+#include "curses_client/curses_client.h" | |
+#endif | |
+ | |
+#ifdef GUI_CLIENT | |
+#include "gui_client/gtk_client.h" | |
+#endif | |
+ | |
#ifdef GUI_SERVER | |
-#include "gtkport.h" | |
+#include "gtkport/gtkport.h" | |
#endif | |
int ClientSock, ListenSock; | |
t@@ -2651,6 +2657,40 @@ static void ServerLogMessage(const gchar *log_domain, | |
} | |
#endif | |
+#ifndef CURSES_CLIENT | |
+/* | |
+ * Stub function to report an error if the Curses client is requested and | |
+ * it isn't compiled in. | |
+ */ | |
+void CursesLoop(void) | |
+{ | |
+ g_print(_("No curses client available - rebuild the binary passing the\n" | |
+ "--enable-curses-client option to configure, or use a windowed\n" | |
+ "client (if available) instead!\n")); | |
+} | |
+#endif | |
+ | |
+#ifndef GUI_CLIENT | |
+/* | |
+ * Stub function to report an error if the GTK+ client is requested and | |
+ * it isn't compiled in. | |
+ */ | |
+#ifdef CYGWIN | |
+gboolean GtkLoop(HINSTANCE hInstance, HINSTANCE hPrevInstance, | |
+ gboolean ReturnOnFail) | |
+#else | |
+gboolean GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail) | |
+#endif | |
+{ | |
+ if (!ReturnOnFail) { | |
+ g_print(_("No graphical client available - rebuild the binary\n" | |
+ "passing the --enable-gui-client option to configure, or\n" | |
+ "use the curses client (if available) instead!\n")); | |
+ } | |
+ return FALSE; | |
+} | |
+#endif | |
+ | |
/* | |
* Standard program entry - Win32 uses WinMain() instead, in winmain.c | |
*/ | |
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: [email protected] * | |
- * WWW: http://dopewars.sourceforge.net/ * | |
- * * | |
- * This program is free software; you can redistribute it and/or * | |
- * modify it under the terms of the GNU General Public License * | |
- * as published by the Free Software Foundation; either version 2 * | |
- * of the License, or (at your option) any later version. * | |
- * * | |
- * This program is distributed in the hope that it will be useful, * | |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
- * GNU General Public License for more details. * | |
- * * | |
- * You should have received a copy of the GNU General Public License * | |
- * along with this program; if not, write to the Free Software * | |
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * | |
- * MA 02111-1307, USA. * | |
- ************************************************************************/ | |
- | |
-#ifdef HAVE_CONFIG_H | |
-#include <config.h> | |
-#endif | |
- | |
-#ifdef GUI_CLIENT | |
- | |
-#include <stdlib.h> | |
-#include <ctype.h> | |
-#include <string.h> | |
- | |
-#include "dopeos.h" | |
-#include "dopewars.h" | |
-#include "gtk_client.h" | |
-#include "message.h" | |
-#include "nls.h" | |
-#include "serverside.h" | |
-#include "tstring.h" | |
-#include "gtkport.h" | |
-#include "dopewars-pill.xpm" | |
- | |
-#define BT_BUY (GINT_TO_POINTER(1)) | |
-#define BT_SELL (GINT_TO_POINTER(2)) | |
-#define BT_DROP (GINT_TO_POINTER(3)) | |
- | |
-#define ET_SPY 0 | |
-#define ET_TIPOFF 1 | |
- | |
-/* Which notebook page to display in the New Game dialog */ | |
-static gint NewGameType = 0; | |
- | |
-struct InventoryWidgets { | |
- GtkWidget *HereList, *CarriedList; | |
- GtkWidget *HereFrame, *CarriedFrame; | |
- GtkWidget *BuyButton, *SellButton, *DropButton; | |
- GtkWidget *vbbox; | |
-}; | |
- | |
-struct StatusWidgets { | |
- GtkWidget *Location, *Date, *SpaceName, *SpaceValue, *CashName; | |
- GtkWidget *CashValue, *DebtName, *DebtValue, *BankName, *BankValue; | |
- GtkWidget *GunsName, *GunsValue, *BitchesName, *BitchesValue; | |
- GtkWidget *HealthName, *HealthValue; | |
-}; | |
- | |
-struct ClientDataStruct { | |
- GtkWidget *window, *messages; | |
- Player *Play; | |
- GtkItemFactory *Menu; | |
- struct StatusWidgets Status; | |
- struct InventoryWidgets Drug, Gun, InvenDrug, InvenGun; | |
- GtkWidget *JetButton, *vbox, *PlayerList, *TalkList; | |
- guint JetAccel; | |
-}; | |
- | |
-GtkWidget *MainWindow; | |
- | |
-struct StartGameStruct { | |
- GtkWidget *dialog, *name, *hostname, *port, *antique, *status, *metaserv; | |
-#ifdef NETWORKING | |
- HttpConnection *MetaConn; | |
- GSList *NewMetaList; | |
-#endif | |
-}; | |
- | |
-static struct ClientDataStruct ClientData; | |
-static gboolean InGame = FALSE; | |
- | |
-static GtkWidget *FightDialog = NULL, *SpyReportsDialog; | |
-static gboolean IsShowingPlayerList = FALSE, IsShowingTalkList = FALSE; | |
-static gboolean IsShowingInventory = FALSE, IsShowingGunShop = FALSE; | |
- | |
-static void display_intro(GtkWidget *widget, gpointer data); | |
-static void QuitGame(GtkWidget *widget, gpointer data); | |
-static void DestroyGtk(GtkWidget *widget, gpointer data); | |
-static void NewGame(GtkWidget *widget, gpointer data); | |
-static void ListScores(GtkWidget *widget, gpointer data); | |
-static void ListInventory(GtkWidget *widget, gpointer data); | |
-static void NewGameDialog(void); | |
-static void StartGame(void); | |
-static void EndGame(void); | |
-static void Jet(GtkWidget *parent); | |
-static void UpdateMenus(void); | |
- | |
-#ifdef NETWORKING | |
-static void DisplayConnectStatus(struct StartGameStruct *widgets, | |
- gboolean meta, NBStatus oldstatus, | |
- NBSocksStatus oldsocks); | |
-static void AuthDialog(HttpConnection *conn, gboolean proxyauth, | |
- gchar *realm, gpointer data); | |
-static void MetaSocksAuthDialog(NetworkBuffer *netbuf, gpointer data); | |
-static void SocksAuthDialog(NetworkBuffer *netbuf, gpointer data); | |
-static void GetClientMessage(gpointer data, gint socket, | |
- GdkInputCondition condition); | |
-static void SocketStatus(NetworkBuffer *NetBuf, gboolean Read, | |
- gboolean Write, gboolean CallNow); | |
-static void MetaSocketStatus(NetworkBuffer *NetBuf, gboolean Read, | |
- gboolean Write, gboolean CallNow); | |
-static void FinishServerConnect(struct StartGameStruct *widgets, | |
- gboolean ConnectOK); | |
- | |
-/* List of servers on the metaserver */ | |
-static GSList *MetaList = NULL; | |
- | |
-#endif /* NETWORKING */ | |
- | |
-static void HandleClientMessage(char *buf, Player *Play); | |
-static void PrepareHighScoreDialog(void); | |
-static void AddScoreToDialog(char *Data); | |
-static void CompleteHighScoreDialog(gboolean AtEnd); | |
-static void PrintMessage(char *Data); | |
-static void DisplayFightMessage(char *Data); | |
-static GtkWidget *CreateStatusWidgets(struct StatusWidgets *Status); | |
-static void DisplayStats(Player *Play, struct StatusWidgets *Status); | |
-static void UpdateStatus(Player *Play); | |
-static void SetJetButtonTitle(GtkAccelGroup *accel_group); | |
-static void UpdateInventory(struct InventoryWidgets *Inven, | |
- Inventory *Objects, int NumObjects, | |
- gboolean AreDrugs); | |
-static void JetButtonPressed(GtkWidget *widget, gpointer data); | |
-static void DealDrugs(GtkWidget *widget, gpointer data); | |
-static void DealGuns(GtkWidget *widget, gpointer data); | |
-static void QuestionDialog(char *Data, Player *From); | |
-static void TransferDialog(gboolean Debt); | |
-static void ListPlayers(GtkWidget *widget, gpointer data); | |
-static void TalkToAll(GtkWidget *widget, gpointer data); | |
-static void TalkToPlayers(GtkWidget *widget, gpointer data); | |
-static void TalkDialog(gboolean TalkToAll); | |
-static GtkWidget *CreatePlayerList(void); | |
-static void UpdatePlayerList(GtkWidget *clist, gboolean IncludeSelf); | |
-static void TipOff(GtkWidget *widget, gpointer data); | |
-static void SpyOnPlayer(GtkWidget *widget, gpointer data); | |
-static void ErrandDialog(gint ErrandType); | |
-static void SackBitch(GtkWidget *widget, gpointer data); | |
-static void DestroyShowing(GtkWidget *widget, gpointer data); | |
-static gint DisallowDelete(GtkWidget *widget, GdkEvent * event, | |
- gpointer data); | |
-static void GunShopDialog(void); | |
-static void NewNameDialog(void); | |
-static void UpdatePlayerLists(void); | |
-static void CreateInventory(GtkWidget *hbox, gchar *Objects, | |
- GtkAccelGroup *accel_group, | |
- gboolean CreateButtons, gboolean CreateHere, | |
- struct InventoryWidgets *widgets, | |
- GtkSignalFunc CallBack); | |
-static void GetSpyReports(GtkWidget *widget, gpointer data); | |
-static void DisplaySpyReports(Player *Play); | |
- | |
-static GtkItemFactoryEntry menu_items[] = { | |
- /* The names of the the menus and their items in the GTK+ client */ | |
- {N_("/_Game"), NULL, NULL, 0, "<Branch>"}, | |
- {N_("/Game/_New..."), "<control>N", NewGame, 0, NULL}, | |
- {N_("/Game/_Quit..."), "<control>Q", QuitGame, 0, NULL}, | |
- {N_("/_Talk"), NULL, NULL, 0, "<Branch>"}, | |
- {N_("/Talk/To _All..."), NULL, TalkToAll, 0, NULL}, | |
- {N_("/Talk/To _Player..."), NULL, TalkToPlayers, 0, NULL}, | |
- {N_("/_List"), NULL, NULL, 0, "<Branch>"}, | |
- {N_("/List/_Players..."), NULL, ListPlayers, 0, NULL}, | |
- {N_("/List/_Scores..."), NULL, ListScores, 0, NULL}, | |
- {N_("/List/_Inventory..."), NULL, ListInventory, 0, NULL}, | |
- {N_("/_Errands"), NULL, NULL, 0, "<Branch>"}, | |
- {N_("/Errands/_Spy..."), NULL, SpyOnPlayer, 0, NULL}, | |
- {N_("/Errands/_Tipoff..."), NULL, TipOff, 0, NULL}, | |
- /* N.B. "Sack Bitch" has to be recreated (and thus translated) at the | |
- * start of each game, below, so is not marked for gettext here */ | |
- {"/Errands/S_ack Bitch...", NULL, SackBitch, 0, NULL}, | |
- {N_("/Errands/_Get spy reports..."), NULL, GetSpyReports, 0, NULL}, | |
- {N_("/_Help"), NULL, NULL, 0, "<LastBranch>"}, | |
- {N_("/Help/_About..."), "F1", display_intro, 0, NULL} | |
-}; | |
- | |
-static gchar *MenuTranslate(const gchar *path, gpointer func_data) | |
-{ | |
- /* Translate menu items, using gettext */ | |
- return _(path); | |
-} | |
- | |
-static void LogMessage(const gchar *log_domain, GLogLevelFlags log_level, | |
- const gchar *message, gpointer user_data) | |
-{ | |
- GtkMessageBox(NULL, message, | |
- /* Titles of the message boxes for warnings and errors */ | |
- log_level & G_LOG_LEVEL_WARNING ? _("Warning") : | |
- log_level & G_LOG_LEVEL_CRITICAL ? _("Error") : | |
- _("Message"), | |
- MB_OK | (gtk_main_level() > 0 ? MB_IMMRETURN : 0)); | |
-} | |
- | |
-void QuitGame(GtkWidget *widget, gpointer data) | |
-{ | |
- if (!InGame || GtkMessageBox(ClientData.window, | |
- /* Prompt in 'quit game' dialog */ | |
- _("Abandon current game?"), | |
- /* Title of 'quit game' dialog */ | |
- _("Quit Game"), MB_YESNO) == IDYES) { | |
- gtk_main_quit(); | |
- } | |
-} | |
- | |
-void DestroyGtk(GtkWidget *widget, gpointer data) | |
-{ | |
- gtk_main_quit(); | |
-} | |
- | |
-gint MainDelete(GtkWidget *widget, GdkEvent * event, gpointer data) | |
-{ | |
- return (InGame | |
- && GtkMessageBox(ClientData.window, _("Abandon current game?"), | |
- _("Quit Game"), MB_YESNO) == IDNO); | |
-} | |
- | |
- | |
-void NewGame(GtkWidget *widget, gpointer data) | |
-{ | |
- if (InGame) { | |
- if (GtkMessageBox(ClientData.window, _("Abandon current game?"), | |
- /* Title of 'stop game to start a new game' dialog */ | |
- _("Start new game"), MB_YESNO) == IDYES) | |
- EndGame(); | |
- else | |
- return; | |
- } | |
- | |
- /* Save the configuration, so we can restore those elements that get | |
- * overwritten when we connect to a dopewars server */ | |
- BackupConfig(); | |
- | |
- NewGameDialog(); | |
-} | |
- | |
-void ListScores(GtkWidget *widget, gpointer data) | |
-{ | |
- SendClientMessage(ClientData.Play, C_NONE, C_REQUESTSCORE, NULL, NULL); | |
-} | |
- | |
-void ListInventory(GtkWidget *widget, gpointer data) | |
-{ | |
- GtkWidget *window, *button, *hsep, *vbox, *hbox; | |
- GtkAccelGroup *accel_group; | |
- | |
- if (IsShowingInventory) | |
- return; | |
- window = gtk_window_new(GTK_WINDOW_DIALOG); | |
- gtk_window_set_default_size(GTK_WINDOW(window), 550, 120); | |
- accel_group = gtk_accel_group_new(); | |
- gtk_window_add_accel_group(GTK_WINDOW(window), accel_group); | |
- | |
- /* Title of inventory window */ | |
- gtk_window_set_title(GTK_WINDOW(window), _("Inventory")); | |
- | |
- IsShowingInventory = TRUE; | |
- gtk_window_set_modal(GTK_WINDOW(window), FALSE); | |
- gtk_object_set_data(GTK_OBJECT(window), "IsShowing", | |
- (gpointer)&IsShowingInventory); | |
- gtk_signal_connect(GTK_OBJECT(window), "destroy", | |
- GTK_SIGNAL_FUNC(DestroyShowing), NULL); | |
- | |
- gtk_window_set_transient_for(GTK_WINDOW(window), | |
- GTK_WINDOW(ClientData.window)); | |
- gtk_container_set_border_width(GTK_CONTAINER(window), 7); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- | |
- hbox = gtk_hbox_new(FALSE, 7); | |
- CreateInventory(hbox, Names.Drugs, accel_group, FALSE, FALSE, | |
- &ClientData.InvenDrug, NULL); | |
- CreateInventory(hbox, Names.Guns, accel_group, FALSE, FALSE, | |
- &ClientData.InvenGun, NULL); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- | |
- /* Caption of the button to close a dialog */ | |
- button = gtk_button_new_with_label(_("Close")); | |
- gtk_signal_connect_object(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
- (gpointer)window); | |
- gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); | |
- | |
- gtk_container_add(GTK_CONTAINER(window), vbox); | |
- | |
- UpdateInventory(&ClientData.InvenDrug, ClientData.Play->Drugs, NumDrug, | |
- TRUE); | |
- UpdateInventory(&ClientData.InvenGun, ClientData.Play->Guns, NumGun, | |
- FALSE); | |
- | |
- gtk_widget_show_all(window); | |
-} | |
- | |
-#ifdef NETWORKING | |
-void GetClientMessage(gpointer data, gint socket, | |
- GdkInputCondition condition) | |
-{ | |
- gchar *pt; | |
- NetworkBuffer *NetBuf; | |
- gboolean DoneOK, datawaiting; | |
- NBStatus status, oldstatus; | |
- NBSocksStatus oldsocks; | |
- | |
- NetBuf = &ClientData.Play->NetBuf; | |
- | |
- oldstatus = NetBuf->status; | |
- oldsocks = NetBuf->sockstat; | |
- | |
- datawaiting = | |
- PlayerHandleNetwork(ClientData.Play, condition & GDK_INPUT_READ, | |
- condition & GDK_INPUT_WRITE, &DoneOK); | |
- | |
- status = NetBuf->status; | |
- | |
- if (status != NBS_CONNECTED) { | |
- /* The start game dialog isn't visible once we're connected... */ | |
- DisplayConnectStatus((struct StartGameStruct *)data, FALSE, | |
- oldstatus, oldsocks); | |
- } | |
- | |
- if (oldstatus != NBS_CONNECTED && (status == NBS_CONNECTED || !DoneOK)) { | |
- FinishServerConnect(data, DoneOK); | |
- } | |
- if (status == NBS_CONNECTED && datawaiting) { | |
- while ((pt = GetWaitingPlayerMessage(ClientData.Play)) != NULL) { | |
- HandleClientMessage(pt, ClientData.Play); | |
- g_free(pt); | |
- } | |
- } | |
- if (!DoneOK) { | |
- if (status == NBS_CONNECTED) { | |
- /* The network connection to the server was dropped unexpectedly */ | |
- g_warning(_("Connection to server lost - switching to " | |
- "single player mode")); | |
- SwitchToSinglePlayer(ClientData.Play); | |
- UpdatePlayerLists(); | |
- UpdateMenus(); | |
- } else { | |
- ShutdownNetworkBuffer(&ClientData.Play->NetBuf); | |
- } | |
- } | |
-} | |
- | |
-void SocketStatus(NetworkBuffer *NetBuf, gboolean Read, gboolean Write, | |
- gboolean CallNow) | |
-{ | |
- if (NetBuf->InputTag) | |
- gdk_input_remove(NetBuf->InputTag); | |
- NetBuf->InputTag = 0; | |
- if (Read || Write) { | |
- NetBuf->InputTag = gdk_input_add(NetBuf->fd, | |
- (Read ? GDK_INPUT_READ : 0) | | |
- (Write ? GDK_INPUT_WRITE : 0), | |
- GetClientMessage, | |
- NetBuf->CallBackData); | |
- } | |
- if (CallNow) | |
- GetClientMessage(NetBuf->CallBackData, NetBuf->fd, 0); | |
-} | |
-#endif /* NETWORKING */ | |
- | |
-void HandleClientMessage(char *pt, Player *Play) | |
-{ | |
- char *Data; | |
- DispMode DisplayMode; | |
- AICode AI; | |
- MsgCode Code; | |
- Player *From, *tmp; | |
- gchar *text; | |
- gboolean Handled; | |
- GtkWidget *MenuItem; | |
- GSList *list; | |
- | |
- if (ProcessMessage(pt, Play, &From, &AI, &Code, | |
- &Data, FirstClient) == -1) { | |
- return; | |
- } | |
- | |
- Handled = | |
- HandleGenericClientMessage(From, AI, Code, Play, Data, &DisplayMode); | |
- switch (Code) { | |
- case C_STARTHISCORE: | |
- PrepareHighScoreDialog(); | |
- break; | |
- case C_HISCORE: | |
- AddScoreToDialog(Data); | |
- break; | |
- case C_ENDHISCORE: | |
- CompleteHighScoreDialog((strcmp(Data, "end") == 0)); | |
- break; | |
- case C_PRINTMESSAGE: | |
- PrintMessage(Data); | |
- break; | |
- case C_FIGHTPRINT: | |
- DisplayFightMessage(Data); | |
- break; | |
- case C_PUSH: | |
- /* The server admin has asked us to leave - so warn the user, and do | |
- * so */ | |
- g_warning(_("You have been pushed from the server.\n" | |
- "Switching to single player mode.")); | |
- SwitchToSinglePlayer(Play); | |
- UpdatePlayerLists(); | |
- UpdateMenus(); | |
- break; | |
- case C_QUIT: | |
- /* The server has sent us notice that it is shutting down */ | |
- g_warning(_("The server has terminated.\n" | |
- "Switching to single player mode.")); | |
- SwitchToSinglePlayer(Play); | |
- UpdatePlayerLists(); | |
- UpdateMenus(); | |
- break; | |
- case C_NEWNAME: | |
- NewNameDialog(); | |
- break; | |
- case C_BANK: | |
- TransferDialog(FALSE); | |
- break; | |
- case C_LOANSHARK: | |
- TransferDialog(TRUE); | |
- break; | |
- case C_GUNSHOP: | |
- GunShopDialog(); | |
- break; | |
- case C_MSG: | |
- text = g_strdup_printf("%s: %s", GetPlayerName(From), Data); | |
- PrintMessage(text); | |
- g_free(text); | |
- break; | |
- case C_MSGTO: | |
- text = g_strdup_printf("%s->%s: %s", GetPlayerName(From), | |
- GetPlayerName(Play), Data); | |
- PrintMessage(text); | |
- g_free(text); | |
- break; | |
- case C_JOIN: | |
- text = g_strdup_printf(_("%s joins the game!"), Data); | |
- PrintMessage(text); | |
- g_free(text); | |
- UpdatePlayerLists(); | |
- UpdateMenus(); | |
- break; | |
- case C_LEAVE: | |
- if (From != &Noone) { | |
- text = g_strdup_printf(_("%s has left the game."), Data); | |
- PrintMessage(text); | |
- g_free(text); | |
- UpdatePlayerLists(); | |
- UpdateMenus(); | |
- } | |
- break; | |
- case C_QUESTION: | |
- QuestionDialog(Data, From == &Noone ? NULL : From); | |
- break; | |
- case C_SUBWAYFLASH: | |
- DisplayFightMessage(NULL); | |
- for (list = FirstClient; list; list = g_slist_next(list)) { | |
- tmp = (Player *)list->data; | |
- tmp->Flags &= ~FIGHTING; | |
- } | |
- /* Message displayed when the player "jets" to a new location */ | |
- text = dpg_strdup_printf(_("Jetting to %tde"), | |
- Location[(int)Play->IsAt].Name); | |
- PrintMessage(text); | |
- g_free(text); | |
- break; | |
- case C_ENDLIST: | |
- MenuItem = gtk_item_factory_get_widget(ClientData.Menu, | |
- "<main>/Errands/Sack Bitch..."); | |
- | |
- /* Text for the Errands/Sack Bitch menu item */ | |
- text = dpg_strdup_printf(_("%/Sack Bitch menu item/S_ack %Tde..."), | |
- Names.Bitch); | |
- SetAccelerator(MenuItem, text, NULL, NULL, NULL); | |
- g_free(text); | |
- | |
- MenuItem = gtk_item_factory_get_widget(ClientData.Menu, | |
- "<main>/Errands/Spy..."); | |
- | |
- /* Text to update the Errands/Spy menu item with the price for spying */ | |
- text = dpg_strdup_printf(_("_Spy (%P)"), Prices.Spy); | |
- SetAccelerator(MenuItem, text, NULL, NULL, NULL); | |
- g_free(text); | |
- | |
- /* Text to update the Errands/Tipoff menu item with the price for a | |
- * tipoff */ | |
- text = dpg_strdup_printf(_("_Tipoff (%P)"), Prices.Tipoff); | |
- MenuItem = gtk_item_factory_get_widget(ClientData.Menu, | |
- "<main>/Errands/Tipoff..."); | |
- SetAccelerator(MenuItem, text, NULL, NULL, NULL); | |
- g_free(text); | |
- if (FirstClient->next) | |
- ListPlayers(NULL, NULL); | |
- UpdateMenus(); | |
- break; | |
- case C_UPDATE: | |
- if (From == &Noone) { | |
- ReceivePlayerData(Play, Data, Play); | |
- UpdateStatus(Play); | |
- } else { | |
- ReceivePlayerData(Play, Data, From); | |
- DisplaySpyReports(From); | |
- } | |
- break; | |
- case C_DRUGHERE: | |
- UpdateInventory(&ClientData.Drug, Play->Drugs, NumDrug, TRUE); | |
- gtk_clist_sort(GTK_CLIST(ClientData.Drug.HereList)); | |
- if (IsShowingInventory) { | |
- UpdateInventory(&ClientData.InvenDrug, Play->Drugs, NumDrug, TRUE); | |
- } | |
- break; | |
- default: | |
- if (!Handled) { | |
- g_print("Unknown network message received: %s^%c^%s^%s", | |
- GetPlayerName(From), Code, GetPlayerName(Play), Data); | |
- } | |
- break; | |
- } | |
-} | |
- | |
-struct HiScoreDiaStruct { | |
- GtkWidget *dialog, *table, *vbox; | |
-}; | |
-static struct HiScoreDiaStruct HiScoreDialog = { NULL, NULL, NULL }; | |
- | |
-/* | |
- * Creates an empty dialog to display high scores. | |
- */ | |
-void PrepareHighScoreDialog(void) | |
-{ | |
- GtkWidget *dialog, *vbox, *hsep, *table; | |
- | |
- /* Make sure the server doesn't fool us into creating multiple dialogs */ | |
- if (HiScoreDialog.dialog) | |
- return; | |
- | |
- HiScoreDialog.dialog = dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
- | |
- /* Title of the GTK+ high score dialog */ | |
- gtk_window_set_title(GTK_WINDOW(dialog), _("High Scores")); | |
- | |
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
- GTK_WINDOW(ClientData.window)); | |
- | |
- HiScoreDialog.vbox = vbox = gtk_vbox_new(FALSE, 7); | |
- HiScoreDialog.table = table = gtk_table_new(NUMHISCORE, 4, FALSE); | |
- gtk_table_set_row_spacings(GTK_TABLE(table), 5); | |
- gtk_table_set_col_spacings(GTK_TABLE(table), 30); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0); | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
- gtk_widget_show_all(dialog); | |
-} | |
- | |
-/* | |
- * Adds a single high score (coded in "Data", which is the information | |
- * received in the relevant network message) to the dialog created by | |
- * PrepareHighScoreDialog(), above. | |
- */ | |
-void AddScoreToDialog(char *Data) | |
-{ | |
- GtkWidget *label; | |
- char *cp; | |
- gchar **spl1, **spl2; | |
- int index, slen; | |
- gboolean bold; | |
- | |
- if (!HiScoreDialog.dialog) | |
- return; | |
- | |
- cp = Data; | |
- index = GetNextInt(&cp, 0); | |
- if (!cp || strlen(cp) < 3) | |
- return; | |
- | |
- bold = (*cp == 'B'); /* Is this score "our" score? (Currently | |
- * ignored) */ | |
- | |
- /* Step past the 'bold' character, and the initial '>' (if present) */ | |
- cp += 2; | |
- g_strchug(cp); | |
- | |
- /* Get the first word - the score */ | |
- spl1 = g_strsplit(cp, " ", 1); | |
- if (!spl1 || !spl1[0] || !spl1[1]) { | |
- /* Error - the high score from the server is invalid */ | |
- g_warning(_("Corrupt high score!")); | |
- g_strfreev(spl1); | |
- return; | |
- } | |
- label = gtk_label_new(spl1[0]); | |
- gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); | |
- gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label, | |
- 0, 1, index, index + 1); | |
- gtk_widget_show(label); | |
- | |
- /* Remove any leading whitespace from the remainder, since g_strsplit | |
- * will split at every space character, not at a run of them */ | |
- g_strchug(spl1[1]); | |
- | |
- /* Get the second word - the date */ | |
- spl2 = g_strsplit(spl1[1], " ", 1); | |
- if (!spl2 || !spl2[0] || !spl2[1]) { | |
- g_warning(_("Corrupt high score!")); | |
- g_strfreev(spl2); | |
- return; | |
- } | |
- label = gtk_label_new(spl2[0]); | |
- gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5); | |
- gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label, | |
- 1, 2, index, index + 1); | |
- gtk_widget_show(label); | |
- | |
- /* The remainder is the name, terminated with (R.I.P.) if the player | |
- * died, and '<' for the 'current' score */ | |
- g_strchug(spl2[1]); | |
- | |
- /* Remove '<' suffix if present */ | |
- slen = strlen(spl2[1]); | |
- if (slen >= 1 && spl2[1][slen - 1] == '<') { | |
- spl2[1][slen - 1] = '\0'; | |
- } | |
- slen--; | |
- | |
- /* Check for (R.I.P.) suffix, and add it to the 4th column if found */ | |
- if (slen > 8 && spl2[1][slen - 1] == ')' && spl2[1][slen - 8] == '(') { | |
- label = gtk_label_new(&spl2[1][slen - 8]); | |
- gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5); | |
- gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label, | |
- 3, 4, index, index + 1); | |
- gtk_widget_show(label); | |
- spl2[1][slen - 8] = '\0'; /* Remove suffix from the player name */ | |
- } | |
- | |
- /* Finally, add in what's left of the player name */ | |
- g_strchomp(spl2[1]); | |
- label = gtk_label_new(spl2[1]); | |
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
- gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label, | |
- 2, 3, index, index + 1); | |
- gtk_widget_show(label); | |
- | |
- g_strfreev(spl1); | |
- g_strfreev(spl2); | |
-} | |
- | |
-/* | |
- * If the high scores are being displayed at the end of the game, | |
- * this function is used to end the game when the high score dialog's | |
- * "OK" button is pressed. | |
- */ | |
-static void EndHighScore(GtkWidget *widget) | |
-{ | |
- EndGame(); | |
-} | |
- | |
-/* | |
- * Called when all high scores have been received. Finishes off the | |
- * high score dialog by adding an "OK" button. If the game has ended, | |
- * then "AtEnd" is TRUE, and clicking this button will end the game. | |
- */ | |
-void CompleteHighScoreDialog(gboolean AtEnd) | |
-{ | |
- GtkWidget *OKButton, *dialog; | |
- | |
- dialog = HiScoreDialog.dialog; | |
- | |
- if (!HiScoreDialog.dialog) | |
- return; | |
- | |
- /* Caption of the "OK" button in dialogs */ | |
- OKButton = gtk_button_new_with_label(_("OK")); | |
- gtk_signal_connect_object(GTK_OBJECT(OKButton), "clicked", | |
- GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
- (gpointer)dialog); | |
- if (AtEnd) { | |
- InGame = FALSE; | |
- gtk_signal_connect_object(GTK_OBJECT(dialog), "destroy", | |
- GTK_SIGNAL_FUNC(EndHighScore), NULL); | |
- } | |
- gtk_box_pack_start(GTK_BOX(HiScoreDialog.vbox), OKButton, TRUE, TRUE, 0); | |
- | |
- GTK_WIDGET_SET_FLAGS(OKButton, GTK_CAN_DEFAULT); | |
- gtk_widget_grab_default(OKButton); | |
- gtk_widget_show(OKButton); | |
- | |
- /* OK, we're done - allow the creation of new high score dialogs */ | |
- HiScoreDialog.dialog = NULL; | |
-} | |
- | |
-/* | |
- * Prints an information message in the display area of the GTK+ client. | |
- * This area is used for displaying drug busts, messages from other | |
- * players, etc. The message is passed in as the string "text". | |
- */ | |
-void PrintMessage(char *text) | |
-{ | |
- gint EditPos; | |
- char *cr = "\n"; | |
- GtkEditable *messages; | |
- | |
- messages = GTK_EDITABLE(ClientData.messages); | |
- | |
- gtk_text_freeze(GTK_TEXT(messages)); | |
- g_strdelimit(text, "^", '\n'); | |
- EditPos = gtk_text_get_length(GTK_TEXT(ClientData.messages)); | |
- while (*text == '\n') | |
- text++; | |
- gtk_editable_insert_text(messages, text, strlen(text), &EditPos); | |
- if (text[strlen(text) - 1] != '\n') { | |
- gtk_editable_insert_text(messages, cr, strlen(cr), &EditPos); | |
- } | |
- gtk_text_thaw(GTK_TEXT(messages)); | |
- gtk_editable_set_position(messages, EditPos); | |
-} | |
- | |
-/* | |
- * Called when one of the action buttons in the Fight dialog is clicked. | |
- * "data" specifies which button (Deal Drugs/Run/Fight/Stand) was pressed. | |
- */ | |
-static void FightCallback(GtkWidget *widget, gpointer data) | |
-{ | |
- gint Answer; | |
- Player *Play; | |
- gchar text[4]; | |
- GtkWidget *window; | |
- gpointer CanRunHere = NULL; | |
- | |
- window = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); | |
- if (window) | |
- CanRunHere = gtk_object_get_data(GTK_OBJECT(window), "CanRunHere"); | |
- | |
- Answer = GPOINTER_TO_INT(data); | |
- Play = ClientData.Play; | |
- switch (Answer) { | |
- case 'D': | |
- gtk_widget_hide(FightDialog); | |
- break; | |
- case 'R': | |
- if (CanRunHere) { | |
- SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, "R"); | |
- } else { | |
- Jet(FightDialog); | |
- } | |
- break; | |
- case 'F': | |
- case 'S': | |
- text[0] = Answer; | |
- text[1] = '\0'; | |
- SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, text); | |
- break; | |
- } | |
-} | |
- | |
-/* | |
- * Adds an action button to the hbox at the base of the Fight dialog. | |
- * The button's caption is given by "Text", and the keyboard shortcut | |
- * (if any) is added to "accel_group". "Answer" gives the identifier | |
- * passed to FightCallback, above. | |
- */ | |
-static GtkWidget *AddFightButton(gchar *Text, GtkAccelGroup *accel_group, | |
- GtkBox *box, gint Answer) | |
-{ | |
- GtkWidget *button; | |
- | |
- button = gtk_button_new_with_label(""); | |
- SetAccelerator(button, Text, button, "clicked", accel_group); | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(FightCallback), | |
- GINT_TO_POINTER(Answer)); | |
- gtk_box_pack_start(box, button, TRUE, TRUE, 0); | |
- return button; | |
-} | |
- | |
-/* Data used to keep track of the widgets giving the information about a | |
- * player/cop involved in a fight */ | |
-struct combatant { | |
- GtkWidget *name, *bitches, *healthprog, *healthlabel; | |
-}; | |
- | |
-/* | |
- * Creates an empty Fight dialog. Usually this only needs to be done once, | |
- * as when the user "closes" it, it is only hidden, ready to be reshown | |
- * later. Buttons for all actions are added here, and are hidden/shown | |
- * as necessary. | |
- */ | |
-static void CreateFightDialog(void) | |
-{ | |
- GtkWidget *dialog, *vbox, *button, *hbox, *hbbox, *hsep, *text, *table; | |
- GtkAccelGroup *accel_group; | |
- GArray *combatants; | |
- gchar *buf; | |
- | |
- FightDialog = dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
- gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300); | |
- gtk_signal_connect(GTK_OBJECT(dialog), "delete_event", | |
- GTK_SIGNAL_FUNC(DisallowDelete), NULL); | |
- gtk_window_set_default_size(GTK_WINDOW(dialog), 240, 130); | |
- accel_group = gtk_accel_group_new(); | |
- gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group); | |
- gtk_window_set_title(GTK_WINDOW(dialog), _("Fight")); | |
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
- | |
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
- GTK_WINDOW(ClientData.window)); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- | |
- table = gtk_table_new(2, 4, FALSE); | |
- gtk_table_set_row_spacings(GTK_TABLE(table), 5); | |
- gtk_table_set_col_spacings(GTK_TABLE(table), 5); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_table_attach_defaults(GTK_TABLE(table), hsep, 0, 4, 1, 2); | |
- gtk_widget_show_all(table); | |
- gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); | |
- gtk_object_set_data(GTK_OBJECT(dialog), "table", table); | |
- | |
- combatants = g_array_new(FALSE, TRUE, sizeof(struct combatant)); | |
- g_array_set_size(combatants, 1); | |
- gtk_object_set_data(GTK_OBJECT(dialog), "combatants", combatants); | |
- | |
- text = gtk_scrolled_text_new(NULL, NULL, &hbox); | |
- gtk_widget_set_usize(text, 150, 120); | |
- | |
- gtk_text_set_editable(GTK_TEXT(text), FALSE); | |
- gtk_text_set_word_wrap(GTK_TEXT(text), TRUE); | |
- gtk_object_set_data(GTK_OBJECT(dialog), "text", text); | |
- gtk_widget_show_all(hbox); | |
- gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- gtk_widget_show(hsep); | |
- | |
- hbbox = gtk_hbutton_box_new(); | |
- | |
- /* Button for closing the "Fight" dialog and going back to dealing drugs | |
- * (%Tde = "Drugs" by default) */ | |
- buf = dpg_strdup_printf(_("_Deal %Tde"), Names.Drugs); | |
- button = AddFightButton(buf, accel_group, GTK_BOX(hbbox), 'D'); | |
- gtk_object_set_data(GTK_OBJECT(dialog), "deal", button); | |
- g_free(buf); | |
- | |
- /* Button for shooting at other players in the "Fight" dialog, or for | |
- * popping up the "Fight" dialog from the main window */ | |
- button = AddFightButton(_("_Fight"), accel_group, GTK_BOX(hbbox), 'F'); | |
- gtk_object_set_data(GTK_OBJECT(dialog), "fight", button); | |
- | |
- /* Button to stand and take it in the "Fight" dialog */ | |
- button = AddFightButton(_("_Stand"), accel_group, GTK_BOX(hbbox), 'S'); | |
- gtk_object_set_data(GTK_OBJECT(dialog), "stand", button); | |
- | |
- /* Button to run from combat in the "Fight" dialog */ | |
- button = AddFightButton(_("_Run"), accel_group, GTK_BOX(hbbox), 'R'); | |
- gtk_object_set_data(GTK_OBJECT(dialog), "run", button); | |
- | |
- gtk_widget_show(hsep); | |
- gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0); | |
- gtk_widget_show(hbbox); | |
- gtk_widget_show(vbox); | |
- gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
- gtk_widget_show(dialog); | |
-} | |
- | |
-/* | |
- * Updates the display of information for a player/cop in the Fight dialog. | |
- * If the player's name (DefendName) already exists, updates the display of | |
- * total health and number of bitches - otherwise, adds a new entry. If | |
- * DefendBitches is -1, then the player has left. | |
- */ | |
-static void UpdateCombatant(gchar *DefendName, int DefendBitches, | |
- gchar *BitchName, int DefendHealth) | |
-{ | |
- guint i, RowIndex; | |
- gchar *name; | |
- struct combatant *compt; | |
- GArray *combatants; | |
- GtkWidget *table; | |
- gchar *BitchText, *HealthText; | |
- gfloat ProgPercent; | |
- | |
- combatants = (GArray *)gtk_object_get_data(GTK_OBJECT(FightDialog), | |
- "combatants"); | |
- table = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "table")); | |
- if (!combatants) | |
- return; | |
- | |
- if (DefendName[0]) { | |
- compt = NULL; | |
- for (i = 1, RowIndex = 2; i < combatants->len; i++, RowIndex++) { | |
- compt = &g_array_index(combatants, struct combatant, i); | |
- | |
- if (!compt || !compt->name) { | |
- compt = NULL; | |
- continue; | |
- } | |
- gtk_label_get(GTK_LABEL(compt->name), &name); | |
- if (name && strcmp(name, DefendName) == 0) | |
- break; | |
- compt = NULL; | |
- } | |
- if (!compt) { | |
- i = combatants->len; | |
- g_array_set_size(combatants, i + 1); | |
- compt = &g_array_index(combatants, struct combatant, i); | |
- | |
- gtk_table_resize(GTK_TABLE(table), i + 2, 4); | |
- RowIndex = i + 1; | |
- } | |
- } else { | |
- compt = &g_array_index(combatants, struct combatant, 0); | |
- | |
- RowIndex = 0; | |
- } | |
- | |
- /* Display of number of bitches or deputies during combat | |
- * (%tde="bitches" or "deputies" (etc.) by default) */ | |
- BitchText = dpg_strdup_printf(_("%/Combat: Bitches/%d %tde"), | |
- DefendBitches, BitchName); | |
- | |
- /* Display of health during combat */ | |
- if (DefendBitches == -1) { | |
- HealthText = g_strdup(_("(Left)")); | |
- } else if (DefendHealth == 0 && DefendBitches == 0) { | |
- HealthText = g_strdup(_("(Dead)")); | |
- } else { | |
- HealthText = g_strdup_printf(_("Health: %d"), DefendHealth); | |
- } | |
- | |
- ProgPercent = (gfloat)DefendHealth / 100.0; | |
- | |
- if (compt->name) { | |
- if (DefendName[0]) { | |
- gtk_label_set_text(GTK_LABEL(compt->name), DefendName); | |
- } | |
- if (DefendBitches >= 0) { | |
- gtk_label_set_text(GTK_LABEL(compt->bitches), BitchText); | |
- } | |
- gtk_label_set_text(GTK_LABEL(compt->healthlabel), HealthText); | |
- gtk_progress_bar_update(GTK_PROGRESS_BAR(compt->healthprog), | |
- ProgPercent); | |
- } else { | |
- /* Display of the current player's name during combat */ | |
- compt->name = gtk_label_new(DefendName[0] ? DefendName : _("You")); | |
- | |
- gtk_table_attach_defaults(GTK_TABLE(table), compt->name, 0, 1, | |
- RowIndex, RowIndex + 1); | |
- compt->bitches = gtk_label_new(DefendBitches >= 0 ? BitchText : ""); | |
- gtk_table_attach_defaults(GTK_TABLE(table), compt->bitches, 1, 2, | |
- RowIndex, RowIndex + 1); | |
- compt->healthprog = gtk_progress_bar_new(); | |
- gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(compt->healthprog), | |
- GTK_PROGRESS_LEFT_TO_RIGHT); | |
- gtk_progress_bar_update(GTK_PROGRESS_BAR(compt->healthprog), | |
- ProgPercent); | |
- gtk_table_attach_defaults(GTK_TABLE(table), compt->healthprog, 2, 3, | |
- RowIndex, RowIndex + 1); | |
- compt->healthlabel = gtk_label_new(HealthText); | |
- gtk_table_attach_defaults(GTK_TABLE(table), compt->healthlabel, 3, 4, | |
- RowIndex, RowIndex + 1); | |
- gtk_widget_show(compt->name); | |
- gtk_widget_show(compt->bitches); | |
- gtk_widget_show(compt->healthprog); | |
- gtk_widget_show(compt->healthlabel); | |
- } | |
- | |
- g_free(BitchText); | |
- g_free(HealthText); | |
-} | |
- | |
-/* | |
- * Cleans up the list of all players/cops involved in a fight. | |
- */ | |
-static void FreeCombatants(void) | |
-{ | |
- GArray *combatants; | |
- | |
- combatants = (GArray *)gtk_object_get_data(GTK_OBJECT(FightDialog), | |
- "combatants"); | |
- if (!combatants) | |
- return; | |
- | |
- g_array_free(combatants, TRUE); | |
-} | |
- | |
-/* | |
- * Given the network message "Data" concerning some happening during | |
- * combat, extracts the relevant data and updates the Fight dialog, | |
- * creating and/or showing it if necessary. | |
- * If "Data" is NULL, then closes the dialog. If "Data" is a blank | |
- * string, then just shows the dialog, displaying no new messages. | |
- */ | |
-void DisplayFightMessage(char *Data) | |
-{ | |
- Player *Play; | |
- gint EditPos; | |
- GtkAccelGroup *accel_group; | |
- GtkWidget *Deal, *Fight, *Stand, *Run, *Text; | |
- char cr[] = "\n"; | |
- gchar *AttackName, *DefendName, *BitchName, *Message; | |
- FightPoint fp; | |
- int DefendHealth, DefendBitches, BitchesKilled, ArmPercent; | |
- gboolean CanRunHere, Loot, CanFire; | |
- | |
- if (!Data) { | |
- if (FightDialog) { | |
- FreeCombatants(); | |
- gtk_widget_destroy(FightDialog); | |
- FightDialog = NULL; | |
- } | |
- return; | |
- } | |
- if (FightDialog) { | |
- if (!GTK_WIDGET_VISIBLE(FightDialog)) | |
- gtk_widget_show(FightDialog); | |
- } else { | |
- CreateFightDialog(); | |
- } | |
- if (!FightDialog || !Data[0]) | |
- return; | |
- | |
- Deal = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "deal")); | |
- Fight = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "fight")); | |
- Stand = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "stand")); | |
- Run = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "run")); | |
- Text = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "text")); | |
- | |
- Play = ClientData.Play; | |
- | |
- if (HaveAbility(Play, A_NEWFIGHT)) { | |
- ReceiveFightMessage(Data, &AttackName, &DefendName, &DefendHealth, | |
- &DefendBitches, &BitchName, &BitchesKilled, | |
- &ArmPercent, &fp, &CanRunHere, &Loot, &CanFire, | |
- &Message); | |
- Play->Flags |= FIGHTING; | |
- switch (fp) { | |
- case F_HIT: | |
- case F_ARRIVED: | |
- case F_MISS: | |
- UpdateCombatant(DefendName, DefendBitches, BitchName, DefendHealth); | |
- break; | |
- case F_LEAVE: | |
- if (AttackName[0]) { | |
- UpdateCombatant(AttackName, -1, BitchName, 0); | |
- } | |
- break; | |
- case F_LASTLEAVE: | |
- Play->Flags &= ~FIGHTING; | |
- break; | |
- default: | |
- } | |
- accel_group = (GtkAccelGroup *) | |
- gtk_object_get_data(GTK_OBJECT(ClientData.window), "accel_group"); | |
- SetJetButtonTitle(accel_group); | |
- } else { | |
- Message = Data; | |
- if (Play->Flags & FIGHTING) | |
- fp = F_MSG; | |
- else | |
- fp = F_LASTLEAVE; | |
- CanFire = (Play->Flags & CANSHOOT); | |
- CanRunHere = FALSE; | |
- } | |
- gtk_object_set_data(GTK_OBJECT(FightDialog), "CanRunHere", | |
- GINT_TO_POINTER(CanRunHere)); | |
- | |
- g_strdelimit(Message, "^", '\n'); | |
- if (strlen(Message) > 0) { | |
- EditPos = gtk_text_get_length(GTK_TEXT(Text)); | |
- gtk_editable_insert_text(GTK_EDITABLE(Text), Message, | |
- strlen(Message), &EditPos); | |
- gtk_editable_insert_text(GTK_EDITABLE(Text), cr, strlen(cr), &EditPos); | |
- } | |
- | |
- if (!CanRunHere || fp == F_LASTLEAVE) | |
- gtk_widget_show(Deal); | |
- else | |
- gtk_widget_hide(Deal); | |
- if (CanFire && TotalGunsCarried(Play) > 0) | |
- gtk_widget_show(Fight); | |
- else | |
- gtk_widget_hide(Fight); | |
- if (CanFire && TotalGunsCarried(Play) == 0) | |
- gtk_widget_show(Stand); | |
- else | |
- gtk_widget_hide(Stand); | |
- if (fp != F_LASTLEAVE) | |
- gtk_widget_show(Run); | |
- else | |
- gtk_widget_hide(Run); | |
-} | |
- | |
-/* | |
- * Updates the display of pertinent data about player "Play" (location, | |
- * health, etc. in the status widgets given by "Status". This can point | |
- * to the widgets at the top of the main window, or those in a Spy | |
- * Reports dialog. | |
- */ | |
-void DisplayStats(Player *Play, struct StatusWidgets *Status) | |
-{ | |
- gchar *prstr; | |
- GString *text; | |
- | |
- text = g_string_new(NULL); | |
- | |
- gtk_label_set_text(GTK_LABEL(Status->Location), | |
- Location[(int)Play->IsAt].Name); | |
- | |
- g_string_sprintf(text, "%s%02d%s", Names.Month, Play->Turn, Names.Year); | |
- gtk_label_set_text(GTK_LABEL(Status->Date), text->str); | |
- | |
- g_string_sprintf(text, "%d", Play->CoatSize); | |
- gtk_label_set_text(GTK_LABEL(Status->SpaceValue), text->str); | |
- | |
- prstr = FormatPrice(Play->Cash); | |
- gtk_label_set_text(GTK_LABEL(Status->CashValue), prstr); | |
- g_free(prstr); | |
- | |
- prstr = FormatPrice(Play->Bank); | |
- gtk_label_set_text(GTK_LABEL(Status->BankValue), prstr); | |
- g_free(prstr); | |
- | |
- prstr = FormatPrice(Play->Debt); | |
- gtk_label_set_text(GTK_LABEL(Status->DebtValue), prstr); | |
- g_free(prstr); | |
- | |
- /* Display of carried guns in GTK+ client status window (%Tde="Guns" by | |
- * default) */ | |
- dpg_string_sprintf(text, _("%/GTK Stats: Guns/%Tde"), Names.Guns); | |
- gtk_label_set_text(GTK_LABEL(Status->GunsName), text->str); | |
- g_string_sprintf(text, "%d", TotalGunsCarried(Play)); | |
- gtk_label_set_text(GTK_LABEL(Status->GunsValue), text->str); | |
- | |
- if (!WantAntique) { | |
- /* Display of number of bitches in GTK+ client status window | |
- * (%Tde="Bitches" by default) */ | |
- dpg_string_sprintf(text, _("%/GTK Stats: Bitches/%Tde"), | |
- Names.Bitches); | |
- gtk_label_set_text(GTK_LABEL(Status->BitchesName), text->str); | |
- g_string_sprintf(text, "%d", Play->Bitches.Carried); | |
- gtk_label_set_text(GTK_LABEL(Status->BitchesValue), text->str); | |
- } else { | |
- gtk_label_set_text(GTK_LABEL(Status->BitchesName), NULL); | |
- gtk_label_set_text(GTK_LABEL(Status->BitchesValue), NULL); | |
- } | |
- | |
- g_string_sprintf(text, "%d", Play->Health); | |
- gtk_label_set_text(GTK_LABEL(Status->HealthValue), text->str); | |
- | |
- g_string_free(text, TRUE); | |
-} | |
- | |
-/* | |
- * Updates all of the player status in response to a message from the | |
- * server. This includes the main window display, the gun shop (if | |
- * displayed) and the inventory (if displayed). | |
- */ | |
-void UpdateStatus(Player *Play) | |
-{ | |
- GtkAccelGroup *accel_group; | |
- | |
- DisplayStats(Play, &ClientData.Status); | |
- UpdateInventory(&ClientData.Drug, ClientData.Play->Drugs, NumDrug, TRUE); | |
- gtk_clist_sort(GTK_CLIST(ClientData.Drug.HereList)); | |
- accel_group = (GtkAccelGroup *) | |
- gtk_object_get_data(GTK_OBJECT(ClientData.window), "accel_group"); | |
- SetJetButtonTitle(accel_group); | |
- if (IsShowingGunShop) { | |
- UpdateInventory(&ClientData.Gun, ClientData.Play->Guns, NumGun, FALSE); | |
- } | |
- if (IsShowingInventory) { | |
- UpdateInventory(&ClientData.InvenDrug, ClientData.Play->Drugs, | |
- NumDrug, TRUE); | |
- UpdateInventory(&ClientData.InvenGun, ClientData.Play->Guns, | |
- NumGun, FALSE); | |
- } | |
-} | |
- | |
-void UpdateInventory(struct InventoryWidgets *Inven, | |
- Inventory *Objects, int NumObjects, gboolean AreDrugs) | |
-{ | |
- GtkWidget *herelist, *carrylist; | |
- Player *Play; | |
- gint i, row, selectrow[2]; | |
- gpointer rowdata; | |
- price_t price; | |
- gchar *titles[2]; | |
- gboolean CanBuy = FALSE, CanSell = FALSE, CanDrop = FALSE; | |
- GList *glist[2], *selection; | |
- GtkCList *clist[2]; | |
- int numlist; | |
- | |
- Play = ClientData.Play; | |
- herelist = Inven->HereList; | |
- carrylist = Inven->CarriedList; | |
- | |
- if (herelist) | |
- numlist = 2; | |
- else | |
- numlist = 1; | |
- | |
- /* Make lists of the current selections */ | |
- clist[0] = GTK_CLIST(carrylist); | |
- if (herelist) | |
- clist[1] = GTK_CLIST(herelist); | |
- else | |
- clist[1] = NULL; | |
- | |
- for (i = 0; i < numlist; i++) { | |
- glist[i] = NULL; | |
- selectrow[i] = -1; | |
- for (selection = clist[i]->selection; selection; | |
- selection = g_list_next(selection)) { | |
- row = GPOINTER_TO_INT(selection->data); | |
- rowdata = gtk_clist_get_row_data(clist[i], row); | |
- glist[i] = g_list_append(glist[i], rowdata); | |
- } | |
- } | |
- | |
- gtk_clist_freeze(GTK_CLIST(carrylist)); | |
- gtk_clist_clear(GTK_CLIST(carrylist)); | |
- | |
- if (herelist) { | |
- gtk_clist_freeze(GTK_CLIST(herelist)); | |
- gtk_clist_clear(GTK_CLIST(herelist)); | |
- } | |
- | |
- for (i = 0; i < NumObjects; i++) { | |
- if (AreDrugs) { | |
- titles[0] = Drug[i].Name; | |
- price = Objects[i].Price; | |
- } else { | |
- titles[0] = Gun[i].Name; | |
- price = Gun[i].Price; | |
- } | |
- | |
- if (herelist && price > 0) { | |
- CanBuy = TRUE; | |
- titles[1] = FormatPrice(price); | |
- row = gtk_clist_append(GTK_CLIST(herelist), titles); | |
- g_free(titles[1]); | |
- gtk_clist_set_row_data(GTK_CLIST(herelist), row, GINT_TO_POINTER(i)); | |
- if (g_list_find(glist[1], GINT_TO_POINTER(i))) { | |
- selectrow[1] = row; | |
- gtk_clist_select_row(GTK_CLIST(herelist), row, 0); | |
- } | |
- } | |
- | |
- if (Objects[i].Carried > 0) { | |
- if (price > 0) | |
- CanSell = TRUE; | |
- else | |
- CanDrop = TRUE; | |
- if (HaveAbility(ClientData.Play, A_DRUGVALUE) && AreDrugs) { | |
- titles[1] = dpg_strdup_printf("%d @ %P", Objects[i].Carried, | |
- Objects[i].TotalValue / | |
- Objects[i].Carried); | |
- } else { | |
- titles[1] = g_strdup_printf("%d", Objects[i].Carried); | |
- } | |
- row = gtk_clist_append(GTK_CLIST(carrylist), titles); | |
- g_free(titles[1]); | |
- gtk_clist_set_row_data(GTK_CLIST(carrylist), row, | |
- GINT_TO_POINTER(i)); | |
- if (g_list_find(glist[0], GINT_TO_POINTER(i))) { | |
- selectrow[0] = row; | |
- gtk_clist_select_row(GTK_CLIST(carrylist), row, 0); | |
- } | |
- } | |
- } | |
- | |
- for (i = 0; i < numlist; i++) { | |
- if (selectrow[i] != -1 && gtk_clist_row_is_visible(clist[i], | |
- selectrow[i]) != | |
- GTK_VISIBILITY_FULL) { | |
- gtk_clist_moveto(clist[i], selectrow[i], 0, 0.0, 0.0); | |
- } | |
- g_list_free(glist[i]); | |
- } | |
- | |
- gtk_clist_thaw(GTK_CLIST(carrylist)); | |
- if (herelist) | |
- gtk_clist_thaw(GTK_CLIST(herelist)); | |
- | |
- if (Inven->vbbox) { | |
- gtk_widget_set_sensitive(Inven->BuyButton, CanBuy); | |
- gtk_widget_set_sensitive(Inven->SellButton, CanSell); | |
- gtk_widget_set_sensitive(Inven->DropButton, CanDrop); | |
- } | |
-} | |
- | |
-static void JetCallback(GtkWidget *widget, gpointer data) | |
-{ | |
- int NewLocation; | |
- gchar *text; | |
- GtkWidget *JetDialog; | |
- | |
- JetDialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "dialog")); | |
- NewLocation = GPOINTER_TO_INT(data); | |
- gtk_widget_destroy(JetDialog); | |
- text = g_strdup_printf("%d", NewLocation); | |
- SendClientMessage(ClientData.Play, C_NONE, C_REQUESTJET, NULL, text); | |
- g_free(text); | |
-} | |
- | |
-void JetButtonPressed(GtkWidget *widget, gpointer data) | |
-{ | |
- if (InGame) { | |
- if (ClientData.Play->Flags & FIGHTING) { | |
- DisplayFightMessage(NULL); | |
- } else { | |
- Jet(NULL); | |
- } | |
- } | |
-} | |
- | |
-void Jet(GtkWidget *parent) | |
-{ | |
- GtkWidget *dialog, *table, *button, *label, *vbox; | |
- GtkAccelGroup *accel_group; | |
- gint boxsize, i, row, col; | |
- gchar *name, AccelChar; | |
- | |
- accel_group = gtk_accel_group_new(); | |
- | |
- dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
- /* Title of 'Jet' dialog */ | |
- gtk_window_set_title(GTK_WINDOW(dialog), _("Jet to location")); | |
- | |
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
- gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group); | |
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
- parent ? GTK_WINDOW(parent) | |
- : GTK_WINDOW(ClientData.window)); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- | |
- /* Prompt in 'Jet' dialog */ | |
- label = gtk_label_new(_("Where to, dude ? ")); | |
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
- | |
- /* Generate a square box of buttons for all locations */ | |
- boxsize = 1; | |
- while (boxsize * boxsize < NumLocation) | |
- boxsize++; | |
- col = boxsize; | |
- row = 1; | |
- | |
- /* Avoid creating a box with an entire row empty at the bottom */ | |
- while (row * col < NumLocation) | |
- row++; | |
- | |
- table = gtk_table_new(row, col, TRUE); | |
- | |
- for (i = 0; i < NumLocation; i++) { | |
- if (i < 9) | |
- AccelChar = '1' + i; | |
- else if (i < 35) | |
- AccelChar = 'A' + i - 9; | |
- else | |
- AccelChar = '\0'; | |
- | |
- row = i / boxsize; | |
- col = i % boxsize; | |
- if (AccelChar == '\0') { | |
- button = gtk_button_new_with_label(Location[i].Name); | |
- } else { | |
- button = gtk_button_new_with_label(""); | |
- | |
- /* Display of locations in 'Jet' window (%tde="The Bronx" etc. by | |
- * default) */ | |
- name = dpg_strdup_printf(_("_%c. %tde"), AccelChar, Location[i].Name); | |
- SetAccelerator(button, name, button, "clicked", accel_group); | |
- /* Add keypad shortcuts as well */ | |
- if (i < 9) { | |
- gtk_widget_add_accelerator(button, "clicked", accel_group, | |
- GDK_KP_1 + i, 0, | |
- GTK_ACCEL_VISIBLE | | |
- GTK_ACCEL_SIGNAL_VISIBLE); | |
- } | |
- g_free(name); | |
- } | |
- gtk_widget_set_sensitive(button, i != ClientData.Play->IsAt); | |
- gtk_object_set_data(GTK_OBJECT(button), "dialog", dialog); | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(JetCallback), GINT_TO_POINTER(i)); | |
- gtk_table_attach_defaults(GTK_TABLE(table), button, col, col + 1, row, | |
- row + 1); | |
- } | |
- gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0); | |
- | |
- gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
- gtk_widget_show_all(dialog); | |
-} | |
- | |
-struct DealDiaStruct { | |
- GtkWidget *dialog, *cost, *carrying, *space, *afford, *amount; | |
- gint DrugInd; | |
- gpointer Type; | |
-}; | |
-static struct DealDiaStruct DealDialog; | |
- | |
-static void UpdateDealDialog(void) | |
-{ | |
- GString *text; | |
- GtkAdjustment *spin_adj; | |
- gint DrugInd, CanDrop, CanCarry, CanAfford, MaxDrug; | |
- Player *Play; | |
- | |
- text = g_string_new(NULL); | |
- DrugInd = DealDialog.DrugInd; | |
- Play = ClientData.Play; | |
- | |
- /* Display of the current price of the selected drug in 'Deal Drugs' | |
- * dialog */ | |
- dpg_string_sprintf(text, _("at %P"), Play->Drugs[DrugInd].Price); | |
- gtk_label_set_text(GTK_LABEL(DealDialog.cost), text->str); | |
- | |
- CanDrop = Play->Drugs[DrugInd].Carried; | |
- | |
- /* Display of current inventory of the selected drug in 'Deal Drugs' | |
- * dialog (%tde="Opium" etc. by default) */ | |
- dpg_string_sprintf(text, _("You are currently carrying %d %tde"), | |
- CanDrop, Drug[DrugInd].Name); | |
- gtk_label_set_text(GTK_LABEL(DealDialog.carrying), text->str); | |
- | |
- CanCarry = Play->CoatSize; | |
- | |
- /* Available space for drugs in 'Deal Drugs' dialog */ | |
- g_string_sprintf(text, _("Available space: %d"), CanCarry); | |
- gtk_label_set_text(GTK_LABEL(DealDialog.space), text->str); | |
- | |
- if (DealDialog.Type == BT_BUY) { | |
- CanAfford = Play->Cash / Play->Drugs[DrugInd].Price; | |
- | |
- /* Number of the selected drug that you can afford in 'Deal Drugs' | |
- * dialog */ | |
- g_string_sprintf(text, _("You can afford %d"), CanAfford); | |
- gtk_label_set_text(GTK_LABEL(DealDialog.afford), text->str); | |
- MaxDrug = MIN(CanCarry, CanAfford); | |
- } else | |
- MaxDrug = CanDrop; | |
- | |
- spin_adj = (GtkAdjustment *)gtk_adjustment_new(MaxDrug, 1.0, MaxDrug, | |
- 1.0, 10.0, 10.0); | |
- gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(DealDialog.amount), | |
- spin_adj); | |
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(DealDialog.amount), MaxDrug); | |
- | |
- g_string_free(text, TRUE); | |
-} | |
- | |
-static void DealSelectCallback(GtkWidget *widget, gpointer data) | |
-{ | |
- DealDialog.DrugInd = GPOINTER_TO_INT(data); | |
- UpdateDealDialog(); | |
-} | |
- | |
-static void DealOKCallback(GtkWidget *widget, gpointer data) | |
-{ | |
- GtkWidget *spinner; | |
- gint amount; | |
- gchar *text; | |
- | |
- spinner = DealDialog.amount; | |
- | |
- gtk_spin_button_update(GTK_SPIN_BUTTON(spinner)); | |
- amount = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner)); | |
- | |
- text = g_strdup_printf("drug^%d^%d", DealDialog.DrugInd, | |
- data == BT_BUY ? amount : -amount); | |
- SendClientMessage(ClientData.Play, C_NONE, C_BUYOBJECT, NULL, text); | |
- g_free(text); | |
- | |
- gtk_widget_destroy(DealDialog.dialog); | |
-} | |
- | |
-void DealDrugs(GtkWidget *widget, gpointer data) | |
-{ | |
- GtkWidget *dialog, *label, *hbox, *hbbox, *button, *spinner, *menu, | |
- *optionmenu, *menuitem, *vbox, *hsep; | |
- GtkAdjustment *spin_adj; | |
- GtkAccelGroup *accel_group; | |
- GtkWidget *clist; | |
- gchar *Action; | |
- GString *text; | |
- GList *selection; | |
- gint row; | |
- Player *Play; | |
- gint DrugInd, i, SelIndex, FirstInd; | |
- gboolean DrugIndOK; | |
- | |
- /* Action in 'Deal Drugs' dialog - "Buy/Sell/Drop Drugs" */ | |
- if (data == BT_BUY) | |
- Action = _("Buy"); | |
- else if (data == BT_SELL) | |
- Action = _("Sell"); | |
- else if (data == BT_DROP) | |
- Action = _("Drop"); | |
- else { | |
- g_warning("Bad DealDrug type"); | |
- return; | |
- } | |
- | |
- DealDialog.Type = data; | |
- Play = ClientData.Play; | |
- | |
- if (data == BT_BUY) | |
- clist = ClientData.Drug.HereList; | |
- else | |
- clist = ClientData.Drug.CarriedList; | |
- selection = GTK_CLIST(clist)->selection; | |
- if (selection) { | |
- row = GPOINTER_TO_INT(selection->data); | |
- DrugInd = | |
- GPOINTER_TO_INT(gtk_clist_get_row_data(GTK_CLIST(clist), row)); | |
- } else | |
- DrugInd = -1; | |
- | |
- DrugIndOK = FALSE; | |
- FirstInd = -1; | |
- for (i = 0; i < NumDrug; i++) { | |
- if ((data == BT_DROP && Play->Drugs[i].Carried > 0 | |
- && Play->Drugs[i].Price == 0) | |
- || (data == BT_SELL && Play->Drugs[i].Carried > 0 | |
- && Play->Drugs[i].Price != 0) | |
- || (data == BT_BUY && Play->Drugs[i].Price != 0)) { | |
- if (FirstInd == -1) | |
- FirstInd = i; | |
- if (DrugInd == i) | |
- DrugIndOK = TRUE; | |
- } | |
- } | |
- if (!DrugIndOK) { | |
- if (FirstInd == -1) | |
- return; | |
- else | |
- DrugInd = FirstInd; | |
- } | |
- | |
- text = g_string_new(NULL); | |
- accel_group = gtk_accel_group_new(); | |
- dialog = DealDialog.dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
- gtk_window_set_title(GTK_WINDOW(dialog), Action); | |
- gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group); | |
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
- GTK_WINDOW(ClientData.window)); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- | |
- hbox = gtk_hbox_new(FALSE, 7); | |
- | |
- label = gtk_label_new(Action); | |
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
- | |
- optionmenu = gtk_option_menu_new(); | |
- menu = gtk_menu_new(); | |
- SelIndex = -1; | |
- for (i = 0; i < NumDrug; i++) { | |
- if ((data == BT_DROP && Play->Drugs[i].Carried > 0 | |
- && Play->Drugs[i].Price == 0) | |
- || (data == BT_SELL && Play->Drugs[i].Carried > 0 | |
- && Play->Drugs[i].Price != 0) | |
- || (data == BT_BUY && Play->Drugs[i].Price != 0)) { | |
- menuitem = gtk_menu_item_new_with_label(Drug[i].Name); | |
- gtk_signal_connect(GTK_OBJECT(menuitem), "activate", | |
- GTK_SIGNAL_FUNC(DealSelectCallback), | |
- GINT_TO_POINTER(i)); | |
- gtk_menu_append(GTK_MENU(menu), menuitem); | |
- if (DrugInd >= i) | |
- SelIndex++; | |
- } | |
- } | |
- gtk_menu_set_active(GTK_MENU(menu), SelIndex); | |
- gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu), menu); | |
- gtk_box_pack_start(GTK_BOX(hbox), optionmenu, TRUE, TRUE, 0); | |
- | |
- DealDialog.DrugInd = DrugInd; | |
- | |
- label = DealDialog.cost = gtk_label_new(NULL); | |
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
- | |
- label = DealDialog.carrying = gtk_label_new(NULL); | |
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
- | |
- label = DealDialog.space = gtk_label_new(NULL); | |
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
- | |
- if (data == BT_BUY) { | |
- label = DealDialog.afford = gtk_label_new(NULL); | |
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
- } | |
- hbox = gtk_hbox_new(FALSE, 7); | |
- if (data == BT_BUY) { | |
- /* Prompts for action in the "deal drugs" dialog */ | |
- g_string_sprintf(text, _("Buy how many?")); | |
- } else if (data == BT_SELL) { | |
- g_string_sprintf(text, _("Sell how many?")); | |
- } else { | |
- g_string_sprintf(text, _("Drop how many?")); | |
- } | |
- label = gtk_label_new(text->str); | |
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
- spin_adj = (GtkAdjustment *)gtk_adjustment_new(1.0, 1.0, 2.0, | |
- 1.0, 10.0, 10.0); | |
- spinner = DealDialog.amount = gtk_spin_button_new(spin_adj, 1.0, 0); | |
- gtk_signal_connect(GTK_OBJECT(spinner), "activate", | |
- GTK_SIGNAL_FUNC(DealOKCallback), data); | |
- gtk_box_pack_start(GTK_BOX(hbox), spinner, FALSE, FALSE, 0); | |
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- | |
- hbbox = gtk_hbutton_box_new(); | |
- button = gtk_button_new_with_label(_("OK")); | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(DealOKCallback), data); | |
- GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); | |
- gtk_widget_grab_default(button); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- | |
- /* Caption of "Cancel" button for GTK+ client dialogs */ | |
- button = gtk_button_new_with_label(_("Cancel")); | |
- gtk_signal_connect_object(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
- (gpointer)dialog); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0); | |
- gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
- | |
- g_string_free(text, TRUE); | |
- UpdateDealDialog(); | |
- | |
- gtk_widget_show_all(dialog); | |
-} | |
- | |
-void DealGuns(GtkWidget *widget, gpointer data) | |
-{ | |
- GtkWidget *clist, *dialog; | |
- GList *selection; | |
- gint row, GunInd; | |
- gchar *Action, *Title; | |
- GString *text; | |
- | |
- dialog = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); | |
- if (data == BT_BUY) | |
- Action = _("Buy"); | |
- else if (data == BT_SELL) | |
- Action = _("Sell"); | |
- else | |
- Action = _("Drop"); | |
- | |
- if (data == BT_BUY) | |
- clist = ClientData.Gun.HereList; | |
- else | |
- clist = ClientData.Gun.CarriedList; | |
- selection = GTK_CLIST(clist)->selection; | |
- if (selection) { | |
- row = GPOINTER_TO_INT(selection->data); | |
- GunInd = | |
- GPOINTER_TO_INT(gtk_clist_get_row_data(GTK_CLIST(clist), row)); | |
- } else | |
- return; | |
- | |
- | |
- /* Title of 'gun shop' dialog (%tde="guns" by default) "Buy/Sell/Drop | |
- * Guns" */ | |
- if (data == BT_BUY) | |
- Title = dpg_strdup_printf(_("Buy %tde"), Names.Guns); | |
- else if (data == BT_SELL) | |
- Title = dpg_strdup_printf(_("Sell %tde"), Names.Guns); | |
- else | |
- Title = dpg_strdup_printf(_("Drop %tde"), Names.Guns); | |
- | |
- text = g_string_new(""); | |
- | |
- if (data != BT_BUY && TotalGunsCarried(ClientData.Play) == 0) { | |
- dpg_string_sprintf(text, _("You don't have any %tde to sell!"), | |
- Names.Guns); | |
- GtkMessageBox(dialog, text->str, Title, MB_OK); | |
- } else if (data == BT_BUY && TotalGunsCarried(ClientData.Play) >= | |
- ClientData.Play->Bitches.Carried + 2) { | |
- dpg_string_sprintf(text, | |
- _("You'll need more %tde to carry any more %tde!"), | |
- Names.Bitches, Names.Guns); | |
- GtkMessageBox(dialog, text->str, Title, MB_OK); | |
- } else if (data == BT_BUY | |
- && Gun[GunInd].Space > ClientData.Play->CoatSize) { | |
- dpg_string_sprintf(text, | |
- _("You don't have enough space to carry that %tde!"), | |
- Names.Gun); | |
- GtkMessageBox(dialog, text->str, Title, MB_OK); | |
- } else if (data == BT_BUY && Gun[GunInd].Price > ClientData.Play->Cash) { | |
- dpg_string_sprintf(text, | |
- _("You don't have enough cash to buy that %tde!"), | |
- Names.Gun); | |
- GtkMessageBox(dialog, text->str, Title, MB_OK); | |
- } else if (data == BT_SELL && ClientData.Play->Guns[GunInd].Carried == 0) { | |
- GtkMessageBox(dialog, _("You don't have any to sell!"), Title, MB_OK); | |
- } else { | |
- g_string_sprintf(text, "gun^%d^%d", GunInd, data == BT_BUY ? 1 : -1); | |
- SendClientMessage(ClientData.Play, C_NONE, C_BUYOBJECT, NULL, | |
- text->str); | |
- } | |
- g_free(Title); | |
- g_string_free(text, TRUE); | |
-} | |
- | |
-static void QuestionCallback(GtkWidget *widget, gpointer data) | |
-{ | |
- gint Answer; | |
- gchar text[5]; | |
- GtkWidget *dialog; | |
- Player *To; | |
- | |
- dialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "dialog")); | |
- To = (Player *)gtk_object_get_data(GTK_OBJECT(dialog), "From"); | |
- Answer = GPOINTER_TO_INT(data); | |
- | |
- text[0] = (gchar)Answer; | |
- text[1] = '\0'; | |
- SendClientMessage(ClientData.Play, C_NONE, C_ANSWER, To, text); | |
- | |
- gtk_widget_destroy(dialog); | |
-} | |
- | |
-void QuestionDialog(char *Data, Player *From) | |
-{ | |
- GtkWidget *dialog, *label, *vbox, *hsep, *hbbox, *button; | |
- GtkAccelGroup *accel_group; | |
- gchar *Responses, **split, *LabelText, *trword, *underline; | |
- | |
- /* Button titles that correspond to the single-keypress options provided | |
- * by the curses client (e.g. _Yes corresponds to 'Y' etc.) */ | |
- gchar *Words[] = { N_("_Yes"), N_("_No"), N_("_Run"), | |
- N_("_Fight"), N_("_Attack"), N_("_Evade") | |
- }; | |
- gint numWords = sizeof(Words) / sizeof(Words[0]); | |
- gint i, j; | |
- | |
- split = g_strsplit(Data, "^", 1); | |
- if (!split[0] || !split[1]) { | |
- g_warning("Bad QUESTION message %s", Data); | |
- return; | |
- } | |
- | |
- g_strdelimit(split[1], "^", '\n'); | |
- | |
- Responses = split[0]; | |
- LabelText = split[1]; | |
- | |
- dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
- accel_group = gtk_accel_group_new(); | |
- gtk_signal_connect(GTK_OBJECT(dialog), "delete_event", | |
- GTK_SIGNAL_FUNC(DisallowDelete), NULL); | |
- gtk_object_set_data(GTK_OBJECT(dialog), "From", (gpointer)From); | |
- | |
- /* Title of the 'ask player a question' dialog */ | |
- gtk_window_set_title(GTK_WINDOW(dialog), _("Question")); | |
- | |
- gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group); | |
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
- GTK_WINDOW(ClientData.window)); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- while (*LabelText == '\n') | |
- LabelText++; | |
- label = gtk_label_new(LabelText); | |
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- | |
- hbbox = gtk_hbutton_box_new(); | |
- | |
- for (i = 0; i < strlen(Responses); i++) { | |
- for (j = 0, trword = NULL; j < numWords && !trword; j++) { | |
- underline = strchr(Words[j], '_'); | |
- if (underline && toupper(underline[1]) == Responses[i]) { | |
- trword = _(Words[j]); | |
- } | |
- } | |
- button = gtk_button_new_with_label(""); | |
- if (trword) { | |
- SetAccelerator(button, trword, button, "clicked", accel_group); | |
- } else { | |
- trword = g_strdup_printf("_%c", Responses[i]); | |
- SetAccelerator(button, trword, button, "clicked", accel_group); | |
- g_free(trword); | |
- } | |
- gtk_object_set_data(GTK_OBJECT(button), "dialog", (gpointer)dialog); | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(QuestionCallback), | |
- GINT_TO_POINTER((gint)Responses[i])); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- } | |
- gtk_box_pack_start(GTK_BOX(vbox), hbbox, TRUE, TRUE, 0); | |
- gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
- gtk_widget_show_all(dialog); | |
- | |
- g_strfreev(split); | |
-} | |
- | |
-void StartGame(void) | |
-{ | |
- Player *Play = ClientData.Play; | |
- | |
- InitAbilities(Play); | |
- SendAbilities(Play); | |
- SendNullClientMessage(Play, C_NONE, C_NAME, NULL, GetPlayerName(Play)); | |
- InGame = TRUE; | |
- UpdateMenus(); | |
- gtk_widget_show_all(ClientData.vbox); | |
- UpdatePlayerLists(); | |
-} | |
- | |
-void EndGame(void) | |
-{ | |
- DisplayFightMessage(NULL); | |
- gtk_widget_hide_all(ClientData.vbox); | |
- gtk_editable_delete_text(GTK_EDITABLE(ClientData.messages), 0, -1); | |
- ShutdownNetwork(ClientData.Play); | |
- UpdatePlayerLists(); | |
- CleanUpServer(); | |
- RestoreConfig(); | |
- InGame = FALSE; | |
- UpdateMenus(); | |
-} | |
- | |
-static void ChangeDrugSort(GtkCList *clist, gint column, | |
- gpointer user_data) | |
-{ | |
- if (column == 0) { | |
- DrugSortMethod = (DrugSortMethod == DS_ATOZ ? DS_ZTOA : DS_ATOZ); | |
- } else { | |
- DrugSortMethod = (DrugSortMethod == DS_CHEAPFIRST ? DS_CHEAPLAST : | |
- DS_CHEAPFIRST); | |
- } | |
- gtk_clist_sort(clist); | |
-} | |
- | |
-static gint DrugSortFunc(GtkCList *clist, gconstpointer ptr1, | |
- gconstpointer ptr2) | |
-{ | |
- int index1, index2; | |
- price_t pricediff; | |
- | |
- index1 = GPOINTER_TO_INT(((const GtkCListRow *)ptr1)->data); | |
- index2 = GPOINTER_TO_INT(((const GtkCListRow *)ptr2)->data); | |
- if (index1 < 0 || index1 >= NumDrug || index2 < 0 || index2 >= NumDrug) | |
- return 0; | |
- | |
- switch (DrugSortMethod) { | |
- case DS_ATOZ: | |
- return g_strcasecmp(Drug[index1].Name, Drug[index2].Name); | |
- case DS_ZTOA: | |
- return g_strcasecmp(Drug[index2].Name, Drug[index1].Name); | |
- case DS_CHEAPFIRST: | |
- pricediff = ClientData.Play->Drugs[index1].Price - | |
- ClientData.Play->Drugs[index2].Price; | |
- return pricediff == 0 ? 0 : pricediff < 0 ? -1 : 1; | |
- case DS_CHEAPLAST: | |
- pricediff = ClientData.Play->Drugs[index2].Price - | |
- ClientData.Play->Drugs[index1].Price; | |
- return pricediff == 0 ? 0 : pricediff < 0 ? -1 : 1; | |
- } | |
- return 0; | |
-} | |
- | |
-void UpdateMenus(void) | |
-{ | |
- gboolean MultiPlayer; | |
- gint Bitches; | |
- | |
- MultiPlayer = (FirstClient && FirstClient->next != NULL); | |
- Bitches = InGame | |
- && ClientData.Play ? ClientData.Play->Bitches.Carried : 0; | |
- | |
- gtk_widget_set_sensitive(gtk_item_factory_get_widget(ClientData.Menu, | |
- "<main>/Talk"), | |
- InGame && Network); | |
- gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
- (ClientData.Menu, "<main>/List"), InGame); | |
- gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
- (ClientData.Menu, "<main>/List/Players..."), | |
- InGame && Network); | |
- gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
- (ClientData.Menu, "<main>/Errands"), InGame); | |
- gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
- (ClientData.Menu, "<main>/Errands/Spy..."), | |
- InGame && MultiPlayer); | |
- gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
- (ClientData.Menu, "<main>/Errands/Tipoff..."), | |
- InGame && MultiPlayer); | |
- gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
- (ClientData.Menu, | |
- "<main>/Errands/Sack Bitch..."), Bitches > 0); | |
- gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
- (ClientData.Menu, | |
- "<main>/Errands/Get spy reports..."), InGame | |
- && MultiPlayer); | |
-} | |
- | |
-GtkWidget *CreateStatusWidgets(struct StatusWidgets *Status) | |
-{ | |
- GtkWidget *table, *label; | |
- | |
- table = gtk_table_new(3, 6, FALSE); | |
- gtk_table_set_row_spacings(GTK_TABLE(table), 3); | |
- gtk_table_set_col_spacings(GTK_TABLE(table), 3); | |
- | |
- label = Status->Location = gtk_label_new(NULL); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 2, 0, 1); | |
- | |
- label = Status->Date = gtk_label_new(NULL); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 4, 0, 1); | |
- | |
- /* Available space label in GTK+ client status display */ | |
- label = Status->SpaceName = gtk_label_new(_("Space")); | |
- | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 4, 5, 0, 1); | |
- label = Status->SpaceValue = gtk_label_new(NULL); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 0, 1); | |
- | |
- /* Player's cash label in GTK+ client status display */ | |
- label = Status->CashName = gtk_label_new(_("Cash")); | |
- | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); | |
- label = Status->CashValue = gtk_label_new(NULL); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 1, 2); | |
- | |
- /* Player's debt label in GTK+ client status display */ | |
- label = Status->DebtName = gtk_label_new(_("Debt")); | |
- | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 1, 2); | |
- label = Status->DebtValue = gtk_label_new(NULL); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, 1, 2); | |
- | |
- /* Player's bank balance label in GTK+ client status display */ | |
- label = Status->BankName = gtk_label_new(_("Bank")); | |
- | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 4, 5, 1, 2); | |
- label = Status->BankValue = gtk_label_new(NULL); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 1, 2); | |
- | |
- label = Status->GunsName = gtk_label_new(NULL); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); | |
- label = Status->GunsValue = gtk_label_new(NULL); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 2, 3); | |
- | |
- label = Status->BitchesName = gtk_label_new(NULL); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 2, 3); | |
- label = Status->BitchesValue = gtk_label_new(NULL); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, 2, 3); | |
- | |
- /* Player's health label in GTK+ client status display */ | |
- label = Status->HealthName = gtk_label_new(_("Health")); | |
- | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 4, 5, 2, 3); | |
- label = Status->HealthValue = gtk_label_new(NULL); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 2, 3); | |
- return table; | |
-} | |
- | |
-void SetJetButtonTitle(GtkAccelGroup *accel_group) | |
-{ | |
- GtkWidget *button; | |
- guint accel_key; | |
- | |
- button = ClientData.JetButton; | |
- accel_key = ClientData.JetAccel; | |
- | |
- if (accel_key) { | |
- gtk_widget_remove_accelerator(button, accel_group, accel_key, 0); | |
- } | |
- | |
- ClientData.JetAccel = SetAccelerator(button, | |
- (ClientData.Play | |
- && ClientData.Play-> | |
- Flags & FIGHTING) ? _("_Fight") : | |
- /* Caption of 'Jet' button in main | |
- * window */ | |
- _("_Jet!"), button, "clicked", | |
- accel_group); | |
-} | |
- | |
-static void SetIcon(GtkWidget *window, gchar **xpmdata) | |
-{ | |
-#ifndef CYGWIN | |
- GdkBitmap *mask; | |
- GdkPixmap *icon; | |
- GtkStyle *style; | |
- | |
- style = gtk_widget_get_style(window); | |
- icon = gdk_pixmap_create_from_xpm_d(window->window, &mask, | |
- &style->bg[GTK_STATE_NORMAL], | |
- xpmdata); | |
- gdk_window_set_icon(window->window, NULL, icon, mask); | |
-#endif | |
-} | |
- | |
-#ifdef CYGWIN | |
-char GtkLoop(HINSTANCE hInstance, HINSTANCE hPrevInstance) | |
-{ | |
-#else | |
-char GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail) | |
-{ | |
-#endif | |
- GtkWidget *window, *vbox, *vbox2, *hbox, *frame, *table, *menubar, *text, | |
- *vpaned, *button, *clist; | |
- GtkAccelGroup *accel_group; | |
- GtkItemFactory *item_factory; | |
- GtkAdjustment *adj; | |
- gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]); | |
- | |
-#ifdef CYGWIN | |
- win32_init(hInstance, hPrevInstance, "mainicon"); | |
-#else | |
- gtk_set_locale(); | |
- if (ReturnOnFail && !gtk_init_check(argc, argv)) | |
- return FALSE; | |
- else if (!ReturnOnFail) | |
- gtk_init(argc, argv); | |
-#endif | |
- | |
- /* Set up message handlers */ | |
- ClientMessageHandlerPt = HandleClientMessage; | |
- | |
- /* Have the GLib log messages pop up in a nice dialog box */ | |
- g_log_set_handler(NULL, | |
- LogMask() | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING | | |
- G_LOG_LEVEL_CRITICAL, LogMessage, NULL); | |
- | |
- if (!CheckHighScoreFileConfig()) | |
- return TRUE; | |
- | |
- /* Create the main player */ | |
- ClientData.Play = g_new(Player, 1); | |
- FirstClient = AddPlayer(0, ClientData.Play, FirstClient); | |
- | |
- window = MainWindow = ClientData.window = gtk_window_new(GTK_WINDOW_TOPLEVEL… | |
- | |
- /* Title of main window in GTK+ client */ | |
- gtk_window_set_title(GTK_WINDOW(window), _("dopewars")); | |
- gtk_window_set_default_size(GTK_WINDOW(window), 450, 390); | |
- gtk_signal_connect(GTK_OBJECT(window), "delete_event", | |
- GTK_SIGNAL_FUNC(MainDelete), NULL); | |
- gtk_signal_connect(GTK_OBJECT(window), "destroy", | |
- GTK_SIGNAL_FUNC(DestroyGtk), NULL); | |
- | |
- accel_group = gtk_accel_group_new(); | |
- gtk_object_set_data(GTK_OBJECT(window), "accel_group", accel_group); | |
- item_factory = ClientData.Menu = gtk_item_factory_new(GTK_TYPE_MENU_BAR, | |
- "<main>", | |
- accel_group); | |
- gtk_item_factory_set_translate_func(item_factory, MenuTranslate, NULL, | |
- NULL); | |
- | |
- gtk_item_factory_create_items(item_factory, nmenu_items, menu_items, | |
- NULL); | |
- gtk_window_add_accel_group(GTK_WINDOW(window), accel_group); | |
- menubar = gtk_item_factory_get_widget(item_factory, "<main>"); | |
- | |
- vbox2 = gtk_vbox_new(FALSE, 0); | |
- gtk_box_pack_start(GTK_BOX(vbox2), menubar, FALSE, FALSE, 0); | |
- gtk_widget_show_all(menubar); | |
- UpdateMenus(); | |
- | |
- vbox = ClientData.vbox = gtk_vbox_new(FALSE, 5); | |
- frame = gtk_frame_new(_("Stats")); | |
- | |
- table = CreateStatusWidgets(&ClientData.Status); | |
- | |
- gtk_container_add(GTK_CONTAINER(frame), table); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); | |
- | |
- vpaned = gtk_vpaned_new(); | |
- | |
- adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 100.0, | |
- 1.0, 10.0, 10.0); | |
- text = ClientData.messages = gtk_scrolled_text_new(NULL, adj, &hbox); | |
- gtk_widget_set_usize(text, 100, 80); | |
- gtk_text_set_point(GTK_TEXT(text), 0); | |
- gtk_text_set_editable(GTK_TEXT(text), FALSE); | |
- gtk_text_set_word_wrap(GTK_TEXT(text), TRUE); | |
- gtk_paned_pack1(GTK_PANED(vpaned), hbox, TRUE, TRUE); | |
- | |
- hbox = gtk_hbox_new(FALSE, 7); | |
- CreateInventory(hbox, Names.Drugs, accel_group, TRUE, TRUE, | |
- &ClientData.Drug, DealDrugs); | |
- clist = ClientData.Drug.HereList; | |
- gtk_clist_column_titles_active(GTK_CLIST(clist)); | |
- gtk_clist_set_compare_func(GTK_CLIST(clist), DrugSortFunc); | |
- gtk_signal_connect(GTK_OBJECT(clist), "click-column", | |
- GTK_SIGNAL_FUNC(ChangeDrugSort), NULL); | |
- | |
- button = ClientData.JetButton = gtk_button_new_with_label(""); | |
- ClientData.JetAccel = 0; | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(JetButtonPressed), NULL); | |
- gtk_box_pack_start(GTK_BOX(ClientData.Drug.vbbox), button, TRUE, TRUE, 0); | |
- SetJetButtonTitle(accel_group); | |
- | |
- gtk_paned_pack2(GTK_PANED(vpaned), hbox, TRUE, TRUE); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), vpaned, TRUE, TRUE, 0); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox2), vbox, TRUE, TRUE, 0); | |
- gtk_container_add(GTK_CONTAINER(window), vbox2); | |
- | |
- /* Just show the window, not the vbox - we'll do that when the game | |
- * starts */ | |
- gtk_widget_show(vbox2); | |
- gtk_widget_show(window); | |
- | |
- gtk_widget_realize(window); | |
- | |
- SetIcon(window, dopewars_pill_xpm); | |
- | |
- gtk_main(); | |
- | |
- /* Free the main player */ | |
- FirstClient = RemovePlayer(ClientData.Play, FirstClient); | |
- | |
- return TRUE; | |
-} | |
- | |
-static void PackCentredURL(GtkWidget *vbox, gchar *title, gchar *target, | |
- gchar *browser) | |
-{ | |
- GtkWidget *hbox, *label, *url; | |
- | |
- /* There must surely be a nicer way of making the URL centred - but I | |
- * can't think of one... */ | |
- hbox = gtk_hbox_new(FALSE, 0); | |
- label = gtk_label_new(""); | |
- gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); | |
- | |
- url = gtk_url_new(title, target, browser); | |
- gtk_box_pack_start(GTK_BOX(hbox), url, FALSE, FALSE, 0); | |
- | |
- label = gtk_label_new(""); | |
- gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, FALSE, 0); | |
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
-} | |
- | |
-void display_intro(GtkWidget *widget, gpointer data) | |
-{ | |
- GtkWidget *dialog, *label, *table, *OKButton, *vbox, *hsep; | |
- gchar *VersionStr, *docindex; | |
- const int rows = 6, cols = 3; | |
- int i, j; | |
- gchar *table_data[6][3] = { | |
- /* Credits labels in GTK+ 'about' dialog */ | |
- {N_("Icons and graphics"), "Ocelot Mantis", NULL}, | |
- {N_("Drug Dealing and Research"), "Dan Wolf", NULL}, | |
- {N_("Play Testing"), "Phil Davis", "Owen Walsh"}, | |
- {N_("Extensive Play Testing"), "Katherine Holt", | |
- "Caroline Moore"}, | |
- {N_("Constructive Criticism"), "Andrea Elliot-Smith", | |
- "Pete Winn"}, | |
- {N_("Unconstructive Criticism"), "James Matthews", NULL} | |
- }; | |
- | |
- dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
- | |
- /* Title of GTK+ 'about' dialog */ | |
- gtk_window_set_title(GTK_WINDOW(dialog), _("About dopewars")); | |
- | |
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
- GTK_WINDOW(ClientData.window)); | |
- gtk_container_border_width(GTK_CONTAINER(dialog), 10); | |
- | |
- vbox = gtk_vbox_new(FALSE, 5); | |
- | |
- /* Main content of GTK+ 'about' dialog */ | |
- label = gtk_label_new(_("Based on John E. Dell's old Drug Wars game, " | |
- "dopewars is a simulation of an\nimaginary drug " | |
- "market. dopewars is an All-American game which " | |
- "features\nbuying, selling, and trying to get " | |
- "past the cops!\n\nThe first thing you need to " | |
- "do is pay off your debt to the Loan Shark. " | |
- "After\nthat, your goal is to make as much " | |
- "money as possible (and stay alive)! You\n" | |
- "have one month of game time to make " | |
- "your fortune.\n")); | |
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
- | |
- /* Version and copyright notice in GTK+ 'about' dialog */ | |
- VersionStr = g_strdup_printf(_("Version %s " | |
- "Copyright (C) 1998-2002 " | |
- "Ben Webb [email protected]\n" | |
- "dopewars is released under the " | |
- "GNU General Public Licence\n"), VERSION); | |
- label = gtk_label_new(VersionStr); | |
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
- g_free(VersionStr); | |
- | |
- table = gtk_table_new(rows, cols, FALSE); | |
- gtk_table_set_row_spacings(GTK_TABLE(table), 3); | |
- gtk_table_set_col_spacings(GTK_TABLE(table), 3); | |
- for (i = 0; i < rows; i++) | |
- for (j = 0; j < cols; j++) | |
- if (table_data[i][j]) { | |
- if (j == 0) | |
- label = gtk_label_new(_(table_data[i][j])); | |
- else | |
- label = gtk_label_new(table_data[i][j]); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, j, j + 1, i, | |
- i + 1); | |
- } | |
- gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); | |
- | |
- /* Label at the bottom of GTK+ 'about' dialog */ | |
- label = gtk_label_new(_("\nFor information on the command line " | |
- "options, type dopewars -h at your\n" | |
- "Unix prompt. This will display a help " | |
- "screen, listing the available options.\n")); | |
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
- | |
- docindex = GetDocIndex(); | |
- PackCentredURL(vbox, "Local HTML documentation", docindex, WebBrowser); | |
- g_free(docindex); | |
- | |
- PackCentredURL(vbox, "http://dopewars.sourceforge.net/", | |
- "http://dopewars.sourceforge.net/", WebBrowser); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- | |
- OKButton = gtk_button_new_with_label(_("OK")); | |
- gtk_signal_connect_object(GTK_OBJECT(OKButton), "clicked", | |
- GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
- (gpointer)dialog); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), OKButton, FALSE, FALSE, 0); | |
- gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
- | |
- GTK_WIDGET_SET_FLAGS(OKButton, GTK_CAN_DEFAULT); | |
- gtk_widget_grab_default(OKButton); | |
- | |
- gtk_widget_show_all(dialog); | |
-} | |
- | |
-static gboolean GetStartGamePlayerName(struct StartGameStruct *widgets, | |
- gchar **PlayerName) | |
-{ | |
- g_free(*PlayerName); | |
- *PlayerName = gtk_editable_get_chars(GTK_EDITABLE(widgets->name), 0, -1); | |
- if (*PlayerName && (*PlayerName)[0]) | |
- return TRUE; | |
- else { | |
- GtkMessageBox(widgets->dialog, | |
- _("You can't start the game without giving a name first!"), | |
- _("New Game"), MB_OK); | |
- return FALSE; | |
- } | |
-} | |
- | |
-static void SetStartGameStatus(struct StartGameStruct *widgets, gchar *msg) | |
-{ | |
- gtk_label_set_text(GTK_LABEL(widgets->status), | |
- msg ? msg : _("Status: Waiting for user input")); | |
-} | |
- | |
-#ifdef NETWORKING | |
-static void ConnectError(struct StartGameStruct *widgets, gboolean meta) | |
-{ | |
- GString *neterr; | |
- gchar *text; | |
- LastError *error; | |
- | |
- if (meta) | |
- error = widgets->MetaConn->NetBuf.error; | |
- else | |
- error = ClientData.Play->NetBuf.error; | |
- | |
- neterr = g_string_new(""); | |
- | |
- if (error) { | |
- g_string_assign_error(neterr, error); | |
- } else { | |
- g_string_assign(neterr, _("Connection closed by remote host")); | |
- } | |
- | |
- if (meta) { | |
- /* Error: GTK+ client could not connect to the metaserver */ | |
- text = | |
- g_strdup_printf(_("Status: Could not connect to metaserver (%s)"), | |
- neterr->str); | |
- } else { | |
- /* Error: GTK+ client could not connect to the given dopewars server */ | |
- text = | |
- g_strdup_printf(_("Status: Could not connect (%s)"), neterr->str); | |
- } | |
- | |
- SetStartGameStatus(widgets, text); | |
- g_free(text); | |
- g_string_free(neterr, TRUE); | |
-} | |
- | |
-void FinishServerConnect(struct StartGameStruct *widgets, | |
- gboolean ConnectOK) | |
-{ | |
- if (ConnectOK) { | |
- Client = Network = TRUE; | |
- gtk_widget_destroy(widgets->dialog); | |
- StartGame(); | |
- } else { | |
- ConnectError(widgets, FALSE); | |
- } | |
-} | |
- | |
-static void DoConnect(struct StartGameStruct *widgets) | |
-{ | |
- gchar *text; | |
- NetworkBuffer *NetBuf; | |
- NBStatus oldstatus; | |
- NBSocksStatus oldsocks; | |
- | |
- NetBuf = &ClientData.Play->NetBuf; | |
- | |
- /* Message displayed during the attempted connect to a dopewars server */ | |
- text = g_strdup_printf(_("Status: Attempting to contact %s..."), | |
- ServerName); | |
- SetStartGameStatus(widgets, text); | |
- g_free(text); | |
- | |
- /* Terminate any existing connection attempts */ | |
- ShutdownNetworkBuffer(NetBuf); | |
- if (widgets->MetaConn) { | |
- CloseHttpConnection(widgets->MetaConn); | |
- widgets->MetaConn = NULL; | |
- } | |
- | |
- oldstatus = NetBuf->status; | |
- oldsocks = NetBuf->sockstat; | |
- if (StartNetworkBufferConnect(NetBuf, ServerName, Port)) { | |
- DisplayConnectStatus(widgets, FALSE, oldstatus, oldsocks); | |
- SetNetworkBufferUserPasswdFunc(NetBuf, SocksAuthDialog, NULL); | |
- SetNetworkBufferCallBack(NetBuf, SocketStatus, (gpointer)widgets); | |
- } else { | |
- ConnectError(widgets, FALSE); | |
- } | |
-} | |
- | |
-static void ConnectToServer(GtkWidget *widget, | |
- struct StartGameStruct *widgets) | |
-{ | |
- gchar *text; | |
- | |
- g_free(ServerName); | |
- ServerName = gtk_editable_get_chars(GTK_EDITABLE(widgets->hostname), | |
- 0, -1); | |
- text = gtk_editable_get_chars(GTK_EDITABLE(widgets->port), 0, -1); | |
- Port = atoi(text); | |
- g_free(text); | |
- | |
- if (!GetStartGamePlayerName(widgets, &ClientData.Play->Name)) | |
- return; | |
- DoConnect(widgets); | |
-} | |
- | |
-static void FillMetaServerList(struct StartGameStruct *widgets, | |
- gboolean UseNewList) | |
-{ | |
- GtkWidget *metaserv; | |
- ServerData *ThisServer; | |
- gchar *titles[5]; | |
- GSList *ListPt; | |
- gint row; | |
- | |
- if (UseNewList && !widgets->NewMetaList) | |
- return; | |
- | |
- metaserv = widgets->metaserv; | |
- gtk_clist_freeze(GTK_CLIST(metaserv)); | |
- gtk_clist_clear(GTK_CLIST(metaserv)); | |
- | |
- if (UseNewList) { | |
- ClearServerList(&MetaList); | |
- MetaList = widgets->NewMetaList; | |
- widgets->NewMetaList = NULL; | |
- } | |
- | |
- for (ListPt = MetaList; ListPt; ListPt = g_slist_next(ListPt)) { | |
- ThisServer = (ServerData *)(ListPt->data); | |
- titles[0] = ThisServer->Name; | |
- titles[1] = g_strdup_printf("%d", ThisServer->Port); | |
- titles[2] = ThisServer->Version; | |
- if (ThisServer->CurPlayers == -1) { | |
- /* Displayed if we don't know how many players are logged on to a | |
- * server */ | |
- titles[3] = _("Unknown"); | |
- } else { | |
- /* e.g. "5 of 20" means 5 players are logged on to a server, out of | |
- * a maximum of 20 */ | |
- titles[3] = g_strdup_printf(_("%d of %d"), ThisServer->CurPlayers, | |
- ThisServer->MaxPlayers); | |
- } | |
- titles[4] = ThisServer->Comment; | |
- row = gtk_clist_append(GTK_CLIST(metaserv), titles); | |
- gtk_clist_set_row_data(GTK_CLIST(metaserv), row, (gpointer)ThisServer); | |
- g_free(titles[1]); | |
- if (ThisServer->CurPlayers != -1) | |
- g_free(titles[3]); | |
- } | |
- gtk_clist_thaw(GTK_CLIST(metaserv)); | |
-} | |
- | |
-void DisplayConnectStatus(struct StartGameStruct *widgets, gboolean meta, | |
- NBStatus oldstatus, NBSocksStatus oldsocks) | |
-{ | |
- NBStatus status; | |
- NBSocksStatus sockstat; | |
- gchar *text; | |
- | |
- if (meta) { | |
- status = widgets->MetaConn->NetBuf.status; | |
- sockstat = widgets->MetaConn->NetBuf.sockstat; | |
- } else { | |
- status = ClientData.Play->NetBuf.status; | |
- sockstat = ClientData.Play->NetBuf.sockstat; | |
- } | |
- if (oldstatus == status && sockstat == oldsocks) | |
- return; | |
- | |
- switch (status) { | |
- case NBS_PRECONNECT: | |
- break; | |
- case NBS_SOCKSCONNECT: | |
- switch (sockstat) { | |
- case NBSS_METHODS: | |
- text = g_strdup_printf(_("Status: Connected to SOCKS server %s..."), | |
- Socks.name); | |
- SetStartGameStatus(widgets, text); | |
- g_free(text); | |
- break; | |
- case NBSS_USERPASSWD: | |
- SetStartGameStatus(widgets, | |
- _("Status: Authenticating with SOCKS server")); | |
- break; | |
- case NBSS_CONNECT: | |
- text = | |
- g_strdup_printf(_("Status: Asking SOCKS for connect to %s..."), | |
- meta ? MetaServer.Name : ServerName); | |
- SetStartGameStatus(widgets, text); | |
- g_free(text); | |
- break; | |
- } | |
- break; | |
- case NBS_CONNECTED: | |
- if (meta) { | |
- SetStartGameStatus(widgets, | |
- _("Status: Obtaining server information " | |
- "from metaserver...")); | |
- } | |
- break; | |
- } | |
-} | |
- | |
-static void MetaDone(struct StartGameStruct *widgets) | |
-{ | |
- if (IsHttpError(widgets->MetaConn)) { | |
- ConnectError(widgets, TRUE); | |
- } else { | |
- SetStartGameStatus(widgets, NULL); | |
- } | |
- CloseHttpConnection(widgets->MetaConn); | |
- widgets->MetaConn = NULL; | |
- FillMetaServerList(widgets, TRUE); | |
-} | |
- | |
-static void HandleMetaSock(gpointer data, gint socket, | |
- GdkInputCondition condition) | |
-{ | |
- struct StartGameStruct *widgets; | |
- gboolean DoneOK; | |
- NBStatus oldstatus; | |
- NBSocksStatus oldsocks; | |
- | |
- widgets = (struct StartGameStruct *)data; | |
- if (!widgets->MetaConn) | |
- return; | |
- | |
- oldstatus = widgets->MetaConn->NetBuf.status; | |
- oldsocks = widgets->MetaConn->NetBuf.sockstat; | |
- | |
- if (NetBufHandleNetwork | |
- (&widgets->MetaConn->NetBuf, condition & GDK_INPUT_READ, | |
- condition & GDK_INPUT_WRITE, &DoneOK)) { | |
- while (HandleWaitingMetaServerData | |
- (widgets->MetaConn, &widgets->NewMetaList, &DoneOK)) { | |
- } | |
- } | |
- | |
- if (!DoneOK && HandleHttpCompletion(widgets->MetaConn)) { | |
- MetaDone(widgets); | |
- } else { | |
- DisplayConnectStatus(widgets, TRUE, oldstatus, oldsocks); | |
- } | |
-} | |
- | |
-void MetaSocketStatus(NetworkBuffer *NetBuf, gboolean Read, gboolean Write, | |
- gboolean CallNow) | |
-{ | |
- if (NetBuf->InputTag) | |
- gdk_input_remove(NetBuf->InputTag); | |
- NetBuf->InputTag = 0; | |
- if (Read || Write) { | |
- NetBuf->InputTag = gdk_input_add(NetBuf->fd, | |
- (Read ? GDK_INPUT_READ : 0) | | |
- (Write ? GDK_INPUT_WRITE : 0), | |
- HandleMetaSock, NetBuf->CallBackData); | |
- } | |
- if (CallNow) | |
- HandleMetaSock(NetBuf->CallBackData, NetBuf->fd, 0); | |
-} | |
- | |
-static void UpdateMetaServerList(GtkWidget *widget, | |
- struct StartGameStruct *widgets) | |
-{ | |
- GtkWidget *metaserv; | |
- gchar *text; | |
- | |
- /* Terminate any existing connection attempts */ | |
- ShutdownNetworkBuffer(&ClientData.Play->NetBuf); | |
- if (widgets->MetaConn) { | |
- CloseHttpConnection(widgets->MetaConn); | |
- widgets->MetaConn = NULL; | |
- } | |
- | |
- ClearServerList(&widgets->NewMetaList); | |
- | |
- /* Message displayed during the attempted connect to the metaserver */ | |
- text = g_strdup_printf(_("Status: Attempting to contact %s..."), | |
- MetaServer.Name); | |
- SetStartGameStatus(widgets, text); | |
- g_free(text); | |
- | |
- if (OpenMetaHttpConnection(&widgets->MetaConn)) { | |
- metaserv = widgets->metaserv; | |
- SetHttpAuthFunc(widgets->MetaConn, AuthDialog, NULL); | |
- SetNetworkBufferUserPasswdFunc(&widgets->MetaConn->NetBuf, | |
- MetaSocksAuthDialog, NULL); | |
- SetNetworkBufferCallBack(&widgets->MetaConn->NetBuf, | |
- MetaSocketStatus, (gpointer)widgets); | |
- } else { | |
- ConnectError(widgets, TRUE); | |
- CloseHttpConnection(widgets->MetaConn); | |
- widgets->MetaConn = NULL; | |
- } | |
-} | |
- | |
-static void MetaServerConnect(GtkWidget *widget, | |
- struct StartGameStruct *widgets) | |
-{ | |
- GList *selection; | |
- gint row; | |
- GtkWidget *clist; | |
- ServerData *ThisServer; | |
- | |
- clist = widgets->metaserv; | |
- selection = GTK_CLIST(clist)->selection; | |
- if (selection) { | |
- row = GPOINTER_TO_INT(selection->data); | |
- ThisServer = (ServerData *)gtk_clist_get_row_data(GTK_CLIST(clist), row); | |
- AssignName(&ServerName, ThisServer->Name); | |
- Port = ThisServer->Port; | |
- | |
- if (!GetStartGamePlayerName(widgets, &ClientData.Play->Name)) | |
- return; | |
- DoConnect(widgets); | |
- } | |
-} | |
-#endif /* NETWORKING */ | |
- | |
-static void StartSinglePlayer(GtkWidget *widget, | |
- struct StartGameStruct *widgets) | |
-{ | |
- WantAntique = | |
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widgets->antique)); | |
- if (!GetStartGamePlayerName(widgets, &ClientData.Play->Name)) | |
- return; | |
- StartGame(); | |
- gtk_widget_destroy(widgets->dialog); | |
-} | |
- | |
-static void CloseNewGameDia(GtkWidget *widget, | |
- struct StartGameStruct *widgets) | |
-{ | |
-#ifdef NETWORKING | |
- /* Terminate any existing connection attempts */ | |
- if (ClientData.Play->NetBuf.status != NBS_CONNECTED) { | |
- ShutdownNetworkBuffer(&ClientData.Play->NetBuf); | |
- } | |
- if (widgets->MetaConn) { | |
- CloseHttpConnection(widgets->MetaConn); | |
- widgets->MetaConn = NULL; | |
- } | |
- ClearServerList(&widgets->NewMetaList); | |
-#endif | |
-} | |
- | |
-void NewGameDialog(void) | |
-{ | |
- GtkWidget *vbox, *vbox2, *hbox, *label, *entry, *notebook; | |
- GtkWidget *frame, *button, *dialog; | |
- GtkAccelGroup *accel_group; | |
- static struct StartGameStruct widgets; | |
- guint AccelKey; | |
- | |
-#ifdef NETWORKING | |
- GtkWidget *clist, *scrollwin, *table, *hbbox; | |
- gchar *server_titles[5], *ServerEntry, *text; | |
- gboolean UpdateMeta = FALSE; | |
- | |
- /* Column titles of metaserver information */ | |
- server_titles[0] = _("Server"); | |
- server_titles[1] = _("Port"); | |
- server_titles[2] = _("Version"); | |
- server_titles[3] = _("Players"); | |
- server_titles[4] = _("Comment"); | |
- | |
- widgets.MetaConn = NULL; | |
- widgets.NewMetaList = NULL; | |
- | |
-#endif /* NETWORKING */ | |
- | |
- widgets.dialog = dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
- gtk_signal_connect(GTK_OBJECT(dialog), "destroy", | |
- GTK_SIGNAL_FUNC(CloseNewGameDia), (gpointer)&widgets); | |
- | |
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
- GTK_WINDOW(ClientData.window)); | |
-#ifdef NETWORKING | |
- gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300); | |
-#endif | |
- accel_group = gtk_accel_group_new(); | |
- | |
- /* Title of 'New Game' dialog */ | |
- gtk_window_set_title(GTK_WINDOW(widgets.dialog), _("New Game")); | |
- gtk_container_set_border_width(GTK_CONTAINER(widgets.dialog), 7); | |
- gtk_window_add_accel_group(GTK_WINDOW(widgets.dialog), accel_group); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- hbox = gtk_hbox_new(FALSE, 7); | |
- | |
- label = gtk_label_new(""); | |
- | |
- AccelKey = gtk_label_parse_uline(GTK_LABEL(label), | |
- /* Prompt for player's name in 'New | |
- * Game' dialog */ | |
- _("Hey dude, what's your _name?")); | |
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
- | |
- entry = widgets.name = gtk_entry_new(); | |
- gtk_widget_add_accelerator(entry, "grab-focus", accel_group, AccelKey, 0, | |
- GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE); | |
- gtk_entry_set_text(GTK_ENTRY(entry), GetPlayerName(ClientData.Play)); | |
- gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
- | |
- notebook = gtk_notebook_new(); | |
- | |
-#ifdef NETWORKING | |
- frame = gtk_frame_new(_("Server")); | |
- gtk_container_set_border_width(GTK_CONTAINER(frame), 4); | |
- vbox2 = gtk_vbox_new(FALSE, 7); | |
- gtk_container_set_border_width(GTK_CONTAINER(vbox2), 4); | |
- table = gtk_table_new(2, 2, FALSE); | |
- gtk_table_set_row_spacings(GTK_TABLE(table), 4); | |
- gtk_table_set_col_spacings(GTK_TABLE(table), 4); | |
- | |
- /* Prompt for hostname to connect to in GTK+ new game dialog */ | |
- label = gtk_label_new(_("Host name")); | |
- | |
- gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, | |
- GTK_SHRINK, GTK_SHRINK, 0, 0); | |
- entry = widgets.hostname = gtk_entry_new(); | |
- | |
- ServerEntry = "localhost"; | |
- if (g_strcasecmp(ServerName, SN_META) == 0) { | |
- NewGameType = 2; | |
- UpdateMeta = TRUE; | |
- } else if (g_strcasecmp(ServerName, SN_PROMPT) == 0) | |
- NewGameType = 0; | |
- else if (g_strcasecmp(ServerName, SN_SINGLE) == 0) | |
- NewGameType = 1; | |
- else | |
- ServerEntry = ServerName; | |
- | |
- gtk_entry_set_text(GTK_ENTRY(entry), ServerEntry); | |
- gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 0, 1, | |
- GTK_EXPAND | GTK_SHRINK | GTK_FILL, | |
- GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); | |
- label = gtk_label_new(_("Port")); | |
- gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, | |
- GTK_SHRINK, GTK_SHRINK, 0, 0); | |
- entry = widgets.port = gtk_entry_new(); | |
- text = g_strdup_printf("%d", Port); | |
- gtk_entry_set_text(GTK_ENTRY(entry), text); | |
- g_free(text); | |
- gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 1, 2, | |
- GTK_EXPAND | GTK_SHRINK | GTK_FILL, | |
- GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox2), table, FALSE, FALSE, 0); | |
- | |
- button = gtk_button_new_with_label(""); | |
- /* Button to connect to a named dopewars server */ | |
- SetAccelerator(button, _("_Connect"), button, "clicked", accel_group); | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(ConnectToServer), (gpointer)&widgets); | |
- gtk_box_pack_start(GTK_BOX(vbox2), button, FALSE, FALSE, 0); | |
- gtk_container_add(GTK_CONTAINER(frame), vbox2); | |
- GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); | |
- gtk_widget_grab_default(button); | |
- | |
- label = gtk_label_new(_("Server")); | |
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label); | |
-#endif /* NETWORKING */ | |
- | |
- /* Title of 'New Game' dialog notebook tab for single-player mode */ | |
- frame = gtk_frame_new(_("Single player")); | |
- gtk_container_set_border_width(GTK_CONTAINER(frame), 4); | |
- vbox2 = gtk_vbox_new(FALSE, 7); | |
- gtk_container_set_border_width(GTK_CONTAINER(vbox2), 4); | |
- widgets.antique = gtk_check_button_new_with_label(""); | |
- | |
- /* Checkbox to activate 'antique mode' in single-player games */ | |
- SetAccelerator(widgets.antique, _("_Antique mode"), widgets.antique, | |
- "clicked", accel_group); | |
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widgets.antique), | |
- WantAntique); | |
- gtk_box_pack_start(GTK_BOX(vbox2), widgets.antique, FALSE, FALSE, 0); | |
- button = gtk_button_new_with_label(""); | |
- | |
- /* Button to start a new single-player (standalone, non-network) game */ | |
- SetAccelerator(button, _("_Start single-player game"), button, | |
- "clicked", accel_group); | |
- | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(StartSinglePlayer), | |
- (gpointer)&widgets); | |
- gtk_box_pack_start(GTK_BOX(vbox2), button, FALSE, FALSE, 0); | |
- gtk_container_add(GTK_CONTAINER(frame), vbox2); | |
- label = gtk_label_new(_("Single player")); | |
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label); | |
- | |
-#ifdef NETWORKING | |
- /* Title of Metaserver frame in New Game dialog */ | |
- frame = gtk_frame_new(_("Metaserver")); | |
- gtk_container_set_border_width(GTK_CONTAINER(frame), 4); | |
- | |
- vbox2 = gtk_vbox_new(FALSE, 7); | |
- gtk_container_set_border_width(GTK_CONTAINER(vbox2), 4); | |
- | |
- clist = widgets.metaserv = | |
- gtk_scrolled_clist_new_with_titles(5, server_titles, &scrollwin); | |
- gtk_clist_column_titles_passive(GTK_CLIST(clist)); | |
- gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_SINGLE); | |
- gtk_clist_set_column_width(GTK_CLIST(clist), 0, 130); | |
- gtk_clist_set_column_width(GTK_CLIST(clist), 1, 35); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox2), scrollwin, TRUE, TRUE, 0); | |
- | |
- hbbox = gtk_hbutton_box_new(); | |
- button = gtk_button_new_with_label(""); | |
- | |
- /* Button to update metaserver information */ | |
- SetAccelerator(button, _("_Update"), button, "clicked", accel_group); | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(UpdateMetaServerList), | |
- (gpointer)&widgets); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- | |
- button = gtk_button_new_with_label(""); | |
- SetAccelerator(button, _("_Connect"), button, "clicked", accel_group); | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(MetaServerConnect), | |
- (gpointer)&widgets); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox2), hbbox, FALSE, FALSE, 0); | |
- gtk_container_add(GTK_CONTAINER(frame), vbox2); | |
- | |
- label = gtk_label_new(_("Metaserver")); | |
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label); | |
-#endif /* NETWORKING */ | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); | |
- | |
- /* Caption of status label in New Game dialog before anything has | |
- * happened */ | |
- label = widgets.status = gtk_label_new(""); | |
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
- | |
- gtk_container_add(GTK_CONTAINER(widgets.dialog), vbox); | |
- | |
- gtk_widget_grab_focus(widgets.name); | |
-#ifdef NETWORKING | |
- if (UpdateMeta) { | |
- UpdateMetaServerList(NULL, &widgets); | |
- } else { | |
- FillMetaServerList(&widgets, FALSE); | |
- } | |
-#endif | |
- | |
- SetStartGameStatus(&widgets, NULL); | |
- gtk_widget_show_all(widgets.dialog); | |
- gtk_notebook_set_page(GTK_NOTEBOOK(notebook), NewGameType); | |
-} | |
- | |
-static void SendDoneMessage(GtkWidget *widget, gpointer data) | |
-{ | |
- SendClientMessage(ClientData.Play, C_NONE, C_DONE, NULL, NULL); | |
-} | |
- | |
-static void TransferPayAll(GtkWidget *widget, GtkWidget *dialog) | |
-{ | |
- gchar *text; | |
- | |
- text = pricetostr(ClientData.Play->Debt); | |
- SendClientMessage(ClientData.Play, C_NONE, C_PAYLOAN, NULL, text); | |
- g_free(text); | |
- gtk_widget_destroy(dialog); | |
-} | |
- | |
-static void TransferOK(GtkWidget *widget, GtkWidget *dialog) | |
-{ | |
- gpointer Debt; | |
- GtkWidget *deposit, *entry; | |
- gchar *text, *title; | |
- price_t money; | |
- gboolean withdraw = FALSE; | |
- | |
- Debt = gtk_object_get_data(GTK_OBJECT(dialog), "debt"); | |
- entry = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(dialog), "entry")); | |
- text = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1); | |
- money = strtoprice(text); | |
- g_free(text); | |
- | |
- if (Debt) { | |
- /* Title of loan shark dialog - (%Tde="The Loan Shark" by default) */ | |
- title = dpg_strdup_printf(_("%/LoanShark window title/%Tde"), | |
- Names.LoanSharkName); | |
- if (money > ClientData.Play->Debt) | |
- money = ClientData.Play->Debt; | |
- } else { | |
- /* Title of bank dialog - (%Tde="The Bank" by default) */ | |
- title = dpg_strdup_printf(_("%/BankName window title/%Tde"), | |
- Names.BankName); | |
- deposit = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(dialog), "deposit")); | |
- if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(deposit))) { | |
- withdraw = TRUE; | |
- } | |
- } | |
- | |
- if (money < 0) { | |
- GtkMessageBox(dialog, _("You must enter a positive amount of money!"), | |
- title, MB_OK); | |
- } else if (!Debt && withdraw && money > ClientData.Play->Bank) { | |
- GtkMessageBox(dialog, _("There isn't that much money available..."), | |
- title, MB_OK); | |
- } else if (!withdraw && money > ClientData.Play->Cash) { | |
- GtkMessageBox(dialog, _("You don't have that much money!"), | |
- title, MB_OK); | |
- } else { | |
- text = pricetostr(withdraw ? -money : money); | |
- SendClientMessage(ClientData.Play, C_NONE, | |
- Debt ? C_PAYLOAN : C_DEPOSIT, NULL, text); | |
- g_free(text); | |
- gtk_widget_destroy(dialog); | |
- } | |
- g_free(title); | |
-} | |
- | |
-void TransferDialog(gboolean Debt) | |
-{ | |
- GtkWidget *dialog, *button, *label, *radio, *table, *vbox; | |
- GtkWidget *hbbox, *hsep, *entry; | |
- GSList *group; | |
- GString *text; | |
- | |
- text = g_string_new(""); | |
- | |
- dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
- gtk_signal_connect(GTK_OBJECT(dialog), "destroy", | |
- GTK_SIGNAL_FUNC(SendDoneMessage), NULL); | |
- if (Debt) { | |
- /* Title of loan shark dialog - (%Tde="The Loan Shark" by default) */ | |
- dpg_string_sprintf(text, _("%/LoanShark window title/%Tde"), | |
- Names.LoanSharkName); | |
- } else { | |
- /* Title of bank dialog - (%Tde="The Bank" by default) */ | |
- dpg_string_sprintf(text, _("%/BankName window title/%Tde"), | |
- Names.BankName); | |
- } | |
- gtk_window_set_title(GTK_WINDOW(dialog), text->str); | |
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
- GTK_WINDOW(ClientData.window)); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- table = gtk_table_new(4, 3, FALSE); | |
- gtk_table_set_row_spacings(GTK_TABLE(table), 4); | |
- gtk_table_set_col_spacings(GTK_TABLE(table), 4); | |
- | |
- /* Display of player's cash in bank or loan shark dialog */ | |
- dpg_string_sprintf(text, _("Cash: %P"), ClientData.Play->Cash); | |
- label = gtk_label_new(text->str); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 3, 0, 1); | |
- | |
- if (Debt) { | |
- /* Display of player's debt in loan shark dialog */ | |
- dpg_string_sprintf(text, _("Debt: %P"), ClientData.Play->Debt); | |
- } else { | |
- /* Display of player's bank balance in bank dialog */ | |
- dpg_string_sprintf(text, _("Bank: %P"), ClientData.Play->Bank); | |
- } | |
- label = gtk_label_new(text->str); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 3, 1, 2); | |
- | |
- gtk_object_set_data(GTK_OBJECT(dialog), "debt", GINT_TO_POINTER(Debt)); | |
- if (Debt) { | |
- /* Prompt for paying back a loan */ | |
- label = gtk_label_new(_("Pay back:")); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 4); | |
- } else { | |
- /* Radio button selected if you want to pay money into the bank */ | |
- radio = gtk_radio_button_new_with_label(NULL, _("Deposit")); | |
- gtk_object_set_data(GTK_OBJECT(dialog), "deposit", radio); | |
- group = gtk_radio_button_group(GTK_RADIO_BUTTON(radio)); | |
- gtk_table_attach_defaults(GTK_TABLE(table), radio, 0, 1, 2, 3); | |
- | |
- /* Radio button selected if you want to withdraw money from the bank */ | |
- radio = gtk_radio_button_new_with_label(group, _("Withdraw")); | |
- gtk_table_attach_defaults(GTK_TABLE(table), radio, 0, 1, 3, 4); | |
- } | |
- label = gtk_label_new(Currency.Symbol); | |
- entry = gtk_entry_new(); | |
- gtk_entry_set_text(GTK_ENTRY(entry), "0"); | |
- gtk_object_set_data(GTK_OBJECT(dialog), "entry", entry); | |
- gtk_signal_connect(GTK_OBJECT(entry), "activate", | |
- GTK_SIGNAL_FUNC(TransferOK), dialog); | |
- | |
- if (Currency.Prefix) { | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 2, 4); | |
- gtk_table_attach_defaults(GTK_TABLE(table), entry, 2, 3, 2, 4); | |
- } else { | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 2, 4); | |
- gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 2, 4); | |
- } | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- | |
- hbbox = gtk_hbutton_box_new(); | |
- button = gtk_button_new_with_label(_("OK")); | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(TransferOK), dialog); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- | |
- if (Debt && ClientData.Play->Cash >= ClientData.Play->Debt) { | |
- /* Button to pay back the entire loan/debt */ | |
- button = gtk_button_new_with_label(_("Pay all")); | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(TransferPayAll), dialog); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- } | |
- button = gtk_button_new_with_label(_("Cancel")); | |
- gtk_signal_connect_object(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
- (gpointer)dialog); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0); | |
- | |
- gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
- | |
- gtk_widget_show_all(dialog); | |
- | |
- g_string_free(text, TRUE); | |
-} | |
- | |
-void ListPlayers(GtkWidget *widget, gpointer data) | |
-{ | |
- GtkWidget *dialog, *clist, *button, *vbox, *hsep; | |
- | |
- if (IsShowingPlayerList) | |
- return; | |
- dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
- | |
- /* Title of player list dialog */ | |
- gtk_window_set_title(GTK_WINDOW(dialog), _("Player List")); | |
- | |
- gtk_window_set_default_size(GTK_WINDOW(dialog), 200, 180); | |
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
- | |
- IsShowingPlayerList = TRUE; | |
- gtk_window_set_modal(GTK_WINDOW(dialog), FALSE); | |
- gtk_object_set_data(GTK_OBJECT(dialog), "IsShowing", | |
- (gpointer)&IsShowingPlayerList); | |
- gtk_signal_connect(GTK_OBJECT(dialog), "destroy", | |
- GTK_SIGNAL_FUNC(DestroyShowing), NULL); | |
- | |
- gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
- GTK_WINDOW(ClientData.window)); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- | |
- clist = ClientData.PlayerList = CreatePlayerList(); | |
- UpdatePlayerList(clist, FALSE); | |
- gtk_box_pack_start(GTK_BOX(vbox), clist, TRUE, TRUE, 0); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- | |
- button = gtk_button_new_with_label(_("OK")); | |
- gtk_signal_connect_object(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
- (gpointer)dialog); | |
- gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); | |
- gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
- gtk_widget_show_all(dialog); | |
-} | |
- | |
-struct TalkStruct { | |
- GtkWidget *dialog, *clist, *entry, *checkbutton; | |
-}; | |
- | |
-static void TalkSend(GtkWidget *widget, struct TalkStruct *TalkData) | |
-{ | |
- gboolean AllPlayers; | |
- gchar *text; | |
- GString *msg; | |
- GList *selection; | |
- gint row; | |
- Player *Play; | |
- | |
- AllPlayers = | |
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON | |
- (TalkData->checkbutton)); | |
- text = gtk_editable_get_chars(GTK_EDITABLE(TalkData->entry), 0, -1); | |
- gtk_editable_delete_text(GTK_EDITABLE(TalkData->entry), 0, -1); | |
- if (!text) | |
- return; | |
- | |
- msg = g_string_new(""); | |
- | |
- if (AllPlayers) { | |
- SendClientMessage(ClientData.Play, C_NONE, C_MSG, NULL, text); | |
- g_string_sprintf(msg, "%s: %s", GetPlayerName(ClientData.Play), text); | |
- PrintMessage(msg->str); | |
- } else { | |
- for (selection = GTK_CLIST(TalkData->clist)->selection; selection; | |
- selection = g_list_next(selection)) { | |
- row = GPOINTER_TO_INT(selection->data); | |
- Play = | |
- (Player *)gtk_clist_get_row_data(GTK_CLIST(TalkData->clist), | |
- row); | |
- if (Play) { | |
- SendClientMessage(ClientData.Play, C_NONE, C_MSGTO, Play, text); | |
- g_string_sprintf(msg, "%s->%s: %s", GetPlayerName(ClientData.Play), | |
- GetPlayerName(Play), text); | |
- PrintMessage(msg->str); | |
- } | |
- } | |
- } | |
- g_free(text); | |
- g_string_free(msg, TRUE); | |
-} | |
- | |
-void TalkToAll(GtkWidget *widget, gpointer data) | |
-{ | |
- TalkDialog(TRUE); | |
-} | |
- | |
-void TalkToPlayers(GtkWidget *widget, gpointer data) | |
-{ | |
- TalkDialog(FALSE); | |
-} | |
- | |
-void TalkDialog(gboolean TalkToAll) | |
-{ | |
- GtkWidget *dialog, *clist, *button, *entry, *label, *vbox, *hsep, | |
- *checkbutton, *hbbox; | |
- static struct TalkStruct TalkData; | |
- | |
- if (IsShowingTalkList) | |
- return; | |
- dialog = TalkData.dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
- | |
- /* Title of talk dialog */ | |
- gtk_window_set_title(GTK_WINDOW(dialog), _("Talk to player(s)")); | |
- | |
- gtk_window_set_default_size(GTK_WINDOW(dialog), 200, 190); | |
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
- | |
- IsShowingTalkList = TRUE; | |
- gtk_window_set_modal(GTK_WINDOW(dialog), FALSE); | |
- gtk_object_set_data(GTK_OBJECT(dialog), "IsShowing", | |
- (gpointer)&IsShowingTalkList); | |
- gtk_signal_connect(GTK_OBJECT(dialog), "destroy", | |
- GTK_SIGNAL_FUNC(DestroyShowing), NULL); | |
- | |
- gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
- GTK_WINDOW(ClientData.window)); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- | |
- clist = TalkData.clist = ClientData.TalkList = CreatePlayerList(); | |
- UpdatePlayerList(clist, FALSE); | |
- gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_MULTIPLE); | |
- gtk_box_pack_start(GTK_BOX(vbox), clist, TRUE, TRUE, 0); | |
- | |
- checkbutton = TalkData.checkbutton = | |
- /* Checkbutton set if you want to talk to all players */ | |
- gtk_check_button_new_with_label(_("Talk to all players")); | |
- | |
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TalkToAll); | |
- gtk_box_pack_start(GTK_BOX(vbox), checkbutton, FALSE, FALSE, 0); | |
- | |
- /* Prompt for you to enter the message to be sent to other players */ | |
- label = gtk_label_new(_("Message:-")); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
- | |
- entry = TalkData.entry = gtk_entry_new(); | |
- gtk_signal_connect(GTK_OBJECT(entry), "activate", | |
- GTK_SIGNAL_FUNC(TalkSend), (gpointer)&TalkData); | |
- gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- | |
- hbbox = gtk_hbutton_box_new(); | |
- | |
- /* Button to send a message to other players */ | |
- button = gtk_button_new_with_label(_("Send")); | |
- | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(TalkSend), (gpointer)&TalkData); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- | |
- button = gtk_button_new_with_label(_("Close")); | |
- gtk_signal_connect_object(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
- (gpointer)dialog); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0); | |
- | |
- gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
- gtk_widget_show_all(dialog); | |
-} | |
- | |
-GtkWidget *CreatePlayerList(void) | |
-{ | |
- GtkWidget *clist; | |
- gchar *text[1]; | |
- | |
- text[0] = "Name"; | |
- clist = gtk_clist_new_with_titles(1, text); | |
- gtk_clist_column_titles_passive(GTK_CLIST(clist)); | |
- gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 0, TRUE); | |
- return clist; | |
-} | |
- | |
-void UpdatePlayerList(GtkWidget *clist, gboolean IncludeSelf) | |
-{ | |
- GSList *list; | |
- gchar *text[1]; | |
- gint row; | |
- Player *Play; | |
- | |
- gtk_clist_freeze(GTK_CLIST(clist)); | |
- gtk_clist_clear(GTK_CLIST(clist)); | |
- for (list = FirstClient; list; list = g_slist_next(list)) { | |
- Play = (Player *)list->data; | |
- if (IncludeSelf || Play != ClientData.Play) { | |
- text[0] = GetPlayerName(Play); | |
- row = gtk_clist_append(GTK_CLIST(clist), text); | |
- gtk_clist_set_row_data(GTK_CLIST(clist), row, Play); | |
- } | |
- } | |
- gtk_clist_thaw(GTK_CLIST(clist)); | |
-} | |
- | |
-static void ErrandOK(GtkWidget *widget, GtkWidget *clist) | |
-{ | |
- GList *selection; | |
- Player *Play; | |
- gint row; | |
- GtkWidget *dialog; | |
- gint ErrandType; | |
- | |
- dialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "dialog")); | |
- ErrandType = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), | |
- "errandtype")); | |
- selection = GTK_CLIST(clist)->selection; | |
- if (selection) { | |
- row = GPOINTER_TO_INT(selection->data); | |
- Play = (Player *)gtk_clist_get_row_data(GTK_CLIST(clist), row); | |
- if (ErrandType == ET_SPY) { | |
- SendClientMessage(ClientData.Play, C_NONE, C_SPYON, Play, NULL); | |
- } else { | |
- SendClientMessage(ClientData.Play, C_NONE, C_TIPOFF, Play, NULL); | |
- } | |
- gtk_widget_destroy(dialog); | |
- } | |
-} | |
- | |
-void SpyOnPlayer(GtkWidget *widget, gpointer data) | |
-{ | |
- ErrandDialog(ET_SPY); | |
-} | |
- | |
-void TipOff(GtkWidget *widget, gpointer data) | |
-{ | |
- ErrandDialog(ET_TIPOFF); | |
-} | |
- | |
-void ErrandDialog(gint ErrandType) | |
-{ | |
- GtkWidget *dialog, *clist, *button, *vbox, *hbbox, *hsep, *label; | |
- gchar *text; | |
- | |
- dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
- | |
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
- GTK_WINDOW(ClientData.window)); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- | |
- if (ErrandType == ET_SPY) { | |
- /* Title of dialog to select a player to spy on */ | |
- gtk_window_set_title(GTK_WINDOW(dialog), _("Spy On Player")); | |
- | |
- /* Informative text for "spy on player" dialog. (%tde = "bitch", | |
- * "bitch", "guns", "drugs", respectively, by default) */ | |
- text = dpg_strdup_printf(_("Please choose the player to spy on. " | |
- "Your %tde will\nthen offer his " | |
- "services to the player, and if " | |
- "successful,\nyou will be able to " | |
- "view the player's stats with the\n" | |
- "\"Get spy reports\" menu. Remember " | |
- "that the %tde will leave\nyou, so " | |
- "any %tde or %tde that he's " | |
- "carrying may be lost!"), Names.Bitch, | |
- Names.Bitch, Names.Guns, Names.Drugs); | |
- label = gtk_label_new(text); | |
- g_free(text); | |
- } else { | |
- | |
- /* Title of dialog to select a player to tip the cops off to */ | |
- gtk_window_set_title(GTK_WINDOW(dialog), _("Tip Off The Cops")); | |
- | |
- /* Informative text for "tip off cops" dialog. (%tde = "bitch", | |
- * "bitch", "guns", "drugs", respectively, by default) */ | |
- text = dpg_strdup_printf(_("Please choose the player to tip off " | |
- "the cops to. Your %tde will\nhelp " | |
- "the cops to attack that player, " | |
- "and then report back to you\non " | |
- "the encounter. Remember that the " | |
- "%tde will leave you temporarily,\n" | |
- "so any %tde or %tde that he's " | |
- "carrying may be lost!"), Names.Bitch, | |
- Names.Bitch, Names.Guns, Names.Drugs); | |
- label = gtk_label_new(text); | |
- g_free(text); | |
- } | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
- | |
- clist = ClientData.PlayerList = CreatePlayerList(); | |
- UpdatePlayerList(clist, FALSE); | |
- gtk_box_pack_start(GTK_BOX(vbox), clist, TRUE, TRUE, 0); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- | |
- hbbox = gtk_hbutton_box_new(); | |
- button = gtk_button_new_with_label(_("OK")); | |
- gtk_object_set_data(GTK_OBJECT(button), "dialog", dialog); | |
- gtk_object_set_data(GTK_OBJECT(button), "errandtype", | |
- GINT_TO_POINTER(ErrandType)); | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(ErrandOK), (gpointer)clist); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- button = gtk_button_new_with_label(_("Cancel")); | |
- gtk_signal_connect_object(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
- (gpointer)dialog); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0); | |
- gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
- gtk_widget_show_all(dialog); | |
-} | |
- | |
-void SackBitch(GtkWidget *widget, gpointer data) | |
-{ | |
- char *title, *text; | |
- | |
- /* Cannot sack bitches if you don't have any! */ | |
- if (ClientData.Play->Bitches.Carried <= 0) | |
- return; | |
- | |
- /* Title of dialog to sack a bitch (%Tde = "Bitch" by default) */ | |
- title = dpg_strdup_printf(_("%/Sack Bitch dialog title/Sack %Tde"), | |
- Names.Bitch); | |
- | |
- /* Confirmation message for sacking a bitch. (%tde = "guns", "drugs", | |
- * "bitch", respectively, by default) */ | |
- text = dpg_strdup_printf(_("Are you sure? (Any %tde or %tde carried\n" | |
- "by this %tde may be lost!)"), Names.Guns, | |
- Names.Drugs, Names.Bitch); | |
- | |
- if (GtkMessageBox(ClientData.window, text, title, MB_YESNO) == IDYES) { | |
- ClientData.Play->Bitches.Carried--; | |
- UpdateMenus(); | |
- SendClientMessage(ClientData.Play, C_NONE, C_SACKBITCH, NULL, NULL); | |
- } | |
- g_free(text); | |
- g_free(title); | |
-} | |
- | |
-void CreateInventory(GtkWidget *hbox, gchar *Objects, | |
- GtkAccelGroup *accel_group, gboolean CreateButtons, | |
- gboolean CreateHere, struct InventoryWidgets *widgets, | |
- GtkSignalFunc CallBack) | |
-{ | |
- GtkWidget *scrollwin, *clist, *vbbox, *frame[2], *button[3]; | |
- gint i, mini; | |
- GString *text; | |
- gchar *titles[2][2]; | |
- gchar *button_text[3]; | |
- gpointer button_type[3] = { BT_BUY, BT_SELL, BT_DROP }; | |
- | |
- /* Column titles for display of drugs/guns carried or available for | |
- * purchase */ | |
- titles[0][0] = titles[1][0] = _("Name"); | |
- titles[0][1] = _("Price"); | |
- titles[1][1] = _("Number"); | |
- | |
- /* Button titles for buying/selling/dropping guns or drugs */ | |
- button_text[0] = _("_Buy ->"); | |
- button_text[1] = _("<- _Sell"); | |
- button_text[2] = _("_Drop <-"); | |
- | |
- text = g_string_new(""); | |
- | |
- if (CreateHere) { | |
- /* Title of the display of available drugs/guns (%Tde = "Guns" or | |
- * "Drugs" by default) */ | |
- dpg_string_sprintf(text, _("%Tde here"), Objects); | |
- widgets->HereFrame = frame[0] = gtk_frame_new(text->str); | |
- } | |
- | |
- /* Title of the display of carried drugs/guns (%Tde = "Guns" or "Drugs" | |
- * by default) */ | |
- dpg_string_sprintf(text, _("%Tde carried"), Objects); | |
- | |
- widgets->CarriedFrame = frame[1] = gtk_frame_new(text->str); | |
- | |
- widgets->HereList = widgets->CarriedList = NULL; | |
- if (CreateHere) | |
- mini = 0; | |
- else | |
- mini = 1; | |
- for (i = mini; i < 2; i++) { | |
- gtk_container_set_border_width(GTK_CONTAINER(frame[i]), 5); | |
- | |
- clist = gtk_scrolled_clist_new_with_titles(2, titles[i], &scrollwin); | |
- gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 0, TRUE); | |
- gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 1, TRUE); | |
- gtk_clist_column_titles_passive(GTK_CLIST(clist)); | |
- gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_SINGLE); | |
- gtk_clist_set_auto_sort(GTK_CLIST(clist), FALSE); | |
- gtk_container_add(GTK_CONTAINER(frame[i]), scrollwin); | |
- if (i == 0) | |
- widgets->HereList = clist; | |
- else | |
- widgets->CarriedList = clist; | |
- } | |
- if (CreateHere) | |
- gtk_box_pack_start(GTK_BOX(hbox), frame[0], TRUE, TRUE, 0); | |
- | |
- if (CreateButtons) { | |
- widgets->vbbox = vbbox = gtk_vbutton_box_new(); | |
- | |
- for (i = 0; i < 3; i++) { | |
- button[i] = gtk_button_new_with_label(""); | |
- SetAccelerator(button[i], _(button_text[i]), button[i], | |
- "clicked", accel_group); | |
- if (CallBack) | |
- gtk_signal_connect(GTK_OBJECT(button[i]), "clicked", | |
- GTK_SIGNAL_FUNC(CallBack), button_type[i]); | |
- gtk_box_pack_start(GTK_BOX(vbbox), button[i], TRUE, TRUE, 0); | |
- } | |
- widgets->BuyButton = button[0]; | |
- widgets->SellButton = button[1]; | |
- widgets->DropButton = button[2]; | |
- gtk_box_pack_start(GTK_BOX(hbox), vbbox, FALSE, FALSE, 0); | |
- } else | |
- widgets->vbbox = NULL; | |
- | |
- gtk_box_pack_start(GTK_BOX(hbox), frame[1], TRUE, TRUE, 0); | |
- g_string_free(text, TRUE); | |
-} | |
- | |
-void DestroyShowing(GtkWidget *widget, gpointer data) | |
-{ | |
- gboolean *IsShowing; | |
- | |
- IsShowing = | |
- (gboolean *)gtk_object_get_data(GTK_OBJECT(widget), "IsShowing"); | |
- if (IsShowing) | |
- *IsShowing = FALSE; | |
-} | |
- | |
-static void NewNameOK(GtkWidget *widget, GtkWidget *window) | |
-{ | |
- GtkWidget *entry; | |
- gchar *text; | |
- | |
- entry = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(window), "entry")); | |
- text = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1); | |
- if (text[0]) { | |
- SetPlayerName(ClientData.Play, text); | |
- SendNullClientMessage(ClientData.Play, C_NONE, C_NAME, NULL, text); | |
- gtk_widget_destroy(window); | |
- } | |
- g_free(text); | |
-} | |
- | |
-void NewNameDialog(void) | |
-{ | |
- GtkWidget *window, *button, *hsep, *vbox, *label, *entry; | |
- | |
- window = gtk_window_new(GTK_WINDOW_DIALOG); | |
- | |
- /* Title of dialog for changing a player's name */ | |
- gtk_window_set_title(GTK_WINDOW(window), _("Change Name")); | |
- | |
- gtk_window_set_modal(GTK_WINDOW(window), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(window), | |
- GTK_WINDOW(ClientData.window)); | |
- gtk_container_set_border_width(GTK_CONTAINER(window), 7); | |
- gtk_signal_connect(GTK_OBJECT(window), "delete_event", | |
- GTK_SIGNAL_FUNC(DisallowDelete), NULL); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- | |
- /* Informational text to prompt the player to change his/her name */ | |
- label = gtk_label_new(_("Unfortunately, somebody else is already " | |
- "using \"your\" name. Please change it:-")); | |
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
- | |
- entry = gtk_entry_new(); | |
- gtk_object_set_data(GTK_OBJECT(window), "entry", entry); | |
- gtk_signal_connect(GTK_OBJECT(entry), "activate", | |
- GTK_SIGNAL_FUNC(NewNameOK), window); | |
- gtk_entry_set_text(GTK_ENTRY(entry), GetPlayerName(ClientData.Play)); | |
- gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- | |
- button = gtk_button_new_with_label(_("OK")); | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(NewNameOK), window); | |
- gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); | |
- GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); | |
- gtk_widget_grab_default(button); | |
- | |
- gtk_container_add(GTK_CONTAINER(window), vbox); | |
- gtk_widget_show_all(window); | |
-} | |
- | |
-gint DisallowDelete(GtkWidget *widget, GdkEvent *event, gpointer data) | |
-{ | |
- return (TRUE); | |
-} | |
- | |
-void GunShopDialog(void) | |
-{ | |
- GtkWidget *window, *button, *hsep, *vbox, *hbox; | |
- GtkAccelGroup *accel_group; | |
- gchar *text; | |
- | |
- window = gtk_window_new(GTK_WINDOW_DIALOG); | |
- gtk_window_set_default_size(GTK_WINDOW(window), 600, 190); | |
- gtk_signal_connect(GTK_OBJECT(window), "destroy", | |
- GTK_SIGNAL_FUNC(SendDoneMessage), NULL); | |
- accel_group = gtk_accel_group_new(); | |
- gtk_window_add_accel_group(GTK_WINDOW(window), accel_group); | |
- | |
- /* Title of 'gun shop' dialog in GTK+ client (%Tde="Dan's House of Guns" | |
- * by default) */ | |
- text = dpg_strdup_printf(_("%/GTK GunShop window title/%Tde"), | |
- Names.GunShopName); | |
- gtk_window_set_title(GTK_WINDOW(window), text); | |
- g_free(text); | |
- gtk_window_set_modal(GTK_WINDOW(window), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(window), | |
- GTK_WINDOW(ClientData.window)); | |
- gtk_container_set_border_width(GTK_CONTAINER(window), 7); | |
- IsShowingGunShop = TRUE; | |
- gtk_object_set_data(GTK_OBJECT(window), "IsShowing", | |
- (gpointer)&IsShowingGunShop); | |
- gtk_signal_connect(GTK_OBJECT(window), "destroy", | |
- GTK_SIGNAL_FUNC(DestroyShowing), NULL); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- | |
- hbox = gtk_hbox_new(FALSE, 7); | |
- CreateInventory(hbox, Names.Guns, accel_group, TRUE, TRUE, | |
- &ClientData.Gun, DealGuns); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- | |
- /* Button to finish buying/selling guns in the gun shop */ | |
- button = gtk_button_new_with_label(_("Done")); | |
- | |
- gtk_signal_connect_object(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
- (gpointer)window); | |
- gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); | |
- | |
- gtk_container_add(GTK_CONTAINER(window), vbox); | |
- | |
- UpdateInventory(&ClientData.Gun, ClientData.Play->Guns, NumGun, FALSE); | |
- gtk_widget_show_all(window); | |
-} | |
- | |
-void UpdatePlayerLists(void) | |
-{ | |
- if (IsShowingPlayerList) | |
- UpdatePlayerList(ClientData.PlayerList, FALSE); | |
- if (IsShowingTalkList) | |
- UpdatePlayerList(ClientData.TalkList, FALSE); | |
-} | |
- | |
-void GetSpyReports(GtkWidget *Widget, gpointer data) | |
-{ | |
- SendClientMessage(ClientData.Play, C_NONE, C_CONTACTSPY, NULL, NULL); | |
-} | |
- | |
-static void DestroySpyReports(GtkWidget *widget, gpointer data) | |
-{ | |
- SpyReportsDialog = NULL; | |
-} | |
- | |
-static void CreateSpyReports(void) | |
-{ | |
- GtkWidget *window, *button, *vbox, *notebook; | |
- GtkAccelGroup *accel_group; | |
- | |
- SpyReportsDialog = window = gtk_window_new(GTK_WINDOW_DIALOG); | |
- accel_group = gtk_accel_group_new(); | |
- gtk_object_set_data(GTK_OBJECT(window), "accel_group", accel_group); | |
- gtk_window_add_accel_group(GTK_WINDOW(window), accel_group); | |
- | |
- /* Title of window to display reports from spies with other players */ | |
- gtk_window_set_title(GTK_WINDOW(window), _("Spy reports")); | |
- | |
- gtk_window_set_modal(GTK_WINDOW(window), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(window), | |
- GTK_WINDOW(ClientData.window)); | |
- gtk_container_set_border_width(GTK_CONTAINER(window), 7); | |
- gtk_signal_connect(GTK_OBJECT(window), "destroy", | |
- GTK_SIGNAL_FUNC(DestroySpyReports), NULL); | |
- | |
- vbox = gtk_vbox_new(FALSE, 5); | |
- notebook = gtk_notebook_new(); | |
- gtk_object_set_data(GTK_OBJECT(window), "notebook", notebook); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); | |
- | |
- button = gtk_button_new_with_label(_("Close")); | |
- gtk_signal_connect_object(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
- (gpointer)window); | |
- gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); | |
- | |
- gtk_container_add(GTK_CONTAINER(window), vbox); | |
- | |
- gtk_widget_show_all(window); | |
-} | |
- | |
-void DisplaySpyReports(Player *Play) | |
-{ | |
- GtkWidget *dialog, *notebook, *vbox, *hbox, *frame, *label, *table; | |
- GtkAccelGroup *accel_group; | |
- struct StatusWidgets Status; | |
- struct InventoryWidgets SpyDrugs, SpyGuns; | |
- | |
- if (!SpyReportsDialog) | |
- CreateSpyReports(); | |
- dialog = SpyReportsDialog; | |
- notebook = | |
- GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(dialog), "notebook")); | |
- accel_group = | |
- (GtkAccelGroup | |
- *)(gtk_object_get_data(GTK_OBJECT(dialog), "accel_group")); | |
- vbox = gtk_vbox_new(FALSE, 5); | |
- frame = gtk_frame_new("Stats"); | |
- gtk_container_set_border_width(GTK_CONTAINER(frame), 4); | |
- table = CreateStatusWidgets(&Status); | |
- gtk_container_add(GTK_CONTAINER(frame), table); | |
- gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); | |
- | |
- hbox = gtk_hbox_new(FALSE, 5); | |
- CreateInventory(hbox, Names.Drugs, accel_group, FALSE, FALSE, &SpyDrugs, | |
- NULL); | |
- CreateInventory(hbox, Names.Guns, accel_group, FALSE, FALSE, &SpyGuns, | |
- NULL); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); | |
- label = gtk_label_new(GetPlayerName(Play)); | |
- | |
- DisplayStats(Play, &Status); | |
- UpdateInventory(&SpyDrugs, Play->Drugs, NumDrug, TRUE); | |
- UpdateInventory(&SpyGuns, Play->Guns, NumGun, FALSE); | |
- | |
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label); | |
- | |
- gtk_widget_show_all(notebook); | |
-} | |
- | |
-#ifdef NETWORKING | |
-static void OKAuthDialog(GtkWidget *widget, GtkWidget *window) | |
-{ | |
- gtk_object_set_data(GTK_OBJECT(window), "authok", GINT_TO_POINTER(TRUE)); | |
- gtk_widget_destroy(window); | |
-} | |
- | |
-static void DestroyAuthDialog(GtkWidget *window, gpointer data) | |
-{ | |
- GtkWidget *userentry, *passwdentry; | |
- gchar *username = NULL, *password = NULL; | |
- gpointer proxy, authok; | |
- HttpConnection *conn; | |
- | |
- authok = gtk_object_get_data(GTK_OBJECT(window), "authok"); | |
- proxy = gtk_object_get_data(GTK_OBJECT(window), "proxy"); | |
- userentry = | |
- (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), "username"); | |
- passwdentry = | |
- (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), "password"); | |
- conn = | |
- (HttpConnection *)gtk_object_get_data(GTK_OBJECT(window), | |
- "httpconn"); | |
- g_assert(userentry && passwdentry && conn); | |
- | |
- if (authok) { | |
- username = gtk_editable_get_chars(GTK_EDITABLE(userentry), 0, -1); | |
- password = gtk_editable_get_chars(GTK_EDITABLE(passwdentry), 0, -1); | |
- } | |
- | |
- SetHttpAuthentication(conn, GPOINTER_TO_INT(proxy), username, password); | |
- | |
- g_free(username); | |
- g_free(password); | |
-} | |
- | |
-void AuthDialog(HttpConnection *conn, gboolean proxy, gchar *realm, | |
- gpointer data) | |
-{ | |
- GtkWidget *window, *button, *hsep, *vbox, *label, *entry, *table, *hbbox; | |
- | |
- window = gtk_window_new(GTK_WINDOW_DIALOG); | |
- gtk_signal_connect(GTK_OBJECT(window), "destroy", | |
- GTK_SIGNAL_FUNC(DestroyAuthDialog), NULL); | |
- gtk_object_set_data(GTK_OBJECT(window), "proxy", GINT_TO_POINTER(proxy)); | |
- gtk_object_set_data(GTK_OBJECT(window), "httpconn", (gpointer)conn); | |
- | |
- if (proxy) { | |
- gtk_window_set_title(GTK_WINDOW(window), | |
- /* Title of dialog for authenticating with a | |
- * proxy server */ | |
- _("Proxy Authentication Required")); | |
- } else { | |
- /* Title of dialog for authenticating with a web server */ | |
- gtk_window_set_title(GTK_WINDOW(window), _("Authentication Required")); | |
- } | |
- | |
- gtk_window_set_modal(GTK_WINDOW(window), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(window), | |
- GTK_WINDOW(ClientData.window)); | |
- gtk_container_set_border_width(GTK_CONTAINER(window), 7); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- | |
- table = gtk_table_new(3, 2, FALSE); | |
- gtk_table_set_row_spacings(GTK_TABLE(table), 10); | |
- gtk_table_set_col_spacings(GTK_TABLE(table), 5); | |
- | |
- label = gtk_label_new("Realm:"); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); | |
- | |
- label = gtk_label_new(realm); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 0, 1); | |
- | |
- label = gtk_label_new("User name:"); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); | |
- | |
- entry = gtk_entry_new(); | |
- gtk_object_set_data(GTK_OBJECT(window), "username", (gpointer)entry); | |
- gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 1, 2); | |
- | |
- label = gtk_label_new("Password:"); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); | |
- | |
- entry = gtk_entry_new(); | |
- gtk_object_set_data(GTK_OBJECT(window), "password", (gpointer)entry); | |
- | |
-#ifdef HAVE_FIXED_GTK | |
- /* GTK+ versions earlier than 1.2.10 do bad things with this */ | |
- gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); | |
-#endif | |
- | |
- gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 2, 3); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- | |
- hbbox = gtk_hbutton_box_new(); | |
- | |
- button = gtk_button_new_with_label(_("OK")); | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(OKAuthDialog), (gpointer)window); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- | |
- button = gtk_button_new_with_label(_("Cancel")); | |
- gtk_signal_connect_object(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
- (gpointer)window); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), hbbox, TRUE, TRUE, 0); | |
- | |
- gtk_container_add(GTK_CONTAINER(window), vbox); | |
- gtk_widget_show_all(window); | |
-} | |
- | |
-static void OKSocksAuth(GtkWidget *widget, GtkWidget *window) | |
-{ | |
- gtk_object_set_data(GTK_OBJECT(window), "authok", GINT_TO_POINTER(TRUE)); | |
- gtk_widget_destroy(window); | |
-} | |
- | |
-static void DestroySocksAuth(GtkWidget *window, gpointer data) | |
-{ | |
- GtkWidget *userentry, *passwdentry; | |
- gchar *username = NULL, *password = NULL; | |
- gpointer authok, meta; | |
- NetworkBuffer *netbuf; | |
- | |
- authok = gtk_object_get_data(GTK_OBJECT(window), "authok"); | |
- meta = gtk_object_get_data(GTK_OBJECT(window), "meta"); | |
- userentry = | |
- (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), "username"); | |
- passwdentry = | |
- (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), "password"); | |
- netbuf = | |
- (NetworkBuffer *)gtk_object_get_data(GTK_OBJECT(window), "netbuf"); | |
- | |
- g_assert(userentry && passwdentry && netbuf); | |
- | |
- if (authok) { | |
- username = gtk_editable_get_chars(GTK_EDITABLE(userentry), 0, -1); | |
- password = gtk_editable_get_chars(GTK_EDITABLE(passwdentry), 0, -1); | |
- } | |
- | |
- SendSocks5UserPasswd(netbuf, username, password); | |
- g_free(username); | |
- g_free(password); | |
-} | |
- | |
-static void RealSocksAuthDialog(NetworkBuffer *netbuf, gboolean meta, | |
- gpointer data) | |
-{ | |
- GtkWidget *window, *button, *hsep, *vbox, *label, *entry, *table, *hbbox; | |
- | |
- window = gtk_window_new(GTK_WINDOW_DIALOG); | |
- gtk_signal_connect(GTK_OBJECT(window), "destroy", | |
- GTK_SIGNAL_FUNC(DestroySocksAuth), NULL); | |
- gtk_object_set_data(GTK_OBJECT(window), "netbuf", (gpointer)netbuf); | |
- gtk_object_set_data(GTK_OBJECT(window), "meta", GINT_TO_POINTER(meta)); | |
- | |
- /* Title of dialog for authenticating with a SOCKS server */ | |
- gtk_window_set_title(GTK_WINDOW(window), | |
- _("SOCKS Authentication Required")); | |
- | |
- gtk_window_set_modal(GTK_WINDOW(window), TRUE); | |
- gtk_window_set_transient_for(GTK_WINDOW(window), | |
- GTK_WINDOW(ClientData.window)); | |
- gtk_container_set_border_width(GTK_CONTAINER(window), 7); | |
- | |
- vbox = gtk_vbox_new(FALSE, 7); | |
- | |
- table = gtk_table_new(2, 2, FALSE); | |
- gtk_table_set_row_spacings(GTK_TABLE(table), 10); | |
- gtk_table_set_col_spacings(GTK_TABLE(table), 5); | |
- | |
- label = gtk_label_new("User name:"); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); | |
- | |
- entry = gtk_entry_new(); | |
- gtk_object_set_data(GTK_OBJECT(window), "username", (gpointer)entry); | |
- gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 0, 1); | |
- | |
- label = gtk_label_new("Password:"); | |
- gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); | |
- | |
- entry = gtk_entry_new(); | |
- gtk_object_set_data(GTK_OBJECT(window), "password", (gpointer)entry); | |
- | |
-#ifdef HAVE_FIXED_GTK | |
- /* GTK+ versions earlier than 1.2.10 do bad things with this */ | |
- gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); | |
-#endif | |
- | |
- gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 1, 2); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0); | |
- | |
- hsep = gtk_hseparator_new(); | |
- gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
- | |
- hbbox = gtk_hbutton_box_new(); | |
- | |
- button = gtk_button_new_with_label(_("OK")); | |
- gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(OKSocksAuth), (gpointer)window); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- | |
- button = gtk_button_new_with_label(_("Cancel")); | |
- gtk_signal_connect_object(GTK_OBJECT(button), "clicked", | |
- GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
- (gpointer)window); | |
- gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
- | |
- gtk_box_pack_start(GTK_BOX(vbox), hbbox, TRUE, TRUE, 0); | |
- | |
- gtk_container_add(GTK_CONTAINER(window), vbox); | |
- gtk_widget_show_all(window); | |
-} | |
- | |
-void MetaSocksAuthDialog(NetworkBuffer *netbuf, gpointer data) | |
-{ | |
- RealSocksAuthDialog(netbuf, TRUE, data); | |
-} | |
- | |
-void SocksAuthDialog(NetworkBuffer *netbuf, gpointer data) | |
-{ | |
- RealSocksAuthDialog(netbuf, FALSE, data); | |
-} | |
- | |
-#endif /* NETWORKING */ | |
- | |
-#else | |
- | |
-#include <glib.h> | |
-#include "nls.h" /* We need this for the definition of '_' */ | |
- | |
-char GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail) | |
-{ | |
- if (!ReturnOnFail) { | |
- /* Error message displayed if the user tries to run the graphical | |
- * client when none is compiled into the dopewars binary. */ | |
- g_print(_("No graphical client available - rebuild the binary\n" | |
- "passing the --enable-gui-client option to configure, or\n" | |
- "use the curses client (if available) instead!\n")); | |
- } | |
- return FALSE; | |
-} | |
- | |
-#endif /* GUI_CLIENT */ | |
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: [email protected] * | |
- * WWW: http://dopewars.sourceforge.net/ * | |
- * * | |
- * This program is free software; you can redistribute it and/or * | |
- * modify it under the terms of the GNU General Public License * | |
- * as published by the Free Software Foundation; either version 2 * | |
- * of the License, or (at your option) any later version. * | |
- * * | |
- * This program is distributed in the hope that it will be useful, * | |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
- * GNU General Public License for more details. * | |
- * * | |
- * You should have received a copy of the GNU General Public License * | |
- * along with this program; if not, write to the Free Software * | |
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * | |
- * MA 02111-1307, USA. * | |
- ************************************************************************/ | |
- | |
-#ifndef __GTK_CLIENT_H__ | |
-#define __GTK_CLIENT_H__ | |
- | |
-#ifdef HAVE_CONFIG_H | |
-#include <config.h> | |
-#endif | |
- | |
-#include "gtkport.h" | |
- | |
-extern GtkWidget *MainWindow; | |
- | |
-#ifdef CYGWIN | |
-char GtkLoop(HINSTANCE hInstance, HINSTANCE hPrevInstance); | |
-#else | |
-char GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail); | |
-#endif | |
- | |
-#endif | |
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) $(… | |
+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 … | |
+ | |
+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… | |
+ @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) $(… | |
+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_LI… | |
+ $(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 … | |
+ | |
+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… | |
+ @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: [email protected] * | |
+ * WWW: http://dopewars.sourceforge.net/ * | |
+ * * | |
+ * This program is free software; you can redistribute it and/or * | |
+ * modify it under the terms of the GNU General Public License * | |
+ * as published by the Free Software Foundation; either version 2 * | |
+ * of the License, or (at your option) any later version. * | |
+ * * | |
+ * This program is distributed in the hope that it will be useful, * | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
+ * GNU General Public License for more details. * | |
+ * * | |
+ * You should have received a copy of the GNU General Public License * | |
+ * along with this program; if not, write to the Free Software * | |
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * | |
+ * MA 02111-1307, USA. * | |
+ ************************************************************************/ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#include <stdlib.h> | |
+#include <ctype.h> | |
+#include <string.h> | |
+ | |
+#include "dopeos.h" | |
+#include "dopewars.h" | |
+#include "gtk_client.h" | |
+#include "message.h" | |
+#include "nls.h" | |
+#include "serverside.h" | |
+#include "tstring.h" | |
+#include "gtkport/gtkport.h" | |
+#include "dopewars-pill.xpm" | |
+ | |
+#define BT_BUY (GINT_TO_POINTER(1)) | |
+#define BT_SELL (GINT_TO_POINTER(2)) | |
+#define BT_DROP (GINT_TO_POINTER(3)) | |
+ | |
+#define ET_SPY 0 | |
+#define ET_TIPOFF 1 | |
+ | |
+/* Which notebook page to display in the New Game dialog */ | |
+static gint NewGameType = 0; | |
+ | |
+struct InventoryWidgets { | |
+ GtkWidget *HereList, *CarriedList; | |
+ GtkWidget *HereFrame, *CarriedFrame; | |
+ GtkWidget *BuyButton, *SellButton, *DropButton; | |
+ GtkWidget *vbbox; | |
+}; | |
+ | |
+struct StatusWidgets { | |
+ GtkWidget *Location, *Date, *SpaceName, *SpaceValue, *CashName; | |
+ GtkWidget *CashValue, *DebtName, *DebtValue, *BankName, *BankValue; | |
+ GtkWidget *GunsName, *GunsValue, *BitchesName, *BitchesValue; | |
+ GtkWidget *HealthName, *HealthValue; | |
+}; | |
+ | |
+struct ClientDataStruct { | |
+ GtkWidget *window, *messages; | |
+ Player *Play; | |
+ GtkItemFactory *Menu; | |
+ struct StatusWidgets Status; | |
+ struct InventoryWidgets Drug, Gun, InvenDrug, InvenGun; | |
+ GtkWidget *JetButton, *vbox, *PlayerList, *TalkList; | |
+ guint JetAccel; | |
+}; | |
+ | |
+GtkWidget *MainWindow; | |
+ | |
+struct StartGameStruct { | |
+ GtkWidget *dialog, *name, *hostname, *port, *antique, *status, *metaserv; | |
+#ifdef NETWORKING | |
+ HttpConnection *MetaConn; | |
+ GSList *NewMetaList; | |
+#endif | |
+}; | |
+ | |
+static struct ClientDataStruct ClientData; | |
+static gboolean InGame = FALSE; | |
+ | |
+static GtkWidget *FightDialog = NULL, *SpyReportsDialog; | |
+static gboolean IsShowingPlayerList = FALSE, IsShowingTalkList = FALSE; | |
+static gboolean IsShowingInventory = FALSE, IsShowingGunShop = FALSE; | |
+ | |
+static void display_intro(GtkWidget *widget, gpointer data); | |
+static void QuitGame(GtkWidget *widget, gpointer data); | |
+static void DestroyGtk(GtkWidget *widget, gpointer data); | |
+static void NewGame(GtkWidget *widget, gpointer data); | |
+static void ListScores(GtkWidget *widget, gpointer data); | |
+static void ListInventory(GtkWidget *widget, gpointer data); | |
+static void NewGameDialog(void); | |
+static void StartGame(void); | |
+static void EndGame(void); | |
+static void Jet(GtkWidget *parent); | |
+static void UpdateMenus(void); | |
+ | |
+#ifdef NETWORKING | |
+static void DisplayConnectStatus(struct StartGameStruct *widgets, | |
+ gboolean meta, NBStatus oldstatus, | |
+ NBSocksStatus oldsocks); | |
+static void AuthDialog(HttpConnection *conn, gboolean proxyauth, | |
+ gchar *realm, gpointer data); | |
+static void MetaSocksAuthDialog(NetworkBuffer *netbuf, gpointer data); | |
+static void SocksAuthDialog(NetworkBuffer *netbuf, gpointer data); | |
+static void GetClientMessage(gpointer data, gint socket, | |
+ GdkInputCondition condition); | |
+static void SocketStatus(NetworkBuffer *NetBuf, gboolean Read, | |
+ gboolean Write, gboolean CallNow); | |
+static void MetaSocketStatus(NetworkBuffer *NetBuf, gboolean Read, | |
+ gboolean Write, gboolean CallNow); | |
+static void FinishServerConnect(struct StartGameStruct *widgets, | |
+ gboolean ConnectOK); | |
+ | |
+/* List of servers on the metaserver */ | |
+static GSList *MetaList = NULL; | |
+ | |
+#endif /* NETWORKING */ | |
+ | |
+static void HandleClientMessage(char *buf, Player *Play); | |
+static void PrepareHighScoreDialog(void); | |
+static void AddScoreToDialog(char *Data); | |
+static void CompleteHighScoreDialog(gboolean AtEnd); | |
+static void PrintMessage(char *Data); | |
+static void DisplayFightMessage(char *Data); | |
+static GtkWidget *CreateStatusWidgets(struct StatusWidgets *Status); | |
+static void DisplayStats(Player *Play, struct StatusWidgets *Status); | |
+static void UpdateStatus(Player *Play); | |
+static void SetJetButtonTitle(GtkAccelGroup *accel_group); | |
+static void UpdateInventory(struct InventoryWidgets *Inven, | |
+ Inventory *Objects, int NumObjects, | |
+ gboolean AreDrugs); | |
+static void JetButtonPressed(GtkWidget *widget, gpointer data); | |
+static void DealDrugs(GtkWidget *widget, gpointer data); | |
+static void DealGuns(GtkWidget *widget, gpointer data); | |
+static void QuestionDialog(char *Data, Player *From); | |
+static void TransferDialog(gboolean Debt); | |
+static void ListPlayers(GtkWidget *widget, gpointer data); | |
+static void TalkToAll(GtkWidget *widget, gpointer data); | |
+static void TalkToPlayers(GtkWidget *widget, gpointer data); | |
+static void TalkDialog(gboolean TalkToAll); | |
+static GtkWidget *CreatePlayerList(void); | |
+static void UpdatePlayerList(GtkWidget *clist, gboolean IncludeSelf); | |
+static void TipOff(GtkWidget *widget, gpointer data); | |
+static void SpyOnPlayer(GtkWidget *widget, gpointer data); | |
+static void ErrandDialog(gint ErrandType); | |
+static void SackBitch(GtkWidget *widget, gpointer data); | |
+static void DestroyShowing(GtkWidget *widget, gpointer data); | |
+static gint DisallowDelete(GtkWidget *widget, GdkEvent * event, | |
+ gpointer data); | |
+static void GunShopDialog(void); | |
+static void NewNameDialog(void); | |
+static void UpdatePlayerLists(void); | |
+static void CreateInventory(GtkWidget *hbox, gchar *Objects, | |
+ GtkAccelGroup *accel_group, | |
+ gboolean CreateButtons, gboolean CreateHere, | |
+ struct InventoryWidgets *widgets, | |
+ GtkSignalFunc CallBack); | |
+static void GetSpyReports(GtkWidget *widget, gpointer data); | |
+static void DisplaySpyReports(Player *Play); | |
+ | |
+static GtkItemFactoryEntry menu_items[] = { | |
+ /* The names of the the menus and their items in the GTK+ client */ | |
+ {N_("/_Game"), NULL, NULL, 0, "<Branch>"}, | |
+ {N_("/Game/_New..."), "<control>N", NewGame, 0, NULL}, | |
+ {N_("/Game/_Quit..."), "<control>Q", QuitGame, 0, NULL}, | |
+ {N_("/_Talk"), NULL, NULL, 0, "<Branch>"}, | |
+ {N_("/Talk/To _All..."), NULL, TalkToAll, 0, NULL}, | |
+ {N_("/Talk/To _Player..."), NULL, TalkToPlayers, 0, NULL}, | |
+ {N_("/_List"), NULL, NULL, 0, "<Branch>"}, | |
+ {N_("/List/_Players..."), NULL, ListPlayers, 0, NULL}, | |
+ {N_("/List/_Scores..."), NULL, ListScores, 0, NULL}, | |
+ {N_("/List/_Inventory..."), NULL, ListInventory, 0, NULL}, | |
+ {N_("/_Errands"), NULL, NULL, 0, "<Branch>"}, | |
+ {N_("/Errands/_Spy..."), NULL, SpyOnPlayer, 0, NULL}, | |
+ {N_("/Errands/_Tipoff..."), NULL, TipOff, 0, NULL}, | |
+ /* N.B. "Sack Bitch" has to be recreated (and thus translated) at the | |
+ * start of each game, below, so is not marked for gettext here */ | |
+ {"/Errands/S_ack Bitch...", NULL, SackBitch, 0, NULL}, | |
+ {N_("/Errands/_Get spy reports..."), NULL, GetSpyReports, 0, NULL}, | |
+ {N_("/_Help"), NULL, NULL, 0, "<LastBranch>"}, | |
+ {N_("/Help/_About..."), "F1", display_intro, 0, NULL} | |
+}; | |
+ | |
+static gchar *MenuTranslate(const gchar *path, gpointer func_data) | |
+{ | |
+ /* Translate menu items, using gettext */ | |
+ return _(path); | |
+} | |
+ | |
+static void LogMessage(const gchar *log_domain, GLogLevelFlags log_level, | |
+ const gchar *message, gpointer user_data) | |
+{ | |
+ GtkMessageBox(NULL, message, | |
+ /* Titles of the message boxes for warnings and errors */ | |
+ log_level & G_LOG_LEVEL_WARNING ? _("Warning") : | |
+ log_level & G_LOG_LEVEL_CRITICAL ? _("Error") : | |
+ _("Message"), | |
+ MB_OK | (gtk_main_level() > 0 ? MB_IMMRETURN : 0)); | |
+} | |
+ | |
+void QuitGame(GtkWidget *widget, gpointer data) | |
+{ | |
+ if (!InGame || GtkMessageBox(ClientData.window, | |
+ /* Prompt in 'quit game' dialog */ | |
+ _("Abandon current game?"), | |
+ /* Title of 'quit game' dialog */ | |
+ _("Quit Game"), MB_YESNO) == IDYES) { | |
+ gtk_main_quit(); | |
+ } | |
+} | |
+ | |
+void DestroyGtk(GtkWidget *widget, gpointer data) | |
+{ | |
+ gtk_main_quit(); | |
+} | |
+ | |
+gint MainDelete(GtkWidget *widget, GdkEvent * event, gpointer data) | |
+{ | |
+ return (InGame | |
+ && GtkMessageBox(ClientData.window, _("Abandon current game?"), | |
+ _("Quit Game"), MB_YESNO) == IDNO); | |
+} | |
+ | |
+ | |
+void NewGame(GtkWidget *widget, gpointer data) | |
+{ | |
+ if (InGame) { | |
+ if (GtkMessageBox(ClientData.window, _("Abandon current game?"), | |
+ /* Title of 'stop game to start a new game' dialog */ | |
+ _("Start new game"), MB_YESNO) == IDYES) | |
+ EndGame(); | |
+ else | |
+ return; | |
+ } | |
+ | |
+ /* Save the configuration, so we can restore those elements that get | |
+ * overwritten when we connect to a dopewars server */ | |
+ BackupConfig(); | |
+ | |
+ NewGameDialog(); | |
+} | |
+ | |
+void ListScores(GtkWidget *widget, gpointer data) | |
+{ | |
+ SendClientMessage(ClientData.Play, C_NONE, C_REQUESTSCORE, NULL, NULL); | |
+} | |
+ | |
+void ListInventory(GtkWidget *widget, gpointer data) | |
+{ | |
+ GtkWidget *window, *button, *hsep, *vbox, *hbox; | |
+ GtkAccelGroup *accel_group; | |
+ | |
+ if (IsShowingInventory) | |
+ return; | |
+ window = gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_window_set_default_size(GTK_WINDOW(window), 550, 120); | |
+ accel_group = gtk_accel_group_new(); | |
+ gtk_window_add_accel_group(GTK_WINDOW(window), accel_group); | |
+ | |
+ /* Title of inventory window */ | |
+ gtk_window_set_title(GTK_WINDOW(window), _("Inventory")); | |
+ | |
+ IsShowingInventory = TRUE; | |
+ gtk_window_set_modal(GTK_WINDOW(window), FALSE); | |
+ gtk_object_set_data(GTK_OBJECT(window), "IsShowing", | |
+ (gpointer)&IsShowingInventory); | |
+ gtk_signal_connect(GTK_OBJECT(window), "destroy", | |
+ GTK_SIGNAL_FUNC(DestroyShowing), NULL); | |
+ | |
+ gtk_window_set_transient_for(GTK_WINDOW(window), | |
+ GTK_WINDOW(ClientData.window)); | |
+ gtk_container_set_border_width(GTK_CONTAINER(window), 7); | |
+ | |
+ vbox = gtk_vbox_new(FALSE, 7); | |
+ | |
+ hbox = gtk_hbox_new(FALSE, 7); | |
+ CreateInventory(hbox, Names.Drugs, accel_group, FALSE, FALSE, | |
+ &ClientData.InvenDrug, NULL); | |
+ CreateInventory(hbox, Names.Guns, accel_group, FALSE, FALSE, | |
+ &ClientData.InvenGun, NULL); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); | |
+ | |
+ hsep = gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
+ | |
+ /* Caption of the button to close a dialog */ | |
+ button = gtk_button_new_with_label(_("Close")); | |
+ gtk_signal_connect_object(GTK_OBJECT(button), "clicked", | |
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
+ (gpointer)window); | |
+ gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); | |
+ | |
+ gtk_container_add(GTK_CONTAINER(window), vbox); | |
+ | |
+ UpdateInventory(&ClientData.InvenDrug, ClientData.Play->Drugs, NumDrug, | |
+ TRUE); | |
+ UpdateInventory(&ClientData.InvenGun, ClientData.Play->Guns, NumGun, | |
+ FALSE); | |
+ | |
+ gtk_widget_show_all(window); | |
+} | |
+ | |
+#ifdef NETWORKING | |
+void GetClientMessage(gpointer data, gint socket, | |
+ GdkInputCondition condition) | |
+{ | |
+ gchar *pt; | |
+ NetworkBuffer *NetBuf; | |
+ gboolean DoneOK, datawaiting; | |
+ NBStatus status, oldstatus; | |
+ NBSocksStatus oldsocks; | |
+ | |
+ NetBuf = &ClientData.Play->NetBuf; | |
+ | |
+ oldstatus = NetBuf->status; | |
+ oldsocks = NetBuf->sockstat; | |
+ | |
+ datawaiting = | |
+ PlayerHandleNetwork(ClientData.Play, condition & GDK_INPUT_READ, | |
+ condition & GDK_INPUT_WRITE, &DoneOK); | |
+ | |
+ status = NetBuf->status; | |
+ | |
+ if (status != NBS_CONNECTED) { | |
+ /* The start game dialog isn't visible once we're connected... */ | |
+ DisplayConnectStatus((struct StartGameStruct *)data, FALSE, | |
+ oldstatus, oldsocks); | |
+ } | |
+ | |
+ if (oldstatus != NBS_CONNECTED && (status == NBS_CONNECTED || !DoneOK)) { | |
+ FinishServerConnect(data, DoneOK); | |
+ } | |
+ if (status == NBS_CONNECTED && datawaiting) { | |
+ while ((pt = GetWaitingPlayerMessage(ClientData.Play)) != NULL) { | |
+ HandleClientMessage(pt, ClientData.Play); | |
+ g_free(pt); | |
+ } | |
+ } | |
+ if (!DoneOK) { | |
+ if (status == NBS_CONNECTED) { | |
+ /* The network connection to the server was dropped unexpectedly */ | |
+ g_warning(_("Connection to server lost - switching to " | |
+ "single player mode")); | |
+ SwitchToSinglePlayer(ClientData.Play); | |
+ UpdatePlayerLists(); | |
+ UpdateMenus(); | |
+ } else { | |
+ ShutdownNetworkBuffer(&ClientData.Play->NetBuf); | |
+ } | |
+ } | |
+} | |
+ | |
+void SocketStatus(NetworkBuffer *NetBuf, gboolean Read, gboolean Write, | |
+ gboolean CallNow) | |
+{ | |
+ if (NetBuf->InputTag) | |
+ gdk_input_remove(NetBuf->InputTag); | |
+ NetBuf->InputTag = 0; | |
+ if (Read || Write) { | |
+ NetBuf->InputTag = gdk_input_add(NetBuf->fd, | |
+ (Read ? GDK_INPUT_READ : 0) | | |
+ (Write ? GDK_INPUT_WRITE : 0), | |
+ GetClientMessage, | |
+ NetBuf->CallBackData); | |
+ } | |
+ if (CallNow) | |
+ GetClientMessage(NetBuf->CallBackData, NetBuf->fd, 0); | |
+} | |
+#endif /* NETWORKING */ | |
+ | |
+void HandleClientMessage(char *pt, Player *Play) | |
+{ | |
+ char *Data; | |
+ DispMode DisplayMode; | |
+ AICode AI; | |
+ MsgCode Code; | |
+ Player *From, *tmp; | |
+ gchar *text; | |
+ gboolean Handled; | |
+ GtkWidget *MenuItem; | |
+ GSList *list; | |
+ | |
+ if (ProcessMessage(pt, Play, &From, &AI, &Code, | |
+ &Data, FirstClient) == -1) { | |
+ return; | |
+ } | |
+ | |
+ Handled = | |
+ HandleGenericClientMessage(From, AI, Code, Play, Data, &DisplayMode); | |
+ switch (Code) { | |
+ case C_STARTHISCORE: | |
+ PrepareHighScoreDialog(); | |
+ break; | |
+ case C_HISCORE: | |
+ AddScoreToDialog(Data); | |
+ break; | |
+ case C_ENDHISCORE: | |
+ CompleteHighScoreDialog((strcmp(Data, "end") == 0)); | |
+ break; | |
+ case C_PRINTMESSAGE: | |
+ PrintMessage(Data); | |
+ break; | |
+ case C_FIGHTPRINT: | |
+ DisplayFightMessage(Data); | |
+ break; | |
+ case C_PUSH: | |
+ /* The server admin has asked us to leave - so warn the user, and do | |
+ * so */ | |
+ g_warning(_("You have been pushed from the server.\n" | |
+ "Switching to single player mode.")); | |
+ SwitchToSinglePlayer(Play); | |
+ UpdatePlayerLists(); | |
+ UpdateMenus(); | |
+ break; | |
+ case C_QUIT: | |
+ /* The server has sent us notice that it is shutting down */ | |
+ g_warning(_("The server has terminated.\n" | |
+ "Switching to single player mode.")); | |
+ SwitchToSinglePlayer(Play); | |
+ UpdatePlayerLists(); | |
+ UpdateMenus(); | |
+ break; | |
+ case C_NEWNAME: | |
+ NewNameDialog(); | |
+ break; | |
+ case C_BANK: | |
+ TransferDialog(FALSE); | |
+ break; | |
+ case C_LOANSHARK: | |
+ TransferDialog(TRUE); | |
+ break; | |
+ case C_GUNSHOP: | |
+ GunShopDialog(); | |
+ break; | |
+ case C_MSG: | |
+ text = g_strdup_printf("%s: %s", GetPlayerName(From), Data); | |
+ PrintMessage(text); | |
+ g_free(text); | |
+ break; | |
+ case C_MSGTO: | |
+ text = g_strdup_printf("%s->%s: %s", GetPlayerName(From), | |
+ GetPlayerName(Play), Data); | |
+ PrintMessage(text); | |
+ g_free(text); | |
+ break; | |
+ case C_JOIN: | |
+ text = g_strdup_printf(_("%s joins the game!"), Data); | |
+ PrintMessage(text); | |
+ g_free(text); | |
+ UpdatePlayerLists(); | |
+ UpdateMenus(); | |
+ break; | |
+ case C_LEAVE: | |
+ if (From != &Noone) { | |
+ text = g_strdup_printf(_("%s has left the game."), Data); | |
+ PrintMessage(text); | |
+ g_free(text); | |
+ UpdatePlayerLists(); | |
+ UpdateMenus(); | |
+ } | |
+ break; | |
+ case C_QUESTION: | |
+ QuestionDialog(Data, From == &Noone ? NULL : From); | |
+ break; | |
+ case C_SUBWAYFLASH: | |
+ DisplayFightMessage(NULL); | |
+ for (list = FirstClient; list; list = g_slist_next(list)) { | |
+ tmp = (Player *)list->data; | |
+ tmp->Flags &= ~FIGHTING; | |
+ } | |
+ /* Message displayed when the player "jets" to a new location */ | |
+ text = dpg_strdup_printf(_("Jetting to %tde"), | |
+ Location[(int)Play->IsAt].Name); | |
+ PrintMessage(text); | |
+ g_free(text); | |
+ break; | |
+ case C_ENDLIST: | |
+ MenuItem = gtk_item_factory_get_widget(ClientData.Menu, | |
+ "<main>/Errands/Sack Bitch..."); | |
+ | |
+ /* Text for the Errands/Sack Bitch menu item */ | |
+ text = dpg_strdup_printf(_("%/Sack Bitch menu item/S_ack %Tde..."), | |
+ Names.Bitch); | |
+ SetAccelerator(MenuItem, text, NULL, NULL, NULL); | |
+ g_free(text); | |
+ | |
+ MenuItem = gtk_item_factory_get_widget(ClientData.Menu, | |
+ "<main>/Errands/Spy..."); | |
+ | |
+ /* Text to update the Errands/Spy menu item with the price for spying */ | |
+ text = dpg_strdup_printf(_("_Spy (%P)"), Prices.Spy); | |
+ SetAccelerator(MenuItem, text, NULL, NULL, NULL); | |
+ g_free(text); | |
+ | |
+ /* Text to update the Errands/Tipoff menu item with the price for a | |
+ * tipoff */ | |
+ text = dpg_strdup_printf(_("_Tipoff (%P)"), Prices.Tipoff); | |
+ MenuItem = gtk_item_factory_get_widget(ClientData.Menu, | |
+ "<main>/Errands/Tipoff..."); | |
+ SetAccelerator(MenuItem, text, NULL, NULL, NULL); | |
+ g_free(text); | |
+ if (FirstClient->next) | |
+ ListPlayers(NULL, NULL); | |
+ UpdateMenus(); | |
+ break; | |
+ case C_UPDATE: | |
+ if (From == &Noone) { | |
+ ReceivePlayerData(Play, Data, Play); | |
+ UpdateStatus(Play); | |
+ } else { | |
+ ReceivePlayerData(Play, Data, From); | |
+ DisplaySpyReports(From); | |
+ } | |
+ break; | |
+ case C_DRUGHERE: | |
+ UpdateInventory(&ClientData.Drug, Play->Drugs, NumDrug, TRUE); | |
+ gtk_clist_sort(GTK_CLIST(ClientData.Drug.HereList)); | |
+ if (IsShowingInventory) { | |
+ UpdateInventory(&ClientData.InvenDrug, Play->Drugs, NumDrug, TRUE); | |
+ } | |
+ break; | |
+ default: | |
+ if (!Handled) { | |
+ g_print("Unknown network message received: %s^%c^%s^%s", | |
+ GetPlayerName(From), Code, GetPlayerName(Play), Data); | |
+ } | |
+ break; | |
+ } | |
+} | |
+ | |
+struct HiScoreDiaStruct { | |
+ GtkWidget *dialog, *table, *vbox; | |
+}; | |
+static struct HiScoreDiaStruct HiScoreDialog = { NULL, NULL, NULL }; | |
+ | |
+/* | |
+ * Creates an empty dialog to display high scores. | |
+ */ | |
+void PrepareHighScoreDialog(void) | |
+{ | |
+ GtkWidget *dialog, *vbox, *hsep, *table; | |
+ | |
+ /* Make sure the server doesn't fool us into creating multiple dialogs */ | |
+ if (HiScoreDialog.dialog) | |
+ return; | |
+ | |
+ HiScoreDialog.dialog = dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
+ | |
+ /* Title of the GTK+ high score dialog */ | |
+ gtk_window_set_title(GTK_WINDOW(dialog), _("High Scores")); | |
+ | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ | |
+ HiScoreDialog.vbox = vbox = gtk_vbox_new(FALSE, 7); | |
+ HiScoreDialog.table = table = gtk_table_new(NUMHISCORE, 4, FALSE); | |
+ gtk_table_set_row_spacings(GTK_TABLE(table), 5); | |
+ gtk_table_set_col_spacings(GTK_TABLE(table), 30); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0); | |
+ hsep = gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
+ gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
+ gtk_widget_show_all(dialog); | |
+} | |
+ | |
+/* | |
+ * Adds a single high score (coded in "Data", which is the information | |
+ * received in the relevant network message) to the dialog created by | |
+ * PrepareHighScoreDialog(), above. | |
+ */ | |
+void AddScoreToDialog(char *Data) | |
+{ | |
+ GtkWidget *label; | |
+ char *cp; | |
+ gchar **spl1, **spl2; | |
+ int index, slen; | |
+ gboolean bold; | |
+ | |
+ if (!HiScoreDialog.dialog) | |
+ return; | |
+ | |
+ cp = Data; | |
+ index = GetNextInt(&cp, 0); | |
+ if (!cp || strlen(cp) < 3) | |
+ return; | |
+ | |
+ bold = (*cp == 'B'); /* Is this score "our" score? (Currently | |
+ * ignored) */ | |
+ | |
+ /* Step past the 'bold' character, and the initial '>' (if present) */ | |
+ cp += 2; | |
+ g_strchug(cp); | |
+ | |
+ /* Get the first word - the score */ | |
+ spl1 = g_strsplit(cp, " ", 1); | |
+ if (!spl1 || !spl1[0] || !spl1[1]) { | |
+ /* Error - the high score from the server is invalid */ | |
+ g_warning(_("Corrupt high score!")); | |
+ g_strfreev(spl1); | |
+ return; | |
+ } | |
+ label = gtk_label_new(spl1[0]); | |
+ gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); | |
+ gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label, | |
+ 0, 1, index, index + 1); | |
+ gtk_widget_show(label); | |
+ | |
+ /* Remove any leading whitespace from the remainder, since g_strsplit | |
+ * will split at every space character, not at a run of them */ | |
+ g_strchug(spl1[1]); | |
+ | |
+ /* Get the second word - the date */ | |
+ spl2 = g_strsplit(spl1[1], " ", 1); | |
+ if (!spl2 || !spl2[0] || !spl2[1]) { | |
+ g_warning(_("Corrupt high score!")); | |
+ g_strfreev(spl2); | |
+ return; | |
+ } | |
+ label = gtk_label_new(spl2[0]); | |
+ gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5); | |
+ gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label, | |
+ 1, 2, index, index + 1); | |
+ gtk_widget_show(label); | |
+ | |
+ /* The remainder is the name, terminated with (R.I.P.) if the player | |
+ * died, and '<' for the 'current' score */ | |
+ g_strchug(spl2[1]); | |
+ | |
+ /* Remove '<' suffix if present */ | |
+ slen = strlen(spl2[1]); | |
+ if (slen >= 1 && spl2[1][slen - 1] == '<') { | |
+ spl2[1][slen - 1] = '\0'; | |
+ } | |
+ slen--; | |
+ | |
+ /* Check for (R.I.P.) suffix, and add it to the 4th column if found */ | |
+ if (slen > 8 && spl2[1][slen - 1] == ')' && spl2[1][slen - 8] == '(') { | |
+ label = gtk_label_new(&spl2[1][slen - 8]); | |
+ gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5); | |
+ gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label, | |
+ 3, 4, index, index + 1); | |
+ gtk_widget_show(label); | |
+ spl2[1][slen - 8] = '\0'; /* Remove suffix from the player name */ | |
+ } | |
+ | |
+ /* Finally, add in what's left of the player name */ | |
+ g_strchomp(spl2[1]); | |
+ label = gtk_label_new(spl2[1]); | |
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
+ gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table), label, | |
+ 2, 3, index, index + 1); | |
+ gtk_widget_show(label); | |
+ | |
+ g_strfreev(spl1); | |
+ g_strfreev(spl2); | |
+} | |
+ | |
+/* | |
+ * If the high scores are being displayed at the end of the game, | |
+ * this function is used to end the game when the high score dialog's | |
+ * "OK" button is pressed. | |
+ */ | |
+static void EndHighScore(GtkWidget *widget) | |
+{ | |
+ EndGame(); | |
+} | |
+ | |
+/* | |
+ * Called when all high scores have been received. Finishes off the | |
+ * high score dialog by adding an "OK" button. If the game has ended, | |
+ * then "AtEnd" is TRUE, and clicking this button will end the game. | |
+ */ | |
+void CompleteHighScoreDialog(gboolean AtEnd) | |
+{ | |
+ GtkWidget *OKButton, *dialog; | |
+ | |
+ dialog = HiScoreDialog.dialog; | |
+ | |
+ if (!HiScoreDialog.dialog) | |
+ return; | |
+ | |
+ /* Caption of the "OK" button in dialogs */ | |
+ OKButton = gtk_button_new_with_label(_("OK")); | |
+ gtk_signal_connect_object(GTK_OBJECT(OKButton), "clicked", | |
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
+ (gpointer)dialog); | |
+ if (AtEnd) { | |
+ InGame = FALSE; | |
+ gtk_signal_connect_object(GTK_OBJECT(dialog), "destroy", | |
+ GTK_SIGNAL_FUNC(EndHighScore), NULL); | |
+ } | |
+ gtk_box_pack_start(GTK_BOX(HiScoreDialog.vbox), OKButton, TRUE, TRUE, 0); | |
+ | |
+ GTK_WIDGET_SET_FLAGS(OKButton, GTK_CAN_DEFAULT); | |
+ gtk_widget_grab_default(OKButton); | |
+ gtk_widget_show(OKButton); | |
+ | |
+ /* OK, we're done - allow the creation of new high score dialogs */ | |
+ HiScoreDialog.dialog = NULL; | |
+} | |
+ | |
+/* | |
+ * Prints an information message in the display area of the GTK+ client. | |
+ * This area is used for displaying drug busts, messages from other | |
+ * players, etc. The message is passed in as the string "text". | |
+ */ | |
+void PrintMessage(char *text) | |
+{ | |
+ gint EditPos; | |
+ char *cr = "\n"; | |
+ GtkEditable *messages; | |
+ | |
+ messages = GTK_EDITABLE(ClientData.messages); | |
+ | |
+ gtk_text_freeze(GTK_TEXT(messages)); | |
+ g_strdelimit(text, "^", '\n'); | |
+ EditPos = gtk_text_get_length(GTK_TEXT(ClientData.messages)); | |
+ while (*text == '\n') | |
+ text++; | |
+ gtk_editable_insert_text(messages, text, strlen(text), &EditPos); | |
+ if (text[strlen(text) - 1] != '\n') { | |
+ gtk_editable_insert_text(messages, cr, strlen(cr), &EditPos); | |
+ } | |
+ gtk_text_thaw(GTK_TEXT(messages)); | |
+ gtk_editable_set_position(messages, EditPos); | |
+} | |
+ | |
+/* | |
+ * Called when one of the action buttons in the Fight dialog is clicked. | |
+ * "data" specifies which button (Deal Drugs/Run/Fight/Stand) was pressed. | |
+ */ | |
+static void FightCallback(GtkWidget *widget, gpointer data) | |
+{ | |
+ gint Answer; | |
+ Player *Play; | |
+ gchar text[4]; | |
+ GtkWidget *window; | |
+ gpointer CanRunHere = NULL; | |
+ | |
+ window = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); | |
+ if (window) | |
+ CanRunHere = gtk_object_get_data(GTK_OBJECT(window), "CanRunHere"); | |
+ | |
+ Answer = GPOINTER_TO_INT(data); | |
+ Play = ClientData.Play; | |
+ switch (Answer) { | |
+ case 'D': | |
+ gtk_widget_hide(FightDialog); | |
+ break; | |
+ case 'R': | |
+ if (CanRunHere) { | |
+ SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, "R"); | |
+ } else { | |
+ Jet(FightDialog); | |
+ } | |
+ break; | |
+ case 'F': | |
+ case 'S': | |
+ text[0] = Answer; | |
+ text[1] = '\0'; | |
+ SendClientMessage(Play, C_NONE, C_FIGHTACT, NULL, text); | |
+ break; | |
+ } | |
+} | |
+ | |
+/* | |
+ * Adds an action button to the hbox at the base of the Fight dialog. | |
+ * The button's caption is given by "Text", and the keyboard shortcut | |
+ * (if any) is added to "accel_group". "Answer" gives the identifier | |
+ * passed to FightCallback, above. | |
+ */ | |
+static GtkWidget *AddFightButton(gchar *Text, GtkAccelGroup *accel_group, | |
+ GtkBox *box, gint Answer) | |
+{ | |
+ GtkWidget *button; | |
+ | |
+ button = gtk_button_new_with_label(""); | |
+ SetAccelerator(button, Text, button, "clicked", accel_group); | |
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
+ GTK_SIGNAL_FUNC(FightCallback), | |
+ GINT_TO_POINTER(Answer)); | |
+ gtk_box_pack_start(box, button, TRUE, TRUE, 0); | |
+ return button; | |
+} | |
+ | |
+/* Data used to keep track of the widgets giving the information about a | |
+ * player/cop involved in a fight */ | |
+struct combatant { | |
+ GtkWidget *name, *bitches, *healthprog, *healthlabel; | |
+}; | |
+ | |
+/* | |
+ * Creates an empty Fight dialog. Usually this only needs to be done once, | |
+ * as when the user "closes" it, it is only hidden, ready to be reshown | |
+ * later. Buttons for all actions are added here, and are hidden/shown | |
+ * as necessary. | |
+ */ | |
+static void CreateFightDialog(void) | |
+{ | |
+ GtkWidget *dialog, *vbox, *button, *hbox, *hbbox, *hsep, *text, *table; | |
+ GtkAccelGroup *accel_group; | |
+ GArray *combatants; | |
+ gchar *buf; | |
+ | |
+ FightDialog = dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300); | |
+ gtk_signal_connect(GTK_OBJECT(dialog), "delete_event", | |
+ GTK_SIGNAL_FUNC(DisallowDelete), NULL); | |
+ gtk_window_set_default_size(GTK_WINDOW(dialog), 240, 130); | |
+ accel_group = gtk_accel_group_new(); | |
+ gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group); | |
+ gtk_window_set_title(GTK_WINDOW(dialog), _("Fight")); | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
+ | |
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ | |
+ vbox = gtk_vbox_new(FALSE, 7); | |
+ | |
+ table = gtk_table_new(2, 4, FALSE); | |
+ gtk_table_set_row_spacings(GTK_TABLE(table), 5); | |
+ gtk_table_set_col_spacings(GTK_TABLE(table), 5); | |
+ | |
+ hsep = gtk_hseparator_new(); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), hsep, 0, 4, 1, 2); | |
+ gtk_widget_show_all(table); | |
+ gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); | |
+ gtk_object_set_data(GTK_OBJECT(dialog), "table", table); | |
+ | |
+ combatants = g_array_new(FALSE, TRUE, sizeof(struct combatant)); | |
+ g_array_set_size(combatants, 1); | |
+ gtk_object_set_data(GTK_OBJECT(dialog), "combatants", combatants); | |
+ | |
+ text = gtk_scrolled_text_new(NULL, NULL, &hbox); | |
+ gtk_widget_set_usize(text, 150, 120); | |
+ | |
+ gtk_text_set_editable(GTK_TEXT(text), FALSE); | |
+ gtk_text_set_word_wrap(GTK_TEXT(text), TRUE); | |
+ gtk_object_set_data(GTK_OBJECT(dialog), "text", text); | |
+ gtk_widget_show_all(hbox); | |
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); | |
+ | |
+ hsep = gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
+ gtk_widget_show(hsep); | |
+ | |
+ hbbox = gtk_hbutton_box_new(); | |
+ | |
+ /* Button for closing the "Fight" dialog and going back to dealing drugs | |
+ * (%Tde = "Drugs" by default) */ | |
+ buf = dpg_strdup_printf(_("_Deal %Tde"), Names.Drugs); | |
+ button = AddFightButton(buf, accel_group, GTK_BOX(hbbox), 'D'); | |
+ gtk_object_set_data(GTK_OBJECT(dialog), "deal", button); | |
+ g_free(buf); | |
+ | |
+ /* Button for shooting at other players in the "Fight" dialog, or for | |
+ * popping up the "Fight" dialog from the main window */ | |
+ button = AddFightButton(_("_Fight"), accel_group, GTK_BOX(hbbox), 'F'); | |
+ gtk_object_set_data(GTK_OBJECT(dialog), "fight", button); | |
+ | |
+ /* Button to stand and take it in the "Fight" dialog */ | |
+ button = AddFightButton(_("_Stand"), accel_group, GTK_BOX(hbbox), 'S'); | |
+ gtk_object_set_data(GTK_OBJECT(dialog), "stand", button); | |
+ | |
+ /* Button to run from combat in the "Fight" dialog */ | |
+ button = AddFightButton(_("_Run"), accel_group, GTK_BOX(hbbox), 'R'); | |
+ gtk_object_set_data(GTK_OBJECT(dialog), "run", button); | |
+ | |
+ gtk_widget_show(hsep); | |
+ gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0); | |
+ gtk_widget_show(hbbox); | |
+ gtk_widget_show(vbox); | |
+ gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
+ gtk_widget_show(dialog); | |
+} | |
+ | |
+/* | |
+ * Updates the display of information for a player/cop in the Fight dialog. | |
+ * If the player's name (DefendName) already exists, updates the display of | |
+ * total health and number of bitches - otherwise, adds a new entry. If | |
+ * DefendBitches is -1, then the player has left. | |
+ */ | |
+static void UpdateCombatant(gchar *DefendName, int DefendBitches, | |
+ gchar *BitchName, int DefendHealth) | |
+{ | |
+ guint i, RowIndex; | |
+ gchar *name; | |
+ struct combatant *compt; | |
+ GArray *combatants; | |
+ GtkWidget *table; | |
+ gchar *BitchText, *HealthText; | |
+ gfloat ProgPercent; | |
+ | |
+ combatants = (GArray *)gtk_object_get_data(GTK_OBJECT(FightDialog), | |
+ "combatants"); | |
+ table = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "table")); | |
+ if (!combatants) | |
+ return; | |
+ | |
+ if (DefendName[0]) { | |
+ compt = NULL; | |
+ for (i = 1, RowIndex = 2; i < combatants->len; i++, RowIndex++) { | |
+ compt = &g_array_index(combatants, struct combatant, i); | |
+ | |
+ if (!compt || !compt->name) { | |
+ compt = NULL; | |
+ continue; | |
+ } | |
+ gtk_label_get(GTK_LABEL(compt->name), &name); | |
+ if (name && strcmp(name, DefendName) == 0) | |
+ break; | |
+ compt = NULL; | |
+ } | |
+ if (!compt) { | |
+ i = combatants->len; | |
+ g_array_set_size(combatants, i + 1); | |
+ compt = &g_array_index(combatants, struct combatant, i); | |
+ | |
+ gtk_table_resize(GTK_TABLE(table), i + 2, 4); | |
+ RowIndex = i + 1; | |
+ } | |
+ } else { | |
+ compt = &g_array_index(combatants, struct combatant, 0); | |
+ | |
+ RowIndex = 0; | |
+ } | |
+ | |
+ /* Display of number of bitches or deputies during combat | |
+ * (%tde="bitches" or "deputies" (etc.) by default) */ | |
+ BitchText = dpg_strdup_printf(_("%/Combat: Bitches/%d %tde"), | |
+ DefendBitches, BitchName); | |
+ | |
+ /* Display of health during combat */ | |
+ if (DefendBitches == -1) { | |
+ HealthText = g_strdup(_("(Left)")); | |
+ } else if (DefendHealth == 0 && DefendBitches == 0) { | |
+ HealthText = g_strdup(_("(Dead)")); | |
+ } else { | |
+ HealthText = g_strdup_printf(_("Health: %d"), DefendHealth); | |
+ } | |
+ | |
+ ProgPercent = (gfloat)DefendHealth / 100.0; | |
+ | |
+ if (compt->name) { | |
+ if (DefendName[0]) { | |
+ gtk_label_set_text(GTK_LABEL(compt->name), DefendName); | |
+ } | |
+ if (DefendBitches >= 0) { | |
+ gtk_label_set_text(GTK_LABEL(compt->bitches), BitchText); | |
+ } | |
+ gtk_label_set_text(GTK_LABEL(compt->healthlabel), HealthText); | |
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(compt->healthprog), | |
+ ProgPercent); | |
+ } else { | |
+ /* Display of the current player's name during combat */ | |
+ compt->name = gtk_label_new(DefendName[0] ? DefendName : _("You")); | |
+ | |
+ gtk_table_attach_defaults(GTK_TABLE(table), compt->name, 0, 1, | |
+ RowIndex, RowIndex + 1); | |
+ compt->bitches = gtk_label_new(DefendBitches >= 0 ? BitchText : ""); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), compt->bitches, 1, 2, | |
+ RowIndex, RowIndex + 1); | |
+ compt->healthprog = gtk_progress_bar_new(); | |
+ gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(compt->healthprog), | |
+ GTK_PROGRESS_LEFT_TO_RIGHT); | |
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(compt->healthprog), | |
+ ProgPercent); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), compt->healthprog, 2, 3, | |
+ RowIndex, RowIndex + 1); | |
+ compt->healthlabel = gtk_label_new(HealthText); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), compt->healthlabel, 3, 4, | |
+ RowIndex, RowIndex + 1); | |
+ gtk_widget_show(compt->name); | |
+ gtk_widget_show(compt->bitches); | |
+ gtk_widget_show(compt->healthprog); | |
+ gtk_widget_show(compt->healthlabel); | |
+ } | |
+ | |
+ g_free(BitchText); | |
+ g_free(HealthText); | |
+} | |
+ | |
+/* | |
+ * Cleans up the list of all players/cops involved in a fight. | |
+ */ | |
+static void FreeCombatants(void) | |
+{ | |
+ GArray *combatants; | |
+ | |
+ combatants = (GArray *)gtk_object_get_data(GTK_OBJECT(FightDialog), | |
+ "combatants"); | |
+ if (!combatants) | |
+ return; | |
+ | |
+ g_array_free(combatants, TRUE); | |
+} | |
+ | |
+/* | |
+ * Given the network message "Data" concerning some happening during | |
+ * combat, extracts the relevant data and updates the Fight dialog, | |
+ * creating and/or showing it if necessary. | |
+ * If "Data" is NULL, then closes the dialog. If "Data" is a blank | |
+ * string, then just shows the dialog, displaying no new messages. | |
+ */ | |
+void DisplayFightMessage(char *Data) | |
+{ | |
+ Player *Play; | |
+ gint EditPos; | |
+ GtkAccelGroup *accel_group; | |
+ GtkWidget *Deal, *Fight, *Stand, *Run, *Text; | |
+ char cr[] = "\n"; | |
+ gchar *AttackName, *DefendName, *BitchName, *Message; | |
+ FightPoint fp; | |
+ int DefendHealth, DefendBitches, BitchesKilled, ArmPercent; | |
+ gboolean CanRunHere, Loot, CanFire; | |
+ | |
+ if (!Data) { | |
+ if (FightDialog) { | |
+ FreeCombatants(); | |
+ gtk_widget_destroy(FightDialog); | |
+ FightDialog = NULL; | |
+ } | |
+ return; | |
+ } | |
+ if (FightDialog) { | |
+ if (!GTK_WIDGET_VISIBLE(FightDialog)) | |
+ gtk_widget_show(FightDialog); | |
+ } else { | |
+ CreateFightDialog(); | |
+ } | |
+ if (!FightDialog || !Data[0]) | |
+ return; | |
+ | |
+ Deal = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "deal")); | |
+ Fight = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "fight")); | |
+ Stand = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "stand")); | |
+ Run = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "run")); | |
+ Text = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog), "text")); | |
+ | |
+ Play = ClientData.Play; | |
+ | |
+ if (HaveAbility(Play, A_NEWFIGHT)) { | |
+ ReceiveFightMessage(Data, &AttackName, &DefendName, &DefendHealth, | |
+ &DefendBitches, &BitchName, &BitchesKilled, | |
+ &ArmPercent, &fp, &CanRunHere, &Loot, &CanFire, | |
+ &Message); | |
+ Play->Flags |= FIGHTING; | |
+ switch (fp) { | |
+ case F_HIT: | |
+ case F_ARRIVED: | |
+ case F_MISS: | |
+ UpdateCombatant(DefendName, DefendBitches, BitchName, DefendHealth); | |
+ break; | |
+ case F_LEAVE: | |
+ if (AttackName[0]) { | |
+ UpdateCombatant(AttackName, -1, BitchName, 0); | |
+ } | |
+ break; | |
+ case F_LASTLEAVE: | |
+ Play->Flags &= ~FIGHTING; | |
+ break; | |
+ default: | |
+ } | |
+ accel_group = (GtkAccelGroup *) | |
+ gtk_object_get_data(GTK_OBJECT(ClientData.window), "accel_group"); | |
+ SetJetButtonTitle(accel_group); | |
+ } else { | |
+ Message = Data; | |
+ if (Play->Flags & FIGHTING) | |
+ fp = F_MSG; | |
+ else | |
+ fp = F_LASTLEAVE; | |
+ CanFire = (Play->Flags & CANSHOOT); | |
+ CanRunHere = FALSE; | |
+ } | |
+ gtk_object_set_data(GTK_OBJECT(FightDialog), "CanRunHere", | |
+ GINT_TO_POINTER(CanRunHere)); | |
+ | |
+ g_strdelimit(Message, "^", '\n'); | |
+ if (strlen(Message) > 0) { | |
+ EditPos = gtk_text_get_length(GTK_TEXT(Text)); | |
+ gtk_editable_insert_text(GTK_EDITABLE(Text), Message, | |
+ strlen(Message), &EditPos); | |
+ gtk_editable_insert_text(GTK_EDITABLE(Text), cr, strlen(cr), &EditPos); | |
+ } | |
+ | |
+ if (!CanRunHere || fp == F_LASTLEAVE) | |
+ gtk_widget_show(Deal); | |
+ else | |
+ gtk_widget_hide(Deal); | |
+ if (CanFire && TotalGunsCarried(Play) > 0) | |
+ gtk_widget_show(Fight); | |
+ else | |
+ gtk_widget_hide(Fight); | |
+ if (CanFire && TotalGunsCarried(Play) == 0) | |
+ gtk_widget_show(Stand); | |
+ else | |
+ gtk_widget_hide(Stand); | |
+ if (fp != F_LASTLEAVE) | |
+ gtk_widget_show(Run); | |
+ else | |
+ gtk_widget_hide(Run); | |
+} | |
+ | |
+/* | |
+ * Updates the display of pertinent data about player "Play" (location, | |
+ * health, etc. in the status widgets given by "Status". This can point | |
+ * to the widgets at the top of the main window, or those in a Spy | |
+ * Reports dialog. | |
+ */ | |
+void DisplayStats(Player *Play, struct StatusWidgets *Status) | |
+{ | |
+ gchar *prstr; | |
+ GString *text; | |
+ | |
+ text = g_string_new(NULL); | |
+ | |
+ gtk_label_set_text(GTK_LABEL(Status->Location), | |
+ Location[(int)Play->IsAt].Name); | |
+ | |
+ g_string_sprintf(text, "%s%02d%s", Names.Month, Play->Turn, Names.Year); | |
+ gtk_label_set_text(GTK_LABEL(Status->Date), text->str); | |
+ | |
+ g_string_sprintf(text, "%d", Play->CoatSize); | |
+ gtk_label_set_text(GTK_LABEL(Status->SpaceValue), text->str); | |
+ | |
+ prstr = FormatPrice(Play->Cash); | |
+ gtk_label_set_text(GTK_LABEL(Status->CashValue), prstr); | |
+ g_free(prstr); | |
+ | |
+ prstr = FormatPrice(Play->Bank); | |
+ gtk_label_set_text(GTK_LABEL(Status->BankValue), prstr); | |
+ g_free(prstr); | |
+ | |
+ prstr = FormatPrice(Play->Debt); | |
+ gtk_label_set_text(GTK_LABEL(Status->DebtValue), prstr); | |
+ g_free(prstr); | |
+ | |
+ /* Display of carried guns in GTK+ client status window (%Tde="Guns" by | |
+ * default) */ | |
+ dpg_string_sprintf(text, _("%/GTK Stats: Guns/%Tde"), Names.Guns); | |
+ gtk_label_set_text(GTK_LABEL(Status->GunsName), text->str); | |
+ g_string_sprintf(text, "%d", TotalGunsCarried(Play)); | |
+ gtk_label_set_text(GTK_LABEL(Status->GunsValue), text->str); | |
+ | |
+ if (!WantAntique) { | |
+ /* Display of number of bitches in GTK+ client status window | |
+ * (%Tde="Bitches" by default) */ | |
+ dpg_string_sprintf(text, _("%/GTK Stats: Bitches/%Tde"), | |
+ Names.Bitches); | |
+ gtk_label_set_text(GTK_LABEL(Status->BitchesName), text->str); | |
+ g_string_sprintf(text, "%d", Play->Bitches.Carried); | |
+ gtk_label_set_text(GTK_LABEL(Status->BitchesValue), text->str); | |
+ } else { | |
+ gtk_label_set_text(GTK_LABEL(Status->BitchesName), NULL); | |
+ gtk_label_set_text(GTK_LABEL(Status->BitchesValue), NULL); | |
+ } | |
+ | |
+ g_string_sprintf(text, "%d", Play->Health); | |
+ gtk_label_set_text(GTK_LABEL(Status->HealthValue), text->str); | |
+ | |
+ g_string_free(text, TRUE); | |
+} | |
+ | |
+/* | |
+ * Updates all of the player status in response to a message from the | |
+ * server. This includes the main window display, the gun shop (if | |
+ * displayed) and the inventory (if displayed). | |
+ */ | |
+void UpdateStatus(Player *Play) | |
+{ | |
+ GtkAccelGroup *accel_group; | |
+ | |
+ DisplayStats(Play, &ClientData.Status); | |
+ UpdateInventory(&ClientData.Drug, ClientData.Play->Drugs, NumDrug, TRUE); | |
+ gtk_clist_sort(GTK_CLIST(ClientData.Drug.HereList)); | |
+ accel_group = (GtkAccelGroup *) | |
+ gtk_object_get_data(GTK_OBJECT(ClientData.window), "accel_group"); | |
+ SetJetButtonTitle(accel_group); | |
+ if (IsShowingGunShop) { | |
+ UpdateInventory(&ClientData.Gun, ClientData.Play->Guns, NumGun, FALSE); | |
+ } | |
+ if (IsShowingInventory) { | |
+ UpdateInventory(&ClientData.InvenDrug, ClientData.Play->Drugs, | |
+ NumDrug, TRUE); | |
+ UpdateInventory(&ClientData.InvenGun, ClientData.Play->Guns, | |
+ NumGun, FALSE); | |
+ } | |
+} | |
+ | |
+void UpdateInventory(struct InventoryWidgets *Inven, | |
+ Inventory *Objects, int NumObjects, gboolean AreDrugs) | |
+{ | |
+ GtkWidget *herelist, *carrylist; | |
+ Player *Play; | |
+ gint i, row, selectrow[2]; | |
+ gpointer rowdata; | |
+ price_t price; | |
+ gchar *titles[2]; | |
+ gboolean CanBuy = FALSE, CanSell = FALSE, CanDrop = FALSE; | |
+ GList *glist[2], *selection; | |
+ GtkCList *clist[2]; | |
+ int numlist; | |
+ | |
+ Play = ClientData.Play; | |
+ herelist = Inven->HereList; | |
+ carrylist = Inven->CarriedList; | |
+ | |
+ if (herelist) | |
+ numlist = 2; | |
+ else | |
+ numlist = 1; | |
+ | |
+ /* Make lists of the current selections */ | |
+ clist[0] = GTK_CLIST(carrylist); | |
+ if (herelist) | |
+ clist[1] = GTK_CLIST(herelist); | |
+ else | |
+ clist[1] = NULL; | |
+ | |
+ for (i = 0; i < numlist; i++) { | |
+ glist[i] = NULL; | |
+ selectrow[i] = -1; | |
+ for (selection = clist[i]->selection; selection; | |
+ selection = g_list_next(selection)) { | |
+ row = GPOINTER_TO_INT(selection->data); | |
+ rowdata = gtk_clist_get_row_data(clist[i], row); | |
+ glist[i] = g_list_append(glist[i], rowdata); | |
+ } | |
+ } | |
+ | |
+ gtk_clist_freeze(GTK_CLIST(carrylist)); | |
+ gtk_clist_clear(GTK_CLIST(carrylist)); | |
+ | |
+ if (herelist) { | |
+ gtk_clist_freeze(GTK_CLIST(herelist)); | |
+ gtk_clist_clear(GTK_CLIST(herelist)); | |
+ } | |
+ | |
+ for (i = 0; i < NumObjects; i++) { | |
+ if (AreDrugs) { | |
+ titles[0] = Drug[i].Name; | |
+ price = Objects[i].Price; | |
+ } else { | |
+ titles[0] = Gun[i].Name; | |
+ price = Gun[i].Price; | |
+ } | |
+ | |
+ if (herelist && price > 0) { | |
+ CanBuy = TRUE; | |
+ titles[1] = FormatPrice(price); | |
+ row = gtk_clist_append(GTK_CLIST(herelist), titles); | |
+ g_free(titles[1]); | |
+ gtk_clist_set_row_data(GTK_CLIST(herelist), row, GINT_TO_POINTER(i)); | |
+ if (g_list_find(glist[1], GINT_TO_POINTER(i))) { | |
+ selectrow[1] = row; | |
+ gtk_clist_select_row(GTK_CLIST(herelist), row, 0); | |
+ } | |
+ } | |
+ | |
+ if (Objects[i].Carried > 0) { | |
+ if (price > 0) | |
+ CanSell = TRUE; | |
+ else | |
+ CanDrop = TRUE; | |
+ if (HaveAbility(ClientData.Play, A_DRUGVALUE) && AreDrugs) { | |
+ titles[1] = dpg_strdup_printf("%d @ %P", Objects[i].Carried, | |
+ Objects[i].TotalValue / | |
+ Objects[i].Carried); | |
+ } else { | |
+ titles[1] = g_strdup_printf("%d", Objects[i].Carried); | |
+ } | |
+ row = gtk_clist_append(GTK_CLIST(carrylist), titles); | |
+ g_free(titles[1]); | |
+ gtk_clist_set_row_data(GTK_CLIST(carrylist), row, | |
+ GINT_TO_POINTER(i)); | |
+ if (g_list_find(glist[0], GINT_TO_POINTER(i))) { | |
+ selectrow[0] = row; | |
+ gtk_clist_select_row(GTK_CLIST(carrylist), row, 0); | |
+ } | |
+ } | |
+ } | |
+ | |
+ for (i = 0; i < numlist; i++) { | |
+ if (selectrow[i] != -1 && gtk_clist_row_is_visible(clist[i], | |
+ selectrow[i]) != | |
+ GTK_VISIBILITY_FULL) { | |
+ gtk_clist_moveto(clist[i], selectrow[i], 0, 0.0, 0.0); | |
+ } | |
+ g_list_free(glist[i]); | |
+ } | |
+ | |
+ gtk_clist_thaw(GTK_CLIST(carrylist)); | |
+ if (herelist) | |
+ gtk_clist_thaw(GTK_CLIST(herelist)); | |
+ | |
+ if (Inven->vbbox) { | |
+ gtk_widget_set_sensitive(Inven->BuyButton, CanBuy); | |
+ gtk_widget_set_sensitive(Inven->SellButton, CanSell); | |
+ gtk_widget_set_sensitive(Inven->DropButton, CanDrop); | |
+ } | |
+} | |
+ | |
+static void JetCallback(GtkWidget *widget, gpointer data) | |
+{ | |
+ int NewLocation; | |
+ gchar *text; | |
+ GtkWidget *JetDialog; | |
+ | |
+ JetDialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "dialog")); | |
+ NewLocation = GPOINTER_TO_INT(data); | |
+ gtk_widget_destroy(JetDialog); | |
+ text = g_strdup_printf("%d", NewLocation); | |
+ SendClientMessage(ClientData.Play, C_NONE, C_REQUESTJET, NULL, text); | |
+ g_free(text); | |
+} | |
+ | |
+void JetButtonPressed(GtkWidget *widget, gpointer data) | |
+{ | |
+ if (InGame) { | |
+ if (ClientData.Play->Flags & FIGHTING) { | |
+ DisplayFightMessage(NULL); | |
+ } else { | |
+ Jet(NULL); | |
+ } | |
+ } | |
+} | |
+ | |
+void Jet(GtkWidget *parent) | |
+{ | |
+ GtkWidget *dialog, *table, *button, *label, *vbox; | |
+ GtkAccelGroup *accel_group; | |
+ gint boxsize, i, row, col; | |
+ gchar *name, AccelChar; | |
+ | |
+ accel_group = gtk_accel_group_new(); | |
+ | |
+ dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
+ /* Title of 'Jet' dialog */ | |
+ gtk_window_set_title(GTK_WINDOW(dialog), _("Jet to location")); | |
+ | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
+ gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group); | |
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ parent ? GTK_WINDOW(parent) | |
+ : GTK_WINDOW(ClientData.window)); | |
+ | |
+ vbox = gtk_vbox_new(FALSE, 7); | |
+ | |
+ /* Prompt in 'Jet' dialog */ | |
+ label = gtk_label_new(_("Where to, dude ? ")); | |
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
+ | |
+ /* Generate a square box of buttons for all locations */ | |
+ boxsize = 1; | |
+ while (boxsize * boxsize < NumLocation) | |
+ boxsize++; | |
+ col = boxsize; | |
+ row = 1; | |
+ | |
+ /* Avoid creating a box with an entire row empty at the bottom */ | |
+ while (row * col < NumLocation) | |
+ row++; | |
+ | |
+ table = gtk_table_new(row, col, TRUE); | |
+ | |
+ for (i = 0; i < NumLocation; i++) { | |
+ if (i < 9) | |
+ AccelChar = '1' + i; | |
+ else if (i < 35) | |
+ AccelChar = 'A' + i - 9; | |
+ else | |
+ AccelChar = '\0'; | |
+ | |
+ row = i / boxsize; | |
+ col = i % boxsize; | |
+ if (AccelChar == '\0') { | |
+ button = gtk_button_new_with_label(Location[i].Name); | |
+ } else { | |
+ button = gtk_button_new_with_label(""); | |
+ | |
+ /* Display of locations in 'Jet' window (%tde="The Bronx" etc. by | |
+ * default) */ | |
+ name = dpg_strdup_printf(_("_%c. %tde"), AccelChar, Location[i].Name); | |
+ SetAccelerator(button, name, button, "clicked", accel_group); | |
+ /* Add keypad shortcuts as well */ | |
+ if (i < 9) { | |
+ gtk_widget_add_accelerator(button, "clicked", accel_group, | |
+ GDK_KP_1 + i, 0, | |
+ GTK_ACCEL_VISIBLE | | |
+ GTK_ACCEL_SIGNAL_VISIBLE); | |
+ } | |
+ g_free(name); | |
+ } | |
+ gtk_widget_set_sensitive(button, i != ClientData.Play->IsAt); | |
+ gtk_object_set_data(GTK_OBJECT(button), "dialog", dialog); | |
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
+ GTK_SIGNAL_FUNC(JetCallback), GINT_TO_POINTER(i)); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), button, col, col + 1, row, | |
+ row + 1); | |
+ } | |
+ gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0); | |
+ | |
+ gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
+ gtk_widget_show_all(dialog); | |
+} | |
+ | |
+struct DealDiaStruct { | |
+ GtkWidget *dialog, *cost, *carrying, *space, *afford, *amount; | |
+ gint DrugInd; | |
+ gpointer Type; | |
+}; | |
+static struct DealDiaStruct DealDialog; | |
+ | |
+static void UpdateDealDialog(void) | |
+{ | |
+ GString *text; | |
+ GtkAdjustment *spin_adj; | |
+ gint DrugInd, CanDrop, CanCarry, CanAfford, MaxDrug; | |
+ Player *Play; | |
+ | |
+ text = g_string_new(NULL); | |
+ DrugInd = DealDialog.DrugInd; | |
+ Play = ClientData.Play; | |
+ | |
+ /* Display of the current price of the selected drug in 'Deal Drugs' | |
+ * dialog */ | |
+ dpg_string_sprintf(text, _("at %P"), Play->Drugs[DrugInd].Price); | |
+ gtk_label_set_text(GTK_LABEL(DealDialog.cost), text->str); | |
+ | |
+ CanDrop = Play->Drugs[DrugInd].Carried; | |
+ | |
+ /* Display of current inventory of the selected drug in 'Deal Drugs' | |
+ * dialog (%tde="Opium" etc. by default) */ | |
+ dpg_string_sprintf(text, _("You are currently carrying %d %tde"), | |
+ CanDrop, Drug[DrugInd].Name); | |
+ gtk_label_set_text(GTK_LABEL(DealDialog.carrying), text->str); | |
+ | |
+ CanCarry = Play->CoatSize; | |
+ | |
+ /* Available space for drugs in 'Deal Drugs' dialog */ | |
+ g_string_sprintf(text, _("Available space: %d"), CanCarry); | |
+ gtk_label_set_text(GTK_LABEL(DealDialog.space), text->str); | |
+ | |
+ if (DealDialog.Type == BT_BUY) { | |
+ CanAfford = Play->Cash / Play->Drugs[DrugInd].Price; | |
+ | |
+ /* Number of the selected drug that you can afford in 'Deal Drugs' | |
+ * dialog */ | |
+ g_string_sprintf(text, _("You can afford %d"), CanAfford); | |
+ gtk_label_set_text(GTK_LABEL(DealDialog.afford), text->str); | |
+ MaxDrug = MIN(CanCarry, CanAfford); | |
+ } else | |
+ MaxDrug = CanDrop; | |
+ | |
+ spin_adj = (GtkAdjustment *)gtk_adjustment_new(MaxDrug, 1.0, MaxDrug, | |
+ 1.0, 10.0, 10.0); | |
+ gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(DealDialog.amount), | |
+ spin_adj); | |
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(DealDialog.amount), MaxDrug); | |
+ | |
+ g_string_free(text, TRUE); | |
+} | |
+ | |
+static void DealSelectCallback(GtkWidget *widget, gpointer data) | |
+{ | |
+ DealDialog.DrugInd = GPOINTER_TO_INT(data); | |
+ UpdateDealDialog(); | |
+} | |
+ | |
+static void DealOKCallback(GtkWidget *widget, gpointer data) | |
+{ | |
+ GtkWidget *spinner; | |
+ gint amount; | |
+ gchar *text; | |
+ | |
+ spinner = DealDialog.amount; | |
+ | |
+ gtk_spin_button_update(GTK_SPIN_BUTTON(spinner)); | |
+ amount = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner)); | |
+ | |
+ text = g_strdup_printf("drug^%d^%d", DealDialog.DrugInd, | |
+ data == BT_BUY ? amount : -amount); | |
+ SendClientMessage(ClientData.Play, C_NONE, C_BUYOBJECT, NULL, text); | |
+ g_free(text); | |
+ | |
+ gtk_widget_destroy(DealDialog.dialog); | |
+} | |
+ | |
+void DealDrugs(GtkWidget *widget, gpointer data) | |
+{ | |
+ GtkWidget *dialog, *label, *hbox, *hbbox, *button, *spinner, *menu, | |
+ *optionmenu, *menuitem, *vbox, *hsep; | |
+ GtkAdjustment *spin_adj; | |
+ GtkAccelGroup *accel_group; | |
+ GtkWidget *clist; | |
+ gchar *Action; | |
+ GString *text; | |
+ GList *selection; | |
+ gint row; | |
+ Player *Play; | |
+ gint DrugInd, i, SelIndex, FirstInd; | |
+ gboolean DrugIndOK; | |
+ | |
+ /* Action in 'Deal Drugs' dialog - "Buy/Sell/Drop Drugs" */ | |
+ if (data == BT_BUY) | |
+ Action = _("Buy"); | |
+ else if (data == BT_SELL) | |
+ Action = _("Sell"); | |
+ else if (data == BT_DROP) | |
+ Action = _("Drop"); | |
+ else { | |
+ g_warning("Bad DealDrug type"); | |
+ return; | |
+ } | |
+ | |
+ DealDialog.Type = data; | |
+ Play = ClientData.Play; | |
+ | |
+ if (data == BT_BUY) | |
+ clist = ClientData.Drug.HereList; | |
+ else | |
+ clist = ClientData.Drug.CarriedList; | |
+ selection = GTK_CLIST(clist)->selection; | |
+ if (selection) { | |
+ row = GPOINTER_TO_INT(selection->data); | |
+ DrugInd = | |
+ GPOINTER_TO_INT(gtk_clist_get_row_data(GTK_CLIST(clist), row)); | |
+ } else | |
+ DrugInd = -1; | |
+ | |
+ DrugIndOK = FALSE; | |
+ FirstInd = -1; | |
+ for (i = 0; i < NumDrug; i++) { | |
+ if ((data == BT_DROP && Play->Drugs[i].Carried > 0 | |
+ && Play->Drugs[i].Price == 0) | |
+ || (data == BT_SELL && Play->Drugs[i].Carried > 0 | |
+ && Play->Drugs[i].Price != 0) | |
+ || (data == BT_BUY && Play->Drugs[i].Price != 0)) { | |
+ if (FirstInd == -1) | |
+ FirstInd = i; | |
+ if (DrugInd == i) | |
+ DrugIndOK = TRUE; | |
+ } | |
+ } | |
+ if (!DrugIndOK) { | |
+ if (FirstInd == -1) | |
+ return; | |
+ else | |
+ DrugInd = FirstInd; | |
+ } | |
+ | |
+ text = g_string_new(NULL); | |
+ accel_group = gtk_accel_group_new(); | |
+ dialog = DealDialog.dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_window_set_title(GTK_WINDOW(dialog), Action); | |
+ gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group); | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ | |
+ vbox = gtk_vbox_new(FALSE, 7); | |
+ | |
+ hbox = gtk_hbox_new(FALSE, 7); | |
+ | |
+ label = gtk_label_new(Action); | |
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
+ | |
+ optionmenu = gtk_option_menu_new(); | |
+ menu = gtk_menu_new(); | |
+ SelIndex = -1; | |
+ for (i = 0; i < NumDrug; i++) { | |
+ if ((data == BT_DROP && Play->Drugs[i].Carried > 0 | |
+ && Play->Drugs[i].Price == 0) | |
+ || (data == BT_SELL && Play->Drugs[i].Carried > 0 | |
+ && Play->Drugs[i].Price != 0) | |
+ || (data == BT_BUY && Play->Drugs[i].Price != 0)) { | |
+ menuitem = gtk_menu_item_new_with_label(Drug[i].Name); | |
+ gtk_signal_connect(GTK_OBJECT(menuitem), "activate", | |
+ GTK_SIGNAL_FUNC(DealSelectCallback), | |
+ GINT_TO_POINTER(i)); | |
+ gtk_menu_append(GTK_MENU(menu), menuitem); | |
+ if (DrugInd >= i) | |
+ SelIndex++; | |
+ } | |
+ } | |
+ gtk_menu_set_active(GTK_MENU(menu), SelIndex); | |
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu), menu); | |
+ gtk_box_pack_start(GTK_BOX(hbox), optionmenu, TRUE, TRUE, 0); | |
+ | |
+ DealDialog.DrugInd = DrugInd; | |
+ | |
+ label = DealDialog.cost = gtk_label_new(NULL); | |
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
+ | |
+ label = DealDialog.carrying = gtk_label_new(NULL); | |
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
+ | |
+ label = DealDialog.space = gtk_label_new(NULL); | |
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
+ | |
+ if (data == BT_BUY) { | |
+ label = DealDialog.afford = gtk_label_new(NULL); | |
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
+ } | |
+ hbox = gtk_hbox_new(FALSE, 7); | |
+ if (data == BT_BUY) { | |
+ /* Prompts for action in the "deal drugs" dialog */ | |
+ g_string_sprintf(text, _("Buy how many?")); | |
+ } else if (data == BT_SELL) { | |
+ g_string_sprintf(text, _("Sell how many?")); | |
+ } else { | |
+ g_string_sprintf(text, _("Drop how many?")); | |
+ } | |
+ label = gtk_label_new(text->str); | |
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
+ spin_adj = (GtkAdjustment *)gtk_adjustment_new(1.0, 1.0, 2.0, | |
+ 1.0, 10.0, 10.0); | |
+ spinner = DealDialog.amount = gtk_spin_button_new(spin_adj, 1.0, 0); | |
+ gtk_signal_connect(GTK_OBJECT(spinner), "activate", | |
+ GTK_SIGNAL_FUNC(DealOKCallback), data); | |
+ gtk_box_pack_start(GTK_BOX(hbox), spinner, FALSE, FALSE, 0); | |
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
+ | |
+ hsep = gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
+ | |
+ hbbox = gtk_hbutton_box_new(); | |
+ button = gtk_button_new_with_label(_("OK")); | |
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
+ GTK_SIGNAL_FUNC(DealOKCallback), data); | |
+ GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); | |
+ gtk_widget_grab_default(button); | |
+ gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
+ | |
+ /* Caption of "Cancel" button for GTK+ client dialogs */ | |
+ button = gtk_button_new_with_label(_("Cancel")); | |
+ gtk_signal_connect_object(GTK_OBJECT(button), "clicked", | |
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
+ (gpointer)dialog); | |
+ gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0); | |
+ gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
+ | |
+ g_string_free(text, TRUE); | |
+ UpdateDealDialog(); | |
+ | |
+ gtk_widget_show_all(dialog); | |
+} | |
+ | |
+void DealGuns(GtkWidget *widget, gpointer data) | |
+{ | |
+ GtkWidget *clist, *dialog; | |
+ GList *selection; | |
+ gint row, GunInd; | |
+ gchar *Action, *Title; | |
+ GString *text; | |
+ | |
+ dialog = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); | |
+ if (data == BT_BUY) | |
+ Action = _("Buy"); | |
+ else if (data == BT_SELL) | |
+ Action = _("Sell"); | |
+ else | |
+ Action = _("Drop"); | |
+ | |
+ if (data == BT_BUY) | |
+ clist = ClientData.Gun.HereList; | |
+ else | |
+ clist = ClientData.Gun.CarriedList; | |
+ selection = GTK_CLIST(clist)->selection; | |
+ if (selection) { | |
+ row = GPOINTER_TO_INT(selection->data); | |
+ GunInd = | |
+ GPOINTER_TO_INT(gtk_clist_get_row_data(GTK_CLIST(clist), row)); | |
+ } else | |
+ return; | |
+ | |
+ | |
+ /* Title of 'gun shop' dialog (%tde="guns" by default) "Buy/Sell/Drop | |
+ * Guns" */ | |
+ if (data == BT_BUY) | |
+ Title = dpg_strdup_printf(_("Buy %tde"), Names.Guns); | |
+ else if (data == BT_SELL) | |
+ Title = dpg_strdup_printf(_("Sell %tde"), Names.Guns); | |
+ else | |
+ Title = dpg_strdup_printf(_("Drop %tde"), Names.Guns); | |
+ | |
+ text = g_string_new(""); | |
+ | |
+ if (data != BT_BUY && TotalGunsCarried(ClientData.Play) == 0) { | |
+ dpg_string_sprintf(text, _("You don't have any %tde to sell!"), | |
+ Names.Guns); | |
+ GtkMessageBox(dialog, text->str, Title, MB_OK); | |
+ } else if (data == BT_BUY && TotalGunsCarried(ClientData.Play) >= | |
+ ClientData.Play->Bitches.Carried + 2) { | |
+ dpg_string_sprintf(text, | |
+ _("You'll need more %tde to carry any more %tde!"), | |
+ Names.Bitches, Names.Guns); | |
+ GtkMessageBox(dialog, text->str, Title, MB_OK); | |
+ } else if (data == BT_BUY | |
+ && Gun[GunInd].Space > ClientData.Play->CoatSize) { | |
+ dpg_string_sprintf(text, | |
+ _("You don't have enough space to carry that %tde!"), | |
+ Names.Gun); | |
+ GtkMessageBox(dialog, text->str, Title, MB_OK); | |
+ } else if (data == BT_BUY && Gun[GunInd].Price > ClientData.Play->Cash) { | |
+ dpg_string_sprintf(text, | |
+ _("You don't have enough cash to buy that %tde!"), | |
+ Names.Gun); | |
+ GtkMessageBox(dialog, text->str, Title, MB_OK); | |
+ } else if (data == BT_SELL && ClientData.Play->Guns[GunInd].Carried == 0) { | |
+ GtkMessageBox(dialog, _("You don't have any to sell!"), Title, MB_OK); | |
+ } else { | |
+ g_string_sprintf(text, "gun^%d^%d", GunInd, data == BT_BUY ? 1 : -1); | |
+ SendClientMessage(ClientData.Play, C_NONE, C_BUYOBJECT, NULL, | |
+ text->str); | |
+ } | |
+ g_free(Title); | |
+ g_string_free(text, TRUE); | |
+} | |
+ | |
+static void QuestionCallback(GtkWidget *widget, gpointer data) | |
+{ | |
+ gint Answer; | |
+ gchar text[5]; | |
+ GtkWidget *dialog; | |
+ Player *To; | |
+ | |
+ dialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "dialog")); | |
+ To = (Player *)gtk_object_get_data(GTK_OBJECT(dialog), "From"); | |
+ Answer = GPOINTER_TO_INT(data); | |
+ | |
+ text[0] = (gchar)Answer; | |
+ text[1] = '\0'; | |
+ SendClientMessage(ClientData.Play, C_NONE, C_ANSWER, To, text); | |
+ | |
+ gtk_widget_destroy(dialog); | |
+} | |
+ | |
+void QuestionDialog(char *Data, Player *From) | |
+{ | |
+ GtkWidget *dialog, *label, *vbox, *hsep, *hbbox, *button; | |
+ GtkAccelGroup *accel_group; | |
+ gchar *Responses, **split, *LabelText, *trword, *underline; | |
+ | |
+ /* Button titles that correspond to the single-keypress options provided | |
+ * by the curses client (e.g. _Yes corresponds to 'Y' etc.) */ | |
+ gchar *Words[] = { N_("_Yes"), N_("_No"), N_("_Run"), | |
+ N_("_Fight"), N_("_Attack"), N_("_Evade") | |
+ }; | |
+ gint numWords = sizeof(Words) / sizeof(Words[0]); | |
+ gint i, j; | |
+ | |
+ split = g_strsplit(Data, "^", 1); | |
+ if (!split[0] || !split[1]) { | |
+ g_warning("Bad QUESTION message %s", Data); | |
+ return; | |
+ } | |
+ | |
+ g_strdelimit(split[1], "^", '\n'); | |
+ | |
+ Responses = split[0]; | |
+ LabelText = split[1]; | |
+ | |
+ dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
+ accel_group = gtk_accel_group_new(); | |
+ gtk_signal_connect(GTK_OBJECT(dialog), "delete_event", | |
+ GTK_SIGNAL_FUNC(DisallowDelete), NULL); | |
+ gtk_object_set_data(GTK_OBJECT(dialog), "From", (gpointer)From); | |
+ | |
+ /* Title of the 'ask player a question' dialog */ | |
+ gtk_window_set_title(GTK_WINDOW(dialog), _("Question")); | |
+ | |
+ gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group); | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); | |
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ | |
+ vbox = gtk_vbox_new(FALSE, 7); | |
+ while (*LabelText == '\n') | |
+ LabelText++; | |
+ label = gtk_label_new(LabelText); | |
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
+ | |
+ hsep = gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); | |
+ | |
+ hbbox = gtk_hbutton_box_new(); | |
+ | |
+ for (i = 0; i < strlen(Responses); i++) { | |
+ for (j = 0, trword = NULL; j < numWords && !trword; j++) { | |
+ underline = strchr(Words[j], '_'); | |
+ if (underline && toupper(underline[1]) == Responses[i]) { | |
+ trword = _(Words[j]); | |
+ } | |
+ } | |
+ button = gtk_button_new_with_label(""); | |
+ if (trword) { | |
+ SetAccelerator(button, trword, button, "clicked", accel_group); | |
+ } else { | |
+ trword = g_strdup_printf("_%c", Responses[i]); | |
+ SetAccelerator(button, trword, button, "clicked", accel_group); | |
+ g_free(trword); | |
+ } | |
+ gtk_object_set_data(GTK_OBJECT(button), "dialog", (gpointer)dialog); | |
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
+ GTK_SIGNAL_FUNC(QuestionCallback), | |
+ GINT_TO_POINTER((gint)Responses[i])); | |
+ gtk_box_pack_start(GTK_BOX(hbbox), button, TRUE, TRUE, 0); | |
+ } | |
+ gtk_box_pack_start(GTK_BOX(vbox), hbbox, TRUE, TRUE, 0); | |
+ gtk_container_add(GTK_CONTAINER(dialog), vbox); | |
+ gtk_widget_show_all(dialog); | |
+ | |
+ g_strfreev(split); | |
+} | |
+ | |
+void StartGame(void) | |
+{ | |
+ Player *Play = ClientData.Play; | |
+ | |
+ InitAbilities(Play); | |
+ SendAbilities(Play); | |
+ SendNullClientMessage(Play, C_NONE, C_NAME, NULL, GetPlayerName(Play)); | |
+ InGame = TRUE; | |
+ UpdateMenus(); | |
+ gtk_widget_show_all(ClientData.vbox); | |
+ UpdatePlayerLists(); | |
+} | |
+ | |
+void EndGame(void) | |
+{ | |
+ DisplayFightMessage(NULL); | |
+ gtk_widget_hide_all(ClientData.vbox); | |
+ gtk_editable_delete_text(GTK_EDITABLE(ClientData.messages), 0, -1); | |
+ ShutdownNetwork(ClientData.Play); | |
+ UpdatePlayerLists(); | |
+ CleanUpServer(); | |
+ RestoreConfig(); | |
+ InGame = FALSE; | |
+ UpdateMenus(); | |
+} | |
+ | |
+static void ChangeDrugSort(GtkCList *clist, gint column, | |
+ gpointer user_data) | |
+{ | |
+ if (column == 0) { | |
+ DrugSortMethod = (DrugSortMethod == DS_ATOZ ? DS_ZTOA : DS_ATOZ); | |
+ } else { | |
+ DrugSortMethod = (DrugSortMethod == DS_CHEAPFIRST ? DS_CHEAPLAST : | |
+ DS_CHEAPFIRST); | |
+ } | |
+ gtk_clist_sort(clist); | |
+} | |
+ | |
+static gint DrugSortFunc(GtkCList *clist, gconstpointer ptr1, | |
+ gconstpointer ptr2) | |
+{ | |
+ int index1, index2; | |
+ price_t pricediff; | |
+ | |
+ index1 = GPOINTER_TO_INT(((const GtkCListRow *)ptr1)->data); | |
+ index2 = GPOINTER_TO_INT(((const GtkCListRow *)ptr2)->data); | |
+ if (index1 < 0 || index1 >= NumDrug || index2 < 0 || index2 >= NumDrug) | |
+ return 0; | |
+ | |
+ switch (DrugSortMethod) { | |
+ case DS_ATOZ: | |
+ return g_strcasecmp(Drug[index1].Name, Drug[index2].Name); | |
+ case DS_ZTOA: | |
+ return g_strcasecmp(Drug[index2].Name, Drug[index1].Name); | |
+ case DS_CHEAPFIRST: | |
+ pricediff = ClientData.Play->Drugs[index1].Price - | |
+ ClientData.Play->Drugs[index2].Price; | |
+ return pricediff == 0 ? 0 : pricediff < 0 ? -1 : 1; | |
+ case DS_CHEAPLAST: | |
+ pricediff = ClientData.Play->Drugs[index2].Price - | |
+ ClientData.Play->Drugs[index1].Price; | |
+ return pricediff == 0 ? 0 : pricediff < 0 ? -1 : 1; | |
+ } | |
+ return 0; | |
+} | |
+ | |
+void UpdateMenus(void) | |
+{ | |
+ gboolean MultiPlayer; | |
+ gint Bitches; | |
+ | |
+ MultiPlayer = (FirstClient && FirstClient->next != NULL); | |
+ Bitches = InGame | |
+ && ClientData.Play ? ClientData.Play->Bitches.Carried : 0; | |
+ | |
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget(ClientData.Menu, | |
+ "<main>/Talk"), | |
+ InGame && Network); | |
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
+ (ClientData.Menu, "<main>/List"), InGame); | |
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
+ (ClientData.Menu, "<main>/List/Players..."), | |
+ InGame && Network); | |
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
+ (ClientData.Menu, "<main>/Errands"), InGame); | |
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
+ (ClientData.Menu, "<main>/Errands/Spy..."), | |
+ InGame && MultiPlayer); | |
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
+ (ClientData.Menu, "<main>/Errands/Tipoff..."), | |
+ InGame && MultiPlayer); | |
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
+ (ClientData.Menu, | |
+ "<main>/Errands/Sack Bitch..."), Bitches > 0); | |
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget | |
+ (ClientData.Menu, | |
+ "<main>/Errands/Get spy reports..."), InGame | |
+ && MultiPlayer); | |
+} | |
+ | |
+GtkWidget *CreateStatusWidgets(struct StatusWidgets *Status) | |
+{ | |
+ GtkWidget *table, *label; | |
+ | |
+ table = gtk_table_new(3, 6, FALSE); | |
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3); | |
+ gtk_table_set_col_spacings(GTK_TABLE(table), 3); | |
+ | |
+ label = Status->Location = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 2, 0, 1); | |
+ | |
+ label = Status->Date = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 4, 0, 1); | |
+ | |
+ /* Available space label in GTK+ client status display */ | |
+ label = Status->SpaceName = gtk_label_new(_("Space")); | |
+ | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 4, 5, 0, 1); | |
+ label = Status->SpaceValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 0, 1); | |
+ | |
+ /* Player's cash label in GTK+ client status display */ | |
+ label = Status->CashName = gtk_label_new(_("Cash")); | |
+ | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); | |
+ label = Status->CashValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 1, 2); | |
+ | |
+ /* Player's debt label in GTK+ client status display */ | |
+ label = Status->DebtName = gtk_label_new(_("Debt")); | |
+ | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 1, 2); | |
+ label = Status->DebtValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, 1, 2); | |
+ | |
+ /* Player's bank balance label in GTK+ client status display */ | |
+ label = Status->BankName = gtk_label_new(_("Bank")); | |
+ | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 4, 5, 1, 2); | |
+ label = Status->BankValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 1, 2); | |
+ | |
+ label = Status->GunsName = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); | |
+ label = Status->GunsValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 2, 3); | |
+ | |
+ label = Status->BitchesName = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 2, 3); | |
+ label = Status->BitchesValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, 2, 3); | |
+ | |
+ /* Player's health label in GTK+ client status display */ | |
+ label = Status->HealthName = gtk_label_new(_("Health")); | |
+ | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 4, 5, 2, 3); | |
+ label = Status->HealthValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 2, 3); | |
+ return table; | |
+} | |
+ | |
+void SetJetButtonTitle(GtkAccelGroup *accel_group) | |
+{ | |
+ GtkWidget *button; | |
+ guint accel_key; | |
+ | |
+ button = ClientData.JetButton; | |
+ accel_key = ClientData.JetAccel; | |
+ | |
+ if (accel_key) { | |
+ gtk_widget_remove_accelerator(button, accel_group, accel_key, 0); | |
+ } | |
+ | |
+ ClientData.JetAccel = SetAccelerator(button, | |
+ (ClientData.Play | |
+ && ClientData.Play-> | |
+ Flags & FIGHTING) ? _("_Fight") : | |
+ /* Caption of 'Jet' button in main | |
+ * window */ | |
+ _("_Jet!"), button, "clicked", | |
+ accel_group); | |
+} | |
+ | |
+static void SetIcon(GtkWidget *window, gchar **xpmdata) | |
+{ | |
+#ifndef CYGWIN | |
+ GdkBitmap *mask; | |
+ GdkPixmap *icon; | |
+ GtkStyle *style; | |
+ | |
+ style = gtk_widget_get_style(window); | |
+ icon = gdk_pixmap_create_from_xpm_d(window->window, &mask, | |
+ &style->bg[GTK_STATE_NORMAL], | |
+ xpmdata); | |
+ gdk_window_set_icon(window->window, NULL, icon, mask); | |
+#endif | |
+} | |
+ | |
+#ifdef CYGWIN | |
+gboolean GtkLoop(HINSTANCE hInstance, HINSTANCE hPrevInstance, | |
+ gboolean ReturnOnFail) | |
+{ | |
+#else | |
+gboolean GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail) | |
+{ | |
+#endif | |
+ GtkWidget *window, *vbox, *vbox2, *hbox, *frame, *table, *menubar, *text, | |
+ *vpaned, *button, *clist; | |
+ GtkAccelGroup *accel_group; | |
+ GtkItemFactory *item_factory; | |
+ GtkAdjustment *adj; | |
+ gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]); | |
+ | |
+#ifdef CYGWIN | |
+ win32_init(hInstance, hPrevInstance, "mainicon"); | |
+#else | |
+ gtk_set_locale(); | |
+ if (ReturnOnFail && !gtk_init_check(argc, argv)) | |
+ return FALSE; | |
+ else if (!ReturnOnFail) | |
+ gtk_init(argc, argv); | |
+#endif | |
+ | |
+ /* Set up message handlers */ | |
+ ClientMessageHandlerPt = HandleClientMessage; | |
+ | |
+ /* Have the GLib log messages pop up in a nice dialog box */ | |
+ g_log_set_handler(NULL, | |
+ LogMask() | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING | | |
+ G_LOG_LEVEL_CRITICAL, LogMessage, NULL); | |
+ | |
+ if (!CheckHighScoreFileConfig()) | |
+ return TRUE; | |
+ | |
+ /* Create the main player */ | |
+ ClientData.Play = g_new(Player, 1); | |
+ FirstClient = AddPlayer(0, ClientData.Play, FirstClient); | |
+ | |
+ window = MainWindow = ClientData.window = gtk_window_new(GTK_WINDOW_TOPLEVEL… | |
+ | |
+ /* Title of main window in GTK+ client */ | |
+ gtk_window_set_title(GTK_WINDOW(window), _("dopewars")); | |
+ gtk_window_set_default_size(GTK_WINDOW(window), 450, 390); | |
+ gtk_signal_connect(GTK_OBJECT(window), "delete_event", | |
+ GTK_SIGNAL_FUNC(MainDelete), NULL); | |
+ gtk_signal_connect(GTK_OBJECT(window), "destroy", | |
+ GTK_SIGNAL_FUNC(DestroyGtk), NULL); | |
+ | |
+ accel_group = gtk_accel_group_new(); | |
+ gtk_object_set_data(GTK_OBJECT(window), "accel_group", accel_group); | |
+ item_factory = ClientData.Menu = gtk_item_factory_new(GTK_TYPE_MENU_BAR, | |
+ "<main>", | |
+ accel_group); | |
+ gtk_item_factory_set_translate_func(item_factory, MenuTranslate, NULL, | |
+ NULL); | |
+ | |
+ gtk_item_factory_create_items(item_factory, nmenu_items, menu_items, | |
+ NULL); | |
+ gtk_window_add_accel_group(GTK_WINDOW(window), accel_group); | |
+ menubar = gtk_item_factory_get_widget(item_factory, "<main>"); | |
+ | |
+ vbox2 = gtk_vbox_new(FALSE, 0); | |
+ gtk_box_pack_start(GTK_BOX(vbox2), menubar, FALSE, FALSE, 0); | |
+ gtk_widget_show_all(menubar); | |
+ UpdateMenus(); | |
+ | |
+ vbox = ClientData.vbox = gtk_vbox_new(FALSE, 5); | |
+ frame = gtk_frame_new(_("Stats")); | |
+ | |
+ table = CreateStatusWidgets(&ClientData.Status); | |
+ | |
+ gtk_container_add(GTK_CONTAINER(frame), table); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); | |
+ | |
+ vpaned = gtk_vpaned_new(); | |
+ | |
+ adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 100.0, | |
+ 1.0, 10.0, 10.0); | |
+ text = ClientData.messages = gtk_scrolled_text_new(NULL, adj, &hbox); | |
+ gtk_widget_set_usize(text, 100, 80); | |
+ gtk_text_set_point(GTK_TEXT(text), 0); | |
+ gtk_text_set_editable(GTK_TEXT(text), FALSE); | |
+ gtk_text_set_word_wrap(GTK_TEXT(text), TRUE); | |
+ gtk_paned_pack1(GTK_PANED(vpaned), hbox, TRUE, TRUE); | |
+ | |
+ hbox = gtk_hbox_new(FALSE, 7); | |
+ CreateInventory(hbox, Names.Drugs, accel_group, TRUE, TRUE, | |
+ &ClientData.Drug, DealDrugs); | |
+ clist = ClientData.Drug.HereList; | |
+ gtk_clist_column_titles_active(GTK_CLIST(clist)); | |
+ gtk_clist_set_compare_func(GTK_CLIST(clist), DrugSortFunc); | |
+ gtk_signal_connect(GTK_OBJECT(clist), "click-column", | |
+ GTK_SIGNAL_FUNC(ChangeDrugSort), NULL); | |
+ | |
+ button = ClientData.JetButton = gtk_button_new_with_label(""); | |
+ ClientData.JetAccel = 0; | |
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", | |
+ GTK_SIGNAL_FUNC(JetButtonPressed), NULL); | |
+ gtk_box_pack_start(GTK_BOX(ClientData.Drug.vbbox), button, TRUE, TRUE, 0); | |
+ SetJetButtonTitle(accel_group); | |
+ | |
+ gtk_paned_pack2(GTK_PANED(vpaned), hbox, TRUE, TRUE); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox), vpaned, TRUE, TRUE, 0); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox2), vbox, TRUE, TRUE, 0); | |
+ gtk_container_add(GTK_CONTAINER(window), vbox2); | |
+ | |
+ /* Just show the window, not the vbox - we'll do that when the game | |
+ * starts */ | |
+ gtk_widget_show(vbox2); | |
+ gtk_widget_show(window); | |
+ | |
+ gtk_widget_realize(window); | |
+ | |
+ SetIcon(window, dopewars_pill_xpm); | |
+ | |
+ gtk_main(); | |
+ | |
+ /* Free the main player */ | |
+ FirstClient = RemovePlayer(ClientData.Play, FirstClient); | |
+ | |
+ return TRUE; | |
+} | |
+ | |
+static void PackCentredURL(GtkWidget *vbox, gchar *title, gchar *target, | |
+ gchar *browser) | |
+{ | |
+ GtkWidget *hbox, *label, *url; | |
+ | |
+ /* There must surely be a nicer way of making the URL centred - but I | |
+ * can't think of one... */ | |
+ hbox = gtk_hbox_new(FALSE, 0); | |
+ label = gtk_label_new(""); | |
+ gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); | |
+ | |
+ url = gtk_url_new(title, target, browser); | |
+ gtk_box_pack_start(GTK_BOX(hbox), url, FALSE, FALSE, 0); | |
+ | |
+ label = gtk_label_new(""); | |
+ gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, FALSE, 0); | |
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
+} | |
+ | |
+void display_intro(GtkWidget *widget, gpointer data) | |
+{ | |
+ GtkWidget *dialog, *label, *table, *OKButton, *vbox, *hsep; | |
+ gchar *VersionStr, *docindex; | |
+ const int rows = 6, cols = 3; | |
+ int i, j; | |
+ gchar *table_data[6][3] = { | |
+ /* Credits labels in GTK+ 'about' dialog */ | |
+ {N_("Icons and graphics"), "Ocelot Mantis", NULL}, | |
+ {N_("Drug Dealing and Research"), "Dan Wolf", NULL}, | |
+ {N_("Play Testing"), "Phil Davis", "Owen Walsh"}, | |
+ {N_("Extensive Play Testing"), "Katherine Holt", | |
+ "Caroline Moore"}, | |
+ {N_("Constructive Criticism"), "Andrea Elliot-Smith", | |
+ "Pete Winn"}, | |
+ {N_("Unconstructive Criticism"), "James Matthews", NULL} | |
+ }; | |
+ | |
+ dialog = gtk_window_new(GTK_WINDOW_DIALOG); | |
+ | |
+ /* Title of GTK+ 'about' dialog */ | |
+ gtk_window_set_title(GTK_WINDOW(dialog), _("About dopewars")); | |
+ | |
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ gtk_container_border_width(GTK_CONTAINER(dialog), 10); | |
+ | |
+ vbox = gtk_vbox_new(FALSE, 5); | |
+ | |
+ /* Main content of GTK+ 'about' dialog */ | |
+ label = gtk_label_new(_("Based on John E. Dell's old Drug Wars game, " | |
+ "dopewars is a simulation of an\nimaginary drug " | |
+ "market. dopewars is an All-American game which " | |
+ "features\nbuying, selling, and trying to get " | |
+ "past the cops!\n\nThe first thing you need to " | |
+ "do is pay off your debt to the Loan Shark. " | |
+ "After\nthat, your goal is to make as much " | |
+ "money as possible (and stay alive)! You\n" | |
+ "have one month of game time to make " | |
+ "your fortune.\n")); | |
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
+ | |
+ /* Version and copyright notice in GTK+ 'about' dialog */ | |
+ VersionStr = g_strdup_printf(_("Version %s " | |
+ "Copyright (C) 1998-2002 " | |
+ "Ben Webb [email protected]\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: [email protected] * | |
+ * WWW: http://dopewars.sourceforge.net/ * | |
+ * * | |
+ * This program is free software; you can redistribute it and/or * | |
+ * modify it under the terms of the GNU General Public License * | |
+ * as published by the Free Software Foundation; either version 2 * | |
+ * of the License, or (at your option) any later version. * | |
+ * * | |
+ * This program is distributed in the hope that it will be useful, * | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
+ * GNU General Public License for more details. * | |
+ * * | |
+ * You should have received a copy of the GNU General Public License * | |
+ * along with this program; if not, write to the Free Software * | |
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * | |
+ * MA 02111-1307, USA. * | |
+ ************************************************************************/ | |
+ | |
+#ifndef __GTK_CLIENT_H__ | |
+#define __GTK_CLIENT_H__ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#include "gtkport/gtkport.h" | |
+ | |
+extern GtkWidget *MainWindow; | |
+ | |
+#ifdef CYGWIN | |
+gboolean GtkLoop(HINSTANCE hInstance, HINSTANCE hPrevInstance, | |
+ gboolean ReturnOnFail); | |
+#else | |
+gboolean GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail); | |
+#endif | |
+ | |
+#endif | |
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 hPre… | |
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(); |