<commit_before>// KMail Account
#include <config.h>

#include "kmaccount.h"

#include "accountmanager.h"
using KMail::AccountManager;
#include "kmacctfolder.h"
#include "kmfoldermgr.h"
#include "kmfiltermgr.h"
#include "messagesender.h"
#include "kmmessage.h"
#include "broadcaststatus.h"
using KPIM::BroadcastStatus;
#include "kmfoldercachedimap.h"

#include "progressmanager.h"
using KPIM::ProgressItem;
using KPIM::ProgressManager;

using KMail::FolderJob;

#include <kapplication.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kconfig.h>

#include <qeventloop.h>

#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#include <assert.h>

//----------------------
#include "kmaccount.moc"

//-----------------------------------------------------------------------------
KMPrecommand::KMPrecommand(const QString &precommand, QObject *parent)
  : QObject(parent), mPrecommand(precommand)
{
  BroadcastStatus::instance()->setStatusMsg(
      i18n("Executing precommand %1").arg(precommand ));

  mPrecommandProcess.setUseShell(true);
  mPrecommandProcess << precommand;

  connect(&mPrecommandProcess, SIGNAL(processExited(KProcess *)),
          SLOT(precommandExited(KProcess *)));
}

//-----------------------------------------------------------------------------
KMPrecommand::~KMPrecommand()
{
}

//-----------------------------------------------------------------------------
bool KMPrecommand::start()
{
  bool ok = mPrecommandProcess.start( KProcess::NotifyOnExit );
  if (!ok) KMessageBox::error(0, i18n("Could not execute precommand '%1'.")
    .arg(mPrecommand));
  return ok;
}

//-----------------------------------------------------------------------------
void KMPrecommand::precommandExited(KProcess *p)
{
  int exitCode = p->normalExit() ? p->exitStatus() : -1;
  if (exitCode)
    KMessageBox::error(0, i18n("The precommand exited with code %1:\n%2")
      .arg(exitCode).arg(strerror(exitCode)));
  emit finished(!exitCode);
}

//-----------------------------------------------------------------------------
KMAccount::KMAccount(AccountManager* aOwner, const QString& aName, uint id)
  : KAccount( id, aName ),
    mTrash(KMKernel::self()->trashFolder()->idString()),
    mOwner(aOwner),
    mFolder(0),
    mTimer(0),
    mInterval(0),
    mExclude(false),
    mCheckingMail(false),
    mHasInbox(false),
    mMailCheckProgressItem(0),
    mPrecommandProcess(0)
{
  assert(aOwner != 0);
}

void KMAccount::init() {
  mTrash = kmkernel->trashFolder()->idString();
  mExclude = false;
  mInterval = 0;
  mNewInFolder.clear();
}

//-----------------------------------------------------------------------------
KMAccount::~KMAccount()
{
  if (!kmkernel->shuttingDown() && mFolder) mFolder->removeAccount(this);
  if (mTimer) deinstallTimer();
}

//-----------------------------------------------------------------------------
void KMAccount::setName(const QString& aName)
{
  mName = aName;
}

//-----------------------------------------------------------------------------
void KMAccount::clearPasswd()
{
}

//-----------------------------------------------------------------------------
void KMAccount::setFolder(KMFolder* aFolder, bool addAccount)
{
  if(!aFolder) {
    //kdDebug(5006) << "KMAccount::setFolder() : aFolder == 0" << endl;
    mFolder = 0;
    return;
  }
  mFolder = (KMAcctFolder*)aFolder;
  if (addAccount) mFolder->addAccount(this);
}

//-----------------------------------------------------------------------------
void KMAccount::readConfig(KConfig& config)
{
  QString folderName;
  mFolder = 0;
  folderName = config.readEntry("Folder");
  setCheckInterval(config.readNumEntry("check-interval", 0));
  setTrash(config.readEntry("trash", kmkernel->trashFolder()->idString()));
  setCheckExclude(config.readBoolEntry("check-exclude", false));
  setPrecommand(config.readPathEntry("precommand"));

  if (!folderName.isEmpty())
  {
    setFolder(kmkernel->folderMgr()->findIdString(folderName), true);
  }

  if (mInterval == 0)
    deinstallTimer();
  else
    installTimer();
}

//-----------------------------------------------------------------------------
void KMAccount::writeConfig(KConfig& config)
{
  // ID, Name
  KAccount::writeConfig(config);

  config.writeEntry("Type", type());
  config.writeEntry("Folder", mFolder ? mFolder->idString() : QString::null);
  config.writeEntry("check-interval", mInterval);
  config.writeEntry("check-exclude", mExclude);
  config.writePathEntry("precommand", mPrecommand);
  config.writeEntry("trash", mTrash);
}

//-----------------------------------------------------------------------------
void KMAccount::sendReceipt(KMMessage* aMsg)
{
  KConfig* cfg = KMKernel::config();
  bool sendReceipts;

  KConfigGroupSaver saver(cfg, "General");

  sendReceipts = cfg->readBoolEntry("send-receipts", false);
  if (!sendReceipts) return;

  KMMessage *newMsg = aMsg->createDeliveryReceipt();
  if (newMsg) {
    mReceipts.append(newMsg);
    QTimer::singleShot( 0, this, SLOT( sendReceipts() ) );
  }
}

//-----------------------------------------------------------------------------
bool KMAccount::processNewMsg(KMMessage* aMsg)
{
  int rc, processResult;

  assert(aMsg != 0);

  // Save this one for readding
  KMFolderCachedImap* parent = 0;
  if( type() == "cachedimap" )
    parent = static_cast<KMFolderCachedImap*>( aMsg->storage() );

  // checks whether we should send delivery receipts
  // and sends them.
  sendReceipt(aMsg);

  // Set status of new messages that are marked as old to read, otherwise
  // the user won't see which messages newly arrived.
  // This is only valid for pop accounts and produces wrong stati for imap.
  if ( type() != "cachedimap" && type() != "imap" ) {
    if ( aMsg->isOld() )
      aMsg->setStatus(KMMsgStatusUnread);  // -sanders
    //    aMsg->setStatus(KMMsgStatusRead);
    else
      aMsg->setStatus(KMMsgStatusNew);
  }
/*
QFile fileD0( "testdat_xx-kmaccount-0" );
if( fileD0.open( IO_WriteOnly ) ) {
    QDataStream ds( &fileD0 );
    ds.writeRawBytes( aMsg->asString(), aMsg->asString().length() );
    fileD0.close();  // If data is 0 we just create a zero length file.
}
*/
  // 0==message moved; 1==processing ok, no move; 2==critical error, abort!

  processResult = kmkernel->filterMgr()->process(aMsg,KMFilterMgr::Inbound,true,id());
  if (processResult == 2) {
    perror("Critical error: Unable to collect mail (out of space?)");
    KMessageBox::information(0,(i18n("Critical error: "
      "Unable to collect mail: ")) + QString::fromLocal8Bit(strerror(errno)));
    return false;
  }
  else if (processResult == 1)
  {
    if( type() == "cachedimap" )
      ; // already done by caller: parent->addMsgInternal( aMsg, false );
    else {
      // TODO: Perhaps it would be best, if this if was handled by a virtual
      // method, so the if( !dimap ) above could die?
      kmkernel->filterMgr()->tempOpenFolder(mFolder);
      rc = mFolder->addMsg(aMsg);
/*
QFile fileD0( "testdat_xx-kmaccount-1" );
if( fileD0.open( IO_WriteOnly ) ) {
    QDataStream ds( &fileD0 );
    ds.writeRawBytes( aMsg->asString(), aMsg->asString().length() );
    fileD0.close();  // If data is 0 we just create a zero length file.
}
*/
      if (rc) {
        perror("failed to add message");
        KMessageBox::information(0, i18n("Failed to add message:\n") +
                                 QString(strerror(rc)));
        return false;
      }
      int count = mFolder->count();
      // If count == 1, the message is immediately displayed
      if (count != 1) mFolder->unGetMsg(count - 1);
    }
  }

  // Count number of new messages for each folder
  QString folderId;
  if ( processResult == 1 ) {
    folderId = ( type() == "cachedimap" ) ? parent->folder()->idString()
                                          : mFolder->idString();
  }
  else {
    folderId = aMsg->parent()->idString();
  }
  addToNewInFolder( folderId, 1 );

  return true; //Everything's fine - message has been added by filter  }
}

//-----------------------------------------------------------------------------
void KMAccount::setCheckInterval(int aInterval)
{
  if (aInterval <= 0)
    mInterval = 0;
  else
    mInterval = aInterval;
  // Don't call installTimer from here! See #117935.
}

int KMAccount::checkInterval() const
{
  if ( mInterval <= 0 )
    return mInterval;
  return QMAX( mInterval, GlobalSettings::self()->minimumCheckInterval() );
}

//----------------------------------------------------------------------------
void KMAccount::deleteFolderJobs()
{
  mJobList.setAutoDelete(true);
  mJobList.clear();
  mJobList.setAutoDelete(false);
}

//----------------------------------------------------------------------------
void KMAccount::ignoreJobsForMessage( KMMessage* msg )
{
  //FIXME: remove, make folders handle those
  for( QPtrListIterator<FolderJob> it(mJobList); it.current(); ++it ) {
    if ( it.current()->msgList().first() == msg) {
      FolderJob *job = it.current();
      mJobList.remove( job );
      delete job;
      break;
    }
  }
}

//-----------------------------------------------------------------------------
void KMAccount::setCheckExclude(bool aExclude)
{
  mExclude = aExclude;
}

//-----------------------------------------------------------------------------
void KMAccount::installTimer()
{
  if (mInterval <= 0) return;
  if(!mTimer)
  {
    mTimer = new QTimer(0, "mTimer");
    connect(mTimer,SIGNAL(timeout()),SLOT(mailCheck()));
  }
  else
  {
    mTimer->stop();
  }
  mTimer->start( checkInterval() * 60000 );
}

//-----------------------------------------------------------------------------
void KMAccount::deinstallTimer()
{
  delete mTimer;
  mTimer = 0;
}

//-----------------------------------------------------------------------------
void KMAccount::startPrecommand(const QString &precommand)
{
  // Run the pre command if there is one
  if ( precommand.isEmpty() )
    emit precommandExited( true );

  KMPrecommand *mPrecommandProcess = new KMPrecommand(precommand, this);

  BroadcastStatus::instance()->setStatusMsg(
      i18n("Executing precommand %1").arg(precommand ));

  connect(mPrecommandProcess, SIGNAL(finished(bool)),
          SLOT(precommandFinished(bool)));

  kdDebug(5006) << "Running precommand " << precommand << endl;
  if (!mPrecommandProcess->start())
    emit precommandExited( false );
}
//-----------------------------------------------------------------------------
void KMAccount::precommandFinished( bool success )
{
  delete mPrecommandProcess; mPrecommandProcess = 0;

  emit precommandExited( success );
}
//-----------------------------------------------------------------------------
void KMAccount::mailCheck()
{
  if (mTimer)
    mTimer->stop();

  if ( kmkernel ) {
    AccountManager *acctmgr = kmkernel->acctMgr();
    if ( acctmgr )
      acctmgr->singleCheckMail(this, false);
  }
}

//-----------------------------------------------------------------------------
void KMAccount::sendReceipts()
{
  QValueList<KMMessage*>::Iterator it;
  for(it = mReceipts.begin(); it != mReceipts.end(); ++it)
    kmkernel->msgSender()->send(*it); //might process events
  mReceipts.clear();
}

//-----------------------------------------------------------------------------
QString KMAccount::encryptStr(const QString &aStr)
{
  QString result;
  for (uint i = 0; i < aStr.length(); i++)
    /* yes, no typo. can't encode ' ' or '!' because
       they're the unicode BOM. stupid scrambling. stupid. */
    result += (aStr[i].unicode() <= 0x21 ) ? aStr[i] :
      QChar(0x1001F - aStr[i].unicode());
  return result;
}

//-----------------------------------------------------------------------------
QString KMAccount::importPassword(const QString &aStr)
{
  unsigned int i, val;
  unsigned int len = aStr.length();
  QCString result;
  result.resize(len+1);

  for (i=0; i<len; i++)
  {
    val = aStr[i] - ' ';
    val = (255-' ') - val;
    result[i] = (char)(val + ' ');
  }
  result[i] = '\0';

  return encryptStr(result);
}

void KMAccount::invalidateIMAPFolders()
{
  // Default: Don't do anything. The IMAP account will handle it
}

void KMAccount::pseudoAssign( const KMAccount * a ) {
  if ( !a ) return;

  setName( a->name() );
  setId( a->id() );
  setCheckInterval( a->checkInterval() );
  setCheckExclude( a->checkExclude() );
  setFolder( a->folder() );
  setPrecommand( a->precommand() );
  setTrash( a->trash() );
}

//-----------------------------------------------------------------------------
void KMAccount::checkDone( bool newmail, CheckStatus status )
{
    setCheckingMail( false );
  // Reset the timeout for automatic mailchecking. The user might have
  // triggered the check manually.
  if (mTimer)
    mTimer->start( checkInterval() * 60000 );
  if ( mMailCheckProgressItem ) {
    // set mMailCheckProgressItem = 0 before calling setComplete() to prevent
    // a race condition
    ProgressItem *savedMailCheckProgressItem = mMailCheckProgressItem;
    mMailCheckProgressItem = 0;
    savedMailCheckProgressItem->setComplete(); // that will delete it
  }

  emit newMailsProcessed( mNewInFolder );
  emit finishedCheck( newmail, status );
  mNewInFolder.clear();
}

//-----------------------------------------------------------------------------
void KMAccount::addToNewInFolder( QString folderId, int num )
{
  if ( mNewInFolder.find( folderId ) == mNewInFolder.end() )
    mNewInFolder[folderId] = num;
  else
    mNewInFolder[folderId] += num;
}
<commit_msg>Fix crash on retrieving pop mail.<commit_after>// KMail Account
#include <config.h>

#include "kmaccount.h"

#include "accountmanager.h"
using KMail::AccountManager;
#include "kmacctfolder.h"
#include "kmfoldermgr.h"
#include "kmfiltermgr.h"
#include "messagesender.h"
#include "kmmessage.h"
#include "broadcaststatus.h"
using KPIM::BroadcastStatus;
#include "kmfoldercachedimap.h"

#include "progressmanager.h"
using KPIM::ProgressItem;
using KPIM::ProgressManager;

using KMail::FolderJob;

#include <kapplication.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kconfig.h>

#include <qeventloop.h>

#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#include <assert.h>

//----------------------
#include "kmaccount.moc"

//-----------------------------------------------------------------------------
KMPrecommand::KMPrecommand(const QString &precommand, QObject *parent)
  : QObject(parent), mPrecommand(precommand)
{
  BroadcastStatus::instance()->setStatusMsg(
      i18n("Executing precommand %1").arg(precommand ));

  mPrecommandProcess.setUseShell(true);
  mPrecommandProcess << precommand;

  connect(&mPrecommandProcess, SIGNAL(processExited(KProcess *)),
          SLOT(precommandExited(KProcess *)));
}

//-----------------------------------------------------------------------------
KMPrecommand::~KMPrecommand()
{
}

//-----------------------------------------------------------------------------
bool KMPrecommand::start()
{
  bool ok = mPrecommandProcess.start( KProcess::NotifyOnExit );
  if (!ok) KMessageBox::error(0, i18n("Could not execute precommand '%1'.")
    .arg(mPrecommand));
  return ok;
}

//-----------------------------------------------------------------------------
void KMPrecommand::precommandExited(KProcess *p)
{
  int exitCode = p->normalExit() ? p->exitStatus() : -1;
  if (exitCode)
    KMessageBox::error(0, i18n("The precommand exited with code %1:\n%2")
      .arg(exitCode).arg(strerror(exitCode)));
  emit finished(!exitCode);
}

//-----------------------------------------------------------------------------
KMAccount::KMAccount(AccountManager* aOwner, const QString& aName, uint id)
  : KAccount( id, aName ),
    mTrash(KMKernel::self()->trashFolder()->idString()),
    mOwner(aOwner),
    mFolder(0),
    mTimer(0),
    mInterval(0),
    mExclude(false),
    mCheckingMail(false),
    mHasInbox(false),
    mMailCheckProgressItem(0),
    mPrecommandProcess(0)
{
  assert(aOwner != 0);
}

void KMAccount::init() {
  mTrash = kmkernel->trashFolder()->idString();
  mExclude = false;
  mInterval = 0;
  mNewInFolder.clear();
}

//-----------------------------------------------------------------------------
KMAccount::~KMAccount()
{
  if (!kmkernel->shuttingDown() && mFolder) mFolder->removeAccount(this);
  if (mTimer) deinstallTimer();
}

//-----------------------------------------------------------------------------
void KMAccount::setName(const QString& aName)
{
  mName = aName;
}

//-----------------------------------------------------------------------------
void KMAccount::clearPasswd()
{
}

//-----------------------------------------------------------------------------
void KMAccount::setFolder(KMFolder* aFolder, bool addAccount)
{
  if(!aFolder) {
    //kdDebug(5006) << "KMAccount::setFolder() : aFolder == 0" << endl;
    mFolder = 0;
    return;
  }
  mFolder = (KMAcctFolder*)aFolder;
  if (addAccount) mFolder->addAccount(this);
}

//-----------------------------------------------------------------------------
void KMAccount::readConfig(KConfig& config)
{
  QString folderName;
  mFolder = 0;
  folderName = config.readEntry("Folder");
  setCheckInterval(config.readNumEntry("check-interval", 0));
  setTrash(config.readEntry("trash", kmkernel->trashFolder()->idString()));
  setCheckExclude(config.readBoolEntry("check-exclude", false));
  setPrecommand(config.readPathEntry("precommand"));

  if (!folderName.isEmpty())
  {
    setFolder(kmkernel->folderMgr()->findIdString(folderName), true);
  }

  if (mInterval == 0)
    deinstallTimer();
  else
    installTimer();
}

//-----------------------------------------------------------------------------
void KMAccount::writeConfig(KConfig& config)
{
  // ID, Name
  KAccount::writeConfig(config);

  config.writeEntry("Type", type());
  config.writeEntry("Folder", mFolder ? mFolder->idString() : QString::null);
  config.writeEntry("check-interval", mInterval);
  config.writeEntry("check-exclude", mExclude);
  config.writePathEntry("precommand", mPrecommand);
  config.writeEntry("trash", mTrash);
}

//-----------------------------------------------------------------------------
void KMAccount::sendReceipt(KMMessage* aMsg)
{
  KConfig* cfg = KMKernel::config();
  bool sendReceipts;

  KConfigGroupSaver saver(cfg, "General");

  sendReceipts = cfg->readBoolEntry("send-receipts", false);
  if (!sendReceipts) return;

  KMMessage *newMsg = aMsg->createDeliveryReceipt();
  if (newMsg) {
    mReceipts.append(newMsg);
    QTimer::singleShot( 0, this, SLOT( sendReceipts() ) );
  }
}

//-----------------------------------------------------------------------------
bool KMAccount::processNewMsg(KMMessage* aMsg)
{
  int rc, processResult;

  assert(aMsg != 0);

  // Save this one for readding
  KMFolderCachedImap* parent = 0;
  if( type() == "cachedimap" )
    parent = static_cast<KMFolderCachedImap*>( aMsg->storage() );

  // checks whether we should send delivery receipts
  // and sends them.
  sendReceipt(aMsg);

  // Set status of new messages that are marked as old to read, otherwise
  // the user won't see which messages newly arrived.
  // This is only valid for pop accounts and produces wrong stati for imap.
  if ( type() != "cachedimap" && type() != "imap" ) {
    if ( aMsg->isOld() )
      aMsg->setStatus(KMMsgStatusUnread);  // -sanders
    //    aMsg->setStatus(KMMsgStatusRead);
    else
      aMsg->setStatus(KMMsgStatusNew);
  }
/*
QFile fileD0( "testdat_xx-kmaccount-0" );
if( fileD0.open( IO_WriteOnly ) ) {
    QDataStream ds( &fileD0 );
    ds.writeRawBytes( aMsg->asString(), aMsg->asString().length() );
    fileD0.close();  // If data is 0 we just create a zero length file.
}
*/
  // 0==message moved; 1==processing ok, no move; 2==critical error, abort!

  processResult = kmkernel->filterMgr()->process(aMsg,KMFilterMgr::Inbound,true,id());
  if (processResult == 2) {
    perror("Critical error: Unable to collect mail (out of space?)");
    KMessageBox::information(0,(i18n("Critical error: "
      "Unable to collect mail: ")) + QString::fromLocal8Bit(strerror(errno)));
    return false;
  }
  else if (processResult == 1)
  {
    if( type() == "cachedimap" )
      ; // already done by caller: parent->addMsgInternal( aMsg, false );
    else {
      // TODO: Perhaps it would be best, if this if was handled by a virtual
      // method, so the if( !dimap ) above could die?
      kmkernel->filterMgr()->tempOpenFolder(mFolder);
      rc = mFolder->addMsg(aMsg);
/*
QFile fileD0( "testdat_xx-kmaccount-1" );
if( fileD0.open( IO_WriteOnly ) ) {
    QDataStream ds( &fileD0 );
    ds.writeRawBytes( aMsg->asString(), aMsg->asString().length() );
    fileD0.close();  // If data is 0 we just create a zero length file.
}
*/
      if (rc) {
        perror("failed to add message");
        KMessageBox::information(0, i18n("Failed to add message:\n") +
                                 QString(strerror(rc)));
        return false;
      }
      int count = mFolder->count();
      // If count == 1, the message is immediately displayed
      if (count != 1) mFolder->unGetMsg(count - 1);
    }
  }

  // Count number of new messages for each folder
  QString folderId;
  if ( processResult == 1 ) {
    folderId = ( type() == "cachedimap" ) ? parent->folder()->idString()
                                          : mFolder->idString();
  }
  else {
    folderId = aMsg->parent()->idString();
  }
  addToNewInFolder( folderId, 1 );

  return true; //Everything's fine - message has been added by filter  }
}

