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,