/******************************************************************
 
         Copyright 1994, 1995 by Sun Microsystems, Inc.
         Copyright 1993, 1994 by Hewlett-Packard Company
 
Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and
that both that copyright notice and this permission notice appear
in supporting documentation, and that the name of Sun Microsystems, Inc.
and Hewlett-Packard not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.
Sun Microsystems, Inc. and Hewlett-Packard make no representations about
the suitability of this software for any purpose.  It is provided "as is"
without express or implied warranty.
 
SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
  Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc.
 
******************************************************************/
#ifndef _Xi18n_h
#define _Xi18n_h
#include <X11/Xlib.h>
#include <X11/Xfuncs.h>
#include <X11/Xos.h>
#include "XimProto.h"

/*
 * Minor Protocol Number for Extension Protocol 
 */
#define XIM_EXTENSION		128
#define XIM_EXT_SET_EVENT_MASK			(0x30)
#define	XIM_EXT_FORWARD_KEYEVENT		(0x32)
#define	XIM_EXT_MOVE				(0x33)
#define COMMON_EXTENSIONS_NUM   3

#include <stdlib.h>
#include "X11R6IMProtoData.h"

/* XI18N Valid Attribute Name Definition */
#define ExtForwardKeyEvent	"extForwardKeyEvent"
#define ExtMove			"extMove"
#define ExtSetEventMask		"extSetEventMask"

/*
 * Padding macro
 */
#define	IMPAD(length) ((4 - ((length) % 4)) % 4)

/*
 * Target Atom for Transport Connection
 */
#define LOCALES		"LOCALES"
#define TRANSPORT	"TRANSPORT"

#define I18N_OPEN	0
#define I18N_SET	1
#define I18N_GET	2

typedef struct {
    char *transportname;
    int   namelen;
    Bool (*checkAddr)();
} TransportSW;

typedef struct _XIMPending {
    unsigned char *p;
    struct _XIMPending *next;
} XIMPending;

typedef struct _XimProtoHdr {
    CARD8	major_opcode;
    CARD8	minor_opcode;
    CARD16	length;
} XimProtoHdr;

typedef struct {
  CARD16	attribute_id;
  CARD16	type;
  CARD16	length;
  const char *name;
} XIMAttr;

typedef struct {
    CARD16	attribute_id;
    CARD16	type;
    CARD16	length;
    char	*name;
} XICAttr;

typedef struct {
    CARD16	major_opcode;
    CARD16	minor_opcode;
    CARD16	length;
    char	*name;
} XIMExt;

typedef struct _Xi18nClient {
    int		connect_id;
    CARD8	byte_order;
		    /*
		       '?': initial value
		       'B': for Big-Endian
		       'l': for little-endian
		     */
    int		sync;
    XIMPending  *pending;
  
    unsigned char *pending_commit;
    int pending_commit_size;

    void *trans_rec;		/* contains transport specific data  */
    struct _Xi18nClient *next;
} Xi18nClient;

typedef struct _Xi18nCore *Xi18n;

#define DEFAULT_FILTER_MASK	(KeyPressMask)

/* Xi18nAddressRec structure */
typedef struct _Xi18nAddressRec {
    Display	*dpy;
    CARD8	im_byteOrder;	/* byte order 'B' or 'l' */
    /* IM Values */
    long	imvalue_mask;
    Window	im_window;	/* IMServerWindow */
    char	*im_name;	/* IMServerName */
    char	*im_locale;	/* IMLocale */
    char	*im_addr;	/* IMServerTransport */
    XIMStyles	input_styles;	/* IMInputStyles */
    XIMTriggerKeys on_keys;	/* IMOnKeysList */
    XIMTriggerKeys off_keys;	/* IMOffKeysList */
    XIMEncodings encoding_list; /* IMEncodingList */
#if IM_PROTO_HANDLER
    X11R6IMProtoHandler *improto;	/* IMProtocolHander */
#endif
    long	filterevent_mask; /* IMFilterEventMask */
    /* XIM_SERVERS target Atoms */
    Atom	selection;
    Atom	Localename;
    Atom	Transportname;
    /* XIM/XIC Attr */
    int		im_attr_num;
    XIMAttr	*xim_attr;
    int		ic_attr_num;
    XICAttr	*xic_attr;
    CARD16	preeditAttr_id;
    CARD16	statusAttr_id;
    CARD16	separatorAttr_id;
    /* XIMExtension List */
    int		ext_num;
    XIMExt	extension[COMMON_EXTENSIONS_NUM];
    /* transport specific connection address */
    void	*connect_addr;
		/* actual data is defined:
		   XSpecRec in Xi18nX.h for X-based connection.
		   TransSpecRec in Xi18nTr.h for Socket-based connection.
		 */
    /* clients table */
    Xi18nClient *clients;
    Xi18nClient *free_clients;
} Xi18nAddressRec;

typedef struct _Xi18nMethodsRec {
    Bool (*begin)(
		  XIMS
		  );
    Bool (*end)(
		XIMS
		);
    Bool (*send)(
		 XIMS, CARD16, unsigned char*, long
		 );
    Bool (*wait)(
		 XIMS, CARD16, CARD8, CARD8
		 );
    Bool (*disconnect)(
		       XIMS, CARD16
		       );
} Xi18nMethodsRec;

typedef struct _Xi18nCore {
    Xi18nAddressRec address;
    Xi18nMethodsRec methods;
} Xi18nCore;

#define CALL_PROTO_HANDLER \
    if (i18n_core->address.improto->proc) \
	if (!(i18n_core->address.improto->proc(ims, \
			       call_data, \
			       i18n_core->address.improto->client_data))) \
		return;

#endif /* _Xi18n_h */