//-----------------------------------------------------------------------------
void KMAccount::setCheckInterval(int aInterval)
{
  if (aInterval <= 0)
    mInterval = 0;
  else
    mInterval = aInterval;
  // Don't call installTimer from here! See #117935.
}

int KMAccount::checkInterval() const
{
  if ( mInterval <= 0 )
    return mInterval;
  return QMAX( mInterval, GlobalSettings::self()->minimumCheckInterval() );
}

//----------------------------------------------------------------------------
void KMAccount::deleteFolderJobs()
{
  mJobList.setAutoDelete(true);
  mJobList.clear();
  mJobList.setAutoDelete(false);
}

//----------------------------------------------------------------------------
void KMAccount::ignoreJobsForMessage( KMMessage* msg )
{
  //FIXME: remove, make folders handle those
  for( QPtrListIterator<FolderJob> it(mJobList); it.current(); ++it ) {
    if ( it.current()->msgList().first() == msg) {
      FolderJob *job = it.current();
      mJobList.remove( job );
      delete job;
      break;
    }
  }
}

//-----------------------------------------------------------------------------
void KMAccount::setCheckExclude(bool aExclude)
{
  mExclude = aExclude;
}

//-----------------------------------------------------------------------------
void KMAccount::installTimer()
{
  if (mInterval <= 0) return;
  if(!mTimer)
  {
    mTimer = new QTimer(0, "mTimer");
    connect(mTimer,SIGNAL(timeout()),SLOT(mailCheck()));
  }
  else
  {
    mTimer->stop();
  }
  mTimer->start( checkInterval() * 60000 );
}

//-----------------------------------------------------------------------------
void KMAccount::deinstallTimer()
{
  delete mTimer;
  mTimer = 0;
}

//-----------------------------------------------------------------------------
void KMAccount::startPrecommand(const QString &precommand)
{
  // Run the pre command if there is one
  if ( precommand.isEmpty() ) {
    emit precommandExited( true );
    return;
  }

  KMPrecommand *mPrecommandProcess = new KMPrecommand(precommand, this);

  BroadcastStatus::instance()->setStatusMsg(
      i18n("Executing precommand %1").arg(precommand ));

  connect(mPrecommandProcess, SIGNAL(finished(bool)),
          SLOT(precommandFinished(bool)));

  kdDebug(5006) << "Running precommand " << precommand << endl;
  if (!mPrecommandProcess->start())
    emit precommandExited( false );
}
//-----------------------------------------------------------------------------
void KMAccount::precommandFinished( bool success )
{
  delete mPrecommandProcess; mPrecommandProcess = 0;

  emit precommandExited( success );
}
//-----------------------------------------------------------------------------
void KMAccount::mailCheck()
{
  if (mTimer)
    mTimer->stop();

  if ( kmkernel ) {
    AccountManager *acctmgr = kmkernel->acctMgr();
    if ( acctmgr )
      acctmgr->singleCheckMail(this, false);
  }
}

//-----------------------------------------------------------------------------
void KMAccount::sendReceipts()
{
  QValueList<KMMessage*>::Iterator it;
  for(it = mReceipts.begin(); it != mReceipts.end(); ++it)
    kmkernel->msgSender()->send(*it); //might process events
  mReceipts.clear();
}

//-----------------------------------------------------------------------------
QString KMAccount::encryptStr(const QString &aStr)
{
  QString result;
  for (uint i = 0; i < aStr.length(); i++)
    /* yes, no typo. can't encode ' ' or '!' because
       they're the unicode BOM. stupid scrambling. stupid. */
    result += (aStr[i].unicode() <= 0x21 ) ? aStr[i] :
      QChar(0x1001F - aStr[i].unicode());
  return result;
}

//-----------------------------------------------------------------------------
QString KMAccount::importPassword(const QString &aStr)
{
  unsigned int i, val;
  unsigned int len = aStr.length();
  QCString result;
  result.resize(len+1);

  for (i=0; i<len; i++)
  {
    val = aStr[i] - ' ';
    val = (255-' ') - val;
    result[i] = (char)(val + ' ');
  }
  result[i] = '\0';

  return encryptStr(result);
}

void KMAccount::invalidateIMAPFolders()
{
  // Default: Don't do anything. The IMAP account will handle it
}

void KMAccount::pseudoAssign( const KMAccount * a ) {
  if ( !a ) return;

  setName( a->name() );
  setId( a->id() );
  setCheckInterval( a->checkInterval() );
  setCheckExclude( a->checkExclude() );
  setFolder( a->folder() );
  setPrecommand( a->precommand() );
  setTrash( a->trash() );
}

//-----------------------------------------------------------------------------
void KMAccount::checkDone( bool newmail, CheckStatus status )
{
    setCheckingMail( false );
  // Reset the timeout for automatic mailchecking. The user might have
  // triggered the check manually.
  if (mTimer)
    mTimer->start( checkInterval() * 60000 );
  if ( mMailCheckProgressItem ) {
    // set mMailCheckProgressItem = 0 before calling setComplete() to prevent
    // a race condition
    ProgressItem *savedMailCheckProgressItem = mMailCheckProgressItem;
    mMailCheckProgressItem = 0;
    savedMailCheckProgressItem->setComplete(); // that will delete it
  }

  emit newMailsProcessed( mNewInFolder );
  emit finishedCheck( newmail, status );
  mNewInFolder.clear();
}

//-----------------------------------------------------------------------------
void KMAccount::addToNewInFolder( QString folderId, int num )
{
  if ( mNewInFolder.find( folderId ) == mNewInFolder.end() )
    mNewInFolder[folderId] = num;
  else
    mNewInFolder[folderId] += num;
}
<|endoftext|>


<commit_before>//
// Copyright (C) 2004-2006 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004-2006 Pingtel Corp.  All rights reserved.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// SYSTEM INCLUDES
#include <limits.h>

// APPLICATION INCLUDES
#include "utl/UtlRandom.h"
#include "os/OsTime.h"
#include "os/OsDateTime.h"

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

// Constructor
UtlRandom::UtlRandom()
{
    static int count = 0 ;

    OsTime now ;
    OsDateTime::getCurTime(now) ;
    srand((int) (now.cvtToMsecs() % INT_MAX) ^ ++count) ;
}

// Constructor
UtlRandom::UtlRandom(int seed)
{
    srand(seed) ;

}

// Destructor
UtlRandom::~UtlRandom()
{
}

/* ============================ MANIPULATORS ============================== */

/* ============================ ACCESSORS ================================= */

int UtlRandom::rand()
{
    return ::rand() ;
}

/* ============================ INQUIRY =================================== */

/* //////////////////////////// PROTECTED ///////////////////////////////// */

/* //////////////////////////// PRIVATE /////////////////////////////////// */

/* ============================ FUNCTIONS ================================= */

<commit_msg>Tweaked seed generation in UtlRandom<commit_after>//
// Copyright (C) 2004-2006 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004-2006 Pingtel Corp.  All rights reserved.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// SYSTEM INCLUDES
#include <limits.h>

// APPLICATION INCLUDES
#include "utl/UtlRandom.h"
#include "os/OsTime.h"
#include "os/OsDateTime.h"
#include "os/OsTask.h"

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

// Constructor
UtlRandom::UtlRandom()
{
    int iTaskId = 0 ;
    OsTime now ;
    unsigned int seed ;

    OsTask::getCurrentTaskId(iTaskId) ;
    OsDateTime::getCurTime(now) ;

    seed = (now.cvtToMsecs() ^ (now.usecs() + now.usecs() << 16) ^ iTaskId) ;

    srand(seed) ;
}

// Constructor
UtlRandom::UtlRandom(int seed)
{
    srand(seed) ;
}

// Destructor
UtlRandom::~UtlRandom()
{
}

/* ============================ MANIPULATORS ============================== */

/* ============================ ACCESSORS ================================= */

int UtlRandom::rand()
{
    return ::rand() ;
}

/* ============================ INQUIRY =================================== */

/* //////////////////////////// PROTECTED ///////////////////////////////// */

/* //////////////////////////// PRIVATE /////////////////////////////////// */

/* ============================ FUNCTIONS ================================= */

<|endoftext|>


<commit_before>/** \copyright
 * Copyright (c) 2015, Balazs Racz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file MultiConfiguredConsumer.hxx
 *
 * Consumer class that uses CDI configuration and many GPIO pins to export a
 * multiple of output pins as two event consumers each to OpenLCB.
 *
 * @author Balazs Racz
 * @date 6 Sep 2015
 */

#ifndef _NMRANET_MULTICONFIGUREDCONSUMER_HXX_
#define _NMRANET_MULTICONFIGUREDCONSUMER_HXX_

#include "openlcb/ConfigRepresentation.hxx"

