1 #pragma once
2 
3 #include <wayfire/config/option-types.hpp>
4 #include <glm/vec4.hpp>
5 #include <memory>
6 #include <vector>
7 
8 namespace wf
9 {
10 namespace option_type
11 {
12 /**
13  * To create an option of a given type, from_string must be specialized for
14  * parsing the type.
15  *
16  * @param string The string representation of the value.
17  * @return The parsed value, if the string was valid.
18  */
19 template<class Type>
20 stdx::optional<Type> from_string(
21     const std::string& string);
22 
23 /**
24  * To create an option of a given type, to_string must be specialized for
25  * converting the type to string.
26  * @return The string representation of a value.
27  *   It is expected that from_string(to_string(value)) == value.
28  */
29 template<class Type>
30 std::string to_string(const Type& value);
31 
32 /**
33  * Parse the given string as a signed 32-bit integer in decimal system.
34  */
35 template<>
36 stdx::optional<int> from_string<int>(const std::string&);
37 
38 /**
39  * Parse the given string as a boolean value.
40  * Truthy values are "True" (any capitalization) and 1.
41  * False values are "False" (any capitalization) and 0.
42  */
43 template<>
44 stdx::optional<bool> from_string<bool>(const std::string&);
45 
46 /**
47  * Parse the given string as a signed 64-bit floating point number.
48  */
49 template<>
50 stdx::optional<double> from_string<double>(const std::string&);
51 
52 /**
53  * Parse the string as a string.
54  * The string should not contain newline characters.
55  */
56 template<>
57 stdx::optional<std::string> from_string<std::string>(const std::string&);
58 
59 /**
60  * Convert the given bool to a string.
61  */
62 template<>
63 std::string to_string<bool>(const bool& value);
64 
65 /**
66  * Convert the given integer to a string.
67  */
68 template<>
69 std::string to_string<int>(const int& value);
70 
71 /**
72  * Convert the given double to a string.
73  */
74 template<>
75 std::string to_string<double>(const double& value);
76 
77 /**
78  * Convert the given string to a string.
79  */
80 template<>
81 std::string to_string<std::string>(const std::string& value);
82 }
83 
84 /**
85  * Represents a color in RGBA format.
86  */
87 struct color_t
88 {
89   public:
90     /** Initialize a black transparent color (default) */
91     color_t();
92 
93     /**
94      * Initialize a new color value with the given values
95      * Values will be clamped to the [0, 1] range.
96      */
97     color_t(double r, double g, double b, double a);
98 
99     /**
100      * Initialize a new color value with the given values.
101      * Values will be clamped to the [0, 1] range.
102      */
103     explicit color_t(const glm::vec4& value);
104 
105     /**
106      * Compare colors channel-for-channel.
107      * Comparisons use a small epsilon 1e-6.
108      */
109     bool operator ==(const color_t& other) const;
110 
111     /** Red channel value */
112     double r;
113     /** Green channel value */
114     double g;
115     /** Blue channel value */
116     double b;
117     /** Alpha channel value */
118     double a;
119 };
120 
121 namespace option_type
122 {
123 /**
124  * Create a new color value from the given hex string, format is either
125  * #RRGGBBAA or #RGBA.
126  */
127 template<>
128 stdx::optional<color_t> from_string(const std::string& value);
129 
130 /** Convert the color to its hex string representation. */
131 template<>
132 std::string to_string(const color_t& value);
133 }
134 
135 /**
136  * A list of valid modifiers.
137  * The enumerations values are the same as the ones in wlroots.
138  */
139 enum keyboard_modifier_t
140 {
141     /* Shift modifier, <shift> */
142     KEYBOARD_MODIFIER_SHIFT = 1,
143     /* Control modifier, <ctrl> */
144     KEYBOARD_MODIFIER_CTRL  = 4,
145     /* Alt modifier, <alt> */
146     KEYBOARD_MODIFIER_ALT   = 8,
147     /* Windows/Mac logo modifier, <super> */
148     KEYBOARD_MODIFIER_LOGO  = 64,
149 };
150 
151 /**
152  * Represents a single keyboard shortcut.
153  */
154 struct keybinding_t
155 {
156   public:
157     /**
158      * Construct a new keybinding with the given modifier and key.
159      */
160     keybinding_t(uint32_t modifier, uint32_t keyval);
161 
162     /* Check whether two keybindings refer to the same shortcut */
163     bool operator ==(const keybinding_t& other) const;
164 
165     /** @return The modifiers of the keybinding */
166     uint32_t get_modifiers() const;
167     /** @return The key of the keybinding */
168     uint32_t get_key() const;
169 
170   private:
171     /** The modifier mask of this keybinding */
172     uint32_t mod;
173     /** The key of this keybinding */
174     uint32_t keyval;
175 };
176 
177 namespace option_type
178 {
179 /**
180  * Construct a new keybinding from the given string description.
181  * Format is <modifier1> .. <modifierN> KEY_<keyname>, where whitespace
182  * characters between the different modifiers and KEY_* are ignored.
183  *
184  * For a list of available modifieres, see @keyboard_modifier_t.
185  *
186  * The KEY_<keyname> is derived from evdev, and possible names are
187  * enumerated in linux/input-event-codes.h
188  *
189  * For example, "<super> <alt> KEY_E" represents pressing the Logo, Alt and
190  * E keys together.
191  *
192  * Special cases are "none" and "disabled", which result in modifiers and
193  * key 0.
194  */
195 template<>
196 stdx::optional<keybinding_t> from_string(
197     const std::string& description);
198 
199 /** Represent the keybinding as a string. */
200 template<>
201 std::string to_string(const keybinding_t& value);
202 }
203 
204 /**
205  * Represents a single button shortcut (pressing a mouse button while holding
206  * modifiers).
207  */
208 struct buttonbinding_t
209 {
210   public:
211     /**
212      * Construct a new buttonbinding with the given modifier and button.
213      */
214     buttonbinding_t(uint32_t modifier, uint32_t button);
215 
216     /* Check whether two keybindings refer to the same shortcut */
217     bool operator ==(const buttonbinding_t& other) const;
218 
219     /** @return The modifiers of the buttonbinding */
220     uint32_t get_modifiers() const;
221     /** @return The button of the buttonbinding */
222     uint32_t get_button() const;
223 
224   private:
225     /** The modifier mask of this keybinding */
226     uint32_t mod;
227     /** The key of this keybinding */
228     uint32_t button;
229 };
230 
231 namespace option_type
232 {
233 /**
234  * Construct a new buttonbinding from the given description.
235  * The format is the same as a keybinding, however instead of KEY_* values,
236  * the buttons are prefixed with BTN_*
237  *
238  * Special case are descriptions "none" and "disable", which result in
239  * mod = button = 0
240  */
241 template<>
242 stdx::optional<buttonbinding_t> from_string(
243     const std::string& description);
244 
245 /** Represent the buttonbinding as a string. */
246 template<>
247 std::string to_string(const buttonbinding_t& value);
248 }
249 
250 /**
251  * The different types of available gestures.
252  */
253 enum touch_gesture_type_t
254 {
255     /* Invalid gesture */
256     GESTURE_TYPE_NONE       = 0,
257     /* Swipe gesture, i.e moving in one direction */
258     GESTURE_TYPE_SWIPE      = 1,
259     /* Edge swipe, which is a swipe originating from the edge of the screen */
260     GESTURE_TYPE_EDGE_SWIPE = 2,
261     /* Pinch gesture, multiple touch points coming closer or farther apart
262      * from the center */
263     GESTURE_TYPE_PINCH      = 3,
264 };
265 
266 enum touch_gesture_direction_t
267 {
268     /* Swipe-specific */
269     GESTURE_DIRECTION_LEFT  = (1 << 0),
270     GESTURE_DIRECTION_RIGHT = (1 << 1),
271     GESTURE_DIRECTION_UP    = (1 << 2),
272     GESTURE_DIRECTION_DOWN  = (1 << 3),
273     /* Pinch-specific */
274     GESTURE_DIRECTION_IN    = (1 << 4),
275     GESTURE_DIRECTION_OUT   = (1 << 5),
276 };
277 
278 /**
279  * Represents a touch gesture.
280  *
281  * A touch gesture has a type, direction and finger count.
282  * Finger count can be arbitrary, although Wayfire supports only gestures
283  * with finger count >= 3 currently.
284  *
285  * Direction can be either one of of @touch_gesture_direction_t or, in case of
286  * the swipe gestures, it can be a bitwise OR of two non-opposing directions.
287  */
288 struct touchgesture_t
289 {
290     /**
291      * Construct a new touchgesture_t with the given type, direction and finger
292      * count. Invalid combinations result in an invalid gesture with type NONE.
293      */
294     touchgesture_t(touch_gesture_type_t type, uint32_t direction,
295         int finger_count);
296 
297     /** @return The type of the gesture */
298     touch_gesture_type_t get_type() const;
299 
300     /** @return The finger count of the gesture, if valid. Undefined otherwise */
301     int get_finger_count() const;
302 
303     /** @return The direction of the gesture, if valid. Undefined otherwise */
304     uint32_t get_direction() const;
305 
306     /**
307      * Check whether two bindings are equal.
308      * Beware that a binding might be only partially set, i.e it might not have
309      * a direction. In this case, the direction acts as a wildcard, so the
310      * touchgesture_t matches any touchgesture_t of the same type with the same
311      * finger count
312      */
313     bool operator ==(const touchgesture_t& other) const;
314 
315   private:
316     /** Type of the gesture */
317     touch_gesture_type_t type;
318     /** Direction of the gesture */
319     uint32_t direction;
320     /** Number of fingers of the gesture */
321     int finger_count;
322 };
323 
324 namespace option_type
325 {
326 /**
327  * Construct a new touchgesture_t with the type, direction and finger count
328  * indicated in the description.
329  *
330  * Format:
331  * 1. pinch [in|out] <fingercount>
332  * 2. [edge-]swipe up|down|left|right <fingercount>
333  * 3. [edge-]swipe up-left|right-down|... <fingercount>
334  * 4. disable | none
335  */
336 template<>
337 stdx::optional<touchgesture_t> from_string(
338     const std::string& description);
339 
340 /** Represent the touch gesture as a string. */
341 template<>
342 std::string to_string(const touchgesture_t& value);
343 }
344 
345 /**
346  * The available edges of an output.
347  */
348 enum output_edge_t
349 {
350     OUTPUT_EDGE_LEFT   = (1 << 0),
351     OUTPUT_EDGE_RIGHT  = (1 << 1),
352     OUTPUT_EDGE_TOP    = (1 << 2),
353     OUTPUT_EDGE_BOTTOM = (1 << 3),
354 };
355 
356 /**
357  * Represents a binding which can be activated by moving the mouse into a
358  * corner of the screen.
359  */
360 struct hotspot_binding_t
361 {
362     /**
363      * Initialize a hotspot with the given edges.
364      *
365      * @param edges The edges of the hotspot, a bitmask of output_edge_t
366      * @param along_edge The size of the hotspot alongside the edge(s)
367      *   it is located on.
368      * @param across_edge The size of the hotspot away from the edge(s)
369      *   it is located on.
370      * @param timeout The time in milliseconds needed for the mouse to stay
371      *   in the hotspot to activate it.
372      */
373     hotspot_binding_t(uint32_t edges = 0, int32_t along_edge = 0,
374         int32_t away_from_edge = 0, int32_t timeout = 0);
375 
376     bool operator ==(const hotspot_binding_t& other) const;
377 
378     /** @return The edges this hotspot binding is on. */
379     uint32_t get_edges() const;
380 
381     /** @return The size along edges. */
382     int32_t get_size_along_edge() const;
383 
384     /** @return The size away from edges. */
385     int32_t get_size_away_from_edge() const;
386 
387     /** @return The timeout of the hotspot. */
388     int32_t get_timeout() const;
389 
390   private:
391     uint32_t edges;
392     int32_t along;
393     int32_t away;
394     int32_t timeout;
395 };
396 
397 namespace option_type
398 {
399 /**
400  * Construct a new hotspot_binding_t with the specified edges and size
401  *
402  * Format:
403  * hotspot top|...|top-left|... <along>x<away> <timeout>
404  */
405 template<>
406 stdx::optional<hotspot_binding_t> from_string(
407     const std::string& description);
408 
409 /** Represent the hotspot binding as a string. */
410 template<>
411 std::string to_string(const hotspot_binding_t& value);
412 }
413 
414 /**
415  * Represents a binding which can be activated via multiple actions -
416  * keybindings, buttonbindings, touch gestures and hotspots.
417  */
418 struct activatorbinding_t
419 {
420   public:
421     /**
422      * Initialize an empty activator binding, i.e one which cannot be activated
423      * in any way.
424      */
425     activatorbinding_t();
426     ~activatorbinding_t();
427 
428     /* Copy constructor */
429     activatorbinding_t(const activatorbinding_t& other);
430     /* Copy assignment */
431     activatorbinding_t& operator =(const activatorbinding_t& other);
432 
433     /** @return true if the activator is activated by the given keybinding. */
434     bool has_match(const keybinding_t& key) const;
435 
436     /** @return true if the activator is activated by the given buttonbinding. */
437     bool has_match(const buttonbinding_t& button) const;
438 
439     /** @return true if the activator is activated by the given gesture. */
440     bool has_match(const touchgesture_t& gesture) const;
441 
442     /**
443      * @return A list of all hotspots which activate this binding.
444      */
445     const std::vector<wf::hotspot_binding_t>& get_hotspots() const;
446 
447     /**
448      * Check equality of two activator bindings.
449      *
450      * @return true if the two activator bindings are activated by the exact
451      *  same bindings, false otherwise.
452      */
453     bool operator ==(const activatorbinding_t& other) const;
454 
455   public:
456     struct impl;
457     std::unique_ptr<impl> priv;
458 };
459 
460 namespace option_type
461 {
462 /**
463  * Create an activator string from the given string description.
464  * The string consists of valid descriptions of keybindings, buttonbindings
465  * and touch gestures, separated by a single '|' sign.
466  */
467 template<>
468 stdx::optional<activatorbinding_t> from_string(
469     const std::string& string);
470 
471 /** Represent the activator binding as a string. */
472 template<>
473 std::string to_string(const activatorbinding_t& value);
474 }
475 
476 /**
477  * Types which are related to various output options.
478  */
479 namespace output_config
480 {
481 enum mode_type_t
482 {
483     /** Output was configured in automatic mode. */
484     MODE_AUTO,
485     /** Output was configured to be turned off. */
486     MODE_OFF,
487     /** Output was configured with a given resolution. */
488     MODE_RESOLUTION,
489     /** Output was configured to be a mirror of another output. */
490     MODE_MIRROR,
491 };
492 
493 /**
494  * Represents the output mode.
495  * It contains different values depending on the source.
496  */
497 struct mode_t
498 {
499     /**
500      * Initialize an OFF or AUTO mode.
501      *
502      * @param auto_on If true, the created mode will be an AUTO mode.
503      */
504     mode_t(bool auto_on = false);
505 
506     /**
507      * Initialize the mode with source self.
508      *
509      * @param width The configured width.
510      * @param height The configured height.
511      * @param refresh The configured refresh rate, or 0 if undefined.
512      */
513     mode_t(int32_t width, int32_t height, int32_t refresh);
514 
515     /**
516      * Initialize a mirror mode.
517      */
518     mode_t(const std::string& mirror_from);
519 
520     /** @return The type of this mode. */
521     mode_type_t get_type() const;
522 
523     /** @return The configured width, if applicable. */
524     int32_t get_width() const;
525     /** @return The configured height, if applicable. */
526     int32_t get_height() const;
527     /** @return The configured refresh rate, if applicable. */
528     int32_t get_refresh() const;
529 
530     /** @return The configured mirror from output, if applicable. */
531     std::string get_mirror_from() const;
532 
533     /**
534      * Check equality of two modes.
535      *
536      * @return true if the modes have the same source types and parameters.
537      */
538     bool operator ==(const mode_t& other) const;
539 
540   private:
541     int32_t width;
542     int32_t height;
543     int32_t refresh;
544 
545     std::string mirror_from;
546 
547     mode_type_t type;
548 };
549 
550 /**
551  * Represents the output's position.
552  */
553 struct position_t
554 {
555     /** Automatically positioned output. */
556     position_t();
557 
558     /** Output positioned at a fixed position. */
559     position_t(int32_t x, int32_t y);
560 
561     /** @return The configured X coordinate. */
562     int32_t get_x() const;
563     /** @return The configured X coordinate. */
564     int32_t get_y() const;
565 
566     /** @return whether the output is automatically positioned. */
567     bool is_automatic_position() const;
568 
569     bool operator ==(const position_t& other) const;
570 
571   private:
572     int32_t x;
573     int32_t y;
574     bool automatic;
575 };
576 }
577 
578 namespace option_type
579 {
580 /**
581  * Create a mode from its string description.
582  * The supported formats are:
583  *
584  * For MODE_AUTO: auto|default
585  * For MODE_OFF: off
586  * For MODE_RESOLUTION: WxH[@RR]
587  * For MODE_MIRROR: mirror <output>
588  */
589 template<>
590 stdx::optional<output_config::mode_t> from_string(
591     const std::string& string);
592 
593 /** Represent the activator binding as a string. */
594 template<>
595 std::string to_string(const output_config::mode_t& value);
596 
597 /**
598  * Create an output position from its string description.
599  * The supported formats are:
600  *
601  * auto|default
602  * x , y
603  */
604 template<>
605 stdx::optional<output_config::position_t> from_string(
606     const std::string& string);
607 
608 /** Represent the activator binding as a string. */
609 template<>
610 std::string to_string(const output_config::position_t& value);
611 }
612 }
613