Apply clang-format

This commit is contained in:
Rico Tiongson 2020-04-18 04:57:17 +08:00
parent 1ecfc79fc4
commit cb51d47a60
24 changed files with 928 additions and 1098 deletions

View File

@ -1,9 +1,3 @@
<<<<<<< Updated upstream
v1.1.0
* Added mouse hold gestures
* Added `hold3` configuration
* Added `hold4` configuration
=======
v1.1.0 (2020-04-18) v1.1.0 (2020-04-18)
* Add mouse hold gestures * Add mouse hold gestures
* Add experimental `hold3` configuration * Add experimental `hold3` configuration
@ -36,4 +30,3 @@ v1.0.1
v1.0.0 v1.0.0
* Initial version * Initial version
>>>>>>> Stashed changes

View File

@ -32,7 +32,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif /* __COMFORTABLE_SWIPE__PROGRAM__ */ #endif /* __COMFORTABLE_SWIPE__PROGRAM__ */
#ifndef __COMFORTABLE_SWIPE__CONFIG__ #ifndef __COMFORTABLE_SWIPE__CONFIG__
#define __COMFORTABLE_SWIPE__CONFIG__ "/usr/local/share/comfortable-swipe/comfortable-swipe.conf" #define __COMFORTABLE_SWIPE__CONFIG__ \
"/usr/local/share/comfortable-swipe/comfortable-swipe.conf"
#endif /* __COMFORTABLE_SWIPE__CONFIG__ */ #endif /* __COMFORTABLE_SWIPE__CONFIG__ */
#ifndef COMFORTABLE_SWIPE_VERSION #ifndef COMFORTABLE_SWIPE_VERSION
@ -40,42 +41,38 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define COMFORTABLE_SWIPE_VERSION "v(UNKNOWN)" #define COMFORTABLE_SWIPE_VERSION "v(UNKNOWN)"
#endif /* COMFORTABLE_SWIPE_VERSION */ #endif /* COMFORTABLE_SWIPE_VERSION */
#include <map> // std::map #include <map> // std::map
#include <string> // std::string #include <string> // std::string
extern "C" extern "C" {
{ namespace comfortable_swipe {
namespace comfortable_swipe // driver method
{ int driver();
// driver method // this is found in the util/ folder
int driver(); namespace util {
// this is found in the util/ folder const char *autostart_filename();
namespace util constexpr const char *conf_filename();
{ std::map<std::string, std::string> read_config_file(const char *);
const char* autostart_filename(); } // namespace util
constexpr const char* conf_filename(); // this is found in the service/ folder
std::map<std::string, std::string> read_config_file(const char*); namespace service {
} void autostart();
// this is found in the service/ folder void buffer();
namespace service void config();
{ void debug();
void autostart(); void help();
void buffer(); void restart();
void config(); void start();
void debug(); void status();
void help(); void stop();
void restart(); } // namespace service
void start(); } // namespace comfortable_swipe
void status();
void stop();
}
}
} }
// add headers for classes here so it can be imported during include // add headers for classes here so it can be imported during include
#include "gesture/xdo_gesture.h"
#include "gesture/swipe_gesture.h"
#include "gesture/keyboard_swipe_gesture.h" #include "gesture/keyboard_swipe_gesture.h"
#include "gesture/mouse_hold_gesture.h" #include "gesture/mouse_hold_gesture.h"
#include "gesture/swipe_gesture.h"
#include "gesture/xdo_gesture.h"
#endif /* __COMFORTABLE_SWIPE__all_headers_hpp__ */ #endif /* __COMFORTABLE_SWIPE__all_headers_hpp__ */

View File

@ -19,74 +19,59 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstdio> // fgets_unlocked, stdin
#include <iostream> // std::ios, std::cout, std::cin
#include "all_headers.hpp" #include "all_headers.hpp"
#include <cstdio> // fgets_unlocked, stdin
#include <iostream> // std::ios, std::cout, std::cin
/** /**
* The main driver program. * The main driver program.
*/ */
namespace comfortable_swipe namespace comfortable_swipe {
{ int driver() {
int driver() // unsync for faster IO
{ std::ios::sync_with_stdio(false);
// unsync for faster IO std::cin.tie(0);
std::ios::sync_with_stdio(false); std::cout.tie(0);
std::cin.tie(0); std::cout.flush();
std::cout.tie(0);
std::cout.flush();
// read config file // read config file
auto config = comfortable_swipe::util::read_config_file( auto config = comfortable_swipe::util::read_config_file(
comfortable_swipe::util::conf_filename() comfortable_swipe::util::conf_filename());
);
// initialize mouse hold gesture handler // initialize mouse hold gesture handler
// for now, this supports 3-finger and 4-finger hold // for now, this supports 3-finger and 4-finger hold
// Examples: // Examples:
// hold3=move move mouse on 3 fingers // hold3=move move mouse on 3 fingers
// hold3=button1 hold button 1 on 3 fingers // hold3=button1 hold button 1 on 3 fingers
// hold4=button3 hold button 3 (right click) on 3 fingers // hold4=button3 hold button 3 (right click) on 3 fingers
// hold3=ignore <do nothing> // hold3=ignore <do nothing>
comfortable_swipe::gesture::mouse_hold_gesture mouse_hold comfortable_swipe::gesture::mouse_hold_gesture mouse_hold(
( config["hold3"].c_str(), config["hold4"].c_str());
config["hold3"].c_str(),
config["hold4"].c_str()
);
// initialize keyboard swipe gesture handler // initialize keyboard swipe gesture handler
comfortable_swipe::gesture::keyboard_swipe_gesture keyboard_swipe comfortable_swipe::gesture::keyboard_swipe_gesture keyboard_swipe(
( config.count("threshold") ? std::stof(config["threshold"]) : 0.0,
config.count("threshold") ? std::stof(config["threshold"]) : 0.0, config["left3"].c_str(), config["left4"].c_str(),
config["left3"].c_str(), config["right3"].c_str(), config["right4"].c_str(), config["up3"].c_str(),
config["left4"].c_str(), config["up4"].c_str(), config["down3"].c_str(), config["down4"].c_str());
config["right3"].c_str(),
config["right4"].c_str(),
config["up3"].c_str(),
config["up4"].c_str(),
config["down3"].c_str(),
config["down4"].c_str()
);
// prepare data containers // prepare data containers
std::array<char, 256> line; std::array<char, 256> line;
// start reading lines from input one by one // start reading lines from input one by one
while (fgets_unlocked(line.data(), line.size(), stdin) != NULL) while (fgets_unlocked(line.data(), line.size(), stdin) != NULL) {
{ // prioritize mouse hold gesture first
// prioritize mouse hold gesture first mouse_hold.parse_line(line.data());
mouse_hold.parse_line(line.data());
// if mouse hold fails, try keyboard hold // if mouse hold fails, try keyboard hold
if (!mouse_hold.is_mousedown()) if (!mouse_hold.is_mousedown()) {
{ // attempt to parse keyboard gestures
// attempt to parse keyboard gestures keyboard_swipe.parse_line(line.data());
keyboard_swipe.parse_line(line.data());
}
}
return 0;
} }
}
return 0;
} }
} // namespace comfortable_swipe
#endif /* __COMFORTABLE_SWIPE__driver__ */ #endif /* __COMFORTABLE_SWIPE__driver__ */

View File

@ -19,177 +19,150 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <iostream> // std::cout, std::endl
#include "keyboard_swipe_gesture.h" #include "keyboard_swipe_gesture.h"
#include <iostream> // std::cout, std::endl
extern "C" extern "C" {
{ #include <xdo.h> // xdo, xdo_new, xdo_free,
#include <xdo.h> // xdo, xdo_new, xdo_free, // xdo_get_mouse_location
// xdo_get_mouse_location // CURRENT_WINDOW
// CURRENT_WINDOW
} }
namespace comfortable_swipe::gesture namespace comfortable_swipe::gesture {
{
/* STATICS DEFINITIONS */ /* STATICS DEFINITIONS */
const int keyboard_swipe_gesture::MSK_THREE_FINGERS = 0; const int keyboard_swipe_gesture::MSK_THREE_FINGERS = 0;
const int keyboard_swipe_gesture::MSK_FOUR_FINGERS = 1; const int keyboard_swipe_gesture::MSK_FOUR_FINGERS = 1;
const int keyboard_swipe_gesture::MSK_NEGATIVE = 0; const int keyboard_swipe_gesture::MSK_NEGATIVE = 0;
const int keyboard_swipe_gesture::MSK_POSITIVE = 2; const int keyboard_swipe_gesture::MSK_POSITIVE = 2;
const int keyboard_swipe_gesture::MSK_HORIZONTAL = 0; const int keyboard_swipe_gesture::MSK_HORIZONTAL = 0;
const int keyboard_swipe_gesture::MSK_VERTICAL = 4; const int keyboard_swipe_gesture::MSK_VERTICAL = 4;
const int keyboard_swipe_gesture::FRESH = -1; const int keyboard_swipe_gesture::FRESH = -1;
const char * const keyboard_swipe_gesture::command_map[8] = { const char *const keyboard_swipe_gesture::command_map[8] = {
"left3", "left3", "left4", "right3", "right4", "up3", "up4", "down3", "down4"};
"left4",
"right3",
"right4",
"up3",
"up4",
"down3",
"down4"
};
/** /**
* Constructs a new keyboard-based swipe gesture, given configurations * Constructs a new keyboard-based swipe gesture, given configurations
* for certain swipe events. Here, we construct our definition based on * for certain swipe events. Here, we construct our definition based on
* the four directions (left, up, right, down) for 3-finger and 4-finger * the four directions (left, up, right, down) for 3-finger and 4-finger
* swipes. Note that the direction is based on the Australian natural * swipes. Note that the direction is based on the Australian natural
* scrolling direction (ie. left3 is natural movement of 3 fingers left). * scrolling direction (ie. left3 is natural movement of 3 fingers left).
*/ */
keyboard_swipe_gesture::keyboard_swipe_gesture keyboard_swipe_gesture::keyboard_swipe_gesture(
( const float threshold, const char *left3 /* 000 */,
const float threshold, const char *left4 /* 001 */, const char *right3 /* 010 */,
const char* left3 /* 000 */, const char *right4 /* 011 */, const char *up3 /* 100 */,
const char* left4 /* 001 */, const char *up4 /* 101 */, const char *down3 /* 110 */,
const char* right3 /* 010 */, const char *down4 /* 111 */
const char* right4 /* 011 */, )
const char* up3 /* 100 */, : // construct superclass
const char* up4 /* 101 */, comfortable_swipe::gesture::swipe_gesture(),
const char* down3 /* 110 */, // compute square of threshold because we will use squared distances
const char* down4 /* 111 */ threshold_squared(threshold * threshold),
): // register our commands
// construct superclass commands(new const char *[8] {
comfortable_swipe::gesture::swipe_gesture(), left3, left4, right3, right4, up3, up4, down3, down4
// compute square of threshold because we will use squared distances }) {}
threshold_squared(threshold*threshold),
// register our commands
commands(new const char*[8]{
left3, left4, right3, right4, up3, up4, down3, down4
})
{ }
/** /**
* Destructs this keyboard swipe gesture. * Destructs this keyboard swipe gesture.
*/ */
keyboard_swipe_gesture::~keyboard_swipe_gesture() keyboard_swipe_gesture::~keyboard_swipe_gesture() { delete[] commands; }
{
delete[] commands;
}
/** /**
* Hook on begin of swipe gesture. * Hook on begin of swipe gesture.
*/ */
void keyboard_swipe_gesture::begin() void keyboard_swipe_gesture::begin() {
{ // call superclass method
// call superclass method swipe_gesture::begin();
swipe_gesture::begin();
// assign previous gesture to FRESH
this->previous_gesture = keyboard_swipe_gesture::FRESH;
}
/**
* Hook on update of swipe gesture.
*/
void keyboard_swipe_gesture::update()
{
// call superclass method
swipe_gesture::update();
// scale threshold to 1/10 when gesture is not fresh
float scale =
this->previous_gesture == keyboard_swipe_gesture::FRESH
? 1.00f
: 0.01f; // square root of 1/10
// we are working with floating points which are not exact
// make sure we compare with a very small value (epsilon)
static const float EPSILON = 1e-6f;
const float distance_squared = this->x * this->x + this->y * this->y;
const float beyond_threshold = this->threshold_squared * scale;
// apply if strictly beyond threshold
if (distance_squared > beyond_threshold + EPSILON)
{
// we parse our mask based on the values obtained from the regex
int mask = 0;
if (this->fingers == 3)
mask |= keyboard_swipe_gesture::MSK_THREE_FINGERS;
else if (this->fingers == 4)
mask |= keyboard_swipe_gesture::MSK_FOUR_FINGERS;
const float absx = x >= 0 ? x : -x;
const float absy = y >= 0 ? y : -y;
if (absx > absy)
{
// gesture is horizontal
mask |= keyboard_swipe_gesture::MSK_HORIZONTAL;
if (x < 0)
mask |= keyboard_swipe_gesture::MSK_NEGATIVE;
else
mask |= keyboard_swipe_gesture::MSK_POSITIVE;
}
else /* std::abs(x) <= std::abs(y) */
{
// gesture is vertical
mask |= keyboard_swipe_gesture::MSK_VERTICAL;
if (y < 0)
mask |= keyboard_swipe_gesture::MSK_NEGATIVE;
else
mask |= keyboard_swipe_gesture::MSK_POSITIVE;
}
// send command on fresh OR opposite gesture
if (this->previous_gesture == keyboard_swipe_gesture::FRESH
|| this->previous_gesture == (mask ^ keyboard_swipe_gesture::MSK_POSITIVE))
{
this->do_keyboard_gesture(mask);
}
}
}
/**
* Apply the update given a mask.
*/
void keyboard_swipe_gesture::do_keyboard_gesture(int mask)
{
// perform our keyboard command with xdo_send_keysequence
const char * command = keyboard_swipe_gesture::commands[mask];
xdo_send_keysequence_window(this->xdo, CURRENTWINDOW, command, 0);
// reset our location variables
this->x = this->y = 0;
this->previous_gesture = mask;
// log our command name in stdout
const char * command_name = keyboard_swipe_gesture::command_map[mask];
std::cout << "SWIPE " << command_name << std::endl;
}
/**
* Hook on end of swipe gesture.
*/
void keyboard_swipe_gesture::end()
{
// call superclass method
swipe_gesture::end();
}
// assign previous gesture to FRESH
this->previous_gesture = keyboard_swipe_gesture::FRESH;
} }
/**
* Hook on update of swipe gesture.
*/
void keyboard_swipe_gesture::update() {
// call superclass method
swipe_gesture::update();
// scale threshold to 1/10 when gesture is not fresh
float scale = this->previous_gesture == keyboard_swipe_gesture::FRESH
? 1.00f
: 0.01f; // square root of 1/10
// we are working with floating points which are not exact
// make sure we compare with a very small value (epsilon)
static const float EPSILON = 1e-6f;
const float distance_squared = this->x * this->x + this->y * this->y;
const float beyond_threshold = this->threshold_squared * scale;
// apply if strictly beyond threshold
if (distance_squared > beyond_threshold + EPSILON) {
// we parse our mask based on the values obtained from the regex
int mask = 0;
if (this->fingers == 3)
mask |= keyboard_swipe_gesture::MSK_THREE_FINGERS;
else if (this->fingers == 4)
mask |= keyboard_swipe_gesture::MSK_FOUR_FINGERS;
const float absx = x >= 0 ? x : -x;
const float absy = y >= 0 ? y : -y;
if (absx > absy) {
// gesture is horizontal
mask |= keyboard_swipe_gesture::MSK_HORIZONTAL;
if (x < 0)
mask |= keyboard_swipe_gesture::MSK_NEGATIVE;
else
mask |= keyboard_swipe_gesture::MSK_POSITIVE;
} else /* std::abs(x) <= std::abs(y) */
{
// gesture is vertical
mask |= keyboard_swipe_gesture::MSK_VERTICAL;
if (y < 0)
mask |= keyboard_swipe_gesture::MSK_NEGATIVE;
else
mask |= keyboard_swipe_gesture::MSK_POSITIVE;
}
// send command on fresh OR opposite gesture
if (this->previous_gesture == keyboard_swipe_gesture::FRESH ||
this->previous_gesture ==
(mask ^ keyboard_swipe_gesture::MSK_POSITIVE)) {
this->do_keyboard_gesture(mask);
}
}
}
/**
* Apply the update given a mask.
*/
void keyboard_swipe_gesture::do_keyboard_gesture(int mask) {
// perform our keyboard command with xdo_send_keysequence
const char *command = keyboard_swipe_gesture::commands[mask];
xdo_send_keysequence_window(this->xdo, CURRENTWINDOW, command, 0);
// reset our location variables
this->x = this->y = 0;
this->previous_gesture = mask;
// log our command name in stdout
const char *command_name = keyboard_swipe_gesture::command_map[mask];
std::cout << "SWIPE " << command_name << std::endl;
}
/**
* Hook on end of swipe gesture.
*/
void keyboard_swipe_gesture::end() {
// call superclass method
swipe_gesture::end();
}
} // namespace comfortable_swipe::gesture
#endif /* __COMFORTABLE_SWIPE__gesture_keyboard_swipe_gesture__ */ #endif /* __COMFORTABLE_SWIPE__gesture_keyboard_swipe_gesture__ */

View File

