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", ¶ms, &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", ¶ms, &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