xkbmisc.c revision 8c9fbc29
1/* $Xorg: xkbmisc.c,v 1.4 2000/08/17 19:46:44 cpqbld Exp $ */ 2/************************************************************ 3 Copyright (c) 1995 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/lib/xkbfile/xkbmisc.c,v 1.7 2003/07/16 02:31:10 dawes Exp $ */ 28 29#ifdef HAVE_DIX_CONFIG_H 30#include <dix-config.h> 31#elif defined(HAVE_CONFIG_H) 32#include <config.h> 33#endif 34 35#include <stdio.h> 36#include <ctype.h> 37#include <stdlib.h> 38 39#include <X11/Xos.h> 40#include <X11/Xfuncs.h> 41 42#ifndef XKB_IN_SERVER 43 44#include <X11/Xlib.h> 45#include <X11/keysym.h> 46#include <X11/XKBlib.h> 47#include <X11/extensions/XKBgeom.h> 48#include "XKMformat.h" 49#include "XKBfileInt.h" 50 51#else 52 53#include <X11/X.h> 54#define NEED_EVENTS 55#include <X11/keysym.h> 56#include <X11/Xproto.h> 57#include "misc.h" 58#include "inputstr.h" 59#include "dix.h" 60#include <X11/extensions/XKBstr.h> 61#define XKBSRV_NEED_FILE_FUNCS 1 62#include <X11/extensions/XKBsrv.h> 63#include <X11/extensions/XKBgeom.h> 64#include "xkb.h" 65 66#endif 67 68unsigned 69_XkbKSCheckCase(KeySym ks) 70{ 71unsigned set,rtrn; 72 73 set= (ks & (~0xff)) >> 8; 74 rtrn= 0; 75 switch (set) { 76 case 0: /* latin 1 */ 77 if (((ks>=XK_A)&&(ks<=XK_Z))|| 78 ((ks>=XK_Agrave)&&(ks<=XK_THORN)&&(ks!=XK_multiply))) { 79 rtrn|= _XkbKSUpper; 80 } 81 if (((ks>=XK_a)&&(ks<=XK_z))|| 82 ((ks>=XK_agrave)&&(ks<=XK_ydiaeresis))) { 83 rtrn|= _XkbKSLower; 84 } 85 break; 86 case 1: /* latin 2 */ 87 if (((ks>=XK_Aogonek)&&(ks<=XK_Zabovedot)&&(ks!=XK_breve))|| 88 ((ks>=XK_Racute)&&(ks<=XK_Tcedilla))) { 89 rtrn|= _XkbKSUpper; 90 } 91 if (((ks>=XK_aogonek)&&(ks<=XK_zabovedot)&&(ks!=XK_caron))|| 92 ((ks>=XK_racute)&&(ks<=XK_tcedilla))) { 93 rtrn|= _XkbKSLower; 94 } 95 break; 96 case 2: /* latin 3 */ 97 if (((ks>=XK_Hstroke)&&(ks<=XK_Jcircumflex))|| 98 ((ks>=XK_Cabovedot)&&(ks<=XK_Scircumflex))) { 99 rtrn|= _XkbKSUpper; 100 } 101 if (((ks>=XK_hstroke)&&(ks<=XK_jcircumflex))|| 102 ((ks>=XK_cabovedot)&&(ks<=XK_scircumflex))) { 103 rtrn|= _XkbKSLower; 104 } 105 break; 106 case 3: /* latin 4 */ 107 if (((ks>=XK_Rcedilla)&&(ks<=XK_Tslash))|| 108 (ks==XK_ENG)|| 109 ((ks>=XK_Amacron)&&(ks<=XK_Umacron))) { 110 rtrn|= _XkbKSUpper; 111 } 112 if (((ks>=XK_rcedilla)&&(ks<=XK_tslash))|| 113 (ks==XK_eng)|| 114 ((ks>=XK_amacron)&&(ks<=XK_umacron))) { 115 rtrn|= _XkbKSLower; 116 } 117 break; 118 case 18: /* latin 8 */ 119 if ((ks==XK_Babovedot)|| 120 ((ks>=XK_Dabovedot)&&(ks<=XK_Wacute))|| 121 ((ks>=XK_Ygrave)&&(ks<=XK_Fabovedot))|| 122 (ks==XK_Mabovedot)|| 123 (ks==XK_Pabovedot)|| 124 (ks==XK_Sabovedot)|| 125 (ks==XK_Wdiaeresis)|| 126 ((ks>=XK_Wcircumflex)&&(ks<=XK_Ycircumflex))) { 127 rtrn|= _XkbKSUpper; 128 } 129 if ((ks==XK_babovedot)|| 130 (ks==XK_dabovedot)|| 131 (ks==XK_fabovedot)|| 132 (ks==XK_mabovedot)|| 133 ((ks>=XK_wgrave)&&(ks<=XK_wacute))|| 134 (ks==XK_ygrave)|| 135 ((ks>=XK_wdiaeresis)&&(ks<=XK_ycircumflex))) { 136 rtrn|= _XkbKSLower; 137 } 138 break; 139 case 19: /* latin 9 */ 140 if ((ks==XK_OE)||(ks==XK_Ydiaeresis)) { 141 rtrn|= _XkbKSUpper; 142 } 143 if (ks==XK_oe) { 144 rtrn|= _XkbKSLower; 145 } 146 break; 147 } 148 return rtrn; 149} 150 151/***===================================================================***/ 152 153Bool 154XkbLookupGroupAndLevel( XkbDescPtr xkb, 155 int key, 156 int * mods_inout, 157 int * grp_inout, 158 int * lvl_rtrn) 159{ 160int nG,eG; 161 162 if ((!xkb)||(!XkbKeycodeInRange(xkb,key))||(!grp_inout)) 163 return False; 164 165 nG= XkbKeyNumGroups(xkb,key); 166 eG= *grp_inout; 167 168 if ( nG==0 ) { 169 *grp_inout= 0; 170 if (lvl_rtrn!=NULL) 171 *lvl_rtrn= 0; 172 return False; 173 } 174 else if ( nG==1 ) { 175 eG= 0; 176 } 177 else if ( eG>=nG ) { 178 unsigned gI= XkbKeyGroupInfo(xkb,key); 179 switch (XkbOutOfRangeGroupAction(gI)) { 180 default: 181 eG %= nG; 182 break; 183 case XkbClampIntoRange: 184 eG = nG-1; 185 break; 186 case XkbRedirectIntoRange: 187 eG = XkbOutOfRangeGroupNumber(gI); 188 if (eG>=nG) 189 eG= 0; 190 break; 191 } 192 } 193 *grp_inout= eG; 194 if (mods_inout!=NULL) { 195 XkbKeyTypePtr type; 196 int preserve; 197 198 type = XkbKeyKeyType(xkb,key,eG); 199 if (lvl_rtrn!=NULL) 200 *lvl_rtrn= 0; 201 preserve= 0; 202 if (type->map) { /* find the shift level */ 203 register int i; 204 register XkbKTMapEntryPtr entry; 205 for (i=0,entry=type->map;i<type->map_count;i++,entry++) { 206 if ((entry->active)&& 207 (((*mods_inout)&type->mods.mask)==entry->mods.mask)){ 208 if (lvl_rtrn!=NULL) 209 *lvl_rtrn= entry->level; 210 if (type->preserve) 211 preserve= type->preserve[i].mask; 212 break; 213 } 214 } 215 } 216 (*mods_inout)&= ~(type->mods.mask&(~preserve)); 217 } 218 return True; 219} 220 221/***===================================================================***/ 222 223static Bool 224XkbWriteSectionFromName(FILE *file,char *sectionName,char *name) 225{ 226 fprintf(file," xkb_%-20s { include \"%s\" };\n",sectionName,name); 227 return True; 228} 229 230#define NEED_DESC(n) ((!n)||((n)[0]=='+')||((n)[0]=='|')||(strchr((n),'%'))) 231#define COMPLETE(n) ((n)&&(!NEED_DESC(n))) 232 233/* ARGSUSED */ 234static void 235_AddIncl( FILE * file, 236 XkbFileInfo * result, 237 Bool topLevel, 238 Bool showImplicit, 239 int index, 240 void * priv) 241{ 242 if ((priv)&&(strcmp((char *)priv,"%")!=0)) 243 fprintf(file," include \"%s\"\n",(char *)priv); 244 return; 245} 246 247Bool 248XkbWriteXKBKeymapForNames( FILE * file, 249 XkbComponentNamesPtr names, 250 Display * dpy, 251 XkbDescPtr xkb, 252 unsigned want, 253 unsigned need) 254{ 255char * name,*tmp; 256unsigned complete; 257XkbNamesPtr old_names; 258int multi_section; 259unsigned wantNames,wantConfig,wantDflts; 260XkbFileInfo finfo; 261 262 bzero(&finfo,sizeof(XkbFileInfo)); 263 264 complete= 0; 265 if ((name=names->keymap)==NULL) name= "default"; 266 if (COMPLETE(names->keycodes)) complete|= XkmKeyNamesMask; 267 if (COMPLETE(names->types)) complete|= XkmTypesMask; 268 if (COMPLETE(names->compat)) complete|= XkmCompatMapMask; 269 if (COMPLETE(names->symbols)) complete|= XkmSymbolsMask; 270 if (COMPLETE(names->geometry)) complete|= XkmGeometryMask; 271 want|= (complete|need); 272 if (want&XkmSymbolsMask) 273 want|= XkmKeyNamesMask|XkmTypesMask; 274 275 if (want==0) 276 return False; 277 278 if (xkb!=NULL) { 279 old_names= xkb->names; 280 finfo.type= 0; 281 finfo.defined= 0; 282 finfo.xkb= xkb; 283 if (!XkbDetermineFileType(&finfo,XkbXKBFile,NULL)) 284 return False; 285 } 286 else old_names= NULL; 287 288 wantConfig= want&(~complete); 289 if (xkb!=NULL) { 290 if (wantConfig&XkmTypesMask) { 291 if ((!xkb->map) || (xkb->map->num_types<XkbNumRequiredTypes)) 292 wantConfig&= ~XkmTypesMask; 293 } 294 if (wantConfig&XkmCompatMapMask) { 295 if ((!xkb->compat) || (xkb->compat->num_si<1)) 296 wantConfig&= ~XkmCompatMapMask; 297 } 298 if (wantConfig&XkmSymbolsMask) { 299 if ((!xkb->map) || (!xkb->map->key_sym_map)) 300 wantConfig&= ~XkmSymbolsMask; 301 } 302 if (wantConfig&XkmIndicatorsMask) { 303 if (!xkb->indicators) 304 wantConfig&= ~XkmIndicatorsMask; 305 } 306 if (wantConfig&XkmKeyNamesMask) { 307 if ((!xkb->names)||(!xkb->names->keys)) 308 wantConfig&= ~XkmKeyNamesMask; 309 } 310 if ((wantConfig&XkmGeometryMask)&&(!xkb->geom)) 311 wantConfig&= ~XkmGeometryMask; 312 } 313 else { 314 wantConfig= 0; 315 } 316 complete|= wantConfig; 317 318 wantDflts= 0; 319 wantNames= want&(~complete); 320 if ((xkb!=NULL) && (old_names!=NULL)) { 321 if (wantNames&XkmTypesMask) { 322 if (old_names->types!=None) { 323 tmp= XkbAtomGetString(dpy,old_names->types); 324 names->types= tmp; 325 } 326 else { 327 wantDflts|= XkmTypesMask; 328 } 329 complete|= XkmTypesMask; 330 } 331 if (wantNames&XkmCompatMapMask) { 332 if (old_names->compat!=None) { 333 tmp= XkbAtomGetString(dpy,old_names->compat); 334 names->compat= tmp; 335 } 336 else wantDflts|= XkmCompatMapMask; 337 complete|= XkmCompatMapMask; 338 } 339 if (wantNames&XkmSymbolsMask) { 340 if (old_names->symbols==None) 341 return False; 342 tmp= XkbAtomGetString(dpy,old_names->symbols); 343 names->symbols= tmp; 344 complete|= XkmSymbolsMask; 345 } 346 if (wantNames&XkmKeyNamesMask) { 347 if (old_names->keycodes!=None) { 348 tmp= XkbAtomGetString(dpy,old_names->keycodes); 349 names->keycodes= tmp; 350 } 351 else wantDflts|= XkmKeyNamesMask; 352 complete|= XkmKeyNamesMask; 353 } 354 if (wantNames&XkmGeometryMask) { 355 if (old_names->geometry==None) 356 return False; 357 tmp= XkbAtomGetString(dpy,old_names->geometry); 358 names->geometry= tmp; 359 complete|= XkmGeometryMask; 360 wantNames&= ~XkmGeometryMask; 361 } 362 } 363 if (complete&XkmCompatMapMask) 364 complete|= XkmIndicatorsMask|XkmVirtualModsMask; 365 else if (complete&(XkmSymbolsMask|XkmTypesMask)) 366 complete|= XkmVirtualModsMask; 367 if (need & (~complete)) 368 return False; 369 if ((complete&XkmSymbolsMask)&&((XkmKeyNamesMask|XkmTypesMask)&(~complete))) 370 return False; 371 372 multi_section= 1; 373 if (((complete&XkmKeymapRequired)==XkmKeymapRequired)&& 374 ((complete&(~XkmKeymapLegal))==0)) { 375 fprintf(file,"xkb_keymap \"%s\" {\n",name); 376 } 377 else if (((complete&XkmSemanticsRequired)==XkmSemanticsRequired)&& 378 ((complete&(~XkmSemanticsLegal))==0)) { 379 fprintf(file,"xkb_semantics \"%s\" {\n",name); 380 } 381 else if (((complete&XkmLayoutRequired)==XkmLayoutRequired)&& 382 ((complete&(~XkmLayoutLegal))==0)) { 383 fprintf(file,"xkb_layout \"%s\" {\n",name); 384 } 385 else if (XkmSingleSection(complete&(~XkmVirtualModsMask))) { 386 multi_section= 0; 387 } 388 else { 389 return False; 390 } 391 392 wantNames= complete&(~(wantConfig|wantDflts)); 393 name= names->keycodes; 394 if (wantConfig&XkmKeyNamesMask) 395 XkbWriteXKBKeycodes(file,&finfo,False,False,_AddIncl,name); 396 else if (wantDflts&XkmKeyNamesMask) 397 fprintf(stderr,"Default symbols not implemented yet!\n"); 398 else if (wantNames&XkmKeyNamesMask) 399 XkbWriteSectionFromName(file,"keycodes",name); 400 401 name= names->types; 402 if (wantConfig&XkmTypesMask) 403 XkbWriteXKBKeyTypes(file,&finfo,False,False,_AddIncl,name); 404 else if (wantDflts&XkmTypesMask) 405 fprintf(stderr,"Default types not implemented yet!\n"); 406 else if (wantNames&XkmTypesMask) 407 XkbWriteSectionFromName(file,"types",name); 408 409 name= names->compat; 410 if (wantConfig&XkmCompatMapMask) 411 XkbWriteXKBCompatMap(file,&finfo,False,False,_AddIncl,name); 412 else if (wantDflts&XkmCompatMapMask) 413 fprintf(stderr,"Default interps not implemented yet!\n"); 414 else if (wantNames&XkmCompatMapMask) 415 XkbWriteSectionFromName(file,"compatibility",name); 416 417 name= names->symbols; 418 if (wantConfig&XkmSymbolsMask) 419 XkbWriteXKBSymbols(file,&finfo,False,False,_AddIncl,name); 420 else if (wantNames&XkmSymbolsMask) 421 XkbWriteSectionFromName(file,"symbols",name); 422 423 name= names->geometry; 424 if (wantConfig&XkmGeometryMask) 425 XkbWriteXKBGeometry(file,&finfo,False,False,_AddIncl,name); 426 else if (wantNames&XkmGeometryMask) 427 XkbWriteSectionFromName(file,"geometry",name); 428 429 if (multi_section) 430 fprintf(file,"};\n"); 431 return True; 432} 433 434/***====================================================================***/ 435 436/*ARGSUSED*/ 437Status 438XkbMergeFile(XkbDescPtr xkb,XkbFileInfo finfo) 439{ 440 return BadImplementation; 441} 442 443/***====================================================================***/ 444 445int 446XkbFindKeycodeByName(XkbDescPtr xkb,char *name,Bool use_aliases) 447{ 448register int i; 449 450 if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) 451 return 0; 452 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 453 if (strncmp(xkb->names->keys[i].name,name,XkbKeyNameLength)==0) 454 return i; 455 } 456 if (!use_aliases) 457 return 0; 458 if (xkb->geom && xkb->geom->key_aliases) { 459 XkbKeyAliasPtr a; 460 a= xkb->geom->key_aliases; 461 for (i=0;i<xkb->geom->num_key_aliases;i++,a++) { 462 if (strncmp(name,a->alias,XkbKeyNameLength)==0) 463 return XkbFindKeycodeByName(xkb,a->real,False); 464 } 465 } 466 if (xkb->names && xkb->names->key_aliases) { 467 XkbKeyAliasPtr a; 468 a= xkb->names->key_aliases; 469 for (i=0;i<xkb->names->num_key_aliases;i++,a++) { 470 if (strncmp(name,a->alias,XkbKeyNameLength)==0) 471 return XkbFindKeycodeByName(xkb,a->real,False); 472 } 473 } 474 return 0; 475} 476 477 478unsigned 479XkbConvertGetByNameComponents(Bool toXkm,unsigned orig) 480{ 481unsigned rtrn; 482 483 rtrn= 0; 484 if (toXkm) { 485 if (orig&XkbGBN_TypesMask) rtrn|= XkmTypesMask; 486 if (orig&XkbGBN_CompatMapMask) rtrn|= XkmCompatMapMask; 487 if (orig&XkbGBN_SymbolsMask) rtrn|= XkmSymbolsMask; 488 if (orig&XkbGBN_IndicatorMapMask) rtrn|= XkmIndicatorsMask; 489 if (orig&XkbGBN_KeyNamesMask) rtrn|= XkmKeyNamesMask; 490 if (orig&XkbGBN_GeometryMask) rtrn|= XkmGeometryMask; 491 } 492 else { 493 if (orig&XkmTypesMask) rtrn|= XkbGBN_TypesMask; 494 if (orig&XkmCompatMapMask) rtrn|= XkbGBN_CompatMapMask; 495 if (orig&XkmSymbolsMask) rtrn|= XkbGBN_SymbolsMask; 496 if (orig&XkmIndicatorsMask) rtrn|= XkbGBN_IndicatorMapMask; 497 if (orig&XkmKeyNamesMask) rtrn|= XkbGBN_KeyNamesMask; 498 if (orig&XkmGeometryMask) rtrn|= XkbGBN_GeometryMask; 499 if (orig!=0) rtrn|= XkbGBN_OtherNamesMask; 500 } 501 return rtrn; 502} 503 504unsigned 505XkbConvertXkbComponents(Bool toXkm,unsigned orig) 506{ 507unsigned rtrn; 508 509 rtrn= 0; 510 if (toXkm) { 511 if (orig&XkbClientMapMask) rtrn|= XkmTypesMask|XkmSymbolsMask; 512 if (orig&XkbServerMapMask) rtrn|= XkmTypesMask|XkmSymbolsMask; 513 if (orig&XkbCompatMapMask) rtrn|= XkmCompatMapMask; 514 if (orig&XkbIndicatorMapMask) rtrn|= XkmIndicatorsMask; 515 if (orig&XkbNamesMask) rtrn|= XkmKeyNamesMask; 516 if (orig&XkbGeometryMask) rtrn|= XkmGeometryMask; 517 } 518 else { 519 if (orig!=0) rtrn|= XkbNamesMask; 520 if (orig&XkmTypesMask) rtrn|= XkbClientMapMask; 521 if (orig&XkmCompatMapMask) 522 rtrn|= XkbCompatMapMask|XkbIndicatorMapMask; 523 if (orig&XkmSymbolsMask) rtrn|=XkbClientMapMask|XkbServerMapMask; 524 if (orig&XkmIndicatorsMask) rtrn|= XkbIndicatorMapMask; 525 if (orig&XkmKeyNamesMask) 526 rtrn|= XkbNamesMask|XkbIndicatorMapMask; 527 if (orig&XkmGeometryMask) rtrn|= XkbGeometryMask; 528 } 529 return rtrn; 530} 531 532Bool 533XkbDetermineFileType(XkbFileInfoPtr finfo,int format,int *opts_missing) 534{ 535unsigned present; 536XkbDescPtr xkb; 537 538 if ((!finfo)||(!finfo->xkb)) 539 return False; 540 if (opts_missing) 541 *opts_missing= 0; 542 xkb= finfo->xkb; 543 present= 0; 544 if ((xkb->names)&&(xkb->names->keys)) present|= XkmKeyNamesMask; 545 if ((xkb->map)&&(xkb->map->types)) present|= XkmTypesMask; 546 if (xkb->compat) present|= XkmCompatMapMask; 547 if ((xkb->map)&&(xkb->map->num_syms>1)) present|= XkmSymbolsMask; 548 if (xkb->indicators) present|= XkmIndicatorsMask; 549 if (xkb->geom) present|= XkmGeometryMask; 550 if (!present) 551 return False; 552 else switch (present) { 553 case XkmKeyNamesMask: 554 finfo->type= XkmKeyNamesIndex; 555 finfo->defined= present; 556 return True; 557 case XkmTypesMask: 558 finfo->type= XkmTypesIndex; 559 finfo->defined= present; 560 return True; 561 case XkmCompatMapMask: 562 finfo->type= XkmCompatMapIndex; 563 finfo->defined= present; 564 return True; 565 case XkmSymbolsMask: 566 if (format!=XkbXKMFile) { 567 finfo->type= XkmSymbolsIndex; 568 finfo->defined= present; 569 return True; 570 } 571 break; 572 case XkmGeometryMask: 573 finfo->type= XkmGeometryIndex; 574 finfo->defined= present; 575 return True; 576 } 577 if ((present&(~XkmSemanticsLegal))==0) { 578 if ((XkmSemanticsRequired&present)==XkmSemanticsRequired) { 579 if (opts_missing) 580 *opts_missing= XkmSemanticsOptional&(~present); 581 finfo->type= XkmSemanticsFile; 582 finfo->defined= present; 583 return True; 584 } 585 } 586 else if ((present&(~XkmLayoutLegal))==0) { 587 if ((XkmLayoutRequired&present)==XkmLayoutRequired) { 588 if (opts_missing) 589 *opts_missing= XkmLayoutOptional&(~present); 590 finfo->type= XkmLayoutFile; 591 finfo->defined= present; 592 return True; 593 } 594 } 595 else if ((present&(~XkmKeymapLegal))==0) { 596 if ((XkmKeymapRequired&present)==XkmKeymapRequired) { 597 if (opts_missing) 598 *opts_missing= XkmKeymapOptional&(~present); 599 finfo->type= XkmKeymapFile; 600 finfo->defined= present; 601 return True; 602 } 603 } 604 return False; 605} 606 607/* all latin-1 alphanumerics, plus parens, slash, minus, underscore and */ 608/* wildcards */ 609 610static unsigned char componentSpecLegal[] = { 611 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83, 612 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, 613 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 614 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 615}; 616 617void 618XkbEnsureSafeMapName(char *name) 619{ 620 if (name==NULL) 621 return; 622 while (*name!='\0') { 623 if ((componentSpecLegal[(*name)/8]&(1<<((*name)%8)))==0) 624 *name= '_'; 625 name++; 626 } 627 return; 628} 629 630/***====================================================================***/ 631 632#define UNMATCHABLE(c) (((c)=='(')||((c)==')')||((c)=='/')) 633 634Bool 635XkbNameMatchesPattern(char *name,char *ptrn) 636{ 637 while (ptrn[0]!='\0') { 638 if (name[0]=='\0') { 639 if (ptrn[0]=='*') { 640 ptrn++; 641 continue; 642 } 643 return False; 644 } 645 if (ptrn[0]=='?') { 646 if (UNMATCHABLE(name[0])) 647 return False; 648 } 649 else if (ptrn[0]=='*') { 650 if ((!UNMATCHABLE(name[0]))&&XkbNameMatchesPattern(name+1,ptrn)) 651 return True; 652 return XkbNameMatchesPattern(name,ptrn+1); 653 } 654 else if (ptrn[0]!=name[0]) 655 return False; 656 name++; 657 ptrn++; 658 } 659 /* if we get here, the pattern is exhausted (-:just like me:-) */ 660 return (name[0]=='\0'); 661} 662 663#ifdef NEED_STRCASECMP 664_X_HIDDEN int 665_XkbStrCaseCmp(char *str1,char *str2) 666{ 667 const u_char *us1 = (const u_char *)str1, *us2 = (const u_char *)str2; 668 669 while (tolower(*us1) == tolower(*us2)) { 670 if (*us1++ == '\0') 671 return (0); 672 us2++; 673 } 674 675 return (tolower(*us1) - tolower(*us2)); 676} 677#endif 678