X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=src%2Finput.c;h=c5134192dfeb974489fc034e96be9ecea9aaf264;hb=24aef54d7203143092c9a7c91096c54494590851;hp=bcd5116757446413bcd6d48005e8b52c483eca74;hpb=cb5fe40c7b2a08bf11e9a90f055b4dd4510e66e6;p=rodin%2Fchimara.git diff --git a/src/input.c b/src/input.c index bcd5116..c513419 100644 --- a/src/input.c +++ b/src/input.c @@ -1,6 +1,9 @@ +#include "charset.h" +#include "magic.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 @@ -12,7 +15,7 @@ void glk_request_char_event(winid_t win) { - g_return_if_fail(win); + VALID_WINDOW(win, return); g_return_if_fail(win->input_request_type == INPUT_REQUEST_NONE); g_return_if_fail(win->type != wintype_TextBuffer || win->type != wintype_TextGrid); @@ -20,7 +23,8 @@ glk_request_char_event(winid_t win) 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 @@ -29,7 +33,7 @@ glk_request_char_event(winid_t win) void glk_request_char_event_uni(winid_t win) { - g_return_if_fail(win); + VALID_WINDOW(win, return); g_return_if_fail(win->input_request_type == INPUT_REQUEST_NONE); g_return_if_fail(win->type != wintype_TextBuffer || win->type != wintype_TextGrid); @@ -38,7 +42,7 @@ glk_request_char_event_uni(winid_t win) } /* Internal function: Request either latin-1 or unicode line input, in a text grid window. */ -void +static void text_grid_request_line_event_common(winid_t win, glui32 maxlen, gboolean insert, gchar *inserttext) { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) ); @@ -56,6 +60,17 @@ text_grid_request_line_event_common(winid_t win, glui32 maxlen, gboolean insert, end_iter = start_iter; gtk_text_iter_set_line_offset(&end_iter, cursorpos + win->input_length); + /* If the buffer currently has a selection with one bound in the middle of + the input field, then deselect it. Otherwise the input field gets trashed */ + GtkTextIter start_sel, end_sel; + if( gtk_text_buffer_get_selection_bounds(buffer, &start_sel, &end_sel) ) + { + if( gtk_text_iter_in_range(&start_sel, &start_iter, &end_iter) ) + gtk_text_buffer_place_cursor(buffer, &end_sel); + if( gtk_text_iter_in_range(&end_sel, &start_iter, &end_iter) ) + gtk_text_buffer_place_cursor(buffer, &start_sel); + } + /* Erase the text currently in the input field and replace it with a GtkEntry */ gtk_text_buffer_delete(buffer, &start_iter, &end_iter); win->input_anchor = gtk_text_buffer_create_child_anchor(buffer, &start_iter); @@ -88,7 +103,7 @@ text_grid_request_line_event_common(winid_t win, glui32 maxlen, gboolean insert, } /* Internal function: Request either latin-1 or unicode line input, in a text buffer window. */ -void +static void text_buffer_request_line_event_common(winid_t win, glui32 maxlen, gboolean insert, gchar *inserttext) { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) ); @@ -145,7 +160,7 @@ text_buffer_request_line_event_common(winid_t win, glui32 maxlen, gboolean inser void glk_request_line_event(winid_t win, char* buf, glui32 maxlen, glui32 initlen) { - g_return_if_fail(win); + VALID_WINDOW(win, return); g_return_if_fail(buf); g_return_if_fail(win->input_request_type == INPUT_REQUEST_NONE); g_return_if_fail(win->type != wintype_TextBuffer || win->type != wintype_TextGrid); @@ -164,8 +179,6 @@ glk_request_line_event(winid_t win, char* buf, glui32 maxlen, glui32 initlen) case wintype_TextGrid: text_grid_request_line_event_common(win, maxlen, (initlen > 0), inserttext); break; - default: - g_assert_not_reached(); } g_free(inserttext); } @@ -191,7 +204,7 @@ glk_request_line_event(winid_t win, char* buf, glui32 maxlen, glui32 initlen) void glk_request_line_event_uni(winid_t win, glui32 *buf, glui32 maxlen, glui32 initlen) { - g_return_if_fail(win); + VALID_WINDOW(win, return); g_return_if_fail(buf); g_return_if_fail(win->input_request_type == INPUT_REQUEST_NONE); g_return_if_fail(win->type != wintype_TextBuffer || win->type != wintype_TextGrid); @@ -203,14 +216,9 @@ glk_request_line_event_uni(winid_t win, glui32 *buf, glui32 maxlen, glui32 initl 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(""); @@ -223,8 +231,6 @@ glk_request_line_event_uni(winid_t win, glui32 *buf, glui32 maxlen, glui32 initl case wintype_TextGrid: text_grid_request_line_event_common(win, maxlen, (initlen > 0), utf8); break; - default: - g_assert_not_reached(); } g_free(utf8); } @@ -325,14 +331,11 @@ end_line_input_request(winid_t win, const gchar *inserted_text) /* 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; } @@ -349,21 +352,18 @@ end_line_input_request(winid_t win, const gchar *inserted_text) } 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); @@ -372,13 +372,16 @@ end_line_input_request(winid_t win, const gchar *inserted_text) event_throw(evtype_LineInput, win, copycount, 0); } else - g_warning("%s: Wrong input request type.", __func__); + WARNING("Wrong input request type"); win->input_request_type = INPUT_REQUEST_NONE; } /* 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) { @@ -396,6 +399,7 @@ after_window_insert_text(GtkTextBuffer *textbuffer, GtkTextIter *location, gchar 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); @@ -437,3 +441,4 @@ on_input_entry_activate(GtkEntry *input_entry, winid_t win) end_line_input_request(win, text); g_free(text); } +