File: eventqueue.h

package info (click to toggle)
yapet 2.6-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,920 kB
  • sloc: cpp: 32,397; sh: 5,032; makefile: 880; ansic: 36; sed: 16
file content (226 lines) | stat: -rw-r--r-- 6,440 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
// -*- mode: c++ -*-
//
// This file is part of libyacurs.
// Copyright (C) 2013  Rafael Ostertag
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program 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
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see
// <http://www.gnu.org/licenses/>.
//
//
// $Id$

#ifndef EVENTQUEUE_H
#define EVENTQUEUE_H 1

#include <signal.h>
#include <list>
#include <map>
#include <queue>

#include "area.h"
#include "event.h"
#include "eventconnector.h"
#include "lockscreen.h"
#include "sigaction.h"

namespace YACURS {
/**
 * @ingroup Event
 *
 * The Event Queue dispatches Events submitted to the respective
 * connectors.
 *
 * It is started by calling EventQueue::run(). It will then wait for
 * keyboard input or Unix Signals and dispatch, aka. `emit`, the Event
 * to all Event Connectors for the given event.
 *
 * The Event Queue will terminate upon submission of @c EVT_QUIT.
 *
 * Libyacurs counts on the order events are connected, so that the
 * EVT_REFRESH/EVT_DOUPDATE event sequence will call the last
 * connected event handler last, thus ensuring the update will not
 * suddenly display a main window before an recently opened dialog,
 * for instance.
 *
 * EventQueue will also emit events for global conditions, such as
 * screen refresh request when pressing Ctrl-L.
 *
 * @section Unix Signals
 *
 * EventQueue will emit events on following Unix Signals
 *
 * - SIGWINCH (@c EVT_SIGWINCH)
 * - SIGALRM (@c EVT_SIGALRM)
 * - SIGUSR1 (@c EVT_SIGUSR1)
 * - SIGUSR2 (@c EVT_SIGUSR2)
 * - SIGINT (@c EVT_SIGINT)
 *
 * @section Terminal Resize
 *
 * If supported by the curses implementation, it consists of following
 * event sequence:
 *
 * - EVT_TERMRESETUP (handled in Curses)
 * - EVT_SIGWINCH (only classes derived from WindowBase should connect.)
 * - EVT_REFRESH
 * - EVT_DOUPDATE
 *
 * @section Complete Refresh
 *
 * A complete refresh is initiated by pressing Ctrl-L or KEY_REFRESH
 * on the keyboard. It consists of following event sequence:
 *
 * - EVT_FORCEREFRESH
 * - EVT_REFRESH
 * - EVT_DOUPDATE
 *
 */
class EventQueue {
   private:
    /// Used by blocksignal()/unblocksignal()
    static sigset_t block_sigmask;
    /// Used by blocksignal()/unblocksignal()
    static sigset_t tmp_old_sigmask;
    /// Used by setup_signal()/restore_signal()
    static sigset_t old_sigmask;

    static INTERNAL::Sigaction* sigwinch;
    static INTERNAL::Sigaction* sigalrm;
    static INTERNAL::Sigaction* sigusr1;
    static INTERNAL::Sigaction* sigusr2;
    static INTERNAL::Sigaction* sigint;
    static INTERNAL::Sigaction* sigterm;
    static INTERNAL::Sigaction* sigquit;
    static INTERNAL::Sigaction* sigtstp;
    static INTERNAL::Sigaction* sigcont;
    static INTERNAL::Sigaction* siginfo;

    static bool signal_blocked;
    static std::queue<Event*> evt_queue;

    /**
     * EventConnectors are not removed immediately, instead remove
     * requests are queue up for processing later.
     */
    static std::list<EventConnectorBase*> evtconn_rem_request;
    static std::map<EventType, std::list<EventConnectorBase*> > evtconn_map;

    /**
     * LockScreen used on timeout
     */
    static LockScreen* _lockscreen;

    /**
     * Timeout for keyboard input.
     *
     * If for _timeout seconds no key (event) is pressed
     * (received), the lock screen kicks in, if any.
     */
    static unsigned int _timeout;

    static void setup_signal();

    static void restore_signal();

#ifdef SA_SIGINFO
    static void signal_handler(int signo, siginfo_t* info, void* d);

#else
    static void signal_handler(int signo);

#endif  // SA_SIGINFO

    static void blocksignal();

    static void unblocksignal();

    static void proc_rem_request();

    static void timeout_handler(Event& e);

   public:
    /**
     * Connect an event connector.
     *
     * Connect a (member) function to an Event. Please note, that
     * only one function per object and Event can be connected. If
     * two or more member functions of the same object will be
     * connected to a single Event, each call to connect
     * overwrites previous connections.
     *
     * @note the last event connector registered will be called
     * first.
     *
     * @note any pending disconnect will be cancelled and the
     * connector unsuspended.
     *
     * @param ec event connector to register.
     */
    static void connect_event(const EventConnectorBase& ec);

    /**
     * Disconnect an event connector.
     *
     * Disconnect the specified event connector.
     *
     * @note disconnecting does not immediately remove the
     * connector. Instead it will be queued up for later
     * removal. Until it is finally removed, it will be suspended.
     * @note any pending removal will be cancelled by a
     * (re-)connect and the connector will be unsuspended.
     *
     * @param ec event connector to disconnect.
     */
    static void disconnect_event(const EventConnectorBase& ec);

    /// Suspend event
    static void suspend(const EventConnectorBase& ec);

    /// Suspend all events equal to a given event
    static void suspend_all(const EventType t);

    /// Suspend all events except the one given
    static void suspend_except(const EventConnectorBase& ec);

    /// Unsuspend event
    static void unsuspend(const EventConnectorBase& ec);

    /// Unsuspend all events equal to a given event
    static void unsuspend_all(const EventType t);

    /// Unsuspend all events except the one given
    static void unsuspend_except(const EventConnectorBase& ec);

    /// Add an event to the qeue
    static void submit(const EventType et);

    static void submit(const Event& ev);

    static void run();

    static void cleanup();

    static void lock_screen(LockScreen* ls);

    static LockScreen* lock_screen();

    static void timeout(unsigned int t);

    static unsigned int timeout();

    static void _dump_event_conn_map();
};
}  // namespace YACURS

#endif  // EVENTQUEUE_H