void os2PostKbdEvent(unsigned scanCode, Bool down)
{
	KeyClassRec *keyc = ((DeviceIntPtr)xf86Info.pKeyboard)->key;
	Bool updateLeds = FALSE;
	Bool UsePrefix = FALSE;
	Bool Direction = FALSE;
	xEvent kevent;
	KeySym *keysym;
	int keycode;
	static int lockkeys = 0;

	/*
	 * and now get some special keysequences
	 */
	if ((ModifierDown(ControlMask | AltMask)) ||
	    (ModifierDown(ControlMask | AltLangMask))) {
		switch (scanCode) {
		case KEY_BackSpace:
			if (!xf86Info.dontZap) GiveUp(0);
			return;
		case KEY_KP_Minus: /* Keypad - */
			if (!xf86Info.dontZoom) {
				if (down)
					xf86ZoomViewport(xf86Info.currentScreen, -1);
				return;
	 		}
			break;
		case KEY_KP_Plus: /* Keypad + */
			if (!xf86Info.dontZoom) {
				if (down)
					xf86ZoomViewport(xf86Info.currentScreen, 1);
				return;
			 }
			 break;
		}
	}

	/* CTRL-ESC is std OS/2 hotkey for going back to PM and popping up
	 * window list... handled by keyboard driverand PM if you tell it. This is 
	 * what we have done, and thus should never detect this key combo */
	if (ModifierDown(ControlMask) && scanCode==KEY_Escape) {
		/* eat it */
		return;	
	} else if (ModifierDown(AltLangMask|AltMask) && scanCode==KEY_Escape) {
		/* same here */
		return;
	}

	/*
	 * Now map the scancodes to real X-keycodes ...
	 */
	keycode = scanCode + MIN_KEYCODE;
	keysym = (keyc->curKeySyms.map +
		  keyc->curKeySyms.mapWidth * 
		  (keycode - keyc->curKeySyms.minKeyCode));
#ifdef XKB
	if (noXkbExtension) {
#endif
	/* Filter autorepeated caps/num/scroll lock keycodes. */

#define CAPSFLAG 0x01
#define NUMFLAG 0x02
#define SCROLLFLAG 0x04
#define MODEFLAG 0x08
	if (down) {
		switch (keysym[0]) {
		case XK_Caps_Lock:
			if (lockkeys & CAPSFLAG)
				return;
			else
				lockkeys |= CAPSFLAG;
			break;
		case XK_Num_Lock:
			if (lockkeys & NUMFLAG)
				return;
			else
				lockkeys |= NUMFLAG;
			break;
		case XK_Scroll_Lock:
			if (lockkeys & SCROLLFLAG)
				return;
			else
				lockkeys |= SCROLLFLAG;
			break;
		}

		if (keysym[1] == XF86XK_ModeLock) {
			if (lockkeys & MODEFLAG)
				return;
			else
				lockkeys |= MODEFLAG;
		}
	} else {
		switch (keysym[0]) {
		case XK_Caps_Lock:
			lockkeys &= ~CAPSFLAG;
			break;
		case XK_Num_Lock:
			lockkeys &= ~NUMFLAG;
			break;
		case XK_Scroll_Lock:
			lockkeys &= ~SCROLLFLAG;
			break;
		}

		if (keysym[1] == XF86XK_ModeLock)
			lockkeys &= ~MODEFLAG;
	}

	/*
	 * LockKey special handling:
	 * ignore releases, toggle on & off on presses.
	 * Don't deal with the Caps_Lock keysym directly, 
	 * but check the lock modifier
	 */
#ifndef PC98
	if (keyc->modifierMap[keycode] & LockMask ||
	    keysym[0] == XK_Scroll_Lock ||
	    keysym[1] == XF86XK_ModeLock ||
	    keysym[0] == XK_Num_Lock) {
		Bool flag;

		if (!down) return;
		flag = !KeyPressed(keycode);
		if (!flag) down = !down;

		if (keyc->modifierMap[keycode] & LockMask)
			xf86Info.capsLock = flag;
		if (keysym[0] == XK_Num_Lock)
			xf86Info.numLock = flag;
		if (keysym[0] == XK_Scroll_Lock)
			xf86Info.scrollLock = flag;
		if (keysym[1] == XF86XK_ModeLock)
			xf86Info.modeSwitchLock = flag;
		updateLeds = TRUE;
	}
#endif /* not PC98 */	

	/* normal, non-keypad keys */
	if (scanCode < KEY_KP_7 || scanCode > KEY_KP_Decimal) {
		/* magic ALT_L key on AT84 keyboards for multilingual support */
		if (xf86Info.kbdType == KB_84 &&
		    ModifierDown(AltMask) &&
		    keysym[2] != NoSymbol) {
			UsePrefix = TRUE;
			Direction = TRUE;
		}
	}

#ifdef XKB /* Warning: got position wrong first time */
	}
#endif

	/* check for an autorepeat-event */
	if ((down && KeyPressed(keycode)) &&
	    (xf86Info.autoRepeat != AutoRepeatModeOn || keyc->modifierMap[keycode]))
		return;

	xf86Info.lastEventTime = 
		kevent.u.keyButtonPointer.time = 
		GetTimeInMillis();

	/*
	 * And now send these prefixes ...
	 * NOTE: There cannot be multiple Mode_Switch keys !!!!
	 */
	if (UsePrefix) {
		ENQUEUE(&kevent,
			keyc->modifierKeyMap[keyc->maxKeysPerModifier*7],
			Direction ? KeyPress : KeyRelease,
			XE_KEYBOARD);
		ENQUEUE(&kevent, 
			keycode, 
			down ? KeyPress : KeyRelease,
			XE_KEYBOARD);
		ENQUEUE(&kevent,
			keyc->modifierKeyMap[keyc->maxKeysPerModifier*7],
			Direction ? KeyRelease : KeyPress,
			XE_KEYBOARD);
	} else {
#ifdef XFreeDGA
		if (((ScrnInfoPtr)(xf86Info.currentScreen->devPrivates[xf86ScreenIndex].ptr))->directMode&XF86DGADirectKeyb) {
			XF86DirectVideoKeyEvent(&kevent, 
						keycode,
						down ? KeyPress : KeyRelease);
		} else
#endif
		{
			ENQUEUE(&kevent,
				keycode,
				down ? KeyPress : KeyRelease,
				XE_KEYBOARD);
		}
	}

	if (updateLeds) xf86KbdLeds();
}
Example #2
0
_X_HIDDEN void
sunPostKbdEvent(int sun_ktype, Firm_event *event)
{
    Bool        down;
    KeyClassRec *keyc = ((DeviceIntPtr)xf86Info.pKeyboard)->key;
    Bool        updateLeds = FALSE;
    xEvent      kevent;
    KeySym      *keysym;
    int         keycode;
    static int  lockkeys = 0;

    /* Give down a value */
    if (event->value == VKEY_DOWN)
	down = TRUE;
    else
	down = FALSE;


#if defined(KB_USB)
    if(sun_ktype == KB_USB)
	keycode = usbmap[event->id];
    else
#endif
	keycode = map[event->id];

    /*
     * and now get some special keysequences
     */
    
#ifdef XKB
    if (((xf86Info.ddxSpecialKeys == SKWhenNeeded) &&
	 (!xf86Info.ActionKeyBindingsSet)) ||
	noXkbExtension || (xf86Info.ddxSpecialKeys == SKAlways))
#endif
    {
	if (!(ModifierDown(ShiftMask)) &&
	    ((ModifierDown(ControlMask | AltMask)) ||
	     (ModifierDown(ControlMask | AltLangMask))))
	{
	    switch (keycode) {
	    /*
	     * The idea here is to pass the scancode down to a list of 
	     * registered routines.  There should be some standard conventions
	     * for processing certain keys.
	     */
	    case KEY_BackSpace:
		xf86ProcessActionEvent(ACTION_TERMINATE, NULL);
		break;
		
	    /*
	     * Check grabs
	     */
	    case KEY_KP_Divide:
		xf86ProcessActionEvent(ACTION_DISABLEGRAB, NULL);
		break;
	    case KEY_KP_Multiply:
		xf86ProcessActionEvent(ACTION_CLOSECLIENT, NULL);
		break;
		
	    /*
	     * Video mode switches
	     */
	    case KEY_KP_Minus:   /* Keypad - */
		if (down) xf86ProcessActionEvent(ACTION_PREV_MODE, NULL);
		if (!xf86Info.dontZoom) return;
		break;
		
	    case KEY_KP_Plus:   /* Keypad + */
		if (down) xf86ProcessActionEvent(ACTION_NEXT_MODE, NULL);
		if (!xf86Info.dontZoom) return;
		break;
	    }
	}
    }

    /*
     * Now map the scancodes to real X-keycodes ...
     */
    if (keycode == KEY_NOTUSED) {
	xf86MsgVerb(X_INFO, 0,
	    "raw code %d mapped to KEY_NOTUSED -- please report\n", event->id);
	return;
    }
    if (keycode == KEY_UNKNOWN) {
	xf86MsgVerb(X_INFO, 0,
	    "raw code %d mapped to KEY_UNKNOWN -- please report\n", event->id);
	return;
    }
    keycode += MIN_KEYCODE;
    keysym = keyc->curKeySyms.map +
	     (keyc->curKeySyms.mapWidth *
	      (keycode - keyc->curKeySyms.minKeyCode));

#ifdef XKB
    if (noXkbExtension)
#endif
    {
	/*
	 * Toggle lock keys.
	 */
#define CAPSFLAG 0x01
#define NUMFLAG 0x02
#define SCROLLFLAG 0x04
#define MODEFLAG 0x08

	if (down) {
	    /*
	     * Handle the KeyPresses of the lock keys.
	     */

	    switch (keysym[0]) {

	    case XK_Caps_Lock:
		if (lockkeys & CAPSFLAG) {
		    lockkeys &= ~CAPSFLAG;
		    return;
		}
		lockkeys |= CAPSFLAG;
		updateLeds = TRUE;
		xf86Info.capsLock = down;
		break;

	    case XK_Num_Lock:
		if (lockkeys & NUMFLAG) {
		    lockkeys &= ~NUMFLAG;
		    return;
		}
		lockkeys |= NUMFLAG;
		updateLeds = TRUE;
		xf86Info.numLock = down;
		break;

	    case XK_Scroll_Lock:
		if (lockkeys & SCROLLFLAG) {
		    lockkeys &= ~SCROLLFLAG;
		    return;
		}
		lockkeys |= SCROLLFLAG;
		updateLeds = TRUE;
		xf86Info.scrollLock = down;
		break;
	    }
	} else {
	    /*
	     * Handle the releases of the lock keys.
	     */

	    switch (keysym[0]) {

	    case XK_Caps_Lock:
		if (lockkeys & CAPSFLAG)
		    return;
		updateLeds = TRUE;
		xf86Info.capsLock = down;
		break;

	    case XK_Num_Lock:
		if (lockkeys & NUMFLAG)
		    return;
		updateLeds = TRUE;
		xf86Info.numLock = down;
		break;

	    case XK_Scroll_Lock:
		if (lockkeys & SCROLLFLAG)
		    return;
		updateLeds = TRUE;
		xf86Info.scrollLock = down;
		break;
	    }
	}

  	if (updateLeds)
	    xf86KbdLeds();

	/*
	 * If this keycode is not a modifier key, and its down initiate the
	 * autorepeate sequence.  (Only necessary if not using XKB).
	 *
	 * If its not down, then reset the timer.
	 */
	if (!keyc->modifierMap[keycode]) {
	    if (down) {
		startautorepeat(keycode);
	    } else {
		TimerFree(sunTimer);
		sunTimer = NULL;
	    }
  	}
    }

    xf86Info.lastEventTime =
	kevent.u.keyButtonPointer.time =
	    GetTimeInMillis();

    /*
     * And now send these prefixes ...
     * NOTE: There cannot be multiple Mode_Switch keys !!!!
     */

    ENQUEUE(&kevent, keycode, (down ? KeyPress : KeyRelease), XE_KEYBOARD);
}