xtrapout.c revision 99435119
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#ifdef HAVE_CONFIG_H
92#include "config.h"
93#endif
94
95#include <inttypes.h>
96#include <stdio.h>
97#include <X11/extensions/xtraplib.h>
98#include <X11/extensions/xtraplibp.h>
99#include <signal.h>
100#include <X11/keysym.h>
101#include <unistd.h>
102#include <stdlib.h>
103
104#include "XEKeybCtrl.h"
105
106#ifndef vaxc
107#define globalref extern
108#endif
109#ifdef Lynx
110extern char *optarg;
111extern int optind;
112extern int opterr;
113#endif
114
115
116/* Forward declarations */
117static void SetGlobalDone (int unused );
118static void print_req_callback (XETC *tc , XETrapDatum *data ,
119    BYTE *my_buf );
120static void print_evt_callback (XETC *tc , XETrapDatum *data ,
121    BYTE *my_buf );
122
123
124static FILE *ofp;
125static Bool GlobalDone = False;
126static XrmOptionDescRec optionTable [] =
127{
128    {"-f",     "*script",    XrmoptionSepArg,  (caddr_t) NULL},
129    {"-e",     "*eventFlag", XrmoptionSkipArg, (caddr_t) NULL},
130    {"-v",     "*verbose",   XrmoptionSkipArg, (caddr_t) NULL},
131};
132
133static void SetGlobalDone(int unused)
134{
135    GlobalDone = 1L;
136    fprintf(stderr,"Process Completed!\n");
137    return;
138}
139
140static void print_req_callback(XETC *tc, XETrapDatum *data, BYTE *my_buf)
141{
142    char *req_type;
143    req_type = (data->u.req.reqType == XETrapGetExtOpcode(tc) ? "XTrap" :
144        XERequestIDToString(data->u.req.reqType,tc));
145    fprintf(ofp,"Request: %-19s (%d): length '%ld' client '%d' window=%ld\n",
146        req_type, data->u.req.reqType, (long)data->hdr.count, data->hdr.client,
147        (long)data->u.req.id);
148}
149
150static void print_evt_callback(XETC *tc, XETrapDatum *data, BYTE *my_buf)
151{
152    static Time last_time = 0;
153    int delta;
154
155    delta = imaxabs((int)last_time ? (intmax_t)data->u.event.u.keyButtonPointer.time -
156        (int)last_time  : (int)last_time);
157    last_time = data->u.event.u.keyButtonPointer.time;
158
159    /* The "screen" and "root" fields aren't valid until "event"
160     * vectoring becomes a reality.  Currently, XTrap intercepts
161     * the core events prior to when fields other than rootX, rootY,
162     * type, detail, time, and state are filled in.  This will be
163     * addressed in the next release of XTrap (3.2?).
164     */
165    fprintf(ofp,
166        "Event: %-15s (%d):det=%d scr=%d (%d,%d) root=%d Msk=%d TS=%d\n",
167        XEEventIDToString(data->u.event.u.u.type,tc), data->u.event.u.u.type,
168        data->u.event.u.u.detail, data->hdr.screen, /* Not really valid yet */
169        data->u.event.u.keyButtonPointer.rootX,
170        data->u.event.u.keyButtonPointer.rootY,
171        (int)data->u.event.u.keyButtonPointer.root, /* Not really valid yet */
172        (int)data->u.event.u.keyButtonPointer.state,
173        (int)delta);
174    fflush(ofp);
175}
176static Boolean eventFlag = False;
177static Boolean verboseFlag = False;
178static Widget appW;
179static Display *dpy;
180
181int
182main(int argc, char *argv[])
183{
184    XETrapGetAvailRep ret_avail;
185    XETrapGetCurRep   ret_cur;
186    XETC    *tc;
187    ReqFlags     requests;
188    EventFlags   events;
189    XtAppContext app;
190    char *tmp = NULL;
191    INT16 ch;
192    int *popterr;
193    char **poptarg;
194#ifndef vms
195    popterr = &opterr;
196    poptarg = &optarg;
197#else
198    popterr = XEgetopterr();
199    poptarg = XEgetoptarg();
200#endif
201
202    eventFlag = False;
203    ofp = NULL;
204    *popterr = 0; /* don't complain about -d (display) */
205    while ((ch = getopt(argc, argv, "d:evf:")) != EOF)
206    {
207        switch(ch)
208        {
209            case 'e':
210                eventFlag = True;
211                break;
212            case 'v':
213                verboseFlag = True;
214                break;
215            case 'f':
216                if ((ofp = fopen(*poptarg,"wb")) == NULL)
217                {   /* can't open it */
218                    fprintf(stderr,"%s: could not open output file '%s'!\n",
219                        ProgName, *poptarg);
220                }
221                break;
222            case 'd':   /* -display, let's let the toolkit parse it */
223                break;
224            default:
225                break;
226        }
227    }
228    ofp = (ofp ? ofp : stdout);
229
230    appW = XtAppInitialize(&app,"XTrap",optionTable,(Cardinal)2L,
231        (int *)&argc, (String *)argv, (String *)NULL,(ArgList)&tmp,
232        0);
233
234    dpy = XtDisplay(appW);
235#ifdef DEBUG
236    XSynchronize(dpy, True);
237#endif
238    fprintf(stderr,"Display:  %s \n", DisplayString(dpy));
239    if ((tc = XECreateTC(dpy,0L, NULL)) == NULL)
240    {
241        fprintf(stderr,"%s: could not initialize XTrap extension\n",ProgName);
242        exit (1L);
243    }
244    XETrapSetTimestamps(tc,True, False);
245    (void)XEGetAvailableRequest(tc,&ret_avail);
246    XEPrintAvail(stderr,&ret_avail);
247    XEPrintTkFlags(stderr,tc);
248
249    /* Need to prime events/requests initially turning all off  */
250    (void)memset(requests,0L,sizeof(requests));
251    (void)memset(events,0L,sizeof(events));
252    /* Now turn on the ones you really want */
253    (void)memset(events,0xFFL,XETrapMaxEvent);
254    if (eventFlag == False)
255    {   /* doesn't want just events */
256        (void)memset(requests,0xFFL,XETrapMaxRequest);
257        /* Turn off XTrap Requests for multi-client regression tests & XLib */
258        BitFalse(requests, XETrapGetExtOpcode(tc));
259        /* Turn off noisy events */
260        BitFalse(events, MotionNotify);
261    }
262    if (verboseFlag == True)
263    {   /* want's *all* requests/events */
264        (void)memset(requests,0xFFL,XETrapMaxRequest);
265        (void)memset(events,0xFFL,XETrapMaxEvent);
266    }
267    /* Tell the TC about it */
268    XETrapSetRequests(tc, True, requests);
269    XETrapSetEvents(tc, True, events);
270    XETrapSetMaxPacket(tc, True, XETrapMinPktSize); /* just get the minimum */
271
272    /* Set up callbacks for data */
273    XEAddRequestCBs(tc, requests, print_req_callback, NULL);
274    XEAddEventCBs(tc, events, print_evt_callback, NULL);
275
276    (void)XEStartTrapRequest(tc);
277    (void)XEGetCurrentRequest(tc,&ret_cur);
278    XEPrintCurrent(stderr,&ret_cur);
279
280    /* Add signal handlers so that we clean up properly */
281    _InitExceptionHandling(SetGlobalDone);
282    (void)XEEnableCtrlKeys(SetGlobalDone);
283
284    XETrapAppWhileLoop(app,tc,&GlobalDone);
285
286    /* Make sure <CTRL> key is released */
287    XESimulateXEventRequest(tc, KeyRelease,
288        XKeysymToKeycode(dpy, XK_Control_L), 0L, 0L, 0L);
289
290    /* close down everything nicely */
291    XEFreeTC(tc);
292    (void)XCloseDisplay(dpy);
293    (void)XEClearCtrlKeys();
294    _ClearExceptionHandling();
295    exit(0L);
296}
297
298