<commit_before>#include <boost/test/unit_test.hpp>

#include "distribution.h"
#include "json/json_spirit_utils.h"

using namespace std;
using namespace json_spirit;

BOOST_AUTO_TEST_SUITE(distribution_tests)

#define PRECISION 1e-8

BOOST_AUTO_TEST_CASE( test_simple_distribution )
{
    BalanceMap mapBalance;

    mapBalance[CBitcoinAddress(1)] = 10;
    mapBalance[CBitcoinAddress(2)] = 30;

    DividendDistributor distributor(mapBalance);
    distributor.Distribute(100, 0.01);

    BOOST_CHECK_EQUAL(25.0, distributor.GetDistribution(CBitcoinAddress(1)).GetDividendAmount());
    BOOST_CHECK_EQUAL(75.0, distributor.GetDistribution(CBitcoinAddress(2)).GetDividendAmount());
    BOOST_CHECK_EQUAL(100.0, distributor.TotalDistributed());

    vector<Object> vTransactionOuts;
    distributor.GenerateOutputs(1, vTransactionOuts);

    BOOST_CHECK_EQUAL(1, vTransactionOuts.size());

    Object& outs = *vTransactionOuts.begin();
    BOOST_CHECK_CLOSE(25.0, find_value(outs, CPeercoinAddress(1).ToString()).get_real(), PRECISION);
    BOOST_CHECK_CLOSE(75.0, find_value(outs, CPeercoinAddress(2).ToString()).get_real(), PRECISION);
}

BOOST_AUTO_TEST_CASE( test_empty_distribution )
{
    BalanceMap mapBalance;

    DividendDistributor distributor(mapBalance);
    BOOST_CHECK_THROW(distributor.Distribute(100, 0.01), runtime_error);
}

BOOST_AUTO_TEST_CASE( test_off_decimal_distribution )
{
    BalanceMap mapBalance;

    mapBalance[CBitcoinAddress(1)] = 1;
    mapBalance[CBitcoinAddress(2)] = 1;
    mapBalance[CBitcoinAddress(3)] = 1;

    DividendDistributor distributor(mapBalance);
    distributor.Distribute(10, 1);

    BOOST_CHECK_CLOSE(3.3333333333, distributor.GetDistribution(CBitcoinAddress(1)).GetDividendAmount(), PRECISION);
    BOOST_CHECK_CLOSE(3.3333333333, distributor.GetDistribution(CBitcoinAddress(2)).GetDividendAmount(), PRECISION);
    BOOST_CHECK_CLOSE(3.3333333333, distributor.GetDistribution(CBitcoinAddress(3)).GetDividendAmount(), PRECISION);
    BOOST_CHECK_CLOSE(10.0, distributor.TotalDistributed(), PRECISION);
}

BOOST_AUTO_TEST_CASE( test_not_enough_dividends_to_pay_fee )
{
    BalanceMap mapBalance;

    mapBalance[CBitcoinAddress(1)] = 90;
    mapBalance[CBitcoinAddress(2)] = 10;

    DividendDistributor distributor(mapBalance);
    distributor.Distribute(0.1, 0.010001);

    BOOST_CHECK_CLOSE(0.1, distributor.GetDistribution(CBitcoinAddress(1)).GetDividendAmount(), PRECISION);
    BOOST_CHECK_EQUAL(1, distributor.GetDistributions().size());
    BOOST_CHECK_CLOSE(0.1, distributor.TotalDistributed(), PRECISION);

    distributor.Distribute(0.1, 0.01);

    BOOST_CHECK_CLOSE(0.09, distributor.GetDistribution(CBitcoinAddress(1)).GetDividendAmount(), PRECISION);
    BOOST_CHECK_CLOSE(0.01, distributor.GetDistribution(CBitcoinAddress(2)).GetDividendAmount(), PRECISION);
    BOOST_CHECK_CLOSE(0.10, distributor.TotalDistributed(), PRECISION);
}

BOOST_AUTO_TEST_CASE( test_nobody_has_enough_funds )
{
    BalanceMap mapBalance;

    mapBalance[CBitcoinAddress(1)] = 1;
    mapBalance[CBitcoinAddress(2)] = 1;

    DividendDistributor distributor(mapBalance);

    BOOST_CHECK_THROW(distributor.Distribute(20000, 10001), runtime_error);

    BOOST_CHECK_EQUAL(0, distributor.GetDistributions().size());

    BOOST_CHECK_EQUAL(0, distributor.TotalDistributed());
}

