xtrapchar.c revision 876ff6fe
1876ff6feSmrg/* $XFree86: xc/programs/xtrap/xtrapchar.c,v 1.2 2001/11/19 15:33:41 tsi Exp $ */ 2876ff6feSmrg/* 3876ff6feSmrg * @DEC_COPYRIGHT@ 4876ff6feSmrg */ 5876ff6feSmrg/* 6876ff6feSmrg * HISTORY 7876ff6feSmrg * Log: xtrapchar.c,v $ 8876ff6feSmrg * Revision 1.1.2.2 1993/12/14 12:37:15 Kenneth_Miller 9876ff6feSmrg * ANSI-standardize code and turn client build on 10876ff6feSmrg * [1993/12/09 20:15:33 Kenneth_Miller] 11876ff6feSmrg * 12876ff6feSmrg * EndLog$ 13876ff6feSmrg */ 14876ff6feSmrg#if !defined(lint) && 0 15876ff6feSmrgstatic char *rcsid = "@(#)RCSfile: xtrapchar.c,v $ Revision: 1.1.2.2 $ (DEC) Date: 1993/12/14 12:37:15 $"; 16876ff6feSmrg#endif 17876ff6feSmrg/***************************************************************************** 18876ff6feSmrgCopyright 1987, 1988, 1989, 1990, 1991, 1993 by Digital Equipment Corp., 19876ff6feSmrgMaynard, MA 20876ff6feSmrg 21876ff6feSmrgPermission to use, copy, modify, and distribute this software and its 22876ff6feSmrgdocumentation for any purpose and without fee is hereby granted, 23876ff6feSmrgprovided that the above copyright notice appear in all copies and that 24876ff6feSmrgboth that copyright notice and this permission notice appear in 25876ff6feSmrgsupporting documentation, and that the name of Digital not be 26876ff6feSmrgused in advertising or publicity pertaining to distribution of the 27876ff6feSmrgsoftware without specific, written prior permission. 28876ff6feSmrg 29876ff6feSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 30876ff6feSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 31876ff6feSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 32876ff6feSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 33876ff6feSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 34876ff6feSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 35876ff6feSmrgSOFTWARE. 36876ff6feSmrg 37876ff6feSmrg*****************************************************************************/ 38876ff6feSmrg#define ProgName "xtrapchar" 39876ff6feSmrg/* 40876ff6feSmrg**++ 41876ff6feSmrg** FACILITY: xtrapchar - Converts ANSI character sequences to X. 42876ff6feSmrg** 43876ff6feSmrg** MODULE DESCRIPTION: 44876ff6feSmrg** 45876ff6feSmrg** Parses ANSI character sequences including application program 46876ff6feSmrg** sequences to synthesize input events to X Window servers 47876ff6feSmrg** using the XTrap server extension. Additionally, this main 48876ff6feSmrg** module is designed to be used with the voice 49876ff6feSmrg** recognition systems which will allow voice input into X Servers. 50876ff6feSmrg** 51876ff6feSmrg** AUTHORS: 52876ff6feSmrg** 53876ff6feSmrg** Kenneth B. Miller 54876ff6feSmrg** 55876ff6feSmrg** CREATION DATE: March 23, 1991 56876ff6feSmrg** 57876ff6feSmrg** DESIGN ISSUES: 58876ff6feSmrg** 59876ff6feSmrg** Accepts non-buffered Ascii characters as input and 60876ff6feSmrg** performs a table look-up to determine what the corresponding 61876ff6feSmrg** X actions are to be performed. 62876ff6feSmrg** 63876ff6feSmrg** Uses chparse() which was contributed to DECUS C by Roy 64876ff6feSmrg** Lomicka and later revised by Martin Minow and myself. 65876ff6feSmrg** Also, getopt() is used to parse the command 66876ff6feSmrg** line arguments prior to calling XtAppInitialize(). 67876ff6feSmrg** Currently only the -v argument is supported to indicate 68876ff6feSmrg** echoing of characters received for debugging 69876ff6feSmrg** purposes. 70876ff6feSmrg** 71876ff6feSmrg** 72876ff6feSmrg** CAVEAT: 73876ff6feSmrg** 74876ff6feSmrg** This program has *only* been used with Digital Workstations 75876ff6feSmrg** using the LK201 compatible keyboard. Though reasonable 76876ff6feSmrg** effort was done to maintain portability, no claims are made 77876ff6feSmrg** as to the current level of portability to non-DEC servers 78876ff6feSmrg** for this program. 79876ff6feSmrg**-- 80876ff6feSmrg*/ 81876ff6feSmrg#include <unistd.h> 82876ff6feSmrg#include <stdlib.h> 83876ff6feSmrg#include <ctype.h> 84876ff6feSmrg#include <X11/extensions/xtraplib.h> 85876ff6feSmrg#include <X11/extensions/xtraplibp.h> 86876ff6feSmrg#include <X11/keysym.h> 87876ff6feSmrg 88876ff6feSmrg#include "chparse.h" 89876ff6feSmrg 90876ff6feSmrg#ifndef vaxc 91876ff6feSmrg#define globalref extern 92876ff6feSmrg#endif 93876ff6feSmrg#ifdef Lynx 94876ff6feSmrgextern char *optarg; 95876ff6feSmrgextern int optind; 96876ff6feSmrgextern int opterr; 97876ff6feSmrg#endif 98876ff6feSmrg 99876ff6feSmrg /* Special private indicators */ 100876ff6feSmrg#define BPRESS '!' 101876ff6feSmrg#define BRELEASE '"' 102876ff6feSmrg#define BCLICK '#' 103876ff6feSmrg#define APRESS '$' 104876ff6feSmrg#define ARELEASE '%' 105876ff6feSmrg#define CPRESS '(' 106876ff6feSmrg#define CRELEASE ')' 107876ff6feSmrg#define SPRESS '+' 108876ff6feSmrg#define SRELEASE '-' 109876ff6feSmrg#define DPRIVATE '=' 110876ff6feSmrg#define MNOTIFY '>' 111876ff6feSmrg#define RMNOTIFY '?' 112876ff6feSmrg 113876ff6feSmrg#define NPARAM 8 114876ff6feSmrg#define NINTER 8 115876ff6feSmrg#define NUL 0x00 116876ff6feSmrg#define CAN 0x18 117876ff6feSmrg#define SUB 0x1A 118876ff6feSmrg#define ESC 0x1B 119876ff6feSmrg#define DEL 0x7F 120876ff6feSmrg#define SS3 0x8f 121876ff6feSmrg#define DCS 0x90 122876ff6feSmrg#define CSI 0x9B 123876ff6feSmrg#define ST 0x9C 124876ff6feSmrg#define OSC 0x9D 125876ff6feSmrg#define PM 0x9E 126876ff6feSmrg#define APC 0x9F 127876ff6feSmrg 128876ff6feSmrgstatic BOOL verbose_flag = FALSE; 129876ff6feSmrgstatic INT16 column = 0; 130876ff6feSmrgstatic int state = NUL; /* Parser state (n.z. if incomplete) */ 131876ff6feSmrgstatic Window root; 132876ff6feSmrgstatic BOOL passive_shift; /* Cap's assumed? */ 133876ff6feSmrgstatic BOOL passive_ctrl; /* Control key assumed? */ 134876ff6feSmrgstatic BOOL shift; /* Cap's on? */ 135876ff6feSmrgstatic BOOL ctrl; /* Control key? */ 136876ff6feSmrgstatic BOOL alt; /* Alt key? */ 137876ff6feSmrgKeyCode alt_code; 138876ff6feSmrgKeyCode ctrl_code; 139876ff6feSmrgKeyCode shift_code; 140876ff6feSmrg 141876ff6feSmrg 142876ff6feSmrg 143876ff6feSmrg#define _AdjustCol(length) \ 144876ff6feSmrg if ((column += length) >= 79) \ 145876ff6feSmrg { \ 146876ff6feSmrg printf("\n"); \ 147876ff6feSmrg column = length; \ 148876ff6feSmrg } 149876ff6feSmrg 150876ff6feSmrgstatic void KeyClick(XETC *tc, KeyCode keycode) 151876ff6feSmrg{ 152876ff6feSmrg if (passive_ctrl && !ctrl) 153876ff6feSmrg { 154876ff6feSmrg XESimulateXEventRequest(tc, KeyPress, ctrl_code, 0, 0, 0); 155876ff6feSmrg } 156876ff6feSmrg if (passive_shift && !shift) 157876ff6feSmrg { 158876ff6feSmrg XESimulateXEventRequest(tc, KeyPress, shift_code, 0, 0, 0); 159876ff6feSmrg } 160876ff6feSmrg XESimulateXEventRequest(tc, KeyPress, keycode, 0, 0, 0); 161876ff6feSmrg XESimulateXEventRequest(tc, KeyRelease, keycode, 0, 0, 0); 162876ff6feSmrg if (passive_shift && !shift) 163876ff6feSmrg { 164876ff6feSmrg XESimulateXEventRequest(tc, KeyRelease, shift_code, 0, 0, 0); 165876ff6feSmrg } 166876ff6feSmrg if (passive_ctrl && !ctrl) 167876ff6feSmrg { 168876ff6feSmrg XESimulateXEventRequest(tc, KeyRelease, ctrl_code, 0, 0, 0); 169876ff6feSmrg } 170876ff6feSmrg passive_ctrl = passive_shift = FALSE; /* Action's been completed */ 171876ff6feSmrg} 172876ff6feSmrg 173876ff6feSmrg 174876ff6feSmrg/* 175876ff6feSmrg** 176876ff6feSmrg** FORWARD DECLARATIONS 177876ff6feSmrg** 178876ff6feSmrg*/ 179876ff6feSmrgstatic int get_csi_key ( XETC *tc , int private , int param [], 180876ff6feSmrg int nparam , int inter [], int ninter , int final ); 181876ff6feSmrgstatic int get_ss3_key ( XETC *tc , int private , int param [], 182876ff6feSmrg int nparam , int inter [], int ninter , int final ); 183876ff6feSmrgstatic void send_special ( XETC *tc , int private , int param [], 184876ff6feSmrg int nparam , int inter [], int ninter , int final ); 185876ff6feSmrgstatic KeyCode get_typical_char ( XETC *tc , CARD32 keysym); 186876ff6feSmrgstatic KeyCode get_keycode ( XETC *tc , KeySym keysym); 187876ff6feSmrg 188876ff6feSmrg 189876ff6feSmrgint 190876ff6feSmrgmain(int argc, char *argv[]) 191876ff6feSmrg{ 192876ff6feSmrg Widget appW; 193876ff6feSmrg Display *dpy; 194876ff6feSmrg XETrapGetCurRep ret_cur; 195876ff6feSmrg XETC *tc; 196876ff6feSmrg XtAppContext app; 197876ff6feSmrg char *tmp = NULL; 198876ff6feSmrg INT16 ch; 199876ff6feSmrg INT16 i; 200876ff6feSmrg KeyCode keycode; 201876ff6feSmrg /* ESC & CSI Parsing variables */ 202876ff6feSmrg int max_delay = 3; 203876ff6feSmrg int rest_delay = 2; 204876ff6feSmrg int private; /* Sequence private char, 'X' if error */ 205876ff6feSmrg int param[NPARAM]; /* numeric param, starting at param[1] */ 206876ff6feSmrg int nparam; /* Number of parameters */ 207876ff6feSmrg int inter[NINTER]; /* intermediate char, starting at [1] */ 208876ff6feSmrg int ninter; /* Number of intermediates */ 209876ff6feSmrg int final; /* Sequence terminator */ 210876ff6feSmrg int *popterr; 211876ff6feSmrg#ifndef vms 212876ff6feSmrg popterr = &opterr; 213876ff6feSmrg#else 214876ff6feSmrg popterr = XEgetopterr(); 215876ff6feSmrg#endif 216876ff6feSmrg *popterr = 0; /* don't complain about -d for display */ 217876ff6feSmrg while ((ch = getopt(argc, argv, "d:v")) != EOF) 218876ff6feSmrg { 219876ff6feSmrg switch(ch) 220876ff6feSmrg { 221876ff6feSmrg case 'v': 222876ff6feSmrg verbose_flag = TRUE; 223876ff6feSmrg break; 224876ff6feSmrg case 'd': /* -display, let's let the toolkit parse it */ 225876ff6feSmrg break; 226876ff6feSmrg default: 227876ff6feSmrg break; 228876ff6feSmrg } 229876ff6feSmrg } 230876ff6feSmrg appW = XtAppInitialize(&app,"XTrap",(XrmOptionDescList)NULL,(Cardinal)0L, 231876ff6feSmrg (int *)&argc, (String *)argv, NULL,(ArgList)&tmp, 232876ff6feSmrg (Cardinal)0); 233876ff6feSmrg 234876ff6feSmrg dpy = XtDisplay(appW); 235876ff6feSmrg if (verbose_flag) 236876ff6feSmrg { 237876ff6feSmrg printf("Display: %s \n", DisplayString(dpy)); 238876ff6feSmrg } 239876ff6feSmrg if ((tc = XECreateTC(dpy,0L, NULL)) == False) 240876ff6feSmrg { 241876ff6feSmrg fprintf(stderr,"%s: could not initialize XTrap extension\n", ProgName); 242876ff6feSmrg exit (1L); 243876ff6feSmrg } 244876ff6feSmrg root = RootWindow(dpy,DefaultScreen(dpy)); 245876ff6feSmrg (void)XEStartTrapRequest(tc); 246876ff6feSmrg alt_code = XKeysymToKeycode(tc->dpy,XK_Alt_L); 247876ff6feSmrg ctrl_code = XKeysymToKeycode(tc->dpy,XK_Control_L); 248876ff6feSmrg shift_code = XKeysymToKeycode(tc->dpy,XK_Shift_L); 249876ff6feSmrg 250876ff6feSmrg 251876ff6feSmrg 252876ff6feSmrg if (verbose_flag) 253876ff6feSmrg { 254876ff6feSmrg (void)XEGetCurrentRequest(tc,&ret_cur); 255876ff6feSmrg XEPrintCurrent(stderr,&ret_cur); 256876ff6feSmrg } 257876ff6feSmrg 258876ff6feSmrg column = 0; /* if displaying char's, don't go beyond 80 columns */ 259876ff6feSmrg 260876ff6feSmrg while ((ch = chparse(max_delay, rest_delay, &state, &private, param, 261876ff6feSmrg &nparam, inter, &ninter, &final)) != -1) 262876ff6feSmrg { 263876ff6feSmrg if (ch == -2) 264876ff6feSmrg { 265876ff6feSmrg continue; /* timeout condition */ 266876ff6feSmrg } 267876ff6feSmrg if ((!ferror(stdin)) && (!feof(stdin)) && (state == 0)) 268876ff6feSmrg { /* we got something */ 269876ff6feSmrg switch(ch) 270876ff6feSmrg { 271876ff6feSmrg case CSI: /* Control Sequence */ 272876ff6feSmrg keycode = get_csi_key(tc, private, param, nparam, inter, 273876ff6feSmrg ninter, final); 274876ff6feSmrg if (keycode) 275876ff6feSmrg KeyClick(tc, keycode); 276876ff6feSmrg break; 277876ff6feSmrg case SS3: /* Keypad stuff */ 278876ff6feSmrg keycode = get_ss3_key(tc, private, param, nparam, inter, 279876ff6feSmrg ninter, final); 280876ff6feSmrg if (keycode) 281876ff6feSmrg KeyClick(tc, keycode); 282876ff6feSmrg break; 283876ff6feSmrg case APC: /* Application Cmd (Button's, Press, Release) */ 284876ff6feSmrg send_special(tc, private, param, nparam, inter, ninter, 285876ff6feSmrg final); 286876ff6feSmrg break; 287876ff6feSmrg case ESC: /* Escape Sequence */ 288876ff6feSmrg /* send ESCAPE */ 289876ff6feSmrg if (!(keycode = XKeysymToKeycode(tc->dpy,XK_Escape))) 290876ff6feSmrg { /* must be an LK201 keyboard */ 291876ff6feSmrg BOOL orig_ctrl = ctrl; 292876ff6feSmrg /* 293876ff6feSmrg * the following is kind of strange. We need to 294876ff6feSmrg * have ctrl TRUE for get_typical_char() to 295876ff6feSmrg * report the verbose message correctly. We 296876ff6feSmrg * can't use passive_ctrl cause it resets it. 297876ff6feSmrg * Then, for KeyClick(), ctrl has to be FALSE 298876ff6feSmrg * and passive_ctrl has to be TRUE in order for 299876ff6feSmrg * us to get the desired <CTRL>[ to simulate 300876ff6feSmrg * an escape key. Once it's all done, we need 301876ff6feSmrg * to return ctrl to whatever it was and clear 302876ff6feSmrg * the passive_ctrl. 303876ff6feSmrg */ 304876ff6feSmrg ctrl = TRUE; /* for get_typical_char */ 305876ff6feSmrg keycode = get_typical_char(tc, (CARD32)'['); 306876ff6feSmrg ctrl = FALSE; /* for KeyClick */ 307876ff6feSmrg passive_ctrl = TRUE; /* for KeyClick */ 308876ff6feSmrg KeyClick(tc, keycode); 309876ff6feSmrg passive_ctrl = FALSE; /* to continue */ 310876ff6feSmrg ctrl = orig_ctrl; /* to continue */ 311876ff6feSmrg } 312876ff6feSmrg else 313876ff6feSmrg { 314876ff6feSmrg KeyClick(tc, keycode); 315876ff6feSmrg if (verbose_flag) 316876ff6feSmrg { 317876ff6feSmrg _AdjustCol(strlen("<ESC>")); 318876ff6feSmrg printf("<ESC>"); 319876ff6feSmrg } 320876ff6feSmrg } 321876ff6feSmrg /* send private (if valid) */ 322876ff6feSmrg if (private != NUL && private != 'X' && 323876ff6feSmrg (keycode = get_typical_char(tc, (CARD32)private))) 324876ff6feSmrg KeyClick(tc, keycode); 325876ff6feSmrg /* send addt'l parameters, if any */ 326876ff6feSmrg for (i = 1; i <= nparam; i++) 327876ff6feSmrg if ((keycode = get_typical_char(tc, (CARD32)param[i]))) 328876ff6feSmrg KeyClick(tc, keycode); 329876ff6feSmrg /* send intermediate's, if any */ 330876ff6feSmrg for (i = 1; i <= ninter; i++) 331876ff6feSmrg if ((keycode = get_typical_char(tc, (CARD32)inter[i]))) 332876ff6feSmrg KeyClick(tc, keycode); 333876ff6feSmrg /* send final character */ 334876ff6feSmrg if ((keycode = get_typical_char(tc, (CARD32)final))) 335876ff6feSmrg KeyClick(tc, keycode); 336876ff6feSmrg break; 337876ff6feSmrg 338876ff6feSmrg case DCS: /* We don't deal with these */ 339876ff6feSmrg case OSC: 340876ff6feSmrg case PM: 341876ff6feSmrg if (verbose_flag) 342876ff6feSmrg { 343876ff6feSmrg printf("Ignoring the following: "); 344876ff6feSmrg dumpsequence(state, ch, private, param, nparam, 345876ff6feSmrg inter, ninter, final, &column); 346876ff6feSmrg } 347876ff6feSmrg break; 348876ff6feSmrg default: /* typical character */ 349876ff6feSmrg keycode = get_typical_char(tc, (CARD32)ch); 350876ff6feSmrg if (keycode) 351876ff6feSmrg KeyClick(tc, keycode); 352876ff6feSmrg break; 353876ff6feSmrg } 354876ff6feSmrg } 355876ff6feSmrg else 356876ff6feSmrg { /* error? */ 357876ff6feSmrg if (ferror(stdin) || state != 0) 358876ff6feSmrg { 359876ff6feSmrg perror("Error occurred parsing input characters!\n"); 360876ff6feSmrg } 361876ff6feSmrg break; 362876ff6feSmrg } 363876ff6feSmrg } 364876ff6feSmrg /* Clean things up */ 365876ff6feSmrg XEFreeTC(tc); 366876ff6feSmrg (void)XCloseDisplay(dpy); 367876ff6feSmrg 368876ff6feSmrg exit(0L); 369876ff6feSmrg} 370876ff6feSmrg 371876ff6feSmrgstatic int get_csi_key(tc, private, param, nparam, inter, ninter, final) 372876ff6feSmrg XETC *tc; 373876ff6feSmrg int private; 374876ff6feSmrg int param[], nparam; 375876ff6feSmrg int inter[], ninter; 376876ff6feSmrg int final; 377876ff6feSmrg{ 378876ff6feSmrg KeySym keysym = 0; 379876ff6feSmrg switch(param[1]) 380876ff6feSmrg { 381876ff6feSmrg case 0: 382876ff6feSmrg switch ((char )final) 383876ff6feSmrg { 384876ff6feSmrg case 'A': keysym = XK_Up; break; 385876ff6feSmrg case 'B': keysym = XK_Down; break; 386876ff6feSmrg case 'C': keysym = XK_Right; break; 387876ff6feSmrg case 'D': keysym = XK_Left; break; 388876ff6feSmrg default: 389876ff6feSmrg dumpsequence(state, CSI, private, param, nparam, 390876ff6feSmrg inter, ninter, final, &column); 391876ff6feSmrg break; 392876ff6feSmrg } 393876ff6feSmrg break; 394876ff6feSmrg case 1: keysym = XK_Find; break; 395876ff6feSmrg case 2: keysym = XK_Insert; break; 396876ff6feSmrg#ifdef DXK_Remove 397876ff6feSmrg case 3: keysym = DXK_Remove; break; 398876ff6feSmrg#endif 399876ff6feSmrg case 4: keysym = XK_Select; break; 400876ff6feSmrg case 5: keysym = XK_Prior; break; 401876ff6feSmrg case 6: keysym = XK_Next; break; 402876ff6feSmrg case 17: keysym = XK_F6; break; 403876ff6feSmrg case 18: keysym = XK_F7; break; 404876ff6feSmrg case 19: keysym = XK_F8; break; 405876ff6feSmrg case 20: keysym = XK_F9; break; 406876ff6feSmrg case 21: keysym = XK_F10; break; 407876ff6feSmrg case 23: keysym = XK_F11; break; 408876ff6feSmrg case 24: keysym = XK_F12; break; 409876ff6feSmrg case 25: keysym = XK_F13; break; 410876ff6feSmrg case 26: keysym = XK_F14; break; 411876ff6feSmrg case 28: keysym = XK_Help; break; 412876ff6feSmrg case 29: keysym = XK_Menu; break; 413876ff6feSmrg case 31: keysym = XK_F17; break; 414876ff6feSmrg case 32: keysym = XK_F18; break; 415876ff6feSmrg case 33: keysym = XK_F19; break; 416876ff6feSmrg case 34: keysym = XK_F20; break; 417876ff6feSmrg default: 418876ff6feSmrg dumpsequence(state, CSI, private, param, nparam, 419876ff6feSmrg inter, ninter, final, &column); 420876ff6feSmrg } 421876ff6feSmrg 422876ff6feSmrg return(get_keycode(tc, keysym)); 423876ff6feSmrg} 424876ff6feSmrg 425876ff6feSmrg /* 426876ff6feSmrg * XTrap special sequences: 427876ff6feSmrg * ButtonPress: <APC>=!X (where 'X' is 'A', 'B', or 'C' 428876ff6feSmrg * for MB1, MB2, MB3 respectively) 429876ff6feSmrg * ButtonRelease: <APC>="X (where 'X' is 'A', 'B', or 'C' 430876ff6feSmrg * for MB1, MB2, MB3 respectively) 431876ff6feSmrg * ButtonClick: <APC>=#X (where 'X' is 'A', 'B', or 'C' 432876ff6feSmrg * for MB1, MB2, MB3 respectively) 433876ff6feSmrg * AltPress: <APC>=$~ 434876ff6feSmrg * AltRelease: <APC>=%~ 435876ff6feSmrg * CtrlPress: <APC>=(~ 436876ff6feSmrg * CtrlRelease: <APC>=)~ 437876ff6feSmrg * ShiftPress: <APC>=+~ 438876ff6feSmrg * ShiftRelease: <APC>=-~ 439876ff6feSmrg * MotionNotify: <APC>>;X;Y~ (where 'X' is the X coord and 'Y' 440876ff6feSmrg * is the Y coord of the desired 441876ff6feSmrg * pointer position) 442876ff6feSmrg * Relative MotionNotify: 443876ff6feSmrg * <APC>?;X;Y~ (where 'X' is the X coord and 'Y' 444876ff6feSmrg * is the Y coord of the desired 445876ff6feSmrg * pointer position) 446876ff6feSmrg * 447876ff6feSmrg */ 448876ff6feSmrgstatic void send_special(tc, private, param, nparam, inter, ninter, final) 449876ff6feSmrg XETC *tc; 450876ff6feSmrg int private; 451876ff6feSmrg int param[], nparam; 452876ff6feSmrg int inter[], ninter; 453876ff6feSmrg int final; 454876ff6feSmrg{ 455876ff6feSmrg switch(private) 456876ff6feSmrg { 457876ff6feSmrg case DPRIVATE: /* default APC */ 458876ff6feSmrg if (ninter != 1) 459876ff6feSmrg { /* Not my sequence */ 460876ff6feSmrg dumpsequence(state, APC, private, param, nparam, 461876ff6feSmrg inter, ninter, final, &column); 462876ff6feSmrg return; 463876ff6feSmrg } 464876ff6feSmrg else 465876ff6feSmrg { 466876ff6feSmrg switch(inter[1]) 467876ff6feSmrg { 468876ff6feSmrg Window rid, wid; 469876ff6feSmrg int x, y, wx, wy; 470876ff6feSmrg unsigned int sm; 471876ff6feSmrg CARD8 detail; 472876ff6feSmrg 473876ff6feSmrg case BPRESS: 474876ff6feSmrg detail = (final - 'A' + 1); 475876ff6feSmrg if ((Bool)XQueryPointer(tc->dpy,root,&rid,&wid,&x, 476876ff6feSmrg &y,&wx,&wy,&sm) == False) 477876ff6feSmrg { 478876ff6feSmrg fprintf(stderr, "\nPointer's not on screen 0!\n"); 479876ff6feSmrg } 480876ff6feSmrg else 481876ff6feSmrg { 482876ff6feSmrg XESimulateXEventRequest(tc, ButtonPress, detail, 483876ff6feSmrg x, y, 0); 484876ff6feSmrg if (verbose_flag) 485876ff6feSmrg { 486876ff6feSmrg _AdjustCol(strlen("<MB%d-Press> ")-1); 487876ff6feSmrg printf("<MB%d-Press> ", detail); 488876ff6feSmrg } 489876ff6feSmrg } 490876ff6feSmrg break; 491876ff6feSmrg case BRELEASE: 492876ff6feSmrg detail = (final - 'A' + 1); 493876ff6feSmrg if ((Bool)XQueryPointer(tc->dpy,root,&rid,&wid,&x, 494876ff6feSmrg &y,&wx,&wy,&sm) == False) 495876ff6feSmrg { 496876ff6feSmrg fprintf(stderr, "\nPointer's not on screen 0!\n"); 497876ff6feSmrg } 498876ff6feSmrg else 499876ff6feSmrg { 500876ff6feSmrg XESimulateXEventRequest(tc, ButtonRelease, detail, 501876ff6feSmrg x,y,0); 502876ff6feSmrg if (verbose_flag) 503876ff6feSmrg { 504876ff6feSmrg _AdjustCol(strlen("<MB%d-Release> ")-1); 505876ff6feSmrg printf("<MB%d-Release> ", detail); 506876ff6feSmrg } 507876ff6feSmrg } 508876ff6feSmrg break; 509876ff6feSmrg case BCLICK: 510876ff6feSmrg detail = (final - 'A' + 1); 511876ff6feSmrg if (XQueryPointer(tc->dpy,root,&rid,&wid,&x,&y, 512876ff6feSmrg &wx,&wy,&sm) 513876ff6feSmrg == False) 514876ff6feSmrg { 515876ff6feSmrg fprintf(stderr, "\nPointer's not on screen 0!\n"); 516876ff6feSmrg } 517876ff6feSmrg else 518876ff6feSmrg { 519876ff6feSmrg XESimulateXEventRequest(tc,ButtonPress, 520876ff6feSmrg detail,x,y,0); 521876ff6feSmrg XESimulateXEventRequest(tc,ButtonRelease, 522876ff6feSmrg detail,x,y,0); 523876ff6feSmrg if (verbose_flag) 524876ff6feSmrg { 525876ff6feSmrg _AdjustCol(strlen("<MB%d> ")-1); 526876ff6feSmrg printf("<MB%d> ", detail); 527876ff6feSmrg } 528876ff6feSmrg } 529876ff6feSmrg break; 530876ff6feSmrg case APRESS: 531876ff6feSmrg alt = TRUE; 532876ff6feSmrg XESimulateXEventRequest(tc,KeyPress,alt_code,0,0,0); 533876ff6feSmrg break; 534876ff6feSmrg case ARELEASE: 535876ff6feSmrg alt = FALSE; 536876ff6feSmrg XESimulateXEventRequest(tc,KeyRelease,alt_code,0,0,0); 537876ff6feSmrg break; 538876ff6feSmrg case SPRESS: 539876ff6feSmrg shift = TRUE; 540876ff6feSmrg XESimulateXEventRequest(tc,KeyPress,shift_code,0,0,0); 541876ff6feSmrg break; 542876ff6feSmrg case SRELEASE: 543876ff6feSmrg shift = FALSE; 544876ff6feSmrg XESimulateXEventRequest(tc,KeyRelease,shift_code, 545876ff6feSmrg 0,0,0); 546876ff6feSmrg break; 547876ff6feSmrg case CPRESS: 548876ff6feSmrg ctrl = TRUE; 549876ff6feSmrg XESimulateXEventRequest(tc,KeyPress,ctrl_code,0,0,0); 550876ff6feSmrg break; 551876ff6feSmrg case CRELEASE: 552876ff6feSmrg ctrl = FALSE; 553876ff6feSmrg XESimulateXEventRequest(tc,KeyRelease,ctrl_code,0,0,0); 554876ff6feSmrg break; 555876ff6feSmrg default: 556876ff6feSmrg fprintf(stderr, "\nInvalid Sequence!\n"); 557876ff6feSmrg dumpsequence(state, APC, private, param, nparam, 558876ff6feSmrg inter, ninter, final, &column); 559876ff6feSmrg } 560876ff6feSmrg } 561876ff6feSmrg break; 562876ff6feSmrg case MNOTIFY: 563876ff6feSmrg if (nparam != 3) 564876ff6feSmrg { /* Not my sequence */ 565876ff6feSmrg dumpsequence(state, APC, private, param, nparam, 566876ff6feSmrg inter, ninter, final, &column); 567876ff6feSmrg return; 568876ff6feSmrg } 569876ff6feSmrg else 570876ff6feSmrg { 571876ff6feSmrg int x, y; 572876ff6feSmrg 573876ff6feSmrg x = param[2]; 574876ff6feSmrg y = param[3]; 575876ff6feSmrg XESimulateXEventRequest(tc,MotionNotify,0,x,y,0); 576876ff6feSmrg if (verbose_flag) 577876ff6feSmrg { 578876ff6feSmrg _AdjustCol(strlen("<M %d,%d> ")+3); 579876ff6feSmrg printf("<M %d,%d> ",x,y); 580876ff6feSmrg } 581876ff6feSmrg } 582876ff6feSmrg break; 583876ff6feSmrg case RMNOTIFY: 584876ff6feSmrg if (nparam != 3) 585876ff6feSmrg { /* Not my sequence */ 586876ff6feSmrg dumpsequence(state, APC, private, param, nparam, 587876ff6feSmrg inter, ninter, final, &column); 588876ff6feSmrg return; 589876ff6feSmrg } 590876ff6feSmrg else 591876ff6feSmrg { 592876ff6feSmrg Window rid, wid; 593876ff6feSmrg int x, y, wx, wy; 594876ff6feSmrg unsigned int sm; 595876ff6feSmrg 596876ff6feSmrg if (XQueryPointer(tc->dpy,root,&rid,&wid,&x,&y,&wx,&wy,&sm) 597876ff6feSmrg == False) 598876ff6feSmrg { 599876ff6feSmrg fprintf(stderr, "\nPointer's not on screen 0!\n"); 600876ff6feSmrg } 601876ff6feSmrg else 602876ff6feSmrg { /* We're ready to go */ 603876ff6feSmrg x += param[2]; 604876ff6feSmrg y += param[3]; 605876ff6feSmrg XESimulateXEventRequest(tc,MotionNotify,0,x,y,0); 606876ff6feSmrg if (verbose_flag) 607876ff6feSmrg { 608876ff6feSmrg _AdjustCol(strlen("<RM ddd+sddd,dddd+sdddd> ")); 609876ff6feSmrg printf("<RM %d+%d,%d+%d> ",x-param[2],param[3], 610876ff6feSmrg y-param[3],param[3]); 611876ff6feSmrg } 612876ff6feSmrg } 613876ff6feSmrg break; 614876ff6feSmrg default: 615876ff6feSmrg dumpsequence(state, APC, private, param, nparam, 616876ff6feSmrg inter, ninter, final, &column); 617876ff6feSmrg break; 618876ff6feSmrg } 619876ff6feSmrg } 620876ff6feSmrg} 621876ff6feSmrg 622876ff6feSmrgstatic int get_ss3_key(tc, private, param, nparam, inter, ninter, final) 623876ff6feSmrg XETC *tc; 624876ff6feSmrg int private; 625876ff6feSmrg int param[], nparam; 626876ff6feSmrg int inter[], ninter; 627876ff6feSmrg int final; 628876ff6feSmrg{ 629876ff6feSmrg KeySym keysym = 0; 630876ff6feSmrg switch(param[1]) 631876ff6feSmrg { 632876ff6feSmrg case 0: 633876ff6feSmrg switch ((char )final) 634876ff6feSmrg { 635876ff6feSmrg case 'A': keysym = XK_Up; break; 636876ff6feSmrg case 'B': keysym = XK_Down; break; 637876ff6feSmrg case 'C': keysym = XK_Right; break; 638876ff6feSmrg case 'D': keysym = XK_Left; break; 639876ff6feSmrg case 'p': keysym = XK_KP_0; break; 640876ff6feSmrg case 'q': keysym = XK_KP_1; break; 641876ff6feSmrg case 'r': keysym = XK_KP_2; break; 642876ff6feSmrg case 's': keysym = XK_KP_3; break; 643876ff6feSmrg case 't': keysym = XK_KP_4; break; 644876ff6feSmrg case 'u': keysym = XK_KP_5; break; 645876ff6feSmrg case 'v': keysym = XK_KP_6; break; 646876ff6feSmrg case 'w': keysym = XK_KP_7; break; 647876ff6feSmrg case 'x': keysym = XK_KP_8; break; 648876ff6feSmrg case 'y': keysym = XK_KP_9; break; 649876ff6feSmrg case 'm': keysym = XK_KP_Subtract; break; 650876ff6feSmrg case 'l': keysym = XK_KP_Separator; break; 651876ff6feSmrg case 'n': keysym = XK_KP_Decimal; break; 652876ff6feSmrg case 'M': keysym = XK_KP_Enter; break; 653876ff6feSmrg case 'P': keysym = XK_KP_F1; break; 654876ff6feSmrg case 'Q': keysym = XK_KP_F2; break; 655876ff6feSmrg case 'R': keysym = XK_KP_F3; break; 656876ff6feSmrg case 'S': keysym = XK_KP_F4; break; 657876ff6feSmrg default: 658876ff6feSmrg dumpsequence(state, SS3, private, param, nparam, 659876ff6feSmrg inter, ninter, final, &column); 660876ff6feSmrg break; 661876ff6feSmrg } 662876ff6feSmrg break; 663876ff6feSmrg } 664876ff6feSmrg 665876ff6feSmrg return(get_keycode(tc, keysym)); 666876ff6feSmrg} 667876ff6feSmrg 668876ff6feSmrgstatic KeyCode get_typical_char(tc, keysym) 669876ff6feSmrg XETC *tc; 670876ff6feSmrg CARD32 keysym; 671876ff6feSmrg{ 672876ff6feSmrg if (iscntrl(keysym)) 673876ff6feSmrg { 674876ff6feSmrg switch(keysym) 675876ff6feSmrg { 676876ff6feSmrg case 0x09: keysym = XK_Tab; break; 677876ff6feSmrg case 0x0d: keysym = XK_Return; break; 678876ff6feSmrg case 0x7f: keysym = XK_Delete; break; 679876ff6feSmrg case ESC: keysym = XK_Escape; break; 680876ff6feSmrg } 681876ff6feSmrg } 682876ff6feSmrg passive_shift = (keysym >= XK_A && keysym <= XK_Z) ? TRUE : FALSE; 683876ff6feSmrg switch(keysym) 684876ff6feSmrg { /* Special case shift's */ 685876ff6feSmrg case '!': case '"': case '@': case '#': case '$': 686876ff6feSmrg case '%': case '^': case '&': case '*': case '(': 687876ff6feSmrg case ')': case '_': case '+': case '{': case '}': 688876ff6feSmrg case '|': case ':': case '>': case '?': case '~': 689876ff6feSmrg passive_shift = TRUE; 690876ff6feSmrg } 691876ff6feSmrg 692876ff6feSmrg if (keysym >= 1 && keysym <= 26) 693876ff6feSmrg { 694876ff6feSmrg passive_ctrl = TRUE; 695876ff6feSmrg keysym += 'a' - 1; 696876ff6feSmrg } 697876ff6feSmrg else 698876ff6feSmrg { 699876ff6feSmrg passive_ctrl = FALSE; 700876ff6feSmrg } 701876ff6feSmrg 702876ff6feSmrg return(get_keycode(tc, keysym)); 703876ff6feSmrg} 704876ff6feSmrg 705876ff6feSmrgstatic KeyCode get_keycode(XETC *tc, KeySym keysym) 706876ff6feSmrg{ 707876ff6feSmrg char *keystr = (char *)XKeysymToString(keysym); 708876ff6feSmrg KeyCode keycode; 709876ff6feSmrg 710876ff6feSmrg keystr = (keystr == NULL) ? "unknown" : keystr; 711876ff6feSmrg if (verbose_flag) 712876ff6feSmrg { 713876ff6feSmrg if (shift || passive_shift) 714876ff6feSmrg { 715876ff6feSmrg _AdjustCol(strlen("<SHIFT>")); 716876ff6feSmrg printf("<SHIFT>"); 717876ff6feSmrg } 718876ff6feSmrg if (alt) 719876ff6feSmrg { 720876ff6feSmrg _AdjustCol(strlen("<ALT>")); 721876ff6feSmrg printf("<ALT>"); 722876ff6feSmrg } 723876ff6feSmrg if (ctrl || passive_ctrl) 724876ff6feSmrg { 725876ff6feSmrg _AdjustCol(strlen("<CTRL>")); 726876ff6feSmrg printf("<CTRL>"); 727876ff6feSmrg } 728876ff6feSmrg _AdjustCol(strlen(keystr)+1); 729876ff6feSmrg printf("%s ", keystr); 730876ff6feSmrg } 731876ff6feSmrg if (!(keycode = XKeysymToKeycode(tc->dpy,keysym))) 732876ff6feSmrg { 733876ff6feSmrg fprintf(stderr,"\n[%s ('%%0x%04x') returns bad Keycode, ignored]\n", 734876ff6feSmrg keystr, (unsigned int)keysym); 735876ff6feSmrg column = 0; 736876ff6feSmrg } 737876ff6feSmrg 738876ff6feSmrg return(keycode); 739876ff6feSmrg} 740