diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | RemoteControlManager.xml | 7 | ||||
-rw-r--r-- | linux-input-enum.h | 2 | ||||
-rw-r--r-- | linux-input-keycodes.h | 9 | ||||
-rw-r--r-- | rcm-client-main.c | 29 | ||||
-rw-r--r-- | rcm-client-receive.c | 29 | ||||
-rw-r--r-- | rcm-client-receive.h | 1 | ||||
-rw-r--r-- | rcm-server-main.c | 47 | ||||
-rwxr-xr-x | tools/generate-input-keycodes.sh | 2 |
9 files changed, 118 insertions, 14 deletions
@@ -12,13 +12,15 @@ EXTRA_CFLAGS = GENERIC_LDFLAGS = EXTRA_LDFLAGS = +COMMON_HEADERS = linux-input-keycodes.h linux-input-enum.h + RCM_PACKAGES = libudev libsystemd RCM_CFLAGS = ${GENERIC_CFLAGS} ${EXTRA_CFLAGS} $(shell pkg-config --cflags ${RCM_PACKAGES}) RCM_LDFLAGS = ${GENERIC_LDFLAGS} ${EXTRA_LDFLAGS} $(shell pkg-config --libs ${RCM_PACKAGES}) RCM_COMPILE = $(CC) $(RCM_CFLAGS) RCM_LINK = $(CC) $(RCM_CFLAGS) $(RCM_LDFLAGS) RCM_OBJECTS = rcm-server-main.o rcm-server-keymap.o -RCM_HEADERS = rcm-server-main.h rcm-server-keymap.h utils.h +RCM_HEADERS = rcm-server-main.h rcm-server-keymap.h utils.h $(COMMON_HEADERS) RCC_PACKAGES = gtk+-3.0 RCC_CFLAGS = ${GENERIC_CFLAGS} ${EXTRA_CFLAGS} $(shell pkg-config --cflags ${RCC_PACKAGES}) @@ -26,7 +28,7 @@ RCC_LDFLAGS = ${GENERIC_LDFLAGS} ${EXTRA_LDFLAGS} $(shell pkg-config --libs ${RC RCC_COMPILE = $(CC) $(RCC_CFLAGS) RCC_LINK = $(CC) $(RCC_CFLAGS) $(RCC_LDFLAGS) RCC_OBJECTS = rcm-client-main.o rcm-client-hardware-list.o rcm-client-hardware-info.o rcm-client-receive.o rcm-client-transmit.o generated.o -RCC_HEADERS = rcm-client-main.h rcm-client-hardware-list.h rcm-client-hardware-info.h rcm-client-receive.h rcm-client-transmit.h generated.h +RCC_HEADERS = rcm-client-main.h rcm-client-hardware-list.h rcm-client-hardware-info.h rcm-client-receive.h rcm-client-transmit.h generated.h $(COMMON_HEADERS) INSTALL = install -c INSTALL_PROGRAM = ${INSTALL} diff --git a/RemoteControlManager.xml b/RemoteControlManager.xml index af9c33f..ac81962 100644 --- a/RemoteControlManager.xml +++ b/RemoteControlManager.xml @@ -15,8 +15,11 @@ <arg type='q' name='keymap_height' direction='out'/> <arg type='aa{sv}' name='keymap_entries' direction='out'/> </method> - <signal name='VelocityChanged'> - <arg type='s' name='event'/> + <signal name='KeyPressed'> + <arg type='s' name='keycode'/> + </signal> + <signal name='KeyReleased'> + <arg type='s' name='keycode'/> </signal> <property name='DriverName' type='s' access='read'/> <property name='KernelKeymapName' type='s' access='read'/> diff --git a/linux-input-enum.h b/linux-input-enum.h index 8e03377..8aa9cf0 100644 --- a/linux-input-enum.h +++ b/linux-input-enum.h @@ -1,6 +1,8 @@ #ifndef foolinuxinputenumhfoo #define foolinuximputenumhfoo +/* AUTOGENERATED: DO NOT EDIT */ + enum linux_input_keyval { KEY_RESERVED = 0, KEY_ESC = 1, diff --git a/linux-input-keycodes.h b/linux-input-keycodes.h index 4ef6bd3..37021a5 100644 --- a/linux-input-keycodes.h +++ b/linux-input-keycodes.h @@ -1,18 +1,15 @@ #ifndef foolinuxinputkeycodesfoo #define foolinuxinputkeycodesfoo -#include "linux-input-enum.h" +/* AUTOGENERATED: DO NOT EDIT */ -#ifndef cairo_surface_t -typedef void * cairo_surface_t; -#endif +#include "linux-input-enum.h" struct linux_input_keycode { const char *name; enum linux_input_keyval value; bool alias; - cairo_surface_t *cs; - //GtkWidget *img; + void *cairo_surface; }; struct linux_input_keycode linux_input_keycodes[] = { diff --git a/rcm-client-main.c b/rcm-client-main.c index c12f046..17979dd 100644 --- a/rcm-client-main.c +++ b/rcm-client-main.c @@ -8,6 +8,7 @@ #include "generated.h" #include "rcm-client-main.h" #include "rcm-client-hardware-list.h" +#include "rcm-client-receive.h" #define WINDOW_WIDTH 300 #define WINDOW_HEIGHT 300 @@ -67,6 +68,33 @@ on_object_removed(GDBusObjectManager *manager, } static void +on_signal(GDBusObjectManagerClient *manager, + GDBusObjectProxy *object_proxy, + GDBusProxy *interface_proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + bool pressed; + gchar *keycode; + + g_print("Signal %s received for obj %s\n", signal_name, + g_dbus_object_get_object_path(G_DBUS_OBJECT(object_proxy))); + + if (!strcmp(signal_name, "KeyReleased")) + pressed = false; + else if (!strcmp(signal_name, "KeyPressed")) + pressed = true; + else + return; + + g_variant_get(parameters, "(s)", &keycode); + rcng_client_receive_keypress(G_DBUS_OBJECT(object_proxy), keycode, pressed); + g_free(keycode); +} + +static void on_owner_change(GDBusObjectManager *manager, gpointer user_data) { g_print("Owner changed, now: %s\n", g_dbus_object_manager_client_get_name_owner(G_DBUS_OBJECT_MANAGER_CLIENT(manager))); @@ -99,6 +127,7 @@ manager_ready_cb(GObject *source, GAsyncResult *res, gpointer user_data) g_signal_connect(mgr, "object-added", G_CALLBACK(on_object_added), NULL); g_signal_connect(mgr, "object-removed", G_CALLBACK(on_object_removed), NULL); + g_signal_connect(mgr, "interface-proxy-signal", G_CALLBACK(on_signal), NULL); g_signal_connect(mgr, "notify::name-owner", G_CALLBACK(on_owner_change), NULL); on_owner_change(mgr, NULL); diff --git a/rcm-client-receive.c b/rcm-client-receive.c index b12b0c2..b54af85 100644 --- a/rcm-client-receive.c +++ b/rcm-client-receive.c @@ -21,6 +21,7 @@ struct remote { guint width; guint height; bool editing; + bool active; }; struct rcbutton { @@ -116,7 +117,7 @@ create_button_img(GtkWidget *button, const char *keycode) label = "<?>"; } - if (lik->cs) + if (lik->cairo_surface) goto out; img_size = calculate_img_size(button); @@ -152,10 +153,10 @@ create_button_img(GtkWidget *button, const char *keycode) pango_cairo_show_layout(ct, layout); g_object_unref(layout); cairo_destroy(ct); - lik->cs = surface; + lik->cairo_surface = surface; out: - img = gtk_image_new_from_surface(lik->cs); + img = gtk_image_new_from_surface(lik->cairo_surface); gtk_button_set_image(GTK_BUTTON(button), img); } @@ -314,14 +315,36 @@ on_notebook_page_change(GtkNotebook *notebook, GtkWidget *page, guint new_page_n if (new_page_num != own_page_num) { remove_header_buttons(); remote->editing = false; + remote->active = false; return; } + remote->active = true; remote->editing = false; set_edit_keymap(remote->editing); g_print("Page change: %i -> %u\n", own_page_num, new_page_num); } +void rcng_client_receive_keypress(GDBusObject *obj, const gchar *keycode, bool pressed) +{ + GList *l; + + /* FIXME: Use object path, this is just test code */ + if (!remote || !remote->active) + return; + + for (l = remote->buttons; l; l = l->next) { + struct rcbutton *rcb = l->data; + + if (strcmp(keycode, rcb->name)) + continue; + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rcb->button), pressed); + } + + g_print("Key %s %s\n", keycode, pressed ? "pressed" : "released"); +} + void rcng_client_receive_init_ui(GDBusObject *new_hw) { static bool first = true; diff --git a/rcm-client-receive.h b/rcm-client-receive.h index 19adad0..7bfe764 100644 --- a/rcm-client-receive.h +++ b/rcm-client-receive.h @@ -1,4 +1,5 @@ void rcng_client_receive_destroy_ui(); void rcng_client_receive_init_ui(GDBusObject *new_hw); +void rcng_client_receive_keypress(GDBusObject *obj, const gchar *keycode, bool pressed); diff --git a/rcm-server-main.c b/rcm-server-main.c index 3d8ceee..283b685 100644 --- a/rcm-server-main.c +++ b/rcm-server-main.c @@ -190,6 +190,8 @@ static const sd_bus_vtable device_vtable[] = { SD_BUS_METHOD("EchoString", "s", "s", method_echostring, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("ListKeymaps", NULL, "as", method_listkeymaps, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("GetKeymap", "s", "qqaa{sv}", method_getkeymap, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_SIGNAL("KeyPressed", "s", 0), + SD_BUS_SIGNAL("KeyReleased", "s", 0), SD_BUS_VTABLE_END }; @@ -477,6 +479,45 @@ block_signals(void) return sigprocmask(SIG_BLOCK, &sigset, NULL); } +#include <time.h> + +typedef uint64_t usec_t; +#define USEC_PER_SEC ((usec_t)1000000ULL) +#define NSEC_PER_USEC ((usec_t)1000ULL) + +static usec_t +now(clockid_t clk_id) +{ + struct timespec ts; + + clock_gettime(clk_id, &ts); + + return (usec_t)(ts.tv_sec * USEC_PER_SEC) + (usec_t)(ts.tv_nsec / NSEC_PER_USEC); +} + +static int +timeout_cb(sd_event_source *source, usec_t usec, void *userdata) +{ + struct manager *mgr = userdata; + static bool pressed = true; + unsigned timeout; + + sd_bus_emit_signal(mgr->bus, "/org/gnome/RemoteControlManager/rc0", + "org.gnome.RemoteControlManager.Device", + pressed ? "KeyPressed" : "KeyReleased", + "s", "KEY_VIDEO"); + + if (pressed) + timeout = USEC_PER_SEC / 2; + else + timeout = USEC_PER_SEC * 3; + + sd_event_source_set_time(source, now(CLOCK_MONOTONIC) + timeout); + sd_event_source_set_enabled(source, SD_EVENT_ONESHOT); + pressed = !pressed; + return 0; +} + int main(int argc, char **argv) { @@ -488,6 +529,7 @@ main(int argc, char **argv) _cleanup_bus_slot_unref_ struct sd_bus_slot *objm_slot = NULL; _cleanup_event_source_unref_ sd_event_source *sigint_ev = NULL; _cleanup_event_source_unref_ sd_event_source *sigterm_ev = NULL; + _cleanup_event_source_unref_ sd_event_source *timeout_ev = NULL; mgr = zmalloc(sizeof(*mgr)); if (!mgr) { @@ -556,6 +598,11 @@ main(int argc, char **argv) sd_event_add_signal(mgr->event, &sigint_ev, SIGINT, NULL, NULL); sd_event_add_signal(mgr->event, &sigterm_ev, SIGTERM, NULL, NULL); + printf("Sending fake keypress events\n"); + sd_event_add_time(mgr->event, &timeout_ev, CLOCK_MONOTONIC, + now(CLOCK_MONOTONIC) + 3 * USEC_PER_SEC, + 0, timeout_cb, mgr); + r = sd_event_loop(mgr->event); if (r < 0) { fprintf(stderr, "Event loop failed: %s\n", strerror(-r)); diff --git a/tools/generate-input-keycodes.sh b/tools/generate-input-keycodes.sh index 96f28ff..51d09e8 100755 --- a/tools/generate-input-keycodes.sh +++ b/tools/generate-input-keycodes.sh @@ -31,7 +31,7 @@ struct linux_input_keycode { const char *name; enum linux_input_keyval value; bool alias; - GtkWidget *img; + void *cairo_surface; }; struct linux_input_keycode linux_input_keycodes[] = { |