* cancel_line_input_event now handles an NULL event parameter correctly
[rodin/chimara.git] / src / input.c
index 394a635ab62b1e928121e46190adec9195a1d213..81b1664cfc161b530175821f9c0ecaf0b9e3f90d 100644 (file)
@@ -276,29 +276,33 @@ glk_request_line_event_uni(winid_t win, glui32 *buf, glui32 maxlen, glui32 initl
 void
 glk_cancel_line_event(winid_t win, event_t *event)
 {
-       /* TODO: write me */
        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);
 
-       event->type = evtype_None;
-       event->win = win;
-       event->val1 = 0;
-       event->val2 = 0;
+       if(event != NULL) {
+               event->type = evtype_None;
+               event->win = win;
+               event->val1 = 0;
+               event->val2 = 0;
+       }
+
+       if(win->input_request_type == INPUT_REQUEST_NONE)
+               return;
 
        g_signal_handler_block( G_OBJECT(win->widget), win->keypress_handler );
 
+       int chars_written = 0;
+
        if(win->type == wintype_TextGrid) {
-               /* No possible input, we're done here */
-               return;
+               g_signal_handler_block( G_OBJECT(win->widget), win->keypress_handler );
+               chars_written = flush_text_grid(win);
+       } else if(win->type == wintype_TextBuffer) {
+               GtkTextBuffer *window_buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) );
+               g_signal_handler_block(window_buffer, win->insert_text_handler);
+               chars_written = flush_text_buffer(win);
        }
 
-       GtkTextBuffer *window_buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) );
-       g_signal_handler_block(window_buffer, win->insert_text_handler);
-
-       /* Retrieve possible input */
-       int chars_written = flush_text_buffer(win);
-       if(chars_written > 0) {
+       if(event != NULL && chars_written > 0) {
                event->type = evtype_LineInput;
                event->val1 = chars_written;
        }
@@ -449,21 +453,65 @@ flush_text_buffer(winid_t win)
        VALID_WINDOW(win, return 0);
        g_return_val_if_fail(win->type == wintype_TextBuffer, 0);
 
-       GtkTextIter start_iter, end_iter;
+       GtkTextIter start_iter, end_iter, last_character;
 
        GtkTextBuffer *window_buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) );
        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 */
-       
+       gtk_text_buffer_get_end_iter(window_buffer, &last_character);
+       gtk_text_iter_backward_cursor_position(&last_character);
+
+       gchar* last_char = gtk_text_buffer_get_text(window_buffer, &last_character, &end_iter, FALSE);
+
+       if( strchr(last_char, '\n') != NULL )
+               gtk_text_iter_backward_cursor_position(&end_iter);
+
        gchar* inserted_text = gtk_text_buffer_get_text(window_buffer, &start_iter, &end_iter, FALSE);
+
        int chars_written = write_to_window_buffer(win, inserted_text);
        g_free(inserted_text);
 
        return chars_written;
 }
 
+/* Internal function: Retrieves the input of a TextGrid window and stores it in the window buffer.
+ * Returns the number of characters written, suitable for inclusion in a line input event. */
+static int
+flush_text_grid(winid_t win)
+{
+       VALID_WINDOW(win, return 0);
+       g_return_val_if_fail(win->type == wintype_TextBuffer, 0);
+
+       GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) );
+       
+       gchar *text = g_strdup( gtk_entry_get_text(GTK_ENTRY(win->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(win->input_entry) );
+       win->input_entry = NULL;
+       /* Delete the child anchor */
+       GtkTextIter start, end;
+       gtk_text_buffer_get_iter_at_child_anchor(buffer, &start, win->input_anchor);
+       end = start;
+       gtk_text_iter_forward_char(&end); /* Point after the child anchor */
+       gtk_text_buffer_delete(buffer, &start, &end);
+       win->input_anchor = NULL;
+       
+    gchar *spaces = g_strnfill(win->input_length - g_utf8_strlen(text, -1), ' ');
+    gchar *text_to_insert = g_strconcat(text, spaces, NULL);
+       g_free(spaces);
+    gtk_text_buffer_insert(buffer, &start, text_to_insert, -1);
+    g_free(text_to_insert);
+    
+    int chars_written = write_to_window_buffer(win, text);
+       g_free(text);
+
+       return chars_written;
+}
+
 /* Internal function: Callback for signal insert-text on a text buffer window.
 Runs after the default handler has already inserted the text.
 FIXME: This function assumes that newline was the last character typed into the
@@ -491,33 +539,9 @@ in a text grid window. */
 void
 on_input_entry_activate(GtkEntry *input_entry, winid_t win)
 {
-       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) );
-       win->input_entry = NULL;
-       /* Delete the child anchor */
-       GtkTextIter start, end;
-       gtk_text_buffer_get_iter_at_child_anchor(buffer, &start, win->input_anchor);
-       end = start;
-       gtk_text_iter_forward_char(&end); /* Point after the child anchor */
-       gtk_text_buffer_delete(buffer, &start, &end);
-       win->input_anchor = NULL;
-       
-    gchar *spaces = g_strnfill(win->input_length - g_utf8_strlen(text, -1), ' ');
-    gchar *text_to_insert = g_strconcat(text, spaces, NULL);
-       g_free(spaces);
-    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 );
-       
-    int chars_written = write_to_window_buffer(win, text);
+
+       int chars_written = flush_text_grid(win);
        event_throw(evtype_LineInput, win, chars_written, 0);
-       g_free(text);
 }