예제 #1
0
KeySym
XkbKeycodeToKeysym(Display *dpy,
#if NeedWidePrototypes
		 unsigned int kc,
#else
		 KeyCode kc,
#endif
		 int 	group,
		 int	level)
{
    XkbDescRec	*xkb;

    if (_XkbUnavailable(dpy))
	return NoSymbol;

    _XkbCheckPendingRefresh(dpy,dpy->xkb_info);

    xkb = dpy->xkb_info->desc;
    if ((kc<xkb->min_key_code)||(kc>xkb->max_key_code))
	return NoSymbol;

    if ((group<0)||(level<0)||(group>=XkbKeyNumGroups(xkb,kc)))
	return NoSymbol;
    if (level>=XkbKeyGroupWidth(xkb,kc,group)) {
	/* for compatibility with the core protocol, _always_ allow  */
	/* two symbols in the first two groups.   If either of the   */
	/* two is of type ONE_LEVEL, just replicate the first symbol */
	if ((group>XkbGroup2Index)||(XkbKeyGroupWidth(xkb,kc,group)!=1)||
								(level!=1)) {
	    return NoSymbol;
	}
	level= 0;
    }
    return XkbKeySymEntry(xkb,kc,level,group);
}
예제 #2
0
unsigned
XkbKeysymToModifiers(Display *dpy,KeySym ks)
{
    XkbDescRec *xkb;
    register int i,j;
    register KeySym *pSyms;
    CARD8 mods;

    if (_XkbUnavailable(dpy))
	return _XKeysymToModifiers(dpy,ks);
    _XkbCheckPendingRefresh(dpy,dpy->xkb_info);

    if (_XkbNeedModmap(dpy->xkb_info)&&(!_XkbComputeModmap(dpy)))
	return _XKeysymToModifiers(dpy,ks);

    xkb= dpy->xkb_info->desc;
    mods= 0;
    for (i = xkb->min_key_code; i <= (int)xkb->max_key_code; i++) {
	pSyms= XkbKeySymsPtr(xkb,i);
	for (j=XkbKeyNumSyms(xkb,i)-1;j>=0;j--) {
	    if (pSyms[j]==ks) {
		mods|= xkb->map->modmap[i];
		break;
	    }
	}
    }
    return mods;
}
예제 #3
0
KeySym
XLookupKeysym(register XKeyEvent *event, int col)
{
    Display *dpy = event->display;
    if (_XkbUnavailable(dpy))
	return _XLookupKeysym(event, col);
    _XkbCheckPendingRefresh(dpy,dpy->xkb_info);
    return XKeycodeToKeysym(dpy, event->keycode, col);
}
예제 #4
0
Bool
XkbLookupKeySym(	register Display *	dpy,
			KeyCode 		key,
			register unsigned int 	mods,
			unsigned int *		mods_rtrn,
			KeySym *		keysym_rtrn)
{
    if (_XkbUnavailable(dpy))
	return _XTranslateKey(dpy, key, mods, mods_rtrn, keysym_rtrn);
    _XkbCheckPendingRefresh(dpy,dpy->xkb_info);
    return XkbTranslateKeyCode(dpy->xkb_info->desc,key,mods,mods_rtrn,
								keysym_rtrn);
}
예제 #5
0
KeySym
XKeycodeToKeysym(Display *dpy,
#if NeedWidePrototypes
		 unsigned int kc,
#else
		 KeyCode kc,
#endif
		 int col)
{
    XkbDescRec	*xkb;

    if (_XkbUnavailable(dpy))
	return _XKeycodeToKeysym(dpy, kc, col);

    _XkbCheckPendingRefresh(dpy,dpy->xkb_info);

    xkb = dpy->xkb_info->desc;
    if ((kc<xkb->min_key_code)||(kc>xkb->max_key_code))
	return NoSymbol;

    if (col>3) {
	int lastSym,tmp,nGrp;

	lastSym= 3;
	nGrp= XkbKeyNumGroups(xkb,kc);
	if ((nGrp>0)&&((tmp=XkbKeyGroupWidth(xkb,kc,XkbGroup1Index))>2)) {
	    if (col<=(lastSym+tmp-2))
		return XkbKeycodeToKeysym(dpy,kc,XkbGroup1Index,col-lastSym+2);
	    lastSym+= tmp-2;
	}
	if ((nGrp>1)&&((tmp=XkbKeyGroupWidth(xkb,kc,XkbGroup2Index))>2)) {
	    if (col<=(lastSym+tmp-2))
		return XkbKeycodeToKeysym(dpy,kc,XkbGroup2Index,col-lastSym+2);
	    lastSym+= tmp-2;
	}
	if (nGrp>2) {
	    tmp= XkbKeyGroupWidth(xkb,kc,XkbGroup3Index);
	    if (col<=lastSym+tmp)
		return XkbKeycodeToKeysym(dpy,kc,XkbGroup3Index,col-lastSym);
	    lastSym+= tmp;
	}
	if (nGrp>3) {
	    tmp= XkbKeyGroupWidth(xkb,kc,XkbGroup4Index);
	    if (col<=lastSym+tmp)
		return XkbKeycodeToKeysym(dpy,kc,XkbGroup4Index,col-lastSym);
	}
	return NoSymbol;
    }
    return XkbKeycodeToKeysym(dpy,kc,(col>>1),(col&1));
}
예제 #6
0
void
_XkbReloadDpy(Display *dpy)
{
    XkbInfoPtr xkbi;
    XkbDescRec *desc;
    unsigned	oldDeviceID;

    if (_XkbUnavailable(dpy))
	return;

    xkbi = dpy->xkb_info;
    LockDisplay(dpy);
    if (xkbi->desc) {
	oldDeviceID= xkbi->desc->device_spec;
	XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,True);
	xkbi->desc= NULL;
	xkbi->flags&= ~(XkbMapPending|XkbXlibNewKeyboard);
	xkbi->changes.changed= 0;
    }
    else oldDeviceID= XkbUseCoreKbd;
    UnlockDisplay(dpy);
    desc = XkbGetMap(dpy,XkbAllClientInfoMask,XkbUseCoreKbd);
    if (!desc)
	return;
    LockDisplay(dpy);
    xkbi->desc = desc;
    UnlockDisplay(dpy);

    if (desc->device_spec!=oldDeviceID) {
	/* transfer(?) event masks here */
#ifdef NOTYET
	unsigned oldEvents;
	oldEvents= xkbi->selected_events;
	XkbSelectEventDetails(dpy,xkbi->desc->device_spec,XkbMapNotify,
				XkbAllMapComponentsMask,XkbAllClientInfoMask);
	LockDisplay(dpy);
	xkbi->selected_events= oldEvents;
	UnlockDisplay(dpy);
#endif
    }
    return;
}
예제 #7
0
Status
XkbRefreshKeyboardMapping(register XkbMapNotifyEvent *event)
{
    Display *dpy = event->display;
    XkbInfoPtr xkbi;

    if (_XkbUnavailable(dpy)) {
	_XRefreshKeyboardMapping((XMappingEvent *)event);
	return Success;
    }
    xkbi= dpy->xkb_info;

    if (((event->type&0x7f)-xkbi->codes->first_event)!=XkbEventCode)
	return BadMatch;
    if (event->xkb_type==XkbNewKeyboardNotify) {
	_XkbReloadDpy(dpy);
	return Success;
    }
    if (event->xkb_type==XkbMapNotify) {
	XkbMapChangesRec	changes;
	Status			rtrn;

	if (xkbi->flags&XkbMapPending)
	     changes= xkbi->changes;
	else bzero(&changes,sizeof(changes));
	XkbNoteMapChanges(&changes,event,XKB_XLIB_MAP_MASK);
	LockDisplay(dpy);
	if ((rtrn=XkbGetMapChanges(dpy,xkbi->desc,&changes))!=Success) {
#ifdef DEBUG
	    fprintf(stderr,"Internal Error! XkbGetMapChanges failed:\n");
#endif
	    xkbi->changes= changes;
	}
	else if (xkbi->flags&XkbMapPending) {
	    xkbi->flags&= ~XkbMapPending;
	    bzero(&xkbi->changes,sizeof(XkbMapChangesRec));
	}
	UnlockDisplay(dpy);
	return rtrn;
    }
    return BadMatch;
}
예제 #8
0
KeyCode
XKeysymToKeycode(Display *dpy, KeySym ks)
{
    register int i, j, gotOne;

    if (_XkbUnavailable(dpy))
	return _XKeysymToKeycode(dpy,ks);
    _XkbCheckPendingRefresh(dpy,dpy->xkb_info);

    j= 0;
    do {
	register XkbDescRec *xkb = dpy->xkb_info->desc;
	gotOne= 0;
	for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) {
	    if ( j<(int)XkbKeyNumSyms(xkb,i) ) {
		gotOne = 1;
		if ((XkbKeySym(xkb,i,j)==ks))
		    return i;
	    }
	}
	j++;
    } while (gotOne);
    return 0;
}
예제 #9
0
int
XLookupString (	register XKeyEvent *	event,
		char *			buffer,
		int 			nbytes,
		KeySym *		keysym,
		XComposeStatus *	status)
{
    KeySym	dummy;
    int rtrnLen;
    unsigned int new_mods;
    Display *dpy = event->display;

    if (keysym==NULL)
	keysym= &dummy;
    if (!XkbLookupKeySym(dpy,event->keycode,event->state, &new_mods,keysym))
	return 0;
    new_mods= (event->state&(~new_mods));

    /* find the group where a symbol can be converted to control one */
    if (new_mods&ControlMask && *keysym > 0x7F &&
	(dpy->xkb_info->xlib_ctrls & XkbLC_ControlFallback)) {
	XKeyEvent tmp_ev = *event;
	KeySym tmp_keysym;
	unsigned int tmp_new_mods;
	if (_XkbUnavailable(dpy)) {
            tmp_ev.state= event->state ^ dpy->mode_switch;
            if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state,
                                &tmp_new_mods, &tmp_keysym) &&
                tmp_keysym != NoSymbol && tmp_keysym < 0x80 ) {
                *keysym = tmp_keysym;
            }
        } else {
            int n = XkbKeyNumGroups(dpy->xkb_info->desc, tmp_ev.keycode);
            int i;
            for (i = 0; i < n; i++) {
                if (XkbGroupForCoreState(event->state) == i)
                    continue;
                tmp_ev.state= XkbBuildCoreState(tmp_ev.state, i);
                if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state,
                                     &tmp_new_mods, &tmp_keysym) &&
                    tmp_keysym != NoSymbol && tmp_keysym < 0x80 ) {
                    *keysym = tmp_keysym;
                    new_mods= (event->state&(~tmp_new_mods));
                    break;
                }
            }
        }
    }

#ifdef USE_OWN_COMPOSE
    if ( status ) {
	static int been_here= 0;
	if ( !been_here ) {
	    XimCompInitTables();
	    been_here = 1;
	}
	if ( !XimCompLegalStatus(status) ) {
	    status->compose_ptr = NULL;
	    status->chars_matched = 0;
	}
	if ( ((status->chars_matched>0)&&(status->compose_ptr!=NULL)) ||
		XimCompIsComposeKey(*keysym,event->keycode,status) ) {
	    XimCompRtrn rtrn;

	    switch (XimCompProcessSym(status,*keysym,&rtrn)) {
		case XIM_COMP_IGNORE:
		    break;
		case XIM_COMP_IN_PROGRESS:
		    if ( keysym!=NULL )
			*keysym = NoSymbol;
#ifndef NO_COMPOSE_LED
		    if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) {
			XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED,
						True,True,False,NULL);
		    }
#endif
		    return 0;
		case XIM_COMP_FAIL:
		{
		    static Atom _ComposeFail= None;
		    int n = 0, len= 0;
#ifndef NO_COMPOSE_LED
		    if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) {
			XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED,
						True,False,False,NULL);
		    }
#endif
#ifndef NO_BELL_ON_COMPOSE_FAIL
		    if (dpy->xkb_info->xlib_ctrls&XkbLC_BeepOnComposeFail) {
			if (_ComposeFail==None)
			    _ComposeFail= XInternAtom(dpy,"ComposeFail",0);
			XkbBell(dpy,event->window,0,_ComposeFail);
		    }
