XETrapInit.c revision 966bf024
1/* $XFree86: xc/lib/XTrap/XETrapInit.c,v 1.2 2001/11/08 04:00:12 tsi Exp $ */
2/*****************************************************************************
3Copyright 1987, 1988, 1989, 1990, 1991, 1992 by Digital Equipment Corp.,
4Maynard, MA
5
6Permission to use, copy, modify, and distribute this software and its
7documentation for any purpose and without fee is hereby granted,
8provided that the above copyright notice appear in all copies and that
9both that copyright notice and this permission notice appear in
10supporting documentation, and that the name of Digital not be
11used in advertising or publicity pertaining to distribution of the
12software without specific, written prior permission.
13
14DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20SOFTWARE.
21
22*****************************************************************************/
23#define NEED_EVENTS
24#define NEED_REPLIES
25
26#include <stdio.h>
27#include <X11/extensions/xtraplib.h>
28#include <X11/extensions/xtraplibp.h>
29#include <X11/extensions/Xext.h>
30#include <X11/extensions/extutil.h>
31
32#ifndef XETrapNumberErrors
33#define XETrapNumberErrors 0
34#endif
35
36#ifdef UWS40
37#define _XSetLastRequestRead _SetLastRequestRead
38#endif
39#ifndef vms
40extern unsigned long _XSetLastRequestRead(Display *dpy, xGenericReply *rep);
41#else
42static unsigned long _XSetLastRequestRead(Display *dpy, xGenericReply *rep);
43#endif
44
45static XExtensionInfo *xtrap_info = NULL;
46static /* const */ char *xtrap_extension_name = XTrapExtName;
47
48#define XTrapCheckExtension(dpy,i,val) \
49    XextCheckExtension(dpy, i, xtrap_extension_name, val)
50#define XTrapSimpleCheckExtension(dpy,i) \
51    XextSimpleCheckExtension(dpy, i, xtrap_extension_name)
52
53static XEXT_CLOSE_DISPLAY_PROTO(close_display);
54static Bool wire_to_event(Display *dpy, XEvent *event, xEvent *wire_ev);
55static Status event_to_wire(Display *dpy, XEvent *event, xEvent *wire_ev);
56
57#ifdef X11R3
58static int error_string();
59#else
60static XEXT_ERROR_STRING_PROTO(error_string);
61#endif
62static /* const */ XExtensionHooks xtrap_extension_hooks = {
63    NULL,                               /* create_gc */
64    NULL,                               /* copy_gc */
65    NULL,                               /* flush_gc */
66    NULL,                               /* free_gc */
67    NULL,                               /* create_font */
68    NULL,                               /* free_font */
69    close_display,                      /* close_display */
70    wire_to_event,                      /* wire_to_event */
71    event_to_wire,                      /* event_to_wire */
72    NULL,                               /* error */
73    error_string                        /* error_string */
74};
75
76static /* const */ char *xtrap_error_list[] = {
77    "BadTransport (I/O transport not available)",
78    "BadMailbox (Cannot connect/disconnect to mailbox)",
79    "BadIO (I/O error while reading/writing in extension)",
80    "BadHostname (Cannot locate requested host)",
81    "BadStatistics (Statistics not configured/available)",
82    "BadDevices (Devices not properly vectored)",
83    "BadSocket (Cannot connect to INTERNET socket)",
84    "BadScreen (Cannot send event to given screen)",
85    "BadSwapReq (Cannot trap extension requests for swapped client)",
86};
87
88static XEXT_GENERATE_FIND_DISPLAY (find_display, xtrap_info,
89                                   xtrap_extension_name,
90                                   &xtrap_extension_hooks,
91                                   XETrapNumberEvents, NULL)
92
93static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xtrap_info)
94
95static XEXT_GENERATE_ERROR_STRING (error_string, xtrap_extension_name,
96                                   XETrapNumErrors, xtrap_error_list)
97
98static Bool event_to_wire(Display *dpy, XEvent *libevent, xEvent *netevent)
99{
100    Bool status = False;
101    XExtDisplayInfo *info = find_display(dpy);
102
103    XTrapCheckExtension(dpy,info,False);
104
105    /* If we had more then one event */
106#if XETrapNumberErrors > 1
107    switch((netevent->u.u.type & 0x7f) - info->codes->first_event)
108    {   case XETrapData:
109#endif
110        {
111            XETrapDataEvent *ev    = (XETrapDataEvent *) libevent;
112            xETrapDataEvent *event = (xETrapDataEvent *) netevent;
113
114            event->type           = ev->type;
115            event->detail         = ev->detail;
116            event->sequenceNumber = (ev->serial & 0xFFFF);
117            event->idx            = ev->idx;
118            (void)memcpy(event->data,ev->data,sizeof(event->data));
119            status = True;
120        }
121#if XETrapNumberErrors > 1
122    }
123#endif
124    return(status);
125}
126
127static Bool wire_to_event(Display *dpy, XEvent *libevent, xEvent *netevent)
128{
129    Bool status = False;
130    XExtDisplayInfo *info = find_display(dpy);
131
132    XTrapCheckExtension(dpy,info,False);
133
134    /* If we had more then one event */
135#if XETrapNumberErrors > 1
136    switch((netevent->u.u.type & 0x7f) - info->codes->first_event)
137    {   case XETrapData:
138#endif
139        {
140            XETrapDataEvent *ev    = (XETrapDataEvent *) libevent;
141            xETrapDataEvent *event = (xETrapDataEvent *) netevent;
142
143            ev->type      = event->type & 0x7F;
144            ev->detail    = event->detail;
145            ev->serial    = _XSetLastRequestRead(dpy,(xGenericReply *)netevent);
146            ev->synthetic = ((event->type & 0x80) != 0);
147            ev->display   = dpy;
148            ev->idx       = event->idx;
149            (void)memcpy(ev->data,event->data,sizeof(ev->data));
150            status = True;
151        }
152#if XETrapNumberErrors > 1
153    }
154#endif
155    return(status);
156}
157
158/*
159 * XETrapQueryExtension -
160 *      Returns True if the DEC-XTRAP extension is available
161 *      on the given display.  If the extension exists, the value of the
162 *      first event code is stored into event_base and the value of the first
163 *      error code is stored into error_base.
164 */
165Bool XETrapQueryExtension(Display *dpy,INT32 *event_base_return,
166    INT32 *error_base_return, INT32 *opcode_return)
167{
168    Bool status = True;
169    XExtDisplayInfo *info = find_display (dpy);
170
171    if (XextHasExtension (info))
172    {
173        *event_base_return = (INT32)(info->codes->first_event);
174        *error_base_return = (INT32)(info->codes->first_error);
175	*opcode_return     = (INT32)(info->codes->major_opcode);
176    }
177    else
178    {
179        status = False;
180    }
181    return(status);
182}
183
184#ifdef vms
185/* Hard-coded since this didn't make it into XLibShr's xfer vector */
186/* From [.XLIBEL.SRC]XLibInt.c in VMS Source Pool */
187unsigned long _XSetLastRequestRead(Display *dpy, xGenericReply *rep)
188{
189    register unsigned long      newseq, lastseq;
190
191    /*
192     * KeymapNotify has no sequence number, but is always guaranteed
193     * to immediately follow another event, except when generated via
194     * SendEvent (hmmm).
195     */
196    if ((rep->type & 0x7f) == KeymapNotify)
197        return(dpy->last_request_read);
198
199    newseq = (dpy->last_request_read & ~((unsigned long)0xffff)) |
200             rep->sequenceNumber;
201    lastseq = dpy->last_request_read;
202    while (newseq < lastseq) {
203        newseq += 0x10000;
204        if (newseq > dpy->request) {
205            (void) fprintf (stderr,
206            "Xlib:  sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n",
207                                    newseq, dpy->request,
208                                   (unsigned int) rep->type);
209            newseq -= 0x10000;
210           break;
211        }
212    }
213
214    dpy->last_request_read = newseq;
215    return(newseq);
216}
217#endif
218
219