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