Ejemplo n.º 1
0
static
inline
void
map_key(gii_key_event *         ge,
        Visual_Key_Event_Type * ve)
{
  switch(GII_KTYP(ge->sym))
  {
  case GII_KT_FN :
    ve->state = 0;
    /* FIXME: CTRL and ALT */
    switch(ge->sym)
    {
    case GIIK_F1  :
    case GIIK_F2  :
    case GIIK_F3  :
    case GIIK_F4  :
    case GIIK_F5  :
    case GIIK_F6  :
    case GIIK_F7  :
    case GIIK_F8  :
    case GIIK_F9  :
    case GIIK_F10 :
      ve->keycode =
        GII_KVAL(ge->sym) - GII_KVAL(GIIK_F1) + VDI_KSCAN(VDI_K_F1);
      break;

    case GIIK_F11 :
    case GIIK_F12 :
    case GIIK_F13 :
    case GIIK_F14 :
    case GIIK_F15 :
    case GIIK_F16 :
    case GIIK_F17 :
    case GIIK_F18 :
    case GIIK_F19 :
    case GIIK_F20 :
      ve->keycode =
        GII_KVAL(ge->sym) - GII_KVAL(GIIK_F11) + VDI_KSCAN(VDI_K_F11);
      break;

    default :
      ;
      /* FIXME */
    }

    ve->ascii = 0;
    break;

  default :
    ve->state = 0;
    ve->keycode = ge->label;
    ve->ascii = GII_KVAL(ge->sym);
  }
}
Ejemplo n.º 2
0
static inline void
handle_modifier(linkbd_priv *priv, gii_event *ev)
{
	uint32_t mask, old_label;

	/* Handle AltGr properly */
	if (ev->key.label == GIIK_AltR) {
		if (ev->key.sym == GIIK_VOID) {
			ev->key.sym = GIIK_AltGr;
		}
		mask = 1 << (ev->key.sym & GII_KM_MASK);
	} else {
		mask = 1 << (ev->key.label & GII_KM_MASK);
	}
	/* Handle CapsShift properly: shift keys undo CapsLock */
	if ((ev->key.label == GIIK_ShiftL || ev->key.label == GIIK_ShiftR) &&
	    ev->key.sym == GIIK_CapsLock) {
		if (priv->lockedmod & GII_MOD_CAPS) {
			old_label = ev->key.label;
			ev->key.label = GIIK_CapsLock;
			handle_modifier(priv, ev);
			ev->key.label = old_label;
		}
		ev->key.sym = GIIK_Shift;
	}

	if (GII_KVAL(ev->key.label) & GII_KM_LOCK) {
		if (ev->key.type == evKeyPress) {
			if (!(priv->lockedmod & mask)) {
				priv->lockedmod |= mask;
				ioctl(priv->fd, KDSKBLED,
				      MASK2LED(priv->lockedmod));
			} else {
				ev->key.sym = GIIK_VOID;
			}
		} else {
			if ((priv->lockedmod & mask)) {
				if (!(priv->lockedmod2 & mask)) {
					priv->lockedmod2 |= mask;
					ev->key.sym = GIIK_VOID;
				} else {
					priv->lockedmod2 &= ~mask;
					priv->lockedmod &= ~mask;
					ioctl(priv->fd, KDSKBLED,
					      MASK2LED(priv->lockedmod));
				}
			}
		}
	} else {
		if (ev->key.type == evKeyRelease) {
			priv->normalmod &= ~mask;
		} else {
			priv->normalmod |= mask;
		}
	}
	priv->modifiers = priv->lockedmod | priv->normalmod;
}
Ejemplo n.º 3
0
static inline gii_event_mask
GII_keyboard_handle_data(gii_input *inp, int code)
{
	linkbd_priv *priv = LINKBD_PRIV(inp);
	gii_event ev;
	struct kbentry entry;
	int symval, labelval;
	gii_event_mask mask;

	_giiEventBlank(&ev, sizeof(gii_key_event));

	if (code & 0x80) {
		code &= 0x7f;
		ev.key.type = evKeyRelease;
		priv->keydown_buf[code] = 0;
	} else if (priv->keydown_buf[code] == 0) {
		ev.key.type = evKeyPress;
		priv->keydown_buf[code] = 1;

	} else {
		ev.key.type = evKeyRepeat;
	}
	ev.key.button = code;
	/* First update modifiers here so linkey.c can use the value */
	ev.key.modifiers = priv->modifiers;

	if (ev.key.type == evKeyRelease &&
	    GII_KTYP(priv->keydown_sym[code]) != GII_KT_MOD &&
	    priv->keydown_sym[code] != GIIK_VOID) {
		/* We can use the cached values */
		ev.key.sym   = priv->keydown_sym[code];
		ev.key.label = priv->keydown_label[code];
	} else {
		/* Temporarily switch back to the old mode because
		   unicodes aren't available through table lookup in MEDIUMRAW
		*/
		if (ioctl(priv->fd, KDSKBMODE, priv->old_mode) < 0) {
			DPRINT_MISC("Linux-kbd: ioctl(KDSKBMODE) failed.\n");
			return 0;
		}
		/* Look up the keysym without modifiers, which will give us
		 * the key label (more or less).
		 */
		entry.kb_table = 0;
		entry.kb_index = code;
		if (ioctl(priv->fd, KDGKBENT, &entry) < 0) {
			DPRINT_MISC("Linux-kbd: ioctl(KDGKBENT) failed.\n");
			return 0;
		}
		labelval = entry.kb_value;
		if (priv->old_mode == K_UNICODE) labelval &= 0x0fff;

		/* Now look up the full keysym in the kernel's table */

		/* calculate kernel-like shift value */
		entry.kb_table =
		  ((priv->modifiers & GII_MOD_SHIFT) ? (1<<KG_SHIFT)     : 0) |
		  ((priv->modifiers & GII_MOD_CTRL)  ? (1<<KG_CTRL)      : 0) |
		  ((priv->modifiers & GII_MOD_ALT)   ? (1<<KG_ALT)       : 0) |
		  ((priv->modifiers & GII_MOD_ALTGR) ? (1<<KG_ALTGR)     : 0) |
		  ((priv->modifiers & GII_MOD_META)  ? (1<<KG_ALT)       : 0) |
		  ((priv->modifiers & GII_MOD_CAPS)  ? (1<<KG_CAPSSHIFT) : 0);

		entry.kb_index = code;
		if (ioctl(priv->fd, KDGKBENT, &entry) < 0) {
			DPRINT_MISC("Linux-kbd: ioctl(KDGKBENT) failed.\n");
			return 0;
		}

		/* Switch back to MEDIUMRAW */
		if (ioctl(priv->fd, KDSKBMODE, K_MEDIUMRAW) < 0) {
			DPRINT_MISC("Linux-kbd: ioctl(KDSKBMODE) failed.\n");
			return 0;
		}

		switch (entry.kb_value) {

		case K_HOLE:
			DPRINT_EVENTS("Linux-kbd: NOSUCHKEY\n");
			break;

		case K_NOSUCHMAP:
			DPRINT_EVENTS("Linux-kbd: NOSUCHMAP\n");
			entry.kb_value = K_HOLE;
			break;
		}
		symval = entry.kb_value;
		if (priv->old_mode == K_UNICODE) symval &= 0x0fff;

		_gii_linkey_trans(code, labelval, symval, &ev.key);

		if (ev.key.type == evKeyPress) {
			if (priv->accent) {
				if (GII_KTYP(ev.key.sym) != GII_KT_MOD) {
					handle_accent(priv, symval, &ev);
				}
			} else if (KTYP(symval) == KT_DEAD) {
				priv->accent = GII_KVAL(ev.key.sym);
			}
		}
		if (GII_KTYP(ev.key.sym) == GII_KT_DEAD) {
			ev.key.sym = GIIK_VOID;
		}
	}

	/* Keep track of modifier state */
	if (GII_KTYP(ev.key.label) == GII_KT_MOD) {
		/* Modifers don't repeat */
		if (ev.key.type == evKeyRepeat) return 0;

		handle_modifier(priv, &ev);
	}
	/* Now update modifiers again to get the value _after_ the current
	   event */
	ev.key.modifiers = priv->modifiers;

	if (ev.any.type == evKeyPress) {
		priv->keydown_sym[code]    = ev.key.sym;
		priv->keydown_label[code]  = ev.key.label;
	}

	DPRINT_EVENTS("KEY-%s button=0x%02x modifiers=0x%02x "
		"sym=0x%04x label=0x%04x\n",
		(ev.key.type == evKeyRelease) ? "UP" :
		((ev.key.type == evKeyPress) ? "DN" : "RP"),
		ev.key.button, ev.key.modifiers,
		ev.key.sym,  ev.key.label);

	if (priv->call_vtswitch) {
		if (ev.key.label == GIIK_CtrlL && priv->needctrl2switch) {
			if (ev.key.type == evKeyRelease) {
				priv->ctrlstate = 0;
			} else if (ev.key.type == evKeyPress) {
				priv->ctrlstate = 1;
			}
		}
		/* Check for console switch.  Unfortunately, the kernel doesn't
		 * recognize KT_CONS when the keyboard is in RAW or MEDIUMRAW
		 * mode, so _we_ have to.  Sigh.
		 */
		if ((ev.key.type == evKeyPress) &&
		    (KTYP(entry.kb_value) == KT_CONS) && priv->ctrlstate) {
			int rc;
			int new_cons = 1+KVAL(entry.kb_value);

			/* Clear the keydown buffer, since we'll never know
			   what keys the user pressed (or released) while they
			   were away.
			 */
			DPRINT_MISC("Flushing all keys.\n");
			rc = GII_keyboard_flush_keys(inp);

			DPRINT_MISC("Switching to console %d.\n", new_cons);

			if (ioctl(priv->fd, VT_ACTIVATE, new_cons) < 0) {
				perror("ioctl(VT_ACTIVATE)");
			}

			return rc;
		}
	}

	mask = (1 << ev.any.type);

	if (! (inp->curreventmask & mask)) return 0;

	/* finally queue the key event */
	ev.any.size   = sizeof(gii_key_event);
	ev.any.origin = inp->origin;

	_giiEvQueueAdd(inp, &ev);

	return (1 << ev.any.type);
}
Ejemplo n.º 4
0
static int
XLateKey (ggi_key_event * ev)
{
	int         key = 0;

	if (GII_KTYP (ev->label) == GII_KT_DEAD) {
		ev->label = GII_KVAL (ev->label);
	}
	switch (ev->label) {
		case GIIK_P9:
			key = KP_PGUP;
			break;
		case GIIK_PageUp:
			key = K_PGUP;
			break;

		case GIIK_P3:
			key = KP_PGDN;
			break;
		case GIIK_PageDown:
			key = K_PGDN;
			break;

		case GIIK_P7:
			key = KP_HOME;
			break;
		case GIIK_Home:
			key = K_HOME;
			break;

		case GIIK_P1:
			key = KP_END;
			break;
		case GIIK_End:
			key = K_END;
			break;

		case GIIK_P4:
			key = KP_LEFTARROW;
			break;
		case GIIK_Left:
			key = K_LEFTARROW;
			break;

		case GIIK_P6:
			key = KP_RIGHTARROW;
			break;
		case GIIK_Right:
			key = K_RIGHTARROW;
			break;

		case GIIK_P2:
			key = KP_DOWNARROW;
			break;
		case GIIK_Down:
			key = K_DOWNARROW;
			break;

		case GIIK_P8:
			key = KP_UPARROW;
			break;
		case GIIK_Up:
			key = K_UPARROW;
			break;

		case GIIK_P5:
			key = KP_5;
			break;
		case GIIK_PBegin:
			key = K_AUX32;
			break;

		case GIIK_P0:
			key = KP_INS;
			break;
		case GIIK_Insert:
			key = K_INS;
			break;

		case GIIK_PSeparator:
		case GIIK_PDecimal:
			key = KP_DEL;
			break;
		case GIIUC_Delete:
			key = K_DEL;
			break;

		case GIIK_PStar:
			key = KP_MULTIPLY;
			break;
		case GIIK_PPlus:
			key = KP_PLUS;
			break;
		case GIIK_PMinus:
			key = KP_MINUS;
			break;
		case GIIK_PSlash:
			key = KP_DIVIDE;
			break;

		case GIIK_PEnter:
			key = KP_ENTER;
			break;
		case GIIUC_Return:
			key = K_ENTER;
			break;

		case GIIUC_Escape:
			key = K_ESCAPE;
			break;

		case GIIUC_Tab:
			key = K_TAB;
			break;

		case GIIK_F1:
			key = K_F1;
			break;
		case GIIK_F2:
			key = K_F2;
			break;
		case GIIK_F3:
			key = K_F3;
			break;
		case GIIK_F4:
			key = K_F4;
			break;
		case GIIK_F5:
			key = K_F5;
			break;
		case GIIK_F6:
			key = K_F6;
			break;
		case GIIK_F7:
			key = K_F7;
			break;
		case GIIK_F8:
			key = K_F8;
			break;
		case GIIK_F9:
			key = K_F9;
			break;
		case GIIK_F10:
			key = K_F10;
			break;
		case GIIK_F11:
			key = K_F11;
			break;
		case GIIK_F12:
			key = K_F12;
			break;

		case GIIUC_BackSpace:
			key = K_BACKSPACE;
			break;

		case GIIK_ShiftL:
		case GIIK_ShiftR:
			key = K_SHIFT;
			break;

		case GIIK_Execute:
		case GIIK_CtrlL:
		case GIIK_CtrlR:
			key = K_CTRL;
			break;

		case GIIK_AltL:
		case GIIK_MetaL:
		case GIIK_AltR:
		case GIIK_MetaR:
		case GIIK_AltGr:
		case GIIK_ModeSwitch:
			key = K_ALT;
			break;

		case GIIK_Caps:
			key = K_CAPSLOCK;
			break;
		case GIIK_PrintScreen:
			key = K_PRNTSCR;
			break;
		case GIIK_ScrollLock:
			key = K_SCRLCK;
			break;
		case GIIK_Pause:
			key = K_PAUSE;
			break;
		case GIIK_NumLock:
			key = KP_NUMLCK;
			break;

		case GIIUC_Comma:
		case GIIUC_Minus:
		case GIIUC_Period:
			key = ev->label;
			break;
		case GIIUC_Section:
			key = '~';
			break;

		default:
			if (ev->label >= 0 && ev->label <= 9)
				return ev->label;
			if (ev->label >= 'A' && ev->label <= 'Z') {
				return ev->label - 'A' + 'a';
			}
			if (ev->label >= 'a' && ev->label <= 'z')
				return ev->label;

			if (ev->sym <= 0x7f) {
				key = ev->sym;
				if (key >= 'A' && key <= 'Z') {
					key = key - 'A' + 'a';
				}
				return key;
			}
			if (ev->label <= 0x7f) {
				return ev->label;
			}
			break;
	}

	return key;
}