mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-11 08:21:34 -04: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;
|
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;
|
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,
|
bool drm_surface_make_current(struct wlr_drm_surface *surf,
|
||||||
int *buffer_damage) {
|
int *buffer_age) {
|
||||||
return wlr_egl_make_current(&surf->renderer->egl, surf->egl, buffer_damage);
|
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) {
|
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,
|
'dep': wlroots,
|
||||||
'proto': ['wlr-virtual-pointer-unstable-v1'],
|
'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
|
foreach name, info : compositors
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ struct wlr_input_method_v2 {
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
|
|
||||||
struct wlr_seat *seat;
|
struct wlr_seat *seat;
|
||||||
|
struct wlr_seat_client *seat_client;
|
||||||
|
|
||||||
struct wlr_input_method_v2_state pending;
|
struct wlr_input_method_v2_state pending;
|
||||||
struct wlr_input_method_v2_state current;
|
struct wlr_input_method_v2_state current;
|
||||||
|
|
@ -41,16 +42,33 @@ struct wlr_input_method_v2 {
|
||||||
bool client_active; // state known to the client
|
bool client_active; // state known to the client
|
||||||
uint32_t current_serial; // received in last commit call
|
uint32_t current_serial; // received in last commit call
|
||||||
|
|
||||||
|
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab;
|
||||||
|
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
|
||||||
struct wl_listener seat_destroy;
|
struct wl_listener seat_client_destroy;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal commit; // (struct wlr_input_method_v2*)
|
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*)
|
struct wl_signal destroy; // (struct wlr_input_method_v2*)
|
||||||
} events;
|
} 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 wlr_input_method_manager_v2 {
|
||||||
struct wl_global *global;
|
struct wl_global *global;
|
||||||
struct wl_list input_methods; // struct wlr_input_method_v2*::link
|
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(
|
void wlr_input_method_v2_send_unavailable(
|
||||||
struct wlr_input_method_v2 *input_method);
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@
|
||||||
*/
|
*/
|
||||||
struct wlr_layer_shell_v1 {
|
struct wlr_layer_shell_v1 {
|
||||||
struct wl_global *global;
|
struct wl_global *global;
|
||||||
struct wl_list surfaces; // wl_layer_surface
|
|
||||||
|
|
||||||
struct wl_listener display_destroy;
|
struct wl_listener display_destroy;
|
||||||
|
|
||||||
|
|
@ -63,7 +62,6 @@ struct wlr_layer_surface_v1_configure {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_layer_surface_v1 {
|
struct wlr_layer_surface_v1 {
|
||||||
struct wl_list link; // wlr_layer_shell_v1::surfaces
|
|
||||||
struct wlr_surface *surface;
|
struct wlr_surface *surface;
|
||||||
struct wlr_output *output;
|
struct wlr_output *output;
|
||||||
struct wl_resource *resource;
|
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);
|
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
|
* Notify the seat of motion over the given surface. Pass surface-local
|
||||||
* coordinates where the pointer motion occurred. Defers to any grab of the
|
* 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 wlr_virtual_keyboard_v1 {
|
||||||
struct wl_resource *resource;
|
|
||||||
struct wlr_input_device input_device;
|
struct wlr_input_device input_device;
|
||||||
|
struct wl_resource *resource;
|
||||||
struct wlr_seat *seat;
|
struct wlr_seat *seat;
|
||||||
bool has_keymap;
|
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 wlr_virtual_keyboard_manager_v1* wlr_virtual_keyboard_manager_v1_create(
|
||||||
struct wl_display *display);
|
struct wl_display *display);
|
||||||
|
|
||||||
|
struct wlr_virtual_keyboard_v1 *wlr_input_device_get_virtual_keyboard(
|
||||||
|
struct wlr_input_device *wlr_dev);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
project(
|
project(
|
||||||
'wlroots',
|
'wlroots',
|
||||||
'c',
|
'c',
|
||||||
version: '0.10.0',
|
version: '0.11.0',
|
||||||
license: 'MIT',
|
license: 'MIT',
|
||||||
meson_version: '>=0.54.0',
|
meson_version: '>=0.54.0',
|
||||||
default_options: [
|
default_options: [
|
||||||
|
|
@ -15,7 +15,7 @@ project(
|
||||||
# necessary for bugfix releases. Increasing soversion is required because
|
# necessary for bugfix releases. Increasing soversion is required because
|
||||||
# wlroots never guarantees ABI stability -- only API stability is guaranteed
|
# wlroots never guarantees ABI stability -- only API stability is guaranteed
|
||||||
# between minor releases.
|
# between minor releases.
|
||||||
soversion = 5
|
soversion = 6
|
||||||
|
|
||||||
add_project_arguments([
|
add_project_arguments([
|
||||||
'-DWLR_USE_UNSTABLE',
|
'-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) {
|
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);
|
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_client = client;
|
||||||
wlr_seat->pointer_state.focused_surface = surface;
|
wlr_seat->pointer_state.focused_surface = surface;
|
||||||
if (surface != NULL) {
|
if (surface != NULL) {
|
||||||
wlr_seat->pointer_state.sx = sx;
|
wlr_seat_pointer_warp(wlr_seat, sx, sy);
|
||||||
wlr_seat->pointer_state.sy = sy;
|
|
||||||
} else {
|
} else {
|
||||||
wlr_seat->pointer_state.sx = NAN;
|
wlr_seat_pointer_warp(wlr_seat, NAN, NAN);
|
||||||
wlr_seat->pointer_state.sy = NAN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_seat_pointer_focus_change_event event = {
|
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);
|
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,
|
void wlr_seat_pointer_send_motion(struct wlr_seat *wlr_seat, uint32_t time,
|
||||||
double sx, double sy) {
|
double sx, double sy) {
|
||||||
struct wlr_seat_client *client = wlr_seat->pointer_state.focused_client;
|
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));
|
wl_fixed_from_double(sy));
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_seat->pointer_state.sx = sx;
|
wlr_seat_pointer_warp(wlr_seat, sx, sy);
|
||||||
wlr_seat->pointer_state.sy = sy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t wlr_seat_pointer_send_button(struct wlr_seat *wlr_seat, uint32_t time,
|
uint32_t wlr_seat_pointer_send_button(struct wlr_seat *wlr_seat, uint32_t time,
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,19 @@
|
||||||
#endif
|
#endif
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <wayland-util.h>
|
#include <wayland-util.h>
|
||||||
#include <wlr/types/wlr_input_method_v2.h>
|
#include <wlr/types/wlr_input_method_v2.h>
|
||||||
#include <wlr/types/wlr_surface.h>
|
#include <wlr/types/wlr_surface.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#include "input-method-unstable-v2-protocol.h"
|
#include "input-method-unstable-v2-protocol.h"
|
||||||
|
#include "util/shm.h"
|
||||||
#include "util/signal.h"
|
#include "util/signal.h"
|
||||||
|
|
||||||
static const struct zwp_input_method_v2_interface input_method_impl;
|
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(
|
static struct wlr_input_method_v2 *input_method_from_resource(
|
||||||
struct wl_resource *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);
|
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) {
|
static void input_method_destroy(struct wlr_input_method_v2 *input_method) {
|
||||||
wlr_signal_emit_safe(&input_method->events.destroy, 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(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.commit_text);
|
||||||
free(input_method->pending.preedit.text);
|
free(input_method->pending.preedit.text);
|
||||||
free(input_method->current.commit_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");
|
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,
|
static void im_grab_keyboard(struct wl_client *client,
|
||||||
struct wl_resource *resource, uint32_t keyboard) {
|
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 = {
|
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);
|
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) {
|
void *data) {
|
||||||
struct wlr_input_method_v2 *input_method = wl_container_of(listener,
|
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);
|
wlr_input_method_v2_send_unavailable(input_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,6 +388,7 @@ static void manager_get_input_method(struct wl_client *client,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wl_signal_init(&input_method->events.commit);
|
wl_signal_init(&input_method->events.commit);
|
||||||
|
wl_signal_init(&input_method->events.grab_keyboard);
|
||||||
wl_signal_init(&input_method->events.destroy);
|
wl_signal_init(&input_method->events.destroy);
|
||||||
int version = wl_resource_get_version(resource);
|
int version = wl_resource_get_version(resource);
|
||||||
struct wl_resource *im_resource = wl_resource_create(client,
|
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,
|
wl_resource_set_implementation(im_resource, &input_method_impl,
|
||||||
input_method, input_method_resource_destroy);
|
input_method, input_method_resource_destroy);
|
||||||
|
|
||||||
struct wlr_seat_client *seat_client = wlr_seat_client_from_resource(seat);
|
input_method->seat_client = wlr_seat_client_from_resource(seat);
|
||||||
wl_signal_add(&seat_client->events.destroy,
|
input_method->seat = input_method->seat_client->seat;
|
||||||
&input_method->seat_destroy);
|
wl_signal_add(&input_method->seat_client->events.destroy,
|
||||||
input_method->seat_destroy.notify =
|
&input_method->seat_client_destroy);
|
||||||
input_method_handle_seat_destroy;
|
input_method->seat_client_destroy.notify =
|
||||||
|
input_method_handle_seat_client_destroy;
|
||||||
|
|
||||||
input_method->resource = im_resource;
|
input_method->resource = im_resource;
|
||||||
input_method->seat = seat_client->seat;
|
|
||||||
wl_list_insert(&im_manager->input_methods,
|
wl_list_insert(&im_manager->input_methods,
|
||||||
wl_resource_get_link(input_method->resource));
|
wl_resource_get_link(input_method->resource));
|
||||||
wlr_signal_emit_safe(&im_manager->events.input_method, input_method);
|
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);
|
wl_resource_set_user_data(surface->resource, NULL);
|
||||||
surface->surface->role_data = NULL;
|
surface->surface->role_data = NULL;
|
||||||
wl_list_remove(&surface->surface_destroy.link);
|
wl_list_remove(&surface->surface_destroy.link);
|
||||||
wl_list_remove(&surface->link);
|
|
||||||
free(surface->namespace);
|
free(surface->namespace);
|
||||||
free(surface);
|
free(surface);
|
||||||
}
|
}
|
||||||
|
|
@ -440,7 +439,6 @@ static void layer_shell_handle_get_layer_surface(struct wl_client *wl_client,
|
||||||
surface, surface->resource);
|
surface, surface->resource);
|
||||||
wl_resource_set_implementation(surface->resource,
|
wl_resource_set_implementation(surface->resource,
|
||||||
&layer_surface_implementation, surface, layer_surface_resource_destroy);
|
&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 = {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_list_init(&layer_shell->surfaces);
|
|
||||||
|
|
||||||
struct wl_global *global = wl_global_create(display,
|
struct wl_global *global = wl_global_create(display,
|
||||||
&zwlr_layer_shell_v1_interface, 2, layer_shell, layer_shell_bind);
|
&zwlr_layer_shell_v1_interface, 2, layer_shell, layer_shell_bind);
|
||||||
if (!global) {
|
if (!global) {
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,14 @@ static struct wlr_virtual_keyboard_v1 *virtual_keyboard_from_resource(
|
||||||
return wl_resource_get_user_data(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,
|
static void virtual_keyboard_keymap(struct wl_client *client,
|
||||||
struct wl_resource *resource, uint32_t format, int32_t fd,
|
struct wl_resource *resource, uint32_t format, int32_t fd,
|
||||||
uint32_t size) {
|
uint32_t size) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue