xtrapin.c revision 99435119
1/* $XFree86: xc/programs/xtrap/xtrapin.c,v 1.2tsi Exp $ */
2/*
3 * @DEC_COPYRIGHT@
4 */
5/*
6 * HISTORY
7 * Log: xtrapin.c,v $
8 * Revision 1.1.4.2  1993/12/14  12:37:20  Kenneth_Miller
9 * 	ANSI-standardize code and turn client build on
10 * 	[1993/12/09  20:15:45  Kenneth_Miller]
11 *
12 * Revision 1.1.2.2  1992/04/27  13:51:39  Leela_Obilichetti
13 * 	Initial load of xtrap clients - from silver BL6
14 * 	[92/04/27  13:49:16  Leela_Obilichetti]
15 *
16 * EndLog$
17 */
18/*****************************************************************************
19Copyright 1987, 1988, 1989, 1990, 1991 by Digital Equipment Corp., Maynard, MA
20
21Permission to use, copy, modify, and distribute this software and its
22documentation for any purpose and without fee is hereby granted,
23provided that the above copyright notice appear in all copies and that
24both that copyright notice and this permission notice appear in
25supporting documentation, and that the name of Digital not be
26used in advertising or publicity pertaining to distribution of the
27software without specific, written prior permission.
28
29DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
30ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
31DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
32ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
33WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
34ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
35SOFTWARE.
36
37*****************************************************************************/
38/*
39 *
40 *  CONTRIBUTORS:
41 *
42 *      Dick Annicchiarico
43 *      Robert Chesler
44 *      Dan Coutu
45 *      Gene Durso
46 *      Marc Evans
47 *      Alan Jamison
48 *      Mark Henry
49 *      Ken Miller
50 *
51 */
52#define ProgName "xtrapin"
53/*
54**++
55**  FACILITY:  xtrapin - Sample client to test input to XTrap extension
56**
57**  MODULE DESCRIPTION:
58**
59**      This is the main module for a sample/test client
60**      for the XTrap X11 Server Extension.  It accepts
61**      a script file and a transport method as input
62**      in addition to the standard X arguments (-d, etc.).
63**      If no script file is provided, stdin is the default
64**      and can be piped from the companion "xtrapout"
65**      client (normally used with the -e argument which
66**      sends all core input events to stdout).
67**
68**
69**  AUTHORS:
70**
71**      Kenneth B. Miller
72**
73**  CREATION DATE:  December 15, 1990
74**
75**  DESIGN ISSUES:
76**
77**      See the companion "xtrapout" client.
78**
79**      Also, getopt() is used to parse the command
80**      line arguments prior to calling XtAppInitialize().
81**      This is because DECwindows appears to remove the user-
82**      defined arguments from the argv[] vector without actually
83**      acting upon them.
84**
85**
86**--
87*/
88#include <stdio.h>
89#include <X11/extensions/xtraplib.h>
90#include <X11/extensions/xtraplibp.h>
91#include <unistd.h>
92#include <stdlib.h>
93
94#ifndef vaxc
95#define globalref extern
96#endif
97#ifdef Lynx
98extern char *optarg;
99extern int optind;
100extern int opterr;
101#endif
102
103static Boolean grabFlag = False;
104
105static FILE *ifp;
106static XrmOptionDescRec optionTable [] =
107{
108    {"-f",     "*script",    XrmoptionSepArg,  (caddr_t) NULL},
109    {"-g",     "*grabServer",XrmoptionSkipArg, (caddr_t) NULL},
110};
111
112typedef struct
113{   /* longword-align fields for arg passing */
114    Time  ts;
115    int   type;
116    int   detail;
117    int   x;
118    int   y;
119    int  screen; /* this will always be 0 till vectored events! */
120} file_rec;
121
122/* Forward declarations */
123static Bool found_input_rec (FILE *ifp , file_rec *rec );
124
125static Widget appW;
126static Display *dpy;
127
128
129int
130main(int argc, char *argv[])
131{
132    XETrapGetAvailRep ret_avail;
133    XETrapGetCurRep   ret_cur;
134    XETC    *tc;
135    XtAppContext app;
136    char *tmp = NULL;
137    INT16 ch;
138    file_rec rec;
139    Time last_time = 0L;
140    int *popterr;
141    char **poptarg;
142#ifndef vms
143    popterr = &opterr;
144    poptarg = &optarg;
145#else
146    popterr = XEgetopterr();
147    poptarg = XEgetoptarg();
148#endif
149
150    ifp = NULL;
151    *popterr = 0; /* don't complain about -d for display */
152    grabFlag = False;
153    while ((ch = getopt(argc, argv, "d:f:g")) != EOF)
154    {
155        switch(ch)
156        {
157            case 'f':
158                if ((ifp = fopen(*poptarg,"rb")) == NULL)
159                {   /* can't open it */
160                    fprintf(stderr,"%s: could not open output file '%s'!\n",
161                        ProgName, *poptarg);
162                }
163                break;
164            case 'd':   /* -display, let's let the toolkit parse it */
165                break;
166            case 'g':
167                grabFlag = True;
168            default:
169                break;
170        }
171    }
172    ifp = (ifp ? ifp : stdin);
173
174    appW = XtAppInitialize(&app,"XTrap",optionTable,(Cardinal)1L,
175        (int *)&argc, (String *)argv, (String *)NULL,(ArgList)&tmp,
176        0);
177
178    dpy = XtDisplay(appW);
179#ifdef DEBUG
180    XSynchronize(dpy, True);
181#endif
182    printf("Display:  %s \n", DisplayString(dpy));
183
184    if ((tc = XECreateTC(dpy,0L, NULL)) == NULL)
185    {
186        fprintf(stderr,"%s: could not initialize XTrap extension\n", ProgName);
187        exit (1L);
188    }
189    (void)XEGetAvailableRequest(tc,&ret_avail);
190    XEPrintAvail(stderr,&ret_avail);
191    XEPrintTkFlags(stderr,tc);
192
193    if (grabFlag == True)
194    {   /*
195         * In order to ignore GrabServer's we must configure at least one
196         * trap.  Let's make it X_GrabServer.  We don't have to receive
197         * a callback, though.
198         */
199        ReqFlags requests;
200        (void)memset(requests,0L,sizeof(requests));
201        BitTrue(requests, X_GrabServer);
202        XETrapSetRequests(tc, True, requests);
203        (void)XETrapSetGrabServer(tc, True);
204    }
205
206    (void)XEStartTrapRequest(tc);
207    (void)XEGetCurrentRequest(tc,&ret_cur);
208    XEPrintCurrent(stderr,&ret_cur);
209
210    /* Open up script file */
211    while (found_input_rec(ifp,&rec) == True)
212    {
213        /* if not pipe'd, delay time delta time recorded */
214        if (ifp != stdin)
215        {
216            register INT32 delta, t1, t2;
217            last_time = (last_time ? last_time : rec.ts);      /* first rec */
218            rec.ts = (rec.ts ? rec.ts : last_time);    /* dual monitor bug! */
219            t1 = rec.ts; t2 = last_time;        /* move to signed variables */
220            delta = abs(t1 - t2);           /* protect from clock roll-over */
221            msleep(delta);
222            last_time = rec.ts;
223        }
224        XESimulateXEventRequest(tc, rec.type, rec.detail, rec.x, rec.y,
225            rec.screen);
226    }
227
228    (void)XCloseDisplay(dpy);
229    exit(0L);
230}
231
232static Bool found_input_rec(FILE *ifp, file_rec *rec)
233{
234    int found = False;
235    char buff[BUFSIZ];
236    char junk[16L];
237    int  tmp[8L];
238
239    while ((found != True) && (fgets(buff,BUFSIZ,ifp) != NULL))
240    {
241        if (!strncmp(buff, "Event:", strlen("Event:")))
242        {   /* we want this record */
243            if (sscanf(buff,
244             "Event: %s (%d):det=%d scr=%d (%d,%d) root=%d Msk=%d TS=%d\n",
245                junk, &(tmp[0L]), &(tmp[1L]), &(tmp[2L]), &(tmp[3L]),
246                &(tmp[4L]), &(tmp[5L]), &(tmp[6L]), &(tmp[7L])) != 9L)
247            {
248                fprintf(stderr, "%s:  Error parsing script input!\n\t'%s'\n",
249                    ProgName, buff);
250            }
251            else
252            {
253                found = True;
254                /* Sun's have problems with "byte" fields passed to scanf */
255                rec->type   = tmp[0L];
256                rec->detail = tmp[1L];
257                rec->screen = tmp[2L];
258                rec->x      = tmp[3L];
259                rec->y      = tmp[4L];
260                rec->ts     = tmp[7L];
261            }
262        }
263        else if (!strncmp(buff, "Request:", strlen("Request:")))
264        {   /* a valid thing to see */
265            continue;
266        }
267        else
268        {   /* this stuff doesn't look like what we'd expect */
269            fprintf(stderr, "%s:  Not a valid script record!\n\t'%s'\n",
270                ProgName, buff);
271        }
272    }
273
274    return(found);
275}
276
277