namespace openlcb
{

/// Version of the @ref ConfiguredConsumer class that can handle many GPIO pins
/// with two events each. This saves very significan amount of memory compared
/// to instantiating individual ConfigredConsumer instances -- helpful when a
/// single small MCU is exporting a large number of IOs via for example shift
/// register outputs.
class MultiConfiguredConsumer : public ConfigUpdateListener,
                                private SimpleEventHandler
{
public:
    typedef ConsumerConfig config_entry_type;

    template <unsigned N>
    __attribute__((noinline))
    MultiConfiguredConsumer(Node *node, const Gpio *const *pins, unsigned size,
        const RepeatedGroup<config_entry_type, N> &config)
        : node_(node)
        , pins_(pins)
        , size_(N)
        , offset_(config)
    {
        HASSERT(size_ == N);
        ConfigUpdateService::instance()->register_update_listener(this);
    }

    ~MultiConfiguredConsumer()
    {
        do_unregister();
        ConfigUpdateService::instance()->unregister_update_listener(this);
    }

    UpdateAction apply_configuration(int fd, bool initial_load,
                                     BarrierNotifiable *done) OVERRIDE
    {
        AutoNotify n(done);

        if (!initial_load)
        {
            // There is no way to figure out what the previously registered
            // eventid values were for the individual pins. Therefore we always
            // unregister everything and register them anew. It also causes us
            // to identify all. This is not a problem since apply_configuration
            // is coming from a user action.
            do_unregister();
        }
        RepeatedGroup<config_entry_type, UINT_MAX> grp_ref(offset_.offset());
        for (unsigned i = 0; i < size_; ++i)
        {
            const config_entry_type cfg_ref(grp_ref.entry(i));
            EventId cfg_event_on = cfg_ref.event_on().read(fd);
            EventId cfg_event_off = cfg_ref.event_off().read(fd);
            EventRegistry::instance()->register_handler(
                EventRegistryEntry(this, cfg_event_off, i * 2), 0);
            EventRegistry::instance()->register_handler(
                EventRegistryEntry(this, cfg_event_on, i * 2 + 1), 0);
        }
        return REINIT_NEEDED; // Causes events identify.
    }

    /// @todo(balazs.racz): implement
    void factory_reset(int fd) OVERRIDE
    {
    }

    // Implementations for the event handler functions.

    void handle_identify_global(const EventRegistryEntry &registry_entry,
                              EventReport *event, BarrierNotifiable *done)
        OVERRIDE
    {
        if (event->dst_node && event->dst_node != node_)
        {
            return done->notify();
        }
        SendConsumerIdentified(registry_entry, done);
    }

    void handle_identify_consumer(const EventRegistryEntry &registry_entry,
                                EventReport *event, BarrierNotifiable *done)
        OVERRIDE
    {
        if (event->event != registry_entry.event)
        {
            return done->notify();
        }
        SendConsumerIdentified(registry_entry, done);
    }

    void handle_event_report(const EventRegistryEntry &registry_entry,
                           EventReport *event, BarrierNotifiable *done) OVERRIDE
    {
        if (event->event != registry_entry.event)
        {
            return done->notify();
        }
        const Gpio *pin = pins_[registry_entry.user_arg >> 1];
        const bool is_on = (registry_entry.user_arg & 1);
        pin->write(is_on);
        done->notify();
    }

private:
    /// Sends out a ConsumerIdentified message for the given registration
    /// entry.
    void SendConsumerIdentified(const EventRegistryEntry &registry_entry,
                                BarrierNotifiable *done)
    {
        Defs::MTI mti = Defs::MTI_CONSUMER_IDENTIFIED_VALID;
        if (pins_[registry_entry.user_arg >> 1]->is_clr())
        {
            mti++; // INVALID
        }
        event_write_helper3.WriteAsync(node_, mti, WriteHelper::global(),
                                       eventid_to_buffer(registry_entry.event),
                                       done);
    }

    /// Removed registration of this event handler from the global event
    /// registry.
    void do_unregister()
    {
        EventRegistry::instance()->unregister_handler(this);
    }

    Node *node_;              //< virtual node to export the consumer on
    const Gpio *const *pins_; //< array of all GPIO pins to use
    size_t size_;             //< number of GPIO pins to export
    ConfigReference offset_;  //< Offset in the configuration space for our
    // configs.
};

} // namespace openlcb

#endif // _NMRANET_MULTICONFIGUREDCONSUMER_HXX_
<commit_msg>Fixes bug in MultiConfiguredConsumer that caused incorrect state to be reported upon boot.<commit_after>/** \copyright
 * Copyright (c) 2015, Balazs Racz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file MultiConfiguredConsumer.hxx
 *
 * Consumer class that uses CDI configuration and many GPIO pins to export a
 * multiple of output pins as two event consumers each to OpenLCB.
 *
 * @author Balazs Racz
 * @date 6 Sep 2015
 */

#ifndef _NMRANET_MULTICONFIGUREDCONSUMER_HXX_
#define _NMRANET_MULTICONFIGUREDCONSUMER_HXX_

#include "openlcb/ConfigRepresentation.hxx"

namespace openlcb
{

/// Version of the @ref ConfiguredConsumer class that can handle many GPIO pins
/// with two events each. This saves very significan amount of memory compared
/// to instantiating individual ConfigredConsumer instances -- helpful when a
/// single small MCU is exporting a large number of IOs via for example shift
/// register outputs.
class MultiConfiguredConsumer : public ConfigUpdateListener,
                                private SimpleEventHandler
{
public:
    typedef ConsumerConfig config_entry_type;

    template <unsigned N>
    __attribute__((noinline))
    MultiConfiguredConsumer(Node *node, const Gpio *const *pins, unsigned size,
        const RepeatedGroup<config_entry_type, N> &config)
        : node_(node)
        , pins_(pins)
        , size_(N)
        , offset_(config)
    {
        HASSERT(size_ == N);
        ConfigUpdateService::instance()->register_update_listener(this);
    }

    ~MultiConfiguredConsumer()
    {
        do_unregister();
        ConfigUpdateService::instance()->unregister_update_listener(this);
    }

    UpdateAction apply_configuration(int fd, bool initial_load,
                                     BarrierNotifiable *done) OVERRIDE
    {
        AutoNotify n(done);

        if (!initial_load)
        {
            // There is no way to figure out what the previously registered
            // eventid values were for the individual pins. Therefore we always
            // unregister everything and register them anew. It also causes us
            // to identify all. This is not a problem since apply_configuration
            // is coming from a user action.
            do_unregister();
        }
        RepeatedGroup<config_entry_type, UINT_MAX> grp_ref(offset_.offset());
        for (unsigned i = 0; i < size_; ++i)
        {
            const config_entry_type cfg_ref(grp_ref.entry(i));
            EventId cfg_event_on = cfg_ref.event_on().read(fd);
            EventId cfg_event_off = cfg_ref.event_off().read(fd);
            EventRegistry::instance()->register_handler(
                EventRegistryEntry(this, cfg_event_off, i * 2), 0);
            EventRegistry::instance()->register_handler(
                EventRegistryEntry(this, cfg_event_on, i * 2 + 1), 0);
        }
        return REINIT_NEEDED; // Causes events identify.
    }

    /// @todo(balazs.racz): implement
    void factory_reset(int fd) OVERRIDE
    {
    }

    // Implementations for the event handler functions.

    void handle_identify_global(const EventRegistryEntry &registry_entry,
                              EventReport *event, BarrierNotifiable *done)
        OVERRIDE
    {
        if (event->dst_node && event->dst_node != node_)
        {
            return done->notify();
        }
        SendConsumerIdentified(registry_entry, done);
    }

    void handle_identify_consumer(const EventRegistryEntry &registry_entry,
                                EventReport *event, BarrierNotifiable *done)
        OVERRIDE
    {
        if (event->event != registry_entry.event)
        {
            return done->notify();
        }
        SendConsumerIdentified(registry_entry, done);
    }

    void handle_event_report(const EventRegistryEntry &registry_entry,
                           EventReport *event, BarrierNotifiable *done) OVERRIDE
    {
        if (event->event != registry_entry.event)
        {
            return done->notify();
        }
        const Gpio *pin = pins_[registry_entry.user_arg >> 1];
        const bool is_on = (registry_entry.user_arg & 1);
        pin->write(is_on);
        done->notify();
    }

private:
    /// Sends out a ConsumerIdentified message for the given registration
    /// entry.
    void SendConsumerIdentified(const EventRegistryEntry &registry_entry,
                                BarrierNotifiable *done)
    {
        Defs::MTI mti = Defs::MTI_CONSUMER_IDENTIFIED_VALID;
        unsigned b1 = pins_[registry_entry.user_arg >> 1]->is_set() ? 1 : 0;
        unsigned b2 = registry_entry.user_arg & 1;  // on or off event?
        if (b1 ^ b2)
        {
            mti++; // INVALID
        }
        event_write_helper3.WriteAsync(node_, mti, WriteHelper::global(),
                                       eventid_to_buffer(registry_entry.event),
                                       done);
    }

    /// Removed registration of this event handler from the global event
    /// registry.
    void do_unregister()
    {
        EventRegistry::instance()->unregister_handler(this);
    }

    Node *node_;              //< virtual node to export the consumer on
    const Gpio *const *pins_; //< array of all GPIO pins to use
    size_t size_;             //< number of GPIO pins to export
    ConfigReference offset_;  //< Offset in the configuration space for our
    // configs.
};

} // namespace openlcb

#endif // _NMRANET_MULTICONFIGUREDCONSUMER_HXX_
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: basmgr.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 16:45:06 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SFX_BASMGR_HXX
#define _SFX_BASMGR_HXX

#ifndef _BASMGR_HXX_
#include <basic/basmgr.hxx>
#endif

#endif  //_SFX_BASMGR_HXX
<commit_msg>INTEGRATION: CWS changefileheader (1.8.732); FILE MERGED 2008/03/31 13:37:53 rt 1.8.732.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: basmgr.hxx,v $
 * $Revision: 1.9 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SFX_BASMGR_HXX
#define _SFX_BASMGR_HXX

#ifndef _BASMGR_HXX_
#include <basic/basmgr.hxx>
#endif

#endif  //_SFX_BASMGR_HXX
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id: map.hpp 39 2005-04-10 20:39:53Z pavlenko $

#ifndef MAP_HPP
#define MAP_HPP

#include <mapnik/feature_type_style.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/layer.hpp>
#include <boost/optional/optional.hpp>

namespace mapnik
{
    class MAPNIK_DECL Map
    {
        static const unsigned MIN_MAPSIZE=16;
        static const unsigned MAX_MAPSIZE=MIN_MAPSIZE<<10;
        unsigned width_;
        unsigned height_;
        std::string  srs_;
        boost::optional<Color> background_;
        std::map<std::string,feature_type_style> styles_;
        std::vector<Layer> layers_;
        Envelope<double> currentExtent_;

    public:
        typedef std::map<std::string,feature_type_style>::const_iterator const_style_iterator;
        typedef std::map<std::string,feature_type_style>::iterator style_iterator;

        /*! \brief Default constructor.
         *
         *  Creates a map with these parameters:
         *  - width = 400
         *  - height = 400
         *  - projection = "+proj=latlong +datum=WGS84"
         */
        Map();

        /*! \brief Constructor
         *  @param width Initial map width.
         *  @param height Initial map height.
         *  @param srs Initial map projection.
         */
        Map(int width, int height, std::string const& srs="+proj=latlong +datum=WGS84");

        /*! \brief Copy Constructur.
         *
         *  @param rhs Map to copy from.
         */
        Map(const Map& rhs);

        /*! \brief Assignment operator
         *
         *  TODO: to be documented
         *
         */
        Map& operator=(const Map& rhs);

        /*! \brief Get all styles
         * @return Const reference to styles
         */
        std::map<std::string,feature_type_style> const& styles() const;

        /*! \brief Get all styles
         * @return Non-constant reference to styles
         */
        std::map<std::string,feature_type_style> & styles();

        /*! \brief Get first iterator in styles.
         *  @return Constant style iterator.
         */
        const_style_iterator begin_styles() const;

        /*! \brief Get last iterator in styles.
         *  @return Constant style iterator.
         */
        const_style_iterator end_styles() const;

        /*! \brief Get first iterator in styles.
         *  @return Non-constant style iterator.
         */
        style_iterator begin_styles();

        /*! \brief Get last iterator in styles.
         *  @return Non-constant style iterator.
         */
        style_iterator end_styles();

        /*! \brief Insert a style in the map.
         *  @param name The name of the style.
         *  @param style The style to insert.
         *  @return true If success.
         *  @return false If no success.
         */
        bool insert_style(std::string const& name,feature_type_style const& style);

        /*! \brief Remove a style from the map.
         *  @param The name of the style.
         */
        void remove_style(const std::string& name);

