Blame lang/cpp/src/eventloopinteractor.h

Packit d7e8d0
/*
Packit d7e8d0
  eventloopinteractor.h
Packit d7e8d0
  Copyright (C) 2003,2004 Klarälvdalens Datakonsult AB
Packit d7e8d0
  2016 Bundesamt für Sicherheit in der Informationstechnik
Packit d7e8d0
  Software engineering by Intevation GmbH
Packit d7e8d0
Packit d7e8d0
  This file is part of GPGME++.
Packit d7e8d0
Packit d7e8d0
  GPGME++ is free software; you can redistribute it and/or
Packit d7e8d0
  modify it under the terms of the GNU Library General Public
Packit d7e8d0
  License as published by the Free Software Foundation; either
Packit d7e8d0
  version 2 of the License, or (at your option) any later version.
Packit d7e8d0
Packit d7e8d0
  GPGME++ is distributed in the hope that it will be useful,
Packit d7e8d0
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit d7e8d0
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit d7e8d0
  GNU Library General Public License for more details.
Packit d7e8d0
Packit d7e8d0
  You should have received a copy of the GNU Library General Public License
Packit d7e8d0
  along with GPGME++; see the file COPYING.LIB.  If not, write to the
Packit d7e8d0
  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit d7e8d0
  Boston, MA 02110-1301, USA.
Packit d7e8d0
*/
Packit d7e8d0
Packit d7e8d0
// -*- c++ -*-
Packit d7e8d0
#ifndef __GPGMEPP_EVENTLOOPINTERACTOR_H__
Packit d7e8d0
#define __GPGMEPP_EVENTLOOPINTERACTOR_H__
Packit d7e8d0
Packit d7e8d0
#include "gpgmepp_export.h"
Packit d7e8d0
Packit d7e8d0
namespace GpgME
Packit d7e8d0
{
Packit d7e8d0
Packit d7e8d0
class Context;
Packit d7e8d0
class Error;
Packit d7e8d0
class TrustItem;
Packit d7e8d0
class Key;
Packit d7e8d0
Packit d7e8d0
/*! \file eventloopinteractor.h
Packit d7e8d0
    \brief Abstract base class for gpgme's external event loop support
Packit d7e8d0
Packit d7e8d0
    This class does most of the work involved with hooking GpgME++
Packit d7e8d0
    up with external event loops, such as the GTK or Qt ones.
Packit d7e8d0
Packit d7e8d0
    It actually provides two interfaces: An interface to the gpgme
Packit d7e8d0
    IO Callback handling and one for gpgme events. The IO Callback
Packit d7e8d0
    interface consists of the three methods \c actOn(), \c
Packit d7e8d0
    registerWatcher() and \c unregisterWatcher(). The event
Packit d7e8d0
    interface consists of the three methods \c nextTrustItemEvent(),
Packit d7e8d0
    \c nextKeyEvent() and \c operationDoneEvent().
Packit d7e8d0
Packit d7e8d0
    \sect General Usage
Packit d7e8d0
Packit d7e8d0
    \c EventLoopInteractor is designed to be used as a
Packit d7e8d0
    singleton. However, in order to make any use of it, you have to
Packit d7e8d0
    subclass it and reimplement it's pure virtual methods (see
Packit d7e8d0
    below). We suggest you keep the constructor protected and
Packit d7e8d0
    provide a static \c instance() method that returns the single
Packit d7e8d0
    instance. Alternatively, you can create an instance on the
Packit d7e8d0
    stack, e.g. in \c main().
Packit d7e8d0
Packit d7e8d0
    If you want \c EventLoopInteractor to manage a particular \c
Packit d7e8d0
    Context, just call \c manage() on the \c Context. OTOH, if you
Packit d7e8d0
    want to disable IO callbacks for a \c Context, use \c unmanage().
Packit d7e8d0
Packit d7e8d0
    \sect IO Callback Interface
Packit d7e8d0
Packit d7e8d0
    One part of this interface is represented by \c
Packit d7e8d0
    registerWatcher() and \c unregisterWatcher(), both of which are
Packit d7e8d0
    pure virtual. \c registerWatcher() should do anything necessary
Packit d7e8d0
    to hook up watching of file descriptor \c fd for reading (\c dir
Packit d7e8d0
    = \c Read) or writing (\c dir = Write) to the event loop you use
Packit d7e8d0
    and return a tag identifying that particular watching process
Packit d7e8d0
    uniquely. This could be the index into an array of objects you
Packit d7e8d0
    use for that purpose or the address of such an object. E.g. in
Packit d7e8d0
    Qt, you'd essentially just create a new \c QSocketNotifier:
Packit d7e8d0
Packit d7e8d0
    \verbatim
Packit d7e8d0
    void * registerWatcher( int fd, Direction dir ) {
Packit d7e8d0
      return new QSocketNotifier( fd, dir == Read ? QSocketNotifier::Read : QSocketNotifier::Write );
Packit d7e8d0
      // misses connecting to the activated() signal...
Packit d7e8d0
    }
Packit d7e8d0
    \endverbatim
Packit d7e8d0
Packit d7e8d0
    which uses the address of the created object as unique tag. The
Packit d7e8d0
    tag returned by \c registerWatcher is stored by \c
Packit d7e8d0
    EventLoopInteractor and passed as argument to \c
Packit d7e8d0
    unregisterWatcher(). So, in the picture above, you'd implement \c
Packit d7e8d0
    unregisterWatcher() like this:
Packit d7e8d0
Packit d7e8d0
    \verbatim
Packit d7e8d0
    void unregisterWatcher( void * tag ) {
Packit d7e8d0
      delete static_cast<QSocketNotifier*>( tag );
Packit d7e8d0
    }
Packit d7e8d0
    \endverbatim
Packit d7e8d0
Packit d7e8d0
    The other part of the IO callback interface is \c actOn(), which
Packit d7e8d0
    you should call if you receive notification from your event loop
Packit d7e8d0
    about activity on file descriptor \c fd in direction \c dir. In
Packit d7e8d0
    the picture above, you'd call this from the slot connected to
Packit d7e8d0
    the socket notifier's \c activated() signal.
Packit d7e8d0
Packit d7e8d0
    \note \c registerWatcher() as well as \c unregisterWatcher() may
Packit d7e8d0
    be called from within \c actOn(), so be careful with
Packit d7e8d0
    e.g. locking in threaded environments and keep in mind that the
Packit d7e8d0
    object you used to find the \c fd and \c dir fo the \c actOn()
Packit d7e8d0
    call might be deleted when \c actOn() returns!
Packit d7e8d0
Packit d7e8d0
    \sect Event Handler Interface
Packit d7e8d0
Packit d7e8d0
*/
Packit d7e8d0
class GPGMEPP_EXPORT EventLoopInteractor
Packit d7e8d0
{
Packit d7e8d0
protected:
Packit d7e8d0
    EventLoopInteractor();
Packit d7e8d0
public:
Packit d7e8d0
    virtual ~EventLoopInteractor();
Packit d7e8d0
Packit d7e8d0
    static EventLoopInteractor *instance()
Packit d7e8d0
    {
Packit d7e8d0
        return mSelf;
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
    void manage(Context *context);
Packit d7e8d0
    void unmanage(Context *context);
Packit d7e8d0
Packit d7e8d0
    enum Direction { Read, Write };
Packit d7e8d0
protected:
Packit d7e8d0
    //
Packit d7e8d0
    // IO Notification Interface
Packit d7e8d0
    //
Packit d7e8d0
Packit d7e8d0
    /** Call this if your event loop detected activity on file
Packit d7e8d0
        descriptor fd, with direction dir */
Packit d7e8d0
    void actOn(int fd, Direction dir);
Packit d7e8d0
Packit d7e8d0
    virtual void *registerWatcher(int fd, Direction dir, bool &ok) = 0;
Packit d7e8d0
    virtual void unregisterWatcher(void *tag) = 0;
Packit d7e8d0
Packit d7e8d0
    //
Packit d7e8d0
    // Event Handler Interface
Packit d7e8d0
    //
Packit d7e8d0
Packit d7e8d0
    virtual void operationStartEvent(Context *context) = 0;
Packit d7e8d0
    virtual void nextTrustItemEvent(Context *context, const TrustItem &item) = 0;
Packit d7e8d0
    virtual void nextKeyEvent(Context *context, const Key &key) = 0;
Packit d7e8d0
    virtual void operationDoneEvent(Context *context, const Error &e) = 0;
Packit d7e8d0
Packit d7e8d0
private:
Packit d7e8d0
    class Private;
Packit d7e8d0
    friend class Private;
Packit d7e8d0
    Private *const d;
Packit d7e8d0
    static EventLoopInteractor *mSelf;
Packit d7e8d0
};
Packit d7e8d0
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
#endif // __GPGMEPP_EVENTLOOPINTERACTOR_H__