deskflow/src/lib/base/EventQueue.h
Chris Rizzitello ed1217e9cc
Use Deskflow Name (#7519)
* Use Deskflow Name

* Remove business-oriented options from issue templates

* Remove business-oriented workflow

* Bump version to 3.0.0 (to avoid confusion with previously used version numbers 1.x & 2.x)

* Update readme to reflect new project name and goals

* Found some more "synergy" to rename

* Rename `synlib` to `app`

* Rename `syntool` to `deskflow-legacy`

* Rename `synwinhk` to `dfwhook`

* Rename dirs from synergy to deskflow

* Rename more "Synergy" files

* Rename app bundle ID

* Fixed copyright typo

* Rename only title in serial key dialog (to be moved downstream later)

* Preserve original serial key window for moving downstream

* Restore dialogs ready for moving downstream

* Rename `QDeskflowApplication` to `DeskflowApplication` (the Q is confusing)

* Restore Volker's original project name

* Fixed mimetype

* Fixed weird grammar

* Fixed (more) weird grammar

* Broken link, restoring (but we should move all links out of source)

* Broken link, restoring (but we should move all links out of source)

* Add write permission to valgrind-analysis.yml

* Restore AUR conflicts

* Apply Clang format

* Update ChangeLog

* Back out version change

---------

Co-authored-by: Nick Bolton <nick@symless.com>
2024-09-17 20:00:25 +01:00

200 lines
6.3 KiB
C++

/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package 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/>.
*/
#pragma once
#include "arch/IArchMultithread.h"
#include "base/Event.h"
#include "base/EventTypes.h"
#include "base/IEventQueue.h"
#include "base/PriorityQueue.h"
#include "base/Stopwatch.h"
#include "common/stdmap.h"
#include "common/stdset.h"
#include "mt/CondVar.h"
#include <queue>
class Mutex;
//! Event queue
/*!
An event queue that implements the platform independent parts and
delegates the platform dependent parts to a subclass.
*/
class EventQueue : public IEventQueue {
public:
EventQueue();
EventQueue(EventQueue const &) = delete;
EventQueue(EventQueue &&) = delete;
virtual ~EventQueue();
EventQueue &operator=(EventQueue const &) = delete;
EventQueue &operator=(EventQueue &&) = delete;
// IEventQueue overrides
virtual void loop();
virtual void adoptBuffer(IEventQueueBuffer *);
virtual bool getEvent(Event &event, double timeout = -1.0);
virtual bool dispatchEvent(const Event &event);
virtual void addEvent(const Event &event);
virtual EventQueueTimer *newTimer(double duration, void *target);
virtual EventQueueTimer *newOneShotTimer(double duration, void *target);
virtual void deleteTimer(EventQueueTimer *);
virtual void adoptHandler(Event::Type type, void *target, IEventJob *handler);
virtual void removeHandler(Event::Type type, void *target);
virtual void removeHandlers(void *target);
virtual Event::Type registerTypeOnce(Event::Type &type, const char *name);
virtual bool isEmpty() const;
virtual IEventJob *getHandler(Event::Type type, void *target) const;
virtual const char *getTypeName(Event::Type type);
virtual Event::Type getRegisteredType(const String &name) const;
void *getSystemTarget();
virtual void waitForReady() const;
private:
UInt32 saveEvent(const Event &event);
Event removeEvent(UInt32 eventID);
bool hasTimerExpired(Event &event);
double getNextTimerTimeout() const;
void addEventToBuffer(const Event &event);
private:
class Timer {
public:
Timer(
EventQueueTimer *, double timeout, double initialTime, void *target,
bool oneShot);
~Timer();
void reset();
Timer &operator-=(double);
operator double() const;
bool isOneShot() const;
EventQueueTimer *getTimer() const;
void *getTarget() const;
void fillEvent(TimerEvent &) const;
bool operator<(const Timer &) const;
private:
EventQueueTimer *m_timer;
double m_timeout;
void *m_target;
bool m_oneShot;
double m_time;
};
typedef std::set<EventQueueTimer *> Timers;
typedef PriorityQueue<Timer> TimerQueue;
typedef std::map<UInt32, Event> EventTable;
typedef std::vector<UInt32> EventIDList;
typedef std::map<Event::Type, const char *> TypeMap;
typedef std::map<String, Event::Type> NameMap;
typedef std::map<Event::Type, IEventJob *> TypeHandlerTable;
typedef std::map<void *, TypeHandlerTable> HandlerTable;
int m_systemTarget;
ArchMutex m_mutex;
// registered events
Event::Type m_nextType;
TypeMap m_typeMap;
NameMap m_nameMap;
// buffer of events
IEventQueueBuffer *m_buffer;
// saved events
EventTable m_events;
EventIDList m_oldEventIDs;
// timers
Stopwatch m_time;
Timers m_timers;
TimerQueue m_timerQueue;
TimerEvent m_timerEvent;
// event handlers
HandlerTable m_handlers;
public:
//
// Event type providers.
//
ClientEvents &forClient();
IStreamEvents &forIStream();
IpcClientEvents &forIpcClient();
IpcClientProxyEvents &forIpcClientProxy();
IpcServerEvents &forIpcServer();
IpcServerProxyEvents &forIpcServerProxy();
IDataSocketEvents &forIDataSocket();
IListenSocketEvents &forIListenSocket();
ISocketEvents &forISocket();
OSXScreenEvents &forOSXScreen();
ClientListenerEvents &forClientListener();
ClientProxyEvents &forClientProxy();
ClientProxyUnknownEvents &forClientProxyUnknown();
ServerEvents &forServer();
ServerAppEvents &forServerApp();
IKeyStateEvents &forIKeyState();
IPrimaryScreenEvents &forIPrimaryScreen();
IScreenEvents &forIScreen();
ClipboardEvents &forClipboard();
FileEvents &forFile();
EiEvents &forEi();
private:
ClientEvents *m_typesForClient;
IStreamEvents *m_typesForIStream;
IpcClientEvents *m_typesForIpcClient;
IpcClientProxyEvents *m_typesForIpcClientProxy;
IpcServerEvents *m_typesForIpcServer;
IpcServerProxyEvents *m_typesForIpcServerProxy;
IDataSocketEvents *m_typesForIDataSocket;
IListenSocketEvents *m_typesForIListenSocket;
ISocketEvents *m_typesForISocket;
OSXScreenEvents *m_typesForOSXScreen;
ClientListenerEvents *m_typesForClientListener;
ClientProxyEvents *m_typesForClientProxy;
ClientProxyUnknownEvents *m_typesForClientProxyUnknown;
ServerEvents *m_typesForServer;
ServerAppEvents *m_typesForServerApp;
IKeyStateEvents *m_typesForIKeyState;
IPrimaryScreenEvents *m_typesForIPrimaryScreen;
IScreenEvents *m_typesForIScreen;
ClipboardEvents *m_typesForClipboard;
FileEvents *m_typesForFile;
EiEvents *m_typesForEi;
Mutex *m_readyMutex;
CondVar<bool> *m_readyCondVar;
std::queue<Event> m_pending;
};
#define EVENT_TYPE_ACCESSOR(type_) \
type_##Events& \
EventQueue::for##type_() { \
if (m_typesFor##type_ == NULL) { \
m_typesFor##type_ = new type_##Events(); \
m_typesFor##type_->setEvents(dynamic_cast<IEventQueue *>(this)); \
} \
return *m_typesFor##type_; \
}