Satoshi MailBeta Open in Satoshi Mail

GUI-less build target bitcoind that links to wxBase and shouldn't need GTK, split init and shutdown from ui.cpp into init.cpp, support wxUSE_GUI=0 -- version 0.2.7

Commit by Satoshi Nakamoto (s_nakamoto) on 25 February 2010 · SVN r71 · release v0.2.7 · 13 files, +817 −773

Open in Satoshi Mail View on GitHub

Files changed

headers.h
@@ -21,9 +21,11 @@
 #include <wx/wx.h>
 #include <wx/clipbrd.h>
 #include <wx/snglinst.h>
-#include <wx/taskbar.h>
 #include <wx/stdpaths.h>
 #include <wx/utils.h>
+#if wxUSE_GUI
+#include <wx/taskbar.h>
+#endif
 #include <openssl/ecdsa.h>
 #include <openssl/evp.h>
 #include <openssl/rand.h>
@@ -100,8 +102,11 @@ using namespace boost;
 #include "irc.h"
 #include "main.h"
 #include "rpc.h"
+#if wxUSE_GUI
 #include "uibase.h"
+#endif
 #include "ui.h"
+#include "init.h"
 
 #include "xpm/addressbook16.xpm"
 #include "xpm/addressbook20.xpm"
init.cpp
@@ -0,0 +1,625 @@
+// Copyright (c) 2009-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.
+
+#include "headers.h"
+
+
+
+
+void ExitTimeout(void* parg)
+{
+#ifdef __WXMSW__
+    Sleep(5000);
+    ExitProcess(0);
+#endif
+}
+
+void Shutdown(void* parg)
+{
+    static CCriticalSection cs_Shutdown;
+    static bool fTaken;
+    bool fFirstThread;
+    CRITICAL_BLOCK(cs_Shutdown)
+    {
+        fFirstThread = !fTaken;
+        fTaken = true;
+    }
+    static bool fExit;
+    if (fFirstThread)
+    {
+        fShutdown = true;
+        nTransactionsUpdated++;
+        DBFlush(false);
+        StopNode();
+        DBFlush(true);
+        CreateThread(ExitTimeout, NULL);
+        Sleep(50);
+        printf("Bitcoin exiting\n\n");
+        fExit = true;
+        exit(0);
+    }
+    else
+    {
+        while (!fExit)
+            Sleep(500);
+        Sleep(100);
+        ExitThread(0);
+    }
+}
+
+
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Startup folder
+//
+
+#ifdef __WXMSW__
+typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
+
+string MyGetSpecialFolderPath(int nFolder, bool fCreate)
+{
+    char pszPath[MAX_PATH+100] = "";
+
+    // SHGetSpecialFolderPath is not usually available on NT 4.0
+    HMODULE hShell32 = LoadLibraryA("shell32.dll");
+    if (hShell32)
+    {
+        PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath =
+            (PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA");
+        if (pSHGetSpecialFolderPath)
+            (*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate);
+        FreeModule(hShell32);
+    }
+
+    // Backup option
+    if (pszPath[0] == '\0')
+    {
+        if (nFolder == CSIDL_STARTUP)
+        {
+            strcpy(pszPath, getenv("USERPROFILE"));
+            strcat(pszPath, "\\Start Menu\\Programs\\Startup");
+        }
+        else if (nFolder == CSIDL_APPDATA)
+        {
+            strcpy(pszPath, getenv("APPDATA"));
+        }
+    }
+
+    return pszPath;
+}
+
+string StartupShortcutPath()
+{
+    return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk";
+}
+
+bool GetStartOnSystemStartup()
+{
+    return wxFileExists(StartupShortcutPath());
+}
+
+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<void**>(&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<void**>(&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();
+    }
+}
+#else
+bool GetStartOnSystemStartup() { return false; }
+void SetStartOnSystemStartup(bool fAutoStart) { }
+#endif
+
+
+
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// CMyApp
+//
+
+// 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)
+{
+    if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') &&
+        wxString(argv[1]) != "start")
+    {
+        fCommandLine = true;
+    }
+    else 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] = '-';
+            str = str.MakeLower();
+            #endif
+            // haven't decided which argument to use for this yet
+            if (str == "-daemon" || str == "-d" || str == "start")
+                fDaemon = true;
+        }
+    }
+
+    if (fDaemon)
+        fprintf(stdout, "bitcoin server starting\n");
+
+#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()
+{
+    bool fRet = false;
+    try
+    {
+        fRet = OnInit2();
+    }
+    catch (std::exception& e) {
+        PrintException(&e, "OnInit()");
+    } catch (...) {
+        PrintException(NULL, "OnInit()");
+    }
+    if (!fRet)
+        Shutdown(NULL);
+    return fRet;
+}
+
+extern int g_isPainting;
+
+bool CMyApp::OnInit2()
+{
+#ifdef _MSC_VER
+    // Turn off microsoft heap dump noise
+    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
+    _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
+#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
+#ifdef __WXMSW__
+    SetAppName("Bitcoin");
+#else
+    SetAppName("bitcoin");
+    umask(077);
+#endif
init.h
@@ -0,0 +1,7 @@
+// Copyright (c) 2009-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.
+
+void Shutdown(void* parg);
+bool GetStartOnSystemStartup();
+void SetStartOnSystemStartup(bool fAutoStart);
main.cpp
@@ -55,6 +55,8 @@ int64 nTransactionFee = 0;
 CAddress addrIncoming;
 int fLimitProcessors = false;
 int nLimitProcessors = 1;
+int fMinimizeToTray = true;
+int fMinimizeOnClose = true;
 
 
 
@@ -2990,7 +2992,7 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx
     if (nValue <= 0)
         return _("Invalid amount");
     if (nValue + nTransactionFee > GetBalance())
-        return _("You don't have enough money");
+        return _("Insufficient funds");
 
     // Parse bitcoin address
     CScript scriptPubKey;
main.h
@@ -45,6 +45,8 @@ extern int64 nTransactionFee;
 extern CAddress addrIncoming;
 extern int fLimitProcessors;
 extern int nLimitProcessors;
+extern int fMinimizeToTray;
+extern int fMinimizeOnClose;
 
 
 
makefile.mingw
@@ -18,69 +18,59 @@ LIBPATHS= \
  -L"/openssl/out" \
  -L"/wxwidgets/lib/gcc_lib"
 
+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 db_cxx \
  -l eay32 \
- -l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd \
  -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
 DEBUGFLAGS=-g -D__WXDEBUG__
 CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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
-
+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
 
 
 all: bitcoin.exe
 
 
-headers.h.gch: headers.h            $(HEADERS)
-	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)
-	g++ -c $(CFLAGS) -o $@ $<
-
-obj/net.o: net.cpp                  $(HEADERS)
-	g++ -c $(CFLAGS) -o $@ $<
-
-obj/main.o: main.cpp                $(HEADERS) sha.h
+headers.h.gch: headers.h $(HEADERS)
 	g++ -c $(CFLAGS) -o $@ $<
 