@ -19,204 +19,162 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <iostream> // std::cout, std::endl
#include <cstdio> // std::sscanf
#include <cstring> // strncmp
#include "mouse_hold_gesture.h" #include "mouse_hold_gesture.h"
#include <cstdio> // std::sscanf
#include <cstring> // strncmp
#include <iostream> // std::cout, std::endl
extern "C" extern "C" {
{ #include <xdo.h> // xdo, xdo_new, xdo_free,
#include <xdo.h> // xdo, xdo_new, xdo_free, // xdo_get_mouse_location
// xdo_get_mouse_location // CURRENT_WINDOW
// CURRENT_WINDOW
} }
namespace comfortable_swipe::gesture namespace comfortable_swipe::gesture {
{ enum {
enum { MOUSE_NONE = -1,
MOUSE_NONE = -1, MOUSE_MOVE = 0,
MOUSE_MOVE = 0, MOUSE_LEFT_CLICK = 1,
MOUSE_LEFT_CLICK = 1, MOUSE_MIDDLE_CLICK = 2,
MOUSE_MIDDLE_CLICK = 2, MOUSE_RIGHT_CLICK = 3,
MOUSE_RIGHT_CLICK = 3, MOUSE_WHEEL_UP = 4,
MOUSE_WHEEL_UP = 4, MOUSE_WHEEL_DOWN = 5,
MOUSE_WHEEL_DOWN = 5, MOUSE_SCROLL = 6,
MOUSE_SCROLL = 6, MOUSE_SCROLL_REVERSE = 7
MOUSE_SCROLL_REVERSE = 7 };
};
/** /**
* Constructs a new mouse gesture, given "hold3" and "hold4" configurations. * Constructs a new mouse gesture, given "hold3" and "hold4" configurations.
*/ */
mouse_hold_gesture::mouse_hold_gesture mouse_hold_gesture::mouse_hold_gesture(const char *hold3, const char *hold4)
( : comfortable_swipe::gesture::swipe_gesture(), button(MOUSE_NONE),
const char* hold3, hold3(hold3), hold4(hold4), flag_mousedown(false) {}
const char* hold4
):
comfortable_swipe::gesture::swipe_gesture(),
button(MOUSE_NONE),
hold3(hold3),
hold4(hold4),
flag_mousedown(false)
{ }
/** /**
* Destructs this mouse swipe gesture. * Destructs this mouse swipe gesture.
*/ */
mouse_hold_gesture::~mouse_hold_gesture() mouse_hold_gesture::~mouse_hold_gesture() {}
{ }
/** /**
* Run mousedown command on hold input. * Run mousedown command on hold input.
*/ */
void mouse_hold_gesture::do_mousedown(const char * mouseinput) void mouse_hold_gesture::do_mousedown(const char *mouseinput) {
{ const int button = this->button = this->parse_mouse_button(mouseinput);
const int button = this->button = this->parse_mouse_button(mouseinput); if (button != MOUSE_NONE) {
if (button != MOUSE_NONE) // eg. MOUSE DOWN hold3 mouse1
{ std::printf("MOUSE DOWN hold%d %s\n", this->fingers, mouseinput);
// eg. MOUSE DOWN hold3 mouse1 if (MOUSE_LEFT_CLICK <= button && button <= MOUSE_RIGHT_CLICK) {
std::printf("MOUSE DOWN hold%d %s\n", this->fingers, mouseinput); // send mouse down on associated button
if (MOUSE_LEFT_CLICK <= button && button <= MOUSE_RIGHT_CLICK) xdo_mouse_down(this->xdo, CURRENTWINDOW, button);
{
// send mouse down on associated button
xdo_mouse_down(this->xdo, CURRENTWINDOW, button);
}
this->flag_mousedown = true;
}
}
/**
* Run mouseup command on hold output.
*/
void mouse_hold_gesture::do_mouseup(const char * mouseinput)
{
const int button = this->button = this->parse_mouse_button(mouseinput);
if (button != MOUSE_NONE)
{
std::printf("MOUSE UP hold%d %s\n", this->fingers, mouseinput);
if (MOUSE_LEFT_CLICK <= button && button <= MOUSE_RIGHT_CLICK)
{
// send mouse up on associated button
xdo_mouse_up(this->xdo, CURRENTWINDOW, button);
}
this->flag_mousedown = false;
}
}
/**
* Utility method to parse mouse number from input.
* Returns -1 on failure.
*/
int mouse_hold_gesture::parse_mouse_button(const char * input) const
{
// just move without holding button down
if (std::strcmp(input, "move") == 0)
return MOUSE_MOVE;
if (std::strcmp(input, "scroll") == 0)
return MOUSE_SCROLL;
if (std::strcmp(input, "scroll_reverse") == 0)
return MOUSE_SCROLL_REVERSE;
// get button number
int button;
if (std::sscanf(input, "button%d", &button) == 1)
{
if (1 <= button && button <= 6)
{
return button;
}
}
return MOUSE_NONE;
}
/**
* Hook on begin of mouse swipe gesture.
*/
void mouse_hold_gesture::begin()
{
// call superclass method
swipe_gesture::begin();
// dispatch mouse down event
if (this->fingers == 3)
{
this->do_mousedown(this->hold3);
}
else if (this->fingers == 4)
{
this->do_mousedown(this->hold4);
}
}
/**
* Hook on end of mouse swipe gesture.
*/
void mouse_hold_gesture::update()
{
// call superclass method
swipe_gesture::update();
if (this->is_mousedown())
{
if (0 <= this->button && this->button <= 3)
{
// drag mouse with pointer during update
xdo_move_mouse_relative(
this->xdo,
this->udx,
this->udy
);
}
else if (this->button == MOUSE_SCROLL || this->button == MOUSE_SCROLL_REVERSE)
{
// perform naive scroll depending on vertical direction
int wheel = MOUSE_WHEEL_DOWN;
if ((this->udy > 0) == (this->button == MOUSE_SCROLL))
wheel = MOUSE_WHEEL_UP;
// click wheel on update (note: this is not precise)
xdo_mouse_down(this->xdo, CURRENTWINDOW, wheel);
xdo_mouse_up(this->xdo, CURRENTWINDOW, wheel);
}
else if (this->button == MOUSE_WHEEL_UP || this->button == MOUSE_WHEEL_DOWN)
{
// click wheel button on 4 or 5
xdo_mouse_down(this->xdo, CURRENTWINDOW, this->button);
xdo_mouse_up(this->xdo, CURRENTWINDOW, this->button);
}
}
}
/**
* Hook on end of swipe gesture.
*/
void mouse_hold_gesture::end()
{
if (this->is_mousedown())
{
if (this->fingers == 3)
{
this->do_mouseup(this->hold3);
}
else if (this->fingers == 4)
{
this->do_mouseup(this->hold4);
}
}
// call superclass method
swipe_gesture::end();
}
/**
* Utility method to check if mouse is current held.
*/
bool mouse_hold_gesture::is_mousedown() const
{
return this->flag_mousedown;
} }
this->flag_mousedown = true;
}
} }
/**
* Run mouseup command on hold output.
*/
void mouse_hold_gesture::do_mouseup(const char *mouseinput) {
const int button = this->button = this->parse_mouse_button(mouseinput);
if (button != MOUSE_NONE) {
std::printf("MOUSE UP hold%d %s\n", this->fingers, mouseinput);
if (MOUSE_LEFT_CLICK <= button && button <= MOUSE_RIGHT_CLICK) {
// send mouse up on associated button
xdo_mouse_up(this->xdo, CURRENTWINDOW, button);
}
this->flag_mousedown = false;
}
}
/**
* Utility method to parse mouse number from input.
* Returns -1 on failure.
*/
int mouse_hold_gesture::parse_mouse_button(const char *input) const {
// just move without holding button down
if (std::strcmp(input, "move") == 0)
return MOUSE_MOVE;
if (std::strcmp(input, "scroll") == 0)
return MOUSE_SCROLL;
if (std::strcmp(input, "scroll_reverse") == 0)
return MOUSE_SCROLL_REVERSE;
// get button number
int button;
if (std::sscanf(input, "button%d", &button) == 1) {
if (1 <= button && button <= 6) {
return button;
}
}
return MOUSE_NONE;
}
/**
* Hook on begin of mouse swipe gesture.
*/
void mouse_hold_gesture::begin() {
// call superclass method
swipe_gesture::begin();
// dispatch mouse down event
if (this->fingers == 3) {
this->do_mousedown(this->hold3);
} else if (this->fingers == 4) {
this->do_mousedown(this->hold4);
}
}
/**
* Hook on end of mouse swipe gesture.
*/
void mouse_hold_gesture::update() {
// call superclass method
swipe_gesture::update();
if (this->is_mousedown()) {
if (0 <= this->button && this->button <= 3) {
// drag mouse with pointer during update
xdo_move_mouse_relative(this->xdo, this->udx, this->udy);
} else if (this->button == MOUSE_SCROLL ||
this->button == MOUSE_SCROLL_REVERSE) {
// perform naive scroll depending on vertical direction
int wheel = MOUSE_WHEEL_DOWN;
if ((this->udy > 0) == (this->button == MOUSE_SCROLL))
wheel = MOUSE_WHEEL_UP;
// click wheel on update (note: this is not precise)
xdo_mouse_down(this->xdo, CURRENTWINDOW, wheel);
xdo_mouse_up(this->xdo, CURRENTWINDOW, wheel);
} else if (this->button == MOUSE_WHEEL_UP ||
this->button == MOUSE_WHEEL_DOWN) {
// click wheel button on 4 or 5
xdo_mouse_down(this->xdo, CURRENTWINDOW, this->button);
xdo_mouse_up(this->xdo, CURRENTWINDOW, this->button);
}
}
}
/**
* Hook on end of swipe gesture.
*/
void mouse_hold_gesture::end() {
if (this->is_mousedown()) {
if (this->fingers == 3) {
this->do_mouseup(this->hold3);
} else if (this->fingers == 4) {
this->do_mouseup(this->hold4);
}
}
// call superclass method
swipe_gesture::end();
}
/**
* Utility method to check if mouse is current held.
*/
bool mouse_hold_gesture::is_mousedown() const { return this->flag_mousedown; }
} // namespace comfortable_swipe::gesture
#endif /* __COMFORTABLE_SWIPE__gesture_mouse_hold_gesture__ */ #endif /* __COMFORTABLE_SWIPE__gesture_mouse_hold_gesture__ */

