mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-02-23 01:40:31 -05:00
Merge remote-tracking branch 'upstream/master' into 10bit-color
This commit is contained in:
commit
e9855a3571
14 changed files with 505 additions and 30 deletions
|
|
@ -935,7 +935,9 @@ static bool drm_connector_set_cursor(struct wlr_output *output,
|
|||
return false;
|
||||
}
|
||||
|
||||
drm_surface_make_current(&plane->surf, NULL);
|
||||
if (!drm_surface_make_current(&plane->surf, NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct wlr_renderer *rend = plane->surf.renderer->wlr_rend;
|
||||
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ static void finish_drm_surface(struct wlr_drm_surface *surf) {
|
|||
}
|
||||
|
||||
bool drm_surface_make_current(struct wlr_drm_surface *surf,
|
||||
int *buffer_damage) {
|
||||
return wlr_egl_make_current(&surf->renderer->egl, surf->egl, buffer_damage);
|
||||
int *buffer_age) {
|
||||
return wlr_egl_make_current(&surf->renderer->egl, surf->egl, buffer_age);
|
||||
}
|
||||
|
||||
bool export_drm_bo(struct gbm_bo *bo, struct wlr_dmabuf_attributes *attribs) {
|
||||
|
|
|
|||
217
examples/input-method-keyboard-grab.c
Normal file
217
examples/input-method-keyboard-grab.c
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <wayland-client.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include "input-method-unstable-v2-client-protocol.h"
|
||||
|
||||
static struct wl_display *display = NULL;
|
||||
static struct wl_seat *seat = NULL;
|
||||
static struct zwp_input_method_manager_v2 *input_method_manager = NULL;
|
||||
static struct zwp_input_method_v2 *input_method = NULL;
|
||||
static struct zwp_input_method_keyboard_grab_v2 *kb_grab = NULL;
|
||||
|
||||
static bool active = false;
|
||||
static bool pending_active = false;
|
||||
|
||||
static struct xkb_context *xkb_context = NULL;
|
||||
static struct xkb_keymap *keymap = NULL;
|
||||
static struct xkb_state *xkb_state = NULL;
|
||||
|
||||
static void handle_key(void *data,
|
||||
struct zwp_input_method_keyboard_grab_v2 *im_keyboard_grab,
|
||||
uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
|
||||
printf("handle_key %u %u %u %u\n", serial, time, key, state);
|
||||
xkb_keysym_t keysym = xkb_state_key_get_one_sym(xkb_state, key + 8);
|
||||
char keysym_name[64];
|
||||
xkb_keysym_get_name(keysym, keysym_name, sizeof(keysym_name));
|
||||
printf("xkb translated to %s\n", keysym_name);
|
||||
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
if (keysym == XKB_KEY_KP_Enter || keysym == XKB_KEY_Return) {
|
||||
printf("Stopping grab\n");
|
||||
zwp_input_method_keyboard_grab_v2_release(kb_grab);
|
||||
kb_grab = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void handle_modifiers(void *data,
|
||||
struct zwp_input_method_keyboard_grab_v2 *im_keyboard_grab,
|
||||
uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
|
||||
uint32_t mods_locked, uint32_t group) {
|
||||
printf("handle_modifiers %u %u %u %u %u\n", serial, mods_depressed,
|
||||
mods_latched, mods_locked, group);
|
||||
xkb_state_update_mask(xkb_state, mods_depressed, mods_latched,
|
||||
mods_locked, 0, 0, group);
|
||||
}
|
||||
|
||||
static void handle_keymap(void *data,
|
||||
struct zwp_input_method_keyboard_grab_v2 *im_keyboard_grab,
|
||||
uint32_t format, int32_t fd, uint32_t size) {
|
||||
printf("handle_keymap\n");
|
||||
char *keymap_string = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
xkb_keymap_unref(keymap);
|
||||
keymap = xkb_keymap_new_from_string(xkb_context, keymap_string,
|
||||
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
munmap(keymap_string, size);
|
||||
close(fd);
|
||||
xkb_state_unref(xkb_state);
|
||||
xkb_state = xkb_state_new(keymap);
|
||||
}
|
||||
|
||||
static void handle_repeat_info(void *data,
|
||||
struct zwp_input_method_keyboard_grab_v2 *im_keyboard_grab,
|
||||
int32_t rate, int32_t delay) {
|
||||
printf("handle_repeat_info %d %d", rate, delay);
|
||||
}
|
||||
|
||||
|
||||
static const struct zwp_input_method_keyboard_grab_v2_listener grab_listener = {
|
||||
.key = handle_key,
|
||||
.modifiers = handle_modifiers,
|
||||
.keymap = handle_keymap,
|
||||
.repeat_info = handle_repeat_info,
|
||||
};
|
||||
|
||||
static void handle_activate(void *data,
|
||||
struct zwp_input_method_v2 *zwp_input_method_v2) {
|
||||
pending_active = true;
|
||||
}
|
||||
|
||||
static void handle_deactivate(void *data,
|
||||
struct zwp_input_method_v2 *zwp_input_method_v2) {
|
||||
pending_active = false;
|
||||
}
|
||||
|
||||
static void handle_unavailable(void *data,
|
||||
struct zwp_input_method_v2 *zwp_input_method_v2) {
|
||||
printf("IM unavailable\n");
|
||||
zwp_input_method_v2_destroy(zwp_input_method_v2);
|
||||
input_method = NULL;
|
||||
}
|
||||
|
||||
static void im_activate(void *data,
|
||||
struct zwp_input_method_v2 *id) {
|
||||
kb_grab = zwp_input_method_v2_grab_keyboard(input_method);
|
||||
if (kb_grab == NULL) {
|
||||
fprintf(stderr, "Failed to grab\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
zwp_input_method_keyboard_grab_v2_add_listener(kb_grab, &grab_listener,
|
||||
NULL);
|
||||
printf("Started grab, press enter to stop grab\n");
|
||||
}
|
||||
|
||||
static void im_deactivate(void *data,
|
||||
struct zwp_input_method_v2 *context) {
|
||||
if (kb_grab != NULL) {
|
||||
zwp_input_method_keyboard_grab_v2_release(kb_grab);
|
||||
kb_grab = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_done(void *data,
|
||||
struct zwp_input_method_v2 *zwp_input_method_v2) {
|
||||
bool prev_active = active;
|
||||
if (active != pending_active) {
|
||||
printf("Now %s\n", pending_active ? "active" : "inactive");
|
||||
}
|
||||
active = pending_active;
|
||||
if (active && !prev_active) {
|
||||
im_activate(data, zwp_input_method_v2);
|
||||
} else if (!active && prev_active) {
|
||||
im_deactivate(data, zwp_input_method_v2);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_surrounding_text(void *data,
|
||||
struct zwp_input_method_v2 *zwp_input_method_v2,
|
||||
const char *text, uint32_t cursor, uint32_t anchor) {
|
||||
// not for this test
|
||||
}
|
||||
|
||||
static void handle_text_change_cause(void *data,
|
||||
struct zwp_input_method_v2 *zwp_input_method_v2,
|
||||
uint32_t cause) {
|
||||
// not for this test
|
||||
}
|
||||
|
||||
static void handle_content_type(void *data,
|
||||
struct zwp_input_method_v2 *zwp_input_method_v2,
|
||||
uint32_t hint, uint32_t purpose) {
|
||||
// not for this test
|
||||
}
|
||||
|
||||
static const struct zwp_input_method_v2_listener im_listener = {
|
||||
.activate = handle_activate,
|
||||
.deactivate = handle_deactivate,
|
||||
.surrounding_text = handle_surrounding_text,
|
||||
.text_change_cause = handle_text_change_cause,
|
||||
.content_type = handle_content_type,
|
||||
.done = handle_done,
|
||||
.unavailable = handle_unavailable,
|
||||
};
|
||||
|
||||
static void handle_global(void *data, struct wl_registry *registry,
|
||||
uint32_t name, const char *interface, uint32_t version) {
|
||||
if (strcmp(interface, zwp_input_method_manager_v2_interface.name) == 0) {
|
||||
input_method_manager = wl_registry_bind(registry, name,
|
||||
&zwp_input_method_manager_v2_interface, 1);
|
||||
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
|
||||
seat = wl_registry_bind(registry, name, &wl_seat_interface, version);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_global_remove(void *data, struct wl_registry *registry,
|
||||
uint32_t name) {
|
||||
// who cares
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
.global = handle_global,
|
||||
.global_remove = handle_global_remove,
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (xkb_context == NULL) {
|
||||
fprintf(stderr, "Failed to create xkb context\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
display = wl_display_connect(NULL);
|
||||
if (display == NULL) {
|
||||
fprintf(stderr, "Failed to create display\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
struct wl_registry *registry = wl_display_get_registry(display);
|
||||
wl_registry_add_listener(registry, ®istry_listener, NULL);
|
||||
wl_display_dispatch(display);
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
if (input_method_manager == NULL) {
|
||||
fprintf(stderr, "input-method not available\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (seat == NULL) {
|
||||
fprintf(stderr, "seat not available\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
input_method = zwp_input_method_manager_v2_get_input_method(
|
||||
input_method_manager, seat);
|
||||
zwp_input_method_v2_add_listener(input_method, &im_listener, NULL);
|
||||
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
while (wl_display_dispatch(display) != -1) {
|
||||
// This space is intentionally left blank
|
||||
};
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -170,6 +170,13 @@ clients = {
|
|||
'dep': wlroots,
|
||||
'proto': ['wlr-virtual-pointer-unstable-v1'],
|
||||
},
|
||||
'input-method-keyboard-grab': {
|
||||
'src': 'input-method-keyboard-grab.c',
|
||||
'dep': xkbcommon,
|
||||
'proto': [
|
||||
'input-method-unstable-v2',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
foreach name, info : compositors
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ struct wlr_input_method_v2 {
|
|||
struct wl_resource *resource;
|
||||
|
||||
struct wlr_seat *seat;
|
||||
struct wlr_seat_client *seat_client;
|
||||
|
||||
struct wlr_input_method_v2_state pending;
|
||||
struct wlr_input_method_v2_state current;
|
||||
|
|
@ -41,16 +42,33 @@ struct wlr_input_method_v2 {
|
|||
bool client_active; // state known to the client
|
||||
uint32_t current_serial; // received in last commit call
|
||||
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab;
|
||||
|
||||
struct wl_list link;
|
||||
|
||||
struct wl_listener seat_destroy;
|
||||
struct wl_listener seat_client_destroy;
|
||||
|
||||
struct {
|
||||
struct wl_signal commit; // (struct wlr_input_method_v2*)
|
||||
struct wl_signal grab_keyboard; // (struct wlr_input_method_keyboard_grab_v2*)
|
||||
struct wl_signal destroy; // (struct wlr_input_method_v2*)
|
||||
} events;
|
||||
};
|
||||
|
||||
struct wlr_input_method_keyboard_grab_v2 {
|
||||
struct wl_resource *resource;
|
||||
struct wlr_input_method_v2 *input_method;
|
||||
struct wlr_keyboard *keyboard;
|
||||
|
||||
struct wl_listener keyboard_keymap;
|
||||
struct wl_listener keyboard_repeat_info;
|
||||
struct wl_listener keyboard_destroy;
|
||||
|
||||
struct {
|
||||
struct wl_signal destroy; // (struct wlr_input_method_keyboard_grab_v2*)
|
||||
} events;
|
||||
};
|
||||
|
||||
struct wlr_input_method_manager_v2 {
|
||||
struct wl_global *global;
|
||||
struct wl_list input_methods; // struct wlr_input_method_v2*::link
|
||||
|
|
@ -82,4 +100,16 @@ void wlr_input_method_v2_send_done(struct wlr_input_method_v2 *input_method);
|
|||
void wlr_input_method_v2_send_unavailable(
|
||||
struct wlr_input_method_v2 *input_method);
|
||||
|
||||
void wlr_input_method_keyboard_grab_v2_send_key(
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab,
|
||||
uint32_t time, uint32_t key, uint32_t state);
|
||||
void wlr_input_method_keyboard_grab_v2_send_modifiers(
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab,
|
||||
struct wlr_keyboard_modifiers *modifiers);
|
||||
void wlr_input_method_keyboard_grab_v2_set_keyboard(
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab,
|
||||
struct wlr_keyboard *keyboard);
|
||||
void wlr_input_method_keyboard_grab_v2_destroy(
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
*/
|
||||
struct wlr_layer_shell_v1 {
|
||||
struct wl_global *global;
|
||||
struct wl_list surfaces; // wl_layer_surface
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
|
||||
|
|
@ -63,7 +62,6 @@ struct wlr_layer_surface_v1_configure {
|
|||
};
|
||||
|
||||
struct wlr_layer_surface_v1 {
|
||||
struct wl_list link; // wlr_layer_shell_v1::surfaces
|
||||
struct wlr_surface *surface;
|
||||
struct wlr_output *output;
|
||||
struct wl_resource *resource;
|
||||
|
|
|
|||
|
|
@ -409,6 +409,12 @@ void wlr_seat_pointer_notify_enter(struct wlr_seat *wlr_seat,
|
|||
*/
|
||||
void wlr_seat_pointer_notify_clear_focus(struct wlr_seat *wlr_seat);
|
||||
|
||||
/**
|
||||
* Warp the pointer of this seat to the given surface-local coordinates, without
|
||||
* generating motion events.
|
||||
*/
|
||||
void wlr_seat_pointer_warp(struct wlr_seat *wlr_seat, double sx, double sy);
|
||||
|
||||
/**
|
||||
* Notify the seat of motion over the given surface. Pass surface-local
|
||||
* coordinates where the pointer motion occurred. Defers to any grab of the
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ struct wlr_virtual_keyboard_manager_v1 {
|
|||
};
|
||||
|
||||
struct wlr_virtual_keyboard_v1 {
|
||||
struct wl_resource *resource;
|
||||
struct wlr_input_device input_device;
|
||||
struct wl_resource *resource;
|
||||
struct wlr_seat *seat;
|
||||
bool has_keymap;
|
||||
|
||||
|
|
@ -41,4 +41,7 @@ struct wlr_virtual_keyboard_v1 {
|
|||
struct wlr_virtual_keyboard_manager_v1* wlr_virtual_keyboard_manager_v1_create(
|
||||
struct wl_display *display);
|
||||
|
||||
struct wlr_virtual_keyboard_v1 *wlr_input_device_get_virtual_keyboard(
|
||||
struct wlr_input_device *wlr_dev);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
project(
|
||||
'wlroots',
|
||||
'c',
|
||||
version: '0.10.0',
|
||||
version: '0.11.0',
|
||||
license: 'MIT',
|
||||
meson_version: '>=0.54.0',
|
||||
default_options: [
|
||||
|
|
@ -15,7 +15,7 @@ project(
|
|||
# necessary for bugfix releases. Increasing soversion is required because
|
||||
# wlroots never guarantees ABI stability -- only API stability is guaranteed
|
||||
# between minor releases.
|
||||
soversion = 5
|
||||
soversion = 6
|
||||
|
||||
add_project_arguments([
|
||||
'-DWLR_USE_UNSTABLE',
|
||||
|
|
|
|||
15
render/egl.c
15
render/egl.c
|
|
@ -459,7 +459,20 @@ void wlr_egl_save_context(struct wlr_egl_context *context) {
|
|||
}
|
||||
|
||||
bool wlr_egl_restore_context(struct wlr_egl_context *context) {
|
||||
return eglMakeCurrent(context->display, context->draw_surface,
|
||||
// If the saved context is a null-context, we must use the current
|
||||
// display instead of the saved display because eglMakeCurrent() can't
|
||||
// handle EGL_NO_DISPLAY.
|
||||
EGLDisplay display = context->display == EGL_NO_DISPLAY ?
|
||||
eglGetCurrentDisplay() : context->display;
|
||||
|
||||
// If the current display is also EGL_NO_DISPLAY, we assume that there
|
||||
// is currently no context set and no action needs to be taken to unset
|
||||
// the context.
|
||||
if (display == EGL_NO_DISPLAY) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return eglMakeCurrent(display, context->draw_surface,
|
||||
context->read_surface, context->context);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -199,11 +199,9 @@ void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat,
|
|||
wlr_seat->pointer_state.focused_client = client;
|
||||
wlr_seat->pointer_state.focused_surface = surface;
|
||||
if (surface != NULL) {
|
||||
wlr_seat->pointer_state.sx = sx;
|
||||
wlr_seat->pointer_state.sy = sy;
|
||||
wlr_seat_pointer_warp(wlr_seat, sx, sy);
|
||||
} else {
|
||||
wlr_seat->pointer_state.sx = NAN;
|
||||
wlr_seat->pointer_state.sy = NAN;
|
||||
wlr_seat_pointer_warp(wlr_seat, NAN, NAN);
|
||||
}
|
||||
|
||||
struct wlr_seat_pointer_focus_change_event event = {
|
||||
|
|
@ -220,6 +218,11 @@ void wlr_seat_pointer_clear_focus(struct wlr_seat *wlr_seat) {
|
|||
wlr_seat_pointer_enter(wlr_seat, NULL, 0, 0);
|
||||
}
|
||||
|
||||
void wlr_seat_pointer_warp(struct wlr_seat *wlr_seat, double sx, double sy) {
|
||||
wlr_seat->pointer_state.sx = sx;
|
||||
wlr_seat->pointer_state.sy = sy;
|
||||
}
|
||||
|
||||
void wlr_seat_pointer_send_motion(struct wlr_seat *wlr_seat, uint32_t time,
|
||||
double sx, double sy) {
|
||||
struct wlr_seat_client *client = wlr_seat->pointer_state.focused_client;
|
||||
|
|
@ -241,8 +244,7 @@ void wlr_seat_pointer_send_motion(struct wlr_seat *wlr_seat, uint32_t time,
|
|||
wl_fixed_from_double(sy));
|
||||
}
|
||||
|
||||
wlr_seat->pointer_state.sx = sx;
|
||||
wlr_seat->pointer_state.sy = sy;
|
||||
wlr_seat_pointer_warp(wlr_seat, sx, sy);
|
||||
}
|
||||
|
||||
uint32_t wlr_seat_pointer_send_button(struct wlr_seat *wlr_seat, uint32_t time,
|
||||
|
|
|
|||
|
|
@ -3,15 +3,19 @@
|
|||
#endif
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <wayland-util.h>
|
||||
#include <wlr/types/wlr_input_method_v2.h>
|
||||
#include <wlr/types/wlr_surface.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include "input-method-unstable-v2-protocol.h"
|
||||
#include "util/shm.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
static const struct zwp_input_method_v2_interface input_method_impl;
|
||||
static const struct zwp_input_method_keyboard_grab_v2_interface keyboard_grab_impl;
|
||||
|
||||
static struct wlr_input_method_v2 *input_method_from_resource(
|
||||
struct wl_resource *resource) {
|
||||
|
|
@ -20,10 +24,19 @@ static struct wlr_input_method_v2 *input_method_from_resource(
|
|||
return wl_resource_get_user_data(resource);
|
||||
}
|
||||
|
||||
static struct wlr_input_method_keyboard_grab_v2 *keyboard_grab_from_resource(
|
||||
struct wl_resource *resource) {
|
||||
assert(wl_resource_instance_of(resource,
|
||||
&zwp_input_method_keyboard_grab_v2_interface,
|
||||
&keyboard_grab_impl));
|
||||
return wl_resource_get_user_data(resource);
|
||||
}
|
||||
|
||||
static void input_method_destroy(struct wlr_input_method_v2 *input_method) {
|
||||
wlr_signal_emit_safe(&input_method->events.destroy, input_method);
|
||||
wl_list_remove(wl_resource_get_link(input_method->resource));
|
||||
wl_list_remove(&input_method->seat_destroy.link);
|
||||
wl_list_remove(&input_method->seat_client_destroy.link);
|
||||
wlr_input_method_keyboard_grab_v2_destroy(input_method->keyboard_grab);
|
||||
free(input_method->pending.commit_text);
|
||||
free(input_method->pending.preedit.text);
|
||||
free(input_method->current.commit_text);
|
||||
|
|
@ -101,10 +114,189 @@ static void im_get_input_popup_surface(struct wl_client *client,
|
|||
wlr_log(WLR_INFO, "Stub: zwp_input_method_v2::get_input_popup_surface");
|
||||
}
|
||||
|
||||
void wlr_input_method_keyboard_grab_v2_destroy(
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab) {
|
||||
if (!keyboard_grab) {
|
||||
return;
|
||||
}
|
||||
wlr_signal_emit_safe(&keyboard_grab->events.destroy, keyboard_grab);
|
||||
keyboard_grab->input_method->keyboard_grab = NULL;
|
||||
if (keyboard_grab->keyboard) {
|
||||
wl_list_remove(&keyboard_grab->keyboard_keymap.link);
|
||||
wl_list_remove(&keyboard_grab->keyboard_repeat_info.link);
|
||||
wl_list_remove(&keyboard_grab->keyboard_destroy.link);
|
||||
}
|
||||
wl_resource_set_user_data(keyboard_grab->resource, NULL);
|
||||
free(keyboard_grab);
|
||||
}
|
||||
|
||||
static void keyboard_grab_resource_destroy(struct wl_resource *resource) {
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab =
|
||||
keyboard_grab_from_resource(resource);
|
||||
wlr_input_method_keyboard_grab_v2_destroy(keyboard_grab);
|
||||
}
|
||||
|
||||
static void keyboard_grab_release(struct wl_client *client,
|
||||
struct wl_resource *resource) {
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
|
||||
static const struct zwp_input_method_keyboard_grab_v2_interface keyboard_grab_impl = {
|
||||
.release = keyboard_grab_release,
|
||||
};
|
||||
|
||||
void wlr_input_method_keyboard_grab_v2_send_key(
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab,
|
||||
uint32_t time, uint32_t key, uint32_t state) {
|
||||
zwp_input_method_keyboard_grab_v2_send_key(
|
||||
keyboard_grab->resource,
|
||||
wlr_seat_client_next_serial(keyboard_grab->input_method->seat_client),
|
||||
time, key, state);
|
||||
}
|
||||
|
||||
void wlr_input_method_keyboard_grab_v2_send_modifiers(
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab,
|
||||
struct wlr_keyboard_modifiers *modifiers) {
|
||||
zwp_input_method_keyboard_grab_v2_send_modifiers(
|
||||
keyboard_grab->resource,
|
||||
wlr_seat_client_next_serial(keyboard_grab->input_method->seat_client),
|
||||
modifiers->depressed, modifiers->latched,
|
||||
modifiers->locked, modifiers->group);
|
||||
}
|
||||
|
||||
static bool keyboard_grab_send_keymap(
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab,
|
||||
struct wlr_keyboard *keyboard) {
|
||||
int keymap_fd = allocate_shm_file(keyboard->keymap_size);
|
||||
if (keymap_fd < 0) {
|
||||
wlr_log(WLR_ERROR, "creating a keymap file for %zu bytes failed",
|
||||
keyboard->keymap_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
void *ptr = mmap(NULL, keyboard->keymap_size, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, keymap_fd, 0);
|
||||
if (ptr == MAP_FAILED) {
|
||||
wlr_log(WLR_ERROR, "failed to mmap() %zu bytes",
|
||||
keyboard->keymap_size);
|
||||
close(keymap_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(ptr, keyboard->keymap_string, keyboard->keymap_size);
|
||||
munmap(ptr, keyboard->keymap_size);
|
||||
|
||||
zwp_input_method_keyboard_grab_v2_send_keymap(keyboard_grab->resource,
|
||||
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymap_fd,
|
||||
keyboard->keymap_size);
|
||||
|
||||
close(keymap_fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void keyboard_grab_send_repeat_info(
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab,
|
||||
struct wlr_keyboard *keyboard) {
|
||||
zwp_input_method_keyboard_grab_v2_send_repeat_info(
|
||||
keyboard_grab->resource, keyboard->repeat_info.rate,
|
||||
keyboard->repeat_info.delay);
|
||||
}
|
||||
|
||||
static void handle_keyboard_keymap(struct wl_listener *listener, void *data) {
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab =
|
||||
wl_container_of(listener, keyboard_grab, keyboard_keymap);
|
||||
keyboard_grab_send_keymap(keyboard_grab, data);
|
||||
}
|
||||
|
||||
static void handle_keyboard_repeat_info(struct wl_listener *listener,
|
||||
void *data) {
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab =
|
||||
wl_container_of(listener, keyboard_grab, keyboard_repeat_info);
|
||||
keyboard_grab_send_repeat_info(keyboard_grab, data);
|
||||
}
|
||||
|
||||
static void handle_keyboard_destroy(struct wl_listener *listener,
|
||||
void *data) {
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab =
|
||||
wl_container_of(listener, keyboard_grab, keyboard_destroy);
|
||||
wlr_input_method_keyboard_grab_v2_set_keyboard(keyboard_grab, NULL);
|
||||
}
|
||||
|
||||
void wlr_input_method_keyboard_grab_v2_set_keyboard(
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab,
|
||||
struct wlr_keyboard *keyboard) {
|
||||
if (keyboard == keyboard_grab->keyboard) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (keyboard_grab->keyboard) {
|
||||
wl_list_remove(&keyboard_grab->keyboard_keymap.link);
|
||||
wl_list_remove(&keyboard_grab->keyboard_repeat_info.link);
|
||||
wl_list_remove(&keyboard_grab->keyboard_destroy.link);
|
||||
}
|
||||
|
||||
if (keyboard) {
|
||||
if (keyboard_grab->keyboard == NULL ||
|
||||
strcmp(keyboard_grab->keyboard->keymap_string,
|
||||
keyboard->keymap_string) != 0) {
|
||||
// send keymap only if it is changed, or if input method is not
|
||||
// aware that it did not change and blindly send it back with
|
||||
// virtual keyboard, it may cause an infinite recursion.
|
||||
if (!keyboard_grab_send_keymap(keyboard_grab, keyboard)) {
|
||||
wlr_log(WLR_ERROR, "Failed to send keymap for input-method keyboard grab");
|
||||
return;
|
||||
}
|
||||
}
|
||||
keyboard_grab_send_repeat_info(keyboard_grab, keyboard);
|
||||
keyboard_grab->keyboard_keymap.notify = handle_keyboard_keymap;
|
||||
wl_signal_add(&keyboard->events.keymap,
|
||||
&keyboard_grab->keyboard_keymap);
|
||||
keyboard_grab->keyboard_repeat_info.notify =
|
||||
handle_keyboard_repeat_info;
|
||||
wl_signal_add(&keyboard->events.repeat_info,
|
||||
&keyboard_grab->keyboard_repeat_info);
|
||||
keyboard_grab->keyboard_destroy.notify =
|
||||
handle_keyboard_destroy;
|
||||
wl_signal_add(&keyboard->events.destroy,
|
||||
&keyboard_grab->keyboard_destroy);
|
||||
}
|
||||
|
||||
keyboard_grab->keyboard = keyboard;
|
||||
};
|
||||
|
||||
static void im_grab_keyboard(struct wl_client *client,
|
||||
struct wl_resource *resource, uint32_t keyboard) {
|
||||
wlr_log(WLR_INFO, "Stub: zwp_input_method_v2::grab_keyboard");
|
||||
struct wlr_input_method_v2 *input_method =
|
||||
input_method_from_resource(resource);
|
||||
if (!input_method) {
|
||||
return;
|
||||
}
|
||||
if (input_method->keyboard_grab) {
|
||||
// Already grabbed
|
||||
return;
|
||||
}
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab =
|
||||
calloc(1, sizeof(struct wlr_input_method_keyboard_grab_v2));
|
||||
if (!keyboard_grab) {
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
struct wl_resource *keyboard_grab_resource = wl_resource_create(
|
||||
client, &zwp_input_method_keyboard_grab_v2_interface,
|
||||
wl_resource_get_version(resource), keyboard);
|
||||
if (keyboard_grab_resource == NULL) {
|
||||
free(keyboard_grab);
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
wl_resource_set_implementation(keyboard_grab_resource,
|
||||
&keyboard_grab_impl, keyboard_grab,
|
||||
keyboard_grab_resource_destroy);
|
||||
keyboard_grab->resource = keyboard_grab_resource;
|
||||
keyboard_grab->input_method = input_method;
|
||||
input_method->keyboard_grab = keyboard_grab;
|
||||
wl_signal_init(&keyboard_grab->events.destroy);
|
||||
wlr_signal_emit_safe(&input_method->events.grab_keyboard, keyboard_grab);
|
||||
}
|
||||
|
||||
static const struct zwp_input_method_v2_interface input_method_impl = {
|
||||
|
|
@ -176,10 +368,10 @@ static struct wlr_input_method_manager_v2 *input_method_manager_from_resource(
|
|||
return wl_resource_get_user_data(resource);
|
||||
}
|
||||
|
||||
static void input_method_handle_seat_destroy(struct wl_listener *listener,
|
||||
static void input_method_handle_seat_client_destroy(struct wl_listener *listener,
|
||||
void *data) {
|
||||
struct wlr_input_method_v2 *input_method = wl_container_of(listener,
|
||||
input_method, seat_destroy);
|
||||
input_method, seat_client_destroy);
|
||||
wlr_input_method_v2_send_unavailable(input_method);
|
||||
}
|
||||
|
||||
|
|
@ -196,6 +388,7 @@ static void manager_get_input_method(struct wl_client *client,
|
|||
return;
|
||||
}
|
||||
wl_signal_init(&input_method->events.commit);
|
||||
wl_signal_init(&input_method->events.grab_keyboard);
|
||||
wl_signal_init(&input_method->events.destroy);
|
||||
int version = wl_resource_get_version(resource);
|
||||
struct wl_resource *im_resource = wl_resource_create(client,
|
||||
|
|
@ -208,14 +401,14 @@ static void manager_get_input_method(struct wl_client *client,
|
|||
wl_resource_set_implementation(im_resource, &input_method_impl,
|
||||
input_method, input_method_resource_destroy);
|
||||
|
||||
struct wlr_seat_client *seat_client = wlr_seat_client_from_resource(seat);
|
||||
wl_signal_add(&seat_client->events.destroy,
|
||||
&input_method->seat_destroy);
|
||||
input_method->seat_destroy.notify =
|
||||
input_method_handle_seat_destroy;
|
||||
input_method->seat_client = wlr_seat_client_from_resource(seat);
|
||||
input_method->seat = input_method->seat_client->seat;
|
||||
wl_signal_add(&input_method->seat_client->events.destroy,
|
||||
&input_method->seat_client_destroy);
|
||||
input_method->seat_client_destroy.notify =
|
||||
input_method_handle_seat_client_destroy;
|
||||
|
||||
input_method->resource = im_resource;
|
||||
input_method->seat = seat_client->seat;
|
||||
wl_list_insert(&im_manager->input_methods,
|
||||
wl_resource_get_link(input_method->resource));
|
||||
wlr_signal_emit_safe(&im_manager->events.input_method, input_method);
|
||||
|
|
|
|||
|
|
@ -232,7 +232,6 @@ static void layer_surface_destroy(struct wlr_layer_surface_v1 *surface) {
|
|||
wl_resource_set_user_data(surface->resource, NULL);
|
||||
surface->surface->role_data = NULL;
|
||||
wl_list_remove(&surface->surface_destroy.link);
|
||||
wl_list_remove(&surface->link);
|
||||
free(surface->namespace);
|
||||
free(surface);
|
||||
}
|
||||
|
|
@ -440,7 +439,6 @@ static void layer_shell_handle_get_layer_surface(struct wl_client *wl_client,
|
|||
surface, surface->resource);
|
||||
wl_resource_set_implementation(surface->resource,
|
||||
&layer_surface_implementation, surface, layer_surface_resource_destroy);
|
||||
wl_list_insert(&shell->surfaces, &surface->link);
|
||||
}
|
||||
|
||||
static const struct zwlr_layer_shell_v1_interface layer_shell_implementation = {
|
||||
|
|
@ -479,8 +477,6 @@ struct wlr_layer_shell_v1 *wlr_layer_shell_v1_create(struct wl_display *display)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
wl_list_init(&layer_shell->surfaces);
|
||||
|
||||
struct wl_global *global = wl_global_create(display,
|
||||
&zwlr_layer_shell_v1_interface, 2, layer_shell, layer_shell_bind);
|
||||
if (!global) {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,14 @@ static struct wlr_virtual_keyboard_v1 *virtual_keyboard_from_resource(
|
|||
return wl_resource_get_user_data(resource);
|
||||
}
|
||||
|
||||
struct wlr_virtual_keyboard_v1 *wlr_input_device_get_virtual_keyboard(
|
||||
struct wlr_input_device *wlr_dev) {
|
||||
if (wlr_dev->impl != &input_device_impl) {
|
||||
return NULL;
|
||||
}
|
||||
return (struct wlr_virtual_keyboard_v1 *)wlr_dev;
|
||||
}
|
||||
|
||||
static void virtual_keyboard_keymap(struct wl_client *client,
|
||||
struct wl_resource *resource, uint32_t format, int32_t fd,
|
||||
uint32_t size) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue