Exemple #1
0
static void
adbkbd_cngetc(void *v, u_int *type, int *data)
{
	struct adbkbd_softc *sc = v;
	int key, press, val;
	int s;

	s = splhigh();

	KASSERT(sc->sc_poll);

	DPRINTF("polling...");
	while (sc->sc_polled_chars == 0) {
		sc->sc_ops->poll(sc->sc_ops->cookie);
	}
	DPRINTF(" got one\n");
	splx(s);

	key = sc->sc_pollbuf[0];
	sc->sc_polled_chars--;
	memmove(sc->sc_pollbuf, sc->sc_pollbuf + 1,
		sc->sc_polled_chars);

	press = ADBK_PRESS(key);
	val = ADBK_KEYVAL(key);

	*data = val;
	*type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
}
Exemple #2
0
void
akbd_capslockwrapper(struct akbd_softc *sc, int key)
{
	if (ADBK_KEYVAL(key) == ADBK_CAPSLOCK)
		sc->sc_caps ^= CL_DOWN_ADB;

	if (key != 0xff)
		akbd_input(sc, key);
}
Exemple #3
0
void
akbd_input(struct akbd_softc *sc, int key)
{
	int press, val;
	int type;

	press = ADBK_PRESS(key);
	val = ADBK_KEYVAL(key);

	type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;

	if (adb_polling) {
		adb_polledkey = key;
#ifdef WSDISPLAY_COMPAT_RAWKBD
	} else if (sc->sc_rawkbd) {
		char cbuf[MAXKEYS *2];
		int c, j, s;
		int npress;

		j = npress = 0;

		c = keyboard[val];
		if (c == 0) {
			return; /* XXX */
		}
		if (c & 0x80)
			cbuf[j++] = 0xe0;
		cbuf[j] = c & 0x7f;
		if (type == WSCONS_EVENT_KEY_UP) {
			cbuf[j] |= 0x80;
		} else {
			/* this only records last key pressed */
			if (c & 0x80)
				sc->sc_rep[npress++] = 0xe0;
			sc->sc_rep[npress++] = c & 0x7f;
		}
		j++;
		s = spltty();
		wskbd_rawinput(sc->sc_wskbddev, cbuf, j);
		splx(s);
		timeout_del(&sc->sc_rawrepeat_ch);
		sc->sc_nrep = npress;
		if (npress != 0)
			timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAY1/1000);
#endif
	} else {
		wskbd_input(sc->sc_wskbddev, type, val);
	}
}
Exemple #4
0
void
akbd_input(struct akbd_softc *sc, int key)
{
	int press, val;
	int type;

	press = ADBK_PRESS(key);
	val = ADBK_KEYVAL(key);

	if (sc->sc_iso)
		val = akbd_iso_swap(val);

	type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;

	if (adb_polling) {
		adb_polledkey = key;
#ifdef WSDISPLAY_COMPAT_RAWKBD
	} else if (sc->sc_rawkbd) {
		char cbuf[2];
		int c, j, s;

		j = 0;

		c = keyboard[val];
		if (c == 0) {
			return; /* XXX */
		}
		if (c & 0x80)
			cbuf[j++] = 0xe0;
		cbuf[j] = c & 0x7f;
		if (type == WSCONS_EVENT_KEY_UP)
			cbuf[j] |= 0x80;
		j++;
		s = spltty();
		wskbd_rawinput(sc->sc_wskbddev, cbuf, j);
		splx(s);
#endif
	} else {
		wskbd_input(sc->sc_wskbddev, type, val);
	}
}
Exemple #5
0
/*
 * Given a keyboard ADB event, decode the keycodes and pass them to wskbd.
 */
void
akbd_processevent(struct akbd_softc *sc, adb_event_t *event)
{
	switch (event->byte_count) {
	case 1:
		akbd_capslockwrapper(sc, event->bytes[0]);
		break;
	case 2:
		/*
		 * The reset (or power) key sends 0x7f7f on press and
		 * 0xffff on release, and we ignore it.
		 */
		if (event->bytes[0] == event->bytes[1] &&
		    ADBK_KEYVAL(event->bytes[0]) == ADBK_RESET) {
			if (event->bytes[0] == ADBK_KEYDOWN(ADBK_RESET))
				SET(sc->sc_caps, CL_DOWN_RESET);
			else {
				if (ISSET(sc->sc_caps, CL_DOWN_RESET))
					CLR(sc->sc_caps, CL_DOWN_RESET);
				else if (ISSET(sc->sc_caps, CL_DOWN_ADB)) {
					akbd_input(sc, ISSET(sc->sc_caps,
					    CL_DOWN_LOGICAL) ?
					      ADBK_KEYDOWN(ADBK_CAPSLOCK) :
					      ADBK_KEYUP(ADBK_CAPSLOCK));
					sc->sc_caps ^= CL_DOWN_LOGICAL;
				}
			}
		} else {
			akbd_capslockwrapper(sc, event->bytes[0]);
			akbd_capslockwrapper(sc, event->bytes[1]);
		}
		break;
	default:
#ifdef DIAGNOSTIC
		printf("%s: unexpected message length %d\n",
		    sc->sc_dev.dv_xname, event->byte_count);
#endif
		break;
	}

}
Exemple #6
0
/*
 * Cancels the currently repeating key event if there is one, schedules
 * a new repeating key event if needed, and hands the event off to the
 * appropriate subsystem.
 */
