mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Merge pull request #999 from dcz-purism/virtual-keyboard
Support virtual keyboard protocol
This commit is contained in:
		
						commit
						e1f56538a8
					
				
					 10 changed files with 427 additions and 0 deletions
				
			
		| 
						 | 
					@ -14,6 +14,7 @@
 | 
				
			||||||
#include <wlr/types/wlr_output.h>
 | 
					#include <wlr/types/wlr_output.h>
 | 
				
			||||||
#include <wlr/types/wlr_primary_selection.h>
 | 
					#include <wlr/types/wlr_primary_selection.h>
 | 
				
			||||||
#include <wlr/types/wlr_screenshooter.h>
 | 
					#include <wlr/types/wlr_screenshooter.h>
 | 
				
			||||||
 | 
					#include <wlr/types/wlr_virtual_keyboard_v1.h>
 | 
				
			||||||
#include <wlr/types/wlr_wl_shell.h>
 | 
					#include <wlr/types/wlr_wl_shell.h>
 | 
				
			||||||
#include <wlr/types/wlr_xcursor_manager.h>
 | 
					#include <wlr/types/wlr_xcursor_manager.h>
 | 
				
			||||||
#include <wlr/types/wlr_xdg_shell_v6.h>
 | 
					#include <wlr/types/wlr_xdg_shell_v6.h>
 | 
				
			||||||
