tEntire codebase run through "indent -kr -i2" to tidy it up and make things nice and consistent - vaccinewars - be a doctor and try to vaccinate the world (HTM) git clone git://src.adamsgaard.dk/vaccinewars (DIR) Log (DIR) Files (DIR) Refs (DIR) README (DIR) LICENSE --- (DIR) commit abe583e0a854064d289b0a6c85a37251ae73cf60 (DIR) parent 8c06aa89b30fe56246729b768b2ee44eefc09c2c (HTM) Author: Ben Webb <ben@salilab.org> Date: Mon, 18 Feb 2002 13:44:07 +0000 Entire codebase run through "indent -kr -i2" to tidy it up and make things nice and consistent Diffstat: M src/AIPlayer.c | 1076 +++++++++++++++++-------------- M src/AIPlayer.h | 41 ++++++++++++++++--------------- M src/admin.c | 133 ++++++++++++++++++------------- M src/admin.h | 41 ++++++++++++++++--------------- M src/curses_client.c | 3547 +++++++++++++++++-------------- M src/curses_client.h | 41 ++++++++++++++++--------------- M src/dopeos.c | 690 +++++++++++++++++++------------- M src/dopeos.h | 127 ++++++++++++++++--------------- M src/dopewars.c | 3992 +++++++++++++++++-------------- M src/dopewars.h | 401 ++++++++++++++++--------------- M src/error.c | 216 +++++++++++++++++-------------- M src/error.h | 63 ++++++++++++++++--------------- M src/gtk_client.c | 6457 ++++++++++++++++--------------- M src/gtk_client.h | 45 ++++++++++++++++--------------- M src/gtkport.c | 8216 +++++++++++++++++-------------- M src/gtkport.h | 673 ++++++++++++++++--------------- M src/message.c | 2081 +++++++++++++++++-------------- M src/message.h | 177 ++++++++++++++++--------------- M src/network.c | 2405 +++++++++++++++++-------------- M src/network.h | 270 +++++++++++++++++-------------- M src/nls.h | 41 ++++++++++++++++--------------- M src/serverside.c | 5686 +++++++++++++++++-------------- M src/serverside.h | 68 ++++++++++++++++--------------- M src/tstring.c | 499 ++++++++++++++++++------------- M src/tstring.h | 40 ++++++++++++++++--------------- M src/winmain.c | 285 +++++++++++++++++-------------- M src/winmain.h | 41 ++++++++++++++++--------------- M win32/guifunc.c | 137 +++++++++++++++++-------------- M win32/guifunc.h | 40 ++++++++++++++++--------------- M win32/makeinstall.c | 336 +++++++++++++++++-------------- M win32/setup.c | 1089 +++++++++++++++++-------------- M win32/uninstall.c | 217 +++++++++++++++++-------------- M win32/util.c | 768 +++++++++++++++++-------------- M win32/util.h | 99 ++++++++++++++++--------------- 34 files changed, 21798 insertions(+), 18240 deletions(-) --- (DIR) diff --git a/src/AIPlayer.c b/src/AIPlayer.c t@@ -1,23 +1,24 @@ -/* AIPlayer.c Code for dopewars computer players */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * AIPlayer.c Code for dopewars computer players * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #include <stdio.h> #include <string.h> t@@ -36,7 +37,7 @@ #include "AIPlayer.h" #if NETWORKING -static int HandleAIMessage(char *Message,Player *AIPlay); +static int HandleAIMessage(char *Message, Player *AIPlay); static void PrintAIMessage(char *Text); static void AIDealDrugs(Player *AIPlay); static void AIJet(Player *AIPlay); t@@ -44,7 +45,8 @@ static void AIGunShop(Player *AIPlay); static void AIPayLoan(Player *AIPlay); static void AISendRandomMessage(Player *AIPlay); static void AISetName(Player *AIPlay); -static void AIHandleQuestion(char *Data,AICode AI,Player *AIPlay,Player *From); +static void AIHandleQuestion(char *Data, AICode AI, Player *AIPlay, + Player *From); #define MINSAFECASH 300 #define MINSAFEHEALTH 140 t@@ -52,27 +54,32 @@ static void AIHandleQuestion(char *Data,AICode AI,Player *AIPlay,Player *From); /* Reserve some space for picking up new guns */ #define SPACERESERVE 10 -/* Locations of the loan shark, bank, gun shop and pub */ -/* Note: these are not the same as the global variables */ -/* LoanSharkLoc, BankLoc, GunShopLoc and RoughPubLoc, */ -/* which are set locally. The remote server could */ -/* have different locations set, and the AI must work */ -/* out where these locations are for itself. */ -int RealLoanShark,RealBank,RealGunShop,RealPub; - -static void AIConnectFailed(NetworkBuffer *netbuf) { +/* + * Locations of the loan shark, bank, gun shop and pub + * Note: these are not the same as the global variables + * LoanSharkLoc, BankLoc, GunShopLoc and RoughPubLoc, + * which are set locally. The remote server could + * have different locations set, and the AI must work + * out where these locations are for itself. + */ +int RealLoanShark, RealBank, RealGunShop, RealPub; + +static void AIConnectFailed(NetworkBuffer *netbuf) +{ GString *errstr; errstr = g_string_new(_("Connection closed by remote host")); - if (netbuf->error) g_string_assign_error(errstr,netbuf->error); - g_log(NULL,G_LOG_LEVEL_CRITICAL, + if (netbuf->error) + g_string_assign_error(errstr, netbuf->error); + g_log(NULL, G_LOG_LEVEL_CRITICAL, _("Could not connect to dopewars server\n(%s)\n" - "AI Player terminating abnormally."),errstr->str); - g_string_free(errstr,TRUE); + "AI Player terminating abnormally."), errstr->str); + g_string_free(errstr, TRUE); } -static void AIStartGame(Player *AIPlay) { - Client=Network=TRUE; +static void AIStartGame(Player *AIPlay) +{ + Client = Network = TRUE; InitAbilities(AIPlay); SendAbilities(AIPlay); t@@ -80,515 +87,602 @@ static void AIStartGame(Player *AIPlay) { g_message(_("Connection established\n")); } -static void DisplayConnectStatus(NetworkBuffer *netbuf,NBStatus oldstatus, - NBSocksStatus oldsocks) { +static void DisplayConnectStatus(NetworkBuffer *netbuf, NBStatus oldstatus, + NBSocksStatus oldsocks) +{ NBStatus status; NBSocksStatus sockstat; status = netbuf->status; sockstat = netbuf->sockstat; - if (oldstatus==status && oldsocks==sockstat) return; - - switch(status) { - case NBS_PRECONNECT: + if (oldstatus == status && oldsocks == sockstat) + return; + + switch (status) { + case NBS_PRECONNECT: + break; + case NBS_SOCKSCONNECT: + switch (sockstat) { + case NBSS_METHODS: + g_print(_("Connected to SOCKS server %s...\n"), Socks.name); break; - case NBS_SOCKSCONNECT: - switch(sockstat) { - case NBSS_METHODS: - g_print(_("Connected to SOCKS server %s...\n"),Socks.name); - break; - case NBSS_USERPASSWD: - g_print(_("Authenticating with SOCKS server\n")); - break; - case NBSS_CONNECT: - g_print(_("Asking SOCKS for connect to %s...\n"),ServerName); - break; - } + case NBSS_USERPASSWD: + g_print(_("Authenticating with SOCKS server\n")); break; - case NBS_CONNECTED: + case NBSS_CONNECT: + g_print(_("Asking SOCKS for connect to %s...\n"), ServerName); break; + } + break; + case NBS_CONNECTED: + break; } } -static void NetBufAuth(NetworkBuffer *netbuf,gpointer data) { +static void NetBufAuth(NetworkBuffer *netbuf, gpointer data) +{ g_print(_("Using Socks.Auth.User and Socks.Auth.Password " "for SOCKS5 authentication\n")); - SendSocks5UserPasswd(netbuf,Socks.authuser,Socks.authpassword); + SendSocks5UserPasswd(netbuf, Socks.authuser, Socks.authpassword); } -void AIPlayerLoop() { -/* Main loop for AI players. Connects to server, plays game, */ -/* and then disconnects. */ - GString *errstr; - gchar *msg; - Player *AIPlay; - fd_set readfs,writefs; - gboolean DoneOK,QuitRequest,datawaiting; - int MaxSock; - NBStatus oldstatus; - NBSocksStatus oldsocks; - NetworkBuffer *netbuf; - - errstr=g_string_new(""); - AIPlay=g_new(Player,1); - FirstClient=AddPlayer(0,AIPlay,FirstClient); - g_message(_("AI Player started; attempting to contact server at %s:%d..."), - ServerName,Port); - - /* Forget where the "special" locations are */ - RealLoanShark=RealBank=RealGunShop=RealPub=-1; - - netbuf = &AIPlay->NetBuf; - oldstatus = netbuf->status; - oldsocks = netbuf->sockstat; - - if (!StartNetworkBufferConnect(netbuf,ServerName,Port)) { - AIConnectFailed(netbuf); return; - } else { - SetNetworkBufferUserPasswdFunc(netbuf,NetBufAuth,NULL); - if (netbuf->status==NBS_CONNECTED) { - AIStartGame(AIPlay); - } else { - DisplayConnectStatus(netbuf,oldstatus,oldsocks); - } - } - - while (1) { - FD_ZERO(&readfs); - FD_ZERO(&writefs); - MaxSock=0; - - SetSelectForNetworkBuffer(netbuf,&readfs,&writefs,NULL,&MaxSock); - - oldstatus = netbuf->status; - oldsocks = netbuf->sockstat; - if (bselect(MaxSock,&readfs,&writefs,NULL,NULL)==-1) { - if (errno==EINTR) continue; - printf("Error in select\n"); exit(1); - } - - datawaiting=RespondToSelect(netbuf,&readfs,&writefs,NULL,&DoneOK); +/* + * Main loop for AI players. Connects to server, plays game, + * and then disconnects. + */ +void AIPlayerLoop() +{ + GString *errstr; + gchar *msg; + Player *AIPlay; + fd_set readfs, writefs; + gboolean DoneOK, QuitRequest, datawaiting; + int MaxSock; + NBStatus oldstatus; + NBSocksStatus oldsocks; + NetworkBuffer *netbuf; + + errstr = g_string_new(""); + AIPlay = g_new(Player, 1); + + FirstClient = AddPlayer(0, AIPlay, FirstClient); + g_message(_("AI Player started; attempting to contact " + "server at %s:%d..."), ServerName, Port); + + /* Forget where the "special" locations are */ + RealLoanShark = RealBank = RealGunShop = RealPub = -1; + + netbuf = &AIPlay->NetBuf; + oldstatus = netbuf->status; + oldsocks = netbuf->sockstat; + + if (!StartNetworkBufferConnect(netbuf, ServerName, Port)) { + AIConnectFailed(netbuf); + return; + } else { + SetNetworkBufferUserPasswdFunc(netbuf, NetBufAuth, NULL); + if (netbuf->status == NBS_CONNECTED) { + AIStartGame(AIPlay); + } else { + DisplayConnectStatus(netbuf, oldstatus, oldsocks); + } + } - if (oldstatus!=NBS_CONNECTED && - (netbuf->status==NBS_CONNECTED || !DoneOK)) { - if (DoneOK) AIStartGame(AIPlay); - else { - AIConnectFailed(netbuf); break; - } - } else if (netbuf->status!=NBS_CONNECTED) { - DisplayConnectStatus(netbuf,oldstatus,oldsocks); + while (1) { + FD_ZERO(&readfs); + FD_ZERO(&writefs); + MaxSock = 0; + + SetSelectForNetworkBuffer(netbuf, &readfs, &writefs, NULL, &MaxSock); + + oldstatus = netbuf->status; + oldsocks = netbuf->sockstat; + if (bselect(MaxSock, &readfs, &writefs, NULL, NULL) == -1) { + if (errno == EINTR) + continue; + printf("Error in select\n"); + exit(1); + } + + datawaiting = + RespondToSelect(netbuf, &readfs, &writefs, NULL, &DoneOK); + + if (oldstatus != NBS_CONNECTED && + (netbuf->status == NBS_CONNECTED || !DoneOK)) { + if (DoneOK) + AIStartGame(AIPlay); + else { + AIConnectFailed(netbuf); + break; } - if (datawaiting && netbuf->status==NBS_CONNECTED) { - QuitRequest=FALSE; - while ((msg=GetWaitingPlayerMessage(AIPlay))!=NULL) { - if (HandleAIMessage(msg,AIPlay)) { - QuitRequest=TRUE; - break; - } - } - if (QuitRequest) { - g_print(_("AI Player terminated OK.\n")); - break; - } + } else if (netbuf->status != NBS_CONNECTED) { + DisplayConnectStatus(netbuf, oldstatus, oldsocks); + } + if (datawaiting && netbuf->status == NBS_CONNECTED) { + QuitRequest = FALSE; + while ((msg = GetWaitingPlayerMessage(AIPlay)) != NULL) { + if (HandleAIMessage(msg, AIPlay)) { + QuitRequest = TRUE; + break; + } } - if (!DoneOK) { - g_print(_("Connection to server lost!\n")); - break; + if (QuitRequest) { + g_print(_("AI Player terminated OK.\n")); + break; } - } - ShutdownNetwork(AIPlay); - g_string_free(errstr,TRUE); - FirstClient=RemovePlayer(AIPlay,FirstClient); + } + if (!DoneOK) { + g_print(_("Connection to server lost!\n")); + break; + } + } + ShutdownNetwork(AIPlay); + g_string_free(errstr, TRUE); + FirstClient = RemovePlayer(AIPlay, FirstClient); } -void AISetName(Player *AIPlay) { -/* Chooses a random name for the AI player, and informs the server */ - char *AINames[] = { - "Chip", "Dopey", "Al", "Dan", "Bob", "Fred", "Bert", "Jim" - }; - const gint NumNames = sizeof(AINames)/sizeof(AINames[0]); - gchar *text; - - text=g_strdup_printf("AI) %s",AINames[brandom(0,NumNames)]); - SetPlayerName(AIPlay,text); - g_free(text); - SendNullClientMessage(AIPlay,C_NONE,C_NAME,NULL,GetPlayerName(AIPlay)); - g_print(_("Using name %s\n"),GetPlayerName(AIPlay)); +/* + * Chooses a random name for the AI player, and informs the server + */ +void AISetName(Player *AIPlay) +{ + char *AINames[] = { + "Chip", "Dopey", "Al", "Dan", "Bob", "Fred", "Bert", "Jim" + }; + const gint NumNames = sizeof(AINames) / sizeof(AINames[0]); + gchar *text; + + text = g_strdup_printf("AI) %s", AINames[brandom(0, NumNames)]); + SetPlayerName(AIPlay, text); + g_free(text); + SendNullClientMessage(AIPlay, C_NONE, C_NAME, NULL, + GetPlayerName(AIPlay)); + g_print(_("Using name %s\n"), GetPlayerName(AIPlay)); } -gboolean ShouldRun(Player *AIPlay) { -/* Returns TRUE if it would be prudent to run away... */ - gint TotalHealth; +/* + * Returns TRUE if it would be prudent to run away... + */ +gboolean ShouldRun(Player *AIPlay) +{ + gint TotalHealth; - if (TotalGunsCarried(AIPlay)==0) return TRUE; + if (TotalGunsCarried(AIPlay) == 0) + return TRUE; - TotalHealth=AIPlay->Health + AIPlay->Bitches.Carried*100; - return (TotalHealth < MINSAFEHEALTH); + TotalHealth = AIPlay->Health + AIPlay->Bitches.Carried * 100; + return (TotalHealth < MINSAFEHEALTH); } -static void HandleCombat(Player *AIPlay,gchar *Msg) { -/* Decodes the fighting-related message "Msg", and then decides whether */ -/* to stand or run... */ - gchar *text; - gchar *AttackName,*DefendName,*BitchName; - FightPoint fp; - int DefendHealth,DefendBitches,BitchesKilled,ArmPercent; - gboolean CanRunHere,Loot,CanFire; - - if (HaveAbility(AIPlay,A_NEWFIGHT)) { - ReceiveFightMessage(Msg,&AttackName,&DefendName,&DefendHealth, - &DefendBitches,&BitchName,&BitchesKilled, - &ArmPercent,&fp,&CanRunHere,&Loot, - &CanFire,&text); - } else { - text=Msg; - if (AIPlay->Flags&FIGHTING) fp=F_MSG; - else fp=F_LASTLEAVE; - CanFire = (AIPlay->Flags&CANSHOOT); - CanRunHere=FALSE; - } - PrintAIMessage(text); - - if (ShouldRun(AIPlay)) { - if (CanRunHere) { - SendClientMessage(AIPlay,C_NONE,C_FIGHTACT,NULL,"R"); - } else { - AIDealDrugs(AIPlay); - AIJet(AIPlay); - } - } else if (fp==F_LASTLEAVE) { +/* + * Decodes the fighting-related message "Msg", and then decides whether + * to stand or run... + */ +static void HandleCombat(Player *AIPlay, gchar *Msg) +{ + gchar *text; + gchar *AttackName, *DefendName, *BitchName; + FightPoint fp; + int DefendHealth, DefendBitches, BitchesKilled, ArmPercent; + gboolean CanRunHere, Loot, CanFire; + + if (HaveAbility(AIPlay, A_NEWFIGHT)) { + ReceiveFightMessage(Msg, &AttackName, &DefendName, &DefendHealth, + &DefendBitches, &BitchName, &BitchesKilled, + &ArmPercent, &fp, &CanRunHere, &Loot, + &CanFire, &text); + } else { + text = Msg; + if (AIPlay->Flags & FIGHTING) + fp = F_MSG; + else + fp = F_LASTLEAVE; + CanFire = (AIPlay->Flags & CANSHOOT); + CanRunHere = FALSE; + } + PrintAIMessage(text); + + if (ShouldRun(AIPlay)) { + if (CanRunHere) { + SendClientMessage(AIPlay, C_NONE, C_FIGHTACT, NULL, "R"); + } else { + AIDealDrugs(AIPlay); AIJet(AIPlay); - } else { - SendClientMessage(AIPlay,C_NONE,C_FIGHTACT,NULL,"F"); - } + } + } else if (fp == F_LASTLEAVE) { + AIJet(AIPlay); + } else { + SendClientMessage(AIPlay, C_NONE, C_FIGHTACT, NULL, "F"); + } } -int HandleAIMessage(char *Message,Player *AIPlay) { -/* Performs appropriate processing on an incoming network message */ -/* "Message" for AI player "AIPlay". Returns 1 if the game should */ -/* be ended as a result, 0 otherwise. */ - char *Data,WasFighting; - AICode AI; - MsgCode Code; - Player *From,*tmp; - GSList *list; - struct timeval tv; - gboolean Handled; - - if (ProcessMessage(Message,AIPlay,&From,&AI,&Code, - &Data,FirstClient)==-1) { - g_warning("Bad network message. Oops."); return 0; - } - Handled=HandleGenericClientMessage(From,AI,Code,AIPlay,Data,NULL); - switch(Code) { - case C_ENDLIST: - g_print(_("Players in this game:-\n")); - for (list=FirstClient;list;list=g_slist_next(list)) { - tmp=(Player *)list->data; - g_print(" %s\n",GetPlayerName(tmp)); - } - break; - case C_NEWNAME: - AISetName(AIPlay); - break; - case C_FIGHTPRINT: - HandleCombat(AIPlay,Data); - break; - case C_PRINTMESSAGE: - PrintAIMessage(Data); - break; - case C_MSG: - g_print("%s: %s\n",GetPlayerName(From),Data); - break; - case C_MSGTO: - g_print("%s->%s: %s\n",GetPlayerName(From),GetPlayerName(AIPlay),Data); - break; - case C_JOIN: - g_print(_("%s joins the game.\n"),Data); break; - case C_LEAVE: - if (From!=&Noone) { - g_print(_("%s has left the game.\n"),Data); - } - break; - case C_SUBWAYFLASH: - dpg_print(_("Jetting to %tde with %P cash and %P debt\n"), - Location[(int)AIPlay->IsAt].Name,AIPlay->Cash,AIPlay->Debt); - /* Use bselect rather than sleep, as this is portable to Win32 */ - tv.tv_sec=AITurnPause; - tv.tv_usec=0; - bselect(0,NULL,NULL,NULL,&tv); - if (brandom(0,100)<10) AISendRandomMessage(AIPlay); - break; - case C_UPDATE: - WasFighting=FALSE; - if (From==&Noone) { - if (AIPlay->Flags & FIGHTING) WasFighting=TRUE; - ReceivePlayerData(AIPlay,Data,AIPlay); - } else { - ReceivePlayerData(AIPlay,Data,From); /* spy reports */ - } - if (!(AIPlay->Flags & FIGHTING) && WasFighting) { - AIDealDrugs(AIPlay); - AIJet(AIPlay); - } - if (AIPlay->Health==0) { - g_print(_("AI Player killed. Terminating normally.\n")); - return 1; - } - break; - case C_DRUGHERE: - AIDealDrugs(AIPlay); - AIJet(AIPlay); - break; - case C_GUNSHOP: - AIGunShop(AIPlay); - break; - case C_LOANSHARK: - AIPayLoan(AIPlay); - break; - case C_QUESTION: - AIHandleQuestion(Data,AI,AIPlay,From); - break; - case C_HISCORE: case C_STARTHISCORE: - break; - case C_ENDHISCORE: - g_print(_("Game time is up. Leaving game.\n")); - return 1; - case C_PUSH: - g_print(_("AI Player pushed from the server.\n")); - return 1; - case C_QUIT: - g_print(_("The server has terminated.\n")); - return 1; - default: - if (!Handled) g_message("%s^%c^%s%s\n",GetPlayerName(From),Code, - GetPlayerName(AIPlay),Data); - break; - } - return 0; +/* + * Performs appropriate processing on an incoming network message + * "Message" for AI player "AIPlay". Returns 1 if the game should + * be ended as a result, 0 otherwise. + */ +int HandleAIMessage(char *Message, Player *AIPlay) +{ + char *Data, WasFighting; + AICode AI; + MsgCode Code; + Player *From, *tmp; + GSList *list; + struct timeval tv; + gboolean Handled; + + if (ProcessMessage(Message, AIPlay, &From, &AI, &Code, + &Data, FirstClient) == -1) { + g_warning("Bad network message. Oops."); + return 0; + } + Handled = HandleGenericClientMessage(From, AI, Code, AIPlay, Data, NULL); + switch (Code) { + case C_ENDLIST: + g_print(_("Players in this game:-\n")); + for (list = FirstClient; list; list = g_slist_next(list)) { + tmp = (Player *)list->data; + g_print(" %s\n", GetPlayerName(tmp)); + } + break; + case C_NEWNAME: + AISetName(AIPlay); + break; + case C_FIGHTPRINT: + HandleCombat(AIPlay, Data); + break; + case C_PRINTMESSAGE: + PrintAIMessage(Data); + break; + case C_MSG: + g_print("%s: %s\n", GetPlayerName(From), Data); + break; + case C_MSGTO: + g_print("%s->%s: %s\n", GetPlayerName(From), GetPlayerName(AIPlay), + Data); + break; + case C_JOIN: + g_print(_("%s joins the game.\n"), Data); + break; + case C_LEAVE: + if (From != &Noone) { + g_print(_("%s has left the game.\n"), Data); + } + break; + case C_SUBWAYFLASH: + dpg_print(_("Jetting to %tde with %P cash and %P debt\n"), + Location[(int)AIPlay->IsAt].Name, AIPlay->Cash, + AIPlay->Debt); + /* Use bselect rather than sleep, as this is portable to Win32 */ + tv.tv_sec = AITurnPause; + tv.tv_usec = 0; + bselect(0, NULL, NULL, NULL, &tv); + if (brandom(0, 100) < 10) + AISendRandomMessage(AIPlay); + break; + case C_UPDATE: + WasFighting = FALSE; + if (From == &Noone) { + if (AIPlay->Flags & FIGHTING) + WasFighting = TRUE; + ReceivePlayerData(AIPlay, Data, AIPlay); + } else { + ReceivePlayerData(AIPlay, Data, From); /* spy reports */ + } + if (!(AIPlay->Flags & FIGHTING) && WasFighting) { + AIDealDrugs(AIPlay); + AIJet(AIPlay); + } + if (AIPlay->Health == 0) { + g_print(_("AI Player killed. Terminating normally.\n")); + return 1; + } + break; + case C_DRUGHERE: + AIDealDrugs(AIPlay); + AIJet(AIPlay); + break; + case C_GUNSHOP: + AIGunShop(AIPlay); + break; + case C_LOANSHARK: + AIPayLoan(AIPlay); + break; + case C_QUESTION: + AIHandleQuestion(Data, AI, AIPlay, From); + break; + case C_HISCORE: + case C_STARTHISCORE: + break; + case C_ENDHISCORE: + g_print(_("Game time is up. Leaving game.\n")); + return 1; + case C_PUSH: + g_print(_("AI Player pushed from the server.\n")); + return 1; + case C_QUIT: + g_print(_("The server has terminated.\n")); + return 1; + default: + if (!Handled) + g_message("%s^%c^%s%s\n", GetPlayerName(From), Code, + GetPlayerName(AIPlay), Data); + break; + } + return 0; } -void PrintAIMessage(char *Text) { -/* Prints a message received via a printmessage or question */ -/* network message, stored in "Text" */ - unsigned i; - gboolean SomeText=FALSE; - for (i=0;i<strlen(Text);i++) { - if (Text[i]=='^') { - if (SomeText) putchar('\n'); - } else { - putchar(Text[i]); - SomeText=TRUE; - } - } - putchar('\n'); +/* + * Prints a message received via a printmessage or question + * network message, stored in "Text". + */ +void PrintAIMessage(char *Text) +{ + unsigned i; + gboolean SomeText = FALSE; + + for (i = 0; i < strlen(Text); i++) { + if (Text[i] == '^') { + if (SomeText) + putchar('\n'); + } else { + putchar(Text[i]); + SomeText = TRUE; + } + } + putchar('\n'); } -void AIDealDrugs(Player *AIPlay) { -/* Buy and sell drugs for AI player "AIPlay" */ - price_t *Profit,MaxProfit; - gchar *text; - int i,LastHighest,Highest,Num,MinProfit; - Profit = g_new(price_t,NumDrug); - for (i=0;i<NumDrug;i++) { - Profit[i]=AIPlay->Drugs[i].Price-(Drug[i].MaxPrice+Drug[i].MinPrice)/2; - } - MinProfit=0; - for (i=0;i<NumDrug;i++) if (Profit[i]<MinProfit) MinProfit=Profit[i]; - MinProfit--; - for (i=0;i<NumDrug;i++) if (Profit[i]<0) Profit[i]=MinProfit-Profit[i]; - LastHighest=-1; - do { - MaxProfit=MinProfit; - Highest=-1; - for (i=0;i<NumDrug;i++) { - if (Profit[i]>MaxProfit && i!=LastHighest && - (LastHighest==-1 || Profit[LastHighest]>Profit[i])) { - Highest=i; - MaxProfit=Profit[i]; - } +/* + * Buys and sell drugs for AI player "AIPlay". + */ +void AIDealDrugs(Player *AIPlay) +{ + price_t *Profit, MaxProfit; + gchar *text; + int i, LastHighest, Highest, Num, MinProfit; + Profit = g_new(price_t, NumDrug); + + for (i = 0; i < NumDrug; i++) { + Profit[i] = + AIPlay->Drugs[i].Price - (Drug[i].MaxPrice + Drug[i].MinPrice) / 2; + } + MinProfit = 0; + for (i = 0; i < NumDrug; i++) + if (Profit[i] < MinProfit) + MinProfit = Profit[i]; + MinProfit--; + for (i = 0; i < NumDrug; i++) + if (Profit[i] < 0) + Profit[i] = MinProfit - Profit[i]; + LastHighest = -1; + do { + MaxProfit = MinProfit; + Highest = -1; + for (i = 0; i < NumDrug; i++) { + if (Profit[i] > MaxProfit && i != LastHighest && + (LastHighest == -1 || Profit[LastHighest] > Profit[i])) { + Highest = i; + MaxProfit = Profit[i]; + } + } + LastHighest = Highest; + if (Highest >= 0) { + Num = AIPlay->Drugs[Highest].Carried; + if (MaxProfit > 0 && Num > 0) { + dpg_print(_("Selling %d %tde at %P\n"), Num, Drug[Highest].Name, + AIPlay->Drugs[Highest].Price); + AIPlay->CoatSize += Num; + AIPlay->Cash += Num * AIPlay->Drugs[Highest].Price; + text = g_strdup_printf("drug^%d^%d", Highest, -Num); + SendClientMessage(AIPlay, C_NONE, C_BUYOBJECT, NULL, text); + g_free(text); } - LastHighest=Highest; - if (Highest>=0) { - Num=AIPlay->Drugs[Highest].Carried; - if (MaxProfit>0 && Num>0) { - dpg_print(_("Selling %d %tde at %P\n"),Num,Drug[Highest].Name, - AIPlay->Drugs[Highest].Price); - AIPlay->CoatSize+=Num; - AIPlay->Cash+=Num*AIPlay->Drugs[Highest].Price; - text=g_strdup_printf("drug^%d^%d",Highest,-Num); - SendClientMessage(AIPlay,C_NONE,C_BUYOBJECT,NULL,text); - g_free(text); + if (AIPlay->Drugs[Highest].Price != 0 && + AIPlay->CoatSize > SPACERESERVE) { + Num = AIPlay->Cash / AIPlay->Drugs[Highest].Price; + if (Num > AIPlay->CoatSize - SPACERESERVE) { + Num = AIPlay->CoatSize - SPACERESERVE; } - if (AIPlay->Drugs[Highest].Price != 0 && - AIPlay->CoatSize>SPACERESERVE) { - Num=AIPlay->Cash/AIPlay->Drugs[Highest].Price; - if (Num>AIPlay->CoatSize-SPACERESERVE) { - Num=AIPlay->CoatSize-SPACERESERVE; - } - if (MaxProfit<0 && Num>0) { - dpg_print(_("Buying %d %tde at %P\n"),Num,Drug[Highest].Name, - AIPlay->Drugs[Highest].Price); - text=g_strdup_printf("drug^%d^%d",Highest,Num); - AIPlay->CoatSize-=Num; - AIPlay->Cash-=Num*AIPlay->Drugs[Highest].Price; - SendClientMessage(AIPlay,C_NONE,C_BUYOBJECT,NULL,text); - g_free(text); - } + if (MaxProfit < 0 && Num > 0) { + dpg_print(_("Buying %d %tde at %P\n"), Num, Drug[Highest].Name, + AIPlay->Drugs[Highest].Price); + text = g_strdup_printf("drug^%d^%d", Highest, Num); + AIPlay->CoatSize -= Num; + AIPlay->Cash -= Num * AIPlay->Drugs[Highest].Price; + SendClientMessage(AIPlay, C_NONE, C_BUYOBJECT, NULL, text); + g_free(text); } } - } while (Highest>=0); - g_free(Profit); + } + } while (Highest >= 0); + g_free(Profit); } -void AIGunShop(Player *AIPlay) { -/* Handles a visit to the gun shop by AI player "AIPlay" */ - int i; - int Bought; - gchar *text; - do { - Bought=0; - for (i=0;i<NumGun;i++) { - if (TotalGunsCarried(AIPlay)<AIPlay->Bitches.Carried+2 && - Gun[i].Space<=AIPlay->CoatSize && - Gun[i].Price<=AIPlay->Cash-MINSAFECASH) { - AIPlay->Cash-=Gun[i].Price; - AIPlay->CoatSize-=Gun[i].Space; - AIPlay->Guns[i].Carried++; - Bought++; - dpg_print(_("Buying a %tde for %P at the gun shop\n"), - Gun[i].Name,Gun[i].Price); - text=g_strdup_printf("gun^%d^1",i); - SendClientMessage(AIPlay,C_NONE,C_BUYOBJECT,NULL,text); - g_free(text); - } +/* + * Handles a visit to the gun shop by AI player "AIPlay". + */ +void AIGunShop(Player *AIPlay) +{ + int i; + int Bought; + gchar *text; + + do { + Bought = 0; + for (i = 0; i < NumGun; i++) { + if (TotalGunsCarried(AIPlay) < AIPlay->Bitches.Carried + 2 && + Gun[i].Space <= AIPlay->CoatSize && + Gun[i].Price <= AIPlay->Cash - MINSAFECASH) { + AIPlay->Cash -= Gun[i].Price; + AIPlay->CoatSize -= Gun[i].Space; + AIPlay->Guns[i].Carried++; + Bought++; + dpg_print(_("Buying a %tde for %P at the gun shop\n"), + Gun[i].Name, Gun[i].Price); + text = g_strdup_printf("gun^%d^1", i); + SendClientMessage(AIPlay, C_NONE, C_BUYOBJECT, NULL, text); + g_free(text); } - } while (Bought); - SendClientMessage(AIPlay,C_NONE,C_DONE,NULL,NULL); + } + } while (Bought); + SendClientMessage(AIPlay, C_NONE, C_DONE, NULL, NULL); } -void AIJet(Player *AIPlay) { -/* Decides on a new game location for AI player "AIPlay" and jets there */ - int NewLocation; - char text[40]; - if (!AIPlay) return; - NewLocation=AIPlay->IsAt; - if (RealLoanShark>=0 && AIPlay->Cash > (price_t)((float)AIPlay->Debt*1.2)) { - NewLocation=RealLoanShark; - } else if (RealPub>=0 && brandom(0,100)<30 && AIPlay->Cash>MINSAFECASH*10) { - NewLocation=RealPub; - } else if (RealGunShop>=0 && brandom(0,100)<70 && - TotalGunsCarried(AIPlay)<AIPlay->Bitches.Carried+2 && - AIPlay->Cash>MINSAFECASH*5) { - NewLocation=RealGunShop; - } - while (NewLocation==AIPlay->IsAt) NewLocation=brandom(0,NumLocation); - sprintf(text,"%d",NewLocation); - SendClientMessage(AIPlay,C_NONE,C_REQUESTJET,NULL,text); +/* + * Decides on a new game location for AI player "AIPlay" and jets there. + */ +void AIJet(Player *AIPlay) +{ + int NewLocation; + char text[40]; + + if (!AIPlay) + return; + NewLocation = AIPlay->IsAt; + if (RealLoanShark >= 0 + && AIPlay->Cash > (price_t)((float)AIPlay->Debt * 1.2)) { + NewLocation = RealLoanShark; + } else if (RealPub >= 0 && brandom(0, 100) < 30 + && AIPlay->Cash > MINSAFECASH * 10) { + NewLocation = RealPub; + } else if (RealGunShop >= 0 && brandom(0, 100) < 70 && + TotalGunsCarried(AIPlay) < AIPlay->Bitches.Carried + 2 && + AIPlay->Cash > MINSAFECASH * 5) { + NewLocation = RealGunShop; + } + while (NewLocation == AIPlay->IsAt) + NewLocation = brandom(0, NumLocation); + sprintf(text, "%d", NewLocation); + SendClientMessage(AIPlay, C_NONE, C_REQUESTJET, NULL, text); } -void AIPayLoan(Player *AIPlay) { -/* Pays off the loan of AI player "AIPlay" if this doesn't leave */ -/* the player with insufficient funds for further dealing */ - gchar *prstr; - if (AIPlay->Cash-AIPlay->Debt >= MINSAFECASH) { - prstr=pricetostr(AIPlay->Debt); - SendClientMessage(AIPlay,C_NONE,C_PAYLOAN,NULL,prstr); - g_free(prstr); - dpg_print(_("Debt of %P paid off to loan shark\n"),AIPlay->Debt); - } - SendClientMessage(AIPlay,C_NONE,C_DONE,NULL,NULL); +/* + * Pays off the loan of AI player "AIPlay" if this doesn't leave + * the player with insufficient funds for further dealing. + */ +void AIPayLoan(Player *AIPlay) +{ + gchar *prstr; + + if (AIPlay->Cash - AIPlay->Debt >= MINSAFECASH) { + prstr = pricetostr(AIPlay->Debt); + SendClientMessage(AIPlay, C_NONE, C_PAYLOAN, NULL, prstr); + g_free(prstr); + dpg_print(_("Debt of %P paid off to loan shark\n"), AIPlay->Debt); + } + SendClientMessage(AIPlay, C_NONE, C_DONE, NULL, NULL); } -void AISendAnswer(Player *From,Player *To,char *answer) { -/* Sends the answer "answer" from AI player "From" to the server, */ -/* claiming to be for player "To". Also prints the answer on the screen. */ - SendClientMessage(From,C_NONE,C_ANSWER,To,answer); puts(answer); +/* + * Sends the answer "answer" from AI player "From" to the server, + * claiming to be for player "To". Also prints the answer on the screen. + */ +void AISendAnswer(Player *From, Player *To, char *answer) +{ + SendClientMessage(From, C_NONE, C_ANSWER, To, answer); + puts(answer); } -void AIHandleQuestion(char *Data,AICode AI,Player *AIPlay,Player *From) { -/* Works out a sensible response to the question coded in "Data" and with */ -/* computer-readable code "AI", claiming to be from "From" and for AI */ -/* player "AIPlay", and sends it */ - char *Prompt,*allowed; - if (From==&Noone) From=NULL; - Prompt=Data; - allowed=GetNextWord(&Prompt,""); - PrintAIMessage(Prompt); - switch (AI) { - case C_ASKLOAN: - if (RealLoanShark==-1) { - g_print(_("Loan shark located at %s\n"), - Location[(int)AIPlay->IsAt].Name); - } - RealLoanShark=AIPlay->IsAt; - AISendAnswer(AIPlay,From,"Y"); - break; - case C_ASKGUNSHOP: - if (RealGunShop==-1) { - g_print(_("Gun shop located at %s\n"), - Location[(int)AIPlay->IsAt].Name); - } - RealGunShop=AIPlay->IsAt; - AISendAnswer(AIPlay,From,"Y"); - break; - case C_ASKPUB: - if (RealPub==-1) { - g_print(_("Pub located at %s\n"),Location[(int)AIPlay->IsAt].Name); - } - RealPub=AIPlay->IsAt; - AISendAnswer(AIPlay,From,"Y"); - break; - case C_ASKBITCH: case C_ASKRUN: case C_ASKGUN: - AISendAnswer(AIPlay,From,"Y"); - break; - case C_ASKRUNFIGHT: - AISendAnswer(AIPlay,From,ShouldRun(AIPlay) ? "R" : "F"); - break; - case C_ASKBANK: - if (RealBank==-1) { - g_print(_("Bank located at %s\n"),Location[(int)AIPlay->IsAt].Name); - } - RealBank=AIPlay->IsAt; - AISendAnswer(AIPlay,From,"N"); - break; - case C_MEETPLAYER: - if (TotalGunsCarried(AIPlay)>0) AISendAnswer(AIPlay,From,"A"); - else { - AISendAnswer(AIPlay,From,"E"); - AIJet(AIPlay); - } - break; - case C_ASKSEW: - AISendAnswer(AIPlay,From,AIPlay->Health<MINSAFEHEALTH ? "Y" : "N"); - break; - default: - AISendAnswer(AIPlay,From,"N"); - break; - } +/* + * Works out a sensible response to the question coded in "Data" and with + * computer-readable code "AI", claiming to be from "From" and for AI + * player "AIPlay", and sends it. + */ +void AIHandleQuestion(char *Data, AICode AI, Player *AIPlay, Player *From) +{ + char *Prompt, *allowed; + + if (From == &Noone) + From = NULL; + Prompt = Data; + allowed = GetNextWord(&Prompt, ""); + PrintAIMessage(Prompt); + switch (AI) { + case C_ASKLOAN: + if (RealLoanShark == -1) { + g_print(_("Loan shark located at %s\n"), + Location[(int)AIPlay->IsAt].Name); + } + RealLoanShark = AIPlay->IsAt; + AISendAnswer(AIPlay, From, "Y"); + break; + case C_ASKGUNSHOP: + if (RealGunShop == -1) { + g_print(_("Gun shop located at %s\n"), + Location[(int)AIPlay->IsAt].Name); + } + RealGunShop = AIPlay->IsAt; + AISendAnswer(AIPlay, From, "Y"); + break; + case C_ASKPUB: + if (RealPub == -1) { + g_print(_("Pub located at %s\n"), Location[(int)AIPlay->IsAt].Name); + } + RealPub = AIPlay->IsAt; + AISendAnswer(AIPlay, From, "Y"); + break; + case C_ASKBITCH: + case C_ASKRUN: + case C_ASKGUN: + AISendAnswer(AIPlay, From, "Y"); + break; + case C_ASKRUNFIGHT: + AISendAnswer(AIPlay, From, ShouldRun(AIPlay) ? "R" : "F"); + break; + case C_ASKBANK: + if (RealBank == -1) { + g_print(_("Bank located at %s\n"), Location[(int)AIPlay->IsAt].Name); + } + RealBank = AIPlay->IsAt; + AISendAnswer(AIPlay, From, "N"); + break; + case C_MEETPLAYER: + if (TotalGunsCarried(AIPlay) > 0) + AISendAnswer(AIPlay, From, "A"); + else { + AISendAnswer(AIPlay, From, "E"); + AIJet(AIPlay); + } + break; + case C_ASKSEW: + AISendAnswer(AIPlay, From, AIPlay->Health < MINSAFEHEALTH ? "Y" : "N"); + break; + default: + AISendAnswer(AIPlay, From, "N"); + break; + } } -void AISendRandomMessage(Player *AIPlay) { -/* Sends a random message to all other dopewars players */ - char *RandomInsult[5]= { -/* Random messages to send from the AI player to other players */ - N_("Call yourselves drug dealers?"), - N_("A trained monkey could do better..."), - N_("Think you\'re hard enough to deal with the likes of me?"), - N_("Zzzzz... are you dealing in candy or what?"), - N_("Reckon I'll just have to shoot you for your own good.") - }; - SendClientMessage(AIPlay,C_NONE,C_MSG,NULL,_(RandomInsult[brandom(0,5)])); +/* + * Sends a random message to all other dopewars players. + */ +void AISendRandomMessage(Player *AIPlay) +{ + char *RandomInsult[5] = { + /* Random messages to send from the AI player to other players */ + N_("Call yourselves drug dealers?"), + N_("A trained monkey could do better..."), + N_("Think you\'re hard enough to deal with the likes of me?"), + N_("Zzzzz... are you dealing in candy or what?"), + N_("Reckon I'll just have to shoot you for your own good.") + }; + + SendClientMessage(AIPlay, C_NONE, C_MSG, NULL, + _(RandomInsult[brandom(0, 5)])); } #else /* NETWORKING */ -void AIPlayerLoop() { -/* Whoops - the user asked that we run an AI player, but the binary was - built without that compiled in. */ - g_print(_("This binary has been compiled without networking support, and " - "thus cannot act as an AI player.\nRecompile passing " - "--enable-networking to the configure script.")); +/* + * Whoops - the user asked that we run an AI player, but the binary was + * built without that compiled in. + */ +void AIPlayerLoop() +{ + g_print(_("This binary has been compiled without networking support, " + "and thus cannot act as an AI player.\nRecompile passing " + "--enable-networking to the configure script.")); } #endif /* NETWORKING */ (DIR) diff --git a/src/AIPlayer.h b/src/AIPlayer.h t@@ -1,23 +1,24 @@ -/* AIPlayer.h Header file for dopewars computer player code */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * AIPlayer.h Header file for dopewars computer player code * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __AIPLAYER_H__ #define __AIPLAYER_H__ (DIR) diff --git a/src/admin.c b/src/admin.c t@@ -1,22 +1,24 @@ -/* admin.c Dopewars server administration */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * admin.c dopewars server administration * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifdef HAVE_CONFIG_H #include <config.h> t@@ -38,74 +40,91 @@ #include "nls.h" #include "serverside.h" -static int OpenSocket(void) { +static int OpenSocket(void) +{ struct sockaddr_un addr; int sock; gchar *sockname; - sockname=GetLocalSocket(); + sockname = GetLocalSocket(); - g_print(_("Attempting to connect to local dopewars server via. Unix domain\n" - "socket %s...\n"),sockname); - sock = socket(PF_UNIX,SOCK_STREAM,0); - if (sock==-1) { perror("socket"); exit(1); } + g_print(_("Attempting to connect to local dopewars server via. " + "Unix domain\n socket %s...\n"), sockname); + sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (sock == -1) { + perror("socket"); + exit(1); + } addr.sun_family = AF_UNIX; - strncpy(addr.sun_path,sockname,sizeof(addr.sun_path)); - addr.sun_path[sizeof(addr.sun_path)-1]='\0'; + strncpy(addr.sun_path, sockname, sizeof(addr.sun_path)); + addr.sun_path[sizeof(addr.sun_path) - 1] = '\0'; - if (connect(sock,(struct sockaddr *)&addr,sizeof(struct sockaddr_un))==-1) { - perror("connect"); exit(1); + if (connect(sock, (struct sockaddr *)&addr, + sizeof(struct sockaddr_un)) == -1) { + perror("connect"); + exit(1); } - g_print(_("Connection established; use Ctrl-D to close your session.\n\n")); + g_print(_("Connection established; use Ctrl-D to " + "close your session.\n\n")); g_free(sockname); return sock; } -void AdminServer(void) { - int sock,topsock; +void AdminServer(void) +{ + int sock, topsock; NetworkBuffer *netbuf; - fd_set readfds,writefds,errorfds; - gchar *msg,inbuf[200]; + fd_set readfds, writefds, errorfds; + gchar *msg, inbuf[200]; gboolean doneOK; - sock=OpenSocket(); - netbuf = g_new(NetworkBuffer,1); - InitNetworkBuffer(netbuf,'\n','\r',NULL); - BindNetworkBufferToSocket(netbuf,sock); + sock = OpenSocket(); + netbuf = g_new(NetworkBuffer, 1); + + InitNetworkBuffer(netbuf, '\n', '\r', NULL); + BindNetworkBufferToSocket(netbuf, sock); - while(1) { + while (1) { FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&errorfds); - FD_SET(0,&readfds); - topsock=1; - SetSelectForNetworkBuffer(netbuf,&readfds,&writefds,&errorfds,&topsock); - - if (select(topsock,&readfds,&writefds,&errorfds,NULL)==-1) { - if (errno==EINTR) continue; - else perror("select"); break; + FD_SET(0, &readfds); + topsock = 1; + SetSelectForNetworkBuffer(netbuf, &readfds, &writefds, &errorfds, + &topsock); + + if (select(topsock, &readfds, &writefds, &errorfds, NULL) == -1) { + if (errno == EINTR) + continue; + else + perror("select"); + break; } - if (FD_ISSET(0,&readfds)) { - if (fgets(inbuf,sizeof(inbuf),stdin)) { - inbuf[sizeof(inbuf)-1]='\0'; - if (strlen(inbuf)>0) { - if (inbuf[strlen(inbuf)-1]=='\n') inbuf[strlen(inbuf)-1]='\0'; - QueueMessageForSend(netbuf,inbuf); + if (FD_ISSET(0, &readfds)) { + if (fgets(inbuf, sizeof(inbuf), stdin)) { + inbuf[sizeof(inbuf) - 1] = '\0'; + if (strlen(inbuf) > 0) { + if (inbuf[strlen(inbuf) - 1] == '\n') + inbuf[strlen(inbuf) - 1] = '\0'; + QueueMessageForSend(netbuf, inbuf); } - } else break; + } else + break; } - if (RespondToSelect(netbuf,&readfds,&writefds,&errorfds,&doneOK)) { - while((msg=GetWaitingMessage(netbuf))!=NULL) { - g_print("%s\n",msg); g_free(msg); + if (RespondToSelect(netbuf, &readfds, &writefds, &errorfds, &doneOK)) { + while ((msg = GetWaitingMessage(netbuf)) != NULL) { + g_print("%s\n", msg); + g_free(msg); } } - if (!doneOK) break; + if (!doneOK) + break; } ShutdownNetworkBuffer(netbuf); g_free(netbuf); (DIR) diff --git a/src/admin.h b/src/admin.h t@@ -1,23 +1,24 @@ -/* admin.h Header file for dopewars server administration */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * admin.h Header file for dopewars server administration * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __ADMIN_H__ #define __ADMIN_H__ (DIR) diff --git a/src/curses_client.c b/src/curses_client.c t@@ -1,22 +1,24 @@ -/* curses_client.c dopewars client using the (n)curses console library */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * curses_client.c dopewars client using the (n)curses console library * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifdef HAVE_CONFIG_H #include <config.h> t@@ -50,297 +52,353 @@ static SCREEN *cur_screen; #ifdef NETWORKING static enum { - CM_SERVER,CM_PROMPT,CM_META,CM_SINGLE + CM_SERVER, CM_PROMPT, CM_META, CM_SINGLE } ConnectMethod = CM_SERVER; #endif -static gboolean CanFire=FALSE,RunHere=FALSE; +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 */ +/* 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 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 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 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); +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; -static void start_curses(void) { -/* Initialises the curses library for accessing the screen */ - 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); +/* + * 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); } -static void end_curses(void) { -/* Shuts down the curses screen library */ - keypad(stdscr,FALSE); - curs_set(1); - erase(); - refresh(); - endwin(); +/* + * Shuts down the curses screen library. + */ +static void end_curses(void) +{ + keypad(stdscr, FALSE); + curs_set(1); + erase(); + refresh(); + endwin(); } -void ResizeHandle(int sig) { -/* Handles a SIGWINCH signal, which is sent to indicate that the */ -/* size of the curses screen has changed. */ - ResizedFlag=1; +/* + * Handles a SIGWINCH signal, which is sent to indicate that the + * size of the curses screen has changed. + */ +void ResizeHandle(int sig) +{ + ResizedFlag = 1; } -void CheckForResize(Player *Play) { -/* Checks to see if the curses window needs to be resized - i.e. if a */ -/* SIGWINCH signal has been received */ - 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); +/* + * 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(); +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(); } -void display_intro(void) { -/* Displays a dopewars introduction screen */ - GString *text; - attrset(TextAttr); - clear_screen(); - attrset(TitleAttr); - -/* Curses client introduction screen */ - text=g_string_new(_("D O P E W A R S")); - mvaddstr(1,(Width-text->len)/2,text->str); - - attrset(TextAttr); - - mvaddstr(3,1,_("Based on John E. Dell's old Drug Wars game, dopewars " - "is a simulation of an")); - mvaddstr(4,1,_("imaginary drug market. dopewars is an All-American " - "game which features")); - mvaddstr(5,1,_("buying, selling, and trying to get past the cops!")); - - mvaddstr(7,1,_("The first thing you need to do is pay off your " - "debt to the Loan Shark. After")); - mvaddstr(8,1,_("that, your goal is to make as much money as " - "possible (and stay alive)! You")); - mvaddstr(9,1,_("have one month of game time to make your fortune.")); - - mvaddstr(11,18,_("Copyright (C) 1998-2002 Ben Webb " - "ben@bellatrix.pcl.ox.ac.uk")); - g_string_sprintf(text,_("Version %s"),VERSION); - mvaddstr(11,2,text->str); - g_string_assign(text, - _("dopewars is released under the GNU General Public Licence")); - mvaddstr(12,(Width-text->len)/2,text->str); - - mvaddstr(14,7,_("Icons and Graphics Ocelot Mantis")); - mvaddstr(15,7,_("Drug Dealing and Research Dan Wolf")); - mvaddstr(16,7,_("Play Testing Phil Davis " - "Owen Walsh")); - mvaddstr(17,7,_("Extensive Play Testing Katherine Holt " - "Caroline Moore")); - mvaddstr(18,7,_("Constructive Criticism Andrea Elliot-Smith " - "Pete Winn")); - mvaddstr(19,7,_("Unconstructive Criticism James Matthews")); - - mvaddstr(21,3,_("For information on the command line options, type " - "dopewars -h at your")); - mvaddstr(22,1,_("Unix prompt. This will display a help screen, listing " - "the available options.")); - - g_string_free(text,TRUE); - nice_wait(); - attrset(TextAttr); clear_screen(); refresh(); +/* + * Displays a dopewars introduction screen. + */ +void display_intro(void) +{ + GString *text; + + attrset(TextAttr); + clear_screen(); + attrset(TitleAttr); + + /* Curses client introduction screen */ + text = g_string_new(_("D O P E W A R S")); + mvaddstr(1, (Width - text->len) / 2, text->str); + + attrset(TextAttr); + + mvaddstr(3, 1, _("Based on John E. Dell's old Drug Wars game, dopewars " + "is a simulation of an")); + mvaddstr(4, 1, _("imaginary drug market. dopewars is an All-American " + "game which features")); + mvaddstr(5, 1, _("buying, selling, and trying to get past the cops!")); + + mvaddstr(7, 1, _("The first thing you need to do is pay off your " + "debt to the Loan Shark. After")); + mvaddstr(8, 1, _("that, your goal is to make as much money as " + "possible (and stay alive)! You")); + mvaddstr(9, 1, _("have one month of game time to make your fortune.")); + + mvaddstr(11, 18, _("Copyright (C) 1998-2002 Ben Webb " + "ben@bellatrix.pcl.ox.ac.uk")); + g_string_sprintf(text, _("Version %s"), VERSION); + mvaddstr(11, 2, text->str); + g_string_assign(text, _("dopewars is released under the GNU " + "General Public Licence")); + mvaddstr(12, (Width - text->len) / 2, text->str); + + mvaddstr(14, 7, _("Icons and Graphics Ocelot Mantis")); + mvaddstr(15, 7, _("Drug Dealing and Research Dan Wolf")); + mvaddstr(16, 7, _("Play Testing Phil Davis " + "Owen Walsh")); + mvaddstr(17, 7, _("Extensive Play Testing Katherine Holt " + "Caroline Moore")); + mvaddstr(18, 7, _("Constructive Criticism Andrea Elliot-Smith " + "Pete Winn")); + mvaddstr(19, 7, _("Unconstructive Criticism James Matthews")); + + mvaddstr(21, 3, _("For information on the command line options, type " + "dopewars -h at your")); + mvaddstr(22, 1, + _("Unix prompt. This will display a help screen, listing " + "the available options.")); + + g_string_free(text, TRUE); + nice_wait(); + attrset(TextAttr); + clear_screen(); + refresh(); } #ifdef NETWORKING -static void SelectServerManually(void) { -/* Prompts the user to enter a server name and port to connect to */ - 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); +/* + * 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); } -static gboolean SelectServerFromMetaServer(Player *Play,GString *errstr) { -/* 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. */ - 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); +/* + * 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; } - if (FD_ISSET(0,&readfds)) { - /* So that Ctrl-L works */ - c = getch(); + perror("bselect"); + exit(1); + } + if (FD_ISSET(0, &readfds)) { + /* So that Ctrl-L works */ + c = getch(); #ifndef CYGWIN - if (c=='\f') wrefresh(curscr); + if (c == '\f') + wrefresh(curscr); #endif + } + if (RespondToSelect + (&MetaConn->NetBuf, &readfds, &writefds, NULL, &DoneOK)) { + while (HandleWaitingMetaServerData(MetaConn, &ServerList, &DoneOK)) { } - 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; - } + } + if (!DoneOK && HandleHttpCompletion(MetaConn)) { + if (IsHttpError(MetaConn)) { + g_string_assign_error(errstr, MetaConn->NetBuf.error); + CloseHttpConnection(MetaConn); + return FALSE; } - } while (DoneOK); - CloseHttpConnection(MetaConn); + } + } while (DoneOK); + CloseHttpConnection(MetaConn); - text=g_string_new(""); + 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; + 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 oldstatus, + NBSocksStatus oldsocks) +{ NBStatus status; NBSocksStatus sockstat; GString *text; t@@ -348,41 +406,43 @@ static void DisplayConnectStatus(NetworkBuffer *netbuf, status = netbuf->status; sockstat = netbuf->sockstat; - if (oldstatus==status && oldsocks==sockstat) return; + if (oldstatus == status && oldsocks == sockstat) + return; - text=g_string_new(""); + text = g_string_new(""); - switch(status) { - case NBS_PRECONNECT: + 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 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; - } + case NBSS_USERPASSWD: + g_string_assign(text, _("Authenticating with SOCKS server")); break; - case NBS_CONNECTED: + 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); + mvaddstr(17, 1, text->str); refresh(); } - g_string_free(text,TRUE); + g_string_free(text, TRUE); } -void HttpAuthFunc(HttpConnection *conn,gboolean proxyauth, - gchar *realm,gpointer data) { - gchar *text,*user,*password=NULL; +void HttpAuthFunc(HttpConnection *conn, gboolean proxyauth, + gchar *realm, gpointer data) +{ + gchar *text, *user, *password = NULL; attrset(TextAttr); clear_bottom(); t@@ -390,306 +450,358 @@ void HttpAuthFunc(HttpConnection *conn,gboolean proxyauth, text = g_strdup_printf(_("Proxy authentication required for realm %s"), realm); } else { - text = g_strdup_printf(_("Authentication required for realm %s"),realm); + text = + g_strdup_printf(_("Authentication required for realm %s"), realm); } - mvaddstr(17,1,text); - mvaddstr(18,1,_("(Enter a blank username to cancel)")); + 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'); + + user = nice_input(_("User name: "), 19, 1, FALSE, NULL, '\0'); if (user && user[0]) { - password=nice_input(_("Password: "),20,1,FALSE,NULL,'*'); + password = nice_input(_("Password: "), 20, 1, FALSE, NULL, '*'); } - SetHttpAuthentication(conn,proxyauth,user,password); - g_free(user); g_free(password); + SetHttpAuthentication(conn, proxyauth, user, password); + g_free(user); + g_free(password); } -void SocksAuthFunc(NetworkBuffer *netbuf,gpointer data) { - gchar *user,*password=NULL; +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'); + 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,'*'); + password = nice_input(_("Password: "), 19, 1, FALSE, NULL, '*'); } - SendSocks5UserPasswd(netbuf,user,password); - g_free(user); g_free(password); + SendSocks5UserPasswd(netbuf, user, password); + g_free(user); + g_free(password); } -static gboolean DoConnect(Player *Play,GString *errstr) { +static gboolean DoConnect(Player *Play, GString *errstr) +{ NetworkBuffer *netbuf; - fd_set readfds,writefds; - int maxsock,c; - gboolean doneOK=TRUE; + fd_set readfds, writefds; + int maxsock, c; + gboolean doneOK = TRUE; NBStatus oldstatus; NBSocksStatus oldsocks; - netbuf=&Play->NetBuf; + netbuf = &Play->NetBuf; oldstatus = netbuf->status; - oldsocks = netbuf->sockstat; + oldsocks = netbuf->sockstat; - if (!StartNetworkBufferConnect(netbuf,ServerName,Port)) { - doneOK=FALSE; + if (!StartNetworkBufferConnect(netbuf, ServerName, Port)) { + doneOK = FALSE; } else { - SetNetworkBufferUserPasswdFunc(netbuf,SocksAuthFunc,NULL); - while (netbuf->status!=NBS_CONNECTED) { - DisplayConnectStatus(netbuf,oldstatus,oldsocks); + 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); + 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)) { + if (FD_ISSET(0, &readfds)) { /* So that Ctrl-L works */ c = getch(); #ifndef CYGWIN - if (c=='\f') wrefresh(curscr); + if (c == '\f') + wrefresh(curscr); #endif } - RespondToSelect(netbuf,&readfds,&writefds,NULL,&doneOK); + RespondToSelect(netbuf, &readfds, &writefds, NULL, &doneOK); } } - if (!doneOK) g_string_assign_error(errstr,netbuf->error); + if (!doneOK) + g_string_assign_error(errstr, netbuf->error); return doneOK; } -static gboolean ConnectToServer(Player *Play) { -/* 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. */ - 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) { +/* + * 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); - clear_bottom(); - if (MetaOK && !firstrun) { - mvaddstr(17,1, - _("Please wait... attempting to contact dopewars server...")); - refresh(); - NetOK=DoConnect(Play,errstr); + + /* 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; } - 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; + } else + break; + } + g_string_free(errstr, TRUE); + Client = Network = TRUE; + return TRUE; } #endif /* NETWORKING */ -static gboolean jet(Player *Play,gboolean AllowReturn) { -/* 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. */ - int i,c; +/* + * 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); + 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 ? ")); + /* 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); + 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); + return (c != 0); } -static void DropDrugs(Player *Play) { -/* Prompts the user "Play" to drop some of the currently carried drugs */ - int i,c,num,NumDrugs; +/* + * 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(""); + 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); + /* 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? ")); + 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 = 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') { + 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); + 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); + g_string_free(text, TRUE); } -static void DealDrugs(Player *Play,gboolean Buy) { -/* 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. */ - 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++; +/* + * 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? ")); + /* 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? ")); + 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); + 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; + 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); + /* 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); + /* 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); } } t@@ -697,557 +809,657 @@ static void DealDrugs(Player *Play,gboolean Buy) { curs_set(0); } -static void GiveErrand(Player *Play) { -/* Prompts the user (player "Play") to give an errand to one of his/her */ -/* bitches. The decision is relayed to the server for implementation. */ - 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; - } +/* + * 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; + } } -static int want_to_quit(void) { -/* Asks the user if he/she _really_ wants to quit dopewars */ - 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'); +/* + * 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'); } -static void change_name(Player *Play,gboolean nullname) { -/* Prompts the user to change his or her name, and notifies the server */ - gchar *NewName; +/* + * 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'); + /* 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); + 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); } -void HandleClientMessage(char *Message,Player *Play) { -/* 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. */ - 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; - } +/* + * 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; + } } -void PrepareHighScoreScreen(void) { -/* Responds to a "starthiscore" message by clearing the screen and */ -/* displaying the title for the high scores screen */ - 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); +/* + * 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); } -void PrintHighScore(char *Data) { -/* 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. */ - 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 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(); } -void PrintMessage(const gchar *text) { -/* Prints a message "text" received via. a "printmessage" message in the */ -/* bottom part of the screen. */ - guint i,line; +/* + * 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++; + 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]); + 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) { +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); + 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? ")); + 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'; + 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); + /* 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); + text = g_strdup_printf("gun^%d^-1", gunind); + SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text); g_free(text); - print_status(Play,FALSE); + print_status(Play, FALSE); } } } } -static void BuyGun(Player *Play) { +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); + 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? ")); + 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'; + 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); + /* 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); + /* 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); + text = g_strdup_printf("gun^%d^1", gunind); + SendClientMessage(Play, C_NONE, C_BUYOBJECT, NULL, text); g_free(text); - print_status(Play,FALSE); + print_status(Play, FALSE); } } } } -void GunShop(Player *Play) { -/* Allows player "Play" to buy and sell guns interactively. Passes the */ -/* decisions on to the server for sanity checking and implementation. */ - int i,action; +/* + * 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); + 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); + 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? "); + /* 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); + 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); + /* 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); } -void LoanShark(Player *Play) { -/* Allows player "Play" to pay off loans interactively. */ - gchar *text,*prstr; +/* + * 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'); + /* 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!")); + 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))); + SendClientMessage(Play, C_NONE, C_PAYLOAN, NULL, + (prstr = pricetostr(money))); g_free(prstr); - money=0; + money = 0; } - } while (money!=0); + } while (money != 0); } -void Bank(Player *Play) { -/* Allows player "Play" to pay in or withdraw money from the bank */ -/* interactively. */ - gchar *text,*prstr; - price_t 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 ? ")); + /* 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); + /* 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'); + 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!")); + 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...")); + /* 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))); + } else if (money != 0) { + SendClientMessage(Play, C_NONE, C_DEPOSIT, NULL, + (prstr = pricetostr(money))); g_free(prstr); - money=0; + money = 0; } } - } while (action!='L' && money!=0); + } while (action != 'L' && money != 0); } -int GetKey(char *allowed,char *orig_allowed,gboolean AllowOther, - gboolean PrintAllowed,gboolean ExpandOut) { -/* 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. */ +/* + * 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; + 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. */ + /* 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") }; + N_("F:Fight"), N_("A:Attack"), N_("E:Evade") + }; guint numWords = sizeof(Words) / sizeof(Words[0]); gchar *trWord; curs_set(1); - ch='\0'; + ch = '\0'; - if (!allowed || strlen(allowed)==0) return 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); + 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) { + 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]; + curs_set(0); + return orig_allowed[AllowInd]; } } } while (!AllowOther); t@@ -1256,819 +1468,954 @@ int GetKey(char *allowed,char *orig_allowed,gboolean AllowOther, return 0; } -void clear_line(int line) { -/* Clears one whole line on the curses screen */ - int i; - move(line,0); - for (i=0;i<Width;i++) addch(' '); +/* + * 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(' '); } -void clear_exceptfor(int skip) { -/* Clears the bottom of the screen (i.e. from line 16 to line 23) */ -/* except for the top "skip" lines */ - int i; - for (i=16+skip;i<=23;i++) clear_line(i); +/* + * 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); } -void clear_bottom(void) { -/* Clears screen lines 16 to 23 */ - int i; - for (i=16;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); } -void clear_screen(void) { -/* Clears the entire screen; 24 lines of 80 characters each */ - int i; - for (i=0;i<Depth;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); } -void nice_wait() { -/* Displays a prompt on the bottom screen line and waits for the user */ -/* to press a key */ - gchar *text; - attrset(PromptAttr); - text=_("Press any key..."); - mvaddstr(23,(Width-strlen(text))/2,text); - bgetch(); - attrset(TextAttr); +/* + * 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); } -void DisplayFightMessage(Player *Play,char *text) { -/* 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 */ +/* + * 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; + static int x, y; gchar *textpt; - gchar *AttackName,*DefendName,*BitchName; - gint i,DefendHealth,DefendBitches,BitchesKilled,ArmPercent; + 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'; + 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]); + 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); + 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; + 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); + 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); } } } -void display_message(char *buf) { -/* 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 */ - guint x,y; +/* + * 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; + if (Width <= 4) + return; - wid = MIN(Width-4,200); + wid = MIN(Width - 4, 200); if (!buf) { - for (y=0;y<5;y++) { - memset(Messages[y],' ',200); + for (y = 0; y < 5; y++) { + memset(Messages[y], ' ', 200); if (Network) { - mvaddch(y+10,0,' ' | TextAttr); + mvaddch(y + 10, 0, ' ' | TextAttr); addch(ACS_VLINE | StatsAttr); - for (x=0;x<wid;x++) addch(' ' | 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); + 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(); } } -void print_location(char *text) { -/* Displays the string "text" at the top of the screen. Usually used for */ -/* displaying the current location or the "Subway" flash. */ - 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 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); } -void print_status(Player *Play,gboolean DispDrug) { -/* 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. */ - 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++; - } +/* + * 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++; - } + } + } 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); + } + } + attrset(TextAttr); + if (!Network) + clear_line(15); + refresh(); + g_string_free(text, TRUE); } -void DisplaySpyReports(char *Data,Player *From,Player *To) { -/* Parses details about player "From" from string "Data" and then */ -/* displays the lot, drugs and guns. */ - gchar *text; +/* + * 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); + ReceivePlayerData(To, Data, From); - clear_bottom(); - text=g_strdup_printf(_("Spy reports for %s"),GetPlayerName(From)); - mvaddstr(17,1,text); g_free(text); + 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 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(); + /* 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(); + print_status(To, TRUE); + refresh(); } -Player *ListPlayers(Player *Play,gboolean Select,char *Prompt) { -/* 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 *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++; - } +/* + * 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; - 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--; + 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; } - return tmp; - } else { - nice_wait(); - } - return NULL; + c--; + } + return tmp; + } else { + nice_wait(); + } + return NULL; } -char *nice_input(char *prompt,int sy,int sx,gboolean digitsonly, - char *displaystr,char passwdchar) { -/* 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) */ - int i,c,x; - gboolean DecimalPoint,Suffix; +/* + * 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); + DecimalPoint = Suffix = FALSE; + + x = sx; + move(sy, x); if (prompt) { attrset(PromptAttr); addstr(prompt); - x+=strlen(prompt); + x += strlen(prompt); } attrset(TextAttr); if (displaystr) { if (passwdchar) { - for (i=strlen(displaystr);i;i--) addch((guint)passwdchar); + for (i = strlen(displaystr); i; i--) + addch((guint)passwdchar); } else { addstr(displaystr); } - i=strlen(displaystr); - text=g_string_new(displaystr); + i = strlen(displaystr); + text = g_string_new(displaystr); } else { - i=0; - text=g_string_new(""); + 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); + 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); + 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); + 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,'.'); + } 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') + DecimalPoint = TRUE; + } else if (digitsonly + && (c == 'M' || c == 'm' || c == 'k' || c == 'K') && !Suffix) { - g_string_append_c(text,c); + g_string_append_c(text, c); i++; addch((guint)passwdchar ? passwdchar : c); - Suffix=TRUE; + Suffix = TRUE; } } - } while (c!='\n' && c!=KEY_ENTER); + } 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 */ + move(sy, x); + ReturnString = text->str; + g_string_free(text, FALSE); /* Leave the buffer to return */ return ReturnString; } -static void Curses_DoGame(Player *Play) { -/* 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. */ - gchar *buf,*OldName,*TalkMsg; - GString *text; - int i,c; - char IsCarrying; +/* + * 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; + fd_set readfs; #endif #ifdef NETWORKING - fd_set writefs; - gboolean DoneOK; - gchar *pt; - gboolean justconnected=FALSE; + 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); + 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; - } + 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; - } + 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 if (Play->Flags&TRADING) { - g_string_append(text,", T>rade");*/ - } 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; + } + 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); } - refresh(); + 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 (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); + 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; } - if (bselect(MaxSock,&readfs,&writefs,NULL,NULL)==-1) { - if (errno==EINTR) { - CheckForResize(Play); - continue; - } - perror("bselect"); exit(1); + 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 (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 (!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)) { + } + 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); + 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 (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); + 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 + 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); + curs_set(0); + } + g_string_free(text, TRUE); } -void CursesLoop(void) { - char c; - Player *Play; +void CursesLoop(void) +{ + char c; + Player *Play; - if (!CheckHighScoreFileConfig()) return; + if (!CheckHighScoreFileConfig()) + return; - start_curses(); - Width=COLS; Depth=LINES; + start_curses(); + Width = COLS; + Depth = LINES; -/* Set up message handlers */ - ClientMessageHandlerPt = HandleClientMessage; + /* 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); + /* 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(); + 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(); + 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 '_' */ +#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")); +void CursesLoop(void) +{ + g_print(_("No curses client available - rebuild the binary passing the\n" + "--enable-curses-client option to configure, or use a windowed\n" + "client (if available) instead!\n")); } #endif /* CURSES_CLIENT */ (DIR) diff --git a/src/curses_client.h b/src/curses_client.h t@@ -1,23 +1,24 @@ -/* curses_client.h dopewars client using the (n)curses console library */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * curses_client.h dopewars client using the (n)curses console library * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __CURSES_CLIENT_H__ #define __CURSES_CLIENT_H__ (DIR) diff --git a/src/dopeos.c b/src/dopeos.c t@@ -1,23 +1,24 @@ -/* dopeos.c dopewars - operating-system-specific functions */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * dopeos.c dopewars - operating-system-specific functions * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifdef HAVE_CONFIG_H #include <config.h> t@@ -26,260 +27,376 @@ #include "dopeos.h" #include "dopewars.h" -#ifdef CYGWIN /* Code for native Win32 build under Cygwin */ +#ifdef CYGWIN /* Code for native Win32 build under Cygwin */ #include <conio.h> #ifdef GUI_CLIENT #include "gtkport.h" #endif -CHAR_INFO RealScreen[25][80],VirtualScreen[25][80]; -HANDLE hOut,hIn; - -void refresh() { - int y; - COORD size,offset; - SMALL_RECT screenpos; - for (y=0;y<Depth;y++) { - if (memcmp(&RealScreen[y][0],&VirtualScreen[y][0], - sizeof(CHAR_INFO)*Width)!=0) { - memcpy(&RealScreen[y][0],&VirtualScreen[y][0], - Width*sizeof(CHAR_INFO)); - size.X=Width; size.Y=1; - offset.X=offset.Y=0; - screenpos.Left=0; screenpos.Top=y; - screenpos.Right=Width-1; screenpos.Bottom=y; - WriteConsoleOutput(hOut,&VirtualScreen[y][0],size, - offset,&screenpos); - } - } +CHAR_INFO RealScreen[25][80], VirtualScreen[25][80]; +HANDLE hOut, hIn; + +void refresh() +{ + int y; + COORD size, offset; + SMALL_RECT screenpos; + + for (y = 0; y < Depth; y++) { + if (memcmp(&RealScreen[y][0], &VirtualScreen[y][0], + sizeof(CHAR_INFO) * Width) != 0) { + memcpy(&RealScreen[y][0], &VirtualScreen[y][0], + Width * sizeof(CHAR_INFO)); + size.X = Width; + size.Y = 1; + offset.X = offset.Y = 0; + screenpos.Left = 0; + screenpos.Top = y; + screenpos.Right = Width - 1; + screenpos.Bottom = y; + WriteConsoleOutput(hOut, &VirtualScreen[y][0], size, + offset, &screenpos); + } + } } -HANDLE WINAPI GetConHandle(TCHAR *pszName) { - SECURITY_ATTRIBUTES sa; - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; - return CreateFile(pszName,GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, - &sa,OPEN_EXISTING,(DWORD)0,(HANDLE)0); +HANDLE WINAPI GetConHandle(TCHAR *pszName) +{ + SECURITY_ATTRIBUTES sa; + + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = TRUE; + return CreateFile(pszName, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + &sa, OPEN_EXISTING, (DWORD)0, (HANDLE)0); } -WORD CurAttr=0,TextAttr=2<<8,PromptAttr=1<<8,TitleAttr=4<<8; -WORD LocationAttr=3<<8,StatsAttr=5<<8,DebtAttr=6<<8; -int Width,Depth,CurX,CurY; +WORD CurAttr = 0, TextAttr = 2 << 8; +WORD PromptAttr = 1 << 8, TitleAttr = 4 << 8; +WORD LocationAttr = 3 << 8, StatsAttr = 5 << 8, DebtAttr = 6 << 8; +int Width, Depth, CurX, CurY; char *optarg; WORD Attr[10]; HWND hwndMain; -SCREEN *newterm(void *a,void *b,void *c) { - COORD coord; - int i; - coord.X=80; coord.Y=25; - Width=80; Depth=25; CurAttr=TextAttr; CurX=0; CurY=0; - for (i=0;i<10;i++) - Attr[i]=FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN; - hOut=GetConHandle("CONOUT$"); - hIn=GetConHandle("CONIN$"); - SetConsoleMode(hIn,0); -/* SetConsoleScreenBufferSize(hOut,coord);*/ -/* clear_screen();*/ - return NULL; -} - -void start_color() {} -void init_pair(int index,WORD fg,WORD bg) { - if (index>=0 && index<10) { - Attr[index]=0; - switch(fg) { - case COLOR_MAGENTA: Attr[index]|=(FOREGROUND_RED+FOREGROUND_BLUE); - break; - case COLOR_BLUE: Attr[index]|=FOREGROUND_BLUE; - break; - case COLOR_RED: Attr[index]|=FOREGROUND_RED; - break; - case COLOR_WHITE: Attr[index]|=(FOREGROUND_RED+FOREGROUND_BLUE+ - FOREGROUND_GREEN); - break; - } - switch(bg) { - case COLOR_MAGENTA: Attr[index]|=(BACKGROUND_RED+BACKGROUND_BLUE); - break; - case COLOR_BLUE: Attr[index]|=BACKGROUND_BLUE; - break; - case COLOR_RED: Attr[index]|=BACKGROUND_RED; - break; - case COLOR_WHITE: Attr[index]|=(BACKGROUND_RED+BACKGROUND_BLUE+ - BACKGROUND_GREEN); - break; - } - } -} - -void cbreak() {} -void noecho() {} -void nodelay(void *a,char b) {} - -void keypad(void *a,char b) {} -void curs_set(BOOL visible) { - CONSOLE_CURSOR_INFO ConCurInfo; - move(CurY,CurX); - ConCurInfo.dwSize=10; - ConCurInfo.bVisible=visible; - SetConsoleCursorInfo(hOut,&ConCurInfo); -} - -void endwin() { - CurAttr=0; -/* clear_screen(); */ - refresh(); - curs_set(1); -/* CloseHandle(hIn); - CloseHandle(hOut);*/ -} - -void move(int y,int x) { - COORD coord; - CurX=x; CurY=y; - coord.X=x; coord.Y=y; - SetConsoleCursorPosition(hOut,coord); -} - -void attrset(WORD newAttr) { - CurAttr=newAttr; -} - -void addstr(char *str) { - int i; - for (i=0;i<strlen(str);i++) addch(str[i]); - move(CurY,CurX); -} - -void addch(int ch) { - int attr; - VirtualScreen[CurY][CurX].Char.AsciiChar=ch%256; - attr=ch>>8; - if (attr>0) VirtualScreen[CurY][CurX].Attributes=Attr[attr]; - else VirtualScreen[CurY][CurX].Attributes=Attr[CurAttr>>8]; - if (++CurX>=Width) { - CurX=0; - if (++CurY>=Depth) CurY=0; - } -} - -void mvaddstr(int y,int x,char *str) { - move(y,x); addstr(str); -} - -void mvaddch(int y,int x,int ch) { - move(y,x); addch(ch); -} - -int bgetch() { -/* Waits for the user to press a key */ - DWORD NumRead; - char Buffer[10]; - refresh(); - ReadConsole(hIn,Buffer,1,&NumRead,NULL); - return (int)(Buffer[0]); -} - -char *index(const char *str,int ch) { - int i; - for (i=0;i<strlen(str);i++) { if (str[i]==ch) return str+i; } - return NULL; -} - -int apos=0; -int getopt(int argc,char * const argv[],const char *str) { - int i,c; - char *pt; - while (apos<argc && argv[apos]) { - if (argv[apos][0]!='-') { apos++; return 0; } - for (i=1;i<strlen(argv[apos]);i++) { - c=argv[apos][i]; - pt=index(str,c); - if (pt) { - argv[apos][i]='-'; - if (*(pt+1)==':') { - if (apos+1<argc && i==strlen(argv[apos])-1) { - apos++; - optarg=argv[apos]; - apos++; - } else return 0; - } - return c; - } - } +SCREEN *newterm(void *a, void *b, void *c) +{ + COORD coord; + int i; + + coord.X = 80; + coord.Y = 25; + Width = 80; + Depth = 25; + CurAttr = TextAttr; + CurX = 0; + CurY = 0; + for (i = 0; i < 10; i++) + Attr[i] = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN; + hOut = GetConHandle("CONOUT$"); + hIn = GetConHandle("CONIN$"); + SetConsoleMode(hIn, 0); + return NULL; +} + +void start_color() +{ +} + +void init_pair(int index, WORD fg, WORD bg) +{ + if (index >= 0 && index < 10) { + Attr[index] = 0; + switch (fg) { + case COLOR_MAGENTA: + Attr[index] |= (FOREGROUND_RED + FOREGROUND_BLUE); + break; + case COLOR_BLUE: + Attr[index] |= FOREGROUND_BLUE; + break; + case COLOR_RED: + Attr[index] |= FOREGROUND_RED; + break; + case COLOR_WHITE: + Attr[index] |= (FOREGROUND_RED + FOREGROUND_BLUE + FOREGROUND_GREEN); + break; + } + switch (bg) { + case COLOR_MAGENTA: + Attr[index] |= (BACKGROUND_RED + BACKGROUND_BLUE); + break; + case COLOR_BLUE: + Attr[index] |= BACKGROUND_BLUE; + break; + case COLOR_RED: + Attr[index] |= BACKGROUND_RED; + break; + case COLOR_WHITE: + Attr[index] |= (BACKGROUND_RED + BACKGROUND_BLUE + BACKGROUND_GREEN); + break; + } + } +} + +void cbreak() +{ +} + +void noecho() +{ +} + +void nodelay(void *a, char b) +{ +} + +void keypad(void *a, char b) +{ +} + +void curs_set(BOOL visible) +{ + CONSOLE_CURSOR_INFO ConCurInfo; + + move(CurY, CurX); + ConCurInfo.dwSize = 10; + ConCurInfo.bVisible = visible; + SetConsoleCursorInfo(hOut, &ConCurInfo); +} + +void endwin() +{ + CurAttr = 0; + refresh(); + curs_set(1); +} + +void move(int y, int x) +{ + COORD coord; + + CurX = x; + CurY = y; + coord.X = x; + coord.Y = y; + SetConsoleCursorPosition(hOut, coord); +} + +void attrset(WORD newAttr) +{ + CurAttr = newAttr; +} + +void addstr(char *str) +{ + int i; + + for (i = 0; i < strlen(str); i++) + addch(str[i]); + move(CurY, CurX); +} + +void addch(int ch) +{ + int attr; + + VirtualScreen[CurY][CurX].Char.AsciiChar = ch % 256; + attr = ch >> 8; + if (attr > 0) + VirtualScreen[CurY][CurX].Attributes = Attr[attr]; + else + VirtualScreen[CurY][CurX].Attributes = Attr[CurAttr >> 8]; + if (++CurX >= Width) { + CurX = 0; + if (++CurY >= Depth) + CurY = 0; + } +} + +void mvaddstr(int y, int x, char *str) +{ + move(y, x); + addstr(str); +} + +void mvaddch(int y, int x, int ch) +{ + move(y, x); + addch(ch); +} + +/* + * Waits for the user to press a key. + */ +int bgetch() +{ + DWORD NumRead; + char Buffer[10]; + + refresh(); + ReadConsole(hIn, Buffer, 1, &NumRead, NULL); + return (int)(Buffer[0]); +} + +char *index(const char *str, int ch) +{ + int i; + + for (i = 0; i < strlen(str); i++) { + if (str[i] == ch) + return str + i; + } + return NULL; +} + +static int apos = 0; + +int getopt(int argc, char *const argv[], const char *str) +{ + int i, c; + char *pt; + + while (apos < argc && argv[apos]) { + if (argv[apos][0] != '-') { apos++; - } - return EOF; + return 0; + } + for (i = 1; i < strlen(argv[apos]); i++) { + c = argv[apos][i]; + pt = index(str, c); + if (pt) { + argv[apos][i] = '-'; + if (*(pt + 1) == ':') { + if (apos + 1 < argc && i == strlen(argv[apos]) - 1) { + apos++; + optarg = argv[apos]; + apos++; + } else + return 0; + } + return c; + } + } + apos++; + } + return EOF; +} + +void sigemptyset(int *mask) +{ +} + +void sigaddset(int *mask, int sig) +{ +} + +int sigaction(int sig, struct sigaction *sact, char *pt) +{ + return 0; +} + +void sigprocmask(int flag, int *mask, char *pt) +{ +} + +void standout() +{ } -void sigemptyset(int *mask) {} -void sigaddset(int *mask,int sig) {} -int sigaction(int sig,struct sigaction *sact,char *pt) { return 0; } -void sigprocmask(int flag,int *mask,char *pt) {} -void standout() {} -void standend() {} +void standend() +{ +} -gboolean IsKeyPressed() { +gboolean IsKeyPressed() +{ INPUT_RECORD ConsoleIn; DWORD NumConsoleIn; - while (PeekConsoleInput(hIn,&ConsoleIn,1,&NumConsoleIn) && NumConsoleIn==1) { - if (ConsoleIn.EventType==KEY_EVENT && ConsoleIn.Event.KeyEvent.bKeyDown) { + + while (PeekConsoleInput(hIn, &ConsoleIn, 1, &NumConsoleIn) + && NumConsoleIn == 1) { + if (ConsoleIn.EventType == KEY_EVENT + && ConsoleIn.Event.KeyEvent.bKeyDown) { return TRUE; } else { - ReadConsoleInput(hIn,&ConsoleIn,1,&NumConsoleIn); + ReadConsoleInput(hIn, &ConsoleIn, 1, &NumConsoleIn); } } return FALSE; } -int bselect(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfds, - struct timeval *tm) { - int retval; - struct timeval tv,*tp; - fd_set localread,localexcept; - char CheckKbHit=0,KeyRead; - if (nfds==0 && tm) { Sleep(tm->tv_sec*1000+tm->tv_usec/1000); return 0; } - if (FD_ISSET(0,readfds)) { - if (nfds==1) return 1; - tp=&tv; - CheckKbHit=1; - FD_CLR(0,readfds); - } else tp=tm; - KeyRead=0; - while (1) { - tv.tv_sec=0; - tv.tv_usec=250000; - - if (readfds) memcpy(&localread,readfds,sizeof(fd_set)); - if (exceptfds) memcpy(&localexcept,exceptfds,sizeof(fd_set)); - if (CheckKbHit && IsKeyPressed()) tv.tv_usec=0; - retval=select(nfds,readfds,writefds,exceptfds,tp); - if (retval==SOCKET_ERROR) return retval; - if (CheckKbHit && IsKeyPressed()) { - retval++; FD_SET(0,readfds); - } - if (retval>0 || !CheckKbHit) break; - if (CheckKbHit && tm) { - if (tm->tv_usec >= 250000) tm->tv_usec-=250000; - else if (tm->tv_sec) { - tm->tv_usec+=750000; - tm->tv_sec--; - } else break; - } - if (readfds) memcpy(readfds,&localread,sizeof(fd_set)); - if (exceptfds) memcpy(exceptfds,&localexcept,sizeof(fd_set)); - } - return retval; +int bselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *tm) +{ + int retval; + struct timeval tv, *tp; + fd_set localread, localexcept; + char CheckKbHit = 0, KeyRead; + + if (nfds == 0 && tm) { + Sleep(tm->tv_sec * 1000 + tm->tv_usec / 1000); + return 0; + } + if (FD_ISSET(0, readfds)) { + if (nfds == 1) + return 1; + tp = &tv; + CheckKbHit = 1; + FD_CLR(0, readfds); + } else + tp = tm; + KeyRead = 0; + while (1) { + tv.tv_sec = 0; + tv.tv_usec = 250000; + + if (readfds) + memcpy(&localread, readfds, sizeof(fd_set)); + if (exceptfds) + memcpy(&localexcept, exceptfds, sizeof(fd_set)); + if (CheckKbHit && IsKeyPressed()) + tv.tv_usec = 0; + retval = select(nfds, readfds, writefds, exceptfds, tp); + if (retval == SOCKET_ERROR) + return retval; + if (CheckKbHit && IsKeyPressed()) { + retval++; + FD_SET(0, readfds); + } + if (retval > 0 || !CheckKbHit) + break; + if (CheckKbHit && tm) { + if (tm->tv_usec >= 250000) + tm->tv_usec -= 250000; + else if (tm->tv_sec) { + tm->tv_usec += 750000; + tm->tv_sec--; + } else + break; + } + if (readfds) + memcpy(readfds, &localread, sizeof(fd_set)); + if (exceptfds) + memcpy(exceptfds, &localexcept, sizeof(fd_set)); + } + return retval; } /* We don't do locking under Win32 right now */ -int ReadLock(FILE *fp) { return 0; } -int WriteLock(FILE *fp) { return 0; } -void ReleaseLock(FILE *fp) { } +int ReadLock(FILE * fp) +{ + return 0; +} + +int WriteLock(FILE * fp) +{ + return 0; +} + +void ReleaseLock(FILE * fp) +{ +} #else /* Code for Unix build */ t@@ -295,50 +412,71 @@ void ReleaseLock(FILE *fp) { } #include <fcntl.h> #endif -int Width,Depth; +int Width, Depth; #ifdef CURSES_CLIENT -int bgetch() { -/* Calls the curses getch() function; if the key pressed is Ctrl-L */ -/* then automatically clears and redraws the screen, otherwise */ -/* passes the key back to the calling routine */ - int c; - c=getch(); - while (c=='\f') { - wrefresh(curscr); - c=getch(); - } - return c; +/* + * Calls the curses getch() function; if the key pressed is Ctrl-L + * then automatically clears and redraws the screen, otherwise + * passes the key back to the calling routine. + */ +int bgetch() +{ + int c; + + c = getch(); + while (c == '\f') { + wrefresh(curscr); + c = getch(); + } + return c; } #endif -static int DoLock(FILE *fp,int l_type) { - struct flock lk; +static int DoLock(FILE * fp, int l_type) +{ + struct flock lk; - lk.l_type = l_type; - lk.l_whence = lk.l_start = lk.l_len = 0; - lk.l_pid = 0; + lk.l_type = l_type; + lk.l_whence = lk.l_start = lk.l_len = 0; + lk.l_pid = 0; - while(1) { - if (fcntl(fileno(fp),F_SETLKW,&lk)==0) return 0; - else if (errno!=EINTR) return 1; - } - return 1; + while (1) { + if (fcntl(fileno(fp), F_SETLKW, &lk) == 0) + return 0; + else if (errno != EINTR) + return 1; + } + return 1; } -int ReadLock(FILE *fp) { return DoLock(fp,F_RDLCK); } -int WriteLock(FILE *fp) { return DoLock(fp,F_WRLCK); } -void ReleaseLock(FILE *fp) { DoLock(fp,F_UNLCK); } +int ReadLock(FILE * fp) +{ + return DoLock(fp, F_RDLCK); +} + +int WriteLock(FILE * fp) +{ + return DoLock(fp, F_WRLCK); +} + +void ReleaseLock(FILE * fp) +{ + DoLock(fp, F_UNLCK); +} #endif /* CYGWIN */ -void MicroSleep(int microsec) { -/* On systems with select, sleep for "microsec" microseconds */ +/* + * On systems with select, sleep for "microsec" microseconds. + */ +void MicroSleep(int microsec) +{ #if HAVE_SELECT - struct timeval tv; - tv.tv_sec=0; - tv.tv_usec=microsec; - bselect(0,NULL,NULL,NULL,&tv); + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = microsec; + bselect(0, NULL, NULL, NULL, &tv); #endif } - (DIR) diff --git a/src/dopeos.h b/src/dopeos.h t@@ -1,23 +1,25 @@ -/* dopeos.h dopewars - operating system-specific function */ -/* definitions */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * dopeos.h dopewars - operating system-specific function * + * definitions * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __DOPEOS_H__ #define __DOPEOS_H__ t@@ -26,16 +28,17 @@ #include <config.h> #endif -#ifdef CYGWIN /* Definitions for native Win32 build */ +#ifdef CYGWIN /* Definitions for native Win32 build */ #include <windows.h> #include <string.h> #include <stdio.h> void refresh(); -HANDLE WINAPI GetConHandle (TCHAR * pszName); -extern WORD TextAttr,PromptAttr,TitleAttr,LocationAttr,StatsAttr,DebtAttr; -extern int Width,Depth; +HANDLE WINAPI GetConHandle(TCHAR *pszName); +extern WORD TextAttr, PromptAttr, TitleAttr; +extern WORD LocationAttr, StatsAttr, DebtAttr; +extern int Width, Depth; #define COLOR_MAGENTA 1 #define COLOR_BLACK 2 t@@ -43,70 +46,72 @@ extern int Width,Depth; #define COLOR_BLUE 4 #define COLOR_RED 5 -#define SIGWINCH 0 -#define SIGPIPE 0 -#define SIG_BLOCK 0 -#define SIG_UNBLOCK 0 +#define SIGWINCH 0 +#define SIGPIPE 0 +#define SIG_BLOCK 0 +#define SIG_UNBLOCK 0 struct sigaction { - void *sa_handler; - int sa_flags; - int sa_mask; + void *sa_handler; + int sa_flags; + int sa_mask; }; void sigemptyset(int *mask); -void sigaddset(int *mask,int sig); -int sigaction(int sig,struct sigaction *sact,char *pt); -void sigprocmask(int flag,int *mask,char *pt); +void sigaddset(int *mask, int sig); +int sigaction(int sig, struct sigaction *sact, char *pt); +void sigprocmask(int flag, int *mask, char *pt); #define COLS Width #define LINES Depth -#define ACS_VLINE 179 -#define ACS_ULCORNER 218 -#define ACS_HLINE 196 -#define ACS_URCORNER 191 -#define ACS_TTEE 194 -#define ACS_LLCORNER 192 -#define ACS_LRCORNER 217 -#define ACS_BTEE 193 -#define ACS_LTEE 195 -#define ACS_RTEE 180 +#define ACS_VLINE 179 +#define ACS_ULCORNER 218 +#define ACS_HLINE 196 +#define ACS_URCORNER 191 +#define ACS_TTEE 194 +#define ACS_LLCORNER 192 +#define ACS_LRCORNER 217 +#define ACS_BTEE 193 +#define ACS_LTEE 195 +#define ACS_RTEE 180 typedef int SCREEN; -#define stdscr 0 -#define curscr 0 + +#define stdscr 0 +#define curscr 0 #define KEY_ENTER 13 #define KEY_BACKSPACE 8 #define A_BOLD 0 -SCREEN *newterm(void *,void *,void *); +SCREEN *newterm(void *, void *, void *); void start_color(); -void init_pair(int index,WORD fg,WORD bg); +void init_pair(int index, WORD fg, WORD bg); void cbreak(); void noecho(); -void nodelay(void *,char); -void keypad(void *,char); +void nodelay(void *, char); +void keypad(void *, char); void curs_set(BOOL visible); void endwin(); -void move(int y,int x); +void move(int y, int x); void attrset(WORD newAttr); void addstr(char *str); void addch(int ch); -void mvaddstr(int x,int y,char *str); -void mvaddch(int x,int y,int ch); +void mvaddstr(int x, int y, char *str); +void mvaddch(int x, int y, int ch); int bgetch(); + #define erase() clear_screen() -char *index(const char *str,int ch); -int getopt(int argc,char * const argv[],const char *str); +char *index(const char *str, int ch); +int getopt(int argc, char *const argv[], const char *str); extern char *optarg; typedef int ssize_t; void standout(); void standend(); void endwin(); -int bselect(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfs, - struct timeval *tm); +int bselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfs, + struct timeval *tm); #else /* Definitions for Unix build */ t@@ -129,7 +134,7 @@ int bselect(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfs, #include <curses_colr/curses.h> #endif -extern int Width,Depth; +extern int Width, Depth; #define PromptAttr (COLOR_PAIR(1)) #define TextAttr (COLOR_PAIR(2)) t@@ -151,9 +156,9 @@ int bgetch(void); void MicroSleep(int microsec); -int ReadLock(FILE *fp); -int WriteLock(FILE *fp); -void ReleaseLock(FILE *fp); +int ReadLock(FILE * fp); +int WriteLock(FILE * fp); +void ReleaseLock(FILE * fp); /* Now make definitions if they haven't been done properly */ #ifndef WEXITSTATUS (DIR) diff --git a/src/dopewars.c b/src/dopewars.c t@@ -1,22 +1,24 @@ -/* dopewars.c dopewars - general purpose routines and initialisation */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * dopewars.c dopewars - general purpose routines and init * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #define _GNU_SOURCE t@@ -55,1411 +57,1709 @@ #include "gtkport.h" #endif -int ClientSock,ListenSock; -gboolean Network,Client,Server,NotifyMetaServer,AIPlayer; -/* dopewars acting as standalone TCP server: - Network=Server=TRUE Client=FALSE - dopewars acting as client, connecting to standalone server: - Network=Client=TRUE Server=FALSE - dopewars in single-player or antique mode: - Network=Server=Client=FALSE -*/ -unsigned Port=7902; -gboolean Sanitized,ConfigVerbose,DrugValue; -gchar *HiScoreFile=NULL,*ServerName=NULL,*ConvertFile=NULL; -gboolean WantHelp,WantVersion,WantAntique,WantColour,WantNetwork, - WantConvert,WantAdmin; +int ClientSock, ListenSock; +gboolean Network, Client, Server, NotifyMetaServer, AIPlayer; + +/* + * dopewars acting as standalone TCP server: + * Network=Server=TRUE Client=FALSE + * dopewars acting as client, connecting to standalone server: + * Network=Client=TRUE Server=FALSE + * dopewars in single-player or antique mode: + * Network=Server=Client=FALSE + */ +unsigned Port = 7902; +gboolean Sanitized, ConfigVerbose, DrugValue; +gchar *HiScoreFile = NULL, *ServerName = NULL, *ConvertFile = NULL; +gboolean WantHelp, WantVersion, WantAntique, WantColour, WantNetwork; +gboolean WantConvert, WantAdmin; #ifdef CYGWIN -gboolean MinToSysTray=TRUE; +gboolean MinToSysTray = TRUE; #else -gboolean Daemonize=TRUE; +gboolean Daemonize = TRUE; #endif gchar *WebBrowser = NULL; -gint ConfigErrors=0; +gint ConfigErrors = 0; ClientType WantedClient; -int NumLocation=0,NumGun=0,NumCop=0,NumDrug=0,NumSubway=0, - NumPlaying=0,NumStoppedTo=0; +int NumLocation = 0, NumGun = 0, NumCop = 0, NumDrug = 0, NumSubway = 0; +int NumPlaying = 0, NumStoppedTo = 0; Player Noone; -int LoanSharkLoc=DEFLOANSHARK,BankLoc=DEFBANK,GunShopLoc=DEFGUNSHOP, - RoughPubLoc=DEFROUGHPUB; -int DrugSortMethod=DS_ATOZ; -int FightTimeout=5,IdleTimeout=14400,ConnectTimeout=300; -int MaxClients=20,AITurnPause=5; -price_t StartCash=2000,StartDebt=5500; -GSList *ServerList=NULL; +int LoanSharkLoc = DEFLOANSHARK, BankLoc = DEFBANK, GunShopLoc = + DEFGUNSHOP; +int RoughPubLoc = DEFROUGHPUB; +int DrugSortMethod = DS_ATOZ; +int FightTimeout = 5, IdleTimeout = 14400, ConnectTimeout = 300; +int MaxClients = 20, AITurnPause = 5; +price_t StartCash = 2000, StartDebt = 5500; +GSList *ServerList = NULL; GScannerConfig ScannerConfig = { - " \t\n", /* Ignore these characters */ - G_CSET_a_2_z "_" G_CSET_A_2_Z, /* Valid characters for starting - an identifier */ - G_CSET_a_2_z "._-0123456789" G_CSET_A_2_Z, /* Valid characters for - continuing an identifier */ - "#\n", /* Single line comments start with # and end with \n */ - FALSE, /* Are symbols case sensitive? */ - TRUE, /* Ignore C-style comments? */ - TRUE, /* Ignore single-line comments? */ - TRUE, /* Treat C-style comments as single tokens - do not break into - words? */ - TRUE, /* Read identifiers as tokens? */ - TRUE, /* Read single-character identifiers as 1-character strings? */ - TRUE, /* Allow the parsing of NULL as the G_TOKEN_IDENTIFIER_NULL ? */ - FALSE, /* Allow symbols (defined by g_scanner_scope_add_symbol) ? */ - TRUE, /* Allow binary numbers in 0b1110 format ? */ - TRUE, /* Allow octal numbers in C-style e.g. 034 ? */ - FALSE, /* Allow floats? */ - TRUE, /* Allow hex numbers in C-style e.g. 0xFF ? */ - TRUE, /* Allow hex numbers in $FF format ? */ - TRUE, /* Allow '' strings (no escaping) ? */ - TRUE, /* Allow "" strings (\ escapes parsed) ? */ - TRUE, /* Convert octal, binary and hex to int? */ - FALSE, /* Convert ints to floats? */ - FALSE, /* Treat all identifiers as strings? */ - TRUE, /* Leave single characters (e.g. {,=) unchanged, instead of - returning G_TOKEN_CHAR ? */ - FALSE, /* Replace read symbols with the token given by their value, instead - of G_TOKEN_SYMBOL ? */ - FALSE /* scope_0_fallback... */ + " \t\n", /* Ignore these characters */ + + /* Valid characters for starting an identifier */ + G_CSET_a_2_z "_" G_CSET_A_2_Z, + + /* Valid characters for continuing an identifier */ + G_CSET_a_2_z "._-0123456789" G_CSET_A_2_Z, + + "#\n", /* Single line comments start with # and + * end with \n */ + FALSE, /* Are symbols case sensitive? */ + TRUE, /* Ignore C-style comments? */ + TRUE, /* Ignore single-line comments? */ + TRUE, /* Treat C-style comments as single tokens + * - do not break into words? */ + TRUE, /* Read identifiers as tokens? */ + TRUE, /* Read single-character identifiers as + * 1-character strings? */ + TRUE, /* Allow the parsing of NULL as the + * G_TOKEN_IDENTIFIER_NULL ? */ + FALSE, /* Allow symbols (defined by + * g_scanner_scope_add_symbol) ? */ + TRUE, /* Allow binary numbers in 0b1110 format ? */ + TRUE, /* Allow octal numbers in C-style e.g. 034 ? */ + FALSE, /* Allow floats? */ + TRUE, /* Allow hex numbers in C-style e.g. 0xFF ? */ + TRUE, /* Allow hex numbers in $FF format ? */ + TRUE, /* Allow '' strings (no escaping) ? */ + TRUE, /* Allow "" strings (\ escapes parsed) ? */ + TRUE, /* Convert octal, binary and hex to int? */ + FALSE, /* Convert ints to floats? */ + FALSE, /* Treat all identifiers as strings? */ + TRUE, /* Leave single characters (e.g. {,=) + * unchanged, instead of returning + * G_TOKEN_CHAR ? */ + FALSE, /* Replace read symbols with the token + * given by their value, instead of + * G_TOKEN_SYMBOL ? */ + FALSE /* scope_0_fallback... */ }; -struct LOCATION StaticLocation,*Location=NULL; -struct DRUG StaticDrug,*Drug=NULL; -struct GUN StaticGun,*Gun=NULL; -struct COP StaticCop,*Cop=NULL; -struct NAMES Names = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, - NULL,NULL,NULL,NULL }; +struct LOCATION StaticLocation, *Location = NULL; +struct DRUG StaticDrug, *Drug = NULL; +struct GUN StaticGun, *Gun = NULL; +struct COP StaticCop, *Cop = NULL; +struct NAMES Names = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; /* N.B. The slightly over-enthusiastic comments here are for the benefit - of translators ;) */ + * of translators ;) */ struct NAMES DefaultNames = { -/* Name of a single bitch - if you need to use different words for "bitch" - depending on where in the sentence it occurs (e.g. subject or object) - then read doc/i18n.html about the %tde (etc.) notation. N.B. This - notation can be used for most of the translatable strings in dopewars. */ - N_("bitch"), -/* Word used for two or more bitches */ - N_("bitches"), -/* Word used for a single gun */ - N_("gun"), -/* Word used for two or more guns */ - N_("guns"), -/* Word used for a single drug */ - N_("drug"), -/* Word used for two or more drugs */ - N_("drugs"), -/* Text that is printed before the turn number. In US mm-dd-yyyy date - notation, with MaxTurns at 31 or less, this works out as the month - - i.e. December in this case */ - N_("12-"), -/* Text that is printed _after_ the turn number (the year, in US notation) */ - N_("-1984"), -/* Names of the loan shark, the bank, the gun shop, and the pub, respectively */ - N_("the Loan Shark"),N_("the Bank"), - N_("Dan\'s House of Guns"),N_("the pub") + /* Name of a single bitch - if you need to use different words for + * "bitch" depending on where in the sentence it occurs (e.g. subject or + * object) then read doc/i18n.html about the %tde (etc.) notation. N.B. + * This notation can be used for most of the translatable strings in + * dopewars. */ + N_("bitch"), + /* Word used for two or more bitches */ + N_("bitches"), + /* Word used for a single gun */ + N_("gun"), + /* Word used for two or more guns */ + N_("guns"), + /* Word used for a single drug */ + N_("drug"), + /* Word used for two or more drugs */ + N_("drugs"), + /* Text that is printed before the turn number. In US mm-dd-yyyy date + * notation, with MaxTurns at 31 or less, this works out as the month - + * i.e. December in this case */ + N_("12-"), + /* Text that is printed _after_ the turn number (the year, in US + * notation) */ + N_("-1984"), + /* Names of the loan shark, the bank, the gun shop, and the pub, + * respectively */ + N_("the Loan Shark"), N_("the Bank"), + N_("Dan\'s House of Guns"), N_("the pub") }; struct CURRENCY Currency; struct PRICES Prices = { - 20000,10000 + 20000, 10000 }; struct BITCH Bitch = { - 50000,150000 + 50000, 150000 }; #ifdef NETWORKING -struct METASERVER MetaServer = { FALSE,NULL,0,NULL,0,NULL,NULL,NULL, - NULL,FALSE,NULL,NULL,NULL,NULL }; +struct METASERVER MetaServer = { + FALSE, NULL, 0, NULL, 0, NULL, NULL, NULL, + NULL, FALSE, NULL, NULL, NULL, NULL +}; struct METASERVER DefaultMetaServer = { - TRUE,"dopewars.sourceforge.net",80,"",8080,"/metaserver.php", - "","","dopewars server", FALSE, "", "", "", "" + TRUE, "dopewars.sourceforge.net", 80, "", 8080, "/metaserver.php", + "", "", "dopewars server", FALSE, "", "", "", "" }; -SocksServer Socks = { NULL,0,0,FALSE,NULL,NULL,NULL }; +SocksServer Socks = { NULL, 0, 0, FALSE, NULL, NULL, NULL }; gboolean UseSocks; #endif -int NumTurns=31; +int NumTurns = 31; -int PlayerArmour=100,BitchArmour=50; +int PlayerArmour = 100, BitchArmour = 50; struct LOG Log; struct GLOBALS Globals[] = { -/* The following strings are the helptexts for all the options that can be - set in a dopewars configuration file, or in the server. See - doc/configfile.html for more detailed explanations. */ - { &Port,NULL,NULL,NULL,NULL,"Port",N_("Network port to connect to"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&HiScoreFile,NULL,"HiScoreFile", - N_("Name of the high score file"),NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&ServerName,NULL,"Server", - N_("Name of the server to connect to"),NULL,NULL,0,"",NULL,NULL }, + /* The following strings are the helptexts for all the options that can + * be set in a dopewars configuration file, or in the server. See + * doc/configfile.html for more detailed explanations. */ + {&Port, NULL, NULL, NULL, NULL, "Port", N_("Network port to connect to"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &HiScoreFile, NULL, "HiScoreFile", + N_("Name of the high score file"), NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &ServerName, NULL, "Server", + N_("Name of the server to connect to"), NULL, NULL, 0, "", NULL, NULL}, #ifdef NETWORKING - { NULL,&UseSocks,NULL,NULL,NULL,"Socks.Active", - N_("TRUE if a SOCKS server should be used for networking"), - NULL,NULL,0,"",NULL,NULL }, + {NULL, &UseSocks, NULL, NULL, NULL, "Socks.Active", + N_("TRUE if a SOCKS server should be used for networking"), + NULL, NULL, 0, "", NULL, NULL}, #ifndef CYGWIN - { NULL,&Socks.numuid,NULL,NULL,NULL,"Socks.NumUID", - N_("TRUE if numeric user IDs should be used for SOCKS4"), - NULL,NULL,0,"",NULL,NULL }, + {NULL, &Socks.numuid, NULL, NULL, NULL, "Socks.NumUID", + N_("TRUE if numeric user IDs should be used for SOCKS4"), + NULL, NULL, 0, "", NULL, NULL}, #endif - { NULL,NULL,NULL,&Socks.user,NULL,"Socks.User", - N_("If not blank, the username to use for SOCKS4"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Socks.name,NULL,"Socks.Name", - N_("The hostname of a SOCKS server to use"), - NULL,NULL,0,"",NULL,NULL }, - { &Socks.port,NULL,NULL,NULL,NULL,"Socks.Port", - N_("The port number of a SOCKS server to use"), - NULL,NULL,0,"",NULL,NULL }, - { &Socks.version,NULL,NULL,NULL,NULL,"Socks.Version", - N_("The version of the SOCKS protocol to use (4 or 5)"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Socks.authuser,NULL,"Socks.Auth.User", - N_("Username for SOCKS5 authentication"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Socks.authpassword,NULL,"Socks.Auth.Password", - N_("Password for SOCKS5 authentication"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,&MetaServer.Active,NULL,NULL,NULL,"MetaServer.Active", - N_("TRUE if server should report to a metaserver"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&MetaServer.Name,NULL,"MetaServer.Name", - N_("Metaserver name to report/get server details to/from"), - NULL,NULL,0,"",NULL,NULL }, - { &MetaServer.Port,NULL,NULL,NULL,NULL,"MetaServer.Port", - N_("Port for metaserver communication"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&MetaServer.ProxyName,NULL,"MetaServer.ProxyName", - N_("Name of a proxy for metaserver communication"), - NULL,NULL,0,"",NULL,NULL }, - { &MetaServer.ProxyPort,NULL,NULL,NULL,NULL,"MetaServer.ProxyPort", - N_("Port for communicating with the proxy server"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&MetaServer.Path,NULL,"MetaServer.Path", - N_("Path of the script on the metaserver"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&MetaServer.LocalName,NULL,"MetaServer.LocalName", - N_("Preferred hostname of your server machine"),NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&MetaServer.Password,NULL,"MetaServer.Password", - N_("Authentication for LocalName with the metaserver"),NULL,NULL,0,"",NULL, - NULL }, - { NULL,NULL,NULL,&MetaServer.Comment,NULL,"MetaServer.Comment", - N_("Server description, reported to the metaserver"),NULL,NULL,0,"",NULL, - NULL }, - { NULL,&MetaServer.UseSocks,NULL,NULL,NULL,"MetaServer.UseSocks", - N_("If TRUE, use SOCKS for metaserver communication"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&MetaServer.authuser,NULL,"MetaServer.Auth.User", - N_("Username for HTTP Basic authentication"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&MetaServer.authpassword,NULL,"MetaServer.Auth.Password", - N_("Password for HTTP Basic authentication"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&MetaServer.proxyuser,NULL,"MetaServer.Proxy.User", - N_("Username for HTTP Basic proxy authentication"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&MetaServer.proxypassword,NULL, - "MetaServer.Proxy.Password", - N_("Password for HTTP Basic proxy authentication"), - NULL,NULL,0,"",NULL,NULL }, + {NULL, NULL, NULL, &Socks.user, NULL, "Socks.User", + N_("If not blank, the username to use for SOCKS4"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &Socks.name, NULL, "Socks.Name", + N_("The hostname of a SOCKS server to use"), + NULL, NULL, 0, "", NULL, NULL}, + {&Socks.port, NULL, NULL, NULL, NULL, "Socks.Port", + N_("The port number of a SOCKS server to use"), + NULL, NULL, 0, "", NULL, NULL}, + {&Socks.version, NULL, NULL, NULL, NULL, "Socks.Version", + N_("The version of the SOCKS protocol to use (4 or 5)"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &Socks.authuser, NULL, "Socks.Auth.User", + N_("Username for SOCKS5 authentication"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &Socks.authpassword, NULL, "Socks.Auth.Password", + N_("Password for SOCKS5 authentication"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, &MetaServer.Active, NULL, NULL, NULL, "MetaServer.Active", + N_("TRUE if server should report to a metaserver"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &MetaServer.Name, NULL, "MetaServer.Name", + N_("Metaserver name to report/get server details to/from"), + NULL, NULL, 0, "", NULL, NULL}, + {&MetaServer.Port, NULL, NULL, NULL, NULL, "MetaServer.Port", + N_("Port for metaserver communication"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &MetaServer.ProxyName, NULL, "MetaServer.ProxyName", + N_("Name of a proxy for metaserver communication"), + NULL, NULL, 0, "", NULL, NULL}, + {&MetaServer.ProxyPort, NULL, NULL, NULL, NULL, "MetaServer.ProxyPort", + N_("Port for communicating with the proxy server"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &MetaServer.Path, NULL, "MetaServer.Path", + N_("Path of the script on the metaserver"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &MetaServer.LocalName, NULL, "MetaServer.LocalName", + N_("Preferred hostname of your server machine"), NULL, NULL, 0, "", + NULL, NULL}, + {NULL, NULL, NULL, &MetaServer.Password, NULL, "MetaServer.Password", + N_("Authentication for LocalName with the metaserver"), NULL, NULL, 0, + "", NULL, NULL}, + {NULL, NULL, NULL, &MetaServer.Comment, NULL, "MetaServer.Comment", + N_("Server description, reported to the metaserver"), NULL, NULL, 0, "", + NULL, NULL}, + {NULL, &MetaServer.UseSocks, NULL, NULL, NULL, "MetaServer.UseSocks", + N_("If TRUE, use SOCKS for metaserver communication"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &MetaServer.authuser, NULL, "MetaServer.Auth.User", + N_("Username for HTTP Basic authentication"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &MetaServer.authpassword, NULL, + "MetaServer.Auth.Password", + N_("Password for HTTP Basic authentication"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &MetaServer.proxyuser, NULL, "MetaServer.Proxy.User", + N_("Username for HTTP Basic proxy authentication"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &MetaServer.proxypassword, NULL, + "MetaServer.Proxy.Password", + N_("Password for HTTP Basic proxy authentication"), + NULL, NULL, 0, "", NULL, NULL}, #endif /* NETWORKING */ #ifdef CYGWIN - { NULL,&MinToSysTray,NULL,NULL,NULL,"MinToSysTray", - N_("If TRUE, the server minimizes to the System Tray"), - NULL,NULL,0,"",NULL,NULL }, + {NULL, &MinToSysTray, NULL, NULL, NULL, "MinToSysTray", + N_("If TRUE, the server minimizes to the System Tray"), + NULL, NULL, 0, "", NULL, NULL}, #else - { NULL,&Daemonize,NULL,NULL,NULL,"Daemonize", - N_("If TRUE, the server runs in the background"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&WebBrowser,NULL,"WebBrowser", - N_("The command used to start your web browser"), - NULL,NULL,0,"",NULL,NULL }, + {NULL, &Daemonize, NULL, NULL, NULL, "Daemonize", + N_("If TRUE, the server runs in the background"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &WebBrowser, NULL, "WebBrowser", + N_("The command used to start your web browser"), + NULL, NULL, 0, "", NULL, NULL}, #endif - { &NumTurns,NULL,NULL,NULL,NULL,"NumTurns", - N_("No. of game turns (if 0, game never ends)"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Currency.Symbol,NULL,"Currency.Symbol", - N_("The currency symbol (e.g. $)"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,&Currency.Prefix,NULL,NULL,NULL,"Currency.Prefix", - N_("If TRUE, the currency symbol precedes prices"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Log.File,NULL,"Log.File", - N_("File to write log messages to"), - NULL,NULL,0,"",NULL,NULL }, - { &Log.Level,NULL,NULL,NULL,NULL,"Log.Level", - N_("Controls the number of log messages produced"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Log.Timestamp,NULL,"Log.Timestamp", - N_("strftime() format string for log timestamps"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,&Sanitized,NULL,NULL,NULL,"Sanitized", - N_("Random events are sanitized"),NULL,NULL,0,"",NULL,NULL }, - { NULL,&DrugValue,NULL,NULL,NULL,"DrugValue", - N_("TRUE if the value of bought drugs should be saved"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,&ConfigVerbose,NULL,NULL,NULL,"ConfigVerbose", - N_("Be verbose in processing config file"),NULL,NULL,0,"",NULL,NULL }, - { &NumLocation,NULL,NULL,NULL,NULL,"NumLocation", - N_("Number of locations in the game"), - (void **)(&Location),NULL,sizeof(struct LOCATION),"",NULL, - ResizeLocations }, - { &NumCop,NULL,NULL,NULL,NULL,"NumCop", - N_("Number of types of cop in the game"), - (void **)(&Cop),NULL,sizeof(struct COP),"",NULL,ResizeCops }, - { &NumGun,NULL,NULL,NULL,NULL,"NumGun",N_("Number of guns in the game"), - (void **)(&Gun),NULL,sizeof(struct GUN),"",NULL,ResizeGuns }, - { &NumDrug,NULL,NULL,NULL,NULL,"NumDrug",N_("Number of drugs in the game"), - (void **)(&Drug),NULL,sizeof(struct DRUG),"",NULL,ResizeDrugs }, - { &LoanSharkLoc,NULL,NULL,NULL,NULL,"LoanShark", - N_("Location of the Loan Shark"),NULL,NULL,0,"",NULL,NULL }, - { &BankLoc,NULL,NULL,NULL,NULL,"Bank",N_("Location of the bank"), - NULL,NULL,0,"",NULL,NULL }, - { &GunShopLoc,NULL,NULL,NULL,NULL,"GunShop",N_("Location of the gun shop"), - NULL,NULL,0,"",NULL,NULL }, - { &RoughPubLoc,NULL,NULL,NULL,NULL,"RoughPub",N_("Location of the pub"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Names.LoanSharkName,NULL,"LoanSharkName", - N_("Name of the loan shark"),NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Names.BankName,NULL,"BankName", - N_("Name of the bank"),NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Names.GunShopName,NULL,"GunShopName", - N_("Name of the gun shop"),NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Names.RoughPubName,NULL,"RoughPubName", - N_("Name of the pub"),NULL,NULL,0,"",NULL,NULL }, - { &DrugSortMethod,NULL,NULL,NULL,NULL,"DrugSortMethod", - N_("Sort key for listing available drugs"), - NULL,NULL,0,"",NULL,NULL }, - { &FightTimeout,NULL,NULL,NULL,NULL,"FightTimeout", - N_("No. of seconds in which to return fire"), - NULL,NULL,0,"",NULL,NULL }, - { &IdleTimeout,NULL,NULL,NULL,NULL,"IdleTimeout", - N_("Players are disconnected after this many seconds"), - NULL,NULL,0,"",NULL,NULL }, - { &ConnectTimeout,NULL,NULL,NULL,NULL,"ConnectTimeout", - N_("Time in seconds for connections to be made or broken"), - NULL,NULL,0,"",NULL,NULL }, - { &MaxClients,NULL,NULL,NULL,NULL,"MaxClients", - N_("Maximum number of TCP/IP connections"), - NULL,NULL,0,"",NULL,NULL }, - { &AITurnPause,NULL,NULL,NULL,NULL,"AITurnPause", - N_("Seconds between turns of AI players"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,&StartCash,NULL,NULL,"StartCash", - N_("Amount of cash that each player starts with"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,&StartDebt,NULL,NULL,"StartDebt", - N_("Amount of debt that each player starts with"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&StaticLocation.Name,NULL,"Name", - N_("Name of each location"),(void **)(&Location),&StaticLocation, - sizeof(struct LOCATION),"Location",&NumLocation,NULL }, - { &(StaticLocation.PolicePresence),NULL,NULL,NULL,NULL,"PolicePresence", - N_("Police presence at each location (%)"), - (void **)(&Location),&StaticLocation, - sizeof(struct LOCATION),"Location",&NumLocation,NULL }, - { &(StaticLocation.MinDrug),NULL,NULL,NULL,NULL,"MinDrug", - N_("Minimum number of drugs at each location"), - (void **)(&Location),&StaticLocation, - sizeof(struct LOCATION),"Location",&NumLocation,NULL }, - { &(StaticLocation.MaxDrug),NULL,NULL,NULL,NULL,"MaxDrug", - N_("Maximum number of drugs at each location"), - (void **)(&Location),&StaticLocation, - sizeof(struct LOCATION),"Location",&NumLocation,NULL }, - { &PlayerArmour,NULL,NULL,NULL,NULL,"PlayerArmour", - N_("% resistance to gunshots of each player"), - NULL,NULL,0,"",NULL,NULL }, - { &BitchArmour,NULL,NULL,NULL,NULL,"BitchArmour", - N_("% resistance to gunshots of each bitch"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&StaticCop.Name,NULL,"Name", - N_("Name of each cop"), - (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL }, - { NULL,NULL,NULL,&StaticCop.DeputyName,NULL,"DeputyName", - N_("Name of each cop's deputy"), - (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL }, - { NULL,NULL,NULL,&StaticCop.DeputiesName,NULL,"DeputiesName", - N_("Name of each cop's deputies"), - (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL }, - { &StaticCop.Armour,NULL,NULL,NULL,NULL,"Armour", - N_("% resistance to gunshots of each cop"), - (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL }, - { &StaticCop.DeputyArmour,NULL,NULL,NULL,NULL,"DeputyArmour", - N_("% resistance to gunshots of each deputy"), - (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL }, - { &StaticCop.AttackPenalty,NULL,NULL,NULL,NULL,"AttackPenalty", - N_("Attack penalty relative to a player"), - (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL }, - { &StaticCop.DefendPenalty,NULL,NULL,NULL,NULL,"DefendPenalty", - N_("Defend penalty relative to a player"), - (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL }, - { &StaticCop.MinDeputies,NULL,NULL,NULL,NULL,"MinDeputies", - N_("Minimum number of accompanying deputies"), - (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL }, - { &StaticCop.MaxDeputies,NULL,NULL,NULL,NULL,"MaxDeputies", - N_("Maximum number of accompanying deputies"), - (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL }, - { &StaticCop.GunIndex,NULL,NULL,NULL,NULL,"GunIndex", - N_("Zero-based index of the gun that cops are armed with"), - (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL }, - { &StaticCop.CopGun,NULL,NULL,NULL,NULL,"CopGun", - N_("Number of guns that each cop carries"), - (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL }, - { &StaticCop.DeputyGun,NULL,NULL,NULL,NULL,"DeputyGun", - N_("Number of guns that each deputy carries"), - (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL }, - { NULL,NULL,NULL,&StaticDrug.Name,NULL,"Name", - N_("Name of each drug"), - (void **)(&Drug),&StaticDrug, - sizeof(struct DRUG),"Drug",&NumDrug,NULL }, - { NULL,NULL,&(StaticDrug.MinPrice),NULL,NULL,"MinPrice", - N_("Minimum normal price of each drug"), - (void **)(&Drug),&StaticDrug, - sizeof(struct DRUG),"Drug",&NumDrug,NULL }, - { NULL,NULL,&(StaticDrug.MaxPrice),NULL,NULL,"MaxPrice", - N_("Maximum normal price of each drug"), - (void **)(&Drug),&StaticDrug, - sizeof(struct DRUG),"Drug",&NumDrug,NULL }, - { NULL,&(StaticDrug.Cheap),NULL,NULL,NULL,"Cheap", - N_("TRUE if this drug can be specially cheap"), - (void **)(&Drug),&StaticDrug, - sizeof(struct DRUG),"Drug",&NumDrug,NULL }, - { NULL,&(StaticDrug.Expensive),NULL,NULL,NULL,"Expensive", - N_("TRUE if this drug can be specially expensive"), - (void **)(&Drug),&StaticDrug, - sizeof(struct DRUG),"Drug",&NumDrug,NULL }, - { NULL,NULL,NULL,&StaticDrug.CheapStr,NULL,"CheapStr", - N_("Message displayed when this drug is specially cheap"), - (void **)(&Drug),&StaticDrug, - sizeof(struct DRUG),"Drug",&NumDrug,NULL }, - { NULL,NULL,NULL,&Drugs.ExpensiveStr1,NULL,"Drugs.ExpensiveStr1", - N_("Format string used for expensive drugs 50% of time"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Drugs.ExpensiveStr2,NULL,"Drugs.ExpensiveStr2", - N_("Format string used for expensive drugs 50% of time"), - NULL,NULL,0,"",NULL,NULL }, - { &(Drugs.CheapDivide),NULL,NULL,NULL,NULL,"Drugs.CheapDivide", - N_("Divider for drug price when it's specially cheap"), - NULL,NULL,0,"",NULL,NULL }, - { &(Drugs.ExpensiveMultiply),NULL,NULL,NULL,NULL,"Drugs.ExpensiveMultiply", - N_("Multiplier for specially expensive drug prices"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&StaticGun.Name,NULL,"Name", - N_("Name of each gun"), - (void **)(&Gun),&StaticGun, - sizeof(struct GUN),"Gun",&NumGun,NULL }, - { NULL,NULL,&(StaticGun.Price),NULL,NULL,"Price", - N_("Price of each gun"), - (void **)(&Gun),&StaticGun, - sizeof(struct GUN),"Gun",&NumGun,NULL }, - { &(StaticGun.Space),NULL,NULL,NULL,NULL,"Space", - N_("Space taken by each gun"), - (void **)(&Gun),&StaticGun, - sizeof(struct GUN),"Gun",&NumGun,NULL }, - { &(StaticGun.Damage),NULL,NULL,NULL,NULL,"Damage", - N_("Damage done by each gun"), - (void **)(&Gun),&StaticGun, - sizeof(struct GUN),"Gun",&NumGun,NULL }, - { NULL,NULL,NULL,&Names.Bitch,NULL,"Names.Bitch", - N_("Word used to denote a single \"bitch\""),NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Names.Bitches,NULL,"Names.Bitches", - N_("Word used to denote two or more \"bitches\""), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Names.Gun,NULL,"Names.Gun", - N_("Word used to denote a single gun or equivalent"),NULL,NULL,0,"",NULL, - NULL }, - { NULL,NULL,NULL,&Names.Guns,NULL,"Names.Guns", - N_("Word used to denote two or more guns"),NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Names.Drug,NULL,"Names.Drug", - N_("Word used to denote a single drug or equivalent"),NULL,NULL,0,"",NULL, - NULL }, - { NULL,NULL,NULL,&Names.Drugs,NULL,"Names.Drugs", - N_("Word used to denote two or more drugs"),NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Names.Month,NULL,"Names.Month", - N_("Text prefixed to the turn number (i.e. the month)"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,&Names.Year,NULL,"Names.Year", - N_("Text appended to the turn number (i.e. the year)"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,&Prices.Spy,NULL,NULL,"Prices.Spy", - N_("Cost for a bitch to spy on the enemy"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,&Prices.Tipoff,NULL,NULL,"Prices.Tipoff", - N_("Cost for a bitch to tipoff the cops to an enemy"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,&Bitch.MinPrice,NULL,NULL,"Bitch.MinPrice", - N_("Minimum price to hire a bitch"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,&Bitch.MaxPrice,NULL,NULL,"Bitch.MaxPrice", - N_("Maximum price to hire a bitch"), - NULL,NULL,0,"",NULL,NULL }, - { NULL,NULL,NULL,NULL,&SubwaySaying,"SubwaySaying", - N_("List of things which you overhear on the subway"), - NULL,NULL,0,"",&NumSubway,ResizeSubway }, - { &NumSubway,NULL,NULL,NULL,NULL,"NumSubwaySaying", - N_("Number of subway sayings"), - NULL,NULL,0,"",NULL,ResizeSubway }, - { NULL,NULL,NULL,NULL,&Playing,"Playing", - N_("List of songs which you can hear playing"), - NULL,NULL,0,"",&NumPlaying,ResizePlaying }, - { &NumPlaying,NULL,NULL,NULL,NULL,"NumPlaying", - N_("Number of playing songs"), - NULL,NULL,0,"",NULL,ResizePlaying }, - { NULL,NULL,NULL,NULL,&StoppedTo,"StoppedTo", - N_("List of things which you can stop to do"), - NULL,NULL,0,"",&NumStoppedTo,ResizeStoppedTo }, - { &NumStoppedTo,NULL,NULL,NULL,NULL,"NumStoppedTo", - N_("Number of things which you can stop to do"), - NULL,NULL,0,"",NULL,ResizeStoppedTo } + {&NumTurns, NULL, NULL, NULL, NULL, "NumTurns", + N_("No. of game turns (if 0, game never ends)"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &Currency.Symbol, NULL, "Currency.Symbol", + N_("The currency symbol (e.g. $)"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, &Currency.Prefix, NULL, NULL, NULL, "Currency.Prefix", + N_("If TRUE, the currency symbol precedes prices"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &Log.File, NULL, "Log.File", + N_("File to write log messages to"), + NULL, NULL, 0, "", NULL, NULL}, + {&Log.Level, NULL, NULL, NULL, NULL, "Log.Level", + N_("Controls the number of log messages produced"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &Log.Timestamp, NULL, "Log.Timestamp", + N_("strftime() format string for log timestamps"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, &Sanitized, NULL, NULL, NULL, "Sanitized", + N_("Random events are sanitized"), NULL, NULL, 0, "", NULL, NULL}, + {NULL, &DrugValue, NULL, NULL, NULL, "DrugValue", + N_("TRUE if the value of bought drugs should be saved"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, &ConfigVerbose, NULL, NULL, NULL, "ConfigVerbose", + N_("Be verbose in processing config file"), NULL, NULL, 0, "", NULL, + NULL}, + {&NumLocation, NULL, NULL, NULL, NULL, "NumLocation", + N_("Number of locations in the game"), + (void **)(&Location), NULL, sizeof(struct LOCATION), "", NULL, + ResizeLocations}, + {&NumCop, NULL, NULL, NULL, NULL, "NumCop", + N_("Number of types of cop in the game"), + (void **)(&Cop), NULL, sizeof(struct COP), "", NULL, ResizeCops}, + {&NumGun, NULL, NULL, NULL, NULL, "NumGun", + N_("Number of guns in the game"), + (void **)(&Gun), NULL, sizeof(struct GUN), "", NULL, ResizeGuns}, + {&NumDrug, NULL, NULL, NULL, NULL, "NumDrug", + N_("Number of drugs in the game"), + (void **)(&Drug), NULL, sizeof(struct DRUG), "", NULL, ResizeDrugs}, + {&LoanSharkLoc, NULL, NULL, NULL, NULL, "LoanShark", + N_("Location of the Loan Shark"), NULL, NULL, 0, "", NULL, NULL}, + {&BankLoc, NULL, NULL, NULL, NULL, "Bank", N_("Location of the bank"), + NULL, NULL, 0, "", NULL, NULL}, + {&GunShopLoc, NULL, NULL, NULL, NULL, "GunShop", + N_("Location of the gun shop"), + NULL, NULL, 0, "", NULL, NULL}, + {&RoughPubLoc, NULL, NULL, NULL, NULL, "RoughPub", + N_("Location of the pub"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &Names.LoanSharkName, NULL, "LoanSharkName", + N_("Name of the loan shark"), NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &Names.BankName, NULL, "BankName", + N_("Name of the bank"), NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &Names.GunShopName, NULL, "GunShopName", + N_("Name of the gun shop"), NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &Names.RoughPubName, NULL, "RoughPubName", + N_("Name of the pub"), NULL, NULL, 0, "", NULL, NULL}, + {&DrugSortMethod, NULL, NULL, NULL, NULL, "DrugSortMethod", + N_("Sort key for listing available drugs"), + NULL, NULL, 0, "", NULL, NULL}, + {&FightTimeout, NULL, NULL, NULL, NULL, "FightTimeout", + N_("No. of seconds in which to return fire"), + NULL, NULL, 0, "", NULL, NULL}, + {&IdleTimeout, NULL, NULL, NULL, NULL, "IdleTimeout", + N_("Players are disconnected after this many seconds"), + NULL, NULL, 0, "", NULL, NULL}, + {&ConnectTimeout, NULL, NULL, NULL, NULL, "ConnectTimeout", + N_("Time in seconds for connections to be made or broken"), + NULL, NULL, 0, "", NULL, NULL}, + {&MaxClients, NULL, NULL, NULL, NULL, "MaxClients", + N_("Maximum number of TCP/IP connections"), + NULL, NULL, 0, "", NULL, NULL}, + {&AITurnPause, NULL, NULL, NULL, NULL, "AITurnPause", + N_("Seconds between turns of AI players"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, &StartCash, NULL, NULL, "StartCash", + N_("Amount of cash that each player starts with"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, &StartDebt, NULL, NULL, "StartDebt", + N_("Amount of debt that each player starts with"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &StaticLocation.Name, NULL, "Name", + N_("Name of each location"), (void **)(&Location), &StaticLocation, + sizeof(struct LOCATION), "Location", &NumLocation, NULL}, + {&(StaticLocation.PolicePresence), NULL, NULL, NULL, NULL, + "PolicePresence", + N_("Police presence at each location (%)"), + (void **)(&Location), &StaticLocation, + sizeof(struct LOCATION), "Location", &NumLocation, NULL}, + {&(StaticLocation.MinDrug), NULL, NULL, NULL, NULL, "MinDrug", + N_("Minimum number of drugs at each location"), + (void **)(&Location), &StaticLocation, + sizeof(struct LOCATION), "Location", &NumLocation, NULL}, + {&(StaticLocation.MaxDrug), NULL, NULL, NULL, NULL, "MaxDrug", + N_("Maximum number of drugs at each location"), + (void **)(&Location), &StaticLocation, + sizeof(struct LOCATION), "Location", &NumLocation, NULL}, + {&PlayerArmour, NULL, NULL, NULL, NULL, "PlayerArmour", + N_("% resistance to gunshots of each player"), + NULL, NULL, 0, "", NULL, NULL}, + {&BitchArmour, NULL, NULL, NULL, NULL, "BitchArmour", + N_("% resistance to gunshots of each bitch"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &StaticCop.Name, NULL, "Name", + N_("Name of each cop"), + (void **)(&Cop), &StaticCop, sizeof(struct COP), "Cop", &NumCop, NULL}, + {NULL, NULL, NULL, &StaticCop.DeputyName, NULL, "DeputyName", + N_("Name of each cop's deputy"), + (void **)(&Cop), &StaticCop, sizeof(struct COP), "Cop", &NumCop, NULL}, + {NULL, NULL, NULL, &StaticCop.DeputiesName, NULL, "DeputiesName", + N_("Name of each cop's deputies"), + (void **)(&Cop), &StaticCop, sizeof(struct COP), "Cop", &NumCop, NULL}, + {&StaticCop.Armour, NULL, NULL, NULL, NULL, "Armour", + N_("% resistance to gunshots of each cop"), + (void **)(&Cop), &StaticCop, sizeof(struct COP), "Cop", &NumCop, NULL}, + {&StaticCop.DeputyArmour, NULL, NULL, NULL, NULL, "DeputyArmour", + N_("% resistance to gunshots of each deputy"), + (void **)(&Cop), &StaticCop, sizeof(struct COP), "Cop", &NumCop, NULL}, + {&StaticCop.AttackPenalty, NULL, NULL, NULL, NULL, "AttackPenalty", + N_("Attack penalty relative to a player"), + (void **)(&Cop), &StaticCop, sizeof(struct COP), "Cop", &NumCop, NULL}, + {&StaticCop.DefendPenalty, NULL, NULL, NULL, NULL, "DefendPenalty", + N_("Defend penalty relative to a player"), + (void **)(&Cop), &StaticCop, sizeof(struct COP), "Cop", &NumCop, NULL}, + {&StaticCop.MinDeputies, NULL, NULL, NULL, NULL, "MinDeputies", + N_("Minimum number of accompanying deputies"), + (void **)(&Cop), &StaticCop, sizeof(struct COP), "Cop", &NumCop, NULL}, + {&StaticCop.MaxDeputies, NULL, NULL, NULL, NULL, "MaxDeputies", + N_("Maximum number of accompanying deputies"), + (void **)(&Cop), &StaticCop, sizeof(struct COP), "Cop", &NumCop, NULL}, + {&StaticCop.GunIndex, NULL, NULL, NULL, NULL, "GunIndex", + N_("Zero-based index of the gun that cops are armed with"), + (void **)(&Cop), &StaticCop, sizeof(struct COP), "Cop", &NumCop, NULL}, + {&StaticCop.CopGun, NULL, NULL, NULL, NULL, "CopGun", + N_("Number of guns that each cop carries"), + (void **)(&Cop), &StaticCop, sizeof(struct COP), "Cop", &NumCop, NULL}, + {&StaticCop.DeputyGun, NULL, NULL, NULL, NULL, "DeputyGun", + N_("Number of guns that each deputy carries"), + (void **)(&Cop), &StaticCop, sizeof(struct COP), "Cop", &NumCop, NULL}, + {NULL, NULL, NULL, &StaticDrug.Name, NULL, "Name", + N_("Name of each drug"), + (void **)(&Drug), &StaticDrug, + sizeof(struct DRUG), "Drug", &NumDrug, NULL}, + {NULL, NULL, &(StaticDrug.MinPrice), NULL, NULL, "MinPrice", + N_("Minimum normal price of each drug"), + (void **)(&Drug), &StaticDrug, + sizeof(struct DRUG), "Drug", &NumDrug, NULL}, + {NULL, NULL, &(StaticDrug.MaxPrice), NULL, NULL, "MaxPrice", + N_("Maximum normal price of each drug"), + (void **)(&Drug), &StaticDrug, + sizeof(struct DRUG), "Drug", &NumDrug, NULL}, + {NULL, &(StaticDrug.Cheap), NULL, NULL, NULL, "Cheap", + N_("TRUE if this drug can be specially cheap"), + (void **)(&Drug), &StaticDrug, + sizeof(struct DRUG), "Drug", &NumDrug, NULL}, + {NULL, &(StaticDrug.Expensive), NULL, NULL, NULL, "Expensive", + N_("TRUE if this drug can be specially expensive"), + (void **)(&Drug), &StaticDrug, + sizeof(struct DRUG), "Drug", &NumDrug, NULL}, + {NULL, NULL, NULL, &StaticDrug.CheapStr, NULL, "CheapStr", + N_("Message displayed when this drug is specially cheap"), + (void **)(&Drug), &StaticDrug, + sizeof(struct DRUG), "Drug", &NumDrug, NULL}, + {NULL, NULL, NULL, &Drugs.ExpensiveStr1, NULL, "Drugs.ExpensiveStr1", + N_("Format string used for expensive drugs 50% of time"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &Drugs.ExpensiveStr2, NULL, "Drugs.ExpensiveStr2", + N_("Format string used for expensive drugs 50% of time"), + NULL, NULL, 0, "", NULL, NULL}, + {&(Drugs.CheapDivide), NULL, NULL, NULL, NULL, "Drugs.CheapDivide", + N_("Divider for drug price when it's specially cheap"), + NULL, NULL, 0, "", NULL, NULL}, + {&(Drugs.ExpensiveMultiply), NULL, NULL, NULL, NULL, + "Drugs.ExpensiveMultiply", + N_("Multiplier for specially expensive drug prices"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &StaticGun.Name, NULL, "Name", + N_("Name of each gun"), + (void **)(&Gun), &StaticGun, + sizeof(struct GUN), "Gun", &NumGun, NULL}, + {NULL, NULL, &(StaticGun.Price), NULL, NULL, "Price", + N_("Price of each gun"), + (void **)(&Gun), &StaticGun, + sizeof(struct GUN), "Gun", &NumGun, NULL}, + {&(StaticGun.Space), NULL, NULL, NULL, NULL, "Space", + N_("Space taken by each gun"), + (void **)(&Gun), &StaticGun, + sizeof(struct GUN), "Gun", &NumGun, NULL}, + {&(StaticGun.Damage), NULL, NULL, NULL, NULL, "Damage", + N_("Damage done by each gun"), + (void **)(&Gun), &StaticGun, + sizeof(struct GUN), "Gun", &NumGun, NULL}, + {NULL, NULL, NULL, &Names.Bitch, NULL, "Names.Bitch", + N_("Word used to denote a single \"bitch\""), NULL, NULL, 0, "", NULL, + NULL}, + {NULL, NULL, NULL, &Names.Bitches, NULL, "Names.Bitches", + N_("Word used to denote two or more \"bitches\""), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &Names.Gun, NULL, "Names.Gun", + N_("Word used to denote a single gun or equivalent"), NULL, NULL, 0, "", + NULL, NULL}, + {NULL, NULL, NULL, &Names.Guns, NULL, "Names.Guns", + N_("Word used to denote two or more guns"), NULL, NULL, 0, "", NULL, + NULL}, + {NULL, NULL, NULL, &Names.Drug, NULL, "Names.Drug", + N_("Word used to denote a single drug or equivalent"), NULL, NULL, 0, + "", NULL, NULL}, + {NULL, NULL, NULL, &Names.Drugs, NULL, "Names.Drugs", + N_("Word used to denote two or more drugs"), NULL, NULL, 0, "", NULL, + NULL}, + {NULL, NULL, NULL, &Names.Month, NULL, "Names.Month", + N_("Text prefixed to the turn number (i.e. the month)"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, &Names.Year, NULL, "Names.Year", + N_("Text appended to the turn number (i.e. the year)"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, &Prices.Spy, NULL, NULL, "Prices.Spy", + N_("Cost for a bitch to spy on the enemy"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, &Prices.Tipoff, NULL, NULL, "Prices.Tipoff", + N_("Cost for a bitch to tipoff the cops to an enemy"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, &Bitch.MinPrice, NULL, NULL, "Bitch.MinPrice", + N_("Minimum price to hire a bitch"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, &Bitch.MaxPrice, NULL, NULL, "Bitch.MaxPrice", + N_("Maximum price to hire a bitch"), + NULL, NULL, 0, "", NULL, NULL}, + {NULL, NULL, NULL, NULL, &SubwaySaying, "SubwaySaying", + N_("List of things which you overhear on the subway"), + NULL, NULL, 0, "", &NumSubway, ResizeSubway}, + {&NumSubway, NULL, NULL, NULL, NULL, "NumSubwaySaying", + N_("Number of subway sayings"), + NULL, NULL, 0, "", NULL, ResizeSubway}, + {NULL, NULL, NULL, NULL, &Playing, "Playing", + N_("List of songs which you can hear playing"), + NULL, NULL, 0, "", &NumPlaying, ResizePlaying}, + {&NumPlaying, NULL, NULL, NULL, NULL, "NumPlaying", + N_("Number of playing songs"), + NULL, NULL, 0, "", NULL, ResizePlaying}, + {NULL, NULL, NULL, NULL, &StoppedTo, "StoppedTo", + N_("List of things which you can stop to do"), + NULL, NULL, 0, "", &NumStoppedTo, ResizeStoppedTo}, + {&NumStoppedTo, NULL, NULL, NULL, NULL, "NumStoppedTo", + N_("Number of things which you can stop to do"), + NULL, NULL, 0, "", NULL, ResizeStoppedTo} }; -const int NUMGLOB = sizeof(Globals)/sizeof(Globals[0]); +const int NUMGLOB = sizeof(Globals) / sizeof(Globals[0]); -char **Playing=NULL; +char **Playing = NULL; char *DefaultPlaying[] = { -/* Default list of songs that you can hear playing (N.B. this can be - overridden in the configuration file with the "Playing" variable) - - look for "You hear someone playing %s" to see how these are used. */ - N_("`Are you Experienced` by Jimi Hendrix"), - N_("`Cheeba Cheeba` by Tone Loc"), - N_("`Comin` in to Los Angeles` by Arlo Guthrie"), - N_("`Commercial` by Spanky and Our Gang"), - N_("`Late in the Evening` by Paul Simon"), - N_("`Light Up` by Styx"), - N_("`Mexico` by Jefferson Airplane"), - N_("`One toke over the line` by Brewer & Shipley"), - N_("`The Smokeout` by Shel Silverstein"), - N_("`White Rabbit` by Jefferson Airplane"), - N_("`Itchycoo Park` by Small Faces"), - N_("`White Punks on Dope` by the Tubes"), - N_("`Legend of a Mind` by the Moody Blues"), - N_("`Eight Miles High` by the Byrds"), - N_("`Acapulco Gold` by Riders of the Purple Sage"), - N_("`Kicks` by Paul Revere & the Raiders"), - N_("the Nixon tapes"), - N_("`Legalize It` by Mojo Nixon & Skid Roper") + /* Default list of songs that you can hear playing (N.B. this can be + * overridden in the configuration file with the "Playing" variable) - + * look for "You hear someone playing %s" to see how these are used. */ + N_("`Are you Experienced` by Jimi Hendrix"), + N_("`Cheeba Cheeba` by Tone Loc"), + N_("`Comin` in to Los Angeles` by Arlo Guthrie"), + N_("`Commercial` by Spanky and Our Gang"), + N_("`Late in the Evening` by Paul Simon"), + N_("`Light Up` by Styx"), + N_("`Mexico` by Jefferson Airplane"), + N_("`One toke over the line` by Brewer & Shipley"), + N_("`The Smokeout` by Shel Silverstein"), + N_("`White Rabbit` by Jefferson Airplane"), + N_("`Itchycoo Park` by Small Faces"), + N_("`White Punks on Dope` by the Tubes"), + N_("`Legend of a Mind` by the Moody Blues"), + N_("`Eight Miles High` by the Byrds"), + N_("`Acapulco Gold` by Riders of the Purple Sage"), + N_("`Kicks` by Paul Revere & the Raiders"), + N_("the Nixon tapes"), + N_("`Legalize It` by Mojo Nixon & Skid Roper") }; -char **StoppedTo=NULL; +char **StoppedTo = NULL; char *DefaultStoppedTo[] = { -/* Default list of things which you can "stop to do" (random events that - cost you a little money). These can be overridden with the "StoppedTo" - variable in the configuration file. See the later string - "You stopped to %s." to see how these strings are used. */ - N_("have a beer"), - N_("smoke a joint"), - N_("smoke a cigar"), - N_("smoke a Djarum"), - N_("smoke a cigarette") + /* Default list of things which you can "stop to do" (random events that + * cost you a little money). These can be overridden with the "StoppedTo" + * variable in the configuration file. See the later string "You stopped + * to %s." to see how these strings are used. */ + N_("have a beer"), + N_("smoke a joint"), + N_("smoke a cigar"), + N_("smoke a Djarum"), + N_("smoke a cigarette") }; struct COP DefaultCop[] = { -/* Name of the first police officer to attack you */ - { N_("Officer Hardass"), -/* Name of a single deputy of the first police officer */ - N_("deputy"), -/* Word used for more than one deputy of the first police officer */ - N_("deputies"),4,3,30,30,2,8,0,1,1 }, -/* Ditto, for the other police officers */ - { N_("Officer Bob"),N_("deputy"),N_("deputies"),15,4,30,20,4,10,0,2,1 }, - { N_("Agent Smith"),N_("cop"),N_("cops"),50,6,20,20,6,18,1,3,2 } + /* Name of the first police officer to attack you */ + {N_("Officer Hardass"), + /* Name of a single deputy of the first police officer */ + N_("deputy"), + /* Word used for more than one deputy of the first police officer */ + N_("deputies"), 4, 3, 30, 30, 2, 8, 0, 1, 1}, + /* Ditto, for the other police officers */ + {N_("Officer Bob"), N_("deputy"), N_("deputies"), 15, 4, 30, 20, 4, 10, + 0, 2, 1}, + {N_("Agent Smith"), N_("cop"), N_("cops"), 50, 6, 20, 20, 6, 18, 1, 3, 2} }; struct GUN DefaultGun[] = { -/* The names of the default guns */ - { N_("Baretta"),3000,4,5 }, - { N_(".38 Special"),3500,4,9 }, - { N_("Ruger"),2900,4,4 }, - { N_("Saturday Night Special"),3100,4,7 } + /* The names of the default guns */ + {N_("Baretta"), 3000, 4, 5}, + {N_(".38 Special"), 3500, 4, 9}, + {N_("Ruger"), 2900, 4, 4}, + {N_("Saturday Night Special"), 3100, 4, 7} }; struct DRUG DefaultDrug[] = { -/* The names of the default drugs, and the messages displayed when they are - specially cheap or expensive */ - { N_("Acid"),1000,4400,TRUE,FALSE, - N_("The market is flooded with cheap home-made acid!") }, - { N_("Cocaine"),15000,29000,FALSE,TRUE,"" }, - { N_("Hashish"),480,1280,TRUE,FALSE, - N_("The Marrakesh Express has arrived!") }, - { N_("Heroin"),5500,13000,FALSE,TRUE,"" }, - { N_("Ludes"),11,60,TRUE,FALSE, - N_("Rival drug dealers raided a pharmacy and are selling cheap ludes!") }, - { N_("MDA"),1500,4400,FALSE,FALSE,"" }, - { N_("Opium"),540,1250,FALSE,TRUE,"" }, - { N_("PCP"),1000,2500,FALSE,FALSE,"" }, - { N_("Peyote"),220,700,FALSE,FALSE,"" }, - { N_("Shrooms"),630,1300,FALSE,FALSE,"" }, - { N_("Speed"),90,250,FALSE,TRUE,"" }, - { N_("Weed"),315,890,TRUE,FALSE, - N_("Columbian freighter dusted the Coast Guard! " - "Weed prices have bottomed out!") } + /* The names of the default drugs, and the messages displayed when they + * are specially cheap or expensive */ + {N_("Acid"), 1000, 4400, TRUE, FALSE, + N_("The market is flooded with cheap home-made acid!")}, + {N_("Cocaine"), 15000, 29000, FALSE, TRUE, ""}, + {N_("Hashish"), 480, 1280, TRUE, FALSE, + N_("The Marrakesh Express has arrived!")}, + {N_("Heroin"), 5500, 13000, FALSE, TRUE, ""}, + {N_("Ludes"), 11, 60, TRUE, FALSE, + N_("Rival drug dealers raided a pharmacy and are selling cheap ludes!")}, + {N_("MDA"), 1500, 4400, FALSE, FALSE, ""}, + {N_("Opium"), 540, 1250, FALSE, TRUE, ""}, + {N_("PCP"), 1000, 2500, FALSE, FALSE, ""}, + {N_("Peyote"), 220, 700, FALSE, FALSE, ""}, + {N_("Shrooms"), 630, 1300, FALSE, FALSE, ""}, + {N_("Speed"), 90, 250, FALSE, TRUE, ""}, + {N_("Weed"), 315, 890, TRUE, FALSE, + N_("Columbian freighter dusted the Coast Guard! " + "Weed prices have bottomed out!")} }; + #define NUMDRUG (sizeof(DefaultDrug)/sizeof(DefaultDrug[0])) struct LOCATION DefaultLocation[] = { -/* The names of the default locations */ - { N_("Bronx"),10,NUMDRUG/2+1,NUMDRUG }, - { N_("Ghetto"),5,NUMDRUG/2+2,NUMDRUG }, - { N_("Central Park"),15,NUMDRUG/2,NUMDRUG }, - { N_("Manhattan"),90,NUMDRUG/2-2,NUMDRUG-2 }, - { N_("Coney Island"),20,NUMDRUG/2,NUMDRUG }, - { N_("Brooklyn"),70,NUMDRUG/2-2,NUMDRUG-1 }, - { N_("Queens"),50,NUMDRUG/2,NUMDRUG }, - { N_("Staten Island"),20,NUMDRUG/2,NUMDRUG } + /* The names of the default locations */ + {N_("Bronx"), 10, NUMDRUG / 2 + 1, NUMDRUG}, + {N_("Ghetto"), 5, NUMDRUG / 2 + 2, NUMDRUG}, + {N_("Central Park"), 15, NUMDRUG / 2, NUMDRUG}, + {N_("Manhattan"), 90, NUMDRUG / 2 - 2, NUMDRUG - 2}, + {N_("Coney Island"), 20, NUMDRUG / 2, NUMDRUG}, + {N_("Brooklyn"), 70, NUMDRUG / 2 - 2, NUMDRUG - 1}, + {N_("Queens"), 50, NUMDRUG / 2, NUMDRUG}, + {N_("Staten Island"), 20, NUMDRUG / 2, NUMDRUG} }; -struct DRUGS Drugs = { NULL,NULL,0,0 }; +struct DRUGS Drugs = { NULL, NULL, 0, 0 }; struct DRUGS DefaultDrugs = { -/* Messages displayed for drug busts, etc. */ - N_("Cops made a big %tde bust! Prices are outrageous!"), - N_("Addicts are buying %tde at ridiculous prices!"), - 4,4 }; + /* Messages displayed for drug busts, etc. */ + N_("Cops made a big %tde bust! Prices are outrageous!"), + N_("Addicts are buying %tde at ridiculous prices!"), + 4, 4 +}; -char **SubwaySaying=NULL; +char **SubwaySaying = NULL; char *DefaultSubwaySaying[] = { -/* Default list of things which the "lady on the subway" can tell you (N.B. - can be overridden with the "SubwaySaying" config. file variable). Look - for "the lady next to you" to see how these strings are used. */ - N_("Wouldn\'t it be funny if everyone suddenly quacked at once?"), - N_("The Pope was once Jewish, you know"), - N_("I\'ll bet you have some really interesting dreams"), - N_("So I think I\'m going to Amsterdam this year"), - N_("Son, you need a yellow haircut"), - N_("I think it\'s wonderful what they\'re doing with incense these days"), - N_("I wasn\'t always a woman, you know"), - N_("Does your mother know you\'re a dope dealer?"), - N_("Are you high on something?"), - N_("Oh, you must be from California"), - N_("I used to be a hippie, myself"), - N_("There\'s nothing like having lots of money"), - N_("You look like an aardvark!"), - N_("I don\'t believe in Ronald Reagan"), - N_("Courage! Bush is a noodle!"), - N_("Haven\'t I seen you on TV?"), - N_("I think hemorrhoid commercials are really neat!"), - N_("We\'re winning the war for drugs!"), - N_("A day without dope is like night"), - N_("We only use 20% of our brains, so why not burn out the other 80%"), - N_("I\'m soliciting contributions for Zombies for Christ"), - N_("I\'d like to sell you an edible poodle"), - N_("Winners don\'t do drugs... unless they do"), - N_("Kill a cop for Christ!"), - N_("I am the walrus!"), - N_("Jesus loves you more than you will know"), - N_("I feel an unaccountable urge to dye my hair blue"), - N_("Wasn\'t Jane Fonda wonderful in Barbarella"), - N_("Just say No... well, maybe... ok, what the hell!"), - N_("Would you like a jelly baby?"), - N_("Drugs can be your friend!") + /* Default list of things which the "lady on the subway" can tell you + * (N.B. can be overridden with the "SubwaySaying" config. file + * variable). Look for "the lady next to you" to see how these strings + * are used. */ + N_("Wouldn\'t it be funny if everyone suddenly quacked at once?"), + N_("The Pope was once Jewish, you know"), + N_("I\'ll bet you have some really interesting dreams"), + N_("So I think I\'m going to Amsterdam this year"), + N_("Son, you need a yellow haircut"), + N_("I think it\'s wonderful what they\'re doing with incense these days"), + N_("I wasn\'t always a woman, you know"), + N_("Does your mother know you\'re a dope dealer?"), + N_("Are you high on something?"), + N_("Oh, you must be from California"), + N_("I used to be a hippie, myself"), + N_("There\'s nothing like having lots of money"), + N_("You look like an aardvark!"), + N_("I don\'t believe in Ronald Reagan"), + N_("Courage! Bush is a noodle!"), + N_("Haven\'t I seen you on TV?"), + N_("I think hemorrhoid commercials are really neat!"), + N_("We\'re winning the war for drugs!"), + N_("A day without dope is like night"), + N_("We only use 20% of our brains, so why not burn out the other 80%"), + N_("I\'m soliciting contributions for Zombies for Christ"), + N_("I\'d like to sell you an edible poodle"), + N_("Winners don\'t do drugs... unless they do"), + N_("Kill a cop for Christ!"), + N_("I am the walrus!"), + N_("Jesus loves you more than you will know"), + N_("I feel an unaccountable urge to dye my hair blue"), + N_("Wasn\'t Jane Fonda wonderful in Barbarella"), + N_("Just say No... well, maybe... ok, what the hell!"), + N_("Would you like a jelly baby?"), + N_("Drugs can be your friend!") }; -int brandom(int bot,int top) { -/* Returns a random integer not less than bot and less than top */ - return (int)((float)(top-bot)*rand()/(RAND_MAX+1.0))+bot; -} - -price_t prandom(price_t bot,price_t top) { -/* Returns a random price not less than bot and less than top */ - return (price_t)((float)(top-bot)*rand()/(RAND_MAX+1.0))+bot; -} - -int CountPlayers(GSList *First) { -/* Returns the total numbers of players in the list starting at "First"; */ -/* players still in the process of connecting or leaving, and those that */ -/* are actually cops (server-created internal AI players) are ignored. */ - GSList *list; - Player *Play; - int count=0; - for (list=First;list;list=g_slist_next(list)) { - Play=(Player *)list->data; - if (strlen(GetPlayerName(Play))>0 && !IsCop(Play)) count++; - } - return count; -} - -GSList *AddPlayer(int fd,Player *NewPlayer,GSList *First) { -/* Adds the new Player structure "NewPlayer" to the linked list */ -/* pointed to by "First", and initialises all fields. Returns the new */ -/* start of the list. If this function is called by the server, then */ -/* it should pass the file descriptor of the socket used to */ -/* communicate with the client player. */ - Player *tmp; - GSList *list; - list=First; - NewPlayer->ID=0; -/* Generate a unique player ID, if we're the server (clients get their IDs - from the server, so don't need to generate IDs) */ - if (Server) while (list) { - tmp=(Player *)list->data; - if (tmp->ID==NewPlayer->ID) { - NewPlayer->ID++; - list=First; +/* + * Returns a random integer not less than bot and less than top. + */ +int brandom(int bot, int top) +{ + return (int)((float)(top - bot) * rand() / (RAND_MAX + 1.0)) + bot; +} + +/* + * Returns a random price not less than bot and less than top. + */ +price_t prandom(price_t bot, price_t top) +{ + return (price_t)((float)(top - bot) * rand() / (RAND_MAX + 1.0)) + bot; +} + +/* + * Returns the total numbers of players in the list starting at "First"; + * players still in the process of connecting or leaving, and those that + * are actually cops (server-created internal AI players) are ignored. + */ +int CountPlayers(GSList *First) +{ + GSList *list; + Player *Play; + int count = 0; + + for (list = First; list; list = g_slist_next(list)) { + Play = (Player *)list->data; + if (strlen(GetPlayerName(Play)) > 0 && !IsCop(Play)) + count++; + } + return count; +} + +/* + * Adds the new Player structure "NewPlayer" to the linked list + * pointed to by "First", and initialises all fields. Returns the new + * start of the list. If this function is called by the server, then + * it should pass the file descriptor of the socket used to + * communicate with the client player. + */ +GSList *AddPlayer(int fd, Player *NewPlayer, GSList *First) +{ + Player *tmp; + GSList *list; + + list = First; + NewPlayer->ID = 0; + /* Generate a unique player ID, if we're the server (clients get their + * IDs from the server, so don't need to generate IDs) */ + if (Server) + while (list) { + tmp = (Player *)list->data; + if (tmp->ID == NewPlayer->ID) { + NewPlayer->ID++; + list = First; } else { - list=g_slist_next(list); + list = g_slist_next(list); } - } - NewPlayer->Name=NULL; - SetPlayerName(NewPlayer,NULL); - NewPlayer->IsAt=0; - NewPlayer->EventNum=E_NONE; - NewPlayer->FightTimeout=NewPlayer->ConnectTimeout=NewPlayer->IdleTimeout=0; - NewPlayer->Guns=(Inventory *)g_malloc0(NumGun*sizeof(Inventory)); - NewPlayer->Drugs=(Inventory *)g_malloc0(NumDrug*sizeof(Inventory)); - InitList(&(NewPlayer->SpyList)); - InitList(&(NewPlayer->TipList)); - NewPlayer->Turn=1; - NewPlayer->Cash=StartCash; - NewPlayer->Debt=StartDebt; - NewPlayer->Bank=0; - NewPlayer->Bitches.Carried=8; - NewPlayer->CopIndex=0; - NewPlayer->Health=100; - NewPlayer->CoatSize=100; - NewPlayer->Flags=0; + } + NewPlayer->Name = NULL; + SetPlayerName(NewPlayer, NULL); + NewPlayer->IsAt = 0; + NewPlayer->EventNum = E_NONE; + NewPlayer->FightTimeout = NewPlayer->ConnectTimeout = + NewPlayer->IdleTimeout = 0; + NewPlayer->Guns = (Inventory *)g_malloc0(NumGun * sizeof(Inventory)); + NewPlayer->Drugs = (Inventory *)g_malloc0(NumDrug * sizeof(Inventory)); + InitList(&(NewPlayer->SpyList)); + InitList(&(NewPlayer->TipList)); + NewPlayer->Turn = 1; + NewPlayer->Cash = StartCash; + NewPlayer->Debt = StartDebt; + NewPlayer->Bank = 0; + NewPlayer->Bitches.Carried = 8; + NewPlayer->CopIndex = 0; + NewPlayer->Health = 100; + NewPlayer->CoatSize = 100; + NewPlayer->Flags = 0; #if NETWORKING - InitNetworkBuffer(&NewPlayer->NetBuf,'\n','\r',UseSocks ? &Socks : NULL); - if (Server) BindNetworkBufferToSocket(&NewPlayer->NetBuf,fd); + InitNetworkBuffer(&NewPlayer->NetBuf, '\n', '\r', + UseSocks ? &Socks : NULL); + if (Server) + BindNetworkBufferToSocket(&NewPlayer->NetBuf, fd); #endif - InitAbilities(NewPlayer); - NewPlayer->FightArray=NULL; - NewPlayer->Attacking=NULL; - return g_slist_append(First,(gpointer)NewPlayer); -} - -gboolean IsConnectedPlayer(Player *play) { -/* Returns TRUE only if the given player has properly connected (i.e. has - a valid name) */ + InitAbilities(NewPlayer); + NewPlayer->FightArray = NULL; + NewPlayer->Attacking = NULL; + return g_slist_append(First, (gpointer)NewPlayer); +} + +/* + * Returns TRUE only if the given player has properly connected (i.e. has + * a valid name). + */ +gboolean IsConnectedPlayer(Player *play) +{ return (play && play->Name && play->Name[0]); } -void UpdatePlayer(Player *Play) { -/* Redimensions the Gun and Drug lists for "Play" */ - Play->Guns=(Inventory *)g_realloc(Play->Guns,NumGun*sizeof(Inventory)); - Play->Drugs=(Inventory *)g_realloc(Play->Drugs,NumDrug*sizeof(Inventory)); -} - -GSList *RemovePlayer(Player *Play,GSList *First) { -/* Removes the Player structure pointed to by "Play" from the linked */ -/* list starting at "First". The client socket is freed if called */ -/* from the server. The new start of the list is returned. */ - g_assert(Play); - g_assert(First); - - First=g_slist_remove(First,(gpointer)Play); +/* + * Redimensions the Gun and Drug lists for "Play". + */ +void UpdatePlayer(Player *Play) +{ + Play->Guns = + (Inventory *)g_realloc(Play->Guns, NumGun * sizeof(Inventory)); + Play->Drugs = + (Inventory *)g_realloc(Play->Drugs, NumDrug * sizeof(Inventory)); +} + +/* + * Removes the Player structure pointed to by "Play" from the linked + * list starting at "First". The client socket is freed if called + * from the server. The new start of the list is returned. + */ +GSList *RemovePlayer(Player *Play, GSList *First) +{ + g_assert(Play); + g_assert(First); + + First = g_slist_remove(First, (gpointer)Play); #if NETWORKING - if (!IsCop(Play)) ShutdownNetworkBuffer(&Play->NetBuf); + if (!IsCop(Play)) + ShutdownNetworkBuffer(&Play->NetBuf); #endif - ClearList(&(Play->SpyList)); - ClearList(&(Play->TipList)); - g_free(Play->Name); - g_free(Play); - return First; -} - -void CopyPlayer(Player *Dest,Player *Src) { -/* Copies player "Src" to player "Dest" */ - if (!Dest || !Src) return; - Dest->Turn=Src->Turn; - Dest->Cash=Src->Cash; - Dest->Debt=Src->Debt; - Dest->Bank=Src->Bank; - Dest->Health=Src->Health; - ClearInventory(Dest->Guns,Dest->Drugs); - AddInventory(Dest->Guns,Src->Guns,NumGun); - AddInventory(Dest->Drugs,Src->Drugs,NumDrug); - Dest->CoatSize=Src->CoatSize; - Dest->IsAt=Src->IsAt; - g_free(Dest->Name); - Dest->Name=g_strdup(Src->Name); - Dest->Bitches.Carried=Src->Bitches.Carried; - Dest->Flags=Src->Flags; -} - -gboolean IsCop(Player *Play) { - return (Play->CopIndex>0); -} - -char *GetPlayerName(Player *Play) { - if (Play->Name) return Play->Name; - else return ""; -} - -void SetPlayerName(Player *Play,char *Name) { - if (Play->Name) g_free(Play->Name); - if (!Name) Play->Name=g_strdup(""); - else Play->Name = g_strdup(Name); -} - -Player *GetPlayerByID(guint ID,GSList *First) { -/* Searches the linked list starting at "First" for a Player structure */ -/* with the given ID. Returns a pointer to this structure, or NULL if */ -/* no match can be found. */ - GSList *list; - Player *Play; - for (list=First;list;list=g_slist_next(list)) { - Play=(Player *)list->data; - if (Play->ID==ID) return Play; - } - return NULL; -} - -Player *GetPlayerByName(char *Name,GSList *First) { -/* Searches the linked list starting at "First" for a Player structure */ -/* with the name "Name". Returns a pointer to this structure, or NULL */ -/* if no match can be found. */ - GSList *list; - Player *Play; - if (Name==NULL || Name[0]==0) return &Noone; - for (list=First;list;list=g_slist_next(list)) { - Play=(Player *)list->data; - if (!IsCop(Play) && strcmp(GetPlayerName(Play),Name)==0) return Play; - } - return NULL; -} - -price_t strtoprice(char *buf) { -/* Forms a price based on the string representation in "buf" */ - guint i,buflen,FracNum; - gchar digit,suffix; - gboolean minus,InFrac; - price_t val=0; - - minus=FALSE; - if (!buf || !buf[0]) return 0; - - buflen=strlen(buf); - suffix=buf[buflen-1]; - suffix=toupper(suffix); - if (suffix=='M') FracNum=6; - else if (suffix=='K') FracNum=3; - else FracNum=0; - - for (i=0,InFrac=FALSE;i<buflen && (!InFrac || FracNum>0);i++) { - digit=buf[i]; - if (digit=='.' || digit==',') { - InFrac=TRUE; - } else if (digit>='0' && digit<='9') { - if (InFrac) FracNum--; - val*=10; - val+=(digit-'0'); - } else if (digit=='-') minus=TRUE; + ClearList(&(Play->SpyList)); + ClearList(&(Play->TipList)); + g_free(Play->Name); + g_free(Play); + return First; +} + +/* + * Copies player "Src" to player "Dest". + */ +void CopyPlayer(Player *Dest, Player *Src) +{ + if (!Dest || !Src) + return; + Dest->Turn = Src->Turn; + Dest->Cash = Src->Cash; + Dest->Debt = Src->Debt; + Dest->Bank = Src->Bank; + Dest->Health = Src->Health; + ClearInventory(Dest->Guns, Dest->Drugs); + AddInventory(Dest->Guns, Src->Guns, NumGun); + AddInventory(Dest->Drugs, Src->Drugs, NumDrug); + Dest->CoatSize = Src->CoatSize; + Dest->IsAt = Src->IsAt; + g_free(Dest->Name); + Dest->Name = g_strdup(Src->Name); + Dest->Bitches.Carried = Src->Bitches.Carried; + Dest->Flags = Src->Flags; +} + +gboolean IsCop(Player *Play) +{ + return (Play->CopIndex > 0); +} + +char *GetPlayerName(Player *Play) +{ + if (Play->Name) + return Play->Name; + else + return ""; +} + +void SetPlayerName(Player *Play, char *Name) +{ + if (Play->Name) + g_free(Play->Name); + if (!Name) + Play->Name = g_strdup(""); + else + Play->Name = g_strdup(Name); +} + +/* + * Searches the linked list starting at "First" for a Player structure + * with the given ID. Returns a pointer to this structure, or NULL if + * no match can be found. + */ +Player *GetPlayerByID(guint ID, GSList *First) +{ + GSList *list; + Player *Play; + + for (list = First; list; list = g_slist_next(list)) { + Play = (Player *)list->data; + if (Play->ID == ID) + return Play; + } + return NULL; +} + +/* + * Searches the linked list starting at "First" for a Player structure + * with the name "Name". Returns a pointer to this structure, or NULL + * if no match can be found. + */ +Player *GetPlayerByName(char *Name, GSList *First) +{ + GSList *list; + Player *Play; + + if (Name == NULL || Name[0] == 0) + return &Noone; + for (list = First; list; list = g_slist_next(list)) { + Play = (Player *)list->data; + if (!IsCop(Play) && strcmp(GetPlayerName(Play), Name) == 0) + return Play; + } + return NULL; +} + +/* + * Forms a price based on the string representation in "buf". + */ +price_t strtoprice(char *buf) +{ + guint i, buflen, FracNum; + gchar digit, suffix; + gboolean minus, InFrac; + price_t val = 0; + + minus = FALSE; + if (!buf || !buf[0]) + return 0; + + buflen = strlen(buf); + suffix = buf[buflen - 1]; + suffix = toupper(suffix); + if (suffix == 'M') + FracNum = 6; + else if (suffix == 'K') + FracNum = 3; + else + FracNum = 0; + + for (i = 0, InFrac = FALSE; i < buflen && (!InFrac || FracNum > 0); i++) { + digit = buf[i]; + if (digit == '.' || digit == ',') { + InFrac = TRUE; + } else if (digit >= '0' && digit <= '9') { + if (InFrac) + FracNum--; + val *= 10; + val += (digit - '0'); + } else if (digit == '-') + minus = TRUE; } - for (i=0;i<FracNum;i++) val*=10; - if (minus) val=-val; + for (i = 0; i < FracNum; i++) + val *= 10; + if (minus) + val = -val; return val; } -gchar *pricetostr(price_t price) { -/* Prints "price" directly into a dynamically-allocated string buffer */ -/* and returns a pointer to this buffer. It is the responsbility of */ -/* the user to g_free this buffer when it is finished with. */ - GString *PriceStr; - gchar *NewBuffer; - price_t absprice; - - if (price<0) absprice=-price; else absprice=price; - PriceStr=g_string_new(NULL); - while (absprice!=0) { - g_string_prepend_c(PriceStr,'0'+(absprice%10)); - absprice /= 10; - if (absprice==0) { - if (price<0) g_string_prepend_c(PriceStr,'-'); - } - } - NewBuffer=PriceStr->str; - /* Free the string structure, but not the actual char array */ - g_string_free(PriceStr,FALSE); - return NewBuffer; -} - -gchar *FormatPrice(price_t price) { -/* Takes the number in "price" and prints it into a dynamically-allocated */ -/* string, adding commas to split up thousands, and adding a currency */ -/* symbol to the start. Returns a pointer to the string, which must be */ -/* g_free'd by the user when it is finished with. */ - GString *PriceStr; - gchar *NewBuffer; - char thou[10]; - gboolean First=TRUE; - price_t absprice; - PriceStr=g_string_new(NULL); - if (price<0) absprice=-price; else absprice=price; - while (First || absprice>0) { - if (absprice>=1000) sprintf(thou,"%03d",(int)(absprice%1000l)); - else sprintf(thou,"%d",(int)(price%1000l)); - price/=1000l; - absprice/=1000l; - if (!First) g_string_prepend_c(PriceStr,','); - g_string_prepend(PriceStr,thou); - First=FALSE; - } - if (Currency.Prefix) g_string_prepend(PriceStr,Currency.Symbol); - else g_string_append(PriceStr,Currency.Symbol); - - NewBuffer=PriceStr->str; - /* Free the string structure only, not the char data */ - g_string_free(PriceStr,FALSE); - return NewBuffer; -} - -int TotalGunsCarried(Player *Play) { -/* Returns the total number of guns being carried by "Play" */ - int i,c; - c=0; - for (i=0;i<NumGun;i++) c+=Play->Guns[i].Carried; - return c; -} - -gchar *InitialCaps(gchar *string) { -/* Capitalises the first character of "string" and writes the resultant */ -/* string into a dynamically-allocated copy; the user must g_free this */ -/* string (a pointer to which is returned) when it is no longer needed. */ - gchar *buf; - if (!string) return NULL; - buf=g_strdup(string); - if (strlen(buf)>=1) buf[0]=toupper(buf[0]); - return buf; -} - -char StartsWithVowel(char *string) { -/* Returns TRUE if "string" starts with a vowel */ - int c; - if (!string || strlen(string)<1) return FALSE; - c=toupper(string[0]); - return (c=='A' || c=='E' || c=='I' || c=='O' || c=='U'); -} - -int read_string(FILE *fp,char **buf) { -/* Reads a NULL-terminated string into the buffer "buf" from file "fp". */ -/* buf is sized to hold the string; this is a dynamic string and must be */ -/* freed by the calling routine. Returns 0 on success, EOF on failure. */ +/* + * Prints "price" directly into a dynamically-allocated string buffer + * and returns a pointer to this buffer. It is the responsbility of + * the user to g_free this buffer when it is finished with. + */ +gchar *pricetostr(price_t price) +{ + GString *PriceStr; + gchar *NewBuffer; + price_t absprice; + + if (price < 0) + absprice = -price; + else + absprice = price; + PriceStr = g_string_new(NULL); + while (absprice != 0) { + g_string_prepend_c(PriceStr, '0' + (absprice % 10)); + absprice /= 10; + if (absprice == 0) { + if (price < 0) + g_string_prepend_c(PriceStr, '-'); + } + } + NewBuffer = PriceStr->str; + /* Free the string structure, but not the actual char array */ + g_string_free(PriceStr, FALSE); + return NewBuffer; +} + +/* + * Takes the number in "price" and prints it into a dynamically-allocated + * string, adding commas to split up thousands, and adding a currency + * symbol to the start. Returns a pointer to the string, which must be + * g_free'd by the user when it is finished with. + */ +gchar *FormatPrice(price_t price) +{ + GString *PriceStr; + gchar *NewBuffer; + char thou[10]; + gboolean First = TRUE; + price_t absprice; + + PriceStr = g_string_new(NULL); + if (price < 0) + absprice = -price; + else + absprice = price; + while (First || absprice > 0) { + if (absprice >= 1000) + sprintf(thou, "%03d", (int)(absprice % 1000l)); + else + sprintf(thou, "%d", (int)(price % 1000l)); + price /= 1000l; + absprice /= 1000l; + if (!First) + g_string_prepend_c(PriceStr, ','); + g_string_prepend(PriceStr, thou); + First = FALSE; + } + if (Currency.Prefix) + g_string_prepend(PriceStr, Currency.Symbol); + else + g_string_append(PriceStr, Currency.Symbol); + + NewBuffer = PriceStr->str; + /* Free the string structure only, not the char data */ + g_string_free(PriceStr, FALSE); + return NewBuffer; +} + +/* + * Returns the total number of guns being carried by "Play". + */ +int TotalGunsCarried(Player *Play) +{ + int i, c; + + c = 0; + for (i = 0; i < NumGun; i++) + c += Play->Guns[i].Carried; + return c; +} + +/* + * Capitalises the first character of "string" and writes the resultant + * string into a dynamically-allocated copy; the user must g_free this + * string (a pointer to which is returned) when it is no longer needed. + */ +gchar *InitialCaps(gchar *string) +{ + gchar *buf; + + if (!string) + return NULL; + buf = g_strdup(string); + if (strlen(buf) >= 1) + buf[0] = toupper(buf[0]); + return buf; +} + +/* + * Returns TRUE if "string" starts with a vowel. + */ +char StartsWithVowel(char *string) +{ + int c; + + if (!string || strlen(string) < 1) + return FALSE; + c = toupper(string[0]); + return (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U'); +} + +/* + * Reads a NULL-terminated string into the buffer "buf" from file "fp". + * buf is sized to hold the string; this is a dynamic string and must be + * freed by the calling routine. Returns 0 on success, EOF on failure. + */ +int read_string(FILE *fp, char **buf) +{ int c; GString *text; - text=g_string_new(""); + text = g_string_new(""); do { - c=fgetc(fp); - if (c!=EOF && c!=0) g_string_append_c(text,(char)c); - } while (c!=EOF && c!=0); + c = fgetc(fp); + if (c != EOF && c != 0) + g_string_append_c(text, (char)c); + } while (c != EOF && c != 0); - *buf=text->str; + *buf = text->str; /* Free the GString, but not the actual data text->str */ - g_string_free(text,FALSE); - if (c==EOF) return EOF; else return 0; -} - -void ClearInventory(Inventory *Guns,Inventory *Drugs) { -/* This function simply clears the given inventories "Guns" */ -/* and "Drugs" if they are non-NULL */ - int i; - if (Guns) for (i=0;i<NumGun;i++) { - Guns[i].Carried=0; Guns[i].TotalValue=0; - } - if (Drugs) for (i=0;i<NumDrug;i++) { - Drugs[i].Carried=0; Drugs[i].TotalValue=0; - } -} - -char IsInventoryClear(Inventory *Guns,Inventory *Drugs) { -/* Returns TRUE only if "Guns" and "Drugs" contain no objects */ - int i; - if (Guns) for (i=0;i<NumGun;i++) if (Guns[i].Carried > 0) return FALSE; - if (Drugs) for (i=0;i<NumDrug;i++) if (Drugs[i].Carried > 0) return FALSE; - return TRUE; -} - -void AddInventory(Inventory *Cumul,Inventory *Add,int Length) { -/* Adds inventory "Add" into the contents of inventory "Cumul" */ -/* Each inventory is of length "Length" */ -/* N.B. TotalValue is not modified, as it is assumed that the */ -/* new items are free (if this is not the case it must be */ -/* handled elsewhere). */ - int i; - for (i=0;i<Length;i++) Cumul[i].Carried+=Add[i].Carried; -} - -void ChangeSpaceForInventory(Inventory *Guns,Inventory *Drugs, - Player *Play) { -/* Given the lists of "Guns" and "Drugs" (which the given player "Play" */ -/* must have sufficient room to carry) updates the player's space to */ -/* reflect carrying them. */ - int i; - if (Guns) for (i=0;i<NumGun;i++) { - Play->CoatSize-=Guns[i].Carried*Gun[i].Space; - } - if (Drugs) for (i=0;i<NumDrug;i++) { - Play->CoatSize-=Drugs[i].Carried; - } -} - -void TruncateInventoryFor(Inventory *Guns,Inventory *Drugs, - Player *Play) { -/* Discards items from "Guns" and/or "Drugs" (if non-NULL) if necessary */ -/* such that player "Play" is able to carry them all. The cheapest */ -/* objects are discarded. */ - int i,Total,CheapIndex; - int CheapestGun; - Total=0; - if (Guns) for (i=0;i<NumGun;i++) Total+=Guns[i].Carried; - Total+=TotalGunsCarried(Play); - while (Guns && Total > Play->Bitches.Carried+2) { - CheapIndex=-1; - for (i=0;i<NumGun;i++) if (Guns[i].Carried && (CheapIndex==-1 || - Gun[i].Price <= Gun[CheapIndex].Price)) { - CheapIndex=i; - } - i=Total-Play->Bitches.Carried-2; - if (Guns[CheapIndex].Carried > i) { - Guns[CheapIndex].Carried-=i; Total-=i; - } else { - Total-=Guns[CheapIndex].Carried; Guns[CheapIndex].Carried=0; - } - } - - Total=Play->CoatSize; - if (Guns) for (i=0;i<NumGun;i++) Total-=Guns[i].Carried*Gun[i].Space; - if (Drugs) for (i=0;i<NumDrug;i++) Total-=Drugs[i].Carried; - while (Total < 0) { - CheapestGun=-1; - CheapIndex=-1; - if (Guns) for (i=0;i<NumGun;i++) if (Guns[i].Carried && (CheapIndex==-1 || - Gun[i].Price <= Gun[CheapIndex].Price)) { - CheapIndex=i; CheapestGun=Gun[i].Price/Gun[i].Space; - } - if (Drugs) for (i=0;i<NumDrug;i++) if (Drugs[i].Carried && - (CheapIndex==-1 || - (CheapestGun==-1 && Drug[i].MinPrice<=Drug[CheapIndex].MinPrice) || - (CheapestGun>=0 && Drug[i].MinPrice<=CheapestGun))) { - CheapIndex=i; CheapestGun=-1; - } - if (Guns && CheapestGun>=0) { - Guns[CheapIndex].Carried--; - Total+=Gun[CheapIndex].Space; - } else { - if (Drugs && Drugs[CheapIndex].Carried >= -Total) { - Drugs[CheapIndex].TotalValue = - Drugs[CheapIndex].TotalValue* - (Drugs[CheapIndex].Carried+Total)/ - Drugs[CheapIndex].Carried; - Drugs[CheapIndex].Carried += Total; Total=0; - } else { - Total+=Drugs[CheapIndex].Carried; Drugs[CheapIndex].Carried=0; - Drugs[CheapIndex].TotalValue=0; - } - } - } -} - -int IsCarryingRandom(Player *Play,int amount) { -/* Returns an index into the drugs array of a random drug that "Play" is */ -/* carrying at least "amount" of. If no suitable drug is found after 5 */ -/* attempts, returns -1. */ - int i,ind; - for (i=0;i<5;i++) { - ind=brandom(0,NumDrug); - if (Play->Drugs[ind].Carried >= amount) { - return ind; - } - } - return -1; -} - -int GetNextDrugIndex(int OldIndex,Player *Play) { -/* Returns an index into the "Drugs" array maintained by player "Play" */ -/* of the next available drug after "OldIndex", following the current */ -/* sort method (defined globally as "DrugSortMethod") */ - int i,MaxIndex; - MaxIndex=-1; - for (i=0;i<NumDrug;i++) { - if (Play->Drugs[i].Price!=0 && i!=OldIndex && i!=MaxIndex && - (MaxIndex==-1 || - (DrugSortMethod==DS_ATOZ && - g_strcasecmp(Drug[MaxIndex].Name,Drug[i].Name)>0) || - (DrugSortMethod==DS_ZTOA && - g_strcasecmp(Drug[MaxIndex].Name,Drug[i].Name)<0) || - (DrugSortMethod==DS_CHEAPFIRST && - Play->Drugs[MaxIndex].Price > Play->Drugs[i].Price) || - (DrugSortMethod==DS_CHEAPLAST && - Play->Drugs[MaxIndex].Price < Play->Drugs[i].Price)) && - (OldIndex==-1 || - (DrugSortMethod==DS_ATOZ && - g_strcasecmp(Drug[OldIndex].Name,Drug[i].Name)<=0) || - (DrugSortMethod==DS_ZTOA && - g_strcasecmp(Drug[OldIndex].Name,Drug[i].Name)>=0) || - (DrugSortMethod==DS_CHEAPFIRST && - Play->Drugs[OldIndex].Price <= Play->Drugs[i].Price) || - (DrugSortMethod==DS_CHEAPLAST && - Play->Drugs[OldIndex].Price >= Play->Drugs[i].Price))) { - MaxIndex=i; - } - } - return MaxIndex; -} + g_string_free(text, FALSE); + if (c == EOF) + return EOF; + else + return 0; +} + +/* + * This function simply clears the given inventories "Guns" + * and "Drugs" if they are non-NULL. + */ +void ClearInventory(Inventory *Guns, Inventory *Drugs) +{ + int i; -void InitList(DopeList *List) { -/* A DopeList is akin to a Vector class; it is a list of DopeEntry */ -/* structures, which can be dynamically extended or compressed. This */ -/* function initialises the newly-created list pointed to by "List" */ -/* (A DopeEntry contains a Player pointer and a counter, and is used */ -/* by the server to keep track of tipoffs and spies.) */ - List->Data=NULL; - List->Number=0; + if (Guns) + for (i = 0; i < NumGun; i++) { + Guns[i].Carried = 0; + Guns[i].TotalValue = 0; + } + if (Drugs) + for (i = 0; i < NumDrug; i++) { + Drugs[i].Carried = 0; + Drugs[i].TotalValue = 0; + } } -void ClearList(DopeList *List) { -/* Clears the list pointed to by "List" */ - free(List->Data); - InitList(List); +/* + * Returns TRUE only if "Guns" and "Drugs" contain no objects. + */ +char IsInventoryClear(Inventory *Guns, Inventory *Drugs) +{ + int i; + + if (Guns) + for (i = 0; i < NumGun; i++) + if (Guns[i].Carried > 0) + return FALSE; + if (Drugs) + for (i = 0; i < NumDrug; i++) + if (Drugs[i].Carried > 0) + return FALSE; + return TRUE; +} + +/* + * Adds inventory "Add" into the contents of inventory "Cumul" + * Each inventory is of length "Length". + * N.B. TotalValue is not modified, as it is assumed that the + * new items are free (if this is not the case it must be + * handled elsewhere). + */ +void AddInventory(Inventory *Cumul, Inventory *Add, int Length) +{ + int i; + + for (i = 0; i < Length; i++) + Cumul[i].Carried += Add[i].Carried; } -void AddListEntry(DopeList *List,DopeEntry *NewEntry) { -/* Adds a new DopeEntry (pointed to by "NewEntry") to the list "List". */ -/* A copy of NewEntry is placed into the list, so the original */ -/* structure pointed to by NewEntry can be reused. */ - if (!NewEntry || !List) return; - List->Number++; - List->Data = (DopeEntry *)g_realloc(List->Data,List->Number* - sizeof(DopeEntry)); - g_memmove(&(List->Data[List->Number-1]),NewEntry,sizeof(DopeEntry)); +/* + * Given the lists of "Guns" and "Drugs" (which the given player "Play" + * must have sufficient room to carry) updates the player's space to + * reflect carrying them. + */ +void ChangeSpaceForInventory(Inventory *Guns, Inventory *Drugs, + Player *Play) +{ + int i; + + if (Guns) + for (i = 0; i < NumGun; i++) { + Play->CoatSize -= Guns[i].Carried * Gun[i].Space; + } + if (Drugs) + for (i = 0; i < NumDrug; i++) { + Play->CoatSize -= Drugs[i].Carried; + } } -void RemoveListEntry(DopeList *List,int Index) { -/* Removes the DopeEntry at index "Index" from list "List" */ - if (!List || Index<0 || Index>=List->Number) return; +/* + * Discards items from "Guns" and/or "Drugs" (if non-NULL) if necessary + * such that player "Play" is able to carry them all. The cheapest + * objects are discarded. + */ +void TruncateInventoryFor(Inventory *Guns, Inventory *Drugs, Player *Play) +{ + int i, Total, CheapIndex; + int CheapestGun; + + Total = 0; + if (Guns) + for (i = 0; i < NumGun; i++) + Total += Guns[i].Carried; + Total += TotalGunsCarried(Play); + while (Guns && Total > Play->Bitches.Carried + 2) { + CheapIndex = -1; + for (i = 0; i < NumGun; i++) + if (Guns[i].Carried && (CheapIndex == -1 + || Gun[i].Price <= Gun[CheapIndex].Price)) { + CheapIndex = i; + } + i = Total - Play->Bitches.Carried - 2; + if (Guns[CheapIndex].Carried > i) { + Guns[CheapIndex].Carried -= i; + Total -= i; + } else { + Total -= Guns[CheapIndex].Carried; + Guns[CheapIndex].Carried = 0; + } + } - g_memmove(&(List->Data[Index]),&(List->Data[Index+1]), - (List->Number-1-Index)*sizeof(DopeEntry)); - List->Number--; - List->Data = (DopeEntry *)g_realloc(List->Data,List->Number* - sizeof(DopeEntry)); - if (List->Number==0) List->Data=NULL; + Total = Play->CoatSize; + if (Guns) + for (i = 0; i < NumGun; i++) + Total -= Guns[i].Carried * Gun[i].Space; + if (Drugs) + for (i = 0; i < NumDrug; i++) + Total -= Drugs[i].Carried; + while (Total < 0) { + CheapestGun = -1; + CheapIndex = -1; + if (Guns) + for (i = 0; i < NumGun; i++) + if (Guns[i].Carried && (CheapIndex == -1 + || Gun[i].Price <= Gun[CheapIndex].Price)) { + CheapIndex = i; + CheapestGun = Gun[i].Price / Gun[i].Space; + } + if (Drugs) + for (i = 0; i < NumDrug; i++) + if (Drugs[i].Carried && + (CheapIndex == -1 || + (CheapestGun == -1 + && Drug[i].MinPrice <= Drug[CheapIndex].MinPrice) + || (CheapestGun >= 0 && Drug[i].MinPrice <= CheapestGun))) { + CheapIndex = i; + CheapestGun = -1; + } + if (Guns && CheapestGun >= 0) { + Guns[CheapIndex].Carried--; + Total += Gun[CheapIndex].Space; + } else { + if (Drugs && Drugs[CheapIndex].Carried >= -Total) { + Drugs[CheapIndex].TotalValue = + Drugs[CheapIndex].TotalValue * + (Drugs[CheapIndex].Carried + Total) / + Drugs[CheapIndex].Carried; + Drugs[CheapIndex].Carried += Total; + Total = 0; + } else { + Total += Drugs[CheapIndex].Carried; + Drugs[CheapIndex].Carried = 0; + Drugs[CheapIndex].TotalValue = 0; + } + } + } } -int GetListEntry(DopeList *List,Player *Play) { -/* Returns the index of the DopeEntry matching "Play" in list "List" */ -/* or -1 if this is not found. */ - int i; - for (i=List->Number-1;i>=0;i--) { - if (List->Data[i].Play==Play) return i; - } - return -1; +/* + * Returns an index into the drugs array of a random drug that "Play" is + * carrying at least "amount" of. If no suitable drug is found after 5 + * attempts, returns -1. + */ +int IsCarryingRandom(Player *Play, int amount) +{ + int i, ind; + + for (i = 0; i < 5; i++) { + ind = brandom(0, NumDrug); + if (Play->Drugs[ind].Carried >= amount) { + return ind; + } + } + return -1; +} + +/* + * Returns an index into the "Drugs" array maintained by player "Play" + * of the next available drug after "OldIndex", following the current + * sort method (defined globally as "DrugSortMethod"). + */ +int GetNextDrugIndex(int OldIndex, Player *Play) +{ + int i, MaxIndex; + + MaxIndex = -1; + for (i = 0; i < NumDrug; i++) { + if (Play->Drugs[i].Price != 0 && i != OldIndex && i != MaxIndex && + (MaxIndex == -1 + || (DrugSortMethod == DS_ATOZ + && g_strcasecmp(Drug[MaxIndex].Name, Drug[i].Name) > 0) + || (DrugSortMethod == DS_ZTOA + && g_strcasecmp(Drug[MaxIndex].Name, Drug[i].Name) < 0) + || (DrugSortMethod == DS_CHEAPFIRST + && Play->Drugs[MaxIndex].Price > Play->Drugs[i].Price) + || (DrugSortMethod == DS_CHEAPLAST + && Play->Drugs[MaxIndex].Price < Play->Drugs[i].Price)) && + (OldIndex == -1 + || (DrugSortMethod == DS_ATOZ + && g_strcasecmp(Drug[OldIndex].Name, Drug[i].Name) <= 0) + || (DrugSortMethod == DS_ZTOA + && g_strcasecmp(Drug[OldIndex].Name, Drug[i].Name) >= 0) + || (DrugSortMethod == DS_CHEAPFIRST + && Play->Drugs[OldIndex].Price <= Play->Drugs[i].Price) + || (DrugSortMethod == DS_CHEAPLAST + && Play->Drugs[OldIndex].Price >= Play->Drugs[i].Price))) { + MaxIndex = i; + } + } + return MaxIndex; +} + +/* + * A DopeList is akin to a Vector class; it is a list of DopeEntry + * structures, which can be dynamically extended or compressed. This + * function initialises the newly-created list pointed to by "List" + * (A DopeEntry contains a Player pointer and a counter, and is used + * by the server to keep track of tipoffs and spies.) + */ +void InitList(DopeList *List) +{ + List->Data = NULL; + List->Number = 0; +} + +/* + * Clears the list pointed to by "List". + */ +void ClearList(DopeList *List) +{ + free(List->Data); + InitList(List); +} + +/* + * Adds a new DopeEntry (pointed to by "NewEntry") to the list "List". + * A copy of NewEntry is placed into the list, so the original + * structure pointed to by NewEntry can be reused. + */ +void AddListEntry(DopeList *List, DopeEntry *NewEntry) +{ + if (!NewEntry || !List) + return; + List->Number++; + List->Data = (DopeEntry *)g_realloc(List->Data, List->Number * + sizeof(DopeEntry)); + g_memmove(&(List->Data[List->Number - 1]), NewEntry, sizeof(DopeEntry)); +} + +/* + * Removes the DopeEntry at index "Index" from list "List". + */ +void RemoveListEntry(DopeList *List, int Index) +{ + if (!List || Index < 0 || Index >= List->Number) + return; + + g_memmove(&(List->Data[Index]), &(List->Data[Index + 1]), + (List->Number - 1 - Index) * sizeof(DopeEntry)); + List->Number--; + List->Data = (DopeEntry *)g_realloc(List->Data, List->Number * + sizeof(DopeEntry)); + if (List->Number == 0) + List->Data = NULL; +} + +/* + * Returns the index of the DopeEntry matching "Play" in list "List" + * or -1 if this is not found. + */ +int GetListEntry(DopeList *List, Player *Play) +{ + int i; + + for (i = List->Number - 1; i >= 0; i--) { + if (List->Data[i].Play == Play) + return i; + } + return -1; } -void RemoveListPlayer(DopeList *List,Player *Play) { -/* Removes (if it exists) the DopeEntry in list "List" matching "Play" */ - RemoveListEntry(List,GetListEntry(List,Play)); +/* + * Removes (if it exists) the DopeEntry in list "List" matching "Play". + */ +void RemoveListPlayer(DopeList *List, Player *Play) +{ + RemoveListEntry(List, GetListEntry(List, Play)); } -void RemoveAllEntries(DopeList *List,Player *Play) { -/* Similar to RemoveListPlayer, except that if the list contains "Play" */ -/* more than once, all the matching entries are removed, not just the first */ +/* + * Similar to RemoveListPlayer, except that if the list contains "Play" more + * than once, all the matching entries are removed, not just the first. + */ +void RemoveAllEntries(DopeList *List, Player *Play) +{ int i; + do { - i=GetListEntry(List,Play); - if (i>=0) RemoveListEntry(List,i); - } while (i>=0); -} - -void dopelog(int loglevel,const gchar *format,...) { -/* General logging function. All messages should be given a loglevel, */ -/* from 0 to 5 (0=vital, 2=normal, 5=maximum debugging output). This */ -/* is essentially just a wrapper around the GLib g_log function. */ - va_list args; - if (!Network) return; /* Don't print server log messages when - running standalone */ - va_start (args,format); - g_logv(G_LOG_DOMAIN,1<<(loglevel+G_LOG_LEVEL_USER_SHIFT),format,args); - va_end (args); -} - -GLogLevelFlags LogMask() { -/* Returns the bitmask necessary to catch all custom log messages */ - return ((1<<(MAXLOG))-1) << G_LOG_LEVEL_USER_SHIFT; -} - -void ResizeLocations(int NewNum) { - int i; - if (NewNum<NumLocation) for (i=NewNum;i<NumLocation;i++) { + i = GetListEntry(List, Play); + if (i >= 0) + RemoveListEntry(List, i); + } while (i >= 0); +} + +/* + * General logging function. All messages should be given a loglevel, + * from 0 to 5 (0=vital, 2=normal, 5=maximum debugging output). This + * is essentially just a wrapper around the GLib g_log function. + */ +void dopelog(int loglevel, const gchar *format, ...) +{ + va_list args; + + if (!Network) + return; /* Don't print server log messages when + * running standalone */ + va_start(args, format); + g_logv(G_LOG_DOMAIN, 1 << (loglevel + G_LOG_LEVEL_USER_SHIFT), format, + args); + va_end(args); +} + +/* + * Returns the bitmask necessary to catch all custom log messages. + */ +GLogLevelFlags LogMask() +{ + return ((1 << (MAXLOG)) - 1) << G_LOG_LEVEL_USER_SHIFT; +} + +void ResizeLocations(int NewNum) +{ + int i; + + if (NewNum < NumLocation) + for (i = NewNum; i < NumLocation; i++) { g_free(Location[i].Name); - } - Location=g_realloc(Location,sizeof(struct LOCATION)*NewNum); - if (NewNum>NumLocation) { - memset(&Location[NumLocation],0, - (NewNum-NumLocation)*sizeof(struct LOCATION)); - for (i=NumLocation;i<NewNum;i++) { - Location[i].Name=g_strdup(""); - } - } - NumLocation=NewNum; + } + Location = g_realloc(Location, sizeof(struct LOCATION) * NewNum); + if (NewNum > NumLocation) { + memset(&Location[NumLocation], 0, + (NewNum - NumLocation) * sizeof(struct LOCATION)); + for (i = NumLocation; i < NewNum; i++) { + Location[i].Name = g_strdup(""); + } + } + NumLocation = NewNum; } -void ResizeCops(int NewNum) { - int i; - if (NewNum<NumCop) for (i=NewNum;i<NumCop;i++) { +void ResizeCops(int NewNum) +{ + int i; + + if (NewNum < NumCop) + for (i = NewNum; i < NumCop; i++) { g_free(Cop[i].Name); g_free(Cop[i].DeputyName); g_free(Cop[i].DeputiesName); - } - Cop=g_realloc(Cop,sizeof(struct COP)*NewNum); - if (NewNum>NumCop) { - memset(&Cop[NumCop],0,(NewNum-NumCop)*sizeof(struct COP)); - for (i=NumCop;i<NewNum;i++) { - Cop[i].Name=g_strdup(""); - Cop[i].DeputyName=g_strdup(""); - Cop[i].DeputiesName=g_strdup(""); - } - } - NumCop=NewNum; + } + Cop = g_realloc(Cop, sizeof(struct COP) * NewNum); + if (NewNum > NumCop) { + memset(&Cop[NumCop], 0, (NewNum - NumCop) * sizeof(struct COP)); + for (i = NumCop; i < NewNum; i++) { + Cop[i].Name = g_strdup(""); + Cop[i].DeputyName = g_strdup(""); + Cop[i].DeputiesName = g_strdup(""); + } + } + NumCop = NewNum; } -void ResizeGuns(int NewNum) { - int i; - if (NewNum<NumGun) for (i=NewNum;i<NumGun;i++) { +void ResizeGuns(int NewNum) +{ + int i; + + if (NewNum < NumGun) + for (i = NewNum; i < NumGun; i++) { g_free(Gun[i].Name); - } - Gun=g_realloc(Gun,sizeof(struct GUN)*NewNum); - if (NewNum>NumGun) { - memset(&Gun[NumGun],0,(NewNum-NumGun)*sizeof(struct GUN)); - for (i=NumGun;i<NewNum;i++) { - Gun[i].Name=g_strdup(""); - } - } - NumGun=NewNum; -} - -void ResizeDrugs(int NewNum) { - int i; - if (NewNum<NumDrug) for (i=NewNum;i<NumDrug;i++) { - g_free(Drug[i].Name); g_free(Drug[i].CheapStr); - } - Drug=g_realloc(Drug,sizeof(struct DRUG)*NewNum); - if (NewNum>NumDrug) { - memset(&Drug[NumDrug],0, - (NewNum-NumDrug)*sizeof(struct DRUG)); - for (i=NumDrug;i<NewNum;i++) { - Drug[i].Name=g_strdup(""); Drug[i].CheapStr=g_strdup(""); - } - } - NumDrug=NewNum; + } + Gun = g_realloc(Gun, sizeof(struct GUN) * NewNum); + if (NewNum > NumGun) { + memset(&Gun[NumGun], 0, (NewNum - NumGun) * sizeof(struct GUN)); + for (i = NumGun; i < NewNum; i++) { + Gun[i].Name = g_strdup(""); + } + } + NumGun = NewNum; } -void ResizeSubway(int NewNum) { - int i; - if (NewNum<NumSubway) for (i=NewNum;i<NumSubway;i++) { - g_free(SubwaySaying[i]); - } - SubwaySaying=g_realloc(SubwaySaying,sizeof(char *)*NewNum); - if (NewNum>NumSubway) for (i=NumSubway;i<NewNum;i++) { - SubwaySaying[i]=g_strdup(""); - } - NumSubway=NewNum; -} +void ResizeDrugs(int NewNum) +{ + int i; -void ResizePlaying(int NewNum) { - int i; - if (NewNum<NumPlaying) for (i=NewNum;i<NumPlaying;i++) { - g_free(Playing[i]); - } - Playing=g_realloc(Playing,sizeof(char *)*NewNum); - if (NewNum>NumPlaying) for (i=NumPlaying;i<NewNum;i++) { - Playing[i]=g_strdup(""); - } - NumPlaying=NewNum; + if (NewNum < NumDrug) + for (i = NewNum; i < NumDrug; i++) { + g_free(Drug[i].Name); + g_free(Drug[i].CheapStr); + } + Drug = g_realloc(Drug, sizeof(struct DRUG) * NewNum); + if (NewNum > NumDrug) { + memset(&Drug[NumDrug], 0, (NewNum - NumDrug) * sizeof(struct DRUG)); + for (i = NumDrug; i < NewNum; i++) { + Drug[i].Name = g_strdup(""); + Drug[i].CheapStr = g_strdup(""); + } + } + NumDrug = NewNum; } -void ResizeStoppedTo(int NewNum) { - int i; - if (NewNum<NumStoppedTo) for (i=NewNum;i<NumStoppedTo;i++) { - g_free(StoppedTo[i]); - } - StoppedTo=g_realloc(StoppedTo,sizeof(char *)*NewNum); - if (NewNum>NumStoppedTo) for (i=NumStoppedTo;i<NewNum;i++) { - StoppedTo[i]=g_strdup(""); - } - NumStoppedTo=NewNum; -} - -void AssignName(gchar **dest,gchar *src) { -/* Sets the dynamically-sized string pointed to by *dest to a copy of */ -/* "src" - src can safely be freed or reused afterwards. Any existing */ -/* string in "dest" is freed. The function returns immediately if src */ -/* and *dest are already the same. */ - if (*dest == src) return; - g_free(*dest); - *dest=g_strdup(src); -} - -void CopyNames(struct NAMES *dest,struct NAMES *src) { - AssignName(&dest->Bitch,_(src->Bitch)); - AssignName(&dest->Bitches,_(src->Bitches)); - AssignName(&dest->Gun,_(src->Gun)); - AssignName(&dest->Guns,_(src->Guns)); - AssignName(&dest->Drug,_(src->Drug)); - AssignName(&dest->Drugs,_(src->Drugs)); - AssignName(&dest->Month,_(src->Month)); - AssignName(&dest->Year,_(src->Year)); - AssignName(&dest->LoanSharkName,_(src->LoanSharkName)); - AssignName(&dest->BankName,_(src->BankName)); - AssignName(&dest->GunShopName,_(src->GunShopName)); - AssignName(&dest->RoughPubName,_(src->RoughPubName)); -} +void ResizeSubway(int NewNum) +{ + int i; -#ifdef NETWORKING -void CopyMetaServer(struct METASERVER *dest,struct METASERVER *src) { - dest->Active=src->Active; - dest->Port=src->Port; - dest->ProxyPort=src->ProxyPort; - dest->UseSocks=src->UseSocks; - AssignName(&dest->Name,src->Name); - AssignName(&dest->ProxyName,src->ProxyName); - AssignName(&dest->Path,src->Path); - AssignName(&dest->LocalName,src->LocalName); - AssignName(&dest->Password,src->Password); - AssignName(&dest->Comment,src->Comment); - AssignName(&dest->authuser,src->authuser); - AssignName(&dest->authpassword,src->authpassword); - AssignName(&dest->proxyuser,src->proxyuser); - AssignName(&dest->proxypassword,src->proxypassword); + if (NewNum < NumSubway) + for (i = NewNum; i < NumSubway; i++) { + g_free(SubwaySaying[i]); + } + SubwaySaying = g_realloc(SubwaySaying, sizeof(char *) * NewNum); + if (NewNum > NumSubway) + for (i = NumSubway; i < NewNum; i++) { + SubwaySaying[i] = g_strdup(""); + } + NumSubway = NewNum; } -#endif -void CopyLocation(struct LOCATION *dest,struct LOCATION *src) { - AssignName(&dest->Name,_(src->Name)); - dest->PolicePresence=src->PolicePresence; - dest->MinDrug=src->MinDrug; dest->MaxDrug=src->MaxDrug; -} +void ResizePlaying(int NewNum) +{ + int i; -void CopyCop(struct COP *dest,struct COP *src) { - AssignName(&dest->Name,_(src->Name)); - AssignName(&dest->DeputyName,_(src->DeputyName)); - AssignName(&dest->DeputiesName,_(src->DeputiesName)); - dest->Armour=src->Armour; - dest->DeputyArmour=src->DeputyArmour; - dest->AttackPenalty=src->AttackPenalty; - dest->DefendPenalty=src->DefendPenalty; - dest->MinDeputies=src->MinDeputies; - dest->MaxDeputies=src->MaxDeputies; - dest->GunIndex=src->GunIndex; - dest->CopGun=src->CopGun; - dest->DeputyGun=src->DeputyGun; + if (NewNum < NumPlaying) + for (i = NewNum; i < NumPlaying; i++) { + g_free(Playing[i]); + } + Playing = g_realloc(Playing, sizeof(char *) * NewNum); + if (NewNum > NumPlaying) + for (i = NumPlaying; i < NewNum; i++) { + Playing[i] = g_strdup(""); + } + NumPlaying = NewNum; } -void CopyGun(struct GUN *dest,struct GUN *src) { - AssignName(&dest->Name,_(src->Name)); - dest->Price=src->Price; - dest->Space=src->Space; - dest->Damage=src->Damage; +void ResizeStoppedTo(int NewNum) +{ + int i; + + if (NewNum < NumStoppedTo) + for (i = NewNum; i < NumStoppedTo; i++) { + g_free(StoppedTo[i]); + } + StoppedTo = g_realloc(StoppedTo, sizeof(char *) * NewNum); + if (NewNum > NumStoppedTo) + for (i = NumStoppedTo; i < NewNum; i++) { + StoppedTo[i] = g_strdup(""); + } + NumStoppedTo = NewNum; +} + +/* + * Sets the dynamically-sized string pointed to by *dest to a copy of + * "src" - src can safely be freed or reused afterwards. Any existing + * string in "dest" is freed. The function returns immediately if src + * and *dest are already the same. + */ +void AssignName(gchar **dest, gchar *src) +{ + if (*dest == src) + return; + g_free(*dest); + *dest = g_strdup(src); +} + +void CopyNames(struct NAMES *dest, struct NAMES *src) +{ + AssignName(&dest->Bitch, _(src->Bitch)); + AssignName(&dest->Bitches, _(src->Bitches)); + AssignName(&dest->Gun, _(src->Gun)); + AssignName(&dest->Guns, _(src->Guns)); + AssignName(&dest->Drug, _(src->Drug)); + AssignName(&dest->Drugs, _(src->Drugs)); + AssignName(&dest->Month, _(src->Month)); + AssignName(&dest->Year, _(src->Year)); + AssignName(&dest->LoanSharkName, _(src->LoanSharkName)); + AssignName(&dest->BankName, _(src->BankName)); + AssignName(&dest->GunShopName, _(src->GunShopName)); + AssignName(&dest->RoughPubName, _(src->RoughPubName)); } -void CopyDrug(struct DRUG *dest,struct DRUG *src) { - AssignName(&dest->Name,_(src->Name)); - dest->MinPrice=src->MinPrice; - dest->MaxPrice=src->MaxPrice; - dest->Cheap=src->Cheap; - dest->Expensive=src->Expensive; - AssignName(&dest->CheapStr,_(src->CheapStr)); +#ifdef NETWORKING +void CopyMetaServer(struct METASERVER *dest, struct METASERVER *src) +{ + dest->Active = src->Active; + dest->Port = src->Port; + dest->ProxyPort = src->ProxyPort; + dest->UseSocks = src->UseSocks; + AssignName(&dest->Name, src->Name); + AssignName(&dest->ProxyName, src->ProxyName); + AssignName(&dest->Path, src->Path); + AssignName(&dest->LocalName, src->LocalName); + AssignName(&dest->Password, src->Password); + AssignName(&dest->Comment, src->Comment); + AssignName(&dest->authuser, src->authuser); + AssignName(&dest->authpassword, src->authpassword); + AssignName(&dest->proxyuser, src->proxyuser); + AssignName(&dest->proxypassword, src->proxypassword); } +#endif -void CopyDrugs(struct DRUGS *dest,struct DRUGS *src) { - AssignName(&dest->ExpensiveStr1,_(src->ExpensiveStr1)); - AssignName(&dest->ExpensiveStr2,_(src->ExpensiveStr2)); - dest->CheapDivide=src->CheapDivide; - dest->ExpensiveMultiply=src->ExpensiveMultiply; +void CopyLocation(struct LOCATION *dest, struct LOCATION *src) +{ + AssignName(&dest->Name, _(src->Name)); + dest->PolicePresence = src->PolicePresence; + dest->MinDrug = src->MinDrug; + dest->MaxDrug = src->MaxDrug; +} + +void CopyCop(struct COP *dest, struct COP *src) +{ + AssignName(&dest->Name, _(src->Name)); + AssignName(&dest->DeputyName, _(src->DeputyName)); + AssignName(&dest->DeputiesName, _(src->DeputiesName)); + dest->Armour = src->Armour; + dest->DeputyArmour = src->DeputyArmour; + dest->AttackPenalty = src->AttackPenalty; + dest->DefendPenalty = src->DefendPenalty; + dest->MinDeputies = src->MinDeputies; + dest->MaxDeputies = src->MaxDeputies; + dest->GunIndex = src->GunIndex; + dest->CopGun = src->CopGun; + dest->DeputyGun = src->DeputyGun; +} + +void CopyGun(struct GUN *dest, struct GUN *src) +{ + AssignName(&dest->Name, _(src->Name)); + dest->Price = src->Price; + dest->Space = src->Space; + dest->Damage = src->Damage; +} + +void CopyDrug(struct DRUG *dest, struct DRUG *src) +{ + AssignName(&dest->Name, _(src->Name)); + dest->MinPrice = src->MinPrice; + dest->MaxPrice = src->MaxPrice; + dest->Cheap = src->Cheap; + dest->Expensive = src->Expensive; + AssignName(&dest->CheapStr, _(src->CheapStr)); +} + +void CopyDrugs(struct DRUGS *dest, struct DRUGS *src) +{ + AssignName(&dest->ExpensiveStr1, _(src->ExpensiveStr1)); + AssignName(&dest->ExpensiveStr2, _(src->ExpensiveStr2)); + dest->CheapDivide = src->CheapDivide; + dest->ExpensiveMultiply = src->ExpensiveMultiply; } static struct PRICES BackupPrices; static struct NAMES BackupNames; -static struct DRUG *BackupDrug=NULL; -static struct GUN *BackupGun=NULL; -static struct LOCATION *BackupLocation=NULL; -static struct CURRENCY BackupCurrency = { NULL,TRUE }; -static gint NumBackupDrug=0,NumBackupGun=0,NumBackupLocation=0; - -void BackupConfig(void) { +static struct DRUG *BackupDrug = NULL; +static struct GUN *BackupGun = NULL; +static struct LOCATION *BackupLocation = NULL; +static struct CURRENCY BackupCurrency = { NULL, TRUE }; +static gint NumBackupDrug = 0, NumBackupGun = 0, NumBackupLocation = 0; + +void BackupConfig(void) +{ gint i; + BackupPrices.Spy = Prices.Spy; BackupPrices.Tipoff = Prices.Tipoff; - AssignName(&BackupCurrency.Symbol,Currency.Symbol); + AssignName(&BackupCurrency.Symbol, Currency.Symbol); BackupCurrency.Prefix = Currency.Prefix; - CopyNames(&BackupNames,&Names); + CopyNames(&BackupNames, &Names); -/* Free existing backups of guns, drugs, and locations */ - for (i=0;i<NumBackupGun;i++) g_free(BackupGun[i].Name); + /* Free existing backups of guns, drugs, and locations */ + for (i = 0; i < NumBackupGun; i++) + g_free(BackupGun[i].Name); g_free(BackupGun); - for (i=0;i<NumBackupDrug;i++) { + for (i = 0; i < NumBackupDrug; i++) { g_free(BackupDrug[i].Name); g_free(BackupDrug[i].CheapStr); } g_free(BackupDrug); - for (i=0;i<NumBackupLocation;i++) g_free(BackupLocation[i].Name); + for (i = 0; i < NumBackupLocation; i++) + g_free(BackupLocation[i].Name); g_free(BackupLocation); NumBackupGun = NumGun; - BackupGun = g_new0(struct GUN,NumGun); - for (i=0;i<NumGun;i++) CopyGun(&BackupGun[i],&Gun[i]); + BackupGun = g_new0(struct GUN, NumGun); + + for (i = 0; i < NumGun; i++) + CopyGun(&BackupGun[i], &Gun[i]); NumBackupDrug = NumDrug; - BackupDrug = g_new0(struct DRUG,NumDrug); - for (i=0;i<NumDrug;i++) CopyDrug(&BackupDrug[i],&Drug[i]); + BackupDrug = g_new0(struct DRUG, NumDrug); + + for (i = 0; i < NumDrug; i++) + CopyDrug(&BackupDrug[i], &Drug[i]); NumBackupLocation = NumLocation; - BackupLocation = g_new0(struct LOCATION,NumLocation); - for (i=0;i<NumLocation;i++) CopyLocation(&BackupLocation[i],&Location[i]); + BackupLocation = g_new0(struct LOCATION, NumLocation); + + for (i = 0; i < NumLocation; i++) + CopyLocation(&BackupLocation[i], &Location[i]); } -void RestoreConfig(void) { +void RestoreConfig(void) +{ gint i; Prices.Spy = BackupPrices.Spy; Prices.Tipoff = BackupPrices.Tipoff; - CopyNames(&Names,&BackupNames); - AssignName(&Currency.Symbol,BackupCurrency.Symbol); + CopyNames(&Names, &BackupNames); + AssignName(&Currency.Symbol, BackupCurrency.Symbol); Currency.Prefix = BackupCurrency.Prefix; ResizeGuns(NumBackupGun); - for (i=0;i<NumGun;i++) CopyGun(&Gun[i],&BackupGun[i]); + for (i = 0; i < NumGun; i++) + CopyGun(&Gun[i], &BackupGun[i]); ResizeDrugs(NumBackupDrug); - for (i=0;i<NumDrug;i++) CopyDrug(&Drug[i],&BackupDrug[i]); + for (i = 0; i < NumDrug; i++) + CopyDrug(&Drug[i], &BackupDrug[i]); ResizeLocations(NumBackupLocation); - for (i=0;i<NumLocation;i++) CopyLocation(&Location[i],&BackupLocation[i]); + for (i = 0; i < NumLocation; i++) + CopyLocation(&Location[i], &BackupLocation[i]); } -void ScannerErrorHandler(GScanner *scanner,gchar *msg,gint error) { - g_print("%s\n",msg); +void ScannerErrorHandler(GScanner *scanner, gchar *msg, gint error) +{ + g_print("%s\n", msg); } -void ReadConfigFile(char *FileName) { -/* Read a configuration file given by "FileName"; GScanner under Win32 */ -/* doesn't work properly with files, so we use a nasty workaround */ +/* + * Read a configuration file given by "FileName"; GScanner under Win32 + * doesn't work properly with files, so we use a nasty workaround. + */ +void ReadConfigFile(char *FileName) +{ FILE *fp; + #ifdef CYGWIN char *buf; #endif GScanner *scanner; - fp=fopen(FileName,"r"); + + fp = fopen(FileName, "r"); if (fp) { - scanner=g_scanner_new(&ScannerConfig); - scanner->input_name=FileName; - scanner->msg_handler=ScannerErrorHandler; + scanner = g_scanner_new(&ScannerConfig); + scanner->input_name = FileName; + scanner->msg_handler = ScannerErrorHandler; #ifdef CYGWIN - read_string(fp,&buf); if (!buf) { fclose(fp); return; } - g_scanner_input_text(scanner,buf,strlen(buf)); + read_string(fp, &buf); + if (!buf) { + fclose(fp); + return; + } + g_scanner_input_text(scanner, buf, strlen(buf)); #else - g_scanner_input_file(scanner,fileno(fp)); + g_scanner_input_file(scanner, fileno(fp)); #endif - while (!g_scanner_eof(scanner)) if (!ParseNextConfig(scanner,FALSE)) { - ConfigErrors++; - g_scanner_error(scanner, - _("Unable to process configuration file %s, line %d"), - FileName,g_scanner_cur_line(scanner)); - } + while (!g_scanner_eof(scanner)) + if (!ParseNextConfig(scanner, FALSE)) { + ConfigErrors++; + g_scanner_error(scanner, + _("Unable to process configuration file %s, line %d"), + FileName, g_scanner_cur_line(scanner)); + } g_scanner_destroy(scanner); fclose(fp); #ifdef CYGWIN t@@ -1468,443 +1768,489 @@ void ReadConfigFile(char *FileName) { } } -gboolean ParseNextConfig(GScanner *scanner,gboolean print) { - GTokenType token; - gchar *ID1,*ID2; - gulong ind=0; - int GlobalIndex; - gboolean IndexGiven=FALSE; - - ID1=ID2=NULL; - token=g_scanner_get_next_token(scanner); - if (token==G_TOKEN_EOF) return TRUE; - if (token!=G_TOKEN_IDENTIFIER) { - g_scanner_unexp_token(scanner,G_TOKEN_IDENTIFIER,NULL,NULL, - NULL,NULL,FALSE); +gboolean ParseNextConfig(GScanner *scanner, gboolean print) +{ + GTokenType token; + gchar *ID1, *ID2; + gulong ind = 0; + int GlobalIndex; + gboolean IndexGiven = FALSE; + + ID1 = ID2 = NULL; + token = g_scanner_get_next_token(scanner); + if (token == G_TOKEN_EOF) + return TRUE; + if (token != G_TOKEN_IDENTIFIER) { + g_scanner_unexp_token(scanner, G_TOKEN_IDENTIFIER, NULL, NULL, + NULL, NULL, FALSE); + return FALSE; + } + ID1 = g_strdup(scanner->value.v_identifier); + token = g_scanner_get_next_token(scanner); + if (token == G_TOKEN_LEFT_BRACE) { + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_INT) { + g_scanner_unexp_token(scanner, G_TOKEN_INT, NULL, NULL, + NULL, NULL, FALSE); return FALSE; - } - ID1=g_strdup(scanner->value.v_identifier); - token=g_scanner_get_next_token(scanner); - if (token==G_TOKEN_LEFT_BRACE) { - token=g_scanner_get_next_token(scanner); - if (token!=G_TOKEN_INT) { - g_scanner_unexp_token(scanner,G_TOKEN_INT,NULL,NULL, - NULL,NULL,FALSE); - return FALSE; - } - ind=scanner->value.v_int; - IndexGiven=TRUE; - token=g_scanner_get_next_token(scanner); - if (token!=G_TOKEN_RIGHT_BRACE) { - g_scanner_unexp_token(scanner,G_TOKEN_RIGHT_BRACE,NULL,NULL, - NULL,NULL,FALSE); - return FALSE; - } - token=g_scanner_get_next_token(scanner); - if (token=='.') { - token=g_scanner_get_next_token(scanner); - if (token!=G_TOKEN_IDENTIFIER) { - g_scanner_unexp_token(scanner,G_TOKEN_IDENTIFIER,NULL,NULL, - NULL,NULL,FALSE); - return FALSE; - } - ID2=g_strdup(scanner->value.v_identifier); - token=g_scanner_get_next_token(scanner); - } - } - GlobalIndex=GetGlobalIndex(ID1,ID2); - g_free(ID1); g_free(ID2); - if (GlobalIndex==-1) return FALSE; - if (token==G_TOKEN_EOF) { - PrintConfigValue(GlobalIndex,(int)ind,IndexGiven,scanner); - return TRUE; - } else if (token==G_TOKEN_EQUAL_SIGN) { - if (CountPlayers(FirstServer)>0) { - g_warning( -_("Configuration can only be changed interactively when no\n" -"players are logged on. Wait for all players to log off, or remove\n" -"them with the push or kill commands, and try again.")); - } else { - if (SetConfigValue(GlobalIndex,(int)ind,IndexGiven,scanner) && print) { - PrintConfigValue(GlobalIndex,(int)ind,IndexGiven,scanner); - } - } - return TRUE; - } else { + } + ind = scanner->value.v_int; + IndexGiven = TRUE; + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_RIGHT_BRACE) { + g_scanner_unexp_token(scanner, G_TOKEN_RIGHT_BRACE, NULL, NULL, + NULL, NULL, FALSE); return FALSE; - } - return FALSE; -} - -int GetGlobalIndex(gchar *ID1,gchar *ID2) { - int i; - const int NumGlob=sizeof(Globals)/sizeof(Globals[0]); - if (!ID1) return -1; - for (i=0;i<NumGlob;i++) { - if (g_strcasecmp(ID1,Globals[i].Name)==0 && !Globals[i].NameStruct[0]) { -/* Just a bog-standard ID1=value */ - return i; + } + token = g_scanner_get_next_token(scanner); + if (token == '.') { + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_IDENTIFIER) { + g_scanner_unexp_token(scanner, G_TOKEN_IDENTIFIER, NULL, NULL, + NULL, NULL, FALSE); + return FALSE; } - if (g_strcasecmp(ID1,Globals[i].NameStruct)==0 && ID2 && - g_strcasecmp(ID2,Globals[i].Name)==0 && - Globals[i].StructStaticPt && Globals[i].StructListPt) { -/* ID1[index].ID2=value */ - return i; + ID2 = g_strdup(scanner->value.v_identifier); + token = g_scanner_get_next_token(scanner); + } + } + GlobalIndex = GetGlobalIndex(ID1, ID2); + g_free(ID1); + g_free(ID2); + if (GlobalIndex == -1) + return FALSE; + if (token == G_TOKEN_EOF) { + PrintConfigValue(GlobalIndex, (int)ind, IndexGiven, scanner); + return TRUE; + } else if (token == G_TOKEN_EQUAL_SIGN) { + if (CountPlayers(FirstServer) > 0) { + g_warning(_("Configuration can only be changed interactively " + "when no\nplayers are logged on. Wait for all " + "players to log off, or remove\nthem with the " + "push or kill commands, and try again.")); + } else { + if (SetConfigValue(GlobalIndex, (int)ind, IndexGiven, scanner) + && print) { + PrintConfigValue(GlobalIndex, (int)ind, IndexGiven, scanner); } - } - return -1; -} - -void *GetGlobalPointer(int GlobalIndex,int StructIndex) { - void *ValPt=NULL; - - if (Globals[GlobalIndex].IntVal) { - ValPt=(void *)Globals[GlobalIndex].IntVal; - } else if (Globals[GlobalIndex].PriceVal) { - ValPt=(void *)Globals[GlobalIndex].PriceVal; - } else if (Globals[GlobalIndex].BoolVal) { - ValPt=(void *)Globals[GlobalIndex].BoolVal; - } else if (Globals[GlobalIndex].StringVal) { - ValPt=(void *)Globals[GlobalIndex].StringVal; - } - if (!ValPt) return NULL; - - if (Globals[GlobalIndex].StructStaticPt && - Globals[GlobalIndex].StructListPt) { - return (char *)ValPt-(char *)Globals[GlobalIndex].StructStaticPt + - (char *)*(Globals[GlobalIndex].StructListPt) + - (StructIndex-1)*Globals[GlobalIndex].LenStruct; - } else { - return ValPt; - } -} - -gboolean CheckMaxIndex(GScanner *scanner,int GlobalIndex,int StructIndex, - gboolean IndexGiven) { - if (!Globals[GlobalIndex].MaxIndex || - (Globals[GlobalIndex].StringList && !IndexGiven) || - (IndexGiven && StructIndex>=1 && + } + return TRUE; + } else { + return FALSE; + } + return FALSE; +} + +int GetGlobalIndex(gchar *ID1, gchar *ID2) +{ + int i; + const int NumGlob = sizeof(Globals) / sizeof(Globals[0]); + + if (!ID1) + return -1; + for (i = 0; i < NumGlob; i++) { + if (g_strcasecmp(ID1, Globals[i].Name) == 0 + && !Globals[i].NameStruct[0]) { + /* Just a bog-standard ID1=value */ + return i; + } + if (g_strcasecmp(ID1, Globals[i].NameStruct) == 0 && ID2 + && g_strcasecmp(ID2, Globals[i].Name) == 0 + && Globals[i].StructStaticPt && Globals[i].StructListPt) { + /* ID1[index].ID2=value */ + return i; + } + } + return -1; +} + +void *GetGlobalPointer(int GlobalIndex, int StructIndex) +{ + void *ValPt = NULL; + + if (Globals[GlobalIndex].IntVal) { + ValPt = (void *)Globals[GlobalIndex].IntVal; + } else if (Globals[GlobalIndex].PriceVal) { + ValPt = (void *)Globals[GlobalIndex].PriceVal; + } else if (Globals[GlobalIndex].BoolVal) { + ValPt = (void *)Globals[GlobalIndex].BoolVal; + } else if (Globals[GlobalIndex].StringVal) { + ValPt = (void *)Globals[GlobalIndex].StringVal; + } + if (!ValPt) + return NULL; + + if (Globals[GlobalIndex].StructStaticPt && + Globals[GlobalIndex].StructListPt) { + return (char *)ValPt - (char *)Globals[GlobalIndex].StructStaticPt + + (char *)*(Globals[GlobalIndex].StructListPt) + + (StructIndex - 1) * Globals[GlobalIndex].LenStruct; + } else { + return ValPt; + } +} + +gboolean CheckMaxIndex(GScanner *scanner, int GlobalIndex, int StructIndex, + gboolean IndexGiven) +{ + if (!Globals[GlobalIndex].MaxIndex || + (Globals[GlobalIndex].StringList && !IndexGiven) || + (IndexGiven && StructIndex >= 1 && StructIndex <= *(Globals[GlobalIndex].MaxIndex))) { - return TRUE; - } -/* Error message displayed when you try to set, for example, Drug[10].Name - when NumDrug<10 (%s="Drug" and %d=10 in this example) */ - g_scanner_error(scanner,_("Index into %s array should be between 1 and %d"), - (Globals[GlobalIndex].NameStruct && - Globals[GlobalIndex].NameStruct[0]) ? - Globals[GlobalIndex].NameStruct : - Globals[GlobalIndex].Name, - *(Globals[GlobalIndex].MaxIndex)); - return FALSE; -} - -void PrintConfigValue(int GlobalIndex,int StructIndex,gboolean IndexGiven, - GScanner *scanner) { - gchar *GlobalName; - int i; - if (!CheckMaxIndex(scanner,GlobalIndex,StructIndex,IndexGiven)) return; - if (Globals[GlobalIndex].NameStruct[0]) { - GlobalName=g_strdup_printf("%s[%d].%s",Globals[GlobalIndex].NameStruct, - StructIndex,Globals[GlobalIndex].Name); - } else GlobalName=Globals[GlobalIndex].Name; - if (Globals[GlobalIndex].IntVal) { -/* Display of a numeric config. file variable - e.g. "NumDrug is 6" */ - g_print(_("%s is %d\n"),GlobalName, - *((int *)GetGlobalPointer(GlobalIndex,StructIndex))); - } else if (Globals[GlobalIndex].BoolVal) { -/* Display of a boolean config. file variable - e.g. "DrugValue is TRUE" */ - g_print(_("%s is %s\n"),GlobalName, - *((gboolean *)GetGlobalPointer(GlobalIndex,StructIndex)) ? - _("TRUE") : _("FALSE")); - } else if (Globals[GlobalIndex].PriceVal) { -/* Display of a price config. file variable - e.g. "Bitch.MinPrice is $200" */ - dpg_print(_("%s is %P\n"),GlobalName, - *((price_t *)GetGlobalPointer(GlobalIndex,StructIndex))); - } else if (Globals[GlobalIndex].StringVal) { -/* Display of a string config. file variable - e.g. - "LoanSharkName is \"the loan shark\"" */ - g_print(_("%s is \"%s\"\n"),GlobalName, - *((gchar **)GetGlobalPointer(GlobalIndex,StructIndex))); - } else if (Globals[GlobalIndex].StringList) { - if (IndexGiven) { -/* Display of an indexed string list config. file variable - e.g. - "StoppedTo[1] is have a beer" */ - g_print(_("%s[%d] is %s\n"),GlobalName,StructIndex, - (*(Globals[GlobalIndex].StringList))[StructIndex-1]); - } else { -/* Display of the first part of an entire string list config. file variable - - e.g. "StoppedTo is { " (followed by "have a beer", "smoke a joint" etc.) */ - g_print(_("%s is { "),GlobalName); - if (Globals[GlobalIndex].MaxIndex) { - for (i=0;i<*(Globals[GlobalIndex].MaxIndex);i++) { - if (i>0) g_print(", "); - g_print("\"%s\"",(*(Globals[GlobalIndex].StringList))[i]); - } - } - g_print(" }\n"); - } - } - if (Globals[GlobalIndex].NameStruct[0]) g_free(GlobalName); -} - -gboolean SetConfigValue(int GlobalIndex,int StructIndex,gboolean IndexGiven, - GScanner *scanner) { - gchar *GlobalName,*tmpstr; - GTokenType token; - int IntVal,NewNum; - Player *tmp; - GSList *list,*StartList; - gboolean parsed; - - if (!CheckMaxIndex(scanner,GlobalIndex,StructIndex,IndexGiven)) return FALSE; - if (Globals[GlobalIndex].NameStruct[0]) { - GlobalName=g_strdup_printf("%s[%d].%s",Globals[GlobalIndex].NameStruct, - StructIndex,Globals[GlobalIndex].Name); - } else GlobalName=Globals[GlobalIndex].Name; - if (Globals[GlobalIndex].IntVal) { - token=g_scanner_get_next_token(scanner); - if (token==G_TOKEN_INT) { - IntVal=(int)scanner->value.v_int; - if (Globals[GlobalIndex].ResizeFunc) { - (*(Globals[GlobalIndex].ResizeFunc))(IntVal); -/* Displayed, for example, when you set NumDrug=10 to allow Drug[10].Name - etc. to be set */ - g_print(_("Resized structure list to %d elements\n"),IntVal); - for (list=FirstClient;list;list=g_slist_next(list)) { - tmp=(Player *)list->data; - UpdatePlayer(tmp); - } - for (list=FirstServer;list;list=g_slist_next(list)) { - tmp=(Player *)list->data; - UpdatePlayer(tmp); - } - } - *((int *)GetGlobalPointer(GlobalIndex,StructIndex))=IntVal; - } else { - g_scanner_unexp_token(scanner,G_TOKEN_INT,NULL,NULL, - NULL,NULL,FALSE); return FALSE; + return TRUE; + } + /* Error message displayed when you try to set, for example, + * Drug[10].Name when NumDrug<10 (%s="Drug" and %d=10 in this example) */ + g_scanner_error(scanner, + _("Index into %s array should be between 1 and %d"), + (Globals[GlobalIndex].NameStruct + && Globals[GlobalIndex]. + NameStruct[0]) ? Globals[GlobalIndex]. + NameStruct : Globals[GlobalIndex].Name, + *(Globals[GlobalIndex].MaxIndex)); + return FALSE; +} + +void PrintConfigValue(int GlobalIndex, int StructIndex, + gboolean IndexGiven, GScanner *scanner) +{ + gchar *GlobalName; + int i; + + if (!CheckMaxIndex(scanner, GlobalIndex, StructIndex, IndexGiven)) + return; + if (Globals[GlobalIndex].NameStruct[0]) { + GlobalName = + g_strdup_printf("%s[%d].%s", Globals[GlobalIndex].NameStruct, + StructIndex, Globals[GlobalIndex].Name); + } else + GlobalName = Globals[GlobalIndex].Name; + if (Globals[GlobalIndex].IntVal) { + /* Display of a numeric config. file variable - e.g. "NumDrug is 6" */ + g_print(_("%s is %d\n"), GlobalName, + *((int *)GetGlobalPointer(GlobalIndex, StructIndex))); + } else if (Globals[GlobalIndex].BoolVal) { + /* Display of a boolean config. file variable - e.g. "DrugValue is + * TRUE" */ + g_print(_("%s is %s\n"), GlobalName, + *((gboolean *)GetGlobalPointer(GlobalIndex, StructIndex)) ? + _("TRUE") : _("FALSE")); + } else if (Globals[GlobalIndex].PriceVal) { + /* Display of a price config. file variable - e.g. "Bitch.MinPrice is + * $200" */ + dpg_print(_("%s is %P\n"), GlobalName, + *((price_t *)GetGlobalPointer(GlobalIndex, StructIndex))); + } else if (Globals[GlobalIndex].StringVal) { + /* Display of a string config. file variable - e.g. "LoanSharkName is + * \"the loan shark\"" */ + g_print(_("%s is \"%s\"\n"), GlobalName, + *((gchar **)GetGlobalPointer(GlobalIndex, StructIndex))); + } else if (Globals[GlobalIndex].StringList) { + if (IndexGiven) { + /* Display of an indexed string list config. file variable - e.g. + * "StoppedTo[1] is have a beer" */ + g_print(_("%s[%d] is %s\n"), GlobalName, StructIndex, + (*(Globals[GlobalIndex].StringList))[StructIndex - 1]); + } else { + /* Display of the first part of an entire string list config. file + * variable - e.g. "StoppedTo is { " (followed by "have a beer", + * "smoke a joint" etc.) */ + g_print(_("%s is { "), GlobalName); + if (Globals[GlobalIndex].MaxIndex) { + for (i = 0; i < *(Globals[GlobalIndex].MaxIndex); i++) { + if (i > 0) + g_print(", "); + g_print("\"%s\"", (*(Globals[GlobalIndex].StringList))[i]); + } } - } else if (Globals[GlobalIndex].BoolVal) { - scanner->config->cset_identifier_first= - G_CSET_a_2_z "01" G_CSET_A_2_Z; - scanner->config->cset_identifier_nth= - G_CSET_a_2_z G_CSET_A_2_Z; - token=g_scanner_get_next_token(scanner); - scanner->config->cset_identifier_first=G_CSET_a_2_z "_" G_CSET_A_2_Z; - scanner->config->cset_identifier_nth= - G_CSET_a_2_z "._0123456789" G_CSET_A_2_Z; - parsed=FALSE; - if (token==G_TOKEN_IDENTIFIER) { - if (g_strcasecmp(scanner->value.v_identifier,_("TRUE"))==0 || - g_strcasecmp(scanner->value.v_identifier,_("YES"))==0 || - g_strcasecmp(scanner->value.v_identifier,_("ON"))==0 || - strcmp(scanner->value.v_identifier,"1")==0) { - parsed=TRUE; - *((gboolean *)GetGlobalPointer(GlobalIndex,StructIndex))=TRUE; - } else if (g_strcasecmp(scanner->value.v_identifier,_("FALSE"))==0 || - g_strcasecmp(scanner->value.v_identifier,_("NO"))==0 || - g_strcasecmp(scanner->value.v_identifier,_("OFF"))==0 || - strcmp(scanner->value.v_identifier,"0")==0) { - parsed=TRUE; - *((gboolean *)GetGlobalPointer(GlobalIndex,StructIndex))=FALSE; - } + g_print(" }\n"); + } + } + if (Globals[GlobalIndex].NameStruct[0]) + g_free(GlobalName); +} + +gboolean SetConfigValue(int GlobalIndex, int StructIndex, + gboolean IndexGiven, GScanner *scanner) +{ + gchar *GlobalName, *tmpstr; + GTokenType token; + int IntVal, NewNum; + Player *tmp; + GSList *list, *StartList; + gboolean parsed; + + if (!CheckMaxIndex(scanner, GlobalIndex, StructIndex, IndexGiven)) + return FALSE; + if (Globals[GlobalIndex].NameStruct[0]) { + GlobalName = + g_strdup_printf("%s[%d].%s", Globals[GlobalIndex].NameStruct, + StructIndex, Globals[GlobalIndex].Name); + } else + GlobalName = Globals[GlobalIndex].Name; + if (Globals[GlobalIndex].IntVal) { + token = g_scanner_get_next_token(scanner); + if (token == G_TOKEN_INT) { + IntVal = (int)scanner->value.v_int; + if (Globals[GlobalIndex].ResizeFunc) { + (*(Globals[GlobalIndex].ResizeFunc)) (IntVal); + /* Displayed, for example, when you set NumDrug=10 to allow + * Drug[10].Name etc. to be set */ + g_print(_("Resized structure list to %d elements\n"), IntVal); + for (list = FirstClient; list; list = g_slist_next(list)) { + tmp = (Player *)list->data; + UpdatePlayer(tmp); + } + for (list = FirstServer; list; list = g_slist_next(list)) { + tmp = (Player *)list->data; + UpdatePlayer(tmp); + } } - if (!parsed) { - g_scanner_unexp_token(scanner,G_TOKEN_NONE,NULL,NULL,NULL, - _("expected a boolean value (one of 0, OFF, NO, FALSE, " - "1, ON, YES, TRUE)"),FALSE); - return FALSE; + *((int *)GetGlobalPointer(GlobalIndex, StructIndex)) = IntVal; + } else { + g_scanner_unexp_token(scanner, G_TOKEN_INT, NULL, NULL, + NULL, NULL, FALSE); + return FALSE; + } + } else if (Globals[GlobalIndex].BoolVal) { + scanner->config->cset_identifier_first = + G_CSET_a_2_z "01" G_CSET_A_2_Z; + scanner->config->cset_identifier_nth = G_CSET_a_2_z G_CSET_A_2_Z; + token = g_scanner_get_next_token(scanner); + scanner->config->cset_identifier_first = G_CSET_a_2_z "_" G_CSET_A_2_Z; + scanner->config->cset_identifier_nth = + G_CSET_a_2_z "._0123456789" G_CSET_A_2_Z; + parsed = FALSE; + if (token == G_TOKEN_IDENTIFIER) { + if (g_strcasecmp(scanner->value.v_identifier, _("TRUE")) == 0 || + g_strcasecmp(scanner->value.v_identifier, _("YES")) == 0 || + g_strcasecmp(scanner->value.v_identifier, _("ON")) == 0 || + strcmp(scanner->value.v_identifier, "1") == 0) { + parsed = TRUE; + *((gboolean *)GetGlobalPointer(GlobalIndex, StructIndex)) = TRUE; + } else if (g_strcasecmp(scanner->value.v_identifier, _("FALSE")) == 0 + || g_strcasecmp(scanner->value.v_identifier, _("NO")) == 0 + || g_strcasecmp(scanner->value.v_identifier, + _("OFF")) == 0 + || strcmp(scanner->value.v_identifier, "0") == 0) { + parsed = TRUE; + *((gboolean *)GetGlobalPointer(GlobalIndex, StructIndex)) = FALSE; } - } else if (Globals[GlobalIndex].PriceVal) { - token=g_scanner_get_next_token(scanner); - if (token==G_TOKEN_INT) { - *((price_t *)GetGlobalPointer(GlobalIndex,StructIndex))= - (price_t)scanner->value.v_int; + } + if (!parsed) { + g_scanner_unexp_token(scanner, G_TOKEN_NONE, NULL, NULL, NULL, + _("expected a boolean value (one of 0, OFF, " + "NO, FALSE, 1, ON, YES, TRUE)"), FALSE); + return FALSE; + } + } else if (Globals[GlobalIndex].PriceVal) { + token = g_scanner_get_next_token(scanner); + if (token == G_TOKEN_INT) { + *((price_t *)GetGlobalPointer(GlobalIndex, StructIndex)) = + (price_t)scanner->value.v_int; + } else { + g_scanner_unexp_token(scanner, G_TOKEN_INT, NULL, NULL, + NULL, NULL, FALSE); + return FALSE; + } + } else if (Globals[GlobalIndex].StringVal) { + scanner->config->identifier_2_string = TRUE; + scanner->config->cset_identifier_first = + G_CSET_a_2_z " ._0123456789" G_CSET_A_2_Z G_CSET_LATINS + G_CSET_LATINC; + scanner->config->cset_identifier_nth = + G_CSET_a_2_z " ._0123456789" G_CSET_A_2_Z G_CSET_LATINS + G_CSET_LATINC; + token = g_scanner_get_next_token(scanner); + if (token == G_TOKEN_STRING) { + AssignName((gchar **)GetGlobalPointer(GlobalIndex, StructIndex), + scanner->value.v_string); + } else if (token == G_TOKEN_IDENTIFIER) { + AssignName((gchar **)GetGlobalPointer(GlobalIndex, StructIndex), + scanner->value.v_identifier); + } else { + g_scanner_unexp_token(scanner, G_TOKEN_STRING, NULL, NULL, + NULL, NULL, FALSE); + } + scanner->config->identifier_2_string = FALSE; + scanner->config->cset_identifier_first = G_CSET_a_2_z "_" G_CSET_A_2_Z; + scanner->config->cset_identifier_nth = + G_CSET_a_2_z "._0123456789" G_CSET_A_2_Z; + } else if (Globals[GlobalIndex].StringList) { + token = g_scanner_get_next_token(scanner); + if (IndexGiven) { + if (token == G_TOKEN_STRING) { + AssignName(&(*(Globals[GlobalIndex].StringList))[StructIndex - 1], + scanner->value.v_string); } else { - g_scanner_unexp_token(scanner,G_TOKEN_INT,NULL,NULL, - NULL,NULL,FALSE); return FALSE; + g_scanner_unexp_token(scanner, G_TOKEN_STRING, NULL, NULL, + NULL, NULL, FALSE); + return FALSE; } - } else if (Globals[GlobalIndex].StringVal) { - scanner->config->identifier_2_string=TRUE; - scanner->config->cset_identifier_first= - G_CSET_a_2_z " ._0123456789" G_CSET_A_2_Z G_CSET_LATINS G_CSET_LATINC; - scanner->config->cset_identifier_nth= - G_CSET_a_2_z " ._0123456789" G_CSET_A_2_Z G_CSET_LATINS G_CSET_LATINC; - token=g_scanner_get_next_token(scanner); - if (token==G_TOKEN_STRING) { - AssignName((gchar **)GetGlobalPointer(GlobalIndex,StructIndex), - scanner->value.v_string); - } else if (token==G_TOKEN_IDENTIFIER) { - AssignName((gchar **)GetGlobalPointer(GlobalIndex,StructIndex), - scanner->value.v_identifier); - } else { - g_scanner_unexp_token(scanner,G_TOKEN_STRING,NULL,NULL, - NULL,NULL,FALSE); + } else { + StartList = NULL; + if (token != G_TOKEN_LEFT_CURLY) { + g_scanner_unexp_token(scanner, G_TOKEN_LEFT_CURLY, NULL, NULL, + NULL, NULL, FALSE); + return FALSE; } - scanner->config->identifier_2_string=FALSE; - scanner->config->cset_identifier_first=G_CSET_a_2_z "_" G_CSET_A_2_Z; - scanner->config->cset_identifier_nth= - G_CSET_a_2_z "._0123456789" G_CSET_A_2_Z; - } else if (Globals[GlobalIndex].StringList) { - token=g_scanner_get_next_token(scanner); - if (IndexGiven) { - if (token==G_TOKEN_STRING) { - AssignName(&(*(Globals[GlobalIndex].StringList))[StructIndex-1], - scanner->value.v_string); - } else { - g_scanner_unexp_token(scanner,G_TOKEN_STRING,NULL,NULL, - NULL,NULL,FALSE); return FALSE; - } - } else { - StartList=NULL; - if (token!=G_TOKEN_LEFT_CURLY) { - g_scanner_unexp_token(scanner,G_TOKEN_LEFT_CURLY,NULL,NULL, - NULL,NULL,FALSE); return FALSE; - } - NewNum=0; - do { - token=g_scanner_get_next_token(scanner); - if (token==G_TOKEN_STRING) { - tmpstr=g_strdup(scanner->value.v_string); - NewNum++; StartList=g_slist_append(StartList,tmpstr); - } else if (token!=G_TOKEN_RIGHT_CURLY && - token!=G_TOKEN_COMMA) { - g_scanner_unexp_token(scanner,G_TOKEN_STRING,NULL,NULL, - NULL,NULL,FALSE); return FALSE; - } - } while (token!=G_TOKEN_RIGHT_CURLY); - (*Globals[GlobalIndex].ResizeFunc)(NewNum); - NewNum=0; - for (list=StartList;list;NewNum++,list=g_slist_next(list)) { - AssignName(&(*(Globals[GlobalIndex].StringList))[NewNum], - (char *)list->data); - g_free(list->data); - } - g_slist_free(StartList); + NewNum = 0; + do { + token = g_scanner_get_next_token(scanner); + if (token == G_TOKEN_STRING) { + tmpstr = g_strdup(scanner->value.v_string); + NewNum++; + StartList = g_slist_append(StartList, tmpstr); + } else if (token != G_TOKEN_RIGHT_CURLY && token != G_TOKEN_COMMA) { + g_scanner_unexp_token(scanner, G_TOKEN_STRING, NULL, NULL, + NULL, NULL, FALSE); + return FALSE; + } + } while (token != G_TOKEN_RIGHT_CURLY); + (*Globals[GlobalIndex].ResizeFunc) (NewNum); + NewNum = 0; + for (list = StartList; list; NewNum++, list = g_slist_next(list)) { + AssignName(&(*(Globals[GlobalIndex].StringList))[NewNum], + (char *)list->data); + g_free(list->data); } - } - if (Globals[GlobalIndex].NameStruct[0]) g_free(GlobalName); - return TRUE; -} - -void SetupParameters(void) { -/* Sets up data - such as the location of the high score file - to */ -/* hard-coded internal values, and then processes the global and */ -/* user-specific configuration files */ - char *ConfigFile,*pt; - int i; - -/* Initialise variables */ - srand((unsigned)time(NULL)); - PidFile=NULL; - ConvertFile=NULL; - Location=NULL; - Gun=NULL; - Drug=NULL; - SubwaySaying=Playing=StoppedTo=NULL; - DrugValue=TRUE; - Sanitized=ConfigVerbose=FALSE; - NumLocation=NumGun=NumDrug=0; - FirstClient=FirstServer=NULL; - Noone.Name=g_strdup("Noone"); - WantColour=WantNetwork=TRUE; - WantHelp=WantConvert=WantVersion=WantAntique=WantAdmin=FALSE; - WantedClient=CLIENT_AUTO; - Server=AIPlayer=Client=Network=FALSE; - - Log.Level=2; - Log.Timestamp=g_strdup("[%H:%M:%S] "); - Log.File=g_strdup(""); - - Currency.Symbol = g_strdup("$"); - Currency.Prefix = TRUE; - -/* Set hard-coded default values */ - g_free(HiScoreFile); g_free(ServerName); - HiScoreFile=g_strdup_printf("%s/dopewars.sco",DATADIR); - ServerName=g_strdup("localhost"); - g_free(WebBrowser); - WebBrowser = g_strdup("/usr/bin/mozilla"); - - CopyNames(&Names,&DefaultNames); - CopyDrugs(&Drugs,&DefaultDrugs); + g_slist_free(StartList); + } + } + if (Globals[GlobalIndex].NameStruct[0]) + g_free(GlobalName); + return TRUE; +} + +/* + * Sets up data - such as the location of the high score file - to + * hard-coded internal values, and then processes the global and + * user-specific configuration files. + */ +void SetupParameters(void) +{ + char *ConfigFile, *pt; + int i; + + /* Initialise variables */ + srand((unsigned)time(NULL)); + PidFile = NULL; + ConvertFile = NULL; + Location = NULL; + Gun = NULL; + Drug = NULL; + SubwaySaying = Playing = StoppedTo = NULL; + DrugValue = TRUE; + Sanitized = ConfigVerbose = FALSE; + NumLocation = NumGun = NumDrug = 0; + FirstClient = FirstServer = NULL; + Noone.Name = g_strdup("Noone"); + WantColour = WantNetwork = TRUE; + WantHelp = WantConvert = WantVersion = WantAntique = WantAdmin = FALSE; + WantedClient = CLIENT_AUTO; + Server = AIPlayer = Client = Network = FALSE; + + Log.Level = 2; + Log.Timestamp = g_strdup("[%H:%M:%S] "); + Log.File = g_strdup(""); + + Currency.Symbol = g_strdup("$"); + Currency.Prefix = TRUE; + + /* Set hard-coded default values */ + g_free(HiScoreFile); + g_free(ServerName); + HiScoreFile = g_strdup_printf("%s/dopewars.sco", DATADIR); + ServerName = g_strdup("localhost"); + g_free(WebBrowser); + WebBrowser = g_strdup("/usr/bin/mozilla"); + + CopyNames(&Names, &DefaultNames); + CopyDrugs(&Drugs, &DefaultDrugs); #ifdef NETWORKING - CopyMetaServer(&MetaServer,&DefaultMetaServer); - AssignName(&Socks.name,"socks"); - Socks.port = 1080; - Socks.version = 4; - Socks.user = g_strdup(""); - Socks.numuid = FALSE; - Socks.authuser = g_strdup(""); - Socks.authpassword = g_strdup(""); - UseSocks = FALSE; + CopyMetaServer(&MetaServer, &DefaultMetaServer); + AssignName(&Socks.name, "socks"); + Socks.port = 1080; + Socks.version = 4; + Socks.user = g_strdup(""); + Socks.numuid = FALSE; + Socks.authuser = g_strdup(""); + Socks.authpassword = g_strdup(""); + UseSocks = FALSE; #endif - ResizeLocations(sizeof(DefaultLocation)/sizeof(DefaultLocation[0])); - for (i=0;i<NumLocation;i++) CopyLocation(&Location[i],&DefaultLocation[i]); - ResizeCops(sizeof(DefaultCop)/sizeof(DefaultCop[0])); - for (i=0;i<NumCop;i++) CopyCop(&Cop[i],&DefaultCop[i]); - ResizeGuns(sizeof(DefaultGun)/sizeof(DefaultGun[0])); - for (i=0;i<NumGun;i++) CopyGun(&Gun[i],&DefaultGun[i]); - ResizeDrugs(sizeof(DefaultDrug)/sizeof(DefaultDrug[0])); - for (i=0;i<NumDrug;i++) CopyDrug(&Drug[i],&DefaultDrug[i]); - ResizeSubway(sizeof(DefaultSubwaySaying)/sizeof(DefaultSubwaySaying[0])); - for (i=0;i<NumSubway;i++) { - AssignName(&SubwaySaying[i],_(DefaultSubwaySaying[i])); - } - ResizePlaying(sizeof(DefaultPlaying)/sizeof(DefaultPlaying[0])); - for (i=0;i<NumPlaying;i++) { - AssignName(&Playing[i],_(DefaultPlaying[i])); - } - ResizeStoppedTo(sizeof(DefaultStoppedTo)/sizeof(DefaultStoppedTo[0])); - for (i=0;i<NumStoppedTo;i++) { - AssignName(&StoppedTo[i],_(DefaultStoppedTo[i])); - } + ResizeLocations(sizeof(DefaultLocation) / sizeof(DefaultLocation[0])); + for (i = 0; i < NumLocation; i++) + CopyLocation(&Location[i], &DefaultLocation[i]); + ResizeCops(sizeof(DefaultCop) / sizeof(DefaultCop[0])); + for (i = 0; i < NumCop; i++) + CopyCop(&Cop[i], &DefaultCop[i]); + ResizeGuns(sizeof(DefaultGun) / sizeof(DefaultGun[0])); + for (i = 0; i < NumGun; i++) + CopyGun(&Gun[i], &DefaultGun[i]); + ResizeDrugs(sizeof(DefaultDrug) / sizeof(DefaultDrug[0])); + for (i = 0; i < NumDrug; i++) + CopyDrug(&Drug[i], &DefaultDrug[i]); + ResizeSubway(sizeof(DefaultSubwaySaying) / + sizeof(DefaultSubwaySaying[0])); + for (i = 0; i < NumSubway; i++) { + AssignName(&SubwaySaying[i], _(DefaultSubwaySaying[i])); + } + ResizePlaying(sizeof(DefaultPlaying) / sizeof(DefaultPlaying[0])); + for (i = 0; i < NumPlaying; i++) { + AssignName(&Playing[i], _(DefaultPlaying[i])); + } + ResizeStoppedTo(sizeof(DefaultStoppedTo) / sizeof(DefaultStoppedTo[0])); + for (i = 0; i < NumStoppedTo; i++) { + AssignName(&StoppedTo[i], _(DefaultStoppedTo[i])); + } #ifdef CYGWIN -/* Read the global configuration from the directory the binary is - installed in */ - pt=GetBinaryDir(); + /* Read the global configuration from the directory the binary is + * installed in */ + pt = GetBinaryDir(); if (pt) { - ConfigFile=g_strdup_printf("%s/dopewars-config.txt",pt); + ConfigFile = g_strdup_printf("%s/dopewars-config.txt", pt); ReadConfigFile(ConfigFile); - g_free(ConfigFile); g_free(pt); + g_free(ConfigFile); + g_free(pt); } -/* Now read the local configuration from the current directory */ + /* Now read the local configuration from the current directory */ ReadConfigFile("dopewars-config.txt"); #else /* CYGWIN */ -/* Now read in the global configuration file */ + /* Now read in the global configuration file */ ReadConfigFile("/etc/dopewars"); -/* Next, try to read in the .dopewars file in the user's home directory */ - pt=getenv("HOME"); + /* Next, try to read in the .dopewars file in the user's home directory */ + pt = getenv("HOME"); if (pt) { - ConfigFile=g_strdup_printf("%s/.dopewars",pt); + ConfigFile = g_strdup_printf("%s/.dopewars", pt); ReadConfigFile(ConfigFile); g_free(ConfigFile); } - #endif /* CYGWIN */ -/* Save this configuration, so we can restore those elements that get - overwritten when we connect to a dopewars server */ + /* Save this configuration, so we can restore those elements that get + * overwritten when we connect to a dopewars server */ BackupConfig(); } -void HandleHelpTexts() { - g_print(_("dopewars version %s\n"),VERSION); - if (!WantHelp) return; +void HandleHelpTexts() +{ + g_print(_("dopewars version %s\n"), VERSION); + if (!WantHelp) + return; - g_print( + g_print( #ifdef HAVE_GETOPT_LONG -/* Usage information, printed when the user runs "dopewars -h" (version - with support for GNU long options) */ -_("Usage: dopewars [OPTION]...\n\ + /* Usage information, printed when the user runs "dopewars -h" + * (version with support for GNU long options) */ + _("Usage: dopewars [OPTION]...\n\ Drug dealing game based on \"Drug Wars\" by John E. Dell\n\ -b, --no-color, \"black and white\" - i.e. do not use pretty colours\n\ --no-colour (by default colours are used where available)\n\ t@@ -1935,11 +2281,11 @@ Drug dealing game based on \"Drug Wars\" by John E. Dell\n\ -h, --help display this help information\n\ -v, --version output version information and exit\n\n\ dopewars is Copyright (C) Ben Webb 1998-2002, and released under the GNU GPL\n\ -Report bugs to the author at ben@bellatrix.pcl.ox.ac.uk\n"),DATADIR); +Report bugs to the author at ben@bellatrix.pcl.ox.ac.uk\n"), DATADIR); #else -/* Usage information, printed when the user runs "dopewars -h" (short - options only version) */ -_("Usage: dopewars [OPTION]...\n\ + /* Usage information, printed when the user runs "dopewars -h" + * (short options only version) */ + _("Usage: dopewars [OPTION]...\n\ Drug dealing game based on \"Drug Wars\" by John E. Dell\n\ -b \"black and white\" - i.e. do not use pretty colours\n\ (by default colours are used where the terminal supports them)\n\ t@@ -1968,76 +2314,120 @@ Drug dealing game based on \"Drug Wars\" by John E. Dell\n\ -h display this help information\n\ -v output version information and exit\n\n\ dopewars is Copyright (C) Ben Webb 1998-2002, and released under the GNU GPL\n\ -Report bugs to the author at ben@bellatrix.pcl.ox.ac.uk\n"),DATADIR); +Report bugs to the author at ben@bellatrix.pcl.ox.ac.uk\n"), DATADIR); #endif } -void HandleCmdLine(int argc,char *argv[]) { - int c; - static const gchar *options = "anbchvf:o:sSp:g:r:wtC:l:NA"; +void HandleCmdLine(int argc, char *argv[]) +{ + int c; + static const gchar *options = "anbchvf:o:sSp:g:r:wtC:l:NA"; + #ifdef HAVE_GETOPT_LONG - static const struct option long_options[] = { - { "no-color", no_argument, NULL, 'b' }, - { "no-colour", no_argument, NULL, 'b' }, - { "single-player", no_argument, NULL, 'n' }, - { "antique", no_argument, NULL, 'a' }, - { "scorefile", required_argument, NULL, 'f' }, - { "hostname", required_argument, NULL, 'o' }, - { "public-server", no_argument, NULL, 's' }, - { "private-server", no_argument, NULL, 'S' }, - { "port", required_argument, NULL, 'p' }, - { "configfile", required_argument, NULL, 'g' }, - { "pidfile", required_argument, NULL, 'r' }, - { "ai-player", no_argument, NULL, 'c' }, - { "windowed-client", no_argument, NULL, 'w' }, - { "text-client", no_argument, NULL, 't' }, - { "convert", required_argument, NULL, 'C' }, - { "logfile", required_argument, NULL, 'l' }, - { "admin", no_argument, NULL, 'A' }, - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, 'v' }, - { 0, 0, 0, 0 } - }; + static const struct option long_options[] = { + {"no-color", no_argument, NULL, 'b'}, + {"no-colour", no_argument, NULL, 'b'}, + {"single-player", no_argument, NULL, 'n'}, + {"antique", no_argument, NULL, 'a'}, + {"scorefile", required_argument, NULL, 'f'}, + {"hostname", required_argument, NULL, 'o'}, + {"public-server", no_argument, NULL, 's'}, + {"private-server", no_argument, NULL, 'S'}, + {"port", required_argument, NULL, 'p'}, + {"configfile", required_argument, NULL, 'g'}, + {"pidfile", required_argument, NULL, 'r'}, + {"ai-player", no_argument, NULL, 'c'}, + {"windowed-client", no_argument, NULL, 'w'}, + {"text-client", no_argument, NULL, 't'}, + {"convert", required_argument, NULL, 'C'}, + {"logfile", required_argument, NULL, 'l'}, + {"admin", no_argument, NULL, 'A'}, + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'v'}, + {0, 0, 0, 0} + }; #endif - do { + do { #ifdef HAVE_GETOPT_LONG - c=getopt_long(argc,argv,options,long_options,NULL); + c = getopt_long(argc, argv, options, long_options, NULL); #else - c=getopt(argc,argv,options); + c = getopt(argc, argv, options); #endif - switch(c) { - case 'n': WantNetwork=FALSE; break; - case 'b': WantColour=FALSE; break; - case 'c': AIPlayer=TRUE; break; - case 'a': WantAntique=TRUE; WantNetwork=FALSE; break; - case 'v': WantVersion=TRUE; break; - case 'h': - case 0 : - case '?': WantHelp=TRUE; break; - case 'f': AssignName(&HiScoreFile,optarg); break; - case 'o': AssignName(&ServerName,optarg); break; - case 's': Server=TRUE; NotifyMetaServer=TRUE; break; - case 'S': Server=TRUE; NotifyMetaServer=FALSE; break; - case 'p': Port=atoi(optarg); break; - case 'g': ReadConfigFile(optarg); break; - case 'r': AssignName(&PidFile,optarg); break; - case 'l': AssignName(&Log.File,optarg); break; - case 'w': WantedClient=CLIENT_WINDOW; break; - case 't': WantedClient=CLIENT_CURSES; break; - case 'C': AssignName(&ConvertFile,optarg); WantConvert=TRUE; break; - case 'A': WantAdmin=TRUE; break; - } - } while (c!=-1); + switch (c) { + case 'n': + WantNetwork = FALSE; + break; + case 'b': + WantColour = FALSE; + break; + case 'c': + AIPlayer = TRUE; + break; + case 'a': + WantAntique = TRUE; + WantNetwork = FALSE; + break; + case 'v': + WantVersion = TRUE; + break; + case 'h': + case 0: + case '?': + WantHelp = TRUE; + break; + case 'f': + AssignName(&HiScoreFile, optarg); + break; + case 'o': + AssignName(&ServerName, optarg); + break; + case 's': + Server = TRUE; + NotifyMetaServer = TRUE; + break; + case 'S': + Server = TRUE; + NotifyMetaServer = FALSE; + break; + case 'p': + Port = atoi(optarg); + break; + case 'g': + ReadConfigFile(optarg); + break; + case 'r': + AssignName(&PidFile, optarg); + break; + case 'l': + AssignName(&Log.File, optarg); + break; + case 'w': + WantedClient = CLIENT_WINDOW; + break; + case 't': + WantedClient = CLIENT_CURSES; + break; + case 'C': + AssignName(&ConvertFile, optarg); + WantConvert = TRUE; + break; + case 'A': + WantAdmin = TRUE; + break; + } + } while (c != -1); } -void GeneralStartup(int argc,char *argv[]) { -/* Does general startup stuff (config. files, command line, and high - score init.) */ - - ConfigErrors=0; +/* + * Does general startup stuff (config. files, command line, and high + * score init.) + */ +void GeneralStartup(int argc, char *argv[]) +{ + ConfigErrors = 0; SetupParameters(); - HandleCmdLine(argc,argv); + HandleCmdLine(argc, argv); if (!WantVersion && !WantHelp && !AIPlayer && !WantConvert && !WantAdmin) { OpenHighScoreFile(); t@@ -2046,119 +2436,141 @@ void GeneralStartup(int argc,char *argv[]) { } } -GString *GetLogString(GLogLevelFlags log_level,const gchar *message) { -/* Returns the text to be displayed in a log message, if any. */ - GString *text; - gchar TimeBuf[80]; - gint i; - time_t tim; - struct tm *timep; - - text=g_string_new(""); - if (Log.Timestamp) { - tim=time(NULL); - timep=localtime(&tim); - strftime(TimeBuf,80,Log.Timestamp,timep); - TimeBuf[79]='\0'; - g_string_append(text,TimeBuf); - } - - for (i=0;i<MAXLOG;i++) if (log_level&(1<<(G_LOG_LEVEL_USER_SHIFT+i))) { - if (i>Log.Level) { g_string_free(text,TRUE); return NULL; } - g_string_sprintfa(text,"%d: ",i); - } - g_string_append(text,message); - return text; -} - -void OpenLog(void) { +/* + * Returns the text to be displayed in a log message, if any. + */ +GString *GetLogString(GLogLevelFlags log_level, const gchar *message) +{ + GString *text; + gchar TimeBuf[80]; + gint i; + time_t tim; + struct tm *timep; + + text = g_string_new(""); + if (Log.Timestamp) { + tim = time(NULL); + timep = localtime(&tim); + strftime(TimeBuf, 80, Log.Timestamp, timep); + TimeBuf[79] = '\0'; + g_string_append(text, TimeBuf); + } + + for (i = 0; i < MAXLOG; i++) + if (log_level & (1 << (G_LOG_LEVEL_USER_SHIFT + i))) { + if (i > Log.Level) { + g_string_free(text, TRUE); + return NULL; + } + g_string_sprintfa(text, "%d: ", i); + } + g_string_append(text, message); + return text; +} + +void OpenLog(void) +{ CloseLog(); - if (Log.File[0]=='\0') return; - Log.fp = fopen(Log.File,"a"); + if (Log.File[0] == '\0') + return; + Log.fp = fopen(Log.File, "a"); if (Log.fp) { -#ifdef SETVBUF_REVERSED /* 2nd and 3rd arguments are reversed on some systems */ - setvbuf(Log.fp,_IOLBF,(char *)NULL,0); +#ifdef SETVBUF_REVERSED /* 2nd and 3rd arguments are reversed on + * some systems */ + setvbuf(Log.fp, _IOLBF, (char *)NULL, 0); #else - setvbuf(Log.fp,(char *)NULL,_IOLBF,0); + setvbuf(Log.fp, (char *)NULL, _IOLBF, 0); #endif } } -void CloseLog(void) { - if (Log.fp) fclose(Log.fp); +void CloseLog(void) +{ + if (Log.fp) + fclose(Log.fp); Log.fp = NULL; } #ifndef CYGWIN #if NETWORKING && !GUI_SERVER -static void ServerLogMessage(const gchar *log_domain,GLogLevelFlags log_level, - const gchar *message,gpointer user_data) { - GString *text; - text=GetLogString(log_level,message); - if (text) { - fprintf(Log.fp ? Log.fp : stdout,"%s\n",text->str); - g_string_free(text,TRUE); - } +static void ServerLogMessage(const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, gpointer user_data) +{ + GString *text; + + text = GetLogString(log_level, message); + if (text) { + fprintf(Log.fp ? Log.fp : stdout, "%s\n", text->str); + g_string_free(text, TRUE); + } } #endif -/* Standard program entry - Win32 uses WinMain() instead, in winmain.c */ -int main(int argc,char *argv[]) { +/* + * Standard program entry - Win32 uses WinMain() instead, in winmain.c + */ +int main(int argc, char *argv[]) +{ #ifdef ENABLE_NLS - setlocale(LC_ALL,""); - bindtextdomain(PACKAGE,LOCALEDIR); - textdomain(PACKAGE); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); #endif - GeneralStartup(argc,argv); - OpenLog(); - if (WantVersion || WantHelp) { - HandleHelpTexts(); - } else if (WantAdmin) { - AdminServer(); - } else if (WantConvert) { - ConvertHighScoreFile(); - } else { + GeneralStartup(argc, argv); + OpenLog(); + if (WantVersion || WantHelp) { + HandleHelpTexts(); + } else if (WantAdmin) { + AdminServer(); + } else if (WantConvert) { + ConvertHighScoreFile(); + } else { #ifdef NETWORKING - StartNetworking(); + StartNetworking(); #endif - if (Server) { + if (Server) { #ifdef NETWORKING #ifdef GUI_SERVER - gtk_set_locale(); - gtk_init(&argc,&argv); - GuiServerLoop(FALSE); + gtk_set_locale(); + gtk_init(&argc, &argv); + GuiServerLoop(FALSE); #else - g_log_set_handler(NULL,LogMask(),ServerLogMessage,NULL); - ServerLoop(); + g_log_set_handler(NULL, LogMask(), ServerLogMessage, NULL); + ServerLoop(); #endif /* GUI_SERVER */ #else - g_print(_("This binary has been compiled without networking " - "support, and thus cannot run\nin server mode. " - "Recompile passing --enable-networking to the " - "configure script.\n")); + g_print(_("This binary has been compiled without networking " + "support, and thus cannot run\nin server mode. " + "Recompile passing --enable-networking to the " + "configure script.\n")); #endif /* NETWORKING */ - } else if (AIPlayer) { - AIPlayerLoop(); - } else switch(WantedClient) { - case CLIENT_AUTO: - if (!GtkLoop(&argc,&argv,TRUE)) CursesLoop(); - break; - case CLIENT_WINDOW: - GtkLoop(&argc,&argv,FALSE); break; - case CLIENT_CURSES: - CursesLoop(); break; - } + } else if (AIPlayer) { + AIPlayerLoop(); + } else + switch (WantedClient) { + case CLIENT_AUTO: + if (!GtkLoop(&argc, &argv, TRUE)) + CursesLoop(); + break; + case CLIENT_WINDOW: + GtkLoop(&argc, &argv, FALSE); + break; + case CLIENT_CURSES: + CursesLoop(); + break; + } #ifdef NETWORKING - StopNetworking(); + StopNetworking(); #endif - } - CloseLog(); - CloseHighScoreFile(); - g_free(PidFile); - g_free(Log.File); - g_free(ConvertFile); - return 0; + } + CloseLog(); + CloseHighScoreFile(); + g_free(PidFile); + g_free(Log.File); + g_free(ConvertFile); + return 0; } #endif /* CYGWIN */ (DIR) diff --git a/src/dopewars.h b/src/dopewars.h t@@ -1,23 +1,24 @@ -/* dopewars.h Common structures and stuff for dopewars */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * dopewars.h Common structures and stuff for dopewars * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __DOPEWARS_H__ #define __DOPEWARS_H__ t@@ -28,8 +29,8 @@ #include <stdio.h> -/* Be careful not to include both sys/time.h and time.h on those systems */ -/* which don't like it */ +/* Be careful not to include both sys/time.h and time.h on those systems + * which don't like it */ #if TIME_WITH_SYS_TIME #include <sys/time.h> #include <time.h> t@@ -54,39 +55,43 @@ typedef long long price_t; #endif /* "Abilities" are protocol extensions, which are negotiated between the - client and server at connect-time. */ + * client and server at connect-time. */ typedef enum { - A_PLAYERID = 0, /* Use numeric IDs rather than player names - in network messages */ - A_DRUGVALUE, /* Server keeps track of purchase price of drugs */ - A_NEWFIGHT, /* Use new unified fighting code */ - A_TSTRING, /* We understand the %Txx (tstring) notation */ - - A_NUM /* N.B. Must be last */ + A_PLAYERID = 0, /* Use numeric IDs rather than player + * names in network messages */ + A_DRUGVALUE, /* Server keeps track of purchase price + * of drugs */ + A_NEWFIGHT, /* Use new unified fighting code */ + A_TSTRING, /* We understand the %Txx (tstring) + * notation */ + A_NUM /* N.B. Must be last */ } AbilType; typedef struct ABILITIES { - gboolean Local[A_NUM]; /* Abilities that we have */ - gboolean Remote[A_NUM]; /* Those that the other end of the connection has */ - gboolean Shared[A_NUM]; /* Abilites shared by us and the remote host */ + gboolean Local[A_NUM]; /* Abilities that we have */ + gboolean Remote[A_NUM]; /* Those that the other end of the + * connection has */ + gboolean Shared[A_NUM]; /* Abilites shared by us and the + * remote host */ } Abilities; struct NAMES { - gchar *Bitch,*Bitches,*Gun,*Guns,*Drug,*Drugs,*Month,*Year, - *LoanSharkName,*BankName,*GunShopName,*RoughPubName; + gchar *Bitch, *Bitches, *Gun, *Guns, *Drug, *Drugs; + gchar *Month, *Year, *LoanSharkName, *BankName; + gchar *GunShopName, *RoughPubName; }; #ifdef NETWORKING struct METASERVER { - gboolean Active; - gchar *Name; - unsigned Port; - gchar *ProxyName; - unsigned ProxyPort; - gchar *Path,*LocalName,*Password,*Comment; - gboolean UseSocks; - gchar *authuser,*authpassword,*proxyuser,*proxypassword; + gboolean Active; + gchar *Name; + unsigned Port; + gchar *ProxyName; + unsigned ProxyPort; + gchar *Path, *LocalName, *Password, *Comment; + gboolean UseSocks; + gchar *authuser, *authpassword, *proxyuser, *proxypassword; }; #endif t@@ -96,49 +101,49 @@ struct CURRENCY { }; struct PRICES { - price_t Spy,Tipoff; + price_t Spy, Tipoff; }; struct BITCH { - price_t MinPrice,MaxPrice; + price_t MinPrice, MaxPrice; }; typedef enum { - CLIENT_AUTO, CLIENT_WINDOW, CLIENT_CURSES + CLIENT_AUTO, CLIENT_WINDOW, CLIENT_CURSES } ClientType; typedef enum { - DM_NONE, DM_STREET, DM_FIGHT, DM_DEAL + DM_NONE, DM_STREET, DM_FIGHT, DM_DEAL } DispMode; typedef enum { - E_NONE = 0, - E_SUBWAY, E_OFFOBJECT, E_WEED, E_SAYING, E_LOANSHARK, - E_BANK, E_GUNSHOP, E_ROUGHPUB, E_HIREBITCH, E_ARRIVE, - E_MAX, + E_NONE = 0, + E_SUBWAY, E_OFFOBJECT, E_WEED, E_SAYING, E_LOANSHARK, + E_BANK, E_GUNSHOP, E_ROUGHPUB, E_HIREBITCH, E_ARRIVE, + E_MAX, - E_FINISH = 100, + E_FINISH = 100, - E_OUTOFSYNC = 120, - E_FIGHT, E_FIGHTASK, E_DOCTOR, - E_MAXOOS + E_OUTOFSYNC = 120, + E_FIGHT, E_FIGHTASK, E_DOCTOR, + E_MAXOOS } EventCode; typedef enum { - FIRSTTURN = 1 << 0, - DEADHARDASS = 1 << 1, - TIPPEDOFF = 1 << 2, - SPIEDON = 1 << 3, - SPYINGON = 1 << 4, - FIGHTING = 1 << 5, - CANSHOOT = 1 << 6, - TRADING = 1 << 7 + FIRSTTURN = 1 << 0, + DEADHARDASS = 1 << 1, + TIPPEDOFF = 1 << 2, + SPIEDON = 1 << 3, + SPYINGON = 1 << 4, + FIGHTING = 1 << 5, + CANSHOOT = 1 << 6, + TRADING = 1 << 7 } PlayerFlags; typedef enum { - ACID = 0, - COCAINE, HASHISH, HEROIN, LUDES, MDA, OPIUM, PCP, - PEYOTE, SHROOMS, SPEED, WEED + ACID = 0, + COCAINE, HASHISH, HEROIN, LUDES, MDA, OPIUM, PCP, + PEYOTE, SHROOMS, SPEED, WEED } DrugIndex; struct LOG { t@@ -147,16 +152,16 @@ struct LOG { gchar *Timestamp; FILE *fp; }; - -extern int ClientSock,ListenSock; -extern gboolean Network,Client,Server,NotifyMetaServer,AIPlayer; +extern int ClientSock, ListenSock; +extern gboolean Network, Client, Server, NotifyMetaServer, AIPlayer; extern unsigned Port; -extern gboolean Sanitized,ConfigVerbose,DrugValue; -extern int NumLocation,NumGun,NumCop,NumDrug,NumSubway,NumPlaying,NumStoppedTo; -extern gchar *HiScoreFile,*ServerName,*ConvertFile; -extern gboolean WantHelp,WantVersion,WantAntique,WantColour, - WantNetwork,WantConvert,WantAdmin; +extern gboolean Sanitized, ConfigVerbose, DrugValue; +extern int NumLocation, NumGun, NumCop, NumDrug, NumSubway, NumPlaying, + NumStoppedTo; +extern gchar *HiScoreFile, *ServerName, *ConvertFile; +extern gboolean WantHelp, WantVersion, WantAntique, WantColour, + WantNetwork, WantConvert, WantAdmin; #ifdef CYGWIN extern gboolean MinToSysTray; #else t@@ -164,13 +169,13 @@ extern gboolean Daemonize; #endif extern gchar *WebBrowser; extern ClientType WantedClient; -extern int LoanSharkLoc,BankLoc,GunShopLoc,RoughPubLoc; -extern int DrugSortMethod,FightTimeout,IdleTimeout,ConnectTimeout; -extern int MaxClients,AITurnPause; +extern int LoanSharkLoc, BankLoc, GunShopLoc, RoughPubLoc; +extern int DrugSortMethod, FightTimeout, IdleTimeout, ConnectTimeout; +extern int MaxClients, AITurnPause; extern struct CURRENCY Currency; extern struct PRICES Prices; extern struct BITCH Bitch; -extern price_t StartCash,StartDebt; +extern price_t StartCash, StartDebt; extern struct NAMES Names; #ifdef NETWORKING t@@ -180,7 +185,7 @@ extern gboolean UseSocks; #endif extern int NumTurns; -extern int PlayerArmour,BitchArmour; +extern int PlayerArmour, BitchArmour; #define MAXLOG 6 t@@ -190,64 +195,64 @@ extern int PlayerArmour,BitchArmour; #define DS_CHEAPLAST 4 #define DS_MAX 5 -#define NUMHISCORE 18 +#define NUMHISCORE 18 -#define DEFLOANSHARK 1 -#define DEFBANK 1 -#define DEFGUNSHOP 2 -#define DEFROUGHPUB 2 +#define DEFLOANSHARK 1 +#define DEFBANK 1 +#define DEFGUNSHOP 2 +#define DEFROUGHPUB 2 -#define METAVERSION 2 +#define METAVERSION 2 struct COP { - gchar *Name,*DeputyName,*DeputiesName; - gint Armour,DeputyArmour; - gint AttackPenalty,DefendPenalty; - gint MinDeputies,MaxDeputies; - gint GunIndex; - gint CopGun,DeputyGun; + gchar *Name, *DeputyName, *DeputiesName; + gint Armour, DeputyArmour; + gint AttackPenalty, DefendPenalty; + gint MinDeputies, MaxDeputies; + gint GunIndex; + gint CopGun, DeputyGun; }; extern struct COP *Cop; struct GUN { - gchar *Name; - price_t Price; - int Space; - int Damage; + gchar *Name; + price_t Price; + int Space; + int Damage; }; extern struct GUN *Gun; struct HISCORE { - gchar *Time; - price_t Money; - gboolean Dead; - gchar *Name; + gchar *Time; + price_t Money; + gboolean Dead; + gchar *Name; }; struct LOCATION { - gchar *Name; - int PolicePresence; - int MinDrug,MaxDrug; + gchar *Name; + int PolicePresence; + int MinDrug, MaxDrug; }; extern struct LOCATION *Location; struct DRUG { - gchar *Name; - price_t MinPrice,MaxPrice; - gboolean Cheap,Expensive; - gchar *CheapStr; + gchar *Name; + price_t MinPrice, MaxPrice; + gboolean Cheap, Expensive; + gchar *CheapStr; }; extern struct DRUG *Drug; struct DRUGS { - gchar *ExpensiveStr1,*ExpensiveStr2; - int CheapDivide,ExpensiveMultiply; + gchar *ExpensiveStr1, *ExpensiveStr2; + int CheapDivide, ExpensiveMultiply; }; extern struct DRUGS Drugs; struct INVENTORY { - price_t Price,TotalValue; - int Carried; + price_t Price, TotalValue; + int Carried; }; typedef struct INVENTORY Inventory; t@@ -255,43 +260,47 @@ struct PLAYER_T; typedef struct PLAYER_T Player; struct TDopeEntry { - Player *Play; - int Turns; + Player *Play; + int Turns; }; typedef struct TDopeEntry DopeEntry; struct TDopeList { - DopeEntry *Data; - int Number; + DopeEntry *Data; + int Number; }; typedef struct TDopeList DopeList; struct PLAYER_T { - guint ID; - int Turn; - price_t Cash,Debt,Bank; - int Health; - int CoatSize; - char IsAt; - PlayerFlags Flags; - gchar *Name; - Inventory *Guns,*Drugs,Bitches; - EventCode EventNum,ResyncNum; - time_t FightTimeout,IdleTimeout,ConnectTimeout; - price_t DocPrice; - DopeList SpyList,TipList; - Player *OnBehalfOf; + guint ID; + int Turn; + price_t Cash, Debt, Bank; + int Health; + int CoatSize; + char IsAt; + PlayerFlags Flags; + gchar *Name; + Inventory *Guns, *Drugs, Bitches; + EventCode EventNum, ResyncNum; + time_t FightTimeout, IdleTimeout, ConnectTimeout; + price_t DocPrice; + DopeList SpyList, TipList; + Player *OnBehalfOf; #ifdef NETWORKING - NetworkBuffer NetBuf; + NetworkBuffer NetBuf; #endif - Abilities Abil; - GPtrArray *FightArray; /* If non-NULL, a list of players in a fight */ - Player *Attacking; /* The player that this player is attacking */ - gint CopIndex; /* if >0, then this player is a cop, described - by Cop[CopIndex-1] - if ==0, this is a normal player that has killed no cops - if <0, then this is a normal player, who has killed - cops up to Cop[-1-CopIndex] */ + Abilities Abil; + GPtrArray *FightArray; /* If non-NULL, a list of players + * in a fight */ + Player *Attacking; /* The player that this player + * is attacking */ + gint CopIndex; /* if >0, then this player is a cop, + * described by Cop[CopIndex-1]; + * if ==0, this is a normal player that + * has killed no cops; + * if <0, then this is a normal player, + * who has killed cops up to + * Cop[-1-CopIndex] */ }; #define SN_PROMPT "(Prompt)" t@@ -299,25 +308,25 @@ struct PLAYER_T { #define SN_SINGLE "(Single)" typedef struct tag_serverdata { - char *Name; - unsigned Port; - int MaxPlayers,CurPlayers; - char *Comment,*Version,*Update,*UpSince; + char *Name; + unsigned Port; + int MaxPlayers, CurPlayers; + char *Comment, *Version, *Update, *UpSince; } ServerData; struct GLOBALS { - int *IntVal; - gboolean *BoolVal; - price_t *PriceVal; - gchar **StringVal; - gchar ***StringList; - char *Name,*Help; - - void **StructListPt,*StructStaticPt; - int LenStruct; - char *NameStruct; - int *MaxIndex; - void (*ResizeFunc)(int NewNum); + int *IntVal; + gboolean *BoolVal; + price_t *PriceVal; + gchar **StringVal; + gchar ***StringList; + char *Name, *Help; + + void **StructListPt, *StructStaticPt; + int LenStruct; + char *NameStruct; + int *MaxIndex; + void (*ResizeFunc) (int NewNum); }; extern const int NUMGLOB; t@@ -332,36 +341,35 @@ extern GScannerConfig ScannerConfig; extern struct LOG Log; extern gint ConfigErrors; -GSList *RemovePlayer(Player *Play,GSList *First); -Player *GetPlayerByID(guint ID,GSList *First); -Player *GetPlayerByName(gchar *Name,GSList *First); +GSList *RemovePlayer(Player *Play, GSList *First); +Player *GetPlayerByID(guint ID, GSList *First); +Player *GetPlayerByName(gchar *Name, GSList *First); int CountPlayers(GSList *First); -GSList *AddPlayer(int fd,Player *NewPlayer,GSList *First); +GSList *AddPlayer(int fd, Player *NewPlayer, GSList *First); void UpdatePlayer(Player *Play); -void CopyPlayer(Player *Dest,Player *Src); -void ClearInventory(Inventory *Guns,Inventory *Drugs); -int IsCarryingRandom(Player *Play,int amount); -void ChangeSpaceForInventory(Inventory *Guns,Inventory *Drugs, +void CopyPlayer(Player *Dest, Player *Src); +void ClearInventory(Inventory *Guns, Inventory *Drugs); +int IsCarryingRandom(Player *Play, int amount); +void ChangeSpaceForInventory(Inventory *Guns, Inventory *Drugs, Player *Play); void InitList(DopeList *List); -void AddListEntry(DopeList *List,DopeEntry *NewEntry); -void RemoveListEntry(DopeList *List,int Entry); -int GetListEntry(DopeList *List,Player *Play); -void RemoveListPlayer(DopeList *List,Player *Play); -void RemoveAllEntries(DopeList *List,Player *Play); +void AddListEntry(DopeList *List, DopeEntry *NewEntry); +void RemoveListEntry(DopeList *List, int Entry); +int GetListEntry(DopeList *List, Player *Play); +void RemoveListPlayer(DopeList *List, Player *Play); +void RemoveAllEntries(DopeList *List, Player *Play); void ClearList(DopeList *List); int TotalGunsCarried(Player *Play); -int read_string(FILE *fp,char **buf); -int brandom(int bot,int top); -price_t prandom(price_t bot,price_t top); -void AddInventory(Inventory *Cumul,Inventory *Add,int Length); -void TruncateInventoryFor(Inventory *Guns,Inventory *Drugs, - Player *Play); -void PrintInventory(Inventory *Guns,Inventory *Drugs); +int read_string(FILE *fp, char **buf); +int brandom(int bot, int top); +price_t prandom(price_t bot, price_t top); +void AddInventory(Inventory *Cumul, Inventory *Add, int Length); +void TruncateInventoryFor(Inventory *Guns, Inventory *Drugs, Player *Play); +void PrintInventory(Inventory *Guns, Inventory *Drugs); price_t strtoprice(char *buf); gchar *pricetostr(price_t price); gchar *FormatPrice(price_t price); -char IsInventoryClear(Inventory *Guns,Inventory *Drugs); +char IsInventoryClear(Inventory *Guns, Inventory *Drugs); void ResizeLocations(int NewNum); void ResizeCops(int NewNum); void ResizeGuns(int NewNum); t@@ -369,39 +377,40 @@ void ResizeDrugs(int NewNum); void ResizeSubway(int NewNum); void ResizePlaying(int NewNum); void ResizeStoppedTo(int NewNum); -void AssignName(gchar **dest,gchar *src); -void CopyNames(struct NAMES *dest,struct NAMES *src); +void AssignName(gchar **dest, gchar *src); +void CopyNames(struct NAMES *dest, struct NAMES *src); + #ifdef NETWORKING -void CopyMetaServer(struct METASERVER *dest,struct METASERVER *src); +void CopyMetaServer(struct METASERVER *dest, struct METASERVER *src); #endif -void CopyLocation(struct LOCATION *dest,struct LOCATION *src); -void CopyCop(struct COP *dest,struct COP *src); -void CopyGun(struct GUN *dest,struct GUN *src); -void CopyDrug(struct DRUG *dest,struct DRUG *src); -void CopyDrugs(struct DRUGS *dest,struct DRUGS *src); -int GetNextDrugIndex(int OldIndex,Player *Play); +void CopyLocation(struct LOCATION *dest, struct LOCATION *src); +void CopyCop(struct COP *dest, struct COP *src); +void CopyGun(struct GUN *dest, struct GUN *src); +void CopyDrug(struct DRUG *dest, struct DRUG *src); +void CopyDrugs(struct DRUGS *dest, struct DRUGS *src); +int GetNextDrugIndex(int OldIndex, Player *Play); gchar *InitialCaps(gchar *string); char StartsWithVowel(char *string); char *GetPlayerName(Player *Play); -void SetPlayerName(Player *Play,char *Name); -void HandleCmdLine(int argc,char *argv[]); +void SetPlayerName(Player *Play, char *Name); +void HandleCmdLine(int argc, char *argv[]); void SetupParameters(void); void HandleHelpTexts(void); -void GeneralStartup(int argc,char *argv[]); +void GeneralStartup(int argc, char *argv[]); void ReadConfigFile(char *FileName); -gboolean ParseNextConfig(GScanner *scanner,gboolean print); -int GetGlobalIndex(gchar *ID1,gchar *ID2); -void *GetGlobalPointer(int GlobalIndex,int StructIndex); -void PrintConfigValue(int GlobalIndex,int StructIndex,gboolean IndexGiven, - GScanner *scanner); -gboolean SetConfigValue(int GlobalIndex,int StructIndex,gboolean IndexGiven, - GScanner *scanner); +gboolean ParseNextConfig(GScanner *scanner, gboolean print); +int GetGlobalIndex(gchar *ID1, gchar *ID2); +void *GetGlobalPointer(int GlobalIndex, int StructIndex); +void PrintConfigValue(int GlobalIndex, int StructIndex, + gboolean IndexGiven, GScanner *scanner); +gboolean SetConfigValue(int GlobalIndex, int StructIndex, + gboolean IndexGiven, GScanner *scanner); gboolean IsCop(Player *Play); -void dopelog(int loglevel,const gchar *format,...); +void dopelog(int loglevel, const gchar *format, ...); GLogLevelFlags LogMask(void); -GString *GetLogString(GLogLevelFlags log_level,const gchar *message); +GString *GetLogString(GLogLevelFlags log_level, const gchar *message); void RestoreConfig(void); -void ScannerErrorHandler(GScanner *scanner,gchar *msg,gint error); +void ScannerErrorHandler(GScanner *scanner, gchar *msg, gint error); void OpenLog(void); void CloseLog(void); gboolean IsConnectedPlayer(Player *play); (DIR) diff --git a/src/error.c b/src/error.c t@@ -1,42 +1,46 @@ -/* error.c Error-handling routines for dopewars */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * error.c Error-handling routines for dopewars * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifdef HAVE_CONFIG_H #include <config.h> #endif -#include <glib.h> /* For GString functions */ -#include <string.h> /* For strerror */ +#include <glib.h> /* For GString functions */ +#include <string.h> /* For strerror */ #ifdef CYGWIN -#include <windows.h> /* For FormatMessage() etc. */ -#include <winsock.h> /* For WSAxxx constants */ +#include <windows.h> /* For FormatMessage() etc. */ +#include <winsock.h> /* For WSAxxx constants */ #else -#include <netdb.h> /* For h_errno error codes */ +#include <netdb.h> /* For h_errno error codes */ #endif #include "error.h" #include "nls.h" -void FreeError(LastError *error) { - if (!error) return; +void FreeError(LastError *error) +{ + if (!error) + return; if (error->type && error->type->FreeErrorData) { (*error->type->FreeErrorData)(error); } else { t@@ -45,129 +49,151 @@ void FreeError(LastError *error) { g_free(error); } -LastError *NewError(ErrorType *type,gint code,gpointer data) { +LastError *NewError(ErrorType *type, gint code, gpointer data) +{ LastError *error; - error = g_new0(LastError,1); - error->type=type; - error->code=code; - error->data=data; + error = g_new0(LastError, 1); + + error->type = type; + error->code = code; + error->data = data; return error; } -void SetError(LastError **error,ErrorType *type,gint code,gpointer data) { - if (!error) return; - if (*error) FreeError(*error); - *error = NewError(type,code,data); +void SetError(LastError **error, ErrorType *type, gint code, gpointer data) +{ + if (!error) + return; + if (*error) + FreeError(*error); + *error = NewError(type, code, data); } -void LookupErrorCode(GString *str,gint code,ErrTable *table, - gchar *fallbackstr) { - for (;table && table->string;table++) { - if (code==table->code) { - g_string_append(str,_(table->string)); +void LookupErrorCode(GString *str, gint code, ErrTable *table, + gchar *fallbackstr) +{ + for (; table && table->string; table++) { + if (code == table->code) { + g_string_append(str, _(table->string)); return; } } - g_string_sprintfa(str,fallbackstr,code); + g_string_sprintfa(str, fallbackstr, code); } /* "Custom" error handling */ static ErrTable CustomErrStr[] = { - { E_FULLBUF,N_("Connection dropped due to full buffer") }, - { 0,NULL } + {E_FULLBUF, N_("Connection dropped due to full buffer")}, + {0, NULL} }; -void CustomAppendError(GString *str,LastError *error) { - LookupErrorCode(str,error->code,CustomErrStr,_("Internal error code %d")); +void CustomAppendError(GString *str, LastError *error) +{ + LookupErrorCode(str, error->code, CustomErrStr, + _("Internal error code %d")); } -static ErrorType ETCustom = { CustomAppendError,NULL }; +static ErrorType ETCustom = { CustomAppendError, NULL }; ErrorType *ET_CUSTOM = &ETCustom; -/* "errno" error handling */ -void ErrnoAppendError(GString *str,LastError *error) { - g_string_append(str,strerror(error->code)); +/* + * "errno" error handling + */ +void ErrnoAppendError(GString *str, LastError *error) +{ + g_string_append(str, strerror(error->code)); } -static ErrorType ETErrno = { ErrnoAppendError,NULL }; +static ErrorType ETErrno = { ErrnoAppendError, NULL }; ErrorType *ET_ERRNO = &ETErrno; #ifdef CYGWIN /* Winsock error handling */ static ErrTable WSAErrStr[] = { -/* These are the explanations of the various Windows Sockets error codes */ - { WSANOTINITIALISED,N_("WinSock has not been properly initialised") }, - { WSASYSNOTREADY,N_("Network subsystem is not ready") }, - { WSAVERNOTSUPPORTED,N_("WinSock version not supported") }, - { WSAENETDOWN,N_("The network subsystem has failed") }, - { WSAEADDRINUSE,N_("Address already in use") }, - { WSAENETDOWN,N_("Cannot reach the network") }, - { WSAETIMEDOUT,N_("The connection timed out") }, - { WSAEMFILE,N_("Out of file descriptors") }, - { WSAENOBUFS,N_("Out of buffer space") }, - { WSAEOPNOTSUPP,N_("Operation not supported") }, - { WSAECONNABORTED,N_("Connection aborted due to failure") }, - { WSAECONNRESET,N_("Connection reset by remote host") }, - { WSAECONNREFUSED,N_("Connection refused") }, - { WSAEAFNOSUPPORT,N_("Address family not supported") }, - { WSAEPROTONOSUPPORT,N_("Protocol not supported") }, - { WSAESOCKTNOSUPPORT,N_("Socket type not supported") }, - { WSAHOST_NOT_FOUND,N_("Host not found") }, - { WSATRY_AGAIN,N_("Temporary name server error - try again later") }, - { WSANO_RECOVERY,N_("Failed to contact nameserver") }, - { WSANO_DATA,N_("Valid name, but no DNS data record present") }, - { 0,NULL } + /* These are the explanations of the various + * Windows Sockets error codes */ + {WSANOTINITIALISED, N_("WinSock has not been properly initialised")}, + {WSASYSNOTREADY, N_("Network subsystem is not ready")}, + {WSAVERNOTSUPPORTED, N_("WinSock version not supported")}, + {WSAENETDOWN, N_("The network subsystem has failed")}, + {WSAEADDRINUSE, N_("Address already in use")}, + {WSAENETDOWN, N_("Cannot reach the network")}, + {WSAETIMEDOUT, N_("The connection timed out")}, + {WSAEMFILE, N_("Out of file descriptors")}, + {WSAENOBUFS, N_("Out of buffer space")}, + {WSAEOPNOTSUPP, N_("Operation not supported")}, + {WSAECONNABORTED, N_("Connection aborted due to failure")}, + {WSAECONNRESET, N_("Connection reset by remote host")}, + {WSAECONNREFUSED, N_("Connection refused")}, + {WSAEAFNOSUPPORT, N_("Address family not supported")}, + {WSAEPROTONOSUPPORT, N_("Protocol not supported")}, + {WSAESOCKTNOSUPPORT, N_("Socket type not supported")}, + {WSAHOST_NOT_FOUND, N_("Host not found")}, + {WSATRY_AGAIN, N_("Temporary name server error - try again later")}, + {WSANO_RECOVERY, N_("Failed to contact nameserver")}, + {WSANO_DATA, N_("Valid name, but no DNS data record present")}, + {0, NULL} }; -void WinsockAppendError(GString *str,LastError *error) { - LookupErrorCode(str,error->code,WSAErrStr,_("Network error code %d")); +void WinsockAppendError(GString *str, LastError *error) +{ + LookupErrorCode(str, error->code, WSAErrStr, _("Network error code %d")); } -static ErrorType ETWinsock = { WinsockAppendError,NULL }; +static ErrorType ETWinsock = { WinsockAppendError, NULL }; ErrorType *ET_WINSOCK = &ETWinsock; -/* Standard Win32 "GetLastError" handling */ -void Win32AppendError(GString *str,LastError *error) { +/* + * Standard Win32 "GetLastError" handling + */ +void Win32AppendError(GString *str, LastError *error) +{ LPTSTR lpMsgBuf; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, - NULL,error->code,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), - (LPTSTR)&lpMsgBuf,0,NULL); - g_string_append(str,lpMsgBuf); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, NULL, error->code, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) & lpMsgBuf, 0, NULL); + g_string_append(str, lpMsgBuf); LocalFree(lpMsgBuf); } -static ErrorType ETWin32 = { Win32AppendError,NULL }; +static ErrorType ETWin32 = { Win32AppendError, NULL }; ErrorType *ET_WIN32 = &ETWin32; #else /* h_errno error handling */ static ErrTable DNSErrStr[] = { -/* These are the explanations of the various name server error codes */ - { HOST_NOT_FOUND,N_("Host not found") }, - { TRY_AGAIN,N_("Temporary name server error - try again later") }, - { 0,NULL } + /* These are the explanations of the various name server error codes */ + {HOST_NOT_FOUND, N_("Host not found")}, + {TRY_AGAIN, N_("Temporary name server error - try again later")}, + {0, NULL} }; -void HErrnoAppendError(GString *str,LastError *error) { - LookupErrorCode(str,error->code,DNSErrStr,_("Name server error code %d")); +void HErrnoAppendError(GString *str, LastError *error) +{ + LookupErrorCode(str, error->code, DNSErrStr, + _("Name server error code %d")); } -static ErrorType ETHErrno = { HErrnoAppendError,NULL }; +static ErrorType ETHErrno = { HErrnoAppendError, NULL }; ErrorType *ET_HERRNO = ÐErrno; #endif /* CYGWIN */ -void g_string_assign_error(GString *str,LastError *error) { - g_string_truncate(str,0); - g_string_append_error(str,error); +void g_string_assign_error(GString *str, LastError *error) +{ + g_string_truncate(str, 0); + g_string_append_error(str, error); } -void g_string_append_error(GString *str,LastError *error) { - if (!error || !error->type) return; - (*error->type->AppendErrorString)(str,error); +void g_string_append_error(GString *str, LastError *error) +{ + if (!error || !error->type) + return; + (*error->type->AppendErrorString) (str, error); } (DIR) diff --git a/src/error.h b/src/error.h t@@ -1,23 +1,24 @@ -/* error.h Header file for dopewars error-handling routines */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * error.h Header file for dopewars error-handling routines * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __ERROR_H__ #define __ERROR_H__ t@@ -30,8 +31,8 @@ struct _LastError; typedef struct _ErrorType { - void (*AppendErrorString)(GString *str,struct _LastError *error); - void (*FreeErrorData)(struct _LastError *error); + void (*AppendErrorString) (GString *str, struct _LastError *error); + void (*FreeErrorData) (struct _LastError *error); } ErrorType; typedef struct _LastError { t@@ -40,15 +41,16 @@ typedef struct _LastError { gpointer data; } LastError; -extern ErrorType *ET_CUSTOM,*ET_ERRNO; +extern ErrorType *ET_CUSTOM, *ET_ERRNO; + #ifdef CYGWIN -extern ErrorType *ET_WIN32,*ET_WINSOCK; +extern ErrorType *ET_WIN32, *ET_WINSOCK; #else extern ErrorType *ET_HERRNO; #endif typedef enum { - E_FULLBUF + E_FULLBUF } CustomErrorCode; typedef struct _ErrTable { t@@ -57,11 +59,12 @@ typedef struct _ErrTable { } ErrTable; void FreeError(LastError *error); -LastError *NewError(ErrorType *type,gint code,gpointer data); -void SetError(LastError **error,ErrorType *type,gint code,gpointer data); -void LookupErrorCode(GString *str,gint code,ErrTable *table, +LastError *NewError(ErrorType *type, gint code, gpointer data); +void SetError(LastError **error, ErrorType *type, gint code, + gpointer data); +void LookupErrorCode(GString *str, gint code, ErrTable *table, gchar *fallbackstr); -void g_string_assign_error(GString *str,LastError *error); -void g_string_append_error(GString *str,LastError *error); +void g_string_assign_error(GString *str, LastError *error); +void g_string_append_error(GString *str, LastError *error); #endif /* __ERROR_H__ */ (DIR) diff --git a/src/gtk_client.c b/src/gtk_client.c t@@ -1,22 +1,24 @@ -/* gtk_client.c dopewars client using the GTK+ toolkit */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * gtk_client.c dopewars client using the GTK+ toolkit * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifdef HAVE_CONFIG_H #include <config.h> t@@ -46,53 +48,53 @@ #define ET_TIPOFF 1 /* Which notebook page to display in the New Game dialog */ -static gint NewGameType=0; +static gint NewGameType = 0; struct InventoryWidgets { - GtkWidget *HereList,*CarriedList; - GtkWidget *HereFrame,*CarriedFrame; - GtkWidget *BuyButton,*SellButton,*DropButton; - GtkWidget *vbbox; + GtkWidget *HereList, *CarriedList; + GtkWidget *HereFrame, *CarriedFrame; + GtkWidget *BuyButton, *SellButton, *DropButton; + GtkWidget *vbbox; }; struct StatusWidgets { - GtkWidget *Location,*Date,*SpaceName,*SpaceValue,*CashName,*CashValue, - *DebtName,*DebtValue,*BankName,*BankValue, - *GunsName,*GunsValue,*BitchesName,*BitchesValue, - *HealthName,*HealthValue; + 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 *window, *messages; + Player *Play; + GtkItemFactory *Menu; + struct StatusWidgets Status; + struct InventoryWidgets Drug, Gun, InvenDrug, InvenGun; + GtkWidget *JetButton, *vbox, *PlayerList, *TalkList; + guint JetAccel; }; struct StartGameStruct { - GtkWidget *dialog,*name,*hostname,*port,*antique,*status,*metaserv; + GtkWidget *dialog, *name, *hostname, *port, *antique, *status, *metaserv; #ifdef NETWORKING - HttpConnection *MetaConn; - GSList *NewMetaList; + HttpConnection *MetaConn; + GSList *NewMetaList; #endif }; static struct ClientDataStruct ClientData; -static gboolean InGame=FALSE; - -static GtkWidget *FightDialog=NULL,*SpyReportsDialog; -static gboolean IsShowingPlayerList=FALSE,IsShowingTalkList=FALSE, - 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 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); t@@ -100,1698 +102,1913 @@ 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, +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 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; +static GSList *MetaList = NULL; #endif /* NETWORKING */ -static void HandleClientMessage(char *buf,Player *Play); +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 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, + 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 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 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 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 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, +static void CreateInventory(GtkWidget *hbox, gchar *Objects, GtkAccelGroup *accel_group, - gboolean CreateButtons,gboolean CreateHere, + gboolean CreateButtons, gboolean CreateHere, struct InventoryWidgets *widgets, GtkSignalFunc CallBack); -static void GetSpyReports(GtkWidget *widget,gpointer data); +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 } + /* 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 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)); +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 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(); +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); +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; - } - NewGameDialog(); +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; + } + NewGameDialog(); } -void ListScores(GtkWidget *widget,gpointer data) { - SendClientMessage(ClientData.Play,C_NONE,C_REQUESTSCORE,NULL,NULL); +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; +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); + 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")); + /* 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); + 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); + 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); + 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); + 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); + 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); + 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); + /* 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); + gtk_container_add(GTK_CONTAINER(window), vbox); - UpdateInventory(&ClientData.InvenDrug,ClientData.Play->Drugs,NumDrug,TRUE); - UpdateInventory(&ClientData.InvenGun,ClientData.Play->Guns,NumGun,FALSE); + UpdateInventory(&ClientData.InvenDrug, ClientData.Play->Drugs, NumDrug, + TRUE); + UpdateInventory(&ClientData.InvenGun, ClientData.Play->Guns, NumGun, + FALSE); - gtk_widget_show_all(window); + 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, +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); + 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\t(%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\t(%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; - } +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\t(%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\t(%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; + GtkWidget *dialog, *table, *vbox; }; -static struct HiScoreDiaStruct HiScoreDialog = { NULL,NULL,NULL }; - -void PrepareHighScoreDialog(void) { -/* Creates an empty dialog to display high scores */ - 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); -} - -void AddScoreToDialog(char *Data) { -/* 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. */ - 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); -} - -static void EndHighScore(GtkWidget *widget) { -/* 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. */ - EndGame(); -} - -void CompleteHighScoreDialog(gboolean AtEnd) { -/* 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. */ - 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; -} - -void PrintMessage(char *text) { -/* 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". */ - 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); -} - -static void FightCallback(GtkWidget *widget,gpointer data) { -/* Called when one of the action buttons in the Fight dialog is clicked. */ -/* "data" specifies which button (Deal Drugs/Run/Fight/Stand) was pressed. */ - 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 { -/* gtk_widget_hide(FightDialog);*/ - Jet(FightDialog); - } - break; - case 'F': case 'S': - text[0]=Answer; text[1]='\0'; - SendClientMessage(Play,C_NONE,C_FIGHTACT,NULL,text); - break; - } -} - -static GtkWidget *AddFightButton(gchar *Text,GtkAccelGroup *accel_group, - GtkBox *box,gint Answer) { -/* 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. */ - 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; +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 */ + * player/cop involved in a fight */ struct combatant { - GtkWidget *name,*bitches,*healthprog,*healthlabel; + GtkWidget *name, *bitches, *healthprog, *healthlabel; }; -static void CreateFightDialog(void) { -/* 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. */ - 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); -} - -static void UpdateCombatant(gchar *DefendName,int DefendBitches, - gchar *BitchName,int DefendHealth) { -/* 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. */ - 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); -} - -static void FreeCombatants(void) { -/* Cleans up the list of all players/cops involved in a fight. */ - GArray *combatants; - combatants=(GArray *)gtk_object_get_data(GTK_OBJECT(FightDialog), - "combatants"); - if (!combatants) return; - - g_array_free(combatants,TRUE); -} - -void DisplayFightMessage(char *Data) { -/* 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. */ - 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; +/* + * 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; } - 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: + 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); } - 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); -} - -void DisplayStats(Player *Play,struct StatusWidgets *Status) { -/* 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. */ - 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); -} - -void UpdateStatus(Player *Play) { -/* 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). */ - 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); - } + 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); - } - } + 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)); + 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)); - } + 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; - } + 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 (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); - } + 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); } - } - - 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); + 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); } - g_list_free(glist[i]); - } + } + } + + 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)); + 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); - } + 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) { +static void JetCallback(GtkWidget *widget, gpointer data) +{ int NewLocation; gchar *text; GtkWidget *JetDialog; - JetDialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),"dialog")); + 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); + text = g_strdup_printf("%d", NewLocation); + SendClientMessage(ClientData.Play, C_NONE, C_REQUESTJET, NULL, text); g_free(text); } -void JetButtonPressed(GtkWidget *widget,gpointer data) { +void JetButtonPressed(GtkWidget *widget, gpointer data) +{ if (InGame) { if (ClientData.Play->Flags & FIGHTING) { - DisplayFightMessage(NULL); + DisplayFightMessage(NULL); } else { - Jet(NULL); + Jet(NULL); } } } -void Jet(GtkWidget *parent) { - GtkWidget *dialog,*table,*button,*label,*vbox; - GtkAccelGroup *accel_group; - gint boxsize,i,row,col; - gchar *name,AccelChar; +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(); + 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")); + 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)); + 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); - vbox=gtk_vbox_new(FALSE,7); + gtk_container_add(GTK_CONTAINER(dialog), vbox); + gtk_widget_show_all(dialog); +} -/* Prompt in 'Jet' dialog */ - label=gtk_label_new(_("Where to, dude ? ")); - gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); +struct DealDiaStruct { + GtkWidget *dialog, *cost, *carrying, *space, *afford, *amount; + gint DrugInd; + gpointer Type; +}; +static struct DealDiaStruct DealDialog; - /* Generate a square box of buttons for all locations */ - boxsize=1; - while (boxsize*boxsize < NumLocation) boxsize++; - col=boxsize; row=1; +static void UpdateDealDialog(void) +{ + GString *text; + GtkAdjustment *spin_adj; + gint DrugInd, CanDrop, CanCarry, CanAfford, MaxDrug; + Player *Play; - /* Avoid creating a box with an entire row empty at the bottom */ - while (row*col < NumLocation) row++; + text = g_string_new(NULL); + DrugInd = DealDialog.DrugInd; + Play = ClientData.Play; - table=gtk_table_new(row,col,TRUE); + /* 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); - for (i=0;i<NumLocation;i++) { - if (i<9) AccelChar='1'+i; - else if (i<35) AccelChar='A'+i-9; - else AccelChar='\0'; + CanDrop = Play->Drugs[DrugInd].Carried; - 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); + /* 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; - gtk_container_add(GTK_CONTAINER(dialog),vbox); - gtk_widget_show_all(dialog); + /* 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); } -struct DealDiaStruct { - GtkWidget *dialog,*cost,*carrying,*space,*afford,*amount; - gint DrugInd; - gpointer Type; -}; -static struct DealDiaStruct DealDialog; +static void DealSelectCallback(GtkWidget *widget, gpointer data) +{ + DealDialog.DrugInd = GPOINTER_TO_INT(data); + UpdateDealDialog(); +} -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; +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; - gchar *Responses,**split,*LabelText,*trword,*underline; + 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; + } -/* Button titles that correspond to the single-keypress options provided - by the curses client (e.g. _Yes corresponds to 'Y' etc.) */ + 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") }; + N_("_Fight"), N_("_Attack"), N_("_Evade") + }; gint numWords = sizeof(Words) / sizeof(Words[0]); - gint i,j; + gint i, j; - split=g_strsplit(Data,"^",1); + split = g_strsplit(Data, "^", 1); if (!split[0] || !split[1]) { - g_warning("Bad QUESTION message %s",Data); return; + g_warning("Bad QUESTION message %s", Data); + return; } - g_strdelimit(split[1],"^",'\n'); + g_strdelimit(split[1], "^", '\n'); - Responses=split[0]; LabelText=split[1]; + 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); + 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")); + /* 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_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); + 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); + hsep = gtk_hseparator_new(); + gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); - hbbox=gtk_hbutton_box_new(); + 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]) { + 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(""); + button = gtk_button_new_with_label(""); if (trword) { - SetAccelerator(button,trword,button,"clicked",accel_group); + SetAccelerator(button, trword, button, "clicked", accel_group); } else { - trword = g_strdup_printf("_%c",Responses[i]); - SetAccelerator(button,trword,button,"clicked",accel_group); + 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_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(hbbox), button, TRUE, TRUE, 0); } - gtk_box_pack_start(GTK_BOX(vbox),hbbox,TRUE,TRUE,0); - gtk_container_add(GTK_CONTAINER(dialog),vbox); + 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); +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) t@@ -1801,369 +2018,414 @@ static void SetIcon(GtkWidget *window, gchar **xpmdata) 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 + 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 = 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; +} + +void display_intro(GtkWidget *widget, gpointer data) +{ + GtkWidget *dialog, *label, *table, *OKButton, *vbox, *hbox, *hsep; + gchar *VersionStr; + const int rows = 6, cols = 3; + int i, j; + gchar *table_data[6][3] = { + /* Credits labels in GTK+ 'about' dialog */ + {N_("Icons and graphics"), "Ocelot Mantis", NULL}, + {N_("Drug Dealing and Research"), "Dan Wolf", NULL}, + {N_("Play Testing"), "Phil Davis", "Owen Walsh"}, + {N_("Extensive Play Testing"), "Katherine Holt", + "Caroline Moore"}, + {N_("Constructive Criticism"), "Andrea Elliot-Smith", + "Pete Winn"}, + {N_("Unconstructive Criticism"), "James Matthews", NULL} + }; + + dialog = gtk_window_new(GTK_WINDOW_DIALOG); + + /* Title of GTK+ 'about' dialog */ + gtk_window_set_title(GTK_WINDOW(dialog), _("About dopewars")); + + gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); + gtk_window_set_transient_for(GTK_WINDOW(dialog), + GTK_WINDOW(ClientData.window)); + gtk_container_border_width(GTK_CONTAINER(dialog), 10); + + vbox = gtk_vbox_new(FALSE, 5); + + /* Main content of GTK+ 'about' dialog */ + label = gtk_label_new(_("Based on John E. Dell's old Drug Wars game, " + "dopewars is a simulation of an\nimaginary drug " + "market. dopewars is an All-American game which " + "features\nbuying, selling, and trying to get " + "past the cops!\n\nThe first thing you need to " + "do is pay off your debt to the Loan Shark. " + "After\nthat, your goal is to make as much " + "money as possible (and stay alive)! You\n" + "have one month of game time to make " + "your fortune.\n")); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + + /* Version and copyright notice in GTK+ 'about' dialog */ + VersionStr = g_strdup_printf(_("Version %s " + "Copyright (C) 1998-2002 " + "Ben Webb ben@bellatrix.pcl.ox.ac.uk\n" + "dopewars is released under the " + "GNU General Public Licence\n"), VERSION); + label = gtk_label_new(VersionStr); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + g_free(VersionStr); + + table = gtk_table_new(rows, cols, FALSE); + gtk_table_set_row_spacings(GTK_TABLE(table), 3); + gtk_table_set_col_spacings(GTK_TABLE(table), 3); + for (i = 0; i < rows; i++) + for (j = 0; j < cols; j++) + if (table_data[i][j]) { + if (j == 0) + label = gtk_label_new(_(table_data[i][j])); + else + label = gtk_label_new(table_data[i][j]); + gtk_table_attach_defaults(GTK_TABLE(table), label, j, j + 1, i, + i + 1); + } + gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); + + /* Label at the bottom of GTK+ 'about' dialog */ + label = gtk_label_new(_("\nFor information on the command line " + "options, type dopewars -h at your\n" + "Unix prompt. This will display a help " + "screen, listing the available options.\n")); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + + /* 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, FALSE, 0); + label = gtk_url_new("http://dopewars.sourceforge.net/", + "http://dopewars.sourceforge.net/", WebBrowser); + gtk_box_pack_start(GTK_BOX(hbox), label, 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); + + 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 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 NETWORKING +static void ConnectError(struct StartGameStruct *widgets, gboolean meta) +{ + GString *neterr; + gchar *text; + LastError *error; -#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 + if (meta) + error = widgets->MetaConn->NetBuf.error; + else + error = ClientData.Play->NetBuf.error; -/* Set up message handlers */ - ClientMessageHandlerPt = HandleClientMessage; + neterr = g_string_new(""); -/* 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 (error) { + g_string_assign_error(neterr, error); + } else { + g_string_assign(neterr, _("Connection closed by remote host")); + } - if (!CheckHighScoreFileConfig()) return TRUE; + 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); + } -/* Create the main player */ - ClientData.Play=g_new(Player,1); - FirstClient=AddPlayer(0,ClientData.Play,FirstClient); + SetStartGameStatus(widgets, text); + g_free(text); + g_string_free(neterr, TRUE); +} - window=ClientData.window=gtk_window_new(GTK_WINDOW_TOPLEVEL); +void FinishServerConnect(struct StartGameStruct *widgets, + gboolean ConnectOK) +{ + if (ConnectOK) { + Client = Network = TRUE; + gtk_widget_destroy(widgets->dialog); + StartGame(); + } else { + ConnectError(widgets, FALSE); + } +} -/* 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); +static void DoConnect(struct StartGameStruct *widgets) +{ + gchar *text; + NetworkBuffer *NetBuf; + NBStatus oldstatus; + NBSocksStatus oldsocks; - 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); + NetBuf = &ClientData.Play->NetBuf; - 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>"); + /* 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); - vbox2=gtk_vbox_new(FALSE,0); - gtk_box_pack_start(GTK_BOX(vbox2),menubar,FALSE,FALSE,0); - gtk_widget_show_all(menubar); - UpdateMenus(); + /* Terminate any existing connection attempts */ + ShutdownNetworkBuffer(NetBuf); + if (widgets->MetaConn) { + CloseHttpConnection(widgets->MetaConn); + widgets->MetaConn = NULL; + } - 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; -} - -void display_intro(GtkWidget *widget,gpointer data) { - GtkWidget *dialog, *label, *table, *OKButton, *vbox, *hbox, *hsep; - gchar *VersionStr; - 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); - - label=gtk_label_new( -/* Main content of GTK+ 'about' dialog */ -_("Based on John E. Dell's old Drug Wars game, dopewars is a simulation of an\n" -"imaginary drug market. dopewars is an All-American game which features\n" -"buying, selling, and trying to get past the cops!\n\n" -"The first thing you need to do is pay off your debt to the Loan Shark. After\n" -"that, your goal is to make as much money as possible (and stay alive)! You\n" -"have one month of game time to make your fortune.\n")); - gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); - -/* Version and copyright notice in GTK+ 'about' dialog */ - VersionStr=g_strdup_printf(_("Version %s " -"Copyright (C) 1998-2002 Ben Webb ben@bellatrix.pcl.ox.ac.uk\n" -"dopewars is released under the GNU General Public Licence\n"),VERSION); - label=gtk_label_new(VersionStr); - gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); - g_free(VersionStr); - - table = gtk_table_new(rows,cols,FALSE); - gtk_table_set_row_spacings(GTK_TABLE(table),3); - gtk_table_set_col_spacings(GTK_TABLE(table),3); - for (i=0;i<rows;i++) for (j=0;j<cols;j++) if (table_data[i][j]) { - if (j==0) label=gtk_label_new(_(table_data[i][j])); - else label=gtk_label_new(table_data[i][j]); - gtk_table_attach_defaults(GTK_TABLE(table),label,j,j+1,i,i+1); - } - gtk_box_pack_start(GTK_BOX(vbox),table,FALSE,FALSE,0); - - label=gtk_label_new( -/* Label at the bottom of GTK+ 'about' dialog */ -_("\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); - - /* 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, FALSE, 0); - label = gtk_url_new("http://dopewars.sourceforge.net/", - "http://dopewars.sourceforge.net/", - WebBrowser); - gtk_box_pack_start(GTK_BOX(hbox), label, 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); - - 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); + 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 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 ConnectToServer(GtkWidget *widget, + struct StartGameStruct *widgets) +{ + gchar *text; -static void SetStartGameStatus(struct StartGameStruct *widgets,gchar *msg) { - gtk_label_set_text(GTK_LABEL(widgets->status), - msg ? msg : _("Status: Waiting for user input")); -} + 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); -#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); + 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)); + 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) { +void DisplayConnectStatus(struct StartGameStruct *widgets, gboolean meta, + NBStatus oldstatus, NBSocksStatus oldsocks) +{ NBStatus status; NBSocksStatus sockstat; gchar *text; t@@ -2175,1344 +2437,1454 @@ void DisplayConnectStatus(struct StartGameStruct *widgets,gboolean meta, status = ClientData.Play->NetBuf.status; sockstat = ClientData.Play->NetBuf.sockstat; } - if (oldstatus==status && sockstat==oldsocks) return; + if (oldstatus == status && sockstat == oldsocks) + return; switch (status) { - case NBS_PRECONNECT: + 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 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; - } + case NBSS_USERPASSWD: + SetStartGameStatus(widgets, + _("Status: Authenticating with SOCKS server")); break; - case NBS_CONNECTED: - if (meta) SetStartGameStatus(widgets, - _("Status: Obtaining server information from metaserver...")); + 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) { +static void MetaDone(struct StartGameStruct *widgets) +{ if (IsHttpError(widgets->MetaConn)) { - ConnectError(widgets,TRUE); + ConnectError(widgets, TRUE); } else { - SetStartGameStatus(widgets,NULL); + 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, + 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); + 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; - } + 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); - } + 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); + 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) { + 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); + /* 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,*frame,*button; - GtkWidget *dialog; - GtkAccelGroup *accel_group; - static struct StartGameStruct widgets; - guint AccelKey; +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; + 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"); + /* 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; + 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)); + 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); + gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300); #endif - accel_group=gtk_accel_group_new(); + 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); + /* 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); + vbox = gtk_vbox_new(FALSE, 7); + hbox = gtk_hbox_new(FALSE, 7); - label=gtk_label_new(""); + 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); + 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); + 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); - notebook=gtk_notebook_new(); + 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); + 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); + /* 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); + /* 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); + 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); + /* 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_container_add(GTK_CONTAINER(widgets.dialog), vbox); - gtk_widget_grab_focus(widgets.name); + gtk_widget_grab_focus(widgets.name); #ifdef NETWORKING - if (UpdateMeta) { - UpdateMetaServerList(NULL,&widgets); - } else { - FillMetaServerList(&widgets,FALSE); - } + 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); + 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 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 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) { +static void TransferOK(GtkWidget *widget, GtkWidget *dialog) +{ gpointer Debt; - GtkWidget *deposit,*entry; - gchar *text,*title; + GtkWidget *deposit, *entry; + gchar *text, *title; price_t money; - gboolean withdraw=FALSE; + 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); + 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 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; + if (money > ClientData.Play->Debt) + money = ClientData.Play->Debt; } else { -/* Title of bank dialog - (%Tde="The Bank" by default) */ + /* 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")); + deposit = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(dialog), "deposit")); if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(deposit))) { - withdraw=TRUE; + 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); + 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); + 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,*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); +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; + 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); - } +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); + } + } + g_free(text); + g_string_free(msg, TRUE); } -void TalkToAll(GtkWidget *widget,gpointer data) { - TalkDialog(TRUE); +void TalkToAll(GtkWidget *widget, gpointer data) +{ + TalkDialog(TRUE); } -void TalkToPlayers(GtkWidget *widget,gpointer data) { - TalkDialog(FALSE); +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; +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); + 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)")); + /* 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); + 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); + 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)); + gtk_window_set_transient_for(GTK_WINDOW(dialog), + GTK_WINDOW(ClientData.window)); - vbox=gtk_vbox_new(FALSE,7); + 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); + 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")); + 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); + 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:-")); + /* 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); + 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); + 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); + hsep = gtk_hseparator_new(); + gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); - hbbox=gtk_hbutton_box_new(); + hbbox = gtk_hbutton_box_new(); -/* Button to send a message to other players */ - button=gtk_button_new_with_label(_("Send")); + /* 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); + 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); + 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_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0); - gtk_container_add(GTK_CONTAINER(dialog),vbox); - gtk_widget_show_all(dialog); + gtk_container_add(GTK_CONTAINER(dialog), vbox); + gtk_widget_show_all(dialog); } -GtkWidget *CreatePlayerList(void) { - GtkWidget *clist; - gchar *text[1]; +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; + 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")); - - text=dpg_strdup_printf( -/* Informative text for "spy on player" dialog. (%tde = "bitch", "bitch", - "guns", "drugs", respectively, by default) */ -_("Please choose the player to spy on. Your %tde will\n" -"then offer his services to the player, and if successful,\n" -"you will be able to view the player's stats with the\n" -"\"Get spy reports\" menu. Remember that the %tde will leave\n" -"you, 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")); - - text=dpg_strdup_printf( -/* Informative text for "tip off cops" dialog. (%tde = "bitch", "bitch", - "guns", "drugs", respectively, by default) */ -_("Please choose the player to tip off the cops to. Your %tde will\n" -"help the cops to attack that player, and then report back to you\n" -"on 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 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 NewNameDialog(void) { - GtkWidget *window,*button,*hsep,*vbox,*label,*entry; +void ErrandDialog(gint ErrandType) +{ + GtkWidget *dialog, *clist, *button, *vbox, *hbbox, *hsep, *label; + gchar *text; - window=gtk_window_new(GTK_WINDOW_DIALOG); + 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)); -/* Title of dialog for changing a player's name */ - gtk_window_set_title(GTK_WINDOW(window),_("Change Name")); + 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 { - 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); + /* 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); + } - vbox=gtk_vbox_new(FALSE,7); + 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); +} -/* 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); +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); +} - 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); +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); + } - hsep=gtk_hseparator_new(); - gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); + /* 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; - 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); + gtk_box_pack_start(GTK_BOX(hbox), frame[1], TRUE, TRUE, 0); + g_string_free(text, TRUE); } -gint DisallowDelete(GtkWidget *widget,GdkEvent *event,gpointer data) { - return(TRUE); +void DestroyShowing(GtkWidget *widget, gpointer data) +{ + gboolean *IsShowing; + + IsShowing = + (gboolean *)gtk_object_get_data(GTK_OBJECT(widget), "IsShowing"); + if (IsShowing) + *IsShowing = FALSE; } -void GunShopDialog(void) { - GtkWidget *window,*button,*hsep,*vbox,*hbox; - GtkAccelGroup *accel_group; - gchar *text; +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); +} - 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); +void NewNameDialog(void) +{ + GtkWidget *window, *button, *hsep, *vbox, *label, *entry; -/* 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); + window = gtk_window_new(GTK_WINDOW_DIALOG); - vbox=gtk_vbox_new(FALSE,7); + /* Title of dialog for changing a player's name */ + gtk_window_set_title(GTK_WINDOW(window), _("Change Name")); - hbox=gtk_hbox_new(FALSE,7); - CreateInventory(hbox,Names.Guns,accel_group,TRUE,TRUE,&ClientData.Gun, - DealGuns); + 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); - gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,0); + vbox = gtk_vbox_new(FALSE, 7); - hsep=gtk_hseparator_new(); - gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); + /* 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); -/* Button to finish buying/selling guns in the gun shop */ - button=gtk_button_new_with_label(_("Done")); + 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); - 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); + hsep = gtk_hseparator_new(); + gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); - gtk_container_add(GTK_CONTAINER(window),vbox); + 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); - UpdateInventory(&ClientData.Gun,ClientData.Play->Guns,NumGun,FALSE); - gtk_widget_show_all(window); + gtk_container_add(GTK_CONTAINER(window), vbox); + gtk_widget_show_all(window); } -void UpdatePlayerLists(void) { - if (IsShowingPlayerList) UpdatePlayerList(ClientData.PlayerList,FALSE); - if (IsShowingTalkList) UpdatePlayerList(ClientData.TalkList,FALSE); +gint DisallowDelete(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + return (TRUE); } -void GetSpyReports(GtkWidget *Widget,gpointer data) { - SendClientMessage(ClientData.Play,C_NONE,C_CONTACTSPY,NULL,NULL); -} +void GunShopDialog(void) +{ + GtkWidget *window, *button, *hsep, *vbox, *hbox; + GtkAccelGroup *accel_group; + gchar *text; -static void DestroySpyReports(GtkWidget *widget,gpointer data) { - SpyReportsDialog=NULL; -} + 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); -static void CreateSpyReports(void) { - GtkWidget *window,*button,*vbox,*notebook; - GtkAccelGroup *accel_group; + vbox = gtk_vbox_new(FALSE, 7); - 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); + hbox = gtk_hbox_new(FALSE, 7); + CreateInventory(hbox, Names.Guns, accel_group, TRUE, TRUE, + &ClientData.Gun, DealGuns); -/* Title of window to display reports from spies with other players */ - gtk_window_set_title(GTK_WINDOW(window),_("Spy reports")); + gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); - 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); + hsep = gtk_hseparator_new(); + gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); - vbox=gtk_vbox_new(FALSE,5); - notebook=gtk_notebook_new(); - gtk_object_set_data(GTK_OBJECT(window),"notebook",notebook); + /* Button to finish buying/selling guns in the gun shop */ + button = gtk_button_new_with_label(_("Done")); - gtk_box_pack_start(GTK_BOX(vbox),notebook,TRUE,TRUE,0); + 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); - 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_container_add(GTK_CONTAINER(window),vbox); + UpdateInventory(&ClientData.Gun, ClientData.Play->Guns, NumGun, FALSE); + gtk_widget_show_all(window); +} - gtk_widget_show_all(window); +void UpdatePlayerLists(void) +{ + if (IsShowingPlayerList) + UpdatePlayerList(ClientData.PlayerList, FALSE); + if (IsShowingTalkList) + UpdatePlayerList(ClientData.TalkList, FALSE); } -void DisplaySpyReports(Player *Play) { - GtkWidget *dialog,*notebook,*vbox,*hbox,*frame,*label,*table; - GtkAccelGroup *accel_group; - struct StatusWidgets Status; - struct InventoryWidgets SpyDrugs,SpyGuns; +void GetSpyReports(GtkWidget *Widget, gpointer data) +{ + SendClientMessage(ClientData.Play, C_NONE, C_CONTACTSPY, NULL, NULL); +} - 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); +static void DestroySpyReports(GtkWidget *widget, gpointer data) +{ + SpyReportsDialog = NULL; +} - 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); +static void CreateSpyReports(void) +{ + GtkWidget *window, *button, *vbox, *notebook; + GtkAccelGroup *accel_group; - gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,0); - label=gtk_label_new(GetPlayerName(Play)); + 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); - DisplayStats(Play,&Status); - UpdateInventory(&SpyDrugs,Play->Drugs,NumDrug,TRUE); - UpdateInventory(&SpyGuns,Play->Guns,NumGun,FALSE); + /* Title of window to display reports from spies with other players */ + gtk_window_set_title(GTK_WINDOW(window), _("Spy reports")); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook),vbox,label); + 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); - gtk_widget_show_all(notebook); -} + vbox = gtk_vbox_new(FALSE, 5); + notebook = gtk_notebook_new(); + gtk_object_set_data(GTK_OBJECT(window), "notebook", 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); -} + gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); -static void DestroyAuthDialog(GtkWidget *window,gpointer data) { - GtkWidget *userentry,*passwdentry; - gchar *username=NULL,*password=NULL; - gpointer proxy,authok; - HttpConnection *conn; + 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); - 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); + gtk_container_add(GTK_CONTAINER(window), vbox); - if (authok) { - username = gtk_editable_get_chars(GTK_EDITABLE(userentry),0,-1); - password = gtk_editable_get_chars(GTK_EDITABLE(passwdentry),0,-1); - } + gtk_widget_show_all(window); +} - SetHttpAuthentication(conn,GPOINTER_TO_INT(proxy),username,password); +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); +} - g_free(username); g_free(password); +#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); } -void AuthDialog(HttpConnection *conn,gboolean proxy,gchar *realm, - gpointer data) { - GtkWidget *window,*button,*hsep,*vbox,*label,*entry,*table,*hbbox; +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); + } - 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); + SetHttpAuthentication(conn, GPOINTER_TO_INT(proxy), username, password); + + g_free(username); + g_free(password); +} - 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")); - } +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); + 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); + 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); + 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, 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(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); + 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); + 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); + 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); + 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); + /* 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_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 2, 3); - gtk_box_pack_start(GTK_BOX(vbox),table,TRUE,TRUE,0); + 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); + hsep = gtk_hseparator_new(); + gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); - hbbox = gtk_hbutton_box_new(); + 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(_("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); + 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_box_pack_start(GTK_BOX(vbox), hbbox, TRUE, TRUE, 0); - gtk_container_add(GTK_CONTAINER(window),vbox); - gtk_widget_show_all(window); + 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 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); - } +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); + 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; +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)); + 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")); + /* 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + /* 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_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 1, 2); - gtk_box_pack_start(GTK_BOX(vbox),table,TRUE,TRUE,0); + 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); + hsep = gtk_hseparator_new(); + gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); - hbbox = gtk_hbutton_box_new(); + 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(_("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); + 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_box_pack_start(GTK_BOX(vbox), hbbox, TRUE, TRUE, 0); - gtk_container_add(GTK_CONTAINER(window),vbox); - gtk_widget_show_all(window); + gtk_container_add(GTK_CONTAINER(window), vbox); + gtk_widget_show_all(window); } -void MetaSocksAuthDialog(NetworkBuffer *netbuf,gpointer data) { - RealSocksAuthDialog(netbuf,TRUE,data); +void MetaSocksAuthDialog(NetworkBuffer *netbuf, gpointer data) +{ + RealSocksAuthDialog(netbuf, TRUE, data); } -void SocksAuthDialog(NetworkBuffer *netbuf,gpointer data) { - RealSocksAuthDialog(netbuf,FALSE,data); +void SocksAuthDialog(NetworkBuffer *netbuf, gpointer data) +{ + RealSocksAuthDialog(netbuf, FALSE, data); } #endif /* NETWORKING */ t@@ -3520,17 +3892,18 @@ void SocksAuthDialog(NetworkBuffer *netbuf,gpointer data) { #else #include <glib.h> -#include "nls.h" /* We need this for the definition of '_' */ +#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" +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; + } + return FALSE; } #endif /* GUI_CLIENT */ (DIR) diff --git a/src/gtk_client.h b/src/gtk_client.h t@@ -1,23 +1,24 @@ -/* gtk_client.h dopewars client using the GTK+ toolkit */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * gtk_client.h dopewars client using the GTK+ toolkit * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __GTK_CLIENT_H__ #define __GTK_CLIENT_H__ t@@ -29,9 +30,9 @@ #include <glib.h> #ifdef CYGWIN -char GtkLoop(HINSTANCE hInstance,HINSTANCE hPrevInstance); +char GtkLoop(HINSTANCE hInstance, HINSTANCE hPrevInstance); #else -char GtkLoop(int *argc,char **argv[],gboolean ReturnOnFail); +char GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail); #endif #endif (DIR) diff --git a/src/gtkport.c b/src/gtkport.c t@@ -1,31 +1,33 @@ -/* gtkport.c Portable "almost-GTK+" for Unix/Win32 */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * gtkport.c Portable "almost-GTK+" for Unix/Win32 * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifdef HAVE_CONFIG_H #include <config.h> #endif #ifndef CYGWIN -#include <sys/types.h> /* For pid_t (fork) */ +#include <sys/types.h> /* For pid_t (fork) */ #ifdef HAVE_UNISTD_H -#include <unistd.h> /* For fork and execv */ +#include <unistd.h> /* For fork and execv */ #endif #endif /* !CYGWIN */ t@@ -49,10 +51,10 @@ #define PANED_STARTPOS 200 -HICON mainIcon=NULL; -static WNDPROC customWndProc=NULL; +HICON mainIcon = NULL; +static WNDPROC customWndProc = NULL; -static guint RecurseLevel=0; +static guint RecurseLevel = 0; static const gchar *WC_GTKSEP = "WC_GTKSEP"; static const gchar *WC_GTKVPANED = "WC_GTKVPANED"; t@@ -81,27 +83,32 @@ static void gtk_radio_button_toggled(GtkRadioButton *radio_button, static void gtk_container_destroy(GtkWidget *widget); static void gtk_container_size_request(GtkWidget *widget, GtkRequisition *requisition); -static void gtk_container_set_size(GtkWidget *widget,GtkAllocation *allocation); -static void gtk_container_show_all(GtkWidget *widget,gboolean hWndOnly); +static void gtk_container_set_size(GtkWidget *widget, + GtkAllocation *allocation); +static void gtk_container_show_all(GtkWidget *widget, gboolean hWndOnly); static void gtk_window_size_request(GtkWidget *widget, GtkRequisition *requisition); -static void gtk_window_set_size(GtkWidget *widget,GtkAllocation *allocation); +static void gtk_window_set_size(GtkWidget *widget, + GtkAllocation *allocation); static void gtk_window_destroy(GtkWidget *widget); -static void gtk_window_set_menu(GtkWindow *window,GtkMenuBar *menu_bar); -static GtkWidget *gtk_window_get_menu_ID(GtkWindow *window,gint ID); +static void gtk_window_set_menu(GtkWindow *window, GtkMenuBar *menu_bar); +static GtkWidget *gtk_window_get_menu_ID(GtkWindow *window, gint ID); static void gtk_table_destroy(GtkWidget *widget); static void gtk_table_size_request(GtkWidget *widget, GtkRequisition *requisition); -static void gtk_table_set_size(GtkWidget *widget,GtkAllocation *allocation); +static void gtk_table_set_size(GtkWidget *widget, + GtkAllocation *allocation); static void gtk_table_realize(GtkWidget *widget); static void gtk_box_destroy(GtkWidget *widget); static void gtk_hbox_size_request(GtkWidget *widget, GtkRequisition *requisition); -static void gtk_hbox_set_size(GtkWidget *widget,GtkAllocation *allocation); +static void gtk_hbox_set_size(GtkWidget *widget, + GtkAllocation *allocation); static void gtk_vbox_size_request(GtkWidget *widget, GtkRequisition *requisition); -static void gtk_vbox_set_size(GtkWidget *widget,GtkAllocation *allocation); -static gint gtk_window_delete_event(GtkWidget *widget,GdkEvent *event); +static void gtk_vbox_set_size(GtkWidget *widget, + GtkAllocation *allocation); +static gint gtk_window_delete_event(GtkWidget *widget, GdkEvent *event); static void gtk_window_realize(GtkWidget *widget); static void gtk_window_show(GtkWidget *widget); static void gtk_window_hide(GtkWidget *widget); t@@ -127,43 +134,45 @@ static void gtk_label_realize(GtkWidget *widget); static void gtk_url_realize(GtkWidget *widget); static void gtk_frame_size_request(GtkWidget *widget, GtkRequisition *requisition); -static void gtk_frame_set_size(GtkWidget *widget,GtkAllocation *allocation); +static void gtk_frame_set_size(GtkWidget *widget, + GtkAllocation *allocation); static void gtk_frame_destroy(GtkWidget *widget); static void gtk_frame_realize(GtkWidget *widget); static void gtk_clist_size_request(GtkWidget *widget, GtkRequisition *requisition); -static void gtk_clist_set_size(GtkWidget *widget,GtkAllocation *allocation); +static void gtk_clist_set_size(GtkWidget *widget, + GtkAllocation *allocation); static void gtk_clist_realize(GtkWidget *widget); static void gtk_clist_show(GtkWidget *widget); static void gtk_clist_hide(GtkWidget *widget); -static void gtk_clist_draw_row(GtkCList *clist,LPDRAWITEMSTRUCT lpdis); -static void gtk_box_show_all(GtkWidget *widget,gboolean hWndOnly); -static void gtk_table_show_all(GtkWidget *widget,gboolean hWndOnly); -static void gtk_widget_show_all_full(GtkWidget *widget,gboolean hWndOnly); -static void gtk_widget_show_full(GtkWidget *widget,gboolean recurse); -static void gtk_widget_update(GtkWidget *widget,gboolean ForceResize); -static void gtk_container_hide_all(GtkWidget *widget,gboolean hWndOnly); -static void gtk_box_hide_all(GtkWidget *widget,gboolean hWndOnly); -static void gtk_table_hide_all(GtkWidget *widget,gboolean hWndOnly); -static void gtk_widget_hide_all_full(GtkWidget *widget,gboolean hWndOnly); -static void gtk_widget_hide_full(GtkWidget *widget,gboolean recurse); - -static void gtk_marshal_BOOL__GPOIN(GtkObject *object,GSList *actions, +static void gtk_clist_draw_row(GtkCList *clist, LPDRAWITEMSTRUCT lpdis); +static void gtk_box_show_all(GtkWidget *widget, gboolean hWndOnly); +static void gtk_table_show_all(GtkWidget *widget, gboolean hWndOnly); +static void gtk_widget_show_all_full(GtkWidget *widget, gboolean hWndOnly); +static void gtk_widget_show_full(GtkWidget *widget, gboolean recurse); +static void gtk_widget_update(GtkWidget *widget, gboolean ForceResize); +static void gtk_container_hide_all(GtkWidget *widget, gboolean hWndOnly); +static void gtk_box_hide_all(GtkWidget *widget, gboolean hWndOnly); +static void gtk_table_hide_all(GtkWidget *widget, gboolean hWndOnly); +static void gtk_widget_hide_all_full(GtkWidget *widget, gboolean hWndOnly); +static void gtk_widget_hide_full(GtkWidget *widget, gboolean recurse); + +static void gtk_marshal_BOOL__GPOIN(GtkObject *object, GSList *actions, GtkSignalFunc default_action, va_list args); -static void gtk_marshal_BOOL__GINT(GtkObject *object,GSList *actions, +static void gtk_marshal_BOOL__GINT(GtkObject *object, GSList *actions, GtkSignalFunc default_action, va_list args); -static void gtk_marshal_VOID__VOID(GtkObject *object,GSList *actions, +static void gtk_marshal_VOID__VOID(GtkObject *object, GSList *actions, GtkSignalFunc default_action, va_list args); -static void gtk_marshal_VOID__BOOL(GtkObject *object,GSList *actions, +static void gtk_marshal_VOID__BOOL(GtkObject *object, GSList *actions, GtkSignalFunc default_action, va_list args); -static void gtk_marshal_VOID__GPOIN(GtkObject *object,GSList *actions, +static void gtk_marshal_VOID__GPOIN(GtkObject *object, GSList *actions, GtkSignalFunc default_action, va_list args); -static void gtk_marshal_VOID__GINT(GtkObject *object,GSList *actions, +static void gtk_marshal_VOID__GINT(GtkObject *object, GSList *actions, GtkSignalFunc default_action, va_list args); static void gtk_menu_bar_realize(GtkWidget *widget); t@@ -172,7 +181,8 @@ static void gtk_menu_item_enable(GtkWidget *widget); static void gtk_menu_item_disable(GtkWidget *widget); static void gtk_menu_realize(GtkWidget *widget); static void gtk_menu_shell_realize(GtkWidget *widget); -static GtkWidget *gtk_menu_shell_get_menu_ID(GtkMenuShell *menu_shell,gint ID); +static GtkWidget *gtk_menu_shell_get_menu_ID(GtkMenuShell *menu_shell, + gint ID); static void gtk_widget_create(GtkWidget *widget); static void gtk_notebook_realize(GtkWidget *widget); static void gtk_notebook_destroy(GtkWidget *widget); t@@ -180,8 +190,8 @@ static void gtk_notebook_set_size(GtkWidget *widget, GtkAllocation *allocation); static void gtk_notebook_size_request(GtkWidget *widget, GtkRequisition *requisition); -static void gtk_notebook_show_all(GtkWidget *widget,gboolean hWndOnly); -static void gtk_notebook_hide_all(GtkWidget *widget,gboolean hWndOnly); +static void gtk_notebook_show_all(GtkWidget *widget, gboolean hWndOnly); +static void gtk_notebook_hide_all(GtkWidget *widget, gboolean hWndOnly); static void gtk_spin_button_size_request(GtkWidget *widget, GtkRequisition *requisition); static void gtk_spin_button_set_size(GtkWidget *widget, t@@ -193,8 +203,8 @@ static void gtk_spin_button_hide(GtkWidget *widget); static void gtk_separator_size_request(GtkWidget *widget, GtkRequisition *requisition); static void gtk_separator_realize(GtkWidget *widget); -static void gtk_paned_show_all(GtkWidget *widget,gboolean hWndOnly); -static void gtk_paned_hide_all(GtkWidget *widget,gboolean hWndOnly); +static void gtk_paned_show_all(GtkWidget *widget, gboolean hWndOnly); +static void gtk_paned_hide_all(GtkWidget *widget, gboolean hWndOnly); static void gtk_paned_realize(GtkWidget *widget); static void gtk_vpaned_realize(GtkWidget *widget); static void gtk_hpaned_realize(GtkWidget *widget); t@@ -202,23 +212,26 @@ static void gtk_vpaned_size_request(GtkWidget *widget, GtkRequisition *requisition); static void gtk_hpaned_size_request(GtkWidget *widget, GtkRequisition *requisition); -static void gtk_vpaned_set_size(GtkWidget *widget,GtkAllocation *allocation); -static void gtk_hpaned_set_size(GtkWidget *widget,GtkAllocation *allocation); +static void gtk_vpaned_set_size(GtkWidget *widget, + GtkAllocation *allocation); +static void gtk_hpaned_set_size(GtkWidget *widget, + GtkAllocation *allocation); static void gtk_option_menu_size_request(GtkWidget *widget, GtkRequisition *requisition); static void gtk_option_menu_set_size(GtkWidget *widget, GtkAllocation *allocation); static void gtk_option_menu_realize(GtkWidget *widget); static void gtk_clist_update_selection(GtkWidget *widget); -static void gtk_button_set_text(GtkButton *button,gchar *text); -static void gtk_menu_item_set_text(GtkMenuItem *menuitem,gchar *text); +static void gtk_button_set_text(GtkButton *button, gchar *text); +static void gtk_menu_item_set_text(GtkMenuItem *menuitem, gchar *text); static void gtk_editable_create(GtkWidget *widget); static void gtk_option_menu_update_selection(GtkWidget *widget); -static void gtk_clist_update_widths(GtkCList *clist,gchar *text[]); +static void gtk_clist_update_widths(GtkCList *clist, gchar *text[]); static void gtk_clist_update_all_widths(GtkCList *clist); static void gtk_clist_do_auto_resize(GtkCList *clist); -static void gtk_clist_set_column_width_full(GtkCList *clist,gint column, - gint width,gboolean ResizeHeader); +static void gtk_clist_set_column_width_full(GtkCList *clist, gint column, + gint width, + gboolean ResizeHeader); static void gtk_widget_set_focus(GtkWidget *widget); static void gtk_widget_lose_focus(GtkWidget *widget); static void gtk_window_update_focus(GtkWindow *window); t@@ -234,202 +247,205 @@ static void gtk_window_set_initial_position(GtkWindow *window, static void gtk_progress_bar_size_request(GtkWidget *widget, GtkRequisition *requisition); static void gtk_progress_bar_realize(GtkWidget *widget); -static gint gtk_accel_group_add(GtkAccelGroup *accel_group,ACCEL *newaccel); -static void gtk_accel_group_set_id(GtkAccelGroup *accel_group,gint ind,gint ID); +static gint gtk_accel_group_add(GtkAccelGroup *accel_group, + ACCEL *newaccel); +static void gtk_accel_group_set_id(GtkAccelGroup *accel_group, gint ind, + gint ID); static void EnableParent(GtkWindow *window); typedef struct _GdkInput GdkInput; struct _GdkInput { - gint source; - GdkInputCondition condition; - GdkInputFunction function; - gpointer data; + gint source; + GdkInputCondition condition; + GdkInputFunction function; + gpointer data; }; typedef struct _GtkTimeout GtkTimeout; struct _GtkTimeout { - guint32 interval; - GtkFunction function; - gpointer data; - guint id; + guint32 interval; + GtkFunction function; + gpointer data; + guint id; }; typedef struct _GtkItemFactoryChild GtkItemFactoryChild; struct _GtkItemFactoryChild { - gchar *path; - GtkWidget *widget; + gchar *path; + GtkWidget *widget; }; static GtkSignalType GtkObjectSignals[] = { - { "create",gtk_marshal_VOID__VOID,NULL }, - { "",NULL,NULL } + {"create", gtk_marshal_VOID__VOID, NULL}, + {"", NULL, NULL} }; static GtkClass GtkObjectClass = { - "object",NULL,sizeof(GtkObject),GtkObjectSignals + "object", NULL, sizeof(GtkObject), GtkObjectSignals }; static GtkClass GtkAdjustmentClass = { - "adjustment",&GtkObjectClass,sizeof(GtkAdjustment),NULL + "adjustment", &GtkObjectClass, sizeof(GtkAdjustment), NULL }; static GtkClass GtkItemFactoryClass = { - "itemfactory",&GtkObjectClass,sizeof(GtkItemFactory),NULL + "itemfactory", &GtkObjectClass, sizeof(GtkItemFactory), NULL }; static GtkSignalType GtkWidgetSignals[] = { - { "create",gtk_marshal_VOID__VOID,gtk_widget_create }, - { "size_request",gtk_marshal_VOID__GPOIN,NULL }, - { "set_size",gtk_marshal_VOID__GPOIN,NULL }, - { "realize",gtk_marshal_VOID__VOID,NULL }, - { "destroy",gtk_marshal_VOID__VOID,NULL }, - { "show",gtk_marshal_VOID__VOID,NULL }, - { "hide",gtk_marshal_VOID__VOID,NULL }, - { "show_all",gtk_marshal_VOID__BOOL,NULL }, - { "hide_all",gtk_marshal_VOID__BOOL,NULL }, - { "enable",gtk_marshal_VOID__VOID,NULL }, - { "disable",gtk_marshal_VOID__VOID,NULL }, - { "",NULL,NULL } + {"create", gtk_marshal_VOID__VOID, gtk_widget_create}, + {"size_request", gtk_marshal_VOID__GPOIN, NULL}, + {"set_size", gtk_marshal_VOID__GPOIN, NULL}, + {"realize", gtk_marshal_VOID__VOID, NULL}, + {"destroy", gtk_marshal_VOID__VOID, NULL}, + {"show", gtk_marshal_VOID__VOID, NULL}, + {"hide", gtk_marshal_VOID__VOID, NULL}, + {"show_all", gtk_marshal_VOID__BOOL, NULL}, + {"hide_all", gtk_marshal_VOID__BOOL, NULL}, + {"enable", gtk_marshal_VOID__VOID, NULL}, + {"disable", gtk_marshal_VOID__VOID, NULL}, + {"", NULL, NULL} }; static GtkClass GtkWidgetClass = { - "widget",&GtkObjectClass,sizeof(GtkWidget),GtkWidgetSignals + "widget", &GtkObjectClass, sizeof(GtkWidget), GtkWidgetSignals }; static GtkSignalType GtkSeparatorSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_separator_size_request }, - { "realize",gtk_marshal_VOID__VOID,gtk_separator_realize }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_separator_size_request}, + {"realize", gtk_marshal_VOID__VOID, gtk_separator_realize}, + {"", NULL, NULL} }; static GtkClass GtkMiscClass = { - "misc",&GtkWidgetClass,sizeof(GtkMisc),NULL + "misc", &GtkWidgetClass, sizeof(GtkMisc), NULL }; static GtkSignalType GtkProgressBarSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_progress_bar_size_request }, - { "realize",gtk_marshal_VOID__VOID,gtk_progress_bar_realize }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_progress_bar_size_request}, + {"realize", gtk_marshal_VOID__VOID, gtk_progress_bar_realize}, + {"", NULL, NULL} }; static GtkClass GtkProgressBarClass = { - "progressbar",&GtkWidgetClass,sizeof(GtkProgressBar),GtkProgressBarSignals + "progressbar", &GtkWidgetClass, sizeof(GtkProgressBar), + GtkProgressBarSignals }; static GtkClass GtkSeparatorClass = { - "separator",&GtkWidgetClass,sizeof(GtkSeparator),GtkSeparatorSignals + "separator", &GtkWidgetClass, sizeof(GtkSeparator), GtkSeparatorSignals }; static GtkClass GtkHSeparatorClass = { - "hseparator",&GtkSeparatorClass,sizeof(GtkHSeparator),NULL + "hseparator", &GtkSeparatorClass, sizeof(GtkHSeparator), NULL }; static GtkClass GtkVSeparatorClass = { - "vseparator",&GtkSeparatorClass,sizeof(GtkVSeparator),NULL + "vseparator", &GtkSeparatorClass, sizeof(GtkVSeparator), NULL }; static GtkClass GtkMenuShellClass = { - "menushell",&GtkWidgetClass,sizeof(GtkMenuShell),NULL + "menushell", &GtkWidgetClass, sizeof(GtkMenuShell), NULL }; static GtkSignalType GtkMenuBarSignals[] = { - { "realize",gtk_marshal_VOID__VOID,gtk_menu_bar_realize }, - { "",NULL,NULL } + {"realize", gtk_marshal_VOID__VOID, gtk_menu_bar_realize}, + {"", NULL, NULL} }; static GtkClass GtkMenuBarClass = { - "menubar",&GtkMenuShellClass,sizeof(GtkMenuBar),GtkMenuBarSignals + "menubar", &GtkMenuShellClass, sizeof(GtkMenuBar), GtkMenuBarSignals }; static GtkSignalType GtkMenuItemSignals[] = { - { "realize",gtk_marshal_VOID__VOID,gtk_menu_item_realize }, - { "set_text",gtk_marshal_VOID__GPOIN,gtk_menu_item_set_text }, - { "activate",gtk_marshal_VOID__VOID,NULL }, - { "enable",gtk_marshal_VOID__VOID,gtk_menu_item_enable }, - { "disable",gtk_marshal_VOID__VOID,gtk_menu_item_disable }, - { "",NULL,NULL } + {"realize", gtk_marshal_VOID__VOID, gtk_menu_item_realize}, + {"set_text", gtk_marshal_VOID__GPOIN, gtk_menu_item_set_text}, + {"activate", gtk_marshal_VOID__VOID, NULL}, + {"enable", gtk_marshal_VOID__VOID, gtk_menu_item_enable}, + {"disable", gtk_marshal_VOID__VOID, gtk_menu_item_disable}, + {"", NULL, NULL} }; static GtkClass GtkMenuItemClass = { - "menuitem",&GtkWidgetClass,sizeof(GtkMenuItem),GtkMenuItemSignals + "menuitem", &GtkWidgetClass, sizeof(GtkMenuItem), GtkMenuItemSignals }; static GtkSignalType GtkMenuSignals[] = { - { "realize",gtk_marshal_VOID__VOID,gtk_menu_realize }, - { "",NULL,NULL } + {"realize", gtk_marshal_VOID__VOID, gtk_menu_realize}, + {"", NULL, NULL} }; static GtkClass GtkMenuClass = { - "menu",&GtkMenuShellClass,sizeof(GtkMenu),GtkMenuSignals + "menu", &GtkMenuShellClass, sizeof(GtkMenu), GtkMenuSignals }; static GtkSignalType GtkEditableSignals[] = { - { "create",gtk_marshal_VOID__VOID,gtk_editable_create }, - { "activate",gtk_marshal_VOID__VOID,NULL }, - { "",NULL,NULL } + {"create", gtk_marshal_VOID__VOID, gtk_editable_create}, + {"activate", gtk_marshal_VOID__VOID, NULL}, + {"", NULL, NULL} }; static GtkClass GtkEditableClass = { - "editable",&GtkWidgetClass,sizeof(GtkEditable),GtkEditableSignals + "editable", &GtkWidgetClass, sizeof(GtkEditable), GtkEditableSignals }; static GtkSignalType GtkEntrySignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_entry_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_entry_set_size }, - { "realize",gtk_marshal_VOID__VOID,gtk_entry_realize }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_entry_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_entry_set_size}, + {"realize", gtk_marshal_VOID__VOID, gtk_entry_realize}, + {"", NULL, NULL} }; static GtkClass GtkEntryClass = { - "entry",&GtkEditableClass,sizeof(GtkEntry),GtkEntrySignals + "entry", &GtkEditableClass, sizeof(GtkEntry), GtkEntrySignals }; static GtkSignalType GtkSpinButtonSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_spin_button_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_spin_button_set_size }, - { "realize",gtk_marshal_VOID__VOID,gtk_spin_button_realize }, - { "destroy",gtk_marshal_VOID__VOID,gtk_spin_button_destroy }, - { "hide",gtk_marshal_VOID__VOID,gtk_spin_button_hide }, - { "show",gtk_marshal_VOID__VOID,gtk_spin_button_show }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_spin_button_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_spin_button_set_size}, + {"realize", gtk_marshal_VOID__VOID, gtk_spin_button_realize}, + {"destroy", gtk_marshal_VOID__VOID, gtk_spin_button_destroy}, + {"hide", gtk_marshal_VOID__VOID, gtk_spin_button_hide}, + {"show", gtk_marshal_VOID__VOID, gtk_spin_button_show}, + {"", NULL, NULL} }; static GtkClass GtkSpinButtonClass = { - "spinbutton",&GtkEntryClass,sizeof(GtkSpinButton),GtkSpinButtonSignals + "spinbutton", &GtkEntryClass, sizeof(GtkSpinButton), GtkSpinButtonSignals }; static GtkSignalType GtkTextSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_text_size_request }, - { "realize",gtk_marshal_VOID__VOID,gtk_text_realize }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_text_size_request}, + {"realize", gtk_marshal_VOID__VOID, gtk_text_realize}, + {"", NULL, NULL} }; static GtkClass GtkTextClass = { - "text",&GtkEditableClass,sizeof(GtkText),GtkTextSignals + "text", &GtkEditableClass, sizeof(GtkText), GtkTextSignals }; static GtkSignalType GtkLabelSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_label_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_label_set_size }, - { "set_text",gtk_marshal_VOID__GPOIN,gtk_label_set_text }, - { "realize",gtk_marshal_VOID__VOID,gtk_label_realize }, - { "destroy",gtk_marshal_VOID__VOID,gtk_label_destroy }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_label_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_label_set_size}, + {"set_text", gtk_marshal_VOID__GPOIN, gtk_label_set_text}, + {"realize", gtk_marshal_VOID__VOID, gtk_label_realize}, + {"destroy", gtk_marshal_VOID__VOID, gtk_label_destroy}, + {"", NULL, NULL} }; static GtkClass GtkLabelClass = { - "label",&GtkWidgetClass,sizeof(GtkLabel),GtkLabelSignals + "label", &GtkWidgetClass, sizeof(GtkLabel), GtkLabelSignals }; static GtkSignalType GtkUrlSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_url_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_label_set_size }, - { "realize",gtk_marshal_VOID__VOID,gtk_url_realize }, - { "destroy",gtk_marshal_VOID__VOID,gtk_url_destroy }, - { "", NULL, NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_url_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_label_set_size}, + {"realize", gtk_marshal_VOID__VOID, gtk_url_realize}, + {"destroy", gtk_marshal_VOID__VOID, gtk_url_destroy}, + {"", NULL, NULL} }; static GtkClass GtkUrlClass = { t@@ -437,382 +453,410 @@ static GtkClass GtkUrlClass = { }; static GtkSignalType GtkButtonSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_button_size_request }, - { "set_text",gtk_marshal_VOID__GPOIN,gtk_button_set_text }, - { "realize",gtk_marshal_VOID__VOID,gtk_button_realize }, - { "destroy",gtk_marshal_VOID__VOID,gtk_button_destroy }, - { "clicked",gtk_marshal_VOID__VOID,NULL }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_button_size_request}, + {"set_text", gtk_marshal_VOID__GPOIN, gtk_button_set_text}, + {"realize", gtk_marshal_VOID__VOID, gtk_button_realize}, + {"destroy", gtk_marshal_VOID__VOID, gtk_button_destroy}, + {"clicked", gtk_marshal_VOID__VOID, NULL}, + {"", NULL, NULL} }; static GtkClass GtkButtonClass = { - "button",&GtkWidgetClass,sizeof(GtkButton),GtkButtonSignals + "button", &GtkWidgetClass, sizeof(GtkButton), GtkButtonSignals }; static GtkSignalType GtkOptionMenuSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_option_menu_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_option_menu_set_size }, - { "realize",gtk_marshal_VOID__VOID,gtk_option_menu_realize }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_option_menu_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_option_menu_set_size}, + {"realize", gtk_marshal_VOID__VOID, gtk_option_menu_realize}, + {"", NULL, NULL} }; static GtkClass GtkOptionMenuClass = { - "optionmenu",&GtkButtonClass,sizeof(GtkOptionMenu),GtkOptionMenuSignals + "optionmenu", &GtkButtonClass, sizeof(GtkOptionMenu), + GtkOptionMenuSignals }; static GtkSignalType GtkToggleButtonSignals[] = { - { "toggled",gtk_marshal_VOID__VOID,NULL }, - { "",NULL,NULL } + {"toggled", gtk_marshal_VOID__VOID, NULL}, + {"", NULL, NULL} }; static GtkClass GtkToggleButtonClass = { - "toggle",&GtkButtonClass,sizeof(GtkToggleButton),GtkToggleButtonSignals + "toggle", &GtkButtonClass, sizeof(GtkToggleButton), + GtkToggleButtonSignals }; static GtkSignalType GtkCheckButtonSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_check_button_size_request }, - { "realize",gtk_marshal_VOID__VOID,gtk_check_button_realize }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_check_button_size_request}, + {"realize", gtk_marshal_VOID__VOID, gtk_check_button_realize}, + {"", NULL, NULL} }; static GtkClass GtkCheckButtonClass = { - "check",&GtkToggleButtonClass,sizeof(GtkCheckButton),GtkCheckButtonSignals + "check", &GtkToggleButtonClass, sizeof(GtkCheckButton), + GtkCheckButtonSignals }; static GtkSignalType GtkRadioButtonSignals[] = { - { "realize",gtk_marshal_VOID__VOID,gtk_radio_button_realize }, - { "destroy",gtk_marshal_VOID__VOID,gtk_radio_button_destroy }, - { "",NULL,NULL } + {"realize", gtk_marshal_VOID__VOID, gtk_radio_button_realize}, + {"destroy", gtk_marshal_VOID__VOID, gtk_radio_button_destroy}, + {"", NULL, NULL} }; static GtkClass GtkRadioButtonClass = { - "radio",&GtkCheckButtonClass,sizeof(GtkRadioButton),GtkRadioButtonSignals + "radio", &GtkCheckButtonClass, sizeof(GtkRadioButton), + GtkRadioButtonSignals }; static GtkSignalType GtkContainerSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_container_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_container_set_size }, - { "realize",gtk_marshal_VOID__VOID,gtk_container_realize }, - { "destroy",gtk_marshal_VOID__VOID,gtk_container_destroy }, - { "show_all",gtk_marshal_VOID__BOOL,gtk_container_show_all }, - { "hide_all",gtk_marshal_VOID__BOOL,gtk_container_hide_all }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_container_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_container_set_size}, + {"realize", gtk_marshal_VOID__VOID, gtk_container_realize}, + {"destroy", gtk_marshal_VOID__VOID, gtk_container_destroy}, + {"show_all", gtk_marshal_VOID__BOOL, gtk_container_show_all}, + {"hide_all", gtk_marshal_VOID__BOOL, gtk_container_hide_all}, + {"", NULL, NULL} }; static GtkClass GtkContainerClass = { - "container",&GtkWidgetClass,sizeof(GtkContainer),GtkContainerSignals + "container", &GtkWidgetClass, sizeof(GtkContainer), GtkContainerSignals }; static GtkSignalType GtkPanedSignals[] = { - { "show_all",gtk_marshal_VOID__BOOL,gtk_paned_show_all }, - { "hide_all",gtk_marshal_VOID__BOOL,gtk_paned_hide_all }, - { "",NULL,NULL } + {"show_all", gtk_marshal_VOID__BOOL, gtk_paned_show_all}, + {"hide_all", gtk_marshal_VOID__BOOL, gtk_paned_hide_all}, + {"", NULL, NULL} }; + static GtkClass GtkPanedClass = { - "paned",&GtkContainerClass,sizeof(GtkPaned),GtkPanedSignals + "paned", &GtkContainerClass, sizeof(GtkPaned), GtkPanedSignals }; static GtkSignalType GtkVPanedSignals[] = { - { "realize",gtk_marshal_VOID__VOID,gtk_vpaned_realize }, - { "size_request",gtk_marshal_VOID__GPOIN,gtk_vpaned_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_vpaned_set_size }, - { "",NULL,NULL } + {"realize", gtk_marshal_VOID__VOID, gtk_vpaned_realize}, + {"size_request", gtk_marshal_VOID__GPOIN, gtk_vpaned_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_vpaned_set_size}, + {"", NULL, NULL} }; static GtkClass GtkVPanedClass = { - "vpaned",&GtkPanedClass,sizeof(GtkVPaned),GtkVPanedSignals + "vpaned", &GtkPanedClass, sizeof(GtkVPaned), GtkVPanedSignals }; static GtkSignalType GtkHPanedSignals[] = { - { "realize",gtk_marshal_VOID__VOID,gtk_hpaned_realize }, - { "size_request",gtk_marshal_VOID__GPOIN,gtk_hpaned_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_hpaned_set_size }, - { "",NULL,NULL } + {"realize", gtk_marshal_VOID__VOID, gtk_hpaned_realize}, + {"size_request", gtk_marshal_VOID__GPOIN, gtk_hpaned_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_hpaned_set_size}, + {"", NULL, NULL} }; static GtkClass GtkHPanedClass = { - "hpaned",&GtkPanedClass,sizeof(GtkHPaned),GtkHPanedSignals + "hpaned", &GtkPanedClass, sizeof(GtkHPaned), GtkHPanedSignals }; static GtkSignalType GtkBoxSignals[] = { - { "realize",gtk_marshal_VOID__VOID,gtk_box_realize }, - { "destroy",gtk_marshal_VOID__VOID,gtk_box_destroy }, - { "show_all",gtk_marshal_VOID__BOOL,gtk_box_show_all }, - { "hide_all",gtk_marshal_VOID__BOOL,gtk_box_hide_all }, - { "",NULL,NULL } + {"realize", gtk_marshal_VOID__VOID, gtk_box_realize}, + {"destroy", gtk_marshal_VOID__VOID, gtk_box_destroy}, + {"show_all", gtk_marshal_VOID__BOOL, gtk_box_show_all}, + {"hide_all", gtk_marshal_VOID__BOOL, gtk_box_hide_all}, + {"", NULL, NULL} }; static GtkClass GtkBoxClass = { - "box",&GtkContainerClass,sizeof(GtkBox),GtkBoxSignals + "box", &GtkContainerClass, sizeof(GtkBox), GtkBoxSignals }; static GtkSignalType GtkNotebookSignals[] = { - { "realize",gtk_marshal_VOID__VOID,gtk_notebook_realize }, - { "destroy",gtk_marshal_VOID__VOID,gtk_notebook_destroy }, - { "size_request",gtk_marshal_VOID__GPOIN,gtk_notebook_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_notebook_set_size }, - { "show_all",gtk_marshal_VOID__BOOL,gtk_notebook_show_all }, - { "hide_all",gtk_marshal_VOID__BOOL,gtk_notebook_hide_all }, - { "",NULL,NULL } + {"realize", gtk_marshal_VOID__VOID, gtk_notebook_realize}, + {"destroy", gtk_marshal_VOID__VOID, gtk_notebook_destroy}, + {"size_request", gtk_marshal_VOID__GPOIN, gtk_notebook_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_notebook_set_size}, + {"show_all", gtk_marshal_VOID__BOOL, gtk_notebook_show_all}, + {"hide_all", gtk_marshal_VOID__BOOL, gtk_notebook_hide_all}, + {"", NULL, NULL} }; static GtkClass GtkNotebookClass = { - "notebook",&GtkContainerClass,sizeof(GtkNotebook),GtkNotebookSignals + "notebook", &GtkContainerClass, sizeof(GtkNotebook), GtkNotebookSignals }; static GtkSignalType GtkTableSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_table_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_table_set_size }, - { "realize",gtk_marshal_VOID__VOID,gtk_table_realize }, - { "destroy",gtk_marshal_VOID__VOID,gtk_table_destroy }, - { "show_all",gtk_marshal_VOID__BOOL,gtk_table_show_all }, - { "hide_all",gtk_marshal_VOID__BOOL,gtk_table_hide_all }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_table_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_table_set_size}, + {"realize", gtk_marshal_VOID__VOID, gtk_table_realize}, + {"destroy", gtk_marshal_VOID__VOID, gtk_table_destroy}, + {"show_all", gtk_marshal_VOID__BOOL, gtk_table_show_all}, + {"hide_all", gtk_marshal_VOID__BOOL, gtk_table_hide_all}, + {"", NULL, NULL} }; static GtkClass GtkTableClass = { - "table",&GtkContainerClass,sizeof(GtkTable),GtkTableSignals + "table", &GtkContainerClass, sizeof(GtkTable), GtkTableSignals }; static GtkSignalType GtkCListSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_clist_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_clist_set_size }, - { "realize",gtk_marshal_VOID__VOID,gtk_clist_realize }, - { "click-column",gtk_marshal_VOID__GINT,NULL }, - { "show",gtk_marshal_VOID__VOID,gtk_clist_show }, - { "hide",gtk_marshal_VOID__VOID,gtk_clist_hide }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_clist_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_clist_set_size}, + {"realize", gtk_marshal_VOID__VOID, gtk_clist_realize}, + {"click-column", gtk_marshal_VOID__GINT, NULL}, + {"show", gtk_marshal_VOID__VOID, gtk_clist_show}, + {"hide", gtk_marshal_VOID__VOID, gtk_clist_hide}, + {"", NULL, NULL} }; static GtkClass GtkCListClass = { - "clist",&GtkContainerClass,sizeof(GtkCList),GtkCListSignals + "clist", &GtkContainerClass, sizeof(GtkCList), GtkCListSignals }; static GtkSignalType GtkHBoxSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_hbox_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_hbox_set_size }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_hbox_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_hbox_set_size}, + {"", NULL, NULL} }; static GtkClass GtkHBoxClass = { - "hbox",&GtkBoxClass,sizeof(GtkHBox),GtkHBoxSignals + "hbox", &GtkBoxClass, sizeof(GtkHBox), GtkHBoxSignals }; static GtkSignalType GtkVBoxSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_vbox_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_vbox_set_size }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_vbox_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_vbox_set_size}, + {"", NULL, NULL} }; static GtkClass GtkVBoxClass = { - "vbox",&GtkBoxClass,sizeof(GtkVBox),GtkVBoxSignals + "vbox", &GtkBoxClass, sizeof(GtkVBox), GtkVBoxSignals }; static GtkClass GtkBinClass = { - "bin",&GtkContainerClass,sizeof(GtkBin),NULL + "bin", &GtkContainerClass, sizeof(GtkBin), NULL }; static GtkSignalType GtkFrameSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_frame_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_frame_set_size }, - { "realize",gtk_marshal_VOID__VOID,gtk_frame_realize }, - { "destroy",gtk_marshal_VOID__VOID,gtk_frame_destroy }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_frame_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_frame_set_size}, + {"realize", gtk_marshal_VOID__VOID, gtk_frame_realize}, + {"destroy", gtk_marshal_VOID__VOID, gtk_frame_destroy}, + {"", NULL, NULL} }; static GtkClass GtkFrameClass = { - "frame",&GtkBinClass,sizeof(GtkFrame),GtkFrameSignals + "frame", &GtkBinClass, sizeof(GtkFrame), GtkFrameSignals }; static GtkSignalType GtkWindowSignals[] = { - { "size_request",gtk_marshal_VOID__GPOIN,gtk_window_size_request }, - { "set_size",gtk_marshal_VOID__GPOIN,gtk_window_set_size }, - { "realize",gtk_marshal_VOID__VOID,gtk_window_realize }, - { "destroy",gtk_marshal_VOID__VOID,gtk_window_destroy }, - { "show",gtk_marshal_VOID__VOID,gtk_window_show }, - { "hide",gtk_marshal_VOID__VOID,gtk_window_hide }, - { "delete_event",gtk_marshal_BOOL__GPOIN, - GTK_SIGNAL_FUNC(gtk_window_delete_event) }, - { "",NULL,NULL } + {"size_request", gtk_marshal_VOID__GPOIN, gtk_window_size_request}, + {"set_size", gtk_marshal_VOID__GPOIN, gtk_window_set_size}, + {"realize", gtk_marshal_VOID__VOID, gtk_window_realize}, + {"destroy", gtk_marshal_VOID__VOID, gtk_window_destroy}, + {"show", gtk_marshal_VOID__VOID, gtk_window_show}, + {"hide", gtk_marshal_VOID__VOID, gtk_window_hide}, + {"delete_event", gtk_marshal_BOOL__GPOIN, + GTK_SIGNAL_FUNC(gtk_window_delete_event)}, + {"", NULL, NULL} }; static GtkClass GtkWindowClass = { - "window",&GtkBinClass,sizeof(GtkWindow),GtkWindowSignals + "window", &GtkBinClass, sizeof(GtkWindow), GtkWindowSignals }; -const GtkType GTK_TYPE_WINDOW=&GtkWindowClass; -const GtkType GTK_TYPE_MENU_BAR=&GtkMenuBarClass; +const GtkType GTK_TYPE_WINDOW = &GtkWindowClass; +const GtkType GTK_TYPE_MENU_BAR = &GtkMenuBarClass; static HINSTANCE hInst; static HFONT defFont, urlFont; -static GSList *WindowList=NULL; -static GSList *GdkInputs=NULL; -static GSList *GtkTimeouts=NULL; -static HWND TopLevel=NULL; +static GSList *WindowList = NULL; +static GSList *GdkInputs = NULL; +static GSList *GtkTimeouts = NULL; +static HWND TopLevel = NULL; -static WNDPROC wpOrigEntryProc,wpOrigTextProc; +static WNDPROC wpOrigEntryProc, wpOrigTextProc; -static void gtk_set_default_font(HWND hWnd) { - SendMessage(hWnd,WM_SETFONT,(WPARAM)defFont,MAKELPARAM(FALSE,0)); +static void gtk_set_default_font(HWND hWnd) +{ + SendMessage(hWnd, WM_SETFONT, (WPARAM)defFont, MAKELPARAM(FALSE, 0)); } -static GtkObject *GtkNewObject(GtkClass *klass) { - GtkObject *newObj; +static GtkObject *GtkNewObject(GtkClass *klass) +{ + GtkObject *newObj; + + newObj = g_malloc0(klass->Size); + newObj->klass = klass; + gtk_signal_emit(newObj, "create"); - newObj=g_malloc0(klass->Size); - newObj->klass=klass; - gtk_signal_emit(newObj,"create"); + return newObj; +} - return newObj; +static void DispatchSocketEvent(SOCKET sock, long event) +{ + GSList *list; + GdkInput *input; + + for (list = GdkInputs; list; list = g_slist_next(list)) { + input = (GdkInput *)(list->data); + if (input->source == sock) { + (*input->function) (input->data, input->source, + (event & (FD_READ | FD_CLOSE | FD_ACCEPT) ? + GDK_INPUT_READ : 0) | + (event & (FD_WRITE | FD_CONNECT) ? + GDK_INPUT_WRITE : 0)); + break; + } + } } -static void DispatchSocketEvent(SOCKET sock,long event) { - GSList *list; - GdkInput *input; - for (list=GdkInputs;list;list=g_slist_next(list)) { - input=(GdkInput *)(list->data); - if (input->source==sock) { - (*input->function)(input->data,input->source, - (event&(FD_READ|FD_CLOSE|FD_ACCEPT) ? GDK_INPUT_READ:0) | - (event&(FD_WRITE|FD_CONNECT) ? GDK_INPUT_WRITE:0)); - break; +static void DispatchTimeoutEvent(UINT id) +{ + GSList *list; + GtkTimeout *timeout; + + for (list = GtkTimeouts; list; list = g_slist_next(list)) { + timeout = (GtkTimeout *)list->data; + if (timeout->id == id) { + if (timeout->function) { + if (!(*timeout->function) (timeout->data)) { + gtk_timeout_remove(id); + } } - } -} - -static void DispatchTimeoutEvent(UINT id) { - GSList *list; - GtkTimeout *timeout; - for (list=GtkTimeouts;list;list=g_slist_next(list)) { - timeout=(GtkTimeout *)list->data; - if (timeout->id == id) { - if (timeout->function) { - if (!(*timeout->function)(timeout->data)) { - gtk_timeout_remove(id); - } - } - break; + break; + } + } +} + +static void UpdatePanedGhostRect(GtkPaned *paned, RECT *OldRect, + RECT *NewRect, gint x, gint y) +{ + HWND hWnd, parent; + RECT rect, clrect; + POINT MouseCoord; + HDC hDC; + GtkWidget *widget = GTK_WIDGET(paned); + + if (!OldRect && !NewRect) + return; + parent = gtk_get_parent_hwnd(widget); + hWnd = widget->hWnd; + if (!parent || !hWnd) + return; + + MouseCoord.x = x; + MouseCoord.y = y; + MapWindowPoints(hWnd, parent, &MouseCoord, 1); + + rect.left = paned->true_alloc.x; + rect.top = paned->true_alloc.y; + GetClientRect(hWnd, &clrect); + if (clrect.right > clrect.bottom) { + rect.right = paned->true_alloc.x + paned->true_alloc.width; + rect.bottom = MouseCoord.y; + } else { + rect.bottom = paned->true_alloc.y + paned->true_alloc.height; + rect.right = MouseCoord.x; + } + + if (OldRect && NewRect && OldRect->right == rect.right && + OldRect->bottom == rect.bottom) + return; + + hDC = GetDC(parent); + + if (OldRect) + DrawFocusRect(hDC, OldRect); + if (NewRect) { + CopyRect(NewRect, &rect); + DrawFocusRect(hDC, NewRect); + } + ReleaseDC(parent, hDC); +} + +LRESULT CALLBACK GtkPanedProc(HWND hwnd, UINT msg, UINT wParam, + LONG lParam) +{ + PAINTSTRUCT ps; + HPEN oldpen, dkpen, ltpen; + RECT rect; + static RECT GhostRect; + HDC hDC; + gint newpos; + GtkPaned *paned; + + paned = GTK_PANED(GetWindowLong(hwnd, GWL_USERDATA)); + switch (msg) { + case WM_PAINT: + if (GetUpdateRect(hwnd, NULL, TRUE)) { + BeginPaint(hwnd, &ps); + GetClientRect(hwnd, &rect); + hDC = ps.hdc; + ltpen = + CreatePen(PS_SOLID, 0, (COLORREF)GetSysColor(COLOR_3DHILIGHT)); + dkpen = + CreatePen(PS_SOLID, 0, (COLORREF)GetSysColor(COLOR_3DSHADOW)); + + if (rect.right > rect.bottom) { + oldpen = SelectObject(hDC, ltpen); + MoveToEx(hDC, rect.left, rect.top, NULL); + LineTo(hDC, rect.right, rect.top); + + SelectObject(hDC, dkpen); + MoveToEx(hDC, rect.left, rect.bottom - 1, NULL); + LineTo(hDC, rect.right, rect.bottom - 1); + } else { + oldpen = SelectObject(hDC, ltpen); + MoveToEx(hDC, rect.left, rect.top, NULL); + LineTo(hDC, rect.left, rect.bottom); + + SelectObject(hDC, ltpen); + MoveToEx(hDC, rect.right - 1, rect.top, NULL); + LineTo(hDC, rect.right - 1, rect.bottom); } - } -} - -static void UpdatePanedGhostRect(GtkPaned *paned,RECT *OldRect,RECT *NewRect, - gint x,gint y) { - HWND hWnd,parent; - RECT rect,clrect; - POINT MouseCoord; - HDC hDC; - GtkWidget *widget=GTK_WIDGET(paned); - - if (!OldRect && !NewRect) return; - parent=gtk_get_parent_hwnd(widget); - hWnd=widget->hWnd; - if (!parent || !hWnd) return; - - MouseCoord.x=x; - MouseCoord.y=y; - MapWindowPoints(hWnd,parent,&MouseCoord,1); - - rect.left=paned->true_alloc.x; - rect.top=paned->true_alloc.y; - GetClientRect(hWnd,&clrect); - if (clrect.right > clrect.bottom) { - rect.right=paned->true_alloc.x+paned->true_alloc.width; - rect.bottom=MouseCoord.y; - } else { - rect.bottom=paned->true_alloc.y+paned->true_alloc.height; - rect.right=MouseCoord.x; - } - - if (OldRect && NewRect && OldRect->right==rect.right && - OldRect->bottom==rect.bottom) return; - - hDC=GetDC(parent); - - if (OldRect) DrawFocusRect(hDC,OldRect); - if (NewRect) { - CopyRect(NewRect,&rect); - DrawFocusRect(hDC,NewRect); - } - ReleaseDC(parent,hDC); -} - -LRESULT CALLBACK GtkPanedProc(HWND hwnd,UINT msg,UINT wParam,LONG lParam) { - PAINTSTRUCT ps; - HPEN oldpen,dkpen,ltpen; - RECT rect; - static RECT GhostRect; - HDC hDC; - gint newpos; - GtkPaned *paned; - paned=GTK_PANED(GetWindowLong(hwnd,GWL_USERDATA)); - switch(msg) { - case WM_PAINT: - if (GetUpdateRect(hwnd,NULL,TRUE)) { - BeginPaint(hwnd,&ps); - GetClientRect(hwnd,&rect); - hDC=ps.hdc; - ltpen=CreatePen(PS_SOLID,0,(COLORREF)GetSysColor(COLOR_3DHILIGHT)); - dkpen=CreatePen(PS_SOLID,0,(COLORREF)GetSysColor(COLOR_3DSHADOW)); - - if (rect.right > rect.bottom) { - oldpen=SelectObject(hDC,ltpen); - MoveToEx(hDC,rect.left,rect.top,NULL); - LineTo(hDC,rect.right,rect.top); - - SelectObject(hDC,dkpen); - MoveToEx(hDC,rect.left,rect.bottom-1,NULL); - LineTo(hDC,rect.right,rect.bottom-1); - } else { - oldpen=SelectObject(hDC,ltpen); - MoveToEx(hDC,rect.left,rect.top,NULL); - LineTo(hDC,rect.left,rect.bottom); - - SelectObject(hDC,ltpen); - MoveToEx(hDC,rect.right-1,rect.top,NULL); - LineTo(hDC,rect.right-1,rect.bottom); - } - - SelectObject(hDC,oldpen); - DeleteObject(ltpen); DeleteObject(dkpen); - EndPaint(hwnd,&ps); - } - return TRUE; - case WM_LBUTTONDOWN: - if (!paned) break; - SetCapture(hwnd); - paned->Tracking=TRUE; - UpdatePanedGhostRect(paned,NULL,&GhostRect, - LOWORD(lParam),HIWORD(lParam)); - return TRUE; - case WM_MOUSEMOVE: - if (!paned||!paned->Tracking) break; - UpdatePanedGhostRect(paned,&GhostRect,&GhostRect, - LOWORD(lParam),HIWORD(lParam)); - return TRUE; - case WM_LBUTTONUP: - if (!paned||!paned->Tracking) break; - ReleaseCapture(); - paned->Tracking=FALSE; - UpdatePanedGhostRect(paned,&GhostRect,NULL, - LOWORD(lParam),HIWORD(lParam)); - GetClientRect(hwnd,&rect); - if (rect.right > rect.bottom) { - newpos=((gint16)HIWORD(lParam)+GTK_WIDGET(paned)->allocation.y- - paned->true_alloc.y)*100/paned->true_alloc.height; - } else { - newpos=((gint16)LOWORD(lParam)+GTK_WIDGET(paned)->allocation.x- - paned->true_alloc.x)*100/paned->true_alloc.width; - } - gtk_paned_set_position(paned,newpos); - return TRUE; - default: - return DefWindowProc(hwnd,msg,wParam,lParam); - } - return FALSE; -} - -LRESULT CALLBACK GtkUrlProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam) { + + SelectObject(hDC, oldpen); + DeleteObject(ltpen); + DeleteObject(dkpen); + EndPaint(hwnd, &ps); + } + return TRUE; + case WM_LBUTTONDOWN: + if (!paned) + break; + SetCapture(hwnd); + paned->Tracking = TRUE; + UpdatePanedGhostRect(paned, NULL, &GhostRect, + LOWORD(lParam), HIWORD(lParam)); + return TRUE; + case WM_MOUSEMOVE: + if (!paned || !paned->Tracking) + break; + UpdatePanedGhostRect(paned, &GhostRect, &GhostRect, + LOWORD(lParam), HIWORD(lParam)); + return TRUE; + case WM_LBUTTONUP: + if (!paned || !paned->Tracking) + break; + ReleaseCapture(); + paned->Tracking = FALSE; + UpdatePanedGhostRect(paned, &GhostRect, NULL, + LOWORD(lParam), HIWORD(lParam)); + GetClientRect(hwnd, &rect); + if (rect.right > rect.bottom) { + newpos = ((gint16)HIWORD(lParam) + GTK_WIDGET(paned)->allocation.y - + paned->true_alloc.y) * 100 / paned->true_alloc.height; + } else { + newpos = ((gint16)LOWORD(lParam) + GTK_WIDGET(paned)->allocation.x - + paned->true_alloc.x) * 100 / paned->true_alloc.width; + } + gtk_paned_set_position(paned, newpos); + return TRUE; + default: + return DefWindowProc(hwnd, msg, wParam, lParam); + } + return FALSE; +} + +LRESULT CALLBACK GtkUrlProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam) +{ GtkWidget *widget; if (msg == WM_PAINT) { t@@ -844,813 +888,925 @@ LRESULT CALLBACK GtkUrlProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam) { ShellExecute(hwnd, "open", target, NULL, NULL, 0); return FALSE; - } else return DefWindowProc(hwnd, msg, wParam, lParam); -} - -LRESULT CALLBACK GtkSepProc(HWND hwnd,UINT msg,UINT wParam,LONG lParam) { - PAINTSTRUCT ps; - HPEN oldpen,dkpen,ltpen; - RECT rect; - HDC hDC; - if (msg==WM_PAINT) { - if (GetUpdateRect(hwnd,NULL,TRUE)) { - BeginPaint(hwnd,&ps); - GetClientRect(hwnd,&rect); - hDC=ps.hdc; - ltpen=CreatePen(PS_SOLID,0,(COLORREF)GetSysColor(COLOR_3DHILIGHT)); - dkpen=CreatePen(PS_SOLID,0,(COLORREF)GetSysColor(COLOR_3DSHADOW)); - - if (rect.right > rect.bottom) { - oldpen=SelectObject(hDC,dkpen); - MoveToEx(hDC,rect.left,rect.top,NULL); - LineTo(hDC,rect.right,rect.top); - - SelectObject(hDC,ltpen); - MoveToEx(hDC,rect.left,rect.top+1,NULL); - LineTo(hDC,rect.right,rect.top+1); - } else { - oldpen=SelectObject(hDC,dkpen); - MoveToEx(hDC,rect.left,rect.top,NULL); - LineTo(hDC,rect.left,rect.bottom); - - SelectObject(hDC,ltpen); - MoveToEx(hDC,rect.left+1,rect.top,NULL); - LineTo(hDC,rect.left+1,rect.bottom); - } - - SelectObject(hDC,oldpen); - DeleteObject(ltpen); DeleteObject(dkpen); - EndPaint(hwnd,&ps); + } else + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +LRESULT CALLBACK GtkSepProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam) +{ + PAINTSTRUCT ps; + HPEN oldpen, dkpen, ltpen; + RECT rect; + HDC hDC; + + if (msg == WM_PAINT) { + if (GetUpdateRect(hwnd, NULL, TRUE)) { + BeginPaint(hwnd, &ps); + GetClientRect(hwnd, &rect); + hDC = ps.hdc; + ltpen = + CreatePen(PS_SOLID, 0, (COLORREF)GetSysColor(COLOR_3DHILIGHT)); + dkpen = + CreatePen(PS_SOLID, 0, (COLORREF)GetSysColor(COLOR_3DSHADOW)); + + if (rect.right > rect.bottom) { + oldpen = SelectObject(hDC, dkpen); + MoveToEx(hDC, rect.left, rect.top, NULL); + LineTo(hDC, rect.right, rect.top); + + SelectObject(hDC, ltpen); + MoveToEx(hDC, rect.left, rect.top + 1, NULL); + LineTo(hDC, rect.right, rect.top + 1); + } else { + oldpen = SelectObject(hDC, dkpen); + MoveToEx(hDC, rect.left, rect.top, NULL); + LineTo(hDC, rect.left, rect.bottom); + + SelectObject(hDC, ltpen); + MoveToEx(hDC, rect.left + 1, rect.top, NULL); + LineTo(hDC, rect.left + 1, rect.bottom); + } + + SelectObject(hDC, oldpen); + DeleteObject(ltpen); + DeleteObject(dkpen); + EndPaint(hwnd, &ps); + } + return TRUE; + } else + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam) +{ + GtkWidget *window, *widget; + GtkClass *klass; + RECT rect; + GtkAllocation alloc; + gboolean signal_return; + GdkEvent event = 0; + LPMEASUREITEMSTRUCT lpmis; + HDC hDC; + TEXTMETRIC tm; + LPDRAWITEMSTRUCT lpdis; + HD_NOTIFY FAR *phdr; + NMHDR *nmhdr; + + if (customWndProc + && CallWindowProc(customWndProc, hwnd, msg, wParam, lParam)) + return TRUE; + + switch (msg) { + case WM_SIZE: + window = GTK_WIDGET(GetWindowLong(hwnd, GWL_USERDATA)); + GetWindowRect(hwnd, &rect); + alloc.x = rect.left; + alloc.y = rect.top; + alloc.width = rect.right - rect.left; + alloc.height = rect.bottom - rect.top; + gtk_window_handle_user_size(GTK_WINDOW(window), &alloc); + gtk_widget_set_size(window, &alloc); + break; + case WM_GETMINMAXINFO: + widget = GTK_WIDGET(GetWindowLong(hwnd, GWL_USERDATA)); + if (widget) + klass = GTK_OBJECT(widget)->klass; + else + klass = NULL; + if (klass == &GtkWindowClass) { + gtk_window_handle_minmax_size(GTK_WINDOW(widget), + (LPMINMAXINFO)lParam); + } + break; + case WM_ACTIVATE: + case WM_ACTIVATEAPP: + widget = GTK_WIDGET(GetWindowLong(hwnd, GWL_USERDATA)); + if (widget) + klass = GTK_OBJECT(widget)->klass; + else + klass = NULL; + if (klass == &GtkWindowClass) { + if ((msg == WM_ACTIVATE && LOWORD(wParam) != WA_INACTIVE) + || (msg == WM_ACTIVATEAPP && wParam)) { + if (GTK_WINDOW(widget)->focus) { + gtk_widget_set_focus(GTK_WINDOW(widget)->focus); + } + if (!GTK_WINDOW(widget)->focus) { + gtk_window_set_focus(GTK_WINDOW(widget)); + } + } else if (msg == WM_ACTIVATE && LOWORD(wParam) == WA_INACTIVE) { + gtk_window_update_focus(GTK_WINDOW(widget)); } + } + break; + case WM_COMMAND: + widget = GTK_WIDGET(GetWindowLong((HWND)lParam, GWL_USERDATA)); + if (widget) + klass = GTK_OBJECT(widget)->klass; + else + klass = NULL; + + if (lParam && klass == &GtkCListClass + && HIWORD(wParam) == LBN_SELCHANGE) { + gtk_clist_update_selection(widget); + } else if (lParam && klass == &GtkOptionMenuClass && + HIWORD(wParam) == CBN_SELENDOK) { + gtk_option_menu_update_selection(widget); + } else if (lParam && HIWORD(wParam) == BN_CLICKED) { + gtk_signal_emit(GTK_OBJECT(widget), "clicked"); + } else if (HIWORD(wParam) == 0 || HIWORD(wParam) == 1) { + window = GTK_WIDGET(GetWindowLong(hwnd, GWL_USERDATA)); + widget = gtk_window_get_menu_ID(GTK_WINDOW(window), LOWORD(wParam)); + if (widget) + gtk_signal_emit(GTK_OBJECT(widget), "activate"); + } else + return TRUE; + break; + case WM_CLOSE: + gtk_signal_emit(GTK_OBJECT(GetWindowLong(hwnd, GWL_USERDATA)), + "delete_event", &event, &signal_return); + return TRUE; + break; + case WM_DRAWITEM: + lpdis = (LPDRAWITEMSTRUCT) lParam; + if (lpdis) { + gtk_clist_draw_row(GTK_CLIST(GetWindowLong(lpdis->hwndItem, + GWL_USERDATA)), lpdis); + return TRUE; + } + break; + case WM_MEASUREITEM: + lpmis = (LPMEASUREITEMSTRUCT)lParam; + hDC = GetDC(hwnd); + if (!GetTextMetrics(hDC, &tm)) + g_warning("GetTextMetrics failed"); + ReleaseDC(hwnd, hDC); + if (lpmis) { + lpmis->itemHeight = tm.tmHeight + LISTITEMVPACK * 2; return TRUE; - } else return DefWindowProc(hwnd,msg,wParam,lParam); -} - -LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,UINT wParam,LONG lParam) { - GtkWidget *window,*widget; - GtkClass *klass; - RECT rect; - GtkAllocation alloc; - gboolean signal_return; - GdkEvent event=0; - LPMEASUREITEMSTRUCT lpmis; - HDC hDC; - TEXTMETRIC tm; - LPDRAWITEMSTRUCT lpdis; - HD_NOTIFY FAR* phdr; - NMHDR *nmhdr; - if (customWndProc && - CallWindowProc(customWndProc,hwnd,msg,wParam,lParam)) return TRUE; - - switch(msg) { - case WM_SIZE: - window=GTK_WIDGET(GetWindowLong(hwnd,GWL_USERDATA)); - GetWindowRect(hwnd,&rect); - alloc.x=rect.left; alloc.y=rect.top; - alloc.width=rect.right-rect.left; - alloc.height=rect.bottom-rect.top; - gtk_window_handle_user_size(GTK_WINDOW(window),&alloc); - gtk_widget_set_size(window,&alloc); - break; - case WM_GETMINMAXINFO: - widget=GTK_WIDGET(GetWindowLong(hwnd,GWL_USERDATA)); - if (widget) klass=GTK_OBJECT(widget)->klass; else klass=NULL; - if (klass==&GtkWindowClass) { - gtk_window_handle_minmax_size(GTK_WINDOW(widget), - (LPMINMAXINFO)lParam); - } - break; - case WM_ACTIVATE: - case WM_ACTIVATEAPP: - widget=GTK_WIDGET(GetWindowLong(hwnd,GWL_USERDATA)); - if (widget) klass=GTK_OBJECT(widget)->klass; else klass=NULL; - if (klass==&GtkWindowClass) { - if ((msg==WM_ACTIVATE && LOWORD(wParam)!=WA_INACTIVE)|| - (msg==WM_ACTIVATEAPP && wParam)) { - if (GTK_WINDOW(widget)->focus) { - gtk_widget_set_focus(GTK_WINDOW(widget)->focus); - } - if (!GTK_WINDOW(widget)->focus) { - gtk_window_set_focus(GTK_WINDOW(widget)); - } - } else if (msg==WM_ACTIVATE && LOWORD(wParam)==WA_INACTIVE) { - gtk_window_update_focus(GTK_WINDOW(widget)); - } - } - break; - case WM_COMMAND: - widget=GTK_WIDGET(GetWindowLong((HWND)lParam,GWL_USERDATA)); - if (widget) klass=GTK_OBJECT(widget)->klass; else klass=NULL; - - if (lParam && klass==&GtkCListClass && HIWORD(wParam)==LBN_SELCHANGE) { - gtk_clist_update_selection(widget); - } else if (lParam && klass==&GtkOptionMenuClass && - HIWORD(wParam)==CBN_SELENDOK) { - gtk_option_menu_update_selection(widget); - } else if (lParam && HIWORD(wParam)==BN_CLICKED) { - gtk_signal_emit(GTK_OBJECT(widget),"clicked"); - } else if (HIWORD(wParam)==0 || HIWORD(wParam)==1) { - window=GTK_WIDGET(GetWindowLong(hwnd,GWL_USERDATA)); - widget=gtk_window_get_menu_ID(GTK_WINDOW(window),LOWORD(wParam)); - if (widget) gtk_signal_emit(GTK_OBJECT(widget),"activate"); - } else return TRUE; - break; - case WM_CLOSE: - gtk_signal_emit(GTK_OBJECT(GetWindowLong(hwnd,GWL_USERDATA)), - "delete_event",&event,&signal_return); - return TRUE; - break; - case WM_DRAWITEM: - lpdis=(LPDRAWITEMSTRUCT)lParam; - if (lpdis) { - gtk_clist_draw_row(GTK_CLIST(GetWindowLong(lpdis->hwndItem, - GWL_USERDATA)),lpdis); - return TRUE; - } - break; - case WM_MEASUREITEM: - lpmis=(LPMEASUREITEMSTRUCT)lParam; - hDC=GetDC(hwnd); - if (!GetTextMetrics(hDC,&tm)) g_warning("GetTextMetrics failed"); - ReleaseDC(hwnd,hDC); - if (lpmis) { - lpmis->itemHeight = tm.tmHeight + LISTITEMVPACK*2; - return TRUE; - } - break; - case WM_NOTIFY: - phdr=(HD_NOTIFY FAR *)lParam; - nmhdr=(NMHDR *)lParam; - if (!nmhdr) break; - if (nmhdr->code==HDN_ENDTRACK) { - gtk_clist_set_column_width_full( - GTK_CLIST(GetWindowLong(nmhdr->hwndFrom,GWL_USERDATA)), - phdr->iItem,phdr->pitem->cxy,FALSE); - return FALSE; - } else if (nmhdr->code==HDN_ITEMCLICK) { - gtk_signal_emit( - GTK_OBJECT(GetWindowLong(nmhdr->hwndFrom,GWL_USERDATA)), - "click-column",(gint)phdr->iItem); - return FALSE; - } else if (nmhdr->code==TCN_SELCHANGE) { - gtk_notebook_set_page( - GTK_NOTEBOOK(GetWindowLong(nmhdr->hwndFrom,GWL_USERDATA)), - TabCtrl_GetCurSel(nmhdr->hwndFrom)); - return FALSE; - } - break; - case MYWM_SOCKETDATA: -/* Ignore network messages if in recursive message loops, to avoid dodgy - race conditions */ - if (RecurseLevel<=1) { -/* Make any error available by the usual WSAGetLastError() mechanism */ - WSASetLastError(WSAGETSELECTERROR(lParam)); - DispatchSocketEvent((SOCKET)wParam,WSAGETSELECTEVENT(lParam)); - } - break; - case WM_TIMER: - DispatchTimeoutEvent((UINT)wParam); - return FALSE; - default: - return DefWindowProc(hwnd,msg,wParam,lParam); - } - return FALSE; -} - -LRESULT APIENTRY EntryWndProc(HWND hwnd,UINT msg,WPARAM wParam, - LPARAM lParam) { - GtkWidget *widget; - if (msg==WM_KEYUP && wParam==VK_RETURN) { - widget=GTK_WIDGET(GetWindowLong(hwnd,GWL_USERDATA)); - if (widget) gtk_signal_emit(GTK_OBJECT(widget),"activate"); + } + break; + case WM_NOTIFY: + phdr = (HD_NOTIFY FAR *)lParam; + nmhdr = (NMHDR *)lParam; + if (!nmhdr) + break; + if (nmhdr->code == HDN_ENDTRACK) { + gtk_clist_set_column_width_full(GTK_CLIST + (GetWindowLong + (nmhdr->hwndFrom, GWL_USERDATA)), + phdr->iItem, phdr->pitem->cxy, + FALSE); + return FALSE; + } else if (nmhdr->code == HDN_ITEMCLICK) { + gtk_signal_emit(GTK_OBJECT + (GetWindowLong(nmhdr->hwndFrom, GWL_USERDATA)), + "click-column", (gint)phdr->iItem); return FALSE; - } - return CallWindowProc(wpOrigEntryProc,hwnd,msg,wParam,lParam); + } else if (nmhdr->code == TCN_SELCHANGE) { + gtk_notebook_set_page(GTK_NOTEBOOK + (GetWindowLong(nmhdr->hwndFrom, GWL_USERDATA)), + TabCtrl_GetCurSel(nmhdr->hwndFrom)); + return FALSE; + } + break; + case MYWM_SOCKETDATA: + /* Ignore network messages if in recursive message loops, to avoid + * dodgy race conditions */ + if (RecurseLevel <= 1) { + /* Make any error available by the usual WSAGetLastError() mechanism + */ + WSASetLastError(WSAGETSELECTERROR(lParam)); + DispatchSocketEvent((SOCKET)wParam, WSAGETSELECTEVENT(lParam)); + } + break; + case WM_TIMER: + DispatchTimeoutEvent((UINT)wParam); + return FALSE; + default: + return DefWindowProc(hwnd, msg, wParam, lParam); + } + return FALSE; } -LRESULT APIENTRY TextWndProc(HWND hwnd,UINT msg,WPARAM wParam, - LPARAM lParam) { - GtkWidget *widget; - if (msg==WM_GETDLGCODE) { - widget=GTK_WIDGET(GetWindowLong(hwnd,GWL_USERDATA)); - if (!GTK_EDITABLE(widget)->is_editable) { - return DLGC_HASSETSEL|DLGC_WANTARROWS; - } - } - return CallWindowProc(wpOrigTextProc,hwnd,msg,wParam,lParam); +LRESULT APIENTRY EntryWndProc(HWND hwnd, UINT msg, WPARAM wParam, + LPARAM lParam) +{ + GtkWidget *widget; + + if (msg == WM_KEYUP && wParam == VK_RETURN) { + widget = GTK_WIDGET(GetWindowLong(hwnd, GWL_USERDATA)); + if (widget) + gtk_signal_emit(GTK_OBJECT(widget), "activate"); + return FALSE; + } + return CallWindowProc(wpOrigEntryProc, hwnd, msg, wParam, lParam); +} + +LRESULT APIENTRY TextWndProc(HWND hwnd, UINT msg, WPARAM wParam, + LPARAM lParam) +{ + GtkWidget *widget; + + if (msg == WM_GETDLGCODE) { + widget = GTK_WIDGET(GetWindowLong(hwnd, GWL_USERDATA)); + if (!GTK_EDITABLE(widget)->is_editable) { + return DLGC_HASSETSEL | DLGC_WANTARROWS; + } + } + return CallWindowProc(wpOrigTextProc, hwnd, msg, wParam, lParam); } -void SetCustomWndProc(WNDPROC wndproc) { +void SetCustomWndProc(WNDPROC wndproc) +{ customWndProc = wndproc; } -void win32_init(HINSTANCE hInstance,HINSTANCE hPrevInstance,char *MainIcon) { - WNDCLASS wc; - - hInst=hInstance; - defFont=(HFONT)GetStockObject(DEFAULT_GUI_FONT); - urlFont = CreateFont(14, 0, 0, 0, FW_SEMIBOLD, FALSE, TRUE, FALSE, - ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, - DEFAULT_QUALITY, FF_SWISS | DEFAULT_PITCH, NULL); - WindowList=NULL; - RecurseLevel=0; - customWndProc = NULL; - if (MainIcon) { - mainIcon = LoadIcon(hInstance,MainIcon); - } else { - mainIcon = LoadIcon(NULL,IDI_APPLICATION); - } - if (!hPrevInstance) { - wc.style = CS_HREDRAW|CS_VREDRAW; - wc.lpfnWndProc = MainWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = mainIcon; - wc.hCursor = LoadCursor(NULL,IDC_ARROW); - wc.hbrBackground = (HBRUSH)(1+COLOR_BTNFACE); - wc.lpszMenuName = NULL; - wc.lpszClassName = "mainwin"; - RegisterClass(&wc); - - wc.style = CS_HREDRAW|CS_VREDRAW; - wc.lpfnWndProc = MainWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = NULL; - wc.hCursor = LoadCursor(NULL,IDC_ARROW); - wc.hbrBackground = (HBRUSH)(1+COLOR_BTNFACE); - wc.lpszMenuName = NULL; - wc.lpszClassName = WC_GTKDIALOG; - RegisterClass(&wc); - - wc.style = CS_HREDRAW|CS_VREDRAW; - wc.lpfnWndProc = GtkPanedProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = NULL; - wc.hCursor = LoadCursor(NULL,IDC_SIZEWE); - wc.hbrBackground = (HBRUSH)(1+COLOR_BTNFACE); - wc.lpszMenuName = NULL; - wc.lpszClassName = WC_GTKHPANED; - RegisterClass(&wc); - - wc.style = CS_HREDRAW|CS_VREDRAW; - wc.lpfnWndProc = GtkPanedProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = NULL; - wc.hCursor = LoadCursor(NULL,IDC_SIZENS); - wc.hbrBackground = (HBRUSH)(1+COLOR_BTNFACE); - wc.lpszMenuName = NULL; - wc.lpszClassName = WC_GTKVPANED; - RegisterClass(&wc); - - wc.style = CS_HREDRAW|CS_VREDRAW; - wc.lpfnWndProc = GtkSepProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = NULL; - wc.hCursor = LoadCursor(NULL,IDC_ARROW); - wc.hbrBackground = (HBRUSH)(1+COLOR_BTNFACE); - wc.lpszMenuName = NULL; - wc.lpszClassName = WC_GTKSEP; - RegisterClass(&wc); - - wc.style = CS_HREDRAW|CS_VREDRAW; - wc.lpfnWndProc = GtkUrlProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = NULL; - wc.hCursor = LoadCursor(NULL,IDC_HAND); - wc.hbrBackground = (HBRUSH)(1+COLOR_BTNFACE); - wc.lpszMenuName = NULL; - wc.lpszClassName = WC_GTKURL; - RegisterClass(&wc); - } - - InitCommonControls(); -} - -guint gtk_main_level(void) { +void win32_init(HINSTANCE hInstance, HINSTANCE hPrevInstance, + char *MainIcon) +{ + WNDCLASS wc; + + hInst = hInstance; + defFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT); + urlFont = CreateFont(14, 0, 0, 0, FW_SEMIBOLD, FALSE, TRUE, FALSE, + ANSI_CHARSET, OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, + FF_SWISS | DEFAULT_PITCH, NULL); + WindowList = NULL; + RecurseLevel = 0; + customWndProc = NULL; + if (MainIcon) { + mainIcon = LoadIcon(hInstance, MainIcon); + } else { + mainIcon = LoadIcon(NULL, IDI_APPLICATION); + } + if (!hPrevInstance) { + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = mainIcon; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE); + wc.lpszMenuName = NULL; + wc.lpszClassName = "mainwin"; + RegisterClass(&wc); + + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE); + wc.lpszMenuName = NULL; + wc.lpszClassName = WC_GTKDIALOG; + RegisterClass(&wc); + + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = GtkPanedProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_SIZEWE); + wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE); + wc.lpszMenuName = NULL; + wc.lpszClassName = WC_GTKHPANED; + RegisterClass(&wc); + + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = GtkPanedProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_SIZENS); + wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE); + wc.lpszMenuName = NULL; + wc.lpszClassName = WC_GTKVPANED; + RegisterClass(&wc); + + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = GtkSepProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE); + wc.lpszMenuName = NULL; + wc.lpszClassName = WC_GTKSEP; + RegisterClass(&wc); + + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = GtkUrlProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_HAND); + wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE); + wc.lpszMenuName = NULL; + wc.lpszClassName = WC_GTKURL; + RegisterClass(&wc); + } + + InitCommonControls(); +} + +guint gtk_main_level(void) +{ return RecurseLevel; } -void gtk_widget_update(GtkWidget *widget,gboolean ForceResize) { - GtkRequisition req; - GtkWidget *window; - GtkAllocation alloc; +void gtk_widget_update(GtkWidget *widget, gboolean ForceResize) +{ + GtkRequisition req; + GtkWidget *window; + GtkAllocation alloc; + + if (!GTK_WIDGET_REALIZED(widget)) + return; + + gtk_widget_size_request(widget, &req); + window = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); + if (window) { + alloc.x = alloc.y = 0; + alloc.width = window->requisition.width; + alloc.height = window->requisition.height; + gtk_window_handle_auto_size(GTK_WINDOW(window), &alloc); + if (alloc.width != window->allocation.width + || alloc.height != window->allocation.height || ForceResize) { + gtk_widget_set_size(window, &alloc); + } + } +} - if (!GTK_WIDGET_REALIZED(widget)) return; +void gtk_widget_show(GtkWidget *widget) +{ + gtk_widget_show_full(widget, TRUE); +} - gtk_widget_size_request(widget,&req); - window=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW); - if (window) { - alloc.x=alloc.y=0; - alloc.width=window->requisition.width; - alloc.height=window->requisition.height; - gtk_window_handle_auto_size(GTK_WINDOW(window),&alloc); - if (alloc.width!=window->allocation.width || - alloc.height!=window->allocation.height || ForceResize) { - gtk_widget_set_size(window,&alloc); - } - } +void gtk_widget_show_full(GtkWidget *widget, gboolean recurse) +{ + GtkAllocation alloc; + + if (GTK_WIDGET_VISIBLE(widget)) + return; + GTK_WIDGET_SET_FLAGS(widget, GTK_VISIBLE); + + if (recurse) + gtk_widget_show_all_full(widget, TRUE); + else + gtk_signal_emit(GTK_OBJECT(widget), "show"); + + if (!GTK_WIDGET_REALIZED(widget) + && GTK_OBJECT(widget)->klass == &GtkWindowClass) { + gtk_widget_realize(widget); + alloc.x = alloc.y = 0; + alloc.width = widget->requisition.width; + alloc.height = widget->requisition.height; + gtk_window_set_initial_position(GTK_WINDOW(widget), &alloc); + gtk_widget_set_size(widget, &alloc); + ShowWindow(widget->hWnd, SW_SHOWNORMAL); + UpdateWindow(widget->hWnd); + } else if (GTK_WIDGET_REALIZED(widget) + && GTK_OBJECT(widget)->klass != &GtkWindowClass) { + gtk_widget_update(widget, TRUE); + if (!recurse) + ShowWindow(widget->hWnd, SW_SHOWNORMAL); + } + // g_print("widget show - set focus\n"); + gtk_widget_set_focus(widget); +} + +void gtk_widget_hide(GtkWidget *widget) +{ + gtk_widget_hide_full(widget, TRUE); +} + +void gtk_widget_hide_full(GtkWidget *widget, gboolean recurse) +{ + GtkAllocation alloc; + GtkRequisition req; + GtkWidget *window; + + if (!GTK_WIDGET_VISIBLE(widget)) + return; + + if (recurse) + gtk_widget_hide_all_full(widget, TRUE); + else { + gtk_signal_emit(GTK_OBJECT(widget), "hide"); + if (widget->hWnd) + ShowWindow(widget->hWnd, SW_HIDE); + } + + GTK_WIDGET_UNSET_FLAGS(widget, GTK_VISIBLE); + + gtk_widget_lose_focus(widget); + + gtk_widget_size_request(widget, &req); + if (GTK_WIDGET_REALIZED(widget)) { + window = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); + if (window) { + alloc.x = alloc.y = 0; + alloc.width = window->requisition.width; + alloc.height = window->requisition.height; + gtk_window_handle_auto_size(GTK_WINDOW(window), &alloc); + gtk_widget_set_size(window, &alloc); + } + } +} + +void gtk_widget_set_focus(GtkWidget *widget) +{ + GtkWidget *window; + + if (!widget || !GTK_WIDGET_CAN_FOCUS(widget) + || !GTK_WIDGET_SENSITIVE(widget) || !GTK_WIDGET_VISIBLE(widget)) + return; + window = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); + gtk_window_update_focus(GTK_WINDOW(window)); + if (!window || GTK_WINDOW(window)->focus) + return; + + // g_print("Window %p focus set to widget %p + // (%s)\n",window,widget,GTK_OBJECT(widget)->klass->Name); + GTK_WINDOW(window)->focus = widget; + if (widget->hWnd) { + // if (!SetFocus(widget->hWnd)) g_print("SetFocus failed on widget + // %p\n",widget); + SetFocus(widget->hWnd); + } + // else g_print("Cannot call SetFocus - no hWnd\n"); +} + +static BOOL CALLBACK SetFocusEnum(HWND hWnd, LPARAM data) +{ + GtkWidget *widget; + GtkWindow *window = GTK_WINDOW(data); + + widget = GTK_WIDGET(GetWindowLong(hWnd, GWL_USERDATA)); + if (!widget || !GTK_WIDGET_CAN_FOCUS(widget) || + !GTK_WIDGET_SENSITIVE(widget) || !GTK_WIDGET_VISIBLE(widget) || + window->focus == widget) { + return TRUE; + } else { + // g_print("gtk_window_set_focus: focus set to widget %p\n",widget); + window->focus = widget; + SetFocus(widget->hWnd); + return FALSE; + } } -void gtk_widget_show(GtkWidget *widget) { - gtk_widget_show_full(widget,TRUE); +void gtk_window_set_focus(GtkWindow *window) +{ + if (!window || !GTK_WIDGET(window)->hWnd) + return; + EnumChildWindows(GTK_WIDGET(window)->hWnd, SetFocusEnum, (LPARAM)window); } -void gtk_widget_show_full(GtkWidget *widget,gboolean recurse) { - GtkAllocation alloc; +void gtk_widget_lose_focus(GtkWidget *widget) +{ + GtkWidget *window; + + if (!widget || !GTK_WIDGET_CAN_FOCUS(widget)) + return; + window = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); + gtk_window_update_focus(GTK_WINDOW(window)); + if (GTK_WINDOW(window)->focus == widget) { + gtk_window_set_focus(GTK_WINDOW(window)); + } +} - if (GTK_WIDGET_VISIBLE(widget)) return; - GTK_WIDGET_SET_FLAGS(widget,GTK_VISIBLE); +void gtk_window_update_focus(GtkWindow *window) +{ + GtkWidget *widget; + HWND FocusWnd; + + if (GTK_WIDGET(window)->hWnd != GetActiveWindow()) + return; + FocusWnd = GetFocus(); + window->focus = NULL; + if (FocusWnd) { + widget = GTK_WIDGET(GetWindowLong(FocusWnd, GWL_USERDATA)); + if (widget && GTK_WIDGET(window)->hWnd && + GetParent(FocusWnd) == GTK_WIDGET(window)->hWnd) { + window->focus = widget; + } + } +} - if (recurse) gtk_widget_show_all_full(widget,TRUE); - else gtk_signal_emit(GTK_OBJECT(widget),"show"); +void gtk_widget_realize(GtkWidget *widget) +{ + GtkRequisition req; - if (!GTK_WIDGET_REALIZED(widget) && - GTK_OBJECT(widget)->klass==&GtkWindowClass) { - gtk_widget_realize(widget); - alloc.x=alloc.y=0; - alloc.width=widget->requisition.width; - alloc.height=widget->requisition.height; - gtk_window_set_initial_position(GTK_WINDOW(widget),&alloc); - gtk_widget_set_size(widget,&alloc); - ShowWindow(widget->hWnd,SW_SHOWNORMAL); - UpdateWindow(widget->hWnd); - } else if (GTK_WIDGET_REALIZED(widget) && - GTK_OBJECT(widget)->klass!=&GtkWindowClass) { - gtk_widget_update(widget,TRUE); - if (!recurse) ShowWindow(widget->hWnd,SW_SHOWNORMAL); - } + if (GTK_WIDGET_REALIZED(widget)) + return; + gtk_signal_emit(GTK_OBJECT(widget), "realize", &req); + if (widget->hWnd) + SetWindowLong(widget->hWnd, GWL_USERDATA, (LONG)widget); + GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); + gtk_widget_set_sensitive(widget, GTK_WIDGET_SENSITIVE(widget)); -// g_print("widget show - set focus\n"); - gtk_widget_set_focus(widget); + gtk_widget_size_request(widget, &req); } -void gtk_widget_hide(GtkWidget *widget) { - gtk_widget_hide_full(widget,TRUE); +void gtk_widget_create(GtkWidget *widget) +{ + GTK_WIDGET_SET_FLAGS(widget, GTK_SENSITIVE); + widget->usize.width = 0; + widget->usize.height = 0; } -void gtk_widget_hide_full(GtkWidget *widget,gboolean recurse) { - GtkAllocation alloc; - GtkRequisition req; - GtkWidget *window; +void gtk_widget_destroy(GtkWidget *widget) +{ + if (!widget) + return; + + /* If we're closing a modal window, reactivate the parent _before_ + * calling DestroyWindow, to avoid annoying flicker caused if Windows + * chooses to reactivate another application when we close the modal + * dialog */ + if (GTK_OBJECT(widget)->klass == &GtkWindowClass) { + EnableParent(GTK_WINDOW(widget)); + } + + gtk_widget_lose_focus(widget); + if (widget->hWnd) + DestroyWindow(widget->hWnd); + widget->hWnd = NULL; + gtk_signal_emit(GTK_OBJECT(widget), "destroy"); + g_free(widget); +} - if (!GTK_WIDGET_VISIBLE(widget)) return; +void gtk_widget_set_sensitive(GtkWidget *widget, gboolean sensitive) +{ + if (sensitive) { + GTK_WIDGET_SET_FLAGS(widget, GTK_SENSITIVE); + if (widget->hWnd) + EnableWindow(widget->hWnd, sensitive); + gtk_widget_set_focus(widget); + } else { + GTK_WIDGET_UNSET_FLAGS(widget, GTK_SENSITIVE); + gtk_widget_lose_focus(widget); + if (widget->hWnd) + EnableWindow(widget->hWnd, sensitive); + } - if (recurse) gtk_widget_hide_all_full(widget,TRUE); - else { - gtk_signal_emit(GTK_OBJECT(widget),"hide"); - if (widget->hWnd) ShowWindow(widget->hWnd,SW_HIDE); - } + gtk_signal_emit(GTK_OBJECT(widget), sensitive ? "enable" : "disable"); + if (sensitive && widget->hWnd + && GTK_OBJECT(widget)->klass == &GtkWindowClass) + SetActiveWindow(widget->hWnd); +} - GTK_WIDGET_UNSET_FLAGS(widget,GTK_VISIBLE); +void gtk_widget_size_request(GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkRequisition req; - gtk_widget_lose_focus(widget); + requisition->width = requisition->height = 0; + if (GTK_WIDGET_VISIBLE(widget)) { + gtk_signal_emit(GTK_OBJECT(widget), "size_request", requisition); + } + if (requisition->width < widget->usize.width) + requisition->width = widget->usize.width; + if (requisition->height < widget->usize.height) + requisition->height = widget->usize.height; + if (requisition->width != widget->requisition.width || + requisition->height != widget->requisition.height) { + memcpy(&widget->requisition, requisition, sizeof(GtkRequisition)); + if (widget->parent) + gtk_widget_size_request(widget->parent, &req); + } +} - gtk_widget_size_request(widget,&req); - if (GTK_WIDGET_REALIZED(widget)) { - window=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW); - if (window) { - alloc.x=alloc.y=0; - alloc.width=window->requisition.width; - alloc.height=window->requisition.height; - gtk_window_handle_auto_size(GTK_WINDOW(window),&alloc); - gtk_widget_set_size(window,&alloc); - } - } -} - -void gtk_widget_set_focus(GtkWidget *widget) { - GtkWidget *window; - if (!widget || !GTK_WIDGET_CAN_FOCUS(widget) || - !GTK_WIDGET_SENSITIVE(widget) || !GTK_WIDGET_VISIBLE(widget)) return; - window=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW); - gtk_window_update_focus(GTK_WINDOW(window)); - if (!window || GTK_WINDOW(window)->focus) return; - -// g_print("Window %p focus set to widget %p (%s)\n",window,widget,GTK_OBJECT(widget)->klass->Name); - GTK_WINDOW(window)->focus=widget; - if (widget->hWnd) { -// if (!SetFocus(widget->hWnd)) g_print("SetFocus failed on widget %p\n",widget); - SetFocus(widget->hWnd); - } -// else g_print("Cannot call SetFocus - no hWnd\n"); -} - -static BOOL CALLBACK SetFocusEnum(HWND hWnd,LPARAM data) { - GtkWidget *widget; - GtkWindow *window=GTK_WINDOW(data); - widget=GTK_WIDGET(GetWindowLong(hWnd,GWL_USERDATA)); - if (!widget || !GTK_WIDGET_CAN_FOCUS(widget) || - !GTK_WIDGET_SENSITIVE(widget) || !GTK_WIDGET_VISIBLE(widget) || - window->focus==widget) { - return TRUE; - } else { -//g_print("gtk_window_set_focus: focus set to widget %p\n",widget); - window->focus=widget; - SetFocus(widget->hWnd); - return FALSE; - } -} - -void gtk_window_set_focus(GtkWindow *window) { - if (!window||!GTK_WIDGET(window)->hWnd) return; - EnumChildWindows(GTK_WIDGET(window)->hWnd,SetFocusEnum,(LPARAM)window); -} - -void gtk_widget_lose_focus(GtkWidget *widget) { - GtkWidget *window; - if (!widget || !GTK_WIDGET_CAN_FOCUS(widget)) return; - window=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW); - gtk_window_update_focus(GTK_WINDOW(window)); - if (GTK_WINDOW(window)->focus==widget) { - gtk_window_set_focus(GTK_WINDOW(window)); - } -} - -void gtk_window_update_focus(GtkWindow *window) { - GtkWidget *widget; - HWND FocusWnd; - if (GTK_WIDGET(window)->hWnd != GetActiveWindow()) return; - FocusWnd=GetFocus(); - window->focus=NULL; - if (FocusWnd) { - widget=GTK_WIDGET(GetWindowLong(FocusWnd,GWL_USERDATA)); - if (widget && GTK_WIDGET(window)->hWnd && - GetParent(FocusWnd)==GTK_WIDGET(window)->hWnd) { - window->focus=widget; - } /*else g_print("Widget %p is not child of window %p\n",widget,window);*/ - }// else g_print("GetFocus returned NULL\n"); -} - -void gtk_widget_realize(GtkWidget *widget) { - GtkRequisition req; - if (GTK_WIDGET_REALIZED(widget)) return; -/* g_print("Realizing widget %p of class %s\n",widget,GTK_OBJECT(widget)->klass->Name);*/ - gtk_signal_emit(GTK_OBJECT(widget),"realize",&req); - if (widget->hWnd) SetWindowLong(widget->hWnd,GWL_USERDATA,(LONG)widget); - GTK_WIDGET_SET_FLAGS(widget,GTK_REALIZED); - gtk_widget_set_sensitive(widget,GTK_WIDGET_SENSITIVE(widget)); - - gtk_widget_size_request(widget,&req); -} - -void gtk_widget_create(GtkWidget *widget) { - GTK_WIDGET_SET_FLAGS(widget,GTK_SENSITIVE); - widget->usize.width=0; - widget->usize.height=0; -} - -void gtk_widget_destroy(GtkWidget *widget) { - if (!widget) return; - - /* If we're closing a modal window, reactivate the parent - * _before_ calling DestroyWindow, to avoid annoying - * flicker caused if Windows chooses to reactivate another - * application when we close the modal dialog */ - if (GTK_OBJECT(widget)->klass == &GtkWindowClass) { - EnableParent(GTK_WINDOW(widget)); - } - - gtk_widget_lose_focus(widget); - if (widget->hWnd) DestroyWindow(widget->hWnd); - widget->hWnd=NULL; -// g_print("gtk_widget_destroy on widget %p\n",widget); - gtk_signal_emit(GTK_OBJECT(widget),"destroy"); -// g_print("Freeing widget\n"); - g_free(widget); -// g_print("Widget freed\n"); -} - -void gtk_widget_set_sensitive(GtkWidget *widget,gboolean sensitive) { - if (sensitive) { - GTK_WIDGET_SET_FLAGS(widget,GTK_SENSITIVE); - if (widget->hWnd) EnableWindow(widget->hWnd,sensitive); - gtk_widget_set_focus(widget); - } else { - GTK_WIDGET_UNSET_FLAGS(widget,GTK_SENSITIVE); - gtk_widget_lose_focus(widget); - if (widget->hWnd) EnableWindow(widget->hWnd,sensitive); - } - - gtk_signal_emit(GTK_OBJECT(widget),sensitive ? "enable" : "disable"); - if (sensitive && widget->hWnd && GTK_OBJECT(widget)->klass==&GtkWindowClass) - SetActiveWindow(widget->hWnd); -} - -void gtk_widget_size_request(GtkWidget *widget,GtkRequisition *requisition) { - GtkRequisition req; - requisition->width=requisition->height=0; - if (GTK_WIDGET_VISIBLE(widget)) { - gtk_signal_emit(GTK_OBJECT(widget),"size_request",requisition); - } - if (requisition->width < widget->usize.width) - requisition->width = widget->usize.width; - if (requisition->height < widget->usize.height) - requisition->height = widget->usize.height; - if (requisition->width != widget->requisition.width || - requisition->height != widget->requisition.height) { - memcpy(&widget->requisition,requisition,sizeof(GtkRequisition)); - if (widget->parent) gtk_widget_size_request(widget->parent,&req); - } -} - -void gtk_widget_set_size(GtkWidget *widget,GtkAllocation *allocation) { - gtk_signal_emit(GTK_OBJECT(widget),"set_size",allocation); - memcpy(&widget->allocation,allocation,sizeof(GtkAllocation)); -/* g_print("Widget pos set to %d,%d, size %d,%d\n", - allocation->x,allocation->y, - allocation->width,allocation->height);*/ - if (widget->hWnd) { - SetWindowPos(widget->hWnd,HWND_TOP, - allocation->x,allocation->y, - allocation->width,allocation->height, +void gtk_widget_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + gtk_signal_emit(GTK_OBJECT(widget), "set_size", allocation); + memcpy(&widget->allocation, allocation, sizeof(GtkAllocation)); + if (widget->hWnd) { + SetWindowPos(widget->hWnd, HWND_TOP, + allocation->x, allocation->y, + allocation->width, allocation->height, SWP_NOZORDER | - (GTK_OBJECT(widget)->klass==&GtkWindowClass ? SWP_NOMOVE : - 0)); - } + (GTK_OBJECT(widget)->klass == + &GtkWindowClass ? SWP_NOMOVE : 0)); + } } -GtkWidget *gtk_window_new(GtkWindowType type) { - GtkWindow *win; +GtkWidget *gtk_window_new(GtkWindowType type) +{ + GtkWindow *win; + + win = GTK_WINDOW(GtkNewObject(&GtkWindowClass)); - win=GTK_WINDOW(GtkNewObject(&GtkWindowClass)); -// g_print("New window %p created\n",win); + win->title = g_strdup(""); + win->type = type; + win->allow_grow = TRUE; - win->title=g_strdup(""); - win->type=type; - win->allow_grow = TRUE; - - return GTK_WIDGET(win); + return GTK_WIDGET(win); } -void gtk_window_set_title(GtkWindow *window,const gchar *title) { - g_free(window->title); - window->title=g_strdup(title); +void gtk_window_set_title(GtkWindow *window, const gchar *title) +{ + g_free(window->title); + window->title = g_strdup(title); } -gint gtk_window_delete_event(GtkWidget *widget,GdkEvent *event) { - gtk_widget_destroy(widget); - return TRUE; +gint gtk_window_delete_event(GtkWidget *widget, GdkEvent *event) +{ + gtk_widget_destroy(widget); + return TRUE; } -void gtk_window_set_default_size(GtkWindow *window,gint width,gint height) { - window->default_width = width; - window->default_height = height; +void gtk_window_set_default_size(GtkWindow *window, gint width, + gint height) +{ + window->default_width = width; + window->default_height = height; } -void gtk_window_set_transient_for(GtkWindow *window,GtkWindow *parent) { - if (window && parent) { - GTK_WIDGET(window)->parent = GTK_WIDGET(parent); - if (GTK_WIDGET(window)->hWnd && GTK_WIDGET(parent)->hWnd) { - SetParent(GTK_WIDGET(window)->hWnd,GTK_WIDGET(parent)->hWnd); - } - } +void gtk_window_set_transient_for(GtkWindow *window, GtkWindow *parent) +{ + if (window && parent) { + GTK_WIDGET(window)->parent = GTK_WIDGET(parent); + if (GTK_WIDGET(window)->hWnd && GTK_WIDGET(parent)->hWnd) { + SetParent(GTK_WIDGET(window)->hWnd, GTK_WIDGET(parent)->hWnd); + } + } } -void gtk_window_set_policy(GtkWindow *window,gint allow_shrink, - gint allow_grow,gint auto_shrink) { +void gtk_window_set_policy(GtkWindow *window, gint allow_shrink, + gint allow_grow, gint auto_shrink) +{ window->allow_shrink = allow_shrink; window->allow_grow = allow_grow; window->auto_shrink = auto_shrink; } -void gtk_window_set_menu(GtkWindow *window,GtkMenuBar *menu_bar) { - HWND hWnd; - HMENU hMenu; - - hWnd=GTK_WIDGET(window)->hWnd; - hMenu=GTK_MENU_SHELL(menu_bar)->menu; - - if (hWnd && hMenu) SetMenu(hWnd,hMenu); - window->menu_bar=menu_bar; -} - -void gtk_container_set_size(GtkWidget *widget,GtkAllocation *allocation) { - GtkContainer *container; - GtkAllocation child_alloc; - container=GTK_CONTAINER(widget); - if (container->child) { - child_alloc.x=allocation->x+container->border_width; - child_alloc.y=allocation->y+container->border_width; - child_alloc.width=allocation->width-container->border_width*2; - child_alloc.height=allocation->height-container->border_width*2; - gtk_widget_set_size(container->child,&child_alloc); - } -} - -void gtk_frame_set_size(GtkWidget *widget,GtkAllocation *allocation) { - GtkFrame *frame; - GtkAllocation child_alloc; - - frame=GTK_FRAME(widget); - child_alloc.x = allocation->x+3; - child_alloc.y = allocation->y + 3 + frame->label_req.height; - child_alloc.width = allocation->width - 6; - child_alloc.height = allocation->height - frame->label_req.height - 6; - gtk_container_set_size(widget,&child_alloc); -} - -void gtk_container_size_request(GtkWidget *widget,GtkRequisition *requisition) { - GtkContainer *container; -/*g_print("gtk_container_size_request\n");*/ - container=GTK_CONTAINER(widget); - if (container->child) { -/*g_print("requesting size of child\n");*/ - requisition->width=container->child->requisition.width+ - container->border_width*2; - requisition->height=container->child->requisition.height+ - container->border_width*2; -/* g_print("Container requesting size %d by %d\n",requisition->width, - requisition->height);*/ - } -} - -void gtk_window_size_request(GtkWidget *widget,GtkRequisition *requisition) { -/*g_print("gtk_window_size_request\n");*/ - gtk_container_size_request(widget,requisition); - requisition->width+=GetSystemMetrics(SM_CXSIZEFRAME)*2; - requisition->height+=GetSystemMetrics(SM_CYSIZEFRAME)*2+ - GetSystemMetrics(SM_CYCAPTION); - if (GTK_WINDOW(widget)->menu_bar) { - requisition->height+=GetSystemMetrics(SM_CYMENU); - } -} - -void gtk_window_set_size(GtkWidget *widget,GtkAllocation *allocation) { - GtkAllocation child_alloc; - GtkWindow *window=GTK_WINDOW(widget); - - child_alloc.x=child_alloc.y=0; - child_alloc.width=allocation->width-GetSystemMetrics(SM_CXSIZEFRAME)*2; - child_alloc.height=allocation->height-GetSystemMetrics(SM_CYSIZEFRAME)*2 - -GetSystemMetrics(SM_CYCAPTION); - if (window->menu_bar) { - child_alloc.height-=GetSystemMetrics(SM_CYMENU); - } - gtk_container_set_size(widget,&child_alloc); -} - -void gtk_button_size_request(GtkWidget *widget,GtkRequisition *requisition) { - SIZE size; - GtkButton *but=GTK_BUTTON(widget); - - gtk_container_size_request(widget,requisition); - - if (GetTextSize(widget->hWnd, but->text, &size, defFont)) { - requisition->width = size.cx + 15; - requisition->height = size.cy + 10; - } -/* g_print("Button %p requesting size %d by %d\n",widget->hWnd, - requisition->width,requisition->height);*/ -} - -BOOL GetTextSize(HWND hWnd, char *text, LPSIZE lpSize, HFONT hFont) { - HDC hDC; - BOOL RetVal=0; - SIZE LineSize; - HFONT oldFont; - char *endpt,*startpt; - - hDC=GetDC(hWnd); - oldFont = SelectObject(hDC, hFont); - - startpt=text; - lpSize->cx=lpSize->cy=0; - - while (startpt) { - endpt=startpt; - while (endpt && *endpt!='\n' && *endpt) endpt++; - if (endpt) { - if ((endpt==startpt && GetTextExtentPoint32(hDC,"W",1,&LineSize)) || - (endpt!=startpt && GetTextExtentPoint32(hDC,startpt, - endpt-startpt,&LineSize))) { - RetVal=1; - if (LineSize.cx > lpSize->cx) lpSize->cx=LineSize.cx; - lpSize->cy+=LineSize.cy; - } - if (*endpt=='\0') break; - startpt=endpt+1; - } else break; - } - SelectObject(hDC,oldFont); - ReleaseDC(hWnd,hDC); - return RetVal; -} - -void gtk_entry_size_request(GtkWidget *widget,GtkRequisition *requisition) { - SIZE size; - if (GetTextSize(widget->hWnd, "Sample text", &size, defFont)) { - requisition->width = size.cx; - requisition->height = size.cy+8; - } +void gtk_window_set_menu(GtkWindow *window, GtkMenuBar *menu_bar) +{ + HWND hWnd; + HMENU hMenu; + + hWnd = GTK_WIDGET(window)->hWnd; + hMenu = GTK_MENU_SHELL(menu_bar)->menu; + + if (hWnd && hMenu) + SetMenu(hWnd, hMenu); + window->menu_bar = menu_bar; } -void gtk_text_size_request(GtkWidget *widget,GtkRequisition *requisition) { - SIZE size; - if (GetTextSize(widget->hWnd, "Sample text", &size, defFont)) { - requisition->width = size.cx; - requisition->height = size.cy*2+8; - } +void gtk_container_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + GtkContainer *container; + GtkAllocation child_alloc; + + container = GTK_CONTAINER(widget); + if (container->child) { + child_alloc.x = allocation->x + container->border_width; + child_alloc.y = allocation->y + container->border_width; + child_alloc.width = allocation->width - container->border_width * 2; + child_alloc.height = allocation->height - container->border_width * 2; + gtk_widget_set_size(container->child, &child_alloc); + } } -void gtk_frame_size_request(GtkWidget *widget,GtkRequisition *requisition) { - SIZE size; - GtkFrame *frame=GTK_FRAME(widget); +void gtk_frame_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + GtkFrame *frame; + GtkAllocation child_alloc; + + frame = GTK_FRAME(widget); + child_alloc.x = allocation->x + 3; + child_alloc.y = allocation->y + 3 + frame->label_req.height; + child_alloc.width = allocation->width - 6; + child_alloc.height = allocation->height - frame->label_req.height - 6; + gtk_container_set_size(widget, &child_alloc); +} - gtk_container_size_request(widget,requisition); +void gtk_container_size_request(GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkContainer *container; + + container = GTK_CONTAINER(widget); + if (container->child) { + requisition->width = container->child->requisition.width + + container->border_width * 2; + requisition->height = container->child->requisition.height + + container->border_width * 2; + } +} - if (GetTextSize(widget->hWnd, frame->text, &size, defFont)) { - frame->label_req.width = size.cx; - frame->label_req.height = size.cy; - if (size.cx > requisition->width) requisition->width=size.cx; - requisition->width += 6; - requisition->height += size.cy+6; - } -/* g_print("Frame requesting size %d by %d\n",requisition->width, - requisition->height);*/ +void gtk_window_size_request(GtkWidget *widget, + GtkRequisition *requisition) +{ + gtk_container_size_request(widget, requisition); + requisition->width += GetSystemMetrics(SM_CXSIZEFRAME) * 2; + requisition->height += GetSystemMetrics(SM_CYSIZEFRAME) * 2 + + GetSystemMetrics(SM_CYCAPTION); + if (GTK_WINDOW(widget)->menu_bar) { + requisition->height += GetSystemMetrics(SM_CYMENU); + } } +void gtk_window_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + GtkAllocation child_alloc; + GtkWindow *window = GTK_WINDOW(widget); + + child_alloc.x = child_alloc.y = 0; + child_alloc.width = + allocation->width - GetSystemMetrics(SM_CXSIZEFRAME) * 2; + child_alloc.height = + allocation->height - GetSystemMetrics(SM_CYSIZEFRAME) * 2 - + GetSystemMetrics(SM_CYCAPTION); + if (window->menu_bar) { + child_alloc.height -= GetSystemMetrics(SM_CYMENU); + } + gtk_container_set_size(widget, &child_alloc); +} -void gtk_check_button_size_request(GtkWidget *widget, - GtkRequisition *requisition) { - gtk_button_size_request(widget,requisition); - requisition->width += 10; +void gtk_button_size_request(GtkWidget *widget, + GtkRequisition *requisition) +{ + SIZE size; + GtkButton *but = GTK_BUTTON(widget); + + gtk_container_size_request(widget, requisition); + + if (GetTextSize(widget->hWnd, but->text, &size, defFont)) { + requisition->width = size.cx + 15; + requisition->height = size.cy + 10; + } +} + +BOOL GetTextSize(HWND hWnd, char *text, LPSIZE lpSize, HFONT hFont) +{ + HDC hDC; + BOOL RetVal = 0; + SIZE LineSize; + HFONT oldFont; + char *endpt, *startpt; + + hDC = GetDC(hWnd); + oldFont = SelectObject(hDC, hFont); + + startpt = text; + lpSize->cx = lpSize->cy = 0; + + while (startpt) { + endpt = startpt; + while (endpt && *endpt != '\n' && *endpt) + endpt++; + if (endpt) { + if ((endpt == startpt + && GetTextExtentPoint32(hDC, "W", 1, &LineSize)) + || (endpt != startpt + && GetTextExtentPoint32(hDC, startpt, endpt - startpt, + &LineSize))) { + RetVal = 1; + if (LineSize.cx > lpSize->cx) + lpSize->cx = LineSize.cx; + lpSize->cy += LineSize.cy; + } + if (*endpt == '\0') + break; + startpt = endpt + 1; + } else + break; + } + SelectObject(hDC, oldFont); + ReleaseDC(hWnd, hDC); + return RetVal; } -GtkWidget *gtk_button_new_with_label(const gchar *label) { - GtkButton *but; - gint i; +void gtk_entry_size_request(GtkWidget *widget, GtkRequisition *requisition) +{ + SIZE size; + + if (GetTextSize(widget->hWnd, "Sample text", &size, defFont)) { + requisition->width = size.cx; + requisition->height = size.cy + 8; + } +} - but=GTK_BUTTON(GtkNewObject(&GtkButtonClass)); - but->text = g_strdup(label); - for (i=0;i<strlen(but->text);i++) { - if (but->text[i]=='_') but->text[i]='&'; - } +void gtk_text_size_request(GtkWidget *widget, GtkRequisition *requisition) +{ + SIZE size; - return GTK_WIDGET(but); + if (GetTextSize(widget->hWnd, "Sample text", &size, defFont)) { + requisition->width = size.cx; + requisition->height = size.cy * 2 + 8; + } } -GtkWidget *gtk_check_button_new_with_label(const gchar *label) { - GtkButton *but; - gint i; +void gtk_frame_size_request(GtkWidget *widget, GtkRequisition *requisition) +{ + SIZE size; + GtkFrame *frame = GTK_FRAME(widget); + + gtk_container_size_request(widget, requisition); + + if (GetTextSize(widget->hWnd, frame->text, &size, defFont)) { + frame->label_req.width = size.cx; + frame->label_req.height = size.cy; + if (size.cx > requisition->width) + requisition->width = size.cx; + requisition->width += 6; + requisition->height += size.cy + 6; + } +} - but=GTK_BUTTON(GtkNewObject(&GtkCheckButtonClass)); - but->text = g_strdup(label); - for (i=0;i<strlen(but->text);i++) { - if (but->text[i]=='_') but->text[i]='&'; - } - return GTK_WIDGET(but); +void gtk_check_button_size_request(GtkWidget *widget, + GtkRequisition *requisition) +{ + gtk_button_size_request(widget, requisition); + requisition->width += 10; } -GtkWidget *gtk_radio_button_new_with_label_from_widget(GtkRadioButton *group, - const gchar *label) { - GSList *list; +GtkWidget *gtk_button_new_with_label(const gchar *label) +{ + GtkButton *but; + gint i; + + but = GTK_BUTTON(GtkNewObject(&GtkButtonClass)); + but->text = g_strdup(label); + for (i = 0; i < strlen(but->text); i++) { + if (but->text[i] == '_') + but->text[i] = '&'; + } - list=gtk_radio_button_group(group); - return (gtk_radio_button_new_with_label(list,label)); + return GTK_WIDGET(but); } -GtkWidget *gtk_radio_button_new_with_label(GSList *group,const gchar *label) { - GtkButton *but; - GtkRadioButton *radio; - GSList *listpt; - gint i; +GtkWidget *gtk_check_button_new_with_label(const gchar *label) +{ + GtkButton *but; + gint i; + + but = GTK_BUTTON(GtkNewObject(&GtkCheckButtonClass)); + but->text = g_strdup(label); + for (i = 0; i < strlen(but->text); i++) { + if (but->text[i] == '_') + but->text[i] = '&'; + } + + return GTK_WIDGET(but); +} + +GtkWidget *gtk_radio_button_new_with_label_from_widget(GtkRadioButton *group, + const gchar *label) +{ + GSList *list; - but=GTK_BUTTON(GtkNewObject(&GtkRadioButtonClass)); - but->text = g_strdup(label); - for (i=0;i<strlen(but->text);i++) { - if (but->text[i]=='_') but->text[i]='&'; - } + list = gtk_radio_button_group(group); + return (gtk_radio_button_new_with_label(list, label)); +} + +GtkWidget *gtk_radio_button_new_with_label(GSList *group, + const gchar *label) +{ + GtkButton *but; + GtkRadioButton *radio; + GSList *listpt; + gint i; + + but = GTK_BUTTON(GtkNewObject(&GtkRadioButtonClass)); + but->text = g_strdup(label); + for (i = 0; i < strlen(but->text); i++) { + if (but->text[i] == '_') + but->text[i] = '&'; + } - if (group==NULL) GTK_TOGGLE_BUTTON(but)->toggled=TRUE; + if (group == NULL) + GTK_TOGGLE_BUTTON(but)->toggled = TRUE; - group=g_slist_append(group,GTK_RADIO_BUTTON(but)); - for (listpt=group;listpt;listpt=g_slist_next(listpt)) { - radio=GTK_RADIO_BUTTON(listpt->data); - radio->group = group; - } + group = g_slist_append(group, GTK_RADIO_BUTTON(but)); + for (listpt = group; listpt; listpt = g_slist_next(listpt)) { + radio = GTK_RADIO_BUTTON(listpt->data); + radio->group = group; + } - return GTK_WIDGET(but); + return GTK_WIDGET(but); } -GtkWidget *gtk_label_new(const gchar *text) { - GtkLabel *label; +GtkWidget *gtk_label_new(const gchar *text) +{ + GtkLabel *label; - label=GTK_LABEL(GtkNewObject(&GtkLabelClass)); - gtk_label_set_text(label,text); + label = GTK_LABEL(GtkNewObject(&GtkLabelClass)); + gtk_label_set_text(label, text); - return GTK_WIDGET(label); + return GTK_WIDGET(label); } GtkWidget *gtk_url_new(const gchar *text, const gchar *target, t@@ -1663,240 +1819,272 @@ GtkWidget *gtk_url_new(const gchar *text, const gchar *target, GTK_LABEL(url)->text = g_strdup(text); url->target = g_strdup(target); - /* N.B. "bin" is ignored under Win32 */ + /* N.B. "bin" argument is ignored under Win32 */ return GTK_WIDGET(url); } -GtkWidget *gtk_hbox_new(gboolean homogeneous,gint spacing) { - GtkBox *hbox; +GtkWidget *gtk_hbox_new(gboolean homogeneous, gint spacing) +{ + GtkBox *hbox; - hbox=GTK_BOX(GtkNewObject(&GtkHBoxClass)); + hbox = GTK_BOX(GtkNewObject(&GtkHBoxClass)); - hbox->spacing=spacing; - hbox->homogeneous=homogeneous; - return GTK_WIDGET(hbox); + hbox->spacing = spacing; + hbox->homogeneous = homogeneous; + return GTK_WIDGET(hbox); } -GtkWidget *gtk_vbox_new(gboolean homogeneous,gint spacing) { - GtkBox *vbox; +GtkWidget *gtk_vbox_new(gboolean homogeneous, gint spacing) +{ + GtkBox *vbox; - vbox=GTK_BOX(GtkNewObject(&GtkVBoxClass)); + vbox = GTK_BOX(GtkNewObject(&GtkVBoxClass)); - vbox->spacing=spacing; - vbox->homogeneous=homogeneous; - return GTK_WIDGET(vbox); + vbox->spacing = spacing; + vbox->homogeneous = homogeneous; + return GTK_WIDGET(vbox); } -GtkWidget *gtk_frame_new(const gchar *text) { - GtkFrame *frame; +GtkWidget *gtk_frame_new(const gchar *text) +{ + GtkFrame *frame; - frame=GTK_FRAME(GtkNewObject(&GtkFrameClass)); - frame->text = g_strdup(text); -/*g_print("Frame created with caption %s\n",frame->text);*/ + frame = GTK_FRAME(GtkNewObject(&GtkFrameClass)); + frame->text = g_strdup(text); - return GTK_WIDGET(frame); + return GTK_WIDGET(frame); } -GtkWidget *gtk_text_new(GtkAdjustment *hadj,GtkAdjustment *vadj) { - return GTK_WIDGET(GtkNewObject(&GtkTextClass)); +GtkWidget *gtk_text_new(GtkAdjustment *hadj, GtkAdjustment *vadj) +{ + return GTK_WIDGET(GtkNewObject(&GtkTextClass)); } -GtkWidget *gtk_scrolled_text_new(GtkAdjustment *hadj,GtkAdjustment *vadj, - GtkWidget **pack_widg) { - GtkWidget *text; - text=gtk_text_new(hadj,vadj); - *pack_widg=text; - return text; +GtkWidget *gtk_scrolled_text_new(GtkAdjustment *hadj, GtkAdjustment *vadj, + GtkWidget **pack_widg) +{ + GtkWidget *text; + + text = gtk_text_new(hadj, vadj); + *pack_widg = text; + return text; } -GtkWidget *gtk_entry_new() { - GtkEntry *entry; +GtkWidget *gtk_entry_new() +{ + GtkEntry *entry; - entry = GTK_ENTRY(GtkNewObject(&GtkEntryClass)); - entry->is_visible = TRUE; + entry = GTK_ENTRY(GtkNewObject(&GtkEntryClass)); + entry->is_visible = TRUE; - return GTK_WIDGET(entry); + return GTK_WIDGET(entry); } -GtkWidget *gtk_clist_new(gint columns) { - GtkCList *clist; - int i; - - clist=GTK_CLIST(GtkNewObject(&GtkCListClass)); - clist->ncols=columns; - clist->cols=g_new0(GtkCListColumn,columns); - for (i=0;i<columns;i++) { - clist->cols[i].width=0; - clist->cols[i].visible=TRUE; - clist->cols[i].resizeable=TRUE; - } +GtkWidget *gtk_clist_new(gint columns) +{ + GtkCList *clist; + int i; + + clist = GTK_CLIST(GtkNewObject(&GtkCListClass)); + clist->ncols = columns; + clist->cols = g_new0(GtkCListColumn, columns); + for (i = 0; i < columns; i++) { + clist->cols[i].width = 0; + clist->cols[i].visible = TRUE; + clist->cols[i].resizeable = TRUE; + } - return GTK_WIDGET(clist); + return GTK_WIDGET(clist); } -GSList *gtk_radio_button_group(GtkRadioButton *radio_button) { - return radio_button->group; +GSList *gtk_radio_button_group(GtkRadioButton *radio_button) +{ + return radio_button->group; } -static void gtk_editable_sync_text(GtkEditable *editable) { - HWND hWnd; - gint textlen; - gchar *buffer; +static void gtk_editable_sync_text(GtkEditable *editable) +{ + HWND hWnd; + gint textlen; + gchar *buffer; - hWnd=GTK_WIDGET(editable)->hWnd; - if (!hWnd) return; + hWnd = GTK_WIDGET(editable)->hWnd; + if (!hWnd) + return; - textlen=SendMessage(hWnd,WM_GETTEXTLENGTH,0,0); - buffer=g_new(gchar,textlen+1); - SendMessage(hWnd,WM_GETTEXT,(WPARAM)(textlen+1),(LPARAM)buffer); - g_string_assign(editable->text,buffer); - g_free(buffer); + textlen = SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0); + buffer = g_new(gchar, textlen + 1); + SendMessage(hWnd, WM_GETTEXT, (WPARAM)(textlen + 1), (LPARAM)buffer); + g_string_assign(editable->text, buffer); + g_free(buffer); } -void gtk_editable_insert_text(GtkEditable *editable,const gchar *new_text, - gint new_text_length,gint *position) { - GtkWidget *widget=GTK_WIDGET(editable); - HWND hWnd; - gint i; - GString *newstr; - - gtk_editable_sync_text(editable); - - /* Convert Unix-style lone '\n' to Windows-style '\r\n' */ - newstr=g_string_new(""); - for (i=0;i<new_text_length && new_text[i];i++) { - if (new_text[i]=='\n' && (i==0 || new_text[i-1]!='\r')) { - g_string_append_c(newstr,'\r'); - } - g_string_append_c(newstr,new_text[i]); - } - g_string_insert(editable->text,*position,newstr->str); - - hWnd=widget->hWnd; - if (hWnd) { - SendMessage(hWnd,EM_SETSEL,(WPARAM)*position,(LPARAM)*position); - SendMessage(hWnd,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)newstr->str); - *position+=newstr->len; - gtk_editable_set_position(editable,*position); - } - g_string_free(newstr,TRUE); -} +void gtk_editable_insert_text(GtkEditable *editable, const gchar *new_text, + gint new_text_length, gint *position) +{ + GtkWidget *widget = GTK_WIDGET(editable); + HWND hWnd; + gint i; + GString *newstr; + + gtk_editable_sync_text(editable); + + /* Convert Unix-style lone '\n' to Windows-style '\r\n' */ + newstr = g_string_new(""); + for (i = 0; i < new_text_length && new_text[i]; i++) { + if (new_text[i] == '\n' && (i == 0 || new_text[i - 1] != '\r')) { + g_string_append_c(newstr, '\r'); + } + g_string_append_c(newstr, new_text[i]); + } + g_string_insert(editable->text, *position, newstr->str); + + hWnd = widget->hWnd; + if (hWnd) { + SendMessage(hWnd, EM_SETSEL, (WPARAM)*position, (LPARAM)*position); + SendMessage(hWnd, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)newstr->str); + *position += newstr->len; + gtk_editable_set_position(editable, *position); + } + g_string_free(newstr, TRUE); +} void gtk_editable_delete_text(GtkEditable *editable, - gint start_pos,gint end_pos) { - GtkWidget *widget=GTK_WIDGET(editable); - HWND hWnd; + gint start_pos, gint end_pos) +{ + GtkWidget *widget = GTK_WIDGET(editable); + HWND hWnd; - gtk_editable_sync_text(editable); - if (end_pos < 0 || end_pos >= editable->text->len) - end_pos=editable->text->len; - g_string_erase(editable->text,start_pos,end_pos-start_pos); + gtk_editable_sync_text(editable); + if (end_pos < 0 || end_pos >= editable->text->len) + end_pos = editable->text->len; + g_string_erase(editable->text, start_pos, end_pos - start_pos); - hWnd=widget->hWnd; - if (hWnd) { - SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)editable->text->str); - } + hWnd = widget->hWnd; + if (hWnd) { + SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)editable->text->str); + } } gchar *gtk_editable_get_chars(GtkEditable *editable, - gint start_pos,gint end_pos) { - gchar *retbuf; - gint copylen; - gtk_editable_sync_text(editable); - if (end_pos < 0 || end_pos >= editable->text->len) - end_pos=editable->text->len; - copylen=end_pos-start_pos+1; - retbuf=g_new(gchar,copylen); - memcpy(retbuf,&editable->text->str[start_pos],copylen); - retbuf[copylen]='\0'; - return retbuf; + gint start_pos, gint end_pos) +{ + gchar *retbuf; + gint copylen; + + gtk_editable_sync_text(editable); + if (end_pos < 0 || end_pos >= editable->text->len) + end_pos = editable->text->len; + copylen = end_pos - start_pos + 1; + retbuf = g_new(gchar, copylen); + + memcpy(retbuf, &editable->text->str[start_pos], copylen); + retbuf[copylen] = '\0'; + return retbuf; } -void gtk_editable_set_editable(GtkEditable *editable,gboolean is_editable) { - GtkWidget *widget=GTK_WIDGET(editable); - HWND hWnd; - editable->is_editable=is_editable; - hWnd=widget->hWnd; - if (hWnd) SendMessage(hWnd,EM_SETREADONLY,(WPARAM)(!is_editable),(LPARAM)0); +void gtk_editable_set_editable(GtkEditable *editable, gboolean is_editable) +{ + GtkWidget *widget = GTK_WIDGET(editable); + HWND hWnd; + + editable->is_editable = is_editable; + hWnd = widget->hWnd; + if (hWnd) + SendMessage(hWnd, EM_SETREADONLY, (WPARAM)(!is_editable), (LPARAM)0); } -void gtk_editable_set_position(GtkEditable *editable,gint position) { - GtkWidget *widget=GTK_WIDGET(editable); - HWND hWnd; - if (!GTK_WIDGET_REALIZED(widget)) return; - hWnd=widget->hWnd; - SendMessage(hWnd,EM_SETSEL,(WPARAM)position,(LPARAM)position); - SendMessage(hWnd,EM_SCROLLCARET,0,0); +void gtk_editable_set_position(GtkEditable *editable, gint position) +{ + GtkWidget *widget = GTK_WIDGET(editable); + HWND hWnd; + + if (!GTK_WIDGET_REALIZED(widget)) + return; + hWnd = widget->hWnd; + SendMessage(hWnd, EM_SETSEL, (WPARAM)position, (LPARAM)position); + SendMessage(hWnd, EM_SCROLLCARET, 0, 0); } -gint gtk_editable_get_position(GtkEditable *editable) { - GtkWidget *widget=GTK_WIDGET(editable); - HWND hWnd; - DWORD EndPos; - if (!GTK_WIDGET_REALIZED(widget)) return 0; - hWnd=widget->hWnd; - SendMessage(hWnd,EM_GETSEL,(WPARAM)NULL,(LPARAM)&EndPos); - return (gint)EndPos; +gint gtk_editable_get_position(GtkEditable *editable) +{ + GtkWidget *widget = GTK_WIDGET(editable); + HWND hWnd; + DWORD EndPos; + + if (!GTK_WIDGET_REALIZED(widget)) + return 0; + hWnd = widget->hWnd; + SendMessage(hWnd, EM_GETSEL, (WPARAM)NULL, (LPARAM)&EndPos); + return (gint)EndPos; } -guint gtk_text_get_length(GtkText *text) { - return GTK_EDITABLE(text)->text->len; +guint gtk_text_get_length(GtkText *text) +{ + return GTK_EDITABLE(text)->text->len; } -void gtk_box_pack_start(GtkBox *box,GtkWidget *child,gboolean Expand, - gboolean Fill,gint Padding) { - GtkBoxChild *newChild; +void gtk_box_pack_start(GtkBox *box, GtkWidget *child, gboolean Expand, + gboolean Fill, gint Padding) +{ + GtkBoxChild *newChild; + + newChild = g_new0(GtkBoxChild, 1); - newChild=g_new0(GtkBoxChild,1); - newChild->widget=child; - newChild->expand=Expand; - newChild->fill=Fill; + newChild->widget = child; + newChild->expand = Expand; + newChild->fill = Fill; - box->children = g_list_append(box->children,(gpointer)newChild); - child->parent = GTK_WIDGET(box); - if (GTK_WIDGET_REALIZED(GTK_WIDGET(box))) { - gtk_widget_realize(child); - gtk_widget_update(GTK_WIDGET(box),TRUE); - } + box->children = g_list_append(box->children, (gpointer)newChild); + child->parent = GTK_WIDGET(box); + if (GTK_WIDGET_REALIZED(GTK_WIDGET(box))) { + gtk_widget_realize(child); + gtk_widget_update(GTK_WIDGET(box), TRUE); + } } -void gtk_button_destroy(GtkWidget *widget) { -/* g_print("Destroying button %p\n",widget);*/ - g_free(GTK_BUTTON(widget)->text); +void gtk_button_destroy(GtkWidget *widget) +{ + g_free(GTK_BUTTON(widget)->text); } -void gtk_frame_destroy(GtkWidget *widget) { - gtk_container_destroy(widget); - g_free(GTK_FRAME(widget)->text); +void gtk_frame_destroy(GtkWidget *widget) +{ + gtk_container_destroy(widget); + g_free(GTK_FRAME(widget)->text); } -void gtk_container_destroy(GtkWidget *widget) { - GtkWidget *child=GTK_CONTAINER(widget)->child; -/* g_print("Destroying container %p\n",widget); - if (child) g_print("Destroying container child %p\n",child);*/ - if (child) gtk_widget_destroy(child); +void gtk_container_destroy(GtkWidget *widget) +{ + GtkWidget *child = GTK_CONTAINER(widget)->child; + + if (child) + gtk_widget_destroy(child); } -void gtk_box_destroy(GtkWidget *widget) { - GtkBoxChild *child; - GList *children; - gtk_container_destroy(widget); +void gtk_box_destroy(GtkWidget *widget) +{ + GtkBoxChild *child; + GList *children; + + gtk_container_destroy(widget); - for (children=GTK_BOX(widget)->children;children; - children=g_list_next(children)) { - child=(GtkBoxChild *)(children->data); -/* if (child && child->widget) g_print("Destroying box child %p\n",child->widget);*/ - if (child && child->widget) gtk_widget_destroy(child->widget); - g_free(child); - } - g_list_free(GTK_BOX(widget)->children); + for (children = GTK_BOX(widget)->children; children; + children = g_list_next(children)) { + child = (GtkBoxChild *)(children->data); + if (child && child->widget) + gtk_widget_destroy(child->widget); + g_free(child); + } + g_list_free(GTK_BOX(widget)->children); } -static void EnableParent(GtkWindow *window) { +static void EnableParent(GtkWindow *window) +{ GtkWidget *parent; - parent=GTK_WIDGET(window)->parent; + parent = GTK_WIDGET(window)->parent; if (window->modal && parent) { GSList *list; t@@ -1905,13 +2093,14 @@ static void EnableParent(GtkWindow *window) { ourhWnd = GTK_WIDGET(window)->hWnd; parenthWnd = parent->hWnd; - for (list=WindowList;list;list=g_slist_next(list)) { - listwin=GTK_WINDOW(list->data); - if (listwin!=window && listwin->modal + for (list = WindowList; list; list = g_slist_next(list)) { + listwin = GTK_WINDOW(list->data); + if (listwin != window && listwin->modal && GTK_WIDGET_VISIBLE(GTK_WIDGET(listwin)) - && GTK_WIDGET(listwin)->parent==parent) return; + && GTK_WIDGET(listwin)->parent == parent) + return; } - gtk_widget_set_sensitive(parent,TRUE); + gtk_widget_set_sensitive(parent, TRUE); if (ourhWnd && parenthWnd && ourhWnd == GetActiveWindow()) { SetActiveWindow(parenthWnd); t@@ -1919,819 +2108,931 @@ static void EnableParent(GtkWindow *window) { } } -void gtk_window_destroy(GtkWidget *widget) { - GtkWindow *window=GTK_WINDOW(widget); -// EnableParent(window); -// g_print("gtk_window_destroy on widget %p\n",widget); - WindowList=g_slist_remove(WindowList,(gpointer)window); - gtk_container_destroy(widget); - if (window->accel_group) gtk_accel_group_destroy(window->accel_group); - if (window->hAccel) DestroyAcceleratorTable(window->hAccel); - g_free(window->title); -// if (widget->hWnd) DestroyWindow(widget->hWnd); -// widget->hWnd=NULL; -} - -void gtk_window_show(GtkWidget *widget) { - GtkWindow *window=GTK_WINDOW(widget); - if (window->modal && widget->parent) - gtk_widget_set_sensitive(widget->parent,FALSE); -} - -void gtk_window_hide(GtkWidget *widget) { - GtkWindow *window=GTK_WINDOW(widget); - EnableParent(window); -} - -void gtk_hbox_size_request(GtkWidget *widget, - GtkRequisition *requisition) { - GtkBoxChild *child; - GList *children; - GtkRequisition *child_req; - gint spacing=GTK_BOX(widget)->spacing,numchildren=0; - gint maxreq=0; - gboolean homogeneous=GTK_BOX(widget)->homogeneous; - - for (children=GTK_BOX(widget)->children;children; - children=g_list_next(children)) { - child=(GtkBoxChild *)(children->data); - if (child && child->widget && GTK_WIDGET_VISIBLE(child->widget)) { - child_req=&child->widget->requisition; - if (homogeneous) { - numchildren++; - if (child_req->width > maxreq) maxreq=child_req->width; - } else { - requisition->width+=child_req->width; - } - if (g_list_next(children)) requisition->width+=spacing; - if (child_req->height > requisition->height) - requisition->height=child_req->height; - } - } - if (homogeneous) requisition->width+=numchildren*maxreq; - GTK_BOX(widget)->maxreq=maxreq; - requisition->width+=2*GTK_CONTAINER(widget)->border_width; - requisition->height+=2*GTK_CONTAINER(widget)->border_width; -} - -void gtk_vbox_size_request(GtkWidget *widget, - GtkRequisition *requisition) { - GtkBoxChild *child; - GList *children; - GtkRequisition *child_req; - gint spacing=GTK_BOX(widget)->spacing,numchildren=0; - gint maxreq=0; - gboolean homogeneous=GTK_BOX(widget)->homogeneous; - - for (children=GTK_BOX(widget)->children;children; - children=g_list_next(children)) { - child=(GtkBoxChild *)(children->data); - if (child && child->widget && GTK_WIDGET_VISIBLE(child->widget)) { - child_req=&child->widget->requisition; - if (homogeneous) { - numchildren++; - if (child_req->height > maxreq) maxreq=child_req->height; - } else { - requisition->height+=child_req->height; - } - if (g_list_next(children)) requisition->height+=spacing; - if (child_req->width > requisition->width) - requisition->width=child_req->width; - } - } - if (homogeneous) requisition->height+=numchildren*maxreq; - GTK_BOX(widget)->maxreq=maxreq; - requisition->width+=2*GTK_CONTAINER(widget)->border_width; - requisition->height+=2*GTK_CONTAINER(widget)->border_width; -} - -static void gtk_box_count_children(GtkBox *box,gint16 allocation, - gint16 requisition,gint *extra) { - GtkBoxChild *child; - GList *children; - gint NumCanExpand=0; - - for (children=box->children;children;children=g_list_next(children)) { - child=(GtkBoxChild *)(children->data); - if (child && child->widget && GTK_WIDGET_VISIBLE(child->widget) && - child->expand) NumCanExpand++; - } - - *extra = allocation-requisition; - if (NumCanExpand>0) *extra /= NumCanExpand; -} - -static void gtk_box_size_child(GtkBox *box,GtkBoxChild *child, - gint extra,gint16 maxpos,gint16 requisition, - gint16 *pos,gint16 *size, - GList *listpt,gint16 *curpos) { - gboolean TooSmall=FALSE; - *pos=*curpos; - if (extra<0) { - extra=0; - TooSmall=TRUE; - } - if (child->expand && child->fill) { - *size=requisition+extra; - *curpos+=requisition+extra; - } else if (child->expand) { - *size=requisition; - *pos+=extra/2; - *curpos+=requisition+extra; - } else { - *size=requisition; - *curpos+=requisition; - } - if (g_list_next(listpt)) *curpos+=box->spacing; - if (TooSmall) { - if (*pos >= maxpos) { *pos=*size=0; } - else if (*pos+*size > maxpos) { *size=maxpos-*pos; } - } -} - -void gtk_hbox_set_size(GtkWidget *widget,GtkAllocation *allocation) { - GtkBox *box; - GtkBoxChild *child; - GList *children; - GtkAllocation child_alloc; - gint extra; - gint16 curpos; - gint maxpos,height,border_width; - - border_width=GTK_CONTAINER(widget)->border_width; - maxpos=allocation->x+allocation->width-border_width; - height=allocation->height-2*border_width; - - box=GTK_BOX(widget); - - curpos = allocation->x+border_width; - gtk_box_count_children(box,allocation->width,widget->requisition.width, - &extra); - - for (children=box->children;children;children=g_list_next(children)) { - child=(GtkBoxChild *)(children->data); - if (child && child->widget && GTK_WIDGET_VISIBLE(child->widget)) { - gtk_box_size_child(box,child,extra,maxpos, - box->homogeneous ? box->maxreq : - child->widget->requisition.width, - &child_alloc.x,&child_alloc.width, - children,&curpos); - child_alloc.y = allocation->y+border_width; - child_alloc.height = height; - gtk_widget_set_size(child->widget,&child_alloc); - } - } -} - -void gtk_vbox_set_size(GtkWidget *widget,GtkAllocation *allocation) { - GtkBox *box; - GtkBoxChild *child; - GList *children; - GtkAllocation child_alloc; - gint extra; - gint16 curpos; - gint width,maxpos,border_width; - - border_width=GTK_CONTAINER(widget)->border_width; - width=allocation->width-2*border_width; - maxpos=allocation->y+allocation->height-border_width; - - box=GTK_BOX(widget); - - curpos = allocation->y+border_width; - gtk_box_count_children(box,allocation->height,widget->requisition.height, - &extra); - - for (children=box->children;children;children=g_list_next(children)) { - child=(GtkBoxChild *)(children->data); - if (child && child->widget && GTK_WIDGET_VISIBLE(child->widget)) { - gtk_box_size_child(box,child,extra,maxpos, - box->homogeneous ? box->maxreq : - child->widget->requisition.height, - &child_alloc.y,&child_alloc.height, - children,&curpos); - child_alloc.x = allocation->x+border_width; - child_alloc.width = width; - gtk_widget_set_size(child->widget,&child_alloc); - } - } -} - -void gtk_window_realize(GtkWidget *widget) { - GtkWindow *win=GTK_WINDOW(widget); - HWND Parent; - DWORD resize=0; - - if (win->allow_shrink || win->allow_grow) resize=WS_SIZEBOX; - - Parent=gtk_get_parent_hwnd(widget->parent); - if (win->type==GTK_WINDOW_TOPLEVEL) { - widget->hWnd = CreateWindow("mainwin",win->title, - WS_OVERLAPPEDWINDOW|CS_HREDRAW|CS_VREDRAW|resize, - CW_USEDEFAULT,0,0,0,Parent,NULL,hInst,NULL); - if (!TopLevel) TopLevel=widget->hWnd; - } else { - widget->hWnd = CreateWindow(WC_GTKDIALOG,win->title, - WS_CAPTION|WS_SYSMENU|CS_HREDRAW|CS_VREDRAW|resize, - CW_USEDEFAULT,0,0,0,Parent,NULL,hInst,NULL); - } - WindowList=g_slist_append(WindowList,(gpointer)win); - gtk_set_default_font(widget->hWnd); -/* g_print("Window window %p created\n",widget->hWnd);*/ - gtk_container_realize(widget); - - if (win->accel_group && win->accel_group->numaccel) { - win->hAccel = CreateAcceleratorTable(win->accel_group->accel, - win->accel_group->numaccel); - } -// if (win->focus && win->focus->hWnd) SetFocus(win->focus->hWnd); -} - -void gtk_container_realize(GtkWidget *widget) { - GtkWidget *child=GTK_CONTAINER(widget)->child; -/*g_print("Realizing container\n"); - if (child) g_print("Realizing container widget %p\n",child);*/ - if (child) gtk_widget_realize(child); -} - -void gtk_box_realize(GtkWidget *widget) { - GtkBoxChild *child; - GList *children; - -/* g_print("Realizing box...\n");*/ - gtk_container_realize(widget); - - for (children=GTK_BOX(widget)->children;children; - children=g_list_next(children)) { - child=(GtkBoxChild *)(children->data); -/* if (child) g_print("Realizing box widget %p\n",child);*/ - if (child && child->widget) gtk_widget_realize(child->widget); - } -} - -HWND gtk_get_parent_hwnd(GtkWidget *widget) { - widget=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW); - if (widget) return widget->hWnd; else return NULL; -} - -void gtk_button_realize(GtkWidget *widget) { - GtkButton *but=GTK_BUTTON(widget); - HWND Parent; - GTK_WIDGET_SET_FLAGS(widget,GTK_CAN_FOCUS); - Parent=gtk_get_parent_hwnd(widget); - widget->hWnd = CreateWindow("BUTTON",but->text, - WS_CHILD|WS_TABSTOP| - (GTK_WIDGET_FLAGS(widget)>K_IS_DEFAULT ? - BS_DEFPUSHBUTTON : BS_PUSHBUTTON), - widget->allocation.x,widget->allocation.y, - widget->allocation.width,widget->allocation.height, - Parent,NULL,hInst,NULL); - gtk_set_default_font(widget->hWnd); -} - -void gtk_entry_realize(GtkWidget *widget) { - HWND Parent; - Parent=gtk_get_parent_hwnd(widget); - GTK_WIDGET_SET_FLAGS(widget,GTK_CAN_FOCUS); - widget->hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","", - WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL, - widget->allocation.x,widget->allocation.y, - widget->allocation.width,widget->allocation.height, - Parent,NULL,hInst,NULL); -/* Subclass the window (we assume that all edit boxes have the same window - procedure) */ - wpOrigEntryProc = (WNDPROC) SetWindowLong(widget->hWnd, - GWL_WNDPROC, - (LONG)EntryWndProc); - gtk_set_default_font(widget->hWnd); - gtk_editable_set_editable(GTK_EDITABLE(widget), - GTK_EDITABLE(widget)->is_editable); - gtk_entry_set_visibility(GTK_ENTRY(widget),GTK_ENTRY(widget)->is_visible); - SendMessage(widget->hWnd,WM_SETTEXT,0, - (LPARAM)GTK_EDITABLE(widget)->text->str); -} - -void gtk_text_realize(GtkWidget *widget) { - HWND Parent; - gboolean editable; - - Parent=gtk_get_parent_hwnd(widget); - editable=GTK_EDITABLE(widget)->is_editable; - GTK_WIDGET_SET_FLAGS(widget,GTK_CAN_FOCUS); - widget->hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","", - WS_CHILD|(editable ? WS_TABSTOP : 0)| - ES_MULTILINE|ES_WANTRETURN|WS_VSCROLL| - (GTK_TEXT(widget)->word_wrap ? 0 : ES_AUTOHSCROLL), - 0,0,0,0,Parent,NULL,hInst,NULL); -/* Subclass the window (we assume that all multiline edit boxes have the same - window procedure) */ - wpOrigTextProc = (WNDPROC) SetWindowLong(widget->hWnd, - GWL_WNDPROC, - (LONG)TextWndProc); - gtk_set_default_font(widget->hWnd); - gtk_editable_set_editable(GTK_EDITABLE(widget), - GTK_EDITABLE(widget)->is_editable); - SendMessage(widget->hWnd,WM_SETTEXT,0, - (LPARAM)GTK_EDITABLE(widget)->text->str); -} - -void gtk_frame_realize(GtkWidget *widget) { - GtkFrame *frame=GTK_FRAME(widget); - HWND Parent; - gtk_container_realize(widget); - Parent=gtk_get_parent_hwnd(widget); -/*g_print("Creating frame window with caption %s\n",frame->text);*/ - widget->hWnd = CreateWindow("BUTTON",frame->text, - WS_CHILD|BS_GROUPBOX, - widget->allocation.x,widget->allocation.y, - widget->allocation.width,widget->allocation.height, - Parent,NULL,hInst,NULL); - gtk_set_default_font(widget->hWnd); -} - -void gtk_check_button_realize(GtkWidget *widget) { - GtkButton *but=GTK_BUTTON(widget); - HWND Parent; - gboolean toggled; - Parent=gtk_get_parent_hwnd(widget); - GTK_WIDGET_SET_FLAGS(widget,GTK_CAN_FOCUS); - widget->hWnd = CreateWindow("BUTTON",but->text, - WS_CHILD|WS_TABSTOP|BS_CHECKBOX, - widget->allocation.x,widget->allocation.y, - widget->allocation.width,widget->allocation.height, - Parent,NULL,hInst,NULL); - gtk_set_default_font(widget->hWnd); - gtk_signal_connect(GTK_OBJECT(widget),"clicked", - gtk_toggle_button_toggled,NULL); - gtk_signal_connect(GTK_OBJECT(widget),"toggled", - gtk_check_button_toggled,NULL); - toggled=GTK_TOGGLE_BUTTON(widget)->toggled; - GTK_TOGGLE_BUTTON(widget)->toggled = !toggled; - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),toggled); -} - -void gtk_radio_button_realize(GtkWidget *widget) { - GtkButton *but=GTK_BUTTON(widget); - HWND Parent; - gboolean toggled; - Parent=gtk_get_parent_hwnd(widget); - GTK_WIDGET_SET_FLAGS(widget,GTK_CAN_FOCUS); - widget->hWnd = CreateWindow("BUTTON",but->text, - WS_CHILD|WS_TABSTOP|BS_RADIOBUTTON, - widget->allocation.x,widget->allocation.y, - widget->allocation.width,widget->allocation.height, - Parent,NULL,hInst,NULL); - gtk_set_default_font(widget->hWnd); - gtk_signal_connect(GTK_OBJECT(widget),"clicked", - gtk_radio_button_clicked,NULL); - gtk_signal_connect(GTK_OBJECT(widget),"toggled", - gtk_radio_button_toggled,NULL); - toggled=GTK_TOGGLE_BUTTON(widget)->toggled; - GTK_TOGGLE_BUTTON(widget)->toggled = !toggled; - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),toggled); -} - -void gtk_radio_button_destroy(GtkWidget *widget) { - GSList *group,*listpt; - GtkRadioButton *radio; - - gtk_button_destroy(widget); - group=GTK_RADIO_BUTTON(widget)->group; - group=g_slist_remove(group,GTK_RADIO_BUTTON(widget)); - for (listpt=group;listpt;listpt=g_slist_next(listpt)) { - radio=GTK_RADIO_BUTTON(listpt->data); - radio->group = group; - } -} - - -void gtk_clist_size_request(GtkWidget *widget,GtkRequisition *requisition) { - SIZE size; - - if (GetTextSize(widget->hWnd, "Sample text", &size, defFont)) { - requisition->width = size.cx; - requisition->height = size.cy*6+12; - } -} - -void gtk_clist_set_size(GtkWidget *widget,GtkAllocation *allocation) { - GtkCList *clist=GTK_CLIST(widget); - gtk_container_set_size(widget,allocation); - if (clist->header) { - SetWindowPos(clist->header,HWND_TOP, - allocation->x,allocation->y, - allocation->width,clist->header_size, - SWP_NOZORDER); - allocation->y+=clist->header_size-1; - allocation->height-=clist->header_size-1; - } -} - -void gtk_clist_realize(GtkWidget *widget) { - HWND Parent,header; - HD_LAYOUT hdl; - HD_ITEM hdi; - RECT rcParent; - WINDOWPOS wp; - GtkCList *clist=GTK_CLIST(widget); - GSList *rows; - GtkCListRow *row; - gint i; - - gtk_container_realize(widget); - Parent=gtk_get_parent_hwnd(widget); - GTK_WIDGET_SET_FLAGS(widget,GTK_CAN_FOCUS); - rcParent.left = rcParent.top = 0; - rcParent.right = rcParent.bottom = 800; - header=CreateWindowEx(0,WC_HEADER,NULL, - WS_CHILD|WS_BORDER|HDS_HORZ - | (GTK_CLIST(widget)->cols[0].button_passive ? - 0 : HDS_BUTTONS), - 0,0,0,0,Parent,NULL,hInst,NULL); - SetWindowLong(header,GWL_USERDATA,(LONG)widget); - GTK_CLIST(widget)->header=header; - gtk_set_default_font(header); - hdl.prc = &rcParent; - hdl.pwpos = ℘ - SendMessage(header,HDM_LAYOUT,0,(LPARAM)&hdl); - clist->header_size=wp.cy; - widget->hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,"LISTBOX","", - WS_CHILD|WS_TABSTOP|LBS_DISABLENOSCROLL| - WS_VSCROLL| - LBS_OWNERDRAWFIXED|LBS_NOTIFY, - 0,0,0,0,Parent,NULL,hInst,NULL); - gtk_set_default_font(widget->hWnd); - - gtk_clist_update_all_widths(clist); - for (rows=clist->rows;rows;rows=g_slist_next(rows)) { - row=(GtkCListRow *)rows->data; - if (row) SendMessage(widget->hWnd,LB_ADDSTRING,0,(LPARAM)row->data); - } - - for (i=0;i<clist->ncols;i++) { - hdi.mask = HDI_TEXT|HDI_FORMAT|HDI_WIDTH; - hdi.pszText=clist->cols[i].title; - if (hdi.pszText) { - if (i==clist->ncols-1) hdi.cxy=9000; - else hdi.cxy=clist->cols[i].width; - hdi.cchTextMax=strlen(hdi.pszText); - hdi.fmt = HDF_LEFT|HDF_STRING; - SendMessage(header,HDM_INSERTITEM,i+1,(LPARAM)&hdi); - } - } - -} - -void gtk_clist_show(GtkWidget *widget) { - if (GTK_WIDGET_REALIZED(widget)) { - ShowWindow(GTK_CLIST(widget)->header,SW_SHOWNORMAL); - } -} - -void gtk_clist_hide(GtkWidget *widget) { - if (GTK_WIDGET_REALIZED(widget)) { - ShowWindow(GTK_CLIST(widget)->header,SW_HIDE); - } -} - -void gtk_clist_draw_row(GtkCList *clist,LPDRAWITEMSTRUCT lpdis) { - HBRUSH bkgrnd; - COLORREF textcol,oldtextcol; - RECT rcCol; - gint i,CurrentX; - GtkCListRow *row; - - if (lpdis->itemState&ODS_SELECTED) { - bkgrnd=(HBRUSH)(1+COLOR_HIGHLIGHT); - textcol=(COLORREF)GetSysColor(COLOR_HIGHLIGHTTEXT); - } else { - bkgrnd=(HBRUSH)(1+COLOR_WINDOW); - textcol=(COLORREF)GetSysColor(COLOR_WINDOWTEXT); - } - oldtextcol=SetTextColor(lpdis->hDC,textcol); - SetBkMode(lpdis->hDC,TRANSPARENT); - FillRect(lpdis->hDC,&lpdis->rcItem,bkgrnd); - - if (lpdis->itemID >= 0 && lpdis->itemID < g_slist_length(clist->rows)) { - row=(GtkCListRow *)g_slist_nth_data(clist->rows,lpdis->itemID); - CurrentX=lpdis->rcItem.left; - rcCol.top=lpdis->rcItem.top; - rcCol.bottom=lpdis->rcItem.bottom; - if (row->text) for (i=0;i<clist->ncols;i++) { - rcCol.left=CurrentX+LISTITEMHPACK; - CurrentX+=clist->cols[i].width; - rcCol.right=CurrentX-LISTITEMHPACK; - if (rcCol.left > lpdis->rcItem.right) rcCol.left=lpdis->rcItem.right; - if (rcCol.right > lpdis->rcItem.right) rcCol.right=lpdis->rcItem.right; - if (i==clist->ncols-1) rcCol.right=lpdis->rcItem.right; - if (row->text[i]) { - DrawText(lpdis->hDC,row->text[i],-1,&rcCol, - DT_LEFT|DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS); - } - } - } +void gtk_window_destroy(GtkWidget *widget) +{ + GtkWindow *window = GTK_WINDOW(widget); - SetTextColor(lpdis->hDC,oldtextcol); - SetBkMode(lpdis->hDC,OPAQUE); - if (lpdis->itemState&ODS_FOCUS) DrawFocusRect(lpdis->hDC,&lpdis->rcItem); + WindowList = g_slist_remove(WindowList, (gpointer)window); + gtk_container_destroy(widget); + if (window->accel_group) + gtk_accel_group_destroy(window->accel_group); + if (window->hAccel) + DestroyAcceleratorTable(window->hAccel); + g_free(window->title); } -void gtk_clist_do_auto_resize(GtkCList *clist) { - gint i; - for (i=0;i<clist->ncols;i++) if (clist->cols[i].auto_resize) { - gtk_clist_set_column_width(clist,i,clist->cols[i].width); - } +void gtk_window_show(GtkWidget *widget) +{ + GtkWindow *window = GTK_WINDOW(widget); + + if (window->modal && widget->parent) + gtk_widget_set_sensitive(widget->parent, FALSE); } -void gtk_clist_update_all_widths(GtkCList *clist) { - GSList *list; - GtkCListRow *row; - gint i; - SIZE size; - HWND header; +void gtk_window_hide(GtkWidget *widget) +{ + GtkWindow *window = GTK_WINDOW(widget); - header=clist->header; - if (header) for (i=0;i<clist->ncols;i++) { - if (GetTextSize(header, clist->cols[i].title, &size, defFont) && - clist->cols[i].width<size.cx+2*LISTHEADERPACK) { - clist->cols[i].width=size.cx+2*LISTHEADERPACK; + EnableParent(window); +} + +void gtk_hbox_size_request(GtkWidget *widget, GtkRequisition *requisition) +{ + GtkBoxChild *child; + GList *children; + GtkRequisition *child_req; + gint spacing = GTK_BOX(widget)->spacing, numchildren = 0; + gint maxreq = 0; + gboolean homogeneous = GTK_BOX(widget)->homogeneous; + + for (children = GTK_BOX(widget)->children; children; + children = g_list_next(children)) { + child = (GtkBoxChild *)(children->data); + if (child && child->widget && GTK_WIDGET_VISIBLE(child->widget)) { + child_req = &child->widget->requisition; + if (homogeneous) { + numchildren++; + if (child_req->width > maxreq) + maxreq = child_req->width; + } else { + requisition->width += child_req->width; } - } - - for (list=clist->rows;list;list=g_slist_next(list)) { - row=(GtkCListRow *)list->data; - if (row && row->text) gtk_clist_update_widths(clist,row->text); - } -} - -void gtk_clist_update_widths(GtkCList *clist,gchar *text[]) { - gint i; - SIZE size; - HWND hWnd; - hWnd=GTK_WIDGET(clist)->hWnd; - if (!hWnd) return; - for (i=0;i<clist->ncols;i++) { - if (clist->cols[i].auto_resize - && GetTextSize(hWnd, text[i], &size, defFont) - && size.cx+2*LISTITEMHPACK > clist->cols[i].width) { - clist->cols[i].width = size.cx+2*LISTITEMHPACK; + if (g_list_next(children)) + requisition->width += spacing; + if (child_req->height > requisition->height) + requisition->height = child_req->height; + } + } + if (homogeneous) + requisition->width += numchildren * maxreq; + GTK_BOX(widget)->maxreq = maxreq; + requisition->width += 2 * GTK_CONTAINER(widget)->border_width; + requisition->height += 2 * GTK_CONTAINER(widget)->border_width; +} + +void gtk_vbox_size_request(GtkWidget *widget, GtkRequisition *requisition) +{ + GtkBoxChild *child; + GList *children; + GtkRequisition *child_req; + gint spacing = GTK_BOX(widget)->spacing, numchildren = 0; + gint maxreq = 0; + gboolean homogeneous = GTK_BOX(widget)->homogeneous; + + for (children = GTK_BOX(widget)->children; children; + children = g_list_next(children)) { + child = (GtkBoxChild *)(children->data); + if (child && child->widget && GTK_WIDGET_VISIBLE(child->widget)) { + child_req = &child->widget->requisition; + if (homogeneous) { + numchildren++; + if (child_req->height > maxreq) + maxreq = child_req->height; + } else { + requisition->height += child_req->height; } - } + if (g_list_next(children)) + requisition->height += spacing; + if (child_req->width > requisition->width) + requisition->width = child_req->width; + } + } + if (homogeneous) + requisition->height += numchildren * maxreq; + GTK_BOX(widget)->maxreq = maxreq; + requisition->width += 2 * GTK_CONTAINER(widget)->border_width; + requisition->height += 2 * GTK_CONTAINER(widget)->border_width; } -gint gtk_clist_insert(GtkCList *clist,gint row,gchar *text[]) { - GtkWidget *widget=GTK_WIDGET(clist); - HWND hWnd; - GtkCListRow *new_row; - gint i; +static void gtk_box_count_children(GtkBox *box, gint16 allocation, + gint16 requisition, gint *extra) +{ + GtkBoxChild *child; + GList *children; + gint NumCanExpand = 0; + + for (children = box->children; children; + children = g_list_next(children)) { + child = (GtkBoxChild *)(children->data); + if (child && child->widget && GTK_WIDGET_VISIBLE(child->widget) && + child->expand) + NumCanExpand++; + } - if (row<0) row=g_slist_length(clist->rows); + *extra = allocation - requisition; + if (NumCanExpand > 0) + *extra /= NumCanExpand; +} - new_row=g_new0(GtkCListRow,1); - new_row->text=g_new0(gchar *,clist->ncols); - for (i=0;i<clist->ncols;i++) { - new_row->text[i]=g_strdup(text[i]); - } - gtk_clist_update_widths(clist,new_row->text); - gtk_clist_do_auto_resize(clist); - clist->rows=g_slist_insert(clist->rows,(gpointer)new_row,row); +static void gtk_box_size_child(GtkBox *box, GtkBoxChild *child, + gint extra, gint16 maxpos, + gint16 requisition, gint16 *pos, + gint16 *size, GList *listpt, gint16 *curpos) +{ + gboolean TooSmall = FALSE; - if (GTK_WIDGET_REALIZED(widget)) { - hWnd=widget->hWnd; - SendMessage(hWnd,LB_INSERTSTRING,(WPARAM)row,(LPARAM)NULL); - } + *pos = *curpos; + if (extra < 0) { + extra = 0; + TooSmall = TRUE; + } + if (child->expand && child->fill) { + *size = requisition + extra; + *curpos += requisition + extra; + } else if (child->expand) { + *size = requisition; + *pos += extra / 2; + *curpos += requisition + extra; + } else { + *size = requisition; + *curpos += requisition; + } + if (g_list_next(listpt)) + *curpos += box->spacing; + if (TooSmall) { + if (*pos >= maxpos) { + *pos = *size = 0; + } else if (*pos + *size > maxpos) { + *size = maxpos - *pos; + } + } +} - return row; +void gtk_hbox_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + GtkBox *box; + GtkBoxChild *child; + GList *children; + GtkAllocation child_alloc; + gint extra; + gint16 curpos; + gint maxpos, height, border_width; + + border_width = GTK_CONTAINER(widget)->border_width; + maxpos = allocation->x + allocation->width - border_width; + height = allocation->height - 2 * border_width; + + box = GTK_BOX(widget); + + curpos = allocation->x + border_width; + gtk_box_count_children(box, allocation->width, widget->requisition.width, + &extra); + + for (children = box->children; children; + children = g_list_next(children)) { + child = (GtkBoxChild *)(children->data); + if (child && child->widget && GTK_WIDGET_VISIBLE(child->widget)) { + gtk_box_size_child(box, child, extra, maxpos, + box->homogeneous ? box->maxreq : + child->widget->requisition.width, + &child_alloc.x, &child_alloc.width, + children, &curpos); + child_alloc.y = allocation->y + border_width; + child_alloc.height = height; + gtk_widget_set_size(child->widget, &child_alloc); + } + } } -GtkWidget *gtk_clist_new_with_titles(gint columns,gchar *titles[]) { - GtkWidget *widget; - GtkCList *clist; - gint i; +void gtk_vbox_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + GtkBox *box; + GtkBoxChild *child; + GList *children; + GtkAllocation child_alloc; + gint extra; + gint16 curpos; + gint width, maxpos, border_width; + + border_width = GTK_CONTAINER(widget)->border_width; + width = allocation->width - 2 * border_width; + maxpos = allocation->y + allocation->height - border_width; + + box = GTK_BOX(widget); + + curpos = allocation->y + border_width; + gtk_box_count_children(box, allocation->height, + widget->requisition.height, &extra); + + for (children = box->children; children; + children = g_list_next(children)) { + child = (GtkBoxChild *)(children->data); + if (child && child->widget && GTK_WIDGET_VISIBLE(child->widget)) { + gtk_box_size_child(box, child, extra, maxpos, + box->homogeneous ? box->maxreq : + child->widget->requisition.height, + &child_alloc.y, &child_alloc.height, + children, &curpos); + child_alloc.x = allocation->x + border_width; + child_alloc.width = width; + gtk_widget_set_size(child->widget, &child_alloc); + } + } +} - widget=gtk_clist_new(columns); - clist=GTK_CLIST(widget); - for (i=0;i<clist->ncols;i++) { - gtk_clist_set_column_title(clist,i,titles[i]); - } - return widget; +void gtk_window_realize(GtkWidget *widget) +{ + GtkWindow *win = GTK_WINDOW(widget); + HWND Parent; + DWORD resize = 0; + + if (win->allow_shrink || win->allow_grow) + resize = WS_SIZEBOX; + + Parent = gtk_get_parent_hwnd(widget->parent); + if (win->type == GTK_WINDOW_TOPLEVEL) { + widget->hWnd = CreateWindow("mainwin", win->title, + WS_OVERLAPPEDWINDOW | CS_HREDRAW | + CS_VREDRAW | resize, CW_USEDEFAULT, 0, 0, + 0, Parent, NULL, hInst, NULL); + if (!TopLevel) + TopLevel = widget->hWnd; + } else { + widget->hWnd = CreateWindow(WC_GTKDIALOG, win->title, + WS_CAPTION | WS_SYSMENU | CS_HREDRAW | + CS_VREDRAW | resize, CW_USEDEFAULT, 0, 0, + 0, Parent, NULL, hInst, NULL); + } + WindowList = g_slist_append(WindowList, (gpointer)win); + gtk_set_default_font(widget->hWnd); + gtk_container_realize(widget); + + if (win->accel_group && win->accel_group->numaccel) { + win->hAccel = CreateAcceleratorTable(win->accel_group->accel, + win->accel_group->numaccel); + } } -GtkWidget *gtk_scrolled_clist_new_with_titles(gint columns,gchar *titles[], - GtkWidget **pack_widg) { - GtkWidget *widget; - widget=gtk_clist_new_with_titles(columns,titles); - *pack_widg=widget; - return widget; +void gtk_container_realize(GtkWidget *widget) +{ + GtkWidget *child = GTK_CONTAINER(widget)->child; + + if (child) + gtk_widget_realize(child); } -gint gtk_clist_append(GtkCList *clist,gchar *text[]) { - return gtk_clist_insert(clist,-1,text); +void gtk_box_realize(GtkWidget *widget) +{ + GtkBoxChild *child; + GList *children; + + gtk_container_realize(widget); + + for (children = GTK_BOX(widget)->children; children; + children = g_list_next(children)) { + child = (GtkBoxChild *)(children->data); + if (child && child->widget) + gtk_widget_realize(child->widget); + } } -void gtk_clist_set_column_title(GtkCList *clist,gint column, - const gchar *title) { - HWND hWnd; - if (column<0 || column>=clist->ncols) return; - g_free(clist->cols[column].title); - clist->cols[column].title=g_strdup(title); - if (GTK_WIDGET_REALIZED(GTK_WIDGET(clist))) { - hWnd=GTK_WIDGET(clist)->hWnd; - InvalidateRect(hWnd,NULL,FALSE); - UpdateWindow(hWnd); - } +HWND gtk_get_parent_hwnd(GtkWidget *widget) +{ + widget = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); + if (widget) + return widget->hWnd; + else + return NULL; } -void gtk_clist_column_title_passive(GtkCList *clist,gint column) { - if (column>=0 && column<clist->ncols) - clist->cols[column].button_passive=TRUE; +void gtk_button_realize(GtkWidget *widget) +{ + GtkButton *but = GTK_BUTTON(widget); + HWND Parent; + + GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS); + Parent = gtk_get_parent_hwnd(widget); + widget->hWnd = CreateWindow("BUTTON", but->text, + WS_CHILD | WS_TABSTOP | + (GTK_WIDGET_FLAGS(widget) & GTK_IS_DEFAULT ? + BS_DEFPUSHBUTTON : BS_PUSHBUTTON), + widget->allocation.x, widget->allocation.y, + widget->allocation.width, + widget->allocation.height, Parent, NULL, + hInst, NULL); + gtk_set_default_font(widget->hWnd); +} + +void gtk_entry_realize(GtkWidget *widget) +{ + HWND Parent; + + Parent = gtk_get_parent_hwnd(widget); + GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS); + widget->hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", + WS_CHILD | WS_TABSTOP | ES_AUTOHSCROLL, + widget->allocation.x, widget->allocation.y, + widget->allocation.width, + widget->allocation.height, Parent, NULL, + hInst, NULL); + /* Subclass the window (we assume that all edit boxes have the same + * window procedure) */ + wpOrigEntryProc = (WNDPROC)SetWindowLong(widget->hWnd, + GWL_WNDPROC, + (LONG)EntryWndProc); + gtk_set_default_font(widget->hWnd); + gtk_editable_set_editable(GTK_EDITABLE(widget), + GTK_EDITABLE(widget)->is_editable); + gtk_entry_set_visibility(GTK_ENTRY(widget), + GTK_ENTRY(widget)->is_visible); + SendMessage(widget->hWnd, WM_SETTEXT, 0, + (LPARAM)GTK_EDITABLE(widget)->text->str); +} + +void gtk_text_realize(GtkWidget *widget) +{ + HWND Parent; + gboolean editable; + + Parent = gtk_get_parent_hwnd(widget); + editable = GTK_EDITABLE(widget)->is_editable; + GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS); + widget->hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", + WS_CHILD | (editable ? WS_TABSTOP : 0) | + ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL | + (GTK_TEXT(widget)->word_wrap ? + 0 : ES_AUTOHSCROLL), 0, 0, 0, + 0, Parent, NULL, hInst, NULL); + /* Subclass the window (we assume that all multiline edit boxes have the + * same window procedure) */ + wpOrigTextProc = (WNDPROC)SetWindowLong(widget->hWnd, + GWL_WNDPROC, + (LONG)TextWndProc); + gtk_set_default_font(widget->hWnd); + gtk_editable_set_editable(GTK_EDITABLE(widget), + GTK_EDITABLE(widget)->is_editable); + SendMessage(widget->hWnd, WM_SETTEXT, 0, + (LPARAM)GTK_EDITABLE(widget)->text->str); +} + +void gtk_frame_realize(GtkWidget *widget) +{ + GtkFrame *frame = GTK_FRAME(widget); + HWND Parent; + + gtk_container_realize(widget); + Parent = gtk_get_parent_hwnd(widget); + widget->hWnd = CreateWindow("BUTTON", frame->text, + WS_CHILD | BS_GROUPBOX, + widget->allocation.x, widget->allocation.y, + widget->allocation.width, + widget->allocation.height, Parent, NULL, + hInst, NULL); + gtk_set_default_font(widget->hWnd); } -void gtk_clist_column_titles_passive(GtkCList *clist) { - gint i; - for (i=0;i<clist->ncols;i++) { - gtk_clist_column_title_passive(clist,i); - } +void gtk_check_button_realize(GtkWidget *widget) +{ + GtkButton *but = GTK_BUTTON(widget); + HWND Parent; + gboolean toggled; + + Parent = gtk_get_parent_hwnd(widget); + GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS); + widget->hWnd = CreateWindow("BUTTON", but->text, + WS_CHILD | WS_TABSTOP | BS_CHECKBOX, + widget->allocation.x, widget->allocation.y, + widget->allocation.width, + widget->allocation.height, Parent, NULL, + hInst, NULL); + gtk_set_default_font(widget->hWnd); + gtk_signal_connect(GTK_OBJECT(widget), "clicked", + gtk_toggle_button_toggled, NULL); + gtk_signal_connect(GTK_OBJECT(widget), "toggled", + gtk_check_button_toggled, NULL); + toggled = GTK_TOGGLE_BUTTON(widget)->toggled; + GTK_TOGGLE_BUTTON(widget)->toggled = !toggled; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), toggled); +} + +void gtk_radio_button_realize(GtkWidget *widget) +{ + GtkButton *but = GTK_BUTTON(widget); + HWND Parent; + gboolean toggled; + + Parent = gtk_get_parent_hwnd(widget); + GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS); + widget->hWnd = CreateWindow("BUTTON", but->text, + WS_CHILD | WS_TABSTOP | BS_RADIOBUTTON, + widget->allocation.x, widget->allocation.y, + widget->allocation.width, + widget->allocation.height, Parent, NULL, + hInst, NULL); + gtk_set_default_font(widget->hWnd); + gtk_signal_connect(GTK_OBJECT(widget), "clicked", + gtk_radio_button_clicked, NULL); + gtk_signal_connect(GTK_OBJECT(widget), "toggled", + gtk_radio_button_toggled, NULL); + toggled = GTK_TOGGLE_BUTTON(widget)->toggled; + GTK_TOGGLE_BUTTON(widget)->toggled = !toggled; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), toggled); +} + +void gtk_radio_button_destroy(GtkWidget *widget) +{ + GSList *group, *listpt; + GtkRadioButton *radio; + + gtk_button_destroy(widget); + group = GTK_RADIO_BUTTON(widget)->group; + group = g_slist_remove(group, GTK_RADIO_BUTTON(widget)); + for (listpt = group; listpt; listpt = g_slist_next(listpt)) { + radio = GTK_RADIO_BUTTON(listpt->data); + radio->group = group; + } } -void gtk_clist_column_title_active(GtkCList *clist,gint column) { - if (column>=0 && column<clist->ncols) - clist->cols[column].button_passive=FALSE; + +void gtk_clist_size_request(GtkWidget *widget, GtkRequisition *requisition) +{ + SIZE size; + + if (GetTextSize(widget->hWnd, "Sample text", &size, defFont)) { + requisition->width = size.cx; + requisition->height = size.cy * 6 + 12; + } } -void gtk_clist_column_titles_active(GtkCList *clist) { - gint i; - for (i=0;i<clist->ncols;i++) { - gtk_clist_column_title_active(clist,i); - } +void gtk_clist_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + GtkCList *clist = GTK_CLIST(widget); + + gtk_container_set_size(widget, allocation); + if (clist->header) { + SetWindowPos(clist->header, HWND_TOP, + allocation->x, allocation->y, + allocation->width, clist->header_size, SWP_NOZORDER); + allocation->y += clist->header_size - 1; + allocation->height -= clist->header_size - 1; + } } -void gtk_clist_set_column_width(GtkCList *clist,gint column,gint width) { - gtk_clist_set_column_width_full(clist,column,width,TRUE); +void gtk_clist_realize(GtkWidget *widget) +{ + HWND Parent, header; + HD_LAYOUT hdl; + HD_ITEM hdi; + RECT rcParent; + WINDOWPOS wp; + GtkCList *clist = GTK_CLIST(widget); + GSList *rows; + GtkCListRow *row; + gint i; + + gtk_container_realize(widget); + Parent = gtk_get_parent_hwnd(widget); + GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS); + rcParent.left = rcParent.top = 0; + rcParent.right = rcParent.bottom = 800; + header = CreateWindowEx(0, WC_HEADER, NULL, + WS_CHILD | WS_BORDER | HDS_HORZ + | (GTK_CLIST(widget)->cols[0].button_passive ? + 0 : HDS_BUTTONS), + 0, 0, 0, 0, Parent, NULL, hInst, NULL); + SetWindowLong(header, GWL_USERDATA, (LONG)widget); + GTK_CLIST(widget)->header = header; + gtk_set_default_font(header); + hdl.prc = &rcParent; + hdl.pwpos = ℘ + SendMessage(header, HDM_LAYOUT, 0, (LPARAM)&hdl); + clist->header_size = wp.cy; + widget->hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "", + WS_CHILD | WS_TABSTOP | LBS_DISABLENOSCROLL + | WS_VSCROLL | LBS_OWNERDRAWFIXED | + LBS_NOTIFY, 0, 0, 0, 0, Parent, NULL, + hInst, NULL); + gtk_set_default_font(widget->hWnd); + + gtk_clist_update_all_widths(clist); + for (rows = clist->rows; rows; rows = g_slist_next(rows)) { + row = (GtkCListRow *)rows->data; + if (row) + SendMessage(widget->hWnd, LB_ADDSTRING, 0, (LPARAM)row->data); + } + + for (i = 0; i < clist->ncols; i++) { + hdi.mask = HDI_TEXT | HDI_FORMAT | HDI_WIDTH; + hdi.pszText = clist->cols[i].title; + if (hdi.pszText) { + if (i == clist->ncols - 1) + hdi.cxy = 9000; + else + hdi.cxy = clist->cols[i].width; + hdi.cchTextMax = strlen(hdi.pszText); + hdi.fmt = HDF_LEFT | HDF_STRING; + SendMessage(header, HDM_INSERTITEM, i + 1, (LPARAM)&hdi); + } + } } -void gtk_clist_set_column_width_full(GtkCList *clist,gint column,gint width, - gboolean ResizeHeader) { - HWND hWnd,header; - HD_ITEM hdi; +void gtk_clist_show(GtkWidget *widget) +{ + if (GTK_WIDGET_REALIZED(widget)) { + ShowWindow(GTK_CLIST(widget)->header, SW_SHOWNORMAL); + } +} - if (column<0 || column>=clist->ncols) return; +void gtk_clist_hide(GtkWidget *widget) +{ + if (GTK_WIDGET_REALIZED(widget)) { + ShowWindow(GTK_CLIST(widget)->header, SW_HIDE); + } +} - clist->cols[column].width=width; - if (GTK_WIDGET_REALIZED(GTK_WIDGET(clist))) { - header=clist->header; - if (ResizeHeader && header) { - hdi.mask=HDI_WIDTH; - if (column==clist->ncols-1) width=9000; - hdi.cxy=width; - if (SendMessage(header,HDM_GETITEM,(WPARAM)column,(LPARAM)&hdi) && - hdi.cxy!=width) { - hdi.mask=HDI_WIDTH; - hdi.cxy=width; - SendMessage(header,HDM_SETITEM,(WPARAM)column,(LPARAM)&hdi); - } +void gtk_clist_draw_row(GtkCList *clist, LPDRAWITEMSTRUCT lpdis) +{ + HBRUSH bkgrnd; + COLORREF textcol, oldtextcol; + RECT rcCol; + gint i, CurrentX; + GtkCListRow *row; + + if (lpdis->itemState & ODS_SELECTED) { + bkgrnd = (HBRUSH)(1 + COLOR_HIGHLIGHT); + textcol = (COLORREF)GetSysColor(COLOR_HIGHLIGHTTEXT); + } else { + bkgrnd = (HBRUSH)(1 + COLOR_WINDOW); + textcol = (COLORREF)GetSysColor(COLOR_WINDOWTEXT); + } + oldtextcol = SetTextColor(lpdis->hDC, textcol); + SetBkMode(lpdis->hDC, TRANSPARENT); + FillRect(lpdis->hDC, &lpdis->rcItem, bkgrnd); + + if (lpdis->itemID >= 0 && lpdis->itemID < g_slist_length(clist->rows)) { + row = (GtkCListRow *)g_slist_nth_data(clist->rows, lpdis->itemID); + CurrentX = lpdis->rcItem.left; + rcCol.top = lpdis->rcItem.top; + rcCol.bottom = lpdis->rcItem.bottom; + if (row->text) + for (i = 0; i < clist->ncols; i++) { + rcCol.left = CurrentX + LISTITEMHPACK; + CurrentX += clist->cols[i].width; + rcCol.right = CurrentX - LISTITEMHPACK; + if (rcCol.left > lpdis->rcItem.right) + rcCol.left = lpdis->rcItem.right; + if (rcCol.right > lpdis->rcItem.right) + rcCol.right = lpdis->rcItem.right; + if (i == clist->ncols - 1) + rcCol.right = lpdis->rcItem.right; + if (row->text[i]) { + DrawText(lpdis->hDC, row->text[i], -1, &rcCol, + DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS); + } } - hWnd=GTK_WIDGET(clist)->hWnd; - if (hWnd /*&& clist->cols[column].width!=width*/) - InvalidateRect(hWnd,NULL,FALSE); - } + } + + SetTextColor(lpdis->hDC, oldtextcol); + SetBkMode(lpdis->hDC, OPAQUE); + if (lpdis->itemState & ODS_FOCUS) + DrawFocusRect(lpdis->hDC, &lpdis->rcItem); } -void gtk_clist_set_selection_mode(GtkCList *clist,GtkSelectionMode mode) { - clist->mode=mode; +void gtk_clist_do_auto_resize(GtkCList *clist) +{ + gint i; + + for (i = 0; i < clist->ncols; i++) + if (clist->cols[i].auto_resize) { + gtk_clist_set_column_width(clist, i, clist->cols[i].width); + } } -void gtk_container_show_all(GtkWidget *widget,gboolean hWndOnly) { - GtkContainer *container=GTK_CONTAINER(widget); +void gtk_clist_update_all_widths(GtkCList *clist) +{ + GSList *list; + GtkCListRow *row; + gint i; + SIZE size; + HWND header; + + header = clist->header; + if (header) + for (i = 0; i < clist->ncols; i++) { + if (GetTextSize(header, clist->cols[i].title, &size, defFont) && + clist->cols[i].width < size.cx + 2 * LISTHEADERPACK) { + clist->cols[i].width = size.cx + 2 * LISTHEADERPACK; + } + } - if (container->child) gtk_widget_show_all_full(container->child,hWndOnly); + for (list = clist->rows; list; list = g_slist_next(list)) { + row = (GtkCListRow *)list->data; + if (row && row->text) + gtk_clist_update_widths(clist, row->text); + } } -void gtk_container_hide_all(GtkWidget *widget,gboolean hWndOnly) { - GtkContainer *container=GTK_CONTAINER(widget); +void gtk_clist_update_widths(GtkCList *clist, gchar *text[]) +{ + gint i; + SIZE size; + HWND hWnd; + + hWnd = GTK_WIDGET(clist)->hWnd; + if (!hWnd) + return; + for (i = 0; i < clist->ncols; i++) { + if (clist->cols[i].auto_resize + && GetTextSize(hWnd, text[i], &size, defFont) + && size.cx + 2 * LISTITEMHPACK > clist->cols[i].width) { + clist->cols[i].width = size.cx + 2 * LISTITEMHPACK; + } + } +} + +gint gtk_clist_insert(GtkCList *clist, gint row, gchar *text[]) +{ + GtkWidget *widget = GTK_WIDGET(clist); + HWND hWnd; + GtkCListRow *new_row; + gint i; + + if (row < 0) + row = g_slist_length(clist->rows); + + new_row = g_new0(GtkCListRow, 1); + new_row->text = g_new0(gchar *, clist->ncols); - if (container->child) gtk_widget_hide_all_full(container->child,hWndOnly); + for (i = 0; i < clist->ncols; i++) { + new_row->text[i] = g_strdup(text[i]); + } + gtk_clist_update_widths(clist, new_row->text); + gtk_clist_do_auto_resize(clist); + clist->rows = g_slist_insert(clist->rows, (gpointer)new_row, row); + + if (GTK_WIDGET_REALIZED(widget)) { + hWnd = widget->hWnd; + SendMessage(hWnd, LB_INSERTSTRING, (WPARAM)row, (LPARAM)NULL); + } + + return row; } -void gtk_box_show_all(GtkWidget *widget,gboolean hWndOnly) { - GtkBoxChild *child; - GList *children; +GtkWidget *gtk_clist_new_with_titles(gint columns, gchar *titles[]) +{ + GtkWidget *widget; + GtkCList *clist; + gint i; + + widget = gtk_clist_new(columns); + clist = GTK_CLIST(widget); + for (i = 0; i < clist->ncols; i++) { + gtk_clist_set_column_title(clist, i, titles[i]); + } + return widget; +} - gtk_container_show_all(widget,hWndOnly); +GtkWidget *gtk_scrolled_clist_new_with_titles(gint columns, + gchar *titles[], + GtkWidget **pack_widg) +{ + GtkWidget *widget; - for (children=GTK_BOX(widget)->children;children; - children=g_list_next(children)) { - child=(GtkBoxChild *)(children->data); - if (child && child->widget) - gtk_widget_show_all_full(child->widget,hWndOnly); - } + widget = gtk_clist_new_with_titles(columns, titles); + *pack_widg = widget; + return widget; } -void gtk_box_hide_all(GtkWidget *widget,gboolean hWndOnly) { - GtkBoxChild *child; - GList *children; +gint gtk_clist_append(GtkCList *clist, gchar *text[]) +{ + return gtk_clist_insert(clist, -1, text); +} - gtk_container_hide_all(widget,hWndOnly); +void gtk_clist_set_column_title(GtkCList *clist, gint column, + const gchar *title) +{ + HWND hWnd; + + if (column < 0 || column >= clist->ncols) + return; + g_free(clist->cols[column].title); + clist->cols[column].title = g_strdup(title); + if (GTK_WIDGET_REALIZED(GTK_WIDGET(clist))) { + hWnd = GTK_WIDGET(clist)->hWnd; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + } +} - for (children=GTK_BOX(widget)->children;children; - children=g_list_next(children)) { - child=(GtkBoxChild *)(children->data); - if (child && child->widget) - gtk_widget_hide_all_full(child->widget,hWndOnly); - } +void gtk_clist_column_title_passive(GtkCList *clist, gint column) +{ + if (column >= 0 && column < clist->ncols) + clist->cols[column].button_passive = TRUE; } -void gtk_table_show_all(GtkWidget *widget,gboolean hWndOnly) { - GList *children; - GtkTableChild *child; +void gtk_clist_column_titles_passive(GtkCList *clist) +{ + gint i; - gtk_container_show_all(widget,hWndOnly); - for (children=GTK_TABLE(widget)->children;children; - children=g_list_next(children)) { - child=(GtkTableChild *)(children->data); - if (child && child->widget) - gtk_widget_show_all_full(child->widget,hWndOnly); - } + for (i = 0; i < clist->ncols; i++) { + gtk_clist_column_title_passive(clist, i); + } } -void gtk_table_hide_all(GtkWidget *widget,gboolean hWndOnly) { - GList *children; - GtkTableChild *child; +void gtk_clist_column_title_active(GtkCList *clist, gint column) +{ + if (column >= 0 && column < clist->ncols) + clist->cols[column].button_passive = FALSE; +} + +void gtk_clist_column_titles_active(GtkCList *clist) +{ + gint i; - gtk_container_hide_all(widget,hWndOnly); - for (children=GTK_TABLE(widget)->children;children; - children=g_list_next(children)) { - child=(GtkTableChild *)(children->data); - if (child && child->widget) - gtk_widget_hide_all_full(child->widget,hWndOnly); - } + for (i = 0; i < clist->ncols; i++) { + gtk_clist_column_title_active(clist, i); + } } -void gtk_widget_hide_all(GtkWidget *widget) { - gtk_widget_hide_all_full(widget,FALSE); +void gtk_clist_set_column_width(GtkCList *clist, gint column, gint width) +{ + gtk_clist_set_column_width_full(clist, column, width, TRUE); } -void gtk_widget_hide_all_full(GtkWidget *widget,gboolean hWndOnly) { - gtk_signal_emit(GTK_OBJECT(widget),"hide_all",hWndOnly); - if (hWndOnly) { - gtk_signal_emit(GTK_OBJECT(widget),"hide"); - if (widget->hWnd) ShowWindow(widget->hWnd,SW_HIDE); - } else gtk_widget_hide_full(widget,FALSE); +void gtk_clist_set_column_width_full(GtkCList *clist, gint column, + gint width, gboolean ResizeHeader) +{ + HWND hWnd, header; + HD_ITEM hdi; + + if (column < 0 || column >= clist->ncols) + return; + + clist->cols[column].width = width; + if (GTK_WIDGET_REALIZED(GTK_WIDGET(clist))) { + header = clist->header; + if (ResizeHeader && header) { + hdi.mask = HDI_WIDTH; + if (column == clist->ncols - 1) + width = 9000; + hdi.cxy = width; + if (SendMessage(header, HDM_GETITEM, (WPARAM)column, (LPARAM)&hdi) && + hdi.cxy != width) { + hdi.mask = HDI_WIDTH; + hdi.cxy = width; + SendMessage(header, HDM_SETITEM, (WPARAM)column, (LPARAM)&hdi); + } + } + hWnd = GTK_WIDGET(clist)->hWnd; + if (hWnd /* && clist->cols[column].width!=width */ ) + InvalidateRect(hWnd, NULL, FALSE); + } } -void gtk_widget_show_all(GtkWidget *widget) { - gtk_widget_show_all_full(widget,FALSE); +void gtk_clist_set_selection_mode(GtkCList *clist, GtkSelectionMode mode) +{ + clist->mode = mode; } -void gtk_widget_show_all_full(GtkWidget *widget,gboolean hWndOnly) { - GtkAllocation alloc; - gboolean InitWindow=FALSE; +void gtk_container_show_all(GtkWidget *widget, gboolean hWndOnly) +{ + GtkContainer *container = GTK_CONTAINER(widget); - if (!GTK_WIDGET_REALIZED(widget) && - GTK_OBJECT(widget)->klass==&GtkWindowClass) InitWindow=TRUE; + if (container->child) + gtk_widget_show_all_full(container->child, hWndOnly); +} - if (InitWindow) gtk_widget_realize(widget); - - gtk_signal_emit(GTK_OBJECT(widget),"show_all",hWndOnly); +void gtk_container_hide_all(GtkWidget *widget, gboolean hWndOnly) +{ + GtkContainer *container = GTK_CONTAINER(widget); - if (hWndOnly) { - if (GTK_WIDGET_VISIBLE(widget)) { - gtk_signal_emit(GTK_OBJECT(widget),"show"); - if (widget->hWnd) ShowWindow(widget->hWnd,SW_SHOWNORMAL); - } - } else gtk_widget_show_full(widget,FALSE); + if (container->child) + gtk_widget_hide_all_full(container->child, hWndOnly); +} + +void gtk_box_show_all(GtkWidget *widget, gboolean hWndOnly) +{ + GtkBoxChild *child; + GList *children; + + gtk_container_show_all(widget, hWndOnly); + + for (children = GTK_BOX(widget)->children; children; + children = g_list_next(children)) { + child = (GtkBoxChild *)(children->data); + if (child && child->widget) + gtk_widget_show_all_full(child->widget, hWndOnly); + } +} - if (InitWindow) { - gtk_widget_update(widget,TRUE); - alloc.x=alloc.y=0; - alloc.width=widget->requisition.width; - alloc.height=widget->requisition.height; - gtk_window_set_initial_position(GTK_WINDOW(widget),&alloc); -// gtk_widget_set_size(widget,&alloc); - ShowWindow(widget->hWnd,SW_SHOWNORMAL); - UpdateWindow(widget->hWnd); - } +void gtk_box_hide_all(GtkWidget *widget, gboolean hWndOnly) +{ + GtkBoxChild *child; + GList *children; + + gtk_container_hide_all(widget, hWndOnly); + for (children = GTK_BOX(widget)->children; children; + children = g_list_next(children)) { + child = (GtkBoxChild *)(children->data); + if (child && child->widget) + gtk_widget_hide_all_full(child->widget, hWndOnly); + } } -GtkWidget *gtk_widget_get_ancestor(GtkWidget *widget,GtkType type) { - if (!widget) return NULL; - while (widget && GTK_OBJECT(widget)->klass!=type) { - widget=widget->parent; - } - return widget; +void gtk_table_show_all(GtkWidget *widget, gboolean hWndOnly) +{ + GList *children; + GtkTableChild *child; + + gtk_container_show_all(widget, hWndOnly); + for (children = GTK_TABLE(widget)->children; children; + children = g_list_next(children)) { + child = (GtkTableChild *)(children->data); + if (child && child->widget) + gtk_widget_show_all_full(child->widget, hWndOnly); + } } -void gtk_label_size_request(GtkWidget *widget,GtkRequisition *requisition) { - SIZE size; - GtkLabel *label=GTK_LABEL(widget); +void gtk_table_hide_all(GtkWidget *widget, gboolean hWndOnly) +{ + GList *children; + GtkTableChild *child; + + gtk_container_hide_all(widget, hWndOnly); + for (children = GTK_TABLE(widget)->children; children; + children = g_list_next(children)) { + child = (GtkTableChild *)(children->data); + if (child && child->widget) + gtk_widget_hide_all_full(child->widget, hWndOnly); + } +} - if (GetTextSize(widget->hWnd, label->text, &size, defFont)) { - requisition->width = size.cx; - requisition->height = size.cy; - } -/* g_print("Label requesting size %d by %d\n",requisition->width, - requisition->height);*/ +void gtk_widget_hide_all(GtkWidget *widget) +{ + gtk_widget_hide_all_full(widget, FALSE); +} + +void gtk_widget_hide_all_full(GtkWidget *widget, gboolean hWndOnly) +{ + gtk_signal_emit(GTK_OBJECT(widget), "hide_all", hWndOnly); + if (hWndOnly) { + gtk_signal_emit(GTK_OBJECT(widget), "hide"); + if (widget->hWnd) + ShowWindow(widget->hWnd, SW_HIDE); + } else + gtk_widget_hide_full(widget, FALSE); +} + +void gtk_widget_show_all(GtkWidget *widget) +{ + gtk_widget_show_all_full(widget, FALSE); +} + +void gtk_widget_show_all_full(GtkWidget *widget, gboolean hWndOnly) +{ + GtkAllocation alloc; + gboolean InitWindow = FALSE; + + if (!GTK_WIDGET_REALIZED(widget) && + GTK_OBJECT(widget)->klass == &GtkWindowClass) + InitWindow = TRUE; + + if (InitWindow) + gtk_widget_realize(widget); + + gtk_signal_emit(GTK_OBJECT(widget), "show_all", hWndOnly); + + if (hWndOnly) { + if (GTK_WIDGET_VISIBLE(widget)) { + gtk_signal_emit(GTK_OBJECT(widget), "show"); + if (widget->hWnd) + ShowWindow(widget->hWnd, SW_SHOWNORMAL); + } + } else { + gtk_widget_show_full(widget, FALSE); + } + + if (InitWindow) { + gtk_widget_update(widget, TRUE); + alloc.x = alloc.y = 0; + alloc.width = widget->requisition.width; + alloc.height = widget->requisition.height; + gtk_window_set_initial_position(GTK_WINDOW(widget), &alloc); + ShowWindow(widget->hWnd, SW_SHOWNORMAL); + UpdateWindow(widget->hWnd); + } +} + +GtkWidget *gtk_widget_get_ancestor(GtkWidget *widget, GtkType type) +{ + if (!widget) + return NULL; + while (widget && GTK_OBJECT(widget)->klass != type) { + widget = widget->parent; + } + return widget; +} + +void gtk_label_size_request(GtkWidget *widget, GtkRequisition *requisition) +{ + SIZE size; + GtkLabel *label = GTK_LABEL(widget); + + if (GetTextSize(widget->hWnd, label->text, &size, defFont)) { + requisition->width = size.cx; + requisition->height = size.cy; + } } void gtk_url_size_request(GtkWidget *widget, GtkRequisition *requisition) t@@ -2745,26 +3046,31 @@ void gtk_url_size_request(GtkWidget *widget, GtkRequisition *requisition) } } -void gtk_label_set_size(GtkWidget *widget,GtkAllocation *allocation) { - gint yexcess; - yexcess=allocation->height-widget->requisition.height; - if (yexcess > 0) { - allocation->y += yexcess/2; - allocation->height -= yexcess; - } +void gtk_label_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + gint yexcess; + + yexcess = allocation->height - widget->requisition.height; + if (yexcess > 0) { + allocation->y += yexcess / 2; + allocation->height -= yexcess; + } } -void gtk_entry_set_size(GtkWidget *widget,GtkAllocation *allocation) { - gint yexcess; - yexcess=allocation->height-widget->requisition.height; - if (yexcess > 0) { - allocation->y += yexcess/2; - allocation->height -= yexcess; - } +void gtk_entry_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + gint yexcess; + + yexcess = allocation->height - widget->requisition.height; + if (yexcess > 0) { + allocation->y += yexcess / 2; + allocation->height -= yexcess; + } } -void gtk_label_destroy(GtkWidget *widget) { - g_free(GTK_LABEL(widget)->text); +void gtk_label_destroy(GtkWidget *widget) +{ + g_free(GTK_LABEL(widget)->text); } void gtk_url_destroy(GtkWidget *widget) t@@ -2773,596 +3079,692 @@ void gtk_url_destroy(GtkWidget *widget) g_free(GTK_URL(widget)->target); } -void gtk_label_realize(GtkWidget *widget) { - GtkLabel *label=GTK_LABEL(widget); - HWND Parent; - Parent=gtk_get_parent_hwnd(widget); - widget->hWnd = CreateWindow("STATIC",label->text, - WS_CHILD|SS_CENTER, - widget->allocation.x,widget->allocation.y, - widget->allocation.width,widget->allocation.height, - Parent,NULL,hInst,NULL); - gtk_set_default_font(widget->hWnd); +void gtk_label_realize(GtkWidget *widget) +{ + GtkLabel *label = GTK_LABEL(widget); + HWND Parent; + + Parent = gtk_get_parent_hwnd(widget); + widget->hWnd = CreateWindow("STATIC", label->text, + WS_CHILD | SS_CENTER, + widget->allocation.x, widget->allocation.y, + widget->allocation.width, + widget->allocation.height, Parent, NULL, + hInst, NULL); + gtk_set_default_font(widget->hWnd); } -void gtk_url_realize(GtkWidget *widget) { - HWND Parent; - Parent=gtk_get_parent_hwnd(widget); - widget->hWnd = CreateWindow(WC_GTKURL,GTK_LABEL(widget)->text, - WS_CHILD, - widget->allocation.x,widget->allocation.y, - widget->allocation.width,widget->allocation.height, - Parent,NULL,hInst,NULL); +void gtk_url_realize(GtkWidget *widget) +{ + HWND Parent; + + Parent = gtk_get_parent_hwnd(widget); + widget->hWnd = CreateWindow(WC_GTKURL, GTK_LABEL(widget)->text, + WS_CHILD, + widget->allocation.x, widget->allocation.y, + widget->allocation.width, + widget->allocation.height, Parent, NULL, + hInst, NULL); } -void gtk_container_add(GtkContainer *container,GtkWidget *widget) { - container->child=widget; - widget->parent=GTK_WIDGET(container); - if (GTK_WIDGET_REALIZED(GTK_WIDGET(container))) { - gtk_widget_realize(widget); - gtk_widget_update(GTK_WIDGET(container),TRUE); - } +void gtk_container_add(GtkContainer *container, GtkWidget *widget) +{ + container->child = widget; + widget->parent = GTK_WIDGET(container); + if (GTK_WIDGET_REALIZED(GTK_WIDGET(container))) { + gtk_widget_realize(widget); + gtk_widget_update(GTK_WIDGET(container), TRUE); + } } void gtk_container_set_border_width(GtkContainer *container, - guint border_width) { - container->border_width = border_width; -} - -GtkWidget *gtk_table_new(guint rows,guint cols,gboolean homogeneous) { - GtkTable *table; - - table=GTK_TABLE(GtkNewObject(&GtkTableClass)); - - table->nrows=rows; - table->ncols=cols; - table->homogeneous=homogeneous; - - table->rows = g_new0(GtkTableRowCol,rows); - table->cols = g_new0(GtkTableRowCol,cols); - - return GTK_WIDGET(table); -} - -void gtk_table_resize(GtkTable *table,guint rows,guint cols) { - gint i; - table->rows = g_realloc(table->rows,sizeof(GtkTableRowCol)*rows); - table->cols = g_realloc(table->cols,sizeof(GtkTableRowCol)*cols); - - for (i=table->nrows;i<rows;i++) { - table->rows[i].requisition=0; - table->rows[i].allocation=0; - table->rows[i].spacing=table->row_spacing; - } - for (i=table->ncols;i<cols;i++) { - table->cols[i].requisition=0; - table->cols[i].allocation=0; - table->cols[i].spacing=table->column_spacing; - } - table->nrows = rows; - table->ncols = cols; - gtk_widget_update(GTK_WIDGET(table),FALSE); -} - -void gtk_table_attach_defaults(GtkTable *table,GtkWidget *widget, - guint left_attach,guint right_attach, - guint top_attach,guint bottom_attach) { - gtk_table_attach(table,widget,left_attach,right_attach, - top_attach,bottom_attach,GTK_EXPAND,GTK_EXPAND,0,0); -} - -void gtk_table_attach(GtkTable *table,GtkWidget *widget, - guint left_attach,guint right_attach, - guint top_attach,guint bottom_attach, - GtkAttachOptions xoptions,GtkAttachOptions yoptions, - guint xpadding,guint ypadding) { - GtkTableChild *newChild; - - newChild=g_new0(GtkTableChild,1); - newChild->widget=widget; - newChild->left_attach=left_attach; - newChild->right_attach=right_attach; - newChild->top_attach=top_attach; - newChild->bottom_attach=bottom_attach; - - table->children=g_list_append(table->children,(gpointer)newChild); - widget->parent = GTK_WIDGET(table); - if (GTK_WIDGET_REALIZED(GTK_WIDGET(table))) { - gtk_widget_realize(widget); - gtk_widget_update(GTK_WIDGET(table),TRUE); - } -} - -void gtk_table_destroy(GtkWidget *widget) { - GList *children; - GtkTableChild *child; - - gtk_container_destroy(widget); - for (children=GTK_TABLE(widget)->children;children; - children=g_list_next(children)) { - child=(GtkTableChild *)(children->data); - if (child->widget) gtk_widget_destroy(child->widget); - g_free(child); - } - g_list_free(GTK_TABLE(widget)->children); -} - -void gtk_table_size_request(GtkWidget *widget,GtkRequisition *requisition) { - GList *children; - GtkTableChild *child; - GtkWidget *child_wid; - GtkRequisition child_req; - GtkTable *table; - gint16 MaxReq; - int i; - - table=GTK_TABLE(widget); - for (i=0;i<table->ncols;i++) table->cols[i].requisition=0; - for (i=0;i<table->nrows;i++) table->rows[i].requisition=0; - - gtk_container_size_request(widget,requisition); - for (children=table->children;children; - children=g_list_next(children)) { - child=(GtkTableChild *)(children->data); - if (!child) continue; - child_wid=child->widget; - if (child_wid && child->left_attach<child->right_attach && - child->top_attach<child->bottom_attach && - GTK_WIDGET_VISIBLE(child_wid)) { - child_req.width=child_wid->requisition.width; - child_req.height=child_wid->requisition.height; - child_req.width /= (child->right_attach-child->left_attach); - child_req.height /= (child->bottom_attach-child->top_attach); - for (i=child->left_attach;i<child->right_attach;i++) { - if (child_req.width > table->cols[i].requisition) - table->cols[i].requisition = child_req.width; - } - for (i=child->top_attach;i<child->bottom_attach;i++) { - if (child_req.height > table->rows[i].requisition) - table->rows[i].requisition = child_req.height; - } - } - } + guint border_width) +{ + container->border_width = border_width; +} - if (table->homogeneous) { - MaxReq=0; - for (i=0;i<table->ncols;i++) if (table->cols[i].requisition>MaxReq) { - MaxReq=table->cols[i].requisition; - } - for (i=0;i<table->ncols;i++) table->cols[i].requisition=MaxReq; +GtkWidget *gtk_table_new(guint rows, guint cols, gboolean homogeneous) +{ + GtkTable *table; - MaxReq=0; - for (i=0;i<table->nrows;i++) if (table->rows[i].requisition>MaxReq) { - MaxReq=table->rows[i].requisition; - } - for (i=0;i<table->nrows;i++) table->rows[i].requisition=MaxReq; - } - - requisition->width=requisition->height=2*GTK_CONTAINER(widget)->border_width; - - for (i=0;i<table->ncols;i++) requisition->width+=table->cols[i].requisition; - for (i=0;i<table->ncols-1;i++) requisition->width+=table->cols[i].spacing; - for (i=0;i<table->nrows;i++) requisition->height+=table->rows[i].requisition; - for (i=0;i<table->nrows-1;i++) requisition->height+=table->rows[i].spacing; - -} - -void gtk_table_set_size(GtkWidget *widget,GtkAllocation *allocation) { - GtkTable *table; - gint row_extra=0,col_extra=0,i; - GtkAllocation child_alloc; - GList *children; - GtkTableChild *child; - gint border_width; - - table=GTK_TABLE(widget); - border_width=GTK_CONTAINER(widget)->border_width; - - if (table->ncols) { - col_extra = (allocation->width-widget->requisition.width)/table->ncols; - } - if (table->nrows) { - row_extra = (allocation->height-widget->requisition.height)/table->nrows; - } - for (i=0;i<table->ncols;i++) { - table->cols[i].allocation = table->cols[i].requisition+col_extra; - } - for (i=0;i<table->nrows;i++) { - table->rows[i].allocation = table->rows[i].requisition+row_extra; - } - for (children=table->children;children;children=g_list_next(children)) { - child=(GtkTableChild *)(children->data); - if (!child || !child->widget || - !GTK_WIDGET_VISIBLE(child->widget)) continue; - child_alloc.x = allocation->x+border_width; - child_alloc.y = allocation->y+border_width; - child_alloc.width = child_alloc.height = 0; - for (i=0;i<child->left_attach;i++) { - child_alloc.x+=table->cols[i].allocation+table->cols[i].spacing; + table = GTK_TABLE(GtkNewObject(&GtkTableClass)); + + table->nrows = rows; + table->ncols = cols; + table->homogeneous = homogeneous; + + table->rows = g_new0(GtkTableRowCol, rows); + table->cols = g_new0(GtkTableRowCol, cols); + + return GTK_WIDGET(table); +} + +void gtk_table_resize(GtkTable *table, guint rows, guint cols) +{ + gint i; + + table->rows = g_realloc(table->rows, sizeof(GtkTableRowCol) * rows); + table->cols = g_realloc(table->cols, sizeof(GtkTableRowCol) * cols); + + for (i = table->nrows; i < rows; i++) { + table->rows[i].requisition = 0; + table->rows[i].allocation = 0; + table->rows[i].spacing = table->row_spacing; + } + for (i = table->ncols; i < cols; i++) { + table->cols[i].requisition = 0; + table->cols[i].allocation = 0; + table->cols[i].spacing = table->column_spacing; + } + table->nrows = rows; + table->ncols = cols; + gtk_widget_update(GTK_WIDGET(table), FALSE); +} + +void gtk_table_attach_defaults(GtkTable *table, GtkWidget *widget, + guint left_attach, guint right_attach, + guint top_attach, guint bottom_attach) +{ + gtk_table_attach(table, widget, left_attach, right_attach, top_attach, + bottom_attach, GTK_EXPAND, GTK_EXPAND, 0, 0); +} + +void gtk_table_attach(GtkTable *table, GtkWidget *widget, + guint left_attach, guint right_attach, + guint top_attach, guint bottom_attach, + GtkAttachOptions xoptions, GtkAttachOptions yoptions, + guint xpadding, guint ypadding) +{ + GtkTableChild *newChild; + + newChild = g_new0(GtkTableChild, 1); + + newChild->widget = widget; + newChild->left_attach = left_attach; + newChild->right_attach = right_attach; + newChild->top_attach = top_attach; + newChild->bottom_attach = bottom_attach; + + table->children = g_list_append(table->children, (gpointer)newChild); + widget->parent = GTK_WIDGET(table); + if (GTK_WIDGET_REALIZED(GTK_WIDGET(table))) { + gtk_widget_realize(widget); + gtk_widget_update(GTK_WIDGET(table), TRUE); + } +} + +void gtk_table_destroy(GtkWidget *widget) +{ + GList *children; + GtkTableChild *child; + + gtk_container_destroy(widget); + for (children = GTK_TABLE(widget)->children; children; + children = g_list_next(children)) { + child = (GtkTableChild *)(children->data); + if (child->widget) + gtk_widget_destroy(child->widget); + g_free(child); + } + g_list_free(GTK_TABLE(widget)->children); +} + +void gtk_table_size_request(GtkWidget *widget, GtkRequisition *requisition) +{ + GList *children; + GtkTableChild *child; + GtkWidget *child_wid; + GtkRequisition child_req; + GtkTable *table; + gint16 MaxReq; + int i; + + table = GTK_TABLE(widget); + for (i = 0; i < table->ncols; i++) + table->cols[i].requisition = 0; + for (i = 0; i < table->nrows; i++) + table->rows[i].requisition = 0; + + gtk_container_size_request(widget, requisition); + for (children = table->children; children; + children = g_list_next(children)) { + child = (GtkTableChild *)(children->data); + if (!child) + continue; + child_wid = child->widget; + if (child_wid && child->left_attach < child->right_attach && + child->top_attach < child->bottom_attach && + GTK_WIDGET_VISIBLE(child_wid)) { + child_req.width = child_wid->requisition.width; + child_req.height = child_wid->requisition.height; + child_req.width /= (child->right_attach - child->left_attach); + child_req.height /= (child->bottom_attach - child->top_attach); + for (i = child->left_attach; i < child->right_attach; i++) { + if (child_req.width > table->cols[i].requisition) + table->cols[i].requisition = child_req.width; } - for (i=0;i<child->top_attach;i++) { - child_alloc.y+=table->rows[i].allocation+table->rows[i].spacing; + for (i = child->top_attach; i < child->bottom_attach; i++) { + if (child_req.height > table->rows[i].requisition) + table->rows[i].requisition = child_req.height; } - for (i=child->left_attach;i<child->right_attach;i++) { - child_alloc.width+=table->cols[i].allocation; + } + } + + if (table->homogeneous) { + MaxReq = 0; + for (i = 0; i < table->ncols; i++) + if (table->cols[i].requisition > MaxReq) { + MaxReq = table->cols[i].requisition; } - for (i=child->top_attach;i<child->bottom_attach;i++) { - child_alloc.height+=table->rows[i].allocation; + for (i = 0; i < table->ncols; i++) + table->cols[i].requisition = MaxReq; + + MaxReq = 0; + for (i = 0; i < table->nrows; i++) + if (table->rows[i].requisition > MaxReq) { + MaxReq = table->rows[i].requisition; } - gtk_widget_set_size(child->widget,&child_alloc); - } + for (i = 0; i < table->nrows; i++) + table->rows[i].requisition = MaxReq; + } + + requisition->width = requisition->height = + 2 * GTK_CONTAINER(widget)->border_width; + + for (i = 0; i < table->ncols; i++) + requisition->width += table->cols[i].requisition; + for (i = 0; i < table->ncols - 1; i++) + requisition->width += table->cols[i].spacing; + for (i = 0; i < table->nrows; i++) + requisition->height += table->rows[i].requisition; + for (i = 0; i < table->nrows - 1; i++) + requisition->height += table->rows[i].spacing; + } -void gtk_table_realize(GtkWidget *widget) { - GList *children; - GtkTableChild *child; +void gtk_table_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + GtkTable *table; + gint row_extra = 0, col_extra = 0, i; + GtkAllocation child_alloc; + GList *children; + GtkTableChild *child; + gint border_width; + + table = GTK_TABLE(widget); + border_width = GTK_CONTAINER(widget)->border_width; + + if (table->ncols) { + col_extra = + (allocation->width - widget->requisition.width) / table->ncols; + } + if (table->nrows) { + row_extra = + (allocation->height - widget->requisition.height) / table->nrows; + } + for (i = 0; i < table->ncols; i++) { + table->cols[i].allocation = table->cols[i].requisition + col_extra; + } + for (i = 0; i < table->nrows; i++) { + table->rows[i].allocation = table->rows[i].requisition + row_extra; + } + for (children = table->children; children; + children = g_list_next(children)) { + child = (GtkTableChild *)(children->data); + if (!child || !child->widget || !GTK_WIDGET_VISIBLE(child->widget)) + continue; + child_alloc.x = allocation->x + border_width; + child_alloc.y = allocation->y + border_width; + child_alloc.width = child_alloc.height = 0; + for (i = 0; i < child->left_attach; i++) { + child_alloc.x += table->cols[i].allocation + table->cols[i].spacing; + } + for (i = 0; i < child->top_attach; i++) { + child_alloc.y += table->rows[i].allocation + table->rows[i].spacing; + } + for (i = child->left_attach; i < child->right_attach; i++) { + child_alloc.width += table->cols[i].allocation; + } + for (i = child->top_attach; i < child->bottom_attach; i++) { + child_alloc.height += table->rows[i].allocation; + } + gtk_widget_set_size(child->widget, &child_alloc); + } +} - gtk_container_realize(widget); - for (children=GTK_TABLE(widget)->children;children; - children=g_list_next(children)) { - child=(GtkTableChild *)(children->data); - if (child->widget) gtk_widget_realize(child->widget); - } +void gtk_table_realize(GtkWidget *widget) +{ + GList *children; + GtkTableChild *child; + + gtk_container_realize(widget); + for (children = GTK_TABLE(widget)->children; children; + children = g_list_next(children)) { + child = (GtkTableChild *)(children->data); + if (child->widget) + gtk_widget_realize(child->widget); + } } -void gtk_table_set_row_spacing(GtkTable *table,guint row,guint spacing) { - if (table && row>=0 && row<table->nrows) { - table->rows[row].spacing=spacing; - } +void gtk_table_set_row_spacing(GtkTable *table, guint row, guint spacing) +{ + if (table && row >= 0 && row < table->nrows) { + table->rows[row].spacing = spacing; + } } -void gtk_table_set_col_spacing(GtkTable *table,guint column,guint spacing) { - if (table && column>=0 && column<table->ncols) { - table->cols[column].spacing=spacing; - } +void gtk_table_set_col_spacing(GtkTable *table, guint column, + guint spacing) +{ + if (table && column >= 0 && column < table->ncols) { + table->cols[column].spacing = spacing; + } } -void gtk_table_set_row_spacings(GtkTable *table,guint spacing) { - int i; - table->row_spacing=spacing; - for (i=0;i<table->nrows;i++) table->rows[i].spacing=spacing; +void gtk_table_set_row_spacings(GtkTable *table, guint spacing) +{ + int i; + + table->row_spacing = spacing; + for (i = 0; i < table->nrows; i++) + table->rows[i].spacing = spacing; } -void gtk_table_set_col_spacings(GtkTable *table,guint spacing) { - int i; - table->column_spacing=spacing; - for (i=0;i<table->ncols;i++) table->cols[i].spacing=spacing; +void gtk_table_set_col_spacings(GtkTable *table, guint spacing) +{ + int i; + + table->column_spacing = spacing; + for (i = 0; i < table->ncols; i++) + table->cols[i].spacing = spacing; } -void gtk_toggle_button_toggled(GtkToggleButton *toggle_button) { - toggle_button->toggled = !toggle_button->toggled; - gtk_signal_emit(GTK_OBJECT(toggle_button),"toggled"); +void gtk_toggle_button_toggled(GtkToggleButton *toggle_button) +{ + toggle_button->toggled = !toggle_button->toggled; + gtk_signal_emit(GTK_OBJECT(toggle_button), "toggled"); } -void gtk_check_button_toggled(GtkCheckButton *check_button,gpointer data) { - HWND hWnd; - gboolean is_active = GTK_TOGGLE_BUTTON(check_button)->toggled; - hWnd=GTK_WIDGET(check_button)->hWnd; - if (hWnd) { - SendMessage(hWnd,BM_SETCHECK,is_active ? BST_CHECKED : BST_UNCHECKED,0); - } +void gtk_check_button_toggled(GtkCheckButton *check_button, gpointer data) +{ + HWND hWnd; + gboolean is_active = GTK_TOGGLE_BUTTON(check_button)->toggled; + + hWnd = GTK_WIDGET(check_button)->hWnd; + if (hWnd) { + SendMessage(hWnd, BM_SETCHECK, + is_active ? BST_CHECKED : BST_UNCHECKED, 0); + } } -void gtk_radio_button_clicked(GtkRadioButton *radio_button,gpointer data) { - GtkToggleButton *toggle=GTK_TOGGLE_BUTTON(radio_button); +void gtk_radio_button_clicked(GtkRadioButton *radio_button, gpointer data) +{ + GtkToggleButton *toggle = GTK_TOGGLE_BUTTON(radio_button); - if (toggle->toggled) return; - else gtk_toggle_button_toggled(toggle); + if (toggle->toggled) + return; + else + gtk_toggle_button_toggled(toggle); } -void gtk_radio_button_toggled(GtkRadioButton *radio_button,gpointer data) { - HWND hWnd; - GSList *group; - GtkRadioButton *radio; - gboolean is_active = GTK_TOGGLE_BUTTON(radio_button)->toggled; - hWnd=GTK_WIDGET(radio_button)->hWnd; - if (hWnd) { - SendMessage(hWnd,BM_SETCHECK,is_active ? BST_CHECKED : BST_UNCHECKED,0); - } - if (is_active) { - for (group=radio_button->group;group;group=g_slist_next(group)) { - radio=GTK_RADIO_BUTTON(group->data); - if (radio && radio!=radio_button) { - GTK_TOGGLE_BUTTON(radio)->toggled=FALSE; - hWnd=GTK_WIDGET(radio)->hWnd; - if (hWnd) SendMessage(hWnd,BM_SETCHECK,BST_UNCHECKED,0); - } +void gtk_radio_button_toggled(GtkRadioButton *radio_button, gpointer data) +{ + HWND hWnd; + GSList *group; + GtkRadioButton *radio; + gboolean is_active = GTK_TOGGLE_BUTTON(radio_button)->toggled; + + hWnd = GTK_WIDGET(radio_button)->hWnd; + if (hWnd) { + SendMessage(hWnd, BM_SETCHECK, + is_active ? BST_CHECKED : BST_UNCHECKED, 0); + } + if (is_active) { + for (group = radio_button->group; group; group = g_slist_next(group)) { + radio = GTK_RADIO_BUTTON(group->data); + if (radio && radio != radio_button) { + GTK_TOGGLE_BUTTON(radio)->toggled = FALSE; + hWnd = GTK_WIDGET(radio)->hWnd; + if (hWnd) + SendMessage(hWnd, BM_SETCHECK, BST_UNCHECKED, 0); } - } + } + } } -gboolean gtk_toggle_button_get_active(GtkToggleButton *toggle_button) { - return (toggle_button->toggled); +gboolean gtk_toggle_button_get_active(GtkToggleButton *toggle_button) +{ + return (toggle_button->toggled); } void gtk_toggle_button_set_active(GtkToggleButton *toggle_button, - gboolean is_active) { - if (toggle_button->toggled == is_active) return; - else gtk_toggle_button_toggled(toggle_button); + gboolean is_active) +{ + if (toggle_button->toggled == is_active) + return; + else + gtk_toggle_button_toggled(toggle_button); } -void gtk_main_quit() { - PostQuitMessage(0); +void gtk_main_quit() +{ + PostQuitMessage(0); } -void gtk_main() { - MSG msg; - GSList *list; - BOOL MsgDone; - GtkWidget *widget,*window; - HACCEL hAccel; - - RecurseLevel++; - - while (GetMessage(&msg,NULL,0,0)) { - MsgDone=FALSE; - widget=GTK_WIDGET(GetWindowLong(msg.hwnd,GWL_USERDATA)); - window=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW); - if (window) { - hAccel=GTK_WINDOW(window)->hAccel; - if (hAccel) { - MsgDone=TranslateAccelerator(window->hWnd,hAccel,&msg); - } - } - if (!MsgDone) for (list=WindowList;list && !MsgDone; - list=g_slist_next(list)) { - widget=GTK_WIDGET(list->data); - if (widget && widget->hWnd && - (MsgDone=IsDialogMessage(widget->hWnd,&msg))==TRUE) break; +void gtk_main() +{ + MSG msg; + GSList *list; + BOOL MsgDone; + GtkWidget *widget, *window; + HACCEL hAccel; + + RecurseLevel++; + + while (GetMessage(&msg, NULL, 0, 0)) { + MsgDone = FALSE; + widget = GTK_WIDGET(GetWindowLong(msg.hwnd, GWL_USERDATA)); + window = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); + if (window) { + hAccel = GTK_WINDOW(window)->hAccel; + if (hAccel) { + MsgDone = TranslateAccelerator(window->hWnd, hAccel, &msg); } - if (!MsgDone) { - TranslateMessage(&msg); - DispatchMessage(&msg); + } + if (!MsgDone) + for (list = WindowList; list && !MsgDone; list = g_slist_next(list)) { + widget = GTK_WIDGET(list->data); + if (widget && widget->hWnd + && (MsgDone = IsDialogMessage(widget->hWnd, &msg)) == TRUE) + break; } - } - RecurseLevel--; + if (!MsgDone) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + RecurseLevel--; } typedef struct _GtkSignal GtkSignal; struct _GtkSignal { - GtkSignalFunc func; - GtkObject *slot_object; - gpointer func_data; + GtkSignalFunc func; + GtkObject *slot_object; + gpointer func_data; }; typedef gint (*GtkGIntSignalFunc) (); -void gtk_marshal_BOOL__GINT(GtkObject *object,GSList *actions, - GtkSignalFunc default_action, - va_list args) { - gboolean *retval; - gint arg1; - GtkSignal *signal; - GtkGIntSignalFunc sigfunc; - - arg1=va_arg(args,gint); - retval=va_arg(args,gboolean *); - if (!retval) { g_warning("gtk_marshal_BOOL__GINT: retval NULL"); return; } - - while (actions) { - signal=(GtkSignal*)actions->data; - sigfunc = (GtkGIntSignalFunc)signal->func; - if (signal->slot_object) { - *retval = (*sigfunc)(signal->slot_object,arg1); - } else *retval = (*sigfunc)(object,arg1,signal->func_data); - if (*retval) return; - actions=g_slist_next(actions); - } - sigfunc=(GtkGIntSignalFunc)default_action; - if (sigfunc) *retval = (*sigfunc)(object,arg1); -} - -void gtk_marshal_BOOL__GPOIN(GtkObject *object,GSList *actions, - GtkSignalFunc default_action, - va_list args) { - gboolean *retval; - gpointer arg1; - GtkSignal *signal; - GtkGIntSignalFunc sigfunc; - - arg1=va_arg(args,gpointer); - retval=va_arg(args,gboolean *); - if (!retval) { g_warning("gtk_marshal_BOOL__GPOIN: retval NULL"); return; } - - while (actions) { - signal=(GtkSignal*)actions->data; - sigfunc = (GtkGIntSignalFunc)signal->func; - if (signal->slot_object) { - *retval = (*sigfunc)(signal->slot_object,arg1); - } else *retval = (*sigfunc)(object,arg1,signal->func_data); - if (*retval) return; - actions=g_slist_next(actions); - } - sigfunc=(GtkGIntSignalFunc)default_action; - if (sigfunc) *retval = (*sigfunc)(object,arg1); -} - -void gtk_marshal_VOID__VOID(GtkObject *object,GSList *actions, - GtkSignalFunc default_action, - va_list args) { - GtkSignal *signal; - - while (actions) { -// g_print("processing action...\n"); - signal=(GtkSignal*)actions->data; - if (signal->slot_object) { - (*signal->func)(signal->slot_object); - } else (*signal->func)(object,signal->func_data); - actions=g_slist_next(actions); - } - if (default_action) (*default_action)(object); -} - -void gtk_marshal_VOID__GINT(GtkObject *object,GSList *actions, - GtkSignalFunc default_action, - va_list args) { - gint arg1; - GtkSignal *signal; - - arg1=va_arg(args,gint); - - while (actions) { - signal=(GtkSignal*)actions->data; - if (signal->slot_object) { - (*signal->func)(signal->slot_object,arg1); - } else (*signal->func)(object,arg1,signal->func_data); - actions=g_slist_next(actions); - } - if (default_action) (*default_action)(object,arg1); -} - -void gtk_marshal_VOID__GPOIN(GtkObject *object,GSList *actions, - GtkSignalFunc default_action, - va_list args) { - gpointer arg1; - GtkSignal *signal; - - arg1=va_arg(args,gpointer); - - while (actions) { - signal=(GtkSignal*)actions->data; - if (signal->slot_object) { - (*signal->func)(signal->slot_object,arg1); - } else (*signal->func)(object,arg1,signal->func_data); - actions=g_slist_next(actions); - } - if (default_action) (*default_action)(object,arg1); -} - -void gtk_marshal_VOID__BOOL(GtkObject *object,GSList *actions, - GtkSignalFunc default_action, - va_list args) { - gboolean arg1; - GtkSignal *signal; - - arg1=va_arg(args,gboolean); - - while (actions) { - signal=(GtkSignal*)actions->data; - if (signal->slot_object) { - (*signal->func)(signal->slot_object,arg1); - } else (*signal->func)(object,arg1,signal->func_data); - actions=g_slist_next(actions); - } - if (default_action) (*default_action)(object,arg1); +void gtk_marshal_BOOL__GINT(GtkObject *object, GSList *actions, + GtkSignalFunc default_action, va_list args) +{ + gboolean *retval; + gint arg1; + GtkSignal *signal; + GtkGIntSignalFunc sigfunc; + + arg1 = va_arg(args, gint); + retval = va_arg(args, gboolean *); + + if (!retval) { + g_warning("gtk_marshal_BOOL__GINT: retval NULL"); + return; + } + + while (actions) { + signal = (GtkSignal *)actions->data; + sigfunc = (GtkGIntSignalFunc)signal->func; + if (signal->slot_object) { + *retval = (*sigfunc) (signal->slot_object, arg1); + } else + *retval = (*sigfunc) (object, arg1, signal->func_data); + if (*retval) + return; + actions = g_slist_next(actions); + } + sigfunc = (GtkGIntSignalFunc)default_action; + if (sigfunc) + *retval = (*sigfunc) (object, arg1); +} + +void gtk_marshal_BOOL__GPOIN(GtkObject *object, GSList *actions, + GtkSignalFunc default_action, va_list args) +{ + gboolean *retval; + gpointer arg1; + GtkSignal *signal; + GtkGIntSignalFunc sigfunc; + + arg1 = va_arg(args, gpointer); + retval = va_arg(args, gboolean *); + + if (!retval) { + g_warning("gtk_marshal_BOOL__GPOIN: retval NULL"); + return; + } + + while (actions) { + signal = (GtkSignal *)actions->data; + sigfunc = (GtkGIntSignalFunc)signal->func; + if (signal->slot_object) { + *retval = (*sigfunc) (signal->slot_object, arg1); + } else + *retval = (*sigfunc) (object, arg1, signal->func_data); + if (*retval) + return; + actions = g_slist_next(actions); + } + sigfunc = (GtkGIntSignalFunc)default_action; + if (sigfunc) + *retval = (*sigfunc) (object, arg1); +} + +void gtk_marshal_VOID__VOID(GtkObject *object, GSList *actions, + GtkSignalFunc default_action, va_list args) +{ + GtkSignal *signal; + + while (actions) { + signal = (GtkSignal *)actions->data; + if (signal->slot_object) { + (*signal->func) (signal->slot_object); + } else + (*signal->func) (object, signal->func_data); + actions = g_slist_next(actions); + } + if (default_action) + (*default_action) (object); +} + +void gtk_marshal_VOID__GINT(GtkObject *object, GSList *actions, + GtkSignalFunc default_action, va_list args) +{ + gint arg1; + GtkSignal *signal; + + arg1 = va_arg(args, gint); + + while (actions) { + signal = (GtkSignal *)actions->data; + if (signal->slot_object) { + (*signal->func) (signal->slot_object, arg1); + } else + (*signal->func) (object, arg1, signal->func_data); + actions = g_slist_next(actions); + } + if (default_action) + (*default_action) (object, arg1); +} + +void gtk_marshal_VOID__GPOIN(GtkObject *object, GSList *actions, + GtkSignalFunc default_action, va_list args) +{ + gpointer arg1; + GtkSignal *signal; + + arg1 = va_arg(args, gpointer); + + while (actions) { + signal = (GtkSignal *)actions->data; + if (signal->slot_object) { + (*signal->func) (signal->slot_object, arg1); + } else + (*signal->func) (object, arg1, signal->func_data); + actions = g_slist_next(actions); + } + if (default_action) + (*default_action) (object, arg1); +} + +void gtk_marshal_VOID__BOOL(GtkObject *object, GSList *actions, + GtkSignalFunc default_action, va_list args) +{ + gboolean arg1; + GtkSignal *signal; + + arg1 = va_arg(args, gboolean); + + while (actions) { + signal = (GtkSignal *)actions->data; + if (signal->slot_object) { + (*signal->func) (signal->slot_object, arg1); + } else + (*signal->func) (object, arg1, signal->func_data); + actions = g_slist_next(actions); + } + if (default_action) + (*default_action) (object, arg1); } static GtkSignalType *gtk_get_signal_type(GtkObject *object, - const gchar *name) { - GtkClass *klass; - GtkSignalType *signals; - - for (klass=object->klass;klass;klass=klass->parent) { -/* g_print("Searching for signal %s in class %s\n",name,klass->Name);*/ - for (signals=klass->signals;signals && signals->name[0];signals++) { - if (strcmp(signals->name,name)==0) return signals; - } - } - return NULL; -} - -void gtk_signal_emit(GtkObject *object,const gchar *name, ...) { - GSList *signal_list; - GtkSignalType *signal_type; - va_list ap; - -/* g_print("gtk_signal_emit of signal %s on object %p, type %p\n", - name,object,object->klass);*/ - - if (!object) return; - -// g_print("Initialising va_list\n"); - va_start(ap,name); -// g_print("Getting signal list\n"); - signal_list=(GSList *)g_datalist_get_data(&object->signals,name); -// g_print("Getting signal list %p\n",signal_list); - signal_type=gtk_get_signal_type(object,name); -// g_print("Getting signal type %p\n",signal_type); - if (signal_type && signal_type->marshaller) { -/* g_print("Calling marshaller %p with signal_list %p\n", - signal_type->marshaller,signal_list);*/ - (*signal_type->marshaller)(object,signal_list, - signal_type->default_action,ap); - } - va_end(ap); - if (!signal_type) g_warning("gtk_signal_emit: unknown signal %s",name); -// g_print("Signal emission done\n"); -} - -guint gtk_signal_connect(GtkObject *object,const gchar *name, - GtkSignalFunc func,gpointer func_data) { - GtkSignal *signal; - GtkSignalType *signal_type; - GSList *signal_list; - -// g_print("Attempting to connect signal %s to object %p\n",name,object); - if (!object) return 0; - signal_type=gtk_get_signal_type(object,name); - if (!signal_type) { - g_warning("gtk_signal_connect: unknown signal %s",name); - return 0; - } - signal_list=(GSList *)g_datalist_get_data(&object->signals,name); - signal=g_new0(GtkSignal,1); - signal->func=func; signal->func_data=func_data; - signal_list=g_slist_append(signal_list,signal); - g_datalist_set_data(&object->signals,name,signal_list); - return 0; -} - -guint gtk_signal_connect_object(GtkObject *object,const gchar *name, - GtkSignalFunc func,GtkObject *slot_object) { - GtkSignal *signal; - GtkSignalType *signal_type; - GSList *signal_list; - - if (!object) return 0; - signal_type=gtk_get_signal_type(object,name); - if (!signal_type) { - g_warning("gtk_signal_connect_object: unknown signal %s",name); - return 0; - } - signal_list=(GSList *)g_datalist_get_data(&object->signals,name); - signal=g_new0(GtkSignal,1); - signal->func=func; signal->slot_object=slot_object; - signal_list=g_slist_append(signal_list,signal); - g_datalist_set_data(&object->signals,name,signal_list); - return 0; + const gchar *name) +{ + GtkClass *klass; + GtkSignalType *signals; + + for (klass = object->klass; klass; klass = klass->parent) { + for (signals = klass->signals; signals && signals->name[0]; signals++) { + if (strcmp(signals->name, name) == 0) + return signals; + } + } + return NULL; } -GtkItemFactory *gtk_item_factory_new(GtkType container_type, - const gchar *path, - GtkAccelGroup *accel_group) { - GtkItemFactory *new_fac; - new_fac=(GtkItemFactory *)GtkNewObject(&GtkItemFactoryClass); - new_fac->path=g_strdup(path); - new_fac->accel_group = accel_group; - new_fac->top_widget=gtk_menu_bar_new(); - new_fac->translate_func=NULL; - return new_fac; +void gtk_signal_emit(GtkObject *object, const gchar *name, ...) +{ + GSList *signal_list; + GtkSignalType *signal_type; + va_list ap; + + if (!object) + return; + + va_start(ap, name); + signal_list = (GSList *)g_datalist_get_data(&object->signals, name); + signal_type = gtk_get_signal_type(object, name); + if (signal_type && signal_type->marshaller) { + (*signal_type->marshaller) (object, signal_list, + signal_type->default_action, ap); + } + va_end(ap); + if (!signal_type) + g_warning("gtk_signal_emit: unknown signal %s", name); } -static gint PathCmp(const gchar *path1,const gchar *path2) { - gint Match=1; +guint gtk_signal_connect(GtkObject *object, const gchar *name, + GtkSignalFunc func, gpointer func_data) +{ + GtkSignal *signal; + GtkSignalType *signal_type; + GSList *signal_list; + + if (!object) + return 0; + signal_type = gtk_get_signal_type(object, name); + if (!signal_type) { + g_warning("gtk_signal_connect: unknown signal %s", name); + return 0; + } + signal_list = (GSList *)g_datalist_get_data(&object->signals, name); + signal = g_new0(GtkSignal, 1); - if (!path1 || !path2) return 0; + signal->func = func; + signal->func_data = func_data; + signal_list = g_slist_append(signal_list, signal); + g_datalist_set_data(&object->signals, name, signal_list); + return 0; +} - while (*path1 && *path2 && Match) { - while (*path1=='_') path1++; - while (*path2=='_') path2++; - if (*path1==*path2) { path1++; path2++; } - else Match=0; - } - if (*path1 || *path2) Match=0; - return Match; +guint gtk_signal_connect_object(GtkObject *object, const gchar *name, + GtkSignalFunc func, GtkObject *slot_object) +{ + GtkSignal *signal; + GtkSignalType *signal_type; + GSList *signal_list; + + if (!object) + return 0; + signal_type = gtk_get_signal_type(object, name); + if (!signal_type) { + g_warning("gtk_signal_connect_object: unknown signal %s", name); + return 0; + } + signal_list = (GSList *)g_datalist_get_data(&object->signals, name); + signal = g_new0(GtkSignal, 1); + + signal->func = func; + signal->slot_object = slot_object; + signal_list = g_slist_append(signal_list, signal); + g_datalist_set_data(&object->signals, name, signal_list); + return 0; } -static gchar *TransPath(GtkItemFactory *ifactory,gchar *path) { - gchar *transpath=NULL; +GtkItemFactory *gtk_item_factory_new(GtkType container_type, + const gchar *path, + GtkAccelGroup *accel_group) +{ + GtkItemFactory *new_fac; + + new_fac = (GtkItemFactory *)GtkNewObject(&GtkItemFactoryClass); + new_fac->path = g_strdup(path); + new_fac->accel_group = accel_group; + new_fac->top_widget = gtk_menu_bar_new(); + new_fac->translate_func = NULL; + return new_fac; +} + +static gint PathCmp(const gchar *path1, const gchar *path2) +{ + gint Match = 1; + + if (!path1 || !path2) + return 0; + + while (*path1 && *path2 && Match) { + while (*path1 == '_') + path1++; + while (*path2 == '_') + path2++; + if (*path1 == *path2) { + path1++; + path2++; + } else + Match = 0; + } + if (*path1 || *path2) + Match = 0; + return Match; +} + +static gchar *TransPath(GtkItemFactory *ifactory, gchar *path) +{ + gchar *transpath = NULL; if (ifactory->translate_func) { - transpath = (*ifactory->translate_func)(path,ifactory->translate_data); + transpath = + (*ifactory->translate_func) (path, ifactory->translate_data); } return transpath ? transpath : path; t@@ -3371,24 +3773,28 @@ static gchar *TransPath(GtkItemFactory *ifactory,gchar *path) { static void gtk_item_factory_parse_path(GtkItemFactory *ifactory, gchar *path, GtkItemFactoryChild **parent, - GString *menu_title) { + GString *menu_title) +{ GSList *list; GtkItemFactoryChild *child; - gchar *root,*pt,*transpath; - - transpath = TransPath(ifactory,path); - pt=strrchr(transpath,'/'); - if (pt) g_string_assign(menu_title,pt+1); - - pt=strrchr(path,'/'); - if (!pt) return; - root=g_strdup(path); - root[pt-path]='\0'; - - for (list=ifactory->children;list;list=g_slist_next(list)) { - child=(GtkItemFactoryChild *)list->data; - if (PathCmp(child->path,root)==1) { - *parent=child; break; + gchar *root, *pt, *transpath; + + transpath = TransPath(ifactory, path); + pt = strrchr(transpath, '/'); + if (pt) + g_string_assign(menu_title, pt + 1); + + pt = strrchr(path, '/'); + if (!pt) + return; + root = g_strdup(path); + root[pt - path] = '\0'; + + for (list = ifactory->children; list; list = g_slist_next(list)) { + child = (GtkItemFactoryChild *)list->data; + if (PathCmp(child->path, root) == 1) { + *parent = child; + break; } } g_free(root); t@@ -3396,672 +3802,800 @@ static void gtk_item_factory_parse_path(GtkItemFactory *ifactory, static gboolean gtk_item_factory_parse_accel(GtkItemFactory *ifactory, gchar *accelerator, - GString *menu_title,ACCEL *accel) { + GString *menu_title, + ACCEL *accel) +{ gchar *apt; - if (!accelerator) return FALSE; + if (!accelerator) + return FALSE; - apt=accelerator; - accel->fVirt=0; - accel->key=0; - accel->cmd=0; + apt = accelerator; + accel->fVirt = 0; + accel->key = 0; + accel->cmd = 0; - g_string_append(menu_title,"\t"); + g_string_append(menu_title, "\t"); - if (strncmp(apt,"<control>",9)==0) { + if (strncmp(apt, "<control>", 9) == 0) { accel->fVirt |= FCONTROL; - g_string_append(menu_title,"Ctrl+"); - apt+=9; + g_string_append(menu_title, "Ctrl+"); + apt += 9; } - if (strlen(apt)==1) { - g_string_append_c(menu_title,*apt); + if (strlen(apt) == 1) { + g_string_append_c(menu_title, *apt); accel->key = *apt; accel->fVirt |= FVIRTKEY; - } else if (strcmp(apt,"F1")==0) { - g_string_append(menu_title,apt); + } else if (strcmp(apt, "F1") == 0) { + g_string_append(menu_title, apt); accel->fVirt |= FVIRTKEY; accel->key = VK_F1; } - return (accel->key!=0); + return (accel->key != 0); } void gtk_item_factory_create_item(GtkItemFactory *ifactory, GtkItemFactoryEntry *entry, - gpointer callback_data,guint callback_type) { - GtkItemFactoryChild *new_child,*parent=NULL; - GString *menu_title; - GtkWidget *menu_item,*menu; - ACCEL accel; - gboolean haveaccel; - - new_child=g_new0(GtkItemFactoryChild,1); - new_child->path=g_strdup(entry->path); - - menu_title = g_string_new(""); - - gtk_item_factory_parse_path(ifactory,new_child->path,&parent,menu_title); - haveaccel = gtk_item_factory_parse_accel(ifactory,entry->accelerator, - menu_title,&accel); - - menu_item=gtk_menu_item_new_with_label(menu_title->str); - new_child->widget=menu_item; - if (entry->callback) { - gtk_signal_connect(GTK_OBJECT(menu_item),"activate", - entry->callback,callback_data); - } - - if (parent) { - menu=GTK_WIDGET(GTK_MENU_ITEM(parent->widget)->submenu); - if (!menu) { - menu=gtk_menu_new(); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent->widget),menu); - } - gtk_menu_append(GTK_MENU(menu),menu_item); - } else { - gtk_menu_bar_append(GTK_MENU_BAR(ifactory->top_widget),menu_item); - } - - if (haveaccel && ifactory->accel_group) { - GTK_MENU_ITEM(menu_item)->accelind= - gtk_accel_group_add(ifactory->accel_group,&accel); - } - - g_string_free(menu_title,TRUE); - - ifactory->children=g_slist_append(ifactory->children,new_child); -} - -void gtk_item_factory_create_items(GtkItemFactory *ifactory,guint n_entries, + gpointer callback_data, + guint callback_type) +{ + GtkItemFactoryChild *new_child, *parent = NULL; + GString *menu_title; + GtkWidget *menu_item, *menu; + ACCEL accel; + gboolean haveaccel; + + new_child = g_new0(GtkItemFactoryChild, 1); + + new_child->path = g_strdup(entry->path); + + menu_title = g_string_new(""); + + gtk_item_factory_parse_path(ifactory, new_child->path, &parent, + menu_title); + haveaccel = + gtk_item_factory_parse_accel(ifactory, entry->accelerator, + menu_title, &accel); + + menu_item = gtk_menu_item_new_with_label(menu_title->str); + new_child->widget = menu_item; + if (entry->callback) { + gtk_signal_connect(GTK_OBJECT(menu_item), "activate", + entry->callback, callback_data); + } + + if (parent) { + menu = GTK_WIDGET(GTK_MENU_ITEM(parent->widget)->submenu); + if (!menu) { + menu = gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent->widget), menu); + } + gtk_menu_append(GTK_MENU(menu), menu_item); + } else { + gtk_menu_bar_append(GTK_MENU_BAR(ifactory->top_widget), menu_item); + } + + if (haveaccel && ifactory->accel_group) { + GTK_MENU_ITEM(menu_item)->accelind = + gtk_accel_group_add(ifactory->accel_group, &accel); + } + + g_string_free(menu_title, TRUE); + + ifactory->children = g_slist_append(ifactory->children, new_child); +} + +void gtk_item_factory_create_items(GtkItemFactory *ifactory, + guint n_entries, GtkItemFactoryEntry *entries, - gpointer callback_data) { - gint i; - for (i=0;i<n_entries;i++) { - gtk_item_factory_create_item(ifactory,&entries[i],callback_data,0); - } + gpointer callback_data) +{ + gint i; + + for (i = 0; i < n_entries; i++) { + gtk_item_factory_create_item(ifactory, &entries[i], callback_data, 0); + } } GtkWidget *gtk_item_factory_get_widget(GtkItemFactory *ifactory, - const gchar *path) { - gint root_len; - GSList *list; - GtkItemFactoryChild *child; + const gchar *path) +{ + gint root_len; + GSList *list; + GtkItemFactoryChild *child; - root_len=strlen(ifactory->path); - if (!path || strlen(path)<root_len) return NULL; + root_len = strlen(ifactory->path); + if (!path || strlen(path) < root_len) + return NULL; - if (strncmp(ifactory->path,path,root_len)!=0) return NULL; - if (strlen(path)==root_len) return ifactory->top_widget; + if (strncmp(ifactory->path, path, root_len) != 0) + return NULL; + if (strlen(path) == root_len) + return ifactory->top_widget; - for (list=ifactory->children;list;list=g_slist_next(list)) { - child=(GtkItemFactoryChild *)list->data; - if (PathCmp(child->path,&path[root_len])==1) return child->widget; - } - return NULL; + for (list = ifactory->children; list; list = g_slist_next(list)) { + child = (GtkItemFactoryChild *)list->data; + if (PathCmp(child->path, &path[root_len]) == 1) + return child->widget; + } + return NULL; } -void gtk_menu_shell_insert(GtkMenuShell *menu_shell,GtkWidget *child, - gint position) { - menu_shell->children=g_slist_insert(menu_shell->children,(gpointer)child, - position); - child->parent=GTK_WIDGET(menu_shell); +void gtk_menu_shell_insert(GtkMenuShell *menu_shell, GtkWidget *child, + gint position) +{ + menu_shell->children = + g_slist_insert(menu_shell->children, (gpointer)child, position); + child->parent = GTK_WIDGET(menu_shell); } -void gtk_menu_shell_append(GtkMenuShell *menu_shell,GtkWidget *child) { - gtk_menu_shell_insert(menu_shell,child,-1); +void gtk_menu_shell_append(GtkMenuShell *menu_shell, GtkWidget *child) +{ + gtk_menu_shell_insert(menu_shell, child, -1); } -void gtk_menu_shell_prepend(GtkMenuShell *menu_shell,GtkWidget *child) { - gtk_menu_shell_insert(menu_shell,child,0); +void gtk_menu_shell_prepend(GtkMenuShell *menu_shell, GtkWidget *child) +{ + gtk_menu_shell_insert(menu_shell, child, 0); } -GtkWidget *gtk_menu_bar_new() { - GtkMenuBar *menu_bar; - menu_bar=GTK_MENU_BAR(GtkNewObject(&GtkMenuBarClass)); - return GTK_WIDGET(menu_bar); +GtkWidget *gtk_menu_bar_new() +{ + GtkMenuBar *menu_bar; + + menu_bar = GTK_MENU_BAR(GtkNewObject(&GtkMenuBarClass)); + return GTK_WIDGET(menu_bar); } -void gtk_menu_bar_insert(GtkMenuBar *menu_bar,GtkWidget *child,gint position) { - gtk_menu_shell_insert(GTK_MENU_SHELL(menu_bar),child,position); +void gtk_menu_bar_insert(GtkMenuBar *menu_bar, GtkWidget *child, + gint position) +{ + gtk_menu_shell_insert(GTK_MENU_SHELL(menu_bar), child, position); } -void gtk_menu_bar_append(GtkMenuBar *menu_bar,GtkWidget *child) { - gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar),child); +void gtk_menu_bar_append(GtkMenuBar *menu_bar, GtkWidget *child) +{ + gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), child); } -void gtk_menu_bar_prepend(GtkMenuBar *menu_bar,GtkWidget *child) { - gtk_menu_shell_prepend(GTK_MENU_SHELL(menu_bar),child); +void gtk_menu_bar_prepend(GtkMenuBar *menu_bar, GtkWidget *child) +{ + gtk_menu_shell_prepend(GTK_MENU_SHELL(menu_bar), child); } -GtkWidget *gtk_menu_new() { - GtkMenu *menu; - menu=GTK_MENU(GtkNewObject(&GtkMenuClass)); - return GTK_WIDGET(menu); +GtkWidget *gtk_menu_new() +{ + GtkMenu *menu; + + menu = GTK_MENU(GtkNewObject(&GtkMenuClass)); + return GTK_WIDGET(menu); } -void gtk_menu_insert(GtkMenu *menu,GtkWidget *child,gint position) { - gtk_menu_shell_insert(GTK_MENU_SHELL(menu),child,position); +void gtk_menu_insert(GtkMenu *menu, GtkWidget *child, gint position) +{ + gtk_menu_shell_insert(GTK_MENU_SHELL(menu), child, position); } -void gtk_menu_append(GtkMenu *menu,GtkWidget *child) { - gtk_menu_shell_append(GTK_MENU_SHELL(menu),child); +void gtk_menu_append(GtkMenu *menu, GtkWidget *child) +{ + gtk_menu_shell_append(GTK_MENU_SHELL(menu), child); } -void gtk_menu_prepend(GtkMenu *menu,GtkWidget *child) { - gtk_menu_shell_prepend(GTK_MENU_SHELL(menu),child); +void gtk_menu_prepend(GtkMenu *menu, GtkWidget *child) +{ + gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), child); } -GtkWidget *gtk_menu_item_new_with_label(const gchar *label) { - GtkMenuItem *menu_item; - gint i; +GtkWidget *gtk_menu_item_new_with_label(const gchar *label) +{ + GtkMenuItem *menu_item; + gint i; + + menu_item = GTK_MENU_ITEM(GtkNewObject(&GtkMenuItemClass)); + menu_item->accelind = -1; + menu_item->text = g_strdup(label); + for (i = 0; i < strlen(menu_item->text); i++) { + if (menu_item->text[i] == '_') + menu_item->text[i] = '&'; + } + return GTK_WIDGET(menu_item); +} - menu_item=GTK_MENU_ITEM(GtkNewObject(&GtkMenuItemClass)); - menu_item->accelind=-1; - menu_item->text=g_strdup(label); - for (i=0;i<strlen(menu_item->text);i++) { - if (menu_item->text[i]=='_') menu_item->text[i]='&'; - } - return GTK_WIDGET(menu_item); +void gtk_menu_item_set_submenu(GtkMenuItem *menu_item, GtkWidget *submenu) +{ + menu_item->submenu = GTK_MENU(submenu); + submenu->parent = GTK_WIDGET(menu_item); } -void gtk_menu_item_set_submenu(GtkMenuItem *menu_item,GtkWidget *submenu) { - menu_item->submenu=GTK_MENU(submenu); - submenu->parent=GTK_WIDGET(menu_item); +static GtkWidget *gtk_menu_item_get_menu_ID(GtkMenuItem *menu_item, + gint ID) +{ + if (menu_item->ID == ID) { + return GTK_WIDGET(menu_item); + } else if (menu_item->submenu) { + return gtk_menu_shell_get_menu_ID(GTK_MENU_SHELL(menu_item->submenu), + ID); + } else + return NULL; } -static GtkWidget *gtk_menu_item_get_menu_ID(GtkMenuItem *menu_item,gint ID) { - if (menu_item->ID==ID) { - return GTK_WIDGET(menu_item); - } else if (menu_item->submenu) { - return gtk_menu_shell_get_menu_ID(GTK_MENU_SHELL(menu_item->submenu),ID); - } else return NULL; +GtkWidget *gtk_menu_shell_get_menu_ID(GtkMenuShell *menu_shell, gint ID) +{ + GSList *list; + GtkWidget *menu_item; + + for (list = menu_shell->children; list; list = list->next) { + menu_item = gtk_menu_item_get_menu_ID(GTK_MENU_ITEM(list->data), ID); + if (menu_item) + return menu_item; + } + return NULL; } -GtkWidget *gtk_menu_shell_get_menu_ID(GtkMenuShell *menu_shell,gint ID) { - GSList *list; - GtkWidget *menu_item; - for (list=menu_shell->children;list;list=list->next) { - menu_item=gtk_menu_item_get_menu_ID(GTK_MENU_ITEM(list->data),ID); - if (menu_item) return menu_item; - } - return NULL; +GtkWidget *gtk_window_get_menu_ID(GtkWindow *window, gint ID) +{ + if (window->menu_bar) { + return gtk_menu_shell_get_menu_ID(GTK_MENU_SHELL(window->menu_bar), + ID); + } else + return NULL; } -GtkWidget *gtk_window_get_menu_ID(GtkWindow *window,gint ID) { - if (window->menu_bar) { - return gtk_menu_shell_get_menu_ID(GTK_MENU_SHELL(window->menu_bar),ID); - } else return NULL; +void gtk_menu_bar_realize(GtkWidget *widget) +{ + GtkMenuBar *menu_bar = GTK_MENU_BAR(widget); + GtkWidget *window; + HMENU hMenu; + + hMenu = GTK_MENU_SHELL(widget)->menu = CreateMenu(); + menu_bar->LastID = 1000; + + gtk_menu_shell_realize(widget); + + window = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); + gtk_window_set_menu(GTK_WINDOW(window), menu_bar); } -void gtk_menu_bar_realize(GtkWidget *widget) { - GtkMenuBar *menu_bar=GTK_MENU_BAR(widget); - GtkWidget *window; - HMENU hMenu; +void gtk_menu_item_realize(GtkWidget *widget) +{ + GtkMenuItem *menu_item = GTK_MENU_ITEM(widget); + MENUITEMINFO mii; + GtkWidget *menu_bar, *window; + HMENU parent_menu; + gint pos; + + menu_bar = gtk_widget_get_ancestor(widget, GTK_TYPE_MENU_BAR); + if (menu_bar) + menu_item->ID = GTK_MENU_BAR(menu_bar)->LastID++; + + if (menu_item->accelind >= 0) { + window = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); + if (window && GTK_WINDOW(window)->accel_group) { + gtk_accel_group_set_id(GTK_WINDOW(window)->accel_group, + menu_item->accelind, menu_item->ID); + } + } + + if (menu_item->submenu) + gtk_widget_realize(GTK_WIDGET(menu_item->submenu)); - hMenu=GTK_MENU_SHELL(widget)->menu=CreateMenu(); - menu_bar->LastID=1000; + parent_menu = GTK_MENU_SHELL(widget->parent)->menu; + pos = g_slist_index(GTK_MENU_SHELL(widget->parent)->children, widget); - gtk_menu_shell_realize(widget); + mii.cbSize = sizeof(MENUITEMINFO); + mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; + if (menu_item->submenu) { + mii.fMask |= MIIM_SUBMENU; + mii.hSubMenu = GTK_MENU_SHELL(menu_item->submenu)->menu; + } + mii.fType = MFT_STRING; + if (GTK_WIDGET_SENSITIVE(widget)) + mii.fState = MFS_ENABLED; + else + mii.fState = MFS_GRAYED; + mii.wID = menu_item->ID; + mii.dwTypeData = (LPTSTR)menu_item->text; + mii.cch = strlen(menu_item->text); + InsertMenuItem(parent_menu, pos, TRUE, &mii); +} + +void gtk_menu_realize(GtkWidget *widget) +{ + GTK_MENU_SHELL(widget)->menu = CreatePopupMenu(); + gtk_menu_shell_realize(widget); +} - window=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW); - gtk_window_set_menu(GTK_WINDOW(window),menu_bar); +void gtk_menu_set_active(GtkMenu *menu, guint index) +{ + menu->active = index; } -void gtk_menu_item_realize(GtkWidget *widget) { - GtkMenuItem *menu_item=GTK_MENU_ITEM(widget); - MENUITEMINFO mii; - GtkWidget *menu_bar,*window; - HMENU parent_menu; - gint pos; +void gtk_menu_shell_realize(GtkWidget *widget) +{ + GSList *children; + GtkMenuShell *menu = GTK_MENU_SHELL(widget); + + for (children = menu->children; children; + children = g_slist_next(children)) { + gtk_widget_realize(GTK_WIDGET(children->data)); + } +} - menu_bar=gtk_widget_get_ancestor(widget,GTK_TYPE_MENU_BAR); - if (menu_bar) menu_item->ID=GTK_MENU_BAR(menu_bar)->LastID++; +void gtk_menu_item_enable(GtkWidget *widget) +{ + GtkWidget *parent; + HMENU hMenu; + HWND hWnd; + + parent = widget->parent; + if (!parent) + return; + hMenu = GTK_MENU_SHELL(parent)->menu; + if (hMenu) + EnableMenuItem(hMenu, GTK_MENU_ITEM(widget)->ID, + MF_BYCOMMAND | MF_ENABLED); + hWnd = gtk_get_parent_hwnd(widget); + if (hWnd) + DrawMenuBar(hWnd); +} + +void gtk_menu_item_disable(GtkWidget *widget) +{ + GtkWidget *parent; + HMENU hMenu; + HWND hWnd; + + parent = widget->parent; + if (!parent) + return; + hMenu = GTK_MENU_SHELL(parent)->menu; + if (hMenu) + EnableMenuItem(hMenu, GTK_MENU_ITEM(widget)->ID, + MF_BYCOMMAND | MF_GRAYED); + hWnd = gtk_get_parent_hwnd(widget); + if (hWnd) + DrawMenuBar(hWnd); +} + +GtkWidget *gtk_notebook_new() +{ + GtkNotebook *notebook; - if (menu_item->accelind>=0) { - window=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW); - if (window && GTK_WINDOW(window)->accel_group) { - gtk_accel_group_set_id(GTK_WINDOW(window)->accel_group, - menu_item->accelind,menu_item->ID); - } - } + notebook = GTK_NOTEBOOK(GtkNewObject(&GtkNotebookClass)); + return GTK_WIDGET(notebook); +} - if (menu_item->submenu) gtk_widget_realize(GTK_WIDGET(menu_item->submenu)); +void gtk_notebook_append_page(GtkNotebook *notebook, GtkWidget *child, + GtkWidget *tab_label) +{ + gtk_notebook_insert_page(notebook, child, tab_label, -1); +} - parent_menu=GTK_MENU_SHELL(widget->parent)->menu; - pos=g_slist_index(GTK_MENU_SHELL(widget->parent)->children,widget); +void gtk_notebook_insert_page(GtkNotebook *notebook, GtkWidget *child, + GtkWidget *tab_label, gint position) +{ + GtkNotebookChild *note_child; + note_child = g_new0(GtkNotebookChild, 1); - mii.cbSize=sizeof(MENUITEMINFO); - mii.fMask=MIIM_TYPE|MIIM_ID|MIIM_STATE; - if (menu_item->submenu) { - mii.fMask|=MIIM_SUBMENU; - mii.hSubMenu=GTK_MENU_SHELL(menu_item->submenu)->menu; - } - mii.fType=MFT_STRING; - if (GTK_WIDGET_SENSITIVE(widget)) mii.fState=MFS_ENABLED; - else mii.fState=MFS_GRAYED; - mii.wID=menu_item->ID; - mii.dwTypeData=(LPTSTR)menu_item->text; - mii.cch=strlen(menu_item->text); - InsertMenuItem(parent_menu,pos,TRUE,&mii); + note_child->child = child; + note_child->tab_label = tab_label; + notebook->children = + g_slist_insert(notebook->children, note_child, position); + child->parent = GTK_WIDGET(notebook); } -void gtk_menu_realize(GtkWidget *widget) { - GTK_MENU_SHELL(widget)->menu=CreatePopupMenu(); - gtk_menu_shell_realize(widget); -} - -void gtk_menu_set_active(GtkMenu *menu,guint index) { - menu->active=index; -} - -void gtk_menu_shell_realize(GtkWidget *widget) { - GSList *children; - GtkMenuShell *menu=GTK_MENU_SHELL(widget); - for (children=menu->children;children;children=g_slist_next(children)) { - gtk_widget_realize(GTK_WIDGET(children->data)); - } -} - -void gtk_menu_item_enable(GtkWidget *widget) { - GtkWidget *parent; - HMENU hMenu; - HWND hWnd; - parent=widget->parent; - if (!parent) return; - hMenu=GTK_MENU_SHELL(parent)->menu; - if (hMenu) EnableMenuItem(hMenu,GTK_MENU_ITEM(widget)->ID, - MF_BYCOMMAND|MF_ENABLED); - hWnd=gtk_get_parent_hwnd(widget); - if (hWnd) DrawMenuBar(hWnd); -} - -void gtk_menu_item_disable(GtkWidget *widget) { - GtkWidget *parent; - HMENU hMenu; - HWND hWnd; - parent=widget->parent; - if (!parent) return; - hMenu=GTK_MENU_SHELL(parent)->menu; - if (hMenu) EnableMenuItem(hMenu,GTK_MENU_ITEM(widget)->ID, - MF_BYCOMMAND|MF_GRAYED); - hWnd=gtk_get_parent_hwnd(widget); - if (hWnd) DrawMenuBar(hWnd); -} - -GtkWidget *gtk_notebook_new() { - GtkNotebook *notebook; - - notebook=GTK_NOTEBOOK(GtkNewObject(&GtkNotebookClass)); - return GTK_WIDGET(notebook); -} - -void gtk_notebook_append_page(GtkNotebook *notebook,GtkWidget *child, - GtkWidget *tab_label) { - gtk_notebook_insert_page(notebook,child,tab_label,-1); -} - -void gtk_notebook_insert_page(GtkNotebook *notebook,GtkWidget *child, - GtkWidget *tab_label,gint position) { - GtkNotebookChild *note_child; - note_child=g_new0(GtkNotebookChild,1); - note_child->child=child; - note_child->tab_label=tab_label; - notebook->children=g_slist_insert(notebook->children,note_child,position); - child->parent=GTK_WIDGET(notebook); -} - -void gtk_notebook_set_page(GtkNotebook *notebook,gint page_num) { - GSList *children; - GtkNotebookChild *note_child; - GtkWidget *widget=GTK_WIDGET(notebook); - gint pos=0; - - if (page_num<0) page_num=g_slist_length(notebook->children)-1; - notebook->selection=page_num; - - if (GTK_WIDGET_REALIZED(widget)) { - if (widget->hWnd) TabCtrl_SetCurSel(widget->hWnd,page_num); - for (children=notebook->children;children; - children=g_slist_next(children)) { - note_child=(GtkNotebookChild *)(children->data); - if (note_child && note_child->child) { - if (pos==page_num) gtk_widget_show_all_full(note_child->child,TRUE); - else gtk_widget_hide_all_full(note_child->child,TRUE); - pos++; - } - } - } -} - -void gtk_notebook_realize(GtkWidget *widget) { - GSList *children; - GtkNotebookChild *note_child; - HWND Parent; - gint tab_pos=0; - TC_ITEM tie; - - Parent=gtk_get_parent_hwnd(widget); - GTK_WIDGET_SET_FLAGS(widget,GTK_CAN_FOCUS); - widget->hWnd = CreateWindow(WC_TABCONTROL,"", - WS_CHILD|WS_TABSTOP,0,0,0,0, - Parent,NULL,hInst,NULL); - if (widget->hWnd==NULL) g_print("Error creating window!\n"); - gtk_set_default_font(widget->hWnd); - - tie.mask = TCIF_TEXT | TCIF_IMAGE; - tie.iImage = -1; - - for (children=GTK_NOTEBOOK(widget)->children;children; - children=g_slist_next(children)) { - note_child=(GtkNotebookChild *)(children->data); - if (note_child) { - if (note_child->tab_label) - tie.pszText=GTK_LABEL(note_child->tab_label)->text; - else tie.pszText="No label"; - TabCtrl_InsertItem(widget->hWnd,tab_pos++,&tie); - if (note_child->child) { - gtk_widget_realize(note_child->child); - } +void gtk_notebook_set_page(GtkNotebook *notebook, gint page_num) +{ + GSList *children; + GtkNotebookChild *note_child; + GtkWidget *widget = GTK_WIDGET(notebook); + gint pos = 0; + + if (page_num < 0) + page_num = g_slist_length(notebook->children) - 1; + notebook->selection = page_num; + + if (GTK_WIDGET_REALIZED(widget)) { + if (widget->hWnd) + TabCtrl_SetCurSel(widget->hWnd, page_num); + for (children = notebook->children; children; + children = g_slist_next(children)) { + note_child = (GtkNotebookChild *)(children->data); + if (note_child && note_child->child) { + if (pos == page_num) + gtk_widget_show_all_full(note_child->child, TRUE); + else + gtk_widget_hide_all_full(note_child->child, TRUE); + pos++; } - } - gtk_notebook_set_page(GTK_NOTEBOOK(widget),GTK_NOTEBOOK(widget)->selection); + } + } } -void gtk_notebook_show_all(GtkWidget *widget,gboolean hWndOnly) { - GSList *children; - GtkNotebookChild *note_child; +void gtk_notebook_realize(GtkWidget *widget) +{ + GSList *children; + GtkNotebookChild *note_child; + HWND Parent; + gint tab_pos = 0; + TC_ITEM tie; + + Parent = gtk_get_parent_hwnd(widget); + GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS); + widget->hWnd = CreateWindow(WC_TABCONTROL, "", + WS_CHILD | WS_TABSTOP, 0, 0, 0, 0, + Parent, NULL, hInst, NULL); + if (widget->hWnd == NULL) + g_print("Error creating window!\n"); + gtk_set_default_font(widget->hWnd); + + tie.mask = TCIF_TEXT | TCIF_IMAGE; + tie.iImage = -1; + + for (children = GTK_NOTEBOOK(widget)->children; children; + children = g_slist_next(children)) { + note_child = (GtkNotebookChild *)(children->data); + if (note_child) { + if (note_child->tab_label) + tie.pszText = GTK_LABEL(note_child->tab_label)->text; + else + tie.pszText = "No label"; + TabCtrl_InsertItem(widget->hWnd, tab_pos++, &tie); + if (note_child->child) { + gtk_widget_realize(note_child->child); + } + } + } + gtk_notebook_set_page(GTK_NOTEBOOK(widget), + GTK_NOTEBOOK(widget)->selection); +} - if (!hWndOnly) for (children=GTK_NOTEBOOK(widget)->children;children; - children=g_slist_next(children)) { - note_child=(GtkNotebookChild *)(children->data); - if (note_child && note_child->child) - gtk_widget_show_all_full(note_child->child,hWndOnly); - } - gtk_notebook_set_page(GTK_NOTEBOOK(widget),GTK_NOTEBOOK(widget)->selection); +void gtk_notebook_show_all(GtkWidget *widget, gboolean hWndOnly) +{ + GSList *children; + GtkNotebookChild *note_child; + + if (!hWndOnly) + for (children = GTK_NOTEBOOK(widget)->children; children; + children = g_slist_next(children)) { + note_child = (GtkNotebookChild *)(children->data); + if (note_child && note_child->child) + gtk_widget_show_all_full(note_child->child, hWndOnly); + } + gtk_notebook_set_page(GTK_NOTEBOOK(widget), + GTK_NOTEBOOK(widget)->selection); } -void gtk_notebook_hide_all(GtkWidget *widget,gboolean hWndOnly) { - GSList *children; - GtkNotebookChild *note_child; +void gtk_notebook_hide_all(GtkWidget *widget, gboolean hWndOnly) +{ + GSList *children; + GtkNotebookChild *note_child; + + for (children = GTK_NOTEBOOK(widget)->children; children; + children = g_slist_next(children)) { + note_child = (GtkNotebookChild *)(children->data); + if (note_child && note_child->child) + gtk_widget_hide_all_full(note_child->child, hWndOnly); + } +} - for (children=GTK_NOTEBOOK(widget)->children;children; - children=g_slist_next(children)) { - note_child=(GtkNotebookChild *)(children->data); - if (note_child && note_child->child) - gtk_widget_hide_all_full(note_child->child,hWndOnly); - } +void gtk_notebook_destroy(GtkWidget *widget) +{ + GSList *children; + GtkNotebookChild *note_child; + + for (children = GTK_NOTEBOOK(widget)->children; children; + children = g_slist_next(children)) { + note_child = (GtkNotebookChild *)(children->data); + if (note_child) { + gtk_widget_destroy(note_child->child); + gtk_widget_destroy(note_child->tab_label); + } + g_free(note_child); + } + g_slist_free(GTK_NOTEBOOK(widget)->children); } -void gtk_notebook_destroy(GtkWidget *widget) { - GSList *children; - GtkNotebookChild *note_child; - - for (children=GTK_NOTEBOOK(widget)->children;children; - children=g_slist_next(children)) { - note_child=(GtkNotebookChild *)(children->data); - if (note_child) { - gtk_widget_destroy(note_child->child); - gtk_widget_destroy(note_child->tab_label); - } - g_free(note_child); - } - g_slist_free(GTK_NOTEBOOK(widget)->children); -} - -void gtk_notebook_set_size(GtkWidget *widget,GtkAllocation *allocation) { - GSList *children; - GtkNotebookChild *note_child; - RECT rect; - GtkAllocation child_alloc; - - gtk_container_set_size(widget,allocation); - rect.left=allocation->x; - rect.top=allocation->y; - rect.right=allocation->x+allocation->width; - rect.bottom=allocation->y+allocation->height; - TabCtrl_AdjustRect(widget->hWnd,FALSE,&rect); - child_alloc.x=rect.left+GTK_CONTAINER(widget)->border_width; - child_alloc.y=rect.top+GTK_CONTAINER(widget)->border_width; - child_alloc.width=rect.right-rect.left - -2*GTK_CONTAINER(widget)->border_width; - child_alloc.height=rect.bottom-rect.top - -2*GTK_CONTAINER(widget)->border_width; - - for (children=GTK_NOTEBOOK(widget)->children;children; - children=g_slist_next(children)) { - note_child=(GtkNotebookChild *)(children->data); - if (note_child && note_child->child) { - gtk_widget_set_size(note_child->child,&child_alloc); - } - } -} - -void gtk_notebook_size_request(GtkWidget *widget,GtkRequisition *requisition) { - GSList *children; - GtkNotebookChild *note_child; - GtkRequisition *child_req; - RECT rect; - - requisition->width=requisition->height=0; - for (children=GTK_NOTEBOOK(widget)->children;children; - children=g_slist_next(children)) { - note_child=(GtkNotebookChild *)(children->data); - if (note_child && note_child->child && - GTK_WIDGET_VISIBLE(note_child->child)) { - child_req=¬e_child->child->requisition; - if (child_req->width > requisition->width) - requisition->width=child_req->width; - if (child_req->height > requisition->height) - requisition->height=child_req->height; - } - } - requisition->width+=GTK_CONTAINER(widget)->border_width*2; - requisition->height+=GTK_CONTAINER(widget)->border_width*2; - rect.left=rect.top=0; - rect.right=requisition->width; - rect.bottom=requisition->height; - TabCtrl_AdjustRect(widget->hWnd,TRUE,&rect); - requisition->width=rect.right-rect.left; - requisition->height=rect.bottom-rect.top; +void gtk_notebook_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + GSList *children; + GtkNotebookChild *note_child; + RECT rect; + GtkAllocation child_alloc; + + gtk_container_set_size(widget, allocation); + rect.left = allocation->x; + rect.top = allocation->y; + rect.right = allocation->x + allocation->width; + rect.bottom = allocation->y + allocation->height; + TabCtrl_AdjustRect(widget->hWnd, FALSE, &rect); + child_alloc.x = rect.left + GTK_CONTAINER(widget)->border_width; + child_alloc.y = rect.top + GTK_CONTAINER(widget)->border_width; + child_alloc.width = rect.right - rect.left + - 2 * GTK_CONTAINER(widget)->border_width; + child_alloc.height = rect.bottom - rect.top + - 2 * GTK_CONTAINER(widget)->border_width; + + for (children = GTK_NOTEBOOK(widget)->children; children; + children = g_slist_next(children)) { + note_child = (GtkNotebookChild *)(children->data); + if (note_child && note_child->child) { + gtk_widget_set_size(note_child->child, &child_alloc); + } + } } -GtkObject *gtk_adjustment_new(gfloat value,gfloat lower,gfloat upper, - gfloat step_increment,gfloat page_increment, - gfloat page_size) { - GtkAdjustment *adj; +void gtk_notebook_size_request(GtkWidget *widget, + GtkRequisition *requisition) +{ + GSList *children; + GtkNotebookChild *note_child; + GtkRequisition *child_req; + RECT rect; + + requisition->width = requisition->height = 0; + for (children = GTK_NOTEBOOK(widget)->children; children; + children = g_slist_next(children)) { + note_child = (GtkNotebookChild *)(children->data); + if (note_child && note_child->child && + GTK_WIDGET_VISIBLE(note_child->child)) { + child_req = ¬e_child->child->requisition; + if (child_req->width > requisition->width) + requisition->width = child_req->width; + if (child_req->height > requisition->height) + requisition->height = child_req->height; + } + } + requisition->width += GTK_CONTAINER(widget)->border_width * 2; + requisition->height += GTK_CONTAINER(widget)->border_width * 2; + rect.left = rect.top = 0; + rect.right = requisition->width; + rect.bottom = requisition->height; + TabCtrl_AdjustRect(widget->hWnd, TRUE, &rect); + requisition->width = rect.right - rect.left; + requisition->height = rect.bottom - rect.top; +} + +GtkObject *gtk_adjustment_new(gfloat value, gfloat lower, gfloat upper, + gfloat step_increment, gfloat page_increment, + gfloat page_size) +{ + GtkAdjustment *adj; - adj=(GtkAdjustment *)(GtkNewObject(&GtkAdjustmentClass)); + adj = (GtkAdjustment *)(GtkNewObject(&GtkAdjustmentClass)); - adj->value=value; - adj->lower=lower; - adj->upper=upper; - adj->step_increment=step_increment; - adj->page_increment=page_increment; - adj->page_size=page_size; + adj->value = value; + adj->lower = lower; + adj->upper = upper; + adj->step_increment = step_increment; + adj->page_increment = page_increment; + adj->page_size = page_size; - return GTK_OBJECT(adj); + return GTK_OBJECT(adj); } -GtkWidget *gtk_spin_button_new(GtkAdjustment *adjustment,gfloat climb_rate, - guint digits) { - GtkSpinButton *spin; +GtkWidget *gtk_spin_button_new(GtkAdjustment *adjustment, + gfloat climb_rate, guint digits) +{ + GtkSpinButton *spin; - spin=GTK_SPIN_BUTTON(GtkNewObject(&GtkSpinButtonClass)); - GTK_ENTRY(spin)->is_visible = TRUE; + spin = GTK_SPIN_BUTTON(GtkNewObject(&GtkSpinButtonClass)); + GTK_ENTRY(spin)->is_visible = TRUE; - gtk_spin_button_set_adjustment(spin,adjustment); + gtk_spin_button_set_adjustment(spin, adjustment); - return GTK_WIDGET(spin); + return GTK_WIDGET(spin); } void gtk_spin_button_size_request(GtkWidget *widget, - GtkRequisition *requisition) { - gtk_entry_size_request(widget,requisition); -// requisition->width += GetSystemMetrics(SM_CXVSCROLL); + GtkRequisition *requisition) +{ + gtk_entry_size_request(widget, requisition); } -void gtk_spin_button_set_size(GtkWidget *widget, - GtkAllocation *allocation) { - int width=allocation->width,udwidth; - HWND updown; +void gtk_spin_button_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + int width = allocation->width, udwidth; + HWND updown; + + udwidth = GetSystemMetrics(SM_CXVSCROLL); + width = allocation->width; + allocation->width -= udwidth; + + updown = GTK_SPIN_BUTTON(widget)->updown; + if (updown) { + SetWindowPos(updown, HWND_TOP, + allocation->x + allocation->width, allocation->y, + udwidth, allocation->height, SWP_NOZORDER); + } +} - udwidth=GetSystemMetrics(SM_CXVSCROLL); - width=allocation->width; - allocation->width-=udwidth; +gint gtk_spin_button_get_value_as_int(GtkSpinButton *spin_button) +{ + HWND hWnd; + LRESULT lres; - updown=GTK_SPIN_BUTTON(widget)->updown; - if (updown) { - SetWindowPos(updown,HWND_TOP, - allocation->x+allocation->width,allocation->y, - udwidth,allocation->height, - SWP_NOZORDER); - } + hWnd = spin_button->updown; + if (hWnd) { + lres = SendMessage(hWnd, UDM_GETPOS, 0, 0); + if (HIWORD(lres) != 0) + return 0; + else + return (gint)LOWORD(lres); + } else + return (gint)spin_button->adj->value; } -gint gtk_spin_button_get_value_as_int(GtkSpinButton *spin_button) { - HWND hWnd; - LRESULT lres; - hWnd=spin_button->updown; - if (hWnd) { - lres=SendMessage(hWnd,UDM_GETPOS,0,0); - if (HIWORD(lres) != 0) return 0; - else return (gint)LOWORD(lres); - } else return (gint)spin_button->adj->value; -} +void gtk_spin_button_set_value(GtkSpinButton *spin_button, gfloat value) +{ + HWND hWnd; -void gtk_spin_button_set_value(GtkSpinButton *spin_button,gfloat value) { - HWND hWnd; - spin_button->adj->value=value; - hWnd=spin_button->updown; - if (hWnd) SendMessage(hWnd,UDM_SETPOS,0,(LPARAM)MAKELONG((short)value,0)); + spin_button->adj->value = value; + hWnd = spin_button->updown; + if (hWnd) + SendMessage(hWnd, UDM_SETPOS, 0, (LPARAM)MAKELONG((short)value, 0)); } void gtk_spin_button_set_adjustment(GtkSpinButton *spin_button, - GtkAdjustment *adjustment) { - HWND hWnd; - spin_button->adj=adjustment; - hWnd=spin_button->updown; - if (hWnd) { - SendMessage(hWnd,UDM_SETRANGE,0, - (LPARAM)MAKELONG((short)adjustment->upper,(short)adjustment->lower)); - SendMessage(hWnd,UDM_SETPOS,0, - (LPARAM)MAKELONG((short)adjustment->value,0)); - } + GtkAdjustment *adjustment) +{ + HWND hWnd; + + spin_button->adj = adjustment; + hWnd = spin_button->updown; + if (hWnd) { + SendMessage(hWnd, UDM_SETRANGE, 0, + (LPARAM)MAKELONG((short)adjustment->upper, + (short)adjustment->lower)); + SendMessage(hWnd, UDM_SETPOS, 0, + (LPARAM)MAKELONG((short)adjustment->value, 0)); + } } -void gtk_spin_button_realize(GtkWidget *widget) { - GtkSpinButton *spin=GTK_SPIN_BUTTON(widget); - HWND Parent; +void gtk_spin_button_realize(GtkWidget *widget) +{ + GtkSpinButton *spin = GTK_SPIN_BUTTON(widget); + HWND Parent; - gtk_entry_realize(widget); + gtk_entry_realize(widget); - Parent=gtk_get_parent_hwnd(widget->parent); - GTK_WIDGET_SET_FLAGS(widget,GTK_CAN_FOCUS); - spin->updown=CreateUpDownControl(WS_CHILD|WS_BORDER|WS_TABSTOP| - UDS_SETBUDDYINT|UDS_NOTHOUSANDS|UDS_ARROWKEYS, - 0,0,0,0,Parent,0,hInst,widget->hWnd,20,10,15); - gtk_set_default_font(spin->updown); - gtk_spin_button_set_adjustment(spin,spin->adj); + Parent = gtk_get_parent_hwnd(widget->parent); + GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS); + spin->updown = CreateUpDownControl(WS_CHILD | WS_BORDER | WS_TABSTOP | + UDS_SETBUDDYINT | UDS_NOTHOUSANDS | + UDS_ARROWKEYS, 0, 0, 0, 0, Parent, 0, + hInst, widget->hWnd, 20, 10, 15); + gtk_set_default_font(spin->updown); + gtk_spin_button_set_adjustment(spin, spin->adj); } -void gtk_spin_button_destroy(GtkWidget *widget) { - g_free(GTK_SPIN_BUTTON(widget)->adj); +void gtk_spin_button_destroy(GtkWidget *widget) +{ + g_free(GTK_SPIN_BUTTON(widget)->adj); } -void gtk_spin_button_show(GtkWidget *widget) { - HWND updown; - updown=GTK_SPIN_BUTTON(widget)->updown; - if (updown) ShowWindow(updown,SW_SHOWNORMAL); -} +void gtk_spin_button_show(GtkWidget *widget) +{ + HWND updown; -void gtk_spin_button_hide(GtkWidget *widget) { - HWND updown; - updown=GTK_SPIN_BUTTON(widget)->updown; - if (updown) ShowWindow(updown,SW_HIDE); + updown = GTK_SPIN_BUTTON(widget)->updown; + if (updown) + ShowWindow(updown, SW_SHOWNORMAL); } -void gtk_spin_button_update(GtkSpinButton *spin_button) { +void gtk_spin_button_hide(GtkWidget *widget) +{ + HWND updown; + + updown = GTK_SPIN_BUTTON(widget)->updown; + if (updown) + ShowWindow(updown, SW_HIDE); } -void gdk_input_remove(gint tag) { - GSList *list; - GdkInput *input; - for (list=GdkInputs;list;list=g_slist_next(list)) { - input=(GdkInput *)list->data; - if (input->source==tag) { - WSAAsyncSelect(input->source,TopLevel,0,0); - GdkInputs=g_slist_remove(GdkInputs,input); - g_free(input); - break; - } - } +void gtk_spin_button_update(GtkSpinButton *spin_button) +{ } -gint gdk_input_add(gint source,GdkInputCondition condition, - GdkInputFunction function,gpointer data) { - GdkInput *input; - int rc; - input=g_new(GdkInput,1); - input->source=source; - input->condition=condition; - input->function=function; - input->data=data; - rc=WSAAsyncSelect(source,TopLevel,MYWM_SOCKETDATA, - (condition&GDK_INPUT_READ ? FD_READ|FD_CLOSE|FD_ACCEPT:0) | - (condition&GDK_INPUT_WRITE ? FD_WRITE|FD_CONNECT:0)); - GdkInputs=g_slist_append(GdkInputs,input); - return source; +void gdk_input_remove(gint tag) +{ + GSList *list; + GdkInput *input; + + for (list = GdkInputs; list; list = g_slist_next(list)) { + input = (GdkInput *)list->data; + if (input->source == tag) { + WSAAsyncSelect(input->source, TopLevel, 0, 0); + GdkInputs = g_slist_remove(GdkInputs, input); + g_free(input); + break; + } + } } -GtkWidget *gtk_hseparator_new() { - return GTK_WIDGET(GtkNewObject(&GtkHSeparatorClass)); +gint gdk_input_add(gint source, GdkInputCondition condition, + GdkInputFunction function, gpointer data) +{ + GdkInput *input; + int rc; + + input = g_new(GdkInput, 1); + input->source = source; + input->condition = condition; + input->function = function; + input->data = data; + rc = WSAAsyncSelect(source, TopLevel, MYWM_SOCKETDATA, + (condition & GDK_INPUT_READ ? FD_READ | FD_CLOSE | + FD_ACCEPT : 0) | (condition & GDK_INPUT_WRITE ? + FD_WRITE | FD_CONNECT : 0)); + GdkInputs = g_slist_append(GdkInputs, input); + return source; +} + +GtkWidget *gtk_hseparator_new() +{ + return GTK_WIDGET(GtkNewObject(&GtkHSeparatorClass)); } -GtkWidget *gtk_vseparator_new() { - return GTK_WIDGET(GtkNewObject(&GtkVSeparatorClass)); +GtkWidget *gtk_vseparator_new() +{ + return GTK_WIDGET(GtkNewObject(&GtkVSeparatorClass)); } void gtk_separator_size_request(GtkWidget *widget, - GtkRequisition *requisition) { - requisition->height=requisition->width=2; + GtkRequisition *requisition) +{ + requisition->height = requisition->width = 2; } -void gtk_separator_realize(GtkWidget *widget) { - HWND Parent; - Parent=gtk_get_parent_hwnd(widget); - widget->hWnd = CreateWindow(WC_GTKSEP,"",WS_CHILD, - 0,0,0,0,Parent,NULL,hInst,NULL); +void gtk_separator_realize(GtkWidget *widget) +{ + HWND Parent; + + Parent = gtk_get_parent_hwnd(widget); + widget->hWnd = CreateWindow(WC_GTKSEP, "", WS_CHILD, + 0, 0, 0, 0, Parent, NULL, hInst, NULL); } -void gtk_object_set_data(GtkObject *object,const gchar *key,gpointer data) { - g_datalist_set_data(&object->object_data,key,data); +void gtk_object_set_data(GtkObject *object, const gchar *key, + gpointer data) +{ + g_datalist_set_data(&object->object_data, key, data); } -gpointer gtk_object_get_data(GtkObject *object,const gchar *key) { - return g_datalist_get_data(&object->object_data,key); +gpointer gtk_object_get_data(GtkObject *object, const gchar *key) +{ + return g_datalist_get_data(&object->object_data, key); } -GtkAccelGroup *gtk_accel_group_new() { - GtkAccelGroup *new_accel; - new_accel=g_new0(GtkAccelGroup,1); - new_accel->accel = NULL; - new_accel->numaccel = 0; - return new_accel; +GtkAccelGroup *gtk_accel_group_new() +{ + GtkAccelGroup *new_accel; + + new_accel = g_new0(GtkAccelGroup, 1); + new_accel->accel = NULL; + new_accel->numaccel = 0; + return new_accel; } -gint gtk_accel_group_add(GtkAccelGroup *accel_group,ACCEL *newaccel) { +gint gtk_accel_group_add(GtkAccelGroup *accel_group, ACCEL *newaccel) +{ accel_group->numaccel++; accel_group->accel = g_realloc(accel_group->accel, - accel_group->numaccel*sizeof(ACCEL)); - memcpy(&accel_group->accel[accel_group->numaccel-1],newaccel,sizeof(ACCEL)); - return (accel_group->numaccel-1); + accel_group->numaccel * sizeof(ACCEL)); + memcpy(&accel_group->accel[accel_group->numaccel - 1], newaccel, + sizeof(ACCEL)); + return (accel_group->numaccel - 1); } -void gtk_accel_group_set_id(GtkAccelGroup *accel_group,gint ind,gint ID) { - if (ind < accel_group->numaccel) accel_group->accel[ind].cmd = ID; +void gtk_accel_group_set_id(GtkAccelGroup *accel_group, gint ind, gint ID) +{ + if (ind < accel_group->numaccel) + accel_group->accel[ind].cmd = ID; } -void gtk_accel_group_destroy(GtkAccelGroup *accel_group) { +void gtk_accel_group_destroy(GtkAccelGroup *accel_group) +{ g_free(accel_group->accel); g_free(accel_group); } t@@ -4069,551 +4603,672 @@ void gtk_accel_group_destroy(GtkAccelGroup *accel_group) { void gtk_item_factory_set_translate_func(GtkItemFactory *ifactory, GtkTranslateFunc func, gpointer data, - GtkDestroyNotify notify) { + GtkDestroyNotify notify) +{ ifactory->translate_func = func; ifactory->translate_data = data; } -void gtk_widget_grab_default(GtkWidget *widget) { - GTK_WIDGET_SET_FLAGS(widget,GTK_IS_DEFAULT); +void gtk_widget_grab_default(GtkWidget *widget) +{ + GTK_WIDGET_SET_FLAGS(widget, GTK_IS_DEFAULT); } -void gtk_widget_grab_focus(GtkWidget *widget) { - if (widget->hWnd && GTK_WIDGET_CAN_FOCUS(widget)) { - SetFocus(widget->hWnd); - } +void gtk_widget_grab_focus(GtkWidget *widget) +{ + if (widget->hWnd && GTK_WIDGET_CAN_FOCUS(widget)) { + SetFocus(widget->hWnd); + } } -void gtk_window_set_modal(GtkWindow *window,gboolean modal) { - window->modal=modal; +void gtk_window_set_modal(GtkWindow *window, gboolean modal) +{ + window->modal = modal; } -void gtk_window_add_accel_group(GtkWindow *window,GtkAccelGroup *accel_group) { - window->accel_group=accel_group; +void gtk_window_add_accel_group(GtkWindow *window, + GtkAccelGroup *accel_group) +{ + window->accel_group = accel_group; } -void gtk_entry_set_text(GtkEntry *entry,const gchar *text) { - int pos=0; - gtk_editable_insert_text(GTK_EDITABLE(entry),text,strlen(text),&pos); +void gtk_entry_set_text(GtkEntry *entry, const gchar *text) +{ + int pos = 0; + + gtk_editable_insert_text(GTK_EDITABLE(entry), text, strlen(text), &pos); } -void gtk_entry_set_visibility(GtkEntry *entry,gboolean visible) { - HWND hWnd; - entry->is_visible = visible; - hWnd=GTK_WIDGET(entry)->hWnd; - if (hWnd) SendMessage(hWnd,EM_SETPASSWORDCHAR,visible ? 0 : (WPARAM)'*',0); +void gtk_entry_set_visibility(GtkEntry *entry, gboolean visible) +{ + HWND hWnd; + + entry->is_visible = visible; + hWnd = GTK_WIDGET(entry)->hWnd; + if (hWnd) + SendMessage(hWnd, EM_SETPASSWORDCHAR, visible ? 0 : (WPARAM)'*', 0); } -guint SetAccelerator(GtkWidget *labelparent,gchar *Text, - GtkWidget *sendto,gchar *signal, - GtkAccelGroup *accel_group) { - gtk_signal_emit(GTK_OBJECT(labelparent),"set_text",Text); - return 0; +guint SetAccelerator(GtkWidget *labelparent, gchar *Text, + GtkWidget *sendto, gchar *signal, + GtkAccelGroup *accel_group) +{ + gtk_signal_emit(GTK_OBJECT(labelparent), "set_text", Text); + return 0; } void gtk_widget_add_accelerator(GtkWidget *widget, const gchar *accel_signal, GtkAccelGroup *accel_group, - guint accel_key,guint accel_mods, - GtkAccelFlags accel_flags) { + guint accel_key, guint accel_mods, + GtkAccelFlags accel_flags) +{ } void gtk_widget_remove_accelerator(GtkWidget *widget, GtkAccelGroup *accel_group, - guint accel_key,guint accel_mods) { + guint accel_key, guint accel_mods) +{ } -GtkWidget *gtk_vpaned_new() { - GtkVPaned *vpaned; - vpaned=GTK_VPANED(GtkNewObject(&GtkVPanedClass)); - GTK_PANED(vpaned)->handle_size=5; - GTK_PANED(vpaned)->handle_pos=PANED_STARTPOS; - return GTK_WIDGET(vpaned); +GtkWidget *gtk_vpaned_new() +{ + GtkVPaned *vpaned; + + vpaned = GTK_VPANED(GtkNewObject(&GtkVPanedClass)); + GTK_PANED(vpaned)->handle_size = 5; + GTK_PANED(vpaned)->handle_pos = PANED_STARTPOS; + return GTK_WIDGET(vpaned); } -GtkWidget *gtk_hpaned_new() { - GtkHPaned *hpaned; - hpaned=GTK_HPANED(GtkNewObject(&GtkHPanedClass)); - GTK_PANED(hpaned)->handle_size=5; - GTK_PANED(hpaned)->handle_pos=PANED_STARTPOS; - return GTK_WIDGET(hpaned); +GtkWidget *gtk_hpaned_new() +{ + GtkHPaned *hpaned; + + hpaned = GTK_HPANED(GtkNewObject(&GtkHPanedClass)); + GTK_PANED(hpaned)->handle_size = 5; + GTK_PANED(hpaned)->handle_pos = PANED_STARTPOS; + return GTK_WIDGET(hpaned); } -static void gtk_paned_pack(GtkPaned *paned,gint pos,GtkWidget *child, - gboolean resize,gboolean shrink) { - paned->children[pos].widget=child; - paned->children[pos].resize=resize; - paned->children[pos].shrink=shrink; - child->parent=GTK_WIDGET(paned); +static void gtk_paned_pack(GtkPaned *paned, gint pos, GtkWidget *child, + gboolean resize, gboolean shrink) +{ + paned->children[pos].widget = child; + paned->children[pos].resize = resize; + paned->children[pos].shrink = shrink; + child->parent = GTK_WIDGET(paned); } -void gtk_paned_pack1(GtkPaned *paned,GtkWidget *child,gboolean resize, - gboolean shrink) { - gtk_paned_pack(paned,0,child,resize,shrink); +void gtk_paned_pack1(GtkPaned *paned, GtkWidget *child, gboolean resize, + gboolean shrink) +{ + gtk_paned_pack(paned, 0, child, resize, shrink); } -void gtk_paned_pack2(GtkPaned *paned,GtkWidget *child,gboolean resize, - gboolean shrink) { - gtk_paned_pack(paned,1,child,resize,shrink); +void gtk_paned_pack2(GtkPaned *paned, GtkWidget *child, gboolean resize, + gboolean shrink) +{ + gtk_paned_pack(paned, 1, child, resize, shrink); } -void gtk_paned_add1(GtkPaned *paned,GtkWidget *child) { - gtk_paned_pack1(paned,child,FALSE,TRUE); +void gtk_paned_add1(GtkPaned *paned, GtkWidget *child) +{ + gtk_paned_pack1(paned, child, FALSE, TRUE); } -void gtk_paned_add2(GtkPaned *paned,GtkWidget *child) { - gtk_paned_pack2(paned,child,FALSE,TRUE); +void gtk_paned_add2(GtkPaned *paned, GtkWidget *child) +{ + gtk_paned_pack2(paned, child, FALSE, TRUE); } -void gtk_paned_show_all(GtkWidget *widget,gboolean hWndOnly) { - GtkPaned *paned=GTK_PANED(widget); - gint i; - for (i=0;i<2;i++) if (paned->children[i].widget) { - gtk_widget_show_all_full(paned->children[i].widget,hWndOnly); - } +void gtk_paned_show_all(GtkWidget *widget, gboolean hWndOnly) +{ + GtkPaned *paned = GTK_PANED(widget); + gint i; + + for (i = 0; i < 2; i++) + if (paned->children[i].widget) { + gtk_widget_show_all_full(paned->children[i].widget, hWndOnly); + } } -void gtk_paned_hide_all(GtkWidget *widget,gboolean hWndOnly) { - GtkPaned *paned=GTK_PANED(widget); - gint i; - for (i=0;i<2;i++) if (paned->children[i].widget) - gtk_widget_hide_all_full(paned->children[i].widget,hWndOnly); +void gtk_paned_hide_all(GtkWidget *widget, gboolean hWndOnly) +{ + GtkPaned *paned = GTK_PANED(widget); + gint i; + + for (i = 0; i < 2; i++) + if (paned->children[i].widget) + gtk_widget_hide_all_full(paned->children[i].widget, hWndOnly); } -void gtk_paned_realize(GtkWidget *widget) { - GtkPaned *paned=GTK_PANED(widget); - gint i; - for (i=0;i<2;i++) if (paned->children[i].widget) { +void gtk_paned_realize(GtkWidget *widget) +{ + GtkPaned *paned = GTK_PANED(widget); + gint i; + + for (i = 0; i < 2; i++) + if (paned->children[i].widget) { gtk_widget_realize(paned->children[i].widget); - } + } } -void gtk_vpaned_realize(GtkWidget *widget) { - HWND Parent; - gtk_paned_realize(widget); - Parent=gtk_get_parent_hwnd(widget); - widget->hWnd = CreateWindow(WC_GTKVPANED,"",WS_CHILD, - 0,0,0,0,Parent,NULL,hInst,NULL); +void gtk_vpaned_realize(GtkWidget *widget) +{ + HWND Parent; + + gtk_paned_realize(widget); + Parent = gtk_get_parent_hwnd(widget); + widget->hWnd = CreateWindow(WC_GTKVPANED, "", WS_CHILD, + 0, 0, 0, 0, Parent, NULL, hInst, NULL); } -void gtk_hpaned_realize(GtkWidget *widget) { - HWND Parent; - gtk_paned_realize(widget); - Parent=gtk_get_parent_hwnd(widget); - widget->hWnd = CreateWindow(WC_GTKHPANED,"",WS_CHILD, - 0,0,0,0,Parent,NULL,hInst,NULL); +void gtk_hpaned_realize(GtkWidget *widget) +{ + HWND Parent; + + gtk_paned_realize(widget); + Parent = gtk_get_parent_hwnd(widget); + widget->hWnd = CreateWindow(WC_GTKHPANED, "", WS_CHILD, + 0, 0, 0, 0, Parent, NULL, hInst, NULL); } -static void gtk_paned_set_handle_percent(GtkPaned *paned,gint16 req[2]) { - if (req[0]+req[1]) paned->handle_pos=req[0]*100/(req[0]+req[1]); - else paned->handle_pos=0; +static void gtk_paned_set_handle_percent(GtkPaned *paned, gint16 req[2]) +{ + if (req[0] + req[1]) + paned->handle_pos = req[0] * 100 / (req[0] + req[1]); + else + paned->handle_pos = 0; } -void gtk_vpaned_size_request(GtkWidget *widget,GtkRequisition *requisition) { - GtkPaned *paned=GTK_PANED(widget); - gint i; - gint16 req[2] = { 0,0 }; - requisition->width=requisition->height=0; - for (i=0;i<2;i++) if (paned->children[i].widget) { - if (paned->children[i].widget->requisition.width > requisition->width) - requisition->width = paned->children[i].widget->requisition.width; - req[i]=paned->children[i].widget->requisition.height; +void gtk_vpaned_size_request(GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkPaned *paned = GTK_PANED(widget); + gint i; + gint16 req[2] = { 0, 0 }; + + requisition->width = requisition->height = 0; + for (i = 0; i < 2; i++) + if (paned->children[i].widget) { + if (paned->children[i].widget->requisition.width > + requisition->width) + requisition->width = paned->children[i].widget->requisition.width; + req[i] = paned->children[i].widget->requisition.height; requisition->height += req[i]; - } - requisition->height += paned->handle_size; - gtk_paned_set_handle_percent(paned,req); -} - -void gtk_hpaned_size_request(GtkWidget *widget,GtkRequisition *requisition) { - GtkPaned *paned=GTK_PANED(widget); - gint i; - gint16 req[2] = { 0,0 }; - requisition->width=requisition->height=0; - for (i=0;i<2;i++) if (paned->children[i].widget) { - if (paned->children[i].widget->requisition.height > requisition->height) - requisition->height = paned->children[i].widget->requisition.height; - req[i]=paned->children[i].widget->requisition.width; - requisition->width += req[i]; - } - requisition->width += paned->handle_size; - gtk_paned_set_handle_percent(paned,req); + } + requisition->height += paned->handle_size; + gtk_paned_set_handle_percent(paned, req); } -void gtk_vpaned_set_size(GtkWidget *widget,GtkAllocation *allocation) { - GtkPaned *paned=GTK_PANED(widget); - GtkWidget *child; - gint16 alloc; - GtkAllocation child_alloc; - - memcpy(&paned->true_alloc,allocation,sizeof(GtkAllocation)); - - alloc=allocation->height-paned->handle_size; +void gtk_hpaned_size_request(GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkPaned *paned = GTK_PANED(widget); + gint i; + gint16 req[2] = { 0, 0 }; + + requisition->width = requisition->height = 0; + for (i = 0; i < 2; i++) + if (paned->children[i].widget) { + if (paned->children[i].widget->requisition.height > + requisition->height) + requisition->height = + paned->children[i].widget->requisition.height; + req[i] = paned->children[i].widget->requisition.width; + requisition->width += req[i]; + } + requisition->width += paned->handle_size; + gtk_paned_set_handle_percent(paned, req); +} - child=paned->children[0].widget; - if (child) { - child_alloc.x=allocation->x; - child_alloc.y=allocation->y; - child_alloc.width=allocation->width; - child_alloc.height=alloc*paned->handle_pos/100; - gtk_widget_set_size(child,&child_alloc); - } +void gtk_vpaned_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + GtkPaned *paned = GTK_PANED(widget); + GtkWidget *child; + gint16 alloc; + GtkAllocation child_alloc; + + memcpy(&paned->true_alloc, allocation, sizeof(GtkAllocation)); + + alloc = allocation->height - paned->handle_size; + + child = paned->children[0].widget; + if (child) { + child_alloc.x = allocation->x; + child_alloc.y = allocation->y; + child_alloc.width = allocation->width; + child_alloc.height = alloc * paned->handle_pos / 100; + gtk_widget_set_size(child, &child_alloc); + } - child=paned->children[1].widget; - if (child) { - child_alloc.x=allocation->x; - child_alloc.width=allocation->width; - child_alloc.height=alloc*(100-paned->handle_pos)/100; - child_alloc.y=allocation->y+allocation->height-child_alloc.height; - gtk_widget_set_size(child,&child_alloc); - } + child = paned->children[1].widget; + if (child) { + child_alloc.x = allocation->x; + child_alloc.width = allocation->width; + child_alloc.height = alloc * (100 - paned->handle_pos) / 100; + child_alloc.y = + allocation->y + allocation->height - child_alloc.height; + gtk_widget_set_size(child, &child_alloc); + } - allocation->y += alloc*paned->handle_pos/100; - allocation->height = paned->handle_size; + allocation->y += alloc * paned->handle_pos / 100; + allocation->height = paned->handle_size; } -void gtk_hpaned_set_size(GtkWidget *widget,GtkAllocation *allocation) { - GtkPaned *paned=GTK_PANED(widget); - GtkWidget *child; - gint16 alloc; - GtkAllocation child_alloc; - - memcpy(&paned->true_alloc,allocation,sizeof(GtkAllocation)); - alloc=allocation->width-paned->handle_size; - - child=paned->children[0].widget; - if (child) { - child_alloc.x=allocation->x; - child_alloc.y=allocation->y; - child_alloc.height=allocation->height; - child_alloc.width=alloc*paned->handle_pos/100; - gtk_widget_set_size(child,&child_alloc); - } +void gtk_hpaned_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + GtkPaned *paned = GTK_PANED(widget); + GtkWidget *child; + gint16 alloc; + GtkAllocation child_alloc; + + memcpy(&paned->true_alloc, allocation, sizeof(GtkAllocation)); + alloc = allocation->width - paned->handle_size; + + child = paned->children[0].widget; + if (child) { + child_alloc.x = allocation->x; + child_alloc.y = allocation->y; + child_alloc.height = allocation->height; + child_alloc.width = alloc * paned->handle_pos / 100; + gtk_widget_set_size(child, &child_alloc); + } - child=paned->children[1].widget; - if (child) { - child_alloc.x=allocation->x; - child_alloc.height=allocation->height; - child_alloc.width=alloc*(100-paned->handle_pos)/100; - child_alloc.x=allocation->x+allocation->width-child_alloc.width; - gtk_widget_set_size(child,&child_alloc); - } + child = paned->children[1].widget; + if (child) { + child_alloc.x = allocation->x; + child_alloc.height = allocation->height; + child_alloc.width = alloc * (100 - paned->handle_pos) / 100; + child_alloc.x = allocation->x + allocation->width - child_alloc.width; + gtk_widget_set_size(child, &child_alloc); + } - allocation->x += alloc*paned->handle_pos/100; - allocation->width = paned->handle_size; + allocation->x += alloc * paned->handle_pos / 100; + allocation->width = paned->handle_size; } -void gtk_text_set_editable(GtkText *text,gboolean is_editable) { - gtk_editable_set_editable(GTK_EDITABLE(text),is_editable); +void gtk_text_set_editable(GtkText *text, gboolean is_editable) +{ + gtk_editable_set_editable(GTK_EDITABLE(text), is_editable); } -void gtk_text_set_word_wrap(GtkText *text,gboolean word_wrap) { - text->word_wrap=word_wrap; +void gtk_text_set_word_wrap(GtkText *text, gboolean word_wrap) +{ + text->word_wrap = word_wrap; } -void gtk_text_freeze(GtkText *text) { +void gtk_text_freeze(GtkText *text) +{ } -void gtk_text_thaw(GtkText *text) { +void gtk_text_thaw(GtkText *text) +{ } static GtkCList *sorting_clist; -static gint gtk_clist_sort_func(gconstpointer a,gconstpointer b) { - return (*sorting_clist->cmp_func)(sorting_clist,a,b); -} - -void gtk_clist_sort(GtkCList *clist) { - HWND hWnd; - gint rowind; - GList *sel; - GSList *rowpt; - - sorting_clist=clist; - if (clist && clist->cmp_func && clist->rows) { -/* Since the order of the list may change, we need to change the selection - as well. Do this by converting the row indices into GSList pointers (which - are invariant to the sort) and then convert back afterwards */ - for (sel=clist->selection;sel;sel=g_list_next(sel)) { - rowind=GPOINTER_TO_INT(sel->data); - sel->data=(gpointer)g_slist_nth(clist->rows,rowind); - } - clist->rows=g_slist_sort(clist->rows,gtk_clist_sort_func); - for (sel=clist->selection;sel;sel=g_list_next(sel)) { - rowpt=(GSList *)(sel->data); - sel->data=GINT_TO_POINTER(g_slist_position(clist->rows,rowpt)); - } - if (GTK_WIDGET_REALIZED(GTK_WIDGET(clist))) { - hWnd=GTK_WIDGET(clist)->hWnd; - if (clist->mode==GTK_SELECTION_SINGLE) { - sel=clist->selection; - if (sel) rowind=GPOINTER_TO_INT(sel->data); - else rowind=-1; - SendMessage(hWnd,LB_SETCURSEL,(WPARAM)rowind,0); - } else { - for (rowind=0;rowind<g_slist_length(clist->rows);rowind++) { - SendMessage(hWnd,LB_SETSEL,(WPARAM)FALSE,(LPARAM)rowind); - } - for (sel=clist->selection;sel;sel=g_list_next(sel)) { - rowind=GPOINTER_TO_INT(sel->data); - SendMessage(hWnd,LB_SETSEL,(WPARAM)TRUE,(LPARAM)rowind); - } - } - InvalidateRect(hWnd,NULL,FALSE); - UpdateWindow(hWnd); +static gint gtk_clist_sort_func(gconstpointer a, gconstpointer b) +{ + return (*sorting_clist->cmp_func) (sorting_clist, a, b); +} + +void gtk_clist_sort(GtkCList *clist) +{ + HWND hWnd; + gint rowind; + GList *sel; + GSList *rowpt; + + sorting_clist = clist; + if (clist && clist->cmp_func && clist->rows) { + /* Since the order of the list may change, we need to change the + * selection as well. Do this by converting the row indices into + * GSList pointers (which are invariant to the sort) and then convert + * back afterwards */ + for (sel = clist->selection; sel; sel = g_list_next(sel)) { + rowind = GPOINTER_TO_INT(sel->data); + sel->data = (gpointer)g_slist_nth(clist->rows, rowind); + } + clist->rows = g_slist_sort(clist->rows, gtk_clist_sort_func); + for (sel = clist->selection; sel; sel = g_list_next(sel)) { + rowpt = (GSList *)(sel->data); + sel->data = GINT_TO_POINTER(g_slist_position(clist->rows, rowpt)); + } + if (GTK_WIDGET_REALIZED(GTK_WIDGET(clist))) { + hWnd = GTK_WIDGET(clist)->hWnd; + if (clist->mode == GTK_SELECTION_SINGLE) { + sel = clist->selection; + if (sel) + rowind = GPOINTER_TO_INT(sel->data); + else + rowind = -1; + SendMessage(hWnd, LB_SETCURSEL, (WPARAM)rowind, 0); + } else { + for (rowind = 0; rowind < g_slist_length(clist->rows); rowind++) { + SendMessage(hWnd, LB_SETSEL, (WPARAM)FALSE, (LPARAM)rowind); + } + for (sel = clist->selection; sel; sel = g_list_next(sel)) { + rowind = GPOINTER_TO_INT(sel->data); + SendMessage(hWnd, LB_SETSEL, (WPARAM)TRUE, (LPARAM)rowind); + } } - } + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + } + } } -void gtk_clist_freeze(GtkCList *clist) { +void gtk_clist_freeze(GtkCList *clist) +{ } -void gtk_clist_thaw(GtkCList *clist) { +void gtk_clist_thaw(GtkCList *clist) +{ } -void gtk_clist_clear(GtkCList *clist) { - GtkCListRow *row; - GSList *list; - gint i; - HWND hWnd; +void gtk_clist_clear(GtkCList *clist) +{ + GtkCListRow *row; + GSList *list; + gint i; + HWND hWnd; - for (list=clist->rows;list;list=g_slist_next(list)) { - row=(GtkCListRow *)list->data; - for (i=0;i<clist->ncols;i++) { - g_free(row->text[i]); - } - g_free(row); - } - g_slist_free(clist->rows); - clist->rows=NULL; + for (list = clist->rows; list; list = g_slist_next(list)) { + row = (GtkCListRow *)list->data; + for (i = 0; i < clist->ncols; i++) { + g_free(row->text[i]); + } + g_free(row); + } + g_slist_free(clist->rows); + clist->rows = NULL; - gtk_clist_update_all_widths(clist); - hWnd=GTK_WIDGET(clist)->hWnd; - if (hWnd) { - SendMessage(hWnd,LB_RESETCONTENT,0,0); - } + gtk_clist_update_all_widths(clist); + hWnd = GTK_WIDGET(clist)->hWnd; + if (hWnd) { + SendMessage(hWnd, LB_RESETCONTENT, 0, 0); + } } -GtkWidget *gtk_option_menu_new() { - GtkOptionMenu *option_menu; - option_menu=GTK_OPTION_MENU(GtkNewObject(&GtkOptionMenuClass)); - return GTK_WIDGET(option_menu); -} +GtkWidget *gtk_option_menu_new() +{ + GtkOptionMenu *option_menu; -GtkWidget *gtk_option_menu_get_menu(GtkOptionMenu *option_menu) { - return option_menu->menu; + option_menu = GTK_OPTION_MENU(GtkNewObject(&GtkOptionMenuClass)); + return GTK_WIDGET(option_menu); } -void gtk_option_menu_set_menu(GtkOptionMenu *option_menu,GtkWidget *menu) { - GSList *list; - GtkMenuItem *menu_item; - HWND hWnd; - - if (!menu) return; - option_menu->menu=menu; - hWnd=GTK_WIDGET(option_menu)->hWnd; +GtkWidget *gtk_option_menu_get_menu(GtkOptionMenu *option_menu) +{ + return option_menu->menu; +} - if (hWnd) { - SendMessage(hWnd,CB_RESETCONTENT,0,0); - for (list=GTK_MENU_SHELL(menu)->children;list;list=g_slist_next(list)) { - menu_item=GTK_MENU_ITEM(list->data); - if (menu_item && menu_item->text) - SendMessage(hWnd,CB_ADDSTRING,0,(LPARAM)menu_item->text); - } - SendMessage(hWnd,CB_SETCURSEL,(WPARAM)GTK_MENU(menu)->active,0); - } +void gtk_option_menu_set_menu(GtkOptionMenu *option_menu, GtkWidget *menu) +{ + GSList *list; + GtkMenuItem *menu_item; + HWND hWnd; + + if (!menu) + return; + option_menu->menu = menu; + hWnd = GTK_WIDGET(option_menu)->hWnd; + + if (hWnd) { + SendMessage(hWnd, CB_RESETCONTENT, 0, 0); + for (list = GTK_MENU_SHELL(menu)->children; list; + list = g_slist_next(list)) { + menu_item = GTK_MENU_ITEM(list->data); + if (menu_item && menu_item->text) + SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)menu_item->text); + } + SendMessage(hWnd, CB_SETCURSEL, (WPARAM)GTK_MENU(menu)->active, 0); + } } -void gtk_option_menu_set_history(GtkOptionMenu *option_menu,guint index) { - GtkWidget *menu; - menu=gtk_option_menu_get_menu(option_menu); - if (menu) gtk_menu_set_active(GTK_MENU(menu),index); +void gtk_option_menu_set_history(GtkOptionMenu *option_menu, guint index) +{ + GtkWidget *menu; + + menu = gtk_option_menu_get_menu(option_menu); + if (menu) + gtk_menu_set_active(GTK_MENU(menu), index); } void gtk_option_menu_size_request(GtkWidget *widget, - GtkRequisition *requisition) { - SIZE size; + GtkRequisition *requisition) +{ + SIZE size; - if (GetTextSize(widget->hWnd, "Sample text", &size, defFont)) { - requisition->width = size.cx+40; - requisition->height = size.cy+4; - } + if (GetTextSize(widget->hWnd, "Sample text", &size, defFont)) { + requisition->width = size.cx + 40; + requisition->height = size.cy + 4; + } } -void gtk_option_menu_set_size(GtkWidget *widget,GtkAllocation *allocation) { - allocation->height *= 6; +void gtk_option_menu_set_size(GtkWidget *widget, GtkAllocation *allocation) +{ + allocation->height *= 6; } -void gtk_option_menu_realize(GtkWidget *widget) { - HWND Parent; - GtkOptionMenu *option_menu=GTK_OPTION_MENU(widget); +void gtk_option_menu_realize(GtkWidget *widget) +{ + HWND Parent; + GtkOptionMenu *option_menu = GTK_OPTION_MENU(widget); - Parent=gtk_get_parent_hwnd(widget); - GTK_WIDGET_SET_FLAGS(widget,GTK_CAN_FOCUS); - widget->hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,"COMBOBOX","", - WS_CHILD|WS_TABSTOP|WS_VSCROLL| - CBS_HASSTRINGS|CBS_DROPDOWNLIST, - 0,0,0,0,Parent,NULL,hInst,NULL); - gtk_set_default_font(widget->hWnd); - gtk_option_menu_set_menu(option_menu,option_menu->menu); + Parent = gtk_get_parent_hwnd(widget); + GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS); + widget->hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, "COMBOBOX", "", + WS_CHILD | WS_TABSTOP | WS_VSCROLL | + CBS_HASSTRINGS | CBS_DROPDOWNLIST, + 0, 0, 0, 0, Parent, NULL, hInst, NULL); + gtk_set_default_font(widget->hWnd); + gtk_option_menu_set_menu(option_menu, option_menu->menu); } -void gtk_label_set_text(GtkLabel *label,const gchar *str) { - gint i; - HWND hWnd; - g_free(label->text); - label->text = g_strdup(str ? str : ""); - for (i=0;i<strlen(label->text);i++) { - if (label->text[i]=='_') label->text[i]='&'; - } - hWnd=GTK_WIDGET(label)->hWnd; - if (hWnd) { - gtk_widget_update(GTK_WIDGET(label),FALSE); - SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)label->text); - } +void gtk_label_set_text(GtkLabel *label, const gchar *str) +{ + gint i; + HWND hWnd; + + g_free(label->text); + label->text = g_strdup(str ? str : ""); + for (i = 0; i < strlen(label->text); i++) { + if (label->text[i] == '_') + label->text[i] = '&'; + } + hWnd = GTK_WIDGET(label)->hWnd; + if (hWnd) { + gtk_widget_update(GTK_WIDGET(label), FALSE); + SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)label->text); + } } -void gtk_button_set_text(GtkButton *button,gchar *text) { - gint i; - HWND hWnd; - g_free(button->text); - button->text = g_strdup(text ? text : ""); - for (i=0;i<strlen(button->text);i++) { - if (button->text[i]=='_') button->text[i]='&'; - } - hWnd=GTK_WIDGET(button)->hWnd; - if (hWnd) { - gtk_widget_update(GTK_WIDGET(button),FALSE); - SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)button->text); - } +void gtk_button_set_text(GtkButton *button, gchar *text) +{ + gint i; + HWND hWnd; + + g_free(button->text); + button->text = g_strdup(text ? text : ""); + for (i = 0; i < strlen(button->text); i++) { + if (button->text[i] == '_') + button->text[i] = '&'; + } + hWnd = GTK_WIDGET(button)->hWnd; + if (hWnd) { + gtk_widget_update(GTK_WIDGET(button), FALSE); + SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)button->text); + } } -static void gtk_menu_item_set_text(GtkMenuItem *menuitem,gchar *text) { - gint i; - g_free(menuitem->text); - menuitem->text = g_strdup(text ? text : ""); - for (i=0;i<strlen(menuitem->text);i++) { - if (menuitem->text[i]=='_') menuitem->text[i]='&'; - } -} +static void gtk_menu_item_set_text(GtkMenuItem *menuitem, gchar *text) +{ + gint i; -guint gtk_label_parse_uline(GtkLabel *label,const gchar *str) { - gint i; - gtk_label_set_text(label,str); - if (str) for (i=0;i<strlen(str);i++) { - if (str[i]=='_') return str[i+1]; - } - return 0; + g_free(menuitem->text); + menuitem->text = g_strdup(text ? text : ""); + for (i = 0; i < strlen(menuitem->text); i++) { + if (menuitem->text[i] == '_') + menuitem->text[i] = '&'; + } } -void gtk_label_get(GtkLabel *label,gchar **str) { - *str = label->text; +guint gtk_label_parse_uline(GtkLabel *label, const gchar *str) +{ + gint i; + + gtk_label_set_text(label, str); + if (str) + for (i = 0; i < strlen(str); i++) { + if (str[i] == '_') + return str[i + 1]; + } + return 0; } -void gtk_clist_set_row_data(GtkCList *clist,gint row,gpointer data) { - GtkCListRow *list_row; - if (row>=0 && row<g_slist_length(clist->rows)) { - list_row=(GtkCListRow *)g_slist_nth_data(clist->rows,row); - if (list_row) list_row->data=data; - } +void gtk_label_get(GtkLabel *label, gchar **str) +{ + *str = label->text; } -gpointer gtk_clist_get_row_data(GtkCList *clist,gint row) { - GtkCListRow *list_row; - if (row>=0 && row<g_slist_length(clist->rows)) { - list_row=(GtkCListRow *)g_slist_nth_data(clist->rows,row); - if (list_row) return list_row->data; - } - return NULL; +void gtk_clist_set_row_data(GtkCList *clist, gint row, gpointer data) +{ + GtkCListRow *list_row; + + if (row >= 0 && row < g_slist_length(clist->rows)) { + list_row = (GtkCListRow *)g_slist_nth_data(clist->rows, row); + if (list_row) + list_row->data = data; + } } -void gtk_clist_set_auto_sort(GtkCList *clist,gboolean auto_sort) { - clist->auto_sort=auto_sort; +gpointer gtk_clist_get_row_data(GtkCList *clist, gint row) +{ + GtkCListRow *list_row; + + if (row >= 0 && row < g_slist_length(clist->rows)) { + list_row = (GtkCListRow *)g_slist_nth_data(clist->rows, row); + if (list_row) + return list_row->data; + } + return NULL; } -void gtk_clist_columns_autosize(GtkCList *clist) { +void gtk_clist_set_auto_sort(GtkCList *clist, gboolean auto_sort) +{ + clist->auto_sort = auto_sort; } -void gtk_text_set_point(GtkText *text,guint index) { - gtk_editable_set_position(GTK_EDITABLE(text),index); +void gtk_clist_columns_autosize(GtkCList *clist) +{ } -void gtk_widget_set_usize(GtkWidget *widget,gint width,gint height) { - widget->usize.width = width; - widget->usize.height = height; +void gtk_text_set_point(GtkText *text, guint index) +{ + gtk_editable_set_position(GTK_EDITABLE(text), index); } -void gtk_clist_select_row(GtkCList *clist,gint row,gint column) { - HWND hWnd; - hWnd=GTK_WIDGET(clist)->hWnd; - if (hWnd) { - if (clist->mode==GTK_SELECTION_SINGLE) { - SendMessage(hWnd,LB_SETCURSEL,(WPARAM)row,0); - } else { - SendMessage(hWnd,LB_SETSEL,(WPARAM)TRUE,(LPARAM)row); - } - gtk_clist_update_selection(GTK_WIDGET(clist)); - } +void gtk_widget_set_usize(GtkWidget *widget, gint width, gint height) +{ + widget->usize.width = width; + widget->usize.height = height; } -GtkVisibility gtk_clist_row_is_visible(GtkCList *clist,gint row) { - return GTK_VISIBILITY_FULL; +void gtk_clist_select_row(GtkCList *clist, gint row, gint column) +{ + HWND hWnd; + + hWnd = GTK_WIDGET(clist)->hWnd; + if (hWnd) { + if (clist->mode == GTK_SELECTION_SINGLE) { + SendMessage(hWnd, LB_SETCURSEL, (WPARAM)row, 0); + } else { + SendMessage(hWnd, LB_SETSEL, (WPARAM)TRUE, (LPARAM)row); + } + gtk_clist_update_selection(GTK_WIDGET(clist)); + } } -void gtk_clist_moveto(GtkCList *clist,gint row,gint column, - gfloat row_align,gfloat col_align) { +GtkVisibility gtk_clist_row_is_visible(GtkCList *clist, gint row) +{ + return GTK_VISIBILITY_FULL; } -void gtk_clist_set_compare_func(GtkCList *clist,GtkCListCompareFunc cmp_func) { - if (clist) clist->cmp_func = cmp_func; +void gtk_clist_moveto(GtkCList *clist, gint row, gint column, + gfloat row_align, gfloat col_align) +{ } -void gtk_clist_set_column_auto_resize(GtkCList *clist,gint column, - gboolean auto_resize) { - if (clist && column>=0 && column<clist->ncols) { - clist->cols[column].auto_resize=auto_resize; - } +void gtk_clist_set_compare_func(GtkCList *clist, + GtkCListCompareFunc cmp_func) +{ + if (clist) + clist->cmp_func = cmp_func; } -void gtk_clist_update_selection(GtkWidget *widget) { - GtkCList *clist=GTK_CLIST(widget); - gint i; - g_list_free(clist->selection); - clist->selection=NULL; - if (widget->hWnd==NULL) return; - for (i=0;i<g_slist_length(clist->rows);i++) { - if (SendMessage(widget->hWnd,LB_GETSEL,(WPARAM)i,0) > 0) { - clist->selection=g_list_append(clist->selection,GINT_TO_POINTER(i)); - } - } +void gtk_clist_set_column_auto_resize(GtkCList *clist, gint column, + gboolean auto_resize) +{ + if (clist && column >= 0 && column < clist->ncols) { + clist->cols[column].auto_resize = auto_resize; + } } -void gtk_editable_create(GtkWidget *widget) { - GtkEditable *editable=GTK_EDITABLE(widget); - gtk_widget_create(widget); - editable->is_editable=TRUE; - editable->text=g_string_new(""); +void gtk_clist_update_selection(GtkWidget *widget) +{ + GtkCList *clist = GTK_CLIST(widget); + gint i; + + g_list_free(clist->selection); + clist->selection = NULL; + if (widget->hWnd == NULL) + return; + for (i = 0; i < g_slist_length(clist->rows); i++) { + if (SendMessage(widget->hWnd, LB_GETSEL, (WPARAM)i, 0) > 0) { + clist->selection = + g_list_append(clist->selection, GINT_TO_POINTER(i)); + } + } } -void gtk_option_menu_update_selection(GtkWidget *widget) { - LRESULT lres; - GtkMenuShell *menu; - GtkWidget *menu_item; +void gtk_editable_create(GtkWidget *widget) +{ + GtkEditable *editable = GTK_EDITABLE(widget); - if (widget->hWnd==NULL) return; - lres=SendMessage(widget->hWnd,CB_GETCURSEL,0,0); - if (lres==CB_ERR) return; + gtk_widget_create(widget); + editable->is_editable = TRUE; + editable->text = g_string_new(""); +} - menu=GTK_MENU_SHELL(gtk_option_menu_get_menu(GTK_OPTION_MENU(widget))); - if (menu) { - menu_item=GTK_WIDGET(g_slist_nth_data(menu->children,lres)); - if (menu_item) gtk_signal_emit(GTK_OBJECT(menu_item),"activate"); - } +void gtk_option_menu_update_selection(GtkWidget *widget) +{ + LRESULT lres; + GtkMenuShell *menu; + GtkWidget *menu_item; + + if (widget->hWnd == NULL) + return; + lres = SendMessage(widget->hWnd, CB_GETCURSEL, 0, 0); + if (lres == CB_ERR) + return; + + menu = GTK_MENU_SHELL(gtk_option_menu_get_menu(GTK_OPTION_MENU(widget))); + if (menu) { + menu_item = GTK_WIDGET(g_slist_nth_data(menu->children, lres)); + if (menu_item) + gtk_signal_emit(GTK_OBJECT(menu_item), "activate"); + } } void gtk_window_handle_user_size(GtkWindow *window, - GtkAllocation *allocation) { + GtkAllocation *allocation) +{ } -void gtk_window_handle_minmax_size(GtkWindow *window,LPMINMAXINFO minmax) { +void gtk_window_handle_minmax_size(GtkWindow *window, LPMINMAXINFO minmax) +{ GtkRequisition *req; req = >K_WIDGET(window)->requisition; t@@ -4628,268 +5283,311 @@ void gtk_window_handle_minmax_size(GtkWindow *window,LPMINMAXINFO minmax) { } void gtk_window_set_initial_position(GtkWindow *window, - GtkAllocation *allocation) { - RECT rect; - GtkWidget *widget=GTK_WIDGET(window); - GetWindowRect(GetDesktopWindow(),&rect); - - if (widget->parent) { - allocation->x = rect.left+(rect.right-rect.left-allocation->width)/2; - allocation->y = rect.top+(rect.bottom-rect.top-allocation->height)/2; - if (allocation->x < 0) allocation->x = 0; - if (allocation->y < 0) allocation->y = 0; - if (widget->hWnd) SetWindowPos(widget->hWnd,HWND_TOP,allocation->x, - allocation->y,0,0,SWP_NOSIZE|SWP_NOZORDER); - } + GtkAllocation *allocation) +{ + RECT rect; + GtkWidget *widget = GTK_WIDGET(window); + + GetWindowRect(GetDesktopWindow(), &rect); + + if (widget->parent) { + allocation->x = + rect.left + (rect.right - rect.left - allocation->width) / 2; + allocation->y = + rect.top + (rect.bottom - rect.top - allocation->height) / 2; + if (allocation->x < 0) + allocation->x = 0; + if (allocation->y < 0) + allocation->y = 0; + if (widget->hWnd) + SetWindowPos(widget->hWnd, HWND_TOP, allocation->x, + allocation->y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); + } } void gtk_window_handle_auto_size(GtkWindow *window, - GtkAllocation *allocation) { - GtkWidget *widget=GTK_WIDGET(window); - if (allocation->width < window->default_width) { - allocation->width=window->default_width; - } - if (allocation->height < window->default_height) { - allocation->height=window->default_height; - } - if (allocation->width < widget->allocation.width) { - allocation->width=widget->allocation.width; - } - if (allocation->height < widget->allocation.height) { - allocation->height=widget->allocation.height; - } + GtkAllocation *allocation) +{ + GtkWidget *widget = GTK_WIDGET(window); + + if (allocation->width < window->default_width) { + allocation->width = window->default_width; + } + if (allocation->height < window->default_height) { + allocation->height = window->default_height; + } + if (allocation->width < widget->allocation.width) { + allocation->width = widget->allocation.width; + } + if (allocation->height < widget->allocation.height) { + allocation->height = widget->allocation.height; + } } -void gtk_paned_set_position(GtkPaned *paned,gint position) { - GtkAllocation allocation; - if (position<0) position=0; - if (position>100) position=100; - paned->handle_pos=position; - memcpy(&allocation,&paned->true_alloc,sizeof(GtkAllocation)); - gtk_widget_set_size(GTK_WIDGET(paned),&allocation); +void gtk_paned_set_position(GtkPaned *paned, gint position) +{ + GtkAllocation allocation; + + if (position < 0) + position = 0; + if (position > 100) + position = 100; + paned->handle_pos = position; + memcpy(&allocation, &paned->true_alloc, sizeof(GtkAllocation)); + gtk_widget_set_size(GTK_WIDGET(paned), &allocation); } -void gtk_misc_set_alignment(GtkMisc *misc,gfloat xalign,gfloat yalign) { +void gtk_misc_set_alignment(GtkMisc *misc, gfloat xalign, gfloat yalign) +{ } -GtkWidget *gtk_progress_bar_new() { - GtkProgressBar *prog; +GtkWidget *gtk_progress_bar_new() +{ + GtkProgressBar *prog; - prog=GTK_PROGRESS_BAR(GtkNewObject(&GtkProgressBarClass)); - prog->orient=GTK_PROGRESS_LEFT_TO_RIGHT; - prog->position=0; + prog = GTK_PROGRESS_BAR(GtkNewObject(&GtkProgressBarClass)); + prog->orient = GTK_PROGRESS_LEFT_TO_RIGHT; + prog->position = 0; - return GTK_WIDGET(prog); + return GTK_WIDGET(prog); } void gtk_progress_bar_set_orientation(GtkProgressBar *pbar, - GtkProgressBarOrientation orientation) { - pbar->orient=orientation; + GtkProgressBarOrientation orientation) +{ + pbar->orient = orientation; } -void gtk_progress_bar_update(GtkProgressBar *pbar,gfloat percentage) { - GtkWidget *widget; +void gtk_progress_bar_update(GtkProgressBar *pbar, gfloat percentage) +{ + GtkWidget *widget; - widget=GTK_WIDGET(pbar); - pbar->position = percentage; - if (GTK_WIDGET_REALIZED(widget)) { - SendMessage(widget->hWnd,PBM_SETPOS,(WPARAM)(10000.0*pbar->position),0); - } + widget = GTK_WIDGET(pbar); + pbar->position = percentage; + if (GTK_WIDGET_REALIZED(widget)) { + SendMessage(widget->hWnd, PBM_SETPOS, + (WPARAM)(10000.0 * pbar->position), 0); + } } void gtk_progress_bar_size_request(GtkWidget *widget, - GtkRequisition *requisition) { - SIZE size; + GtkRequisition *requisition) +{ + SIZE size; - if (GetTextSize(widget->hWnd, "Sample", &size, defFont)) { - requisition->width = size.cx; - requisition->height = size.cy; - } + if (GetTextSize(widget->hWnd, "Sample", &size, defFont)) { + requisition->width = size.cx; + requisition->height = size.cy; + } } -void gtk_progress_bar_realize(GtkWidget *widget) { - HWND Parent; - GtkProgressBar *prog; +void gtk_progress_bar_realize(GtkWidget *widget) +{ + HWND Parent; + GtkProgressBar *prog; + + prog = GTK_PROGRESS_BAR(widget); + Parent = gtk_get_parent_hwnd(widget); + widget->hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, PROGRESS_CLASS, "", + WS_CHILD, + widget->allocation.x, widget->allocation.y, + widget->allocation.width, + widget->allocation.height, Parent, NULL, + hInst, NULL); + gtk_set_default_font(widget->hWnd); + SendMessage(widget->hWnd, PBM_SETRANGE, 0, MAKELPARAM(0, 10000)); + SendMessage(widget->hWnd, PBM_SETPOS, (WPARAM)(10000.0 * prog->position), 0); +} + +gint GtkMessageBox(GtkWidget *parent, const gchar *Text, + const gchar *Title, gint Options) +{ + gint retval; + + RecurseLevel++; + retval = MessageBox(parent && parent->hWnd ? parent->hWnd : NULL, + Text, Title, Options); + RecurseLevel--; - prog=GTK_PROGRESS_BAR(widget); - Parent=gtk_get_parent_hwnd(widget); - widget->hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,PROGRESS_CLASS,"", - WS_CHILD, - widget->allocation.x,widget->allocation.y, - widget->allocation.width,widget->allocation.height, - Parent,NULL,hInst,NULL); - gtk_set_default_font(widget->hWnd); - SendMessage(widget->hWnd,PBM_SETRANGE,0,MAKELPARAM(0,10000)); - SendMessage(widget->hWnd,PBM_SETPOS,(WPARAM)(10000.0*prog->position),0); + return retval; } -gint GtkMessageBox(GtkWidget *parent,const gchar *Text, - const gchar *Title,gint Options) { - gint retval; +guint gtk_timeout_add(guint32 interval, GtkFunction function, + gpointer data) +{ + GtkTimeout *timeout; + GSList *list; + guint id = 1; + + /* Get an unused ID */ + list = GtkTimeouts; + while (list) { + timeout = (GtkTimeout *)list->data; + if (timeout->id == id) { + id++; + list = GtkTimeouts; + } else { + list = g_slist_next(list); + } + } + + timeout = g_new(GtkTimeout, 1); + timeout->interval = interval; + timeout->function = function; + timeout->data = data; - RecurseLevel++; - retval = MessageBox(parent && parent->hWnd ? parent->hWnd : NULL, - Text,Title,Options); - RecurseLevel--; + timeout->id = SetTimer(TopLevel, id, interval, NULL); + if (timeout->id == 0) { + g_warning("Failed to create timer!"); + } - return retval; + GtkTimeouts = g_slist_append(GtkTimeouts, timeout); + return timeout->id; } -guint gtk_timeout_add(guint32 interval,GtkFunction function,gpointer data) { - GtkTimeout *timeout; - GSList *list; - guint id=1; +void gtk_timeout_remove(guint timeout_handler_id) +{ + GSList *list; + GtkTimeout *timeout; -/* Get an unused ID */ - list=GtkTimeouts; - while (list) { - timeout=(GtkTimeout *)list->data; - if (timeout->id == id) { - id++; list=GtkTimeouts; - } else { - list=g_slist_next(list); - } - } - - timeout=g_new(GtkTimeout,1); - timeout->interval = interval; - timeout->function = function; - timeout->data = data; - - timeout->id=SetTimer(TopLevel,id,interval,NULL); - if (timeout->id==0) { - g_warning("Failed to create timer!"); - } - - GtkTimeouts = g_slist_append(GtkTimeouts,timeout); - return timeout->id; -} - -void gtk_timeout_remove(guint timeout_handler_id) { - GSList *list; - GtkTimeout *timeout; - for (list=GtkTimeouts;list;list=g_slist_next(list)) { - timeout=(GtkTimeout *)list->data; - if (timeout->id == timeout_handler_id) { - if (KillTimer(TopLevel,timeout->id)==0) { - g_warning("Failed to kill timer!"); - } - GtkTimeouts=g_slist_remove(GtkTimeouts,timeout); - g_free(timeout); - break; + for (list = GtkTimeouts; list; list = g_slist_next(list)) { + timeout = (GtkTimeout *)list->data; + if (timeout->id == timeout_handler_id) { + if (KillTimer(TopLevel, timeout->id) == 0) { + g_warning("Failed to kill timer!"); } - } -} - -#else /* CYGWIN */ -guint SetAccelerator(GtkWidget *labelparent,gchar *Text, - GtkWidget *sendto,gchar *signal, - GtkAccelGroup *accel_group) { - guint AccelKey; - AccelKey=gtk_label_parse_uline(GTK_LABEL(GTK_BIN(labelparent)->child),Text); - if (sendto && AccelKey) { - gtk_widget_add_accelerator(sendto,signal,accel_group,AccelKey,0, - GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE); - } - return AccelKey; -} - -GtkWidget *gtk_scrolled_text_new(GtkAdjustment *hadj,GtkAdjustment *vadj, - GtkWidget **pack_widg) { - GtkWidget *hbox,*text,*vscroll; - GtkAdjustment *adj; - hbox=gtk_hbox_new(FALSE,0); - adj=(GtkAdjustment *)gtk_adjustment_new(0.0,0.0,100.0,1.0,10.0,10.0); - text=gtk_text_new(NULL,adj); - gtk_box_pack_start(GTK_BOX(hbox),text,TRUE,TRUE,0); - vscroll=gtk_vscrollbar_new(adj); - gtk_box_pack_start(GTK_BOX(hbox),vscroll,FALSE,FALSE,0); - *pack_widg=hbox; - return text; + GtkTimeouts = g_slist_remove(GtkTimeouts, timeout); + g_free(timeout); + break; + } + } +} + +#else /* CYGWIN */ +guint SetAccelerator(GtkWidget *labelparent, gchar *Text, + GtkWidget *sendto, gchar *signal, + GtkAccelGroup *accel_group) +{ + guint AccelKey; + + AccelKey = + gtk_label_parse_uline(GTK_LABEL(GTK_BIN(labelparent)->child), Text); + if (sendto && AccelKey) { + gtk_widget_add_accelerator(sendto, signal, accel_group, AccelKey, 0, + GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE); + } + return AccelKey; +} + +GtkWidget *gtk_scrolled_text_new(GtkAdjustment *hadj, GtkAdjustment *vadj, + GtkWidget **pack_widg) +{ + GtkWidget *hbox, *text, *vscroll; + GtkAdjustment *adj; + + hbox = gtk_hbox_new(FALSE, 0); + adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0.0, 100.0, 1.0, 10.0, 10.0); + text = gtk_text_new(NULL, adj); + gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 0); + vscroll = gtk_vscrollbar_new(adj); + gtk_box_pack_start(GTK_BOX(hbox), vscroll, FALSE, FALSE, 0); + *pack_widg = hbox; + return text; } GtkWidget *gtk_scrolled_clist_new_with_titles(gint columns, gchar *titles[], - GtkWidget **pack_widg) { - GtkWidget *scrollwin,*clist; - clist=gtk_clist_new_with_titles(columns,titles); - scrollwin=gtk_scrolled_window_new(NULL,NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), - GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); - gtk_container_add(GTK_CONTAINER(scrollwin),clist); - *pack_widg=scrollwin; - return clist; -} - -static void DestroyGtkMessageBox(GtkWidget *widget,gpointer data) { - gtk_main_quit(); -} - -static void GtkMessageBoxCallback(GtkWidget *widget,gpointer data) { - gint *retval; - GtkWidget *dialog; - dialog=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW); - retval=(gint *)gtk_object_get_data(GTK_OBJECT(widget),"retval"); - if (retval) *retval=GPOINTER_TO_INT(data); - gtk_widget_destroy(dialog); -} - -gint GtkMessageBox(GtkWidget *parent,const gchar *Text, - const gchar *Title,gint Options) { - GtkWidget *dialog,*button,*label,*vbox,*hbbox,*hsep; - GtkAccelGroup *accel_group; - gint i; - static gint retval; - gboolean imm_return; - gchar *ButtonData[MB_MAX] = { N_("OK"), N_("Cancel"), - N_("_Yes"), N_("_No") }; - - imm_return = Options & MB_IMMRETURN; - dialog=gtk_window_new(GTK_WINDOW_DIALOG); - accel_group=gtk_accel_group_new(); - gtk_window_add_accel_group(GTK_WINDOW(dialog),accel_group); - gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); - gtk_container_set_border_width(GTK_CONTAINER(dialog),7); - if (parent) gtk_window_set_transient_for(GTK_WINDOW(dialog), - GTK_WINDOW(parent)); - if (!imm_return) { - gtk_signal_connect(GTK_OBJECT(dialog),"destroy", - GTK_SIGNAL_FUNC(DestroyGtkMessageBox),NULL); - } - if (Title) gtk_window_set_title(GTK_WINDOW(dialog),Title); - - vbox=gtk_vbox_new(FALSE,7); - - if (Text) { - label=gtk_label_new(Text); - 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); - - retval=MB_CANCEL; - - hbbox=gtk_hbutton_box_new(); - for (i=0;i<MB_MAX;i++) { - if (Options & (1<<i)) { - button=gtk_button_new_with_label(""); - SetAccelerator(button,_(ButtonData[i]),button, - "clicked",accel_group); - if (!imm_return) { - gtk_object_set_data(GTK_OBJECT(button),"retval",&retval); - } - gtk_signal_connect(GTK_OBJECT(button),"clicked", - GTK_SIGNAL_FUNC(GtkMessageBoxCallback), - GINT_TO_POINTER(1<<i)); - gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); + GtkWidget **pack_widg) +{ + GtkWidget *scrollwin, *clist; + + clist = gtk_clist_new_with_titles(columns, titles); + scrollwin = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_container_add(GTK_CONTAINER(scrollwin), clist); + *pack_widg = scrollwin; + return clist; +} + +static void DestroyGtkMessageBox(GtkWidget *widget, gpointer data) +{ + gtk_main_quit(); +} + +static void GtkMessageBoxCallback(GtkWidget *widget, gpointer data) +{ + gint *retval; + GtkWidget *dialog; + + dialog = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); + retval = (gint *)gtk_object_get_data(GTK_OBJECT(widget), "retval"); + if (retval) + *retval = GPOINTER_TO_INT(data); + gtk_widget_destroy(dialog); +} + +gint GtkMessageBox(GtkWidget *parent, const gchar *Text, + const gchar *Title, gint Options) +{ + GtkWidget *dialog, *button, *label, *vbox, *hbbox, *hsep; + GtkAccelGroup *accel_group; + gint i; + static gint retval; + gboolean imm_return; + gchar *ButtonData[MB_MAX] = { + N_("OK"), N_("Cancel"), N_("_Yes"), N_("_No") + }; + + imm_return = Options & MB_IMMRETURN; + dialog = gtk_window_new(GTK_WINDOW_DIALOG); + accel_group = gtk_accel_group_new(); + gtk_window_add_accel_group(GTK_WINDOW(dialog), accel_group); + gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); + gtk_container_set_border_width(GTK_CONTAINER(dialog), 7); + if (parent) + gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(parent)); + if (!imm_return) { + gtk_signal_connect(GTK_OBJECT(dialog), "destroy", + GTK_SIGNAL_FUNC(DestroyGtkMessageBox), NULL); + } + if (Title) + gtk_window_set_title(GTK_WINDOW(dialog), Title); + + vbox = gtk_vbox_new(FALSE, 7); + + if (Text) { + label = gtk_label_new(Text); + 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); + + retval = MB_CANCEL; + + hbbox = gtk_hbutton_box_new(); + for (i = 0; i < MB_MAX; i++) { + if (Options & (1 << i)) { + button = gtk_button_new_with_label(""); + SetAccelerator(button, _(ButtonData[i]), button, + "clicked", accel_group); + if (!imm_return) { + gtk_object_set_data(GTK_OBJECT(button), "retval", &retval); } - } - gtk_box_pack_start(GTK_BOX(vbox),hbbox,TRUE,TRUE,0); - gtk_container_add(GTK_CONTAINER(dialog),vbox); - gtk_widget_show_all(dialog); - if (!imm_return) gtk_main(); - return retval; + gtk_signal_connect(GTK_OBJECT(button), "clicked", + GTK_SIGNAL_FUNC(GtkMessageBoxCallback), + GINT_TO_POINTER(1 << 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); + if (!imm_return) + gtk_main(); + return retval; } static void gtk_url_set_cursor(GtkWidget *widget, GtkWidget *label) t@@ -4922,7 +5620,6 @@ static gboolean gtk_url_triggered(GtkWidget *widget, GdkEventButton *event, _exit(1); } } - #endif return TRUE; } t@@ -4952,15 +5649,16 @@ GtkWidget *gtk_url_new(const gchar *text, const gchar *target, /* Make the text underlined */ len = strlen(text); - pattern = g_new(gchar, len+1); - for (i = 0; i < len; i++) pattern[i] = '_'; + pattern = g_new(gchar, len + 1); + + for (i = 0; i < len; i++) + pattern[i] = '_'; pattern[len] = '\0'; gtk_label_set_pattern(GTK_LABEL(label), pattern); g_free(pattern); - /* We cannot set the cursor until the widget is realized, so - * set up a handler to do this later - */ + /* We cannot set the cursor until the widget is realized, so set up a + * handler to do this later */ gtk_signal_connect(GTK_OBJECT(label), "realize", GTK_SIGNAL_FUNC(gtk_url_set_cursor), label); t@@ -4977,4 +5675,4 @@ GtkWidget *gtk_url_new(const gchar *text, const gchar *target, return eventbox; } -#endif /* CYGWIN */ +#endif /* CYGWIN */ (DIR) diff --git a/src/gtkport.h b/src/gtkport.h t@@ -1,22 +1,24 @@ -/* gtkport.h Portable "almost-GTK+" for Unix/Win32 */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * gtkport.h Portable "almost-GTK+" for Unix/Win32 * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __GTKPORT_H__ #define __GTKPORT_H__ t@@ -42,44 +44,44 @@ extern HICON mainIcon; typedef enum { - GTK_WINDOW_TOPLEVEL, GTK_WINDOW_DIALOG, GTK_WINDOW_POPUP + GTK_WINDOW_TOPLEVEL, GTK_WINDOW_DIALOG, GTK_WINDOW_POPUP } GtkWindowType; typedef enum { - GTK_ACCEL_VISIBLE = 1 << 0, - GTK_ACCEL_SIGNAL_VISIBLE = 1 << 1 + GTK_ACCEL_VISIBLE = 1 << 0, + GTK_ACCEL_SIGNAL_VISIBLE = 1 << 1 } GtkAccelFlags; typedef enum { - GTK_VISIBILITY_NONE, - GTK_VISIBILITY_PARTIAL, - GTK_VISIBILITY_FULL + GTK_VISIBILITY_NONE, + GTK_VISIBILITY_PARTIAL, + GTK_VISIBILITY_FULL } GtkVisibility; typedef enum { - GTK_PROGRESS_LEFT_TO_RIGHT, - GTK_PROGRESS_RIGHT_TO_LEFT, - GTK_PROGRESS_BOTTOM_TO_TOP, - GTK_PROGRESS_TOP_TO_BOTTOM + GTK_PROGRESS_LEFT_TO_RIGHT, + GTK_PROGRESS_RIGHT_TO_LEFT, + GTK_PROGRESS_BOTTOM_TO_TOP, + GTK_PROGRESS_TOP_TO_BOTTOM } GtkProgressBarOrientation; typedef enum { - GTK_EXPAND = 1 << 0, - GTK_SHRINK = 1 << 1, - GTK_FILL = 1 << 2 + GTK_EXPAND = 1 << 0, + GTK_SHRINK = 1 << 1, + GTK_FILL = 1 << 2 } GtkAttachOptions; typedef enum { - GTK_SELECTION_SINGLE, - GTK_SELECTION_BROWSE, - GTK_SELECTION_MULTIPLE, - GTK_SELECTION_EXTENDED + GTK_SELECTION_SINGLE, + GTK_SELECTION_BROWSE, + GTK_SELECTION_MULTIPLE, + GTK_SELECTION_EXTENDED } GtkSelectionMode; typedef enum { - GDK_INPUT_READ = 1 << 0, - GDK_INPUT_WRITE = 1 << 1, - GDK_INPUT_EXCEPTION = 1 << 2 + GDK_INPUT_READ = 1 << 0, + GDK_INPUT_WRITE = 1 << 1, + GDK_INPUT_EXCEPTION = 1 << 2 } GdkInputCondition; #define GDK_KP_0 0xFFB0 t@@ -93,20 +95,20 @@ typedef enum { #define GDK_KP_8 0xFFB8 #define GDK_KP_9 0xFFB9 -typedef gint (*GtkFunction)(gpointer data); -typedef void (*GdkInputFunction)(gpointer data,gint source, - GdkInputCondition condition); -typedef gchar* (*GtkTranslateFunc)(const gchar *path,gpointer func_data); -typedef void (*GtkDestroyNotify)(gpointer data); +typedef gint (*GtkFunction) (gpointer data); +typedef void (*GdkInputFunction) (gpointer data, gint source, + GdkInputCondition condition); +typedef gchar *(*GtkTranslateFunc) (const gchar *path, gpointer func_data); +typedef void (*GtkDestroyNotify) (gpointer data); typedef enum { - GTK_REALIZED = 1 << 6, - GTK_VISIBLE = 1 << 8, - GTK_SENSITIVE = 1 << 10, - GTK_CAN_FOCUS = 1 << 11, - GTK_HAS_FOCUS = 1 << 12, - GTK_CAN_DEFAULT = 1 << 13, - GTK_IS_DEFAULT = 1 << 14 + GTK_REALIZED = 1 << 6, + GTK_VISIBLE = 1 << 8, + GTK_SENSITIVE = 1 << 10, + GTK_CAN_FOCUS = 1 << 11, + GTK_HAS_FOCUS = 1 << 12, + GTK_CAN_DEFAULT = 1 << 13, + GTK_IS_DEFAULT = 1 << 14 } GtkWidgetFlags; #define GTK_VISIBLE 1 t@@ -121,9 +123,9 @@ typedef struct _GtkSignalType GtkSignalType; typedef void (*GtkSignalFunc) (); typedef void (*GtkItemFactoryCallback) (); -typedef void (*GtkSignalMarshaller)(GtkObject *object,GSList *actions, - GtkSignalFunc default_action, - va_list args); +typedef void (*GtkSignalMarshaller) (GtkObject *object, GSList *actions, + GtkSignalFunc default_action, + va_list args); typedef struct _GtkMenuShell GtkMenuShell; typedef struct _GtkMenuBar GtkMenuBar; typedef struct _GtkMenuItem GtkMenuItem; t@@ -142,99 +144,99 @@ typedef struct _GtkHPaned GtkHPaned; typedef struct _GtkOptionMenu GtkOptionMenu; struct _GtkAccelGroup { - ACCEL *accel; /* list of ACCEL structures */ - gint numaccel; + ACCEL *accel; /* list of ACCEL structures */ + gint numaccel; }; struct _GtkSignalType { - gchar *name; - GtkSignalMarshaller marshaller; - GtkSignalFunc default_action; + gchar *name; + GtkSignalMarshaller marshaller; + GtkSignalFunc default_action; }; struct _GtkClass { - gchar *Name; - GtkClass *parent; - gint Size; - GtkSignalType *signals; + gchar *Name; + GtkClass *parent; + gint Size; + GtkSignalType *signals; }; typedef GtkClass *GtkType; struct _GtkObject { - GtkClass *klass; - GData *object_data; - GData *signals; - guint32 flags; + GtkClass *klass; + GData *object_data; + GData *signals; + guint32 flags; }; struct _GtkAdjustment { - GtkObject object; - gfloat value,lower,upper; - gfloat step_increment,page_increment,page_size; + GtkObject object; + gfloat value, lower, upper; + gfloat step_increment, page_increment, page_size; }; struct _GtkRequisition { - gint16 width, height; + gint16 width, height; }; struct _GtkAllocation { - gint16 x,y,width,height; + gint16 x, y, width, height; }; struct _GtkWidget { - GtkObject object; - HWND hWnd; - GtkRequisition requisition; - GtkAllocation allocation; - GtkRequisition usize; - GtkWidget *parent; + GtkObject object; + HWND hWnd; + GtkRequisition requisition; + GtkAllocation allocation; + GtkRequisition usize; + GtkWidget *parent; }; struct _GtkMisc { - GtkWidget widget; + GtkWidget widget; }; struct _GtkProgressBar { - GtkWidget widget; - GtkProgressBarOrientation orient; - gfloat position; + GtkWidget widget; + GtkProgressBarOrientation orient; + gfloat position; }; struct _GtkSeparator { - GtkWidget widget; + GtkWidget widget; }; struct _GtkHSeparator { - GtkSeparator separator; + GtkSeparator separator; }; struct _GtkVSeparator { - GtkSeparator separator; + GtkSeparator separator; }; struct _GtkMenuItem { - GtkWidget widget; - GtkMenu *submenu; - gint ID; - gint accelind; - gchar *text; + GtkWidget widget; + GtkMenu *submenu; + gint ID; + gint accelind; + gchar *text; }; struct _GtkMenuShell { - GtkWidget widget; - HMENU menu; - GSList *children; + GtkWidget widget; + HMENU menu; + GSList *children; }; struct _GtkMenu { - GtkMenuShell menushell; - guint active; + GtkMenuShell menushell; + guint active; }; struct _GtkMenuBar { - GtkMenuShell menushell; - gint LastID; + GtkMenuShell menushell; + gint LastID; }; typedef struct _GtkEditable GtkEditable; t@@ -243,32 +245,32 @@ typedef struct _GtkText GtkText; typedef struct _GtkSpinButton GtkSpinButton; struct _GtkEditable { - GtkWidget widget; - GString *text; - gint is_editable : 1; + GtkWidget widget; + GString *text; + gint is_editable:1; }; struct _GtkEntry { - GtkEditable editable; - gint is_visible : 1; + GtkEditable editable; + gint is_visible:1; }; struct _GtkSpinButton { - GtkEntry entry; - GtkAdjustment *adj; - HWND updown; + GtkEntry entry; + GtkAdjustment *adj; + HWND updown; }; struct _GtkText { - GtkEditable editable; - gint word_wrap : 1; + GtkEditable editable; + gint word_wrap:1; }; typedef struct _GtkLabel GtkLabel; struct _GtkLabel { - GtkWidget widget; - gchar *text; + GtkWidget widget; + gchar *text; }; typedef struct _GtkUrl GtkUrl; t@@ -281,32 +283,32 @@ struct _GtkUrl { typedef struct _GtkContainer GtkContainer; struct _GtkContainer { - GtkWidget widget; - GtkWidget *child; - guint border_width : 16; + GtkWidget widget; + GtkWidget *child; + guint border_width:16; }; struct _GtkPanedChild { - GtkWidget *widget; - gint resize : 1; - gint shrink : 1; + GtkWidget *widget; + gint resize:1; + gint shrink:1; }; struct _GtkPaned { - GtkContainer container; - GtkPanedChild children[2]; - GtkAllocation true_alloc; - gint handle_size,gutter_size; - gint handle_pos; - gint Tracking : 1; + GtkContainer container; + GtkPanedChild children[2]; + GtkAllocation true_alloc; + gint handle_size, gutter_size; + gint handle_pos; + gint Tracking:1; }; struct _GtkVPaned { - GtkPaned paned; + GtkPaned paned; }; struct _GtkHPaned { - GtkPaned paned; + GtkPaned paned; }; typedef struct _GtkBox GtkBox; t@@ -321,91 +323,91 @@ typedef struct _GtkCListColumn GtkCListColumn; typedef struct _GtkItemFactoryEntry GtkItemFactoryEntry; typedef struct _GtkItemFactory GtkItemFactory; -typedef gint (*GtkCListCompareFunc)(GtkCList *clist,gconstpointer ptr1, - gconstpointer ptr2); +typedef gint (*GtkCListCompareFunc) (GtkCList *clist, gconstpointer ptr1, + gconstpointer ptr2); struct _GtkItemFactoryEntry { - gchar *path; - gchar *accelerator; - GtkItemFactoryCallback callback; - guint callback_action; - gchar *item_type; + gchar *path; + gchar *accelerator; + GtkItemFactoryCallback callback; + guint callback_action; + gchar *item_type; }; struct _GtkItemFactory { - GtkObject object; - GSList *children; - gchar *path; - GtkAccelGroup *accel_group; - GtkWidget *top_widget; - GtkTranslateFunc translate_func; - gpointer translate_data; + GtkObject object; + GSList *children; + gchar *path; + GtkAccelGroup *accel_group; + GtkWidget *top_widget; + GtkTranslateFunc translate_func; + gpointer translate_data; }; struct _GtkBoxChild { - GtkWidget *widget; - guint expand : 1; - guint fill : 1; + GtkWidget *widget; + guint expand:1; + guint fill:1; }; struct _GtkBox { - GtkContainer container; - GList *children; - guint16 spacing; - gint maxreq; - guint homogeneous : 1; + GtkContainer container; + GList *children; + guint16 spacing; + gint maxreq; + guint homogeneous:1; }; struct _GtkHBox { - GtkBox box; + GtkBox box; }; struct _GtkVBox { - GtkBox box; + GtkBox box; }; struct _GtkNotebookChild { - GtkWidget *child,*tab_label; + GtkWidget *child, *tab_label; }; struct _GtkNotebook { - GtkContainer container; - GSList *children; - gint selection; + GtkContainer container; + GSList *children; + gint selection; }; struct _GtkCListColumn { - gchar *title; - gint width; - guint visible : 1; - guint resizeable : 1; - guint auto_resize : 1; - guint button_passive : 1; + gchar *title; + gint width; + guint visible:1; + guint resizeable:1; + guint auto_resize:1; + guint button_passive:1; }; struct _GtkCListRow { - gpointer data; - gchar **text; + gpointer data; + gchar **text; }; struct _GtkCList { - GtkContainer container; - gint ncols; - HWND header; - gint16 header_size; - GSList *rows; - GtkCListColumn *cols; - GList *selection; - GtkSelectionMode mode; - GtkCListCompareFunc cmp_func; - gint auto_sort : 1; + GtkContainer container; + gint ncols; + HWND header; + gint16 header_size; + GSList *rows; + GtkCListColumn *cols; + GList *selection; + GtkSelectionMode mode; + GtkCListCompareFunc cmp_func; + gint auto_sort:1; }; typedef struct _GtkBin GtkBin; struct _GtkBin { - GtkContainer container; - GtkWidget *child; + GtkContainer container; + GtkWidget *child; }; typedef struct _GtkFrame GtkFrame; t@@ -415,51 +417,51 @@ typedef struct _GtkCheckButton GtkCheckButton; typedef struct _GtkRadioButton GtkRadioButton; struct _GtkFrame { - GtkBin bin; - gchar *text; - GtkRequisition label_req; + GtkBin bin; + gchar *text; + GtkRequisition label_req; }; struct _GtkButton { - GtkWidget widget; - gchar *text; + GtkWidget widget; + gchar *text; }; struct _GtkOptionMenu { - GtkButton button; - GtkWidget *menu; - guint selection; + GtkButton button; + GtkWidget *menu; + guint selection; }; struct _GtkToggleButton { - GtkButton button; - gboolean toggled; + GtkButton button; + gboolean toggled; }; struct _GtkCheckButton { - GtkToggleButton toggle; + GtkToggleButton toggle; }; struct _GtkRadioButton { - GtkCheckButton check; - GSList *group; + GtkCheckButton check; + GSList *group; }; typedef struct _GtkWindow GtkWindow; struct _GtkWindow { - GtkBin bin; - GtkWindowType type; - gchar *title; - gint default_width,default_height; - GtkMenuBar *menu_bar; - GtkAccelGroup *accel_group; - GtkWidget *focus; - HACCEL hAccel; - guint modal : 1; - guint allow_shrink : 1; - guint allow_grow : 1; - guint auto_shrink : 1; + GtkBin bin; + GtkWindowType type; + gchar *title; + gint default_width, default_height; + GtkMenuBar *menu_bar; + GtkAccelGroup *accel_group; + GtkWidget *focus; + HACCEL hAccel; + guint modal:1; + guint allow_shrink:1; + guint allow_grow:1; + guint auto_shrink:1; }; typedef struct _GtkTable GtkTable; t@@ -467,23 +469,23 @@ typedef struct _GtkTableChild GtkTableChild; typedef struct _GtkTableRowCol GtkTableRowCol; struct _GtkTable { - GtkContainer container; - GList *children; - GtkTableRowCol *rows,*cols; - guint16 nrows,ncols; - guint16 column_spacing,row_spacing; - guint homogeneous : 1; + GtkContainer container; + GList *children; + GtkTableRowCol *rows, *cols; + guint16 nrows, ncols; + guint16 column_spacing, row_spacing; + guint homogeneous:1; }; struct _GtkTableChild { - GtkWidget *widget; - guint16 left_attach,right_attach,top_attach,bottom_attach; + GtkWidget *widget; + guint16 left_attach, right_attach, top_attach, bottom_attach; }; struct _GtkTableRowCol { - guint16 requisition; - guint16 allocation; - gint16 spacing; + guint16 requisition; + guint16 allocation; + gint16 spacing; }; #define GTK_OBJECT(obj) ((GtkObject *)(obj)) t@@ -538,133 +540,146 @@ void gtk_widget_hide_all(GtkWidget *widget); void gtk_widget_hide(GtkWidget *widget); void gtk_widget_destroy(GtkWidget *widget); void gtk_widget_realize(GtkWidget *widget); -void gtk_widget_set_sensitive(GtkWidget *widget,gboolean sensitive); -void gtk_widget_size_request(GtkWidget *widget,GtkRequisition *requisition); -void gtk_widget_set_size(GtkWidget *widget,GtkAllocation *allocation); -GtkWidget *gtk_widget_get_ancestor(GtkWidget *widget,GtkType type); +void gtk_widget_set_sensitive(GtkWidget *widget, gboolean sensitive); +void gtk_widget_size_request(GtkWidget *widget, + GtkRequisition *requisition); +void gtk_widget_set_size(GtkWidget *widget, GtkAllocation *allocation); +GtkWidget *gtk_widget_get_ancestor(GtkWidget *widget, GtkType type); GtkWidget *gtk_window_new(GtkWindowType type); -void gtk_window_set_title(GtkWindow *window,const gchar *title); -void gtk_window_set_default_size(GtkWindow *window,gint width,gint height); -void gtk_window_set_transient_for(GtkWindow *window,GtkWindow *parent); -void gtk_window_set_policy(GtkWindow *window,gint allow_shrink, - gint allow_grow,gint auto_shrink); -void gtk_container_add(GtkContainer *container,GtkWidget *widget); -void gtk_container_set_border_width(GtkContainer *container,guint border_width); +void gtk_window_set_title(GtkWindow *window, const gchar *title); +void gtk_window_set_default_size(GtkWindow *window, gint width, + gint height); +void gtk_window_set_transient_for(GtkWindow *window, GtkWindow *parent); +void gtk_window_set_policy(GtkWindow *window, gint allow_shrink, + gint allow_grow, gint auto_shrink); +void gtk_container_add(GtkContainer *container, GtkWidget *widget); +void gtk_container_set_border_width(GtkContainer *container, + guint border_width); GtkWidget *gtk_button_new_with_label(const gchar *label); GtkWidget *gtk_label_new(const gchar *text); -GtkWidget *gtk_hbox_new(gboolean homogeneous,gint spacing); -GtkWidget *gtk_vbox_new(gboolean homogeneous,gint spacing); +GtkWidget *gtk_hbox_new(gboolean homogeneous, gint spacing); +GtkWidget *gtk_vbox_new(gboolean homogeneous, gint spacing); GtkWidget *gtk_check_button_new_with_label(const gchar *label); -GtkWidget *gtk_radio_button_new_with_label(GSList *group,const gchar *label); +GtkWidget *gtk_radio_button_new_with_label(GSList *group, + const gchar *label); GtkWidget *gtk_radio_button_new_with_label_from_widget(GtkRadioButton *group, const gchar *label); GtkWidget *gtk_frame_new(const gchar *text); -GtkWidget *gtk_text_new(GtkAdjustment *hadj,GtkAdjustment *vadj); +GtkWidget *gtk_text_new(GtkAdjustment *hadj, GtkAdjustment *vadj); GtkWidget *gtk_entry_new(); -void gtk_entry_set_visibility(GtkEntry *entry,gboolean visible); -GtkWidget *gtk_table_new(guint rows,guint cols,gboolean homogeneous); -void gtk_table_resize(GtkTable *table,guint rows,guint cols); +void gtk_entry_set_visibility(GtkEntry *entry, gboolean visible); +GtkWidget *gtk_table_new(guint rows, guint cols, gboolean homogeneous); +void gtk_table_resize(GtkTable *table, guint rows, guint cols); GtkItemFactory *gtk_item_factory_new(GtkType container_type, const gchar *path, GtkAccelGroup *accel_group); void gtk_item_factory_create_item(GtkItemFactory *ifactory, GtkItemFactoryEntry *entry, - gpointer callback_data,guint callback_type); -void gtk_item_factory_create_items(GtkItemFactory *ifactory,guint n_entries, + gpointer callback_data, + guint callback_type); +void gtk_item_factory_create_items(GtkItemFactory *ifactory, + guint n_entries, GtkItemFactoryEntry *entries, gpointer callback_data); GtkWidget *gtk_item_factory_get_widget(GtkItemFactory *ifactory, const gchar *path); GtkWidget *gtk_clist_new(gint columns); -GtkWidget *gtk_clist_new_with_titles(gint columns,gchar *titles[]); -gint gtk_clist_append(GtkCList *clist,gchar *text[]); -void gtk_clist_set_column_title(GtkCList *clist,gint column,const gchar *title); -gint gtk_clist_insert(GtkCList *clist,gint row,gchar *text[]); -void gtk_clist_set_column_width(GtkCList *clist,gint column,gint width); -void gtk_clist_column_title_passive(GtkCList *clist,gint column); +GtkWidget *gtk_clist_new_with_titles(gint columns, gchar *titles[]); +gint gtk_clist_append(GtkCList *clist, gchar *text[]); +void gtk_clist_set_column_title(GtkCList *clist, gint column, + const gchar *title); +gint gtk_clist_insert(GtkCList *clist, gint row, gchar *text[]); +void gtk_clist_set_column_width(GtkCList *clist, gint column, gint width); +void gtk_clist_column_title_passive(GtkCList *clist, gint column); void gtk_clist_column_titles_passive(GtkCList *clist); -void gtk_clist_column_title_active(GtkCList *clist,gint column); +void gtk_clist_column_title_active(GtkCList *clist, gint column); void gtk_clist_column_titles_active(GtkCList *clist); -void gtk_clist_set_selection_mode(GtkCList *clist,GtkSelectionMode mode); +void gtk_clist_set_selection_mode(GtkCList *clist, GtkSelectionMode mode); void gtk_clist_sort(GtkCList *clist); void gtk_clist_freeze(GtkCList *clist); void gtk_clist_thaw(GtkCList *clist); void gtk_clist_clear(GtkCList *clist); GSList *gtk_radio_button_group(GtkRadioButton *radio_button); -void gtk_editable_insert_text(GtkEditable *editable,const gchar *new_text, - gint new_text_length,gint *position); +void gtk_editable_insert_text(GtkEditable *editable, const gchar *new_text, + gint new_text_length, gint *position); void gtk_editable_delete_text(GtkEditable *editable, - gint start_pos,gint end_pos); + gint start_pos, gint end_pos); gchar *gtk_editable_get_chars(GtkEditable *editable, - gint start_pos,gint end_pos); -void gtk_editable_set_editable(GtkEditable *editable,gboolean is_editable); -void gtk_editable_set_position(GtkEditable *editable,gint position); + gint start_pos, gint end_pos); +void gtk_editable_set_editable(GtkEditable *editable, + gboolean is_editable); +void gtk_editable_set_position(GtkEditable *editable, gint position); gint gtk_editable_get_position(GtkEditable *editable); guint gtk_text_get_length(GtkText *text); -void gtk_text_set_editable(GtkText *text,gboolean is_editable); -void gtk_text_set_word_wrap(GtkText *text,gboolean word_wrap); +void gtk_text_set_editable(GtkText *text, gboolean is_editable); +void gtk_text_set_word_wrap(GtkText *text, gboolean word_wrap); void gtk_text_freeze(GtkText *text); void gtk_text_thaw(GtkText *text); -void gtk_table_attach(GtkTable *table,GtkWidget *widget, - guint left_attach,guint right_attach, - guint top_attach,guint bottom_attach, - GtkAttachOptions xoptions,GtkAttachOptions yoptions, - guint xpadding,guint ypadding); -void gtk_table_attach_defaults(GtkTable *table,GtkWidget *widget, - guint left_attach,guint right_attach, - guint top_attach,guint bottom_attach); -void gtk_table_set_row_spacing(GtkTable *table,guint row,guint spacing); -void gtk_table_set_col_spacing(GtkTable *table,guint column,guint spacing); -void gtk_table_set_row_spacings(GtkTable *table,guint spacing); -void gtk_table_set_col_spacings(GtkTable *table,guint spacing); -void gtk_box_pack_start(GtkBox *box,GtkWidget *child,gboolean Expand, - gboolean Fill,gint Padding); +void gtk_table_attach(GtkTable *table, GtkWidget *widget, + guint left_attach, guint right_attach, + guint top_attach, guint bottom_attach, + GtkAttachOptions xoptions, GtkAttachOptions yoptions, + guint xpadding, guint ypadding); +void gtk_table_attach_defaults(GtkTable *table, GtkWidget *widget, + guint left_attach, guint right_attach, + guint top_attach, guint bottom_attach); +void gtk_table_set_row_spacing(GtkTable *table, guint row, guint spacing); +void gtk_table_set_col_spacing(GtkTable *table, guint column, + guint spacing); +void gtk_table_set_row_spacings(GtkTable *table, guint spacing); +void gtk_table_set_col_spacings(GtkTable *table, guint spacing); +void gtk_box_pack_start(GtkBox *box, GtkWidget *child, gboolean Expand, + gboolean Fill, gint Padding); void gtk_toggle_button_toggled(GtkToggleButton *toggle_button); gboolean gtk_toggle_button_get_active(GtkToggleButton *toggle_button); void gtk_toggle_button_set_active(GtkToggleButton *toggle_button, gboolean is_active); void gtk_main_quit(); void gtk_main(); -guint gtk_signal_connect(GtkObject *object,const gchar *name, - GtkSignalFunc func,gpointer func_data); -guint gtk_signal_connect_object(GtkObject *object,const gchar *name, - GtkSignalFunc func,GtkObject *slot_object); -void gtk_signal_emit(GtkObject *object,const gchar *name, ...); +guint gtk_signal_connect(GtkObject *object, const gchar *name, + GtkSignalFunc func, gpointer func_data); +guint gtk_signal_connect_object(GtkObject *object, const gchar *name, + GtkSignalFunc func, + GtkObject *slot_object); +void gtk_signal_emit(GtkObject *object, const gchar *name, ...); void SetCustomWndProc(WNDPROC wndproc); -void win32_init(HINSTANCE hInstance,HINSTANCE hPrevInstance,char *MainIcon); -void gtk_menu_shell_insert(GtkMenuShell *menu_shell,GtkWidget *child, +void win32_init(HINSTANCE hInstance, HINSTANCE hPrevInstance, + char *MainIcon); +void gtk_menu_shell_insert(GtkMenuShell *menu_shell, GtkWidget *child, gint position); -void gtk_menu_shell_append(GtkMenuShell *menu_shell,GtkWidget *child); -void gtk_menu_shell_prepend(GtkMenuShell *menu_shell,GtkWidget *child); +void gtk_menu_shell_append(GtkMenuShell *menu_shell, GtkWidget *child); +void gtk_menu_shell_prepend(GtkMenuShell *menu_shell, GtkWidget *child); GtkWidget *gtk_menu_bar_new(); -void gtk_menu_bar_insert(GtkMenuBar *menu_bar,GtkWidget *child,gint position); -void gtk_menu_bar_append(GtkMenuBar *menu_bar,GtkWidget *child); -void gtk_menu_bar_prepend(GtkMenuBar *menu_bar,GtkWidget *child); +void gtk_menu_bar_insert(GtkMenuBar *menu_bar, GtkWidget *child, + gint position); +void gtk_menu_bar_append(GtkMenuBar *menu_bar, GtkWidget *child); +void gtk_menu_bar_prepend(GtkMenuBar *menu_bar, GtkWidget *child); GtkWidget *gtk_menu_new(); -void gtk_menu_insert(GtkMenu *menu,GtkWidget *child,gint position); -void gtk_menu_append(GtkMenu *menu,GtkWidget *child); -void gtk_menu_prepend(GtkMenu *menu,GtkWidget *child); +void gtk_menu_insert(GtkMenu *menu, GtkWidget *child, gint position); +void gtk_menu_append(GtkMenu *menu, GtkWidget *child); +void gtk_menu_prepend(GtkMenu *menu, GtkWidget *child); GtkWidget *gtk_menu_item_new_with_label(const gchar *label); -void gtk_menu_item_set_submenu(GtkMenuItem *menu_item,GtkWidget *submenu); -void gtk_menu_set_active(GtkMenu *menu,guint index); +void gtk_menu_item_set_submenu(GtkMenuItem *menu_item, GtkWidget *submenu); +void gtk_menu_set_active(GtkMenu *menu, guint index); GtkWidget *gtk_notebook_new(); -void gtk_notebook_append_page(GtkNotebook *notebook,GtkWidget *child, +void gtk_notebook_append_page(GtkNotebook *notebook, GtkWidget *child, GtkWidget *tab_label); -void gtk_notebook_insert_page(GtkNotebook *notebook,GtkWidget *child, - GtkWidget *tab_label,gint position); -void gtk_notebook_set_page(GtkNotebook *notebook,gint page_num); -GtkObject *gtk_adjustment_new(gfloat value,gfloat lower,gfloat upper, - gfloat step_increment,gfloat page_increment, +void gtk_notebook_insert_page(GtkNotebook *notebook, GtkWidget *child, + GtkWidget *tab_label, gint position); +void gtk_notebook_set_page(GtkNotebook *notebook, gint page_num); +GtkObject *gtk_adjustment_new(gfloat value, gfloat lower, gfloat upper, + gfloat step_increment, gfloat page_increment, gfloat page_size); -GtkWidget *gtk_spin_button_new(GtkAdjustment *adjustment,gfloat climb_rate, - guint digits); +GtkWidget *gtk_spin_button_new(GtkAdjustment *adjustment, + gfloat climb_rate, guint digits); void gdk_input_remove(gint tag); -gint gdk_input_add(gint source,GdkInputCondition condition, - GdkInputFunction function,gpointer data); +gint gdk_input_add(gint source, GdkInputCondition condition, + GdkInputFunction function, gpointer data); GtkWidget *gtk_hseparator_new(); GtkWidget *gtk_vseparator_new(); -void gtk_object_set_data(GtkObject *object,const gchar *key,gpointer data); -gpointer gtk_object_get_data(GtkObject *object,const gchar *key); +void gtk_object_set_data(GtkObject *object, const gchar *key, + gpointer data); +gpointer gtk_object_get_data(GtkObject *object, const gchar *key); GtkAccelGroup *gtk_accel_group_new(); void gtk_accel_group_destroy(GtkAccelGroup *accel_group); void gtk_item_factory_set_translate_func(GtkItemFactory *ifactory, t@@ -673,66 +688,69 @@ void gtk_item_factory_set_translate_func(GtkItemFactory *ifactory, GtkDestroyNotify notify); void gtk_widget_grab_default(GtkWidget *widget); void gtk_widget_grab_focus(GtkWidget *widget); -void gtk_window_set_modal(GtkWindow *window,gboolean modal); -void gtk_window_add_accel_group(GtkWindow *window,GtkAccelGroup *accel_group); -void gtk_entry_set_text(GtkEntry *entry,const gchar *text); +void gtk_window_set_modal(GtkWindow *window, gboolean modal); +void gtk_window_add_accel_group(GtkWindow *window, + GtkAccelGroup *accel_group); +void gtk_entry_set_text(GtkEntry *entry, const gchar *text); void gtk_widget_add_accelerator(GtkWidget *widget, const gchar *accel_signal, GtkAccelGroup *accel_group, - guint accel_key,guint accel_mods, + guint accel_key, guint accel_mods, GtkAccelFlags accel_flags); void gtk_widget_remove_accelerator(GtkWidget *widget, GtkAccelGroup *accel_group, - guint accel_key,guint accel_mods); -extern const GtkType GTK_TYPE_WINDOW,GTK_TYPE_MENU_BAR; + guint accel_key, guint accel_mods); +extern const GtkType GTK_TYPE_WINDOW, GTK_TYPE_MENU_BAR; GtkWidget *gtk_vpaned_new(); GtkWidget *gtk_hpaned_new(); -void gtk_paned_add1(GtkPaned *paned,GtkWidget *child); -void gtk_paned_add2(GtkPaned *paned,GtkWidget *child); -void gtk_paned_pack1(GtkPaned *paned,GtkWidget *child,gboolean resize, +void gtk_paned_add1(GtkPaned *paned, GtkWidget *child); +void gtk_paned_add2(GtkPaned *paned, GtkWidget *child); +void gtk_paned_pack1(GtkPaned *paned, GtkWidget *child, gboolean resize, gboolean shrink); -void gtk_paned_pack2(GtkPaned *paned,GtkWidget *child,gboolean resize, +void gtk_paned_pack2(GtkPaned *paned, GtkWidget *child, gboolean resize, gboolean shrink); -void gtk_paned_set_position(GtkPaned *paned,gint position); +void gtk_paned_set_position(GtkPaned *paned, gint position); #define gtk_container_border_width gtk_container_set_border_width -#define gtk_hbutton_box_new() gtk_hbox_new(TRUE,5) -#define gtk_vbutton_box_new() gtk_vbox_new(TRUE,5) +#define gtk_hbutton_box_new() gtk_hbox_new(TRUE, 5) +#define gtk_vbutton_box_new() gtk_vbox_new(TRUE, 5) GtkWidget *gtk_option_menu_new(); GtkWidget *gtk_option_menu_get_menu(GtkOptionMenu *option_menu); -void gtk_option_menu_set_menu(GtkOptionMenu *option_menu,GtkWidget *menu); -void gtk_option_menu_set_history(GtkOptionMenu *option_menu,guint index); -void gtk_label_set_text(GtkLabel *label,const gchar *str); -guint gtk_label_parse_uline(GtkLabel *label,const gchar *str); -void gtk_label_get(GtkLabel *label,gchar **str); -void gtk_clist_set_row_data(GtkCList *clist,gint row,gpointer data); -gpointer gtk_clist_get_row_data(GtkCList *clist,gint row); -void gtk_clist_set_auto_sort(GtkCList *clist,gboolean auto_sort); +void gtk_option_menu_set_menu(GtkOptionMenu *option_menu, GtkWidget *menu); +void gtk_option_menu_set_history(GtkOptionMenu *option_menu, guint index); +void gtk_label_set_text(GtkLabel *label, const gchar *str); +guint gtk_label_parse_uline(GtkLabel *label, const gchar *str); +void gtk_label_get(GtkLabel *label, gchar **str); +void gtk_clist_set_row_data(GtkCList *clist, gint row, gpointer data); +gpointer gtk_clist_get_row_data(GtkCList *clist, gint row); +void gtk_clist_set_auto_sort(GtkCList *clist, gboolean auto_sort); void gtk_clist_columns_autosize(GtkCList *clist); -void gtk_text_set_point(GtkText *text,guint index); -void gtk_widget_set_usize(GtkWidget *widget,gint width,gint height); -void gtk_clist_select_row(GtkCList *clist,gint row,gint column); -GtkVisibility gtk_clist_row_is_visible(GtkCList *clist,gint row); -void gtk_clist_moveto(GtkCList *clist,gint row,gint column, - gfloat row_align,gfloat col_align); -void gtk_clist_set_compare_func(GtkCList *clist,GtkCListCompareFunc cmp_func); -void gtk_clist_set_column_auto_resize(GtkCList *clist,gint column, +void gtk_text_set_point(GtkText *text, guint index); +void gtk_widget_set_usize(GtkWidget *widget, gint width, gint height); +void gtk_clist_select_row(GtkCList *clist, gint row, gint column); +GtkVisibility gtk_clist_row_is_visible(GtkCList *clist, gint row); +void gtk_clist_moveto(GtkCList *clist, gint row, gint column, + gfloat row_align, gfloat col_align); +void gtk_clist_set_compare_func(GtkCList *clist, + GtkCListCompareFunc cmp_func); +void gtk_clist_set_column_auto_resize(GtkCList *clist, gint column, gboolean auto_resize); gint gtk_spin_button_get_value_as_int(GtkSpinButton *spin_button); -void gtk_spin_button_set_value(GtkSpinButton *spin_button,gfloat value); +void gtk_spin_button_set_value(GtkSpinButton *spin_button, gfloat value); void gtk_spin_button_set_adjustment(GtkSpinButton *spin_button, GtkAdjustment *adjustment); void gtk_spin_button_update(GtkSpinButton *spin_button); -void gtk_misc_set_alignment(GtkMisc *misc,gfloat xalign,gfloat yalign); +void gtk_misc_set_alignment(GtkMisc *misc, gfloat xalign, gfloat yalign); GtkWidget *gtk_progress_bar_new(); void gtk_progress_bar_set_orientation(GtkProgressBar *pbar, GtkProgressBarOrientation orientation); -void gtk_progress_bar_update(GtkProgressBar *pbar,gfloat percentage); -guint gtk_timeout_add(guint32 interval,GtkFunction function,gpointer data); +void gtk_progress_bar_update(GtkProgressBar *pbar, gfloat percentage); +guint gtk_timeout_add(guint32 interval, GtkFunction function, + gpointer data); void gtk_timeout_remove(guint timeout_handler_id); guint gtk_main_level(void); -#else /* CYGWIN */ +#else /* CYGWIN */ /* Include standard GTK+ headers on Unix systems */ #include <gtk/gtk.h> t@@ -760,17 +778,18 @@ struct _GtkUrl { gchar *target, *bin; }; -#endif /* CYGWIN */ +#endif /* CYGWIN */ /* Global functions */ -gint GtkMessageBox(GtkWidget *parent,const gchar *Text, - const gchar *Title,gint Options); -GtkWidget *gtk_scrolled_clist_new_with_titles(gint columns,gchar *titles[], +gint GtkMessageBox(GtkWidget *parent, const gchar *Text, + const gchar *Title, gint Options); +GtkWidget *gtk_scrolled_clist_new_with_titles(gint columns, + gchar *titles[], GtkWidget **pack_widg); -guint SetAccelerator(GtkWidget *labelparent,gchar *Text, - GtkWidget *sendto,gchar *signal, +guint SetAccelerator(GtkWidget *labelparent, gchar *Text, + GtkWidget *sendto, gchar *signal, GtkAccelGroup *accel_group); -GtkWidget *gtk_scrolled_text_new(GtkAdjustment *hadj,GtkAdjustment *vadj, +GtkWidget *gtk_scrolled_text_new(GtkAdjustment *hadj, GtkAdjustment *vadj, GtkWidget **pack_widg); GtkWidget *gtk_url_new(const gchar *text, const gchar *target, const gchar *bin); (DIR) diff --git a/src/message.c b/src/message.c t@@ -1,22 +1,24 @@ -/* message.c Message-handling routines for dopewars */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * message.c Message-handling routines for dopewars * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifdef HAVE_CONFIG_H #include <config.h> t@@ -43,10 +45,11 @@ #include "tstring.h" /* Maximum sizes (in bytes) of read and write buffers - connections should - be dropped if either buffer is filled */ + * be dropped if either buffer is filled */ #define MAXREADBUF (32768) #define MAXWRITEBUF (65536) +/* *INDENT-OFF* */ /* dopewars is built around a client-server model. Each client handles the user interface, but all the important calculation and processing is handled by the server. All communication is conducted via. TCP by means t@@ -92,215 +95,280 @@ When the network is down, a server is simulated locally. Messages from the client are passed directly to the server message handling routine, and vice versa. */ +/* *INDENT-ON* */ GSList *FirstClient; -void (*ClientMessageHandlerPt) (char *,Player *) = NULL; +void (*ClientMessageHandlerPt)(char *, Player *) = NULL; -void SendClientMessage(Player *From,AICode AI,MsgCode Code, - Player *To,char *Data) { -/* Sends a message from player "From" to player "To" via. the server. */ -/* AI, Code and Data define the message. */ - DoSendClientMessage(From,AI,Code,To,Data,From); +/* + * Sends a message from player "From" to player "To" via. the server. + * AI, Code and Data define the message. + */ +void SendClientMessage(Player *From, AICode AI, MsgCode Code, + Player *To, char *Data) +{ + DoSendClientMessage(From, AI, Code, To, Data, From); } -void SendNullClientMessage(Player *From,AICode AI,MsgCode Code, - Player *To,char *Data) { -/* Sends a message from player "From" to player "To" via. the server, */ -/* sending a blank name for "From" (this is required with the old message */ -/* format, up to and including the first successful C_NAME message, but */ -/* has no effect with the new format. AI, Code and Data define the */ -/* message. */ - DoSendClientMessage(NULL,AI,Code,To,Data,From); +/* + * Sends a message from player "From" to player "To" via. the server, + * sending a blank name for "From" (this is required with the old message + * format, up to and including the first successful C_NAME message, but has + * no effect with the new format. AI, Code and Data define the message. + */ +void SendNullClientMessage(Player *From, AICode AI, MsgCode Code, + Player *To, char *Data) +{ + DoSendClientMessage(NULL, AI, Code, To, Data, From); } -void DoSendClientMessage(Player *From,AICode AI,MsgCode Code, - Player *To,char *Data,Player *BufOwn) { -/* Send a message from client player "From" with computer code "AI", */ -/* human-readable code "Code" and data "Data". The message is sent to the */ -/* server, identifying itself as for "To". "BufOwn" identifies the player */ -/* which owns the buffers used for the actual wire connection. With the */ -/* new message format, "From" is ignored. From, To, or Data may be NULL. */ - GString *text; - Player *ServerFrom; - g_assert(BufOwn!=NULL); - text=g_string_new(NULL); - if (HaveAbility(BufOwn,A_PLAYERID)) { - if (To) g_string_sprintfa(text,"%d",To->ID); - g_string_sprintfa(text,"^%c%c%s",AI,Code,Data ? Data : ""); - } else { - g_string_sprintf(text,"%s^%s^%c%c%s",From ? GetPlayerName(From) : "", - To ? GetPlayerName(To) : "",AI,Code, - Data ? Data : ""); - } +/* + * Send a message from client player "From" with computer code "AI", + * human-readable code "Code" and data "Data". The message is sent to the + * server, identifying itself as for "To". "BufOwn" identifies the player + * which owns the buffers used for the actual wire connection. With the + * new message format, "From" is ignored. From, To, or Data may be NULL. + */ +void DoSendClientMessage(Player *From, AICode AI, MsgCode Code, + Player *To, char *Data, Player *BufOwn) +{ + GString *text; + Player *ServerFrom; + + g_assert(BufOwn != NULL); + text = g_string_new(NULL); + if (HaveAbility(BufOwn, A_PLAYERID)) { + if (To) + g_string_sprintfa(text, "%d", To->ID); + g_string_sprintfa(text, "^%c%c%s", AI, Code, Data ? Data : ""); + } else { + g_string_sprintf(text, "%s^%s^%c%c%s", From ? GetPlayerName(From) : "", + To ? GetPlayerName(To) : "", AI, Code, + Data ? Data : ""); + } #if NETWORKING - if (!Network) { + if (!Network) { #endif - if (From) ServerFrom=GetPlayerByName(GetPlayerName(From),FirstServer); - else if (FirstServer) ServerFrom=(Player *)(FirstServer->data); - else { - ServerFrom=g_new(Player,1); - FirstServer=AddPlayer(0,ServerFrom,FirstServer); - } - HandleServerMessage(text->str,ServerFrom); + if (From) + ServerFrom = GetPlayerByName(GetPlayerName(From), FirstServer); + else if (FirstServer) + ServerFrom = (Player *)(FirstServer->data); + else { + ServerFrom = g_new(Player, 1); + FirstServer = AddPlayer(0, ServerFrom, FirstServer); + } + HandleServerMessage(text->str, ServerFrom); #if NETWORKING - } else { - QueuePlayerMessageForSend(BufOwn,text->str); - } + } else { + QueuePlayerMessageForSend(BufOwn, text->str); + } #endif /* NETWORKING */ - g_string_free(text,TRUE); + g_string_free(text, TRUE); } -void SendPrintMessage(Player *From,AICode AI,Player *To,char *Data) { -/* Shorthand for the server sending a "printmessage"; instructs the */ -/* client "To" to display "Data" */ - SendServerMessage(From,AI,C_PRINTMESSAGE,To,Data); +/* + * Shorthand for the server sending a "printmessage"; instructs the + * client "To" to display "Data". + */ +void SendPrintMessage(Player *From, AICode AI, Player *To, char *Data) +{ + SendServerMessage(From, AI, C_PRINTMESSAGE, To, Data); } -void SendQuestion(Player *From,AICode AI,Player *To,char *Data) { -/* Shorthand for the server sending a "question"; instructs the client */ -/* "To" to display the second word of Data and accept any letter within */ -/* the first word of Data as suitable reply */ - SendServerMessage(From,AI,C_QUESTION,To,Data); +/* + * Shorthand for the server sending a "question"; instructs the client + * "To" to display the second word of Data and accept any letter within + * the first word of Data as suitable reply. + */ +void SendQuestion(Player *From, AICode AI, Player *To, char *Data) +{ + SendServerMessage(From, AI, C_QUESTION, To, Data); } -void SendServerMessage(Player *From,AICode AI,MsgCode Code, - Player *To,char *Data) { -/* Sends a message from the server to client player "To" with computer */ -/* code "AI", human-readable code "Code" and data "Data", claiming */ -/* to be from player "From" */ - GString *text; - if (IsCop(To)) return; - text=g_string_new(NULL); - if (HaveAbility(To,A_PLAYERID)) { - if (From) g_string_sprintfa(text,"%d",From->ID); - g_string_sprintfa(text,"^%c%c%s",AI,Code,Data ? Data : ""); - } else { - g_string_sprintf(text,"%s^%s^%c%c%s",From ? GetPlayerName(From) : "", - To ? GetPlayerName(To) : "",AI,Code, - Data ? Data : ""); - } +/* + * Sends a message from the server to client player "To" with computer + * code "AI", human-readable code "Code" and data "Data", claiming + * to be from player "From". + */ +void SendServerMessage(Player *From, AICode AI, MsgCode Code, + Player *To, char *Data) +{ + GString *text; + + if (IsCop(To)) + return; + text = g_string_new(NULL); + if (HaveAbility(To, A_PLAYERID)) { + if (From) + g_string_sprintfa(text, "%d", From->ID); + g_string_sprintfa(text, "^%c%c%s", AI, Code, Data ? Data : ""); + } else { + g_string_sprintf(text, "%s^%s^%c%c%s", From ? GetPlayerName(From) : "", + To ? GetPlayerName(To) : "", AI, Code, + Data ? Data : ""); + } #if NETWORKING - if (!Network) { + if (!Network) { #endif - if (ClientMessageHandlerPt) { - (*ClientMessageHandlerPt)(text->str,(Player *)(FirstClient->data)); - } + if (ClientMessageHandlerPt) + (*ClientMessageHandlerPt)(text->str, (Player *)(FirstClient->data)); #if NETWORKING - } else { - QueuePlayerMessageForSend(To,text->str); - } + } else { + QueuePlayerMessageForSend(To, text->str); + } #endif - g_string_free(text,TRUE); + g_string_free(text, TRUE); } -void InitAbilities(Player *Play) { -/* Sets up the "abilities" of player "Play". Abilities are used to extend */ -/* the protocol; if both the client and server share an ability, then the */ -/* protocol extension can be used. */ - int i; -/* Clear all abilities */ - for (i=0;i<A_NUM;i++) { - Play->Abil.Local[i]= FALSE; - Play->Abil.Remote[i]=FALSE; - Play->Abil.Shared[i]=FALSE; - } -/* Set local abilities; abilities that are client-dependent - (e.g. A_NEWFIGHT) can be overridden by individual clients if required, - by calling SetAbility, prior to calling SendAbilities */ - - Play->Abil.Local[A_PLAYERID]=TRUE; - Play->Abil.Local[A_NEWFIGHT]=TRUE; - Play->Abil.Local[A_DRUGVALUE]=(DrugValue ? TRUE : FALSE); - Play->Abil.Local[A_TSTRING]=TRUE; - - if (!Network) for (i=0;i<A_NUM;i++) { - Play->Abil.Remote[i]=Play->Abil.Shared[i]=Play->Abil.Local[i]; - } +/* + * Sets up the "abilities" of player "Play". Abilities are used to extend + * the protocol; if both the client and server share an ability, then the + * protocol extension can be used. + */ +void InitAbilities(Player *Play) +{ + int i; + + /* Clear all abilities */ + for (i = 0; i < A_NUM; i++) { + Play->Abil.Local[i] = FALSE; + Play->Abil.Remote[i] = FALSE; + Play->Abil.Shared[i] = FALSE; + } + + /* Set local abilities; abilities that are client-dependent (e.g. + * A_NEWFIGHT) can be overridden by individual clients if required, by + * calling SetAbility, prior to calling SendAbilities */ + Play->Abil.Local[A_PLAYERID] = TRUE; + Play->Abil.Local[A_NEWFIGHT] = TRUE; + Play->Abil.Local[A_DRUGVALUE] = (DrugValue ? TRUE : FALSE); + Play->Abil.Local[A_TSTRING] = TRUE; + + if (!Network) + for (i = 0; i < A_NUM; i++) { + Play->Abil.Remote[i] = Play->Abil.Shared[i] = Play->Abil.Local[i]; + } } -void SendAbilities(Player *Play) { -/* Sends abilities of player "Play" to the other end of the client-server */ -/* connection. */ - int i; - gchar Data[A_NUM+1]; - if (!Network) return; - for (i=0;i<A_NUM;i++) Data[i]= (Play->Abil.Local[i] ? '1' : '0'); - Data[A_NUM]='\0'; - if (Server) SendServerMessage(NULL,C_NONE,C_ABILITIES,Play,Data); - else SendClientMessage(Play,C_NONE,C_ABILITIES,NULL,Data); +/* + * Sends abilities of player "Play" to the other end of the client-server + * connection. + */ +void SendAbilities(Player *Play) +{ + int i; + gchar Data[A_NUM + 1]; + + if (!Network) + return; + for (i = 0; i < A_NUM; i++) + Data[i] = (Play->Abil.Local[i] ? '1' : '0'); + Data[A_NUM] = '\0'; + if (Server) + SendServerMessage(NULL, C_NONE, C_ABILITIES, Play, Data); + else + SendClientMessage(Play, C_NONE, C_ABILITIES, NULL, Data); } -void ReceiveAbilities(Player *Play,gchar *Data) { -/* Fills in the "remote" abilities of player "Play" using the message data */ -/* in "Data". These are the abilities of the server/client at the other */ -/* end of the connection. */ - int i,Length; - InitAbilities(Play); - if (!Network) return; - Length=MIN(strlen(Data),A_NUM); - for (i=0;i<Length;i++) { - Play->Abil.Remote[i]= (Data[i]=='1' ? TRUE : FALSE); - } +/* + * Fills in the "remote" abilities of player "Play" using the message data + * in "Data". These are the abilities of the server/client at the other + * end of the connection. + */ +void ReceiveAbilities(Player *Play, gchar *Data) +{ + int i, Length; + + InitAbilities(Play); + if (!Network) + return; + Length = MIN(strlen(Data), A_NUM); + for (i = 0; i < Length; i++) { + Play->Abil.Remote[i] = (Data[i] == '1' ? TRUE : FALSE); + } } -void CombineAbilities(Player *Play) { -/* Combines the local and remote abilities of player "Play". The resulting */ -/* shared abilities are used to determine when protocol extensions can be */ -/* used. */ - int i; - for (i=0;i<A_NUM;i++) { - Play->Abil.Shared[i]= (Play->Abil.Remote[i] && Play->Abil.Local[i]); - } +/* + * Combines the local and remote abilities of player "Play". The resulting + * shared abilities are used to determine when protocol extensions can be + * used. + */ +void CombineAbilities(Player *Play) +{ + int i; + + for (i = 0; i < A_NUM; i++) { + Play->Abil.Shared[i] = (Play->Abil.Remote[i] && Play->Abil.Local[i]); + } } -void SetAbility(Player *Play,gint Type,gboolean Set) { -/* Sets ability "Type" of player "Play", and also sets shared abilities if */ -/* networking is not active (the local server should support all abilities */ -/* that the client uses). Call this function prior to calling SendAbilities */ -/* so that the ability is recognised properly when networking _is_ active */ - if (Type<0 || Type>=A_NUM) return; - Play->Abil.Local[Type]=Set; - if (!Network) { - Play->Abil.Remote[Type]=Play->Abil.Shared[Type]=Play->Abil.Local[Type]; - } +/* + * Sets ability "Type" of player "Play", and also sets shared abilities if + * networking is not active (the local server should support all abilities + * that the client uses). Call this function prior to calling SendAbilities + * so that the ability is recognised properly when networking _is_ active + */ +void SetAbility(Player *Play, gint Type, gboolean Set) +{ + if (Type < 0 || Type >= A_NUM) + return; + Play->Abil.Local[Type] = Set; + if (!Network) { + Play->Abil.Remote[Type] = Play->Abil.Shared[Type] = + Play->Abil.Local[Type]; + } } -gboolean HaveAbility(Player *Play,gint Type) { -/* Returns TRUE if ability "Type" is one of player "Play"'s shared abilities */ - if (Type<0 || Type>=A_NUM) return FALSE; - else return (Play->Abil.Shared[Type]); +/* + * Returns TRUE if ability "Type" is one of player "Play"'s shared abilities + */ +gboolean HaveAbility(Player *Play, gint Type) +{ + if (Type < 0 || Type >= A_NUM) + return FALSE; + else + return (Play->Abil.Shared[Type]); } #if NETWORKING -gboolean PlayerHandleNetwork(Player *Play,gboolean ReadReady, - gboolean WriteReady,gboolean *DoneOK) { -/* Reads and writes player data from/to the network if it is ready. */ -/* If any data were read, TRUE is returned. "DoneOK" is set TRUE */ -/* unless a fatal error (i.e. the connection was broken) occurred. */ - gboolean DataWaiting=FALSE; - - *DoneOK=TRUE; - if (!Play) return DataWaiting; - DataWaiting=NetBufHandleNetwork(&Play->NetBuf,ReadReady,WriteReady,DoneOK); - - return DataWaiting; +/* + * Reads and writes player data from/to the network if it is ready. + * If any data were read, TRUE is returned. "DoneOK" is set TRUE + * unless a fatal error (i.e. the connection was broken) occurred. + */ +gboolean PlayerHandleNetwork(Player *Play, gboolean ReadReady, + gboolean WriteReady, gboolean *DoneOK) +{ + gboolean DataWaiting = FALSE; + + *DoneOK = TRUE; + if (!Play) + return DataWaiting; + DataWaiting = + NetBufHandleNetwork(&Play->NetBuf, ReadReady, WriteReady, DoneOK); + + return DataWaiting; } -gchar *GetWaitingPlayerMessage(Player *Play) { - return GetWaitingMessage(&Play->NetBuf); +gchar *GetWaitingPlayerMessage(Player *Play) +{ + return GetWaitingMessage(&Play->NetBuf); } -gboolean ReadPlayerDataFromWire(Player *Play) { +gboolean ReadPlayerDataFromWire(Player *Play) +{ return ReadDataFromWire(&Play->NetBuf); } -void QueuePlayerMessageForSend(Player *Play,gchar *data) { - QueueMessageForSend(&Play->NetBuf,data); +void QueuePlayerMessageForSend(Player *Play, gchar *data) +{ + QueueMessageForSend(&Play->NetBuf, data); } -gboolean WritePlayerDataToWire(Player *Play) { - return WriteDataToWire(&Play->NetBuf); +gboolean WritePlayerDataToWire(Player *Play) +{ + return WriteDataToWire(&Play->NetBuf); } typedef enum { t@@ -308,845 +376,1012 @@ typedef enum { MEC_BADREPLY } MetaErrorCode; -static void MetaAppendError(GString *str,LastError *error) { +static void MetaAppendError(GString *str, LastError *error) +{ switch (error->code) { - case MEC_INTERNAL: - g_string_sprintfa(str,_("Internal metaserver error \"%s\""), - (gchar *)error->data); - break; - case MEC_BADREPLY: - g_string_sprintfa(str,_("Bad metaserver reply \"%s\""), - (gchar *)error->data); - break; - default: - g_string_sprintfa(str,_("Unknown metaserver error code %d"),error->code); - break; + case MEC_INTERNAL: + g_string_sprintfa(str, _("Internal metaserver error \"%s\""), + (gchar *)error->data); + break; + case MEC_BADREPLY: + g_string_sprintfa(str, _("Bad metaserver reply \"%s\""), + (gchar *)error->data); + break; + default: + g_string_sprintfa(str, _("Unknown metaserver error code %d"), + error->code); + break; } } static ErrorType ETMeta = { MetaAppendError, NULL }; -gboolean OpenMetaHttpConnection(HttpConnection **conn) { - gchar *query; - gboolean retval; - - query = g_strdup_printf("%s?output=text&getlist=%d", - MetaServer.Path,METAVERSION); - retval = OpenHttpConnection(conn,MetaServer.Name,MetaServer.Port, - MetaServer.ProxyName,MetaServer.ProxyPort, - UseSocks && MetaServer.UseSocks ? &Socks : NULL, - "GET",query,NULL,NULL); - g_free(query); - return retval; +gboolean OpenMetaHttpConnection(HttpConnection **conn) +{ + gchar *query; + gboolean retval; + + query = g_strdup_printf("%s?output=text&getlist=%d", + MetaServer.Path, METAVERSION); + retval = OpenHttpConnection(conn, MetaServer.Name, MetaServer.Port, + MetaServer.ProxyName, MetaServer.ProxyPort, + UseSocks + && MetaServer.UseSocks ? &Socks : NULL, + "GET", query, NULL, NULL); + g_free(query); + return retval; } -gboolean HandleWaitingMetaServerData(HttpConnection *conn,GSList **listpt, - gboolean *doneOK) { - gchar *msg; - ServerData *NewServer; - g_assert(conn && listpt && doneOK); - -/* If we're done reading the headers, only read if the data for a whole - server is available (8 lines) N.B. "Status" is from the _last_ read */ - if (conn->Status==HS_READBODY && conn->StatusCode==200) { - if (CountWaitingMessages(&conn->NetBuf)<8) return FALSE; - - NewServer=g_new0(ServerData,1); - NewServer->Name=ReadHttpResponse(conn,doneOK); - msg=ReadHttpResponse(conn,doneOK); - NewServer->Port=atoi(msg); g_free(msg); - NewServer->Version=ReadHttpResponse(conn,doneOK); - msg=ReadHttpResponse(conn,doneOK); - if (msg[0]) NewServer->CurPlayers=atoi(msg); - else NewServer->CurPlayers=-1; - g_free(msg); - msg=ReadHttpResponse(conn,doneOK); - NewServer->MaxPlayers=atoi(msg); g_free(msg); - NewServer->Update=ReadHttpResponse(conn,doneOK); - NewServer->Comment=ReadHttpResponse(conn,doneOK); - NewServer->UpSince=ReadHttpResponse(conn,doneOK); - *listpt=g_slist_append(*listpt,NewServer); - } else if (conn->Status==HS_READSEPARATOR && conn->StatusCode==200) { - /* This should be the first line of the body, the "MetaServer:" line */ - msg=ReadHttpResponse(conn,doneOK); - if (!msg) return FALSE; - if (strlen(msg)>=14 && strncmp(msg,"FATAL ERROR:",12)==0) { - SetError(&conn->NetBuf.error,&ETMeta,MEC_INTERNAL,g_strdup(&msg[13])); - *doneOK=FALSE; - return FALSE; - } else if (strncmp(msg,"MetaServer:",11)!=0) { - SetError(&conn->NetBuf.error,&ETMeta,MEC_BADREPLY,g_strdup(msg)); - g_free(msg); - *doneOK=FALSE; - return FALSE; - } +gboolean HandleWaitingMetaServerData(HttpConnection *conn, + GSList **listpt, gboolean *doneOK) +{ + gchar *msg; + ServerData *NewServer; + + g_assert(conn && listpt && doneOK); + + /* If we're done reading the headers, only read if the data for a whole + * server is available (8 lines) N.B. "Status" is from the _last_ read */ + if (conn->Status == HS_READBODY && conn->StatusCode == 200) { + if (CountWaitingMessages(&conn->NetBuf) < 8) + return FALSE; + + NewServer = g_new0(ServerData, 1); + NewServer->Name = ReadHttpResponse(conn, doneOK); + msg = ReadHttpResponse(conn, doneOK); + NewServer->Port = atoi(msg); + g_free(msg); + NewServer->Version = ReadHttpResponse(conn, doneOK); + msg = ReadHttpResponse(conn, doneOK); + if (msg[0]) + NewServer->CurPlayers = atoi(msg); + else + NewServer->CurPlayers = -1; + g_free(msg); + msg = ReadHttpResponse(conn, doneOK); + NewServer->MaxPlayers = atoi(msg); + g_free(msg); + NewServer->Update = ReadHttpResponse(conn, doneOK); + NewServer->Comment = ReadHttpResponse(conn, doneOK); + NewServer->UpSince = ReadHttpResponse(conn, doneOK); + *listpt = g_slist_append(*listpt, NewServer); + } else if (conn->Status == HS_READSEPARATOR && conn->StatusCode == 200) { + /* This should be the first line of the body, the "MetaServer:" line */ + msg = ReadHttpResponse(conn, doneOK); + if (!msg) + return FALSE; + if (strlen(msg) >= 14 && strncmp(msg, "FATAL ERROR:", 12) == 0) { + SetError(&conn->NetBuf.error, &ETMeta, MEC_INTERNAL, + g_strdup(&msg[13])); + *doneOK = FALSE; + return FALSE; + } else if (strncmp(msg, "MetaServer:", 11) != 0) { + SetError(&conn->NetBuf.error, &ETMeta, MEC_BADREPLY, g_strdup(msg)); g_free(msg); - } else { - msg=ReadHttpResponse(conn,doneOK); - if (!msg) return FALSE; - g_free(msg); - } - return TRUE; + *doneOK = FALSE; + return FALSE; + } + g_free(msg); + } else { + msg = ReadHttpResponse(conn, doneOK); + if (!msg) + return FALSE; + g_free(msg); + } + return TRUE; } -void ClearServerList(GSList **listpt) { - ServerData *ThisServer; - while (*listpt) { - ThisServer=(ServerData *)((*listpt)->data); - g_free(ThisServer->Name); g_free(ThisServer->Comment); - g_free(ThisServer->Version); g_free(ThisServer->Update); - g_free(ThisServer->UpSince); g_free(ThisServer); - *listpt=g_slist_remove(*listpt,ThisServer); - } +void ClearServerList(GSList **listpt) +{ + ServerData *ThisServer; + + while (*listpt) { + ThisServer = (ServerData *)((*listpt)->data); + g_free(ThisServer->Name); + g_free(ThisServer->Comment); + g_free(ThisServer->Version); + g_free(ThisServer->Update); + g_free(ThisServer->UpSince); + g_free(ThisServer); + *listpt = g_slist_remove(*listpt, ThisServer); + } } #endif /* NETWORKING */ -void chomp(char *str) { -/* Removes a terminating newline from "str", if one is present. */ - int len=strlen(str); - if (str[len-1]=='\n') str[len-1]=0; +/* + * Removes a terminating newline from "str", if one is present. + */ +void chomp(char *str) +{ + int len = strlen(str); + + if (str[len - 1] == '\n') + str[len - 1] = 0; } -void AddURLEnc(GString *str,gchar *unenc) { -/* Adds the plain text string "unenc" to the end of the GString "str", */ -/* replacing "special" characters in the same way as the */ -/* application/x-www-form-urlencoded media type, suitable for sending */ -/* to CGI scripts etc. */ - guint i; - if (!unenc || !str) return; - for (i=0;i<strlen(unenc);i++) { - if ((unenc[i]>='a' && unenc[i]<='z') || - (unenc[i]>='A' && unenc[i]<='Z') || - (unenc[i]>='0' && unenc[i]<='9') || - unenc[i]=='-' || unenc[i]=='_' || unenc[i]=='.') { - g_string_append_c(str,unenc[i]); - } else if (unenc[i]==' ') { - g_string_append_c(str,'+'); - } else { - g_string_sprintfa(str,"%%%02X",unenc[i]); - } - } +/* + * Adds the plain text string "unenc" to the end of the GString "str", + * replacing "special" characters in the same way as the + * application/x-www-form-urlencoded media type, suitable for sending + * to CGI scripts etc. + */ +void AddURLEnc(GString *str, gchar *unenc) +{ + guint i; + + if (!unenc || !str) + return; + for (i = 0; i < strlen(unenc); i++) { + if ((unenc[i] >= 'a' && unenc[i] <= 'z') || + (unenc[i] >= 'A' && unenc[i] <= 'Z') || + (unenc[i] >= '0' && unenc[i] <= '9') || + unenc[i] == '-' || unenc[i] == '_' || unenc[i] == '.') { + g_string_append_c(str, unenc[i]); + } else if (unenc[i] == ' ') { + g_string_append_c(str, '+'); + } else { + g_string_sprintfa(str, "%%%02X", unenc[i]); + } + } } -void BroadcastToClients(AICode AI,MsgCode Code,char *Data, - Player *From,Player *Except) { -/* Sends the message made up of AI,Code and Data to all players except */ -/* "Except" (if non-NULL). It will be sent by the server, and on behalf of */ -/* player "From" */ +/* + * Sends the message made up of AI,Code and Data to all players except + * "Except" (if non-NULL). It will be sent by the server, and on behalf of + * player "From". + */ +void BroadcastToClients(AICode AI, MsgCode Code, char *Data, + Player *From, Player *Except) +{ Player *tmp; GSList *list; - for (list=FirstServer;list;list=g_slist_next(list)) { - tmp=(Player *)list->data; - if (IsConnectedPlayer(tmp) && tmp!=Except) { - SendServerMessage(From,AI,Code,tmp,Data); + for (list = FirstServer; list; list = g_slist_next(list)) { + tmp = (Player *)list->data; + if (IsConnectedPlayer(tmp) && tmp != Except) { + SendServerMessage(From, AI, Code, tmp, Data); } } } -void SendInventory(Player *From,AICode AI,MsgCode Code, - Player *To,Inventory *Guns,Inventory *Drugs) { -/* Encodes an Inventory structure into a string, and sends it as the data */ -/* with a server message constructed from the other arguments. */ - int i; - GString *text; - text=g_string_new(NULL); - for (i=0;i<NumGun;i++) { - g_string_sprintfa(text,"%d:",Guns ? Guns[i].Carried : 0); - } - for (i=0;i<NumDrug;i++) { - g_string_sprintfa(text,"%d:",Drugs ? Drugs[i].Carried : 0); - } - SendServerMessage(From,AI,Code,To,text->str); - g_string_free(text,TRUE); +/* + * Encodes an Inventory structure into a string, and sends it as the data + * with a server message constructed from the other arguments. + */ +void SendInventory(Player *From, AICode AI, MsgCode Code, + Player *To, Inventory *Guns, Inventory *Drugs) +{ + int i; + GString *text; + + text = g_string_new(NULL); + for (i = 0; i < NumGun; i++) { + g_string_sprintfa(text, "%d:", Guns ? Guns[i].Carried : 0); + } + for (i = 0; i < NumDrug; i++) { + g_string_sprintfa(text, "%d:", Drugs ? Drugs[i].Carried : 0); + } + SendServerMessage(From, AI, Code, To, text->str); + g_string_free(text, TRUE); } -void ReceiveInventory(char *Data,Inventory *Guns,Inventory *Drugs) { -/* Decodes a string representation (in "Data") to its original Inventory */ -/* contents, and stores it in "Guns" and "Drugs" if non-NULL */ - int i,val; - char *pt; - pt=Data; - for (i=0;i<NumGun;i++) { - val=GetNextInt(&pt,0); - if (Guns) Guns[i].Carried=val; - } - for (i=0;i<NumDrug;i++) { - val=GetNextInt(&pt,0); - if (Drugs) Drugs[i].Carried=val; - } +/* + * Decodes a string representation (in "Data") to its original Inventory + * contents, and stores it in "Guns" and "Drugs" if non-NULL. + */ +void ReceiveInventory(char *Data, Inventory *Guns, Inventory *Drugs) +{ + int i, val; + char *pt; + + pt = Data; + for (i = 0; i < NumGun; i++) { + val = GetNextInt(&pt, 0); + if (Guns) + Guns[i].Carried = val; + } + for (i = 0; i < NumDrug; i++) { + val = GetNextInt(&pt, 0); + if (Drugs) + Drugs[i].Carried = val; + } } -void SendPlayerData(Player *To) { -/* Sends all pertinent data about player "To" from the server to player "To" */ - SendSpyReport(To,To); +/* + * Sends all pertinent data about player "To" from the server + * to player "To". + */ +void SendPlayerData(Player *To) +{ + SendSpyReport(To, To); } -void SendSpyReport(Player *To,Player *SpiedOn) { -/* Sends pertinent data about player "SpiedOn" from the server to player "To" */ - gchar *cashstr,*debtstr,*bankstr; - GString *text; - int i; - text=g_string_new(NULL); - g_string_sprintf(text,"%s^%s^%s^%d^%d^%d^%d^%d^", - (cashstr=pricetostr(SpiedOn->Cash)), - (debtstr=pricetostr(SpiedOn->Debt)), - (bankstr=pricetostr(SpiedOn->Bank)), - SpiedOn->Health,SpiedOn->CoatSize, - SpiedOn->IsAt,SpiedOn->Turn,SpiedOn->Flags); - g_free(cashstr); g_free(debtstr); g_free(bankstr); - for (i=0;i<NumGun;i++) { - g_string_sprintfa(text,"%d^",SpiedOn->Guns[i].Carried); - } - for (i=0;i<NumDrug;i++) { - g_string_sprintfa(text,"%d^",SpiedOn->Drugs[i].Carried); - } - if (HaveAbility(To,A_DRUGVALUE)) for (i=0;i<NumDrug;i++) { - g_string_sprintfa(text,"%s^", - (cashstr=pricetostr(SpiedOn->Drugs[i].TotalValue))); +/* + * Sends pertinent data about player "SpiedOn" from the server + * to player "To". + */ +void SendSpyReport(Player *To, Player *SpiedOn) +{ + gchar *cashstr, *debtstr, *bankstr; + GString *text; + int i; + + text = g_string_new(NULL); + g_string_sprintf(text, "%s^%s^%s^%d^%d^%d^%d^%d^", + (cashstr = pricetostr(SpiedOn->Cash)), + (debtstr = pricetostr(SpiedOn->Debt)), + (bankstr = pricetostr(SpiedOn->Bank)), + SpiedOn->Health, SpiedOn->CoatSize, + SpiedOn->IsAt, SpiedOn->Turn, SpiedOn->Flags); + g_free(cashstr); + g_free(debtstr); + g_free(bankstr); + for (i = 0; i < NumGun; i++) { + g_string_sprintfa(text, "%d^", SpiedOn->Guns[i].Carried); + } + for (i = 0; i < NumDrug; i++) { + g_string_sprintfa(text, "%d^", SpiedOn->Drugs[i].Carried); + } + if (HaveAbility(To, A_DRUGVALUE)) + for (i = 0; i < NumDrug; i++) { + g_string_sprintfa(text, "%s^", + (cashstr = + pricetostr(SpiedOn->Drugs[i].TotalValue))); g_free(cashstr); - } - g_string_sprintfa(text,"%d",SpiedOn->Bitches.Carried); - if (To!=SpiedOn) SendServerMessage(SpiedOn,C_NONE,C_UPDATE,To,text->str); - else SendServerMessage(NULL,C_NONE,C_UPDATE,To,text->str); - g_string_free(text,TRUE); + } + g_string_sprintfa(text, "%d", SpiedOn->Bitches.Carried); + if (To != SpiedOn) + SendServerMessage(SpiedOn, C_NONE, C_UPDATE, To, text->str); + else + SendServerMessage(NULL, C_NONE, C_UPDATE, To, text->str); + g_string_free(text, TRUE); } #define NUMNAMES 12 -void SendInitialData(Player *To) { - gchar *LocalNames[NUMNAMES] = { Names.Bitch,Names.Bitches,Names.Gun, - Names.Guns,Names.Drug,Names.Drugs, - Names.Month,Names.Year,Names.LoanSharkName, - Names.BankName,Names.GunShopName, - Names.RoughPubName }; +void SendInitialData(Player *To) +{ + gchar *LocalNames[NUMNAMES] = { Names.Bitch, Names.Bitches, Names.Gun, + Names.Guns, Names.Drug, Names.Drugs, + Names.Month, Names.Year, Names.LoanSharkName, + Names.BankName, Names.GunShopName, + Names.RoughPubName + }; gint i; GString *text; - if (!Network) return; - if (!HaveAbility(To,A_TSTRING)) for (i=0;i<NUMNAMES;i++) { - LocalNames[i] = GetDefaultTString(LocalNames[i]); - } - text=g_string_new(""); - g_string_sprintf(text,"%s^%d^%d^%d^",VERSION,NumLocation,NumGun,NumDrug); - for (i=0;i<8;i++) { - g_string_append(text,LocalNames[i]); - g_string_append_c(text,'^'); + if (!Network) + return; + if (!HaveAbility(To, A_TSTRING)) + for (i = 0; i < NUMNAMES; i++) { + LocalNames[i] = GetDefaultTString(LocalNames[i]); + } + text = g_string_new(""); + g_string_sprintf(text, "%s^%d^%d^%d^", VERSION, NumLocation, NumGun, + NumDrug); + for (i = 0; i < 8; i++) { + g_string_append(text, LocalNames[i]); + g_string_append_c(text, '^'); } - if (HaveAbility(To,A_PLAYERID)) g_string_sprintfa(text,"%d^",To->ID); + if (HaveAbility(To, A_PLAYERID)) + g_string_sprintfa(text, "%d^", To->ID); -/* Player ID is expected after the first 8 names, so send the rest now */ - for (i=8;i<NUMNAMES;i++) { - g_string_append(text,LocalNames[i]); - g_string_append_c(text,'^'); + /* Player ID is expected after the first 8 names, so send the rest now */ + for (i = 8; i < NUMNAMES; i++) { + g_string_append(text, LocalNames[i]); + g_string_append_c(text, '^'); } - if (!HaveAbility(To,A_TSTRING)) for (i=0;i<NUMNAMES;i++) { - g_free(LocalNames[i]); - } + if (!HaveAbility(To, A_TSTRING)) + for (i = 0; i < NUMNAMES; i++) { + g_free(LocalNames[i]); + } - g_string_sprintfa(text,"%c%s^",Currency.Prefix ? '1' : '0',Currency.Symbol); - SendServerMessage(NULL,C_NONE,C_INIT,To,text->str); - g_string_free(text,TRUE); + g_string_sprintfa(text, "%c%s^", Currency.Prefix ? '1' : '0', + Currency.Symbol); + SendServerMessage(NULL, C_NONE, C_INIT, To, text->str); + g_string_free(text, TRUE); } -void ReceiveInitialData(Player *Play,char *Data) { - char *pt,*ServerVersion,*curr; +void ReceiveInitialData(Player *Play, char *Data) +{ + char *pt, *ServerVersion, *curr; GSList *list; - pt=Data; - ServerVersion=GetNextWord(&pt,"(unknown)"); - ResizeLocations(GetNextInt(&pt,NumLocation)); - ResizeGuns(GetNextInt(&pt,NumGun)); - ResizeDrugs(GetNextInt(&pt,NumDrug)); - for (list=FirstClient;list;list=g_slist_next(list)) { - UpdatePlayer((Player*)list->data); + + pt = Data; + ServerVersion = GetNextWord(&pt, "(unknown)"); + ResizeLocations(GetNextInt(&pt, NumLocation)); + ResizeGuns(GetNextInt(&pt, NumGun)); + ResizeDrugs(GetNextInt(&pt, NumDrug)); + for (list = FirstClient; list; list = g_slist_next(list)) { + UpdatePlayer((Player *)list->data); } - AssignName(&Names.Bitch,GetNextWord(&pt,"")); - AssignName(&Names.Bitches,GetNextWord(&pt,"")); - AssignName(&Names.Gun,GetNextWord(&pt,"")); - AssignName(&Names.Guns,GetNextWord(&pt,"")); - AssignName(&Names.Drug,GetNextWord(&pt,"")); - AssignName(&Names.Drugs,GetNextWord(&pt,"")); - AssignName(&Names.Month,GetNextWord(&pt,"")); - AssignName(&Names.Year,GetNextWord(&pt,"")); - if (HaveAbility(Play,A_PLAYERID)) Play->ID=GetNextInt(&pt,0); - -/* Servers up to version 1.4.8 don't send the following names, so - default to the existing values if they haven't been sent */ - AssignName(&Names.LoanSharkName,GetNextWord(&pt,Names.LoanSharkName)); - AssignName(&Names.BankName,GetNextWord(&pt,Names.BankName)); - AssignName(&Names.GunShopName,GetNextWord(&pt,Names.GunShopName)); - AssignName(&Names.RoughPubName,GetNextWord(&pt,Names.RoughPubName)); - -/* Currency data are only sent by versions >= 1.5.3 */ - curr = GetNextWord(&pt,NULL); - if (curr && strlen(curr)>=1) { - Currency.Prefix = (curr[0]=='1'); - AssignName(&Currency.Symbol,&curr[1]); + AssignName(&Names.Bitch, GetNextWord(&pt, "")); + AssignName(&Names.Bitches, GetNextWord(&pt, "")); + AssignName(&Names.Gun, GetNextWord(&pt, "")); + AssignName(&Names.Guns, GetNextWord(&pt, "")); + AssignName(&Names.Drug, GetNextWord(&pt, "")); + AssignName(&Names.Drugs, GetNextWord(&pt, "")); + AssignName(&Names.Month, GetNextWord(&pt, "")); + AssignName(&Names.Year, GetNextWord(&pt, "")); + if (HaveAbility(Play, A_PLAYERID)) + Play->ID = GetNextInt(&pt, 0); + + /* Servers up to version 1.4.8 don't send the following names, so + * default to the existing values if they haven't been sent */ + AssignName(&Names.LoanSharkName, GetNextWord(&pt, Names.LoanSharkName)); + AssignName(&Names.BankName, GetNextWord(&pt, Names.BankName)); + AssignName(&Names.GunShopName, GetNextWord(&pt, Names.GunShopName)); + AssignName(&Names.RoughPubName, GetNextWord(&pt, Names.RoughPubName)); + + /* Currency data are only sent by versions >= 1.5.3 */ + curr = GetNextWord(&pt, NULL); + if (curr && strlen(curr) >= 1) { + Currency.Prefix = (curr[0] == '1'); + AssignName(&Currency.Symbol, &curr[1]); } - if (strcmp(VERSION,ServerVersion)!=0) { + if (strcmp(VERSION, ServerVersion) != 0) { g_message(_("This server is version %s, while your client is " -"version %s.\nBe warned that different versions may not be fully compatible!\n" -"Refer to the website at http://dopewars.sourceforge.net/\n" -"for the latest version."),ServerVersion,VERSION); + "version %s.\nBe warned that different versions may not " + "be fully compatible!\nRefer to the website at " + "http://dopewars.sourceforge.net/\nfor the latest version."), + ServerVersion, VERSION); } } -void SendMiscData(Player *To) { - gchar *text,*prstr[2],*LocalName; - int i; - gboolean HaveTString; - if (!Network) return; - HaveTString=HaveAbility(To,A_TSTRING); - text=g_strdup_printf("0^%c%s^%s^",DT_PRICES, - (prstr[0]=pricetostr(Prices.Spy)), - (prstr[1]=pricetostr(Prices.Tipoff))); - SendServerMessage(NULL,C_NONE,C_DATA,To,text); - g_free(prstr[0]); g_free(prstr[1]); g_free(text); - for (i=0;i<NumGun;i++) { - if (HaveTString) LocalName=Gun[i].Name; - else LocalName=GetDefaultTString(Gun[i].Name); - text=g_strdup_printf("%d^%c%s^%s^%d^%d^",i,DT_GUN,LocalName, - (prstr[0]=pricetostr(Gun[i].Price)), - Gun[i].Space,Gun[i].Damage); - if (!HaveTString) g_free(LocalName); - SendServerMessage(NULL,C_NONE,C_DATA,To,text); - g_free(prstr[0]); g_free(text); - } - for (i=0;i<NumDrug;i++) { - if (HaveTString) LocalName=Drug[i].Name; - else LocalName=GetDefaultTString(Drug[i].Name); - text=g_strdup_printf("%d^%c%s^%s^%s^",i,DT_DRUG,LocalName, - (prstr[0]=pricetostr(Drug[i].MinPrice)), - (prstr[1]=pricetostr(Drug[i].MaxPrice))); - if (!HaveTString) g_free(LocalName); - SendServerMessage(NULL,C_NONE,C_DATA,To,text); - g_free(prstr[0]); g_free(prstr[1]); g_free(text); - } - for (i=0;i<NumLocation;i++) { - if (HaveTString) LocalName=Location[i].Name; - else LocalName=GetDefaultTString(Location[i].Name); - text=g_strdup_printf("%d^%c%s^",i,DT_LOCATION,LocalName); - if (!HaveTString) g_free(LocalName); - SendServerMessage(NULL,C_NONE,C_DATA,To,text); - g_free(text); - } +void SendMiscData(Player *To) +{ + gchar *text, *prstr[2], *LocalName; + int i; + gboolean HaveTString; + + if (!Network) + return; + HaveTString = HaveAbility(To, A_TSTRING); + text = g_strdup_printf("0^%c%s^%s^", DT_PRICES, + (prstr[0] = pricetostr(Prices.Spy)), + (prstr[1] = pricetostr(Prices.Tipoff))); + SendServerMessage(NULL, C_NONE, C_DATA, To, text); + g_free(prstr[0]); + g_free(prstr[1]); + g_free(text); + for (i = 0; i < NumGun; i++) { + if (HaveTString) + LocalName = Gun[i].Name; + else + LocalName = GetDefaultTString(Gun[i].Name); + text = g_strdup_printf("%d^%c%s^%s^%d^%d^", i, DT_GUN, LocalName, + (prstr[0] = pricetostr(Gun[i].Price)), + Gun[i].Space, Gun[i].Damage); + if (!HaveTString) + g_free(LocalName); + SendServerMessage(NULL, C_NONE, C_DATA, To, text); + g_free(prstr[0]); + g_free(text); + } + for (i = 0; i < NumDrug; i++) { + if (HaveTString) + LocalName = Drug[i].Name; + else + LocalName = GetDefaultTString(Drug[i].Name); + text = g_strdup_printf("%d^%c%s^%s^%s^", i, DT_DRUG, LocalName, + (prstr[0] = pricetostr(Drug[i].MinPrice)), + (prstr[1] = pricetostr(Drug[i].MaxPrice))); + if (!HaveTString) + g_free(LocalName); + SendServerMessage(NULL, C_NONE, C_DATA, To, text); + g_free(prstr[0]); + g_free(prstr[1]); + g_free(text); + } + for (i = 0; i < NumLocation; i++) { + if (HaveTString) + LocalName = Location[i].Name; + else + LocalName = GetDefaultTString(Location[i].Name); + text = g_strdup_printf("%d^%c%s^", i, DT_LOCATION, LocalName); + if (!HaveTString) + g_free(LocalName); + SendServerMessage(NULL, C_NONE, C_DATA, To, text); + g_free(text); + } } -void ReceiveMiscData(char *Data) { -/* Decodes information about locations, drugs, prices, etc. in "Data" */ - char *pt,*Name,Type; - int i; - pt=Data; - i=GetNextInt(&pt,0); - Name=GetNextWord(&pt,""); - Type=Name[0]; - if (strlen(Name)>1) switch(Type) { - case DT_LOCATION: - if (i>=0 && i<NumLocation) { - AssignName(&Location[i].Name,&Name[1]); - Location[i].PolicePresence=10; - Location[i].MinDrug=NumDrug/2+1; - Location[i].MaxDrug=NumDrug; - } - break; - case DT_GUN: - if (i>=0 && i<NumGun) { - AssignName(&Gun[i].Name,&Name[1]); - Gun[i].Price=GetNextPrice(&pt,(price_t)0); - Gun[i].Space=GetNextInt(&pt,0); - Gun[i].Damage=GetNextInt(&pt,0); - } - break; - case DT_DRUG: - if (i>=0 && i<NumDrug) { - AssignName(&Drug[i].Name,&Name[1]); - Drug[i].MinPrice=GetNextPrice(&pt,(price_t)0); - Drug[i].MaxPrice=GetNextPrice(&pt,(price_t)0); - } - break; - case DT_PRICES: - Prices.Spy=strtoprice(&Name[1]); - Prices.Tipoff=GetNextPrice(&pt,(price_t)0); - break; - } +/* + * Decodes information about locations, drugs, prices, etc. in "Data" + */ +void ReceiveMiscData(char *Data) +{ + char *pt, *Name, Type; + int i; + + pt = Data; + i = GetNextInt(&pt, 0); + Name = GetNextWord(&pt, ""); + Type = Name[0]; + if (strlen(Name) > 1) { + switch (Type) { + case DT_LOCATION: + if (i >= 0 && i < NumLocation) { + AssignName(&Location[i].Name, &Name[1]); + Location[i].PolicePresence = 10; + Location[i].MinDrug = NumDrug / 2 + 1; + Location[i].MaxDrug = NumDrug; + } + break; + case DT_GUN: + if (i >= 0 && i < NumGun) { + AssignName(&Gun[i].Name, &Name[1]); + Gun[i].Price = GetNextPrice(&pt, (price_t)0); + Gun[i].Space = GetNextInt(&pt, 0); + Gun[i].Damage = GetNextInt(&pt, 0); + } + break; + case DT_DRUG: + if (i >= 0 && i < NumDrug) { + AssignName(&Drug[i].Name, &Name[1]); + Drug[i].MinPrice = GetNextPrice(&pt, (price_t)0); + Drug[i].MaxPrice = GetNextPrice(&pt, (price_t)0); + } + break; + case DT_PRICES: + Prices.Spy = strtoprice(&Name[1]); + Prices.Tipoff = GetNextPrice(&pt, (price_t)0); + break; + } + } } -void ReceivePlayerData(Player *Play,char *text,Player *From) { -/* Decode player data from the string "text" into player "From"; "Play" */ -/* specifies the player that owns the network connection. */ - char *cp; - int i; - cp=text; - From->Cash=GetNextPrice(&cp,(price_t)0); - From->Debt=GetNextPrice(&cp,(price_t)0); - From->Bank=GetNextPrice(&cp,(price_t)0); - From->Health=GetNextInt(&cp,100); - From->CoatSize=GetNextInt(&cp,0); - From->IsAt=GetNextInt(&cp,0); - From->Turn=GetNextInt(&cp,0); - From->Flags=GetNextInt(&cp,0); - for (i=0;i<NumGun;i++) { - From->Guns[i].Carried=GetNextInt(&cp,0); - } - for (i=0;i<NumDrug;i++) { - From->Drugs[i].Carried=GetNextInt(&cp,0); - } - if (HaveAbility(Play,A_DRUGVALUE)) for (i=0;i<NumDrug;i++) { - From->Drugs[i].TotalValue=GetNextPrice(&cp,(price_t)0); - } - From->Bitches.Carried=GetNextInt(&cp,0); +/* + * Decode player data from the string "text" into player "From"; "Play" + * specifies the player that owns the network connection. + */ +void ReceivePlayerData(Player *Play, char *text, Player *From) +{ + char *cp; + int i; + + cp = text; + From->Cash = GetNextPrice(&cp, (price_t)0); + From->Debt = GetNextPrice(&cp, (price_t)0); + From->Bank = GetNextPrice(&cp, (price_t)0); + From->Health = GetNextInt(&cp, 100); + From->CoatSize = GetNextInt(&cp, 0); + From->IsAt = GetNextInt(&cp, 0); + From->Turn = GetNextInt(&cp, 0); + From->Flags = GetNextInt(&cp, 0); + for (i = 0; i < NumGun; i++) { + From->Guns[i].Carried = GetNextInt(&cp, 0); + } + for (i = 0; i < NumDrug; i++) { + From->Drugs[i].Carried = GetNextInt(&cp, 0); + } + if (HaveAbility(Play, A_DRUGVALUE)) { + for (i = 0; i < NumDrug; i++) { + From->Drugs[i].TotalValue = GetNextPrice(&cp, (price_t)0); + } + } + From->Bitches.Carried = GetNextInt(&cp, 0); } -gchar *GetNextWord(gchar **Data,gchar *Default) { - gchar *Word; - if (*Data==NULL || **Data=='\0') return Default; - Word=*Data; - while (**Data!='\0' && **Data!='^') (*Data)++; - if (**Data!='\0') { - **Data='\0'; (*Data)++; - } - return Word; +gchar *GetNextWord(gchar **Data, gchar *Default) +{ + gchar *Word; + + if (*Data == NULL || **Data == '\0') + return Default; + Word = *Data; + while (**Data != '\0' && **Data != '^') + (*Data)++; + if (**Data != '\0') { + **Data = '\0'; + (*Data)++; + } + return Word; } -void AssignNextWord(gchar **Data,gchar **Dest) { - if (!Dest) return; - g_free(*Dest); - *Dest=g_strdup(GetNextWord(Data,"")); +void AssignNextWord(gchar **Data, gchar **Dest) +{ + if (!Dest) + return; + g_free(*Dest); + *Dest = g_strdup(GetNextWord(Data, "")); } -int GetNextInt(gchar **Data,int Default) { - gchar *Word=GetNextWord(Data,NULL); - if (Word) return atoi(Word); else return Default; +int GetNextInt(gchar **Data, int Default) +{ + gchar *Word = GetNextWord(Data, NULL); + + if (Word) + return atoi(Word); + else + return Default; } -price_t GetNextPrice(gchar **Data,price_t Default) { - gchar *Word=GetNextWord(Data,NULL); - if (Word) return strtoprice(Word); else return Default; +price_t GetNextPrice(gchar **Data, price_t Default) +{ + gchar *Word = GetNextWord(Data, NULL); + + if (Word) + return strtoprice(Word); + else + return Default; } -void SwitchToSinglePlayer(Player *Play) { -/* Called when the client is pushed off the server, or the server */ -/* terminates. Using the client information, starts a local server */ -/* to reproduce the current game situation as best as possible so */ -/* that the game can be continued in single player mode */ - Player *NewPlayer; - if (!Network || !Client || !FirstClient) return; - ShutdownNetwork(Play); - CleanUpServer(); - Network=Server=Client=FALSE; - InitAbilities(Play); - NewPlayer=g_new(Player,1); - FirstServer=AddPlayer(0,NewPlayer,FirstServer); - CopyPlayer(NewPlayer,Play); - NewPlayer->Flags=0; - NewPlayer->EventNum=E_ARRIVE; - SendEvent(NewPlayer); +/* + * Called when the client is pushed off the server, or the server + * terminates. Using the client information, starts a local server + * to reproduce the current game situation as best as possible so + * that the game can be continued in single player mode. + */ +void SwitchToSinglePlayer(Player *Play) +{ + if (Network && Client && FirstClient) { + Player *NewPlayer; + + ShutdownNetwork(Play); + CleanUpServer(); + Network = Server = Client = FALSE; + InitAbilities(Play); + NewPlayer = g_new(Player, 1); + FirstServer = AddPlayer(0, NewPlayer, FirstServer); + CopyPlayer(NewPlayer, Play); + NewPlayer->Flags = 0; + NewPlayer->EventNum = E_ARRIVE; + SendEvent(NewPlayer); + } } -void ShutdownNetwork(Player *Play) { -/* Closes down the client side of the network connection. Clears the list */ -/* of client players (with the exception of "you", the player "Play"), */ -/* and closes the network socket. */ - if (Play!=FirstClient->data) { - g_error("Oops! FirstClient should be player!"); - } - while (g_slist_next(FirstClient)) { - FirstClient=RemovePlayer((Player *)g_slist_next(FirstClient)->data, +/* + * Closes down the client side of the network connection. Clears the list + * of client players (with the exception of "you", the player "Play"), + * and closes the network socket. + */ +void ShutdownNetwork(Player *Play) +{ + if (Play != FirstClient->data) { + g_error("Oops! FirstClient should be player!"); + } + while (g_slist_next(FirstClient)) { + FirstClient = RemovePlayer((Player *)g_slist_next(FirstClient)->data, FirstClient); - } + } #ifdef NETWORKING - ShutdownNetworkBuffer(&Play->NetBuf); + ShutdownNetworkBuffer(&Play->NetBuf); #endif - Client=Network=Server=FALSE; + Client = Network = Server = FALSE; } -int ProcessMessage(char *Msg,Player *Play,Player **Other,AICode *AI, - MsgCode *Code,char **Data,GSList *First) { -/* Given a "raw" message in "Msg" and a pointer to the start of the linked */ -/* list of known players in "First", sets the other arguments to the message */ -/* fields. Data is returned as a pointer into the message "Msg", and should */ -/* therefore NOT be g_free'd. "Play" is a pointer to the player which is */ -/* receiving the message. "Other" is the player that is identified by the */ -/* message; for messages to clients, this will be the player "From" which */ -/* the message claims to be, while for messages to servers, this will be */ -/* the player "To" which to send messages. Returns 0 on success, -1 on */ -/* failure. */ - gchar *pt,*buf; - guint ID; - - if (!First || !Play) return -1; - - *AI=C_NONE; - *Code=C_PRINTMESSAGE; - *Other=&Noone; - pt=Msg; - if (HaveAbility(Play,A_PLAYERID)) { - buf=GetNextWord(&pt,NULL); - if (buf[0]) { - ID=atoi(buf); - *Other=GetPlayerByID(ID,First); - } - } else { - buf=GetNextWord(&pt,NULL); - if (Client) *Other=GetPlayerByName(buf,First); - buf=GetNextWord(&pt,NULL); - if (Server) *Other=GetPlayerByName(buf,First); - } - if (!(*Other)) return -1; - - if (strlen(pt)>=2) { - *AI=pt[0]; - *Code=pt[1]; - *Data=&pt[2]; - return 0; - } - return -1; +/* + * Given a "raw" message in "Msg" and a pointer to the start of the linked + * list of known players in "First", sets the other arguments to the message + * fields. Data is returned as a pointer into the message "Msg", and should + * therefore NOT be g_free'd. "Play" is a pointer to the player which is + * receiving the message. "Other" is the player that is identified by the + * message; for messages to clients, this will be the player "From" which + * the message claims to be, while for messages to servers, this will be + * the player "To" which to send messages. Returns 0 on success, -1 on failure. + */ +int ProcessMessage(char *Msg, Player *Play, Player **Other, AICode *AI, + MsgCode *Code, char **Data, GSList *First) +{ + gchar *pt, *buf; + guint ID; + + if (!First || !Play) + return -1; + + *AI = C_NONE; + *Code = C_PRINTMESSAGE; + *Other = &Noone; + pt = Msg; + if (HaveAbility(Play, A_PLAYERID)) { + buf = GetNextWord(&pt, NULL); + if (buf[0]) { + ID = atoi(buf); + *Other = GetPlayerByID(ID, First); + } + } else { + buf = GetNextWord(&pt, NULL); + if (Client) + *Other = GetPlayerByName(buf, First); + buf = GetNextWord(&pt, NULL); + if (Server) + *Other = GetPlayerByName(buf, First); + } + if (!(*Other)) + return -1; + + if (strlen(pt) >= 2) { + *AI = pt[0]; + *Code = pt[1]; + *Data = &pt[2]; + return 0; + } + return -1; } -void ReceiveDrugsHere(char *text,Player *To) { -/* Decodes the message data "text" into a list of drug prices for */ -/* player "To" */ - char *cp; - int i; - - To->EventNum=E_ARRIVE; - cp=text; - for (i=0;i<NumDrug;i++) { - To->Drugs[i].Price=GetNextPrice(&cp,(price_t)0); - } +/* + * Decodes the message data "text" into a list of drug prices for + * player "To" + */ +void ReceiveDrugsHere(char *text, Player *To) +{ + char *cp; + int i; + + To->EventNum = E_ARRIVE; + cp = text; + for (i = 0; i < NumDrug; i++) { + To->Drugs[i].Price = GetNextPrice(&cp, (price_t)0); + } } -gboolean HandleGenericClientMessage(Player *From,AICode AI,MsgCode Code, - Player *To,char *Data, - DispMode *DisplayMode) { -/* Handles messages that both human clients and AI players deal with in the */ -/* same way. */ - Player *tmp; - gchar *pt; - switch(Code) { - case C_LIST: case C_JOIN: - tmp=g_new(Player,1); - FirstClient=AddPlayer(0,tmp,FirstClient); - pt=Data; - SetPlayerName(tmp,GetNextWord(&pt,NULL)); - if (HaveAbility(To,A_PLAYERID)) tmp->ID=GetNextInt(&pt,0); - break; - case C_DATA: - ReceiveMiscData(Data); break; - case C_INIT: - ReceiveInitialData(To,Data); break; - case C_ABILITIES: - ReceiveAbilities(To,Data); CombineAbilities(To); - break; - case C_LEAVE: - if (From!=&Noone) FirstClient=RemovePlayer(From,FirstClient); - break; - case C_TRADE: - if (DisplayMode) *DisplayMode=DM_DEAL; - break; - case C_DRUGHERE: - ReceiveDrugsHere(Data,To); - if (DisplayMode) *DisplayMode=DM_STREET; - break; - case C_FIGHTPRINT: - if (From!=&Noone) { - From->Flags |= FIGHTING; - To->Flags |= CANSHOOT; - } - if (DisplayMode) *DisplayMode=DM_FIGHT; - break; - case C_CHANGEDISP: - if (DisplayMode) { - if (Data[0]=='N' && *DisplayMode==DM_STREET) *DisplayMode=DM_NONE; - if (Data[0]=='Y' && *DisplayMode==DM_NONE) *DisplayMode=DM_STREET; - } - break; - default: - return FALSE; break; - } - return TRUE; +/* + * Handles messages that both human clients and AI players deal with + * in the same way. + */ +gboolean HandleGenericClientMessage(Player *From, AICode AI, MsgCode Code, + Player *To, char *Data, + DispMode *DisplayMode) +{ + Player *tmp; + gchar *pt; + + switch (Code) { + case C_LIST: + case C_JOIN: + tmp = g_new(Player, 1); + + FirstClient = AddPlayer(0, tmp, FirstClient); + pt = Data; + SetPlayerName(tmp, GetNextWord(&pt, NULL)); + if (HaveAbility(To, A_PLAYERID)) + tmp->ID = GetNextInt(&pt, 0); + break; + case C_DATA: + ReceiveMiscData(Data); + break; + case C_INIT: + ReceiveInitialData(To, Data); + break; + case C_ABILITIES: + ReceiveAbilities(To, Data); + CombineAbilities(To); + break; + case C_LEAVE: + if (From != &Noone) + FirstClient = RemovePlayer(From, FirstClient); + break; + case C_TRADE: + if (DisplayMode) + *DisplayMode = DM_DEAL; + break; + case C_DRUGHERE: + ReceiveDrugsHere(Data, To); + if (DisplayMode) + *DisplayMode = DM_STREET; + break; + case C_FIGHTPRINT: + if (From != &Noone) { + From->Flags |= FIGHTING; + To->Flags |= CANSHOOT; + } + if (DisplayMode) + *DisplayMode = DM_FIGHT; + break; + case C_CHANGEDISP: + if (DisplayMode) { + if (Data[0] == 'N' && *DisplayMode == DM_STREET) + *DisplayMode = DM_NONE; + if (Data[0] == 'Y' && *DisplayMode == DM_NONE) + *DisplayMode = DM_STREET; + } + break; + default: + return FALSE; + break; + } + return TRUE; } -void SendFightReload(Player *To) { - SendFightMessage(To,NULL,0,F_RELOAD,(price_t)0,FALSE,NULL); +void SendFightReload(Player *To) +{ + SendFightMessage(To, NULL, 0, F_RELOAD, (price_t)0, FALSE, NULL); } -void SendOldCanFireMessage(Player *To,GString *text) { - if (To->EventNum==E_FIGHT) { - To->EventNum=E_FIGHTASK; - if (CanRunHere(To) && To->Health>0 && !HaveAbility(To,A_NEWFIGHT)) { - if (text->len>0) g_string_append_c(text,'^'); - if (TotalGunsCarried(To)==0) { - g_string_prepend(text,"YN^"); - g_string_append(text,_("Do you run?")); - } else { - g_string_prepend(text,"RF^"); - g_string_append(text,_("Do you run, or fight?")); - } - SendQuestion(NULL,C_NONE,To,text->str); +void SendOldCanFireMessage(Player *To, GString *text) +{ + if (To->EventNum == E_FIGHT) { + To->EventNum = E_FIGHTASK; + if (CanRunHere(To) && To->Health > 0 && !HaveAbility(To, A_NEWFIGHT)) { + if (text->len > 0) + g_string_append_c(text, '^'); + if (TotalGunsCarried(To) == 0) { + g_string_prepend(text, "YN^"); + g_string_append(text, _("Do you run?")); } else { - SendOldFightPrint(To,text,FALSE); + g_string_prepend(text, "RF^"); + g_string_append(text, _("Do you run, or fight?")); } - } + SendQuestion(NULL, C_NONE, To, text->str); + } else { + SendOldFightPrint(To, text, FALSE); + } + } } -void SendOldFightPrint(Player *To,GString *text,gboolean FightOver) { - gboolean Fighting,CanShoot; +void SendOldFightPrint(Player *To, GString *text, gboolean FightOver) +{ + gboolean Fighting, CanShoot; + + Fighting = !FightOver; + CanShoot = CanPlayerFire(To); - Fighting=!FightOver; - CanShoot=CanPlayerFire(To); + To->Flags &= ~(CANSHOOT + FIGHTING); + if (Fighting) + To->Flags |= FIGHTING; + if (Fighting && CanShoot) + To->Flags |= CANSHOOT; + SendPlayerData(To); + To->Flags &= ~(CANSHOOT + FIGHTING); - To->Flags &= ~(CANSHOOT+FIGHTING); - if (Fighting) To->Flags |= FIGHTING; - if (Fighting && CanShoot) To->Flags |= CANSHOOT; - SendPlayerData(To); - To->Flags &= ~(CANSHOOT+FIGHTING); + SendServerMessage(NULL, C_NONE, C_FIGHTPRINT, To, text->str); +} - SendServerMessage(NULL,C_NONE,C_FIGHTPRINT,To,text->str); +void SendFightLeave(Player *Play, gboolean FightOver) +{ + SendFightMessage(Play, NULL, 0, FightOver ? F_LASTLEAVE : F_LEAVE, + (price_t)0, TRUE, NULL); } -void SendFightLeave(Player *Play,gboolean FightOver) { - SendFightMessage(Play,NULL,0,FightOver ? F_LASTLEAVE : F_LEAVE, - (price_t)0,TRUE,NULL); +void ReceiveFightMessage(gchar *Data, gchar **AttackName, + gchar **DefendName, int *DefendHealth, + int *DefendBitches, gchar **BitchName, + int *BitchesKilled, int *ArmPercent, + FightPoint *fp, gboolean *CanRunHere, + gboolean *Loot, gboolean *CanFire, + gchar **Message) +{ + gchar *pt, *Flags; + + pt = Data; + *AttackName = GetNextWord(&pt, ""); + *DefendName = GetNextWord(&pt, ""); + *DefendHealth = GetNextInt(&pt, 0); + *DefendBitches = GetNextInt(&pt, 0); + *BitchName = GetNextWord(&pt, ""); + *BitchesKilled = GetNextInt(&pt, 0); + *ArmPercent = GetNextInt(&pt, 0); + + Flags = GetNextWord(&pt, NULL); + if (Flags && strlen(Flags) >= 4) { + *fp = Flags[0]; + *CanRunHere = (Flags[1] == '1'); + *Loot = (Flags[2] == '1'); + *CanFire = (Flags[3] == '1'); + } else { + *fp = F_MSG; + *CanRunHere = *Loot = *CanFire = FALSE; + } + *Message = pt; } -void ReceiveFightMessage(gchar *Data,gchar **AttackName,gchar **DefendName, - int *DefendHealth,int *DefendBitches, - gchar **BitchName, - int *BitchesKilled,int *ArmPercent, - FightPoint *fp,gboolean *CanRunHere, - gboolean *Loot,gboolean *CanFire,gchar **Message) { - gchar *pt,*Flags; - - pt=Data; - *AttackName=GetNextWord(&pt,""); - *DefendName=GetNextWord(&pt,""); - *DefendHealth=GetNextInt(&pt,0); - *DefendBitches=GetNextInt(&pt,0); - *BitchName=GetNextWord(&pt,""); - *BitchesKilled=GetNextInt(&pt,0); - *ArmPercent=GetNextInt(&pt,0); - - Flags=GetNextWord(&pt,NULL); - if (Flags && strlen(Flags)>=4) { - *fp=Flags[0]; - *CanRunHere=(Flags[1]=='1'); - *Loot=(Flags[2]=='1'); - *CanFire=(Flags[3]=='1'); - } else { - *fp=F_MSG; - *CanRunHere=*Loot=*CanFire=FALSE; - } - *Message=pt; +void SendFightMessage(Player *Attacker, Player *Defender, + int BitchesKilled, FightPoint fp, + price_t Loot, gboolean Broadcast, gchar *Msg) +{ + guint ArrayInd; + int ArmPercent, Damage, MaxDamage, i; + Player *To; + GString *text; + gchar *BitchName; + + if (!Attacker->FightArray) + return; + + MaxDamage = Damage = 0; + for (i = 0; i < NumGun; i++) { + if (Gun[i].Damage > MaxDamage) + MaxDamage = Gun[i].Damage; + Damage += Gun[i].Damage * Attacker->Guns[i].Carried; + } + MaxDamage *= (Attacker->Bitches.Carried + 2); + ArmPercent = Damage * 100 / MaxDamage; + + text = g_string_new(""); + + for (ArrayInd = 0; ArrayInd < Attacker->FightArray->len; ArrayInd++) { + To = (Player *)g_ptr_array_index(Attacker->FightArray, ArrayInd); + if (!Broadcast && To != Attacker) + continue; + g_string_truncate(text, 0); + if (HaveAbility(To, A_NEWFIGHT)) { + if (Defender) { + if (IsCop(Defender)) { + if (Defender->Bitches.Carried == 1) { + BitchName = Cop[Defender->CopIndex - 1].DeputyName; + } else { + BitchName = Cop[Defender->CopIndex - 1].DeputiesName; + } + } else { + if (Defender->Bitches.Carried == 1) { + BitchName = Names.Bitch; + } else { + BitchName = Names.Bitches; + } + } + } else + BitchName = ""; + g_string_sprintf(text, "%s^%s^%d^%d^%s^%d^%d^%c%c%c%c^", + Attacker == To ? "" : GetPlayerName(Attacker), + (Defender == To || Defender == NULL) + ? "" : GetPlayerName(Defender), + Defender ? Defender->Health : 0, + Defender ? Defender->Bitches.Carried : 0, + BitchName, + BitchesKilled, ArmPercent, + fp, CanRunHere(To) ? '1' : '0', + Loot ? '1' : '0', + fp != F_ARRIVED && fp != F_LASTLEAVE && + CanPlayerFire(To) ? '1' : '0'); + } + if (Msg) { + g_string_append(text, Msg); + } else { + FormatFightMessage(To, text, Attacker, Defender, BitchesKilled, + ArmPercent, fp, Loot); + } + if (HaveAbility(To, A_NEWFIGHT)) { + SendServerMessage(NULL, C_NONE, C_FIGHTPRINT, To, text->str); + } else if (CanRunHere(To)) { + if (fp != F_ARRIVED && fp != F_MSG && + fp != F_LASTLEAVE && + (fp != F_LEAVE || Attacker != To) && + CanPlayerFire(To) && To->EventNum == E_FIGHT) { + SendOldCanFireMessage(To, text); + } else if (text->len > 0) + SendPrintMessage(NULL, C_NONE, To, text->str); + } else { + SendOldFightPrint(To, text, fp == F_LASTLEAVE); + } + } + g_string_free(text, TRUE); } -void SendFightMessage(Player *Attacker,Player *Defender, - int BitchesKilled,FightPoint fp, - price_t Loot,gboolean Broadcast,gchar *Msg) { - guint ArrayInd; - int ArmPercent,Damage,MaxDamage,i; - Player *To; - GString *text; - gchar *BitchName; - - if (!Attacker->FightArray) return; - - MaxDamage=Damage=0; - for (i=0;i<NumGun;i++) { - if (Gun[i].Damage>MaxDamage) MaxDamage=Gun[i].Damage; - Damage+=Gun[i].Damage*Attacker->Guns[i].Carried; - } - MaxDamage *= (Attacker->Bitches.Carried+2); - ArmPercent = Damage*100/MaxDamage; - - text=g_string_new(""); - - for (ArrayInd=0;ArrayInd<Attacker->FightArray->len;ArrayInd++) { - To=(Player *)g_ptr_array_index(Attacker->FightArray,ArrayInd); - if (!Broadcast && To!=Attacker) continue; - g_string_truncate(text,0); - if (HaveAbility(To,A_NEWFIGHT)) { - if (Defender) { - if (IsCop(Defender)) { - if (Defender->Bitches.Carried==1) { - BitchName=Cop[Defender->CopIndex-1].DeputyName; - } else { - BitchName=Cop[Defender->CopIndex-1].DeputiesName; - } - } else { - if (Defender->Bitches.Carried==1) { - BitchName=Names.Bitch; - } else { - BitchName=Names.Bitches; - } - } - } else BitchName=""; - g_string_sprintf(text,"%s^%s^%d^%d^%s^%d^%d^%c%c%c%c^", - Attacker==To ? "" : GetPlayerName(Attacker), - (Defender==To || Defender==NULL) - ? "" : GetPlayerName(Defender), - Defender ? Defender->Health : 0, - Defender ? Defender->Bitches.Carried : 0, - BitchName, - BitchesKilled,ArmPercent, - fp,CanRunHere(To) ? '1' : '0', - Loot ? '1' : '0', - fp!=F_ARRIVED && fp!=F_LASTLEAVE && - CanPlayerFire(To) ? '1' : '0'); +void FormatFightMessage(Player *To, GString *text, Player *Attacker, + Player *Defender, int BitchesKilled, + int ArmPercent, FightPoint fp, price_t Loot) +{ + gchar *Armament, *DefendName, *AttackName; + int Health, Bitches; + gchar *BitchName, *BitchesName; + + if (Defender && IsCop(Defender)) { + BitchName = Cop[Defender->CopIndex - 1].DeputyName; + BitchesName = Cop[Defender->CopIndex - 1].DeputiesName; + } else { + BitchName = Names.Bitch; + BitchesName = Names.Bitches; + } + + AttackName = (!Attacker + || Attacker == To ? "" : GetPlayerName(Attacker)); + DefendName = (!Defender + || Defender == To ? "" : GetPlayerName(Defender)); + Health = Defender ? Defender->Health : 0; + Bitches = Defender ? Defender->Bitches.Carried : 0; + + switch (fp) { + case F_ARRIVED: + Armament = ArmPercent < 10 ? _("pitifully armed") : + ArmPercent < 25 ? _("lightly armed") : + ArmPercent < 60 ? _("moderately well armed") : + ArmPercent < 80 ? _("heavily armed") : _("armed to the teeth"); + if (DefendName[0]) { + if (IsCop(Defender) && !AttackName[0]) { + if (Bitches == 0) { + dpg_string_sprintfa(text, _("%s - %s - is chasing you, man!"), + DefendName, Armament); + } else { + dpg_string_sprintfa(text, + _("%s and %d %tde - %s - are chasing you, man!"), + DefendName, Bitches, BitchesName, Armament); + } + } else { + dpg_string_sprintfa(text, _("%s arrives with %d %tde, %s!"), + DefendName, Bitches, BitchesName, Armament); } - if (Msg) { - g_string_append(text,Msg); + } + break; + case F_STAND: + if (AttackName[0]) { + g_string_sprintfa(text, _("%s stands and takes it"), AttackName); + } else { + g_string_append(text, _("You stand there like a dummy.")); + } + break; + case F_FAILFLEE: + if (AttackName[0]) { + g_string_sprintfa(text, _("%s tries to get away, but fails."), + AttackName); + } else { + g_string_append(text, _("Panic! You can't get away!")); + } + break; + case F_LEAVE: + case F_LASTLEAVE: + if (Attacker->Health > 0) { + if (AttackName[0]) { + if (!IsCop(Attacker) && brandom(0, 100) < 70 + && Attacker->IsAt >= 0) { + g_string_sprintfa(text, _("%s has got away to %s!"), AttackName, + Location[(int)Attacker->IsAt].Name); + } else { + g_string_sprintfa(text, _("%s has got away!"), AttackName); + } } else { - FormatFightMessage(To,text,Attacker,Defender,BitchesKilled, - ArmPercent,fp,Loot); + g_string_sprintfa(text, _("You got away!")); } - if (HaveAbility(To,A_NEWFIGHT)) { - SendServerMessage(NULL,C_NONE,C_FIGHTPRINT,To,text->str); - } else if (CanRunHere(To)) { - if (fp!=F_ARRIVED && fp!=F_MSG && - fp!=F_LASTLEAVE && - (fp!=F_LEAVE || Attacker!=To) && - CanPlayerFire(To) && To->EventNum==E_FIGHT) { - SendOldCanFireMessage(To,text); - } else if (text->len>0) SendPrintMessage(NULL,C_NONE,To,text->str); + } + break; + case F_RELOAD: + if (!AttackName[0]) { + g_string_append(text, _("Guns reloaded...")); + } + break; + case F_MISS: + if (AttackName[0] && DefendName[0]) { + g_string_sprintfa(text, _("%s shoots at %s... and misses!"), + AttackName, DefendName); + } else if (AttackName[0]) { + g_string_sprintfa(text, _("%s shoots at you... and misses!"), + AttackName); + } else if (DefendName[0]) { + g_string_sprintfa(text, _("You missed %s!"), DefendName); + } + break; + case F_HIT: + if (AttackName[0] && DefendName[0]) { + if (Health == 0 && Bitches == 0) { + g_string_sprintfa(text, _("%s shoots %s dead."), + AttackName, DefendName); + } else if (BitchesKilled) { + dpg_string_sprintfa(text, _("%s shoots at %s and kills a %tde!"), + AttackName, DefendName, BitchName); } else { - SendOldFightPrint(To,text,fp==F_LASTLEAVE); + g_string_sprintfa(text, _("%s shoots at %s."), + AttackName, DefendName); } - } - g_string_free(text,TRUE); -} - -void FormatFightMessage(Player *To,GString *text,Player *Attacker, - Player *Defender,int BitchesKilled,int ArmPercent, - FightPoint fp,price_t Loot) { - gchar *Armament,*DefendName,*AttackName; - int Health,Bitches; - gchar *BitchName,*BitchesName; - - if (Defender && IsCop(Defender)) { - BitchName=Cop[Defender->CopIndex-1].DeputyName; - BitchesName=Cop[Defender->CopIndex-1].DeputiesName; - } else { - BitchName=Names.Bitch; - BitchesName=Names.Bitches; - } - - AttackName = (!Attacker || Attacker==To ? "" : GetPlayerName(Attacker)); - DefendName = (!Defender || Defender==To ? "" : GetPlayerName(Defender)); - Health = Defender ? Defender->Health : 0; - Bitches = Defender ? Defender->Bitches.Carried : 0; - - switch(fp) { - case F_ARRIVED: - Armament= ArmPercent<10 ? _("pitifully armed") : - ArmPercent<25 ? _("lightly armed") : - ArmPercent<60 ? _("moderately well armed") : - ArmPercent<80 ? _("heavily armed") : - _("armed to the teeth"); - if (DefendName[0]) { - if (IsCop(Defender) && !AttackName[0]) { - if (Bitches==0) { - dpg_string_sprintfa(text,_("%s - %s - is chasing you, man!"), - DefendName,Armament); - } else { - dpg_string_sprintfa(text, - _("%s and %d %tde - %s - are chasing you, man!"), - DefendName,Bitches,BitchesName,Armament); - } - } else { - dpg_string_sprintfa(text,_("%s arrives with %d %tde, %s!"), - DefendName,Bitches,BitchesName,Armament); - } - } - break; - case F_STAND: - if (AttackName[0]) { - g_string_sprintfa(text,_("%s stands and takes it"),AttackName); - } else { - g_string_append(text,_("You stand there like a dummy.")); - } - break; - case F_FAILFLEE: - if (AttackName[0]) { - g_string_sprintfa(text,_("%s tries to get away, but fails."), - AttackName); - } else { - g_string_append(text,_("Panic! You can't get away!")); - } - break; - case F_LEAVE: case F_LASTLEAVE: - if (Attacker->Health>0) { - if (AttackName[0]) { - if (!IsCop(Attacker) && brandom(0,100)<70 && Attacker->IsAt>=0) { - g_string_sprintfa(text,_("%s has got away to %s!"),AttackName, - Location[(int)Attacker->IsAt].Name); - } else { - g_string_sprintfa(text,_("%s has got away!"),AttackName); - } - } else { - g_string_sprintfa(text,_("You got away!")); - } - } - break; - case F_RELOAD: - if (!AttackName[0]) { - g_string_append(text,_("Guns reloaded...")); - } - break; - case F_MISS: - if (AttackName[0] && DefendName[0]) { - g_string_sprintfa(text,_("%s shoots at %s... and misses!"), - AttackName,DefendName); - } else if (AttackName[0]) { - g_string_sprintfa(text,_("%s shoots at you... and misses!"), - AttackName); - } else if (DefendName[0]) { - g_string_sprintfa(text,_("You missed %s!"),DefendName); - } - break; - case F_HIT: - if (AttackName[0] && DefendName[0]) { - if (Health==0 && Bitches==0) { - g_string_sprintfa(text,_("%s shoots %s dead."), - AttackName,DefendName); - } else if (BitchesKilled) { - dpg_string_sprintfa(text,_("%s shoots at %s and kills a %tde!"), - AttackName,DefendName,BitchName); - } else { - g_string_sprintfa(text,_("%s shoots at %s."), - AttackName,DefendName); - } - } else if (AttackName[0]) { - if (Health==0 && Bitches==0) { - g_string_sprintfa(text,_("%s wasted you, man! What a drag!"), - AttackName); - } else if (BitchesKilled) { - dpg_string_sprintfa(text, - _("%s shoots at you... and kills a %tde!"), - AttackName,BitchName); - } else { - g_string_sprintfa(text,_("%s hits you, man!"),AttackName); - } - } else if (DefendName[0]) { - if (Health==0 && Bitches==0) { - g_string_sprintfa(text,_("You killed %s!"),DefendName); - } else if (BitchesKilled) { - dpg_string_sprintfa(text,_("You hit %s, and killed a %tde!"), - DefendName,BitchName); - } else { - g_string_sprintfa(text,_("You hit %s!"),DefendName); - } - if (Loot>0) { - dpg_string_sprintfa(text,_(" You find %P on the body!"),Loot); - } else if (Loot<0) { - g_string_append(text,_(" You loot the body!")); - } - } -/* if (Health>0) g_string_sprintfa(text,_(" (Health: %d)"),Health);*/ - break; - case F_MSG: - break; - } + } else if (AttackName[0]) { + if (Health == 0 && Bitches == 0) { + g_string_sprintfa(text, _("%s wasted you, man! What a drag!"), + AttackName); + } else if (BitchesKilled) { + dpg_string_sprintfa(text, + _("%s shoots at you... and kills a %tde!"), + AttackName, BitchName); + } else { + g_string_sprintfa(text, _("%s hits you, man!"), AttackName); + } + } else if (DefendName[0]) { + if (Health == 0 && Bitches == 0) { + g_string_sprintfa(text, _("You killed %s!"), DefendName); + } else if (BitchesKilled) { + dpg_string_sprintfa(text, _("You hit %s, and killed a %tde!"), + DefendName, BitchName); + } else { + g_string_sprintfa(text, _("You hit %s!"), DefendName); + } + if (Loot > 0) { + dpg_string_sprintfa(text, _(" You find %P on the body!"), Loot); + } else if (Loot < 0) { + g_string_append(text, _(" You loot the body!")); + } + } + break; + case F_MSG: + break; + } } (DIR) diff --git a/src/message.h b/src/message.h t@@ -1,23 +1,24 @@ -/* message.h Header file for dopewars message-handling routines */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * message.h Header file for dopewars message-handling routines * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __MESSAGE_H__ #define __MESSAGE_H__ t@@ -32,23 +33,23 @@ #include "network.h" typedef enum { - C_PRINTMESSAGE = 'A', - C_LIST, C_ENDLIST, C_NEWNAME, C_MSG, C_MSGTO, C_JOIN, C_LEAVE, - C_SUBWAYFLASH, C_UPDATE, C_DRUGHERE, C_GUNSHOP, C_LOANSHARK, - C_BANK, C_QUESTION, C_UNUSED, C_HISCORE, C_STARTHISCORE, C_ENDHISCORE, - C_BUYOBJECT, C_DONE, C_REQUESTJET, C_PAYLOAN, C_ANSWER, C_DEPOSIT, C_PUSH, - C_QUIT = 'a', - C_RENAME, C_NAME, C_SACKBITCH, C_TIPOFF, C_SPYON, C_WANTQUIT, - C_CONTACTSPY, C_KILL, C_REQUESTSCORE, C_INIT, C_DATA, - C_FIGHTPRINT, C_FIGHTACT, C_TRADE, C_CHANGEDISP, - C_NETMESSAGE, C_ABILITIES + C_PRINTMESSAGE = 'A', + C_LIST, C_ENDLIST, C_NEWNAME, C_MSG, C_MSGTO, C_JOIN, C_LEAVE, + C_SUBWAYFLASH, C_UPDATE, C_DRUGHERE, C_GUNSHOP, C_LOANSHARK, + C_BANK, C_QUESTION, C_UNUSED, C_HISCORE, C_STARTHISCORE, C_ENDHISCORE, + C_BUYOBJECT, C_DONE, C_REQUESTJET, C_PAYLOAN, C_ANSWER, C_DEPOSIT, C_PUSH, + C_QUIT = 'a', + C_RENAME, C_NAME, C_SACKBITCH, C_TIPOFF, C_SPYON, C_WANTQUIT, + C_CONTACTSPY, C_KILL, C_REQUESTSCORE, C_INIT, C_DATA, + C_FIGHTPRINT, C_FIGHTACT, C_TRADE, C_CHANGEDISP, + C_NETMESSAGE, C_ABILITIES } MsgCode; typedef enum { - C_NONE = 'A', - C_ASKLOAN, C_COPSMESG, C_ASKBITCH, C_ASKGUN, C_ASKGUNSHOP, - C_ASKPUB, C_ASKBANK, C_ASKRUN, C_ASKRUNFIGHT, C_ASKSEW, - C_MEETPLAYER, C_FIGHT, C_FIGHTDONE + C_NONE = 'A', + C_ASKLOAN, C_COPSMESG, C_ASKBITCH, C_ASKGUN, C_ASKGUNSHOP, + C_ASKPUB, C_ASKBANK, C_ASKRUN, C_ASKRUNFIGHT, C_ASKSEW, + C_MEETPLAYER, C_FIGHT, C_FIGHTDONE } AICode; #define DT_LOCATION 'A' t@@ -57,86 +58,88 @@ typedef enum { #define DT_PRICES 'D' typedef enum { - F_ARRIVED = 'A', F_STAND = 'S', F_HIT = 'H', - F_MISS = 'M', F_RELOAD = 'R', F_LEAVE = 'L', - F_LASTLEAVE = 'D', F_FAILFLEE = 'F', F_MSG = 'G' + F_ARRIVED = 'A', F_STAND = 'S', F_HIT = 'H', + F_MISS = 'M', F_RELOAD = 'R', F_LEAVE = 'L', + F_LASTLEAVE = 'D', F_FAILFLEE = 'F', F_MSG = 'G' } FightPoint; -void SendClientMessage(Player *From,AICode AI,MsgCode Code, - Player *To,char *Data); -void SendNullClientMessage(Player *From,AICode AI,MsgCode Code, - Player *To,char *Data); -void DoSendClientMessage(Player *From,AICode AI,MsgCode Code, - Player *To,char *Data,Player *BufOwn); -void SendServerMessage(Player *From,AICode AI,MsgCode Code, - Player *To,char *Data); -void SendPrintMessage(Player *From,AICode AI,Player *To,char *Data); -void SendQuestion(Player *From,AICode AI,Player *To,char *Data); +void SendClientMessage(Player *From, AICode AI, MsgCode Code, + Player *To, char *Data); +void SendNullClientMessage(Player *From, AICode AI, MsgCode Code, + Player *To, char *Data); +void DoSendClientMessage(Player *From, AICode AI, MsgCode Code, + Player *To, char *Data, Player *BufOwn); +void SendServerMessage(Player *From, AICode AI, MsgCode Code, + Player *To, char *Data); +void SendPrintMessage(Player *From, AICode AI, Player *To, char *Data); +void SendQuestion(Player *From, AICode AI, Player *To, char *Data); #if NETWORKING -gboolean PlayerHandleNetwork(Player *Play,gboolean ReadReady, - gboolean WriteReady,gboolean *DoneOK); +gboolean PlayerHandleNetwork(Player *Play, gboolean ReadReady, + gboolean WriteReady, gboolean *DoneOK); gboolean ReadPlayerDataFromWire(Player *Play); -void QueuePlayerMessageForSend(Player *Play,gchar *data); +void QueuePlayerMessageForSend(Player *Play, gchar *data); gboolean WritePlayerDataToWire(Player *Play); gchar *GetWaitingPlayerMessage(Player *Play); gboolean OpenMetaHttpConnection(HttpConnection **conn); -gboolean HandleWaitingMetaServerData(HttpConnection *conn,GSList **listpt, +gboolean HandleWaitingMetaServerData(HttpConnection *conn, GSList **listpt, gboolean *doneOK); void ClearServerList(GSList **listpt); #endif /* NETWORKING */ extern GSList *FirstClient; -extern void (*ClientMessageHandlerPt) (char *,Player *); +extern void (*ClientMessageHandlerPt) (char *, Player *); -void AddURLEnc(GString *str,gchar *unenc); +void AddURLEnc(GString *str, gchar *unenc); void chomp(char *str); -void BroadcastToClients(AICode AI,MsgCode Code,char *Data,Player *From, +void BroadcastToClients(AICode AI, MsgCode Code, char *Data, Player *From, Player *Except); -void SendInventory(Player *From,AICode AI,MsgCode Code,Player *To, - Inventory *Guns,Inventory *Drugs); -void ReceiveInventory(char *Data,Inventory *Guns,Inventory *Drugs); +void SendInventory(Player *From, AICode AI, MsgCode Code, Player *To, + Inventory *Guns, Inventory *Drugs); +void ReceiveInventory(char *Data, Inventory *Guns, Inventory *Drugs); void SendPlayerData(Player *To); -void SendSpyReport(Player *To,Player *SpiedOn); -void ReceivePlayerData(Player *Play,char *text,Player *From); +void SendSpyReport(Player *To, Player *SpiedOn); +void ReceivePlayerData(Player *Play, char *text, Player *From); void SendInitialData(Player *To); -void ReceiveInitialData(Player *Play,char *data); +void ReceiveInitialData(Player *Play, char *data); void SendMiscData(Player *To); void ReceiveMiscData(char *Data); -gchar *GetNextWord(gchar **Data,gchar *Default); -void AssignNextWord(gchar **Data,gchar **Dest); -int GetNextInt(gchar **Data,int Default); -price_t GetNextPrice(gchar **Data,price_t Default); +gchar *GetNextWord(gchar **Data, gchar *Default); +void AssignNextWord(gchar **Data, gchar **Dest); +int GetNextInt(gchar **Data, int Default); +price_t GetNextPrice(gchar **Data, price_t Default); void ShutdownNetwork(Player *Play); void SwitchToSinglePlayer(Player *Play); -int ProcessMessage(char *Msg,Player *Play,Player **Other,AICode *AI, - MsgCode *Code,char **Data,GSList *First); -void ReceiveDrugsHere(char *text,Player *To); -gboolean HandleGenericClientMessage(Player *From,AICode AI,MsgCode Code, - Player *To,char *Data,DispMode *DisplayMode); +int ProcessMessage(char *Msg, Player *Play, Player **Other, AICode *AI, + MsgCode *Code, char **Data, GSList *First); +void ReceiveDrugsHere(char *text, Player *To); +gboolean HandleGenericClientMessage(Player *From, AICode AI, MsgCode Code, + Player *To, char *Data, + DispMode *DisplayMode); void InitAbilities(Player *Play); void SendAbilities(Player *Play); -void ReceiveAbilities(Player *Play,gchar *Data); +void ReceiveAbilities(Player *Play, gchar *Data); void CombineAbilities(Player *Play); -void SetAbility(Player *Play,gint Type,gboolean Set); -gboolean HaveAbility(Player *Play,gint Type); +void SetAbility(Player *Play, gint Type, gboolean Set); +gboolean HaveAbility(Player *Play, gint Type); void SendFightReload(Player *To); -void SendOldCanFireMessage(Player *To,GString *text); -void SendOldFightPrint(Player *To,GString *text,gboolean FightOver); -void SendFightLeave(Player *Play,gboolean FightOver); -void ReceiveFightMessage(gchar *Data,gchar **AttackName,gchar **DefendName, - int *DefendHealth,int *DefendBitches, - gchar **BitchName, - int *BitchesKilled,int *ArmPercent, - FightPoint *fp,gboolean *CanRunHere, - gboolean *Loot,gboolean *CanFire,gchar **Message); -void SendFightMessage(Player *Attacker,Player *Defender, - int BitchesKilled,FightPoint fp, - price_t Loot,gboolean Broadcast,gchar *Msg); -void FormatFightMessage(Player *To,GString *text,Player *Attacker, - Player *Defender,int BitchesKilled,int ArmPercent, - FightPoint fp,price_t Loot); +void SendOldCanFireMessage(Player *To, GString *text); +void SendOldFightPrint(Player *To, GString *text, gboolean FightOver); +void SendFightLeave(Player *Play, gboolean FightOver); +void ReceiveFightMessage(gchar *Data, gchar **AttackName, + gchar **DefendName, int *DefendHealth, + int *DefendBitches, gchar **BitchName, + int *BitchesKilled, int *ArmPercent, + FightPoint *fp, gboolean *CanRunHere, + gboolean *Loot, gboolean *CanFire, + gchar **Message); +void SendFightMessage(Player *Attacker, Player *Defender, + int BitchesKilled, FightPoint fp, price_t Loot, + gboolean Broadcast, gchar *Msg); +void FormatFightMessage(Player *To, GString *text, Player *Attacker, + Player *Defender, int BitchesKilled, + int ArmPercent, FightPoint fp, price_t Loot); #endif /* __MESSAGE_H__ */ (DIR) diff --git a/src/network.c b/src/network.c t@@ -1,22 +1,24 @@ -/* network.c Low-level networking routines */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * network.c Low-level networking routines * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifdef HAVE_CONFIG_H #include <config.h> t@@ -25,189 +27,227 @@ #ifdef NETWORKING #ifdef CYGWIN -#include <windows.h> /* For datatypes such as BOOL */ -#include <winsock.h> /* For network functions */ +#include <windows.h> /* For datatypes such as BOOL */ +#include <winsock.h> /* For network functions */ #else -#include <sys/types.h> /* For size_t etc. */ -#include <sys/socket.h> /* For struct sockaddr etc. */ -#include <netinet/in.h> /* For struct sockaddr_in etc. */ -#include <arpa/inet.h> /* For socklen_t */ -#include <pwd.h> /* For getpwuid */ -#include <string.h> /* For memcpy, strlen etc. */ +#include <sys/types.h> /* For size_t etc. */ +#include <sys/socket.h> /* For struct sockaddr etc. */ +#include <netinet/in.h> /* For struct sockaddr_in etc. */ +#include <arpa/inet.h> /* For socklen_t */ +#include <pwd.h> /* For getpwuid */ +#include <string.h> /* For memcpy, strlen etc. */ #ifdef HAVE_UNISTD_H -#include <unistd.h> /* For close(), various types and constants */ +#include <unistd.h> /* For close(), various types and + * constants */ #endif #ifdef HAVE_FCNTL_H -#include <fcntl.h> /* For fcntl() */ +#include <fcntl.h> /* For fcntl() */ #endif -#include <netdb.h> /* For gethostbyname() */ +#include <netdb.h> /* For gethostbyname() */ #endif /* CYGWIN */ #include <glib.h> -#include <errno.h> /* For errno and Unix error codes */ -#include <stdlib.h> /* For exit() and atoi() */ -#include <stdio.h> /* For perror() */ +#include <errno.h> /* For errno and Unix error codes */ +#include <stdlib.h> /* For exit() and atoi() */ +#include <stdio.h> /* For perror() */ #include "error.h" #include "network.h" #include "nls.h" /* Maximum sizes (in bytes) of read and write buffers - connections should - be dropped if either buffer is filled */ + * be dropped if either buffer is filled */ #define MAXREADBUF (32768) #define MAXWRITEBUF (65536) /* SOCKS5 authentication method codes */ typedef enum { - SM_NOAUTH = 0, /* No authentication required */ - SM_GSSAPI = 1, /* GSSAPI */ - SM_USERPASSWD = 2 /* Username/password authentication */ + SM_NOAUTH = 0, /* No authentication required */ + SM_GSSAPI = 1, /* GSSAPI */ + SM_USERPASSWD = 2 /* Username/password authentication */ } SocksMethods; -static gboolean StartSocksNegotiation(NetworkBuffer *NetBuf,gchar *RemoteHost, +static gboolean StartSocksNegotiation(NetworkBuffer *NetBuf, + gchar *RemoteHost, unsigned RemotePort); -static gboolean StartConnect(int *fd,gchar *RemoteHost,unsigned RemotePort, - gboolean *doneOK,LastError **error); +static gboolean StartConnect(int *fd, gchar *RemoteHost, + unsigned RemotePort, gboolean *doneOK, + LastError **error); #ifdef CYGWIN -void StartNetworking() { +void StartNetworking() +{ WSADATA wsaData; LastError *error; GString *errstr; - if (WSAStartup(MAKEWORD(1,0),&wsaData)!=0) { - error = NewError(ET_WINSOCK,WSAGetLastError(),NULL); + if (WSAStartup(MAKEWORD(1, 0), &wsaData) != 0) { + error = NewError(ET_WINSOCK, WSAGetLastError(), NULL); errstr = g_string_new(""); - g_string_assign_error(errstr,error); - g_log(NULL,G_LOG_LEVEL_CRITICAL,_("Cannot initialise WinSock (%s)!"), + g_string_assign_error(errstr, error); + g_log(NULL, G_LOG_LEVEL_CRITICAL, _("Cannot initialise WinSock (%s)!"), errstr->str); - g_string_free(errstr,TRUE); + g_string_free(errstr, TRUE); FreeError(error); exit(1); } } -void StopNetworking() { +void StopNetworking() +{ WSACleanup(); } -void SetReuse(SOCKET sock) { - BOOL i=TRUE; - if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&i,sizeof(i))==-1) { - perror("setsockopt"); exit(1); +void SetReuse(SOCKET sock) +{ + BOOL i = TRUE; + + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&i, + sizeof(i)) == -1) { + perror("setsockopt"); + exit(1); } } -void SetBlocking(SOCKET sock,gboolean blocking) { +void SetBlocking(SOCKET sock, gboolean blocking) +{ unsigned long param; + param = blocking ? 0 : 1; - ioctlsocket(sock,FIONBIO,¶m); + ioctlsocket(sock, FIONBIO, ¶m); } #else -void StartNetworking() {} -void StopNetworking() {} +void StartNetworking() +{ +} + +void StopNetworking() +{ +} + +void SetReuse(int sock) +{ + int i = 1; -void SetReuse(int sock) { - int i=1; - if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i))==-1) { - perror("setsockopt"); exit(1); + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) == -1) { + perror("setsockopt"); + exit(1); } } -void SetBlocking(int sock,gboolean blocking) { - fcntl(sock,F_SETFL,blocking ? 0 : O_NONBLOCK); +void SetBlocking(int sock, gboolean blocking) +{ + fcntl(sock, F_SETFL, blocking ? 0 : O_NONBLOCK); } #endif /* CYGWIN */ -static gboolean FinishConnect(int fd,LastError **error); - -static void NetBufCallBack(NetworkBuffer *NetBuf,gboolean CallNow) { - if (NetBuf && NetBuf->CallBack) { - (*NetBuf->CallBack)(NetBuf,NetBuf->status!=NBS_PRECONNECT, - (NetBuf->status==NBS_CONNECTED && - NetBuf->WriteBuf.DataPresent) || - (NetBuf->status==NBS_SOCKSCONNECT && - NetBuf->negbuf.DataPresent) || - NetBuf->WaitConnect,CallNow); - } +static gboolean FinishConnect(int fd, LastError **error); + +static void NetBufCallBack(NetworkBuffer *NetBuf, gboolean CallNow) +{ + if (NetBuf && NetBuf->CallBack) { + (*NetBuf->CallBack) (NetBuf, NetBuf->status != NBS_PRECONNECT, + (NetBuf->status == NBS_CONNECTED + && NetBuf->WriteBuf.DataPresent) + || (NetBuf->status == NBS_SOCKSCONNECT + && NetBuf->negbuf.DataPresent) + || NetBuf->WaitConnect, CallNow); + } } -static void NetBufCallBackStop(NetworkBuffer *NetBuf) { - if (NetBuf && NetBuf->CallBack) { - (*NetBuf->CallBack)(NetBuf,FALSE,FALSE,FALSE); - } +static void NetBufCallBackStop(NetworkBuffer *NetBuf) +{ + if (NetBuf && NetBuf->CallBack) { + (*NetBuf->CallBack) (NetBuf, FALSE, FALSE, FALSE); + } } -static void InitConnBuf(ConnBuf *buf) { - buf->Data=NULL; - buf->Length=0; - buf->DataPresent=0; +static void InitConnBuf(ConnBuf *buf) +{ + buf->Data = NULL; + buf->Length = 0; + buf->DataPresent = 0; } -static void FreeConnBuf(ConnBuf *buf) { - g_free(buf->Data); - InitConnBuf(buf); +static void FreeConnBuf(ConnBuf *buf) +{ + g_free(buf->Data); + InitConnBuf(buf); } -void InitNetworkBuffer(NetworkBuffer *NetBuf,char Terminator,char StripChar, - SocksServer *socks) { -/* Initialises the passed network buffer, ready for use. Messages sent */ -/* or received on the buffered connection will be terminated by the */ -/* given character, and if they end in "StripChar" it will be removed */ -/* before the messages are sent or received. */ - NetBuf->fd=-1; - NetBuf->InputTag=0; - NetBuf->CallBack=NULL; - NetBuf->CallBackData=NULL; - NetBuf->Terminator=Terminator; - NetBuf->StripChar=StripChar; - InitConnBuf(&NetBuf->ReadBuf); - InitConnBuf(&NetBuf->WriteBuf); - InitConnBuf(&NetBuf->negbuf); - NetBuf->WaitConnect=FALSE; - NetBuf->status = NBS_PRECONNECT; - NetBuf->socks = socks; - NetBuf->host = NULL; - NetBuf->userpasswd = NULL; - NetBuf->error = NULL; +/* + * Initialises the passed network buffer, ready for use. Messages sent + * or received on the buffered connection will be terminated by the + * given character, and if they end in "StripChar" it will be removed + * before the messages are sent or received. + */ +void InitNetworkBuffer(NetworkBuffer *NetBuf, char Terminator, + char StripChar, SocksServer *socks) +{ + NetBuf->fd = -1; + NetBuf->InputTag = 0; + NetBuf->CallBack = NULL; + NetBuf->CallBackData = NULL; + NetBuf->Terminator = Terminator; + NetBuf->StripChar = StripChar; + InitConnBuf(&NetBuf->ReadBuf); + InitConnBuf(&NetBuf->WriteBuf); + InitConnBuf(&NetBuf->negbuf); + NetBuf->WaitConnect = FALSE; + NetBuf->status = NBS_PRECONNECT; + NetBuf->socks = socks; + NetBuf->host = NULL; + NetBuf->userpasswd = NULL; + NetBuf->error = NULL; } -void SetNetworkBufferCallBack(NetworkBuffer *NetBuf,NBCallBack CallBack, - gpointer CallBackData) { - NetBufCallBackStop(NetBuf); - NetBuf->CallBack=CallBack; - NetBuf->CallBackData=CallBackData; - NetBufCallBack(NetBuf,FALSE); +void SetNetworkBufferCallBack(NetworkBuffer *NetBuf, NBCallBack CallBack, + gpointer CallBackData) +{ + NetBufCallBackStop(NetBuf); + NetBuf->CallBack = CallBack; + NetBuf->CallBackData = CallBackData; + NetBufCallBack(NetBuf, FALSE); } +/* + * Sets the function used to obtain a username and password for SOCKS5 + * username/password authentication. + */ void SetNetworkBufferUserPasswdFunc(NetworkBuffer *NetBuf, - NBUserPasswd userpasswd,gpointer data) { -/* Sets the function used to obtain a username and password for SOCKS5 */ -/* username/password authentication */ - NetBuf->userpasswd=userpasswd; - NetBuf->userpasswddata=data; + NBUserPasswd userpasswd, gpointer data) +{ + NetBuf->userpasswd = userpasswd; + NetBuf->userpasswddata = data; } -void BindNetworkBufferToSocket(NetworkBuffer *NetBuf,int fd) { -/* Sets up the given network buffer to handle data being sent/received */ -/* through the given socket */ - NetBuf->fd=fd; - SetBlocking(fd,FALSE); /* We only deal with non-blocking sockets */ - NetBuf->status=NBS_CONNECTED; /* Assume the socket is connected */ +/* + * Sets up the given network buffer to handle data being sent/received + * through the given socket. + */ +void BindNetworkBufferToSocket(NetworkBuffer *NetBuf, int fd) +{ + NetBuf->fd = fd; + SetBlocking(fd, FALSE); /* We only deal with non-blocking sockets */ + NetBuf->status = NBS_CONNECTED; /* Assume the socket is connected */ } -gboolean IsNetworkBufferActive(NetworkBuffer *NetBuf) { -/* Returns TRUE if the pointer is to a valid network buffer, and it's */ -/* connected to an active socket. */ - return (NetBuf && NetBuf->fd>=0); +/* + * Returns TRUE if the pointer is to a valid network buffer, and it's + * connected to an active socket. + */ +gboolean IsNetworkBufferActive(NetworkBuffer *NetBuf) +{ + return (NetBuf && NetBuf->fd >= 0); } -gboolean StartNetworkBufferConnect(NetworkBuffer *NetBuf,gchar *RemoteHost, - unsigned RemotePort) { +gboolean StartNetworkBufferConnect(NetworkBuffer *NetBuf, + gchar *RemoteHost, unsigned RemotePort) +{ gchar *realhost; unsigned realport; gboolean doneOK; t@@ -222,23 +262,25 @@ gboolean StartNetworkBufferConnect(NetworkBuffer *NetBuf,gchar *RemoteHost, realport = RemotePort; } - if (StartConnect(&NetBuf->fd,realhost,realport,&doneOK,&NetBuf->error)) { -/* If we connected immediately, then set status, otherwise signal that we're - waiting for the connect to complete */ + if (StartConnect(&NetBuf->fd, realhost, realport, &doneOK, + &NetBuf->error)) { + /* If we connected immediately, then set status, otherwise signal that + * we're waiting for the connect to complete */ if (doneOK) { NetBuf->status = NetBuf->socks ? NBS_SOCKSCONNECT : NBS_CONNECTED; NetBuf->sockstat = NBSS_METHODS; } else { - NetBuf->WaitConnect=TRUE; + NetBuf->WaitConnect = TRUE; } - if (NetBuf->socks && !StartSocksNegotiation(NetBuf,RemoteHost,RemotePort)) { + if (NetBuf->socks + && !StartSocksNegotiation(NetBuf, RemoteHost, RemotePort)) { return FALSE; } -/* Notify the owner if necessary to check for the connection completing - and/or for data to be writeable */ - NetBufCallBack(NetBuf,FALSE); + /* Notify the owner if necessary to check for the connection + * completing and/or for data to be writeable */ + NetBufCallBack(NetBuf, FALSE); return TRUE; } else { t@@ -246,896 +288,1034 @@ gboolean StartNetworkBufferConnect(NetworkBuffer *NetBuf,gchar *RemoteHost, } } -void ShutdownNetworkBuffer(NetworkBuffer *NetBuf) { -/* Frees the network buffer's data structures (leaving it in the */ -/* 'initialised' state) and closes the accompanying socket. */ - - NetBufCallBackStop(NetBuf); +/* + * Frees the network buffer's data structures (leaving it in the + * 'initialised' state) and closes the accompanying socket. + */ +void ShutdownNetworkBuffer(NetworkBuffer *NetBuf) +{ + NetBufCallBackStop(NetBuf); - if (NetBuf->fd>=0) CloseSocket(NetBuf->fd); + if (NetBuf->fd >= 0) + CloseSocket(NetBuf->fd); - FreeConnBuf(&NetBuf->ReadBuf); - FreeConnBuf(&NetBuf->WriteBuf); - FreeConnBuf(&NetBuf->negbuf); + FreeConnBuf(&NetBuf->ReadBuf); + FreeConnBuf(&NetBuf->WriteBuf); + FreeConnBuf(&NetBuf->negbuf); - FreeError(NetBuf->error); NetBuf->error=NULL; + FreeError(NetBuf->error); + NetBuf->error = NULL; - g_free(NetBuf->host); + g_free(NetBuf->host); - InitNetworkBuffer(NetBuf,NetBuf->Terminator,NetBuf->StripChar,NetBuf->socks); + InitNetworkBuffer(NetBuf, NetBuf->Terminator, NetBuf->StripChar, + NetBuf->socks); } -void SetSelectForNetworkBuffer(NetworkBuffer *NetBuf,fd_set *readfds, - fd_set *writefds,fd_set *errorfds,int *MaxSock) { -/* Updates the sets of read and write file descriptors to monitor */ -/* input to/output from the given network buffer. MaxSock is updated */ -/* with the highest-numbered file descriptor (plus 1) for use in a */ -/* later select() call. */ - if (!NetBuf || NetBuf->fd<=0) return; - FD_SET(NetBuf->fd,readfds); - if (errorfds) FD_SET(NetBuf->fd,errorfds); - if (NetBuf->fd >= *MaxSock) *MaxSock=NetBuf->fd+1; - if ((NetBuf->status==NBS_CONNECTED && NetBuf->WriteBuf.DataPresent) || - (NetBuf->status==NBS_SOCKSCONNECT && NetBuf->negbuf.DataPresent) || - NetBuf->WaitConnect) { - FD_SET(NetBuf->fd,writefds); - } +/* + * Updates the sets of read and write file descriptors to monitor + * input to/output from the given network buffer. MaxSock is updated + * with the highest-numbered file descriptor (plus 1) for use in a + * later select() call. + */ +void SetSelectForNetworkBuffer(NetworkBuffer *NetBuf, fd_set *readfds, + fd_set *writefds, fd_set *errorfds, + int *MaxSock) +{ + if (!NetBuf || NetBuf->fd <= 0) + return; + FD_SET(NetBuf->fd, readfds); + if (errorfds) + FD_SET(NetBuf->fd, errorfds); + if (NetBuf->fd >= *MaxSock) + *MaxSock = NetBuf->fd + 1; + if ((NetBuf->status == NBS_CONNECTED && NetBuf->WriteBuf.DataPresent) + || (NetBuf->status == NBS_SOCKSCONNECT && NetBuf->negbuf.DataPresent) + || NetBuf->WaitConnect) { + FD_SET(NetBuf->fd, writefds); + } } typedef enum { - SEC_5FAILURE = 1, - SEC_5RULESET = 2, - SEC_5NETDOWN = 3, - SEC_5UNREACH = 4, - SEC_5CONNREF = 5, - SEC_5TTLEXPIRED = 6, - SEC_5COMMNOSUPP = 7, - SEC_5ADDRNOSUPP = 8, - - SEC_REJECT = 91, - SEC_NOIDENTD = 92, - SEC_IDMISMATCH = 93, - - SEC_UNKNOWN = 200, - SEC_AUTHFAILED, - SEC_USERCANCEL, - SEC_ADDRTYPE, - SEC_REPLYVERSION, - SEC_VERSION, - SEC_NOMETHODS + SEC_5FAILURE = 1, + SEC_5RULESET = 2, + SEC_5NETDOWN = 3, + SEC_5UNREACH = 4, + SEC_5CONNREF = 5, + SEC_5TTLEXPIRED = 6, + SEC_5COMMNOSUPP = 7, + SEC_5ADDRNOSUPP = 8, + + SEC_REJECT = 91, + SEC_NOIDENTD = 92, + SEC_IDMISMATCH = 93, + + SEC_UNKNOWN = 200, + SEC_AUTHFAILED, + SEC_USERCANCEL, + SEC_ADDRTYPE, + SEC_REPLYVERSION, + SEC_VERSION, + SEC_NOMETHODS } SocksErrorCode; static ErrTable SocksErrStr[] = { -/* SOCKS version 5 error messages */ - { SEC_5FAILURE,N_("SOCKS server general failure") }, - { SEC_5RULESET,N_("Connection denied by SOCKS ruleset") }, - { SEC_5NETDOWN,N_("SOCKS: Network unreachable") }, - { SEC_5UNREACH,N_("SOCKS: Host unreachable") }, - { SEC_5CONNREF,N_("SOCKS: Connection refused") }, - { SEC_5TTLEXPIRED,N_("SOCKS: TTL expired") }, - { SEC_5COMMNOSUPP,N_("SOCKS: Command not supported") }, - { SEC_5ADDRNOSUPP,N_("SOCKS: Address type not supported") }, - { SEC_NOMETHODS,N_("SOCKS server rejected all offered methods") }, - { SEC_ADDRTYPE,N_("Unknown SOCKS address type returned") }, - { SEC_AUTHFAILED,N_("SOCKS authentication failed") }, - { SEC_USERCANCEL,N_("SOCKS authentication cancelled by user") }, - -/* SOCKS version 4 error messages */ - { SEC_REJECT,N_("SOCKS: Request rejected or failed") }, - { SEC_NOIDENTD,N_("SOCKS: Rejected - unable to contact identd") }, - { SEC_IDMISMATCH,N_("SOCKS: Rejected - identd reports different user-id") }, - -/* SOCKS errors due to protocol violations */ - { SEC_UNKNOWN,N_("Unknown SOCKS reply code") }, - { SEC_REPLYVERSION,N_("Unknown SOCKS reply version code") }, - { SEC_VERSION,N_("Unknown SOCKS server version") }, - { 0,NULL } + /* SOCKS version 5 error messages */ + {SEC_5FAILURE, N_("SOCKS server general failure")}, + {SEC_5RULESET, N_("Connection denied by SOCKS ruleset")}, + {SEC_5NETDOWN, N_("SOCKS: Network unreachable")}, + {SEC_5UNREACH, N_("SOCKS: Host unreachable")}, + {SEC_5CONNREF, N_("SOCKS: Connection refused")}, + {SEC_5TTLEXPIRED, N_("SOCKS: TTL expired")}, + {SEC_5COMMNOSUPP, N_("SOCKS: Command not supported")}, + {SEC_5ADDRNOSUPP, N_("SOCKS: Address type not supported")}, + {SEC_NOMETHODS, N_("SOCKS server rejected all offered methods")}, + {SEC_ADDRTYPE, N_("Unknown SOCKS address type returned")}, + {SEC_AUTHFAILED, N_("SOCKS authentication failed")}, + {SEC_USERCANCEL, N_("SOCKS authentication cancelled by user")}, + + /* SOCKS version 4 error messages */ + {SEC_REJECT, N_("SOCKS: Request rejected or failed")}, + {SEC_NOIDENTD, N_("SOCKS: Rejected - unable to contact identd")}, + {SEC_IDMISMATCH, + N_("SOCKS: Rejected - identd reports different user-id")}, + + /* SOCKS errors due to protocol violations */ + {SEC_UNKNOWN, N_("Unknown SOCKS reply code")}, + {SEC_REPLYVERSION, N_("Unknown SOCKS reply version code")}, + {SEC_VERSION, N_("Unknown SOCKS server version")}, + {0, NULL} }; -static void SocksAppendError(GString *str,LastError *error) { - LookupErrorCode(str,error->code,SocksErrStr,_("SOCKS error code %d")); +static void SocksAppendError(GString *str, LastError *error) +{ + LookupErrorCode(str, error->code, SocksErrStr, _("SOCKS error code %d")); } -static ErrorType ETSocks = { SocksAppendError,NULL }; +static ErrorType ETSocks = { SocksAppendError, NULL }; typedef enum { - HEC_TRIESEX = 1, + HEC_TRIESEX = 1, HEC_BADAUTH, HEC_BADREDIR, HEC_BADSTATUS, - HEC_OK = 200, - HEC_REDIRECT = 300, - HEC_MOVEPERM = 301, - HEC_MOVETEMP = 302, + HEC_OK = 200, + HEC_REDIRECT = 300, + HEC_MOVEPERM = 301, + HEC_MOVETEMP = 302, HEC_CLIENTERR = 400, - HEC_AUTHREQ = 401, + HEC_AUTHREQ = 401, HEC_PROXYAUTH = 407, HEC_FORBIDDEN = 403, - HEC_NOTFOUND = 404, + HEC_NOTFOUND = 404, HEC_SERVERERR = 500 } HTTPErrorCode; -static void HTTPAppendError(GString *str,LastError *error) { +static void HTTPAppendError(GString *str, LastError *error) +{ switch (error->code) { - case HEC_TRIESEX: -/* Various HTTP error messages */ - g_string_append(str,_("Number of tries exceeded")); - break; - case HEC_BADAUTH: - g_string_sprintfa(str,_("Bad auth header: %s"),(gchar *)error->data); - break; - case HEC_BADREDIR: - g_string_sprintfa(str,_("Bad redirect: %s"),(gchar *)error->data); - break; - case HEC_BADSTATUS: - g_string_sprintfa(str,_("Invalid HTTP status line: %s"), - (gchar *)error->data); - break; - case HEC_FORBIDDEN: - g_string_append(str,_("403: forbidden")); - break; - case HEC_NOTFOUND: - g_string_append(str,_("404: page not found")); - break; - case HEC_AUTHREQ: - g_string_append(str,_("401: HTTP authentication failed")); - break; - case HEC_PROXYAUTH: - g_string_append(str,_("407: HTTP proxy authentication failed")); - break; - case HEC_MOVETEMP: case HEC_MOVEPERM: - g_string_append(str,_("Bad redirect message from server")); - break; - default: - if (error->code<HEC_REDIRECT || error->code>=600) { - g_string_sprintfa(str,_("Unknown HTTP error %d"),error->code); - } else if (error->code<HEC_CLIENTERR) { - g_string_sprintfa(str,_("%d: redirect error"),error->code); - } else if (error->code<HEC_SERVERERR) { - g_string_sprintfa(str,_("%d: HTTP client error"),error->code); - } else { - g_string_sprintfa(str,_("%d: HTTP server error"),error->code); - } - break; + case HEC_TRIESEX: + /* Various HTTP error messages */ + g_string_append(str, _("Number of tries exceeded")); + break; + case HEC_BADAUTH: + g_string_sprintfa(str, _("Bad auth header: %s"), (gchar *)error->data); + break; + case HEC_BADREDIR: + g_string_sprintfa(str, _("Bad redirect: %s"), (gchar *)error->data); + break; + case HEC_BADSTATUS: + g_string_sprintfa(str, _("Invalid HTTP status line: %s"), + (gchar *)error->data); + break; + case HEC_FORBIDDEN: + g_string_append(str, _("403: forbidden")); + break; + case HEC_NOTFOUND: + g_string_append(str, _("404: page not found")); + break; + case HEC_AUTHREQ: + g_string_append(str, _("401: HTTP authentication failed")); + break; + case HEC_PROXYAUTH: + g_string_append(str, _("407: HTTP proxy authentication failed")); + break; + case HEC_MOVETEMP: + case HEC_MOVEPERM: + g_string_append(str, _("Bad redirect message from server")); + break; + default: + if (error->code < HEC_REDIRECT || error->code >= 600) { + g_string_sprintfa(str, _("Unknown HTTP error %d"), error->code); + } else if (error->code < HEC_CLIENTERR) { + g_string_sprintfa(str, _("%d: redirect error"), error->code); + } else if (error->code < HEC_SERVERERR) { + g_string_sprintfa(str, _("%d: HTTP client error"), error->code); + } else { + g_string_sprintfa(str, _("%d: HTTP server error"), error->code); + } + break; } } -static ErrorType ETHTTP = { HTTPAppendError,NULL }; +static ErrorType ETHTTP = { HTTPAppendError, NULL }; -static gboolean Socks5UserPasswd(NetworkBuffer *NetBuf) { - if (!NetBuf->userpasswd) { - SetError(&NetBuf->error,&ETSocks,SEC_NOMETHODS,NULL); - return FALSE; - } else { -/* Request a username and password (the callback function should in turn - call SendSocks5UserPasswd when it's done) */ - NetBuf->sockstat = NBSS_USERPASSWD; - (*NetBuf->userpasswd)(NetBuf,NetBuf->userpasswddata); - return TRUE; - } +static gboolean Socks5UserPasswd(NetworkBuffer *NetBuf) +{ + if (!NetBuf->userpasswd) { + SetError(&NetBuf->error, &ETSocks, SEC_NOMETHODS, NULL); + return FALSE; + } else { + /* Request a username and password (the callback function should in + * turn call SendSocks5UserPasswd when it's done) */ + NetBuf->sockstat = NBSS_USERPASSWD; + (*NetBuf->userpasswd) (NetBuf, NetBuf->userpasswddata); + return TRUE; + } } -void SendSocks5UserPasswd(NetworkBuffer *NetBuf,gchar *user,gchar *password) { - gchar *addpt; - guint addlen; - ConnBuf *conn; - - if (!user || !password || !user[0] || !password[0]) { - SetError(&NetBuf->error,&ETSocks,SEC_USERCANCEL,NULL); - NetBufCallBack(NetBuf,TRUE); - return; - } - conn=&NetBuf->negbuf; - addlen = 3 + strlen(user) + strlen(password); - addpt = ExpandWriteBuffer(conn,addlen,&NetBuf->error); - if (!addpt || strlen(user)>255 || strlen(password)>255) { - SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF,NULL); - NetBufCallBack(NetBuf,TRUE); - return; - } - addpt[0] = 1; /* Subnegotiation version code */ - addpt[1] = strlen(user); - strcpy(&addpt[2],user); - addpt[2+strlen(user)] = strlen(password); - strcpy(&addpt[3+strlen(user)],password); - - CommitWriteBuffer(NetBuf,conn,addpt,addlen); -} +void SendSocks5UserPasswd(NetworkBuffer *NetBuf, gchar *user, + gchar *password) +{ + gchar *addpt; + guint addlen; + ConnBuf *conn; + + if (!user || !password || !user[0] || !password[0]) { + SetError(&NetBuf->error, &ETSocks, SEC_USERCANCEL, NULL); + NetBufCallBack(NetBuf, TRUE); + return; + } + conn = &NetBuf->negbuf; + addlen = 3 + strlen(user) + strlen(password); + addpt = ExpandWriteBuffer(conn, addlen, &NetBuf->error); + if (!addpt || strlen(user) > 255 || strlen(password) > 255) { + SetError(&NetBuf->error, ET_CUSTOM, E_FULLBUF, NULL); + NetBufCallBack(NetBuf, TRUE); + return; + } + addpt[0] = 1; /* Subnegotiation version code */ + addpt[1] = strlen(user); + strcpy(&addpt[2], user); + addpt[2 + strlen(user)] = strlen(password); + strcpy(&addpt[3 + strlen(user)], password); -static gboolean Socks5Connect(NetworkBuffer *NetBuf) { - guchar *addpt; - guint addlen,hostlen; - ConnBuf *conn; - unsigned short int netport; + CommitWriteBuffer(NetBuf, conn, addpt, addlen); +} - conn=&NetBuf->negbuf; - g_assert(NetBuf->host); - hostlen=strlen(NetBuf->host); - if (hostlen>255) return FALSE; +static gboolean Socks5Connect(NetworkBuffer *NetBuf) +{ + guchar *addpt; + guint addlen, hostlen; + ConnBuf *conn; + unsigned short int netport; + + conn = &NetBuf->negbuf; + g_assert(NetBuf->host); + hostlen = strlen(NetBuf->host); + if (hostlen > 255) + return FALSE; - netport = htons(NetBuf->port); - g_assert(sizeof(netport)==2); + netport = htons(NetBuf->port); + g_assert(sizeof(netport) == 2); - addlen = hostlen + 7; - addpt = ExpandWriteBuffer(conn,addlen,&NetBuf->error); - if (!addpt) return FALSE; - addpt[0] = 5; /* SOCKS version 5 */ - addpt[1] = 1; /* CONNECT */ - addpt[2] = 0; /* reserved - must be zero */ - addpt[3] = 3; /* Address type - FQDN */ - addpt[4] = hostlen; /* Length of address */ - strcpy(&addpt[5],NetBuf->host); - memcpy(&addpt[5+hostlen],&netport,sizeof(netport)); + addlen = hostlen + 7; + addpt = ExpandWriteBuffer(conn, addlen, &NetBuf->error); + if (!addpt) + return FALSE; + addpt[0] = 5; /* SOCKS version 5 */ + addpt[1] = 1; /* CONNECT */ + addpt[2] = 0; /* reserved - must be zero */ + addpt[3] = 3; /* Address type - FQDN */ + addpt[4] = hostlen; /* Length of address */ + strcpy(&addpt[5], NetBuf->host); + memcpy(&addpt[5 + hostlen], &netport, sizeof(netport)); - NetBuf->sockstat = NBSS_CONNECT; + NetBuf->sockstat = NBSS_CONNECT; - CommitWriteBuffer(NetBuf,conn,addpt,addlen); + CommitWriteBuffer(NetBuf, conn, addpt, addlen); - return TRUE; + return TRUE; } -static gboolean HandleSocksReply(NetworkBuffer *NetBuf) { - guchar *data; - guchar addrtype; - guint replylen; - gboolean retval=TRUE; - if (NetBuf->socks->version==5) { - if (NetBuf->sockstat == NBSS_METHODS) { - data = GetWaitingData(NetBuf,2); - if (data) { - retval=FALSE; - if (data[0]!=5) { - SetError(&NetBuf->error,&ETSocks,SEC_VERSION,NULL); - } else if (data[1]==SM_NOAUTH) { - retval=Socks5Connect(NetBuf); - } else if (data[1]==SM_USERPASSWD) { - retval=Socks5UserPasswd(NetBuf); - } else { - SetError(&NetBuf->error,&ETSocks,SEC_NOMETHODS,NULL); - } - g_free(data); - } - } else if (NetBuf->sockstat == NBSS_USERPASSWD) { - data = GetWaitingData(NetBuf,2); - if (data) { - retval=FALSE; - if (data[1]!=0) { - SetError(&NetBuf->error,&ETSocks,SEC_AUTHFAILED,NULL); - } else { - retval=Socks5Connect(NetBuf); - } - g_free(data); - } - } else if (NetBuf->sockstat == NBSS_CONNECT) { - data = PeekWaitingData(NetBuf,5); - if (data) { - retval=FALSE; - addrtype = data[3]; - if (data[0]!=5) { - SetError(&NetBuf->error,&ETSocks,SEC_VERSION,NULL); - } else if (data[1]>8) { - SetError(&NetBuf->error,&ETSocks,SEC_UNKNOWN,NULL); - } else if (data[1]!=0) { - SetError(&NetBuf->error,&ETSocks,data[1],NULL); - } else if (addrtype!=1 && addrtype!=3 && addrtype!=4) { - SetError(&NetBuf->error,&ETSocks,SEC_ADDRTYPE,NULL); - } else { - retval=TRUE; - replylen = 6; - if (addrtype==1) replylen+=4; /* IPv4 address */ - else if (addrtype==4) replylen+=16; /* IPv6 address */ - else replylen+=data[4]; /* FQDN */ - data = GetWaitingData(NetBuf,replylen); - if (data) { -/* if (addrtype==1) g_print("IPv4 address %d.%d.%d.%d\n",data[4],data[5],data[6],data[7]); - else if (addrtype==4) g_print("IPv6 address\n"); - else g_print("FQDN\n");*/ - NetBuf->status = NBS_CONNECTED; - g_free(data); - NetBufCallBack(NetBuf,FALSE); /* status has changed */ - } - } - } +static gboolean HandleSocksReply(NetworkBuffer *NetBuf) +{ + guchar *data; + guchar addrtype; + guint replylen; + gboolean retval = TRUE; + + if (NetBuf->socks->version == 5) { + if (NetBuf->sockstat == NBSS_METHODS) { + data = GetWaitingData(NetBuf, 2); + if (data) { + retval = FALSE; + if (data[0] != 5) { + SetError(&NetBuf->error, &ETSocks, SEC_VERSION, NULL); + } else if (data[1] == SM_NOAUTH) { + retval = Socks5Connect(NetBuf); + } else if (data[1] == SM_USERPASSWD) { + retval = Socks5UserPasswd(NetBuf); + } else { + SetError(&NetBuf->error, &ETSocks, SEC_NOMETHODS, NULL); + } + g_free(data); + } + } else if (NetBuf->sockstat == NBSS_USERPASSWD) { + data = GetWaitingData(NetBuf, 2); + if (data) { + retval = FALSE; + if (data[1] != 0) { + SetError(&NetBuf->error, &ETSocks, SEC_AUTHFAILED, NULL); + } else { + retval = Socks5Connect(NetBuf); + } + g_free(data); } - return retval; - } else { - data = GetWaitingData(NetBuf,8); + } else if (NetBuf->sockstat == NBSS_CONNECT) { + data = PeekWaitingData(NetBuf, 5); if (data) { - retval=FALSE; - if (data[0]!=0) { - SetError(&NetBuf->error,&ETSocks,SEC_REPLYVERSION,NULL); - } else { - if (data[1]==90) { - NetBuf->status = NBS_CONNECTED; - NetBufCallBack(NetBuf,FALSE); /* status has changed */ - retval=TRUE; - } else if (data[1]>=SEC_REJECT && data[1]<=SEC_IDMISMATCH) { - SetError(&NetBuf->error,&ETSocks,data[1],NULL); - } else { - SetError(&NetBuf->error,&ETSocks,SEC_UNKNOWN,NULL); - } - } - g_free(data); + retval = FALSE; + addrtype = data[3]; + if (data[0] != 5) { + SetError(&NetBuf->error, &ETSocks, SEC_VERSION, NULL); + } else if (data[1] > 8) { + SetError(&NetBuf->error, &ETSocks, SEC_UNKNOWN, NULL); + } else if (data[1] != 0) { + SetError(&NetBuf->error, &ETSocks, data[1], NULL); + } else if (addrtype != 1 && addrtype != 3 && addrtype != 4) { + SetError(&NetBuf->error, &ETSocks, SEC_ADDRTYPE, NULL); + } else { + retval = TRUE; + replylen = 6; + if (addrtype == 1) + replylen += 4; /* IPv4 address */ + else if (addrtype == 4) + replylen += 16; /* IPv6 address */ + else + replylen += data[4]; /* FQDN */ + data = GetWaitingData(NetBuf, replylen); + if (data) { + NetBuf->status = NBS_CONNECTED; + g_free(data); + NetBufCallBack(NetBuf, FALSE); /* status has changed */ + } + } } - return retval; - } + } + return retval; + } else { + data = GetWaitingData(NetBuf, 8); + if (data) { + retval = FALSE; + if (data[0] != 0) { + SetError(&NetBuf->error, &ETSocks, SEC_REPLYVERSION, NULL); + } else { + if (data[1] == 90) { + NetBuf->status = NBS_CONNECTED; + NetBufCallBack(NetBuf, FALSE); /* status has changed */ + retval = TRUE; + } else if (data[1] >= SEC_REJECT && data[1] <= SEC_IDMISMATCH) { + SetError(&NetBuf->error, &ETSocks, data[1], NULL); + } else { + SetError(&NetBuf->error, &ETSocks, SEC_UNKNOWN, NULL); + } + } + g_free(data); + } + return retval; + } } -static gboolean DoNetworkBufferStuff(NetworkBuffer *NetBuf,gboolean ReadReady, - gboolean WriteReady,gboolean ErrorReady, - gboolean *ReadOK,gboolean *WriteOK, - gboolean *ErrorOK) { -/* Reads and writes data if the network connection is ready. Sets the */ -/* various OK variables to TRUE if no errors occurred in the relevant */ -/* operations, and returns TRUE if data was read and is waiting for */ -/* processing. */ - gboolean DataWaiting=FALSE,ConnectDone=FALSE; - gboolean retval; - *ReadOK=*WriteOK=*ErrorOK=TRUE; - - if (ErrorReady || NetBuf->error) *ErrorOK=FALSE; - else if (NetBuf->WaitConnect) { - if (WriteReady) { - retval=FinishConnect(NetBuf->fd,&NetBuf->error); - ConnectDone=TRUE; - NetBuf->WaitConnect=FALSE; - - if (retval) { - if (NetBuf->socks) { - NetBuf->status = NBS_SOCKSCONNECT; - NetBuf->sockstat = NBSS_METHODS; - } else { - NetBuf->status = NBS_CONNECTED; - } - } else { - NetBuf->status = NBS_PRECONNECT; - *WriteOK=FALSE; - } +/* + * Reads and writes data if the network connection is ready. Sets the + * various OK variables to TRUE if no errors occurred in the relevant + * operations, and returns TRUE if data was read and is waiting for + * processing. + */ +static gboolean DoNetworkBufferStuff(NetworkBuffer *NetBuf, + gboolean ReadReady, + gboolean WriteReady, + gboolean ErrorReady, gboolean *ReadOK, + gboolean *WriteOK, gboolean *ErrorOK) +{ + gboolean DataWaiting = FALSE, ConnectDone = FALSE; + gboolean retval; + + *ReadOK = *WriteOK = *ErrorOK = TRUE; + + if (ErrorReady || NetBuf->error) + *ErrorOK = FALSE; + else if (NetBuf->WaitConnect) { + if (WriteReady) { + retval = FinishConnect(NetBuf->fd, &NetBuf->error); + ConnectDone = TRUE; + NetBuf->WaitConnect = FALSE; + + if (retval) { + if (NetBuf->socks) { + NetBuf->status = NBS_SOCKSCONNECT; + NetBuf->sockstat = NBSS_METHODS; + } else { + NetBuf->status = NBS_CONNECTED; + } + } else { + NetBuf->status = NBS_PRECONNECT; + *WriteOK = FALSE; + } + } + } else { + if (WriteReady) + *WriteOK = WriteDataToWire(NetBuf); + + if (ReadReady) { + *ReadOK = ReadDataFromWire(NetBuf); + if (NetBuf->ReadBuf.DataPresent > 0 && + NetBuf->status == NBS_SOCKSCONNECT) { + if (!HandleSocksReply(NetBuf) + || NetBuf->error) { /* From SendSocks5UserPasswd, possibly */ + *ErrorOK = FALSE; + } } - } else { - if (WriteReady) *WriteOK=WriteDataToWire(NetBuf); - - if (ReadReady) { - *ReadOK=ReadDataFromWire(NetBuf); - if (NetBuf->ReadBuf.DataPresent>0 && - NetBuf->status==NBS_SOCKSCONNECT) { - if (!HandleSocksReply(NetBuf) - || NetBuf->error) { /* From SendSocks5UserPasswd, possibly */ - *ErrorOK=FALSE; - } - } - if (NetBuf->ReadBuf.DataPresent>0 && - NetBuf->status!=NBS_SOCKSCONNECT) { - DataWaiting=TRUE; - } + if (NetBuf->ReadBuf.DataPresent > 0 && + NetBuf->status != NBS_SOCKSCONNECT) { + DataWaiting = TRUE; } - } - - if (!(*ErrorOK && *WriteOK && *ReadOK)) { -/* We don't want to check the socket any more */ - NetBufCallBackStop(NetBuf); -/* If there were errors, then the socket is now useless - so close it */ - CloseSocket(NetBuf->fd); - NetBuf->fd=-1; - } else if (ConnectDone) { -/* If we just connected, then no need to listen for write-ready status - any more */ - NetBufCallBack(NetBuf,FALSE); - } else if (WriteReady && - ((NetBuf->status==NBS_CONNECTED && - NetBuf->WriteBuf.DataPresent==0) || - (NetBuf->status==NBS_SOCKSCONNECT && - NetBuf->negbuf.DataPresent==0))) { -/* If we wrote out everything, then tell the owner so that the socket no - longer needs to be checked for write-ready status */ - NetBufCallBack(NetBuf,FALSE); - } - - return DataWaiting; + } + } + + if (!(*ErrorOK && *WriteOK && *ReadOK)) { + /* We don't want to check the socket any more */ + NetBufCallBackStop(NetBuf); + /* If there were errors, then the socket is now useless - so close it */ + CloseSocket(NetBuf->fd); + NetBuf->fd = -1; + } else if (ConnectDone) { + /* If we just connected, then no need to listen for write-ready status + * any more */ + NetBufCallBack(NetBuf, FALSE); + } else if (WriteReady + && ((NetBuf->status == NBS_CONNECTED + && NetBuf->WriteBuf.DataPresent == 0) + || (NetBuf->status == NBS_SOCKSCONNECT + && NetBuf->negbuf.DataPresent == 0))) { + /* If we wrote out everything, then tell the owner so that the socket + * no longer needs to be checked for write-ready status */ + NetBufCallBack(NetBuf, FALSE); + } + + return DataWaiting; } -gboolean RespondToSelect(NetworkBuffer *NetBuf,fd_set *readfds, - fd_set *writefds,fd_set *errorfds, - gboolean *DoneOK) { -/* Responds to a select() call by reading/writing data as necessary. */ -/* If any data were read, TRUE is returned. "DoneOK" is set TRUE */ -/* unless a fatal error (i.e. the connection was broken) occurred. */ - gboolean ReadOK,WriteOK,ErrorOK; - gboolean DataWaiting=FALSE; - - *DoneOK=TRUE; - if (!NetBuf || NetBuf->fd<=0) return DataWaiting; - DataWaiting=DoNetworkBufferStuff(NetBuf,FD_ISSET(NetBuf->fd,readfds), - FD_ISSET(NetBuf->fd,writefds), - errorfds ? FD_ISSET(NetBuf->fd,errorfds) : FALSE, - &ReadOK,&WriteOK,&ErrorOK); - *DoneOK=(WriteOK && ErrorOK && ReadOK); - return DataWaiting; +/* + * Responds to a select() call by reading/writing data as necessary. + * If any data were read, TRUE is returned. "DoneOK" is set TRUE + * unless a fatal error (i.e. the connection was broken) occurred. + */ +gboolean RespondToSelect(NetworkBuffer *NetBuf, fd_set *readfds, + fd_set *writefds, fd_set *errorfds, + gboolean *DoneOK) +{ + gboolean ReadOK, WriteOK, ErrorOK; + gboolean DataWaiting = FALSE; + + *DoneOK = TRUE; + if (!NetBuf || NetBuf->fd <= 0) + return DataWaiting; + DataWaiting = DoNetworkBufferStuff(NetBuf, FD_ISSET(NetBuf->fd, readfds), + FD_ISSET(NetBuf->fd, writefds), + errorfds ? FD_ISSET(NetBuf->fd, + errorfds) : FALSE, + &ReadOK, &WriteOK, &ErrorOK); + *DoneOK = (WriteOK && ErrorOK && ReadOK); + return DataWaiting; } -gboolean NetBufHandleNetwork(NetworkBuffer *NetBuf,gboolean ReadReady, - gboolean WriteReady,gboolean *DoneOK) { - gboolean ReadOK,WriteOK,ErrorOK; - gboolean DataWaiting=FALSE; +gboolean NetBufHandleNetwork(NetworkBuffer *NetBuf, gboolean ReadReady, + gboolean WriteReady, gboolean *DoneOK) +{ + gboolean ReadOK, WriteOK, ErrorOK; + gboolean DataWaiting = FALSE; - *DoneOK=TRUE; - if (!NetBuf || NetBuf->fd<=0) return DataWaiting; + *DoneOK = TRUE; + if (!NetBuf || NetBuf->fd <= 0) + return DataWaiting; - DataWaiting=DoNetworkBufferStuff(NetBuf,ReadReady,WriteReady,FALSE, - &ReadOK,&WriteOK,&ErrorOK); + DataWaiting = DoNetworkBufferStuff(NetBuf, ReadReady, WriteReady, FALSE, + &ReadOK, &WriteOK, &ErrorOK); - *DoneOK=(WriteOK && ErrorOK && ReadOK); - return DataWaiting; + *DoneOK = (WriteOK && ErrorOK && ReadOK); + return DataWaiting; } -gint CountWaitingMessages(NetworkBuffer *NetBuf) { -/* Returns the number of complete (terminated) messages waiting in the */ -/* given network buffer. This is the number of times that */ -/* GetWaitingMessage() can be safely called without it returning NULL. */ - ConnBuf *conn; - gint i,msgs=0; - - if (NetBuf->status!=NBS_CONNECTED) return 0; +/* + * Returns the number of complete (terminated) messages waiting in the + * given network buffer. This is the number of times that + * GetWaitingMessage() can be safely called without it returning NULL. + */ +gint CountWaitingMessages(NetworkBuffer *NetBuf) +{ + ConnBuf *conn; + gint i, msgs = 0; + + if (NetBuf->status != NBS_CONNECTED) + return 0; + + conn = &NetBuf->ReadBuf; + + if (conn->Data) + for (i = 0; i < conn->DataPresent; i++) { + if (conn->Data[i] == NetBuf->Terminator) + msgs++; + } + return msgs; +} - conn=&NetBuf->ReadBuf; +gchar *PeekWaitingData(NetworkBuffer *NetBuf, int numbytes) +{ + ConnBuf *conn; - if (conn->Data) for (i=0;i<conn->DataPresent;i++) { - if (conn->Data[i]==NetBuf->Terminator) msgs++; - } - return msgs; + conn = &NetBuf->ReadBuf; + if (!conn->Data || conn->DataPresent < numbytes) + return NULL; + else + return conn->Data; } -gchar *PeekWaitingData(NetworkBuffer *NetBuf,int numbytes) { - ConnBuf *conn; - conn=&NetBuf->ReadBuf; - if (!conn->Data || conn->DataPresent < numbytes) return NULL; - else return conn->Data; -} +gchar *GetWaitingData(NetworkBuffer *NetBuf, int numbytes) +{ + ConnBuf *conn; + gchar *data; -gchar *GetWaitingData(NetworkBuffer *NetBuf,int numbytes) { - ConnBuf *conn; - gchar *data; - conn=&NetBuf->ReadBuf; - if (!conn->Data || conn->DataPresent < numbytes) return NULL; + conn = &NetBuf->ReadBuf; + if (!conn->Data || conn->DataPresent < numbytes) + return NULL; - data = g_new(gchar,numbytes); - memcpy(data,conn->Data,numbytes); + data = g_new(gchar, numbytes); + memcpy(data, conn->Data, numbytes); - memmove(&conn->Data[0],&conn->Data[numbytes],conn->DataPresent-numbytes); - conn->DataPresent-=numbytes; + memmove(&conn->Data[0], &conn->Data[numbytes], + conn->DataPresent - numbytes); + conn->DataPresent -= numbytes; - return data; + return data; } -gchar *GetWaitingMessage(NetworkBuffer *NetBuf) { -/* Reads a complete (terminated) message from the network buffer. The */ -/* message is removed from the buffer, and returned as a null-terminated */ -/* string (the network terminator is removed). If no complete message is */ -/* waiting, NULL is returned. The string is dynamically allocated, and */ -/* so must be g_free'd by the caller. */ - ConnBuf *conn; - int MessageLen; - char *SepPt; - gchar *NewMessage; - conn=&NetBuf->ReadBuf; - if (!conn->Data || !conn->DataPresent || NetBuf->status!=NBS_CONNECTED) { - return NULL; - } - SepPt=memchr(conn->Data,NetBuf->Terminator,conn->DataPresent); - if (!SepPt) return NULL; - *SepPt='\0'; - MessageLen=SepPt-conn->Data+1; - SepPt--; - if (NetBuf->StripChar && *SepPt==NetBuf->StripChar) *SepPt='\0'; - NewMessage=g_new(gchar,MessageLen); - memcpy(NewMessage,conn->Data,MessageLen); - if (MessageLen<conn->DataPresent) { - memmove(&conn->Data[0],&conn->Data[MessageLen], - conn->DataPresent-MessageLen); - } - conn->DataPresent-=MessageLen; - return NewMessage; +/* + * Reads a complete (terminated) message from the network buffer. The + * message is removed from the buffer, and returned as a null-terminated + * string (the network terminator is removed). If no complete message is + * waiting, NULL is returned. The string is dynamically allocated, and + * so must be g_free'd by the caller. + */ +gchar *GetWaitingMessage(NetworkBuffer *NetBuf) +{ + ConnBuf *conn; + int MessageLen; + char *SepPt; + gchar *NewMessage; + + conn = &NetBuf->ReadBuf; + if (!conn->Data || !conn->DataPresent || NetBuf->status != NBS_CONNECTED) { + return NULL; + } + SepPt = memchr(conn->Data, NetBuf->Terminator, conn->DataPresent); + if (!SepPt) + return NULL; + *SepPt = '\0'; + MessageLen = SepPt - conn->Data + 1; + SepPt--; + if (NetBuf->StripChar && *SepPt == NetBuf->StripChar) + *SepPt = '\0'; + NewMessage = g_new(gchar, MessageLen); + + memcpy(NewMessage, conn->Data, MessageLen); + if (MessageLen < conn->DataPresent) { + memmove(&conn->Data[0], &conn->Data[MessageLen], + conn->DataPresent - MessageLen); + } + conn->DataPresent -= MessageLen; + return NewMessage; } -gboolean ReadDataFromWire(NetworkBuffer *NetBuf) { -/* Reads any waiting data on the given network buffer's TCP/IP connection */ -/* into the read buffer. Returns FALSE if the connection was closed, or */ -/* if the read buffer's maximum size was reached. */ - ConnBuf *conn; - int CurrentPosition,BytesRead; - conn=&NetBuf->ReadBuf; - CurrentPosition=conn->DataPresent; - while(1) { - if (CurrentPosition>=conn->Length) { - if (conn->Length==MAXREADBUF) { - SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF,NULL); - return FALSE; /* drop connection */ - } - if (conn->Length==0) conn->Length=256; else conn->Length*=2; - if (conn->Length>MAXREADBUF) conn->Length=MAXREADBUF; - conn->Data=g_realloc(conn->Data,conn->Length); +/* + * Reads any waiting data on the given network buffer's TCP/IP connection + * into the read buffer. Returns FALSE if the connection was closed, or + * if the read buffer's maximum size was reached. + */ +gboolean ReadDataFromWire(NetworkBuffer *NetBuf) +{ + ConnBuf *conn; + int CurrentPosition, BytesRead; + + conn = &NetBuf->ReadBuf; + CurrentPosition = conn->DataPresent; + while (1) { + if (CurrentPosition >= conn->Length) { + if (conn->Length == MAXREADBUF) { + SetError(&NetBuf->error, ET_CUSTOM, E_FULLBUF, NULL); + return FALSE; /* drop connection */ } - BytesRead=recv(NetBuf->fd,&conn->Data[CurrentPosition], - conn->Length-CurrentPosition,0); - if (BytesRead==SOCKET_ERROR) { + if (conn->Length == 0) + conn->Length = 256; + else + conn->Length *= 2; + if (conn->Length > MAXREADBUF) + conn->Length = MAXREADBUF; + conn->Data = g_realloc(conn->Data, conn->Length); + } + BytesRead = recv(NetBuf->fd, &conn->Data[CurrentPosition], + conn->Length - CurrentPosition, 0); + if (BytesRead == SOCKET_ERROR) { #ifdef CYGWIN - int Error = WSAGetLastError(); - if (Error==WSAEWOULDBLOCK) break; - else { SetError(&NetBuf->error,ET_WINSOCK,Error,NULL); return FALSE; } + int Error = WSAGetLastError(); + + if (Error == WSAEWOULDBLOCK) + break; + else { + SetError(&NetBuf->error, ET_WINSOCK, Error, NULL); + return FALSE; + } #else - if (errno==EAGAIN) break; - else if (errno!=EINTR) { - SetError(&NetBuf->error,ET_ERRNO,errno,NULL); - return FALSE; - } -#endif - } else if (BytesRead==0) { - return FALSE; - } else { - CurrentPosition+=BytesRead; - conn->DataPresent=CurrentPosition; + if (errno == EAGAIN) + break; + else if (errno != EINTR) { + SetError(&NetBuf->error, ET_ERRNO, errno, NULL); + return FALSE; } - } - return TRUE; +#endif + } else if (BytesRead == 0) { + return FALSE; + } else { + CurrentPosition += BytesRead; + conn->DataPresent = CurrentPosition; + } + } + return TRUE; } -gchar *ExpandWriteBuffer(ConnBuf *conn,int numbytes,LastError **error) { +gchar *ExpandWriteBuffer(ConnBuf *conn, int numbytes, LastError **error) +{ int newlen; + newlen = conn->DataPresent + numbytes; if (newlen > conn->Length) { - conn->Length*=2; - conn->Length=MAX(conn->Length,newlen); - if (conn->Length > MAXWRITEBUF) conn->Length=MAXWRITEBUF; + conn->Length *= 2; + conn->Length = MAX(conn->Length, newlen); + if (conn->Length > MAXWRITEBUF) + conn->Length = MAXWRITEBUF; if (newlen > conn->Length) { - if (error) SetError(error,ET_CUSTOM,E_FULLBUF,NULL); + if (error) + SetError(error, ET_CUSTOM, E_FULLBUF, NULL); return NULL; } - conn->Data=g_realloc(conn->Data,conn->Length); + conn->Data = g_realloc(conn->Data, conn->Length); } return (&conn->Data[conn->DataPresent]); } -void CommitWriteBuffer(NetworkBuffer *NetBuf,ConnBuf *conn, - gchar *addpt,guint addlen) { - conn->DataPresent+=addlen; +void CommitWriteBuffer(NetworkBuffer *NetBuf, ConnBuf *conn, + gchar *addpt, guint addlen) +{ + conn->DataPresent += addlen; -/* If the buffer was empty before, we may need to tell the owner to check - the socket for write-ready status */ - if (NetBuf && addpt==conn->Data) NetBufCallBack(NetBuf,FALSE); + /* If the buffer was empty before, we may need to tell the owner to + * check the socket for write-ready status */ + if (NetBuf && addpt == conn->Data) + NetBufCallBack(NetBuf, FALSE); } -void QueueMessageForSend(NetworkBuffer *NetBuf,gchar *data) { -/* Writes the null-terminated string "data" to the network buffer, ready */ -/* to be sent to the wire when the network connection becomes free. The */ -/* message is automatically terminated. Fails to write the message without */ -/* error if the buffer reaches its maximum size (although this error will */ -/* be detected when an attempt is made to write the buffer to the wire). */ - gchar *addpt; - guint addlen; - ConnBuf *conn; - conn=&NetBuf->WriteBuf; - - if (!data) return; - addlen = strlen(data)+1; - addpt = ExpandWriteBuffer(conn,addlen,NULL); - if (!addpt) return; - - memcpy(addpt,data,addlen); - addpt[addlen-1]=NetBuf->Terminator; - - CommitWriteBuffer(NetBuf,conn,addpt,addlen); +/* + * Writes the null-terminated string "data" to the network buffer, ready + * to be sent to the wire when the network connection becomes free. The + * message is automatically terminated. Fails to write the message without + * error if the buffer reaches its maximum size (although this error will + * be detected when an attempt is made to write the buffer to the wire). + */ +void QueueMessageForSend(NetworkBuffer *NetBuf, gchar *data) +{ + gchar *addpt; + guint addlen; + ConnBuf *conn; + + conn = &NetBuf->WriteBuf; + + if (!data) + return; + addlen = strlen(data) + 1; + addpt = ExpandWriteBuffer(conn, addlen, NULL); + if (!addpt) + return; + + memcpy(addpt, data, addlen); + addpt[addlen - 1] = NetBuf->Terminator; + + CommitWriteBuffer(NetBuf, conn, addpt, addlen); } -static struct hostent *LookupHostname(gchar *host,LastError **error) { - struct hostent *he; - if ((he=gethostbyname(host))==NULL) { +static struct hostent *LookupHostname(gchar *host, LastError **error) +{ + struct hostent *he; + + if ((he = gethostbyname(host)) == NULL) { #ifdef CYGWIN - if (error) SetError(error,ET_WINSOCK,WSAGetLastError(),NULL); + if (error) + SetError(error, ET_WINSOCK, WSAGetLastError(), NULL); #else - if (error) SetError(error,ET_HERRNO,h_errno,NULL); + if (error) + SetError(error, ET_HERRNO, h_errno, NULL); #endif - } - return he; + } + return he; } -gboolean StartSocksNegotiation(NetworkBuffer *NetBuf,gchar *RemoteHost, - unsigned RemotePort) { - guint num_methods; - ConnBuf *conn; - struct hostent *he; - guchar *addpt; - guint addlen,i; - struct in_addr *haddr; - unsigned short int netport; - gchar *username=NULL; +gboolean StartSocksNegotiation(NetworkBuffer *NetBuf, gchar *RemoteHost, + unsigned RemotePort) +{ + guint num_methods; + ConnBuf *conn; + struct hostent *he; + guchar *addpt; + guint addlen, i; + struct in_addr *haddr; + unsigned short int netport; + gchar *username = NULL; + #ifdef CYGWIN - DWORD bufsize; + DWORD bufsize; #else - struct passwd *pwd; + struct passwd *pwd; #endif - conn=&NetBuf->negbuf; + conn = &NetBuf->negbuf; - if (NetBuf->socks->version==5) { - num_methods=1; - if (NetBuf->userpasswd) num_methods++; - addlen=2+num_methods; - addpt = ExpandWriteBuffer(conn,addlen,&NetBuf->error); - if (!addpt) return FALSE; - addpt[0] = 5; /* SOCKS version 5 */ - addpt[1] = num_methods; - i=2; - addpt[i++] = SM_NOAUTH; - if (NetBuf->userpasswd) addpt[i++] = SM_USERPASSWD; + if (NetBuf->socks->version == 5) { + num_methods = 1; + if (NetBuf->userpasswd) + num_methods++; + addlen = 2 + num_methods; + addpt = ExpandWriteBuffer(conn, addlen, &NetBuf->error); + if (!addpt) + return FALSE; + addpt[0] = 5; /* SOCKS version 5 */ + addpt[1] = num_methods; + i = 2; + addpt[i++] = SM_NOAUTH; + if (NetBuf->userpasswd) + addpt[i++] = SM_USERPASSWD; - g_free(NetBuf->host); - NetBuf->host = g_strdup(RemoteHost); - NetBuf->port = RemotePort; + g_free(NetBuf->host); + NetBuf->host = g_strdup(RemoteHost); + NetBuf->port = RemotePort; - CommitWriteBuffer(NetBuf,conn,addpt,addlen); + CommitWriteBuffer(NetBuf, conn, addpt, addlen); - return TRUE; - } + return TRUE; + } - he = LookupHostname(RemoteHost,&NetBuf->error); - if (!he) return FALSE; + he = LookupHostname(RemoteHost, &NetBuf->error); + if (!he) + return FALSE; - if (NetBuf->socks->user && NetBuf->socks->user[0]) { - username = g_strdup(NetBuf->socks->user); - } else { + if (NetBuf->socks->user && NetBuf->socks->user[0]) { + username = g_strdup(NetBuf->socks->user); + } else { #ifdef CYGWIN - bufsize=0; - WNetGetUser(NULL,username,&bufsize); - if (GetLastError()!=ERROR_MORE_DATA) { - SetError(&NetBuf->error,ET_WIN32,GetLastError(),NULL); - return FALSE; - } else { - username=g_malloc(bufsize); - if (WNetGetUser(NULL,username,&bufsize)!=NO_ERROR) { - SetError(&NetBuf->error,ET_WIN32,GetLastError(),NULL); - return FALSE; - } - } + bufsize = 0; + WNetGetUser(NULL, username, &bufsize); + if (GetLastError() != ERROR_MORE_DATA) { + SetError(&NetBuf->error, ET_WIN32, GetLastError(), NULL); + return FALSE; + } else { + username = g_malloc(bufsize); + if (WNetGetUser(NULL, username, &bufsize) != NO_ERROR) { + SetError(&NetBuf->error, ET_WIN32, GetLastError(), NULL); + return FALSE; + } + } #else - if (NetBuf->socks->numuid) { - username=g_strdup_printf("%d",getuid()); - } else { - pwd = getpwuid(getuid()); - if (!pwd || !pwd->pw_name) return FALSE; - username=g_strdup(pwd->pw_name); - } + if (NetBuf->socks->numuid) { + username = g_strdup_printf("%d", getuid()); + } else { + pwd = getpwuid(getuid()); + if (!pwd || !pwd->pw_name) + return FALSE; + username = g_strdup(pwd->pw_name); + } #endif - } - addlen=9+strlen(username); + } + addlen = 9 + strlen(username); - haddr = (struct in_addr *)he->h_addr; - g_assert(sizeof(struct in_addr)==4); + haddr = (struct in_addr *)he->h_addr; + g_assert(sizeof(struct in_addr) == 4); - netport = htons(RemotePort); - g_assert(sizeof(netport)==2); + netport = htons(RemotePort); + g_assert(sizeof(netport) == 2); - addpt = ExpandWriteBuffer(conn,addlen,&NetBuf->error); - if (!addpt) return FALSE; + addpt = ExpandWriteBuffer(conn, addlen, &NetBuf->error); + if (!addpt) + return FALSE; - addpt[0] = 4; /* SOCKS version */ - addpt[1] = 1; /* CONNECT */ - memcpy(&addpt[2],&netport,sizeof(netport)); - memcpy(&addpt[4],haddr,sizeof(struct in_addr)); - strcpy(&addpt[8],username); - g_free(username); - addpt[addlen-1] = '\0'; + addpt[0] = 4; /* SOCKS version */ + addpt[1] = 1; /* CONNECT */ + memcpy(&addpt[2], &netport, sizeof(netport)); + memcpy(&addpt[4], haddr, sizeof(struct in_addr)); + strcpy(&addpt[8], username); + g_free(username); + addpt[addlen - 1] = '\0'; - CommitWriteBuffer(NetBuf,conn,addpt,addlen); + CommitWriteBuffer(NetBuf, conn, addpt, addlen); - return TRUE; + return TRUE; } -static gboolean WriteBufToWire(NetworkBuffer *NetBuf,ConnBuf *conn) { - int CurrentPosition,BytesSent; - if (!conn->Data || !conn->DataPresent) return TRUE; - if (conn->Length==MAXWRITEBUF) { - SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF,NULL); - return FALSE; - } - CurrentPosition=0; - while (CurrentPosition<conn->DataPresent) { - BytesSent=send(NetBuf->fd,&conn->Data[CurrentPosition], - conn->DataPresent-CurrentPosition,0); - if (BytesSent==SOCKET_ERROR) { +static gboolean WriteBufToWire(NetworkBuffer *NetBuf, ConnBuf *conn) +{ + int CurrentPosition, BytesSent; + + if (!conn->Data || !conn->DataPresent) + return TRUE; + if (conn->Length == MAXWRITEBUF) { + SetError(&NetBuf->error, ET_CUSTOM, E_FULLBUF, NULL); + return FALSE; + } + CurrentPosition = 0; + while (CurrentPosition < conn->DataPresent) { + BytesSent = send(NetBuf->fd, &conn->Data[CurrentPosition], + conn->DataPresent - CurrentPosition, 0); + if (BytesSent == SOCKET_ERROR) { #ifdef CYGWIN - int Error=WSAGetLastError(); - if (Error==WSAEWOULDBLOCK) break; - else { SetError(&NetBuf->error,ET_WINSOCK,Error,NULL); return FALSE; } + int Error = WSAGetLastError(); + + if (Error == WSAEWOULDBLOCK) + break; + else { + SetError(&NetBuf->error, ET_WINSOCK, Error, NULL); + return FALSE; + } #else - if (errno==EAGAIN) break; - else if (errno!=EINTR) { - SetError(&NetBuf->error,ET_ERRNO,errno,NULL); - return FALSE; - } -#endif - } else { - CurrentPosition+=BytesSent; + if (errno == EAGAIN) + break; + else if (errno != EINTR) { + SetError(&NetBuf->error, ET_ERRNO, errno, NULL); + return FALSE; } - } - if (CurrentPosition>0 && CurrentPosition<conn->DataPresent) { - memmove(&conn->Data[0],&conn->Data[CurrentPosition], - conn->DataPresent-CurrentPosition); - } - conn->DataPresent-=CurrentPosition; - return TRUE; +#endif + } else { + CurrentPosition += BytesSent; + } + } + if (CurrentPosition > 0 && CurrentPosition < conn->DataPresent) { + memmove(&conn->Data[0], &conn->Data[CurrentPosition], + conn->DataPresent - CurrentPosition); + } + conn->DataPresent -= CurrentPosition; + return TRUE; } -gboolean WriteDataToWire(NetworkBuffer *NetBuf) { -/* Writes any waiting data in the network buffer to the wire. Returns */ -/* TRUE on success, or FALSE if the buffer's maximum length is */ -/* reached, or the remote end has closed the connection. */ - if (NetBuf->status==NBS_SOCKSCONNECT) { - return WriteBufToWire(NetBuf,&NetBuf->negbuf); - } else { - return WriteBufToWire(NetBuf,&NetBuf->WriteBuf); - } +/* + * Writes any waiting data in the network buffer to the wire. Returns + * TRUE on success, or FALSE if the buffer's maximum length is + * reached, or the remote end has closed the connection. + */ +gboolean WriteDataToWire(NetworkBuffer *NetBuf) +{ + if (NetBuf->status == NBS_SOCKSCONNECT) { + return WriteBufToWire(NetBuf, &NetBuf->negbuf); + } else { + return WriteBufToWire(NetBuf, &NetBuf->WriteBuf); + } } -static void SendHttpRequest(HttpConnection *conn) { - GString *text; - char *userpasswd; +static void SendHttpRequest(HttpConnection *conn) +{ + GString *text; + char *userpasswd; - conn->Tries++; - conn->StatusCode=0; - conn->Status=HS_CONNECTING; + conn->Tries++; + conn->StatusCode = 0; + conn->Status = HS_CONNECTING; - text=g_string_new(""); + text = g_string_new(""); - g_string_sprintf(text,"%s http://%s:%u%s HTTP/1.0", - conn->Method,conn->HostName,conn->Port,conn->Query); - QueueMessageForSend(&conn->NetBuf,text->str); + g_string_sprintf(text, "%s http://%s:%u%s HTTP/1.0", + conn->Method, conn->HostName, conn->Port, conn->Query); + QueueMessageForSend(&conn->NetBuf, text->str); - if (conn->Headers) QueueMessageForSend(&conn->NetBuf,conn->Headers); + if (conn->Headers) + QueueMessageForSend(&conn->NetBuf, conn->Headers); - if (conn->user && conn->password) { - userpasswd = g_strdup_printf("%s:%s",conn->user,conn->password); - g_string_assign(text,"Authorization: Basic "); - AddB64Enc(text,userpasswd); - g_free(userpasswd); - QueueMessageForSend(&conn->NetBuf,text->str); - } - if (conn->proxyuser && conn->proxypassword) { - userpasswd = g_strdup_printf("%s:%s",conn->proxyuser,conn->proxypassword); - g_string_assign(text,"Proxy-Authenticate: Basic "); - AddB64Enc(text,userpasswd); - g_free(userpasswd); - QueueMessageForSend(&conn->NetBuf,text->str); - } + if (conn->user && conn->password) { + userpasswd = g_strdup_printf("%s:%s", conn->user, conn->password); + g_string_assign(text, "Authorization: Basic "); + AddB64Enc(text, userpasswd); + g_free(userpasswd); + QueueMessageForSend(&conn->NetBuf, text->str); + } + if (conn->proxyuser && conn->proxypassword) { + userpasswd = + g_strdup_printf("%s:%s", conn->proxyuser, conn->proxypassword); + g_string_assign(text, "Proxy-Authenticate: Basic "); + AddB64Enc(text, userpasswd); + g_free(userpasswd); + QueueMessageForSend(&conn->NetBuf, text->str); + } - g_string_sprintf(text,"User-Agent: dopewars/%s",VERSION); - QueueMessageForSend(&conn->NetBuf,text->str); + g_string_sprintf(text, "User-Agent: dopewars/%s", VERSION); + QueueMessageForSend(&conn->NetBuf, text->str); -/* Insert a blank line between headers and body */ - QueueMessageForSend(&conn->NetBuf,""); + /* Insert a blank line between headers and body */ + QueueMessageForSend(&conn->NetBuf, ""); - if (conn->Body) QueueMessageForSend(&conn->NetBuf,conn->Body); + if (conn->Body) + QueueMessageForSend(&conn->NetBuf, conn->Body); - g_string_free(text,TRUE); + g_string_free(text, TRUE); } -static gboolean StartHttpConnect(HttpConnection *conn) { - gchar *ConnectHost; - unsigned ConnectPort; - - if (conn->Proxy) { - ConnectHost=conn->Proxy; ConnectPort=conn->ProxyPort; - } else { - ConnectHost=conn->HostName; ConnectPort=conn->Port; - } - - if (!StartNetworkBufferConnect(&conn->NetBuf,ConnectHost,ConnectPort)) { - return FALSE; - } - return TRUE; -} +static gboolean StartHttpConnect(HttpConnection *conn) +{ + gchar *ConnectHost; + unsigned ConnectPort; -gboolean OpenHttpConnection(HttpConnection **connpt,gchar *HostName, - unsigned Port,gchar *Proxy,unsigned ProxyPort, - SocksServer *socks, - gchar *Method,gchar *Query, - gchar *Headers,gchar *Body) { - HttpConnection *conn; - g_assert(HostName && Method && Query && connpt); - - conn=g_new0(HttpConnection,1); - InitNetworkBuffer(&conn->NetBuf,'\n','\r',socks); - conn->HostName=g_strdup(HostName); - if (Proxy && Proxy[0]) conn->Proxy=g_strdup(Proxy); - conn->Method=g_strdup(Method); - conn->Query=g_strdup(Query); - if (Headers && Headers[0]) conn->Headers=g_strdup(Headers); - if (Body && Body[0]) conn->Body=g_strdup(Body); - conn->Port = Port; - conn->ProxyPort = ProxyPort; - *connpt = conn; - - if (StartHttpConnect(conn)) { - SendHttpRequest(conn); - return TRUE; - } else { - return FALSE; - } -} + if (conn->Proxy) { + ConnectHost = conn->Proxy; + ConnectPort = conn->ProxyPort; + } else { + ConnectHost = conn->HostName; + ConnectPort = conn->Port; + } -void CloseHttpConnection(HttpConnection *conn) { - ShutdownNetworkBuffer(&conn->NetBuf); - g_free(conn->HostName); - g_free(conn->Proxy); - g_free(conn->Method); - g_free(conn->Query); - g_free(conn->Headers); - g_free(conn->Body); - g_free(conn->RedirHost); - g_free(conn->RedirQuery); - g_free(conn->user); - g_free(conn->password); - g_free(conn->proxyuser); - g_free(conn->proxypassword); - g_free(conn); + if (!StartNetworkBufferConnect(&conn->NetBuf, ConnectHost, ConnectPort)) { + return FALSE; + } + return TRUE; } -void SetHttpAuthentication(HttpConnection *conn,gboolean proxy, - gchar *user,gchar *password) { - gchar **ptuser,**ptpassword; - g_assert(conn); - if (proxy) { - ptuser=&conn->proxyuser; ptpassword=&conn->proxypassword; - } else { - ptuser=&conn->user; ptpassword=&conn->password; - } - g_free(*ptuser); g_free(*ptpassword); - if (user && password && user[0] && password[0]) { - *ptuser = g_strdup(user); - *ptpassword = g_strdup(password); - } else { - *ptuser = *ptpassword = NULL; - } - conn->waitinput=FALSE; - if (conn->Status==HS_WAITCOMPLETE) { - NetBufCallBack(&conn->NetBuf,TRUE); - } +gboolean OpenHttpConnection(HttpConnection **connpt, gchar *HostName, + unsigned Port, gchar *Proxy, + unsigned ProxyPort, SocksServer *socks, + gchar *Method, gchar *Query, gchar *Headers, + gchar *Body) +{ + HttpConnection *conn; + + g_assert(HostName && Method && Query && connpt); + + conn = g_new0(HttpConnection, 1); + + InitNetworkBuffer(&conn->NetBuf, '\n', '\r', socks); + conn->HostName = g_strdup(HostName); + if (Proxy && Proxy[0]) + conn->Proxy = g_strdup(Proxy); + conn->Method = g_strdup(Method); + conn->Query = g_strdup(Query); + if (Headers && Headers[0]) + conn->Headers = g_strdup(Headers); + if (Body && Body[0]) + conn->Body = g_strdup(Body); + conn->Port = Port; + conn->ProxyPort = ProxyPort; + *connpt = conn; + + if (StartHttpConnect(conn)) { + SendHttpRequest(conn); + return TRUE; + } else { + return FALSE; + } } -void SetHttpAuthFunc(HttpConnection *conn,HCAuthFunc authfunc,gpointer data) { - g_assert(conn && authfunc); - conn->authfunc = authfunc; - conn->authdata = data; +void CloseHttpConnection(HttpConnection *conn) +{ + ShutdownNetworkBuffer(&conn->NetBuf); + g_free(conn->HostName); + g_free(conn->Proxy); + g_free(conn->Method); + g_free(conn->Query); + g_free(conn->Headers); + g_free(conn->Body); + g_free(conn->RedirHost); + g_free(conn->RedirQuery); + g_free(conn->user); + g_free(conn->password); + g_free(conn->proxyuser); + g_free(conn->proxypassword); + g_free(conn); } -static gboolean ParseHtmlLocation(gchar *uri,gchar **host,unsigned *port, - gchar **query) { - gchar *uris,*colon,*slash; +void SetHttpAuthentication(HttpConnection *conn, gboolean proxy, + gchar *user, gchar *password) +{ + gchar **ptuser, **ptpassword; - uris = g_strstrip(uri); - if (!uris || strlen(uris)<7 || - g_strncasecmp(uris,"http://",7)!=0) return FALSE; + g_assert(conn); + if (proxy) { + ptuser = &conn->proxyuser; + ptpassword = &conn->proxypassword; + } else { + ptuser = &conn->user; + ptpassword = &conn->password; + } + g_free(*ptuser); + g_free(*ptpassword); + if (user && password && user[0] && password[0]) { + *ptuser = g_strdup(user); + *ptpassword = g_strdup(password); + } else { + *ptuser = *ptpassword = NULL; + } + conn->waitinput = FALSE; + if (conn->Status == HS_WAITCOMPLETE) { + NetBufCallBack(&conn->NetBuf, TRUE); + } +} - uris+=7; /* skip to hostname */ +void SetHttpAuthFunc(HttpConnection *conn, HCAuthFunc authfunc, + gpointer data) +{ + g_assert(conn && authfunc); + conn->authfunc = authfunc; + conn->authdata = data; +} -/* ':' denotes the port to connect to */ - colon = strchr(uris,':'); - if (colon && colon==uris) return FALSE; /* No hostname */ +static gboolean ParseHtmlLocation(gchar *uri, gchar **host, unsigned *port, + gchar **query) +{ + gchar *uris, *colon, *slash; -/* '/' denotes the start of the path of the HTML file */ - slash = strchr(uris,'/'); - if (slash && slash==uris) return FALSE; /* No hostname */ + uris = g_strstrip(uri); + if (!uris || strlen(uris) < 7 || g_strncasecmp(uris, "http://", 7) != 0) + return FALSE; - if (colon && (!slash || slash>colon)) { - if (slash) *slash='\0'; - *port = atoi(colon+1); - if (slash) *slash='\\'; - if (*port==0) return FALSE; /* Invalid port */ - *host = g_strndup(uris,colon-uris); + uris += 7; /* skip to hostname */ + + /* ':' denotes the port to connect to */ + colon = strchr(uris, ':'); + if (colon && colon == uris) + return FALSE; /* No hostname */ + + /* '/' denotes the start of the path of the HTML file */ + slash = strchr(uris, '/'); + if (slash && slash == uris) + return FALSE; /* No hostname */ + + if (colon && (!slash || slash > colon)) { + if (slash) + *slash = '\0'; + *port = atoi(colon + 1); + if (slash) + *slash = '\\'; + if (*port == 0) + return FALSE; /* Invalid port */ + *host = g_strndup(uris, colon - uris); } else { - *port=80; - if (slash) *host=g_strndup(uris,slash-uris); - else *host=g_strdup(uris); + *port = 80; + if (slash) + *host = g_strndup(uris, slash - uris); + else + *host = g_strdup(uris); } if (slash) { t@@ -1146,287 +1326,340 @@ static gboolean ParseHtmlLocation(gchar *uri,gchar **host,unsigned *port, return TRUE; } -static void StartHttpAuth(HttpConnection *conn,gboolean proxy,gchar *header, - gboolean *doneOK) { - gchar *realm,**split; +static void StartHttpAuth(HttpConnection *conn, gboolean proxy, + gchar *header, gboolean *doneOK) +{ + gchar *realm, **split; - if (!conn->authfunc) return; + if (!conn->authfunc) + return; - split=g_strsplit(header," ",1); + split = g_strsplit(header, " ", 1); - if (split[0] && split[1] && g_strcasecmp(split[0],"Basic")==0 && - g_strncasecmp(split[1],"realm=",6)==0 && strlen(split[1])>6) { - realm = &split[1][6]; - conn->waitinput=TRUE; - (*conn->authfunc)(conn,proxy,realm,conn->authdata); - } else { - *doneOK=FALSE; - SetError(&conn->NetBuf.error,ÐTTP,HEC_BADAUTH,g_strdup(header)); - } + if (split[0] && split[1] && g_strcasecmp(split[0], "Basic") == 0 && + g_strncasecmp(split[1], "realm=", 6) == 0 && strlen(split[1]) > 6) { + realm = &split[1][6]; + conn->waitinput = TRUE; + (*conn->authfunc) (conn, proxy, realm, conn->authdata); + } else { + *doneOK = FALSE; + SetError(&conn->NetBuf.error, ÐTTP, HEC_BADAUTH, g_strdup(header)); + } - g_strfreev(split); + g_strfreev(split); } -static void ParseHtmlHeader(gchar *line,HttpConnection *conn,gboolean *doneOK) { - gchar **split,*host,*query; +static void ParseHtmlHeader(gchar *line, HttpConnection *conn, + gboolean *doneOK) +{ + gchar **split, *host, *query; unsigned port; - split=g_strsplit(line," ",1); + split = g_strsplit(line, " ", 1); if (split[0] && split[1]) { - if (g_strcasecmp(split[0],"Location:")==0 && - (conn->StatusCode==HEC_MOVETEMP || conn->StatusCode==HEC_MOVEPERM)) { - if (ParseHtmlLocation(split[1],&host,&port,&query)) { - g_free(conn->RedirHost); g_free(conn->RedirQuery); - conn->RedirHost=host; conn->RedirQuery=query; - conn->RedirPort=port; + if (g_strcasecmp(split[0], "Location:") == 0 && + (conn->StatusCode == HEC_MOVETEMP + || conn->StatusCode == HEC_MOVEPERM)) { + if (ParseHtmlLocation(split[1], &host, &port, &query)) { + g_free(conn->RedirHost); + g_free(conn->RedirQuery); + conn->RedirHost = host; + conn->RedirQuery = query; + conn->RedirPort = port; } else { - *doneOK=FALSE; - SetError(&conn->NetBuf.error,ÐTTP,HEC_BADREDIR,g_strdup(line)); + *doneOK = FALSE; + SetError(&conn->NetBuf.error, ÐTTP, HEC_BADREDIR, + g_strdup(line)); } - } else if (g_strcasecmp(split[0],"WWW-Authenticate:")==0 && - conn->StatusCode==HEC_AUTHREQ) { - StartHttpAuth(conn,FALSE,split[1],doneOK); -/* Proxy-Authenticate is, strictly speaking, an HTTP/1.1 thing, but some - HTTP/1.0 proxies seem to support it anyway */ - } else if (g_strcasecmp(split[0],"Proxy-Authenticate:")==0 && - conn->StatusCode==HEC_PROXYAUTH) { - StartHttpAuth(conn,TRUE,split[1],doneOK); + } else if (g_strcasecmp(split[0], "WWW-Authenticate:") == 0 && + conn->StatusCode == HEC_AUTHREQ) { + StartHttpAuth(conn, FALSE, split[1], doneOK); + } else if (g_strcasecmp(split[0], "Proxy-Authenticate:") == 0 && + conn->StatusCode == HEC_PROXYAUTH) { + /* Proxy-Authenticate is, strictly speaking, an HTTP/1.1 thing, but + * some HTTP/1.0 proxies seem to support it anyway */ + StartHttpAuth(conn, TRUE, split[1], doneOK); } } g_strfreev(split); } -gchar *ReadHttpResponse(HttpConnection *conn,gboolean *doneOK) { - gchar *msg,**split; - - msg=GetWaitingMessage(&conn->NetBuf); - if (msg) switch(conn->Status) { - case HS_CONNECTING: /* OK, we should have the HTTP status line */ - conn->Status=HS_READHEADERS; - split=g_strsplit(msg," ",2); - if (split[0] && split[1]) { - conn->StatusCode=atoi(split[1]); - } else { - *doneOK=FALSE; - SetError(&conn->NetBuf.error,ÐTTP,HEC_BADSTATUS,g_strdup(msg)); - } - g_strfreev(split); - break; - case HS_READHEADERS: - if (msg[0]==0) conn->Status=HS_READSEPARATOR; - else ParseHtmlHeader(msg,conn,doneOK); - break; - case HS_READSEPARATOR: - conn->Status=HS_READBODY; - break; - case HS_READBODY: /* At present, we do nothing special with the body */ - break; - case HS_WAITCOMPLETE: /* Well, we shouldn't be here at all... */ - g_free(msg); msg=NULL; - break; - } - return msg; +gchar *ReadHttpResponse(HttpConnection *conn, gboolean *doneOK) +{ + gchar *msg, **split; + + msg = GetWaitingMessage(&conn->NetBuf); + if (msg) + switch (conn->Status) { + case HS_CONNECTING: /* OK, we should have the HTTP status line */ + conn->Status = HS_READHEADERS; + split = g_strsplit(msg, " ", 2); + if (split[0] && split[1]) { + conn->StatusCode = atoi(split[1]); + } else { + *doneOK = FALSE; + SetError(&conn->NetBuf.error, ÐTTP, HEC_BADSTATUS, + g_strdup(msg)); + } + g_strfreev(split); + break; + case HS_READHEADERS: + if (msg[0] == 0) + conn->Status = HS_READSEPARATOR; + else + ParseHtmlHeader(msg, conn, doneOK); + break; + case HS_READSEPARATOR: + conn->Status = HS_READBODY; + break; + case HS_READBODY: /* At present, we do nothing special + * with the body */ + break; + case HS_WAITCOMPLETE: /* Well, we shouldn't be here at all... */ + g_free(msg); + msg = NULL; + break; + } + return msg; } -gboolean HandleHttpCompletion(HttpConnection *conn) { - NBCallBack CallBack; - gpointer CallBackData,userpasswddata; - NBUserPasswd userpasswd; - gboolean retry=FALSE; - LastError **error; +gboolean HandleHttpCompletion(HttpConnection *conn) +{ + NBCallBack CallBack; + gpointer CallBackData, userpasswddata; + NBUserPasswd userpasswd; + gboolean retry = FALSE; + LastError **error; + + error = &conn->NetBuf.error; + + /* If we're still waiting for authentication etc., then signal that the + * connection shouldn't be closed yet, and go into the "WAITCOMPLETE" + * state */ + if (conn->waitinput) { + conn->Status = HS_WAITCOMPLETE; + return FALSE; + } + + if (conn->Tries >= 5) { + SetError(error, ÐTTP, HEC_TRIESEX, NULL); + return TRUE; + } - error=&conn->NetBuf.error; + if (conn->RedirHost) { + g_free(conn->HostName); + g_free(conn->Query); + conn->HostName = conn->RedirHost; + conn->Query = conn->RedirQuery; + conn->Port = conn->RedirPort; + conn->RedirHost = conn->RedirQuery = NULL; + retry = TRUE; + } + if (conn->StatusCode == HEC_AUTHREQ && conn->user && conn->password) { + retry = TRUE; + } + if (conn->StatusCode == HEC_PROXYAUTH && conn->proxyuser && + conn->proxypassword) { + retry = TRUE; + } -/* If we're still waiting for authentication etc., then signal that the - connection shouldn't be closed yet, and go into the "WAITCOMPLETE" state */ - if (conn->waitinput) { - conn->Status = HS_WAITCOMPLETE; + if (retry) { + CallBack = conn->NetBuf.CallBack; + userpasswd = conn->NetBuf.userpasswd; + userpasswddata = conn->NetBuf.userpasswddata; + CallBackData = conn->NetBuf.CallBackData; + ShutdownNetworkBuffer(&conn->NetBuf); + if (StartHttpConnect(conn)) { + SendHttpRequest(conn); + SetNetworkBufferCallBack(&conn->NetBuf, CallBack, CallBackData); + SetNetworkBufferUserPasswdFunc(&conn->NetBuf, + userpasswd, userpasswddata); return FALSE; - } - - if (conn->Tries>=5) { - SetError(error,ÐTTP,HEC_TRIESEX,NULL); - return TRUE; - } - - if (conn->RedirHost) { - g_free(conn->HostName); g_free(conn->Query); - conn->HostName = conn->RedirHost; - conn->Query = conn->RedirQuery; - conn->Port = conn->RedirPort; - conn->RedirHost = conn->RedirQuery = NULL; - retry = TRUE; - } - if (conn->StatusCode==HEC_AUTHREQ && conn->user && conn->password) { - retry = TRUE; - } - if (conn->StatusCode==HEC_PROXYAUTH && conn->proxyuser && - conn->proxypassword) { - retry = TRUE; - } - - if (retry) { - CallBack=conn->NetBuf.CallBack; - userpasswd=conn->NetBuf.userpasswd; - userpasswddata=conn->NetBuf.userpasswddata; - CallBackData=conn->NetBuf.CallBackData; - ShutdownNetworkBuffer(&conn->NetBuf); - if (StartHttpConnect(conn)) { - SendHttpRequest(conn); - SetNetworkBufferCallBack(&conn->NetBuf,CallBack,CallBackData); - SetNetworkBufferUserPasswdFunc(&conn->NetBuf, - userpasswd,userpasswddata); - return FALSE; - } - } else if (conn->StatusCode>=300) { - SetError(error,ÐTTP,conn->StatusCode,NULL); - } - return TRUE; + } + } else if (conn->StatusCode >= 300) { + SetError(error, ÐTTP, conn->StatusCode, NULL); + } + return TRUE; } -gboolean IsHttpError(HttpConnection *conn) { - return (conn->NetBuf.error!=NULL); +gboolean IsHttpError(HttpConnection *conn) +{ + return (conn->NetBuf.error != NULL); } -int CreateTCPSocket(LastError **error) { +int CreateTCPSocket(LastError **error) +{ int fd; - fd=socket(AF_INET,SOCK_STREAM,0); + fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd==SOCKET_ERROR && error) { + if (fd == SOCKET_ERROR && error) { #ifdef CYGWIN - SetError(error,ET_WINSOCK,WSAGetLastError(),NULL); + SetError(error, ET_WINSOCK, WSAGetLastError(), NULL); #else - SetError(error,ET_ERRNO,errno,NULL); + SetError(error, ET_ERRNO, errno, NULL); #endif } return fd; } - -gboolean BindTCPSocket(int sock,unsigned port,LastError **error) { + +gboolean BindTCPSocket(int sock, unsigned port, LastError **error) +{ struct sockaddr_in bindaddr; int retval; - bindaddr.sin_family=AF_INET; - bindaddr.sin_port=htons(port); - bindaddr.sin_addr.s_addr=INADDR_ANY; - memset(bindaddr.sin_zero,0,sizeof(bindaddr.sin_zero)); + bindaddr.sin_family = AF_INET; + bindaddr.sin_port = htons(port); + bindaddr.sin_addr.s_addr = INADDR_ANY; + memset(bindaddr.sin_zero, 0, sizeof(bindaddr.sin_zero)); - retval = bind(sock,(struct sockaddr *)&bindaddr,sizeof(struct sockaddr)); + retval = + bind(sock, (struct sockaddr *)&bindaddr, sizeof(struct sockaddr)); - if (retval==SOCKET_ERROR && error) { + if (retval == SOCKET_ERROR && error) { #ifdef CYGWIN - SetError(error,ET_WINSOCK,WSAGetLastError(),NULL); + SetError(error, ET_WINSOCK, WSAGetLastError(), NULL); #else - SetError(error,ET_ERRNO,errno,NULL); + SetError(error, ET_ERRNO, errno, NULL); #endif } - return (retval!=SOCKET_ERROR); + return (retval != SOCKET_ERROR); } -gboolean StartConnect(int *fd,gchar *RemoteHost,unsigned RemotePort, - gboolean *doneOK,LastError **error) { - struct sockaddr_in ClientAddr; - struct hostent *he; +gboolean StartConnect(int *fd, gchar *RemoteHost, unsigned RemotePort, + gboolean *doneOK, LastError **error) +{ + struct sockaddr_in ClientAddr; + struct hostent *he; - if (doneOK) *doneOK=FALSE; - he = LookupHostname(RemoteHost,error); - if (!he) return FALSE; + if (doneOK) + *doneOK = FALSE; + he = LookupHostname(RemoteHost, error); + if (!he) + return FALSE; - *fd=CreateTCPSocket(error); - if (*fd==SOCKET_ERROR) return FALSE; + *fd = CreateTCPSocket(error); + if (*fd == SOCKET_ERROR) + return FALSE; - ClientAddr.sin_family=AF_INET; - ClientAddr.sin_port=htons(RemotePort); - ClientAddr.sin_addr=*((struct in_addr *)he->h_addr); - memset(ClientAddr.sin_zero,0,sizeof(ClientAddr.sin_zero)); + ClientAddr.sin_family = AF_INET; + ClientAddr.sin_port = htons(RemotePort); + ClientAddr.sin_addr = *((struct in_addr *)he->h_addr); + memset(ClientAddr.sin_zero, 0, sizeof(ClientAddr.sin_zero)); - SetBlocking(*fd,FALSE); + SetBlocking(*fd, FALSE); - if (connect(*fd,(struct sockaddr *)&ClientAddr, - sizeof(struct sockaddr))==SOCKET_ERROR) { + if (connect(*fd, (struct sockaddr *)&ClientAddr, + sizeof(struct sockaddr)) == SOCKET_ERROR) { #ifdef CYGWIN - int errcode=WSAGetLastError(); - if (errcode==WSAEWOULDBLOCK) return TRUE; - else if (error) SetError(error,ET_WINSOCK,errcode,NULL); + int errcode = WSAGetLastError(); + + if (errcode == WSAEWOULDBLOCK) + return TRUE; + else if (error) + SetError(error, ET_WINSOCK, errcode, NULL); #else - if (errno==EINPROGRESS) return TRUE; - else if (error) SetError(error,ET_ERRNO,errno,NULL); + if (errno == EINPROGRESS) + return TRUE; + else if (error) + SetError(error, ET_ERRNO, errno, NULL); #endif - CloseSocket(*fd); *fd=-1; - return FALSE; - } else { - if (doneOK) *doneOK=TRUE; - } - return TRUE; + CloseSocket(*fd); + *fd = -1; + return FALSE; + } else { + if (doneOK) + *doneOK = TRUE; + } + return TRUE; } -gboolean FinishConnect(int fd,LastError **error) { - int errcode; +gboolean FinishConnect(int fd, LastError **error) +{ + int errcode; + #ifdef CYGWIN - errcode = WSAGetLastError(); - if (errcode==0) return TRUE; - else { - if (error) { SetError(error,ET_WINSOCK,errcode,NULL); } - return FALSE; - } + errcode = WSAGetLastError(); + if (errcode == 0) + return TRUE; + else { + if (error) { + SetError(error, ET_WINSOCK, errcode, NULL); + } + return FALSE; + } #else #ifdef HAVE_SOCKLEN_T - socklen_t optlen; + socklen_t optlen; #else - int optlen; + int optlen; #endif - optlen=sizeof(errcode); - if (getsockopt(fd,SOL_SOCKET,SO_ERROR,&errcode,&optlen)==-1) { - errcode = errno; - } - if (errcode==0) return TRUE; - else { - if (error) { SetError(error,ET_ERRNO,errcode,NULL); } - return FALSE; - } + optlen = sizeof(errcode); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &errcode, &optlen) == -1) { + errcode = errno; + } + if (errcode == 0) + return TRUE; + else { + if (error) { + SetError(error, ET_ERRNO, errcode, NULL); + } + return FALSE; + } #endif /* CYGWIN */ } -static void AddB64char(GString *str,int c) { - if (c<0) return; - else if (c<26) g_string_append_c(str,c+'A'); - else if (c<52) g_string_append_c(str,c-26+'a'); - else if (c<62) g_string_append_c(str,c-52+'0'); - else if (c==62) g_string_append_c(str,'+'); - else g_string_append_c(str,'/'); +static void AddB64char(GString *str, int c) +{ + if (c < 0) + return; + else if (c < 26) + g_string_append_c(str, c + 'A'); + else if (c < 52) + g_string_append_c(str, c - 26 + 'a'); + else if (c < 62) + g_string_append_c(str, c - 52 + '0'); + else if (c == 62) + g_string_append_c(str, '+'); + else + g_string_append_c(str, '/'); } -void AddB64Enc(GString *str,gchar *unenc) { -/* Adds the plain text string "unenc" to the end of the GString "str", */ -/* using the Base64 encoding scheme. */ - guint i; - long value=0; - if (!unenc || !str) return; - for (i=0;i<strlen(unenc);i++) { - value <<= 8; - value |= (unsigned char)unenc[i]; - if (i % 3 == 2) { - AddB64char(str,(value>>18)&0x3F); - AddB64char(str,(value>>12)&0x3F); - AddB64char(str,(value>>6)&0x3F); - AddB64char(str,value&0x3F); - value=0; - } - } - if (i % 3 == 1) { - AddB64char(str,(value>>2)&0x3F); - AddB64char(str,(value<<4)&0x3F); - g_string_append(str,"=="); - } else if (i % 3 == 2) { - AddB64char(str,(value>>10)&0x3F); - AddB64char(str,(value>>4)&0x3F); - AddB64char(str,(value<<2)&0x3F); - g_string_append_c(str,'='); - } +/* + * Adds the plain text string "unenc" to the end of the GString "str", + * using the Base64 encoding scheme. + */ +void AddB64Enc(GString *str, gchar *unenc) +{ + guint i; + long value = 0; + + if (!unenc || !str) + return; + for (i = 0; i < strlen(unenc); i++) { + value <<= 8; + value |= (unsigned char)unenc[i]; + if (i % 3 == 2) { + AddB64char(str, (value >> 18) & 0x3F); + AddB64char(str, (value >> 12) & 0x3F); + AddB64char(str, (value >> 6) & 0x3F); + AddB64char(str, value & 0x3F); + value = 0; + } + } + if (i % 3 == 1) { + AddB64char(str, (value >> 2) & 0x3F); + AddB64char(str, (value << 4) & 0x3F); + g_string_append(str, "=="); + } else if (i % 3 == 2) { + AddB64char(str, (value >> 10) & 0x3F); + AddB64char(str, (value >> 4) & 0x3F); + AddB64char(str, (value << 2) & 0x3F); + g_string_append_c(str, '='); + } } #endif /* NETWORKING */ (DIR) diff --git a/src/network.h b/src/network.h t@@ -1,23 +1,24 @@ -/* network.h Header file for low-level networking routines */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * network.h Header file for low-level networking routines * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __NETWORK_H__ #define __NETWORK_H__ t@@ -28,8 +29,8 @@ /* Various includes necessary for select() calls */ #include <sys/types.h> -/* Be careful not to include both sys/time.h and time.h on those systems */ -/* which don't like it */ +/* Be careful not to include both sys/time.h and time.h on those systems + * which don't like it */ #if TIME_WITH_SYS_TIME #include <sys/time.h> #include <time.h> t@@ -56,167 +57,186 @@ #endif typedef struct _ConnBuf { - gchar *Data; /* bytes waiting to be read/written */ - gint Length; /* allocated length of the "Data" buffer */ - gint DataPresent; /* number of bytes currently in "Data" */ + gchar *Data; /* bytes waiting to be read/written */ + gint Length; /* allocated length of the "Data" buffer */ + gint DataPresent; /* number of bytes currently in "Data" */ } ConnBuf; typedef struct _NetworkBuffer NetworkBuffer; -typedef void (*NBCallBack)(NetworkBuffer *NetBuf,gboolean Read,gboolean Write, - gboolean CallNow); +typedef void (*NBCallBack) (NetworkBuffer *NetBuf, gboolean Read, + gboolean Write, gboolean CallNow); -typedef void (*NBUserPasswd)(NetworkBuffer *NetBuf,gpointer data); +typedef void (*NBUserPasswd) (NetworkBuffer *NetBuf, gpointer data); /* Information about a SOCKS server */ typedef struct _SocksServer { - gchar *name; /* hostname */ - unsigned port; /* port number */ - int version; /* desired protocol version (usually 4 or 5) */ - gboolean numuid; /* if TRUE, send numeric user IDs rather than names */ - char *user; /* if not blank, override the username with this */ - gchar *authuser; /* if set, the username for SOCKS5 auth */ - gchar *authpassword; /* if set, the password for SOCKS5 auth */ + gchar *name; /* hostname */ + unsigned port; /* port number */ + int version; /* desired protocol version (usually + * 4 or 5) */ + gboolean numuid; /* if TRUE, send numeric user IDs rather + * than names */ + char *user; /* if not blank, override the username + * with this */ + gchar *authuser; /* if set, the username for SOCKS5 auth */ + gchar *authpassword; /* if set, the password for SOCKS5 auth */ } SocksServer; /* The status of a network buffer */ typedef enum { - NBS_PRECONNECT, /* Socket is not yet connected */ - NBS_SOCKSCONNECT, /* A CONNECT request is being sent to a SOCKS server */ - NBS_CONNECTED /* Socket is connected */ + NBS_PRECONNECT, /* Socket is not yet connected */ + NBS_SOCKSCONNECT, /* A CONNECT request is being sent to a + * SOCKS server */ + NBS_CONNECTED /* Socket is connected */ } NBStatus; /* Status of a SOCKS v5 negotiation */ typedef enum { - NBSS_METHODS, /* Negotiation of available methods */ - NBSS_USERPASSWD, /* Username-password request is being sent */ - NBSS_CONNECT /* CONNECT request is being sent */ + NBSS_METHODS, /* Negotiation of available methods */ + NBSS_USERPASSWD, /* Username-password request is being sent */ + NBSS_CONNECT /* CONNECT request is being sent */ } NBSocksStatus; /* Handles reading and writing messages from/to a network connection */ struct _NetworkBuffer { - int fd; /* File descriptor of the socket */ - gint InputTag; /* Identifier for gdk_input routines */ - NBCallBack CallBack; /* Function called when the socket status changes */ - gpointer CallBackData; /* Data accessible to the callback function */ - char Terminator; /* Character that separates messages */ - char StripChar; /* Char that should be removed from messages */ - ConnBuf ReadBuf; /* New data, waiting for the application */ - ConnBuf WriteBuf; /* Data waiting to be written to the wire */ - ConnBuf negbuf; /* Output for protocol negotiation (e.g. SOCKS) */ - gboolean WaitConnect; /* TRUE if a non-blocking connect is in progress */ - NBStatus status; /* Status of the connection (if any) */ - NBSocksStatus sockstat; /* Status of SOCKS negotiation (if any) */ - SocksServer *socks; /* If non-NULL, a SOCKS server to use */ - NBUserPasswd userpasswd; /* Function to supply username and password for - SOCKS5 authentication */ - gpointer userpasswddata; /* data to pass to the above function */ - gchar *host; /* If non-NULL, the host to connect to */ - unsigned port; /* If non-NULL, the port to connect to */ - LastError *error; /* Any error from the last operation */ + int fd; /* File descriptor of the socket */ + gint InputTag; /* Identifier for gdk_input routines */ + NBCallBack CallBack; /* Function called when the socket + * status changes */ + gpointer CallBackData; /* Data accessible to the callback + * function */ + char Terminator; /* Character that separates messages */ + char StripChar; /* Char that should be removed + * from messages */ + ConnBuf ReadBuf; /* New data, waiting for the application */ + ConnBuf WriteBuf; /* Data waiting to be written to the wire */ + ConnBuf negbuf; /* Output for protocol negotiation + * (e.g. SOCKS) */ + gboolean WaitConnect; /* TRUE if a non-blocking connect is in + * progress */ + NBStatus status; /* Status of the connection (if any) */ + NBSocksStatus sockstat; /* Status of SOCKS negotiation (if any) */ + SocksServer *socks; /* If non-NULL, a SOCKS server to use */ + NBUserPasswd userpasswd; /* Function to supply username and + * password for SOCKS5 authentication */ + gpointer userpasswddata; /* data to pass to the above function */ + gchar *host; /* If non-NULL, the host to connect to */ + unsigned port; /* If non-NULL, the port to connect to */ + LastError *error; /* Any error from the last operation */ }; /* Keeps track of the progress of an HTTP connection */ typedef enum { - HS_CONNECTING, /* Waiting for connect() to complete */ - HS_READHEADERS, /* Reading HTTP headers */ - HS_READSEPARATOR, /* Reading the header/body separator line */ - HS_READBODY, /* Reading HTTP body */ - HS_WAITCOMPLETE /* Done reading, now waiting for authentication etc. - before closing and/or retrying the connection */ + HS_CONNECTING, /* Waiting for connect() to complete */ + HS_READHEADERS, /* Reading HTTP headers */ + HS_READSEPARATOR, /* Reading the header/body separator line */ + HS_READBODY, /* Reading HTTP body */ + HS_WAITCOMPLETE /* Done reading, now waiting for + * authentication etc. before closing + * and/or retrying the connection */ } HttpStatus; typedef struct _HttpConnection HttpConnection; -typedef void (*HCAuthFunc)(struct _HttpConnection *conn, - gboolean proxyauth,gchar *realm,gpointer data); +typedef void (*HCAuthFunc) (HttpConnection *conn, gboolean proxyauth, + gchar *realm, gpointer data); /* A structure used to keep track of an HTTP connection */ struct _HttpConnection { - gchar *HostName; /* The machine on which the desired page resides */ - unsigned Port; /* The port */ - gchar *Proxy; /* If non-NULL, a web proxy to use */ - unsigned ProxyPort; /* The port to use for talking to the proxy */ - gchar *Method; /* e.g. GET, POST */ - gchar *Query; /* e.g. the path of the desired webpage */ - gchar *Headers; /* if non-NULL, e.g. Content-Type */ - gchar *Body; /* if non-NULL, data to send */ - gchar *RedirHost; /* if non-NULL, a hostname to redirect to */ - gchar *RedirQuery; /* if non-NULL, the path to redirect to */ - unsigned RedirPort; /* The port on the host to redirect to */ - HCAuthFunc authfunc; /* Callback function for authentication */ - gpointer authdata; /* Data to be passed to authfunc */ - gboolean waitinput; /* TRUE if we're waiting for auth etc. - to be supplied */ - gchar *user; /* The supplied username for HTTP auth */ - gchar *password; /* The supplied password for HTTP auth */ - gchar *proxyuser; /* The supplied username for HTTP proxy auth */ - gchar *proxypassword; /* The supplied password for HTTP proxy auth */ - NetworkBuffer NetBuf; /* The actual network connection itself */ - gint Tries; /* Number of requests actually sent so far */ - gint StatusCode; /* 0=no status yet, otherwise an HTTP status code */ - HttpStatus Status; + gchar *HostName; /* The machine on which the desired page + * resides */ + unsigned Port; /* The port */ + gchar *Proxy; /* If non-NULL, a web proxy to use */ + unsigned ProxyPort; /* The port to use for talking to + * the proxy */ + gchar *Method; /* e.g. GET, POST */ + gchar *Query; /* e.g. the path of the desired webpage */ + gchar *Headers; /* if non-NULL, e.g. Content-Type */ + gchar *Body; /* if non-NULL, data to send */ + gchar *RedirHost; /* if non-NULL, a hostname to redirect to */ + gchar *RedirQuery; /* if non-NULL, the path to redirect to */ + unsigned RedirPort; /* The port on the host to redirect to */ + HCAuthFunc authfunc; /* Callback function for authentication */ + gpointer authdata; /* Data to be passed to authfunc */ + gboolean waitinput; /* TRUE if we're waiting for auth etc. to + * be supplied */ + gchar *user; /* The supplied username for HTTP auth */ + gchar *password; /* The supplied password for HTTP auth */ + gchar *proxyuser; /* The supplied username for HTTP + * proxy auth */ + gchar *proxypassword; /* The supplied password for HTTP + * proxy auth */ + NetworkBuffer NetBuf; /* The actual network connection itself */ + gint Tries; /* Number of requests actually sent so far */ + gint StatusCode; /* 0=no status yet, otherwise an HTTP + * status code */ + HttpStatus Status; }; -void InitNetworkBuffer(NetworkBuffer *NetBuf,char Terminator,char StripChar, - SocksServer *socks); -void SetNetworkBufferCallBack(NetworkBuffer *NetBuf,NBCallBack CallBack, +void InitNetworkBuffer(NetworkBuffer *NetBuf, char Terminator, + char StripChar, SocksServer *socks); +void SetNetworkBufferCallBack(NetworkBuffer *NetBuf, NBCallBack CallBack, gpointer CallBackData); void SetNetworkBufferUserPasswdFunc(NetworkBuffer *NetBuf, - NBUserPasswd userpasswd,gpointer data); + NBUserPasswd userpasswd, + gpointer data); gboolean IsNetworkBufferActive(NetworkBuffer *NetBuf); -void BindNetworkBufferToSocket(NetworkBuffer *NetBuf,int fd); -gboolean StartNetworkBufferConnect(NetworkBuffer *NetBuf,gchar *RemoteHost, - unsigned RemotePort); +void BindNetworkBufferToSocket(NetworkBuffer *NetBuf, int fd); +gboolean StartNetworkBufferConnect(NetworkBuffer *NetBuf, + gchar *RemoteHost, unsigned RemotePort); void ShutdownNetworkBuffer(NetworkBuffer *NetBuf); -void SetSelectForNetworkBuffer(NetworkBuffer *NetBuf,fd_set *readfds, - fd_set *writefds,fd_set *errorfds,int *MaxSock); -gboolean RespondToSelect(NetworkBuffer *NetBuf,fd_set *readfds, - fd_set *writefds,fd_set *errorfds, +void SetSelectForNetworkBuffer(NetworkBuffer *NetBuf, fd_set *readfds, + fd_set *writefds, fd_set *errorfds, + int *MaxSock); +gboolean RespondToSelect(NetworkBuffer *NetBuf, fd_set *readfds, + fd_set *writefds, fd_set *errorfds, gboolean *DoneOK); -gboolean NetBufHandleNetwork(NetworkBuffer *NetBuf,gboolean ReadReady, - gboolean WriteReady,gboolean *DoneOK); +gboolean NetBufHandleNetwork(NetworkBuffer *NetBuf, gboolean ReadReady, + gboolean WriteReady, gboolean *DoneOK); gboolean ReadDataFromWire(NetworkBuffer *NetBuf); gboolean WriteDataToWire(NetworkBuffer *NetBuf); -void QueueMessageForSend(NetworkBuffer *NetBuf,gchar *data); +void QueueMessageForSend(NetworkBuffer *NetBuf, gchar *data); gint CountWaitingMessages(NetworkBuffer *NetBuf); gchar *GetWaitingMessage(NetworkBuffer *NetBuf); -void SendSocks5UserPasswd(NetworkBuffer *NetBuf,gchar *user,gchar *password); -gchar *GetWaitingData(NetworkBuffer *NetBuf,int numbytes); -gchar *PeekWaitingData(NetworkBuffer *NetBuf,int numbytes); -gchar *ExpandWriteBuffer(ConnBuf *conn,int numbytes,LastError **error); -void CommitWriteBuffer(NetworkBuffer *NetBuf,ConnBuf *conn, - gchar *addpt,guint addlen); - -gboolean OpenHttpConnection(HttpConnection **conn,gchar *HostName, - unsigned Port,gchar *Proxy,unsigned ProxyPort, - SocksServer *socks, - gchar *Method,gchar *Query, - gchar *Headers,gchar *Body); +void SendSocks5UserPasswd(NetworkBuffer *NetBuf, gchar *user, + gchar *password); +gchar *GetWaitingData(NetworkBuffer *NetBuf, int numbytes); +gchar *PeekWaitingData(NetworkBuffer *NetBuf, int numbytes); +gchar *ExpandWriteBuffer(ConnBuf *conn, int numbytes, LastError **error); +void CommitWriteBuffer(NetworkBuffer *NetBuf, ConnBuf *conn, gchar *addpt, + guint addlen); + +gboolean OpenHttpConnection(HttpConnection **conn, gchar *HostName, + unsigned Port, gchar *Proxy, + unsigned ProxyPort, SocksServer *socks, + gchar *Method, gchar *Query, gchar *Headers, + gchar *Body); void CloseHttpConnection(HttpConnection *conn); -gchar *ReadHttpResponse(HttpConnection *conn,gboolean *doneOK); -void SetHttpAuthentication(HttpConnection *conn,gboolean proxy, - gchar *user,gchar *password); -void SetHttpAuthFunc(HttpConnection *conn,HCAuthFunc authfunc,gpointer data); +gchar *ReadHttpResponse(HttpConnection *conn, gboolean *doneOK); +void SetHttpAuthentication(HttpConnection *conn, gboolean proxy, + gchar *user, gchar *password); +void SetHttpAuthFunc(HttpConnection *conn, HCAuthFunc authfunc, + gpointer data); gboolean HandleHttpCompletion(HttpConnection *conn); gboolean IsHttpError(HttpConnection *conn); int CreateTCPSocket(LastError **error); -gboolean BindTCPSocket(int sock,unsigned port,LastError **error); +gboolean BindTCPSocket(int sock, unsigned port, LastError **error); void StartNetworking(void); void StopNetworking(void); #ifdef CYGWIN #define CloseSocket(sock) closesocket(sock) void SetReuse(SOCKET sock); -void SetBlocking(SOCKET sock,gboolean blocking); +void SetBlocking(SOCKET sock, gboolean blocking); #else #define CloseSocket(sock) close(sock) void SetReuse(int sock); -void SetBlocking(int sock,gboolean blocking); +void SetBlocking(int sock, gboolean blocking); #endif -void AddB64Enc(GString *str,gchar *unenc); +void AddB64Enc(GString *str, gchar *unenc); #endif /* NETWORKING */ (DIR) diff --git a/src/nls.h b/src/nls.h t@@ -1,23 +1,24 @@ -/* nls.h Header file for NLS (internationalization) defines */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * nls.h Header file for NLS (internationalization) defines * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __NLS_H__ #define __NLS_H__ (DIR) diff --git a/src/serverside.c b/src/serverside.c t@@ -1,23 +1,24 @@ -/* serverside.c Handles the server side of dopewars */ -/* Copyright (c) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * serverside.c Handles the server side of dopewars * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifdef HAVE_CONFIG_H #include <config.h> t@@ -25,17 +26,17 @@ #include <stdio.h> #include <string.h> -#include <sys/types.h> /* For size_t etc. */ +#include <sys/types.h> /* For size_t etc. */ #include <sys/stat.h> #ifdef CYGWIN -#include <windows.h> /* For datatypes such as BOOL */ -#include <winsock.h> /* For network functions */ +#include <windows.h> /* For datatypes such as BOOL */ +#include <winsock.h> /* For network functions */ #else -#include <sys/socket.h> /* For struct sockaddr etc. */ -#include <netinet/in.h> /* For struct sockaddr_in etc. */ -#include <sys/un.h> /* For struct sockaddr_un */ -#include <arpa/inet.h> /* For socklen_t */ +#include <sys/socket.h> /* For struct sockaddr etc. */ +#include <netinet/in.h> /* For struct sockaddr_in etc. */ +#include <sys/un.h> /* For struct sockaddr_un */ +#include <arpa/inet.h> /* For socklen_t */ #endif /* CYGWIN */ #ifdef HAVE_UNISTD_H t@@ -57,2980 +58,3497 @@ #include "gtkport.h" #endif -static const price_t MINTRENCHPRICE=200,MAXTRENCHPRICE=300; +static const price_t MINTRENCHPRICE = 200, MAXTRENCHPRICE = 300; #define ESCAPE 0 #define DEFECT 1 #define SHOT 2 #define NUMDISCOVER 3 char *Discover[NUMDISCOVER] = { -/* Things that can "happen" to your spies - look for strings containing - "The spy %s!" to see how these strings are used. */ - N_("escaped"), N_("defected"), N_("was shot") + /* Things that can "happen" to your spies - look for strings containing + * "The spy %s!" to see how these strings are used. */ + N_("escaped"), N_("defected"), N_("was shot") }; /* The two keys that are valid answers to the Attack/Evade question. If - you wish to translate them, do so in the same order as they given here. - You will also need to translate the answers given by the clients. */ + * you wish to translate them, do so in the same order as they given here. + * You will also need to translate the answers given by the clients. */ static char *attackquestiontr = N_("AE"); /* If we haven't talked to the metaserver for 3 hours, then remind it that - we still exist, so we don't get wiped from the list of active servers */ + * we still exist, so we don't get wiped from the list of active servers */ #define METAUPDATETIME (10800) /* Don't report players logging in/out to the metaserver more frequently - than once every minute (so as not to overload the metaserver, or slow - down our own server). */ + * than once every minute (so as not to overload the metaserver, or slow + * down our own server). */ #define METAMINTIME (60) -int TerminateRequest,ReregisterRequest,RelogRequest; +int TerminateRequest, ReregisterRequest, RelogRequest; int MetaUpdateTimeout; int MetaMinTimeout; -gboolean WantQuit=FALSE; +gboolean WantQuit = FALSE; #ifdef CYGWIN static SERVICE_STATUS_HANDLE scHandle; #endif /* Do we want to update the player details on the metaserver when the - timeout expires? */ -gboolean MetaPlayerPending=FALSE; + * timeout expires? */ +gboolean MetaPlayerPending = FALSE; -GSList *FirstServer=NULL; +GSList *FirstServer = NULL; #ifdef NETWORKING static GScanner *Scanner; /* Data waiting to be sent to/read from the metaserver */ -HttpConnection *MetaConn=NULL; +HttpConnection *MetaConn = NULL; #endif /* Handle to the high score file */ -static FILE *ScoreFP=NULL; +static FILE *ScoreFP = NULL; /* Pointer to the filename of a pid file (if non-NULL) */ char *PidFile; -static char HelpText[] = { -/* Help on various general server commands */ - N_("dopewars server version %s commands and settings\n\n" - "help Displays this help screen\n" - "list Lists all players logged on\n" - "push <player> Politely asks the named player to leave\n" - "kill <player> Abruptly breaks the connection with the " - "named player\n" - "msg:<mesg> Send message to all players\n" - "quit Gracefully quit, after notifying all players\n" - "<variable>=<value> Sets the named variable to the given value\n" - "<variable> Displays the value of the named variable\n" - "<list>[x].<var>=<value> Sets the named variable in the given list,\n" - " index x, to the given value\n" - "<list>[x].<var> Displays the value of the named list variable\n" - "\nValid variables are listed below:-\n\n") +static char HelpText[] = { + /* Help on various general server commands */ + N_("dopewars server version %s commands and settings\n\n" + "help Displays this help screen\n" + "list Lists all players logged on\n" + "push <player> Politely asks the named player to leave\n" + "kill <player> Abruptly breaks the connection with the " + "named player\n" + "msg:<mesg> Send message to all players\n" + "quit Gracefully quit, after notifying all players\n" + "<variable>=<value> Sets the named variable to the given value\n" + "<variable> Displays the value of the named variable\n" + "<list>[x].<var>=<value> Sets the named variable in the given list,\n" + " index x, to the given value\n" + "<list>[x].<var> Displays the value of the named list variable\n" + "\nValid variables are listed below:-\n\n") }; typedef enum _OfferForce { - NOFORCE, FORCECOPS, FORCEBITCH + NOFORCE, FORCECOPS, FORCEBITCH } OfferForce; -int SendSingleHighScore(Player *Play,struct HISCORE *Score, - int ind,gboolean Bold); -static int SendCopOffer(Player *To,OfferForce Force); -static int OfferObject(Player *To,gboolean ForceBitch); -static gboolean HighScoreWrite(FILE *fp,struct HISCORE *MultiScore, +int SendSingleHighScore(Player *Play, struct HISCORE *Score, + int ind, gboolean Bold); +static int SendCopOffer(Player *To, OfferForce Force); +static int OfferObject(Player *To, gboolean ForceBitch); +static gboolean HighScoreWrite(FILE *fp, struct HISCORE *MultiScore, struct HISCORE *AntiqueScore); #ifdef GUI_SERVER -static void GuiHandleMeta(gpointer data,gint socket, +static void GuiHandleMeta(gpointer data, gint socket, GdkInputCondition condition); static void MetaSocketStatus(NetworkBuffer *NetBuf, - gboolean Read,gboolean Write,gboolean CallNow); + gboolean Read, gboolean Write, + gboolean CallNow); #endif #ifdef NETWORKING -static gboolean MetaConnectError(HttpConnection *conn) { - GString *errstr; - if (!IsHttpError(conn)) return FALSE; - errstr=g_string_new(""); - g_string_assign_error(errstr,MetaConn->NetBuf.error); - dopelog(1,_("Failed to connect to metaserver at %s:%u (%s)"), - MetaServer.Name,MetaServer.Port,errstr->str); - g_string_free(errstr,TRUE); - return TRUE; -} - -static void ServerHttpAuth(HttpConnection *conn,gboolean proxyauth, - gchar *realm,gpointer data) { - gchar *user=NULL,*password=NULL; +static gboolean MetaConnectError(HttpConnection *conn) +{ + GString *errstr; + + if (!IsHttpError(conn)) + return FALSE; + errstr = g_string_new(""); + g_string_assign_error(errstr, MetaConn->NetBuf.error); + dopelog(1, _("Failed to connect to metaserver at %s:%u (%s)"), + MetaServer.Name, MetaServer.Port, errstr->str); + g_string_free(errstr, TRUE); + return TRUE; +} + +static void ServerHttpAuth(HttpConnection *conn, gboolean proxyauth, + gchar *realm, gpointer data) +{ + gchar *user = NULL, *password = NULL; + if (proxyauth) { if (MetaServer.proxyuser[0] && MetaServer.proxypassword[0]) { - user = MetaServer.proxyuser; password = MetaServer.proxypassword; - dopelog(3,_("Using MetaServer.Proxy.User and MetaServer.Proxy.Password " - "for HTTP proxy authentication")); + user = MetaServer.proxyuser; + password = MetaServer.proxypassword; + dopelog(3, + _("Using MetaServer.Proxy.User and " + "MetaServer.Proxy.Password for HTTP proxy authentication")); } else { - dopelog(0,_("Unable to authenticate with HTTP proxy; please set " - "MetaServer.Proxy.User and MetaServer.Proxy.Password variables")); + dopelog(0, _("Unable to authenticate with HTTP proxy; please " + "set MetaServer.Proxy.User and " + "MetaServer.Proxy.Password variables")); } } else { if (MetaServer.authuser[0] && MetaServer.authpassword[0]) { - user = MetaServer.authuser; password = MetaServer.authpassword; - dopelog(3,_("Using MetaServer.Auth.User and MetaServer.Auth.Password " - "for HTTP authentication")); + user = MetaServer.authuser; + password = MetaServer.authpassword; + dopelog(3, + _("Using MetaServer.Auth.User and MetaServer.Auth.Password " + "for HTTP authentication")); } else { - dopelog(0,_("Unable to authenticate with HTTP server; please set " - "MetaServer.Auth.User and MetaServer.Auth.Password variables")); + dopelog(0, _("Unable to authenticate with HTTP server; please set " + "MetaServer.Auth.User and " + "MetaServer.Auth.Password variables")); } } - SetHttpAuthentication(conn,proxyauth,user,password); + SetHttpAuthentication(conn, proxyauth, user, password); } -static void ServerNetBufAuth(NetworkBuffer *netbuf,gpointer data) { - dopelog(3,_("Using Socks.Auth.User and Socks.Auth.Password " - "for SOCKS5 authentication")); - SendSocks5UserPasswd(netbuf,Socks.authuser,Socks.authpassword); +static void ServerNetBufAuth(NetworkBuffer *netbuf, gpointer data) +{ + dopelog(3, _("Using Socks.Auth.User and Socks.Auth.Password " + "for SOCKS5 authentication")); + SendSocks5UserPasswd(netbuf, Socks.authuser, Socks.authpassword); } #endif -void RegisterWithMetaServer(gboolean Up,gboolean SendData, - gboolean RespectTimeout) { -/* Sends server details to the metaserver, if specified. If "Up" is */ -/* TRUE, informs the metaserver that the server is now accepting */ -/* connections - otherwise tells the metaserver that this server is */ -/* about to go down. If "SendData" is TRUE, then also sends game */ -/* data (e.g. scores) to the metaserver. If "RespectTimeout" is TRUE */ -/* then the update is delayed if a previous update happened too */ -/* recently. If networking is disabled, this function does nothing. */ +/* + * Sends server details to the metaserver, if specified. If "Up" is + * TRUE, informs the metaserver that the server is now accepting + * connections - otherwise tells the metaserver that this server is + * about to go down. If "SendData" is TRUE, then also sends game + * data (e.g. scores) to the metaserver. If "RespectTimeout" is TRUE + * then the update is delayed if a previous update happened too + * recently. If networking is disabled, this function does nothing. + */ +void RegisterWithMetaServer(gboolean Up, gboolean SendData, + gboolean RespectTimeout) +{ #if NETWORKING - struct HISCORE MultiScore[NUMHISCORE],AntiqueScore[NUMHISCORE]; - GString *headers,*body; - gchar *prstr; - gboolean retval; - int i; - - if (!MetaServer.Active || !NotifyMetaServer || WantQuit) return; - - if (MetaMinTimeout > time(NULL) && RespectTimeout) { - dopelog(3,_("Attempt to connect to metaserver too frequently " - "- waiting for next timeout")); - MetaPlayerPending=TRUE; - return; - } - -/* If the previous connect hung for so long that it's still active, then - break the connection before we start a new one */ - if (MetaConn) CloseHttpConnection(MetaConn); - - headers=g_string_new(""); - body=g_string_new(""); - - g_string_assign(body,"output=text&"); - - g_string_sprintfa(body,"up=%d&port=%d&version=",Up ? 1 : 0,Port); - AddURLEnc(body,VERSION); - g_string_sprintfa(body,"&players=%d&maxplay=%d&comment=", - CountPlayers(FirstServer),MaxClients); - AddURLEnc(body,MetaServer.Comment); - - if (MetaServer.LocalName[0]) { - g_string_append(body,"&hostname="); - AddURLEnc(body,MetaServer.LocalName); - } - if (MetaServer.Password[0]) { - g_string_append(body,"&password="); - AddURLEnc(body,MetaServer.Password); - } - - if (SendData && HighScoreRead(ScoreFP,MultiScore,AntiqueScore,TRUE)) { - for (i=0;i<NUMHISCORE;i++) { - if (MultiScore[i].Name && MultiScore[i].Name[0]) { - g_string_sprintfa(body,"&nm[%d]=",i); - AddURLEnc(body,MultiScore[i].Name); - g_string_sprintfa(body,"&dt[%d]=",i); - AddURLEnc(body,MultiScore[i].Time); - g_string_sprintfa(body,"&st[%d]=%s&sc[%d]=",i, - MultiScore[i].Dead ? "dead" : "alive",i); - AddURLEnc(body,prstr=FormatPrice(MultiScore[i].Money)); - g_free(prstr); - } + struct HISCORE MultiScore[NUMHISCORE], AntiqueScore[NUMHISCORE]; + GString *headers, *body; + gchar *prstr; + gboolean retval; + int i; + + if (!MetaServer.Active || !NotifyMetaServer || WantQuit) + return; + + if (MetaMinTimeout > time(NULL) && RespectTimeout) { + dopelog(3, _("Attempt to connect to metaserver too frequently " + "- waiting for next timeout")); + MetaPlayerPending = TRUE; + return; + } + + /* If the previous connect hung for so long that it's still active, then + * break the connection before we start a new one */ + if (MetaConn) + CloseHttpConnection(MetaConn); + + headers = g_string_new(""); + body = g_string_new(""); + + g_string_assign(body, "output=text&"); + + g_string_sprintfa(body, "up=%d&port=%d&version=", Up ? 1 : 0, Port); + AddURLEnc(body, VERSION); + g_string_sprintfa(body, "&players=%d&maxplay=%d&comment=", + CountPlayers(FirstServer), MaxClients); + AddURLEnc(body, MetaServer.Comment); + + if (MetaServer.LocalName[0]) { + g_string_append(body, "&hostname="); + AddURLEnc(body, MetaServer.LocalName); + } + if (MetaServer.Password[0]) { + g_string_append(body, "&password="); + AddURLEnc(body, MetaServer.Password); + } + + if (SendData && HighScoreRead(ScoreFP, MultiScore, AntiqueScore, TRUE)) { + for (i = 0; i < NUMHISCORE; i++) { + if (MultiScore[i].Name && MultiScore[i].Name[0]) { + g_string_sprintfa(body, "&nm[%d]=", i); + AddURLEnc(body, MultiScore[i].Name); + g_string_sprintfa(body, "&dt[%d]=", i); + AddURLEnc(body, MultiScore[i].Time); + g_string_sprintfa(body, "&st[%d]=%s&sc[%d]=", i, + MultiScore[i].Dead ? "dead" : "alive", i); + AddURLEnc(body, prstr = FormatPrice(MultiScore[i].Money)); + g_free(prstr); } - } - - g_string_sprintf(headers, - "Content-Type: application/x-www-form-urlencoded\n" - "Content-Length: %d",(int)strlen(body->str)); - - retval=OpenHttpConnection(&MetaConn,MetaServer.Name,MetaServer.Port, - MetaServer.ProxyName,MetaServer.ProxyPort, - UseSocks && MetaServer.UseSocks ? &Socks : NULL, - "POST",MetaServer.Path,headers->str,body->str); - g_string_free(headers,TRUE); - g_string_free(body,TRUE); - - if (retval) { - dopelog(2,_("Waiting for metaserver connect to %s:%u..."), - MetaServer.Name,MetaServer.Port); - } else { - MetaConnectError(MetaConn); - CloseHttpConnection(MetaConn); MetaConn=NULL; - return; - } - SetHttpAuthFunc(MetaConn,ServerHttpAuth,NULL); - - if (Socks.authuser && Socks.authuser[0] && - Socks.authpassword && Socks.authpassword[0]) { - SetNetworkBufferUserPasswdFunc(&MetaConn->NetBuf,ServerNetBufAuth,NULL); - } + } + } + + g_string_sprintf(headers, + "Content-Type: application/x-www-form-urlencoded\n" + "Content-Length: %d", (int)strlen(body->str)); + + retval = OpenHttpConnection(&MetaConn, MetaServer.Name, MetaServer.Port, + MetaServer.ProxyName, MetaServer.ProxyPort, + UseSocks && MetaServer.UseSocks ? &Socks : NULL, + "POST", MetaServer.Path, headers->str, + body->str); + g_string_free(headers, TRUE); + g_string_free(body, TRUE); + + if (retval) { + dopelog(2, _("Waiting for metaserver connect to %s:%u..."), + MetaServer.Name, MetaServer.Port); + } else { + MetaConnectError(MetaConn); + CloseHttpConnection(MetaConn); + MetaConn = NULL; + return; + } + SetHttpAuthFunc(MetaConn, ServerHttpAuth, NULL); + + if (Socks.authuser && Socks.authuser[0] && + Socks.authpassword && Socks.authpassword[0]) { + SetNetworkBufferUserPasswdFunc(&MetaConn->NetBuf, ServerNetBufAuth, + NULL); + } #ifdef GUI_SERVER - SetNetworkBufferCallBack(&MetaConn->NetBuf,MetaSocketStatus,NULL); + SetNetworkBufferCallBack(&MetaConn->NetBuf, MetaSocketStatus, NULL); #endif - MetaPlayerPending=FALSE; + MetaPlayerPending = FALSE; - MetaUpdateTimeout=time(NULL)+METAUPDATETIME; - MetaMinTimeout=time(NULL)+METAMINTIME; + MetaUpdateTimeout = time(NULL) + METAUPDATETIME; + MetaMinTimeout = time(NULL) + METAMINTIME; #endif /* NETWORKING */ } #ifdef NETWORKING -void HandleServerPlayer(Player *Play) { - gchar *buf; - gboolean MessageRead=FALSE; - while ((buf=GetWaitingPlayerMessage(Play))!=NULL) { - MessageRead=TRUE; - HandleServerMessage(buf,Play); - g_free(buf); - } -/* Reset the idle timeout (if necessary) */ - if (MessageRead && IdleTimeout) { - Play->IdleTimeout=time(NULL)+(time_t)IdleTimeout; - } +void HandleServerPlayer(Player *Play) +{ + gchar *buf; + gboolean MessageRead = FALSE; + + while ((buf = GetWaitingPlayerMessage(Play)) != NULL) { + MessageRead = TRUE; + HandleServerMessage(buf, Play); + g_free(buf); + } + /* Reset the idle timeout (if necessary) */ + if (MessageRead && IdleTimeout) { + Play->IdleTimeout = time(NULL) + (time_t) IdleTimeout; + } } #endif /* NETWORKING */ -void SendPlayerDetails(Player *Play,Player *To,MsgCode Code) { -/* Sends details (name, ID) about player "Play" to player "To", using */ -/* message code "Code" */ - GString *text; - text=g_string_new(GetPlayerName(Play)); - if (HaveAbility(To,A_PLAYERID)) { - g_string_sprintfa(text,"^%d",Play->ID); - } - SendServerMessage(NULL,C_NONE,Code,To,text->str); - g_string_free(text,TRUE); -} - -void HandleServerMessage(gchar *buf,Player *Play) { -/* Given a message "buf", from player "Play", performs processing and */ -/* sends suitable replies. */ - Player *To,*tmp,*pt; - GSList *list; - char *Data; - AICode AI; - MsgCode Code; - gchar *text; - DopeEntry NewEntry; - int i; - price_t money; - - if (ProcessMessage(buf,Play,&To,&AI,&Code,&Data,FirstServer)==-1) { - g_warning("Bad message"); - return; - } - switch(Code) { - case C_MSGTO: - if (Network) { - dopelog(3,"%s->%s: %s",GetPlayerName(Play),GetPlayerName(To),Data); - } - SendServerMessage(Play,AI,Code,To,Data); - break; -/* case C_NETMESSAGE: - dopelog(1,"Net:%s\n",Data);*/ -/* Make sure they do actually disconnect, eventually! */ -/* if (ConnectTimeout) { - Play->ConnectTimeout=time(NULL)+(time_t)ConnectTimeout; - } - break;*/ - case C_ABILITIES: - ReceiveAbilities(Play,Data); - break; - case C_NAME: - pt=GetPlayerByName(Data,FirstServer); - if (pt && pt!=Play) { - if (ConnectTimeout) { - Play->ConnectTimeout=time(NULL)+(time_t)ConnectTimeout; - } - SendServerMessage(NULL,C_NONE,C_NEWNAME,Play,NULL); - } else if (strlen(GetPlayerName(Play))==0 && Data[0]) { - if (CountPlayers(FirstServer)<MaxClients || !Network) { - SendAbilities(Play); - CombineAbilities(Play); - SendInitialData(Play); - SendMiscData(Play); - SetPlayerName(Play,Data); - for (list=FirstServer;list;list=g_slist_next(list)) { - pt=(Player *)list->data; - if (pt!=Play && IsConnectedPlayer(pt) && !IsCop(pt)) { - SendPlayerDetails(pt,Play,C_LIST); - } - } - SendServerMessage(NULL,C_NONE,C_ENDLIST,Play,NULL); - RegisterWithMetaServer(TRUE,FALSE,TRUE); - Play->ConnectTimeout=0; - - if (Network) { - dopelog(2,_("%s joins the game!"),GetPlayerName(Play)); - } - for (list=FirstServer;list;list=g_slist_next(list)) { - pt=(Player *)list->data; - if (IsConnectedPlayer(pt) && pt!=Play) { - SendPlayerDetails(Play,pt,C_JOIN); - } - } - Play->EventNum=E_ARRIVE; - SendPlayerData(Play); - SendEvent(Play); - } else { -/* Message displayed in the server when too many players try to connect */ - dopelog(2,_("MaxClients (%d) exceeded - dropping connection"), - MaxClients); - if (MaxClients==1) { - text=g_strdup_printf( -/* Message sent to a player if the server is full */ - _("Sorry, but this server has a limit of 1 " - "player, which has been reached.^" - "Please try connecting again later.")); - } else { - text=g_strdup_printf( -/* Message sent to a player if the server is full */ - _("Sorry, but this server has a limit of %d " - "players, which has been reached.^" - "Please try connecting again later."),MaxClients); - } - SendServerMessage(NULL,C_NONE,C_PRINTMESSAGE,Play,text); - g_free(text); -/* Make sure they do actually disconnect, eventually! */ - if (ConnectTimeout) { - Play->ConnectTimeout=time(NULL)+(time_t)ConnectTimeout; - } - } - } else { -/* A player changed their name during the game (unusual, and not really - properly supported anyway) - notify all players of the change */ - dopelog(2,_("%s will now be known as %s"),GetPlayerName(Play),Data); - BroadcastToClients(C_NONE,C_RENAME,Data,Play,Play); - SetPlayerName(Play,Data); - } - break; - case C_WANTQUIT: - if (Play->EventNum!=E_FINISH) FinishGame(Play,NULL); - break; - case C_REQUESTJET: - i=atoi(Data); - if (Play->EventNum==E_FIGHT || Play->EventNum==E_FIGHTASK) { - if (CanRunHere(Play)) break; - else RunFromCombat(Play,i); - } - if (NumTurns>0 && Play->Turn>=NumTurns && Play->EventNum!=E_FINISH) { -/* Message displayed when a player reaches their maximum number of turns */ - FinishGame(Play,_("Your dealing time is up...")); - } else if (i!=Play->IsAt && (NumTurns==0 || Play->Turn<NumTurns) && - Play->EventNum==E_NONE && Play->Health>0) { - dopelog(4,"%s jets to %s",GetPlayerName(Play),Location[i].Name); - Play->IsAt=(char)i; - Play->Turn++; - Play->Debt=(price_t)((float)Play->Debt*1.1); - Play->Bank=(price_t)((float)Play->Bank*1.05); - SendPlayerData(Play); - Play->EventNum=E_SUBWAY; - SendEvent(Play); - } else { -/* A player has tried to jet to a new location, but we don't allow them to. - (e.g. they're still fighting someone, or they're supposed to be dead) */ - dopelog(3,_("%s: DENIED jet to %s"),GetPlayerName(Play), - Location[i].Name); - } - break; - case C_REQUESTSCORE: - SendHighScores(Play,FALSE,NULL); - break; - case C_CONTACTSPY: - for (list=FirstServer;list;list=g_slist_next(list)) { - tmp=(Player *)list->data; - i=GetListEntry(&(tmp->SpyList),Play); - if (tmp!=Play && i>=0 && tmp->SpyList.Data[i].Turns>=0) { - SendSpyReport(Play,tmp); - } +/* + * Sends details (name, ID) about player "Play" to player "To", using + * message code "Code". + */ +void SendPlayerDetails(Player *Play, Player *To, MsgCode Code) +{ + GString *text; + + text = g_string_new(GetPlayerName(Play)); + if (HaveAbility(To, A_PLAYERID)) { + g_string_sprintfa(text, "^%d", Play->ID); + } + SendServerMessage(NULL, C_NONE, Code, To, text->str); + g_string_free(text, TRUE); +} + +/* + * Given a message "buf", from player "Play", performs processing and + * sends suitable replies. + */ +void HandleServerMessage(gchar *buf, Player *Play) +{ + Player *To, *tmp, *pt; + GSList *list; + char *Data; + AICode AI; + MsgCode Code; + gchar *text; + DopeEntry NewEntry; + int i; + price_t money; + + if (ProcessMessage(buf, Play, &To, &AI, &Code, &Data, FirstServer) == -1) { + g_warning("Bad message"); + return; + } + switch (Code) { + case C_MSGTO: + if (Network) { + dopelog(3, "%s->%s: %s", GetPlayerName(Play), GetPlayerName(To), + Data); + } + SendServerMessage(Play, AI, Code, To, Data); + break; + case C_ABILITIES: + ReceiveAbilities(Play, Data); + break; + case C_NAME: + pt = GetPlayerByName(Data, FirstServer); + if (pt && pt != Play) { + if (ConnectTimeout) { + Play->ConnectTimeout = time(NULL) + (time_t) ConnectTimeout; + } + SendServerMessage(NULL, C_NONE, C_NEWNAME, Play, NULL); + } else if (strlen(GetPlayerName(Play)) == 0 && Data[0]) { + if (CountPlayers(FirstServer) < MaxClients || !Network) { + SendAbilities(Play); + CombineAbilities(Play); + SendInitialData(Play); + SendMiscData(Play); + SetPlayerName(Play, Data); + for (list = FirstServer; list; list = g_slist_next(list)) { + pt = (Player *)list->data; + if (pt != Play && IsConnectedPlayer(pt) && !IsCop(pt)) { + SendPlayerDetails(pt, Play, C_LIST); + } + } + SendServerMessage(NULL, C_NONE, C_ENDLIST, Play, NULL); + RegisterWithMetaServer(TRUE, FALSE, TRUE); + Play->ConnectTimeout = 0; + + if (Network) { + dopelog(2, _("%s joins the game!"), GetPlayerName(Play)); + } + for (list = FirstServer; list; list = g_slist_next(list)) { + pt = (Player *)list->data; + if (IsConnectedPlayer(pt) && pt != Play) { + SendPlayerDetails(Play, pt, C_JOIN); + } + } + Play->EventNum = E_ARRIVE; + SendPlayerData(Play); + SendEvent(Play); + } else { + /* Message displayed in the server when too many players try to + * connect */ + dopelog(2, _("MaxClients (%d) exceeded - dropping connection"), + MaxClients); + if (MaxClients == 1) { + text = g_strdup_printf( + /* Message sent to a player if the + * server is full */ + _("Sorry, but this server has a limit of " + "1 player, which has been reached.^" + "Please try connecting again later.")); + } else { + text = g_strdup_printf( + /* Message sent to a player if the + * server is full */ + _("Sorry, but this server has a limit of " + "%d players, which has been reached.^" + "Please try connecting again later."), + MaxClients); + } + SendServerMessage(NULL, C_NONE, C_PRINTMESSAGE, Play, text); + g_free(text); + /* Make sure they do actually disconnect, eventually! */ + if (ConnectTimeout) { + Play->ConnectTimeout = time(NULL) + (time_t) ConnectTimeout; } + } + } else { + /* A player changed their name during the game (unusual, and not + * really properly supported anyway) - notify all players of the + * change */ + dopelog(2, _("%s will now be known as %s"), GetPlayerName(Play), + Data); + BroadcastToClients(C_NONE, C_RENAME, Data, Play, Play); + SetPlayerName(Play, Data); + } + break; + case C_WANTQUIT: + if (Play->EventNum != E_FINISH) + FinishGame(Play, NULL); + break; + case C_REQUESTJET: + i = atoi(Data); + if (Play->EventNum == E_FIGHT || Play->EventNum == E_FIGHTASK) { + if (CanRunHere(Play)) break; - case C_DEPOSIT: - money=strtoprice(Data); - if (Play->Bank+money >=0 && Play->Cash-money >=0) { - Play->Bank+=money; Play->Cash-=money; - SendPlayerData(Play); - } - break; - case C_PAYLOAN: - money=strtoprice(Data); - if (Play->Debt-money >=0 && Play->Cash-money >=0) { - Play->Debt-=money; Play->Cash-=money; - SendPlayerData(Play); - } - break; - case C_BUYOBJECT: - BuyObject(Play,Data); - break; - case C_FIGHTACT: - if (Data[0]=='R') RunFromCombat(Play,-1); else Fire(Play); - break; - case C_ANSWER: - HandleAnswer(Play,To,Data); - break; - case C_DONE: - if (Play->EventNum!=E_NONE && Play->EventNum<E_OUTOFSYNC) { - Play->EventNum++; SendEvent(Play); - } - break; - case C_SPYON: - if (Play->Cash >= Prices.Spy) { - dopelog(3,_("%s now spying on %s"),GetPlayerName(Play), - GetPlayerName(To)); - Play->Cash -= Prices.Spy; - LoseBitch(Play,NULL,NULL); - NewEntry.Play=Play; NewEntry.Turns=-1; - AddListEntry(&(To->SpyList),&NewEntry); - SendPlayerData(Play); - } else { - g_warning(_("%s spy on %s: DENIED"),GetPlayerName(Play), - GetPlayerName(To)); - } - break; - case C_TIPOFF: - if (Play->Cash >= Prices.Tipoff) { - dopelog(3,_("%s tipped off the cops to %s"),GetPlayerName(Play), - GetPlayerName(To)); - Play->Cash -= Prices.Tipoff; - LoseBitch(Play,NULL,NULL); - NewEntry.Play=Play; NewEntry.Turns=0; - AddListEntry(&(To->TipList),&NewEntry); - SendPlayerData(Play); - } else { - g_warning(_("%s tipoff about %s: DENIED"),GetPlayerName(Play), - GetPlayerName(To)); - } - break; - case C_SACKBITCH: - if (Play->Bitches.Carried>0) { - LoseBitch(Play,NULL,NULL); - SendPlayerData(Play); - } - break; - case C_MSG: - if (Network) dopelog(3,"%s: %s",GetPlayerName(Play),Data); - BroadcastToClients(C_NONE,C_MSG,Data,Play,Play); - break; - default: - dopelog(0,_("Unknown message: %s:%c:%s:%s"),GetPlayerName(Play),Code, - GetPlayerName(To),Data); - break; - } -} - -void ClientLeftServer(Player *Play) { -/* Notifies all clients that player "Play" has left the game and */ -/* cleans up after them if necessary. */ - Player *tmp; - GSList *list; - - if (!IsConnectedPlayer(Play)) return; - - if (Play->EventNum==E_FIGHT || Play->EventNum==E_FIGHTASK) { - WithdrawFromCombat(Play); - } - for (list=FirstServer;list;list=g_slist_next(list)) { - tmp=(Player *)list->data; - if (tmp!=Play) { - RemoveAllEntries(&(tmp->TipList),Play); - RemoveAllEntries(&(tmp->SpyList),Play); + else + RunFromCombat(Play, i); + } + if (NumTurns > 0 && Play->Turn >= NumTurns + && Play->EventNum != E_FINISH) { + /* Message displayed when a player reaches their maximum number of + * turns */ + FinishGame(Play, _("Your dealing time is up...")); + } else if (i != Play->IsAt && (NumTurns == 0 || Play->Turn < NumTurns) + && Play->EventNum == E_NONE && Play->Health > 0) { + dopelog(4, "%s jets to %s", GetPlayerName(Play), Location[i].Name); + Play->IsAt = (char)i; + Play->Turn++; + Play->Debt = (price_t)((float)Play->Debt * 1.1); + Play->Bank = (price_t)((float)Play->Bank * 1.05); + SendPlayerData(Play); + Play->EventNum = E_SUBWAY; + SendEvent(Play); + } else { + /* A player has tried to jet to a new location, but we don't allow + * them to. (e.g. they're still fighting someone, or they're + * supposed to be dead) */ + dopelog(3, _("%s: DENIED jet to %s"), GetPlayerName(Play), + Location[i].Name); + } + break; + case C_REQUESTSCORE: + SendHighScores(Play, FALSE, NULL); + break; + case C_CONTACTSPY: + for (list = FirstServer; list; list = g_slist_next(list)) { + tmp = (Player *)list->data; + i = GetListEntry(&(tmp->SpyList), Play); + if (tmp != Play && i >= 0 && tmp->SpyList.Data[i].Turns >= 0) { + SendSpyReport(Play, tmp); } - } - BroadcastToClients(C_NONE,C_LEAVE,GetPlayerName(Play),Play,Play); + } + break; + case C_DEPOSIT: + money = strtoprice(Data); + if (Play->Bank + money >= 0 && Play->Cash - money >= 0) { + Play->Bank += money; + Play->Cash -= money; + SendPlayerData(Play); + } + break; + case C_PAYLOAN: + money = strtoprice(Data); + if (Play->Debt - money >= 0 && Play->Cash - money >= 0) { + Play->Debt -= money; + Play->Cash -= money; + SendPlayerData(Play); + } + break; + case C_BUYOBJECT: + BuyObject(Play, Data); + break; + case C_FIGHTACT: + if (Data[0] == 'R') + RunFromCombat(Play, -1); + else + Fire(Play); + break; + case C_ANSWER: + HandleAnswer(Play, To, Data); + break; + case C_DONE: + if (Play->EventNum != E_NONE && Play->EventNum < E_OUTOFSYNC) { + Play->EventNum++; + SendEvent(Play); + } + break; + case C_SPYON: + if (Play->Cash >= Prices.Spy) { + dopelog(3, _("%s now spying on %s"), GetPlayerName(Play), + GetPlayerName(To)); + Play->Cash -= Prices.Spy; + LoseBitch(Play, NULL, NULL); + NewEntry.Play = Play; + NewEntry.Turns = -1; + AddListEntry(&(To->SpyList), &NewEntry); + SendPlayerData(Play); + } else { + g_warning(_("%s spy on %s: DENIED"), GetPlayerName(Play), + GetPlayerName(To)); + } + break; + case C_TIPOFF: + if (Play->Cash >= Prices.Tipoff) { + dopelog(3, _("%s tipped off the cops to %s"), GetPlayerName(Play), + GetPlayerName(To)); + Play->Cash -= Prices.Tipoff; + LoseBitch(Play, NULL, NULL); + NewEntry.Play = Play; + NewEntry.Turns = 0; + AddListEntry(&(To->TipList), &NewEntry); + SendPlayerData(Play); + } else { + g_warning(_("%s tipoff about %s: DENIED"), GetPlayerName(Play), + GetPlayerName(To)); + } + break; + case C_SACKBITCH: + if (Play->Bitches.Carried > 0) { + LoseBitch(Play, NULL, NULL); + SendPlayerData(Play); + } + break; + case C_MSG: + if (Network) + dopelog(3, "%s: %s", GetPlayerName(Play), Data); + BroadcastToClients(C_NONE, C_MSG, Data, Play, Play); + break; + default: + dopelog(0, _("Unknown message: %s:%c:%s:%s"), GetPlayerName(Play), + Code, GetPlayerName(To), Data); + break; + } +} + +/* + * Notifies all clients that player "Play" has left the game and + * cleans up after them if necessary. + */ +void ClientLeftServer(Player *Play) +{ + Player *tmp; + GSList *list; + + if (!IsConnectedPlayer(Play)) + return; + + if (Play->EventNum == E_FIGHT || Play->EventNum == E_FIGHTASK) { + WithdrawFromCombat(Play); + } + for (list = FirstServer; list; list = g_slist_next(list)) { + tmp = (Player *)list->data; + if (tmp != Play) { + RemoveAllEntries(&(tmp->TipList), Play); + RemoveAllEntries(&(tmp->SpyList), Play); + } + } + BroadcastToClients(C_NONE, C_LEAVE, GetPlayerName(Play), Play, Play); } -void CleanUpServer() { -/* Closes down the server and frees up associated handles and memory */ - while (FirstServer) { - FirstServer=RemovePlayer((Player *)FirstServer->data,FirstServer); - } +/* + * Closes down the server and frees up associated handles and memory. + */ +void CleanUpServer() +{ + while (FirstServer) { + FirstServer = RemovePlayer((Player *)FirstServer->data, FirstServer); + } #if NETWORKING - if (Server) CloseSocket(ListenSock); + if (Server) + CloseSocket(ListenSock); #endif } -void ReregisterHandle(int sig) { -/* Responds to a SIGUSR1 signal, and requests the main event loop to */ -/* reregister the server with the dopewars metaserver. */ - ReregisterRequest=1; -} - -void RelogHandle(int sig) { -/* Responds to a SIGHUP signal, and requests the main event loop to - close and then reopen the log file (if any). */ - RelogRequest=1; -} - -void BreakHandle(int sig) { -/* Traps an attempt by the user to send dopewars a SIGTERM or SIGINT */ -/* (e.g. pressing Ctrl-C) and signals for a "nice" shutdown. Restores */ -/* the default signal action (to terminate without cleanup) so that */ -/* the user can still close the program easily if this cleanup code */ -/* then causes problems or long delays. */ - struct sigaction sact; - TerminateRequest=1; - sact.sa_handler=SIG_DFL; - sact.sa_flags=0; - sigaction(SIGTERM,&sact,NULL); - sigaction(SIGINT,&sact,NULL); -} - -void PrintHelpTo(FILE *fp) { -/* Prints the server help screen to the given file pointer */ - int i; - GString *VarName; - VarName=g_string_new(""); - fprintf(fp,_(HelpText),VERSION); - for (i=0;i<NUMGLOB;i++) { - if (Globals[i].NameStruct[0]) { - g_string_sprintf(VarName,"%s%s.%s",Globals[i].NameStruct, - Globals[i].StructListPt ? "[x]" : "",Globals[i].Name); - } else { - g_string_assign(VarName,Globals[i].Name); - } - fprintf(fp,"%-26s %s\n",VarName->str,_(Globals[i].Help)); - } - fprintf(fp,"\n\n"); - g_string_free(VarName,TRUE); +/* + * Responds to a SIGUSR1 signal, and requests the main event loop to + * reregister the server with the dopewars metaserver. + */ +void ReregisterHandle(int sig) +{ + ReregisterRequest = 1; +} + +/* + * Responds to a SIGHUP signal, and requests the main event loop to + * close and then reopen the log file (if any). + */ +void RelogHandle(int sig) +{ + RelogRequest = 1; +} + +/* + * Traps an attempt by the user to send dopewars a SIGTERM or SIGINT + * (e.g. pressing Ctrl-C) and signals for a "nice" shutdown. Restores + * the default signal action (to terminate without cleanup) so that + * the user can still close the program easily if this cleanup code + * then causes problems or long delays. + */ +void BreakHandle(int sig) +{ + struct sigaction sact; + + TerminateRequest = 1; + sact.sa_handler = SIG_DFL; + sact.sa_flags = 0; + sigaction(SIGTERM, &sact, NULL); + sigaction(SIGINT, &sact, NULL); +} + +/* + * Prints the server help screen to the given file pointer. + */ +void PrintHelpTo(FILE *fp) +{ + int i; + GString *VarName; + + VarName = g_string_new(""); + fprintf(fp, _(HelpText), VERSION); + for (i = 0; i < NUMGLOB; i++) { + if (Globals[i].NameStruct[0]) { + g_string_sprintf(VarName, "%s%s.%s", Globals[i].NameStruct, + Globals[i].StructListPt ? "[x]" : "", + Globals[i].Name); + } else { + g_string_assign(VarName, Globals[i].Name); + } + fprintf(fp, "%-26s %s\n", VarName->str, _(Globals[i].Help)); + } + fprintf(fp, "\n\n"); + g_string_free(VarName, TRUE); } static NetworkBuffer *reply_netbuf; -static void ServerReply(const gchar *msg) { +static void ServerReply(const gchar *msg) +{ int msglen; gchar *msgcp; if (reply_netbuf) { - msglen=strlen(msg); - while (msglen>0 && msg[msglen-1]=='\n') msglen--; - if (msglen>0) { - msgcp = g_strndup(msg,msglen); - QueueMessageForSend(reply_netbuf,msgcp); + msglen = strlen(msg); + while (msglen > 0 && msg[msglen - 1] == '\n') + msglen--; + if (msglen > 0) { + msgcp = g_strndup(msg, msglen); + QueueMessageForSend(reply_netbuf, msgcp); g_free(msgcp); } - } else g_print(msg); + } else + g_print(msg); } -void ServerHelp(void) { -/* Displays a simple help screen listing the server commands and options */ +/* + * Displays a simple help screen listing the server commands and options. + */ +void ServerHelp(void) +{ int i; GString *VarName; - VarName=g_string_new(""); - g_print(_(HelpText),VERSION); - for (i=0;i<NUMGLOB;i++) { + + VarName = g_string_new(""); + g_print(_(HelpText), VERSION); + for (i = 0; i < NUMGLOB; i++) { if (Globals[i].NameStruct[0]) { - g_string_sprintf(VarName,"%s%s.%s",Globals[i].NameStruct, - Globals[i].StructListPt ? "[x]" : "",Globals[i].Name); + g_string_sprintf(VarName, "%s%s.%s", Globals[i].NameStruct, + Globals[i].StructListPt ? "[x]" : "", + Globals[i].Name); } else { - g_string_assign(VarName,Globals[i].Name); + g_string_assign(VarName, Globals[i].Name); } - g_print("%-26s\t%s\n",VarName->str,_(Globals[i].Help)); + g_print("%-26s\t%s\n", VarName->str, _(Globals[i].Help)); } - g_string_free(VarName,TRUE); + g_string_free(VarName, TRUE); } #if NETWORKING -void CreatePidFile(void) { -/* Creates a pid file (if "PidFile" is non-NULL) and writes the process */ -/* ID into it */ - FILE *fp; - char *OpenError; - if (!PidFile) return; - fp=fopen(PidFile,"w"); - if (fp) { - dopelog(1,_("Maintaining pid file %s"),PidFile); - fprintf(fp,"%ld\n",(long)getpid()); - fclose(fp); - chmod(PidFile,S_IREAD|S_IWRITE); - } else { - OpenError=strerror(errno); - g_warning(_("Cannot create pid file %s: %s"),PidFile,OpenError); - } -} - -void RemovePidFile(void) { -/* Removes the previously-created pid file "PidFile" */ - if (PidFile) unlink(PidFile); -} - -static gboolean StartServer(void) { - LastError *sockerr=NULL; - GString *errstr; +/* + * Creates a pid file (if "PidFile" is non-NULL) and writes the process + * ID into it. + */ +void CreatePidFile(void) +{ + FILE *fp; + char *OpenError; + + if (!PidFile) + return; + fp = fopen(PidFile, "w"); + if (fp) { + dopelog(1, _("Maintaining pid file %s"), PidFile); + fprintf(fp, "%ld\n", (long)getpid()); + fclose(fp); + chmod(PidFile, S_IREAD | S_IWRITE); + } else { + OpenError = strerror(errno); + g_warning(_("Cannot create pid file %s: %s"), PidFile, OpenError); + } +} + +/* + * Removes the previously-created pid file "PidFile". + */ +void RemovePidFile(void) +{ + if (PidFile) + unlink(PidFile); +} + +static gboolean StartServer(void) +{ + LastError *sockerr = NULL; + GString *errstr; + #ifndef CYGWIN - struct sigaction sact; + struct sigaction sact; #else - SERVICE_STATUS status; + SERVICE_STATUS status; #endif - if (!CheckHighScoreFileConfig()) return FALSE; - Scanner=g_scanner_new(&ScannerConfig); - Scanner->msg_handler=ScannerErrorHandler; - Scanner->input_name="(stdin)"; - CreatePidFile(); - -/* Make the output line-buffered, so that the log file (if used) is */ -/* updated regularly */ - fflush(stdout); - -#ifdef SETVBUF_REVERSED /* 2nd and 3rd arguments are reversed on some systems */ - setvbuf(stdout,_IOLBF,(char *)NULL,0); + if (!CheckHighScoreFileConfig()) + return FALSE; + Scanner = g_scanner_new(&ScannerConfig); + Scanner->msg_handler = ScannerErrorHandler; + Scanner->input_name = "(stdin)"; + CreatePidFile(); + + /* Make the output line-buffered, so that the log file (if used) is + * updated regularly */ + fflush(stdout); + +#ifdef SETVBUF_REVERSED /* 2nd and 3rd arguments are reversed on + * some systems */ + setvbuf(stdout, _IOLBF, (char *)NULL, 0); #else - setvbuf(stdout,(char *)NULL,_IOLBF,0); + setvbuf(stdout, (char *)NULL, _IOLBF, 0); #endif - Network=TRUE; - FirstServer=NULL; - ClientMessageHandlerPt=NULL; - ListenSock=CreateTCPSocket(&sockerr); - if (ListenSock==SOCKET_ERROR) { - errstr=g_string_new(""); - g_string_assign_error(errstr,sockerr); - g_log(NULL,G_LOG_LEVEL_CRITICAL, - _("Cannot create server (listening) socket (%s) Aborting."), - errstr->str); - g_string_free(errstr,TRUE); - FreeError(sockerr); - exit(1); - } - -/* This doesn't seem to work properly under Win32 */ + Network = TRUE; + FirstServer = NULL; + ClientMessageHandlerPt = NULL; + ListenSock = CreateTCPSocket(&sockerr); + if (ListenSock == SOCKET_ERROR) { + errstr = g_string_new(""); + g_string_assign_error(errstr, sockerr); + g_log(NULL, G_LOG_LEVEL_CRITICAL, + _("Cannot create server (listening) socket (%s) Aborting."), + errstr->str); + g_string_free(errstr, TRUE); + FreeError(sockerr); + exit(1); + } + + /* This doesn't seem to work properly under Win32 */ #ifndef CYGWIN - SetReuse(ListenSock); + SetReuse(ListenSock); #endif - SetBlocking(ListenSock,FALSE); + SetBlocking(ListenSock, FALSE); - if (!BindTCPSocket(ListenSock,Port,&sockerr)) { - errstr=g_string_new(""); - g_string_assign_error(errstr,sockerr); - g_log(NULL,G_LOG_LEVEL_CRITICAL, - _("Cannot bind to port %u (%s) Aborting."), - Port,errstr->str); - g_string_free(errstr,TRUE); - FreeError(sockerr); - exit(1); - } + if (!BindTCPSocket(ListenSock, Port, &sockerr)) { + errstr = g_string_new(""); + g_string_assign_error(errstr, sockerr); + g_log(NULL, G_LOG_LEVEL_CRITICAL, + _("Cannot bind to port %u (%s) Aborting."), Port, errstr->str); + g_string_free(errstr, TRUE); + FreeError(sockerr); + exit(1); + } - if (listen(ListenSock,10)==SOCKET_ERROR) { - g_log(NULL,G_LOG_LEVEL_CRITICAL, - _("Cannot listen to network socket. Aborting.")); - exit(1); - } + if (listen(ListenSock, 10) == SOCKET_ERROR) { + g_log(NULL, G_LOG_LEVEL_CRITICAL, + _("Cannot listen to network socket. Aborting.")); + exit(1); + } -/* Initial startup message for the server */ - dopelog(0,_("dopewars server version %s ready and waiting for " - "connections on port %d."),VERSION,Port); + /* Initial startup message for the server */ + dopelog(0, _("dopewars server version %s ready and waiting for " + "connections on port %d."), VERSION, Port); - MetaUpdateTimeout=MetaMinTimeout=0; + MetaUpdateTimeout = MetaMinTimeout = 0; - TerminateRequest=ReregisterRequest=RelogRequest=0; + TerminateRequest = ReregisterRequest = RelogRequest = 0; #if !CYGWIN - sact.sa_handler=ReregisterHandle; - sact.sa_flags=0; - sigemptyset(&sact.sa_mask); - if (sigaction(SIGUSR1,&sact,NULL)==-1) { -/* Warning messages displayed if we fail to trap various signals */ - g_warning(_("Cannot install SIGUSR1 interrupt handler!")); - } - sact.sa_handler=RelogHandle; - sact.sa_flags=0; - sigemptyset(&sact.sa_mask); - if (sigaction(SIGHUP,&sact,NULL)==-1) { - g_warning(_("Cannot install SIGHUP interrupt handler!")); - } - sact.sa_handler=BreakHandle; - sact.sa_flags=0; - sigemptyset(&sact.sa_mask); - if (sigaction(SIGINT,&sact,NULL)==-1) { - g_warning(_("Cannot install SIGINT interrupt handler!")); - } - if (sigaction(SIGTERM,&sact,NULL)==-1) { - g_warning(_("Cannot install SIGTERM interrupt handler!")); - } - sact.sa_handler=SIG_IGN; - sact.sa_flags=0; - if (sigaction(SIGPIPE,&sact,NULL)==-1) { - g_warning(_("Cannot install pipe handler!")); - } + sact.sa_handler = ReregisterHandle; + sact.sa_flags = 0; + sigemptyset(&sact.sa_mask); + if (sigaction(SIGUSR1, &sact, NULL) == -1) { + /* Warning messages displayed if we fail to trap various signals */ + g_warning(_("Cannot install SIGUSR1 interrupt handler!")); + } + sact.sa_handler = RelogHandle; + sact.sa_flags = 0; + sigemptyset(&sact.sa_mask); + if (sigaction(SIGHUP, &sact, NULL) == -1) { + g_warning(_("Cannot install SIGHUP interrupt handler!")); + } + sact.sa_handler = BreakHandle; + sact.sa_flags = 0; + sigemptyset(&sact.sa_mask); + if (sigaction(SIGINT, &sact, NULL) == -1) { + g_warning(_("Cannot install SIGINT interrupt handler!")); + } + if (sigaction(SIGTERM, &sact, NULL) == -1) { + g_warning(_("Cannot install SIGTERM interrupt handler!")); + } + sact.sa_handler = SIG_IGN; + sact.sa_flags = 0; + if (sigaction(SIGPIPE, &sact, NULL) == -1) { + g_warning(_("Cannot install pipe handler!")); + } #endif - RegisterWithMetaServer(TRUE,TRUE,FALSE); - return TRUE; -} - -void RequestServerShutdown(void) { -/* Begin the process of shutting down the server. In order to do this, */ -/* we need to log out all of the currently connected players, and tell */ -/* the metaserver that we're shutting down. We only shut down properly */ -/* once all of these messages have been completely sent and */ -/* acknowledged. (Of course, this can be overridden by a SIGINT or */ -/* similar in the case of unresponsive players.) */ - RegisterWithMetaServer(FALSE,FALSE,FALSE); - BroadcastToClients(C_NONE,C_QUIT,NULL,NULL,NULL); - WantQuit=TRUE; -} - -gboolean IsServerShutdown(void) { -/* Returns TRUE if the actions initiated by RequestServerShutdown() */ -/* have been successfully completed, such that we can shut down the */ -/* server properly now. */ - return (WantQuit && !FirstServer && !MetaConn); + RegisterWithMetaServer(TRUE, TRUE, FALSE); + return TRUE; } -static GPrintFunc StartServerReply(NetworkBuffer *netbuf) { +/* + * Begin the process of shutting down the server. In order to do this, + * we need to log out all of the currently connected players, and tell + * the metaserver that we're shutting down. We only shut down properly + * once all of these messages have been completely sent and + * acknowledged. (Of course, this can be overridden by a SIGINT or + * similar in the case of unresponsive players.) + */ +void RequestServerShutdown(void) +{ + RegisterWithMetaServer(FALSE, FALSE, FALSE); + BroadcastToClients(C_NONE, C_QUIT, NULL, NULL, NULL); + WantQuit = TRUE; +} + +/* + * Returns TRUE if the actions initiated by RequestServerShutdown() + * have been successfully completed, such that we can shut down the + * server properly now. + */ +gboolean IsServerShutdown(void) +{ + return (WantQuit && !FirstServer && !MetaConn); +} + +static GPrintFunc StartServerReply(NetworkBuffer *netbuf) +{ reply_netbuf = netbuf; - if (netbuf) return g_set_print_handler(ServerReply); - else return NULL; -} - -static void FinishServerReply(GPrintFunc oldprint) { - if (oldprint) g_set_print_handler(oldprint); -} - -static void HandleServerCommand(char *string,NetworkBuffer *netbuf) { - GSList *list; - Player *tmp; - GPrintFunc oldprint; - - oldprint = StartServerReply(netbuf); - - g_scanner_input_text(Scanner,string,strlen(string)); - if (!ParseNextConfig(Scanner,TRUE)) { - if (g_strcasecmp(string,"help")==0 || g_strcasecmp(string,"h")==0 || - strcmp(string,"?")==0) { - ServerHelp(); - } else if (g_strcasecmp(string,"quit")==0) { - RequestServerShutdown(); - } else if (g_strncasecmp(string,"msg:",4)==0) { - BroadcastToClients(C_NONE,C_MSG,string+4,NULL,NULL); - } else if (g_strcasecmp(string,"list")==0) { - if (FirstServer) { - g_print(_("Users currently logged on:-\n")); - for (list=FirstServer;list;list=g_slist_next(list)) { - tmp=(Player *)list->data; - if (!IsCop(tmp)) { - g_print("%s\n",GetPlayerName(tmp)); - } - } - } else g_print(_("No users currently logged on!\n")); - } else if (g_strncasecmp(string,"push ",5)==0) { - tmp=GetPlayerByName(string+5,FirstServer); - if (tmp) { - g_print(_("Pushing %s\n"),GetPlayerName(tmp)); - SendServerMessage(NULL,C_NONE,C_PUSH,tmp,NULL); - } else g_print(_("No such user!\n")); - } else if (g_strncasecmp(string,"kill ",5)==0) { - tmp=GetPlayerByName(string+5,FirstServer); - if (tmp) { - g_print(_("%s killed\n"),GetPlayerName(tmp)); - BroadcastToClients(C_NONE,C_KILL,GetPlayerName(tmp),tmp, - (Player *)FirstServer->data); - FirstServer=RemovePlayer(tmp,FirstServer); - } else g_print(_("No such user!\n")); - } else { - g_print(_("Unknown command - try \"help\" for help...\n")); - } - } - FinishServerReply(oldprint); -} - -Player *HandleNewConnection(void) { - int cadsize; - int ClientSock; - struct sockaddr_in ClientAddr; - Player *tmp; - cadsize=sizeof(struct sockaddr); - if ((ClientSock=accept(ListenSock,(struct sockaddr *)&ClientAddr, - &cadsize))==-1) { - perror("accept socket"); bgetch(); exit(1); - } - dopelog(2,_("got connection from %s"),inet_ntoa(ClientAddr.sin_addr)); - tmp=g_new(Player,1); - FirstServer=AddPlayer(ClientSock,tmp,FirstServer); - if (ConnectTimeout) { - tmp->ConnectTimeout=time(NULL)+(time_t)ConnectTimeout; - } - return tmp; -} - -void StopServer() { - dopelog(0,_("dopewars server terminating.")); - g_scanner_destroy(Scanner); - CleanUpServer(); - RemovePidFile(); -} - -void RemovePlayerFromServer(Player *Play) { - if (!WantQuit && strlen(GetPlayerName(Play))>0) { - dopelog(2,_("%s leaves the server!"),GetPlayerName(Play)); - ClientLeftServer(Play); -/* Blank the name, so that CountPlayers ignores this player */ - SetPlayerName(Play,NULL); -/* Report the new high scores (if any) and the new number of players - to the metaserver */ - RegisterWithMetaServer(TRUE,TRUE,TRUE); - } - FirstServer=RemovePlayer(Play,FirstServer); + if (netbuf) + return g_set_print_handler(ServerReply); + else + return NULL; +} + +static void FinishServerReply(GPrintFunc oldprint) +{ + if (oldprint) + g_set_print_handler(oldprint); +} + +static void HandleServerCommand(char *string, NetworkBuffer *netbuf) +{ + GSList *list; + Player *tmp; + GPrintFunc oldprint; + + oldprint = StartServerReply(netbuf); + + g_scanner_input_text(Scanner, string, strlen(string)); + if (!ParseNextConfig(Scanner, TRUE)) { + if (g_strcasecmp(string, "help") == 0 || g_strcasecmp(string, "h") == 0 + || strcmp(string, "?") == 0) { + ServerHelp(); + } else if (g_strcasecmp(string, "quit") == 0) { + RequestServerShutdown(); + } else if (g_strncasecmp(string, "msg:", 4) == 0) { + BroadcastToClients(C_NONE, C_MSG, string + 4, NULL, NULL); + } else if (g_strcasecmp(string, "list") == 0) { + if (FirstServer) { + g_print(_("Users currently logged on:-\n")); + for (list = FirstServer; list; list = g_slist_next(list)) { + tmp = (Player *)list->data; + if (!IsCop(tmp)) { + g_print("%s\n", GetPlayerName(tmp)); + } + } + } else + g_print(_("No users currently logged on!\n")); + } else if (g_strncasecmp(string, "push ", 5) == 0) { + tmp = GetPlayerByName(string + 5, FirstServer); + if (tmp) { + g_print(_("Pushing %s\n"), GetPlayerName(tmp)); + SendServerMessage(NULL, C_NONE, C_PUSH, tmp, NULL); + } else + g_print(_("No such user!\n")); + } else if (g_strncasecmp(string, "kill ", 5) == 0) { + tmp = GetPlayerByName(string + 5, FirstServer); + if (tmp) { + g_print(_("%s killed\n"), GetPlayerName(tmp)); + BroadcastToClients(C_NONE, C_KILL, GetPlayerName(tmp), tmp, + (Player *)FirstServer->data); + FirstServer = RemovePlayer(tmp, FirstServer); + } else + g_print(_("No such user!\n")); + } else { + g_print(_("Unknown command - try \"help\" for help...\n")); + } + } + FinishServerReply(oldprint); +} + +Player *HandleNewConnection(void) +{ + int cadsize; + int ClientSock; + struct sockaddr_in ClientAddr; + Player *tmp; + cadsize = sizeof(struct sockaddr); + if ((ClientSock = accept(ListenSock, (struct sockaddr *)&ClientAddr, + &cadsize)) == -1) { + perror("accept socket"); + bgetch(); + exit(1); + } + dopelog(2, _("got connection from %s"), inet_ntoa(ClientAddr.sin_addr)); + tmp = g_new(Player, 1); + + FirstServer = AddPlayer(ClientSock, tmp, FirstServer); + if (ConnectTimeout) { + tmp->ConnectTimeout = time(NULL) + (time_t) ConnectTimeout; + } + return tmp; +} + +void StopServer() +{ + dopelog(0, _("dopewars server terminating.")); + g_scanner_destroy(Scanner); + CleanUpServer(); + RemovePidFile(); +} + +void RemovePlayerFromServer(Player *Play) +{ + if (!WantQuit && strlen(GetPlayerName(Play)) > 0) { + dopelog(2, _("%s leaves the server!"), GetPlayerName(Play)); + ClientLeftServer(Play); + /* Blank the name, so that CountPlayers ignores this player */ + SetPlayerName(Play, NULL); + /* Report the new high scores (if any) and the new number of players + * to the metaserver */ + RegisterWithMetaServer(TRUE, TRUE, TRUE); + } + FirstServer = RemovePlayer(Play, FirstServer); } #ifndef CYGWIN static gchar sockdir[] = "/tmp/.dopewars/"; -gchar *GetLocalSocket(void) { - return g_strdup_printf("%ssocket-%u",sockdir,Port); +gchar *GetLocalSocket(void) +{ + return g_strdup_printf("%ssocket-%u", sockdir, Port); } -static void CloseLocalSocket(int localsock) { +static void CloseLocalSocket(int localsock) +{ gchar *sockname; - if (localsock>=0) close(localsock); + if (localsock >= 0) + close(localsock); - sockname=GetLocalSocket(); + sockname = GetLocalSocket(); unlink(sockname); rmdir(sockdir); g_free(sockname); } -static int SetupLocalSocket(void) { +static int SetupLocalSocket(void) +{ int sock; struct sockaddr_un addr; gchar *sockname; CloseLocalSocket(-1); - sock = socket(PF_UNIX,SOCK_STREAM,0); - if (sock==-1) return -1; + sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (sock == -1) + return -1; - SetBlocking(sock,FALSE); + SetBlocking(sock, FALSE); - sockname=GetLocalSocket(); - mkdir(sockdir,S_IRUSR|S_IWUSR|S_IXUSR); + sockname = GetLocalSocket(); + mkdir(sockdir, S_IRUSR | S_IWUSR | S_IXUSR); addr.sun_family = AF_UNIX; - strncpy(addr.sun_path,sockname,sizeof(addr.sun_path)); - addr.sun_path[sizeof(addr.sun_path)-1]='\0'; + strncpy(addr.sun_path, sockname, sizeof(addr.sun_path)); + addr.sun_path[sizeof(addr.sun_path) - 1] = '\0'; - bind(sock,(struct sockaddr *)&addr,sizeof(struct sockaddr_un)); + bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)); - chmod(sockname,S_IRUSR|S_IWUSR); + chmod(sockname, S_IRUSR | S_IWUSR); g_free(sockname); - listen(sock,10); - + listen(sock, 10); + return sock; } #endif -void ServerLoop() { -/* Initialises server, processes network and interactive messages, and */ -/* finally cleans up the server on exit. */ - Player *tmp; - GSList *list,*nextlist,*localconn=NULL; - fd_set readfs,writefs,errorfs; - int topsock; - GPrintFunc oldprint; - struct timeval timeout; - int MinTimeout; - GString *LineBuf; - gboolean DoneOK; - gchar *buf; +/* + * Initialises server, processes network and interactive messages, and + * finally cleans up the server on exit. + */ +void ServerLoop() +{ + Player *tmp; + GSList *list, *nextlist, *localconn = NULL; + fd_set readfs, writefs, errorfs; + int topsock; + GPrintFunc oldprint; + struct timeval timeout; + int MinTimeout; + GString *LineBuf; + gboolean DoneOK; + gchar *buf; + #ifndef CYGWIN - int localsock; + int localsock; #endif - if (!StartServer()) return; + if (!StartServer()) + return; #ifdef HAVE_FORK -/* Daemonize; continue if the fork was successful and we are the child, or - if the fork failed */ - if (Daemonize && fork()>0) return; + /* Daemonize; continue if the fork was successful and we are the child, + * or if the fork failed */ + if (Daemonize && fork() > 0) + return; #endif #ifndef CYGWIN - localsock=SetupLocalSocket(); + localsock = SetupLocalSocket(); #endif - LineBuf=g_string_new(""); - while (1) { - FD_ZERO(&readfs); - FD_ZERO(&writefs); - FD_ZERO(&errorfs); - FD_SET(ListenSock,&readfs); - FD_SET(ListenSock,&errorfs); - topsock=ListenSock+1; + LineBuf = g_string_new(""); + while (1) { + FD_ZERO(&readfs); + FD_ZERO(&writefs); + FD_ZERO(&errorfs); + FD_SET(ListenSock, &readfs); + FD_SET(ListenSock, &errorfs); + topsock = ListenSock + 1; #ifndef CYGWIN - FD_SET(localsock,&readfs); - topsock=MAX(topsock,localsock+1); - for (list=localconn;list;list=g_slist_next(list)) { - NetworkBuffer *netbuf; - netbuf = (NetworkBuffer *)list->data; - SetSelectForNetworkBuffer(netbuf,&readfs,&writefs,&errorfs,&topsock); - } + FD_SET(localsock, &readfs); + topsock = MAX(topsock, localsock + 1); + for (list = localconn; list; list = g_slist_next(list)) { + NetworkBuffer *netbuf; + + netbuf = (NetworkBuffer *)list->data; + SetSelectForNetworkBuffer(netbuf, &readfs, &writefs, &errorfs, + &topsock); + } #endif - if (MetaConn) { - SetSelectForNetworkBuffer(&MetaConn->NetBuf,&readfs,&writefs, - &errorfs,&topsock); - } - for (list=FirstServer;list;list=g_slist_next(list)) { - tmp=(Player *)list->data; - if (!IsCop(tmp)) { - SetSelectForNetworkBuffer(&tmp->NetBuf,&readfs,&writefs, - &errorfs,&topsock); - } - } - MinTimeout=GetMinimumTimeout(FirstServer); - if (MinTimeout!=-1) { - timeout.tv_sec=MinTimeout; - timeout.tv_usec=0; - } - if (select(topsock,&readfs,&writefs,&errorfs, - MinTimeout==-1 ? NULL : &timeout)==-1) { - if (errno==EINTR) { - if (ReregisterRequest) { - ReregisterRequest=0; - RegisterWithMetaServer(TRUE,TRUE,FALSE); - continue; - } else if (TerminateRequest) { - TerminateRequest=0; - RequestServerShutdown(); - if (IsServerShutdown()) break; - else continue; - } else if (RelogRequest) { /* Re-open log file */ - RelogRequest=0; - CloseLog(); - OpenLog(); - continue; - } else continue; - } - perror("select"); bgetch(); break; + if (MetaConn) { + SetSelectForNetworkBuffer(&MetaConn->NetBuf, &readfs, &writefs, + &errorfs, &topsock); + } + for (list = FirstServer; list; list = g_slist_next(list)) { + tmp = (Player *)list->data; + if (!IsCop(tmp)) { + SetSelectForNetworkBuffer(&tmp->NetBuf, &readfs, &writefs, + &errorfs, &topsock); } - FirstServer=HandleTimeouts(FirstServer); - if (FD_ISSET(ListenSock,&readfs)) { - HandleNewConnection(); + } + MinTimeout = GetMinimumTimeout(FirstServer); + if (MinTimeout != -1) { + timeout.tv_sec = MinTimeout; + timeout.tv_usec = 0; + } + if (select(topsock, &readfs, &writefs, &errorfs, + MinTimeout == -1 ? NULL : &timeout) == -1) { + if (errno == EINTR) { + if (ReregisterRequest) { + ReregisterRequest = 0; + RegisterWithMetaServer(TRUE, TRUE, FALSE); + continue; + } else if (TerminateRequest) { + TerminateRequest = 0; + RequestServerShutdown(); + if (IsServerShutdown()) + break; + else + continue; + } else if (RelogRequest) { /* Re-open log file */ + RelogRequest = 0; + CloseLog(); + OpenLog(); + continue; + } else + continue; } + perror("select"); + bgetch(); + break; + } + FirstServer = HandleTimeouts(FirstServer); + if (FD_ISSET(ListenSock, &readfs)) { + HandleNewConnection(); + } #ifndef CYGWIN - if (FD_ISSET(localsock,&readfs)) { - int newlocal; - NetworkBuffer *netbuf; - newlocal = accept(localsock,NULL,NULL); - netbuf=g_new(NetworkBuffer,1); - InitNetworkBuffer(netbuf,'\n','\r',NULL); - BindNetworkBufferToSocket(netbuf,newlocal); - localconn = g_slist_append(localconn,netbuf); - oldprint = StartServerReply(netbuf); - g_print(_("dopewars server version %s ready for admin commands; " - "try \"help\" for help"),VERSION); - FinishServerReply(oldprint); - dopelog(1,_("New admin connection")); - } - list=localconn; - while (list) { - NetworkBuffer *netbuf; - nextlist=g_slist_next(list); - netbuf = (NetworkBuffer *)list->data; - if (netbuf) { - if (RespondToSelect(netbuf,&readfs,&writefs,&errorfs,&DoneOK)) { - while((buf=GetWaitingMessage(netbuf))!=NULL) { - dopelog(2,_("Admin command: %s"),buf); - HandleServerCommand(buf,netbuf); - g_free(buf); - } - } - if (!DoneOK) { - dopelog(1,_("Admin connection closed")); - localconn = g_slist_remove(localconn,netbuf); - ShutdownNetworkBuffer(netbuf); - g_free(netbuf); + if (FD_ISSET(localsock, &readfs)) { + int newlocal; + NetworkBuffer *netbuf; + + newlocal = accept(localsock, NULL, NULL); + netbuf = g_new(NetworkBuffer, 1); + + InitNetworkBuffer(netbuf, '\n', '\r', NULL); + BindNetworkBufferToSocket(netbuf, newlocal); + localconn = g_slist_append(localconn, netbuf); + oldprint = StartServerReply(netbuf); + g_print(_("dopewars server version %s ready for admin commands; " + "try \"help\" for help"), VERSION); + FinishServerReply(oldprint); + dopelog(1, _("New admin connection")); + } + list = localconn; + while (list) { + NetworkBuffer *netbuf; + + nextlist = g_slist_next(list); + netbuf = (NetworkBuffer *)list->data; + if (netbuf) { + if (RespondToSelect(netbuf, &readfs, &writefs, &errorfs, &DoneOK)) { + while ((buf = GetWaitingMessage(netbuf)) != NULL) { + dopelog(2, _("Admin command: %s"), buf); + HandleServerCommand(buf, netbuf); + g_free(buf); } - list=nextlist; } + if (!DoneOK) { + dopelog(1, _("Admin connection closed")); + localconn = g_slist_remove(localconn, netbuf); + ShutdownNetworkBuffer(netbuf); + g_free(netbuf); + } + list = nextlist; } - if (IsServerShutdown()) break; + } + if (IsServerShutdown()) + break; #endif - if (MetaConn) { - if (RespondToSelect(&MetaConn->NetBuf,&readfs,&writefs, - &errorfs,&DoneOK)) { - while ((buf=ReadHttpResponse(MetaConn,&DoneOK))) { - gboolean ReadingBody = (MetaConn->Status==HS_READBODY); - if (buf[0] || !ReadingBody) { - dopelog(ReadingBody ? 2 : 4,"MetaServer: %s",buf); - } - g_free(buf); - } - } - if (!DoneOK && HandleHttpCompletion(MetaConn)) { - if (!MetaConnectError(MetaConn)) { - dopelog(4,"MetaServer: (closed)\n"); - } - CloseHttpConnection(MetaConn); MetaConn=NULL; - if (IsServerShutdown()) break; - } + if (MetaConn) { + if (RespondToSelect(&MetaConn->NetBuf, &readfs, &writefs, + &errorfs, &DoneOK)) { + while ((buf = ReadHttpResponse(MetaConn, &DoneOK))) { + gboolean ReadingBody = (MetaConn->Status == HS_READBODY); + + if (buf[0] || !ReadingBody) { + dopelog(ReadingBody ? 2 : 4, "MetaServer: %s", buf); + } + g_free(buf); + } + } + if (!DoneOK && HandleHttpCompletion(MetaConn)) { + if (!MetaConnectError(MetaConn)) { + dopelog(4, "MetaServer: (closed)\n"); + } + CloseHttpConnection(MetaConn); + MetaConn = NULL; + if (IsServerShutdown()) + break; } - list=FirstServer; - while (list) { - nextlist=g_slist_next(list); - tmp=(Player *)list->data; - if (tmp) { - if (RespondToSelect(&tmp->NetBuf,&readfs,&writefs, - &errorfs,&DoneOK)) { -/* If any complete messages were read, process them */ - HandleServerPlayer(tmp); - } - if (!DoneOK) { -/* The socket has been shut down, or the buffer was filled - remove player */ - RemovePlayerFromServer(tmp); - if (IsServerShutdown()) break; - tmp=NULL; - } - } - list=nextlist; + } + list = FirstServer; + while (list) { + nextlist = g_slist_next(list); + tmp = (Player *)list->data; + if (tmp) { + if (RespondToSelect(&tmp->NetBuf, &readfs, &writefs, + &errorfs, &DoneOK)) { + /* If any complete messages were read, process them */ + HandleServerPlayer(tmp); + } + if (!DoneOK) { + /* The socket has been shut down, or the buffer was filled - + * remove player */ + RemovePlayerFromServer(tmp); + if (IsServerShutdown()) + break; + tmp = NULL; + } } - if (list && IsServerShutdown()) break; - } + list = nextlist; + } + if (list && IsServerShutdown()) + break; + } #ifndef CYGWIN - CloseLocalSocket(localsock); + CloseLocalSocket(localsock); #endif - StopServer(); - g_string_free(LineBuf,TRUE); + StopServer(); + g_string_free(LineBuf, TRUE); } #ifdef GUI_SERVER static GtkWidget *TextOutput; -static gint ListenTag=0; -static void SocketStatus(NetworkBuffer *NetBuf,gboolean Read,gboolean Write, - gboolean CallNow); +static gint ListenTag = 0; +static void SocketStatus(NetworkBuffer *NetBuf, gboolean Read, + gboolean Write, gboolean CallNow); static void GuiSetTimeouts(void); -static time_t NextTimeout=0; -static guint TimeoutTag=0; - -static gint GuiDoTimeouts(gpointer data) { -/* Forget the TimeoutTag so that GuiSetTimeouts doesn't delete it - it'll be - deleted automatically anyway when we return FALSE */ - TimeoutTag=0; - NextTimeout=0; - - FirstServer=HandleTimeouts(FirstServer); - GuiSetTimeouts(); - return FALSE; -} - -void GuiSetTimeouts(void) { - int MinTimeout; - time_t TimeNow; - TimeNow=time(NULL); - MinTimeout=GetMinimumTimeout(FirstServer); - if (TimeNow+MinTimeout < NextTimeout || NextTimeout<TimeNow) { - if (TimeoutTag>0) gtk_timeout_remove(TimeoutTag); - TimeoutTag = 0; - if (MinTimeout>0) { - TimeoutTag=gtk_timeout_add(MinTimeout*1000,GuiDoTimeouts,NULL); - NextTimeout=TimeNow+MinTimeout; - } - } +static time_t NextTimeout = 0; +static guint TimeoutTag = 0; + +static gint GuiDoTimeouts(gpointer data) +{ + /* Forget the TimeoutTag so that GuiSetTimeouts doesn't delete it - + * it'll be deleted automatically anyway when we return FALSE */ + TimeoutTag = 0; + NextTimeout = 0; + + FirstServer = HandleTimeouts(FirstServer); + GuiSetTimeouts(); + return FALSE; +} + +void GuiSetTimeouts(void) +{ + int MinTimeout; + time_t TimeNow; + + TimeNow = time(NULL); + MinTimeout = GetMinimumTimeout(FirstServer); + if (TimeNow + MinTimeout < NextTimeout || NextTimeout < TimeNow) { + if (TimeoutTag > 0) + gtk_timeout_remove(TimeoutTag); + TimeoutTag = 0; + if (MinTimeout > 0) { + TimeoutTag = gtk_timeout_add(MinTimeout * 1000, GuiDoTimeouts, NULL); + NextTimeout = TimeNow + MinTimeout; + } + } } -static void GuiServerPrintFunc(const gchar *string) { - gint EditPos; - - gtk_text_freeze(GTK_TEXT(TextOutput)); - EditPos=gtk_text_get_length(GTK_TEXT(TextOutput)); - gtk_editable_insert_text(GTK_EDITABLE(TextOutput),string,strlen(string), - &EditPos); - gtk_text_thaw(GTK_TEXT(TextOutput)); - gtk_editable_set_position(GTK_EDITABLE(TextOutput),EditPos); +static void GuiServerPrintFunc(const gchar *string) +{ + gint EditPos; + + gtk_text_freeze(GTK_TEXT(TextOutput)); + EditPos = gtk_text_get_length(GTK_TEXT(TextOutput)); + gtk_editable_insert_text(GTK_EDITABLE(TextOutput), string, + strlen(string), &EditPos); + gtk_text_thaw(GTK_TEXT(TextOutput)); + gtk_editable_set_position(GTK_EDITABLE(TextOutput), EditPos); } static void GuiServerLogMessage(const gchar *log_domain, - GLogLevelFlags log_level,const gchar *message, - gpointer user_data) { - GString *text; - text=GetLogString(log_level,message); - if (text) { - g_string_append(text,"\n"); - GuiServerPrintFunc(text->str); - g_string_free(text,TRUE); - } + GLogLevelFlags log_level, + const gchar *message, gpointer user_data) +{ + GString *text; + + text = GetLogString(log_level, message); + if (text) { + g_string_append(text, "\n"); + GuiServerPrintFunc(text->str); + g_string_free(text, TRUE); + } } #ifdef CYGWIN static void ServiceFailure(const gchar *log_domain, - GLogLevelFlags log_level,const gchar *message, - gpointer user_data) { + GLogLevelFlags log_level, const gchar *message, + gpointer user_data) +{ SERVICE_STATUS status; - g_print("%s\n",message); + g_print("%s\n", message); status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; status.dwCurrentState = SERVICE_STOPPED; status.dwControlsAccepted = SERVICE_ACCEPT_STOP; status.dwWin32ExitCode = ERROR_NETWORK_UNREACHABLE; status.dwCheckPoint = 0; status.dwWaitHint = 0; - SetServiceStatus(scHandle,&status); + SetServiceStatus(scHandle, &status); } #endif -static void GuiQuitServer() { - gtk_main_quit(); - StopServer(); -} - -static void GuiDoCommand(GtkWidget *widget,gpointer data) { - gchar *text; - text=gtk_editable_get_chars(GTK_EDITABLE(widget),0,-1); - gtk_editable_delete_text(GTK_EDITABLE(widget),0,-1); - HandleServerCommand(text,NULL); - g_free(text); - if (IsServerShutdown()) GuiQuitServer(); -} - -void GuiHandleMeta(gpointer data,gint socket,GdkInputCondition condition) { - gboolean DoneOK; - gchar *buf; - - if (!MetaConn) return; - if (NetBufHandleNetwork(&MetaConn->NetBuf,condition&GDK_INPUT_READ, - condition&GDK_INPUT_WRITE,&DoneOK)) { - while ((buf=ReadHttpResponse(MetaConn,&DoneOK))) { - gboolean ReadingBody = (MetaConn->Status==HS_READBODY); - if (buf[0] || !ReadingBody) { - dopelog(ReadingBody ? 2 : 4,"MetaServer: %s",buf); - } - g_free(buf); - } - } - if (!DoneOK && HandleHttpCompletion(MetaConn)) { - if (!MetaConnectError(MetaConn)) { - dopelog(4,"MetaServer: (closed)\n"); +static void GuiQuitServer() +{ + gtk_main_quit(); + StopServer(); +} + +static void GuiDoCommand(GtkWidget *widget, gpointer data) +{ + gchar *text; + + text = gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1); + gtk_editable_delete_text(GTK_EDITABLE(widget), 0, -1); + HandleServerCommand(text, NULL); + g_free(text); + if (IsServerShutdown()) + GuiQuitServer(); +} + +void GuiHandleMeta(gpointer data, gint socket, GdkInputCondition condition) +{ + gboolean DoneOK; + gchar *buf; + + if (!MetaConn) + return; + if (NetBufHandleNetwork(&MetaConn->NetBuf, condition & GDK_INPUT_READ, + condition & GDK_INPUT_WRITE, &DoneOK)) { + while ((buf = ReadHttpResponse(MetaConn, &DoneOK))) { + gboolean ReadingBody = (MetaConn->Status == HS_READBODY); + + if (buf[0] || !ReadingBody) { + dopelog(ReadingBody ? 2 : 4, "MetaServer: %s", buf); } - CloseHttpConnection(MetaConn); MetaConn=NULL; - if (IsServerShutdown()) GuiQuitServer(); - } -} - -static void GuiHandleSocket(gpointer data,gint socket, - GdkInputCondition condition) { - Player *Play; - gboolean DoneOK; - Play = (Player *)data; - - /* Sanity check - is the player still around? */ - if (!g_slist_find(FirstServer,(gpointer)Play)) return; - - if (PlayerHandleNetwork(Play,condition&GDK_INPUT_READ, - condition&GDK_INPUT_WRITE,&DoneOK)) { - HandleServerPlayer(Play); - GuiSetTimeouts(); /* We may have set some new timeouts */ - } - if (!DoneOK) { - RemovePlayerFromServer(Play); - if (IsServerShutdown()) GuiQuitServer(); - } -} - -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), - GuiHandleSocket,NetBuf->CallBackData); - } - if (CallNow) GuiHandleSocket(NetBuf->CallBackData,NetBuf->fd,0); + g_free(buf); + } + } + if (!DoneOK && HandleHttpCompletion(MetaConn)) { + if (!MetaConnectError(MetaConn)) { + dopelog(4, "MetaServer: (closed)\n"); + } + CloseHttpConnection(MetaConn); + MetaConn = NULL; + if (IsServerShutdown()) + GuiQuitServer(); + } +} + +static void GuiHandleSocket(gpointer data, gint socket, + GdkInputCondition condition) +{ + Player *Play; + gboolean DoneOK; + + Play = (Player *)data; + + /* Sanity check - is the player still around? */ + if (!g_slist_find(FirstServer, (gpointer)Play)) + return; + + if (PlayerHandleNetwork(Play, condition & GDK_INPUT_READ, + condition & GDK_INPUT_WRITE, &DoneOK)) { + HandleServerPlayer(Play); + GuiSetTimeouts(); /* We may have set some new timeouts */ + } + if (!DoneOK) { + RemovePlayerFromServer(Play); + if (IsServerShutdown()) + GuiQuitServer(); + } } -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, +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), - GuiHandleMeta,NetBuf->CallBackData); - } - if (CallNow) GuiHandleMeta(NetBuf->CallBackData,NetBuf->fd,0); + GuiHandleSocket, + NetBuf->CallBackData); + } + if (CallNow) + GuiHandleSocket(NetBuf->CallBackData, NetBuf->fd, 0); +} + +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), + GuiHandleMeta, NetBuf->CallBackData); + } + if (CallNow) + GuiHandleMeta(NetBuf->CallBackData, NetBuf->fd, 0); } -static void GuiNewConnect(gpointer data,gint socket, - GdkInputCondition condition) { - Player *Play; - if (condition&GDK_INPUT_READ) { - Play=HandleNewConnection(); - SetNetworkBufferCallBack(&Play->NetBuf,SocketStatus,(gpointer)Play); - } +static void GuiNewConnect(gpointer data, gint socket, + GdkInputCondition condition) +{ + Player *Play; + + if (condition & GDK_INPUT_READ) { + Play = HandleNewConnection(); + SetNetworkBufferCallBack(&Play->NetBuf, SocketStatus, (gpointer)Play); + } } -static gboolean TriedPoliteShutdown=FALSE; +static gboolean TriedPoliteShutdown = FALSE; -static gint GuiRequestDelete(GtkWidget *widget,GdkEvent *event,gpointer data) { - if (TriedPoliteShutdown) { +static gint GuiRequestDelete(GtkWidget *widget, GdkEvent * event, + gpointer data) +{ + if (TriedPoliteShutdown) { + GuiQuitServer(); + } else { + TriedPoliteShutdown = TRUE; + HandleServerCommand("quit", NULL); + if (IsServerShutdown()) GuiQuitServer(); - } else { - TriedPoliteShutdown=TRUE; - HandleServerCommand("quit",NULL); - if (IsServerShutdown()) GuiQuitServer(); - } - return TRUE; /* Never allow automatic deletion - we handle it manually */ + } + return TRUE; /* Never allow automatic deletion - we + * handle it manually */ } #ifdef CYGWIN -static HWND mainhwnd=NULL; -static BOOL systray=FALSE; +static HWND mainhwnd = NULL; +static BOOL systray = FALSE; -static BOOL RegisterStatus(DWORD state) { +static BOOL RegisterStatus(DWORD state) +{ SERVICE_STATUS status; + status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; status.dwCurrentState = state; status.dwControlsAccepted = SERVICE_ACCEPT_STOP; status.dwWin32ExitCode = NO_ERROR; status.dwCheckPoint = 0; status.dwWaitHint = 5000; - return SetServiceStatus(scHandle,&status); + return SetServiceStatus(scHandle, &status); } -static VOID WINAPI ServiceHandler(DWORD control) { - DWORD state=SERVICE_RUNNING; - switch(control) { - case SERVICE_CONTROL_STOP: - state=SERVICE_STOP_PENDING; - break; +static VOID WINAPI ServiceHandler(DWORD control) +{ + DWORD state = SERVICE_RUNNING; + + switch (control) { + case SERVICE_CONTROL_STOP: + state = SERVICE_STOP_PENDING; + break; } if (!RegisterStatus(state)) { - dopelog(0,_("Failed to set NT Service status")); + dopelog(0, _("Failed to set NT Service status")); return; } - if (mainhwnd && !PostMessage(mainhwnd,MYWM_SERVICE,0,(LPARAM)control)) { - dopelog(0,_("Failed to post service notification message")); + if (mainhwnd + && !PostMessage(mainhwnd, MYWM_SERVICE, 0, (LPARAM) control)) { + dopelog(0, _("Failed to post service notification message")); return; } } -static VOID WINAPI ServiceInit(DWORD argc,LPTSTR *argv) { - scHandle = RegisterServiceCtrlHandler("dopewars-server",ServiceHandler); +static VOID WINAPI ServiceInit(DWORD argc, LPTSTR * argv) +{ + scHandle = RegisterServiceCtrlHandler("dopewars-server", ServiceHandler); if (!scHandle) { - dopelog(0,_("Failed to register service handler")); return; + dopelog(0, _("Failed to register service handler")); + return; } if (!RegisterStatus(SERVICE_START_PENDING)) { - dopelog(0,_("Failed to set NT Service status")); + dopelog(0, _("Failed to set NT Service status")); return; } GuiServerLoop(TRUE); if (!RegisterStatus(SERVICE_STOPPED)) { - dopelog(0,_("Failed to set NT Service status")); + dopelog(0, _("Failed to set NT Service status")); return; } } -void ServiceMain(void) { +void ServiceMain(void) +{ SERVICE_TABLE_ENTRY services[] = { - { "dopewars-server",ServiceInit }, - { NULL,NULL } + {"dopewars-server", ServiceInit}, + {NULL, NULL} }; + if (!StartServiceCtrlDispatcher(services)) { - dopelog(0,_("Failed to start NT Service")); + dopelog(0, _("Failed to start NT Service")); } } -static LRESULT CALLBACK GuiServerWndProc(HWND hwnd,UINT msg,WPARAM wparam, - LPARAM lparam) { - if (hwnd==mainhwnd) switch(msg) { +static LRESULT CALLBACK GuiServerWndProc(HWND hwnd, UINT msg, + WPARAM wparam, LPARAM lparam) +{ + if (hwnd == mainhwnd) + switch (msg) { case MYWM_SERVICE: - if (lparam==SERVICE_CONTROL_STOP) { + if (lparam == SERVICE_CONTROL_STOP) { GuiQuitServer(); } break; case MYWM_TASKBAR: - if ((UINT)lparam==WM_LBUTTONDOWN) ShowWindow(mainhwnd,SW_SHOW); + if ((UINT) lparam == WM_LBUTTONDOWN) + ShowWindow(mainhwnd, SW_SHOW); break; case WM_SYSCOMMAND: - if (wparam==SC_MINIMIZE && systray) { - ShowWindow(mainhwnd,SW_HIDE); return TRUE; + if (wparam == SC_MINIMIZE && systray) { + ShowWindow(mainhwnd, SW_HIDE); + return TRUE; } break; - } + } return FALSE; } -static void SetupTaskBarIcon(GtkWidget *widget) { +static void SetupTaskBarIcon(GtkWidget *widget) +{ NOTIFYICONDATA nid; nid.cbSize = sizeof(NOTIFYICONDATA); nid.uID = 1000; - if (widget && !widget->hWnd) return; - if (!widget && !mainhwnd) return; + if (widget && !widget->hWnd) + return; + if (!widget && !mainhwnd) + return; nid.hWnd = mainhwnd; if (widget && MinToSysTray) { nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; nid.uCallbackMessage = MYWM_TASKBAR; nid.hIcon = mainIcon; - strcpy(nid.szTip,"dopewars server - running"); - systray=Shell_NotifyIcon(NIM_ADD,&nid); + strcpy(nid.szTip, "dopewars server - running"); + systray = Shell_NotifyIcon(NIM_ADD, &nid); } else { - systray=FALSE; - Shell_NotifyIcon(NIM_DELETE,&nid); + systray = FALSE; + Shell_NotifyIcon(NIM_DELETE, &nid); } } #endif /* CYGWIN */ -void GuiServerLoop(gboolean is_service) { - GtkWidget *window,*text,*hbox,*vbox,*entry,*label; - GtkAdjustment *adj; - - window=gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_signal_connect(GTK_OBJECT(window),"delete_event", - GTK_SIGNAL_FUNC(GuiRequestDelete),NULL); - gtk_window_set_default_size(GTK_WINDOW(window),500,250); - -/* Title of dopewars server window (if used) */ - gtk_window_set_title(GTK_WINDOW(window),_("dopewars server")); - - gtk_container_set_border_width(GTK_CONTAINER(window),7); - - vbox=gtk_vbox_new(FALSE,7); - adj=(GtkAdjustment *)gtk_adjustment_new(0,0,100,1,10,10); - TextOutput=text=gtk_scrolled_text_new(NULL,adj,&hbox); - gtk_text_set_editable(GTK_TEXT(text),FALSE); - gtk_text_set_word_wrap(GTK_TEXT(text),TRUE); - gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,0); - - hbox=gtk_hbox_new(FALSE,4); - label=gtk_label_new(_("Command:")); - gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0); - entry=gtk_entry_new(); - gtk_signal_connect(GTK_OBJECT(entry),"activate", - GTK_SIGNAL_FUNC(GuiDoCommand),NULL); - gtk_box_pack_start(GTK_BOX(hbox),entry,TRUE,TRUE,0); - gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0); - - gtk_container_add(GTK_CONTAINER(window),vbox); - gtk_widget_show_all(window); - - if (is_service) { +void GuiServerLoop(gboolean is_service) +{ + GtkWidget *window, *text, *hbox, *vbox, *entry, *label; + GtkAdjustment *adj; + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_signal_connect(GTK_OBJECT(window), "delete_event", + GTK_SIGNAL_FUNC(GuiRequestDelete), NULL); + gtk_window_set_default_size(GTK_WINDOW(window), 500, 250); + + /* Title of dopewars server window (if used) */ + gtk_window_set_title(GTK_WINDOW(window), _("dopewars server")); + + gtk_container_set_border_width(GTK_CONTAINER(window), 7); + + vbox = gtk_vbox_new(FALSE, 7); + adj = (GtkAdjustment *)gtk_adjustment_new(0, 0, 100, 1, 10, 10); + TextOutput = text = gtk_scrolled_text_new(NULL, adj, &hbox); + gtk_text_set_editable(GTK_TEXT(text), FALSE); + gtk_text_set_word_wrap(GTK_TEXT(text), TRUE); + gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); + + hbox = gtk_hbox_new(FALSE, 4); + label = gtk_label_new(_("Command:")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + entry = gtk_entry_new(); + gtk_signal_connect(GTK_OBJECT(entry), "activate", + GTK_SIGNAL_FUNC(GuiDoCommand), NULL); + gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + gtk_container_add(GTK_CONTAINER(window), vbox); + gtk_widget_show_all(window); + + if (is_service) { #ifdef CYGWIN - g_log_set_handler(NULL,G_LOG_LEVEL_CRITICAL,ServiceFailure,NULL); + g_log_set_handler(NULL, G_LOG_LEVEL_CRITICAL, ServiceFailure, NULL); #endif - } else { - g_set_print_handler(GuiServerPrintFunc); - g_log_set_handler(NULL,LogMask()|G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_WARNING, - GuiServerLogMessage,NULL); - } - if (!StartServer()) return; - - ListenTag=gdk_input_add(ListenSock,GDK_INPUT_READ,GuiNewConnect,NULL); + } else { + g_set_print_handler(GuiServerPrintFunc); + g_log_set_handler(NULL, + LogMask() | G_LOG_LEVEL_MESSAGE | + G_LOG_LEVEL_WARNING, GuiServerLogMessage, NULL); + } + if (!StartServer()) + return; + + ListenTag = + gdk_input_add(ListenSock, GDK_INPUT_READ, GuiNewConnect, NULL); #ifdef CYGWIN - mainhwnd=window->hWnd; - SetupTaskBarIcon(window); - SetCustomWndProc(GuiServerWndProc); - if (is_service && !RegisterStatus(SERVICE_RUNNING)) { - dopelog(0,_("Failed to set NT Service status")); - return; - } + mainhwnd = window->hWnd; + SetupTaskBarIcon(window); + SetCustomWndProc(GuiServerWndProc); + if (is_service && !RegisterStatus(SERVICE_RUNNING)) { + dopelog(0, _("Failed to set NT Service status")); + return; + } #endif - gtk_main(); + gtk_main(); #ifdef CYGWIN - SetupTaskBarIcon(NULL); + SetupTaskBarIcon(NULL); #endif } #endif /* GUI_SERVER */ #endif /* NETWORKING */ -void FinishGame(Player *Play,char *Message) { -/* Tells player "Play" that the game is over; display "Message" */ - Play->EventNum=E_FINISH; - ClientLeftServer(Play); - SendHighScores(Play,TRUE,Message); - -/* Blank the name, so that CountPlayers ignores this player */ - SetPlayerName(Play,NULL); - -/* Make sure they do actually disconnect, eventually! */ - if (ConnectTimeout) { - Play->ConnectTimeout=time(NULL)+(time_t)ConnectTimeout; - } -} - -void HighScoreTypeRead(struct HISCORE *HiScore,FILE *fp) { -/* Reads a batch of NUMHISCORE high scores into "HiScore" from "fp" */ - int i; - char *buf; - for (i=0;i<NUMHISCORE;i++) { - if (read_string(fp,&HiScore[i].Name)==EOF) break; - read_string(fp,&HiScore[i].Time); - read_string(fp,&buf); - HiScore[i].Money=strtoprice(buf); g_free(buf); - HiScore[i].Dead=(fgetc(fp)>0); - } -} - -void HighScoreTypeWrite(struct HISCORE *HiScore,FILE *fp) { -/* Writes out a batch of NUMHISCORE high scores from "HiScore" to "fp" */ - int i; - gchar *text; - for (i=0;i<NUMHISCORE;i++) { - if (HiScore[i].Name) { - fwrite(HiScore[i].Name,strlen(HiScore[i].Name)+1,1,fp); - } else fputc(0,fp); - if (HiScore[i].Time) { - fwrite(HiScore[i].Time,strlen(HiScore[i].Time)+1,1,fp); - } else fputc(0,fp); - text=pricetostr(HiScore[i].Money); - fwrite(text,strlen(text)+1,1,fp); - g_free(text); - fputc(HiScore[i].Dead ? 1 : 0,fp); - } +/* + * Tells player "Play" that the game is over; display "Message". + */ +void FinishGame(Player *Play, char *Message) +{ + Play->EventNum = E_FINISH; + ClientLeftServer(Play); + SendHighScores(Play, TRUE, Message); + + /* Blank the name, so that CountPlayers ignores this player */ + SetPlayerName(Play, NULL); + + /* Make sure they do actually disconnect, eventually! */ + if (ConnectTimeout) { + Play->ConnectTimeout = time(NULL) + (time_t) ConnectTimeout; + } } -void CloseHighScoreFile() { -/* Closes the high score file opened by OpenHighScoreFile, below */ - if (ScoreFP) fclose(ScoreFP); +/* + * Reads a batch of NUMHISCORE high scores into "HiScore" from "fp". + */ +void HighScoreTypeRead(struct HISCORE *HiScore, FILE *fp) +{ + int i; + char *buf; + + for (i = 0; i < NUMHISCORE; i++) { + if (read_string(fp, &HiScore[i].Name) == EOF) + break; + read_string(fp, &HiScore[i].Time); + read_string(fp, &buf); + HiScore[i].Money = strtoprice(buf); + g_free(buf); + HiScore[i].Dead = (fgetc(fp) > 0); + } +} + +/* + * Writes out a batch of NUMHISCORE high scores from "HiScore" to "fp". + */ +void HighScoreTypeWrite(struct HISCORE *HiScore, FILE *fp) +{ + int i; + gchar *text; + + for (i = 0; i < NUMHISCORE; i++) { + if (HiScore[i].Name) { + fwrite(HiScore[i].Name, strlen(HiScore[i].Name) + 1, 1, fp); + } else + fputc(0, fp); + if (HiScore[i].Time) { + fwrite(HiScore[i].Time, strlen(HiScore[i].Time) + 1, 1, fp); + } else + fputc(0, fp); + text = pricetostr(HiScore[i].Money); + fwrite(text, strlen(text) + 1, 1, fp); + g_free(text); + fputc(HiScore[i].Dead ? 1 : 0, fp); + } +} + +/* + * Closes the high score file opened by OpenHighScoreFile, below. + */ +void CloseHighScoreFile() +{ + if (ScoreFP) + fclose(ScoreFP); } -void DropPrivileges() { -/* If we're running setuid/setgid, drop down to the privilege level of the */ -/* user that started the dopewars process */ +/* + * If we're running setuid/setgid, drop down to the privilege level of the + * user that started the dopewars process. + */ +void DropPrivileges() +{ #ifndef CYGWIN - if (setregid(getgid(),getgid())!=0) { - perror("setregid"); - exit(1); - } + if (setregid(getgid(), getgid()) != 0) { + perror("setregid"); + exit(1); + } #endif } static const gchar SCOREHEADER[] = "DOPEWARS SCORES V."; -static const guint SCOREHDRLEN = sizeof(SCOREHEADER)-1; /* Don't include \0 */ +static const guint SCOREHDRLEN = sizeof(SCOREHEADER) - 1; /* Don't include \0 */ static const guint SCOREVERSION = 1; -static gboolean HighScoreReadHeader(FILE *fp,gint *ScoreVersion) { - gchar *header; - - if (read_string(fp,&header)!=EOF) { - if (header && strlen(header) > SCOREHDRLEN && - strncmp(header,SCOREHEADER,SCOREHDRLEN)==0) { - if (ScoreVersion) *ScoreVersion = atoi(header+SCOREHDRLEN); - g_free(header); - return TRUE; - } - } - g_free(header); - return FALSE; +static gboolean HighScoreReadHeader(FILE *fp, gint *ScoreVersion) +{ + gchar *header; + + if (read_string(fp, &header) != EOF) { + if (header && strlen(header) > SCOREHDRLEN && + strncmp(header, SCOREHEADER, SCOREHDRLEN) == 0) { + if (ScoreVersion) + *ScoreVersion = atoi(header + SCOREHDRLEN); + g_free(header); + return TRUE; + } + } + g_free(header); + return FALSE; } -static void HighScoreWriteHeader(FILE *fp) { - gchar *header; +static void HighScoreWriteHeader(FILE *fp) +{ + gchar *header; - header = g_strdup_printf("%s%d",SCOREHEADER,SCOREVERSION); - fwrite(header,strlen(header)+1,1,fp); + header = g_strdup_printf("%s%d", SCOREHEADER, SCOREVERSION); + fwrite(header, strlen(header) + 1, 1, fp); } -void ConvertHighScoreFile(void) { -/* Converts an old format high score file to the new format. */ - FILE *old,*backup; - gchar *BackupFile; - int ch; - char *OldError=NULL,*BackupError=NULL; - struct HISCORE MultiScore[NUMHISCORE],AntiqueScore[NUMHISCORE]; +/* + * Converts an old format high score file to the new format. + */ +void ConvertHighScoreFile(void) +{ + FILE *old, *backup; + gchar *BackupFile; + int ch; + char *OldError = NULL, *BackupError = NULL; + struct HISCORE MultiScore[NUMHISCORE], AntiqueScore[NUMHISCORE]; -/* The user running dopewars must be allowed to mess with the score file */ - DropPrivileges(); + /* The user running dopewars must be allowed to mess with the score file */ + DropPrivileges(); - BackupFile = g_strdup_printf("%s.bak",ConvertFile); + BackupFile = g_strdup_printf("%s.bak", ConvertFile); - old=fopen(ConvertFile,"r+"); - if (!old) OldError = strerror(errno); + old = fopen(ConvertFile, "r+"); + if (!old) + OldError = strerror(errno); - backup=fopen(BackupFile,"w"); - if (!backup) BackupError = strerror(errno); + backup = fopen(BackupFile, "w"); + if (!backup) + BackupError = strerror(errno); - if (old && backup) { + if (old && backup) { -/* First, make sure that the "old" file doesn't have a valid "new" header */ + /* First, make sure that the "old" file doesn't have a valid "new" + * header */ + rewind(old); + if (HighScoreReadHeader(old, NULL)) { + g_log(NULL, G_LOG_LEVEL_CRITICAL, + _("The high score file %s\n" + "is already in the new format! Aborting."), ConvertFile); + fclose(old); + fclose(backup); + } else { + /* Make a backup of the old file */ + ftruncate(fileno(backup), 0); + rewind(backup); rewind(old); - if (HighScoreReadHeader(old,NULL)) { - g_log(NULL,G_LOG_LEVEL_CRITICAL, - _("The high score file %s\n" - "is already in the new format! Aborting."), - ConvertFile); - fclose(old); fclose(backup); - } else { -/* Make a backup of the old file */ - ftruncate(fileno(backup),0); rewind(backup); - rewind(old); - while(1) { - ch = fgetc(old); - if (ch==EOF) break; else fputc(ch,backup); - } - fclose(backup); - -/* Read in the scores without the header, and then write out with the header */ - if (!HighScoreRead(old,MultiScore,AntiqueScore,FALSE)) { - g_log(NULL,G_LOG_LEVEL_CRITICAL,_("Error reading scores from %s."), - ConvertFile); - } else { - ftruncate(fileno(old),0); rewind(old); - if (HighScoreWrite(old,MultiScore,AntiqueScore)) { - g_message(_("The high score file %s has been converted to the " - "new format.\nA backup of the old file has been " - "created as %s.\n"),ConvertFile,BackupFile); - } - } - fclose(old); + while (1) { + ch = fgetc(old); + if (ch == EOF) + break; + else + fputc(ch, backup); } - } else { - if (!old) { - g_log(NULL,G_LOG_LEVEL_CRITICAL, - _("Cannot open high score file %s: %s."), - ConvertFile,OldError); - } else if (!backup) { - g_log(NULL,G_LOG_LEVEL_CRITICAL, - _("Cannot create backup (%s) of the\nhigh score file: %s."), - BackupFile,BackupError); + fclose(backup); + + /* Read in the scores without the header, and then write out with + * the header */ + if (!HighScoreRead(old, MultiScore, AntiqueScore, FALSE)) { + g_log(NULL, G_LOG_LEVEL_CRITICAL, + _("Error reading scores from %s."), ConvertFile); + } else { + ftruncate(fileno(old), 0); + rewind(old); + if (HighScoreWrite(old, MultiScore, AntiqueScore)) { + g_message(_("The high score file %s has been converted to the " + "new format.\nA backup of the old file has been " + "created as %s.\n"), ConvertFile, BackupFile); + } } - } + fclose(old); + } + } else { + if (!old) { + g_log(NULL, G_LOG_LEVEL_CRITICAL, + _("Cannot open high score file %s: %s."), + ConvertFile, OldError); + } else if (!backup) { + g_log(NULL, G_LOG_LEVEL_CRITICAL, + _("Cannot create backup (%s) of the\nhigh score file: %s."), + BackupFile, BackupError); + } + } - g_free(BackupFile); + g_free(BackupFile); } /* State, set by OpenHighScoreFile, and later used by - CheckHighScoreFileConfig */ + * CheckHighScoreFileConfig */ static gboolean NewFile; static int OpenError; -void OpenHighScoreFile(void) { -/* Opens the high score file for later use, and then drops privileges. */ +/* + * Opens the high score file for later use, and then drops privileges. + */ +void OpenHighScoreFile(void) +{ + NewFile = FALSE; + OpenError = 0; - NewFile=FALSE; OpenError=0; - - if (ScoreFP) return; /* If already opened, then we're done */ + if (ScoreFP) + return; /* If already opened, then we're done */ /* Win32 gets upset if we use "a+" so we use this nasty hack instead */ - ScoreFP=fopen(HiScoreFile,"r+"); + ScoreFP = fopen(HiScoreFile, "r+"); if (!ScoreFP) { - ScoreFP=fopen(HiScoreFile,"w+"); - if (!ScoreFP) OpenError=errno; - NewFile=TRUE; + ScoreFP = fopen(HiScoreFile, "w+"); + if (!ScoreFP) + OpenError = errno; + NewFile = TRUE; } DropPrivileges(); } -gboolean CheckHighScoreFileConfig(void) { -/* Checks the high score file opened by OpenHighScoreFile, above. Also warns - the user about other problems encountered during startup. Returns - TRUE if it's valid; otherwise, returns FALSE. */ +/* + * Checks the high score file opened by OpenHighScoreFile, above. Also warns + * the user about other problems encountered during startup. Returns + * TRUE if it's valid; otherwise, returns FALSE. + */ +gboolean CheckHighScoreFileConfig(void) +{ if (!ScoreFP) { - g_log(NULL,G_LOG_LEVEL_CRITICAL,_("Cannot open high score file %s.\n" - "(%s.) Either ensure you have permissions to access\n" - "this file and directory, or specify an alternate high score " - "file with the\n-f command line option."),HiScoreFile, - strerror(OpenError)); + g_log(NULL, G_LOG_LEVEL_CRITICAL, + _("Cannot open high score file %s.\n" + "(%s.) Either ensure you have permissions to access\n" + "this file and directory, or specify an alternate high score " + "file with the\n-f command line option."), + HiScoreFile, strerror(OpenError)); return FALSE; } if (NewFile) { HighScoreWriteHeader(ScoreFP); fflush(ScoreFP); - } else if (!HighScoreReadHeader(ScoreFP,NULL)) { - g_log(NULL,G_LOG_LEVEL_CRITICAL,_("%s does not appear to be a valid\n" - "high score file - please check it. If it is a high score file\n" - "from an older version of dopewars, then first convert it to the\n" - "new format by running \"dopewars -C %s\"\n" - "from the command line."),HiScoreFile,HiScoreFile); + } else if (!HighScoreReadHeader(ScoreFP, NULL)) { + g_log(NULL, G_LOG_LEVEL_CRITICAL, + _("%s does not appear to be a valid\n" + "high score file - please check it. If it is a high score file\n" + "from an older version of dopewars, then first convert it to the\n" + "new format by running \"dopewars -C %s\"\n" + "from the command line."), HiScoreFile, HiScoreFile); return FALSE; } if (ConfigErrors) { #ifdef CYGWIN - g_warning( -_("Errors were encountered during the reading of the configuration file.\n" -"As as result, some settings may not work as expected. Please consult the\n" -"file \"dopewars-log.txt\" for further details.")); + g_warning(_("Errors were encountered during the reading of the " + "configuration file.\nAs as result, some settings may not " + "work as expected. Please consult the\n" + "file \"dopewars-log.txt\" for further details.")); #else - g_warning( -_("Errors were encountered during the reading of the configuration\n" -"file. As a result, some settings may not work as expected. Please see the\n" -"messages on standard output for further details.")); + g_warning(_("Errors were encountered during the reading of the " + "configuration\nfile. As a result, some settings may not " + "work as expected. Please see the\nmessages on standard " + "output for further details.")); #endif } return TRUE; } -gboolean HighScoreRead(FILE *fp,struct HISCORE *MultiScore, - struct HISCORE *AntiqueScore,gboolean ReadHeader) { -/* Reads all the high scores into MultiScore and AntiqueScore (antique */ -/* mode scores). If ReadHeader is TRUE, read the high score file header */ -/* first. Returns TRUE on success, FALSE on failure. */ - gint ScoreVersion=0; - memset(MultiScore,0,sizeof(struct HISCORE)*NUMHISCORE); - memset(AntiqueScore,0,sizeof(struct HISCORE)*NUMHISCORE); - if (fp && ReadLock(fp)==0) { - rewind(fp); - if (ReadHeader && !HighScoreReadHeader(fp,&ScoreVersion)) { - ReleaseLock(fp); - return FALSE; - } - HighScoreTypeRead(AntiqueScore,fp); - HighScoreTypeRead(MultiScore,fp); +/* + * Reads all the high scores into MultiScore and AntiqueScore (antique + * mode scores). If ReadHeader is TRUE, read the high score file header + * first. Returns TRUE on success, FALSE on failure. + */ +gboolean HighScoreRead(FILE *fp, struct HISCORE *MultiScore, + struct HISCORE *AntiqueScore, gboolean ReadHeader) +{ + gint ScoreVersion = 0; + memset(MultiScore, 0, sizeof(struct HISCORE) * NUMHISCORE); + memset(AntiqueScore, 0, sizeof(struct HISCORE) * NUMHISCORE); + if (fp && ReadLock(fp) == 0) { + rewind(fp); + if (ReadHeader && !HighScoreReadHeader(fp, &ScoreVersion)) { ReleaseLock(fp); - } else return FALSE; - return TRUE; -} - -gboolean HighScoreWrite(FILE *fp,struct HISCORE *MultiScore, - struct HISCORE *AntiqueScore) { -/* Writes out all the high scores from MultiScore and AntiqueScore; returns */ -/* TRUE on success, FALSE on failure. */ - if (fp && WriteLock(fp)==0) { - ftruncate(fileno(fp),0); - rewind(fp); - HighScoreWriteHeader(fp); - HighScoreTypeWrite(AntiqueScore,fp); - HighScoreTypeWrite(MultiScore,fp); - ReleaseLock(fp); - fflush(fp); - } else return 0; - return 1; -} - -void SendHighScores(Player *Play,gboolean EndGame,char *Message) { -/* Adds "Play" to the high score list if necessary, and then sends the */ -/* scores over the network to "Play" */ -/* If "EndGame" is TRUE, add the current score if it's high enough and */ -/* display an explanatory message. "Message" is tacked onto the start */ -/* if it's non-NULL. The client is then informed that the game's over. */ - struct HISCORE MultiScore[NUMHISCORE],AntiqueScore[NUMHISCORE],Score; - struct HISCORE *HiScore; - struct tm *timep; - time_t tim; - GString *text; - int i,j,InList=-1; - text=g_string_new(""); - if (!HighScoreRead(ScoreFP,MultiScore,AntiqueScore,TRUE)) { - g_warning(_("Unable to read high score file %s"),HiScoreFile); - } - if (Message) { - g_string_assign(text,Message); - if (strlen(text->str)>0) g_string_append_c(text,'^'); - } - if (WantAntique) HiScore=AntiqueScore; else HiScore=MultiScore; - if (EndGame) { - Score.Money=Play->Cash+Play->Bank-Play->Debt; - Score.Name=g_strdup(GetPlayerName(Play)); - Score.Dead = (Play->Health==0); - tim=time(NULL); - timep=gmtime(&tim); - Score.Time=g_new(char,80); /* Yuck! */ - strftime(Score.Time,80,"%d-%m-%Y",timep); - Score.Time[79]='\0'; - for (i=0;i<NUMHISCORE;i++) { - if (InList==-1 && (Score.Money > HiScore[i].Money || - !HiScore[i].Time || HiScore[i].Time[0]==0)) { - InList=i; - g_string_append(text, - _("Congratulations! You made the high scores!")); - SendPrintMessage(NULL,C_NONE,Play,text->str); - g_free(HiScore[NUMHISCORE-1].Name); - g_free(HiScore[NUMHISCORE-1].Time); - for (j=NUMHISCORE-1;j>i;j--) { - memcpy(&HiScore[j],&HiScore[j-1],sizeof(struct HISCORE)); - } - memcpy(&HiScore[i],&Score,sizeof(struct HISCORE)); - break; - } + return FALSE; + } + HighScoreTypeRead(AntiqueScore, fp); + HighScoreTypeRead(MultiScore, fp); + ReleaseLock(fp); + } else + return FALSE; + return TRUE; +} + +/* + * Writes out all the high scores from MultiScore and AntiqueScore; returns + * TRUE on success, FALSE on failure. + */ +gboolean HighScoreWrite(FILE *fp, struct HISCORE *MultiScore, + struct HISCORE *AntiqueScore) +{ + if (fp && WriteLock(fp) == 0) { + ftruncate(fileno(fp), 0); + rewind(fp); + HighScoreWriteHeader(fp); + HighScoreTypeWrite(AntiqueScore, fp); + HighScoreTypeWrite(MultiScore, fp); + ReleaseLock(fp); + fflush(fp); + } else + return 0; + return 1; +} + +/* + * Adds "Play" to the high score list if necessary, and then sends the + * scores over the network to "Play". + * If "EndGame" is TRUE, add the current score if it's high enough and + * display an explanatory message. "Message" is tacked onto the start + * if it's non-NULL. The client is then informed that the game's over. + */ +void SendHighScores(Player *Play, gboolean EndGame, char *Message) +{ + struct HISCORE MultiScore[NUMHISCORE], AntiqueScore[NUMHISCORE], Score; + struct HISCORE *HiScore; + struct tm *timep; + time_t tim; + GString *text; + int i, j, InList = -1; + + text = g_string_new(""); + if (!HighScoreRead(ScoreFP, MultiScore, AntiqueScore, TRUE)) { + g_warning(_("Unable to read high score file %s"), HiScoreFile); + } + if (Message) { + g_string_assign(text, Message); + if (strlen(text->str) > 0) + g_string_append_c(text, '^'); + } + if (WantAntique) + HiScore = AntiqueScore; + else + HiScore = MultiScore; + if (EndGame) { + Score.Money = Play->Cash + Play->Bank - Play->Debt; + Score.Name = g_strdup(GetPlayerName(Play)); + Score.Dead = (Play->Health == 0); + tim = time(NULL); + timep = gmtime(&tim); + Score.Time = g_new(char, 80); /* Yuck! */ + + strftime(Score.Time, 80, "%d-%m-%Y", timep); + Score.Time[79] = '\0'; + for (i = 0; i < NUMHISCORE; i++) { + if (InList == -1 && (Score.Money > HiScore[i].Money || + !HiScore[i].Time || HiScore[i].Time[0] == 0)) { + InList = i; + g_string_append(text, + _("Congratulations! You made the high scores!")); + SendPrintMessage(NULL, C_NONE, Play, text->str); + g_free(HiScore[NUMHISCORE - 1].Name); + g_free(HiScore[NUMHISCORE - 1].Time); + for (j = NUMHISCORE - 1; j > i; j--) { + memcpy(&HiScore[j], &HiScore[j - 1], sizeof(struct HISCORE)); + } + memcpy(&HiScore[i], &Score, sizeof(struct HISCORE)); + break; + } + } + if (InList == -1) { + g_string_append(text, + _("You didn't even make the high score table...")); + SendPrintMessage(NULL, C_NONE, Play, text->str); + } + } + SendServerMessage(NULL, C_NONE, C_STARTHISCORE, Play, NULL); + + j = 0; + for (i = 0; i < NUMHISCORE; i++) { + if (SendSingleHighScore(Play, &HiScore[i], j, InList == i)) + j++; + } + if (InList == -1 && EndGame) + SendSingleHighScore(Play, &Score, j, TRUE); + SendServerMessage(NULL, C_NONE, C_ENDHISCORE, Play, + EndGame ? "end" : NULL); + if (!EndGame) + SendDrugsHere(Play, FALSE); + if (EndGame && !HighScoreWrite(ScoreFP, MultiScore, AntiqueScore)) { + g_warning(_("Unable to write high score file %s"), HiScoreFile); + } + for (i = 0; i < NUMHISCORE; i++) { + g_free(MultiScore[i].Name); + g_free(MultiScore[i].Time); + g_free(AntiqueScore[i].Name); + g_free(AntiqueScore[i].Time); + } + g_string_free(text, TRUE); +} + +/* + * Sends a single high score in "Score" with position "ind" to player + * "Play". If Bold is TRUE, instructs the client to display the score in + * bold text. + */ +int SendSingleHighScore(Player *Play, struct HISCORE *Score, + int ind, gboolean Bold) +{ + gchar *Data, *prstr; + + if (!Score->Time || Score->Time[0] == 0) + return 0; + Data = g_strdup_printf("%d^%c%c%18s %-14s %-34s %8s%c", ind, + Bold ? 'B' : 'N', Bold ? '>' : ' ', + prstr = FormatPrice(Score->Money), + Score->Time, Score->Name, + Score->Dead ? _("(R.I.P.)") : "", + Bold ? '<' : ' '); + SendServerMessage(NULL, C_NONE, C_HISCORE, Play, Data); + g_free(prstr); + g_free(Data); + return 1; +} + +/* + * In order for the server to keep track of the state of each client, each + * client's state is identified by its EventNum data member. So, for example, + * there is a state for fighting the cops, a state for going to the bank, and + * so on. This function instructs client player "To" to carry out the actions + * expected of it in its current state. It is the client's responsibility to + * ensure that it carries out the correct actions to advance itself to the + * "next" state; if it fails in this duty it will hang! + */ +void SendEvent(Player *To) +{ + price_t Money; + int i, j; + gchar *text; + Player *Play; + GSList *list; + + if (!To) + return; + if (To->EventNum == E_MAX) + To->EventNum = E_NONE; + if (To->EventNum == E_NONE || To->EventNum >= E_OUTOFSYNC) + return; + Money = To->Cash + To->Bank - To->Debt; + + ClearPrices(To); + + while (To->EventNum < E_MAX) { + switch (To->EventNum) { + case E_SUBWAY: + SendServerMessage(NULL, C_NONE, C_SUBWAYFLASH, To, NULL); + break; + case E_OFFOBJECT: + To->OnBehalfOf = NULL; + for (i = 0; i < To->TipList.Number; i++) { + dopelog(3, _("%s: Tipoff from %s"), GetPlayerName(To), + GetPlayerName(To->TipList.Data[i].Play)); + To->OnBehalfOf = To->TipList.Data[i].Play; + SendCopOffer(To, FORCECOPS); + return; } - if (InList==-1) { - g_string_append(text, - _("You didn't even make the high score table...")); - SendPrintMessage(NULL,C_NONE,Play,text->str); + for (i = 0; i < To->SpyList.Number; i++) { + if (To->SpyList.Data[i].Turns < 0) { + dopelog(3, _("%s: Spy offered by %s"), GetPlayerName(To), + GetPlayerName(To->SpyList.Data[i].Play)); + To->OnBehalfOf = To->SpyList.Data[i].Play; + SendCopOffer(To, FORCEBITCH); + return; + } + To->SpyList.Data[i].Turns++; + if (To->SpyList.Data[i].Turns > 3 && + brandom(0, 100) < 10 + To->SpyList.Data[i].Turns) { + if (TotalGunsCarried(To) > 0) + j = brandom(0, NUMDISCOVER); + else + j = brandom(0, NUMDISCOVER - 1); + text = + dpg_strdup_printf(_("One of your %tde was spying for %s." + "^The spy %s!"), Names.Bitches, + GetPlayerName(To->SpyList.Data[i].Play), + _(Discover[j])); + if (j != DEFECT) + LoseBitch(To, NULL, NULL); + SendPlayerData(To); + SendPrintMessage(NULL, C_NONE, To, text); + g_free(text); + text = g_strdup_printf(_("Your spy working with %s has " + "been discovered!^The spy %s!"), + GetPlayerName(To), _(Discover[j])); + if (j == ESCAPE) + GainBitch(To->SpyList.Data[i].Play); + To->SpyList.Data[i].Play->Flags &= ~SPYINGON; + SendPlayerData(To->SpyList.Data[i].Play); + SendPrintMessage(NULL, C_NONE, To->SpyList.Data[i].Play, text); + g_free(text); + RemoveListEntry(&(To->SpyList), i); + i--; + } } - } - SendServerMessage(NULL,C_NONE,C_STARTHISCORE,Play,NULL); - - j=0; - for (i=0;i<NUMHISCORE;i++) { - if (SendSingleHighScore(Play,&HiScore[i],j,InList==i)) j++; - } - if (InList==-1 && EndGame) SendSingleHighScore(Play,&Score,j,TRUE); - SendServerMessage(NULL,C_NONE,C_ENDHISCORE,Play,EndGame ? "end" : NULL); - if (!EndGame) SendDrugsHere(Play,FALSE); - if (EndGame && !HighScoreWrite(ScoreFP,MultiScore,AntiqueScore)) { - g_warning(_("Unable to write high score file %s"),HiScoreFile); - } - for (i=0;i<NUMHISCORE;i++) { - g_free(MultiScore[i].Name); g_free(MultiScore[i].Time); - g_free(AntiqueScore[i].Name); g_free(AntiqueScore[i].Time); - } - g_string_free(text,TRUE); -} - -int SendSingleHighScore(Player *Play,struct HISCORE *Score, - int ind,gboolean Bold) { -/* Sends a single high score in "Score" with position "ind" to player */ -/* "Play". If Bold is TRUE, instructs the client to display the score in */ -/* bold text. */ - gchar *Data,*prstr; - if (!Score->Time || Score->Time[0]==0) return 0; - Data=g_strdup_printf("%d^%c%c%18s %-14s %-34s %8s%c",ind, - Bold ? 'B' : 'N',Bold ? '>' : ' ', - prstr=FormatPrice(Score->Money), - Score->Time,Score->Name,Score->Dead ? _("(R.I.P.)") :"", - Bold ? '<' : ' '); - SendServerMessage(NULL,C_NONE,C_HISCORE,Play,Data); - g_free(prstr); g_free(Data); - return 1; -} - -void SendEvent(Player *To) { -/* In order for the server to keep track of the state of each client, each */ -/* client's state is identified by its EventNum data member. So, for example, */ -/* there is a state for fighting the cops, a state for going to the bank, and */ -/* so on. This function instructs client player "To" to carry out the actions */ -/* expected of it in its current state. It is the client's responsibility to */ -/* ensure that it carries out the correct actions to advance itself to the */ -/* "next" state; if it fails in this duty it will hang! */ - price_t Money; - int i,j; - gchar *text; - Player *Play; - GSList *list; - - if (!To) return; - if (To->EventNum==E_MAX) To->EventNum=E_NONE; - if (To->EventNum==E_NONE || To->EventNum>=E_OUTOFSYNC) return; - Money=To->Cash+To->Bank-To->Debt; - - ClearPrices(To); - - while (To->EventNum<E_MAX) { - switch (To->EventNum) { - case E_SUBWAY: - SendServerMessage(NULL,C_NONE,C_SUBWAYFLASH,To,NULL); - break; - case E_OFFOBJECT: - To->OnBehalfOf=NULL; - for (i=0;i<To->TipList.Number;i++) { - dopelog(3,_("%s: Tipoff from %s"),GetPlayerName(To), - GetPlayerName(To->TipList.Data[i].Play)); - To->OnBehalfOf=To->TipList.Data[i].Play; - SendCopOffer(To,FORCECOPS); - return; - } - for (i=0;i<To->SpyList.Number;i++) { - if (To->SpyList.Data[i].Turns<0) { - dopelog(3,_("%s: Spy offered by %s"),GetPlayerName(To), - GetPlayerName(To->SpyList.Data[i].Play)); - To->OnBehalfOf=To->SpyList.Data[i].Play; - SendCopOffer(To,FORCEBITCH); - return; - } - To->SpyList.Data[i].Turns++; - if (To->SpyList.Data[i].Turns>3 && - brandom(0,100)<10+To->SpyList.Data[i].Turns) { - if (TotalGunsCarried(To) > 0) j=brandom(0,NUMDISCOVER); - else j=brandom(0,NUMDISCOVER-1); - text=dpg_strdup_printf( - _("One of your %tde was spying for %s.^The spy %s!"), - Names.Bitches,GetPlayerName(To->SpyList.Data[i].Play), - _(Discover[j])); - if (j!=DEFECT) LoseBitch(To,NULL,NULL); - SendPlayerData(To); - SendPrintMessage(NULL,C_NONE,To,text); - g_free(text); - text=g_strdup_printf(_("Your spy working with %s has " - "been discovered!^The spy %s!"), - GetPlayerName(To),_(Discover[j])); - if (j==ESCAPE) GainBitch(To->SpyList.Data[i].Play); - To->SpyList.Data[i].Play->Flags &= ~SPYINGON; - SendPlayerData(To->SpyList.Data[i].Play); - SendPrintMessage(NULL,C_NONE, - To->SpyList.Data[i].Play,text); - g_free(text); - RemoveListEntry(&(To->SpyList),i); - i--; - } - } - if (Money>3000000) i=130; - else if (Money>1000000) i=115; - else i=100; - if (brandom(0,i)>75) { - if (SendCopOffer(To,NOFORCE)) return; - } - break; - case E_SAYING: - if (!Sanitized && (brandom(0,100) < 15)) { - if (brandom(0,100)<50) { - text=g_strdup_printf(_("The lady next to you on the subway " - "said,^ \"%s\"%s"), - SubwaySaying[brandom(0,NumSubway)],brandom(0,100)<30 ? - _("^ (at least, you -think- that's what she said)") : ""); - } else { - text=g_strdup_printf(_("You hear someone playing %s"), - Playing[brandom(0,NumPlaying)]); - } - SendPrintMessage(NULL,C_NONE,To,text); - g_free(text); - } - break; - case E_LOANSHARK: - if (To->IsAt+1==LoanSharkLoc && To->Debt>0) { - text=dpg_strdup_printf(_("YN^Would you like to visit %tde?"), - Names.LoanSharkName); - SendQuestion(NULL,C_ASKLOAN,To,text); - g_free(text); - return; - } - break; - case E_BANK: - if (To->IsAt+1==BankLoc) { - text=dpg_strdup_printf(_("YN^Would you like to visit %tde?"), - Names.BankName); - SendQuestion(NULL,C_ASKBANK,To,text); - g_free(text); - return; - } - break; - case E_GUNSHOP: - if (To->IsAt+1==GunShopLoc && !Sanitized && !WantAntique) { - text=dpg_strdup_printf(_("YN^Would you like to visit %tde?"), - Names.GunShopName); - SendQuestion(NULL,C_ASKGUNSHOP,To,text); - g_free(text); - return; - } - break; - case E_ROUGHPUB: - if (To->IsAt+1==RoughPubLoc && !WantAntique) { - text=dpg_strdup_printf(_("YN^Would you like to visit %tde?"), - Names.RoughPubName); - SendQuestion(NULL,C_ASKPUB,To,text); - g_free(text); - return; - } - break; - case E_HIREBITCH: - if (To->IsAt+1==RoughPubLoc && !WantAntique) { - To->Bitches.Price=prandom(Bitch.MinPrice,Bitch.MaxPrice); - text=dpg_strdup_printf( - _("YN^^Would you like to hire a %tde for %P?"), - Names.Bitch,To->Bitches.Price); - SendQuestion(NULL,C_ASKBITCH,To,text); - g_free(text); - return; - } - break; - case E_ARRIVE: - for (list=FirstServer;list;list=g_slist_next(list)) { - Play=(Player *)list->data; - if (IsConnectedPlayer(Play) && Play!=To && - Play->IsAt==To->IsAt && - Play->EventNum==E_NONE && TotalGunsCarried(To)>0) { - text=g_strdup_printf(_("AE^%s is already here!^" - "Do you Attack, or Evade?"), - GetPlayerName(Play)); -/* Steal this to keep track of the potential defender */ - To->OnBehalfOf=Play; - - SendDrugsHere(To,TRUE); - SendQuestion(NULL,C_MEETPLAYER,To,text); - g_free(text); - return; - } - } - SendDrugsHere(To,TRUE); - break; - default: - break; + if (Money > 3000000) + i = 130; + else if (Money > 1000000) + i = 115; + else + i = 100; + if (brandom(0, i) > 75) { + if (SendCopOffer(To, NOFORCE)) + return; } - To->EventNum++; - } - if (To->EventNum >= E_MAX) To->EventNum=E_NONE; -} - -int SendCopOffer(Player *To,OfferForce Force) { -/* In response to client player "To" being in state E_OFFOBJECT, */ -/* randomly engages the client in combat with the cops or offers */ -/* other random events. Returns 0 if the client should then be */ -/* advanced to the next state, 1 otherwise (i.e. if there are */ -/* questions pending which the client must answer first) */ -/* If Force==FORCECOPS, engage in combat with the cops for certain */ -/* If Force==FORCEBITCH, offer the client a bitch for certain */ - int i; - - /* The cops are more likely to attack in locations with higher - police presence ratings */ - i=brandom(0,80+Location[(int)To->IsAt].PolicePresence); - - if (Force==FORCECOPS) i=100; - else if (Force==FORCEBITCH) i=0; - else To->OnBehalfOf=NULL; - if (i<33) { - return(OfferObject(To,Force==FORCEBITCH)); - } else if (i<50) { return(RandomOffer(To)); - } else if (Sanitized) { return 0; - } else { - CopsAttackPlayer(To); - return 1; - } - return 1; -} - -void CopsAttackPlayer(Player *Play) { -/* Has the cops attack player "Play" */ - Player *Cops; - gint CopIndex,NumDeputy,GunIndex; - - CopIndex=1-Play->CopIndex; - if (CopIndex<0) { - g_warning(_("Cops cannot attack other cops!")); - return; - } - if (CopIndex > NumCop) CopIndex=NumCop; - Cops=g_new(Player,1); - FirstServer=AddPlayer(0,Cops,FirstServer); - SetPlayerName(Cops,Cop[CopIndex-1].Name); - Cops->CopIndex=CopIndex; - Cops->Cash=brandom(100,2000); - Cops->Debt=Cops->Bank=0; - - NumDeputy=brandom(Cop[CopIndex-1].MinDeputies, - Cop[CopIndex-1].MaxDeputies); - Cops->Bitches.Carried=NumDeputy; - GunIndex=Cop[CopIndex-1].GunIndex; - if (GunIndex>=NumGun) GunIndex=NumGun-1; - Cops->Guns[GunIndex].Carried=(NumDeputy*Cop[CopIndex-1].DeputyGun)+ - Cop[CopIndex-1].CopGun; - Cops->Health=100; - - Play->EventNum++; - AttackPlayer(Cops,Play); -} - -void AttackPlayer(Player *Play,Player *Attacked) { -/* Starts combat between player "Play" and player "Attacked"; if */ -/* either player is currently engaged in combat, add the other */ -/* player to the existing combat. If neither player is currently */ -/* fighting, start a new combat between them. Either player can be */ -/* the cops. */ - GPtrArray *FightArray; - g_assert(Play && Attacked); - - if (Play->FightArray && Attacked->FightArray) { - if (Play->FightArray==Attacked->FightArray) { - g_error(_("Players are already in a fight!")); - } else { - g_error(_("Players are already in separate fights!")); + break; + case E_SAYING: + if (!Sanitized && (brandom(0, 100) < 15)) { + if (brandom(0, 100) < 50) { + text = g_strdup_printf(_("The lady next to you on the subway " + "said,^ \"%s\"%s"), + SubwaySaying[brandom(0, NumSubway)], + brandom(0, 100) < 30 ? + _("^ (at least, you -think- that's " + "what she said)") : ""); + } else { + text = g_strdup_printf(_("You hear someone playing %s"), + Playing[brandom(0, NumPlaying)]); + } + SendPrintMessage(NULL, C_NONE, To, text); + g_free(text); + } + break; + case E_LOANSHARK: + if (To->IsAt + 1 == LoanSharkLoc && To->Debt > 0) { + text = dpg_strdup_printf(_("YN^Would you like to visit %tde?"), + Names.LoanSharkName); + SendQuestion(NULL, C_ASKLOAN, To, text); + g_free(text); + return; + } + break; + case E_BANK: + if (To->IsAt + 1 == BankLoc) { + text = dpg_strdup_printf(_("YN^Would you like to visit %tde?"), + Names.BankName); + SendQuestion(NULL, C_ASKBANK, To, text); + g_free(text); + return; + } + break; + case E_GUNSHOP: + if (To->IsAt + 1 == GunShopLoc && !Sanitized && !WantAntique) { + text = dpg_strdup_printf(_("YN^Would you like to visit %tde?"), + Names.GunShopName); + SendQuestion(NULL, C_ASKGUNSHOP, To, text); + g_free(text); + return; } - return; - } - if (NumGun==0) { - g_error(_("Cannot start fight - no guns to use!")); - return; - } - - if (!Play->FightArray && !Attacked->FightArray) { - FightArray = g_ptr_array_new(); - } else { - FightArray = Play->FightArray ? Play->FightArray : Attacked->FightArray; - } - - if (!Play->FightArray) { - Play->ResyncNum=Play->EventNum; - g_ptr_array_add(FightArray,Play); - } - if (!Attacked->FightArray) { - Attacked->ResyncNum=Attacked->EventNum; - g_ptr_array_add(FightArray,Attacked); - } - Play->FightArray=Attacked->FightArray=FightArray; - Play->EventNum=Attacked->EventNum=E_FIGHT; - - Play->Attacking = Attacked; - - SendFightMessage(Attacked,Play,0,F_ARRIVED,(price_t)0,TRUE,NULL); - - Fire(Play); -} - -gboolean IsOpponent(Player *Play,Player *Other) { -/* Returns TRUE if player "Other" is not allied with player "Play" */ - return TRUE; -} - -void HandleDamage(Player *Defend,Player *Attack,int Damage, - int *BitchesKilled,price_t *Loot) { - Inventory *Guns,*Drugs; - price_t Bounty; - - Guns=(Inventory *)g_malloc0(sizeof(Inventory)*NumGun); - Drugs=(Inventory *)g_malloc0(sizeof(Inventory)*NumDrug); - ClearInventory(Guns,Drugs); - - Bounty=0; - if (Defend->Health<=Damage && Defend->Bitches.Carried==0) { - Bounty=Defend->Cash+Defend->Bank-Defend->Debt; - AddInventory(Guns,Defend->Guns,NumGun); - AddInventory(Drugs,Defend->Drugs,NumDrug); - Defend->Health=0; - } else if (Defend->Bitches.Carried>0 && - Defend->Health<=Damage) { - if (IsCop(Defend)) LoseBitch(Defend,NULL,NULL); - else LoseBitch(Defend,Guns,Drugs); - Defend->Health=100; - *BitchesKilled=1; - } else { - Defend->Health-=Damage; - } - if (IsCop(Attack)) { /* Don't let cops loot players */ - ClearInventory(Guns,Drugs); - } else { - TruncateInventoryFor(Guns,Drugs,Attack); - } - SendPlayerData(Defend); - if (Bounty<0) Bounty=0; - if (!IsInventoryClear(Guns,Drugs)) { - AddInventory(Attack->Guns,Guns,NumGun); - AddInventory(Attack->Drugs,Drugs,NumDrug); - ChangeSpaceForInventory(Guns,Drugs,Attack); - } - Attack->Cash+=Bounty; - if (Bounty>0 || !IsInventoryClear(Guns,Drugs)) { - if (Bounty>0) *Loot=Bounty; else *Loot=-1; - SendPlayerData(Attack); - } - g_free(Guns); g_free(Drugs); -} - -void GetFightRatings(Player *Attack,Player *Defend, - int *AttackRating,int *DefendRating) { - int i; - -/* Base values */ - *AttackRating=80; - *DefendRating=100; - - for (i=0;i<NumGun;i++) { - *AttackRating+=Gun[i].Damage*Attack->Guns[i].Carried; - } - if (IsCop(Attack)) *AttackRating-=Cop[Attack->CopIndex-1].AttackPenalty; - - *DefendRating-=5*Defend->Bitches.Carried; - if (IsCop(Defend)) *DefendRating-=Cop[Defend->CopIndex-1].DefendPenalty; - - *DefendRating=MAX(*DefendRating,10); - *AttackRating=MAX(*AttackRating,10); -} - -void AllowNextShooter(Player *Play) { - Player *NextShooter; - if (FightTimeout) { - NextShooter=GetNextShooter(Play); - if (NextShooter && !CanPlayerFire(NextShooter)) { - NextShooter->FightTimeout=0; + break; + case E_ROUGHPUB: + if (To->IsAt + 1 == RoughPubLoc && !WantAntique) { + text = dpg_strdup_printf(_("YN^Would you like to visit %tde?"), + Names.RoughPubName); + SendQuestion(NULL, C_ASKPUB, To, text); + g_free(text); + return; + } + break; + case E_HIREBITCH: + if (To->IsAt + 1 == RoughPubLoc && !WantAntique) { + To->Bitches.Price = prandom(Bitch.MinPrice, Bitch.MaxPrice); + text = + dpg_strdup_printf(_ + ("YN^^Would you like to hire a %tde for %P?"), + Names.Bitch, To->Bitches.Price); + SendQuestion(NULL, C_ASKBITCH, To, text); + g_free(text); + return; + } + break; + case E_ARRIVE: + for (list = FirstServer; list; list = g_slist_next(list)) { + Play = (Player *)list->data; + if (IsConnectedPlayer(Play) && Play != To && + Play->IsAt == To->IsAt && + Play->EventNum == E_NONE && TotalGunsCarried(To) > 0) { + text = g_strdup_printf(_("AE^%s is already here!^" + "Do you Attack, or Evade?"), + GetPlayerName(Play)); + /* Steal this to keep track of the potential defender */ + To->OnBehalfOf = Play; + + SendDrugsHere(To, TRUE); + SendQuestion(NULL, C_MEETPLAYER, To, text); + g_free(text); + return; + } } - } + SendDrugsHere(To, TRUE); + break; + default: + break; + } + To->EventNum++; + } + if (To->EventNum >= E_MAX) + To->EventNum = E_NONE; +} + +/* + * In response to client player "To" being in state E_OFFOBJECT, + * randomly engages the client in combat with the cops or offers + * other random events. Returns 0 if the client should then be + * advanced to the next state, 1 otherwise (i.e. if there are + * questions pending which the client must answer first) + * If Force==FORCECOPS, engage in combat with the cops for certain + * If Force==FORCEBITCH, offer the client a bitch for certain + */ +int SendCopOffer(Player *To, OfferForce Force) +{ + int i; + + /* The cops are more likely to attack in locations with higher police + * presence ratings */ + i = brandom(0, 80 + Location[(int)To->IsAt].PolicePresence); + + if (Force == FORCECOPS) + i = 100; + else if (Force == FORCEBITCH) + i = 0; + else + To->OnBehalfOf = NULL; + if (i < 33) { + return (OfferObject(To, Force == FORCEBITCH)); + } else if (i < 50) { + return (RandomOffer(To)); + } else if (Sanitized) { + return 0; + } else { + CopsAttackPlayer(To); + return 1; + } + return 1; } -void DoReturnFire(Player *Play) { - guint ArrayInd; - Player *Defend; +/* + * Has the cops attack player "Play". + */ +void CopsAttackPlayer(Player *Play) +{ + Player *Cops; + gint CopIndex, NumDeputy, GunIndex; - if (!Play || !Play->FightArray) return; + CopIndex = 1 - Play->CopIndex; + if (CopIndex < 0) { + g_warning(_("Cops cannot attack other cops!")); + return; + } + if (CopIndex > NumCop) + CopIndex = NumCop; + Cops = g_new(Player, 1); + + FirstServer = AddPlayer(0, Cops, FirstServer); + SetPlayerName(Cops, Cop[CopIndex - 1].Name); + Cops->CopIndex = CopIndex; + Cops->Cash = brandom(100, 2000); + Cops->Debt = Cops->Bank = 0; + + NumDeputy = brandom(Cop[CopIndex - 1].MinDeputies, + Cop[CopIndex - 1].MaxDeputies); + Cops->Bitches.Carried = NumDeputy; + GunIndex = Cop[CopIndex - 1].GunIndex; + if (GunIndex >= NumGun) + GunIndex = NumGun - 1; + Cops->Guns[GunIndex].Carried = + (NumDeputy * Cop[CopIndex - 1].DeputyGun) + Cop[CopIndex - 1].CopGun; + Cops->Health = 100; + + Play->EventNum++; + AttackPlayer(Cops, Play); +} + +/* + * Starts combat between player "Play" and player "Attacked"; if + * either player is currently engaged in combat, add the other + * player to the existing combat. If neither player is currently + * fighting, start a new combat between them. Either player can be + * the cops. + */ +void AttackPlayer(Player *Play, Player *Attacked) +{ + GPtrArray *FightArray; + + g_assert(Play && Attacked); + + if (Play->FightArray && Attacked->FightArray) { + if (Play->FightArray == Attacked->FightArray) { + g_error(_("Players are already in a fight!")); + } else { + g_error(_("Players are already in separate fights!")); + } + return; + } + if (NumGun == 0) { + g_error(_("Cannot start fight - no guns to use!")); + return; + } - if (FightTimeout!=0 || !IsCop(Play)) { - for (ArrayInd=0;Play->FightArray && ArrayInd<Play->FightArray->len; - ArrayInd++) { - Defend=(Player *)g_ptr_array_index(Play->FightArray,ArrayInd); - if (IsCop(Defend) && CanPlayerFire(Defend)) Fire(Defend); - } - } + if (!Play->FightArray && !Attacked->FightArray) { + FightArray = g_ptr_array_new(); + } else { + FightArray = + Play->FightArray ? Play->FightArray : Attacked->FightArray; + } + + if (!Play->FightArray) { + Play->ResyncNum = Play->EventNum; + g_ptr_array_add(FightArray, Play); + } + if (!Attacked->FightArray) { + Attacked->ResyncNum = Attacked->EventNum; + g_ptr_array_add(FightArray, Attacked); + } + Play->FightArray = Attacked->FightArray = FightArray; + Play->EventNum = Attacked->EventNum = E_FIGHT; + + Play->Attacking = Attacked; + + SendFightMessage(Attacked, Play, 0, F_ARRIVED, (price_t)0, TRUE, NULL); + + Fire(Play); +} + +/* + * Returns TRUE if player "Other" is not allied with player "Play". + */ +gboolean IsOpponent(Player *Play, Player *Other) +{ + return TRUE; +} + +void HandleDamage(Player *Defend, Player *Attack, int Damage, + int *BitchesKilled, price_t *Loot) +{ + Inventory *Guns, *Drugs; + price_t Bounty; + + Guns = (Inventory *)g_malloc0(sizeof(Inventory) * NumGun); + Drugs = (Inventory *)g_malloc0(sizeof(Inventory) * NumDrug); + ClearInventory(Guns, Drugs); + + Bounty = 0; + if (Defend->Health <= Damage && Defend->Bitches.Carried == 0) { + Bounty = Defend->Cash + Defend->Bank - Defend->Debt; + AddInventory(Guns, Defend->Guns, NumGun); + AddInventory(Drugs, Defend->Drugs, NumDrug); + Defend->Health = 0; + } else if (Defend->Bitches.Carried > 0 && Defend->Health <= Damage) { + if (IsCop(Defend)) + LoseBitch(Defend, NULL, NULL); + else + LoseBitch(Defend, Guns, Drugs); + Defend->Health = 100; + *BitchesKilled = 1; + } else { + Defend->Health -= Damage; + } + if (IsCop(Attack)) { /* Don't let cops loot players */ + ClearInventory(Guns, Drugs); + } else { + TruncateInventoryFor(Guns, Drugs, Attack); + } + SendPlayerData(Defend); + if (Bounty < 0) + Bounty = 0; + if (!IsInventoryClear(Guns, Drugs)) { + AddInventory(Attack->Guns, Guns, NumGun); + AddInventory(Attack->Drugs, Drugs, NumDrug); + ChangeSpaceForInventory(Guns, Drugs, Attack); + } + Attack->Cash += Bounty; + if (Bounty > 0 || !IsInventoryClear(Guns, Drugs)) { + if (Bounty > 0) + *Loot = Bounty; + else + *Loot = -1; + SendPlayerData(Attack); + } + g_free(Guns); + g_free(Drugs); } -void RunFromCombat(Player *Play,int ToLocation) { -/* Withdraws player "Play" from combat, and levies any penalties on */ -/* the player for this cowardly act, if applicable. If "ToLocation" */ -/* is >=0, then it identifies the location that the player is */ -/* trying to run to. */ - int EscapeProb,RandNum; - guint ArrayInd; - gboolean FightingCop=FALSE; - Player *Defend; - char BackupAt; +void GetFightRatings(Player *Attack, Player *Defend, + int *AttackRating, int *DefendRating) +{ + int i; - if (!Play || !Play->FightArray) return; + /* Base values */ + *AttackRating = 80; + *DefendRating = 100; - EscapeProb=60; + for (i = 0; i < NumGun; i++) { + *AttackRating += Gun[i].Damage * Attack->Guns[i].Carried; + } + if (IsCop(Attack)) + *AttackRating -= Cop[Attack->CopIndex - 1].AttackPenalty; -/* Penalise players that are attacking others */ - if (Play->Attacking) EscapeProb/=2; + *DefendRating -= 5 * Defend->Bitches.Carried; + if (IsCop(Defend)) + *DefendRating -= Cop[Defend->CopIndex - 1].DefendPenalty; - RandNum=brandom(0,100); + *DefendRating = MAX(*DefendRating, 10); + *AttackRating = MAX(*AttackRating, 10); +} - if (RandNum<EscapeProb) { - if (!IsCop(Play) && brandom(0,100)<30) { - for (ArrayInd=0;ArrayInd<Play->FightArray->len;ArrayInd++) { - Defend=(Player *)g_ptr_array_index(Play->FightArray,ArrayInd); - if (IsCop(Defend)) { FightingCop=TRUE; break; } - } - if (FightingCop) Play->CopIndex--; - } - BackupAt=Play->IsAt; - Play->IsAt=(char)ToLocation; - WithdrawFromCombat(Play); - Play->IsAt=BackupAt; - Play->EventNum=Play->ResyncNum; SendEvent(Play); - } else { - SendFightMessage(Play,NULL,0,F_FAILFLEE,(price_t)0,TRUE,NULL); - AllowNextShooter(Play); - if (FightTimeout) SetFightTimeout(Play); - DoReturnFire(Play); - } -} - -void CheckForKilledPlayers(Player *Play) { - Player *Defend; - guint ArrayInd; - GPtrArray *KilledPlayers; - - KilledPlayers=g_ptr_array_new(); - for (ArrayInd=0;ArrayInd<Play->FightArray->len;ArrayInd++) { - Defend=(Player *)g_ptr_array_index(Play->FightArray,ArrayInd); - - if (Defend && Defend!=Play && IsOpponent(Play,Defend) && - Defend->Health==0) { - g_ptr_array_add(KilledPlayers,(gpointer)Defend); - } - } - for (ArrayInd=0;ArrayInd<KilledPlayers->len;ArrayInd++) { - Defend=(Player *)g_ptr_array_index(KilledPlayers,ArrayInd); - WithdrawFromCombat(Defend); - if (IsCop(Defend)) { - if (!IsCop(Play)) Play->CopIndex=-Defend->CopIndex; - FirstServer=RemovePlayer(Defend,FirstServer); - } else { - FinishGame(Defend,_("You're dead! Game over.")); +void AllowNextShooter(Player *Play) +{ + Player *NextShooter; + + if (FightTimeout) { + NextShooter = GetNextShooter(Play); + if (NextShooter && !CanPlayerFire(NextShooter)) { + NextShooter->FightTimeout = 0; + } + } +} + +void DoReturnFire(Player *Play) +{ + guint ArrayInd; + Player *Defend; + + if (!Play || !Play->FightArray) + return; + + if (FightTimeout != 0 || !IsCop(Play)) { + for (ArrayInd = 0; + Play->FightArray && ArrayInd < Play->FightArray->len; + ArrayInd++) { + Defend = (Player *)g_ptr_array_index(Play->FightArray, ArrayInd); + if (IsCop(Defend) && CanPlayerFire(Defend)) + Fire(Defend); + } + } +} + +/* + * Withdraws player "Play" from combat, and levies any penalties on + * the player for this cowardly act, if applicable. If "ToLocation" + * is >=0, then it identifies the location that the player is + * trying to run to. + */ +void RunFromCombat(Player *Play, int ToLocation) +{ + int EscapeProb, RandNum; + guint ArrayInd; + gboolean FightingCop = FALSE; + Player *Defend; + char BackupAt; + + if (!Play || !Play->FightArray) + return; + + EscapeProb = 60; + + /* Penalise players that are attacking others */ + if (Play->Attacking) + EscapeProb /= 2; + + RandNum = brandom(0, 100); + + if (RandNum < EscapeProb) { + if (!IsCop(Play) && brandom(0, 100) < 30) { + for (ArrayInd = 0; ArrayInd < Play->FightArray->len; ArrayInd++) { + Defend = (Player *)g_ptr_array_index(Play->FightArray, ArrayInd); + if (IsCop(Defend)) { + FightingCop = TRUE; + break; + } } - } + if (FightingCop) + Play->CopIndex--; + } + BackupAt = Play->IsAt; + Play->IsAt = (char)ToLocation; + WithdrawFromCombat(Play); + Play->IsAt = BackupAt; + Play->EventNum = Play->ResyncNum; + SendEvent(Play); + } else { + SendFightMessage(Play, NULL, 0, F_FAILFLEE, (price_t)0, TRUE, NULL); + AllowNextShooter(Play); + if (FightTimeout) + SetFightTimeout(Play); + DoReturnFire(Play); + } +} + +void CheckForKilledPlayers(Player *Play) +{ + Player *Defend; + guint ArrayInd; + GPtrArray *KilledPlayers; - g_ptr_array_free(KilledPlayers,FALSE); + KilledPlayers = g_ptr_array_new(); + for (ArrayInd = 0; ArrayInd < Play->FightArray->len; ArrayInd++) { + Defend = (Player *)g_ptr_array_index(Play->FightArray, ArrayInd); + + if (Defend && Defend != Play && IsOpponent(Play, Defend) && + Defend->Health == 0) { + g_ptr_array_add(KilledPlayers, (gpointer)Defend); + } + } + for (ArrayInd = 0; ArrayInd < KilledPlayers->len; ArrayInd++) { + Defend = (Player *)g_ptr_array_index(KilledPlayers, ArrayInd); + WithdrawFromCombat(Defend); + if (IsCop(Defend)) { + if (!IsCop(Play)) + Play->CopIndex = -Defend->CopIndex; + FirstServer = RemovePlayer(Defend, FirstServer); + } else { + FinishGame(Defend, _("You're dead! Game over.")); + } + } + + g_ptr_array_free(KilledPlayers, FALSE); } -static void CheckCopsIntervene(Player *Play) { -/* If "Play" is attacking someone, and no cops are currently present, */ -/* then have the cops intervene (with a probability dependent on the */ -/* current location's PolicePresence) */ - guint ArrayInd; - Player *Defend; +/* + * If "Play" is attacking someone, and no cops are currently present, + * then have the cops intervene (with a probability dependent on the + * current location's PolicePresence) + */ +static void CheckCopsIntervene(Player *Play) +{ + guint ArrayInd; + Player *Defend; - if (!Play || !Play->FightArray) return; /* Sanity check */ + if (!Play || !Play->FightArray) + return; /* Sanity check */ - if (!Play->Attacking) return; /* Cops don't attack "innocent victims" ;) */ + if (!Play->Attacking) + return; /* Cops don't attack "innocent victims" ;) */ - if (brandom(0,100) > Location[(int)Play->IsAt].PolicePresence) { - return; /* The cops shouldn't _always_ attack (unless P.P. == 100) */ - } + if (brandom(0, 100) > Location[(int)Play->IsAt].PolicePresence) { + return; /* The cops shouldn't _always_ attack + * (unless P.P. == 100) */ + } - for (ArrayInd=0;Play->FightArray && ArrayInd<Play->FightArray->len; - ArrayInd++) { - Defend=(Player *)g_ptr_array_index(Play->FightArray,ArrayInd); - if (IsCop(Defend)) return; /* We don't want _more_ cops! */ - } + for (ArrayInd = 0; Play->FightArray && ArrayInd < Play->FightArray->len; + ArrayInd++) { + Defend = (Player *)g_ptr_array_index(Play->FightArray, ArrayInd); + if (IsCop(Defend)) + return; /* We don't want _more_ cops! */ + } - /* OK - let 'em have it... */ - CopsAttackPlayer(Play); + /* OK - let 'em have it... */ + CopsAttackPlayer(Play); } -static Player *GetFireTarget(Player *Play) { -/* Returns a suitable player (or cop) for "Play" to fire at. If "Play" */ -/* is attacking a designated target already, return that, otherwise */ -/* return the first valid opponent in the player's FightArray. */ - Player *Defend; - guint ArrayInd; +/* + * Returns a suitable player (or cop) for "Play" to fire at. If "Play" + * is attacking a designated target already, return that, otherwise + * return the first valid opponent in the player's FightArray. + */ +static Player *GetFireTarget(Player *Play) +{ + Player *Defend; + guint ArrayInd; - if (Play->Attacking && g_slist_find(FirstServer,(gpointer)Play->Attacking)) { - return Play->Attacking; - } else { - Play->Attacking=NULL; - for (ArrayInd=0;ArrayInd<Play->FightArray->len;ArrayInd++) { - Defend=(Player *)g_ptr_array_index(Play->FightArray,ArrayInd); - if (Defend && Defend!=Play && IsOpponent(Play,Defend)) { - return Defend; - } - } - } - return NULL; -} - -static int GetArmour(Player *Play) { - int Armour; - if (IsCop(Play)) { - if (Play->Bitches.Carried==0) Armour=Cop[Play->CopIndex-1].Armour; - else Armour=Cop[Play->CopIndex-1].DeputyArmour; - } else { - if (Play->Bitches.Carried==0) Armour=PlayerArmour; - else Armour=BitchArmour; - } - if (Armour==0) Armour=1; - return Armour; -} - -void Fire(Player *Play) { -/* Fires all weapons of player "Play" at an opponent, and resets */ -/* the fight timeout (the reload time) */ - int Damage,i,j; - int AttackRating,DefendRating; - int BitchesKilled; - price_t Loot; - FightPoint fp; - Player *Defend; - - if (!Play->FightArray) return; - if (!CanPlayerFire(Play)) return; - - AllowNextShooter(Play); - if (FightTimeout) SetFightTimeout(Play); - - Defend = GetFireTarget(Play); - if (Defend) { - Damage=0; BitchesKilled=0; Loot=0; - if (TotalGunsCarried(Play)>0) { - GetFightRatings(Play,Defend,&AttackRating,&DefendRating); - if (brandom(0,AttackRating)>brandom(0,DefendRating)) { - fp=F_HIT; - for (i=0;i<NumGun;i++) for (j=0;j<Play->Guns[i].Carried;j++) { - Damage+=brandom(0,Gun[i].Damage); - } - Damage=Damage*100/GetArmour(Defend); - if (Damage==0) Damage=1; - HandleDamage(Defend,Play,Damage,&BitchesKilled,&Loot); - } else fp=F_MISS; - } else fp=F_STAND; - SendFightMessage(Play,Defend,BitchesKilled,fp,Loot,TRUE,NULL); - } - CheckForKilledPlayers(Play); - -/* Careful, as we might have killed Player "Play" */ - if (g_slist_find(FirstServer,(gpointer)Play)) DoReturnFire(Play); - - if (g_slist_find(FirstServer,(gpointer)Play)) CheckCopsIntervene(Play); -} - -gboolean CanPlayerFire(Player *Play) { - return (FightTimeout==0 || Play->FightTimeout==0 || - Play->FightTimeout<=time(NULL)); -} - -gboolean CanRunHere(Player *Play) { - return (Play->ResyncNum < E_ARRIVE && Play->ResyncNum!=E_NONE); -} - -Player *GetNextShooter(Player *Play) { -/* To avoid boring waits, return the player who is next in line to be */ -/* able to shoot (i.e. with the smallest FightTimeout) so that this */ -/* player can be allowed to shoot immediately. If a player is already */ -/* eligible to shoot, or there is a tie for "first place" then do */ -/* nothing (i.e. return NULL) */ - Player *MinPlay,*Defend; - time_t MinTimeout; - guint ArrayInd; - gboolean Tie=FALSE; - - if (!FightTimeout) return NULL; - - MinPlay=NULL; MinTimeout=0; - for (ArrayInd=0;ArrayInd<Play->FightArray->len;ArrayInd++) { - Defend=(Player *)g_ptr_array_index(Play->FightArray,ArrayInd); - if (Defend==Play) continue; - if (Defend->FightTimeout==0) return NULL; - if (MinTimeout==0 || Defend->FightTimeout<=MinTimeout) { - Tie = (Defend->FightTimeout==MinTimeout); - MinPlay=Defend; MinTimeout=Defend->FightTimeout; + if (Play->Attacking + && g_slist_find(FirstServer, (gpointer)Play->Attacking)) { + return Play->Attacking; + } else { + Play->Attacking = NULL; + for (ArrayInd = 0; ArrayInd < Play->FightArray->len; ArrayInd++) { + Defend = (Player *)g_ptr_array_index(Play->FightArray, ArrayInd); + if (Defend && Defend != Play && IsOpponent(Play, Defend)) { + return Defend; } - } + } + } + return NULL; +} + +static int GetArmour(Player *Play) +{ + int Armour; - return (Tie ? NULL : MinPlay); + if (IsCop(Play)) { + if (Play->Bitches.Carried == 0) + Armour = Cop[Play->CopIndex - 1].Armour; + else + Armour = Cop[Play->CopIndex - 1].DeputyArmour; + } else { + if (Play->Bitches.Carried == 0) + Armour = PlayerArmour; + else + Armour = BitchArmour; + } + if (Armour == 0) + Armour = 1; + return Armour; +} + +/* + * Fires all weapons of player "Play" at an opponent, and resets + * the fight timeout (the reload time). + */ +void Fire(Player *Play) +{ + int Damage, i, j; + int AttackRating, DefendRating; + int BitchesKilled; + price_t Loot; + FightPoint fp; + Player *Defend; + + if (!Play->FightArray) + return; + if (!CanPlayerFire(Play)) + return; + + AllowNextShooter(Play); + if (FightTimeout) + SetFightTimeout(Play); + + Defend = GetFireTarget(Play); + if (Defend) { + Damage = 0; + BitchesKilled = 0; + Loot = 0; + if (TotalGunsCarried(Play) > 0) { + GetFightRatings(Play, Defend, &AttackRating, &DefendRating); + if (brandom(0, AttackRating) > brandom(0, DefendRating)) { + fp = F_HIT; + for (i = 0; i < NumGun; i++) + for (j = 0; j < Play->Guns[i].Carried; j++) { + Damage += brandom(0, Gun[i].Damage); + } + Damage = Damage * 100 / GetArmour(Defend); + if (Damage == 0) + Damage = 1; + HandleDamage(Defend, Play, Damage, &BitchesKilled, &Loot); + } else + fp = F_MISS; + } else + fp = F_STAND; + SendFightMessage(Play, Defend, BitchesKilled, fp, Loot, TRUE, NULL); + } + CheckForKilledPlayers(Play); + + /* Careful, as we might have killed Player "Play" */ + if (g_slist_find(FirstServer, (gpointer)Play)) + DoReturnFire(Play); + + if (g_slist_find(FirstServer, (gpointer)Play)) + CheckCopsIntervene(Play); +} + +gboolean CanPlayerFire(Player *Play) +{ + return (FightTimeout == 0 || Play->FightTimeout == 0 || + Play->FightTimeout <= time(NULL)); +} + +gboolean CanRunHere(Player *Play) +{ + return (Play->ResyncNum < E_ARRIVE && Play->ResyncNum != E_NONE); +} + +/* + * To avoid boring waits, return the player who is next in line to be + * able to shoot (i.e. with the smallest FightTimeout) so that this + * player can be allowed to shoot immediately. If a player is already + * eligible to shoot, or there is a tie for "first place" then do + * nothing (i.e. return NULL). + */ +Player *GetNextShooter(Player *Play) +{ + Player *MinPlay, *Defend; + time_t MinTimeout; + guint ArrayInd; + gboolean Tie = FALSE; + + if (!FightTimeout) + return NULL; + + MinPlay = NULL; + MinTimeout = 0; + for (ArrayInd = 0; ArrayInd < Play->FightArray->len; ArrayInd++) { + Defend = (Player *)g_ptr_array_index(Play->FightArray, ArrayInd); + if (Defend == Play) + continue; + if (Defend->FightTimeout == 0) + return NULL; + if (MinTimeout == 0 || Defend->FightTimeout <= MinTimeout) { + Tie = (Defend->FightTimeout == MinTimeout); + MinPlay = Defend; + MinTimeout = Defend->FightTimeout; + } + } + + return (Tie ? NULL : MinPlay); } -void ResolveTipoff(Player *Play) { - GString *text; +void ResolveTipoff(Player *Play) +{ + GString *text; - if (IsCop(Play) || !CanRunHere(Play)) return; + if (IsCop(Play) || !CanRunHere(Play)) + return; - if (g_slist_find(FirstServer,(gpointer)Play->OnBehalfOf)) { - dopelog(4,_("%s: tipoff by %s finished OK."),GetPlayerName(Play), - GetPlayerName(Play->OnBehalfOf)); - RemoveListPlayer(&(Play->TipList),Play->OnBehalfOf); - text=g_string_new(""); - if (Play->Health==0) { - g_string_sprintf(text, - _("Following your tipoff, the cops ambushed %s, who was shot dead!"), - GetPlayerName(Play)); - } else { - dpg_string_sprintf(text, - _("Following your tipoff, the cops ambushed %s, who escaped " - "with %d %tde. "),GetPlayerName(Play), - Play->Bitches.Carried,Names.Bitches); - } - GainBitch(Play->OnBehalfOf); - SendPlayerData(Play->OnBehalfOf); - SendPrintMessage(NULL,C_NONE,Play->OnBehalfOf,text->str); - g_string_free(text,TRUE); - } - Play->OnBehalfOf=NULL; -} - -void WithdrawFromCombat(Player *Play) { -/* Cleans up combat after player "Play" has left */ - guint AttackInd,DefendInd; - gboolean FightDone; - Player *Attack,*Defend; - GSList *list; - gchar *text; - - for (list=FirstServer;list;list=g_slist_next(list)) { - Attack=(Player *)list->data; - if (Attack->Attacking==Play) Attack->Attacking=NULL; - } - - if (!Play->FightArray) return; - - ResolveTipoff(Play); - FightDone=TRUE; - for (AttackInd=0;AttackInd<Play->FightArray->len;AttackInd++) { - Attack=(Player *)g_ptr_array_index(Play->FightArray,AttackInd); - for (DefendInd=0;DefendInd<AttackInd;DefendInd++) { - Defend=(Player *)g_ptr_array_index(Play->FightArray,DefendInd); - if (Attack!=Play && Defend!=Play && - IsOpponent(Attack,Defend)) { FightDone=FALSE; break; } - } - if (!FightDone) break; - } - - SendFightLeave(Play,FightDone); - g_ptr_array_remove(Play->FightArray,(gpointer)Play); - - if (FightDone) { - for (DefendInd=0;DefendInd<Play->FightArray->len;DefendInd++) { - Defend=(Player *)g_ptr_array_index(Play->FightArray,DefendInd); - Defend->FightArray=NULL; - ResolveTipoff(Defend); - if (IsCop(Defend)) { - FirstServer=RemovePlayer(Defend,FirstServer); - } else if (Defend->Health==0) { - FinishGame(Defend,_("You're dead! Game over.")); - } else if (CanRunHere(Defend) && - brandom(0,100)>Location[(int)Defend->IsAt].PolicePresence) { - Defend->EventNum=E_DOCTOR; - Defend->DocPrice=prandom(Bitch.MinPrice,Bitch.MaxPrice)* - Defend->Health/500; - text=dpg_strdup_printf( - _("YN^Do you pay a doctor %P to sew you up?"), - Defend->DocPrice); - SendQuestion(NULL,C_ASKSEW,Defend,text); - g_free(text); - } else { - Defend->EventNum=Defend->ResyncNum; SendEvent(Defend); - } - } - g_ptr_array_free(Play->FightArray,TRUE); - } - Play->FightArray=NULL; - Play->Attacking=NULL; -} - -int RandomOffer(Player *To) { -/* Inform player "To" of random offers or happenings. Returns 0 if */ -/* the client can immediately be advanced to the next state, or 1 */ -/* there are first questions to be answered. */ - int r,amount,ind; - GString *text; - r=brandom(0,100); - - text=g_string_new(NULL); - - if (!Sanitized && (r < 10)) { - g_string_assign(text,_("You were mugged in the subway!")); - To->Cash=To->Cash*(price_t)brandom(80,95)/100l; - } else if (r<30) { - amount=brandom(3,7); - ind=IsCarryingRandom(To,amount); - if (ind==-1 && amount>To->CoatSize) { - g_string_free(text,TRUE); return 0; + if (g_slist_find(FirstServer, (gpointer)Play->OnBehalfOf)) { + dopelog(4, _("%s: tipoff by %s finished OK."), GetPlayerName(Play), + GetPlayerName(Play->OnBehalfOf)); + RemoveListPlayer(&(Play->TipList), Play->OnBehalfOf); + text = g_string_new(""); + if (Play->Health == 0) { + g_string_sprintf(text, + _("Following your tipoff, the cops ambushed %s, " + "who was shot dead!"), GetPlayerName(Play)); + } else { + dpg_string_sprintf(text, + _("Following your tipoff, the cops ambushed %s, " + "who escaped with %d %tde. "), GetPlayerName(Play), + Play->Bitches.Carried, Names.Bitches); + } + GainBitch(Play->OnBehalfOf); + SendPlayerData(Play->OnBehalfOf); + SendPrintMessage(NULL, C_NONE, Play->OnBehalfOf, text->str); + g_string_free(text, TRUE); + } + Play->OnBehalfOf = NULL; +} + +/* + * Cleans up combat after player "Play" has left. + */ +void WithdrawFromCombat(Player *Play) +{ + guint AttackInd, DefendInd; + gboolean FightDone; + Player *Attack, *Defend; + GSList *list; + gchar *text; + + for (list = FirstServer; list; list = g_slist_next(list)) { + Attack = (Player *)list->data; + if (Attack->Attacking == Play) + Attack->Attacking = NULL; + } + + if (!Play->FightArray) + return; + + ResolveTipoff(Play); + FightDone = TRUE; + for (AttackInd = 0; AttackInd < Play->FightArray->len; AttackInd++) { + Attack = (Player *)g_ptr_array_index(Play->FightArray, AttackInd); + for (DefendInd = 0; DefendInd < AttackInd; DefendInd++) { + Defend = (Player *)g_ptr_array_index(Play->FightArray, DefendInd); + if (Attack != Play && Defend != Play && IsOpponent(Attack, Defend)) { + FightDone = FALSE; + break; } - if (ind==-1) { - ind=brandom(0,NumDrug); - dpg_string_sprintf(text,_("You meet a friend! He gives you %d %tde."), - amount,Drug[ind].Name); - To->Drugs[ind].Carried+=amount; - To->CoatSize-=amount; + } + if (!FightDone) + break; + } + + SendFightLeave(Play, FightDone); + g_ptr_array_remove(Play->FightArray, (gpointer)Play); + + if (FightDone) { + for (DefendInd = 0; DefendInd < Play->FightArray->len; DefendInd++) { + Defend = (Player *)g_ptr_array_index(Play->FightArray, DefendInd); + Defend->FightArray = NULL; + ResolveTipoff(Defend); + if (IsCop(Defend)) { + FirstServer = RemovePlayer(Defend, FirstServer); + } else if (Defend->Health == 0) { + FinishGame(Defend, _("You're dead! Game over.")); + } else if (CanRunHere(Defend) && + brandom(0, + 100) > + Location[(int)Defend->IsAt].PolicePresence) { + Defend->EventNum = E_DOCTOR; + Defend->DocPrice = prandom(Bitch.MinPrice, Bitch.MaxPrice) * + Defend->Health / 500; + text = + dpg_strdup_printf(_ + ("YN^Do you pay a doctor %P to sew you up?"), + Defend->DocPrice); + SendQuestion(NULL, C_ASKSEW, Defend, text); + g_free(text); } else { - dpg_string_sprintf(text,_("You meet a friend! You give him %d %tde."), - amount,Drug[ind].Name); - To->Drugs[ind].TotalValue = To->Drugs[ind].TotalValue* - (To->Drugs[ind].Carried-amount)/To->Drugs[ind].Carried; - To->Drugs[ind].Carried-=amount; - To->CoatSize+=amount; + Defend->EventNum = Defend->ResyncNum; + SendEvent(Defend); } + } + g_ptr_array_free(Play->FightArray, TRUE); + } + Play->FightArray = NULL; + Play->Attacking = NULL; +} + +/* + * Inform player "To" of random offers or happenings. Returns 0 if + * the client can immediately be advanced to the next state, or 1 + * there are first questions to be answered. + */ +int RandomOffer(Player *To) +{ + int r, amount, ind; + GString *text; + + r = brandom(0, 100); + + text = g_string_new(NULL); + + if (!Sanitized && (r < 10)) { + g_string_assign(text, _("You were mugged in the subway!")); + To->Cash = To->Cash * (price_t)brandom(80, 95) / 100l; + } else if (r < 30) { + amount = brandom(3, 7); + ind = IsCarryingRandom(To, amount); + if (ind == -1 && amount > To->CoatSize) { + g_string_free(text, TRUE); + return 0; + } + if (ind == -1) { + ind = brandom(0, NumDrug); + dpg_string_sprintf(text, + _("You meet a friend! He gives you %d %tde."), + amount, Drug[ind].Name); + To->Drugs[ind].Carried += amount; + To->CoatSize -= amount; + } else { + dpg_string_sprintf(text, + _("You meet a friend! You give him %d %tde."), + amount, Drug[ind].Name); + To->Drugs[ind].TotalValue = + To->Drugs[ind].TotalValue * (To->Drugs[ind].Carried - + amount) / To->Drugs[ind].Carried; + To->Drugs[ind].Carried -= amount; + To->CoatSize += amount; + } + SendPlayerData(To); + SendPrintMessage(NULL, C_NONE, To, text->str); + } else if (Sanitized) { + dopelog(3, _("Sanitized away a RandomOffer")); + } else if (r < 50) { + amount = brandom(3, 7); + ind = IsCarryingRandom(To, amount); + if (ind != -1) { + dpg_string_sprintf(text, _("Police dogs chase you for %d blocks! " + "You dropped some %tde! That's a drag, man!"), + brandom(3, 7), Names.Drugs); + To->Drugs[ind].TotalValue = To->Drugs[ind].TotalValue * + (To->Drugs[ind].Carried - amount) / To->Drugs[ind].Carried; + To->Drugs[ind].Carried -= amount; + To->CoatSize += amount; SendPlayerData(To); - SendPrintMessage(NULL,C_NONE,To,text->str); - } else if (Sanitized) { - dopelog(3,_("Sanitized away a RandomOffer")); - } else if (r<50) { - amount=brandom(3,7); - ind=IsCarryingRandom(To,amount); - if (ind!=-1) { - dpg_string_sprintf(text,_("Police dogs chase you for %d blocks! " - "You dropped some %tde! That's a drag, man!"), - brandom(3,7),Names.Drugs); - To->Drugs[ind].TotalValue = To->Drugs[ind].TotalValue* - (To->Drugs[ind].Carried-amount)/To->Drugs[ind].Carried; - To->Drugs[ind].Carried-=amount; - To->CoatSize+=amount; - SendPlayerData(To); - SendPrintMessage(NULL,C_NONE,To,text->str); - } else { - ind=brandom(0,NumDrug); - amount=brandom(3,7); - if (amount>To->CoatSize) { - g_string_free(text,TRUE); return 0; - } - dpg_string_sprintf(text, - _("You find %d %tde on a dead dude in the subway!"), - amount,Drug[ind].Name); - To->Drugs[ind].Carried+=amount; - To->CoatSize-=amount; - SendPlayerData(To); - SendPrintMessage(NULL,C_NONE,To,text->str); + SendPrintMessage(NULL, C_NONE, To, text->str); + } else { + ind = brandom(0, NumDrug); + amount = brandom(3, 7); + if (amount > To->CoatSize) { + g_string_free(text, TRUE); + return 0; } - } else if (r<60 && To->Drugs[WEED].Carried+To->Drugs[HASHISH].Carried>0) { - ind = (To->Drugs[WEED].Carried>To->Drugs[HASHISH].Carried) ? - WEED : HASHISH; - amount=brandom(2,6); - if (amount>To->Drugs[ind].Carried) amount=To->Drugs[ind].Carried; dpg_string_sprintf(text, - _("Your mama made brownies with some of your %tde! " - "They were great!"),Drug[ind].Name); - To->Drugs[ind].TotalValue = To->Drugs[ind].TotalValue* - (To->Drugs[ind].Carried-amount)/To->Drugs[ind].Carried; - To->Drugs[ind].Carried-=amount; - To->CoatSize+=amount; - SendPlayerData(To); - SendPrintMessage(NULL,C_NONE,To,text->str); - } else if (r<65) { - g_string_assign(text, - _("YN^There is some weed that smells like paraquat here!" - "^It looks good! Will you smoke it? ")); - To->EventNum=E_WEED; - SendQuestion(NULL,C_NONE,To,text->str); - g_string_free(text,TRUE); - return 1; - } else { - g_string_sprintf(text,_("You stopped to %s."), - StoppedTo[brandom(0,NumStoppedTo)]); - amount=brandom(1,10); - if (To->Cash>=amount) To->Cash-=amount; + _("You find %d %tde on a dead dude in the subway!"), + amount, Drug[ind].Name); + To->Drugs[ind].Carried += amount; + To->CoatSize -= amount; SendPlayerData(To); - SendPrintMessage(NULL,C_NONE,To,text->str); - } - g_string_free(text,TRUE); - return 0; -} - -int OfferObject(Player *To,gboolean ForceBitch) { -/* Offers player "To" bitches/trenchcoats or guns. If ForceBitch is */ -/* TRUE, then a bitch is definitely offered. Returns 0 if the client */ -/* can advance immediately to the next state, 1 otherwise. */ - int ObjNum; - gchar *text=NULL; - - if (brandom(0,100)<50 || ForceBitch) { - if (WantAntique) { - To->Bitches.Price=prandom(MINTRENCHPRICE,MAXTRENCHPRICE); - text=dpg_strdup_printf(_("YN^Would you like to buy a bigger " - "trenchcoat for %P?"),To->Bitches.Price); + SendPrintMessage(NULL, C_NONE, To, text->str); + } + } else if (r < 60 + && To->Drugs[WEED].Carried + To->Drugs[HASHISH].Carried > 0) { + ind = (To->Drugs[WEED].Carried > + To->Drugs[HASHISH].Carried) ? WEED : HASHISH; + amount = brandom(2, 6); + if (amount > To->Drugs[ind].Carried) + amount = To->Drugs[ind].Carried; + dpg_string_sprintf(text, + _("Your mama made brownies with some of your %tde! " + "They were great!"), Drug[ind].Name); + To->Drugs[ind].TotalValue = To->Drugs[ind].TotalValue * + (To->Drugs[ind].Carried - amount) / To->Drugs[ind].Carried; + To->Drugs[ind].Carried -= amount; + To->CoatSize += amount; + SendPlayerData(To); + SendPrintMessage(NULL, C_NONE, To, text->str); + } else if (r < 65) { + g_string_assign(text, + _("YN^There is some weed that smells like paraquat " + "here!^It looks good! Will you smoke it? ")); + To->EventNum = E_WEED; + SendQuestion(NULL, C_NONE, To, text->str); + g_string_free(text, TRUE); + return 1; + } else { + g_string_sprintf(text, _("You stopped to %s."), + StoppedTo[brandom(0, NumStoppedTo)]); + amount = brandom(1, 10); + if (To->Cash >= amount) + To->Cash -= amount; + SendPlayerData(To); + SendPrintMessage(NULL, C_NONE, To, text->str); + } + g_string_free(text, TRUE); + return 0; +} + +/* + * Offers player "To" bitches/trenchcoats or guns. If ForceBitch is + * TRUE, then a bitch is definitely offered. Returns 0 if the client + * can advance immediately to the next state, 1 otherwise. + */ +int OfferObject(Player *To, gboolean ForceBitch) +{ + int ObjNum; + gchar *text = NULL; + + if (brandom(0, 100) < 50 || ForceBitch) { + if (WantAntique) { + To->Bitches.Price = prandom(MINTRENCHPRICE, MAXTRENCHPRICE); + text = dpg_strdup_printf(_("YN^Would you like to buy a bigger " + "trenchcoat for %P?"), To->Bitches.Price); + } else { + To->Bitches.Price = + prandom(Bitch.MinPrice, Bitch.MaxPrice) / (price_t)10; + text = + dpg_strdup_printf(_ + ("YN^Hey dude! I'll help carry your %tde for a " + "mere %P. Yes or no?"), Names.Drugs, + To->Bitches.Price); + } + SendQuestion(NULL, C_ASKBITCH, To, text); + g_free(text); + return 1; + } else if (!Sanitized + && (TotalGunsCarried(To) < To->Bitches.Carried + 2)) { + ObjNum = brandom(0, NumGun); + To->Guns[ObjNum].Price = Gun[ObjNum].Price / 10; + if (Gun[ObjNum].Space > To->CoatSize) + return 0; + text = dpg_strdup_printf(_("YN^Would you like to buy a %tde for %P?"), + Gun[ObjNum].Name, To->Guns[ObjNum].Price); + SendQuestion(NULL, C_ASKGUN, To, text); + g_free(text); + return 1; + } + return 0; +} + +/* + * Sends details of drug prices to player "To". If "DisplayBusts" + * is TRUE, also regenerates drug prices and sends details of + * special events such as drug busts. + */ +void SendDrugsHere(Player *To, gboolean DisplayBusts) +{ + int i; + gchar *Deal, *prstr; + GString *text; + gboolean First; + + Deal = g_malloc0(NumDrug); + if (DisplayBusts) + GenerateDrugsHere(To, Deal); + + text = g_string_new(NULL); + First = TRUE; + if (DisplayBusts) + for (i = 0; i < NumDrug; i++) + if (Deal[i]) { + if (!First) + g_string_append_c(text, '^'); + if (Drug[i].Expensive) { + dpg_string_sprintfa(text, Deal[i] == 1 ? Drugs.ExpensiveStr1 : + Drugs.ExpensiveStr2, Drug[i].Name); + } else if (Drug[i].Cheap) { + g_string_append(text, Drug[i].CheapStr); + } + First = FALSE; + } + if (!First) + SendPrintMessage(NULL, C_NONE, To, text->str); + g_string_truncate(text, 0); + for (i = 0; i < NumDrug; i++) { + g_string_sprintfa(text, "%s^", + (prstr = pricetostr(To->Drugs[i].Price))); + g_free(prstr); + } + SendServerMessage(NULL, C_NONE, C_DRUGHERE, To, text->str); + g_string_free(text, TRUE); +} + +/* + * Generates drug prices and drug busts etc. for player "To" + * "Deal" is an array of chars of size NumDrug. + */ +void GenerateDrugsHere(Player *To, gchar *Deal) +{ + int NumEvents, NumDrugs, NumRandom, i; + + for (i = 0; i < NumDrug; i++) { + To->Drugs[i].Price = 0; + Deal[i] = 0; + } + NumEvents = 0; + if (brandom(0, 100) < 70) + NumEvents = 1; + if (brandom(0, 100) < 40 && NumEvents == 1) + NumEvents = 2; + if (brandom(0, 100) < 5 && NumEvents == 2) + NumEvents = 3; + NumDrugs = 0; + while (NumEvents > 0) { + i = brandom(0, NumDrug); + if (Deal[i] != 0) + continue; + if (Drug[i].Expensive && (!Drug[i].Cheap || brandom(0, 100) < 50)) { + Deal[i] = brandom(1, 3); + To->Drugs[i].Price = prandom(Drug[i].MinPrice, Drug[i].MaxPrice) + * Drugs.ExpensiveMultiply; + NumDrugs++; + NumEvents--; + } else if (Drug[i].Cheap) { + Deal[i] = 1; + To->Drugs[i].Price = prandom(Drug[i].MinPrice, Drug[i].MaxPrice) + / Drugs.CheapDivide; + NumDrugs++; + NumEvents--; + } + } + NumRandom = brandom(Location[(int)To->IsAt].MinDrug, + Location[(int)To->IsAt].MaxDrug); + if (NumRandom > NumDrug) + NumRandom = NumDrug; + + NumDrugs = NumRandom - NumDrugs; + while (NumDrugs > 0) { + i = brandom(0, NumDrug); + if (To->Drugs[i].Price == 0) { + To->Drugs[i].Price = prandom(Drug[i].MinPrice, Drug[i].MaxPrice); + NumDrugs--; + } + } +} + +/* + * Handles the incoming message in "answer" from player "From" and + * intended for player "To". + */ +void HandleAnswer(Player *From, Player *To, char *answer) +{ + int i; + gchar *text; + Player *Defender; + + if (!From || From->EventNum == E_NONE) + return; + if (answer[0] == 'Y' && From->EventNum == E_OFFOBJECT + && From->Bitches.Price && From->Bitches.Price > From->Cash) + answer[0] = 'N'; + if ((From->EventNum == E_FIGHT || From->EventNum == E_FIGHTASK) && + CanRunHere(From)) { + From->EventNum = E_FIGHT; + if (answer[0] == 'R' || answer[0] == 'Y') + RunFromCombat(From, -1); + else + Fire(From); + } else if (answer[0] == 'Y') + switch (From->EventNum) { + case E_OFFOBJECT: + if (g_slist_find(FirstServer, (gpointer)From->OnBehalfOf)) { + dopelog(3, _("%s: offer was on behalf of %s"), GetPlayerName(From), + GetPlayerName(From->OnBehalfOf)); + if (From->Bitches.Price) { + text = dpg_strdup_printf(_("%s has accepted your %tde!" + "^Use the G key to contact your spy."), + GetPlayerName(From), Names.Bitch); + From->OnBehalfOf->Flags |= SPYINGON; + SendPlayerData(From->OnBehalfOf); + SendPrintMessage(NULL, C_NONE, From->OnBehalfOf, text); + g_free(text); + i = GetListEntry(&(From->SpyList), From->OnBehalfOf); + if (i >= 0) + From->SpyList.Data[i].Turns = 0; + } + } + if (From->Bitches.Price) { + text = g_strdup_printf("bitch^0^1"); + BuyObject(From, text); + g_free(text); } else { - To->Bitches.Price=prandom(Bitch.MinPrice,Bitch.MaxPrice)/(price_t)10; - text=dpg_strdup_printf( - _("YN^Hey dude! I'll help carry your %tde for a " - "mere %P. Yes or no?"),Names.Drugs,To->Bitches.Price); + for (i = 0; i < NumGun; i++) + if (From->Guns[i].Price) { + text = g_strdup_printf("gun^%d^1", i); + BuyObject(From, text); + g_free(text); + break; + } } - SendQuestion(NULL,C_ASKBITCH,To,text); - g_free(text); - return 1; - } else if (!Sanitized && (TotalGunsCarried(To) < To->Bitches.Carried+2)) { - ObjNum=brandom(0,NumGun); - To->Guns[ObjNum].Price=Gun[ObjNum].Price/10; - if (Gun[ObjNum].Space>To->CoatSize) return 0; - text=dpg_strdup_printf(_("YN^Would you like to buy a %tde for %P?"), - Gun[ObjNum].Name,To->Guns[ObjNum].Price); - SendQuestion(NULL,C_ASKGUN,To,text); + From->OnBehalfOf = NULL; + From->EventNum++; + SendEvent(From); + break; + case E_LOANSHARK: + SendServerMessage(NULL, C_NONE, C_LOANSHARK, From, NULL); + break; + case E_BANK: + SendServerMessage(NULL, C_NONE, C_BANK, From, NULL); + break; + case E_GUNSHOP: + for (i = 0; i < NumGun; i++) + From->Guns[i].Price = Gun[i].Price; + SendServerMessage(NULL, C_NONE, C_GUNSHOP, From, NULL); + break; + case E_HIREBITCH: + text = g_strdup_printf("bitch^0^1"); + BuyObject(From, text); g_free(text); - return 1; - } - return 0; -} - -void SendDrugsHere(Player *To,gboolean DisplayBusts) { -/* Sends details of drug prices to player "To". If "DisplayBusts" */ -/* is TRUE, also regenerates drug prices and sends details of */ -/* special events such as drug busts */ - int i; - gchar *Deal,*prstr; - GString *text; - gboolean First; - - Deal=g_malloc0(NumDrug); - if (DisplayBusts) GenerateDrugsHere(To,Deal); - - text=g_string_new(NULL); - First=TRUE; - if (DisplayBusts) for (i=0;i<NumDrug;i++) if (Deal[i]) { - if (!First) g_string_append_c(text,'^'); - if (Drug[i].Expensive) { - dpg_string_sprintfa(text,Deal[i]==1 ? Drugs.ExpensiveStr1 : - Drugs.ExpensiveStr2,Drug[i].Name); - } else if (Drug[i].Cheap) { - g_string_append(text,Drug[i].CheapStr); - } - First=FALSE; - } - if (!First) SendPrintMessage(NULL,C_NONE,To,text->str); - g_string_truncate(text,0); - for (i=0;i<NumDrug;i++) { - g_string_sprintfa(text,"%s^",(prstr=pricetostr(To->Drugs[i].Price))); - g_free(prstr); - } - SendServerMessage(NULL,C_NONE,C_DRUGHERE,To,text->str); - g_string_free(text,TRUE); -} - -void GenerateDrugsHere(Player *To,gchar *Deal) { -/* Generates drug prices and drug busts etc. for player "To" */ -/* "Deal" is an array of chars of size NumDrug */ - int NumEvents,NumDrugs,NumRandom,i; - for (i=0;i<NumDrug;i++) { - To->Drugs[i].Price=0; - Deal[i]=0; - } - NumEvents=0; - if (brandom(0,100)<70) NumEvents=1; - if (brandom(0,100)<40 && NumEvents==1) NumEvents=2; - if (brandom(0,100)<5 && NumEvents==2) NumEvents=3; - NumDrugs=0; - while (NumEvents>0) { - i=brandom(0,NumDrug); - if (Deal[i]!=0) continue; - if (Drug[i].Expensive && (!Drug[i].Cheap || brandom(0,100)<50)) { - Deal[i]=brandom(1,3); - To->Drugs[i].Price=prandom(Drug[i].MinPrice,Drug[i].MaxPrice) - *Drugs.ExpensiveMultiply; - NumDrugs++; - NumEvents--; - } else if (Drug[i].Cheap) { - Deal[i]=1; - To->Drugs[i].Price=prandom(Drug[i].MinPrice,Drug[i].MaxPrice) - /Drugs.CheapDivide; - NumDrugs++; - NumEvents--; - } - } - NumRandom=brandom(Location[(int)To->IsAt].MinDrug, - Location[(int)To->IsAt].MaxDrug); - if (NumRandom > NumDrug) NumRandom=NumDrug; - - NumDrugs=NumRandom-NumDrugs; - while (NumDrugs>0) { - i=brandom(0,NumDrug); - if (To->Drugs[i].Price==0) { - To->Drugs[i].Price=prandom(Drug[i].MinPrice,Drug[i].MaxPrice); - NumDrugs--; + From->EventNum++; + SendEvent(From); + break; + case E_ROUGHPUB: + From->EventNum++; + SendEvent(From); + break; + case E_WEED: + FinishGame(From, _("You hallucinated for three days on the wildest " + "trip you ever imagined!^Then you died because " + "your brain disintegrated!")); + break; + case E_DOCTOR: + if (From->Cash >= From->DocPrice) { + From->Cash -= From->DocPrice; + From->Health = 100; + SendPlayerData(From); } - } -} - -void HandleAnswer(Player *From,Player *To,char *answer) { -/* Handles the incoming message in "answer" from player "From" and */ -/* intended for player "To". */ - int i; - gchar *text; - Player *Defender; - if (!From || From->EventNum==E_NONE) return; - if (answer[0]=='Y' && From->EventNum==E_OFFOBJECT && From->Bitches.Price - && From->Bitches.Price>From->Cash) answer[0]='N'; - if ((From->EventNum==E_FIGHT || From->EventNum==E_FIGHTASK) && - CanRunHere(From)) { - From->EventNum=E_FIGHT; - if (answer[0]=='R' || answer[0]=='Y') RunFromCombat(From,-1); - else Fire(From); - } else if (answer[0]=='Y') switch (From->EventNum) { - case E_OFFOBJECT: - if (g_slist_find(FirstServer,(gpointer)From->OnBehalfOf)) { - dopelog(3,_("%s: offer was on behalf of %s"),GetPlayerName(From), - GetPlayerName(From->OnBehalfOf)); - if (From->Bitches.Price) { - text=dpg_strdup_printf(_("%s has accepted your %tde!" - "^Use the G key to contact your spy."), - GetPlayerName(From),Names.Bitch); - From->OnBehalfOf->Flags |= SPYINGON; - SendPlayerData(From->OnBehalfOf); - SendPrintMessage(NULL,C_NONE,From->OnBehalfOf,text); - g_free(text); - i=GetListEntry(&(From->SpyList),From->OnBehalfOf); - if (i>=0) From->SpyList.Data[i].Turns=0; - } - } - if (From->Bitches.Price) { - text=g_strdup_printf("bitch^0^1"); - BuyObject(From,text); - g_free(text); - } else { - for (i=0;i<NumGun;i++) if (From->Guns[i].Price) { - text=g_strdup_printf("gun^%d^1",i); - BuyObject(From,text); - g_free(text); - break; - } - } - From->OnBehalfOf=NULL; - From->EventNum++; SendEvent(From); - break; - case E_LOANSHARK: - SendServerMessage(NULL,C_NONE,C_LOANSHARK,From,NULL); - break; - case E_BANK: - SendServerMessage(NULL,C_NONE,C_BANK,From,NULL); - break; - case E_GUNSHOP: - for (i=0;i<NumGun;i++) From->Guns[i].Price=Gun[i].Price; - SendServerMessage(NULL,C_NONE,C_GUNSHOP,From,NULL); - break; - case E_HIREBITCH: - text=g_strdup_printf("bitch^0^1"); - BuyObject(From,text); - g_free(text); - From->EventNum++; SendEvent(From); - break; - case E_ROUGHPUB: - From->EventNum++; SendEvent(From); - break; - case E_WEED: - FinishGame(From,_("You hallucinated for three days on the wildest " -"trip you ever imagined!^Then you died because your brain disintegrated!")); - break; - case E_DOCTOR: - if (From->Cash >= From->DocPrice) { - From->Cash -= From->DocPrice; - From->Health=100; - SendPlayerData(From); - } - From->EventNum=From->ResyncNum; SendEvent(From); - break; - default: - break; - } else if (From->EventNum==E_ARRIVE) { - if ((answer[0]=='A' || answer[0]=='T') && - IsConnectedPlayer(From->OnBehalfOf) && - g_slist_find(FirstServer,(gpointer)From->OnBehalfOf)) { - Defender=From->OnBehalfOf; - From->OnBehalfOf=NULL; /* So we don't think it was a tipoff */ - if (Defender->IsAt==From->IsAt) { - if (answer[0]=='A') { - From->EventNum=Defender->EventNum=E_NONE; - AttackPlayer(From,Defender); -/* } else if (answer[0]=='T') { - From->Flags |= TRADING; - SendPlayerData(From); - SendServerMessage(NULL,C_NONE,C_TRADE,From,NULL);*/ - } - } else { - text=g_strdup_printf(_("Too late - %s has just left!"), - GetPlayerName(Defender)); - SendPrintMessage(NULL,C_NONE,From,text); - g_free(text); - From->EventNum++; SendEvent(From); - } + From->EventNum = From->ResyncNum; + SendEvent(From); + break; + default: + break; + } else if (From->EventNum == E_ARRIVE) { + if ((answer[0] == 'A' || answer[0] == 'T') && + IsConnectedPlayer(From->OnBehalfOf) && + g_slist_find(FirstServer, (gpointer)From->OnBehalfOf)) { + Defender = From->OnBehalfOf; + From->OnBehalfOf = NULL; /* So we don't think it was a tipoff */ + if (Defender->IsAt == From->IsAt) { + if (answer[0] == 'A') { + From->EventNum = Defender->EventNum = E_NONE; + AttackPlayer(From, Defender); + } } else { - From->EventNum++; SendEvent(From); + text = g_strdup_printf(_("Too late - %s has just left!"), + GetPlayerName(Defender)); + SendPrintMessage(NULL, C_NONE, From, text); + g_free(text); + From->EventNum++; + SendEvent(From); } - From->OnBehalfOf=NULL; - } else switch(From->EventNum) { - case E_ROUGHPUB: - From->EventNum++; - From->EventNum++; SendEvent(From); - break; - case E_DOCTOR: - From->EventNum=From->ResyncNum; SendEvent(From); - break; - case E_HIREBITCH: case E_GUNSHOP: case E_BANK: case E_LOANSHARK: - case E_OFFOBJECT: case E_WEED: - if (g_slist_find(FirstServer,(gpointer)From->OnBehalfOf)) { - dopelog(3,_("%s: offer was on behalf of %s"),GetPlayerName(From), - GetPlayerName(From->OnBehalfOf)); - if (From->Bitches.Price && From->EventNum==E_OFFOBJECT) { - text=dpg_strdup_printf(_("%s has rejected your %tde!"), - GetPlayerName(From),Names.Bitch); - GainBitch(From->OnBehalfOf); - SendPlayerData(From->OnBehalfOf); - SendPrintMessage(NULL,C_NONE,From->OnBehalfOf,text); - g_free(text); - RemoveListPlayer(&(From->SpyList),From->OnBehalfOf); - } - } - From->EventNum++; SendEvent(From); - break; - default: - break; - } -} - -void BuyObject(Player *From,char *data) { -/* Processes a request stored in "data" from player "From" to buy an */ -/* object (bitch, gun, or drug) */ -/* Objects can be sold if the amount given in "data" is negative, and */ -/* given away if their current price is zero. */ - char *cp,*type; - int index,i,amount; - cp=data; - type=GetNextWord(&cp,""); - index=GetNextInt(&cp,0); - amount=GetNextInt(&cp,0); - if (strcmp(type,"drug")==0) { - if (index>=0 && index<NumDrug && From->Drugs[index].Carried+amount >= 0 - && From->CoatSize-amount >= 0 && (From->Drugs[index].Price!=0 || - amount<0) && From->Cash >= amount*From->Drugs[index].Price) { - if (amount>0) { - From->Drugs[index].TotalValue+=amount*From->Drugs[index].Price; - } else if (From->Drugs[index].Carried!=0) { - From->Drugs[index].TotalValue = From->Drugs[index].TotalValue* - (From->Drugs[index].Carried+amount)/From->Drugs[index].Carried; - } - From->Drugs[index].Carried+=amount; - From->CoatSize-=amount; - From->Cash-=amount*From->Drugs[index].Price; - SendPlayerData(From); - - if (!Sanitized && (From->Drugs[index].Price==0 && - brandom(0,100)<Location[(int)From->IsAt].PolicePresence)) { - SendPrintMessage(NULL,C_NONE,From, - _("The cops spot you dropping drugs!")); - CopsAttackPlayer(From); - } + } else { + From->EventNum++; + SendEvent(From); + } + From->OnBehalfOf = NULL; + } else + switch (From->EventNum) { + case E_ROUGHPUB: + From->EventNum++; + From->EventNum++; + SendEvent(From); + break; + case E_DOCTOR: + From->EventNum = From->ResyncNum; + SendEvent(From); + break; + case E_HIREBITCH: + case E_GUNSHOP: + case E_BANK: + case E_LOANSHARK: + case E_OFFOBJECT: + case E_WEED: + if (g_slist_find(FirstServer, (gpointer)From->OnBehalfOf)) { + dopelog(3, _("%s: offer was on behalf of %s"), GetPlayerName(From), + GetPlayerName(From->OnBehalfOf)); + if (From->Bitches.Price && From->EventNum == E_OFFOBJECT) { + text = dpg_strdup_printf(_("%s has rejected your %tde!"), + GetPlayerName(From), Names.Bitch); + GainBitch(From->OnBehalfOf); + SendPlayerData(From->OnBehalfOf); + SendPrintMessage(NULL, C_NONE, From->OnBehalfOf, text); + g_free(text); + RemoveListPlayer(&(From->SpyList), From->OnBehalfOf); + } } - } else if (strcmp(type,"gun")==0) { - if (index>=0 && index<NumGun && TotalGunsCarried(From)+amount >= 0 - && TotalGunsCarried(From)+amount <= From->Bitches.Carried+2 - && From->Guns[index].Price!=0 - && From->CoatSize-amount*Gun[index].Space >= 0 - && From->Cash >= amount*From->Guns[index].Price) { - From->Guns[index].Carried+=amount; - From->CoatSize-=amount*Gun[index].Space; - From->Cash-=amount*From->Guns[index].Price; - SendPlayerData(From); + From->EventNum++; + SendEvent(From); + break; + default: + break; + } +} + +/* + * Processes a request stored in "data" from player "From" to buy an + * object (bitch, gun, or drug). + * Objects can be sold if the amount given in "data" is negative, and + * given away if their current price is zero. + */ +void BuyObject(Player *From, char *data) +{ + char *cp, *type; + int index, i, amount; + + cp = data; + type = GetNextWord(&cp, ""); + index = GetNextInt(&cp, 0); + amount = GetNextInt(&cp, 0); + if (strcmp(type, "drug") == 0) { + if (index >= 0 && index < NumDrug + && From->Drugs[index].Carried + amount >= 0 + && From->CoatSize - amount >= 0 && (From->Drugs[index].Price != 0 + || amount < 0) + && From->Cash >= amount * From->Drugs[index].Price) { + if (amount > 0) { + From->Drugs[index].TotalValue += amount * From->Drugs[index].Price; + } else if (From->Drugs[index].Carried != 0) { + From->Drugs[index].TotalValue = From->Drugs[index].TotalValue * + (From->Drugs[index].Carried + + amount) / From->Drugs[index].Carried; } - } else if (strcmp(type,"bitch")==0) { - if (From->Bitches.Carried+amount >= 0 - && From->Bitches.Price!=0 - && amount*From->Bitches.Price <= From->Cash) { - for (i=0;i<amount;i++) GainBitch(From); - if (amount>0) From->Cash-=amount*From->Bitches.Price; - SendPlayerData(From); + From->Drugs[index].Carried += amount; + From->CoatSize -= amount; + From->Cash -= amount * From->Drugs[index].Price; + SendPlayerData(From); + + if (!Sanitized && (From->Drugs[index].Price == 0 && + brandom(0, + 100) < + Location[(int)From->IsAt].PolicePresence)) { + SendPrintMessage(NULL, C_NONE, From, + _("The cops spot you dropping drugs!")); + CopsAttackPlayer(From); } - } -} - -void ClearPrices(Player *Play) { -/* Clears the bitch and gun prices stored for player "Play" */ - int i; - Play->Bitches.Price=0; - for (i=0;i<NumGun;i++) Play->Guns[i].Price=0; -} - -void GainBitch(Player *Play) { -/* Gives player "Play" a new bitch (or larger trenchcoat) */ - Play->CoatSize+=10; - Play->Bitches.Carried++; -} - -int LoseBitch(Player *Play,Inventory *Guns,Inventory *Drugs) { -/* Loses one bitch belonging to player "Play". If drugs or guns are */ -/* lost with the bitch, 1 is returned (0 otherwise) and the lost */ -/* items are added to "Guns" and "Drugs" if non-NULL */ - int losedrug=0,i,num,drugslost; - int *GunIndex,tmp; - GunIndex=g_new(int,NumGun); - ClearInventory(Guns,Drugs); - Play->CoatSize-=10; - if (TotalGunsCarried(Play)>0) { - if (brandom(0,100)<TotalGunsCarried(Play)*100/(Play->Bitches.Carried+2)) { - for (i=0;i<NumGun;i++) GunIndex[i]=i; - for (i=0;i<NumGun*5;i++) { - num=brandom(0,NumGun-1); - tmp=GunIndex[num+1]; - GunIndex[num+1]=GunIndex[num]; - GunIndex[num]=tmp; - } - for (i=0;i<NumGun;i++) { - if (Play->Guns[GunIndex[i]].Carried > 0) { - Play->Guns[GunIndex[i]].Carried--; losedrug=1; - Play->CoatSize+=Gun[GunIndex[i]].Space; - if (Guns) Guns[GunIndex[i]].Carried++; - break; - } - } + } + } else if (strcmp(type, "gun") == 0) { + if (index >= 0 && index < NumGun + && TotalGunsCarried(From) + amount >= 0 + && TotalGunsCarried(From) + amount <= From->Bitches.Carried + 2 + && From->Guns[index].Price != 0 + && From->CoatSize - amount * Gun[index].Space >= 0 + && From->Cash >= amount * From->Guns[index].Price) { + From->Guns[index].Carried += amount; + From->CoatSize -= amount * Gun[index].Space; + From->Cash -= amount * From->Guns[index].Price; + SendPlayerData(From); + } + } else if (strcmp(type, "bitch") == 0) { + if (From->Bitches.Carried + amount >= 0 + && From->Bitches.Price != 0 + && amount * From->Bitches.Price <= From->Cash) { + for (i = 0; i < amount; i++) + GainBitch(From); + if (amount > 0) + From->Cash -= amount * From->Bitches.Price; + SendPlayerData(From); + } + } +} + +/* + * Clears the bitch and gun prices stored for player "Play". + */ +void ClearPrices(Player *Play) +{ + int i; + + Play->Bitches.Price = 0; + for (i = 0; i < NumGun; i++) + Play->Guns[i].Price = 0; +} + +/* + * Gives player "Play" a new bitch (or larger trenchcoat). + */ +void GainBitch(Player *Play) +{ + Play->CoatSize += 10; + Play->Bitches.Carried++; +} + +/* + * Loses one bitch belonging to player "Play". If drugs or guns are + * lost with the bitch, 1 is returned (0 otherwise) and the lost + * items are added to "Guns" and "Drugs" if non-NULL. + */ +int LoseBitch(Player *Play, Inventory *Guns, Inventory *Drugs) +{ + int losedrug = 0, i, num, drugslost; + int *GunIndex, tmp; + GunIndex = g_new(int, NumGun); + + ClearInventory(Guns, Drugs); + Play->CoatSize -= 10; + if (TotalGunsCarried(Play) > 0) { + if (brandom(0, 100) < + TotalGunsCarried(Play) * 100 / (Play->Bitches.Carried + 2)) { + for (i = 0; i < NumGun; i++) + GunIndex[i] = i; + for (i = 0; i < NumGun * 5; i++) { + num = brandom(0, NumGun - 1); + tmp = GunIndex[num + 1]; + GunIndex[num + 1] = GunIndex[num]; + GunIndex[num] = tmp; } - } - for (i=0;i<NumDrug;i++) if (Play->Drugs[i].Carried>0) { - num=(int)((float)Play->Drugs[i].Carried/(Play->Bitches.Carried+2.0)+0.5); - if (num>0) { - Play->Drugs[i].TotalValue = Play->Drugs[i].TotalValue* - (Play->Drugs[i].Carried-num)/Play->Drugs[i].Carried; - Play->Drugs[i].Carried-=num; - if (Drugs) Drugs[i].Carried+=num; - Play->CoatSize+=num; - losedrug=1; + for (i = 0; i < NumGun; i++) { + if (Play->Guns[GunIndex[i]].Carried > 0) { + Play->Guns[GunIndex[i]].Carried--; + losedrug = 1; + Play->CoatSize += Gun[GunIndex[i]].Space; + if (Guns) + Guns[GunIndex[i]].Carried++; + break; + } } - } - while (Play->CoatSize<0) { - drugslost=0; - for (i=0;i<NumDrug;i++) { - if (Play->Drugs[i].Carried>0) { - losedrug=1; drugslost=1; - Play->Drugs[i].TotalValue = Play->Drugs[i].TotalValue* - (Play->Drugs[i].Carried-1)/Play->Drugs[i].Carried; - Play->Drugs[i].Carried--; - Play->CoatSize++; - if (Play->CoatSize>=0) break; - } + } + } + for (i = 0; i < NumDrug; i++) + if (Play->Drugs[i].Carried > 0) { + num = + (int)((float)Play->Drugs[i].Carried / + (Play->Bitches.Carried + 2.0) + 0.5); + if (num > 0) { + Play->Drugs[i].TotalValue = Play->Drugs[i].TotalValue * + (Play->Drugs[i].Carried - num) / Play->Drugs[i].Carried; + Play->Drugs[i].Carried -= num; + if (Drugs) + Drugs[i].Carried += num; + Play->CoatSize += num; + losedrug = 1; } - if (!drugslost) for (i=0;i<NumGun;i++) { - if (Play->Guns[i].Carried>0) { - losedrug=1; - Play->Guns[i].Carried--; - Play->CoatSize+=Gun[i].Space; - if (Play->CoatSize>=0) break; - } + } + while (Play->CoatSize < 0) { + drugslost = 0; + for (i = 0; i < NumDrug; i++) { + if (Play->Drugs[i].Carried > 0) { + losedrug = 1; + drugslost = 1; + Play->Drugs[i].TotalValue = Play->Drugs[i].TotalValue * + (Play->Drugs[i].Carried - 1) / Play->Drugs[i].Carried; + Play->Drugs[i].Carried--; + Play->CoatSize++; + if (Play->CoatSize >= 0) + break; } - } - Play->Bitches.Carried--; - g_free(GunIndex); - return losedrug; -} - -void SetFightTimeout(Player *Play) { -/* If fight timeouts are in force, sets the timeout for the given player. */ - if (FightTimeout) Play->FightTimeout=time(NULL)+(time_t)FightTimeout; - else Play->FightTimeout=0; -} - -void ClearFightTimeout(Player *Play) { -/* Removes any fight timeout for the given player. */ - Play->FightTimeout=0; + } + if (!drugslost) + for (i = 0; i < NumGun; i++) { + if (Play->Guns[i].Carried > 0) { + losedrug = 1; + Play->Guns[i].Carried--; + Play->CoatSize += Gun[i].Space; + if (Play->CoatSize >= 0) + break; + } + } + } + Play->Bitches.Carried--; + g_free(GunIndex); + return losedrug; +} + +/* + * If fight timeouts are in force, sets the timeout for the given player. + */ +void SetFightTimeout(Player *Play) +{ + if (FightTimeout) + Play->FightTimeout = time(NULL) + (time_t) FightTimeout; + else + Play->FightTimeout = 0; +} + +/* + * Removes any fight timeout for the given player. + */ +void ClearFightTimeout(Player *Play) +{ + Play->FightTimeout = 0; +} + +/* + * Given the time of a pending event in "timeout" and the current time in + * "timenow", updates "mintime" with the number of seconds to that event, + * unless "mintime" is already smaller (as long as it's not -1, which + * means "uninitialized"). Returns 1 if the timeout has already expired. + */ +int AddTimeout(time_t timeout, time_t timenow, int *mintime) +{ + if (timeout == 0) + return 0; + else if (timeout <= timenow) + return 1; + else { + if (*mintime < 0 || timeout - timenow < *mintime) + *mintime = timeout - timenow; + return 0; + } } -int AddTimeout(time_t timeout,time_t timenow,int *mintime) { -/* Given the time of a pending event in "timeout" and the current time in */ -/* "timenow", updates "mintime" with the number of seconds to that event, */ -/* unless "mintime" is already smaller (as long as it's not -1, which */ -/* means "uninitialized"). Returns 1 if the timeout has already expired. */ - if (timeout==0) return 0; - else if (timeout<=timenow) return 1; - else { - if (*mintime<0 || timeout-timenow < *mintime) *mintime=timeout-timenow; +/* + * Returns the number of seconds until the next scheduled event. If such + * an event has already expired, returns 0. If no events are pending, + * returns -1. "First" should point to a list of valid players. + */ +int GetMinimumTimeout(GSList *First) +{ + Player *Play; + GSList *list; + int mintime = -1; + time_t timenow; + + timenow = time(NULL); + if (AddTimeout(MetaMinTimeout, timenow, &mintime)) + return 0; + if (AddTimeout(MetaUpdateTimeout, timenow, &mintime)) + return 0; + for (list = First; list; list = g_slist_next(list)) { + Play = (Player *)list->data; + if (AddTimeout(Play->FightTimeout, timenow, &mintime) || + AddTimeout(Play->IdleTimeout, timenow, &mintime) || + AddTimeout(Play->ConnectTimeout, timenow, &mintime)) return 0; - } -} - -int GetMinimumTimeout(GSList *First) { -/* Returns the number of seconds until the next scheduled event. If such */ -/* an event has already expired, returns 0. If no events are pending, */ -/* returns -1. "First" should point to a list of valid players. */ - Player *Play; - GSList *list; - int mintime=-1; - time_t timenow; - - timenow=time(NULL); - if (AddTimeout(MetaMinTimeout,timenow,&mintime)) return 0; - if (AddTimeout(MetaUpdateTimeout,timenow,&mintime)) return 0; - for (list=First;list;list=g_slist_next(list)) { - Play=(Player *)list->data; - if (AddTimeout(Play->FightTimeout,timenow,&mintime) || - AddTimeout(Play->IdleTimeout,timenow,&mintime) || - AddTimeout(Play->ConnectTimeout,timenow,&mintime)) return 0; - } - return mintime; -} - -GSList *HandleTimeouts(GSList *First) { -/* Given a list of players in "First", checks to see if any events */ -/* have timed out, and if so, performs the necessary actions. The */ -/* new start of the list is returned, since a player may be removed */ -/* if their ConnectTimeout has expired. */ - GSList *list,*nextlist; - Player *Play; - time_t timenow; - - timenow=time(NULL); - if (MetaMinTimeout<=timenow) { - MetaMinTimeout=0; - if (MetaPlayerPending) { - dopelog(3,_("Sending pending updates to the metaserver...")); - RegisterWithMetaServer(TRUE,TRUE,FALSE); - } - } - if (MetaUpdateTimeout!=0 && MetaUpdateTimeout<=timenow) { - dopelog(3,_("Sending reminder message to the metaserver...")); - RegisterWithMetaServer(TRUE,FALSE,FALSE); - } - list=First; - while (list) { - nextlist=g_slist_next(list); - Play=(Player *)list->data; - if (Play->IdleTimeout!=0 && Play->IdleTimeout<=timenow) { - Play->IdleTimeout=0; - dopelog(1,_("Player removed due to idle timeout")); - SendPrintMessage(NULL,C_NONE,Play,"Disconnected due to idle timeout"); - ClientLeftServer(Play); -/* Blank the name, so that CountPlayers ignores this player */ - SetPlayerName(Play,NULL); -/* Make sure they do actually disconnect, eventually! */ - if (ConnectTimeout) { - Play->ConnectTimeout=time(NULL)+(time_t)ConnectTimeout; - } - } else if (Play->ConnectTimeout!=0 && Play->ConnectTimeout<=timenow) { - Play->ConnectTimeout=0; - dopelog(1,_("Player removed due to connect timeout")); - First=RemovePlayer(Play,First); - } else if (IsConnectedPlayer(Play) && - Play->FightTimeout!=0 && Play->FightTimeout<=timenow) { - ClearFightTimeout(Play); - if (IsCop(Play)) Fire(Play); - else SendFightReload(Play); + } + return mintime; +} + +/* + * Given a list of players in "First", checks to see if any events + * have timed out, and if so, performs the necessary actions. The + * new start of the list is returned, since a player may be removed + * if their ConnectTimeout has expired. + */ +GSList *HandleTimeouts(GSList *First) +{ + GSList *list, *nextlist; + Player *Play; + time_t timenow; + + timenow = time(NULL); + if (MetaMinTimeout <= timenow) { + MetaMinTimeout = 0; + if (MetaPlayerPending) { + dopelog(3, _("Sending pending updates to the metaserver...")); + RegisterWithMetaServer(TRUE, TRUE, FALSE); + } + } + if (MetaUpdateTimeout != 0 && MetaUpdateTimeout <= timenow) { + dopelog(3, _("Sending reminder message to the metaserver...")); + RegisterWithMetaServer(TRUE, FALSE, FALSE); + } + list = First; + while (list) { + nextlist = g_slist_next(list); + Play = (Player *)list->data; + if (Play->IdleTimeout != 0 && Play->IdleTimeout <= timenow) { + Play->IdleTimeout = 0; + dopelog(1, _("Player removed due to idle timeout")); + SendPrintMessage(NULL, C_NONE, Play, + "Disconnected due to idle timeout"); + ClientLeftServer(Play); + /* Blank the name, so that CountPlayers ignores this player */ + SetPlayerName(Play, NULL); + /* Make sure they do actually disconnect, eventually! */ + if (ConnectTimeout) { + Play->ConnectTimeout = time(NULL) + (time_t) ConnectTimeout; } - list=nextlist; - } - return First; + } else if (Play->ConnectTimeout != 0 + && Play->ConnectTimeout <= timenow) { + Play->ConnectTimeout = 0; + dopelog(1, _("Player removed due to connect timeout")); + First = RemovePlayer(Play, First); + } else if (IsConnectedPlayer(Play) && + Play->FightTimeout != 0 && Play->FightTimeout <= timenow) { + ClearFightTimeout(Play); + if (IsCop(Play)) + Fire(Play); + else + SendFightReload(Play); + } + list = nextlist; + } + return First; } (DIR) diff --git a/src/serverside.h b/src/serverside.h t@@ -1,23 +1,24 @@ -/* serverside.h Server-side parts of dopewars */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * serverside.h Server-side parts of dopewars * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __SERVERSIDE_H__ #define __SERVERSIDE_H__ t@@ -38,17 +39,17 @@ void StopServer(void); Player *HandleNewConnection(void); void ServerLoop(void); void HandleServerPlayer(Player *Play); -void HandleServerMessage(gchar *buf,Player *ReallyFrom); -void FinishGame(Player *Play,char *Message); -void SendHighScores(Player *Play,gboolean EndGame,char *Message); +void HandleServerMessage(gchar *buf, Player *ReallyFrom); +void FinishGame(Player *Play, char *Message); +void SendHighScores(Player *Play, gboolean EndGame, char *Message); void SendEvent(Player *To); -void SendDrugsHere(Player *To,gboolean DisplayBusts); -void GenerateDrugsHere(Player *To,char *Deal); -void BuyObject(Player *From,char *data); +void SendDrugsHere(Player *To, gboolean DisplayBusts); +void GenerateDrugsHere(Player *To, char *Deal); +void BuyObject(Player *From, char *data); int RandomOffer(Player *To); -void HandleAnswer(Player *From,Player *To,char *answer); +void HandleAnswer(Player *From, Player *To, char *answer); void ClearPrices(Player *Play); -int LoseBitch(Player *Play,Inventory *Guns,Inventory *Drugs); +int LoseBitch(Player *Play, Inventory *Guns, Inventory *Drugs); void GainBitch(Player *Play); void SetFightTimeout(Player *Play); void ClearFightTimeout(Player *Play); t@@ -58,18 +59,19 @@ void ConvertHighScoreFile(void); void OpenHighScoreFile(void); gboolean CheckHighScoreFileConfig(void); void CloseHighScoreFile(void); -gboolean HighScoreRead(FILE *fp,struct HISCORE *MultiScore, - struct HISCORE *AntiqueScore,gboolean ReadHeader); +gboolean HighScoreRead(FILE *fp, struct HISCORE *MultiScore, + struct HISCORE *AntiqueScore, gboolean ReadHeader); void CopsAttackPlayer(Player *Play); -void AttackPlayer(Player *Play,Player *Attacked); -gboolean IsOpponent(Player *Play,Player *Other); +void AttackPlayer(Player *Play, Player *Attacked); +gboolean IsOpponent(Player *Play, Player *Other); void Fire(Player *Play); void WithdrawFromCombat(Player *Play); -void RunFromCombat(Player *Play,int ToLocation); +void RunFromCombat(Player *Play, int ToLocation); gboolean CanPlayerFire(Player *Play); gboolean CanRunHere(Player *Play); Player *GetNextShooter(Player *Play); void DropPrivileges(void); + #ifdef GUI_SERVER void GuiServerLoop(gboolean is_service); #endif (DIR) diff --git a/src/tstring.c b/src/tstring.c t@@ -1,23 +1,24 @@ -/* tstring.c "Translated string" wrappers for dopewars */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * tstring.c "Translated string" wrappers for dopewars * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #include <stdio.h> #include <string.h> t@@ -33,216 +34,284 @@ #include "tstring.h" typedef struct _FmtData { - union { - int IntVal; - price_t PriceVal; - char CharVal; - char *StrVal; - } data; - char Type; + union { + int IntVal; + price_t PriceVal; + char CharVal; + char *StrVal; + } data; + char Type; } FmtData; -gchar *GetDefaultTString(gchar *tstring) { - gchar *dstr,*pt; - dstr=g_strdup(tstring); - pt=strchr(dstr,'_'); - if (pt) *pt='\0'; - return dstr; -} +gchar *GetDefaultTString(gchar *tstring) +{ + gchar *dstr, *pt; -gchar *GetTranslatedString(gchar *str,gchar *code,gboolean Caps) { - gchar *dstr,*pt,*tstr,*Default,*tcode; - - dstr=g_strdup(str); - g_strdelimit(dstr,"_",'^'); - pt=dstr; - Default=GetNextWord(&pt,""); - tstr=NULL; - - while(1) { - tcode=GetNextWord(&pt,NULL); - tstr=GetNextWord(&pt,""); - if (!tcode) { tstr=NULL; break; } - if (strcmp(tcode,code)==0) { - break; - } else tstr=NULL; - } - - if (tstr) { - if (Caps) tstr=InitialCaps(tstr); else tstr=g_strdup(tstr); - } else { - if (Caps) tstr=InitialCaps(Default); else tstr=g_strdup(Default); - } - - g_free(dstr); - return tstr; + dstr = g_strdup(tstring); + pt = strchr(dstr, '_'); + if (pt) + *pt = '\0'; + return dstr; } -void GetNextFormat(guint *Index,gchar *str,int *StartPos, - int *EndPos,int *FmtPos,gchar *Type,int *ArgNum,int *Wid, - int *Prec,char *Code) { - int anum,wid,prec; - guint i; - gchar type; - *StartPos=-1; - *EndPos=*FmtPos=*ArgNum=*Wid=*Prec=0; - *Type=0; - Code[0]=0; - anum=wid=prec=0; - i=*Index; - while (str[i]) { - if (str[i]=='%') { - *StartPos=*EndPos=i++; - while (strchr("#0- +'",str[i])) i++; /* Skip flag characters */ - while (str[i]>='0' && str[i]<='9') wid=wid*10+str[i++]-'0'; - if (str[i]=='$') { - *EndPos=i; - i++; anum=wid; wid=0; - while (strchr("#0- +'",str[i])) i++; /* Skip flag characters */ - while (str[i]>='0' && str[i]<='9') wid=wid*10+str[i++]-'0'; - } - if (str[i]=='.') { - i++; - while (str[i]>='0' && str[i]<='9') prec=prec*10+str[i++]-'0'; - } - *FmtPos=i; - type=str[i]; - if ((type=='T' || type=='t') && i+2<strlen(str)) { - Code[0]=str[i+1]; - Code[1]=str[i+2]; - Code[2]=0; - i+=3; - } else if (type=='/') { - i++; - while (str[i]!='\0' && str[i]!='/') i++; - if (str[i]=='/') i++; - } else i++; - *ArgNum=anum; *Wid=wid; *Prec=prec; *Index=i; *Type=type; - return; - } else i++; - } - *Index=i; +gchar *GetTranslatedString(gchar *str, gchar *code, gboolean Caps) +{ + gchar *dstr, *pt, *tstr, *Default, *tcode; + + dstr = g_strdup(str); + g_strdelimit(dstr, "_", '^'); + pt = dstr; + Default = GetNextWord(&pt, ""); + tstr = NULL; + + while (1) { + tcode = GetNextWord(&pt, NULL); + tstr = GetNextWord(&pt, ""); + if (!tcode) { + tstr = NULL; + break; + } + if (strcmp(tcode, code) == 0) { + break; + } else + tstr = NULL; + } + + if (tstr) { + if (Caps) + tstr = InitialCaps(tstr); + else + tstr = g_strdup(tstr); + } else { + if (Caps) + tstr = InitialCaps(Default); + else + tstr = g_strdup(Default); + } + + g_free(dstr); + return tstr; } -gchar *HandleTFmt(gchar *format, va_list va) { - int StrInd,StartPos,EndPos,FmtPos,Wid,Prec; - guint i,ArgNum,DefaultArgNum; - char Code[3],Type; - gchar *retstr,*fstr; - GString *string,*tmpfmt; - GArray *arr; - FmtData *fdat; - - string=g_string_new(""); - tmpfmt=g_string_new(""); - - arr=g_array_new(FALSE,TRUE,sizeof(FmtData)); - i=DefaultArgNum=0; - while (i<strlen(format)) { - GetNextFormat(&i,format,&StartPos,&EndPos,&FmtPos,&Type,&ArgNum, - &Wid,&Prec,Code); - if (StartPos==-1) break; - if (ArgNum==0) ArgNum=++DefaultArgNum; - if (ArgNum>arr->len) { - g_array_set_size(arr,ArgNum); - } - g_array_index(arr,FmtData,ArgNum-1).Type=Type; - } - for (i=0;i<arr->len;i++) { - fdat=&g_array_index(arr,FmtData,i); - switch(fdat->Type) { - case '\0': - g_error("Incomplete format string!"); break; - case 'd': - fdat->data.IntVal=va_arg(va,int); break; - case 'P': - fdat->data.PriceVal=va_arg(va,price_t); break; - case 'c': - fdat->data.CharVal=(char)va_arg(va,int); break; - case 's': case 't': case 'T': - fdat->data.StrVal=va_arg(va,char *); break; - case '%': case '/': - break; /* No special action for %% or %/.../ */ - default: - g_error("Unknown format type %c!",fdat->Type); - } - } - i=DefaultArgNum=0; - while (i<strlen(format)) { - StrInd=i; - GetNextFormat(&i,format,&StartPos,&EndPos,&FmtPos,&Type,&ArgNum, - &Wid,&Prec,Code); - if (StartPos==-1) { - g_string_append(string,&format[StrInd]); break; +void GetNextFormat(guint *Index, gchar *str, int *StartPos, + int *EndPos, int *FmtPos, gchar *Type, int *ArgNum, + int *Wid, int *Prec, char *Code) +{ + int anum, wid, prec; + guint i; + gchar type; + + *StartPos = -1; + *EndPos = *FmtPos = *ArgNum = *Wid = *Prec = 0; + *Type = 0; + Code[0] = 0; + anum = wid = prec = 0; + i = *Index; + while (str[i]) { + if (str[i] == '%') { + *StartPos = *EndPos = i++; + while (strchr("#0- +'", str[i])) + i++; /* Skip flag characters */ + while (str[i] >= '0' && str[i] <= '9') + wid = wid * 10 + str[i++] - '0'; + if (str[i] == '$') { + *EndPos = i; + i++; + anum = wid; + wid = 0; + while (strchr("#0- +'", str[i])) + i++; /* Skip flag characters */ + while (str[i] >= '0' && str[i] <= '9') + wid = wid * 10 + str[i++] - '0'; } - while (StrInd<StartPos) g_string_append_c(string,format[StrInd++]); - if (ArgNum==0) ArgNum=++DefaultArgNum; - g_string_assign(tmpfmt,"%"); - EndPos++; - while (EndPos<FmtPos) g_string_append_c(tmpfmt,format[EndPos++]); - if (Type=='T' || Type=='t' || Type=='P') g_string_append_c(tmpfmt,'s'); - else g_string_append_c(tmpfmt,Type); - fdat=&g_array_index(arr,FmtData,ArgNum-1); - if (Type!=fdat->Type) g_error("Unmatched types!"); - switch(Type) { - case 'd': - g_string_sprintfa(string,tmpfmt->str,fdat->data.IntVal); break; - case 'c': - g_string_sprintfa(string,tmpfmt->str,fdat->data.CharVal); break; - case 'P': - fstr=FormatPrice(fdat->data.PriceVal); - g_string_sprintfa(string,tmpfmt->str,fstr); g_free(fstr); break; - case 't': case 'T': - fstr=GetTranslatedString(fdat->data.StrVal,Code,Type=='T'); - g_string_sprintfa(string,tmpfmt->str,fstr); g_free(fstr); break; - case 's': - g_string_sprintfa(string,tmpfmt->str,fdat->data.StrVal); break; - case '%': - g_string_append_c(string,'%'); break; + if (str[i] == '.') { + i++; + while (str[i] >= '0' && str[i] <= '9') + prec = prec * 10 + str[i++] - '0'; } - } - retstr=string->str; - g_array_free(arr,TRUE); - g_string_free(string,FALSE); - g_string_free(tmpfmt,TRUE); - return retstr; + *FmtPos = i; + type = str[i]; + if ((type == 'T' || type == 't') && i + 2 < strlen(str)) { + Code[0] = str[i + 1]; + Code[1] = str[i + 2]; + Code[2] = 0; + i += 3; + } else if (type == '/') { + i++; + while (str[i] != '\0' && str[i] != '/') + i++; + if (str[i] == '/') + i++; + } else + i++; + *ArgNum = anum; + *Wid = wid; + *Prec = prec; + *Index = i; + *Type = type; + return; + } else + i++; + } + *Index = i; } -void dpg_print(gchar *format, ...) { - va_list ap; - gchar *retstr; - va_start(ap,format); - retstr=HandleTFmt(format,ap); - va_end(ap); - g_print(retstr); - g_free(retstr); +gchar *HandleTFmt(gchar *format, va_list va) +{ + int StrInd, StartPos, EndPos, FmtPos, Wid, Prec; + guint i, ArgNum, DefaultArgNum; + char Code[3], Type; + gchar *retstr, *fstr; + GString *string, *tmpfmt; + GArray *arr; + FmtData *fdat; + + string = g_string_new(""); + tmpfmt = g_string_new(""); + + arr = g_array_new(FALSE, TRUE, sizeof(FmtData)); + i = DefaultArgNum = 0; + while (i < strlen(format)) { + GetNextFormat(&i, format, &StartPos, &EndPos, &FmtPos, &Type, &ArgNum, + &Wid, &Prec, Code); + if (StartPos == -1) + break; + if (ArgNum == 0) + ArgNum = ++DefaultArgNum; + if (ArgNum > arr->len) { + g_array_set_size(arr, ArgNum); + } + g_array_index(arr, FmtData, ArgNum - 1).Type = Type; + } + for (i = 0; i < arr->len; i++) { + fdat = &g_array_index(arr, FmtData, i); + + switch (fdat->Type) { + case '\0': + g_error("Incomplete format string!"); + break; + case 'd': + fdat->data.IntVal = va_arg(va, int); + break; + case 'P': + fdat->data.PriceVal = va_arg(va, price_t); + break; + case 'c': + fdat->data.CharVal = (char)va_arg(va, int); + break; + case 's': + case 't': + case 'T': + fdat->data.StrVal = va_arg(va, char *); + break; + case '%': + case '/': + break; /* No special action for %% or %/.../ */ + default: + g_error("Unknown format type %c!", fdat->Type); + } + } + i = DefaultArgNum = 0; + while (i < strlen(format)) { + StrInd = i; + GetNextFormat(&i, format, &StartPos, &EndPos, &FmtPos, &Type, &ArgNum, + &Wid, &Prec, Code); + if (StartPos == -1) { + g_string_append(string, &format[StrInd]); + break; + } + while (StrInd < StartPos) + g_string_append_c(string, format[StrInd++]); + if (ArgNum == 0) + ArgNum = ++DefaultArgNum; + g_string_assign(tmpfmt, "%"); + EndPos++; + while (EndPos < FmtPos) + g_string_append_c(tmpfmt, format[EndPos++]); + if (Type == 'T' || Type == 't' || Type == 'P') + g_string_append_c(tmpfmt, 's'); + else + g_string_append_c(tmpfmt, Type); + fdat = &g_array_index(arr, FmtData, ArgNum - 1); + + if (Type != fdat->Type) + g_error("Unmatched types!"); + switch (Type) { + case 'd': + g_string_sprintfa(string, tmpfmt->str, fdat->data.IntVal); + break; + case 'c': + g_string_sprintfa(string, tmpfmt->str, fdat->data.CharVal); + break; + case 'P': + fstr = FormatPrice(fdat->data.PriceVal); + g_string_sprintfa(string, tmpfmt->str, fstr); + g_free(fstr); + break; + case 't': + case 'T': + fstr = GetTranslatedString(fdat->data.StrVal, Code, Type == 'T'); + g_string_sprintfa(string, tmpfmt->str, fstr); + g_free(fstr); + break; + case 's': + g_string_sprintfa(string, tmpfmt->str, fdat->data.StrVal); + break; + case '%': + g_string_append_c(string, '%'); + break; + } + } + retstr = string->str; + g_array_free(arr, TRUE); + g_string_free(string, FALSE); + g_string_free(tmpfmt, TRUE); + return retstr; } -gchar *dpg_strdup_printf(gchar *format, ...) { - va_list ap; - gchar *retstr; - va_start(ap,format); - retstr=HandleTFmt(format,ap); - va_end(ap); - return retstr; +void dpg_print(gchar *format, ...) +{ + va_list ap; + gchar *retstr; + + va_start(ap, format); + retstr = HandleTFmt(format, ap); + va_end(ap); + g_print(retstr); + g_free(retstr); } -void dpg_string_sprintf(GString *string, gchar *format, ...) { - va_list ap; - gchar *newstr; - va_start(ap,format); - newstr=HandleTFmt(format,ap); - g_string_assign(string,newstr); - g_free(newstr); - va_end(ap); +gchar *dpg_strdup_printf(gchar *format, ...) +{ + va_list ap; + gchar *retstr; + + va_start(ap, format); + retstr = HandleTFmt(format, ap); + va_end(ap); + return retstr; } -void dpg_string_sprintfa(GString *string, gchar *format, ...) { - va_list ap; - gchar *newstr; - va_start(ap,format); - newstr=HandleTFmt(format,ap); - g_string_append(string,newstr); - g_free(newstr); - va_end(ap); +void dpg_string_sprintf(GString *string, gchar *format, ...) +{ + va_list ap; + gchar *newstr; + + va_start(ap, format); + newstr = HandleTFmt(format, ap); + g_string_assign(string, newstr); + g_free(newstr); + va_end(ap); +} + +void dpg_string_sprintfa(GString *string, gchar *format, ...) +{ + va_list ap; + gchar *newstr; + + va_start(ap, format); + newstr = HandleTFmt(format, ap); + g_string_append(string, newstr); + g_free(newstr); + va_end(ap); } (DIR) diff --git a/src/tstring.h b/src/tstring.h t@@ -1,22 +1,24 @@ -/* tstring.h "Translated string" wrappers for dopewars */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * tstring.h "Translated string" wrappers for dopewars * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __TSTRING_H__ #define __TSTRING_H__ (DIR) diff --git a/src/winmain.c b/src/winmain.c t@@ -1,22 +1,24 @@ -/* winmain.c Startup code and support for the Win32 platform */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * winmain.c Startup code and support for the Win32 platform * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifdef HAVE_CONFIG_H #include <config.h> t@@ -41,103 +43,122 @@ #include "gtkport.h" #include "winmain.h" -static void ServerLogMessage(const gchar *log_domain,GLogLevelFlags log_level, - const gchar *message,gpointer user_data) { - DWORD NumChar; - GString *text; - text=GetLogString(log_level,message); - if (text) { - g_string_append(text,"\n"); - g_print(text->str); -/* WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),text->str,strlen(text->str), - &NumChar,NULL);*/ - g_string_free(text,TRUE); - } +static void ServerLogMessage(const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, gpointer user_data) +{ + DWORD NumChar; + GString *text; + + text = GetLogString(log_level, message); + if (text) { + g_string_append(text, "\n"); + g_print(text->str); + g_string_free(text, TRUE); + } } -static void ServerPrintFunc(const gchar *string) { - DWORD NumChar; - WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),string,strlen(string), - &NumChar,NULL); +static void ServerPrintFunc(const gchar *string) +{ + DWORD NumChar; + + WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), string, strlen(string), + &NumChar, NULL); } -static void LogMessage(const gchar *log_domain,GLogLevelFlags log_level, - const gchar *message,gpointer user_data) { - MessageBox(NULL,message,"Error",MB_OK|MB_ICONSTOP); +static void LogMessage(const gchar *log_domain, GLogLevelFlags log_level, + const gchar *message, gpointer user_data) +{ + MessageBox(NULL, message, "Error", MB_OK | MB_ICONSTOP); } -static GString *TextOutput=NULL; +static GString *TextOutput = NULL; -static void WindowPrintStart() { - TextOutput=g_string_new(""); +static void WindowPrintStart() +{ + TextOutput = g_string_new(""); } -static void WindowPrintFunc(const gchar *string) { - g_string_append(TextOutput,string); +static void WindowPrintFunc(const gchar *string) +{ + g_string_append(TextOutput, string); } -static void WindowPrintEnd() { - MessageBox(NULL,TextOutput->str,"dopewars",MB_OK|MB_ICONINFORMATION); - g_string_free(TextOutput,TRUE); - TextOutput=NULL; +static void WindowPrintEnd() +{ + MessageBox(NULL, TextOutput->str, "dopewars", + MB_OK | MB_ICONINFORMATION); + g_string_free(TextOutput, TRUE); + TextOutput = NULL; } -static FILE *LogFile=NULL; +static FILE *LogFile = NULL; -static void LogFileStart() { - LogFile=fopen("dopewars-log.txt","w"); +static void LogFileStart() +{ + LogFile = fopen("dopewars-log.txt", "w"); } -static void LogFilePrintFunc(const gchar *string) { +static void LogFilePrintFunc(const gchar *string) +{ if (LogFile) { - fprintf(LogFile,string); + fprintf(LogFile, string); fflush(LogFile); } } -static void LogFileEnd(void) { - if (LogFile) fclose(LogFile); +static void LogFileEnd(void) +{ + if (LogFile) + fclose(LogFile); } -gchar *GetBinaryDir(void) { - gchar *filename=NULL,*lastslash; - gint filelen=80; +gchar *GetBinaryDir(void) +{ + gchar *filename = NULL, *lastslash; + gint filelen = 80; DWORD retval; - while(1) { - filename = g_realloc(filename,filelen); - filename[filelen-1]='\0'; - retval = GetModuleFileName(NULL,filename,filelen); + while (1) { + filename = g_realloc(filename, filelen); + filename[filelen - 1] = '\0'; + retval = GetModuleFileName(NULL, filename, filelen); - if (retval==0) { - g_free(filename); filename=NULL; break; - } else if (filename[filelen-1]) { - filelen*=2; - } else break; + if (retval == 0) { + g_free(filename); + filename = NULL; + break; + } else if (filename[filelen - 1]) { + filelen *= 2; + } else + break; } if (filename) { - lastslash=strrchr(filename,'\\'); - if (lastslash) *lastslash='\0'; + lastslash = strrchr(filename, '\\'); + if (lastslash) + *lastslash = '\0'; } return filename; } #ifdef ENABLE_NLS -static gchar *GetWindowsLocale(void) { +static gchar *GetWindowsLocale(void) +{ LCID userID; - WORD lang,sublang; - static gchar langenv[30]; /* Should only be 5 chars, so this'll be plenty */ + WORD lang, sublang; + static gchar langenv[30]; /* Should only be 5 chars, so + * this'll be plenty */ gchar *oldlang; - langenv[0]='\0'; - strcpy(langenv,"LANG="); + langenv[0] = '\0'; + strcpy(langenv, "LANG="); oldlang = getenv("LANG"); if (oldlang) { - g_print("Started with LANG = %s\n",oldlang); + g_print("Started with LANG = %s\n", oldlang); return NULL; } t@@ -145,45 +166,53 @@ static gchar *GetWindowsLocale(void) { lang = PRIMARYLANGID(LANGIDFROMLCID(userID)); sublang = SUBLANGID(LANGIDFROMLCID(userID)); - switch(lang) { - case LANG_ENGLISH: - strcat(langenv,"en"); - if (sublang==SUBLANG_ENGLISH_UK) strcat(langenv,"_gb"); - break; - case LANG_FRENCH: - strcat(langenv,"fr"); break; - case LANG_GERMAN: - strcat(langenv,"de"); break; - case LANG_POLISH: - strcat(langenv,"pl"); break; - case LANG_PORTUGUESE: - strcat(langenv,"pt"); - if (sublang==SUBLANG_PORTUGUESE_BRAZILIAN) strcat(langenv,"_br"); - break; + switch (lang) { + case LANG_ENGLISH: + strcat(langenv, "en"); + if (sublang == SUBLANG_ENGLISH_UK) + strcat(langenv, "_gb"); + break; + case LANG_FRENCH: + strcat(langenv, "fr"); + break; + case LANG_GERMAN: + strcat(langenv, "de"); + break; + case LANG_POLISH: + strcat(langenv, "pl"); + break; + case LANG_PORTUGUESE: + strcat(langenv, "pt"); + if (sublang == SUBLANG_PORTUGUESE_BRAZILIAN) + strcat(langenv, "_br"); + break; } if (strlen(langenv) > 5) { - g_print("Using Windows language %s\n",langenv); + g_print("Using Windows language %s\n", langenv); return langenv; - } else return NULL; + } else + return NULL; } -#endif /* ENABLE_NLS */ +#endif /* ENABLE_NLS */ -int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, - LPSTR lpszCmdParam,int nCmdShow) { +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpszCmdParam, int nCmdShow) +{ gchar **split; int argc; gboolean is_service; gchar *modpath; + #ifdef ENABLE_NLS gchar *winlocale; #endif -/* Are we running as an NT service? */ - is_service = (lpszCmdParam && strncmp(lpszCmdParam,"-N",2)==0); + /* Are we running as an NT service? */ + is_service = (lpszCmdParam && strncmp(lpszCmdParam, "-N", 2) == 0); if (is_service) { - modpath=GetBinaryDir(); + modpath = GetBinaryDir(); SetCurrentDirectory(modpath); g_free(modpath); } t@@ -191,34 +220,36 @@ int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LogFileStart(); g_set_print_handler(LogFilePrintFunc); - g_log_set_handler(NULL,LogMask()|G_LOG_LEVEL_MESSAGE,ServerLogMessage,NULL); + g_log_set_handler(NULL, LogMask() | G_LOG_LEVEL_MESSAGE, + ServerLogMessage, NULL); if (!is_service) { - g_log_set_handler(NULL,G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL, - LogMessage,NULL); + g_log_set_handler(NULL, G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL, + LogMessage, NULL); } - #ifdef ENABLE_NLS - winlocale=GetWindowsLocale(); - if (winlocale) putenv(winlocale); + winlocale = GetWindowsLocale(); + if (winlocale) + putenv(winlocale); - setlocale(LC_ALL,""); - bindtextdomain(PACKAGE,LOCALEDIR); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif -/* Informational comment placed at the start of the Windows log file - (this is used for messages printed during processing of the config - files - under Unix these are just printed to stdout) */ + /* Informational comment placed at the start of the Windows log file + * (this is used for messages printed during processing of the config + * files - under Unix these are just printed to stdout) */ g_print(_("# This is the dopewars startup log, containing any\n" "# informative messages resulting from configuration\n" "# file processing and the like.\n\n")); - split=g_strsplit(lpszCmdParam," ",0); - argc=0; - while (split[argc] && split[argc][0]) argc++; + split = g_strsplit(lpszCmdParam, " ", 0); + argc = 0; + while (split[argc] && split[argc][0]) + argc++; - GeneralStartup(argc,split); + GeneralStartup(argc, split); OpenLog(); if (WantVersion || WantHelp) { WindowPrintStart(); t@@ -228,8 +259,8 @@ int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, #ifdef NETWORKING } else if (is_service) { StartNetworking(); - Network=Server=TRUE; - win32_init(hInstance,hPrevInstance,"mainicon"); + Network = Server = TRUE; + win32_init(hInstance, hPrevInstance, "mainicon"); ServiceMain(); StopNetworking(); #endif t@@ -245,17 +276,17 @@ int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, if (Server) { #ifdef NETWORKING #ifdef GUI_SERVER - g_log_set_handler(NULL,G_LOG_LEVEL_CRITICAL,LogMessage,NULL); - win32_init(hInstance,hPrevInstance,"mainicon"); + g_log_set_handler(NULL, G_LOG_LEVEL_CRITICAL, LogMessage, NULL); + win32_init(hInstance, hPrevInstance, "mainicon"); GuiServerLoop(FALSE); #else AllocConsole(); SetConsoleTitle(_("dopewars server")); g_log_set_handler(NULL, - LogMask()|G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_WARNING, - ServerLogMessage,NULL); + LogMask() | G_LOG_LEVEL_MESSAGE | + G_LOG_LEVEL_WARNING, ServerLogMessage, NULL); g_set_print_handler(ServerPrintFunc); - newterm(NULL,NULL,NULL); + newterm(NULL, NULL, NULL); ServerLoop(); #endif /* GUI_SERVER */ #else t@@ -270,26 +301,26 @@ int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, } else if (AIPlayer) { AllocConsole(); -/* Title of the Windows window used for AI player output */ + /* Title of the Windows window used for AI player output */ SetConsoleTitle(_("dopewars AI")); g_log_set_handler(NULL, - LogMask()|G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_WARNING, - ServerLogMessage,NULL); + LogMask() | G_LOG_LEVEL_MESSAGE | + G_LOG_LEVEL_WARNING, ServerLogMessage, NULL); g_set_print_handler(ServerPrintFunc); - newterm(NULL,NULL,NULL); + newterm(NULL, NULL, NULL); AIPlayerLoop(); - } else if (WantedClient==CLIENT_CURSES) { + } else if (WantedClient == CLIENT_CURSES) { AllocConsole(); SetConsoleTitle(_("dopewars")); CursesLoop(); } else { #if GUI_CLIENT - GtkLoop(hInstance,hPrevInstance); + 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")); + "passing the --enable-gui-client option to configure, or\n" + "use the curses client (if available) instead!\n")); #endif } #ifdef NETWORKING (DIR) diff --git a/src/winmain.h b/src/winmain.h t@@ -1,23 +1,24 @@ -/* winmain.h Startup code and support for the Win32 platform */ -/* Copyright (C) 1998-2002 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ - +/************************************************************************ + * winmain.h Startup code and support for the Win32 platform * + * Copyright (C) 1998-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #ifndef __WINMAIN_H__ #define __WINMAIN_H__ (DIR) diff --git a/win32/guifunc.c b/win32/guifunc.c t@@ -1,90 +1,103 @@ -/* guifunc.c GUI-specific shared functions for installer */ -/* Copyright (C) 2001 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * guifunc.c GUI-specific shared functions for installer * + * Copyright (C) 2001-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #include <windows.h> #include "guifunc.h" -static LRESULT CALLBACK GtkSepProc(HWND hwnd,UINT msg,WPARAM wParam, - LPARAM lParam) { - PAINTSTRUCT ps; - HPEN oldpen,dkpen,ltpen; - RECT rect; - HDC hDC; - if (msg==WM_PAINT) { - if (GetUpdateRect(hwnd,NULL,TRUE)) { - BeginPaint(hwnd,&ps); - GetClientRect(hwnd,&rect); - hDC=ps.hdc; - ltpen=CreatePen(PS_SOLID,0,(COLORREF)GetSysColor(COLOR_3DHILIGHT)); - dkpen=CreatePen(PS_SOLID,0,(COLORREF)GetSysColor(COLOR_3DSHADOW)); +static LRESULT CALLBACK GtkSepProc(HWND hwnd, UINT msg, WPARAM wParam, + LPARAM lParam) +{ + PAINTSTRUCT ps; + HPEN oldpen, dkpen, ltpen; + RECT rect; + HDC hDC; - if (rect.right > rect.bottom) { - oldpen=SelectObject(hDC,dkpen); - MoveToEx(hDC,rect.left,rect.top,NULL); - LineTo(hDC,rect.right,rect.top); + if (msg == WM_PAINT) { + if (GetUpdateRect(hwnd, NULL, TRUE)) { + BeginPaint(hwnd, &ps); + GetClientRect(hwnd, &rect); + hDC = ps.hdc; + ltpen = CreatePen(PS_SOLID, 0, (COLORREF)GetSysColor(COLOR_3DHILIGHT)); + dkpen = CreatePen(PS_SOLID, 0, (COLORREF)GetSysColor(COLOR_3DSHADOW)); - SelectObject(hDC,ltpen); - MoveToEx(hDC,rect.left,rect.top+1,NULL); - LineTo(hDC,rect.right,rect.top+1); - } else { - oldpen=SelectObject(hDC,dkpen); - MoveToEx(hDC,rect.left,rect.top,NULL); - LineTo(hDC,rect.left,rect.bottom); + if (rect.right > rect.bottom) { + oldpen = SelectObject(hDC, dkpen); + MoveToEx(hDC, rect.left, rect.top, NULL); + LineTo(hDC, rect.right, rect.top); - SelectObject(hDC,ltpen); - MoveToEx(hDC,rect.left+1,rect.top,NULL); - LineTo(hDC,rect.left+1,rect.bottom); - } + SelectObject(hDC, ltpen); + MoveToEx(hDC, rect.left, rect.top + 1, NULL); + LineTo(hDC, rect.right, rect.top + 1); + } else { + oldpen = SelectObject(hDC, dkpen); + MoveToEx(hDC, rect.left, rect.top, NULL); + LineTo(hDC, rect.left, rect.bottom); - SelectObject(hDC,oldpen); - DeleteObject(ltpen); DeleteObject(dkpen); - EndPaint(hwnd,&ps); + SelectObject(hDC, ltpen); + MoveToEx(hDC, rect.left + 1, rect.top, NULL); + LineTo(hDC, rect.left + 1, rect.bottom); } - return TRUE; - } else return DefWindowProc(hwnd,msg,wParam,lParam); + + SelectObject(hDC, oldpen); + DeleteObject(ltpen); + DeleteObject(dkpen); + EndPaint(hwnd, &ps); + } + return TRUE; + } else + return DefWindowProc(hwnd, msg, wParam, lParam); } -void RegisterSepClass(HINSTANCE hInstance) { +void RegisterSepClass(HINSTANCE hInstance) +{ WNDCLASS wc; - wc.style = CS_HREDRAW|CS_VREDRAW; + + wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = GtkSepProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; - wc.hCursor = LoadCursor(NULL,IDC_ARROW); - wc.hbrBackground = (HBRUSH)(1+COLOR_BTNFACE); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE); wc.lpszMenuName = NULL; wc.lpszClassName = "WC_GTKSEP"; RegisterClass(&wc); } -static BOOL CALLBACK enumFunc(HWND hWnd,LPARAM lParam) { +static BOOL CALLBACK enumFunc(HWND hWnd, LPARAM lParam) +{ HFONT GuiFont; - GuiFont=(HFONT)lParam; - SendMessage(hWnd,WM_SETFONT,(WPARAM)GuiFont,MAKELPARAM(FALSE,0)); + + GuiFont = (HFONT)lParam; + SendMessage(hWnd, WM_SETFONT, (WPARAM)GuiFont, MAKELPARAM(FALSE, 0)); return TRUE; } -void SetGuiFont(HWND hWnd) { +void SetGuiFont(HWND hWnd) +{ HFONT GuiFont; - GuiFont=(HFONT)GetStockObject(DEFAULT_GUI_FONT); - if (GuiFont) EnumChildWindows(hWnd,enumFunc,(LPARAM)GuiFont); + + GuiFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); + if (GuiFont) + EnumChildWindows(hWnd, enumFunc, (LPARAM)GuiFont); } (DIR) diff --git a/win32/guifunc.h b/win32/guifunc.h t@@ -1,22 +1,24 @@ -/* guifunc.h GUI-specific shared functions for installer */ -/* Copyright (C) 2001 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * guifunc.h GUI-specific shared functions for installer * + * Copyright (C) 2001-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #include <windows.h> (DIR) diff --git a/win32/makeinstall.c b/win32/makeinstall.c t@@ -1,68 +1,81 @@ -/* makeinstall.c Program to create install data for setup.c */ -/* Copyright (C) 2001 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * makeinstall.c Program to create install data for setup.c * + * Copyright (C) 2001-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #include <windows.h> #include <stdio.h> #include "zlib/zlib.h" #include "util.h" -char *read_line(HANDLE hin) { +char *read_line(HANDLE hin) +{ char *buf; - int bufsize=32,strind=0; + int bufsize = 32, strind = 0; DWORD bytes_read; + buf = bmalloc(bufsize); while (1) { - if (!ReadFile(hin,&buf[strind],1,&bytes_read,NULL)) { - printf("Read error\n"); break; + if (!ReadFile(hin, &buf[strind], 1, &bytes_read, NULL)) { + printf("Read error\n"); + break; } - if (bytes_read==0) { buf[strind]='\0'; break; } - else if (buf[strind]=='\r') continue; - else if (buf[strind]=='\n') { buf[strind++]='\0'; break; } - else { + if (bytes_read == 0) { + buf[strind] = '\0'; + break; + } else if (buf[strind] == '\r') + continue; + else if (buf[strind] == '\n') { + buf[strind++] = '\0'; + break; + } else { strind++; - if (strind>=bufsize) { - bufsize*=2; - buf = brealloc(buf,bufsize); + if (strind >= bufsize) { + bufsize *= 2; + buf = brealloc(buf, bufsize); } } } - if (strind==0) { bfree(buf); return NULL; } - else return buf; + if (strind == 0) { + bfree(buf); + return NULL; + } else + return buf; } -InstData *ReadInstallData() { +InstData *ReadInstallData() +{ HANDLE fin; - char *line,*line2,*line3,*line4; - InstFiles *lastinst=NULL,*lastextra=NULL,*lastkeep=NULL; - InstLink *lastmenu=NULL,*lastdesktop=NULL; + char *line, *line2, *line3, *line4; + InstFiles *lastinst = NULL, *lastextra = NULL, *lastkeep = NULL; + InstLink *lastmenu = NULL, *lastdesktop = NULL; InstData *idata; int i; enum { - S_PRODUCT=0,S_INSTDIR,S_INSTALL,S_EXTRA,S_KEEP,S_STARTMENUDIR, - S_STARTMENU,S_DESKTOP,S_NTSERVICE, - S_NONE - } section=S_NONE; + S_PRODUCT = 0, S_INSTDIR, S_INSTALL, S_EXTRA, S_KEEP, S_STARTMENUDIR, + S_STARTMENU, S_DESKTOP, S_NTSERVICE, S_NONE + } section = S_NONE; char *titles[S_NONE] = { - "[product]","[instdir]", "[install]","[extrafiles]","[keepfiles]", - "[startmenudir]","[startmenu]","[desktop]","[NT Service]" + "[product]", "[instdir]", "[install]", "[extrafiles]", "[keepfiles]", + "[startmenudir]", "[startmenu]", "[desktop]", "[NT Service]" }; idata = bmalloc(sizeof(InstData)); t@@ -71,57 +84,73 @@ InstData *ReadInstallData() { idata->startmenu = idata->desktop = NULL; idata->service = NULL; - fin = CreateFile("filelist",GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); + fin = CreateFile("filelist", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); - if (fin!=INVALID_HANDLE_VALUE) { + if (fin != INVALID_HANDLE_VALUE) { while (1) { - line=read_line(fin); - if (!line) break; - if (line[0]=='\0') { bfree(line); continue; } + line = read_line(fin); + if (!line) + break; + if (line[0] == '\0') { + bfree(line); + continue; + } - for (i=S_PRODUCT;i<S_NONE;i++) { - if (strcmp(line,titles[i])==0) { - section=i; break; + for (i = S_PRODUCT; i < S_NONE; i++) { + if (strcmp(line, titles[i]) == 0) { + section = i; + break; } } - if (i<S_NONE) { bfree(line); continue; } - - switch(section) { - case S_NONE: - printf("Bad line %s\n",line); exit(1); - case S_PRODUCT: -printf("product ID = %s\n",line); - idata->product = line; break; - case S_INSTDIR: -printf("install dir = %s\n",line); - idata->installdir = line; break; - case S_STARTMENUDIR: -printf("start menu dir = %s\n",line); - idata->startmenudir = line; break; - case S_INSTALL: - AddInstFiles(line,0,&lastinst,&idata->instfiles); - break; - case S_EXTRA: - AddInstFiles(line,0,&lastextra,&idata->extrafiles); - break; - case S_KEEP: - AddInstFiles(line,0,&lastkeep,&idata->keepfiles); - break; - case S_STARTMENU: - line2=read_line(fin); line3=read_line(fin); -printf("start menu entry = %s/%s/%s\n",line,line2,line3); - AddInstLink(line,line2,line3,&lastmenu,&idata->startmenu); - break; - case S_NTSERVICE: - line2=read_line(fin); line3=read_line(fin); line4=read_line(fin); -printf("NT Service = %s/%s/%s/%s\n",line,line2,line3,line4); - AddServiceDetails(line,line2,line3,line4,&idata->service); - break; - case S_DESKTOP: - line2=read_line(fin); line3=read_line(fin); -printf("desktop entry = %s/%s/%s\n",line,line2,line3); - AddInstLink(line,line2,line3,&lastdesktop,&idata->desktop); - break; + if (i < S_NONE) { + bfree(line); + continue; + } + + switch (section) { + case S_NONE: + printf("Bad line %s\n", line); + exit(1); + case S_PRODUCT: + printf("product ID = %s\n", line); + idata->product = line; + break; + case S_INSTDIR: + printf("install dir = %s\n", line); + idata->installdir = line; + break; + case S_STARTMENUDIR: + printf("start menu dir = %s\n", line); + idata->startmenudir = line; + break; + case S_INSTALL: + AddInstFiles(line, 0, &lastinst, &idata->instfiles); + break; + case S_EXTRA: + AddInstFiles(line, 0, &lastextra, &idata->extrafiles); + break; + case S_KEEP: + AddInstFiles(line, 0, &lastkeep, &idata->keepfiles); + break; + case S_STARTMENU: + line2 = read_line(fin); + line3 = read_line(fin); + printf("start menu entry = %s/%s/%s\n", line, line2, line3); + AddInstLink(line, line2, line3, &lastmenu, &idata->startmenu); + break; + case S_NTSERVICE: + line2 = read_line(fin); + line3 = read_line(fin); + line4 = read_line(fin); + printf("NT Service = %s/%s/%s/%s\n", line, line2, line3, line4); + AddServiceDetails(line, line2, line3, line4, &idata->service); + break; + case S_DESKTOP: + line2 = read_line(fin); + line3 = read_line(fin); + printf("desktop entry = %s/%s/%s\n", line, line2, line3); + AddInstLink(line, line2, line3, &lastdesktop, &idata->desktop); + break; } } CloseHandle(fin); t@@ -138,38 +167,47 @@ printf("desktop entry = %s/%s/%s\n",line,line2,line3); #define BUFFER_SIZE (32*1024) #define COMPRESSION Z_BEST_COMPRESSION -void OpenNextFile(InstFiles *filelist,InstFiles **listpt,HANDLE *fin) { - char *filename,*sep; - if (*fin) CloseHandle(*fin); - *fin=NULL; +void OpenNextFile(InstFiles *filelist, InstFiles **listpt, HANDLE *fin) +{ + char *filename, *sep; + + if (*fin) + CloseHandle(*fin); + *fin = NULL; - if (!*listpt) *listpt = filelist; - else *listpt = (*listpt)->next; + if (!*listpt) + *listpt = filelist; + else + *listpt = (*listpt)->next; if (*listpt) { filename = (*listpt)->filename; - sep = strstr(filename," -> "); - if (sep) *sep='\0'; - *fin = CreateFile(filename,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); - if (sep) strcpy(filename,sep+4); - if (*fin==INVALID_HANDLE_VALUE) printf("Cannot open file: %s\n",filename); + sep = strstr(filename, " -> "); + if (sep) + *sep = '\0'; + *fin = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + if (sep) + strcpy(filename, sep + 4); + if (*fin == INVALID_HANDLE_VALUE) + printf("Cannot open file: %s\n", filename); } } -int main() { - HANDLE fout,fin; - DWORD bytes_read,bytes_written; +int main() +{ + HANDLE fout, fin; + DWORD bytes_read, bytes_written; InstData *idata; InstFiles *filept; - char *inbuf,*outbuf; - int status,count; + char *inbuf, *outbuf; + int status, count; bstr *str; z_stream z; - idata=ReadInstallData(); + idata = ReadInstallData(); - fout = CreateFile("installfiles.gz",GENERIC_WRITE,0,NULL, - CREATE_ALWAYS,0,NULL); + fout = CreateFile("installfiles.gz", GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, 0, NULL); outbuf = bmalloc(BUFFER_SIZE); inbuf = bmalloc(BUFFER_SIZE); t@@ -177,40 +215,44 @@ int main() { z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL; - deflateInit(&z,COMPRESSION); - z.avail_in=0; + deflateInit(&z, COMPRESSION); + z.avail_in = 0; z.next_out = outbuf; z.avail_out = BUFFER_SIZE; - filept=NULL; - fin=NULL; - OpenNextFile(idata->instfiles,&filept,&fin); - if (fin==INVALID_HANDLE_VALUE) { return 1; } + filept = NULL; + fin = NULL; + OpenNextFile(idata->instfiles, &filept, &fin); + if (fin == INVALID_HANDLE_VALUE) { + return 1; + } - while (fin!=INVALID_HANDLE_VALUE) { - if (z.avail_in==0) { + while (fin != INVALID_HANDLE_VALUE) { + if (z.avail_in == 0) { z.next_in = inbuf; - bytes_read=0; + bytes_read = 0; while (!bytes_read && fin) { - if (!ReadFile(fin,inbuf,BUFFER_SIZE,&bytes_read,NULL)) { - printf("Read error\n"); break; + if (!ReadFile(fin, inbuf, BUFFER_SIZE, &bytes_read, NULL)) { + printf("Read error\n"); + break; } - filept->filesize+=bytes_read; - if (!bytes_read) OpenNextFile(idata->instfiles,&filept,&fin); + filept->filesize += bytes_read; + if (!bytes_read) + OpenNextFile(idata->instfiles, &filept, &fin); } z.avail_in = bytes_read; } - if (z.avail_in==0) { - status = deflate(&z,Z_FINISH); + if (z.avail_in == 0) { + status = deflate(&z, Z_FINISH); count = BUFFER_SIZE - z.avail_out; - if (!WriteFile(fout,outbuf,count,&bytes_written,NULL)) { + if (!WriteFile(fout, outbuf, count, &bytes_written, NULL)) { printf("Write error\n"); } break; } - status = deflate(&z,Z_NO_FLUSH); + status = deflate(&z, Z_NO_FLUSH); count = BUFFER_SIZE - z.avail_out; - if (!WriteFile(fout,outbuf,count,&bytes_written,NULL)) { + if (!WriteFile(fout, outbuf, count, &bytes_written, NULL)) { printf("Write error\n"); } z.next_out = outbuf; t@@ -218,50 +260,52 @@ int main() { } printf("Written compressed data: raw %lu, compressed %lu\n", - z.total_in,z.total_out); + z.total_in, z.total_out); bytes_written = z.total_out; deflateEnd(&z); CloseHandle(fout); - fout = CreateFile("manifest",GENERIC_WRITE,0,NULL, - CREATE_ALWAYS,0,NULL); - if (fout==INVALID_HANDLE_VALUE) printf("Cannot create file list\n"); + fout = CreateFile("manifest", GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, 0, NULL); + if (fout == INVALID_HANDLE_VALUE) + printf("Cannot create file list\n"); - str=bstr_new(); - bstr_setlength(str,0); - bstr_append_long(str,bytes_written); - if (!WriteFile(fout,str->text,str->length+1,&bytes_written,NULL)) { + str = bstr_new(); + bstr_setlength(str, 0); + bstr_append_long(str, bytes_written); + if (!WriteFile(fout, str->text, str->length + 1, &bytes_written, NULL)) { printf("Write error\n"); } - if (!WriteFile(fout,idata->product,strlen(idata->product)+1, - &bytes_written,NULL)) { + if (!WriteFile(fout, idata->product, strlen(idata->product) + 1, + &bytes_written, NULL)) { printf("Write error\n"); } - if (!WriteFile(fout,idata->installdir,strlen(idata->installdir)+1, - &bytes_written,NULL)) { + if (!WriteFile(fout, idata->installdir, strlen(idata->installdir) + 1, + &bytes_written, NULL)) { printf("Write error\n"); } - if (!WriteFile(fout,idata->startmenudir,strlen(idata->startmenudir)+1, - &bytes_written,NULL)) { + if (!WriteFile + (fout, idata->startmenudir, strlen(idata->startmenudir) + 1, + &bytes_written, NULL)) { printf("Write error\n"); } - WriteFileList(fout,idata->instfiles); - WriteFileList(fout,idata->extrafiles); + WriteFileList(fout, idata->instfiles); + WriteFileList(fout, idata->extrafiles); - WriteLinkList(fout,idata->startmenu); - WriteLinkList(fout,idata->desktop); + WriteLinkList(fout, idata->startmenu); + WriteLinkList(fout, idata->desktop); - WriteServiceDetails(fout,idata->service); - WriteFileList(fout,idata->keepfiles); + WriteServiceDetails(fout, idata->service); + WriteFileList(fout, idata->keepfiles); CloseHandle(fout); bfree(inbuf); bfree(outbuf); - FreeInstData(idata,TRUE); + FreeInstData(idata, TRUE); return 0; } (DIR) diff --git a/win32/setup.c b/win32/setup.c t@@ -1,22 +1,24 @@ -/* setup.c Simple Win32 installer for dopewars */ -/* Copyright (C) 2001 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * setup.c Simple Win32 installer for dopewars * + * Copyright (C) 2001-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #include <windows.h> #include <commctrl.h> t@@ -31,75 +33,79 @@ #include "util.h" typedef enum { - DL_INTRO=0, DL_LICENCE,DL_SHORTCUTS,DL_INSTALLDIR,DL_DOINSTALL, - DL_NUM + DL_INTRO = 0, + DL_LICENCE, DL_SHORTCUTS, DL_INSTALLDIR, DL_DOINSTALL, DL_NUM } DialogType; InstData *idata; HWND mainDlg[DL_NUM]; DialogType CurrentDialog; -HINSTANCE hInst=NULL; -char *oldversion=NULL; +HINSTANCE hInst = NULL; +char *oldversion = NULL; BOOL services_supported, have_admin_rights, install_all_users; DWORD WINAPI DoInstall(LPVOID lpParam); -static void GetWinText(char **text,HWND hWnd); +static void GetWinText(char **text, HWND hWnd); static void FillFolderList(void); -/* Does this OS version support NT services? If so, do we have the +/* + * Does this OS version support NT services? If so, do we have the * necessary (administrator) rights to use them? */ -void ServiceCheck(BOOL *hasServices, BOOL *isAdmin) { +void ServiceCheck(BOOL *hasServices, BOOL *isAdmin) +{ SC_HANDLE scManager; - scManager = OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE); + scManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (scManager) { *hasServices = *isAdmin = TRUE; CloseServiceHandle(scManager); - } else if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED) { + } else if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { *hasServices = *isAdmin = FALSE; } else { *hasServices = TRUE; *isAdmin = FALSE; - } + } } -BOOL InstallService(InstData *idata) { - SC_HANDLE scManager,scService; +BOOL InstallService(InstData *idata) +{ + SC_HANDLE scManager, scService; HKEY key; bstr *str; static char keyprefix[] = "SYSTEM\\ControlSet001\\Services\\"; NTService *service; service = idata->service; - if (!service) return FALSE; + if (!service) + return FALSE; - scManager = OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE); + scManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (!scManager) { - DisplayError("Cannot connect to service manager",TRUE,FALSE); + DisplayError("Cannot connect to service manager", TRUE, FALSE); return FALSE; } str = bstr_new(); - bstr_assign(str,idata->installdir); - bstr_appendpath(str,service->exe); + bstr_assign(str, idata->installdir); + bstr_appendpath(str, service->exe); - scService = CreateService(scManager,service->name,service->display, - SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS, - SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL, - str->text,NULL,NULL,NULL,NULL,NULL); + scService = CreateService(scManager, service->name, service->display, + SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, + SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, + str->text, NULL, NULL, NULL, NULL, NULL); if (!scService) { - DisplayError("Cannot create service",TRUE,FALSE); - bstr_free(str,TRUE); + DisplayError("Cannot create service", TRUE, FALSE); + bstr_free(str, TRUE); return FALSE; } - bstr_assign(str,keyprefix); - bstr_append(str,service->name); - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,str->text,0,KEY_WRITE,&key) - ==ERROR_SUCCESS) { - RegSetValueEx(key,"Description",0,REG_SZ,service->description, + bstr_assign(str, keyprefix); + bstr_append(str, service->name); + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, str->text, + 0, KEY_WRITE, &key) == ERROR_SUCCESS) { + RegSetValueEx(key, "Description", 0, REG_SZ, service->description, strlen(service->description)); RegCloseKey(key); } t@@ -109,46 +115,54 @@ BOOL InstallService(InstData *idata) { return TRUE; } -BOOL CheckCreateDir(void) { -/* Checks that the install directory exists, and creates it if it does not. - Returns TRUE if the directory is OK. */ - +/* + * Checks that the install directory exists, and creates it if it does not. + * Returns TRUE if the directory is OK. + */ +BOOL CheckCreateDir(void) +{ char *instdir; - GetWinText(&idata->installdir,GetDlgItem(mainDlg[DL_INSTALLDIR],ED_INSTDIR)); - instdir=idata->installdir; + + GetWinText(&idata->installdir, + GetDlgItem(mainDlg[DL_INSTALLDIR], ED_INSTDIR)); + instdir = idata->installdir; if (SetCurrentDirectory(instdir)) { return TRUE; } else { if (MessageBox(mainDlg[CurrentDialog], "The install directory does not exist.\n" - "Create it?","Install Directory",MB_YESNO)==IDYES) { + "Create it?", "Install Directory", MB_YESNO) == IDYES) { if (CreateWholeDirectory(instdir)) { return TRUE; } else { - DisplayError("Could not create directory",TRUE,FALSE); + DisplayError("Could not create directory", TRUE, FALSE); } } return FALSE; } } -void ShowNewDialog(DialogType NewDialog) { - RECT DeskRect,OurRect; - int newX,newY; +void ShowNewDialog(DialogType NewDialog) +{ + RECT DeskRect, OurRect; + int newX, newY; HWND hWnd; HANDLE hThread; DWORD threadID; - if (NewDialog<0 || NewDialog>=DL_NUM) return; + + if (NewDialog < 0 || NewDialog >= DL_NUM) + return; if (NewDialog > CurrentDialog) { - switch(CurrentDialog) { + switch (CurrentDialog) { case DL_INSTALLDIR: - if (!CheckCreateDir()) return; + if (!CheckCreateDir()) + return; break; case DL_INTRO: install_all_users = (services_supported && IsDlgButtonChecked(mainDlg[DL_INTRO], - RB_ALLUSERS)==BST_CHECKED); + RB_ALLUSERS) == BST_CHECKED); FillFolderList(); break; default: t@@ -156,212 +170,253 @@ void ShowNewDialog(DialogType NewDialog) { } } - hWnd=mainDlg[NewDialog]; - if (GetWindowRect(hWnd,&OurRect) && - GetWindowRect(GetDesktopWindow(),&DeskRect)) { - newX = (DeskRect.left+DeskRect.right+OurRect.left-OurRect.right)/2; - newY = (DeskRect.top+DeskRect.bottom+OurRect.top-OurRect.bottom)/2; - SetWindowPos(hWnd,HWND_TOP,newX,newY,0,0,SWP_NOSIZE); + hWnd = mainDlg[NewDialog]; + if (GetWindowRect(hWnd, &OurRect) && + GetWindowRect(GetDesktopWindow(), &DeskRect)) { + newX = (DeskRect.left + DeskRect.right + OurRect.left - OurRect.right) / 2; + newY = (DeskRect.top + DeskRect.bottom + OurRect.top - OurRect.bottom) / 2; + SetWindowPos(hWnd, HWND_TOP, newX, newY, 0, 0, SWP_NOSIZE); } - ShowWindow(hWnd,SW_SHOW); + ShowWindow(hWnd, SW_SHOW); - if (CurrentDialog!=DL_NUM) ShowWindow(mainDlg[CurrentDialog],SW_HIDE); - CurrentDialog=NewDialog; + if (CurrentDialog != DL_NUM) + ShowWindow(mainDlg[CurrentDialog], SW_HIDE); + CurrentDialog = NewDialog; - if (NewDialog==DL_DOINSTALL) { - hThread = CreateThread(NULL,0,DoInstall,NULL,0,&threadID); + if (NewDialog == DL_DOINSTALL) { + hThread = CreateThread(NULL, 0, DoInstall, NULL, 0, &threadID); } } -int CALLBACK BrowseCallback(HWND hwnd,UINT msg,LPARAM lParam,LPARAM lpData) { - switch(msg) { - case BFFM_INITIALIZED: - SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)idata->installdir); - break; +int CALLBACK BrowseCallback(HWND hwnd, UINT msg, LPARAM lParam, + LPARAM lpData) +{ + switch (msg) { + case BFFM_INITIALIZED: + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)idata->installdir); + break; } return 0; } -void SelectInstDir(HWND parent) { +void SelectInstDir(HWND parent) +{ BROWSEINFO bi = { 0 }; TCHAR path[MAX_PATH]; LPITEMIDLIST pidl; - IMalloc *imalloc=0; + IMalloc *imalloc = 0; if (SUCCEEDED(SHGetMalloc(&imalloc))) { bi.lpszTitle = "Pick a directory"; bi.pszDisplayName = path; - bi.ulFlags = BIF_STATUSTEXT|BIF_RETURNONLYFSDIRS; + bi.ulFlags = BIF_STATUSTEXT | BIF_RETURNONLYFSDIRS; bi.lpfn = BrowseCallback; pidl = SHBrowseForFolder(&bi); if (pidl) { - if (SHGetPathFromIDList(pidl,path)) { + if (SHGetPathFromIDList(pidl, path)) { bfree(idata->installdir); idata->installdir = bstrdup(path); - SendDlgItemMessage(mainDlg[DL_INSTALLDIR],ED_INSTDIR,WM_SETTEXT, - 0,(LPARAM)idata->installdir); + SendDlgItemMessage(mainDlg[DL_INSTALLDIR], ED_INSTDIR, WM_SETTEXT, + 0, (LPARAM)idata->installdir); } - imalloc->lpVtbl->Free(imalloc,pidl); + imalloc->lpVtbl->Free(imalloc, pidl); } imalloc->lpVtbl->Release(imalloc); } } -void ConditionalExit(HWND hWnd) { - if (MessageBox(hWnd,"This will exit without installing any new software on " +void ConditionalExit(HWND hWnd) +{ + if (MessageBox(hWnd, + "This will exit without installing any new software on " "your machine.\nAre you sure you want to quit?\n\n(You can " "continue the installation at a\nlater date simply by " - "running this program again.)","Exit Install", - MB_YESNO|MB_ICONQUESTION)==IDYES) { + "running this program again.)", "Exit Install", + MB_YESNO | MB_ICONQUESTION) == IDYES) { PostQuitMessage(0); } } -void UpdateStartMenuFolder(void) { +void UpdateStartMenuFolder(void) +{ char *buf; HWND folderlist; LRESULT lres; int selind; - folderlist = GetDlgItem(mainDlg[DL_SHORTCUTS],LB_FOLDLIST); - if (!folderlist) return; + folderlist = GetDlgItem(mainDlg[DL_SHORTCUTS], LB_FOLDLIST); + if (!folderlist) + return; - lres=SendMessage(folderlist,LB_GETCURSEL,0,0); - if (lres==LB_ERR) return; + lres = SendMessage(folderlist, LB_GETCURSEL, 0, 0); + if (lres == LB_ERR) + return; - selind=(int)lres; - lres=SendMessage(folderlist,LB_GETTEXTLEN,(WPARAM)selind,0); - if (lres==LB_ERR) return; + selind = (int)lres; + lres = SendMessage(folderlist, LB_GETTEXTLEN, (WPARAM)selind, 0); + if (lres == LB_ERR) + return; - buf = bmalloc(lres+1); - lres=SendMessage(folderlist,LB_GETTEXT,(WPARAM)selind,(LPARAM)buf); - if (lres!=LB_ERR) { - SendDlgItemMessage(mainDlg[DL_SHORTCUTS],ED_FOLDER,WM_SETTEXT, - 0,(LPARAM)buf); + buf = bmalloc(lres + 1); + lres = SendMessage(folderlist, LB_GETTEXT, (WPARAM)selind, (LPARAM)buf); + if (lres != LB_ERR) { + SendDlgItemMessage(mainDlg[DL_SHORTCUTS], ED_FOLDER, WM_SETTEXT, + 0, (LPARAM)buf); } bfree(buf); } -BOOL CALLBACK MainDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { - switch(msg) { - case WM_INITDIALOG: - return TRUE; - case WM_COMMAND: - if (HIWORD(wParam)==BN_CLICKED && lParam) { - switch(LOWORD(wParam)) { - case BT_CANCEL: ConditionalExit(hWnd); break; - case BT_NEXT: ShowNewDialog(CurrentDialog+1); break; - case BT_BACK: ShowNewDialog(CurrentDialog-1); break; - case BT_FINISH: PostQuitMessage(0); break; - case BT_BROWSE: SelectInstDir(hWnd); break; - } - } else if (HIWORD(wParam)==LBN_SELCHANGE && lParam && - LOWORD(wParam)==LB_FOLDLIST) { - UpdateStartMenuFolder(); +BOOL CALLBACK MainDlgProc(HWND hWnd, UINT msg, WPARAM wParam, + LPARAM lParam) +{ + switch (msg) { + case WM_INITDIALOG: + return TRUE; + case WM_COMMAND: + if (HIWORD(wParam) == BN_CLICKED && lParam) { + switch (LOWORD(wParam)) { + case BT_CANCEL: + ConditionalExit(hWnd); + break; + case BT_NEXT: + ShowNewDialog(CurrentDialog + 1); + break; + case BT_BACK: + ShowNewDialog(CurrentDialog - 1); + break; + case BT_FINISH: + PostQuitMessage(0); + break; + case BT_BROWSE: + SelectInstDir(hWnd); + break; } - break; - case WM_CLOSE: - ConditionalExit(hWnd); - return TRUE; + } else if (HIWORD(wParam) == LBN_SELCHANGE && lParam && + LOWORD(wParam) == LB_FOLDLIST) { + UpdateStartMenuFolder(); + } + break; + case WM_CLOSE: + ConditionalExit(hWnd); + return TRUE; } return FALSE; } -LPVOID GetResource(LPCTSTR resname,LPCTSTR restype) { +LPVOID GetResource(LPCTSTR resname, LPCTSTR restype) +{ HRSRC hrsrc; HGLOBAL hglobal; LPVOID respt; - hrsrc = FindResource(NULL,resname,restype); - if (!hrsrc) DisplayError("Could not find resource",TRUE,TRUE); + hrsrc = FindResource(NULL, resname, restype); + if (!hrsrc) + DisplayError("Could not find resource", TRUE, TRUE); - hglobal = LoadResource(NULL,hrsrc); - if (!hglobal) DisplayError("Could not load resource",TRUE,TRUE); + hglobal = LoadResource(NULL, hrsrc); + if (!hglobal) + DisplayError("Could not load resource", TRUE, TRUE); respt = LockResource(hglobal); - if (!respt) DisplayError("Could not lock resource",TRUE,TRUE); + if (!respt) + DisplayError("Could not lock resource", TRUE, TRUE); return respt; } -InstData *ReadInstData() { - InstFiles *lastinst=NULL,*lastextra=NULL,*lastkeep=NULL; - InstLink *lastmenu=NULL,*lastdesktop=NULL; - char *instdata,*pt,*filename,*line2,*line3,*line4; +InstData *ReadInstData() +{ + InstFiles *lastinst = NULL, *lastextra = NULL, *lastkeep = NULL; + InstLink *lastmenu = NULL, *lastdesktop = NULL; + char *instdata, *pt, *filename, *line2, *line3, *line4; DWORD filesize; InstData *idata; - instdata = GetResource(MAKEINTRESOURCE(0),"INSTLIST"); - if (!instdata) return NULL; + instdata = GetResource(MAKEINTRESOURCE(0), "INSTLIST"); + if (!instdata) + return NULL; - pt=instdata; + pt = instdata; idata = bmalloc(sizeof(InstData)); idata->flags = 0; idata->service = NULL; idata->totalsize = atol(pt); - pt += strlen(pt)+1; + pt += strlen(pt) + 1; idata->product = bstrdup(pt); - pt += strlen(pt)+1; + pt += strlen(pt) + 1; idata->installdir = bstrdup(pt); - pt += strlen(pt)+1; + pt += strlen(pt) + 1; idata->startmenudir = bstrdup(pt); - pt += strlen(pt)+1; + pt += strlen(pt) + 1; while (1) { - filename=pt; - pt += strlen(pt)+1; + filename = pt; + pt += strlen(pt) + 1; if (filename[0]) { - filesize=atol(pt); - pt += strlen(pt)+1; - AddInstFiles(filename,filesize,&lastinst,&idata->instfiles); - } else break; + filesize = atol(pt); + pt += strlen(pt) + 1; + AddInstFiles(filename, filesize, &lastinst, &idata->instfiles); + } else + break; } while (1) { - filename=pt; - pt += strlen(pt)+1; + filename = pt; + pt += strlen(pt) + 1; if (filename[0]) { - filesize=atol(pt); - pt += strlen(pt)+1; - AddInstFiles(filename,filesize,&lastextra,&idata->extrafiles); - } else break; + filesize = atol(pt); + pt += strlen(pt) + 1; + AddInstFiles(filename, filesize, &lastextra, &idata->extrafiles); + } else + break; } while (1) { - filename=pt; - pt += strlen(pt)+1; + filename = pt; + pt += strlen(pt) + 1; if (filename[0]) { - line2=pt; pt += strlen(pt)+1; - line3=pt; pt += strlen(pt)+1; - AddInstLink(filename,line2,line3,&lastmenu,&idata->startmenu); - } else break; + line2 = pt; + pt += strlen(pt) + 1; + line3 = pt; + pt += strlen(pt) + 1; + AddInstLink(filename, line2, line3, &lastmenu, &idata->startmenu); + } else + break; } while (1) { - filename=pt; - pt += strlen(pt)+1; + filename = pt; + pt += strlen(pt) + 1; if (filename[0]) { - line2=pt; pt += strlen(pt)+1; - line3=pt; pt += strlen(pt)+1; - AddInstLink(filename,line2,line3,&lastdesktop,&idata->desktop); - } else break; + line2 = pt; + pt += strlen(pt) + 1; + line3 = pt; + pt += strlen(pt) + 1; + AddInstLink(filename, line2, line3, &lastdesktop, &idata->desktop); + } else + break; } - filename=pt; pt += strlen(pt)+1; + filename = pt; + pt += strlen(pt) + 1; if (filename[0]) { - line2=pt; pt += strlen(pt)+1; - line3=pt; pt += strlen(pt)+1; - line4=pt; pt += strlen(pt)+1; - AddServiceDetails(filename,line2,line3,line4,&idata->service); + line2 = pt; + pt += strlen(pt) + 1; + line3 = pt; + pt += strlen(pt) + 1; + line4 = pt; + pt += strlen(pt) + 1; + AddServiceDetails(filename, line2, line3, line4, &idata->service); } while (1) { - filename=pt; - pt += strlen(pt)+1; + filename = pt; + pt += strlen(pt) + 1; if (filename[0]) { - filesize=atol(pt); - pt += strlen(pt)+1; - AddInstFiles(filename,filesize,&lastkeep,&idata->keepfiles); - } else break; + filesize = atol(pt); + pt += strlen(pt) + 1; + AddInstFiles(filename, filesize, &lastkeep, &idata->keepfiles); + } else + break; } return idata; t@@ -369,19 +424,22 @@ InstData *ReadInstData() { #define BUFFER_SIZE (32*1024) -char *GetFirstFile(InstFiles *filelist,DWORD totalsize) { +char *GetFirstFile(InstFiles *filelist, DWORD totalsize) +{ DWORD bufsiz; - char *inbuf,*outbuf; + char *inbuf, *outbuf; int status; z_stream z; - if (!filelist) return NULL; + if (!filelist) + return NULL; - inbuf = GetResource(MAKEINTRESOURCE(1),"INSTFILE"); - if (!inbuf) return NULL; + inbuf = GetResource(MAKEINTRESOURCE(1), "INSTFILE"); + if (!inbuf) + return NULL; bufsiz = filelist->filesize; - outbuf = bmalloc(bufsiz+1); + outbuf = bmalloc(bufsiz + 1); z.zalloc = Z_NULL; z.zfree = Z_NULL; t@@ -394,390 +452,428 @@ char *GetFirstFile(InstFiles *filelist,DWORD totalsize) { z.avail_out = bufsiz; while (1) { - status = inflate(&z,Z_SYNC_FLUSH); - if ((status!=Z_OK && status!=Z_STREAM_END) || z.avail_out==0) break; + status = inflate(&z, Z_SYNC_FLUSH); + if ((status != Z_OK && status != Z_STREAM_END) || z.avail_out == 0) + break; } inflateEnd(&z); - outbuf[bufsiz]='\0'; + outbuf[bufsiz] = '\0'; return outbuf; } -BOOL OpenNextOutput(HANDLE *fout,InstFiles *filelist,InstFiles *keepfiles, - InstFiles **listpt,DWORD *fileleft,HANDLE logf, - BOOL *skipfile) { - char *filename,*sep; +BOOL OpenNextOutput(HANDLE *fout, InstFiles *filelist, + InstFiles *keepfiles, InstFiles **listpt, + DWORD *fileleft, HANDLE logf, BOOL *skipfile) +{ + char *filename, *sep; bstr *str; InstFiles *keeppt; DWORD bytes_written; - *skipfile=FALSE; + *skipfile = FALSE; - if (*fout) CloseHandle(*fout); + if (*fout) + CloseHandle(*fout); *fout = INVALID_HANDLE_VALUE; - str=bstr_new(); + str = bstr_new(); if (*listpt) { - if (!WriteFile(logf,(*listpt)->filename,strlen((*listpt)->filename)+1, - &bytes_written,NULL)) { + if (!WriteFile + (logf, (*listpt)->filename, strlen((*listpt)->filename) + 1, + &bytes_written, NULL)) { printf("Write error\n"); } - bstr_setlength(str,0); - bstr_append_long(str,(*listpt)->filesize); - if (!WriteFile(logf,str->text,str->length+1,&bytes_written,NULL)) { + bstr_setlength(str, 0); + bstr_append_long(str, (*listpt)->filesize); + if (!WriteFile(logf, str->text, str->length + 1, &bytes_written, NULL)) { printf("Write error\n"); } - *listpt=(*listpt)->next; - } else *listpt = filelist; + *listpt = (*listpt)->next; + } else + *listpt = filelist; if (*listpt) { filename = (*listpt)->filename; - sep = strrchr(filename,'\\'); + sep = strrchr(filename, '\\'); if (sep) { *sep = '\0'; CreateWholeDirectory(filename); *sep = '\\'; } keeppt = keepfiles; - while (keeppt && strcmp(keeppt->filename,filename)!=0) keeppt=keeppt->next; + while (keeppt && strcmp(keeppt->filename, filename) != 0) + keeppt = keeppt->next; -/* If the file is already installed (filesize!=0), then skip it */ - if (keeppt && keeppt->filesize!=0) { - *fout = INVALID_HANDLE_VALUE+1; /* Make sure the handle is valid */ + /* If the file is already installed (filesize!=0), then skip it */ + if (keeppt && keeppt->filesize != 0) { + *fout = INVALID_HANDLE_VALUE + 1; /* Make sure the handle is valid */ *skipfile = TRUE; } else { - *fout = CreateFile(filename,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL); - bstr_assign(str,"Installing file: "); - bstr_append(str,filename); - bstr_append(str," (size "); - bstr_append_long(str,(*listpt)->filesize); - bstr_append(str,")"); - SendDlgItemMessage(mainDlg[DL_DOINSTALL],ST_FILELIST, - WM_SETTEXT,0,(LPARAM)str->text); - if (*fout==INVALID_HANDLE_VALUE) { - bstr_assign(str,"Cannot create file "); - bstr_append(str,filename); - DisplayError(str->text,TRUE,FALSE); + *fout = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + 0, NULL); + bstr_assign(str, "Installing file: "); + bstr_append(str, filename); + bstr_append(str, " (size "); + bstr_append_long(str, (*listpt)->filesize); + bstr_append(str, ")"); + SendDlgItemMessage(mainDlg[DL_DOINSTALL], ST_FILELIST, + WM_SETTEXT, 0, (LPARAM)str->text); + if (*fout == INVALID_HANDLE_VALUE) { + bstr_assign(str, "Cannot create file "); + bstr_append(str, filename); + DisplayError(str->text, TRUE, FALSE); } } *fileleft = (*listpt)->filesize; } - bstr_free(str,TRUE); + bstr_free(str, TRUE); - return (*fout!=INVALID_HANDLE_VALUE); + return (*fout != INVALID_HANDLE_VALUE); } -HRESULT CreateLink(LPCSTR origPath,LPSTR linkArgs,LPSTR workDir, - LPSTR linkPath,LPSTR linkDesc) { +HRESULT CreateLink(LPCSTR origPath, LPSTR linkArgs, LPSTR workDir, + LPSTR linkPath, LPSTR linkDesc) +{ HRESULT hres; IShellLink *psl; IPersistFile *ppf; WORD wsz[MAX_PATH]; - hres = CoCreateInstance(&CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER, - &IID_IShellLink,(void **)&psl); + hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + &IID_IShellLink, (void **)&psl); if (SUCCEEDED(hres)) { - psl->lpVtbl->SetPath(psl,origPath); - if (workDir) psl->lpVtbl->SetWorkingDirectory(psl,workDir); - if (linkDesc) psl->lpVtbl->SetDescription(psl,linkDesc); - if (linkArgs) psl->lpVtbl->SetArguments(psl,linkArgs); - hres = psl->lpVtbl->QueryInterface(psl,&IID_IPersistFile,(void **)&ppf); + psl->lpVtbl->SetPath(psl, origPath); + if (workDir) + psl->lpVtbl->SetWorkingDirectory(psl, workDir); + if (linkDesc) + psl->lpVtbl->SetDescription(psl, linkDesc); + if (linkArgs) + psl->lpVtbl->SetArguments(psl, linkArgs); + hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, (void **)&ppf); if (SUCCEEDED(hres)) { - MultiByteToWideChar(CP_ACP,0,linkPath,-1,wsz,MAX_PATH); - hres = ppf->lpVtbl->Save(ppf,wsz,TRUE); + MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wsz, MAX_PATH); + hres = ppf->lpVtbl->Save(ppf, wsz, TRUE); ppf->lpVtbl->Release(ppf); } else { - DisplayError("Cannot write shortcut",FALSE,FALSE); + DisplayError("Cannot write shortcut", FALSE, FALSE); } psl->lpVtbl->Release(psl); } else { - DisplayError("Cannot create shortcut",FALSE,FALSE); + DisplayError("Cannot create shortcut", FALSE, FALSE); } return hres; } -void GetWinText(char **text,HWND hWnd) { +void GetWinText(char **text, HWND hWnd) +{ int textlen; - bfree(*text); - *text=NULL; - if (!hWnd) return; - textlen=GetWindowTextLength(hWnd)+1; - if (!textlen) return; - - *text=bmalloc(textlen); - if (!GetWindowText(hWnd,*text,textlen)) { - bfree(*text); *text=NULL; + bfree(*text); + *text = NULL; + if (!hWnd) + return; + + textlen = GetWindowTextLength(hWnd) + 1; + if (!textlen) + return; + + *text = bmalloc(textlen); + if (!GetWindowText(hWnd, *text, textlen)) { + bfree(*text); + *text = NULL; } } -void CreateLinks(char *linkdir,InstLink *linkpt) { - bstr *linkpath,*origfile; +void CreateLinks(char *linkdir, InstLink *linkpt) +{ + bstr *linkpath, *origfile; - linkpath=bstr_new(); - origfile=bstr_new(); + linkpath = bstr_new(); + origfile = bstr_new(); - for (;linkpt;linkpt=linkpt->next) { - bstr_assign(linkpath,linkdir); - bstr_appendpath(linkpath,linkpt->linkfile); + for (; linkpt; linkpt = linkpt->next) { + bstr_assign(linkpath, linkdir); + bstr_appendpath(linkpath, linkpt->linkfile); - bstr_assign(origfile,idata->installdir); - bstr_appendpath(origfile,linkpt->origfile); + bstr_assign(origfile, idata->installdir); + bstr_appendpath(origfile, linkpt->origfile); - CreateLink(origfile->text,linkpt->args,idata->installdir, - linkpath->text,NULL); + CreateLink(origfile->text, linkpt->args, idata->installdir, + linkpath->text, NULL); } } -void SetupShortcuts(HANDLE fout) { - char *startmenu,*desktop; +void SetupShortcuts(HANDLE fout) +{ + char *startmenu, *desktop; BOOL dodesktop; startmenu = GetStartMenuDir(install_all_users, idata); desktop = GetDesktopDir(); - dodesktop=(IsDlgButtonChecked(mainDlg[DL_SHORTCUTS],CB_DESKTOP)==BST_CHECKED); + dodesktop = + (IsDlgButtonChecked(mainDlg[DL_SHORTCUTS], CB_DESKTOP) == + BST_CHECKED); if (startmenu) { - if (CreateDirectory(startmenu,NULL)) { - CreateLinks(startmenu,idata->startmenu); - WriteLinkList(fout,idata->startmenu); + if (CreateDirectory(startmenu, NULL)) { + CreateLinks(startmenu, idata->startmenu); + WriteLinkList(fout, idata->startmenu); } else { - DisplayError("Could not create Start Menu directory",TRUE,FALSE); - WriteLinkList(fout,NULL); + DisplayError("Could not create Start Menu directory", TRUE, FALSE); + WriteLinkList(fout, NULL); } } else { - WriteLinkList(fout,NULL); + WriteLinkList(fout, NULL); } if (dodesktop && desktop) { - CreateLinks(desktop,idata->desktop); - WriteLinkList(fout,idata->desktop); + CreateLinks(desktop, idata->desktop); + WriteLinkList(fout, idata->desktop); } else { - WriteLinkList(fout,NULL); + WriteLinkList(fout, NULL); } - bfree(startmenu); bfree(desktop); + bfree(startmenu); + bfree(desktop); } -void SetupUninstall() { +void SetupUninstall() +{ HKEY key; DWORD disp; - bstr *str,*uninstexe,*link; - BOOL haveuninstall=FALSE; + bstr *str, *uninstexe, *link; + BOOL haveuninstall = FALSE; char *startmenu; InstFiles *listpt; - for (listpt=idata->instfiles;listpt;listpt=listpt->next) { - if (strcmp(listpt->filename,"uninstall.exe")==0) { - haveuninstall=TRUE; + for (listpt = idata->instfiles; listpt; listpt = listpt->next) { + if (strcmp(listpt->filename, "uninstall.exe") == 0) { + haveuninstall = TRUE; break; } } - if (!haveuninstall) return; + if (!haveuninstall) + return; + + str = bstr_new(); + uninstexe = bstr_new(); + link = bstr_new(); - str=bstr_new(); - uninstexe=bstr_new(); - link=bstr_new(); + bstr_assign(str, UninstallKey); + bstr_appendpath(str, idata->product); - bstr_assign(str,UninstallKey); - bstr_appendpath(str,idata->product); - - if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,str->text,0,NULL,0, - KEY_WRITE,NULL,&key,&disp)==ERROR_SUCCESS) { - RegSetValueEx(key,"DisplayName",0,REG_SZ,idata->product, + if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, str->text, 0, NULL, 0, + KEY_WRITE, NULL, &key, &disp) == ERROR_SUCCESS) { + RegSetValueEx(key, "DisplayName", 0, REG_SZ, idata->product, strlen(idata->product)); bstr_assign_windir(str); - bstr_appendpath(str,UninstallEXE); - bstr_append_c(str,' '); - bstr_append(str,idata->product); - RegSetValueEx(key,"UninstallString",0,REG_SZ,str->text,str->length); - bstr_assign(str,idata->installdir); - RegSetValueEx(key,"InstallDirectory",0,REG_SZ,str->text,str->length); + bstr_appendpath(str, UninstallEXE); + bstr_append_c(str, ' '); + bstr_append(str, idata->product); + RegSetValueEx(key, "UninstallString", 0, REG_SZ, str->text, + str->length); + bstr_assign(str, idata->installdir); + RegSetValueEx(key, "InstallDirectory", 0, REG_SZ, str->text, + str->length); RegCloseKey(key); } else { - DisplayError("Cannot create registry key for uninstall",TRUE,FALSE); + DisplayError("Cannot create registry key for uninstall", TRUE, FALSE); } bstr_assign_windir(str); - bstr_appendpath(str,"bw-uninstall.exe"); + bstr_appendpath(str, "bw-uninstall.exe"); DeleteFile(str->text); - bstr_assign(uninstexe,idata->installdir); - bstr_appendpath(uninstexe,"uninstall.exe"); + bstr_assign(uninstexe, idata->installdir); + bstr_appendpath(uninstexe, "uninstall.exe"); - if (!MoveFile(uninstexe->text,str->text)) { - DisplayError("Unable to create uninstall program",TRUE,FALSE); + if (!MoveFile(uninstexe->text, str->text)) { + DisplayError("Unable to create uninstall program", TRUE, FALSE); } DeleteFile(uninstexe->text); startmenu = GetStartMenuDir(install_all_users, idata); - bstr_assign(link,startmenu); - bstr_appendpath(link,"Uninstall "); - bstr_append(link,idata->product); - bstr_append(link,".LNK"); + bstr_assign(link, startmenu); + bstr_appendpath(link, "Uninstall "); + bstr_append(link, idata->product); + bstr_append(link, ".LNK"); - CreateLink(str->text,idata->product,NULL,link->text,NULL); + CreateLink(str->text, idata->product, NULL, link->text, NULL); - bstr_free(link,TRUE); - bstr_free(uninstexe,TRUE); - bstr_free(str,TRUE); + bstr_free(link, TRUE); + bstr_free(uninstexe, TRUE); + bstr_free(str, TRUE); bfree(startmenu); } -void StartRemoveOldVersion(char *oldversion,InstData *idata, - InstData **oldidata,HWND hwnd) { +void StartRemoveOldVersion(char *oldversion, InstData *idata, + InstData **oldidata, HWND hwnd) +{ InstData *old; bstr *str; - char *oldidir,*startmenu,*desktop; + char *oldidir, *startmenu, *desktop; HANDLE fin; - *oldidata=NULL; + *oldidata = NULL; - if (!oldversion) return; + if (!oldversion) + return; oldidir = GetInstallDir(oldversion); if (!SetCurrentDirectory(oldidir)) { - str=bstr_new(); - bstr_assign(str,"Could not access old version's install directory "); - bstr_append(str,oldidir); - DisplayError(str->text,TRUE,TRUE); + str = bstr_new(); + bstr_assign(str, "Could not access old version's install directory "); + bstr_append(str, oldidir); + DisplayError(str->text, TRUE, TRUE); } - fin = CreateFile("install.log",GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); + fin = CreateFile("install.log", GENERIC_READ, 0, NULL, OPEN_EXISTING, + 0, NULL); if (fin) { - old = ReadOldInstData(fin,oldversion,oldidir); + old = ReadOldInstData(fin, oldversion, oldidir); CloseHandle(fin); DeleteFile("install.log"); RemoveService(old->service); - DeleteFileList(old->instfiles,hwnd,idata->keepfiles); - DeleteFileList(old->extrafiles,hwnd,idata->keepfiles); + DeleteFileList(old->instfiles, hwnd, idata->keepfiles); + DeleteFileList(old->extrafiles, hwnd, idata->keepfiles); startmenu = GetStartMenuDir(old->flags & IF_ALLUSERS, old); desktop = GetDesktopDir(); - DeleteLinkList(startmenu,old->startmenu,hwnd); - DeleteLinkList(desktop,old->desktop,hwnd); + DeleteLinkList(startmenu, old->startmenu, hwnd); + DeleteLinkList(desktop, old->desktop, hwnd); - RemoveUninstall(startmenu,oldversion,FALSE); + RemoveUninstall(startmenu, oldversion, FALSE); - bfree(startmenu); bfree(desktop); + bfree(startmenu); + bfree(desktop); *oldidata = old; } } -void FinishRemoveOldVersion(char *oldversion,InstData *idata, - InstData *oldidata) { +void FinishRemoveOldVersion(char *oldversion, InstData *idata, + InstData *oldidata) +{ InstFiles *keeppt; bstr *str; - char *desktop,*startmenu; - if (!oldidata) return; + char *desktop, *startmenu; + + if (!oldidata) + return; desktop = GetDesktopDir(); str = bstr_new(); -/* If we're installing into a different directory, move config. files etc. - from the old directory to the new one */ - if (strcmp(oldidata->installdir,idata->installdir)!=0 && + /* If we're installing into a different directory, move config. files + * etc. from the old directory to the new one */ + if (strcmp(oldidata->installdir, idata->installdir) != 0 && SetCurrentDirectory(oldidata->installdir)) { - for (keeppt = idata->keepfiles;keeppt;keeppt=keeppt->next) { - if (keeppt->filesize!=0) { - bstr_assign(str,idata->installdir); - bstr_appendpath(str,keeppt->filename); - if (CopyFile(keeppt->filename,str->text,FALSE)) { + for (keeppt = idata->keepfiles; keeppt; keeppt = keeppt->next) { + if (keeppt->filesize != 0) { + bstr_assign(str, idata->installdir); + bstr_appendpath(str, keeppt->filename); + if (CopyFile(keeppt->filename, str->text, FALSE)) { DeleteFile(keeppt->filename); } } } - SetCurrentDirectory(desktop); /* Make sure we're not in the install dir */ + SetCurrentDirectory(desktop); /* Make sure we're not in the + * install dir */ if (!RemoveWholeDirectory(oldidata->installdir)) { - bstr_assign(str,"Could not remove old install directory:\n"); - bstr_append(str,oldidata->installdir); - bstr_append(str,"\nYou may wish to manually remove it later."); - DisplayError(str->text,FALSE,FALSE); + bstr_assign(str, "Could not remove old install directory:\n"); + bstr_append(str, oldidata->installdir); + bstr_append(str, "\nYou may wish to manually remove it later."); + DisplayError(str->text, FALSE, FALSE); } } - if (strcmp(idata->startmenudir,oldidata->startmenudir)!=0) { - SetCurrentDirectory(desktop); /* Make sure we're not in the menu dir */ + if (strcmp(idata->startmenudir, oldidata->startmenudir) != 0) { + SetCurrentDirectory(desktop); /* Make sure we're not in the menu + * dir */ startmenu = GetStartMenuDir(oldidata->flags & IF_ALLUSERS, oldidata); if (!RemoveWholeDirectory(startmenu)) { - bstr_assign(str,"Could not remove old Start Menu directory:\n"); - bstr_append(str,startmenu); - bstr_append(str,"\nYou may wish to manually remove it later."); - DisplayError(str->text,FALSE,FALSE); + bstr_assign(str, "Could not remove old Start Menu directory:\n"); + bstr_append(str, startmenu); + bstr_append(str, "\nYou may wish to manually remove it later."); + DisplayError(str->text, FALSE, FALSE); } bfree(startmenu); } -/* Remove the old registry key */ - bstr_assign(str,UninstallKey); - bstr_appendpath(str,oldversion); - RegDeleteKey(HKEY_LOCAL_MACHINE,str->text); + /* Remove the old registry key */ + bstr_assign(str, UninstallKey); + bstr_appendpath(str, oldversion); + RegDeleteKey(HKEY_LOCAL_MACHINE, str->text); bfree(desktop); - bstr_free(str,TRUE); - - FreeInstData(oldidata,TRUE); - oldversion=NULL; /* This is freed by FreeInstData */ + bstr_free(str, TRUE); + + FreeInstData(oldidata, TRUE); + oldversion = NULL; /* This is freed by FreeInstData */ } -DWORD WINAPI DoInstall(LPVOID lpParam) { - HANDLE fout,logf,fin; - DWORD bytes_written,fileleft; +DWORD WINAPI DoInstall(LPVOID lpParam) +{ + HANDLE fout, logf, fin; + DWORD bytes_written, fileleft; BOOL skipfile, service_installed; - char *inbuf,*outbuf; - int status,count; + char *inbuf, *outbuf; + int status, count; z_stream z; InstFiles *listpt; InstData *oldidata; -/* Steal the filesize attribute to mark that these files are not - already installed */ - for (listpt=idata->keepfiles;listpt;listpt=listpt->next) { - listpt->filesize=0; + /* Steal the filesize attribute to mark that these files are not already + * installed */ + for (listpt = idata->keepfiles; listpt; listpt = listpt->next) { + listpt->filesize = 0; } - StartRemoveOldVersion(oldversion,idata,&oldidata, - GetDlgItem(mainDlg[DL_DOINSTALL],ST_FILELIST)); + StartRemoveOldVersion(oldversion, idata, &oldidata, + GetDlgItem(mainDlg[DL_DOINSTALL], ST_FILELIST)); - inbuf = GetResource(MAKEINTRESOURCE(1),"INSTFILE"); - if (!inbuf) return 0; + inbuf = GetResource(MAKEINTRESOURCE(1), "INSTFILE"); + if (!inbuf) + return 0; - GetWinText(&idata->startmenudir,GetDlgItem(mainDlg[DL_SHORTCUTS],ED_FOLDER)); + GetWinText(&idata->startmenudir, + GetDlgItem(mainDlg[DL_SHORTCUTS], ED_FOLDER)); if (!SetCurrentDirectory(idata->installdir)) { - DisplayError("Cannot access install directory",TRUE,TRUE); + DisplayError("Cannot access install directory", TRUE, TRUE); } -/* Check for already-installed files */ - for (listpt=idata->keepfiles;listpt;listpt=listpt->next) { - fin = CreateFile(listpt->filename,GENERIC_READ,0,NULL,OPEN_EXISTING, - 0,NULL); + /* Check for already-installed files */ + for (listpt = idata->keepfiles; listpt; listpt = listpt->next) { + fin = CreateFile(listpt->filename, GENERIC_READ, 0, NULL, + OPEN_EXISTING, 0, NULL); if (fin != INVALID_HANDLE_VALUE) { CloseHandle(fin); - listpt->filesize=1; + listpt->filesize = 1; } } - logf = CreateFile("install.log",GENERIC_WRITE,0,NULL, - CREATE_ALWAYS,0,NULL); + logf = CreateFile("install.log", GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, 0, NULL); - if (!WriteFile(logf,idata->startmenudir,strlen(idata->startmenudir)+1, - &bytes_written,NULL)) { + if (!WriteFile(logf, idata->startmenudir, + strlen(idata->startmenudir) + 1, + &bytes_written, NULL)) { printf("Write error\n"); } fout = INVALID_HANDLE_VALUE; - listpt=NULL; - OpenNextOutput(&fout,idata->instfiles,idata->keepfiles, - &listpt,&fileleft,logf,&skipfile); + listpt = NULL; + OpenNextOutput(&fout, idata->instfiles, idata->keepfiles, + &listpt, &fileleft, logf, &skipfile); outbuf = bmalloc(BUFFER_SIZE); t@@ -792,49 +888,53 @@ DWORD WINAPI DoInstall(LPVOID lpParam) { z.avail_out = BUFFER_SIZE; while (1) { - status = inflate(&z,Z_SYNC_FLUSH); - if (status==Z_OK || status==Z_STREAM_END) { + status = inflate(&z, Z_SYNC_FLUSH); + if (status == Z_OK || status == Z_STREAM_END) { count = BUFFER_SIZE - z.avail_out; z.next_out = outbuf; while (count >= fileleft) { - if (fileleft && !skipfile && - !WriteFile(fout,z.next_out,fileleft,&bytes_written,NULL)) { + if (fileleft && !skipfile + && !WriteFile(fout, z.next_out, fileleft, &bytes_written, NULL)) { printf("Write error\n"); } - count-=fileleft; - z.next_out+=fileleft; - if (!OpenNextOutput(&fout,idata->instfiles,idata->keepfiles, - &listpt,&fileleft,logf,&skipfile)) break; + count -= fileleft; + z.next_out += fileleft; + if (!OpenNextOutput(&fout, idata->instfiles, idata->keepfiles, + &listpt, &fileleft, logf, &skipfile)) + break; } - if (fout==INVALID_HANDLE_VALUE) break; - if (count && !skipfile && - !WriteFile(fout,z.next_out,count,&bytes_written,NULL)) { + if (fout == INVALID_HANDLE_VALUE) + break; + if (count && !skipfile + && !WriteFile(fout, z.next_out, count, &bytes_written, NULL)) { printf("Write error\n"); } - fileleft-=count; + fileleft -= count; z.next_out = outbuf; z.avail_out = BUFFER_SIZE; } - if (status!=Z_OK) break; + if (status != Z_OK) + break; } inflateEnd(&z); - if (!skipfile) CloseHandle(fout); + if (!skipfile) + CloseHandle(fout); - outbuf[0]='\0'; - if (!WriteFile(logf,outbuf,1,&bytes_written,NULL)) { + outbuf[0] = '\0'; + if (!WriteFile(logf, outbuf, 1, &bytes_written, NULL)) { printf("Write error\n"); } bfree(outbuf); - WriteFileList(logf,idata->extrafiles); + WriteFileList(logf, idata->extrafiles); - FinishRemoveOldVersion(oldversion,idata,oldidata); + FinishRemoveOldVersion(oldversion, idata, oldidata); if (services_supported) { service_installed = InstallService(idata); } else { - service_installed = FALSE; + service_installed = FALSE; } if (service_installed) { t@@ -845,7 +945,7 @@ DWORD WINAPI DoInstall(LPVOID lpParam) { "you turn on your computer, see the \"Services\" application\n" "from Control Panel. You can also run an interactive server " "by using\nthe \"dopewars server\" shortcut from the desktop " - "and/or Start Menu.","Service Installed",MB_OK); + "and/or Start Menu.", "Service Installed", MB_OK); } CoInitialize(NULL); t@@ -853,7 +953,7 @@ DWORD WINAPI DoInstall(LPVOID lpParam) { SetupUninstall(); CoUninitialize(); - WriteServiceDetails(logf,service_installed ? idata->service : NULL); + WriteServiceDetails(logf, service_installed ? idata->service : NULL); if (install_all_users) { idata->flags |= IF_ALLUSERS; t@@ -862,111 +962,119 @@ DWORD WINAPI DoInstall(LPVOID lpParam) { CloseHandle(logf); - SetFileAttributes("install.log",FILE_ATTRIBUTE_HIDDEN); + SetFileAttributes("install.log", FILE_ATTRIBUTE_HIDDEN); - ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL],ST_COMPLETE),SW_SHOW); - ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL],ST_EXIT),SW_SHOW); - EnableWindow(GetDlgItem(mainDlg[DL_DOINSTALL],BT_FINISH),TRUE); + ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL], ST_COMPLETE), SW_SHOW); + ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL], ST_EXIT), SW_SHOW); + EnableWindow(GetDlgItem(mainDlg[DL_DOINSTALL], BT_FINISH), TRUE); return 0; } -void FillFolderList(void) { +void FillFolderList(void) +{ HANDLE findfile; WIN32_FIND_DATA finddata; bstr *str; char *startdir; HWND folderlist; - folderlist = GetDlgItem(mainDlg[DL_SHORTCUTS],LB_FOLDLIST); - if (!folderlist) return; + folderlist = GetDlgItem(mainDlg[DL_SHORTCUTS], LB_FOLDLIST); + if (!folderlist) + return; - SendMessage(folderlist,LB_RESETCONTENT,0,0); + SendMessage(folderlist, LB_RESETCONTENT, 0, 0); - str=bstr_new(); + str = bstr_new(); - startdir=GetStartMenuTopDir(install_all_users); - bstr_assign(str,startdir); + startdir = GetStartMenuTopDir(install_all_users); + bstr_assign(str, startdir); bfree(startdir); - bstr_appendpath(str,"Programs\\*"); - - findfile = FindFirstFile(str->text,&finddata); - if (findfile!=INVALID_HANDLE_VALUE) { - while(1) { - if (finddata.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY && - strcmp(finddata.cFileName,".")!=0 && - strcmp(finddata.cFileName,"..")!=0) { - SendMessage(folderlist,LB_ADDSTRING,0,(LPARAM)finddata.cFileName); + bstr_appendpath(str, "Programs\\*"); + + findfile = FindFirstFile(str->text, &finddata); + if (findfile != INVALID_HANDLE_VALUE) { + while (1) { + if (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY + && strcmp(finddata.cFileName, ".") != 0 + && strcmp(finddata.cFileName, "..") != 0) { + SendMessage(folderlist, LB_ADDSTRING, 0, + (LPARAM)finddata.cFileName); } - if (!FindNextFile(findfile,&finddata)) break; + if (!FindNextFile(findfile, &finddata)) + break; } FindClose(findfile); } - bstr_free(str,TRUE); + bstr_free(str, TRUE); } -BOOL CheckAdminRights(void) { - return (!services_supported || have_admin_rights || - MessageBox(NULL, - "To successfully install all components of this " - "program Administrator\nrights are required, and you " - "do not appear to have them. Do you want\nto attempt " - "to continue the installation anyway?", - "Administrator rights not found", - MB_YESNO | MB_DEFBUTTON2)==IDYES); +BOOL CheckAdminRights(void) +{ + return (!services_supported || have_admin_rights + || MessageBox(NULL, + "To successfully install all components of this " + "program Administrator\nrights are required, and you " + "do not appear to have them. Do you want\nto attempt " + "to continue the installation anyway?", + "Administrator rights not found", + MB_YESNO | MB_DEFBUTTON2) == IDYES); } -BOOL CheckExistingInstall(InstData *idata) { +BOOL CheckExistingInstall(InstData *idata) +{ bstr *str; - char *sep,*prodname,*prodversion; + char *sep, *prodname, *prodversion; char *subkey; int sublen; DWORD sublencp; HKEY key; DWORD ind; FILETIME ftime; - BOOL retval=TRUE; + BOOL retval = TRUE; + + str = bstr_new(); + bstr_assign(str, UninstallKey); + bstr_appendpath(str, idata->product); - str=bstr_new(); - bstr_assign(str,UninstallKey); - bstr_appendpath(str,idata->product); + /* Split product into name and version */ + sep = strrchr(idata->product, '-'); -/* Split product into name and version */ - sep = strrchr(idata->product,'-'); - - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,str->text,0,KEY_READ,&key) - ==ERROR_SUCCESS) { + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, str->text, 0, KEY_READ, &key) == + ERROR_SUCCESS) { RegCloseKey(key); - if (MessageBox(NULL,"This program appears to already be installed.\n" + if (MessageBox(NULL, "This program appears to already be installed.\n" "Are you sure you want to go ahead and install it anyway?", - idata->product,MB_YESNO)==IDNO) retval=FALSE; + idata->product, MB_YESNO) == IDNO) + retval = FALSE; } else if (sep) { - *sep='\0'; - prodversion = sep+1; + *sep = '\0'; + prodversion = sep + 1; prodname = bstrdup(idata->product); - *sep='-'; - sublencp=sublen=strlen(idata->product)+30; + *sep = '-'; + sublencp = sublen = strlen(idata->product) + 30; subkey = bmalloc(sublen); - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,UninstallKey,0,KEY_READ,&key) - ==ERROR_SUCCESS) { - ind=0; - while (RegEnumKeyEx(key,ind++,subkey,&sublencp, - NULL,NULL,NULL,&ftime)==ERROR_SUCCESS) { - sublencp=sublen; - sep=strrchr(subkey,'-'); + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, UninstallKey, 0, + KEY_READ, &key) == ERROR_SUCCESS) { + ind = 0; + while (RegEnumKeyEx(key, ind++, subkey, &sublencp, + NULL, NULL, NULL, &ftime) == ERROR_SUCCESS) { + sublencp = sublen; + sep = strrchr(subkey, '-'); if (sep) { - *sep='\0'; - if (strcmp(subkey,prodname)==0) { - bstr_assign(str,"You are trying to install "); - bstr_append(str,idata->product); - bstr_append(str,".\nHowever, version "); - bstr_append(str,sep+1); - bstr_append(str," appears to already be installed.\n" + *sep = '\0'; + if (strcmp(subkey, prodname) == 0) { + bstr_assign(str, "You are trying to install "); + bstr_append(str, idata->product); + bstr_append(str, ".\nHowever, version "); + bstr_append(str, sep + 1); + bstr_append(str, " appears to already be installed.\n" "Do you want to replace the existing version with " "this one?\n(If you answer \"No\", and continue, " "both versions will be installed.)"); - if (MessageBox(NULL,str->text,"Existing version",MB_YESNO)==IDYES) { - *sep='-'; - oldversion=bstrdup(subkey); + if (MessageBox(NULL, str->text, "Existing version", + MB_YESNO) == IDYES) { + *sep = '-'; + oldversion = bstrdup(subkey); } break; } t@@ -977,11 +1085,12 @@ BOOL CheckExistingInstall(InstData *idata) { bfree(prodname); bfree(subkey); } - bstr_free(str,TRUE); + bstr_free(str, TRUE); return retval; } -BOOL SetDefaultInstall(void) { +BOOL SetDefaultInstall(void) +{ HWND dlg; dlg = mainDlg[DL_INTRO]; t@@ -997,8 +1106,9 @@ BOOL SetDefaultInstall(void) { return have_admin_rights; } -int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, - LPSTR lpszCmdParam,int nCmdShow) { +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpszCmdParam, int nCmdShow) +{ MSG msg; int i; BOOL Handled; t@@ -1008,47 +1118,50 @@ int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, hInst = hInstance; - if (!hPrevInstance) RegisterSepClass(hInstance); + if (!hPrevInstance) + RegisterSepClass(hInstance); - for (i=0;i<DL_NUM;i++) { - mainDlg[i] = CreateDialog(hInst,MAKEINTRESOURCE(i+1),NULL,MainDlgProc); + for (i = 0; i < DL_NUM; i++) { + mainDlg[i] = + CreateDialog(hInst, MAKEINTRESOURCE(i + 1), NULL, MainDlgProc); } - ServiceCheck(&services_supported,&have_admin_rights); + ServiceCheck(&services_supported, &have_admin_rights); install_all_users = SetDefaultInstall(); - CheckDlgButton(mainDlg[DL_SHORTCUTS],CB_DESKTOP,BST_CHECKED); - EnableWindow(GetDlgItem(mainDlg[DL_DOINSTALL],BT_FINISH),FALSE); + CheckDlgButton(mainDlg[DL_SHORTCUTS], CB_DESKTOP, BST_CHECKED); + EnableWindow(GetDlgItem(mainDlg[DL_DOINSTALL], BT_FINISH), FALSE); + + ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL], ST_COMPLETE), SW_HIDE); + ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL], ST_EXIT), SW_HIDE); - ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL],ST_COMPLETE),SW_HIDE); - ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL],ST_EXIT),SW_HIDE); + idata = ReadInstData(); - idata=ReadInstData(); + SendDlgItemMessage(mainDlg[DL_SHORTCUTS], ED_FOLDER, WM_SETTEXT, + 0, (LPARAM)idata->startmenudir); + SendDlgItemMessage(mainDlg[DL_INSTALLDIR], ED_INSTDIR, WM_SETTEXT, + 0, (LPARAM)idata->installdir); - SendDlgItemMessage(mainDlg[DL_SHORTCUTS],ED_FOLDER,WM_SETTEXT, - 0,(LPARAM)idata->startmenudir); - SendDlgItemMessage(mainDlg[DL_INSTALLDIR],ED_INSTDIR,WM_SETTEXT, - 0,(LPARAM)idata->installdir); - - licence=GetFirstFile(idata->instfiles,idata->totalsize); + licence = GetFirstFile(idata->instfiles, idata->totalsize); if (licence) { - SendDlgItemMessage(mainDlg[DL_LICENCE],ED_LICENCE,WM_SETTEXT, - 0,(LPARAM)licence); + SendDlgItemMessage(mainDlg[DL_LICENCE], ED_LICENCE, WM_SETTEXT, + 0, (LPARAM)licence); bfree(licence); } - for (i=0;i<DL_NUM;i++) SetGuiFont(mainDlg[i]); + for (i = 0; i < DL_NUM; i++) + SetGuiFont(mainDlg[i]); if (CheckAdminRights() && CheckExistingInstall(idata)) { - CurrentDialog=DL_NUM; + CurrentDialog = DL_NUM; ShowNewDialog(DL_INTRO); - while (GetMessage(&msg,NULL,0,0)) { - Handled=FALSE; - for (i=0;i<DL_NUM && !Handled;i++) { - Handled=IsDialogMessage(mainDlg[i],&msg); + while (GetMessage(&msg, NULL, 0, 0)) { + Handled = FALSE; + for (i = 0; i < DL_NUM && !Handled; i++) { + Handled = IsDialogMessage(mainDlg[i], &msg); } if (!Handled) { TranslateMessage(&msg); t@@ -1056,7 +1169,7 @@ int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, } } } - FreeInstData(idata,FALSE); + FreeInstData(idata, FALSE); return 0; } (DIR) diff --git a/win32/uninstall.c b/win32/uninstall.c t@@ -1,22 +1,24 @@ -/* uninstall.c Simple Win32 uninstaller for dopewars */ -/* Copyright (C) 2001 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * uninstall.c Simple Win32 uninstaller for dopewars * + * Copyright (C) 2001-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #include <windows.h> #include <stdio.h> t@@ -30,144 +32,161 @@ HINSTANCE hInst; HWND mainDlg; char *product; -char *GetProduct(void) { +char *GetProduct(void) +{ char *product; - product = strrchr(GetCommandLine(),' '); - if (product && strlen(product+1)>0) return bstrdup(++product); + + product = strrchr(GetCommandLine(), ' '); + if (product && strlen(product + 1) > 0) + return bstrdup(++product); else { - DisplayError("This program should be called with a product ID",FALSE,TRUE); + DisplayError("This program should be called with a product ID", + FALSE, TRUE); ExitProcess(1); } } -DWORD WINAPI DoUninstall(LPVOID lpParam) { +DWORD WINAPI DoUninstall(LPVOID lpParam) +{ InstData *idata; HANDLE fin; HWND delstat; bstr *str; - char *startmenu,*desktop,*installdir; + char *startmenu, *desktop, *installdir; - installdir=GetInstallDir(product); + installdir = GetInstallDir(product); if (!SetCurrentDirectory(installdir)) { - str=bstr_new(); - bstr_assign(str,"Could not access install directory "); - bstr_append(str,installdir); - DisplayError(str->text,TRUE,TRUE); -/* Pointless to try to free the bstr, since DisplayError ends the process */ + str = bstr_new(); + bstr_assign(str, "Could not access install directory "); + bstr_append(str, installdir); + DisplayError(str->text, TRUE, TRUE); + /* Pointless to try to free the bstr, since DisplayError ends the + * process */ } - fin = CreateFile("install.log",GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); + fin = CreateFile("install.log", GENERIC_READ, 0, NULL, + OPEN_EXISTING, 0, NULL); if (fin) { - idata = ReadOldInstData(fin,product,installdir); + idata = ReadOldInstData(fin, product, installdir); CloseHandle(fin); DeleteFile("install.log"); RemoveService(idata->service); - delstat = GetDlgItem(mainDlg,ST_DELSTAT); - DeleteFileList(idata->instfiles,delstat,NULL); - DeleteFileList(idata->extrafiles,delstat,NULL); + delstat = GetDlgItem(mainDlg, ST_DELSTAT); + DeleteFileList(idata->instfiles, delstat, NULL); + DeleteFileList(idata->extrafiles, delstat, NULL); startmenu = GetStartMenuDir(idata->flags & IF_ALLUSERS, idata); desktop = GetDesktopDir(); - DeleteLinkList(startmenu,idata->startmenu,delstat); - DeleteLinkList(desktop,idata->desktop,delstat); + DeleteLinkList(startmenu, idata->startmenu, delstat); + DeleteLinkList(desktop, idata->desktop, delstat); - RemoveUninstall(startmenu,product,TRUE); + RemoveUninstall(startmenu, product, TRUE); - SetCurrentDirectory(desktop); /* Just make sure we're not in the install - directory any more */ + SetCurrentDirectory(desktop); /* Just make sure we're not in the + * install directory any more */ - str=bstr_new(); + str = bstr_new(); if (!RemoveWholeDirectory(installdir)) { - bstr_assign(str,"Could not remove install directory:\n"); - bstr_append(str,installdir); - bstr_append(str,"\nYou may wish to manually remove it later."); - DisplayError(str->text,FALSE,FALSE); + bstr_assign(str, "Could not remove install directory:\n"); + bstr_append(str, installdir); + bstr_append(str, "\nYou may wish to manually remove it later."); + DisplayError(str->text, FALSE, FALSE); } if (!RemoveWholeDirectory(startmenu)) { - bstr_assign(str,"Could not remove Start Menu directory:\n"); - bstr_append(str,startmenu); - bstr_append(str,"\nYou may wish to manually remove it later."); - DisplayError(str->text,FALSE,FALSE); + bstr_assign(str, "Could not remove Start Menu directory:\n"); + bstr_append(str, startmenu); + bstr_append(str, "\nYou may wish to manually remove it later."); + DisplayError(str->text, FALSE, FALSE); } - bstr_assign(str,UninstallKey); - bstr_appendpath(str,product); - RegDeleteKey(HKEY_LOCAL_MACHINE,str->text); - bstr_free(str,TRUE); + bstr_assign(str, UninstallKey); + bstr_appendpath(str, product); + RegDeleteKey(HKEY_LOCAL_MACHINE, str->text); + bstr_free(str, TRUE); - bfree(startmenu); bfree(desktop); - FreeInstData(idata,TRUE); + bfree(startmenu); + bfree(desktop); + FreeInstData(idata, TRUE); } else { - bfree(product); bfree(installdir); /* Normally FreeInstData frees these */ - str=bstr_new(); - bstr_assign(str,"Could not read install.log from "); - bstr_append(str,installdir); - DisplayError(str->text,TRUE,TRUE); -/* Pointless to try to free the bstr, since DisplayError ends the process */ + bfree(product); + bfree(installdir); /* Normally FreeInstData frees these */ + str = bstr_new(); + bstr_assign(str, "Could not read install.log from "); + bstr_append(str, installdir); + DisplayError(str->text, TRUE, TRUE); + /* Pointless to try to free the bstr, since DisplayError ends the + * process */ } - ShowWindow(GetDlgItem(mainDlg,ST_DELDONE),SW_SHOW); - EnableWindow(GetDlgItem(mainDlg,BT_DELOK),TRUE); - SetFocus(GetDlgItem(mainDlg,BT_DELOK)); + ShowWindow(GetDlgItem(mainDlg, ST_DELDONE), SW_SHOW); + EnableWindow(GetDlgItem(mainDlg, BT_DELOK), TRUE); + SetFocus(GetDlgItem(mainDlg, BT_DELOK)); return 0; } -BOOL CALLBACK MainDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { +BOOL CALLBACK MainDlgProc(HWND hWnd, UINT msg, WPARAM wParam, + LPARAM lParam) +{ HANDLE hThread; DWORD threadID; - static BOOL startedun=FALSE; - switch(msg) { - case WM_INITDIALOG: - return TRUE; - case WM_SHOWWINDOW: - if (wParam && !startedun) { - startedun=TRUE; - hThread = CreateThread(NULL,0,DoUninstall,NULL,0,&threadID); - } - return TRUE; - case WM_COMMAND: - if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==BT_DELOK && lParam) { - PostQuitMessage(0); - return TRUE; - } - break; - case WM_CLOSE: + static BOOL startedun = FALSE; + + switch (msg) { + case WM_INITDIALOG: + return TRUE; + case WM_SHOWWINDOW: + if (wParam && !startedun) { + startedun = TRUE; + hThread = CreateThread(NULL, 0, DoUninstall, NULL, 0, &threadID); + } + return TRUE; + case WM_COMMAND: + if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == BT_DELOK + && lParam) { PostQuitMessage(0); return TRUE; + } + break; + case WM_CLOSE: + PostQuitMessage(0); + return TRUE; } return FALSE; } -int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, - LPSTR lpszCmdParam,int nCmdShow) { +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpszCmdParam, int nCmdShow) +{ MSG msg; bstr *str; - product=GetProduct(); + product = GetProduct(); - str=bstr_new(); - bstr_assign(str,"Are you sure you want to uninstall "); - bstr_append(str,product); - bstr_append(str," ?"); - if (MessageBox(NULL,str->text,"Uninstall",MB_YESNO)==IDNO) return(1); - bstr_free(str,TRUE); + str = bstr_new(); + bstr_assign(str, "Are you sure you want to uninstall "); + bstr_append(str, product); + bstr_append(str, " ?"); + if (MessageBox(NULL, str->text, "Uninstall", MB_YESNO) == IDNO) + return (1); + bstr_free(str, TRUE); hInst = hInstance; - if (!hPrevInstance) RegisterSepClass(hInstance); + if (!hPrevInstance) + RegisterSepClass(hInstance); - mainDlg = CreateDialog(hInstance,MAKEINTRESOURCE(1),NULL,MainDlgProc); + mainDlg = CreateDialog(hInstance, MAKEINTRESOURCE(1), NULL, MainDlgProc); SetGuiFont(mainDlg); - EnableWindow(GetDlgItem(mainDlg,BT_DELOK),FALSE); - ShowWindow(mainDlg,SW_SHOW); - ShowWindow(GetDlgItem(mainDlg,ST_DELDONE),SW_HIDE); + EnableWindow(GetDlgItem(mainDlg, BT_DELOK), FALSE); + ShowWindow(mainDlg, SW_SHOW); + ShowWindow(GetDlgItem(mainDlg, ST_DELDONE), SW_HIDE); - while (GetMessage(&msg,NULL,0,0)) { - if (!IsDialogMessage(mainDlg,&msg)) { + while (GetMessage(&msg, NULL, 0, 0)) { + if (!IsDialogMessage(mainDlg, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } (DIR) diff --git a/win32/util.c b/win32/util.c t@@ -1,22 +1,24 @@ -/* util.c Shared functions for Win32 installer programs */ -/* Copyright (C) 2001 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * util.c Shared functions for Win32 installer programs * + * Copyright (C) 2001-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #include <windows.h> #include <stdio.h> t@@ -24,203 +26,240 @@ #include <shlobj.h> #include "util.h" -const char *UninstallKey= - "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; -const char *UninstallEXE="bw-uninstall.exe"; +const char *UninstallKey = + "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; +const char *UninstallEXE = "bw-uninstall.exe"; -static void bstr_append_dir(bstr *str,BOOL windir); +static void bstr_append_dir(bstr *str, BOOL windir); -void *bmalloc(UINT numbytes) { +void *bmalloc(UINT numbytes) +{ HLOCAL localpt; - if (numbytes<=0) numbytes=1; + if (numbytes <= 0) + numbytes = 1; - localpt = LocalAlloc(LMEM_FIXED,numbytes); - if (localpt) return (void *)localpt; + localpt = LocalAlloc(LMEM_FIXED, numbytes); + if (localpt) + return (void *)localpt; else { - DisplayError("Could not allocate memory: ",TRUE,TRUE); + DisplayError("Could not allocate memory: ", TRUE, TRUE); ExitProcess(1); } } -void bfree(void *pt) { - if (!pt) return; - if (LocalFree((HLOCAL)pt)) { - DisplayError("Could not free memory: ",TRUE,TRUE); +void bfree(void *pt) +{ + if (!pt) + return; + if (LocalFree((HLOCAL) pt)) { + DisplayError("Could not free memory: ", TRUE, TRUE); } } -void *brealloc(void *pt,UINT numbytes) { +void *brealloc(void *pt, UINT numbytes) +{ UINT numcp; void *newpt; - if (!pt && numbytes) return bmalloc(numbytes); + + if (!pt && numbytes) + return bmalloc(numbytes); else if (pt && !numbytes) { bfree(pt); } else if (pt && numbytes) { - newpt=bmalloc(numbytes); - memset(newpt,0,numbytes); - numcp = LocalSize((HLOCAL)pt); - if (numbytes < numcp) numcp = numbytes; - memcpy((char *)newpt,(char *)pt,numcp); + newpt = bmalloc(numbytes); + memset(newpt, 0, numbytes); + numcp = LocalSize((HLOCAL) pt); + if (numbytes < numcp) + numcp = numbytes; + memcpy((char *)newpt, (char *)pt, numcp); bfree(pt); return newpt; } return NULL; } -char *bstrdup(char *str) { +char *bstrdup(char *str) +{ char *newstr; + if (str) { - newstr = bmalloc(strlen(str)+1); - strcpy(newstr,str); + newstr = bmalloc(strlen(str) + 1); + strcpy(newstr, str); } else { newstr = bmalloc(1); - newstr[0]='\0'; + newstr[0] = '\0'; } return newstr; } -bstr *bstr_new(void) { +bstr *bstr_new(void) +{ bstr *str; str = bmalloc(sizeof(bstr)); - str->bufsiz=64; - str->length=0; - str->text= bmalloc(str->bufsiz); - str->text[0]='\0'; + str->bufsiz = 64; + str->length = 0; + str->text = bmalloc(str->bufsiz); + str->text[0] = '\0'; return str; } -void bstr_free(bstr *str,BOOL free_text) { - if (free_text) bfree(str->text); +void bstr_free(bstr *str, BOOL free_text) +{ + if (free_text) + bfree(str->text); bfree(str); } -void bstr_expandby(bstr *str,unsigned extralength) { - if (str->bufsiz >= str->length+1+extralength) return; +void bstr_expandby(bstr *str, unsigned extralength) +{ + if (str->bufsiz >= str->length + 1 + extralength) + return; - while (str->bufsiz < str->length+1+extralength) str->bufsiz*=2; - str->text = brealloc(str->text,str->bufsiz); + while (str->bufsiz < str->length + 1 + extralength) + str->bufsiz *= 2; + str->text = brealloc(str->text, str->bufsiz); } -void bstr_setlength(bstr *str,unsigned length) { +void bstr_setlength(bstr *str, unsigned length) +{ if (length <= str->length) { str->length = length; - str->text[length]='\0'; + str->text[length] = '\0'; } else { - bstr_expandby(str,length-str->length); + bstr_expandby(str, length - str->length); } } -void bstr_assign(bstr *str,const char *text) { +void bstr_assign(bstr *str, const char *text) +{ if (text) { - bstr_setlength(str,strlen(text)); - strcpy(str->text,text); - str->length=strlen(text); + bstr_setlength(str, strlen(text)); + strcpy(str->text, text); + str->length = strlen(text); } else { - bstr_setlength(str,0); + bstr_setlength(str, 0); } } -void bstr_append(bstr *str,const char *text) { - if (!text) return; - bstr_expandby(str,strlen(text)); - strcat(str->text,text); - str->length+=strlen(text); +void bstr_append(bstr *str, const char *text) +{ + if (!text) + return; + bstr_expandby(str, strlen(text)); + strcat(str->text, text); + str->length += strlen(text); } -void bstr_appendpath(bstr *str,const char *text) { - if (str->length && str->text[str->length-1]!='\\') { - bstr_append_c(str,'\\'); +void bstr_appendpath(bstr *str, const char *text) +{ + if (str->length && str->text[str->length - 1] != '\\') { + bstr_append_c(str, '\\'); } - bstr_append(str,text); + bstr_append(str, text); } -void bstr_append_c(bstr *str,char ch) { - bstr_expandby(str,1); - str->text[str->length]=ch; +void bstr_append_c(bstr *str, char ch) +{ + bstr_expandby(str, 1); + str->text[str->length] = ch; str->length++; - str->text[str->length]='\0'; + str->text[str->length] = '\0'; } /* We can be pretty confident that this is enough space for an integer */ #define MAX_LENGTH_INT 80 -void bstr_append_long(bstr *str,long val) { +void bstr_append_long(bstr *str, long val) +{ char tmpbuf[MAX_LENGTH_INT]; - sprintf(tmpbuf,"%ld",val); - bstr_append(str,tmpbuf); + + sprintf(tmpbuf, "%ld", val); + bstr_append(str, tmpbuf); } -void bstr_append_windir(bstr *str) { - bstr_append_dir(str,TRUE); +void bstr_append_windir(bstr *str) +{ + bstr_append_dir(str, TRUE); } -void bstr_append_curdir(bstr *str) { - bstr_append_dir(str,FALSE); +void bstr_append_curdir(bstr *str) +{ + bstr_append_dir(str, FALSE); } -void bstr_assign_windir(bstr *str) { - bstr_setlength(str,0); +void bstr_assign_windir(bstr *str) +{ + bstr_setlength(str, 0); bstr_append_windir(str); } -void bstr_assign_curdir(bstr *str) { - bstr_setlength(str,0); +void bstr_assign_curdir(bstr *str) +{ + bstr_setlength(str, 0); bstr_append_curdir(str); } -void bstr_append_dir(bstr *str,BOOL windir) { +void bstr_append_dir(bstr *str, BOOL windir) +{ unsigned spaceleft; UINT retval; int tries; - spaceleft = str->bufsiz-str->length; /* spaceleft includes the null */ + spaceleft = str->bufsiz - str->length; /* spaceleft includes the + * null */ - for (tries=0;tries<5;tries++) { + for (tries = 0; tries < 5; tries++) { if (windir) { - retval = GetWindowsDirectory(str->text+str->length,spaceleft); + retval = GetWindowsDirectory(str->text + str->length, spaceleft); } else { - retval = GetCurrentDirectory(spaceleft,str->text+str->length); + retval = GetCurrentDirectory(spaceleft, str->text + str->length); } - if (retval==0) DisplayError("Cannot get directory: ",TRUE,TRUE); - if (retval <= spaceleft-1) { + if (retval == 0) + DisplayError("Cannot get directory: ", TRUE, TRUE); + if (retval <= spaceleft - 1) { str->length += retval; break; } - bstr_expandby(str,retval); /* Let's err on the side of caution */ - spaceleft = str->bufsiz-str->length; + bstr_expandby(str, retval); /* Let's err on the side of caution */ + spaceleft = str->bufsiz - str->length; } - if (tries>=5) DisplayError("Cannot get directory: ",TRUE,TRUE); + if (tries >= 5) + DisplayError("Cannot get directory: ", TRUE, TRUE); } -void DisplayError(const char *errtext,BOOL addsyserr,BOOL fatal) { +void DisplayError(const char *errtext, BOOL addsyserr, BOOL fatal) +{ DWORD syserr; bstr *str; LPTSTR lpMsgBuf; - syserr=GetLastError(); + syserr = GetLastError(); - str=bstr_new(); - bstr_assign(str,errtext); + str = bstr_new(); + bstr_assign(str, errtext); if (addsyserr) { - bstr_append(str,"; "); - bstr_append_long(str,syserr); - bstr_append(str,": "); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, - NULL,syserr,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), - (LPTSTR)&lpMsgBuf,0,NULL); - bstr_append(str,lpMsgBuf); + bstr_append(str, "; "); + bstr_append_long(str, syserr); + bstr_append(str, ": "); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, NULL, syserr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&lpMsgBuf, 0, NULL); + bstr_append(str, lpMsgBuf); LocalFree(lpMsgBuf); } - MessageBox(NULL,str->text,fatal ? "Fatal Error" : "Error", + MessageBox(NULL, str->text, fatal ? "Fatal Error" : "Error", MB_OK | MB_ICONSTOP); - if (fatal) ExitProcess(1); + if (fatal) + ExitProcess(1); } -void AddInstFiles(char *filename,DWORD filesize,InstFiles **lastpt, - InstFiles **firstpt) { +void AddInstFiles(char *filename, DWORD filesize, InstFiles **lastpt, + InstFiles **firstpt) +{ InstFiles *newpt; newpt = bmalloc(sizeof(InstFiles)); t@@ -230,13 +269,14 @@ void AddInstFiles(char *filename,DWORD filesize,InstFiles **lastpt, *firstpt = newpt; } *lastpt = newpt; - newpt->next=NULL; - newpt->filename=filename; - newpt->filesize=filesize; + newpt->next = NULL; + newpt->filename = filename; + newpt->filesize = filesize; } -void AddInstLink(char *linkfile,char *origfile,char *args,InstLink **lastpt, - InstLink **firstpt) { +void AddInstLink(char *linkfile, char *origfile, char *args, + InstLink **lastpt, InstLink **firstpt) +{ InstLink *newpt; newpt = bmalloc(sizeof(InstLink)); t@@ -246,18 +286,19 @@ void AddInstLink(char *linkfile,char *origfile,char *args,InstLink **lastpt, *firstpt = newpt; } *lastpt = newpt; - newpt->next=NULL; - newpt->linkfile=linkfile; - newpt->origfile=origfile; - newpt->args=args; + newpt->next = NULL; + newpt->linkfile = linkfile; + newpt->origfile = origfile; + newpt->args = args; } -void FreeLinkList(InstLink *linklist,BOOL freepts) { - InstLink *thispt,*nextpt; +void FreeLinkList(InstLink *linklist, BOOL freepts) +{ + InstLink *thispt, *nextpt; - thispt=linklist; + thispt = linklist; while (thispt) { - nextpt=thispt->next; + nextpt = thispt->next; if (freepts) { bfree(thispt->linkfile); t@@ -266,27 +307,30 @@ void FreeLinkList(InstLink *linklist,BOOL freepts) { } bfree(thispt); - thispt=nextpt; + thispt = nextpt; } } -void FreeFileList(InstFiles *filelist,BOOL freepts) { - InstFiles *thispt,*nextpt; +void FreeFileList(InstFiles *filelist, BOOL freepts) +{ + InstFiles *thispt, *nextpt; - thispt=filelist; + thispt = filelist; while (thispt) { - nextpt=thispt->next; + nextpt = thispt->next; - if (freepts) bfree(thispt->filename); + if (freepts) + bfree(thispt->filename); bfree(thispt); - thispt=nextpt; + thispt = nextpt; } } -void AddServiceDetails(char *servicename,char *servicedisp, - char *servicedesc,char *serviceexe, - NTService **service) { +void AddServiceDetails(char *servicename, char *servicedisp, + char *servicedesc, char *serviceexe, + NTService **service) +{ *service = bmalloc(sizeof(NTService)); (*service)->name = servicename; (*service)->display = servicedisp; t@@ -294,8 +338,10 @@ void AddServiceDetails(char *servicename,char *servicedisp, (*service)->exe = serviceexe; } -void FreeServiceDetails(NTService *service,BOOL freepts) { - if (!service) return; +void FreeServiceDetails(NTService *service, BOOL freepts) +{ + if (!service) + return; if (freepts) { bfree(service->name); t@@ -306,15 +352,16 @@ void FreeServiceDetails(NTService *service,BOOL freepts) { bfree(service); } -void FreeInstData(InstData *idata,BOOL freepts) { - FreeFileList(idata->instfiles,freepts); - FreeFileList(idata->extrafiles,freepts); - FreeFileList(idata->keepfiles,freepts); +void FreeInstData(InstData *idata, BOOL freepts) +{ + FreeFileList(idata->instfiles, freepts); + FreeFileList(idata->extrafiles, freepts); + FreeFileList(idata->keepfiles, freepts); - FreeLinkList(idata->startmenu,freepts); - FreeLinkList(idata->desktop,freepts); + FreeLinkList(idata->startmenu, freepts); + FreeLinkList(idata->desktop, freepts); - FreeServiceDetails(idata->service,freepts); + FreeServiceDetails(idata->service, freepts); bfree(idata->product); bfree(idata->installdir); t@@ -323,203 +370,230 @@ void FreeInstData(InstData *idata,BOOL freepts) { bfree(idata); } -void WriteInstFlags(HANDLE fout, InstFlags flags) { +void WriteInstFlags(HANDLE fout, InstFlags flags) +{ DWORD bytes_written; char str[3]; str[0] = (char)flags; - if (!WriteFile(fout,str,1,&bytes_written,NULL)) { + if (!WriteFile(fout, str, 1, &bytes_written, NULL)) { printf("Write error\n"); } } -void WriteServiceDetails(HANDLE fout,NTService *service) { +void WriteServiceDetails(HANDLE fout, NTService *service) +{ DWORD bytes_written; - char str[]=""; + char str[] = ""; if (!service) { - if (!WriteFile(fout,str,strlen(str)+1,&bytes_written,NULL)) { + if (!WriteFile(fout, str, strlen(str) + 1, &bytes_written, NULL)) { printf("Write error\n"); } } else { - if (!WriteFile(fout,service->name,strlen(service->name)+1, - &bytes_written,NULL)) { + if (!WriteFile(fout, service->name, strlen(service->name) + 1, + &bytes_written, NULL)) { printf("Write error\n"); } - if (!WriteFile(fout,service->display,strlen(service->display)+1, - &bytes_written,NULL)) { + if (!WriteFile(fout, service->display, strlen(service->display) + 1, + &bytes_written, NULL)) { printf("Write error\n"); } - if (!WriteFile(fout,service->description,strlen(service->description)+1, - &bytes_written,NULL)) { + if (!WriteFile + (fout, service->description, strlen(service->description) + 1, + &bytes_written, NULL)) { printf("Write error\n"); } - if (!WriteFile(fout,service->exe,strlen(service->exe)+1, - &bytes_written,NULL)) { + if (!WriteFile(fout, service->exe, strlen(service->exe) + 1, + &bytes_written, NULL)) { printf("Write error\n"); } } } -void WriteLinkList(HANDLE fout,InstLink *listpt) { - char str[]=""; +void WriteLinkList(HANDLE fout, InstLink *listpt) +{ + char str[] = ""; DWORD bytes_written; - for (;listpt;listpt=listpt->next) { - if (!WriteFile(fout,listpt->linkfile,strlen(listpt->linkfile)+1, - &bytes_written,NULL)) { + + for (; listpt; listpt = listpt->next) { + if (!WriteFile(fout, listpt->linkfile, strlen(listpt->linkfile) + 1, + &bytes_written, NULL)) { printf("Write error\n"); } - if (!WriteFile(fout,listpt->origfile,strlen(listpt->origfile)+1, - &bytes_written,NULL)) { + if (!WriteFile(fout, listpt->origfile, strlen(listpt->origfile) + 1, + &bytes_written, NULL)) { printf("Write error\n"); } - if (!WriteFile(fout,listpt->args,strlen(listpt->args)+1, - &bytes_written,NULL)) { + if (!WriteFile(fout, listpt->args, strlen(listpt->args) + 1, + &bytes_written, NULL)) { printf("Write error\n"); } } - if (!WriteFile(fout,str,strlen(str)+1,&bytes_written,NULL)) { + if (!WriteFile(fout, str, strlen(str) + 1, &bytes_written, NULL)) { printf("Write error\n"); } } -void WriteFileList(HANDLE fout,InstFiles *listpt) { +void WriteFileList(HANDLE fout, InstFiles *listpt) +{ bstr *str; DWORD bytes_written; - str=bstr_new(); - for (;listpt;listpt=listpt->next) { - if (!WriteFile(fout,listpt->filename,strlen(listpt->filename)+1, - &bytes_written,NULL)) { + str = bstr_new(); + + for (; listpt; listpt = listpt->next) { + if (!WriteFile(fout, listpt->filename, strlen(listpt->filename) + 1, + &bytes_written, NULL)) { printf("Write error\n"); } - bstr_setlength(str,0); - bstr_append_long(str,listpt->filesize); - if (!WriteFile(fout,str->text,str->length+1,&bytes_written,NULL)) { + bstr_setlength(str, 0); + bstr_append_long(str, listpt->filesize); + if (!WriteFile(fout, str->text, str->length + 1, &bytes_written, NULL)) { printf("Write error\n"); } } - bstr_assign(str,""); - if (!WriteFile(fout,str->text,str->length+1,&bytes_written,NULL)) { + bstr_assign(str, ""); + if (!WriteFile(fout, str->text, str->length + 1, &bytes_written, NULL)) { printf("Write error\n"); } - bstr_free(str,TRUE); + bstr_free(str, TRUE); } -static char *GetSpecialDir(int dirtype) { +static char *GetSpecialDir(int dirtype) +{ LPITEMIDLIST pidl; LPMALLOC pmalloc; char szDir[MAX_PATH]; - BOOL doneOK=FALSE; + BOOL doneOK = FALSE; if (SUCCEEDED(SHGetMalloc(&pmalloc))) { - if (SUCCEEDED(SHGetSpecialFolderLocation(NULL,dirtype,&pidl))) { - if (SHGetPathFromIDList(pidl,szDir)) doneOK=TRUE; - pmalloc->lpVtbl->Free(pmalloc,pidl); + if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, dirtype, &pidl))) { + if (SHGetPathFromIDList(pidl, szDir)) + doneOK = TRUE; + pmalloc->lpVtbl->Free(pmalloc, pidl); } pmalloc->lpVtbl->Release(pmalloc); } return (doneOK ? bstrdup(szDir) : NULL); } -char *GetStartMenuTopDir(BOOL AllUsers) { - return GetSpecialDir(AllUsers ? CSIDL_COMMON_STARTMENU : CSIDL_STARTMENU); +char *GetStartMenuTopDir(BOOL AllUsers) +{ + return GetSpecialDir(AllUsers ? CSIDL_COMMON_STARTMENU : + CSIDL_STARTMENU); } -char *GetDesktopDir(void) { +char *GetDesktopDir(void) +{ return GetSpecialDir(CSIDL_DESKTOPDIRECTORY); } -char *GetStartMenuDir(BOOL AllUsers, InstData *idata) { +char *GetStartMenuDir(BOOL AllUsers, InstData *idata) +{ bstr *str; - char *topdir,*retval; + char *topdir, *retval; - topdir=GetStartMenuTopDir(AllUsers); + topdir = GetStartMenuTopDir(AllUsers); str = bstr_new(); - - bstr_assign(str,topdir); + + bstr_assign(str, topdir); bfree(topdir); - bstr_appendpath(str,"Programs"); - bstr_appendpath(str,idata->startmenudir); + bstr_appendpath(str, "Programs"); + bstr_appendpath(str, idata->startmenudir); retval = str->text; - bstr_free(str,FALSE); + bstr_free(str, FALSE); return retval; } -BOOL CreateWholeDirectory(char *path) { +BOOL CreateWholeDirectory(char *path) +{ char *pt; - if (!path) return FALSE; -/* We may as well try the easy way first */ - if (CreateDirectory(path,NULL)) return TRUE; + if (!path) + return FALSE; + + /* We may as well try the easy way first */ + if (CreateDirectory(path, NULL)) + return TRUE; /* \\machine\share notation */ - if (strlen(path)>2 && path[0]=='\\' && path[1]=='\\') { - pt=&path[2]; /* Skip initial "\\" */ - while (*pt && *pt!='\\') pt++; /* Skip the machine name */ - /* X: notation */ - } else if (strlen(path)>2 && path[1]==':') { - pt=&path[2]; /* Skip the X: part */ + if (strlen(path) > 2 && path[0] == '\\' && path[1] == '\\') { + pt = &path[2]; /* Skip initial "\\" */ + while (*pt && *pt != '\\') + pt++; /* Skip the machine name */ + /* X: notation */ + } else if (strlen(path) > 2 && path[1] == ':') { + pt = &path[2]; /* Skip the X: part */ } else { - pt=path; + pt = path; } while (*pt) { pt++; - if (*pt=='\\') { - *pt='\0'; - if (!CreateDirectory(path,NULL) && GetLastError()!=ERROR_ALREADY_EXISTS) { - *pt='\\'; return FALSE; + if (*pt == '\\') { + *pt = '\0'; + if (!CreateDirectory(path, NULL) + && GetLastError() != ERROR_ALREADY_EXISTS) { + *pt = '\\'; + return FALSE; } - *pt='\\'; + *pt = '\\'; } } - return (CreateDirectory(path,NULL) || GetLastError()==ERROR_ALREADY_EXISTS); + return (CreateDirectory(path, NULL) + || GetLastError() == ERROR_ALREADY_EXISTS); } -BOOL RemoveWholeDirectory(char *path) { +BOOL RemoveWholeDirectory(char *path) +{ char *pt; BOOL retval; - if (!path || !RemoveDirectory(path)) return FALSE; - - for (pt=&path[strlen(path)-2];pt>path;pt--) { - if (*pt=='\\') { - *pt='\0'; - retval=RemoveDirectory(path); - *pt='\\'; - if (!retval) break; + + if (!path || !RemoveDirectory(path)) + return FALSE; + + for (pt = &path[strlen(path) - 2]; pt > path; pt--) { + if (*pt == '\\') { + *pt = '\0'; + retval = RemoveDirectory(path); + *pt = '\\'; + if (!retval) + break; } } return TRUE; } -void RemoveService(NTService *service) { - SC_HANDLE scManager,scService; +void RemoveService(NTService *service) +{ + SC_HANDLE scManager, scService; SERVICE_STATUS status; - if (!service) return; + if (!service) + return; - scManager = OpenSCManager(NULL,NULL,GENERIC_READ); + scManager = OpenSCManager(NULL, NULL, GENERIC_READ); if (!scManager) { - DisplayError("Cannot connect to service manager",TRUE,FALSE); + DisplayError("Cannot connect to service manager", TRUE, FALSE); return; } - scService = OpenService(scManager,service->name,DELETE|SERVICE_STOP); + scService = OpenService(scManager, service->name, DELETE | SERVICE_STOP); if (!scService) { - DisplayError("Cannot open service",TRUE,FALSE); + DisplayError("Cannot open service", TRUE, FALSE); } else { - if (!ControlService(scService,SERVICE_CONTROL_STOP,&status) && - GetLastError()!=ERROR_SERVICE_NOT_ACTIVE) { - DisplayError("Cannot stop service",TRUE,FALSE); + if (!ControlService(scService, SERVICE_CONTROL_STOP, &status) && + GetLastError() != ERROR_SERVICE_NOT_ACTIVE) { + DisplayError("Cannot stop service", TRUE, FALSE); } if (!DeleteService(scService)) { - DisplayError("Cannot delete service",TRUE,FALSE); + DisplayError("Cannot delete service", TRUE, FALSE); } CloseServiceHandle(scService); } t@@ -527,67 +601,83 @@ void RemoveService(NTService *service) { CloseServiceHandle(scManager); } -char *read_line0(HANDLE hin) { +char *read_line0(HANDLE hin) +{ char *buf; - int bufsize=32,strind=0; + int bufsize = 32, strind = 0; DWORD bytes_read; + buf = bmalloc(bufsize); while (1) { - if (!ReadFile(hin,&buf[strind],1,&bytes_read,NULL)) { - printf("Read error\n"); break; + if (!ReadFile(hin, &buf[strind], 1, &bytes_read, NULL)) { + printf("Read error\n"); + break; } - if (bytes_read==0) { buf[strind]='\0'; break; } - else if (buf[strind]=='\0') break; + if (bytes_read == 0) { + buf[strind] = '\0'; + break; + } else if (buf[strind] == '\0') + break; else { strind++; - if (strind>=bufsize) { - bufsize*=2; - buf = brealloc(buf,bufsize); + if (strind >= bufsize) { + bufsize *= 2; + buf = brealloc(buf, bufsize); } } } - if (strind==0) { bfree(buf); return NULL; } - else return buf; + if (strind == 0) { + bfree(buf); + return NULL; + } else + return buf; } -InstLink *ReadLinkList(HANDLE fin) { - InstLink *first=NULL,*listpt=NULL,*newpt; - char *linkfile,*origfile,*args; +InstLink *ReadLinkList(HANDLE fin) +{ + InstLink *first = NULL, *listpt = NULL, *newpt; + char *linkfile, *origfile, *args; while (1) { - linkfile=read_line0(fin); - if (!linkfile) break; - origfile=read_line0(fin); - args=read_line0(fin); - if (!origfile) DisplayError("Corrupt install.log",FALSE,TRUE); + linkfile = read_line0(fin); + if (!linkfile) + break; + origfile = read_line0(fin); + args = read_line0(fin); + if (!origfile) + DisplayError("Corrupt install.log", FALSE, TRUE); newpt = bmalloc(sizeof(InstLink)); - if (listpt) listpt->next = newpt; - else first = newpt; + if (listpt) + listpt->next = newpt; + else + first = newpt; listpt = newpt; - newpt->next=NULL; - newpt->linkfile=linkfile; - newpt->origfile=origfile; - newpt->args=args; + newpt->next = NULL; + newpt->linkfile = linkfile; + newpt->origfile = origfile; + newpt->args = args; } return first; } -InstFlags ReadInstFlags(HANDLE fin) { +InstFlags ReadInstFlags(HANDLE fin) +{ DWORD bytes_read; char buf[3]; buf[0] = 0; - if (!ReadFile(fin,buf,1,&bytes_read,NULL)) { + if (!ReadFile(fin, buf, 1, &bytes_read, NULL)) { printf("Read error\n"); } return (InstFlags)buf[0]; } -NTService *ReadServiceDetails(HANDLE fin) { - NTService *service=NULL; - char *name,*disp,*desc,*exe; +NTService *ReadServiceDetails(HANDLE fin) +{ + NTService *service = NULL; + char *name, *disp, *desc, *exe; name = read_line0(fin); if (name) { t@@ -595,75 +685,82 @@ NTService *ReadServiceDetails(HANDLE fin) { desc = read_line0(fin); exe = read_line0(fin); if (!disp || !desc || !exe) { - DisplayError("Corrupt install.log",FALSE,TRUE); + DisplayError("Corrupt install.log", FALSE, TRUE); } else { - AddServiceDetails(name,disp,desc,exe,&service); + AddServiceDetails(name, disp, desc, exe, &service); } } return service; } -InstFiles *ReadFileList(HANDLE fin) { - InstFiles *first=NULL,*listpt=NULL,*newpt; - char *filename,*filesize; +InstFiles *ReadFileList(HANDLE fin) +{ + InstFiles *first = NULL, *listpt = NULL, *newpt; + char *filename, *filesize; while (1) { - filename=read_line0(fin); - if (!filename) break; - filesize=read_line0(fin); - if (!filesize) DisplayError("Corrupt install.log",FALSE,TRUE); + filename = read_line0(fin); + if (!filename) + break; + filesize = read_line0(fin); + if (!filesize) + DisplayError("Corrupt install.log", FALSE, TRUE); newpt = bmalloc(sizeof(InstFiles)); - if (listpt) listpt->next = newpt; - else first = newpt; + if (listpt) + listpt->next = newpt; + else + first = newpt; listpt = newpt; - newpt->next=NULL; - newpt->filename=filename; - newpt->filesize=atol(filesize); + newpt->next = NULL; + newpt->filename = filename; + newpt->filesize = atol(filesize); bfree(filesize); } return first; } -char *GetInstallDir(char *product) { +char *GetInstallDir(char *product) +{ HKEY key; bstr *str; - DWORD keytype,keylen; + DWORD keytype, keylen; char *installdir; - str=bstr_new(); - bstr_assign(str,UninstallKey); - bstr_appendpath(str,product); - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,str->text,0, - KEY_ALL_ACCESS,&key)!=ERROR_SUCCESS) { - DisplayError("Could not open registry",FALSE,TRUE); + str = bstr_new(); + bstr_assign(str, UninstallKey); + bstr_appendpath(str, product); + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, str->text, 0, + KEY_ALL_ACCESS, &key) != ERROR_SUCCESS) { + DisplayError("Could not open registry", FALSE, TRUE); } - if (RegQueryValueEx(key,"InstallDirectory",NULL, - &keytype,NULL,&keylen)!=ERROR_SUCCESS || - keytype!=REG_SZ) { - DisplayError("Could not query registry key",FALSE,TRUE); + if (RegQueryValueEx(key, "InstallDirectory", NULL, + &keytype, NULL, &keylen) != ERROR_SUCCESS || + keytype != REG_SZ) { + DisplayError("Could not query registry key", FALSE, TRUE); } installdir = bmalloc(keylen); - if (RegQueryValueEx(key,"InstallDirectory",NULL, - &keytype,installdir,&keylen)!=ERROR_SUCCESS) { - DisplayError("Could not get registry key value",FALSE,TRUE); + if (RegQueryValueEx(key, "InstallDirectory", NULL, + &keytype, installdir, &keylen) != ERROR_SUCCESS) { + DisplayError("Could not get registry key value", FALSE, TRUE); } - bstr_free(str,TRUE); + bstr_free(str, TRUE); return installdir; } -InstData *ReadOldInstData(HANDLE fin,char *product,char *installdir) { +InstData *ReadOldInstData(HANDLE fin, char *product, char *installdir) +{ InstData *idata; - idata=bmalloc(sizeof(InstData)); + idata = bmalloc(sizeof(InstData)); - idata->product=product; - idata->installdir=installdir; - idata->startmenudir=read_line0(fin); + idata->product = product; + idata->installdir = installdir; + idata->startmenudir = read_line0(fin); idata->instfiles = ReadFileList(fin); idata->extrafiles = ReadFileList(fin); t@@ -679,80 +776,85 @@ InstData *ReadOldInstData(HANDLE fin,char *product,char *installdir) { return idata; } -void DeleteFileList(InstFiles *listpt,HWND hwnd,InstFiles *keepfiles) { +void DeleteFileList(InstFiles *listpt, HWND hwnd, InstFiles *keepfiles) +{ bstr *str; char *sep; InstFiles *keeppt; - str=bstr_new(); - for (;listpt;listpt=listpt->next) { + str = bstr_new(); + for (; listpt; listpt = listpt->next) { keeppt = keepfiles; - while (keeppt && strcmp(keeppt->filename,listpt->filename)!=0) { + while (keeppt && strcmp(keeppt->filename, listpt->filename) != 0) { keeppt = keeppt->next; } if (keeppt) { - keeppt->filesize=1; /* Mark that this file is already installed */ + keeppt->filesize = 1; /* Mark that this file is already + * installed */ } else { - bstr_assign(str,"Deleting file: "); - bstr_append(str,listpt->filename); - SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)str->text); + bstr_assign(str, "Deleting file: "); + bstr_append(str, listpt->filename); + SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)str->text); DeleteFile(listpt->filename); - sep = strrchr(listpt->filename,'\\'); + sep = strrchr(listpt->filename, '\\'); if (sep) { *sep = '\0'; RemoveWholeDirectory(listpt->filename); - *sep = '\\'; + *sep = '\\'; } } } - bstr_free(str,TRUE); + bstr_free(str, TRUE); } -void DeleteLinkList(char *dir,InstLink *listpt,HWND hwnd) { +void DeleteLinkList(char *dir, InstLink *listpt, HWND hwnd) +{ bstr *str; - str=bstr_new(); + + str = bstr_new(); if (SetCurrentDirectory(dir)) { - for (;listpt;listpt=listpt->next) { - bstr_assign(str,"Deleting shortcut: "); - bstr_append(str,listpt->linkfile); - SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)str->text); + for (; listpt; listpt = listpt->next) { + bstr_assign(str, "Deleting shortcut: "); + bstr_append(str, listpt->linkfile); + SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)str->text); DeleteFile(listpt->linkfile); } } else { - bstr_assign(str,"Could not find shortcut directory "); - bstr_append(str,dir); - DisplayError(str->text,TRUE,FALSE); + bstr_assign(str, "Could not find shortcut directory "); + bstr_append(str, dir); + DisplayError(str->text, TRUE, FALSE); } - bstr_free(str,TRUE); + bstr_free(str, TRUE); } -void RemoveUninstall(char *startmenu,char *product,BOOL delexe) { - bstr *inipath,*uninstpath,*uninstlink; +void RemoveUninstall(char *startmenu, char *product, BOOL delexe) +{ + bstr *inipath, *uninstpath, *uninstlink; - inipath=bstr_new(); - uninstpath=bstr_new(); - uninstlink=bstr_new(); + inipath = bstr_new(); + uninstpath = bstr_new(); + uninstlink = bstr_new(); - bstr_assign(uninstlink,startmenu); - bstr_appendpath(uninstlink,"Uninstall "); - bstr_append(uninstlink,product); - bstr_append(uninstlink,".LNK"); + bstr_assign(uninstlink, startmenu); + bstr_appendpath(uninstlink, "Uninstall "); + bstr_append(uninstlink, product); + bstr_append(uninstlink, ".LNK"); DeleteFile(uninstlink->text); if (delexe) { bstr_assign_windir(inipath); - bstr_assign(uninstpath,inipath->text); + bstr_assign(uninstpath, inipath->text); - bstr_appendpath(inipath,"wininit.ini"); - bstr_appendpath(uninstpath,UninstallEXE); + bstr_appendpath(inipath, "wininit.ini"); + bstr_appendpath(uninstpath, UninstallEXE); - if (!WritePrivateProfileString("Renane","NUL",uninstpath->text, + if (!WritePrivateProfileString("Renane", "NUL", uninstpath->text, inipath->text)) { - DisplayError("Cannot write to wininit.ini: ",TRUE,FALSE); + DisplayError("Cannot write to wininit.ini: ", TRUE, FALSE); } } - bstr_free(uninstlink,TRUE); - bstr_free(uninstpath,TRUE); - bstr_free(inipath,TRUE); + bstr_free(uninstlink, TRUE); + bstr_free(uninstpath, TRUE); + bstr_free(inipath, TRUE); } (DIR) diff --git a/win32/util.h b/win32/util.h t@@ -1,29 +1,32 @@ -/* util.h Shared functions for Win32 installer programs */ -/* Copyright (C) 2001 Ben Webb */ -/* Email: ben@bellatrix.pcl.ox.ac.uk */ -/* WWW: http://dopewars.sourceforge.net/ */ - -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ - -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ - -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, */ -/* MA 02111-1307, USA. */ +/************************************************************************ + * util.h Shared functions for Win32 installer programs * + * Copyright (C) 2001-2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ #include <windows.h> typedef struct _bstr { char *text; - unsigned length; /* Length of current text, NOT including terminating null */ - unsigned bufsiz; /* Size of the allocated memory buffer */ + unsigned length; /* Length of current text, NOT including + * terminating null */ + unsigned bufsiz; /* Size of the allocated memory buffer */ } bstr; typedef struct _InstFiles { t@@ -52,7 +55,7 @@ typedef enum { typedef struct _InstData { char *product; - char *installdir,*startmenudir; + char *installdir, *startmenudir; DWORD totalsize; NTService *service; InstFiles *instfiles; t@@ -68,47 +71,47 @@ extern const char *UninstallEXE; void *bmalloc(UINT numbytes); void bfree(void *pt); -void *brealloc(void *pt,UINT numbytes); +void *brealloc(void *pt, UINT numbytes); char *bstrdup(char *str); bstr *bstr_new(void); -void bstr_free(bstr *str,BOOL free_text); -void bstr_expandby(bstr *str,unsigned extralength); -void bstr_setlength(bstr *str,unsigned length); -void bstr_assign(bstr *str,const char *text); -void bstr_append(bstr *str,const char *text); -void bstr_appendpath(bstr *str,const char *text); -void bstr_append_c(bstr *str,const char ch); -void bstr_append_long(bstr *str,const long val); +void bstr_free(bstr *str, BOOL free_text); +void bstr_expandby(bstr *str, unsigned extralength); +void bstr_setlength(bstr *str, unsigned length); +void bstr_assign(bstr *str, const char *text); +void bstr_append(bstr *str, const char *text); +void bstr_appendpath(bstr *str, const char *text); +void bstr_append_c(bstr *str, const char ch); +void bstr_append_long(bstr *str, const long val); void bstr_append_windir(bstr *str); void bstr_append_curdir(bstr *str); void bstr_assign_windir(bstr *str); void bstr_assign_curdir(bstr *str); -void DisplayError(const char *errtext,BOOL addsyserr,BOOL fatal); -void AddInstFiles(char *filename,DWORD filesize,InstFiles **lastpt, +void DisplayError(const char *errtext, BOOL addsyserr, BOOL fatal); +void AddInstFiles(char *filename, DWORD filesize, InstFiles **lastpt, InstFiles **firstpt); -void AddInstLink(char *linkfile,char *origfile,char *args,InstLink **lastpt, - InstLink **firstpt); -void FreeLinkList(InstLink *linklist,BOOL freepts); -void FreeFileList(InstFiles *filelist,BOOL freepts); -void FreeInstData(InstData *idata,BOOL freepts); -void AddServiceDetails(char *servicename,char *servicedisp, - char *servicedesc,char *serviceexe, +void AddInstLink(char *linkfile, char *origfile, char *args, + InstLink **lastpt, InstLink **firstpt); +void FreeLinkList(InstLink *linklist, BOOL freepts); +void FreeFileList(InstFiles *filelist, BOOL freepts); +void FreeInstData(InstData *idata, BOOL freepts); +void AddServiceDetails(char *servicename, char *servicedisp, + char *servicedesc, char *serviceexe, NTService **service); -void FreeServiceDetails(NTService *service,BOOL freepts); -void WriteServiceDetails(HANDLE fout,NTService *service); +void FreeServiceDetails(NTService *service, BOOL freepts); +void WriteServiceDetails(HANDLE fout, NTService *service); void WriteInstFlags(HANDLE fout, InstFlags flags); -void WriteLinkList(HANDLE fout,InstLink *listpt); -void WriteFileList(HANDLE fout,InstFiles *listpt); +void WriteLinkList(HANDLE fout, InstLink *listpt); +void WriteFileList(HANDLE fout, InstFiles *listpt); char *GetStartMenuTopDir(BOOL AllUsers); char *GetStartMenuDir(BOOL AllUsers, InstData *idata); char *GetDesktopDir(void); BOOL CreateWholeDirectory(char *path); BOOL RemoveWholeDirectory(char *path); -void DeleteLinkList(char *dir,InstLink *listpt,HWND hwnd); -void DeleteFileList(InstFiles *listpt,HWND hwnd,InstFiles *keepfiles); -InstData *ReadOldInstData(HANDLE fin,char *product,char *installdir); +void DeleteLinkList(char *dir, InstLink *listpt, HWND hwnd); +void DeleteFileList(InstFiles *listpt, HWND hwnd, InstFiles *keepfiles); +InstData *ReadOldInstData(HANDLE fin, char *product, char *installdir); char *GetInstallDir(char *product); void RemoveService(NTService *service); -void RemoveUninstall(char *startmenu,char *product,BOOL delexe); +void RemoveUninstall(char *startmenu, char *product, BOOL delexe);