Commit 64d31b0b authored by Dorota Czaplejewicz's avatar Dorota Czaplejewicz
Browse files

dbus: Listen to visibility requests

Added object: /sm/puri/OSK0 sm.puri.OSK0
with the requests SetVisible(bool) -> (), GetVisible() -> (bool),
and a notifying property Visible:bool
parent b9d9b602
Pipeline #1429 passed with stage
in 1 minute and 5 seconds
variables:
DEPS: debhelper meson pkg-config libglib2.0-dev libpixman-1-dev libpng-dev libxcb1-dev
libxcb-xkb-dev libxkbcommon-dev libcairo2-dev libwayland-dev
DEPS: debhelper meson pkg-config
libglib2.0-dev libpixman-1-dev libpng-dev libxcb1-dev
libxcb-xkb-dev libxkbcommon-dev libcairo2-dev libsystemd-dev libwayland-dev
wayland-protocols
before_script:
......
......@@ -63,3 +63,26 @@ Remember the quoted display identifier (here it's `wayland-1`) and run virtboard
WAYLAND_DISPLAY="$DISPLAY_IDENTIFIER" $BUILD/virtboard
```
Dbus interface
--------------
The keyboard will normally show and hide when the application supports input methods, but it's possible to hide and show it using Dbus. It supports 2 methods and 1 property.
To call the methods:
```
busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true
busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 GetVisible
```
To check the property:
```
busctl --user get-property sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 Visible
```
To listen to property changes:
```
busctl --user monitor --match path=/sm/puri/OSK0
```
......@@ -40,6 +40,7 @@
#include <linux/input.h>
#include <cairo.h>
#include <systemd/sd-bus.h>
#include "keymap.h"
#include "window.h"
......@@ -309,7 +310,14 @@ struct size {
double height;
};
static const char* dbus_bus_name = "sm.puri.OSK0";
static const char* dbus_path_name = "/sm/puri/OSK0";
static const char* dbus_interface_name = "sm.puri.OSK0";
static GDBusProxy *_proxy;
static struct sd_bus *bus = NULL;
static bool dbus_visible = false;
struct task *tsk = NULL;
static void __attribute__ ((format (printf, 1, 2)))
dbg(const char *fmt, ...)
......@@ -326,6 +334,19 @@ dbg(const char *fmt, ...)
#endif
}
void
update_visible(bool visible)
{
if (dbus_visible == visible) {
return;
}
dbus_visible = visible;
int ret = sd_bus_emit_properties_changed(bus, dbus_path_name, dbus_interface_name, "Visible", NULL);
if (ret < 0) {
fprintf(stderr, "Failed to notify of changed properties");
}
}
static const char *
label_from_key(struct keyboard *keyboard,
const struct key *key)
......@@ -390,8 +411,11 @@ get_current_layout(struct virtual_keyboard *keyboard)
{
if (!keyboard->current.active ^ keyboard->forced_toggle
&& keyboard->buttons_held == 0) {
update_visible(false);
return &hidden_layout;
}
update_visible(true);
switch (keyboard->current.content_purpose) {
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DIGITS:
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER:
......@@ -1155,6 +1179,91 @@ void session_register() {
}
}
static void
bus_handle(struct task *tsk, uint32_t events)
{
int ret;
while (true) {
ret = sd_bus_process(bus, NULL);
if (ret == 0) {
break;
}
if (ret < 0) {
fprintf(stderr, "Couldnt process dbus event\n");
return;
}
}
}
static int
set_visible(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
{
struct virtual_keyboard *keyboard = userdata;
bool value;
int ret = sd_bus_message_read(m, "b", &value);
if (ret < 0) {
fprintf(stderr, "Failed to read dbus argument\n");
return ret;
}
dbg("Received set message from dbus: %d\n", value);
if ((get_current_layout(keyboard) != &hidden_layout) ^ value) {
keyboard->forced_toggle ^= true;
}
struct size size = keyboard_get_size(keyboard->keyboard); // triggers visiblility recalculation
window_schedule_resize(keyboard->keyboard->window, size.width, size.height);
widget_schedule_redraw(keyboard->keyboard->widget);
return sd_bus_reply_method_return(m, NULL);
}
static int
get_visible(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
return sd_bus_reply_method_return(m, "b", dbus_visible);
}
static int
get_visible_p(struct sd_bus *bus, const char *path, const char *interface, const char *property,
struct sd_bus_message *reply, void *userdata, sd_bus_error *error) {
return sd_bus_message_append(reply, "b", dbus_visible);
}
static struct sd_bus_vtable dbus_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_METHOD("SetVisible", "b", NULL, set_visible, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetVisible", NULL, "b", get_visible, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_PROPERTY("Visible", "b", get_visible_p, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_VTABLE_END,
};
static int
popup_setup(struct display *display, struct virtual_keyboard *virtual_keyboard)
{
int ret = sd_bus_default_user(&bus);
if (ret < 0) {
fprintf(stderr, "Failed to connect to bus\n");
return ret;
}
struct sd_bus_slot *slot;
ret = sd_bus_add_object_vtable(bus, &slot,
dbus_path_name, dbus_interface_name,
dbus_vtable,
virtual_keyboard);
if (ret < 0) {
fprintf(stderr, "Failed to create dbus object\n");
return ret;
}
ret = sd_bus_request_name(bus, dbus_bus_name, 0);
if (ret < 0) {
fprintf(stderr, "Failed to claim bus name\n");
return ret;
}
tsk = calloc(1, sizeof(struct task));
tsk->run = bus_handle;
display_watch_fd(display, sd_bus_get_fd(bus), EPOLLIN, tsk);
return 0;
}
int
main(int argc, char *argv[])
{
......@@ -1192,7 +1301,7 @@ main(int argc, char *argv[])
handle_output_changed);
if (virtual_keyboard.input_method_manager == NULL) {
fprintf(stderr, "No input method manager global,some functionality"
fprintf(stderr, "No input method manager global, some functionality"
" unavailable\n");
} else {
make_input_method(&virtual_keyboard);
......@@ -1200,9 +1309,15 @@ main(int argc, char *argv[])
make_virtual_keyboard(&virtual_keyboard);
keyboard_create(&virtual_keyboard);
if (popup_setup(virtual_keyboard.display, &virtual_keyboard) != 0) {
fprintf(stderr, "Could not register dbus service\n");
return -1;
}
session_register();
display_run(virtual_keyboard.display);
free(tsk);
return 0;
}
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<interface name="sm.puri.OSK0">
<method name="SetVisible">
<arg name="visible" type="b" direction="in"/>
<doc:doc><doc:description>
Switch keyboard visibility
</doc:description></doc:doc>
</method>
<method name="GetVisible">
<arg name="visible" type="b" direction="out"/>
<doc:doc><doc:description>
Get keyboard visibility
</doc:description></doc:doc>
</method>
<property name="Visible" type="b" access="read">
</property>
</interface>
</node>
......@@ -18,3 +18,7 @@ foreach desktop_file : desktop_files
type: 'desktop'
)
endforeach
install_data('dbus/sm.puri.Virtboard.xml',
install_dir: dbusdir
)
virtboard (0.0.3) unstable; urgency=medium
* Added dbus protocol
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Fri, 05 Oct 2018 18:56:17 +0000
virtboard (0.0.2) unstable; urgency=medium
* Added text-input protocol
......
......@@ -9,6 +9,7 @@ Build-Depends:
libglib2.0-dev,
libpixman-1-dev (>= 0.25.2),
libpng-dev,
libsystemd-dev,
libxcb1-dev,
libxcb-xkb-dev,
libxkbcommon-dev (>= 0.3.0),
......
project(
'virtboard',
'c',
version: '0.0.2',
version: '0.0.3',
license: 'MIT',
meson_version: '>=0.43.0',
)
......@@ -21,6 +21,7 @@ math = cc.find_library('m', required: false)
pixman = dependency('pixman-1')
png = dependency('libpng')
gio = dependency('gio-2.0')
systemd = dependency('libsystemd')
wl_protocol_dir = wayland_protos.get_pkgconfig_variable('pkgdatadir')
......@@ -86,13 +87,16 @@ add_global_arguments('-DLIBEXECDIR=""', language : 'c')
add_global_arguments('-DDATADIR=""', language : 'c')
executable(
'virtboard', sources, dependencies: [png, math, pixman, wayland_cursor, wayland_client, wayland_protos, xkbcommon, cairo, gio], install: true,
'virtboard', sources,
dependencies: [png, math, pixman, wayland_cursor, wayland_client, wayland_protos, xkbcommon, cairo, gio, systemd],
install: true,
)
prefix = get_option('prefix')
bindir = join_paths(prefix, get_option('bindir'))
datadir = join_paths(prefix, get_option('datadir'))
desktopdir = join_paths(datadir, 'applications')
dbusdir = join_paths(datadir, 'dbus-1/interfaces')
i18n = import('i18n')
subdir('data')
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment