From e4c05d31778a85014b2a52e2f20753b38dfbf950 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 5 Nov 2009 04:41:36 +0000 Subject: [PATCH] unix build merged in, bitmap resources from xpm instead of rc, better addr relay, better selection of addrs by time last seen for faster connect git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@32 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build-unix.txt | 73 ++++++++++ build.txt | 88 ------------ db.cpp | 10 +- headers.h | 38 ++++-- irc.cpp | 16 +-- irc.h | 4 +- main.cpp | 68 +++++---- main.h | 8 ++ makefile.unix | 86 ++++++++++++ net.cpp | 177 ++++++++++++------------ net.h | 3 +- ui.cpp | 103 ++++++++------ uibase.cpp | 10 +- uiproject.fbp | 10 +- util.cpp | 8 +- util.h | 40 ++++-- xpm/addressbook16.xpm | 278 +++++++++++++++++++++++++++++++++++++ xpm/addressbook20.xpm | 282 ++++++++++++++++++++++++++++++++++++++ xpm/bitcoin.xpm | 304 +++++++++++++++++++++++++++++++++++++++++ xpm/check.xpm | 41 ++++++ xpm/send16.xpm | 278 +++++++++++++++++++++++++++++++++++++ xpm/send16noshadow.xpm | 278 +++++++++++++++++++++++++++++++++++++ xpm/send20.xpm | 282 ++++++++++++++++++++++++++++++++++++++ 23 files changed, 2184 insertions(+), 301 deletions(-) create mode 100644 build-unix.txt delete mode 100644 build.txt create mode 100644 makefile.unix create mode 100644 xpm/addressbook16.xpm create mode 100644 xpm/addressbook20.xpm create mode 100644 xpm/bitcoin.xpm create mode 100644 xpm/check.xpm create mode 100644 xpm/send16.xpm create mode 100644 xpm/send16noshadow.xpm create mode 100644 xpm/send20.xpm diff --git a/build-unix.txt b/build-unix.txt new file mode 100644 index 000000000..6b29e1e5c --- /dev/null +++ b/build-unix.txt @@ -0,0 +1,73 @@ +Bitcoin v0.2.0 BETA + +Copyright (c) 2009 Satoshi Nakamoto +Distributed under the MIT/X11 software license, see the accompanying +file license.txt or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +UNIX BUILD NOTES + + +Dependencies +------------ +apt-get install build-essential +apt-get install libgtk2.0-dev +apt-get install libssl-dev + +Libraries you need to obtain separately and build: + default path download +wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ +Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \boost http://www.boost.org/users/download/ + +Their licenses: +wxWidgets LGPL 2.1 with very liberal exceptions +Berkeley DB New BSD license with additional requirement that linked software must be free open source +Boost MIT-like license + +Versions used in this release: +GCC 4.3.3 +OpenSSL 0.9.8k +wxWidgets 2.8.9 +Berkeley DB 4.7.25.NC +Boost 1.40.0 + + +Notes +----- +The UI layout is edited with wxFormBuilder. Open the project file +uiproject.fbp. It generates uibase.cpp and uibase.h, which define base +classes that do the rote work of constructing all the UI elements. + +The release is built with GCC and then "strip bitcoin" to strip the debug +symbols, which reduces the executable size by about 90%. + + +wxWidgets +--------- +cd /usr/local/wxWidgets-2.8.9 +mkdir buildgtk +cd buildgtk +../configure --with-gtk --enable-debug --disable-shared --enable-monolithic +make +su +make install +ldconfig + + +Berkeley DB +----------- +cd /usr/local/db-4.7.25.NC/build_unix +../dist/configure --enable-cxx +make + + +Boost +----- +cd /usr/local/boost_1_40_0 +su +./bootstrap.sh +./bjam install diff --git a/build.txt b/build.txt deleted file mode 100644 index 4368af855..000000000 --- a/build.txt +++ /dev/null @@ -1,88 +0,0 @@ -BitCoin v0.1.6 BETA - -Copyright (c) 2009 Satoshi Nakamoto -Distributed under the MIT/X11 software license, see the accompanying -file license.txt or http://www.opensource.org/licenses/mit-license.php. -This product includes software developed by the OpenSSL Project for use in -the OpenSSL Toolkit (http://www.openssl.org/). This product includes -cryptographic software written by Eric Young (eay@cryptsoft.com). - - -Compilers Supported -------------------- -MinGW GCC (v3.4.5) -Microsoft Visual C++ 6.0 SP6 - - -Dependencies ------------- -Libraries you need to obtain separately to build: - - default path download -wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ - or prebuilt: http://wxpack.sourceforge.net -OpenSSL \openssl http://www.openssl.org/source/ -Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html -Boost \boost http://www.boost.org/users/download/ - -Their licenses: -wxWidgets LGPL 2.1 with very liberal exceptions -OpenSSL Old BSD license with the problematic advertising requirement -Berkeley DB New BSD license with additional requirement that linked software must be free open source -Boost MIT-like license - - -Notes ------ -The UI layout is edited with wxFormBuilder. Open the project file -uiproject.fbp. It generates uibase.cpp and uibase.h, which define base -classes that do the rote work of constructing all the UI elements. - -The release is built with GCC and then "strip bitcoin.exe" to strip the debug -symbols, which reduces the executable size by about 90%. - - -OpenSSL -------- -Bitcoin does not use any encryption. If you want to do a no-everything -build of OpenSSL to exclude encryption routines, a few patches are required. -(OpenSSL v0.9.8h) - -Edit engines\e_gmp.c and put this #ifndef around #include - #ifndef OPENSSL_NO_RSA - #include - #endif - -Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line: - void ERR_load_RSA_strings(void) { } - -Edit ms\mingw32.bat and replace the Configure line's parameters with this -no-everything list. You have to put this in the batch file because batch -files can't take more than 9 command line parameters. - perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh - -Also REM out the following line in ms\mingw32.bat. The build fails after it's -already finished building libeay32, which is all we care about, but the -failure aborts the script before it runs dllwrap to generate libeay32.dll. - REM if errorlevel 1 goto end - -Build - ms\mingw32.bat - -If you want to use it with MSVC, generate the .lib file - lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib - - -Berkeley DB ------------ -Using MinGW and MSYS: -cd \db\build_unix -sh ../dist/configure --enable-mingw --enable-cxx -make - - -Boost ------ -If you have trouble compiling Boost with Microsoft Visual C++ 6.0, try going -back to Boost version 1.35. It looks like they may be starting to reduce -support for MSVC 6.0. diff --git a/db.cpp b/db.cpp index f9e25834d..b702b0cba 100644 --- a/db.cpp +++ b/db.cpp @@ -62,9 +62,9 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) if (fShutdown) return; string strDataDir = GetDataDir(); - string strLogDir = strDataDir + "\\database"; + string strLogDir = strDataDir + "/database"; _mkdir(strLogDir.c_str()); - string strErrorFile = strDataDir + "\\db.log"; + string strErrorFile = strDataDir + "/db.log"; printf("dbenv.open strLogDir=%s strErrorFile=%s\n", strLogDir.c_str(), strErrorFile.c_str()); dbenv.set_lg_dir(strLogDir.c_str()); @@ -411,7 +411,6 @@ bool CAddrDB::WriteAddress(const CAddress& addr) bool CAddrDB::LoadAddresses() { - CRITICAL_BLOCK(cs_mapIRCAddresses) CRITICAL_BLOCK(cs_mapAddresses) { // Load user provided addresses @@ -425,10 +424,7 @@ bool CAddrDB::LoadAddresses() { CAddress addr(psz, NODE_NETWORK); if (addr.IsValid()) - { AddAddress(*this, addr); - mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); - } } } catch (...) { } @@ -678,7 +674,7 @@ void ThreadFlushWalletDB(void* parg) if (nRefCount == 0 && !fShutdown) { // Flush wallet.dat so it's self contained - nLastFlushed == nWalletDBUpdated; + nLastFlushed = nWalletDBUpdated; int64 nStart = GetTimeMillis(); dbenv.txn_checkpoint(0, 0, 0); dbenv.lsn_reset(strFile.c_str(), 0); diff --git a/headers.h b/headers.h index f00b7dde0..c7f3cd851 100644 --- a/headers.h +++ b/headers.h @@ -17,16 +17,18 @@ #endif #define _WIN32_IE 0x0400 #define WIN32_LEAN_AND_MEAN 1 +#define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h #include #include #include #include #include +#include #include #include #include #include -#include +#include #include #include #include @@ -50,22 +52,28 @@ #include #include #include -#include - +#include + #ifdef __WXMSW__ #include #include -#include +#include #include -#include -#include -#include -#else +#include +#include +#include +#else #include +#include #include -#include -#include -#endif +#include +#include +#include +#include +#include +#include +#include +#endif #pragma hdrstop using namespace std; @@ -88,3 +96,11 @@ using namespace boost; #include "market.h" #include "uibase.h" #include "ui.h" + +#include "xpm/addressbook16.xpm" +#include "xpm/addressbook20.xpm" +#include "xpm/bitcoin.xpm" +#include "xpm/check.xpm" +#include "xpm/send16.xpm" +#include "xpm/send16noshadow.xpm" +#include "xpm/send20.xpm" diff --git a/irc.cpp b/irc.cpp index f839dc522..4d4ed0f41 100644 --- a/irc.cpp +++ b/irc.cpp @@ -4,10 +4,7 @@ #include "headers.h" - -map, CAddress> mapIRCAddresses; -CCriticalSection cs_mapIRCAddresses; - +int nGotIRCAddresses = 0; @@ -259,16 +256,7 @@ void ThreadIRCSeed(void* parg) CAddrDB addrdb; if (AddAddress(addrdb, addr)) printf("IRC got new address\n"); - else - { - // make it try connecting again - CRITICAL_BLOCK(cs_mapAddresses) - if (mapAddresses.count(addr.GetKey())) - mapAddresses[addr.GetKey()].nLastFailed = 0; - } - - CRITICAL_BLOCK(cs_mapIRCAddresses) - mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); + nGotIRCAddresses++; } else { diff --git a/irc.h b/irc.h index 91c3ffe68..c69fd9ee9 100644 --- a/irc.h +++ b/irc.h @@ -4,7 +4,5 @@ extern bool RecvLine(SOCKET hSocket, string& strLine); extern void ThreadIRCSeed(void* parg); -extern bool fRestartIRCSeed; -extern map, CAddress> mapIRCAddresses; -extern CCriticalSection cs_mapIRCAddresses; +extern int nGotIRCAddresses; diff --git a/main.cpp b/main.cpp index ade3b51c7..2119495e6 100644 --- a/main.cpp +++ b/main.cpp @@ -100,13 +100,10 @@ bool AddToWallet(const CWalletTx& wtxIn) if (fInsertedNew) wtx.nTimeReceived = GetAdjustedTime(); - //// debug print - printf("AddToWallet %s %s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), fInsertedNew ? "new" : "update"); - + bool fUpdated = false; if (!fInsertedNew) { // Merge - bool fUpdated = false; if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) { wtx.hashBlock = wtxIn.hashBlock; @@ -128,13 +125,15 @@ bool AddToWallet(const CWalletTx& wtxIn) wtx.fSpent = wtxIn.fSpent; fUpdated = true; } - if (!fUpdated) - return true; } + //// debug print + printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : "")); + // Write to disk - if (!wtx.WriteToDisk()) - return false; + if (fInsertedNew || fUpdated) + if (!wtx.WriteToDisk()) + return false; // Notify UI vWalletUpdated.push_back(hash); @@ -820,7 +819,7 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map& mapTestPoo } if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) - return error("ConnectInputs() : %s prevout.n out of range %d %d %d", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size()); + return error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,6).c_str(), txPrev.ToString().c_str()); // If prev is coinbase, check that it's matured if (txPrev.IsCoinBase()) @@ -1217,7 +1216,7 @@ bool CBlock::AcceptBlock() if (nTime <= pindexPrev->GetMedianTimePast()) return error("AcceptBlock() : block's timestamp is too early"); - // Check that all transactions are finalized (starting around 30 Nov 2009) + // Check that all transactions are finalized (starting around Dec 2009) if (nBestHeight > 31000) // 25620 + 5320 foreach(const CTransaction& tx, vtx) if (!tx.IsFinal(nTime)) @@ -1384,7 +1383,7 @@ FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszM { if (nFile == -1) return NULL; - FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode); + FILE* file = fopen(strprintf("%s/blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode); if (!file) return NULL; if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w')) @@ -1718,6 +1717,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) + if (strCommand == "version") { // Each connection can only send one version message @@ -1765,6 +1765,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->fSuccessfullyConnected = true; + // Update the last seen time + if (pfrom->fNetworkNode) + AddressCurrentlyConnected(pfrom->addr); + printf("version message: version %d\n", pfrom->nVersion); } @@ -1781,23 +1785,16 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vector vAddr; vRecv >> vAddr; - // Clear addrknown lists periodically to allow refresh broadcasts - static int64 nLastClearedAddrKnown; - if (nLastClearedAddrKnown < GetAdjustedTime() - 24 * 60 * 60) - { - nLastClearedAddrKnown = GetAdjustedTime(); - CRITICAL_BLOCK(cs_vNodes) - foreach(CNode* pnode, vNodes) - pnode->setAddrKnown.clear(); - } - // Store the new addresses CAddrDB addrdb; - foreach(const CAddress& addr, vAddr) + foreach(CAddress& addr, vAddr) { if (fShutdown) return true; - AddAddress(addrdb, addr); + addr.nTime = GetAdjustedTime(); + if (pfrom->fGetAddr) + addr.nTime -= 5 * 24 * 60 * 60; + AddAddress(addrdb, addr, false); pfrom->AddAddressKnown(addr); if (!pfrom->fGetAddr && addr.IsRoutable()) { @@ -1816,6 +1813,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vector vInv; vRecv >> vInv; + // Update the last seen time for this node's address + if (pfrom->fNetworkNode) + AddressCurrentlyConnected(pfrom->addr); + CTxDB txdb("r"); foreach(const CInv& inv, vInv) { @@ -2099,6 +2100,25 @@ bool SendMessages(CNode* pto) if (pto->nVersion == 0) return true; + // Address refresh broadcast + static int64 nLastRebroadcast; + if (nLastRebroadcast < GetTime() - 24 * 60 * 60) // every 24 hours + { + nLastRebroadcast = GetTime(); + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + { + // Periodically clear setAddrKnown to allow refresh broadcasts + pnode->setAddrKnown.clear(); + + // Rebroadcast our address + if (addrLocalHost.IsRoutable() && !fUseProxy) + pnode->PushAddress(addrLocalHost); + } + } + } + // // Message: addr @@ -2187,7 +2207,7 @@ void GenerateBitcoins(bool fGenerate) } if (fGenerateBitcoins) { - int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS")); + int nProcessors = wxThread::GetCPUCount(); printf("%d processors\n", nProcessors); if (nProcessors < 1) nProcessors = 1; diff --git a/main.h b/main.h index a0258cf2c..6d8f0ed87 100644 --- a/main.h +++ b/main.h @@ -968,6 +968,14 @@ public: return error("CBlock::WriteToDisk() : ftell failed"); fileout << *this; + // Flush stdio buffers and commit to disk before returning + fflush(fileout); +#ifdef __WXMSW__ + _commit(_fileno(fileout)); +#else + fsync(fileno(fileout)); +#endif + return true; } diff --git a/makefile.unix b/makefile.unix new file mode 100644 index 000000000..c62efc008 --- /dev/null +++ b/makefile.unix @@ -0,0 +1,86 @@ +# Copyright (c) 2009 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +ifneq "$(BUILD)" "debug" +ifneq "$(BUILD)" "release" +BUILD=debug +endif +endif +ifeq "$(BUILD)" "debug" +D=d +DEBUGFLAGS=-g -D__WXDEBUG__ +endif + + + +INCLUDEPATHS=-I"/usr/include" \ + -I"/usr/local/boost_1_40_0" \ + -I"/usr/local/db-4.7.25.NC/build_unix" \ + -I"/usr/local/include/wx-2.8" \ + -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" + +LIBPATHS=-L"/usr/lib" \ + -L"/usr/local/lib" \ + -L"/usr/local/db-4.7.25.NC/build_unix" + +LIBS= \ + -Wl,-Bstatic -l boost_thread -l boost_system -l boost_filesystem -Wl,-Bdynamic \ + -Wl,-Bstatic -l db_cxx -l wx_gtk2$(D)-2.8 -Wl,-Bdynamic \ + -l crypto \ + -l gtk-x11-2.0 -l gthread-2.0 -l SM +WXDEFS=-D__WXGTK__ -DNOPCH +CFLAGS=-O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h + + + +all: bitcoin + + +headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h + g++ -c $(CFLAGS) -o $@ $< + +obj/util.o: util.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/script.o: script.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/db.o: db.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/net.o: net.cpp $(HEADERS) net.h + g++ -c $(CFLAGS) -o $@ $< + +obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h + g++ -c $(CFLAGS) -o $@ $< + +obj/market.o: market.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/uibase.o: uibase.cpp uibase.h + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/irc.o: irc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + + + + +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + +bitcoin: headers.h.gch $(OBJS) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) + +clean: + -rm obj/* + -rm headers.h.gch diff --git a/net.cpp b/net.cpp index 8ccf48b81..c14061e7d 100644 --- a/net.cpp +++ b/net.cpp @@ -3,7 +3,6 @@ // file license.txt or http://www.opensource.org/licenses/mit-license.php. #include "headers.h" -#include void ThreadMessageHandler2(void* parg); void ThreadSocketHandler2(void* parg); @@ -201,12 +200,14 @@ bool GetMyExternalIP(unsigned int& ipRet) -bool AddAddress(CAddrDB& addrdb, const CAddress& addr) +bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline) { if (!addr.IsRoutable()) return false; if (addr.ip == addrLocalHost.ip) return false; + if (fCurrentlyOnline) + addr.nTime = GetAdjustedTime(); CRITICAL_BLOCK(cs_mapAddresses) { map, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); @@ -219,24 +220,47 @@ bool AddAddress(CAddrDB& addrdb, const CAddress& addr) } else { + bool fUpdated = false; CAddress& addrFound = (*it).second; if ((addrFound.nServices | addr.nServices) != addrFound.nServices) { // Services have been added addrFound.nServices |= addr.nServices; - addrdb.WriteAddress(addrFound); - return true; + fUpdated = true; + } + int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60); + if (addrFound.nTime < addr.nTime - nUpdateInterval) + { + // Periodically update most recently seen time + addrFound.nTime = addr.nTime; + fUpdated = true; } - else if (addrFound.nTime < GetAdjustedTime() - 24 * 60 * 60) + if (fUpdated) + addrdb.WriteAddress(addrFound); + } + } + return false; +} + +void AddressCurrentlyConnected(const CAddress& addr) +{ + CRITICAL_BLOCK(cs_mapAddresses) + { + // Only if it's been published already + map, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); + if (it != mapAddresses.end()) + { + CAddress& addrFound = (*it).second; + int64 nUpdateInterval = 60 * 60; + if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval) { // Periodically update most recently seen time addrFound.nTime = GetAdjustedTime(); + CAddrDB addrdb; addrdb.WriteAddress(addrFound); - return false; } } } - return false; } @@ -398,9 +422,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) printf("connected %s\n", addrConnect.ToStringLog().c_str()); // Set to nonblocking - u_long nOne = 1; +#ifdef __WXMSW__ + u_long nOne = 1; if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError()); +#else + if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) + printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno); +#endif // Add node CNode* pnode = new CNode(hSocket, addrConnect, false); @@ -418,7 +447,7 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) else { CRITICAL_BLOCK(cs_mapAddresses) - mapAddresses[addrConnect.GetKey()].nLastFailed = GetTime(); + mapAddresses[addrConnect.GetKey()].nLastFailed = GetAdjustedTime(); return NULL; } } @@ -432,7 +461,7 @@ void CNode::DoDisconnect() // If outbound and never got version message, mark address as failed if (!fInbound && !fSuccessfullyConnected) CRITICAL_BLOCK(cs_mapAddresses) - mapAddresses[addr.GetKey()].nLastFailed = GetTime(); + mapAddresses[addr.GetKey()].nLastFailed = GetAdjustedTime(); // All of a nodes broadcasts and subscriptions are automatically torn down // when it goes down, so a node has to stay up to keep its broadcast going. @@ -549,8 +578,8 @@ void ThreadSocketHandler2(void* parg) timeout.tv_sec = 0; timeout.tv_usec = 50000; // frequency to poll pnode->vSend - struct fd_set fdsetRecv; - struct fd_set fdsetSend; + fd_set fdsetRecv; + fd_set fdsetSend; FD_ZERO(&fdsetRecv); FD_ZERO(&fdsetSend); SOCKET hSocketMax = 0; @@ -599,7 +628,11 @@ void ThreadSocketHandler2(void* parg) if (FD_ISSET(hListenSocket, &fdsetRecv)) { struct sockaddr_in sockaddr; +#ifdef __WXMSW__ int len = sizeof(sockaddr); +#else + socklen_t len = sizeof(sockaddr); +#endif SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); CAddress addr(sockaddr); if (hSocket == INVALID_SOCKET) @@ -765,14 +798,12 @@ void ThreadOpenConnections2(void* parg) } // Initiate network connections - int nTry = 0; - bool fIRCOnly = false; - const int nMaxConnections = 15; loop { // Wait vnThreadsRunning[1]--; Sleep(500); + const int nMaxConnections = 15; while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) { CheckForShutdown(1); @@ -781,93 +812,55 @@ void ThreadOpenConnections2(void* parg) vnThreadsRunning[1]++; CheckForShutdown(1); - // - // The IP selection process is designed to limit vulnerability to address flooding. - // Any class C (a.b.c.?) has an equal chance of being chosen, then an IP is - // chosen within the class C. An attacker may be able to allocate many IPs, but - // they would normally be concentrated in blocks of class C's. They can hog the - // attention within their class C, but not the whole IP address space overall. - // A lone node in a class C will get as much attention as someone holding all 255 - // IPs in another class C. + // Choose an address to connect to based on most recently seen // + CAddress addrConnect; + int64 nBestTime = 0; + int64 nDelay = ((60 * 60) << vNodes.size()); + if (vNodes.size() >= 3) + nDelay *= 4; + if (nGotIRCAddresses > 0) + nDelay *= 100; + + // Do this here so we don't have to critsect vNodes inside mapAddresses critsect + set setConnected; + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + setConnected.insert(pnode->addr.ip); - // Every other try is with IRC addresses only - fIRCOnly = !fIRCOnly; - if (mapIRCAddresses.empty()) - fIRCOnly = false; - else if (nTry++ < 30 && vNodes.size() < nMaxConnections/2) - fIRCOnly = true; - - // Make a list of unique class C's - unsigned char pchIPCMask[4] = { 0xff, 0xff, 0xff, 0x00 }; - unsigned int nIPCMask = *(unsigned int*)pchIPCMask; - vector vIPC; - CRITICAL_BLOCK(cs_mapIRCAddresses) CRITICAL_BLOCK(cs_mapAddresses) { - vIPC.reserve(mapAddresses.size()); - unsigned int nPrev = 0; foreach(const PAIRTYPE(vector, CAddress)& item, mapAddresses) { const CAddress& addr = item.second; - if (!addr.IsIPv4()) - continue; - if (fIRCOnly && !mapIRCAddresses.count(item.first)) + if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip)) continue; - // Taking advantage of mapAddresses being in sorted order, - // with IPs of the same class C grouped together. - unsigned int ipC = addr.ip & nIPCMask; - if (ipC != nPrev) - vIPC.push_back(nPrev = ipC); - } - } - if (vIPC.empty()) - continue; - - // Choose a random class C - unsigned int ipC = vIPC[GetRand(vIPC.size())]; + // Limit retry frequency + if (GetAdjustedTime() < addr.nLastFailed + nDelay) + continue; - // Organize all addresses in the class C by IP - map > mapIP; - CRITICAL_BLOCK(cs_mapIRCAddresses) - CRITICAL_BLOCK(cs_mapAddresses) - { - int64 nDelay = ((30 * 60) << vNodes.size()); - if (!fIRCOnly) - { - nDelay *= 2; - if (vNodes.size() >= 3) - nDelay *= 4; - if (!mapIRCAddresses.empty()) - nDelay *= 100; - } + // Try again only after all addresses had a first attempt + int64 nTime = addr.nTime; + if (addr.nLastFailed > addr.nTime) + nTime -= 365 * 24 * 60 * 60; - for (map, CAddress>::iterator mi = mapAddresses.lower_bound(CAddress(ipC, 0).GetKey()); - mi != mapAddresses.upper_bound(CAddress(ipC | ~nIPCMask, 0xffff).GetKey()); - ++mi) - { - const CAddress& addr = (*mi).second; - if (fIRCOnly && !mapIRCAddresses.count((*mi).first)) - continue; + // Randomize the order a little, putting the standard port first + nTime += GetRand(1 * 60 * 60); + if (addr.port != DEFAULT_PORT) + nTime -= 1 * 60 * 60; - int64 nRandomizer = (addr.nLastFailed * addr.ip * 7777U) % 20000; - if (GetTime() - addr.nLastFailed > nDelay * nRandomizer / 10000) - mapIP[addr.ip].push_back(addr); + if (nTime > nBestTime) + { + nBestTime = nTime; + addrConnect = addr; + } } } - if (mapIP.empty()) - continue; - - // Choose a random IP in the class C - map >::iterator mi = mapIP.begin(); - advance(mi, GetRand(mapIP.size())); - // Once we've chosen an IP, we'll try every given port before moving on - foreach(const CAddress& addrConnect, (*mi).second) - if (OpenNetworkConnection(addrConnect)) - break; + if (addrConnect.IsValid()) + OpenNetworkConnection(addrConnect); } } @@ -989,6 +982,7 @@ bool StartNode(string& strError) pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); strError = ""; +#ifdef __WXMSW__ // Sockets startup WSADATA wsadata; int ret = WSAStartup(MAKEWORD(2,2), &wsadata); @@ -998,6 +992,7 @@ bool StartNode(string& strError) printf("%s\n", strError.c_str()); return false; } +#endif // Get local host ip char pszHostName[255]; @@ -1029,10 +1024,14 @@ bool StartNode(string& strError) } // Set to nonblocking, incoming connections will also inherit this +#ifdef __WXMSW__ u_long nOne = 1; if (ioctlsocket(hListenSocket, FIONBIO, &nOne) == SOCKET_ERROR) +#else + if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) +#endif { - strError = strprintf("Error: Couldn't set properties on socket for incoming connections (ioctlsocket returned error %d)", WSAGetLastError()); + strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError()); printf("%s\n", strError.c_str()); return false; } @@ -1041,7 +1040,7 @@ bool StartNode(string& strError) // IP address, and port for the socket that is being bound int nRetryLimit = 15; struct sockaddr_in sockaddr = addrLocalHost.GetSockAddr(); - if (bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) + if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) { int nErr = WSAGetLastError(); if (nErr == WSAEADDRINUSE) @@ -1131,7 +1130,9 @@ bool StopNode() Sleep(50); // Sockets shutdown +#ifdef __WXMSW__ WSACleanup(); +#endif return true; } diff --git a/net.h b/net.h index 7716426f0..275a4cb88 100644 --- a/net.h +++ b/net.h @@ -22,7 +22,8 @@ enum bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); bool GetMyExternalIP(unsigned int& ipRet); -bool AddAddress(CAddrDB& addrdb, const CAddress& addr); +bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline=true); +void AddressCurrentlyConnected(const CAddress& addr); CNode* FindNode(unsigned int ip); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); diff --git a/ui.cpp b/ui.cpp index 9185b8159..212548199 100644 --- a/ui.cpp +++ b/ui.cpp @@ -260,7 +260,8 @@ void AddPendingReplyEvent3(void* pevthandler, CDataStream& vRecv) CDataStream GetStreamFromEvent(const wxCommandEvent& event) { wxString strData = event.GetString(); - return CDataStream(strData.begin(), strData.begin() + event.GetInt(), SER_NETWORK); + const char* pszBegin = strData.c_str(); + return CDataStream(pszBegin, pszBegin + event.GetInt(), SER_NETWORK); } @@ -288,20 +289,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) SetIcon(wxICON(bitcoin)); ptaskbaricon = new CMyTaskBarIcon(); - // Init toolbar with transparency masked bitmaps - m_toolBar->ClearTools(); - - //// shouldn't have to do mask separately anymore, bitmap alpha support added in wx 2.8.9, - wxBitmap bmpSend(wxT("send20"), wxBITMAP_TYPE_RESOURCE); - bmpSend.SetMask(new wxMask(wxBitmap(wxT("send20mask"), wxBITMAP_TYPE_RESOURCE))); - m_toolBar->AddTool(wxID_BUTTONSEND, wxT("&Send Coins"), bmpSend, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); - - wxBitmap bmpAddressBook(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE); - bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook20mask"), wxBITMAP_TYPE_RESOURCE))); - m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), bmpAddressBook, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); - - m_toolBar->Realize(); - // Init column headers int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) @@ -909,15 +896,17 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) { TRY_CRITICAL_BLOCK(cs_mapWallet) { - bool fInserted = false; + string strTop; + if (m_listCtrl->GetItemCount()) + strTop = (string)m_listCtrl->GetItemText(0); foreach(uint256 hash, vWalletUpdated) { map::iterator mi = mapWallet.find(hash); if (mi != mapWallet.end()) - fInserted |= InsertTransaction((*mi).second, false); + InsertTransaction((*mi).second, false); } vWalletUpdated.clear(); - if (fInserted) + if (m_listCtrl->GetItemCount() && strTop != (string)m_listCtrl->GetItemText(0)) m_listCtrl->ScrollList(0, INT_MAX); } } @@ -954,7 +943,9 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); +#ifdef __WXMSW__ m_listCtrl->OnPaint(event); +#endif } @@ -1407,7 +1398,7 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) m_checkBoxLimitProcessors->SetValue(fLimitProcessors); m_spinCtrlLimitProcessors->Enable(fLimitProcessors); m_spinCtrlLimitProcessors->SetValue(nLimitProcessors); - int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS")); + int nProcessors = wxThread::GetCPUCount(); if (nProcessors < 1) nProcessors = 999; m_spinCtrlLimitProcessors->SetRange(1, nProcessors); @@ -1549,17 +1540,11 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose); } - if (fUseProxy != m_checkBoxUseProxy->GetValue()) - { - fUseProxy = m_checkBoxUseProxy->GetValue(); - walletdb.WriteSetting("fUseProxy", fUseProxy); - } + fUseProxy = m_checkBoxUseProxy->GetValue(); + walletdb.WriteSetting("fUseProxy", fUseProxy); - if (addrProxy != GetProxyAddr()) - { - addrProxy = GetProxyAddr(); - walletdb.WriteSetting("addrProxy", addrProxy); - } + addrProxy = GetProxyAddr(); + walletdb.WriteSetting("addrProxy", addrProxy); } @@ -1608,10 +1593,8 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi //// todo: should add a display of your balance for convenience // Set Icon - wxBitmap bmpSend(wxT("send16"), wxBITMAP_TYPE_RESOURCE); - bmpSend.SetMask(new wxMask(wxBitmap(wxT("send16masknoshadow"), wxBITMAP_TYPE_RESOURCE))); wxIcon iconSend; - iconSend.CopyFromBitmap(bmpSend); + iconSend.CopyFromBitmap(wxBitmap(send16noshadow_xpm)); SetIcon(iconSend); wxCommandEvent event; @@ -2231,10 +2214,8 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit m_listCtrl->SetFocus(); // Set Icon - wxBitmap bmpAddressBook(wxT("addressbook16"), wxBITMAP_TYPE_RESOURCE); - bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook16mask"), wxBITMAP_TYPE_RESOURCE))); wxIcon iconAddressBook; - iconAddressBook.CopyFromBitmap(bmpAddressBook); + iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm)); SetIcon(iconAddressBook); // Fill listctrl with address book data @@ -3345,7 +3326,7 @@ bool CMyApp::OnInit2() _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); #endif -#ifdef __WXDEBUG__ +#if defined(__WXMSW__) && defined(__WXDEBUG__) // Disable malfunctioning wxWidgets debug assertion g_isPainting = 10000; #endif @@ -3362,8 +3343,7 @@ bool CMyApp::OnInit2() " -gen=0\t\t Don't generate coins\n" " -min\t\t Start minimized\n" " -datadir=\t Specify data directory\n" - " -proxy=\t Connect through socks4 proxy,\n" - " \t\t e.g. -proxy=127.0.0.1:9050 to use TOR\n" + " -proxy=\t Connect through socks4 proxy\n" " -addnode=\t Add a node to connect to\n" " -connect=\t Connect only to the specified node\n" " -?\t\t This help message\n"; @@ -3386,6 +3366,8 @@ bool CMyApp::OnInit2() unsigned int nStart = GetTime(); loop { + // TODO: find out how to do this in Linux, or replace with wxWidgets commands +#ifdef __WXMSW__ // Show the previous instance and exit HWND hwndPrev = FindWindow("wxWindowClassNR", "Bitcoin"); if (hwndPrev) @@ -3395,6 +3377,7 @@ bool CMyApp::OnInit2() SetForegroundWindow(hwndPrev); return false; } +#endif if (GetTime() > nStart + 60) return false; @@ -3421,7 +3404,7 @@ bool CMyApp::OnInit2() fPrintToDebugger = true; printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - printf("Bitcoin version %d, Windows version %08x\n", VERSION, GetVersion()); + printf("Bitcoin version %d, OS version %s\n", VERSION, wxGetOsDescription().mb_str()); if (mapArgs.count("-dropmessages")) { @@ -3493,12 +3476,36 @@ bool CMyApp::OnInit2() return false; } + if (mapArgs.count("-printblock")) + { + string strMatch = mapArgs["-printblock"]; + int nFound = 0; + for (map::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + { + uint256 hash = (*mi).first; + if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0) + { + CBlockIndex* pindex = (*mi).second; + CBlock block; + block.ReadFromDisk(pindex, true); + block.BuildMerkleTree(); + block.print(); + printf("\n"); + nFound++; + } + } + if (nFound == 0) + printf("No blocks matching %s were found\n", strMatch.c_str()); + OnExit(); + return false; + } + if (mapArgs.count("-gen")) { if (mapArgs["-gen"].empty()) fGenerateBitcoins = true; else - fGenerateBitcoins = atoi(mapArgs["-gen"].c_str()); + fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0); } if (mapArgs.count("-proxy")) @@ -3511,9 +3518,6 @@ bool CMyApp::OnInit2() OnExit(); return false; } - CWalletDB walletdb; - walletdb.WriteSetting("fUseProxy", fUseProxy); - walletdb.WriteSetting("addrProxy", addrProxy); } if (mapArgs.count("-addnode")) @@ -3522,6 +3526,7 @@ bool CMyApp::OnInit2() foreach(string strAddr, mapMultiArgs["-addnode"]) { CAddress addr(strAddr, NODE_NETWORK); + addr.nTime = 0; // so it won't relay unless successfully connected if (addr.IsValid()) AddAddress(addrdb, addr); } @@ -3559,7 +3564,11 @@ bool CMyApp::OnInit2() // // Tests // +#ifdef __WXMSW__ if (argc >= 2 && stricmp(argv[1], "-send") == 0) +#else + if (argc >= 2 && strcmp(argv[1], "-send") == 0) +#endif { int64 nValue = 1; if (argc >= 3) @@ -3646,7 +3655,8 @@ void CMyApp::OnFatalException() -typedef WINSHELLAPI BOOL WINAPI (*PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); +#ifdef __WXMSW__ +typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); string MyGetSpecialFolderPath(int nFolder, bool fCreate) { @@ -3737,7 +3747,10 @@ void SetStartOnSystemStartup(bool fAutoStart) CoUninitialize(); } } - +#else +bool GetStartOnSystemStartup() { return false; } +void SetStartOnSystemStartup(bool fAutoStart) { } +#endif diff --git a/uibase.cpp b/uibase.cpp index b03e578bd..bb564e996 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -7,6 +7,10 @@ #include "uibase.h" +#include "xpm/addressbook20.xpm" +#include "xpm/check.xpm" +#include "xpm/send20.xpm" + /////////////////////////////////////////////////////////////////////////// CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) @@ -60,8 +64,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_toolBar->SetToolSeparation( 1 ); m_toolBar->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - m_toolBar->AddTool( wxID_BUTTONSEND, wxT("&Send Coins"), wxBitmap( wxT("send20"), wxBITMAP_TYPE_RESOURCE ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); - m_toolBar->AddTool( wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap( wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->AddTool( wxID_BUTTONSEND, wxT("&Send Coins"), wxBitmap( send20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->AddTool( wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap( addressbook20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); m_toolBar->Realize(); m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); @@ -666,7 +670,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin bSizer47->Add( 0, 0, 1, wxEXPAND, 5 ); - m_bitmapCheckMark = new wxStaticBitmap( this, wxID_ANY, wxICON( check ), wxDefaultPosition, wxSize( 16,16 ), 0 ); + m_bitmapCheckMark = new wxStaticBitmap( this, wxID_ANY, wxBitmap( check_xpm ), wxDefaultPosition, wxSize( 16,16 ), 0 ); bSizer47->Add( m_bitmapCheckMark, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); m_staticText36 = new wxStaticText( this, wxID_ANY, wxT("Pay &To:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); diff --git a/uiproject.fbp b/uiproject.fbp index 313e5aa6c..7bce7349f 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -225,7 +225,7 @@ - + 20,20 @@ -273,7 +273,7 @@ - send20; Load From Resource + xpm/send20.xpm; Load From File wxID_BUTTONSEND wxITEM_NORMAL &Send Coins @@ -287,7 +287,7 @@ - addressbook20; Load From Resource + xpm/addressbook20.xpm; Load From File wxID_BUTTONRECEIVE wxITEM_NORMAL &Address Book @@ -1685,7 +1685,7 @@ - + @@ -3699,7 +3699,7 @@ 0 - check; Load From Icon Resource [-1; -1] + xpm/check.xpm; Load From File 1 diff --git a/util.cpp b/util.cpp index 23b59f11f..d2e624d67 100644 --- a/util.cpp +++ b/util.cpp @@ -38,8 +38,10 @@ public: ppmutexOpenSSL[i] = new wxMutex(); CRYPTO_set_locking_callback(locking_callback); +#ifdef __WXMSW__ // Seed random number generator with screen scrape and other hardware sources RAND_screen(); +#endif // Seed random number generator with performance counter RandAddSeed(); @@ -325,8 +327,8 @@ void ParseParameters(int argc, char* argv[]) pszValue = strchr(psz, '='); *pszValue++ = '\0'; } - strlwr(psz); #ifdef __WXMSW__ + _strlwr(psz); if (psz[0] == '/') psz[0] = '-'; #endif @@ -343,9 +345,13 @@ void ParseParameters(int argc, char* argv[]) void FormatException(char* pszMessage, std::exception* pex, const char* pszThread) { +#ifdef __WXMSW__ char pszModule[MAX_PATH]; pszModule[0] = '\0'; GetModuleFileName(NULL, pszModule, sizeof(pszModule)); +#else + const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str(); +#endif if (pex) snprintf(pszMessage, 1000, "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); diff --git a/util.h b/util.h index 822a049ce..3bc7c798a 100644 --- a/util.h +++ b/util.h @@ -55,9 +55,34 @@ inline T& REF(const T& val) } #ifndef __WXMSW__ -#define closesocket(s) close(s) -#define INVALID_SOCKET (SOCKET)(~0) +#define _UI64_MAX UINT64_MAX +#define _I64_MAX INT64_MAX +#define WSAGetLastError() errno +#define WSAEWOULDBLOCK EWOULDBLOCK +#define WSAEMSGSIZE EMSGSIZE +#define WSAEINTR EINTR +#define WSAEINPROGRESS EINPROGRESS +#define WSAEADDRINUSE EADDRINUSE +#define closesocket(s) close(s) +#define INVALID_SOCKET (SOCKET)(~0) +#define SOCKET_ERROR -1 typedef u_int SOCKET; +#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d) +#define strlwr(psz) to_lower(psz) +#define _strlwr(psz) to_lower(psz) +#define _mkdir(psz) filesystem::create_directory(psz) +#define MAX_PATH 1024 +#define Sleep(n) wxMilliSleep(n) +#define Beep(n1,n2) (0) +inline int _beginthread(void(*pfn)(void*), unsigned nStack, void* parg) { thread(bind(pfn, parg)); return 0; } +inline void _endthread() { pthread_exit(NULL); } +inline int GetCurrentThread() { return 0; } +// threads are processes on linux, so setpriority affects just the one thread +inline void SetThreadPriority(int nThread, int nPriority) { setpriority(PRIO_PROCESS, getpid(), nPriority); } +#define THREAD_PRIORITY_LOWEST PRIO_MIN +#define THREAD_PRIORITY_BELOW_NORMAL 2 +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_ABOVE_NORMAL 0 #endif @@ -120,7 +145,7 @@ public: protected: wxMutex mutex; public: - explicit CCriticalSection() { } + explicit CCriticalSection() : mutex(wxMUTEX_RECURSIVE) { } ~CCriticalSection() { } void Enter() { mutex.Lock(); } void Leave() { mutex.Unlock(); } @@ -183,7 +208,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...) // print to debug.log char pszFile[MAX_PATH+100]; GetDataDir(pszFile); - strlcat(pszFile, "\\debug.log", sizeof(pszFile)); + strlcat(pszFile, "/debug.log", sizeof(pszFile)); FILE* fileout = fopen(pszFile, "a"); if (fileout) { @@ -354,13 +379,6 @@ inline int64 GetTimeMillis() return wxGetLocalTimeMillis().GetValue(); } -#ifndef __WXMSW__ -inline void Sleep(unsigned int nMilliseconds) -{ - wxMilliSleep(nMilliseconds); -} -#endif - diff --git a/xpm/addressbook16.xpm b/xpm/addressbook16.xpm new file mode 100644 index 000000000..471f700c7 --- /dev/null +++ b/xpm/addressbook16.xpm @@ -0,0 +1,278 @@ +/* XPM */ +static char * addressbook16_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 16 256 2", +" c #FFFFFF", +". c #F7FFFF", +"X c #F7F7FF", +"o c #EFF7FF", +"O c #E6EFF7", +"+ c #E6E6F7", +"@ c #CEE6F7", +"# c #DEDEEF", +"$ c #D6DEEF", +"% c #D6DEE6", +"& c #CEDEF7", +"* c #CEDEEF", +"= c #EFF708", +"- c #C5DEF7", +"; c #CED6EF", +": c None", +"> c #C5D6E6", +", c #BDD6F7", +"< c #BDD6EF", +"1 c #D6CECE", +"2 c #BDCEE6", +"3 c #BDC5E6", +"4 c #B5C5DE", +"5 c #BDD631", +"6 c #ADBDDE", +"7 c #B5B5BD", +"8 c #A5B5D6", +"9 c #00FFFF", +"0 c #9CB5CE", +"q c #9CADD6", +"w c #94A5D6", +"e c #8CA5D6", +"r c #8CA5CE", +"t c #8CA5C5", +"y c #849CC5", +"u c #7B9CD6", +"i c #7B9CCE", +"p c #31BDCE", +"a c #6B9CD6", +"s c #00F708", +"d c #8494AD", +"f c #7B94B5", +"g c #6B94D6", +"h c #6B9C84", +"j c #7B8CAD", +"k c #738CAD", +"l c #638CC5", +"z c #10CE42", +"x c #638CBD", +"c c #7B849C", +"v c #73849C", +"b c #6B84A5", +"n c #7B7BA5", +"m c #6B849C", +"M c #7B8C42", +"N c #5A84C5", +"B c #29AD6B", +"V c #F74A4A", +"C c #6384A5", +"Z c #5284C5", +"A c #637BA5", +"S c #637B9C", +"D c #9C637B", +"F c #6B7B5A", +"G c #637394", +"H c #52739C", +"J c #5A7384", +"K c #526B94", +"L c #426B94", +"P c #52638C", +"I c #426B7B", +"U c #5A5A8C", +"Y c #524A7B", +"T c #425273", +"R c #21636B", +"E c #106394", +"W c #106B52", +"Q c #3A4273", +"! c #31426B", +"~ c #523163", +"^ c #29426B", +"/ c #293A63", +"( c #213A63", +") c #193A63", +"_ c #193163", +"` c #19315A", +"' c #212963", +"] c #10315A", +"[ c #082952", +"{ c #FFCC33", +"} c #33FF33", +"| c #66FF33", +" . c #99FF33", +".. c #CCFF33", +"X. c #FFFF33", +"o. c #000066", +"O. c #330066", +"+. c #660066", +"@. c #990066", +"#. c #CC0066", +"$. c #FF0066", +"%. c #003366", +"&. c #333366", +"*. c #663366", +"=. c #993366", +"-. c #CC3366", +";. c #FF3366", +":. c #006666", +">. c #336666", +",. c #666666", +"<. c #996666", +"1. c #CC6666", +"2. c #009966", +"3. c #339966", +"4. c #669966", +"5. c #999966", +"6. c #CC9966", +"7. c #FF9966", +"8. c #00CC66", +"9. c #33CC66", +"0. c #99CC66", +"q. c #CCCC66", +"w. c #FFCC66", +"e. c #00FF66", +"r. c #33FF66", +"t. c #99FF66", +"y. c #CCFF66", +"u. c #FF00CC", +"i. c #CC00FF", +"p. c #009999", +"a. c #993399", +"s. c #990099", +"d. c #CC0099", +"f. c #000099", +"g. c #333399", +"h. c #660099", +"j. c #CC3399", +"k. c #FF0099", +"l. c #006699", +"z. c #336699", +"x. c #663399", +"c. c #996699", +"v. c #CC6699", +"b. c #FF3399", +"n. c #339999", +"m. c #669999", +"M. c #999999", +"N. c #CC9999", +"B. c #FF9999", +"V. c #00CC99", +"C. c #33CC99", +"Z. c #66CC66", +"A. c #99CC99", +"S. c #CCCC99", +"D. c #FFCC99", +"F. c #00FF99", +"G. c #33FF99", +"H. c #66CC99", +"J. c #99FF99", +"K. c #CCFF99", +"L. c #FFFF99", +"P. c #0000CC", +"I. c #330099", +"U. c #6600CC", +"Y. c #9900CC", +"T. c #CC00CC", +"R. c #003399", +"E. c #3333CC", +"W. c #6633CC", +"Q. c #9933CC", +"!. c #CC33CC", +"~. c #FF33CC", +"^. c #0066CC", +"/. c #3366CC", +"(. c #666699", +"). c #9966CC", +"_. c #CC66CC", +"`. c #FF6699", +"'. c #0099CC", +"]. c #3399CC", +"[. c #6699CC", +"{. c #9999CC", +"}. c #CC99CC", +"|. c #FF99CC", +" X c #00CCCC", +".X c #33CCCC", +"XX c #66CCCC", +"oX c #99CCCC", +"OX c #CCCCCC", +"+X c #FFCCCC", +"@X c #00FFCC", +"#X c #33FFCC", +"$X c #66FF99", +"%X c #99FFCC", +"&X c #CCFFCC", +"*X c #FFFFCC", +"=X c #3300CC", +"-X c #6600FF", +";X c #9900FF", +":X c #0033CC", +">X c #3333FF", +",X c #6633FF", +" g , S z R : ", +"n * c * r r y g , 6 r q S s W : ", +"n * c X 4 N u + m B I : ", +"n * c X ; a - S 5 F : ", +"n * c * r r r g - S = M : ", +"n * c X 4 N - m h J : ", +"n * c X ; a - A 9 E : ", +"n * ( ] ` ^ P l y T / / ( p L : ", +"n O > 0 f ) ! t 8 % n : ", +"U U U U U U U ' Q U U U U U U : ", +": : : : : : : : : : : : : : : : " +}; diff --git a/xpm/addressbook20.xpm b/xpm/addressbook20.xpm new file mode 100644 index 000000000..48df12d80 --- /dev/null +++ b/xpm/addressbook20.xpm @@ -0,0 +1,282 @@ +/* XPM */ +static char * addressbook20_xpm[] = { +/* columns rows colors chars-per-pixel */ +"20 20 256 2", +" c #FFFFFF", +". c #F7FFFF", +"X c #F7F7FF", +"o c #EFF7FF", +"O c #EFF7F7", +"+ c #E6EFFF", +"@ c #E6EFF7", +"# c #DEEFFF", +"$ c #DEE6F7", +"% c #DEE6EF", +"& c #D6E6F7", +"* c #FFFF00", +"= c #DEDEE6", +"- c #D6DEE6", +"; c #D6D6DE", +": c #CED6E6", +"> c None", +", c #C5D6E6", +"< c #C5CEE6", +"1 c #B5CEEF", +"2 c #C5C5C5", +"3 c #C5DE31", +"4 c #B5C5DE", +"5 c #BDC5C5", +"6 c #ADC5EF", +"7 c #B5C5CE", +"8 c #BDBDBD", +"9 c #B5BDCE", +"0 c #ADBDDE", +"q c #ADBDD6", +"w c #B5CE52", +"e c #ADB5C5", +"r c #00FFFF", +"t c #A5B5C5", +"y c #9CB5CE", +"u c #94B5DE", +"i c #9CADD6", +"p c #A5ADB5", +"a c #94ADDE", +"s c #94ADD6", +"d c #9CADBD", +"f c #8CADDE", +"g c #BD9CA5", +"h c #9CA5BD", +"j c #9CA5B5", +"k c #29D6E6", +"l c #8CA5CE", +"z c #849CCE", +"x c #6BA5C5", +"c c #739CDE", +"v c #00FF00", +"b c #739CD6", +"n c #7B94CE", +"m c #8494AD", +"M c #7394CE", +"N c #7B94B5", +"B c #4AB584", +"V c #848CB5", +"C c #6B94CE", +"Z c #6394D6", +"A c #6394CE", +"S c #7B8CAD", +"D c #6B8CC5", +"F c #738CAD", +"G c #5294B5", +"H c #6B84C5", +"J c #7384A5", +"K c #73849C", +"L c #738494", +"P c #FF4A4A", +"I c #FF4A42", +"U c #737B8C", +"Y c #637BAD", +"T c #527BBD", +"R c #637394", +"E c #637352", +"W c #5A6B8C", +"Q c #526B9C", +"! c #63638C", +"~ c #5A734A", +"^ c #4A6B9C", +"/ c #526B63", +"( c #0884A5", +") c #526384", +"_ c #52637B", +"` c #4A6B5A", +"' c #52636B", +"] c #525A8C", +"[ c #525A7B", +"{ c #426363", +"} c #4A5A7B", +"| c #425A8C", +" . c #196B94", +".. c #3A5A8C", +"X. c #3A5A84", +"o. c #087B4A", +"O. c #21636B", +"+. c #634263", +"@. c #3A527B", +"#. c #424A84", +"$. c #315284", +"%. c #295284", +"&. c #3A4A6B", +"*. c #42427B", +"=. c #424273", +"-. c #294A84", +";. c #3A3A73", +":. c #194284", +">. c #104A63", +",. c #213A6B", +"<. c #31316B", +"1. c #21315A", +"2. c #212163", +"3. c #08295A", +"4. c #082152", +"5. c #101952", +"6. c #CC9966", +"7. c #FF9966", +"8. c #00CC66", +"9. c #33CC66", +"0. c #99CC66", +"q. c #CCCC66", +"w. c #FFCC66", +"e. c #00FF66", +"r. c #33FF66", +"t. c #99FF66", +"y. c #CCFF66", +"u. c #FF00CC", +"i. c #CC00FF", +"p. c #009999", +"a. c #993399", +"s. c #990099", +"d. c #CC0099", +"f. c #000099", +"g. c #333399", +"h. c #660099", +"j. c #CC3399", +"k. c #FF0099", +"l. c #006699", +"z. c #336699", +"x. c #663399", +"c. c #996699", +"v. c #CC6699", +"b. c #FF3399", +"n. c #339999", +"m. c #669999", +"M. c #999999", +"N. c #CC9999", +"B. c #FF9999", +"V. c #00CC99", +"C. c #33CC99", +"Z. c #66CC66", +"A. c #99CC99", +"S. c #CCCC99", +"D. c #FFCC99", +"F. c #00FF99", +"G. c #33FF99", +"H. c #66CC99", +"J. c #99FF99", +"K. c #CCFF99", +"L. c #FFFF99", +"P. c #0000CC", +"I. c #330099", +"U. c #6600CC", +"Y. c #9900CC", +"T. c #CC00CC", +"R. c #003399", +"E. c #3333CC", +"W. c #6633CC", +"Q. c #9933CC", +"!. c #CC33CC", +"~. c #FF33CC", +"^. c #0066CC", +"/. c #3366CC", +"(. c #666699", +"). c #9966CC", +"_. c #CC66CC", +"`. c #FF6699", +"'. c #0099CC", +"]. c #3399CC", +"[. c #6699CC", +"{. c #9999CC", +"}. c #CC99CC", +"|. c #FF99CC", +" X c #00CCCC", +".X c #33CCCC", +"XX c #66CCCC", +"oX c #99CCCC", +"OX c #CCCCCC", +"+X c #FFCCCC", +"@X c #00FFCC", +"#X c #33FFCC", +"$X c #66FF99", +"%X c #99FFCC", +"&X c #CCFFCC", +"*X c #FFFFCC", +"=X c #3300CC", +"-X c #6600FF", +";X c #9900FF", +":X c #0033CC", +">X c #3333FF", +",X c #6633FF", +" > > > > > > > > > > > > > > > > > > > ", +"> > > > > > > > > > > > > > > > > > > > ", +"> > U $.| | ^ S 2 > p W | | @.L > > > > ", +"8 5 R - < Y j S O - ) g e > > ", +"! V K - % a Q # - +.P <.> > ", +"! & K - 0 z n D C b f n n z q +.P <.> > ", +"! & K - % M A 1 - %.G #.> > ", +"! & K - % u b # - o.v >.> > ", +"! & K - 0 z n H M b 6 z n z q o.v >.> > ", +"! & K - X - M A a - O.B @.> > ", +"! & K - X % u b # - ` 3 / > > ", +"! & K - 0 l i 4 u b # - ~ * E > > ", +"! & K - X o $ s T b # - { w ' > > ", +"! & K - % f b # - .k -.> > ", +"! & K m d t 7 , u b # ; 9 9 h ( r :.> > ", +"! & h _ _ [ &.4.$.A ,.1.} _ _ F x ] > > ", +"! @ , y N _ 3._ N y , @ ! > > ", +"*.*.*.*.*.*.*.*.;.5.*.*.*.*.*.*.*.2.> > ", +"> > > > > > > > > > > > > > > > > > > > ", +"> > > > > > > > > > > > > > > > > > > > " +}; diff --git a/xpm/bitcoin.xpm b/xpm/bitcoin.xpm new file mode 100644 index 000000000..166d5aa6e --- /dev/null +++ b/xpm/bitcoin.xpm @@ -0,0 +1,304 @@ +/* XPM */ +static char * bitcoin_xpm[] = { +/* columns rows colors chars-per-pixel */ +"48 48 250 2", +" c #725203", +". c #795603", +"X c #7D5903", +"o c #76560B", +"O c #77590E", +"+ c #795A0D", +"@ c #7B5D14", +"# c #7C5F18", +"$ c #7D6019", +"% c #825D05", +"& c #856007", +"* c #86620B", +"= c #8B660B", +"- c #8E690E", +"; c #906A0F", +": c #8F6B17", +"> c #83641C", +", c #8D6C1E", +"< c #926C11", +"1 c #967014", +"2 c #997215", +"3 c #9C761B", +"4 c #9E791D", +"5 c #A37C1E", +"6 c #816520", +"7 c #876A25", +"8 c #8E6E22", +"9 c #866A29", +"0 c #896E2C", +"q c #8E7020", +"w c #937324", +"e c #997722", +"r c #9E7B25", +"t c #94762B", +"y c #967828", +"u c #9A7B2D", +"i c #8B7131", +"p c #9E7E31", +"a c #947839", +"s c #A37D22", +"d c #A68125", +"f c #AA8325", +"g c #AE8827", +"h c #A6832D", +"j c #AA852B", +"k c #AD892B", +"l c #B08727", +"z c #B28827", +"x c #B08729", +"c c #B38B2C", +"v c #B88E2F", +"b c #B8902D", +"n c #A38334", +"m c #A98632", +"M c #AB8A34", +"N c #A4873C", +"B c #A78A3D", +"V c #AC8B3C", +"C c #B38D32", +"Z c #BA8F30", +"A c #B28E3C", +"S c #B69332", +"D c #BC9433", +"F c #BF9832", +"G c #B4923C", +"H c #BA963D", +"J c #B7993E", +"K c #BE9A3B", +"L c #C1932F", +"P c #C39732", +"I c #C49935", +"U c #C59C3A", +"Y c #C99E3D", +"T c #C2A13F", +"R c #CDA23F", +"E c #9D8342", +"W c #AB8C43", +"Q c #B28E40", +"! c #AE9144", +"~ c #AE914A", +"^ c #B49445", +"/ c #BC9B44", +"( c #B3964D", +") c #B5994C", +"_ c #BD9B4A", +"` c #A98F50", +"' c #B19553", +"] c #B59A54", +"[ c #BD9F51", +"{ c #B59B5C", +"} c #B89D5C", +"| c #BEA155", +" . c #BDA35D", +".. c #B59C61", +"X. c #B99F66", +"o. c #BCA363", +"O. c #BDA56C", +"+. c #BCA571", +"@. c #BDA873", +"#. c #BFAA78", +"$. c #C49D43", +"%. c #C99F45", +"&. c #C29E4B", +"*. c #C5A144", +"=. c #CCA244", +"-. c #C5A44B", +";. c #CAA54B", +":. c #C8A84C", +">. c #D0A644", +",. c #D3AA44", +"<. c #D3AC4C", +"1. c #D8AD4D", +"2. c #DAB046", +"3. c #DCB24E", +"4. c #C3A454", +"5. c #CBA751", +"6. c #CCAA53", +"7. c #C1A65B", +"8. c #C8A75A", +"9. c #CBAC5B", +"0. c #D0A650", +"q. c #D2AC53", +"w. c #DAAD54", +"e. c #D3AD5C", +"r. c #CFB259", +"t. c #D4B156", +"y. c #DDB454", +"u. c #D4B25C", +"i. c #DAB65A", +"p. c #D7B95F", +"a. c #DEBA5E", +"s. c #E2B555", +"d. c #E5BA53", +"f. c #E1B55A", +"g. c #E5BC5C", +"h. c #EABF5D", +"j. c #C1A761", +"k. c #C4AA63", +"l. c #CBAE63", +"z. c #CBB166", +"x. c #CBB26C", +"c. c #D4B263", +"v. c #DAB462", +"b. c #D6B864", +"n. c #DCB965", +"m. c #D3B669", +"M. c #DCB768", +"N. c #D4BA6E", +"B. c #DCBB6C", +"V. c #CDB672", +"C. c #D2B972", +"Z. c #DBBE72", +"A. c #E4BC62", +"S. c #E9BE62", +"D. c #E2BD6C", +"F. c #E0BF72", +"G. c #E6C05E", +"H. c #EFC05D", +"J. c #F0C15B", +"K. c #DFC167", +"L. c #D7C069", +"P. c #DDC36D", +"I. c #DBC376", +"U. c #D4C17B", +"Y. c #DAC17B", +"T. c #D8C878", +"R. c #E4C362", +"E. c #EBC364", +"W. c #E3C865", +"Q. c #EDC866", +"!. c #E4C36A", +"~. c #E9C66B", +"^. c #ECCA6B", +"/. c #F1C564", +"(. c #F8C765", +"). c #F5CB66", +"_. c #F8CC67", +"`. c #F6CC6A", +"'. c #F9CD6B", +"]. c #EED26A", +"[. c #F2D06F", +"{. c #FBD26D", +"}. c #E4C374", +"|. c #EBC474", +" X c #E1C972", +".X c #EDCD72", +"XX c #E4C57A", +"oX c #E9C67C", +"OX c #E5C87C", +"+X c #EACA7D", +"@X c #F2CC74", +"#X c #FBCF71", +"$X c #EED174", +"%X c #ECD37B", +"&X c #F4D274", +"*X c #FDD473", +"=X c #FFD975", +"-X c #F4D57C", +";X c #FCD57A", +":X c #F3DA7C", +">X c #FEDB7C", +",X c #FFE37D", +"X=XQ.s.=.v 5 1 < E HXHXHXHXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHX' g f F d.).).{.{.=X=X=X{.{.{.`.`.`.).g.U f 2 * a HXHXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXV f b G.J.{.{.{.*X=X,X=X*X{.`.).`.).).{.`.{./.U 5 ; + HXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHX} h g 1.)._._.{.,X*X=X,X{.{.)._.).).`.`.`.{.*X*X*X`.y.g 2 & $ HXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHX{ j c G.).{.{.{.=X,X{.{.J.d.2.R 2.,.3.g.`.&X;X;X;X&X[.{.`.I 3 & + HXHXHXHXHXHXHXHX", +"HXHXHXHXHXHX{ d D /.{.{.*X=X=X*X).3.R I I I P F F U $.;.n.-XrXrX;X&X;X>XdX:.4 X o HXHXHXHXHXHXHX", +"HXHXHXHXHX..j v /.*X=X=X=X=X`.1.R R R R I I I P K U *.e.D.|.}.+XrXqXhXhXdXfX:.4 X o HXHXHXHXHXHX", +"HXHXHXHXHXh v `.{.>X,X*X{.g.>.Y R I I I I I I U U ;.t.D.|.oXB.z.F.kXvXcXjXjXjX/ 1 . + HXHXHXHXHX", +"HXHXHXHXV g Q.=X=X>X>X'.>.Y Y U R I I I P P I U U <.n.~.}.F.XXXX}.%XbXbXcXcXcXsXc = # HXHXHXHX", +"HXHXHX} j t.>X>X>X*X'.>.U U I U P U U I P P I U T 6.M.D.oX5XwXeXeXqX0XvXbXbXcXjXW.5 % HXHXHXHX", +"HXHXHXM G hXhXqX>X*X<.U U U I I I I I I D D U T T -.9.B.3XpXpXzXgXqX:X:XbXbXcXjXfXT < o HXHXHX", +"HXHX} k XlXkXkXrXA.$.D Z Z Z v v v b b v D U U *.-.9.B.OX2XOXI.P.L.K.W.$XbXcXjX,X].d % 9 HXHX", +"HXHXV J xXxXxXxXrX5.&.A M m m m h h n s 5 g S K *.:.8.4.| k.x.C.N.z.7.) :.$XjXfX,X,XT ; o HXHX", +"HXHXM L.vXxXxXxXF._ MXCXCXCXCXCXCXCXCXmXY.h g K *./ ^ Y.mXCXCXCXCXCXCXVXZ.4.hXfX,X,XW.4 X HXHX", +"HX] k gXxXxXxXgXe.V MXCXCXCXCXVXCXCXCXCXCXyXh D G [ mXCXCXCXCXCXCXCXCXCX4XG ~.fX,X,X,Xg & $ HX", +"HXV J vXxXxXxX6Xe.V MXCXCXCXCXk.N VXCXCXCXVX| h ^ MXCXCXCXCXuX( n V l.mX4XA y.fX,X,X=XT ; HX", +"HXk r.xXxXxXxX|.v.V MXCXCXCXCXo.> 4XCXCXCXCXx.w tXCXCXCXCXnXn V / / M V m.&.t.=X,X,X=Xy.2 o HX", +"HXk P.xXvXxXxX|.M.Q nXCXCXCXCXj.w X>X=XH.5 X $ ", +"o.k %XvXbXBXkX|.D.Q nXCXCXCXCXj., 7XCXCXCXCX~ k.CXCXCXCXCXV &.n.R.g.G.g.S.S.S.(.qX*X=X`.5 X $ ", +" .k 0XvXvXvXrX@XD.^ VXCXCXCXCXx.~ VXCXCXCXX=X*X*Xd X $ ", +"{ k sXcXvXBXeX@XD.( nXCXCXCXCXCXCXCXCXVXo., u T.CXCXCXVXmXn t.E.g.g.h.S.g.S.f.A.>X;X*X*Xf & o ", +"{ k sXjXlXcX0X~.n.^ MXCXCXCXCXCXCXCXCXCXCXU.t U.CXCXCXCXmXM p.~.W.g.s.s.s.s.f.A.>X*X*X*Xj % ", +"o.k :XjXlXlX-XD.v.A MXCXCXCXCXj.t mXCXCXCXCX .x.CXCXCXCXVXV p.$X^.E.g.s.w.w.w.A.9X;X*X*Xf X ", +"o.g ].dXjXhX-Xn.e.V MXCXCXCXCXj.8 X*X#X5 X O ", +"HXj K.dXdXhX9Xv.9.M MXCXCXCXCXk.a Z.CXCXCXCX7Xu CXCXCXCXCXV./ !.$X~.f.5.%.0.q.S.>X*X*XE.5 X # ", +"HXj t.dX,XdXdXi.6.N MXCXCXCXCXo.q XqXqXqX!.6.m MXCXCXCXCXV.' VXCXCXZXCXk.! ] VXCXCXCXCXVXC.[ 7.Z.VX2Xx %.#X#X'.'.%.- o 6 ", +"HX( g &X>X>XdX-X5.M MXCXCXCXCXCXCXCXCXCXCX7X) m.9. .MXCXCXCXCXCXCXCXCXCX2Xs 1.'.`.'.'.x % HX", +"HXO.j y.>X>X>X>X6.! zXMXMXMXMXMXMXMXMXuXx.( N.8X6Xz.) C.uXCXCXCXCXCXVX7X4.c h.'.(.(.s.5 X HX", +"HXHXj H &X=X:X>X~./ V h y u n n n N W ( 7.Z.8XpXpX+Xm.| V V ^ ) ( m e 3 s R (.(.'.'.Y ; . > HX", +"HXHX} f G.&X&X&X:Xt._ / ) _ 4.8.l.m.B.Z.2XwXpXeXwX6X+XP.c.8.-./ C x x z P J.(.'.(./.5 % HXHX", +"HXHXHXh D &X&X&X&X@X:.4.5.9.c.m.F.OX+XwXwXwXwX6X3XOX}.D.D.v.w.%.Y I P P d.(.(.'.'.=.< . + HXHX", +"HXHXHX] d y.[.&X&X&X~.:.4.9.e.M.B.}.oX3X5X3X3X+X}.F.M.e.0.0.0.%.%.Y Y s.#X#X#X#XS.s % HXHXHX", +"HXHXHXHXm g `.@X&X&X&X~.5.6.e.b.B.}.XX+X3XOX}.I.F.F.D.e.e.e.e.e.q.0.A.;X;X#X-X@XZ = o + HXHXHX", +"HXHXHXHX..j D @X&X&X&X&X@Xp.u.M.D.}.XXOXOXZ.Z.XX1XOXoXoXF.F.F.M.D.6XrXqX9X9X9X%.1 . HXHXHXHX", +"HXHXHXHXHX' f $.&X&X&X>XqXqX XB.D.!.XXXXZ.XXOX5XwXwXwXwXiXwXwXnXVXZXBXxXzXxXb.r X $ HXHXHXHX", +"HXHXHXHXHXHX~ j ;.qXqXqXqXrXkXrX+XD.Z.Z.XX1X2X5X5X5XwXwXiXnXCXGXGXFXFXSXAXT.s % @ HXHXHXHXHX", +"HXHXHXHXHXHXHX~ j -.0XrXzXxXzXzXzXzXwX3XXXXXOX1X2X5XpXmXAXFXGXGXGXFXFXSXL.r % O HXHXHXHXHXHX", +"HXHXHXHXHXHXHXHX! j / gXSXSXZXxXzXzXkXxXzXBXBXBXZXCXAXAXAXAXSXSXSXSXNX| 3 & O HXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHX} n V U.DXSXBXzXkXkXkXxXxXxXBXxXBXBXCXZXZXZXAXAXU.M < . @ HXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXV d G Z.pXzXkXzXjXkXkXxXzXxXxXxXBXBXZXNXT.G 3 * . 9 HXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXHX@.u s k -.K.6XhXjXhXkXlXzXzXzXeXOX9.k 3 = X O HXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXHXHXHX..w < s j k K -.;.:.-./ C j 4 < & . O HXHXHXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXE * = - - < < - = & X . 0 HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXi 7 7 @ o o O > 0 i HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX" +}; diff --git a/xpm/check.xpm b/xpm/check.xpm new file mode 100644 index 000000000..8f0b9d28e --- /dev/null +++ b/xpm/check.xpm @@ -0,0 +1,41 @@ +/* XPM */ +static char * check_xpm[] = { +/* columns rows colors chars-per-pixel */ +"32 32 3 1", +" c #008000", +". c #00FF00", +"X c None", +/* pixels */ +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXX XXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXX . XXXXXXXXXXX", +"XXXXXXXXXXXXXXXX .. XXXXXXXXXXXX", +"XXXXXXXXXXXXXXXX . XXXXXXXXXXXX", +"XXXXXXXXXXXXXXX .. XXXXXXXXXXXXX", +"XXXXXXXXXXX XX . XXXXXXXXXXXXX", +"XXXXXXXXXXX . .. XXXXXXXXXXXXXX", +"XXXXXXXXXXX .. . XXXXXXXXXXXXXX", +"XXXXXXXXXXXX ... XXXXXXXXXXXXXXX", +"XXXXXXXXXXXXX . XXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXX XXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +}; diff --git a/xpm/send16.xpm b/xpm/send16.xpm new file mode 100644 index 000000000..1eeceb4ec --- /dev/null +++ b/xpm/send16.xpm @@ -0,0 +1,278 @@ +/* XPM */ +static char * send16_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 16 256 2", +" c #ADF7AD", +". c #9CFF9C", +"X c None", +"o c #ADEFAD", +"O c #94FF94", +"+ c #D6CECE", +"@ c #8CFF8C", +"# c #CECECE", +"$ c #CECEC5", +"% c #84FF84", +"& c #CEC5C5", +"* c #73FF73", +"= c #C5C5C5", +"- c #6BFF6B", +"; c #73F773", +": c #C5BDBD", +"> c #6BF76B", +", c #BDBDBD", +"< c #63F763", +"1 c #B5B5B5", +"2 c #52F752", +"3 c #42FF42", +"4 c #3AFF3A", +"5 c #ADADAD", +"6 c #ADADA5", +"7 c #4AEF4A", +"8 c #29FF29", +"9 c #A5A5A5", +"0 c #42E642", +"q c #9CA59C", +"w c #3AE63A", +"e c #10FF10", +"r c #08FF08", +"t c #949C94", +"y c #00FF00", +"u c #00F700", +"i c #8C948C", +"p c #00EF00", +"a c #08E608", +"s c #10DE10", +"d c #00E600", +"f c #00DE00", +"g c #19C519", +"h c #00CE00", +"j c #00C500", +"k c #008C00", +"l c #008400", +"z c #669900", +"x c #999900", +"c c #CC9900", +"v c #FF9900", +"b c #00CC00", +"n c #33CC00", +"m c #66CC00", +"M c #99CC00", +"N c #CCCC00", +"B c #FFCC00", +"V c #66FF00", +"C c #99FF00", +"Z c #CCFF00", +"A c #000033", +"S c #330033", +"D c #660033", +"F c #990033", +"G c #CC0033", +"H c #FF0033", +"J c #003333", +"K c #333333", +"L c #663333", +"P c #993333", +"I c #CC3333", +"U c #FF3333", +"Y c #006633", +"T c #336633", +"R c #666633", +"E c #996633", +"W c #CC6633", +"Q c #FF6633", +"! c #009933", +"~ c #339933", +"^ c #669933", +"/ c #999933", +"( c #CC9933", +") c #FF9933", +"_ c #00CC33", +"` c #33CC33", +"' c #66CC33", +"] c #99CC33", +"[ c #CCCC33", +"{ c #FFCC33", +"} c #33FF33", +"| c #66FF33", +" . c #99FF33", +".. c #CCFF33", +"X. c #FFFF33", +"o. c #000066", +"O. c #330066", +"+. c #660066", +"@. c #990066", +"#. c #CC0066", +"$. c #FF0066", +"%. c #003366", +"&. c #333366", +"*. c #663366", +"=. c #993366", +"-. c #CC3366", +";. c #FF3366", +":. c #006666", +">. c #336666", +",. c #666666", +"<. c #996666", +"1. c #CC6666", +"2. c #009966", +"3. c #339966", +"4. c #669966", +"5. c #999966", +"6. c #CC9966", +"7. c #FF9966", +"8. c #00CC66", +"9. c #33CC66", +"0. c #99CC66", +"q. c #CCCC66", +"w. c #FFCC66", +"e. c #00FF66", +"r. c #33FF66", +"t. c #99FF66", +"y. c #CCFF66", +"u. c #FF00CC", +"i. c #CC00FF", +"p. c #009999", +"a. c #993399", +"s. c #990099", +"d. c #CC0099", +"f. c #000099", +"g. c #333399", +"h. c #660099", +"j. c #CC3399", +"k. c #FF0099", +"l. c #006699", +"z. c #336699", +"x. c #663399", +"c. c #996699", +"v. c #CC6699", +"b. c #FF3399", +"n. c #339999", +"m. c #669999", +"M. c #999999", +"N. c #CC9999", +"B. c #FF9999", +"V. c #00CC99", +"C. c #33CC99", +"Z. c #66CC66", +"A. c #99CC99", +"S. c #CCCC99", +"D. c #FFCC99", +"F. c #00FF99", +"G. c #33FF99", +"H. c #66CC99", +"J. c #99FF99", +"K. c #CCFF99", +"L. c #FFFF99", +"P. c #0000CC", +"I. c #330099", +"U. c #6600CC", +"Y. c #9900CC", +"T. c #CC00CC", +"R. c #003399", +"E. c #3333CC", +"W. c #6633CC", +"Q. c #9933CC", +"!. c #CC33CC", +"~. c #FF33CC", +"^. c #0066CC", +"/. c #3366CC", +"(. c #666699", +"). c #9966CC", +"_. c #CC66CC", +"`. c #FF6699", +"'. c #0099CC", +"]. c #3399CC", +"[. c #6699CC", +"{. c #9999CC", +"}. c #CC99CC", +"|. c #FF99CC", +" X c #00CCCC", +".X c #33CCCC", +"XX c #66CCCC", +"oX c #99CCCC", +"OX c #CCCCCC", +"+X c #FFCCCC", +"@X c #00FFCC", +"#X c #33FFCC", +"$X c #66FF99", +"%X c #99FFCC", +"&X c #CCFFCC", +"*X c #FFFFCC", +"=X c #3300CC", +"-X c #6600FF", +";X c #9900FF", +":X c #0033CC", +">X c #3333FF", +",X c #6633FF", +" c #6BF76B", +", c #BDBDBD", +"< c #63F763", +"1 c #B5B5B5", +"2 c #52F752", +"3 c #42FF42", +"4 c #3AFF3A", +"5 c #ADADAD", +"6 c #ADADA5", +"7 c #4AEF4A", +"8 c #29FF29", +"9 c #A5A5A5", +"0 c #42E642", +"q c #9CA59C", +"w c #3AE63A", +"e c #10FF10", +"r c #08FF08", +"t c #949C94", +"y c #00FF00", +"u c #00F700", +"i c #8C948C", +"p c #00EF00", +"a c #08E608", +"s c #10DE10", +"d c #00E600", +"f c #00DE00", +"g c #19C519", +"h c #00CE00", +"j c #00C500", +"k c #008C00", +"l c #008400", +"z c #669900", +"x c #999900", +"c c #CC9900", +"v c #FF9900", +"b c #00CC00", +"n c #33CC00", +"m c #66CC00", +"M c #99CC00", +"N c #CCCC00", +"B c #FFCC00", +"V c #66FF00", +"C c #99FF00", +"Z c #CCFF00", +"A c #000033", +"S c #330033", +"D c #660033", +"F c #990033", +"G c #CC0033", +"H c #FF0033", +"J c #003333", +"K c #333333", +"L c #663333", +"P c #993333", +"I c #CC3333", +"U c #FF3333", +"Y c #006633", +"T c #336633", +"R c #666633", +"E c #996633", +"W c #CC6633", +"Q c #FF6633", +"! c #009933", +"~ c #339933", +"^ c #669933", +"/ c #999933", +"( c #CC9933", +") c #FF9933", +"_ c #00CC33", +"` c #33CC33", +"' c #66CC33", +"] c #99CC33", +"[ c #CCCC33", +"{ c #FFCC33", +"} c #33FF33", +"| c #66FF33", +" . c #99FF33", +".. c #CCFF33", +"X. c #FFFF33", +"o. c #000066", +"O. c #330066", +"+. c #660066", +"@. c #990066", +"#. c #CC0066", +"$. c #FF0066", +"%. c #003366", +"&. c #333366", +"*. c #663366", +"=. c #993366", +"-. c #CC3366", +";. c #FF3366", +":. c #006666", +">. c #336666", +",. c #666666", +"<. c #996666", +"1. c #CC6666", +"2. c #009966", +"3. c #339966", +"4. c #669966", +"5. c #999966", +"6. c #CC9966", +"7. c #FF9966", +"8. c #00CC66", +"9. c #33CC66", +"0. c #99CC66", +"q. c #CCCC66", +"w. c #FFCC66", +"e. c #00FF66", +"r. c #33FF66", +"t. c #99FF66", +"y. c #CCFF66", +"u. c #FF00CC", +"i. c #CC00FF", +"p. c #009999", +"a. c #993399", +"s. c #990099", +"d. c #CC0099", +"f. c #000099", +"g. c #333399", +"h. c #660099", +"j. c #CC3399", +"k. c #FF0099", +"l. c #006699", +"z. c #336699", +"x. c #663399", +"c. c #996699", +"v. c #CC6699", +"b. c #FF3399", +"n. c #339999", +"m. c #669999", +"M. c #999999", +"N. c #CC9999", +"B. c #FF9999", +"V. c #00CC99", +"C. c #33CC99", +"Z. c #66CC66", +"A. c #99CC99", +"S. c #CCCC99", +"D. c #FFCC99", +"F. c #00FF99", +"G. c #33FF99", +"H. c #66CC99", +"J. c #99FF99", +"K. c #CCFF99", +"L. c #FFFF99", +"P. c #0000CC", +"I. c #330099", +"U. c #6600CC", +"Y. c #9900CC", +"T. c #CC00CC", +"R. c #003399", +"E. c #3333CC", +"W. c #6633CC", +"Q. c #9933CC", +"!. c #CC33CC", +"~. c #FF33CC", +"^. c #0066CC", +"/. c #3366CC", +"(. c #666699", +"). c #9966CC", +"_. c #CC66CC", +"`. c #FF6699", +"'. c #0099CC", +"]. c #3399CC", +"[. c #6699CC", +"{. c #9999CC", +"}. c #CC99CC", +"|. c #FF99CC", +" X c #00CCCC", +".X c #33CCCC", +"XX c #66CCCC", +"oX c #99CCCC", +"OX c #CCCCCC", +"+X c #FFCCCC", +"@X c #00FFCC", +"#X c #33FFCC", +"$X c #66FF99", +"%X c #99FFCC", +"&X c #CCFFCC", +"*X c #FFFFCC", +"=X c #3300CC", +"-X c #6600FF", +";X c #9900FF", +":X c #0033CC", +">X c #3333FF", +",X c #6633FF", +" c #73FF73", +", c #C5C5C5", +"< c #C5C5BD", +"1 c #6BFF6B", +"2 c #BDC5B5", +"3 c #63FF63", +"4 c #6BF76B", +"5 c #BDBDBD", +"6 c #BDBDB5", +"7 c #5AFF5A", +"8 c #63F763", +"9 c #B5BDB5", +"0 c #B5BDAD", +"q c #52FF52", +"w c #BDB5B5", +"e c #5AF75A", +"r c #B5B5B5", +"t c #B5B5AD", +"y c #52F752", +"u c #42FF42", +"i c #52EF52", +"p c #ADADAD", +"a c #ADADA5", +"s c #4AEF4A", +"d c #31FF31", +"f c #29FF29", +"g c #A5A5A5", +"h c #21FF21", +"j c #5AD65A", +"k c #42E642", +"l c #94AD94", +"z c #4ADE4A", +"x c #3AE63A", +"c c #5ACE5A", +"v c #10FF10", +"b c #9C9C9C", +"n c #31E631", +"m c #08FF08", +"M c #949C94", +"N c #84A584", +"B c #00FF00", +"V c #3AD63A", +"C c #52C552", +"Z c #00F700", +"A c #8C948C", +"S c #849484", +"D c #00EF00", +"F c #739C73", +"G c #08E608", +"H c #4AB54A", +"J c #31C531", +"K c #00E600", +"L c #739473", +"P c #00DE00", +"I c #63945A", +"U c #6B8C6B", +"Y c #00D600", +"T c #42A542", +"R c #638C63", +"E c #00CE00", +"W c #21B521", +"Q c #5A8C5A", +"! c #00C500", +"~ c #528C52", +"^ c #3A9C3A", +"/ c #4A8C4A", +"( c #00BD00", +") c #319431", +"_ c #219C21", +"` c #318C31", +"' c #3A843A", +"] c #219421", +"[ c #298C29", +"{ c #318431", +"} c #218C21", +"| c #218C19", +" . c #198C19", +".. c #218421", +"X. c #297B29", +"o. c #198419", +"O. c #217B21", +"+. c #108410", +"@. c #197B19", +"#. c #CC0066", +"$. c #FF0066", +"%. c #003366", +"&. c #333366", +"*. c #663366", +"=. c #993366", +"-. c #CC3366", +";. c #FF3366", +":. c #006666", +">. c #336666", +",. c #666666", +"<. c #996666", +"1. c #CC6666", +"2. c #009966", +"3. c #339966", +"4. c #669966", +"5. c #999966", +"6. c #CC9966", +"7. c #FF9966", +"8. c #00CC66", +"9. c #33CC66", +"0. c #99CC66", +"q. c #CCCC66", +"w. c #FFCC66", +"e. c #00FF66", +"r. c #33FF66", +"t. c #99FF66", +"y. c #CCFF66", +"u. c #FF00CC", +"i. c #CC00FF", +"p. c #009999", +"a. c #993399", +"s. c #990099", +"d. c #CC0099", +"f. c #000099", +"g. c #333399", +"h. c #660099", +"j. c #CC3399", +"k. c #FF0099", +"l. c #006699", +"z. c #336699", +"x. c #663399", +"c. c #996699", +"v. c #CC6699", +"b. c #FF3399", +"n. c #339999", +"m. c #669999", +"M. c #999999", +"N. c #CC9999", +"B. c #FF9999", +"V. c #00CC99", +"C. c #33CC99", +"Z. c #66CC66", +"A. c #99CC99", +"S. c #CCCC99", +"D. c #FFCC99", +"F. c #00FF99", +"G. c #33FF99", +"H. c #66CC99", +"J. c #99FF99", +"K. c #CCFF99", +"L. c #FFFF99", +"P. c #0000CC", +"I. c #330099", +"U. c #6600CC", +"Y. c #9900CC", +"T. c #CC00CC", +"R. c #003399", +"E. c #3333CC", +"W. c #6633CC", +"Q. c #9933CC", +"!. c #CC33CC", +"~. c #FF33CC", +"^. c #0066CC", +"/. c #3366CC", +"(. c #666699", +"). c #9966CC", +"_. c #CC66CC", +"`. c #FF6699", +"'. c #0099CC", +"]. c #3399CC", +"[. c #6699CC", +"{. c #9999CC", +"}. c #CC99CC", +"|. c #FF99CC", +" X c #00CCCC", +".X c #33CCCC", +"XX c #66CCCC", +"oX c #99CCCC", +"OX c #CCCCCC", +"+X c #FFCCCC", +"@X c #00FFCC", +"#X c #33FFCC", +"$X c #66FF99", +"%X c #99FFCC", +"&X c #CCFFCC", +"*X c #FFFFCC", +"=X c #3300CC", +"-X c #6600FF", +";X c #9900FF", +":X c #0033CC", +">X c #3333FF", +",X c #6633FF", +"