Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/core/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ namespace lvh::detail {
return OperationStatus::success();
}

OperationStatus release_contact(std::int32_t /*contact_id*/) override {
OperationStatus release_contact(std::int32_t /*contact_id*/, PointerTransition /*transition*/) override {
return OperationStatus::success();
}

Expand All @@ -94,7 +94,7 @@ namespace lvh::detail {
return OperationStatus::success();
}

OperationStatus release_contact(std::int32_t /*contact_id*/) override {
OperationStatus release_contact(std::int32_t /*contact_id*/, PointerTransition /*transition*/) override {
return OperationStatus::success();
}

Expand Down
6 changes: 4 additions & 2 deletions src/core/backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,10 @@ namespace lvh::detail {
* @brief Release a touch contact.
*
* @param contact_id Consumer-stable contact identifier.
* @param transition Pointer transition used to remove the contact.
* @return Submit status.
*/
virtual OperationStatus release_contact(std::int32_t contact_id) = 0;
virtual OperationStatus release_contact(std::int32_t contact_id, PointerTransition transition) = 0;

/**
* @brief Get platform-visible nodes associated with this backend device.
Expand Down Expand Up @@ -236,9 +237,10 @@ namespace lvh::detail {
* @brief Release a trackpad contact.
*
* @param contact_id Consumer-stable contact identifier.
* @param transition Pointer transition used to remove the contact.
* @return Submit status.
*/
virtual OperationStatus release_contact(std::int32_t contact_id) = 0;
virtual OperationStatus release_contact(std::int32_t contact_id, PointerTransition transition) = 0;

/**
* @brief Submit a trackpad button transition.
Expand Down
52 changes: 50 additions & 2 deletions src/core/runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

// standard includes
#include <algorithm>
#include <cmath>
#include <memory>
#include <mutex>
#include <utility>
Expand Down Expand Up @@ -638,6 +639,19 @@ namespace lvh {
return submit({.kind = MouseEventKind::absolute_motion, .x = x, .y = y, .width = width, .height = height});
}

OperationStatus Mouse::move_absolute(float x, float y, std::int32_t width, std::int32_t height) {
return submit({
.kind = MouseEventKind::absolute_motion,
.x = static_cast<std::int32_t>(std::lround(x)),
.y = static_cast<std::int32_t>(std::lround(y)),
.absolute_x = x,
.absolute_y = y,
.has_fractional_absolute_coordinates = true,
.width = width,
.height = height,
});
}

OperationStatus Mouse::button(MouseButton button, bool pressed) {
MouseEvent event;
event.kind = MouseEventKind::button;
Expand Down Expand Up @@ -749,7 +763,41 @@ namespace lvh {
device_,
"touchscreen is closed",
[contact_id](auto &backend) {
return backend.release_contact(contact_id);
return backend.release_contact(contact_id, PointerTransition::release);
},
[contact_id](auto &device) {
device.last_contact.id = contact_id;
}
);
}

OperationStatus Touchscreen::cancel_contact(std::int32_t contact_id) {
if (contact_id < 0) {
return OperationStatus::failure(ErrorCode::invalid_argument, "touch contact id must not be negative");
}

return submit_touch_event(
device_,
"touchscreen is closed",
[contact_id](auto &backend) {
return backend.release_contact(contact_id, PointerTransition::cancel);
},
[contact_id](auto &device) {
device.last_contact.id = contact_id;
}
);
}

OperationStatus Touchscreen::leave_contact(std::int32_t contact_id) {
if (contact_id < 0) {
return OperationStatus::failure(ErrorCode::invalid_argument, "touch contact id must not be negative");
}

return submit_touch_event(
device_,
"touchscreen is closed",
[contact_id](auto &backend) {
return backend.release_contact(contact_id, PointerTransition::leave);
},
[contact_id](auto &device) {
device.last_contact.id = contact_id;
Expand Down Expand Up @@ -846,7 +894,7 @@ namespace lvh {
device_,
"trackpad is closed",
[contact_id](auto &backend) {
return backend.release_contact(contact_id);
return backend.release_contact(contact_id, PointerTransition::release);
},
[contact_id](auto &device) {
device.last_contact.id = contact_id;
Expand Down
27 changes: 27 additions & 0 deletions src/include/libvirtualhid/runtime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,17 @@ namespace lvh {
*/
OperationStatus move_absolute(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height);

/**
* @brief Submit absolute pointer movement with fractional coordinates.
*
* @param x Absolute X coordinate.
* @param y Absolute Y coordinate.
* @param width Width of the absolute coordinate space.
* @param height Height of the absolute coordinate space.
* @return Submit operation status.
*/
OperationStatus move_absolute(float x, float y, std::int32_t width, std::int32_t height);

/**
* @brief Submit a mouse button transition.
*
Expand Down Expand Up @@ -554,6 +565,22 @@ namespace lvh {
*/
OperationStatus release_contact(std::int32_t contact_id);

/**
* @brief Cancel a touch contact.
*
* @param contact_id Consumer-stable contact identifier.
* @return Submit operation status.
*/
OperationStatus cancel_contact(std::int32_t contact_id);

/**
* @brief Mark a touch contact as leaving range.
*
* @param contact_id Consumer-stable contact identifier.
* @return Submit operation status.
*/
OperationStatus leave_contact(std::int32_t contact_id);

/**
* @brief Get the most recently submitted touch contact.
*
Expand Down
95 changes: 95 additions & 0 deletions src/include/libvirtualhid/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,21 @@ namespace lvh {
* @brief Whether the key is pressed.
*/
bool pressed = false;

/**
* @brief Optional platform scan code to submit instead of translating `key_code`.
*/
std::uint16_t scan_code = 0;

/**
* @brief Whether `key_code` is normalized to the Windows US English keyboard layout.
*/
bool uses_normalized_key_code = false;

/**
* @brief Whether the backend should prefer a native scan-code translation when `scan_code` is not provided.
*/
bool prefer_native_scan_code = false;
};

/**
Expand All @@ -731,6 +746,41 @@ namespace lvh {
std::string text;
};

/**
* @brief Pixel viewport used by backends that need screen-local pointer coordinates.
*/
struct PointerViewport {
/**
* @brief Horizontal viewport offset in pixels.
*/
std::int32_t offset_x = 0;

/**
* @brief Vertical viewport offset in pixels.
*/
std::int32_t offset_y = 0;

/**
* @brief Viewport width in pixels, or `0` to use the platform default.
*/
std::int32_t width = 0;

/**
* @brief Viewport height in pixels, or `0` to use the platform default.
*/
std::int32_t height = 0;
};

/**
* @brief Pointer state transition requested for contact-capable devices.
*/
enum class PointerTransition : std::uint8_t {
update, ///< Pointer is in range, with contact state described by the event.
release, ///< Pointer contact ended normally.
cancel, ///< Pointer contact was canceled.
leave, ///< Pointer left range without an in-contact release.
};

/**
* @brief Mouse buttons accepted by the mouse event model.
*/
Expand Down Expand Up @@ -772,6 +822,21 @@ namespace lvh {
*/
std::int32_t y = 0;

/**
* @brief Fractional absolute X coordinate used when `has_fractional_absolute_coordinates` is true.
*/
float absolute_x = 0.0F;

/**
* @brief Fractional absolute Y coordinate used when `has_fractional_absolute_coordinates` is true.
*/
float absolute_y = 0.0F;

/**
* @brief Whether absolute motion should use `absolute_x` and `absolute_y` instead of integer `x` and `y`.
*/
bool has_fractional_absolute_coordinates = false;

/**
* @brief Width of the absolute coordinate space.
*/
Expand Down Expand Up @@ -826,6 +891,26 @@ namespace lvh {
* @brief Contact orientation in degrees, typically in the inclusive range `[-90, 90]`.
*/
std::int32_t orientation = 0;

/**
* @brief Whether the contact is touching the surface.
*/
bool touching = true;

/**
* @brief Pixel viewport that receives the contact.
*/
PointerViewport viewport;

/**
* @brief Contact major-axis size in viewport pixels, or `0.0` when unknown.
*/
float contact_major_axis = 0.0F;

/**
* @brief Contact minor-axis size in viewport pixels, or `0.0` when unknown.
*/
float contact_minor_axis = 0.0F;
};

/**
Expand Down Expand Up @@ -888,6 +973,16 @@ namespace lvh {
* @brief Y-axis tilt in degrees.
*/
float tilt_y = 0.0F;

/**
* @brief Pointer transition represented by this tool state.
*/
PointerTransition transition = PointerTransition::update;

/**
* @brief Pixel viewport that receives the pen tool.
*/
PointerViewport viewport;
};

/**
Expand Down
4 changes: 2 additions & 2 deletions src/platform/linux/uhid_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1759,7 +1759,7 @@ namespace lvh::detail {
return place_touch_contact(contact, false);
}

OperationStatus release_contact(std::int32_t contact_id) override {
OperationStatus release_contact(std::int32_t contact_id, PointerTransition /*transition*/) override {
return release_touch_contact(contact_id, false);
}

Expand Down Expand Up @@ -1792,7 +1792,7 @@ namespace lvh::detail {
return place_touch_contact(contact, true);
}

OperationStatus release_contact(std::int32_t contact_id) override {
OperationStatus release_contact(std::int32_t contact_id, PointerTransition /*transition*/) override {
return release_touch_contact(contact_id, true);
}

Expand Down
Loading
Loading