Exemplo n.º 1
0
Arquivo: atkbd.c Projeto: MarginC/kame
/* keyboard interrupt routine */
static int
atkbd_intr(keyboard_t *kbd, void *arg)
{
	atkbd_state_t *state;
	int delay[2];
	int c;

	if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
		/* let the callback function to process the input */
		(*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
					    kbd->kb_callback.kc_arg);
	} else {
		/* read and discard the input; no one is waiting for input */
		do {
			c = atkbd_read_char(kbd, FALSE);
		} while (c != NOKEY);

		if (!KBD_HAS_DEVICE(kbd)) {
			/*
			 * The keyboard was not detected before;
			 * it must have been reconnected!
			 */
			state = (atkbd_state_t *)kbd->kb_data;
			init_keyboard(state->kbdc, &kbd->kb_type,
				      kbd->kb_config);
			atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
			get_typematic(kbd);
			delay[0] = kbd->kb_delay1;
			delay[1] = kbd->kb_delay2;
			atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
			KBD_FOUND_DEVICE(kbd);
		}
	}
	return 0;
}
Exemplo n.º 2
0
static void
akbd_repeat(void *xsc) {
	struct adb_kbd_softc *sc = xsc;
	int notify_kbd = 0;

	/* Fake an up/down key repeat so long as we have the
	   free buffers */
	mtx_lock(&sc->sc_mutex);
		if (sc->buffers < 7) {
			sc->buffer[sc->buffers++] = sc->last_press | (1 << 7);
			sc->buffer[sc->buffers++] = sc->last_press;

			notify_kbd = 1;
		}
	mtx_unlock(&sc->sc_mutex);

	if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd) 
	    && KBD_IS_BUSY(&sc->sc_kbd)) {
		sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
		    KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
	}

	/* Reschedule the callout */
	callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2),
	    akbd_repeat, sc);
}
Exemplo n.º 3
0
static void
sunkbd_repeat(void *v)
{
	struct sunkbd_softc *sc = v;

	if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
		if (sc->sc_repeat_key != -1) {
			sc->sc_repeating = 1;
			sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
			    KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
		}
	}
}
Exemplo n.º 4
0
/* keyboard interrupt routine */
static int
pckbd_intr(keyboard_t *kbd, void *arg)
{
	int c;

	if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
		/* let the callback function to process the input */
		(*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
					    kbd->kb_callback.kc_arg);
	} else {
		/* read and discard the input; no one is waiting for input */
		do {
			c = pckbd_read_char(kbd, FALSE);
		} while (c != NOKEY);
	}
	return 0;
}
Exemplo n.º 5
0
static void
sunkbd_uart_intr(void *arg)
{
	struct sunkbd_softc *sc = arg;
	int pend;

	if (sc->sc_uart->sc_leaving)
		return;

	pend = atomic_readandclear_32(&sc->sc_uart->sc_ttypend);
	if (!(pend & SER_INT_MASK))
		return;

	if (pend & SER_INT_RXREADY) {
		if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
			sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
			    KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
		}
	}
}
Exemplo n.º 6
0
static int
vt_allocate_keyboard(struct vt_device *vd)
{
	int		 idx0, idx;
	keyboard_t	*k0, *k;
	keyboard_info_t	 ki;

	idx0 = kbd_allocate("kbdmux", -1, (void *)&vd->vd_keyboard,
	    vt_kbdevent, vd);
	/* XXX: kb_token lost */
	vd->vd_keyboard = idx0;
	if (idx0 != -1) {
		DPRINTF(20, "%s: kbdmux allocated, idx = %d\n", __func__, idx0);
		k0 = kbd_get_keyboard(idx0);

		for (idx = kbd_find_keyboard2("*", -1, 0);
		     idx != -1;
		     idx = kbd_find_keyboard2("*", -1, idx + 1)) {
			k = kbd_get_keyboard(idx);

			if (idx == idx0 || KBD_IS_BUSY(k))
				continue;

			bzero(&ki, sizeof(ki));
			strcpy(ki.kb_name, k->kb_name);
			ki.kb_unit = k->kb_unit;

			kbdd_ioctl(k0, KBADDKBD, (caddr_t) &ki);
		}
	} else {
		DPRINTF(20, "%s: no kbdmux allocated\n", __func__);
		idx0 = kbd_allocate("*", -1, (void *)&vd->vd_keyboard,
		    vt_kbdevent, vd);
	}
	DPRINTF(20, "%s: vd_keyboard = %d\n", __func__, vd->vd_keyboard);

	return (idx0);
}
Exemplo n.º 7
0
static void
pl050_kmi_intr(void *arg)
{
	struct kmi_softc *sc = arg;
	uint32_t c;

	KMI_CTX_LOCK_ASSERT();

	if ((sc->sc_flags & KMI_FLAG_POLLING) != 0)
		return;

	if (KBD_IS_ACTIVE(&sc->sc_kbd) &&
	    KBD_IS_BUSY(&sc->sc_kbd)) {
		/* let the callback function process the input */
		(sc->sc_kbd.kb_callback.kc_func) (&sc->sc_kbd, KBDIO_KEYINPUT,
		    sc->sc_kbd.kb_callback.kc_arg);
	} else {
		/* read and discard the input, no one is waiting for it */
		do {
			c = kmi_read_char_locked(&sc->sc_kbd, 0);
		} while (c != NOKEY);
	}

}
Exemplo n.º 8
0
static int
ukbd_interrupt(keyboard_t *kbd, void *arg)
{
	usbd_status status = (usbd_status)arg;
	ukbd_state_t *state;
	struct ukbd_data *ud;
	struct timeval tv;
	u_long now;
	int mod, omod;
	int key, c;
	int i, j;

	DPRINTFN(5, ("ukbd_intr: status=%d\n", status));
	if (status == USBD_CANCELLED)
		return 0;

	state = (ukbd_state_t *)kbd->kb_data;
	ud = &state->ks_ndata;

	if (status != USBD_NORMAL_COMPLETION) {
		DPRINTF(("ukbd_intr: status=%d\n", status));
		if (status == USBD_STALLED)
		    usbd_clear_endpoint_stall_async(state->ks_intrpipe);
		return 0;
	}

	if (ud->keycode[0] == KEY_ERROR) {
		return 0;		/* ignore  */
	}

	getmicrouptime(&tv);
	now = (u_long)tv.tv_sec*1000 + (u_long)tv.tv_usec/1000;

#define ADDKEY1(c) 		\
	if (state->ks_inputs < INPUTBUFSIZE) {				\
		state->ks_input[state->ks_inputtail] = (c);		\
		++state->ks_inputs;					\
		state->ks_inputtail = (state->ks_inputtail + 1)%INPUTBUFSIZE; \
	}

	mod = ud->modifiers;
	omod = state->ks_odata.modifiers;
	if (mod != omod) {
		for (i = 0; i < NMOD; i++)
			if (( mod & ukbd_mods[i].mask) !=
			    (omod & ukbd_mods[i].mask))
				ADDKEY1(ukbd_mods[i].key |
				       (mod & ukbd_mods[i].mask
					  ? KEY_PRESS : KEY_RELEASE));
	}

	/* Check for released keys. */
	for (i = 0; i < NKEYCODE; i++) {
		key = state->ks_odata.keycode[i];
		if (key == 0)
			continue;
		for (j = 0; j < NKEYCODE; j++) {
			if (ud->keycode[j] == 0)
				continue;
			if (key == ud->keycode[j])
				goto rfound;
		}
		ADDKEY1(key | KEY_RELEASE);
	rfound:
		;
	}

	/* Check for pressed keys. */
	for (i = 0; i < NKEYCODE; i++) {
		key = ud->keycode[i];
		if (key == 0)
			continue;
		state->ks_ntime[i] = now + kbd->kb_delay1;
		for (j = 0; j < NKEYCODE; j++) {
			if (state->ks_odata.keycode[j] == 0)
				continue;
			if (key == state->ks_odata.keycode[j]) {
				state->ks_ntime[i] = state->ks_otime[j];
				if (state->ks_otime[j] > now)
					goto pfound;
				state->ks_ntime[i] = now + kbd->kb_delay2;
				break;
			}
		}
		ADDKEY1(key | KEY_PRESS);
		/*
		 * If any other key is presently down, force its repeat to be
		 * well in the future (100s).  This makes the last key to be
		 * pressed do the autorepeat.
		 */
		for (j = 0; j < NKEYCODE; j++) {
			if (j != i)
				state->ks_ntime[j] = now + 100 * 1000;
		}
	pfound:
		;
	}

	state->ks_odata = *ud;
	bcopy(state->ks_ntime, state->ks_otime, sizeof(state->ks_ntime));
	if (state->ks_inputs <= 0) {
		return 0;
	}

#ifdef USB_DEBUG
	for (i = state->ks_inputhead, j = 0; j < state->ks_inputs; ++j,
		i = (i + 1)%INPUTBUFSIZE) {
		c = state->ks_input[i];
		DPRINTF(("0x%x (%d) %s\n", c, c,
			(c & KEY_RELEASE) ? "released":"pressed"));
	}
	if (ud->modifiers)
		DPRINTF(("mod:0x%04x ", ud->modifiers));
        for (i = 0; i < NKEYCODE; i++) {
		if (ud->keycode[i])
			DPRINTF(("%d ", ud->keycode[i]));
	}
	DPRINTF(("\n"));
#endif /* USB_DEBUG */

	if (state->ks_polling) {
		return 0;
	}

	if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
		/* let the callback function to process the input */
		(*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
					    kbd->kb_callback.kc_arg);
	} else {
		/* read and discard the input; no one is waiting for it */
		do {
			c = ukbd_read_char(kbd, FALSE);
		} while (c != NOKEY);
	}

	return 0;
}
Exemplo n.º 9
0
static u_int 
adb_kbd_receive_packet(device_t dev, u_char status, 
    u_char command, u_char reg, int len, u_char *data)
{
	struct adb_kbd_softc *sc;

	sc = device_get_softc(dev);

	if (command != ADB_COMMAND_TALK)
		return 0;

	if (reg != 0 || len != 2)
		return (0);

	mtx_lock(&sc->sc_mutex);
		/* 0x7f is always the power button */
		if (data[0] == 0x7f && devctl_process_running()) {
			devctl_notify("PMU", "Button", "pressed", NULL);
			mtx_unlock(&sc->sc_mutex);
			return (0);
		} else if (data[0] == 0xff) {
			mtx_unlock(&sc->sc_mutex);
			return (0);	/* Ignore power button release. */
		}
		if ((data[0] & 0x7f) == 57 && sc->buffers < 7) {
			/* Fake the down/up cycle for caps lock */
			sc->buffer[sc->buffers++] = data[0] & 0x7f;
			sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7);
		} else {
			sc->buffer[sc->buffers++] = data[0];
		}
		if (sc->buffer[sc->buffers-1] < 0xff)
			sc->last_press = sc->buffer[sc->buffers-1];

		if ((data[1] & 0x7f) == 57 && sc->buffers < 7) {
			/* Fake the down/up cycle for caps lock */
			sc->buffer[sc->buffers++] = data[1] & 0x7f;
			sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7);
		} else {
			sc->buffer[sc->buffers++] = data[1];
		}

		if (sc->buffer[sc->buffers-1] < 0xff)
			sc->last_press = sc->buffer[sc->buffers-1];

		/* Stop any existing key repeating */
		callout_stop(&sc->sc_repeater);

		/* Schedule a repeat callback on keydown */
		if (!(sc->last_press & (1 << 7))) {
			callout_reset(&sc->sc_repeater, 
			    ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc);
		}
	mtx_unlock(&sc->sc_mutex);

	cv_broadcast(&sc->sc_cv);

	if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
		sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
			 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
	}

	return (0);
}