Support for dead keys and compose sequences on Unix, by instantiating
[sgt/putty] / terminal.c
index 9865355..e30784b 100644 (file)
@@ -1225,6 +1225,7 @@ static void power_on(Terminal *term, int clear)
     term_print_finish(term);
     term->xterm_mouse = 0;
     set_raw_mouse_mode(term->frontend, FALSE);
+    term->bracketed_paste = FALSE;
     {
        int i;
        for (i = 0; i < 256; i++)
@@ -1538,6 +1539,8 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata,
     term->selstate = NO_SELECTION;
     term->curstype = 0;
 
+    term_copy_stuff_from_conf(term);
+
     term->screen = term->alt_screen = term->scrollback = NULL;
     term->tempsblines = 0;
     term->alt_sblines = 0;
@@ -1576,8 +1579,6 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata,
     term->basic_erase_char.cc_next = 0;
     term->erase_char = term->basic_erase_char;
 
-    term_copy_stuff_from_conf(term);
-
     return term;
 }
 
@@ -2503,6 +2504,9 @@ static void toggle_mode(Terminal *term, int mode, int query, int state)
                save_cursor(term, state);
            term->disptop = 0;
            break;
+         case 2004:                   /* xterm bracketed paste */
+           term->bracketed_paste = state ? TRUE : FALSE;
+           break;
     } else
        switch (mode) {
          case 4:                      /* IRM: set insert mode */
@@ -3016,8 +3020,8 @@ static void term_out(Terminal *term)
                        width = 1;
                    if (!width)
                        width = (term->cjk_ambig_wide ?
-                                mk_wcwidth_cjk((wchar_t) c) :
-                                mk_wcwidth((wchar_t) c));
+                                mk_wcwidth_cjk((unsigned int) c) :
+                                mk_wcwidth((unsigned int) c));
 
                    if (term->wrapnext && term->wrap && width > 0) {
                        cline->lattr |= LATTR_WRAPPED;
@@ -4692,7 +4696,7 @@ static termchar *term_bidi_line(Terminal *term, struct termline *ldata,
                }
 
                term->wcFrom[it].origwc = term->wcFrom[it].wc =
-                   (wchar_t)uc;
+                   (unsigned int)uc;
                term->wcFrom[it].index = it;
            }
 
@@ -5015,9 +5019,13 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
 
            break_run = ((tattr ^ attr) & term->attr_mask) != 0;
 
+#ifdef USES_VTLINE_HACK
            /* Special hack for VT100 Linedraw glyphs */
-           if (tchar >= 0x23BA && tchar <= 0x23BD)
+           if ((tchar >= 0x23BA && tchar <= 0x23BD) ||
+                (j > 0 && (newline[j-1].chr >= 0x23BA &&
+                           newline[j-1].chr <= 0x23BD)))
                break_run = TRUE;
+#endif
 
            /*
             * Separate out sequences of characters that have the
@@ -5065,10 +5073,17 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
                dirty_run = TRUE;
            }
 
-           if (ccount >= chlen) {
+           if (ccount+2 > chlen) {
                chlen = ccount + 256;
                ch = sresize(ch, chlen, wchar_t);
            }
+
+#ifdef PLATFORM_IS_UTF16
+           if (tchar > 0x10000 && tchar < 0x110000) {
+               ch[ccount++] = (wchar_t) HIGH_SURROGATE_OF(tchar);
+               ch[ccount++] = (wchar_t) LOW_SURROGATE_OF(tchar);
+           } else
+#endif /* PLATFORM_IS_UTF16 */
            ch[ccount++] = (wchar_t) tchar;
 
            if (d->cc_next) {
@@ -5092,10 +5107,17 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
                        break;
                    }
 
-                   if (ccount >= chlen) {
+                   if (ccount+2 > chlen) {
                        chlen = ccount + 256;
                        ch = sresize(ch, chlen, wchar_t);
                    }
+
+#ifdef PLATFORM_IS_UTF16
+                   if (schar > 0x10000 && schar < 0x110000) {
+                       ch[ccount++] = (wchar_t) HIGH_SURROGATE_OF(schar);
+                       ch[ccount++] = (wchar_t) LOW_SURROGATE_OF(schar);
+                   } else
+#endif /* PLATFORM_IS_UTF16 */
                    ch[ccount++] = (wchar_t) schar;
                }
 
@@ -5680,7 +5702,12 @@ void term_do_paste(Terminal *term)
         if (term->paste_buffer)
             sfree(term->paste_buffer);
         term->paste_pos = term->paste_hold = term->paste_len = 0;
-        term->paste_buffer = snewn(len, wchar_t);
+        term->paste_buffer = snewn(len + 12, wchar_t);
+
+        if (term->bracketed_paste) {
+            memcpy(term->paste_buffer, L"\033[200~", 6 * sizeof(wchar_t));
+            term->paste_len += 6;
+        }
 
         p = q = data;
         while (p < data + len) {
@@ -5704,6 +5731,12 @@ void term_do_paste(Terminal *term)
             q = p;
         }
 
+        if (term->bracketed_paste) {
+            memcpy(term->paste_buffer + term->paste_len,
+                   L"\033[201~", 6 * sizeof(wchar_t));
+            term->paste_len += 6;
+        }
+
         /* Assume a small paste will be OK in one go. */
         if (term->paste_len < 256) {
             if (term->ldisc)
@@ -6602,7 +6635,7 @@ int term_get_userpass_input(Terminal *term, prompts_t *p,
        {
            int i;
            for (i = 0; i < (int)p->n_prompts; i++)
-               memset(p->prompts[i]->result, 0, p->prompts[i]->result_len);
+                prompt_set_result(p->prompts[i], "");
        }
     }
 
@@ -6629,8 +6662,8 @@ int term_get_userpass_input(Terminal *term, prompts_t *p,
              case 10:
              case 13:
                term_data(term, 0, "\r\n", 2);
+                prompt_ensure_result_size(pr, s->pos + 1);
                pr->result[s->pos] = '\0';
-               pr->result[pr->result_len - 1] = '\0';
                /* go to next prompt, if any */
                s->curr_prompt++;
                s->done_prompt = 0;
@@ -6665,10 +6698,9 @@ int term_get_userpass_input(Terminal *term, prompts_t *p,
                 * when we're doing password input, because some people
                 * have control characters in their passwords.
                 */
-               if ((!pr->echo ||
-                    (c >= ' ' && c <= '~') ||
-                    ((unsigned char) c >= 160))
-                   && s->pos < pr->result_len - 1) {
+               if (!pr->echo || (c >= ' ' && c <= '~') ||
+                    ((unsigned char) c >= 160)) {
+                    prompt_ensure_result_size(pr, s->pos + 1);
                    pr->result[s->pos++] = c;
                    if (pr->echo)
                        term_data(term, 0, &c, 1);