Line data Source code
1 : /*
2 : eventloopinteractor.h
3 : Copyright (C) 2003,2004 Klarälvdalens Datakonsult AB
4 :
5 : This file is part of GPGME++.
6 :
7 : GPGME++ is free software; you can redistribute it and/or
8 : modify it under the terms of the GNU Library General Public
9 : License as published by the Free Software Foundation; either
10 : version 2 of the License, or (at your option) any later version.
11 :
12 : GPGME++ is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU Library General Public License for more details.
16 :
17 : You should have received a copy of the GNU Library General Public License
18 : along with GPGME++; see the file COPYING.LIB. If not, write to the
19 : Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 : Boston, MA 02110-1301, USA.
21 : */
22 :
23 : // -*- c++ -*-
24 : #ifndef __GPGMEPP_EVENTLOOPINTERACTOR_H__
25 : #define __GPGMEPP_EVENTLOOPINTERACTOR_H__
26 :
27 : #include "gpgmepp_export.h"
28 :
29 : namespace GpgME
30 : {
31 :
32 : class Context;
33 : class Error;
34 : class TrustItem;
35 : class Key;
36 :
37 : /*! \file eventloopinteractor.h
38 : \brief Abstract base class for gpgme's external event loop support
39 :
40 : This class does most of the work involved with hooking GpgME++
41 : up with external event loops, such as the GTK or Qt ones.
42 :
43 : It actually provides two interfaces: An interface to the gpgme
44 : IO Callback handling and one for gpgme events. The IO Callback
45 : interface consists of the three methods \c actOn(), \c
46 : registerWatcher() and \c unregisterWatcher(). The event
47 : interface consists of the three methods \c nextTrustItemEvent(),
48 : \c nextKeyEvent() and \c operationDoneEvent().
49 :
50 : \sect General Usage
51 :
52 : \c EventLoopInteractor is designed to be used as a
53 : singleton. However, in order to make any use of it, you have to
54 : subclass it and reimplement it's pure virtual methods (see
55 : below). We suggest you keep the constructor protected and
56 : provide a static \c instance() method that returns the single
57 : instance. Alternatively, you can create an instance on the
58 : stack, e.g. in \c main().
59 :
60 : If you want \c EventLoopInteractor to manage a particular \c
61 : Context, just call \c manage() on the \c Context. OTOH, if you
62 : want to disable IO callbacks for a \c Context, use \c unmanage().
63 :
64 : \sect IO Callback Interface
65 :
66 : One part of this interface is represented by \c
67 : registerWatcher() and \c unregisterWatcher(), both of which are
68 : pure virtual. \c registerWatcher() should do anything necessary
69 : to hook up watching of file descriptor \c fd for reading (\c dir
70 : = \c Read) or writing (\c dir = Write) to the event loop you use
71 : and return a tag identifying that particular watching process
72 : uniquely. This could be the index into an array of objects you
73 : use for that purpose or the address of such an object. E.g. in
74 : Qt, you'd essentially just create a new \c QSocketNotifier:
75 :
76 : \verbatim
77 : void * registerWatcher( int fd, Direction dir ) {
78 : return new QSocketNotifier( fd, dir == Read ? QSocketNotifier::Read : QSocketNotifier::Write );
79 : // misses connecting to the activated() signal...
80 : }
81 : \endverbatim
82 :
83 : which uses the address of the created object as unique tag. The
84 : tag returned by \c registerWatcher is stored by \c
85 : EventLoopInteractor and passed as argument to \c
86 : unregisterWatcher(). So, in the picture above, you'd implement \c
87 : unregisterWatcher() like this:
88 :
89 : \verbatim
90 : void unregisterWatcher( void * tag ) {
91 : delete static_cast<QSocketNotifier*>( tag );
92 : }
93 : \endverbatim
94 :
95 : The other part of the IO callback interface is \c actOn(), which
96 : you should call if you receive notification from your event loop
97 : about activity on file descriptor \c fd in direction \c dir. In
98 : the picture above, you'd call this from the slot connected to
99 : the socket notifier's \c activated() signal.
100 :
101 : \note \c registerWatcher() as well as \c unregisterWatcher() may
102 : be called from within \c actOn(), so be careful with
103 : e.g. locking in threaded environments and keep in mind that the
104 : object you used to find the \c fd and \c dir fo the \c actOn()
105 : call might be deleted when \c actOn() returns!
106 :
107 : \sect Event Handler Interface
108 :
109 : */
110 : class GPGMEPP_EXPORT EventLoopInteractor
111 : {
112 : protected:
113 : EventLoopInteractor();
114 : public:
115 : virtual ~EventLoopInteractor();
116 :
117 0 : static EventLoopInteractor *instance()
118 : {
119 0 : return mSelf;
120 : }
121 :
122 : void manage(Context *context);
123 : void unmanage(Context *context);
124 :
125 : enum Direction { Read, Write };
126 : protected:
127 : //
128 : // IO Notification Interface
129 : //
130 :
131 : /** Call this if your event loop detected activity on file
132 : descriptor fd, with direction dir */
133 : void actOn(int fd, Direction dir);
134 :
135 : virtual void *registerWatcher(int fd, Direction dir, bool &ok) = 0;
136 : virtual void unregisterWatcher(void *tag) = 0;
137 :
138 : //
139 : // Event Handler Interface
140 : //
141 :
142 : virtual void operationStartEvent(Context *context) = 0;
143 : virtual void nextTrustItemEvent(Context *context, const TrustItem &item) = 0;
144 : virtual void nextKeyEvent(Context *context, const Key &key) = 0;
145 : virtual void operationDoneEvent(Context *context, const Error &e) = 0;
146 :
147 : private:
148 : class Private;
149 : friend class Private;
150 : Private *const d;
151 : static EventLoopInteractor *mSelf;
152 : };
153 :
154 : }
155 :
156 : #endif // __GPGMEPP_EVENTLOOPINTERACTOR_H__
|