deskflow/src/lib/base/EventQueue.h

129 lines
3.5 KiB
C
Raw Normal View History

2012-06-10 16:50:54 +00:00
/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
* SPDX-FileCopyrightText: (C) 2004 Chris Schoeneman
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
2012-06-10 16:50:54 +00:00
*/
#pragma once
2012-06-10 16:50:54 +00:00
Wayland support (port Red Hat `libei` and `libportal` impl) (#7449) * Add libei and libportal * Port libei and libportal code by Peter Hutterer and Olivier Fourdan * Add Peter Hutterer and Olivier Fourdan to important devs list * Improve error handling for libei and libportal builds * Checkout libportal tags/0.7.1 * Hack out the gi-docgen clone * Remove new submodules in favor of using ExternalProject_Add * Remove submodule dirs * Use ExternalProject_Add instead of submodules * Fixed namespace * Hack to work around type libportal causing type conflicts * Add log helper functions * Use original log functions * Switch to FetchContent, use libportal a1530a9 (unreleased) and use camelCase member names for consistency * Restore a few events (much more work required) * Add TODOs for supporting multiple lib versions * Revert "Switch to FetchContent, use libportal a1530a9 (unreleased) and use camelCase member names for consistency" This reverts commit 610cebb5b6a08282eee68f4424fcdbe9eaab4bf9. * Simplify cmake config by removing builds for libei and libportal (will do this in `install_deps.py` instead) * Remove submodules * Remove .gitmodules * Use meson to build subprojects * Update copyright with Peter Hutterer's guidance * Use meson for installing deps * Fixed typo in tag name * Remove submodules * Remove old submodules * Fixed libei name * Defaults for pugixml and gtest depending on whether source exists in subprojects * Ignore some subproject dirs * Make deps OS-specific * Move python deps to pyproject * Only compile and install on Linux with Meson * Revert "Move python deps to pyproject" This reverts commit 92c8a287b8376a4d166058c85f1d6081f6fdb423. * Add ninja to brewfile * Add python3-attr * Restore original coverage config * Add ninja for meson * Include meson in same try-except * Fixed ninja dep name * Move libs to correct oS * Fixed include for wintoast * Disable docs for libportal * More options for libei and libportal * Fixed option for libei * Use ninja directly to install * Revert "Use ninja directly to install" This reverts commit c926d78ba483406a55acd10fb157c39e13f90b71. * Meson install verbose * Prints stdout/stderr * Remove `from None` * Remove submodules that somehow crept back in?! * Prepend sudo if exists * Add libei deps for all distros * Fixed Fedora package name * Add more deps for other distros * Add more libs (including pugixml) * Fix lib name * Drop -u from pacman * Add vala to rhel * Make libportal optional * Make portal link optional * Remove example code * Always use system pugixml * Disable interactive apt through install_deps.py * Revert "Disable interactive apt through install_deps.py" This reverts commit 5bbc8fd689182447c79b81db16c961b98361a292. * Set DEBIAN_FRONTEND in workflows * Set DEBIAN_FRONTEND in CodeQL workflow * Add gtest dep * Add bundled libei dep * Add libei dep to Arch * Use `googletest` on openSUSE * Add gmock dep * Remove gtest dep from openSUSE * Add libei on Fedora * Bundle libei for older Linux distros * Disable libei dep for RPM * Also bundle symlink to .so * Use ${CMAKE_INSTALL_LIBDIR} * Rename libei to fix openSUSE * List installed files * Add libei-devel to openSUSE * Add googletest-devel to openSUSE * Remove manual deps (probably resolved automatically) * Remove googletest from openSUSE (doesn't provide google mock) * Only add Portal* if libportal found * WIP - Partial work on using old events system :'( * Add deps install commands for subprojects * Solved more compile issues related to events system, threads, etc * Fixed bad config for adding x, ei, portal sources * Remove redundant deps * Remove (another) redundant dep * Fixed pacman command * Add Ubuntu and Linux Mint libei deps * Fixed Ubuntu and Linux Mint libei deps aliases * Only iterate subprojects if not None * Add rhel, rocky, and alma for libei * Make rhel-like deps same as fedora again * Build libportal on rhel-like * Re-enable meson rhel-like for libportal * Remove dbus-python * Make libportal optional (for rhel-like) * Handle ei event queue results * Re-introduce libportal * Print libei and libportal versions * Add ei/portal args and client screen * Switch --use args to --no * Don't build libei/libportal on older distros as it's pointless * Make libei and libportal optional * Add Debian 13 runner * Make some packages optional * Remove subprojects * Improve comment * Add comment for libportal * Improve comment * Add Debian 13 runner * Make optional... optional * Change continuation stripper to remove newline and continuation char * Make command strip more uniform * Fixed help var syntax * Fixed libei linking * Ensure `kHelpNoWayland` is always defined * Improve help message * Fixed Debian 13 runner name * Include sstream and use const var * Update ChangeLog * Remove Wayland block * Return new timer * Make tray icon logging verbose * Fixed arg parser for wayland args * Fixed init of EI screen * Fixed lint issues * Update README to indicate Wayland support in GNOME 46 * Add missing word * Fixed comment positions * Automate CI env * Tone down debug log messages * Add missing comma * Remove redundant log line
2024-08-30 14:53:25 +00:00
#include "base/EventTypes.h"
#include "base/IEventQueue.h"
#include "base/PriorityQueue.h"
#include "base/Stopwatch.h"
#include "mt/CondVar.h"
2012-06-10 16:50:54 +00:00
#include <map>
#include <memory>
#include <mutex>
#include <queue>
#include <set>
2012-06-10 16:50:54 +00:00
//! Event queue
/*!
An event queue that implements the platform independent parts and
delegates the platform dependent parts to a subclass.
*/
class EventQueue : public IEventQueue
{
2012-06-10 16:50:54 +00:00
public:
EventQueue();
EventQueue(EventQueue const &) = delete;
EventQueue(EventQueue &&) = delete;
~EventQueue() override;
EventQueue &operator=(EventQueue const &) = delete;
EventQueue &operator=(EventQueue &&) = delete;
// IEventQueue overrides
void loop() override;
void adoptBuffer(IEventQueueBuffer *) override;
bool getEvent(Event &event, double timeout = -1.0) override;
bool dispatchEvent(const Event &event) override;
void addEvent(const Event &event) override;
EventQueueTimer *newTimer(double duration, void *target) override;
EventQueueTimer *newOneShotTimer(double duration, void *target) override;
void deleteTimer(EventQueueTimer *) override;
void adoptHandler(EventTypes type, void *target, IEventJob *handler) override;
void removeHandler(EventTypes type, void *target) override;
void removeHandlers(void *target) override;
bool isEmpty() const override;
IEventJob *getHandler(EventTypes type, void *target) const override;
void *getSystemTarget() override;
void waitForReady() const override;
2012-06-10 16:50:54 +00:00
private:
2025-01-11 02:13:19 +00:00
uint32_t saveEvent(const Event &event);
Event removeEvent(uint32_t eventID);
bool hasTimerExpired(Event &event);
double getNextTimerTimeout() const;
void addEventToBuffer(const Event &event);
//!
//! \brief processEvent Internal event proccessing
//! \param event - event to process
//! \param timeout - Timeout to stop
//! \param timer - StopWatch to use
//! \return true if handled
//!
bool processEvent(Event &event, double timeout, Stopwatch &timer);
2012-06-10 16:50:54 +00:00
private:
class Timer
{
public:
Timer(EventQueueTimer *, double timeout, double initialTime, void *target, bool oneShot);
~Timer() = default;
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;
};
using Timers = std::set<EventQueueTimer *>;
using TimerQueue = PriorityQueue<Timer>;
2025-01-11 02:13:19 +00:00
using EventTable = std::map<uint32_t, Event>;
using EventIDList = std::vector<uint32_t>;
using TypeHandlerTable = std::map<EventTypes, std::unique_ptr<IEventJob>>;
using HandlerTable = std::map<void *, TypeHandlerTable>;
int m_systemTarget = 0;
mutable std::mutex m_mutex;
// buffer of events
std::unique_ptr<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;
private:
Mutex *m_readyMutex = nullptr;
CondVar<bool> *m_readyCondVar = nullptr;
std::queue<Event> m_pending;
2012-06-10 16:50:54 +00:00
};