diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index e91fcfb3..3e275e34 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -65,6 +65,8 @@ static void entry_text_grow(GUI_ENTRY_REC *entry, int grow_size) entry->text_alloc = nearest_power(entry->text_alloc+grow_size); entry->text = g_realloc(entry->text, sizeof(unichar) * entry->text_alloc); + entry->colors = g_realloc(entry->colors, + sizeof(int) * entry->text_alloc); } GUI_ENTRY_REC *gui_entry_create(int xpos, int ypos, int width, int utf8) @@ -74,11 +76,12 @@ GUI_ENTRY_REC *gui_entry_create(int xpos, int ypos, int width, int utf8) rec = g_new0(GUI_ENTRY_REC, 1); rec->xpos = xpos; rec->ypos = ypos; - rec->width = width; - rec->text_alloc = 1024; + rec->width = width; + rec->text_alloc = 1024; rec->text = g_new(unichar, rec->text_alloc); - rec->text[0] = '\0'; - rec->utf8 = utf8; + rec->colors = g_new(int, rec->text_alloc); + rec->text[0] = '\0'; + rec->utf8 = utf8; return rec; } @@ -100,9 +103,10 @@ void gui_entry_destroy(GUI_ENTRY_REC *entry) } g_slist_free(entry->kill_ring); - g_free(entry->text); + g_free(entry->text); + g_free(entry->colors); g_free(entry->prompt); - g_free(entry); + g_free(entry); } /* big5 functions */ @@ -238,7 +242,8 @@ static void gui_entry_fix_cursor(GUI_ENTRY_REC *entry) static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) { int i; - int xpos, end_xpos; + const int *col; + int xpos, end_xpos, color; xpos = entry->xpos + entry->promptlen + pos2scrpos(entry, pos + entry->scrstart) - @@ -248,10 +253,13 @@ static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) if (xpos > end_xpos) return; + color = ATTR_RESET; term_set_color(root_window, ATTR_RESET); term_move(root_window, xpos, entry->ypos); - for (i = entry->scrstart + pos; i < entry->text_len; i++) { + col = entry->scrstart + pos < entry->text_len ? + entry->colors + entry->scrstart + pos : 0; + for (i = entry->scrstart + pos; i < entry->text_len; i++, col++) { unichar c = entry->text[i]; if (entry->hidden) @@ -266,6 +274,11 @@ static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) if (xpos > end_xpos) break; + if (*col != color) { + term_set_color(root_window, *col); + color = *col; + } + if (entry->hidden) term_addch(root_window, ' '); else if (unichar_isprint(c)) @@ -273,7 +286,7 @@ static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) else { term_set_color(root_window, ATTR_RESET|ATTR_REVERSE); term_addch(root_window, (c & 127)+'A'-1); - term_set_color(root_window, ATTR_RESET); + term_set_color(root_window, color); } } @@ -488,6 +501,10 @@ void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str) g_memmove(entry->text + entry->pos + len, entry->text + entry->pos, (entry->text_len-entry->pos + 1) * sizeof(unichar)); + /* make space for the color */ + g_memmove(entry->colors + entry->pos + len, entry->colors + entry->pos, + (entry->text_len-entry->pos) * sizeof(int)); + if (!entry->utf8) { if (term_type == TERM_TYPE_BIG5) { chr = entry->text[entry->pos + len]; @@ -505,6 +522,10 @@ void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str) } } + for(i = 0; i < len; i++) { + entry->colors[entry->pos + i] = ATTR_RESET; + } + entry->text_len += len; entry->pos += len; @@ -514,7 +535,7 @@ void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str) void gui_entry_insert_char(GUI_ENTRY_REC *entry, unichar chr) { - g_return_if_fail(entry != NULL); + g_return_if_fail(entry != NULL); if (chr == 0 || chr == 13 || chr == 10) return; /* never insert NUL, CR or LF characters */ @@ -522,7 +543,7 @@ void gui_entry_insert_char(GUI_ENTRY_REC *entry, unichar chr) if (entry->utf8 && entry->pos == 0 && mk_wcwidth(chr) == 0) return; - gui_entry_redraw_from(entry, entry->pos); + gui_entry_redraw_from(entry, entry->pos); entry_text_grow(entry, 1); @@ -530,9 +551,14 @@ void gui_entry_insert_char(GUI_ENTRY_REC *entry, unichar chr) g_memmove(entry->text + entry->pos + 1, entry->text + entry->pos, (entry->text_len-entry->pos + 1) * sizeof(unichar)); + g_memmove(entry->colors + entry->pos + 1, entry->colors + entry->pos, + (entry->text_len-entry->pos) * sizeof(int)); + + entry->text[entry->pos] = chr; + entry->colors[entry->pos] = ATTR_RESET; entry->text_len++; - entry->pos++; + entry->pos++; gui_entry_fix_cursor(entry); gui_entry_draw(entry); @@ -700,6 +726,9 @@ void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_ g_memmove(entry->text + entry->pos - size, entry->text + entry->pos, (entry->text_len-entry->pos+1) * sizeof(unichar)); + g_memmove(entry->colors + entry->pos - size, entry->colors + entry->pos, + (entry->text_len - entry->pos) * sizeof(int)); + entry->pos -= size; entry->text_len -= size; @@ -719,7 +748,10 @@ void gui_entry_erase_cell(GUI_ENTRY_REC *entry) mk_wcwidth(entry->text[entry->pos+size]) == 0) size++; g_memmove(entry->text + entry->pos, entry->text + entry->pos + size, - (entry->text_len-entry->pos-size+1) * sizeof(unichar)); + (entry->text_len-entry->pos-size+1) * sizeof(unichar)); + + g_memmove(entry->colors + entry->pos, entry->colors + entry->pos + size, + (entry->text_len-entry->pos-size) * sizeof(int)); entry->text_len -= size; @@ -782,6 +814,7 @@ void gui_entry_erase_next_word(GUI_ENTRY_REC *entry, int to_space, CUTBUFFER_UPD void gui_entry_transpose_chars(GUI_ENTRY_REC *entry) { unichar chr; + int color; if (entry->pos == 0 || entry->text_len < 2) return; @@ -794,6 +827,10 @@ void gui_entry_transpose_chars(GUI_ENTRY_REC *entry) entry->text[entry->pos] = entry->text[entry->pos-1]; entry->text[entry->pos-1] = chr; + color = entry->colors[entry->pos]; + entry->colors[entry->pos] = entry->colors[entry->pos-1]; + entry->colors[entry->pos-1] = color; + entry->pos++; gui_entry_redraw_from(entry, entry->pos-2); @@ -830,31 +867,55 @@ void gui_entry_transpose_words(GUI_ENTRY_REC *entry) /* do wordswap if any found */ if (spos1 < epos1 && epos1 < spos2 && spos2 < epos2) { unichar *first, *sep, *second; + int *first_color, *sep_color, *second_color; int i; first = (unichar *) g_malloc( (epos1 - spos1) * sizeof(unichar) ); sep = (unichar *) g_malloc( (spos2 - epos1) * sizeof(unichar) ); second = (unichar *) g_malloc( (epos2 - spos2) * sizeof(unichar) ); - for (i = spos1; i < epos1; i++) + first_color = (int *) g_malloc( (epos1 - spos1) * sizeof(int) ); + sep_color = (int *) g_malloc( (spos2 - epos1) * sizeof(int) ); + second_color = (int *) g_malloc( (epos2 - spos2) * sizeof(int) ); + + for (i = spos1; i < epos1; i++) { first[i-spos1] = entry->text[i]; - for (i = epos1; i < spos2; i++) + first_color[i-spos1] = entry->colors[i]; + } + for (i = epos1; i < spos2; i++) { sep[i-epos1] = entry->text[i]; - for (i = spos2; i < epos2; i++) + sep_color[i-epos1] = entry->colors[i]; + } + for (i = spos2; i < epos2; i++) { second[i-spos2] = entry->text[i]; + second_color[i-spos2] = entry->colors[i]; + } entry->pos = spos1; - for (i = 0; i < epos2-spos2; i++) - entry->text[entry->pos++] = second[i]; - for (i = 0; i < spos2-epos1; i++) - entry->text[entry->pos++] = sep[i]; - for (i = 0; i < epos1-spos1; i++) - entry->text[entry->pos++] = first[i]; + for (i = 0; i < epos2-spos2; i++) { + entry->text[entry->pos] = second[i]; + entry->colors[entry->pos] = second_color[i]; + entry->pos++; + } + for (i = 0; i < spos2-epos1; i++) { + entry->text[entry->pos] = sep[i]; + entry->colors[entry->pos] = sep_color[i]; + entry->pos++; + } + for (i = 0; i < epos1-spos1; i++) { + entry->text[entry->pos] = first[i]; + entry->colors[entry->pos] = first_color[i]; + entry->pos++; + } g_free(first); g_free(sep); g_free(second); + g_free(first_color); + g_free(sep_color); + g_free(second_color); + } gui_entry_redraw_from(entry, spos1); @@ -1042,3 +1103,31 @@ void gui_entry_redraw(GUI_ENTRY_REC *entry) gui_entry_fix_cursor(entry); gui_entry_draw(entry); } + +void gui_entry_set_color(GUI_ENTRY_REC *entry, int pos, int len, int color) +{ + int i, end, update = 0; + + g_return_if_fail(entry != NULL); + + if (pos > entry->text_len) + return; + + end = pos + len; + + if (end > entry->text_len) + end = entry->text_len; + + for (i = pos; i < end; i++) { + if (entry->colors[i] != color) { + entry->colors[i] = color; + update = 1; + } + } + + if (update) { + gui_entry_redraw_from(entry, pos); + gui_entry_fix_cursor(entry); + gui_entry_draw(entry); + } +} diff --git a/src/fe-text/gui-entry.h b/src/fe-text/gui-entry.h index 000c5f03..18cc5a4d 100644 --- a/src/fe-text/gui-entry.h +++ b/src/fe-text/gui-entry.h @@ -9,6 +9,7 @@ typedef struct { typedef struct { int text_len, text_alloc; /* as shorts, not chars */ unichar *text; + int *colors; GSList *kill_ring; @@ -77,5 +78,6 @@ void gui_entry_move_words(GUI_ENTRY_REC *entry, int count, int to_space); void gui_entry_redraw(GUI_ENTRY_REC *entry); +void gui_entry_set_color(GUI_ENTRY_REC *entry, int pos, int len, int color); #endif diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs index 12732e3f..02ef6c73 100644 --- a/src/perl/textui/TextUI.xs +++ b/src/perl/textui/TextUI.xs @@ -124,6 +124,14 @@ gui_input_set(str) CODE: gui_entry_set_text(active_entry, str); +void +gui_input_color(pos, len, color) + int pos + int len + int color +CODE: + gui_entry_set_color(active_entry, pos, len, color); + int gui_input_get_pos() CODE: