From 8269a0953ee9ccbdc422433fc37184e60f94b178 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Mon, 11 Feb 2013 18:52:30 -0500 Subject: Reimplement click-to-pay links. Add OSX support. Switch to using Qt's QLocalServer/QLocalSocket to handle bitcoin payment links (bitcoin:... URIs) Reason for switch: the boost::interprocess mechanism seemed flaky, and doesn't mesh as well with "The Qt Way" qtipcserver.cpp/h is replaced by paymentserver.cpp/h Click-to-pay now also works on OSX, with a custom Info.plist that registers Bitcoin-Qt as a handler for bitcoin: URLs and an event listener on the main QApplication that handles QFileOpenEvents (Qt translates 'url clicked' AppleEvents into QFileOpenEvents automagically). --- src/qt/qtipcserver.cpp | 165 ------------------------------------------------- 1 file changed, 165 deletions(-) delete mode 100644 src/qt/qtipcserver.cpp (limited to 'src/qt/qtipcserver.cpp') diff --git a/src/qt/qtipcserver.cpp b/src/qt/qtipcserver.cpp deleted file mode 100644 index 2777fab852..0000000000 --- a/src/qt/qtipcserver.cpp +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (c) 2009-2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#if defined(WIN32) && BOOST_VERSION == 104900 -#define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME -#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME -#endif - -#include "qtipcserver.h" -#include "guiconstants.h" -#include "ui_interface.h" -#include "util.h" - -#include -#include -#include -#include - -#if defined(WIN32) && (!defined(BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME) || !defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME) || BOOST_VERSION < 104900) -#warning Compiling without BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME and BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME uncommented in boost/interprocess/detail/tmp_dir_helpers.hpp or using a boost version before 1.49 may have unintended results see svn.boost.org/trac/boost/ticket/5392 -#endif - -using namespace boost; -using namespace boost::interprocess; -using namespace boost::posix_time; - -// holds Bitcoin-Qt message queue name (initialized in bitcoin.cpp) -std::string strBitcoinURIQueueName; - -#if defined MAC_OSX || defined __FreeBSD__ -// URI handling not implemented on OSX yet - -void ipcScanRelay(int argc, char *argv[]) { } -void ipcInit(int argc, char *argv[]) { } - -#else - -static void ipcThread2(void* pArg); - -static bool ipcScanCmd(int argc, char *argv[], bool fRelay) -{ - // Check for URI in argv - bool fSent = false; - for (int i = 1; i < argc; i++) - { - if (boost::algorithm::istarts_with(argv[i], "bitcoin:")) - { - const char *strURI = argv[i]; - try { - boost::interprocess::message_queue mq(boost::interprocess::open_only, strBitcoinURIQueueName.c_str()); - if (mq.try_send(strURI, strlen(strURI), 0)) - fSent = true; - else if (fRelay) - break; - } - catch (boost::interprocess::interprocess_exception &ex) { - // don't log the "file not found" exception, because that's normal for - // the first start of the first instance - if (ex.get_error_code() != boost::interprocess::not_found_error || !fRelay) - { - printf("main() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what()); - break; - } - } - } - } - return fSent; -} - -void ipcScanRelay(int argc, char *argv[]) -{ - if (ipcScanCmd(argc, argv, true)) - exit(0); -} - -static void ipcThread(void* pArg) -{ - // Make this thread recognisable as the GUI-IPC thread - RenameThread("bitcoin-gui-ipc"); - - try - { - ipcThread2(pArg); - } - catch (std::exception& e) { - PrintExceptionContinue(&e, "ipcThread()"); - } catch (...) { - PrintExceptionContinue(NULL, "ipcThread()"); - } - printf("ipcThread exited\n"); -} - -static void ipcThread2(void* pArg) -{ - printf("ipcThread started\n"); - - message_queue* mq = (message_queue*)pArg; - char buffer[MAX_URI_LENGTH + 1] = ""; - size_t nSize = 0; - unsigned int nPriority = 0; - - loop - { - ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(100); - if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d)) - { - uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize)); - Sleep(1000); - } - - if (fShutdown) - break; - } - - // Remove message queue - message_queue::remove(strBitcoinURIQueueName.c_str()); - // Cleanup allocated memory - delete mq; -} - -void ipcInit(int argc, char *argv[]) -{ - message_queue* mq = NULL; - char buffer[MAX_URI_LENGTH + 1] = ""; - size_t nSize = 0; - unsigned int nPriority = 0; - - try { - mq = new message_queue(open_or_create, strBitcoinURIQueueName.c_str(), 2, MAX_URI_LENGTH); - - // Make sure we don't lose any bitcoin: URIs - for (int i = 0; i < 2; i++) - { - ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(1); - if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d)) - { - uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize)); - } - else - break; - } - - // Make sure only one bitcoin instance is listening - message_queue::remove(strBitcoinURIQueueName.c_str()); - delete mq; - - mq = new message_queue(open_or_create, strBitcoinURIQueueName.c_str(), 2, MAX_URI_LENGTH); - } - catch (interprocess_exception &ex) { - printf("ipcInit() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what()); - return; - } - - if (!NewThread(ipcThread, mq)) - { - delete mq; - return; - } - - ipcScanCmd(argc, argv, false); -} - -#endif -- cgit v1.2.3