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