From 9f3250cb3fa6bff5fa35508e39489181f743af84 Mon Sep 17 00:00:00 2001 From: Eric House Date: Thu, 24 Jan 2013 07:49:49 -0800 Subject: [PATCH] make curses version use udp socket when --db param passed. There's no UI for the DB and the assumption is only one game will be stored but this should let the test script be modified to test the new protocol. --- xwords4/linux/cursesask.c | 4 +- xwords4/linux/cursesask.h | 4 +- xwords4/linux/cursesdlgutil.c | 2 +- xwords4/linux/cursesdlgutil.h | 2 +- xwords4/linux/cursesletterask.c | 4 +- xwords4/linux/cursesmain.c | 154 +++++++++++++++++++++++++++++++- xwords4/linux/cursesmain.h | 1 + xwords4/linux/gamesdb.c | 12 +-- xwords4/linux/gamesdb.h | 4 +- xwords4/linux/gtkboard.c | 34 ------- xwords4/linux/gtkboard.h | 2 - xwords4/linux/gtkmain.c | 46 +++------- xwords4/linux/linuxmain.c | 68 ++++++++++++++ xwords4/linux/linuxmain.h | 6 ++ xwords4/linux/main.h | 2 - xwords4/linux/relaycon.c | 4 +- xwords4/linux/relaycon.h | 3 + 17 files changed, 259 insertions(+), 93 deletions(-) diff --git a/xwords4/linux/cursesask.c b/xwords4/linux/cursesask.c index 463c622dc..ffca1a9a7 100644 --- a/xwords4/linux/cursesask.c +++ b/xwords4/linux/cursesask.c @@ -32,8 +32,8 @@ /* Figure out how many lines there are and how wide the widest is. */ short -cursesask( CursesAppGlobals* globals, char* question, short numButtons, - char* button1, ... ) +cursesask( CursesAppGlobals* globals, const char* question, short numButtons, + const char* button1, ... ) { WINDOW* confWin; int x, y, rows, row, nLines; diff --git a/xwords4/linux/cursesask.h b/xwords4/linux/cursesask.h index f4930a682..36f20fb35 100644 --- a/xwords4/linux/cursesask.h +++ b/xwords4/linux/cursesask.h @@ -22,8 +22,8 @@ #include "cursesmain.h" -short cursesask( CursesAppGlobals* globals, char* question, - short numButtons, char* button1, ... ); +short cursesask( CursesAppGlobals* globals, const char* question, + short numButtons, const char* button1, ... ); #endif diff --git a/xwords4/linux/cursesdlgutil.c b/xwords4/linux/cursesdlgutil.c index b7484691d..740bf27ec 100644 --- a/xwords4/linux/cursesdlgutil.c +++ b/xwords4/linux/cursesdlgutil.c @@ -70,7 +70,7 @@ measureAskText( const XP_UCHAR* question, int width, FormatInfo* fip ) void drawButtons( WINDOW* win, XP_U16 line, short spacePerButton, - short numButtons, short curSelButton, char** button1 ) + short numButtons, short curSelButton, const char** button1 ) { short i; for ( i = 0; i < numButtons; ++i ) { diff --git a/xwords4/linux/cursesdlgutil.h b/xwords4/linux/cursesdlgutil.h index 1f9199c7e..dd9a2403c 100644 --- a/xwords4/linux/cursesdlgutil.h +++ b/xwords4/linux/cursesdlgutil.h @@ -44,6 +44,6 @@ typedef struct FormatInfo { void measureAskText( const XP_UCHAR* question, int maxWidth, FormatInfo* fip ); void drawButtons( WINDOW* confWin, XP_U16 line, short spacePerButton, - short numButtons, short curSelButton, char** button1 ); + short numButtons, short curSelButton, const char** button1 ); #endif diff --git a/xwords4/linux/cursesletterask.c b/xwords4/linux/cursesletterask.c index 332d722eb..1dc5d0e19 100644 --- a/xwords4/linux/cursesletterask.c +++ b/xwords4/linux/cursesletterask.c @@ -57,7 +57,7 @@ curses_askLetter( CursesAppGlobals* globals, XP_UCHAR* query, short curSelButton = 1; /* force draw by being different */ short maxWidth; short numCtlButtons; - char* ctlButtons[] = { "Ok", "Cancel" }; + const char* ctlButtons[] = { "Ok", "Cancel" }; XP_Bool dismissed = XP_FALSE; FormatInfo fi; int len; @@ -138,7 +138,7 @@ curses_askLetter( CursesAppGlobals* globals, XP_UCHAR* query, MAX_TILE_BUTTON_WIDTH-1, nInRow, newSelButton - textsOffsets[i], - (char**)&textPtrs[textsOffsets[i]] ); + (const char**)&textPtrs[textsOffsets[i]] ); } diff --git a/xwords4/linux/cursesmain.c b/xwords4/linux/cursesmain.c index fb7862604..d3c1a87c0 100644 --- a/xwords4/linux/cursesmain.c +++ b/xwords4/linux/cursesmain.c @@ -60,6 +60,8 @@ #include "dbgutil.h" #include "linuxsms.h" #include "linuxudp.h" +#include "gamesdb.h" +#include "relaycon.h" #ifdef CURSES_SMALL_SCREEN # define MENU_WINDOW_HEIGHT 1 @@ -1121,6 +1123,15 @@ curses_socket_changed( void* closure, int oldSock, int newSock, #endif } /* curses_socket_changed */ +static void +curses_onGameSaved( void* closure, sqlite3_int64 rowid, + XP_Bool XP_UNUSED(firstTime) ) +{ + CursesAppGlobals* globals = (CursesAppGlobals*)closure; + /* May not be recorded */ + globals->cGlobals.selRow = rowid; +} + #ifdef USE_GLIBLOOP static gboolean fire_acceptor( GIOChannel* source, GIOCondition condition, gpointer data ) @@ -1717,6 +1728,107 @@ curses_getFlags( void* XP_UNUSED(closure) ) } #endif +static void +cursesGotBuf( void* closure, const XP_U8* buf, XP_U16 len ) +{ + LOG_FUNC(); + CursesAppGlobals* globals = (CursesAppGlobals*)closure; + XP_U32 gameToken; + XP_ASSERT( sizeof(gameToken) < len ); + gameToken = ntohl(*(XP_U32*)&buf[0]); + buf += sizeof(gameToken); + len -= sizeof(gameToken); + + gameGotBuf( &globals->cGlobals, XP_TRUE, buf, len ); +} + +static gint +curses_requestMsgs( gpointer data ) +{ + CursesAppGlobals* globals = (CursesAppGlobals*)data; + XP_UCHAR devIDBuf[64] = {0}; + db_fetch( globals->cGlobals.pDb, KEY_RDEVID, devIDBuf, sizeof(devIDBuf) ); + if ( '\0' != devIDBuf[0] ) { + relaycon_requestMsgs( globals->cGlobals.params, devIDBuf ); + } else { + XP_LOGF( "%s: not requesting messages as don't have relay id", __func__ ); + } + return 0; /* don't run again */ +} + + +static void +cursesNoticeRcvd( void* closure, XP_U32 XP_UNUSED(gameToken) ) +{ + LOG_FUNC(); + CursesAppGlobals* globals = (CursesAppGlobals*)closure; + (void)g_idle_add( curses_requestMsgs, globals ); +} + +static void +cursesDevIDChanged( void* closure, const XP_UCHAR* devID ) +{ + CursesAppGlobals* globals = (CursesAppGlobals*)closure; + sqlite3* pDb = globals->cGlobals.pDb; + if ( !!devID ) { + XP_LOGF( "%s(devID=%s)", __func__, devID ); + db_store( pDb, KEY_RDEVID, devID ); + } else { + XP_LOGF( "%s: bad relayid", __func__ ); + db_remove( pDb, KEY_RDEVID ); + sendRelayReg( globals->cGlobals.params, pDb ); + } +} + +static void +cursesErrorMsgRcvd( void* closure, const XP_UCHAR* msg ) +{ + CursesAppGlobals* globals = (CursesAppGlobals*)closure; + if ( !!globals->lastErr && 0 == strcmp( globals->lastErr, msg ) ) { + XP_LOGF( "skipping error message from relay" ); + } else { + g_free( globals->lastErr ); + globals->lastErr = g_strdup( msg ); + (void)cursesask( globals, msg, 1, "Ok" ); + } +} + + +static gboolean +curses_app_socket_proc( GIOChannel* source, GIOCondition condition, + gpointer data ) +{ + if ( 0 != (G_IO_IN & condition) ) { + CursesAppGlobals* globals = (CursesAppGlobals*)data; + int socket = g_io_channel_unix_get_fd( source ); + GList* iter; + for ( iter = globals->sources; !!iter; iter = iter->next ) { + SourceData* sd = (SourceData*)iter->data; + if ( sd->channel == source ) { + (*sd->proc)( sd->procClosure, socket ); + break; + } + } + XP_ASSERT( !!iter ); /* didn't fail to find it */ + } + return TRUE; +} + +static void +cursesUDPSocketChanged( void* closure, int newSock, int XP_UNUSED(oldSock), + SockReceiver proc, void* procClosure ) +{ + CursesAppGlobals* globals = (CursesAppGlobals*)closure; + + SourceData* sd = g_malloc( sizeof(*sd) ); + sd->channel = g_io_channel_unix_new( newSock ); + sd->watch = g_io_add_watch( sd->channel, G_IO_IN | G_IO_ERR, + curses_app_socket_proc, globals ); + sd->proc = proc; + sd->procClosure = procClosure; + globals->sources = g_list_append( globals->sources, sd ); +} + void cursesmain( XP_Bool isServer, LaunchParams* params ) { @@ -1737,6 +1849,9 @@ cursesmain( XP_Bool isServer, LaunchParams* params ) g_globals.cGlobals.socketChanged = curses_socket_changed; g_globals.cGlobals.socketChangedClosure = &g_globals; + g_globals.cGlobals.onSave = curses_onGameSaved; + g_globals.cGlobals.onSaveClosure = &g_globals; + g_globals.cGlobals.addAcceptor = curses_socket_acceptor; g_globals.cGlobals.cp.showBoardArrow = XP_TRUE; @@ -1816,7 +1931,38 @@ cursesmain( XP_Bool isServer, LaunchParams* params ) cursesDrawCtxtMake( g_globals.boardWin ); XWStreamCtxt* stream = NULL; - if ( !!params->fileName && file_exists( params->fileName ) ) { + if ( !!params->dbName ) { + g_globals.cGlobals.pDb = openGamesDB( params->dbName ); + + RelayConnProcs procs = { + .msgReceived = cursesGotBuf, + .msgNoticeReceived = cursesNoticeRcvd, + .devIDChanged = cursesDevIDChanged, + .msgErrorMsg = cursesErrorMsgRcvd, + .socketChanged = cursesUDPSocketChanged, + }; + + relaycon_init( params, &procs, &g_globals, + params->connInfo.relay.relayName, + params->connInfo.relay.defaultSendPort ); + sendRelayReg( params, g_globals.cGlobals.pDb ); + + GSList* games = listGames( g_globals.cGlobals.pDb ); + if ( !!games ) { + stream = mem_stream_make( MEMPOOL params->vtMgr, + &g_globals.cGlobals, CHANNEL_NONE, + NULL ); + sqlite3_int64 selRow = *(sqlite3_int64*)games->data; + if ( loadGame( stream, g_globals.cGlobals.pDb, selRow ) ) { + g_globals.cGlobals.selRow = selRow; + } else { + stream_destroy( stream ); + stream = NULL; + } + g_slist_free( games ); + } + + } else if ( !!params->fileName && file_exists( params->fileName ) ) { stream = streamFromFile( &g_globals.cGlobals, params->fileName, &g_globals ); #ifdef USE_SQLITE @@ -1830,8 +1976,8 @@ cursesmain( XP_Bool isServer, LaunchParams* params ) cGlobals->dict = makeDictForStream( cGlobals, stream ); } (void)game_makeFromStream( MEMPOOL stream, &cGlobals->game, - &cGlobals->gi, cGlobals->dict, &cGlobals->dicts, - cGlobals->util, + &cGlobals->gi, cGlobals->dict, + &cGlobals->dicts, cGlobals->util, (DrawCtx*)g_globals.draw, &g_globals.cGlobals.cp, &procs ); @@ -1845,6 +1991,8 @@ cursesmain( XP_Bool isServer, LaunchParams* params ) game_makeNewGame( MEMPOOL &cGlobals->game, &cGlobals->gi, cGlobals->util, (DrawCtx*)g_globals.draw, &g_globals.cGlobals.cp, &procs, params->gameSeed ); + g_globals.cGlobals.selRow = -1; + saveGame( &g_globals.cGlobals ); } #ifndef XWFEATURE_STANDALONE_ONLY diff --git a/xwords4/linux/cursesmain.h b/xwords4/linux/cursesmain.h index f520c9eeb..3d21ae3ce 100644 --- a/xwords4/linux/cursesmain.h +++ b/xwords4/linux/cursesmain.h @@ -68,6 +68,7 @@ struct CursesAppGlobals { XP_Bool doDraw; const struct MenuList* menuList; XP_U16 nLinesMenu; + gchar* lastErr; union { struct { diff --git a/xwords4/linux/gamesdb.c b/xwords4/linux/gamesdb.c index c0f217e10..d6255d48d 100644 --- a/xwords4/linux/gamesdb.c +++ b/xwords4/linux/gamesdb.c @@ -141,14 +141,14 @@ summarize( CommonGlobals* cGlobals ) } GSList* -listGames( GtkAppGlobals* apg ) +listGames( sqlite3* pDb ) { GSList* list = NULL; sqlite3_stmt *ppStmt; - int result = sqlite3_prepare_v2( apg->pDb, - "SELECT rowid FROM games ORDER BY rowid", -1, - &ppStmt, NULL ); + int result = sqlite3_prepare_v2( pDb, + "SELECT rowid FROM games ORDER BY rowid", + -1, &ppStmt, NULL ); XP_ASSERT( SQLITE_OK == result ); while ( NULL != ppStmt ) { switch( sqlite3_step( ppStmt ) ) { @@ -173,7 +173,7 @@ listGames( GtkAppGlobals* apg ) } XP_Bool -getGameInfo( GtkAppGlobals* apg, sqlite3_int64 rowid, GameInfo* gib ) +getGameInfo( sqlite3* pDb, sqlite3_int64 rowid, GameInfo* gib ) { XP_Bool success = XP_FALSE; const char* fmt = "SELECT room, ended, turn, nmoves, nmissing " @@ -182,7 +182,7 @@ getGameInfo( GtkAppGlobals* apg, sqlite3_int64 rowid, GameInfo* gib ) snprintf( query, sizeof(query), fmt, rowid ); sqlite3_stmt* ppStmt; - int result = sqlite3_prepare_v2( apg->pDb, query, -1, &ppStmt, NULL ); + int result = sqlite3_prepare_v2( pDb, query, -1, &ppStmt, NULL ); XP_ASSERT( SQLITE_OK == result ); result = sqlite3_step( ppStmt ); if ( SQLITE_ROW == result ) { diff --git a/xwords4/linux/gamesdb.h b/xwords4/linux/gamesdb.h index 97fccee8f..3272c3c20 100644 --- a/xwords4/linux/gamesdb.h +++ b/xwords4/linux/gamesdb.h @@ -44,8 +44,8 @@ void writeToDB( XWStreamCtxt* stream, void* closure ); void summarize( CommonGlobals* cGlobals ); /* Return GSList whose data is (ptrs to) rowids */ -GSList* listGames( GtkAppGlobals* apg ); -XP_Bool getGameInfo( GtkAppGlobals* apg, sqlite3_int64 rowid, GameInfo* gib ); +GSList* listGames( sqlite3* dbp ); +XP_Bool getGameInfo( sqlite3* dbp, sqlite3_int64 rowid, GameInfo* gib ); XP_Bool loadGame( XWStreamCtxt* stream, sqlite3* pDb, sqlite3_int64 rowid ); void deleteGame( sqlite3* pDb, sqlite3_int64 rowid ); diff --git a/xwords4/linux/gtkboard.c b/xwords4/linux/gtkboard.c index 935f49839..b0ee2c6f6 100644 --- a/xwords4/linux/gtkboard.c +++ b/xwords4/linux/gtkboard.c @@ -2629,38 +2629,4 @@ makeNewGame( GtkGameGlobals* globals ) return success; } -void -gameGotBuf( GtkGameGlobals* globals, XP_Bool hasDraw, const XP_U8* buf, - XP_U16 len ) -{ - XP_LOGF( "%s(hasDraw=%d)", __func__, hasDraw ); - XP_Bool redraw = XP_FALSE; - XWGame* game = &globals->cGlobals.game; - XWStreamCtxt* stream = stream_from_msgbuf( &globals->cGlobals, buf, len ); - if ( !!stream ) { - if ( comms_checkIncomingStream( game->comms, stream, NULL ) ) { - redraw = server_receiveMessage( game->server, stream ); - if ( redraw ) { - saveGame( &globals->cGlobals ); - } - } - stream_destroy( stream ); - - /* if there's something to draw resulting from the message, we - need to give the main loop time to reflect that on the screen - before giving the server another shot. So just call the idle - proc. */ - if ( hasDraw && redraw ) { - gtk_util_requestTime( globals->cGlobals.util ); - } else { - for ( int ii = 0; ii < 4; ++ii ) { - redraw = server_do( game->server ) || redraw; - } - } - if ( hasDraw && redraw ) { - board_draw( game->board ); - } - } -} - #endif /* PLATFORM_GTK */ diff --git a/xwords4/linux/gtkboard.h b/xwords4/linux/gtkboard.h index 4253b5cb6..29436c4f5 100644 --- a/xwords4/linux/gtkboard.h +++ b/xwords4/linux/gtkboard.h @@ -169,8 +169,6 @@ typedef struct GtkGameGlobals { void initGlobals( GtkGameGlobals* globals, LaunchParams* params ); void freeGlobals( GtkGameGlobals* globals ); XP_Bool makeNewGame( GtkGameGlobals* globals ); -void gameGotBuf( GtkGameGlobals* globals, XP_Bool haveDraw, - const XP_U8* buf, XP_U16 len ); XP_Bool loadGameNoDraw( GtkGameGlobals* globals, LaunchParams* params, sqlite3* pDb, sqlite3_int64 rowid ); void destroy_board_window( GtkWidget* widget, GtkGameGlobals* globals ); diff --git a/xwords4/linux/gtkmain.c b/xwords4/linux/gtkmain.c index cc57d1c89..d98211f94 100644 --- a/xwords4/linux/gtkmain.c +++ b/xwords4/linux/gtkmain.c @@ -31,7 +31,6 @@ static void onNewData( GtkAppGlobals* apg, sqlite3_int64 rowid, XP_Bool isNew ); static void updateButtons( GtkAppGlobals* apg ); -static void sendRelayReg( GtkAppGlobals* apg ); static void recordOpened( GtkAppGlobals* apg, GtkGameGlobals* globals ) @@ -302,7 +301,7 @@ makeGamesWindow( GtkAppGlobals* apg ) gtk_widget_show( list ); - GSList* games = listGames( apg ); + GSList* games = listGames( apg->pDb ); for ( GSList* iter = games; !!iter; iter = iter->next ) { sqlite3_int64* rowid = (sqlite3_int64*)iter->data; onNewData( apg, *rowid, XP_TRUE ); @@ -347,13 +346,13 @@ static void onNewData( GtkAppGlobals* apg, sqlite3_int64 rowid, XP_Bool isNew ) { GameInfo gib; - if ( getGameInfo( apg, rowid, &gib ) ) { + if ( getGameInfo( apg->pDb, rowid, &gib ) ) { add_to_list( apg->listWidget, rowid, isNew, &gib ); } } static gboolean -app_socket_proc( GIOChannel* source, GIOCondition condition, gpointer data ) +gtk_app_socket_proc( GIOChannel* source, GIOCondition condition, gpointer data ) { if ( 0 != (G_IO_IN & condition) ) { GtkAppGlobals* apg = (GtkAppGlobals*)data; @@ -372,13 +371,14 @@ app_socket_proc( GIOChannel* source, GIOCondition condition, gpointer data ) } static void -socketChanged( void* closure, int newSock, int XP_UNUSED(oldSock), - SockReceiver proc, void* procClosure ) +gtkSocketChanged( void* closure, int newSock, int XP_UNUSED(oldSock), + SockReceiver proc, void* procClosure ) { GtkAppGlobals* apg = (GtkAppGlobals*)closure; SourceData* sd = g_malloc( sizeof(*sd) ); sd->channel = g_io_channel_unix_new( newSock ); - sd->watch = g_io_add_watch( sd->channel, G_IO_IN | G_IO_ERR, app_socket_proc, apg ); + sd->watch = g_io_add_watch( sd->channel, G_IO_IN | G_IO_ERR, + gtk_app_socket_proc, apg ); sd->proc = proc; sd->procClosure = procClosure; apg->sources = g_list_append( apg->sources, sd ); @@ -397,11 +397,11 @@ gtkGotBuf( void* closure, const XP_U8* buf, XP_U16 len ) GtkGameGlobals* globals = findGame( apg, gameToken ); if ( !!globals ) { - gameGotBuf( globals, XP_TRUE, buf, len ); + gameGotBuf( &globals->cGlobals, XP_TRUE, buf, len ); } else { GtkGameGlobals tmpGlobals; if ( loadGameNoDraw( &tmpGlobals, apg->params, apg->pDb, gameToken ) ) { - gameGotBuf( &tmpGlobals, XP_FALSE, buf, len ); + gameGotBuf( &tmpGlobals.cGlobals, XP_FALSE, buf, len ); saveGame( &tmpGlobals.cGlobals ); } freeGlobals( &tmpGlobals ); @@ -440,7 +440,7 @@ gtkDevIDChanged( void* closure, const XP_UCHAR* devID ) } else { XP_LOGF( "%s: bad relayid", __func__ ); db_remove( apg->pDb, KEY_RDEVID ); - sendRelayReg( apg ); + sendRelayReg( apg->params, apg->pDb ); } } @@ -482,27 +482,6 @@ handle_sigintterm( int XP_UNUSED(sig) ) handle_destroy( NULL, g_globals_for_signal ); } -static void -sendRelayReg( GtkAppGlobals* apg ) -{ - LaunchParams* params = apg->params; - XP_UCHAR devIDBuf[64] = {0}; - XP_UCHAR* devID; - DevIDType typ = ID_TYPE_RELAY; - if ( !!params->rDevID ) { - devID = params->rDevID; - } else { - db_fetch( apg->pDb, KEY_RDEVID, devIDBuf, sizeof(devIDBuf) ); - if ( '\0' != devIDBuf[0] ) { - devID = devIDBuf; - } else { - devID = params->devID; - typ = ID_TYPE_LINUX; - } - } - relaycon_reg( params, devID, typ ); -} - int gtkmain( LaunchParams* params ) { @@ -516,20 +495,19 @@ gtkmain( LaunchParams* params ) apg.selRows = g_array_new( FALSE, FALSE, sizeof( sqlite3_int64 ) ); apg.params = params; apg.pDb = openGamesDB( params->dbName ); - params->socketChanged = socketChanged; - params->socketChangedClosure = &apg; RelayConnProcs procs = { .msgReceived = gtkGotBuf, .msgNoticeReceived = gtkNoticeRcvd, .devIDChanged = gtkDevIDChanged, .msgErrorMsg = gtkErrorMsgRcvd, + .socketChanged = gtkSocketChanged, }; relaycon_init( params, &procs, &apg, params->connInfo.relay.relayName, params->connInfo.relay.defaultSendPort ); - sendRelayReg( &apg ); + sendRelayReg( params, apg.pDb ); apg.window = makeGamesWindow( &apg ); gtk_main(); diff --git a/xwords4/linux/linuxmain.c b/xwords4/linux/linuxmain.c index c25f5b7f9..41bb9816d 100644 --- a/xwords4/linux/linuxmain.c +++ b/xwords4/linux/linuxmain.c @@ -172,6 +172,54 @@ makeDictForStream( CommonGlobals* cGlobals, XWStreamCtxt* stream ) return dict; } +void +gameGotBuf( CommonGlobals* cGlobals, XP_Bool hasDraw, const XP_U8* buf, + XP_U16 len ) +{ + XP_LOGF( "%s(hasDraw=%d)", __func__, hasDraw ); + XP_Bool redraw = XP_FALSE; + XWGame* game = &cGlobals->game; + XWStreamCtxt* stream = stream_from_msgbuf( cGlobals, buf, len ); + if ( !!stream ) { + if ( comms_checkIncomingStream( game->comms, stream, NULL ) ) { + redraw = server_receiveMessage( game->server, stream ); + if ( redraw ) { + saveGame( cGlobals ); + } + } + stream_destroy( stream ); + + /* if there's something to draw resulting from the message, we + need to give the main loop time to reflect that on the screen + before giving the server another shot. So just call the idle + proc. */ + if ( hasDraw && redraw ) { + util_requestTime( cGlobals->util ); + } else { + for ( int ii = 0; ii < 4; ++ii ) { + redraw = server_do( game->server ) || redraw; + } + } + if ( hasDraw && redraw ) { + board_draw( game->board ); + } + } +} + +gint +requestMsgsIdle( gpointer data ) +{ + CommonGlobals* cGlobals = (CommonGlobals*)data; + XP_UCHAR devIDBuf[64] = {0}; + db_fetch( cGlobals->pDb, KEY_RDEVID, devIDBuf, sizeof(devIDBuf) ); + if ( '\0' != devIDBuf[0] ) { + relaycon_requestMsgs( cGlobals->params, devIDBuf ); + } else { + XP_LOGF( "%s: not requesting messages as don't have relay id", __func__ ); + } + return 0; /* don't run again */ +} + void writeToFile( XWStreamCtxt* stream, void* closure ) { @@ -801,6 +849,26 @@ linShiftFocus( CommonGlobals* cGlobals, XP_Key key, const BoardObjectType* order } /* linShiftFocus */ #endif +void +sendRelayReg( LaunchParams* params, sqlite3* pDb ) +{ + XP_UCHAR devIDBuf[64] = {0}; + XP_UCHAR* devID; + DevIDType typ = ID_TYPE_RELAY; + if ( !!params->rDevID ) { + devID = params->rDevID; + } else { + db_fetch( pDb, KEY_RDEVID, devIDBuf, sizeof(devIDBuf) ); + if ( '\0' != devIDBuf[0] ) { + devID = devIDBuf; + } else { + devID = params->devID; + typ = ID_TYPE_LINUX; + } + } + relaycon_reg( params, devID, typ ); +} + #ifdef XWFEATURE_RELAY static int linux_init_relay_socket( CommonGlobals* cGlobals, const CommsAddrRec* addrRec ) diff --git a/xwords4/linux/linuxmain.h b/xwords4/linux/linuxmain.h index c52f0c356..86bdedd72 100644 --- a/xwords4/linux/linuxmain.h +++ b/xwords4/linux/linuxmain.h @@ -103,6 +103,12 @@ DictionaryCtxt* makeDictForStream( CommonGlobals* cGlobals, void linuxSetIsServer( CommonGlobals* cGlobals, XP_Bool isServer ); void linuxChangeRoles( CommonGlobals* cGlobals ); +void sendRelayReg( LaunchParams* params, sqlite3* pDb ); +void gameGotBuf( CommonGlobals* globals, XP_Bool haveDraw, + const XP_U8* buf, XP_U16 len ); +gboolean app_socket_proc( GIOChannel* source, GIOCondition condition, + gpointer data ); + /* void initParams( LaunchParams* params ); */ /* void freeParams( LaunchParams* params ); */ diff --git a/xwords4/linux/main.h b/xwords4/linux/main.h index d0cd1c0fa..d3b22c4e1 100644 --- a/xwords4/linux/main.h +++ b/xwords4/linux/main.h @@ -55,8 +55,6 @@ typedef struct LaunchParams { GSList* dictDirs; char* fileName; char* dbName; - NewSocketProc socketChanged; - void* socketChangedClosure; XP_U16 saveFailPct; const XP_UCHAR* playerDictNames[MAX_NUM_PLAYERS]; #ifdef USE_SQLITE diff --git a/xwords4/linux/relaycon.c b/xwords4/linux/relaycon.c index 0b14ded54..c97e82dfe 100644 --- a/xwords4/linux/relaycon.c +++ b/xwords4/linux/relaycon.c @@ -56,8 +56,8 @@ relaycon_init( LaunchParams* params, const RelayConnProcs* procs, storage->procsClosure = procsClosure; storage->socket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); - (*params->socketChanged)( params->socketChangedClosure, storage->socket, -1, - relaycon_receive, params ); + (*procs->socketChanged)( procsClosure, storage->socket, -1, + relaycon_receive, params ); XP_MEMSET( &storage->saddr, 0, sizeof(storage->saddr) ); storage->saddr.sin_family = PF_INET; diff --git a/xwords4/linux/relaycon.h b/xwords4/linux/relaycon.h index 1e1de55f7..19324ed7d 100644 --- a/xwords4/linux/relaycon.h +++ b/xwords4/linux/relaycon.h @@ -27,6 +27,9 @@ typedef struct _Procs { void (*msgNoticeReceived)( void* closure, XP_U32 gameToken ); void (*devIDChanged)( void* closure, const XP_UCHAR* devID ); void (*msgErrorMsg)( void* closure, const XP_UCHAR* msg ); + void (*socketChanged)( void* closure, int newSock, int oldSock, + SockReceiver proc, void* procClosure ); + } RelayConnProcs; void relaycon_init( LaunchParams* params, const RelayConnProcs* procs,