Attempt fix g++ error
This commit is contained in:
parent
5457e012f2
commit
2ee59cf722
@ -15,6 +15,9 @@ addons:
|
|||||||
packages:
|
packages:
|
||||||
- libxdo-dev
|
- libxdo-dev
|
||||||
- libinput-tools
|
- libinput-tools
|
||||||
|
- g++-7
|
||||||
|
env:
|
||||||
|
CC: g++-7
|
||||||
install:
|
install:
|
||||||
- pip install .
|
- pip install .
|
||||||
script:
|
script:
|
||||||
|
|||||||
@ -32,182 +32,185 @@ extern "C"
|
|||||||
// CURRENT_WINDOW
|
// CURRENT_WINDOW
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace comfortable_swipe::gesture
|
namespace comfortable_swipe
|
||||||
{
|
{
|
||||||
/**
|
namespace gesture
|
||||||
* Constructs a new swipe gesture, given configurations for certain swipe events.
|
|
||||||
*/
|
|
||||||
swipe_gesture::swipe_gesture
|
|
||||||
(
|
|
||||||
const float threshold,
|
|
||||||
const char* left3 /* 000 */,
|
|
||||||
const char* left4 /* 001 */,
|
|
||||||
const char* right3 /* 010 */,
|
|
||||||
const char* right4 /* 011 */,
|
|
||||||
const char* up3 /* 100 */,
|
|
||||||
const char* up4 /* 101 */,
|
|
||||||
const char* down3 /* 110 */,
|
|
||||||
const char* down4 /* 111 */
|
|
||||||
):
|
|
||||||
comfortable_swipe::gesture::xdo_gesture(),
|
|
||||||
threshold_squared(threshold*threshold),
|
|
||||||
commands(new const char*[8]{left3, left4, right3, right4, up3, up4, down3, down4}),
|
|
||||||
flag_swiping(false)
|
|
||||||
{
|
{
|
||||||
// improve responsiveness of first gesture by pre-empting xdotool runtime
|
/**
|
||||||
xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num);
|
* Constructs a new swipe gesture, given configurations for certain swipe events.
|
||||||
}
|
*/
|
||||||
|
swipe_gesture::swipe_gesture
|
||||||
/**
|
(
|
||||||
* Destructs this swipe gesture.
|
const float threshold,
|
||||||
*/
|
const char* left3 /* 000 */,
|
||||||
swipe_gesture::~swipe_gesture()
|
const char* left4 /* 001 */,
|
||||||
{
|
const char* right3 /* 010 */,
|
||||||
delete[] commands;
|
const char* right4 /* 011 */,
|
||||||
}
|
const char* up3 /* 100 */,
|
||||||
|
const char* up4 /* 101 */,
|
||||||
/**
|
const char* down3 /* 110 */,
|
||||||
* Hook on begin of swipe gesture.
|
const char* down4 /* 111 */
|
||||||
*/
|
):
|
||||||
void swipe_gesture::begin()
|
comfortable_swipe::gesture::xdo_gesture(),
|
||||||
{
|
threshold_squared(threshold*threshold),
|
||||||
xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num);
|
commands(new const char*[8]{left3, left4, right3, right4, up3, up4, down3, down4}),
|
||||||
this->previous_gesture = swipe_gesture::FRESH;
|
flag_swiping(false)
|
||||||
this->x = 0;
|
|
||||||
this->y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook on update of swipe gesture.
|
|
||||||
*/
|
|
||||||
void swipe_gesture::update()
|
|
||||||
{
|
|
||||||
this->x += this->dx;
|
|
||||||
this->y += this->dy;
|
|
||||||
// scale threshold to 1/10 when gesture is not fresh
|
|
||||||
float scale = this->previous_gesture == swipe_gesture::FRESH
|
|
||||||
? 1.00f
|
|
||||||
: 0.01f; // square root of 1/10
|
|
||||||
static const float EPSILON = 1e-6f;
|
|
||||||
if (this->x * this->x + this->y * this->y
|
|
||||||
> this->threshold_squared * scale + EPSILON)
|
|
||||||
{
|
{
|
||||||
int mask = 0;
|
// improve responsiveness of first gesture by pre-empting xdotool runtime
|
||||||
if (this->fingers == 3) mask |= swipe_gesture::MSK_THREE_FINGERS;
|
xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num);
|
||||||
else if (this->fingers == 4) mask |= swipe_gesture::MSK_FOUR_FINGERS;
|
|
||||||
|
|
||||||
const float absx = x >= 0 ? x : -x;
|
|
||||||
const float absy = y >= 0 ? y : -y;
|
|
||||||
if (absx > absy)
|
|
||||||
{ // horizontal
|
|
||||||
mask |= swipe_gesture::MSK_HORIZONTAL;
|
|
||||||
if (x < 0)
|
|
||||||
mask |= swipe_gesture::MSK_NEGATIVE;
|
|
||||||
else
|
|
||||||
mask |= swipe_gesture::MSK_POSITIVE;
|
|
||||||
}
|
|
||||||
else /* std::abs(x) <= std::abs(y) */
|
|
||||||
{ // vertical
|
|
||||||
mask |= swipe_gesture::MSK_VERTICAL;
|
|
||||||
if (y < 0)
|
|
||||||
mask |= swipe_gesture::MSK_NEGATIVE;
|
|
||||||
else
|
|
||||||
mask |= swipe_gesture::MSK_POSITIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// send command on fresh OR opposite gesture
|
|
||||||
if (this->previous_gesture == swipe_gesture::FRESH
|
|
||||||
|| this->previous_gesture == (mask ^ swipe_gesture::MSK_POSITIVE))
|
|
||||||
{
|
|
||||||
xdo_send_keysequence_window(this->xdo, CURRENTWINDOW, swipe_gesture::commands[mask], 0);
|
|
||||||
this->x = this->y = 0;
|
|
||||||
this->previous_gesture = mask;
|
|
||||||
std::cout << "SWIPE " << swipe_gesture::command_map[mask] << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook on end of swipe gesture.
|
* Destructs this swipe gesture.
|
||||||
*/
|
*/
|
||||||
void swipe_gesture::end()
|
swipe_gesture::~swipe_gesture()
|
||||||
{ }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)
|
|
||||||
{
|
|
||||||
static const std::regex gesture_swipe_begin(swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN);
|
|
||||||
static const std::regex gesture_swipe_update(swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN);
|
|
||||||
static const std::regex gesture_swipe_end(swipe_gesture::GESTURE_END_REGEX_PATTERN);
|
|
||||||
|
|
||||||
// prepare holder for regex matches
|
|
||||||
static std::cmatch matches;
|
|
||||||
|
|
||||||
if (this->flag_swiping)
|
|
||||||
{
|
{
|
||||||
// currently swiping
|
delete[] commands;
|
||||||
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
|
|
||||||
|
/**
|
||||||
|
* Hook on begin of swipe gesture.
|
||||||
|
*/
|
||||||
|
void swipe_gesture::begin()
|
||||||
{
|
{
|
||||||
// not swiping, check if swipe will begin
|
xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num);
|
||||||
if (std::regex_match(line, matches, gesture_swipe_begin) != 0)
|
this->previous_gesture = swipe_gesture::FRESH;
|
||||||
|
this->x = 0;
|
||||||
|
this->y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook on update of swipe gesture.
|
||||||
|
*/
|
||||||
|
void swipe_gesture::update()
|
||||||
|
{
|
||||||
|
this->x += this->dx;
|
||||||
|
this->y += this->dy;
|
||||||
|
// scale threshold to 1/10 when gesture is not fresh
|
||||||
|
float scale = this->previous_gesture == swipe_gesture::FRESH
|
||||||
|
? 1.00f
|
||||||
|
: 0.01f; // square root of 1/10
|
||||||
|
static const float EPSILON = 1e-6f;
|
||||||
|
if (this->x * this->x + this->y * this->y
|
||||||
|
> this->threshold_squared * scale + EPSILON)
|
||||||
{
|
{
|
||||||
// assign necessary variables for swipe begin
|
int mask = 0;
|
||||||
this->flag_swiping = true;
|
if (this->fingers == 3) mask |= swipe_gesture::MSK_THREE_FINGERS;
|
||||||
this->fingers = std::stoi(matches[1]);
|
else if (this->fingers == 4) mask |= swipe_gesture::MSK_FOUR_FINGERS;
|
||||||
// dispatch begin
|
|
||||||
this->begin();
|
const float absx = x >= 0 ? x : -x;
|
||||||
return true;
|
const float absy = y >= 0 ? y : -y;
|
||||||
|
if (absx > absy)
|
||||||
|
{ // horizontal
|
||||||
|
mask |= swipe_gesture::MSK_HORIZONTAL;
|
||||||
|
if (x < 0)
|
||||||
|
mask |= swipe_gesture::MSK_NEGATIVE;
|
||||||
|
else
|
||||||
|
mask |= swipe_gesture::MSK_POSITIVE;
|
||||||
|
}
|
||||||
|
else /* std::abs(x) <= std::abs(y) */
|
||||||
|
{ // vertical
|
||||||
|
mask |= swipe_gesture::MSK_VERTICAL;
|
||||||
|
if (y < 0)
|
||||||
|
mask |= swipe_gesture::MSK_NEGATIVE;
|
||||||
|
else
|
||||||
|
mask |= swipe_gesture::MSK_POSITIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send command on fresh OR opposite gesture
|
||||||
|
if (this->previous_gesture == swipe_gesture::FRESH
|
||||||
|
|| this->previous_gesture == (mask ^ swipe_gesture::MSK_POSITIVE))
|
||||||
|
{
|
||||||
|
xdo_send_keysequence_window(this->xdo, CURRENTWINDOW, swipe_gesture::commands[mask], 0);
|
||||||
|
this->x = this->y = 0;
|
||||||
|
this->previous_gesture = mask;
|
||||||
|
std::cout << "SWIPE " << swipe_gesture::command_map[mask] << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
/**
|
||||||
}
|
* Hook on end of swipe gesture.
|
||||||
|
*/
|
||||||
|
void swipe_gesture::end()
|
||||||
|
{ }
|
||||||
|
|
||||||
/* STATICS DEFINITIONS */
|
/**
|
||||||
const int swipe_gesture::MSK_THREE_FINGERS = 0;
|
* Dispatches begin/update/end depending on the regex pattern provided by this class.
|
||||||
const int swipe_gesture::MSK_FOUR_FINGERS = 1;
|
*
|
||||||
const int swipe_gesture::MSK_NEGATIVE = 0;
|
* @param line the line from libinput debug-events to parse
|
||||||
const int swipe_gesture::MSK_POSITIVE = 2;
|
* @return true if begin/update/end was dispatched
|
||||||
const int swipe_gesture::MSK_HORIZONTAL = 0;
|
*/
|
||||||
const int swipe_gesture::MSK_VERTICAL = 4;
|
bool swipe_gesture::parse_line(const char * line)
|
||||||
const int swipe_gesture::FRESH = -1;
|
{
|
||||||
const char * const swipe_gesture::command_map[8] = {
|
static const std::regex gesture_swipe_begin(swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN);
|
||||||
"left3",
|
static const std::regex gesture_swipe_update(swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN);
|
||||||
"left4",
|
static const std::regex gesture_swipe_end(swipe_gesture::GESTURE_END_REGEX_PATTERN);
|
||||||
"right3",
|
|
||||||
"right4",
|
// prepare holder for regex matches
|
||||||
"up3",
|
static std::cmatch matches;
|
||||||
"up4",
|
|
||||||
"down3",
|
if (this->flag_swiping)
|
||||||
"down4"
|
{
|
||||||
};
|
// 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)
|
||||||
|
{
|
||||||
|
// assign necessary variables for swipe begin
|
||||||
|
this->flag_swiping = true;
|
||||||
|
this->fingers = std::stoi(matches[1]);
|
||||||
|
// dispatch begin
|
||||||
|
this->begin();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* STATICS DEFINITIONS */
|
||||||
|
const int swipe_gesture::MSK_THREE_FINGERS = 0;
|
||||||
|
const int swipe_gesture::MSK_FOUR_FINGERS = 1;
|
||||||
|
const int swipe_gesture::MSK_NEGATIVE = 0;
|
||||||
|
const int swipe_gesture::MSK_POSITIVE = 2;
|
||||||
|
const int swipe_gesture::MSK_HORIZONTAL = 0;
|
||||||
|
const int swipe_gesture::MSK_VERTICAL = 4;
|
||||||
|
const int swipe_gesture::FRESH = -1;
|
||||||
|
const char * const swipe_gesture::command_map[8] = {
|
||||||
|
"left3",
|
||||||
|
"left4",
|
||||||
|
"right3",
|
||||||
|
"right4",
|
||||||
|
"up3",
|
||||||
|
"up4",
|
||||||
|
"down3",
|
||||||
|
"down4"
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture__ */
|
#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture__ */
|
||||||
|
|||||||
@ -21,70 +21,65 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#include "xdo_gesture.h"
|
#include "xdo_gesture.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
namespace comfortable_swipe
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace comfortable_swipe::gesture
|
|
||||||
{
|
{
|
||||||
class swipe_gesture : protected xdo_gesture
|
namespace gesture
|
||||||
{
|
{
|
||||||
public:
|
class swipe_gesture : protected xdo_gesture
|
||||||
// constructor
|
{
|
||||||
swipe_gesture(
|
public:
|
||||||
const float threshold,
|
// constructor
|
||||||
const char* left3 /* 000 */,
|
swipe_gesture(
|
||||||
const char* left4 /* 001 */,
|
const float threshold,
|
||||||
const char* right3 /* 010 */,
|
const char* left3 /* 000 */,
|
||||||
const char* right4 /* 011 */,
|
const char* left4 /* 001 */,
|
||||||
const char* up3 /* 100 */,
|
const char* right3 /* 010 */,
|
||||||
const char* up4 /* 101 */,
|
const char* right4 /* 011 */,
|
||||||
const char* down3 /* 110 */,
|
const char* up3 /* 100 */,
|
||||||
const char* down4 /* 111 */
|
const char* up4 /* 101 */,
|
||||||
);
|
const char* down3 /* 110 */,
|
||||||
|
const char* down4 /* 111 */
|
||||||
|
);
|
||||||
|
|
||||||
~swipe_gesture();
|
~swipe_gesture();
|
||||||
|
|
||||||
// fields for xdo
|
// fields for xdo
|
||||||
int fingers;
|
int fingers;
|
||||||
float dx, dy, udx, udy;
|
float dx, dy, udx, udy;
|
||||||
|
|
||||||
void begin() override;
|
void begin() override;
|
||||||
void update() override;
|
void update() override;
|
||||||
void end() override;
|
void end() override;
|
||||||
bool parse_line(const char *) override;
|
bool parse_line(const char *) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// location of mouse
|
// location of mouse
|
||||||
int screen_num, ix, iy;
|
int screen_num, ix, iy;
|
||||||
|
|
||||||
// current location
|
// current location
|
||||||
float x, y, threshold_squared;
|
float x, y, threshold_squared;
|
||||||
int previous_gesture;
|
int previous_gesture;
|
||||||
const char ** commands;
|
const char ** commands;
|
||||||
|
|
||||||
// optimization flag for checking if GESTURE_SWIPE_BEGIN was dispatched
|
// optimization flag for checking if GESTURE_SWIPE_BEGIN was dispatched
|
||||||
bool flag_swiping;
|
bool flag_swiping;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// static constants
|
// static constants
|
||||||
static const int MSK_THREE_FINGERS;
|
static const int MSK_THREE_FINGERS;
|
||||||
static const int MSK_FOUR_FINGERS;
|
static const int MSK_FOUR_FINGERS;
|
||||||
static const int MSK_NEGATIVE;
|
static const int MSK_NEGATIVE;
|
||||||
static const int MSK_POSITIVE;
|
static const int MSK_POSITIVE;
|
||||||
static const int MSK_HORIZONTAL;
|
static const int MSK_HORIZONTAL;
|
||||||
static const int MSK_VERTICAL;
|
static const int MSK_VERTICAL;
|
||||||
static const int FRESH;
|
static const int FRESH;
|
||||||
static const char * const command_map[8];
|
static const char * const command_map[8];
|
||||||
// regex patterns
|
// regex patterns
|
||||||
static const char* GESTURE_BEGIN_REGEX_PATTERN;
|
static const char* GESTURE_BEGIN_REGEX_PATTERN;
|
||||||
static const char* GESTURE_UPDATE_REGEX_PATTERN;
|
static const char* GESTURE_UPDATE_REGEX_PATTERN;
|
||||||
static const char* GESTURE_END_REGEX_PATTERN;
|
static const char* GESTURE_END_REGEX_PATTERN;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ */
|
#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ */
|
||||||
|
|||||||
@ -21,71 +21,74 @@ 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
|
||||||
{
|
{
|
||||||
/**
|
namespace gesture
|
||||||
* Regex pattern for the libinput entry for start of swipe.
|
{
|
||||||
* Extracts one match for the number of fingers used during the swipe.
|
/**
|
||||||
*
|
* Regex pattern for the libinput entry for start of swipe.
|
||||||
* eg. event15 GESTURE_SWIPE_BEGIN +34.33s 3
|
* Extracts one match for the number of fingers used during the swipe.
|
||||||
* ^
|
*
|
||||||
* fingers
|
* eg. event15 GESTURE_SWIPE_BEGIN +34.33s 3
|
||||||
*/
|
* ^
|
||||||
const char* swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN =
|
* fingers
|
||||||
"^" // start of string
|
*/
|
||||||
"[ -]event\\d+" // event
|
const char* swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN =
|
||||||
"\\s+GESTURE_SWIPE_BEGIN" // gesture
|
"^" // start of string
|
||||||
"\\s+\\S+" // timestamp
|
"[ -]event\\d+" // event
|
||||||
"\\s+(\\d+)" // fingers
|
"\\s+GESTURE_SWIPE_BEGIN" // gesture
|
||||||
"\\s*$" // end of string
|
"\\s+\\S+" // timestamp
|
||||||
;
|
"\\s+(\\d+)" // fingers
|
||||||
|
"\\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 unaccelerated)
|
||||||
* ^ ^ ^ ^ ^
|
* ^ ^ ^ ^ ^
|
||||||
* fingers dx dy udx udy
|
* 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+unaccelerated\\)" // unaccelerated speed (udx/udy)
|
||||||
"\\s*$" // end of string
|
"\\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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_regex__ */
|
#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_regex__ */
|
||||||
|
|||||||
@ -26,21 +26,24 @@ extern "C"
|
|||||||
|
|
||||||
#include "xdo_gesture.h"
|
#include "xdo_gesture.h"
|
||||||
|
|
||||||
namespace comfortable_swipe::gesture
|
namespace comfortable_swipe
|
||||||
{
|
{
|
||||||
/**
|
namespace gesture
|
||||||
* Constructs a new gesture handler with xdo.
|
|
||||||
*/
|
|
||||||
xdo_gesture::xdo_gesture():
|
|
||||||
xdo(xdo_new(NULL))
|
|
||||||
{ }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new swipe gesture with xdo.
|
|
||||||
*/
|
|
||||||
xdo_gesture::~xdo_gesture()
|
|
||||||
{
|
{
|
||||||
xdo_free(this->xdo);
|
/**
|
||||||
|
* Constructs a new gesture handler with xdo.
|
||||||
|
*/
|
||||||
|
xdo_gesture::xdo_gesture():
|
||||||
|
xdo(xdo_new(NULL))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new swipe gesture with xdo.
|
||||||
|
*/
|
||||||
|
xdo_gesture::~xdo_gesture()
|
||||||
|
{
|
||||||
|
xdo_free(this->xdo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,20 +4,17 @@
|
|||||||
#include <map> // std::map
|
#include <map> // std::map
|
||||||
#include <string> // std::string
|
#include <string> // std::string
|
||||||
|
|
||||||
extern "C"
|
namespace comfortable_swipe
|
||||||
{
|
{
|
||||||
namespace comfortable_swipe
|
namespace service
|
||||||
{
|
{
|
||||||
namespace service
|
void buffer();
|
||||||
{
|
void debug();
|
||||||
void buffer();
|
void help();
|
||||||
void debug();
|
void restart();
|
||||||
void help();
|
void start();
|
||||||
void restart();
|
void stop();
|
||||||
void start();
|
void status();
|
||||||
void stop();
|
|
||||||
void status();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,60 +2,69 @@
|
|||||||
#define __COMFORTABLE_SWIPE__service_python__
|
#define __COMFORTABLE_SWIPE__service_python__
|
||||||
|
|
||||||
#include "_index.hpp"
|
#include "_index.hpp"
|
||||||
#include <Python.h>
|
extern "C"
|
||||||
|
{
|
||||||
|
#include <Python.h>
|
||||||
|
}
|
||||||
|
|
||||||
// export as python module
|
// export as python module
|
||||||
namespace comfortable_swipe::service::python
|
namespace comfortable_swipe
|
||||||
{
|
{
|
||||||
#define __comfortable_swipe_void_method(method) \
|
namespace service
|
||||||
static PyObject * \
|
{
|
||||||
method(PyObject * self, PyObject * args) \
|
namespace python
|
||||||
{ \
|
{
|
||||||
comfortable_swipe::service::method(); \
|
#define __comfortable_swipe_void_method(method) \
|
||||||
Py_RETURN_NONE; \
|
static PyObject * \
|
||||||
|
method(PyObject * self, PyObject * args) \
|
||||||
|
{ \
|
||||||
|
comfortable_swipe::service::method(); \
|
||||||
|
Py_RETURN_NONE; \
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the python method signatures
|
||||||
|
__comfortable_swipe_void_method(status);
|
||||||
|
__comfortable_swipe_void_method(start);
|
||||||
|
__comfortable_swipe_void_method(stop);
|
||||||
|
__comfortable_swipe_void_method(restart);
|
||||||
|
// __comfortable_swipe_void_method(autostart);
|
||||||
|
__comfortable_swipe_void_method(buffer);
|
||||||
|
__comfortable_swipe_void_method(help);
|
||||||
|
// __comfortable_swipe_void_method(config);
|
||||||
|
__comfortable_swipe_void_method(debug);
|
||||||
|
|
||||||
|
#undef __comfortable_swipe_void_method
|
||||||
|
|
||||||
|
// create the method list for C++
|
||||||
|
static PyMethodDef methods[] =
|
||||||
|
{
|
||||||
|
{ "status", &status, METH_VARARGS , "checks status of program, autostart, and config" },
|
||||||
|
{ "start", &start, METH_VARARGS , "starts 3/4-finger gesture service" },
|
||||||
|
{ "stop", &stop, METH_VARARGS , "stops 3/4-finger gesture service" },
|
||||||
|
{ "restart", &restart, METH_VARARGS , "stops then starts 3/4-finger gesture service" },
|
||||||
|
// { "autostart", &autostart, METH_VARARGS , "automatically run on startup (toggleable)" },
|
||||||
|
{ "buffer", &buffer, METH_VARARGS , "parses output of libinput debug-events" },
|
||||||
|
{ "help", &help, METH_VARARGS , "shows the help dialog" },
|
||||||
|
// { "config", &config, METH_VARARGS , "locates the config file " },
|
||||||
|
{ "debug", &debug, METH_VARARGS , "logs raw output from input events taken from libinput" },
|
||||||
|
{ NULL, NULL, 0, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
// create the module configuration
|
||||||
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
static struct PyModuleDef module_def =
|
||||||
|
{
|
||||||
|
PyModuleDef_HEAD_INIT,
|
||||||
|
"service",
|
||||||
|
"Comfortable swipe service",
|
||||||
|
-1,
|
||||||
|
methods
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PyObject * module;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// create the python method signatures
|
|
||||||
__comfortable_swipe_void_method(status);
|
|
||||||
__comfortable_swipe_void_method(start);
|
|
||||||
__comfortable_swipe_void_method(stop);
|
|
||||||
__comfortable_swipe_void_method(restart);
|
|
||||||
// __comfortable_swipe_void_method(autostart);
|
|
||||||
__comfortable_swipe_void_method(buffer);
|
|
||||||
__comfortable_swipe_void_method(help);
|
|
||||||
// __comfortable_swipe_void_method(config);
|
|
||||||
__comfortable_swipe_void_method(debug);
|
|
||||||
|
|
||||||
#undef __comfortable_swipe_void_method
|
|
||||||
|
|
||||||
// create the method list for C++
|
|
||||||
static PyMethodDef methods[] =
|
|
||||||
{
|
|
||||||
{ "status", &status, METH_VARARGS , "checks status of program, autostart, and config" },
|
|
||||||
{ "start", &start, METH_VARARGS , "starts 3/4-finger gesture service" },
|
|
||||||
{ "stop", &stop, METH_VARARGS , "stops 3/4-finger gesture service" },
|
|
||||||
{ "restart", &restart, METH_VARARGS , "stops then starts 3/4-finger gesture service" },
|
|
||||||
// { "autostart", &autostart, METH_VARARGS , "automatically run on startup (toggleable)" },
|
|
||||||
{ "buffer", &buffer, METH_VARARGS , "parses output of libinput debug-events" },
|
|
||||||
{ "help", &help, METH_VARARGS , "shows the help dialog" },
|
|
||||||
// { "config", &config, METH_VARARGS , "locates the config file " },
|
|
||||||
{ "debug", &debug, METH_VARARGS , "logs raw output from input events taken from libinput" },
|
|
||||||
{ NULL, NULL, 0, NULL } // sentinel
|
|
||||||
};
|
|
||||||
|
|
||||||
// create the module configuration
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
static struct PyModuleDef module_def =
|
|
||||||
{
|
|
||||||
PyModuleDef_HEAD_INIT,
|
|
||||||
"service",
|
|
||||||
"Comfortable swipe service",
|
|
||||||
-1,
|
|
||||||
methods
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyObject * module;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize module
|
// initialize module
|
||||||
|
|||||||
@ -21,14 +21,17 @@ 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
|
||||||
{
|
{
|
||||||
/**
|
namespace service
|
||||||
* Debugs output from `libinput debug-events`.
|
|
||||||
*/
|
|
||||||
void debug()
|
|
||||||
{
|
{
|
||||||
(void) std::system("bash -c \"stdbuf -oL -e0 libinput debug-events 2> >(grep -v 'double tracking')\"");
|
/**
|
||||||
|
* Debugs output from `libinput debug-events`.
|
||||||
|
*/
|
||||||
|
void debug()
|
||||||
|
{
|
||||||
|
(void) std::system("bash -c \"stdbuf -oL -e0 libinput debug-events 2> >(grep -v 'double tracking')\"");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,24 +21,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#include <cstdio> // std::puts, std::printf
|
#include <cstdio> // std::puts, std::printf
|
||||||
|
|
||||||
namespace comfortable_swipe::service
|
namespace comfortable_swipe
|
||||||
{
|
{
|
||||||
/**
|
namespace service
|
||||||
* Shows the help window.
|
|
||||||
*/
|
|
||||||
void help()
|
|
||||||
{
|
{
|
||||||
std::puts("comfortable-swipe [start|stop|restart|autostart|buffer|help|config|debug|status]");
|
/**
|
||||||
std::puts("");
|
* Shows the help window.
|
||||||
std::puts("start - starts 3/4-finger gesture service");
|
*/
|
||||||
std::puts("stop - stops 3/4-finger gesture service");
|
void help()
|
||||||
std::puts("restart - stops then starts 3/4-finger gesture service");
|
{
|
||||||
std::puts("autostart - automatically run on startup (toggleable)");
|
std::puts("comfortable-swipe [start|stop|restart|autostart|buffer|help|config|debug|status]");
|
||||||
std::puts("buffer - parses output of libinput debug-events");
|
std::puts("");
|
||||||
std::puts("help - shows the help dialog");
|
std::puts("start - starts 3/4-finger gesture service");
|
||||||
std::puts("config - locates the config file");
|
std::puts("stop - stops 3/4-finger gesture service");
|
||||||
std::puts("debug - logs raw output from input events taken from libinput");
|
std::puts("restart - stops then starts 3/4-finger gesture service");
|
||||||
std::puts("status - checks status of program and autostart");
|
std::puts("autostart - automatically run on startup (toggleable)");
|
||||||
|
std::puts("buffer - parses output of libinput debug-events");
|
||||||
|
std::puts("help - shows the help dialog");
|
||||||
|
std::puts("config - locates the config file");
|
||||||
|
std::puts("debug - logs raw output from input events taken from libinput");
|
||||||
|
std::puts("status - checks status of program and autostart");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,15 +21,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#include "../service/_index.hpp"
|
#include "../service/_index.hpp"
|
||||||
|
|
||||||
namespace comfortable_swipe::service
|
namespace comfortable_swipe
|
||||||
{
|
{
|
||||||
/**
|
namespace service
|
||||||
* Restarts the comfortable-swipe service.
|
|
||||||
*/
|
|
||||||
void restart()
|
|
||||||
{
|
{
|
||||||
comfortable_swipe::service::stop();
|
/**
|
||||||
comfortable_swipe::service::start();
|
* Restarts the comfortable-swipe service.
|
||||||
|
*/
|
||||||
|
void restart()
|
||||||
|
{
|
||||||
|
comfortable_swipe::service::stop();
|
||||||
|
comfortable_swipe::service::start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,39 +24,42 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include <cstdlib> // std::system
|
#include <cstdlib> // std::system
|
||||||
#include <unistd.h> // pipe, fork, perror, exit
|
#include <unistd.h> // pipe, fork, perror, exit
|
||||||
|
|
||||||
namespace comfortable_swipe::service
|
namespace comfortable_swipe
|
||||||
{
|
{
|
||||||
/**
|
namespace service
|
||||||
* Starts the comfortable-swipe service by buffering libinput debug-events.
|
|
||||||
* This method is deferred. Please refer to comfortable_swipe::service::buffer()
|
|
||||||
* for the technical implementation.
|
|
||||||
*/
|
|
||||||
void start()
|
|
||||||
{
|
{
|
||||||
std::ios::sync_with_stdio(false);
|
/**
|
||||||
std::cin.tie(0);
|
* Starts the comfortable-swipe service by buffering libinput debug-events.
|
||||||
std::cout.tie(0);
|
* This method is deferred. Please refer to comfortable_swipe::service::buffer()
|
||||||
std::cout.flush();
|
* for the technical implementation.
|
||||||
|
*/
|
||||||
|
void start()
|
||||||
|
{
|
||||||
|
std::ios::sync_with_stdio(false);
|
||||||
|
std::cin.tie(0);
|
||||||
|
std::cout.tie(0);
|
||||||
|
std::cout.flush();
|
||||||
|
|
||||||
// redirect stdout to stdin
|
// redirect stdout to stdin
|
||||||
int fd[2];
|
int fd[2];
|
||||||
pipe(fd); // create the pipes
|
pipe(fd); // create the pipes
|
||||||
|
|
||||||
int child;
|
int child;
|
||||||
if ((child = fork()) == -1) {
|
if ((child = fork()) == -1) {
|
||||||
perror("fork");
|
perror("fork");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (child) {
|
||||||
|
dup2(fd[1], STDOUT_FILENO);
|
||||||
|
comfortable_swipe::service::debug();
|
||||||
|
close(fd[0]);
|
||||||
|
} else {
|
||||||
|
dup2(fd[0], STDIN_FILENO);
|
||||||
|
comfortable_swipe::service::buffer();
|
||||||
|
close(fd[1]);
|
||||||
|
}
|
||||||
|
comfortable_swipe::service::stop();
|
||||||
}
|
}
|
||||||
if (child) {
|
|
||||||
dup2(fd[1], STDOUT_FILENO);
|
|
||||||
comfortable_swipe::service::debug();
|
|
||||||
close(fd[0]);
|
|
||||||
} else {
|
|
||||||
dup2(fd[0], STDIN_FILENO);
|
|
||||||
comfortable_swipe::service::buffer();
|
|
||||||
close(fd[1]);
|
|
||||||
}
|
|
||||||
comfortable_swipe::service::stop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,44 +30,47 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include <cstdio> // FILE, std::feof, std::fgets, std::printf
|
#include <cstdio> // FILE, std::feof, std::fgets, std::printf
|
||||||
#include <regex> // std::cmatch, std::regex, std::regex_match
|
#include <regex> // std::cmatch, std::regex, std::regex_match
|
||||||
|
|
||||||
namespace comfortable_swipe::service
|
namespace comfortable_swipe
|
||||||
{
|
{
|
||||||
/**
|
namespace service
|
||||||
* Prints the status of comfortable-swipe.
|
|
||||||
*/
|
|
||||||
void status()
|
|
||||||
{
|
{
|
||||||
// std::printf("autostart is %s\n", autostart_on ? "ON" : "OFF");
|
/**
|
||||||
|
* Prints the status of comfortable-swipe.
|
||||||
// check status of configuration file
|
*/
|
||||||
try
|
void status()
|
||||||
{
|
{
|
||||||
std::puts(COMFORTABLE_SWIPE_CONFIG);
|
// std::printf("autostart is %s\n", autostart_on ? "ON" : "OFF");
|
||||||
auto config = comfortable_swipe::util::read_config_file(COMFORTABLE_SWIPE_CONFIG);
|
|
||||||
// print threshold
|
|
||||||
if (config.count("threshold") > 0)
|
|
||||||
{
|
|
||||||
auto & threshold = config["threshold"];
|
|
||||||
// std::cmatch matches;
|
|
||||||
// bool ok = (std::regex_match(threshold.data(), matches, std::regex("^\\d+(?:\\.\\d+)??$")) != 0);
|
|
||||||
// print status of threshold
|
|
||||||
std::printf(" %9s = %s\n", "threshold", threshold.data()); // ok ? "VALID" : "INVALID"
|
|
||||||
}
|
|
||||||
else
|
|
||||||
std::printf(" %9s is OFF\n", "threshold");
|
|
||||||
|
|
||||||
// print swipe commands
|
// check status of configuration file
|
||||||
for (auto &command : comfortable_swipe::gesture::swipe_gesture::command_map)
|
try
|
||||||
{
|
{
|
||||||
if (config.count(command) > 0)
|
std::puts(COMFORTABLE_SWIPE_CONFIG);
|
||||||
std::printf(" %9s = %s\n", command, config[command].data());
|
auto config = comfortable_swipe::util::read_config_file(COMFORTABLE_SWIPE_CONFIG);
|
||||||
|
// print threshold
|
||||||
|
if (config.count("threshold") > 0)
|
||||||
|
{
|
||||||
|
auto & threshold = config["threshold"];
|
||||||
|
// std::cmatch matches;
|
||||||
|
// bool ok = (std::regex_match(threshold.data(), matches, std::regex("^\\d+(?:\\.\\d+)??$")) != 0);
|
||||||
|
// print status of threshold
|
||||||
|
std::printf(" %9s = %s\n", "threshold", threshold.data()); // ok ? "VALID" : "INVALID"
|
||||||
|
}
|
||||||
else
|
else
|
||||||
std::printf(" %9s NOT SET\n", command);
|
std::printf(" %9s is OFF\n", "threshold");
|
||||||
|
|
||||||
|
// print swipe commands
|
||||||
|
for (auto &command : comfortable_swipe::gesture::swipe_gesture::command_map)
|
||||||
|
{
|
||||||
|
if (config.count(command) > 0)
|
||||||
|
std::printf(" %9s = %s\n", command, config[command].data());
|
||||||
|
else
|
||||||
|
std::printf(" %9s NOT SET\n", command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const std::runtime_error& e)
|
||||||
|
{
|
||||||
|
std::printf("config error: %s\n", e.what());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (const std::runtime_error& e)
|
|
||||||
{
|
|
||||||
std::printf("config error: %s\n", e.what());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,41 +29,44 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include <cstdlib> // std::atoi
|
#include <cstdlib> // std::atoi
|
||||||
#include <cstdio> // FILE, std::feof, std::fgets
|
#include <cstdio> // FILE, std::feof, std::fgets
|
||||||
|
|
||||||
namespace comfortable_swipe::service
|
namespace comfortable_swipe
|
||||||
{
|
{
|
||||||
/**
|
namespace service
|
||||||
* Stops all comfortable-swipe instances.
|
|
||||||
*/
|
|
||||||
void stop()
|
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
// read all service names from process (pgrep)
|
* Stops all comfortable-swipe instances.
|
||||||
std::array<char, 128> buffer;
|
*/
|
||||||
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen("pgrep -f comfortable-swipe", "r"), pclose);
|
void stop()
|
||||||
|
|
||||||
// make sure pipe exists
|
|
||||||
if (!pipe)
|
|
||||||
throw std::runtime_error("stop command failed");
|
|
||||||
|
|
||||||
// buffer what to kill
|
|
||||||
std::string kill = "kill";
|
|
||||||
|
|
||||||
// read until end of line
|
|
||||||
while (!std::feof(pipe.get()))
|
|
||||||
{
|
{
|
||||||
if (std::fgets(buffer.data(), buffer.size(), pipe.get()) != NULL)
|
|
||||||
|
// read all service names from process (pgrep)
|
||||||
|
std::array<char, 128> buffer;
|
||||||
|
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen("pgrep -f comfortable-swipe", "r"), pclose);
|
||||||
|
|
||||||
|
// make sure pipe exists
|
||||||
|
if (!pipe)
|
||||||
|
throw std::runtime_error("stop command failed");
|
||||||
|
|
||||||
|
// buffer what to kill
|
||||||
|
std::string kill = "kill";
|
||||||
|
|
||||||
|
// read until end of line
|
||||||
|
while (!std::feof(pipe.get()))
|
||||||
{
|
{
|
||||||
int pid = std::atoi(buffer.data());
|
if (std::fgets(buffer.data(), buffer.size(), pipe.get()) != NULL)
|
||||||
if (pid != getpid())
|
|
||||||
{
|
{
|
||||||
kill += " ";
|
int pid = std::atoi(buffer.data());
|
||||||
kill += std::to_string(pid);
|
if (pid != getpid())
|
||||||
|
{
|
||||||
|
kill += " ";
|
||||||
|
kill += std::to_string(pid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// run "kill {pid1} {pid2}..."
|
// run "kill {pid1} {pid2}..."
|
||||||
(void) std::system(kill.data());
|
(void) std::system(kill.data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,14 +4,11 @@
|
|||||||
#include <map> // std::map
|
#include <map> // std::map
|
||||||
#include <string> // std::string
|
#include <string> // std::string
|
||||||
|
|
||||||
extern "C"
|
namespace comfortable_swipe
|
||||||
{
|
{
|
||||||
namespace comfortable_swipe
|
namespace util
|
||||||
{
|
{
|
||||||
namespace util
|
std::map<std::string, std::string> read_config_file(const char*);
|
||||||
{
|
|
||||||
std::map<std::string, std::string> read_config_file(const char*);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,82 +22,86 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include <map> // std::map
|
#include <map> // std::map
|
||||||
#include <string> // std::string
|
#include <string> // std::string
|
||||||
#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 <sstream> // std::ostringstream
|
||||||
#include <cstdlib> // exit
|
#include <cstdlib> // exit
|
||||||
#include <cctype> // std::isspace
|
#include <cctype> // std::isspace
|
||||||
#include <stdexcept> // std::runtime_error
|
#include <stdexcept> // std::runtime_error
|
||||||
|
|
||||||
namespace comfortable_swipe::util
|
namespace comfortable_swipe
|
||||||
{
|
{
|
||||||
/**
|
namespace util
|
||||||
* A utility method for reading 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> conf;
|
* A utility method for reading the config file.
|
||||||
std::ifstream fin(filename);
|
*
|
||||||
|
* @param filename (const char*) the path of the config file.
|
||||||
if (!fin.is_open())
|
*/
|
||||||
|
std::map<std::string, std::string> read_config_file(const char* filename)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("config file does not exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string line, token[2];
|
std::map<std::string, std::string> conf;
|
||||||
int line_number = 0;
|
std::ifstream fin(filename, std::ios::in);
|
||||||
|
|
||||||
while (std::getline(fin, line))
|
if (!fin.is_open())
|
||||||
{
|
|
||||||
++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
|
throw std::runtime_error("config file does not exist");
|
||||||
break;
|
}
|
||||||
if (line[i] == '=') // flag equal sign
|
|
||||||
|
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 (++equal_flag > 1)
|
if (line[i] == '#') // skip comments
|
||||||
|
break;
|
||||||
|
if (line[i] == '=') // flag equal sign
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
if (++equal_flag > 1)
|
||||||
stream << "error in conf file " << filename << std::endl;
|
{
|
||||||
stream << "multiple equal signs in line " << line_number << std::endl;
|
std::ostringstream stream;
|
||||||
throw std::runtime_error(stream.str());
|
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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!std::isspace(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)
|
||||||
{
|
{
|
||||||
// add to buffer
|
std::ostringstream stream;
|
||||||
token[equal_flag].push_back(line[i]);
|
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];
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore empty lines
|
return conf;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __COMFORTABLE_SWIPE__util_read_config_file__ */
|
#endif /* __COMFORTABLE_SWIPE__util_read_config_file__ */
|
||||||
|
|||||||
3
setup.py
3
setup.py
@ -49,9 +49,6 @@ try:
|
|||||||
COMFORTABLE_SWIPE_CONFIG='"{}"'.format(CONFIG)
|
COMFORTABLE_SWIPE_CONFIG='"{}"'.format(CONFIG)
|
||||||
)
|
)
|
||||||
|
|
||||||
# make sure to use gnu-gcc
|
|
||||||
os.putenv('CC', 'x86_64-linux-gnu-gcc')
|
|
||||||
|
|
||||||
# read C++ libraries for comfortable swipe
|
# read C++ libraries for comfortable swipe
|
||||||
extensions = [Extension(
|
extensions = [Extension(
|
||||||
name='{}.cpp.{}'.format(PYTHON_NAME, extension_name),
|
name='{}.cpp.{}'.format(PYTHON_NAME, extension_name),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user