|
|
|
|
@@ -72,18 +72,18 @@ static GHOST_IWindow *get_window(struct wl_surface *surface);
|
|
|
|
|
#define BTN_STYLUS3 0x149
|
|
|
|
|
|
|
|
|
|
struct buffer_t {
|
|
|
|
|
void *data;
|
|
|
|
|
size_t size;
|
|
|
|
|
void *data = nullptr;
|
|
|
|
|
size_t size = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct cursor_t {
|
|
|
|
|
bool visible;
|
|
|
|
|
struct wl_surface *surface = nullptr;
|
|
|
|
|
struct wl_buffer *buffer;
|
|
|
|
|
struct wl_cursor_image image;
|
|
|
|
|
bool visible = false;
|
|
|
|
|
struct wl_surface *wl_surface = nullptr;
|
|
|
|
|
struct wl_buffer *wl_buffer = nullptr;
|
|
|
|
|
struct wl_cursor_image wl_image = {0};
|
|
|
|
|
struct wl_cursor_theme *wl_theme = nullptr;
|
|
|
|
|
struct buffer_t *file_buffer = nullptr;
|
|
|
|
|
struct wl_cursor_theme *theme = nullptr;
|
|
|
|
|
int size;
|
|
|
|
|
int size = 0;
|
|
|
|
|
std::string theme_name;
|
|
|
|
|
/** Outputs on which the cursor is visible. */
|
|
|
|
|
std::unordered_set<const output_t *> outputs;
|
|
|
|
|
@@ -96,27 +96,27 @@ struct cursor_t {
|
|
|
|
|
* Since are no API's to access properties of the tool, store the values here.
|
|
|
|
|
*/
|
|
|
|
|
struct tablet_tool_input_t {
|
|
|
|
|
struct input_t *input;
|
|
|
|
|
struct wl_surface *cursor_surface;
|
|
|
|
|
struct input_t *input = nullptr;
|
|
|
|
|
struct wl_surface *cursor_surface = nullptr;
|
|
|
|
|
|
|
|
|
|
GHOST_TabletData data;
|
|
|
|
|
GHOST_TabletData data = GHOST_TABLET_DATA_NONE;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct data_offer_t {
|
|
|
|
|
std::unordered_set<std::string> types;
|
|
|
|
|
uint32_t source_actions;
|
|
|
|
|
uint32_t dnd_action;
|
|
|
|
|
struct wl_data_offer *id;
|
|
|
|
|
std::atomic<bool> in_use;
|
|
|
|
|
uint32_t source_actions = 0;
|
|
|
|
|
uint32_t dnd_action = 0;
|
|
|
|
|
struct wl_data_offer *id = nullptr;
|
|
|
|
|
std::atomic<bool> in_use = false;
|
|
|
|
|
struct {
|
|
|
|
|
/** Compatible with #input_t.xy coordinates. */
|
|
|
|
|
wl_fixed_t xy[2];
|
|
|
|
|
wl_fixed_t xy[2] = {0, 0};
|
|
|
|
|
} dnd;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct data_source_t {
|
|
|
|
|
struct wl_data_source *data_source;
|
|
|
|
|
char *buffer_out;
|
|
|
|
|
struct wl_data_source *data_source = nullptr;
|
|
|
|
|
char *buffer_out = nullptr;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct key_repeat_payload_t {
|
|
|
|
|
@@ -130,9 +130,9 @@ struct input_t {
|
|
|
|
|
GHOST_SystemWayland *system;
|
|
|
|
|
|
|
|
|
|
std::string name;
|
|
|
|
|
struct wl_seat *seat;
|
|
|
|
|
struct wl_pointer *pointer = nullptr;
|
|
|
|
|
struct wl_keyboard *keyboard = nullptr;
|
|
|
|
|
struct wl_seat *wl_seat;
|
|
|
|
|
struct wl_pointer *wl_pointer = nullptr;
|
|
|
|
|
struct wl_keyboard *wl_keyboard = nullptr;
|
|
|
|
|
struct zwp_tablet_seat_v2 *tablet_seat = nullptr;
|
|
|
|
|
|
|
|
|
|
/** All currently active tablet tools (needed for changing the cursor). */
|
|
|
|
|
@@ -157,15 +157,15 @@ struct input_t {
|
|
|
|
|
* \endocde
|
|
|
|
|
*/
|
|
|
|
|
wl_fixed_t xy[2];
|
|
|
|
|
GHOST_Buttons buttons;
|
|
|
|
|
GHOST_Buttons buttons = GHOST_Buttons();
|
|
|
|
|
struct cursor_t cursor;
|
|
|
|
|
|
|
|
|
|
struct zwp_relative_pointer_v1 *relative_pointer;
|
|
|
|
|
struct zwp_locked_pointer_v1 *locked_pointer;
|
|
|
|
|
struct zwp_confined_pointer_v1 *confined_pointer;
|
|
|
|
|
struct zwp_relative_pointer_v1 *relative_pointer = nullptr;
|
|
|
|
|
struct zwp_locked_pointer_v1 *locked_pointer = nullptr;
|
|
|
|
|
struct zwp_confined_pointer_v1 *confined_pointer = nullptr;
|
|
|
|
|
|
|
|
|
|
struct xkb_context *xkb_context;
|
|
|
|
|
struct xkb_state *xkb_state;
|
|
|
|
|
struct xkb_context *xkb_context = nullptr;
|
|
|
|
|
struct xkb_state *xkb_state = nullptr;
|
|
|
|
|
struct {
|
|
|
|
|
/** Key repetition in character per second. */
|
|
|
|
|
int32_t rate;
|
|
|
|
|
@@ -182,14 +182,14 @@ struct input_t {
|
|
|
|
|
|
|
|
|
|
struct wl_data_device *data_device = nullptr;
|
|
|
|
|
/** Drag & Drop. */
|
|
|
|
|
struct data_offer_t *data_offer_dnd;
|
|
|
|
|
struct data_offer_t *data_offer_dnd = nullptr;
|
|
|
|
|
std::mutex data_offer_dnd_mutex;
|
|
|
|
|
|
|
|
|
|
/** Copy & Paste. */
|
|
|
|
|
struct data_offer_t *data_offer_copy_paste;
|
|
|
|
|
struct data_offer_t *data_offer_copy_paste = nullptr;
|
|
|
|
|
std::mutex data_offer_copy_paste_mutex;
|
|
|
|
|
|
|
|
|
|
struct data_source_t *data_source;
|
|
|
|
|
struct data_source_t *data_source = nullptr;
|
|
|
|
|
std::mutex data_source_mutex;
|
|
|
|
|
|
|
|
|
|
/** Last device that was active. */
|
|
|
|
|
@@ -197,9 +197,9 @@ struct input_t {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct display_t {
|
|
|
|
|
GHOST_SystemWayland *system;
|
|
|
|
|
GHOST_SystemWayland *system = nullptr;
|
|
|
|
|
|
|
|
|
|
struct wl_display *display;
|
|
|
|
|
struct wl_display *display = nullptr;
|
|
|
|
|
struct wl_compositor *compositor = nullptr;
|
|
|
|
|
struct xdg_wm_base *xdg_shell = nullptr;
|
|
|
|
|
struct zxdg_decoration_manager_v1 *xdg_decoration_manager = nullptr;
|
|
|
|
|
@@ -209,7 +209,7 @@ struct display_t {
|
|
|
|
|
std::vector<input_t *> inputs;
|
|
|
|
|
struct {
|
|
|
|
|
std::string theme;
|
|
|
|
|
int size;
|
|
|
|
|
int size = 0;
|
|
|
|
|
} cursor;
|
|
|
|
|
struct wl_data_device_manager *data_device_manager = nullptr;
|
|
|
|
|
struct zwp_tablet_manager_v2 *tablet_manager = nullptr;
|
|
|
|
|
@@ -259,7 +259,7 @@ static void display_destroy(display_t *d)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (output_t *output : d->outputs) {
|
|
|
|
|
wl_output_destroy(output->output);
|
|
|
|
|
wl_output_destroy(output->wl_output);
|
|
|
|
|
delete output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -278,28 +278,28 @@ static void display_destroy(display_t *d)
|
|
|
|
|
if (input->data_device) {
|
|
|
|
|
wl_data_device_release(input->data_device);
|
|
|
|
|
}
|
|
|
|
|
if (input->pointer) {
|
|
|
|
|
if (input->wl_pointer) {
|
|
|
|
|
if (input->cursor.file_buffer) {
|
|
|
|
|
munmap(input->cursor.file_buffer->data, input->cursor.file_buffer->size);
|
|
|
|
|
delete input->cursor.file_buffer;
|
|
|
|
|
}
|
|
|
|
|
if (input->cursor.surface) {
|
|
|
|
|
wl_surface_destroy(input->cursor.surface);
|
|
|
|
|
if (input->cursor.wl_surface) {
|
|
|
|
|
wl_surface_destroy(input->cursor.wl_surface);
|
|
|
|
|
}
|
|
|
|
|
if (input->cursor.theme) {
|
|
|
|
|
wl_cursor_theme_destroy(input->cursor.theme);
|
|
|
|
|
if (input->cursor.wl_theme) {
|
|
|
|
|
wl_cursor_theme_destroy(input->cursor.wl_theme);
|
|
|
|
|
}
|
|
|
|
|
if (input->pointer) {
|
|
|
|
|
wl_pointer_destroy(input->pointer);
|
|
|
|
|
if (input->wl_pointer) {
|
|
|
|
|
wl_pointer_destroy(input->wl_pointer);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (input->keyboard) {
|
|
|
|
|
if (input->wl_keyboard) {
|
|
|
|
|
if (input->key_repeat.timer) {
|
|
|
|
|
delete static_cast<key_repeat_payload_t *>(input->key_repeat.timer->getUserData());
|
|
|
|
|
input->system->removeTimer(input->key_repeat.timer);
|
|
|
|
|
input->key_repeat.timer = nullptr;
|
|
|
|
|
}
|
|
|
|
|
wl_keyboard_destroy(input->keyboard);
|
|
|
|
|
wl_keyboard_destroy(input->wl_keyboard);
|
|
|
|
|
}
|
|
|
|
|
if (input->xkb_state) {
|
|
|
|
|
xkb_state_unref(input->xkb_state);
|
|
|
|
|
@@ -307,7 +307,7 @@ static void display_destroy(display_t *d)
|
|
|
|
|
if (input->xkb_context) {
|
|
|
|
|
xkb_context_unref(input->xkb_context);
|
|
|
|
|
}
|
|
|
|
|
wl_seat_destroy(input->seat);
|
|
|
|
|
wl_seat_destroy(input->wl_seat);
|
|
|
|
|
delete input;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -553,7 +553,7 @@ static const std::vector<std::string> mime_send = {
|
|
|
|
|
* an event is received from the compositor.
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void relative_pointer_relative_motion(
|
|
|
|
|
static void relative_pointer_handle_relative_motion(
|
|
|
|
|
void *data,
|
|
|
|
|
struct zwp_relative_pointer_v1 * /*zwp_relative_pointer_v1*/,
|
|
|
|
|
uint32_t /*utime_hi*/,
|
|
|
|
|
@@ -581,7 +581,7 @@ static void relative_pointer_relative_motion(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const zwp_relative_pointer_v1_listener relative_pointer_listener = {
|
|
|
|
|
relative_pointer_relative_motion,
|
|
|
|
|
relative_pointer_handle_relative_motion,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -646,17 +646,17 @@ static std::string read_pipe(data_offer_t *data_offer,
|
|
|
|
|
* Sent when a target accepts pointer_focus or motion events. If
|
|
|
|
|
* a target does not accept any of the offered types, type is nullptr.
|
|
|
|
|
*/
|
|
|
|
|
static void data_source_target(void * /*data*/,
|
|
|
|
|
struct wl_data_source * /*wl_data_source*/,
|
|
|
|
|
const char * /*mime_type*/)
|
|
|
|
|
static void data_source_handle_target(void * /*data*/,
|
|
|
|
|
struct wl_data_source * /*wl_data_source*/,
|
|
|
|
|
const char * /*mime_type*/)
|
|
|
|
|
{
|
|
|
|
|
/* pass */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void data_source_send(void *data,
|
|
|
|
|
struct wl_data_source * /*wl_data_source*/,
|
|
|
|
|
const char * /*mime_type*/,
|
|
|
|
|
int32_t fd)
|
|
|
|
|
static void data_source_handle_send(void *data,
|
|
|
|
|
struct wl_data_source * /*wl_data_source*/,
|
|
|
|
|
const char * /*mime_type*/,
|
|
|
|
|
int32_t fd)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
std::lock_guard lock{input->data_source_mutex};
|
|
|
|
|
@@ -668,7 +668,7 @@ static void data_source_send(void *data,
|
|
|
|
|
close(fd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void data_source_cancelled(void * /*data*/, struct wl_data_source *wl_data_source)
|
|
|
|
|
static void data_source_handle_cancelled(void * /*data*/, struct wl_data_source *wl_data_source)
|
|
|
|
|
{
|
|
|
|
|
wl_data_source_destroy(wl_data_source);
|
|
|
|
|
}
|
|
|
|
|
@@ -680,8 +680,8 @@ static void data_source_cancelled(void * /*data*/, struct wl_data_source *wl_dat
|
|
|
|
|
* indicate acceptance, #wl_data_source.cancelled may still be
|
|
|
|
|
* emitted afterwards if the drop destination does not accept any mime type.
|
|
|
|
|
*/
|
|
|
|
|
static void data_source_dnd_drop_performed(void * /*data*/,
|
|
|
|
|
struct wl_data_source * /*wl_data_source*/)
|
|
|
|
|
static void data_source_handle_dnd_drop_performed(void * /*data*/,
|
|
|
|
|
struct wl_data_source * /*wl_data_source*/)
|
|
|
|
|
{
|
|
|
|
|
/* pass */
|
|
|
|
|
}
|
|
|
|
|
@@ -693,7 +693,8 @@ static void data_source_dnd_drop_performed(void * /*data*/,
|
|
|
|
|
* source, so the client is now free to destroy this data source
|
|
|
|
|
* and free all associated data.
|
|
|
|
|
*/
|
|
|
|
|
static void data_source_dnd_finished(void * /*data*/, struct wl_data_source * /*wl_data_source*/)
|
|
|
|
|
static void data_source_handle_dnd_finished(void * /*data*/,
|
|
|
|
|
struct wl_data_source * /*wl_data_source*/)
|
|
|
|
|
{
|
|
|
|
|
/* pass */
|
|
|
|
|
}
|
|
|
|
|
@@ -705,20 +706,20 @@ static void data_source_dnd_finished(void * /*data*/, struct wl_data_source * /*
|
|
|
|
|
* after matching the source/destination side actions. Only one
|
|
|
|
|
* action (or none) will be offered here.
|
|
|
|
|
*/
|
|
|
|
|
static void data_source_action(void * /*data*/,
|
|
|
|
|
struct wl_data_source * /*wl_data_source*/,
|
|
|
|
|
uint32_t /*dnd_action*/)
|
|
|
|
|
static void data_source_handle_action(void * /*data*/,
|
|
|
|
|
struct wl_data_source * /*wl_data_source*/,
|
|
|
|
|
uint32_t /*dnd_action*/)
|
|
|
|
|
{
|
|
|
|
|
/* pass */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct wl_data_source_listener data_source_listener = {
|
|
|
|
|
data_source_target,
|
|
|
|
|
data_source_send,
|
|
|
|
|
data_source_cancelled,
|
|
|
|
|
data_source_dnd_drop_performed,
|
|
|
|
|
data_source_dnd_finished,
|
|
|
|
|
data_source_action,
|
|
|
|
|
data_source_handle_target,
|
|
|
|
|
data_source_handle_send,
|
|
|
|
|
data_source_handle_cancelled,
|
|
|
|
|
data_source_handle_dnd_drop_performed,
|
|
|
|
|
data_source_handle_dnd_finished,
|
|
|
|
|
data_source_handle_action,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -727,31 +728,31 @@ static const struct wl_data_source_listener data_source_listener = {
|
|
|
|
|
/** \name Listener (Data Offer), #wl_data_offer_listener
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void data_offer_offer(void *data,
|
|
|
|
|
struct wl_data_offer * /*wl_data_offer*/,
|
|
|
|
|
const char *mime_type)
|
|
|
|
|
static void data_offer_handle_offer(void *data,
|
|
|
|
|
struct wl_data_offer * /*wl_data_offer*/,
|
|
|
|
|
const char *mime_type)
|
|
|
|
|
{
|
|
|
|
|
static_cast<data_offer_t *>(data)->types.insert(mime_type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void data_offer_source_actions(void *data,
|
|
|
|
|
struct wl_data_offer * /*wl_data_offer*/,
|
|
|
|
|
uint32_t source_actions)
|
|
|
|
|
static void data_offer_handle_source_actions(void *data,
|
|
|
|
|
struct wl_data_offer * /*wl_data_offer*/,
|
|
|
|
|
uint32_t source_actions)
|
|
|
|
|
{
|
|
|
|
|
static_cast<data_offer_t *>(data)->source_actions = source_actions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void data_offer_action(void *data,
|
|
|
|
|
struct wl_data_offer * /*wl_data_offer*/,
|
|
|
|
|
uint32_t dnd_action)
|
|
|
|
|
static void data_offer_handle_action(void *data,
|
|
|
|
|
struct wl_data_offer * /*wl_data_offer*/,
|
|
|
|
|
uint32_t dnd_action)
|
|
|
|
|
{
|
|
|
|
|
static_cast<data_offer_t *>(data)->dnd_action = dnd_action;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct wl_data_offer_listener data_offer_listener = {
|
|
|
|
|
data_offer_offer,
|
|
|
|
|
data_offer_source_actions,
|
|
|
|
|
data_offer_action,
|
|
|
|
|
data_offer_handle_offer,
|
|
|
|
|
data_offer_handle_source_actions,
|
|
|
|
|
data_offer_handle_action,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -760,22 +761,22 @@ static const struct wl_data_offer_listener data_offer_listener = {
|
|
|
|
|
/** \name Listener (Data Device), #wl_data_device_listener
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void data_device_data_offer(void * /*data*/,
|
|
|
|
|
struct wl_data_device * /*wl_data_device*/,
|
|
|
|
|
struct wl_data_offer *id)
|
|
|
|
|
static void data_device_handle_data_offer(void * /*data*/,
|
|
|
|
|
struct wl_data_device * /*wl_data_device*/,
|
|
|
|
|
struct wl_data_offer *id)
|
|
|
|
|
{
|
|
|
|
|
data_offer_t *data_offer = new data_offer_t;
|
|
|
|
|
data_offer->id = id;
|
|
|
|
|
wl_data_offer_add_listener(id, &data_offer_listener, data_offer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void data_device_enter(void *data,
|
|
|
|
|
struct wl_data_device * /*wl_data_device*/,
|
|
|
|
|
uint32_t serial,
|
|
|
|
|
struct wl_surface *surface,
|
|
|
|
|
wl_fixed_t x,
|
|
|
|
|
wl_fixed_t y,
|
|
|
|
|
struct wl_data_offer *id)
|
|
|
|
|
static void data_device_handle_enter(void *data,
|
|
|
|
|
struct wl_data_device * /*wl_data_device*/,
|
|
|
|
|
uint32_t serial,
|
|
|
|
|
struct wl_surface *surface,
|
|
|
|
|
wl_fixed_t x,
|
|
|
|
|
wl_fixed_t y,
|
|
|
|
|
struct wl_data_offer *id)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
std::lock_guard lock{input->data_offer_dnd_mutex};
|
|
|
|
|
@@ -800,7 +801,7 @@ static void data_device_enter(void *data,
|
|
|
|
|
dnd_events(input, GHOST_kEventDraggingEntered);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void data_device_leave(void *data, struct wl_data_device * /*wl_data_device*/)
|
|
|
|
|
static void data_device_handle_leave(void *data, struct wl_data_device * /*wl_data_device*/)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
std::lock_guard lock{input->data_offer_dnd_mutex};
|
|
|
|
|
@@ -815,11 +816,11 @@ static void data_device_leave(void *data, struct wl_data_device * /*wl_data_devi
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void data_device_motion(void *data,
|
|
|
|
|
struct wl_data_device * /*wl_data_device*/,
|
|
|
|
|
uint32_t /*time*/,
|
|
|
|
|
wl_fixed_t x,
|
|
|
|
|
wl_fixed_t y)
|
|
|
|
|
static void data_device_handle_motion(void *data,
|
|
|
|
|
struct wl_data_device * /*wl_data_device*/,
|
|
|
|
|
uint32_t /*time*/,
|
|
|
|
|
wl_fixed_t x,
|
|
|
|
|
wl_fixed_t y)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
std::lock_guard lock{input->data_offer_dnd_mutex};
|
|
|
|
|
@@ -830,7 +831,7 @@ static void data_device_motion(void *data,
|
|
|
|
|
dnd_events(input, GHOST_kEventDraggingUpdated);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void data_device_drop(void *data, struct wl_data_device * /*wl_data_device*/)
|
|
|
|
|
static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_data_device*/)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
std::lock_guard lock{input->data_offer_dnd_mutex};
|
|
|
|
|
@@ -842,10 +843,10 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
|
|
|
|
|
data_offer->types.begin(),
|
|
|
|
|
data_offer->types.end());
|
|
|
|
|
|
|
|
|
|
auto read_uris = [](input_t *const input,
|
|
|
|
|
data_offer_t *data_offer,
|
|
|
|
|
wl_surface *surface,
|
|
|
|
|
const std::string mime_receive) {
|
|
|
|
|
auto read_uris_fn = [](input_t *const input,
|
|
|
|
|
data_offer_t *data_offer,
|
|
|
|
|
wl_surface *surface,
|
|
|
|
|
const std::string mime_receive) {
|
|
|
|
|
const wl_fixed_t xy[2] = {data_offer->dnd.xy[0], data_offer->dnd.xy[1]};
|
|
|
|
|
|
|
|
|
|
const std::string data = read_pipe(data_offer, mime_receive, nullptr);
|
|
|
|
|
@@ -907,13 +908,13 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
|
|
|
|
|
|
|
|
|
|
/* Pass in `input->focus_dnd` instead of accessing it from `input` since the leave callback
|
|
|
|
|
* (#data_device_leave) will clear the value once this function starts. */
|
|
|
|
|
std::thread read_thread(read_uris, input, data_offer, input->focus_dnd, mime_receive);
|
|
|
|
|
std::thread read_thread(read_uris_fn, input, data_offer, input->focus_dnd, mime_receive);
|
|
|
|
|
read_thread.detach();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void data_device_selection(void *data,
|
|
|
|
|
struct wl_data_device * /*wl_data_device*/,
|
|
|
|
|
struct wl_data_offer *id)
|
|
|
|
|
static void data_device_handle_selection(void *data,
|
|
|
|
|
struct wl_data_device * /*wl_data_device*/,
|
|
|
|
|
struct wl_data_offer *id)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
|
|
|
|
|
@@ -936,7 +937,7 @@ static void data_device_selection(void *data,
|
|
|
|
|
data_offer = static_cast<data_offer_t *>(wl_data_offer_get_user_data(id));
|
|
|
|
|
input->data_offer_copy_paste = data_offer;
|
|
|
|
|
|
|
|
|
|
auto read_selection = [](input_t *input) {
|
|
|
|
|
auto read_selection_fn = [](input_t *input) {
|
|
|
|
|
GHOST_SystemWayland *const system = input->system;
|
|
|
|
|
input->data_offer_copy_paste_mutex.lock();
|
|
|
|
|
|
|
|
|
|
@@ -957,17 +958,39 @@ static void data_device_selection(void *data,
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::thread read_thread(read_selection, input);
|
|
|
|
|
std::thread read_thread(read_selection_fn, input);
|
|
|
|
|
read_thread.detach();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct wl_data_device_listener data_device_listener = {
|
|
|
|
|
data_device_data_offer,
|
|
|
|
|
data_device_enter,
|
|
|
|
|
data_device_leave,
|
|
|
|
|
data_device_motion,
|
|
|
|
|
data_device_drop,
|
|
|
|
|
data_device_selection,
|
|
|
|
|
data_device_handle_data_offer,
|
|
|
|
|
data_device_handle_enter,
|
|
|
|
|
data_device_handle_leave,
|
|
|
|
|
data_device_handle_motion,
|
|
|
|
|
data_device_handle_drop,
|
|
|
|
|
data_device_handle_selection,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Listener (Buffer), #wl_buffer_listener
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void cursor_buffer_handle_release(void *data, struct wl_buffer *wl_buffer)
|
|
|
|
|
{
|
|
|
|
|
cursor_t *cursor = static_cast<cursor_t *>(data);
|
|
|
|
|
|
|
|
|
|
wl_buffer_destroy(wl_buffer);
|
|
|
|
|
|
|
|
|
|
if (wl_buffer == cursor->wl_buffer) {
|
|
|
|
|
/* the mapped buffer was from a custom cursor */
|
|
|
|
|
cursor->wl_buffer = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const struct wl_buffer_listener cursor_buffer_listener = {
|
|
|
|
|
cursor_buffer_handle_release,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -976,22 +999,6 @@ static const struct wl_data_device_listener data_device_listener = {
|
|
|
|
|
/** \name Listener (Surface), #wl_surface_listener
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void cursor_buffer_release(void *data, struct wl_buffer *wl_buffer)
|
|
|
|
|
{
|
|
|
|
|
cursor_t *cursor = static_cast<cursor_t *>(data);
|
|
|
|
|
|
|
|
|
|
wl_buffer_destroy(wl_buffer);
|
|
|
|
|
|
|
|
|
|
if (wl_buffer == cursor->buffer) {
|
|
|
|
|
/* the mapped buffer was from a custom cursor */
|
|
|
|
|
cursor->buffer = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const struct wl_buffer_listener cursor_buffer_listener = {
|
|
|
|
|
cursor_buffer_release,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static GHOST_IWindow *get_window(struct wl_surface *surface)
|
|
|
|
|
{
|
|
|
|
|
if (!surface) {
|
|
|
|
|
@@ -1017,34 +1024,34 @@ static bool update_cursor_scale(cursor_t &cursor, wl_shm *shm)
|
|
|
|
|
|
|
|
|
|
if (scale > 0 && cursor.scale != scale) {
|
|
|
|
|
cursor.scale = scale;
|
|
|
|
|
wl_surface_set_buffer_scale(cursor.surface, scale);
|
|
|
|
|
wl_cursor_theme_destroy(cursor.theme);
|
|
|
|
|
cursor.theme = wl_cursor_theme_load(cursor.theme_name.c_str(), scale * cursor.size, shm);
|
|
|
|
|
wl_surface_set_buffer_scale(cursor.wl_surface, scale);
|
|
|
|
|
wl_cursor_theme_destroy(cursor.wl_theme);
|
|
|
|
|
cursor.wl_theme = wl_cursor_theme_load(cursor.theme_name.c_str(), scale * cursor.size, shm);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void cursor_surface_enter(void *data,
|
|
|
|
|
struct wl_surface * /*wl_surface*/,
|
|
|
|
|
struct wl_output *output)
|
|
|
|
|
static void cursor_surface_handle_enter(void *data,
|
|
|
|
|
struct wl_surface * /*wl_surface*/,
|
|
|
|
|
struct wl_output *output)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
for (const output_t *reg_output : input->system->outputs()) {
|
|
|
|
|
if (reg_output->output == output) {
|
|
|
|
|
if (reg_output->wl_output == output) {
|
|
|
|
|
input->cursor.outputs.insert(reg_output);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
update_cursor_scale(input->cursor, input->system->shm());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void cursor_surface_leave(void *data,
|
|
|
|
|
struct wl_surface * /*wl_surface*/,
|
|
|
|
|
struct wl_output *output)
|
|
|
|
|
static void cursor_surface_handle_leave(void *data,
|
|
|
|
|
struct wl_surface * /*wl_surface*/,
|
|
|
|
|
struct wl_output *output)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
for (const output_t *reg_output : input->system->outputs()) {
|
|
|
|
|
if (reg_output->output == output) {
|
|
|
|
|
if (reg_output->wl_output == output) {
|
|
|
|
|
input->cursor.outputs.erase(reg_output);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -1052,8 +1059,8 @@ static void cursor_surface_leave(void *data,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct wl_surface_listener cursor_surface_listener = {
|
|
|
|
|
cursor_surface_enter,
|
|
|
|
|
cursor_surface_leave,
|
|
|
|
|
cursor_surface_handle_enter,
|
|
|
|
|
cursor_surface_handle_leave,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -1062,12 +1069,12 @@ struct wl_surface_listener cursor_surface_listener = {
|
|
|
|
|
/** \name Listener (Pointer), #wl_pointer_listener
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void pointer_enter(void *data,
|
|
|
|
|
struct wl_pointer * /*wl_pointer*/,
|
|
|
|
|
uint32_t serial,
|
|
|
|
|
struct wl_surface *surface,
|
|
|
|
|
wl_fixed_t surface_x,
|
|
|
|
|
wl_fixed_t surface_y)
|
|
|
|
|
static void pointer_handle_enter(void *data,
|
|
|
|
|
struct wl_pointer * /*wl_pointer*/,
|
|
|
|
|
uint32_t serial,
|
|
|
|
|
struct wl_surface *surface,
|
|
|
|
|
wl_fixed_t surface_x,
|
|
|
|
|
wl_fixed_t surface_y)
|
|
|
|
|
{
|
|
|
|
|
GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(get_window(surface));
|
|
|
|
|
|
|
|
|
|
@@ -1095,10 +1102,10 @@ static void pointer_enter(void *data,
|
|
|
|
|
GHOST_TABLET_DATA_NONE));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void pointer_leave(void *data,
|
|
|
|
|
struct wl_pointer * /*wl_pointer*/,
|
|
|
|
|
uint32_t /*serial*/,
|
|
|
|
|
struct wl_surface *surface)
|
|
|
|
|
static void pointer_handle_leave(void *data,
|
|
|
|
|
struct wl_pointer * /*wl_pointer*/,
|
|
|
|
|
uint32_t /*serial*/,
|
|
|
|
|
struct wl_surface *surface)
|
|
|
|
|
{
|
|
|
|
|
GHOST_IWindow *win = get_window(surface);
|
|
|
|
|
|
|
|
|
|
@@ -1110,11 +1117,11 @@ static void pointer_leave(void *data,
|
|
|
|
|
static_cast<GHOST_WindowWayland *>(win)->deactivate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void pointer_motion(void *data,
|
|
|
|
|
struct wl_pointer * /*wl_pointer*/,
|
|
|
|
|
uint32_t /*time*/,
|
|
|
|
|
wl_fixed_t surface_x,
|
|
|
|
|
wl_fixed_t surface_y)
|
|
|
|
|
static void pointer_handle_motion(void *data,
|
|
|
|
|
struct wl_pointer * /*wl_pointer*/,
|
|
|
|
|
uint32_t /*time*/,
|
|
|
|
|
wl_fixed_t surface_x,
|
|
|
|
|
wl_fixed_t surface_y)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
|
|
|
|
|
@@ -1136,12 +1143,12 @@ static void pointer_motion(void *data,
|
|
|
|
|
GHOST_TABLET_DATA_NONE));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void pointer_button(void *data,
|
|
|
|
|
struct wl_pointer * /*wl_pointer*/,
|
|
|
|
|
uint32_t serial,
|
|
|
|
|
uint32_t /*time*/,
|
|
|
|
|
uint32_t button,
|
|
|
|
|
uint32_t state)
|
|
|
|
|
static void pointer_handle_button(void *data,
|
|
|
|
|
struct wl_pointer * /*wl_pointer*/,
|
|
|
|
|
uint32_t serial,
|
|
|
|
|
uint32_t /*time*/,
|
|
|
|
|
uint32_t button,
|
|
|
|
|
uint32_t state)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
|
|
|
|
|
@@ -1192,11 +1199,11 @@ static void pointer_button(void *data,
|
|
|
|
|
input->system->getMilliSeconds(), etype, win, ebutton, GHOST_TABLET_DATA_NONE));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void pointer_axis(void *data,
|
|
|
|
|
struct wl_pointer * /*wl_pointer*/,
|
|
|
|
|
uint32_t /*time*/,
|
|
|
|
|
uint32_t axis,
|
|
|
|
|
wl_fixed_t value)
|
|
|
|
|
static void pointer_handle_axis(void *data,
|
|
|
|
|
struct wl_pointer * /*wl_pointer*/,
|
|
|
|
|
uint32_t /*time*/,
|
|
|
|
|
uint32_t axis,
|
|
|
|
|
wl_fixed_t value)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
|
|
|
|
|
@@ -1215,11 +1222,11 @@ static void pointer_axis(void *data,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct wl_pointer_listener pointer_listener = {
|
|
|
|
|
pointer_enter,
|
|
|
|
|
pointer_leave,
|
|
|
|
|
pointer_motion,
|
|
|
|
|
pointer_button,
|
|
|
|
|
pointer_axis,
|
|
|
|
|
pointer_handle_enter,
|
|
|
|
|
pointer_handle_leave,
|
|
|
|
|
pointer_handle_motion,
|
|
|
|
|
pointer_handle_button,
|
|
|
|
|
pointer_handle_axis,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -1228,39 +1235,41 @@ static const struct wl_pointer_listener pointer_listener = {
|
|
|
|
|
/** \name Listener (Tablet Tool), #zwp_tablet_tool_v2_listener
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void tablet_tool_type(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t tool_type)
|
|
|
|
|
static void tablet_tool_handle_type(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t tool_type)
|
|
|
|
|
{
|
|
|
|
|
tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data);
|
|
|
|
|
|
|
|
|
|
tool_input->data.Active = tablet_tool_map_type((enum zwp_tablet_tool_v2_type)tool_type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tablet_tool_hardware_serial(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t /*hardware_serial_hi*/,
|
|
|
|
|
uint32_t /*hardware_serial_lo*/)
|
|
|
|
|
static void tablet_tool_handle_hardware_serial(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t /*hardware_serial_hi*/,
|
|
|
|
|
uint32_t /*hardware_serial_lo*/)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tablet_tool_hardware_id_wacom(void * /*data*/,
|
|
|
|
|
static void tablet_tool_handle_hardware_id_wacom(
|
|
|
|
|
void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t /*hardware_id_hi*/,
|
|
|
|
|
uint32_t /*hardware_id_lo*/)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tablet_tool_handle_capability(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t /*hardware_id_hi*/,
|
|
|
|
|
uint32_t /*hardware_id_lo*/)
|
|
|
|
|
uint32_t /*capability*/)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tablet_tool_capability(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t /*capability*/)
|
|
|
|
|
static void tablet_tool_handle_done(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tablet_tool_done(void * /*data*/, struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
static void tablet_tool_removed(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2)
|
|
|
|
|
static void tablet_tool_handle_removed(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2)
|
|
|
|
|
{
|
|
|
|
|
tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data);
|
|
|
|
|
input_t *input = tool_input->input;
|
|
|
|
|
@@ -1272,11 +1281,11 @@ static void tablet_tool_removed(void *data, struct zwp_tablet_tool_v2 *zwp_table
|
|
|
|
|
|
|
|
|
|
delete tool_input;
|
|
|
|
|
}
|
|
|
|
|
static void tablet_tool_proximity_in(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t serial,
|
|
|
|
|
struct zwp_tablet_v2 * /*tablet*/,
|
|
|
|
|
struct wl_surface *surface)
|
|
|
|
|
static void tablet_tool_handle_proximity_in(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t serial,
|
|
|
|
|
struct zwp_tablet_v2 * /*tablet*/,
|
|
|
|
|
struct wl_surface *surface)
|
|
|
|
|
{
|
|
|
|
|
tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data);
|
|
|
|
|
input_t *input = tool_input->input;
|
|
|
|
|
@@ -1304,8 +1313,8 @@ static void tablet_tool_proximity_in(void *data,
|
|
|
|
|
|
|
|
|
|
win->setCursorShape(win->getCursorShape());
|
|
|
|
|
}
|
|
|
|
|
static void tablet_tool_proximity_out(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/)
|
|
|
|
|
static void tablet_tool_handle_proximity_out(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/)
|
|
|
|
|
{
|
|
|
|
|
tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data);
|
|
|
|
|
input_t *input = tool_input->input;
|
|
|
|
|
@@ -1316,9 +1325,9 @@ static void tablet_tool_proximity_out(void *data,
|
|
|
|
|
win->setCursorShape(win->getCursorShape());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tablet_tool_down(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t serial)
|
|
|
|
|
static void tablet_tool_handle_down(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t serial)
|
|
|
|
|
{
|
|
|
|
|
tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data);
|
|
|
|
|
input_t *input = tool_input->input;
|
|
|
|
|
@@ -1336,7 +1345,7 @@ static void tablet_tool_down(void *data,
|
|
|
|
|
input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tablet_tool_up(void *data, struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/)
|
|
|
|
|
static void tablet_tool_handle_up(void *data, struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/)
|
|
|
|
|
{
|
|
|
|
|
tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data);
|
|
|
|
|
input_t *input = tool_input->input;
|
|
|
|
|
@@ -1352,10 +1361,10 @@ static void tablet_tool_up(void *data, struct zwp_tablet_tool_v2 * /*zwp_tablet_
|
|
|
|
|
input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tablet_tool_motion(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
wl_fixed_t x,
|
|
|
|
|
wl_fixed_t y)
|
|
|
|
|
static void tablet_tool_handle_motion(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
wl_fixed_t x,
|
|
|
|
|
wl_fixed_t y)
|
|
|
|
|
{
|
|
|
|
|
tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data);
|
|
|
|
|
input_t *input = tool_input->input;
|
|
|
|
|
@@ -1377,9 +1386,9 @@ static void tablet_tool_motion(void *data,
|
|
|
|
|
tool_input->data));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tablet_tool_pressure(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t pressure)
|
|
|
|
|
static void tablet_tool_handle_pressure(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t pressure)
|
|
|
|
|
{
|
|
|
|
|
tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data);
|
|
|
|
|
input_t *input = tool_input->input;
|
|
|
|
|
@@ -1391,15 +1400,15 @@ static void tablet_tool_pressure(void *data,
|
|
|
|
|
GHOST_TabletData &td = tool_input->data;
|
|
|
|
|
td.Pressure = (float)pressure / 65535;
|
|
|
|
|
}
|
|
|
|
|
static void tablet_tool_distance(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t /*distance*/)
|
|
|
|
|
static void tablet_tool_handle_distance(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t /*distance*/)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
static void tablet_tool_tilt(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
wl_fixed_t tilt_x,
|
|
|
|
|
wl_fixed_t tilt_y)
|
|
|
|
|
static void tablet_tool_handle_tilt(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
wl_fixed_t tilt_x,
|
|
|
|
|
wl_fixed_t tilt_y)
|
|
|
|
|
{
|
|
|
|
|
tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data);
|
|
|
|
|
input_t *input = tool_input->input;
|
|
|
|
|
@@ -1417,23 +1426,23 @@ static void tablet_tool_tilt(void *data,
|
|
|
|
|
td.Ytilt = td.Ytilt < -1.0f ? -1.0f : (td.Ytilt > 1.0f ? 1.0f : td.Ytilt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tablet_tool_rotation(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
wl_fixed_t /*degrees*/)
|
|
|
|
|
static void tablet_tool_handle_rotation(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
wl_fixed_t /*degrees*/)
|
|
|
|
|
{
|
|
|
|
|
/* Pass. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tablet_tool_slider(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
int32_t /*position*/)
|
|
|
|
|
static void tablet_tool_handle_slider(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
int32_t /*position*/)
|
|
|
|
|
{
|
|
|
|
|
/* Pass. */
|
|
|
|
|
}
|
|
|
|
|
static void tablet_tool_wheel(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
wl_fixed_t /*degrees*/,
|
|
|
|
|
int32_t clicks)
|
|
|
|
|
static void tablet_tool_handle_wheel(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
wl_fixed_t /*degrees*/,
|
|
|
|
|
int32_t clicks)
|
|
|
|
|
{
|
|
|
|
|
if (clicks == 0) {
|
|
|
|
|
return;
|
|
|
|
|
@@ -1448,11 +1457,11 @@ static void tablet_tool_wheel(void *data,
|
|
|
|
|
}
|
|
|
|
|
input->system->pushEvent(new GHOST_EventWheel(input->system->getMilliSeconds(), win, clicks));
|
|
|
|
|
}
|
|
|
|
|
static void tablet_tool_button(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t serial,
|
|
|
|
|
uint32_t button,
|
|
|
|
|
uint32_t state)
|
|
|
|
|
static void tablet_tool_handle_button(void *data,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t serial,
|
|
|
|
|
uint32_t button,
|
|
|
|
|
uint32_t state)
|
|
|
|
|
{
|
|
|
|
|
tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data);
|
|
|
|
|
input_t *input = tool_input->input;
|
|
|
|
|
@@ -1489,32 +1498,32 @@ static void tablet_tool_button(void *data,
|
|
|
|
|
input->system->pushEvent(new GHOST_EventButton(
|
|
|
|
|
input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data));
|
|
|
|
|
}
|
|
|
|
|
static void tablet_tool_frame(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t /*time*/)
|
|
|
|
|
static void tablet_tool_handle_frame(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
|
|
|
|
|
uint32_t /*time*/)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct zwp_tablet_tool_v2_listener tablet_tool_listner = {
|
|
|
|
|
tablet_tool_type,
|
|
|
|
|
tablet_tool_hardware_serial,
|
|
|
|
|
tablet_tool_hardware_id_wacom,
|
|
|
|
|
tablet_tool_capability,
|
|
|
|
|
tablet_tool_done,
|
|
|
|
|
tablet_tool_removed,
|
|
|
|
|
tablet_tool_proximity_in,
|
|
|
|
|
tablet_tool_proximity_out,
|
|
|
|
|
tablet_tool_down,
|
|
|
|
|
tablet_tool_up,
|
|
|
|
|
tablet_tool_motion,
|
|
|
|
|
tablet_tool_pressure,
|
|
|
|
|
tablet_tool_distance,
|
|
|
|
|
tablet_tool_tilt,
|
|
|
|
|
tablet_tool_rotation,
|
|
|
|
|
tablet_tool_slider,
|
|
|
|
|
tablet_tool_wheel,
|
|
|
|
|
tablet_tool_button,
|
|
|
|
|
tablet_tool_frame,
|
|
|
|
|
tablet_tool_handle_type,
|
|
|
|
|
tablet_tool_handle_hardware_serial,
|
|
|
|
|
tablet_tool_handle_hardware_id_wacom,
|
|
|
|
|
tablet_tool_handle_capability,
|
|
|
|
|
tablet_tool_handle_done,
|
|
|
|
|
tablet_tool_handle_removed,
|
|
|
|
|
tablet_tool_handle_proximity_in,
|
|
|
|
|
tablet_tool_handle_proximity_out,
|
|
|
|
|
tablet_tool_handle_down,
|
|
|
|
|
tablet_tool_handle_up,
|
|
|
|
|
tablet_tool_handle_motion,
|
|
|
|
|
tablet_tool_handle_pressure,
|
|
|
|
|
tablet_tool_handle_distance,
|
|
|
|
|
tablet_tool_handle_tilt,
|
|
|
|
|
tablet_tool_handle_rotation,
|
|
|
|
|
tablet_tool_handle_slider,
|
|
|
|
|
tablet_tool_handle_wheel,
|
|
|
|
|
tablet_tool_handle_button,
|
|
|
|
|
tablet_tool_handle_frame,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -1523,16 +1532,16 @@ static const struct zwp_tablet_tool_v2_listener tablet_tool_listner = {
|
|
|
|
|
/** \name Listener (Table Seat), #zwp_tablet_seat_v2_listener
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void tablet_seat_tablet_added(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_seat_v2 * /*zwp_tablet_seat_v2*/,
|
|
|
|
|
struct zwp_tablet_v2 * /*id*/)
|
|
|
|
|
static void tablet_seat_handle_tablet_added(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_seat_v2 * /*zwp_tablet_seat_v2*/,
|
|
|
|
|
struct zwp_tablet_v2 * /*id*/)
|
|
|
|
|
{
|
|
|
|
|
/* Pass. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tablet_seat_tool_added(void *data,
|
|
|
|
|
struct zwp_tablet_seat_v2 * /*zwp_tablet_seat_v2*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 *id)
|
|
|
|
|
static void tablet_seat_handle_tool_added(void *data,
|
|
|
|
|
struct zwp_tablet_seat_v2 * /*zwp_tablet_seat_v2*/,
|
|
|
|
|
struct zwp_tablet_tool_v2 *id)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
tablet_tool_input_t *tool_input = new tablet_tool_input_t();
|
|
|
|
|
@@ -1542,24 +1551,22 @@ static void tablet_seat_tool_added(void *data,
|
|
|
|
|
tool_input->cursor_surface = wl_compositor_create_surface(input->system->compositor());
|
|
|
|
|
wl_surface_add_listener(tool_input->cursor_surface, &cursor_surface_listener, (void *)input);
|
|
|
|
|
|
|
|
|
|
tool_input->data = GHOST_TABLET_DATA_NONE;
|
|
|
|
|
|
|
|
|
|
zwp_tablet_tool_v2_add_listener(id, &tablet_tool_listner, tool_input);
|
|
|
|
|
|
|
|
|
|
input->tablet_tools.insert(id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tablet_seat_pad_added(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_seat_v2 * /*zwp_tablet_seat_v2*/,
|
|
|
|
|
struct zwp_tablet_pad_v2 * /*id*/)
|
|
|
|
|
static void tablet_seat_handle_pad_added(void * /*data*/,
|
|
|
|
|
struct zwp_tablet_seat_v2 * /*zwp_tablet_seat_v2*/,
|
|
|
|
|
struct zwp_tablet_pad_v2 * /*id*/)
|
|
|
|
|
{
|
|
|
|
|
/* Pass. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const struct zwp_tablet_seat_v2_listener tablet_seat_listener = {
|
|
|
|
|
tablet_seat_tablet_added,
|
|
|
|
|
tablet_seat_tool_added,
|
|
|
|
|
tablet_seat_pad_added,
|
|
|
|
|
tablet_seat_handle_tablet_added,
|
|
|
|
|
tablet_seat_handle_tool_added,
|
|
|
|
|
tablet_seat_handle_pad_added,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -1568,7 +1575,7 @@ const struct zwp_tablet_seat_v2_listener tablet_seat_listener = {
|
|
|
|
|
/** \name Listener (Keyboard), #wl_keyboard_listener
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void keyboard_keymap(
|
|
|
|
|
static void keyboard_handle_keymap(
|
|
|
|
|
void *data, struct wl_keyboard * /*wl_keyboard*/, uint32_t format, int32_t fd, uint32_t size)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
@@ -1604,11 +1611,11 @@ static void keyboard_keymap(
|
|
|
|
|
* Notification that this seat's keyboard focus is on a certain
|
|
|
|
|
* surface.
|
|
|
|
|
*/
|
|
|
|
|
static void keyboard_enter(void *data,
|
|
|
|
|
struct wl_keyboard * /*wl_keyboard*/,
|
|
|
|
|
uint32_t /*serial*/,
|
|
|
|
|
struct wl_surface *surface,
|
|
|
|
|
struct wl_array * /*keys*/)
|
|
|
|
|
static void keyboard_handle_enter(void *data,
|
|
|
|
|
struct wl_keyboard * /*wl_keyboard*/,
|
|
|
|
|
uint32_t /*serial*/,
|
|
|
|
|
struct wl_surface *surface,
|
|
|
|
|
struct wl_array * /*keys*/)
|
|
|
|
|
{
|
|
|
|
|
if (surface != nullptr) {
|
|
|
|
|
static_cast<input_t *>(data)->focus_keyboard = surface;
|
|
|
|
|
@@ -1621,10 +1628,10 @@ static void keyboard_enter(void *data,
|
|
|
|
|
* Notification that this seat's keyboard focus is no longer on a
|
|
|
|
|
* certain surface.
|
|
|
|
|
*/
|
|
|
|
|
static void keyboard_leave(void *data,
|
|
|
|
|
struct wl_keyboard * /*wl_keyboard*/,
|
|
|
|
|
uint32_t /*serial*/,
|
|
|
|
|
struct wl_surface *surface)
|
|
|
|
|
static void keyboard_handle_leave(void *data,
|
|
|
|
|
struct wl_keyboard * /*wl_keyboard*/,
|
|
|
|
|
uint32_t /*serial*/,
|
|
|
|
|
struct wl_surface *surface)
|
|
|
|
|
{
|
|
|
|
|
if (surface != nullptr) {
|
|
|
|
|
static_cast<input_t *>(data)->focus_keyboard = nullptr;
|
|
|
|
|
@@ -1657,12 +1664,12 @@ static xkb_keysym_t xkb_state_key_get_one_sym_without_modifiers(struct xkb_state
|
|
|
|
|
return sym;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void keyboard_key(void *data,
|
|
|
|
|
struct wl_keyboard * /*wl_keyboard*/,
|
|
|
|
|
uint32_t serial,
|
|
|
|
|
uint32_t /*time*/,
|
|
|
|
|
uint32_t key,
|
|
|
|
|
uint32_t state)
|
|
|
|
|
static void keyboard_handle_key(void *data,
|
|
|
|
|
struct wl_keyboard * /*wl_keyboard*/,
|
|
|
|
|
uint32_t serial,
|
|
|
|
|
uint32_t /*time*/,
|
|
|
|
|
uint32_t key,
|
|
|
|
|
uint32_t state)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
|
|
|
|
|
@@ -1720,7 +1727,7 @@ static void keyboard_key(void *data,
|
|
|
|
|
.key_data = key_data,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
auto cb = [](GHOST_ITimerTask *task, uint64_t /*time*/) {
|
|
|
|
|
auto key_repeat_fn = [](GHOST_ITimerTask *task, uint64_t /*time*/) {
|
|
|
|
|
struct key_repeat_payload_t *payload = static_cast<key_repeat_payload_t *>(
|
|
|
|
|
task->getUserData());
|
|
|
|
|
payload->system->pushEvent(new GHOST_EventKey(payload->system->getMilliSeconds(),
|
|
|
|
|
@@ -1732,17 +1739,17 @@ static void keyboard_key(void *data,
|
|
|
|
|
true));
|
|
|
|
|
};
|
|
|
|
|
input->key_repeat.timer = input->system->installTimer(
|
|
|
|
|
input->key_repeat.delay, 1000 / input->key_repeat.rate, cb, payload);
|
|
|
|
|
input->key_repeat.delay, 1000 / input->key_repeat.rate, key_repeat_fn, payload);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void keyboard_modifiers(void *data,
|
|
|
|
|
struct wl_keyboard * /*wl_keyboard*/,
|
|
|
|
|
uint32_t /*serial*/,
|
|
|
|
|
uint32_t mods_depressed,
|
|
|
|
|
uint32_t mods_latched,
|
|
|
|
|
uint32_t mods_locked,
|
|
|
|
|
uint32_t group)
|
|
|
|
|
static void keyboard_handle_modifiers(void *data,
|
|
|
|
|
struct wl_keyboard * /*wl_keyboard*/,
|
|
|
|
|
uint32_t /*serial*/,
|
|
|
|
|
uint32_t mods_depressed,
|
|
|
|
|
uint32_t mods_latched,
|
|
|
|
|
uint32_t mods_locked,
|
|
|
|
|
uint32_t group)
|
|
|
|
|
{
|
|
|
|
|
xkb_state_update_mask(static_cast<input_t *>(data)->xkb_state,
|
|
|
|
|
mods_depressed,
|
|
|
|
|
@@ -1753,10 +1760,10 @@ static void keyboard_modifiers(void *data,
|
|
|
|
|
group);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void keyboard_repeat_info(void *data,
|
|
|
|
|
struct wl_keyboard * /*wl_keyboard*/,
|
|
|
|
|
int32_t rate,
|
|
|
|
|
int32_t delay)
|
|
|
|
|
static void keyboard_repeat_handle_info(void *data,
|
|
|
|
|
struct wl_keyboard * /*wl_keyboard*/,
|
|
|
|
|
int32_t rate,
|
|
|
|
|
int32_t delay)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
|
|
|
|
|
@@ -1765,12 +1772,12 @@ static void keyboard_repeat_info(void *data,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct wl_keyboard_listener keyboard_listener = {
|
|
|
|
|
keyboard_keymap,
|
|
|
|
|
keyboard_enter,
|
|
|
|
|
keyboard_leave,
|
|
|
|
|
keyboard_key,
|
|
|
|
|
keyboard_modifiers,
|
|
|
|
|
keyboard_repeat_info,
|
|
|
|
|
keyboard_handle_keymap,
|
|
|
|
|
keyboard_handle_enter,
|
|
|
|
|
keyboard_handle_leave,
|
|
|
|
|
keyboard_handle_key,
|
|
|
|
|
keyboard_handle_modifiers,
|
|
|
|
|
keyboard_repeat_handle_info,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -1779,40 +1786,40 @@ static const struct wl_keyboard_listener keyboard_listener = {
|
|
|
|
|
/** \name Listener (Seat), #wl_seat_listener
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities)
|
|
|
|
|
static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities)
|
|
|
|
|
{
|
|
|
|
|
input_t *input = static_cast<input_t *>(data);
|
|
|
|
|
input->pointer = nullptr;
|
|
|
|
|
input->keyboard = nullptr;
|
|
|
|
|
input->wl_pointer = nullptr;
|
|
|
|
|
input->wl_keyboard = nullptr;
|
|
|
|
|
|
|
|
|
|
if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
|
|
|
|
|
input->pointer = wl_seat_get_pointer(wl_seat);
|
|
|
|
|
input->cursor.surface = wl_compositor_create_surface(input->system->compositor());
|
|
|
|
|
input->wl_pointer = wl_seat_get_pointer(wl_seat);
|
|
|
|
|
input->cursor.wl_surface = wl_compositor_create_surface(input->system->compositor());
|
|
|
|
|
input->cursor.visible = true;
|
|
|
|
|
input->cursor.buffer = nullptr;
|
|
|
|
|
input->cursor.wl_buffer = nullptr;
|
|
|
|
|
input->cursor.file_buffer = new buffer_t;
|
|
|
|
|
if (!get_cursor_settings(input->cursor.theme_name, input->cursor.size)) {
|
|
|
|
|
input->cursor.theme_name = std::string();
|
|
|
|
|
input->cursor.size = default_cursor_size;
|
|
|
|
|
}
|
|
|
|
|
wl_pointer_add_listener(input->pointer, &pointer_listener, data);
|
|
|
|
|
wl_surface_add_listener(input->cursor.surface, &cursor_surface_listener, data);
|
|
|
|
|
wl_pointer_add_listener(input->wl_pointer, &pointer_listener, data);
|
|
|
|
|
wl_surface_add_listener(input->cursor.wl_surface, &cursor_surface_listener, data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
|
|
|
|
|
input->keyboard = wl_seat_get_keyboard(wl_seat);
|
|
|
|
|
wl_keyboard_add_listener(input->keyboard, &keyboard_listener, data);
|
|
|
|
|
input->wl_keyboard = wl_seat_get_keyboard(wl_seat);
|
|
|
|
|
wl_keyboard_add_listener(input->wl_keyboard, &keyboard_listener, data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void seat_name(void *data, struct wl_seat * /*wl_seat*/, const char *name)
|
|
|
|
|
static void seat_handle_name(void *data, struct wl_seat * /*wl_seat*/, const char *name)
|
|
|
|
|
{
|
|
|
|
|
static_cast<input_t *>(data)->name = std::string(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct wl_seat_listener seat_listener = {
|
|
|
|
|
seat_capabilities,
|
|
|
|
|
seat_name,
|
|
|
|
|
seat_handle_capabilities,
|
|
|
|
|
seat_handle_name,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -1894,16 +1901,16 @@ static const struct zxdg_output_v1_listener xdg_output_listener = {
|
|
|
|
|
/** \name Listener (Output), #wl_output_listener
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void output_geometry(void *data,
|
|
|
|
|
struct wl_output * /*wl_output*/,
|
|
|
|
|
int32_t /*x*/,
|
|
|
|
|
int32_t /*y*/,
|
|
|
|
|
int32_t physical_width,
|
|
|
|
|
int32_t physical_height,
|
|
|
|
|
int32_t /*subpixel*/,
|
|
|
|
|
const char *make,
|
|
|
|
|
const char *model,
|
|
|
|
|
int32_t transform)
|
|
|
|
|
static void output_handle_geometry(void *data,
|
|
|
|
|
struct wl_output * /*wl_output*/,
|
|
|
|
|
int32_t /*x*/,
|
|
|
|
|
int32_t /*y*/,
|
|
|
|
|
int32_t physical_width,
|
|
|
|
|
int32_t physical_height,
|
|
|
|
|
int32_t /*subpixel*/,
|
|
|
|
|
const char *make,
|
|
|
|
|
const char *model,
|
|
|
|
|
int32_t transform)
|
|
|
|
|
{
|
|
|
|
|
output_t *output = static_cast<output_t *>(data);
|
|
|
|
|
output->transform = transform;
|
|
|
|
|
@@ -1913,12 +1920,12 @@ static void output_geometry(void *data,
|
|
|
|
|
output->size_mm[1] = physical_height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void output_mode(void *data,
|
|
|
|
|
struct wl_output * /*wl_output*/,
|
|
|
|
|
uint32_t flags,
|
|
|
|
|
int32_t width,
|
|
|
|
|
int32_t height,
|
|
|
|
|
int32_t /*refresh*/)
|
|
|
|
|
static void output_handle_mode(void *data,
|
|
|
|
|
struct wl_output * /*wl_output*/,
|
|
|
|
|
uint32_t flags,
|
|
|
|
|
int32_t width,
|
|
|
|
|
int32_t height,
|
|
|
|
|
int32_t /*refresh*/)
|
|
|
|
|
{
|
|
|
|
|
output_t *output = static_cast<output_t *>(data);
|
|
|
|
|
|
|
|
|
|
@@ -1943,7 +1950,7 @@ static void output_mode(void *data,
|
|
|
|
|
* changes done after that. This allows changes to the output
|
|
|
|
|
* properties to be seen as atomic, even if they happen via multiple events.
|
|
|
|
|
*/
|
|
|
|
|
static void output_done(void *data, struct wl_output * /*wl_output*/)
|
|
|
|
|
static void output_handle_done(void *data, struct wl_output * /*wl_output*/)
|
|
|
|
|
{
|
|
|
|
|
output_t *output = static_cast<output_t *>(data);
|
|
|
|
|
int32_t size_native[2];
|
|
|
|
|
@@ -1970,16 +1977,16 @@ static void output_done(void *data, struct wl_output * /*wl_output*/)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void output_scale(void *data, struct wl_output * /*wl_output*/, int32_t factor)
|
|
|
|
|
static void output_handle_scale(void *data, struct wl_output * /*wl_output*/, int32_t factor)
|
|
|
|
|
{
|
|
|
|
|
static_cast<output_t *>(data)->scale = factor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct wl_output_listener output_listener = {
|
|
|
|
|
output_geometry,
|
|
|
|
|
output_mode,
|
|
|
|
|
output_done,
|
|
|
|
|
output_scale,
|
|
|
|
|
output_handle_geometry,
|
|
|
|
|
output_handle_mode,
|
|
|
|
|
output_handle_done,
|
|
|
|
|
output_handle_scale,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -1988,13 +1995,13 @@ static const struct wl_output_listener output_listener = {
|
|
|
|
|
/** \name Listener (XDG WM Base), #xdg_wm_base_listener
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void shell_ping(void * /*data*/, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
|
|
|
|
|
static void shell_handle_ping(void * /*data*/, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
|
|
|
|
|
{
|
|
|
|
|
xdg_wm_base_pong(xdg_wm_base, serial);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct xdg_wm_base_listener shell_listener = {
|
|
|
|
|
shell_ping,
|
|
|
|
|
shell_handle_ping,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -2003,11 +2010,11 @@ static const struct xdg_wm_base_listener shell_listener = {
|
|
|
|
|
/** \name Listener (Registry), #wl_registry_listener
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void global_add(void *data,
|
|
|
|
|
struct wl_registry *wl_registry,
|
|
|
|
|
uint32_t name,
|
|
|
|
|
const char *interface,
|
|
|
|
|
uint32_t /*version*/)
|
|
|
|
|
static void global_handle_add(void *data,
|
|
|
|
|
struct wl_registry *wl_registry,
|
|
|
|
|
uint32_t name,
|
|
|
|
|
const char *interface,
|
|
|
|
|
uint32_t /*version*/)
|
|
|
|
|
{
|
|
|
|
|
struct display_t *display = static_cast<struct display_t *>(data);
|
|
|
|
|
if (!strcmp(interface, wl_compositor_interface.name)) {
|
|
|
|
|
@@ -2028,28 +2035,20 @@ static void global_add(void *data,
|
|
|
|
|
wl_registry_bind(wl_registry, name, &zxdg_output_manager_v1_interface, 3));
|
|
|
|
|
for (output_t *output : display->outputs) {
|
|
|
|
|
output->xdg_output = zxdg_output_manager_v1_get_xdg_output(display->xdg_output_manager,
|
|
|
|
|
output->output);
|
|
|
|
|
output->wl_output);
|
|
|
|
|
zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, output);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (!strcmp(interface, wl_output_interface.name)) {
|
|
|
|
|
output_t *output = new output_t;
|
|
|
|
|
|
|
|
|
|
output->scale = 1;
|
|
|
|
|
output->has_scale_fractional = false;
|
|
|
|
|
output->scale_fractional = wl_fixed_from_int(1);
|
|
|
|
|
|
|
|
|
|
output->has_size_logical = false;
|
|
|
|
|
output->has_position_logical = false;
|
|
|
|
|
|
|
|
|
|
output->output = static_cast<wl_output *>(
|
|
|
|
|
output->wl_output = static_cast<wl_output *>(
|
|
|
|
|
wl_registry_bind(wl_registry, name, &wl_output_interface, 2));
|
|
|
|
|
display->outputs.push_back(output);
|
|
|
|
|
wl_output_add_listener(output->output, &output_listener, output);
|
|
|
|
|
wl_output_add_listener(output->wl_output, &output_listener, output);
|
|
|
|
|
|
|
|
|
|
if (display->xdg_output_manager) {
|
|
|
|
|
output->xdg_output = zxdg_output_manager_v1_get_xdg_output(display->xdg_output_manager,
|
|
|
|
|
output->output);
|
|
|
|
|
output->wl_output);
|
|
|
|
|
zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, output);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -2057,19 +2056,11 @@ static void global_add(void *data,
|
|
|
|
|
input_t *input = new input_t;
|
|
|
|
|
input->system = display->system;
|
|
|
|
|
input->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
|
|
|
|
input->xkb_state = nullptr;
|
|
|
|
|
input->data_offer_dnd = nullptr;
|
|
|
|
|
input->data_offer_copy_paste = nullptr;
|
|
|
|
|
input->data_source = new data_source_t;
|
|
|
|
|
input->data_source->data_source = nullptr;
|
|
|
|
|
input->data_source->buffer_out = nullptr;
|
|
|
|
|
input->relative_pointer = nullptr;
|
|
|
|
|
input->locked_pointer = nullptr;
|
|
|
|
|
input->confined_pointer = nullptr;
|
|
|
|
|
input->seat = static_cast<wl_seat *>(
|
|
|
|
|
input->wl_seat = static_cast<wl_seat *>(
|
|
|
|
|
wl_registry_bind(wl_registry, name, &wl_seat_interface, 4));
|
|
|
|
|
display->inputs.push_back(input);
|
|
|
|
|
wl_seat_add_listener(input->seat, &seat_listener, input);
|
|
|
|
|
wl_seat_add_listener(input->wl_seat, &seat_listener, input);
|
|
|
|
|
}
|
|
|
|
|
else if (!strcmp(interface, wl_shm_interface.name)) {
|
|
|
|
|
display->shm = static_cast<wl_shm *>(
|
|
|
|
|
@@ -2102,13 +2093,15 @@ static void global_add(void *data,
|
|
|
|
|
* name is no longer available. If the client bound to the global
|
|
|
|
|
* using the bind request, the client should now destroy that object.
|
|
|
|
|
*/
|
|
|
|
|
static void global_remove(void * /*data*/, struct wl_registry * /*wl_registry*/, uint32_t /*name*/)
|
|
|
|
|
static void global_handle_remove(void * /*data*/,
|
|
|
|
|
struct wl_registry * /*wl_registry*/,
|
|
|
|
|
uint32_t /*name*/)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct wl_registry_listener registry_listener = {
|
|
|
|
|
global_add,
|
|
|
|
|
global_remove,
|
|
|
|
|
global_handle_add,
|
|
|
|
|
global_handle_remove,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -2149,14 +2142,15 @@ GHOST_SystemWayland::GHOST_SystemWayland() : GHOST_System(), d(new display_t)
|
|
|
|
|
if (d->data_device_manager) {
|
|
|
|
|
for (input_t *input : d->inputs) {
|
|
|
|
|
input->data_device = wl_data_device_manager_get_data_device(d->data_device_manager,
|
|
|
|
|
input->seat);
|
|
|
|
|
input->wl_seat);
|
|
|
|
|
wl_data_device_add_listener(input->data_device, &data_device_listener, input);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (d->tablet_manager) {
|
|
|
|
|
for (input_t *input : d->inputs) {
|
|
|
|
|
input->tablet_seat = zwp_tablet_manager_v2_get_tablet_seat(d->tablet_manager, input->seat);
|
|
|
|
|
input->tablet_seat = zwp_tablet_manager_v2_get_tablet_seat(d->tablet_manager,
|
|
|
|
|
input->wl_seat);
|
|
|
|
|
zwp_tablet_seat_v2_add_listener(input->tablet_seat, &tablet_seat_listener, input);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -2435,12 +2429,12 @@ wl_compositor *GHOST_SystemWayland::compositor()
|
|
|
|
|
return d->compositor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xdg_wm_base *GHOST_SystemWayland::shell()
|
|
|
|
|
xdg_wm_base *GHOST_SystemWayland::xdg_shell()
|
|
|
|
|
{
|
|
|
|
|
return d->xdg_shell;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zxdg_decoration_manager_v1 *GHOST_SystemWayland::decoration_manager()
|
|
|
|
|
zxdg_decoration_manager_v1 *GHOST_SystemWayland::xdg_decoration_manager()
|
|
|
|
|
{
|
|
|
|
|
return d->xdg_decoration_manager;
|
|
|
|
|
}
|
|
|
|
|
@@ -2466,22 +2460,22 @@ static void set_cursor_buffer(input_t *input, wl_buffer *buffer)
|
|
|
|
|
|
|
|
|
|
c->visible = (buffer != nullptr);
|
|
|
|
|
|
|
|
|
|
const int32_t image_size_x = int32_t(c->image.width);
|
|
|
|
|
const int32_t image_size_y = int32_t(c->image.height);
|
|
|
|
|
const int32_t image_size_x = int32_t(c->wl_image.width);
|
|
|
|
|
const int32_t image_size_y = int32_t(c->wl_image.height);
|
|
|
|
|
|
|
|
|
|
const int32_t hotspot_x = int32_t(c->image.hotspot_x) / c->scale;
|
|
|
|
|
const int32_t hotspot_y = int32_t(c->image.hotspot_y) / c->scale;
|
|
|
|
|
const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / c->scale;
|
|
|
|
|
const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / c->scale;
|
|
|
|
|
|
|
|
|
|
wl_surface_attach(c->surface, buffer, 0, 0);
|
|
|
|
|
wl_surface_damage(c->surface, 0, 0, image_size_x, image_size_y);
|
|
|
|
|
wl_surface_attach(c->wl_surface, buffer, 0, 0);
|
|
|
|
|
wl_surface_damage(c->wl_surface, 0, 0, image_size_x, image_size_y);
|
|
|
|
|
|
|
|
|
|
wl_pointer_set_cursor(input->pointer,
|
|
|
|
|
wl_pointer_set_cursor(input->wl_pointer,
|
|
|
|
|
input->pointer_serial,
|
|
|
|
|
c->visible ? c->surface : nullptr,
|
|
|
|
|
c->visible ? c->wl_surface : nullptr,
|
|
|
|
|
hotspot_x,
|
|
|
|
|
hotspot_y);
|
|
|
|
|
|
|
|
|
|
wl_surface_commit(c->surface);
|
|
|
|
|
wl_surface_commit(c->wl_surface);
|
|
|
|
|
|
|
|
|
|
/* Set the cursor for all tablet tools as well. */
|
|
|
|
|
for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : input->tablet_tools) {
|
|
|
|
|
@@ -2514,12 +2508,13 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorShape(GHOST_TStandardCursor shape)
|
|
|
|
|
input_t *input = d->inputs[0];
|
|
|
|
|
cursor_t *c = &input->cursor;
|
|
|
|
|
|
|
|
|
|
if (!c->theme) {
|
|
|
|
|
if (!c->wl_theme) {
|
|
|
|
|
/* The cursor surface hasn't entered an output yet. Initialize theme with scale 1. */
|
|
|
|
|
c->theme = wl_cursor_theme_load(c->theme_name.c_str(), c->size, d->inputs[0]->system->shm());
|
|
|
|
|
c->wl_theme = wl_cursor_theme_load(
|
|
|
|
|
c->theme_name.c_str(), c->size, d->inputs[0]->system->shm());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wl_cursor *cursor = wl_cursor_theme_get_cursor(c->theme, cursor_name.c_str());
|
|
|
|
|
wl_cursor *cursor = wl_cursor_theme_get_cursor(c->wl_theme, cursor_name.c_str());
|
|
|
|
|
|
|
|
|
|
if (!cursor) {
|
|
|
|
|
GHOST_PRINT("cursor '" << cursor_name << "' does not exist" << std::endl);
|
|
|
|
|
@@ -2532,8 +2527,8 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorShape(GHOST_TStandardCursor shape)
|
|
|
|
|
return GHOST_kFailure;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c->buffer = buffer;
|
|
|
|
|
c->image = *image;
|
|
|
|
|
c->wl_buffer = buffer;
|
|
|
|
|
c->wl_image = *image;
|
|
|
|
|
|
|
|
|
|
set_cursor_buffer(input, buffer);
|
|
|
|
|
|
|
|
|
|
@@ -2639,11 +2634,11 @@ GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(uint8_t *bitmap,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cursor->buffer = buffer;
|
|
|
|
|
cursor->image.width = uint32_t(sizex);
|
|
|
|
|
cursor->image.height = uint32_t(sizey);
|
|
|
|
|
cursor->image.hotspot_x = uint32_t(hotX);
|
|
|
|
|
cursor->image.hotspot_y = uint32_t(hotY);
|
|
|
|
|
cursor->wl_buffer = buffer;
|
|
|
|
|
cursor->wl_image.width = uint32_t(sizex);
|
|
|
|
|
cursor->wl_image.height = uint32_t(sizey);
|
|
|
|
|
cursor->wl_image.hotspot_x = uint32_t(hotX);
|
|
|
|
|
cursor->wl_image.hotspot_y = uint32_t(hotY);
|
|
|
|
|
|
|
|
|
|
set_cursor_buffer(d->inputs[0], buffer);
|
|
|
|
|
|
|
|
|
|
@@ -2661,7 +2656,7 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorVisibility(bool visible)
|
|
|
|
|
cursor_t *cursor = &input->cursor;
|
|
|
|
|
if (visible) {
|
|
|
|
|
if (!cursor->visible) {
|
|
|
|
|
set_cursor_buffer(input, cursor->buffer);
|
|
|
|
|
set_cursor_buffer(input, cursor->wl_buffer);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
@@ -2680,7 +2675,6 @@ bool GHOST_SystemWayland::supportsCursorWarp()
|
|
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mode,
|
|
|
|
|
const GHOST_TGrabCursorMode mode_current,
|
|
|
|
|
|
|
|
|
|
wl_surface *surface)
|
|
|
|
|
{
|
|
|
|
|
/* ignore, if the required protocols are not supported */
|
|
|
|
|
@@ -2787,13 +2781,13 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo
|
|
|
|
|
* An alternative could be to draw the cursor in software (and hide the real cursor),
|
|
|
|
|
* or just accept a locked cursor on WAYLAND. */
|
|
|
|
|
input->relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(
|
|
|
|
|
d->relative_pointer_manager, input->pointer);
|
|
|
|
|
d->relative_pointer_manager, input->wl_pointer);
|
|
|
|
|
zwp_relative_pointer_v1_add_listener(
|
|
|
|
|
input->relative_pointer, &relative_pointer_listener, input);
|
|
|
|
|
input->locked_pointer = zwp_pointer_constraints_v1_lock_pointer(
|
|
|
|
|
d->pointer_constraints,
|
|
|
|
|
surface,
|
|
|
|
|
input->pointer,
|
|
|
|
|
input->wl_pointer,
|
|
|
|
|
nullptr,
|
|
|
|
|
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
|
|
|
|
|
}
|
|
|
|
|
@@ -2803,7 +2797,7 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo
|
|
|
|
|
input->confined_pointer = zwp_pointer_constraints_v1_confine_pointer(
|
|
|
|
|
d->pointer_constraints,
|
|
|
|
|
surface,
|
|
|
|
|
input->pointer,
|
|
|
|
|
input->wl_pointer,
|
|
|
|
|
nullptr,
|
|
|
|
|
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
|
|
|
|
|
}
|
|
|
|
|
|