Lots of changes to make gtk version better test with relay: make

possible to start without specifying comms params, to switch roles
and/or number of players when starting new game; clean up dialogs,
esp. use notebook widget to have tab switch between comms types.
This commit is contained in:
ehouse 2009-02-28 18:52:44 +00:00
parent c2b34e459d
commit 3f01c9129e
6 changed files with 272 additions and 150 deletions

View file

@ -30,27 +30,78 @@ typedef struct _GtkConnsState {
GtkWidget* cookie;
GtkWidget* hostName;
GtkWidget* port;
GtkWidget* bthost;
GtkWidget* notebook;
CommsConnType pageTypes[COMMS_CONN_NTYPES];
gboolean cancelled;
gboolean readOnly;
} GtkConnsState;
static gint
conTypeToPageNum( const GtkConnsState* state, CommsConnType conType )
{
gint pageNum = 0; /* default */
int ii;
for ( ii = 0; ; ++ii ) {
CommsConnType thisType = state->pageTypes[ii];
if ( thisType == COMMS_CONN_NONE || thisType == conType ) {
pageNum = ii;
break;
}
XP_ASSERT( ii < VSIZE(state->pageTypes) );
}
return pageNum;
}
static CommsConnType
pageNoToConnType( const GtkConnsState* state, gint page )
{
XP_ASSERT( page < VSIZE(state->pageTypes) );
XP_ASSERT( state->pageTypes[page] != COMMS_CONN_NONE );
return state->pageTypes[page];
}
static void
handle_ok( GtkWidget* XP_UNUSED(widget), gpointer closure )
{
GtkConnsState* state = (GtkConnsState*)closure;
const gchar* txt;
if ( !state->readOnly ) {
const gchar* txt;
gint page = gtk_notebook_get_current_page
( GTK_NOTEBOOK(state->notebook) );
CommsConnType conType = pageNoToConnType( state, page );
txt = gtk_entry_get_text( GTK_ENTRY(state->cookie) );
XP_STRNCPY( state->addr->u.ip_relay.cookie, txt,
sizeof(state->addr->u.ip_relay.cookie) );
txt = gtk_entry_get_text( GTK_ENTRY(state->hostName) );
XP_STRNCPY( state->addr->u.ip_relay.hostName, txt,
sizeof(state->addr->u.ip_relay.hostName) );
switch ( conType ) {
case COMMS_CONN_IP_DIRECT:
#ifdef XWFEATURE_RELAY
case COMMS_CONN_RELAY:
txt = gtk_entry_get_text( GTK_ENTRY(state->cookie) );
XP_STRNCPY( state->addr->u.ip_relay.cookie, txt,
sizeof(state->addr->u.ip_relay.cookie) );
txt = gtk_entry_get_text( GTK_ENTRY(state->hostName) );
XP_STRNCPY( state->addr->u.ip_relay.hostName, txt,
sizeof(state->addr->u.ip_relay.hostName) );
txt = gtk_entry_get_text( GTK_ENTRY(state->port) );
state->addr->u.ip_relay.port = atoi( txt );
txt = gtk_entry_get_text( GTK_ENTRY(state->port) );
state->addr->u.ip_relay.port = atoi( txt );
break;
#endif
#ifdef XWFEATURE_BLUETOOTH
case COMMS_CONN_BT:
break;
#endif
case COMMS_CONN_SMS:
break;
default:
XP_ASSERT( 0 ); /* keep compiler happy */
break;
}
state->addr->conType = conType;
}
state->cancelled = XP_FALSE;
gtk_main_quit();
} /* handle_ok */
@ -70,13 +121,57 @@ handle_cancel( GtkWidget* XP_UNUSED(widget), void* closure )
* Cancel OK
*/
static GtkWidget*
makeRelayPage( GtkConnsState* state )
{
GtkWidget* vbox = gtk_vbox_new( FALSE, 0 );
GtkWidget* hbox = makeLabeledField( "Cookie", &state->cookie );
gtk_entry_set_text( GTK_ENTRY(state->cookie),
state->addr->u.ip_relay.cookie );
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
gtk_widget_set_sensitive( state->cookie, !state->readOnly );
hbox = makeLabeledField( "Relay address", &state->hostName );
gtk_entry_set_text( GTK_ENTRY(state->hostName),
state->addr->u.ip_relay.hostName );
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
gtk_widget_set_sensitive( state->hostName, !state->readOnly );
hbox = makeLabeledField( "Relay port", &state->port );
char buf[16];
snprintf( buf, sizeof(buf), "%d", state->addr->u.ip_relay.port );
gtk_entry_set_text( GTK_ENTRY(state->port), buf );
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
gtk_widget_set_sensitive( state->port, !state->readOnly );
gtk_widget_show( vbox );
return vbox;
} /* makeRelayPage */
static GtkWidget*
makeBTPage( GtkConnsState* state )
{
GtkWidget* vbox = gtk_vbox_new( FALSE, 0 );
GtkWidget* hbox = makeLabeledField( "Host device", &state->bthost );
gtk_entry_set_text( GTK_ENTRY(state->bthost), state->addr->u.bt.hostName );
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
gtk_widget_set_sensitive( state->bthost, !state->readOnly );
gtk_widget_show( vbox );
return vbox;
} /* makeBTPage */
gboolean
gtkConnsDlg( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool readOnly )
{
LOG_FUNC();
GtkConnsState state;
XP_MEMSET( &state, 0, sizeof(state) );
gint loc;
XP_U16 nTypes = 0;
state.readOnly = readOnly;
state.globals = globals;
@ -86,44 +181,54 @@ gtkConnsDlg( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool readOnly )
GtkWidget* vbox;
GtkWidget* hbox;
vbox = gtk_vbox_new( FALSE, 0 );
state.notebook = gtk_notebook_new();
#ifdef XWFEATURE_RELAY
state.pageTypes[nTypes++] = COMMS_CONN_RELAY;
loc = gtk_notebook_append_page( GTK_NOTEBOOK(state.notebook),
makeRelayPage(&state),
gtk_label_new( "Relay" ) );
#endif
#ifdef XWFEATURE_BLUETOOTH
state.pageTypes[nTypes++] = COMMS_CONN_BT;
loc = gtk_notebook_append_page( GTK_NOTEBOOK(state.notebook),
makeBTPage(&state),
gtk_label_new( "Bluetooth" ) );
#endif
vbox = gtk_vbox_new( FALSE, 0 );
gtk_box_pack_start( GTK_BOX(vbox), state.notebook, FALSE, TRUE, 0 );
state.pageTypes[nTypes++] = COMMS_CONN_NONE; /* mark end of list */
gint pageNo = conTypeToPageNum( &state, addr->conType );
gtk_notebook_set_current_page( GTK_NOTEBOOK(state.notebook), pageNo );
gtk_widget_show( state.notebook );
hbox = makeLabeledField( "Cookie", &state.cookie );
gtk_entry_set_text( GTK_ENTRY(state.cookie), state.addr->u.ip_relay.cookie );
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
hbox = makeLabeledField( "Relay address", &state.hostName );
gtk_entry_set_text( GTK_ENTRY(state.hostName),
state.addr->u.ip_relay.hostName );
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
hbox = makeLabeledField( "Relay port", &state.port );
char buf[16];
snprintf( buf, sizeof(buf), "%d", state.addr->u.ip_relay.port );
gtk_entry_set_text( GTK_ENTRY(state.port), buf );
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
/* buttons at the bottom */
hbox = gtk_hbox_new( FALSE, 0 );
gtk_box_pack_start( GTK_BOX(hbox),
makeButton( "Ok", GTK_SIGNAL_FUNC(handle_ok) , &state ),
FALSE, TRUE, 0 );
gtk_box_pack_start( GTK_BOX(hbox),
makeButton( "Cancel", GTK_SIGNAL_FUNC(handle_cancel),
&state ),
FALSE, TRUE, 0 );
if ( !readOnly ) {
gtk_box_pack_start( GTK_BOX(hbox),
makeButton( "Cancel",
GTK_SIGNAL_FUNC(handle_cancel),
&state ),
FALSE, TRUE, 0 );
}
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
gtk_widget_show( vbox );
dialog = gtk_dialog_new();
gtk_window_set_modal( GTK_WINDOW( dialog ), TRUE );
gtk_container_add( GTK_CONTAINER( GTK_DIALOG(dialog)->action_area), vbox );
gtk_widget_show_all( dialog );
gtk_main();
gtk_widget_destroy( dialog );
return !state.cancelled;
}
} /* gtkConnsDlg */
#endif