        /*! \brief Find a style.
         * @param name The name of the style.
         *  @return The style if found. If not found return the default map style.
         */
        feature_type_style const& find_style(std::string const& name) const;

        /*! \brief Get number of all layers.
         */
        size_t layerCount() const;

        /*! \brief Add a layer to the map.
         *  @param l The layer to add.
         */
        void addLayer(const Layer& l);

        /*! \brief Get a layer.
         *  @param index Layer number.
         *  @return Constant layer.
         */
        const Layer& getLayer(size_t index) const;

        /*! \brief Get a layer.
         *  @param index Layer number.
         *  @return Non-constant layer.
         */
        Layer& getLayer(size_t index);

        /*! \brief Remove a layer.
         *  @param index Layer number.
         */
        void removeLayer(size_t index);

        /*! \brief Get all layers.
         *  @return Constant layers.
         */
        std::vector<Layer> const& layers() const;

        /*! \brief Get all layers.
         *  @return Non-constant layers.
         */
        std::vector<Layer> & layers();

        /*! \brief Remove all layers and styles from the map.
         */
        void remove_all();

        /*! \brief Get map width.
         */
        unsigned getWidth() const;

        /*! \brief Get map height.
         */
        unsigned getHeight() const;

        /*! \brief Set map width.
         */
        void setWidth(unsigned width);

        /*! \brief Set map height.
         */
        void setHeight(unsigned height);

        /*! \brief Resize the map.
         */
        void resize(unsigned width,unsigned height);

        /*! \brief Get the map projection.
         *  @return Map projection.
         */
        std::string const& srs() const;

        /*! \brief Set the map projection.
         *  @param srs Map projection.
         */
        void set_srs(std::string const& srs);

        /*! \brief Set the map background color.
         *  @param c Background color.
         */
        void set_background(const Color& c);

        /*! \brief Get the map background color
         *  @return Background color as boost::optional
         *  object
         */
        boost::optional<Color> const& background() const;

        /*! \brief Zoom the map at the current position.
         *  @param factor The factor how much the map is zoomed in or out.
         */
        void zoom(double factor);

        /*! \brief Zoom the map to a bounding box.
         *
         *  Aspect is handled automatic if not fitting to width/height.
         *  @param box The bounding box where to zoom.
         */
        void zoomToBox(const Envelope<double>& box);

        /*! \brief Zoom the map to show all data.
         */
        void zoom_all();

        void pan(int x,int y);

        void pan_and_zoom(int x,int y,double zoom);

        /*! \brief Get current bounding box.
         *  @return The current bounding box.
         */
        const Envelope<double>& getCurrentExtent() const;

        double scale() const;

        CoordTransform view_transform() const;

        featureset_ptr query_point(unsigned index, double x, double y) const;

        featureset_ptr query_map_point(unsigned index, double x, double y) const;
        ~Map();
    private:
        void fixAspectRatio();
    };
}

#endif //MAP_HPP
<commit_msg>only minor docs<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id: map.hpp 39 2005-04-10 20:39:53Z pavlenko $

#ifndef MAP_HPP
#define MAP_HPP

#include <mapnik/feature_type_style.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/layer.hpp>
#include <boost/optional/optional.hpp>

namespace mapnik
{
    class MAPNIK_DECL Map
    {
        static const unsigned MIN_MAPSIZE=16;
        static const unsigned MAX_MAPSIZE=MIN_MAPSIZE<<10;
        unsigned width_;
        unsigned height_;
        std::string  srs_;
        boost::optional<Color> background_;
        std::map<std::string,feature_type_style> styles_;
        std::vector<Layer> layers_;
        Envelope<double> currentExtent_;

    public:
        typedef std::map<std::string,feature_type_style>::const_iterator const_style_iterator;
        typedef std::map<std::string,feature_type_style>::iterator style_iterator;

        /*! \brief Default constructor.
         *
         *  Creates a map with these parameters:
         *  - width = 400
         *  - height = 400
         *  - projection = "+proj=latlong +datum=WGS84"
         */
        Map();

        /*! \brief Constructor
         *  @param width Initial map width.
         *  @param height Initial map height.
         *  @param srs Initial map projection.
         */
        Map(int width, int height, std::string const& srs="+proj=latlong +datum=WGS84");

        /*! \brief Copy Constructur.
         *
         *  @param rhs Map to copy from.
         */
        Map(const Map& rhs);

        /*! \brief Assignment operator
         *
         *  TODO: to be documented
         *
         */
        Map& operator=(const Map& rhs);

        /*! \brief Get all styles
         * @return Const reference to styles
         */
        std::map<std::string,feature_type_style> const& styles() const;

        /*! \brief Get all styles
         * @return Non-constant reference to styles
         */
        std::map<std::string,feature_type_style> & styles();

        /*! \brief Get first iterator in styles.
         *  @return Constant style iterator.
         */
        const_style_iterator begin_styles() const;

        /*! \brief Get last iterator in styles.
         *  @return Constant style iterator.
         */
        const_style_iterator end_styles() const;

        /*! \brief Get first iterator in styles.
         *  @return Non-constant style iterator.
         */
        style_iterator begin_styles();

        /*! \brief Get last iterator in styles.
         *  @return Non-constant style iterator.
         */
        style_iterator end_styles();

        /*! \brief Insert a style in the map.
         *  @param name The name of the style.
         *  @param style The style to insert.
         *  @return true If success.
         *  @return false If no success.
         */
        bool insert_style(std::string const& name,feature_type_style const& style);

        /*! \brief Remove a style from the map.
         *  @param name The name of the style.
         */
        void remove_style(const std::string& name);

        /*! \brief Find a style.
         *  @param name The name of the style.
         *  @return The style if found. If not found return the default map style.
         */
        feature_type_style const& find_style(std::string const& name) const;

        /*! \brief Get number of all layers.
         */
        size_t layerCount() const;

        /*! \brief Add a layer to the map.
         *  @param l The layer to add.
         */
        void addLayer(const Layer& l);

        /*! \brief Get a layer.
         *  @param index Layer number.
         *  @return Constant layer.
         */
        const Layer& getLayer(size_t index) const;

        /*! \brief Get a layer.
         *  @param index Layer number.
         *  @return Non-constant layer.
         */
        Layer& getLayer(size_t index);

        /*! \brief Remove a layer.
         *  @param index Layer number.
         */
        void removeLayer(size_t index);

        /*! \brief Get all layers.
         *  @return Constant layers.
         */
        std::vector<Layer> const& layers() const;

        /*! \brief Get all layers.
         *  @return Non-constant layers.
         */
        std::vector<Layer> & layers();

        /*! \brief Remove all layers and styles from the map.
         */
        void remove_all();

        /*! \brief Get map width.
         */
        unsigned getWidth() const;

        /*! \brief Get map height.
         */
        unsigned getHeight() const;

        /*! \brief Set map width.
         */
        void setWidth(unsigned width);

        /*! \brief Set map height.
         */
        void setHeight(unsigned height);

        /*! \brief Resize the map.
         */
        void resize(unsigned width,unsigned height);

        /*! \brief Get the map projection.
         *  @return Map projection.
         */
        std::string const& srs() const;

        /*! \brief Set the map projection.
         *  @param srs Map projection.
         */
        void set_srs(std::string const& srs);

        /*! \brief Set the map background color.
         *  @param c Background color.
         */
        void set_background(const Color& c);

        /*! \brief Get the map background color
         *  @return Background color as boost::optional
         *  object
         */
        boost::optional<Color> const& background() const;

        /*! \brief Zoom the map at the current position.
         *  @param factor The factor how much the map is zoomed in or out.
         */
        void zoom(double factor);

        /*! \brief Zoom the map to a bounding box.
         *
         *  Aspect is handled automatic if not fitting to width/height.
         *  @param box The bounding box where to zoom.
         */
        void zoomToBox(const Envelope<double>& box);

        /*! \brief Zoom the map to show all data.
         */
        void zoom_all();

        void pan(int x,int y);

        void pan_and_zoom(int x,int y,double zoom);

        /*! \brief Get current bounding box.
         *  @return The current bounding box.
         */
        const Envelope<double>& getCurrentExtent() const;

        double scale() const;

        CoordTransform view_transform() const;

        featureset_ptr query_point(unsigned index, double x, double y) const;

        featureset_ptr query_map_point(unsigned index, double x, double y) const;
        ~Map();
    private:
        void fixAspectRatio();
    };
}

#endif //MAP_HPP
<|endoftext|>


<commit_before>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>

#include "common.h"
#include <dlog.h>
#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>

#include <bluetooth.h>

#undef LOG_TAG
#define LOG_TAG "REMOTE_KEY_FW"

static GMainLoop* gMainLoop = NULL;
static bt_adapter_visibility_mode_e gVisibilityMode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
static int gSocketFd = -1;
static bt_adapter_state_e gBtState = BT_ADAPTER_DISABLED;
static const char uuid[] = "00001101-0000-1000-8000-00805F9B34FB";

// Lifecycle of this framework
int rkf_initialize_bluetooth(void);
int rkf_finalize_bluetooth_socket(void);
int rkf_finalize_bluetooth(void);
int rkf_listen_connection(void);
int rkf_send_data(const char *, int);
void rkf_main_loop(void);

// Callbacks
void rkf_received_data_cb(bt_socket_received_data_s *, void *);
void rkf_socket_connection_state_changed_cb(int, bt_socket_connection_state_e, bt_socket_connection_s *, void *);
void rkf_state_changed_cb(int, bt_adapter_state_e, void *);
gboolean timeout_func_cb(gpointer);

