Back to index

im-sdk  12.3.91
i18nTr.c
Go to the documentation of this file.
00001 /******************************************************************
00002  
00003          Copyright 1994, 1995 by Sun Microsystems, Inc.
00004          Copyright 1993, 1994 by Hewlett-Packard Company
00005  
00006 Permission to use, copy, modify, distribute, and sell this software
00007 and its documentation for any purpose is hereby granted without fee,
00008 provided that the above copyright notice appear in all copies and
00009 that both that copyright notice and this permission notice appear
00010 in supporting documentation, and that the name of Sun Microsystems, Inc.
00011 and Hewlett-Packard not be used in advertising or publicity pertaining to
00012 distribution of the software without specific, written prior permission.
00013 Sun Microsystems, Inc. and Hewlett-Packard make no representations about
00014 the suitability of this software for any purpose.  It is provided "as is"
00015 without express or implied warranty.
00016  
00017 SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL
00018 WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
00019 WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
00020 SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY
00021 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
00022 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
00023 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
00024 IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00025  
00026   Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc.
00027  
00028 ******************************************************************/
00029 #include <stdio.h>
00030 #include <X11/Xlib.h>
00031 #include <X11/Xlibint.h>
00032 #include "Xtrans.h"
00033 #include "FrameMgr.h"
00034 #include "X11R6IMProtoData.h"
00035 #include "Xi18n.h"
00036 #include "Xi18nTr.h"
00037 
00038 #ifdef USE_DIRECT_CONN
00039 
00040 extern Xi18nClient *_Xi18nFindClient(Xi18n, CARD16);
00041 extern Xi18nClient *_Xi18nNewClient(Xi18n);
00042 extern void _Xi18nDeleteClient(Xi18n, CARD16);
00043 extern int _Xi18nNeedSwap(Xi18n i18n_core, CARD16 connect_id);
00044 extern int _XimdXTransDisconnect (XtransConnInfo ciptr);
00045 extern int _XimdXTransClose (XtransConnInfo ciptr);
00046 extern XtransConnInfo _XimdXTransOpenCOTSServer (char *address);
00047 extern int _XimdXTransCreateListener(XtransConnInfo ciptr, char *port);
00048 extern int _XimdXTransGetConnectionNumber(XtransConnInfo ciptr);
00049 extern int _XimdXTransRead(XtransConnInfo ciptr, char *buf, int size);
00050 extern int _XimdXTransWrite(XtransConnInfo ciptr, char *buf, int size);
00051 extern XtransConnInfo _XimdXTransAccept(XtransConnInfo ciptr, int *status);
00052 static Bool TransRead(XtransConnInfo, char *, int, int *);
00053 static Bool TransWrite(XtransConnInfo, char *, int);
00054 static void Xi18nWaitTransListen(Display *,
00055                              int, XPointer);
00056 static void Xi18nWaitTransAccept(Display *, int,
00057                              XPointer);
00058 
00059 static unsigned char *
00060 ReadTrIMMessage(XIMS ims, int fd, int *connect_id) {
00061     Xi18n i18n_core = ims->protocol;
00062     Xi18nClient *client = i18n_core->address.clients;
00063     TransClient *tr_client = NULL;
00064 
00065     FrameMgr fm;
00066     extern XimFrameRec packet_header_fr[];
00067     int total_size;
00068     unsigned char *p = NULL;
00069     unsigned char *pp;
00070     int read_length;
00071     XimProtoHdr      *hdr;
00072     Bool isConnect = False;
00073     CARD8 major_opcode, minor_opcode;
00074     CARD16 length;
00075 
00076     while (client != NULL) {
00077        tr_client = (TransClient *)client->trans_rec;
00078        if (tr_client->accept_fd == fd) {
00079            *connect_id = client->connect_id;
00080            break;
00081        }
00082        client = client->next;
00083     }
00084 
00085     if ((hdr = (XimProtoHdr *)malloc(sizeof(hdr))) == NULL)
00086        return (unsigned char *)NULL;
00087 
00088     if (!TransRead(tr_client->accept_conn, (char *)hdr,
00089                  sizeof(hdr), &read_length) ||
00090        read_length != sizeof(hdr)) {
00091        goto read_error;
00092     } else {
00093        if (client->byte_order == '?') {
00094            if (hdr->major_opcode == XIM_CONNECT) {
00095               CARD8 byte_order;
00096               if (!TransRead(tr_client->accept_conn, (char *)&byte_order,
00097                             sizeof(CARD8), &read_length) ||
00098                   read_length != sizeof(CARD8)) {
00099                   goto read_error;
00100               }
00101               isConnect = True;
00102               client->byte_order = (CARD8)byte_order;
00103            } else {
00104               return (unsigned char *)NULL;      /* can do nothing */
00105            }
00106        }
00107        fm = FrameMgrInit(packet_header_fr, (char *)hdr,
00108                        _Xi18nNeedSwap(i18n_core, *connect_id));
00109        total_size = FrameMgrGetTotalSize(fm);
00110        /* get data */
00111        FrameMgrGetToken(fm, major_opcode);
00112        FrameMgrGetToken(fm, minor_opcode);
00113        FrameMgrGetToken(fm, length);
00114        /* free FrameMgr */
00115        FrameMgrFree(fm);
00116 
00117        if ((p = (unsigned char *)malloc(total_size + length * 4)) == NULL)
00118          return (unsigned char *)NULL;
00119        pp = p;
00120        memmove(pp, &major_opcode, sizeof(CARD8)); pp += sizeof(CARD8);
00121        memmove(pp, &minor_opcode, sizeof(CARD8)); pp += sizeof(CARD8);
00122        memmove(pp, &length, sizeof(CARD16)); pp += sizeof(CARD16);
00123        XFree(hdr);
00124        if (!isConnect) {
00125            if (length > 0) {
00126               if (!TransRead(tr_client->accept_conn, (char *)pp,
00127                             length * 4, &read_length) ||
00128                   read_length != length * 4) {
00129                   goto read_error;
00130               }
00131            }
00132        } else {
00133            memmove(pp, &client->byte_order, sizeof(CARD8));
00134            pp += sizeof(CARD8);
00135            if (!TransRead(tr_client->accept_conn, (char *)pp,
00136                         length * 4 - sizeof(CARD8), &read_length) ||
00137               read_length != length * 4 - sizeof(CARD8)) {
00138               goto read_error;
00139            }
00140        }
00141     }
00142     return (unsigned char *)p;
00143   read_error:
00144     _XUnregisterInternalConnection(i18n_core->address.dpy, fd);
00145     _XimdXTransDisconnect(tr_client->accept_conn);
00146     (void)_XimdXTransClose(tr_client->accept_conn);
00147     return (unsigned char *)NULL;
00148 }
00149 
00150 static Bool 
00151 Xi18nTransBegin(XIMS ims) {
00152     Xi18n i18n_core = ims->protocol;
00153     char *address = i18n_core->address.im_addr;
00154     TransSpecRec *spec = (TransSpecRec *)i18n_core->address.connect_addr;
00155     int fd;
00156 
00157     if (((spec->trans_conn = (struct _XtransConnInfo *)
00158          _XimdXTransOpenCOTSServer(address)) == NULL) ||
00159        (_XimdXTransCreateListener(spec->trans_conn, spec->port) != 0)) {
00160        return False;
00161     }
00162     fd = _XimdXTransGetConnectionNumber(spec->trans_conn);
00163     return _XRegisterInternalConnection(i18n_core->address.dpy, fd,
00164                      (_XInternalConnectionProc)Xi18nWaitTransListen,
00165                      (XPointer)ims);
00166 }
00167 
00168 static Bool
00169 Xi18nTransEnd(XIMS ims) {
00170     Xi18n i18n_core = ims->protocol;
00171     TransSpecRec *spec = (TransSpecRec *)i18n_core->address.connect_addr;
00172     int fd;
00173     
00174     fd = _XimdXTransGetConnectionNumber(spec->trans_conn);
00175     if (fd == 0) return False;
00176     _XUnregisterInternalConnection(i18n_core->address.dpy, fd);
00177     _XimdXTransDisconnect(spec->trans_conn);
00178     (void)_XimdXTransClose(spec->trans_conn);
00179 
00180     XFree(spec->port);
00181     XFree(spec);
00182     return True;
00183 }
00184 
00185 static Bool
00186 Xi18nTransSend(XIMS ims, CARD16 connect_id,
00187               unsigned char *reply, long length) {
00188     Xi18n i18n_core = ims->protocol;
00189     Xi18nClient *client = _Xi18nFindClient(i18n_core, connect_id);
00190     TransClient *tr_client = (TransClient *)client->trans_rec;
00191 
00192     if (length > 0)
00193       if (TransWrite(tr_client->accept_conn, (char *)reply, length) != length)
00194        return False;
00195 
00196     return True;
00197 }
00198 
00199 static Bool
00200 Xi18nTransWait(XIMS ims, CARD16 connect_id,
00201               CARD8 major_opcode, CARD8 minor_opcode) {
00202     Xi18n i18n_core = ims->protocol;
00203     Xi18nClient *client = _Xi18nFindClient(i18n_core, connect_id);
00204     TransClient *tr_client = (TransClient *)client->trans_rec;
00205     int fd = _XimdXTransGetConnectionNumber(tr_client->accept_conn);
00206 
00207     for (;;) {
00208        unsigned char *packet;
00209        XimProtoHdr *hdr;
00210        int connect_id_ret;
00211 
00212        if ((packet = ReadTrIMMessage(ims, fd, &connect_id_ret)) ==
00213            (unsigned char*)NULL) return False;
00214 
00215        hdr = (XimProtoHdr *)packet;
00216 
00217        if ((hdr->major_opcode == major_opcode) &&
00218            (hdr->minor_opcode == minor_opcode))
00219          return True;
00220        else if (hdr->major_opcode == XIM_ERROR)
00221          return False;
00222     }
00223 }
00224 
00225 static Bool
00226 Xi18nTransDisconnect(XIMS ims, CARD16 connect_id) {
00227     Xi18n i18n_core = ims->protocol;
00228     Xi18nClient *client = _Xi18nFindClient(i18n_core, connect_id);
00229     TransClient *tr_client = (TransClient *)client->trans_rec;
00230 
00231     _XUnregisterInternalConnection(i18n_core->address.dpy,
00232                                tr_client->accept_fd);
00233     _XimdXTransDisconnect(tr_client->accept_conn);
00234     (void)_XimdXTransClose(tr_client->accept_conn);
00235     XFree(tr_client);
00236     _Xi18nDeleteClient(i18n_core, connect_id);
00237     return True;
00238 }
00239 
00240 static Bool
00241 TransRead(XtransConnInfo accept_conn, char *buf,
00242          int buf_len, int *ret_len) {
00243     int len;
00244 
00245     if ((len = _XimdXTransRead(accept_conn, buf, buf_len)) <= 0)
00246       return False;
00247     *ret_len = len;
00248     return True;
00249 }
00250 
00251 static Bool
00252 TransWrite(XtransConnInfo accept_conn, char *buf, int len) {
00253     int nbyte;
00254 
00255     while (len > 0) {
00256        if ((nbyte = _XimdXTransWrite(accept_conn, buf, len)) <= 0)
00257          return False;
00258        len -= nbyte;
00259        buf += nbyte;
00260     }
00261     return True;
00262 }
00263 
00264 Bool
00265 _Xi18nCheckTransAddress(Xi18n i18n_core, TransportSW *transSW,
00266                      char *address) {
00267     TransSpecRec *spec;
00268     char *p;
00269     char *hostname;
00270 
00271     if(!(spec = (TransSpecRec *)malloc(sizeof(TransSpecRec))))
00272        return False ;
00273 
00274     if (!(hostname = (char *)malloc(strlen(address) + 1))) {
00275        XFree(spec);
00276        return False ;
00277     }
00278     strcpy(hostname, address);
00279 
00280     if ((p = (char *)index(hostname, ':'))) {
00281        p++;
00282        if (!(spec->port = (char*)malloc(strlen(p) + 1))) {
00283            XFree(spec);
00284            XFree(hostname);
00285            return False;
00286        }
00287        strcpy(spec->port, p);
00288        XFree(hostname);
00289     } else {
00290        XFree(spec);
00291        XFree(hostname);
00292        return False;
00293     }
00294     i18n_core->address.connect_addr = (TransSpecRec *)spec;
00295     i18n_core->methods.begin = Xi18nTransBegin;
00296     i18n_core->methods.end  = Xi18nTransEnd;
00297     i18n_core->methods.send = Xi18nTransSend;
00298     i18n_core->methods.wait = Xi18nTransWait;
00299     i18n_core->methods.disconnect = Xi18nTransDisconnect;
00300     return True;
00301 }
00302 
00303 static TransClient *
00304 NewTrClient(Xi18n i18n_core, XtransConnInfo accept_conn) {
00305     Xi18nClient *client = _Xi18nNewClient(i18n_core);
00306     TransClient *tr_client;
00307 
00308     tr_client = (TransClient *)malloc(sizeof(TransClient));
00309 
00310     tr_client->accept_conn = accept_conn;
00311     tr_client->accept_fd = _XimdXTransGetConnectionNumber(accept_conn);
00312     client->trans_rec = tr_client;
00313 
00314     return ((TransClient *)tr_client);
00315 }
00316 
00317 static void
00318 Xi18nWaitTransListen(Display *d, int fd, XPointer arg) {
00319     XIMS ims =(XIMS)arg;
00320     Xi18n i18n_core = ims->protocol;
00321     TransSpecRec *spec = (TransSpecRec *)i18n_core->address.connect_addr;
00322     XtransConnInfo new_client;
00323     TransClient *client;
00324     int status;
00325 
00326     if ((new_client = (struct _XtransConnInfo *)
00327         _XimdXTransAccept(spec->trans_conn, &status)) != NULL) {
00328        client = NewTrClient(i18n_core, new_client);
00329        (void)_XRegisterInternalConnection(i18n_core->address.dpy,
00330                    client->accept_fd,
00331                    (_XInternalConnectionProc)Xi18nWaitTransAccept,
00332                    (XPointer)ims);
00333     }
00334     return;
00335 }
00336 
00337 static void
00338 Xi18nWaitTransAccept(Display *d, int fd, XPointer arg) {
00339     XIMS ims =(XIMS)arg;
00340     extern void _Xi18nMessageHandler(XIMS, CARD16, unsigned char*, Bool*);
00341     Bool delete = True;
00342     unsigned char *packet;
00343     int connect_id;
00344 
00345     if ((packet = ReadTrIMMessage(ims, fd, &connect_id)) ==
00346        (unsigned char*)NULL) return;
00347 
00348     _Xi18nMessageHandler(ims, connect_id, packet, &delete);
00349     if (delete == True)
00350        XFree(packet);
00351     return;
00352 }
00353 
00354 #endif /* USE_DIRECT_CONN */
00355