Files
deskflow/src/lib/base/Log.h
Nick Bolton 4e844bf307 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 15:53:25 +01:00

232 lines
8.0 KiB
C++

/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 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/Arch.h"
#include "arch/IArchMultithread.h"
#include "common/common.h"
#include "common/stdlist.h"
#include <stdarg.h>
#define CLOG (Log::getInstance())
#define BYE "\nTry `%s --help' for more information."
class ILogOutputter;
class Thread;
//! Logging facility
/*!
The logging class; all console output should go through this class.
It supports multithread safe operation, several message priority levels,
filtering by priority, and output redirection. The macros LOG() and
LOGC() provide convenient access.
*/
class Log {
public:
Log(bool singleton = true);
Log(Log *src);
Log(Log const &) = delete;
Log(Log &&) = delete;
~Log();
Log &operator=(Log const &) = delete;
Log &operator=(Log &&) = delete;
//! @name manipulators
//@{
//! Add an outputter to the head of the list
/*!
Inserts an outputter to the head of the outputter list. When the
logger writes a message, it goes to the outputter at the head of
the outputter list. If that outputter's \c write() method returns
true then it also goes to the next outputter, as so on until an
outputter returns false or there are no more outputters. Outputters
still in the outputter list when the log is destroyed will be
deleted. If \c alwaysAtHead is true then the outputter is always
called before all outputters with \c alwaysAtHead false and the
return value of the outputter is ignored.
By default, the logger has one outputter installed which writes to
the console.
*/
void insert(ILogOutputter *adopted, bool alwaysAtHead = false);
//! Remove an outputter from the list
/*!
Removes the first occurrence of the given outputter from the
outputter list. It does nothing if the outputter is not in the
list. The outputter is not deleted.
*/
void remove(ILogOutputter *orphaned);
//! Remove the outputter from the head of the list
/*!
Removes and deletes the outputter at the head of the outputter list.
This does nothing if the outputter list is empty. Only removes
outputters that were inserted with the matching \c alwaysAtHead.
*/
void pop_front(bool alwaysAtHead = false);
//! Set the minimum priority filter.
/*!
Set the filter. Messages below this priority are discarded.
The default priority is 4 (INFO) (unless built without NDEBUG
in which case it's 5 (DEBUG)). setFilter(const char*) returns
true if the priority \c name was recognized; if \c name is NULL
then it simply returns true.
*/
bool setFilter(const char *name);
//! Set the minimum priority filter (by ordinal).
void setFilter(int);
//@}
//! @name accessors
//@{
//! Print a log message
/*!
Print a log message using the printf-like \c format and arguments
preceded by the filename and line number. If \c file is NULL then
neither the file nor the line are printed.
*/
void print(const char *file, int line, const char *format, ...);
//! Get the minimum priority level.
int getFilter() const;
//! Get the filter name of the current filter level.
const char *getFilterName() const;
//! Get the filter name of a specified filter level.
const char *getFilterName(int level) const;
//! Get the singleton instance of the log
static Log *getInstance();
//! Get the console filter level (messages above this are not sent to
//! console).
int getConsoleMaxLevel() const { return kDEBUG2; }
//@}
private:
void output(ELevel priority, char *msg);
private:
typedef std::list<ILogOutputter *> OutputterList;
static Log *s_log;
ArchMutex m_mutex;
OutputterList m_outputters;
OutputterList m_alwaysOutputters;
int m_maxPriority;
};
/*!
\def LOG(arg)
Write to the log. Because macros cannot accept variable arguments, this
should be invoked like so:
\code
LOG((CLOG_XXX "%d and %d are %s", x, y, x == y ? "equal" : "not equal"));
\endcode
In particular, notice the double open and close parentheses. Also note
that there is no comma after the \c CLOG_XXX. The \c XXX should be
replaced by one of enumerants in \c Log::ELevel without the leading
\c k. For example, \c CLOG_INFO. The special \c CLOG_PRINT level will
not be filtered and is never prefixed by the filename and line number.
If \c NOLOGGING is defined during the build then this macro expands to
nothing. If \c NDEBUG is defined during the build then it expands to a
call to Log::print. Otherwise it expands to a call to Log::print,
which includes the filename and line number.
*/
/*!
\def LOGC(expr, arg)
Write to the log if and only if expr is true. Because macros cannot accept
variable arguments, this should be invoked like so:
\code
LOGC(x == y, (CLOG_XXX "%d and %d are equal", x, y));
\endcode
In particular, notice the parentheses around everything after the boolean
expression. Also note that there is no comma after the \c CLOG_XXX.
The \c XXX should be replaced by one of enumerants in \c Log::ELevel
without the leading \c k. For example, \c CLOG_INFO. The special
\c CLOG_PRINT level will not be filtered and is never prefixed by the
filename and line number.
If \c NOLOGGING is defined during the build then this macro expands to
nothing. If \c NDEBUG is not defined during the build then it expands
to a call to Log::print that prints the filename and line number,
otherwise it expands to a call that doesn't.
*/
#if defined(NOLOGGING)
#define LOG(_a1)
#define LOGC(_a1, _a2)
#define CLOG_TRACE
#elif defined(NDEBUG)
#define LOG(_a1) CLOG->print _a1
#define LOGC(_a1, _a2) \
if (_a1) \
CLOG->print _a2
#define CLOG_TRACE NULL, 0,
#else
#define LOG(_a1) CLOG->print _a1
#define LOGC(_a1, _a2) \
if (_a1) \
CLOG->print _a2
#define CLOG_TRACE __FILE__, __LINE__,
#endif
// the CLOG_* defines are line and file plus %z and an octal number (060=0,
// 071=9), but the limitation is that once we run out of numbers at either
// end, then we resort to using non-numerical chars. this still works (since
// to deduce the number we subtract octal \060, so '/' is -1, and ':' is 10
#define CLOG_PRINT CLOG_TRACE "%z\057" // char is '/'
#define CLOG_CRIT CLOG_TRACE "%z\060" // char is '0'
#define CLOG_ERR CLOG_TRACE "%z\061"
#define CLOG_WARN CLOG_TRACE "%z\062"
#define CLOG_NOTE CLOG_TRACE "%z\063"
#define CLOG_INFO CLOG_TRACE "%z\064"
#define CLOG_DEBUG CLOG_TRACE "%z\065"
#define CLOG_DEBUG1 CLOG_TRACE "%z\066"
#define CLOG_DEBUG2 CLOG_TRACE "%z\067"
#define CLOG_DEBUG3 CLOG_TRACE "%z\070"
#define CLOG_DEBUG4 CLOG_TRACE "%z\071" // char is '9'
#define CLOG_DEBUG5 CLOG_TRACE "%z\072" // char is ':'
#define LOG_PRINT(...) LOG((CLOG_PRINT __VA_ARGS__))
#define LOG_CRIT(...) LOG((CLOG_CRIT __VA_ARGS__))
#define LOG_ERR(...) LOG((CLOG_ERR __VA_ARGS__))
#define LOG_WARN(...) LOG((CLOG_WARN __VA_ARGS__))
#define LOG_NOTE(...) LOG((CLOG_NOTE __VA_ARGS__))
#define LOG_INFO(...) LOG((CLOG_INFO __VA_ARGS__))
#define LOG_DEBUG(...) LOG((CLOG_DEBUG __VA_ARGS__))
#define LOG_DEBUG1(...) LOG((CLOG_DEBUG1 __VA_ARGS__))
#define LOG_DEBUG2(...) LOG((CLOG_DEBUG2 __VA_ARGS__))
#define LOG_DEBUG3(...) LOG((CLOG_DEBUG3 __VA_ARGS__))
#define LOG_DEBUG4(...) LOG((CLOG_DEBUG4 __VA_ARGS__))
#define LOG_DEBUG5(...) LOG((CLOG_DEBUG5 __VA_ARGS__))