| 
						 | 
					@ -51,6 +52,7 @@ struct roots_desktop {
 | 
				
			||||||
	struct wlr_input_inhibit_manager *input_inhibit;
 | 
						struct wlr_input_inhibit_manager *input_inhibit;
 | 
				
			||||||
	struct wlr_linux_dmabuf *linux_dmabuf;
 | 
						struct wlr_linux_dmabuf *linux_dmabuf;
 | 
				
			||||||
	struct wlr_layer_shell *layer_shell;
 | 
						struct wlr_layer_shell *layer_shell;
 | 
				
			||||||
 | 
						struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener new_output;
 | 
						struct wl_listener new_output;
 | 
				
			||||||
	struct wl_listener layout_change;
 | 
						struct wl_listener layout_change;
 | 
				
			||||||
| 
						 | 
					@ -61,6 +63,7 @@ struct roots_desktop {
 | 
				
			||||||
	struct wl_listener decoration_new;
 | 
						struct wl_listener decoration_new;
 | 
				
			||||||
	struct wl_listener input_inhibit_activate;
 | 
						struct wl_listener input_inhibit_activate;
 | 
				
			||||||
	struct wl_listener input_inhibit_deactivate;
 | 
						struct wl_listener input_inhibit_deactivate;
 | 
				
			||||||
 | 
						struct wl_listener virtual_keyboard_new;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef WLR_HAS_XWAYLAND
 | 
					#ifdef WLR_HAS_XWAYLAND
 | 
				
			||||||
	struct wlr_xwayland *xwayland;
 | 
						struct wlr_xwayland *xwayland;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										7
									
								
								include/rootston/virtual_keyboard.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								include/rootston/virtual_keyboard.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					#ifndef ROOTSTON_VIRTUAL_KEYBOARD_H
 | 
				
			||||||
 | 
					#define ROOTSTON_VIRTUAL_KEYBOARD_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <wayland-server-core.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void handle_virtual_keyboard(struct wl_listener *listener, void *data);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										37
									
								
								include/wlr/types/wlr_virtual_keyboard_v1.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								include/wlr/types/wlr_virtual_keyboard_v1.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,37 @@
 | 
				
			||||||
 | 
					#ifndef WLR_TYPES_WLR_VIRTUAL_KEYBOARD_V1_H
 | 
				
			||||||
 | 
					#define WLR_TYPES_WLR_VIRTUAL_KEYBOARD_V1_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <wayland-server.h>
 | 
				
			||||||
 | 
					#include <wlr/interfaces/wlr_input_device.h>
 | 
				
			||||||
 | 
					#include <wlr/interfaces/wlr_keyboard.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_virtual_keyboard_manager_v1 {
 | 
				
			||||||
 | 
						struct wl_global *global;
 | 
				
			||||||
 | 
						struct wl_list resources; // struct wl_resource*
 | 
				
			||||||
 | 
						struct wl_list virtual_keyboards; // struct wlr_virtual_keyboard_v1*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_listener display_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							struct wl_signal new_virtual_keyboard; // struct wlr_virtual_keyboard_v1*
 | 
				
			||||||
 | 
						} events;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_virtual_keyboard_v1 {
 | 
				
			||||||
 | 
						struct wl_resource *resource;
 | 
				
			||||||
 | 
						struct wlr_input_device input_device;
 | 
				
			||||||
 | 
						struct wlr_seat *seat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_list link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							struct wl_signal destroy; // struct wlr_virtual_keyboard_v1*
 | 
				
			||||||
 | 
						} events;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_virtual_keyboard_manager_v1* wlr_virtual_keyboard_manager_v1_create(
 | 
				
			||||||
 | 
						struct wl_display *display);
 | 
				
			||||||
 | 
					void wlr_virtual_keyboard_manager_v1_destroy(
 | 
				
			||||||
 | 
						struct wlr_virtual_keyboard_manager_v1 *manager);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,7 @@ protocols = [
 | 
				
			||||||
	'idle.xml',
 | 
						'idle.xml',
 | 
				
			||||||
	'screenshooter.xml',
 | 
						'screenshooter.xml',
 | 
				
			||||||
	'server-decoration.xml',
 | 
						'server-decoration.xml',
 | 
				
			||||||
 | 
						'virtual-keyboard-unstable-v1.xml',
 | 
				
			||||||
	'wlr-layer-shell-unstable-v1.xml',
 | 
						'wlr-layer-shell-unstable-v1.xml',
 | 
				
			||||||
	'wlr-input-inhibitor-unstable-v1.xml',
 | 
						'wlr-input-inhibitor-unstable-v1.xml',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										113
									
								
								protocol/virtual-keyboard-unstable-v1.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								protocol/virtual-keyboard-unstable-v1.xml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,113 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<protocol name="virtual_keyboard_unstable_v1">
 | 
				
			||||||
 | 
					  <copyright>
 | 
				
			||||||
 | 
					    Copyright © 2008-2011  Kristian Høgsberg
 | 
				
			||||||
 | 
					    Copyright © 2010-2013  Intel Corporation
 | 
				
			||||||
 | 
					    Copyright © 2012-2013  Collabora, Ltd.
 | 
				
			||||||
 | 
					    Copyright © 2018       Purism SPC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					    copy of this software and associated documentation files (the "Software"),
 | 
				
			||||||
 | 
					    to deal in the Software without restriction, including without limitation
 | 
				
			||||||
 | 
					    the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
				
			||||||
 | 
					    and/or sell copies of the Software, and to permit persons to whom the
 | 
				
			||||||
 | 
					    Software is furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    The above copyright notice and this permission notice (including the next
 | 
				
			||||||
 | 
					    paragraph) shall be included in all copies or substantial portions of the
 | 
				
			||||||
 | 
					    Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
				
			||||||
 | 
					    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
				
			||||||
 | 
					    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
				
			||||||
 | 
					    DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 | 
					  </copyright>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <interface name="zwp_virtual_keyboard_v1" version="1">
 | 
				
			||||||
 | 
					    <description summary="virtual keyboard">
 | 
				
			||||||
 | 
					      The virtual keyboard provides an application with requests which emulate
 | 
				
			||||||
 | 
					      the behaviour of a physical keyboard.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      This interface can be used by clients on its own to provide raw input
 | 
				
			||||||
 | 
					      events, or it can accompany the input method protocol.
 | 
				
			||||||
 | 
					    </description>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <request name="keymap">
 | 
				
			||||||
 | 
					      <description summary="keyboard mapping">
 | 
				
			||||||
 | 
					        Provide a file descriptor to the compositor which can be
 | 
				
			||||||
 | 
					        memory-mapped to provide a keyboard mapping description.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Format carries a value from the keymap_format enumeration.
 | 
				
			||||||
 | 
					      </description>
 | 
				
			||||||
 | 
					      <arg name="format" type="uint" summary="keymap format"/>
 | 
				
			||||||
 | 
					      <arg name="fd" type="fd" summary="keymap file descriptor"/>
 | 
				
			||||||
 | 
					      <arg name="size" type="uint" summary="keymap size, in bytes"/>
 | 
				
			||||||
 | 
					    </request>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <enum name="error">
 | 
				
			||||||
 | 
					      <entry name="no_keymap" value="0" summary="No keymap was set"/>
 | 
				
			||||||
 | 
					    </enum>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <request name="key">
 | 
				
			||||||
 | 
					      <description summary="key event">
 | 
				
			||||||
 | 
					        A key was pressed or released.
 | 
				
			||||||
 | 
					        The time argument is a timestamp with millisecond granularity, with an
 | 
				
			||||||
 | 
					        undefined base. All requests regarding a single object must share the
 | 
				
			||||||
 | 
					        same clock.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Keymap must be set before issuing this request.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        State carries a value from the key_state enumeration.
 | 
				
			||||||
 | 
					      </description>
 | 
				
			||||||
 | 
					      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
 | 
				
			||||||
 | 
					      <arg name="key" type="uint" summary="key that produced the event"/>
 | 
				
			||||||
 | 
					      <arg name="state" type="uint" summary="physical state of the key"/>
 | 
				
			||||||
 | 
					    </request>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <request name="modifiers">
 | 
				
			||||||
 | 
					      <description summary="modifier and group state">
 | 
				
			||||||
 | 
					        Notifies the compositor that the modifier and/or group state has
 | 
				
			||||||
 | 
					        changed, and it should update state.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        The client should use wl_keyboard.modifiers event to synchronize its
 | 
				
			||||||
 | 
					        internal state with seat state.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Keymap must be set before issuing this request.
 | 
				
			||||||
 | 
					      </description>
 | 
				
			||||||
 | 
					      <arg name="mods_depressed" type="uint" summary="depressed modifiers"/>
 | 
				
			||||||
 | 
					      <arg name="mods_latched" type="uint" summary="latched modifiers"/>
 | 
				
			||||||
 | 
					      <arg name="mods_locked" type="uint" summary="locked modifiers"/>
 | 
				
			||||||
 | 
					      <arg name="group" type="uint" summary="keyboard layout"/>
 | 
				
			||||||
 | 
					    </request>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <request name="destroy" type="destructor" since="1">
 | 
				
			||||||
 | 
					      <description summary="destroy the virtual keyboard keyboard object"/>
 | 
				
			||||||
 | 
					    </request>
 | 
				
			||||||
 | 
					  </interface>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <interface name="zwp_virtual_keyboard_manager_v1" version="1">
 | 
				
			||||||
 | 
					    <description summary="virtual keyboard manager">
 | 
				
			||||||
 | 
					      A virtual keyboard manager allows an application to provide keyboard
 | 
				
			||||||
 | 
					      input events as if they came from a physical keyboard.
 | 
				
			||||||
 | 
					    </description>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <enum name="error">
 | 
				
			||||||
 | 
					      <entry name="unauthorized" value="0" summary="client not authorized to use the interface"/>
 | 
				
			||||||
 | 
					    </enum>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <request name="create_virtual_keyboard">
 | 
				
			||||||
 | 
					      <description summary="Create a new virtual keyboard">
 | 
				
			||||||
 | 
					        Creates a new virtual keyboard associated to a seat.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If the compositor enables a keyboard to perform arbitrary actions, it
 | 
				
			||||||
 | 
					        should present an error when an untrusted client requests a new
 | 
				
			||||||
 | 
					        keyboard.
 | 
				
			||||||
 | 
					      </description>
 | 
				
			||||||
 | 
					      <arg name="seat" type="object" interface="wl_seat"/>
 | 
				
			||||||
 | 
					      <arg name="id" type="new_id" interface="zwp_virtual_keyboard_v1"/>
 | 
				
			||||||
 | 
					    </request>
 | 
				
			||||||
 | 
					  </interface>
 | 
				
			||||||
 | 
					</protocol>
 | 
				
			||||||
| 
						 | 
					@ -26,6 +26,7 @@
 | 
				
			||||||
#include "rootston/seat.h"
 | 
					#include "rootston/seat.h"
 | 
				
			||||||
#include "rootston/server.h"
 | 
					#include "rootston/server.h"
 | 
				
			||||||
#include "rootston/view.h"
 | 
					#include "rootston/view.h"
 | 
				
			||||||
 | 
					#include "rootston/virtual_keyboard.h"
 | 
				
			||||||
#include "rootston/xcursor.h"
 | 
					#include "rootston/xcursor.h"
 | 
				
			||||||
#include "wlr-layer-shell-unstable-v1-protocol.h"
 | 
					#include "wlr-layer-shell-unstable-v1-protocol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -865,6 +866,12 @@ struct roots_desktop *desktop_create(struct roots_server *server,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	desktop->linux_dmabuf = wlr_linux_dmabuf_create(server->wl_display,
 | 
						desktop->linux_dmabuf = wlr_linux_dmabuf_create(server->wl_display,
 | 
				
			||||||
		server->renderer);
 | 
							server->renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						desktop->virtual_keyboard = wlr_virtual_keyboard_manager_v1_create(
 | 
				
			||||||
 | 
							server->wl_display);
 | 
				
			||||||
 | 
						wl_signal_add(&desktop->virtual_keyboard->events.new_virtual_keyboard,
 | 
				
			||||||
 | 
							&desktop->virtual_keyboard_new);
 | 
				
			||||||
 | 
						desktop->virtual_keyboard_new.notify = handle_virtual_keyboard;
 | 
				
			||||||
	return desktop;
 | 
						return desktop;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@ sources = [
 | 
				
			||||||
	'main.c',
 | 
						'main.c',
 | 
				
			||||||
	'output.c',
 | 
						'output.c',
 | 
				
			||||||
	'seat.c',
 | 
						'seat.c',
 | 
				
			||||||
 | 
						'virtual_keyboard.c',
 | 
				
			||||||
	'wl_shell.c',
 | 
						'wl_shell.c',
 | 
				
			||||||
	'xdg_shell_v6.c',
 | 
						'xdg_shell_v6.c',
 | 
				
			||||||
	'xdg_shell.c',
 | 
						'xdg_shell.c',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										21
									
								
								rootston/virtual_keyboard.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								rootston/virtual_keyboard.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					#define _POSIX_C_SOURCE 199309L
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <wlr/util/log.h>
 | 
				
			||||||
 | 
					#include <wlr/types/wlr_virtual_keyboard_v1.h>
 | 
				
			||||||
 | 
					#include "rootston/virtual_keyboard.h"
 | 
				
			||||||
 | 
					#include "rootston/seat.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void handle_virtual_keyboard(struct wl_listener *listener, void *data) {
 | 
				
			||||||
 | 
						struct roots_desktop *desktop =
 | 
				
			||||||
 | 
							wl_container_of(listener, desktop, virtual_keyboard_new);
 | 
				
			||||||
 | 
						struct wlr_virtual_keyboard_v1 *keyboard = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct roots_seat *seat = input_seat_from_wlr_seat(desktop->server->input,
 | 
				
			||||||
 | 
							keyboard->seat);
 | 
				
			||||||
 | 
						if (!seat) {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "could not find roots seat");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						roots_seat_add_device(seat, &keyboard->input_device);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,7 @@ lib_wlr_types = static_library(
 | 
				
			||||||
		'wlr_tablet_pad.c',
 | 
							'wlr_tablet_pad.c',
 | 
				
			||||||
		'wlr_tablet_tool.c',
 | 
							'wlr_tablet_tool.c',
 | 
				
			||||||
		'wlr_touch.c',
 | 
							'wlr_touch.c',
 | 
				
			||||||
 | 
							'wlr_virtual_keyboard_v1.c',
 | 
				
			||||||
		'wlr_wl_shell.c',
 | 
							'wlr_wl_shell.c',
 | 
				
			||||||
		'wlr_xcursor_manager.c',
 | 
							'wlr_xcursor_manager.c',
 | 
				
			||||||
		'wlr_xdg_output.c',
 | 
							'wlr_xdg_output.c',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										236
									
								
								types/wlr_virtual_keyboard_v1.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								types/wlr_virtual_keyboard_v1.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,236 @@
 | 
				
			||||||
 | 
					#define _POSIX_C_SOURCE 1
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <sys/mman.h>
 | 
				
			||||||
 | 
					#include <wlr/types/wlr_seat.h>
 | 
				
			||||||
 | 
					#include <wlr/types/wlr_virtual_keyboard_v1.h>
 | 
				
			||||||
 | 
					#include <wlr/util/log.h>
 | 
				
			||||||
 | 
					#include <xkbcommon/xkbcommon.h>
 | 
				
			||||||
 | 
					#include "util/signal.h"
 | 
				
			||||||
 | 
					#include "virtual-keyboard-unstable-v1-protocol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void keyboard_led_update(struct wlr_keyboard *wlr_kb, uint32_t leds) {
 | 
				
			||||||
 | 
						// unsupported by virtual keyboard protocol
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void keyboard_destroy(struct wlr_keyboard *wlr_kb) {
 | 
				
			||||||
 | 
						// safe to ignore - keyboard will be destroyed only iff associated virtual
 | 
				
			||||||
 | 
						// keyboard is torn down, no need to tear down the keyboard separately
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct wlr_keyboard_impl keyboard_impl = {
 | 
				
			||||||
 | 
						.destroy = keyboard_destroy,
 | 
				
			||||||
 | 
						.led_update = keyboard_led_update
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void input_device_destroy(struct wlr_input_device *dev) {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct wlr_input_device_impl input_device_impl = {
 | 
				
			||||||
 | 
						.destroy = input_device_destroy
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct zwp_virtual_keyboard_v1_interface virtual_keyboard_impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct wlr_virtual_keyboard_v1 *virtual_keyboard_from_resource(
 | 
				
			||||||
 | 
							struct wl_resource *resource) {
 | 
				
			||||||
 | 
						assert(wl_resource_instance_of(resource,
 | 
				
			||||||
 | 
						   &zwp_virtual_keyboard_v1_interface, &virtual_keyboard_impl));
 | 
				
			||||||
 | 
						return wl_resource_get_user_data(resource);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void virtual_keyboard_keymap(struct wl_client *client,
 | 
				
			||||||
 | 
							struct wl_resource *resource, uint32_t format, int32_t fd,
 | 
				
			||||||
 | 
							uint32_t size) {
 | 
				
			||||||
 | 
						struct wlr_virtual_keyboard_v1 *keyboard =
 | 
				
			||||||
 | 
							virtual_keyboard_from_resource(resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
 | 
				
			||||||
 | 
						if (!context) {
 | 
				
			||||||
 | 
							goto context_fail;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						void *data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
 | 
				
			||||||
 | 
						if (!data) {
 | 
				
			||||||
 | 
							goto fd_fail;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, data,
 | 
				
			||||||
 | 
							XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
 | 
				
			||||||
 | 
						munmap(data, size);
 | 
				
			||||||
 | 
						if (!keymap) {
 | 
				
			||||||
 | 
							goto keymap_fail;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						wlr_keyboard_set_keymap(keyboard->input_device.keyboard, keymap);
 | 
				
			||||||
 | 
						xkb_keymap_unref(keymap);
 | 
				
			||||||
 | 
						xkb_context_unref(context);
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					keymap_fail:
 | 
				
			||||||
 | 
					fd_fail:
 | 
				
			||||||
 | 
						xkb_context_unref(context);
 | 
				
			||||||
 | 
					context_fail:
 | 
				
			||||||
 | 
						wl_client_post_no_memory(client);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void virtual_keyboard_key(struct wl_client *client,
 | 
				
			||||||
 | 
							struct wl_resource *resource, uint32_t time, uint32_t key,
 | 
				
			||||||
 | 
							uint32_t state) {
 | 
				
			||||||
 | 
						struct wlr_virtual_keyboard_v1 *keyboard =
 | 
				
			||||||
 | 
							virtual_keyboard_from_resource(resource);
 | 
				
			||||||
 | 
						struct wlr_event_keyboard_key event = {
 | 
				
			||||||
 | 
							.time_msec = time,
 | 
				
			||||||
 | 
							.keycode = key,
 | 
				
			||||||
 | 
							.update_state = false,
 | 
				
			||||||
 | 
							.state = state,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						wlr_keyboard_notify_key(keyboard->input_device.keyboard, &event);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void virtual_keyboard_modifiers(struct wl_client *client,
 | 
				
			||||||
 | 
							struct wl_resource *resource, uint32_t mods_depressed,
 | 
				
			||||||
 | 
							uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {
 | 
				
			||||||
 | 
						struct wlr_virtual_keyboard_v1 *keyboard =
 | 
				
			||||||
 | 
							virtual_keyboard_from_resource(resource);
 | 
				
			||||||
 | 
						wlr_keyboard_notify_modifiers(keyboard->input_device.keyboard,
 | 
				
			||||||
 | 
							mods_depressed, mods_latched, mods_locked, group);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void virtual_keyboard_destroy_resource(struct wl_resource *resource) {
 | 
				
			||||||
 | 
						struct wlr_virtual_keyboard_v1 *keyboard =
 | 
				
			||||||
 | 
							virtual_keyboard_from_resource(resource);
 | 
				
			||||||
 | 
						wlr_signal_emit_safe(&keyboard->events.destroy, keyboard);
 | 
				
			||||||
 | 
						wl_list_remove(&keyboard->link);
 | 
				
			||||||
 | 
						wlr_keyboard_destroy(keyboard->input_device.keyboard);
 | 
				
			||||||
 | 
						free(keyboard);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void virtual_keyboard_destroy(struct wl_client *client,
 | 
				
			||||||
 | 
							struct wl_resource *resource) {
 | 
				
			||||||
 | 
						wl_resource_destroy(resource);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct zwp_virtual_keyboard_v1_interface virtual_keyboard_impl = {
 | 
				
			||||||
 | 
						.keymap = virtual_keyboard_keymap,
 | 
				
			||||||
 | 
						.key = virtual_keyboard_key,
 | 
				
			||||||
 | 
						.modifiers = virtual_keyboard_modifiers,
 | 
				
			||||||
 | 
						.destroy = virtual_keyboard_destroy,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct zwp_virtual_keyboard_manager_v1_interface manager_impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct wlr_virtual_keyboard_manager_v1 *manager_from_resource(
 | 
				
			||||||
 | 
							struct wl_resource *resource) {
 | 
				
			||||||
 | 
						assert(wl_resource_instance_of(resource,
 | 
				
			||||||
 | 
							&zwp_virtual_keyboard_manager_v1_interface, &manager_impl));
 | 
				
			||||||
 | 
						return wl_resource_get_user_data(resource);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void virtual_keyboard_manager_create_virtual_keyboard(
 | 
				
			||||||
 | 
							struct wl_client *client, struct wl_resource *resource,
 | 
				
			||||||
 | 
							struct wl_resource *seat, uint32_t id) {
 | 
				
			||||||
 | 
						struct wlr_virtual_keyboard_manager_v1 *manager =
 | 
				
			||||||
 | 
							manager_from_resource(resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_virtual_keyboard_v1 *virtual_keyboard = calloc(1,
 | 
				
			||||||
 | 
							sizeof(struct wlr_virtual_keyboard_v1));
 | 
				
			||||||
 | 
						if (!virtual_keyboard) {
 | 
				
			||||||
 | 
							wl_client_post_no_memory(client);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_keyboard* keyboard = calloc(1, sizeof(struct wlr_keyboard));
 | 
				
			||||||
 | 
						if (!keyboard) {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "Cannot allocate wlr_keyboard");
 | 
				
			||||||
 | 
							free(virtual_keyboard);
 | 
				
			||||||
 | 
							wl_client_post_no_memory(client);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						wlr_keyboard_init(keyboard, &keyboard_impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_resource *keyboard_resource = wl_resource_create(client,
 | 
				
			||||||
 | 
							&zwp_virtual_keyboard_v1_interface, wl_resource_get_version(resource),
 | 
				
			||||||
 | 
							id);
 | 
				
			||||||
 | 
						if (!keyboard_resource) {
 | 
				
			||||||
 | 
							free(keyboard);
 | 
				
			||||||
 | 
							free(virtual_keyboard);
 | 
				
			||||||
 | 
							wl_client_post_no_memory(client);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_resource_set_implementation(keyboard_resource, &virtual_keyboard_impl,
 | 
				
			||||||
 | 
							virtual_keyboard, virtual_keyboard_destroy_resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_input_device_init(&virtual_keyboard->input_device,
 | 
				
			||||||
 | 
							WLR_INPUT_DEVICE_KEYBOARD, &input_device_impl, "virtual keyboard",
 | 
				
			||||||
 | 
							0x0, 0x0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_seat_client *seat_client = wlr_seat_client_from_resource(seat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						virtual_keyboard->input_device.keyboard = keyboard;
 | 
				
			||||||
 | 
						virtual_keyboard->resource = keyboard_resource;
 | 
				
			||||||
 | 
						virtual_keyboard->seat = seat_client->seat;
 | 
				
			||||||
 | 
						wl_signal_init(&virtual_keyboard->events.destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_list_insert(&manager->virtual_keyboards, &virtual_keyboard->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_signal_emit_safe(&manager->events.new_virtual_keyboard,
 | 
				
			||||||
 | 
							virtual_keyboard);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct zwp_virtual_keyboard_manager_v1_interface manager_impl = {
 | 
				
			||||||
 | 
						.create_virtual_keyboard = virtual_keyboard_manager_create_virtual_keyboard,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_manager_unbind(struct wl_resource *resource) {
 | 
				
			||||||
 | 
						wl_list_remove(wl_resource_get_link(resource));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void virtual_keyboard_manager_bind(struct wl_client *client, void *data,
 | 
				
			||||||
 | 
							uint32_t version, uint32_t id) {
 | 
				
			||||||
 | 
						struct wlr_virtual_keyboard_manager_v1 *manager = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_resource *resource = wl_resource_create(client,
 | 
				
			||||||
 | 
							&zwp_virtual_keyboard_manager_v1_interface, version, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!resource) {
 | 
				
			||||||
 | 
							wl_client_post_no_memory(client);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_resource_set_implementation(resource, &manager_impl, manager,
 | 
				
			||||||
 | 
							handle_manager_unbind);
 | 
				
			||||||
 | 
						wl_list_insert(&manager->resources, wl_resource_get_link(resource));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_display_destroy(struct wl_listener *listener, void *data) {
 | 
				
			||||||
 | 
						struct wlr_virtual_keyboard_manager_v1 *manager =
 | 
				
			||||||
 | 
							wl_container_of(listener, manager, display_destroy);
 | 
				
			||||||
 | 
						wlr_virtual_keyboard_manager_v1_destroy(manager);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_virtual_keyboard_manager_v1*
 | 
				
			||||||
 | 
							wlr_virtual_keyboard_manager_v1_create(
 | 
				
			||||||
 | 
							struct wl_display *display) {
 | 
				
			||||||
 | 
						struct wlr_virtual_keyboard_manager_v1 *manager = calloc(1,
 | 
				
			||||||
 | 
							sizeof(struct wlr_virtual_keyboard_manager_v1));
 | 
				
			||||||
 | 
						if (!manager) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						manager->display_destroy.notify = handle_display_destroy;
 | 
				
			||||||
 | 
						wl_display_add_destroy_listener(display, &manager->display_destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_list_init(&manager->resources);
 | 
				
			||||||
 | 
						wl_list_init(&manager->virtual_keyboards);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_init(&manager->events.new_virtual_keyboard);
 | 
				
			||||||
 | 
						manager->global = wl_global_create(display,
 | 
				
			||||||
 | 
							&zwp_virtual_keyboard_manager_v1_interface, 1, manager,
 | 
				
			||||||
 | 
							virtual_keyboard_manager_bind);
 | 
				
			||||||
 | 
						return manager;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_virtual_keyboard_manager_v1_destroy(
 | 
				
			||||||
 | 
							struct wlr_virtual_keyboard_manager_v1 *manager) {
 | 
				
			||||||
 | 
						wl_global_destroy(manager->global);
 | 
				
			||||||
 | 
						free(manager);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue