X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=src%2Fstrio.c;h=974a1099b79f0f1005a4e75f95245e2c08e69f55;hb=e7b655fa76e4a42b1a0228bd7e9290998a1fbeae;hp=de6ccb48f5ed9057cb15dd5606078b7b527a1a77;hpb=49eca40060b04105343874714fa67976b9430def;p=rodin%2Fchimara.git diff --git a/src/strio.c b/src/strio.c index de6ccb4..974a109 100644 --- a/src/strio.c +++ b/src/strio.c @@ -4,8 +4,6 @@ #include #include -#define min(x,y) ( (x > y)? y : x ) - /* * **************** WRITING FUNCTIONS ******************************************** @@ -48,21 +46,62 @@ convert_latin1_to_utf8(gchar *s, gsize len) if(utf8 == NULL) { - error_dialog(NULL, error, "Error during latin1->utf8 conversion: "); + g_warning("Error during latin1->utf8 conversion: %s", error->message); return NULL; } return utf8; } -/* Internal function: write a UTF-8 string to a window's text buffer. */ +/* Internal function: write a UTF-8 string to a text grid window's text buffer. */ +static void +write_utf8_to_grid(winid_t win, gchar *s) +{ + /* Number of characters to insert */ + glong length = g_utf8_strlen(s, -1); + glong chars_left = length; + + gdk_threads_enter(); + + GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) ); + GtkTextMark *cursor = gtk_text_buffer_get_mark(buffer, "cursor_position"); + + /* Get cursor position */ + GtkTextIter start; + gtk_text_buffer_get_iter_at_mark(buffer, &start, cursor); + /* Spaces available on this line */ + gint available_space = win->width - gtk_text_iter_get_line_offset(&start); + + while(chars_left > available_space && !gtk_text_iter_is_end(&start)) + { + GtkTextIter end = start; + gtk_text_iter_forward_to_line_end(&end); + gtk_text_buffer_delete(buffer, &start, &end); + gtk_text_buffer_insert(buffer, &start, s + (length - chars_left), available_space); + chars_left -= available_space; + gtk_text_iter_forward_line(&start); + available_space = win->width; + } + if(!gtk_text_iter_is_end(&start)) + { + GtkTextIter end = start; + gtk_text_iter_forward_chars(&end, chars_left); + gtk_text_buffer_delete(buffer, &start, &end); + gtk_text_buffer_insert(buffer, &start, s + (length - chars_left), -1); + } + + gtk_text_buffer_move_mark(buffer, cursor, &start); + + gdk_threads_leave(); +} + +/* Internal function: write a UTF-8 string to a text buffer window's text buffer. */ static void write_utf8_to_window(winid_t win, gchar *s) { gdk_threads_enter(); - GtkTextBuffer *buffer = - gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) ); + GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) ); GtkTextIter iter; gtk_text_buffer_get_end_iter(buffer, &iter); @@ -71,15 +110,15 @@ write_utf8_to_window(winid_t win, gchar *s) gdk_threads_leave(); } -/* Internal function: write a UTF-8 buffer with length to a stream. */ +/* Internal function: write a Latin-1 buffer with length to a stream. */ static void write_buffer_to_stream(strid_t str, gchar *buf, glui32 len) { - switch(str->stream_type) + switch(str->type) { case STREAM_TYPE_WINDOW: /* Each window type has a different way of printing to it */ - switch(str->window->window_type) + switch(str->window->type) { /* Printing to these windows' streams does nothing */ case wintype_Blank: @@ -87,6 +126,21 @@ write_buffer_to_stream(strid_t str, gchar *buf, glui32 len) case wintype_Graphics: str->write_count += len; break; + + /* Text grid window */ + case wintype_TextGrid: + { + gchar *utf8 = convert_latin1_to_utf8(buf, len); + if(utf8) + { + /* FIXME: What to do if string contains \n? Split the input string at newlines and write each string separately? */ + write_utf8_to_grid(str->window, utf8); + g_free(utf8); + } + } + str->write_count += len; + break; + /* Text buffer window */ case wintype_TextBuffer: { @@ -100,8 +154,7 @@ write_buffer_to_stream(strid_t str, gchar *buf, glui32 len) str->write_count += len; break; default: - g_warning("%s: Writing to this kind of window unsupported.", - __func__); + g_warning("%s: Writing to this kind of window unsupported.", __func__); } /* Now write the same buffer to the window's echo stream */ @@ -119,7 +172,7 @@ write_buffer_to_stream(strid_t str, gchar *buf, glui32 len) } if(!str->unicode && str->buffer) { - int copycount = min(len, str->buflen - str->mark); + int copycount = MIN(len, str->buflen - str->mark); memmove(str->buffer + str->mark, buf, copycount); str->mark += copycount; } @@ -155,8 +208,7 @@ write_buffer_to_stream(strid_t str, gchar *buf, glui32 len) str->write_count += len; break; default: - g_warning("%s: Writing to this kind of stream unsupported.", - __func__); + g_warning("%s: Writing to this kind of stream unsupported.", __func__); } } @@ -299,10 +351,9 @@ glsi32 glk_get_char_stream(strid_t str) { g_return_val_if_fail(str != NULL, -1); - g_return_val_if_fail(str->file_mode == filemode_Read - || str->file_mode == filemode_ReadWrite, -1); + g_return_val_if_fail(str->file_mode == filemode_Read || str->file_mode == filemode_ReadWrite, -1); - switch(str->stream_type) + switch(str->type) { case STREAM_TYPE_MEMORY: if(str->unicode) @@ -354,8 +405,7 @@ glk_get_char_stream(strid_t str) return (ch > 0xFF)? 0x3F : ch; } default: - g_warning("%s: Reading from this kind of stream unsupported.", - __func__); + g_warning("%s: Reading from this kind of stream unsupported.", __func__); return -1; } } @@ -375,19 +425,17 @@ glui32 glk_get_buffer_stream(strid_t str, char *buf, glui32 len) { g_return_val_if_fail(str != NULL, 0); - g_return_val_if_fail(str->file_mode == filemode_Read - || str->file_mode == filemode_ReadWrite, 0); + g_return_val_if_fail(str->file_mode == filemode_Read || str->file_mode == filemode_ReadWrite, 0); g_return_val_if_fail(buf != NULL, 0); - switch(str->stream_type) + switch(str->type) { case STREAM_TYPE_MEMORY: { int copycount = 0; if(str->unicode) { - while(copycount < len && str->ubuffer - && str->mark < str->buflen) + while(copycount < len && str->ubuffer && str->mark < str->buflen) { glui32 ch = str->ubuffer[str->mark++]; buf[copycount++] = (ch > 0xFF)? '?' : (char)ch; @@ -396,7 +444,7 @@ glk_get_buffer_stream(strid_t str, char *buf, glui32 len) else { if(str->buffer) /* if not, copycount stays 0 */ - copycount = min(len, str->buflen - str->mark); + copycount = MIN(len, str->buflen - str->mark); memmove(buf, str->buffer + str->mark, copycount); str->mark += copycount; } @@ -411,14 +459,12 @@ glk_get_buffer_stream(strid_t str, char *buf, glui32 len) { /* Read len characters of 4 bytes each */ unsigned char *readbuffer = g_new0(unsigned char, 4 * len); - size_t count = fread(readbuffer, sizeof(unsigned char), - 4 * len, str->file_pointer); + size_t count = fread(readbuffer, sizeof(unsigned char), 4 * len, str->file_pointer); /* If there was an incomplete character */ if(count % 4 != 0) { count -= count % 4; - g_warning("%s: Incomplete character in binary Unicode " - "file.", __func__); + g_warning("%s: Incomplete character in binary Unicode file.", __func__); } str->read_count += count / 4; @@ -436,8 +482,7 @@ glk_get_buffer_stream(strid_t str, char *buf, glui32 len) } else /* Regular binary file */ { - size_t count = fread(buf, sizeof(char), len, - str->file_pointer); + size_t count = fread(buf, sizeof(char), len, str->file_pointer); str->read_count += count; return count; } @@ -457,8 +502,7 @@ glk_get_buffer_stream(strid_t str, char *buf, glui32 len) return foo; } default: - g_warning("%s: Reading from this kind of stream unsupported.", - __func__); + g_warning("%s: Reading from this kind of stream unsupported.", __func__); return 0; } } @@ -484,11 +528,10 @@ glui32 glk_get_line_stream(strid_t str, char *buf, glui32 len) { g_return_val_if_fail(str != NULL, 0); - g_return_val_if_fail(str->file_mode == filemode_Read - || str->file_mode == filemode_ReadWrite, 0); + g_return_val_if_fail(str->file_mode == filemode_Read || str->file_mode == filemode_ReadWrite, 0); g_return_val_if_fail(buf != NULL, 0); - switch(str->stream_type) + switch(str->type) { case STREAM_TYPE_MEMORY: { @@ -496,14 +539,12 @@ glk_get_line_stream(strid_t str, char *buf, glui32 len) if(str->unicode) { /* Do it character-by-character */ - while(copycount < len - 1 && str->ubuffer - && str->mark < str->buflen) + while(copycount < len - 1 && str->ubuffer && str->mark < str->buflen) { glui32 ch = str->ubuffer[str->mark++]; /* Check for Unicode newline; slightly different than in file streams */ - if(ch == 0x0A || ch == 0x85 || ch == 0x0C || ch == 0x2028 - || ch == 0x2029) + if(ch == 0x0A || ch == 0x85 || ch == 0x0C || ch == 0x2028 || ch == 0x2029) { buf[copycount++] = '\n'; break; @@ -522,9 +563,8 @@ glk_get_line_stream(strid_t str, char *buf, glui32 len) else { if(str->buffer) /* if not, copycount stays 0 */ - copycount = min(len - 1, str->buflen - str->mark); - char *endptr = memccpy(buf, str->buffer + str->mark, '\n', - copycount); + copycount = MIN(len - 1, str->buflen - str->mark); + char *endptr = memccpy(buf, str->buffer + str->mark, '\n', copycount); if(endptr) /* newline was found */ copycount = endptr - buf; /* Real copy count */ buf[copycount] = '\0'; @@ -543,8 +583,7 @@ glk_get_line_stream(strid_t str, char *buf, glui32 len) int foo; for(foo = 0; foo < len - 1; foo++) { - glsi32 ch = - read_ucs4be_char_from_file(str->file_pointer); + glsi32 ch = read_ucs4be_char_from_file(str->file_pointer); if(ch == -1) { buf[foo] = '\0'; @@ -594,8 +633,7 @@ glk_get_line_stream(strid_t str, char *buf, glui32 len) return foo; } default: - g_warning("%s: Reading from this kind of stream unsupported.", - __func__); + g_warning("%s: Reading from this kind of stream unsupported.", __func__); return 0; } } @@ -631,7 +669,7 @@ glk_stream_get_position(strid_t str) { g_return_val_if_fail(str != NULL, 0); - switch(str->stream_type) + switch(str->type) { case STREAM_TYPE_MEMORY: return str->mark; @@ -683,7 +721,7 @@ glk_stream_set_position(strid_t str, glsi32 pos, glui32 seekmode) g_return_if_fail(!(seekmode == seekmode_Start && pos < 0)); g_return_if_fail(!(seekmode == seekmode_End || pos > 0)); - switch(str->stream_type) + switch(str->type) { case STREAM_TYPE_MEMORY: switch(seekmode) @@ -712,8 +750,7 @@ glk_stream_set_position(strid_t str, glsi32 pos, glui32 seekmode) break; } default: - g_warning("%s: Seeking not supported on this type of stream.", - __func__); + g_warning("%s: Seeking not supported on this type of stream.", __func__); return; } }