From 793200e5e918a6e993ddf701967a8b6535a6828f Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Mon, 26 Jul 2010 17:15:18 +0000 Subject: [PATCH] bitcoind now compiles without wxWidgets or wxBase git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@112 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build-unix.txt | 16 +- db.cpp | 2 +- headers.h | 17 ++- init.cpp | 388 ++++++------------------------------------------- init.h | 4 +- main.cpp | 5 +- makefile.mingw | 26 ++-- makefile.osx | 13 +- makefile.unix | 20 +-- makefile.vc | 34 +++-- net.cpp | 4 +- noui.h | 34 +++++ rpc.cpp | 6 +- serialize.h | 4 +- ui.cpp | 350 +++++++++++++++++++++++++++++++++++++++++++- ui.h | 63 ++------ util.cpp | 21 +-- util.h | 15 +- 18 files changed, 539 insertions(+), 483 deletions(-) create mode 100644 noui.h diff --git a/build-unix.txt b/build-unix.txt index 30a4a363..fad502a3 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -18,11 +18,8 @@ sudo apt-get install libdb4.7-dev sudo apt-get install libdb4.7++-dev sudo apt-get install libboost-all-dev -We're now using wxWidgets 2.9, which uses UTF-8. - -There isn't currently a debian package of wxWidgets we can use. The 2.8 -packages for Karmic are UTF-16 unicode and won't work for us, and we've had -trouble building 2.8 on 64-bit. +We're now using wxWidgets 2.9, which uses UTF-8. Don't try to use 2.8, it +won't work. You need to download wxWidgets from http://www.wxwidgets.org/downloads/ and build it yourself. See the build instructions and configure parameters @@ -63,15 +60,6 @@ make sudo su make install ldconfig -su -cd .. -mkdir buildbase -cd buildbase -../configure --disable-gui --enable-debug --disable-shared --enable-monolithic -make -sudo su -make install -ldconfig Boost diff --git a/db.cpp b/db.cpp index ea0b581b..50965665 100644 --- a/db.cpp +++ b/db.cpp @@ -60,7 +60,7 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL) return; string strDataDir = GetDataDir(); string strLogDir = strDataDir + "/database"; - _mkdir(strLogDir.c_str()); + filesystem::create_directory(strLogDir.c_str()); string strErrorFile = strDataDir + "/db.log"; printf("dbenv.open strLogDir=%s strErrorFile=%s\n", strLogDir.c_str(), strErrorFile.c_str()); diff --git a/headers.h b/headers.h index f920fd3f..a0b4c5ed 100644 --- a/headers.h +++ b/headers.h @@ -18,13 +18,19 @@ #define _WIN32_IE 0x0400 #define WIN32_LEAN_AND_MEAN 1 #define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h +#ifdef GUI #include #include #include -#if wxUSE_GUI #include #include #include +#else +#ifdef __WXMAC_OSX__ +#define __WXMAC__ 1 +#define __WXOSX__ 1 +#define __BSD__ 1 +#endif #endif #include #include @@ -61,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -82,12 +89,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #endif #ifdef __BSD__ #include @@ -111,10 +120,12 @@ using namespace boost; #include "irc.h" #include "main.h" #include "rpc.h" -#if wxUSE_GUI +#ifdef GUI #include "uibase.h" -#endif #include "ui.h" +#else +#include "noui.h" +#endif #include "init.h" #include "xpm/addressbook16.xpm" diff --git a/init.cpp b/init.cpp index d6d45628..b8df26c8 100644 --- a/init.cpp +++ b/init.cpp @@ -7,6 +7,15 @@ + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Shutdown +// + void ExitTimeout(void* parg) { #ifdef __WXMSW__ @@ -55,273 +64,59 @@ void Shutdown(void* parg) ////////////////////////////////////////////////////////////////////////////// // -// Startup folder -// - -#ifdef __WXMSW__ -string StartupShortcutPath() -{ - return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk"; -} - -bool GetStartOnSystemStartup() -{ - return filesystem::exists(StartupShortcutPath().c_str()); -} - -void SetStartOnSystemStartup(bool fAutoStart) -{ - // If the shortcut exists already, remove it for updating - remove(StartupShortcutPath().c_str()); - - if (fAutoStart) - { - CoInitialize(NULL); - - // Get a pointer to the IShellLink interface. - IShellLink* psl = NULL; - HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, - CLSCTX_INPROC_SERVER, IID_IShellLink, - reinterpret_cast(&psl)); - - if (SUCCEEDED(hres)) - { - // Get the current executable path - TCHAR pszExePath[MAX_PATH]; - GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); - - // Set the path to the shortcut target - psl->SetPath(pszExePath); - PathRemoveFileSpec(pszExePath); - psl->SetWorkingDirectory(pszExePath); - psl->SetShowCmd(SW_SHOWMINNOACTIVE); - - // Query IShellLink for the IPersistFile interface for - // saving the shortcut in persistent storage. - IPersistFile* ppf = NULL; - hres = psl->QueryInterface(IID_IPersistFile, - reinterpret_cast(&ppf)); - if (SUCCEEDED(hres)) - { - WCHAR pwsz[MAX_PATH]; - // Ensure that the string is ANSI. - MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().c_str(), -1, pwsz, MAX_PATH); - // Save the link by calling IPersistFile::Save. - hres = ppf->Save(pwsz, TRUE); - ppf->Release(); - } - psl->Release(); - } - CoUninitialize(); - } -} - -#elif defined(__WXGTK__) - -// -// Follow the Desktop Application Autostart Spec: -// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html -// - -boost::filesystem::path GetAutostartDir() -{ - namespace fs = boost::filesystem; - - char* pszConfigHome = getenv("XDG_CONFIG_HOME"); - if (pszConfigHome) return fs::path(pszConfigHome) / fs::path("autostart"); - char* pszHome = getenv("HOME"); - if (pszHome) return fs::path(pszHome) / fs::path(".config/autostart"); - return fs::path(); -} - -boost::filesystem::path GetAutostartFilePath() -{ - return GetAutostartDir() / boost::filesystem::path("bitcoin.desktop"); -} - -bool GetStartOnSystemStartup() -{ - boost::filesystem::ifstream optionFile(GetAutostartFilePath()); - if (!optionFile.good()) - return false; - // Scan through file for "Hidden=true": - string line; - while (!optionFile.eof()) - { - getline(optionFile, line); - if (line.find("Hidden") != string::npos && - line.find("true") != string::npos) - return false; - } - optionFile.close(); - - return true; -} - -void SetStartOnSystemStartup(bool fAutoStart) -{ - if (!fAutoStart) - { - unlink(GetAutostartFilePath().native_file_string().c_str()); - } - else - { - boost::filesystem::create_directories(GetAutostartDir()); - - boost::filesystem::ofstream optionFile(GetAutostartFilePath(), ios_base::out|ios_base::trunc); - if (!optionFile.good()) - { - wxMessageBox(_("Cannot write autostart/bitcoin.desktop file"), "Bitcoin"); - return; - } - // Write a bitcoin.desktop file to the autostart directory: - char pszExePath[MAX_PATH+1]; - memset(pszExePath, 0, sizeof(pszExePath)); - readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1); - optionFile << "[Desktop Entry]\n"; - optionFile << "Type=Application\n"; - optionFile << "Name=Bitcoin\n"; - optionFile << "Exec=" << pszExePath << "\n"; - optionFile << "Terminal=false\n"; - optionFile << "Hidden=false\n"; - optionFile.close(); - } -} -#else - -// TODO: OSX startup stuff; see: -// http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html - -bool GetStartOnSystemStartup() { return false; } -void SetStartOnSystemStartup(bool fAutoStart) { } - -#endif - - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CMyApp +// Start // -// Define a new application -class CMyApp : public wxApp -{ -public: - wxLocale m_locale; - - CMyApp(){}; - ~CMyApp(){}; - bool OnInit(); - bool OnInit2(); - int OnExit(); - - // Hook Initialize so we can start without GUI - virtual bool Initialize(int& argc, wxChar** argv); - - // 2nd-level exception handling: we get all the exceptions occurring in any - // event handler here - virtual bool OnExceptionInMainLoop(); - - // 3rd, and final, level exception handling: whenever an unhandled - // exception is caught, this function is called - virtual void OnUnhandledException(); - - // and now for something different: this function is called in case of a - // crash (e.g. dereferencing null pointer, division by 0, ...) - virtual void OnFatalException(); -}; - -IMPLEMENT_APP(CMyApp) - -bool CMyApp::Initialize(int& argc, wxChar** argv) +#ifndef GUI +int main(int argc, char* argv[]) { for (int i = 1; i < argc; i++) if (!IsSwitchChar(argv[i][0])) fCommandLine = true; - - if (!fCommandLine) - { - if (!fGUI) - { - fDaemon = true; - } - else - { - // wxApp::Initialize will remove environment-specific parameters, - // so it's too early to call ParseParameters yet - for (int i = 1; i < argc; i++) - { - wxString str = argv[i]; - #ifdef __WXMSW__ - if (str.size() >= 1 && str[0] == '/') - str[0] = '-'; - char pszLower[MAX_PATH]; - strlcpy(pszLower, str.c_str(), sizeof(pszLower)); - strlwr(pszLower); - str = pszLower; - #endif - if (str == "-daemon") - fDaemon = true; - } - } - } + fDaemon = !fCommandLine; #ifdef __WXGTK__ - if (fDaemon || fCommandLine) + if (!fCommandLine) { - // Call the original Initialize while suppressing error messages - // and ignoring failure. If unable to initialize GTK, it fails - // near the end so hopefully the last few things don't matter. + // Daemonize + pid_t pid = fork(); + if (pid < 0) { - wxLogNull logNo; - wxApp::Initialize(argc, argv); + fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); + return 1; } - - if (fDaemon) - { - // Daemonize - pid_t pid = fork(); - if (pid < 0) - { - fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); - return false; - } - if (pid > 0) - pthread_exit((void*)0); - } - - return true; + if (pid > 0) + pthread_exit((void*)0); } #endif - return wxApp::Initialize(argc, argv); + if (!AppInit(argc, argv)) + return 1; + + while (!fShutdown) + Sleep(1000000); + return 0; } +#endif -bool CMyApp::OnInit() +bool AppInit(int argc, char* argv[]) { bool fRet = false; try { - fRet = OnInit2(); + fRet = AppInit2(argc, argv); } catch (std::exception& e) { - PrintException(&e, "OnInit()"); + PrintException(&e, "AppInit()"); } catch (...) { - PrintException(NULL, "OnInit()"); + PrintException(NULL, "AppInit()"); } if (!fRet) Shutdown(NULL); return fRet; } -extern int g_isPainting; - -bool CMyApp::OnInit2() +bool AppInit2(int argc, char* argv[]) { #ifdef _MSC_VER // Turn off microsoft heap dump noise @@ -332,46 +127,9 @@ bool CMyApp::OnInit2() // Disable confusing "helpful" text message on abort, ctrl-c _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); #endif -#if defined(__WXMSW__) && defined(__WXDEBUG__) && wxUSE_GUI - // Disable malfunctioning wxWidgets debug assertion - g_isPainting = 10000; -#endif -#if wxUSE_GUI - wxImage::AddHandler(new wxPNGHandler); -#endif -#if defined(__WXMSW__ ) || defined(__WXMAC__) - SetAppName("Bitcoin"); -#else - SetAppName("bitcoin"); -#endif #ifndef __WXMSW__ umask(077); #endif -#ifdef __WXMSW__ -#if wxUSE_UNICODE - // Hack to set wxConvLibc codepage to UTF-8 on Windows, - // may break if wxMBConv_win32 implementation in strconv.cpp changes. - class wxMBConv_win32 : public wxMBConv - { - public: - long m_CodePage; - size_t m_minMBCharWidth; - }; - if (((wxMBConv_win32*)&wxConvLibc)->m_CodePage == CP_ACP) - ((wxMBConv_win32*)&wxConvLibc)->m_CodePage = CP_UTF8; -#endif -#endif - - // Load locale//LC_MESSAGES/bitcoin.mo language file - m_locale.Init(wxLANGUAGE_DEFAULT, 0); - m_locale.AddCatalogLookupPathPrefix("locale"); - if (!fWindows) - { - m_locale.AddCatalogLookupPathPrefix("/usr/share/locale"); - m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale"); - } - m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any - m_locale.AddCatalog("bitcoin"); // // Parameters @@ -385,7 +143,7 @@ bool CMyApp::OnInit2() if (mapArgs.count("-?") || mapArgs.count("--help")) { - wxString strUsage = string() + + string strUsage = string() + _("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" + " bitcoin [options] \t " + "\n" + " bitcoin [options] [params]\t " + _("Send command to -server or bitcoind\n") + @@ -404,13 +162,13 @@ bool CMyApp::OnInit2() " -daemon \t " + _("Run in the background as a daemon and accept commands\n") + " -? \t " + _("This help message\n"); -#if defined(__WXMSW__) && wxUSE_GUI +#if defined(__WXMSW__) && defined(GUI) // Tabs make the columns line up in the message box wxMessageBox(strUsage, "Bitcoin", wxOK); #else // Remove tabs - strUsage.Replace("\t", ""); - fprintf(stderr, "%s", ((string)strUsage).c_str()); + strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end()); + fprintf(stderr, "%s", strUsage.c_str()); #endif return false; } @@ -430,9 +188,12 @@ bool CMyApp::OnInit2() if (!fDebug && !pszSetDataDir[0]) ShrinkDebugFile(); 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.%d.%d%s beta, OS version %s\n", VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str()); - printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str()); - printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str()); + printf("Bitcoin version %d.%d.%d%s beta\n", VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer); +#ifdef GUI + printf("OS version %s\n", ((string)wxGetOsDescription()).c_str()); + printf("System default language is %d %s\n", g_locale.GetSystemLanguage(), ((string)g_locale.GetSysName()).c_str()); + printf("Language file %s (%s)\n", (string("locale/") + (string)g_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)g_locale.GetLocale()).c_str()); +#endif printf("Default data directory %s\n", GetDefaultDataDir().c_str()); if (mapArgs.count("-loadblockindextest")) @@ -447,7 +208,7 @@ bool CMyApp::OnInit2() // Limit to single instance per user // Required to protect the database files if we're going to keep deleting log.* // -#ifdef __WXMSW__ +#if defined(__WXMSW__) && defined(GUI) // todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file // maybe should go by whether successfully bind port 8333 instead wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH"); @@ -605,8 +366,10 @@ bool CMyApp::OnInit2() // // Create the main window and start the node // +#ifdef GUI if (!fDaemon) CreateMainWindow(); +#endif if (!CheckDiskSpace()) return false; @@ -619,65 +382,10 @@ bool CMyApp::OnInit2() if (mapArgs.count("-server") || fDaemon) CreateThread(ThreadRPCServer, NULL); +#ifdef GUI if (fFirstRun) SetStartOnSystemStartup(true); +#endif return true; } - -int CMyApp::OnExit() -{ - Shutdown(NULL); - return wxApp::OnExit(); -} - -bool CMyApp::OnExceptionInMainLoop() -{ - try - { - throw; - } - catch (std::exception& e) - { - PrintException(&e, "CMyApp::OnExceptionInMainLoop()"); - wxLogWarning("Exception %s %s", typeid(e).name(), e.what()); - Sleep(1000); - throw; - } - catch (...) - { - PrintException(NULL, "CMyApp::OnExceptionInMainLoop()"); - wxLogWarning("Unknown exception"); - Sleep(1000); - throw; - } - return true; -} - -void CMyApp::OnUnhandledException() -{ - // this shows how we may let some exception propagate uncaught - try - { - throw; - } - catch (std::exception& e) - { - PrintException(&e, "CMyApp::OnUnhandledException()"); - wxLogWarning("Exception %s %s", typeid(e).name(), e.what()); - Sleep(1000); - throw; - } - catch (...) - { - PrintException(NULL, "CMyApp::OnUnhandledException()"); - wxLogWarning("Unknown exception"); - Sleep(1000); - throw; - } -} - -void CMyApp::OnFatalException() -{ - wxMessageBox(_("Program has crashed and will terminate. "), "Bitcoin", wxOK | wxICON_ERROR); -} diff --git a/init.h b/init.h index bd5e3659..fd1fabd7 100644 --- a/init.h +++ b/init.h @@ -3,5 +3,5 @@ // file license.txt or http://www.opensource.org/licenses/mit-license.php. void Shutdown(void* parg); -bool GetStartOnSystemStartup(); -void SetStartOnSystemStartup(bool fAutoStart); +bool AppInit(int argc, char* argv[]); +bool AppInit2(int argc, char* argv[]); diff --git a/main.cpp b/main.cpp index afa7add5..34ac2999 100644 --- a/main.cpp +++ b/main.cpp @@ -83,6 +83,7 @@ bool AddKey(const CKey& key) vector GenerateNewKey() { + RandAddSeedPerfmon(); CKey key; key.MakeNewKey(); if (!AddKey(key)) @@ -1506,7 +1507,7 @@ bool CheckDiskSpace(int64 nAdditionalBytes) { fShutdown = true; printf("*** %s***\n", _("Warning: Disk space is low ")); -#if wxUSE_GUI +#ifdef GUI ThreadSafeMessageBox(_("Warning: Disk space is low "), "Bitcoin", wxOK | wxICON_EXCLAMATION); #endif CreateThread(Shutdown, NULL); @@ -2494,7 +2495,7 @@ void GenerateBitcoins(bool fGenerate) } if (fGenerateBitcoins) { - int nProcessors = wxThread::GetCPUCount(); + int nProcessors = boost::thread::hardware_concurrency(); printf("%d processors\n", nProcessors); if (nProcessors < 1) nProcessors = 1; diff --git a/makefile.mingw b/makefile.mingw index 26944dfd..2cceca54 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -3,8 +3,6 @@ # file license.txt or http://www.opensource.org/licenses/mit-license.php. -# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28" - INCLUDEPATHS= \ -I"/boost" \ -I"/db/build_unix" \ @@ -22,32 +20,32 @@ WXLIBS= \ -l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd LIBS= \ - -l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d -l libboost_program_options-mgw34-mt-d \ + -l libboost_system-mgw34-mt-d \ + -l libboost_filesystem-mgw34-mt-d \ + -l libboost_program_options-mgw34-mt-d \ + -l libboost_thread-mgw34-mt-d \ -l db_cxx \ -l eay32 \ -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi -WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH +DEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH DEBUGFLAGS=-g -D__WXDEBUG__ -CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h + script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h sha.h all: bitcoin.exe -headers.h.gch: headers.h $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/%.o: %.cpp $(HEADERS) headers.h.gch - g++ -c $(CFLAGS) -o $@ $< +obj/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -DGUI -o $@ $< obj/sha.o: sha.cpp sha.h g++ -c $(CFLAGS) -O3 -o $@ $< obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp - windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< + windres $(DEFS) $(INCLUDEPATHS) -o $@ -i $< OBJS= \ obj/util.o \ @@ -64,10 +62,10 @@ bitcoin.exe: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o obj/ui_res.o obj/nogui/%.o: %.cpp $(HEADERS) - g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $< + g++ -c $(CFLAGS) -o $@ $< bitcoind.exe: $(OBJS:obj/%=obj/nogui/%) obj/sha.o obj/ui_res.o - g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wxbase29ud $(LIBS) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) clean: diff --git a/makefile.osx b/makefile.osx index 3f5be73a..28d14bea 100644 --- a/makefile.osx +++ b/makefile.osx @@ -20,22 +20,23 @@ LIBS= -dead_strip \ $(DEPSDIR)/lib/libboost_system.a \ $(DEPSDIR)/lib/libboost_filesystem.a \ $(DEPSDIR)/lib/libboost_program_options.a \ + $(DEPSDIR)/lib/libboost_thread.a \ $(DEPSDIR)/lib/libcrypto.a -WXDEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -DNOPCH -DMSG_NOSIGNAL=0 +DEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -D__WXMAC_OSX__ -DNOPCH -DMSG_NOSIGNAL=0 DEBUGFLAGS=-g -DwxDEBUG_LEVEL=0 # ppc doesn't work because we don't support big-endian -CFLAGS=-mmacosx-version-min=10.5 -arch i386 -arch x86_64 -O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +CFLAGS=-mmacosx-version-min=10.5 -arch i386 -arch x86_64 -O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h + script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h sha.h all: bitcoin obj/%.o: %.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< + g++ -c $(CFLAGS) -DGUI -o $@ $< obj/sha.o: sha.cpp sha.h g++ -c $(CFLAGS) -O3 -o $@ $< @@ -55,10 +56,10 @@ bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o obj/nogui/%.o: %.cpp $(HEADERS) - g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $< + g++ -c $(CFLAGS) -o $@ $< bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o - g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) clean: diff --git a/makefile.unix b/makefile.unix index cc5111bb..0b549621 100644 --- a/makefile.unix +++ b/makefile.unix @@ -3,7 +3,6 @@ # file license.txt or http://www.opensource.org/licenses/mit-license.php. - INCLUDEPATHS= \ -I"/usr/include" \ -I"/usr/local/include/wx-2.9" \ @@ -21,27 +20,30 @@ WXLIBS= \ LIBS= \ -Wl,-Bstatic \ - -l boost_system -l boost_filesystem -l boost_program_options \ + -l boost_system \ + -l boost_filesystem \ + -l boost_program_options \ + -l boost_thread \ -l db_cxx \ -l crypto \ -Wl,-Bdynamic \ -l gthread-2.0 -WXDEFS=-D__WXGTK__ -DNOPCH +DEFS=-D__WXGTK__ -DNOPCH DEBUGFLAGS=-g -D__WXDEBUG__ -CFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +CFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h + script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h sha.h all: bitcoin headers.h.gch: headers.h $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< + g++ -c $(CFLAGS) -DGUI -o $@ $< obj/%.o: %.cpp $(HEADERS) headers.h.gch - g++ -c $(CFLAGS) -o $@ $< + g++ -c $(CFLAGS) -DGUI -o $@ $< obj/sha.o: sha.cpp sha.h g++ -c $(CFLAGS) -O3 -o $@ $< @@ -61,10 +63,10 @@ bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o obj/nogui/%.o: %.cpp $(HEADERS) - g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $< + g++ -c $(CFLAGS) -o $@ $< bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o - g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wx_baseud-2.9 $(LIBS) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) clean: diff --git a/makefile.vc b/makefile.vc index f5452f4d..d6fd319c 100644 --- a/makefile.vc +++ b/makefile.vc @@ -3,8 +3,6 @@ # file license.txt or http://www.opensource.org/licenses/mit-license.php. -# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28" - INCLUDEPATHS= \ /I"/boost" \ /I"/db/build_windows" \ @@ -18,25 +16,29 @@ LIBPATHS= \ /LIBPATH:"/openssl/out" \ /LIBPATH:"/wxwidgets/lib/vc_lib" +WXLIBS=wxmsw29ud_html.lib wxmsw29ud_core.lib wxmsw29ud_adv.lib wxbase29ud.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib + LIBS= \ - libboost_system-vc80-mt-gd.lib libboost_filesystem-vc80-mt-gd.lib libboost_program_options-vc80-mt-gd.lib \ + libboost_system-vc80-mt-gd.lib \ + libboost_filesystem-vc80-mt-gd.lib \ + libboost_program_options-vc80-mt-gd.lib \ + libboost_thread-vc80-mt-gd.lib \ libdb47sd.lib \ libeay32.lib \ - wxmsw29ud_html.lib wxmsw29ud_core.lib wxmsw29ud_adv.lib wxbase29ud.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib \ kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib shlwapi.lib -WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH +DEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ -CFLAGS=/c /nologo /Ob0 /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +CFLAGS=/c /nologo /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h + script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h sha.h all: bitcoin.exe .cpp{obj}.obj: - cl $(CFLAGS) /Fo$@ %s + cl $(CFLAGS) /DGUI /Fo$@ %s obj\util.obj: $(HEADERS) @@ -59,10 +61,10 @@ obj\ui.obj: $(HEADERS) obj\uibase.obj: $(HEADERS) obj\sha.obj: sha.cpp sha.h - cl $(CFLAGS) /O2 /Fo$@ %s + cl $(CFLAGS) /O2 /Fo$@ %s obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp - rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s + rc $(INCLUDEPATHS) $(DEFS) /Fo$@ %s OBJS= \ obj\util.obj \ @@ -75,11 +77,11 @@ OBJS= \ obj\init.obj bitcoin.exe: $(OBJS) obj\ui.obj obj\uibase.obj obj\sha.obj obj\ui.res - link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) + link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(WXLIBS) $(LIBS) .cpp{obj\nogui}.obj: - cl $(CFLAGS) /DwxUSE_GUI=0 /Fo$@ %s + cl $(CFLAGS) /Fo$@ %s obj\nogui\util.obj: $(HEADERS) @@ -98,10 +100,10 @@ obj\nogui\rpc.obj: $(HEADERS) obj\nogui\init.obj: $(HEADERS) bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\sha.obj obj\ui.res - link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS) + link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS) clean: - -del /Q obj\* - -del *.ilk - -del *.pdb + -del /Q obj\* + -del *.ilk + -del *.pdb diff --git a/net.cpp b/net.cpp index dc1debd2..c4a2cabd 100644 --- a/net.cpp +++ b/net.cpp @@ -64,7 +64,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (hSocket == INVALID_SOCKET) return false; -#if defined(__BSD__) || defined(__WXOSX__) +#if defined(__BSD__) || defined(__WXMAC_OSX__) int set = 1; setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); #endif @@ -1163,7 +1163,7 @@ bool BindListenPort(string& strError) return false; } -#if defined(__BSD__) || defined(__WXOSX__) +#if defined(__BSD__) || defined(__WXMAC_OSX__) // Different way of disabling SIGPIPE on BSD setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)); #endif diff --git a/noui.h b/noui.h new file mode 100644 index 00000000..45ef4bc9 --- /dev/null +++ b/noui.h @@ -0,0 +1,34 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +inline int MyMessageBox(const string& message, const string& caption="Message", int style=4, void* parent=NULL, int x=-1, int y=-1) +{ + printf("%s: %s\n", caption.c_str(), message.c_str()); + fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str()); + return 4; +} +#define wxMessageBox MyMessageBox + +inline int ThreadSafeMessageBox(const string& message, const string& caption, int style, void* parent, int x, int y) +{ + return MyMessageBox(message, caption, style, parent, x, y); +} + +inline bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, void* parent) +{ + return true; +} + +inline void CalledSetStatusBar(const string& strText, int nField) +{ +} + +inline void UIThreadCall(boost::function0 fn) +{ +} + +inline void MainFrameRepaint() +{ +} diff --git a/rpc.cpp b/rpc.cpp index ee5e8463..52bdece3 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -36,7 +36,7 @@ void PrintConsole(const char* format, ...) ret = limit - 1; buffer[limit-1] = 0; } -#if defined(__WXMSW__) && wxUSE_GUI +#if defined(__WXMSW__) && defined(GUI) MyMessageBox(buffer, "Bitcoin", wxOK | wxICON_EXCLAMATION); #else fprintf(stdout, "%s", buffer); @@ -1111,7 +1111,7 @@ int CommandLineRPC(int argc, char *argv[]) string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true)); if (result.type() != null_type) { -#if defined(__WXMSW__) && wxUSE_GUI +#if defined(__WXMSW__) && defined(GUI) // Windows GUI apps can't print to command line, // so settle for a message box yuck MyMessageBox(strResult.c_str(), "Bitcoin", wxOK); @@ -1122,7 +1122,7 @@ int CommandLineRPC(int argc, char *argv[]) return 0; } catch (std::exception& e) { -#if defined(__WXMSW__) && wxUSE_GUI +#if defined(__WXMSW__) && defined(GUI) MyMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK); #else fprintf(stderr, "error: %s\n", e.what()); diff --git a/serialize.h b/serialize.h index dd2127cf..7cf002e7 100644 --- a/serialize.h +++ b/serialize.h @@ -19,8 +19,8 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 303; -static const char* pszSubVer = ""; +static const int VERSION = 304; +static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index 0ba6a104..e457d10e 100644 --- a/ui.cpp +++ b/ui.cpp @@ -14,6 +14,7 @@ DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; bool fClosedToTray = false; +wxLocale g_locale; @@ -263,7 +264,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); ptaskbaricon = new CMyTaskBarIcon(); -#ifdef __WXMAC__ +#ifdef __WXMAC_OSX__ // Mac automatically moves wxID_EXIT, wxID_PREFERENCES and wxID_ABOUT // to their standard places, leaving these menus empty. GetMenuBar()->Remove(2); // remove Help menu @@ -274,7 +275,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) nDateWidth += 12; -#ifdef __WXMAC__ +#ifdef __WXMAC_OSX__ nDateWidth += 5; dResize -= 0.01; #endif @@ -1437,6 +1438,154 @@ void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) + +////////////////////////////////////////////////////////////////////////////// +// +// Startup folder +// + +#ifdef __WXMSW__ +string StartupShortcutPath() +{ + return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk"; +} + +bool GetStartOnSystemStartup() +{ + return filesystem::exists(StartupShortcutPath().c_str()); +} + +void SetStartOnSystemStartup(bool fAutoStart) +{ + // If the shortcut exists already, remove it for updating + remove(StartupShortcutPath().c_str()); + + if (fAutoStart) + { + CoInitialize(NULL); + + // Get a pointer to the IShellLink interface. + IShellLink* psl = NULL; + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, + CLSCTX_INPROC_SERVER, IID_IShellLink, + reinterpret_cast(&psl)); + + if (SUCCEEDED(hres)) + { + // Get the current executable path + TCHAR pszExePath[MAX_PATH]; + GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); + + // Set the path to the shortcut target + psl->SetPath(pszExePath); + PathRemoveFileSpec(pszExePath); + psl->SetWorkingDirectory(pszExePath); + psl->SetShowCmd(SW_SHOWMINNOACTIVE); + + // Query IShellLink for the IPersistFile interface for + // saving the shortcut in persistent storage. + IPersistFile* ppf = NULL; + hres = psl->QueryInterface(IID_IPersistFile, + reinterpret_cast(&ppf)); + if (SUCCEEDED(hres)) + { + WCHAR pwsz[MAX_PATH]; + // Ensure that the string is ANSI. + MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().c_str(), -1, pwsz, MAX_PATH); + // Save the link by calling IPersistFile::Save. + hres = ppf->Save(pwsz, TRUE); + ppf->Release(); + } + psl->Release(); + } + CoUninitialize(); + } +} + +#elif defined(__WXGTK__) + +// Follow the Desktop Application Autostart Spec: +// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html + +boost::filesystem::path GetAutostartDir() +{ + namespace fs = boost::filesystem; + + char* pszConfigHome = getenv("XDG_CONFIG_HOME"); + if (pszConfigHome) return fs::path(pszConfigHome) / fs::path("autostart"); + char* pszHome = getenv("HOME"); + if (pszHome) return fs::path(pszHome) / fs::path(".config/autostart"); + return fs::path(); +} + +boost::filesystem::path GetAutostartFilePath() +{ + return GetAutostartDir() / boost::filesystem::path("bitcoin.desktop"); +} + +bool GetStartOnSystemStartup() +{ + boost::filesystem::ifstream optionFile(GetAutostartFilePath()); + if (!optionFile.good()) + return false; + // Scan through file for "Hidden=true": + string line; + while (!optionFile.eof()) + { + getline(optionFile, line); + if (line.find("Hidden") != string::npos && + line.find("true") != string::npos) + return false; + } + optionFile.close(); + + return true; +} + +void SetStartOnSystemStartup(bool fAutoStart) +{ + if (!fAutoStart) + { + unlink(GetAutostartFilePath().native_file_string().c_str()); + } + else + { + boost::filesystem::create_directories(GetAutostartDir()); + + boost::filesystem::ofstream optionFile(GetAutostartFilePath(), ios_base::out|ios_base::trunc); + if (!optionFile.good()) + { + wxMessageBox(_("Cannot write autostart/bitcoin.desktop file"), "Bitcoin"); + return; + } + // Write a bitcoin.desktop file to the autostart directory: + char pszExePath[MAX_PATH+1]; + memset(pszExePath, 0, sizeof(pszExePath)); + readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1); + optionFile << "[Desktop Entry]\n"; + optionFile << "Type=Application\n"; + optionFile << "Name=Bitcoin\n"; + optionFile << "Exec=" << pszExePath << "\n"; + optionFile << "Terminal=false\n"; + optionFile << "Hidden=false\n"; + optionFile.close(); + } +} +#else + +// TODO: OSX startup stuff; see: +// http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html + +bool GetStartOnSystemStartup() { return false; } +void SetStartOnSystemStartup(bool fAutoStart) { } + +#endif + + + + + + ////////////////////////////////////////////////////////////////////////////// // // COptionsDialog @@ -1606,6 +1755,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) + ////////////////////////////////////////////////////////////////////////////// // // CAboutDialog @@ -2538,12 +2688,10 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu() - - - - - - +////////////////////////////////////////////////////////////////////////////// +// +// CMyApp +// void CreateMainWindow() { @@ -2561,3 +2709,189 @@ void CreateMainWindow() ptaskbaricon->Show(fMinimizeToTray || fClosedToTray); CreateThread(ThreadDelayedRepaint, NULL); } + + +// Define a new application +class CMyApp : public wxApp +{ +public: + CMyApp(){}; + ~CMyApp(){}; + bool OnInit(); + bool OnInit2(); + int OnExit(); + + // Hook Initialize so we can start without GUI + virtual bool Initialize(int& argc, wxChar** argv); + + // 2nd-level exception handling: we get all the exceptions occurring in any + // event handler here + virtual bool OnExceptionInMainLoop(); + + // 3rd, and final, level exception handling: whenever an unhandled + // exception is caught, this function is called + virtual void OnUnhandledException(); + + // and now for something different: this function is called in case of a + // crash (e.g. dereferencing null pointer, division by 0, ...) + virtual void OnFatalException(); +}; + +IMPLEMENT_APP(CMyApp) + +bool CMyApp::Initialize(int& argc, wxChar** argv) +{ + for (int i = 1; i < argc; i++) + if (!IsSwitchChar(argv[i][0])) + fCommandLine = true; + + if (!fCommandLine) + { + // wxApp::Initialize will remove environment-specific parameters, + // so it's too early to call ParseParameters yet + for (int i = 1; i < argc; i++) + { + wxString str = argv[i]; + #ifdef __WXMSW__ + if (str.size() >= 1 && str[0] == '/') + str[0] = '-'; + char pszLower[MAX_PATH]; + strlcpy(pszLower, str.c_str(), sizeof(pszLower)); + strlwr(pszLower); + str = pszLower; + #endif + if (str == "-daemon") + fDaemon = true; + } + } + +#ifdef __WXGTK__ + if (fDaemon || fCommandLine) + { + // Call the original Initialize while suppressing error messages + // and ignoring failure. If unable to initialize GTK, it fails + // near the end so hopefully the last few things don't matter. + { + wxLogNull logNo; + wxApp::Initialize(argc, argv); + } + + if (fDaemon) + { + // Daemonize + pid_t pid = fork(); + if (pid < 0) + { + fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); + return false; + } + if (pid > 0) + pthread_exit((void*)0); + } + + return true; + } +#endif + + return wxApp::Initialize(argc, argv); +} + +bool CMyApp::OnInit() +{ +#if defined(__WXMSW__) && defined(__WXDEBUG__) && defined(GUI) + // Disable malfunctioning wxWidgets debug assertion + extern int g_isPainting; + g_isPainting = 10000; +#endif +#ifdef GUI + wxImage::AddHandler(new wxPNGHandler); +#endif +#if defined(__WXMSW__ ) || defined(__WXMAC_OSX__) + SetAppName("Bitcoin"); +#else + SetAppName("bitcoin"); +#endif +#ifdef __WXMSW__ +#if wxUSE_UNICODE + // Hack to set wxConvLibc codepage to UTF-8 on Windows, + // may break if wxMBConv_win32 implementation in strconv.cpp changes. + class wxMBConv_win32 : public wxMBConv + { + public: + long m_CodePage; + size_t m_minMBCharWidth; + }; + if (((wxMBConv_win32*)&wxConvLibc)->m_CodePage == CP_ACP) + ((wxMBConv_win32*)&wxConvLibc)->m_CodePage = CP_UTF8; +#endif +#endif + + // Load locale//LC_MESSAGES/bitcoin.mo language file + g_locale.Init(wxLANGUAGE_DEFAULT, 0); + g_locale.AddCatalogLookupPathPrefix("locale"); +#ifndef __WXMSW__ + g_locale.AddCatalogLookupPathPrefix("/usr/share/locale"); + g_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale"); +#endif + g_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any + g_locale.AddCatalog("bitcoin"); + + return AppInit(argc, argv); +} + +int CMyApp::OnExit() +{ + Shutdown(NULL); + return wxApp::OnExit(); +} + +bool CMyApp::OnExceptionInMainLoop() +{ + try + { + throw; + } + catch (std::exception& e) + { + PrintException(&e, "CMyApp::OnExceptionInMainLoop()"); + wxLogWarning("Exception %s %s", typeid(e).name(), e.what()); + Sleep(1000); + throw; + } + catch (...) + { + PrintException(NULL, "CMyApp::OnExceptionInMainLoop()"); + wxLogWarning("Unknown exception"); + Sleep(1000); + throw; + } + return true; +} + +void CMyApp::OnUnhandledException() +{ + // this shows how we may let some exception propagate uncaught + try + { + throw; + } + catch (std::exception& e) + { + PrintException(&e, "CMyApp::OnUnhandledException()"); + wxLogWarning("Exception %s %s", typeid(e).name(), e.what()); + Sleep(1000); + throw; + } + catch (...) + { + PrintException(NULL, "CMyApp::OnUnhandledException()"); + wxLogWarning("Unknown exception"); + Sleep(1000); + throw; + } +} + +void CMyApp::OnFatalException() +{ + wxMessageBox(_("Program has crashed and will terminate. "), "Bitcoin", wxOK | wxICON_ERROR); +} diff --git a/ui.h b/ui.h index a59e4326..1fb6f265 100644 --- a/ui.h +++ b/ui.h @@ -4,24 +4,9 @@ DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) -#if wxUSE_GUI -static const bool fGUI=true; -#else -static const bool fGUI=false; -#endif -inline int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1) -{ -#if wxUSE_GUI - if (!fDaemon) - return wxMessageBox(message, caption, style, parent, x, y); -#endif - printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str()); - fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str()); - return wxOK; -} -#define wxMessageBox MyMessageBox +extern wxLocale g_locale; @@ -33,38 +18,23 @@ bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* pa void CalledSetStatusBar(const string& strText, int nField); void MainFrameRepaint(); void CreateMainWindow(); +void SetStartOnSystemStartup(bool fAutoStart); - -#if !wxUSE_GUI -inline int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) -{ - return MyMessageBox(message, caption, style, parent, x, y); -} - -inline bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent) -{ - return true; -} - -inline void CalledSetStatusBar(const string& strText, int nField) -{ -} - -inline void UIThreadCall(boost::function0 fn) -{ -} - -inline void MainFrameRepaint() +inline int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1) { +#ifdef GUI + if (!fDaemon) + return wxMessageBox(message, caption, style, parent, x, y); +#endif + printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str()); + fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str()); + return wxOK; } +#define wxMessageBox MyMessageBox -inline void CreateMainWindow() -{ -} -#else // wxUSE_GUI @@ -334,11 +304,10 @@ public: m_textCtrl2->SetValue(strValue2); y += 46 + wxString(strMessage2).Freq('\n') * 14; } - if (!fWindows) - { - x *= 1.14; - y *= 1.14; - } +#ifndef __WXMSW__ + x *= 1.14; + y *= 1.14; +#endif SetSize(x, y); } @@ -375,5 +344,3 @@ public: DECLARE_EVENT_TABLE() }; - -#endif // wxUSE_GUI diff --git a/util.cpp b/util.cpp index 5d3728a1..7cb6600f 100644 --- a/util.cpp +++ b/util.cpp @@ -134,7 +134,7 @@ uint64 GetRand(uint64 nMax) inline int OutputDebugStringF(const char* pszFormat, ...) { int ret = 0; - if (fPrintToConsole || wxTheApp == NULL) + if (fPrintToConsole) { // print to console va_list arg_ptr; @@ -441,6 +441,7 @@ void ParseParameters(int argc, char* argv[]) const char* wxGetTranslation(const char* pszEnglish) { +#ifdef GUI // Wrapper of wxGetTranslation returning the same const char* type as was passed in static CCriticalSection cs; CRITICAL_BLOCK(cs) @@ -467,6 +468,9 @@ const char* wxGetTranslation(const char* pszEnglish) return pszCached; } return NULL; +#else + return pszEnglish; +#endif } @@ -485,8 +489,6 @@ void FormatException(char* pszMessage, std::exception* pex, const char* pszThrea pszModule[0] = '\0'; GetModuleFileNameA(NULL, pszModule, sizeof(pszModule)); #else - // might not be thread safe, uses wxString - //const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str(); const char* pszModule = "bitcoin"; #endif if (pex) @@ -510,8 +512,10 @@ void PrintException(std::exception* pex, const char* pszThread) FormatException(pszMessage, pex, pszThread); printf("\n\n************************\n%s\n", pszMessage); fprintf(stderr, "\n\n************************\n%s\n", pszMessage); - if (wxTheApp && !fDaemon && fGUI) +#ifdef GUI + if (wxTheApp && !fDaemon) MyMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); +#endif throw; //DebugBreak(); } @@ -574,10 +578,10 @@ string GetDefaultDataDir() string strHome = pszHome; if (strHome[strHome.size()-1] != '/') strHome += '/'; -#ifdef __WXOSX__ +#ifdef __WXMAC_OSX__ // Mac strHome += "Library/Application Support/"; - _mkdir(strHome.c_str()); + filesystem::create_directory(strHome.c_str()); return strHome + "Bitcoin"; #else // Unix @@ -596,7 +600,7 @@ void GetDataDir(char* pszDir) if (!fMkdirDone) { fMkdirDone = true; - _mkdir(pszDir); + filesystem::create_directory(pszDir); } } else @@ -606,9 +610,8 @@ void GetDataDir(char* pszDir) static char pszCachedDir[MAX_PATH]; if (pszCachedDir[0] == 0) { - //strlcpy(pszCachedDir, wxStandardPaths::Get().GetUserDataDir().c_str(), sizeof(pszCachedDir)); strlcpy(pszCachedDir, GetDefaultDataDir().c_str(), sizeof(pszCachedDir)); - _mkdir(pszCachedDir); + filesystem::create_directory(pszCachedDir); } strlcpy(pszDir, pszCachedDir, MAX_PATH); } diff --git a/util.h b/util.h index 49e38630..366c0e15 100644 --- a/util.h +++ b/util.h @@ -55,7 +55,6 @@ inline T& REF(const T& val) } #ifdef __WXMSW__ -static const bool fWindows = true; #define MSG_NOSIGNAL 0 #define MSG_DONTWAIT 0 #ifndef UINT64_MAX @@ -70,7 +69,6 @@ static const bool fWindows = true; #define unlink _unlink typedef int socklen_t; #else -static const bool fWindows = false; #define WSAGetLastError() errno #define WSAEWOULDBLOCK EWOULDBLOCK #define WSAEMSGSIZE EMSGSIZE @@ -84,10 +82,12 @@ 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 void Sleep(int64 n) +{ + boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(n)); +} #endif inline int myclosesocket(SOCKET& hSocket) @@ -104,6 +104,13 @@ inline int myclosesocket(SOCKET& hSocket) } #define closesocket(s) myclosesocket(s) +#ifndef GUI +inline const char* _(const char* psz) +{ + return psz; +} +#endif +