int rkf_initialize_bluetooth(const char *device_name) {
	// Initialize bluetooth and get adapter state
	int ret;
	ret = bt_initialize();
	if(ret != BT_ERROR_NONE) {
		ALOGD("Unknown exception is occured in bt_initialize(): %x", ret);
		return -1;
	}

	ret = bt_adapter_get_state(&gBtState);
	if(ret != BT_ERROR_NONE) {
		ALOGD("Unknown exception is occured in bt_adapter_get_state(): %x", ret);
		return -2;
	}

	// Enable bluetooth device manually
	if(gBtState == BT_ADAPTER_DISABLED)
	{
		if(bt_adapter_set_state_changed_cb(rkf_state_changed_cb, NULL) != BT_ERROR_NONE)
		{
			ALOGE("[%s] bt_adapter_set_state_changed_cb() failed.", __FUNCTION__);
			return -3;
		}

		if(bt_adapter_enable() == BT_ERROR_NONE)
		{
			int timeout_id = -1;
			ALOGE("[%s] bt_adapter_state_changed_cb will be called.", __FUNCTION__);
			timeout_id = g_timeout_add(60000, timeout_func_cb, gMainLoop);
			g_main_loop_run(gMainLoop);
			g_source_remove(timeout_id);
		}
		else
		{
			ALOGE("[%s] bt_adapter_enable() failed.", __FUNCTION__);
			return -4;
		}
	}
	else
	{
		ALOGI("[%s] BT was already enabled.", __FUNCTION__);
	}

	// Set adapter's name
	if(gBtState == BT_ADAPTER_ENABLED) {
		char *name = NULL;
		ret = bt_adapter_get_name(&name);
		if(name == NULL) {
			ALOGD("NULL name exception is occured in bt_adapter_get_name(): %x", ret);
			return -5;
		}

		if(strncmp(name, device_name, strlen(name)) != 0) {
			if(bt_adapter_set_name(device_name) != BT_ERROR_NONE)
			{
				if (NULL != name)
					free(name);
				ALOGD("Unknown exception is occured in bt_adapter_set_name : %x", ret);
				return -6;
			}
		}
		free(name);
	} else {
		ALOGD("Bluetooth is not enabled");
		return -7;
	}

	//  Set visibility as BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE
	if(bt_adapter_get_visibility(&gVisibilityMode, NULL) != BT_ERROR_NONE)
	{
		LOGE("[%s] bt_adapter_get_visibility() failed.", __FUNCTION__);
		return -11;
	}

	if(gVisibilityMode != BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE)
	{
		if(bt_adapter_set_visibility(BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE, 0) != BT_ERROR_NONE)
		{
			LOGE("[%s] bt_adapter_set_visibility() failed.", __FUNCTION__);
			return -12;
		}
		gVisibilityMode = BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE;
	}
	else
	{
		LOGI("[%s] Visibility mode was already set as BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE.", __FUNCTION__);
	}

	// Connecting socket as a server
	ret = bt_socket_create_rfcomm(uuid, &gSocketFd);
	if(ret != BT_ERROR_NONE) {
		ALOGD("Unknown exception is occured in bt_socket_create_rfcomm(): %x", ret);
		return -8;
	}

	ret = bt_socket_set_connection_state_changed_cb(rkf_socket_connection_state_changed_cb, NULL);
	if(ret != BT_ERROR_NONE) {
		ALOGD("Unknown exception is occured in bt_socket_set_connection_state_changed_cb(): %x", ret);
		return -9;
	}

	ret = bt_socket_set_data_received_cb(rkf_received_data_cb, NULL);
	if(ret != BT_ERROR_NONE) {
		ALOGD("Unknown exception is occured in bt_socket_set_data_received_cb(): %x", ret);
		return -10;
	}

	return 0;
}

int rkf_finalize_bluetooth_socket(void) {
	int ret;
	sleep(5); // Wait for completing delivery
	ret = bt_socket_destroy_rfcomm(gSocketFd);
	if(ret != BT_ERROR_NONE)
	{
		ALOGD("Unknown exception is occured in bt_socket_destory_rfcomm(): %x", ret);
		return -1;
	}

	bt_deinitialize();
	return 0;
}

int rkf_finalize_bluetooth(void) {
	bt_deinitialize();
	return 0;
}

int dbus_listen_connection(void) {

	DBusConnection *connection;
	DBusError error;

	dbus_error_init(&error);

	connection = dbus_bus_get(DBUS_BUS_SESSION, &error);

	if (dbus_error_is_set(&error)) {
		ALOGD("Error connecting to the daemon bus: %s",error.message);
		dbus_error_free(&error);
		return -1;
	}

	dbus_bus_add_match (connection, "type='signal',interface='org.share.linux'",NULL);
	dbus_connection_add_filter (connection, dbus_filter, gMainLoop, NULL);

	/* dbus-glib call */
	dbus_connection_setup_with_g_main(connection,NULL);

	return 0;
}

int rkf_listen_connection(void) {
	// Success to get a socket
	int ret = bt_socket_listen_and_accept_rfcomm(gSocketFd, 5);
	switch(ret) {
		case BT_ERROR_NONE:
			{
				// Success to listen and accept a connection from client
				ALOGD("listen successful");
				return 0;
			}
			break;
		case BT_ERROR_INVALID_PARAMETER:
			{
				// Invalid parameter exception
				ALOGD("Invalid parameter exception is occured in bt_socket_listen_and_accept_rfcomm()");
				return -1;
			}
			break;
		default:
			{
				// Unknown exception
				ALOGD("Unknown exception is occured in bt_socket_listen_and_accept_rfcomm(): %x", ret);
				return -2;
			}
	}
}

int rkf_send_data(const char *data, int length) {
	int ret = bt_socket_send_data(gSocketFd, data, length);
	if(ret != BT_ERROR_NONE) {
		ALOGD("RemoteKeyFW: unknown error is occured in rkf_serror_end_data()");
		return -1;
	} else {
		return 0;
	}
}

void rkf_main_loop(void) {
	g_main_loop_run(gMainLoop);
}

int gReceiveCount = 0;

// bt_socket_data_received_cb
void rkf_received_data_cb(bt_socket_received_data_s *data, void *user_data) {
	static char buffer[1024];
	char menu_string[]="menu";
	char home_string[]="home";
	char back_string[]="back";

	strncpy(buffer, data->data, 1024);
	buffer[data->data_size] = '\0';
	ALOGD("RemoteKeyFW: received a data!(%d) %s", ++gReceiveCount, buffer);

	// ACTION!
	if(strncmp(buffer, menu_string, strlen(home_string)) == 0) {
		system("/bin/echo 1 > /sys/bus/platform/devices/homekey/coordinates");
	} else if(strncmp(buffer, home_string, strlen(home_string)) == 0) {
		system("/bin/echo 11 > /sys/bus/platform/devices/homekey/coordinates");
	} else if(strncmp(buffer, back_string, strlen(home_string)) == 0) {
		system("/bin/echo 111 > /sys/bus/platform/devices/homekey/coordinates");
	}

	// Sending ack is optional
	//char ack_string[]="ack rkf ";
	//ack_string[strlen(ack_string)-1] = '0' + (gReceiveCount % 10);
	//rkf_send_data(ack_string, strlen(ack_string)+1);
}

// bt_socket_connection_state_changed_cb
void rkf_socket_connection_state_changed_cb(int result, bt_socket_connection_state_e connection_state_event, bt_socket_connection_s *connection, void *user_data) {
	if(result == BT_ERROR_NONE) {
		ALOGD("RemoteKeyFW: connection state changed (BT_ERROR_NONE)");
	} else {
		ALOGD("RemoteKeyFW: connection state changed (not BT_ERROR_NONE)");
	}

	if(connection_state_event == BT_SOCKET_CONNECTED) {
		ALOGD("RemoteKeyFW: connected");
//		if(connection != NULL) {
//			ALOGD("RemoteKeyFW: connected (%d,%s)", connection->local_role, connection->remote_address);
//		}
	} else if(connection_state_event == BT_SOCKET_DISCONNECTED) {
		ALOGD("RemoteKeyFW: disconnected");
//		if(connection != NULL) {
//			ALOGD("RemoteKeyFW: disconnected (%d,%s)", connection->local_role, connection->remote_address);
//		}
		g_main_loop_quit(gMainLoop);
	}
}

void rkf_state_changed_cb(int result, bt_adapter_state_e adapter_state, void *user_data) {
	if(adapter_state == BT_ADAPTER_ENABLED) {
		if(result == BT_ERROR_NONE) {
			ALOGD("RemoteKeyFW: bluetooth was enabled successfully.");
			gBtState = BT_ADAPTER_ENABLED;
		} else {
			ALOGD("RemoteKeyFW: failed to enable BT.: %x", result);
			gBtState = BT_ADAPTER_DISABLED;
		}
	}
	if(gMainLoop) {
		ALOGD("It will terminate gMainLoop.", result);
		g_main_loop_quit(gMainLoop);
	}
}

gboolean timeout_func_cb(gpointer data)
{
	ALOGE("timeout_func_cb");
	if(gMainLoop)
	{
		g_main_loop_quit((GMainLoop*)data);
	}
	return FALSE;
}

int main(int argc, char *argv[])
{
	int error, ret = 0;
	const char default_device_name[] = "Tizen-RK";
	const char *device_name = NULL;
	gMainLoop = g_main_loop_new(NULL, FALSE);
	ALOGD("Sever started\n");

	if(argc < 2) {
		char errMsg[] = "No bluetooth device name, so its name is set as default.";
		printf("%s\n", errMsg);
		ALOGW("%s\n", errMsg);
		device_name = default_device_name;
	} else {
		device_name = argv[1];
	}

	// Initialize bluetooth
	error = rkf_initialize_bluetooth(device_name);
	if(error != 0) {
		ret = -2;
		goto error_end_without_socket;
	}
	ALOGD("succeed in rkf_initialize_bluetooth()\n");

	// Listen connection
	error = rkf_listen_connection();
	if(error != 0) {
		ret = -3;
		goto error_end_with_socket;
	}

	// Listen connection (dbus)
	error = dbus_listen_connection();

	// If succeed to accept a connection, start a main loop.
	rkf_main_loop();

	ALOGI("Server is terminated successfully\n");

error_end_with_socket:
	// Finalized bluetooth
	rkf_finalize_bluetooth_socket();

error_end_without_socket:
	rkf_finalize_bluetooth();
	return ret;
}

//! End of a file
<commit_msg>Add dbus<commit_after>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>

#include "common.h"
#include <dlog.h>
#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>

#include <bluetooth.h>

#undef LOG_TAG
#define LOG_TAG "REMOTE_KEY_FW"

static GMainLoop* gMainLoop = NULL;
static bt_adapter_visibility_mode_e gVisibilityMode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
static int gSocketFd = -1;
static bt_adapter_state_e gBtState = BT_ADAPTER_DISABLED;
static const char uuid[] = "00001101-0000-1000-8000-00805F9B34FB";

// Lifecycle of this framework
int rkf_initialize_bluetooth(void);
int rkf_finalize_bluetooth_socket(void);
int rkf_finalize_bluetooth(void);
int rkf_listen_connection(void);
int rkf_send_data(const char *, int);
void rkf_main_loop(void);

// Callbacks
void rkf_received_data_cb(bt_socket_received_data_s *, void *);
void rkf_socket_connection_state_changed_cb(int, bt_socket_connection_state_e, bt_socket_connection_s *, void *);
void rkf_state_changed_cb(int, bt_adapter_state_e, void *);
gboolean timeout_func_cb(gpointer);

