LINK: Continue simplifying the link init oode

git-svn-id: https://svn.code.sf.net/p/vbam/code/branches/bgk-link@1127 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
bgk 2012-09-09 11:01:20 +00:00
parent a1c041a116
commit e0ece3f35b
4 changed files with 296 additions and 387 deletions

View File

@ -148,9 +148,13 @@ int WaitForSingleObject(sem_t *s, int t)
#define UPDATE_REG(address, value) WRITE16LE(((u16 *)&ioMem[address]),value)
static LinkMode gba_link_mode = LINK_DISCONNECTED;
static ConnectionState gba_connection_state = LINK_OK;
LinkMode GetLinkMode() {
return gba_link_mode;
if (gba_connection_state == LINK_OK)
return gba_link_mode;
else
return LINK_DISCONNECTED;
}
int linktime = 0;
@ -224,11 +228,6 @@ int gbtime = 1024;
int GetSIOMode(u16, u16);
void LinkClientThread(void *);
void LinkServerThread(void *);
int StartServer(void);
u16 StartRFU(u16);
void StartLink(u16 value)
@ -244,7 +243,6 @@ void StartLink(u16 value)
switch (GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT]))) {
case MULTIPLAYER: {
bool start = (value & 0x80) && !linkid && !transfer && GetLinkMode() != LINK_DISCONNECTED;
u16 si = value & 4;
// clear start, seqno, si (RO on slave, start = pulse on master)
value &= 0xff4b;
// get current si. This way, on slaves, it is low during xfer
@ -956,13 +954,13 @@ u16 StartRFU(u16 value)
}
}
static bool InitIPC() {
static ConnectionState InitIPC() {
linkid = 0;
#if (defined __WIN32__ || defined _WIN32)
if((mmf=CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(LINKDATA), LOCAL_LINK_NAME))==NULL){
systemMessage(0, N_("Error creating file mapping"));
return false;
return LINK_ERROR;
}
if(GetLastError() == ERROR_ALREADY_EXISTS)
@ -974,7 +972,7 @@ static bool InitIPC() {
if((linkmem=(LINKDATA *)MapViewOfFile(mmf, FILE_MAP_WRITE, 0, 0, sizeof(LINKDATA)))==NULL){
CloseHandle(mmf);
systemMessage(0, N_("Error mapping file"));
return false;
return LINK_ERROR;
}
#else
if((mmf = shm_open("/" LOCAL_LINK_NAME, O_RDWR|O_CREAT|O_EXCL, 0777)) < 0) {
@ -1024,7 +1022,7 @@ static bool InitIPC() {
close(mmf);
#endif
systemMessage(0, N_("5 or more GBAs not supported."));
return false;
return LINK_ERROR;
}
if(vbaid == n)
linkmem->numgbas = n + 1;
@ -1045,7 +1043,7 @@ static bool InitIPC() {
CloseHandle(linksync[j]);
}
systemMessage(0, N_("Error opening event"));
return false;
return LINK_ERROR;
}
#else
if((linksync[i] = sem_open(linkevent,
@ -1063,45 +1061,187 @@ static bool InitIPC() {
}
}
systemMessage(0, N_("Error opening event"));
return false;
return LINK_ERROR;
}
#endif
}
return true;
return LINK_OK;
}
//////////////////////////////////////////////////////////////////////////
// Probably from here down needs to be replaced with SFML goodness :)
// tjm: what SFML goodness? SFML for network, yes, but not for IPC
bool InitLink(LinkMode mode)
ConnectionState InitLink(LinkMode mode)
{
// Do nothing if we are already connected
if (GetLinkMode() != LINK_DISCONNECTED) {
systemMessage(0, N_("Error, link already connected"));
return false;
return LINK_ERROR;
}
bool initOk = true;
gba_connection_state = LINK_OK;
if (mode == LINK_GAMECUBE_DOLPHIN) {
JoyBusConnect();
} else if (mode == LINK_CABLE_IPC || mode == LINK_RFU_IPC) {
initOk = InitIPC();
gba_connection_state = InitIPC();
} else if (mode == LINK_CABLE_SOCKET) {
for(i=0;i<4;i++)
linkid = 0;
for(int i = 0; i < 4; i++)
linkdata[i] = 0xffff;
if (lanlink.server) {
lanlink.connectedSlaves = 0;
// should probably use GetPublicAddress()
//sid->ShowServerIP(sf::IPAddress::GetLocalAddress());
// too bad Listen() doesn't take an address as well
// then again, old code used INADDR_ANY anyway
if (!lanlink.tcpsocket.Listen(IP_LINK_PORT))
// Note: old code closed socket & retried once on bind failure
gba_connection_state = LINK_ERROR; // FIXME: error code?
else
gba_connection_state = LINK_NEEDS_UPDATE;
} else {
lc.serverport = IP_LINK_PORT;
if (!lc.serveraddr.IsValid()) {
gba_connection_state = LINK_ERROR;
} else {
lanlink.tcpsocket.SetBlocking(false);
sf::Socket::Status status = lanlink.tcpsocket.Connect(lc.serverport, lc.serveraddr);
if (status == sf::Socket::Error || status == sf::Socket::Disconnected)
gba_connection_state = LINK_ERROR;
else
gba_connection_state = LINK_NEEDS_UPDATE;
}
}
}
// No errors, save the link mode
if (initOk) {
if (gba_connection_state != LINK_ERROR) {
gba_link_mode = mode;
} else {
gba_link_mode = LINK_DISCONNECTED;
}
return initOk;
return gba_connection_state;
}
ConnectionState ConnectLinkUpdate(char * const message, size_t size)
{
message[0] = '\0';
if (gba_connection_state != LINK_NEEDS_UPDATE) {
gba_connection_state = LINK_ERROR;
snprintf(message, size, N_("Link connection does not need updates."));
return LINK_ERROR;
}
if (gba_link_mode == LINK_CABLE_SOCKET && lanlink.server) {
sf::Selector<sf::SocketTCP> fdset;
fdset.Add(lanlink.tcpsocket);
if (fdset.Wait(0.1) == 1) {
int nextSlave = lanlink.connectedSlaves + 1;
sf::Socket::Status st = lanlink.tcpsocket.Accept(ls.tcpsocket[nextSlave]);
if (st == sf::Socket::Error) {
for (int j = 1; j < nextSlave; j++)
ls.tcpsocket[j].Close();
snprintf(message, size, N_("Network error."));
gba_connection_state = LINK_ERROR;
} else {
sf::Packet packet;
packet << static_cast<sf::Uint16>(nextSlave)
<< static_cast<sf::Uint16>(lanlink.numslaves);
ls.tcpsocket[nextSlave].Send(packet);
snprintf(message, size, N_("Player %d connected"), nextSlave);
lanlink.connectedSlaves++;
}
}
if (lanlink.numslaves == lanlink.connectedSlaves) {
lanlink.connected = true;
for (int i = 1; i <= lanlink.numslaves; i++) {
sf::Packet packet;
packet << true;
ls.tcpsocket[i].Send(packet);
}
snprintf(message, size, N_("All players connected"));
gba_connection_state = LINK_OK;
}
} else if (gba_link_mode == LINK_CABLE_SOCKET && !lanlink.server) {
sf::Packet packet;
sf::Socket::Status status = lanlink.tcpsocket.Receive(packet);
if (status == sf::Socket::Error || status == sf::Socket::Disconnected) {
snprintf(message, size, N_("Network error."));
gba_connection_state = LINK_ERROR;
} else if (status == sf::Socket::Done) {
if (linkid == 0) {
sf::Uint16 receivedId, receivedSlaves;
packet >> receivedId >> receivedSlaves;
if (packet) {
linkid = receivedId;
lanlink.numslaves = receivedSlaves;
snprintf(message, size, N_("Connected as #%d, Waiting for %d players to join"),
linkid + 1, lanlink.numslaves - linkid);
}
} else {
bool gameReady;
packet >> gameReady;
if (packet && gameReady) {
lanlink.connected = true;
gba_connection_state = LINK_OK;
snprintf(message, size, N_("All players joined."));
}
}
sf::Selector<sf::SocketTCP> fdset;
fdset.Add(lanlink.tcpsocket);
fdset.Wait(0.1);
}
}
return gba_connection_state;
}
void SetLinkServerHost(const char *host) {
lc.serveraddr = sf::IPAddress(host);
joybusHostAddr = sf::IPAddress(host);
}
void GetLinkServerHost(char * const host, size_t size) {
if (host == NULL || size == 0)
return;
host[0] = '\0';
if (gba_link_mode == LINK_GAMECUBE_DOLPHIN)
strncpy(host, joybusHostAddr.ToString().c_str(), size);
else if (lanlink.server)
strncpy(host, sf::IPAddress::GetLocalAddress().ToString().c_str(), size);
else
strncpy(host, lc.serveraddr.ToString().c_str(), size);
}
static void ReInitLink()
@ -1120,11 +1260,11 @@ static void ReInitLink()
}
void CloseLink(void){
if (GetLinkMode() == LINK_DISCONNECTED) {
if (gba_link_mode == LINK_DISCONNECTED) {
return; // Nothing to do
}
if (GetLinkMode() == LINK_GAMECUBE_DOLPHIN) {
if (gba_link_mode == LINK_GAMECUBE_DOLPHIN) {
JoyBusShutdown();
}
@ -1147,45 +1287,48 @@ void CloseLink(void){
}
}
}
int f = linkmem->linkflags;
f &= ~(1 << linkid);
if(f & 0xf) {
linkmem->linkflags = f;
int n = linkmem->numgbas;
for(int i = 0; i < n; i--)
if(f <= (1 << (i + 1)) - 1) {
linkmem->numgbas = i + 1;
break;
}
}
for(i=0;i<4;i++){
if(linksync[i]!=NULL){
#if (defined __WIN32__ || defined _WIN32)
ReleaseSemaphore(linksync[i], 1, NULL);
CloseHandle(linksync[i]);
#else
sem_close(linksync[i]);
if(!(f & 0xf)) {
linkevent[sizeof(linkevent)-2]=(char)i+'1';
sem_unlink(linkevent);
}
#endif
if (gba_link_mode == LINK_CABLE_IPC || gba_link_mode == LINK_RFU_IPC) {
int f = linkmem->linkflags;
f &= ~(1 << linkid);
if(f & 0xf) {
linkmem->linkflags = f;
int n = linkmem->numgbas;
for(int i = 0; i < n; i--)
if(f <= (1 << (i + 1)) - 1) {
linkmem->numgbas = i + 1;
break;
}
}
}
#if (defined __WIN32__ || defined _WIN32)
CloseHandle(mmf);
UnmapViewOfFile(linkmem);
// FIXME: move to caller
// (but there are no callers, so why bother?)
//regSetDwordValue("LAN", lanlink.active);
for(i=0;i<4;i++){
if(linksync[i]!=NULL){
#if (defined __WIN32__ || defined _WIN32)
ReleaseSemaphore(linksync[i], 1, NULL);
CloseHandle(linksync[i]);
#else
if(!(f & 0xf))
shm_unlink("/" LOCAL_LINK_NAME);
munmap(linkmem, sizeof(LINKDATA));
close(mmf);
sem_close(linksync[i]);
if(!(f & 0xf)) {
linkevent[sizeof(linkevent)-2]=(char)i+'1';
sem_unlink(linkevent);
}
#endif
}
}
#if (defined __WIN32__ || defined _WIN32)
CloseHandle(mmf);
UnmapViewOfFile(linkmem);
// FIXME: move to caller
// (but there are no callers, so why bother?)
//regSetDwordValue("LAN", lanlink.active);
#else
if(!(f & 0xf))
shm_unlink("/" LOCAL_LINK_NAME);
munmap(linkmem, sizeof(LINKDATA));
close(mmf);
#endif
}
gba_link_mode = LINK_DISCONNECTED;
@ -1215,81 +1358,6 @@ lserver::lserver(void){
oncewait = false;
}
bool lserver::Init(ServerInfoDisplay *sid){
// too bad Listen() doesn't take an address as well
// then again, old code used INADDR_ANY anyway
if(!lanlink.tcpsocket.Listen(IP_LINK_PORT))
// Note: old code closed socket & retried once on bind failure
return false; // FIXME: error code?
if(lanlink.thread!=NULL){
lanlink.terminate = true;
WaitForSingleObject(linksync[vbaid], 500);
lanlink.thread = NULL;
}
lanlink.terminate = false;
linkid = 0;
// should probably use GetPublicAddress()
sid->ShowServerIP(sf::IPAddress::GetLocalAddress());
lanlink.thread = new sf::Thread(LinkServerThread, sid);
lanlink.thread->Launch();
return true;
}
void LinkServerThread(void *_sid){
ServerInfoDisplay *sid = (ServerInfoDisplay *)_sid;
sf::Selector<sf::SocketTCP> fdset;
char inbuffer[256], outbuffer[256];
s32 *intinbuffer = (s32*)inbuffer;
u16 *u16inbuffer = (u16*)inbuffer;
s32 *intoutbuffer = (s32*)outbuffer;
u16 *u16outbuffer = (u16*)outbuffer;
i = 0;
while(i<lanlink.numslaves){
fdset.Clear();
fdset.Add(lanlink.tcpsocket);
if(lanlink.terminate){
ReleaseSemaphore(linksync[vbaid], 1, NULL);
goto CloseInfoDisplay;
}
if(fdset.Wait(0.1)==1){
sf::Socket::Status st =
lanlink.tcpsocket.Accept(ls.tcpsocket[i+1]);
if(st == sf::Socket::Error) {
for(int j=1;j<i;j++) ls.tcpsocket[j].Close();
systemMessage(0, N_("Network error."));
lanlink.terminate = true;
} else {
i++;
WRITE16LE(&u16outbuffer[0], i);
WRITE16LE(&u16outbuffer[1], lanlink.numslaves);
ls.tcpsocket[i].Send(outbuffer, 4);
sid->ShowConnect(i);
}
}
sid->Ping();
}
lanlink.connected = true;
sid->Connected();
for(i=1;i<=lanlink.numslaves;i++){
outbuffer[0] = 4;
ls.tcpsocket[i].Send(outbuffer, 4);
}
CloseInfoDisplay:
delete sid;
return;
}
void lserver::Send(void){
if(lanlink.type==0){ // TCP
if(savedlinktime==-1){
@ -1388,92 +1456,6 @@ lclient::lclient(void){
return;
}
bool lclient::Init(sf::IPAddress addr, ClientInfoDisplay *cid){
serveraddr = addr;
serverport = IP_LINK_PORT;
lanlink.tcpsocket.SetBlocking(false);
if(lanlink.thread!=NULL){
lanlink.terminate = true;
WaitForSingleObject(linksync[vbaid], 500);
lanlink.thread = NULL;
}
cid->ConnectStart(addr);
lanlink.terminate = false;
lanlink.thread = new sf::Thread(LinkClientThread, cid);
lanlink.thread->Launch();
return true;
}
void LinkClientThread(void *_cid){
ClientInfoDisplay *cid = (ClientInfoDisplay *)_cid;
sf::Selector<sf::SocketTCP> fdset;
int numbytes;
char inbuffer[16];
u16 *u16inbuffer = (u16*)inbuffer;
unsigned long block = 0;
while(lanlink.tcpsocket.Connect(lc.serverport, lc.serveraddr) != sf::Socket::Done) {
// stupid SFML has no way of giving what sort of error occurred
// so we'll just have to do a retry loop, I guess.
cid->Ping();
if(lanlink.terminate)
goto CloseInfoDisplay;
// old code had broken sleep on socket, which isn't
// even connected yet
// corrected sleep on socket worked, but this is more sane
// and probably less portable... works with mingw32 at least
#if (defined __WIN32__ || defined _WIN32)
Sleep(100); // in milliseconds
#else
usleep(100000); // in microseconds
#endif
}
numbytes = 0;
size_t got;
while(numbytes<4) {
lanlink.tcpsocket.Receive(inbuffer+numbytes, 4 - numbytes, got);
numbytes += got;
fdset.Clear();
fdset.Add(lanlink.tcpsocket);
fdset.Wait(0.1);
cid->Ping();
if(lanlink.terminate) {
lanlink.tcpsocket.Close();
goto CloseInfoDisplay;
}
}
linkid = (int)READ16LE(&u16inbuffer[0]);
lanlink.numslaves = (int)READ16LE(&u16inbuffer[1]);
cid->ShowConnect(linkid + 1, lanlink.numslaves - linkid);
numbytes = 0;
inbuffer[0] = 1;
while(numbytes<inbuffer[0]) {
lanlink.tcpsocket.Receive(inbuffer+numbytes, inbuffer[0] - got, got);
numbytes += got;
fdset.Clear();
fdset.Add(lanlink.tcpsocket);
fdset.Wait(0.1);
cid->Ping();
if(lanlink.terminate) {
lanlink.tcpsocket.Close();
goto CloseInfoDisplay;
}
}
lanlink.connected = true;
cid->Connected();
CloseInfoDisplay:
delete cid;
return;
}
void lclient::CheckConn(void){
size_t nr;
lanlink.tcpsocket.Receive(inbuffer, 1, nr);

View File

@ -1,8 +1,6 @@
#ifndef GBA_GBALINK_H
#define GBA_GBALINK_H
#pragma once
/**
* Link modes to be passed to InitLink
*/
@ -15,13 +13,32 @@ enum LinkMode
LINK_GAMECUBE_DOLPHIN
};
/**
* State of the connection attempt
*/
enum ConnectionState
{
LINK_OK,
LINK_ERROR,
LINK_NEEDS_UPDATE,
LINK_ABORT
};
/**
* Initialize GBA linking
*
* @param mode Device to emulate, plugged to the GBA link port.
* @return success
*/
extern bool InitLink(LinkMode mode);
extern ConnectionState InitLink(LinkMode mode);
/**
* Update a link connection request
*
* @param message Information message
* @param size Maximum message size
*/
extern ConnectionState ConnectLinkUpdate(char * const message, size_t size);
/**
* Get the currently enabled link mode
@ -30,6 +47,21 @@ extern bool InitLink(LinkMode mode);
*/
extern LinkMode GetLinkMode();
/**
* Set the host to connect to when in socket mode
*/
extern void SetLinkServerHost(const char *host);
/**
* Get the host relevant to context
*
* If in lan server mode, returns the external IP adress
* If in lan client mode, returns the IP adress of the host to connect to
* If in gamecube mode, returns the IP adress of the dolphin host
*
*/
extern void GetLinkServerHost(char * const host, size_t size);
/**
* Set the current link mode to LINK_DISCONNECTED
*/
@ -87,18 +119,8 @@ extern const char *MakeInstanceFilename(const char *Input);
#ifndef NO_LINK
// Link implementation
#include <SFML/System.hpp>
#include <SFML/Network.hpp>
class ServerInfoDisplay
{
public:
virtual void ShowServerIP(const sf::IPAddress& addr) = 0;
virtual void ShowConnect(const int player) = 0;
virtual void Ping() = 0;
virtual void Connected() = 0;
};
typedef struct {
u16 linkdata[5];
u16 linkcmd;
@ -130,19 +152,10 @@ public:
sf::SocketTCP tcpsocket[4];
sf::IPAddress udpaddr[4];
lserver(void);
bool Init(ServerInfoDisplay *);
void Send(void);
void Recv(void);
};
class ClientInfoDisplay {
public:
virtual void ConnectStart(const sf::IPAddress& addr) = 0;
virtual void Ping() = 0;
virtual void ShowConnect(const int player, const int togo) = 0;
virtual void Connected() = 0;
};
class lclient{
sf::Selector<sf::SocketTCP> fdset;
char inbuffer[256], outbuffer[256];
@ -157,7 +170,6 @@ public:
sf::SocketTCP noblock;
int numtransfers;
lclient(void);
bool Init(sf::IPAddress, ClientInfoDisplay *);
void Send(void);
void Recv(void);
void CheckConn(void);
@ -165,12 +177,10 @@ public:
typedef struct {
sf::SocketTCP tcpsocket;
//sf::SocketUDP udpsocket;
int numslaves;
sf::Thread *thread;
int connectedSlaves;
int type;
bool server;
bool terminate;
bool connected;
bool speed;
} LANLINKDATA;
@ -192,8 +202,6 @@ extern int linkid;
#else
// stubs to keep #ifdef's out of mainline
inline void JoyBusConnect() { }
inline void JoyBusShutdown() { }
inline void JoyBusUpdate(int) { }
inline bool InitLink() { return true; }

View File

@ -689,7 +689,10 @@ void LinkOptions::GetAllData(LinkGeneral *src)
if (newMode != oldMode) {
CloseLink();
InitLink(newMode);
ConnectionState state = InitLink(newMode);
if (state != LINK_OK) {
CloseLink();
}
}
return;

View File

@ -63,6 +63,7 @@ public:
// attached to OK, so skip when OK
void NetConnect(wxCommandEvent &ev)
{
static const int length = 256;
if(!dlg->Validate() || !dlg->TransferDataFromWindow())
return;
update_opts(); // save fast flag and client host
@ -70,150 +71,62 @@ public:
// Close any previous link
CloseLink();
wxString connmsg, pmsg;
wxMutex lock;
wxCondition sig(lock);
lock.Lock();
bool done = false;
wxString connmsg;
wxString title;
if(lanlink.server) {
lanlink.numslaves = n_players - 1;
class sid_t : public ServerInfoDisplay
{
wxMutex *lock;
wxCondition *sig;
wxString *connmsg, *pmsg;
bool *done;
bool conn[3];
public:
sid_t(wxMutex *m, wxCondition *c, wxString *cm, wxString *pm,
bool *d) :
lock(m), sig(c), connmsg(cm), pmsg(pm), done(d) {}
void ShowServerIP(const sf::IPAddress &addr) {
wxString addr_s(addr.ToString().c_str(), wxConvLibc);
wxString msg;
msg.Printf(_("Server IP address is: %s\n"), addr_s.c_str());
connmsg->append(msg);
conn[0] = conn[1] = conn[2] = false;
}
void ShowConnect(int player) {
wxString msg;
conn[player - 1] = true;
lock->Lock();
pmsg->clear();
for(int i = 0; i < 3; i++)
if(conn[i]) {
msg.Printf(_("Player %d connected\n"), i + 2);
pmsg->append(msg);
}
sig->Signal();
lock->Unlock();
}
void Ping() {
lock->Lock();
sig->Signal();
if(*done)
lanlink.terminate = true;
lock->Unlock();
}
void Connected() {
lock->Lock();
*done = true;
sig->Signal();
lock->Unlock();
}
};
sid_t* sid = new sid_t(&lock, &sig, &connmsg, &pmsg, &done);
if (!ls.Init(sid)) {
wxLogError(_("Error occurred.\nPlease try again."));
lock.Unlock();
delete sid;
return;
}
wxProgressDialog
pdlg(_("Waiting for clients..."), connmsg,
100, dlg, wxPD_APP_MODAL|wxPD_CAN_ABORT|wxPD_ELAPSED_TIME);
while(!done) {
if(!pdlg.Pulse(connmsg + pmsg))
done = true;
sig.Wait();
}
char host[length];
GetLinkServerHost(host, length);
lanlink.numslaves = n_players - 1;
title.Printf(_("Waiting for clients..."));
connmsg.Printf(_("Server IP address is: %s\n"), wxString(host, wxConvLibc).c_str());
} else {
class cid_t : public ClientInfoDisplay
{
wxMutex *lock;
wxCondition *sig;
wxString *connmsg, *pmsg;
bool *done;
public:
cid_t(wxMutex *m, wxCondition *c, wxString *cm, wxString *pm,
bool *d) :
lock(m), sig(c), connmsg(cm), pmsg(pm), done(d) {}
void ConnectStart(const sf::IPAddress &addr) {
wxString addr_s(addr.ToString().c_str(), wxConvLibc);
connmsg->Printf(_("Connecting to %s\n"), addr_s.c_str());
}
void ShowConnect(int player, int togo) {
wxString msg;
lock->Lock();
pmsg->Printf(_("Connected as #%d\n"), player);
if(togo)
msg.Printf(_("Waiting for %d players to join"), togo);
else
msg = _("All players joined.");
pmsg->append(msg);
sig->Signal();
lock->Unlock();
}
void Ping() {
lock->Lock();
sig->Signal();
if(*done)
lanlink.terminate = true;
lock->Unlock();
}
void Connected() {
lock->Lock();
*done = true;
sig->Signal();
lock->Unlock();
}
};
cid_t* cid = new cid_t(&lock, &sig, &connmsg, &pmsg, &done);
if (!lc.Init(sf::IPAddress(std::string(gopts.link_host.mb_str())), cid)) {
wxLogError(_("Error occurred.\nPlease try again."));
lock.Unlock();
delete cid;
return;
}
wxProgressDialog
pdlg(_("Waiting for connection..."), connmsg,
100, dlg, wxPD_APP_MODAL|wxPD_CAN_ABORT|wxPD_ELAPSED_TIME);
while(!done) {
if(!pdlg.Pulse(connmsg + pmsg))
done = true;
sig.Wait();
}
SetLinkServerHost(gopts.link_host.mb_str());
title.Printf(_("Waiting for connection..."));
connmsg.Printf(_("Connecting to %s\n"), gopts.link_host.c_str());
}
lock.Unlock();
// Init link
ConnectionState state = InitLink(LINK_CABLE_SOCKET);
// Display a progress dialog while the connection is establishing
if (state == LINK_NEEDS_UPDATE) {
wxProgressDialog pdlg(title, connmsg,
100, dlg, wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME);
while (state == LINK_NEEDS_UPDATE) {
// Ask the core for updates
char message[length];
state = ConnectLinkUpdate(message, length);
connmsg = wxString(message, wxConvLibc);
// Does the user want to abort?
if (!pdlg.Pulse(connmsg)) {
state = LINK_ABORT;
}
}
}
// The user canceled the connection attempt
if (state == LINK_ABORT) {
CloseLink();
}
// Something failed during init
if (state == LINK_ERROR) {
CloseLink();
wxLogError(_("Error occurred.\nPlease try again."));
}
if(lanlink.connected) {
pmsg.Replace(wxT("\n"), wxT(" "));
systemScreenMessage(pmsg);
// Init link
InitLink(LINK_CABLE_SOCKET);
ev.Skip(); // all OK
connmsg.Replace(wxT("\n"), wxT(" "));
systemScreenMessage(connmsg);
ev.Skip(); // all OK
}
}
} net_link_handler;
@ -3228,7 +3141,10 @@ bool MainFrame::InitMore(void)
}
}
InitLink(linkMode);
ConnectionState linkState = InitLink(linkMode);
if (linkState != LINK_OK) {
CloseLink();
}
if (GetLinkMode() != LINK_DISCONNECTED)
cmd_enable |= CMDEN_LINK_ANY;