summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Pelz <pelzflorian@pelzflorian.de>2017-04-08 12:46:46 +0200
committerFlorian Pelz <pelzflorian@pelzflorian.de>2017-04-08 12:46:46 +0200
commitc6ec36e0f0e9fe19597fefb7b8dd7f4441350ba4 (patch)
tree49300338c11df9e1c98a2654c3ebe5b113cc4a2d
parent4addfbc7465d2ec30db17f24f7abde7783048df3 (diff)
Support paste from clipboard
-rw-r--r--bin/hangman/hangman.c88
1 files changed, 78 insertions, 10 deletions
diff --git a/bin/hangman/hangman.c b/bin/hangman/hangman.c
index 255cd6e..381c13e 100644
--- a/bin/hangman/hangman.c
+++ b/bin/hangman/hangman.c
@@ -32,10 +32,11 @@ typedef struct _GameData GameData;
struct _AppData
{
- GameData *game_data;
- GtkLabel *guessed;
- GtkWidget *gallow;
- GtkIMContext *input_method;
+ GameData *game_data;
+ GtkLabel *guessed;
+ GtkWidget *gallow;
+ GtkIMContext *input_method;
+ GtkAccelGroup *accel_group;
};
typedef struct _AppData AppData;
@@ -270,24 +271,23 @@ new_game (AppData *app_data)
}
static void
-handle_input (GtkIMContext *input_method,
- gchar *str,
- AppData *app_data)
+play_characters_in_string (const gchar *text,
+ AppData *app_data)
{
GameData *game_data;
PangoLogAttr *log_attrs, *input_log_attrs;
gint input_byte_count, input_uchar_count;
- gchar *tmp, *remaining;
+ gchar *tmp, *str, *remaining;
gint new_char_count;
- if (!g_utf8_validate (str, -1, NULL))
+ if (!g_utf8_validate (text, -1, NULL))
return;
game_data = app_data->game_data;
log_attrs = game_data->log_attrs;
/* Make str uppercase and normalized. */
- tmp = g_utf8_strup (str, -1);
+ tmp = g_utf8_strup (text, -1);
str = g_utf8_normalize (tmp, -1, G_NORMALIZE_ALL);
g_free (tmp);
@@ -428,14 +428,61 @@ handle_input (GtkIMContext *input_method,
gtk_widget_queue_draw (app_data->gallow);
}
+static void
+handle_input (GtkIMContext *input_method,
+ gchar *text,
+ AppData *app_data)
+{
+ play_characters_in_string (text, app_data);
+}
+
+static void
+handle_clipboard_recv (GtkClipboard *clipboard,
+ const gchar *text,
+ AppData *app_data)
+{
+ play_characters_in_string (text, app_data);
+}
+
+static gboolean
+handle_paste (GtkAccelGroup *accel_group,
+ GObject *acceleratable,
+ guint accel_key,
+ GdkModifierType accel_mod,
+ AppData *app_data)
+{
+ GdkDisplay *display;
+ GtkClipboard *clipboard;
+
+ display = gtk_widget_get_display (app_data->gallow);
+ clipboard = gtk_clipboard_get_default (display);
+
+ gtk_clipboard_request_text (clipboard,
+ (GtkClipboardTextReceivedFunc)
+ handle_clipboard_recv,
+ app_data);
+
+ return FALSE;
+}
+
static gboolean
handle_key_press (GtkWidget *window,
GdkEventKey *key,
AppData *app_data)
{
+ guint accel_key;
+ GdkModifierType accel_mods;
gint state;
GtkIMContext *input_method;
+ accel_key = key->keyval;
+ accel_mods = key->state;
+ gtk_accel_group_activate (app_data->accel_group,
+ 0, /* no detail for accel-activate */
+ G_OBJECT (window),
+ accel_key,
+ accel_mods);
+
state = app_data->game_data->state;
if (state == -1 || state == 6)
{
@@ -552,6 +599,11 @@ app_startup (GApplication *app)
GameData *game_data;
AppData *app_data;
+ GtkAccelGroup *accel_group;
+ GClosure *handle_paste_closure;
+ guint accel_key;
+ GdkModifierType accel_mods;
+
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW (window),
370,
@@ -588,10 +640,26 @@ app_startup (GApplication *app)
game_data = g_malloc0 (sizeof (GameData));
app_data = g_malloc (sizeof (AppData));
+
+ handle_paste_closure = g_cclosure_new (G_CALLBACK (handle_paste),
+ app_data,
+ NULL);
+
+ /* This accelerator group gets activated by handle_key_press. */
+ accel_group = gtk_accel_group_new ();
+ gtk_accelerator_parse ("<Control>v", &accel_key, &accel_mods);
+ gtk_accel_group_connect (accel_group,
+ accel_key,
+ accel_mods,
+ 0,
+ handle_paste_closure);
+ gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
+
app_data->game_data = game_data;
app_data->guessed = GTK_LABEL (guessed);
app_data->gallow = gallow;
app_data->input_method = input_method;
+ app_data->accel_group = accel_group;
new_game (app_data);