+void
+force_char_input_from_queue(winid_t win, event_t *event)
+{
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+ guint keyval = GPOINTER_TO_UINT(g_async_queue_pop(glk_data->char_input_queue));
+
+ glk_cancel_char_event(win);
+
+ gdk_threads_enter();
+ ChimaraGlk *glk = CHIMARA_GLK(gtk_widget_get_ancestor(win->widget, CHIMARA_TYPE_GLK));
+ g_assert(glk);
+ g_signal_emit_by_name(glk, "char-input", win->rock, keyval);
+ gdk_threads_leave();
+
+ event->type = evtype_CharInput;
+ event->win = win;
+ event->val1 = keyval_to_glk_keycode(keyval, win->input_request_type == INPUT_REQUEST_CHARACTER_UNICODE);
+ event->val2 = 0;
+}
+
+void
+force_line_input_from_queue(winid_t win, event_t *event)
+{
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+ const gchar *text = g_async_queue_pop(glk_data->line_input_queue);
+ glui32 chars_written = 0;
+
+ gdk_threads_enter();
+ if(win->type == wintype_TextBuffer)
+ {
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) );
+ GtkTextIter start, end;
+
+ /* Remove signal handlers so the line input doesn't get picked up again */
+ g_signal_handler_block(buffer, win->insert_text_handler);
+ g_signal_handler_block(win->widget, win->line_input_keypress_handler);
+
+ /* Erase any text that was already typed */
+ GtkTextMark *input_position = gtk_text_buffer_get_mark(buffer, "input_position");
+ gtk_text_buffer_get_iter_at_mark(buffer, &start, input_position);
+ gtk_text_buffer_get_end_iter(buffer, &end);
+ gtk_text_buffer_delete(buffer, &start, &end);
+
+ /* Make the window uneditable again */
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(win->widget), FALSE);
+
+ /* Insert the forced input into the window */
+ gtk_text_buffer_get_end_iter(buffer, &end);
+ gchar *text_to_insert = g_strconcat(text, "\n", NULL);
+ gtk_text_buffer_insert_with_tags_by_name(buffer, &end, text_to_insert, -1, "input", NULL);
+ chars_written = finish_text_buffer_line_input(win, TRUE);
+ }
+ else if(win->type == wintype_TextGrid)
+ {
+ /* Remove signal handlers so the line input doesn't get picked up again */
+ g_signal_handler_block(win->widget, win->char_input_keypress_handler);
+
+ /* Insert the forced input into the window */
+ gtk_entry_set_text(GTK_ENTRY(win->input_entry), text);
+ chars_written = finish_text_grid_line_input(win, TRUE);
+ }
+ gdk_threads_leave();
+
+ event->type = evtype_LineInput;
+ event->win = win;
+ event->val1 = chars_written;
+ event->val2 = 0;
+}
+
+/*** Internal function: cancels any pending input requests on the window and presents a warning if not INPUT_REQUEST_NONE ***/
+void
+cancel_old_input_request(winid_t win)
+{
+ switch(win->input_request_type) {
+ case INPUT_REQUEST_NONE:
+ break; /* All is well */
+ case INPUT_REQUEST_CHARACTER:
+ case INPUT_REQUEST_CHARACTER_UNICODE:
+ glk_cancel_char_event(win);
+ WARNING("Cancelling pending char event");
+ break;
+ case INPUT_REQUEST_LINE:
+ case INPUT_REQUEST_LINE_UNICODE:
+ glk_cancel_line_event(win, NULL);
+ WARNING("Cancelling pending line event");
+ break;
+ default:
+ WARNING("Could not cancel pending input request: unknown input request");
+ }
+}