int rkf_initialize_bluetooth(const char *device_name) {
	// Initialize bluetooth and get adapter state
	int ret;
	ret = bt_initialize();
	if(ret != BT_ERROR_NONE) {
		ALOGD("Unknown exception is occured in bt_initialize(): %x", ret);
		return -1;
	}

	ret = bt_adapter_get_state(&gBtState);
	if(ret != BT_ERROR_NONE) {
		ALOGD("Unknown exception is occured in bt_adapter_get_state(): %x", ret);
		return -2;
	}

	// Enable bluetooth device manually
	if(gBtState == BT_ADAPTER_DISABLED)
	{
		if(bt_adapter_set_state_changed_cb(rkf_state_changed_cb, NULL) != BT_ERROR_NONE)
		{
			ALOGE("[%s] bt_adapter_set_state_changed_cb() failed.", __FUNCTION__);
			return -3;
		}

		if(bt_adapter_enable() == BT_ERROR_NONE)
		{
			int timeout_id = -1;
			ALOGE("[%s] bt_adapter_state_changed_cb will be called.", __FUNCTION__);
			timeout_id = g_timeout_add(60000, timeout_func_cb, gMainLoop);
			g_main_loop_run(gMainLoop);
			g_source_remove(timeout_id);
		}
		else
		{
			ALOGE("[%s] bt_adapter_enable() failed.", __FUNCTION__);
			return -4;
		}
	}
	else
	{
		ALOGI("[%s] BT was already enabled.", __FUNCTION__);
	}

	// Set adapter's name
	if(gBtState == BT_ADAPTER_ENABLED) {
		char *name = NULL;
		ret = bt_adapter_get_name(&name);
		if(name == NULL) {
			ALOGD("NULL name exception is occured in bt_adapter_get_name(): %x", ret);
			return -5;
		}

		if(strncmp(name, device_name, strlen(name)) != 0) {
			if(bt_adapter_set_name(device_name) != BT_ERROR_NONE)
			{
				if (NULL != name)
					free(name);
				ALOGD("Unknown exception is occured in bt_adapter_set_name : %x", ret);
				return -6;
			}
		}
		free(name);
	} else {
		ALOGD("Bluetooth is not enabled");
		return -7;
	}

	//  Set visibility as BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE
	if(bt_adapter_get_visibility(&gVisibilityMode, NULL) != BT_ERROR_NONE)
	{
		LOGE("[%s] bt_adapter_get_visibility() failed.", __FUNCTION__);
		return -11;
	}

	if(gVisibilityMode != BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE)
	{
		if(bt_adapter_set_visibility(BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE, 0) != BT_ERROR_NONE)
		{
			LOGE("[%s] bt_adapter_set_visibility() failed.", __FUNCTION__);
			return -12;
		}
		gVisibilityMode = BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE;
	}
	else
	{
		LOGI("[%s] Visibility mode was already set as BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE.", __FUNCTION__);
	}

	// Connecting socket as a server
	ret = bt_socket_create_rfcomm(uuid, &gSocketFd);
	if(ret != BT_ERROR_NONE) {
		ALOGD("Unknown exception is occured in bt_socket_create_rfcomm(): %x", ret);
		return -8;
	}

	ret = bt_socket_set_connection_state_changed_cb(rkf_socket_connection_state_changed_cb, NULL);
	if(ret != BT_ERROR_NONE) {
		ALOGD("Unknown exception is occured in bt_socket_set_connection_state_changed_cb(): %x", ret);
		return -9;
	}

	ret = bt_socket_set_data_received_cb(rkf_received_data_cb, NULL);
	if(ret != BT_ERROR_NONE) {
		ALOGD("Unknown exception is occured in bt_socket_set_data_received_cb(): %x", ret);
		return -10;
	}

	return 0;
}

int rkf_finalize_bluetooth_socket(void) {
	int ret;
	sleep(5); // Wait for completing delivery
	ret = bt_socket_destroy_rfcomm(gSocketFd);
	if(ret != BT_ERROR_NONE)
	{
		ALOGD("Unknown exception is occured in bt_socket_destory_rfcomm(): %x", ret);
		return -1;
	}

	bt_deinitialize();
	return 0;
}

int rkf_finalize_bluetooth(void) {
	bt_deinitialize();
	return 0;
}

