Home | History | Annotate | Line # | Download | only in src
      1 /******************************************************************
      2 
      3               Copyright 1991, 1992 by Fuji Xerox Co.,Ltd.
      4 	      Copyright 1993, 1994 by FUJITSU LIMITED
      5 
      6 Permission to use, copy, modify, distribute, and sell this software
      7 and its documentation for any purpose is hereby granted without fee,
      8 provided that the above copyright notice appear in all copies and
      9 that both that copyright notice and this permission notice appear
     10 in supporting documentation, and that the name of Fuji Xerox Co.,Ltd.
     11 , and that the name of FUJITSU LIMITED not be used in advertising or
     12 publicity pertaining to distribution of the software without specific,
     13  written prior permission.
     14 Fuji Xerox Co.,Ltd. , and FUJITSU LIMITED makes no representations about
     15 the suitability of this software for any purpose.
     16 It is provided "as is" without express or implied warranty.
     17 
     18 FUJI XEROX CO.,LTD. AND FUJITSU LIMITED DISCLAIMS ALL WARRANTIES WITH
     19 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
     20 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX CO.,LTD.
     21 AND FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT
     22 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
     23 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
     24 NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
     25 THE USE OR PERFORMANCE OF THIS SOFTWARE.
     26 
     27   Author:   Kazunori Nishihara, Fuji Xerox Co.,Ltd.
     28                                 kaz (at) ssdev.ksp.fujixerox.co.jp
     29   Modifier: Takashi Fujiwara    FUJITSU LIMITED
     30                                 fujiwara (at) a80.tech.yk.fujitsu.co.jp
     31 
     32 ******************************************************************/
     33 /* 2000 Modifier: Ivan Pascal	The XFree86 Project.
     34  */
     35 
     36 #ifdef HAVE_CONFIG_H
     37 #include <config.h>
     38 #endif
     39 #include <stdio.h>
     40 #include "Xlibint.h"
     41 #include "Xlcint.h"
     42 #include "Ximint.h"
     43 #include "XlcPubI.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 typedef unsigned int ucs4_t;
     58 
     59 typedef int (*ucstocsConvProc)(
     60     XPointer,
     61     unsigned char *,
     62     ucs4_t,
     63     int
     64 );
     65 
     66 struct SubstRec {
     67     const char encoding_name[8];
     68     const char charset_name[12];
     69 };
     70 
     71 static const struct SubstRec SubstTable[] = {
     72     {"STRING", "ISO8859-1"},
     73     {"TIS620", "TIS620-0"},
     74     {"UTF-8",  "ISO10646-1"}
     75 };
     76 #define num_substitute (sizeof SubstTable / sizeof SubstTable[0])
     77 
     78 /*
     79  * Given the name of a charset, returns the pointer to convertors
     80  * from UCS char to specified charset char.
     81  * This converter is needed for _XimGetCharCode subroutine.
     82  */
     83 XPointer
     84 _XimGetLocaleCode (
     85     _Xconst char*	encoding_name)
     86 {
     87     XPointer cvt = _Utf8GetConvByName(encoding_name);
     88     if (!cvt && encoding_name) {
     89        int i;
     90        for (i = 0; i < num_substitute; i++)
     91            if (!strcmp(encoding_name, SubstTable[i].encoding_name))
     92                return _Utf8GetConvByName(SubstTable[i].charset_name);
     93     }
     94     return cvt;
     95 }
     96 
     97 /*
     98  * Returns the locale dependent representation of a keysym.
     99  * The locale's encoding is passed in form of pointer to UCS converter.
    100  * The resulting multi-byte sequence is placed starting at buf (a buffer
    101  * with nbytes bytes, nbytes should be >= 8) and is NUL terminated.
    102  * Returns the length of the resulting multi-byte sequence, excluding the
    103  * terminating NUL byte. Return 0 if the keysym is not representable in the
    104  * locale
    105  */
    106 /*ARGSUSED*/
    107 int
    108 _XimGetCharCode (
    109     XPointer            ucs_conv,
    110     KeySym 		keysym,
    111     unsigned char*	buf,
    112     int 		nbytes)
    113 {
    114     int count = 0;
    115     ucstocsConvProc cvt = (ucstocsConvProc) ucs_conv;
    116     ucs4_t ucs4;
    117 
    118     if (keysym < 0x80) {
    119         buf[0] = (char) keysym;
    120         count = 1;
    121     } else if (cvt) {
    122         ucs4 = KeySymToUcs4(keysym);
    123         if (ucs4)
    124             count = (*cvt)((XPointer)NULL, buf, ucs4, nbytes);
    125     }
    126 
    127     if (count < 0)
    128        	count = 0;
    129     if (count>nbytes)
    130         return nbytes;
    131     if (count<nbytes)
    132         buf[count]= '\0';
    133     return count;
    134 }
    135 
    136 #ifdef XKB
    137 static int lookup_string(
    138     XKeyEvent*		event,
    139     char*		buffer,
    140     int			nbytes,
    141     KeySym*		keysym,
    142     XComposeStatus*	status)
    143 {
    144     int ret;
    145     unsigned ctrls = XkbGetXlibControls (event->display);
    146     XkbSetXlibControls (event->display,
    147 			XkbLC_ForceLatin1Lookup, XkbLC_ForceLatin1Lookup);
    148     ret = XLookupString(event, (char *)buffer, nbytes, keysym, status);
    149     XkbSetXlibControls (event->display,
    150 			XkbLC_ForceLatin1Lookup, ctrls);
    151     return ret;
    152 }
    153 #endif
    154 
    155 #define BUF_SIZE (20)
    156 
    157 int
    158 _XimLookupMBText(
    159     Xic			 ic,
    160     XKeyEvent*		event,
    161     char*		buffer,
    162     int			nbytes,
    163     KeySym*		keysym,
    164     XComposeStatus*	status)
    165 {
    166     int count;
    167     KeySym symbol;
    168     Status	dummy;
    169     Xim	im = (Xim)ic->core.im;
    170     XimCommonPrivateRec* private = &im->private.common;
    171     unsigned char look[BUF_SIZE];
    172     ucs4_t ucs4;
    173 
    174     /* force a latin-1 lookup for compatibility */
    175     count = XLOOKUPSTRING(event, (char *)buffer, nbytes, &symbol, status);
    176     if (keysym != NULL) *keysym = symbol;
    177     if ((nbytes == 0) || (symbol == NoSymbol)) return count;
    178 
    179     if (count > 1) {
    180 	if ((unsigned)count >= sizeof(look))
    181 	    return 0;
    182 	memcpy(look, (char *)buffer,count);
    183 	look[count] = '\0';
    184 	if ((count = im->methods->ctstombs(ic->core.im,
    185 				(char*) look, count,
    186 				buffer, nbytes, &dummy)) < 0) {
    187 	    count = 0;
    188 	}
    189     } else if ((count == 0) ||
    190 	       (count == 1 && (symbol > 0x7f && symbol < 0xff00))) {
    191 
    192         XPointer from = (XPointer) &ucs4;
    193         XPointer to =   (XPointer) look;
    194         int from_len = 1;
    195         int to_len = BUF_SIZE;
    196         XPointer args[1];
    197         XlcCharSet charset;
    198         args[0] = (XPointer) &charset;
    199         ucs4 = (ucs4_t) KeySymToUcs4(symbol);
    200         if (!ucs4)
    201             return 0;
    202 
    203 	if (_XlcConvert(private->ucstoc_conv,
    204                         &from, &from_len, &to, &to_len,
    205                         args, 1 ) != 0) {
    206 	    count = 0;
    207 	} else {
    208             from = (XPointer) look;
    209             to =   (XPointer) buffer;
    210             from_len = BUF_SIZE - to_len;
    211             to_len = nbytes;
    212             args[0] = (XPointer) charset;
    213 	    if (_XlcConvert(private->cstomb_conv,
    214                             &from, &from_len, &to, &to_len,
    215 			    args, 1 ) != 0) {
    216 		count = 0;
    217 	    } else {
    218                 count = nbytes - to_len;
    219 	    }
    220 	}
    221     }
    222     /* FIXME:
    223      * we should make sure that if the character is a Latin1 character
    224      * and it's on the right side, and we're in a non-Latin1 locale
    225      * that this is a valid Latin1 character for this locale.
    226      */
    227     return count;
    228 }
    229 
    230 int
    231 _XimLookupWCText(
    232     Xic			 ic,
    233     XKeyEvent*		event,
    234     wchar_t*		buffer,
    235     int			nbytes,
    236     KeySym*		keysym,
    237     XComposeStatus*	status)
    238 {
    239     int count;
    240     KeySym symbol;
    241     Status	dummy;
    242     Xim	im = (Xim)ic->core.im;
    243     XimCommonPrivateRec* private = &im->private.common;
    244     unsigned char look[BUF_SIZE];
    245     ucs4_t ucs4;
    246 
    247     /* force a latin-1 lookup for compatibility */
    248     count = XLOOKUPSTRING(event, (char *)look, nbytes, &symbol, status);
    249     if (keysym != NULL) *keysym = symbol;
    250     if ((nbytes == 0) || (symbol == NoSymbol)) return count;
    251 
    252     if (count > 1) {
    253 	if ((count = im->methods->ctstowcs(ic->core.im,
    254 				(char*) look, count,
    255 				buffer, nbytes, &dummy)) < 0) {
    256 	    count = 0;
    257 	}
    258     } else if ((count == 0) ||
    259 	       (count == 1 && (symbol > 0x7f && symbol < 0xff00))) {
    260 
    261         XPointer from = (XPointer) &ucs4;
    262         XPointer to =   (XPointer) look;
    263         int from_len = 1;
    264         int to_len = BUF_SIZE;
    265         XPointer args[1];
    266         XlcCharSet charset;
    267         args[0] = (XPointer) &charset;
    268         ucs4 = (ucs4_t) KeySymToUcs4(symbol);
    269         if (!ucs4)
    270             return 0;
    271 
    272 	if (_XlcConvert(private->ucstoc_conv,
    273                         &from, &from_len, &to, &to_len,
    274                         args, 1 ) != 0) {
    275 	    count = 0;
    276 	} else {
    277             from = (XPointer) look;
    278             to =   (XPointer) buffer;
    279             from_len = BUF_SIZE - to_len;
    280             to_len = nbytes;
    281             args[0] = (XPointer) charset;
    282 
    283 	    if (_XlcConvert(private->cstowc_conv,
    284                             &from, &from_len, &to, &to_len,
    285 			    args, 1 ) != 0) {
    286 		count = 0;
    287 	    } else {
    288                 count = nbytes - to_len;
    289 	    }
    290 	}
    291     } else
    292 	/* FIXME:
    293 	 * we should make sure that if the character is a Latin1 character
    294 	 * and it's on the right side, and we're in a non-Latin1 locale
    295 	 * that this is a valid Latin1 character for this locale.
    296 	 */
    297 	buffer[0] = look[0];
    298 
    299     return count;
    300 }
    301 
    302 int
    303 _XimLookupUTF8Text(
    304     Xic			 ic,
    305     XKeyEvent*		event,
    306     char*		buffer,
    307     int			nbytes,
    308     KeySym*		keysym,
    309     XComposeStatus*	status)
    310 {
    311     int count;
    312     KeySym symbol;
    313     Status	dummy;
    314     Xim	im = (Xim)ic->core.im;
    315     XimCommonPrivateRec* private = &im->private.common;
    316     unsigned char look[BUF_SIZE];
    317     ucs4_t ucs4;
    318 
    319     /* force a latin-1 lookup for compatibility */
    320     count = XLOOKUPSTRING(event, (char *)buffer, nbytes, &symbol, status);
    321     if (keysym != NULL) *keysym = symbol;
    322     if ((nbytes == 0) || (symbol == NoSymbol)) return count;
    323 
    324     if (count > 1) {
    325 	if ((unsigned)count >= sizeof(look))
    326 	    return 0;
    327 	memcpy(look, (char *)buffer,count);
    328 	look[count] = '\0';
    329 	if ((count = im->methods->ctstoutf8(ic->core.im,
    330 				(char*) look, count,
    331 				buffer, nbytes, &dummy)) < 0) {
    332 	    count = 0;
    333 	}
    334     } else if ((count == 0) ||
    335 	       (count == 1 && (symbol > 0x7f && symbol < 0xff00))) {
    336 
    337         XPointer from = (XPointer) &ucs4;
    338         int from_len = 1;
    339         XPointer to = (XPointer) buffer;
    340         int to_len = nbytes;
    341 
    342         ucs4 = (ucs4_t) KeySymToUcs4(symbol);
    343         if (!ucs4)
    344             return 0;
    345 
    346 	if (_XlcConvert(private->ucstoutf8_conv,
    347                         &from, &from_len, &to, &to_len,
    348                         NULL, 0) != 0) {
    349 	    count = 0;
    350 	} else {
    351             count = nbytes - to_len;
    352 	}
    353     }
    354     /* FIXME:
    355      * we should make sure that if the character is a Latin1 character
    356      * and it's on the right side, and we're in a non-Latin1 locale
    357      * that this is a valid Latin1 character for this locale.
    358      */
    359     return count;
    360 }
    361