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