/* * Copyright (C) 1994,1995 Edward Der-Hua Liu, Hsin-Chu, Taiwan * * @(#)$Header: /mm2/home/cvs/bc-src/tgif/cli_xcin.c,v 1.1 2004/06/18 23:19:08 william Exp $ */ #ifndef _NO_XCIN #define _INCLUDE_FROM_CLI_XCIN_C_ #include "tgifdefs.h" #include "cli_xcin.e" #define K_REJECT (0) #define K_ACCEPT (1) #define CLI_FOCUS_IN (1) #define CLI_FOCUS_OUT (3) #define LOAD_KEYWORD (2) #define XCIN_ATOM "XCIN_A" typedef struct { char kb_state; char _CurInMethod; } InmdState; #define EngChiMask (1) #define HalfFullMask (2) typedef struct { int len; int status; InmdState inmdstate; char tkey[512]; } XCIN_RES; #define EngChi ((inmdstate.kb_state & EngChiMask) ? 1:0) #define HalfFull ((inmdstate.kb_state & HalfFullMask) ? 1:0) #define CurInMethod (inmdstate._CurInMethod) /*static void p_err(char *fmt,...) { va_list args; va_start(args, fmt); fprintf(stderr,"%s:", "cli_xcin:"); vfprintf(stderr, fmt, args); va_end(args); fprintf(stderr,"\n"); exit(-1); } */ static Atom xcin_atom=0; static Window xcin_win=None; static InmdState inmdstate; #define ENDIAN_TEST() (*(int *)"\021\042\063\104"==0x11223344) int my_endian=0; static Window connect_xcin(display) Display *display; { /*Window twin;*/ xcin_atom=XInternAtom(display, XCIN_ATOM,False); my_endian=(int)ENDIAN_TEST(); /* if == 11223344, it is big-endian */ xcin_win=XGetSelectionOwner(display,xcin_atom); return xcin_win; } void send_FocusIn(display, window) Display *display; Window window; { XClientMessageEvent event; /*XEvent erreve;*/ char *tmp=event.data.b; if (connect_xcin(display)==None) return; /* Ensure xcin exists, or the process will be hanged */ event.type=ClientMessage; event.window=window; event.message_type=xcin_atom; event.format=8; tmp[0]=tmp[1]=tmp[2]=0xff; tmp[3]=CLI_FOCUS_IN; memcpy(&tmp[4],&inmdstate, sizeof(inmdstate)); XSendEvent(display, xcin_win, False, 0, (XEvent *)&event); } void send_FocusOut(display, window) Display *display; Window window; { XClientMessageEvent event; /* XEvent erreve; */ char *tmp=event.data.b; if (connect_xcin(display)==None) return; /* Ensure xcin exists, or the process will be hanged */ event.type=ClientMessage; event.window=window; event.message_type=xcin_atom; event.format=8; tmp[0]=tmp[1]=tmp[2]=0xff; tmp[3]=CLI_FOCUS_OUT; memcpy(&tmp[4],&inmdstate, sizeof(inmdstate)); XSendEvent(display, xcin_win, False, 0, (XEvent *)&event); } #ifdef STRUCT_MEMBERS_ARE_BYTE_ALIGNED static void big_little(i) char *i; { char t; t=*i; *i=*(i+3); *(i+3)=t; t=*(i+1); *(i+1)=*(i+2); *(i+2)=t; } #endif static int read_keys(display, buf) Display *display; char *buf; { Atom actual_type; int actual_format/*,i*/; u_long nitems,bytes_after; char *ttt, *cp; #ifdef STRUCT_MEMBERS_ARE_BYTE_ALIGNED XCIN_RES res; #else u_char res[sizeof(XCIN_RES)]; int res_len; #endif int ofs; cp=(char *)&res; ofs=0; do { if (XGetWindowProperty(display,xcin_win,xcin_atom, ofs/4,(sizeof(XCIN_RES)+3)/4, True, AnyPropertyType, &actual_type,&actual_format, &nitems,&bytes_after,(unsigned char **)&ttt) != Success) puts("err property"); memcpy((char *)(&res)+(ofs & ~0x3), ttt, nitems); #ifdef _TGIF_DBG tgif_dbg_enable(FALSE); XFree(ttt); tgif_dbg_enable(TRUE); #else /* ~_TGIF_DBG */ XFree(ttt); #endif /* _TGIF_DBG */ ofs=(ofs & ~0x3) + nitems; } while ((!nitems && !ofs) || bytes_after>0); #ifdef STRUCT_MEMBERS_ARE_BYTE_ALIGNED if (my_endian) { big_little((char *)&res.len); big_little((char *)&res.status); } memcpy(buf,res.tkey, res.len); inmdstate=res.inmdstate; buf[res.len]=0; return res.status; #else res_len = res[0] + (res[1]<<8) + (res[2]<<16) + (res[3]<<24); memcpy(buf, res+10, res_len); buf[res_len] = 0; inmdstate.kb_state = res[8]; inmdstate._CurInMethod = res[9]; return res[4] + (res[5] << 8) + (res[6] << 16) + (res[7] << 24); #endif } static XComposeStatus compose_status = {NULL, 0}; int send_key(display, win, eve, buf) Display *display; Window win; XKeyEvent *eve; char *buf; { XClientMessageEvent event; /*XEvent erreve;*/ char *tmp=event.data.b; u_char tttt[8]; /*KeySym keysym;*/ int count; if (xcin_win==None && connect_xcin(display)==None) return K_REJECT; if ((xcin_win=XGetSelectionOwner(display,xcin_atom))==None) return K_REJECT; event.type=ClientMessage; event.window=win; event.message_type=xcin_atom; event.format=32; count = XLookupString (eve, (char*)tttt, sizeof(tmp), (KeySym *)tmp, &compose_status); memcpy(&tmp[4],&eve->state,4); XSendEvent(display, xcin_win, False, 0, (XEvent *)&event); XSync(display,False); return (read_keys(display, buf)); } #endif /* ~_NO_XCIN */