#endif
		    for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
			if ( nbytes-len > 0 ) {
			    len+= XkbTranslateKeySym(dpy,&rtrn.sym[n],new_mods,
							buffer+len,nbytes-len,
							NULL);
			}
		    }
		    if ( keysym!=NULL ) {
			if ( n==1 )	*keysym = rtrn.sym[0];
			else		*keysym = NoSymbol;
		    }
		    return len;
		}
		case XIM_COMP_SUCCEED:
		{
		    int len,n = 0;

#ifndef NO_COMPOSE_LED
		    if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) {
			XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED,
						True,False,False,NULL);
		    }
#endif
		    *keysym = rtrn.matchSym;
		    if ( rtrn.str[0]!='\0' ) {
			strncpy(buffer,rtrn.str,nbytes-1);
			buffer[nbytes-1]= '\0';
			len = (int)strlen(buffer);
		    }
		    else {
			len = XkbTranslateKeySym(dpy,keysym,new_mods,
							buffer,nbytes,
							NULL);
		    }
		    for (n=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
			if ( nbytes-len > 0 ) {
			    len+= XkbTranslateKeySym(dpy,&rtrn.sym[n],
							event->state,
							buffer+len,nbytes-len,
							NULL);
			}
		    }
		    return len;
		}
	    }
	}
    }
