示例#1
0
/*
 * Supply raw keystrokes when keyboard is open in firm event mode.
 *
 * Turn the keystroke into an event and put it in the queue.
 * If the queue is full, the keystroke is lost (sorry!).
 */
static void
kbd_input_event(struct kbd_softc *k, int code)
{
	struct firm_event *fe;
	int put;

#ifdef DIAGNOSTIC
	if (!k->k_evmode) {
		printf("%s: kbd_input_event called when not in event mode\n",
		    device_xname(k->k_dev));
		return;
	}
#endif
	put = k->k_events.ev_put;
	fe = &k->k_events.ev_q[put];
	put = (put + 1) % EV_QSIZE;
	if (put == k->k_events.ev_get) {
		log(LOG_WARNING, "%s: event queue overflow\n",
		    device_xname(k->k_dev));
		return;
	}

	fe->id = KEY_CODE(code);
	fe->value = KEY_UP(code) ? VKEY_UP : VKEY_DOWN;
	getmicrotime(&fe->time);
	k->k_events.ev_put = put;
	EV_WAKEUP(&k->k_events);
}
示例#2
0
void
kbdsoftint(void *arg)			/* what if ite is not configured? */
{
	struct kbd_softc *sc = arg;
	int s;

	s = spltty();

	if (sc->sc_event_mode)
		EV_WAKEUP(&sc->sc_events);

	while(kbdgetoff < kbdputoff)
		ite_filter(kbdbuf[kbdgetoff++ & KBDBUFMASK]);
	kbdgetoff = kbdputoff = 0;

	splx(s);
}
示例#3
0
文件: ms.c 项目: lacombar/netbsd-alc
/*
 * we're emulating a mousesystems serial mouse here..
 */
void
msintr(void *arg)
{
	static const char to_one[] = { 1, 2, 2, 4, 4, 4, 4 };
	static const int to_id[] = { MS_RIGHT, MS_MIDDLE, 0, MS_LEFT };
	struct ms_port *ms = arg;
	struct firm_event *fe;
	int mb, ub, d, get, put, any, port;
	u_char pra, *horc, *verc;
	u_short pot, count;
	short dx, dy;

	port = ms->ms_portno;

	horc = ((u_char *) &count) + 1;
	verc = (u_char *) &count;

	/*
	 * first read the three buttons.
	 */
	pot  = custom.potgor;
	pra  = ciaa.pra;
	pot >>= port == 0 ? 8 : 12;	/* contains right and middle button */
	pra >>= port == 0 ? 6 : 7;	/* contains left button */
	mb = (pot & 4) / 4 + (pot & 1) * 2 + (pra & 1) * 4;
	mb ^= 0x07;

	/*
	 * read current values of counter registers
	 */
	if (port == 0)
		count = custom.joy0dat;
	else
		count = custom.joy1dat;

	/*
	 * take care of wraparound
	 */
	dx = *horc - ms->ms_horc;
	if (dx < -127)
		dx += 255;
	else if (dx > 127)
		dx -= 255;
	dy = *verc - ms->ms_verc;
	if (dy < -127)
		dy += 255;
	else if (dy > 127)
		dy -= 255;

	/*
	 * remember current values for next scan
	 */
	ms->ms_horc = *horc;
	ms->ms_verc = *verc;

	ms->ms_dx = dx;
	ms->ms_dy = dy;
	ms->ms_mb = mb;

#if NWSMOUSE > 0
	/*
	 * If we have attached wsmouse and we are not opened
	 * directly then pass events to wscons.
	 */
	if (ms->ms_wsmousedev && ms->ms_wsenabled)
	{
		int buttons = 0;

		if (mb & 4)
			buttons |= 1;
		if (mb & 2)
			buttons |= 2;
		if (mb & 1)
			buttons |= 4;

		wsmouse_input(ms->ms_wsmousedev, 
			      buttons,
			      dx, -dy, 0, 0,
			      WSMOUSE_INPUT_DELTA);

	} else
#endif
	if (dx || dy || ms->ms_ub != ms->ms_mb) {
		/*
		 * We have at least one event (mouse button, delta-X, or
		 * delta-Y; possibly all three, and possibly three separate
		 * button events).  Deliver these events until we are out of
		 * changes or out of room.  As events get delivered, mark them
		 * `unchanged'.
		 */
		any = 0;
		get = ms->ms_events.ev_get;
		put = ms->ms_events.ev_put;
		fe = &ms->ms_events.ev_q[put];

		mb = ms->ms_mb;
		ub = ms->ms_ub;
		while ((d = mb ^ ub) != 0) {
			/*
			 * Mouse button change.  Convert up to three changes
			 * to the `first' change, and drop it into the event
			 * queue.
			 */
			if ((++put) % EV_QSIZE == get) {
				put--;
				goto out;
			}

			d = to_one[d - 1];	/* from 1..7 to {1,2,4} */
			fe->id = to_id[d - 1];	/* from {1,2,4} to ID */
			fe->value = mb & d ? VKEY_DOWN : VKEY_UP;
			getmicrotime(&fe->time);
			fe++;

			if (put >= EV_QSIZE) {
				put = 0;
				fe = &ms->ms_events.ev_q[0];
			}
			any = 1;

			ub ^= d;
		}
		if (ms->ms_dx) {
			if ((++put) % EV_QSIZE == get) {
				put--;
				goto out;
			}

			fe->id = LOC_X_DELTA;
			fe->value = ms->ms_dx;
			getmicrotime(&fe->time);
			fe++;

			if (put >= EV_QSIZE) {
				put = 0;
				fe = &ms->ms_events.ev_q[0];
			}
			any = 1;

			ms->ms_dx = 0;
		}
		if (ms->ms_dy) {
			if ((++put) % EV_QSIZE == get) {
				put--;
				goto out;
			}

			fe->id = LOC_Y_DELTA;
			fe->value = ms->ms_dy;
			getmicrotime(&fe->time);
			fe++;

			if (put >= EV_QSIZE) {
				put = 0;
				fe = &ms->ms_events.ev_q[0];
			}
			any = 1;

			ms->ms_dy = 0;
		}
out:
		if (any) {
			ms->ms_ub = ub;
			ms->ms_events.ev_put = put;
			EV_WAKEUP(&ms->ms_events);
		}
	}

	/*
	 * reschedule handler, or if terminating,
	 * handshake with ms_disable
	 */
	if (ms->ms_ready)
		callout_reset(&ms->ms_intr_ch, 2, msintr, ms);
	else
		wakeup(ms);
}
示例#4
0
/* 
 * Note that we are called from the keyboard software interrupt!
 */
