1 | /*
|
---|
2 | * synergy -- mouse and keyboard sharing utility
|
---|
3 | * Copyright (C) 2002 Chris Schoeneman
|
---|
4 | *
|
---|
5 | * This package is free software; you can redistribute it and/or
|
---|
6 | * modify it under the terms of the GNU General Public License
|
---|
7 | * found in the file COPYING that should have accompanied this file.
|
---|
8 | *
|
---|
9 | * This package is distributed in the hope that it will be useful,
|
---|
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
12 | * GNU General Public License for more details.
|
---|
13 | */
|
---|
14 |
|
---|
15 | #ifndef CCONFIG_H
|
---|
16 | #define CCONFIG_H
|
---|
17 |
|
---|
18 | #include "OptionTypes.h"
|
---|
19 | #include "ProtocolTypes.h"
|
---|
20 | #include "CNetworkAddress.h"
|
---|
21 | #include "CStringUtil.h"
|
---|
22 | #include "CInputFilter.h"
|
---|
23 | #include "XBase.h"
|
---|
24 | #include "stdmap.h"
|
---|
25 | #include "stdset.h"
|
---|
26 | #include "IPlatformScreen.h"
|
---|
27 | #include <iosfwd>
|
---|
28 |
|
---|
29 | class CConfig;
|
---|
30 | class CConfigReadContext;
|
---|
31 |
|
---|
32 | namespace std {
|
---|
33 | template <>
|
---|
34 | struct iterator_traits<CConfig> {
|
---|
35 | typedef CString value_type;
|
---|
36 | typedef ptrdiff_t difference_type;
|
---|
37 | typedef bidirectional_iterator_tag iterator_category;
|
---|
38 | typedef CString* pointer;
|
---|
39 | typedef CString& reference;
|
---|
40 | };
|
---|
41 | };
|
---|
42 |
|
---|
43 | //! Server configuration
|
---|
44 | /*!
|
---|
45 | This class holds server configuration information. That includes
|
---|
46 | the names of screens and their aliases, the links between them,
|
---|
47 | and network addresses.
|
---|
48 |
|
---|
49 | Note that case is preserved in screen names but is ignored when
|
---|
50 | comparing names. Screen names and their aliases share a
|
---|
51 | namespace and must be unique.
|
---|
52 | */
|
---|
53 | class CConfig {
|
---|
54 | public:
|
---|
55 | typedef std::map<OptionID, OptionValue> CScreenOptions;
|
---|
56 | typedef std::pair<float, float> CInterval;
|
---|
57 |
|
---|
58 | class CCellEdge {
|
---|
59 | public:
|
---|
60 | CCellEdge(EDirection side, float position);
|
---|
61 | CCellEdge(EDirection side, const CInterval&);
|
---|
62 | CCellEdge(const CString& name, EDirection side, const CInterval&);
|
---|
63 | ~CCellEdge();
|
---|
64 |
|
---|
65 | CInterval getInterval() const;
|
---|
66 | void setName(const CString& newName);
|
---|
67 | CString getName() const;
|
---|
68 | EDirection getSide() const;
|
---|
69 | bool overlaps(const CCellEdge&) const;
|
---|
70 | bool isInside(float x) const;
|
---|
71 |
|
---|
72 | // transform position to [0,1]
|
---|
73 | float transform(float x) const;
|
---|
74 |
|
---|
75 | // transform [0,1] to position
|
---|
76 | float inverseTransform(float x) const;
|
---|
77 |
|
---|
78 | // compares side and start of interval
|
---|
79 | bool operator<(const CCellEdge&) const;
|
---|
80 |
|
---|
81 | // compares side and interval
|
---|
82 | bool operator==(const CCellEdge&) const;
|
---|
83 | bool operator!=(const CCellEdge&) const;
|
---|
84 |
|
---|
85 | private:
|
---|
86 | void init(const CString& name, EDirection side,
|
---|
87 | const CInterval&);
|
---|
88 |
|
---|
89 | private:
|
---|
90 | CString m_name;
|
---|
91 | EDirection m_side;
|
---|
92 | CInterval m_interval;
|
---|
93 | };
|
---|
94 |
|
---|
95 | private:
|
---|
96 | class CName {
|
---|
97 | public:
|
---|
98 | CName(CConfig*, const CString& name);
|
---|
99 |
|
---|
100 | bool operator==(const CString& name) const;
|
---|
101 |
|
---|
102 | private:
|
---|
103 | CConfig* m_config;
|
---|
104 | CString m_name;
|
---|
105 | };
|
---|
106 |
|
---|
107 | class CCell {
|
---|
108 | private:
|
---|
109 | typedef std::map<CCellEdge, CCellEdge> CEdgeLinks;
|
---|
110 |
|
---|
111 | public:
|
---|
112 | typedef CEdgeLinks::const_iterator const_iterator;
|
---|
113 |
|
---|
114 | bool add(const CCellEdge& src, const CCellEdge& dst);
|
---|
115 | void remove(EDirection side);
|
---|
116 | void remove(EDirection side, float position);
|
---|
117 | void remove(const CName& destinationName);
|
---|
118 | void rename(const CName& oldName, const CString& newName);
|
---|
119 |
|
---|
120 | bool hasEdge(const CCellEdge&) const;
|
---|
121 | bool overlaps(const CCellEdge&) const;
|
---|
122 |
|
---|
123 | bool getLink(EDirection side, float position,
|
---|
124 | const CCellEdge*& src, const CCellEdge*& dst) const;
|
---|
125 |
|
---|
126 | bool operator==(const CCell&) const;
|
---|
127 | bool operator!=(const CCell&) const;
|
---|
128 |
|
---|
129 | const_iterator begin() const;
|
---|
130 | const_iterator end() const;
|
---|
131 |
|
---|
132 | private:
|
---|
133 | CEdgeLinks m_neighbors;
|
---|
134 |
|
---|
135 | public:
|
---|
136 | CScreenOptions m_options;
|
---|
137 | };
|
---|
138 | typedef std::map<CString, CCell, CStringUtil::CaselessCmp> CCellMap;
|
---|
139 | typedef std::map<CString, CString, CStringUtil::CaselessCmp> CNameMap;
|
---|
140 |
|
---|
141 | public:
|
---|
142 | typedef CCell::const_iterator link_const_iterator;
|
---|
143 | typedef CCellMap::const_iterator internal_const_iterator;
|
---|
144 | typedef CNameMap::const_iterator all_const_iterator;
|
---|
145 | class const_iterator : std::iterator_traits<CConfig> {
|
---|
146 | public:
|
---|
147 | explicit const_iterator() : m_i() { }
|
---|
148 | explicit const_iterator(const internal_const_iterator& i) : m_i(i) { }
|
---|
149 |
|
---|
150 | const_iterator& operator=(const const_iterator& i) {
|
---|
151 | m_i = i.m_i;
|
---|
152 | return *this;
|
---|
153 | }
|
---|
154 | CString operator*() { return m_i->first; }
|
---|
155 | const CString* operator->() { return &(m_i->first); }
|
---|
156 | const_iterator& operator++() { ++m_i; return *this; }
|
---|
157 | const_iterator operator++(int) { return const_iterator(m_i++); }
|
---|
158 | const_iterator& operator--() { --m_i; return *this; }
|
---|
159 | const_iterator operator--(int) { return const_iterator(m_i--); }
|
---|
160 | bool operator==(const const_iterator& i) const {
|
---|
161 | return (m_i == i.m_i);
|
---|
162 | }
|
---|
163 | bool operator!=(const const_iterator& i) const {
|
---|
164 | return (m_i != i.m_i);
|
---|
165 | }
|
---|
166 |
|
---|
167 | private:
|
---|
168 | internal_const_iterator m_i;
|
---|
169 | };
|
---|
170 |
|
---|
171 | CConfig();
|
---|
172 | virtual ~CConfig();
|
---|
173 |
|
---|
174 | //! @name manipulators
|
---|
175 | //@{
|
---|
176 |
|
---|
177 | //! Add screen
|
---|
178 | /*!
|
---|
179 | Adds a screen, returning true iff successful. If a screen or
|
---|
180 | alias with the given name exists then it fails.
|
---|
181 | */
|
---|
182 | bool addScreen(const CString& name);
|
---|
183 |
|
---|
184 | //! Rename screen
|
---|
185 | /*!
|
---|
186 | Renames a screen. All references to the name are updated.
|
---|
187 | Returns true iff successful.
|
---|
188 | */
|
---|
189 | bool renameScreen(const CString& oldName,
|
---|
190 | const CString& newName);
|
---|
191 |
|
---|
192 | //! Remove screen
|
---|
193 | /*!
|
---|
194 | Removes a screen. This also removes aliases for the screen and
|
---|
195 | disconnects any connections to the screen. \c name may be an
|
---|
196 | alias.
|
---|
197 | */
|
---|
198 | void removeScreen(const CString& name);
|
---|
199 |
|
---|
200 | //! Remove all screens
|
---|
201 | /*!
|
---|
202 | Removes all screens, aliases, and connections.
|
---|
203 | */
|
---|
204 | void removeAllScreens();
|
---|
205 |
|
---|
206 | //! Add alias
|
---|
207 | /*!
|
---|
208 | Adds an alias for a screen name. An alias can be used
|
---|
209 | any place the canonical screen name can (except addScreen()).
|
---|
210 | Returns false if the alias name already exists or the canonical
|
---|
211 | name is unknown, otherwise returns true.
|
---|
212 | */
|
---|
213 | bool addAlias(const CString& canonical,
|
---|
214 | const CString& alias);
|
---|
215 |
|
---|
216 | //! Remove alias
|
---|
217 | /*!
|
---|
218 | Removes an alias for a screen name. It returns false if the
|
---|
219 | alias is unknown or a canonical name, otherwise returns true.
|
---|
220 | */
|
---|
221 | bool removeAlias(const CString& alias);
|
---|
222 |
|
---|
223 | //! Remove aliases
|
---|
224 | /*!
|
---|
225 | Removes all aliases for a canonical screen name. It returns false
|
---|
226 | if the canonical name is unknown, otherwise returns true.
|
---|
227 | */
|
---|
228 | bool removeAliases(const CString& canonical);
|
---|
229 |
|
---|
230 | //! Remove all aliases
|
---|
231 | /*!
|
---|
232 | This removes all aliases but not the screens.
|
---|
233 | */
|
---|
234 | void removeAllAliases();
|
---|
235 |
|
---|
236 | //! Connect screens
|
---|
237 | /*!
|
---|
238 | Establishes a one-way connection between portions of opposite edges
|
---|
239 | of two screens. Each portion is described by an interval defined
|
---|
240 | by two numbers, the start and end of the interval half-open on the
|
---|
241 | end. The numbers range from 0 to 1, inclusive, for the left/top
|
---|
242 | to the right/bottom. The user will be able to jump from the
|
---|
243 | \c srcStart to \c srcSend interval of \c srcSide of screen
|
---|
244 | \c srcName to the opposite side of screen \c dstName in the interval
|
---|
245 | \c dstStart and \c dstEnd when both screens are connected to the
|
---|
246 | server and the user isn't locked to a screen. Returns false if
|
---|
247 | \c srcName is unknown. \c srcStart must be less than or equal to
|
---|
248 | \c srcEnd and \c dstStart must be less then or equal to \c dstEnd
|
---|
249 | and all of \c srcStart, \c srcEnd, \c dstStart, or \c dstEnd must
|
---|
250 | be inside the range [0,1].
|
---|
251 | */
|
---|
252 | bool connect(const CString& srcName,
|
---|
253 | EDirection srcSide,
|
---|
254 | float srcStart, float srcEnd,
|
---|
255 | const CString& dstName,
|
---|
256 | float dstStart, float dstEnd);
|
---|
257 |
|
---|
258 | //! Disconnect screens
|
---|
259 | /*!
|
---|
260 | Removes all connections created by connect() on side \c srcSide.
|
---|
261 | Returns false if \c srcName is unknown.
|
---|
262 | */
|
---|
263 | bool disconnect(const CString& srcName,
|
---|
264 | EDirection srcSide);
|
---|
265 |
|
---|
266 | //! Disconnect screens
|
---|
267 | /*!
|
---|
268 | Removes the connections created by connect() on side \c srcSide
|
---|
269 | covering position \c position. Returns false if \c srcName is
|
---|
270 | unknown.
|
---|
271 | */
|
---|
272 | bool disconnect(const CString& srcName,
|
---|
273 | EDirection srcSide, float position);
|
---|
274 |
|
---|
275 | //! Set server address
|
---|
276 | /*!
|
---|
277 | Set the synergy listen addresses. There is no default address so
|
---|
278 | this must be called to run a server using this configuration.
|
---|
279 | */
|
---|
280 | void setSynergyAddress(const CNetworkAddress&);
|
---|
281 |
|
---|
282 | //! Add a screen option
|
---|
283 | /*!
|
---|
284 | Adds an option and its value to the named screen. Replaces the
|
---|
285 | existing option's value if there is one. Returns true iff \c name
|
---|
286 | is a known screen.
|
---|
287 | */
|
---|
288 | bool addOption(const CString& name,
|
---|
289 | OptionID option, OptionValue value);
|
---|
290 |
|
---|
291 | //! Remove a screen option
|
---|
292 | /*!
|
---|
293 | Removes an option and its value from the named screen. Does
|
---|
294 | nothing if the option doesn't exist on the screen. Returns true
|
---|
295 | iff \c name is a known screen.
|
---|
296 | */
|
---|
297 | bool removeOption(const CString& name, OptionID option);
|
---|
298 |
|
---|
299 | //! Remove a screen options
|
---|
300 | /*!
|
---|
301 | Removes all options and values from the named screen. Returns true
|
---|
302 | iff \c name is a known screen.
|
---|
303 | */
|
---|
304 | bool removeOptions(const CString& name);
|
---|
305 |
|
---|
306 | //! Get the hot key input filter
|
---|
307 | /*!
|
---|
308 | Returns the hot key input filter. Clients can modify hotkeys using
|
---|
309 | that object.
|
---|
310 | */
|
---|
311 | CInputFilter* getInputFilter();
|
---|
312 |
|
---|
313 | //@}
|
---|
314 | //! @name accessors
|
---|
315 | //@{
|
---|
316 |
|
---|
317 | //! Test screen name validity
|
---|
318 | /*!
|
---|
319 | Returns true iff \c name is a valid screen name.
|
---|
320 | */
|
---|
321 | bool isValidScreenName(const CString& name) const;
|
---|
322 |
|
---|
323 | //! Get beginning (canonical) screen name iterator
|
---|
324 | const_iterator begin() const;
|
---|
325 | //! Get ending (canonical) screen name iterator
|
---|
326 | const_iterator end() const;
|
---|
327 |
|
---|
328 | //! Get beginning screen name iterator
|
---|
329 | all_const_iterator beginAll() const;
|
---|
330 | //! Get ending screen name iterator
|
---|
331 | all_const_iterator endAll() const;
|
---|
332 |
|
---|
333 | //! Test for screen name
|
---|
334 | /*!
|
---|
335 | Returns true iff \c name names a screen.
|
---|
336 | */
|
---|
337 | bool isScreen(const CString& name) const;
|
---|
338 |
|
---|
339 | //! Test for canonical screen name
|
---|
340 | /*!
|
---|
341 | Returns true iff \c name is the canonical name of a screen.
|
---|
342 | */
|
---|
343 | bool isCanonicalName(const CString& name) const;
|
---|
344 |
|
---|
345 | //! Get canonical name
|
---|
346 | /*!
|
---|
347 | Returns the canonical name of a screen or the empty string if
|
---|
348 | the name is unknown. Returns the canonical name if one is given.
|
---|
349 | */
|
---|
350 | CString getCanonicalName(const CString& name) const;
|
---|
351 |
|
---|
352 | //! Get neighbor
|
---|
353 | /*!
|
---|
354 | Returns the canonical screen name of the neighbor in the given
|
---|
355 | direction (set through connect()) at position \c position. Returns
|
---|
356 | the empty string if there is no neighbor in that direction, otherwise
|
---|
357 | saves the position on the neighbor in \c positionOut if it's not
|
---|
358 | \c NULL.
|
---|
359 | */
|
---|
360 | CString getNeighbor(const CString&, EDirection,
|
---|
361 | float position, float* positionOut) const;
|
---|
362 |
|
---|
363 | //! Check for neighbor
|
---|
364 | /*!
|
---|
365 | Returns \c true if the screen has a neighbor anywhere along the edge
|
---|
366 | given by the direction.
|
---|
367 | */
|
---|
368 | bool hasNeighbor(const CString&, EDirection) const;
|
---|
369 |
|
---|
370 | //! Check for neighbor
|
---|
371 | /*!
|
---|
372 | Returns \c true if the screen has a neighbor in the given range along
|
---|
373 | the edge given by the direction.
|
---|
374 | */
|
---|
375 | bool hasNeighbor(const CString&, EDirection,
|
---|
376 | float start, float end) const;
|
---|
377 |
|
---|
378 | //! Get beginning neighbor iterator
|
---|
379 | link_const_iterator beginNeighbor(const CString&) const;
|
---|
380 | //! Get ending neighbor iterator
|
---|
381 | link_const_iterator endNeighbor(const CString&) const;
|
---|
382 |
|
---|
383 | //! Get the server address
|
---|
384 | const CNetworkAddress& getSynergyAddress() const;
|
---|
385 |
|
---|
386 | //! Get the screen options
|
---|
387 | /*!
|
---|
388 | Returns all the added options for the named screen. Returns NULL
|
---|
389 | if the screen is unknown and an empty collection if there are no
|
---|
390 | options.
|
---|
391 | */
|
---|
392 | const CScreenOptions* getOptions(const CString& name) const;
|
---|
393 |
|
---|
394 | //! Check for lock to screen action
|
---|
395 | /*!
|
---|
396 | Returns \c true if this configuration has a lock to screen action.
|
---|
397 | This is for backwards compatible support of ScrollLock locking.
|
---|
398 | */
|
---|
399 | bool hasLockToScreenAction() const;
|
---|
400 |
|
---|
401 | //! Compare configurations
|
---|
402 | bool operator==(const CConfig&) const;
|
---|
403 | //! Compare configurations
|
---|
404 | bool operator!=(const CConfig&) const;
|
---|
405 |
|
---|
406 | //! Read configuration
|
---|
407 | /*!
|
---|
408 | Reads a configuration from a context. Throws XConfigRead on error
|
---|
409 | and context is unchanged.
|
---|
410 | */
|
---|
411 | void read(CConfigReadContext& context);
|
---|
412 |
|
---|
413 | //! Read configuration
|
---|
414 | /*!
|
---|
415 | Reads a configuration from a stream. Throws XConfigRead on error.
|
---|
416 | */
|
---|
417 | friend std::istream& operator>>(std::istream&, CConfig&);
|
---|
418 |
|
---|
419 | //! Write configuration
|
---|
420 | /*!
|
---|
421 | Writes a configuration to a stream.
|
---|
422 | */
|
---|
423 | friend std::ostream& operator<<(std::ostream&, const CConfig&);
|
---|
424 |
|
---|
425 | //! Get direction name
|
---|
426 | /*!
|
---|
427 | Returns the name of a direction (for debugging).
|
---|
428 | */
|
---|
429 | static const char* dirName(EDirection);
|
---|
430 |
|
---|
431 | //! Get interval as string
|
---|
432 | /*!
|
---|
433 | Returns an interval as a parseable string.
|
---|
434 | */
|
---|
435 | static CString formatInterval(const CInterval&);
|
---|
436 |
|
---|
437 | //@}
|
---|
438 |
|
---|
439 | private:
|
---|
440 | void readSection(CConfigReadContext&);
|
---|
441 | void readSectionOptions(CConfigReadContext&);
|
---|
442 | void readSectionScreens(CConfigReadContext&);
|
---|
443 | void readSectionLinks(CConfigReadContext&);
|
---|
444 | void readSectionAliases(CConfigReadContext&);
|
---|
445 |
|
---|
446 | CInputFilter::CCondition*
|
---|
447 | parseCondition(CConfigReadContext&,
|
---|
448 | const CString& condition,
|
---|
449 | const std::vector<CString>& args);
|
---|
450 | void parseAction(CConfigReadContext&,
|
---|
451 | const CString& action,
|
---|
452 | const std::vector<CString>& args,
|
---|
453 | CInputFilter::CRule&, bool activate);
|
---|
454 |
|
---|
455 | void parseScreens(CConfigReadContext&, const CString&,
|
---|
456 | std::set<CString>& screens) const;
|
---|
457 | static const char* getOptionName(OptionID);
|
---|
458 | static CString getOptionValue(OptionID, OptionValue);
|
---|
459 |
|
---|
460 | private:
|
---|
461 | CCellMap m_map;
|
---|
462 | CNameMap m_nameToCanonicalName;
|
---|
463 | CNetworkAddress m_synergyAddress;
|
---|
464 | CScreenOptions m_globalOptions;
|
---|
465 | CInputFilter m_inputFilter;
|
---|
466 | bool m_hasLockToScreenAction;
|
---|
467 | };
|
---|
468 |
|
---|
469 | //! Configuration read context
|
---|
470 | /*!
|
---|
471 | Maintains a context when reading a configuration from a stream.
|
---|
472 | */
|
---|
473 | class CConfigReadContext {
|
---|
474 | public:
|
---|
475 | typedef std::vector<CString> ArgList;
|
---|
476 |
|
---|
477 | CConfigReadContext(std::istream&, SInt32 firstLine = 1);
|
---|
478 | ~CConfigReadContext();
|
---|
479 |
|
---|
480 | bool readLine(CString&);
|
---|
481 | UInt32 getLineNumber() const;
|
---|
482 |
|
---|
483 | operator void*() const;
|
---|
484 | bool operator!() const;
|
---|
485 |
|
---|
486 | OptionValue parseBoolean(const CString&) const;
|
---|
487 | OptionValue parseInt(const CString&) const;
|
---|
488 | OptionValue parseModifierKey(const CString&) const;
|
---|
489 | OptionValue parseCorner(const CString&) const;
|
---|
490 | OptionValue parseCorners(const CString&) const;
|
---|
491 | CConfig::CInterval
|
---|
492 | parseInterval(const ArgList& args) const;
|
---|
493 | void parseNameWithArgs(
|
---|
494 | const CString& type, const CString& line,
|
---|
495 | const CString& delim, CString::size_type& index,
|
---|
496 | CString& name, ArgList& args) const;
|
---|
497 | IPlatformScreen::CKeyInfo*
|
---|
498 | parseKeystroke(const CString& keystroke) const;
|
---|
499 | IPlatformScreen::CKeyInfo*
|
---|
500 | parseKeystroke(const CString& keystroke,
|
---|
501 | const std::set<CString>& screens) const;
|
---|
502 | IPlatformScreen::CButtonInfo*
|
---|
503 | parseMouse(const CString& mouse) const;
|
---|
504 | KeyModifierMask parseModifier(const CString& modifiers) const;
|
---|
505 |
|
---|
506 | private:
|
---|
507 | // not implemented
|
---|
508 | CConfigReadContext& operator=(const CConfigReadContext&);
|
---|
509 |
|
---|
510 | static CString concatArgs(const ArgList& args);
|
---|
511 |
|
---|
512 | private:
|
---|
513 | std::istream& m_stream;
|
---|
514 | SInt32 m_line;
|
---|
515 | };
|
---|
516 |
|
---|
517 | //! Configuration stream read exception
|
---|
518 | /*!
|
---|
519 | Thrown when a configuration stream cannot be parsed.
|
---|
520 | */
|
---|
521 | class XConfigRead : public XBase {
|
---|
522 | public:
|
---|
523 | XConfigRead(const CConfigReadContext& context, const CString&);
|
---|
524 | XConfigRead(const CConfigReadContext& context,
|
---|
525 | const char* errorFmt, const CString& arg);
|
---|
526 | ~XConfigRead();
|
---|
527 |
|
---|
528 | protected:
|
---|
529 | // XBase overrides
|
---|
530 | virtual CString getWhat() const throw();
|
---|
531 |
|
---|
532 | private:
|
---|
533 | CString m_error;
|
---|
534 | };
|
---|
535 |
|
---|
536 | #endif
|
---|