summaryrefslogtreecommitdiff
path: root/rcm-client-receive.c
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2015-07-16 12:32:07 +0200
committerDavid Härdeman <david@hardeman.nu>2015-07-16 12:32:07 +0200
commite664eafdac547ef8f7176a4c602eeae9fa0f6dea (patch)
treebcd9626ede73769920457b72a0d763e97be9f3bb /rcm-client-receive.c
parentac13d05d8bcf212e3423f3100331ffe0fa1a433a (diff)
Support multiple keymaps in client
Diffstat (limited to 'rcm-client-receive.c')
-rw-r--r--rcm-client-receive.c230
1 files changed, 136 insertions, 94 deletions
diff --git a/rcm-client-receive.c b/rcm-client-receive.c
index b54af85..734bc31 100644
--- a/rcm-client-receive.c
+++ b/rcm-client-receive.c
@@ -15,26 +15,29 @@
#define WINDOW_WIDTH 300
#define WINDOW_HEIGHT 300
+struct rcbutton {
+ char *name;
+ GtkWidget *button;
+};
+
struct remote {
+ char *name;
+ guint16 width;
+ guint16 height;
GList *buttons;
+ GtkWidget *widget;
+ GtkWidget *grid;
+ GtkWidget *edit_button;
+};
+
+struct state {
+ GList *remotes;
GList *header_buttons;
- guint width;
- guint height;
bool editing;
bool active;
};
-struct rcbutton {
- char *name;
- guint row;
- guint col;
- guint rows;
- guint cols;
- GtkWidget *button;
- struct rcbutton *next;
-};
-
-static struct remote *remote = NULL;
+static struct state state;
#if 0
static void
@@ -162,25 +165,19 @@ out:
static struct rcbutton *
new_button_add(GtkGrid *grid, const gchar *protocol, guint64 scancode,
- const char *keycode, GdkRGBA *color,
- guint x, guint y, guint w, guint h)
+ const char *keycode, GdkRGBA *color, guint x, guint y)
{
struct rcbutton *rcb;
gchar *tooltip;
rcb = g_malloc0(sizeof(*rcb));
rcb->name = strdup(keycode);
- rcb->col = x;
- rcb->row = y;
- rcb->cols = w;
- rcb->rows = h;
rcb->button = gtk_toggle_button_new();
gtk_widget_set_sensitive(rcb->button, false);
tooltip = g_strdup_printf("Protocol: %s\nScancode: 0x%08" PRIx64 "\nKeycode : %s", protocol, scancode, keycode);
gtk_widget_set_tooltip_text(rcb->button, tooltip);
g_free(tooltip);
- remote->buttons = g_list_append(remote->buttons, rcb);
- gtk_grid_attach(grid, rcb->button, x, y, w, h);
+ gtk_grid_attach(grid, rcb->button, x, y, 1, 1);
create_button_img(rcb->button, keycode);
return rcb;
}
@@ -210,7 +207,7 @@ create_header_button(const gchar *label, const gchar *icon_name,
g_signal_connect(button, "clicked", callback, user_data);
gtk_widget_show_all(button);
gtk_header_bar_pack_end(GTK_HEADER_BAR(global->header), button);
- remote->header_buttons = g_list_prepend(remote->header_buttons, button);
+ state.header_buttons = g_list_prepend(state.header_buttons, button);
}
static void
@@ -218,11 +215,11 @@ remove_header_buttons(void)
{
GList *l;
- for (l = remote->header_buttons; l; l = l->next)
+ for (l = state.header_buttons; l; l = l->next)
gtk_widget_destroy(l->data);
- g_list_free(remote->header_buttons);
- remote->header_buttons = NULL;
+ g_list_free(state.header_buttons);
+ state.header_buttons = NULL;
}
static void toggle_edit_keymap(GtkButton *button, gpointer user_data);
@@ -230,6 +227,7 @@ static void toggle_edit_keymap(GtkButton *button, gpointer user_data);
static void
resize_keymap(GtkButton *button, gpointer user_data)
{
+ struct remote *remote = user_data;
GtkWindow *parent = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button)));
GtkWidget *dialog;
GtkWidget *content_area;
@@ -280,7 +278,7 @@ resize_keymap(GtkButton *button, gpointer user_data)
width = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(width_input));
height = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(height_input));
- printf("Asked to resize keylayout to %ix%i\n", width, height);
+ printf("Asked to resize keymap '%s' to to %ix%i\n", remote->name, width, height);
out:
gtk_widget_destroy(dialog);
@@ -289,23 +287,36 @@ out:
static void
set_edit_keymap(bool editing)
{
- if (remote->width < 1 || remote->height < 1)
- return;
+ GList *l;
remove_header_buttons();
- if (editing) {
- create_header_button("Apply", "gtk-apply", G_CALLBACK(toggle_edit_keymap), &remote);
- create_header_button("Resize", "document-page-setup", G_CALLBACK(resize_keymap), &remote);
- } else
- create_header_button("Edit", "list-add", G_CALLBACK(toggle_edit_keymap), &remote);
+ if (editing)
+ create_header_button("Apply", "gtk-apply", G_CALLBACK(toggle_edit_keymap), NULL);
+ else
+ create_header_button("Edit", "list-add", G_CALLBACK(toggle_edit_keymap), NULL);
+
+ for (l = state.remotes; l; l = l->next) {
+ struct remote *remote = l->data;
+
+ if (editing) {
+ remote->edit_button = gtk_button_new_with_label("Resize");
+ g_signal_connect(remote->edit_button, "clicked", G_CALLBACK(resize_keymap), remote);
+ gtk_grid_attach(GTK_GRID(remote->grid), remote->edit_button, 0, -1, remote->width, 1);
+ gtk_widget_show_all(remote->edit_button);
+ } else {
+ if (remote->edit_button)
+ gtk_widget_destroy(remote->edit_button);
+ remote->edit_button = NULL;
+ }
+ }
}
static void
toggle_edit_keymap(GtkButton *button, gpointer user_data)
{
- remote->editing = !remote->editing;
- set_edit_keymap(remote->editing);
+ state.editing = !state.editing;
+ set_edit_keymap(state.editing);
}
static void
@@ -314,70 +325,55 @@ 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;
+ state.editing = false;
+ state.active = false;
return;
}
- remote->active = true;
- remote->editing = false;
- set_edit_keymap(remote->editing);
+ state.active = true;
+ state.editing = false;
+ set_edit_keymap(state.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;
+ unsigned affected = 0;
/* FIXME: Use object path, this is just test code */
- if (!remote || !remote->active)
+ if (!state.active)
return;
- for (l = remote->buttons; l; l = l->next) {
- struct rcbutton *rcb = l->data;
+ for (l = state.remotes; l; l = l->next) {
+ struct remote *remote = l->data;
+ GList *button;
- if (strcmp(keycode, rcb->name))
- continue;
+ for (button = remote->buttons; button; button = button->next) {
+ struct rcbutton *rcb = button->data;
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rcb->button), pressed);
+ if (strcmp(keycode, rcb->name))
+ continue;
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rcb->button), pressed);
+ affected++;
+ }
}
- g_print("Key %s %s\n", keycode, pressed ? "pressed" : "released");
+ g_print("Key %s %s (%u affected)\n", keycode, pressed ? "pressed" : "released", affected);
}
-void rcng_client_receive_init_ui(GDBusObject *new_hw)
+static struct remote *
+get_keymap(RCDevice *object, const gchar *keymap_name)
{
- 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;
+ struct remote *remote;
GVariant *km_entries = NULL;
- rcdevice_call_get_keymap_sync(object, keymaps[0], &km_width, &km_height,
- &km_entries, NULL, NULL);
remote = g_malloc0(sizeof(*remote));
- remote->width = km_width;
- remote->height = km_height;
- remote->editing = false;
+ remote->name = strdup(keymap_name);
+
+ rcdevice_call_get_keymap_sync(object, keymap_name, &remote->width,
+ &remote->height, &km_entries, NULL, NULL);
g_print("type of keymaps is %s\n", g_variant_get_type_string(km_entries));
GVariantIter iter;
@@ -389,25 +385,13 @@ void rcng_client_receive_init_ui(GDBusObject *new_hw)
guint row = 0;
guint col = 0;
- scrollda = gtk_scrolled_window_new(NULL, NULL);
- gtk_container_set_border_width(GTK_CONTAINER(scrollda), 12);
- own_page_num = gtk_notebook_append_page(global->notebook, scrollda, gtk_label_new("Receive"));
-
- GtkWidget *rgrid;
- rgrid = gtk_grid_new();
- gtk_widget_set_halign(rgrid, GTK_ALIGN_CENTER);
- gtk_grid_set_column_spacing(GTK_GRID(rgrid), 12);
- gtk_grid_set_row_spacing(GTK_GRID(rgrid), 12);
- gtk_container_add(GTK_CONTAINER(scrollda), rgrid);
-
GtkWidget *fixed;
fixed = gtk_fixed_new();
gtk_widget_set_name(fixed, "RemoteControlClientFixed");
- gtk_grid_attach(GTK_GRID(rgrid), fixed, 1, 1, 1, 1);
+ remote->widget = fixed;
GtkWidget *frame;
- frame = gtk_frame_new(keymaps[0]);
- g_free(keymaps);
+ frame = gtk_frame_new(keymap_name);
gtk_widget_set_name(gtk_frame_get_label_widget(GTK_FRAME(frame)), "RemoteControlClientRemoteLabel");
gtk_widget_set_name(frame, "RemoteControlClientRemoteFrame");
gtk_fixed_put(GTK_FIXED(fixed), frame, 0, 0);
@@ -420,6 +404,7 @@ void rcng_client_receive_init_ui(GDBusObject *new_hw)
gtk_grid_set_column_homogeneous(GTK_GRID(grid), true);
gtk_grid_set_row_homogeneous(GTK_GRID(grid), true);
gtk_container_set_border_width(GTK_CONTAINER(grid), 12);
+ remote->grid = grid;
while (g_variant_iter_loop (&iter, "@a{sv}", &item)) {
gchar *type;
@@ -432,18 +417,75 @@ void rcng_client_receive_init_ui(GDBusObject *new_hw)
g_variant_lookup(item, "scancode", "t", &scancode);
g_variant_lookup(item, "keycode", "s", &keycode);
- if (!strcmp(type, "button"))
- new_button_add(GTK_GRID(grid), protocol, scancode, keycode, NULL, col, row, 1, 1);
+ if (!strcmp(type, "button")) {
+ struct rcbutton *rcb;
+ rcb = new_button_add(GTK_GRID(grid), protocol, scancode,
+ keycode, NULL, col, row);
+ remote->buttons = g_list_append(remote->buttons, rcb);
+ printf("Got a button: %s:0x%08" PRIx64 ":%s\n", protocol, scancode, keycode);
+ } else if (!strcmp(type, "blank"))
+ printf("Got a blank\n");
+ else
+ printf("Error: unknown type: %s (treating as blank)\n", type);
col++;
- if (col >= km_width) {
+ if (col >= remote->width) {
col = 0;
row++;
}
- printf("Got a %s: %s:0x%08" PRIx64 ":%s\n", type, protocol, scancode, keycode);
}
+ return remote;
+}
+
+void rcng_client_receive_init_ui(GDBusObject *new_hw)
+{
+ static bool first = true;
+ unsigned i;
+
+ if (first) {
+ g_signal_connect(global->notebook, "switch-page", G_CALLBACK(on_notebook_page_change), NULL);
+ state.remotes = NULL;
+ state.header_buttons = NULL;
+ state.editing = false;
+ state.active = false;
+ first = false;
+ }
+
+ rcng_client_receive_destroy_ui();
+
+ /* FIXME: if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a(uuuuaa{sv}))"))) */
+ scrollda = gtk_scrolled_window_new(NULL, NULL);
+ gtk_container_set_border_width(GTK_CONTAINER(scrollda), 12);
+ own_page_num = gtk_notebook_append_page(global->notebook, scrollda, gtk_label_new("Receive"));
+
+ GtkWidget *rgrid;
+ rgrid = gtk_grid_new();
+ gtk_widget_set_halign(rgrid, GTK_ALIGN_CENTER);
+ gtk_grid_set_column_spacing(GTK_GRID(rgrid), 12);
+ gtk_grid_set_row_spacing(GTK_GRID(rgrid), 12);
+ gtk_container_add(GTK_CONTAINER(scrollda), rgrid);
+
+ GDBusInterface *interface;
+ interface = g_dbus_object_get_interface(new_hw, "org.gnome.RemoteControlManager.Device");
+ if (!interface)
+ return;
+
+ gchar **keymaps = NULL;
+ RCDevice *object = RCDEVICE(interface);
+ rcdevice_call_list_keymaps_sync(object, &keymaps, NULL, NULL);
+ for (i = 0; keymaps[i]; i++) {
+ struct remote *remote;
+
+ g_print("Fetching keymap: %s\n", keymaps[i]);
+ remote = get_keymap(object, keymaps[i]);
+
+ state.remotes = g_list_prepend(state.remotes, remote);
+ gtk_grid_attach(GTK_GRID(rgrid), remote->widget, i, 1, 1, 1);
+ }
+
+ g_free(keymaps);
gtk_widget_show_all(scrollda);
}