Fix pasting of newlines in local line editing mode. Possibly not a
[u/mdw/putty] / unicode.c
index c3e1051..37df590 100644 (file)
--- a/unicode.c
+++ b/unicode.c
@@ -8,10 +8,6 @@
 #include "putty.h"
 #include "misc.h"
 
-void init_ucs_tables(void);
-void lpage_send(int codepage, char *buf, int len);
-void luni_send(wchar_t * widebuf, int len);
-
 static void get_unitab(int codepage, wchar_t * unitab, int ftype);
 
 /* Character conversion arrays; they are usually taken from windows,
@@ -393,6 +389,13 @@ void init_ucs_tables(void)
        link_font(unitab_xterm, unitab_oemcp, ATTR_OEMCP);
     }
 
+    if (dbcs_screenfont && font_codepage != line_codepage) {
+       /* F***ing Microsoft fonts, Japanese and Korean codepage fonts
+        * have a currency symbol at 0x5C but their unicode value is 
+        * still given as U+005C not the correct U+00A5. */
+       unitab_line['\\'] = ATTR_OEMCP + '\\';
+    }
+
     /* Last chance, if !unicode then try poorman links. */
     if (cfg.vtmode != VT_UNICODE) {
        static char poorman_scoacs[] = 
@@ -420,28 +423,28 @@ void init_ucs_tables(void)
 
 static void link_font(WCHAR * line_tbl, WCHAR * font_tbl, WCHAR attr)
 {
-    int i, j, k;
-    for (k = 0; k < 256; k++) {
-       i = ((k + 32) & 0xFF);
-       if (DIRECT_FONT(line_tbl[i]))
+    int font_index, line_index, i;
+    for (line_index = 0; line_index < 256; line_index++) {
+       if (DIRECT_FONT(line_tbl[line_index]))
            continue;
-       for (j = 0; j < 256; j++) {
-           if (line_tbl[i] == font_tbl[j]) {
-               line_tbl[i] = (WCHAR) (attr + j);
+       for(i = 0; i < 256; i++) {
+           font_index = ((32 + i) & 0xFF);
+           if (line_tbl[line_index] == font_tbl[font_index]) {
+               line_tbl[line_index] = (WCHAR) (attr + font_index);
                break;
            }
        }
     }
 }
 
-void lpage_send(int codepage, char *buf, int len)
+void lpage_send(int codepage, char *buf, int len, int interactive)
 {
     static wchar_t *widebuffer = 0;
     static int widesize = 0;
     int wclen;
 
     if (codepage < 0) {
-       ldisc_send(buf, len);
+       ldisc_send(buf, len, interactive);
        return;
     }
 
@@ -453,10 +456,10 @@ void lpage_send(int codepage, char *buf, int len)
 
     wclen =
        MultiByteToWideChar(codepage, 0, buf, len, widebuffer, widesize);
-    luni_send(widebuffer, wclen);
+    luni_send(widebuffer, wclen, interactive);
 }
 
-void luni_send(wchar_t * widebuf, int len)
+void luni_send(wchar_t * widebuf, int len, int interactive)
 {
     static char *linebuffer = 0;
     static int linesize = 0;
@@ -474,6 +477,9 @@ void luni_send(wchar_t * widebuf, int len)
        /* UTF is a simple algorithm */
        for (p = linebuffer, i = 0; i < len; i++) {
            wchar_t ch = widebuf[i];
+           /* Windows wchar_t is UTF-16 */
+           if ((ch&0xF800) == 0xD800) ch = '.';
+
            if (ch < 0x80) {
                *p++ = (char) (ch);
            } else if (ch < 0x800) {
@@ -511,7 +517,30 @@ void luni_send(wchar_t * widebuf, int len)
        }
     }
     if (p > linebuffer)
-       ldisc_send(linebuffer, p - linebuffer);
+       ldisc_send(linebuffer, p - linebuffer, interactive);
+}
+
+wchar_t xlat_uskbd2cyrllic(int ch)
+{
+    static wchar_t cyrtab[] = {
+            0,      1,       2,      3,      4,      5,      6,      7,
+            8,      9,      10,     11,     12,     13,     14,     15,
+            16,     17,     18,     19,     20,     21,     22,     23,
+            24,     25,     26,     27,     28,     29,     30,     31,
+            32,     33, 0x042d,     35,     36,     37,     38, 0x044d,
+            40,     41,     42, 0x0406, 0x0431, 0x0454, 0x044e, 0x002e,
+            48,     49,     50,     51,     52,     53,     54,     55,
+            56,     57, 0x0416, 0x0436, 0x0411, 0x0456, 0x042e, 0x002c,
+            64, 0x0424, 0x0418, 0x0421, 0x0412, 0x0423, 0x0410, 0x041f,
+        0x0420, 0x0428, 0x041e, 0x041b, 0x0414, 0x042c, 0x0422, 0x0429,
+        0x0417, 0x0419, 0x041a, 0x042b, 0x0415, 0x0413, 0x041c, 0x0426,
+        0x0427, 0x041d, 0x042f, 0x0445, 0x0457, 0x044a,     94, 0x0404,
+            96, 0x0444, 0x0438, 0x0441, 0x0432, 0x0443, 0x0430, 0x043f,
+        0x0440, 0x0448, 0x043e, 0x043b, 0x0434, 0x044c, 0x0442, 0x0449,
+        0x0437, 0x0439, 0x043a, 0x044b, 0x0435, 0x0433, 0x043c, 0x0446,
+        0x0447, 0x043d, 0x044f, 0x0425, 0x0407, 0x042a,    126,    127
+       };
+    return cyrtab[ch&0x7F];
 }
 
 int check_compose(int first, int second)
@@ -534,7 +563,7 @@ int check_compose(int first, int second)
        0x43, 0x2f, 0x00a2}, {
        0x43, 0x7c, 0x00a2}, {
        0x4c, 0x2d, 0x00a3}, {
-       0x4c, 0x3d, 0x00a3}, {
+       0x4c, 0x3d, 0x20a4}, {
        0x58, 0x4f, 0x00a4}, {
        0x58, 0x30, 0x00a4}, {
        0x59, 0x2d, 0x00a5}, {