View File

@ -19,131 +19,113 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <iostream> // std::cout, std::endl
#include <string> // std::stoi, std::stof
#include <regex> // std::regex, std::regex_match, std::cmatch
#include "swipe_gesture.h" #include "swipe_gesture.h"
#include <iostream> // std::cout, std::endl
#include <regex> // std::regex, std::regex_match, std::cmatch
#include <string> // std::stoi, std::stof
extern "C" extern "C" {
{ #include <xdo.h> // xdo, xdo_new, xdo_free,
#include <xdo.h> // xdo, xdo_new, xdo_free, // xdo_get_mouse_location
// xdo_get_mouse_location // CURRENT_WINDOW
// CURRENT_WINDOW
} }
namespace comfortable_swipe::gesture namespace comfortable_swipe::gesture {
{ /**
/** * Constructs a new fresh swipe gesture container.
* Constructs a new fresh swipe gesture container. */
*/ swipe_gesture::swipe_gesture()
swipe_gesture::swipe_gesture : // construct our superclass
(): comfortable_swipe::gesture::xdo_gesture(), flag_swiping(false) {
// construct our superclass // improve responsiveness of first gesture by pre-empting xdotool
comfortable_swipe::gesture::xdo_gesture(), xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num);
flag_swiping(false)
{
// improve responsiveness of first gesture by pre-empting xdotool
xdo_get_mouse_location(this->xdo, &this->ix, &this->iy,
&this->screen_num);
}
/**
* Destructs this swipe gesture.
*/
swipe_gesture::~swipe_gesture()
{ }
/**
* Hook on begin of swipe gesture (you can override this).
*/
void swipe_gesture::begin()
{
// save current screen location for gestured mouse movement
xdo_get_mouse_location(this->xdo, &this->ix, &this->iy,
&this->screen_num);
this->x = 0;
this->y = 0;
this->ux = 0;
this->uy = 0;
}
/**
* Hook on update of swipe gesture (you can override this).
*/
void swipe_gesture::update()
{
this->x += this->dx;
this->y += this->dy;
this->ux += this->udx;
this->uy += this->udy;
}
/**
* Hook on end of swipe gesture (you can override this).
*/
void swipe_gesture::end()
{ }
/**
* Dispatches begin/update/end depending on the regex pattern provided by this class.
*
* @param line the line from libinput debug-events to parse
* @return true if begin/update/end was dispatched
*/
bool swipe_gesture::parse_line(const char * line)
{
// prepare regex matchers statically (will only load at most once)
static const std::regex
gesture_swipe_begin(swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN),
gesture_swipe_update(swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN),
gesture_swipe_end(swipe_gesture::GESTURE_END_REGEX_PATTERN);
// prepare holder for regex matches
static std::cmatch matches;
if (this->flag_swiping)
{
// currently swiping
if (std::regex_match(line, matches, gesture_swipe_update) != 0)
{
// assign necessary variables for swipe update
this->fingers = std::stoi(matches[1]);
this->dx = std::stof(matches[2]);
this->dy = std::stof(matches[3]);
this->udx = std::stof(matches[4]);
this->udy = std::stof(matches[5]);
// dispatch update
this->update();
return true;
}
else if (std::regex_match(line, matches, gesture_swipe_end) != 0)
{
// assign necessary variables for swipe end
this->flag_swiping = false;
this->fingers = std::stoi(matches[1]);
// dispatch end
this->end();
return true;
}
}
else
{
// not swiping, check if swipe will begin
if (std::regex_match(line, matches, gesture_swipe_begin) != 0
|| std::regex_match(line, matches, gesture_swipe_update) != 0)
{
// assign necessary variables for swipe begin
this->flag_swiping = true;
this->fingers = std::stoi(matches[1]);
// dispatch begin
this->begin();
return true;
}
}
return false;
}
} }
/**
* Destructs this swipe gesture.
*/
swipe_gesture::~swipe_gesture() {}
/**
* Hook on begin of swipe gesture (you can override this).
*/
void swipe_gesture::begin() {
// save current screen location for gestured mouse movement
xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num);
this->x = 0;
this->y = 0;
this->ux = 0;
this->uy = 0;
}
/**
* Hook on update of swipe gesture (you can override this).
*/
void swipe_gesture::update() {
this->x += this->dx;
this->y += this->dy;
this->ux += this->udx;
this->uy += this->udy;
}
/**
* Hook on end of swipe gesture (you can override this).
*/
void swipe_gesture::end() {}
/**
* Dispatches begin/update/end depending on the regex pattern provided by this
* class.
*
* @param line the line from libinput debug-events to parse
* @return true if begin/update/end was dispatched
*/
bool swipe_gesture::parse_line(const char *line) {
// prepare regex matchers statically (will only load at most once)
static const std::regex gesture_swipe_begin(
swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN),
gesture_swipe_update(swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN),
gesture_swipe_end(swipe_gesture::GESTURE_END_REGEX_PATTERN);
// prepare holder for regex matches
static std::cmatch matches;
if (this->flag_swiping) {
// currently swiping
if (std::regex_match(line, matches, gesture_swipe_update) != 0) {
// assign necessary variables for swipe update
this->fingers = std::stoi(matches[1]);
this->dx = std::stof(matches[2]);
this->dy = std::stof(matches[3]);
this->udx = std::stof(matches[4]);
this->udy = std::stof(matches[5]);
// dispatch update
this->update();
return true;
} else if (std::regex_match(line, matches, gesture_swipe_end) != 0) {
// assign necessary variables for swipe end
this->flag_swiping = false;
this->fingers = std::stoi(matches[1]);
// dispatch end
this->end();
return true;
}
} else {
// not swiping, check if swipe will begin
if (std::regex_match(line, matches, gesture_swipe_begin) != 0 ||
std::regex_match(line, matches, gesture_swipe_update) != 0) {
// assign necessary variables for swipe begin
this->flag_swiping = true;
this->fingers = std::stoi(matches[1]);
// dispatch begin
this->begin();
return true;
}
}
return false;
}
} // namespace comfortable_swipe::gesture
#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture__ */ #endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture__ */

View File

@ -21,71 +21,71 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "swipe_gesture.h" #include "swipe_gesture.h"
namespace comfortable_swipe::gesture namespace comfortable_swipe::gesture {
{ /**
/** * Regex pattern for the libinput entry for start of swipe.
* Regex pattern for the libinput entry for start of swipe. * Extracts one match for the number of fingers used during the swipe.
* Extracts one match for the number of fingers used during the swipe. *
* * eg. event15 GESTURE_SWIPE_BEGIN +34.33s 3
* eg. event15 GESTURE_SWIPE_BEGIN +34.33s 3 * ^
* ^ * fingers
* fingers */
*/ const char *swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN =
const char* swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN = "^" // start of string
"^" // start of string "[ -]event\\d+" // event
"[ -]event\\d+" // event "\\s+GESTURE_SWIPE_BEGIN" // gesture
"\\s+GESTURE_SWIPE_BEGIN" // gesture "\\s+\\S+" // timestamp
"\\s+\\S+" // timestamp "\\s+(\\d+)" // fingers
"\\s+(\\d+)" // fingers "\\s*$" // end of string
"\\s*$" // end of string
; ;
/** /**
* Regex pattern for the libinput entry for the end of swipe. * Regex pattern for the libinput entry for the end of swipe.
* Extracts one match for the number of fingers used during the swipe. * Extracts one match for the number of fingers used during the swipe.
* *
* eg. event15 GESTURE_SWIPE_END +35.03s 3 * eg. event15 GESTURE_SWIPE_END +35.03s 3
* ^ * ^
* fingers * fingers
*/ */
const char* swipe_gesture::GESTURE_END_REGEX_PATTERN = const char *swipe_gesture::GESTURE_END_REGEX_PATTERN =
"^" // start of string "^" // start of string
"[ -]event\\d+" // event "[ -]event\\d+" // event
"\\s+GESTURE_SWIPE_END" // gesture "\\s+GESTURE_SWIPE_END" // gesture
"\\s+\\S+" // timestamp "\\s+\\S+" // timestamp
"\\s+(\\d+)" // fingers "\\s+(\\d+)" // fingers
"\\s*$" // end of string "\\s*$" // end of string
; ;
// matches signed decimal numbers (eg. "6.02" "-1.1") // matches signed decimal numbers (eg. "6.02" "-1.1")
#define CF_NUMBER_REGEX "-?\\d+(?:\\.\\d+)" #define CF_NUMBER_REGEX "-?\\d+(?:\\.\\d+)"
// matches and extracts a space-prefixed signed fraction (eg. "-3.00/ 5.12") // matches and extracts a space-prefixed signed fraction (eg. "-3.00/ 5.12")
#define CF_NUMBER_DIVISION "\\s*(" CF_NUMBER_REGEX ")/\\s*(" CF_NUMBER_REGEX ")" #define CF_NUMBER_DIVISION "\\s*(" CF_NUMBER_REGEX ")/\\s*(" CF_NUMBER_REGEX ")"
/** /**
* Regex pattern for the libinput entry for during a swipe. * Regex pattern for the libinput entry for during a swipe.
* Extracts number of fingers used and the speed (normal and accelerated) of the swipe. * Extracts number of fingers used and the speed (normal and accelerated) of the
* * swipe.
* eg. event15 GESTURE_SWIPE_UPDATE +34.70s 3 -0.12/ 4.99 (-0.33/13.50 unaccelerated) *
* ^ ^ ^ ^ ^ * eg. event15 GESTURE_SWIPE_UPDATE +34.70s 3 -0.12/ 4.99 (-0.33/13.50
* fingers dx dy udx udy * unaccelerated) ^ ^ ^ ^ ^ fingers dx dy udx udy
*/ */
const char* swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN = const char *swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN =
"^" // start of string "^" // start of string
"[ -]event\\d+" // event "[ -]event\\d+" // event
"\\s+GESTURE_SWIPE_UPDATE" // gesture "\\s+GESTURE_SWIPE_UPDATE" // gesture
"\\s+\\S+" // timestamp "\\s+\\S+" // timestamp
"\\s+(\\d+)" // fingers "\\s+(\\d+)" // fingers
"\\s+" CF_NUMBER_DIVISION // speed (dx/dy) "\\s+" CF_NUMBER_DIVISION // speed (dx/dy)
"\\s+\\(" CF_NUMBER_DIVISION "\\s+unaccelerated\\)" // unaccelerated speed (udx/udy) "\\s+\\(" CF_NUMBER_DIVISION
"\\s*$" // end of string "\\s+unaccelerated\\)" // unaccelerated speed (udx/udy)
"\\s*$" // end of string
; ;
// delete macros // delete macros
#undef CF_NUMBER_DIVISION #undef CF_NUMBER_DIVISION
#undef CF_NUMBER_EXTRACT #undef CF_NUMBER_EXTRACT
#undef CF_NUMBER_REGEX #undef CF_NUMBER_REGEX
} } // namespace comfortable_swipe::gesture
#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_regex__ */ #endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_regex__ */