void
mouse_soft(REL_MOUSE *rel_ms, int size, int type)
{
	struct ms_softc		*ms = &ms_softc[0];
	struct firm_event	*fe, *fe2;
	REL_MOUSE		fake_mouse;
	int			get, put;
	int			sps;
	u_char			mbut, bmask;
	int			flush_buttons;

	if (ms->ms_events.ev_io == NULL)
		return;

	switch (type) {
	    case KBD_JOY1_PKG:
		/*
		 * Ignore if in emulation mode
		 */
		if (ms->ms_emul3b)
			return;

		/*
		 * There are some mice that have their middle button
		 * wired to the 'up' bit of joystick 1....
		 * Simulate a mouse packet with dx = dy = 0, the middle
		 * button state set by UP and the other buttons unchanged.
		 * Flush all button changes.
		 */
		flush_buttons = 1;
		fake_mouse.id = (rel_ms->dx & 1 ? 4 : 0) | (ms->ms_buttons & 3);
		fake_mouse.dx = fake_mouse.dy = 0;
		rel_ms = &fake_mouse;
		break;
	    case KBD_TIMEO_PKG:
		/*
		 * Timeout package. No button changes and no movement.
		 * Flush all button changes.
		 */
		flush_buttons = 1;
		fake_mouse.id = ms->ms_buttons;
		fake_mouse.dx = fake_mouse.dy = 0;
		rel_ms = &fake_mouse;
		break;
	    case KBD_RMS_PKG:
		/*
		 * Normal mouse package. Always copy the middle button
		 * status. The emulation code decides if button changes
		 * must be flushed.
		 */
		rel_ms->id = (ms->ms_buttons & 4) | (rel_ms->id & 3);
		flush_buttons = (ms->ms_emul3b) ? 0 : 1;
		break;
	    default:
		return;
	}

	sps = splev();
	get = ms->ms_events.ev_get;
	put = ms->ms_events.ev_put;
	fe  = &ms->ms_events.ev_q[put];

	if ((type != KBD_TIMEO_PKG) && ms->ms_emul3b && ms->ms_bq_idx)
		callout_stop(&ms->ms_delay_ch);

	/*
	 * Button states are encoded in the lower 3 bits of 'id'
	 */
	if (!(mbut = (rel_ms->id ^ ms->ms_buttons)) && (put != get)) {
		/*
		 * Compact dx/dy messages. Always generate an event when
		 * a button is pressed or the event queue is empty.
		 */
		ms->ms_dx += rel_ms->dx;
		ms->ms_dy += rel_ms->dy;
		goto out;
	}
	rel_ms->dx += ms->ms_dx;
	rel_ms->dy += ms->ms_dy;
	ms->ms_dx = ms->ms_dy = 0;

	/*
	 * Output location events _before_ button events ie. make sure
	 * the button is pressed at the correct location.
	 */
	if (rel_ms->dx) {
		if ((++put) % EV_QSIZE == get) {
			put--;
			goto out;
		}
		fe->id    = LOC_X_DELTA;
		fe->value = rel_ms->dx;
		firm_gettime(fe);
		if (put >= EV_QSIZE) {
			put = 0;
			fe  = &ms->ms_events.ev_q[0];
		}
		else fe++;
	}
	if (rel_ms->dy) {
		if ((++put) % EV_QSIZE == get) {
			put--;
			goto out;
		}
		fe->id    = LOC_Y_DELTA;
		fe->value = rel_ms->dy;
		firm_gettime(fe);
		if (put >= EV_QSIZE) {
			put = 0;
			fe  = &ms->ms_events.ev_q[0];
		}
		else fe++;
	}
	if (mbut && (type != KBD_TIMEO_PKG)) {
		for (bmask = 1; bmask < 0x08; bmask <<= 1) {
			if (!(mbut & bmask))
				continue;
			fe2 = &ms->ms_bq[ms->ms_bq_idx++];
			if (bmask == 1)
				fe2->id = MS_RIGHT;
			else if (bmask == 2)
				fe2->id = MS_LEFT;
			else fe2->id = MS_MIDDLE;
			fe2->value = rel_ms->id & bmask ? VKEY_DOWN : VKEY_UP;
			firm_gettime(fe2);
		}
	}

	/*
	 * Handle 3rd button emulation.
	 */
	if (ms->ms_emul3b && ms->ms_bq_idx && (type != KBD_TIMEO_PKG)) {
		/*
		 * If the middle button is pressed, any change to
		 * one of the other buttons releases all.
		 */
		if ((ms->ms_buttons & 4) && (mbut & 3)) {
			ms->ms_bq[0].id = MS_MIDDLE;
			ms->ms_bq_idx   = 1;
			rel_ms->id      = 0;
			flush_buttons   = 1;
			goto out;
		}
	    	if (ms->ms_bq_idx == 2) {
			if (ms->ms_bq[0].value == ms->ms_bq[1].value) {
				/* Must be 2 button presses! */
				ms->ms_bq[0].id = MS_MIDDLE;
				ms->ms_bq_idx   = 1;
				rel_ms->id      = 7;
			}
		}
		else if (ms->ms_bq[0].value == VKEY_DOWN) {
			callout_reset(&ms->ms_delay_ch, 10,
			    (FPV)ms_3b_delay, (void *)ms);
			goto out;
		}
		flush_buttons   = 1;
	}
out:
	if (flush_buttons) {
		int	i;

		for (i = 0; i < ms->ms_bq_idx; i++) {
			if ((++put) % EV_QSIZE == get) {
				ms->ms_bq_idx = 0;
				put--;
				goto out;
			}
			*fe = ms->ms_bq[i];
			if (put >= EV_QSIZE) {
				put = 0;
				fe  = &ms->ms_events.ev_q[0];
			}
			else fe++;
		}
		ms->ms_bq_idx = 0;
	}
	ms->ms_events.ev_put = put;
	ms->ms_buttons       = rel_ms->id;
	splx(sps);
	EV_WAKEUP(&ms->ms_events);
}