-obj/ui.o: ui.cpp                    $(HEADERS)
+obj/%.o: %.cpp $(HEADERS) headers.h.gch
 	g++ -c $(CFLAGS) -o $@ $<
 
-obj/uibase.o: uibase.cpp            uibase.h
-	g++ -c $(CFLAGS) -o $@ $<
-
-obj/sha.o: sha.cpp                  sha.h
+obj/sha.o: sha.cpp sha.h
 	g++ -c $(CFLAGS) -O3 -o $@ $<
 
-obj/irc.o: irc.cpp                  $(HEADERS)
-	g++ -c $(CFLAGS) -o $@ $<
-
-obj/rpc.o: rpc.cpp                  $(HEADERS)
-	g++ -c $(CFLAGS) -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 $<
 
+OBJS= \
+    obj/util.o \
+    obj/script.o \
+    obj/db.o \
+    obj/net.o \
+    obj/irc.o \
+    obj/main.o \
+    obj/rpc.o \
+    obj/init.o
+
+bitcoin.exe: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o obj/ui_res.o
+	g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
+
 
+obj/nogui/%.o: %.cpp $(HEADERS)
+	g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $<
 
-OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \
-        obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \
-        obj/ui_res.o
+bitcoind.exe: $(OBJS:obj/%=obj/nogui/%) obj/sha.o obj/ui_res.o
+	g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wxbase29ud $(LIBS)
 
-bitcoin.exe: headers.h.gch $(OBJS)
-	-kill /f bitcoin.exe
-	g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS)
 
 clean:
 	-del /Q obj\*
+	-del /Q obj\nogui\*
 	-del /Q headers.h.gch
makefile.unix
@@ -13,66 +13,61 @@ LIBPATHS= \
  -L"/usr/lib" \
  -L"/usr/local/lib"
 
