mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-29 08:34:37 +01:00
make curses app more like the rest
Lots of changes adding a games-list view to the app from which you create new games, open and delete existing ones, etc. There's still plenty that's unimplemented, but it's already more useful for testing and development. Which is the point.
This commit is contained in:
parent
9f0324f8ae
commit
598be04bef
42 changed files with 3437 additions and 2179 deletions
|
@ -643,15 +643,14 @@ CommsCtxt*
|
||||||
comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, XW_UtilCtxt* util,
|
comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, XW_UtilCtxt* util,
|
||||||
const TransportProcs* procs, XP_U16 forceChannel )
|
const TransportProcs* procs, XP_U16 forceChannel )
|
||||||
{
|
{
|
||||||
XP_Bool isServer;
|
XP_U16 nPlayersHere, nPlayersTotal;
|
||||||
XP_U16 nAddrRecs, nPlayersHere, nPlayersTotal;
|
|
||||||
AddressRecord** prevsAddrNext;
|
AddressRecord** prevsAddrNext;
|
||||||
MsgQueueElem** prevsQueueNext;
|
MsgQueueElem** prevsQueueNext;
|
||||||
XP_U16 version = stream_getVersion( stream );
|
XP_U16 version = stream_getVersion( stream );
|
||||||
CommsAddrRec addr;
|
CommsAddrRec addr;
|
||||||
short ii;
|
short ii;
|
||||||
|
|
||||||
isServer = stream_getU8( stream );
|
XP_Bool isServer = stream_getU8( stream );
|
||||||
addrFromStream( &addr, stream );
|
addrFromStream( &addr, stream );
|
||||||
|
|
||||||
if ( version >= STREAM_VERS_DEVIDS
|
if ( version >= STREAM_VERS_DEVIDS
|
||||||
|
@ -692,7 +691,7 @@ comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, XW_UtilCtxt* util,
|
||||||
|
|
||||||
comms->queueLen = stream_getU8( stream );
|
comms->queueLen = stream_getU8( stream );
|
||||||
|
|
||||||
nAddrRecs = stream_getU8( stream );
|
XP_U16 nAddrRecs = stream_getU8( stream );
|
||||||
prevsAddrNext = &comms->recs;
|
prevsAddrNext = &comms->recs;
|
||||||
for ( ii = 0; ii < nAddrRecs; ++ii ) {
|
for ( ii = 0; ii < nAddrRecs; ++ii ) {
|
||||||
AddressRecord* rec = (AddressRecord*)XP_CALLOC( mpool, sizeof(*rec));
|
AddressRecord* rec = (AddressRecord*)XP_CALLOC( mpool, sizeof(*rec));
|
||||||
|
@ -1206,13 +1205,15 @@ makeElemWithID( CommsCtxt* comms, MsgID msgID, AddressRecord* rec,
|
||||||
XP_U16
|
XP_U16
|
||||||
comms_getChannelSeed( CommsCtxt* comms )
|
comms_getChannelSeed( CommsCtxt* comms )
|
||||||
{
|
{
|
||||||
while ( 0 == (comms->channelSeed & ~CHANNEL_MASK) ) {
|
XP_U16 result = !!comms ? comms->channelSeed : 0;
|
||||||
comms->channelSeed = XP_RANDOM() & ~CHANNEL_MASK;
|
while ( !!comms && 0 == (result & ~CHANNEL_MASK) ) {
|
||||||
comms->channelSeed |= comms->forceChannel;
|
result = XP_RANDOM() & ~CHANNEL_MASK;
|
||||||
CNO_FMT( cbuf, comms->channelSeed );
|
result |= comms->forceChannel;
|
||||||
XP_LOGF( "%s: made seed: %s(%d)", __func__, cbuf, comms->channelSeed );
|
CNO_FMT( cbuf, result );
|
||||||
|
XP_LOGF( "%s: made seed: %s(%d)", __func__, cbuf, result );
|
||||||
|
comms->channelSeed = result;
|
||||||
}
|
}
|
||||||
return comms->channelSeed;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send a message using the sequentially next MsgID. Save the message so
|
/* Send a message using the sequentially next MsgID. Save the message so
|
||||||
|
@ -1687,16 +1688,16 @@ got_connect_cmd( CommsCtxt* comms, XWStreamCtxt* stream,
|
||||||
set_relay_state( comms, reconnected ? COMMS_RELAYSTATE_RECONNECTED
|
set_relay_state( comms, reconnected ? COMMS_RELAYSTATE_RECONNECTED
|
||||||
: COMMS_RELAYSTATE_CONNECTED );
|
: COMMS_RELAYSTATE_CONNECTED );
|
||||||
XWHostID myHostID = stream_getU8( stream );
|
XWHostID myHostID = stream_getU8( stream );
|
||||||
XP_LOGF( "%s: changing rr.myHostID from %x to %x", __func__,
|
|
||||||
comms->rr.myHostID, myHostID );
|
|
||||||
if ( comms->rr.myHostID != myHostID ) {
|
if ( comms->rr.myHostID != myHostID ) {
|
||||||
|
XP_LOGF( "%s: changing rr.myHostID from %x to %x", __func__,
|
||||||
|
comms->rr.myHostID, myHostID );
|
||||||
comms->rr.myHostID = myHostID;
|
comms->rr.myHostID = myHostID;
|
||||||
}
|
}
|
||||||
|
|
||||||
isServer = HOST_ID_SERVER == comms->rr.myHostID;
|
isServer = HOST_ID_SERVER == comms->rr.myHostID;
|
||||||
|
|
||||||
if ( isServer != comms->isServer ) {
|
if ( isServer != comms->isServer ) {
|
||||||
XP_LOGF( "%s: becoming a server", __func__ );
|
XP_LOGF( "%s: becoming%s a server", __func__, isServer ? "" : " NOT" );
|
||||||
comms->isServer = isServer;
|
comms->isServer = isServer;
|
||||||
util_setIsServer( comms->util, comms->isServer );
|
util_setIsServer( comms->util, comms->isServer );
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ load( XW_DUtilCtxt* dutil )
|
||||||
if ( 0 < stream_getSize( stream ) ) {
|
if ( 0 < stream_getSize( stream ) ) {
|
||||||
state->devCount = stream_getU16( stream );
|
state->devCount = stream_getU16( stream );
|
||||||
++state->devCount; /* for testing until something's there */
|
++state->devCount; /* for testing until something's there */
|
||||||
XP_LOGF( "%s(): read devCount: %d", __func__, state->devCount );
|
/* XP_LOGF( "%s(): read devCount: %d", __func__, state->devCount ); */
|
||||||
} else {
|
} else {
|
||||||
XP_LOGF( "%s(): empty stream!!", __func__ );
|
XP_LOGF( "%s(): empty stream!!", __func__ );
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,6 +388,13 @@ game_getState( const XWGame* game, GameStateInfo* gsi )
|
||||||
comms_countPendingPackets(game->comms) : 0;
|
comms_countPendingPackets(game->comms) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XP_Bool
|
||||||
|
game_getIsServer( const XWGame* game )
|
||||||
|
{
|
||||||
|
XP_Bool result = comms_getIsServer( game->comms );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
game_dispose( XWGame* game )
|
game_dispose( XWGame* game )
|
||||||
{
|
{
|
||||||
|
@ -642,7 +649,6 @@ gi_writeToStream( XWStreamCtxt* stream, const CurGameInfo* gi )
|
||||||
stream_putBits( stream, NPLAYERS_NBITS, gi->nPlayers );
|
stream_putBits( stream, NPLAYERS_NBITS, gi->nPlayers );
|
||||||
stream_putBits( stream, nColsNBits, gi->boardSize );
|
stream_putBits( stream, nColsNBits, gi->boardSize );
|
||||||
stream_putBits( stream, 2, gi->serverRole );
|
stream_putBits( stream, 2, gi->serverRole );
|
||||||
/* XP_LOGF( "%s: wrote serverRole of %d", __func__, gi->serverRole ); */
|
|
||||||
stream_putBits( stream, 1, gi->hintsNotAllowed );
|
stream_putBits( stream, 1, gi->hintsNotAllowed );
|
||||||
stream_putBits( stream, 2, gi->phoniesAction );
|
stream_putBits( stream, 2, gi->phoniesAction );
|
||||||
stream_putBits( stream, 1, gi->timerEnabled );
|
stream_putBits( stream, 1, gi->timerEnabled );
|
||||||
|
|
|
@ -89,6 +89,7 @@ XP_Bool game_receiveMessage( XWGame* game, XWStreamCtxt* stream,
|
||||||
void game_dispose( XWGame* game );
|
void game_dispose( XWGame* game );
|
||||||
|
|
||||||
void game_getState( const XWGame* game, GameStateInfo* gsi );
|
void game_getState( const XWGame* game, GameStateInfo* gsi );
|
||||||
|
XP_Bool game_getIsServer( const XWGame* game );
|
||||||
|
|
||||||
void gi_initPlayerInfo( MPFORMAL CurGameInfo* gi,
|
void gi_initPlayerInfo( MPFORMAL CurGameInfo* gi,
|
||||||
const XP_UCHAR* nameTemplate );
|
const XP_UCHAR* nameTemplate );
|
||||||
|
|
|
@ -238,7 +238,9 @@ syncPlayers( ServerCtxt* server )
|
||||||
static XP_Bool
|
static XP_Bool
|
||||||
amServer( const ServerCtxt* server )
|
amServer( const ServerCtxt* server )
|
||||||
{
|
{
|
||||||
return SERVER_ISSERVER == server->vol.gi->serverRole;
|
XP_Bool result = SERVER_ISSERVER == server->vol.gi->serverRole;
|
||||||
|
// LOG_RETURNF( "%d (seed=%d)", result, comms_getChannelSeed( server->vol.comms ) );
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -867,7 +869,6 @@ makeRobotMove( ServerCtxt* server )
|
||||||
XP_Bool result = XP_FALSE;
|
XP_Bool result = XP_FALSE;
|
||||||
XP_Bool searchComplete;
|
XP_Bool searchComplete;
|
||||||
XP_S16 turn;
|
XP_S16 turn;
|
||||||
const TrayTileSet* tileSet;
|
|
||||||
MoveInfo newMove = {0};
|
MoveInfo newMove = {0};
|
||||||
ModelCtxt* model = server->vol.model;
|
ModelCtxt* model = server->vol.model;
|
||||||
CurGameInfo* gi = server->vol.gi;
|
CurGameInfo* gi = server->vol.gi;
|
||||||
|
@ -899,7 +900,7 @@ makeRobotMove( ServerCtxt* server )
|
||||||
model_resetCurrentTurn( model, turn );
|
model_resetCurrentTurn( model, turn );
|
||||||
|
|
||||||
if ( !forceTrade ) {
|
if ( !forceTrade ) {
|
||||||
tileSet = model_getPlayerTiles( model, turn );
|
const TrayTileSet* tileSet = model_getPlayerTiles( model, turn );
|
||||||
#ifdef XWFEATURE_BONUSALL
|
#ifdef XWFEATURE_BONUSALL
|
||||||
XP_U16 allTilesBonus = server_figureFinishBonus( server, turn );
|
XP_U16 allTilesBonus = server_figureFinishBonus( server, turn );
|
||||||
#endif
|
#endif
|
||||||
|
@ -1143,7 +1144,7 @@ server_do( ServerCtxt* server )
|
||||||
} else {
|
} else {
|
||||||
XP_Bool moreToDo = XP_FALSE;
|
XP_Bool moreToDo = XP_FALSE;
|
||||||
server->serverDoing = XP_TRUE;
|
server->serverDoing = XP_TRUE;
|
||||||
|
XP_LOGF( "%s(): gameState: %s", __func__, getStateStr(server->nv.gameState) );
|
||||||
switch( server->nv.gameState ) {
|
switch( server->nv.gameState ) {
|
||||||
case XWSTATE_BEGIN:
|
case XWSTATE_BEGIN:
|
||||||
if ( server->nv.pendingRegistrations == 0 ) { /* all players on
|
if ( server->nv.pendingRegistrations == 0 ) { /* all players on
|
||||||
|
@ -2952,6 +2953,7 @@ server_receiveMessage( ServerCtxt* server, XWStreamCtxt* incoming )
|
||||||
XP_Bool accepted = XP_FALSE;
|
XP_Bool accepted = XP_FALSE;
|
||||||
XP_Bool isServer = amServer( server );
|
XP_Bool isServer = amServer( server );
|
||||||
const XW_Proto code = readProto( server, incoming );
|
const XW_Proto code = readProto( server, incoming );
|
||||||
|
XP_LOGF( "%s(code=%s)", __func__, codeToStr(code) );
|
||||||
|
|
||||||
if ( code == XWPROTO_DEVICE_REGISTRATION ) {
|
if ( code == XWPROTO_DEVICE_REGISTRATION ) {
|
||||||
accepted = isServer;
|
accepted = isServer;
|
||||||
|
|
|
@ -257,7 +257,7 @@ smsproto_prepOutbound( SMSProto* state, SMS_CMD cmd, XP_U32 gameID,
|
||||||
}
|
}
|
||||||
|
|
||||||
static SMSMsgArray*
|
static SMSMsgArray*
|
||||||
appendLocMsg( SMSProto* state, SMSMsgArray* arr, SMSMsgLoc* msg )
|
appendLocMsg( SMSProto* XP_UNUSED_DBG(state), SMSMsgArray* arr, SMSMsgLoc* msg )
|
||||||
{
|
{
|
||||||
if ( NULL == arr ) {
|
if ( NULL == arr ) {
|
||||||
arr = XP_CALLOC( state->mpool, sizeof(*arr) );
|
arr = XP_CALLOC( state->mpool, sizeof(*arr) );
|
||||||
|
@ -273,7 +273,7 @@ appendLocMsg( SMSProto* state, SMSMsgArray* arr, SMSMsgLoc* msg )
|
||||||
}
|
}
|
||||||
|
|
||||||
static SMSMsgArray*
|
static SMSMsgArray*
|
||||||
appendNetMsg( SMSProto* state, SMSMsgArray* arr, SMSMsgNet* msg )
|
appendNetMsg( SMSProto* XP_UNUSED_DBG(state), SMSMsgArray* arr, SMSMsgNet* msg )
|
||||||
{
|
{
|
||||||
if ( NULL == arr ) {
|
if ( NULL == arr ) {
|
||||||
arr = XP_CALLOC( state->mpool, sizeof(*arr) );
|
arr = XP_CALLOC( state->mpool, sizeof(*arr) );
|
||||||
|
@ -396,7 +396,7 @@ smsproto_freeMsgArray( SMSProto* state, SMSMsgArray* arr )
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
freeMsg( SMSProto* state, MsgRec** msgp )
|
freeMsg( SMSProto* XP_UNUSED_DBG(state), MsgRec** msgp )
|
||||||
{
|
{
|
||||||
XP_FREEP( state->mpool, &(*msgp)->msgNet.data );
|
XP_FREEP( state->mpool, &(*msgp)->msgNet.data );
|
||||||
XP_FREEP( state->mpool, msgp );
|
XP_FREEP( state->mpool, msgp );
|
||||||
|
@ -595,7 +595,7 @@ rmFromPhoneRec( SMSProto* state, int fromPhoneIndex )
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
freeMsgIDRec( SMSProto* state, MsgIDRec* rec, int fromPhoneIndex, int msgIDIndex )
|
freeMsgIDRec( SMSProto* state, MsgIDRec* XP_UNUSED_DBG(rec), int fromPhoneIndex, int msgIDIndex )
|
||||||
{
|
{
|
||||||
FromPhoneRec* fromPhoneRec = &state->fromPhoneRecs[fromPhoneIndex];
|
FromPhoneRec* fromPhoneRec = &state->fromPhoneRecs[fromPhoneIndex];
|
||||||
MsgIDRec* msgIDRec = &fromPhoneRec->msgIDRecs[msgIDIndex];
|
MsgIDRec* msgIDRec = &fromPhoneRec->msgIDRecs[msgIDIndex];
|
||||||
|
|
|
@ -104,5 +104,7 @@ void smsproto_freeMsgArray( SMSProto* state, SMSMsgArray* arr );
|
||||||
|
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG
|
||||||
void smsproto_runTests( MPFORMAL XW_DUtilCtxt* dutil );
|
void smsproto_runTests( MPFORMAL XW_DUtilCtxt* dutil );
|
||||||
|
# else
|
||||||
|
# define smsproto_runTests( p1, p2 )
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,6 +21,7 @@ BUILD_DIR ?= .
|
||||||
ifeq ($(MEMDEBUG),TRUE)
|
ifeq ($(MEMDEBUG),TRUE)
|
||||||
DEFINES = -DMEM_DEBUG -DDEBUG -DENABLE_LOGGING -DNUMBER_KEY_AS_INDEX
|
DEFINES = -DMEM_DEBUG -DDEBUG -DENABLE_LOGGING -DNUMBER_KEY_AS_INDEX
|
||||||
DEFINES += -DCOMMS_CHECKSUM
|
DEFINES += -DCOMMS_CHECKSUM
|
||||||
|
DEFINES += -DLOG_COMMS_MSGNOS
|
||||||
CFLAGS += -g $(GPROFFLAG) -Wall -Wunused-parameter -Wcast-align -Werror -O0
|
CFLAGS += -g $(GPROFFLAG) -Wall -Wunused-parameter -Wcast-align -Werror -O0
|
||||||
# DEFINES += -DDEBUG_HASHING
|
# DEFINES += -DDEBUG_HASHING
|
||||||
CFLAGS += -DDEBUG_TS -rdynamic
|
CFLAGS += -DDEBUG_TS -rdynamic
|
||||||
|
@ -144,8 +145,6 @@ DEFINES += -DCURSES_CELL_WIDTH=$(CURSES_CELL_WIDTH)
|
||||||
endif
|
endif
|
||||||
DEFINES += $(UNICODE)
|
DEFINES += $(UNICODE)
|
||||||
|
|
||||||
DEFINES += -DLOG_COMMS_MSGNOS
|
|
||||||
|
|
||||||
# Networking-related features. Only set these if STANDALONE is not set
|
# Networking-related features. Only set these if STANDALONE is not set
|
||||||
ifeq ($(STANDALONE),)
|
ifeq ($(STANDALONE),)
|
||||||
|
|
||||||
|
@ -210,16 +209,19 @@ endif
|
||||||
ifdef DO_CURSES
|
ifdef DO_CURSES
|
||||||
CURSES_OBJS = \
|
CURSES_OBJS = \
|
||||||
$(BUILD_PLAT_DIR)/cursesmain.o \
|
$(BUILD_PLAT_DIR)/cursesmain.o \
|
||||||
|
$(BUILD_PLAT_DIR)/cursesboard.o \
|
||||||
|
$(BUILD_PLAT_DIR)/cursesmenu.o \
|
||||||
|
$(BUILD_PLAT_DIR)/curgamlistwin.o \
|
||||||
$(BUILD_PLAT_DIR)/cursesdraw.o \
|
$(BUILD_PLAT_DIR)/cursesdraw.o \
|
||||||
$(BUILD_PLAT_DIR)/cursesask.o \
|
$(BUILD_PLAT_DIR)/cursesask.o \
|
||||||
$(BUILD_PLAT_DIR)/cursesdlgutil.o \
|
$(BUILD_PLAT_DIR)/cursesdlgutil.o \
|
||||||
$(BUILD_PLAT_DIR)/cursesletterask.o
|
$(BUILD_PLAT_DIR)/cursesletterask.o
|
||||||
endif
|
endif
|
||||||
ifndef LIB_NO_UI
|
ifndef LIB_NO_UI
|
||||||
MAIN_OBJS = $(BUILD_PLAT_DIR)/linuxmain.o
|
MAIN_OBJS = $(BUILD_PLAT_DIR)/linuxmain.o \
|
||||||
|
$(BUILD_PLAT_DIR)/gsrcwrap.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
OBJ = \
|
OBJ = \
|
||||||
$(BUILD_PLAT_DIR)/filestream.o \
|
$(BUILD_PLAT_DIR)/filestream.o \
|
||||||
$(BUILD_PLAT_DIR)/linuxbt.o \
|
$(BUILD_PLAT_DIR)/linuxbt.o \
|
||||||
|
|
293
xwords4/linux/curgamlistwin.c
Normal file
293
xwords4/linux/curgamlistwin.c
Normal file
|
@ -0,0 +1,293 @@
|
||||||
|
/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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
|
||||||
|
* 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 <ncurses.h>
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "curgamlistwin.h"
|
||||||
|
|
||||||
|
struct CursGameList {
|
||||||
|
WINDOW* window;
|
||||||
|
int width, height;
|
||||||
|
int curSel;
|
||||||
|
int yOffset;
|
||||||
|
GSList* games;
|
||||||
|
sqlite3* pDb;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void adjustCurSel( CursGameList* cgl );
|
||||||
|
|
||||||
|
CursGameList*
|
||||||
|
cgl_init( sqlite3* pDb, int width, int height )
|
||||||
|
{
|
||||||
|
CursGameList* cgl = g_malloc0( sizeof( *cgl ) );
|
||||||
|
cgl->pDb = pDb;
|
||||||
|
cgl->window = newwin( height, width, 0, 0 );
|
||||||
|
XP_LOGF( "%s(): made window with height=%d, width=%d", __func__, height, width );
|
||||||
|
cgl->width = width;
|
||||||
|
cgl->height = height;
|
||||||
|
return cgl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cgl_destroy( CursGameList* cgl )
|
||||||
|
{
|
||||||
|
g_slist_free_full( cgl->games, g_free );
|
||||||
|
delwin( cgl->window );
|
||||||
|
g_free( cgl );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
addOne( CursGameList* cgl, sqlite3_int64 rowid )
|
||||||
|
{
|
||||||
|
GameInfo gib;
|
||||||
|
if ( getGameInfo( cgl->pDb, rowid, &gib ) ) {
|
||||||
|
GameInfo* gibp = g_malloc( sizeof(*gibp) );
|
||||||
|
*gibp = gib;
|
||||||
|
cgl->games = g_slist_append( cgl->games, gibp );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load from the DB */
|
||||||
|
void
|
||||||
|
cgl_refresh( CursGameList* cgl )
|
||||||
|
{
|
||||||
|
g_slist_free_full( cgl->games, g_free );
|
||||||
|
cgl->games = NULL;
|
||||||
|
|
||||||
|
sqlite3* pDb = cgl->pDb;
|
||||||
|
GSList* games = listGames( pDb );
|
||||||
|
for ( GSList* iter = games; !!iter; iter = iter->next ) {
|
||||||
|
sqlite3_int64* rowid = (sqlite3_int64*)iter->data;
|
||||||
|
addOne( cgl, *rowid );
|
||||||
|
}
|
||||||
|
cgl_draw( cgl );
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSList*
|
||||||
|
findFor( CursGameList* cgl, sqlite3_int64 rowid )
|
||||||
|
{
|
||||||
|
GSList* result = NULL;
|
||||||
|
for ( GSList* iter = cgl->games; !!iter && !result; iter = iter->next ) {
|
||||||
|
GameInfo* gib = (GameInfo*)iter->data;
|
||||||
|
if ( gib->rowid == rowid ) {
|
||||||
|
result = iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cgl_refreshOne( CursGameList* cgl, sqlite3_int64 rowid, bool select )
|
||||||
|
{
|
||||||
|
// Update the info. In place if it exists, otherwise creating a new list
|
||||||
|
// elem
|
||||||
|
|
||||||
|
GameInfo gib;
|
||||||
|
if ( getGameInfo( cgl->pDb, rowid, &gib ) ) {
|
||||||
|
GameInfo* found;
|
||||||
|
GSList* elem = findFor( cgl, rowid );
|
||||||
|
if ( !!elem ) {
|
||||||
|
found = (GameInfo*)elem->data;
|
||||||
|
*found = gib;
|
||||||
|
} else {
|
||||||
|
found = g_malloc( sizeof(*found) );
|
||||||
|
*found = gib;
|
||||||
|
cgl->games = g_slist_append( cgl->games, found );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( select ) {
|
||||||
|
cgl->curSel = g_slist_index( cgl->games, found );
|
||||||
|
}
|
||||||
|
adjustCurSel( cgl );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cgl_remove( CursGameList* cgl, sqlite3_int64 rowid )
|
||||||
|
{
|
||||||
|
GSList* elem = findFor( cgl, rowid );
|
||||||
|
if ( !!elem ) {
|
||||||
|
g_free( elem->data );
|
||||||
|
cgl->games = g_slist_delete_link( cgl->games, elem );
|
||||||
|
}
|
||||||
|
adjustCurSel( cgl );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cgl_moveSel( CursGameList* cgl, bool down )
|
||||||
|
{
|
||||||
|
int nGames = g_slist_length( cgl->games );
|
||||||
|
cgl->curSel += nGames + (down ? 1 : -1);
|
||||||
|
cgl->curSel %= nGames;
|
||||||
|
adjustCurSel( cgl );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
adjustCurSel( CursGameList* cgl )
|
||||||
|
{
|
||||||
|
XP_LOGF( "%s() start: curSel: %d; yOffset: %d", __func__, cgl->curSel, cgl->yOffset );
|
||||||
|
int nGames = g_slist_length( cgl->games );
|
||||||
|
if ( cgl->curSel >= nGames ) {
|
||||||
|
cgl->curSel = nGames - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now adjust yOffset */
|
||||||
|
int nVisRows = cgl->height - 2; /* 1 for the title and header rows */
|
||||||
|
if ( cgl->curSel - cgl->yOffset >= nVisRows ) {
|
||||||
|
cgl->yOffset = cgl->curSel - nVisRows + 1;
|
||||||
|
} else {
|
||||||
|
while ( cgl->curSel < cgl->yOffset ) {
|
||||||
|
--cgl->yOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XP_LOGF( "%s() end: curSel: %d; yOffset: %d", __func__, cgl->curSel, cgl->yOffset );
|
||||||
|
cgl_draw( cgl );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
countBits( int bits )
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
while ( 0 != bits ) {
|
||||||
|
++result;
|
||||||
|
bits &= bits - 1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char*
|
||||||
|
codeToLang( XP_LangCode langCode )
|
||||||
|
{
|
||||||
|
const char* langName = "<\?\?\?>";
|
||||||
|
switch( langCode ) {
|
||||||
|
case 1: langName = "English"; break;
|
||||||
|
case 2: langName = "French"; break;
|
||||||
|
case 3: langName = "German"; break;
|
||||||
|
case 4: langName = "Turkish";break;
|
||||||
|
case 5: langName = "Arabic"; break;
|
||||||
|
case 6: langName = "Spanish"; break;
|
||||||
|
case 7: langName = "Swedish"; break;
|
||||||
|
case 8:langName = "Polish";; break;
|
||||||
|
case 9: langName = "Danish"; break;
|
||||||
|
case 10: langName = "Italian"; break;
|
||||||
|
case 11: langName = "Dutch"; break;
|
||||||
|
case 12: langName = "Catalan"; break;
|
||||||
|
case 13: langName = "Portuguese"; break;
|
||||||
|
case 15: langName = "Russian"; break;
|
||||||
|
case 17: langName = "Czech"; break;
|
||||||
|
case 18: langName = "Greek"; break;
|
||||||
|
case 19: langName = "Slovak"; break;
|
||||||
|
default:
|
||||||
|
XP_LOGF( "%s(): bad code %d", __func__, langCode );
|
||||||
|
break;
|
||||||
|
// XP_ASSERT(0);
|
||||||
|
}
|
||||||
|
return langName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cgl_draw( CursGameList* cgl )
|
||||||
|
{
|
||||||
|
WINDOW* win = cgl->window;
|
||||||
|
werase( win );
|
||||||
|
|
||||||
|
const int nGames = g_slist_length( cgl->games );
|
||||||
|
|
||||||
|
/* Draw '+' at far right if scrollable */
|
||||||
|
int nBelow = nGames - (cgl->height-2) - cgl->yOffset;
|
||||||
|
XP_LOGF( "%s(): yOffset: %d; nBelow: %d", __func__, cgl->yOffset, nBelow );
|
||||||
|
if ( 0 < nBelow ) {
|
||||||
|
mvwaddstr( win, cgl->height-2, cgl->width - 1, "+" );
|
||||||
|
}
|
||||||
|
if ( 0 < cgl->yOffset ) {
|
||||||
|
mvwaddstr( win, 0, cgl->width-1, "+" );
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* cols[] = {"Row", "RowID", "Lang", "Scores", "GameID", "Role", "Room",
|
||||||
|
"nTotal", "nMissing", "Seed", "nMoves", "Turn", "nPend", };
|
||||||
|
|
||||||
|
int nShown = nGames <= cgl->height - 2 ? nGames : cgl->height - 2;
|
||||||
|
char* data[nShown + 1][VSIZE(cols)];
|
||||||
|
for ( int ii = 0; ii < VSIZE(cols); ++ii ) {
|
||||||
|
data[0][ii] = g_strdup(cols[ii]);
|
||||||
|
}
|
||||||
|
int line = 1;
|
||||||
|
for ( int ii = 0; ii < nShown; ++ii ) {
|
||||||
|
const GameInfo* gi = g_slist_nth_data( cgl->games, ii + cgl->yOffset );
|
||||||
|
int col = 0;
|
||||||
|
data[line][col++] = g_strdup_printf( "%d", ii + cgl->yOffset + 1 ); /* 1-based */
|
||||||
|
data[line][col++] = g_strdup_printf( "%05lld", gi->rowid );
|
||||||
|
data[line][col++] = g_strdup( codeToLang(gi->dictLang) );
|
||||||
|
data[line][col++] = g_strdup( gi->scores );
|
||||||
|
data[line][col++] = g_strdup_printf( "%d", gi->gameID );
|
||||||
|
data[line][col++] = g_strdup_printf( "%d", gi->role );
|
||||||
|
data[line][col++] = g_strdup( gi->room );
|
||||||
|
data[line][col++] = g_strdup_printf( "%d", gi->nTotal );
|
||||||
|
data[line][col++] = g_strdup_printf( "%d", countBits(gi->nMissing) );
|
||||||
|
data[line][col++] = g_strdup_printf( "%d", gi->seed );
|
||||||
|
data[line][col++] = g_strdup_printf( "%d", gi->nMoves );
|
||||||
|
data[line][col++] = g_strdup_printf( "%d", gi->turn );
|
||||||
|
data[line][col++] = g_strdup_printf( "%d", gi->nPending );
|
||||||
|
XP_ASSERT( col == VSIZE(data[line]) );
|
||||||
|
++line;
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxlen = 0;
|
||||||
|
int offset = 0;
|
||||||
|
for ( int col = 0; col < VSIZE(data[0]); ++col ) {
|
||||||
|
for ( int line = 0; line < VSIZE(data); ++line ) {
|
||||||
|
char* str = data[line][col];
|
||||||
|
int len = strlen(str);
|
||||||
|
if ( maxlen < len ) {
|
||||||
|
maxlen = len;
|
||||||
|
}
|
||||||
|
bool highlight = cgl->yOffset + line - 1 == cgl->curSel;
|
||||||
|
if ( highlight ) {
|
||||||
|
wstandout( win );
|
||||||
|
}
|
||||||
|
mvwaddstr( win, line + 1, offset, str );
|
||||||
|
if ( highlight ) {
|
||||||
|
wstandend( win );
|
||||||
|
}
|
||||||
|
g_free( str );
|
||||||
|
}
|
||||||
|
offset += maxlen + 2;
|
||||||
|
maxlen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[cgl->width + 1];
|
||||||
|
snprintf( buf, VSIZE(buf), "%d games total", nGames );
|
||||||
|
mvwaddstr( win, 0, 0, buf );
|
||||||
|
|
||||||
|
wrefresh( win );
|
||||||
|
}
|
||||||
|
|
||||||
|
const GameInfo*
|
||||||
|
cgl_getSel( CursGameList* cgl )
|
||||||
|
{
|
||||||
|
return g_slist_nth_data( cgl->games, cgl->curSel );
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
cgl_getNGames( CursGameList* cgl )
|
||||||
|
{
|
||||||
|
return g_slist_length( cgl->games );
|
||||||
|
}
|
43
xwords4/linux/curgamlistwin.h
Normal file
43
xwords4/linux/curgamlistwin.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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
|
||||||
|
* 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 _CURGAMLISTWIN_H_
|
||||||
|
#define _CURGAMLISTWIN_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "gamesdb.h"
|
||||||
|
|
||||||
|
typedef struct CursGameList CursGameList;
|
||||||
|
|
||||||
|
CursGameList* cgl_init( sqlite3* pDb, int width, int height );
|
||||||
|
void cgl_destroy( CursGameList* cgl );
|
||||||
|
|
||||||
|
void cgl_refresh( CursGameList* cgl );
|
||||||
|
void cgl_refreshOne( CursGameList* cgl, sqlite3_int64 rowid, bool select );
|
||||||
|
void cgl_remove( CursGameList* cgl, sqlite3_int64 rowid );
|
||||||
|
|
||||||
|
void cgl_moveSel( CursGameList* cgl, bool down );
|
||||||
|
|
||||||
|
void cgl_draw( CursGameList* cgl );
|
||||||
|
|
||||||
|
const GameInfo* cgl_getSel( CursGameList* cgl );
|
||||||
|
int cgl_getNGames( CursGameList* cgl );
|
||||||
|
|
||||||
|
#endif
|
|
@ -32,11 +32,12 @@
|
||||||
/* Figure out how many lines there are and how wide the widest is.
|
/* Figure out how many lines there are and how wide the widest is.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
cursesask( CursesAppGlobals* globals, const char* question, short numButtons,
|
cursesask( WINDOW* window, const char* question, short numButtons,
|
||||||
const char** buttons )
|
const char** buttons )
|
||||||
{
|
{
|
||||||
WINDOW* confWin;
|
WINDOW* confWin;
|
||||||
int x, y, rows, row, nLines;
|
int x, y, rows, row, nLines;
|
||||||
|
int left, top;
|
||||||
short newSelButton = 0;
|
short newSelButton = 0;
|
||||||
short curSelButton = 1; /* force draw by being different */
|
short curSelButton = 1; /* force draw by being different */
|
||||||
short spacePerButton, num;
|
short spacePerButton, num;
|
||||||
|
@ -45,7 +46,8 @@ cursesask( CursesAppGlobals* globals, const char* question, short numButtons,
|
||||||
FormatInfo fi;
|
FormatInfo fi;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
getmaxyx(globals->boardWin, y, x);
|
getmaxyx( window, y, x);
|
||||||
|
getbegyx( window, top, left );
|
||||||
|
|
||||||
measureAskText( question, x-2, &fi );
|
measureAskText( question, x-2, &fi );
|
||||||
len = fi.maxLen;
|
len = fi.maxLen;
|
||||||
|
@ -62,8 +64,8 @@ cursesask( CursesAppGlobals* globals, const char* question, short numButtons,
|
||||||
}
|
}
|
||||||
|
|
||||||
nLines = ASK_HEIGHT + rows - 1;
|
nLines = ASK_HEIGHT + rows - 1;
|
||||||
confWin = newwin( nLines, len+(PAD*2),
|
confWin = newwin( nLines, len+(PAD*2), top + ((y/2) - (nLines/2)),
|
||||||
(y/2) - (nLines/2), (x-len-2)/2 );
|
left + ((x-len-2)/2) );
|
||||||
keypad( confWin, TRUE );
|
keypad( confWin, TRUE );
|
||||||
wclear( confWin );
|
wclear( confWin );
|
||||||
box( confWin, '|', '-');
|
box( confWin, '|', '-');
|
||||||
|
@ -120,9 +122,9 @@ cursesask( CursesAppGlobals* globals, const char* question, short numButtons,
|
||||||
delwin( confWin );
|
delwin( confWin );
|
||||||
|
|
||||||
/* this leaves a ghost line, but I can't figure out a better way. */
|
/* this leaves a ghost line, but I can't figure out a better way. */
|
||||||
wtouchln( globals->boardWin, (y/2)-(nLines/2), ASK_HEIGHT + rows - 1, 1 );
|
wtouchln( window, (y/2)-(nLines/2), ASK_HEIGHT + rows - 1, 1 );
|
||||||
wrefresh( globals->boardWin );
|
wrefresh( window );
|
||||||
return curSelButton;
|
return curSelButton;
|
||||||
} /* ask */
|
} /* cursesask */
|
||||||
|
|
||||||
#endif /* PLATFORM_NCURSES */
|
#endif /* PLATFORM_NCURSES */
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include "cursesmain.h"
|
#include "cursesmain.h"
|
||||||
|
|
||||||
int cursesask( CursesAppGlobals* globals, const char* question,
|
int cursesask( WINDOW* window, const char* question,
|
||||||
short numButtons, const char** buttons );
|
short numButtons, const char** buttons );
|
||||||
|
|
||||||
|
|
||||||
|
|
1351
xwords4/linux/cursesboard.c
Normal file
1351
xwords4/linux/cursesboard.c
Normal file
File diff suppressed because it is too large
Load diff
42
xwords4/linux/cursesboard.h
Normal file
42
xwords4/linux/cursesboard.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2000 - 2020 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
|
||||||
|
* 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 _CURSESBOARD_H_
|
||||||
|
#define _CURSESBOARD_H_
|
||||||
|
|
||||||
|
#include "cursesmain.h"
|
||||||
|
|
||||||
|
typedef struct CursesAppGlobals CursesAppGlobals;
|
||||||
|
typedef struct CursesBoardState CursesBoardState;
|
||||||
|
|
||||||
|
typedef void (*OnGameSaved)( CursesAppGlobals* aGlobals, sqlite3_int64 rowid, bool isNew );
|
||||||
|
|
||||||
|
CursesBoardState* cb_init( CursesAppGlobals* aGlobals, LaunchParams* params,
|
||||||
|
CursesMenuState* menuState, OnGameSaved onGameSaved );
|
||||||
|
|
||||||
|
void cb_open( CursesBoardState* cbState, sqlite3_int64 rowid,
|
||||||
|
int width, int top, int height );
|
||||||
|
void cb_new( CursesBoardState* cbState, int width, int top, int height );
|
||||||
|
|
||||||
|
XP_U16 cb_feedBuffer( CursesBoardState* cbState, sqlite3_int64 rowid,
|
||||||
|
const XP_U8* buf, XP_U16 len, const CommsAddrRec* from );
|
||||||
|
void cb_closeAll( CursesBoardState* cbState );
|
||||||
|
|
||||||
|
#endif
|
|
@ -646,4 +646,12 @@ cursesDrawCtxtMake( WINDOW* boardWin )
|
||||||
return (DrawCtx*)dctx;
|
return (DrawCtx*)dctx;
|
||||||
} /* curses_drawctxt_init */
|
} /* curses_drawctxt_init */
|
||||||
|
|
||||||
|
void
|
||||||
|
cursesDrawCtxtFree( DrawCtx* pdctx )
|
||||||
|
{
|
||||||
|
CursesDrawCtx* dctx = (CursesDrawCtx*)pdctx;
|
||||||
|
free( dctx->vtable );
|
||||||
|
free( dctx );
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* PLATFORM_NCURSES */
|
#endif /* PLATFORM_NCURSES */
|
||||||
|
|
|
@ -47,7 +47,7 @@ sizeTextsAsButtons( XP_U16 maxLen, XP_U16 nTiles, XP_U16* textsCols,
|
||||||
} /* sizeTextsAsButtons */
|
} /* sizeTextsAsButtons */
|
||||||
|
|
||||||
XP_S16
|
XP_S16
|
||||||
curses_askLetter( CursesAppGlobals* globals, XP_UCHAR* query,
|
curses_askLetter( WINDOW* window, XP_UCHAR* query,
|
||||||
const XP_UCHAR** texts, XP_U16 nTiles )
|
const XP_UCHAR** texts, XP_U16 nTiles )
|
||||||
{
|
{
|
||||||
XP_S16 result;
|
XP_S16 result;
|
||||||
|
@ -70,7 +70,7 @@ curses_askLetter( CursesAppGlobals* globals, XP_UCHAR* query,
|
||||||
textPtrs[i] = (char*)&texts[i];
|
textPtrs[i] = (char*)&texts[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
getmaxyx( globals->boardWin, y, x );
|
getmaxyx( window, y, x );
|
||||||
|
|
||||||
numCtlButtons = VSIZE(ctlButtons);
|
numCtlButtons = VSIZE(ctlButtons);
|
||||||
|
|
||||||
|
@ -209,8 +209,8 @@ curses_askLetter( CursesAppGlobals* globals, XP_UCHAR* query,
|
||||||
delwin( confWin );
|
delwin( confWin );
|
||||||
|
|
||||||
/* this leaves a ghost line, but I can't figure out a better way. */
|
/* this leaves a ghost line, but I can't figure out a better way. */
|
||||||
wtouchln( globals->boardWin, (y/2)-(nLines/2), ASK_HEIGHT + rows - 1, 1 );
|
wtouchln( window, (y/2)-(nLines/2), ASK_HEIGHT + rows - 1, 1 );
|
||||||
wrefresh( globals->boardWin );
|
wrefresh( window );
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} /* curses_askLetter */
|
} /* curses_askLetter */
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include "linuxmain.h"
|
#include "linuxmain.h"
|
||||||
#include "cursesmain.h"
|
#include "cursesmain.h"
|
||||||
|
|
||||||
XP_S16 curses_askLetter( CursesAppGlobals* globals, XP_UCHAR* query,
|
XP_S16 curses_askLetter( WINDOW* window, XP_UCHAR* query,
|
||||||
const XP_UCHAR** texts, XP_U16 nTiles );
|
const XP_UCHAR** texts, XP_U16 nTiles );
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||||
/*
|
/*
|
||||||
* Copyright 1997-2000 by Eric House (xwords@eehouse.org). All rights reserved.
|
* Copyright 1997-2020 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -39,11 +39,17 @@
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "xwstate.h"
|
#include "xwstate.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "cursesmenu.h"
|
||||||
|
#include "cursesboard.h"
|
||||||
/* #include "compipe.h" */
|
/* #include "compipe.h" */
|
||||||
|
|
||||||
typedef struct CursesAppGlobals CursesAppGlobals;
|
typedef struct CursesAppGlobals CursesAppGlobals;
|
||||||
|
typedef struct CursesBoardGlobals CursesBoardGlobals;
|
||||||
|
|
||||||
typedef XP_Bool (*EventFunc)(CursesAppGlobals* globals, int ch);
|
typedef XP_Bool (*EventFunc)(CursesAppGlobals* globals, int ch);
|
||||||
|
void onCursesBoardClosing( CursesAppGlobals* aGlobals, CursesBoardGlobals* bGlobals );
|
||||||
|
void onCursesGameSaved( CursesAppGlobals* aGlobals, sqlite3_int64 rowid );
|
||||||
|
|
||||||
/* typedef void (*MenuDrawer)(CursesAppGlobals* globals); */
|
/* typedef void (*MenuDrawer)(CursesAppGlobals* globals); */
|
||||||
|
|
||||||
#define FD_MAX 6
|
#define FD_MAX 6
|
||||||
|
@ -51,56 +57,10 @@ typedef XP_Bool (*EventFunc)(CursesAppGlobals* globals, int ch);
|
||||||
#define FD_TIMEEVT 1
|
#define FD_TIMEEVT 1
|
||||||
#define FD_FIRSTSOCKET 2
|
#define FD_FIRSTSOCKET 2
|
||||||
|
|
||||||
struct CursesAppGlobals {
|
// typedef struct CursesBoardGlobals;
|
||||||
CommonGlobals cGlobals;
|
|
||||||
|
|
||||||
struct CursesDrawCtx* draw;
|
|
||||||
|
|
||||||
DictionaryCtxt* dictionary;
|
|
||||||
EngineCtxt* engine;
|
|
||||||
|
|
||||||
XP_Bool amServer; /* this process acting as server */
|
|
||||||
|
|
||||||
WINDOW* mainWin;
|
|
||||||
WINDOW* menuWin;
|
|
||||||
WINDOW* boardWin;
|
|
||||||
|
|
||||||
XP_Bool doDraw;
|
|
||||||
const struct MenuList* menuList;
|
|
||||||
XP_U16 nLinesMenu;
|
|
||||||
gchar* lastErr;
|
|
||||||
|
|
||||||
XP_U16 nChatsSent;
|
|
||||||
XP_U16 nextQueryTimeSecs;
|
|
||||||
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
XWStreamCtxt* stream; /* how we can reach the server */
|
|
||||||
} client;
|
|
||||||
struct {
|
|
||||||
int serverSocket;
|
|
||||||
XP_Bool socketOpen;
|
|
||||||
} server;
|
|
||||||
} csInfo;
|
|
||||||
|
|
||||||
short statusLine;
|
|
||||||
XWGameState state;
|
|
||||||
CommsRelayState commsRelayState;
|
|
||||||
|
|
||||||
struct sockaddr_in listenerSockAddr;
|
|
||||||
#ifdef USE_GLIBLOOP
|
|
||||||
GMainLoop* loop;
|
|
||||||
GList* sources;
|
|
||||||
int quitpipe[2];
|
|
||||||
#else
|
|
||||||
XP_Bool timeToExit;
|
|
||||||
short fdCount;
|
|
||||||
struct pollfd fdArray[FD_MAX]; /* one for stdio, one for listening socket */
|
|
||||||
int timepipe[2]; /* for reading/writing "user events" */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
DrawCtx* cursesDrawCtxtMake( WINDOW* boardWin );
|
DrawCtx* cursesDrawCtxtMake( WINDOW* boardWin );
|
||||||
|
void cursesDrawCtxtFree( DrawCtx* dctx );
|
||||||
|
|
||||||
/* Ports: Client and server pick a port at startup on which they'll listen.
|
/* Ports: Client and server pick a port at startup on which they'll listen.
|
||||||
* If both are to be on the same device using localhost as their ip address,
|
* If both are to be on the same device using localhost as their ip address,
|
||||||
|
@ -114,5 +74,6 @@ DrawCtx* cursesDrawCtxtMake( WINDOW* boardWin );
|
||||||
|
|
||||||
|
|
||||||
void cursesmain( XP_Bool isServer, LaunchParams* params );
|
void cursesmain( XP_Bool isServer, LaunchParams* params );
|
||||||
|
bool handleQuit( void* closure, int unused_key );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
213
xwords4/linux/cursesmenu.c
Normal file
213
xwords4/linux/cursesmenu.c
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 1997-2020 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
|
||||||
|
* 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 <glib.h>
|
||||||
|
#include <ncurses.h>
|
||||||
|
|
||||||
|
#include "cursesmenu.h"
|
||||||
|
#include "xptypes.h"
|
||||||
|
#include "comtypes.h"
|
||||||
|
#include "cursesmain.h"
|
||||||
|
#include "linuxmain.h"
|
||||||
|
#include "gsrcwrap.h"
|
||||||
|
|
||||||
|
struct CursesMenuState {
|
||||||
|
WINDOW* menuWin;
|
||||||
|
GSList* menuLists;
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_stdin( GIOChannel* XP_UNUSED_DBG(source), GIOCondition condition,
|
||||||
|
gpointer data )
|
||||||
|
{
|
||||||
|
if ( 0 != (G_IO_IN & condition) ) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
gint fd = g_io_channel_unix_get_fd( source );
|
||||||
|
XP_ASSERT( 0 == fd );
|
||||||
|
#endif
|
||||||
|
CursesMenuState* state = (CursesMenuState*)data;
|
||||||
|
int ch = wgetch( state->menuWin );
|
||||||
|
cmenu_handleKeyEvent( state, ch );
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CursesMenuState*
|
||||||
|
cmenu_init( WINDOW* mainWindow )
|
||||||
|
{
|
||||||
|
CursesMenuState* result = g_malloc0( sizeof(*result) );
|
||||||
|
|
||||||
|
int width, height;
|
||||||
|
getmaxyx( mainWindow, height, width );
|
||||||
|
result->menuWin = newwin( MENU_WINDOW_HEIGHT, width,
|
||||||
|
height-MENU_WINDOW_HEIGHT, 0 );
|
||||||
|
nodelay( result->menuWin, 1 ); /* don't block on getch */
|
||||||
|
|
||||||
|
ADD_SOCKET( result, 0, handle_stdin );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmenu_dispose( CursesMenuState* state )
|
||||||
|
{
|
||||||
|
XP_ASSERT( !!state );
|
||||||
|
g_free( state );
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _MenuListElem {
|
||||||
|
MenuList* list;
|
||||||
|
void* closure;
|
||||||
|
} MenuListElem;
|
||||||
|
#define PUSH_TOKEN ((MenuListElem*)-1)
|
||||||
|
|
||||||
|
void
|
||||||
|
cmenu_pop( CursesMenuState* state )
|
||||||
|
{
|
||||||
|
/* pop off the front of the list until we've popped a PUSH_TOKEN */
|
||||||
|
for ( ; ; ) {
|
||||||
|
MenuListElem* elem = state->menuLists->data;
|
||||||
|
state->menuLists = g_slist_remove_link( state->menuLists,
|
||||||
|
state->menuLists );
|
||||||
|
if ( PUSH_TOKEN == elem ) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
g_free( elem );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cmenu_draw( state );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
addMenus( CursesMenuState* state, void* closure, va_list ap )
|
||||||
|
{
|
||||||
|
for ( ; ; ) {
|
||||||
|
MenuList* param = va_arg(ap, MenuList*);
|
||||||
|
if ( !param ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
MenuListElem* elem = g_malloc0( sizeof( *elem ) );
|
||||||
|
elem->closure = closure;
|
||||||
|
elem->list = param;
|
||||||
|
state->menuLists = g_slist_prepend( state->menuLists, elem );
|
||||||
|
}
|
||||||
|
cmenu_draw( state );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmenu_addMenus( CursesMenuState* state, void* closure, ... )
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start( ap, closure );
|
||||||
|
addMenus( state, closure, ap );
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmenu_push( CursesMenuState* state, void* closure, ... )
|
||||||
|
{
|
||||||
|
if ( !!state ) {
|
||||||
|
state->menuLists = g_slist_prepend( state->menuLists, PUSH_TOKEN );
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
|
va_start( ap, closure );
|
||||||
|
addMenus( state, closure, ap );
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmenu_removeMenus( CursesMenuState* state, ... )
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start( ap, state );
|
||||||
|
for ( ; ; ) {
|
||||||
|
MenuList* param = va_arg(ap, MenuList*);
|
||||||
|
if ( !param ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for ( GSList* iter = state->menuLists; !!iter; iter = iter->next ) {
|
||||||
|
MenuListElem* elem = iter->data;
|
||||||
|
if ( elem->list == param ) {
|
||||||
|
state->menuLists = g_slist_remove( state->menuLists, elem );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
va_end( ap );
|
||||||
|
|
||||||
|
cmenu_draw( state );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
cmenu_handleKeyEvent( CursesMenuState* state, char ch )
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
for ( GSList* iter = state->menuLists; !!iter; iter = iter->next ) {
|
||||||
|
const MenuListElem* elem = iter->data;
|
||||||
|
if ( PUSH_TOKEN == elem ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for ( const MenuList* list = elem->list; !!list->handler; ++list ) {
|
||||||
|
if ( list->key == ch ) {
|
||||||
|
result = (*list->handler)(elem->closure, ch);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fmtMenuItem( const MenuList* item, char* buf, int maxLen )
|
||||||
|
{
|
||||||
|
snprintf( buf, maxLen, "%s %s", item->keyDesc, item->desc );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmenu_draw( const CursesMenuState* state )
|
||||||
|
{
|
||||||
|
WINDOW* win = state->menuWin;
|
||||||
|
wclear( win );
|
||||||
|
int line = 0;
|
||||||
|
int col = 0;
|
||||||
|
int maxLen = 0;
|
||||||
|
for ( GSList* iter = state->menuLists; !!iter; iter = iter->next ) {
|
||||||
|
const MenuListElem* elem = iter->data;
|
||||||
|
if ( PUSH_TOKEN == elem ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for ( MenuList* list = elem->list; !!list->handler; ++list ) {
|
||||||
|
char buf[32];
|
||||||
|
fmtMenuItem( list, buf, sizeof(buf) );
|
||||||
|
int len = strlen(buf);
|
||||||
|
if ( maxLen < len ) {
|
||||||
|
maxLen = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
mvwaddstr( win, line, col, buf );
|
||||||
|
if ( ++line >= MENU_WINDOW_HEIGHT ) {
|
||||||
|
line = 0;
|
||||||
|
col += maxLen + 1;
|
||||||
|
maxLen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wrefresh( win );
|
||||||
|
}
|
54
xwords4/linux/cursesmenu.h
Normal file
54
xwords4/linux/cursesmenu.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 1997-2020 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
|
||||||
|
* 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 _CURSESMENU_H_
|
||||||
|
#define _CURSESMENU_H_
|
||||||
|
|
||||||
|
#include <ncurses.h>
|
||||||
|
|
||||||
|
#ifdef CURSES_SMALL_SCREEN
|
||||||
|
# define MENU_WINDOW_HEIGHT 1
|
||||||
|
# define BOARD_OFFSET 0
|
||||||
|
#else
|
||||||
|
# define MENU_WINDOW_HEIGHT 5 /* three lines plus borders */
|
||||||
|
# define BOARD_OFFSET 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef bool (*CursesMenuHandler)( void* closure, int key );
|
||||||
|
typedef struct MenuList {
|
||||||
|
CursesMenuHandler handler;
|
||||||
|
char* desc;
|
||||||
|
char* keyDesc;
|
||||||
|
char key;
|
||||||
|
} MenuList;
|
||||||
|
|
||||||
|
typedef struct CursesMenuState CursesMenuState;
|
||||||
|
|
||||||
|
CursesMenuState* cmenu_init( WINDOW* mainWindow );
|
||||||
|
void cmenu_dispose( CursesMenuState* state );
|
||||||
|
|
||||||
|
void cmenu_clearMenus( CursesMenuState* state );
|
||||||
|
void cmenu_draw( const CursesMenuState* state );
|
||||||
|
void cmenu_addMenus( CursesMenuState* state, void* closure, ... );
|
||||||
|
void cmenu_push( CursesMenuState* state, void* closure, ... );
|
||||||
|
void cmenu_pop( CursesMenuState* state );
|
||||||
|
void cmenu_removeMenus( CursesMenuState* state, ... );
|
||||||
|
bool cmenu_handleKeyEvent( CursesMenuState* state, char ch );
|
||||||
|
|
||||||
|
#endif
|
|
@ -59,10 +59,14 @@ openGamesDB( const char* dbName )
|
||||||
",local INT(1)"
|
",local INT(1)"
|
||||||
",nmoves INT"
|
",nmoves INT"
|
||||||
",seed INT"
|
",seed INT"
|
||||||
|
",nPending INT"
|
||||||
|
",role INT"
|
||||||
|
",dictlang INT"
|
||||||
",gameid INT"
|
",gameid INT"
|
||||||
",ntotal INT(2)"
|
",ntotal INT(2)"
|
||||||
",nmissing INT(2)"
|
",nmissing INT(2)"
|
||||||
",lastMoveTime INT"
|
",lastMoveTime INT"
|
||||||
|
",scores TEXT"
|
||||||
",dupTimerExpires INT"
|
",dupTimerExpires INT"
|
||||||
")";
|
")";
|
||||||
result = sqlite3_exec( pDb, createGamesStr, NULL, NULL, NULL );
|
result = sqlite3_exec( pDb, createGamesStr, NULL, NULL, NULL );
|
||||||
|
@ -161,17 +165,17 @@ void
|
||||||
writeToDB( XWStreamCtxt* stream, void* closure )
|
writeToDB( XWStreamCtxt* stream, void* closure )
|
||||||
{
|
{
|
||||||
CommonGlobals* cGlobals = (CommonGlobals*)closure;
|
CommonGlobals* cGlobals = (CommonGlobals*)closure;
|
||||||
sqlite3_int64 selRow = cGlobals->selRow;
|
sqlite3_int64 selRow = cGlobals->rowid;
|
||||||
sqlite3* pDb = cGlobals->params->pDb;
|
sqlite3* pDb = cGlobals->params->pDb;
|
||||||
|
|
||||||
XP_Bool newGame = -1 == selRow;
|
XP_Bool newGame = -1 == selRow;
|
||||||
selRow = writeBlobColumnStream( stream, pDb, selRow, "game" );
|
selRow = writeBlobColumnStream( stream, pDb, selRow, "game" );
|
||||||
|
|
||||||
if ( newGame ) { /* new row; need to insert blob first */
|
if ( newGame ) { /* new row; need to insert blob first */
|
||||||
cGlobals->selRow = selRow;
|
cGlobals->rowid = selRow;
|
||||||
XP_LOGF( "%s(): new game at row %lld", __func__, selRow );
|
XP_LOGF( "%s(): new game at row %lld", __func__, selRow );
|
||||||
} else {
|
} else {
|
||||||
assert( selRow == cGlobals->selRow );
|
assert( selRow == cGlobals->rowid );
|
||||||
}
|
}
|
||||||
|
|
||||||
(*cGlobals->onSave)( cGlobals->onSaveClosure, selRow, newGame );
|
(*cGlobals->onSave)( cGlobals->onSaveClosure, selRow, newGame );
|
||||||
|
@ -193,8 +197,8 @@ addSnapshot( CommonGlobals* cGlobals )
|
||||||
cGlobals->params->vtMgr );
|
cGlobals->params->vtMgr );
|
||||||
getImage( dctx, stream );
|
getImage( dctx, stream );
|
||||||
removeSurface( dctx );
|
removeSurface( dctx );
|
||||||
cGlobals->selRow = writeBlobColumnStream( stream, cGlobals->params->pDb,
|
cGlobals->rowid = writeBlobColumnStream( stream, cGlobals->params->pDb,
|
||||||
cGlobals->selRow, "snap" );
|
cGlobals->rowid, "snap" );
|
||||||
stream_destroy( stream );
|
stream_destroy( stream );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,8 +219,11 @@ summarize( CommonGlobals* cGlobals )
|
||||||
XP_U32 lastMoveTime = server_getLastMoveTime( game->server );
|
XP_U32 lastMoveTime = server_getLastMoveTime( game->server );
|
||||||
XP_U16 seed = 0;
|
XP_U16 seed = 0;
|
||||||
XP_S16 nMissing = 0;
|
XP_S16 nMissing = 0;
|
||||||
XP_U16 nTotal = cGlobals->gi->nPlayers;
|
XP_U16 nPending = 0;
|
||||||
XP_U32 gameID = cGlobals->gi->gameID;
|
const CurGameInfo* gi = cGlobals->gi;
|
||||||
|
XP_U16 nTotal = gi->nPlayers;
|
||||||
|
XP_U32 gameID = gi->gameID;
|
||||||
|
XP_LangCode dictLang = gi->dictLang;
|
||||||
XP_ASSERT( 0 != gameID );
|
XP_ASSERT( 0 != gameID );
|
||||||
CommsAddrRec addr = {0};
|
CommsAddrRec addr = {0};
|
||||||
gchar* room = "";
|
gchar* room = "";
|
||||||
|
@ -225,6 +232,24 @@ summarize( CommonGlobals* cGlobals )
|
||||||
gchar connvia[128] = {0};
|
gchar connvia[128] = {0};
|
||||||
XP_UCHAR relayID[32] = {0};
|
XP_UCHAR relayID[32] = {0};
|
||||||
|
|
||||||
|
ScoresArray scores = {0};
|
||||||
|
if ( gameOver ) {
|
||||||
|
model_figureFinalScores( game->model, &scores, NULL );
|
||||||
|
} else {
|
||||||
|
for ( int ii = 0; ii < nTotal; ++ii ) {
|
||||||
|
scores.arr[ii] = model_getPlayerScore( game->model, ii );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gchar scoreBufs[MAX_NUM_PLAYERS][64] = {0};
|
||||||
|
gchar* arr[MAX_NUM_PLAYERS+1] = {0};
|
||||||
|
for ( int ii = 0; ii < nTotal; ++ii ) {
|
||||||
|
XP_SNPRINTF( scoreBufs[ii], VSIZE(scoreBufs[ii]), "%s: %d",
|
||||||
|
gi->players[ii].name, scores.arr[ii] );
|
||||||
|
arr[ii] = scoreBufs[ii];
|
||||||
|
}
|
||||||
|
gchar* scoresStr = g_strjoinv( "; ", arr );
|
||||||
|
XP_LOGF( "%s(): scoresStr: %s", __func__, scoresStr );
|
||||||
|
|
||||||
if ( !!game->comms ) {
|
if ( !!game->comms ) {
|
||||||
nMissing = server_getMissingPlayers( game->server );
|
nMissing = server_getMissingPlayers( game->server );
|
||||||
comms_getAddr( game->comms, &addr );
|
comms_getAddr( game->comms, &addr );
|
||||||
|
@ -255,19 +280,21 @@ summarize( CommonGlobals* cGlobals )
|
||||||
seed = comms_getChannelSeed( game->comms );
|
seed = comms_getChannelSeed( game->comms );
|
||||||
XP_U16 len = VSIZE(relayID);
|
XP_U16 len = VSIZE(relayID);
|
||||||
(void)comms_getRelayID( game->comms, relayID, &len );
|
(void)comms_getRelayID( game->comms, relayID, &len );
|
||||||
|
|
||||||
|
nPending = comms_countPendingPackets( game->comms );
|
||||||
} else {
|
} else {
|
||||||
strcat( connvia, "local" );
|
strcat( connvia, "local" );
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* fmt = "UPDATE games "
|
const char* fmt = "UPDATE games "
|
||||||
" SET room='%s', ended=%d, turn=%d, local=%d, ntotal=%d, "
|
" SET room='%s', ended=%d, turn=%d, local=%d, ntotal=%d, "
|
||||||
" nmissing=%d, nmoves=%d, seed=%d, gameid=%d, connvia='%s', "
|
" nmissing=%d, nmoves=%d, seed=%d, dictlang=%d, gameid=%d, connvia='%s', "
|
||||||
" relayid='%s', lastMoveTime=%d"
|
" relayid='%s', lastMoveTime=%d, scores='%s', nPending=%d, role=%d"
|
||||||
" WHERE rowid=%lld";
|
" WHERE rowid=%lld";
|
||||||
XP_UCHAR buf[256];
|
XP_UCHAR buf[2*256];
|
||||||
snprintf( buf, sizeof(buf), fmt, room, gameOver?1:0, turn, isLocal?1:0,
|
snprintf( buf, sizeof(buf), fmt, room, gameOver?1:0, turn, isLocal?1:0,
|
||||||
nTotal, nMissing, nMoves, seed, gameID, connvia, relayID, lastMoveTime,
|
nTotal, nMissing, nMoves, seed, dictLang, gameID, connvia, relayID, lastMoveTime,
|
||||||
cGlobals->selRow );
|
scoresStr, nPending, gi->serverRole, cGlobals->rowid );
|
||||||
XP_LOGF( "query: %s", buf );
|
XP_LOGF( "query: %s", buf );
|
||||||
sqlite3_stmt* stmt = NULL;
|
sqlite3_stmt* stmt = NULL;
|
||||||
int result = sqlite3_prepare_v2( cGlobals->params->pDb, buf, -1, &stmt, NULL );
|
int result = sqlite3_prepare_v2( cGlobals->params->pDb, buf, -1, &stmt, NULL );
|
||||||
|
@ -283,6 +310,7 @@ summarize( CommonGlobals* cGlobals )
|
||||||
if ( !cGlobals->params->useCurses ) {
|
if ( !cGlobals->params->useCurses ) {
|
||||||
addSnapshot( cGlobals );
|
addSnapshot( cGlobals );
|
||||||
}
|
}
|
||||||
|
g_free( scoresStr );
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList*
|
GSList*
|
||||||
|
@ -370,7 +398,7 @@ getGameInfo( sqlite3* pDb, sqlite3_int64 rowid, GameInfo* gib )
|
||||||
{
|
{
|
||||||
XP_Bool success = XP_FALSE;
|
XP_Bool success = XP_FALSE;
|
||||||
const char* fmt = "SELECT room, ended, turn, local, nmoves, ntotal, nmissing, "
|
const char* fmt = "SELECT room, ended, turn, local, nmoves, ntotal, nmissing, "
|
||||||
"seed, connvia, gameid, lastMoveTime, relayid, snap "
|
"dictlang, seed, connvia, gameid, lastMoveTime, relayid, scores, nPending, role, snap "
|
||||||
"FROM games WHERE rowid = %lld";
|
"FROM games WHERE rowid = %lld";
|
||||||
XP_UCHAR query[256];
|
XP_UCHAR query[256];
|
||||||
snprintf( query, sizeof(query), fmt, rowid );
|
snprintf( query, sizeof(query), fmt, rowid );
|
||||||
|
@ -384,12 +412,14 @@ getGameInfo( sqlite3* pDb, sqlite3_int64 rowid, GameInfo* gib )
|
||||||
int col = 0;
|
int col = 0;
|
||||||
int len = sizeof(gib->room);
|
int len = sizeof(gib->room);
|
||||||
getColumnText( ppStmt, col++, gib->room, &len );
|
getColumnText( ppStmt, col++, gib->room, &len );
|
||||||
|
gib->rowid = rowid;
|
||||||
gib->gameOver = 1 == sqlite3_column_int( ppStmt, col++ );
|
gib->gameOver = 1 == sqlite3_column_int( ppStmt, col++ );
|
||||||
gib->turn = sqlite3_column_int( ppStmt, col++ );
|
gib->turn = sqlite3_column_int( ppStmt, col++ );
|
||||||
gib->turnLocal = 1 == sqlite3_column_int( ppStmt, col++ );
|
gib->turnLocal = 1 == sqlite3_column_int( ppStmt, col++ );
|
||||||
gib->nMoves = sqlite3_column_int( ppStmt, col++ );
|
gib->nMoves = sqlite3_column_int( ppStmt, col++ );
|
||||||
gib->nTotal = sqlite3_column_int( ppStmt, col++ );
|
gib->nTotal = sqlite3_column_int( ppStmt, col++ );
|
||||||
gib->nMissing = sqlite3_column_int( ppStmt, col++ );
|
gib->nMissing = sqlite3_column_int( ppStmt, col++ );
|
||||||
|
gib->dictLang = sqlite3_column_int( ppStmt, col++ );
|
||||||
gib->seed = sqlite3_column_int( ppStmt, col++ );
|
gib->seed = sqlite3_column_int( ppStmt, col++ );
|
||||||
len = sizeof(gib->conn);
|
len = sizeof(gib->conn);
|
||||||
getColumnText( ppStmt, col++, gib->conn, &len );
|
getColumnText( ppStmt, col++, gib->conn, &len );
|
||||||
|
@ -397,6 +427,10 @@ getGameInfo( sqlite3* pDb, sqlite3_int64 rowid, GameInfo* gib )
|
||||||
gib->lastMoveTime = sqlite3_column_int( ppStmt, col++ );
|
gib->lastMoveTime = sqlite3_column_int( ppStmt, col++ );
|
||||||
len = sizeof(gib->relayID);
|
len = sizeof(gib->relayID);
|
||||||
getColumnText( ppStmt, col++, gib->relayID, &len );
|
getColumnText( ppStmt, col++, gib->relayID, &len );
|
||||||
|
len = sizeof(gib->scores);
|
||||||
|
getColumnText( ppStmt, col++, gib->scores, &len );
|
||||||
|
gib->nPending = sqlite3_column_int( ppStmt, col++ );
|
||||||
|
gib->role = sqlite3_column_int( ppStmt, col++ );
|
||||||
snprintf( gib->name, sizeof(gib->name), "Game %lld", rowid );
|
snprintf( gib->name, sizeof(gib->name), "Game %lld", rowid );
|
||||||
|
|
||||||
#ifdef PLATFORM_GTK
|
#ifdef PLATFORM_GTK
|
||||||
|
@ -533,8 +567,11 @@ db_fetch( sqlite3* pDb, const gchar* key, gchar* buf, gint* buflen )
|
||||||
XP_ASSERT( !!pDb );
|
XP_ASSERT( !!pDb );
|
||||||
FetchResult result = NOT_THERE;
|
FetchResult result = NOT_THERE;
|
||||||
char query[256];
|
char query[256];
|
||||||
int len = snprintf( query, sizeof(query),
|
#ifdef DEBUG
|
||||||
"SELECT value from pairs where key = '%s'", key );
|
int len =
|
||||||
|
#endif
|
||||||
|
snprintf( query, sizeof(query),
|
||||||
|
"SELECT value from pairs where key = '%s'", key );
|
||||||
XP_ASSERT( len < sizeof(query) );
|
XP_ASSERT( len < sizeof(query) );
|
||||||
sqlite3_stmt *ppStmt;
|
sqlite3_stmt *ppStmt;
|
||||||
int sqlResult = sqlite3_prepare_v2( pDb, query, -1, &ppStmt, NULL );
|
int sqlResult = sqlite3_prepare_v2( pDb, query, -1, &ppStmt, NULL );
|
||||||
|
|
|
@ -28,13 +28,16 @@
|
||||||
#include "comtypes.h"
|
#include "comtypes.h"
|
||||||
|
|
||||||
typedef struct _GameInfo {
|
typedef struct _GameInfo {
|
||||||
|
sqlite3_int64 rowid;
|
||||||
XP_UCHAR name[128];
|
XP_UCHAR name[128];
|
||||||
XP_UCHAR room[128];
|
XP_UCHAR room[128];
|
||||||
XP_UCHAR conn[128];
|
XP_UCHAR conn[128];
|
||||||
|
XP_UCHAR scores[128];
|
||||||
XP_UCHAR relayID[32];
|
XP_UCHAR relayID[32];
|
||||||
#ifdef PLATFORM_GTK
|
#ifdef PLATFORM_GTK
|
||||||
GdkPixbuf* snap;
|
GdkPixbuf* snap;
|
||||||
#endif
|
#endif
|
||||||
|
XP_LangCode dictLang;
|
||||||
XP_U32 gameID;
|
XP_U32 gameID;
|
||||||
XP_S16 nMoves;
|
XP_S16 nMoves;
|
||||||
XP_Bool gameOver;
|
XP_Bool gameOver;
|
||||||
|
@ -43,7 +46,9 @@ typedef struct _GameInfo {
|
||||||
XP_U16 nTotal;
|
XP_U16 nTotal;
|
||||||
XP_S16 nMissing;
|
XP_S16 nMissing;
|
||||||
XP_U16 seed;
|
XP_U16 seed;
|
||||||
|
XP_U16 nPending;
|
||||||
XP_U32 lastMoveTime;
|
XP_U32 lastMoveTime;
|
||||||
|
XP_U16 role;
|
||||||
} GameInfo;
|
} GameInfo;
|
||||||
|
|
||||||
sqlite3* openGamesDB( const char* dbName );
|
sqlite3* openGamesDB( const char* dbName );
|
||||||
|
|
183
xwords4/linux/gsrcwrap.c
Normal file
183
xwords4/linux/gsrcwrap.c
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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
|
||||||
|
* 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 <glib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "gsrcwrap.h"
|
||||||
|
#include "xptypes.h"
|
||||||
|
#include "comtypes.h"
|
||||||
|
|
||||||
|
#define TAG __FILE__ ": "
|
||||||
|
|
||||||
|
typedef struct _WrapperState {
|
||||||
|
union {
|
||||||
|
GSourceFunc srcProc;
|
||||||
|
GIOFunc ioProc;
|
||||||
|
} proc;
|
||||||
|
void* data;
|
||||||
|
const char* caller;
|
||||||
|
const char* procName;
|
||||||
|
struct timespec spec;
|
||||||
|
} WrapperState;
|
||||||
|
|
||||||
|
static GSList* s_idleProcs = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
printElapsedFor( struct timespec* first, struct timespec* second,
|
||||||
|
const char* XP_UNUSED_DBG(proc),
|
||||||
|
const char* XP_UNUSED_DBG(action) )
|
||||||
|
/* time_t tv_sec; /\* seconds *\/ */
|
||||||
|
/* long tv_nsec; /\* nanoseconds *\/ */
|
||||||
|
{
|
||||||
|
time_t secs = second->tv_sec - first->tv_sec;
|
||||||
|
long nsecs = second->tv_nsec - first->tv_nsec;
|
||||||
|
while ( nsecs < 0 ) {
|
||||||
|
++secs;
|
||||||
|
nsecs += 1000000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* float firstSecs = (float)first->tv_sec + (((float)first->tv_nsec)/1000000000.0f); */
|
||||||
|
/* float secondSecs = (float)second->tv_sec + (((float)second->tv_nsec)/1000000000.0f); */
|
||||||
|
XP_LOGF( TAG "elapsed %s %s(): %ld.%ld", action, proc, secs, nsecs );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gint
|
||||||
|
idle_wrapper( gpointer data )
|
||||||
|
{
|
||||||
|
WrapperState* state = (WrapperState*)data;
|
||||||
|
XP_LOGF( TAG "%s(): CALLED for %s", __func__, state->procName );
|
||||||
|
|
||||||
|
struct timespec callTime;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &callTime);
|
||||||
|
printElapsedFor( &state->spec, &callTime, state->procName, "scheduling" );
|
||||||
|
|
||||||
|
gint result = (*state->proc.srcProc)(state->data);
|
||||||
|
|
||||||
|
struct timespec returnTime;
|
||||||
|
clock_gettime( CLOCK_REALTIME, &returnTime );
|
||||||
|
|
||||||
|
printElapsedFor( &callTime, &returnTime, state->procName, "running" );
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
const char* procName = state->procName;
|
||||||
|
#endif
|
||||||
|
if ( 0 == result ) { /* won't be getting called again */
|
||||||
|
s_idleProcs = g_slist_remove( s_idleProcs, state );
|
||||||
|
g_free( state );
|
||||||
|
}
|
||||||
|
|
||||||
|
XP_LOGF( TAG "%s(): DONE for %s; now have %d", __func__, procName,
|
||||||
|
g_slist_length(s_idleProcs) );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
_wrapIdle( GSourceFunc function, gpointer data,
|
||||||
|
const char* procName, const char* caller )
|
||||||
|
{
|
||||||
|
XP_LOGF( TAG "%s(): installing proc %s from caller %s", __func__,
|
||||||
|
procName, caller );
|
||||||
|
WrapperState* state = g_malloc0( sizeof(*state) );
|
||||||
|
s_idleProcs = g_slist_append( s_idleProcs, state );
|
||||||
|
state->proc.srcProc = function;
|
||||||
|
state->data = data;
|
||||||
|
state->caller = caller;
|
||||||
|
state->procName = procName;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &state->spec);
|
||||||
|
|
||||||
|
guint res = g_idle_add( idle_wrapper, state );
|
||||||
|
XP_LOGF( TAG "%s(): added idle for %s; now have %d", __func__,
|
||||||
|
procName, g_slist_length(s_idleProcs) );
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TRY_ONE(FLAG) \
|
||||||
|
if ((condition & FLAG) == FLAG) { \
|
||||||
|
offset += snprintf( &buf[offset], len - offset, #FLAG " " ); \
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
formatFlags( char* buf, size_t len, GIOCondition condition )
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
TRY_ONE(G_IO_IN);
|
||||||
|
TRY_ONE(G_IO_HUP);
|
||||||
|
TRY_ONE(G_IO_ERR);
|
||||||
|
TRY_ONE(G_IO_PRI);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
watch_wrapper( GIOChannel* source, GIOCondition condition, gpointer data )
|
||||||
|
{
|
||||||
|
WrapperState* state = (WrapperState*)data;
|
||||||
|
|
||||||
|
char buf[128] = {0};
|
||||||
|
formatFlags( buf, VSIZE(buf), condition );
|
||||||
|
XP_LOGF( TAG "%s(%s): CALLED; flags: %s", __func__, state->procName, buf );
|
||||||
|
|
||||||
|
struct timespec callTime;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &callTime);
|
||||||
|
|
||||||
|
bool keep = (*state->proc.ioProc)(source, condition, state->data);
|
||||||
|
|
||||||
|
struct timespec returnTime;
|
||||||
|
clock_gettime( CLOCK_REALTIME, &returnTime );
|
||||||
|
|
||||||
|
printElapsedFor( &callTime, &returnTime, state->procName, "running" );
|
||||||
|
|
||||||
|
XP_LOGF( TAG "%s(%s): DONE", __func__, state->procName );
|
||||||
|
|
||||||
|
if ( 0 == keep ) { /* won't be getting called again */
|
||||||
|
// g_source_destroy( source );
|
||||||
|
g_free( state );
|
||||||
|
}
|
||||||
|
return keep;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
_wrapWatch( gpointer data, int socket, GIOFunc ioProc,
|
||||||
|
const char* procName, const char* caller )
|
||||||
|
{
|
||||||
|
XP_LOGF( TAG "%s(): installing proc %s from caller %s", __func__,
|
||||||
|
procName, caller );
|
||||||
|
|
||||||
|
WrapperState* state = g_malloc0( sizeof(*state) );
|
||||||
|
state->proc.ioProc = ioProc;
|
||||||
|
state->data = data;
|
||||||
|
state->caller = caller;
|
||||||
|
state->procName = procName;
|
||||||
|
|
||||||
|
GIOChannel* channel = g_io_channel_unix_new( socket );
|
||||||
|
guint watch = g_io_add_watch( channel,
|
||||||
|
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI,
|
||||||
|
watch_wrapper, state );
|
||||||
|
g_io_channel_unref( channel ); /* only main loop holds it now */
|
||||||
|
|
||||||
|
XP_LOGF( TAG "%s(): added watch for %s", __func__, procName );
|
||||||
|
return watch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gsw_logIdles()
|
||||||
|
{
|
||||||
|
XP_LOGF( TAG "%s(): %d idles pending", __func__, g_slist_length(s_idleProcs) );
|
||||||
|
}
|
37
xwords4/linux/gsrcwrap.h
Normal file
37
xwords4/linux/gsrcwrap.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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
|
||||||
|
* 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 _GSRCWRAP_H_
|
||||||
|
#define _GSRCWRAP_H_
|
||||||
|
|
||||||
|
guint _wrapIdle( GSourceFunc function, gpointer data, const char* procName,
|
||||||
|
const char* caller );
|
||||||
|
guint _wrapWatch( gpointer data, int socket, GIOFunc func,
|
||||||
|
const char* procName, const char* caller );
|
||||||
|
|
||||||
|
void gsw_logIdles();
|
||||||
|
|
||||||
|
#define ADD_ONETIME_IDLE( PROC, CLOSURE ) \
|
||||||
|
_wrapIdle( PROC, CLOSURE, #PROC, __func__ )
|
||||||
|
|
||||||
|
#define ADD_SOCKET( CLOSURE, SOCKET, PROC ) \
|
||||||
|
_wrapWatch( CLOSURE, SOCKET, PROC, #PROC, __func__ )
|
||||||
|
|
||||||
|
#endif
|
|
@ -323,10 +323,11 @@ relay_status_gtk( void* closure, CommsRelayState state )
|
||||||
{
|
{
|
||||||
XP_LOGF( "%s got status: %s", __func__, CommsRelayState2Str(state) );
|
XP_LOGF( "%s got status: %s", __func__, CommsRelayState2Str(state) );
|
||||||
GtkGameGlobals* globals = (GtkGameGlobals*)closure;
|
GtkGameGlobals* globals = (GtkGameGlobals*)closure;
|
||||||
if ( !!globals->draw ) {
|
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||||
globals->cGlobals.state = state;
|
if ( !!cGlobals->draw ) {
|
||||||
|
cGlobals->state = state;
|
||||||
globals->stateChar = 'A' + COMMS_RELAYSTATE_ALLCONNECTED - state;
|
globals->stateChar = 'A' + COMMS_RELAYSTATE_ALLCONNECTED - state;
|
||||||
draw_gtk_status( globals->draw, globals->stateChar );
|
draw_gtk_status( (GtkDrawCtx*)cGlobals->draw, globals->stateChar );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,10 +420,11 @@ relay_sendNoConn_gtk( const XP_U8* msg, XP_U16 len,
|
||||||
{
|
{
|
||||||
GtkGameGlobals* globals = (GtkGameGlobals*)closure;
|
GtkGameGlobals* globals = (GtkGameGlobals*)closure;
|
||||||
XP_Bool success = XP_FALSE;
|
XP_Bool success = XP_FALSE;
|
||||||
LaunchParams* params = globals->cGlobals.params;
|
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||||
if ( params->useUdp && !globals->draw ) {
|
LaunchParams* params = cGlobals->params;
|
||||||
XP_U16 seed = comms_getChannelSeed( globals->cGlobals.game.comms );
|
if ( params->useUdp && !cGlobals->draw ) {
|
||||||
XP_U32 clientToken = makeClientToken( globals->cGlobals.selRow, seed );
|
XP_U16 seed = comms_getChannelSeed( cGlobals->game.comms );
|
||||||
|
XP_U32 clientToken = makeClientToken( cGlobals->rowid, seed );
|
||||||
XP_S16 nSent = relaycon_sendnoconn( params, msg, len, relayID,
|
XP_S16 nSent = relaycon_sendnoconn( params, msg, len, relayID,
|
||||||
clientToken );
|
clientToken );
|
||||||
success = nSent == len;
|
success = nSent == len;
|
||||||
|
@ -430,18 +432,6 @@ relay_sendNoConn_gtk( const XP_U8* msg, XP_U16 len,
|
||||||
return success;
|
return success;
|
||||||
} /* relay_sendNoConn_gtk */
|
} /* relay_sendNoConn_gtk */
|
||||||
|
|
||||||
static void
|
|
||||||
tryConnectToServer(CommonGlobals* cGlobals)
|
|
||||||
{
|
|
||||||
LaunchParams* params = cGlobals->params;
|
|
||||||
XWStreamCtxt* stream =
|
|
||||||
mem_stream_make( MPPARM(cGlobals->util->mpool) params->vtMgr,
|
|
||||||
cGlobals, CHANNEL_NONE,
|
|
||||||
sendOnClose );
|
|
||||||
(void)server_initClientConnection( cGlobals->game.server,
|
|
||||||
stream );
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RELAY_VIA_HTTP
|
#ifdef RELAY_VIA_HTTP
|
||||||
static void
|
static void
|
||||||
onJoined( void* closure, const XP_UCHAR* connname, XWHostID hid )
|
onJoined( void* closure, const XP_UCHAR* connname, XWHostID hid )
|
||||||
|
@ -478,7 +468,7 @@ gtk_getFlags( void* closure )
|
||||||
XP_USE( globals );
|
XP_USE( globals );
|
||||||
return COMMS_XPORT_FLAGS_HASNOCONN;
|
return COMMS_XPORT_FLAGS_HASNOCONN;
|
||||||
# else
|
# else
|
||||||
return (!!globals->draw) ? COMMS_XPORT_FLAGS_NONE
|
return (!!globals->cGlobals.draw) ? COMMS_XPORT_FLAGS_NONE
|
||||||
: COMMS_XPORT_FLAGS_HASNOCONN;
|
: COMMS_XPORT_FLAGS_HASNOCONN;
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
@ -584,167 +574,25 @@ addDropChecks( GtkGameGlobals* globals )
|
||||||
static void
|
static void
|
||||||
createOrLoadObjects( GtkGameGlobals* globals )
|
createOrLoadObjects( GtkGameGlobals* globals )
|
||||||
{
|
{
|
||||||
XWStreamCtxt* stream = NULL;
|
|
||||||
XP_Bool opened = XP_FALSE;
|
|
||||||
|
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
#endif
|
#endif
|
||||||
CommonGlobals* cGlobals = &globals->cGlobals;
|
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||||
LaunchParams* params = cGlobals->params;
|
LaunchParams* params = cGlobals->params;
|
||||||
|
|
||||||
globals->draw = (GtkDrawCtx*)gtkDrawCtxtMake( globals->drawing_area,
|
cGlobals->draw = gtkDrawCtxtMake( globals->drawing_area,
|
||||||
globals );
|
globals );
|
||||||
|
|
||||||
TransportProcs procs;
|
TransportProcs procs;
|
||||||
setTransportProcs( &procs, globals );
|
setTransportProcs( &procs, globals );
|
||||||
|
linuxOpenGame( cGlobals, &procs );
|
||||||
if ( !!params->fileName && file_exists( params->fileName ) ) {
|
|
||||||
stream = streamFromFile( cGlobals, params->fileName );
|
|
||||||
#ifdef USE_SQLITE
|
|
||||||
} else if ( !!params->dbFileName && file_exists( params->dbFileName ) ) {
|
|
||||||
XP_UCHAR buf[32];
|
|
||||||
XP_SNPRINTF( buf, sizeof(buf), "%d", params->dbFileID );
|
|
||||||
mpool_setTag( MEMPOOL buf );
|
|
||||||
stream = streamFromDB( cGlobals );
|
|
||||||
#endif
|
|
||||||
} else if ( !!params->pDb && 0 <= cGlobals->selRow ) {
|
|
||||||
stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool)
|
|
||||||
params->vtMgr );
|
|
||||||
if ( !loadGame( stream, params->pDb, cGlobals->selRow ) ) {
|
|
||||||
stream_destroy( stream );
|
|
||||||
stream = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !!stream ) {
|
|
||||||
if ( NULL == cGlobals->dict ) {
|
|
||||||
cGlobals->dict = makeDictForStream( cGlobals, stream );
|
|
||||||
}
|
|
||||||
|
|
||||||
opened = game_makeFromStream( MEMPOOL stream, &cGlobals->game,
|
|
||||||
cGlobals->gi, cGlobals->dict,
|
|
||||||
&cGlobals->dicts, cGlobals->util,
|
|
||||||
(DrawCtx*)globals->draw,
|
|
||||||
&cGlobals->cp, &procs );
|
|
||||||
XP_LOGF( "%s: loaded gi at %p", __func__, &cGlobals->gi );
|
|
||||||
stream_destroy( stream );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !opened ) {
|
|
||||||
CommsAddrRec addr = cGlobals->addr;
|
|
||||||
|
|
||||||
/* XP_MEMSET( &addr, 0, sizeof(addr) ); */
|
|
||||||
/* addr.conType = cGlobals->addr.conType; */
|
|
||||||
|
|
||||||
#ifdef XWFEATURE_RELAY
|
|
||||||
/* if ( addr.conType == COMMS_CONN_RELAY ) { */
|
|
||||||
/* XP_ASSERT( !!params->connInfo.relay.relayName ); */
|
|
||||||
/* globals->cGlobals.defaultServerName */
|
|
||||||
/* = params->connInfo.relay.relayName; */
|
|
||||||
/* } */
|
|
||||||
#endif
|
|
||||||
game_makeNewGame( MEMPOOL &cGlobals->game, cGlobals->gi,
|
|
||||||
cGlobals->util, (DrawCtx*)globals->draw,
|
|
||||||
&cGlobals->cp, &procs
|
|
||||||
#ifdef SET_GAMESEED
|
|
||||||
, params->gameSeed
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
// addr.conType = params->conType;
|
|
||||||
CommsConnType typ;
|
|
||||||
for ( XP_U32 st = 0; addr_iter( &addr, &typ, &st ); ) {
|
|
||||||
if ( params->commsDisableds[typ][0] ) {
|
|
||||||
comms_setAddrDisabled( cGlobals->game.comms, typ, XP_FALSE, XP_TRUE );
|
|
||||||
}
|
|
||||||
if ( params->commsDisableds[typ][1] ) {
|
|
||||||
comms_setAddrDisabled( cGlobals->game.comms, typ, XP_TRUE, XP_TRUE );
|
|
||||||
}
|
|
||||||
switch( typ ) {
|
|
||||||
#ifdef XWFEATURE_RELAY
|
|
||||||
case COMMS_CONN_RELAY:
|
|
||||||
/* addr.u.ip_relay.ipAddr = 0; */
|
|
||||||
/* addr.u.ip_relay.port = params->connInfo.relay.defaultSendPort; */
|
|
||||||
/* addr.u.ip_relay.seeksPublicRoom = params->connInfo.relay.seeksPublicRoom; */
|
|
||||||
/* addr.u.ip_relay.advertiseRoom = params->connInfo.relay.advertiseRoom; */
|
|
||||||
/* XP_STRNCPY( addr.u.ip_relay.hostName, params->connInfo.relay.relayName, */
|
|
||||||
/* sizeof(addr.u.ip_relay.hostName) - 1 ); */
|
|
||||||
/* XP_STRNCPY( addr.u.ip_relay.invite, params->connInfo.relay.invite, */
|
|
||||||
/* sizeof(addr.u.ip_relay.invite) - 1 ); */
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
|
||||||
case COMMS_CONN_BT:
|
|
||||||
XP_ASSERT( sizeof(addr.u.bt.btAddr)
|
|
||||||
>= sizeof(params->connInfo.bt.hostAddr));
|
|
||||||
XP_MEMCPY( &addr.u.bt.btAddr, ¶ms->connInfo.bt.hostAddr,
|
|
||||||
sizeof(params->connInfo.bt.hostAddr) );
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef XWFEATURE_IP_DIRECT
|
|
||||||
case COMMS_CONN_IP_DIRECT:
|
|
||||||
XP_STRNCPY( addr.u.ip.hostName_ip, params->connInfo.ip.hostName,
|
|
||||||
sizeof(addr.u.ip.hostName_ip) - 1 );
|
|
||||||
addr.u.ip.port_ip = params->connInfo.ip.port;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef XWFEATURE_SMS
|
|
||||||
case COMMS_CONN_SMS:
|
|
||||||
/* No! Don't overwrite what may be a return address with local
|
|
||||||
stuff */
|
|
||||||
/* XP_STRNCPY( addr.u.sms.phone, params->connInfo.sms.phone, */
|
|
||||||
/* sizeof(addr.u.sms.phone) - 1 ); */
|
|
||||||
/* addr.u.sms.port = params->connInfo.sms.port; */
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Need to save in order to have a valid selRow for the first send */
|
|
||||||
saveGame( cGlobals );
|
|
||||||
|
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
||||||
/* This may trigger network activity */
|
|
||||||
if ( !!cGlobals->game.comms ) {
|
|
||||||
comms_setAddr( cGlobals->game.comms, &addr );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
model_setDictionary( cGlobals->game.model, cGlobals->dict );
|
|
||||||
setSquareBonuses( cGlobals );
|
|
||||||
model_setPlayerDicts( cGlobals->game.model, &cGlobals->dicts );
|
|
||||||
|
|
||||||
#ifdef XWFEATURE_SEARCHLIMIT
|
|
||||||
cGlobals->gi->allowHintRect = params->allowHintRect;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( params->needsNewGame ) {
|
|
||||||
new_game_impl( globals, XP_FALSE );
|
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
||||||
} else {
|
|
||||||
DeviceRole serverRole = cGlobals->gi->serverRole;
|
|
||||||
if ( serverRole == SERVER_ISCLIENT ) {
|
|
||||||
tryConnectToServer( cGlobals );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !params->fileName && !!params->dbName ) {
|
if ( !params->fileName && !!params->dbName ) {
|
||||||
XP_UCHAR buf[64];
|
XP_UCHAR buf[64];
|
||||||
snprintf( buf, sizeof(buf), "%s / %lld", params->dbName,
|
snprintf( buf, sizeof(buf), "%s / %lld", params->dbName,
|
||||||
cGlobals->selRow );
|
cGlobals->rowid );
|
||||||
gtk_window_set_title( GTK_WINDOW(globals->window), buf );
|
gtk_window_set_title( GTK_WINDOW(globals->window), buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
||||||
if ( !!globals->cGlobals.game.comms ) {
|
|
||||||
comms_start( globals->cGlobals.game.comms );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
server_do( globals->cGlobals.game.server );
|
|
||||||
saveGame( cGlobals ); /* again, to include address etc. */
|
|
||||||
|
|
||||||
addDropChecks( globals );
|
addDropChecks( globals );
|
||||||
disenable_buttons( globals );
|
disenable_buttons( globals );
|
||||||
|
@ -758,11 +606,11 @@ configure_event( GtkWidget* widget, GdkEventConfigure* XP_UNUSED(event),
|
||||||
GtkGameGlobals* globals )
|
GtkGameGlobals* globals )
|
||||||
{
|
{
|
||||||
globals->gridOn = XP_TRUE;
|
globals->gridOn = XP_TRUE;
|
||||||
if ( globals->draw == NULL ) {
|
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||||
|
if ( cGlobals->draw == NULL ) {
|
||||||
createOrLoadObjects( globals );
|
createOrLoadObjects( globals );
|
||||||
}
|
}
|
||||||
|
|
||||||
CommonGlobals* cGlobals = &globals->cGlobals;
|
|
||||||
BoardCtxt* board = cGlobals->game.board;
|
BoardCtxt* board = cGlobals->game.board;
|
||||||
|
|
||||||
GtkAllocation alloc;
|
GtkAllocation alloc;
|
||||||
|
@ -796,7 +644,7 @@ destroy_board_window( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
|
||||||
if ( !!globals->cGlobals.game.comms ) {
|
if ( !!globals->cGlobals.game.comms ) {
|
||||||
comms_stop( globals->cGlobals.game.comms );
|
comms_stop( globals->cGlobals.game.comms );
|
||||||
}
|
}
|
||||||
saveGame( &globals->cGlobals );
|
linuxSaveGame( &globals->cGlobals );
|
||||||
windowDestroyed( globals );
|
windowDestroyed( globals );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,7 +662,7 @@ on_board_window_shown( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
|
||||||
/* If it has pending invite info, send the invitation! */
|
/* If it has pending invite info, send the invitation! */
|
||||||
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool)
|
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool)
|
||||||
cGlobals->params->vtMgr );
|
cGlobals->params->vtMgr );
|
||||||
if ( loadInviteAddrs( stream, cGlobals->params->pDb, cGlobals->selRow ) ) {
|
if ( loadInviteAddrs( stream, cGlobals->params->pDb, cGlobals->rowid ) ) {
|
||||||
CommsAddrRec addr = {0};
|
CommsAddrRec addr = {0};
|
||||||
addrFromStream( &addr, stream );
|
addrFromStream( &addr, stream );
|
||||||
comms_setAddr( cGlobals->game.comms, &addr );
|
comms_setAddr( cGlobals->game.comms, &addr );
|
||||||
|
@ -840,7 +688,7 @@ static void
|
||||||
cleanup( GtkGameGlobals* globals )
|
cleanup( GtkGameGlobals* globals )
|
||||||
{
|
{
|
||||||
CommonGlobals* cGlobals = &globals->cGlobals;
|
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||||
saveGame( cGlobals );
|
linuxSaveGame( cGlobals );
|
||||||
if ( 0 < globals->idleID ) {
|
if ( 0 < globals->idleID ) {
|
||||||
g_source_remove( globals->idleID );
|
g_source_remove( globals->idleID );
|
||||||
}
|
}
|
||||||
|
@ -955,7 +803,7 @@ new_game_impl( GtkGameGlobals* globals, XP_Bool fireConnDlg )
|
||||||
}
|
}
|
||||||
|
|
||||||
CurGameInfo* gi = cGlobals->gi;
|
CurGameInfo* gi = cGlobals->gi;
|
||||||
success = newGameDialog( globals, gi, &addr, XP_TRUE, fireConnDlg );
|
success = gtkNewGameDialog( globals, gi, &addr, XP_TRUE, fireConnDlg );
|
||||||
if ( success ) {
|
if ( success ) {
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
XP_Bool isClient = gi->serverRole == SERVER_ISCLIENT;
|
XP_Bool isClient = gi->serverRole == SERVER_ISCLIENT;
|
||||||
|
@ -1022,7 +870,7 @@ game_info( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
|
||||||
/* Anything to do if OK is clicked? Changed names etc. already saved. Try
|
/* Anything to do if OK is clicked? Changed names etc. already saved. Try
|
||||||
server_do in case one's become a robot. */
|
server_do in case one's become a robot. */
|
||||||
CurGameInfo* gi = globals->cGlobals.gi;
|
CurGameInfo* gi = globals->cGlobals.gi;
|
||||||
if ( newGameDialog( globals, gi, &addr, XP_FALSE, XP_FALSE ) ) {
|
if ( gtkNewGameDialog( globals, gi, &addr, XP_FALSE, XP_FALSE ) ) {
|
||||||
if ( server_do( globals->cGlobals.game.server ) ) {
|
if ( server_do( globals->cGlobals.game.server ) ) {
|
||||||
board_draw( globals->cGlobals.game.board );
|
board_draw( globals->cGlobals.game.board );
|
||||||
}
|
}
|
||||||
|
@ -1858,7 +1706,7 @@ static void
|
||||||
gtk_util_turnChanged( XW_UtilCtxt* uc, XP_S16 XP_UNUSED(newTurn) )
|
gtk_util_turnChanged( XW_UtilCtxt* uc, XP_S16 XP_UNUSED(newTurn) )
|
||||||
{
|
{
|
||||||
GtkGameGlobals* globals = (GtkGameGlobals*)uc->closure;
|
GtkGameGlobals* globals = (GtkGameGlobals*)uc->closure;
|
||||||
saveGame( &globals->cGlobals );
|
linuxSaveGame( &globals->cGlobals );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1954,22 +1802,6 @@ gtk_util_informNetDict( XW_UtilCtxt* uc, XP_LangCode XP_UNUSED(lang),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
|
||||||
changeRoles( gpointer data )
|
|
||||||
{
|
|
||||||
linuxChangeRoles( (CommonGlobals*)data );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_util_setIsServer( XW_UtilCtxt* uc, XP_Bool isServer )
|
|
||||||
{
|
|
||||||
CommonGlobals* cGlobals = (CommonGlobals*)uc->closure;
|
|
||||||
linuxSetIsServer( cGlobals, isServer );
|
|
||||||
|
|
||||||
(void)g_idle_add( changeRoles, cGlobals );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* define this to prevent user events during debugging from stopping the engine */
|
/* define this to prevent user events during debugging from stopping the engine */
|
||||||
/* #define DONT_ABORT_ENGINE */
|
/* #define DONT_ABORT_ENGINE */
|
||||||
|
|
||||||
|
@ -2334,14 +2166,6 @@ gtk_util_notifyMove( XW_UtilCtxt* uc, XWStreamCtxt* stream )
|
||||||
XP_ASSERT( len <= VSIZE(cGlobals->question) );
|
XP_ASSERT( len <= VSIZE(cGlobals->question) );
|
||||||
stream_getBytes( stream, cGlobals->question, len );
|
stream_getBytes( stream, cGlobals->question, len );
|
||||||
(void)g_idle_add( ask_move, globals );
|
(void)g_idle_add( ask_move, globals );
|
||||||
|
|
||||||
/* question = strFromStream( stream ); */
|
|
||||||
/* strcpy( cGlobals->question, question ); */
|
|
||||||
/* free( question ); */
|
|
||||||
|
|
||||||
/* /\*gint chosen = *\/gtkask( globals->window, question, buttons, NULL ); */
|
|
||||||
// result = GTK_RESPONSE_OK == chosen || chosen == GTK_RESPONSE_YES;
|
|
||||||
|
|
||||||
} /* gtk_util_userQuery */
|
} /* gtk_util_userQuery */
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
|
@ -2501,52 +2325,53 @@ makeButtons( GtkGameGlobals* globals )
|
||||||
static void
|
static void
|
||||||
setupGtkUtilCallbacks( GtkGameGlobals* globals, XW_UtilCtxt* util )
|
setupGtkUtilCallbacks( GtkGameGlobals* globals, XW_UtilCtxt* util )
|
||||||
{
|
{
|
||||||
util->vtable->m_util_userError = gtk_util_userError;
|
util->closure = globals;
|
||||||
util->vtable->m_util_notifyMove = gtk_util_notifyMove;
|
#define SET_PROC(NAM) util->vtable->m_util_##NAM = gtk_util_##NAM
|
||||||
util->vtable->m_util_notifyTrade = gtk_util_notifyTrade;
|
SET_PROC(userError);
|
||||||
util->vtable->m_util_notifyPickTileBlank = gtk_util_notifyPickTileBlank;
|
SET_PROC(notifyMove);
|
||||||
util->vtable->m_util_informNeedPickTiles = gtk_util_informNeedPickTiles;
|
SET_PROC(notifyTrade);
|
||||||
util->vtable->m_util_informNeedPassword = gtk_util_informNeedPassword;
|
SET_PROC(notifyPickTileBlank);
|
||||||
util->vtable->m_util_trayHiddenChange = gtk_util_trayHiddenChange;
|
SET_PROC(informNeedPickTiles);
|
||||||
util->vtable->m_util_yOffsetChange = gtk_util_yOffsetChange;
|
SET_PROC(informNeedPassword);
|
||||||
|
SET_PROC(trayHiddenChange);
|
||||||
|
SET_PROC(yOffsetChange);
|
||||||
#ifdef XWFEATURE_TURNCHANGENOTIFY
|
#ifdef XWFEATURE_TURNCHANGENOTIFY
|
||||||
util->vtable->m_util_turnChanged = gtk_util_turnChanged;
|
SET_PROC(turnChanged);
|
||||||
#endif
|
#endif
|
||||||
util->vtable->m_util_informMove = gtk_util_informMove;
|
SET_PROC(informMove);
|
||||||
util->vtable->m_util_informUndo = gtk_util_informUndo;
|
SET_PROC(informUndo);
|
||||||
util->vtable->m_util_notifyGameOver = gtk_util_notifyGameOver;
|
SET_PROC(notifyGameOver);
|
||||||
util->vtable->m_util_informNetDict = gtk_util_informNetDict;
|
SET_PROC(informNetDict);
|
||||||
util->vtable->m_util_setIsServer = gtk_util_setIsServer;
|
/* SET_PROC(setIsServer); */
|
||||||
#ifdef XWFEATURE_HILITECELL
|
#ifdef XWFEATURE_HILITECELL
|
||||||
util->vtable->m_util_hiliteCell = gtk_util_hiliteCell;
|
SET_PROC(hiliteCell);
|
||||||
#endif
|
#endif
|
||||||
util->vtable->m_util_altKeyDown = gtk_util_altKeyDown;
|
SET_PROC(altKeyDown);
|
||||||
util->vtable->m_util_engineProgressCallback =
|
SET_PROC(engineProgressCallback);
|
||||||
gtk_util_engineProgressCallback;
|
SET_PROC(setTimer);
|
||||||
util->vtable->m_util_setTimer = gtk_util_setTimer;
|
SET_PROC(clearTimer);
|
||||||
util->vtable->m_util_clearTimer = gtk_util_clearTimer;
|
SET_PROC(requestTime);
|
||||||
util->vtable->m_util_requestTime = gtk_util_requestTime;
|
SET_PROC(notifyIllegalWords);
|
||||||
util->vtable->m_util_notifyIllegalWords = gtk_util_notifyIllegalWords;
|
SET_PROC(remSelected);
|
||||||
util->vtable->m_util_remSelected = gtk_util_remSelected;
|
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
util->vtable->m_util_makeStreamFromAddr = gtk_util_makeStreamFromAddr;
|
SET_PROC(makeStreamFromAddr);
|
||||||
#endif
|
#endif
|
||||||
#ifdef XWFEATURE_CHAT
|
#ifdef XWFEATURE_CHAT
|
||||||
util->vtable->m_util_showChat = gtk_util_showChat;
|
SET_PROC(showChat);
|
||||||
#endif
|
#endif
|
||||||
#ifdef XWFEATURE_SEARCHLIMIT
|
#ifdef XWFEATURE_SEARCHLIMIT
|
||||||
util->vtable->m_util_getTraySearchLimits = gtk_util_getTraySearchLimits;
|
SET_PROC(getTraySearchLimits);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef XWFEATURE_MINIWIN
|
#ifndef XWFEATURE_MINIWIN
|
||||||
util->vtable->m_util_bonusSquareHeld = gtk_util_bonusSquareHeld;
|
SET_PROC(bonusSquareHeld);
|
||||||
util->vtable->m_util_playerScoreHeld = gtk_util_playerScoreHeld;
|
SET_PROC(playerScoreHeld);
|
||||||
#endif
|
#endif
|
||||||
#ifdef XWFEATURE_BOARDWORDS
|
#ifdef XWFEATURE_BOARDWORDS
|
||||||
util->vtable->m_util_cellSquareHeld = gtk_util_cellSquareHeld;
|
SET_PROC(cellSquareHeld);
|
||||||
#endif
|
#endif
|
||||||
|
#undef SET_PROC
|
||||||
util->closure = globals;
|
assertAllCallbacksSet( util );
|
||||||
} /* setupGtkUtilCallbacks */
|
} /* setupGtkUtilCallbacks */
|
||||||
|
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
|
@ -2556,33 +2381,6 @@ typedef struct _SockInfo {
|
||||||
int socket;
|
int socket;
|
||||||
} SockInfo;
|
} SockInfo;
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_socket_added( void* closure, int newSock, GIOFunc proc )
|
|
||||||
{
|
|
||||||
GtkGameGlobals* globals = (GtkGameGlobals*)closure;
|
|
||||||
|
|
||||||
if ( newSock != -1 ) {
|
|
||||||
XP_ASSERT( !!proc );
|
|
||||||
GIOChannel* channel = g_io_channel_unix_new( newSock );
|
|
||||||
g_io_channel_set_close_on_unref( channel, TRUE );
|
|
||||||
#ifdef DEBUG
|
|
||||||
guint result =
|
|
||||||
#endif
|
|
||||||
g_io_add_watch( channel, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI,
|
|
||||||
proc, globals );
|
|
||||||
XP_LOGF( "g_io_add_watch(%d) => %d", newSock, result );
|
|
||||||
}
|
|
||||||
/* A hack for the bluetooth case. */
|
|
||||||
CommsCtxt* comms = globals->cGlobals.game.comms;
|
|
||||||
|
|
||||||
CommsAddrRec addr;
|
|
||||||
comms_getAddr( comms, &addr );
|
|
||||||
if ( (comms != NULL) && (addr_hasType( &addr, COMMS_CONN_BT) ) ) {
|
|
||||||
comms_resendAll( comms, COMMS_CONN_NONE, XP_FALSE );
|
|
||||||
}
|
|
||||||
LOG_RETURN_VOID();
|
|
||||||
} /* gtk_socket_changed */
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
acceptorInput( GIOChannel* source, GIOCondition condition, gpointer data )
|
acceptorInput( GIOChannel* source, GIOCondition condition, gpointer data )
|
||||||
{
|
{
|
||||||
|
@ -2671,44 +2469,44 @@ initGlobalsNoDraw( GtkGameGlobals* globals, LaunchParams* params,
|
||||||
{
|
{
|
||||||
memset( globals, 0, sizeof(*globals) );
|
memset( globals, 0, sizeof(*globals) );
|
||||||
|
|
||||||
globals->cGlobals.gi = &globals->gi;
|
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||||
|
cGlobals->gi = &cGlobals->_gi;
|
||||||
if ( !gi ) {
|
if ( !gi ) {
|
||||||
gi = ¶ms->pgi;
|
gi = ¶ms->pgi;
|
||||||
}
|
}
|
||||||
gi_copy( MPPARM(params->mpool) globals->cGlobals.gi, gi );
|
gi_copy( MPPARM(params->mpool) cGlobals->gi, gi );
|
||||||
|
|
||||||
globals->cGlobals.params = params;
|
cGlobals->params = params;
|
||||||
globals->cGlobals.lastNTilesToUse = MAX_TRAY_TILES;
|
cGlobals->lastNTilesToUse = MAX_TRAY_TILES;
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
# ifdef XWFEATURE_RELAY
|
# ifdef XWFEATURE_RELAY
|
||||||
globals->cGlobals.relaySocket = -1;
|
cGlobals->relaySocket = -1;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
globals->cGlobals.socketAdded = gtk_socket_added;
|
cGlobals->socketAddedClosure = globals;
|
||||||
globals->cGlobals.socketAddedClosure = globals;
|
cGlobals->onSave = gtkOnGameSaved;
|
||||||
globals->cGlobals.onSave = onGameSaved;
|
cGlobals->onSaveClosure = globals;
|
||||||
globals->cGlobals.onSaveClosure = globals;
|
cGlobals->addAcceptor = gtk_socket_acceptor;
|
||||||
globals->cGlobals.addAcceptor = gtk_socket_acceptor;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
globals->cGlobals.cp.showBoardArrow = XP_TRUE;
|
cGlobals->cp.showBoardArrow = XP_TRUE;
|
||||||
globals->cGlobals.cp.hideTileValues = params->hideValues;
|
cGlobals->cp.hideTileValues = params->hideValues;
|
||||||
globals->cGlobals.cp.skipCommitConfirm = params->skipCommitConfirm;
|
cGlobals->cp.skipCommitConfirm = params->skipCommitConfirm;
|
||||||
globals->cGlobals.cp.sortNewTiles = params->sortNewTiles;
|
cGlobals->cp.sortNewTiles = params->sortNewTiles;
|
||||||
globals->cGlobals.cp.showColors = params->showColors;
|
cGlobals->cp.showColors = params->showColors;
|
||||||
globals->cGlobals.cp.allowPeek = params->allowPeek;
|
cGlobals->cp.allowPeek = params->allowPeek;
|
||||||
globals->cGlobals.cp.showRobotScores = params->showRobotScores;
|
cGlobals->cp.showRobotScores = params->showRobotScores;
|
||||||
#ifdef XWFEATURE_SLOW_ROBOT
|
#ifdef XWFEATURE_SLOW_ROBOT
|
||||||
globals->cGlobals.cp.robotThinkMin = params->robotThinkMin;
|
cGlobals->cp.robotThinkMin = params->robotThinkMin;
|
||||||
globals->cGlobals.cp.robotThinkMax = params->robotThinkMax;
|
cGlobals->cp.robotThinkMax = params->robotThinkMax;
|
||||||
globals->cGlobals.cp.robotTradePct = params->robotTradePct;
|
cGlobals->cp.robotTradePct = params->robotTradePct;
|
||||||
#endif
|
#endif
|
||||||
#ifdef XWFEATURE_CROSSHAIRS
|
#ifdef XWFEATURE_CROSSHAIRS
|
||||||
globals->cGlobals.cp.hideCrosshairs = params->hideCrosshairs;
|
cGlobals->cp.hideCrosshairs = params->hideCrosshairs;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
setupUtil( &globals->cGlobals );
|
setupUtil( cGlobals );
|
||||||
setupGtkUtilCallbacks( globals, globals->cGlobals.util );
|
setupGtkUtilCallbacks( globals, cGlobals->util );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This gets called all the time, e.g. when the mouse moves across
|
/* This gets called all the time, e.g. when the mouse moves across
|
||||||
|
@ -2727,9 +2525,10 @@ on_draw_event( GtkWidget* widget, cairo_t* cr, gpointer user_data )
|
||||||
/* } */
|
/* } */
|
||||||
|
|
||||||
GtkGameGlobals* globals = (GtkGameGlobals*)user_data;
|
GtkGameGlobals* globals = (GtkGameGlobals*)user_data;
|
||||||
board_invalAll( globals->cGlobals.game.board );
|
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||||
board_draw( globals->cGlobals.game.board );
|
board_invalAll( cGlobals->game.board );
|
||||||
draw_gtk_status( globals->draw, globals->stateChar );
|
board_draw( cGlobals->game.board );
|
||||||
|
draw_gtk_status( (GtkDrawCtx*)cGlobals->draw, globals->stateChar );
|
||||||
|
|
||||||
XP_USE(widget);
|
XP_USE(widget);
|
||||||
XP_USE(cr);
|
XP_USE(cr);
|
||||||
|
@ -2737,7 +2536,8 @@ on_draw_event( GtkWidget* widget, cairo_t* cr, gpointer user_data )
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
initGlobals( GtkGameGlobals* globals, LaunchParams* params, CurGameInfo* gi )
|
initBoardGlobalsGtk( GtkGameGlobals* globals, LaunchParams* params,
|
||||||
|
CurGameInfo* gi )
|
||||||
{
|
{
|
||||||
CommonGlobals* cGlobals = &globals->cGlobals;
|
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||||
short width, height;
|
short width, height;
|
||||||
|
@ -2746,7 +2546,6 @@ initGlobals( GtkGameGlobals* globals, LaunchParams* params, CurGameInfo* gi )
|
||||||
GtkWidget* menubar;
|
GtkWidget* menubar;
|
||||||
GtkWidget* vbox;
|
GtkWidget* vbox;
|
||||||
GtkWidget* hbox;
|
GtkWidget* hbox;
|
||||||
gulong id;
|
|
||||||
|
|
||||||
initGlobalsNoDraw( globals, params, gi );
|
initGlobalsNoDraw( globals, params, gi );
|
||||||
if ( !!gi ) {
|
if ( !!gi ) {
|
||||||
|
@ -2765,12 +2564,18 @@ initGlobals( GtkGameGlobals* globals, LaunchParams* params, CurGameInfo* gi )
|
||||||
gtk_container_add( GTK_CONTAINER(window), vbox );
|
gtk_container_add( GTK_CONTAINER(window), vbox );
|
||||||
gtk_widget_show( vbox );
|
gtk_widget_show( vbox );
|
||||||
|
|
||||||
id = g_signal_connect( window, "destroy", G_CALLBACK(destroy_board_window),
|
#ifdef DEBUG
|
||||||
globals );
|
gulong id =
|
||||||
|
#endif
|
||||||
|
g_signal_connect( window, "destroy", G_CALLBACK(destroy_board_window),
|
||||||
|
globals );
|
||||||
XP_ASSERT( id > 0 );
|
XP_ASSERT( id > 0 );
|
||||||
XP_ASSERT( !!globals );
|
XP_ASSERT( !!globals );
|
||||||
id = g_signal_connect( window, "show", G_CALLBACK( on_board_window_shown ),
|
#ifdef DEBUG
|
||||||
globals );
|
id =
|
||||||
|
#endif
|
||||||
|
g_signal_connect( window, "show", G_CALLBACK( on_board_window_shown ),
|
||||||
|
globals );
|
||||||
XP_ASSERT( id > 0 );
|
XP_ASSERT( id > 0 );
|
||||||
|
|
||||||
menubar = makeMenus( globals );
|
menubar = makeMenus( globals );
|
||||||
|
@ -2786,8 +2591,11 @@ initGlobals( GtkGameGlobals* globals, LaunchParams* params, CurGameInfo* gi )
|
||||||
|
|
||||||
drawing_area = gtk_drawing_area_new();
|
drawing_area = gtk_drawing_area_new();
|
||||||
gtk_widget_add_events( drawing_area, GDK_ALL_EVENTS_MASK );
|
gtk_widget_add_events( drawing_area, GDK_ALL_EVENTS_MASK );
|
||||||
id = g_signal_connect(G_OBJECT(drawing_area), "draw",
|
#ifdef DEBUG
|
||||||
G_CALLBACK(on_draw_event), globals);
|
id =
|
||||||
|
#endif
|
||||||
|
g_signal_connect(G_OBJECT(drawing_area), "draw",
|
||||||
|
G_CALLBACK(on_draw_event), globals);
|
||||||
XP_ASSERT( id > 0 );
|
XP_ASSERT( id > 0 );
|
||||||
|
|
||||||
globals->drawing_area = drawing_area;
|
globals->drawing_area = drawing_area;
|
||||||
|
@ -2815,8 +2623,11 @@ initGlobals( GtkGameGlobals* globals, LaunchParams* params, CurGameInfo* gi )
|
||||||
gtk_adjustment_new( 0, 0, nRows, 1, 2,
|
gtk_adjustment_new( 0, 0, nRows, 1, 2,
|
||||||
nRows - params->nHidden );
|
nRows - params->nHidden );
|
||||||
vscrollbar = gtk_scrollbar_new( GTK_ORIENTATION_VERTICAL, globals->adjustment );
|
vscrollbar = gtk_scrollbar_new( GTK_ORIENTATION_VERTICAL, globals->adjustment );
|
||||||
id = g_signal_connect( globals->adjustment, "value_changed",
|
#ifdef DEBUG
|
||||||
G_CALLBACK(scroll_value_changed), globals );
|
id =
|
||||||
|
#endif
|
||||||
|
g_signal_connect( globals->adjustment, "value_changed",
|
||||||
|
G_CALLBACK(scroll_value_changed), globals );
|
||||||
XP_ASSERT( id > 0 );
|
XP_ASSERT( id > 0 );
|
||||||
gtk_widget_show( vscrollbar );
|
gtk_widget_show( vscrollbar );
|
||||||
gtk_box_pack_start( GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0 );
|
gtk_box_pack_start( GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0 );
|
||||||
|
@ -2831,18 +2642,29 @@ initGlobals( GtkGameGlobals* globals, LaunchParams* params, CurGameInfo* gi )
|
||||||
GtkWidget* label = globals->countLabel = gtk_label_new( "" );
|
GtkWidget* label = globals->countLabel = gtk_label_new( "" );
|
||||||
gtk_box_pack_start( GTK_BOX(vbox), label, TRUE, TRUE, 0);
|
gtk_box_pack_start( GTK_BOX(vbox), label, TRUE, TRUE, 0);
|
||||||
gtk_widget_show( label );
|
gtk_widget_show( label );
|
||||||
|
#ifdef DEBUG
|
||||||
id = g_signal_connect( drawing_area, "configure-event",
|
id =
|
||||||
G_CALLBACK(configure_event), globals );
|
#endif
|
||||||
|
g_signal_connect( drawing_area, "configure-event",
|
||||||
|
G_CALLBACK(configure_event), globals );
|
||||||
XP_ASSERT( id > 0 );
|
XP_ASSERT( id > 0 );
|
||||||
id = g_signal_connect( drawing_area, "button_press_event",
|
#ifdef DEBUG
|
||||||
G_CALLBACK(button_press_event), globals );
|
id =
|
||||||
|
#endif
|
||||||
|
g_signal_connect( drawing_area, "button_press_event",
|
||||||
|
G_CALLBACK(button_press_event), globals );
|
||||||
XP_ASSERT( id > 0 );
|
XP_ASSERT( id > 0 );
|
||||||
id = g_signal_connect( drawing_area, "motion_notify_event",
|
#ifdef DEBUG
|
||||||
G_CALLBACK(motion_notify_event), globals );
|
id =
|
||||||
|
#endif
|
||||||
|
g_signal_connect( drawing_area, "motion_notify_event",
|
||||||
|
G_CALLBACK(motion_notify_event), globals );
|
||||||
XP_ASSERT( id > 0 );
|
XP_ASSERT( id > 0 );
|
||||||
id = g_signal_connect( drawing_area, "button_release_event",
|
#ifdef DEBUG
|
||||||
G_CALLBACK(button_release_event), globals );
|
id =
|
||||||
|
#endif
|
||||||
|
g_signal_connect( drawing_area, "button_release_event",
|
||||||
|
G_CALLBACK(button_release_event), globals );
|
||||||
XP_ASSERT( id > 0 );
|
XP_ASSERT( id > 0 );
|
||||||
|
|
||||||
setOneSecondTimer( cGlobals );
|
setOneSecondTimer( cGlobals );
|
||||||
|
@ -2889,7 +2711,7 @@ loadGameNoDraw( GtkGameGlobals* globals, LaunchParams* params,
|
||||||
setTransportProcs( &procs, globals );
|
setTransportProcs( &procs, globals );
|
||||||
|
|
||||||
CommonGlobals* cGlobals = &globals->cGlobals;
|
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||||
cGlobals->selRow = rowid;
|
cGlobals->rowid = rowid;
|
||||||
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool)
|
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool)
|
||||||
params->vtMgr );
|
params->vtMgr );
|
||||||
XP_Bool loaded = loadGame( stream, pDb, rowid );
|
XP_Bool loaded = loadGame( stream, pDb, rowid );
|
||||||
|
@ -2924,7 +2746,7 @@ makeNewGame( GtkGameGlobals* globals )
|
||||||
if ( !!cGlobals->game.comms ) {
|
if ( !!cGlobals->game.comms ) {
|
||||||
comms_getAddr( cGlobals->game.comms, &cGlobals->addr );
|
comms_getAddr( cGlobals->game.comms, &cGlobals->addr );
|
||||||
} else {
|
} else {
|
||||||
LaunchParams* params = globals->cGlobals.params;
|
LaunchParams* params = cGlobals->params;
|
||||||
const XP_UCHAR* relayName = params->connInfo.relay.relayName;
|
const XP_UCHAR* relayName = params->connInfo.relay.relayName;
|
||||||
if ( !relayName ) {
|
if ( !relayName ) {
|
||||||
relayName = RELAY_NAME_DEFAULT;
|
relayName = RELAY_NAME_DEFAULT;
|
||||||
|
@ -2937,8 +2759,8 @@ makeNewGame( GtkGameGlobals* globals )
|
||||||
}
|
}
|
||||||
|
|
||||||
CurGameInfo* gi = cGlobals->gi;
|
CurGameInfo* gi = cGlobals->gi;
|
||||||
XP_Bool success = newGameDialog( globals, gi, &cGlobals->addr,
|
XP_Bool success = gtkNewGameDialog( globals, gi, &cGlobals->addr,
|
||||||
XP_TRUE, XP_FALSE );
|
XP_TRUE, XP_FALSE );
|
||||||
if ( success && !!gi->dictName && !cGlobals->dict ) {
|
if ( success && !!gi->dictName && !cGlobals->dict ) {
|
||||||
cGlobals->dict =
|
cGlobals->dict =
|
||||||
linux_dictionary_make( MEMPOOL cGlobals->params,
|
linux_dictionary_make( MEMPOOL cGlobals->params,
|
||||||
|
|
|
@ -94,9 +94,7 @@ typedef struct _DropTypeData {
|
||||||
|
|
||||||
typedef struct GtkGameGlobals {
|
typedef struct GtkGameGlobals {
|
||||||
CommonGlobals cGlobals;
|
CommonGlobals cGlobals;
|
||||||
CurGameInfo gi;
|
|
||||||
GtkWidget* window;
|
GtkWidget* window;
|
||||||
GtkDrawCtx* draw;
|
|
||||||
GtkAppGlobals* apg;
|
GtkAppGlobals* apg;
|
||||||
/* GdkPixmap* pixmap; */
|
/* GdkPixmap* pixmap; */
|
||||||
GtkWidget* drawing_area;
|
GtkWidget* drawing_area;
|
||||||
|
@ -184,8 +182,8 @@ typedef struct GtkGameGlobals {
|
||||||
#define GTK_BOTTOM_MARGIN GTK_TOP_MARGIN
|
#define GTK_BOTTOM_MARGIN GTK_TOP_MARGIN
|
||||||
#define GTK_RIGHT_MARGIN GTK_BOARD_LEFT_MARGIN
|
#define GTK_RIGHT_MARGIN GTK_BOARD_LEFT_MARGIN
|
||||||
|
|
||||||
void initGlobals( GtkGameGlobals* globals, LaunchParams* params,
|
void initBoardGlobalsGtk( GtkGameGlobals* globals, LaunchParams* params,
|
||||||
CurGameInfo* gi );
|
CurGameInfo* gi );
|
||||||
void freeGlobals( GtkGameGlobals* globals );
|
void freeGlobals( GtkGameGlobals* globals );
|
||||||
XP_Bool makeNewGame( GtkGameGlobals* globals );
|
XP_Bool makeNewGame( GtkGameGlobals* globals );
|
||||||
XP_Bool loadGameNoDraw( GtkGameGlobals* globals, LaunchParams* params,
|
XP_Bool loadGameNoDraw( GtkGameGlobals* globals, LaunchParams* params,
|
||||||
|
|
|
@ -1531,7 +1531,6 @@ removeSurface( GtkDrawCtx* dctx )
|
||||||
dctx->surface = NULL;
|
dctx->surface = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
write_func( void *closure, const unsigned char *data,
|
write_func( void *closure, const unsigned char *data,
|
||||||
unsigned int length )
|
unsigned int length )
|
||||||
|
@ -1540,21 +1539,18 @@ write_func( void *closure, const unsigned char *data,
|
||||||
stream_putBytes( stream, data, length );
|
stream_putBytes( stream, data, length );
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
void
|
||||||
getImage( GtkDrawCtx* XP_UNUSED_DBG(dctx), XWStreamCtxt* XP_UNUSED_DBG(stream) )
|
getImage( GtkDrawCtx* dctx, XWStreamCtxt* stream )
|
||||||
{
|
{
|
||||||
LOG_FUNC();
|
LOG_FUNC();
|
||||||
XP_ASSERT( !!dctx->surface );
|
XP_ASSERT( !!dctx->surface );
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
cairo_status_t status =
|
cairo_status_t status =
|
||||||
|
#endif
|
||||||
cairo_surface_write_to_png_stream( dctx->surface,
|
cairo_surface_write_to_png_stream( dctx->surface,
|
||||||
write_func, stream );
|
write_func, stream );
|
||||||
XP_ASSERT( CAIRO_STATUS_SUCCESS == status );
|
XP_ASSERT( CAIRO_STATUS_SUCCESS == status );
|
||||||
#else
|
|
||||||
error Will Robinson
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -36,18 +36,19 @@
|
||||||
static void onNewData( GtkAppGlobals* apg, sqlite3_int64 rowid,
|
static void onNewData( GtkAppGlobals* apg, sqlite3_int64 rowid,
|
||||||
XP_Bool isNew );
|
XP_Bool isNew );
|
||||||
static void updateButtons( GtkAppGlobals* apg );
|
static void updateButtons( GtkAppGlobals* apg );
|
||||||
|
static void open_row( GtkAppGlobals* apg, sqlite3_int64 row, XP_Bool isNew );
|
||||||
|
|
||||||
static void
|
static void
|
||||||
recordOpened( GtkAppGlobals* apg, GtkGameGlobals* globals )
|
recordOpened( GtkAppGlobals* apg, GtkGameGlobals* globals )
|
||||||
{
|
{
|
||||||
apg->globalsList = g_slist_prepend( apg->globalsList, globals );
|
apg->cag.globalsList = g_slist_prepend( apg->cag.globalsList, globals );
|
||||||
globals->apg = apg;
|
globals->apg = apg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
recordClosed( GtkAppGlobals* apg, GtkGameGlobals* globals )
|
recordClosed( GtkAppGlobals* apg, GtkGameGlobals* globals )
|
||||||
{
|
{
|
||||||
apg->globalsList = g_slist_remove( apg->globalsList, globals );
|
apg->cag.globalsList = g_slist_remove( apg->cag.globalsList, globals );
|
||||||
}
|
}
|
||||||
|
|
||||||
static XP_Bool
|
static XP_Bool
|
||||||
|
@ -55,9 +56,9 @@ gameIsOpen( GtkAppGlobals* apg, sqlite3_int64 rowid )
|
||||||
{
|
{
|
||||||
XP_Bool found = XP_FALSE;
|
XP_Bool found = XP_FALSE;
|
||||||
GSList* iter;
|
GSList* iter;
|
||||||
for ( iter = apg->globalsList; !!iter && !found; iter = iter->next ) {
|
for ( iter = apg->cag.globalsList; !!iter && !found; iter = iter->next ) {
|
||||||
GtkGameGlobals* globals = (GtkGameGlobals*)iter->data;
|
GtkGameGlobals* globals = (GtkGameGlobals*)iter->data;
|
||||||
found = globals->cGlobals.selRow == rowid;
|
found = globals->cGlobals.rowid == rowid;
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
@ -67,10 +68,10 @@ findOpenGame( const GtkAppGlobals* apg, sqlite3_int64 rowid )
|
||||||
{
|
{
|
||||||
GtkGameGlobals* result = NULL;
|
GtkGameGlobals* result = NULL;
|
||||||
GSList* iter;
|
GSList* iter;
|
||||||
for ( iter = apg->globalsList; !!iter; iter = iter->next ) {
|
for ( iter = apg->cag.globalsList; !!iter; iter = iter->next ) {
|
||||||
GtkGameGlobals* globals = (GtkGameGlobals*)iter->data;
|
GtkGameGlobals* globals = (GtkGameGlobals*)iter->data;
|
||||||
CommonGlobals* cGlobals = &globals->cGlobals;
|
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||||
if ( cGlobals->selRow == rowid ) {
|
if ( cGlobals->rowid == rowid ) {
|
||||||
result = globals;
|
result = globals;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +79,7 @@ findOpenGame( const GtkAppGlobals* apg, sqlite3_int64 rowid )
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum { ROW_ITEM, ROW_THUMB, NAME_ITEM, ROOM_ITEM, GAMEID_ITEM, SEED_ITEM,
|
enum { ROW_ITEM, ROW_THUMB, NAME_ITEM, ROOM_ITEM, GAMEID_ITEM, SEED_ITEM, ROLE_ITEM,
|
||||||
CONN_ITEM, RELAYID_ITEM, OVER_ITEM, TURN_ITEM, LOCAL_ITEM, NMOVES_ITEM, NTOTAL_ITEM,
|
CONN_ITEM, RELAYID_ITEM, OVER_ITEM, TURN_ITEM, LOCAL_ITEM, NMOVES_ITEM, NTOTAL_ITEM,
|
||||||
MISSING_ITEM, LASTTURN_ITEM, N_ITEMS };
|
MISSING_ITEM, LASTTURN_ITEM, N_ITEMS };
|
||||||
|
|
||||||
|
@ -169,6 +170,7 @@ init_games_list( GtkAppGlobals* apg )
|
||||||
addTextColumn( list, "Room", ROOM_ITEM );
|
addTextColumn( list, "Room", ROOM_ITEM );
|
||||||
addTextColumn( list, "GameID", GAMEID_ITEM );
|
addTextColumn( list, "GameID", GAMEID_ITEM );
|
||||||
addTextColumn( list, "Seed", SEED_ITEM );
|
addTextColumn( list, "Seed", SEED_ITEM );
|
||||||
|
addTextColumn( list, "Role", ROLE_ITEM );
|
||||||
addTextColumn( list, "Conn. via", CONN_ITEM );
|
addTextColumn( list, "Conn. via", CONN_ITEM );
|
||||||
addTextColumn( list, "RelayID", RELAYID_ITEM );
|
addTextColumn( list, "RelayID", RELAYID_ITEM );
|
||||||
addTextColumn( list, "Ended", OVER_ITEM );
|
addTextColumn( list, "Ended", OVER_ITEM );
|
||||||
|
@ -186,6 +188,7 @@ init_games_list( GtkAppGlobals* apg )
|
||||||
G_TYPE_STRING, /* ROOM_ITEM */
|
G_TYPE_STRING, /* ROOM_ITEM */
|
||||||
G_TYPE_INT, /* GAMEID_ITEM */
|
G_TYPE_INT, /* GAMEID_ITEM */
|
||||||
G_TYPE_INT, /* SEED_ITEM */
|
G_TYPE_INT, /* SEED_ITEM */
|
||||||
|
G_TYPE_INT, /* ROLE_ITEM */
|
||||||
G_TYPE_STRING, /* CONN_ITEM */
|
G_TYPE_STRING, /* CONN_ITEM */
|
||||||
G_TYPE_STRING, /*RELAYID_ITEM */
|
G_TYPE_STRING, /*RELAYID_ITEM */
|
||||||
G_TYPE_BOOLEAN, /* OVER_ITEM */
|
G_TYPE_BOOLEAN, /* OVER_ITEM */
|
||||||
|
@ -247,6 +250,7 @@ add_to_list( GtkWidget* list, sqlite3_int64 rowid, XP_Bool isNew,
|
||||||
ROOM_ITEM, gib->room,
|
ROOM_ITEM, gib->room,
|
||||||
GAMEID_ITEM, gib->gameID,
|
GAMEID_ITEM, gib->gameID,
|
||||||
SEED_ITEM, gib->seed,
|
SEED_ITEM, gib->seed,
|
||||||
|
ROLE_ITEM, gib->role,
|
||||||
CONN_ITEM, gib->conn,
|
CONN_ITEM, gib->conn,
|
||||||
RELAYID_ITEM, gib->relayID,
|
RELAYID_ITEM, gib->relayID,
|
||||||
TURN_ITEM, gib->turn,
|
TURN_ITEM, gib->turn,
|
||||||
|
@ -275,20 +279,20 @@ handle_newgame_button( GtkWidget* XP_UNUSED(widget), void* closure )
|
||||||
{
|
{
|
||||||
GtkAppGlobals* apg = (GtkAppGlobals*)closure;
|
GtkAppGlobals* apg = (GtkAppGlobals*)closure;
|
||||||
XP_LOGF( "%s called", __func__ );
|
XP_LOGF( "%s called", __func__ );
|
||||||
GtkGameGlobals* globals = malloc( sizeof(*globals) );
|
GtkGameGlobals* globals = calloc( 1, sizeof(*globals) );
|
||||||
apg->params->needsNewGame = XP_FALSE;
|
apg->cag.params->needsNewGame = XP_FALSE;
|
||||||
initGlobals( globals, apg->params, NULL );
|
initBoardGlobalsGtk( globals, apg->cag.params, NULL );
|
||||||
if ( !makeNewGame( globals ) ) {
|
if ( !makeNewGame( globals ) ) {
|
||||||
freeGlobals( globals );
|
freeGlobals( globals );
|
||||||
} else {
|
} else {
|
||||||
GtkWidget* gameWindow = globals->window;
|
GtkWidget* gameWindow = globals->window;
|
||||||
globals->cGlobals.selRow = -1;
|
globals->cGlobals.rowid = -1;
|
||||||
recordOpened( apg, globals );
|
recordOpened( apg, globals );
|
||||||
gtk_widget_show( gameWindow );
|
gtk_widget_show( gameWindow );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
open_row( GtkAppGlobals* apg, sqlite3_int64 row, XP_Bool isNew )
|
open_row( GtkAppGlobals* apg, sqlite3_int64 row, XP_Bool isNew )
|
||||||
{
|
{
|
||||||
if ( -1 != row && !gameIsOpen( apg, row ) ) {
|
if ( -1 != row && !gameIsOpen( apg, row ) ) {
|
||||||
|
@ -296,10 +300,10 @@ open_row( GtkAppGlobals* apg, sqlite3_int64 row, XP_Bool isNew )
|
||||||
onNewData( apg, row, XP_TRUE );
|
onNewData( apg, row, XP_TRUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
apg->params->needsNewGame = XP_FALSE;
|
apg->cag.params->needsNewGame = XP_FALSE;
|
||||||
GtkGameGlobals* globals = malloc( sizeof(*globals) );
|
GtkGameGlobals* globals = malloc( sizeof(*globals) );
|
||||||
initGlobals( globals, apg->params, NULL );
|
initBoardGlobalsGtk( globals, apg->cag.params, NULL );
|
||||||
globals->cGlobals.selRow = row;
|
globals->cGlobals.rowid = row;
|
||||||
recordOpened( apg, globals );
|
recordOpened( apg, globals );
|
||||||
gtk_widget_show( globals->window );
|
gtk_widget_show( globals->window );
|
||||||
}
|
}
|
||||||
|
@ -320,7 +324,7 @@ handle_open_button( GtkWidget* XP_UNUSED(widget), void* closure )
|
||||||
void
|
void
|
||||||
make_rematch( GtkAppGlobals* apg, const CommonGlobals* cGlobals )
|
make_rematch( GtkAppGlobals* apg, const CommonGlobals* cGlobals )
|
||||||
{
|
{
|
||||||
LaunchParams* params = apg->params;
|
LaunchParams* params = apg->cag.params;
|
||||||
XP_ASSERT( params == cGlobals->params );
|
XP_ASSERT( params == cGlobals->params );
|
||||||
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool)
|
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool)
|
||||||
params->vtMgr );
|
params->vtMgr );
|
||||||
|
@ -383,7 +387,7 @@ handle_rematch_button( GtkWidget* XP_UNUSED(widget), void* closure )
|
||||||
for ( int ii = 0; ii < selRows->len; ++ii ) {
|
for ( int ii = 0; ii < selRows->len; ++ii ) {
|
||||||
sqlite3_int64 rowid = g_array_index( selRows, sqlite3_int64, ii );
|
sqlite3_int64 rowid = g_array_index( selRows, sqlite3_int64, ii );
|
||||||
GtkGameGlobals tmpGlobals;
|
GtkGameGlobals tmpGlobals;
|
||||||
if ( loadGameNoDraw( &tmpGlobals, apg->params, rowid ) ) {
|
if ( loadGameNoDraw( &tmpGlobals, apg->cag.params, rowid ) ) {
|
||||||
make_rematch( apg, &tmpGlobals.cGlobals );
|
make_rematch( apg, &tmpGlobals.cGlobals );
|
||||||
}
|
}
|
||||||
freeGlobals( &tmpGlobals );
|
freeGlobals( &tmpGlobals );
|
||||||
|
@ -394,7 +398,7 @@ static void
|
||||||
handle_delete_button( GtkWidget* XP_UNUSED(widget), void* closure )
|
handle_delete_button( GtkWidget* XP_UNUSED(widget), void* closure )
|
||||||
{
|
{
|
||||||
GtkAppGlobals* apg = (GtkAppGlobals*)closure;
|
GtkAppGlobals* apg = (GtkAppGlobals*)closure;
|
||||||
LaunchParams* params = apg->params;
|
LaunchParams* params = apg->cag.params;
|
||||||
guint len = apg->selRows->len;
|
guint len = apg->selRows->len;
|
||||||
for ( guint ii = 0; ii < len; ++ii ) {
|
for ( guint ii = 0; ii < len; ++ii ) {
|
||||||
sqlite3_int64 rowid = g_array_index( apg->selRows, sqlite3_int64, ii );
|
sqlite3_int64 rowid = g_array_index( apg->selRows, sqlite3_int64, ii );
|
||||||
|
@ -429,18 +433,18 @@ handle_destroy( GtkWidget* XP_UNUSED(widget), gpointer data )
|
||||||
LOG_FUNC();
|
LOG_FUNC();
|
||||||
GtkAppGlobals* apg = (GtkAppGlobals*)data;
|
GtkAppGlobals* apg = (GtkAppGlobals*)data;
|
||||||
GSList* iter;
|
GSList* iter;
|
||||||
for ( iter = apg->globalsList; !!iter; iter = iter->next ) {
|
for ( iter = apg->cag.globalsList; !!iter; iter = iter->next ) {
|
||||||
GtkGameGlobals* globals = (GtkGameGlobals*)iter->data;
|
GtkGameGlobals* globals = (GtkGameGlobals*)iter->data;
|
||||||
destroy_board_window( NULL, globals );
|
destroy_board_window( NULL, globals );
|
||||||
// freeGlobals( globals );
|
// freeGlobals( globals );
|
||||||
}
|
}
|
||||||
g_slist_free( apg->globalsList );
|
g_slist_free( apg->cag.globalsList );
|
||||||
|
|
||||||
gchar buf[64];
|
gchar buf[64];
|
||||||
sprintf( buf, "%d:%d:%d:%d", apg->lastConfigure.x,
|
sprintf( buf, "%d:%d:%d:%d", apg->lastConfigure.x,
|
||||||
apg->lastConfigure.y, apg->lastConfigure.width,
|
apg->lastConfigure.y, apg->lastConfigure.width,
|
||||||
apg->lastConfigure.height );
|
apg->lastConfigure.height );
|
||||||
db_store( apg->params->pDb, KEY_WIN_LOC, buf );
|
db_store( apg->cag.params->pDb, KEY_WIN_LOC, buf );
|
||||||
|
|
||||||
gtk_main_quit();
|
gtk_main_quit();
|
||||||
}
|
}
|
||||||
|
@ -477,7 +481,7 @@ static void
|
||||||
setWindowTitle( GtkAppGlobals* apg )
|
setWindowTitle( GtkAppGlobals* apg )
|
||||||
{
|
{
|
||||||
GtkWidget* window = apg->window;
|
GtkWidget* window = apg->window;
|
||||||
LaunchParams* params = apg->params;
|
LaunchParams* params = apg->cag.params;
|
||||||
|
|
||||||
gchar title[128] = {0};
|
gchar title[128] = {0};
|
||||||
if ( !!params->dbName ) {
|
if ( !!params->dbName ) {
|
||||||
|
@ -505,7 +509,7 @@ trySetWinConfig( GtkAppGlobals* apg )
|
||||||
int height = 400;
|
int height = 400;
|
||||||
|
|
||||||
gchar buf[64];
|
gchar buf[64];
|
||||||
if ( db_fetch_safe( apg->params->pDb, KEY_WIN_LOC, buf, sizeof(buf)) ) {
|
if ( db_fetch_safe( apg->cag.params->pDb, KEY_WIN_LOC, buf, sizeof(buf)) ) {
|
||||||
sscanf( buf, "%d:%d:%d:%d", &xx, &yy, &width, &height );
|
sscanf( buf, "%d:%d:%d:%d", &xx, &yy, &width, &height );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,14 +520,14 @@ trySetWinConfig( GtkAppGlobals* apg )
|
||||||
static void
|
static void
|
||||||
handle_movescheck( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* apg )
|
handle_movescheck( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* apg )
|
||||||
{
|
{
|
||||||
LaunchParams* params = apg->params;
|
LaunchParams* params = apg->cag.params;
|
||||||
relaycon_checkMsgs( params );
|
relaycon_checkMsgs( params );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_relayid_to_clip( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* apg )
|
handle_relayid_to_clip( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* apg )
|
||||||
{
|
{
|
||||||
LaunchParams* params = apg->params;
|
LaunchParams* params = apg->cag.params;
|
||||||
XP_U32 relayID = linux_getDevIDRelay( params );
|
XP_U32 relayID = linux_getDevIDRelay( params );
|
||||||
gchar str[32];
|
gchar str[32];
|
||||||
snprintf( &str[0], VSIZE(str), "%d", relayID );
|
snprintf( &str[0], VSIZE(str), "%d", relayID );
|
||||||
|
@ -535,7 +539,7 @@ static void
|
||||||
makeGamesWindow( GtkAppGlobals* apg )
|
makeGamesWindow( GtkAppGlobals* apg )
|
||||||
{
|
{
|
||||||
GtkWidget* window;
|
GtkWidget* window;
|
||||||
LaunchParams* params = apg->params;
|
LaunchParams* params = apg->cag.params;
|
||||||
|
|
||||||
apg->window = window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
|
apg->window = window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
|
||||||
g_signal_connect( G_OBJECT(window), "destroy",
|
g_signal_connect( G_OBJECT(window), "destroy",
|
||||||
|
@ -602,7 +606,7 @@ static GtkWidget*
|
||||||
openDBFile( GtkAppGlobals* apg )
|
openDBFile( GtkAppGlobals* apg )
|
||||||
{
|
{
|
||||||
GtkGameGlobals* globals = malloc( sizeof(*globals) );
|
GtkGameGlobals* globals = malloc( sizeof(*globals) );
|
||||||
initGlobals( globals, apg->params, NULL );
|
initBoardGlobalsGtk( globals, apg->cag.params, NULL );
|
||||||
|
|
||||||
GtkWidget* window = globals->window;
|
GtkWidget* window = globals->window;
|
||||||
gtk_widget_show( window );
|
gtk_widget_show( window );
|
||||||
|
@ -633,7 +637,7 @@ static void
|
||||||
onNewData( GtkAppGlobals* apg, sqlite3_int64 rowid, XP_Bool isNew )
|
onNewData( GtkAppGlobals* apg, sqlite3_int64 rowid, XP_Bool isNew )
|
||||||
{
|
{
|
||||||
GameInfo gib;
|
GameInfo gib;
|
||||||
if ( getGameInfo( apg->params->pDb, rowid, &gib ) ) {
|
if ( getGameInfo( apg->cag.params->pDb, rowid, &gib ) ) {
|
||||||
add_to_list( apg->listWidget, rowid, isNew, &gib );
|
add_to_list( apg->listWidget, rowid, isNew, &gib );
|
||||||
g_object_unref( gib.snap );
|
g_object_unref( gib.snap );
|
||||||
}
|
}
|
||||||
|
@ -651,31 +655,22 @@ feedBufferGTK( GtkAppGlobals* apg, sqlite3_int64 rowid,
|
||||||
seed = comms_getChannelSeed( globals->cGlobals.game.comms );
|
seed = comms_getChannelSeed( globals->cGlobals.game.comms );
|
||||||
} else {
|
} else {
|
||||||
GtkGameGlobals tmpGlobals;
|
GtkGameGlobals tmpGlobals;
|
||||||
if ( loadGameNoDraw( &tmpGlobals, apg->params, rowid ) ) {
|
if ( loadGameNoDraw( &tmpGlobals, apg->cag.params, rowid ) ) {
|
||||||
gameGotBuf( &tmpGlobals.cGlobals, XP_FALSE, buf, len, from );
|
gameGotBuf( &tmpGlobals.cGlobals, XP_FALSE, buf, len, from );
|
||||||
seed = comms_getChannelSeed( tmpGlobals.cGlobals.game.comms );
|
seed = comms_getChannelSeed( tmpGlobals.cGlobals.game.comms );
|
||||||
saveGame( &tmpGlobals.cGlobals );
|
linuxSaveGame( &tmpGlobals.cGlobals );
|
||||||
}
|
}
|
||||||
freeGlobals( &tmpGlobals );
|
freeGlobals( &tmpGlobals );
|
||||||
}
|
}
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gtkSocketAdded( void* closure, int newSock, GIOFunc proc )
|
|
||||||
{
|
|
||||||
GIOChannel* channel = g_io_channel_unix_new( newSock );
|
|
||||||
(void)g_io_add_watch( channel, G_IO_IN | G_IO_ERR, proc, closure );
|
|
||||||
LOG_RETURN_VOID();
|
|
||||||
} /* gtk_socket_changed */
|
|
||||||
|
|
||||||
|
|
||||||
/* Stuff common to receiving invitations */
|
/* Stuff common to receiving invitations */
|
||||||
static void
|
static void
|
||||||
gameFromInvite( GtkAppGlobals* apg, const NetLaunchInfo* invite,
|
gameFromInvite( GtkAppGlobals* apg, const NetLaunchInfo* invite,
|
||||||
const CommsAddrRec* returnAddr )
|
const CommsAddrRec* returnAddr )
|
||||||
{
|
{
|
||||||
LaunchParams* params = apg->params;
|
LaunchParams* params = apg->cag.params;
|
||||||
CurGameInfo gi = {0};
|
CurGameInfo gi = {0};
|
||||||
gi_copy( MPPARM(params->mpool) &gi, ¶ms->pgi );
|
gi_copy( MPPARM(params->mpool) &gi, ¶ms->pgi );
|
||||||
|
|
||||||
|
@ -688,7 +683,7 @@ gameFromInvite( GtkAppGlobals* apg, const NetLaunchInfo* invite,
|
||||||
|
|
||||||
GtkGameGlobals* globals = malloc( sizeof(*globals) );
|
GtkGameGlobals* globals = malloc( sizeof(*globals) );
|
||||||
params->needsNewGame = XP_FALSE;
|
params->needsNewGame = XP_FALSE;
|
||||||
initGlobals( globals, params, &gi );
|
initBoardGlobalsGtk( globals, params, &gi );
|
||||||
|
|
||||||
if ( !!returnAddr ) {
|
if ( !!returnAddr ) {
|
||||||
globals->cGlobals.addr = *returnAddr;
|
globals->cGlobals.addr = *returnAddr;
|
||||||
|
@ -697,7 +692,7 @@ gameFromInvite( GtkAppGlobals* apg, const NetLaunchInfo* invite,
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget* gameWindow = globals->window;
|
GtkWidget* gameWindow = globals->window;
|
||||||
globals->cGlobals.selRow = -1;
|
globals->cGlobals.rowid = -1;
|
||||||
recordOpened( apg, globals );
|
recordOpened( apg, globals );
|
||||||
gtk_widget_show( gameWindow );
|
gtk_widget_show( gameWindow );
|
||||||
|
|
||||||
|
@ -712,7 +707,7 @@ relayInviteReceived( void* closure, NetLaunchInfo* invite )
|
||||||
XP_U32 gameID = invite->gameID;
|
XP_U32 gameID = invite->gameID;
|
||||||
sqlite3_int64 rowids[1];
|
sqlite3_int64 rowids[1];
|
||||||
int nRowIDs = VSIZE(rowids);
|
int nRowIDs = VSIZE(rowids);
|
||||||
getRowsForGameID( apg->params->pDb, gameID, rowids, &nRowIDs );
|
getRowsForGameID( apg->cag.params->pDb, gameID, rowids, &nRowIDs );
|
||||||
|
|
||||||
if ( 0 < nRowIDs ) {
|
if ( 0 < nRowIDs ) {
|
||||||
gtktell( apg->window, "Duplicate invite rejected" );
|
gtktell( apg->window, "Duplicate invite rejected" );
|
||||||
|
@ -748,7 +743,7 @@ gtkGotMsgForRow( void* closure, const CommsAddrRec* from,
|
||||||
{
|
{
|
||||||
XP_LOGF( "%s(): got msg of len %d for row %lld", __func__, len, rowid );
|
XP_LOGF( "%s(): got msg of len %d for row %lld", __func__, len, rowid );
|
||||||
GtkAppGlobals* apg = (GtkAppGlobals*)closure;
|
GtkAppGlobals* apg = (GtkAppGlobals*)closure;
|
||||||
// LaunchParams* params = apg->params;
|
// LaunchParams* params = apg->cag.params;
|
||||||
(void)feedBufferGTK( apg, rowid, buf, len, from );
|
(void)feedBufferGTK( apg, rowid, buf, len, from );
|
||||||
LOG_RETURN_VOID();
|
LOG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
@ -758,9 +753,9 @@ requestMsgs( gpointer data )
|
||||||
{
|
{
|
||||||
GtkAppGlobals* apg = (GtkAppGlobals*)data;
|
GtkAppGlobals* apg = (GtkAppGlobals*)data;
|
||||||
XP_UCHAR devIDBuf[64] = {0};
|
XP_UCHAR devIDBuf[64] = {0};
|
||||||
db_fetch_safe( apg->params->pDb, KEY_RDEVID, devIDBuf, sizeof(devIDBuf) );
|
db_fetch_safe( apg->cag.params->pDb, KEY_RDEVID, devIDBuf, sizeof(devIDBuf) );
|
||||||
if ( '\0' != devIDBuf[0] ) {
|
if ( '\0' != devIDBuf[0] ) {
|
||||||
relaycon_requestMsgs( apg->params, devIDBuf );
|
relaycon_requestMsgs( apg->cag.params, devIDBuf );
|
||||||
} else {
|
} else {
|
||||||
XP_LOGF( "%s: not requesting messages as don't have relay id", __func__ );
|
XP_LOGF( "%s: not requesting messages as don't have relay id", __func__ );
|
||||||
}
|
}
|
||||||
|
@ -794,7 +789,7 @@ smsMsgReceivedGTK( void* closure, const CommsAddrRec* from, XP_U32 gameID,
|
||||||
{
|
{
|
||||||
LOG_FUNC();
|
LOG_FUNC();
|
||||||
GtkAppGlobals* apg = (GtkAppGlobals*)closure;
|
GtkAppGlobals* apg = (GtkAppGlobals*)closure;
|
||||||
LaunchParams* params = apg->params;
|
LaunchParams* params = apg->cag.params;
|
||||||
|
|
||||||
sqlite3_int64 rowids[4];
|
sqlite3_int64 rowids[4];
|
||||||
int nRowIDs = VSIZE(rowids);
|
int nRowIDs = VSIZE(rowids);
|
||||||
|
@ -817,7 +812,7 @@ static void
|
||||||
gtkDevIDReceived( void* closure, const XP_UCHAR* devID, XP_U16 maxInterval )
|
gtkDevIDReceived( void* closure, const XP_UCHAR* devID, XP_U16 maxInterval )
|
||||||
{
|
{
|
||||||
GtkAppGlobals* apg = (GtkAppGlobals*)closure;
|
GtkAppGlobals* apg = (GtkAppGlobals*)closure;
|
||||||
LaunchParams* params = apg->params;
|
LaunchParams* params = apg->cag.params;
|
||||||
if ( !!devID ) {
|
if ( !!devID ) {
|
||||||
XP_LOGF( "%s(devID=%s)", __func__, devID );
|
XP_LOGF( "%s(devID=%s)", __func__, devID );
|
||||||
db_store( params->pDb, KEY_RDEVID, devID );
|
db_store( params->pDb, KEY_RDEVID, devID );
|
||||||
|
@ -842,8 +837,7 @@ gtkErrorMsgRcvd( void* closure, const XP_UCHAR* msg )
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
onGameSaved( void* closure, sqlite3_int64 rowid,
|
gtkOnGameSaved( void* closure, sqlite3_int64 rowid, XP_Bool firstTime )
|
||||||
XP_Bool firstTime )
|
|
||||||
{
|
{
|
||||||
GtkGameGlobals* globals = (GtkGameGlobals*)closure;
|
GtkGameGlobals* globals = (GtkGameGlobals*)closure;
|
||||||
GtkAppGlobals* apg = globals->apg;
|
GtkAppGlobals* apg = globals->apg;
|
||||||
|
@ -874,10 +868,10 @@ gtkmain( LaunchParams* params )
|
||||||
sigaction( SIGTERM, &act, NULL );
|
sigaction( SIGTERM, &act, NULL );
|
||||||
|
|
||||||
apg.selRows = g_array_new( FALSE, FALSE, sizeof( sqlite3_int64 ) );
|
apg.selRows = g_array_new( FALSE, FALSE, sizeof( sqlite3_int64 ) );
|
||||||
apg.params = params;
|
apg.cag.params = params;
|
||||||
XP_ASSERT( !!params->dbName || params->dbFileName );
|
XP_ASSERT( !!params->dbName || params->dbFileName );
|
||||||
if ( !!params->dbName ) {
|
if ( !!params->dbName ) {
|
||||||
params->pDb = openGamesDB( params->dbName );
|
/* params->pDb = openGamesDB( params->dbName ); */
|
||||||
|
|
||||||
/* Check if we have a local ID already. If we do and it's
|
/* Check if we have a local ID already. If we do and it's
|
||||||
changed, we care. */
|
changed, we care. */
|
||||||
|
@ -890,7 +884,6 @@ gtkmain( LaunchParams* params )
|
||||||
.msgNoticeReceived = gtkNoticeRcvd,
|
.msgNoticeReceived = gtkNoticeRcvd,
|
||||||
.devIDReceived = gtkDevIDReceived,
|
.devIDReceived = gtkDevIDReceived,
|
||||||
.msgErrorMsg = gtkErrorMsgRcvd,
|
.msgErrorMsg = gtkErrorMsgRcvd,
|
||||||
.socketAdded = gtkSocketAdded,
|
|
||||||
.inviteReceived = relayInviteReceived,
|
.inviteReceived = relayInviteReceived,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -919,7 +912,6 @@ gtkmain( LaunchParams* params )
|
||||||
}
|
}
|
||||||
if ( !!myPhone && 0 < myPort ) {
|
if ( !!myPhone && 0 < myPort ) {
|
||||||
SMSProcs smsProcs = {
|
SMSProcs smsProcs = {
|
||||||
.socketAdded = gtkSocketAdded,
|
|
||||||
.inviteReceived = smsInviteReceived,
|
.inviteReceived = smsInviteReceived,
|
||||||
.msgReceived = smsMsgReceivedGTK,
|
.msgReceived = smsMsgReceivedGTK,
|
||||||
};
|
};
|
||||||
|
@ -943,8 +935,8 @@ gtkmain( LaunchParams* params )
|
||||||
|
|
||||||
gtk_main();
|
gtk_main();
|
||||||
device_store( params->dutil );
|
device_store( params->dutil );
|
||||||
closeGamesDB( params->pDb );
|
/* closeGamesDB( params->pDb ); */
|
||||||
params->pDb = NULL;
|
/* params->pDb = NULL; */
|
||||||
relaycon_cleanup( params );
|
relaycon_cleanup( params );
|
||||||
#ifdef XWFEATURE_SMS
|
#ifdef XWFEATURE_SMS
|
||||||
linux_sms_cleanup( params );
|
linux_sms_cleanup( params );
|
||||||
|
|
|
@ -25,8 +25,7 @@
|
||||||
|
|
||||||
int gtkmain( LaunchParams* params );
|
int gtkmain( LaunchParams* params );
|
||||||
void windowDestroyed( GtkGameGlobals* globals );
|
void windowDestroyed( GtkGameGlobals* globals );
|
||||||
void onGameSaved( void* closure, sqlite3_int64 rowid, XP_Bool firstTime );
|
void gtkOnGameSaved( void* closure, sqlite3_int64 rowid, XP_Bool firstTime );
|
||||||
void open_row( GtkAppGlobals* apg, sqlite3_int64 row, XP_Bool isNew );
|
|
||||||
void make_rematch( GtkAppGlobals* apg, const CommonGlobals* cGlobals );
|
void make_rematch( GtkAppGlobals* apg, const CommonGlobals* cGlobals );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -639,8 +639,8 @@ setDefaults( CurGameInfo* gi )
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
newGameDialog( GtkGameGlobals* globals, CurGameInfo* gi, CommsAddrRec* addr,
|
gtkNewGameDialog( GtkGameGlobals* globals, CurGameInfo* gi, CommsAddrRec* addr,
|
||||||
XP_Bool isNewGame, XP_Bool fireConnDlg )
|
XP_Bool isNewGame, XP_Bool fireConnDlg )
|
||||||
{
|
{
|
||||||
GtkNewGameState state;
|
GtkNewGameState state;
|
||||||
XP_MEMSET( &state, 0, sizeof(state) );
|
XP_MEMSET( &state, 0, sizeof(state) );
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
|
|
||||||
#include "gtkboard.h"
|
#include "gtkboard.h"
|
||||||
|
|
||||||
gboolean newGameDialog( GtkGameGlobals* globals, CurGameInfo* gi,
|
gboolean gtkNewGameDialog( GtkGameGlobals* globals, CurGameInfo* gi,
|
||||||
CommsAddrRec* addr, XP_Bool isNewGame,
|
CommsAddrRec* addr, XP_Bool isNewGame,
|
||||||
XP_Bool fireConnDlg );
|
XP_Bool fireConnDlg );
|
||||||
|
|
||||||
#endif /* _GTKNEWGAME_H_ */
|
#endif /* _GTKNEWGAME_H_ */
|
||||||
#endif /* PLATFORM_GTK */
|
#endif /* PLATFORM_GTK */
|
||||||
|
|
|
@ -94,7 +94,7 @@ dutils_init( MPFORMAL VTableMgr* vtMgr, void* closure )
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dutils_free( XW_DUtilCtxt** ducp )
|
void dutils_free( XW_DUtilCtxt** XP_UNUSED_DBG(ducp) )
|
||||||
{
|
{
|
||||||
# ifdef MEM_DEBUG
|
# ifdef MEM_DEBUG
|
||||||
XP_FREEP( (*ducp)->mpool, ducp );
|
XP_FREEP( (*ducp)->mpool, ducp );
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
#include "strutils.h"
|
#include "strutils.h"
|
||||||
#include "uuidhack.h"
|
#include "uuidhack.h"
|
||||||
|
#include "gsrcwrap.h"
|
||||||
|
|
||||||
#define MAX_CLIENTS 1
|
#define MAX_CLIENTS 1
|
||||||
|
|
||||||
|
@ -186,7 +187,7 @@ lbt_connectSocket( LinBtStuff* btStuff, const CommsAddrRec* addrP )
|
||||||
// connect to server
|
// connect to server
|
||||||
&& (0 == connect( sock, (struct sockaddr *)&saddr, sizeof(saddr) )) ) {
|
&& (0 == connect( sock, (struct sockaddr *)&saddr, sizeof(saddr) )) ) {
|
||||||
CommonGlobals* globals = btStuff->globals;
|
CommonGlobals* globals = btStuff->globals;
|
||||||
(*globals->socketAdded)( globals->socketAddedClosure, sock, bt_socket_proc );
|
ADD_SOCKET( globals->socketAddedClosure, sock, bt_socket_proc );
|
||||||
btStuff->socket = sock;
|
btStuff->socket = sock;
|
||||||
} else {
|
} else {
|
||||||
XP_LOGF( "%s: connect->%s; closing socket %d", __func__, strerror(errno), sock );
|
XP_LOGF( "%s: connect->%s; closing socket %d", __func__, strerror(errno), sock );
|
||||||
|
@ -215,7 +216,7 @@ lbt_accept( int listener, void* ctxt )
|
||||||
|
|
||||||
success = sock >= 0;
|
success = sock >= 0;
|
||||||
if ( success ) {
|
if ( success ) {
|
||||||
(*globals->socketAdded)( globals->socketAddedClosure, sock, bt_socket_proc );
|
ADD_SOCKET( globals->socketAddedClosure, sock, bt_socket_proc );
|
||||||
XP_ASSERT( btStuff->socket == -1 );
|
XP_ASSERT( btStuff->socket == -1 );
|
||||||
btStuff->socket = sock;
|
btStuff->socket = sock;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
#include "strutils.h"
|
#include "strutils.h"
|
||||||
#include "dbgutil.h"
|
#include "dbgutil.h"
|
||||||
#include "dictiter.h"
|
#include "dictiter.h"
|
||||||
|
#include "gsrcwrap.h"
|
||||||
/* #include "commgr.h" */
|
/* #include "commgr.h" */
|
||||||
/* #include "compipe.h" */
|
/* #include "compipe.h" */
|
||||||
#include "memstream.h"
|
#include "memstream.h"
|
||||||
|
@ -80,6 +81,12 @@
|
||||||
#define DEFAULT_PORT 10997
|
#define DEFAULT_PORT 10997
|
||||||
#define DEFAULT_LISTEN_PORT 4998
|
#define DEFAULT_LISTEN_PORT 4998
|
||||||
|
|
||||||
|
#ifdef MEM_DEBUG
|
||||||
|
# define MEMPOOL cGlobals->util->mpool,
|
||||||
|
#else
|
||||||
|
# define MEMPOOL
|
||||||
|
#endif
|
||||||
|
|
||||||
static int blocking_read( int fd, unsigned char* buf, const int len );
|
static int blocking_read( int fd, unsigned char* buf, const int len );
|
||||||
|
|
||||||
XP_Bool
|
XP_Bool
|
||||||
|
@ -120,6 +127,191 @@ streamFromFile( CommonGlobals* cGlobals, char* name )
|
||||||
return stream;
|
return stream;
|
||||||
} /* streamFromFile */
|
} /* streamFromFile */
|
||||||
|
|
||||||
|
void
|
||||||
|
tryConnectToServer( CommonGlobals* cGlobals )
|
||||||
|
{
|
||||||
|
LaunchParams* params = cGlobals->params;
|
||||||
|
XWStreamCtxt* stream =
|
||||||
|
mem_stream_make( MPPARM(cGlobals->util->mpool) params->vtMgr,
|
||||||
|
cGlobals, CHANNEL_NONE,
|
||||||
|
sendOnClose );
|
||||||
|
(void)server_initClientConnection( cGlobals->game.server,
|
||||||
|
stream );
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
canMakeFromGI( const CurGameInfo* gi )
|
||||||
|
{
|
||||||
|
LOG_FUNC();
|
||||||
|
bool result = 0 < gi->nPlayers
|
||||||
|
&& 0 < gi->dictLang
|
||||||
|
;
|
||||||
|
bool haveDict = !!gi->dictName;
|
||||||
|
bool allHaveDicts = true;
|
||||||
|
for ( int ii = 0; result && ii < gi->nPlayers; ++ii ) {
|
||||||
|
const LocalPlayer* lp = &gi->players[ii];
|
||||||
|
result = !lp->isLocal || '\0' != lp->name[0];
|
||||||
|
if ( allHaveDicts ) {
|
||||||
|
allHaveDicts = !!lp->dictName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = result && (haveDict || allHaveDicts);
|
||||||
|
|
||||||
|
LOG_RETURNF( "%d", result );
|
||||||
|
XP_ASSERT( result );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs )
|
||||||
|
{
|
||||||
|
LOG_FUNC();
|
||||||
|
XWStreamCtxt* stream = NULL;
|
||||||
|
XP_Bool opened = XP_FALSE;
|
||||||
|
|
||||||
|
LaunchParams* params = cGlobals->params;
|
||||||
|
if ( !!params->fileName && file_exists( params->fileName ) ) {
|
||||||
|
stream = streamFromFile( cGlobals, params->fileName );
|
||||||
|
#ifdef USE_SQLITE
|
||||||
|
} else if ( !!params->dbFileName && file_exists( params->dbFileName ) ) {
|
||||||
|
XP_UCHAR buf[32];
|
||||||
|
XP_SNPRINTF( buf, sizeof(buf), "%d", params->dbFileID );
|
||||||
|
mpool_setTag( MEMPOOL buf );
|
||||||
|
stream = streamFromDB( cGlobals );
|
||||||
|
#endif
|
||||||
|
} else if ( !!params->pDb && 0 <= cGlobals->rowid ) {
|
||||||
|
stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool)
|
||||||
|
params->vtMgr );
|
||||||
|
if ( !loadGame( stream, params->pDb, cGlobals->rowid ) ) {
|
||||||
|
stream_destroy( stream );
|
||||||
|
stream = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !!stream ) {
|
||||||
|
if ( NULL == cGlobals->dict ) {
|
||||||
|
cGlobals->dict = makeDictForStream( cGlobals, stream );
|
||||||
|
}
|
||||||
|
|
||||||
|
opened = game_makeFromStream( MEMPOOL stream, &cGlobals->game,
|
||||||
|
cGlobals->gi, cGlobals->dict,
|
||||||
|
&cGlobals->dicts, cGlobals->util,
|
||||||
|
cGlobals->draw,
|
||||||
|
&cGlobals->cp, procs );
|
||||||
|
XP_LOGF( "%s: loaded gi at %p", __func__, &cGlobals->gi );
|
||||||
|
stream_destroy( stream );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !opened && canMakeFromGI( cGlobals->gi ) ) {
|
||||||
|
|
||||||
|
#ifdef XWFEATURE_RELAY
|
||||||
|
/* if ( addr.conType == COMMS_CONN_RELAY ) { */
|
||||||
|
/* XP_ASSERT( !!params->connInfo.relay.relayName ); */
|
||||||
|
/* globals->cGlobals.defaultServerName */
|
||||||
|
/* = params->connInfo.relay.relayName; */
|
||||||
|
/* } */
|
||||||
|
#endif
|
||||||
|
game_makeNewGame( MEMPOOL &cGlobals->game, cGlobals->gi,
|
||||||
|
cGlobals->util, cGlobals->draw,
|
||||||
|
&cGlobals->cp, procs
|
||||||
|
#ifdef SET_GAMESEED
|
||||||
|
, params->gameSeed
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
CommsAddrRec addr = cGlobals->addr;
|
||||||
|
// addr.conType = params->conType;
|
||||||
|
CommsConnType typ;
|
||||||
|
for ( XP_U32 st = 0; addr_iter( &addr, &typ, &st ); ) {
|
||||||
|
if ( params->commsDisableds[typ][0] ) {
|
||||||
|
comms_setAddrDisabled( cGlobals->game.comms, typ, XP_FALSE, XP_TRUE );
|
||||||
|
}
|
||||||
|
if ( params->commsDisableds[typ][1] ) {
|
||||||
|
comms_setAddrDisabled( cGlobals->game.comms, typ, XP_TRUE, XP_TRUE );
|
||||||
|
}
|
||||||
|
switch( typ ) {
|
||||||
|
#ifdef XWFEATURE_RELAY
|
||||||
|
case COMMS_CONN_RELAY:
|
||||||
|
/* addr.u.ip_relay.ipAddr = 0; */
|
||||||
|
/* addr.u.ip_relay.port = params->connInfo.relay.defaultSendPort; */
|
||||||
|
/* addr.u.ip_relay.seeksPublicRoom = params->connInfo.relay.seeksPublicRoom; */
|
||||||
|
/* addr.u.ip_relay.advertiseRoom = params->connInfo.relay.advertiseRoom; */
|
||||||
|
/* XP_STRNCPY( addr.u.ip_relay.hostName, params->connInfo.relay.relayName, */
|
||||||
|
/* sizeof(addr.u.ip_relay.hostName) - 1 ); */
|
||||||
|
/* XP_STRNCPY( addr.u.ip_relay.invite, params->connInfo.relay.invite, */
|
||||||
|
/* sizeof(addr.u.ip_relay.invite) - 1 ); */
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef XWFEATURE_BLUETOOTH
|
||||||
|
case COMMS_CONN_BT:
|
||||||
|
XP_ASSERT( sizeof(addr.u.bt.btAddr)
|
||||||
|
>= sizeof(params->connInfo.bt.hostAddr));
|
||||||
|
XP_MEMCPY( &addr.u.bt.btAddr, ¶ms->connInfo.bt.hostAddr,
|
||||||
|
sizeof(params->connInfo.bt.hostAddr) );
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef XWFEATURE_IP_DIRECT
|
||||||
|
case COMMS_CONN_IP_DIRECT:
|
||||||
|
XP_STRNCPY( addr.u.ip.hostName_ip, params->connInfo.ip.hostName,
|
||||||
|
sizeof(addr.u.ip.hostName_ip) - 1 );
|
||||||
|
addr.u.ip.port_ip = params->connInfo.ip.port;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef XWFEATURE_SMS
|
||||||
|
case COMMS_CONN_SMS:
|
||||||
|
/* No! Don't overwrite what may be a return address with local
|
||||||
|
stuff */
|
||||||
|
/* XP_STRNCPY( addr.u.sms.phone, params->connInfo.sms.phone, */
|
||||||
|
/* sizeof(addr.u.sms.phone) - 1 ); */
|
||||||
|
/* addr.u.sms.port = params->connInfo.sms.port; */
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model_setDictionary( cGlobals->game.model, cGlobals->dict );
|
||||||
|
setSquareBonuses( cGlobals );
|
||||||
|
model_setPlayerDicts( cGlobals->game.model, &cGlobals->dicts );
|
||||||
|
|
||||||
|
/* Need to save in order to have a valid selRow for the first send */
|
||||||
|
linuxSaveGame( cGlobals );
|
||||||
|
|
||||||
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
|
/* This may trigger network activity */
|
||||||
|
if ( !!cGlobals->game.comms ) {
|
||||||
|
comms_setAddr( cGlobals->game.comms, &addr );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef XWFEATURE_SEARCHLIMIT
|
||||||
|
cGlobals->gi->allowHintRect = params->allowHintRect;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( params->needsNewGame ) {
|
||||||
|
XP_ASSERT(0);
|
||||||
|
// new_game_impl( globals, XP_FALSE );
|
||||||
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
|
} else {
|
||||||
|
DeviceRole serverRole = cGlobals->gi->serverRole;
|
||||||
|
if ( serverRole == SERVER_ISCLIENT ) {
|
||||||
|
tryConnectToServer( cGlobals );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
|
if ( !!cGlobals->game.comms ) {
|
||||||
|
comms_start( cGlobals->game.comms );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
server_do( cGlobals->game.server );
|
||||||
|
linuxSaveGame( cGlobals ); /* again, to include address etc. */
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_SQLITE
|
#ifdef USE_SQLITE
|
||||||
XWStreamCtxt*
|
XWStreamCtxt*
|
||||||
streamFromDB( CommonGlobals* cGlobals )
|
streamFromDB( CommonGlobals* cGlobals )
|
||||||
|
@ -189,7 +381,7 @@ gameGotBuf( CommonGlobals* cGlobals, XP_Bool hasDraw, const XP_U8* buf,
|
||||||
if ( !!stream ) {
|
if ( !!stream ) {
|
||||||
redraw = game_receiveMessage( game, stream, from );
|
redraw = game_receiveMessage( game, stream, from );
|
||||||
if ( redraw ) {
|
if ( redraw ) {
|
||||||
saveGame( cGlobals );
|
linuxSaveGame( cGlobals );
|
||||||
}
|
}
|
||||||
stream_destroy( stream );
|
stream_destroy( stream );
|
||||||
|
|
||||||
|
@ -328,7 +520,7 @@ strFromStream( XWStreamCtxt* stream )
|
||||||
} /* strFromStream */
|
} /* strFromStream */
|
||||||
|
|
||||||
void
|
void
|
||||||
saveGame( CommonGlobals* cGlobals )
|
linuxSaveGame( CommonGlobals* cGlobals )
|
||||||
{
|
{
|
||||||
LOG_FUNC();
|
LOG_FUNC();
|
||||||
sqlite3* pDb = cGlobals->params->pDb;
|
sqlite3* pDb = cGlobals->params->pDb;
|
||||||
|
@ -336,7 +528,7 @@ saveGame( CommonGlobals* cGlobals )
|
||||||
(!!cGlobals->params->fileName || !!pDb) ) {
|
(!!cGlobals->params->fileName || !!pDb) ) {
|
||||||
XP_Bool doSave = XP_TRUE;
|
XP_Bool doSave = XP_TRUE;
|
||||||
XP_Bool newGame = !file_exists( cGlobals->params->fileName )
|
XP_Bool newGame = !file_exists( cGlobals->params->fileName )
|
||||||
|| -1 == cGlobals->selRow;
|
|| -1 == cGlobals->rowid;
|
||||||
/* don't fail to save first time! */
|
/* don't fail to save first time! */
|
||||||
if ( 0 < cGlobals->params->saveFailPct && !newGame ) {
|
if ( 0 < cGlobals->params->saveFailPct && !newGame ) {
|
||||||
XP_U16 pct = XP_RANDOM() % 100;
|
XP_U16 pct = XP_RANDOM() % 100;
|
||||||
|
@ -550,7 +742,14 @@ secondTimerFired( gpointer data )
|
||||||
void
|
void
|
||||||
setOneSecondTimer( CommonGlobals* cGlobals )
|
setOneSecondTimer( CommonGlobals* cGlobals )
|
||||||
{
|
{
|
||||||
(void)g_timeout_add_seconds( 1, secondTimerFired, cGlobals );
|
guint id = g_timeout_add_seconds( 1, secondTimerFired, cGlobals );
|
||||||
|
cGlobals->secondsTimerID = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearOneSecondTimer( CommonGlobals* cGlobals )
|
||||||
|
{
|
||||||
|
g_source_remove( cGlobals->secondsTimerID );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -603,6 +802,7 @@ typedef enum {
|
||||||
,CMD_NOHEARTBEAT
|
,CMD_NOHEARTBEAT
|
||||||
,CMD_HOSTNAME
|
,CMD_HOSTNAME
|
||||||
,CMD_CLOSESTDIN
|
,CMD_CLOSESTDIN
|
||||||
|
,CMD_NOCLOSESTDIN
|
||||||
,CMD_QUITAFTER
|
,CMD_QUITAFTER
|
||||||
,CMD_BOARDSIZE
|
,CMD_BOARDSIZE
|
||||||
,CMD_HIDEVALUES
|
,CMD_HIDEVALUES
|
||||||
|
@ -655,6 +855,7 @@ typedef enum {
|
||||||
#if defined PLATFORM_GTK && defined PLATFORM_NCURSES
|
#if defined PLATFORM_GTK && defined PLATFORM_NCURSES
|
||||||
,CMD_GTK
|
,CMD_GTK
|
||||||
,CMD_CURSES
|
,CMD_CURSES
|
||||||
|
,CMD_CURSES_LIST_HT
|
||||||
#endif
|
#endif
|
||||||
#if defined PLATFORM_GTK
|
#if defined PLATFORM_GTK
|
||||||
,CMD_ASKNEWGAME
|
,CMD_ASKNEWGAME
|
||||||
|
@ -725,6 +926,7 @@ static CmdInfoRec CmdInfoRecs[] = {
|
||||||
,{ CMD_NOHEARTBEAT, false, "no-heartbeat", "don't send heartbeats" }
|
,{ CMD_NOHEARTBEAT, false, "no-heartbeat", "don't send heartbeats" }
|
||||||
,{ CMD_HOSTNAME, true, "host", "name of remote host" }
|
,{ CMD_HOSTNAME, true, "host", "name of remote host" }
|
||||||
,{ CMD_CLOSESTDIN, false, "close-stdin", "close stdin on start" }
|
,{ CMD_CLOSESTDIN, false, "close-stdin", "close stdin on start" }
|
||||||
|
,{ CMD_NOCLOSESTDIN, false, "no-close-stdin", "do not close stdin on start" }
|
||||||
,{ CMD_QUITAFTER, true, "quit-after", "exit <n> seconds after game's done" }
|
,{ CMD_QUITAFTER, true, "quit-after", "exit <n> seconds after game's done" }
|
||||||
,{ CMD_BOARDSIZE, true, "board-size", "board is <n> by <n> cells" }
|
,{ CMD_BOARDSIZE, true, "board-size", "board is <n> by <n> cells" }
|
||||||
,{ CMD_HIDEVALUES, false, "hide-values", "show letters, not nums, on tiles" }
|
,{ CMD_HIDEVALUES, false, "hide-values", "show letters, not nums, on tiles" }
|
||||||
|
@ -784,6 +986,7 @@ static CmdInfoRec CmdInfoRecs[] = {
|
||||||
#if defined PLATFORM_GTK && defined PLATFORM_NCURSES
|
#if defined PLATFORM_GTK && defined PLATFORM_NCURSES
|
||||||
,{ CMD_GTK, false, "gtk", "use GTK for display" }
|
,{ CMD_GTK, false, "gtk", "use GTK for display" }
|
||||||
,{ CMD_CURSES, false, "curses", "use curses for display" }
|
,{ CMD_CURSES, false, "curses", "use curses for display" }
|
||||||
|
,{ CMD_CURSES_LIST_HT, true, "curses-list-ht", "how many cols tall is the games list" }
|
||||||
#endif
|
#endif
|
||||||
#if defined PLATFORM_GTK
|
#if defined PLATFORM_GTK
|
||||||
,{ CMD_ASKNEWGAME, false, "ask-new", "put up ui for new game params" }
|
,{ CMD_ASKNEWGAME, false, "ask-new", "put up ui for new game params" }
|
||||||
|
@ -1121,7 +1324,8 @@ linux_relay_ioproc( GIOChannel* source, GIOCondition condition, gpointer data )
|
||||||
unsigned char buf[1024];
|
unsigned char buf[1024];
|
||||||
int sock = g_io_channel_unix_get_fd( source );
|
int sock = g_io_channel_unix_get_fd( source );
|
||||||
if ( cGlobals->relaySocket != sock ) {
|
if ( cGlobals->relaySocket != sock ) {
|
||||||
XP_LOGF( "%s: changing relaySocket from %d to %d", __func__, cGlobals->relaySocket, sock );
|
XP_LOGF( "%s: changing relaySocket from %d to %d", __func__,
|
||||||
|
cGlobals->relaySocket, sock );
|
||||||
cGlobals->relaySocket = sock;
|
cGlobals->relaySocket = sock;
|
||||||
}
|
}
|
||||||
int nBytes = linux_relay_receive( cGlobals, sock, buf, sizeof(buf) );
|
int nBytes = linux_relay_receive( cGlobals, sock, buf, sizeof(buf) );
|
||||||
|
@ -1164,9 +1368,9 @@ linux_relay_send( CommonGlobals* cGlobals, const XP_U8* buf, XP_U16 buflen,
|
||||||
{
|
{
|
||||||
XP_S16 result = 0;
|
XP_S16 result = 0;
|
||||||
if ( cGlobals->params->useUdp ) {
|
if ( cGlobals->params->useUdp ) {
|
||||||
XP_ASSERT( -1 != cGlobals->selRow );
|
XP_ASSERT( -1 != cGlobals->rowid );
|
||||||
XP_U16 seed = comms_getChannelSeed( cGlobals->game.comms );
|
XP_U16 seed = comms_getChannelSeed( cGlobals->game.comms );
|
||||||
XP_U32 clientToken = makeClientToken( cGlobals->selRow, seed );
|
XP_U32 clientToken = makeClientToken( cGlobals->rowid, seed );
|
||||||
result = relaycon_send( cGlobals->params, buf, buflen,
|
result = relaycon_send( cGlobals->params, buf, buflen,
|
||||||
clientToken, addrRec );
|
clientToken, addrRec );
|
||||||
} else {
|
} else {
|
||||||
|
@ -1176,7 +1380,7 @@ linux_relay_send( CommonGlobals* cGlobals, const XP_U8* buf, XP_U16 buflen,
|
||||||
if ( sock == -1 ) {
|
if ( sock == -1 ) {
|
||||||
XP_LOGF( "%s: socket uninitialized", __func__ );
|
XP_LOGF( "%s: socket uninitialized", __func__ );
|
||||||
sock = linux_init_relay_socket( cGlobals, addrRec );
|
sock = linux_init_relay_socket( cGlobals, addrRec );
|
||||||
(*cGlobals->socketAdded)( cGlobals, sock, linux_relay_ioproc );
|
ADD_SOCKET( cGlobals, sock, linux_relay_ioproc );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( sock != -1 ) {
|
if ( sock != -1 ) {
|
||||||
|
@ -1262,7 +1466,7 @@ linux_send( const XP_U8* buf, XP_U16 buflen, const XP_UCHAR* XP_UNUSED_DBG(msgNo
|
||||||
#endif
|
#endif
|
||||||
#if defined XWFEATURE_BLUETOOTH
|
#if defined XWFEATURE_BLUETOOTH
|
||||||
case COMMS_CONN_BT: {
|
case COMMS_CONN_BT: {
|
||||||
XP_Bool isServer = comms_getIsServer( cGlobals->game.comms );
|
XP_Bool isServer = game_getIsServer( &cGlobals->game );
|
||||||
linux_bt_open( cGlobals, isServer );
|
linux_bt_open( cGlobals, isServer );
|
||||||
nSent = linux_bt_send( buf, buflen, addrRec, cGlobals );
|
nSent = linux_bt_send( buf, buflen, addrRec, cGlobals );
|
||||||
}
|
}
|
||||||
|
@ -1506,7 +1710,7 @@ linux_util_addrChange( XW_UtilCtxt* uc,
|
||||||
switch ( typ ) {
|
switch ( typ ) {
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#ifdef XWFEATURE_BLUETOOTH
|
||||||
case COMMS_CONN_BT: {
|
case COMMS_CONN_BT: {
|
||||||
XP_Bool isServer = comms_getIsServer( cGlobals->game.comms );
|
XP_Bool isServer = game_getIsServer( &cGlobals->game );
|
||||||
linux_bt_open( cGlobals, isServer );
|
linux_bt_open( cGlobals, isServer );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1530,18 +1734,10 @@ linux_util_addrChange( XW_UtilCtxt* uc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static gint
|
||||||
linuxSetIsServer( CommonGlobals* cGlobals, XP_Bool isServer )
|
changeRolesIdle( gpointer data )
|
||||||
{
|
|
||||||
XP_LOGF( "%s(isServer=%d)", __func__, isServer );
|
|
||||||
DeviceRole newRole = isServer? SERVER_ISSERVER : SERVER_ISCLIENT;
|
|
||||||
cGlobals->params->serverRole = newRole;
|
|
||||||
cGlobals->gi->serverRole = newRole;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
linuxChangeRoles( CommonGlobals* cGlobals )
|
|
||||||
{
|
{
|
||||||
|
CommonGlobals* cGlobals = (CommonGlobals*)data;
|
||||||
ServerCtxt* server = cGlobals->game.server;
|
ServerCtxt* server = cGlobals->game.server;
|
||||||
server_reset( server, cGlobals->game.comms );
|
server_reset( server, cGlobals->game.comms );
|
||||||
if ( SERVER_ISCLIENT == cGlobals->gi->serverRole ) {
|
if ( SERVER_ISCLIENT == cGlobals->gi->serverRole ) {
|
||||||
|
@ -1551,7 +1747,23 @@ linuxChangeRoles( CommonGlobals* cGlobals )
|
||||||
(void)server_initClientConnection( server, stream );
|
(void)server_initClientConnection( server, stream );
|
||||||
}
|
}
|
||||||
(void)server_do( server );
|
(void)server_do( server );
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
linux_util_setIsServer( XW_UtilCtxt* uc, XP_Bool isServer )
|
||||||
|
{
|
||||||
|
XP_LOGF( "%s(isServer=%d)", __func__, isServer );
|
||||||
|
CommonGlobals* cGlobals = (CommonGlobals*)uc->closure;
|
||||||
|
|
||||||
|
DeviceRole newRole = isServer? SERVER_ISSERVER : SERVER_ISCLIENT;
|
||||||
|
cGlobals->params->serverRole = newRole;
|
||||||
|
cGlobals->gi->serverRole = newRole;
|
||||||
|
|
||||||
|
(void)ADD_ONETIME_IDLE( changeRolesIdle, cGlobals );
|
||||||
|
XP_ASSERT( isServer == game_getIsServer( &cGlobals->game ) );
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
|
@ -1906,59 +2118,22 @@ setupLinuxUtilCallbacks( XW_UtilCtxt* util )
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
util->vtable->m_util_informMissing = linux_util_informMissing;
|
util->vtable->m_util_informMissing = linux_util_informMissing;
|
||||||
util->vtable->m_util_addrChange = linux_util_addrChange;
|
util->vtable->m_util_addrChange = linux_util_addrChange;
|
||||||
|
util->vtable->m_util_setIsServer = linux_util_setIsServer;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up cGlobals->gi and cGlobals->addr based on params fields */
|
|
||||||
void
|
void
|
||||||
initFromParams( CommonGlobals* cGlobals, LaunchParams* params )
|
assertAllCallbacksSet( XW_UtilCtxt* util )
|
||||||
{
|
{
|
||||||
LOG_FUNC();
|
LOG_FUNC();
|
||||||
/* CurGameInfo */
|
XWStreamCtxt* (**proc)(XW_UtilCtxt*, XP_PlayerAddr ) =
|
||||||
cGlobals->gi = ¶ms->pgi;
|
&util->vtable->m_util_makeStreamFromAddr;
|
||||||
|
for ( int ii = 0; ii < sizeof(*util->vtable)/sizeof(*proc); ++ii ) {
|
||||||
/* addr */
|
if ( !*proc ) {
|
||||||
CommsAddrRec* addr = &cGlobals->addr;
|
XP_LOGF( "%s(): null ptr at index %d", __func__, ii );
|
||||||
XP_MEMSET( addr, 0, sizeof(*addr) );
|
XP_ASSERT( 0 );
|
||||||
|
|
||||||
CommsConnType typ;
|
|
||||||
for ( XP_U32 st = 0; addr_iter( ¶ms->addr, &typ, &st ); ) {
|
|
||||||
switch( typ ) {
|
|
||||||
#ifdef XWFEATURE_RELAY
|
|
||||||
case COMMS_CONN_RELAY:
|
|
||||||
addr_addType( addr, COMMS_CONN_RELAY );
|
|
||||||
addr->u.ip_relay.ipAddr = 0; /* ??? */
|
|
||||||
addr->u.ip_relay.port = params->connInfo.relay.defaultSendPort;
|
|
||||||
addr->u.ip_relay.seeksPublicRoom =
|
|
||||||
params->connInfo.relay.seeksPublicRoom;
|
|
||||||
addr->u.ip_relay.advertiseRoom = params->connInfo.relay.advertiseRoom;
|
|
||||||
XP_STRNCPY( addr->u.ip_relay.hostName,
|
|
||||||
params->connInfo.relay.relayName,
|
|
||||||
sizeof(addr->u.ip_relay.hostName) - 1 );
|
|
||||||
XP_STRNCPY( addr->u.ip_relay.invite, params->connInfo.relay.invite,
|
|
||||||
sizeof(addr->u.ip_relay.invite) - 1 );
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef XWFEATURE_SMS
|
|
||||||
case COMMS_CONN_SMS:
|
|
||||||
addr_addType( addr, COMMS_CONN_SMS );
|
|
||||||
XP_STRNCPY( addr->u.sms.phone, params->connInfo.sms.myPhone,
|
|
||||||
sizeof(addr->u.sms.phone) - 1 );
|
|
||||||
addr->u.sms.port = params->connInfo.sms.port;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
|
||||||
case COMMS_CONN_BT:
|
|
||||||
addr_addType( addr, COMMS_CONN_BT );
|
|
||||||
XP_ASSERT( sizeof(addr->u.bt.btAddr)
|
|
||||||
>= sizeof(params->connInfo.bt.hostAddr));
|
|
||||||
XP_MEMCPY( &addr->u.bt.btAddr, ¶ms->connInfo.bt.hostAddr,
|
|
||||||
sizeof(params->connInfo.bt.hostAddr) );
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
++proc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1972,6 +2147,12 @@ setupUtil( CommonGlobals* cGlobals )
|
||||||
setupLinuxUtilCallbacks( util );
|
setupLinuxUtilCallbacks( util );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
disposeUtil( CommonGlobals* cGlobals )
|
||||||
|
{
|
||||||
|
linux_util_vt_destroy( cGlobals->util );
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
initParams( LaunchParams* params )
|
initParams( LaunchParams* params )
|
||||||
{
|
{
|
||||||
|
@ -2000,6 +2181,9 @@ initParams( LaunchParams* params )
|
||||||
static void
|
static void
|
||||||
freeParams( LaunchParams* params )
|
freeParams( LaunchParams* params )
|
||||||
{
|
{
|
||||||
|
closeGamesDB( params->pDb );
|
||||||
|
params->pDb = NULL;
|
||||||
|
|
||||||
vtmgr_destroy( MPPARM(params->mpool) params->vtMgr );
|
vtmgr_destroy( MPPARM(params->mpool) params->vtMgr );
|
||||||
dutils_free( ¶ms->dutil );
|
dutils_free( ¶ms->dutil );
|
||||||
dmgr_destroy( params->dictMgr );
|
dmgr_destroy( params->dictMgr );
|
||||||
|
@ -2116,6 +2300,7 @@ main( int argc, char** argv )
|
||||||
mainParams.useMmap = XP_TRUE;
|
mainParams.useMmap = XP_TRUE;
|
||||||
mainParams.useUdp = true;
|
mainParams.useUdp = true;
|
||||||
mainParams.dbName = "xwgames.sqldb";
|
mainParams.dbName = "xwgames.sqldb";
|
||||||
|
mainParams.cursesListWinHt = 5;
|
||||||
|
|
||||||
char* envDictPath = getenv( "XW_DICTDIR" );
|
char* envDictPath = getenv( "XW_DICTDIR" );
|
||||||
XP_LOGF( "%s: envDictPath=%s", __func__, envDictPath );
|
XP_LOGF( "%s: envDictPath=%s", __func__, envDictPath );
|
||||||
|
@ -2180,6 +2365,7 @@ main( int argc, char** argv )
|
||||||
if ( !path ) {
|
if ( !path ) {
|
||||||
path = ".";
|
path = ".";
|
||||||
}
|
}
|
||||||
|
XP_LOGF( "%s(): appending dict path: %s", __func__, path );
|
||||||
mainParams.dictDirs = g_slist_append( mainParams.dictDirs, path );
|
mainParams.dictDirs = g_slist_append( mainParams.dictDirs, path );
|
||||||
break;
|
break;
|
||||||
#ifdef XWFEATURE_WALKDICT
|
#ifdef XWFEATURE_WALKDICT
|
||||||
|
@ -2376,6 +2562,9 @@ main( int argc, char** argv )
|
||||||
case CMD_CLOSESTDIN:
|
case CMD_CLOSESTDIN:
|
||||||
mainParams.closeStdin = XP_TRUE;
|
mainParams.closeStdin = XP_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case CMD_NOCLOSESTDIN:
|
||||||
|
mainParams.closeStdin = XP_FALSE;
|
||||||
|
break;
|
||||||
case CMD_QUITAFTER:
|
case CMD_QUITAFTER:
|
||||||
mainParams.quitAfter = atoi(optarg);
|
mainParams.quitAfter = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
@ -2481,6 +2670,9 @@ main( int argc, char** argv )
|
||||||
case CMD_CURSES:
|
case CMD_CURSES:
|
||||||
mainParams.useCurses = XP_TRUE;
|
mainParams.useCurses = XP_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case CMD_CURSES_LIST_HT:
|
||||||
|
mainParams.cursesListWinHt = atoi(optarg);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if defined PLATFORM_GTK
|
#if defined PLATFORM_GTK
|
||||||
case CMD_ASKNEWGAME:
|
case CMD_ASKNEWGAME:
|
||||||
|
@ -2539,17 +2731,22 @@ main( int argc, char** argv )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XP_LOGF( "%s(): here: %s", __func__, mainParams.pgi.dictName );
|
||||||
if ( !!mainParams.pgi.dictName ) {
|
if ( !!mainParams.pgi.dictName ) {
|
||||||
|
XP_LOGF( "%s(): there", __func__ );
|
||||||
/* char path[256]; */
|
/* char path[256]; */
|
||||||
/* getDictPath( &mainParams, mainParams.gi.dictName, path, VSIZE(path) ); */
|
/* getDictPath( &mainParams, mainParams.gi.dictName, path, VSIZE(path) ); */
|
||||||
/* mainParams.dict = */
|
DictionaryCtxt* dict =
|
||||||
/* linux_dictionary_make( MPPARM(mainParams.mpool) &mainParams, */
|
linux_dictionary_make( MPPARM(mainParams.mpool) &mainParams,
|
||||||
/* mainParams.pgi.dictName, */
|
mainParams.pgi.dictName,
|
||||||
/* mainParams.useMmap ); */
|
mainParams.useMmap );
|
||||||
/* XP_ASSERT( !!mainParams.dict ); */
|
XP_ASSERT( !!dict );
|
||||||
/* mainParams.pgi.dictLang = dict_getLangCode( mainParams.dict ); */
|
mainParams.pgi.dictLang = dict_getLangCode( dict );
|
||||||
|
XP_LOGF( "%s(): set lang code: %d", __func__, mainParams.pgi.dictLang );
|
||||||
|
dict_unref( dict );
|
||||||
} else if ( isServer ) {
|
} else if ( isServer ) {
|
||||||
#ifdef STUBBED_DICT
|
#ifdef STUBBED_DICT
|
||||||
|
foo
|
||||||
mainParams.dict =
|
mainParams.dict =
|
||||||
make_stubbed_dict( MPPARM_NOCOMMA(mainParams.util->mpool) );
|
make_stubbed_dict( MPPARM_NOCOMMA(mainParams.util->mpool) );
|
||||||
XP_WARNF( "no dictionary provided: using English stub dict\n" );
|
XP_WARNF( "no dictionary provided: using English stub dict\n" );
|
||||||
|
@ -2666,21 +2863,19 @@ main( int argc, char** argv )
|
||||||
mainParams.serverRole = SERVER_ISCLIENT;
|
mainParams.serverRole = SERVER_ISCLIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if ( mainParams.needsNewGame ) { */
|
XP_ASSERT( !!mainParams.dbName );
|
||||||
/* gi_disposePlayerInfo( MPPARM(mainParams.mpool) &mainParams.pgi ); */
|
mainParams.pDb = openGamesDB( mainParams.dbName );
|
||||||
/* gi_initPlayerInfo( MPPARM(mainParams.mpool) &mainParams.pgi, NULL ); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
if ( mainParams.useCurses ) {
|
if ( mainParams.useCurses ) {
|
||||||
if ( mainParams.needsNewGame ) {
|
/* if ( mainParams.needsNewGame ) { */
|
||||||
/* curses doesn't have newgame dialog */
|
/* /\* curses doesn't have newgame dialog *\/ */
|
||||||
usage( argv[0], "game params required for curses version, e.g. --name Eric --room MyRoom"
|
/* usage( argv[0], "game params required for curses version, e.g. --name Eric --room MyRoom" */
|
||||||
" --remote-player --dict-dir ../ --game-dict CollegeEng_2to8.xwd");
|
/* " --remote-player --dict-dir ../ --game-dict CollegeEng_2to8.xwd"); */
|
||||||
} else {
|
/* } else { */
|
||||||
#if defined PLATFORM_NCURSES
|
#if defined PLATFORM_NCURSES
|
||||||
cursesmain( isServer, &mainParams );
|
cursesmain( isServer, &mainParams );
|
||||||
#endif
|
#endif
|
||||||
}
|
/* } */
|
||||||
} else {
|
} else {
|
||||||
#if defined PLATFORM_GTK
|
#if defined PLATFORM_GTK
|
||||||
gtk_init( &argc, &argv );
|
gtk_init( &argc, &argv );
|
||||||
|
@ -2694,6 +2889,8 @@ main( int argc, char** argv )
|
||||||
free( longopts );
|
free( longopts );
|
||||||
g_slist_free( mainParams.dictDirs );
|
g_slist_free( mainParams.dictDirs );
|
||||||
|
|
||||||
|
gsw_logIdles();
|
||||||
|
|
||||||
XP_LOGF( "%s exiting main, returning %d", argv[0], result );
|
XP_LOGF( "%s exiting main, returning %d", argv[0], result );
|
||||||
return result;
|
return result;
|
||||||
} /* main */
|
} /* main */
|
||||||
|
|
|
@ -70,7 +70,7 @@ void writeToFile( XWStreamCtxt* stream, void* closure );
|
||||||
XP_Bool getDictPath( const LaunchParams *params, const char* name,
|
XP_Bool getDictPath( const LaunchParams *params, const char* name,
|
||||||
char* result, int resultLen );
|
char* result, int resultLen );
|
||||||
GSList* listDicts( const LaunchParams *params );
|
GSList* listDicts( const LaunchParams *params );
|
||||||
void saveGame( CommonGlobals* cGlobals );
|
void linuxSaveGame( CommonGlobals* cGlobals );
|
||||||
|
|
||||||
void linux_close_socket( CommonGlobals* cGlobals );
|
void linux_close_socket( CommonGlobals* cGlobals );
|
||||||
|
|
||||||
|
@ -87,18 +87,18 @@ void do_nbs_then_close( CommonGlobals* cGlobals,
|
||||||
|
|
||||||
#ifdef USE_GLIBLOOP
|
#ifdef USE_GLIBLOOP
|
||||||
void setOneSecondTimer( CommonGlobals* cGlobals );
|
void setOneSecondTimer( CommonGlobals* cGlobals );
|
||||||
|
void clearOneSecondTimer( CommonGlobals* cGlobals );
|
||||||
#else
|
#else
|
||||||
# define setOneSecondTimer( cGlobals )
|
# define setOneSecondTimer( cGlobals )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void setupLinuxUtilCallbacks( XW_UtilCtxt* util );
|
void setupLinuxUtilCallbacks( XW_UtilCtxt* util );
|
||||||
void initFromParams( CommonGlobals* cGlobals, LaunchParams* params );
|
void assertAllCallbacksSet( XW_UtilCtxt* util );
|
||||||
void setupUtil( CommonGlobals* cGlobals );
|
void setupUtil( CommonGlobals* cGlobals );
|
||||||
|
void disposeUtil( CommonGlobals* cGlobals );
|
||||||
|
|
||||||
DictionaryCtxt* makeDictForStream( CommonGlobals* cGlobals,
|
DictionaryCtxt* makeDictForStream( CommonGlobals* cGlobals,
|
||||||
XWStreamCtxt* stream );
|
XWStreamCtxt* stream );
|
||||||
void linuxSetIsServer( CommonGlobals* cGlobals, XP_Bool isServer );
|
|
||||||
void linuxChangeRoles( CommonGlobals* cGlobals );
|
|
||||||
|
|
||||||
void sendRelayReg( LaunchParams* params, sqlite3* pDb );
|
void sendRelayReg( LaunchParams* params, sqlite3* pDb );
|
||||||
void gameGotBuf( CommonGlobals* globals, XP_Bool haveDraw,
|
void gameGotBuf( CommonGlobals* globals, XP_Bool haveDraw,
|
||||||
|
@ -111,6 +111,8 @@ void linux_doInitialReg( LaunchParams* params, XP_Bool idIsNew );
|
||||||
XP_Bool linux_setupDevidParams( LaunchParams* params );
|
XP_Bool linux_setupDevidParams( LaunchParams* params );
|
||||||
|
|
||||||
unsigned int makeRandomInt();
|
unsigned int makeRandomInt();
|
||||||
|
void linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs );
|
||||||
|
void tryConnectToServer( CommonGlobals* cGlobals );
|
||||||
|
|
||||||
/* void initParams( LaunchParams* params ); */
|
/* void initParams( LaunchParams* params ); */
|
||||||
/* void freeParams( LaunchParams* params ); */
|
/* void freeParams( LaunchParams* params ); */
|
||||||
|
|
|
@ -34,7 +34,6 @@ typedef struct _SMSProcs {
|
||||||
void (*devIDReceived)( void* closure, const XP_UCHAR* devID,
|
void (*devIDReceived)( void* closure, const XP_UCHAR* devID,
|
||||||
XP_U16 maxInterval );
|
XP_U16 maxInterval );
|
||||||
void (*msgErrorMsg)( void* closure, const XP_UCHAR* msg );
|
void (*msgErrorMsg)( void* closure, const XP_UCHAR* msg );
|
||||||
SocketAddedFunc socketAdded;
|
|
||||||
} SMSProcs;
|
} SMSProcs;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ typedef struct LaunchParams {
|
||||||
XP_U16 splitPackets;
|
XP_U16 splitPackets;
|
||||||
XP_U16 chatsInterval; /* 0 means disabled */
|
XP_U16 chatsInterval; /* 0 means disabled */
|
||||||
XP_U16 askTimeout;
|
XP_U16 askTimeout;
|
||||||
|
int cursesListWinHt;
|
||||||
#ifdef XWFEATURE_SEARCHLIMIT
|
#ifdef XWFEATURE_SEARCHLIMIT
|
||||||
XP_Bool allowHintRect;
|
XP_Bool allowHintRect;
|
||||||
#endif
|
#endif
|
||||||
|
@ -170,7 +171,7 @@ typedef struct LaunchParams {
|
||||||
|
|
||||||
typedef struct CommonGlobals CommonGlobals;
|
typedef struct CommonGlobals CommonGlobals;
|
||||||
|
|
||||||
typedef void (*SocketAddedFunc)( void* closure, int newsock, GIOFunc func );
|
typedef guint (*SocketAddedFunc)( void* closure, int newsock, GIOFunc func );
|
||||||
typedef XP_Bool (*Acceptor)( int sock, void* ctxt );
|
typedef XP_Bool (*Acceptor)( int sock, void* ctxt );
|
||||||
typedef void (*AddAcceptorFunc)(int listener, Acceptor func,
|
typedef void (*AddAcceptorFunc)(int listener, Acceptor func,
|
||||||
CommonGlobals* globals, void** storage );
|
CommonGlobals* globals, void** storage );
|
||||||
|
@ -189,11 +190,13 @@ typedef void (*OnSaveFunc)( void* closure, sqlite3_int64 rowid,
|
||||||
XP_Bool firstTime );
|
XP_Bool firstTime );
|
||||||
|
|
||||||
struct CommonGlobals {
|
struct CommonGlobals {
|
||||||
|
CurGameInfo _gi;
|
||||||
LaunchParams* params;
|
LaunchParams* params;
|
||||||
CommonPrefs cp;
|
CommonPrefs cp;
|
||||||
XW_UtilCtxt* util;
|
XW_UtilCtxt* util;
|
||||||
|
|
||||||
XWGame game;
|
XWGame game;
|
||||||
|
DrawCtx* draw;
|
||||||
CurGameInfo* gi;
|
CurGameInfo* gi;
|
||||||
CommsAddrRec addr;
|
CommsAddrRec addr;
|
||||||
DictionaryCtxt* dict;
|
DictionaryCtxt* dict;
|
||||||
|
@ -202,9 +205,8 @@ struct CommonGlobals {
|
||||||
XP_U16 lastStreamSize;
|
XP_U16 lastStreamSize;
|
||||||
XP_U16 nMissing;
|
XP_U16 nMissing;
|
||||||
XP_Bool manualFinal; /* use asked for final scores */
|
XP_Bool manualFinal; /* use asked for final scores */
|
||||||
sqlite3_int64 selRow;
|
sqlite3_int64 rowid;
|
||||||
|
|
||||||
SocketAddedFunc socketAdded;
|
|
||||||
void* socketAddedClosure;
|
void* socketAddedClosure;
|
||||||
OnSaveFunc onSave;
|
OnSaveFunc onSave;
|
||||||
void* onSaveClosure;
|
void* onSaveClosure;
|
||||||
|
@ -248,10 +250,16 @@ struct CommonGlobals {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TimerInfo timerInfo[NUM_TIMERS_PLUS_ONE];
|
TimerInfo timerInfo[NUM_TIMERS_PLUS_ONE];
|
||||||
|
guint secondsTimerID;
|
||||||
|
|
||||||
XP_U16 curSaveToken;
|
XP_U16 curSaveToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _CommonAppGlobals {
|
||||||
|
LaunchParams* params;
|
||||||
|
GSList* globalsList;
|
||||||
|
} CommonAppGlobals;
|
||||||
|
|
||||||
typedef struct _SourceData {
|
typedef struct _SourceData {
|
||||||
GIOChannel* channel;
|
GIOChannel* channel;
|
||||||
gint watch;
|
gint watch;
|
||||||
|
@ -261,9 +269,8 @@ typedef struct _SourceData {
|
||||||
|
|
||||||
#ifdef PLATFORM_GTK
|
#ifdef PLATFORM_GTK
|
||||||
typedef struct _GtkAppGlobals {
|
typedef struct _GtkAppGlobals {
|
||||||
|
CommonAppGlobals cag;
|
||||||
GArray* selRows;
|
GArray* selRows;
|
||||||
LaunchParams* params;
|
|
||||||
GSList* globalsList;
|
|
||||||
GList* sources;
|
GList* sources;
|
||||||
GtkWidget* window;
|
GtkWidget* window;
|
||||||
GtkWidget* listWidget;
|
GtkWidget* listWidget;
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "linuxmain.h"
|
#include "linuxmain.h"
|
||||||
#include "comtypes.h"
|
#include "comtypes.h"
|
||||||
#include "gamesdb.h"
|
#include "gamesdb.h"
|
||||||
|
#include "gsrcwrap.h"
|
||||||
|
|
||||||
#define MAX_MOVE_CHECK_MS ((XP_U16)(1000 * 60 * 60 * 24))
|
#define MAX_MOVE_CHECK_MS ((XP_U16)(1000 * 60 * 60 * 24))
|
||||||
#define RELAY_API_PROTO "http"
|
#define RELAY_API_PROTO "http"
|
||||||
|
@ -265,7 +266,7 @@ relaycon_init( LaunchParams* params, const RelayConnProcs* procs,
|
||||||
XP_MEMCPY( storage->host, host, XP_STRLEN(host) + 1 );
|
XP_MEMCPY( storage->host, host, XP_STRLEN(host) + 1 );
|
||||||
} else {
|
} else {
|
||||||
storage->socket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
|
storage->socket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
|
||||||
(*procs->socketAdded)( storage, storage->socket, relaycon_receive );
|
ADD_SOCKET( storage, storage->socket, relaycon_receive );
|
||||||
|
|
||||||
XP_MEMSET( &storage->saddr, 0, sizeof(storage->saddr) );
|
XP_MEMSET( &storage->saddr, 0, sizeof(storage->saddr) );
|
||||||
storage->saddr.sin_family = PF_INET;
|
storage->saddr.sin_family = PF_INET;
|
||||||
|
@ -705,6 +706,7 @@ process( RelayConStorage* storage, XP_U8* buf, ssize_t nRead )
|
||||||
XP_LOGF( "%s: error reading udp socket: %d (%s)", __func__,
|
XP_LOGF( "%s: error reading udp socket: %d (%s)", __func__,
|
||||||
errno, strerror(errno) );
|
errno, strerror(errno) );
|
||||||
}
|
}
|
||||||
|
LOG_RETURNF( "%d", TRUE );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,21 +721,24 @@ relaycon_receive( GIOChannel* source, GIOCondition XP_UNUSED_DBG(condition), gpo
|
||||||
socklen_t fromlen = sizeof(from);
|
socklen_t fromlen = sizeof(from);
|
||||||
|
|
||||||
int socket = g_io_channel_unix_get_fd( source );
|
int socket = g_io_channel_unix_get_fd( source );
|
||||||
XP_LOGF( "%s: calling recvfrom on socket %d", __func__, socket );
|
|
||||||
|
|
||||||
ssize_t nRead = recvfrom( socket, buf, sizeof(buf), 0, /* flags */
|
ssize_t nRead = recvfrom( socket, buf, sizeof(buf), 0, /* flags */
|
||||||
(struct sockaddr*)&from, &fromlen );
|
(struct sockaddr*)&from, &fromlen );
|
||||||
|
|
||||||
gchar* b64 = g_base64_encode( (const guchar*)buf,
|
gchar* b64 = g_base64_encode( (const guchar*)buf,
|
||||||
((0 <= nRead)? nRead : 0) );
|
((0 <= nRead)? nRead : 0) );
|
||||||
XP_LOGF( "%s: read %zd bytes ('%s')", __func__, nRead, b64 );
|
|
||||||
#ifdef COMMS_CHECKSUM
|
#ifdef COMMS_CHECKSUM
|
||||||
gchar* sum = g_compute_checksum_for_data( G_CHECKSUM_MD5, buf, nRead );
|
gchar* sum = g_compute_checksum_for_data( G_CHECKSUM_MD5, buf, nRead );
|
||||||
XP_LOGF( "%s: read %zd bytes ('%s')(sum=%s)", __func__, nRead, b64, sum );
|
XP_LOGF( "%s: read %zd bytes ('%s')(sum=%s)", __func__, nRead, b64, sum );
|
||||||
g_free( sum );
|
g_free( sum );
|
||||||
|
#else
|
||||||
|
XP_LOGF( "%s: read %zd bytes ('%s')", __func__, nRead, b64 );
|
||||||
#endif
|
#endif
|
||||||
g_free( b64 );
|
g_free( b64 );
|
||||||
return process( storage, buf, nRead );
|
|
||||||
|
gboolean result = process( storage, buf, nRead );
|
||||||
|
// LOG_RETURNF( "%d", result );
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -34,7 +34,6 @@ typedef struct _Procs {
|
||||||
XP_U16 maxInterval );
|
XP_U16 maxInterval );
|
||||||
void (*msgErrorMsg)( void* closure, const XP_UCHAR* msg );
|
void (*msgErrorMsg)( void* closure, const XP_UCHAR* msg );
|
||||||
void (*inviteReceived)( void* closure, NetLaunchInfo* invit );
|
void (*inviteReceived)( void* closure, NetLaunchInfo* invit );
|
||||||
SocketAddedFunc socketAdded;
|
|
||||||
} RelayConnProcs;
|
} RelayConnProcs;
|
||||||
|
|
||||||
void relaycon_init( LaunchParams* params, const RelayConnProcs* procs,
|
void relaycon_init( LaunchParams* params, const RelayConnProcs* procs,
|
||||||
|
|
|
@ -163,7 +163,7 @@ class Device():
|
||||||
sTilesLeftTrayPat = re.compile('.*player \d+ now has (\d+) tiles')
|
sTilesLeftTrayPat = re.compile('.*player \d+ now has (\d+) tiles')
|
||||||
sRelayIDPat = re.compile('.*UPDATE games.*seed=(\d+),.*relayid=\'([^\']+)\'.*')
|
sRelayIDPat = re.compile('.*UPDATE games.*seed=(\d+),.*relayid=\'([^\']+)\'.*')
|
||||||
|
|
||||||
def __init__(self, args, game, indx, params, room, peers, db, log, nInGame):
|
def __init__(self, args, game, indx, params, room, peers, db, log, script, nInGame):
|
||||||
self.game = game
|
self.game = game
|
||||||
self.indx = indx
|
self.indx = indx
|
||||||
self.args = args
|
self.args = args
|
||||||
|
@ -173,6 +173,7 @@ class Device():
|
||||||
self.room = room
|
self.room = room
|
||||||
self.db = db
|
self.db = db
|
||||||
self.logPath = log
|
self.logPath = log
|
||||||
|
self.script = script
|
||||||
self.nInGame = nInGame
|
self.nInGame = nInGame
|
||||||
# runtime stuff; init now
|
# runtime stuff; init now
|
||||||
self.app = args.APP_OLD
|
self.app = args.APP_OLD
|
||||||
|
@ -198,6 +199,8 @@ class Device():
|
||||||
if pct >= random.randint(0, 99):
|
if pct >= random.randint(0, 99):
|
||||||
print('launch(): upgrading from ', self.app, ' to ', self.args.APP_NEW)
|
print('launch(): upgrading from ', self.app, ' to ', self.args.APP_NEW)
|
||||||
self.app = self.args.APP_NEW
|
self.app = self.args.APP_NEW
|
||||||
|
# nuke script to force regeneration
|
||||||
|
os.unlink(self.script)
|
||||||
|
|
||||||
def logReaderMain(self):
|
def logReaderMain(self):
|
||||||
assert self and self.proc
|
assert self and self.proc
|
||||||
|
@ -234,19 +237,26 @@ class Device():
|
||||||
|
|
||||||
# print('logReaderMain done, wrote lines:', nLines, 'to', self.logPath);
|
# print('logReaderMain done, wrote lines:', nLines, 'to', self.logPath);
|
||||||
|
|
||||||
|
def checkScript(self):
|
||||||
|
if not os.path.exists(self.script):
|
||||||
|
args = ['exec'] # without exec means terminate() won't work
|
||||||
|
if self.args.VALGRIND:
|
||||||
|
args += ['valgrind']
|
||||||
|
# args += ['--leak-check=full']
|
||||||
|
# args += ['--track-origins=yes']
|
||||||
|
args += [self.app] + [str(p) for p in self.params]
|
||||||
|
if self.devID: args.extend( ' '.split(self.devID))
|
||||||
|
args += [ '$*' ]
|
||||||
|
with open( self.script, 'w' ) as fil:
|
||||||
|
fil.write( "#!/bin/sh\n" )
|
||||||
|
fil.write( ' '.join(args) + '\n' )
|
||||||
|
os.chmod(self.script, 0o755)
|
||||||
|
|
||||||
def launch(self):
|
def launch(self):
|
||||||
args = []
|
|
||||||
if self.args.VALGRIND:
|
|
||||||
args += ['valgrind']
|
|
||||||
# args += ['--leak-check=full']
|
|
||||||
# args += ['--track-origins=yes']
|
|
||||||
|
|
||||||
# Upgrade if appropriate
|
|
||||||
self.setApp(self.args.UPGRADE_PCT)
|
self.setApp(self.args.UPGRADE_PCT)
|
||||||
|
self.checkScript()
|
||||||
args += [self.app] + [str(p) for p in self.params]
|
|
||||||
if self.devID: args.extend( ' '.split(self.devID))
|
|
||||||
self.launchCount += 1
|
self.launchCount += 1
|
||||||
|
args = [ self.script ]
|
||||||
self.proc = subprocess.Popen(args, stdout = subprocess.DEVNULL,
|
self.proc = subprocess.Popen(args, stdout = subprocess.DEVNULL,
|
||||||
stderr = subprocess.PIPE, universal_newlines = True)
|
stderr = subprocess.PIPE, universal_newlines = True)
|
||||||
self.pid = self.proc.pid
|
self.pid = self.proc.pid
|
||||||
|
@ -287,8 +297,8 @@ class Device():
|
||||||
|
|
||||||
def moveFiles(self):
|
def moveFiles(self):
|
||||||
assert not self.running()
|
assert not self.running()
|
||||||
shutil.move(self.logPath, self.args.LOGDIR + '/done')
|
for fil in [ self.logPath, self.db, self.script ]:
|
||||||
shutil.move(self.db, self.args.LOGDIR + '/done')
|
shutil.move(fil, self.args.LOGDIR + '/done')
|
||||||
|
|
||||||
def send_dead(self):
|
def send_dead(self):
|
||||||
if self.args.ADD_RELAY:
|
if self.args.ADD_RELAY:
|
||||||
|
@ -393,6 +403,7 @@ def build_cmds(args):
|
||||||
DEV += 1
|
DEV += 1
|
||||||
DB = '{}/{:02d}_{:02d}_DB.sql3'.format(args.LOGDIR, GAME, DEV)
|
DB = '{}/{:02d}_{:02d}_DB.sql3'.format(args.LOGDIR, GAME, DEV)
|
||||||
LOG = '{}/{:02d}_{:02d}_LOG.txt'.format(args.LOGDIR, GAME, DEV)
|
LOG = '{}/{:02d}_{:02d}_LOG.txt'.format(args.LOGDIR, GAME, DEV)
|
||||||
|
SCRIPT = '{}/start_{:02d}_{:02d}.sh'.format(args.LOGDIR, GAME, DEV)
|
||||||
|
|
||||||
PARAMS = player_params(args, NLOCALS, NPLAYERS, DEV)
|
PARAMS = player_params(args, NLOCALS, NPLAYERS, DEV)
|
||||||
PARAMS += PLAT_PARMS
|
PARAMS += PLAT_PARMS
|
||||||
|
@ -442,7 +453,7 @@ def build_cmds(args):
|
||||||
|
|
||||||
# print('PARAMS:', PARAMS)
|
# print('PARAMS:', PARAMS)
|
||||||
|
|
||||||
dev = Device(args, GAME, COUNTER, PARAMS, ROOM, peers, DB, LOG, len(LOCALS))
|
dev = Device(args, GAME, COUNTER, PARAMS, ROOM, peers, DB, LOG, SCRIPT, len(LOCALS))
|
||||||
peers.add(dev)
|
peers.add(dev)
|
||||||
dev.update_ldevid()
|
dev.update_ldevid()
|
||||||
devs.append(dev)
|
devs.append(dev)
|
||||||
|
@ -515,7 +526,7 @@ def summarizeTileCounts(devs, endTime, state):
|
||||||
state['lastChange'] = now
|
state['lastChange'] = now
|
||||||
state['tilesStr'] = tilesStr
|
state['tilesStr'] = tilesStr
|
||||||
|
|
||||||
return now - state['lastChange'] < datetime.timedelta(minutes = 1)
|
return now - state['lastChange'] < datetime.timedelta(seconds = 30)
|
||||||
|
|
||||||
def countCores():
|
def countCores():
|
||||||
return len(glob.glob1('/tmp',"core*"))
|
return len(glob.glob1('/tmp',"core*"))
|
||||||
|
@ -549,18 +560,7 @@ def run_cmds(args, devs):
|
||||||
if dev.handleAllDone():
|
if dev.handleAllDone():
|
||||||
devs.remove(dev)
|
devs.remove(dev)
|
||||||
else:
|
else:
|
||||||
# if [ -n "$ONE_PER_ROOM" -a 0 -ne ${ROOM_PIDS[$ROOM]} ]; then
|
|
||||||
# continue
|
|
||||||
# fi
|
|
||||||
# try_upgrade $KEY
|
|
||||||
# try_upgrade_upd $KEY
|
|
||||||
dev.launch()
|
dev.launch()
|
||||||
# PID=$!
|
|
||||||
# # renice doesn't work on one of my machines...
|
|
||||||
# renice -n 1 -p $PID >/dev/null 2>&1 || /bin/true
|
|
||||||
# PIDS[$KEY]=$PID
|
|
||||||
# ROOM_PIDS[$ROOM]=$PID
|
|
||||||
# MINEND[$KEY]=$(($NOW + $MINRUN))
|
|
||||||
elif dev.minTimeExpired():
|
elif dev.minTimeExpired():
|
||||||
dev.kill()
|
dev.kill()
|
||||||
if dev.handleAllDone():
|
if dev.handleAllDone():
|
||||||
|
|
|
@ -3,7 +3,26 @@
|
||||||
# This script just runs the curses app with a set of params known to
|
# This script just runs the curses app with a set of params known to
|
||||||
# work. At least when it was last committed. :-)
|
# work. At least when it was last committed. :-)
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "usage: $0 [--help] [param-for-xwords]*"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
PARAMS=''
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case $1 in
|
||||||
|
--help)
|
||||||
|
usage;
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
PARAMS="$PARAMS $1"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
WD=$(cd $(dirname $0)/.. && pwd)
|
WD=$(cd $(dirname $0)/.. && pwd)
|
||||||
cd $WD
|
cd $WD
|
||||||
./obj_linux_memdbg/xwords --curses --name Eric --robot Kati --dict-dir ./ --game-dict ../dict.xwd 2>/dev/null
|
./obj_linux_memdbg/xwords --curses --name Eric --name Kati \
|
||||||
|
--dict-dir ./ --game-dict ../dict.xwd \
|
||||||
|
$PARAMS \
|
||||||
|
|
Loading…
Add table
Reference in a new issue