/* * 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); }
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); }
/* * 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); }
/* * 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); }