+WXLIBS= \
+ -Wl,-Bstatic \
+   -l wx_gtk2ud-2.9 \
+ -Wl,-Bdynamic \
+   -l gtk-x11-2.0 -l SM
+
 LIBS= \
  -Wl,-Bstatic \
    -l boost_system-mt -l boost_filesystem-mt \
    -l db_cxx \
-   -l wx_gtk2ud-2.9 \
  -Wl,-Bdynamic \
    -l crypto \
-   -l gtk-x11-2.0 -l gthread-2.0 -l SM
+   -l gthread-2.0
 
 WXDEFS=-D__WXGTK__ -DNOPCH
 DEBUGFLAGS=-g -D__WXDEBUG__
 CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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
-
+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
 
 
 all: bitcoin
 
 
-headers.h.gch: headers.h            $(HEADERS)
-	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)
-	g++ -c $(CFLAGS) -o $@ $<
-
-obj/net.o: net.cpp                  $(HEADERS)
-	g++ -c $(CFLAGS) -o $@ $<
-
-obj/main.o: main.cpp                $(HEADERS) sha.h
-	g++ -c $(CFLAGS) -o $@ $<
-
-obj/ui.o: ui.cpp                    $(HEADERS)
+headers.h.gch: headers.h $(HEADERS)
 	g++ -c $(CFLAGS) -o $@ $<
 
-obj/uibase.o: uibase.cpp            uibase.h
+obj/%.o: %.cpp $(HEADERS) headers.h.gch
 	g++ -c $(CFLAGS) -o $@ $<
 
-obj/sha.o: sha.cpp                  sha.h
+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/irc.o \
+    obj/main.o \
+    obj/rpc.o \
+    obj/init.o
 
-obj/rpc.o: rpc.cpp                  $(HEADERS)
-	g++ -c $(CFLAGS) -o $@ $<
+bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o
+	g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
 
 
+obj/nogui/%.o: %.cpp $(HEADERS)
+	g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $<
 
-OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \
-        obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o
+bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o
+	g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wx_baseud-2.9 $(LIBS)
 
