home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / evbl0627.zip / everblue_20010627.zip / x11 / Xim_Conv.c < prev    next >
C/C++ Source or Header  |  1999-11-02  |  40KB  |  909 lines

  1. /* $TOG: imConv.c /main/20 1998/06/17 15:46:41 kaleb $ */
  2. /******************************************************************
  3.  
  4.               Copyright 1991, 1992 by Fuji Xerox Co.,Ltd.
  5.           Copyright 1993, 1994 by FUJITSU LIMITED
  6.  
  7. Permission to use, copy, modify, distribute, and sell this software
  8. and its documentation for any purpose is hereby granted without fee,
  9. provided that the above copyright notice appear in all copies and
  10. that both that copyright notice and this permission notice appear
  11. in supporting documentation, and that the name of Fuji Xerox Co.,Ltd.
  12. , and that the name of FUJITSU LIMITED not be used in advertising or
  13. publicity pertaining to distribution of the software without specific,
  14.  written prior permission.
  15. Fuji Xerox Co.,Ltd. , and FUJITSU LIMITED makes no representations about
  16. the suitability of this software for any purpose.
  17. It is provided "as is" without express or implied warranty.
  18.  
  19. FUJI XEROX CO.,LTD. AND FUJITSU LIMITED DISCLAIMS ALL WARRANTIES WITH
  20. REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
  21. MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX CO.,LTD.
  22. AND FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT
  23. OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  24. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  25. NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
  26. THE USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  
  28.   Auther:   Kazunori Nishihara, Fuji Xerox Co.,Ltd.
  29.                                 kaz@ssdev.ksp.fujixerox.co.jp
  30.   Modifier: Takashi Fujiwara    FUJITSU LIMITED
  31.                                 fujiwara@a80.tech.yk.fujitsu.co.jp
  32.  
  33. ******************************************************************/
  34. /* $XFree86: xc/lib/X11/imConv.c,v 1.5.2.5 1998/10/21 06:40:38 dawes Exp $ */
  35.  
  36. #define NEED_EVENTS
  37. #include <stdio.h>
  38. #include "Xlib_private.h"
  39. #include "Xlcint.h"
  40. #include "Ximint.h"
  41. #include "XlcPubI.h"
  42. #define XK_PUBLISHING
  43. #include "X11/keysym.h"
  44.  
  45. #ifdef XKB
  46. /* 
  47.  * rather than just call _XLookupString (i.e. the pre-XKB XLookupString) 
  48.  * do this because with XKB the event may have some funky modifiers that 
  49.  * _XLookupString doesn't grok.
  50.  */
  51. #include "XKBlib.h"
  52. #define    XLOOKUPSTRING lookup_string
  53. #else
  54. #define    XLOOKUPSTRING XLookupString
  55. #endif
  56.  
  57. /* bit (1<<i) means character is in codeset i */
  58. unsigned int _Xlatin1[128] = {
  59. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
  60. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  61. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
  62. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  63. 0x990ee, 0x88000, 0x89000, 0x89084, 0x0902e, 0x89000, 0x09080, 0x9908e,
  64. 0x0908e, 0x89080, 0x88000, 0x89080, 0x89080, 0x990ee, 0x89000, 0x89008,
  65. 0x9908e, 0x89080, 0x89084, 0x89084, 0x0908e, 0x89004, 0x89000, 0x99084,
  66. 0x0900c, 0x89000, 0x88000, 0x89080, 0x09000, 0x09084, 0x09000, 0x88000,
  67. 0x88004, 0x9800e, 0x9800e, 0x98008, 0x9800e, 0x98008, 0x98008, 0x88006,
  68. 0x88004, 0x9800e, 0x88004, 0x9800e, 0x88004, 0x9800e, 0x9800e, 0x98004,
  69. 0x90000, 0x88004, 0x88004, 0x98006, 0x9800e, 0x98008, 0x9800e, 0x8800e,
  70. 0x98008, 0x88004, 0x9800e, 0x9800c, 0x9800e, 0x90002, 0x90000, 0x9800e,
  71. 0x88004, 0x9800e, 0x9800e, 0x98008, 0x9800e, 0x98008, 0x98008, 0x88004,
  72. 0x88004, 0x9800e, 0x88004, 0x9800e, 0x88004, 0x9800e, 0x9800e, 0x98004,
  73. 0x90000, 0x88004, 0x88004, 0x98006, 0x9800e, 0x98008, 0x9800e, 0x8800e,
  74. 0x98008, 0x88004, 0x9800e, 0x9800c, 0x9800e, 0x90002, 0x90000, 0x88000
  75. };
  76.  
  77. /* bit (1<<i) means character is in codeset i */
  78. unsigned int _Xlatin2[128] = {
  79. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
  80. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  81. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  82. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  83. 0x1800c, 0x10008, 0x00004, 0x00000, 0x0800c, 0x00000, 0x00000, 0x1800c,
  84. 0x0800c, 0x00008, 0x00004, 0x00000, 0x00000, 0x1800c, 0x00008, 0x00004,
  85. 0x1800c, 0x10008, 0x00008, 0x00000, 0x0800c, 0x00000, 0x00000, 0x00008,
  86. 0x0800c, 0x00008, 0x00004, 0x00000, 0x00000, 0x00000, 0x00008, 0x00004,
  87. 0x00000, 0x1800c, 0x1800c, 0x00000, 0x1800c, 0x00000, 0x00000, 0x08004,
  88. 0x10008, 0x1800c, 0x10008, 0x1800c, 0x00000, 0x18008, 0x18008, 0x00000,
  89. 0x00008, 0x00000, 0x00000, 0x18004, 0x1800c, 0x00000, 0x1800c, 0x0800c,
  90. 0x00000, 0x00000, 0x0800c, 0x00000, 0x0800c, 0x10000, 0x00000, 0x1800c,
  91. 0x00000, 0x1800c, 0x1800c, 0x00000, 0x1800c, 0x00000, 0x00000, 0x08004,
  92. 0x10008, 0x1800c, 0x10008, 0x1800c, 0x00000, 0x1800c, 0x1800c, 0x00000,
  93. 0x00008, 0x00000, 0x00000, 0x18004, 0x1800c, 0x00000, 0x1800c, 0x0800c,
  94. 0x00000, 0x00000, 0x0800c, 0x00000, 0x0800c, 0x10000, 0x00000, 0x0000c
  95. };
  96.  
  97. /* maps Cyrillic keysyms to 8859-5 */
  98. unsigned char _Xcyrillic[] = {
  99.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80 - */
  100.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  101.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90 - */
  102.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  103.     0x00, 0xf2, 0xf3, 0xf1, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xa0 - */
  104.     0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0xfe, 0xff,
  105.     0xf0, 0xa2, 0xa3, 0xa1, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xb0 - */
  106.     0xa8, 0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf,
  107.     0xee, 0xd0, 0xd1, 0xe6, 0xd4, 0xd5, 0xe4, 0xd3, /* 0xc0 - */
  108.     0xe5, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
  109.     0xdf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0xd6, 0xd2, /* 0xd0 - */
  110.     0xec, 0xeb, 0xd7, 0xe8, 0xed, 0xe9, 0xe7, 0xea,
  111.     0xce, 0xb0, 0xb1, 0xc6, 0xb4, 0xb5, 0xc4, 0xb3, /* 0xe0 - */
  112.     0xc5, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
  113.     0xbf, 0xcf, 0xc0, 0xc1, 0xc2, 0xc3, 0xb6, 0xb2, /* 0xf0 - */
  114.     0xcc, 0xcb, 0xb7, 0xc8, 0xcd, 0xc9, 0xc7, 0xca
  115. };
  116.  
  117. /* maps Cyrillic keysyms to KOI8-R */
  118. unsigned char _Xkoi8[] =
  119.    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  120.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  121.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  122.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  123.     0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, /* 10 */
  124.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  125.     0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, /* 11 */
  126.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  127.     0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 12 */
  128.     0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
  129.     0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 13 */
  130.     0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
  131.     0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 14 */
  132.     0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
  133.     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 15 */
  134.     0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
  135.  
  136. unsigned short _Xkoi8_size = sizeof _Xkoi8;
  137.  
  138. /* maps Greek keysyms to 8859-7 */
  139. unsigned char _Xgreek[] = {
  140.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80 - */
  141.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  142.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90 - */
  143.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  144.     0x00, 0xb6, 0xb8, 0xb9, 0xba, 0xda, 0x00, 0xbc, /* 0xa0 - */
  145.     0xbe, 0xdb, 0x00, 0xbf, 0x00, 0x00, 0xb5, 0xaf,
  146.     0x00, 0xdc, 0xdd, 0xde, 0xdf, 0xfa, 0xc0, 0xfc, /* 0xb0 - */
  147.     0xfd, 0xfb, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00,
  148.     0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0 - */
  149.     0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
  150.     0xd0, 0xd1, 0xd3, 0x00, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0 - */
  151.     0xd8, 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  152.     0x00, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0 - */
  153.     0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
  154.     0xf0, 0xf1, 0xf3, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0 - */
  155.     0xf8, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  156. };
  157.  
  158.  
  159. static unsigned short keysym_to_unicode_1a1_1ff[] = {
  160.             0x0104, 0x02d8, 0x0141, 0x0000, 0x013d, 0x015a, 0x0000, /* 0x01a0-0x01a7 */
  161.     0x0000, 0x0160, 0x015e, 0x0164, 0x0179, 0x0000, 0x017d, 0x017b, /* 0x01a8-0x01af */
  162.     0x0000, 0x0105, 0x02db, 0x0142, 0x0000, 0x013e, 0x015b, 0x02c7, /* 0x01b0-0x01b7 */
  163.     0x0000, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, /* 0x01b8-0x01bf */
  164.     0x0154, 0x0000, 0x0000, 0x0102, 0x0000, 0x0139, 0x0106, 0x0000, /* 0x01c0-0x01c7 */
  165.     0x010c, 0x0000, 0x0118, 0x0000, 0x011a, 0x0000, 0x0000, 0x010e, /* 0x01c8-0x01cf */
  166.     0x0110, 0x0143, 0x0147, 0x0000, 0x0000, 0x0150, 0x0000, 0x0000, /* 0x01d0-0x01d7 */
  167.     0x0158, 0x016e, 0x0000, 0x0170, 0x0000, 0x0000, 0x0162, 0x0000, /* 0x01d8-0x01df */
  168.     0x0155, 0x0000, 0x0000, 0x0103, 0x0000, 0x013a, 0x0107, 0x0000, /* 0x01e0-0x01e7 */
  169.     0x010d, 0x0000, 0x0119, 0x0000, 0x011b, 0x0000, 0x0000, 0x010f, /* 0x01e8-0x01ef */
  170.     0x0111, 0x0144, 0x0148, 0x0000, 0x0000, 0x0151, 0x0000, 0x0000, /* 0x01f0-0x01f7 */
  171.     0x0159, 0x016f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0163, 0x02d9  /* 0x01f8-0x01ff */
  172. };
  173.  
  174. static unsigned short keysym_to_unicode_2a1_2fe[] = {
  175.             0x0126, 0x0000, 0x0000, 0x0000, 0x0000, 0x0124, 0x0000, /* 0x02a0-0x02a7 */
  176.     0x0000, 0x0130, 0x0000, 0x011e, 0x0134, 0x0000, 0x0000, 0x0000, /* 0x02a8-0x02af */
  177.     0x0000, 0x0127, 0x0000, 0x0000, 0x0000, 0x0000, 0x0125, 0x0000, /* 0x02b0-0x02b7 */
  178.     0x0000, 0x0131, 0x0000, 0x011f, 0x0135, 0x0000, 0x0000, 0x0000, /* 0x02b8-0x02bf */
  179.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010a, 0x0108, 0x0000, /* 0x02c0-0x02c7 */
  180.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02c8-0x02cf */
  181.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0120, 0x0000, 0x0000, /* 0x02d0-0x02d7 */
  182.     0x011c, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x015c, 0x0000, /* 0x02d8-0x02df */
  183.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010b, 0x0109, 0x0000, /* 0x02e0-0x02e7 */
  184.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02e8-0x02ef */
  185.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0121, 0x0000, 0x0000, /* 0x02f0-0x02f7 */
  186.     0x011d, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x015d          /* 0x02f8-0x02ff */
  187. };
  188.  
  189. static unsigned short keysym_to_unicode_3a2_3fe[] = {
  190.                     0x0138, 0x0156, 0x0000, 0x0128, 0x013b, 0x0000, /* 0x03a0-0x03a7 */
  191.     0x0000, 0x0000, 0x0112, 0x0122, 0x0166, 0x0000, 0x0000, 0x0000, /* 0x03a8-0x03af */
  192.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x013c, 0x0000, /* 0x03b0-0x03b7 */
  193.     0x0000, 0x0000, 0x0113, 0x0123, 0x0167, 0x014a, 0x0000, 0x014b, /* 0x03b8-0x03bf */
  194.     0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012e, /* 0x03c0-0x03c7 */
  195.     0x0000, 0x0000, 0x0000, 0x0000, 0x0116, 0x0000, 0x0000, 0x012a, /* 0x03c8-0x03cf */
  196.     0x0000, 0x0145, 0x014c, 0x0136, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03d0-0x03d7 */
  197.     0x0000, 0x0172, 0x0000, 0x0000, 0x0000, 0x0168, 0x016a, 0x0000, /* 0x03d8-0x03df */
  198.     0x0101, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012f, /* 0x03e0-0x03e7 */
  199.     0x0000, 0x0000, 0x0000, 0x0000, 0x0117, 0x0000, 0x0000, 0x012b, /* 0x03e8-0x03ef */
  200.     0x0000, 0x0146, 0x014d, 0x0137, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03f0-0x03f7 */
  201.     0x0000, 0x0173, 0x0000, 0x0000, 0x0000, 0x0169, 0x016b          /* 0x03f8-0x03ff */
  202. };
  203.  
  204. static unsigned short keysym_to_unicode_4a1_4df[] = {
  205.             0x3002, 0x3008, 0x3009, 0x3001, 0x30fb, 0x30f2, 0x30a1, /* 0x04a0-0x04a7 */
  206.     0x30a3, 0x03a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, /* 0x04a8-0x04af */
  207.     0x30fc, 0x03a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad, /* 0x04b0-0x04b7 */
  208.     0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, 0x30bd, /* 0x04b8-0x04bf */
  209.     0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, /* 0x04c0-0x04c7 */
  210.     0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, /* 0x04c8-0x04cf */
  211.     0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, /* 0x04d0-0x04d7 */
  212.     0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c  /* 0x04d8-0x04df */
  213. };
  214.  
  215. static unsigned short keysym_to_unicode_5ac_5f2[] = {
  216.                                     0x060c, 0x0000, 0x0000, 0x0000, /* 0x05ac-0x05af */
  217.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x05b0-0x05b7 */
  218.     0x0000, 0x0000, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f, /* 0x05b8-0x05bf */
  219.     0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, /* 0x05c0-0x05c7 */
  220.     0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, /* 0x05c8-0x05cf */
  221.     0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, /* 0x05d0-0x05d7 */
  222.     0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x05d8-0x05df */
  223.     0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, /* 0x05e0-0x05e7 */
  224.     0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, /* 0x05e8-0x05ef */
  225.     0x0650, 0x0651, 0x0652                                          /* 0x05f0-0x05f7 */
  226. };
  227.  
  228. static unsigned short keysym_to_unicode_6a1_6ff[] = {
  229.             0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, /* 0x06a0-0x06a7 */
  230.     0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0000, 0x045e, 0x045f, /* 0x06a8-0x06af */
  231.     0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, /* 0x06b0-0x06b7 */
  232.     0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0000, 0x040e, 0x040f, /* 0x06b8-0x06bf */
  233.     0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, /* 0x06c0-0x06c7 */
  234.     0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, /* 0x06c8-0x06cf */
  235.     0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, /* 0x06d0-0x06d7 */
  236.     0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, /* 0x06d8-0x06df */
  237.     0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, /* 0x06e0-0x06e7 */
  238.     0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, /* 0x06e8-0x06ef */
  239.     0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, /* 0x06f0-0x06f7 */
  240.     0x042c, 0x042d, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a  /* 0x06f8-0x06ff */
  241. };
  242.  
  243. static unsigned short keysym_to_unicode_7a1_7f9[] = {
  244.             0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c, /* 0x07a0-0x07a7 */
  245.     0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015, /* 0x07a8-0x07af */
  246.     0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, /* 0x07b0-0x07b7 */
  247.     0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07b8-0x07bf */
  248.     0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, /* 0x07c0-0x07c7 */
  249.     0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, /* 0x07c8-0x07cf */
  250.     0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, /* 0x07d0-0x07d7 */
  251.     0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07d8-0x07df */
  252.     0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, /* 0x07e0-0x07e7 */
  253.     0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, /* 0x07e8-0x07ef */
  254.     0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, /* 0x07f0-0x07f7 */
  255.     0x03c8, 0x03c9                                                  /* 0x07f8-0x07ff */
  256. };
  257.  
  258. static unsigned short keysym_to_unicode_8a4_8fe[] = {
  259.                                     0x2320, 0x2321, 0x0000, 0x231c, /* 0x08a0-0x08a7 */
  260.     0x231d, 0x231e, 0x231f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08a8-0x08af */
  261.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08b0-0x08b7 */
  262.     0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222b, /* 0x08b8-0x08bf */
  263.     0x2234, 0x0000, 0x221e, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000, /* 0x08c0-0x08c7 */
  264.     0x2245, 0x2246, 0x0000, 0x0000, 0x0000, 0x0000, 0x22a2, 0x0000, /* 0x08c8-0x08cf */
  265.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221a, 0x0000, /* 0x08d0-0x08d7 */
  266.     0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222a, 0x2227, 0x2228, /* 0x08d8-0x08df */
  267.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e0-0x08e7 */
  268.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e8-0x08ef */
  269.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000, /* 0x08f0-0x08f7 */
  270.     0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193          /* 0x08f8-0x08ff */
  271. };
  272.  
  273. static unsigned short keysym_to_unicode_9df_9f8[] = {
  274.                                                             0x2422, /* 0x09d8-0x09df */
  275.     0x2666, 0x25a6, 0x2409, 0x240c, 0x240d, 0x240a, 0x0000, 0x0000, /* 0x09e0-0x09e7 */
  276.     0x240a, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x2500, /* 0x09e8-0x09ef */
  277.     0x0000, 0x0000, 0x0000, 0x0000, 0x251c, 0x2524, 0x2534, 0x252c, /* 0x09f0-0x09f7 */
  278.     0x2502                                                          /* 0x09f8-0x09ff */
  279. };
  280.  
  281. static unsigned short keysym_to_unicode_aa1_afe[] = {
  282.             0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009, /* 0x0aa0-0x0aa7 */
  283.     0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025, /* 0x0aa8-0x0aaf */
  284.     0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, /* 0x0ab0-0x0ab7 */
  285.     0x2105, 0x0000, 0x0000, 0x2012, 0x2039, 0x2024, 0x203a, 0x0000, /* 0x0ab8-0x0abf */
  286.     0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000, /* 0x0ac0-0x0ac7 */
  287.     0x0000, 0x2122, 0x2120, 0x00ae, 0x25c1, 0x25b7, 0x25cb, 0x25ad, /* 0x0ac8-0x0acf */
  288.     0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x0000, 0x2032, 0x2033, /* 0x0ad0-0x0ad7 */
  289.     0x0000, 0x271d, 0x0000, 0x220e, 0x25c2, 0x2023, 0x25cf, 0x25ac, /* 0x0ad8-0x0adf */
  290.     0x25e6, 0x25ab, 0x25ae, 0x25b5, 0x25bf, 0x2606, 0x2022, 0x25aa, /* 0x0ae0-0x0ae7 */
  291.     0x25b4, 0x25be, 0x261a, 0x261b, 0x2663, 0x2666, 0x2665, 0x0000, /* 0x0ae8-0x0aef */
  292.     0x2720, 0x2020, 0x2021, 0x2713, 0x2612, 0x266f, 0x266d, 0x2642, /* 0x0af0-0x0af7 */
  293.     0x2640, 0x2121, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e          /* 0x0af8-0x0aff */
  294. };
  295.  
  296. /* none of the APL keysyms match the Unicode characters */
  297.  
  298. static unsigned short keysym_to_unicode_cdf_cfa[] = {
  299.                                                             0x2017, /* 0x0cd8-0x0cdf */
  300.     0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, /* 0x0ce0-0x0ce7 */
  301.     0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, /* 0x0ce8-0x0cef */
  302.     0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, /* 0x0cf0-0x0cf7 */
  303.     0x05e8, 0x05e9, 0x05ea                                          /* 0x0cf8-0x0cff */
  304. };
  305.  
  306. static unsigned short keysym_to_unicode_da1_df9[] = {
  307.             0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, /* 0x0da0-0x0da7 */
  308.     0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, /* 0x0da8-0x0daf */
  309.     0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, /* 0x0db0-0x0db7 */
  310.     0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, /* 0x0db8-0x0dbf */
  311.     0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, /* 0x0dc0-0x0dc7 */
  312.     0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, /* 0x0dc8-0x0dcf */
  313.     0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, /* 0x0dd0-0x0dd7 */
  314.     0x0e38, 0x0e39, 0x0e3a, 0x0e3b, 0x0e3c, 0x0e3d, 0x0e3e, 0x0e3f, /* 0x0dd8-0x0ddf */
  315.     0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, /* 0x0de0-0x0de7 */
  316.     0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0000, 0x0000, /* 0x0de8-0x0def */
  317.     0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, /* 0x0df0-0x0df7 */
  318.     0x0e58, 0x0e59                                                  /* 0x0df8-0x0dff */
  319. };
  320.  
  321. static unsigned short keysym_to_unicode_ea0_eff[] = {
  322.     0x0000, 0x1101, 0x1101, 0x11aa, 0x1102, 0x11ac, 0x11ad, 0x1103, /* 0x0ea0-0x0ea7 */
  323.     0x1104, 0x1105, 0x11b0, 0x11b1, 0x11b2, 0x11b3, 0x11b4, 0x11b5, /* 0x0ea8-0x0eaf */
  324.     0x11b6, 0x1106, 0x1107, 0x1108, 0x11b9, 0x1109, 0x110a, 0x110b, /* 0x0eb0-0x0eb7 */
  325.     0x110c, 0x110d, 0x110e, 0x110f, 0x1110, 0x1111, 0x1112, 0x1161, /* 0x0eb8-0x0ebf */
  326.     0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 0x1168, 0x1169, /* 0x0ec0-0x0ec7 */
  327.     0x116a, 0x116b, 0x116c, 0x116d, 0x116e, 0x116f, 0x1170, 0x1171, /* 0x0ec8-0x0ecf */
  328.     0x1172, 0x1173, 0x1174, 0x1175, 0x11a8, 0x11a9, 0x11aa, 0x11ab, /* 0x0ed0-0x0ed7 */
  329.     0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3, /* 0x0ed8-0x0edf */
  330.     0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb, /* 0x0ee0-0x0ee7 */
  331.     0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x0000, /* 0x0ee8-0x0eef */
  332.     0x0000, 0x0000, 0x1140, 0x0000, 0x0000, 0x1159, 0x119e, 0x0000, /* 0x0ef0-0x0ef7 */
  333.     0x11eb, 0x0000, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9, /* 0x0ef8-0x0eff */
  334. };
  335.  
  336. static unsigned short keysym_to_unicode_13bc_13be[] = {
  337.                                     0x0152, 0x0153, 0x0178          /* 0x13b8-0x13bf */
  338. };
  339.  
  340. static unsigned short keysym_to_unicode_20a0_20ac[] = {
  341.     0x20a0, 0x20a1, 0x20a2, 0x20a3, 0x20a4, 0x20a5, 0x20a6, 0x20a7, /* 0x20a0-0x20a7 */
  342.     0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac                          /* 0x20a8-0x20af */
  343. };
  344.  
  345. static int keysym_to_ucs4(keysym)
  346.     KeySym keysym;
  347. {
  348.     DBUG_ENTER("keysym_to_ucs4")
  349.     if (keysym > 0 && keysym < 0x100) {
  350.     DBUG_RETURN(keysym);
  351.     } else if (keysym > 0x1a0 && keysym < 0x200) {
  352.     DBUG_RETURN(keysym_to_unicode_1a1_1ff[keysym - 0x1a1]);
  353.     } else if (keysym > 0x2a0 && keysym < 0x2ff) {
  354.     DBUG_RETURN(keysym_to_unicode_2a1_2fe[keysym - 0x2a1]);
  355.     } else if (keysym > 0x3a1 && keysym < 0x3ff) {
  356.     DBUG_RETURN(keysym_to_unicode_3a2_3fe[keysym - 0x3a2]);
  357.     } else if (keysym > 0x4a0 && keysym < 0x4e0) {
  358.     DBUG_RETURN(keysym_to_unicode_4a1_4df[keysym - 0x4a1]);
  359.     } else if (keysym > 0x5ab && keysym < 0x5f3) {
  360.     DBUG_RETURN(keysym_to_unicode_5ac_5f2[keysym - 0x5ac]);
  361.     } else if (keysym > 0x6a0 && keysym < 0x700) {
  362.     DBUG_RETURN(keysym_to_unicode_6a1_6ff[keysym - 0x6a1]);
  363.     } else if (keysym > 0x7a0 && keysym < 0x7fa) {
  364.     DBUG_RETURN(keysym_to_unicode_7a1_7f9[keysym - 0x7a1]);
  365.     } else if (keysym > 0x8a3 && keysym < 0x8ff) {
  366.     DBUG_RETURN(keysym_to_unicode_8a4_8fe[keysym - 0x8a4]);
  367.     } else if (keysym > 0x9de && keysym < 0x9f9) {
  368.     DBUG_RETURN(keysym_to_unicode_9df_9f8[keysym - 0x9df]);
  369.     } else if (keysym > 0xaa0 && keysym < 0xaff) {
  370.     DBUG_RETURN(keysym_to_unicode_aa1_afe[keysym - 0xaa1]);
  371.     } else if (keysym > 0xcde && keysym < 0xcfb) {
  372.     DBUG_RETURN(keysym_to_unicode_cdf_cfa[keysym - 0xcdf]);
  373.     } else if (keysym > 0xda0 && keysym < 0xdfa) {
  374.     DBUG_RETURN(keysym_to_unicode_da1_df9[keysym - 0xda1]);
  375.     } else if (keysym > 0xe9f && keysym < 0xf00) {
  376.     DBUG_RETURN(keysym_to_unicode_ea0_eff[keysym - 0xea0]);
  377.     } else if (keysym > 0x13bb && keysym < 0x13bf) {
  378.     DBUG_RETURN(keysym_to_unicode_13bc_13be[keysym - 0x13bc]);
  379.     } else if (keysym > 0x209f && keysym < 0x20ad) {
  380.     DBUG_RETURN(keysym_to_unicode_20a0_20ac[keysym - 0x20a0]);
  381.     } else 
  382.     DBUG_RETURN(0);
  383. }
  384.  
  385. struct CodesetRec {
  386.     unsigned long locale_code;
  387.     char* locale_name;
  388.     char* escape_seq;
  389. };
  390.  
  391. #define sLatin1    0L
  392. #define sLatin2    1L
  393. #define sLatin3    2L
  394. #define sLatin4    3L
  395. #define sKana    4L
  396. #define sX0201  0x01000004L
  397. #define sArabic    5L
  398. #define sCyrillic    6L
  399. #define sKoi8    0x01000006L
  400. #define sGreek    7L
  401. #define sHebrew    12L
  402. #define sThai    13L
  403. #define sKorean    14L
  404. #define sLatin5    15L
  405. #define sLatin6    16L
  406. #define sLatin7    17L
  407. #define sLatin8    18L
  408. #define sLatin9    19L
  409. #define sCurrency 32L
  410. #define sUTF8    0x02000000L
  411.  
  412. static struct CodesetRec CodesetTable[] = {
  413.     {sLatin1,    "ISO8859-1",    "\033-A"},
  414.     {sLatin2,    "ISO8859-2",    "\033-B"},
  415.     {sLatin3,    "ISO8859-3",    "\033-C"},
  416.     {sLatin4,    "ISO8859-4",    "\033-D"},
  417.     {sArabic,    "ISO8859-5",    "\033-G"},
  418.     {sCyrillic,    "ISO8859-6",    "\033-L"},
  419.     {sGreek,    "ISO8859-7",    "\033-F"},
  420.     {sHebrew,    "ISO8859-8",    "\033-H"},
  421.     {sLatin5,    "ISO8859-9",    "\033-M"},
  422.     {sLatin6,    "ISO8859-10",    "\033-V"},
  423.     {sThai,    "TACTIS",    "\033-T"},
  424.     {sKorean,    "ko.euc",    "\033$(C"},
  425.     {sThai,    "ISO8859-11",    "\033-T"},
  426. #if 0
  427.     {sLatin8,    "ISO8859-12",    "\033-?"},/* Celtic, superceded by -14 */
  428.     {sLatin7,    "ISO8859-13",    "\033-?"},/* Baltic Rim */
  429.     {sLatin8    "ISO8859-14",    "\033-?"},/* Celtic */
  430. #endif
  431.     {sUTF8,    "utf8",        "\033%B"},
  432.     /* Non-standard */
  433.     {sCyrillic,    "KOI8-R", "\033%/1\200\210koi8-r\002"},
  434.     {sLatin9,    "ISO8859-15",    "\033%/1\200\213iso8859-15\002"},/* a.k.a. Latin-0 */
  435. };
  436.  
  437. #define NUM_CODESETS sizeof CodesetTable / sizeof CodesetTable[0]
  438.  
  439. #ifndef XK_emdash
  440. #define XK_emdash 0xaa9
  441. #endif
  442.  
  443.  
  444. /* ================================================================ */
  445. /*
  446. File:    ConvertUTF.C
  447. Author: Mark E. Davis
  448. Copyright (C) 1994 Taligent, Inc. All rights reserved.
  449.  
  450. This code is copyrighted. Under the copyright laws, this code may not
  451. be copied, in whole or part, without prior written consent of Taligent. 
  452.  
  453. Taligent grants the right to use or reprint this code as long as this
  454. ENTIRE copyright notice is reproduced in the code or reproduction.
  455. The code is provided AS-IS, AND TALIGENT DISCLAIMS ALL WARRANTIES,
  456. EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO IMPLIED
  457. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IN
  458. NO EVENT WILL TALIGENT BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING,
  459. WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS
  460. INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY
  461. LOSS) ARISING OUT OF THE USE OR INABILITY TO USE THIS CODE, EVEN
  462. IF TALIGENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  463. BECAUSE SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF
  464. LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
  465. LIMITATION MAY NOT APPLY TO YOU.
  466.  
  467. RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the
  468. government is subject to restrictions as set forth in subparagraph
  469. (c)(l)(ii) of the Rights in Technical Data and Computer Software
  470. clause at DFARS 252.227-7013 and FAR 52.227-19.
  471.  
  472. This code may be protected by one or more U.S. and International
  473. Patents.
  474.  
  475. TRADEMARKS: Taligent and the Taligent Design Mark are registered
  476. trademarks of Taligent, Inc.
  477. */
  478. /* ================================================================ */
  479.  
  480. #define kReplacementCharacter    0x0000FFFDUL
  481. #define kMaximumUCS2        0x0000FFFFUL
  482. #define kMaximumUCS4        0x7FFFFFFFUL
  483.  
  484. typedef enum {
  485.     ok,                 /* conversion successful */
  486.     sourceExhausted,    /* partial character in source, but hit end */
  487.     targetExhausted        /* insuff. room in target for conversion */
  488. } ConversionResult;
  489.  
  490. #define halfShift        10
  491. #define halfBase        0x0010000UL
  492. #define halfMask        0x3FFUL
  493. #define kSurrogateHighStart    0xD800UL
  494. #define kSurrogateHighEnd    0xDBFFUL
  495. #define kSurrogateLowStart    0xDC00UL
  496. #define kSurrogateLowEnd    0xDFFFUL
  497.  
  498. typedef unsigned int UCS4; /* wchar_t, but on AIX, SunOS wchar_t is 16 bits */
  499. typedef unsigned char UTF8;
  500.  
  501. static UCS4 offsetsFromUTF8[6] = {
  502.     0x00000000UL, 0x00003080UL, 0x000E2080UL, 
  503.      0x03C82080UL, 0xFA082080UL, 0x82082080UL
  504. };
  505.  
  506. static char bytesFromUTF8[256] = {
  507.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  508.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  509.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  510.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  511.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  512.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  513.     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  514.     2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
  515. };
  516.  
  517. static UTF8 firstByteMark[7] = {
  518.     0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
  519. };
  520.  
  521. static ConversionResult    ConvertUCS4toUTF8 (
  522.     UCS4** sourceStart, UCS4* sourceEnd, 
  523.     UTF8** targetStart, UTF8* targetEnd)
  524. {
  525.     DBUG_ENTER("ConvertUCS4toUTF8")
  526.     ConversionResult result = ok;
  527.     register UCS4* source = *sourceStart;
  528.     register UTF8* target = *targetStart;
  529.     while (source < sourceEnd) {
  530.         register UCS4 ch;
  531.         register unsigned short bytesToWrite = 0;
  532.         register const UCS4 byteMask = 0xBF;
  533.         register const UCS4 byteMark = 0x80; 
  534.         ch = *source++;
  535.         if (ch >= kSurrogateHighStart && ch <= kSurrogateHighEnd
  536.                 && source < sourceEnd) {
  537.             register UCS4 ch2 = *source;
  538.             if (ch2 >= kSurrogateLowStart && ch2 <= kSurrogateLowEnd) {
  539.                 ch = ((ch - kSurrogateHighStart) << halfShift)
  540.                     + (ch2 - kSurrogateLowStart) + halfBase;
  541.                 ++source;
  542.             };
  543.         };
  544.         if (ch < 0x80) {        bytesToWrite = 1;
  545.         } else if (ch < 0x800) {    bytesToWrite = 2;
  546.         } else if (ch < 0x10000) {    bytesToWrite = 3;
  547.         } else if (ch < 0x200000) {    bytesToWrite = 4;
  548.         } else if (ch < 0x4000000) {    bytesToWrite = 5;
  549.         } else if (ch <= kMaximumUCS4){    bytesToWrite = 6;
  550.         } else {            bytesToWrite = 2;
  551.                         ch = kReplacementCharacter;
  552.         }; /* I wish there were a smart way to avoid this conditional */
  553.         
  554.         target += bytesToWrite;
  555.         if (target > targetEnd) {
  556.             target -= bytesToWrite; result = targetExhausted; break;
  557.         };
  558.         switch (bytesToWrite) {    /* note: code falls through cases! */
  559.         case 6:    *--target = (ch | byteMark) & byteMask; ch >>= 6;
  560.         case 5:    *--target = (ch | byteMark) & byteMask; ch >>= 6;
  561.         case 4:    *--target = (ch | byteMark) & byteMask; ch >>= 6;
  562.         case 3:    *--target = (ch | byteMark) & byteMask; ch >>= 6;
  563.         case 2:    *--target = (ch | byteMark) & byteMask; ch >>= 6;
  564.         case 1:    *--target =  ch | firstByteMark[bytesToWrite];
  565.         };
  566.         target += bytesToWrite;
  567.     };
  568.     *sourceStart = source;
  569.     *targetStart = target;
  570.     DBUG_RETURN(result);
  571. }
  572.  
  573. /*ARGSUSED*/
  574. int 
  575. #if NeedFunctionPrototypes
  576. _XGetCharCode (
  577.      unsigned long locale_code,
  578.      KeySym         keysym,
  579.      unsigned char*    buf,
  580.      int         nbytes)
  581. #else
  582. _XGetCharCode (locale_code, keysym, buf, nbytes)
  583.     unsigned long locale_code;
  584.     KeySym keysym;
  585.     unsigned char *buf;
  586.     int nbytes;
  587. #endif
  588. {
  589.     DBUG_ENTER("_XGetCharCode")
  590.     unsigned long kset;
  591.     int    count,isLatin1;
  592.  
  593.     if (locale_code == sUTF8) {
  594.     unsigned int ucs4[2];
  595.     unsigned int* ucs4vec[1];
  596.     unsigned char* utf8vec[1];
  597.  
  598.     ucs4[0] = keysym_to_ucs4 (keysym);
  599.     ucs4[1] = 0;
  600.     ucs4vec[0] = ucs4;
  601.     utf8vec[0] = buf;
  602.  
  603.     (void) ConvertUCS4toUTF8 (ucs4vec, &ucs4[1], utf8vec, &buf[nbytes]);
  604.     DBUG_RETURN(strlen ((char*) buf));
  605.     }
  606.  
  607.     kset = locale_code&0xffffff;
  608.  
  609.     isLatin1 = ((keysym&0xffffff00)==0);
  610.     count = 0;
  611.  
  612.     if ( keysym == NoSymbol ) {
  613.     DBUG_RETURN(0);
  614.     } else if ((keysym >> 8) == kset) {
  615.     count = 1;
  616.     switch (kset) {
  617.     case sKana:
  618.         *buf = (unsigned char)(keysym & 0xff);
  619.         if (buf[0] == 0x7e)
  620.         count = 0;
  621.         break;
  622.     case sCyrillic:
  623.         if (locale_code == sKoi8)
  624.         *buf = _Xkoi8[keysym & 0x7f];
  625.         else
  626.         *buf = _Xcyrillic[keysym & 0x7f];
  627.         break;
  628.     case sGreek:
  629.         *buf = _Xgreek[keysym & 0x7f];
  630.         if (!buf[0])
  631.         count = 0;
  632.         break;
  633.     default:
  634.         *buf = (unsigned char)(keysym & 0xff);
  635.         break;
  636.     }
  637.     } else if ((locale_code != 0) && (isLatin1) && (keysym & 0x80)) {
  638.     if (_Xlatin1[keysym & 0x7f] & (1 << kset)) {
  639.         /* Most non-latin1 locales use some latin-1 upper half
  640.            keysyms as defined by bitpatterns in array latin1.
  641.            Enforce it. */
  642.         *buf = (unsigned char)(keysym & 0xff);
  643.         count = 1;
  644.     } else {
  645.         count= 1;
  646.         if ((locale_code == sHebrew) && (keysym == XK_multiply))
  647.         *buf = (unsigned char)0xaa;
  648.         else if ((locale_code == sHebrew) && (keysym == XK_division))
  649.         *buf = (unsigned char)0xba;
  650.         else if ((locale_code == sCyrillic) && (keysym == XK_section))
  651.         *buf = (unsigned char)0xfd;
  652.         else if ((locale_code == sX0201) && (keysym == XK_yen))
  653.         *buf = (unsigned char)0x5c;
  654.         else count = 0;
  655.     }
  656.     } else if (isLatin1) {
  657.     if ((locale_code == sX0201) &&
  658.         ((keysym == XK_backslash) || (keysym == XK_asciitilde)))
  659.         count = 0;
  660.     if ( (keysym&0x80)==0 ) {
  661.         *buf = (unsigned char)(keysym&0x7f);
  662.         count = 1;
  663.     }
  664.     } else if ((keysym >> 8) == sLatin2) {
  665.     count = 1;
  666.     if ((keysym & 0x80) && (_Xlatin2[keysym & 0x7f] & (1 << kset)))
  667.         *buf = (unsigned char)(keysym & 0xff);
  668.     else if (locale_code == sLatin5) {
  669.         if (keysym == XK_Scedilla)
  670.         *buf = (unsigned char)0xde;
  671.         else if (keysym == XK_scedilla)
  672.         *buf = (unsigned char)0xfe;
  673.         else count = 0;
  674.     } else if (locale_code == sLatin9) {
  675.         if (keysym == XK_Scaron)
  676.         *buf = (unsigned char)0xa6;
  677.         else if (keysym == XK_scaron)
  678.         *buf = (unsigned char)0xa8;
  679.         else if (keysym == XK_Zcaron)
  680.         *buf = (unsigned char)0xb4;
  681.         else if (keysym == XK_zcaron)
  682.         *buf = (unsigned char)0xb8;
  683.         else count = 0;
  684.     } else count = 0;
  685.     } else if ((keysym >> 8) == sLatin3) {
  686.     if (locale_code == sLatin5) {
  687.         count = 1;
  688.         switch (keysym) {
  689.         case XK_Gbreve:    *buf = (unsigned char)0xd0; break;
  690.         case XK_gbreve:    *buf = (unsigned char)0xf0; break;
  691.         case XK_Scedilla:    *buf = (unsigned char)0xde; break;
  692.         case XK_scedilla:    *buf = (unsigned char)0xfe; break;
  693.         case XK_Iabovedot:    *buf = (unsigned char)0xdd; break;
  694.         case XK_idotless:    *buf = (unsigned char)0xfd; break;
  695.         default:  count = 0;
  696.         }
  697.     }
  698.     } else if ((keysym >> 8) == sLatin4) {
  699.     if (locale_code == sLatin6) {
  700.         count = 1;
  701.         switch (keysym) {
  702.         case XK_Emacron:    *buf = (unsigned char)0xa2; break;
  703.         case XK_Gcedilla:    *buf = (unsigned char)0xa3; break;
  704.         case XK_Imacron:    *buf = (unsigned char)0xa4; break;
  705.         case XK_Lcedilla:    *buf = (unsigned char) 0xa8; break;
  706.         case XK_Dstroke:    *buf = (unsigned char)0xa9; break;
  707.         case XK_Scaron:    *buf = (unsigned char)0xaa; break;
  708.         case XK_Tslash:    *buf = (unsigned char)0xab; break;
  709.         case XK_Zcaron:    *buf = (unsigned char)0xac; break;
  710.         case XK_Umacron:    *buf = (unsigned char)0xae; break;
  711.         case XK_Utilde:    *buf = (unsigned char)0xd7; break;
  712.         case XK_ENG:    *buf = (unsigned char)0xaf; break;
  713.         case XK_emacron:    *buf = (unsigned char)0xb2; break;
  714.         case XK_gcedilla:    *buf = (unsigned char)0xb3; break;
  715.         case XK_imacron:    *buf = (unsigned char)0xb4; break;
  716.         case XK_lcedilla:    *buf = (unsigned char) 0xb8; break;
  717.         case XK_dstroke:    *buf = (unsigned char)0xb9; break;
  718.         case XK_scaron:    *buf = (unsigned char)0xba; break;
  719.         case XK_tslash:    *buf = (unsigned char)0xbb; break;
  720.         case XK_zcaron:    *buf = (unsigned char)0xbc; break;
  721.         case XK_umacron:    *buf = (unsigned char)0xbe; break;
  722.         case XK_utilde:    *buf = (unsigned char)0xf7; break;
  723.         case XK_eng:    *buf = (unsigned char)0xbf; break;
  724.         case XK_kra:    *buf = (unsigned char)0xff; break;
  725.         case XK_Itilde:
  726.         case XK_Kcedilla: 
  727.         case XK_Iogonek:
  728.         case XK_Ncedilla:
  729.         case XK_Omacron:
  730.         case XK_Uogonek:
  731.         case XK_itilde:
  732.         case XK_kcedilla: 
  733.         case XK_iogonek:
  734.         case XK_ncedilla:
  735.         case XK_omacron:
  736.         case XK_uogonek:    *buf = (unsigned char)(keysym & 0xff); break;
  737.         default: count = 0;
  738.         }
  739.     }
  740.     } else if (locale_code == sLatin9 && keysym == XK_EuroSign) {
  741.     count = 1;
  742.     *buf = (unsigned char)0xa4;
  743.     } else if ((locale_code == sGreek) &&
  744.            ((keysym == XK_leftsinglequotemark) ||
  745.         (keysym == XK_rightsinglequotemark))) {
  746.     *buf = (unsigned char)(keysym - (XK_leftsinglequotemark - 0xa1));
  747.     count = 1;
  748.     }
  749.     if (count>nbytes)
  750.     DBUG_RETURN(nbytes);
  751.     if (count<nbytes)
  752.     buf[count]= '\0';
  753.     DBUG_RETURN(count);
  754. }
  755.  
  756. #ifdef XKB
  757. static int lookup_string (event, buffer, nbytes, keysym, status)
  758.     XKeyEvent*        event;
  759.     char*        buffer;
  760.     int            nbytes;
  761.     KeySym*        keysym;
  762.     XComposeStatus*    status;
  763. {
  764.     DBUG_ENTER("lookup_string")
  765.     int ret;
  766.     unsigned ctrls;
  767.     ctrls = XkbGetXlibControls (event->display);
  768.     XkbSetXlibControls (event->display, 
  769.             XkbLC_ForceLatin1Lookup, XkbLC_ForceLatin1Lookup);
  770.     ret = XLookupString(event, (char *)buffer, nbytes, keysym, status);
  771.     XkbSetXlibControls (event->display, ctrls, ctrls);
  772.     DBUG_RETURN(ret);
  773. }
  774. #endif
  775.  
  776. #define BUF_SIZE (20)
  777.  
  778. int
  779. _XimLookupMBText(ic, event, buffer, nbytes, keysym, status)
  780.     Xic             ic;
  781.     XKeyEvent*        event;
  782.     char*        buffer;
  783.     int            nbytes;
  784.     KeySym*        keysym;
  785.     XComposeStatus*    status;
  786. {
  787.     DBUG_ENTER("_XimLookupMBText")
  788.     int count, local_count;
  789.     KeySym symbol;
  790.     struct CodesetRec *cset;
  791.     int i;
  792.     unsigned char c;
  793.     Status    dummy;
  794.     Xim    im;
  795.     XLCd lcd;
  796.     unsigned char local_buf[BUF_SIZE];
  797.     unsigned char look[BUF_SIZE];
  798.     im = (Xim)ic->core.im;
  799.     lcd = im->core.lcd;
  800.  
  801.     /* force a latin-1 lookup for compatibility */
  802.     count = XLOOKUPSTRING(event, (char *)buffer, nbytes, &symbol, status);
  803.     if (keysym != NULL) *keysym = symbol;
  804.     if ((nbytes == 0) || (symbol == NoSymbol)) DBUG_RETURN(count);
  805.  
  806.     for (cset = NULL, i = 0; i < NUM_CODESETS; i++) {
  807.     if (strcmp (XLC_PUBLIC(lcd,encoding_name), CodesetTable[i].locale_name) == 0) {
  808.         cset = &CodesetTable[i];
  809.         break;
  810.     }
  811.     }
  812.     if (count == 0 && cset != NULL || 
  813.     (count == 1 && (symbol > 0x7f && symbol < 0xff00) && 
  814.      cset != NULL && cset->locale_code != 0)) {
  815.     if ((count = _XGetCharCode(cset->locale_code, symbol,
  816.                    look, sizeof look))) {
  817.         strcpy((char*) local_buf, cset->escape_seq);
  818.         local_count = strlen(cset->escape_seq);
  819.         local_buf[local_count] = look[0];
  820.         local_count++;
  821.         local_buf[local_count] = '\0';
  822.         if ((count = im->methods->ctstombs(ic->core.im,
  823.                 (char*) local_buf, local_count,
  824.                 (char *)buffer, nbytes, &dummy)) < 0) {
  825.         count = 0;
  826.         }
  827.     }
  828.     } else if (count > 1) { /* not ASCII Encoding */
  829.     memcpy(look, (char *)buffer,count);
  830.     look[count] = '\0';
  831.     if ((count = im->methods->ctstombs(ic->core.im,
  832.                 (char*) look, count, 
  833.                 buffer, nbytes, &dummy)) < 0) {
  834.         count = 0;
  835.     }
  836.     }
  837.     /* 
  838.      * we should make sure that if the character is a Latin1 character
  839.      * and it's on the right side, and we're in a non-Latin1 locale
  840.      * that this is a valid Latin1 character for this locale.
  841.      */
  842.     DBUG_RETURN(count);
  843. }
  844.  
  845. int
  846. _XimLookupWCText(ic, event, buffer, nbytes, keysym, status)
  847.     Xic             ic;
  848.     XKeyEvent*        event;
  849.     wchar_t*        buffer;
  850.     int            nbytes;
  851.     KeySym*        keysym;
  852.     XComposeStatus*    status;
  853. {
  854.     DBUG_ENTER("_XimLookupWCText")
  855.     int count, local_count;
  856.     KeySym symbol;
  857.     struct CodesetRec *cset;
  858.     int i;
  859.     unsigned char c;
  860.     Status    dummy;
  861.     Xim    im = (Xim)ic->core.im;
  862.     XLCd lcd = im->core.lcd;
  863.     unsigned char local_buf[BUF_SIZE];
  864.     unsigned char look[BUF_SIZE];
  865.  
  866.     /* force a latin-1 lookup for compatibility */
  867.     count = XLOOKUPSTRING(event, (char *)look, nbytes, &symbol, status);
  868.     if (keysym != NULL) *keysym = symbol;
  869.     if ((nbytes == 0) || (symbol == NoSymbol)) DBUG_RETURN(count);
  870.  
  871.     for (cset = NULL, i = 0; i < NUM_CODESETS; i++) {
  872.     if (strcmp (XLC_PUBLIC(lcd,encoding_name), CodesetTable[i].locale_name) == 0) {
  873.         cset = &CodesetTable[i];
  874.         break;
  875.     }
  876.     }
  877.     if (count == 0 && cset != NULL ||
  878.     (count == 1 && (symbol > 0x7f && symbol < 0xff00) && 
  879.      cset != NULL && cset->locale_code != 0)) {
  880.     if ((count = _XGetCharCode(cset->locale_code, symbol,
  881.                    look, sizeof look))) {
  882.         strcpy((char*) local_buf, cset->escape_seq);
  883.         local_count = strlen(cset->escape_seq);
  884.         local_buf[local_count] = look[0];
  885.         local_count++;
  886.         local_buf[local_count] = '\0';
  887.         if ((count = im->methods->ctstowcs(ic->core.im,
  888.                 (char*) local_buf, local_count,
  889.                 buffer, nbytes, &dummy)) < 0) {
  890.         count = 0;
  891.         }
  892.     }
  893.     } else if (count > 1) {
  894.     if ((count = im->methods->ctstowcs(ic->core.im,
  895.                 (char*) look, count, 
  896.                 buffer, nbytes, &dummy)) < 0) {
  897.         count = 0;
  898.     }
  899.     } else
  900.     /* 
  901.      * we should make sure that if the character is a Latin1 character
  902.      * and it's on the right side, and we're in a non-Latin1 locale
  903.      * that this is a valid Latin1 character for this locale.
  904.      */
  905.     buffer[0] = look[0];
  906.  
  907.     DBUG_RETURN(count);
  908. }
  909.