View File

@ -19,29 +19,22 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
extern "C" extern "C" {
{ #include <xdo.h> // xdo, xdo_new
#include <xdo.h> // xdo, xdo_new
} }
#include "xdo_gesture.h" #include "xdo_gesture.h"
namespace comfortable_swipe::gesture namespace comfortable_swipe::gesture {
{ /**
/** * Constructs a new gesture handler with xdo.
* Constructs a new gesture handler with xdo. */
*/ xdo_gesture::xdo_gesture() : xdo(xdo_new(NULL)) {}
xdo_gesture::xdo_gesture():
xdo(xdo_new(NULL))
{ }
/** /**
* Constructs a new swipe gesture with xdo. * Constructs a new swipe gesture with xdo.
*/ */
xdo_gesture::~xdo_gesture() xdo_gesture::~xdo_gesture() { xdo_free(this->xdo); }
{ } // namespace comfortable_swipe::gesture
xdo_free(this->xdo);
}
}
#endif /* __COMFORTABLE_SWIPE__xdo_gesture__ */ #endif /* __COMFORTABLE_SWIPE__xdo_gesture__ */

View File

@ -25,11 +25,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* Add all cpp files below to be ready for export. * Add all cpp files below to be ready for export.
*/ */
#include "gesture/xdo_gesture.cpp" #include "driver.cpp"
#include "gesture/swipe_gesture.cpp"
#include "gesture/swipe_gesture.regex.cpp"
#include "gesture/keyboard_swipe_gesture.cpp" #include "gesture/keyboard_swipe_gesture.cpp"
#include "gesture/mouse_hold_gesture.cpp" #include "gesture/mouse_hold_gesture.cpp"
#include "gesture/swipe_gesture.cpp"
#include "gesture/swipe_gesture.regex.cpp"
#include "gesture/xdo_gesture.cpp"
#include "service/autostart.cpp" #include "service/autostart.cpp"
#include "service/buffer.cpp" #include "service/buffer.cpp"
#include "service/config.cpp" #include "service/config.cpp"
@ -42,6 +43,5 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "util/autostart_filename.cpp" #include "util/autostart_filename.cpp"
#include "util/conf_filename.cpp" #include "util/conf_filename.cpp"
#include "util/read_config_file.cpp" #include "util/read_config_file.cpp"
#include "driver.cpp"
#endif /* __COMFORTABLE_SWIPE__ */ #endif /* __COMFORTABLE_SWIPE__ */

View File

@ -19,57 +19,48 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <iostream> // std::cerr, std::cout, std::endl
#include <fstream> // std::ifstream, std::ofstream
#include <string> // std::string
#include <cstdio> // std::remove
#include <cstdlib> // std::system
#include "../all_headers.hpp" #include "../all_headers.hpp"
#include <cstdio> // std::remove
#include <cstdlib> // std::system
#include <fstream> // std::ifstream, std::ofstream
#include <iostream> // std::cerr, std::cout, std::endl
#include <string> // std::string
namespace comfortable_swipe::service namespace comfortable_swipe::service {
{ /**
/** * Toggles automatic startup of comfortable swipe.
* Toggles automatic startup of comfortable swipe. */
*/ void autostart() {
void autostart() using comfortable_swipe::util::autostart_filename;
{
using comfortable_swipe::util::autostart_filename;
const std::string& path = autostart_filename(); const std::string &path = autostart_filename();
if (std::ifstream(path.data()).good()) if (std::ifstream(path.data()).good()) {
{ // file found, delete it
// file found, delete it if (std::remove(path.data()) != 0)
if (std::remove(path.data()) != 0) std::cerr << "Error: failed to switch off autostart. "
std::cerr << "Error: failed to switch off autostart. " << "Maybe the autostart file is in use?" << std::endl;
<< "Maybe the autostart file is in use?" else
<< std::endl; std::cout << "Autostart switched off" << std::endl;
else } else {
std::cout << "Autostart switched off" << std::endl; // file not found, create it
} int result = std::system(("mkdir -p $(dirname " + path + ")").data());
else { std::ofstream fout(path.data());
// file not found, create it if (result != 0 || !fout.good())
int result = std::system(("mkdir -p $(dirname " + path + ")").data()); std::cerr << "Error: failed to switch on autostart. "
std::ofstream fout(path.data()); << "Are you sure you have the permissions?" << std::endl;
if (result != 0 || !fout.good()) else {
std::cerr << "Error: failed to switch on autostart. " fout << "[Desktop Entry]\n"
<< "Are you sure you have the permissions?" "Type=Application\n"
<< std::endl; "Exec=bash -c \"" __COMFORTABLE_SWIPE__PROGRAM__ " start\"\n"
else { "Hidden=false\n"
fout << "NoDisplay=false\n"
"[Desktop Entry]\n" "X-GNOME-Autostart-enabled=true\n"
"Type=Application\n" "Name=Comfortable Swipe\n"
"Exec=bash -c \"" "Comment=3 or 4 touchpad gestures\n";
__COMFORTABLE_SWIPE__PROGRAM__ std::cout << "Autostart switched on" << std::endl;
" start\"\n"
"Hidden=false\n"
"NoDisplay=false\n"
"X-GNOME-Autostart-enabled=true\n"
"Name=Comfortable Swipe\n"
"Comment=3 or 4 touchpad gestures\n";
std::cout << "Autostart switched on" << std::endl;
}
}
} }
}
} }
} // namespace comfortable_swipe::service
#endif /* __COMFORTABLE_SWIPE__service_autostart__ */ #endif /* __COMFORTABLE_SWIPE__service_autostart__ */

View File

@ -19,18 +19,14 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstdlib> // std::exit
#include "../all_headers.hpp" #include "../all_headers.hpp"
#include <cstdlib> // std::exit
/** /**
* Starts the comfortable-swipe service by buffering libinput debug-events. * Starts the comfortable-swipe service by buffering libinput debug-events.
*/ */
namespace comfortable_swipe::service namespace comfortable_swipe::service {
{ void buffer() { std::exit(comfortable_swipe::driver()); }
void buffer() } // namespace comfortable_swipe::service
{
std::exit(comfortable_swipe::driver());
}
}
#endif /* __COMFORTABLE_SWIPE__service_buffer__ */ #endif /* __COMFORTABLE_SWIPE__service_buffer__ */

View File

@ -19,20 +19,16 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstdio> // std::puts
#include "../all_headers.hpp" #include "../all_headers.hpp"
#include <cstdio> // std::puts
namespace comfortable_swipe::service namespace comfortable_swipe::service {
{ /**
/** * Prints where the config file of comfortable swipe is located.
* Prints where the config file of comfortable swipe is located. *
* * Usage: nano $(comfortable-swipe config)
* Usage: nano $(comfortable-swipe config) */
*/ void config() { std::puts(comfortable_swipe::util::conf_filename()); }
void config() } // namespace comfortable_swipe::service
{
std::puts(comfortable_swipe::util::conf_filename());
}
}
#endif /* __COMFORTABLE_SWIPE__service_config__ */ #endif /* __COMFORTABLE_SWIPE__service_config__ */

View File

@ -21,15 +21,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cstdlib> // std::system #include <cstdlib> // std::system
namespace comfortable_swipe::service namespace comfortable_swipe::service {
{ /**
/** * Debugs output from `libinput debug-events`.
* Debugs output from `libinput debug-events`. */
*/ void debug() {
void debug() (void)std::system("bash -c \"stdbuf -oL -e0 libinput debug-events 2> >(grep "
{ "-v 'double tracking')\"");
(void) std::system("bash -c \"stdbuf -oL -e0 libinput debug-events 2> >(grep -v 'double tracking')\"");
}
} }
} // namespace comfortable_swipe::service
#endif /* __COMFORTABLE_SWIPE__service_debug__ */ #endif /* __COMFORTABLE_SWIPE__service_debug__ */

