/*
###
### This file is part of
###
###                        TurboLinux  ZWinPro
###
###                 Copyright (C) 1999-2000 TurboLinux, Inc.
###                        All Rights Reserved
### Distributed under the terms of the GNU General Public License (GPL)
###
###
### Authors:     TurboLinux Chinese Development Team:
###              Justin Yu   <justiny@turbolinux.com.cn>
###              Sean Chen   <seanc@turbolinux.com.cn>
###              Daniel Fang <danf@turbolinux.com.cn>
###
*/
/* Virtual Keyboard Implementated by Justin Yu
*/

#include "all.h"
#include "layout.h"

#define INC		(x0 += KEY_WIDTH)
#define HALFINC	(x0 += KEY_WIDTH / 2)

static int chinput_vk_in_key (int x0, int y0)
{
	int i;

	// Get 
	for (i = 0; i < N_KEYS; i++)
	{
		if (chinput_util_in_box (x0, y0, vkkeys[i].x, vkkeys[i].y,
				vkkeys[i].x + vkkeys[i].w, vkkeys[i].y + vkkeys[i].h))
			return i;
	}
	// Last chance for return key
	if (chinput_util_in_box (x0, y0,
				vkkeys[28].x - KEY_WIDTH / 2, vkkeys[28].y + KEY_HEIGHT,
				vkkeys[28].x + KEY_WIDTH, vkkeys[28].y + KEY_HEIGHT * 2))
		return  28;

	return -1;
}

static void chinput_vk_set_key (int n, unsigned long keysym,
		int x, int y, int w, int h)
{
	vkkeys[n].s = keysym;		// Keysym defined in X
	vkkeys[n].x = x;
	vkkeys[n].y = y;
	vkkeys[n].w = w;
	vkkeys[n].h = h;
}

void chinput_init_server_virtual_keyboard (int x, int y, int w, int h)
{
	int i;
	int x0, y0;

	// Geometry
	HZServer.hzVKwin.onflag = False;
	HZServer.hzVKwin.x = x;
	HZServer.hzVKwin.y = y;
	HZServer.hzVKwin.w = w;
	HZServer.hzVKwin.h = h;

	// For virtual keyboard
	keytype = KEYBOARD_DEFAULT;

	for (i = 0; i < N_KEYS; i++)
	{
		vkkeys[i].c = vkkeyboard[keytype].normal_keys[i];
		vkkeys[i].f = vkkeyboard[keytype].shift_keys[i];
	}
	vkkeyboard[keytype].flag_shift = False;
	vkkeyboard[keytype].flag_control = False;
	vkkeyboard[keytype].flag_alt = False;

	// Row 1
	x0 = KEY_XOFF;
	y0 = KEY_YOFF * 2 + KEY_WIDTH * 2;
	chinput_vk_set_key (0, XK_asciitilde, 	x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (1, XK_0,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (2, XK_1,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (3, XK_2,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (4, XK_3,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (5, XK_4,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (6, XK_5,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (7, XK_6,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (8, XK_7,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (9, XK_8,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (10, XK_9,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (11, XK_minus,		x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (12, XK_equal,		x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (13, XK_backslash,	x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (14, XK_BackSpace,	x0, y0, KEY_WIDTH, KEY_HEIGHT);

	// Row 2
	x0 = KEY_XOFF;
	y0 = KEY_YOFF * 2 + KEY_HEIGHT * 3;
	chinput_vk_set_key (15, XK_Tab,	x0, y0, (int)(KEY_WIDTH * 1.5), KEY_HEIGHT);
	x0 += (int)(KEY_WIDTH * 1.5);
	chinput_vk_set_key (16, XK_q,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (17, XK_w,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (18, XK_e,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (19, XK_r,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (20, XK_t,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (21, XK_y,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (22, XK_u,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (23, XK_i,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (24, XK_o,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (25, XK_p,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (26, XK_bracketleft,	x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (27, XK_bracketright,x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (28, XK_Return,		x0, y0, (int)(KEY_WIDTH * 1.5),
			KEY_HEIGHT * 2);

	// Row 3
	x0 = KEY_XOFF;
	y0 = KEY_YOFF * 2 + KEY_HEIGHT * 4;
	chinput_vk_set_key (29, XK_Caps_Lock,	x0, y0, KEY_WIDTH * 2, KEY_HEIGHT);
	x0 += KEY_WIDTH * 2;
	chinput_vk_set_key (30, XK_a,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (31, XK_s,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (32, XK_d,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (33, XK_f,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (34, XK_g,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (35, XK_h,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (36, XK_j,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (37, XK_k,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (38, XK_l,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (39, XK_semicolon,	x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (40, XK_apostrophe,	x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;

	// Row 4
	x0 = KEY_XOFF;
	y0 = KEY_YOFF * 2 + KEY_HEIGHT * 5;
	chinput_vk_set_key (41, XK_Shift_L,	x0, y0, (int)(KEY_WIDTH * 2.5),
			KEY_HEIGHT);
	x0 += (int)(KEY_WIDTH * 2.5);
	chinput_vk_set_key (42, XK_z,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (43, XK_x,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (44, XK_c,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (45, XK_v,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (46, XK_b,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (47, XK_n,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (48, XK_m,			x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (49, XK_comma,		x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (50, XK_period,		x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (51, XK_slash,		x0, y0, KEY_WIDTH, KEY_HEIGHT);INC;
	chinput_vk_set_key (52, XK_Shift_R,		x0, y0, (int)(KEY_WIDTH * 2.5),
			KEY_HEIGHT);

	// Row 5
	x0 = KEY_XOFF;
	y0 = KEY_YOFF * 2 + KEY_HEIGHT * 6;
	chinput_vk_set_key (53, XK_Control_L,	x0, y0, KEY_WIDTH * 2, KEY_HEIGHT);
	x0 += KEY_WIDTH * 2;
	chinput_vk_set_key (54, XK_Alt_L,		x0, y0, KEY_WIDTH * 2, KEY_HEIGHT);
	x0 += KEY_WIDTH * 2;
	chinput_vk_set_key (55, XK_space,		x0, y0, KEY_WIDTH * 7, KEY_HEIGHT);
	x0 += KEY_WIDTH * 7;
	chinput_vk_set_key (56, XK_Alt_R,		x0, y0, KEY_WIDTH * 2, KEY_HEIGHT);
	x0 += KEY_WIDTH * 2;
	chinput_vk_set_key (57, XK_Control_R,	x0, y0, KEY_WIDTH * 2, KEY_HEIGHT);

	// Row 0
	x0 = KEY_XOFF;
	y0 = KEY_YOFF + KEY_WIDTH;
	chinput_vk_set_key (58, XK_Escape,	x0, y0, KEY_WIDTH, KEY_HEIGHT);
	INC; INC;
	chinput_vk_set_key (59, XK_F1,		x0, y0, KEY_WIDTH, KEY_HEIGHT); INC;
	chinput_vk_set_key (60, XK_F2,		x0, y0, KEY_WIDTH, KEY_HEIGHT); INC;
	chinput_vk_set_key (61, XK_F3,		x0, y0, KEY_WIDTH, KEY_HEIGHT); INC;
	chinput_vk_set_key (62, XK_F4,		x0, y0, KEY_WIDTH, KEY_HEIGHT);
	INC; HALFINC;
	chinput_vk_set_key (63, XK_F5,		x0, y0, KEY_WIDTH, KEY_HEIGHT); INC;
	chinput_vk_set_key (64, XK_F6,		x0, y0, KEY_WIDTH, KEY_HEIGHT); INC;
	chinput_vk_set_key (65, XK_F7,		x0, y0, KEY_WIDTH, KEY_HEIGHT); INC;
	chinput_vk_set_key (66, XK_F8,		x0, y0, KEY_WIDTH, KEY_HEIGHT);
	INC; HALFINC;
	chinput_vk_set_key (67, XK_F9,		x0, y0, KEY_WIDTH, KEY_HEIGHT); INC;
	chinput_vk_set_key (68, XK_F10,		x0, y0, KEY_WIDTH, KEY_HEIGHT); INC;
	chinput_vk_set_key (69, XK_F11,		x0, y0, KEY_WIDTH, KEY_HEIGHT); INC;
	chinput_vk_set_key (70, XK_F12,		x0, y0, KEY_WIDTH, KEY_HEIGHT);
}

void chinput_vk_draw_window (void)
{
	int i;
	Display *dpy = HZServer.display;
	Window  win  = HZServer.window3;
	GC   dimgc = HZServer.dimGC;
	GC   lightgc = HZServer.lightGC;
	GC   normalgc = HZServer.normalGC;
	GC   panelgc = HZServer.panelGC;
	GC   bargc = HZServer.barGC;
	char str[2];

	// Draw title bar
	XFillRectangle (dpy, win, bargc, KEY_XOFF, KEY_YOFF,
			KEY_WIDTH * 15, KEY_HEIGHT - 6);

	// GB Caption
	if ( (HZServer.encoding == HZSERVER_ENCODING_GB2312)
			|| (HZServer.encoding == HZSERVER_ENCODING_GB18030))
		chinput_util_draw_str (win, lightgc, KEY_XOFF + 180, KEY_YOFF + 17,
				"ÐéÄâ¼üÅÌ", strlen ("ÐéÄâ¼üÅÌ"));

	// Big5 Caption
	else if ( (HZServer.encoding == HZSERVER_ENCODING_BIG5)
			|| (HZServer.encoding == HZSERVER_ENCODING_BIG5HKSCS))
		chinput_util_draw_str (win, lightgc, KEY_XOFF + 180, KEY_YOFF + 17,
				"µêÀÀÁä½L", strlen ("µêÀÀÁä½L"));

	for (i = 0; i < N_KEYS; i++)
	{
		if (vkkeys[i].c)
		{
			if (vkkeyboard[keytype].flag_shift)
				str[0] = vkkeys[i].f;
			else
				str[0] = vkkeys[i].c;
			str[1] = '\0';
			chinput_util_draw_btn (dpy, win, dimgc, lightgc, 
					vkkeys[i].x, vkkeys[i].y, 
					vkkeys[i].x + vkkeys[i].w - 1, 
					vkkeys[i].y + vkkeys[i].h - 1, True);
			//clear first
			XFillRectangle(dpy, win, panelgc, 
					vkkeys[i].x + 8, vkkeys[i].y + 6, 18, 18);
			chinput_util_draw_str (win, normalgc, vkkeys[i].x + 10, vkkeys[i].y + 20,
					str, 1);
#if 0
			chinput_util_draw_mbstr(dpy, win, fontset_gb, normalgc, 
					vkkeys[i].x + 10, vkkeys[i].y + 20, str, 1);
#endif
		}
		else if(vkkeys[i].s == XK_Return){
			chinput_util_draw_btn_ret(dpy, win, dimgc, lightgc,
					vkkeys[i].x, vkkeys[i].y, 
					KEY_WIDTH, KEY_HEIGHT, True);
			chinput_util_draw_str(win, normalgc, vkkeys[i].x + 13, vkkeys[i].y + 35,
					"|", 1);
			chinput_util_draw_str (win, normalgc, vkkeys[i].x + 2,
					vkkeys[i].y + 15 + KEY_HEIGHT,
					"<-", 2);
#if 0
			chinput_util_draw_mbstr(dpy, win, fontset_gb, normalgc, 
					vkkeys[i].x + 13, vkkeys[i].y + 35, "|", 1);
			chinput_util_draw_mbstr(dpy, win, fontset_gb, normalgc, 
					vkkeys[i].x + 2, 
					vkkeys[i].y + 15 + KEY_HEIGHT, "<-", 2);
#endif
		}
		else if(vkkeys[i].s == XK_BackSpace)
		{
			chinput_util_draw_btn(dpy, win, dimgc, lightgc, 
					vkkeys[i].x, vkkeys[i].y, 
					vkkeys[i].x + vkkeys[i].w - 1, 
					vkkeys[i].y + vkkeys[i].h - 1, True);
			chinput_util_draw_str (win, normalgc, vkkeys[i].x + 6, vkkeys[i].y + 22,
					"<-", 2);
#if 0
			chinput_util_draw_mbstr(dpy, win, fontset_gb, normalgc, 
					vkkeys[i].x + 6, vkkeys[i].y + 22, "<-", 2);
#endif
		}
		else if(vkkeys[i].s == XK_Tab)
		{
			chinput_util_draw_btn(dpy, win, dimgc, lightgc, 
					vkkeys[i].x, vkkeys[i].y, 
					vkkeys[i].x + vkkeys[i].w - 1, 
					vkkeys[i].y + vkkeys[i].h - 1, True);
			chinput_util_draw_str (win, normalgc, vkkeys[i].x + 4, vkkeys[i].y + 22,
					"Tab", 3);
#if 0
			chinput_util_draw_mbstr(dpy, win, fontset_gb, normalgc,
					vkkeys[i].x + 4, vkkeys[i].y + 22, "Tab", 3);
#endif
		}
		else if(vkkeys[i].s == XK_Caps_Lock)
		{
			chinput_util_draw_btn(dpy, win, dimgc, lightgc, 
					vkkeys[i].x, vkkeys[i].y, 
					vkkeys[i].x + vkkeys[i].w - 1, 
					vkkeys[i].y + vkkeys[i].h - 1,
					!vkkeyboard[keytype].flag_capslock);
			chinput_util_draw_str (win, normalgc, vkkeys[i].x + 2, vkkeys[i].y + 22,
					"CapsLck", 7);
#if 0
			chinput_util_draw_mbstr(dpy, win, fontset_gb, normalgc, 
					vkkeys[i].x + 2, vkkeys[i].y + 22, "CapsLck", 7);
#endif
		}
		else if(vkkeys[i].s == XK_Shift_L || vkkeys[i].s == XK_Shift_R )
		{
			chinput_util_draw_btn(dpy, win, dimgc, lightgc, 
					vkkeys[i].x, vkkeys[i].y, 
					vkkeys[i].x + vkkeys[i].w - 1, 
					vkkeys[i].y + vkkeys[i].h - 1,
					!vkkeyboard[keytype].flag_shift);
			chinput_util_draw_str (win, normalgc, vkkeys[i].x + 12, vkkeys[i].y + 22,
					"Shift", 5);
#if 0
			chinput_util_draw_mbstr(dpy, win, fontset_gb, normalgc, 
					vkkeys[i].x + 12, vkkeys[i].y + 22, "Shift", 5);
#endif 
		}
		else if(vkkeys[i].s == XK_Control_L || vkkeys[i].s == XK_Control_R )
		{
			chinput_util_draw_btn(dpy, win, dimgc, lightgc, 
					vkkeys[i].x, vkkeys[i].y, 
					vkkeys[i].x + vkkeys[i].w - 1, 
					vkkeys[i].y + vkkeys[i].h - 1,
					!vkkeyboard[keytype].flag_control);
			chinput_util_draw_str (win, normalgc, vkkeys[i].x + 12, vkkeys[i].y + 22,
					"Ctrl", 4);
#if 0
			chinput_util_draw_mbstr(dpy, win, fontset_gb, normalgc, 
					vkkeys[i].x + 12, vkkeys[i].y + 22, "Ctrl", 4);
#endif
		}
		else if(vkkeys[i].s == XK_Alt_L || vkkeys[i].s == XK_Alt_R )
		{
			chinput_util_draw_btn(dpy, win, dimgc, lightgc, 
					vkkeys[i].x, vkkeys[i].y, 
					vkkeys[i].x + vkkeys[i].w - 1, 
					vkkeys[i].y + vkkeys[i].h - 1,
					!vkkeyboard[keytype].flag_alt);
			chinput_util_draw_str (win, normalgc, vkkeys[i].x + 12, vkkeys[i].y + 22,
					"Alt", 3);
#if 0
			chinput_util_draw_mbstr(dpy, win, fontset_gb, normalgc, 
					vkkeys[i].x + 12, vkkeys[i].y + 22, "Alt", 3);
#endif
		}
		else if(vkkeys[i].s == XK_Escape)
		{
			chinput_util_draw_btn(dpy, win, dimgc, lightgc,
					vkkeys[i].x, vkkeys[i].y,
					vkkeys[i].x + vkkeys[i].w - 1,
					vkkeys[i].y + vkkeys[i].h - 1, True);
			chinput_util_draw_str (win, normalgc, vkkeys[i].x + 4, vkkeys[i].y + 22,
					"Esc", 3);
#if 0
			chinput_util_draw_mbstr(dpy, win, fontset_gb, normalgc, 
					vkkeys[i].x + 4, vkkeys[i].y + 22, "Esc", 3);
#endif
		}
		else if(vkkeys[i].s >= XK_F1 && vkkeys[i].s <= XK_F12)
		{
			char buf[4];
			chinput_util_draw_btn(dpy, win, dimgc, lightgc,
					vkkeys[i].x, vkkeys[i].y,
					vkkeys[i].x + vkkeys[i].w - 1,
					vkkeys[i].y + vkkeys[i].h - 1, True);
			sprintf(buf, "F%d", (int)(vkkeys[i].s - XK_F1 + 1));
			chinput_util_draw_str (win, normalgc, vkkeys[i].x + 10 - strlen(buf)*3, 
					vkkeys[i].y + 22,
					buf, strlen(buf));
#if 0
			chinput_util_draw_mbstr(dpy, win, fontset_gb, normalgc, 
					vkkeys[i].x + 10 - strlen(buf)*3, 
					vkkeys[i].y + 22, buf, strlen(buf));
#endif
		}
	}
}

void chinput_vk_proc_window (int x0, int y0)
{
	int i;
	char buf[2];
	Display *dpy = HZServer.display;
	Window  win  = HZServer.window3;
	GC   dimgc = HZServer.dimGC;
	GC   lightgc = HZServer.lightGC;

	//check if a key pressed
	if ((i = chinput_vk_in_key (x0, y0)) != -1)
	{
		if (vkkeys[i].s != XK_Return)
		{
			int another;

			another = -1;
			//shift, alt, control buttons has twins
			chinput_util_draw_btn(dpy, win, dimgc, lightgc, 
					vkkeys[i].x, vkkeys[i].y, 
					vkkeys[i].x + vkkeys[i].w - 1, 
					vkkeys[i].y + vkkeys[i].h - 1, False);
			if (vkkeys[i].s == XK_Shift_L)
				another = 52;
			if (vkkeys[i].s == XK_Shift_R)
				another = 41;
			if (vkkeys[i].s == XK_Control_L)
				another = 57;
			if (vkkeys[i].s == XK_Control_R)
				another = 53;
			if (vkkeys[i].s == XK_Alt_L)
				another = 56;
			if (vkkeys[i].s == XK_Alt_R)
				another = 54;
			if (another != -1)
			{
				chinput_util_draw_btn(dpy, win, dimgc, lightgc, 
						vkkeys[another].x, vkkeys[another].y, 
						vkkeys[another].x+vkkeys[another].w-1, 
						vkkeys[another].y+vkkeys[another].h-1, 
						False);
			}
		}
		else
		{
			chinput_util_draw_btn_ret(dpy, win, dimgc, lightgc,
					vkkeys[i].x, vkkeys[i].y, 
					KEY_WIDTH, KEY_HEIGHT, False);
		}
		chinput_util_wait_btn_release();
		//check the pointer ?
		if (vkkeys[i].s != XK_Return)
		{
			Bool flag;
			int another;
			//check flags, capslock, shift, alt, control keys
			//are in toggle mode
			flag = True;	//default to popup
			another = -1;
			if (vkkeys[i].s == XK_Caps_Lock)
			{
				vkkeyboard[keytype].flag_capslock = 
						!vkkeyboard[keytype].flag_capslock;
				flag = vkkeyboard[keytype].flag_capslock;
			}
			else if(vkkeys[i].s == XK_Shift_L || vkkeys[i].s == XK_Shift_R )
			{
				vkkeyboard[keytype].flag_shift =
						!vkkeyboard[keytype].flag_shift;
				flag = vkkeyboard[keytype].flag_shift;
				//refresh again
				chinput_vk_draw_window ();
			}
			else if(vkkeys[i].s == XK_Control_L || vkkeys[i].s == XK_Control_R)
			{
				vkkeyboard[keytype].flag_control =
						!vkkeyboard[keytype].flag_control;
				flag = vkkeyboard[keytype].flag_control;
			}
			else if(vkkeys[i].s == XK_Alt_L || vkkeys[i].s == XK_Alt_R )
			{
				vkkeyboard[keytype].flag_alt =
						!vkkeyboard[keytype].flag_alt;
				flag = vkkeyboard[keytype].flag_alt;
				//refresh again
				chinput_vk_draw_window ();
			}
			else
			{
				flag = False;
			}

			chinput_util_draw_btn(dpy, win, dimgc, lightgc, 
					vkkeys[i].x, vkkeys[i].y, 
					vkkeys[i].x + vkkeys[i].w - 1, 
					vkkeys[i].y + vkkeys[i].h - 1, !flag);
			//if has twins
			if (vkkeys[i].s == XK_Shift_L)
				another = 52;
			if (vkkeys[i].s == XK_Shift_R)
				another = 41;
			if (vkkeys[i].s == XK_Control_L)
				another = 57;
			if (vkkeys[i].s == XK_Control_R)
				another = 53;
			if (vkkeys[i].s == XK_Alt_L)
				another = 56;
			if (vkkeys[i].s == XK_Alt_R)
				another = 54;
			if (another != -1)
			{
				chinput_util_draw_btn(dpy, win, dimgc, lightgc, 
						vkkeys[another].x, vkkeys[another].y, 
						vkkeys[another].x+vkkeys[another].w-1, 
						vkkeys[another].y+vkkeys[another].h-1, 
						!flag);
			}		
		}
		else
		{
			chinput_util_draw_btn_ret(dpy, win, dimgc, lightgc,
					vkkeys[i].x, vkkeys[i].y, 
					KEY_WIDTH, KEY_HEIGHT, True);
		}

		if (vkkeys[i].s == XK_BackSpace || vkkeys[i].s == XK_Escape	||
				   vkkeys[i].s == XK_Tab	|| vkkeys[i].s == XK_Return	||
				   (vkkeys[i].s >= XK_F1 && vkkeys[i].s <= XK_F12))
		{
			//check which type of client
			//ic = (IC *)chinput_find_ic(last_icid);
			//XGetInputFocus(display, &twin, &revert_to_return);
			if (1)
			{
#if 0
				if(vkkeys[i].s == XK_Tab) buf[0] = '\t';
				else if(vkkeys[i].s == XK_Escape) buf[0] = 0x1b;
				else if(vkkeys[i].s == XK_BackSpace)buf[0] = '\b';
				else if(vkkeys[i].s == XK_Return) buf[0] = '\n';
				else buf[0] = '\0';
				buf[1] = '\0';
				chinput_xim_forward_string (buf, 1);
#endif
				//some clients will hang, so
				if(vkkeys[i].s == XK_BackSpace)
					return;

				chinput_xim_forward_event (vkkeys[i].s,
						vkkeyboard[keytype].flag_shift,
						vkkeyboard[keytype].flag_control,
						vkkeyboard[keytype].flag_alt);
			}
			else
			{
				chinput_util_send_keysym (vkkeys[i].s, 
						vkkeyboard[keytype].flag_shift,
						vkkeyboard[keytype].flag_control,
						vkkeyboard[keytype].flag_alt);
			}
		}
		else
		{
			//check which type of client
			//ic = (IC *)chinput_find_ic(last_icid);
			//XGetInputFocus(display, &twin, &revert_to_return);
			if (1)
			{
				//submit the char
				if (vkkeyboard[keytype].flag_shift)
					buf[0] = vkkeys[i].f;
				else
					buf[0] = vkkeys[i].c;
				buf[1] = '\0';
				chinput_xim_forward_string (buf, 1);
			}
			else
			{
				if (vkkeyboard[keytype].flag_shift)
					chinput_util_send_event (vkkeys[i].f, 
							vkkeyboard[keytype].flag_shift,
							vkkeyboard[keytype].flag_control,
							vkkeyboard[keytype].flag_alt);
				else
					chinput_util_send_event (vkkeys[i].c,
							vkkeyboard[keytype].flag_shift,
							vkkeyboard[keytype].flag_control,
							vkkeyboard[keytype].flag_alt);
			}
		}
	}
	else
	{
		//moving the window
		chinput_util_proc_move_win();
	}
}

void chinput_vk_draw_panel (void)
{
	Display *dpy = HZServer.display;
	Window  win  = HZServer.window3;
	GC  dimgc = HZServer.dimGC;
	GC  lightgc = HZServer.lightGC;
	GC  panelgc = HZServer.panelGC;
	int width = HZServer.hzVKwin.w;
	int height = HZServer.hzVKwin.h;

	if (!(HZServer.hzVKwin.onflag))
		return;

	XFillRectangle (dpy, win, panelgc, 0, 0, width, height);

	// Draw 3D border
	XDrawLine (dpy, win, lightgc, 0, 0, width-1, 0);
	XDrawLine (dpy, win, lightgc, 0, 1, width-1, 1);
	XDrawLine (dpy, win, lightgc, 0, 0, 0, height-1);
	XDrawLine (dpy, win, lightgc, 1, 0, 1, height-1);
	XDrawLine (dpy, win, dimgc, 0, height-1, width-1, height-1);
	XDrawLine (dpy, win, dimgc, 0, height-2, width-1, height-2);
	XDrawLine (dpy, win, dimgc, width-1, 0, width-1, height-1);
	XDrawLine (dpy, win, dimgc, width-2, 0, width-2, height-1);
}
