1876ff6feSmrg/* $XFree86: xc/programs/xtrap/xtrapin.c,v 1.2tsi Exp $ */
2876ff6feSmrg/*
3876ff6feSmrg * @DEC_COPYRIGHT@
4876ff6feSmrg */
5876ff6feSmrg/*
6876ff6feSmrg * HISTORY
7876ff6feSmrg * Log: xtrapin.c,v $
8876ff6feSmrg * Revision 1.1.4.2  1993/12/14  12:37:20  Kenneth_Miller
9876ff6feSmrg * 	ANSI-standardize code and turn client build on
10876ff6feSmrg * 	[1993/12/09  20:15:45  Kenneth_Miller]
11876ff6feSmrg *
12876ff6feSmrg * Revision 1.1.2.2  1992/04/27  13:51:39  Leela_Obilichetti
13876ff6feSmrg * 	Initial load of xtrap clients - from silver BL6
14876ff6feSmrg * 	[92/04/27  13:49:16  Leela_Obilichetti]
15876ff6feSmrg *
16876ff6feSmrg * EndLog$
17876ff6feSmrg */
18876ff6feSmrg/*****************************************************************************
19876ff6feSmrgCopyright 1987, 1988, 1989, 1990, 1991 by Digital Equipment Corp., Maynard, 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/*
39876ff6feSmrg *
40876ff6feSmrg *  CONTRIBUTORS:
41876ff6feSmrg *
42876ff6feSmrg *      Dick Annicchiarico
43876ff6feSmrg *      Robert Chesler
44876ff6feSmrg *      Dan Coutu
45876ff6feSmrg *      Gene Durso
46876ff6feSmrg *      Marc Evans
47876ff6feSmrg *      Alan Jamison
48876ff6feSmrg *      Mark Henry
49876ff6feSmrg *      Ken Miller
50876ff6feSmrg *
51876ff6feSmrg */
52876ff6feSmrg#define ProgName "xtrapin"
53876ff6feSmrg/*
54876ff6feSmrg**++
55876ff6feSmrg**  FACILITY:  xtrapin - Sample client to test input to XTrap extension
56876ff6feSmrg**
57876ff6feSmrg**  MODULE DESCRIPTION:
58876ff6feSmrg**
59876ff6feSmrg**      This is the main module for a sample/test client
60876ff6feSmrg**      for the XTrap X11 Server Extension.  It accepts
61876ff6feSmrg**      a script file and a transport method as input
62876ff6feSmrg**      in addition to the standard X arguments (-d, etc.).
63876ff6feSmrg**      If no script file is provided, stdin is the default
64876ff6feSmrg**      and can be piped from the companion "xtrapout"
65876ff6feSmrg**      client (normally used with the -e argument which
66876ff6feSmrg**      sends all core input events to stdout).
67876ff6feSmrg**
68876ff6feSmrg**
69876ff6feSmrg**  AUTHORS:
70876ff6feSmrg**
71876ff6feSmrg**      Kenneth B. Miller
72876ff6feSmrg**
73876ff6feSmrg**  CREATION DATE:  December 15, 1990
74876ff6feSmrg**
75876ff6feSmrg**  DESIGN ISSUES:
76876ff6feSmrg**
77876ff6feSmrg**      See the companion "xtrapout" client.
78876ff6feSmrg**
79876ff6feSmrg**      Also, getopt() is used to parse the command
80876ff6feSmrg**      line arguments prior to calling XtAppInitialize().
81876ff6feSmrg**      This is because DECwindows appears to remove the user-
82876ff6feSmrg**      defined arguments from the argv[] vector without actually
83876ff6feSmrg**      acting upon them.
84876ff6feSmrg**
85876ff6feSmrg**
86876ff6feSmrg**--
87876ff6feSmrg*/
88876ff6feSmrg#include <stdio.h>
89876ff6feSmrg#include <X11/extensions/xtraplib.h>
90876ff6feSmrg#include <X11/extensions/xtraplibp.h>
91876ff6feSmrg#include <unistd.h>
92876ff6feSmrg#include <stdlib.h>
93876ff6feSmrg
94876ff6feSmrg#ifndef vaxc
95876ff6feSmrg#define globalref extern
96876ff6feSmrg#endif
97876ff6feSmrg#ifdef Lynx
98876ff6feSmrgextern char *optarg;
99876ff6feSmrgextern int optind;
100876ff6feSmrgextern int opterr;
101876ff6feSmrg#endif
102876ff6feSmrg
103876ff6feSmrgstatic Boolean grabFlag = False;
104876ff6feSmrg
10599435119Smrgstatic FILE *ifp;
10699435119Smrgstatic XrmOptionDescRec optionTable [] =
107876ff6feSmrg{
108876ff6feSmrg    {"-f",     "*script",    XrmoptionSepArg,  (caddr_t) NULL},
109876ff6feSmrg    {"-g",     "*grabServer",XrmoptionSkipArg, (caddr_t) NULL},
110876ff6feSmrg};
111876ff6feSmrg
112876ff6feSmrgtypedef struct
113876ff6feSmrg{   /* longword-align fields for arg passing */
114876ff6feSmrg    Time  ts;
115876ff6feSmrg    int   type;
116876ff6feSmrg    int   detail;
117876ff6feSmrg    int   x;
118876ff6feSmrg    int   y;
119876ff6feSmrg    int  screen; /* this will always be 0 till vectored events! */
120876ff6feSmrg} file_rec;
121876ff6feSmrg
122876ff6feSmrg/* Forward declarations */
123876ff6feSmrgstatic Bool found_input_rec (FILE *ifp , file_rec *rec );
124876ff6feSmrg
125876ff6feSmrgstatic Widget appW;
126876ff6feSmrgstatic Display *dpy;
127876ff6feSmrg
128876ff6feSmrg
129876ff6feSmrgint
130876ff6feSmrgmain(int argc, char *argv[])
131876ff6feSmrg{
132876ff6feSmrg    XETrapGetAvailRep ret_avail;
133876ff6feSmrg    XETrapGetCurRep   ret_cur;
134876ff6feSmrg    XETC    *tc;
135876ff6feSmrg    XtAppContext app;
136876ff6feSmrg    char *tmp = NULL;
137876ff6feSmrg    INT16 ch;
138876ff6feSmrg    file_rec rec;
139876ff6feSmrg    Time last_time = 0L;
140876ff6feSmrg    int *popterr;
141876ff6feSmrg    char **poptarg;
142876ff6feSmrg#ifndef vms
143876ff6feSmrg    popterr = &opterr;
144876ff6feSmrg    poptarg = &optarg;
145876ff6feSmrg#else
146876ff6feSmrg    popterr = XEgetopterr();
147876ff6feSmrg    poptarg = XEgetoptarg();
148876ff6feSmrg#endif
149876ff6feSmrg
150876ff6feSmrg    ifp = NULL;
151876ff6feSmrg    *popterr = 0; /* don't complain about -d for display */
152876ff6feSmrg    grabFlag = False;
153876ff6feSmrg    while ((ch = getopt(argc, argv, "d:f:g")) != EOF)
154876ff6feSmrg    {
155876ff6feSmrg        switch(ch)
156876ff6feSmrg        {
157876ff6feSmrg            case 'f':
158876ff6feSmrg                if ((ifp = fopen(*poptarg,"rb")) == NULL)
159876ff6feSmrg                {   /* can't open it */
160876ff6feSmrg                    fprintf(stderr,"%s: could not open output file '%s'!\n",
161876ff6feSmrg                        ProgName, *poptarg);
162876ff6feSmrg                }
163876ff6feSmrg                break;
164876ff6feSmrg            case 'd':   /* -display, let's let the toolkit parse it */
165876ff6feSmrg                break;
166876ff6feSmrg            case 'g':
167876ff6feSmrg                grabFlag = True;
168876ff6feSmrg            default:
169876ff6feSmrg                break;
170876ff6feSmrg        }
171876ff6feSmrg    }
172876ff6feSmrg    ifp = (ifp ? ifp : stdin);
173876ff6feSmrg
174876ff6feSmrg    appW = XtAppInitialize(&app,"XTrap",optionTable,(Cardinal)1L,
175876ff6feSmrg        (int *)&argc, (String *)argv, (String *)NULL,(ArgList)&tmp,
17699435119Smrg        0);
177876ff6feSmrg
178876ff6feSmrg    dpy = XtDisplay(appW);
179876ff6feSmrg#ifdef DEBUG
180876ff6feSmrg    XSynchronize(dpy, True);
181876ff6feSmrg#endif
182876ff6feSmrg    printf("Display:  %s \n", DisplayString(dpy));
183876ff6feSmrg
18499435119Smrg    if ((tc = XECreateTC(dpy,0L, NULL)) == NULL)
185876ff6feSmrg    {
186876ff6feSmrg        fprintf(stderr,"%s: could not initialize XTrap extension\n", ProgName);
187876ff6feSmrg        exit (1L);
188876ff6feSmrg    }
189876ff6feSmrg    (void)XEGetAvailableRequest(tc,&ret_avail);
190876ff6feSmrg    XEPrintAvail(stderr,&ret_avail);
191876ff6feSmrg    XEPrintTkFlags(stderr,tc);
192876ff6feSmrg
193876ff6feSmrg    if (grabFlag == True)
194876ff6feSmrg    {   /*
195876ff6feSmrg         * In order to ignore GrabServer's we must configure at least one
196876ff6feSmrg         * trap.  Let's make it X_GrabServer.  We don't have to receive
197876ff6feSmrg         * a callback, though.
198876ff6feSmrg         */
199876ff6feSmrg        ReqFlags requests;
200876ff6feSmrg        (void)memset(requests,0L,sizeof(requests));
201876ff6feSmrg        BitTrue(requests, X_GrabServer);
202876ff6feSmrg        XETrapSetRequests(tc, True, requests);
203876ff6feSmrg        (void)XETrapSetGrabServer(tc, True);
204876ff6feSmrg    }
205876ff6feSmrg
206876ff6feSmrg    (void)XEStartTrapRequest(tc);
207876ff6feSmrg    (void)XEGetCurrentRequest(tc,&ret_cur);
208876ff6feSmrg    XEPrintCurrent(stderr,&ret_cur);
209876ff6feSmrg
210876ff6feSmrg    /* Open up script file */
211876ff6feSmrg    while (found_input_rec(ifp,&rec) == True)
212876ff6feSmrg    {
213876ff6feSmrg        /* if not pipe'd, delay time delta time recorded */
214876ff6feSmrg        if (ifp != stdin)
215876ff6feSmrg        {
216876ff6feSmrg            register INT32 delta, t1, t2;
217876ff6feSmrg            last_time = (last_time ? last_time : rec.ts);      /* first rec */
218876ff6feSmrg            rec.ts = (rec.ts ? rec.ts : last_time);    /* dual monitor bug! */
219876ff6feSmrg            t1 = rec.ts; t2 = last_time;        /* move to signed variables */
220876ff6feSmrg            delta = abs(t1 - t2);           /* protect from clock roll-over */
221876ff6feSmrg            msleep(delta);
222876ff6feSmrg            last_time = rec.ts;
223876ff6feSmrg        }
224876ff6feSmrg        XESimulateXEventRequest(tc, rec.type, rec.detail, rec.x, rec.y,
225876ff6feSmrg            rec.screen);
226876ff6feSmrg    }
227876ff6feSmrg
228876ff6feSmrg    (void)XCloseDisplay(dpy);
229876ff6feSmrg    exit(0L);
230876ff6feSmrg}
231876ff6feSmrg
232876ff6feSmrgstatic Bool found_input_rec(FILE *ifp, file_rec *rec)
233876ff6feSmrg{
234876ff6feSmrg    int found = False;
235876ff6feSmrg    char buff[BUFSIZ];
236876ff6feSmrg    char junk[16L];
237876ff6feSmrg    int  tmp[8L];
238876ff6feSmrg
239876ff6feSmrg    while ((found != True) && (fgets(buff,BUFSIZ,ifp) != NULL))
240876ff6feSmrg    {
241876ff6feSmrg        if (!strncmp(buff, "Event:", strlen("Event:")))
242876ff6feSmrg        {   /* we want this record */
243876ff6feSmrg            if (sscanf(buff,
244876ff6feSmrg             "Event: %s (%d):det=%d scr=%d (%d,%d) root=%d Msk=%d TS=%d\n",
245876ff6feSmrg                junk, &(tmp[0L]), &(tmp[1L]), &(tmp[2L]), &(tmp[3L]),
246876ff6feSmrg                &(tmp[4L]), &(tmp[5L]), &(tmp[6L]), &(tmp[7L])) != 9L)
247876ff6feSmrg            {
248876ff6feSmrg                fprintf(stderr, "%s:  Error parsing script input!\n\t'%s'\n",
249876ff6feSmrg                    ProgName, buff);
250876ff6feSmrg            }
251876ff6feSmrg            else
252876ff6feSmrg            {
253876ff6feSmrg                found = True;
254876ff6feSmrg                /* Sun's have problems with "byte" fields passed to scanf */
255876ff6feSmrg                rec->type   = tmp[0L];
256876ff6feSmrg                rec->detail = tmp[1L];
257876ff6feSmrg                rec->screen = tmp[2L];
258876ff6feSmrg                rec->x      = tmp[3L];
259876ff6feSmrg                rec->y      = tmp[4L];
260876ff6feSmrg                rec->ts     = tmp[7L];
261876ff6feSmrg            }
262876ff6feSmrg        }
263876ff6feSmrg        else if (!strncmp(buff, "Request:", strlen("Request:")))
264876ff6feSmrg        {   /* a valid thing to see */
265876ff6feSmrg            continue;
266876ff6feSmrg        }
267876ff6feSmrg        else
268876ff6feSmrg        {   /* this stuff doesn't look like what we'd expect */
269876ff6feSmrg            fprintf(stderr, "%s:  Not a valid script record!\n\t'%s'\n",
270876ff6feSmrg                ProgName, buff);
271876ff6feSmrg        }
272876ff6feSmrg    }
273876ff6feSmrg
274876ff6feSmrg    return(found);
275876ff6feSmrg}
276876ff6feSmrg
277