View File

@ -19,31 +19,32 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstdio> // std::puts, std::printf
#include "../all_headers.hpp" #include "../all_headers.hpp"
#include <cstdio> // std::puts, std::printf
namespace comfortable_swipe::service namespace comfortable_swipe::service {
{ /**
/** * Shows the help window.
* Shows the help window. */
*/ void help() {
void help() using comfortable_swipe::util::conf_filename;
{ std::puts("comfortable-swipe " COMFORTABLE_SWIPE_VERSION
using comfortable_swipe::util::conf_filename; " [start|stop|restart|autostart|buffer|help|config|debug|status]");
std::puts("comfortable-swipe " COMFORTABLE_SWIPE_VERSION " [start|stop|restart|autostart|buffer|help|config|debug|status]"); std::puts("");
std::puts(""); std::puts("start - starts 3/4-finger gesture service");
std::puts("start - starts 3/4-finger gesture service"); std::puts("stop - stops 3/4-finger gesture service");
std::puts("stop - stops 3/4-finger gesture service"); std::puts("restart - stops then starts 3/4-finger gesture service");
std::puts("restart - stops then starts 3/4-finger gesture service"); std::puts("autostart - automatically run on startup (toggleable)");
std::puts("autostart - automatically run on startup (toggleable)"); std::puts("buffer - parses output of libinput debug-events");
std::puts("buffer - parses output of libinput debug-events"); std::puts("help - shows the help dialog");
std::puts("help - shows the help dialog"); std::puts("config - locates the config file "
std::puts("config - locates the config file [/usr/share/comfortable-swipe/comfortable-swipe.conf]"); "[/usr/share/comfortable-swipe/comfortable-swipe.conf]");
std::puts("debug - logs raw output from input events taken from libinput"); std::puts(
std::puts("status - checks status of program and autostart"); "debug - logs raw output from input events taken from libinput");
std::puts(""); std::puts("status - checks status of program and autostart");
std::printf("Configuration file can be found in %s\n", conf_filename()); std::puts("");
} std::printf("Configuration file can be found in %s\n", conf_filename());
} }
} // namespace comfortable_swipe::service
#endif /* __COMFORTABLE_SWIPE__service_help__ */ #endif /* __COMFORTABLE_SWIPE__service_help__ */

View File

@ -19,25 +19,22 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstdio> // freopen, stdout
#include "../all_headers.hpp" #include "../all_headers.hpp"
#include <cstdio> // freopen, stdout
namespace comfortable_swipe::service namespace comfortable_swipe::service {
{ /**
/** * Restarts the comfortable-swipe service.
* Restarts the comfortable-swipe service. */
*/ void restart() {
void restart() // dont show stdout on stop
{ freopen("/dev/null", "a", stdout);
// dont show stdout on stop comfortable_swipe::service::stop();
freopen("/dev/null", "a", stdout);
comfortable_swipe::service::stop();
// show back on start // show back on start
freopen ("/dev/tty", "a", stdout); freopen("/dev/tty", "a", stdout);
comfortable_swipe::service::start(); comfortable_swipe::service::start();
}
} }
} // namespace comfortable_swipe::service
#endif /* __COMFORTABLE_SWIPE__service_restart__ */ #endif /* __COMFORTABLE_SWIPE__service_restart__ */

View File

@ -19,20 +19,19 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstdlib> // std::system
#include "../all_headers.hpp" #include "../all_headers.hpp"
#include <cstdlib> // std::system
namespace comfortable_swipe::service namespace comfortable_swipe::service {
{ /**
/** * Starts the comfortable-swipe service by buffering libinput debug-events.
* Starts the comfortable-swipe service by buffering libinput debug-events. * This method is deferred. Please refer to comfortable_swipe::service::buffer()
* This method is deferred. Please refer to comfortable_swipe::service::buffer() * for the technical implementation.
* for the technical implementation. */
*/ void start() {
void start() (void)std::system(__COMFORTABLE_SWIPE__PROGRAM__
{ " debug | " __COMFORTABLE_SWIPE__PROGRAM__ " buffer");
(void) std::system(__COMFORTABLE_SWIPE__PROGRAM__ " debug | " __COMFORTABLE_SWIPE__PROGRAM__ " buffer");
}
} }
} // namespace comfortable_swipe::service
#endif /* __COMFORTABLE_SWIPE__service_start__ */ #endif /* __COMFORTABLE_SWIPE__service_start__ */

View File

@ -19,77 +19,75 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdexcept> // std::runtime_error
#include <unistd.h> // popen, pclose, getpid, access, F_OK
#include <memory> // std::unique_ptr
#include <array> // std::array
#include <cstdlib> // std::atoi
#include <cstdio> // FILE, std::feof, std::fgets, std::printf
#include <regex> // std::cmatch, std::regex, std::regex_match
#include "../all_headers.hpp" #include "../all_headers.hpp"
#include <array> // std::array
#include <cstdio> // FILE, std::feof, std::fgets, std::printf
#include <cstdlib> // std::atoi
#include <memory> // std::unique_ptr
#include <regex> // std::cmatch, std::regex, std::regex_match
#include <stdexcept> // std::runtime_error
#include <unistd.h> // popen, pclose, getpid, access, F_OK
namespace comfortable_swipe::service namespace comfortable_swipe::service {
{ /**
/** * Prints the status of comfortable-swipe.
* Prints the status of comfortable-swipe. */
*/ void status() {
void status() // check if comfortable-swipe is running
{ bool running = false;
// check if comfortable-swipe is running std::array<char, 128> buffer;
bool running = false; std::unique_ptr<FILE, decltype(&pclose)> pipe(
std::array<char, 128> buffer; popen("pgrep -f comfortable-swipe", "r"), pclose);
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen("pgrep -f comfortable-swipe", "r"), pclose); if (pipe && !std::feof(pipe.get()) &&
if (pipe && !std::feof(pipe.get()) && std::fgets(buffer.data(), buffer.size(), pipe.get()) != NULL) std::fgets(buffer.data(), buffer.size(), pipe.get()) != NULL) {
{ int pid = std::atoi(buffer.data());
int pid = std::atoi(buffer.data()); if (pid != getpid())
if (pid != getpid()) running = true;
running = true; }
}
// check if autostart is on // check if autostart is on
auto autostart_f = comfortable_swipe::util::autostart_filename(); auto autostart_f = comfortable_swipe::util::autostart_filename();
bool autostart_on = access(autostart_f, F_OK) != -1; bool autostart_on = access(autostart_f, F_OK) != -1;
std::puts(comfortable_swipe::util::conf_filename()); std::puts(comfortable_swipe::util::conf_filename());
// check status of configuration file // check status of configuration file
try try {
{ auto config = comfortable_swipe::util::read_config_file(
auto config = comfortable_swipe::util::read_config_file(comfortable_swipe::util::conf_filename()); comfortable_swipe::util::conf_filename());
// print threshold // print threshold
if (config.count("threshold") > 0) if (config.count("threshold") > 0) {
{ auto &threshold = config["threshold"];
auto & threshold = config["threshold"];
// check if regex pattern matches threshold // check if regex pattern matches threshold
std::cmatch matches; std::cmatch matches;
bool ok = (std::regex_match(threshold.data(), matches, std::regex("^\\d+(?:\\.\\d+)??$")) != 0); bool ok = (std::regex_match(threshold.data(), matches,
std::regex("^\\d+(?:\\.\\d+)??$")) != 0);
// print status of threshold // print status of threshold
std::printf(" %9s is %s (%s)\n", "threshold", ok ? "OK" : "INVALID", threshold.data()); std::printf(" %9s is %s (%s)\n", "threshold", ok ? "OK" : "INVALID",
} threshold.data());
else } else
std::printf(" %9s is OFF\n", "threshold"); std::printf(" %9s is OFF\n", "threshold");
// print swipe commands // print swipe commands
for (auto &command : comfortable_swipe::gesture::keyboard_swipe_gesture::command_map) for (auto &command :
{ comfortable_swipe::gesture::keyboard_swipe_gesture::command_map) {
if (config.count(command) > 0) if (config.count(command) > 0)
std::printf(" %9s is OK (%s)\n", command, config[command].data()); std::printf(" %9s is OK (%s)\n", command, config[command].data());
else else
std::printf(" %9s is OFF\n", command); std::printf(" %9s is OFF\n", command);
}
}
catch (const std::runtime_error& e)
{
std::printf("config error: %s\n", e.what());
}
// print status
std::printf("autostart is %s\n", autostart_on ? "ON" : "OFF");
std::printf("comfortable-swipe program is %s\n", running ? "RUNNING" : "STOPPED");
} }
} catch (const std::runtime_error &e) {
std::printf("config error: %s\n", e.what());
}
// print status
std::printf("autostart is %s\n", autostart_on ? "ON" : "OFF");
std::printf("comfortable-swipe program is %s\n",
running ? "RUNNING" : "STOPPED");
} }
} // namespace comfortable_swipe::service
#endif /* __COMFORTABLE_SWIPE__service_restart__ */ #endif /* __COMFORTABLE_SWIPE__service_restart__ */

View File

