24#ifdef WITH_OPENGL_BACKEND
28#ifdef WITH_VULKAN_BACKEND
36#ifdef WITH_GHOST_WAYLAND_DYNLOAD
40#ifdef WITH_OPENGL_BACKEND
41# ifdef WITH_GHOST_WAYLAND_DYNLOAD
44# include <wayland-egl.h>
51#include <unordered_set>
53#ifdef WITH_GHOST_WAYLAND_DYNLOAD
56#include <wayland-cursor.h>
58#include <xkbcommon/xkbcommon-compose.h>
59#include <xkbcommon/xkbcommon.h>
62#include <fractional-scale-v1-client-protocol.h>
63#include <pointer-constraints-unstable-v1-client-protocol.h>
64#include <pointer-gestures-unstable-v1-client-protocol.h>
65#include <primary-selection-unstable-v1-client-protocol.h>
66#include <relative-pointer-unstable-v1-client-protocol.h>
67#include <tablet-v2-client-protocol.h>
68#include <viewporter-client-protocol.h>
69#include <xdg-activation-v1-client-protocol.h>
70#include <xdg-output-unstable-v1-client-protocol.h>
72# include <text-input-unstable-v3-client-protocol.h>
76#include <xdg-decoration-unstable-v1-client-protocol.h>
77#include <xdg-shell-client-protocol.h>
97#ifdef USE_EVENT_BACKGROUND_THREAD
101#ifdef WITH_GHOST_WAYLAND_LIBDECOR
102static bool use_libdecor =
true;
103# ifdef WITH_GHOST_WAYLAND_DYNLOAD
104static bool has_libdecor =
false;
106static bool has_libdecor =
true;
134 int *r_interface_slot);
143 xkb_compose_state *compose_state,
145 const xkb_keycode_t key,
148#ifdef USE_EVENT_BACKGROUND_THREAD
160#define pushEvent DONT_USE
175#define USE_GNOME_CONFINE_HACK
182#ifdef USE_GNOME_CONFINE_HACK
191#define USE_KDE_TABLET_HIDDEN_CURSOR_HACK
216#ifdef USE_VERBOSE_OLD_IFACE_PRINT
217# define _VERBOSE_OLD_IFACE_PRINT(params_version, version_max) \
218 ((params_version > version_max) ? \
220 "%s: version_max=%u, is smaller than run-time version=%u\n", \
226# define _VERBOSE_OLD_IFACE_PRINT(params_version, version_max) \
227 ((void)(params_version), (version_max))
230#define GWL_IFACE_VERSION_CLAMP(params_version, version_min, version_max) \
231 ((void)_VERBOSE_OLD_IFACE_PRINT(params_version, version_max), \
232 std::clamp(params_version, version_min, version_max))
238#define USE_NON_LATIN_KB_WORKAROUND
240#define WL_NAME_UNSET uint32_t(-1)
246#define WL_FIXED_TO_INT_FOR_WINDOW_V2(win, xy) \
247 wl_fixed_to_int((win)->wl_fixed_to_window((xy)[0])), \
248 wl_fixed_to_int((win)->wl_fixed_to_window((xy)[1])),
274#define BTN_RANGE_MIN BTN_LEFT
275#define BTN_RANGE_MAX BTN_BACK
308#ifdef USE_NON_LATIN_KB_WORKAROUND
323#ifndef XKB_VMOD_NAME_HYPER
324# define XKB_VMOD_NAME_HYPER "Hyper"
342#define MOD_INDEX_NUM (MOD_INDEX_HYPER + 1)
414 free(
const_cast<char *
>(buffer->
data));
415 buffer->
data =
nullptr;
421 free(
const_cast<char *
>(buffer->
data));
438#define EVDEV_OFFSET 8
524#define GWL_TabletTool_FrameTypes_NUM (int(GWL_TabletTool_EventTypes::Stylus3_Up) + 1)
579 const int ty_mask = 1 << int(ty);
608 wl_data_offer *
id =
nullptr;
611 std::unordered_set<std::string>
types;
620 enum wl_data_device_manager_dnd_action
source_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
621 enum wl_data_device_manager_dnd_action
action = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
623 wl_fixed_t
xy[2] = {0, 0};
707 wl_fixed_t
xy[2] = {0, 0};
710 std::unordered_set<const GWL_Output *>
outputs;
755#define GWL_SeatStatePointer_EventTypes_NUM (int(GWL_Pointer_EventTypes::Button6_Up) + 1)
794 GHOST_ASSERT(event_ms == 0,
"Scroll events must not have a time-stamp");
797 GHOST_ASSERT(event_ms != 0,
"Non-scroll events must have a time-stamp");
800 const int ty_mask = 1 << int(ty);
842 enum wl_pointer_axis_source
axis_source = WL_POINTER_AXIS_SOURCE_WHEEL;
871 const wl_fixed_t
add)
873 const int result_prev = wl_fixed_to_int(sf->
value * sf->
factor);
875 const int result_curr = wl_fixed_to_int(sf->
value * sf->
factor);
876 return result_curr - result_prev;
915#ifdef WITH_GHOST_WAYLAND_LIBDECOR
916struct GWL_LibDecor_System {
920static void gwl_libdecor_system_destroy(GWL_LibDecor_System *decor)
922 if (decor->context) {
924 decor->context =
nullptr;
934 zxdg_decoration_manager_v1 *
manager =
nullptr;
955 zwp_primary_selection_offer_v1 *
id =
nullptr;
958 std::unordered_set<std::string>
types;
965 zwp_primary_selection_source_v1 *
source =
nullptr;
986 zwp_primary_selection_offer_v1_destroy(primary->
data_offer->
wp.
id);
994 if (data_source ==
nullptr) {
999 zwp_primary_selection_source_v1_destroy(data_source->
wp.
source);
1005#ifdef WITH_INPUT_IME
1015 GHOST_TEventImeData event_ime_data = {
1031 bool has_preedit =
false;
1034 bool result_is_null =
false;
1036 bool composite_is_null =
false;
1039 bool has_preedit_string_callback =
false;
1041 bool has_commit_string_callback =
false;
1070#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE
1071 zwp_pointer_gesture_hold_v1 *pointer_gesture_hold =
nullptr;
1073#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE
1076#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE
1077 zwp_pointer_gesture_swipe_v1 *pointer_gesture_swipe =
nullptr;
1089#ifdef WITH_INPUT_IME
1090 zwp_text_input_v3 *text_input =
nullptr;
1127#ifdef WITH_INPUT_IME
1149#ifdef USE_GNOME_CONFINE_HACK
1157#ifdef USE_NON_LATIN_KB_WORKAROUND
1242 GHOST_ASSERT(0,
"Surface found without pointer/tablet tag");
1260 xkb_state_update_mask(seat->
xkb.
state_empty, 0, 0, 0, 0, 0, group);
1264 "Invalid state for SHIFT");
1270 GHOST_ASSERT((mod_mod2 == XKB_MOD_INVALID || mod_numlock == XKB_MOD_INVALID) ==
1272 "Invalid state for NUMLOCK");
1274 xkb_state_update_mask(
1286 if (
UNLIKELY(wl_surface_focus ==
nullptr)) {
1303 xkb_state_key_get_utf8(seat->
xkb.
state, payload->
key_code, utf8_buf,
sizeof(utf8_buf));
1316 const bool use_delay)
1325#ifdef USE_EVENT_BACKGROUND_THREAD
1327 time_now + time_start, time_step, key_repeat_fn, payload);
1341#ifdef USE_EVENT_BACKGROUND_THREAD
1350#ifdef WITH_INPUT_IME
1352static void gwl_seat_ime_full_reset(
GWL_Seat *seat)
1354 const GWL_SeatIME ime_default{};
1357 wl_surface *surface_window = seat->ime.surface_window;
1358 const bool is_enabled = seat->ime.is_enabled;
1359 const bool has_preedit_string_callback = seat->ime.has_preedit_string_callback;
1360 const bool has_commit_string_callback = seat->ime.has_commit_string_callback;
1362 seat->ime = ime_default;
1364 seat->ime.surface_window = surface_window;
1366 seat->ime.has_preedit_string_callback = has_preedit_string_callback;
1367 seat->ime.has_commit_string_callback = has_commit_string_callback;
1370static void gwl_seat_ime_result_reset(
GWL_Seat *seat)
1373 event_ime_data.
result.clear();
1374 seat->ime.result_is_null =
false;
1377static void gwl_seat_ime_preedit_reset(
GWL_Seat *seat)
1382 seat->ime.composite_is_null =
false;
1389static void gwl_seat_ime_rect_reset(
GWL_Seat *seat)
1391 seat->ime.rect.x = -1;
1392 seat->ime.rect.y = -1;
1393 seat->ime.rect.w = -1;
1394 seat->ime.rect.h = -1;
1446#ifdef WITH_INPUT_IME
1447 zwp_text_input_manager_v3 *text_input_manager =
nullptr;
1471#ifdef WITH_GHOST_WAYLAND_LIBDECOR
1472 GWL_LibDecor_System *libdecor =
nullptr;
1507#ifdef USE_EVENT_BACKGROUND_THREAD
1551#ifdef USE_EVENT_BACKGROUND_THREAD
1575#ifdef WITH_GHOST_WAYLAND_LIBDECOR
1577 if (display->libdecor) {
1578 gwl_libdecor_system_destroy(display->libdecor);
1579 display->libdecor =
nullptr;
1591#ifdef WITH_OPENGL_BACKEND
1593 if (eglGetDisplay) {
1594 ::eglTerminate(eglGetDisplay(EGLNativeDisplayType(display->
wl.
display)));
1599#ifdef USE_EVENT_BACKGROUND_THREAD
1628 std::vector<GWL_Seat *>::iterator iter = std::find(
1629 display->
seats.begin(), display->
seats.end(), seat);
1630 const int index = (iter != display->
seats.cend()) ? std::distance(display->
seats.begin(), iter) :
1781 int *r_interface_slot)
1787 if (r_interface_slot) {
1788 *r_interface_slot = -1;
1792 if (reg->
name == name) {
1797 if (r_interface_slot) {
1801 *reg_link_p = reg_next;
1805 reg_link_p = ®->
next;
1826 *reg_link_p = reg_next;
1831 reg_link_p = ®->
next;
1842 const bool on_exit =
true;
1856 while (interface_slot--) {
1882 GHOST_ASSERT(interface_slot_exclude == -1 || (
uint(interface_slot_exclude) <
1884 "Invalid exclude slot");
1887 if (reg->interface_slot == interface_slot_exclude) {
1891 reg->interface_slot);
1898 params.interface_slot = reg->interface_slot;
1899 params.version = reg->version;
1900 params.user_data = reg->user_data;
1912#ifdef WITH_GHOST_WAYLAND_LIBDECOR
1913static const char *strchr_or_end(
const char *
str,
const char ch)
1915 const char *p =
str;
1916 while (!
ELEM(*p, ch,
'\0')) {
1922static bool string_elem_split_by_delim(
const char *haystack,
const char delim,
const char *needle)
1927 const size_t needle_len = strlen(needle);
1928 const char *p = haystack, *p_next;
1930 p_next = strchr_or_end(p, delim);
1931 if ((
size_t(p_next - p) == needle_len) && (memcmp(p, needle, needle_len) == 0)) {
1934 if (*p_next ==
'\0') {
1945 return a >
b ? a -
b :
b - a;
1961 const char *locale = getenv(
"LC_ALL");
1962 if (!locale || !*locale) {
1963 locale = getenv(
"LC_CTYPE");
1964 if (!locale || !*locale) {
1965 locale = getenv(
"LANG");
1966 if (!locale || !*locale) {
1977 if (
ELEM(ecode, EPIPE, ECONNRESET)) {
1978 fprintf(stderr,
"The Wayland connection broke. Did the Wayland compositor die?\n");
1982 if (ecode == EPROTO) {
1983 const wl_interface *
interface =
nullptr;
1986 "The Wayland connection experienced a protocol error %d in interface: %s\n",
1989 const char *env_debug =
"WAYLAND_DEBUG";
1990 if (getenv(env_debug) ==
nullptr) {
1991 fprintf(stderr,
"Run with the environment variable \"%s=1\" for details.\n", env_debug);
1996 fprintf(stderr,
"The Wayland connection experienced a fatal error: %s\n", strerror(ecode));
2045 fprintf(stderr,
"GHOST/Wayland: ");
2046 vfprintf(stderr, msg, arg);
2050 backtrace_fn(stderr);
2059 if (strstr(msg,
"error: XDG_RUNTIME_DIR not set in the environment") ||
2060 strstr(msg,
"error: XDG_RUNTIME_DIR is invalid or not set in the environment"))
2067#if defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND_LIBDECOR)
2073static bool ghost_wayland_is_x11_available()
2075 const char *x11_display = getenv(
"DISPLAY");
2076 if (x11_display && x11_display[0]) {
2087 if (sym >= XKB_KEY_0 && sym <= XKB_KEY_9) {
2090 else if (sym >= XKB_KEY_KP_0 && sym <= XKB_KEY_KP_9) {
2093 else if (sym >= XKB_KEY_A && sym <= XKB_KEY_Z) {
2096 else if (sym >= XKB_KEY_a && sym <= XKB_KEY_z) {
2097 gkey =
GHOST_TKey(sym - XKB_KEY_a + XKB_KEY_A);
2099 else if (sym >= XKB_KEY_F1 && sym <= XKB_KEY_F24) {
2104#define GXMAP(k, x, y) \
2217 "unhandled key: " << std::hex << std::showbase << sym <<
2218 std::dec <<
" (" << sym <<
"), " <<
2220 "scan-code: " << std::hex << std::showbase << key <<
2221 std::dec <<
" (" << key <<
")" <<
2234 case WL_POINTER_AXIS_HORIZONTAL_SCROLL: {
2237 case WL_POINTER_AXIS_VERTICAL_SCROLL: {
2248 switch (wp_tablet_tool_type) {
2249 case ZWP_TABLET_TOOL_V2_TYPE_ERASER: {
2252 case ZWP_TABLET_TOOL_V2_TYPE_PEN:
2253 case ZWP_TABLET_TOOL_V2_TYPE_BRUSH:
2254 case ZWP_TABLET_TOOL_V2_TYPE_PENCIL:
2255 case ZWP_TABLET_TOOL_V2_TYPE_AIRBRUSH:
2256 case ZWP_TABLET_TOOL_V2_TYPE_FINGER:
2257 case ZWP_TABLET_TOOL_V2_TYPE_MOUSE:
2258 case ZWP_TABLET_TOOL_V2_TYPE_LENS: {
2263 GHOST_PRINT(
"unknown tablet tool: " << wp_tablet_tool_type << std::endl);
2276#define CASE_CURSOR(shape_id, shape_name_in_theme) \
2278 info.names[int(shape_id)] = shape_name_in_theme; \
2357 "text/plain;charset=utf-8",
2366 size_t data_buf_len)
2368 std::vector<std::string_view> uris;
2369 const char file_proto[] =
"file://";
2372 const char lf =
'\n';
2374 const std::string_view
data = std::string_view(data_buf, data_buf_len);
2377 while (
pos != std::string::npos) {
2379 if (
pos == std::string::npos) {
2382 const size_t start =
pos +
sizeof(file_proto) - 1;
2386 if (
UNLIKELY(end == std::string::npos)) {
2392 if (
data[end - 1] ==
'\r') {
2396 std::string_view data_substr =
data.substr(start, end - start);
2397 uris.push_back(data_substr);
2402#ifdef USE_EVENT_BACKGROUND_THREAD
2406 sched_param sch_params;
2407 if (pthread_getschedparam(handle, &policy, &sch_params) == 0) {
2408 sch_params.sched_priority = sched_get_priority_min(policy);
2409 pthread_setschedparam(handle, policy, &sch_params);
2415 constexpr bool is_pthread = std::is_same<std::thread::native_handle_type, pthread_t>();
2427#ifdef HAVE_MEMFD_CREATE
2428 const int fd = memfd_create(name, MFD_CLOEXEC | MFD_ALLOW_SEALING);
2430 fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
2434 char *path = getenv(
"XDG_RUNTIME_DIR");
2440 asprintf(&tmpname,
"%s/%s-XXXXXX", path, name);
2441 const int fd = mkostemp(tmpname, O_CLOEXEC);
2470 info.events |= POLLIN | POLLPRI;
2473 info.events |= POLLOUT;
2475 result = poll(&info, 1, timeout_ms);
2477 fd_set rfdset, *rfdp =
nullptr;
2478 fd_set wfdset, *wfdp =
nullptr;
2479 struct timeval tv, *tvp =
nullptr;
2486 FD_SET(fd, &rfdset);
2491 FD_SET(fd, &wfdset);
2495 if (timeout_ms >= 0) {
2496 tv.tv_sec = timeout_ms / 1000;
2497 tv.tv_usec = (timeout_ms % 1000) * 1000;
2534#ifdef USE_EVENT_BACKGROUND_THREAD
2544 server_mutex->lock();
2550 }
while (
state == 0);
2555 std::mutex *server_mutex)
2558 server_mutex->lock();
2561 bool wait_on_fd =
false;
2572 server_mutex->unlock();
2580 server_mutex->unlock();
2586 server_mutex->lock();
2591 server_mutex->unlock();
2602 case WL_SHM_FORMAT_ARGB8888: {
2622 enum wl_shm_format
format,
2623 void **r_buffer_data,
2624 size_t *r_buffer_data_size)
2627 wl_buffer *buffer =
nullptr;
2630 const int32_t buffer_size = buffer_stride * size_xy[1];
2631 if (posix_fallocate(fd, 0, buffer_size) == 0) {
2632 void *buffer_data = mmap(
nullptr, buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
2633 if (buffer_data != MAP_FAILED) {
2634 wl_shm_pool *pool = wl_shm_create_pool(shm, fd, buffer_size);
2635 buffer = wl_shm_pool_create_buffer(pool, 0,
UNPACK2(size_xy), buffer_stride,
format);
2636 wl_shm_pool_destroy(pool);
2638 *r_buffer_data = buffer_data;
2639 *r_buffer_data_size = size_t(buffer_size);
2643 munmap(buffer_data, buffer_size);
2658 ssize_t nbytes_read =
read(fd,
data, nbytes);
2659 if (nbytes_read > 0) {
2660 while (nbytes_read < nbytes) {
2661 const ssize_t nbytes_extra =
read(
2662 fd,
static_cast<char *
>(
data) + nbytes_read, nbytes - nbytes_read);
2663 if (nbytes_extra > 0) {
2664 nbytes_read += nbytes_extra;
2668 nbytes_read = nbytes_extra;
2688 char data[4096 -
sizeof(ByteChunk *)];
2693 ByteChunk *chunk_first =
static_cast<ByteChunk *
>(malloc(
sizeof(ByteChunk)));
2695 ByteChunk **chunk_link_p = &chunk_first;
2696 ByteChunk *chunk = chunk_first;
2703 chunk->next =
nullptr;
2705 const ssize_t len_chunk =
read_exhaustive(fd, chunk->data,
sizeof(ByteChunk::data));
2706 if (len_chunk <= 0) {
2710 if (chunk == chunk_first) {
2711 chunk_first =
nullptr;
2716 *chunk_link_p = chunk;
2717 chunk_link_p = &chunk->next;
2720 if (len_chunk !=
sizeof(ByteChunk::data)) {
2723 chunk =
static_cast<ByteChunk *
>(malloc(
sizeof(ByteChunk)));
2727 char *buf =
nullptr;
2729 buf =
static_cast<char *
>(malloc(
len + (nil_terminate ? 1 : 0)));
2738 if (nil_terminate) {
2746 char *buf_stride = buf;
2747 while (chunk_first) {
2749 const size_t len_chunk = std::min(
len,
sizeof(chunk_first->data));
2750 memcpy(buf_stride, chunk_first->data, len_chunk);
2751 buf_stride += len_chunk;
2754 ByteChunk *chunk = chunk_first->next;
2756 chunk_first = chunk;
2775 GHOST_ASSERT((image_size_x % scale) == 0 && (image_size_y % scale) == 0,
2776 "The size must be a multiple of the scale!");
2778 wl_surface_set_buffer_scale(
wl_surface, scale);
2780 wl_surface_damage(
wl_surface, 0, 0, image_size_x, image_size_y);
2792 if ((image_size_x % scale) == 0 && (image_size_y % scale) == 0) {
2802 const char **r_cursor_name)
2806 wl_cursor *wl_cursor =
nullptr;
2809 if (cursor_name[0] !=
'\0') {
2821 GHOST_PRINT(
"cursor '" << cursor_name <<
"' does not exist" << std::endl);
2826 if (r_cursor_name && wl_cursor) {
2827 *r_cursor_name = cursor_name;
2846 wl_pointer_set_cursor(
2854 for (zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->
wp.
tablet_tools) {
2856 zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2));
2857 zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2,
2862#ifdef USE_KDE_TABLET_HIDDEN_CURSOR_HACK
2881 wl_pointer_set_cursor(seat->
wl.
pointer, seat->
pointer.serial,
nullptr, 0, 0);
2882 for (zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->
wp.
tablet_tools) {
2883 zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2, seat->
tablet.
serial,
nullptr, 0, 0);
2888 const wl_cursor_image *wl_image,
2915 for (zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->
wp.
tablet_tools) {
2917 zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2));
2919 zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2,
2944 const bool is_hardware,
2949 const bool use_visible = is_hardware && visible;
2985#ifdef USE_EVENT_BACKGROUND_THREAD
2997 return wl_cursor->image_count > 1;
3006 auto cursor_anim_frame_step_fn =
3012 while (!anim_handle->exit_pending.load()) {
3013 std::this_thread::sleep_for(std::chrono::milliseconds(delay));
3014 if (!anim_handle->exit_pending.load()) {
3015 std::lock_guard lock_server_guard{*server_mutex};
3016 if (!anim_handle->exit_pending.load()) {
3018 frame = (frame + 1) % wl_cursor->image_count;
3019 wl_cursor_image *image = wl_cursor->images[frame];
3022 delay = wl_cursor->images[frame]->delay;
3036 std::thread cursor_anim_thread(cursor_anim_frame_step_fn, seat, anim_handle, delay);
3039 cursor_anim_thread.detach();
3090#define LOG (&LOG_WL_KEYBOARD_DEPRESSED_STATE)
3109 CLOG_WARN(
LOG,
"modifier (%d) has negative keys held (%d)!", index, value);
3161#define LOG (&LOG_WL_RELATIVE_POINTER)
3168 const wl_fixed_t
xy[2],
3174#ifdef USE_GNOME_CONFINE_HACK
3195 zwp_relative_pointer_v1 * ,
3196 const uint32_t utime_hi,
3197 const uint32_t utime_lo,
3198 const wl_fixed_t dx,
3199 const wl_fixed_t dy,
3210 const wl_fixed_t xy_next[2] = {
3234#define LOG (&LOG_WL_DATA_SOURCE)
3253 const char *mime_receive,
3255 const bool nil_terminate,
3259 const bool pipefd_ok = pipe(pipefd) == 0;
3261 wl_data_offer_receive(data_offer->
wl.
id, mime_receive, pipefd[1]);
3265 CLOG_WARN(
LOG,
"error creating pipe: %s", std::strerror(errno));
3276 char *buf =
nullptr;
3279 if (buf ==
nullptr) {
3280 CLOG_WARN(
LOG,
"unable to pipe into buffer: %s", std::strerror(errno));
3291 const char *mime_receive,
3293 const bool nil_terminate,
3297 const bool pipefd_ok = pipe(pipefd) == 0;
3299 zwp_primary_selection_offer_v1_receive(data_offer->
wp.
id, mime_receive, pipefd[1]);
3303 CLOG_WARN(
LOG,
"error creating pipe: %s", std::strerror(errno));
3310 char *buf =
nullptr;
3313 if (buf ==
nullptr) {
3314 CLOG_WARN(
LOG,
"unable to pipe into buffer: %s", std::strerror(errno));
3343 auto write_file_fn = [](
GWL_Seat *seat,
const int fd) {
3348 CLOG_WARN(
LOG,
"error writing to clipboard: %s", std::strerror(errno));
3355 std::thread write_thread(write_file_fn, seat, fd);
3356 write_thread.detach();
3368 wl_data_source_destroy(wl_data_source);
3405 const uint32_t dnd_action)
3407 CLOG_INFO(
LOG, 2,
"handle_action (dnd_action=%u)", dnd_action);
3428#define LOG (&LOG_WL_DATA_OFFER)
3432 const char *mime_type)
3437 data_offer->
types.insert(mime_type);
3442 const uint32_t source_actions)
3445 CLOG_INFO(
LOG, 2,
"source_actions (%u)", source_actions);
3447 data_offer->
dnd.
source_actions = (
enum wl_data_device_manager_dnd_action)source_actions;
3452 const uint32_t dnd_action)
3457 data_offer->
dnd.
action = (
enum wl_data_device_manager_dnd_action)dnd_action;
3475#define LOG (&LOG_WL_DATA_DEVICE)
3495 data_offer->
wl.
id = id;
3501 const uint32_t serial,
3523 wl_data_offer_destroy(data_offer->
wl.
id);
3532 data_offer->
dnd.
xy[0] =
x;
3533 data_offer->
dnd.
xy[1] =
y;
3535 wl_data_offer_set_actions(
id,
3536 WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY |
3537 WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE,
3538 WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY);
3542 wl_data_offer_accept(
id, serial, type);
3576 const uint32_t time,
3615 const char *mime_receive =
"";
3618 if (data_offer->
types.count(type)) {
3619 mime_receive = type;
3624 CLOG_INFO(
LOG, 2,
"drop mime_recieve=%s", mime_receive);
3626 auto read_drop_data_fn = [](
GWL_Seat *
const seat,
3629 const char *mime_receive) {
3634 size_t data_buf_len = 0;
3636 data_offer, mime_receive,
nullptr, nil_terminate, &data_buf_len);
3638 CLOG_INFO(
LOG, 2,
"read_drop_data mime_receive=%s, data_len=%zu", mime_receive, data_buf_len);
3640 wl_data_offer_finish(data_offer->
wl.
id);
3641 wl_data_offer_destroy(data_offer->
wl.
id);
3644 data_offer =
nullptr;
3648 if (data_buf !=
nullptr) {
3650 void *ghost_dnd_data =
nullptr;
3658 flist->
count = int(uris.size());
3659 flist->
strings =
static_cast<uint8_t **
>(malloc(uris.size() *
sizeof(uint8_t *)));
3660 for (
size_t i = 0;
i < uris.size();
i++) {
3661 flist->
strings[
i] =
reinterpret_cast<uint8_t *
>(
3667 ghost_dnd_data = flist;
3671 ghost_dnd_data = (
void *)data_buf;
3693 free(
const_cast<char *
>(data_buf));
3699 std::thread read_thread(
3701 read_thread.detach();
3720 if (
id ==
nullptr) {
3750#define LOG (&LOG_WL_CURSOR_BUFFER)
3757 wl_buffer_destroy(wl_buffer);
3759 if (wl_buffer == cursor->
wl.
buffer) {
3778#define LOG (&LOG_WL_CURSOR_SURFACE)
3787 int output_scale_floor =
output->scale;
3799 if (output_scale_floor > 1 &&
output->has_scale_fractional) {
3803 scale = std::max(output_scale_floor, scale);
3806 if (scale > 0 && seat_state_pointer->
theme_scale != scale) {
3809 if (wl_surface_cursor) {
3810 wl_surface_set_buffer_scale(wl_surface_cursor, scale);
3840 seat_state_pointer->
outputs.insert(reg_output);
3856 seat_state_pointer->
outputs.erase(reg_output);
3865 CLOG_INFO(
LOG, 2,
"handle_preferred_buffer_scale (factor=%d)", factor);
3868#if defined(WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION) && \
3869 defined(WL_SURFACE_PREFERRED_BUFFER_TRANSFORM_SINCE_VERSION)
3870static void cursor_surface_handle_preferred_buffer_transform(
void * ,
3883#if defined(WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION) && \
3884 defined(WL_SURFACE_PREFERRED_BUFFER_TRANSFORM_SINCE_VERSION)
3886 cursor_surface_handle_preferred_buffer_transform,
3899#define LOG (&LOG_WL_POINTER)
3903 const uint32_t serial,
3905 const wl_fixed_t surface_x,
3906 const wl_fixed_t surface_y)
3921 seat->
pointer.serial = serial;
3922 seat->
pointer.xy[0] = surface_x;
3923 seat->
pointer.xy[1] = surface_y;
3945 static_cast<GWL_Seat *
>(
data)->pointer.
wl.surface_window =
nullptr;
3955 const uint32_t time,
3956 const wl_fixed_t surface_x,
3957 const wl_fixed_t surface_y)
3962 seat->
pointer.xy[0] = surface_x;
3963 seat->
pointer.xy[1] = surface_y;
3973 const uint32_t serial,
3974 const uint32_t time,
3975 const uint32_t button,
3976 const uint32_t
state)
3987 case WL_POINTER_BUTTON_STATE_RELEASED:
3990 case WL_POINTER_BUTTON_STATE_PRESSED:
4012 const uint32_t time,
4013 const uint32_t axis,
4014 const wl_fixed_t value)
4022 CLOG_INFO(
LOG, 2,
"axis (axis=%u, value=%d)", axis, value);
4063 GHOST_ASSERT(event_ms == 0,
"Scroll events are not expected to have a time!");
4066 for (
int i = 0;
i < 2;
i++) {
4077 if (ps.
axis_source == WL_POINTER_AXIS_SOURCE_WHEEL) {
4085 else if (ps.
axis_source == WL_POINTER_AXIS_SOURCE_FINGER) {
4092 for (
int i = 0;
i < 2;
i++) {
4111 if (ps.
axis_source == WL_POINTER_AXIS_SOURCE_WHEEL) {
4198 const int button_index = button_enum_offset / 2;
4199 const bool button_down = (button_index * 2) == button_enum_offset;
4203 seat->
pointer.buttons.set(ebutton, button_down);
4216 uint32_t axis_source)
4218 CLOG_INFO(
LOG, 2,
"axis_source (axis_source=%u)", axis_source);
4250 CLOG_INFO(
LOG, 2,
"axis_discrete (axis=%u, discrete=%d)", axis, discrete);
4266 CLOG_INFO(
LOG, 2,
"axis_value120 (axis=%u, value120=%d)", axis, value120);
4276#ifdef WL_POINTER_AXIS_RELATIVE_DIRECTION_ENUM
4277static void pointer_handle_axis_relative_direction(
void *
data,
4283 CLOG_INFO(
LOG, 2,
"axis_relative_direction (axis=%u, direction=%u)", axis, direction);
4290 WL_POINTER_AXIS_RELATIVE_DIRECTION_INVERTED);
4305#ifdef WL_POINTER_AXIS_RELATIVE_DIRECTION_ENUM
4306 pointer_handle_axis_relative_direction,
4318#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE
4319static CLG_LogRef LOG_WL_POINTER_GESTURE_HOLD = {
"ghost.wl.handle.pointer_gesture.hold"};
4320# define LOG (&LOG_WL_POINTER_GESTURE_HOLD)
4322static void gesture_hold_handle_begin(
4324 zwp_pointer_gesture_hold_v1 * ,
4333static void gesture_hold_handle_end(
void * ,
4334 zwp_pointer_gesture_hold_v1 * ,
4342static const zwp_pointer_gesture_hold_v1_listener gesture_hold_listener = {
4343 gesture_hold_handle_begin,
4344 gesture_hold_handle_end,
4356#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE
4357static CLG_LogRef LOG_WL_POINTER_GESTURE_PINCH = {
"ghost.wl.handle.pointer_gesture.pinch"};
4358# define LOG (&LOG_WL_POINTER_GESTURE_PINCH)
4360static void gesture_pinch_handle_begin(
void *
data,
4361 zwp_pointer_gesture_pinch_v1 * ,
4417static void gesture_pinch_handle_update(
void *
data,
4418 zwp_pointer_gesture_pinch_v1 * ,
4423 wl_fixed_t rotation)
4430 "update (dx=%.3f, dy=%.3f, scale=%.3f, rotation=%.3f)",
4431 wl_fixed_to_double(dx),
4432 wl_fixed_to_double(dy),
4433 wl_fixed_to_double(scale),
4434 wl_fixed_to_double(rotation));
4454 if (scale_as_delta_px) {
4465 if (rotation_as_delta_px) {
4471 rotation_as_delta_px,
4478static void gesture_pinch_handle_end(
void *
data,
4479 zwp_pointer_gesture_pinch_v1 * ,
4490static const zwp_pointer_gesture_pinch_v1_listener gesture_pinch_listener = {
4491 gesture_pinch_handle_begin,
4492 gesture_pinch_handle_update,
4493 gesture_pinch_handle_end,
4510#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE
4511static CLG_LogRef LOG_WL_POINTER_GESTURE_SWIPE = {
"ghost.wl.handle.pointer_gesture.swipe"};
4512# define LOG (&LOG_WL_POINTER_GESTURE_SWIPE)
4514static void gesture_swipe_handle_begin(
4516 zwp_pointer_gesture_swipe_v1 * ,
4525static void gesture_swipe_handle_update(
4527 zwp_pointer_gesture_swipe_v1 * ,
4532 CLOG_INFO(
LOG, 2,
"update (dx=%.3f, dy=%.3f)", wl_fixed_to_double(dx), wl_fixed_to_double(dy));
4535static void gesture_swipe_handle_end(
4537 zwp_pointer_gesture_swipe_v1 * ,
4545static const zwp_pointer_gesture_swipe_v1_listener gesture_swipe_listener = {
4546 gesture_swipe_handle_begin,
4547 gesture_swipe_handle_update,
4548 gesture_swipe_handle_end,
4565#define LOG (&LOG_WL_TOUCH)
4645#define LOG (&LOG_WL_TABLET_TOOL)
4648 zwp_tablet_tool_v2 * ,
4649 const uint32_t tool_type)
4659 zwp_tablet_tool_v2 * ,
4667 zwp_tablet_tool_v2 * ,
4675 zwp_tablet_tool_v2 * ,
4676 const uint32_t capability)
4680 "capability (tilt=%d, distance=%d, rotation=%d, slider=%d, wheel=%d)",
4681 (capability & ZWP_TABLET_TOOL_V2_CAPABILITY_TILT) != 0,
4682 (capability & ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE) != 0,
4683 (capability & ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION) != 0,
4684 (capability & ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER) != 0,
4685 (capability & ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL) != 0);
4707 zwp_tablet_tool_v2 * ,
4708 const uint32_t serial,
4742 zwp_tablet_tool_v2 * )
4752 zwp_tablet_tool_v2 * ,
4753 const uint32_t serial)
4775 zwp_tablet_tool_v2 * ,
4783 tablet_tool->
xy[0] =
x;
4784 tablet_tool->
xy[1] =
y;
4785 tablet_tool->
has_xy =
true;
4791 zwp_tablet_tool_v2 * ,
4792 const uint32_t pressure)
4794 const float pressure_unit = float(pressure) / 65535;
4805 zwp_tablet_tool_v2 * ,
4812 zwp_tablet_tool_v2 * ,
4813 const wl_fixed_t tilt_x,
4814 const wl_fixed_t tilt_y)
4818 const float tilt_unit[2] = {
4819 float(wl_fixed_to_double(tilt_x) / 90.0f),
4820 float(wl_fixed_to_double(tilt_y) / 90.0f),
4825 td.
Xtilt = std::clamp(tilt_unit[0], -1.0f, 1.0f);
4826 td.
Ytilt = std::clamp(tilt_unit[1], -1.0f, 1.0f);
4832 zwp_tablet_tool_v2 * ,
4839 zwp_tablet_tool_v2 * ,
4845 zwp_tablet_tool_v2 * ,
4863 zwp_tablet_tool_v2 * ,
4864 const uint32_t serial,
4865 const uint32_t button,
4866 const uint32_t
state)
4873 bool is_press =
false;
4875 case WL_POINTER_BUTTON_STATE_RELEASED:
4878 case WL_POINTER_BUTTON_STATE_PRESSED:
4909 zwp_tablet_tool_v2 * ,
4910 const uint32_t time)
4921 bool has_motion =
false;
4935 if (tablet_tool->
has_xy ==
false) {
4962 const int button_index = button_enum_offset / 2;
4963 const bool button_down = (button_index * 2) == button_enum_offset;
5026#define LOG (&LOG_WL_TABLET_SEAT)
5029 zwp_tablet_seat_v2 * ,
5036 zwp_tablet_seat_v2 * ,
5037 zwp_tablet_tool_v2 *
id)
5043 tablet_tool->
seat = seat;
5049 wl_surface_add_listener(
5058 zwp_tablet_seat_v2 * ,
5059 zwp_tablet_pad_v2 *
id)
5079#define LOG (&LOG_WL_KEYBOARD)
5085 const uint32_t
size)
5089 if ((!
data) || (
format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)) {
5090 CLOG_INFO(
LOG, 2,
"keymap (no data or wrong version)");
5095 char *map_str =
static_cast<char *
>(mmap(
nullptr,
size, PROT_READ, MAP_PRIVATE, fd, 0));
5096 if (map_str == MAP_FAILED) {
5098 CLOG_INFO(
LOG, 2,
"keymap mmap failed: %s", std::strerror(errno));
5102 xkb_keymap *keymap = xkb_keymap_new_from_string(
5103 seat->
xkb.
context, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
5104 munmap(map_str,
size);
5126 XKB_COMPOSE_STATE_NO_FLAGS);
5131 seat->
xkb.
state = xkb_state_new(keymap);
5159#ifdef USE_NON_LATIN_KB_WORKAROUND
5168 if (!(sym_test >= XKB_KEY_0 && sym_test <= XKB_KEY_9)) {
5178 xkb_keymap_unref(keymap);
5188 const uint32_t serial,
5215 uint32_t key = std::numeric_limits<uint32_t>::max();
5216 xkb_keysym_t sym = 0;
5222 CLOG_INFO(
LOG, 2,
"enter (key_held=%d)",
int(key_code));
5223 const xkb_keysym_t sym = xkb_state_key_get_one_sym(seat->
xkb.
state, key_code);
5229 if (xkb_keymap_key_repeats(xkb_state_get_keymap(seat->
xkb.
state), key_code)) {
5239 if ((repeat.key != std::numeric_limits<uint32_t>::max()) && (seat->
key_repeat.
rate > 0)) {
5242#ifdef USE_EVENT_BACKGROUND_THREAD
5250 const xkb_keycode_t key_code = repeat.key +
EVDEV_OFFSET;
5254 key_repeat_payload->
seat = seat;
5255 key_repeat_payload->
key_code = key_code;
5282 seat->
keyboard.wl.surface_window =
nullptr;
5285#ifdef USE_EVENT_BACKGROUND_THREAD
5300 xkb_state *xkb_state_empty,
5301 xkb_state *xkb_state_empty_with_numlock,
5302 xkb_state *xkb_state_empty_with_shift,
5303 const bool xkb_use_non_latin_workaround,
5304 const xkb_keycode_t key)
5307 xkb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state_empty, key);
5317 if (sym >= XKB_KEY_KP_Home && sym <= XKB_KEY_KP_Delete) {
5318 if (xkb_state_empty_with_numlock) {
5319 const xkb_keysym_t sym_test = xkb_state_key_get_one_sym(xkb_state_empty_with_numlock, key);
5320 if (sym_test != XKB_KEY_NoSymbol) {
5326#ifdef USE_NON_LATIN_KB_WORKAROUND
5328 if (xkb_state_empty_with_shift && xkb_use_non_latin_workaround) {
5329 const xkb_keysym_t sym_test = xkb_state_key_get_one_sym(xkb_state_empty_with_shift, key);
5330 if (sym_test != XKB_KEY_NoSymbol) {
5332 GHOST_ASSERT(sym_test >= XKB_KEY_0 && sym_test <= XKB_KEY_9,
"Unexpected key");
5338 (void)xkb_state_empty_with_shift;
5339 (void)xkb_use_non_latin_workaround;
5347 xkb_compose_state *compose_state,
5349 const xkb_keycode_t key,
5352 const xkb_keysym_t sym = xkb_state_key_get_one_sym(
state, key);
5353 const xkb_compose_feed_result
result = xkb_compose_state_feed(compose_state, sym);
5354 bool handled =
false;
5356 if (
result == XKB_COMPOSE_FEED_ACCEPTED) {
5357 switch (xkb_compose_state_get_status(compose_state)) {
5358 case XKB_COMPOSE_NOTHING: {
5361 case XKB_COMPOSE_COMPOSING: {
5362 r_utf8_buf[0] =
'\0';
5366 case XKB_COMPOSE_COMPOSED: {
5368 const int utf8_buf_compose_len = xkb_compose_state_get_utf8(
5369 compose_state, utf8_buf_compose,
sizeof(utf8_buf_compose));
5370 if (utf8_buf_compose_len > 0) {
5382 CLOG_WARN(
LOG,
"key (compose_size=%d) exceeds the maximum size", utf8_buf_compose_len);
5389 case XKB_COMPOSE_CANCELLED: {
5395 r_utf8_buf[0] =
'\0';
5434 const uint32_t serial,
5435 const uint32_t time,
5437 const uint32_t
state)
5454 if (sym == XKB_KEY_NoSymbol) {
5455 CLOG_INFO(
LOG, 2,
"key (code=%d, state=%u, no symbol, skipped)",
int(key_code),
state);
5462 case WL_KEYBOARD_KEY_STATE_RELEASED:
5465 case WL_KEYBOARD_KEY_STATE_PRESSED:
5470#ifdef USE_EVENT_BACKGROUND_THREAD
5479 enum { NOP = 1, RESET, CANCEL } timer_action = NOP;
5485 timer_action = CANCEL;
5487 else if (key_code == key_repeat_payload->
key_code) {
5489 timer_action = CANCEL;
5491 else if (xkb_keymap_key_repeats(xkb_state_get_keymap(seat->
xkb.
state), key_code)) {
5494 timer_action = CANCEL;
5502 timer_action = RESET;
5506 switch (timer_action) {
5509 key_repeat_payload =
nullptr;
5518 delete key_repeat_payload;
5519 key_repeat_payload =
nullptr;
5538 xkb_state_key_get_utf8(seat->
xkb.
state, key_code, utf8_buf,
sizeof(utf8_buf));
5549 new GHOST_EventKey(event_ms, etype, win, gkey,
false, utf8_buf));
5553 if (key_repeat_payload ==
nullptr) {
5556 xkb_keymap_key_repeats(xkb_state_get_keymap(seat->
xkb.
state), key_code))
5559 key_repeat_payload->
seat = seat;
5560 key_repeat_payload->
key_code = key_code;
5565 if (key_repeat_payload) {
5572 const uint32_t serial,
5573 const uint32_t mods_depressed,
5574 const uint32_t mods_latched,
5575 const uint32_t mods_locked,
5576 const uint32_t group)
5580 "modifiers (depressed=%u, latched=%u, locked=%u, group=%u)",
5587 xkb_state_update_mask(seat->
xkb.
state, mods_depressed, mods_latched, mods_locked, 0, 0, group);
5599#ifdef USE_EVENT_BACKGROUND_THREAD
5615 CLOG_INFO(
LOG, 2,
"info (rate=%d, delay=%d)", rate, delay);
5622#ifdef USE_EVENT_BACKGROUND_THREAD
5650#define LOG (&LOG_WL_PRIMARY_SELECTION_OFFER)
5653 zwp_primary_selection_offer_v1 *
id,
5658 if (data_offer->
wp.
id !=
id) {
5659 CLOG_INFO(
LOG, 2,
"offer: %p: offer for unknown selection %p of %s (skipped)",
data,
id, type);
5663 data_offer->
types.insert(std::string(type));
5679#define LOG (&LOG_WL_PRIMARY_SELECTION_DEVICE)
5683 zwp_primary_selection_device_v1 * ,
5684 zwp_primary_selection_offer_v1 *
id)
5689 data_offer->
wp.
id = id;
5695 zwp_primary_selection_device_v1 * ,
5696 zwp_primary_selection_offer_v1 *
id)
5707 if (
id ==
nullptr) {
5714 zwp_primary_selection_offer_v1_get_user_data(
id));
5732#define LOG (&LOG_WL_PRIMARY_SELECTION_SOURCE)
5735 zwp_primary_selection_source_v1 * ,
5748 CLOG_WARN(
LOG,
"error writing to primary clipboard: %s", std::strerror(errno));
5755 std::thread write_thread(write_file_fn, primary, fd);
5756 write_thread.detach();
5783#ifdef WITH_INPUT_IME
5787 GHOST_TEventImeData event_ime_data;
5798 GHOST_IWindow *window,
5799 GHOST_TEventImeData *customdata)
5800 : GHOST_Event(msec, type, window)
5804 this->event_ime_data = *customdata;
5805 this->
m_data = &this->event_ime_data;
5809static CLG_LogRef LOG_WL_TEXT_INPUT = {
"ghost.wl.handle.text_input"};
5810# define LOG (&LOG_WL_TEXT_INPUT)
5812static void text_input_handle_enter(
void *
data,
5813 zwp_text_input_v3 * ,
5822 seat->ime.surface_window = surface;
5825 if (seat->ime.is_enabled) {
5826 zwp_text_input_v3_enable(seat->
wp.text_input);
5827 zwp_text_input_v3_commit(seat->
wp.text_input);
5831static void text_input_handle_leave(
void *
data,
5832 zwp_text_input_v3 * ,
5841 if (seat->ime.surface_window == surface) {
5842 seat->ime.surface_window =
nullptr;
5845 zwp_text_input_v3_disable(seat->
wp.text_input);
5846 zwp_text_input_v3_commit(seat->
wp.text_input);
5849static void text_input_handle_preedit_string(
void *
data,
5850 zwp_text_input_v3 * ,
5857 "preedit_string (text=\"%s\", cursor_begin=%d, cursor_end=%d)",
5858 text ? text :
"<null>",
5863 if (seat->ime.has_preedit ==
false) {
5865 gwl_seat_ime_full_reset(seat);
5868 seat->ime.composite_is_null = (text ==
nullptr);
5869 if (!seat->ime.composite_is_null) {
5870 seat->ime.event_ime_data.composite = text;
5872 seat->ime.event_ime_data.cursor_position = cursor_begin;
5873 seat->ime.event_ime_data.target_start = cursor_begin;
5874 seat->ime.event_ime_data.target_end = cursor_end;
5877 seat->ime.has_preedit_string_callback =
true;
5880static void text_input_handle_commit_string(
void *
data,
5881 zwp_text_input_v3 * ,
5884 CLOG_INFO(
LOG, 2,
"commit_string (text=\"%s\")", text ? text :
"<null>");
5887 seat->ime.result_is_null = (text ==
nullptr);
5888 seat->ime.event_ime_data.result = text ? text :
"";
5889 seat->ime.event_ime_data.cursor_position = seat->ime.event_ime_data.result.size();
5891 seat->ime.has_commit_string_callback =
true;
5894static void text_input_handle_delete_surrounding_text(
void * ,
5895 zwp_text_input_v3 * ,
5896 uint32_t before_length,
5897 uint32_t after_length)
5901 "delete_surrounding_text (before_length=%u, after_length=%u)",
5909static void text_input_handle_done(
void *
data,
5910 zwp_text_input_v3 * ,
5922 if (seat->ime.has_commit_string_callback) {
5923 if (seat->ime.has_preedit) {
5924 const bool is_end = seat->ime.composite_is_null;
5926 seat->ime.has_preedit =
false;
5949 if (seat->ime.has_preedit ==
false) {
5950 gwl_seat_ime_preedit_reset(seat);
5953 else if (seat->ime.has_preedit_string_callback) {
5954 const bool is_end = seat->ime.composite_is_null;
5957 seat->ime.has_preedit =
false;
5962 const bool is_start = seat->ime.has_preedit ==
false;
5964 seat->ime.has_preedit =
true;
5969 &seat->ime.event_ime_data));
5973 seat->ime.has_preedit_string_callback =
false;
5974 seat->ime.has_commit_string_callback =
false;
5977static zwp_text_input_v3_listener text_input_listener = {
5978 text_input_handle_enter,
5979 text_input_handle_leave,
5980 text_input_handle_preedit_string,
5981 text_input_handle_commit_string,
5982 text_input_handle_delete_surrounding_text,
5983 text_input_handle_done,
5997#define LOG (&LOG_WL_SEAT)
6002 if (pointer_gestures ==
nullptr) {
6007#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE
6008 if (seat->
wp.pointer_gesture_hold) {
6013#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE
6019#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE
6020 if (seat->
wp.pointer_gesture_swipe) {
6029 if (found ==
false) {
6042 if (pointer_gestures ==
nullptr) {
6046 const uint pointer_gestures_version = zwp_pointer_gestures_v1_get_version(pointer_gestures);
6047#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE
6048 if (pointer_gestures_version >= ZWP_POINTER_GESTURES_V1_GET_HOLD_GESTURE_SINCE_VERSION)
6050 zwp_pointer_gesture_hold_v1 *gesture = zwp_pointer_gestures_v1_get_hold_gesture(
6052 zwp_pointer_gesture_hold_v1_set_user_data(gesture, seat);
6053 zwp_pointer_gesture_hold_v1_add_listener(gesture, &gesture_hold_listener, seat);
6054 seat->
wp.pointer_gesture_hold = gesture;
6057#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE
6059 zwp_pointer_gesture_pinch_v1 *gesture = zwp_pointer_gestures_v1_get_pinch_gesture(
6061 zwp_pointer_gesture_pinch_v1_set_user_data(gesture, seat);
6062 zwp_pointer_gesture_pinch_v1_add_listener(gesture, &gesture_pinch_listener, seat);
6066#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE
6068 zwp_pointer_gesture_swipe_v1 *gesture = zwp_pointer_gestures_v1_get_swipe_gesture(
6070 zwp_pointer_gesture_swipe_v1_set_user_data(gesture, seat);
6071 zwp_pointer_gesture_swipe_v1_add_listener(gesture, &gesture_swipe_listener, seat);
6072 seat->
wp.pointer_gesture_swipe = gesture;
6086 if (pointer_gestures ==
nullptr) {
6089#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE
6091 zwp_pointer_gesture_hold_v1 **gesture_p = &seat->
wp.pointer_gesture_hold;
6093 zwp_pointer_gesture_hold_v1_destroy(*gesture_p);
6094 *gesture_p =
nullptr;
6098#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE
6102 zwp_pointer_gesture_pinch_v1_destroy(*gesture_p);
6103 *gesture_p =
nullptr;
6107#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE
6109 zwp_pointer_gesture_swipe_v1 **gesture_p = &seat->
wp.pointer_gesture_swipe;
6111 zwp_pointer_gesture_swipe_v1_destroy(*gesture_p);
6112 *gesture_p =
nullptr;
6133 env = getenv(
"XCURSOR_THEME");
6136 env = getenv(
"XCURSOR_SIZE");
6139 if (env && (*env !=
'\0')) {
6140 char *env_end =
nullptr;
6143 const long value = strtol(env, &env_end, 10);
6144 if ((*env_end ==
'\0') && (value > 0)) {
6194#ifdef USE_EVENT_BACKGROUND_THREAD
6211 wl_touch_set_user_data(seat->
wl.
touch, seat);
6220 wl_touch_destroy(seat->
wl.
touch);
6226 [[maybe_unused]] wl_seat *wl_seat,
6227 const uint32_t capabilities)
6231 "capabilities (pointer=%d, keyboard=%d, touch=%d)",
6232 (capabilities & WL_SEAT_CAPABILITY_POINTER) != 0,
6233 (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) != 0,
6234 (capabilities & WL_SEAT_CAPABILITY_TOUCH) != 0);
6239 if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
6246 if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
6253 if (capabilities & WL_SEAT_CAPABILITY_TOUCH) {
6264 static_cast<GWL_Seat *
>(
data)->name = std::string(name);
6281#define LOG (&LOG_WL_XDG_OUTPUT)
6291 output->position_logical[0] =
x;
6292 output->position_logical[1] =
y;
6293 output->has_position_logical =
true;
6301 CLOG_INFO(
LOG, 2,
"logical_size [%d, %d]", width, height);
6304 if (
output->size_native[0] != 0 &&
output->size_native[1] != 0) {
6312 int width_native =
output->size_native[(
output->transform & WL_OUTPUT_TRANSFORM_90) ? 1 : 0];
6314 GHOST_PRINT(
"xdg_output scale did not match, overriding with wl_output scale\n");
6316#ifdef USE_GNOME_CONFINE_HACK
6326 output->size_logical[0] = width;
6327 output->size_logical[1] = height;
6328 output->has_size_logical =
true;
6337 if (zxdg_output_v1_get_version(
output->xdg.output) < 3) {
6351 const char *description)
6353 CLOG_INFO(
LOG, 2,
"description (description=\"%s\")", description);
6373#define LOG (&LOG_WL_OUTPUT)
6380 const int32_t physical_height,
6388 "geometry (make=\"%s\", model=\"%s\", transform=%d, size=[%d, %d])",
6398 output->model = std::string(model);
6399 output->size_mm[0] = physical_width;
6400 output->size_mm[1] = physical_height;
6405 const uint32_t flags,
6410 if ((flags & WL_OUTPUT_MODE_CURRENT) == 0) {
6414 CLOG_INFO(
LOG, 2,
"mode (size=[%d, %d], flags=%u)", width, height, flags);
6417 output->size_native[0] = width;
6418 output->size_native[1] = height;
6435 if (
output->transform & WL_OUTPUT_TRANSFORM_90) {
6436 std::swap(size_native[0], size_native[1]);
6440 if (
output->has_size_logical) {
6446 "Screen size values were not set when they were expected to be.");
6449 output->has_scale_fractional =
true;
6468 const char *description)
6492#define LOG (&LOG_WL_XDG_WM_BASE)
6497 xdg_wm_base_pong(xdg_wm_base, serial);
6512#ifdef WITH_GHOST_WAYLAND_LIBDECOR
6514static CLG_LogRef LOG_WL_LIBDECOR = {
"ghost.wl.handle.libdecor"};
6515# define LOG (&LOG_WL_LIBDECOR)
6517static void decor_handle_error(libdecor * ,
6518 enum libdecor_error
error,
6519 const char *message)
6525 GHOST_PRINT(
"decoration error (" <<
error <<
"): " << message << std::endl);
6529static libdecor_interface libdecor_interface = {
6544#define LOG (&LOG_WL_REGISTRY)
6554 wl_registry_bind(display->
wl.
registry,
params.name, &wl_compositor_interface, version));
6562 wl_compositor_destroy(*value_p);
6574 decor.
shell =
static_cast<xdg_wm_base *
>(
6575 wl_registry_bind(display->
wl.
registry,
params.name, &xdg_wm_base_interface, version));
6585 xdg_wm_base **value_p = &decor.
shell;
6587 xdg_wm_base_destroy(*value_p);
6600 decor.
manager =
static_cast<zxdg_decoration_manager_v1 *
>(wl_registry_bind(
6601 display->
wl.
registry,
params.name, &zxdg_decoration_manager_v1_interface, version));
6610 zxdg_decoration_manager_v1 **value_p = &decor.
manager;
6612 zxdg_decoration_manager_v1_destroy(*value_p);
6624 display->
xdg.
output_manager =
static_cast<zxdg_output_manager_v1 *
>(wl_registry_bind(
6625 display->
wl.
registry,
params.name, &zxdg_output_manager_v1_interface, version));
6633 zxdg_output_manager_v1_destroy(*value_p);
6645 output->wl.output =
static_cast<wl_output *
>(
6646 wl_registry_bind(display->
wl.
registry,
params.name, &wl_output_interface, version));
6659 if (
output->xdg.output ==
nullptr) {
6666 output->xdg.output =
nullptr;
6685 "mis-behaving compositor failed to call \"surface_listener.leave\" "
6686 "window scale may be invalid!");
6690 if (
output->xdg.output) {
6691 zxdg_output_v1_destroy(
output->xdg.output);
6693 wl_output_destroy(
output->wl.output);
6694 std::vector<GWL_Output *>::iterator iter = std::find(
6696 const int index = (iter != display->
outputs.cend()) ?
6697 std::distance(display->
outputs.begin(), iter) :
6713 seat->
xkb.
context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
6720 seat->
wl.
seat =
static_cast<wl_seat *
>(
6721 wl_registry_bind(display->
wl.
registry,
params.name, &wl_seat_interface, version));
6722 display->
seats.push_back(seat);
6736 seat->
wl.
data_device = wl_data_device_manager_get_data_device(
6770#ifdef WITH_INPUT_IME
6771 if (display->
wp.text_input_manager) {
6772 if (seat->
wp.text_input ==
nullptr) {
6773 seat->
wp.text_input = zwp_text_input_manager_v3_get_text_input(
6774 display->
wp.text_input_manager, seat->
wl.
seat);
6775 zwp_text_input_v3_set_user_data(seat->
wp.text_input, seat);
6776 zwp_text_input_v3_add_listener(seat->
wp.text_input, &text_input_listener, seat);
6780 seat->
wp.text_input =
nullptr;
6833#ifdef WITH_INPUT_IME
6834 if (seat->
wp.text_input) {
6835 zwp_text_input_v3_destroy(seat->
wp.text_input);
6872 wl_seat_destroy(seat->
wl.
seat);
6874 std::vector<GWL_Seat *>::iterator iter = std::find(
6875 display->
seats.begin(), display->
seats.end(), seat);
6876 const int index = (iter != display->
seats.cend()) ? std::distance(display->
seats.begin(), iter) :
6884 display->
seats.erase(display->
seats.begin() + index);
6895 display->
wl.
shm =
static_cast<wl_shm *
>(
6896 wl_registry_bind(display->
wl.
registry,
params.name, &wl_shm_interface, version));
6903 wl_shm **value_p = &display->
wl.
shm;
6904 wl_shm_destroy(*value_p);
6916 display->
wl.
registry,
params.name, &wl_data_device_manager_interface, version));
6924 wl_data_device_manager_destroy(*value_p);
6935 display->
wp.
tablet_manager =
static_cast<zwp_tablet_manager_v2 *
>(wl_registry_bind(
6936 display->
wl.
registry,
params.name, &zwp_tablet_manager_v2_interface, version));
6944 zwp_tablet_manager_v2_destroy(*value_p);
6957 display->
wl.
registry,
params.name, &zwp_relative_pointer_manager_v1_interface, version));
6965 zwp_relative_pointer_manager_v1_destroy(*value_p);
6977 display->
wl.
registry,
params.name, &zwp_pointer_constraints_v1_interface, version));
6985 zwp_pointer_constraints_v1_destroy(*value_p);
6999 &zwp_pointer_gestures_v1_interface,
7000 std::min(
params.version, version)));
7008 zwp_pointer_gestures_v1_destroy(*value_p);
7020 wl_registry_bind(display->
wl.
registry,
params.name, &xdg_activation_v1_interface, version));
7028 xdg_activation_v1_destroy(*value_p);
7041 display->
wl.
registry,
params.name, &wp_fractional_scale_manager_v1_interface, version));
7049 wp_fractional_scale_manager_v1_destroy(*value_p);
7061 wl_registry_bind(display->
wl.
registry,
params.name, &wp_viewporter_interface, version));
7069 wp_viewporter_destroy(*value_p);
7081 static_cast<zwp_primary_selection_device_manager_v1 *
>(
7084 &zwp_primary_selection_device_manager_v1_interface,
7092 zwp_primary_selection_device_manager_v1 **value_p =
7094 zwp_primary_selection_device_manager_v1_destroy(*value_p);
7098#ifdef WITH_INPUT_IME
7102static void gwl_registry_wp_text_input_manager_add(
GWL_Display *display,
7107 display->
wp.text_input_manager =
static_cast<zwp_text_input_manager_v3 *
>(wl_registry_bind(
7108 display->
wl.
registry,
params.name, &zwp_text_input_manager_v3_interface, version));
7111static void gwl_registry_wp_text_input_manager_remove(
GWL_Display *display,
7115 zwp_text_input_manager_v3 **value_p = &display->
wp.text_input_manager;
7116 zwp_text_input_manager_v3_destroy(*value_p);
7135 &wl_compositor_interface.name,
7141 &wl_shm_interface.name,
7147 &xdg_wm_base_interface.name,
7154 &zxdg_decoration_manager_v1_interface.name,
7160 &zxdg_output_manager_v1_interface.name,
7166 &wl_data_device_manager_interface.name,
7172 &zwp_primary_selection_device_manager_v1_interface.name,
7178 &zwp_tablet_manager_v2_interface.name,
7184 &zwp_relative_pointer_manager_v1_interface.name,
7189#ifdef WITH_INPUT_IME
7191 &zwp_text_input_manager_v3_interface.name,
7192 gwl_registry_wp_text_input_manager_add,
7194 gwl_registry_wp_text_input_manager_remove,
7199 &zwp_pointer_constraints_v1_interface.name,
7205 &zwp_pointer_gestures_v1_interface.name,
7211 &xdg_activation_v1_interface.name,
7217 &wp_fractional_scale_manager_v1_interface.name,
7223 &wp_viewporter_interface.name,
7230 &wl_output_interface.name,
7239 &wl_seat_interface.name,
7272 "Index out of range");
7277 [[maybe_unused]] wl_registry *wl_registry,
7278 const uint32_t name,
7280 const uint32_t version)
7289 if (interface_slot != -1) {
7296 params.interface_slot = interface_slot;
7297 params.version = version;
7306 "add %s(interface=%s, version=%u, name=%u)",
7307 (interface_slot != -1) ? (added ?
"" :
"(found but not added)") :
"(skipped), ",
7331 [[maybe_unused]] wl_registry *wl_registry,
7332 const uint32_t name)
7337 int interface_slot = 0;
7342 "remove (name=%u, interface=%s)",
7367#ifdef USE_EVENT_BACKGROUND_THREAD
7434 display_->system =
this;
7435 display_->background = background;
7439 if (!display_->wl.display) {
7440 display_destroy_and_free_all();
7441 throw std::runtime_error(
"unable to connect to display!");
7449 display_->registry_skip_update_all =
true;
7450 wl_registry *registry = wl_display_get_registry(display_->wl.display);
7451 display_->wl.registry = registry;
7461 display_->registry_skip_update_all =
false;
7464#ifdef WITH_GHOST_WAYLAND_LIBDECOR
7465 bool libdecor_required =
false;
7467 const char *xdg_current_desktop = [] {
7469 const char *key =
"ORIGINAL_XDG_CURRENT_DESKTOP";
7470 const char *value = getenv(key);
7471 return value ? value : getenv(key + 9);
7474 if (xdg_current_desktop) {
7478 if (string_elem_split_by_delim(xdg_current_desktop,
':',
"GNOME")) {
7479 libdecor_required =
true;
7484 if (libdecor_required) {
7490 libdecor_required =
false;
7492# ifdef WITH_GHOST_X11
7493 else if (!has_libdecor && !ghost_wayland_is_x11_available()) {
7496 libdecor_required =
false;
7501 if (libdecor_required) {
7503 display_->xdg_decor =
nullptr;
7505 if (!has_libdecor) {
7506# ifdef WITH_GHOST_X11
7509 "WAYLAND found but libdecor was not, install libdecor for Wayland support, "
7510 "falling back to X11\n");
7512 display_destroy_and_free_all();
7513 throw std::runtime_error(
"unable to find libdecor!");
7517 use_libdecor =
false;
7521#ifdef WITH_GHOST_WAYLAND_LIBDECOR
7523 display_->libdecor =
new GWL_LibDecor_System;
7524 GWL_LibDecor_System &decor = *display_->libdecor;
7525 decor.context =
libdecor_new(display_->wl.display, &libdecor_interface);
7526 if (!decor.context) {
7527 display_destroy_and_free_all();
7528 throw std::runtime_error(
"unable to create window decorations!");
7536 display_destroy_and_free_all();
7537 throw std::runtime_error(
"unable to access xdg_shell!");
7547#ifdef USE_EVENT_BACKGROUND_THREAD
7551 GHOST_ASSERT(display_->events_pthread_is_active ==
false,
"Expected to be false");
7562void GHOST_SystemWayland::display_destroy_and_free_all()
7566#ifdef USE_EVENT_BACKGROUND_THREAD
7574 display_destroy_and_free_all();
7582#ifdef WITH_INPUT_NDOF
7595 bool any_processed =
false;
7597#ifdef USE_EVENT_BACKGROUND_THREAD
7606 if (!display_->background) {
7607 std::lock_guard
lock{display_->events_pending_mutex};
7608 for (
const GHOST_IEvent *event : display_->events_pending) {
7627 display_->events_pending.clear();
7632 display_->events_pending.shrink_to_fit();
7640#ifdef USE_EVENT_BACKGROUND_THREAD
7642 std::lock_guard lock_timer_guard{*display_->system->timer_mutex};
7644 any_processed =
true;
7649 any_processed =
true;
7653#ifdef WITH_INPUT_NDOF
7657 waitForEvent =
false;
7658 any_processed =
true;
7663#ifdef USE_EVENT_BACKGROUND_THREAD
7671#ifdef USE_EVENT_BACKGROUND_THREAD
7688 any_processed =
true;
7691 return any_processed;
7701#ifdef USE_EVENT_BACKGROUND_THREAD
7726 const bool is_keyboard_active = seat->
keyboard.wl.surface_window !=
nullptr;
7727 const xkb_mod_mask_t
state = is_keyboard_active ?
7728 xkb_state_serialize_mods(seat->
xkb.
state,
7729 XKB_STATE_MODS_DEPRESSED) :
7748 bool val_l = depressed_l > 0;
7749 bool val_r = depressed_r > 0;
7751 if (is_keyboard_active) {
7758 "modifier (%s) state is inconsistent (GHOST held keys do not match XKB)",
7769 "modifier (%s) state is inconsistent (GHOST released keys do not match XKB)",
7788#ifdef USE_EVENT_BACKGROUND_THREAD
7797 if (!seat_state_pointer) {
7801 buttons = seat_state_pointer->
buttons;
7810 const std::unordered_set<std::string> &data_offer_types)
7813 for (
size_t i = 0;
i <
ARRAY_SIZE(ghost_supported_types);
i++) {
7814 if (data_offer_types.count(ghost_supported_types[
i])) {
7815 return ghost_supported_types[
i];
7822 const bool nil_terminate,
7823 const char *mime_receive_override,
7834 bool mutex_locked =
true;
7835 char *
data =
nullptr;
7838 if (data_offer !=
nullptr) {
7839 const char *mime_receive = mime_receive_override ?
7840 mime_receive_override :
7843 data_offer->
types.count(mime_receive_override) != 0,
7844 "Mime type override not found in data offer, caller must check");
7849 struct ThreadResult {
7850 char *
data =
nullptr;
7851 size_t data_len = 0;
7852 std::atomic<bool> done =
false;
7855 const bool nil_terminate,
7856 const char *mime_receive,
7858 ThreadResult *thread_result) {
7860 data_offer, mime_receive,
mutex, nil_terminate, &thread_result->data_len);
7861 thread_result->done =
true;
7863 std::thread read_thread(
7864 read_clipboard_fn, data_offer, nil_terminate, mime_receive, &
mutex, &thread_result);
7865 read_thread.detach();
7867 while (!thread_result.done) {
7870 data = thread_result.data;
7871 *r_data_len = thread_result.data_len;
7874 mutex_locked =
false;
7885 const char *mime_receive_override,
7895 bool mutex_locked =
true;
7896 char *
data =
nullptr;
7899 if (data_offer !=
nullptr) {
7900 const char *mime_receive = mime_receive_override ?
7901 mime_receive_override :
7904 data_offer->
types.count(mime_receive_override) != 0,
7905 "Mime type override not found in data offer, caller must check");
7910 struct ThreadResult {
7911 char *
data =
nullptr;
7912 size_t data_len = 0;
7913 std::atomic<bool> done =
false;
7916 const bool nil_terminate,
7917 const char *mime_receive,
7919 ThreadResult *thread_result) {
7921 data_offer, mime_receive,
mutex, nil_terminate, &thread_result->data_len);
7922 thread_result->done =
true;
7924 std::thread read_thread(
7925 read_clipboard_fn, data_offer, nil_terminate, mime_receive, &
mutex, &thread_result);
7926 read_thread.detach();
7928 while (!thread_result.done) {
7931 data = thread_result.data;
7932 *r_data_len = thread_result.data_len;
7935 mutex_locked =
false;
7946#ifdef USE_EVENT_BACKGROUND_THREAD
7950 const bool nil_terminate =
true;
7951 char *
data =
nullptr;
7952 size_t data_len = 0;
7983 data_source->
wp.
source = zwp_primary_selection_device_manager_v1_create_source(
7986 zwp_primary_selection_source_v1_add_listener(
7994 zwp_primary_selection_device_v1_set_selection(
8015 data_source->
wl.
source = wl_data_device_manager_create_data_source(
8025 wl_data_device_set_selection(
8032#ifdef USE_EVENT_BACKGROUND_THREAD
8048#ifdef USE_EVENT_BACKGROUND_THREAD
8069 const bool nil_terminate =
true;
8070 size_t data_buf_len = 0;
8076 if (!uris.empty()) {
8077 const std::string_view &uri = uris.front();
8096#ifdef USE_EVENT_BACKGROUND_THREAD
8105 uint *rgba =
nullptr;
8109 ImBuf *ibuf =
nullptr;
8115 size_t data_len = 0;
8126 const bool nil_terminate =
true;
8127 size_t data_len = 0;
8133 if (!uris.empty()) {
8134 const std::string_view &uri = uris.front();
8145 *r_height = ibuf->
y;
8146 const size_t byte_count = size_t(ibuf->
x) * size_t(ibuf->
y) * 4;
8147 rgba = (
uint *)malloc(byte_count);
8158#ifdef USE_EVENT_BACKGROUND_THREAD
8184 char *
data =
static_cast<char *
>(malloc(imgbuffer->
data_size));
8188 data_source->
wl.
source = wl_data_device_manager_create_data_source(
8189 display_->wl.data_device_manager);
8196 wl_data_device_set_selection(
8206#ifdef USE_EVENT_BACKGROUND_THREAD
8210 return display_ ? uint8_t(display_->outputs.size()) : 0;
8216 timespec ts = {0, 0};
8217 clock_gettime(CLOCK_MONOTONIC, &ts);
8235 wl_fixed_t xy_wrap[2] = {
8236 seat_state_pointer->
xy[0],
8237 seat_state_pointer->
xy[1],
8270 const wl_fixed_t xy_next[2]{
8286#ifdef USE_EVENT_BACKGROUND_THREAD
8306#ifdef USE_EVENT_BACKGROUND_THREAD
8320#ifdef USE_EVENT_BACKGROUND_THREAD
8329 if (!seat_state_pointer) {
8342#ifdef USE_EVENT_BACKGROUND_THREAD
8362#ifdef USE_EVENT_BACKGROUND_THREAD
8371#ifdef USE_EVENT_BACKGROUND_THREAD
8375 if (!display_->outputs.empty()) {
8379 if (
output->transform & WL_OUTPUT_TRANSFORM_90) {
8380 std::swap(size_native[0], size_native[1]);
8382 width = uint32_t(size_native[0]);
8383 height = uint32_t(size_native[1]);
8389#ifdef USE_EVENT_BACKGROUND_THREAD
8392 if (!display_->outputs.empty()) {
8399 if (
output->has_position_logical) {
8400 xy[0] =
output->position_logical[0];
8401 xy[1] =
output->position_logical[1];
8403 if (
output->transform & WL_OUTPUT_TRANSFORM_90) {
8404 std::swap(size_native[0], size_native[1]);
8406 xy_min[0] = std::min(xy_min[0],
xy[0]);
8407 xy_min[1] = std::min(xy_min[1],
xy[1]);
8408 xy_max[0] = std::max(xy_max[0],
xy[0] + size_native[0]);
8409 xy_max[1] = std::max(xy_max[1],
xy[1] + size_native[1]);
8412 width = xy_max[0] - xy_min[0];
8413 height = xy_max[1] - xy_min[1];
8419#ifdef USE_EVENT_BACKGROUND_THREAD
8427#ifdef WITH_VULKAN_BACKEND
8428 case GHOST_kDrawingContextTypeVulkan: {
8433 GHOST_kVulkanPlatformWayland,
8437 display_->wl.display,
8444 if (context->initializeDrawingContext()) {
8457#ifdef WITH_OPENGL_BACKEND
8458 case GHOST_kDrawingContextTypeOpenGL: {
8463 for (
int minor = 6; minor >= 3; --minor) {
8468 EGLNativeWindowType(egl_window),
8469 EGLNativeDisplayType(display_->wl.display),
8470 EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
8474 (debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
8478 if (context->initializeDrawingContext()) {
8479 wl_surface_set_user_data(
wl_surface, egl_window);
8486 GHOST_PRINT(
"Cannot create off-screen EGL context" << std::endl);
8505#ifdef USE_EVENT_BACKGROUND_THREAD
8510#ifdef WITH_OPENGL_BACKEND
8512 type = GHOST_kDrawingContextTypeOpenGL;
8515#ifdef WITH_VULKAN_BACKEND
8517 type = GHOST_kDrawingContextTypeVulkan;
8528#ifdef WITH_OPENGL_BACKEND
8529 if (type == GHOST_kDrawingContextTypeOpenGL) {
8530 wl_egl_window *egl_window =
static_cast<wl_egl_window *
>(wl_surface_get_user_data(
wl_surface));
8531 if (egl_window !=
nullptr) {
8547 const uint32_t width,
8548 const uint32_t height,
8551 const bool exclusive,
8552 const bool is_dialog,
8593#ifdef USE_GNOME_CONFINE_HACK
8595 if (use_software_confine) {
8600 (void)use_software_confine;
8614 const char *cursor_name =
nullptr;
8616 if (wl_cursor ==
nullptr) {
8621 wl_cursor_image *image = wl_cursor->images[0];
8648 if (wl_cursor ==
nullptr) {
8655 const uint8_t *
mask,
8675 const int32_t size_xy[2] = {sizex, sizey};
8678 WL_SHM_FORMAT_ARGB8888,
8681 if (buffer ==
nullptr) {
8687 static constexpr uint32_t black = 0xFF000000;
8688 static constexpr uint32_t white = 0xFFFFFFFF;
8689 static constexpr uint32_t transparent = 0x00000000;
8691 uint8_t datab = 0, maskb = 0;
8693 for (
int y = 0;
y < sizey; ++
y) {
8694 uint32_t *pixel = &
static_cast<uint32_t *
>(cursor->
custom_data)[
y * sizex];
8695 for (
int x = 0;
x < sizex; ++
x) {
8701 datab = uint8_t((datab * 0x0202020202ULL & 0x010884422010ULL) % 1023);
8702 maskb = uint8_t((maskb * 0x0202020202ULL & 0x010884422010ULL) % 1023);
8706 *pixel++ = (datab & 0x80) ? white : black;
8709 *pixel++ = (datab & 0x80) ? white : transparent;
8737 int output_scale = -1;
8739 output_scale = (output_scale == -1) ?
output->scale : std::min(output_scale,
output->scale);
8741 if (output_scale == -1) {
8745 const int custom_size = std::max(sizex, sizey);
8748 cursor->
custom_scale = std::max(1, (output_scale * custom_size) / target_size);
8761 cursor->
wl.
image.width = uint32_t(sizex);
8762 cursor->
wl.
image.height = uint32_t(sizey);
8763 cursor->
wl.
image.hotspot_x = uint32_t(hotX);
8764 cursor->
wl.
image.hotspot_y = uint32_t(hotY);
8817 "The trackpad direction was expected to be initialized");
8859#ifdef USE_GNOME_CONFINE_HACK
8862 const bool use_software_confine =
false;
8868#ifdef USE_GNOME_CONFINE_HACK
8872# ifndef USE_GNOME_CONFINE_HACK_ALWAYS_ON
8885# ifndef USE_GNOME_CONFINE_HACK_ALWAYS_ON
8895 const bool use_software_confine)
8912#ifdef USE_EVENT_BACKGROUND_THREAD
8916 for (
GWL_Seat *seat : display_->seats) {
8942 const wl_proxy *proxy =
reinterpret_cast<const wl_proxy *
>(wl_output);
8948 const wl_proxy *proxy =
reinterpret_cast<const wl_proxy *
>(
wl_surface);
8959 const wl_proxy *proxy =
reinterpret_cast<const wl_proxy *
>(
wl_surface);
8966 const wl_proxy *proxy =
reinterpret_cast<const wl_proxy *
>(
wl_surface);
8972 wl_proxy *proxy =
reinterpret_cast<wl_proxy *
>(wl_output);
8978 wl_proxy *proxy =
reinterpret_cast<wl_proxy *
>(
wl_surface);
8984 wl_proxy *proxy =
reinterpret_cast<wl_proxy *
>(
wl_surface);
8990 wl_proxy *proxy =
reinterpret_cast<wl_proxy *
>(
wl_surface);
9004 return display_->wl.display;
9009 return display_->wl.compositor;
9014 return display_->wp.primary_selection_device_manager;
9019 return display_->xdg.activation_manager;
9024 return display_->wp.fractional_scale_manager;
9028 return display_->wp.viewporter;
9033 return display_->wp.pointer_gestures;
9044#ifdef WITH_GHOST_WAYLAND_APP_ID
9056#ifdef WITH_GHOST_WAYLAND_LIBDECOR
9058libdecor *GHOST_SystemWayland::libdecor_context_get()
9060 return display_->libdecor->context;
9072 return display_->xdg_decor->manager;
9079 return display_->outputs;
9084 return display_->wl.shm;
9087#ifdef USE_EVENT_BACKGROUND_THREAD
9090 return display_->ghost_timer_manager;
9102#ifdef WITH_INPUT_IME
9109 bool completed)
const
9115 if (seat->
wp.text_input ==
nullptr) {
9122 gwl_seat_ime_result_reset(seat);
9125 if (seat->ime.is_enabled && completed) {
9129 bool force_rect_update =
false;
9130 if (seat->ime.is_enabled ==
false) {
9131 seat->ime.has_preedit =
false;
9132 seat->ime.is_enabled =
true;
9134 zwp_text_input_v3_enable(seat->
wp.text_input);
9135 zwp_text_input_v3_commit(seat->
wp.text_input);
9138 zwp_text_input_v3_set_content_type(seat->
wp.text_input,
9139 ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE,
9140 ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL);
9142 gwl_seat_ime_rect_reset(seat);
9143 force_rect_update =
true;
9146 if ((force_rect_update ==
false) &&
9147 (seat->ime.rect.x ==
x) &&
9148 (seat->ime.rect.y ==
y) &&
9149 (seat->ime.rect.w ==
w) &&
9150 (seat->ime.rect.h == h))
9160 zwp_text_input_v3_set_cursor_rectangle(seat->
wp.text_input, rect_x, rect_y, rect_w, rect_h);
9162 zwp_text_input_v3_commit(seat->
wp.text_input);
9164 seat->ime.rect.x =
x;
9165 seat->ime.rect.y =
y;
9166 seat->ime.rect.w =
w;
9167 seat->ime.rect.h = h;
9178 seat->ime.is_enabled =
false;
9180 gwl_seat_ime_rect_reset(seat);
9182 if (seat->
wp.text_input ==
nullptr) {
9186 zwp_text_input_v3_disable(seat->
wp.text_input);
9187 zwp_text_input_v3_commit(seat->
wp.text_input);
9233 if (
UNLIKELY(timestamp_as_uint < input_timestamp.
last)) {
9241 if (input_timestamp.
last - timestamp_as_uint > std::numeric_limits<uint32_t>::max() / 2) {
9245 uint64_t(std::numeric_limits<uint32_t>::max()) + 1;
9251 input_timestamp.
offset = offset_test;
9255 input_timestamp.
last = timestamp_as_uint;
9258 timestamp += input_timestamp.
offset;
9262 const uint32_t now_as_uint32 = uint32_t(now);
9263 if (now_as_uint32 == timestamp_as_uint) {
9271 if (!input_timestamp.
offset) {
9272 input_timestamp.
offset = (now - timestamp);
9274 timestamp += input_timestamp.
offset;
9276 if (timestamp > now) {
9277 input_timestamp.
offset -= (timestamp - now);
9288#ifdef USE_EVENT_BACKGROUND_THREAD
9289 GHOST_ASSERT(!display_->background,
"Foreground only");
9291 std::lock_guard
lock{display_->events_pending_mutex};
9292 display_->events_pending.push_back(event);
9317 bool changed =
false;
9318#define SURFACE_CLEAR_PTR(surface_test) \
9319 if (surface_test == wl_surface) { \
9320 surface_test = nullptr; \
9326 for (
GWL_Seat *seat : display_->seats) {
9331#ifdef WITH_INPUT_IME
9335#undef SURFACE_CLEAR_PTR
9342 bool changed =
false;
9350 if (window_manager) {
9359 for (
GWL_Seat *seat : display_->seats) {
9374 if (window_manager) {
9384 for (
GWL_Seat *seat : display_->seats) {
9393 for (zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->
wp.
tablet_tools) {
9395 zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2));
9416 if (
UNLIKELY(!display_->wp.relative_pointer_manager || !display_->wp.pointer_constraints)) {
9425 if (mode == mode_current) {
9429#ifdef USE_GNOME_CONFINE_HACK
9433 const bool was_software_confine =
false;
9434 const bool use_software_confine =
false;
9438 was_software_confine);
9459 wl_fixed_t xy_motion[2] = {0, 0};
9460 bool xy_motion_create_event =
false;
9471 wl_fixed_from_int(wrap_bounds->
m_l));
9473 wl_fixed_from_int(wrap_bounds->
m_t));
9475 wl_fixed_from_int(wrap_bounds->
m_r));
9477 wl_fixed_from_int(wrap_bounds->
m_b));
9482 if ((xy_next[0] != seat->
pointer.xy[0]) || (xy_next[1] != seat->
pointer.xy[1])) {
9483 xy_motion[0] = xy_next[0];
9484 xy_motion[1] = xy_next[1];
9485 xy_motion_create_event =
true;
9487 seat->
pointer.xy[0] = xy_next[0];
9488 seat->
pointer.xy[1] = xy_next[1];
9494 const wl_fixed_t xy_next[2] = {
9509 xy_motion[0] = xy_next[0];
9510 xy_motion[1] = xy_next[1];
9511 xy_motion_create_event =
true;
9513 else if (grab_state_prev.
use_lock) {
9517 xy_motion[0] = xy_next[0];
9518 xy_motion[1] = xy_next[1];
9519 xy_motion_create_event =
true;
9522#ifdef USE_GNOME_CONFINE_HACK
9524 if (was_software_confine) {
9532 if (xy_motion_create_event) {
9565 display_->wp.relative_pointer_manager, seat->
wl.
pointer);
9566 zwp_relative_pointer_v1_add_listener(
9569 display_->wp.pointer_constraints,
9573 ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
9578 init_grab_xy[0] = wl_fixed_to_int(
9580 init_grab_xy[1] = wl_fixed_to_int(
9589 display_->wp.pointer_constraints,
9593 ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
9601#ifdef USE_GNOME_CONFINE_HACK
9608#ifdef WITH_GHOST_WAYLAND_LIBDECOR
9609bool GHOST_SystemWayland::use_libdecor_runtime()
9611 return use_libdecor;
9615#ifdef WITH_GHOST_WAYLAND_DYNLOAD
9616bool ghost_wl_dynload_libraries_init()
9618# ifdef WITH_GHOST_X11
9622 bool verbose = getenv(
"WAYLAND_DISPLAY") !=
nullptr;
9629# ifdef WITH_OPENGL_BACKEND
9630 wayland_dynload_egl_init(
verbose)
9636# ifdef WITH_GHOST_WAYLAND_LIBDECOR
9637 has_libdecor = wayland_dynload_libdecor_init(
verbose);
9644# ifdef WITH_OPENGL_BACKEND
9651void ghost_wl_dynload_libraries_exit()
9655# ifdef WITH_OPENGL_BACKEND
9658# ifdef WITH_GHOST_WAYLAND_LIBDECOR
KDTree *BLI_kdtree_nd_ new(unsigned int nodes_len_capacity)
void BLI_kdtree_nd_ free(KDTree *tree)
#define CLOG_WARN(clg_ref,...)
#define CLOG_INFO(clg_ref, level,...)
#define GHOST_OPENGL_EGL_CONTEXT_FLAGS
#define GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY
#define GHOST_ASSERT(x, info)
char * GHOST_URL_decode_alloc(const char *buf_src, const int buf_src_len)
static void keyboard_handle_repeat_info(void *data, wl_keyboard *, const int32_t rate, const int32_t delay)
void(*)(GWL_Display *display, void *user_data, bool on_exit) GWL_RegistryEntry_RemoveFn
static constexpr int smooth_as_discrete_steps
static void ghost_wl_display_lock_without_input(wl_display *wl_display, std::mutex *server_mutex)
static void gwl_registry_wp_viewporter_remove(GWL_Display *display, void *, const bool)
static void tablet_tool_handle_button(void *data, zwp_tablet_tool_v2 *, const uint32_t serial, const uint32_t button, const uint32_t state)
static CLG_LogRef LOG_WL_PRIMARY_SELECTION_SOURCE
#define USE_NON_LATIN_KB_WORKAROUND
#define WL_FIXED_TO_INT_FOR_WINDOW_V2(win, xy)
static const char * ghost_wl_mime_send[]
static void cursor_surface_handle_enter(void *data, wl_surface *wl_surface, wl_output *wl_output)
static void tablet_tool_handle_distance(void *, zwp_tablet_tool_v2 *, const uint32_t distance)
static void data_source_handle_target(void *, wl_data_source *, const char *)
static void primary_selection_device_handle_selection(void *data, zwp_primary_selection_device_v1 *, zwp_primary_selection_offer_v1 *id)
static void global_handle_add(void *data, wl_registry *wl_registry, const uint32_t name, const char *interface, const uint32_t version)
static void gwl_registry_wp_relative_pointer_manager_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
static int gwl_registry_handler_interface_slot_from_string(const char *interface)
static const wl_keyboard_listener keyboard_listener
static CLG_LogRef LOG_WL_TABLET_TOOL
static void gwl_registry_xdg_wm_base_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
static void touch_seat_handle_cancel(void *, wl_touch *)
static void keyboard_depressed_state_push_events_from_change(GWL_Seat *seat, GHOST_IWindow *win, const uint64_t event_ms, const GWL_KeyboardDepressedState &key_depressed_prev)
static GHOST_TTabletMode tablet_tool_map_type(enum zwp_tablet_tool_v2_type wp_tablet_tool_type)
static void keyboard_handle_modifiers(void *data, wl_keyboard *, const uint32_t serial, const uint32_t mods_depressed, const uint32_t mods_latched, const uint32_t mods_locked, const uint32_t group)
static const GWL_Cursor_ShapeInfo ghost_wl_cursors
static void seat_handle_capabilities(void *data, wl_seat *wl_seat, const uint32_t capabilities)
static void cursor_surface_handle_leave(void *data, wl_surface *wl_surface, wl_output *wl_output)
static const char * ghost_wl_surface_cursor_tablet_tag_id
static const xdg_wm_base_listener shell_listener
static CLG_LogRef LOG_WL_KEYBOARD_DEPRESSED_STATE
static void keyboard_handle_keymap(void *data, wl_keyboard *, const uint32_t format, const int32_t fd, const uint32_t size)
static void data_source_handle_cancelled(void *data, wl_data_source *wl_data_source)
bool ghost_wl_surface_own(const wl_surface *wl_surface)
static void tablet_seat_handle_tool_added(void *data, zwp_tablet_seat_v2 *, zwp_tablet_tool_v2 *id)
static void pointer_handle_frame(void *data, wl_pointer *)
static void pointer_handle_axis(void *data, wl_pointer *, const uint32_t time, const uint32_t axis, const wl_fixed_t value)
static const char * ghost_wl_app_id
static void xdg_output_handle_name(void *, zxdg_output_v1 *, const char *name)
static GHOST_TSuccess getCursorPositionClientRelative_impl(const GWL_SeatStatePointer *seat_state_pointer, const GHOST_WindowWayland *win, int32_t &x, int32_t &y)
static void gwl_primary_selection_discard_offer(GWL_PrimarySelection *primary)
static void pthread_set_min_priority(pthread_t handle)
static void gwl_registry_wl_data_device_manager_remove(GWL_Display *display, void *, const bool)
static char * read_buffer_from_primary_selection_offer(GWL_PrimarySelection_DataOffer *data_offer, const char *mime_receive, std::mutex *mutex, const bool nil_terminate, size_t *r_len)
static void gwl_seat_capability_keyboard_disable(GWL_Seat *seat)
static void gwl_seat_cursor_anim_end(GWL_Seat *seat)
static void tablet_tool_handle_type(void *data, zwp_tablet_tool_v2 *, const uint32_t tool_type)
static void gwl_registry_wp_relative_pointer_manager_remove(GWL_Display *display, void *, const bool)
static CLG_LogRef LOG_WL_TABLET_SEAT
static void data_device_handle_drop(void *data, wl_data_device *)
static void data_source_handle_send(void *data, wl_data_source *, const char *, const int32_t fd)
static bool gwl_display_seat_active_set(GWL_Display *display, const GWL_Seat *seat)
static const zwp_relative_pointer_v1_listener relative_pointer_listener
static const wl_cursor * gwl_seat_cursor_find_from_shape(GWL_Seat *seat, const GHOST_TStandardCursor shape, const char **r_cursor_name)
static void tablet_tool_handle_proximity_out(void *data, zwp_tablet_tool_v2 *)
void ghost_wl_output_tag(wl_output *wl_output)
static void gwl_registry_xdg_decoration_manager_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
static void output_handle_geometry(void *data, wl_output *, const int32_t, const int32_t, const int32_t physical_width, const int32_t physical_height, const int32_t, const char *make, const char *model, const int32_t transform)
static void gwl_registry_xdg_decoration_manager_remove(GWL_Display *display, void *, const bool)
static CLG_LogRef LOG_WL_PRIMARY_SELECTION_OFFER
static void data_device_handle_selection(void *data, wl_data_device *, wl_data_offer *id)
static int memfd_create_sealed(const char *name)
static uint64_t ghost_wl_ms_from_utime_pair(uint32_t utime_hi, uint32_t utime_lo)
#define GWL_TabletTool_FrameTypes_NUM
static void keyboard_handle_key_repeat_cancel(GWL_Seat *seat)
GHOST_WindowWayland * ghost_wl_surface_user_data(wl_surface *wl_surface)
static void gwl_seat_key_repeat_timer_remove(GWL_Seat *seat)
static const GHOST_TButton gwl_pointer_events_ebutton[]
static CLG_LogRef LOG_WL_TOUCH
static void gwl_registry_wp_primary_selection_device_manager_remove(GWL_Display *display, void *, const bool)
static GHOST_TSuccess setCursorPositionClientRelative_impl(GWL_Seat *seat, GHOST_WindowWayland *win, const int32_t x, const int32_t y)
static const zxdg_output_v1_listener xdg_output_listener
static void keyboard_handle_key_repeat_reset(GWL_Seat *seat, const bool use_delay)
static void global_handle_remove(void *data, wl_registry *wl_registry, const uint32_t name)
static void primary_selection_source_send(void *data, zwp_primary_selection_source_v1 *, const char *, int32_t fd)
static const wl_buffer_listener cursor_buffer_listener
static void gwl_registry_wp_pointer_constraints_remove(GWL_Display *display, void *, const bool)
static void tablet_tool_handle_done(void *, zwp_tablet_tool_v2 *)
static void output_handle_done(void *data, wl_output *wl_output)
static void gwl_registry_wl_seat_update(GWL_Display *display, const GWL_RegisteryUpdate_Params ¶ms)
static void gwl_seat_capability_keyboard_enable(GWL_Seat *seat)
static ssize_t read_exhaustive(const int fd, void *data, size_t nbytes)
static CLG_LogRef LOG_WL_RELATIVE_POINTER
static void thread_set_min_priority(std::thread &thread)
static void relative_pointer_handle_relative_motion_impl(GWL_Seat *seat, GHOST_WindowWayland *win, const wl_fixed_t xy[2], const uint64_t event_ms)
static uint64_t sub_abs_u64(const uint64_t a, const uint64_t b)
static bool gwl_registry_entry_remove_by_name(GWL_Display *display, uint32_t name, int *r_interface_slot)
static void gwl_registry_compositor_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
void ghost_wl_surface_tag_cursor_tablet(wl_surface *wl_surface)
static void gwl_registry_entry_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms, void *user_data)
static void xdg_output_handle_description(void *, zxdg_output_v1 *, const char *description)
bool ghost_wl_surface_own_cursor_tablet(const wl_surface *wl_surface)
static CLG_LogRef LOG_WL_XDG_OUTPUT
static void gwl_seat_cursor_anim_begin(GWL_Seat *seat)
static void gwl_seat_cursor_buffer_set(const GWL_Seat *seat, const wl_cursor_image *wl_image, wl_buffer *buffer)
static void gwl_registry_entry_update_all(GWL_Display *display, const int interface_slot_exclude)
static CLG_LogRef LOG_WL_PRIMARY_SELECTION_DEVICE
GWL_Output * ghost_wl_output_user_data(wl_output *wl_output)
static void touch_seat_handle_orientation(void *, wl_touch *, int32_t, wl_fixed_t)
static char * read_buffer_from_data_offer(GWL_DataOffer *data_offer, const char *mime_receive, std::mutex *mutex, const bool nil_terminate, size_t *r_len)
static bool gwl_seat_capability_pointer_multitouch_check(const GWL_Seat *seat, const bool fallback)
static const wl_registry_listener registry_listener
static void keyboard_depressed_state_reset(GWL_Seat *seat)
static const zwp_tablet_seat_v2_listener tablet_seat_listener
static void gwl_tablet_tool_frame_event_reset(GWL_TabletTool *tablet_tool)
static GWL_SeatStatePointer * gwl_seat_state_pointer_active(GWL_Seat *seat)
static constexpr const char * ghost_wl_mime_text_plain
static void tablet_seat_handle_tablet_added(void *, zwp_tablet_seat_v2 *, zwp_tablet_v2 *id)
static void tablet_tool_handle_frame(void *data, zwp_tablet_tool_v2 *, const uint32_t time)
static const zwp_primary_selection_offer_v1_listener primary_selection_offer_listener
static int pointer_axis_as_index(const uint32_t axis)
static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym)
static const wl_pointer_listener pointer_listener
static void system_clipboard_put_primary_selection(GWL_Display *display, const char *buffer)
static void touch_seat_handle_up(void *, wl_touch *, uint32_t, uint32_t, int32_t)
static void data_source_handle_dnd_finished(void *, wl_data_source *)
static void gwl_registry_xdg_output_manager_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
static void gwl_registry_wp_tablet_manager_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
static void tablet_tool_handle_hardware_id_wacom(void *, zwp_tablet_tool_v2 *, const uint32_t, const uint32_t)
static void gwl_seat_capability_pointer_disable(GWL_Seat *seat)
static void gwl_registry_wp_pointer_gestures_remove(GWL_Display *display, void *, const bool)
static const wl_data_offer_listener data_offer_listener
static bool update_cursor_scale(GWL_Cursor &cursor, wl_shm *shm, GWL_SeatStatePointer *seat_state_pointer, wl_surface *wl_surface_cursor)
static void ghost_wl_display_report_error_from_code(wl_display *display, const int ecode)
static void gwl_pointer_handle_frame_event_reset(GWL_SeatStatePointer_Events *pointer_events)
static void tablet_tool_handle_motion(void *data, zwp_tablet_tool_v2 *, const wl_fixed_t x, const wl_fixed_t y)
static const GWL_RegistryHandler * gwl_registry_handler_from_interface_slot(int interface_slot)
static CLG_LogRef LOG_WL_OUTPUT
static const wl_data_source_listener data_source_listener
static void ghost_wayland_log_handler_background(const char *msg, va_list arg)
static void gwl_registry_wl_seat_remove(GWL_Display *display, void *user_data, const bool on_exit)
static void keyboard_depressed_state_key_event(GWL_Seat *seat, const GHOST_TKey gkey, const GHOST_TEventType etype)
static const zwp_tablet_tool_v2_listener tablet_tool_listner
static void tablet_seat_handle_pad_added(void *, zwp_tablet_seat_v2 *, zwp_tablet_pad_v2 *id)
static void tablet_tool_handle_hardware_serial(void *, zwp_tablet_tool_v2 *, const uint32_t, const uint32_t)
static bool gwl_registry_entry_remove_by_interface_slot(GWL_Display *display, int interface_slot, bool on_exit)
static char * system_clipboard_get_primary_selection(GWL_Display *display, const bool nil_terminate, const char *mime_receive_override, size_t *r_data_len)
void ghost_wl_surface_tag(wl_surface *wl_surface)
static wl_buffer * ghost_wl_buffer_create_for_image(wl_shm *shm, const int32_t size_xy[2], enum wl_shm_format format, void **r_buffer_data, size_t *r_buffer_data_size)
static bool cursor_is_software(const GHOST_TGrabCursorMode mode, const bool use_software_confine)
static void gwl_registry_xdg_activation_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
static const wl_data_device_listener data_device_listener
static void pointer_handle_axis_value120(void *data, wl_pointer *, uint32_t axis, int32_t value120)
static void touch_seat_handle_shape(void *, wl_touch *, int32_t, wl_fixed_t, wl_fixed_t)
static void pointer_handle_axis_stop(void *data, wl_pointer *, uint32_t time, uint32_t axis)
static void gwl_seat_capability_touch_disable(GWL_Seat *seat)
static bool gwl_seat_cursor_anim_check(GWL_Seat *seat)
static void ghost_wl_display_report_error(wl_display *display)
static void tablet_tool_handle_tilt(void *data, zwp_tablet_tool_v2 *, const wl_fixed_t tilt_x, const wl_fixed_t tilt_y)
bool ghost_wl_display_report_error_if_set(wl_display *display)
static void tablet_tool_handle_removed(void *data, zwp_tablet_tool_v2 *zwp_tablet_tool_v2)
static const wl_touch_listener touch_seat_listener
static void gwl_registry_wl_seat_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
static void pointer_handle_button(void *data, wl_pointer *, const uint32_t serial, const uint32_t time, const uint32_t button, const uint32_t state)
static void gwl_seat_key_layout_active_state_update_mask(GWL_Seat *seat)
static void gwl_display_event_thread_destroy(GWL_Display *display)
static CLG_LogRef LOG_WL_KEYBOARD
static GHOST_TKey xkb_map_gkey_or_scan_code(const xkb_keysym_t sym, const uint32_t key)
static void keyboard_handle_key(void *data, wl_keyboard *, const uint32_t serial, const uint32_t time, const uint32_t key, const uint32_t state)
void ghost_wl_surface_tag_cursor_pointer(wl_surface *wl_surface)
static void ghost_wayland_log_handler(const char *msg, va_list arg)
static void gwl_seat_cursor_buffer_show(GWL_Seat *seat)
static CLG_LogRef LOG_WL_REGISTRY
static const wl_surface_listener cursor_surface_listener
static void primary_selection_source_cancelled(void *data, zwp_primary_selection_source_v1 *source)
@ CURSOR_VISIBLE_ONLY_HIDE
@ CURSOR_VISIBLE_ALWAYS_SET
@ CURSOR_VISIBLE_ONLY_SHOW
static CLG_LogRef LOG_WL_POINTER
static void gwl_seat_cursor_buffer_hide(GWL_Seat *seat)
void(*)(GWL_Display *display, const GWL_RegisteryUpdate_Params ¶ms) GWL_RegistryHandler_UpdateFn
static void pointer_handle_axis_discrete(void *data, wl_pointer *, uint32_t axis, int32_t discrete)
static void keyboard_handle_leave(void *data, wl_keyboard *, const uint32_t, wl_surface *wl_surface)
static constexpr const char * ghost_wl_mime_img_png
static void data_source_handle_action(void *, wl_data_source *, const uint32_t dnd_action)
static xkb_keysym_t xkb_state_key_get_one_sym_without_modifiers(xkb_state *xkb_state_empty, xkb_state *xkb_state_empty_with_numlock, xkb_state *xkb_state_empty_with_shift, const bool xkb_use_non_latin_workaround, const xkb_keycode_t key)
#define XKB_VMOD_NAME_HYPER
static void gwl_registry_wp_tablet_manager_remove(GWL_Display *display, void *, const bool)
static void xdg_output_handle_logical_position(void *data, zxdg_output_v1 *, const int32_t x, const int32_t y)
static const zwp_primary_selection_source_v1_listener primary_selection_source_listener
static void data_device_handle_data_offer(void *, wl_data_device *, wl_data_offer *id)
static void pointer_handle_enter(void *data, wl_pointer *, const uint32_t serial, wl_surface *wl_surface, const wl_fixed_t surface_x, const wl_fixed_t surface_y)
static void cursor_surface_handle_preferred_buffer_scale(void *, wl_surface *, int32_t factor)
static void tablet_tool_handle_capability(void *, zwp_tablet_tool_v2 *, const uint32_t capability)
static void cursor_buffer_set_surface_impl(const wl_cursor_image *wl_image, wl_buffer *buffer, wl_surface *wl_surface, const int scale)
static void gwl_registry_wl_output_remove(GWL_Display *display, void *user_data, const bool on_exit)
static void pointer_handle_axis_source(void *data, wl_pointer *, uint32_t axis_source)
static void pointer_handle_motion(void *data, wl_pointer *, const uint32_t time, const wl_fixed_t surface_x, const wl_fixed_t surface_y)
static void touch_seat_handle_motion(void *, wl_touch *, uint32_t, int32_t, wl_fixed_t, wl_fixed_t)
static void primary_selection_device_handle_data_offer(void *, zwp_primary_selection_device_v1 *, zwp_primary_selection_offer_v1 *id)
static const zwp_primary_selection_device_v1_listener primary_selection_device_listener
static constexpr const char * ghost_wl_mime_text_uri_list
static void cursor_buffer_handle_release(void *data, wl_buffer *wl_buffer)
static const char * system_clipboard_text_mime_type(const std::unordered_set< std::string > &data_offer_types)
static void gwl_registry_wl_shm_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
bool ghost_wl_output_own(const wl_output *wl_output)
static void * gwl_display_event_thread_fn(void *display_voidp)
static const char * ghost_wl_locale_from_env_with_default()
static void gwl_registry_wp_viewporter_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
static void pointer_handle_leave(void *data, wl_pointer *, const uint32_t, wl_surface *wl_surface)
static void gwl_registry_wl_data_device_manager_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
static CLG_LogRef LOG_WL_DATA_OFFER
static void data_offer_handle_source_actions(void *data, wl_data_offer *, const uint32_t source_actions)
static void tablet_tool_handle_rotation(void *, zwp_tablet_tool_v2 *, const wl_fixed_t degrees)
static void gwl_seat_capability_pointer_enable(GWL_Seat *seat)
static CLG_LogRef LOG_WL_SEAT
static void data_offer_handle_action(void *data, wl_data_offer *, const uint32_t dnd_action)
static char * system_clipboard_get(GWL_Display *display, bool nil_terminate, const char *mime_receive_override, size_t *r_data_len)
static void gwl_seat_cursor_buffer_set_current(GWL_Seat *seat)
static void tablet_tool_handle_proximity_in(void *data, zwp_tablet_tool_v2 *, const uint32_t serial, zwp_tablet_v2 *, wl_surface *wl_surface)
static void gwl_display_event_thread_create(GWL_Display *display)
#define SURFACE_CLEAR_PTR(surface_test)
static void seat_handle_name(void *data, wl_seat *, const char *name)
static void gwl_tablet_tool_frame_event_add(GWL_TabletTool *tablet_tool, const GWL_TabletTool_EventTypes ty)
static void tablet_tool_handle_wheel(void *data, zwp_tablet_tool_v2 *, const wl_fixed_t, const int32_t clicks)
static void gwl_primary_selection_discard_source(GWL_PrimarySelection *primary)
static void tablet_tool_handle_down(void *data, zwp_tablet_tool_v2 *, const uint32_t serial)
static void gwl_seat_cursor_visible_set(GWL_Seat *seat, const bool visible, const bool is_hardware, const enum eCursorSetMode set_mode)
static CLG_LogRef LOG_WL_CURSOR_SURFACE
static void output_handle_scale(void *data, wl_output *, const int32_t factor)
static void data_device_handle_leave(void *data, wl_data_device *)
static const char * ghost_wl_surface_cursor_pointer_tag_id
static void gwl_display_destroy(GWL_Display *display)
static void touch_seat_handle_down(void *, wl_touch *, uint32_t, uint32_t, wl_surface *, int32_t, wl_fixed_t, wl_fixed_t)
static void gwl_seat_capability_touch_enable(GWL_Seat *seat)
static void gwl_seat_cursor_anim_begin_if_needed(GWL_Seat *seat)
static bool xkb_compose_state_feed_and_get_utf8(xkb_compose_state *compose_state, xkb_state *state, const xkb_keycode_t key, char r_utf8_buf[sizeof(GHOST_TEventKeyData::utf8_buf)])
static void primary_selection_offer_offer(void *data, zwp_primary_selection_offer_v1 *id, const char *type)
static const wl_output_listener output_listener
static void gwl_registry_entry_remove_all(GWL_Display *display)
static void keyboard_handle_enter(void *data, wl_keyboard *, const uint32_t serial, wl_surface *wl_surface, wl_array *keys)
static int ghost_wl_display_event_pump(wl_display *wl_display)
static CLG_LogRef LOG_WL_XDG_WM_BASE
static void output_handle_mode(void *data, wl_output *, const uint32_t flags, const int32_t width, const int32_t height, const int32_t)
static void gwl_seat_key_repeat_timer_fn(GHOST_ITimerTask *task, uint64_t time_ms)
static void relative_pointer_handle_relative_motion(void *data, zwp_relative_pointer_v1 *, const uint32_t utime_hi, const uint32_t utime_lo, const wl_fixed_t dx, const wl_fixed_t dy, const wl_fixed_t, const wl_fixed_t)
static GWL_Seat * gwl_display_seat_active_get(const GWL_Display *display)
static const char * ghost_wl_surface_tag_id
static void xdg_output_handle_logical_size(void *data, zxdg_output_v1 *, const int32_t width, const int32_t height)
static signed char has_wl_trackpad_physical_direction
constexpr size_t events_pending_default_size
static void gwl_registry_xdg_wm_base_remove(GWL_Display *display, void *, const bool)
static bool setCursorGrab_use_software_confine(const GHOST_TGrabCursorMode mode, wl_surface *wl_surface)
static void data_offer_handle_offer(void *data, wl_data_offer *, const char *mime_type)
static const GHOST_TDragnDropTypes ghost_wl_mime_preference_order_type[]
static char * read_file_as_buffer(const int fd, const bool nil_terminate, size_t *r_len)
static void data_device_handle_motion(void *data, wl_data_device *, const uint32_t time, const wl_fixed_t x, const wl_fixed_t y)
static void gwl_registry_wl_output_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
static void gwl_registry_wp_fractional_scale_manager_remove(GWL_Display *display, void *, const bool)
static void gwl_registry_wp_fractional_scale_manager_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
GWL_TabletTool_EventTypes
static void gwl_seat_capability_pointer_multitouch_disable(GWL_Seat *seat)
#define CASE_CURSOR(shape_id, shape_name_in_theme)
static void output_handle_description(void *, wl_output *, const char *description)
static std::vector< std::string_view > gwl_clipboard_uri_ranges(const char *data_buf, size_t data_buf_len)
static void gwl_registry_wp_pointer_gestures_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
static CLG_LogRef LOG_WL_DATA_SOURCE
bool ghost_wl_surface_own_cursor_pointer(const wl_surface *wl_surface)
static void gwl_simple_buffer_free_data(GWL_SimpleBuffer *buffer)
void(*)(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms) GWL_RegistryHandler_AddFn
static CLG_LogRef LOG_WL_CURSOR_BUFFER
static void touch_seat_handle_frame(void *, wl_touch *)
static CLG_LogRef LOG_WL_DATA_DEVICE
static void gwl_seat_cursor_anim_reset(GWL_Seat *seat)
static void gwl_seat_capability_pointer_multitouch_enable(GWL_Seat *seat)
static const GHOST_TButton gwl_tablet_tool_ebutton[]
static void gwl_registry_xdg_output_manager_remove(GWL_Display *display, void *, const bool)
static GWL_SeatStateGrab seat_grab_state_from_mode(const GHOST_TGrabCursorMode mode, const bool use_software_confine)
static const int default_cursor_size
static const wl_seat_listener seat_listener
static const GWL_ModifierInfo g_modifier_info_table[MOD_INDEX_NUM]
static constexpr const char * ghost_wl_mime_text_utf8
static void gwl_seat_key_repeat_timer_add(GWL_Seat *seat, GHOST_TimerProcPtr key_repeat_fn, GHOST_TUserDataPtr payload, const bool use_delay)
static void data_source_handle_dnd_drop_performed(void *, wl_data_source *)
static void tablet_tool_handle_up(void *data, zwp_tablet_tool_v2 *)
static void gwl_xdg_decor_system_destroy(GWL_Display *display, GWL_XDG_Decor_System *decor)
static void gwl_simple_buffer_set_from_string(GWL_SimpleBuffer *buffer, const char *str)
static GWL_SeatStatePointer * gwl_seat_state_pointer_from_cursor_surface(GWL_Seat *seat, const wl_surface *wl_surface)
static void gwl_registry_xdg_activation_remove(GWL_Display *display, void *, const bool)
static int gwl_scaled_fixed_t_add_and_calc_rounded_delta(GWL_ScaledFixedT *sf, const wl_fixed_t add)
static const GWL_RegistryHandler gwl_registry_handlers[]
static void gwl_registry_wl_shm_remove(GWL_Display *display, void *, const bool)
static bool use_gnome_confine_hack
static void tablet_tool_handle_slider(void *, zwp_tablet_tool_v2 *, const int32_t position)
bool ghost_wl_surface_own_with_null_check(const wl_surface *wl_surface)
static int ghost_wl_display_event_pump_from_thread(wl_display *wl_display, const int fd, std::mutex *server_mutex)
static void output_handle_name(void *, wl_output *, const char *name)
static void data_device_handle_enter(void *data, wl_data_device *, const uint32_t serial, wl_surface *wl_surface, const wl_fixed_t x, const wl_fixed_t y, wl_data_offer *id)
static void system_clipboard_put(GWL_Display *display, const char *buffer)
static int gwl_display_seat_index(GWL_Display *display, const GWL_Seat *seat)
static const char * ghost_wl_output_tag_id
static const char * ghost_wl_mime_preference_order[]
static void shell_handle_ping(void *, xdg_wm_base *xdg_wm_base, const uint32_t serial)
static int file_descriptor_is_io_ready(int fd, const int flags, const int timeout_ms)
static void gwl_pointer_handle_frame_event_add(GWL_SeatStatePointer_Events *pointer_events, const GWL_Pointer_EventTypes ty, const uint64_t event_ms)
static void dnd_events(const GWL_Seat *const seat, const GHOST_TEventType event, const uint64_t event_ms)
static void tablet_tool_handle_pressure(void *data, zwp_tablet_tool_v2 *, const uint32_t pressure)
static int cursor_buffer_compatible_scale_from_image(const wl_cursor_image *wl_image, int scale)
static void gwl_registry_wp_pointer_constraints_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
#define GWL_IFACE_VERSION_CLAMP(params_version, version_min, version_max)
static int gwl_registry_handler_interface_slot_max()
static void gwl_registry_wl_output_update(GWL_Display *display, const GWL_RegisteryUpdate_Params ¶ms)
static void xdg_output_handle_done(void *data, zxdg_output_v1 *)
static void gwl_registry_wp_primary_selection_device_manager_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms)
static size_t ghost_wl_shm_format_as_size(enum wl_shm_format format)
static void gwl_registry_compositor_remove(GWL_Display *display, void *, const bool)
wl_fixed_t gwl_window_scale_wl_fixed_to(const GWL_WindowScaleParams &scale_params, wl_fixed_t value)
wl_fixed_t gwl_window_scale_wl_fixed_from(const GWL_WindowScaleParams &scale_params, wl_fixed_t value)
int gwl_window_scale_int_to(const GWL_WindowScaleParams &scale_params, int value)
#define FRACTIONAL_DENOMINATOR
bool ghost_wl_output_own(const struct wl_output *wl_output)
struct GWL_Output * ghost_wl_output_user_data(struct wl_output *wl_output)
GHOST_WindowWayland * ghost_wl_surface_user_data(struct wl_surface *wl_surface)
@ GHOST_kEventWheelAxisVertical
@ GHOST_kEventWheelAxisHorizontal
@ GHOST_kTrackpadEventMagnify
@ GHOST_kTrackpadEventRotate
@ GHOST_kTrackpadEventScroll
void * GHOST_TUserDataPtr
@ GHOST_kStandardCursorLeftHandle
@ GHOST_kStandardCursorHandClosed
@ GHOST_kStandardCursorHandOpen
@ GHOST_kStandardCursorBottomLeftCorner
@ GHOST_kStandardCursorZoomIn
@ GHOST_kStandardCursorVerticalSplit
@ GHOST_kStandardCursorHelp
@ GHOST_kStandardCursorCopy
@ GHOST_kStandardCursorWait
@ GHOST_kStandardCursorRightHandle
@ GHOST_kStandardCursorHorizontalSplit
@ GHOST_kStandardCursorTopSide
@ GHOST_kStandardCursorStop
@ GHOST_kStandardCursorCrosshair
@ GHOST_kStandardCursorCustom
@ GHOST_kStandardCursorNSEWScroll
@ GHOST_kStandardCursorLeftRight
@ GHOST_kStandardCursorPencil
@ GHOST_kStandardCursorNSScroll
@ GHOST_kStandardCursorCrosshairA
@ GHOST_kStandardCursorUpDown
@ GHOST_kStandardCursorUpArrow
@ GHOST_kStandardCursorHandPoint
@ GHOST_kStandardCursorBottomSide
@ GHOST_kStandardCursorBothHandles
@ GHOST_kStandardCursorInfo
@ GHOST_kStandardCursorTopLeftCorner
@ GHOST_kStandardCursorEyedropper
@ GHOST_kStandardCursorKnife
@ GHOST_kStandardCursorMove
@ GHOST_kStandardCursorCrosshairB
@ GHOST_kStandardCursorBlade
@ GHOST_kStandardCursorBottomRightCorner
@ GHOST_kStandardCursorDownArrow
@ GHOST_kStandardCursorEraser
@ GHOST_kStandardCursorDefault
@ GHOST_kStandardCursorEWScroll
@ GHOST_kStandardCursorRightSide
@ GHOST_kStandardCursorRightArrow
@ GHOST_kStandardCursorTopRightCorner
@ GHOST_kStandardCursorDestroy
@ GHOST_kStandardCursorCrosshairC
@ GHOST_kStandardCursorZoomOut
@ GHOST_kStandardCursorLeftSide
@ GHOST_kStandardCursorText
@ GHOST_kStandardCursorLeftArrow
#define GHOST_KEY_MODIFIER_TO_INDEX(key)
#define GHOST_kStandardCursorNumCursors
@ GHOST_kEventDraggingDropDone
@ GHOST_kEventDraggingExited
@ GHOST_kEventImeComposition
@ GHOST_kEventDraggingUpdated
@ GHOST_kEventDraggingEntered
@ GHOST_kEventWindowActivate
@ GHOST_kEventWindowDeactivate
@ GHOST_kEventImeCompositionStart
@ GHOST_kEventImeCompositionEnd
static const GHOST_TabletData GHOST_TABLET_DATA_NONE
#define GHOST_KEY_MODIFIER_CHECK(key)
#define GHOST_KEY_MODIFIER_NUM
@ GHOST_kTabletModeEraser
@ GHOST_kTabletModeStylus
@ GHOST_kCapabilityWindowPosition
@ GHOST_kCapabilityGPUReadFrontBuffer
@ GHOST_kCapabilityCursorWarp
@ GHOST_kCapabilityTrackpadPhysicalDirection
@ GHOST_kCapabilityWindowDecorationStyles
@ GHOST_kCapabilityDesktopSample
#define GHOST_CAPABILITY_FLAG_ALL
#define GHOST_KEY_MODIFIER_FROM_INDEX(key)
void(* GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__ *task, uint64_t time)
@ GHOST_kKeyNumpadAsterisk
GHOST_TDrawingContextType
@ GHOST_kDrawingContextTypeNone
@ GHOST_kModifierKeyRightControl
@ GHOST_kModifierKeyLeftControl
@ GHOST_kModifierKeyRightHyper
@ GHOST_kModifierKeyRightAlt
@ GHOST_kModifierKeyRightShift
@ GHOST_kModifierKeyLeftAlt
@ GHOST_kModifierKeyLeftShift
@ GHOST_kModifierKeyLeftOS
@ GHOST_kModifierKeyRightOS
@ GHOST_kModifierKeyLeftHyper
void(* GHOST_TBacktraceFn)(void *file_handle)
@ GHOST_kDragnDropTypeUnknown
@ GHOST_kDragnDropTypeFilenames
@ GHOST_kDragnDropTypeString
@ GHOST_kButtonMaskButton4
@ GHOST_kButtonMaskButton7
@ GHOST_kButtonMaskButton6
@ GHOST_kButtonMaskButton5
@ GHOST_kButtonMaskMiddle
GHOST_TConsoleWindowState
#define WL_ARRAY_FOR_EACH(pos, array)
static const wl_surface_listener wl_surface_listener
#define USE_EVENT_BACKGROUND_THREAD
ImBuf * IMB_load_image_from_filepath(const char *filepath, const int flags, char r_colorspace[IM_MAX_SPACE]=nullptr)
ImBuf * IMB_load_image_from_memory(const unsigned char *mem, const size_t size, const int flags, const char *descr, const char *filepath=nullptr, char r_colorspace[IM_MAX_SPACE]=nullptr)
ImBuf * IMB_allocFromBuffer(const uint8_t *byte_buffer, const float *float_buffer, unsigned int w, unsigned int h, unsigned int channels)
void IMB_freeImBuf(ImBuf *ibuf)
bool IMB_save_image(ImBuf *ibuf, const char *filepath, const int flags)
bool IMB_test_image(const char *filepath)
BMesh const char void * data
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
btAlignedObjectArray< btScalar > m_data
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
virtual GHOST_TEventType getType() const =0
virtual GHOST_IWindow * getWindow() const =0
static GHOST_TBacktraceFn getBacktraceFn()
virtual GHOST_TUserDataPtr getUserData() const =0
virtual GHOST_TimerProcPtr getTimerProc() const =0
virtual void wrapPoint(int32_t &x, int32_t &y, int32_t ofs, GHOST_TAxisFlag axis)
struct zwp_primary_selection_device_manager_v1 * wp_primary_selection_manager_get()
static const char * xdg_app_id_get()
GHOST_TSuccess init() override
GHOST_TSuccess pushEvent_maybe_pending(const GHOST_IEvent *event)
bool window_surface_unref(const wl_surface *wl_surface)
uint64_t getMilliSeconds() const override
GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const override
bool window_cursor_grab_set(const GHOST_TGrabCursorMode mode, const GHOST_TGrabCursorMode mode_current, int32_t init_grab_xy[2], const GHOST_Rect *wrap_bounds, GHOST_TAxisFlag wrap_axis, wl_surface *wl_surface, const struct GWL_WindowScaleParams &scale_params)
GHOST_TSuccess cursor_visibility_set(bool visible)
std::thread::id main_thread_id
struct wl_display * wl_display_get()
char * getClipboard(bool selection) const override
GHOST_TSuccess setCursorPosition(int32_t x, int32_t y) override
GHOST_TSuccess cursor_shape_check(GHOST_TStandardCursor cursorShape)
bool cursor_grab_use_software_display_get(const GHOST_TGrabCursorMode mode)
uint64_t ms_from_input_time(const uint32_t timestamp_as_uint)
GHOST_TimerManager * ghost_timer_manager()
uint * getClipboardImage(int *r_width, int *r_height) const override
struct xdg_wm_base * xdg_decor_shell_get()
struct wl_compositor * wl_compositor_get()
struct wp_fractional_scale_manager_v1 * wp_fractional_scale_manager_get()
void setMultitouchGestures(const bool use) override
struct wl_shm * wl_shm_get() const
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const override
GHOST_TSuccess cursor_shape_set(GHOST_TStandardCursor shape)
const std::vector< GWL_Output * > & outputs_get() const
GHOST_TSuccess disposeContext(GHOST_IContext *context) override
GHOST_IWindow * createWindow(const char *title, int32_t left, int32_t top, uint32_t width, uint32_t height, GHOST_TWindowState state, GHOST_GPUSettings gpuSettings, const bool exclusive, const bool is_dialog, const GHOST_IWindow *parentWindow) override
struct wp_viewporter * wp_viewporter_get()
struct zxdg_decoration_manager_v1 * xdg_decor_manager_get()
struct wl_seat * wl_seat_active_get_with_input_serial(uint32_t &serial)
GHOST_TSuccess cursor_bitmap_get(GHOST_CursorBitmapRef *bitmap)
GHOST_TSuccess cursor_shape_custom_set(const uint8_t *bitmap, const uint8_t *mask, int sizex, int sizey, int hotX, int hotY, bool canInvertColor)
GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const override
void ime_begin(const GHOST_WindowWayland *win, int32_t x, int32_t y, int32_t w, int32_t h, bool completed) const
uint8_t getNumDisplays() const override
bool output_unref(struct wl_output *wl_output)
~GHOST_SystemWayland() override
void putClipboard(const char *buffer, bool selection) const override
void output_scale_update(GWL_Output *output)
GHOST_TCapabilityFlag getCapabilities() const override
std::atomic< bool > has_pending_actions_for_window
bool processEvents(bool waitForEvent) override
void seat_active_set(const struct GWL_Seat *seat)
GHOST_TSuccess getCursorPositionClientRelative(const GHOST_IWindow *window, int32_t &x, int32_t &y) const override
GHOST_TSuccess setCursorPositionClientRelative(GHOST_IWindow *window, int32_t x, int32_t y) override
GHOST_TSuccess hasClipboardImage() const override
bool setConsoleWindowState(GHOST_TConsoleWindowState action) override
std::mutex * server_mutex
void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const override
struct xdg_activation_v1 * xdg_activation_manager_get()
uint32_t getCursorPreferredLogicalSize() const override
struct zwp_pointer_gestures_v1 * wp_pointer_gestures_get()
void ime_end(const GHOST_WindowWayland *win) const
GHOST_IContext * createOffscreenContext(GHOST_GPUSettings gpuSettings) override
void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const override
GHOST_TSuccess putClipboardImage(uint *rgba, int width, int height) const override
GHOST_TSuccess removeTimer(GHOST_ITimerTask *timerTask) override
GHOST_EventManager * getEventManager() const
GHOST_WindowManager * getWindowManager() const
bool m_multitouchGestures
GHOST_TSuccess init() override
GHOST_TimerManager * getTimerManager() const
GHOST_ITimerTask * installTimer(uint64_t delay, uint64_t interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData=nullptr) override
GHOST_WindowManager * m_windowManager
GHOST_TSuccess removeTimer(GHOST_TimerTask *timer)
GHOST_TSuccess addTimer(GHOST_TimerTask *timer)
const std::vector< GHOST_IWindow * > & getWindows() const
GHOST_TSuccess setActiveWindow(GHOST_IWindow *window)
void setWindowInactive(const GHOST_IWindow *window)
const struct GWL_WindowScaleParams & scale_params_get() const
bool outputs_leave(GWL_Output *output)
wl_fixed_t wl_fixed_to_window(wl_fixed_t value) const
void outputs_changed_update_scale_tag()
void pending_actions_handle()
bool getValid() const override
wl_fixed_t wl_fixed_from_window(wl_fixed_t value) const
void getClientBounds(GHOST_Rect &bounds) const override
GHOST_TSuccess cursor_shape_refresh()
const std::vector< GWL_Output * > & outputs_get()
GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) const override
GHOST_TAxisFlag getCursorGrabAxis() const
bool getCursorGrabModeIsWarp() const
static __attribute__((constructor)) void cpu_check()
float distance(VecOp< float, D >, VecOp< float, D >) RET
constexpr T degrees(T) RET
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
static void error(const char *str)
static int make(const char *input_file_name, const char *output_file_name)
static void add(blender::Map< std::string, std::string > &messages, Message &msg)
int context(const bContext *C, const char *member, bContextDataResult *result)
bool is_enabled(const Sculpt &sd, const Object &object, const Brush *br)
MatBase< T, NumCol, NumRow > scale(const MatBase< T, NumCol, NumRow > &mat, const VectorT &scale)
static blender::bke::bNodeSocketTemplate outputs[]
GHOST_TDrawingContextType context_type
GHOST_GPUDevice preferred_device
void set(GHOST_TModifierKey mask, bool down)
std::atomic< bool > exit_pending
const char * names[GHOST_kStandardCursorNumCursors]
struct GWL_Cursor::@050316242345211375236221043351014205236353051251 wl
GWL_Cursor_AnimHandle * anim_handle
const wl_cursor * theme_cursor
wl_surface * surface_cursor
const char * theme_cursor_name
std::unordered_set< std::string > types
enum wl_data_device_manager_dnd_action source_actions
struct GWL_DataOffer::@000321357326273027247056345031354174337224053377 wl
enum wl_data_device_manager_dnd_action action
struct GWL_DataOffer::@011247255043237154242043025362334115133317316307 dnd
GWL_SimpleBuffer buffer_out
struct GWL_DataSource::@171373255262027061130125060265037104067374340011 wl
wp_viewporter * viewporter
zwp_primary_selection_device_manager_v1 * primary_selection_device_manager
std::vector< GWL_Seat * > seats
bool events_pthread_is_active
GHOST_TimerManager * ghost_timer_manager
struct GWL_Display::@311217013120347372235111234227065250031142315272 xdg
std::vector< const GHOST_IEvent * > events_pending
std::vector< GWL_Output * > outputs
zwp_pointer_gestures_v1 * pointer_gestures
GWL_DisplayTimeStamp input_timestamp
struct GWL_Display::@332351376246201271020375353224364047225056022363 wl
GWL_XDG_Decor_System * xdg_decor
bool registry_skip_update_all
GWL_RegistryEntry * registry_entry
zwp_pointer_constraints_v1 * pointer_constraints
zwp_relative_pointer_manager_v1 * relative_pointer_manager
wl_compositor * compositor
zxdg_output_manager_v1 * output_manager
struct GWL_Display::@041375341326273211065375343216100110111213252212 wp
xdg_activation_v1 * activation_manager
wl_data_device_manager * data_device_manager
zwp_tablet_manager_v2 * tablet_manager
GHOST_SystemWayland * system
std::mutex events_pending_mutex
wp_fractional_scale_manager_v1 * fractional_scale_manager
struct GWL_KeyRepeatPlayload::@133074121273233316143122154352324207053125164376 key_data
int16_t mods[GHOST_KEY_MODIFIER_NUM]
const char * display_name
zwp_primary_selection_offer_v1 * id
std::unordered_set< std::string > types
struct GWL_PrimarySelection_DataOffer::@224052045254066252237315110075221223001265154224 wp
GWL_SimpleBuffer buffer_out
zwp_primary_selection_source_v1 * source
struct GWL_PrimarySelection_DataSource::@214262242275022125172372225345372305347362001205 wp
GWL_PrimarySelection_DataSource * data_source
std::mutex data_offer_mutex
GWL_PrimarySelection_DataOffer * data_offer
std::mutex data_source_mutex
GWL_RegistryHandler_AddFn add_fn
const char *const * interface_p
GWL_RegistryEntry_RemoveFn remove_fn
GWL_RegistryHandler_UpdateFn update_fn
struct GWL_SeatStateKeyboard::@000213333310320026041147135010277053023061216335 wl
wl_surface * surface_window
GWL_ScaledFixedT rotation
struct GWL_SeatStatePointer_Events::@227246237361267121111060051345102206175303062350 frame_pending
GWL_Pointer_EventTypes frame_types[GWL_TabletTool_FrameTypes_NUM]
uint64_t frame_event_ms[GWL_TabletTool_FrameTypes_NUM]
wl_surface * surface_window
struct GWL_SeatStatePointer::@106371335315343070276130104021044224024005363234 wl
std::unordered_set< const GWL_Output * > outputs
struct GWL_Seat::@035335017147325312156122174053370360242062243043 key_repeat
GHOST_SystemWayland * system
GWL_SeatStatePointerScroll pointer_scroll
GWL_KeyboardDepressedState key_depressed
GWL_SeatStatePointer_Events pointer_events
GWL_DataSource * data_source
uint32_t data_source_serial
struct GWL_Seat::@017114216203334356214327031134132054273005244337 wl
std::unordered_set< zwp_tablet_tool_v2 * > tablet_tools
GWL_DataOffer * data_offer_copy_paste
zwp_primary_selection_device_v1 * primary_selection_device
std::mutex data_source_mutex
xkb_mod_index_t xkb_keymap_mod_index[MOD_INDEX_NUM]
zwp_relative_pointer_v1 * relative_pointer
xkb_compose_state * compose_state
std::optional< GHOST_TSuccess > data_offer_copy_paste_has_image
xkb_state * state_empty_with_shift
std::mutex data_offer_dnd_mutex
xkb_state * state_empty_with_numlock
GWL_PrimarySelection primary_selection
std::mutex data_offer_copy_paste_mutex
uint32_t cursor_source_serial
GWL_SeatStatePointer tablet
bool use_pointer_scroll_smooth_as_discrete
struct GWL_Seat::@010013076176246161274337005250343273344166001063 wp
zwp_tablet_seat_v2 * tablet_seat
wl_surface * surface_window_focus_dnd
xkb_layout_index_t layout_active
zwp_confined_pointer_v1 * confined_pointer
xkb_compose_table * compose_table
wl_data_device * data_device
xkb_mod_index_t xkb_keymap_mod_index_numlock
bool xkb_use_non_latin_workaround
wl_fixed_t grab_lock_xy[2]
GWL_DataOffer * data_offer_dnd
struct GWL_Seat::@043243047264252106207033262235132033213071332203 xkb
xkb_mod_index_t xkb_keymap_mod_index_mod2
zwp_locked_pointer_v1 * locked_pointer
GWL_SeatStatePointerGesture_Pinch pointer_gesture_pinch
bool use_pointer_software_confine
zxdg_decoration_manager_v1 * manager
ImbFormatOptions foptions
ImBufByteBuffer byte_buffer
unsigned int encoded_buffer_size
ImBufByteBuffer encoded_buffer
void wayland_dynload_client_exit(void)
void wayland_dynload_cursor_exit(void)
bool wayland_dynload_cursor_init(bool verbose)
bool wayland_dynload_client_init(bool verbose)
#define wl_proxy_get_tag(...)
#define wl_display_connect(...)
#define wl_log_set_handler_client(...)
#define wl_display_dispatch_pending(...)
#define wl_proxy_set_tag(...)
#define wl_display_get_error(...)
#define wl_display_cancel_read(...)
#define wl_display_dispatch(...)
#define wl_display_get_fd(...)
#define wl_display_prepare_read(...)
#define wl_display_flush(...)
#define wl_display_get_protocol_error(...)
#define wl_display_disconnect(...)
#define wl_display_read_events(...)
#define wl_display_roundtrip(...)
#define wl_cursor_theme_get_cursor(...)
#define wl_cursor_theme_load(...)
#define wl_cursor_image_get_buffer(...)
#define wl_cursor_theme_destroy(...)
void wayland_dynload_egl_exit(void)
#define wl_egl_window_create(...)
#define wl_egl_window_destroy(...)
void wayland_dynload_libdecor_exit(void)
#define libdecor_unref(...)
#define libdecor_new(...)