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

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