static void 
aed_dokeyupdown(adb_event_t *event)
{
	int kbd_key;

	kbd_key = ADBK_KEYVAL(event->u.k.key);
	if (ADBK_PRESS(event->u.k.key) && keyboard[kbd_key][0] != 0) {
		/* ignore shift & control */
		if (aed_sc->sc_repeating != -1) {
			callout_stop(&aed_sc->sc_repeat_ch);
		}
		aed_sc->sc_rptevent = *event;
		aed_sc->sc_repeating = kbd_key;
		callout_reset(&aed_sc->sc_repeat_ch, aed_sc->sc_rptdelay,
		    aed_kbdrpt, (void *)aed_sc);
	} else {
		if (aed_sc->sc_repeating != -1) {
			aed_sc->sc_repeating = -1;
			callout_stop(&aed_sc->sc_repeat_ch);
		}
		aed_sc->sc_rptevent = *event;
	}
	aed_handoff(event);
}
void
akbd_cngetc(void *v, u_int *type, int *data)
{
	int intbits, key, press, val;
	int s;
	extern int adb_intr(void *);
	extern void pm_intr(void *);

	s = splhigh();

	adb_polledkey = -1;
	adb_polling = 1;

	while (adb_polledkey == -1) {
		intbits = via_reg(VIA1, vIFR);

		if (intbits & V1IF_ADBRDY) {
			adb_intr(NULL);
			via_reg(VIA1, vIFR) = V1IF_ADBRDY;
		}
		if (intbits & V1IF_ADBCLK) {
			pm_intr(NULL);
			via_reg(VIA1, vIFR) = 0x10;
		}
	}

	adb_polling = 0;
	splx(s);

	key = adb_polledkey;
	press = ADBK_PRESS(key);
	val = ADBK_KEYVAL(key);

	*data = val;
	*type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
}
Exemple #8
0
/*
 * Handles mouse button emulation via the keyboard.  If the emulation
 * modifier key is down, left and right arrows will generate 2nd and
 * 3rd mouse button events while the 1, 2, and 3 keys will generate
 * the corresponding mouse button event.
 */
