source: vendor/synergy/current/lib/server/CConfig.h

Last change on this file was 2749, checked in by bird, 19 years ago

synergy v1.3.1 sources (zip).

File size: 14.8 KB
Line 
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
29class CConfig;
30class CConfigReadContext;
31
32namespace std {
33template <>
34struct 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/*!
45This class holds server configuration information. That includes
46the names of screens and their aliases, the links between them,
47and network addresses.
48
49Note that case is preserved in screen names but is ignored when
50comparing names. Screen names and their aliases share a
51namespace and must be unique.
52*/
53class CConfig {
54public:
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
95private:
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
141public:
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
439private:
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
460private:
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/*!
471Maintains a context when reading a configuration from a stream.
472*/
473class CConfigReadContext {
474public:
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
506private:
507 // not implemented
508 CConfigReadContext& operator=(const CConfigReadContext&);
509
510 static CString concatArgs(const ArgList& args);
511
512private:
513 std::istream& m_stream;
514 SInt32 m_line;
515};
516
517//! Configuration stream read exception
518/*!
519Thrown when a configuration stream cannot be parsed.
520*/
521class XConfigRead : public XBase {
522public:
523 XConfigRead(const CConfigReadContext& context, const CString&);
524 XConfigRead(const CConfigReadContext& context,
525 const char* errorFmt, const CString& arg);
526 ~XConfigRead();
527
528protected:
529 // XBase overrides
530 virtual CString getWhat() const throw();
531
532private:
533 CString m_error;
534};
535
536#endif
Note: See TracBrowser for help on using the repository browser.