static DBusHandlerResult dbus_filter (DBusConnection *connection, DBusMessage *message, void *user_data) {

	if (dbus_message_is_signal(message,"org.share.linux","Customize")) {
		ALOGD("Message cutomize received\n");
		return DBUS_HANDLER_RESULT_HANDLED;
	}
	if (dbus_message_is_signal(message,"org.share.linux","Quit")) {
		ALOGD("Message quit received\n");
		return DBUS_HANDLER_RESULT_HANDLED;
	}
	ALOGD("DBUS_HANDLER_RESULT_NOT_YET_HANDLED\n");
	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

int dbus_listen_connection(void) {

	DBusConnection *connection;
	DBusError error;

	dbus_error_init(&error);

	connection = dbus_bus_get(DBUS_BUS_SESSION, &error);

	if (dbus_error_is_set(&error)) {
		ALOGD("Error connecting to the daemon bus: %s",error.message);
		dbus_error_free(&error);
		return -1;
	}

	dbus_bus_add_match (connection, "type='signal',interface='org.share.linux'",NULL);
	dbus_connection_add_filter (connection, dbus_filter, gMainLoop, NULL);

	/* dbus-glib call */
	dbus_connection_setup_with_g_main(connection,NULL);

	return 0;
}

int rkf_listen_connection(void) {
	// Success to get a socket
	int ret = bt_socket_listen_and_accept_rfcomm(gSocketFd, 5);
	switch(ret) {
		case BT_ERROR_NONE:
			{
				// Success to listen and accept a connection from client
				ALOGD("listen successful");
				return 0;
			}
			break;
		case BT_ERROR_INVALID_PARAMETER:
			{
				// Invalid parameter exception
				ALOGD("Invalid parameter exception is occured in bt_socket_listen_and_accept_rfcomm()");
				return -1;
			}
			break;
		default:
			{
				// Unknown exception
				ALOGD("Unknown exception is occured in bt_socket_listen_and_accept_rfcomm(): %x", ret);
				return -2;
			}
	}
}

int rkf_send_data(const char *data, int length) {
	int ret = bt_socket_send_data(gSocketFd, data, length);
	if(ret != BT_ERROR_NONE) {
		ALOGD("RemoteKeyFW: unknown error is occured in rkf_serror_end_data()");
		return -1;
	} else {
		return 0;
	}
}

void rkf_main_loop(void) {
	g_main_loop_run(gMainLoop);
}

int gReceiveCount = 0;

// bt_socket_data_received_cb
void rkf_received_data_cb(bt_socket_received_data_s *data, void *user_data) {
	static char buffer[1024];
	char menu_string[]="menu";
	char home_string[]="home";
	char back_string[]="back";

	strncpy(buffer, data->data, 1024);
	buffer[data->data_size] = '\0';
	ALOGD("RemoteKeyFW: received a data!(%d) %s", ++gReceiveCount, buffer);

	// ACTION!
	if(strncmp(buffer, menu_string, strlen(home_string)) == 0) {
		system("/bin/echo 1 > /sys/bus/platform/devices/homekey/coordinates");
	} else if(strncmp(buffer, home_string, strlen(home_string)) == 0) {
		system("/bin/echo 11 > /sys/bus/platform/devices/homekey/coordinates");
	} else if(strncmp(buffer, back_string, strlen(home_string)) == 0) {
		system("/bin/echo 111 > /sys/bus/platform/devices/homekey/coordinates");
	}

	// Sending ack is optional
	//char ack_string[]="ack rkf ";
	//ack_string[strlen(ack_string)-1] = '0' + (gReceiveCount % 10);
	//rkf_send_data(ack_string, strlen(ack_string)+1);
}

// bt_socket_connection_state_changed_cb
void rkf_socket_connection_state_changed_cb(int result, bt_socket_connection_state_e connection_state_event, bt_socket_connection_s *connection, void *user_data) {
	if(result == BT_ERROR_NONE) {
		ALOGD("RemoteKeyFW: connection state changed (BT_ERROR_NONE)");
	} else {
		ALOGD("RemoteKeyFW: connection state changed (not BT_ERROR_NONE)");
	}

	if(connection_state_event == BT_SOCKET_CONNECTED) {
		ALOGD("RemoteKeyFW: connected");
//		if(connection != NULL) {
//			ALOGD("RemoteKeyFW: connected (%d,%s)", connection->local_role, connection->remote_address);
//		}
	} else if(connection_state_event == BT_SOCKET_DISCONNECTED) {
		ALOGD("RemoteKeyFW: disconnected");
//		if(connection != NULL) {
//			ALOGD("RemoteKeyFW: disconnected (%d,%s)", connection->local_role, connection->remote_address);
//		}
		g_main_loop_quit(gMainLoop);
	}
}

void rkf_state_changed_cb(int result, bt_adapter_state_e adapter_state, void *user_data) {
	if(adapter_state == BT_ADAPTER_ENABLED) {
		if(result == BT_ERROR_NONE) {
			ALOGD("RemoteKeyFW: bluetooth was enabled successfully.");
			gBtState = BT_ADAPTER_ENABLED;
		} else {
			ALOGD("RemoteKeyFW: failed to enable BT.: %x", result);
			gBtState = BT_ADAPTER_DISABLED;
		}
	}
	if(gMainLoop) {
		ALOGD("It will terminate gMainLoop.", result);
		g_main_loop_quit(gMainLoop);
	}
}

gboolean timeout_func_cb(gpointer data)
{
	ALOGE("timeout_func_cb");
	if(gMainLoop)
	{
		g_main_loop_quit((GMainLoop*)data);
	}
	return FALSE;
}

int main(int argc, char *argv[])
{
	int error, ret = 0;
	const char default_device_name[] = "Tizen-RK";
	const char *device_name = NULL;
	gMainLoop = g_main_loop_new(NULL, FALSE);
	ALOGD("Sever started\n");

	if(argc < 2) {
		char errMsg[] = "No bluetooth device name, so its name is set as default.";
		printf("%s\n", errMsg);
		ALOGW("%s\n", errMsg);
		device_name = default_device_name;
	} else {
		device_name = argv[1];
	}

	// Initialize bluetooth
	error = rkf_initialize_bluetooth(device_name);
	if(error != 0) {
		ret = -2;
		goto error_end_without_socket;
	}
	ALOGD("succeed in rkf_initialize_bluetooth()\n");

	// Listen connection
	error = rkf_listen_connection();
	if(error != 0) {
		ret = -3;
		goto error_end_with_socket;
	}

	// Listen connection (dbus)
	error = dbus_listen_connection();

	// If succeed to accept a connection, start a main loop.
	rkf_main_loop();

	ALOGI("Server is terminated successfully\n");

error_end_with_socket:
	// Finalized bluetooth
	rkf_finalize_bluetooth_socket();

error_end_without_socket:
	rkf_finalize_bluetooth();
	return ret;
}

//! End of a file
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

#ifndef __MESOS_HOOK_HPP__
#define __MESOS_HOOK_HPP__

#include <map>
#include <string>

#include <mesos/attributes.hpp>
#include <mesos/mesos.hpp>
#include <mesos/resources.hpp>

#include <process/future.hpp>

#include <stout/none.hpp>
#include <stout/nothing.hpp>
#include <stout/result.hpp>
#include <stout/try.hpp>

namespace mesos {

class Hook
{
public:
  virtual ~Hook() {}

  // This label decorator hook is called from within master during
  // the launchTask routine. A module implementing the hook creates
  // and returns a set of labels. These labels overwrite the existing
  // labels on the task info.
  virtual Result<Labels> masterLaunchTaskLabelDecorator(
      const TaskInfo& taskInfo,
      const FrameworkInfo& frameworkInfo,
      const SlaveInfo& slaveInfo)
  {
    return None();
  }

  // This label decorator hook is called from within the slave when
  // receiving a run task request from the master. A module
  // implementing the hook creates and returns a set of labels. These
  // labels overwrite the existing labels on the task info.
  virtual Result<Labels> slaveRunTaskLabelDecorator(
      const TaskInfo& taskInfo,
      const ExecutorInfo& executorInfo,
      const FrameworkInfo& frameworkInfo,
      const SlaveInfo& slaveInfo)
  {
    return None();
  }

  // This hook is called when an Agent is removed i.e. deemed lost by the
  // master. The hook is invoked after all frameworks have been informed about
  // the loss.
  virtual Try<Nothing> masterSlaveLostHook(const SlaveInfo& slaveInfo)
  {
    return Nothing();
  }

  // This environment decorator hook is called from within slave when
  // launching a new executor. A module implementing the hook creates
  // and returns a set of environment variables. These environment
  // variables then become part of the executor's environment.
  // Ideally, a hook module will also look at the exiting environment
  // variables in executorInfo and extend the values as needed in case
  // of a conflict.
  virtual Result<Environment> slaveExecutorEnvironmentDecorator(
      const ExecutorInfo& executorInfo)
  {
    return None();
  }

  // This environment decorator is called from within the slave after
  // receiving a run task request from the master but before the docker
  // containerizer launches the task. A module implementing the hook can
  // inspect the arguments and return a `Failure` if the task should be
  // rejected with a `TASK_FAILED`.
  // The hook can return a set of environment variables. For command tasks
  // the environment variables will become part of the task's environment.
  // For custom executors, the environment variables will be part of the
  // custom executor's environment.
  //
  // NOTE: The order of hooks matters for environment variables.
  // If there is a conflict, the hook loaded last will take priority.
  //
  // NOTE: Unlike `slaveExecutorEnvironmentDecorator`, environment variables
  // returned from this hook *will* overwrite environment variables inside
  // the `ExecutorInfo`.
  //
  // NOTE: This hook is designed to be an asynchronous replacement for
  // `slavePreLaunchDockerHook`. This hook is called first.
  virtual process::Future<Option<Environment>>
    slavePreLaunchDockerEnvironmentDecorator(
        const Option<TaskInfo>& taskInfo,
        const ExecutorInfo& executorInfo,
        const std::string& name,
        const std::string& sandboxDirectory,
        const std::string& mappedDirectory,
        const Option<std::map<std::string, std::string>>& env)
  {
    return None();
  }

  // This hook is called from within slave before docker is launched.
  // A typical module implementing the hook will perform some settings
  // as required.
  //
  // NOTE: Superceded by `slavePreLaunchDockerEnvironmentDecorator`.
  virtual Try<Nothing> slavePreLaunchDockerHook(
      const ContainerInfo& containerInfo,
      const CommandInfo& commandInfo,
      const Option<TaskInfo>& taskInfo,
      const ExecutorInfo& executorInfo,
      const std::string& name,
      const std::string& sandboxDirectory,
      const std::string& mappedDirectory,
      const Option<Resources>& resources,
      const Option<std::map<std::string, std::string>>& env)
  {
    return Nothing();
  }

  // This hook is called from within slave after URIs and container
  // image are fetched. A typical module implementing this hook will
  // perform some operations on the fetched artifacts.
  virtual Try<Nothing> slavePostFetchHook(
      const ContainerID& containerId,
      const std::string& directory)
  {
    return Nothing();
  }

  // This hook is called from within slave when an executor is being
  // removed. A typical module implementing the hook will perform some
  // cleanup as required.
  virtual Try<Nothing> slaveRemoveExecutorHook(
      const FrameworkInfo& frameworkInfo,
      const ExecutorInfo& executorInfo)
  {
    return Nothing();
  }

  // This hook is called from within slave when it receives a status update from
  // the executor. A module implementing the hook creates and returns a
  // TaskStatus with a set of labels and container_status. These labels and
  // container status overwrite the existing labels on the TaskStatus. Remaining
  // fields from the returned TaskStatus are discarded.
  virtual Result<TaskStatus> slaveTaskStatusDecorator(
      const FrameworkID& frameworkId,
      const TaskStatus& status)
  {
    return None();
  }

  // This hook is called from within the slave when it initializes. A module
  // implementing the hook creates and returns a Resources object with the new
  // list of resources available on the slave before they are advertised to the
  // master. These new resources overwrite the previous ones in SlaveInfo.
  virtual Result<Resources> slaveResourcesDecorator(
      const SlaveInfo& slaveInfo)
  {
    return None();
  }

  // This hook is called from within the slave when it initializes. A module
  // implementing the hook creates and returns an Attributes object with the
  // new list of attributes for the slave before they are advertised to the
  // master. These new attributes overwrite the previous ones in SlaveInfo.
  virtual Result<Attributes> slaveAttributesDecorator(
      const SlaveInfo& slaveInfo)
  {
    return None();
  }
};

} // namespace mesos {

#endif // __MESOS_HOOK_HPP__
<commit_msg>Fixed typo in a comment in hooks.hpp.<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

#ifndef __MESOS_HOOK_HPP__
#define __MESOS_HOOK_HPP__

#include <map>
#include <string>

#include <mesos/attributes.hpp>
#include <mesos/mesos.hpp>
#include <mesos/resources.hpp>

#include <process/future.hpp>

#include <stout/none.hpp>
#include <stout/nothing.hpp>
#include <stout/result.hpp>
#include <stout/try.hpp>

namespace mesos {

class Hook
{
public:
  virtual ~Hook() {}

  // This label decorator hook is called from within master during
  // the launchTask routine. A module implementing the hook creates
  // and returns a set of labels. These labels overwrite the existing
  // labels on the task info.
  virtual Result<Labels> masterLaunchTaskLabelDecorator(
      const TaskInfo& taskInfo,
      const FrameworkInfo& frameworkInfo,
      const SlaveInfo& slaveInfo)
  {
    return None();
  }

  // This label decorator hook is called from within the slave when
  // receiving a run task request from the master. A module
  // implementing the hook creates and returns a set of labels. These
  // labels overwrite the existing labels on the task info.
  virtual Result<Labels> slaveRunTaskLabelDecorator(
      const TaskInfo& taskInfo,
      const ExecutorInfo& executorInfo,
      const FrameworkInfo& frameworkInfo,
      const SlaveInfo& slaveInfo)
  {
    return None();
  }

  // This hook is called when an Agent is removed i.e. deemed lost by the
  // master. The hook is invoked after all frameworks have been informed about
  // the loss.
  virtual Try<Nothing> masterSlaveLostHook(const SlaveInfo& slaveInfo)
  {
    return Nothing();
  }

  // This environment decorator hook is called from within slave when
  // launching a new executor. A module implementing the hook creates
  // and returns a set of environment variables. These environment
  // variables then become part of the executor's environment.
  // Ideally, a hook module will also look at the existing environment
  // variables in executorInfo and extend the values as needed in case
  // of a conflict.
  virtual Result<Environment> slaveExecutorEnvironmentDecorator(
      const ExecutorInfo& executorInfo)
  {
    return None();
  }

  // This environment decorator is called from within the slave after
  // receiving a run task request from the master but before the docker
  // containerizer launches the task. A module implementing the hook can
  // inspect the arguments and return a `Failure` if the task should be
  // rejected with a `TASK_FAILED`.
  // The hook can return a set of environment variables. For command tasks
  // the environment variables will become part of the task's environment.
  // For custom executors, the environment variables will be part of the
  // custom executor's environment.
  //
  // NOTE: The order of hooks matters for environment variables.
  // If there is a conflict, the hook loaded last will take priority.
  //
  // NOTE: Unlike `slaveExecutorEnvironmentDecorator`, environment variables
  // returned from this hook *will* overwrite environment variables inside
  // the `ExecutorInfo`.
  //
  // NOTE: This hook is designed to be an asynchronous replacement for
  // `slavePreLaunchDockerHook`. This hook is called first.
  virtual process::Future<Option<Environment>>
    slavePreLaunchDockerEnvironmentDecorator(
        const Option<TaskInfo>& taskInfo,
        const ExecutorInfo& executorInfo,
        const std::string& name,
        const std::string& sandboxDirectory,
        const std::string& mappedDirectory,
        const Option<std::map<std::string, std::string>>& env)
  {
    return None();
  }

  // This hook is called from within slave before docker is launched.
  // A typical module implementing the hook will perform some settings
  // as required.
  //
  // NOTE: Superceded by `slavePreLaunchDockerEnvironmentDecorator`.
  virtual Try<Nothing> slavePreLaunchDockerHook(
      const ContainerInfo& containerInfo,
      const CommandInfo& commandInfo,
      const Option<TaskInfo>& taskInfo,
      const ExecutorInfo& executorInfo,
      const std::string& name,
      const std::string& sandboxDirectory,
      const std::string& mappedDirectory,
      const Option<Resources>& resources,
      const Option<std::map<std::string, std::string>>& env)
  {
    return Nothing();
  }

  // This hook is called from within slave after URIs and container
  // image are fetched. A typical module implementing this hook will
  // perform some operations on the fetched artifacts.
  virtual Try<Nothing> slavePostFetchHook(
      const ContainerID& containerId,
      const std::string& directory)
  {
    return Nothing();
  }

  // This hook is called from within slave when an executor is being
  // removed. A typical module implementing the hook will perform some
  // cleanup as required.
  virtual Try<Nothing> slaveRemoveExecutorHook(
      const FrameworkInfo& frameworkInfo,
      const ExecutorInfo& executorInfo)
  {
    return Nothing();
  }

  // This hook is called from within slave when it receives a status update from
  // the executor. A module implementing the hook creates and returns a
  // TaskStatus with a set of labels and container_status. These labels and
  // container status overwrite the existing labels on the TaskStatus. Remaining
  // fields from the returned TaskStatus are discarded.
  virtual Result<TaskStatus> slaveTaskStatusDecorator(
      const FrameworkID& frameworkId,
      const TaskStatus& status)
  {
    return None();
  }

  // This hook is called from within the slave when it initializes. A module
  // implementing the hook creates and returns a Resources object with the new
  // list of resources available on the slave before they are advertised to the
  // master. These new resources overwrite the previous ones in SlaveInfo.
  virtual Result<Resources> slaveResourcesDecorator(
      const SlaveInfo& slaveInfo)
  {
    return None();
  }

  // This hook is called from within the slave when it initializes. A module
  // implementing the hook creates and returns an Attributes object with the
  // new list of attributes for the slave before they are advertised to the
  // master. These new attributes overwrite the previous ones in SlaveInfo.
  virtual Result<Attributes> slaveAttributesDecorator(
      const SlaveInfo& slaveInfo)
  {
    return None();
  }
};

} // namespace mesos {

#endif // __MESOS_HOOK_HPP__
<|endoftext|>