Home | History | Annotate | Line # | Download | only in ximcp
      1 /*
      2  * Copyright (c) 1990, 1991, 1992, Oracle and/or its affiliates.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  */
     23 
     24 /******************************************************************
     25          Copyright 1992, 1993, 1994 by FUJITSU LIMITED
     26          Copyright 1993, 1994 by Sony Corporation
     27 
     28 Permission to use, copy, modify, and distribute this software and its
     29 documentation for any purpose and without fee is hereby granted,
     30 provided that the above copyright notice appear in all copies and that
     31 both that copyright notice and this permission notice appear in
     32 supporting documentation, and that the names of Digital, FUJITSU
     33 LIMITED and Sony Corporation not be used in advertising or publicity
     34 pertaining to distribution of the software without specific, written
     35 prior permission.
     36 
     37 DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES
     38 WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
     39 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED
     40 AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     41 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
     42 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
     43 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     44 PERFORMANCE OF THIS SOFTWARE.
     45 
     46   Author: Hideki Hiura (hhiura (at) Sun.COM) Sun Microsystems, Inc.
     47           Takashi Fujiwara     FUJITSU LIMITED
     48                                fujiwara (at) a80.tech.yk.fujitsu.co.jp
     49           Makoto Wakamatsu     Sony Corporation
     50                                makoto (at) sm.sony.co.jp
     51 
     52 ******************************************************************/
     53 
     54 #ifdef HAVE_CONFIG_H
     55 #include <config.h>
     56 #endif
     57 #include <X11/Xatom.h>
     58 #include "Xlibint.h"
     59 #include "Xlcint.h"
     60 #include "XlcPublic.h"
     61 #include "XlcPubI.h"
     62 #include "XimTrInt.h"
     63 #include "Ximint.h"
     64 
     65 #include <limits.h>
     66 #include <stdlib.h>
     67 #include <strings.h>
     68 
     69 int
     70 _XimCheckDataSize(
     71     XPointer	 buf,
     72     int		 len)
     73 {
     74     CARD16	*buf_s = (CARD16 *)buf;
     75 
     76     if(len < XIM_HEADER_SIZE)
     77 	return -1;
     78     return  buf_s[1];
     79 }
     80 
     81 void
     82 _XimSetHeader(
     83     XPointer	 buf,
     84     CARD8	 major_opcode,
     85     CARD8	 minor_opcode,
     86     INT16	*len
     87 )
     88 {
     89     CARD8	*buf_b = (CARD8 *)buf;
     90     CARD16	*buf_s = (CARD16 *)buf;
     91 
     92     buf_b[0] = major_opcode;
     93     buf_b[1] = minor_opcode;
     94     buf_s[1] = ((*len) / 4);
     95     *len += XIM_HEADER_SIZE;
     96     return;
     97 }
     98 
     99 char
    100 _XimGetMyEndian(void)
    101 {
    102     CARD16	 test_card = 1;
    103 
    104     if(*((char *)&test_card))
    105 	return LITTLEENDIAN;
    106     else
    107 	return BIGENDIAN;
    108 }
    109 
    110 static Bool
    111 _XimCheckServerName(
    112     Xim		   im,
    113     char	  *str)
    114 {
    115     char	  *server_name = im->core.im_name;
    116     int		   len;
    117     int		   str_len;
    118     int		   category_len = strlen(XIM_SERVER_CATEGORY);
    119     char	  *pp;
    120     register char *p;
    121 
    122     if(server_name && *server_name)
    123 	len = strlen(server_name);
    124     else
    125 	return True;
    126 
    127     if((int)strlen(str) < category_len)
    128 	return False;
    129 
    130     if(strncmp(str, XIM_SERVER_CATEGORY, category_len))
    131 	return False;
    132 
    133     pp = &str[category_len];
    134 
    135     for(;;) {
    136 	for(p = pp; (*p != ',') && (*p); p++);
    137 	str_len = (int)(p - pp);
    138 
    139 	if((len == str_len) && (!strncmp(pp, server_name, len)))
    140 	    break;
    141 	if(!(*p))
    142 	    return False;
    143 	pp = p + 1;
    144     }
    145     return True;
    146 }
    147 
    148 static char *
    149 _XimCheckLocaleName(
    150     Xim		   im,
    151     char	  *address,
    152     int		   address_len,
    153     char	  *locale_name[],
    154     int		   len)
    155 {
    156     int		   category_len;
    157     char	  *pp;
    158     register char *p;
    159     register int   n;
    160     Bool           finish = False;
    161 
    162     category_len = strlen(XIM_LOCAL_CATEGORY);
    163     if(address_len < category_len)
    164 	return (char*)NULL;
    165 
    166     if(strncmp(address, XIM_LOCAL_CATEGORY, category_len))
    167 	return (char*)NULL;
    168 
    169     pp = &address[category_len];
    170 
    171     for(;;) {
    172 	for( p = pp; *p && *p != ','; p++);
    173 	if (!*p)
    174 	    finish = True;
    175 	address_len = (int)(p - pp);
    176 	*p = '\0';
    177 
    178 	for( n = 0; n < len; n++ )
    179 	    if( locale_name[n] && !_XlcCompareISOLatin1( pp, locale_name[n] ) )
    180 		return locale_name[n];
    181 	if (finish)
    182 	    break;
    183 	pp = p + 1;
    184     }
    185     return (char *)NULL;
    186 }
    187 
    188 static Bool
    189 _XimCheckTransport(
    190     char	  *address,
    191     int		   address_len,
    192     const char	  *transport,
    193     int		   len,
    194     char	 **trans_addr)
    195 {
    196     int		   category_len = strlen(XIM_TRANSPORT_CATEGORY);
    197     char	  *pp;
    198     register char *p;
    199 
    200     if(address_len < category_len)
    201 	return False;
    202 
    203     if(strncmp(address, XIM_TRANSPORT_CATEGORY, category_len))
    204 	return False;
    205 
    206     pp = &address[category_len];
    207 
    208     for(;;) {
    209 	*trans_addr = pp;
    210 
    211 	for(p = pp; (*p != '/') && (*p != ',') && (*p); p++);
    212 	if(*p == ',') {
    213 	    pp = p + 1;
    214 	    continue;
    215 	}
    216 	if(!(*p))
    217 	    return False;
    218 
    219 	address_len = (int)(p - pp);
    220 
    221 	if((len == address_len) && (!strncmp(pp, transport, len)))
    222 	    break;
    223 	pp = p + 1;
    224     }
    225     pp = p + 1;
    226     for(p = pp; (*p != ',') && (*p); p++);
    227     if (*p)
    228 	*p = '\0';
    229     return True;
    230 }
    231 
    232 static Bool
    233 _CheckSNEvent(
    234     Display		*display,
    235     XEvent		*xevent,
    236     XPointer		 arg)
    237 {
    238     XSelectionEvent	*event = (XSelectionEvent *)xevent;
    239     Window		 window = *(Window*)arg;
    240 
    241     if((event->type == SelectionNotify) && (window == event->requestor))
    242 	return True;
    243     return False;
    244 }
    245 
    246 static Bool
    247 _XimGetSelectionNotify(
    248     Display		 *display,
    249     Window		  window,
    250     Atom		  target,
    251     char		**ret_address)
    252 {
    253     XEvent		  event;
    254     XSelectionEvent	 *ev = (XSelectionEvent *)&event;
    255     Atom		  actual_type;
    256     int			  actual_format;
    257     unsigned long	  nitems, bytes_after;
    258 
    259     for(;;) {
    260 	XIfEvent(display, &event, _CheckSNEvent, (XPointer)&window);
    261 	if((ev->type == SelectionNotify) && (window == ev->requestor))
    262 	    break;
    263     }
    264 
    265     if(ev->property == (Atom)None)
    266 	return False;
    267     if( XGetWindowProperty( display, window, target, 0L, 1000000L,
    268 			    True, target, &actual_type, &actual_format,
    269 			    &nitems, &bytes_after,
    270 			    (unsigned char **)&*ret_address ) != Success )
    271 	return False;
    272     return True;
    273 }
    274 
    275 static Bool
    276 _XimPreConnectionIM(
    277     Xim			 im,
    278     Atom		 selection)
    279 {
    280     Display		*display = im->core.display;
    281     Atom		 locales, transport;
    282     char		*address;
    283     XLCd		 lcd;
    284     char		*language;
    285     char		*territory;
    286     char		*codeset;
    287     char		*trans_addr;
    288     char		*locale_name[4], *locale;
    289     int			 llen, tlen, clen;
    290     register int	 i;
    291     Window		 window;
    292     char		*str;
    293 
    294     if(!(lcd = im->core.lcd))
    295 	return False;
    296 
    297     for( i = 0; i < 4; i++ )
    298 	locale_name[i] = NULL;
    299     /* requestor window */
    300     if(!(window = XCreateSimpleWindow(display, DefaultRootWindow(display),
    301 			 				0, 0, 1, 1, 1, 0, 0)))
    302 	return False;
    303 
    304     /* server name check */
    305     if( !(str = XGetAtomName( display, selection )) )
    306 	goto Error;
    307     if(!_XimCheckServerName(im, str)) {
    308 	XFree( (XPointer)str );
    309 	goto Error;
    310     }
    311     XFree( (XPointer)str );
    312 
    313     /* locale name check */
    314     _XGetLCValues(lcd, XlcNLanguage, &language, XlcNTerritory, &territory,
    315                     XlcNCodeset, &codeset, NULL);
    316     llen = strlen( language );
    317     tlen = territory ? strlen( territory ): 0;
    318     clen = codeset ? strlen( codeset ): 0;
    319 
    320     if( tlen != 0  &&  clen != 0 ) {
    321 	if( (locale_name[0] = Xmalloc(llen+tlen+clen+3)) != NULL )
    322 	    sprintf( locale_name[0], "%s_%s.%s", language, territory, codeset );
    323     }
    324     if( clen != 0 ) {
    325 	if( (locale_name[1] = Xmalloc(llen+clen+2)) != NULL )
    326 	    sprintf( locale_name[1], "%s.%s", language, codeset );
    327 	else
    328 	    goto Error;
    329     }
    330     if( tlen != 0 ) {
    331 	if( (locale_name[2] = Xmalloc(llen+tlen+2)) != NULL )
    332 	    sprintf( locale_name[2], "%s_%s", language, territory );
    333 	else
    334 	    goto Error;
    335     }
    336     if( (locale_name[3] = strdup(language)) == NULL )
    337 	goto Error;
    338     if((locales = XInternAtom(display, XIM_LOCALES, True)) == (Atom)None)
    339 	goto Error;
    340 
    341     XConvertSelection(display, selection, locales, locales, window,
    342 		      CurrentTime);
    343     if(!(_XimGetSelectionNotify(display, window, locales, &address)))
    344 	goto Error;
    345 
    346     if((locale = _XimCheckLocaleName(im, address, strlen(address), locale_name,
    347 				     4)) == NULL) {
    348 	XFree((XPointer)address);
    349 	goto Error;
    350     }
    351     im->private.proto.locale_name = locale;
    352     for( i = 0; i < 4; i++ ) {
    353 	if( locale_name[i] != NULL  &&  locale_name[i] != locale ) {
    354 	    XFree( locale_name[i] );
    355 	    locale_name[i] = NULL;
    356 	}
    357     }
    358     XFree((XPointer)address);
    359 
    360     /* transport check */
    361     if((transport = XInternAtom(display, XIM_TRANSPORT, True)) == (Atom)None)
    362 	goto Error;
    363 
    364     XConvertSelection(display, selection, transport, transport, window,
    365 		      CurrentTime);
    366     if(!_XimGetSelectionNotify(display, window, transport, &address))
    367 	goto Error;
    368 
    369     for(i = 0; _XimTransportRec[i].transportname ; i++) {
    370 	if( _XimCheckTransport(address, strlen(address),
    371 				_XimTransportRec[i].transportname,
    372 				strlen(_XimTransportRec[i].transportname),
    373 				 &trans_addr)) {
    374 	    if( _XimTransportRec[i].config(im, trans_addr) ) {
    375 		XFree((XPointer)address);
    376 		XDestroyWindow(display, window);
    377 		return True;
    378 	    }
    379 	}
    380     }
    381 
    382     XFree((XPointer)address);
    383 Error:
    384     for( i = 0; i < 4; i++ )
    385 	if( locale_name[i] != NULL )
    386 	    XFree( locale_name[i] );
    387     XDestroyWindow(display, window);
    388     return False;
    389 }
    390 
    391 static Bool
    392 _XimPreConnect(
    393     Xim		    im)
    394 {
    395     Display	   *display = im->core.display;
    396     Atom	    imserver;
    397     Atom	    actual_type;
    398     int		    actual_format;
    399     unsigned long   nitems;
    400     unsigned long   bytes_after;
    401     unsigned char  *prop_return;
    402     Atom	   *atoms;
    403     Window	    im_window = 0;
    404     register int    i;
    405     const char	   *env_enable_fabricated_order;
    406 
    407     if((imserver = XInternAtom(display, XIM_SERVERS, True)) == (Atom)None)
    408 	return False;
    409 
    410     if(XGetWindowProperty(display, RootWindow(display, 0),
    411 			imserver, 0L, 1000000L, False, XA_ATOM, &actual_type,
    412 			&actual_format, &nitems, &bytes_after,
    413 			&prop_return) != Success)
    414 	return False;
    415 
    416     if( (actual_type != XA_ATOM) || (actual_format != 32) ) {
    417 	if( nitems )
    418 	    XFree((XPointer)prop_return);
    419 	return False;
    420     }
    421 
    422     atoms = (Atom *)prop_return;
    423     for(i = 0; i < nitems; i++) {
    424 	if((im_window = XGetSelectionOwner(display, atoms[i])) == (Window)None)
    425 	    continue;
    426 
    427 	if(_XimPreConnectionIM(im, atoms[i]))
    428 	    break;
    429     }
    430 
    431     XFree((XPointer)prop_return);
    432     if(i >= nitems)
    433 	return False;
    434 
    435     im->private.proto.im_window = im_window;
    436     im->private.proto.fabricated_serial = 0;
    437     im->private.proto.fabricated_time = 0;
    438     im->private.proto.enable_fabricated_order = True;
    439     env_enable_fabricated_order = getenv("LIBX11_ENABLE_FABRICATED_ORDER");
    440     if (env_enable_fabricated_order && *env_enable_fabricated_order) {
    441 	if (!strncasecmp(env_enable_fabricated_order, "0", 2) ||
    442 	    !strncasecmp(env_enable_fabricated_order, "false", 6)) {
    443 	    im->private.proto.enable_fabricated_order = False;
    444 	}
    445     }
    446     return True;
    447 }
    448 
    449 static Bool
    450 _XimGetAuthProtocolNames(
    451     Xim		 im,
    452     CARD16	*buf,
    453     CARD8	*num,
    454     INT16	*len)
    455 {
    456     if (!IS_USE_AUTHORIZATION_FUNC(im)) {
    457 	*num = 0;
    458 	*len = 0;
    459 	return True;
    460     }
    461     /*
    462      * Not yet
    463      */
    464     return True;
    465 }
    466 
    467 static Bool
    468 _XimSetAuthReplyData(
    469     Xim		 im,
    470     XPointer	 buf,
    471     INT16	*len)
    472 {
    473     /*
    474      * Not yet
    475      */
    476     *len = 0;
    477     return True;
    478 }
    479 
    480 static Bool
    481 _XimSetAuthNextData(
    482     Xim		 im,
    483     XPointer	 buf,
    484     INT16	*len)
    485 {
    486     /*
    487      * Not yet
    488      */
    489     *len = 0;
    490     return True;
    491 }
    492 
    493 static Bool
    494 _XimSetAuthRequiredData(
    495     Xim		 im,
    496     XPointer	 buf,
    497     INT16	*len)
    498 {
    499     /*
    500      * Not yet
    501      */
    502     *len = 0;
    503     return True;
    504 }
    505 
    506 static Bool
    507 _XimCheckAuthSetupData(
    508     Xim		 im,
    509     XPointer	 buf)
    510 {
    511     /*
    512      * Not yet
    513      */
    514     return True;
    515 }
    516 
    517 static Bool
    518 _XimCheckAuthNextData(
    519     Xim		 im,
    520     XPointer	 buf)
    521 {
    522     /*
    523      * Not yet
    524      */
    525     return True;
    526 }
    527 
    528 #define	NO_MORE_AUTH	2
    529 #define	GOOD_AUTH	1
    530 #define	BAD_AUTH	0
    531 
    532 static int
    533 _XimClientAuthCheck(
    534     Xim		 im,
    535     XPointer	 buf)
    536 {
    537     /*
    538      * Not yet
    539      */
    540     return NO_MORE_AUTH;
    541 }
    542 
    543 static void
    544 _XimAuthNG(
    545     Xim		 im)
    546 {
    547     CARD32	 buf32[BUFSIZE/4];
    548     CARD8	*buf = (CARD8 *)buf32;
    549     INT16	 len = 0;
    550 
    551     _XimSetHeader((XPointer)buf, XIM_AUTH_NG, 0, &len);
    552     (void)_XimWrite(im, len, (XPointer)buf);
    553     _XimFlush(im);
    554     return;
    555 }
    556 
    557 static Bool
    558 _XimAllRecv(
    559     Xim		 im,
    560     INT16	 len,
    561     XPointer	 data,
    562     XPointer	 arg)
    563 {
    564     return True;
    565 }
    566 
    567 #define	CLIENT_WAIT1		1
    568 #define	CLIENT_WAIT2		2
    569 
    570 static Bool
    571 _XimConnection(
    572     Xim		 im)
    573 {
    574     CARD32	 buf32[BUFSIZE/4];
    575     CARD8	*buf = (CARD8 *)buf32;
    576     CARD8	*buf_b = &buf[XIM_HEADER_SIZE];
    577     CARD16	*buf_s = (CARD16 *)((XPointer)buf_b);
    578     INT16	 len;
    579     CARD8	 num;
    580     CARD32	 reply32[BUFSIZE/4];
    581     char	*reply = (char *)reply32;
    582     XPointer	 preply;
    583     int		 buf_size;
    584     int		 ret_code;
    585     CARD8	 major_opcode;
    586     int		 wait_mode;
    587     int		 ret;
    588 
    589     if(!(_XimConnect(im)))	/* Transport Connect */
    590 	return False;
    591 
    592     if(!_XimDispatchInit(im))
    593 	return False;
    594 
    595     _XimRegProtoIntrCallback(im, XIM_ERROR, 0, _XimErrorCallback, (XPointer)im);
    596 
    597     if(!_XimGetAuthProtocolNames(im, &buf_s[4], &num, &len))
    598 	return False;
    599 
    600     im->private.proto.protocol_major_version = PROTOCOLMAJORVERSION;
    601     im->private.proto.protocol_minor_version = PROTOCOLMINORVERSION;
    602 
    603     buf_b[0] = _XimGetMyEndian();
    604     buf_b[1] = 0;
    605     buf_s[1] = PROTOCOLMAJORVERSION;
    606     buf_s[2] = PROTOCOLMINORVERSION;
    607     buf_s[3] = num;
    608     len  += sizeof(CARD8)
    609           + sizeof(CARD8)
    610           + sizeof(CARD16)
    611           + sizeof(CARD16)
    612           + sizeof(CARD16);
    613 
    614     major_opcode = XIM_CONNECT;
    615     wait_mode = (IS_USE_AUTHORIZATION_FUNC(im)) ? CLIENT_WAIT1 : CLIENT_WAIT2;
    616 
    617     for(;;) {
    618 	_XimSetHeader((XPointer)buf, major_opcode, 0, &len);
    619 	if (!(_XimWrite(im, len, (XPointer)buf)))
    620 	    return False;
    621 	_XimFlush(im);
    622 	buf_size = BUFSIZE;
    623 	ret_code = _XimRead(im, &len, reply, buf_size, _XimAllRecv, 0);
    624 	if(ret_code == XIM_TRUE) {
    625 	    preply = reply;
    626 	} else if(ret_code == XIM_OVERFLOW) {
    627 	    if(len <= 0) {
    628 		preply = reply;
    629 	    } else {
    630 		buf_size = len;
    631 		preply = Xmalloc(buf_size);
    632 		ret_code = _XimRead(im, &len, preply, buf_size, _XimAllRecv, 0);
    633 		if(ret_code != XIM_TRUE) {
    634 		    Xfree(preply);
    635 		    return False;
    636 		}
    637 	    }
    638 	} else
    639 	    return False;
    640 
    641 	major_opcode = *((CARD8 *)preply);
    642 	buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
    643 
    644 	if (wait_mode == CLIENT_WAIT1) {
    645 	    if (major_opcode == XIM_AUTH_REQUIRED) {
    646 		ret = _XimClientAuthCheck(im, (XPointer)buf_s);
    647 		if(reply != preply)
    648 		    Xfree(preply);
    649 		if (ret == NO_MORE_AUTH) {
    650 		    if (!(_XimSetAuthReplyData(im,
    651 				(XPointer)&buf[XIM_HEADER_SIZE], &len))) {
    652 			_XimAuthNG(im);
    653 			return False;
    654 		    }
    655 		    major_opcode = XIM_AUTH_REPLY;
    656 		    wait_mode = CLIENT_WAIT2;
    657 		} else if (ret == GOOD_AUTH) {
    658 		    if (!(_XimSetAuthNextData(im,
    659 				(XPointer)&buf[XIM_HEADER_SIZE], &len))) {
    660 			_XimAuthNG(im);
    661 			return False;
    662 		    }
    663 		    major_opcode = XIM_AUTH_NEXT;
    664 		} else {	/* BAD_AUTH */
    665 		    _XimAuthNG(im);
    666 		    return False;
    667 		}
    668 	    } else {
    669 		if(reply != preply)
    670 		    Xfree(preply);
    671 		_XimAuthNG(im);
    672 		return False;
    673 	    }
    674 	} else {	/* CLIENT_WAIT2 */
    675 	    if (major_opcode == XIM_CONNECT_REPLY) {
    676 		break;
    677 	    } else if (major_opcode == XIM_AUTH_SETUP) {
    678 		if (!(_XimCheckAuthSetupData(im, (XPointer)buf_s))) {
    679 		    _XimAuthNG(im);
    680 		    return False;
    681 		}
    682 		if(reply != preply)
    683 		    Xfree(preply);
    684 		if (!(_XimSetAuthRequiredData(im,
    685 				(XPointer)&buf[XIM_HEADER_SIZE], &len))) {
    686 		    _XimAuthNG(im);
    687 		    return False;
    688 		}
    689 		major_opcode = XIM_AUTH_REQUIRED;
    690 	    } else if (major_opcode == XIM_AUTH_NEXT) {
    691 		if (!(_XimCheckAuthNextData(im, (XPointer)buf_s))) {
    692 		    _XimAuthNG(im);
    693 		    return False;
    694 		}
    695 		if(reply != preply)
    696 		    Xfree(preply);
    697 		if (!(_XimSetAuthRequiredData(im,
    698 				(XPointer)&buf[XIM_HEADER_SIZE], &len))) {
    699 		    _XimAuthNG(im);
    700 		    return False;
    701 		}
    702 		major_opcode = XIM_AUTH_REQUIRED;
    703 	    } else if (major_opcode == XIM_AUTH_NG) {
    704 		if(reply != preply)
    705 		    Xfree(preply);
    706 		return False;
    707 	    } else {
    708 		_XimAuthNG(im);
    709 		if(reply != preply)
    710 		    Xfree(preply);
    711 		return False;
    712 	    }
    713 	}
    714     }
    715 
    716     if (!( buf_s[0] == im->private.proto.protocol_major_version
    717         && buf_s[1] == im->private.proto.protocol_minor_version)) {
    718 	if(reply != preply)
    719 	    Xfree(preply);
    720 	return False;
    721     }
    722     if(reply != preply)
    723 	Xfree(preply);
    724     MARK_SERVER_CONNECTED(im);
    725 
    726     _XimRegProtoIntrCallback(im, XIM_REGISTER_TRIGGERKEYS, 0,
    727 				 _XimRegisterTriggerKeysCallback, (XPointer)im);
    728     return True;
    729 }
    730 
    731 static Bool
    732 _XimDisconnectCheck(
    733     Xim		 im,
    734     INT16	 len,
    735     XPointer	 data,
    736     XPointer	 arg)
    737 {
    738     CARD8	 major_opcode = *((CARD8 *)data);
    739     CARD8	 minor_opcode = *((CARD8 *)data + 1);
    740 
    741     if ((major_opcode == XIM_DISCONNECT_REPLY)
    742      && (minor_opcode == 0))
    743 	return True;
    744     if ((major_opcode == XIM_ERROR)
    745      && (minor_opcode == 0))
    746 	return True;
    747     return False;
    748 }
    749 
    750 static Bool
    751 _XimDisconnect(
    752     Xim		 im)
    753 {
    754     CARD32	 buf32[BUFSIZE/4];
    755     CARD8	*buf = (CARD8 *)buf32;
    756     INT16	 len = 0;
    757     CARD32	 reply32[BUFSIZE/4];
    758     char	*reply = (char *)reply32;
    759     XPointer	 preply;
    760     int		 buf_size;
    761     int		 ret_code;
    762 
    763     if (IS_SERVER_CONNECTED(im)) {
    764 	_XimSetHeader((XPointer)buf, XIM_DISCONNECT, 0, &len);
    765 	if (!(_XimWrite(im, len, (XPointer)buf)))
    766 	    return False;
    767 	_XimFlush(im);
    768 	buf_size = BUFSIZE;
    769 	ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
    770 						_XimDisconnectCheck, 0);
    771 	if(ret_code == XIM_OVERFLOW) {
    772 	    if(len > 0) {
    773 		buf_size = len;
    774 		preply = Xmalloc(buf_size);
    775 		ret_code = _XimRead(im, &len, preply, buf_size,
    776 						 _XimDisconnectCheck, 0);
    777 		Xfree(preply);
    778 		if(ret_code != XIM_TRUE)
    779 		    return False;
    780 	    }
    781 	} else if(ret_code == XIM_FALSE)
    782 	    return False;
    783 
    784     }
    785     if (!(_XimShutdown(im)))	/* Transport shutdown */
    786 	return False;
    787     return True;
    788 }
    789 
    790 static Bool
    791 _XimOpenCheck(
    792     Xim		 im,
    793     INT16	 len,
    794     XPointer	 data,
    795     XPointer	 arg)
    796 {
    797     CARD8	 major_opcode = *((CARD8 *)data);
    798     CARD8	 minor_opcode = *((CARD8 *)data + 1);
    799 
    800     if ((major_opcode == XIM_OPEN_REPLY)
    801      && (minor_opcode == 0))
    802 	return True;
    803     if ((major_opcode == XIM_ERROR)
    804      && (minor_opcode == 0))
    805 	return True;
    806     return False;
    807 }
    808 
    809 static Bool
    810 _XimOpen(
    811     Xim			 im)
    812 {
    813     CARD32		 buf32[BUFSIZE/4];
    814     CARD8		*buf = (CARD8 *)buf32;
    815     CARD8		*buf_b = &buf[XIM_HEADER_SIZE];
    816     CARD16		*buf_s;
    817     INT16		 len;
    818     CARD32		 reply32[BUFSIZE/4];
    819     char		*reply = (char *)reply32;
    820     XPointer		 preply;
    821     int			 buf_size;
    822     int			 ret_code;
    823     char		*locale_name;
    824     size_t		 locale_len;
    825 
    826     locale_name = im->private.proto.locale_name;
    827     locale_len = strlen(locale_name);
    828     if (locale_len > UCHAR_MAX)
    829       return False;
    830     memset(buf32, 0, sizeof(buf32));
    831     buf_b[0] = (BYTE)locale_len;		/* length of locale name */
    832     memcpy(&buf_b[1], locale_name, locale_len);	   /* locale name */
    833     len = (INT16)(locale_len + sizeof(BYTE));	   /* sizeof length */
    834     XIM_SET_PAD(buf_b, len);			   /* pad */
    835 
    836     _XimSetHeader((XPointer)buf, XIM_OPEN, 0, &len);
    837     if (!(_XimWrite(im, len, (XPointer)buf)))
    838 	return False;
    839     _XimFlush(im);
    840     buf_size = BUFSIZE;
    841     ret_code = _XimRead(im, &len, reply, buf_size,
    842 					_XimOpenCheck, 0);
    843     if(ret_code == XIM_TRUE) {
    844 	preply = reply;
    845     } else if(ret_code == XIM_OVERFLOW) {
    846 	if(len <= 0) {
    847 	    preply = reply;
    848 	} else {
    849 	    buf_size = len;
    850 	    preply = Xmalloc(buf_size);
    851 	    ret_code = _XimRead(im, &len, preply, buf_size,
    852 					_XimOpenCheck, 0);
    853 	    if(ret_code != XIM_TRUE) {
    854 		Xfree(preply);
    855 		return False;
    856 	    }
    857 	}
    858     } else
    859 	return False;
    860     buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
    861     if (*((CARD8 *)preply) == XIM_ERROR) {
    862 	_XimProcError(im, 0, (XPointer)&buf_s[3]);
    863 	if(reply != preply)
    864 	    Xfree(preply);
    865 	return False;
    866     }
    867 
    868     im->private.proto.imid = buf_s[0];		/* imid */
    869 
    870     if (!(_XimGetAttributeID(im, &buf_s[1]))) {
    871 	if(reply != preply)
    872 	    Xfree(preply);
    873 	return False;
    874     }
    875     if(reply != preply)
    876 	Xfree(preply);
    877 
    878     if (!(_XimSetInnerIMResourceList(&(im->private.proto.im_inner_resources),
    879 				&(im->private.proto.im_num_inner_resources))))
    880 	return False;
    881 
    882     if (!(_XimSetInnerICResourceList(&(im->private.proto.ic_inner_resources),
    883 				&(im->private.proto.ic_num_inner_resources))))
    884 	return False;
    885 
    886     _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
    887     _XimSetIMMode(im->private.proto.im_inner_resources,
    888 				im->private.proto.im_num_inner_resources);
    889 
    890     /* Transport Callback */
    891     _XimRegProtoIntrCallback(im, XIM_SET_EVENT_MASK, 0,
    892 				 _XimSetEventMaskCallback, (XPointer)im);
    893     _XimRegProtoIntrCallback(im, XIM_FORWARD_EVENT, 0,
    894 				 _XimForwardEventCallback, (XPointer)im);
    895     _XimRegProtoIntrCallback(im, XIM_COMMIT, 0,
    896 				 _XimCommitCallback, (XPointer)im);
    897     _XimRegProtoIntrCallback(im, XIM_SYNC, 0,
    898 				 _XimSyncCallback, (XPointer)im);
    899 
    900     if(!_XimExtension(im))
    901 	return False;
    902 
    903     /* register a hook for callback protocols */
    904     _XimRegisterDispatcher(im, _XimCbDispatch, (XPointer)im);
    905 
    906     return True;
    907 }
    908 
    909 static Bool
    910 _XimCloseCheck(
    911     Xim		 im,
    912     INT16	 len,
    913     XPointer	 data,
    914     XPointer	 arg)
    915 {
    916     CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
    917     CARD8	 major_opcode = *((CARD8 *)data);
    918     CARD8	 minor_opcode = *((CARD8 *)data + 1);
    919     XIMID	 imid = buf_s[0];
    920 
    921     if ((major_opcode == XIM_CLOSE_REPLY)
    922      && (minor_opcode == 0)
    923      && (imid == im->private.proto.imid))
    924 	return True;
    925     if ((major_opcode == XIM_ERROR)
    926      && (minor_opcode == 0)
    927      && (buf_s[2] & XIM_IMID_VALID)
    928      && (imid == im->private.proto.imid))
    929 	return True;
    930     return False;
    931 }
    932 
    933 static Bool
    934 _XimClose(
    935     Xim		 im)
    936 {
    937     CARD32	 buf32[BUFSIZE/4];
    938     CARD8	*buf = (CARD8 *)buf32;
    939     CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
    940     INT16	 len;
    941     CARD32	 reply32[BUFSIZE/4];
    942     char	*reply = (char *)reply32;
    943     XPointer	 preply;
    944     int		 buf_size;
    945     int		 ret_code;
    946 
    947     if (!IS_SERVER_CONNECTED(im))
    948 	return True;
    949 
    950     buf_s[0] = im->private.proto.imid;		/* imid */
    951     buf_s[1] = 0;				/* unused */
    952     len = sizeof(CARD16)			/* sizeof imid */
    953         + sizeof(CARD16);			/* sizeof unused */
    954 
    955     _XimSetHeader((XPointer)buf, XIM_CLOSE, 0, &len);
    956     if (!(_XimWrite(im, len, (XPointer)buf)))
    957 	return False;
    958     _XimFlush(im);
    959     buf_size = BUFSIZE;
    960     ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
    961 						_XimCloseCheck, 0);
    962     if(ret_code == XIM_TRUE) {
    963 	preply = reply;
    964     } else if(ret_code == XIM_OVERFLOW) {
    965 	if(len <= 0) {
    966 	    preply = reply;
    967 	} else {
    968 	    buf_size = len;
    969 	    preply = Xmalloc(buf_size);
    970 	    ret_code = _XimRead(im, &len, preply, buf_size, _XimCloseCheck, 0);
    971 	    if(ret_code != XIM_TRUE) {
    972 		Xfree(preply);
    973 		return False;
    974 	    }
    975 	}
    976     } else
    977 	return False;
    978     buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
    979     if (*((CARD8 *)preply) == XIM_ERROR) {
    980 	_XimProcError(im, 0, (XPointer)&buf_s[3]);
    981 	if(reply != preply)
    982 	    Xfree(preply);
    983 	return False;
    984     }
    985 
    986     if(reply != preply)
    987 	Xfree(preply);
    988     return True;
    989 }
    990 
    991 void
    992 _XimProtoIMFree(
    993     Xim		  im)
    994 {
    995     /* XIMPrivateRec */
    996 
    997     Xfree(im->private.proto.im_onkeylist);
    998     im->private.proto.im_onkeylist = NULL;
    999 
   1000     Xfree(im->private.proto.im_offkeylist);
   1001     im->private.proto.im_offkeylist = NULL;
   1002 
   1003     if (im->private.proto.intrproto) {
   1004       _XimFreeProtoIntrCallback(im);
   1005       im->private.proto.intrproto = NULL;
   1006     }
   1007 
   1008     Xfree(im->private.proto.im_inner_resources);
   1009     im->private.proto.im_inner_resources = NULL;
   1010 
   1011     Xfree(im->private.proto.ic_inner_resources);
   1012     im->private.proto.ic_inner_resources = NULL;
   1013 
   1014     Xfree(im->private.proto.hold_data);
   1015     im->private.proto.hold_data = NULL;
   1016 
   1017     Xfree(im->private.proto.locale_name);
   1018     im->private.proto.locale_name = NULL;
   1019 
   1020     if (im->private.proto.ctom_conv) {
   1021 	_XlcCloseConverter(im->private.proto.ctom_conv);
   1022 	im->private.proto.ctom_conv = NULL;
   1023     }
   1024     if (im->private.proto.ctow_conv) {
   1025 	_XlcCloseConverter(im->private.proto.ctow_conv);
   1026 	im->private.proto.ctow_conv = NULL;
   1027     }
   1028     if (im->private.proto.ctoutf8_conv) {
   1029 	_XlcCloseConverter(im->private.proto.ctoutf8_conv);
   1030 	im->private.proto.ctoutf8_conv = NULL;
   1031     }
   1032     if (im->private.proto.cstomb_conv) {
   1033 	_XlcCloseConverter(im->private.proto.cstomb_conv);
   1034 	im->private.proto.cstomb_conv = NULL;
   1035     }
   1036     if (im->private.proto.cstowc_conv) {
   1037 	_XlcCloseConverter(im->private.proto.cstowc_conv);
   1038 	im->private.proto.cstowc_conv = NULL;
   1039     }
   1040     if (im->private.proto.cstoutf8_conv) {
   1041 	_XlcCloseConverter(im->private.proto.cstoutf8_conv);
   1042 	im->private.proto.cstoutf8_conv = NULL;
   1043     }
   1044     if (im->private.proto.ucstoc_conv) {
   1045 	_XlcCloseConverter(im->private.proto.ucstoc_conv);
   1046 	im->private.proto.ucstoc_conv = NULL;
   1047     }
   1048     if (im->private.proto.ucstoutf8_conv) {
   1049 	_XlcCloseConverter(im->private.proto.ucstoutf8_conv);
   1050 	im->private.proto.ucstoutf8_conv = NULL;
   1051     }
   1052 
   1053 #ifdef XIM_CONNECTABLE
   1054     if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
   1055 	return;
   1056     }
   1057 #endif /* XIM_CONNECTABLE */
   1058 
   1059     Xfree(im->private.proto.saved_imvalues);
   1060     im->private.proto.saved_imvalues = NULL;
   1061 
   1062     Xfree(im->private.proto.default_styles);
   1063     im->private.proto.default_styles = NULL;
   1064 
   1065     /* core */
   1066 
   1067     Xfree(im->core.res_name);
   1068     im->core.res_name = NULL;
   1069 
   1070     Xfree(im->core.res_class);
   1071     im->core.res_class = NULL;
   1072 
   1073     Xfree(im->core.im_values_list);
   1074     im->core.im_values_list = NULL;
   1075 
   1076     Xfree(im->core.ic_values_list);
   1077     im->core.ic_values_list = NULL;
   1078 
   1079     Xfree(im->core.im_name);
   1080     im->core.im_name = NULL;
   1081 
   1082     Xfree(im->core.styles);
   1083     im->core.styles = NULL;
   1084 
   1085     Xfree(im->core.im_resources);
   1086     im->core.im_resources = NULL;
   1087 
   1088     Xfree(im->core.ic_resources);
   1089     im->core.ic_resources = NULL;
   1090 
   1091     return;
   1092 }
   1093 
   1094 static Status
   1095 _XimProtoCloseIM(
   1096     XIM		 xim)
   1097 {
   1098     Xim		 im = (Xim)xim;
   1099     XIC		 ic;
   1100     XIC		 next;
   1101     Status	 status;
   1102 
   1103     ic = im->core.ic_chain;
   1104     while (ic) {
   1105 	(*ic->methods->destroy) (ic);
   1106 	next = ic->core.next;
   1107 #ifdef XIM_CONNECTABLE
   1108 	if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im))) {
   1109 	    Xfree (ic);
   1110 	}
   1111 #else
   1112 	Xfree (ic);
   1113 #endif /* XIM_CONNECTABLE */
   1114 	ic = next;
   1115     }
   1116 #ifdef XIM_CONNECTABLE
   1117     if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)))
   1118 	im->core.ic_chain = NULL;
   1119 #else
   1120     im->core.ic_chain = NULL;
   1121 #endif
   1122 
   1123     _XimUnregisterServerFilter(im);
   1124     _XimResetIMInstantiateCallback(im);
   1125     status = (Status)_XimClose(im);
   1126     status = (Status)_XimDisconnect(im) && status;
   1127     _XimProtoIMFree(im);
   1128 #ifdef XIM_CONNECTABLE
   1129     if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
   1130 	_XimReconnectModeSetAttr(im);
   1131         for (ic = im->core.ic_chain; ic; ic = ic->core.next) {
   1132 	    _XimReconnectModeCreateIC(ic);
   1133         }
   1134 	return 0;
   1135     }
   1136 #endif /* XIM_CONNECTABLE */
   1137     _XimDestroyIMStructureList(im);
   1138     return status;
   1139 }
   1140 
   1141 #ifdef XIM_CONNECTABLE
   1142 static Bool
   1143 _XimCheckIMQuarkList(
   1144     XrmQuark		*quark_list,
   1145     int			 num_quark,
   1146     XrmQuark		 quark)
   1147 {
   1148     register int	 i;
   1149 
   1150     for (i = 0; i < num_quark; i++) {
   1151 	if (quark_list[i] == quark) {
   1152 	    return True;
   1153 	}
   1154     }
   1155     return False;
   1156 }
   1157 
   1158 static Bool
   1159 _XimSaveIMValues(
   1160     Xim			 im,
   1161     XIMArg		*arg)
   1162 {
   1163     register XIMArg	*p;
   1164     register int	 n;
   1165     XrmQuark		*quark_list;
   1166     XrmQuark		*tmp;
   1167     XrmQuark		 quark;
   1168     int			 num_quark;
   1169 
   1170     if (quark_list = im->private.proto.saved_imvalues) {
   1171 	num_quark = im->private.proto.num_saved_imvalues;
   1172 	for (p = arg; p && p->name; p++) {
   1173 	    quark = XrmStringToQuark(p->name);
   1174 	    if (_XimCheckIMQuarkList(quark_list, num_quark, quark)) {
   1175 		continue;
   1176 	    }
   1177 	    if (!(tmp = Xrealloc(quark_list,
   1178 				(sizeof(XrmQuark) * (num_quark + 1))))) {
   1179 		im->private.proto.saved_imvalues = quark_list;
   1180 		im->private.proto.num_saved_imvalues = num_quark;
   1181 		return False;
   1182 	    }
   1183 	    num_quark++;
   1184 	    quark_list = tmp;
   1185 	    quark_list[num_quark] = quark;
   1186 	}
   1187 	im->private.proto.saved_imvalues = quark_list;
   1188 	im->private.proto.num_saved_imvalues = num_quark;
   1189 	return True;
   1190     }
   1191 
   1192     for (p = arg, n = 0; p && p->name; p++, n++);
   1193 
   1194     if (!(quark_list = Xmalloc(sizeof(XrmQuark) * n))) {
   1195 	return False;
   1196     }
   1197 
   1198     im->private.proto.saved_imvalues = quark_list;
   1199     im->private.proto.num_saved_imvalues = n;
   1200     for (p = arg; p && p->name; p++, quark_list++) {
   1201 	*quark_list = XrmStringToQuark(p->name);
   1202     }
   1203 
   1204     return True;
   1205 }
   1206 
   1207 static char *
   1208 _XimDelayModeSetIMValues(
   1209     Xim			 im,
   1210     XIMArg		*arg)
   1211 {
   1212     XimDefIMValues	 im_values;
   1213     char		*name;
   1214     XIMArg		*values;
   1215 
   1216     _XimGetCurrentIMValues(im, &im_values);
   1217     name = _XimSetIMValueData(im, (XPointer)&im_values, values,
   1218 		im->core.im_resources, im->core.im_num_resources);
   1219     _XimSetCurrentIMValues(im, &im_values);
   1220 
   1221     return name;
   1222 }
   1223 #endif /* XIM_CONNECTABLE */
   1224 
   1225 static Bool
   1226 _XimSetIMValuesCheck(
   1227     Xim          im,
   1228     INT16        len,
   1229     XPointer	 data,
   1230     XPointer     arg)
   1231 {
   1232     CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
   1233     CARD8	 major_opcode = *((CARD8 *)data);
   1234     CARD8	 minor_opcode = *((CARD8 *)data + 1);
   1235     XIMID	 imid = buf_s[0];
   1236 
   1237     if ((major_opcode == XIM_SET_IM_VALUES_REPLY)
   1238      && (minor_opcode == 0)
   1239      && (imid == im->private.proto.imid))
   1240 	return True;
   1241     if ((major_opcode == XIM_ERROR)
   1242      && (minor_opcode == 0)
   1243      && (buf_s[2] & XIM_IMID_VALID)
   1244      && (imid == im->private.proto.imid))
   1245 	return True;
   1246     return False;
   1247 }
   1248 
   1249 static char *
   1250 _XimProtoSetIMValues(
   1251     XIM			 xim,
   1252     XIMArg		*arg)
   1253 {
   1254     Xim			 im = (Xim)xim;
   1255     XimDefIMValues	 im_values;
   1256     INT16		 len;
   1257     CARD16		*buf_s;
   1258     char		*tmp;
   1259     CARD32		 tmp_buf32[BUFSIZE/4];
   1260     char		*tmp_buf = (char *)tmp_buf32;
   1261     char		*buf;
   1262     int			 buf_size;
   1263     char		*data;
   1264     int			 data_len;
   1265     int			 ret_len;
   1266     int			 total;
   1267     XIMArg		*arg_ret;
   1268     CARD32		 reply32[BUFSIZE/4];
   1269     char		*reply = (char *)reply32;
   1270     XPointer		 preply;
   1271     int			 ret_code;
   1272     char		*name;
   1273 
   1274 #ifndef XIM_CONNECTABLE
   1275     if (!IS_SERVER_CONNECTED(im))
   1276 	return arg->name;
   1277 #else
   1278     if (!_XimSaveIMValues(im, arg))
   1279 	return arg->name;
   1280 
   1281     if (!IS_SERVER_CONNECTED(im)) {
   1282 	if (IS_CONNECTABLE(im)) {
   1283 	    if (!_XimConnectServer(im)) {
   1284 	        return _XimDelayModeSetIMValues(im, arg);
   1285 	    }
   1286         } else {
   1287 	    return arg->name;
   1288         }
   1289     }
   1290 #endif /* XIM_CONNECTABLE */
   1291 
   1292     _XimGetCurrentIMValues(im, &im_values);
   1293     memset(tmp_buf, 0, sizeof(tmp_buf32));
   1294     buf = tmp_buf;
   1295     buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
   1296     data_len = BUFSIZE - buf_size;
   1297     total = 0;
   1298     arg_ret = arg;
   1299     for (;;) {
   1300 	data = &buf[buf_size];
   1301 	if ((name = _XimEncodeIMATTRIBUTE(im, im->core.im_resources,
   1302 		im->core.im_num_resources, arg, &arg_ret, data, data_len,
   1303 		&ret_len, (XPointer)&im_values, XIM_SETIMVALUES))) {
   1304 	    break;
   1305 	}
   1306 
   1307 	total += ret_len;
   1308 	if (!(arg = arg_ret)) {
   1309 	    break;
   1310 	}
   1311 
   1312 	buf_size += ret_len;
   1313 	if (buf == tmp_buf) {
   1314 	    if (!(tmp = Xcalloc(buf_size + data_len, 1))) {
   1315 		return arg->name;
   1316 	    }
   1317 	    memcpy(tmp, buf, buf_size);
   1318 	    buf = tmp;
   1319 	} else {
   1320 	    if (!(tmp = Xrealloc(buf, (buf_size + data_len)))) {
   1321 		Xfree(buf);
   1322 		return arg->name;
   1323 	    }
   1324             memset(&tmp[buf_size], 0, data_len);
   1325 	    buf = tmp;
   1326 	}
   1327     }
   1328     _XimSetCurrentIMValues(im, &im_values);
   1329 
   1330     if (!total) {
   1331         if (buf != tmp_buf)
   1332 	    Xfree(buf);
   1333         return (char *)NULL;
   1334     }
   1335 
   1336     buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
   1337     buf_s[0] = im->private.proto.imid;
   1338     buf_s[1] = (INT16)total;
   1339 
   1340     len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
   1341     _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len);
   1342     if (!(_XimWrite(im, len, (XPointer)buf))) {
   1343 	if (buf != tmp_buf)
   1344 	    Xfree(buf);
   1345 	return arg->name;
   1346     }
   1347     _XimFlush(im);
   1348     if (buf != tmp_buf)
   1349 	Xfree(buf);
   1350     buf_size = BUFSIZE;
   1351     ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
   1352 					 _XimSetIMValuesCheck, 0);
   1353     if(ret_code == XIM_TRUE) {
   1354 	preply = reply;
   1355     } else if(ret_code == XIM_OVERFLOW) {
   1356 	if(len <= 0) {
   1357 	    preply = reply;
   1358 	} else {
   1359 	    buf_size = (int)len;
   1360 	    preply = Xmalloc(buf_size);
   1361 	    ret_code = _XimRead(im, &len, reply, buf_size,
   1362 					_XimSetIMValuesCheck, 0);
   1363 	    if(ret_code != XIM_TRUE) {
   1364 		Xfree(preply);
   1365 		return arg->name;
   1366 	    }
   1367 	}
   1368     } else
   1369 	return arg->name;
   1370     buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
   1371     if (*((CARD8 *)preply) == XIM_ERROR) {
   1372 	_XimProcError(im, 0, (XPointer)&buf_s[3]);
   1373 	if(reply != preply)
   1374 	    Xfree(preply);
   1375 	return arg->name;
   1376     }
   1377     if(reply != preply)
   1378 	Xfree(preply);
   1379 
   1380     return name;
   1381 }
   1382 
   1383 #ifdef XIM_CONNECTABLE
   1384 static char *
   1385 _XimDelayModeGetIMValues(
   1386     Xim			 im,
   1387     XIMArg		*arg)
   1388 {
   1389     XimDefIMValues	 im_values;
   1390 
   1391     _XimGetCurrentIMValues(im, &im_values);
   1392     return(_XimGetIMValueData(im, (XPointer)&im_values, arg,
   1393 			im->core.im_resources, im->core.im_num_resources));
   1394 }
   1395 #endif /* XIM_CONNECTABLE */
   1396 
   1397 static Bool
   1398 _XimGetIMValuesCheck(
   1399     Xim          im,
   1400     INT16        len,
   1401     XPointer	 data,
   1402     XPointer     arg)
   1403 {
   1404     CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
   1405     CARD8	 major_opcode = *((CARD8 *)data);
   1406     CARD8	 minor_opcode = *((CARD8 *)data + 1);
   1407     XIMID	 imid = buf_s[0];
   1408 
   1409     if ((major_opcode == XIM_GET_IM_VALUES_REPLY)
   1410      && (minor_opcode == 0)
   1411      && (imid == im->private.proto.imid))
   1412 	return True;
   1413     if ((major_opcode == XIM_ERROR)
   1414      && (minor_opcode == 0)
   1415      && (buf_s[2] & XIM_IMID_VALID)
   1416      && (imid == im->private.proto.imid))
   1417 	return True;
   1418     return False;
   1419 }
   1420 
   1421 static char *
   1422 _XimProtoGetIMValues(
   1423     XIM			 xim,
   1424     XIMArg		*arg)
   1425 {
   1426     Xim			 im = (Xim)xim;
   1427     register XIMArg	*p;
   1428     register int	 n;
   1429     CARD8		*buf;
   1430     CARD16		*buf_s;
   1431     INT16		 len;
   1432     CARD32		 reply32[BUFSIZE/4];
   1433     char		*reply = (char *)reply32;
   1434     XPointer		 preply = NULL;
   1435     int			 buf_size;
   1436     int			 ret_code;
   1437     char		*makeid_name;
   1438     char		*decode_name;
   1439     CARD16		*data = NULL;
   1440     INT16		 data_len = 0;
   1441 
   1442 #ifndef XIM_CONNECTABLE
   1443     if (!IS_SERVER_CONNECTED(im))
   1444 	return arg->name;
   1445 #else
   1446     if (!IS_SERVER_CONNECTED(im)) {
   1447 	if (IS_CONNECTABLE(im)) {
   1448 	    if (!_XimConnectServer(im)) {
   1449 	        return _XimDelayModeGetIMValues(im, arg);
   1450 	    }
   1451         } else {
   1452 	    return arg->name;
   1453         }
   1454     }
   1455 #endif /* XIM_CONNECTABLE */
   1456 
   1457     for (n = 0, p = arg; p->name; p++)
   1458 	n++;
   1459 
   1460     if (!n)
   1461 	return (char *)NULL;
   1462 
   1463     buf_size =  sizeof(CARD16) * n;
   1464     buf_size += XIM_HEADER_SIZE
   1465 	     + sizeof(CARD16)
   1466 	     + sizeof(INT16)
   1467 	     + XIM_PAD(buf_size);
   1468 
   1469     if (!(buf = Xcalloc(buf_size, 1)))
   1470 	return arg->name;
   1471     buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
   1472 
   1473     makeid_name = _XimMakeIMAttrIDList(im, im->core.im_resources,
   1474 				im->core.im_num_resources, arg,
   1475 				&buf_s[2], &len, XIM_GETIMVALUES);
   1476 
   1477     if (len) {
   1478 	buf_s[0] = im->private.proto.imid;	/* imid */
   1479 	buf_s[1] = len;				/* length of im-attr-id */
   1480 	XIM_SET_PAD(&buf_s[2], len);		/* pad */
   1481 	len += sizeof(CARD16)			/* sizeof imid */
   1482 	     + sizeof(INT16);			/* sizeof length of attr */
   1483 
   1484 	_XimSetHeader((XPointer)buf, XIM_GET_IM_VALUES, 0, &len);
   1485 	if (!(_XimWrite(im, len, (XPointer)buf))) {
   1486 	    Xfree(buf);
   1487 	    return arg->name;
   1488 	}
   1489 	_XimFlush(im);
   1490 	Xfree(buf);
   1491     	buf_size = BUFSIZE;
   1492     	ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
   1493     						_XimGetIMValuesCheck, 0);
   1494 	if(ret_code == XIM_TRUE) {
   1495 	    preply = reply;
   1496 	} else if(ret_code == XIM_OVERFLOW) {
   1497 	    if(len <= 0) {
   1498 		preply = reply;
   1499 	    } else {
   1500 		buf_size = len;
   1501 		preply = Xmalloc(buf_size);
   1502 		ret_code = _XimRead(im, &len, preply, buf_size,
   1503 						_XimGetIMValuesCheck, 0);
   1504 		if(ret_code != XIM_TRUE) {
   1505 		    Xfree(preply);
   1506 		    return arg->name;
   1507 		}
   1508 	    }
   1509 	} else
   1510 	    return arg->name;
   1511 	buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
   1512 	if (*((CARD8 *)preply) == XIM_ERROR) {
   1513 	    _XimProcError(im, 0, (XPointer)&buf_s[3]);
   1514 	    if(reply != preply)
   1515 		Xfree(preply);
   1516 	    return arg->name;
   1517 	}
   1518 	data = &buf_s[2];
   1519 	data_len = buf_s[1];
   1520     }
   1521     decode_name = _XimDecodeIMATTRIBUTE(im, im->core.im_resources,
   1522 			im->core.im_num_resources, data, data_len,
   1523 			arg, XIM_GETIMVALUES);
   1524     if (reply != preply)
   1525 	Xfree(preply);
   1526 
   1527     if (decode_name)
   1528 	return decode_name;
   1529     else
   1530 	return makeid_name;
   1531 }
   1532 
   1533 static XIMMethodsRec     im_methods = {
   1534     _XimProtoCloseIM,           /* close */
   1535     _XimProtoSetIMValues,       /* set_values */
   1536     _XimProtoGetIMValues,       /* get_values */
   1537     _XimProtoCreateIC,          /* create_ic */
   1538     _Ximctstombs,		/* ctstombs */
   1539     _Ximctstowcs,		/* ctstowcs */
   1540     _Ximctstoutf8		/* ctstoutf8 */
   1541 };
   1542 
   1543 static Bool
   1544 _XimSetEncodingByName(
   1545     Xim		  im,
   1546     char	**buf,
   1547     int		 *len)
   1548 {
   1549     char	*encoding = (char *)NULL;
   1550     int		 encoding_len;
   1551     int		 compound_len;
   1552     BYTE	*ret;
   1553 
   1554     _XGetLCValues(im->core.lcd, XlcNCodeset, &encoding, NULL);
   1555     if (!encoding) {
   1556 	*buf = (char *)NULL;
   1557 	*len = 0;
   1558 	return True;
   1559     }
   1560     encoding_len = strlen(encoding);
   1561     compound_len = strlen("COMPOUND_TEXT");
   1562     *len = encoding_len + sizeof(BYTE) + compound_len + sizeof(BYTE);
   1563     if (!(ret = Xmalloc(*len))) {
   1564 	return False;
   1565     }
   1566     *buf = (char *)ret;
   1567 
   1568     ret[0] = (BYTE)encoding_len;
   1569     memcpy(&ret[1], encoding, encoding_len);
   1570     ret += (encoding_len + sizeof(BYTE));
   1571     ret[0] = (BYTE)compound_len;
   1572     memcpy(&ret[1], "COMPOUND_TEXT", compound_len);
   1573     return True;
   1574 }
   1575 
   1576 static Bool
   1577 _XimSetEncodingByDetail(
   1578     Xim		 im,
   1579     char	**buf,
   1580     int		 *len)
   1581 {
   1582     *len = 0;
   1583     *buf = NULL;
   1584     return True;
   1585 }
   1586 
   1587 static Bool
   1588 _XimGetEncoding(
   1589     Xim		 im,
   1590     CARD16	*buf,
   1591     char	*name,
   1592     int		 name_len,
   1593     char	*detail,
   1594     int		 detail_len)
   1595 {
   1596     XLCd	 lcd = im->core.lcd;
   1597     CARD16	 category = buf[0];
   1598     CARD16	 idx = buf[1];
   1599     int		 len;
   1600     XlcConv	 ctom_conv = NULL;
   1601     XlcConv	 ctow_conv = NULL;
   1602     XlcConv	 ctoutf8_conv = NULL;
   1603     XlcConv	 conv;
   1604     XimProtoPrivateRec *private = &im->private.proto;
   1605 
   1606     if (idx == (CARD16)XIM_Default_Encoding_IDX) { /* XXX */
   1607 	if (!(ctom_conv = _XlcOpenConverter(lcd,
   1608 				 XlcNCompoundText, lcd, XlcNMultiByte)))
   1609 	    return False;
   1610 	if (!(ctow_conv = _XlcOpenConverter(lcd,
   1611 				 XlcNCompoundText, lcd, XlcNWideChar)))
   1612 	    return False;
   1613 	if (!(ctoutf8_conv = _XlcOpenConverter(lcd,
   1614 				 XlcNCompoundText, lcd, XlcNUtf8String)))
   1615 	    return False;
   1616     }
   1617 
   1618     if (category == XIM_Encoding_NameCategory) {
   1619 	while (name_len > 0) {
   1620 	    len = (int)name[0];
   1621 	    if (!strncmp(&name[1], "COMPOUND_TEXT", len)) {
   1622 		if (!(ctom_conv = _XlcOpenConverter(lcd,
   1623 				 XlcNCompoundText, lcd, XlcNMultiByte)))
   1624 		    return False;
   1625 		if (!(ctow_conv = _XlcOpenConverter(lcd,
   1626 				 XlcNCompoundText, lcd, XlcNWideChar)))
   1627 		    return False;
   1628 		if (!(ctoutf8_conv = _XlcOpenConverter(lcd,
   1629 				 XlcNCompoundText, lcd, XlcNUtf8String)))
   1630 		    return False;
   1631 		break;
   1632 	    } else {
   1633 		/*
   1634 		 * Not yet
   1635 		 */
   1636 	    }
   1637 	    len += sizeof(BYTE);
   1638 	    name_len -= len;
   1639 	    name += len;
   1640 	}
   1641     } else if (category == XIM_Encoding_DetailCategory) {
   1642 	/*
   1643 	 * Not yet
   1644 	 */
   1645     } else {
   1646 	return False;
   1647     }
   1648 
   1649     private->ctom_conv = ctom_conv;
   1650     private->ctow_conv = ctow_conv;
   1651     private->ctoutf8_conv = ctoutf8_conv;
   1652 
   1653     if (!(conv = _XlcOpenConverter(lcd,	XlcNCharSet, lcd, XlcNMultiByte)))
   1654 	return False;
   1655     private->cstomb_conv = conv;
   1656 
   1657     if (!(conv = _XlcOpenConverter(lcd,	XlcNCharSet, lcd, XlcNWideChar)))
   1658 	return False;
   1659     private->cstowc_conv = conv;
   1660 
   1661     if (!(conv = _XlcOpenConverter(lcd,	XlcNCharSet, lcd, XlcNUtf8String)))
   1662 	return False;
   1663     private->cstoutf8_conv = conv;
   1664 
   1665     if (!(conv = _XlcOpenConverter(lcd,	XlcNUcsChar, lcd, XlcNChar)))
   1666 	return False;
   1667     private->ucstoc_conv = conv;
   1668 
   1669     if (!(conv = _XlcOpenConverter(lcd,	XlcNUcsChar, lcd, XlcNUtf8String)))
   1670 	return False;
   1671     private->ucstoutf8_conv = conv;
   1672 
   1673     return True;
   1674 }
   1675 
   1676 static Bool
   1677 _XimEncodingNegoCheck(
   1678     Xim		 im,
   1679     INT16	 len,
   1680     XPointer	 data,
   1681     XPointer	 arg)
   1682 {
   1683     CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
   1684     CARD8	 major_opcode = *((CARD8 *)data);
   1685     CARD8	 minor_opcode = *((CARD8 *)data + 1);
   1686     XIMID	 imid = buf_s[0];
   1687 
   1688     if ((major_opcode == XIM_ENCODING_NEGOTIATION_REPLY)
   1689      && (minor_opcode == 0)
   1690      && (imid == im->private.proto.imid))
   1691 	return True;
   1692     if ((major_opcode == XIM_ERROR)
   1693      && (minor_opcode == 0)
   1694      && (buf_s[2] & XIM_IMID_VALID)
   1695      && (imid == im->private.proto.imid))
   1696 	return True;
   1697     return False;
   1698 }
   1699 
   1700 static Bool
   1701 _XimEncodingNegotiation(
   1702     Xim		 im)
   1703 {
   1704     char	*name_ptr = 0;
   1705     int		 name_len = 0;
   1706     char	*detail_ptr = 0;
   1707     int		 detail_len = 0;
   1708     CARD8	*buf;
   1709     CARD16	*buf_s;
   1710     INT16	 len;
   1711     CARD32	 reply32[BUFSIZE/4];
   1712     char	*reply = (char *)reply32;
   1713     XPointer	 preply;
   1714     int		 buf_size;
   1715     int		 ret_code;
   1716 
   1717     if (!(_XimSetEncodingByName(im, &name_ptr, &name_len)))
   1718 	return False;
   1719 
   1720     if (!(_XimSetEncodingByDetail(im, &detail_ptr, &detail_len)))
   1721 	goto free_name_ptr;
   1722 
   1723     len = sizeof(CARD16)
   1724 	+ sizeof(INT16)
   1725 	+ name_len
   1726 	+ XIM_PAD(name_len)
   1727 	+ sizeof(INT16)
   1728 	+ sizeof(CARD16)
   1729 	+ detail_len;
   1730 
   1731     if (!(buf = Xcalloc(1, XIM_HEADER_SIZE + len)))
   1732 	goto free_detail_ptr;
   1733 
   1734     buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
   1735 
   1736     buf_s[0] = im->private.proto.imid;
   1737     buf_s[1] = (INT16)name_len;
   1738     if (name_ptr)
   1739 	(void)memcpy((char *)&buf_s[2], name_ptr, name_len);
   1740     XIM_SET_PAD(&buf_s[2], name_len);
   1741     buf_s = (CARD16 *)((char *)&buf_s[2] + name_len);
   1742     buf_s[0] = detail_len;
   1743     buf_s[1] = 0;
   1744     if (detail_ptr)
   1745 	(void)memcpy((char *)&buf_s[2], detail_ptr, detail_len);
   1746 
   1747     _XimSetHeader((XPointer)buf, XIM_ENCODING_NEGOTIATION, 0, &len);
   1748     if (!(_XimWrite(im, len, (XPointer)buf))) {
   1749 	Xfree(buf);
   1750 	goto free_detail_ptr;
   1751     }
   1752     _XimFlush(im);
   1753     Xfree(buf);
   1754     buf_size = BUFSIZE;
   1755     ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
   1756 					_XimEncodingNegoCheck, 0);
   1757     if(ret_code == XIM_TRUE) {
   1758 	preply = reply;
   1759     } else if(ret_code == XIM_OVERFLOW) {
   1760 	if(len <= 0) {
   1761 	    preply = reply;
   1762 	} else {
   1763 	    buf_size = len;
   1764 	    preply = Xmalloc(buf_size);
   1765 	    ret_code = _XimRead(im, &len, preply, buf_size,
   1766 					_XimEncodingNegoCheck, 0);
   1767 	    if(ret_code != XIM_TRUE)
   1768 		goto free_preply;
   1769 	}
   1770     } else
   1771 	goto free_detail_ptr;
   1772     buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
   1773     if (*((CARD8 *)preply) == XIM_ERROR) {
   1774 	_XimProcError(im, 0, (XPointer)&buf_s[3]);
   1775 	goto free_preply;
   1776     }
   1777 
   1778     if (!(_XimGetEncoding(im, &buf_s[1], name_ptr, name_len,
   1779 						detail_ptr, detail_len)))
   1780 	goto free_preply;
   1781 
   1782     Xfree(name_ptr);
   1783     Xfree(detail_ptr);
   1784 
   1785     if(reply != preply)
   1786 	Xfree(preply);
   1787 
   1788     return True;
   1789 
   1790 free_preply:
   1791     if (reply != preply)
   1792 	Xfree(preply);
   1793 
   1794 free_detail_ptr:
   1795     Xfree(detail_ptr);
   1796 
   1797 free_name_ptr:
   1798     Xfree(name_ptr);
   1799 
   1800     return False;
   1801 }
   1802 
   1803 #ifdef XIM_CONNECTABLE
   1804 static Bool
   1805 _XimSendSavedIMValues(
   1806     Xim			 im)
   1807 {
   1808     XimDefIMValues	 im_values;
   1809     INT16		 len;
   1810     CARD16		*buf_s;
   1811     char		*tmp;
   1812     CARD32		 tmp_buf32[BUFSIZE/4];
   1813     char		*tmp_buf = (char *)tmp_buf32;
   1814     char		*buf;
   1815     int			 buf_size;
   1816     char		*data;
   1817     int			 data_len;
   1818     int			 ret_len;
   1819     int			 total;
   1820     int			 idx;
   1821     CARD32		 reply32[BUFSIZE/4];
   1822     char		*reply = (char *)reply32;
   1823     XPointer		 preply;
   1824     int			 ret_code;
   1825 
   1826     _XimGetCurrentIMValues(im, &im_values);
   1827     memset(tmp_buf, 0, sizeof(tmp_buf32));
   1828     buf = tmp_buf;
   1829     buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
   1830     data_len = BUFSIZE - buf_size;
   1831     total = 0;
   1832     idx = 0;
   1833     for (;;) {
   1834 	data = &buf[buf_size];
   1835 	if (!_XimEncodeSavedIMATTRIBUTE(im, im->core.im_resources,
   1836 		im->core.im_num_resources, &idx, data, data_len,
   1837 		&ret_len, (XPointer)&im_values, XIM_SETIMVALUES)) {
   1838 	    if (buf != tmp_buf)
   1839 		Xfree(buf);
   1840 	    return False;
   1841 	}
   1842 
   1843 	total += ret_len;
   1844 	if (idx == -1) {
   1845 	    break;
   1846 	}
   1847 
   1848 	buf_size += ret_len;
   1849 	if (buf == tmp_buf) {
   1850 	    if (!(tmp = Xcalloc(buf_size + data_len, 1))) {
   1851 		return False;
   1852 	    }
   1853 	    memcpy(tmp, buf, buf_size);
   1854 	    buf = tmp;
   1855 	} else {
   1856 	    if (!(tmp = Xrealloc(buf, (buf_size + data_len)))) {
   1857 		Xfree(buf);
   1858 		return False;
   1859 	    }
   1860             memset(&tmp[buf_size], 0, data_len);
   1861 	    buf = tmp;
   1862 	}
   1863     }
   1864 
   1865     if (!total)
   1866 	return True;
   1867 
   1868     buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
   1869     buf_s[0] = im->private.proto.imid;
   1870     buf_s[1] = (INT16)total;
   1871 
   1872     len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
   1873     _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len);
   1874     if (!(_XimWrite(im, len, (XPointer)buf))) {
   1875 	if (buf != tmp_buf)
   1876 	    Xfree(buf);
   1877 	return False;
   1878     }
   1879     _XimFlush(im);
   1880     if (buf != tmp_buf)
   1881 	Xfree(buf);
   1882     buf_size = BUFSIZE;
   1883     ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
   1884     					 _XimSetIMValuesCheck, 0);
   1885     if(ret_code == XIM_TRUE) {
   1886 	preply = reply;
   1887     } else if(ret_code == XIM_OVERFLOW) {
   1888 	if(len <= 0) {
   1889 	    preply = reply;
   1890 	} else {
   1891 	    buf_size = (int)len;
   1892 	    preply = Xmalloc(buf_size);
   1893 	    ret_code = _XimRead(im, &len, reply, buf_size,
   1894 					_XimSetIMValuesCheck, 0);
   1895     	    if(ret_code != XIM_TRUE) {
   1896 		Xfree(preply);
   1897 		return False;
   1898 	    }
   1899 	}
   1900     } else
   1901 	return False;
   1902 
   1903     buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
   1904     if (*((CARD8 *)preply) == XIM_ERROR) {
   1905 	_XimProcError(im, 0, (XPointer)&buf_s[3]);
   1906     	if(reply != preply)
   1907 	    Xfree(preply);
   1908 	return False;
   1909     }
   1910     if(reply != preply)
   1911 	Xfree(preply);
   1912 
   1913     return True;
   1914 }
   1915 
   1916 static void
   1917 _XimDelayModeIMFree(
   1918     Xim		 im)
   1919 {
   1920     if (im->core.im_resources) {
   1921 	Xfree(im->core.im_resources);
   1922 	im->core.im_resources = NULL;
   1923     }
   1924     if (im->core.ic_resources) {
   1925 	Xfree(im->core.ic_resources);
   1926 	im->core.ic_resources = NULL;
   1927     }
   1928     if (im->core.im_values_list) {
   1929 	Xfree(im->core.im_values_list);
   1930 	im->core.im_values_list = NULL;
   1931     }
   1932     if (im->core.ic_values_list) {
   1933 	Xfree(im->core.ic_values_list);
   1934 	im->core.ic_values_list = NULL;
   1935     }
   1936     return;
   1937 }
   1938 
   1939 Bool
   1940 _XimConnectServer(
   1941     Xim		 im)
   1942 {
   1943     Xim		 save_im;
   1944 
   1945     if (!(save_im = Xmalloc(sizeof(XimRec))))
   1946 	return False;
   1947     memcpy((char *)save_im, (char *)im, sizeof(XimRec));
   1948 
   1949     if (_XimPreConnect(im) && _XimConnection(im)
   1950 			&& _XimOpen(im) && _XimEncodingNegotiation(im)) {
   1951 	if (_XimSendSavedIMValues(im)) {
   1952 	    _XimDelayModeIMFree(save_im);
   1953 	    _XimRegisterServerFilter(im);
   1954 	    Xfree(save_im);
   1955 	    return True;
   1956 	}
   1957     }
   1958     memcpy((char *)im, (char *)save_im, sizeof(XimRec));
   1959     Xfree(save_im);
   1960     return False;
   1961 }
   1962 
   1963 Bool
   1964 _XimDelayModeSetAttr(
   1965     Xim			 im)
   1966 {
   1967     XimDefIMValues	 im_values;
   1968 
   1969     if(!_XimSetIMResourceList(&im->core.im_resources,
   1970 						&im->core.im_num_resources)) {
   1971 	return False;
   1972     }
   1973     if(!_XimSetICResourceList(&im->core.ic_resources,
   1974 						&im->core.ic_num_resources)) {
   1975 	return False;
   1976     }
   1977 
   1978     _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
   1979 
   1980     _XimGetCurrentIMValues(im, &im_values);
   1981     if(!_XimSetLocalIMDefaults(im, (XPointer)&im_values,
   1982 			im->core.im_resources, im->core.im_num_resources)) {
   1983 	return False;
   1984     }
   1985     _XimSetCurrentIMValues(im, &im_values);
   1986     if (im->private.proto.default_styles) {
   1987         if (im->core.styles)
   1988 	    Xfree(im->core.styles);
   1989         im->core.styles = im->private.proto.default_styles;
   1990     }
   1991 
   1992     return True;
   1993 }
   1994 
   1995 static Bool
   1996 _XimReconnectModeSetAttr(
   1997     Xim			 im)
   1998 {
   1999     XimDefIMValues	 im_values;
   2000 
   2001     if(!_XimSetIMResourceList(&im->core.im_resources,
   2002 						&im->core.im_num_resources)) {
   2003 	return False;
   2004     }
   2005     if(!_XimSetICResourceList(&im->core.ic_resources,
   2006 						&im->core.ic_num_resources)) {
   2007 	return False;
   2008     }
   2009 
   2010     _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
   2011 
   2012     if (im->private.proto.default_styles) {
   2013         if (im->core.styles)
   2014 	    Xfree(im->core.styles);
   2015         im->core.styles = im->private.proto.default_styles;
   2016     }
   2017 
   2018     return True;
   2019 }
   2020 #endif /* XIM_CONNECTABLE */
   2021 
   2022 Bool
   2023 _XimProtoOpenIM(
   2024     Xim		 im)
   2025 {
   2026     _XimInitialResourceInfo();
   2027 
   2028     im->methods = &im_methods;
   2029 
   2030 #ifdef XIM_CONNECTABLE
   2031     _XimSetProtoResource(im);
   2032 #endif /* XIM_CONNECTABLE */
   2033 
   2034     if (_XimPreConnect(im)) {
   2035 	if (_XimConnection(im) && _XimOpen(im) && _XimEncodingNegotiation(im)) {
   2036 	    _XimRegisterServerFilter(im);
   2037 	    return True;
   2038 	}
   2039 	_XimShutdown(im);
   2040 #ifdef XIM_CONNECTABLE
   2041     } else if (IS_DELAYBINDABLE(im)) {
   2042 	if (_XimDelayModeSetAttr(im))
   2043 	    return True;
   2044 #endif /* XIM_CONNECTABLE */
   2045     }
   2046     _XimProtoIMFree(im);
   2047     return False;
   2048 }
   2049