action.c revision f46a6179
1/* $Xorg: action.c,v 1.3 2000/08/17 19:54:30 cpqbld Exp $ */ 2/************************************************************ 3 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 4 5 Permission to use, copy, modify, and distribute this 6 software and its documentation for any purpose and without 7 fee is hereby granted, provided that the above copyright 8 notice appear in all copies and that both that copyright 9 notice and this permission notice appear in supporting 10 documentation, and that the name of Silicon Graphics not be 11 used in advertising or publicity pertaining to distribution 12 of the software without specific prior written permission. 13 Silicon Graphics makes no representation about the suitability 14 of this software for any purpose. It is provided "as is" 15 without any express or implied warranty. 16 17 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 18 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 20 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 21 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 23 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 24 THE USE OR PERFORMANCE OF THIS SOFTWARE. 25 26 ********************************************************/ 27/* $XFree86: xc/programs/xkbcomp/action.c,v 3.10tsi Exp $ */ 28 29#include "xkbcomp.h" 30#include "tokens.h" 31#include "expr.h" 32 33#include "keycodes.h" 34#include "vmod.h" 35#include "misc.h" 36#include "action.h" 37#include "misc.h" 38 39static Bool actionsInitialized; 40static ExprDef constTrue; 41static ExprDef constFalse; 42 43/***====================================================================***/ 44 45static Bool 46stringToAction(char *str,unsigned *type_rtrn) 47{ 48 if (str==NULL) 49 return False; 50 51 if (uStrCaseCmp(str,"noaction")==0) *type_rtrn= XkbSA_NoAction; 52 else if (uStrCaseCmp(str,"setmods")==0) *type_rtrn= XkbSA_SetMods; 53 else if (uStrCaseCmp(str,"latchmods")==0) *type_rtrn= XkbSA_LatchMods; 54 else if (uStrCaseCmp(str,"lockmods")==0) *type_rtrn= XkbSA_LockMods; 55 else if (uStrCaseCmp(str,"setgroup")==0) *type_rtrn= XkbSA_SetGroup; 56 else if (uStrCaseCmp(str,"latchgroup")==0) *type_rtrn= XkbSA_LatchGroup; 57 else if (uStrCaseCmp(str,"lockgroup")==0) *type_rtrn= XkbSA_LockGroup; 58 else if (uStrCaseCmp(str,"moveptr")==0) *type_rtrn= XkbSA_MovePtr; 59 else if (uStrCaseCmp(str,"movepointer")==0) *type_rtrn= XkbSA_MovePtr; 60 else if (uStrCaseCmp(str,"ptrbtn")==0) *type_rtrn= XkbSA_PtrBtn; 61 else if (uStrCaseCmp(str,"pointerbutton")==0) 62 *type_rtrn= XkbSA_PtrBtn; 63 else if (uStrCaseCmp(str,"lockptrbtn")==0) *type_rtrn= XkbSA_LockPtrBtn; 64 else if (uStrCaseCmp(str,"lockpointerbutton")==0) 65 *type_rtrn= XkbSA_LockPtrBtn; 66 else if (uStrCaseCmp(str,"lockptrbutton")==0) 67 *type_rtrn= XkbSA_LockPtrBtn; 68 else if (uStrCaseCmp(str,"lockpointerbtn")==0) 69 *type_rtrn= XkbSA_LockPtrBtn; 70 else if (uStrCaseCmp(str,"setptrdflt")==0) *type_rtrn= XkbSA_SetPtrDflt; 71 else if (uStrCaseCmp(str,"setpointerdefault")==0) 72 *type_rtrn= XkbSA_SetPtrDflt; 73 else if (uStrCaseCmp(str,"isolock")==0) *type_rtrn= XkbSA_ISOLock; 74 else if (uStrCaseCmp(str,"terminate")==0) *type_rtrn= XkbSA_Terminate; 75 else if (uStrCaseCmp(str,"terminateserver")==0) 76 *type_rtrn= XkbSA_Terminate; 77 else if (uStrCaseCmp(str,"switchscreen")==0)*type_rtrn= XkbSA_SwitchScreen; 78 else if (uStrCaseCmp(str,"setcontrols")==0) *type_rtrn= XkbSA_SetControls; 79 else if (uStrCaseCmp(str,"lockcontrols")==0)*type_rtrn= XkbSA_LockControls; 80 else if (uStrCaseCmp(str,"actionmessage")==0)*type_rtrn= XkbSA_ActionMessage; 81 else if (uStrCaseCmp(str,"messageaction")==0)*type_rtrn= XkbSA_ActionMessage; 82 else if (uStrCaseCmp(str,"message")==0) *type_rtrn= XkbSA_ActionMessage; 83 else if (uStrCaseCmp(str,"redirect")==0) *type_rtrn= XkbSA_RedirectKey; 84 else if (uStrCaseCmp(str,"redirectkey")==0) *type_rtrn= XkbSA_RedirectKey; 85 else if (uStrCaseCmp(str,"devbtn")==0) *type_rtrn= XkbSA_DeviceBtn; 86 else if (uStrCaseCmp(str,"devicebtn")==0) *type_rtrn= XkbSA_DeviceBtn; 87 else if (uStrCaseCmp(str,"devbutton")==0) *type_rtrn= XkbSA_DeviceBtn; 88 else if (uStrCaseCmp(str,"devicebutton")==0)*type_rtrn= XkbSA_DeviceBtn; 89 else if (uStrCaseCmp(str,"lockdevbtn")==0) *type_rtrn= XkbSA_DeviceBtn; 90 else if (uStrCaseCmp(str,"lockdevicebtn")==0) 91 *type_rtrn= XkbSA_LockDeviceBtn; 92 else if (uStrCaseCmp(str,"lockdevbutton")==0) 93 *type_rtrn= XkbSA_LockDeviceBtn; 94 else if (uStrCaseCmp(str,"lockdevicebutton")==0) 95 *type_rtrn= XkbSA_LockDeviceBtn; 96 else if (uStrCaseCmp(str,"devval")==0) *type_rtrn=XkbSA_DeviceValuator; 97 else if (uStrCaseCmp(str,"deviceval")==0) *type_rtrn=XkbSA_DeviceValuator; 98 else if (uStrCaseCmp(str,"devvaluator")==0) *type_rtrn=XkbSA_DeviceValuator; 99 else if (uStrCaseCmp(str,"devicevaluator")==0) 100 *type_rtrn=XkbSA_DeviceValuator; 101 else if (uStrCaseCmp(str,"private")==0) *type_rtrn= PrivateAction; 102 else return False; 103 return True; 104} 105 106static Bool 107stringToField(char *str,unsigned *field_rtrn) 108{ 109 110 if (str==NULL) 111 return False; 112 113 if (uStrCaseCmp(str,"clearlocks")==0) *field_rtrn= F_ClearLocks; 114 else if (uStrCaseCmp(str,"latchtolock")==0) *field_rtrn= F_LatchToLock; 115 else if (uStrCaseCmp(str,"genkeyevent")==0) *field_rtrn= F_GenKeyEvent; 116 else if (uStrCaseCmp(str,"generatekeyevent")==0) 117 *field_rtrn= F_GenKeyEvent; 118 else if (uStrCaseCmp(str,"report")==0) *field_rtrn= F_Report; 119 else if (uStrCaseCmp(str,"default")==0) *field_rtrn= F_Default; 120 else if (uStrCaseCmp(str,"affect")==0) *field_rtrn= F_Affect; 121 else if (uStrCaseCmp(str,"increment")==0) *field_rtrn= F_Increment; 122 else if (uStrCaseCmp(str,"mods")==0) *field_rtrn= F_Modifiers; 123 else if (uStrCaseCmp(str,"modifiers")==0) *field_rtrn= F_Modifiers; 124 else if (uStrCaseCmp(str,"group")==0) *field_rtrn= F_Group; 125 else if (uStrCaseCmp(str,"x")==0) *field_rtrn= F_X; 126 else if (uStrCaseCmp(str,"y")==0) *field_rtrn= F_Y; 127 else if (uStrCaseCmp(str,"accel")==0) *field_rtrn= F_Accel; 128 else if (uStrCaseCmp(str,"accelerate")==0) *field_rtrn= F_Accel; 129 else if (uStrCaseCmp(str,"repeat")==0) *field_rtrn= F_Accel; 130 else if (uStrCaseCmp(str,"button")==0) *field_rtrn= F_Button; 131 else if (uStrCaseCmp(str,"value")==0) *field_rtrn= F_Value; 132 else if (uStrCaseCmp(str,"controls")==0) *field_rtrn= F_Controls; 133 else if (uStrCaseCmp(str,"ctrls")==0) *field_rtrn= F_Controls; 134 else if (uStrCaseCmp(str,"type")==0) *field_rtrn= F_Type; 135 else if (uStrCaseCmp(str,"count")==0) *field_rtrn= F_Count; 136 else if (uStrCaseCmp(str,"screen")==0) *field_rtrn= F_Screen; 137 else if (uStrCaseCmp(str,"same")==0) *field_rtrn= F_Same; 138 else if (uStrCaseCmp(str,"sameserver")==0) *field_rtrn= F_Same; 139 else if (uStrCaseCmp(str,"data")==0) *field_rtrn= F_Data; 140 else if (uStrCaseCmp(str,"device")==0) *field_rtrn= F_Device; 141 else if (uStrCaseCmp(str,"dev")==0) *field_rtrn= F_Device; 142 else if (uStrCaseCmp(str,"key")==0) *field_rtrn= F_Keycode; 143 else if (uStrCaseCmp(str,"keycode")==0) *field_rtrn= F_Keycode; 144 else if (uStrCaseCmp(str,"kc")==0) *field_rtrn= F_Keycode; 145 else if (uStrCaseCmp(str,"clearmods")==0) *field_rtrn= F_ModsToClear; 146 else if (uStrCaseCmp(str,"clearmodifiers")==0) *field_rtrn= F_ModsToClear; 147 else return False; 148 return True; 149} 150 151static char * 152fieldText(unsigned field) 153{ 154static char buf[32]; 155 156 switch (field) { 157 case F_ClearLocks: strcpy(buf,"clearLocks"); break; 158 case F_LatchToLock: strcpy(buf,"latchToLock"); break; 159 case F_GenKeyEvent: strcpy(buf,"genKeyEvent"); break; 160 case F_Report: strcpy(buf,"report"); break; 161 case F_Default: strcpy(buf,"default"); break; 162 case F_Affect: strcpy(buf,"affect"); break; 163 case F_Increment: strcpy(buf,"increment"); break; 164 case F_Modifiers: strcpy(buf,"modifiers"); break; 165 case F_Group: strcpy(buf,"group"); break; 166 case F_X: strcpy(buf,"x"); break; 167 case F_Y: strcpy(buf,"y"); break; 168 case F_Accel: strcpy(buf,"accel"); break; 169 case F_Button: strcpy(buf,"button"); break; 170 case F_Value: strcpy(buf,"value"); break; 171 case F_Controls: strcpy(buf,"controls"); break; 172 case F_Type: strcpy(buf,"type"); break; 173 case F_Count: strcpy(buf,"count"); break; 174 case F_Screen: strcpy(buf,"screen"); break; 175 case F_Same: strcpy(buf,"sameServer"); break; 176 case F_Data: strcpy(buf,"data"); break; 177 case F_Device: strcpy(buf,"device"); break; 178 case F_Keycode: strcpy(buf,"keycode"); break; 179 case F_ModsToClear: strcpy(buf,"clearmods"); break; 180 default: strcpy(buf,"unknown"); break; 181 } 182 return buf; 183} 184 185/***====================================================================***/ 186 187static Bool 188ReportMismatch(unsigned action, unsigned field, const char *type) 189{ 190 ERROR2("Value of %s field must be of type %s\n",fieldText(field),type); 191 ACTION1("Action %s definition ignored\n", 192 XkbActionTypeText(action,XkbMessage)); 193 return False; 194} 195 196static Bool 197ReportIllegal(unsigned action,unsigned field) 198{ 199 ERROR2("Field %s is not defined for an action of type %s\n", 200 fieldText(field), 201 XkbActionTypeText(action,XkbMessage)); 202 ACTION("Action definition ignored\n"); 203 return False; 204} 205 206static Bool 207ReportActionNotArray(unsigned action,unsigned field) 208{ 209 ERROR2("The %s field in the %s action is not an array\n", 210 fieldText(field), 211 XkbActionTypeText(action,XkbMessage)); 212 ACTION("Action definition ignored\n"); 213 return False; 214} 215 216static Bool 217ReportNotFound(unsigned action, unsigned field, const char *what, char *bad) 218{ 219 ERROR2("%s named %s not found\n",what,bad); 220 ACTION2("Ignoring the %s field of an %s action\n",fieldText(field), 221 XkbActionTypeText(action,XkbMessage)); 222 return False; 223} 224 225static Bool 226HandleNoAction( XkbDescPtr xkb, 227 XkbAnyAction * action, 228 unsigned field, 229 ExprDef * array_ndx, 230 ExprDef * value) 231{ 232 return ReportIllegal(action->type,field); 233} 234 235static Bool 236CheckLatchLockFlags( unsigned action, 237 unsigned field, 238 ExprDef * value, 239 unsigned * flags_inout) 240{ 241unsigned tmp; 242ExprResult result; 243 244 if (field==F_ClearLocks) tmp= XkbSA_ClearLocks; 245 else if (field==F_LatchToLock) tmp= XkbSA_LatchToLock; 246 else return False; /* WSGO! */ 247 if (!ExprResolveBoolean(value,&result,NULL,NULL)) 248 return ReportMismatch(action,field,"boolean"); 249 if (result.uval) *flags_inout|= tmp; 250 else *flags_inout&= ~tmp; 251 return True; 252} 253 254static Bool 255CheckModifierField( XkbDescPtr xkb, 256 unsigned action, 257 ExprDef * value, 258 unsigned * flags_inout, 259 unsigned * mods_rtrn) 260{ 261ExprResult rtrn; 262 263 if (value->op==ExprIdent) { 264 register char *valStr; 265 valStr= XkbAtomGetString(NULL,value->value.str); 266 if (valStr&&((uStrCaseCmp(valStr,"usemodmapmods")==0)|| 267 (uStrCaseCmp(valStr,"modmapmods")==0))) { 268 269 *mods_rtrn= 0; 270 *flags_inout|= XkbSA_UseModMapMods; 271 return True; 272 } 273 } 274 if (!ExprResolveModMask(value,&rtrn,LookupVModMask,(XPointer)xkb)) 275 return ReportMismatch(action,F_Modifiers,"modifier mask"); 276 *mods_rtrn= rtrn.uval; 277 *flags_inout&= ~XkbSA_UseModMapMods; 278 return True; 279} 280 281static Bool 282HandleSetLatchMods( XkbDescPtr xkb, 283 XkbAnyAction * action, 284 unsigned field, 285 ExprDef * array_ndx, 286 ExprDef * value) 287{ 288XkbModAction * act; 289unsigned rtrn; 290unsigned t1,t2; 291 292 act= (XkbModAction *)action; 293 if (array_ndx!=NULL) { 294 switch (field) { 295 case F_ClearLocks: case F_LatchToLock: 296 case F_Modifiers: 297 return ReportActionNotArray(action->type,field); 298 } 299 } 300 switch (field) { 301 case F_ClearLocks: 302 case F_LatchToLock: 303 rtrn= act->flags; 304 if (CheckLatchLockFlags(action->type,field,value,&rtrn)) { 305 act->flags= rtrn; 306 return True; 307 } 308 return False; 309 case F_Modifiers: 310 t1= act->flags; 311 if (CheckModifierField(xkb,action->type,value,&t1,&t2)) { 312 act->flags= t1; 313 act->real_mods= act->mask= (t2&0xff); 314 t2= (t2>>8)&0xffff; 315 XkbSetModActionVMods(act,t2); 316 return True; 317 } 318 return False; 319 } 320 return ReportIllegal(action->type,field); 321} 322 323static Bool 324HandleLockMods( XkbDescPtr xkb, 325 XkbAnyAction * action, 326 unsigned field, 327 ExprDef * array_ndx, 328 ExprDef * value) 329{ 330XkbModAction * act; 331unsigned t1,t2; 332 333 act= (XkbModAction *)action; 334 if ((array_ndx!=NULL)&&(field==F_Modifiers)) 335 return ReportActionNotArray(action->type,field); 336 switch (field) { 337 case F_Modifiers: 338 t1= act->flags; 339 if (CheckModifierField(xkb,action->type,value,&t1,&t2)) { 340 act->flags= t1; 341 act->real_mods= act->mask= (t2&0xff); 342 t2= (t2>>8)&0xffff; 343 XkbSetModActionVMods(act,t2); 344 return True; 345 } 346 return False; 347 } 348 return ReportIllegal(action->type,field); 349} 350 351static LookupEntry groupNames[] = { 352 { "group1", 1 }, 353 { "group2", 2 }, 354 { "group3", 3 }, 355 { "group4", 4 }, 356 { "group5", 5 }, 357 { "group6", 6 }, 358 { "group7", 7 }, 359 { "group8", 8 }, 360 { NULL, 0 }, 361}; 362 363static Bool 364CheckGroupField( unsigned action, 365 ExprDef * value, 366 unsigned * flags_inout, 367 int * grp_rtrn) 368{ 369ExprDef * spec; 370ExprResult rtrn; 371 372 if ((value->op==OpNegate)||(value->op==OpUnaryPlus)) { 373 *flags_inout&= ~XkbSA_GroupAbsolute; 374 spec= value->value.child; 375 } 376 else { 377 *flags_inout|= XkbSA_GroupAbsolute; 378 spec= value; 379 } 380 381 if (!ExprResolveInteger(spec,&rtrn,SimpleLookup,(XPointer)groupNames)) 382 return ReportMismatch(action,F_Group,"integer (range 1..8)"); 383 if ((rtrn.ival<1)||(rtrn.ival>XkbNumKbdGroups)) { 384 ERROR2("Illegal group %d (must be in the range 1..%d)\n",rtrn.ival, 385 XkbNumKbdGroups); 386 ACTION1("Action %s definition ignored\n", 387 XkbActionTypeText(action,XkbMessage)); 388 return False; 389 } 390 if (value->op==OpNegate) *grp_rtrn= -rtrn.ival; 391 else if (value->op==OpUnaryPlus) *grp_rtrn= rtrn.ival; 392 else *grp_rtrn= rtrn.ival-1; 393 return True; 394} 395 396static Bool 397HandleSetLatchGroup( XkbDescPtr xkb, 398 XkbAnyAction * action, 399 unsigned field, 400 ExprDef * array_ndx, 401 ExprDef * value) 402{ 403XkbGroupAction * act; 404unsigned rtrn; 405unsigned t1; 406int t2; 407 408 act= (XkbGroupAction *)action; 409 if (array_ndx!=NULL) { 410 switch (field) { 411 case F_ClearLocks: case F_LatchToLock: 412 case F_Group: 413 return ReportActionNotArray(action->type,field); 414 } 415 } 416 switch (field) { 417 case F_ClearLocks: 418 case F_LatchToLock: 419 rtrn= act->flags; 420 if (CheckLatchLockFlags(action->type,field,value,&rtrn)) { 421 act->flags= rtrn; 422 return True; 423 } 424 return False; 425 case F_Group: 426 t1= act->flags; 427 if (CheckGroupField(action->type,value,&t1,&t2)) { 428 act->flags= t1; 429 XkbSASetGroup(act,t2); 430 return True; 431 } 432 return False; 433 } 434 return ReportIllegal(action->type,field); 435} 436 437static Bool 438HandleLockGroup( XkbDescPtr xkb, 439 XkbAnyAction * action, 440 unsigned field, 441 ExprDef * array_ndx, 442 ExprDef * value) 443{ 444XkbGroupAction * act; 445unsigned t1; 446int t2; 447 448 act= (XkbGroupAction *)action; 449 if ((array_ndx!=NULL) && (field==F_Group)) 450 return ReportActionNotArray(action->type,field); 451 if (field==F_Group) { 452 t1= act->flags; 453 if (CheckGroupField(action->type,value,&t1,&t2)) { 454 act->flags= t1; 455 XkbSASetGroup(act,t2); 456 return True; 457 } 458 return False; 459 } 460 return ReportIllegal(action->type,field); 461} 462 463static Bool 464HandleMovePtr( XkbDescPtr xkb, 465 XkbAnyAction * action, 466 unsigned field, 467 ExprDef * array_ndx, 468 ExprDef * value) 469{ 470ExprResult rtrn; 471XkbPtrAction * act; 472Bool absolute; 473 474 act= (XkbPtrAction *)action; 475 if ((array_ndx!=NULL)&&((field==F_X)||(field==F_Y))) 476 return ReportActionNotArray(action->type,field); 477 478 if ((field==F_X)||(field==F_Y)) { 479 if ((value->op==OpNegate)||(value->op==OpUnaryPlus)) 480 absolute= False; 481 else absolute= True; 482 if (!ExprResolveInteger(value,&rtrn,NULL,NULL)) 483 return ReportMismatch(action->type,field,"integer"); 484 if (field==F_X) { 485 if (absolute) 486 act->flags|= XkbSA_MoveAbsoluteX; 487 XkbSetPtrActionX(act,rtrn.ival); 488 } 489 else { 490 if (absolute) 491 act->flags|= XkbSA_MoveAbsoluteY; 492 XkbSetPtrActionY(act,rtrn.ival); 493 } 494 return True; 495 } 496 else if (field==F_Accel) { 497 if (!ExprResolveBoolean(value,&rtrn,NULL,NULL)) 498 return ReportMismatch(action->type,field,"boolean"); 499 if (rtrn.uval) act->flags&= ~XkbSA_NoAcceleration; 500 else act->flags|= XkbSA_NoAcceleration; 501 } 502 return ReportIllegal(action->type,field); 503} 504 505static LookupEntry btnNames[] = { 506 { "button1", 1 }, 507 { "button2", 2 }, 508 { "button3", 3 }, 509 { "button4", 4 }, 510 { "button5", 5 }, 511 { "default", 0 }, 512 { NULL, 0 } 513}; 514 515static LookupEntry lockWhich[] = { 516 { "both", 0 }, 517 { "lock", XkbSA_LockNoUnlock }, 518 { "neither", (XkbSA_LockNoLock|XkbSA_LockNoUnlock) }, 519 { "unlock", XkbSA_LockNoLock }, 520 { NULL, 0 } 521}; 522 523static Bool 524HandlePtrBtn( XkbDescPtr xkb, 525 XkbAnyAction * action, 526 unsigned field, 527 ExprDef * array_ndx, 528 ExprDef * value) 529{ 530ExprResult rtrn; 531XkbPtrBtnAction * act; 532 533 act= (XkbPtrBtnAction *)action; 534 if (field==F_Button) { 535 if (array_ndx!=NULL) 536 return ReportActionNotArray(action->type,field); 537 if (!ExprResolveInteger(value,&rtrn,SimpleLookup,(XPointer)btnNames)) 538 return ReportMismatch(action->type,field,"integer (range 1..5)"); 539 if ((rtrn.ival<0)||(rtrn.ival>5)) { 540 ERROR("Button must specify default or be in the range 1..5\n"); 541 ACTION1("Illegal button value %d ignored\n",rtrn.ival); 542 return False; 543 } 544 act->button= rtrn.ival; 545 return True; 546 } 547 else if ((action->type==XkbSA_LockPtrBtn)&&(field==F_Affect)) { 548 if (array_ndx!=NULL) 549 return ReportActionNotArray(action->type,field); 550 if (!ExprResolveEnum(value,&rtrn,lockWhich)) 551 return ReportMismatch(action->type,field,"lock or unlock"); 552 act->flags&= ~(XkbSA_LockNoLock|XkbSA_LockNoUnlock); 553 act->flags|= rtrn.ival; 554 return True; 555 } 556 else if (field==F_Count) { 557 if (array_ndx!=NULL) 558 return ReportActionNotArray(action->type,field); 559 if (!ExprResolveInteger(value,&rtrn,SimpleLookup,(XPointer)btnNames)) 560 return ReportMismatch(action->type,field,"integer"); 561 if ((rtrn.ival<0)||(rtrn.ival>255)) { 562 ERROR("The count field must have a value in the range 0..255\n"); 563 ACTION1("Illegal count %d ignored\n",rtrn.ival); 564 return False; 565 } 566 act->count= rtrn.ival; 567 return True; 568 } 569 return ReportIllegal(action->type,field); 570} 571 572static LookupEntry ptrDflts[] = { 573 { "dfltbtn", XkbSA_AffectDfltBtn }, 574 { "defaultbutton", XkbSA_AffectDfltBtn }, 575 { "button", XkbSA_AffectDfltBtn }, 576 { NULL, 0 } 577}; 578 579static Bool 580HandleSetPtrDflt( XkbDescPtr xkb, 581 XkbAnyAction * action, 582 unsigned field, 583 ExprDef * array_ndx, 584 ExprDef * value) 585{ 586ExprResult rtrn; 587XkbPtrDfltAction * act; 588 589 act= (XkbPtrDfltAction *)action; 590 if (field==F_Affect) { 591 if (array_ndx!=NULL) 592 return ReportActionNotArray(action->type,field); 593 if (!ExprResolveEnum(value,&rtrn,ptrDflts)) 594 return ReportMismatch(action->type,field,"pointer component"); 595 act->affect= rtrn.uval; 596 return True; 597 } 598 else if ((field==F_Button)||(field==F_Value)) { 599 ExprDef *btn; 600 if (array_ndx!=NULL) 601 return ReportActionNotArray(action->type,field); 602 if ((value->op==OpNegate)||(value->op==OpUnaryPlus)) { 603 act->flags&= ~XkbSA_DfltBtnAbsolute; 604 btn= value->value.child; 605 } 606 else { 607 act->flags|= XkbSA_DfltBtnAbsolute; 608 btn= value; 609 } 610 611 if (!ExprResolveInteger(btn,&rtrn,SimpleLookup,(XPointer)btnNames)) 612 return ReportMismatch(action->type,field,"integer (range 1..5)"); 613 if ((rtrn.ival<0)||(rtrn.ival>5)) { 614 ERROR("New default button value must be in the range 1..5\n"); 615 ACTION1("Illegal default button value %d ignored\n",rtrn.ival); 616 return False; 617 } 618 if (rtrn.ival==0) { 619 ERROR("Cannot set default pointer button to \"default\"\n"); 620 ACTION("Illegal default button setting ignored\n"); 621 return False; 622 } 623 if (value->op==OpNegate) 624 XkbSASetPtrDfltValue(act,-rtrn.ival); 625 else XkbSASetPtrDfltValue(act,rtrn.ival); 626 return True; 627 } 628 return ReportIllegal(action->type,field); 629} 630 631static LookupEntry isoNames[] = { 632 { "mods", XkbSA_ISONoAffectMods }, 633 { "modifiers", XkbSA_ISONoAffectMods }, 634 { "group", XkbSA_ISONoAffectGroup }, 635 { "groups", XkbSA_ISONoAffectGroup }, 636 { "ptr", XkbSA_ISONoAffectPtr }, 637 { "pointer", XkbSA_ISONoAffectPtr }, 638 { "ctrls", XkbSA_ISONoAffectCtrls }, 639 { "controls", XkbSA_ISONoAffectCtrls }, 640 { "all", ~((unsigned)0) }, 641 { "none", 0 }, 642 { NULL, 0 }, 643}; 644 645static Bool 646HandleISOLock( XkbDescPtr xkb, 647 XkbAnyAction * action, 648 unsigned field, 649 ExprDef * array_ndx, 650 ExprDef * value) 651{ 652ExprResult rtrn; 653XkbISOAction * act; 654unsigned flags,mods; 655int group; 656 657 act= (XkbISOAction *)action; 658 switch (field) { 659 case F_Modifiers: 660 if (array_ndx!=NULL) 661 return ReportActionNotArray(action->type,field); 662 flags= act->flags; 663 if (CheckModifierField(xkb,action->type,value,&flags,&mods)) { 664 act->flags= flags&(~XkbSA_ISODfltIsGroup); 665 act->real_mods= mods&0xff; 666 mods= (mods>>8)&0xff; 667 XkbSetModActionVMods(act,mods); 668 return True; 669 } 670 return False; 671 case F_Group: 672 if (array_ndx!=NULL) 673 return ReportActionNotArray(action->type,field); 674 flags= act->flags; 675 if (CheckGroupField(action->type,value,&flags,&group)) { 676 act->flags= flags|XkbSA_ISODfltIsGroup; 677 XkbSASetGroup(act,group); 678 return True; 679 } 680 return False; 681 case F_Affect: 682 if (array_ndx!=NULL) 683 return ReportActionNotArray(action->type,field); 684 if (!ExprResolveMask(value,&rtrn,SimpleLookup,(XPointer)isoNames)) 685 return ReportMismatch(action->type,field,"keyboard component"); 686 act->affect= (~rtrn.uval)&XkbSA_ISOAffectMask; 687 return True; 688 } 689 return ReportIllegal(action->type,field); 690} 691 692static Bool 693HandleSwitchScreen( XkbDescPtr xkb, 694 XkbAnyAction * action, 695 unsigned field, 696 ExprDef * array_ndx, 697 ExprDef * value) 698{ 699ExprResult rtrn; 700XkbSwitchScreenAction * act; 701 702 act= (XkbSwitchScreenAction *)action; 703 if (field==F_Screen) { 704 ExprDef *scrn; 705 if (array_ndx!=NULL) 706 return ReportActionNotArray(action->type,field); 707 if ((value->op==OpNegate)||(value->op==OpUnaryPlus)) { 708 act->flags&= ~XkbSA_SwitchAbsolute; 709 scrn= value->value.child; 710 } 711 else { 712 act->flags|= XkbSA_SwitchAbsolute; 713 scrn= value; 714 } 715 716 if (!ExprResolveInteger(scrn,&rtrn,NULL,NULL)) 717 return ReportMismatch(action->type,field,"integer (0..255)"); 718 if ((rtrn.ival<0)||(rtrn.ival>255)) { 719 ERROR("Screen index must be in the range 1..255\n"); 720 ACTION1("Illegal screen value %d ignored\n",rtrn.ival); 721 return False; 722 } 723 if (value->op==OpNegate) 724 XkbSASetScreen(act,-rtrn.ival); 725 else XkbSASetScreen(act,rtrn.ival); 726 return True; 727 } 728 else if (field==F_Same) { 729 if (array_ndx!=NULL) 730 return ReportActionNotArray(action->type,field); 731 if (!ExprResolveBoolean(value,&rtrn,NULL,NULL)) 732 return ReportMismatch(action->type,field,"boolean"); 733 if (rtrn.uval) act->flags&= ~XkbSA_SwitchApplication; 734 else act->flags|= XkbSA_SwitchApplication; 735 return True; 736 } 737 return ReportIllegal(action->type,field); 738} 739 740LookupEntry ctrlNames[]= { 741 { "repeatkeys", XkbRepeatKeysMask }, 742 { "repeat", XkbRepeatKeysMask }, 743 { "autorepeat", XkbRepeatKeysMask }, 744 { "slowkeys", XkbSlowKeysMask }, 745 { "bouncekeys", XkbBounceKeysMask }, 746 { "stickykeys", XkbStickyKeysMask }, 747 { "mousekeys", XkbMouseKeysMask }, 748 { "mousekeysaccel", XkbMouseKeysAccelMask }, 749 { "accessxkeys", XkbAccessXKeysMask }, 750 { "accessxtimeout", XkbAccessXTimeoutMask }, 751 { "accessxfeedback", XkbAccessXFeedbackMask }, 752 { "audiblebell", XkbAudibleBellMask }, 753 { "overlay1", XkbOverlay1Mask }, 754 { "overlay2", XkbOverlay2Mask }, 755 { "ignoregrouplock", XkbIgnoreGroupLockMask }, 756 { "all", XkbAllBooleanCtrlsMask }, 757 { "none", 0 }, 758 { NULL, 0 } 759}; 760 761static Bool 762HandleSetLockControls( XkbDescPtr xkb, 763 XkbAnyAction * action, 764 unsigned field, 765 ExprDef * array_ndx, 766 ExprDef * value) 767{ 768ExprResult rtrn; 769XkbCtrlsAction * act; 770 771 act= (XkbCtrlsAction *)action; 772 if (field==F_Controls) { 773 if (array_ndx!=NULL) 774 return ReportActionNotArray(action->type,field); 775 if (!ExprResolveMask(value,&rtrn,SimpleLookup,(XPointer)ctrlNames)) 776 return ReportMismatch(action->type,field,"controls mask"); 777 XkbActionSetCtrls(act,rtrn.uval); 778 return True; 779 } 780 return ReportIllegal(action->type,field); 781} 782 783static LookupEntry evNames[]= { 784 { "press", XkbSA_MessageOnPress }, 785 { "keypress", XkbSA_MessageOnPress }, 786 { "release", XkbSA_MessageOnRelease }, 787 { "keyrelease", XkbSA_MessageOnRelease }, 788 { "all", XkbSA_MessageOnPress|XkbSA_MessageOnRelease }, 789 { "none", 0 }, 790 { NULL, 0 } 791}; 792 793static Bool 794HandleActionMessage( XkbDescPtr xkb, 795 XkbAnyAction * action, 796 unsigned field, 797 ExprDef * array_ndx, 798 ExprDef * value) 799{ 800ExprResult rtrn; 801XkbMessageAction * act; 802 803 act= (XkbMessageAction *)action; 804 switch (field) { 805 case F_Report: 806 if (array_ndx!=NULL) 807 return ReportActionNotArray(action->type,field); 808 if (!ExprResolveMask(value,&rtrn,SimpleLookup,(XPointer)evNames)) 809 return ReportMismatch(action->type,field,"key event mask"); 810 act->flags&= ~(XkbSA_MessageOnPress|XkbSA_MessageOnRelease); 811 act->flags= rtrn.uval&(XkbSA_MessageOnPress|XkbSA_MessageOnRelease); 812 return True; 813 case F_GenKeyEvent: 814 if (array_ndx!=NULL) 815 return ReportActionNotArray(action->type,field); 816 if (!ExprResolveBoolean(value,&rtrn,NULL,NULL)) 817 return ReportMismatch(action->type,field,"boolean"); 818 if (rtrn.uval) act->flags|= XkbSA_MessageGenKeyEvent; 819 else act->flags&= ~XkbSA_MessageGenKeyEvent; 820 return True; 821 case F_Data: 822 if (array_ndx==NULL) { 823 if (!ExprResolveString(value,&rtrn,NULL,NULL)) 824 return ReportMismatch(action->type,field,"string"); 825 else { 826 int len= strlen(rtrn.str); 827 if ((len<1)||(len>6)) { 828 WARN("An action message can hold only 6 bytes\n"); 829 ACTION1("Extra %d bytes ignored\n",len-6); 830 } 831 strncpy((char *)act->message,rtrn.str,6); 832 } 833 return True; 834 } 835 else { 836 unsigned ndx; 837 if (!ExprResolveInteger(array_ndx,&rtrn,NULL,NULL)) { 838 ERROR("Array subscript must be integer\n"); 839 ACTION("Illegal subscript ignored\n"); 840 return False; 841 } 842 ndx= rtrn.uval; 843 if (ndx>5) { 844 ERROR("An action message is at most 6 bytes long\n"); 845 ACTION1("Attempt to use data[%d] ignored\n",ndx); 846 return False; 847 } 848 if (!ExprResolveInteger(value,&rtrn,NULL,NULL)) 849 return ReportMismatch(action->type,field,"integer"); 850 if ((rtrn.ival<0)||(rtrn.ival>255)) { 851 ERROR("Message data must be in the range 0..255\n"); 852 ACTION1("Illegal datum %d ignored\n",rtrn.ival); 853 return False; 854 } 855 act->message[ndx]= rtrn.uval; 856 } 857 return True; 858 } 859 return ReportIllegal(action->type,field); 860} 861 862static Bool 863HandleRedirectKey( XkbDescPtr xkb, 864 XkbAnyAction * action, 865 unsigned field, 866 ExprDef * array_ndx, 867 ExprDef * value) 868{ 869ExprResult rtrn; 870XkbRedirectKeyAction * act; 871unsigned t1,t2,vmods,vmask; 872unsigned long tmp; 873 874 if (array_ndx!=NULL) 875 return ReportActionNotArray(action->type,field); 876 877 act= (XkbRedirectKeyAction *)action; 878 switch (field) { 879 case F_Keycode: 880 if (!ExprResolveKeyName(value,&rtrn,NULL,NULL)) 881 return ReportMismatch(action->type,field,"key name"); 882 tmp= KeyNameToLong(rtrn.keyName.name); 883 if (!FindNamedKey(xkb,tmp,&t1,True,CreateKeyNames(xkb),0)) { 884 return ReportNotFound(action->type,field,"Key", 885 XkbKeyNameText(rtrn.keyName.name,XkbMessage)); 886 } 887 act->new_key= t1; 888 return True; 889 case F_ModsToClear: 890 case F_Modifiers: 891 t1= 0; 892 if (CheckModifierField(xkb,action->type,value,&t1,&t2)) { 893 act->mods_mask|= (t2&0xff); 894 if (field==F_Modifiers) 895 act->mods|= (t2&0xff); 896 else act->mods&= ~(t2&0xff); 897 898 t2= (t2>>8)&0xffff; 899 vmods= XkbSARedirectVMods(act); 900 vmask= XkbSARedirectVModsMask(act); 901 vmask|= t2; 902 if (field==F_Modifiers) 903 vmods|= t2; 904 else vmods&= ~t2; 905 XkbSARedirectSetVMods(act,vmods); 906 XkbSARedirectSetVModsMask(act,vmask); 907 return True; 908 } 909 return True; 910 } 911 return ReportIllegal(action->type,field); 912} 913 914static Bool 915HandleDeviceBtn( XkbDescPtr xkb, 916 XkbAnyAction * action, 917 unsigned field, 918 ExprDef * array_ndx, 919 ExprDef * value) 920{ 921ExprResult rtrn; 922XkbDeviceBtnAction * act; 923 924 act= (XkbDeviceBtnAction *)action; 925 if (field==F_Button) { 926 if (array_ndx!=NULL) 927 return ReportActionNotArray(action->type,field); 928 if (!ExprResolveInteger(value,&rtrn,NULL,NULL)) 929 return ReportMismatch(action->type,field,"integer (range 1..255)"); 930 if ((rtrn.ival<0)||(rtrn.ival>255)) { 931 ERROR("Button must specify default or be in the range 1..255\n"); 932 ACTION1("Illegal button value %d ignored\n",rtrn.ival); 933 return False; 934 } 935 act->button= rtrn.ival; 936 return True; 937 } 938 else if ((action->type==XkbSA_LockDeviceBtn)&&(field==F_Affect)) { 939 if (array_ndx!=NULL) 940 return ReportActionNotArray(action->type,field); 941 if (!ExprResolveEnum(value,&rtrn,lockWhich)) 942 return ReportMismatch(action->type,field,"lock or unlock"); 943 act->flags&= ~(XkbSA_LockNoLock|XkbSA_LockNoUnlock); 944 act->flags|= rtrn.ival; 945 return True; 946 } 947 else if (field==F_Count) { 948 if (array_ndx!=NULL) 949 return ReportActionNotArray(action->type,field); 950 if (!ExprResolveInteger(value,&rtrn,SimpleLookup,(XPointer)btnNames)) 951 return ReportMismatch(action->type,field,"integer"); 952 if ((rtrn.ival<0)||(rtrn.ival>255)) { 953 ERROR("The count field must have a value in the range 0..255\n"); 954 ACTION1("Illegal count %d ignored\n",rtrn.ival); 955 return False; 956 } 957 act->count= rtrn.ival; 958 return True; 959 } 960 else if (field==F_Device) { 961 if (array_ndx!=NULL) 962 return ReportActionNotArray(action->type,field); 963 if (!ExprResolveInteger(value,&rtrn,NULL,NULL)) 964 return ReportMismatch(action->type,field,"integer (range 1..255)"); 965 if ((rtrn.ival<0)||(rtrn.ival>255)) { 966 ERROR("Device must specify default or be in the range 1..255\n"); 967 ACTION1("Illegal device value %d ignored\n",rtrn.ival); 968 return False; 969 } 970 act->device= rtrn.ival; 971 return True; 972 } 973 return ReportIllegal(action->type,field); 974} 975 976static Bool 977HandleDeviceValuator( XkbDescPtr xkb, 978 XkbAnyAction * action, 979 unsigned field, 980 ExprDef * array_ndx, 981 ExprDef * value) 982{ 983#if 0 984ExprResult rtrn; 985XkbDeviceValuatorAction * act; 986 987 act= (XkbDeviceValuatorAction *)action; 988 /* XXX - Not yet implemented */ 989#endif 990 return False; 991} 992 993static Bool 994HandlePrivate( XkbDescPtr xkb, 995 XkbAnyAction * action, 996 unsigned field, 997 ExprDef * array_ndx, 998 ExprDef * value) 999{ 1000ExprResult rtrn; 1001 1002 switch (field) { 1003 case F_Type: 1004 if (!ExprResolveInteger(value,&rtrn,NULL,NULL)) 1005 return ReportMismatch(PrivateAction,field,"integer"); 1006 if ((rtrn.ival<0)||(rtrn.ival>255)) { 1007 ERROR("Private action type must be in the range 0..255\n"); 1008 ACTION1("Illegal type %d ignored\n",rtrn.ival); 1009 return False; 1010 } 1011 action->type= rtrn.uval; 1012 return True; 1013 case F_Data: 1014 if (array_ndx==NULL) { 1015 if (!ExprResolveString(value,&rtrn,NULL,NULL)) 1016 return ReportMismatch(action->type,field,"string"); 1017 else { 1018 int len= strlen(rtrn.str); 1019 if ((len<1)||(len>7)) { 1020 WARN("A private action has 7 data bytes\n"); 1021 ACTION1("Extra %d bytes ignored\n",len-6); 1022 return False; 1023 } 1024 strncpy((char *)action->data,rtrn.str,7); 1025 } 1026 return True; 1027 } 1028 else { 1029 unsigned ndx; 1030 if (!ExprResolveInteger(array_ndx,&rtrn,NULL,NULL)) { 1031 ERROR("Array subscript must be integer\n"); 1032 ACTION("Illegal subscript ignored\n"); 1033 return False; 1034 } 1035 ndx= rtrn.uval; 1036 if (ndx>6) { 1037 ERROR("The data for a private action is 7 bytes long\n"); 1038 ACTION1("Attempt to use data[%d] ignored\n",ndx); 1039 return False; 1040 } 1041 if (!ExprResolveInteger(value,&rtrn,NULL,NULL)) 1042 return ReportMismatch(action->type,field,"integer"); 1043 if ((rtrn.ival<0)||(rtrn.ival>255)) { 1044 ERROR("All data for a private action must be 0..255\n"); 1045 ACTION1("Illegal datum %d ignored\n",rtrn.ival); 1046 return False; 1047 } 1048 action->data[ndx]= rtrn.uval; 1049 return True; 1050 } 1051 } 1052 return ReportIllegal(PrivateAction,field); 1053} 1054 1055typedef Bool (*actionHandler)( 1056 XkbDescPtr /* xkb */, 1057 XkbAnyAction * /* action */, 1058 unsigned /* field */, 1059 ExprDef * /* array_ndx */, 1060 ExprDef * /* value */ 1061); 1062 1063static actionHandler handleAction[XkbSA_NumActions+1] = { 1064 HandleNoAction /* NoAction */, 1065 HandleSetLatchMods /* SetMods */, 1066 HandleSetLatchMods /* LatchMods */, 1067 HandleLockMods /* LockMods */, 1068 HandleSetLatchGroup /* SetGroup */, 1069 HandleSetLatchGroup /* LatchGroup */, 1070 HandleLockGroup /* LockGroup */, 1071 HandleMovePtr /* MovePtr */, 1072 HandlePtrBtn /* PtrBtn */, 1073 HandlePtrBtn /* LockPtrBtn */, 1074 HandleSetPtrDflt /* SetPtrDflt */, 1075 HandleISOLock /* ISOLock */, 1076 HandleNoAction /* Terminate */, 1077 HandleSwitchScreen /* SwitchScreen */, 1078 HandleSetLockControls /* SetControls */, 1079 HandleSetLockControls /* LockControls */, 1080 HandleActionMessage /* ActionMessage*/, 1081 HandleRedirectKey /* RedirectKey */, 1082 HandleDeviceBtn /* DeviceBtn */, 1083 HandleDeviceBtn /* LockDeviceBtn*/, 1084 HandleDeviceValuator /* DeviceValuatr*/, 1085 HandlePrivate /* Private */ 1086}; 1087 1088/***====================================================================***/ 1089 1090static void 1091ApplyActionFactoryDefaults(XkbAction *action) 1092{ 1093 if (action->type==XkbSA_SetPtrDflt) { /* increment default button */ 1094 action->dflt.affect= XkbSA_AffectDfltBtn; 1095 action->dflt.flags= 0; 1096 XkbSASetPtrDfltValue(&action->dflt,1); 1097 } 1098 else if (action->type==XkbSA_ISOLock) { 1099 action->iso.real_mods= LockMask; 1100 } 1101 return; 1102} 1103 1104 1105int 1106HandleActionDef( ExprDef * def, 1107 XkbDescPtr xkb, 1108 XkbAnyAction * action, 1109 unsigned mergeMode, 1110 ActionInfo * info) 1111{ 1112ExprDef * arg; 1113register char * str; 1114unsigned tmp,hndlrType; 1115 1116 if (!actionsInitialized) 1117 ActionsInit(); 1118 1119 if (def->op!=ExprActionDecl) { 1120 ERROR1("Expected an action definition, found %s\n",exprOpText(def->op)); 1121 return False; 1122 } 1123 str= XkbAtomGetString(NULL,def->value.action.name); 1124 if (!str) { 1125 WSGO("Missing name in action definition!!\n"); 1126 return False; 1127 } 1128 if (!stringToAction(str,&tmp)) { 1129 ERROR1("Unknown action %s\n",str); 1130 return False; 1131 } 1132 action->type= hndlrType= tmp; 1133 if (action->type!=XkbSA_NoAction) { 1134 ApplyActionFactoryDefaults((XkbAction *)action); 1135 while (info) { 1136 if ((info->action==XkbSA_NoAction)||(info->action==hndlrType)) { 1137 if (!(*handleAction[hndlrType])(xkb,action, 1138 info->field,info->array_ndx, 1139 info->value)) { 1140 return False; 1141 } 1142 } 1143 info= info->next; 1144 } 1145 } 1146 for (arg=def->value.action.args;arg!=NULL;arg=(ExprDef*)arg->common.next) { 1147 ExprDef *field,*value,*arrayRtrn; 1148 ExprResult elemRtrn,fieldRtrn; 1149 unsigned fieldNdx; 1150 1151 if (arg->op==OpAssign) { 1152 field= arg->value.binary.left; 1153 value= arg->value.binary.right; 1154 } 1155 else { 1156 if ((arg->op==OpNot)||(arg->op==OpInvert)) { 1157 field= arg->value.child; 1158 value= &constFalse; 1159 } 1160 else { 1161 field= arg; 1162 value= &constTrue; 1163 } 1164 } 1165 if (!ExprResolveLhs(field,&elemRtrn,&fieldRtrn,&arrayRtrn)) 1166 return False; /* internal error -- already reported */ 1167 1168 if (elemRtrn.str!=NULL) { 1169 ERROR("Cannot change defaults in an action definition\n"); 1170 ACTION2("Ignoring attempt to change %s.%s\n",elemRtrn.str, 1171 fieldRtrn.str); 1172 return False; 1173 } 1174 if (!stringToField(fieldRtrn.str,&fieldNdx)) { 1175 ERROR1("Unknown field name %s\n",uStringText(fieldRtrn.str)); 1176 return False; 1177 } 1178 if (!(*handleAction[hndlrType])(xkb,action,fieldNdx,arrayRtrn,value)) { 1179 return False; 1180 } 1181 } 1182 return True; 1183} 1184 1185/***====================================================================***/ 1186 1187int 1188SetActionField( XkbDescPtr xkb, 1189 char * elem, 1190 char * field, 1191 ExprDef * array_ndx, 1192 ExprDef * value, 1193 ActionInfo ** info_rtrn) 1194{ 1195ActionInfo *new,*old; 1196 1197 if (!actionsInitialized) 1198 ActionsInit(); 1199 1200 new= uTypedAlloc(ActionInfo); 1201 if (new==NULL) { 1202 WSGO("Couldn't allocate space for action default\n"); 1203 return False; 1204 } 1205 if (uStrCaseCmp(elem,"action")==0) 1206 new->action= XkbSA_NoAction; 1207 else { 1208 if (!stringToAction(elem,&new->action)) 1209 return False; 1210 if (new->action==XkbSA_NoAction) { 1211 ERROR1("\"%s\" is not a valid field in a NoAction action\n",field); 1212 return False; 1213 } 1214 } 1215 if (!stringToField(field,&new->field)) { 1216 ERROR1("\"%s\" is not a legal field name\n",field); 1217 return False; 1218 } 1219 new->array_ndx= array_ndx; 1220 new->value= value; 1221 new->next= NULL; 1222 old= *info_rtrn; 1223 while ((old)&&(old->next)) 1224 old= old->next; 1225 if (old==NULL) *info_rtrn= new; 1226 else old->next= new; 1227 return True; 1228} 1229 1230/***====================================================================***/ 1231 1232void 1233ActionsInit(void) 1234{ 1235 if (!actionsInitialized) { 1236 bzero((char *)&constTrue,sizeof(constTrue)); 1237 bzero((char *)&constFalse,sizeof(constFalse)); 1238 constTrue.common.stmtType= StmtExpr; 1239 constTrue.common.next= NULL; 1240 constTrue.op= ExprIdent; 1241 constTrue.type= TypeBoolean; 1242 constTrue.value.str= XkbInternAtom(NULL,"true",False); 1243 constFalse.common.stmtType= StmtExpr; 1244 constFalse.common.next= NULL; 1245 constFalse.op= ExprIdent; 1246 constFalse.type= TypeBoolean; 1247 constFalse.value.str= XkbInternAtom(NULL,"false",False); 1248 actionsInitialized= 1; 1249 } 1250 return; 1251} 1252 1253