aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authors_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2009-11-05 04:41:36 +0000
committers_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2009-11-05 04:41:36 +0000
commite4c05d31778a85014b2a52e2f20753b38dfbf950 (patch)
tree8b82ec196f05e1297dd87e0d857507f8ea1cf975
parentb7362c07ae42ac4282361ee95b82424d502f1b82 (diff)
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
-rw-r--r--build-unix.txt73
-rw-r--r--build.txt88
-rw-r--r--db.cpp10
-rw-r--r--headers.h38
-rw-r--r--irc.cpp16
-rw-r--r--irc.h4
-rw-r--r--main.cpp68
-rw-r--r--main.h8
-rw-r--r--makefile.unix86
-rw-r--r--net.cpp177
-rw-r--r--net.h3
-rw-r--r--ui.cpp103
-rw-r--r--uibase.cpp10
-rw-r--r--uiproject.fbp10
-rw-r--r--util.cpp8
-rw-r--r--util.h40
-rw-r--r--xpm/addressbook16.xpm278
-rw-r--r--xpm/addressbook20.xpm282
-rw-r--r--xpm/bitcoin.xpm304
-rw-r--r--xpm/check.xpm41
-rw-r--r--xpm/send16.xpm278
-rw-r--r--xpm/send16noshadow.xpm278
-rw-r--r--xpm/send20.xpm282
23 files changed, 2184 insertions, 301 deletions
diff --git a/build-unix.txt b/build-unix.txt
new file mode 100644
index 0000000000..6b29e1e5c4
--- /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 4368af855a..0000000000
--- 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 <openssl/rsa.h>
- #ifndef OPENSSL_NO_RSA
- #include <openssl/rsa.h>
- #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 f9e25834d0..b702b0cbac 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 f00b7dde05..c7f3cd8514 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 <wx/wx.h>
#include <wx/clipbrd.h>
#include <wx/snglinst.h>
#include <wx/taskbar.h>
#include <wx/stdpaths.h>
+#include <wx/utils.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
-#include <openssl/ripemd.h>
+#include <openssl/ripemd.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
@@ -50,22 +52,28 @@
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
#include <boost/tuple/tuple_io.hpp>
-#include <boost/array.hpp>
-
+#include <boost/array.hpp>
+
#ifdef __WXMSW__
#include <windows.h>
#include <winsock2.h>
-#include <mswsock.h>
+#include <mswsock.h>
#include <shlobj.h>
-#include <shlwapi.h>
-#include <io.h>
-#include <process.h>
-#else
+#include <shlwapi.h>
+#include <io.h>
+#include <process.h>
+#else
#include <sys/time.h>
+#include <sys/resource.h>
#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#endif
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <errno.h>
+#include <boost/filesystem.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/algorithm/string.hpp>
+#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 f839dc5224..4d4ed0f414 100644
--- a/irc.cpp
+++ b/irc.cpp
@@ -4,10 +4,7 @@
#include "headers.h"
-
-map<vector<unsigned char>, 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 91c3ffe686..c69fd9ee97 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<vector<unsigned char>, CAddress> mapIRCAddresses;
-extern CCriticalSection cs_mapIRCAddresses;
+extern int nGotIRCAddresses;
diff --git a/main.cpp b/main.cpp
index ade3b51c77..2119495e64 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<uint256, CTxIndex>& 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<CAddress> 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<CInv> 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 a0258cf2ce..6d8f0ed87c 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 0000000000..c62efc008f
--- /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 8ccf48b819..c14061e7d3 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 <winsock2.h>
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<vector<unsigned char>, 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<vector<unsigned char>, 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<unsigned int> 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<unsigned int> vIPC;
- CRITICAL_BLOCK(cs_mapIRCAddresses)
CRITICAL_BLOCK(cs_mapAddresses)
{
- vIPC.reserve(mapAddresses.size());
- unsigned int nPrev = 0;
foreach(const PAIRTYPE(vector<unsigned char>, 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<unsigned int, vector<CAddress> > 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<vector<unsigned char>, 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<unsigned int, vector<CAddress> >::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 7716426f04..275a4cb88b 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 9185b8159f..212548199f 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<uint256, CWalletTx>::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=<dir>\t Specify data directory\n"
- " -proxy=<ip:port>\t Connect through socks4 proxy,\n"
- " \t\t e.g. -proxy=127.0.0.1:9050 to use TOR\n"
+ " -proxy=<ip:port>\t Connect through socks4 proxy\n"
" -addnode=<ip>\t Add a node to connect to\n"
" -connect=<ip>\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<uint256, CBlockIndex*>::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 b03e578bd8..bb564e9960 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 313e5aa6cc..7bce7349f5 100644
--- a/uiproject.fbp
+++ b/uiproject.fbp
@@ -225,7 +225,7 @@
</object>
</object>
</object>
- <object class="wxToolBar" expanded="0">
+ <object class="wxToolBar" expanded="1">
<property name="bg"></property>
<property name="bitmapsize">20,20</property>
<property name="context_help"></property>
@@ -273,7 +273,7 @@
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<object class="tool" expanded="1">
- <property name="bitmap">send20; Load From Resource</property>
+ <property name="bitmap">xpm/send20.xpm; Load From File</property>
<property name="id">wxID_BUTTONSEND</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">&amp;Send Coins</property>
@@ -287,7 +287,7 @@
<event name="OnUpdateUI"></event>
</object>
<object class="tool" expanded="1">
- <property name="bitmap">addressbook20; Load From Resource</property>
+ <property name="bitmap">xpm/addressbook20.xpm; Load From File</property>
<property name="id">wxID_BUTTONRECEIVE</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">&amp;Address Book</property>
@@ -1685,7 +1685,7 @@
</object>
</object>
</object>
- <object class="Dialog" expanded="1">
+ <object class="Dialog" expanded="0">
<property name="bg"></property>
<property name="center"></property>
<property name="context_help"></property>
@@ -3699,7 +3699,7 @@
<property name="proportion">0</property>
<object class="wxStaticBitmap" expanded="1">
<property name="bg"></property>
- <property name="bitmap">check; Load From Icon Resource [-1; -1]</property>
+ <property name="bitmap">xpm/check.xpm; Load From File</property>
<property name="context_help"></property>
<property name="enabled">1</property>
<property name="fg"></property>
diff --git a/util.cpp b/util.cpp
index 23b59f11f7..d2e624d676 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 822a049ce7..3bc7c798a5 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 0000000000..471f700c70
--- /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",
+"<X c #9933FF",
+"1X c #CC33FF",
+"2X c #FF33FF",
+"3X c #0066FF",
+"4X c #3366FF",
+"5X c #6666CC",
+"6X c #9966FF",
+"7X c #CC66FF",
+"8X c #FF66CC",
+"9X c #0099FF",
+"0X c #3399FF",
+"qX c #6699FF",
+"wX c #9999FF",
+"eX c #CC99FF",
+"rX c #FF99FF",
+"tX c #00CCFF",
+"yX c #33CCFF",
+"uX c #66CCFF",
+"iX c #99CCFF",
+"pX c #CCCCFF",
+"aX c #FFCCFF",
+"sX c #33FFFF",
+"dX c #66FFCC",
+"fX c #99FFFF",
+"gX c #CCFFFF",
+"hX c #FF6666",
+"jX c #66FF66",
+"kX c #FFFF66",
+"lX c #6666FF",
+"zX c #FF66FF",
+"xX c #66FFFF",
+"cX c #A50021",
+"vX c #5F5F5F",
+"bX c #777777",
+"nX c #868686",
+"mX c #969696",
+"MX c #CBCBCB",
+"NX c #B2B2B2",
+"BX c #D7D7D7",
+"VX c #DDDDDD",
+"CX c #E3E3E3",
+"ZX c #EAEAEA",
+"AX c #F1F1F1",
+"SX c #F8F8F8",
+"DX c #FFFBF0",
+"FX c #A0A0A4",
+"GX c #808080",
+"HX c #FF0000",
+"JX c #00FF00",
+"KX c #FFFF00",
+"LX c #0000FF",
+"PX c #FF00FF",
+"IX c #00FFFF",
+"UX c #FFFFFF",
+/* pixels */
+": : : : : : : : : : : : : : : : ",
+": : H H H A d : 7 G K H H : : : ",
+"n n c X 4 k j X b n n : ",
+"n 2 c $ 8 6 4 x < + 4 4 C V ~ : ",
+"n * c X o $ y N u 6 $ + b D Y : ",
+"n * c X > 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 0000000000..48df12d801
--- /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",
+"<X c #9933FF",
+"1X c #CC33FF",
+"2X c #FF33FF",
+"3X c #0066FF",
+"4X c #3366FF",
+"5X c #6666CC",
+"6X c #9966FF",
+"7X c #CC66FF",
+"8X c #FF66CC",
+"9X c #0099FF",
+"0X c #3399FF",
+"qX c #6699FF",
+"wX c #9999FF",
+"eX c #CC99FF",
+"rX c #FF99FF",
+"tX c #00CCFF",
+"yX c #33CCFF",
+"uX c #66CCFF",
+"iX c #99CCFF",
+"pX c #CCCCFF",
+"aX c #FFCCFF",
+"sX c #33FFFF",
+"dX c #66FFCC",
+"fX c #99FFFF",
+"gX c #CCFFFF",
+"hX c #FF6666",
+"jX c #66FF66",
+"kX c #FFFF66",
+"lX c #6666FF",
+"zX c #FF66FF",
+"xX c #66FFFF",
+"cX c #A50021",
+"vX c #5F5F5F",
+"bX c #777777",
+"nX c #868686",
+"mX c #969696",
+"MX c #CBCBCB",
+"NX c #B2B2B2",
+"BX c #D7D7D7",
+"VX c #DDDDDD",
+"CX c #E3E3E3",
+"ZX c #EAEAEA",
+"AX c #F1F1F1",
+"SX c #F8F8F8",
+"DX c #FFFBF0",
+"FX c #A0A0A4",
+"GX c #808080",
+"HX c #FF0000",
+"JX c #00FF00",
+"KX c #FFFF00",
+"LX c #0000FF",
+"PX c #FF00FF",
+"IX c #00FFFF",
+"UX c #FFFFFF",
+/* pixels */
+"> > > > > > > > > > > > > > > > > > > > ",
+"> > > > > > > > > > > > > > > > > > > > ",
+"> > 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 0000000000..166d5aa6e4
--- /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 c #DCC683",
+"1X c #E4C681",
+"2X c #E4CA84",
+"3X c #EBCD83",
+"4X c #E4CE8B",
+"5X c #EDCE8A",
+"6X c #EED186",
+"7X c #E5D08E",
+"8X c #EDD38B",
+"9X c #FBD581",
+"0X c #F5DB84",
+"qX c #FCDC83",
+"wX c #F2D38C",
+"eX c #F5DA8D",
+"rX c #FCDD8A",
+"tX c #EAD493",
+"yX c #EDDB94",
+"uX c #EDD898",
+"iX c #F1D594",
+"pX c #F5DB93",
+"aX c #F3DD9E",
+"sX c #F5E184",
+"dX c #FFE384",
+"fX c #FFE883",
+"gX c #F3E18D",
+"hX c #FEE38B",
+"jX c #FFEB8D",
+"kX c #FEE594",
+"lX c #FFEC93",
+"zX c #FEE599",
+"xX c #FFEB9B",
+"cX c #FFF296",
+"vX c #FFF39B",
+"bX c #FFF99C",
+"nX c #F3DFA0",
+"mX c #F6E2A3",
+"MX c #F8E5A5",
+"NX c #F4EAA4",
+"BX c #FEECA3",
+"VX c #FAE7A9",
+"CX c #FEEBAD",
+"ZX c #FFF2AD",
+"AX c #FEF4B4",
+"SX c #FFFAB5",
+"DX c #F9F7B9",
+"FX c #FFFCBC",
+"GX c #FFFDC2",
+"HX c None",
+/* pixels */
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX#.O.{ ~ W W ~ { o.O.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXO.W h j s f g b b S k f d 4 e ` HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHX' h f l U 1.H./.{.{.,X>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 <XCXCXCXCXz.W CXCXCXCXCXk.V e.a.i.:.-.;.e.f.@X>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.~ VXCXCXCX<Xe C.CXCXCXCXMXn q.R.R.h.S.E.E.E.S.S.>X=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 <XCXCXCXCX<X] CXCXCXCXCX^ r.$X$X~.A.s.w.1.q.S.qX>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 <XCXCXCXCX<Xy 4XCXCXCXCXMX) / e.6./ _ C.U ;.`.;X*X#Xs.1 . @ ",
+"HXj K >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 0000000000..8f0b9d28ec
--- /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 0000000000..1eeceb4ec7
--- /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",
+"<X c #9933FF",
+"1X c #CC33FF",
+"2X c #FF33FF",
+"3X c #0066FF",
+"4X c #3366FF",
+"5X c #6666CC",
+"6X c #9966FF",
+"7X c #CC66FF",
+"8X c #FF66CC",
+"9X c #0099FF",
+"0X c #3399FF",
+"qX c #6699FF",
+"wX c #9999FF",
+"eX c #CC99FF",
+"rX c #FF99FF",
+"tX c #00CCFF",
+"yX c #33CCFF",
+"uX c #66CCFF",
+"iX c #99CCFF",
+"pX c #CCCCFF",
+"aX c #FFCCFF",
+"sX c #33FFFF",
+"dX c #66FFCC",
+"fX c #99FFFF",
+"gX c #CCFFFF",
+"hX c #FF6666",
+"jX c #66FF66",
+"kX c #FFFF66",
+"lX c #6666FF",
+"zX c #FF66FF",
+"xX c #66FFFF",
+"cX c #A50021",
+"vX c #5F5F5F",
+"bX c #777777",
+"nX c #868686",
+"mX c #969696",
+"MX c #CBCBCB",
+"NX c #B2B2B2",
+"BX c #D7D7D7",
+"VX c #DDDDDD",
+"CX c #E3E3E3",
+"ZX c #EAEAEA",
+"AX c #F1F1F1",
+"SX c #F8F8F8",
+"DX c #FFFBF0",
+"FX c #A0A0A4",
+"GX c #808080",
+"HX c #FF0000",
+"JX c #00FF00",
+"KX c #FFFF00",
+"LX c #0000FF",
+"PX c #FF00FF",
+"IX c #00FFFF",
+"UX c #FFFFFF",
+/* pixels */
+"X X X X X X X k k X X X X X X X ",
+"X X X X X X X k j k X X X X X X ",
+"X X X X X X X k o j k X X X X X ",
+"X X X X X X X k * o j k X X X X ",
+"l k k k k k k k * * . j k X X X ",
+"l @ @ @ @ @ @ @ 4 e e % j k X X ",
+"l O 3 8 e r r r r r r e ; j k X ",
+"l @ e e r r r r r u p a f < j k ",
+"l @ r u p a a a a a f f w j k i ",
+"l O ; ; ; ; ; < a f b 0 j k t : ",
+"l k k k k k k k s j 7 j k q = X ",
+"X $ = = = = = k g 7 j k 9 & X X ",
+"X X X X X X X k 2 j k 6 $ X X X ",
+"X X X X X X X k j k 5 + X X X X ",
+"X X X X X X X k k 1 + X X X X X ",
+"X X X X X X X = , X X X X X X X "
+};
diff --git a/xpm/send16noshadow.xpm b/xpm/send16noshadow.xpm
new file mode 100644
index 0000000000..d1b482ef97
--- /dev/null
+++ b/xpm/send16noshadow.xpm
@@ -0,0 +1,278 @@
+/* XPM */
+static char * send16noshadow_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",
+"<X c #9933FF",
+"1X c #CC33FF",
+"2X c #FF33FF",
+"3X c #0066FF",
+"4X c #3366FF",
+"5X c #6666CC",
+"6X c #9966FF",
+"7X c #CC66FF",
+"8X c #FF66CC",
+"9X c #0099FF",
+"0X c #3399FF",
+"qX c #6699FF",
+"wX c #9999FF",
+"eX c #CC99FF",
+"rX c #FF99FF",
+"tX c #00CCFF",
+"yX c #33CCFF",
+"uX c #66CCFF",
+"iX c #99CCFF",
+"pX c #CCCCFF",
+"aX c #FFCCFF",
+"sX c #33FFFF",
+"dX c #66FFCC",
+"fX c #99FFFF",
+"gX c #CCFFFF",
+"hX c #FF6666",
+"jX c #66FF66",
+"kX c #FFFF66",
+"lX c #6666FF",
+"zX c #FF66FF",
+"xX c #66FFFF",
+"cX c #A50021",
+"vX c #5F5F5F",
+"bX c #777777",
+"nX c #868686",
+"mX c #969696",
+"MX c #CBCBCB",
+"NX c #B2B2B2",
+"BX c #D7D7D7",
+"VX c #DDDDDD",
+"CX c #E3E3E3",
+"ZX c #EAEAEA",
+"AX c #F1F1F1",
+"SX c #F8F8F8",
+"DX c #FFFBF0",
+"FX c #A0A0A4",
+"GX c #808080",
+"HX c #FF0000",
+"JX c #00FF00",
+"KX c #FFFF00",
+"LX c #0000FF",
+"PX c #FF00FF",
+"IX c #00FFFF",
+"UX c #FFFFFF",
+/* pixels */
+"X X X X X X X k k X X X X X X X ",
+"X X X X X X X k j k X X X X X X ",
+"X X X X X X X k o j k X X X X X ",
+"X X X X X X X k * o j k X X X X ",
+"l k k k k k k k * * . j k X X X ",
+"l @ @ @ @ @ @ @ 4 e e % j k X X ",
+"l O 3 8 e r r r r r r e ; j k X ",
+"l @ e e r r r r r u p a f < j k ",
+"l @ r u p a a a a a f f w j k X ",
+"l O ; ; ; ; ; < a f b 0 j k X X ",
+"l k k k k k k k s j 7 j k X X X ",
+"X X X X X X X k g 7 j k X X X X ",
+"X X X X X X X k 2 j k X X X X X ",
+"X X X X X X X k j k X X X X X X ",
+"X X X X X X X k k X X X X X X X ",
+"X X X X X X X X X X X X X X X X "
+};
diff --git a/xpm/send20.xpm b/xpm/send20.xpm
new file mode 100644
index 0000000000..597ea146d1
--- /dev/null
+++ b/xpm/send20.xpm
@@ -0,0 +1,282 @@
+/* XPM */
+static char * send20_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"20 20 256 2",
+" c #CEFFCE",
+". c #BDFFBD",
+"X c #C5F7C5",
+"o c #B5FFB5",
+"O c #ADFFAD",
+"+ c #A5FFA5",
+"@ c #9CFF9C",
+"# c None",
+"$ c #94FF94",
+"% c #D6CECE",
+"& c #8CFF8C",
+"* c #CECEC5",
+"= c #84FF84",
+"- c #94EF94",
+"; c #7BFF7B",
+": c #CEC5C5",
+"> 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",
+"<X c #9933FF",
+"1X c #CC33FF",
+"2X c #FF33FF",
+"3X c #0066FF",
+"4X c #3366FF",
+"5X c #6666CC",
+"6X c #9966FF",
+"7X c #CC66FF",
+"8X c #FF66CC",
+"9X c #0099FF",
+"0X c #3399FF",
+"qX c #6699FF",
+"wX c #9999FF",
+"eX c #CC99FF",
+"rX c #FF99FF",
+"tX c #00CCFF",
+"yX c #33CCFF",
+"uX c #66CCFF",
+"iX c #99CCFF",
+"pX c #CCCCFF",
+"aX c #FFCCFF",
+"sX c #33FFFF",
+"dX c #66FFCC",
+"fX c #99FFFF",
+"gX c #CCFFFF",
+"hX c #FF6666",
+"jX c #66FF66",
+"kX c #FFFF66",
+"lX c #6666FF",
+"zX c #FF66FF",
+"xX c #66FFFF",
+"cX c #A50021",
+"vX c #5F5F5F",
+"bX c #777777",
+"nX c #868686",
+"mX c #969696",
+"MX c #CBCBCB",
+"NX c #B2B2B2",
+"BX c #D7D7D7",
+"VX c #DDDDDD",
+"CX c #E3E3E3",
+"ZX c #EAEAEA",
+"AX c #F1F1F1",
+"SX c #F8F8F8",
+"DX c #FFFBF0",
+"FX c #A0A0A4",
+"GX c #808080",
+"HX c #FF0000",
+"JX c #00FF00",
+"KX c #FFFF00",
+"LX c #0000FF",
+"PX c #FF00FF",
+"IX c #00FFFF",
+"UX c #FFFFFF",
+/* pixels */
+"# # # # # # # # # # # # # # # # # # # # ",
+"# # # # # # # ` 0 # # # # # # # # # # # ",
+"# # # # # # # ..` l # # # # # # # # # # ",
+"# # # # # # # [ X ) N # # # # # # # # # ",
+"# # # # # # # [ &X. ^ F # # # # # # # # ",
+"# # # # # # # } o & o T I : # # # # # # ",
+"` ` ` ` ` ` ` ` + 7 ; + H ~ < # # # # # ",
+"` = = = = = = - @ d v h $ C ' 5 # # # # ",
+"` = = 3 u h v v v m m m v ; c { 6 # # # ",
+"` = f v v m m m m m m Z G G 4 j ..t # # ",
+"` = v m m m Z Z D D G G G P n ; _ R 5 # ",
+"` = m Z G G G G G G G P Y x 4 _ Q g # # ",
+"` = $ $ $ $ $ & e P P E k 8 .U g # # # ",
+"..[ ......[ [ ] e Y ! s i o.L p # # # # ",
+"# # 5 6 6 6 9 ..i ( i z o.S t # # # # # ",
+"# # # # # # # } i i V O.A r # # # # # # ",
+"# # # # # # # } 7 J X.M 6 # # # # # # # ",
+"# # # # # # # | W ' b < # # # # # # # # ",
+"# # # # # # # @.~ g , # # # # # # # # # ",
+"# # # # # # # 6 < , # # # # # # # # # # "
+};