BOOST_AUTO_TEST_CASE( test_split_transaction )
{
    BalanceMap mapBalance;

    mapBalance[CBitcoinAddress(1)] = 1;
    mapBalance[CBitcoinAddress(2)] = 8;
    mapBalance[CBitcoinAddress(3)] = 1;

    DividendDistributor distributor(mapBalance);
    distributor.Distribute(10, 0.01);

    vector<Object> vTransactionOuts;
    vector<Object>::iterator iTransaction;
    Object outs;

    distributor.GenerateOutputs(1, vTransactionOuts);
    BOOST_CHECK_EQUAL(1, vTransactionOuts.size());

    iTransaction = vTransactionOuts.begin();
    outs = *iTransaction;
    BOOST_CHECK_CLOSE(1.0, find_value(outs, CPeercoinAddress(1).ToString()).get_real(), PRECISION);
    BOOST_CHECK_CLOSE(8.0, find_value(outs, CPeercoinAddress(2).ToString()).get_real(), PRECISION);
    BOOST_CHECK_CLOSE(1.0, find_value(outs, CPeercoinAddress(3).ToString()).get_real(), PRECISION);
    BOOST_CHECK_EQUAL(3, outs.size());

    distributor.GenerateOutputs(2, vTransactionOuts);
    BOOST_CHECK_EQUAL(2, vTransactionOuts.size());

    iTransaction = vTransactionOuts.begin();
    outs = *iTransaction;
    BOOST_CHECK_CLOSE(1.0, find_value(outs, CPeercoinAddress(1).ToString()).get_real(), PRECISION);
    BOOST_CHECK_CLOSE(1.0, find_value(outs, CPeercoinAddress(3).ToString()).get_real(), PRECISION);
    BOOST_CHECK_EQUAL(2, outs.size());

    iTransaction++;
    outs = *iTransaction;
    BOOST_CHECK_CLOSE(8.0, find_value(outs, CPeercoinAddress(2).ToString()).get_real(), PRECISION);
    BOOST_CHECK_EQUAL(1, outs.size());

    distributor.GenerateOutputs(3, vTransactionOuts);
    BOOST_CHECK_EQUAL(3, vTransactionOuts.size());

    iTransaction = vTransactionOuts.begin();
    outs = *iTransaction;
    BOOST_CHECK_CLOSE(1.0, find_value(outs, CPeercoinAddress(1).ToString()).get_real(), PRECISION);
    BOOST_CHECK_EQUAL(1, outs.size());

    iTransaction++;
    outs = *iTransaction;
    BOOST_CHECK_CLOSE(8.0, find_value(outs, CPeercoinAddress(2).ToString()).get_real(), PRECISION);
    BOOST_CHECK_EQUAL(1, outs.size());

    iTransaction++;
    outs = *iTransaction;
    BOOST_CHECK_CLOSE(1.0, find_value(outs, CPeercoinAddress(3).ToString()).get_real(), PRECISION);
    BOOST_CHECK_EQUAL(1, outs.size());

    BOOST_CHECK_THROW(distributor.GenerateOutputs(4, vTransactionOuts), runtime_error);
    BOOST_CHECK_THROW(distributor.GenerateOutputs(0, vTransactionOuts), runtime_error);
    BOOST_CHECK_THROW(distributor.GenerateOutputs(-1, vTransactionOuts), runtime_error);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>distribution tests set units<commit_after>#include <boost/test/unit_test.hpp>

#include "distribution.h"
#include "json/json_spirit_utils.h"

using namespace std;
using namespace json_spirit;

BOOST_AUTO_TEST_SUITE(distribution_tests)

#define PRECISION 1e-8

BOOST_AUTO_TEST_CASE( test_simple_distribution )
{
    BalanceMap mapBalance;

    mapBalance[CBitcoinAddress(1, 'S')] = 10;
    mapBalance[CBitcoinAddress(2, 'S')] = 30;

    DividendDistributor distributor(mapBalance);
    distributor.Distribute(100, 0.01);

    BOOST_CHECK_EQUAL(25.0, distributor.GetDistribution(CBitcoinAddress(1, 'S')).GetDividendAmount());
    BOOST_CHECK_EQUAL(75.0, distributor.GetDistribution(CBitcoinAddress(2, 'S')).GetDividendAmount());
    BOOST_CHECK_EQUAL(100.0, distributor.TotalDistributed());

    vector<Object> vTransactionOuts;
    distributor.GenerateOutputs(1, vTransactionOuts);

    BOOST_CHECK_EQUAL(1, vTransactionOuts.size());

    Object& outs = *vTransactionOuts.begin();
    BOOST_CHECK_CLOSE(25.0, find_value(outs, CPeercoinAddress(1).ToString()).get_real(), PRECISION);
    BOOST_CHECK_CLOSE(75.0, find_value(outs, CPeercoinAddress(2).ToString()).get_real(), PRECISION);
}

BOOST_AUTO_TEST_CASE( test_empty_distribution )
{
    BalanceMap mapBalance;

    DividendDistributor distributor(mapBalance);
    BOOST_CHECK_THROW(distributor.Distribute(100, 0.01), runtime_error);
}

BOOST_AUTO_TEST_CASE( test_off_decimal_distribution )
{
    BalanceMap mapBalance;

    mapBalance[CBitcoinAddress(1, 'S')] = 1;
    mapBalance[CBitcoinAddress(2, 'S')] = 1;
    mapBalance[CBitcoinAddress(3, 'S')] = 1;

    DividendDistributor distributor(mapBalance);
    distributor.Distribute(10, 1);

    BOOST_CHECK_CLOSE(3.3333333333, distributor.GetDistribution(CBitcoinAddress(1, 'S')).GetDividendAmount(), PRECISION);
    BOOST_CHECK_CLOSE(3.3333333333, distributor.GetDistribution(CBitcoinAddress(2, 'S')).GetDividendAmount(), PRECISION);
    BOOST_CHECK_CLOSE(3.3333333333, distributor.GetDistribution(CBitcoinAddress(3, 'S')).GetDividendAmount(), PRECISION);
    BOOST_CHECK_CLOSE(10.0, distributor.TotalDistributed(), PRECISION);
}

BOOST_AUTO_TEST_CASE( test_not_enough_dividends_to_pay_fee )
{
    BalanceMap mapBalance;

    mapBalance[CBitcoinAddress(1, 'S')] = 90;
    mapBalance[CBitcoinAddress(2, 'S')] = 10;

    DividendDistributor distributor(mapBalance);
    distributor.Distribute(0.1, 0.010001);

    BOOST_CHECK_CLOSE(0.1, distributor.GetDistribution(CBitcoinAddress(1, 'S')).GetDividendAmount(), PRECISION);
    BOOST_CHECK_EQUAL(1, distributor.GetDistributions().size());
    BOOST_CHECK_CLOSE(0.1, distributor.TotalDistributed(), PRECISION);

    distributor.Distribute(0.1, 0.01);

    BOOST_CHECK_CLOSE(0.09, distributor.GetDistribution(CBitcoinAddress(1, 'S')).GetDividendAmount(), PRECISION);
    BOOST_CHECK_CLOSE(0.01, distributor.GetDistribution(CBitcoinAddress(2, 'S')).GetDividendAmount(), PRECISION);
    BOOST_CHECK_CLOSE(0.10, distributor.TotalDistributed(), PRECISION);
}

BOOST_AUTO_TEST_CASE( test_nobody_has_enough_funds )
{
    BalanceMap mapBalance;

    mapBalance[CBitcoinAddress(1, 'S')] = 1;
    mapBalance[CBitcoinAddress(2, 'S')] = 1;

    DividendDistributor distributor(mapBalance);

    BOOST_CHECK_THROW(distributor.Distribute(20000, 10001), runtime_error);

    BOOST_CHECK_EQUAL(0, distributor.GetDistributions().size());

    BOOST_CHECK_EQUAL(0, distributor.TotalDistributed());
}

BOOST_AUTO_TEST_CASE( test_split_transaction )
{
    BalanceMap mapBalance;

    mapBalance[CBitcoinAddress(1, 'S')] = 1;
    mapBalance[CBitcoinAddress(2, 'S')] = 8;
    mapBalance[CBitcoinAddress(3, 'S')] = 1;

    DividendDistributor distributor(mapBalance);
    distributor.Distribute(10, 0.01);

    vector<Object> vTransactionOuts;
    vector<Object>::iterator iTransaction;
    Object outs;

    distributor.GenerateOutputs(1, vTransactionOuts);
    BOOST_CHECK_EQUAL(1, vTransactionOuts.size());

    iTransaction = vTransactionOuts.begin();
    outs = *iTransaction;
    BOOST_CHECK_CLOSE(1.0, find_value(outs, CPeercoinAddress(1).ToString()).get_real(), PRECISION);
    BOOST_CHECK_CLOSE(8.0, find_value(outs, CPeercoinAddress(2).ToString()).get_real(), PRECISION);
    BOOST_CHECK_CLOSE(1.0, find_value(outs, CPeercoinAddress(3).ToString()).get_real(), PRECISION);
    BOOST_CHECK_EQUAL(3, outs.size());

    distributor.GenerateOutputs(2, vTransactionOuts);
    BOOST_CHECK_EQUAL(2, vTransactionOuts.size());

    iTransaction = vTransactionOuts.begin();
    outs = *iTransaction;
    BOOST_CHECK_CLOSE(1.0, find_value(outs, CPeercoinAddress(1).ToString()).get_real(), PRECISION);
    BOOST_CHECK_CLOSE(1.0, find_value(outs, CPeercoinAddress(3).ToString()).get_real(), PRECISION);
    BOOST_CHECK_EQUAL(2, outs.size());

    iTransaction++;
    outs = *iTransaction;
    BOOST_CHECK_CLOSE(8.0, find_value(outs, CPeercoinAddress(2).ToString()).get_real(), PRECISION);
    BOOST_CHECK_EQUAL(1, outs.size());

    distributor.GenerateOutputs(3, vTransactionOuts);
    BOOST_CHECK_EQUAL(3, vTransactionOuts.size());

    iTransaction = vTransactionOuts.begin();
    outs = *iTransaction;
    BOOST_CHECK_CLOSE(1.0, find_value(outs, CPeercoinAddress(1).ToString()).get_real(), PRECISION);
    BOOST_CHECK_EQUAL(1, outs.size());

    iTransaction++;
    outs = *iTransaction;
    BOOST_CHECK_CLOSE(8.0, find_value(outs, CPeercoinAddress(2).ToString()).get_real(), PRECISION);
    BOOST_CHECK_EQUAL(1, outs.size());

    iTransaction++;
    outs = *iTransaction;
    BOOST_CHECK_CLOSE(1.0, find_value(outs, CPeercoinAddress(3).ToString()).get_real(), PRECISION);
    BOOST_CHECK_EQUAL(1, outs.size());

    BOOST_CHECK_THROW(distributor.GenerateOutputs(4, vTransactionOuts), runtime_error);
    BOOST_CHECK_THROW(distributor.GenerateOutputs(0, vTransactionOuts), runtime_error);
    BOOST_CHECK_THROW(distributor.GenerateOutputs(-1, vTransactionOuts), runtime_error);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include "detectPeaks.h"
#include "powerSleep.h"
#include <SD.h>

bool peakDetected(volatile SignalState_t* signalState)
{
  float s = 0;
  bool peak = false;

  signalState->offset = (signalState->x_max - signalState->x_min) / 2.208;

  float high_thresh = signalState->x_max - signalState->offset;
  float low_thresh = signalState->x_min + signalState->offset;

  s = signalState->x[1] - signalState->x[0];

  if(s > 0)
  {
    signalState->slopeIsPositive = true;
    signalState->slopeIsNegative = false;
    if (signalState->x[1] > signalState->x_max)
    {
      signalState->x_max = signalState->x[1];
      high_thresh = signalState->x_max - signalState->offset;
    }
  }
  else if(s < 0)
  {
    signalState->slopeIsPositive = false;
    signalState->slopeIsNegative = true;
    if (signalState->x[1] < signalState->x_min)
    {
      signalState->x_min = signalState->x[1];
      low_thresh = signalState->x_min + signalState->offset;
    }
  }

  if(!signalState->slopeIsNegative && signalState->slopeWasNegative)
  {
    signalState->currentMin = signalState->x[0];
  }

  if(!signalState->slopeIsPositive && signalState->slopeWasPositive)
  {
    signalState->currentMax = signalState->x[0];
    if((signalState->currentMax > high_thresh) && (signalState->currentMin < low_thresh))
    {
      peak = true;
    }
  }

  if(signalState->slopeIsPositive)
    signalState->slopeWasPositive = true;
  else
    signalState->slopeWasPositive = false;

  if(signalState->slopeIsNegative)
    signalState->slopeWasNegative = true;
  else
    signalState->slopeWasNegative = false;
  /*
  /* Data to plot the waveform measured by the magnetometer. For testing purposes. To be removed when no longer needed. */
  /* Along with the wavefrom, the calculated peaks are marked, where 1 indicates a peak and -2 indicates no peak.*/
  SDPowerUp();
  File waveFile = SD.open("waveform.csv", FILE_WRITE);
  waveFile.print(signalState->x[1], 4);
  if(peak)
    waveFile.print(",1,");   // 1 on the graph means a peak
  else
    waveFile.print(",-2,");  // -2 on the graph means no peak
  //waveFile.println();
  waveFile.close();
  SDPowerDown();
  */
  return peak;
}
<commit_msg>Update detectPeaks.cpp<commit_after>#include "detectPeaks.h"
#include "powerSleep.h"
#include <SD.h>

bool peakDetected(volatile SignalState_t* signalState)
{
  float s = 0;
  bool peak = false;

  signalState->offset = (signalState->x_max - signalState->x_min) / 2.208;

  float high_thresh = signalState->x_max - signalState->offset;
  float low_thresh = signalState->x_min + signalState->offset;

  s = signalState->x[1] - signalState->x[0];

  if(s > 0)
  {
    signalState->slopeIsPositive = true;
    signalState->slopeIsNegative = false;
    if (signalState->x[1] > signalState->x_max)
    {
      signalState->x_max = signalState->x[1];
      high_thresh = signalState->x_max - signalState->offset;
    }
  }
  else if(s < 0)
  {
    signalState->slopeIsPositive = false;
    signalState->slopeIsNegative = true;
    if (signalState->x[1] < signalState->x_min)
    {
      signalState->x_min = signalState->x[1];
      low_thresh = signalState->x_min + signalState->offset;
    }
  }

  if(!signalState->slopeIsNegative && signalState->slopeWasNegative)
  {
    signalState->currentMin = signalState->x[0];
  }

  if(!signalState->slopeIsPositive && signalState->slopeWasPositive)
  {
    signalState->currentMax = signalState->x[0];
    if((signalState->currentMax > high_thresh) && (signalState->currentMin < low_thresh))
    {
      peak = true;
    }
  }

  if(signalState->slopeIsPositive)
    signalState->slopeWasPositive = true;
  else
    signalState->slopeWasPositive = false;

  if(signalState->slopeIsNegative)
    signalState->slopeWasNegative = true;
  else
    signalState->slopeWasNegative = false;

  /* Data to plot the waveform measured by the magnetometer. For testing purposes. To be removed when no longer needed. */
  /* Along with the wavefrom, the calculated peaks are marked, where 1 indicates a peak and -2 indicates no peak.*/
  //SDPowerUp();
  //File waveFile = SD.open("waveform.csv", FILE_WRITE);
  //waveFile.print(signalState->x[1], 4);
  //if(peak)
  //  waveFile.print(",1,");   // 1 on the graph means a peak
  //else
  //  waveFile.print(",-2,");  // -2 on the graph means no peak
  //waveFile.println();
  //waveFile.close();
  //SDPowerDown();
  return peak;
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/ppapi_plugin/ppapi_webkitplatformsupport_impl.h"

#include <map>

#include "base/synchronization/lock.h"
#include "base/logging.h"
#include "base/string16.h"
#include "build/build_config.h"
#include "content/common/child_process_messages.h"
#include "content/common/child_thread.h"
#include "ppapi/proxy/plugin_globals.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"

#if defined(OS_WIN)
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/win/WebSandboxSupport.h"
#elif defined(OS_MACOSX)
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/mac/WebSandboxSupport.h"
#elif defined(OS_POSIX)
#if !defined(OS_ANDROID)
#include "content/common/child_process_sandbox_support_impl_linux.h"
#endif
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/linux/WebFontFamily.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/linux/WebSandboxSupport.h"

#endif

using WebKit::WebSandboxSupport;
using WebKit::WebString;
using WebKit::WebUChar;

typedef struct CGFont* CGFontRef;

namespace content {

class PpapiWebKitPlatformSupportImpl::SandboxSupport
    : public WebSandboxSupport {
 public:
  virtual ~SandboxSupport() {}

#if defined(OS_WIN)
  virtual bool ensureFontLoaded(HFONT);
#elif defined(OS_MACOSX)
  virtual bool loadFont(
      NSFont* srcFont, CGFontRef* out, uint32_t* fontID);
#elif defined(OS_POSIX)
  virtual void getFontFamilyForCharacters(
      const WebUChar* characters,
      size_t numCharacters,
      const char* preferred_locale,
      WebKit::WebFontFamily* family);
  virtual void getRenderStyleForStrike(
      const char* family, int sizeAndStyle, WebKit::WebFontRenderStyle* out);

 private:
  // WebKit likes to ask us for the correct font family to use for a set of
  // unicode code points. It needs this information frequently so we cache it
  // here. The key in this map is an array of 16-bit UTF16 values from WebKit.
  // The value is a string containing the correct font family.
  base::Lock unicode_font_families_mutex_;
  std::map<string16, WebKit::WebFontFamily> unicode_font_families_;
#endif
};

#if defined(OS_WIN)

bool PpapiWebKitPlatformSupportImpl::SandboxSupport::ensureFontLoaded(
    HFONT font) {
  LOGFONT logfont;
  GetObject(font, sizeof(LOGFONT), &logfont);

  // Use the proxy sender rather than going directly to the ChildThread since
  // the proxy browser sender will properly unlock during sync messages.
  return ppapi::proxy::PluginGlobals::Get()->GetBrowserSender()->Send(
      new ChildProcessHostMsg_PreCacheFont(logfont));
}

#elif defined(OS_MACOSX)

bool PpapiWebKitPlatformSupportImpl::SandboxSupport::loadFont(
    NSFont* src_font,
    CGFontRef* out,
    uint32_t* font_id) {
  // TODO(brettw) this should do the something similar to what
  // RendererWebKitClientImpl does and request that the browser load the font.
  // Note: need to unlock the proxy lock like ensureFontLoaded does.
  NOTIMPLEMENTED();
  return false;
}

#elif defined(OS_ANDROID)

// TODO(jrg): resolve (and implement?) PPAPI SandboxSupport for Android.

void
PpapiWebKitPlatformSupportImpl::SandboxSupport::getFontFamilyForCharacters(
    const WebUChar* characters,
    size_t num_characters,
    const char* preferred_locale,
    WebKit::WebFontFamily* family) {
  NOTIMPLEMENTED();
}

void PpapiWebKitPlatformSupportImpl::SandboxSupport::getRenderStyleForStrike(
    const char* family, int sizeAndStyle, WebKit::WebFontRenderStyle* out) {
  NOTIMPLEMENTED();
}

#elif defined(OS_POSIX)

void
PpapiWebKitPlatformSupportImpl::SandboxSupport::getFontFamilyForCharacters(
    const WebUChar* characters,
    size_t num_characters,
    const char* preferred_locale,
    WebKit::WebFontFamily* family) {
  base::AutoLock lock(unicode_font_families_mutex_);
  const string16 key(characters, num_characters);
  const std::map<string16, WebKit::WebFontFamily>::const_iterator iter =
      unicode_font_families_.find(key);
  if (iter != unicode_font_families_.end()) {
    family->name = iter->second.name;
    family->isBold = iter->second.isBold;
    family->isItalic = iter->second.isItalic;
    return;
  }

  GetFontFamilyForCharacters(
      characters,
      num_characters,
      preferred_locale,
      family);
  unicode_font_families_.insert(make_pair(key, *family));
}

void PpapiWebKitPlatformSupportImpl::SandboxSupport::getRenderStyleForStrike(
    const char* family, int sizeAndStyle, WebKit::WebFontRenderStyle* out) {
  GetRenderStyleForStrike(family, sizeAndStyle, out);
}

#endif

PpapiWebKitPlatformSupportImpl::PpapiWebKitPlatformSupportImpl()
    : sandbox_support_(new PpapiWebKitPlatformSupportImpl::SandboxSupport()) {
}

PpapiWebKitPlatformSupportImpl::~PpapiWebKitPlatformSupportImpl() {
}

WebKit::WebClipboard* PpapiWebKitPlatformSupportImpl::clipboard() {
  NOTREACHED();
  return NULL;
}

WebKit::WebMimeRegistry* PpapiWebKitPlatformSupportImpl::mimeRegistry() {
  NOTREACHED();
  return NULL;
}

WebKit::WebFileUtilities* PpapiWebKitPlatformSupportImpl::fileUtilities() {
  NOTREACHED();
  return NULL;
}

WebKit::WebSandboxSupport* PpapiWebKitPlatformSupportImpl::sandboxSupport() {
  return sandbox_support_.get();
}

bool PpapiWebKitPlatformSupportImpl::sandboxEnabled() {
  return true;  // Assume PPAPI is always sandboxed.
}

unsigned long long PpapiWebKitPlatformSupportImpl::visitedLinkHash(
    const char* canonical_url,
    size_t length) {
  NOTREACHED();
  return 0;
}

bool PpapiWebKitPlatformSupportImpl::isLinkVisited(
    unsigned long long link_hash) {
  NOTREACHED();
  return false;
}

WebKit::WebMessagePortChannel*
PpapiWebKitPlatformSupportImpl::createMessagePortChannel() {
  NOTREACHED();
  return NULL;
}

void PpapiWebKitPlatformSupportImpl::setCookies(
    const WebKit::WebURL& url,
    const WebKit::WebURL& first_party_for_cookies,
    const WebKit::WebString& value) {
  NOTREACHED();
}

WebKit::WebString PpapiWebKitPlatformSupportImpl::cookies(
    const WebKit::WebURL& url,
    const WebKit::WebURL& first_party_for_cookies) {
  NOTREACHED();
  return WebKit::WebString();
}

void PpapiWebKitPlatformSupportImpl::prefetchHostName(
    const WebKit::WebString&) {
  NOTREACHED();
}

WebKit::WebString PpapiWebKitPlatformSupportImpl::defaultLocale() {
  NOTREACHED();
  return WebKit::WebString();
}

WebKit::WebThemeEngine* PpapiWebKitPlatformSupportImpl::themeEngine() {
  NOTREACHED();
  return NULL;
}

WebKit::WebURLLoader* PpapiWebKitPlatformSupportImpl::createURLLoader() {
  NOTREACHED();
  return NULL;
}

WebKit::WebSocketStreamHandle*
    PpapiWebKitPlatformSupportImpl::createSocketStreamHandle() {
  NOTREACHED();
  return NULL;
}

void PpapiWebKitPlatformSupportImpl::getPluginList(bool refresh,
    WebKit::WebPluginListBuilder* builder) {
  NOTREACHED();
}

WebKit::WebData PpapiWebKitPlatformSupportImpl::loadResource(const char* name) {
  NOTREACHED();
  return WebKit::WebData();
}

WebKit::WebStorageNamespace*
PpapiWebKitPlatformSupportImpl::createLocalStorageNamespace(
    const WebKit::WebString& path, unsigned quota) {
  NOTREACHED();
  return 0;
}

void PpapiWebKitPlatformSupportImpl::dispatchStorageEvent(
    const WebKit::WebString& key, const WebKit::WebString& old_value,
    const WebKit::WebString& new_value, const WebKit::WebString& origin,
    const WebKit::WebURL& url, bool is_local_storage) {
  NOTREACHED();
}

int PpapiWebKitPlatformSupportImpl::databaseDeleteFile(
    const WebKit::WebString& vfs_file_name, bool sync_dir) {
  NOTREACHED();
  return 0;
}

}  // namespace content
<commit_msg>Update some #includes in content/ppapi_plugin for new Platform directory<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/ppapi_plugin/ppapi_webkitplatformsupport_impl.h"

#include <map>

#include "base/synchronization/lock.h"
#include "base/logging.h"
#include "base/string16.h"
#include "build/build_config.h"
#include "content/common/child_process_messages.h"
#include "content/common/child_thread.h"
#include "ppapi/proxy/plugin_globals.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"

#if defined(OS_WIN)
#include "third_party/WebKit/Source/Platform/chromium/public/win/WebSandboxSupport.h"
#elif defined(OS_MACOSX)
#include "third_party/WebKit/Source/Platform/chromium/public/mac/WebSandboxSupport.h"
#elif defined(OS_POSIX)
#if !defined(OS_ANDROID)
#include "content/common/child_process_sandbox_support_impl_linux.h"
#endif
#include "third_party/WebKit/Source/Platform/chromium/public/linux/WebFontFamily.h"
#include "third_party/WebKit/Source/Platform/chromium/public/linux/WebSandboxSupport.h"

#endif

using WebKit::WebSandboxSupport;
using WebKit::WebString;
using WebKit::WebUChar;

typedef struct CGFont* CGFontRef;

namespace content {

class PpapiWebKitPlatformSupportImpl::SandboxSupport
    : public WebSandboxSupport {
 public:
  virtual ~SandboxSupport() {}

#if defined(OS_WIN)
  virtual bool ensureFontLoaded(HFONT);
#elif defined(OS_MACOSX)
  virtual bool loadFont(
      NSFont* srcFont, CGFontRef* out, uint32_t* fontID);
#elif defined(OS_POSIX)
  virtual void getFontFamilyForCharacters(
      const WebUChar* characters,
      size_t numCharacters,
      const char* preferred_locale,
      WebKit::WebFontFamily* family);
  virtual void getRenderStyleForStrike(
      const char* family, int sizeAndStyle, WebKit::WebFontRenderStyle* out);

 private:
  // WebKit likes to ask us for the correct font family to use for a set of
  // unicode code points. It needs this information frequently so we cache it
  // here. The key in this map is an array of 16-bit UTF16 values from WebKit.
  // The value is a string containing the correct font family.
  base::Lock unicode_font_families_mutex_;
  std::map<string16, WebKit::WebFontFamily> unicode_font_families_;
#endif
};

#if defined(OS_WIN)

bool PpapiWebKitPlatformSupportImpl::SandboxSupport::ensureFontLoaded(
    HFONT font) {
  LOGFONT logfont;
  GetObject(font, sizeof(LOGFONT), &logfont);

  // Use the proxy sender rather than going directly to the ChildThread since
  // the proxy browser sender will properly unlock during sync messages.
  return ppapi::proxy::PluginGlobals::Get()->GetBrowserSender()->Send(
      new ChildProcessHostMsg_PreCacheFont(logfont));
}

#elif defined(OS_MACOSX)

bool PpapiWebKitPlatformSupportImpl::SandboxSupport::loadFont(
    NSFont* src_font,
    CGFontRef* out,
    uint32_t* font_id) {
  // TODO(brettw) this should do the something similar to what
  // RendererWebKitClientImpl does and request that the browser load the font.
  // Note: need to unlock the proxy lock like ensureFontLoaded does.
  NOTIMPLEMENTED();
  return false;
}

#elif defined(OS_ANDROID)

// TODO(jrg): resolve (and implement?) PPAPI SandboxSupport for Android.

void
PpapiWebKitPlatformSupportImpl::SandboxSupport::getFontFamilyForCharacters(
    const WebUChar* characters,
    size_t num_characters,
    const char* preferred_locale,
    WebKit::WebFontFamily* family) {
  NOTIMPLEMENTED();
}

void PpapiWebKitPlatformSupportImpl::SandboxSupport::getRenderStyleForStrike(
    const char* family, int sizeAndStyle, WebKit::WebFontRenderStyle* out) {
  NOTIMPLEMENTED();
}

#elif defined(OS_POSIX)

void
PpapiWebKitPlatformSupportImpl::SandboxSupport::getFontFamilyForCharacters(
    const WebUChar* characters,
    size_t num_characters,
    const char* preferred_locale,
    WebKit::WebFontFamily* family) {
  base::AutoLock lock(unicode_font_families_mutex_);
  const string16 key(characters, num_characters);
  const std::map<string16, WebKit::WebFontFamily>::const_iterator iter =
      unicode_font_families_.find(key);
  if (iter != unicode_font_families_.end()) {
    family->name = iter->second.name;
    family->isBold = iter->second.isBold;
    family->isItalic = iter->second.isItalic;
    return;
  }

  GetFontFamilyForCharacters(
      characters,
      num_characters,
      preferred_locale,
      family);
  unicode_font_families_.insert(make_pair(key, *family));
}

void PpapiWebKitPlatformSupportImpl::SandboxSupport::getRenderStyleForStrike(
    const char* family, int sizeAndStyle, WebKit::WebFontRenderStyle* out) {
  GetRenderStyleForStrike(family, sizeAndStyle, out);
}

#endif

PpapiWebKitPlatformSupportImpl::PpapiWebKitPlatformSupportImpl()
    : sandbox_support_(new PpapiWebKitPlatformSupportImpl::SandboxSupport()) {
}

PpapiWebKitPlatformSupportImpl::~PpapiWebKitPlatformSupportImpl() {
}

WebKit::WebClipboard* PpapiWebKitPlatformSupportImpl::clipboard() {
  NOTREACHED();
  return NULL;
}

WebKit::WebMimeRegistry* PpapiWebKitPlatformSupportImpl::mimeRegistry() {
  NOTREACHED();
  return NULL;
}

WebKit::WebFileUtilities* PpapiWebKitPlatformSupportImpl::fileUtilities() {
  NOTREACHED();
  return NULL;
}

WebKit::WebSandboxSupport* PpapiWebKitPlatformSupportImpl::sandboxSupport() {
  return sandbox_support_.get();
}

bool PpapiWebKitPlatformSupportImpl::sandboxEnabled() {
  return true;  // Assume PPAPI is always sandboxed.
}

unsigned long long PpapiWebKitPlatformSupportImpl::visitedLinkHash(
    const char* canonical_url,
    size_t length) {
  NOTREACHED();
  return 0;
}

bool PpapiWebKitPlatformSupportImpl::isLinkVisited(
    unsigned long long link_hash) {
  NOTREACHED();
  return false;
}

WebKit::WebMessagePortChannel*
PpapiWebKitPlatformSupportImpl::createMessagePortChannel() {
  NOTREACHED();
  return NULL;
}

void PpapiWebKitPlatformSupportImpl::setCookies(
    const WebKit::WebURL& url,
    const WebKit::WebURL& first_party_for_cookies,
    const WebKit::WebString& value) {
  NOTREACHED();
}

WebKit::WebString PpapiWebKitPlatformSupportImpl::cookies(
    const WebKit::WebURL& url,
    const WebKit::WebURL& first_party_for_cookies) {
  NOTREACHED();
  return WebKit::WebString();
}

void PpapiWebKitPlatformSupportImpl::prefetchHostName(
    const WebKit::WebString&) {
  NOTREACHED();
}

WebKit::WebString PpapiWebKitPlatformSupportImpl::defaultLocale() {
  NOTREACHED();
  return WebKit::WebString();
}

WebKit::WebThemeEngine* PpapiWebKitPlatformSupportImpl::themeEngine() {
  NOTREACHED();
  return NULL;
}

WebKit::WebURLLoader* PpapiWebKitPlatformSupportImpl::createURLLoader() {
  NOTREACHED();
  return NULL;
}

WebKit::WebSocketStreamHandle*
    PpapiWebKitPlatformSupportImpl::createSocketStreamHandle() {
  NOTREACHED();
  return NULL;
}

void PpapiWebKitPlatformSupportImpl::getPluginList(bool refresh,
    WebKit::WebPluginListBuilder* builder) {
  NOTREACHED();
}

WebKit::WebData PpapiWebKitPlatformSupportImpl::loadResource(const char* name) {
  NOTREACHED();
  return WebKit::WebData();
}

WebKit::WebStorageNamespace*
PpapiWebKitPlatformSupportImpl::createLocalStorageNamespace(
    const WebKit::WebString& path, unsigned quota) {
  NOTREACHED();
  return 0;
}

void PpapiWebKitPlatformSupportImpl::dispatchStorageEvent(
    const WebKit::WebString& key, const WebKit::WebString& old_value,
    const WebKit::WebString& new_value, const WebKit::WebString& origin,
    const WebKit::WebURL& url, bool is_local_storage) {
  NOTREACHED();
}

int PpapiWebKitPlatformSupportImpl::databaseDeleteFile(
    const WebKit::WebString& vfs_file_name, bool sync_dir) {
  NOTREACHED();
  return 0;
}

}  // namespace content
<|endoftext|>


<commit_before>#pragma once

#include "boost_defs.hpp"

#include "iokit_utility.hpp"
#include "service_observer.hpp"
#include "types.hpp"
#include <boost/optional.hpp>
#include <list>
#include <memory>

class hid_system_client final {
public:
  hid_system_client(const hid_system_client&) = delete;

  // Note:
  // OS X shares IOHIDSystem among all input devices even the serial_number of IOHIDSystem is same with the one of the input device.
  //
  // Example:
  //   The matched_callback always contains only one IOHIDSystem even if the following devices are connected.
  //     * Apple Internal Keyboard / Track
  //     * HHKB-BT
  //     * org.pqrs.driver.VirtualHIDKeyboard
  //
  //   The IOHIDSystem object's serial_number is one of the connected devices.
  //
  //   But the IOHIDSystem object is shared by all input devices.
  //   Thus, the IOHIDGetModifierLockState returns true if caps lock is on in one device.

  hid_system_client(spdlog::logger& logger) : logger_(logger),
                                              service_(IO_OBJECT_NULL),
                                              connect_(IO_OBJECT_NULL) {
    matching_dictionary_ = IOServiceNameMatching(kIOHIDSystemClass);
    if (!matching_dictionary_) {
      logger_.error("IOServiceNameMatching error @ {0}", __PRETTY_FUNCTION__);
    } else {
      service_observer_ = std::make_unique<service_observer>(logger_,
                                                             matching_dictionary_,
                                                             std::bind(&hid_system_client::matched_callback, this, std::placeholders::_1),
                                                             std::bind(&hid_system_client::terminated_callback, this, std::placeholders::_1));
    }
  }

  ~hid_system_client(void) {
    close_connection();

    if (matching_dictionary_) {
      CFRelease(matching_dictionary_);
    }
  }

  void post_modifier_flags(uint8_t key_code, IOOptionBits flags) {
    NXEventData event{};
    event.key.keyCode = key_code;

    IOGPoint loc{};
    post_event(NX_FLAGSCHANGED, loc, &event, kNXEventDataVersion, flags, kIOHIDSetGlobalEventFlags);
  }

  enum class post_key_type {
    key,
    aux_control_button,
  };

  void post_key(post_key_type type, uint8_t key_code, krbn::event_type event_type, IOOptionBits flags, bool repeat) {
    switch (type) {
    case post_key_type::key:
      post_key(key_code, event_type, flags, repeat);
      break;

    case post_key_type::aux_control_button:
      post_aux_control_button(key_code, event_type, flags, repeat);
      break;
    }
  }

  void post_key(krbn::key_code key_code, krbn::event_type event_type, IOOptionBits flags, bool repeat) {
    if (auto key = krbn::types::get_mac_aux_control_button(key_code)) {
      post_aux_control_button(*key, event_type, flags, repeat);
      return;
    }

    if (auto key = krbn::types::get_mac_key(key_code)) {
      post_key(*key, event_type, flags, repeat);
      return;
    }

    logger::get_logger().warn("key_code:{1:#x} is unsupported key @ {0}", __PRETTY_FUNCTION__, static_cast<uint32_t>(key_code));
  }

  void post_key(uint8_t key_code, krbn::event_type event_type, IOOptionBits flags, bool repeat) {
    NXEventData event{};
    event.key.origCharCode = 0;
    event.key.repeat = repeat;
    event.key.charSet = NX_ASCIISET;
    event.key.charCode = 0;
    event.key.keyCode = key_code;
    event.key.origCharSet = NX_ASCIISET;
    event.key.keyboardType = 0;

    IOGPoint loc{};
    post_event(event_type == krbn::event_type::key_down ? NX_KEYDOWN : NX_KEYUP,
               loc,
               &event,
               kNXEventDataVersion,
               flags,
               kIOHIDSetGlobalEventFlags);
  }

  void post_aux_control_button(uint8_t key_code, krbn::event_type event_type, IOOptionBits flags, bool repeat) {
    NXEventData event{};
    event.compound.subType = NX_SUBTYPE_AUX_CONTROL_BUTTONS;
    event.compound.misc.L[0] = (key_code << 16) | ((event_type == krbn::event_type::key_down ? NX_KEYDOWN : NX_KEYUP) << 8) | repeat;

    IOGPoint loc{};
    post_event(NX_SYSDEFINED, loc, &event, kNXEventDataVersion, flags, kIOHIDSetGlobalEventFlags);
  }

  boost::optional<bool> get_caps_lock_state(void) {
    return get_modifier_lock_state(kIOHIDCapsLockState);
  }

  bool set_caps_lock_state(bool state) {
    return set_modifier_lock_state(kIOHIDCapsLockState, state);
  }

private:
  void matched_callback(io_iterator_t iterator) {
    while (auto service = IOIteratorNext(iterator)) {
      std::lock_guard<std::mutex> guard(connect_mutex_);

      // Use first matched service.
      if (!service_) {
        service_ = service;
        IOObjectRetain(service_);

        auto kr = IOServiceOpen(service_, mach_task_self(), kIOHIDParamConnectType, &connect_);
        if (kr != KERN_SUCCESS) {
          logger_.error("IOServiceOpen error: {1} @ {0}", __PRETTY_FUNCTION__, kr);
          connect_ = IO_OBJECT_NULL;
        }

        logger_.info("IOServiceOpen is succeeded @ {0}", __PRETTY_FUNCTION__);
      }

      IOObjectRelease(service);
    }
  }

  void terminated_callback(io_iterator_t iterator) {
    bool found = false;

    while (auto service = IOIteratorNext(iterator)) {
      found = true;
      IOObjectRelease(service);
    }

    if (!found) {
      return;
    }

    // ----------------------------------------
    // Refresh connection.

    close_connection();

    io_iterator_t it;
    auto kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matching_dictionary_, &it);
    if (kr != KERN_SUCCESS) {
      logger_.error("IOServiceGetMatchingServices error: {1} @ {0}", __PRETTY_FUNCTION__, kr);
    } else {
      matched_callback(it);
      IOObjectRelease(it);
    }
  }

  void post_event(UInt32 event_type,
                  IOGPoint location,
                  const NXEventData* _Nullable event_data,
                  UInt32 event_data_version,
                  IOOptionBits event_flags,
                  IOOptionBits options) {
    std::lock_guard<std::mutex> guard(connect_mutex_);

    if (!connect_) {
      logger_.error("connect_ is null @ {0}", __PRETTY_FUNCTION__);
      return;
    }

    auto kr = IOHIDPostEvent(connect_, event_type, location, event_data, event_data_version, event_flags, options);
    if (kr != KERN_SUCCESS) {
      logger_.error("IOHIDPostEvent error: {1} @ {0}", __PRETTY_FUNCTION__, kr);
    }
  }

  boost::optional<bool> get_modifier_lock_state(int selector) {
    std::lock_guard<std::mutex> guard(connect_mutex_);

    if (!connect_) {
      logger_.error("connect_ is null @ {0}", __PRETTY_FUNCTION__);
      return boost::none;
    }

    bool value;
    auto kr = IOHIDGetModifierLockState(connect_, selector, &value);
    if (kr != KERN_SUCCESS) {
      logger_.error("IOHIDGetModifierLockState error: {1} @ {0}", __PRETTY_FUNCTION__, kr);
    }

    return value;
  }

  bool set_modifier_lock_state(int selector, bool state) {
    std::lock_guard<std::mutex> guard(connect_mutex_);

    if (!connect_) {
      logger_.error("connect_ is null @ {0}", __PRETTY_FUNCTION__);
      return false;
    }

    auto kr = IOHIDSetModifierLockState(connect_, selector, state);
    if (kr != KERN_SUCCESS) {
      logger_.error("IOHIDSetModifierLockState error: {1} @ {0}", __PRETTY_FUNCTION__, kr);
      return false;
    }

    return true;
  }

  void close_connection(void) {
    std::lock_guard<std::mutex> guard(connect_mutex_);

    if (connect_) {
      auto kr = IOServiceClose(connect_);
      if (kr != kIOReturnSuccess) {
        logger_.error("IOConnectRelease error: {1} @ {0}", __PRETTY_FUNCTION__, kr);
      }
      connect_ = IO_OBJECT_NULL;
    }

    logger_.info("IOServiceClose is succeeded @ {0}", __PRETTY_FUNCTION__);

    if (service_) {
      IOObjectRelease(service_);
      service_ = IO_OBJECT_NULL;
    }
  }

  spdlog::logger& logger_;

  std::unique_ptr<service_observer> service_observer_;
  CFMutableDictionaryRef _Nullable matching_dictionary_;
  io_service_t service_;
  io_connect_t connect_;
  std::mutex connect_mutex_;
};
<commit_msg>fix logger<commit_after>#pragma once

#include "boost_defs.hpp"

#include "iokit_utility.hpp"
#include "service_observer.hpp"
#include "types.hpp"
#include <boost/optional.hpp>
#include <list>
#include <memory>

class hid_system_client final {
public:
  hid_system_client(const hid_system_client&) = delete;

  // Note:
  // OS X shares IOHIDSystem among all input devices even the serial_number of IOHIDSystem is same with the one of the input device.
  //
  // Example:
  //   The matched_callback always contains only one IOHIDSystem even if the following devices are connected.
  //     * Apple Internal Keyboard / Track
  //     * HHKB-BT
  //     * org.pqrs.driver.VirtualHIDKeyboard
  //
  //   The IOHIDSystem object's serial_number is one of the connected devices.
  //
  //   But the IOHIDSystem object is shared by all input devices.
  //   Thus, the IOHIDGetModifierLockState returns true if caps lock is on in one device.

  hid_system_client(spdlog::logger& logger) : logger_(logger),
                                              service_(IO_OBJECT_NULL),
                                              connect_(IO_OBJECT_NULL) {
    matching_dictionary_ = IOServiceNameMatching(kIOHIDSystemClass);
    if (!matching_dictionary_) {
      logger_.error("IOServiceNameMatching error @ {0}", __PRETTY_FUNCTION__);
    } else {
      service_observer_ = std::make_unique<service_observer>(logger_,
                                                             matching_dictionary_,
                                                             std::bind(&hid_system_client::matched_callback, this, std::placeholders::_1),
                                                             std::bind(&hid_system_client::terminated_callback, this, std::placeholders::_1));
    }
  }

  ~hid_system_client(void) {
    close_connection();

    if (matching_dictionary_) {
      CFRelease(matching_dictionary_);
    }
  }

  void post_modifier_flags(uint8_t key_code, IOOptionBits flags) {
    NXEventData event{};
    event.key.keyCode = key_code;

    IOGPoint loc{};
    post_event(NX_FLAGSCHANGED, loc, &event, kNXEventDataVersion, flags, kIOHIDSetGlobalEventFlags);
  }

  enum class post_key_type {
    key,
    aux_control_button,
  };

  void post_key(post_key_type type, uint8_t key_code, krbn::event_type event_type, IOOptionBits flags, bool repeat) {
    switch (type) {
    case post_key_type::key:
      post_key(key_code, event_type, flags, repeat);
      break;

    case post_key_type::aux_control_button:
      post_aux_control_button(key_code, event_type, flags, repeat);
      break;
    }
  }

  void post_key(krbn::key_code key_code, krbn::event_type event_type, IOOptionBits flags, bool repeat) {
    if (auto key = krbn::types::get_mac_aux_control_button(key_code)) {
      post_aux_control_button(*key, event_type, flags, repeat);
      return;
    }

    if (auto key = krbn::types::get_mac_key(key_code)) {
      post_key(*key, event_type, flags, repeat);
      return;
    }

    logger_.warn("key_code:{1:#x} is unsupported key @ {0}", __PRETTY_FUNCTION__, static_cast<uint32_t>(key_code));
  }

  void post_key(uint8_t key_code, krbn::event_type event_type, IOOptionBits flags, bool repeat) {
    NXEventData event{};
    event.key.origCharCode = 0;
    event.key.repeat = repeat;
    event.key.charSet = NX_ASCIISET;
    event.key.charCode = 0;
    event.key.keyCode = key_code;
    event.key.origCharSet = NX_ASCIISET;
    event.key.keyboardType = 0;

    IOGPoint loc{};
    post_event(event_type == krbn::event_type::key_down ? NX_KEYDOWN : NX_KEYUP,
               loc,
               &event,
               kNXEventDataVersion,
               flags,
               kIOHIDSetGlobalEventFlags);
  }

  void post_aux_control_button(uint8_t key_code, krbn::event_type event_type, IOOptionBits flags, bool repeat) {
    NXEventData event{};
    event.compound.subType = NX_SUBTYPE_AUX_CONTROL_BUTTONS;
    event.compound.misc.L[0] = (key_code << 16) | ((event_type == krbn::event_type::key_down ? NX_KEYDOWN : NX_KEYUP) << 8) | repeat;

    IOGPoint loc{};
    post_event(NX_SYSDEFINED, loc, &event, kNXEventDataVersion, flags, kIOHIDSetGlobalEventFlags);
  }

  boost::optional<bool> get_caps_lock_state(void) {
    return get_modifier_lock_state(kIOHIDCapsLockState);
  }

  bool set_caps_lock_state(bool state) {
    return set_modifier_lock_state(kIOHIDCapsLockState, state);
  }

private:
  void matched_callback(io_iterator_t iterator) {
    while (auto service = IOIteratorNext(iterator)) {
      std::lock_guard<std::mutex> guard(connect_mutex_);

      // Use first matched service.
      if (!service_) {
        service_ = service;
        IOObjectRetain(service_);

        auto kr = IOServiceOpen(service_, mach_task_self(), kIOHIDParamConnectType, &connect_);
        if (kr != KERN_SUCCESS) {
          logger_.error("IOServiceOpen error: {1} @ {0}", __PRETTY_FUNCTION__, kr);
          connect_ = IO_OBJECT_NULL;
        }

        logger_.info("IOServiceOpen is succeeded @ {0}", __PRETTY_FUNCTION__);
      }

      IOObjectRelease(service);
    }
  }

  void terminated_callback(io_iterator_t iterator) {
    bool found = false;

    while (auto service = IOIteratorNext(iterator)) {
      found = true;
      IOObjectRelease(service);
    }

    if (!found) {
      return;
    }

    // ----------------------------------------
    // Refresh connection.

    close_connection();

    io_iterator_t it;
    auto kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matching_dictionary_, &it);
    if (kr != KERN_SUCCESS) {
      logger_.error("IOServiceGetMatchingServices error: {1} @ {0}", __PRETTY_FUNCTION__, kr);
    } else {
      matched_callback(it);
      IOObjectRelease(it);
    }
  }

  void post_event(UInt32 event_type,
                  IOGPoint location,
                  const NXEventData* _Nullable event_data,
                  UInt32 event_data_version,
                  IOOptionBits event_flags,
                  IOOptionBits options) {
    std::lock_guard<std::mutex> guard(connect_mutex_);

    if (!connect_) {
      logger_.error("connect_ is null @ {0}", __PRETTY_FUNCTION__);
      return;
    }

    auto kr = IOHIDPostEvent(connect_, event_type, location, event_data, event_data_version, event_flags, options);
    if (kr != KERN_SUCCESS) {
      logger_.error("IOHIDPostEvent error: {1} @ {0}", __PRETTY_FUNCTION__, kr);
    }
  }

  boost::optional<bool> get_modifier_lock_state(int selector) {
    std::lock_guard<std::mutex> guard(connect_mutex_);

    if (!connect_) {
      logger_.error("connect_ is null @ {0}", __PRETTY_FUNCTION__);
      return boost::none;
    }

    bool value;
    auto kr = IOHIDGetModifierLockState(connect_, selector, &value);
    if (kr != KERN_SUCCESS) {
      logger_.error("IOHIDGetModifierLockState error: {1} @ {0}", __PRETTY_FUNCTION__, kr);
    }

    return value;
  }

  bool set_modifier_lock_state(int selector, bool state) {
    std::lock_guard<std::mutex> guard(connect_mutex_);

    if (!connect_) {
      logger_.error("connect_ is null @ {0}", __PRETTY_FUNCTION__);
      return false;
    }

    auto kr = IOHIDSetModifierLockState(connect_, selector, state);
    if (kr != KERN_SUCCESS) {
      logger_.error("IOHIDSetModifierLockState error: {1} @ {0}", __PRETTY_FUNCTION__, kr);
      return false;
    }

    return true;
  }

  void close_connection(void) {
    std::lock_guard<std::mutex> guard(connect_mutex_);

    if (connect_) {
      auto kr = IOServiceClose(connect_);
      if (kr != kIOReturnSuccess) {
        logger_.error("IOConnectRelease error: {1} @ {0}", __PRETTY_FUNCTION__, kr);
      }
      connect_ = IO_OBJECT_NULL;
    }

    logger_.info("IOServiceClose is succeeded @ {0}", __PRETTY_FUNCTION__);

    if (service_) {
      IOObjectRelease(service_);
      service_ = IO_OBJECT_NULL;
    }
  }

  spdlog::logger& logger_;

  std::unique_ptr<service_observer> service_observer_;
  CFMutableDictionaryRef _Nullable matching_dictionary_;
  io_service_t service_;
  io_connect_t connect_;
  std::mutex connect_mutex_;
};
<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#include "Importer.h"
#include "common/sg/SceneGraph.h"
#include <memory>

/*! \file sg/module/Importer.cpp Defines the interface for writing
    file importers for the ospray::sg */

namespace ospray {
  namespace sg {

    struct Sphere
    {
      Sphere(const vec3f &position = vec3f(0.f),
             float radius = 1.f,
             uint32_t typeID = 0)
        : position(position), radius(radius), typeID(typeID) {}

      box3f bounds() const
      { return {position - vec3f(radius), position + vec3f(radius)}; }

      vec3f position;
      float radius;
      uint32_t typeID;
    };

    struct ColorMap
    {
      ColorMap(float lo, float hi)
        : lo(lo), hi(hi)
      {
        assert(lo <= hi);

        color.push_back(ospcommon::vec3f(0.231373, 0.298039 , 0.752941));
        color.push_back(ospcommon::vec3f(0.865003, 0.865003 , 0.865003));
        color.push_back(ospcommon::vec3f(0.705882, 0.0156863, 0.14902 ));
      }

      vec4f colorFor(float f)
      {
        if (f <= lo) return vec4f(color.front(),1.f);
        if (f >= hi) return vec4f(color.back(),1.f);

        float r = ((f-lo) * (color.size()-1)) / (hi-lo);
        int idx = int(r);
        if (idx < 0) idx = 0;
        if (idx >= static_cast<int>(color.size())) idx = color.size()-2;

        vec3f c = color[idx] + (r-idx)*(color[idx+1]-color[idx]);
        return vec4f(c,1.f);
      }

      float lo, hi;
      std::vector<vec3f> color;
    };

    bool readOne(FILE *file, float *f, int N, bool ascii)
    {
      if (!ascii)
        return fread(f,sizeof(float),N,file) == size_t(N);

      // ascii:
      for (int i=0;i<N;i++) {
        int rc = fscanf(file,"%f",f+i);
        if (rc == 0) return (i == 0);
        fscanf(file,"\n");
      }
      return true;
    }

    /*! importer for a binary set of points, the format of which are
        controlled through the 'Pseudo-URL' "url" parameter. e.g.,
        'points://fileName.raw:format=xyzff,radius=.2' means the file
        is sequence of records with 5 elements, the first three of
        which are x, y, and z coordinates, and the other two are
        (unused) floats, with a fixed radius of 0.2 for every
        sphere */
    void importFileType_points(std::shared_ptr<Node> &world,
                               const FileName &url)
    {
      std::cout << "--------------------------------------------" << std::endl;
      std::cout << "#osp.sg: importer for 'points': " << url.str() << std::endl;

      FormatURL fu(url.str());
      FILE *file = fopen(fu.fileName.c_str(),"rb");
      if (!file)
        throw std::runtime_error("could not open file "+fu.fileName);

      // read the data vector
      auto sphereData = std::make_shared<DataVectorT<Sphere,OSP_RAW>>();

      float radius = .1f;
      if (fu.hasArg("radius"))
        radius = std::stof(fu["radius"]);
      if (radius == 0.f)
        throw std::runtime_error("#sg.importPoints: could not parse radius ...");

      std::string format = "xyz";
      if (fu.hasArg("format"))
        format = fu["format"];

      bool ascii = fu.hasArg("ascii");

      /* for now, hard-coded sphere componetns to be in float format,
         so the number of chars in the format string is the num components */
      int numFloatsPerSphere = format.size();
      size_t xPos = format.find("x");
      size_t yPos = format.find("y");
      size_t zPos = format.find("z");
      size_t rPos = format.find("r");
      size_t sPos = format.find("s");

      if (xPos == std::string::npos)
        throw std::runtime_error("invalid points format: no x component");
      if (yPos == std::string::npos)
        throw std::runtime_error("invalid points format: no y component");
      if (zPos == std::string::npos)
        throw std::runtime_error("invalid points format: no z component");

      float * const f = (float *)alloca(sizeof(float)*numFloatsPerSphere);
      box3f bounds;

      std::vector<float> mappedScalarVector;
      float mappedScalarMin = +std::numeric_limits<float>::infinity();
      float mappedScalarMax = -std::numeric_limits<float>::infinity();

      while (readOne(file,f,numFloatsPerSphere,ascii)) {
        // read one more sphere ....
        Sphere s;
        s.position.x = f[xPos];
        s.position.y = f[yPos];
        s.position.z = f[zPos];
        s.radius
          = (rPos == std::string::npos)
          ? radius
          : f[rPos];
        sphereData->v.push_back(s);
        bounds.extend(s.position-s.radius);
        bounds.extend(s.position+s.radius);

        if (sPos != std::string::npos) {
          mappedScalarVector.push_back(f[sPos]);
          mappedScalarMin = std::min(mappedScalarMin,f[sPos]);
          mappedScalarMax = std::max(mappedScalarMax,f[sPos]);
        }
      }

      fclose(file);

      // create the node
      auto &sphereObject = world->createChild("spheres", "Spheres");

      // iw - note that 'add' sounds wrong here, but that's the way
      // the current scene graph works - 'adding' that node (which
      // happens to have the right name) will essentially replace the
      // old value of that node, and thereby assign the 'data' field
      sphereData->setName("spheres");
      sphereObject.add(sphereData);

      if (!mappedScalarVector.empty()) {
        std::cout << "#osp.sg: creating color map for points data ..."
                  << std::endl;
        ColorMap cm(mappedScalarMin,mappedScalarMax);
        auto colorData = std::make_shared<DataVectorT<vec4f,OSP_RAW>>();
        for (size_t i = 0; i < mappedScalarVector.size(); i++)
          colorData->v.push_back(cm.colorFor(mappedScalarVector[i]));
        colorData->setName("colorData");
        sphereObject.add(colorData);
      }

      sphereObject.createChild("bytes_per_sphere", "int", int(sizeof(Sphere)));
      sphereObject.createChild("offset_center", "int", int(0*sizeof(float)));
      sphereObject.createChild("offset_radius", "int", int(3*sizeof(float)));
      sphereObject.createChild("offset_materialID", "int",int(4*sizeof(float)));
      sphereObject.createChild("color_offset", "int", int(0*sizeof(float)));
      sphereObject.createChild("color_stride", "int", int(4*sizeof(float)));

      std::cout << "#osp.sg: imported " << prettyNumber(sphereData->v.size())
                << " points, bounds = " << bounds << std::endl;;
    }

  }// ::ospray::sg
}// ::ospray

<commit_msg>fixed warning<commit_after>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#include "Importer.h"
#include "common/sg/SceneGraph.h"
#include <memory>

/*! \file sg/module/Importer.cpp Defines the interface for writing
    file importers for the ospray::sg */

namespace ospray {
  namespace sg {

    struct Sphere
    {
      Sphere(const vec3f &position = vec3f(0.f),
             float radius = 1.f,
             uint32_t typeID = 0)
        : position(position), radius(radius), typeID(typeID) {}

      box3f bounds() const
      { return {position - vec3f(radius), position + vec3f(radius)}; }

      vec3f position;
      float radius;
      uint32_t typeID;
    };

    struct ColorMap
    {
      ColorMap(float lo, float hi)
        : lo(lo), hi(hi)
      {
        assert(lo <= hi);

        color.push_back(ospcommon::vec3f(0.231373, 0.298039 , 0.752941));
        color.push_back(ospcommon::vec3f(0.865003, 0.865003 , 0.865003));
        color.push_back(ospcommon::vec3f(0.705882, 0.0156863, 0.14902 ));
      }

      vec4f colorFor(float f)
      {
        if (f <= lo) return vec4f(color.front(),1.f);
        if (f >= hi) return vec4f(color.back(),1.f);

        float r = ((f-lo) * (color.size()-1)) / (hi-lo);
        int idx = int(r);
        if (idx < 0) idx = 0;
        if (idx >= static_cast<int>(color.size())) idx = color.size()-2;

        vec3f c = color[idx] + (r-idx)*(color[idx+1]-color[idx]);
        return vec4f(c,1.f);
      }

      float lo, hi;
      std::vector<vec3f> color;
    };

    bool readOne(FILE *file, float *f, int N, bool ascii)
    {
      if (!ascii)
        return fread(f,sizeof(float),N,file) == size_t(N);

      // ascii:
      for (int i=0;i<N;i++) {
        int rc = fscanf(file,"%f",f+i);
        if (rc == 0) return (i == 0);
        rc = fscanf(file,"\n");
      }
      return true;
    }

    /*! importer for a binary set of points, the format of which are
        controlled through the 'Pseudo-URL' "url" parameter. e.g.,
        'points://fileName.raw:format=xyzff,radius=.2' means the file
        is sequence of records with 5 elements, the first three of
        which are x, y, and z coordinates, and the other two are
        (unused) floats, with a fixed radius of 0.2 for every
        sphere */
    void importFileType_points(std::shared_ptr<Node> &world,
                               const FileName &url)
    {
      std::cout << "--------------------------------------------" << std::endl;
      std::cout << "#osp.sg: importer for 'points': " << url.str() << std::endl;

      FormatURL fu(url.str());
      FILE *file = fopen(fu.fileName.c_str(),"rb");
      if (!file)
        throw std::runtime_error("could not open file "+fu.fileName);

      // read the data vector
      auto sphereData = std::make_shared<DataVectorT<Sphere,OSP_RAW>>();

      float radius = .1f;
      if (fu.hasArg("radius"))
        radius = std::stof(fu["radius"]);
      if (radius == 0.f)
        throw std::runtime_error("#sg.importPoints: could not parse radius ...");

      std::string format = "xyz";
      if (fu.hasArg("format"))
        format = fu["format"];

      bool ascii = fu.hasArg("ascii");

      /* for now, hard-coded sphere componetns to be in float format,
         so the number of chars in the format string is the num components */
      int numFloatsPerSphere = format.size();
      size_t xPos = format.find("x");
      size_t yPos = format.find("y");
      size_t zPos = format.find("z");
      size_t rPos = format.find("r");
      size_t sPos = format.find("s");

      if (xPos == std::string::npos)
        throw std::runtime_error("invalid points format: no x component");
      if (yPos == std::string::npos)
        throw std::runtime_error("invalid points format: no y component");
      if (zPos == std::string::npos)
        throw std::runtime_error("invalid points format: no z component");

      float * const f = (float *)alloca(sizeof(float)*numFloatsPerSphere);
      box3f bounds;

      std::vector<float> mappedScalarVector;
      float mappedScalarMin = +std::numeric_limits<float>::infinity();
      float mappedScalarMax = -std::numeric_limits<float>::infinity();

      while (readOne(file,f,numFloatsPerSphere,ascii)) {
        // read one more sphere ....
        Sphere s;
        s.position.x = f[xPos];
        s.position.y = f[yPos];
        s.position.z = f[zPos];
        s.radius
          = (rPos == std::string::npos)
          ? radius
          : f[rPos];
        sphereData->v.push_back(s);
        bounds.extend(s.position-s.radius);
        bounds.extend(s.position+s.radius);

        if (sPos != std::string::npos) {
          mappedScalarVector.push_back(f[sPos]);
          mappedScalarMin = std::min(mappedScalarMin,f[sPos]);
          mappedScalarMax = std::max(mappedScalarMax,f[sPos]);
        }
      }

      fclose(file);

      // create the node
      auto &sphereObject = world->createChild("spheres", "Spheres");

      // iw - note that 'add' sounds wrong here, but that's the way
      // the current scene graph works - 'adding' that node (which
      // happens to have the right name) will essentially replace the
      // old value of that node, and thereby assign the 'data' field
      sphereData->setName("spheres");
      sphereObject.add(sphereData);

      if (!mappedScalarVector.empty()) {
        std::cout << "#osp.sg: creating color map for points data ..."
                  << std::endl;
        ColorMap cm(mappedScalarMin,mappedScalarMax);
        auto colorData = std::make_shared<DataVectorT<vec4f,OSP_RAW>>();
        for (size_t i = 0; i < mappedScalarVector.size(); i++)
          colorData->v.push_back(cm.colorFor(mappedScalarVector[i]));
        colorData->setName("colorData");
        sphereObject.add(colorData);
      }

      sphereObject.createChild("bytes_per_sphere", "int", int(sizeof(Sphere)));
      sphereObject.createChild("offset_center", "int", int(0*sizeof(float)));
      sphereObject.createChild("offset_radius", "int", int(3*sizeof(float)));
      sphereObject.createChild("offset_materialID", "int",int(4*sizeof(float)));
      sphereObject.createChild("color_offset", "int", int(0*sizeof(float)));
      sphereObject.createChild("color_stride", "int", int(4*sizeof(float)));

      std::cout << "#osp.sg: imported " << prettyNumber(sphereData->v.size())
                << " points, bounds = " << bounds << std::endl;;
    }

  }// ::ospray::sg
}// ::ospray

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "iosdebugsupport.h"

#include "iosrunner.h"
#include "iosmanager.h"
#include "iosdevice.h"

#include <debugger/debuggerengine.h>
#include <debugger/debuggerplugin.h>
#include <debugger/debuggerkitinformation.h>
#include <debugger/debuggerrunner.h>
#include <debugger/debuggerstartparameters.h>
#include <debugger/debuggerrunconfigurationaspect.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/target.h>
#include <projectexplorer/taskhub.h>
#include <qmakeprojectmanager/qmakebuildconfiguration.h>
#include <qmakeprojectmanager/qmakenodes.h>
#include <qmakeprojectmanager/qmakeproject.h>
#include <qtsupport/qtkitinformation.h>
#include <utils/fileutils.h>

#include <QDir>
#include <QTcpServer>
#include <QSettings>

#include <stdio.h>
#include <fcntl.h>
#ifdef Q_OS_UNIX
#include <unistd.h>
#else
#include <io.h>
#endif

using namespace Debugger;
using namespace ProjectExplorer;
using namespace QmakeProjectManager;

namespace Ios {
namespace Internal {

RunControl *IosDebugSupport::createDebugRunControl(IosRunConfiguration *runConfig,
                                                   QString *errorMessage)
{
    Target *target = runConfig->target();
    if (!target)
        return 0;
    ProjectExplorer::IDevice::ConstPtr device = DeviceKitInformation::device(target->kit());
    if (device.isNull())
        return 0;
    QmakeProject *project = static_cast<QmakeProject *>(target->project());
    Kit *kit = target->kit();

    DebuggerStartParameters params;
    if (device->type() == Core::Id(Ios::Constants::IOS_DEVICE_TYPE)) {
        params.startMode = AttachToRemoteProcess;
        params.platform = QLatin1String("remote-ios");
        IosDevice::ConstPtr iosDevice = device.dynamicCast<const IosDevice>();
        if (iosDevice.isNull())
                return 0;
        QString osVersion = iosDevice->osVersion();
        Utils::FileName deviceSdk1 = Utils::FileName::fromString(QDir::homePath()
                                             + QLatin1String("/Library/Developer/Xcode/iOS DeviceSupport/")
                                             + osVersion + QLatin1String("/Symbols"));
        QString deviceSdk;
        if (deviceSdk1.toFileInfo().isDir()) {
            deviceSdk = deviceSdk1.toString();
        } else {
            Utils::FileName deviceSdk2 = IosConfigurations::developerPath()
                    .appendPath(QLatin1String("Platforms/iPhoneOS.platform/DeviceSupport/"))
                    .appendPath(osVersion).appendPath(QLatin1String("Symbols"));
            if (deviceSdk2.toFileInfo().isDir()) {
                deviceSdk = deviceSdk2.toString();
            } else {
                TaskHub::addTask(Task::Warning, tr(
                  "Could not find device specific debug symbols at %1. "
                  "Debugging initialization will be slow until you open the Organizer window of "
                  "Xcode with the device connected to have the symbols generated.")
                                 .arg(deviceSdk1.toUserOutput()),
                                 ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
            }
        }
        params.deviceSymbolsRoot = deviceSdk;
    } else {
        params.startMode = AttachExternal;
        params.platform = QLatin1String("ios-simulator");
    }
    params.displayName = runConfig->appName();
    params.remoteSetupNeeded = true;
    if (!params.breakOnMain)
        params.continueAfterAttach = true;

    Debugger::DebuggerRunConfigurationAspect *aspect
            = runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>();
    bool cppDebug = aspect->useCppDebugger();
    bool qmlDebug = aspect->useQmlDebugger();
    if (cppDebug) {
        params.languages |= CppLanguage;
        params.sysRoot = SysRootKitInformation::sysRoot(kit).toString();
        params.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString();
        if (ToolChain *tc = ToolChainKitInformation::toolChain(kit))
            params.toolChainAbi = tc->targetAbi();
        params.executable = runConfig->exePath().toString();
        params.remoteChannel = QLatin1String("connect://localhost:0");

        Utils::FileName xcodeInfo = IosConfigurations::developerPath().parentDir()
                .appendPath(QLatin1String("Info.plist"));
        bool buggyLldb = false;
        if (xcodeInfo.toFileInfo().exists()) {
            QSettings settings(xcodeInfo.toString(), QSettings::NativeFormat);
            QStringList version = settings.value(QLatin1String("CFBundleShortVersionString")).toString()
                    .split(QLatin1Char('.'));
            if (version.value(0).toInt() == 5 && version.value(1, QString::number(1)).toInt() == 0)
                buggyLldb = true;
        }
        QString bundlePath = runConfig->bundleDir().toString();
        bundlePath.chop(4);
        Utils::FileName dsymPath = Utils::FileName::fromString(
                    bundlePath.append(QLatin1String(".dSYM")));
        if (!dsymPath.toFileInfo().exists()) {
            if (buggyLldb)
                TaskHub::addTask(Task::Warning,
                                 tr("Debugging with Xcode 5.0.x can be unreliable without a dSYM. "
                                    "To create one, add a dsymutil deploystep."),
                                 ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
        } else if (dsymPath.toFileInfo().lastModified()
                   < QFileInfo(runConfig->exePath().toUserOutput()).lastModified()) {
            TaskHub::addTask(Task::Warning,
                             tr("The dSYM %1 seems to be outdated, it might confuse the debugger.")
                             .arg(dsymPath.toUserOutput()),
                             ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
        }
    }
    if (qmlDebug) {
        params.languages |= QmlLanguage;
        params.projectSourceDirectory = project->projectDirectory();
        params.projectSourceFiles = project->files(QmakeProject::ExcludeGeneratedFiles);
        params.projectBuildDirectory = project->rootQmakeProjectNode()->buildDir();
        if (!cppDebug)
            params.startMode = AttachToRemoteServer;
    }

    DebuggerRunControl * const debuggerRunControl
        = DebuggerPlugin::createDebugger(params, runConfig, errorMessage);
    if (debuggerRunControl)
        new IosDebugSupport(runConfig, debuggerRunControl, cppDebug, qmlDebug);
    return debuggerRunControl;
}

IosDebugSupport::IosDebugSupport(IosRunConfiguration *runConfig,
    DebuggerRunControl *runControl, bool cppDebug, bool qmlDebug)
    : QObject(runControl), m_runControl(runControl),
      m_runner(new IosRunner(this, runConfig, cppDebug, qmlDebug))
{
    connect(m_runControl->engine(), SIGNAL(requestRemoteSetup()),
            m_runner, SLOT(start()));
    connect(m_runControl, SIGNAL(finished()),
            m_runner, SLOT(stop()));

    connect(m_runner, SIGNAL(gotServerPorts(int,int)),
        SLOT(handleServerPorts(int,int)));
    connect(m_runner, SIGNAL(gotInferiorPid(Q_PID, int)),
        SLOT(handleGotInferiorPid(Q_PID, int)));
    connect(m_runner, SIGNAL(finished(bool)),
        SLOT(handleRemoteProcessFinished(bool)));

    connect(m_runner, SIGNAL(errorMsg(QString)),
        SLOT(handleRemoteErrorOutput(QString)));
    connect(m_runner, SIGNAL(appOutput(QString)),
        SLOT(handleRemoteOutput(QString)));
}

IosDebugSupport::~IosDebugSupport()
{
}

void IosDebugSupport::handleServerPorts(int gdbServerPort, int qmlPort)
{
    if (gdbServerPort > 0 || (m_runner && !m_runner->cppDebug() && qmlPort > 0)) {
        m_runControl->engine()->notifyEngineRemoteSetupDone(gdbServerPort, qmlPort);
    } else {
        m_runControl->engine()->notifyEngineRemoteSetupFailed(
                    tr("Could not get debug server file descriptor."));
    }
}

void IosDebugSupport::handleGotInferiorPid(Q_PID pid, int qmlPort)
{
    if (pid > 0) {
        //m_runControl->engine()->notifyInferiorPid(pid);
#ifndef Q_OS_WIN // Q_PID might be 64 bit pointer...
        m_runControl->engine()->notifyEngineRemoteSetupDone(int(pid), qmlPort);
#endif
    } else {
        m_runControl->engine()->notifyEngineRemoteSetupFailed(
                    tr("Got an invalid process id."));
    }
}

void IosDebugSupport::handleRemoteProcessFinished(bool cleanEnd)
{
    if (!cleanEnd && m_runControl)
        m_runControl->showMessage(tr("Run failed unexpectedly."), AppStuff);
    //m_runControl->engine()->notifyInferiorIll();
    m_runControl->engine()->abortDebugger();
}

void IosDebugSupport::handleRemoteOutput(const QString &output)
{
    if (m_runControl) {
        if (m_runControl->engine())
            m_runControl->engine()->showMessage(output, AppOutput);
        else
            m_runControl->showMessage(output, AppOutput);
    }
}

void IosDebugSupport::handleRemoteErrorOutput(const QString &output)
{
    if (m_runControl) {
        if (m_runControl->engine())
            m_runControl->engine()->showMessage(output, AppError);
        else
            m_runControl->showMessage(output, AppError);
    }
}

} // namespace Internal
} // namespace Ios
<commit_msg>Fix warning about unused variable in IOS.<commit_after>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "iosdebugsupport.h"

#include "iosrunner.h"
#include "iosmanager.h"
#include "iosdevice.h"

#include <debugger/debuggerengine.h>
#include <debugger/debuggerplugin.h>
#include <debugger/debuggerkitinformation.h>
#include <debugger/debuggerrunner.h>
#include <debugger/debuggerstartparameters.h>
#include <debugger/debuggerrunconfigurationaspect.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/target.h>
#include <projectexplorer/taskhub.h>
#include <qmakeprojectmanager/qmakebuildconfiguration.h>
#include <qmakeprojectmanager/qmakenodes.h>
#include <qmakeprojectmanager/qmakeproject.h>
#include <qtsupport/qtkitinformation.h>
#include <utils/fileutils.h>
#include <utils/qtcprocess.h>

#include <QDir>
#include <QTcpServer>
#include <QSettings>

#include <stdio.h>
#include <fcntl.h>
#ifdef Q_OS_UNIX
#include <unistd.h>
#else
#include <io.h>
#endif

using namespace Debugger;
using namespace ProjectExplorer;
using namespace QmakeProjectManager;

namespace Ios {
namespace Internal {

RunControl *IosDebugSupport::createDebugRunControl(IosRunConfiguration *runConfig,
                                                   QString *errorMessage)
{
    Target *target = runConfig->target();
    if (!target)
        return 0;
    ProjectExplorer::IDevice::ConstPtr device = DeviceKitInformation::device(target->kit());
    if (device.isNull())
        return 0;
    QmakeProject *project = static_cast<QmakeProject *>(target->project());
    Kit *kit = target->kit();

    DebuggerStartParameters params;
    if (device->type() == Core::Id(Ios::Constants::IOS_DEVICE_TYPE)) {
        params.startMode = AttachToRemoteProcess;
        params.platform = QLatin1String("remote-ios");
        IosDevice::ConstPtr iosDevice = device.dynamicCast<const IosDevice>();
        if (iosDevice.isNull())
                return 0;
        QString osVersion = iosDevice->osVersion();
        Utils::FileName deviceSdk1 = Utils::FileName::fromString(QDir::homePath()
                                             + QLatin1String("/Library/Developer/Xcode/iOS DeviceSupport/")
                                             + osVersion + QLatin1String("/Symbols"));
        QString deviceSdk;
        if (deviceSdk1.toFileInfo().isDir()) {
            deviceSdk = deviceSdk1.toString();
        } else {
            Utils::FileName deviceSdk2 = IosConfigurations::developerPath()
                    .appendPath(QLatin1String("Platforms/iPhoneOS.platform/DeviceSupport/"))
                    .appendPath(osVersion).appendPath(QLatin1String("Symbols"));
            if (deviceSdk2.toFileInfo().isDir()) {
                deviceSdk = deviceSdk2.toString();
            } else {
                TaskHub::addTask(Task::Warning, tr(
                  "Could not find device specific debug symbols at %1. "
                  "Debugging initialization will be slow until you open the Organizer window of "
                  "Xcode with the device connected to have the symbols generated.")
                                 .arg(deviceSdk1.toUserOutput()),
                                 ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
            }
        }
        params.deviceSymbolsRoot = deviceSdk;
    } else {
        params.startMode = AttachExternal;
        params.platform = QLatin1String("ios-simulator");
    }
    params.displayName = runConfig->appName();
    params.remoteSetupNeeded = true;
    if (!params.breakOnMain)
        params.continueAfterAttach = true;

    Debugger::DebuggerRunConfigurationAspect *aspect
            = runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>();
    bool cppDebug = aspect->useCppDebugger();
    bool qmlDebug = aspect->useQmlDebugger();
    if (cppDebug) {
        params.languages |= CppLanguage;
        params.sysRoot = SysRootKitInformation::sysRoot(kit).toString();
        params.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString();
        if (ToolChain *tc = ToolChainKitInformation::toolChain(kit))
            params.toolChainAbi = tc->targetAbi();
        params.executable = runConfig->exePath().toString();
        params.remoteChannel = QLatin1String("connect://localhost:0");

        Utils::FileName xcodeInfo = IosConfigurations::developerPath().parentDir()
                .appendPath(QLatin1String("Info.plist"));
        bool buggyLldb = false;
        if (xcodeInfo.toFileInfo().exists()) {
            QSettings settings(xcodeInfo.toString(), QSettings::NativeFormat);
            QStringList version = settings.value(QLatin1String("CFBundleShortVersionString")).toString()
                    .split(QLatin1Char('.'));
            if (version.value(0).toInt() == 5 && version.value(1, QString::number(1)).toInt() == 0)
                buggyLldb = true;
        }
        QString bundlePath = runConfig->bundleDir().toString();
        bundlePath.chop(4);
        Utils::FileName dsymPath = Utils::FileName::fromString(
                    bundlePath.append(QLatin1String(".dSYM")));
        if (!dsymPath.toFileInfo().exists()) {
            if (buggyLldb)
                TaskHub::addTask(Task::Warning,
                                 tr("Debugging with Xcode 5.0.x can be unreliable without a dSYM. "
                                    "To create one, add a dsymutil deploystep."),
                                 ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
        } else if (dsymPath.toFileInfo().lastModified()
                   < QFileInfo(runConfig->exePath().toUserOutput()).lastModified()) {
            TaskHub::addTask(Task::Warning,
                             tr("The dSYM %1 seems to be outdated, it might confuse the debugger.")
                             .arg(dsymPath.toUserOutput()),
                             ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
        }
    }
    if (qmlDebug) {
        params.languages |= QmlLanguage;
        params.projectSourceDirectory = project->projectDirectory();
        params.projectSourceFiles = project->files(QmakeProject::ExcludeGeneratedFiles);
        params.projectBuildDirectory = project->rootQmakeProjectNode()->buildDir();
        if (!cppDebug)
            params.startMode = AttachToRemoteServer;
    }

    DebuggerRunControl * const debuggerRunControl
        = DebuggerPlugin::createDebugger(params, runConfig, errorMessage);
    if (debuggerRunControl)
        new IosDebugSupport(runConfig, debuggerRunControl, cppDebug, qmlDebug);
    return debuggerRunControl;
}

IosDebugSupport::IosDebugSupport(IosRunConfiguration *runConfig,
    DebuggerRunControl *runControl, bool cppDebug, bool qmlDebug)
    : QObject(runControl), m_runControl(runControl),
      m_runner(new IosRunner(this, runConfig, cppDebug, qmlDebug))
{
    connect(m_runControl->engine(), SIGNAL(requestRemoteSetup()),
            m_runner, SLOT(start()));
    connect(m_runControl, SIGNAL(finished()),
            m_runner, SLOT(stop()));

    connect(m_runner, SIGNAL(gotServerPorts(int,int)),
        SLOT(handleServerPorts(int,int)));
    connect(m_runner, SIGNAL(gotInferiorPid(Q_PID, int)),
        SLOT(handleGotInferiorPid(Q_PID, int)));
    connect(m_runner, SIGNAL(finished(bool)),
        SLOT(handleRemoteProcessFinished(bool)));

    connect(m_runner, SIGNAL(errorMsg(QString)),
        SLOT(handleRemoteErrorOutput(QString)));
    connect(m_runner, SIGNAL(appOutput(QString)),
        SLOT(handleRemoteOutput(QString)));
}

IosDebugSupport::~IosDebugSupport()
{
}

void IosDebugSupport::handleServerPorts(int gdbServerPort, int qmlPort)
{
    if (gdbServerPort > 0 || (m_runner && !m_runner->cppDebug() && qmlPort > 0)) {
        m_runControl->engine()->notifyEngineRemoteSetupDone(gdbServerPort, qmlPort);
    } else {
        m_runControl->engine()->notifyEngineRemoteSetupFailed(
                    tr("Could not get debug server file descriptor."));
    }
}

void IosDebugSupport::handleGotInferiorPid(Q_PID pid, int qmlPort)
{
    if (pid > 0) {
        //m_runControl->engine()->notifyInferiorPid(pid);
        m_runControl->engine()->notifyEngineRemoteSetupDone(int(Utils::qPidToPid(pid)), qmlPort);
    } else {
        m_runControl->engine()->notifyEngineRemoteSetupFailed(
                    tr("Got an invalid process id."));
    }
}

void IosDebugSupport::handleRemoteProcessFinished(bool cleanEnd)
{
    if (!cleanEnd && m_runControl)
        m_runControl->showMessage(tr("Run failed unexpectedly."), AppStuff);
    //m_runControl->engine()->notifyInferiorIll();
    m_runControl->engine()->abortDebugger();
}

void IosDebugSupport::handleRemoteOutput(const QString &output)
{
    if (m_runControl) {
        if (m_runControl->engine())
            m_runControl->engine()->showMessage(output, AppOutput);
        else
            m_runControl->showMessage(output, AppOutput);
    }
}

void IosDebugSupport::handleRemoteErrorOutput(const QString &output)
{
    if (m_runControl) {
        if (m_runControl->engine())
            m_runControl->engine()->showMessage(output, AppError);
        else
            m_runControl->showMessage(output, AppError);
    }
}

} // namespace Internal
} // namespace Ios
<|endoftext|>