summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2015-07-08 23:16:06 +0200
committerDavid Härdeman <david@hardeman.nu>2015-07-08 23:16:06 +0200
commit018efc8ef96a77529507b8a1614067821be8b90d (patch)
treec9ddacf9f800a63131d7bfa9a241d379f389701c
parentce38f3d01c76327fcbeadccf125f7e7540ed4721 (diff)
Add simple test client embryo
-rw-r--r--.gitignore2
-rw-r--r--Makefile38
-rw-r--r--RemoteControlManager.xml31
-rw-r--r--rcm-client-hardware-info.c74
-rw-r--r--rcm-client-hardware-info.h3
-rw-r--r--rcm-client-hardware-list.c140
-rw-r--r--rcm-client-hardware-list.h6
-rw-r--r--rcm-client-main.c216
-rw-r--r--rcm-client-main.h10
-rw-r--r--rcm-client-receive.c612
-rw-r--r--rcm-client-receive.h4
-rw-r--r--rcm-client-transmit.c31
-rw-r--r--rcm-client-transmit.h4
-rw-r--r--rcm-server-keymap.c61
-rw-r--r--rcm-server-keymap.h5
-rw-r--r--rcm-server-main.c (renamed from rcm-server.c)9
-rw-r--r--rcm-server-main.h (renamed from rcm-server.h)0
17 files changed, 1229 insertions, 17 deletions
diff --git a/.gitignore b/.gitignore
index a558115..b4d4283 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
*.o
rcm-server
+rcm-client
*.swp
keymaps
+generated.*
diff --git a/Makefile b/Makefile
index 9b601f3..571427b 100644
--- a/Makefile
+++ b/Makefile
@@ -11,16 +11,26 @@ GENERIC_CFLAGS = -g -Wall -Werror -D_FILE_OFFSET_BITS=64 \
EXTRA_CFLAGS =
GENERIC_LDFLAGS =
EXTRA_LDFLAGS =
+
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
+
+RCC_PACKAGES = gtk+-3.0
+RCC_CFLAGS = ${GENERIC_CFLAGS} ${EXTRA_CFLAGS} $(shell pkg-config --cflags ${RCC_PACKAGES})
+RCC_LDFLAGS = ${GENERIC_LDFLAGS} ${EXTRA_LDFLAGS} $(shell pkg-config --libs ${RCC_PACKAGES})
+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
+
INSTALL = install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
-RCM_COMPILE = $(CC) $(RCM_CFLAGS)
-RCM_LINK = $(CC) $(RCM_CFLAGS) $(RCM_LDFLAGS)
-RCM_SERVER_OBJ = rcm-server.o rcm-server-keymap.o
-RCM_SERVER_HDR = rcm-server.h rcm-server-keymap.h utils.h
DESTDIR ?=
prefix = /usr
@@ -33,13 +43,25 @@ mandir = ${prefix}/share/man
# Targets
#
-all: rcm-server
+all: rcm-server rcm-client
.DEFAULT: all
-%.o: %.c $(RCM_SERVER_HDR)
+rcm-client-%.o: rcm-client-%.c $(RCC_HEADERS)
+ $(RCC_COMPILE) -o $@ -c $<
+
+generated.o: generated.c generated.h
+ $(RCC_COMPILE) -o $@ -c $<
+
+generated.c generated.h: RemoteControlManager.xml
+ gdbus-codegen --interface-prefix org.gnome --c-generate-object-manager --generate-c-code generated RemoteControlManager.xml
+
+rcm-client: $(RCC_OBJECTS)
+ $(RCC_LINK) -o $@ $^
+
+rcm-server-%.o: rcm-server-%.c $(RCM_HEADERS)
$(RCM_COMPILE) -o $@ -c $<
-rcm-server: $(RCM_SERVER_OBJ)
+rcm-server: $(RCM_OBJECTS)
$(RCM_LINK) -o $@ $^
install: all
@@ -49,7 +71,7 @@ uninstall:
- rm -f $(DESTDIR)$(usrbindir)/rcm-server
clean:
- - rm -f *.o rcm-server
+ - rm -f generated.[ch] *.o rcm-server rcm-client
.PHONY: install uninstall clean all
diff --git a/RemoteControlManager.xml b/RemoteControlManager.xml
new file mode 100644
index 0000000..ede8f69
--- /dev/null
+++ b/RemoteControlManager.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<node name="/org/gnome/RemoteControlManager">
+ <interface name='org.gnome.RemoteControlManager.Device'>
+ <annotation name="org.gtk.GDBus.C.Name" value="RCDevice"/>
+ <method name='EchoString'>
+ <arg type='s' name='greeting' direction='in'/>
+ <arg type='s' name='response' direction='out'/>
+ </method>
+ <method name='ListKeymaps'>
+ <arg type='as' name='keymap_names' direction='out'/>
+ </method>
+ <method name='GetKeymap'>
+ <arg type='s' name='keymap_name' direction='in'/>
+ <arg type='q' name='keymap_width' direction='out'/>
+ <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>
+ <property name='DriverName' type='s' access='read'/>
+ <property name='KernelKeymapName' type='s' access='read'/>
+ <property name='GetHardwareType' type='s' access='read'/>
+ </interface>
+ <interface name='org.gnome.RemoteControlManager.IRDevice'>
+ <annotation name="org.gtk.GDBus.C.Name" value="RCIRDevice"/>
+ <method name='GetIRRXParameters'>
+ <arg type='a{sv}' name='ir_rx_parameters' direction='out'/>
+ </method>
+ </interface>
+</node>
diff --git a/rcm-client-hardware-info.c b/rcm-client-hardware-info.c
new file mode 100644
index 0000000..662f526
--- /dev/null
+++ b/rcm-client-hardware-info.c
@@ -0,0 +1,74 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
+#include <gtk/gtk.h>
+
+#include "generated.h"
+#include "rcm-client-main.h"
+#include "rcm-client-hardware-list.h"
+#include "rcm-client-hardware-info.h"
+#include "rcm-client-receive.h"
+#include "rcm-client-transmit.h"
+
+static GtkWidget *info = NULL;
+static GDBusObject *hw = NULL;
+
+void
+rcng_client_hardware_init_info_ui(GDBusObject *new_hw)
+{
+ GtkWidget *icon;
+ GtkWidget *hbox;
+ GtkWidget *title;
+ GtkWidget *line;
+
+ if (new_hw == hw)
+ return;
+
+ hw = new_hw;
+ if (info)
+ gtk_widget_destroy(info);
+ info = NULL;
+ rcng_client_receive_destroy_ui();
+ rcng_client_transmit_destroy_ui();
+
+ if (!hw)
+ return;
+
+ icon = gtk_image_new_from_icon_name("gtk-harddisk", GTK_ICON_SIZE_DIALOG);
+ gtk_widget_set_valign(icon, GTK_ALIGN_START);
+ gtk_widget_set_halign(icon, GTK_ALIGN_START);
+ gtk_widget_set_margin_start(icon, 12);
+ gtk_widget_set_margin_end(icon, 12);
+
+ hbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
+
+ title = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(title), "<b>Hardware</b>");
+ gtk_widget_set_halign(title, GTK_ALIGN_START);
+ gtk_box_pack_start(GTK_BOX(hbox), title, FALSE, FALSE, 0);
+
+ line = gtk_label_new("Apan 1");
+ gtk_widget_set_halign(line, GTK_ALIGN_START);
+ gtk_box_pack_start(GTK_BOX(hbox), line, FALSE, FALSE, 0);
+
+ line = gtk_label_new("Apan 2");
+ line = gtk_label_new(g_dbus_object_get_object_path(hw));
+ gtk_widget_set_halign(line, GTK_ALIGN_START);
+ gtk_box_pack_start(GTK_BOX(hbox), line, FALSE, FALSE, 0);
+
+ info = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_widget_set_margin_start(info, 12);
+ gtk_widget_set_margin_end(info, 12);
+ gtk_widget_set_margin_top(info, 12);
+ gtk_widget_set_margin_bottom(info, 12);
+ gtk_box_pack_start(GTK_BOX(info), icon, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(info), hbox, FALSE, FALSE, 0);
+
+ gtk_widget_show_all(info);
+ gtk_notebook_append_page(global->notebook, info, gtk_label_new("Details"));
+ gtk_notebook_set_current_page(global->notebook, 1);
+
+ rcng_client_receive_init_ui(new_hw);
+}
diff --git a/rcm-client-hardware-info.h b/rcm-client-hardware-info.h
new file mode 100644
index 0000000..37e65f0
--- /dev/null
+++ b/rcm-client-hardware-info.h
@@ -0,0 +1,3 @@
+
+void rcng_client_hardware_init_info_ui(GDBusObject *);
+
diff --git a/rcm-client-hardware-list.c b/rcm-client-hardware-list.c
new file mode 100644
index 0000000..eec0d03
--- /dev/null
+++ b/rcm-client-hardware-list.c
@@ -0,0 +1,140 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
+#include <gtk/gtk.h>
+
+#include "generated.h"
+#include "rcm-client-main.h"
+#include "rcm-client-hardware-list.h"
+#include "rcm-client-hardware-info.h"
+
+static GtkWidget *status_msg;
+static GtkWidget *hw_list_box;
+static GtkWidget *stack;
+static GList *hw_list = NULL;
+
+struct hwentry {
+ GDBusObject *hw;
+ GtkWidget *widget;
+};
+
+static gint
+find_hwentry_by_object(gconstpointer a, gconstpointer user_data)
+{
+ const struct hwentry *hwe = a;
+
+ return hwe->hw == user_data ? 0 : -1;
+}
+
+static gint
+find_hwentry_by_widget(gconstpointer a, gconstpointer user_data)
+{
+ const struct hwentry *hwe = a;
+
+ return hwe->widget == user_data ? 0 : -1;
+}
+
+void rcng_client_hardware_list_remove(GDBusObject *hw)
+{
+ GList *entry;
+ struct hwentry *hwe;
+
+ entry = g_list_find_custom(hw_list, hw, find_hwentry_by_object);
+ if (!entry)
+ return;
+
+ hwe = entry->data;
+ hw_list = g_list_remove_all(hw_list, hwe);
+
+ g_print(" - Object removed %s\n", g_dbus_object_get_object_path(hwe->hw));
+ gtk_widget_destroy(hwe->widget);
+ g_free(hwe);
+
+ if (!hw_list)
+ gtk_stack_set_visible_child(GTK_STACK(stack), status_msg);
+}
+
+void rcng_client_hardware_list_add(GDBusObject *hw)
+{
+ GList *interfaces;
+ GList *ll;
+ GtkWidget *box;
+ GtkWidget *icon;
+ GtkWidget *label;
+ struct hwentry *hwe;
+
+ g_print(" - Object at %s\n", g_dbus_object_get_object_path(hw));
+
+ interfaces = g_dbus_object_get_interfaces(hw);
+ for (ll = interfaces; ll != NULL; ll = ll->next) {
+ GDBusInterface *interface = G_DBUS_INTERFACE(ll->data);
+ g_print (" - Interface %s\n", g_dbus_interface_get_info(interface)->name);
+ }
+ g_list_free_full (interfaces, g_object_unref);
+
+ if (!hw_list)
+ gtk_stack_set_visible_child(GTK_STACK(stack), hw_list_box);
+
+ box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+ icon = gtk_image_new_from_icon_name("gtk-harddisk", GTK_ICON_SIZE_DIALOG);
+ gtk_widget_set_valign(icon, GTK_ALIGN_START);
+ gtk_widget_set_halign(icon, GTK_ALIGN_START);
+ gtk_widget_set_margin_start(icon, 12);
+ gtk_widget_set_margin_end(icon, 12);
+ label = gtk_label_new(g_dbus_object_get_object_path(hw));
+ gtk_box_pack_start(GTK_BOX(box), icon, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
+ gtk_widget_show_all(box);
+
+ gtk_list_box_insert(GTK_LIST_BOX(hw_list_box), box, -1);
+
+ hwe = g_malloc(sizeof(*hwe));
+ hwe->hw = hw;
+ hwe->widget = box;
+ hw_list = g_list_append(hw_list, hwe);
+}
+
+static void
+on_hw_selected(GtkListBox *box,
+ GtkListBoxRow *row,
+ gpointer user_data)
+{
+ GList *entry;
+ GtkWidget *child;
+ struct hwentry *hwe;
+
+ child = row ? gtk_bin_get_child(GTK_BIN(row)) : NULL;
+ entry = g_list_find_custom(hw_list, child, find_hwentry_by_widget);
+ hwe = entry ? entry->data : NULL;
+
+ rcng_client_hardware_init_info_ui(hwe ? hwe->hw : NULL);
+}
+
+void rcng_client_hardware_list_update_status(gchar *status)
+{
+ gtk_label_set_text(GTK_LABEL(status_msg), status);
+}
+
+void rcng_client_hardware_list_init_ui()
+{
+ stack = gtk_stack_new();
+ gtk_widget_set_margin_start(stack, 12);
+ gtk_widget_set_margin_end(stack, 12);
+ gtk_widget_set_margin_top(stack, 12);
+ gtk_widget_set_margin_bottom(stack, 12);
+ gtk_stack_set_transition_type(GTK_STACK(stack), GTK_STACK_TRANSITION_TYPE_CROSSFADE);
+
+ status_msg = gtk_label_new("Connecting to server...");
+ gtk_stack_add_named(GTK_STACK(stack), status_msg, "nohw");
+ gtk_stack_set_visible_child(GTK_STACK(stack), status_msg);
+
+ hw_list_box = gtk_list_box_new();
+ gtk_stack_add_named(GTK_STACK(stack), hw_list_box, "yeshw");
+ g_signal_connect(hw_list_box, "row-selected", G_CALLBACK(on_hw_selected), NULL);
+
+ gtk_notebook_append_page(global->notebook, stack, gtk_label_new("Hardware"));
+}
+
+
diff --git a/rcm-client-hardware-list.h b/rcm-client-hardware-list.h
new file mode 100644
index 0000000..47314e0
--- /dev/null
+++ b/rcm-client-hardware-list.h
@@ -0,0 +1,6 @@
+
+void rcng_client_hardware_list_remove(GDBusObject *);
+void rcng_client_hardware_list_add(GDBusObject *);
+void rcng_client_hardware_list_init_ui();
+void rcng_client_hardware_list_update_status(gchar *);
+
diff --git a/rcm-client-main.c b/rcm-client-main.c
new file mode 100644
index 0000000..cd119a3
--- /dev/null
+++ b/rcm-client-main.c
@@ -0,0 +1,216 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
+#include <gtk/gtk.h>
+
+#include "generated.h"
+#include "rcm-client-main.h"
+#include "rcm-client-hardware-list.h"
+
+#define WINDOW_WIDTH 300
+#define WINDOW_HEIGHT 300
+
+static GDBusObjectManager *mgr = NULL;
+
+struct global_variables *global;
+
+void
+poke_objects()
+{
+ GList *objects;
+ GList *l;
+ GDBusObjectManager *manager = mgr;
+
+ objects = g_dbus_object_manager_get_objects (manager);
+ for (l = objects; l != NULL; l = l->next)
+ {
+ GDBusInterface *interface;
+
+ interface = g_dbus_object_get_interface(G_DBUS_OBJECT(l->data),
+ "org.gnome.RemoteControlManager.Device");
+ if (!interface) {
+ g_print("That's weird, an object which is not a device...\n");
+ continue;
+ }
+
+ RCDevice *object = RCDEVICE(interface);
+ gchar *reply = NULL;
+ rcdevice_call_echo_string_sync(object, "Roeven", &reply, NULL, NULL);
+ printf("Called object %s: %s\n", g_dbus_object_get_object_path (G_DBUS_OBJECT(l->data)), reply);
+ printf("Driver name is: %s\n", rcdevice_get_driver_name(object));
+ printf("Keymap name is: %s\n", rcdevice_get_kernel_keymap_name(object));
+ g_free(reply);
+
+ g_object_unref(interface);
+ }
+ g_list_free_full (objects, g_object_unref);
+}
+
+void
+poke_objects2()
+{
+ GList *objects;
+ GList *l;
+ GDBusObjectManager *manager = mgr;
+
+ objects = g_dbus_object_manager_get_objects (manager);
+ for (l = objects; l != NULL; l = l->next)
+ {
+ GDBusInterface *interface;
+
+ interface = g_dbus_object_get_interface(G_DBUS_OBJECT(l->data),
+ "org.gnome.RemoteControlManager.IRDevice");
+ if (!interface) {
+ g_print("That's weird, an object which is not an ir device...\n");
+ continue;
+ }
+
+ RCIRDevice *object = RCIRDEVICE(interface);
+ GVariant *reply = NULL;
+ rcirdevice_call_get_irrxparameters_sync(object, &reply, NULL, NULL);
+
+ printf("Got a reply %p\n", reply);
+ gchar *ans = NULL;
+
+ g_variant_lookup(reply, "name", "s", &ans);
+ printf("The rsult is %s\n", ans);
+/*
+ printf("Called object %s: %s\n", g_dbus_object_get_object_path (G_DBUS_OBJECT(l->data)), reply);
+ printf("Driver name is: %s\n", rcdevice_get_driver_name(object));
+ printf("Keymap name is: %s\n", rcdevice_get_kernel_keymap_name(object));
+ */
+ //g_free(reply);
+
+ g_object_unref(interface);
+ }
+ g_list_free_full (objects, g_object_unref);
+}
+
+static void
+on_object_added(GDBusObjectManager *manager,
+ GDBusObject *object,
+ gpointer user_data)
+{
+ g_print("Added object at %s\n", g_dbus_object_get_object_path(object));
+ rcng_client_hardware_list_add(object);
+}
+
+static void
+on_object_removed(GDBusObjectManager *manager,
+ GDBusObject *object,
+ gpointer user_data)
+{
+ g_print("Removed object at %s\n", g_dbus_object_get_object_path(object));
+ rcng_client_hardware_list_remove(object);
+}
+
+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)));
+
+ if (!g_dbus_object_manager_client_get_name_owner(G_DBUS_OBJECT_MANAGER_CLIENT(manager)))
+ rcng_client_hardware_list_update_status("Server not running...\n");
+ else
+ rcng_client_hardware_list_update_status("No hardware connected...");
+}
+
+static void
+manager_ready_cb(GObject *source, GAsyncResult *res, gpointer user_data)
+{
+ GError *error = NULL;
+ GList *objects;
+ GList *l;
+
+ mgr = object_manager_client_new_for_bus_finish(res, &error);
+ if (!mgr) {
+ gchar *msg;
+
+ msg = g_strdup_printf("Error creating object manager client: %s",
+ error->message);
+ rcng_client_hardware_list_update_status(msg);
+
+ g_free(msg);
+ g_error_free(error);
+ return;
+ }
+
+ 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, "notify::name-owner", G_CALLBACK(on_owner_change), NULL);
+
+ on_owner_change(mgr, NULL);
+ g_print("Object manager at %s\n", g_dbus_object_manager_get_object_path(mgr));
+ objects = g_dbus_object_manager_get_objects(mgr);
+ for (l = objects; l != NULL; l = l->next) {
+ rcng_client_hardware_list_add(G_DBUS_OBJECT(l->data));
+ rcng_client_hardware_list_add(G_DBUS_OBJECT(l->data));
+ }
+
+ g_list_free_full (objects, g_object_unref);
+
+}
+
+int main (int argc, char *argv[])
+{
+ GtkWidget *win;
+ GdkScreen *screen;
+ gint monitor;
+ GdkRectangle rect;
+
+ global = g_malloc(sizeof(*global));
+
+ gtk_init (&argc, &argv);
+
+ object_manager_client_new_for_bus(G_BUS_TYPE_SESSION,
+ G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
+ "org.gnome.RemoteControlManager",
+ "/org/gnome/RemoteControlManager",
+ NULL, manager_ready_cb, NULL);
+
+ win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ global->window = GTK_WINDOW(win);
+ g_signal_connect(win, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+ screen = gtk_window_get_screen(global->window);
+ monitor = gdk_screen_get_monitor_at_point(screen, 0, 0);
+ gdk_screen_get_monitor_geometry(screen, monitor, &rect);
+ gtk_window_set_default_size(global->window,
+ rect.width * 4 / 5,
+ rect.height * 1 / 2);
+
+ global->header = GTK_HEADER_BAR(gtk_header_bar_new());
+ gtk_header_bar_set_title(global->header, "Remote Control Configuration");
+ gtk_header_bar_set_has_subtitle(global->header, FALSE);
+ gtk_header_bar_set_show_close_button(global->header, TRUE);
+ gtk_window_set_titlebar(global->window, GTK_WIDGET(global->header));
+
+ /*
+ GtkWidget *label;
+ label = gtk_label_new("Pack Start");
+ gtk_header_bar_pack_start(GTK_HEADER_BAR(header), label);
+ label = gtk_label_new("Pack End");
+ gtk_header_bar_pack_end(GTK_HEADER_BAR(header), label);
+ GtkWidget *test = gtk_button_new_from_icon_name("gtk-add", GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_label(GTK_BUTTON(test), "Test");
+ gtk_button_set_always_show_image(GTK_BUTTON(test), TRUE);
+ gtk_header_bar_pack_end(GTK_HEADER_BAR(header), test);
+ */
+
+
+ global->notebook = GTK_NOTEBOOK(gtk_notebook_new());
+ gtk_notebook_set_tab_pos(global->notebook, GTK_POS_LEFT);
+
+ rcng_client_hardware_list_init_ui(global->notebook);
+
+ gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(global->notebook));
+ //gtk_window_set_title(window, "Remote Control Configuration");
+ gtk_window_set_icon_name(global->window, "gnome-multimedia");
+ gtk_widget_show_all(win);
+
+ gtk_main();
+
+ return 0;
+}
diff --git a/rcm-client-main.h b/rcm-client-main.h
new file mode 100644
index 0000000..d27fb24
--- /dev/null
+++ b/rcm-client-main.h
@@ -0,0 +1,10 @@
+void poke_objects();
+void poke_objects2();
+
+struct global_variables {
+ GtkWindow *window;
+ GtkHeaderBar *header;
+ GtkNotebook *notebook;
+};
+
+extern struct global_variables *global;
diff --git a/rcm-client-receive.c b/rcm-client-receive.c
new file mode 100644
index 0000000..8abc64a
--- /dev/null
+++ b/rcm-client-receive.c
@@ -0,0 +1,612 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
+#include <inttypes.h>
+#include <gtk/gtk.h>
+
+#include "generated.h"
+#include "rcm-client-main.h"
+#include "rcm-client-receive.h"
+
+#define WINDOW_WIDTH 300
+#define WINDOW_HEIGHT 300
+
+struct remote {
+ GList *buttons;
+ guint width;
+ guint height;
+ struct rcbutton *hover;
+};
+
+struct rcbutton {
+ char *name;
+ bool clicked;
+ guint x;
+ guint y;
+ guint row;
+ guint col;
+ guint rows;
+ guint cols;
+ guint width;
+ guint height;
+ guint padding;
+ guint corner_radius;
+ struct rcbutton *next;
+ GdkRGBA *color;
+ void (*on_hover)(struct rcbutton *rcb, GtkWidget *widget, bool hover);
+};
+
+static struct remote *remote = NULL;
+
+static void
+curve_rectangle(cairo_t * cr, gdouble x0, gdouble y0,
+ gdouble width, gdouble height, gdouble radius)
+{
+ gdouble x1, y1;
+
+ if (!width || !height)
+ return;
+
+ x1 = x0 + width;
+ y1 = y0 + height;
+
+ radius = MIN (radius, MIN (width / 2, height / 2));
+
+ cairo_move_to (cr, x0, y0 + radius);
+ cairo_arc (cr, x0 + radius, y0 + radius, radius, M_PI,
+ 3 * M_PI / 2);
+ cairo_line_to (cr, x1 - radius, y0);
+ cairo_arc (cr, x1 - radius, y0 + radius, radius, 3 * M_PI / 2,
+ 2 * M_PI);
+ cairo_line_to (cr, x1, y1 - radius);
+ cairo_arc (cr, x1 - radius, y1 - radius, radius, 0, M_PI / 2);
+ cairo_line_to (cr, x0 + radius, y1);
+ cairo_arc (cr, x0 + radius, y1 - radius, radius, M_PI / 2, M_PI);
+
+ cairo_close_path (cr);
+}
+
+GdkRGBA *c;
+GdkRGBA *cd;
+GdkRGBA *cre;
+GdkRGBA *cb;
+GdkRGBA cgreen;
+GdkRGBA cred;
+
+static void
+draw_curve_rectangle(cairo_t * cr, struct rcbutton *rcb)
+{
+ double tx, ty;
+ cairo_text_extents_t extents;
+ const char *label = rcb->name ? rcb->name : "?";
+
+ curve_rectangle(cr, rcb->x, rcb->y,
+ rcb->width, rcb->height, rcb->corner_radius);
+
+ if (rcb->color)
+ gdk_cairo_set_source_rgba(cr, rcb->color);
+ else
+ gdk_cairo_set_source_rgba(cr, rcb->clicked ? cre : cd);
+ cairo_fill_preserve(cr);
+
+ gdk_cairo_set_source_rgba(cr, cb);
+ cairo_set_line_width(cr, 1.0);
+ cairo_stroke(cr);
+ /*
+ if (filled)
+ cairo_fill(cr);
+ else {
+ cairo_set_line_width(cr, 1.0);
+ cairo_stroke(cr);
+ }
+ */
+
+ cairo_save(cr);
+ cairo_rectangle(cr,
+ rcb->x + rcb->padding,
+ rcb->y + rcb->padding,
+ rcb->width - rcb->padding * 2,
+ rcb->height - rcb->padding * 2);
+ cairo_clip(cr);
+ cairo_set_font_size(cr, 13);
+ cairo_text_extents (cr, label, &extents);
+ tx = rcb->x + (rcb->width / 2) - (extents.width / 2 + extents.x_bearing);
+ ty = rcb->y + (rcb->height / 2) - (extents.height / 2 + extents.y_bearing);
+ cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
+ cairo_move_to(cr, tx, ty);
+ cairo_show_text(cr, label);
+ cairo_restore(cr);
+ cairo_new_sub_path(cr);
+}
+
+#define SPACING 5
+#define PADDING 5
+#define BW 56
+#define BH 56
+
+static gboolean draw_cb(GtkWidget *widget, cairo_t *cr, gpointer data)
+{
+ struct rcbutton *rcb;
+ guint w = 0, h = 0;
+
+ /* Set color for background */
+ gdk_cairo_set_source_rgba(cr, c);
+
+ /* fill in the background color*/
+ cairo_paint(cr);
+
+ GList *l;
+
+ for (l = remote->buttons; l; l = l->next) {
+ rcb = l->data;
+
+ draw_curve_rectangle(cr, rcb);
+
+ if (rcb->x + rcb->width > w)
+ w = rcb->x + rcb->width;
+
+ if (rcb->y + rcb->height > h)
+ h = rcb->y + rcb->height;
+ }
+
+ w += (SPACING + BW) / 2;
+ h += (SPACING + BH) / 2;
+
+ /*->name ? rcb->name : "?", false,
+ rcb->clicked ? cre : cd,
+ rcb->x, rcb->y, rcb->width, rcb->height,
+ rcb->padding, rcb->corner_radius);
+*/
+ gtk_widget_set_size_request(widget, w, h);
+ gtk_widget_set_halign(widget, GTK_ALIGN_CENTER);
+ gtk_widget_set_valign(widget, GTK_ALIGN_CENTER);
+ gtk_widget_set_margin_top(widget, BH / 2);
+ gtk_widget_set_margin_bottom(widget, BH / 2);
+ gtk_widget_set_margin_start(widget, BW / 2);
+ gtk_widget_set_margin_end(widget, BW / 2);
+
+
+ return FALSE;
+}
+
+#if 0
+static struct rcbutton *new_button(const char *name, guint row, guint col)
+{
+ struct rcbutton *rcb;
+
+ rcb = g_malloc(sizeof(*rcb));
+ rcb->name = strdup(name);
+ rcb->clicked = false;
+ rcb->x = (SPACING + BW) * (col) + (SPACING + BW) / 2;
+ rcb->y = (SPACING + BH) * (row) + (SPACING + BH) / 2;
+ rcb->width = BW;
+ rcb->height = BH;
+ rcb->padding = PADDING;
+ rcb->corner_radius = 3;
+ rcb->color = NULL;
+ return rcb;
+}
+#endif
+
+static void
+button_calculate_position(struct rcbutton *rcb)
+{
+ rcb->x = (SPACING + BW) * (rcb->col) + (SPACING + BW) / 2;
+ rcb->y = (SPACING + BH) * (rcb->row) + (SPACING + BH) / 2;
+ rcb->width = BW + (rcb->cols - 1) * (BW + SPACING);
+ rcb->height = BH + (rcb->rows - 1) * (BH + SPACING);
+}
+
+static void
+move_buttons(gint row, gint col)
+{
+ GList *l;
+
+ for (l = remote->buttons; l; l = l->next) {
+ struct rcbutton *rcb = l->data;
+
+ rcb->row += row;
+ rcb->col += col;
+ button_calculate_position(rcb);
+ }
+}
+
+static struct rcbutton *
+new_button_add(const char *name, GdkRGBA *color,
+ guint x, guint y, guint w, guint h)
+{
+ struct rcbutton *rcb;
+
+ rcb = g_malloc0(sizeof(*rcb));
+ rcb->name = strdup(name);
+ rcb->clicked = false;
+ rcb->col = x;
+ rcb->row = y;
+ rcb->cols = w;
+ rcb->rows = h;
+ button_calculate_position(rcb);
+ rcb->padding = PADDING;
+ rcb->corner_radius = 3;
+ rcb->color = color;
+ remote->buttons = g_list_append(remote->buttons, rcb);
+ remote->width = MAX(remote->width, w);
+ remote->height = MAX(remote->height, h);
+ return rcb;
+}
+
+#if 0
+static struct rcbutton *new_button_addr(const char *name, guint row, guint col)
+{
+ struct rcbutton *rcb;
+
+ rcb = g_malloc(sizeof(*rcb));
+ rcb->name = strdup(name);
+ rcb->clicked = false;
+ rcb->x = (SPACING + BW) / 2;
+ rcb->y = (SPACING + BH) / 2;
+ rcb->width = (SPACING + BW) * (col) - SPACING;
+ rcb->height = BH;
+ rcb->padding = PADDING;
+ rcb->corner_radius = 3;
+ rcb->color = &cred;
+ return rcb;
+}
+#endif
+static void
+button_redraw(struct rcbutton *rcb, GtkWidget *widget)
+{
+ printf("Asked to redraw: X,Y,W,H - %u,%u,%u,%u\n",
+ rcb->x - 1, rcb->y - 1, rcb->width + 2, rcb->height + 2);
+ gtk_widget_queue_draw_area(widget, rcb->x - 1, rcb->y - 1,
+ rcb->width + 2, rcb->height + 2);
+}
+
+static gboolean
+button_press_event_cb(GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data)
+{
+ struct rcbutton *rcb;
+ GList *l;
+ char buf[1024];
+
+ if (event->button != GDK_BUTTON_PRIMARY)
+ return true;
+
+ for (l = remote->buttons; l; l = l->next) {
+ rcb = l->data;
+
+ if (event->x < rcb->x || event->x > (rcb->x + rcb->width))
+ continue;
+
+ if (event->y < rcb->y || event->y > (rcb->y + rcb->height))
+ continue;
+
+ rcb->clicked = true;
+ button_redraw(rcb, widget);
+ sprintf(buf, "Button at %ux%u clicked\n", rcb->x, rcb->y);
+ poke_objects();
+ poke_objects2();
+ }
+
+ return true;
+}
+
+static gboolean
+button_release_event_cb(GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data)
+{
+ struct rcbutton *rcb;
+ GList *l;
+
+ if (event->button != GDK_BUTTON_PRIMARY)
+ return true;
+
+ for (l = remote->buttons; l; l = l->next) {
+ rcb = l->data;
+
+ if (!rcb->clicked)
+ continue;
+
+ rcb->clicked = false;
+
+ button_redraw(rcb, widget);
+ }
+
+ return true;
+}
+
+static gboolean
+motion_notify_event_cb (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer data)
+{
+ struct rcbutton *rcb;
+ static GdkCursor *cursor = NULL;
+ GdkWindow* win = gtk_widget_get_parent_window(widget);
+ GList *l;
+
+ if (!cursor)
+ cursor = gdk_cursor_new_for_display(gdk_window_get_display(win), GDK_HAND1);
+
+ for (l = remote->buttons; l; l = l->next) {
+ rcb = l->data;
+
+ if (event->x < rcb->x || event->x > (rcb->x + rcb->width))
+ continue;
+
+ if (event->y < rcb->y || event->y > (rcb->y + rcb->height))
+ continue;
+
+ break;
+ }
+
+ if (!l)
+ rcb = NULL;
+
+ if (remote->hover == rcb)
+ return true;
+
+ gdk_window_set_cursor(win, rcb ? cursor : NULL);
+
+ if (remote->hover && remote->hover->on_hover) {
+ remote->hover->on_hover(remote->hover, widget, false);
+ remote->hover = NULL;
+ }
+
+ if (rcb && rcb->on_hover) {
+ rcb->on_hover(rcb, widget, true);
+ remote->hover = rcb;
+ }
+
+ return true;
+}
+
+static GtkWidget *scrollda = NULL;
+
+void rcng_client_receive_destroy_ui()
+{
+ if (scrollda)
+ gtk_widget_destroy(scrollda);
+
+ scrollda = NULL;
+}
+
+static gint own_page_num = -1;
+static GtkWidget *header_button = NULL;
+static GtkWidget *da;
+
+#if 0
+static void
+edit_keymap_done(GtkButton *button, gpointer user_data)
+{
+
+}
+#endif
+static void
+on_hover_delete(struct rcbutton *rcb, GtkWidget *widget, bool hover)
+{
+ if (hover) {
+ if (rcb->col == 0 && rcb->cols == 1) {
+ rcb->cols = 2 + remote->width;
+ button_calculate_position(rcb);
+ button_redraw(rcb, widget);
+ } else if (rcb->row == 0 && rcb->rows == 1) {
+ rcb->rows = 2 + remote->height;
+ button_calculate_position(rcb);
+ button_redraw(rcb, widget);
+ }
+ } else {
+ if (rcb->col == 0 && rcb->cols != 1) {
+ button_redraw(rcb, widget);
+ rcb->cols = 1;
+ button_calculate_position(rcb);
+ } else if (rcb->row == 0 && rcb->rows != 1) {
+ button_redraw(rcb, widget);
+ rcb->rows = 1;
+ button_calculate_position(rcb);
+ }
+ }
+
+}
+
+static void
+edit_keymap(GtkButton *button, gpointer user_data)
+{
+ guint i;
+ gboolean *do_edit = user_data;
+ struct rcbutton *rcb;
+
+ g_print("Button clicked\n");
+ g_print("Remote width: %u x %u\n", remote->width, remote->height);
+ if (remote->width < 1 || remote->height < 1)
+ return;
+
+ if (!*do_edit) {
+ move_buttons(2, 2);
+ new_button_add("+", &cgreen, 2, 1, remote->width, 1);
+ new_button_add("+", &cgreen, 2, 2 + remote->height, remote->width, 1);
+ new_button_add("+", &cgreen, 1, 2, 1, remote->height);
+ new_button_add("+", &cgreen, 2 + remote->width, 2, 1, remote->height);
+
+ for (i = 0; i < remote->height; i++) {
+ rcb = new_button_add("-", &cred, 0, 2 + i, 1, 1);
+ rcb->on_hover = on_hover_delete;
+ }
+
+ for (i = 0; i < remote->width; i++) {
+ rcb = new_button_add("-", &cred, 2 + i, 0, 1, 1);
+ rcb->on_hover = on_hover_delete;
+ }
+
+ /*
+ new_button_add("+", &cgreen, 5, 2, 1, 7);
+ new_button_add("+", &cgreen, 2, 4, 1, 1);
+ new_button_add("+", &cgreen, 2, 4, 10, 10);
+ new_button_add("+", &cgreen, 2, 4, 10, 10);
+ new_button_add("-", &cred, 2, 2, 0, 0);
+ new_button_add("Del", &cred, 3, 3, 0, 0);
+ */
+
+ gtk_widget_queue_draw(da);
+ *do_edit = true;
+ } else {
+ GList *l = remote->buttons;
+
+ while (l) {
+ GList *next = l->next;
+ struct rcbutton *rcb = l->data;
+
+ if (rcb->color) {
+ g_free(rcb);
+ remote->buttons = g_list_delete_link (remote->buttons, l);
+ }
+
+ l = next;
+ }
+ move_buttons(-2, -2);
+ gtk_widget_queue_draw(da);
+ *do_edit = false;
+
+ }
+}
+
+static void
+on_notebook_page_change(GtkNotebook *notebook, GtkWidget *page, guint new_page_num,
+ gpointer user_data)
+{
+ static gboolean do_edit = false;
+
+ if (new_page_num != own_page_num) {
+ if (header_button) {
+ gtk_widget_destroy(header_button);
+ header_button = NULL;
+ do_edit = false;
+ }
+ return;
+ }
+
+ GtkWidget *test = gtk_button_new_from_icon_name("gtk-add", GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_label(GTK_BUTTON(test), "Edit Keymap");
+ gtk_button_set_always_show_image(GTK_BUTTON(test), TRUE);
+ g_signal_connect(test, "clicked", G_CALLBACK(edit_keymap), &do_edit);
+ gtk_widget_show_all(test);
+ gtk_header_bar_pack_end(GTK_HEADER_BAR(global->header), test);
+ header_button = test;
+ g_print("Page change: %i -> %u\n", own_page_num, new_page_num);
+}
+
+void rcng_client_receive_init_ui(GDBusObject *new_hw)
+{
+ GtkStateFlags state;
+ GtkStyleContext *style_context;
+ static bool first = true;
+
+ if (first) {
+ g_signal_connect(global->notebook, "switch-page", G_CALLBACK(on_notebook_page_change), NULL);
+ first = false;
+ }
+
+ rcng_client_receive_destroy_ui();
+
+ GDBusInterface *interface;
+ interface = g_dbus_object_get_interface(new_hw, "org.gnome.RemoteControlManager.Device");
+ if (!interface)
+ return;
+
+ /* FIXME: if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a(uuuuaa{sv}))"))) */
+
+ gchar **keymaps = NULL;
+ RCDevice *object = RCDEVICE(interface);
+ rcdevice_call_list_keymaps_sync(object, &keymaps, NULL, NULL);
+ g_print("I should look at keymap: %s\n", keymaps[0]);
+
+ guint16 km_width;
+ guint16 km_height;
+ GVariant *km_entries = NULL;
+ rcdevice_call_get_keymap_sync(object, keymaps[0], &km_width, &km_height,
+ &km_entries, NULL, NULL);
+
+ g_free(keymaps);
+ remote = g_malloc0(sizeof(*remote));
+ remote->width = km_width;
+ remote->height = km_height;
+
+ g_print("type of keymaps is %s\n", g_variant_get_type_string(km_entries));
+ GVariantIter iter;
+ gsize n_items;
+ GVariant *item;
+
+ style_context = gtk_widget_get_style_context(GTK_WIDGET(global->window));
+ state = gtk_widget_get_state_flags(GTK_WIDGET(global->window));
+ gtk_style_context_get(style_context, state, "background-color", &c, NULL);
+
+ cd = gdk_rgba_copy(c);
+ cd->red *= 0.7;
+ cd->green *= 0.7;
+ cd->blue *= 0.7;
+
+ cre = gdk_rgba_copy(c);
+ cre->red *= 2.0;
+
+ cb = gdk_rgba_copy(c);
+ cb->red = 0.0;
+ cb->green = 0.0;
+ cb->blue = 0.0;
+ cb->alpha = 1.0;
+
+ gdk_rgba_parse(&cgreen, "#a9b68f");
+ gdk_rgba_parse(&cred, "#cf8989");
+ cred.alpha = 0.8;
+
+ n_items = g_variant_iter_init(&iter, km_entries);
+ g_print("Key items: %zu\n", n_items);
+ guint row = 0;
+ guint col = 0;
+
+ while (g_variant_iter_loop (&iter, "@a{sv}", &item)) {
+ gchar *protocol;
+ guint64 scancode;
+ gchar *keycode;
+
+ g_variant_lookup(item, "protocol", "s", &protocol);
+ g_variant_lookup(item, "scancode", "t", &scancode);
+ g_variant_lookup(item, "keycode", "s", &keycode);
+
+ new_button_add(keycode, NULL, col, row, 1, 1);
+
+ col++;
+ if (col >= km_width) {
+ col = 0;
+ row++;
+ }
+
+ printf("Got a key: %s:0x%08" PRIx64 ":%s\n", protocol, scancode, keycode);
+ }
+
+ da = gtk_drawing_area_new();
+// gtk_widget_set_size_request (da, WINDOW_WIDTH, WINDOW_HEIGHT);
+ g_signal_connect (da, "draw", G_CALLBACK(draw_cb), NULL);
+
+ g_signal_connect(da, "button-press-event",
+ G_CALLBACK (button_press_event_cb), NULL);
+
+ g_signal_connect(da, "button-release-event",
+ G_CALLBACK (button_release_event_cb), NULL);
+
+ g_signal_connect(da, "motion-notify-event",
+ G_CALLBACK (motion_notify_event_cb), NULL);
+
+ gtk_widget_set_events (da, gtk_widget_get_events (da)
+ | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
+
+ scrollda = gtk_scrolled_window_new(NULL, NULL);
+
+ gtk_container_add(GTK_CONTAINER(scrollda), da);
+ gtk_widget_show_all(scrollda);
+ own_page_num = gtk_notebook_append_page(global->notebook, scrollda, gtk_label_new("Receive"));
+}
+
diff --git a/rcm-client-receive.h b/rcm-client-receive.h
new file mode 100644
index 0000000..19adad0
--- /dev/null
+++ b/rcm-client-receive.h
@@ -0,0 +1,4 @@
+
+void rcng_client_receive_destroy_ui();
+void rcng_client_receive_init_ui(GDBusObject *new_hw);
+
diff --git a/rcm-client-transmit.c b/rcm-client-transmit.c
new file mode 100644
index 0000000..62b0a7f
--- /dev/null
+++ b/rcm-client-transmit.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
+#include <gtk/gtk.h>
+
+#include "generated.h"
+#include "rcm-client-main.h"
+#include "rcm-client-transmit.h"
+
+static GtkWidget *label = NULL;
+
+void rcng_client_transmit_destroy_ui()
+{
+ if (label)
+ gtk_widget_destroy(label);
+
+ label = NULL;
+}
+
+void rcng_client_transmit_init_ui()
+{
+ GtkWidget *label;
+
+ rcng_client_transmit_destroy_ui();
+ label = gtk_label_new("Transmitting");
+ gtk_widget_show_all(label);
+ gtk_notebook_append_page(global->notebook, label, gtk_label_new("Transmit"));
+}
+
diff --git a/rcm-client-transmit.h b/rcm-client-transmit.h
new file mode 100644
index 0000000..92b3786
--- /dev/null
+++ b/rcm-client-transmit.h
@@ -0,0 +1,4 @@
+
+void rcng_client_transmit_destroy_ui();
+void rcng_client_transmit_init_ui();
+
diff --git a/rcm-server-keymap.c b/rcm-server-keymap.c
index d0f772e..39b4440 100644
--- a/rcm-server-keymap.c
+++ b/rcm-server-keymap.c
@@ -14,7 +14,7 @@
#include <limits.h>
#include "utils.h"
-#include "rcm-server.h"
+#include "rcm-server-main.h"
#include "rcm-server-keymap.h"
enum ini_section {
@@ -63,6 +63,33 @@ static int strtol_strict(const char *str, int *result)
return 0;
}
+static int strtoull_strict(const char *str, uint64_t *result)
+{
+ char *end;
+ unsigned long long val;
+
+ errno = 0;
+ val = strtoull(str, &end, 16);
+
+ if (errno == ERANGE && (val == ULLONG_MAX || val == 0))
+ return -EINVAL;
+
+ if (errno != 0 && val == 0)
+ return -EINVAL;
+
+ if (end == str)
+ return -EINVAL;
+
+ if (*end != '\0')
+ return -EINVAL;
+
+ if (val > UINT64_MAX)
+ return -EINVAL;
+
+ *result = val;
+ return 0;
+}
+
static int
keymap_parse(FILE *fp, char **line, size_t *buf_size, struct keymap *keymap,
uint16_t *rows_return, uint16_t *cols_return,
@@ -142,9 +169,37 @@ keymap_parse(FILE *fp, char **line, size_t *buf_size, struct keymap *keymap,
break;
case INI_SECTION_KEYMAP:
if (!strcasecmp(p, "Map")) {
+ char *protocol;
+ char *scanstr;
+ char *keycode;
+ char *end;
+ uint64_t scancode;
+
+ printf("Map %s\n", tmp);
+ protocol = strtok(tmp, " :");
+ scanstr = strtok(NULL, " :");
+ keycode = strtok(NULL, " :");
+ end = strtok(NULL, " :");
+
+ if (!protocol || !scancode || !keycode || end) {
+ fprintf(stderr, "Invalid map directive\n");
+ return -ENOMEM;
+ }
+
+ r = strtoull_strict(scanstr, &scancode);
+ if (r < 0) {
+ fprintf(stderr, "Invalid scancode value\n");
+ return r;
+ }
+
+ printf("Map means protocol %s scancode 0x%08" PRIx64 " keycode %s\n",
+ protocol, scancode, keycode);
+
if (keymap) {
- keymap->keycodes[keycode_count].name = "apan";
- keymap->keycodes[keycode_count].value = "papan";
+ /* FIXME: leaks */
+ keymap->keycodes[keycode_count].protocol = strdup(protocol);
+ keymap->keycodes[keycode_count].scancode = scancode;
+ keymap->keycodes[keycode_count].keycode = strdup(keycode);
}
keycode_count++;
} else {
diff --git a/rcm-server-keymap.h b/rcm-server-keymap.h
index 6ece017..8676fbc 100644
--- a/rcm-server-keymap.h
+++ b/rcm-server-keymap.h
@@ -2,8 +2,9 @@
#define foorcmserverkeymaphfoo
struct keycode {
- char *name;
- char *value;
+ char *protocol;
+ uint64_t scancode;
+ char *keycode;
};
struct keymap {
diff --git a/rcm-server.c b/rcm-server-main.c
index 11223b1..02387a1 100644
--- a/rcm-server.c
+++ b/rcm-server-main.c
@@ -9,7 +9,7 @@
#include <errno.h>
#include "utils.h"
-#include "rcm-server.h"
+#include "rcm-server-main.h"
#include "rcm-server-keymap.h"
static int
@@ -153,9 +153,10 @@ method_getkeymap(sd_bus_message *m, void *userdata, sd_bus_error *error)
goto out;
for (i = 0; i < (keymap->rows * keymap->cols); i++) {
- r = sd_bus_message_append(reply, "a{sv}", 2,
- "name", "s", keymap->layout[i]->name,
- "keycode", "s", keymap->layout[i]->value);
+ r = sd_bus_message_append(reply, "a{sv}", 3,
+ "protocol", "s", keymap->layout[i]->protocol,
+ "scancode", "t", keymap->layout[i]->scancode,
+ "keycode", "s", keymap->layout[i]->keycode);
if (r < 0)
goto out;
}
diff --git a/rcm-server.h b/rcm-server-main.h
index 188ffab..188ffab 100644
--- a/rcm-server.h
+++ b/rcm-server-main.h