@ -19,58 +19,51 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <array> // std::array
#include <cstdio> // std::FILE, std::feof, std::fgets
#include <cstdlib> // std::atoi, std::system
#include <memory> // std::unique_ptr
#include <stdexcept> // std::runtime_error #include <stdexcept> // std::runtime_error
#include <unistd.h> // popen, pclose, getpid #include <string> // std::string, std::to_string
#include <memory> // std::unique_ptr #include <unistd.h> // popen, pclose, getpid
#include <array> // std::array
#include <cstdio> // std::FILE, std::feof, std::fgets
#include <cstdlib> // std::atoi, std::system
#include <string> // std::string, std::to_string
namespace comfortable_swipe::service namespace comfortable_swipe::service {
{ /**
/** * Stops all comfortable-swipe instances.
* Stops all comfortable-swipe instances. */
*/ void stop() {
void stop()
{
// read all service names from process (pgrep) // read all service names from process (pgrep)
std::array<char, 128> buffer; std::array<char, 128> buffer;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen("pgrep -f \"$(which comfortable-swipe)\"", "r"), pclose); std::unique_ptr<FILE, decltype(&pclose)> pipe(
popen("pgrep -f \"$(which comfortable-swipe)\"", "r"), pclose);
// make sure pipe exists // make sure pipe exists
if (!pipe) if (!pipe)
throw std::runtime_error("stop command failed"); throw std::runtime_error("stop command failed");
// buffer what to kill // buffer what to kill
std::string kill = ""; std::string kill = "";
// read until end of line // read until end of line
while (!std::feof(pipe.get())) while (!std::feof(pipe.get())) {
{ if (std::fgets(buffer.data(), buffer.size(), pipe.get()) != NULL) {
if (std::fgets(buffer.data(), buffer.size(), pipe.get()) != NULL) int pid = std::atoi(buffer.data());
{ if (pid != getpid()) {
int pid = std::atoi(buffer.data()); kill += " ";
if (pid != getpid()) kill += std::to_string(pid);
{ }
kill += " ";
kill += std::to_string(pid);
}
}
}
// run "kill {pid1} {pid2}..."
if (kill.length())
{
std::printf("Stopped%s\n", kill.c_str());
(void) std::system(("kill" + kill).c_str());
}
else
{
std::printf("No program to stop\n");
}
} }
}
// run "kill {pid1} {pid2}..."
if (kill.length()) {
std::printf("Stopped%s\n", kill.c_str());
(void)std::system(("kill" + kill).c_str());
} else {
std::printf("No program to stop\n");
}
} }
} // namespace comfortable_swipe::service
#endif /* __COMFORTABLE_SWIPE__service_stop__ */ #endif /* __COMFORTABLE_SWIPE__service_stop__ */

View File

@ -19,28 +19,24 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string> // std::string #include <string> // std::string
#include <unistd.h> // getenv #include <unistd.h> // getenv
namespace comfortable_swipe::util namespace comfortable_swipe::util {
{ /**
/** * The path where the autostart configuration is located.
* The path where the autostart configuration is located. */
*/ const char *autostart_filename() {
const char* autostart_filename() static std::string filename;
{ if (filename.empty()) {
static std::string filename; const char *xdg_config = getenv("XDG_CONFIG_HOME");
if (filename.empty()) { std::string config(xdg_config == NULL
const char* xdg_config = getenv("XDG_CONFIG_HOME"); ? std::string(getenv("HOME")) + "/.config"
std::string config( : xdg_config);
xdg_config == NULL filename = config + "/autostart/comfortable-swipe.desktop";
? std::string(getenv("HOME")) + "/.config" }
: xdg_config return filename.data();
);
filename = config + "/autostart/comfortable-swipe.desktop";
}
return filename.data();
}
} }
} // namespace comfortable_swipe::util
#endif /* __COMFORTABLE_SWIPE__util_autostart_filename__ */ #endif /* __COMFORTABLE_SWIPE__util_autostart_filename__ */

View File

@ -21,15 +21,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "../all_headers.hpp" #include "../all_headers.hpp"
namespace comfortable_swipe::util namespace comfortable_swipe::util {
{ /**
/** * The path where the configuration file is located.
* The path where the configuration file is located. */
*/ constexpr const char *conf_filename() { return __COMFORTABLE_SWIPE__CONFIG__; }
constexpr const char* conf_filename() } // namespace comfortable_swipe::util
{
return __COMFORTABLE_SWIPE__CONFIG__;
}
}
#endif /* __COMFORTABLE_SWIPE__util_conf_filename__ */ #endif /* __COMFORTABLE_SWIPE__util_conf_filename__ */

View File

@ -19,85 +19,76 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <map> // std::map #include <cctype> // std::isspace
#include <string> // std::string #include <cstdlib> // exit
#include <fstream> // std::ifstream #include <fstream> // std::ifstream
#include <sstream> // std::ostringstream #include <iostream> // std::endl, std::getline
#include <iostream> // std::endl, std::getline #include <map> // std::map
#include <cstdlib> // exit #include <sstream> // std::ostringstream
#include <cctype> // std::isspace
#include <stdexcept> // std::runtime_error #include <stdexcept> // std::runtime_error
#include <string> // std::string
namespace comfortable_swipe::util namespace comfortable_swipe::util {
{ /**
/** * A utility method for reading the config file.
* A utility method for reading the config file. *
* * @param filename (const char*) the path of the config file.
* @param filename (const char*) the path of the config file. */
*/ std::map<std::string, std::string> read_config_file(const char *filename) {
std::map<std::string, std::string> read_config_file(const char* filename)
{
std::map<std::string, std::string> conf; std::map<std::string, std::string> conf;
std::ifstream fin(filename); std::ifstream fin(filename);
if (!fin.is_open()) if (!fin.is_open()) {
{ throw std::runtime_error("config file does not exist");
throw std::runtime_error("config file does not exist"); }
static std::string line, token[2];
int line_number = 0;
while (std::getline(fin, line)) {
++line_number;
token[0].clear();
token[1].clear();
int length = line.length();
int equal_flag = 0;
// tokenize comfig config
for (int i = 0; i < length; ++i) {
if (line[i] == '#') // skip comments
break;
if (line[i] == '=') // flag equal sign
{
if (++equal_flag > 1) {
std::ostringstream stream;
stream << "error in conf file " << filename << std::endl;
stream << "multiple equal signs in line " << line_number << std::endl;
throw std::runtime_error(stream.str());
} }
} else if (!std::isspace(line[i])) {
static std::string line, token[2]; // add to buffer
int line_number = 0; token[equal_flag].push_back(line[i]);
}
while (std::getline(fin, line))
{
++line_number;
token[0].clear();
token[1].clear();
int length = line.length();
int equal_flag = 0;
// tokenize comfig config
for (int i = 0; i < length; ++i)
{
if (line[i] == '#') // skip comments
break;
if (line[i] == '=') // flag equal sign
{
if (++equal_flag > 1)
{
std::ostringstream stream;
stream << "error in conf file " << filename << std::endl;
stream << "multiple equal signs in line " << line_number << std::endl;
throw std::runtime_error(stream.str());
}
}
else if (!std::isspace(line[i]))
{
// add to buffer
token[equal_flag].push_back(line[i]);
}
}
// ignore empty lines
if (equal_flag == 0 && token[0].length() == 0)
continue;
// no equal sign found in non-empty line
if (equal_flag == 0)
{
std::ostringstream stream;
stream << "error in conf file: " << filename << std::endl;
stream << "equal sign expected in line " << line_number << std::endl;
throw std::runtime_error(stream.str());
}
// equal sign found, add to tokens
if (token[1].length() > 0)
conf[token[0]] = token[1];
}
return conf;
} }
// ignore empty lines
if (equal_flag == 0 && token[0].length() == 0)
continue;
// no equal sign found in non-empty line
if (equal_flag == 0) {
std::ostringstream stream;
stream << "error in conf file: " << filename << std::endl;
stream << "equal sign expected in line " << line_number << std::endl;
throw std::runtime_error(stream.str());
}
// equal sign found, add to tokens
if (token[1].length() > 0)
conf[token[0]] = token[1];
}
return conf;
} }
} // namespace comfortable_swipe::util
#endif /* __COMFORTABLE_SWIPE__util_read_config_file__ */ #endif /* __COMFORTABLE_SWIPE__util_read_config_file__ */

View File

@ -16,55 +16,52 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <ios> // std::ios
#include <iostream> // std::cin, std::cout, std::cerr
#include <string> // std::string
#include "comfortable_swipe/lib" #include "comfortable_swipe/lib"
#include <ios> // std::ios
#include <iostream> // std::cin, std::cout, std::cerr
#include <string> // std::string
/* Command-line function. */ /* Command-line function. */
int main(int argc, char** args) int main(int argc, char **args) {
{ // improve buffering by decoupling loggers from stdio
// improve buffering by decoupling loggers from stdio std::ios::sync_with_stdio(false);
std::ios::sync_with_stdio(false); std::cin.tie(0);
std::cin.tie(0); std::cout.tie(0);
std::cout.tie(0); std::cerr.tie(0);
std::cerr.tie(0);
if (argc > 1) if (argc > 1) {
{ std::string arg = args[1];
std::string arg = args[1];
// select based on argument // select based on argument
if (arg == "start") if (arg == "start")
comfortable_swipe::service::start(); comfortable_swipe::service::start();
else if (arg == "stop") else if (arg == "stop")
comfortable_swipe::service::stop(); comfortable_swipe::service::stop();
else if (arg == "restart") else if (arg == "restart")
comfortable_swipe::service::restart(); comfortable_swipe::service::restart();
else if (arg == "buffer") else if (arg == "buffer")
comfortable_swipe::service::buffer(); comfortable_swipe::service::buffer();
else if (arg == "autostart") else if (arg == "autostart")
comfortable_swipe::service::autostart(); comfortable_swipe::service::autostart();
else if (arg == "config") else if (arg == "config")
comfortable_swipe::service::config(); comfortable_swipe::service::config();
else if (arg == "debug") else if (arg == "debug")
comfortable_swipe::service::debug(); comfortable_swipe::service::debug();
else if (arg == "status") else if (arg == "status")
comfortable_swipe::service::status(); comfortable_swipe::service::status();
else /* if (arg == "help") */ else /* if (arg == "help") */
comfortable_swipe::service::help(); comfortable_swipe::service::help();
} } else
else comfortable_swipe::service::help();
comfortable_swipe::service::help();
return 0; return 0;
} }

18
install
View File

@ -5,17 +5,17 @@ set -e
function install { function install {
# prefer running as root # prefer running as root
local dir="$(dirname "$0")" local dir="$(dirname "$0")"
local program=comfortable-swipe local program="comfortable-swipe"
local program_exe=/usr/local/bin/$program local program_exe="/usr/local/bin/$program"
local compile_command="$dir/cpp.compile.sh" local compile_command="$dir/cpp.compile.sh"
local compile_target="$dir/command_line.cpp" local compile_target="$dir/command_line.cpp"
local conf_path=/usr/local/share/$program/$program.conf local conf_path="/usr/local/share/$program/$program.conf"
local dconf_path="$dir/defaults.conf" local dconf_path="$dir/defaults.conf"
local old_conf_path="${XDG_CONFIG_HOME:-$HOME/.config}/$program.conf" local old_conf_path="${XDG_CONFIG_HOME:-$HOME/.config}/$program.conf"
if [ -x "$(command -v $program_exe)" ]; then if [ -x "$(command -v "$program_exe")" ]; then
# stop any running $program if it exists # stop any running $program if it exists
$program_exe stop "$program_exe" stop > /dev/null
fi fi
#copy config file #copy config file
@ -68,8 +68,8 @@ function install {
echo "Installing to $program_exe ..." echo "Installing to $program_exe ..."
# remove existing $program # remove existing $program
if [ -x "$(command -v $program_exe)" ]; then if [ -x "$(command -v "$program_exe")" ]; then
sudo rm -f "$(which $program)" sudo rm -f "$(which "$program")"
fi fi
# compile library # compile library
@ -79,9 +79,9 @@ function install {
# GROUP=$(ls -l /dev/input/event* | awk '{print $4}' | head --line=1) || abort # GROUP=$(ls -l /dev/input/event* | awk '{print $4}' | head --line=1) || abort
# turn on autostart by default # turn on autostart by default
local autostart_status="$($program_exe autostart)" local autostart_status="$("$program_exe" autostart)"
if [[ "$autostart_status" == *off* ]]; then if [[ "$autostart_status" == *off* ]]; then
autostart_status="$($program_exe autostart)" autostart_status="$("$program_exe" autostart)"
fi fi
echo "Successfully installed $program $(cat $dir/VERSION | tr -d '[:space:]')" echo "Successfully installed $program $(cat $dir/VERSION | tr -d '[:space:]')"

133
tests/test_regex.cpp Executable file → Normal file
View File

@ -1,9 +1,9 @@
#include <iostream>
#include <cassert>
#include <regex>
#include <string>
#include "../comfortable_swipe/gesture/swipe_gesture.h" #include "../comfortable_swipe/gesture/swipe_gesture.h"
#include "../comfortable_swipe/gesture/swipe_gesture.regex.cpp" #include "../comfortable_swipe/gesture/swipe_gesture.regex.cpp"
#include <cassert>
#include <iostream>
#include <regex>
#include <string>
/* /*
Comfortable Swipe Comfortable Swipe
@ -23,71 +23,70 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
namespace test namespace test {
{ void gesture_begin_should_match_regex();
void gesture_begin_should_match_regex(); void gesture_update_should_match_regex();
void gesture_update_should_match_regex(); void gesture_end_should_match_regex();
void gesture_end_should_match_regex(); } // namespace test
int main() {
std::cout << "(1) Testing gesture_begin_should_match_regex()" << std::endl;
test::gesture_begin_should_match_regex();
std::cout << "(2) Testing gesture_begin_should_match_regex()" << std::endl;
test::gesture_update_should_match_regex();
std::cout << "(3) Testing gesture_begin_should_match_regex()" << std::endl;
test::gesture_end_should_match_regex();
std::cout << "ALL TEST PASSED" << std::endl;
} }
int main() namespace test {
{ void gesture_begin_test(const std::regex &matcher, const char *data,
std::cout << "(1) Testing gesture_begin_should_match_regex()" << std::endl; const char *expected_fingers) {
test::gesture_begin_should_match_regex(); std::cout << " testing against \"" << data << "\"...";
std::cmatch matches;
std::cout << "(2) Testing gesture_begin_should_match_regex()" << std::endl; int result = std::regex_match(data, matches, matcher);
test::gesture_update_should_match_regex(); assert(result != 0);
assert((std::string)matches[1] == expected_fingers);
std::cout << "(3) Testing gesture_begin_should_match_regex()" << std::endl; std::cout << "PASSED" << std::endl;
test::gesture_end_should_match_regex();
std::cout << "ALL TEST PASSED" << std::endl;
} }
namespace test void gesture_begin_should_match_regex() {
{ std::regex matcher(
void gesture_begin_test( comfortable_swipe::gesture::swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN);
const std::regex& matcher, test::gesture_begin_test(matcher, " event15 GESTURE_SWIPE_BEGIN +34.33s 3\n",
const char* data, "3");
const char* expected_fingers) test::gesture_begin_test(matcher, "-event4 GESTURE_SWIPE_BEGIN +3.12s 4\n",
{ "4");
std::cout << " testing against \"" << data << "\"..."; test::gesture_begin_test(matcher, "-event7 GESTURE_SWIPE_BEGIN +4.72s 3\n",
std::cmatch matches; "3");
int result = std::regex_match(data, matches, matcher); test::gesture_begin_test(matcher, " event9 GESTURE_SWIPE_BEGIN +45.80s 4\n",
assert(result != 0); "4");
assert((std::string) matches[1] == expected_fingers);
std::cout << "PASSED" << std::endl;
}
void gesture_begin_should_match_regex()
{
std::regex matcher(comfortable_swipe::gesture::swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN);
test::gesture_begin_test(matcher, " event15 GESTURE_SWIPE_BEGIN +34.33s 3\n", "3");
test::gesture_begin_test(matcher, "-event4 GESTURE_SWIPE_BEGIN +3.12s 4\n", "4");
test::gesture_begin_test(matcher, "-event7 GESTURE_SWIPE_BEGIN +4.72s 3\n", "3");
test::gesture_begin_test(matcher, " event9 GESTURE_SWIPE_BEGIN +45.80s 4\n", "4");
}
void gesture_update_should_match_regex()
{
const char* data = " event15 GESTURE_SWIPE_UPDATE +34.70s 3 -0.12/ 4.99 (-0.33/13.50 unaccelerated)\n";
std::regex matcher(comfortable_swipe::gesture::swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN);
std::cmatch matches;
auto result = std::regex_match(data, matches, matcher);
assert(result != 0);
assert((std::string) matches[1] == "3");
assert((std::string) matches[2] == "-0.12");
assert((std::string) matches[3] == "4.99");
assert((std::string) matches[4] == "-0.33");
assert((std::string) matches[5] == "13.50");
}
void gesture_end_should_match_regex()
{
const char* data = " event15 GESTURE_SWIPE_END +35.03s 3\n";
std::regex matcher(comfortable_swipe::gesture::swipe_gesture::GESTURE_END_REGEX_PATTERN);
std::cmatch matches;
auto result = std::regex_match(data, matches, matcher);
assert(result != 0);
assert((std::string) matches[1] == "3");
}
} }
void gesture_update_should_match_regex() {
const char *data = " event15 GESTURE_SWIPE_UPDATE +34.70s 3 -0.12/ 4.99 "
"(-0.33/13.50 unaccelerated)\n";
std::regex matcher(
comfortable_swipe::gesture::swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN);
std::cmatch matches;
auto result = std::regex_match(data, matches, matcher);
assert(result != 0);
assert((std::string)matches[1] == "3");
assert((std::string)matches[2] == "-0.12");
assert((std::string)matches[3] == "4.99");
assert((std::string)matches[4] == "-0.33");
assert((std::string)matches[5] == "13.50");
}
void gesture_end_should_match_regex() {
const char *data = " event15 GESTURE_SWIPE_END +35.03s 3\n";
std::regex matcher(
comfortable_swipe::gesture::swipe_gesture::GESTURE_END_REGEX_PATTERN);
std::cmatch matches;
auto result = std::regex_match(data, matches, matcher);
assert(result != 0);
assert((std::string)matches[1] == "3");
}
} // namespace test