View file

@ -66,6 +66,7 @@ static void sendOnClose( XWStreamCtxt* stream, void* closure );
#endif
static void setCtrlsForTray( GtkAppGlobals* globals );
static void printFinalScores( GtkAppGlobals* globals );
static void new_game( GtkWidget* widget, GtkAppGlobals* globals );
#define GTK_TRAY_HT_ROWS 3
@ -386,15 +387,17 @@ createOrLoadObjects( GtkAppGlobals* globals )
params->gi.allowHintRect = params->allowHintRect;
#endif
if ( params->needsNewGame ) {
new_game( NULL, globals );
#ifndef XWFEATURE_STANDALONE_ONLY
if ( !isServer ) {
} else if ( !isServer ) {
XWStreamCtxt* stream =
mem_stream_make( MEMPOOL params->vtMgr, globals, CHANNEL_NONE,
sendOnClose );
server_initClientConnection( globals->cGlobals.game.server,
stream );
}
#endif
}
}
#ifndef XWFEATURE_STANDALONE_ONLY
@ -629,23 +632,31 @@ final_scores( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
static void
new_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
{
gboolean confirmed;
CommsAddrRec addr;
confirmed = newGameDialog( globals, XP_TRUE );
if ( confirmed ) {
if ( !!globals->cGlobals.game.comms ) {
comms_getAddr( globals->cGlobals.game.comms, &addr );
} else {
comms_getInitialAddr( &addr );
}
if ( newGameDialog( globals, &addr, XP_TRUE ) ) {
CurGameInfo* gi = &globals->cGlobals.params->gi;
#ifndef XWFEATURE_STANDALONE_ONLY
XP_Bool isClient = gi->serverRole == SERVER_ISCLIENT;
#endif
XP_U32 gameID = util_getCurSeconds( globals->cGlobals.params->util );
XP_STATUSF( "grabbed gameID: %ld\n", gameID );
game_reset( MEMPOOL &globals->cGlobals.game, gi,
globals->cGlobals.params->util,
gameID, &globals->cp, LINUX_SEND,
0, &globals->cp, LINUX_SEND,
IF_CH(linux_reset) globals );
#ifndef XWFEATURE_STANDALONE_ONLY
if ( !!globals->cGlobals.game.comms ) {
comms_setAddr( globals->cGlobals.game.comms, &addr );
} else if ( gi->serverRole != SERVER_STANDALONE ) {
XP_ASSERT(0);
}
if ( isClient ) {
XWStreamCtxt* stream =
mem_stream_make( MEMPOOL
@ -667,9 +678,12 @@ new_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
static void
game_info( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
{
CommsAddrRec addr;
comms_getAddr( globals->cGlobals.game.comms, &addr );
/* Anything to do if OK is clicked? Changed names etc. already saved. Try
server_do in case one's become a robot. */
if ( newGameDialog( globals, XP_FALSE ) ) {
if ( newGameDialog( globals, &addr, XP_FALSE ) ) {
if ( server_do( globals->cGlobals.game.server ) ) {
board_draw( globals->cGlobals.game.board );
}
@ -1445,7 +1459,7 @@ makeShowButtonFromBitmap( void* closure, const gchar* filename,
GtkWidget* button;
if ( file_exists( filename ) ) {
widget = gtk_image_new_from_file (filename);
widget = gtk_image_new_from_file( filename );
} else {
widget = gtk_label_new( alt );
}
@ -1616,7 +1630,7 @@ newConnectionInput( GIOChannel *source,
CommsAddrRec addr;
#endif
switch ( globals->cGlobals.params->conType ) {
switch ( comms_getConType( globals->cGlobals.game.comms ) ) {
#ifdef XWFEATURE_RELAY
case COMMS_CONN_RELAY:
XP_ASSERT( globals->cGlobals.socket == sock );

View file

@ -45,7 +45,7 @@ typedef struct GtkNewGameState {
#ifndef XWFEATURE_STANDALONE_ONLY
GtkWidget* remoteChecks[MAX_NUM_PLAYERS];
GtkWidget* roleCombo;
GtkWidget* radios[3];
#endif
GtkWidget* robotChecks[MAX_NUM_PLAYERS];
GtkWidget* nameLabels[MAX_NUM_PLAYERS];
@ -69,26 +69,26 @@ nplayers_menu_changed( GtkComboBox* combo, GtkNewGameState* state )
#ifndef XWFEATURE_STANDALONE_ONLY
static void
role_combo_changed( GtkComboBox* combo, gpointer gp )
radio_clicked( GtkRadioButton* radio, gpointer gp )
{
GtkNewGameState* state = (GtkNewGameState*)gp;
NGValue value;
gint index = gtk_combo_box_get_active( GTK_COMBO_BOX(combo) );
gint index = -1, ii;
if ( index >= 0 ) {
DeviceRole role = (DeviceRole)index;
value.ng_role = role;
if ( state->isNewGame ) {
newg_attrChanged( state->newGameCtxt, NG_ATTR_ROLE, value );
} else if ( state->loaded ) {
/* put it back */
gtk_combo_box_set_active( GTK_COMBO_BOX(combo), state->role );
for ( ii = 0; ii < VSIZE(state->radios); ++ii ) {
if (GTK_RADIO_BUTTON(state->radios[ii]) == radio ) {
index = ii;
break;
}
}
if ( index >= 0 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio)) ) {
DeviceRole role = (DeviceRole)index;
NGValue value = { .ng_role = role };
newg_attrChanged( state->newGameCtxt, NG_ATTR_ROLE, value );
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_RELAY
if ( state->loaded && SERVER_STANDALONE != role ) {
gtkConnsDlg( state->globals, &state->addr, !state->isNewGame );
gtkConnsDlg( state->globals, &state->addr, FALSE );
}
#endif
}
@ -176,13 +176,12 @@ makeNewGameDialog( GtkNewGameState* state )
GtkWidget* vbox;
GtkWidget* hbox;
#ifndef XWFEATURE_STANDALONE_ONLY
GtkWidget* roleCombo;
char* roles[] = { "Standalone", "Host", "Guest" };
#endif
GtkWidget* nPlayersCombo;
GtkWidget* boardSizeCombo;
CurGameInfo* gi;
short i;
short ii;
dialog = gtk_dialog_new();
gtk_window_set_modal( GTK_WINDOW( dialog ), TRUE );
@ -193,16 +192,24 @@ makeNewGameDialog( GtkNewGameState* state )
hbox = gtk_hbox_new( FALSE, 0 );
gtk_box_pack_start( GTK_BOX(hbox), gtk_label_new("Role:"),
FALSE, TRUE, 0 );
roleCombo = gtk_combo_box_new_text();
state->roleCombo = roleCombo;
for ( i = 0; i < VSIZE(roles); ++i ) {
gtk_combo_box_append_text( GTK_COMBO_BOX(roleCombo), roles[i] );
GtkWidget* radio = NULL;
for ( ii = 0; ii < VSIZE(roles); ++ii ) {
if ( NULL == radio ) {
radio = gtk_radio_button_new_with_label( NULL, roles[ii] );
} else {
radio = gtk_radio_button_new_with_label_from_widget(
GTK_RADIO_BUTTON(radio), roles[ii] );
}
state->radios[ii] = radio;
g_signal_connect( GTK_OBJECT(radio), "clicked",
G_CALLBACK(radio_clicked), state );
gtk_box_pack_start( GTK_BOX(hbox), radio, FALSE, TRUE, 0 );
if ( !state->isNewGame && ii != state->role ) {
gtk_widget_set_sensitive( radio, FALSE );
}
}
g_signal_connect( GTK_OBJECT(roleCombo), "changed",
G_CALLBACK(role_combo_changed), state );
gtk_box_pack_start( GTK_BOX(hbox), roleCombo, FALSE, TRUE, 0 );
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
#endif
@ -216,8 +223,8 @@ makeNewGameDialog( GtkNewGameState* state )
gi = &state->globals->cGlobals.params->gi;
for ( i = 0; i < MAX_NUM_PLAYERS; ++i ) {
char buf[2] = { i + '1', '\0' };
for ( ii = 0; ii < MAX_NUM_PLAYERS; ++ii ) {
char buf[2] = { ii + '1', '\0' };
gtk_combo_box_append_text( GTK_COMBO_BOX(nPlayersCombo), buf );
}
@ -234,7 +241,7 @@ makeNewGameDialog( GtkNewGameState* state )
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
for ( i = 0; i < MAX_NUM_PLAYERS; ++i ) {
for ( ii = 0; ii < MAX_NUM_PLAYERS; ++ii ) {
GtkWidget* label = gtk_label_new("Name:");
#ifndef XWFEATURE_STANDALONE_ONLY
GtkWidget* remoteCheck = gtk_check_button_new_with_label( "Remote" );
@ -255,29 +262,29 @@ makeNewGameDialog( GtkNewGameState* state )
#ifndef XWFEATURE_STANDALONE_ONLY
gtk_box_pack_start( GTK_BOX(hbox), remoteCheck, FALSE, TRUE, 0 );
gtk_widget_show( remoteCheck );
state->remoteChecks[i] = remoteCheck;
state->remoteChecks[ii] = remoteCheck;
#endif
gtk_box_pack_start( GTK_BOX(hbox), label, FALSE, TRUE, 0 );
gtk_widget_show( label );
state->nameLabels[i] = label;
state->nameLabels[ii] = label;
gtk_box_pack_start( GTK_BOX(hbox), nameField, FALSE, TRUE, 0 );
gtk_widget_show( nameField );
state->nameFields[i] = nameField;
state->nameFields[ii] = nameField;
gtk_box_pack_start( GTK_BOX(hbox), robotCheck, FALSE, TRUE, 0 );
gtk_widget_show( robotCheck );
state->robotChecks[i] = robotCheck;
state->robotChecks[ii] = robotCheck;
label = gtk_label_new("Passwd:");
gtk_box_pack_start( GTK_BOX(hbox), label, FALSE, TRUE, 0 );
gtk_widget_show( label );
state->passwdLabels[i] = label;
state->passwdLabels[ii] = label;
gtk_box_pack_start( GTK_BOX(hbox), passwdField, FALSE, TRUE, 0 );
gtk_widget_show( passwdField );
state->passwdFields[i] = passwdField;
state->passwdFields[ii] = passwdField;
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
gtk_widget_show( hbox );
@ -293,13 +300,13 @@ makeNewGameDialog( GtkNewGameState* state )
gtk_widget_set_sensitive( boardSizeCombo, FALSE );
}
for ( i = 0; i < MAX_SIZE_CHOICES; ++i ) {
for ( ii = 0; ii < MAX_SIZE_CHOICES; ++ii ) {
char buf[10];
XP_U16 siz = MAX_COLS - i;
XP_U16 siz = MAX_COLS - ii;
snprintf( buf, sizeof(buf), "%dx%d", siz, siz );
gtk_combo_box_append_text( GTK_COMBO_BOX(boardSizeCombo), buf );
if ( siz == state->nCols ) {
gtk_combo_box_set_active( GTK_COMBO_BOX(boardSizeCombo), i );
gtk_combo_box_set_active( GTK_COMBO_BOX(boardSizeCombo), ii );
}
}
@ -312,10 +319,11 @@ makeNewGameDialog( GtkNewGameState* state )
gtk_box_pack_start( GTK_BOX(hbox), gtk_label_new("Dictionary: "),
FALSE, TRUE, 0 );
XP_ASSERT( gi->dictName );
gtk_box_pack_start( GTK_BOX(hbox),
gtk_label_new(gi->dictName),
FALSE, TRUE, 0 );
if ( !!gi->dictName ) {
gtk_box_pack_start( GTK_BOX(hbox),
gtk_label_new(gi->dictName),
FALSE, TRUE, 0 );
}
gtk_widget_show( hbox );
@ -326,17 +334,20 @@ makeNewGameDialog( GtkNewGameState* state )
gtk_box_pack_start( GTK_BOX(hbox),
makeButton( "Ok", GTK_SIGNAL_FUNC(handle_ok) , state ),
FALSE, TRUE, 0 );
gtk_box_pack_start( GTK_BOX(hbox),
makeButton( "Revert", GTK_SIGNAL_FUNC(handle_revert),
state ),
FALSE, TRUE, 0 );
gtk_box_pack_start( GTK_BOX(hbox),
makeButton( "Cancel", GTK_SIGNAL_FUNC(handle_cancel),
state ),
FALSE, TRUE, 0 );
if ( state->isNewGame ) {
gtk_box_pack_start( GTK_BOX(hbox),
makeButton( "Revert",
GTK_SIGNAL_FUNC(handle_revert),
state ),
FALSE, TRUE, 0 );
gtk_box_pack_start( GTK_BOX(hbox),
makeButton( "Cancel",
GTK_SIGNAL_FUNC(handle_cancel),
state ),
FALSE, TRUE, 0 );
}
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
gtk_widget_show( vbox );
gtk_container_add( GTK_CONTAINER( GTK_DIALOG(dialog)->action_area), vbox);
@ -384,18 +395,11 @@ gtk_newgame_col_enable( void* closure, XP_U16 player, NewGameColumn col,
GtkWidget* widget = widgetForCol( state, player, col );
GtkWidget* label = labelForCol( state, player, col );
if ( enable == TRI_ENAB_HIDDEN ) {
gtk_widget_hide( widget );
if ( !!label ) {
gtk_widget_hide( label );
}
} else {
gtk_widget_show( widget );
gtk_widget_set_sensitive( widget, enable == TRI_ENAB_ENABLED );
if ( !!label ) {
gtk_widget_show( label );
gtk_widget_set_sensitive( label, enable == TRI_ENAB_ENABLED );
}
gtk_widget_show( widget );
gtk_widget_set_sensitive( widget, enable == TRI_ENAB_ENABLED );
if ( !!label ) {
gtk_widget_show( label );
gtk_widget_set_sensitive( label, enable == TRI_ENAB_ENABLED );
}
} /* gtk_newgame_col_enable */
@ -477,11 +481,10 @@ gtk_newgame_attr_set( void* closure, NewGameAttr attr, NGValue value )
XP_U16 ii = value.ng_u16;
XP_LOGF( "%s: setting menu %d", __func__, ii-1 );
gtk_combo_box_set_active( GTK_COMBO_BOX(state->nPlayersCombo), ii-1 );
state->role = ii - 1;
#ifndef XWFEATURE_STANDALONE_ONLY
} else if ( attr == NG_ATTR_ROLE ) {
gtk_combo_box_set_active( GTK_COMBO_BOX(state->roleCombo),
value.ng_role );
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(state->radios[value.ng_role]), TRUE );
} else if ( attr == NG_ATTR_REMHEADER ) {
/* ignored on GTK: no headers at all */
#endif
@ -491,7 +494,7 @@ gtk_newgame_attr_set( void* closure, NewGameAttr attr, NGValue value )
}
gboolean
newGameDialog( GtkAppGlobals* globals, XP_Bool isNewGame )
newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool isNewGame )
{
GtkNewGameState state;
XP_MEMSET( &state, 0, sizeof(state) );
@ -516,10 +519,9 @@ newGameDialog( GtkAppGlobals* globals, XP_Bool isNewGame )
state.revert = FALSE;
state.loaded = XP_FALSE;
state.nCols = globals->cGlobals.params->gi.boardSize;
state.role = globals->cGlobals.params->gi.serverRole;
if ( !!globals->cGlobals.game.comms ) {
comms_getAddr( globals->cGlobals.game.comms, &state.addr );
}
XP_MEMCPY( &state.addr, addr, sizeof(state.addr) );
dialog = makeNewGameDialog( &state );
@ -543,6 +545,9 @@ newGameDialog( GtkAppGlobals* globals, XP_Bool isNewGame )
newg_destroy( state.newGameCtxt );
if ( !state.cancelled ) {
XP_MEMCPY( addr, &state.addr, sizeof(state.addr) );
}
return !state.cancelled;
} /* newGameDialog */

View file

@ -1,6 +1,7 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/* -*- compile-command: "make MEMDEBUG=TRUE"; -*- */
/*
* Copyright 2000 by Eric House (xwords@eehouse.org). All rights reserved.
* Copyright 2000-2009 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -25,7 +26,8 @@
#include "gtkmain.h"
gboolean newGameDialog( GtkAppGlobals* globals, XP_Bool isNewGame );
gboolean newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr,
XP_Bool isNewGame );
#endif /* _GTKNEWGAME_H_ */
#endif /* PLATFORM_GTK */

View file

@ -304,7 +304,7 @@ linShiftFocus( CommonGlobals* cGlobals, XP_Key key, const BoardObjectType* order
#ifdef XWFEATURE_RELAY
static int
linux_init_relay_socket( CommonGlobals* cGlobals )
linux_init_relay_socket( CommonGlobals* cGlobals, const CommsAddrRec* addrRec )
{
struct sockaddr_in to_sock;
struct hostent* host;
@ -315,20 +315,17 @@ linux_init_relay_socket( CommonGlobals* cGlobals )
sock = socket( AF_INET, SOCK_STREAM, 0 );
if ( sock == -1 ) {
XP_DEBUGF( "socket returned -1\n" );
return -1;
goto done;
}
to_sock.sin_port = htons(cGlobals->params->
connInfo.relay.defaultSendPort );
XP_STATUSF( "1: sending to port %d",
cGlobals->params->connInfo.relay.defaultSendPort );
host = gethostbyname( cGlobals->params->connInfo.relay.relayName );
to_sock.sin_port = htons( addrRec->u.ip_relay.port );
XP_STATUSF( "1: sending to port %d", addrRec->u.ip_relay.port );
host = gethostbyname( addrRec->u.ip_relay.hostName );
if ( NULL == host ) {
XP_WARNF( "gethostbyname returned -1\n" );
return -1;
} else {
XP_WARNF( "gethostbyname for %s worked",
cGlobals->defaultServerName );
XP_WARNF( "gethostbyname(%s) returned -1",
addrRec->u.ip_relay.hostName );
sock = -1;
goto done;
}
memcpy( &(to_sock.sin_addr.s_addr), host->h_addr_list[0],
sizeof(struct in_addr));
@ -341,23 +338,24 @@ linux_init_relay_socket( CommonGlobals* cGlobals )
} else {
close( sock );
sock = -1;
XP_STATUSF( "%s: connect failed: %s (%d)", __func__, strerror(errno), errno );
XP_STATUSF( "%s: connect failed: %s (%d)", __func__,
strerror(errno), errno );
}
}
done:
return sock;
} /* linux_init_relay_socket */
static XP_S16
linux_tcp_send( const XP_U8* buf, XP_U16 buflen,
CommonGlobals* globals )
CommonGlobals* globals, const CommsAddrRec* addrRec )
{
XP_S16 result = 0;
int socket = globals->socket;
if ( socket == -1 ) {
XP_STATUSF( "%s: socket uninitialized", __func__ );
socket = linux_init_relay_socket( globals );
socket = linux_init_relay_socket( globals, addrRec );
if ( socket != -1 ) {
assert( globals->socket == socket );
(*globals->socketChanged)( globals->socketChangedClosure,
@ -444,7 +442,7 @@ linux_send( const XP_U8* buf, XP_U16 buflen,
if ( 0 ) {
#ifdef XWFEATURE_RELAY
} else if ( conType == COMMS_CONN_RELAY ) {
nSent = linux_tcp_send( buf, buflen, globals );
nSent = linux_tcp_send( buf, buflen, globals, addrRec );
#endif
#if defined XWFEATURE_BLUETOOTH
} else if ( conType == COMMS_CONN_BT ) {
@ -653,7 +651,7 @@ nameToBtAddr( const char* name, bdaddr_t* ba )
int
main( int argc, char** argv )
{
XP_Bool useGTK, useCurses;
XP_Bool useCurses;
int opt;
int totalPlayerCount = 0;
XP_Bool isServer = XP_FALSE;
@ -719,6 +717,7 @@ main( int argc, char** argv )
mainParams.gi.robotSmartness = SMART_ROBOT;
mainParams.noHeartbeat = XP_FALSE;
mainParams.nHidden = 0;
mainParams.needsNewGame = XP_FALSE;
#ifdef XWFEATURE_SEARCHLIMIT
mainParams.allowHintRect = XP_TRUE;
#endif
@ -726,11 +725,9 @@ main( int argc, char** argv )
/* serverName = mainParams.info.clientInfo.serverName = "localhost"; */
#if defined PLATFORM_GTK
useGTK = 1;
useCurses = 0;
useCurses = XP_FALSE;
#else /* curses is the default if GTK isn't available */
useGTK = 0;
useCurses = 1;
useCurses = XP_TRUE;
#endif
@ -892,11 +889,10 @@ main( int argc, char** argv )
break;
#if defined PLATFORM_GTK && defined PLATFORM_NCURSES
case 'g':
useGTK = 1;
useCurses = XP_FALSE;
break;
case 'u':
useCurses = 1;
useGTK = 0;
useCurses = XP_TRUE;
break;
#endif
#if defined PLATFORM_GTK
@ -929,7 +925,7 @@ main( int argc, char** argv )
if ( !mainParams.fileName ) {
if ( (totalPlayerCount < 1) ||
(totalPlayerCount > MAX_NUM_PLAYERS) ) {
usage( argv[0], "Need between 1 and 4 players" );
mainParams.needsNewGame = XP_TRUE;
}
}
@ -943,15 +939,15 @@ main( int argc, char** argv )
MPPARM_NOCOMMA(mainParams.util->mpool) );
XP_WARNF( "no dictionary provided: using English stub dict\n" );
#else
usage( argv[0], "Server needs a dictionary" );
mainParams.needsNewGame = XP_TRUE;
#endif
} else if ( robotCount > 0 ) {
usage( argv[0], "Client can't have robots without a dictionary" );
mainParams.needsNewGame = XP_TRUE;
}
if ( !isServer ) {
if ( mainParams.info.serverInfo.nRemotePlayers > 0 ) {
usage( argv[0], "Client can't have remote players" );
mainParams.needsNewGame = XP_TRUE;
}
}
@ -1037,18 +1033,17 @@ main( int argc, char** argv )
mainParams.serverRole = SERVER_ISCLIENT;
}
if ( mainParams.nLocalPlayers > 0 || !!mainParams.fileName) {
if ( useCurses ) {
/* curses doesn't have newgame dialog */
if ( useCurses && !mainParams.needsNewGame ) {
#if defined PLATFORM_NCURSES
cursesmain( isServer, &mainParams );
cursesmain( isServer, &mainParams );
#endif
} else {
} else if ( !useCurses ) {
#if defined PLATFORM_GTK
gtkmain( &mainParams, argc, argv );
gtkmain( &mainParams, argc, argv );
#endif
}
} else {
/* run server as faceless process? */
usage( argv[0], "rtfm" );
}
linux_util_vt_destroy( mainParams.util );

View file

@ -58,6 +58,7 @@ typedef struct LaunchParams {
XP_Bool undoWhenDone;
XP_Bool verticalScore;
XP_Bool hideValues;
XP_Bool needsNewGame;
// XP_Bool mainParams;
XP_Bool skipWarnings;
XP_Bool showRobotScores;