searchcode logo
protect your actionscript code with irrfuscatorAdvertise Here

libX11 /libX11-1.5.0/src/xkb/XKBBind.c

git clone git://pkgs.fedoraproject.org/libX11

Language

C

MD5 Hash

cbfad56b75ab1a63640ca412b0063ed9

Lines in File 849
Blank Lines 87 (10.25%)
Comment Lines 45 (5%)
Code Lines 716 (84%)
Estimated Development Effort (Months)1.69
Estimated Development Effort (Years)0
Estimated Developers0.55
Estimated Cost$19024.00
Generated using David A. Wheeler's 'SLOCCount'.
  1. /*
  2.  
  3. Copyright 1985, 1987, 1994, 1998 The Open Group
  4.  
  5. Permission to use, copy, modify, distribute, and sell this software and its
  6. documentation for any purpose is hereby granted without fee, provided that
  7. the above copyright notice appear in all copies and that both that
  8. copyright notice and this permission notice appear in supporting
  9. documentation.
  10.  
  11. The above copyright notice and this permission notice shall be included
  12. in all copies or substantial portions of the Software.
  13.  
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  17. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. OTHER DEALINGS IN THE SOFTWARE.
  21.  
  22. Except as contained in this notice, the name of The Open Group shall
  23. not be used in advertising or otherwise to promote the sale, use or
  24. other dealings in this Software without prior written authorization
  25. from The Open Group.
  26.  
  27. */
  28.  
  29. /* the new monsters ate the old ones */
  30.  
  31. #ifdef HAVE_CONFIG_H
  32. #include <config.h>
  33. #endif
  34. #include "XKBlib.h"
  35. #include <X11/Xlibint.h>
  36. #include <X11/Xutil.h>
  37. #include <X11/keysym.h>
  38. #include <stdio.h>
  39. #include <ctype.h>
  40.  
  41. #include <X11/extensions/XKBproto.h>
  42. #include "XKBlibint.h"
  43.  
  44. #ifdef USE_OWN_COMPOSE
  45. #define COMPOSE_NO_CONST_MEMBERS
  46. #include "imComp.h"
  47. #endif
  48.  
  49. #define AllMods (ShiftMask|LockMask|ControlMask| \
  50. Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
  51.  
  52. static int _XkbLoadDpy(
  53. Display *dpy
  54. );
  55.  
  56. struct _XKeytrans {
  57. struct _XKeytrans *next;/* next on list */
  58. char *string; /* string to return when the time comes */
  59. int len; /* length of string (since NULL is legit)*/
  60. KeySym key; /* keysym rebound */
  61. unsigned int state; /* modifier state */
  62. KeySym *modifiers; /* modifier keysyms you want */
  63. int mlen; /* length of modifier list */
  64. };
  65.  
  66. KeySym
  67. XkbKeycodeToKeysym(Display *dpy,
  68. #if NeedWidePrototypes
  69. unsigned int kc,
  70. #else
  71. KeyCode kc,
  72. #endif
  73. int group,
  74. int level)
  75. {
  76. XkbDescRec *xkb;
  77.  
  78. if (_XkbUnavailable(dpy))
  79. return NoSymbol;
  80.  
  81. _XkbCheckPendingRefresh(dpy,dpy->xkb_info);
  82.  
  83. xkb = dpy->xkb_info->desc;
  84. if ((kc<xkb->min_key_code)||(kc>xkb->max_key_code))
  85. return NoSymbol;
  86.  
  87. if ((group<0)||(level<0)||(group>=XkbKeyNumGroups(xkb,kc)))
  88. return NoSymbol;
  89. if (level>=XkbKeyGroupWidth(xkb,kc,group)) {
  90. /* for compatibility with the core protocol, _always_ allow */
  91. /* two symbols in the first two groups. If either of the */
  92. /* two is of type ONE_LEVEL, just replicate the first symbol */
  93. if ((group>XkbGroup2Index)||(XkbKeyGroupWidth(xkb,kc,group)!=1)||
  94. (level!=1)) {
  95. return NoSymbol;
  96. }
  97. level= 0;
  98. }
  99. return XkbKeySymEntry(xkb,kc,level,group);
  100. }
  101.  
  102. KeySym
  103. XKeycodeToKeysym(Display *dpy,
  104. #if NeedWidePrototypes
  105. unsigned int kc,
  106. #else
  107. KeyCode kc,
  108. #endif
  109. int col)
  110. {
  111. XkbDescRec *xkb;
  112.  
  113. if (_XkbUnavailable(dpy))
  114. return _XKeycodeToKeysym(dpy, kc, col);
  115.  
  116. _XkbCheckPendingRefresh(dpy,dpy->xkb_info);
  117.  
  118. xkb = dpy->xkb_info->desc;
  119. if ((kc<xkb->min_key_code)||(kc>xkb->max_key_code))
  120. return NoSymbol;
  121.  
  122. if (col>3) {
  123. int lastSym,tmp,nGrp;
  124.  
  125. lastSym= 3;
  126. nGrp= XkbKeyNumGroups(xkb,kc);
  127. if ((nGrp>0)&&((tmp=XkbKeyGroupWidth(xkb,kc,XkbGroup1Index))>2)) {
  128. if (col<=(lastSym+tmp-2))
  129. return XkbKeycodeToKeysym(dpy,kc,XkbGroup1Index,col-lastSym+2);
  130. lastSym+= tmp-2;
  131. }
  132. if ((nGrp>1)&&((tmp=XkbKeyGroupWidth(xkb,kc,XkbGroup2Index))>2)) {
  133. if (col<=(lastSym+tmp-2))
  134. return XkbKeycodeToKeysym(dpy,kc,XkbGroup2Index,col-lastSym+2);
  135. lastSym+= tmp-2;
  136. }
  137. if (nGrp>2) {
  138. tmp= XkbKeyGroupWidth(xkb,kc,XkbGroup3Index);
  139. if (col<=lastSym+tmp)
  140. return XkbKeycodeToKeysym(dpy,kc,XkbGroup3Index,col-lastSym);
  141. lastSym+= tmp;
  142. }
  143. if (nGrp>3) {
  144. tmp= XkbKeyGroupWidth(xkb,kc,XkbGroup4Index);
  145. if (col<=lastSym+tmp)
  146. return XkbKeycodeToKeysym(dpy,kc,XkbGroup4Index,col-lastSym);
  147. }
  148. return NoSymbol;
  149. }
  150. return XkbKeycodeToKeysym(dpy,kc,(col>>1),(col&1));
  151. }
  152.  
  153. KeyCode
  154. XKeysymToKeycode(Display *dpy, KeySym ks)
  155. {
  156. register int i, j, gotOne;
  157.  
  158. if (_XkbUnavailable(dpy))
  159. return _XKeysymToKeycode(dpy,ks);
  160. _XkbCheckPendingRefresh(dpy,dpy->xkb_info);
  161.  
  162. j= 0;
  163. do {
  164. register XkbDescRec *xkb = dpy->xkb_info->desc;
  165. gotOne= 0;
  166. for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) {
  167. if ( j<(int)XkbKeyNumSyms(xkb,i) ) {
  168. gotOne = 1;
  169. if ((XkbKeySym(xkb,i,j)==ks))
  170. return i;
  171. }
  172. }
  173. j++;
  174. } while (gotOne);
  175. return 0;
  176. }
  177.  
  178. static int
  179. _XkbComputeModmap(Display *dpy)
  180. {
  181. register XkbDescPtr xkb;
  182.  
  183. xkb= dpy->xkb_info->desc;
  184. if (XkbGetUpdatedMap(dpy,XkbModifierMapMask,xkb)==Success)
  185. return 1;
  186. return 0;
  187. }
  188.  
  189. unsigned
  190. XkbKeysymToModifiers(Display *dpy,KeySym ks)
  191. {
  192. XkbDescRec *xkb;
  193. register int i,j;
  194. register KeySym *pSyms;
  195. CARD8 mods;
  196.  
  197. if (_XkbUnavailable(dpy))
  198. return _XKeysymToModifiers(dpy,ks);
  199. _XkbCheckPendingRefresh(dpy,dpy->xkb_info);
  200.  
  201. if (_XkbNeedModmap(dpy->xkb_info)&&(!_XkbComputeModmap(dpy)))
  202. return _XKeysymToModifiers(dpy,ks);
  203.  
  204. xkb= dpy->xkb_info->desc;
  205. mods= 0;
  206. for (i = xkb->min_key_code; i <= (int)xkb->max_key_code; i++) {
  207. pSyms= XkbKeySymsPtr(xkb,i);
  208. for (j=XkbKeyNumSyms(xkb,i)-1;j>=0;j--) {
  209. if (pSyms[j]==ks) {
  210. mods|= xkb->map->modmap[i];
  211. break;
  212. }
  213. }
  214. }
  215. return mods;
  216. }
  217.  
  218. KeySym
  219. XLookupKeysym(register XKeyEvent *event, int col)
  220. {
  221. Display *dpy = event->display;
  222. if (_XkbUnavailable(dpy))
  223. return _XLookupKeysym(event, col);
  224. _XkbCheckPendingRefresh(dpy,dpy->xkb_info);
  225. return XKeycodeToKeysym(dpy, event->keycode, col);
  226. }
  227.  
  228. /*
  229.   * Not a public entry point -- XkbTranslateKey is an obsolete name
  230.   * that is preserved here so that functions linked against the old
  231.   * version will continue to work in a shared library environment.
  232.   */
  233. int
  234. XkbTranslateKey( register Display * dpy,
  235. KeyCode key,
  236. register unsigned int mods,
  237. unsigned int * mods_rtrn,
  238. KeySym * keysym_rtrn);
  239. int
  240. XkbTranslateKey( register Display * dpy,
  241. KeyCode key,
  242. register unsigned int mods,
  243. unsigned int * mods_rtrn,
  244. KeySym * keysym_rtrn)
  245. {
  246. return XkbLookupKeySym(dpy,key,mods,mods_rtrn,keysym_rtrn);
  247. }
  248.  
  249. Bool
  250. XkbLookupKeySym( register Display * dpy,
  251. KeyCode key,
  252. register unsigned int mods,
  253. unsigned int * mods_rtrn,
  254. KeySym * keysym_rtrn)
  255. {
  256. if (_XkbUnavailable(dpy))
  257. return _XTranslateKey(dpy, key, mods, mods_rtrn, keysym_rtrn);
  258. _XkbCheckPendingRefresh(dpy,dpy->xkb_info);
  259. return XkbTranslateKeyCode(dpy->xkb_info->desc,key,mods,mods_rtrn,
  260. keysym_rtrn);
  261. }
  262.  
  263. Bool
  264. XkbTranslateKeyCode( register XkbDescPtr xkb,
  265. KeyCode key,
  266. register unsigned int mods,
  267. unsigned int * mods_rtrn,
  268. KeySym * keysym_rtrn)
  269. {
  270. XkbKeyTypeRec *type;
  271. int col,nKeyGroups;
  272. unsigned preserve,effectiveGroup;
  273. KeySym *syms;
  274.  
  275. if (mods_rtrn!=NULL)
  276. *mods_rtrn = 0;
  277.  
  278. nKeyGroups= XkbKeyNumGroups(xkb,key);
  279. if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) {
  280. if (keysym_rtrn!=NULL)
  281. *keysym_rtrn = NoSymbol;
  282. return False;
  283. }
  284.  
  285. syms = XkbKeySymsPtr(xkb,key);
  286.  
  287. /* find the offset of the effective group */
  288. col = 0;
  289. effectiveGroup= XkbGroupForCoreState(mods);
  290. if ( effectiveGroup>=nKeyGroups ) {
  291. unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
  292. switch (XkbOutOfRangeGroupAction(groupInfo)) {
  293. default:
  294. effectiveGroup %= nKeyGroups;
  295. break;
  296. case XkbClampIntoRange:
  297. effectiveGroup = nKeyGroups-1;
  298. break;
  299. case XkbRedirectIntoRange:
  300. effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
  301. if (effectiveGroup>=nKeyGroups)
  302. effectiveGroup= 0;
  303. break;
  304. }
  305. }
  306. col= effectiveGroup*XkbKeyGroupsWidth(xkb,key);
  307. type = XkbKeyKeyType(xkb,key,effectiveGroup);
  308.  
  309. preserve= 0;
  310. if (type->map) { /* find the column (shift level) within the group */
  311. register int i;
  312. register XkbKTMapEntryPtr entry;
  313. for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
  314. if ((entry->active)&&((mods&type->mods.mask)==entry->mods.mask)) {
  315. col+= entry->level;
  316. if (type->preserve)
  317. preserve= type->preserve[i].mask;
  318. break;
  319. }
  320. }
  321. }
  322.  
  323. if (keysym_rtrn!=NULL)
  324. *keysym_rtrn= syms[col];
  325. if (mods_rtrn) {
  326. *mods_rtrn= type->mods.mask&(~preserve);
  327. /* The Motif VTS doesn't get the help callback called if help
  328. * is bound to Shift+<whatever>, and it appears as though it
  329. * is XkbTranslateKeyCode that is causing the problem. The
  330. * core X version of XTranslateKey always OR's in ShiftMask
  331. * and LockMask for mods_rtrn, so this "fix" keeps this behavior
  332. * and solves the VTS problem.
  333. */
  334. if ((xkb->dpy)&&(xkb->dpy->xkb_info)&&
  335. (xkb->dpy->xkb_info->xlib_ctrls&XkbLC_AlwaysConsumeShiftAndLock)) {
  336. *mods_rtrn|= (ShiftMask|LockMask);
  337. }
  338. }
  339. return (syms[col]!=NoSymbol);
  340. }
  341.  
  342. Status
  343. XkbRefreshKeyboardMapping(register XkbMapNotifyEvent *event)
  344. {
  345. Display *dpy = event->display;
  346. XkbInfoPtr xkbi;
  347.  
  348. if (_XkbUnavailable(dpy)) {
  349. _XRefreshKeyboardMapping((XMappingEvent *)event);
  350. return Success;
  351. }
  352. xkbi= dpy->xkb_info;
  353.  
  354. if (((event->type&0x7f)-xkbi->codes->first_event)!=XkbEventCode)
  355. return BadMatch;
  356. if (event->xkb_type==XkbNewKeyboardNotify) {
  357. _XkbReloadDpy(dpy);
  358. return Success;
  359. }
  360. if (event->xkb_type==XkbMapNotify) {
  361. XkbMapChangesRec changes;
  362. Status rtrn;
  363.  
  364. if (xkbi->flags&XkbMapPending)
  365. changes= xkbi->changes;
  366. else bzero(&changes,sizeof(changes));
  367. XkbNoteMapChanges(&changes,event,XKB_XLIB_MAP_MASK);
  368. if ((rtrn=XkbGetMapChanges(dpy,xkbi->desc,&changes))!=Success) {
  369. #ifdef DEBUG
  370. fprintf(stderr,"Internal Error! XkbGetMapChanges failed:\n");
  371. #endif
  372. xkbi->changes= changes;
  373. }
  374. else if (xkbi->flags&XkbMapPending) {
  375. xkbi->flags&= ~XkbMapPending;
  376. bzero(&xkbi->changes,sizeof(XkbMapChangesRec));
  377. }
  378. return rtrn;
  379. }
  380. return BadMatch;
  381. }
  382.  
  383. int
  384. XRefreshKeyboardMapping(register XMappingEvent *event)
  385. {
  386. XkbEvent *xkbevent = (XkbEvent *)event;
  387. Display *dpy = event->display;
  388. XkbMapChangesRec changes;
  389. XkbInfoPtr xkbi;
  390.  
  391. /* always do this for input methods, which still use the old keymap */
  392. (void) _XRefreshKeyboardMapping(event);
  393.  
  394. if (_XkbUnavailable(dpy))
  395. return 1;
  396.  
  397. xkbi = dpy->xkb_info;
  398.  
  399. if (((event->type&0x7f)-xkbi->codes->first_event)==XkbEventCode)
  400. return XkbRefreshKeyboardMapping(&xkbevent->map);
  401.  
  402. if (xkbi->flags&XkbXlibNewKeyboard) {
  403. _XkbReloadDpy(dpy);
  404. return 1;
  405. }
  406.  
  407. if ((xkbi->flags&XkbMapPending)||(event->request==MappingKeyboard)) {
  408. if (xkbi->flags&XkbMapPending) {
  409. changes= xkbi->changes;
  410. _XkbNoteCoreMapChanges(&changes,event,XKB_XLIB_MAP_MASK);
  411. }
  412. else {
  413. bzero(&changes,sizeof(changes));
  414. changes.changed= XkbKeySymsMask;
  415. if (xkbi->desc->min_key_code<xkbi->desc->max_key_code) {
  416. changes.first_key_sym= xkbi->desc->min_key_code;
  417. changes.num_key_syms= xkbi->desc->max_key_code-
  418. xkbi->desc->min_key_code+1;
  419. }
  420. else {
  421. changes.first_key_sym= event->first_keycode;
  422. changes.num_key_syms= event->count;
  423. }
  424. }
  425.  
  426. if (XkbGetMapChanges(dpy,xkbi->desc, &changes)!=Success) {
  427. #ifdef DEBUG
  428. fprintf(stderr,"Internal Error! XkbGetMapChanges failed:\n");
  429. if (changes.changed&XkbKeyTypesMask) {
  430. int first= changes.first_type;
  431. int last= changes.first_type+changes.num_types-1;
  432. fprintf(stderr," types: %d..%d\n",first,last);
  433. }
  434. if (changes.changed&XkbKeySymsMask) {
  435. int first= changes.first_key_sym;
  436. int last= changes.first_key_sym+changes.num_key_syms-1;
  437. fprintf(stderr," symbols: %d..%d\n",first,last);
  438. }
  439. if (changes.changed&XkbKeyActionsMask) {
  440. int last,first= changes.first_key_act;
  441. last= changes.first_key_act+changes.num_key_acts-1;
  442. fprintf(stderr," acts: %d..%d\n",first,last);
  443. }
  444. if (changes.changed&XkbKeyBehaviorsMask) {
  445. int last,first= changes.first_key_behavior;
  446. last= first+changes.num_key_behaviors-1;
  447. fprintf(stderr," behaviors: %d..%d\n",first,last);
  448. }
  449. if (changes.changed&XkbVirtualModsMask) {
  450. fprintf(stderr,"virtual mods: 0x%04x\n",
  451. changes.vmods);
  452. }
  453. if (changes.changed&XkbExplicitComponentsMask) {
  454. int last,first= changes.first_key_explicit;
  455. last= first+changes.num_key_explicit-1;
  456. fprintf(stderr," explicit: %d..%d\n",first,last);
  457. }
  458. #endif
  459. }
  460. LockDisplay(dpy);
  461. if (xkbi->flags&XkbMapPending) {
  462. xkbi->flags&= ~XkbMapPending;
  463. bzero(&xkbi->changes,sizeof(XkbMapChangesRec));
  464. }
  465. UnlockDisplay(dpy);
  466. }
  467. if (event->request==MappingModifier) {
  468. LockDisplay(dpy);
  469. if (xkbi->desc->map->modmap) {
  470. _XkbFree(xkbi->desc->map->modmap);
  471. xkbi->desc->map->modmap= NULL;
  472. }
  473. if (dpy->key_bindings) {
  474. register struct _XKeytrans *p;
  475. for (p = dpy->key_bindings; p; p = p->next) {
  476. register int i;
  477. p->state= 0;
  478. if (p->mlen>0) {
  479. for (i = 0; i < p->mlen; i++) {
  480. p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]);
  481. }
  482. if (p->state) p->state &= AllMods;
  483. else p->state = AnyModifier;
  484. }
  485. }
  486. }
  487. UnlockDisplay(dpy);
  488. }
  489. return 1;
  490. }
  491.  
  492. static int
  493. _XkbLoadDpy(Display *dpy)
  494. {
  495. XkbInfoPtr xkbi;
  496. unsigned query,oldEvents;
  497. XkbDescRec *desc;
  498.  
  499. if (!XkbUseExtension(dpy,NULL,NULL))
  500. return 0;
  501.  
  502. xkbi = dpy->xkb_info;
  503. query = XkbAllClientInfoMask;
  504. desc = XkbGetMap(dpy,query,XkbUseCoreKbd);
  505. if (!desc) {
  506. #ifdef DEBUG
  507. fprintf(stderr,"Warning! XkbGetMap failed!\n");
  508. #endif
  509. return 0;
  510. }
  511. LockDisplay(dpy);
  512. xkbi->desc = desc;
  513.  
  514. UnlockDisplay(dpy);
  515. oldEvents= xkbi->selected_events;
  516. if (!(xkbi->xlib_ctrls&XkbLC_IgnoreNewKeyboards)) {
  517. XkbSelectEventDetails(dpy,xkbi->desc->device_spec,XkbNewKeyboardNotify,
  518. XkbNKN_KeycodesMask|XkbNKN_DeviceIDMask,
  519. XkbNKN_KeycodesMask|XkbNKN_DeviceIDMask);
  520. }
  521. XkbSelectEventDetails(dpy,xkbi->desc->device_spec,XkbMapNotify,
  522. XkbAllClientInfoMask,XkbAllClientInfoMask);
  523. LockDisplay(dpy);
  524. xkbi->selected_events= oldEvents;
  525. UnlockDisplay(dpy);
  526. return 1;
  527. }
  528.  
  529. void
  530. _XkbReloadDpy(Display *dpy)
  531. {
  532. XkbInfoPtr xkbi;
  533. XkbDescRec *desc;
  534. unsigned oldDeviceID;
  535.  
  536. if (_XkbUnavailable(dpy))
  537. return;
  538.  
  539. xkbi = dpy->xkb_info;
  540. LockDisplay(dpy);
  541. if (xkbi->desc) {
  542. oldDeviceID= xkbi->desc->device_spec;
  543. XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,True);
  544. xkbi->desc= NULL;
  545. xkbi->flags&= ~(XkbMapPending|XkbXlibNewKeyboard);
  546. xkbi->changes.changed= 0;
  547. }
  548. else oldDeviceID= XkbUseCoreKbd;
  549. UnlockDisplay(dpy);
  550. desc = XkbGetMap(dpy,XkbAllClientInfoMask,XkbUseCoreKbd);
  551. if (!desc)
  552. return;
  553. LockDisplay(dpy);
  554. xkbi->desc = desc;
  555. UnlockDisplay(dpy);
  556.  
  557. if (desc->device_spec!=oldDeviceID) {
  558. /* transfer(?) event masks here */
  559. #ifdef NOTYET
  560. unsigned oldEvents;
  561. oldEvents= xkbi->selected_events;
  562. XkbSelectEventDetails(dpy,xkbi->desc->device_spec,XkbMapNotify,
  563. XkbAllMapComponentsMask,XkbAllClientInfoMask);
  564. LockDisplay(dpy);
  565. xkbi->selected_events= oldEvents;
  566. UnlockDisplay(dpy);
  567. #endif
  568. }
  569. return;
  570. }
  571.  
  572. int
  573. XkbTranslateKeySym( register Display * dpy,
  574. register KeySym * sym_rtrn,
  575. unsigned int mods,
  576. char * buffer,
  577. int nbytes,
  578. int * extra_rtrn)
  579. {
  580. register XkbInfoPtr xkb;
  581. XkbKSToMBFunc cvtr;
  582. XPointer priv;
  583. char tmp[4];
  584. int n;
  585.  
  586. xkb= dpy->xkb_info;
  587. if (!xkb->cvt.KSToMB) {
  588. _XkbGetConverters(_XkbGetCharset(),&xkb->cvt);
  589. _XkbGetConverters("ISO8859-1",&xkb->latin1cvt);
  590. }
  591.  
  592. if (extra_rtrn)
  593. *extra_rtrn= 0;
  594.  
  595. if ((buffer==NULL)||(nbytes==0)) {
  596. buffer= tmp;
  597. nbytes= 4;
  598. }
  599.  
  600. /* see if symbol rebound, if so, return that string. */
  601. n = XkbLookupKeyBinding(dpy,*sym_rtrn,mods,buffer,nbytes,extra_rtrn);
  602. if (n)
  603. return n;
  604.  
  605. if ( nbytes>0 )
  606. buffer[0]= '\0';
  607.  
  608. if ( xkb->cvt.KSToUpper && (mods&LockMask) ) {
  609. *sym_rtrn = (*xkb->cvt.KSToUpper)(*sym_rtrn);
  610. }
  611. if (xkb->xlib_ctrls & XkbLC_ForceLatin1Lookup) {
  612. cvtr = xkb->latin1cvt.KSToMB;
  613. priv = xkb->latin1cvt.KSToMBPriv;
  614. } else {
  615. cvtr = xkb->cvt.KSToMB;
  616. priv = xkb->cvt.KSToMBPriv;
  617. }
  618.  
  619. n = (*cvtr)(priv,*sym_rtrn,buffer,nbytes,extra_rtrn);
  620.  
  621. if ((!xkb->cvt.KSToUpper)&&( mods&LockMask )) {
  622. register int i;
  623. int change;
  624. char ch;
  625. for (i=change=0;i<n;i++) {
  626. ch= toupper(buffer[i]);
  627. change= (change||(buffer[i]!=ch));
  628. buffer[i] = ch;
  629. }
  630. if (change) {
  631. if (n==1)
  632. *sym_rtrn=(*xkb->cvt.MBToKS)(xkb->cvt.MBToKSPriv,buffer,n,NULL);
  633. else *sym_rtrn= NoSymbol;
  634. }
  635. }
  636.  
  637. if ( mods&ControlMask ) {
  638. if ( n==1 ) {
  639. buffer[0]= XkbToControl(buffer[0]);
  640. if ( nbytes>1 )
  641. buffer[1]= '\0';
  642. return 1;
  643. }
  644. if ( nbytes > 0 )
  645. buffer[0]= '\0';
  646. return 0;
  647. }
  648. return n;
  649. }
  650.  
  651. int
  652. XLookupString ( register XKeyEvent * event,
  653. char * buffer,
  654. int nbytes,
  655. KeySym * keysym,
  656. XComposeStatus * status)
  657. {
  658. KeySym dummy;
  659. int rtrnLen;
  660. unsigned int new_mods;
  661. Display *dpy = event->display;
  662.  
  663. if (keysym==NULL)
  664. keysym= &dummy;
  665. if (!XkbLookupKeySym(dpy,event->keycode,event->state, &new_mods,keysym))
  666. return 0;
  667. new_mods= (event->state&(~new_mods));
  668.  
  669. /* find the group where a symbol can be converted to control one */
  670. if (new_mods&ControlMask && *keysym > 0x7F &&
  671. (dpy->xkb_info->xlib_ctrls & XkbLC_ControlFallback)) {
  672. XKeyEvent tmp_ev = *event;
  673. KeySym tmp_keysym;
  674. unsigned int tmp_new_mods;
  675. if (_XkbUnavailable(dpy)) {
  676. tmp_ev.state= event->state ^ dpy->mode_switch;
  677. if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state,
  678. &tmp_new_mods, &tmp_keysym) &&
  679. tmp_keysym != NoSymbol && tmp_keysym < 0x80 ) {
  680. *keysym = tmp_keysym;
  681. }
  682. } else {
  683. int n = XkbKeyNumGroups(dpy->xkb_info->desc, tmp_ev.keycode);
  684. int i;
  685. for (i = 0; i < n; i++) {
  686. if (XkbGroupForCoreState(event->state) == i)
  687. continue;
  688. tmp_ev.state= XkbBuildCoreState(tmp_ev.state, i);
  689. if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state,
  690. &tmp_new_mods, &tmp_keysym) &&
  691. tmp_keysym != NoSymbol && tmp_keysym < 0x80 ) {
  692. *keysym = tmp_keysym;
  693. new_mods= (event->state&(~tmp_new_mods));
  694. break;
  695. }
  696. }
  697. }
  698. }
  699.  
  700. #ifdef USE_OWN_COMPOSE
  701. if ( status ) {
  702. static int been_here= 0;
  703. if ( !been_here ) {
  704. XimCompInitTables();
  705. been_here = 1;
  706. }
  707. if ( !XimCompLegalStatus(status) ) {
  708. status->compose_ptr = NULL;
  709. status->chars_matched = 0;
  710. }
  711. if ( ((status->chars_matched>0)&&(status->compose_ptr!=NULL)) ||
  712. XimCompIsComposeKey(*keysym,event->keycode,status) ) {
  713. XimCompRtrn rtrn;
  714.  
  715. switch (XimCompProcessSym(status,*keysym,&rtrn)) {
  716. case XIM_COMP_IGNORE:
  717. break;
  718. case XIM_COMP_IN_PROGRESS:
  719. if ( keysym!=NULL )
  720. *keysym = NoSymbol;
  721. #ifndef NO_COMPOSE_LED
  722. if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) {
  723. XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED,
  724. True,True,False,NULL);
  725. }
  726. #endif
  727. return 0;
  728. case XIM_COMP_FAIL:
  729. {
  730. static Atom _ComposeFail= None;
  731. int n = 0, len= 0;
  732. #ifndef NO_COMPOSE_LED
  733. if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) {
  734. XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED,
  735. True,False,False,NULL);
  736. }
  737. #endif
  738. #ifndef NO_BELL_ON_COMPOSE_FAIL
  739. if (dpy->xkb_info->xlib_ctrls&XkbLC_BeepOnComposeFail) {
  740. if (_ComposeFail==None)
  741. _ComposeFail= XInternAtom(dpy,"ComposeFail",0);
  742. XkbBell(dpy,event->window,0,_ComposeFail);
  743. }
  744. #endif
  745. for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
  746. if ( nbytes-len > 0 ) {
  747. len+= XkbTranslateKeySym(dpy,&rtrn.sym[n],new_mods,
  748. buffer+len,nbytes-len,
  749. NULL);
  750. }
  751. }
  752. if ( keysym!=NULL ) {
  753. if ( n==1 ) *keysym = rtrn.sym[0];
  754. else *keysym = NoSymbol;
  755. }
  756. return len;
  757. }
  758. case XIM_COMP_SUCCEED:
  759. {
  760. int len,n = 0;
  761.  
  762. #ifndef NO_COMPOSE_LED
  763. if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) {
  764. XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED,
  765. True,False,False,NULL);
  766. }
  767. #endif
  768. *keysym = rtrn.matchSym;
  769. if ( rtrn.str[0]!='\0' ) {
  770. strncpy(buffer,rtrn.str,nbytes-1);
  771. buffer[nbytes-1]= '\0';
  772. len = (int)strlen(buffer);
  773. }
  774. else {
  775. len = XkbTranslateKeySym(dpy,keysym,new_mods,
  776. buffer,nbytes,
  777. NULL);
  778. }
  779. for (n=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
  780. if ( nbytes-len > 0 ) {
  781. len+= XkbTranslateKeySym(dpy,&rtrn.sym[n],
  782. event->state,
  783. buffer+len,nbytes-len,
  784. NULL);
  785. }
  786. }
  787. return len;
  788. }
  789. }
  790. }
  791. }
  792. #endif
  793.  
  794. /* We *should* use the new_mods (which does not contain any modifiers */
  795. /* that were used to compute the symbol here, but pre-XKB XLookupString */
  796. /* did not and we have to remain compatible. Sigh. */
  797. if (_XkbUnavailable(dpy) ||
  798. (dpy->xkb_info->xlib_ctrls&XkbLC_ConsumeLookupMods)==0)
  799. new_mods= event->state;
  800.  
  801. rtrnLen= XkbLookupKeyBinding(dpy,*keysym,new_mods,buffer,nbytes,NULL);
  802. if (rtrnLen>0)
  803. return rtrnLen;
  804.  
  805. return XkbTranslateKeySym(dpy,keysym,new_mods,buffer,nbytes,NULL);
  806. }
  807.  
  808.  
  809. int
  810. XkbLookupKeyBinding( Display * dpy,
  811. register KeySym sym,
  812. unsigned int mods,
  813. char * buffer,
  814. int nbytes,
  815. int * extra_rtrn)
  816. {
  817. register struct _XKeytrans *p;
  818.  
  819. if (extra_rtrn)
  820. *extra_rtrn= 0;
  821. for (p = dpy->key_bindings; p; p = p->next) {
  822. if (((mods & AllMods) == p->state) && (sym == p->key)) {
  823. int tmp = p->len;
  824. if (tmp > nbytes) {
  825. if (extra_rtrn)
  826. *extra_rtrn= (tmp-nbytes);
  827. tmp = nbytes;
  828. }
  829. memcpy (buffer, p->string, tmp);
  830. if (tmp < nbytes) buffer[tmp]= '\0';
  831. return tmp;
  832. }
  833. }
  834. return 0;
  835. }
  836.  
  837. char
  838. XkbToControl( char ch )
  839. {
  840. register char c = ch;
  841.  
  842. if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
  843. else if (c == '2') c = '\000';
  844. else if (c >= '3' && c <= '7') c -= ('3' - '\033');
  845. else if (c == '8') c = '\177';
  846. else if (c == '/') c = '_' & 0x1F;
  847. return c;
  848. }
  849.