XEConTxt.c revision 51b8cbae
1/* $XFree86: xc/lib/XTrap/XEConTxt.c,v 1.1 2001/11/02 23:29:27 dawes Exp $ */
2/*****************************************************************************
3Copyright 1987, 1988, 1989, 1990, 1991, 1994 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/*
24 *
25 *  CONTRIBUTORS:
26 *
27 *      Dick Annicchiarico
28 *      Robert Chesler
29 *      Dan Coutu
30 *      Gene Durso
31 *      Marc Evans
32 *      Alan Jamison
33 *      Mark Henry
34 *      Ken Miller
35 *
36 */
37
38#define NEED_REPLIES
39#define NEED_EVENTS
40
41
42#include <X11/extensions/xtraplib.h>
43#include <X11/extensions/xtraplibp.h>
44
45#ifndef TRUE
46# define TRUE 1L
47#endif
48#ifndef FALSE
49# define FALSE 0L
50#endif
51
52static XETC     TC;
53
54/*
55 * This function is used to create a new XTrap context structure. The new
56 * context is initialized to a hard coded default, then modified by the
57 * valuemask and values passed in by the caller.
58 */
59
60XETC *XECreateTC(Display *dpy, CARD32 valuemask, XETCValues *value)
61{
62    static Bool firsttime = True;
63    register XETC *tc     = &TC;
64    register XETC *last_tc;
65    XETrapGetAvailRep rep;
66
67    /* If this is the first time here, then initialize the default TC */
68    if (firsttime == True)
69    {
70        firsttime = False;
71        /* The first Trap Context is the Template (default) TC */
72        memset(tc,0L,sizeof(*tc));
73        tc->eventBase             = 0x7FFFFFFFL;
74        tc->errorBase             = 0x7FFFFFFFL;
75        tc->values.v.max_pkt_size = 0x7FFFL;
76    }
77
78    /* Position to the end of the list */
79    for (;tc->next != NULL; tc = tc->next);
80
81    /* Allocate memory for the new context */
82    last_tc = tc;   /* save the address of the last on the list */
83    if ((tc = (tc->next = (XETC *)XtMalloc(sizeof(*tc)))) == NULL)
84    {   /* No memory to build TC, XtMalloc has already reported the error */
85        return(NULL);
86    }
87
88    /* Use the original TC as the template to start from */
89    (void)memcpy(tc,&TC,sizeof(TC));
90    tc->next      = NULL;
91    tc->dpy       = dpy;
92    tc->xmax_size = XMaxRequestSize(tc->dpy);
93
94    /* Initialize Extension */
95    if (!XETrapQueryExtension(dpy,&(tc->eventBase),&(tc->errorBase),
96        &(tc->extOpcode)))
97    {
98        char *params = XTrapExtName;
99        unsigned int num_params = 1L;
100        XtWarningMsg("CantLoadExt", "XECreateTC", "XTrapToolkitError",
101            "Can't load %s extension", &params, &num_params);
102        (void)XtFree((XtPointer)tc);
103        last_tc->next = NULL;    /* Clear now nonexistant forward pointer */
104        return(NULL);
105    }
106
107    /* Allocate memory for the XLIB transport */
108    if ((tc->xbuff = (BYTE *)XtMalloc(tc->xmax_size * sizeof(CARD32) +
109        SIZEOF(XETrapHeader))) == NULL)
110    {   /* No memory to build TC, XtMalloc has already reported the error */
111        (void)XtFree((XtPointer)tc);        /* free the allocated TC */
112        last_tc->next = NULL;    /* Clear now nonexistant forward pointer */
113        return(NULL);
114    }
115
116    /* Decide on a protocol version to communicate with */
117    /* would *like* to use XEGetVersionRequest() but it's broken in V3.1 */
118    if (XEGetAvailableRequest(tc,&rep) == True)
119    {
120        /* stow the protocol number */
121        switch (rep.xtrap_protocol)
122        {
123            /* known acceptable protocols */
124            case 31:
125            case XETrapProtocol:
126                tc->protocol = rep.xtrap_protocol;
127                break;
128            /* all else */
129            default:    /* stay backwards compatible */
130                tc->protocol = 31;
131                break;
132        }
133        /* TC to contain *oldest* release/version/revision */
134        if (XETrapGetAvailRelease(&rep) <= XETrapRelease)
135        {
136            tc->release = XETrapGetAvailRelease(&rep);
137            if (XETrapGetAvailVersion(&rep) <= XETrapVersion)
138            {
139                tc->version = XETrapGetAvailVersion(&rep);
140                tc->revision = (XETrapGetAvailRevision(&rep) <= XETrapRevision ?
141                    XETrapGetAvailRevision(&rep) : XETrapRevision);
142            }
143            else
144            {
145                tc->version  = XETrapVersion;
146                tc->revision = XETrapRevision;
147            }
148        }
149        else
150        {
151                tc->release = XETrapRelease;
152                tc->version  = XETrapVersion;
153                tc->revision = XETrapRevision;
154        }
155    }
156    else
157    {   /* We can't seem to communicate with the extension! */
158        char *params = XTrapExtName;
159        unsigned int num_params = 1L;
160        XtWarningMsg("CantComm", "XECreateTC", "XTrapToolkitError",
161            "Can't communicate with extension %s", &params, &num_params);
162        (void)XtFree((XtPointer)tc->xbuff);/* de-allocate memory just alloc'd */
163        (void)XtFree((XtPointer)tc);           /* free the allocated TC */
164        last_tc->next = NULL;       /* Clear now nonexistant forward pointer */
165        return(NULL);
166    }
167
168    /* Assign the context values the caller provided */
169    (void)XEChangeTC(tc, valuemask, value);
170
171    return (tc);
172}
173
174
175static int CheckChangeBits(XETrapFlags *dest, XETrapFlags *src, INT32 bit)
176{
177    int chg_flag = False;
178
179    if (!(BitIsFalse(dest->valid,bit) && BitIsFalse(src->valid,bit)) ||
180        !(BitIsTrue(dest->valid,bit) && BitIsTrue(src->valid,bit)))
181    {
182        BitCopy(dest->valid, src->valid, bit);
183        chg_flag = True;
184    }
185    if (!(BitIsFalse(dest->data,bit) && BitIsFalse(src->data,bit)) ||
186        !(BitIsTrue(dest->data,bit) && BitIsTrue(src->data,bit)))
187    {
188        BitCopy(dest->data, src->data, bit);
189        chg_flag = True;
190    }
191    return(chg_flag);
192}
193
194/*
195 * This function is called to change one or more parameters used to define
196 * a context in which XTrap is or will be running.
197 */
198int XEChangeTC(XETC *tc, CARD32 mask, XETCValues *values)
199{
200    int status = True;
201    register XETCValues *tval = &(tc->values);
202    register int i;
203
204    if (mask & TCStatistics)
205    {   /* Statistics need changing */
206        if(CheckChangeBits(&(tval->v.flags), &(values->v.flags),
207            XETrapStatistics))
208        {
209            tc->dirty |= TCStatistics;
210        }
211    }
212    if (mask & TCRequests)
213    {   /* Requests need changing */
214        CheckChangeBits(&(tval->v.flags), &(values->v.flags), XETrapRequest);
215        for (i=0; i<256L; i++)
216        {
217            XETrapSetCfgFlagReq(tval, i, BitValue(values->v.flags.req,i));
218        }
219        tc->dirty |= TCRequests;
220    }
221    if (mask & TCEvents)
222    {   /* Events need changing */
223        CheckChangeBits(&(tval->v.flags), &(values->v.flags), XETrapEvent);
224        for (i=KeyPress; i<=MotionNotify; i++)
225        {
226            XETrapSetCfgFlagEvt(tval, i, BitValue(values->v.flags.event,i));
227        }
228        tc->dirty |= TCEvents;
229    }
230    if (mask & TCMaxPacket)
231    {   /* MaxPacket needs changing */
232        CheckChangeBits(&(tval->v.flags), &(values->v.flags), XETrapMaxPacket);
233        XETrapSetCfgMaxPktSize(tval, values->v.max_pkt_size);
234        tc->dirty |= TCMaxPacket;
235    }
236    if (mask & TCCmdKey)
237    {   /* CmdKey needs changing */
238        CheckChangeBits(&(tval->v.flags), &(values->v.flags), XETrapCmd);
239        tval->v.cmd_key = values->v.cmd_key;
240        CheckChangeBits(&(tval->v.flags), &(values->v.flags), XETrapCmdKeyMod);
241        tc->dirty |= TCCmdKey;
242    }
243    if (mask & TCTimeStamps)
244    {   /* TimeStamps needs changing */
245        if (CheckChangeBits(&(tval->v.flags), &(values->v.flags), XETrapTimestamp))
246        {
247            tc->dirty |= TCTimeStamps;
248        }
249        BitCopy(tval->tc_flags, values->tc_flags, XETCDeltaTimes);
250    }
251    if (mask & TCWinXY)
252    {   /* Window XY's need changing */
253        if (CheckChangeBits(&(tval->v.flags), &(values->v.flags), XETrapWinXY))
254        {
255            tc->dirty |= TCWinXY;
256        }
257    }
258    if (mask & TCCursor)
259    {   /* Window XY's need changing */
260        if (CheckChangeBits(&(tval->v.flags), &(values->v.flags),XETrapCursor))
261        {
262            tc->dirty |= TCCursor;
263        }
264    }
265    if (mask & TCXInput)
266    {   /*  XInput flag needs changing */
267        if (CheckChangeBits(&(tval->v.flags), &(values->v.flags),XETrapXInput))
268        {
269            tc->dirty |= TCXInput;
270        }
271    }
272    if (mask & TCColorReplies)
273    {   /*  ColorReplies flag needs changing */
274        if (CheckChangeBits(&(tval->v.flags), &(values->v.flags),
275            XETrapColorReplies))
276        {
277            tc->dirty |= TCColorReplies;
278        }
279    }
280    if (mask & TCGrabServer )
281    {   /* GrabServer flag needs changing */
282        if (CheckChangeBits(&(tval->v.flags), &(values->v.flags),
283            XETrapGrabServer ))
284        {
285            tc->dirty |= TCGrabServer;
286        }
287    }
288    if (XETrapGetTCFlagTrapActive(tc))
289    {
290        status = XEFlushConfig(tc);
291    }
292#ifdef VMS
293    sys$setast(True);   /* Make sure AST's are enabled */
294#endif /* VMS */
295    return(status);
296}
297
298
299void XEFreeTC(XETC *tc)
300{
301    register XETC *list = &TC;
302
303    if (tc)
304    {
305        while(list->next != NULL)
306        {
307            if (list->next == tc)
308                list->next = list->next->next;  /* Got it, remove from list */
309            else
310                list = list->next;              /* Update the list pointer */
311        }
312        if (tc->values.req_cb)
313        {
314            XtFree((XtPointer)tc->values.req_cb);
315        }
316        if (tc->values.evt_cb)
317        {
318            XtFree((XtPointer)tc->values.evt_cb);
319        }
320        if (tc->xbuff != NULL)
321        {
322            XtFree((XtPointer)tc->xbuff);
323        }
324
325        XtFree((XtPointer)tc);
326    }
327    return;
328}
329
330/* The following are Convenience routines for setting values within
331 * the Trap Context.  These are analogous to the GC's Convenience
332 * Functions such as XSetState & XSetForeground
333 */
334int XETrapSetMaxPacket(XETC *tc, Bool set_flag, CARD16 size)
335{
336    XETCValues tcv;
337    int status = True;
338
339    memset((char *)&tcv,0L,sizeof(tcv));
340    XETrapSetCfgFlagMaxPacket(&tcv, valid, True);
341    XETrapSetCfgFlagMaxPacket(&tcv, data, set_flag);
342    XETrapSetCfgMaxPktSize(&tcv, size);
343    status = XEChangeTC(tc, TCMaxPacket, &tcv);
344    return(status);
345}
346int XETrapSetCommandKey(XETC *tc, Bool set_flag, KeySym cmd_key, Bool mod_flag)
347{
348    XETCValues tcv;
349    int status = True;
350    KeyCode cmd_keycode;
351
352    memset((char *)&tcv,0L,sizeof(tcv));
353    XETrapSetCfgFlagCmd(&tcv, valid, True);
354    XETrapSetCfgFlagCmd(&tcv, data, set_flag);
355    if (set_flag == True)
356    {
357        XETrapSetCfgFlagCmdKeyMod(&tcv, valid, True);
358        XETrapSetCfgFlagCmdKeyMod(&tcv, data, mod_flag);
359        if (!(cmd_keycode = XKeysymToKeycode(XETrapGetDpy(tc), cmd_key)))
360        {
361            status = False;
362        }
363        else
364        {
365            XETrapSetCfgCmdKey(&tcv, cmd_keycode);
366        }
367    }
368    else
369    {   /* Clear command key */
370        XETrapSetCfgFlagCmdKeyMod(&tcv, valid, True);
371        XETrapSetCfgFlagCmdKeyMod(&tcv, data, False);
372        XETrapSetCfgCmdKey(&tcv, 0);
373    }
374    if (status == True)
375    {
376        status = XEChangeTC(tc, TCCmdKey, &tcv);
377    }
378    return(status);
379}
380
381int XETrapSetTimestamps(XETC *tc, Bool set_flag, Bool delta_flag)
382{
383    XETCValues tcv;
384    int status = True;
385
386    memset((char *)&tcv,0L,sizeof(tcv));
387    XETrapSetCfgFlagTimestamp(&tcv, valid, True);
388    XETrapSetCfgFlagTimestamp(&tcv, data, set_flag);
389    XETrapSetValFlagDeltaTimes(&tcv, delta_flag);
390    status = XEChangeTC(tc, TCTimeStamps, &tcv);
391    return(status);
392}
393
394int XETrapSetWinXY(XETC *tc, Bool set_flag)
395{
396    XETCValues tcv;
397    int status = True;
398
399    memset((char *)&tcv,0L,sizeof(tcv));
400    XETrapSetCfgFlagWinXY(&tcv, valid, True);
401    XETrapSetCfgFlagWinXY(&tcv, data, set_flag);
402    status = XEChangeTC(tc, TCWinXY, &tcv);
403    return(status);
404}
405
406int XETrapSetCursor(XETC *tc, Bool set_flag)
407{
408    XETCValues tcv;
409    int status = True;
410
411    memset((char *)&tcv,0L,sizeof(tcv));
412    XETrapSetCfgFlagCursor(&tcv, valid, True);
413    XETrapSetCfgFlagCursor(&tcv, data, set_flag);
414    status = XEChangeTC(tc, TCCursor, &tcv);
415    return(status);
416}
417
418int XETrapSetXInput(XETC *tc, Bool set_flag)
419{
420    XETCValues tcv;
421    int status = True;
422
423    memset((char *)&tcv,0L,sizeof(tcv));
424    XETrapSetCfgFlagXInput(&tcv, valid, True);
425    XETrapSetCfgFlagXInput(&tcv, data, set_flag);
426    status = XEChangeTC(tc, TCXInput, &tcv);
427    return(status);
428}
429
430int XETrapSetColorReplies(XETC *tc, Bool set_flag)
431{
432    XETCValues tcv;
433    int status = True;
434
435    memset((char *)&tcv,0L,sizeof(tcv));
436    XETrapSetCfgFlagColorReplies(&tcv, valid, True);
437    XETrapSetCfgFlagColorReplies(&tcv, data, set_flag);
438    status = XEChangeTC(tc, TCColorReplies, &tcv);
439    return(status);
440}
441
442int XETrapSetGrabServer(XETC *tc, Bool set_flag)
443{
444    XETCValues tcv;
445    int status = True;
446
447    memset((char *)&tcv,0L,sizeof(tcv));
448    XETrapSetCfgFlagGrabServer(&tcv, valid, True);
449    XETrapSetCfgFlagGrabServer(&tcv, data, set_flag);
450    status = XEChangeTC(tc, TCGrabServer, &tcv);
451    return(status);
452}
453
454int XETrapSetStatistics(XETC *tc, Bool set_flag)
455{
456    XETCValues tcv;
457    int status = True;
458
459    memset((char *)&tcv,0L,sizeof(tcv));
460    XETrapSetCfgFlagStatistics(&tcv, valid, True);
461    XETrapSetCfgFlagStatistics(&tcv, data, set_flag);
462    status = XEChangeTC(tc, TCStatistics, &tcv);
463    return(status);
464}
465
466int XETrapSetRequests(XETC *tc, Bool set_flag, ReqFlags requests)
467{
468    XETCValues tcv;
469    int status = True;
470    int i;
471
472    memset((char *)&tcv,0L,sizeof(tcv));
473    XETrapSetCfgFlagRequest(&tcv, valid, True);
474    XETrapSetCfgFlagRequest(&tcv, data, set_flag);
475    for (i=0; i<256L; i++)
476    {
477        XETrapSetCfgFlagReq(&tcv, i, BitValue(requests, i));
478    }
479    status = XEChangeTC(tc, TCRequests, &tcv);
480    return(status);
481}
482
483int XETrapSetEvents(XETC *tc, Bool set_flag, EventFlags events)
484{
485    XETCValues tcv;
486    int status = True;
487    int i;
488
489    memset((char *)&tcv,0L,sizeof(tcv));
490    XETrapSetCfgFlagEvent(&tcv, valid, True);
491    XETrapSetCfgFlagEvent(&tcv, data, set_flag);
492    for (i=KeyPress; i<=MotionNotify; i++)
493    {
494        XETrapSetCfgFlagEvt(&tcv, i, BitValue(events, i));
495    }
496    status = XEChangeTC(tc, (CARD32)TCEvents, &tcv);
497    return(status);
498}
499
500Bool XESetCmdGateState(XETC *tc, CARD8 type, Bool *gate_closed,
501    CARD8 *next_key, Bool *key_ignore)
502{
503
504    *key_ignore = False;
505    if (XETrapGetTCFlagCmdKeyMod(tc,data) == True)
506    {
507        switch (type)
508        {
509            case KeyPress:
510                if (*next_key == XEKeyIsEcho)
511                {
512                    break;
513                }
514                *gate_closed = True;
515                *next_key = XEKeyIsClear;
516                break;
517
518            case KeyRelease:
519                if (*next_key == XEKeyIsEcho)
520                {
521                    *next_key = XEKeyIsClear;
522                    break;
523                }
524                if (*next_key == XEKeyIsClear)
525                {
526                    *next_key = XEKeyIsEcho;
527                }
528                else
529                {   /* it's XEKeyIsOther, so Clear it */
530                    *next_key = XEKeyIsClear;
531                }
532                *gate_closed = False;
533                *key_ignore = True;
534                break;
535
536            default: break;
537        }
538    }
539    else
540    {
541        switch (type)
542        {
543            case KeyPress:
544                if (*next_key == XEKeyIsEcho)
545                {
546                    *gate_closed = False;
547                    break;
548                }
549                /* Open gate on cmd key release */
550                if ((*next_key == XEKeyIsOther) &&
551                    *gate_closed == True)
552                {
553                    break;
554                }
555                *gate_closed = True;
556                *next_key = XEKeyIsClear;
557                break;
558
559            case KeyRelease:
560                if (*next_key == XEKeyIsClear)
561                {
562                    *next_key = XEKeyIsEcho;
563                    break;
564                }
565
566                if (*next_key == XEKeyIsEcho)
567                {
568                    *next_key = XEKeyIsClear;
569                    break;
570                }
571
572                *gate_closed = False;
573                *key_ignore = True;
574                *next_key = XEKeyIsClear;
575                break;
576
577            default:
578                break;
579        }
580    }
581
582    return(*gate_closed);
583}
584