Merge branch 'blender-v4.0-release'

This commit is contained in:
Campbell Barton
2023-10-20 14:00:41 +11:00

View File

@@ -56,6 +56,7 @@
#endif
#include <wayland-cursor.h>
#include <xkbcommon/xkbcommon-compose.h>
#include <xkbcommon/xkbcommon.h>
/* Generated by `wayland-scanner`. */
@@ -813,6 +814,12 @@ struct GWL_Seat {
struct {
xkb_context *context = nullptr;
/** The compose key table (check for null before use). */
xkb_compose_table *compose_table = nullptr;
/** The compose state is expected to use the keyboard `state` (check for null before use). */
xkb_compose_state *compose_state = nullptr;
xkb_state *state = nullptr;
/**
* Keep a state with no modifiers active, use for symbol lookups.
@@ -1486,6 +1493,24 @@ static void gwl_registry_entry_update_all(GWL_Display *display, const int interf
/** \name Private Utility Functions
* \{ */
/**
* Access the LOCALE (with a fallback).
*/
static const char *ghost_wl_locale_from_env_with_default()
{
const char *locale = getenv("LC_ALL");
if (!locale || !*locale) {
locale = getenv("LC_CTYPE");
if (!locale || !*locale) {
locale = getenv("LANG");
if (!locale || !*locale) {
locale = "C";
}
}
}
return locale;
}
static void ghost_wl_display_report_error(wl_display *display)
{
int ecode = wl_display_get_error(display);
@@ -3897,6 +3922,14 @@ static void keyboard_handle_keymap(void *data,
CLOG_INFO(LOG, 2, "keymap");
if (seat->xkb.compose_state) {
xkb_compose_state_reset(seat->xkb.compose_state);
}
else {
seat->xkb.compose_state = xkb_compose_state_new(seat->xkb.compose_table,
XKB_COMPOSE_STATE_NO_FLAGS);
}
/* In practice we can assume `xkb_state_new` always succeeds. */
xkb_state_unref(seat->xkb.state);
seat->xkb.state = xkb_state_new(keymap);
@@ -4077,6 +4110,42 @@ static xkb_keysym_t xkb_state_key_get_one_sym_without_modifiers(
return sym;
}
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)])
{
const xkb_keysym_t sym = xkb_state_key_get_one_sym(state, key);
const xkb_compose_feed_result result = xkb_compose_state_feed(compose_state, sym);
bool handled = false;
if (result == XKB_COMPOSE_FEED_ACCEPTED) {
switch (xkb_compose_state_get_status(compose_state)) {
case XKB_COMPOSE_NOTHING: {
break;
}
case XKB_COMPOSE_COMPOSING: {
break;
}
case XKB_COMPOSE_COMPOSED: {
char utf8_buf_compose[sizeof(GHOST_TEventKeyData::utf8_buf) + 1] = {'\0'};
const int utf8_buf_compose_len = xkb_compose_state_get_utf8(
compose_state, utf8_buf_compose, sizeof(utf8_buf_compose));
if (utf8_buf_compose_len > 0) {
memcpy(r_utf8_buf, utf8_buf_compose, utf8_buf_compose_len);
handled = true;
}
break;
}
case XKB_COMPOSE_CANCELLED: {
break;
}
}
}
return handled;
}
/**
* \note Caller must lock `timer_mutex`.
*/
@@ -4198,9 +4267,19 @@ static void keyboard_handle_key(void *data,
}
const GHOST_TKey gkey = xkb_map_gkey_or_scan_code(sym, key);
char utf8_buf[sizeof(GHOST_TEventKeyData::utf8_buf)] = {'\0'};
if (etype == GHOST_kEventKeyDown) {
xkb_state_key_get_utf8(seat->xkb.state, key_code, utf8_buf, sizeof(utf8_buf));
/* Handle key-compose (dead-keys). */
if (seat->xkb.compose_state &&
xkb_compose_state_feed_and_get_utf8(
seat->xkb.compose_state, seat->xkb.state, key_code, utf8_buf))
{
/* `utf8_buf` has been filled by a compose action. */
}
else {
xkb_state_key_get_utf8(seat->xkb.state, key_code, utf8_buf, sizeof(utf8_buf));
}
}
seat->data_source_serial = serial;
@@ -4235,8 +4314,18 @@ static void keyboard_handle_key(void *data,
GHOST_IWindow *win = ghost_wl_surface_user_data(wl_surface_focus);
GHOST_SystemWayland *system = seat->system;
/* Calculate this value every time in case modifier keys are pressed. */
char utf8_buf[sizeof(GHOST_TEventKeyData::utf8_buf)] = {'\0'};
xkb_state_key_get_utf8(seat->xkb.state, payload->key_code, utf8_buf, sizeof(utf8_buf));
if (seat->xkb.compose_state &&
xkb_compose_state_feed_and_get_utf8(
seat->xkb.compose_state, seat->xkb.state, payload->key_code, utf8_buf))
{
/* `utf8_buf` has been filled by a compose action. */
}
else {
xkb_state_key_get_utf8(seat->xkb.state, payload->key_code, utf8_buf, sizeof(utf8_buf));
}
system->pushEvent_maybe_pending(new GHOST_EventKey(system->getMilliSeconds(),
GHOST_kEventKeyDown,
win,
@@ -5318,6 +5407,11 @@ static void gwl_registry_wl_seat_add(GWL_Display *display, const GWL_RegisteryAd
GWL_Seat *seat = new GWL_Seat;
seat->system = display->system;
seat->xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
/* May be null (skip dead-key support in this case). */
seat->xkb.compose_table = xkb_compose_table_new_from_locale(
seat->xkb.context, ghost_wl_locale_from_env_with_default(), XKB_COMPOSE_COMPILE_NO_FLAGS);
seat->data_source = new GWL_DataSource;
seat->wl.seat = static_cast<wl_seat *>(
wl_registry_bind(display->wl.registry, params->name, &wl_seat_interface, 5));
@@ -5453,6 +5547,9 @@ static void gwl_registry_wl_seat_remove(GWL_Display *display, void *user_data, c
xkb_state_unref(seat->xkb.state_empty_with_shift);
xkb_state_unref(seat->xkb.state_empty_with_numlock);
xkb_compose_state_unref(seat->xkb.compose_state);
xkb_compose_table_unref(seat->xkb.compose_table);
xkb_context_unref(seat->xkb.context);
/* Remove the seat. */