- /* Set the entire contents of the window_buffer as uneditable
- * (so input can only be entered at the end) */
- GtkTextIter start_iter;
- gtk_text_buffer_get_start_iter(buffer, &start_iter);
- gtk_text_buffer_remove_tag_by_name(buffer, "uneditable", &start_iter, &end_iter);
- gtk_text_buffer_apply_tag_by_name(buffer, "uneditable", &start_iter, &end_iter);
-
- /* Insert pre-entered text if needed */
- if(insert)
- gtk_text_buffer_insert(buffer, &end_iter, inserttext, -1);
-
- /* Scroll to input point */
- gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(win->widget), input_position);
-
- gtk_text_view_set_editable(GTK_TEXT_VIEW(win->widget), TRUE);
- g_signal_handler_unblock(buffer, win->insert_text_handler);
- }
+ /* Determine the maximum length of the line input */
+ gint cursorpos = gtk_text_iter_get_line_offset(&start_iter);
+ /* Odd; the Glk spec says the maximum input length is
+ windowwidth - 1 - cursorposition. I say no, because if cursorposition is
+ zero, then the input should fill the whole line. FIXME??? */
+ win->input_length = MIN(win->width - cursorpos, win->line_input_buffer_max_len);
+ 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);
+ win->input_entry = gtk_entry_new();
+ /* Set the entry's font to match that of the window */
+ GtkRcStyle *style = gtk_widget_get_modifier_style(win->widget); /* Don't free */
+ gtk_widget_modify_font(win->input_entry, style->font_desc);
+ /* Make the entry as small as possible to fit with the text */
+ gtk_entry_set_has_frame(GTK_ENTRY(win->input_entry), FALSE);
+ GtkBorder border = { 0, 0, 0, 0 };
+ gtk_entry_set_inner_border(GTK_ENTRY(win->input_entry), &border);
+ gtk_entry_set_max_length(GTK_ENTRY(win->input_entry), win->input_length);
+ gtk_entry_set_width_chars(GTK_ENTRY(win->input_entry), win->input_length);
+
+ /* Insert pre-entered text if needed */
+ if(insert)
+ gtk_entry_set_text(GTK_ENTRY(win->input_entry), inserttext);
+
+ /* Set background color of entry (TODO: implement as property) */
+ GdkColor background;
+ gdk_color_parse("grey", &background);
+ gtk_widget_modify_base(win->input_entry, GTK_STATE_NORMAL, &background);
+
+ g_signal_connect(win->input_entry, "activate", G_CALLBACK(on_input_entry_activate), win);
+
+ 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. */
+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) );
+
+ /* Move the input_position mark to the end of the window_buffer */
+ GtkTextMark *input_position = gtk_text_buffer_get_mark(buffer, "input_position");
+ GtkTextIter end_iter;
+ gtk_text_buffer_get_end_iter(buffer, &end_iter);
+ gtk_text_buffer_move_mark(buffer, input_position, &end_iter);
+
+ /* Set the entire contents of the window_buffer as uneditable
+ * (so input can only be entered at the end) */
+ GtkTextIter start_iter;
+ gtk_text_buffer_get_start_iter(buffer, &start_iter);
+ gtk_text_buffer_remove_tag_by_name(buffer, "uneditable", &start_iter, &end_iter);
+ gtk_text_buffer_apply_tag_by_name(buffer, "uneditable", &start_iter, &end_iter);
+
+ /* Insert pre-entered text if needed */
+ if(insert)
+ gtk_text_buffer_insert(buffer, &end_iter, inserttext, -1);
+
+ /* Scroll to input point */
+ gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(win->widget), input_position);
+
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(win->widget), TRUE);
+ g_signal_handler_unblock(buffer, win->insert_text_handler);