aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/server/Config.h
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2018-04-25 18:07:30 -0400
committerLibravatarUnit 193 <unit193@ubuntu.com>2018-04-25 18:07:30 -0400
commit9b1b081cfdb1c0fb6457278775e0823f8bc10f62 (patch)
treece8840148d8445055ba9e4f12263b2208f234c16 /src/lib/server/Config.h
Import Upstream version 2.0.0+dfsgupstream/2.0.0+dfsg
Diffstat (limited to 'src/lib/server/Config.h')
-rw-r--r--src/lib/server/Config.h549
1 files changed, 549 insertions, 0 deletions
diff --git a/src/lib/server/Config.h b/src/lib/server/Config.h
new file mode 100644
index 0000000..69b01c4
--- /dev/null
+++ b/src/lib/server/Config.h
@@ -0,0 +1,549 @@
+/*
+ * barrier -- 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 "server/InputFilter.h"
+#include "barrier/option_types.h"
+#include "barrier/protocol_types.h"
+#include "barrier/IPlatformScreen.h"
+#include "net/NetworkAddress.h"
+#include "base/String.h"
+#include "base/XBase.h"
+#include "common/stdmap.h"
+#include "common/stdset.h"
+
+#include <iosfwd>
+
+class Config;
+class ConfigReadContext;
+class IEventQueue;
+
+namespace std {
+template <>
+struct iterator_traits<Config> {
+ typedef String value_type;
+ typedef ptrdiff_t difference_type;
+ typedef bidirectional_iterator_tag iterator_category;
+ typedef String* pointer;
+ typedef String& reference;
+};
+};
+
+//! Server configuration
+/*!
+This class holds server configuration information. That includes
+the names of screens and their aliases, the links between them,
+and network addresses.
+
+Note that case is preserved in screen names but is ignored when
+comparing names. Screen names and their aliases share a
+namespace and must be unique.
+*/
+class Config {
+public:
+ typedef std::map<OptionID, OptionValue> ScreenOptions;
+ typedef std::pair<float, float> Interval;
+
+ class CellEdge {
+ public:
+ CellEdge(EDirection side, float position);
+ CellEdge(EDirection side, const Interval&);
+ CellEdge(const String& name, EDirection side, const Interval&);
+ ~CellEdge();
+
+ Interval getInterval() const;
+ void setName(const String& newName);
+ String getName() const;
+ EDirection getSide() const;
+ bool overlaps(const CellEdge&) const;
+ bool isInside(float x) const;
+
+ // transform position to [0,1]
+ float transform(float x) const;
+
+ // transform [0,1] to position
+ float inverseTransform(float x) const;
+
+ // compares side and start of interval
+ bool operator<(const CellEdge&) const;
+
+ // compares side and interval
+ bool operator==(const CellEdge&) const;
+ bool operator!=(const CellEdge&) const;
+
+ private:
+ void init(const String& name, EDirection side,
+ const Interval&);
+
+ private:
+ String m_name;
+ EDirection m_side;
+ Interval m_interval;
+ };
+
+private:
+ class Name {
+ public:
+ Name(Config*, const String& name);
+
+ bool operator==(const String& name) const;
+
+ private:
+ Config* m_config;
+ String m_name;
+ };
+
+ class Cell {
+ private:
+ typedef std::map<CellEdge, CellEdge> EdgeLinks;
+
+ public:
+ typedef EdgeLinks::const_iterator const_iterator;
+
+ bool add(const CellEdge& src, const CellEdge& dst);
+ void remove(EDirection side);
+ void remove(EDirection side, float position);
+ void remove(const Name& destinationName);
+ void rename(const Name& oldName, const String& newName);
+
+ bool hasEdge(const CellEdge&) const;
+ bool overlaps(const CellEdge&) const;
+
+ bool getLink(EDirection side, float position,
+ const CellEdge*& src, const CellEdge*& dst) const;
+
+ bool operator==(const Cell&) const;
+ bool operator!=(const Cell&) const;
+
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ private:
+ EdgeLinks m_neighbors;
+
+ public:
+ ScreenOptions m_options;
+ };
+ typedef std::map<String, Cell, barrier::string::CaselessCmp> CellMap;
+ typedef std::map<String, String, barrier::string::CaselessCmp> NameMap;
+
+public:
+ typedef Cell::const_iterator link_const_iterator;
+ typedef CellMap::const_iterator internal_const_iterator;
+ typedef NameMap::const_iterator all_const_iterator;
+ class const_iterator : std::iterator_traits<Config> {
+ public:
+ explicit const_iterator() : m_i() { }
+ explicit const_iterator(const internal_const_iterator& i) : m_i(i) { }
+
+ const_iterator& operator=(const const_iterator& i) {
+ m_i = i.m_i;
+ return *this;
+ }
+ String operator*() { return m_i->first; }
+ const String* operator->() { return &(m_i->first); }
+ const_iterator& operator++() { ++m_i; return *this; }
+ const_iterator operator++(int) { return const_iterator(m_i++); }
+ const_iterator& operator--() { --m_i; return *this; }
+ const_iterator operator--(int) { return const_iterator(m_i--); }
+ bool operator==(const const_iterator& i) const {
+ return (m_i == i.m_i);
+ }
+ bool operator!=(const const_iterator& i) const {
+ return (m_i != i.m_i);
+ }
+
+ private:
+ internal_const_iterator m_i;
+ };
+
+ Config(IEventQueue* events);
+ virtual ~Config();
+
+#ifdef TEST_ENV
+ Config() : m_inputFilter(NULL) { }
+#endif
+
+ //! @name manipulators
+ //@{
+
+ //! Add screen
+ /*!
+ Adds a screen, returning true iff successful. If a screen or
+ alias with the given name exists then it fails.
+ */
+ bool addScreen(const String& name);
+
+ //! Rename screen
+ /*!
+ Renames a screen. All references to the name are updated.
+ Returns true iff successful.
+ */
+ bool renameScreen(const String& oldName,
+ const String& newName);
+
+ //! Remove screen
+ /*!
+ Removes a screen. This also removes aliases for the screen and
+ disconnects any connections to the screen. \c name may be an
+ alias.
+ */
+ void removeScreen(const String& name);
+
+ //! Remove all screens
+ /*!
+ Removes all screens, aliases, and connections.
+ */
+ void removeAllScreens();
+
+ //! Add alias
+ /*!
+ Adds an alias for a screen name. An alias can be used
+ any place the canonical screen name can (except addScreen()).
+ Returns false if the alias name already exists or the canonical
+ name is unknown, otherwise returns true.
+ */
+ bool addAlias(const String& canonical,
+ const String& alias);
+
+ //! Remove alias
+ /*!
+ Removes an alias for a screen name. It returns false if the
+ alias is unknown or a canonical name, otherwise returns true.
+ */
+ bool removeAlias(const String& alias);
+
+ //! Remove aliases
+ /*!
+ Removes all aliases for a canonical screen name. It returns false
+ if the canonical name is unknown, otherwise returns true.
+ */
+ bool removeAliases(const String& canonical);
+
+ //! Remove all aliases
+ /*!
+ This removes all aliases but not the screens.
+ */
+ void removeAllAliases();
+
+ //! Connect screens
+ /*!
+ Establishes a one-way connection between portions of opposite edges
+ of two screens. Each portion is described by an interval defined
+ by two numbers, the start and end of the interval half-open on the
+ end. The numbers range from 0 to 1, inclusive, for the left/top
+ to the right/bottom. The user will be able to jump from the
+ \c srcStart to \c srcSend interval of \c srcSide of screen
+ \c srcName to the opposite side of screen \c dstName in the interval
+ \c dstStart and \c dstEnd when both screens are connected to the
+ server and the user isn't locked to a screen. Returns false if
+ \c srcName is unknown. \c srcStart must be less than or equal to
+ \c srcEnd and \c dstStart must be less then or equal to \c dstEnd
+ and all of \c srcStart, \c srcEnd, \c dstStart, or \c dstEnd must
+ be inside the range [0,1].
+ */
+ bool connect(const String& srcName,
+ EDirection srcSide,
+ float srcStart, float srcEnd,
+ const String& dstName,
+ float dstStart, float dstEnd);
+
+ //! Disconnect screens
+ /*!
+ Removes all connections created by connect() on side \c srcSide.
+ Returns false if \c srcName is unknown.
+ */
+ bool disconnect(const String& srcName,
+ EDirection srcSide);
+
+ //! Disconnect screens
+ /*!
+ Removes the connections created by connect() on side \c srcSide
+ covering position \c position. Returns false if \c srcName is
+ unknown.
+ */
+ bool disconnect(const String& srcName,
+ EDirection srcSide, float position);
+
+ //! Set server address
+ /*!
+ Set the barrier listen addresses. There is no default address so
+ this must be called to run a server using this configuration.
+ */
+ void setBarrierAddress(const NetworkAddress&);
+
+ //! Add a screen option
+ /*!
+ Adds an option and its value to the named screen. Replaces the
+ existing option's value if there is one. Returns true iff \c name
+ is a known screen.
+ */
+ bool addOption(const String& name,
+ OptionID option, OptionValue value);
+
+ //! Remove a screen option
+ /*!
+ Removes an option and its value from the named screen. Does
+ nothing if the option doesn't exist on the screen. Returns true
+ iff \c name is a known screen.
+ */
+ bool removeOption(const String& name, OptionID option);
+
+ //! Remove a screen options
+ /*!
+ Removes all options and values from the named screen. Returns true
+ iff \c name is a known screen.
+ */
+ bool removeOptions(const String& name);
+
+ //! Get the hot key input filter
+ /*!
+ Returns the hot key input filter. Clients can modify hotkeys using
+ that object.
+ */
+ virtual InputFilter*
+ getInputFilter();
+
+ //@}
+ //! @name accessors
+ //@{
+
+ //! Test screen name validity
+ /*!
+ Returns true iff \c name is a valid screen name.
+ */
+ bool isValidScreenName(const String& name) const;
+
+ //! Get beginning (canonical) screen name iterator
+ const_iterator begin() const;
+ //! Get ending (canonical) screen name iterator
+ const_iterator end() const;
+
+ //! Get beginning screen name iterator
+ all_const_iterator beginAll() const;
+ //! Get ending screen name iterator
+ all_const_iterator endAll() const;
+
+ //! Test for screen name
+ /*!
+ Returns true iff \c name names a screen.
+ */
+ virtual bool isScreen(const String& name) const;
+
+ //! Test for canonical screen name
+ /*!
+ Returns true iff \c name is the canonical name of a screen.
+ */
+ bool isCanonicalName(const String& name) const;
+
+ //! Get canonical name
+ /*!
+ Returns the canonical name of a screen or the empty string if
+ the name is unknown. Returns the canonical name if one is given.
+ */
+ String getCanonicalName(const String& name) const;
+
+ //! Get neighbor
+ /*!
+ Returns the canonical screen name of the neighbor in the given
+ direction (set through connect()) at position \c position. Returns
+ the empty string if there is no neighbor in that direction, otherwise
+ saves the position on the neighbor in \c positionOut if it's not
+ \c NULL.
+ */
+ String getNeighbor(const String&, EDirection,
+ float position, float* positionOut) const;
+
+ //! Check for neighbor
+ /*!
+ Returns \c true if the screen has a neighbor anywhere along the edge
+ given by the direction.
+ */
+ bool hasNeighbor(const String&, EDirection) const;
+
+ //! Check for neighbor
+ /*!
+ Returns \c true if the screen has a neighbor in the given range along
+ the edge given by the direction.
+ */
+ bool hasNeighbor(const String&, EDirection,
+ float start, float end) const;
+
+ //! Get beginning neighbor iterator
+ link_const_iterator beginNeighbor(const String&) const;
+ //! Get ending neighbor iterator
+ link_const_iterator endNeighbor(const String&) const;
+
+ //! Get the server address
+ const NetworkAddress&
+ getBarrierAddress() const;
+
+ //! Get the screen options
+ /*!
+ Returns all the added options for the named screen. Returns NULL
+ if the screen is unknown and an empty collection if there are no
+ options.
+ */
+ const ScreenOptions*
+ getOptions(const String& name) const;
+
+ //! Check for lock to screen action
+ /*!
+ Returns \c true if this configuration has a lock to screen action.
+ This is for backwards compatible support of ScrollLock locking.
+ */
+ bool hasLockToScreenAction() const;
+
+ //! Compare configurations
+ bool operator==(const Config&) const;
+ //! Compare configurations
+ bool operator!=(const Config&) const;
+
+ //! Read configuration
+ /*!
+ Reads a configuration from a context. Throws XConfigRead on error
+ and context is unchanged.
+ */
+ void read(ConfigReadContext& context);
+
+ //! Read configuration
+ /*!
+ Reads a configuration from a stream. Throws XConfigRead on error.
+ */
+ friend std::istream&
+ operator>>(std::istream&, Config&);
+
+ //! Write configuration
+ /*!
+ Writes a configuration to a stream.
+ */
+ friend std::ostream&
+ operator<<(std::ostream&, const Config&);
+
+ //! Get direction name
+ /*!
+ Returns the name of a direction (for debugging).
+ */
+ static const char* dirName(EDirection);
+
+ //! Get interval as string
+ /*!
+ Returns an interval as a parseable string.
+ */
+ static String formatInterval(const Interval&);
+
+ //@}
+
+private:
+ void readSection(ConfigReadContext&);
+ void readSectionOptions(ConfigReadContext&);
+ void readSectionScreens(ConfigReadContext&);
+ void readSectionLinks(ConfigReadContext&);
+ void readSectionAliases(ConfigReadContext&);
+
+ InputFilter::Condition*
+ parseCondition(ConfigReadContext&,
+ const String& condition,
+ const std::vector<String>& args);
+ void parseAction(ConfigReadContext&,
+ const String& action,
+ const std::vector<String>& args,
+ InputFilter::Rule&, bool activate);
+
+ void parseScreens(ConfigReadContext&, const String&,
+ std::set<String>& screens) const;
+ static const char* getOptionName(OptionID);
+ static String getOptionValue(OptionID, OptionValue);
+
+private:
+ CellMap m_map;
+ NameMap m_nameToCanonicalName;
+ NetworkAddress m_barrierAddress;
+ ScreenOptions m_globalOptions;
+ InputFilter m_inputFilter;
+ bool m_hasLockToScreenAction;
+ IEventQueue* m_events;
+};
+
+//! Configuration read context
+/*!
+Maintains a context when reading a configuration from a stream.
+*/
+class ConfigReadContext {
+public:
+ typedef std::vector<String> ArgList;
+
+ ConfigReadContext(std::istream&, SInt32 firstLine = 1);
+ ~ConfigReadContext();
+
+ bool readLine(String&);
+ UInt32 getLineNumber() const;
+
+ bool operator!() const;
+
+ OptionValue parseBoolean(const String&) const;
+ OptionValue parseInt(const String&) const;
+ OptionValue parseModifierKey(const String&) const;
+ OptionValue parseCorner(const String&) const;
+ OptionValue parseCorners(const String&) const;
+ Config::Interval
+ parseInterval(const ArgList& args) const;
+ void parseNameWithArgs(
+ const String& type, const String& line,
+ const String& delim, String::size_type& index,
+ String& name, ArgList& args) const;
+ IPlatformScreen::KeyInfo*
+ parseKeystroke(const String& keystroke) const;
+ IPlatformScreen::KeyInfo*
+ parseKeystroke(const String& keystroke,
+ const std::set<String>& screens) const;
+ IPlatformScreen::ButtonInfo*
+ parseMouse(const String& mouse) const;
+ KeyModifierMask parseModifier(const String& modifiers) const;
+ std::istream& getStream() const { return m_stream; };
+
+private:
+ // not implemented
+ ConfigReadContext& operator=(const ConfigReadContext&);
+
+ static String concatArgs(const ArgList& args);
+
+private:
+ std::istream& m_stream;
+ SInt32 m_line;
+};
+
+//! Configuration stream read exception
+/*!
+Thrown when a configuration stream cannot be parsed.
+*/
+class XConfigRead : public XBase {
+public:
+ XConfigRead(const ConfigReadContext& context, const String&);
+ XConfigRead(const ConfigReadContext& context,
+ const char* errorFmt, const String& arg);
+ virtual ~XConfigRead() _NOEXCEPT;
+
+protected:
+ // XBase overrides
+ virtual String getWhat() const throw();
+
+private:
+ String m_error;
+};