#endif

    /* We *should* use the new_mods (which does not contain any modifiers */
    /* that were used to compute the symbol here, but pre-XKB XLookupString */
    /* did not and we have to remain compatible.  Sigh. */
    if (_XkbUnavailable(dpy) ||
	(dpy->xkb_info->xlib_ctrls&XkbLC_ConsumeLookupMods)==0)
	new_mods= event->state;

    rtrnLen= XkbLookupKeyBinding(dpy,*keysym,new_mods,buffer,nbytes,NULL);
    if (rtrnLen>0)
	return rtrnLen;

    return XkbTranslateKeySym(dpy,keysym,new_mods,buffer,nbytes,NULL);
}
예제 #10
0
int
XRefreshKeyboardMapping(register XMappingEvent *event)
{
    XkbEvent	*xkbevent = (XkbEvent *)event;
    Display *dpy = event->display;
    XkbMapChangesRec changes;
    XkbInfoPtr xkbi;

    /* always do this for input methods, which still use the old keymap */
    (void) _XRefreshKeyboardMapping(event);

    if (_XkbUnavailable(dpy))
	return 1;

    xkbi = dpy->xkb_info;

    if (((event->type&0x7f)-xkbi->codes->first_event)==XkbEventCode)
	return XkbRefreshKeyboardMapping(&xkbevent->map);

    if (xkbi->flags&XkbXlibNewKeyboard) {
	_XkbReloadDpy(dpy);
	return 1;
    }

    if ((xkbi->flags&XkbMapPending)||(event->request==MappingKeyboard)) {
	if (xkbi->flags&XkbMapPending) {
	    changes= xkbi->changes;
	    _XkbNoteCoreMapChanges(&changes,event,XKB_XLIB_MAP_MASK);
	}
	else {
	    bzero(&changes,sizeof(changes));
	    changes.changed= XkbKeySymsMask;
	    if (xkbi->desc->min_key_code<xkbi->desc->max_key_code) {
		changes.first_key_sym= xkbi->desc->min_key_code;
		changes.num_key_syms= xkbi->desc->max_key_code-
						xkbi->desc->min_key_code+1;
	    }
	    else {
		changes.first_key_sym= event->first_keycode;
		changes.num_key_syms= event->count;
	    }
	}

	if (XkbGetMapChanges(dpy,xkbi->desc, &changes)!=Success) {
#ifdef DEBUG
		fprintf(stderr,"Internal Error! XkbGetMapChanges failed:\n");
		if (changes.changed&XkbKeyTypesMask) {
		    int first= changes.first_type;
		    int last= changes.first_type+changes.num_types-1;
		    fprintf(stderr,"       types:  %d..%d\n",first,last);
		}
		if (changes.changed&XkbKeySymsMask) {
		    int first= changes.first_key_sym;
		    int last= changes.first_key_sym+changes.num_key_syms-1;
		    fprintf(stderr,"     symbols:  %d..%d\n",first,last);
		}
		if (changes.changed&XkbKeyActionsMask) {
		    int last,first= changes.first_key_act;
		    last= changes.first_key_act+changes.num_key_acts-1;
		    fprintf(stderr,"     acts:  %d..%d\n",first,last);
		}
		if (changes.changed&XkbKeyBehaviorsMask) {
		    int last,first= changes.first_key_behavior;
		    last= first+changes.num_key_behaviors-1;
		    fprintf(stderr,"   behaviors:  %d..%d\n",first,last);
		}
		if (changes.changed&XkbVirtualModsMask) {
		    fprintf(stderr,"virtual mods: 0x%04x\n",
					changes.vmods);
		}
		if (changes.changed&XkbExplicitComponentsMask) {
		    int last,first= changes.first_key_explicit;
		    last= first+changes.num_key_explicit-1;
		    fprintf(stderr,"    explicit:  %d..%d\n",first,last);
		}
#endif
	}
	LockDisplay(dpy);
	if (xkbi->flags&XkbMapPending) {
	    xkbi->flags&= ~XkbMapPending;
	    bzero(&xkbi->changes,sizeof(XkbMapChangesRec));
	}
	UnlockDisplay(dpy);
    }
    if (event->request==MappingModifier) {
	LockDisplay(dpy);
	if (xkbi->desc->map->modmap) {
	    _XkbFree(xkbi->desc->map->modmap);
	    xkbi->desc->map->modmap= NULL;
	}
	if (dpy->key_bindings) {
	    register struct _XKeytrans *p;
	    for (p = dpy->key_bindings; p; p = p->next) {
		register int i;
		p->state= 0;
	  	if (p->mlen>0) {
		    for (i = 0; i < p->mlen; i++) {
			p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]);
		    }
		    if (p->state)	p->state &= AllMods;
		    else		p->state = AnyModifier;
		}
	    }
	}
	UnlockDisplay(dpy);
    }
    return 1;
}