+#include "charset.h"
#include "input.h"
-/** glk_request_char_event:
+/**
+ * glk_request_char_event:
* @win: A window to request char events from.
*
* Request input of a Latin-1 character or special key. A window cannot have
g_signal_handler_unblock( G_OBJECT(win->widget), win->keypress_handler );
}
-/** glk_request_char_event_uni:
+/**
+ * glk_request_char_event_uni:
* @win: A window to request char events from.
*
* Request input of a Unicode character or special key. See
gtk_widget_show(win->input_entry);
gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(win->widget), win->input_entry, win->input_anchor);
+
+ g_signal_handler_unblock( G_OBJECT(win->widget), win->keypress_handler );
}
/* Internal function: Request either latin-1 or unicode line input, in a text buffer window. */
gchar *utf8;
if(initlen > 0) {
- GError *error = NULL;
- utf8 = g_ucs4_to_utf8(buf, initlen, NULL, NULL, &error);
-
+ utf8 = convert_ucs4_to_utf8(buf, initlen);
if(utf8 == NULL)
- {
- g_warning("Error during unicode->utf8 conversion: %s", error->message);
return;
- }
}
else
utf8 = g_strdup("");
g_free(utf8);
}
-/* Internal function: Callback for signal key-press-event on a text buffer or text grid window. */
+/* Internal function: General callback for signal key-press-event on a text buffer or text grid window. Used in character input on both text buffers and grids, and also in line input on grids, to redirect keystrokes to the line input field. Blocked when not in use. */
gboolean
on_window_key_press_event(GtkWidget *widget, GdkEventKey *event, winid_t win)
-{
+{
+ /* If this is a text grid window, and line input is active, then redirect the key press to the line input GtkEntry */
+ if( win->type == wintype_TextGrid && (win->input_request_type == INPUT_REQUEST_LINE || win->input_request_type == INPUT_REQUEST_LINE_UNICODE) )
+ {
+ if(event->keyval == GDK_Up || event->keyval == GDK_KP_Up
+ || event->keyval == GDK_Down || event->keyval == GDK_KP_Down
+ || event->keyval == GDK_Left || event->keyval == GDK_KP_Left
+ || event->keyval == GDK_Right || event->keyval == GDK_KP_Right
+ || event->keyval == GDK_Tab || event->keyval == GDK_KP_Tab
+ || event->keyval == GDK_Page_Up || event->keyval == GDK_KP_Page_Up
+ || event->keyval == GDK_Page_Down || event->keyval == GDK_KP_Page_Down
+ || event->keyval == GDK_Home || event->keyval == GDK_KP_Home
+ || event->keyval == GDK_End || event->keyval == GDK_KP_End)
+ return FALSE; /* Don't redirect these keys */
+ gtk_widget_grab_focus(win->input_entry);
+ gtk_editable_set_position(GTK_EDITABLE(win->input_entry), -1);
+ gboolean retval = TRUE;
+ g_signal_emit_by_name(win->input_entry, "key-press-event", event, &retval);
+ return retval; /* Block this key event if the entry handled it */
+ }
if(win->input_request_type != INPUT_REQUEST_CHARACTER &&
win->input_request_type != INPUT_REQUEST_CHARACTER_UNICODE)
return FALSE;
/* Convert the string from UTF-8 to Latin-1 or Unicode */
if(win->input_request_type == INPUT_REQUEST_LINE)
{
- GError *error = NULL;
- gchar *latin1;
gsize bytes_written;
- latin1 = g_convert_with_fallback(inserted_text, -1, "ISO-8859-1", "UTF-8", "?", NULL, &bytes_written, &error);
+ gchar *latin1 = convert_utf8_to_latin1(inserted_text, &bytes_written);
if(latin1 == NULL)
{
- g_warning("Error during utf8->latin1 conversion: %s", error->message);
event_throw(evtype_LineInput, win, 0, 0);
return;
}
}
else if(win->input_request_type == INPUT_REQUEST_LINE_UNICODE)
{
- gunichar *unicode;
glong items_written;
- unicode = g_utf8_to_ucs4_fast(inserted_text, -1, &items_written);
+ gunichar *unicode = convert_utf8_to_ucs4(inserted_text, &items_written);
if(unicode == NULL)
{
- g_warning("Error during utf8->unicode conversion");
event_throw(evtype_LineInput, win, 0, 0);
return;
}
/* Place input in the echo stream */
- /* TODO: glk_put_string_stream_uni not implemented yet
if(win->echo_stream != NULL)
- glk_put_string_stream_uni(window->echo_stream, unicode);*/
+ glk_put_string_stream_uni(win->echo_stream, unicode);
/* Copy the string (but not the NULL at the end) */
int copycount = MIN(win->line_input_buffer_max_len, items_written);
}
/* Internal function: Callback for signal insert-text on a text buffer window.
-Runs after the default handler has already inserted the text.*/
+Runs after the default handler has already inserted the text.
+FIXME: This function assumes that newline was the last character typed into the
+window. That assumption is wrong if, for example, text containing a newline was
+pasted into the window. */
void
after_window_insert_text(GtkTextBuffer *textbuffer, GtkTextIter *location, gchar *text, gint len, winid_t win)
{
GtkTextMark *input_position = gtk_text_buffer_get_mark(window_buffer, "input_position");
gtk_text_buffer_get_iter_at_mark(window_buffer, &start_iter, input_position);
gtk_text_buffer_get_end_iter(window_buffer, &end_iter);
+ gtk_text_iter_backward_cursor_position(&end_iter); /* don't include \n */
inserted_text = gtk_text_buffer_get_text(window_buffer, &start_iter, &end_iter, FALSE);
GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) );
gchar *text = g_strdup(gtk_entry_get_text(input_entry));
-
+ /* Move the focus back into the text view */
+ gtk_widget_grab_focus(win->widget);
/* Remove entry widget from text view */
/* Should be ok even though this is the widget's own signal handler */
gtk_container_remove( GTK_CONTAINER(win->widget), GTK_WIDGET(input_entry) );
gtk_text_buffer_insert(buffer, &start, text_to_insert, -1);
g_free(text_to_insert);
+ g_signal_handler_block( G_OBJECT(win->widget), win->keypress_handler );
+
end_line_input_request(win, text);
g_free(text);
}
+