static void 
aed_emulate_mouse(adb_event_t *event)
{
	static int emulmodkey_down;
	adb_event_t new_event;

	if (event->u.k.key == ADBK_KEYDOWN(ADBK_OPTION)) {
		emulmodkey_down = 1;
	} else if (event->u.k.key == ADBK_KEYUP(ADBK_OPTION)) {
		/* key up */
		emulmodkey_down = 0;
		if (aed_sc->sc_buttons & 0xfe) {
			aed_sc->sc_buttons &= 1;
			new_event.def_addr = ADBADDR_MS;
			new_event.u.m.buttons = aed_sc->sc_buttons;
			new_event.u.m.dx = new_event.u.m.dy = 0;
			microtime(&new_event.timestamp);
			aed_handoff(&new_event);
		}
	} else if (emulmodkey_down) {
		switch(event->u.k.key) {
#ifdef ALTXBUTTONS
		case ADBK_KEYDOWN(ADBK_1):
			aed_sc->sc_buttons |= 1;	/* left down */
			new_event.def_addr = ADBADDR_MS;
			new_event.u.m.buttons = aed_sc->sc_buttons;
			new_event.u.m.dx = new_event.u.m.dy = 0;
			microtime(&new_event.timestamp);
			aed_handoff(&new_event);
			break;
		case ADBK_KEYUP(ADBK_1):
			aed_sc->sc_buttons &= ~1;	/* left up */
			new_event.def_addr = ADBADDR_MS;
			new_event.u.m.buttons = aed_sc->sc_buttons;
			new_event.u.m.dx = new_event.u.m.dy = 0;
			microtime(&new_event.timestamp);
			aed_handoff(&new_event);
			break;
#endif
		case ADBK_KEYDOWN(ADBK_LEFT):
#ifdef ALTXBUTTONS
		case ADBK_KEYDOWN(ADBK_2):
#endif
			aed_sc->sc_buttons |= 2;	/* middle down */
			new_event.def_addr = ADBADDR_MS;
			new_event.u.m.buttons = aed_sc->sc_buttons;
			new_event.u.m.dx = new_event.u.m.dy = 0;
			microtime(&new_event.timestamp);
			aed_handoff(&new_event);
			break;
		case ADBK_KEYUP(ADBK_LEFT):
#ifdef ALTXBUTTONS
		case ADBK_KEYUP(ADBK_2):
#endif
			aed_sc->sc_buttons &= ~2;	/* middle up */
			new_event.def_addr = ADBADDR_MS;
			new_event.u.m.buttons = aed_sc->sc_buttons;
			new_event.u.m.dx = new_event.u.m.dy = 0;
			microtime(&new_event.timestamp);
			aed_handoff(&new_event);
			break;
		case ADBK_KEYDOWN(ADBK_RIGHT):
#ifdef ALTXBUTTONS
		case ADBK_KEYDOWN(ADBK_3):
#endif
			aed_sc->sc_buttons |= 4;	/* right down */
			new_event.def_addr = ADBADDR_MS;
			new_event.u.m.buttons = aed_sc->sc_buttons;
			new_event.u.m.dx = new_event.u.m.dy = 0;
			microtime(&new_event.timestamp);
			aed_handoff(&new_event);
			break;
		case ADBK_KEYUP(ADBK_RIGHT):
#ifdef ALTXBUTTONS
		case ADBK_KEYUP(ADBK_3):
#endif
			aed_sc->sc_buttons &= ~4;	/* right up */
			new_event.def_addr = ADBADDR_MS;
			new_event.u.m.buttons = aed_sc->sc_buttons;
			new_event.u.m.dx = new_event.u.m.dy = 0;
			microtime(&new_event.timestamp);
			aed_handoff(&new_event);
			break;
		case ADBK_KEYUP(ADBK_SHIFT):
		case ADBK_KEYDOWN(ADBK_SHIFT):
		case ADBK_KEYUP(ADBK_CONTROL):
		case ADBK_KEYDOWN(ADBK_CONTROL):
		case ADBK_KEYUP(ADBK_FLOWER):
		case ADBK_KEYDOWN(ADBK_FLOWER):
			/* ctrl, shift, cmd */
			aed_dokeyupdown(event);
			break;
		default:
			if (event->u.k.key & 0x80)
				/* ignore keyup */
				break;

			/* key down */
			new_event = *event;

			/* send option-down */
			new_event.u.k.key = ADBK_KEYDOWN(ADBK_OPTION);
			new_event.bytes[0] = new_event.u.k.key;
			microtime(&new_event.timestamp);
			aed_dokeyupdown(&new_event);

			/* send key-down */
			new_event.u.k.key = event->bytes[0];
			new_event.bytes[0] = new_event.u.k.key;
			microtime(&new_event.timestamp);
			aed_dokeyupdown(&new_event);

			/* send key-up */
			new_event.u.k.key =
				ADBK_KEYUP(ADBK_KEYVAL(event->bytes[0]));
			microtime(&new_event.timestamp);
			new_event.bytes[0] = new_event.u.k.key;
			aed_dokeyupdown(&new_event);

			/* send option-up */
			new_event.u.k.key = ADBK_KEYUP(ADBK_OPTION);
			new_event.bytes[0] = new_event.u.k.key;
			microtime(&new_event.timestamp);
			aed_dokeyupdown(&new_event);
			break;
		}
	} else {
		aed_dokeyupdown(event);
	}
}
Exemple #9
0
static inline void
adbkbd_key(struct adbkbd_softc *sc, uint8_t k)
{

	if (sc->sc_poll) {
		if (sc->sc_polled_chars >= 16) {
			aprint_error_dev(sc->sc_dev,"polling buffer is full\n");
		}
		sc->sc_pollbuf[sc->sc_polled_chars] = k;
		sc->sc_polled_chars++;
		return;
	}

#if NWSMOUSE > 0
	/* translate some keys to mouse events */
	if (sc->sc_wsmousedev != NULL) {
		if (ADBK_KEYVAL(k) == sc->sc_trans[1]) {
			wsmouse_input(sc->sc_wsmousedev, ADBK_PRESS(k) ? 2 : 0,
			      0, 0, 0, 0,
			      WSMOUSE_INPUT_DELTA);
			return;
		}			
		if (ADBK_KEYVAL(k) == sc->sc_trans[2]) {
			wsmouse_input(sc->sc_wsmousedev, ADBK_PRESS(k) ? 4 : 0,
			      0, 0, 0, 0,
			      WSMOUSE_INPUT_DELTA);
			return;
		}			
	}
#endif

#ifdef WSDISPLAY_COMPAT_RAWKBD
	if (sc->sc_rawkbd) {
		char cbuf[2];
		int s;

		cbuf[0] = k;

		s = spltty();
		wskbd_rawinput(sc->sc_wskbddev, cbuf, 1);
		splx(s);
	} else {
#endif

	if (ADBK_KEYVAL(k) == 0x39) {
		/* caps lock - send up and down */
		if (ADBK_PRESS(k) != sc->sc_capslock) {
			sc->sc_capslock = ADBK_PRESS(k);
			wskbd_input(sc->sc_wskbddev,
			    WSCONS_EVENT_KEY_DOWN, 0x39);
			wskbd_input(sc->sc_wskbddev,
			    WSCONS_EVENT_KEY_UP, 0x39);
		}
	} else {
		/* normal event */
		int type;

		type = ADBK_PRESS(k) ? 
		    WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
		wskbd_input(sc->sc_wskbddev, type, ADBK_KEYVAL(k));
	}
#ifdef WSDISPLAY_COMPAT_RAWKBD
	}
#endif
}