1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-04-24 14:26:29 -05:00

Support longer pre-edit text

Now the pre-edit text is converted into a dynamically-allocated array of
termchars in term_set_preedit_text(), which slightly simplifies
do_paint().  This means that the long pre-edit generated by Ctrl+Shift+U
in GNOME now displays more or less properly.  I may need a better plan
for what to do about cursor positioning, though.
This commit is contained in:
Ben Harris 2025-04-02 10:06:22 +01:00
parent f9928fb7d5
commit 29ac4da8fb
2 changed files with 33 additions and 22 deletions

View File

@ -2096,8 +2096,6 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata, TermWin *win)
palette_reset(term, false); palette_reset(term, false);
term->preedit_char = -1;
return term; return term;
} }
@ -2162,6 +2160,8 @@ void term_free(Terminal *term)
if (term->userpass_state) if (term->userpass_state)
term_userpass_state_free(term->userpass_state); term_userpass_state_free(term->userpass_state);
sfree(term->preedit_termchars);
sfree(term); sfree(term);
} }
@ -6096,7 +6096,7 @@ static void do_paint(Terminal *term)
/* The normal screen data */ /* The normal screen data */
for (i = 0; i < term->rows; i++) { for (i = 0; i < term->rows; i++) {
termline *ldata; termline *ldata;
termchar *lchars, preedit_termchars[2]; termchar *lchars;
bool dirty_line, dirty_run, selected; bool dirty_line, dirty_run, selected;
unsigned long attr = 0, cset = 0; unsigned long attr = 0, cset = 0;
int start = 0; int start = 0;
@ -6106,7 +6106,7 @@ static void do_paint(Terminal *term)
bool dirtyrect; bool dirtyrect;
int *backward; int *backward;
truecolour tc; truecolour tc;
int preedit_width = 0, preedit_start = 0, preedit_end = 0; int preedit_start = 0, preedit_end = 0;
scrpos.y = i + term->disptop; scrpos.y = i + term->disptop;
ldata = lineptr(scrpos.y); ldata = lineptr(scrpos.y);
@ -6121,18 +6121,13 @@ static void do_paint(Terminal *term)
} }
/* Work out if and where to display pre-edit text. */ /* Work out if and where to display pre-edit text. */
if (i == our_curs_y && term->preedit_char != -1) { if (i == our_curs_y && term->preedit_termchars != NULL) {
preedit_width = term_char_width(term, term->preedit_char); debug("preedit_width = %d\n", term->preedit_width);
debug("preedit_width = %d\n", preedit_width);
preedit_start = our_curs_x; preedit_start = our_curs_x;
preedit_end = preedit_start + preedit_width; preedit_end = preedit_start + term->preedit_width;
if (preedit_end > term->cols) { if (preedit_end > term->cols) {
preedit_end = term->cols; preedit_end = term->cols;
preedit_start = preedit_end - preedit_width; preedit_start = preedit_end - term->preedit_width;
}
for (j = 0; j < preedit_width; j++) {
preedit_termchars[j] = term->basic_erase_char;
preedit_termchars[j].chr = !j ? term->preedit_char : UCSWIDE;
} }
our_curs_x = preedit_start; our_curs_x = preedit_start;
} }
@ -6148,7 +6143,7 @@ static void do_paint(Terminal *term)
scrpos.x = backward ? backward[j] : j; scrpos.x = backward ? backward[j] : j;
if (in_preedit) if (in_preedit)
d = preedit_termchars + j - preedit_start; d = term->preedit_termchars + j - preedit_start;
tchar = d->chr; tchar = d->chr;
tattr = d->attr; tattr = d->attr;
@ -8139,21 +8134,36 @@ void term_notify_window_size_pixels(Terminal *term, int x, int y)
*/ */
void term_set_preedit_text(Terminal *term, char *preedit_text) void term_set_preedit_text(Terminal *term, char *preedit_text)
{ {
BinarySource src[1]; sfree(term->preedit_termchars);
term->preedit_termchars = NULL;
term->preedit_width = 0;
if (preedit_text != NULL) { if (preedit_text != NULL) {
BinarySource src[1];
int i;
debug("Pre-edit:"); debug("Pre-edit:");
BinarySource_BARE_INIT(src, preedit_text, strlen(preedit_text)); BinarySource_BARE_INIT(src, preedit_text, strlen(preedit_text));
if (get_avail(src)) { while (get_avail(src))
term->preedit_width +=
term_char_width(term, decode_utf8(src, NULL));
term->preedit_termchars = snewn(term->preedit_width, termchar);
BinarySource_REWIND(src);
for (i = 0; i < term->preedit_width; i++) {
unsigned int c = decode_utf8(src, NULL); unsigned int c = decode_utf8(src, NULL);
debug(" U+%04X", c); debug(" U+%04X", c);
term->preedit_char = c; if (term_char_width(term, c) >= 1) {
} else term->preedit_termchars[i] = term->basic_erase_char;
term->preedit_char = -1; term->preedit_termchars[i].chr = c;
if (term_char_width(term, c) >= 2) {
term->preedit_termchars[i+1] = term->basic_erase_char;
term->preedit_termchars[i+1].chr = UCSWIDE;
i++;
}
}
}
debug("\n"); debug("\n");
} else { } else {
debug("Pre-edit finished\n"); debug("Pre-edit finished\n");
term->preedit_char = -1;
} }
seen_disp_event(term); seen_disp_event(term);
} }

View File

@ -444,7 +444,8 @@ struct terminal_tag {
bool userpass_utf8_override; bool userpass_utf8_override;
/* Input method state. */ /* Input method state. */
int preedit_char; /* -1 for none */ termchar *preedit_termchars;
int preedit_width;
}; };
static inline bool in_utf(Terminal *term) static inline bool in_utf(Terminal *term)