/*
 * Copyright 1997 by Yu Mingjian.          All Rights Reserved
 *
 * Permission to retain, use, modify, copy, and distribute Chinput1.0
 * in source or binary and its documentation (hereafter, the Software)
 * for noncommercial purpose is hereby granted to you without a fee,
 * provided that this entire copyright and permission notice appear in
 * all such copies, that no charge be associated with such copies,
 * that distribution of derivative works (including value-added
 * distributions such as with additional input dictionaries or fonts)
 * include clarification that such added or derived parts are not from
 * the original Software, and that the names of the author(s) not be
 * used to endorse or promote such works. The author(s) of the software
 * makes no representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 * THE AUTHOR(S) OF THE SOFTWARE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
 * IN NO EVENT SHALL THE AUTHOR(S) OF THE SOFTWARE 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: Yu Mingjian, Institute of High Energy Physics, Academia Sinica
 * 
 */

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <stdio.h>

#include "hzclient.h"


HZclientInit(dpy)
Display *dpy;
{
        hz_protocol_atom = XInternAtom(dpy, HZ_PROTOCOL_ATOM, False);
        hz_input_atom    = XInternAtom(dpy, HZ_INPUT_ATOM,    False);
        hz_output_atom   = XInternAtom(dpy, HZ_OUTPUT_ATOM,   False);
        hz_query_atom    = XInternAtom(dpy, HZ_QUERY_ATOM,    False);
        hz_reply_atom    = XInternAtom(dpy, HZ_REPLY_ATOM,    False);
	hz_config_atom   = XInternAtom(dpy, HZ_CONFIG_ATOM,   False);

}

int HZprocInput(ev, number, keycode, keystate, str)
XClientMessageEvent *ev;
int *number; 
unsigned int *keycode, *keystate;
char *str;
{
	int i;
	char *buf = ev->data.b;

        if (ev->message_type != hz_output_atom) return -1;

	memset(str, '\0', 20);
	strncpy(str, buf+1, ev->data.b[0]);
	*number = ev->data.b[0];

	/* only one char */
	if(ev->data.b[0] == 1) {
		*keycode = ev->data.l[1];

		/* function key, or control keys */
		if(ev->data.l[1] & 0xff00 || (ev->data.l[2] & ControlMask)) {
			*keystate = ev->data.l[2];
			return HZSERVER_OUTPUT_FUNCTION_KEY;
		}

		/* normal keys */
		else return HZSERVER_OUTPUT_NORMAL_KEY;

	/* hanzi string */
	} else 
		return HZSERVER_OUTPUT_HANZI;
	

}
/*
int HZqueryServer(dpy, win, type, str)
Display *dpy;
Window win;
int type;
char *str;
{
	Window twin;
	XEvent report;
        XClientMessageEvent event;
        hz_protocol_atom = XInternAtom(dpy, HZ_PROTOCOL_ATOM,False);

        twin = XGetSelectionOwner(dpy,hz_protocol_atom);
        if(twin == None){
                strcpy(str, "");
                return 0;
	}
        event.type=ClientMessage;
        event.window=win;
        event.message_type=hz_query_atom;
        event.format=32;
        event.data.l[0] = type;
        XSendEvent(dpy, twin, False, 0, (XEvent *)&event);
        XSync(dpy,False);

	while(1){
		XNextEvent(dpy, &report);
		switch(report.type){
		case ClientMessage:
			if(report.xclient.message_type == hz_reply_atom &&
				report.xclient.data.b[0] == type)
		        strcpy(str, &report.xclient.data.b[1]);
			return 1;
		default:
			break;
		}	
	}
}
*/


int HZsendKey(dpy, win, eve)
Display *dpy;
Window win;
XKeyEvent *eve;
{
	Window twin;
	XClientMessageEvent event;
        char bf[20];
        int  bfsize = 20;
        KeySym keysym;
        XComposeStatus compose;
        int charcount;

	hz_protocol_atom = XInternAtom(dpy, HZ_PROTOCOL_ATOM,False);
	twin = XGetSelectionOwner(dpy,hz_protocol_atom);

        charcount = XLookupString(eve, bf,
                bfsize, &keysym, &compose);

	if(twin == None || (eve->state & ControlMask) ) {
		event.type = ClientMessage;
        	event.window = win;
        	event.message_type=hz_output_atom;
        	event.format=32;
        	event.data.b[0] = 1;
        	event.data.l[1] = keysym;
		event.data.l[2] = eve->state;
	        XSendEvent(dpy, win, False, 0, (XEvent *)&event);
        	XSync(dpy,False);
	} else {

		event.type=ClientMessage;
		event.window=win;
		event.message_type=hz_input_atom;
		event.format=32;
		event.data.l[0] = keysym;
		event.data.l[1] = eve->state;

		XSendEvent(dpy, twin, False, 0, (XEvent *)&event);
		XSync(dpy,False);
	}
}

/* configure the server
*/

HZconfigServer(dpy, win, flag, n1, n2, n3)
Display *dpy;
Window  win;
int flag;		/* configure type */
int n1, n2, n3;		/* for color n1,n2,n3 = red,green,blue
			   for input method n1 = method, n2, n3 not used */
{
	
        Window twin;
        XClientMessageEvent event;

        hz_protocol_atom = XInternAtom(dpy, HZ_PROTOCOL_ATOM,False);
        twin = XGetSelectionOwner(dpy,hz_protocol_atom);

        if(twin == None) {
		printf("Server not started.\n");
		return 0;
	}

        event.type = ClientMessage;
        event.window = win;
        event.message_type=hz_config_atom;
        event.format=32;
        event.data.l[0] = flag;
        event.data.l[1] = n1;
        event.data.l[2] = n2;
        event.data.l[3] = n3;
        XSendEvent(dpy, twin, False, 0, (XEvent *)&event);
}