-bitcoin: headers.h.gch $(OBJS)
-	g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS)
 
 clean:
 	-rm obj/*
+	-rm obj/nogui/*
 	-rm headers.h.gch
makefile.vc
@@ -28,57 +28,80 @@ LIBS= \
 WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH
 DEBUGFLAGS=/Zi /Od /D__WXDEBUG__
 CFLAGS=/c /nologo /Ob0 /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(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
-
+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
 
 
 all: bitcoin.exe
 
 
-obj\util.obj: util.cpp        $(HEADERS)
-    cl $(CFLAGS) /Fo$@ %s
+.cpp{obj}.obj:
+	cl $(CFLAGS) /Fo$@ %s
+
+obj\util.obj: $(HEADERS)
 
-obj\script.obj: script.cpp    $(HEADERS)
-    cl $(CFLAGS) /Fo$@ %s
+obj\script.obj: $(HEADERS)
 
-obj\db.obj: db.cpp            $(HEADERS)
-    cl $(CFLAGS) /Fo$@ %s
+obj\db.obj: $(HEADERS)
 
-obj\net.obj: net.cpp          $(HEADERS)
-    cl $(CFLAGS) /Fo$@ %s
+obj\net.obj: $(HEADERS)
 
-obj\main.obj: main.cpp        $(HEADERS) sha.h
-    cl $(CFLAGS) /Fo$@ %s
+obj\irc.obj: $(HEADERS)
 
-obj\ui.obj: ui.cpp            $(HEADERS)
-    cl $(CFLAGS) /Fo$@ %s
+obj\main.obj: $(HEADERS)
 
-obj\uibase.obj: uibase.cpp    uibase.h
-    cl $(CFLAGS) /Fo$@ %s
+obj\rpc.obj: $(HEADERS)
 
-obj\sha.obj: sha.cpp          sha.h
-    cl $(CFLAGS) /O2 /Fo$@ %s
+obj\init.obj: $(HEADERS)
 
-obj\irc.obj:  irc.cpp         $(HEADERS)
-    cl $(CFLAGS) /Fo$@ %s
+obj\ui.obj: $(HEADERS)
 
-obj\rpc.obj:  rpc.cpp         $(HEADERS)
-    cl $(CFLAGS) /Fo$@ %s
+obj\uibase.obj: $(HEADERS)
+
+obj\sha.obj: sha.cpp sha.h
+	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) $(WXDEFS) /Fo$@ %s
+
+OBJS= \
+    obj\util.obj \
+    obj\script.obj \
+    obj\db.obj \
+    obj\net.obj \
+    obj\irc.obj \
+    obj\main.obj \
+    obj\rpc.obj \
+    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)
+
+
+.cpp{obj\nogui}.obj:
+	cl $(CFLAGS) /DwxUSE_GUI=0 /Fo$@ %s
+
+obj\nogui\util.obj: $(HEADERS)
+
+obj\nogui\script.obj: $(HEADERS)
+
+obj\nogui\db.obj: $(HEADERS)
+
+obj\nogui\net.obj: $(HEADERS)
+
+obj\nogui\irc.obj: $(HEADERS)
+
+obj\nogui\main.obj: $(HEADERS)
 
+obj\nogui\rpc.obj: $(HEADERS)
 
+obj\nogui\init.obj: $(HEADERS)
 
-OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj \
-    obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\rpc.obj \
-    obj\ui.res
+bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\sha.obj obj\ui.res
+	link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS)
 
-bitcoin.exe: $(OBJS)
-    -kill /f bitcoin.exe & sleep 1
-    link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS)
 
 clean:
-    -del /Q obj\*
-    -del *.ilk
-    -del *.pdb
+	-del /Q obj\*
+	-del *.ilk
+	-del *.pdb
rpc.cpp
@@ -676,18 +676,18 @@ 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 (fWindows)
+            if (fWindows && fGUI)
                 // Windows GUI apps can't print to command line,
-                // so for now settle for a message box yuck
-                wxMessageBox(strResult.c_str(), "Bitcoin", wxOK);
+                // so settle for a message box yuck
+                MyMessageBox(strResult.c_str(), "Bitcoin", wxOK);
             else
                 fprintf(stdout, "%s\n", strResult.c_str());
         }
         return 0;
     }
     catch (std::exception& e) {
-        if (fWindows)
-            wxMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK);
+        if (fWindows && fGUI)
+            MyMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK);
         else
             fprintf(stderr, "error: %s\n", e.what());
     } catch (...) {
serialize.h
@@ -19,7 +19,7 @@ class CScript;
 class CDataStream;
 class CAutoFile;
 
-static const int VERSION = 206;
+static const int VERSION = 207;
 static const char* pszSubVer = ".0";
 
 
ui.cpp
@@ -7,38 +7,18 @@
 #include <crtdbg.h>
 #endif
 
-bool GetStartOnSystemStartup();
-void SetStartOnSystemStartup(bool fAutoStart);
-
 
 
 DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL)
 
 CMainFrame* pframeMain = NULL;
 CMyTaskBarIcon* ptaskbaricon = NULL;
-extern int g_isPainting;
 bool fClosedToTray = false;
 
-// Settings
-int fMinimizeToTray = true;
-int fMinimizeOnClose = true;
 
 
 
 
-int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
-{
-    if (fDaemon)
-    {
-        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;
-    }
-    return wxMessageBox(message, caption, style, parent, x, y);
-}
-#define wxMessageBox  MyMessageBox
-
-
 
 
 
@@ -48,47 +28,6 @@ int MyMessageBox(const wxString& message, const wxString& caption="Message", int
 // Util
 //
 
-void ExitTimeout(void* parg)
-{
-#ifdef __WXMSW__
-    Sleep(5000);
-    ExitProcess(0);
-#endif
-}
-
-void Shutdown(void* parg)
-{
-    static CCriticalSection cs_Shutdown;
-    static bool fTaken;
-    bool fFirstThread;
-    CRITICAL_BLOCK(cs_Shutdown)
-    {
-        fFirstThread = !fTaken;
-        fTaken = true;
-    }
-    static bool fExit;
-    if (fFirstThread)
-    {
-        fShutdown = true;
-        nTransactionsUpdated++;
-        DBFlush(false);
-        StopNode();
-        DBFlush(true);
-        CreateThread(ExitTimeout, NULL);
-        Sleep(50);
-        printf("Bitcoin exiting\n\n");
-        fExit = true;
-        exit(0);
-    }
-    else
-    {
-        while (!fExit)
-            Sleep(500);
-        Sleep(100);
-        ExitThread(0);
-    }
-}
-
 void HandleCtrlA(wxKeyEvent& event)
 {
     // Ctrl-a select all
@@ -312,7 +251,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
     m_staticTextBalance->SetSize(140, 17);
     // resize to fit ubuntu's huge default font
     dResize = 1.22;
-    SetSize(dResize * GetSize().GetWidth(), 1.09 * GetSize().GetHeight());
+    SetSize(dResize * GetSize().GetWidth(), 1.15 * GetSize().GetHeight());
 #endif
     m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + "  ");
     m_listCtrl->SetFocus();
@@ -1630,7 +1569,6 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event)
 
 
 
-
 //////////////////////////////////////////////////////////////////////////////
 //
 // CAboutDialog
@@ -2014,7 +1952,7 @@ void CSendingDialog::StartTransfer()
     // Make sure we have enough money
     if (nPrice + nTransactionFee > GetBalance())
     {
-        Error(_("You don't have enough money"));
+        Error(_("Insufficient funds"));
         return;
     }
 
@@ -2081,7 +2019,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
             return;
         if (nPrice + nTransactionFee > GetBalance())
         {
-            Error(_("You don't have enough money"));
+            Error(_("Insufficient funds"));
             return;
         }
         CKey key;
@@ -2562,602 +2500,21 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu()
 
 
 
-//////////////////////////////////////////////////////////////////////////////
-//
-// CMyApp
-//
-
-// 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)
-{
-    if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') &&
-        wxString(argv[1]) != "start")
-    {
-        fCommandLine = 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] = '-';
-            str = str.MakeLower();
-            #endif
-            // haven't decided which argument to use for this yet
-            if (str == "-daemon" || str == "-d" || str == "start")
-                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)
-        {
-            fprintf(stdout, "bitcoin server starting\n");
-
-            // 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()
-{
-    bool fRet = false;
-    try
-    {
-        fRet = OnInit2();
-    }
-    catch (std::exception& e) {
-        PrintException(&e, "OnInit()");
-    } catch (...) {
-        PrintException(NULL, "OnInit()");
-    }
-    if (!fRet)
-        Shutdown(NULL);
-    return fRet;
-}
-
-bool CMyApp::OnInit2()
-{
-#ifdef _MSC_VER
-    // Turn off microsoft heap dump noise
-    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
-    _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
-#endif
-#if defined(__WXMSW__) && defined(__WXDEBUG__)
-    // Disable malfunctioning wxWidgets debug assertion
-    g_isPainting = 10000;
-#endif
-    wxImage::AddHandler(new wxPNGHandler);
-#ifdef __WXMSW__
-    SetAppName("Bitcoin");
-#else
-    SetAppName("bitcoin");
-    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/<lang>/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
-    //
-    if (fCommandLine)
-    {
-        int ret = CommandLineRPC(argc, argv);
-        exit(ret);
-    }
-
-    ParseParameters(argc, argv);
-    if (mapArgs.count("-?") || mapArgs.count("--help"))
-    {
-        wxString strUsage = string() +
-            _("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" +
-            _("Options:\n") +
-            "  -gen            \t\t  " + _("Generate coins\n") +
-            "  -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") +
ui.h
@@ -4,26 +4,61 @@
 
 DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1)
 
+#if wxUSE_GUI
+static const bool fGUI=true;
+#else
+static const bool fGUI=false;
+#endif
 
-extern map<string, string> mapArgs;
+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
 
-// Settings
-extern int fMinimizeToTray;
-extern int fMinimizeOnClose;
 
 
 
 void HandleCtrlA(wxKeyEvent& event);
 string FormatTxStatus(const CWalletTx& wtx);
 void UIThreadCall(boost::function0<void>);
-void MainFrameRepaint();
-void Shutdown(void* parg);
 int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1);
 bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent);
+void MainFrameRepaint();
+void CreateMainWindow();
+
 
 
 
 
+#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 MainFrameRepaint()
+{
+}
+
+inline void CreateMainWindow()
+{
+}
+#else // wxUSE_GUI
+
+
+
 
 
 class CMainFrame : public CMainFrameBase
@@ -331,3 +366,5 @@ public:
 
 DECLARE_EVENT_TABLE()
 };
+
+#endif // wxUSE_GUI
util.cpp
@@ -459,6 +459,7 @@ const char* wxGetTranslation(const char* pszEnglish)
         mapCache[pszEnglish] = pszCached;
         return pszCached;
     }
+    return NULL;
 }
 
 
@@ -502,8 +503,8 @@ 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)
-        wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
+    if (wxTheApp && !fDaemon && fGUI)
+        MyMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
     throw;
     //DebugBreak();
 }