xtrapout.c revision 47cb5690
1/* $XFree86: xc/programs/xtrap/xtrapout.c,v 1.1 2001/11/02 23:29:34 dawes Exp $ */
2/*
3 * @DEC_COPYRIGHT@
4 */
5/*
6 * HISTORY
7 * Log: xtrapout.c,v $
8 * Revision 1.1.4.2  1993/12/14  12:37:28  Kenneth_Miller
9 * 	ANSI-standardize code and turn client build on
10 * 	[1993/12/09  20:16:01  Kenneth_Miller]
11 *
12 * Revision 1.1.2.2  1992/04/27  13:51:57  Leela_Obilichetti
13 * 	initial load of xtrap clients - from silver BL6 pool
14 * 	[92/04/27  13:49:33  Leela_Obilichetti]
15 *
16 * EndLog$
17 */
18/*****************************************************************************
19Copyright 1987, 1988, 1989, 1990, 1991, 1993 by Digital Equipment Corp.,
20Maynard, MA
21
22Permission to use, copy, modify, and distribute this software and its
23documentation for any purpose and without fee is hereby granted,
24provided that the above copyright notice appear in all copies and that
25both that copyright notice and this permission notice appear in
26supporting documentation, and that the name of Digital not be
27used in advertising or publicity pertaining to distribution of the
28software without specific, written prior permission.
29
30DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
31ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
32DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
33ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
34WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
35ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
36SOFTWARE.
37
38*****************************************************************************/
39/*
40 *
41 *  CONTRIBUTORS:
42 *
43 *      Dick Annicchiarico
44 *      Robert Chesler
45 *      Dan Coutu
46 *      Gene Durso
47 *      Marc Evans
48 *      Alan Jamison
49 *      Mark Henry
50 *      Ken Miller
51 *
52 */
53#define ProgName "xtrapout"
54/*
55**++
56**  FACILITY:  xtrapout - Sample client to test output from XTrap extension
57**
58**  MODULE DESCRIPTION:
59**
60**      This is the main module for a sample/test client
61**      for the XTrap X11 Server Extension.  It accepts
62**      a script output file, a transport method,
63**      and an "events mode" flag (-e) as input,
64**      in addition to the standard X arguments (-d, etc.).
65**      If no script file is provided, stdout is the default
66**      and can be piped to the companion "xtrapin"
67**      client (normally used with the -e argument which
68**      sends all core input events to stdout).
69**
70**
71**  AUTHORS:
72**
73**      Kenneth B. Miller
74**
75**  CREATION DATE:  March 28, 1990
76**
77**  DESIGN ISSUES:
78**
79**      See the companion "xtrapin" client.
80**
81**      Also, getopt() is used to parse the command
82**      line arguments prior to calling XtAppInitialize().
83**      This is because DECwindows appears to remove the user-
84**      defined arguments from the argv[] vector without actually
85**      acting upon them.
86**
87**
88**--
89*/
90
91#include <inttypes.h>
92#include <stdio.h>
93#include <X11/extensions/xtraplib.h>
94#include <X11/extensions/xtraplibp.h>
95#include <signal.h>
96#include <X11/keysym.h>
97#include <unistd.h>
98#include <stdlib.h>
99
100#include "XEKeybCtrl.h"
101
102#ifndef vaxc
103#define globalref extern
104#endif
105#ifdef Lynx
106extern char *optarg;
107extern int optind;
108extern int opterr;
109#endif
110
111
112/* Forward declarations */
113static void SetGlobalDone (void );
114static void print_req_callback (XETC *tc , XETrapDatum *data ,
115    char *my_buf );
116static void print_evt_callback (XETC *tc , XETrapDatum *data ,
117    char *my_buf );
118
119
120FILE *ofp;
121Bool GlobalDone = False;
122XrmOptionDescRec optionTable [] =
123{
124    {"-f",     "*script",    XrmoptionSepArg,  (caddr_t) NULL},
125    {"-e",     "*eventFlag", XrmoptionSkipArg, (caddr_t) NULL},
126    {"-v",     "*verbose",   XrmoptionSkipArg, (caddr_t) NULL},
127};
128
129static void SetGlobalDone(void)
130{
131    GlobalDone = 1L;
132    fprintf(stderr,"Process Completed!\n");
133    return;
134}
135
136static void print_req_callback(XETC *tc, XETrapDatum *data, char *my_buf)
137{
138    char *req_type;
139    req_type = (data->u.req.reqType == XETrapGetExtOpcode(tc) ? "XTrap" :
140        XERequestIDToString(data->u.req.reqType,tc));
141    fprintf(ofp,"Request: %-19s (%d): length '%ld' client '%d' window=%ld\n",
142        req_type, data->u.req.reqType, (long)data->hdr.count, data->hdr.client,
143        (long)data->u.req.id);
144}
145
146static void print_evt_callback(XETC *tc, XETrapDatum *data, char *my_buf)
147{
148    static Time last_time = 0;
149    int delta;
150
151    delta = imaxabs((int)last_time ? (intmax_t)data->u.event.u.keyButtonPointer.time -
152        (int)last_time  : (int)last_time);
153    last_time = data->u.event.u.keyButtonPointer.time;
154
155    /* The "screen" and "root" fields aren't valid until "event"
156     * vectoring becomes a reality.  Currently, XTrap intercepts
157     * the core events prior to when fields other than rootX, rootY,
158     * type, detail, time, and state are filled in.  This will be
159     * addressed in the next release of XTrap (3.2?).
160     */
161    fprintf(ofp,
162        "Event: %-15s (%d):det=%d scr=%d (%d,%d) root=%d Msk=%d TS=%d\n",
163        XEEventIDToString(data->u.event.u.u.type,tc), data->u.event.u.u.type,
164        data->u.event.u.u.detail, data->hdr.screen, /* Not really valid yet */
165        data->u.event.u.keyButtonPointer.rootX,
166        data->u.event.u.keyButtonPointer.rootY,
167        (int)data->u.event.u.keyButtonPointer.root, /* Not really valid yet */
168        (int)data->u.event.u.keyButtonPointer.state,
169        (int)delta);
170    fflush(ofp);
171}
172static Boolean eventFlag = False;
173static Boolean verboseFlag = False;
174static Widget appW;
175static Display *dpy;
176
177int
178main(int argc, char *argv[])
179{
180    XETrapGetAvailRep ret_avail;
181    XETrapGetCurRep   ret_cur;
182    XETC    *tc;
183    ReqFlags     requests;
184    EventFlags   events;
185    XtAppContext app;
186    char *tmp = NULL;
187    INT16 ch;
188    int *popterr;
189    char **poptarg;
190#ifndef vms
191    popterr = &opterr;
192    poptarg = &optarg;
193#else
194    popterr = XEgetopterr();
195    poptarg = XEgetoptarg();
196#endif
197
198    eventFlag = False;
199    ofp = NULL;
200    *popterr = 0; /* don't complain about -d (display) */
201    while ((ch = getopt(argc, argv, "d:evf:")) != EOF)
202    {
203        switch(ch)
204        {
205            case 'e':
206                eventFlag = True;
207                break;
208            case 'v':
209                verboseFlag = True;
210                break;
211            case 'f':
212                if ((ofp = fopen(*poptarg,"wb")) == NULL)
213                {   /* can't open it */
214                    fprintf(stderr,"%s: could not open output file '%s'!\n",
215                        ProgName, *poptarg);
216                }
217                break;
218            case 'd':   /* -display, let's let the toolkit parse it */
219                break;
220            default:
221                break;
222        }
223    }
224    ofp = (ofp ? ofp : stdout);
225
226    appW = XtAppInitialize(&app,"XTrap",optionTable,(Cardinal)2L,
227        (int *)&argc, (String *)argv, (String *)NULL,(ArgList)&tmp,
228        (Cardinal)0);
229
230    dpy = XtDisplay(appW);
231#ifdef DEBUG
232    XSynchronize(dpy, True);
233#endif
234    fprintf(stderr,"Display:  %s \n", DisplayString(dpy));
235    if ((tc = XECreateTC(dpy,0L, NULL)) == False)
236    {
237        fprintf(stderr,"%s: could not initialize XTrap extension\n",ProgName);
238        exit (1L);
239    }
240    XETrapSetTimestamps(tc,True, False);
241    (void)XEGetAvailableRequest(tc,&ret_avail);
242    XEPrintAvail(stderr,&ret_avail);
243    XEPrintTkFlags(stderr,tc);
244
245    /* Need to prime events/requests initially turning all off  */
246    (void)memset(requests,0L,sizeof(requests));
247    (void)memset(events,0L,sizeof(events));
248    /* Now turn on the ones you really want */
249    (void)memset(events,0xFFL,XETrapMaxEvent);
250    if (eventFlag == False)
251    {   /* doesn't want just events */
252        (void)memset(requests,0xFFL,XETrapMaxRequest);
253        /* Turn off XTrap Requests for multi-client regression tests & XLib */
254        BitFalse(requests, XETrapGetExtOpcode(tc));
255        /* Turn off noisy events */
256        BitFalse(events, MotionNotify);
257    }
258    if (verboseFlag == True)
259    {   /* want's *all* requests/events */
260        (void)memset(requests,0xFFL,XETrapMaxRequest);
261        (void)memset(events,0xFFL,XETrapMaxEvent);
262    }
263    /* Tell the TC about it */
264    XETrapSetRequests(tc, True, requests);
265    XETrapSetEvents(tc, True, events);
266    XETrapSetMaxPacket(tc, True, XETrapMinPktSize); /* just get the minimum */
267
268    /* Set up callbacks for data */
269    XEAddRequestCBs(tc, requests, print_req_callback, NULL);
270    XEAddEventCBs(tc, events, print_evt_callback, NULL);
271
272    (void)XEStartTrapRequest(tc);
273    (void)XEGetCurrentRequest(tc,&ret_cur);
274    XEPrintCurrent(stderr,&ret_cur);
275
276    /* Add signal handlers so that we clean up properly */
277    _InitExceptionHandling((void_function)SetGlobalDone);
278    (void)XEEnableCtrlKeys((void_function)SetGlobalDone);
279
280    XETrapAppWhileLoop(app,tc,&GlobalDone);
281
282    /* Make sure <CTRL> key is released */
283    XESimulateXEventRequest(tc, KeyRelease,
284        XKeysymToKeycode(dpy, XK_Control_L), 0L, 0L, 0L);
285
286    /* close down everything nicely */
287    XEFreeTC(tc);
288    (void)XCloseDisplay(dpy);
289    (void)XEClearCtrlKeys();
290    _ClearExceptionHandling();
291    exit(0L);
292}
293
294