Ejemplo n.º 1
0
void
pr_field(const char *pre, struct field *f, const char *sep)
{
	struct field_pc *pc;
	u_int flags;
	int i, n;
	char *p;

	if (sep)
		printf("%s.%s%s", pre, f->name, sep);

	switch (f->format) {
	case FMT_UINT:
		printf("%u", *((u_int *) f->valp));
		break;
	case FMT_INT:
		printf("%d", *((int *) f->valp));
		break;
	case FMT_BOOL:
		printf("%s", *((u_int *) f->valp)? "on" : "off");
		break;
	case FMT_PC:
		pc = f->valp;
		i = pc->max - pc->min;
		n = pc->cur - pc->min;
		printf("%u.%02u%%", n * 100 / i, ((n * 100) % i) * 100 / i);
		break;
	case FMT_KBDTYPE:
		p = int2name(*((u_int *) f->valp), 1,
			     kbtype_tab, TABLEN(kbtype_tab));
		printf("%s", p);
		break;
	case FMT_MSTYPE:
		p = int2name(*((u_int *) f->valp), 1,
			     mstype_tab, TABLEN(mstype_tab));
		printf("%s", p);
		break;
	case FMT_DPYTYPE:
		p = int2name(*((u_int *) f->valp), 1,
			     dpytype_tab, TABLEN(dpytype_tab));
		printf("%s", p);
		break;
	case FMT_KBDENC:
		p = int2name(KB_ENCODING(*((u_int *) f->valp)), 1,
			     kbdenc_tab, TABLEN(kbdenc_tab));
		printf("%s", p);

		flags = KB_VARIANT(*((u_int *) f->valp));
		for (i = 0; i < 32; i++) {
			if (!(flags & (1 << i)))
				continue;
			p = int2name(flags & (1 << i), 1,
				     kbdvar_tab, TABLEN(kbdvar_tab));
			printf(".%s", p);
		}
		break;
	case FMT_KBMAP:
		print_kmap((struct wskbd_map_data *) f->valp);
		break;
	case FMT_SCALE:
		printf("%d,%d,%d,%d,%d,%d,%d", wmcoords.minx, wmcoords.maxx,
		    wmcoords.miny, wmcoords.maxy, wmcoords.swapxy,
		    wmcoords.resx, wmcoords.resy);
		break;
	case FMT_EMUL:
		print_emul((struct wsdisplay_emultype *) f->valp);
		break;
	case FMT_SCREEN:
		print_screen((struct wsdisplay_screentype *) f->valp);
		break;
	case FMT_STRING:
		printf("%s", (const char *)f->valp);
		break;
	default:
		errx(1, "internal error: pr_field: no format %d", f->format);
		break;
	}

	printf("\n");
}
Ejemplo n.º 2
0
void
kbd_show_enc(kvm_t *kd, int idx)
{
#ifndef NOKVM
	struct wscons_keydesc r;
	unsigned long p;
	int found;
	u_int32_t variant;
	struct nameint *n;
#else
	int i;
#endif /* NOKVM */

#ifndef NOKVM
	p = nl[idx].n_value;
	if (p == 0) {
		printf("no tables available for %s keyboard\n\n",
		    kbtype_tab[idx]);
		return;
	}
#endif

	printf("tables available for %s keyboard:\nencoding\n\n",
	    kbtype_tab[idx]);

#ifdef NOKVM
	for (i = 0; kbdenc_tab[i].value; i++)
		printf("%s\n", kbdenc_tab[i].name);
#else
	kvm_read(kd, p, &r, sizeof(r));
	while (r.name != 0) {
		n = &kbdenc_tab[0];
		found = 0;
		while (n->value) {
			if (n->value == KB_ENCODING(r.name)) {
				printf("%s",n->name);
				found++;
			}
			n++;
		}
		if (found == 0) {
			printf("<encoding 0x%04x>",KB_ENCODING(r.name));
			rebuild++;
		}
		n = &kbdvar_tab[0];
		found = 0;
		variant = KB_VARIANT(r.name);
		while (n->value) {
			if ((n->value & KB_VARIANT(r.name)) == n->value) {
				printf(".%s",n->name);
				variant &= ~n->value;
			}
			n++;
		}
		if (variant != 0) {
			printf(".<variant 0x%08x>",variant);
			rebuild++;
		}
		printf("\n");
		p += sizeof(r);
		kvm_read(kd, p, &r, sizeof(r));
	}
#endif
	printf("\n");
}
Ejemplo n.º 3
0
/*
 * WSKBDIO ioctls, handled in both emulation mode and in ``raw'' mode.
 * Some of these have no real effect in raw mode, however.
 */
int
wskbd_displayioctl(struct device *dev, u_long cmd, caddr_t data, int flag,
    struct proc *p)
{
	struct wskbd_softc *sc = (struct wskbd_softc *)dev;
	struct wskbd_bell_data *ubdp, *kbdp;
	struct wskbd_keyrepeat_data *ukdp, *kkdp;
	struct wskbd_map_data *umdp;
	kbd_t enc;
	void *buf;
	int len, error;

	switch (cmd) {
	case WSKBDIO_BELL:
	case WSKBDIO_COMPLEXBELL:
	case WSKBDIO_SETBELL:
	case WSKBDIO_SETKEYREPEAT:
	case WSKBDIO_SETDEFAULTKEYREPEAT:
	case WSKBDIO_SETMAP:
	case WSKBDIO_SETENCODING:
		if ((flag & FWRITE) == 0)
			return (EACCES);
	}

	switch (cmd) {
#define	SETBELL(dstp, srcp, dfltp)					\
    do {								\
	(dstp)->pitch = ((srcp)->which & WSKBD_BELL_DOPITCH) ?		\
	    (srcp)->pitch : (dfltp)->pitch;				\
	(dstp)->period = ((srcp)->which & WSKBD_BELL_DOPERIOD) ?	\
	    (srcp)->period : (dfltp)->period;				\
	(dstp)->volume = ((srcp)->which & WSKBD_BELL_DOVOLUME) ?	\
	    (srcp)->volume : (dfltp)->volume;				\
	(dstp)->which = WSKBD_BELL_DOALL;				\
    } while (0)

	case WSKBDIO_BELL:
		return ((*sc->sc_accessops->ioctl)(sc->sc_accesscookie,
		    WSKBDIO_COMPLEXBELL, (caddr_t)&sc->sc_bell_data, flag, p));

	case WSKBDIO_COMPLEXBELL:
		ubdp = (struct wskbd_bell_data *)data;
		SETBELL(ubdp, ubdp, &sc->sc_bell_data);
		return ((*sc->sc_accessops->ioctl)(sc->sc_accesscookie,
		    WSKBDIO_COMPLEXBELL, (caddr_t)ubdp, flag, p));

	case WSKBDIO_SETBELL:
		kbdp = &sc->sc_bell_data;
setbell:
		ubdp = (struct wskbd_bell_data *)data;
		SETBELL(kbdp, ubdp, kbdp);
		return (0);

	case WSKBDIO_GETBELL:
		kbdp = &sc->sc_bell_data;
getbell:
		ubdp = (struct wskbd_bell_data *)data;
		SETBELL(ubdp, kbdp, kbdp);
		return (0);

	case WSKBDIO_SETDEFAULTBELL:
		if ((error = suser(p, 0)) != 0)
			return (error);
		kbdp = &wskbd_default_bell_data;
		goto setbell;


	case WSKBDIO_GETDEFAULTBELL:
		kbdp = &wskbd_default_bell_data;
		goto getbell;

#undef SETBELL

#define	SETKEYREPEAT(dstp, srcp, dfltp)					\
    do {								\
	(dstp)->del1 = ((srcp)->which & WSKBD_KEYREPEAT_DODEL1) ?	\
	    (srcp)->del1 : (dfltp)->del1;				\
	(dstp)->delN = ((srcp)->which & WSKBD_KEYREPEAT_DODELN) ?	\
	    (srcp)->delN : (dfltp)->delN;				\
	(dstp)->which = WSKBD_KEYREPEAT_DOALL;				\
    } while (0)

	case WSKBDIO_SETKEYREPEAT:
		kkdp = &sc->sc_keyrepeat_data;
setkeyrepeat:
		ukdp = (struct wskbd_keyrepeat_data *)data;
		SETKEYREPEAT(kkdp, ukdp, kkdp);
		return (0);

	case WSKBDIO_GETKEYREPEAT:
		kkdp = &sc->sc_keyrepeat_data;
getkeyrepeat:
		ukdp = (struct wskbd_keyrepeat_data *)data;
		SETKEYREPEAT(ukdp, kkdp, kkdp);
		return (0);

	case WSKBDIO_SETDEFAULTKEYREPEAT:
		if ((error = suser(p, 0)) != 0)
			return (error);
		kkdp = &wskbd_default_keyrepeat_data;
		goto setkeyrepeat;


	case WSKBDIO_GETDEFAULTKEYREPEAT:
		kkdp = &wskbd_default_keyrepeat_data;
		goto getkeyrepeat;

#undef SETKEYREPEAT

	case WSKBDIO_SETMAP:
		umdp = (struct wskbd_map_data *)data;
		if (umdp->maplen > WSKBDIO_MAXMAPLEN)
			return (EINVAL);

		len = umdp->maplen * sizeof(struct wscons_keymap);
		buf = malloc(len, M_TEMP, M_WAITOK);
		error = copyin(umdp->map, buf, len);
		if (error == 0) {
			wskbd_init_keymap(umdp->maplen,
					  &sc->sc_map, &sc->sc_maplen);
			memcpy(sc->sc_map, buf, len);
			/* drop the variant bits handled by the map */
			enc = KB_USER | (KB_VARIANT(sc->id->t_keymap.layout) &
			    KB_HANDLEDBYWSKBD);
			wskbd_update_layout(sc->id, enc);
		}
		free(buf, M_TEMP);
		return(error);

	case WSKBDIO_GETMAP:
		umdp = (struct wskbd_map_data *)data;
		if (umdp->maplen > sc->sc_maplen)
			umdp->maplen = sc->sc_maplen;
		error = copyout(sc->sc_map, umdp->map,
				umdp->maplen*sizeof(struct wscons_keymap));
		return(error);

	case WSKBDIO_GETENCODING:
		*((kbd_t *)data) = sc->id->t_keymap.layout & ~KB_DEFAULT;
		return(0);

	case WSKBDIO_SETENCODING:
		enc = *((kbd_t *)data);
		if (KB_ENCODING(enc) == KB_USER) {
			/* user map must already be loaded */
			if (KB_ENCODING(sc->id->t_keymap.layout) != KB_USER)
				return (EINVAL);
			/* map variants make no sense */
			if (KB_VARIANT(enc) & ~KB_HANDLEDBYWSKBD)
				return (EINVAL);
		} else {
			error = wskbd_load_keymap(&sc->id->t_keymap, enc,
			    &sc->sc_map, &sc->sc_maplen);
			if (error)
				return (error);
		}
		wskbd_update_layout(sc->id, enc);
#if NWSMUX > 0
		/* Update mux default layout */
		if (sc->sc_base.me_parent != NULL)
			wsmux_set_layout(sc->sc_base.me_parent, enc);
#endif
		return (0);
	}

	/*
	 * Try the keyboard driver for WSKBDIO ioctls.  It returns -1
	 * if it didn't recognize the request, and in turn we return
	 * -1 if we didn't recognize the request.
	 */
/* printf("kbdaccess\n"); */
	error = (*sc->sc_accessops->ioctl)(sc->sc_accesscookie, cmd, data,
					   flag, p);
#ifdef WSDISPLAY_COMPAT_RAWKBD
	if (!error && cmd == WSKBDIO_SETMODE && *(int *)data == WSKBD_RAW) {
		int s = spltty();
		sc->id->t_modifiers &= ~(MOD_SHIFT_L | MOD_SHIFT_R
					 | MOD_CONTROL_L | MOD_CONTROL_R
					 | MOD_META_L | MOD_META_R
					 | MOD_COMMAND
					 | MOD_COMMAND1 | MOD_COMMAND2);
#if NWSDISPLAY > 0
		if (sc->sc_repeating) {
			sc->sc_repeating = 0;
			timeout_del(&sc->sc_repeat_ch);
		}
#endif
		splx(s);
	}
#endif
	return (error);
}
Ejemplo n.º 4
0
static void
wscons_add_keyboard(void)
{
    InputAttributes attrs = { };
    DeviceIntPtr dev = NULL;
    InputOption *input_options = NULL;
    char *config_info = NULL;
    int fd, i, rc;
    unsigned int type;
    kbd_t wsenc = 0;

    /* Find keyboard configuration */
    fd = priv_open_device(WSCONS_KBD_DEVICE);
    if (fd == -1) {
        LogMessage(X_ERROR, "wskbd: open %s: %s\n",
                   WSCONS_KBD_DEVICE, strerror(errno));
        return;
    }
    if (ioctl(fd, WSKBDIO_GETENCODING, &wsenc) == -1) {
        LogMessage(X_WARNING, "wskbd: ioctl(WSKBDIO_GETENCODING) "
                   "failed: %s\n", strerror(errno));
        close(fd);
        return;
    }
    if (ioctl(fd, WSKBDIO_GTYPE, &type) == -1) {
        LogMessage(X_WARNING, "wskbd: ioctl(WSKBDIO_GTYPE) "
                   "failed: %s\n", strerror(errno));
        close(fd);
        return;
    }
    close (fd);

    input_options = input_option_new(input_options, "_source", "server/wscons");
    if (input_options == NULL)
        return;

    LogMessage(X_INFO, "config/wscons: checking input device %s\n",
               WSCONS_KBD_DEVICE);
    input_options = input_option_new(input_options, "name", WSCONS_KBD_DEVICE);
    input_options = input_option_new(input_options, "driver", "kbd");

    config_info = Xprintf("wscons:%s", WSCONS_KBD_DEVICE);
    if (!config_info)
        goto unwind;
    if (KB_ENCODING(wsenc) == KB_USER) {
        /* Ignore wscons "user" layout */
        LogMessageVerb(X_INFO, 3, "wskbd: ignoring \"user\" layout\n");
        goto kbd_config_done;
    }
    for (i = 0; kbdenc[i].val; i++)
        if (KB_ENCODING(wsenc) == kbdenc[i].val) {
            LogMessageVerb(X_INFO, 3, "wskbd: using layout %s\n",
                           kbdenc[i].name);
            input_options = input_option_new(input_options,
                                             "xkb_layout", kbdenc[i].name);
            break;
        }
    for (i = 0; kbdvar[i].val; i++)
        if (wsenc == kbdvar[i].val || KB_VARIANT(wsenc) == kbdvar[i].val) {
            LogMessageVerb(X_INFO, 3, "wskbd: using variant %s\n",
                           kbdvar[i].name);
            input_options = input_option_new(input_options,
                                             "xkb_variant", kbdvar[i].name);
            break;
        }
    for (i = 0; kbdopt[i].val; i++)
        if (KB_VARIANT(wsenc) == kbdopt[i].val) {
            LogMessageVerb(X_INFO, 3, "wskbd: using option %s\n",
                           kbdopt[i].name);
            input_options = input_option_new(input_options,
                                             "xkb_options", kbdopt[i].name);
            break;
        }
    for (i = 0; kbdmodel[i].val; i++)
        if (type == kbdmodel[i].val) {
            LogMessageVerb(X_INFO, 3, "wskbd: using model %s\n",
                           kbdmodel[i].name);
            input_options = input_option_new(input_options,
                                             "xkb_model", kbdmodel[i].name);
            break;
        }

 kbd_config_done:
    attrs.flags |= ATTR_KEYBOARD;
    rc = NewInputDeviceRequest(input_options, &attrs, &dev);
    if (rc != Success)
        goto unwind;

    for (; dev; dev = dev->next) {
        free(dev->config_info);
        dev->config_info = strdup(config_info);
    }
 unwind:
    input_option_free_list(&input_options);
}
Ejemplo n.º 5
0
/*
 * WSKBDIO ioctls, handled in both emulation mode and in ``raw'' mode.
 * Some of these have no real effect in raw mode, however.
 */
static int
wskbd_displayioctl(device_t dev, u_long cmd, void *data, int flag,
	struct lwp *l)
{
#ifdef WSDISPLAY_SCROLLSUPPORT
	struct wskbd_scroll_data *usdp, *ksdp;
#endif
	struct wskbd_softc *sc = device_private(dev);
	struct wskbd_bell_data *ubdp, *kbdp;
	struct wskbd_keyrepeat_data *ukdp, *kkdp;
	struct wskbd_map_data *umdp;
	struct wskbd_mapdata md;
	kbd_t enc;
	void *tbuf;
	int len, error;

	switch (cmd) {
#define	SETBELL(dstp, srcp, dfltp)					\
    do {								\
	(dstp)->pitch = ((srcp)->which & WSKBD_BELL_DOPITCH) ?		\
	    (srcp)->pitch : (dfltp)->pitch;				\
	(dstp)->period = ((srcp)->which & WSKBD_BELL_DOPERIOD) ?	\
	    (srcp)->period : (dfltp)->period;				\
	(dstp)->volume = ((srcp)->which & WSKBD_BELL_DOVOLUME) ?	\
	    (srcp)->volume : (dfltp)->volume;				\
	(dstp)->which = WSKBD_BELL_DOALL;				\
    } while (0)

	case WSKBDIO_BELL:
		if ((flag & FWRITE) == 0)
			return (EACCES);
		return ((*sc->sc_accessops->ioctl)(sc->sc_accesscookie,
		    WSKBDIO_COMPLEXBELL, (void *)&sc->sc_bell_data, flag, l));

	case WSKBDIO_COMPLEXBELL:
		if ((flag & FWRITE) == 0)
			return (EACCES);
		ubdp = (struct wskbd_bell_data *)data;
		SETBELL(ubdp, ubdp, &sc->sc_bell_data);
		return ((*sc->sc_accessops->ioctl)(sc->sc_accesscookie,
		    WSKBDIO_COMPLEXBELL, (void *)ubdp, flag, l));

	case WSKBDIO_SETBELL:
		if ((flag & FWRITE) == 0)
			return (EACCES);
		kbdp = &sc->sc_bell_data;
setbell:
		ubdp = (struct wskbd_bell_data *)data;
		SETBELL(kbdp, ubdp, kbdp);
		return (0);

	case WSKBDIO_GETBELL:
		kbdp = &sc->sc_bell_data;
getbell:
		ubdp = (struct wskbd_bell_data *)data;
		SETBELL(ubdp, kbdp, kbdp);
		return (0);

	case WSKBDIO_SETDEFAULTBELL:
		if ((error = kauth_authorize_device(l->l_cred,
		    KAUTH_DEVICE_WSCONS_KEYBOARD_BELL, NULL, NULL,
		    NULL, NULL)) != 0)
			return (error);
		kbdp = &wskbd_default_bell_data;
		goto setbell;


	case WSKBDIO_GETDEFAULTBELL:
		kbdp = &wskbd_default_bell_data;
		goto getbell;

#undef SETBELL

#define	SETKEYREPEAT(dstp, srcp, dfltp)					\
    do {								\
	(dstp)->del1 = ((srcp)->which & WSKBD_KEYREPEAT_DODEL1) ?	\
	    (srcp)->del1 : (dfltp)->del1;				\
	(dstp)->delN = ((srcp)->which & WSKBD_KEYREPEAT_DODELN) ?	\
	    (srcp)->delN : (dfltp)->delN;				\
	(dstp)->which = WSKBD_KEYREPEAT_DOALL;				\
    } while (0)

	case WSKBDIO_SETKEYREPEAT:
		if ((flag & FWRITE) == 0)
			return (EACCES);
		kkdp = &sc->sc_keyrepeat_data;
setkeyrepeat:
		ukdp = (struct wskbd_keyrepeat_data *)data;
		SETKEYREPEAT(kkdp, ukdp, kkdp);
		return (0);

	case WSKBDIO_GETKEYREPEAT:
		kkdp = &sc->sc_keyrepeat_data;
getkeyrepeat:
		ukdp = (struct wskbd_keyrepeat_data *)data;
		SETKEYREPEAT(ukdp, kkdp, kkdp);
		return (0);

	case WSKBDIO_SETDEFAULTKEYREPEAT:
		if ((error = kauth_authorize_device(l->l_cred,
		    KAUTH_DEVICE_WSCONS_KEYBOARD_KEYREPEAT, NULL, NULL,
		    NULL, NULL)) != 0)
			return (error);
		kkdp = &wskbd_default_keyrepeat_data;
		goto setkeyrepeat;


	case WSKBDIO_GETDEFAULTKEYREPEAT:
		kkdp = &wskbd_default_keyrepeat_data;
		goto getkeyrepeat;

#ifdef WSDISPLAY_SCROLLSUPPORT
#define	SETSCROLLMOD(dstp, srcp, dfltp)					\
    do {								\
	(dstp)->mode = ((srcp)->which & WSKBD_SCROLL_DOMODE) ?		\
	    (srcp)->mode : (dfltp)->mode;				\
	(dstp)->modifier = ((srcp)->which & WSKBD_SCROLL_DOMODIFIER) ?	\
	    (srcp)->modifier : (dfltp)->modifier;			\
	(dstp)->which = WSKBD_SCROLL_DOALL;				\
    } while (0)

	case WSKBDIO_SETSCROLL:
		usdp = (struct wskbd_scroll_data *)data;
		ksdp = &sc->sc_scroll_data;
		SETSCROLLMOD(ksdp, usdp, ksdp);
		return (0);

	case WSKBDIO_GETSCROLL:
		usdp = (struct wskbd_scroll_data *)data;
		ksdp = &sc->sc_scroll_data;
		SETSCROLLMOD(usdp, ksdp, ksdp);
		return (0);
#else
	case WSKBDIO_GETSCROLL:
	case WSKBDIO_SETSCROLL:
		return ENODEV;
#endif

#undef SETKEYREPEAT

	case WSKBDIO_SETMAP:
		if ((flag & FWRITE) == 0)
			return (EACCES);
		umdp = (struct wskbd_map_data *)data;
		if (umdp->maplen > WSKBDIO_MAXMAPLEN)
			return (EINVAL);

		len = umdp->maplen*sizeof(struct wscons_keymap);
		tbuf = malloc(len, M_TEMP, M_WAITOK);
		error = copyin(umdp->map, tbuf, len);
		if (error == 0) {
			wskbd_init_keymap(umdp->maplen,
					  &sc->sc_map, &sc->sc_maplen);
			memcpy(sc->sc_map, tbuf, len);
			/* drop the variant bits handled by the map */
			sc->sc_layout = KB_USER |
			      (KB_VARIANT(sc->sc_layout) & KB_HANDLEDBYWSKBD);
			wskbd_update_layout(sc->id, sc->sc_layout);
		}
		free(tbuf, M_TEMP);
		return(error);

	case WSKBDIO_GETMAP:
		umdp = (struct wskbd_map_data *)data;
		if (umdp->maplen > sc->sc_maplen)
			umdp->maplen = sc->sc_maplen;
		error = copyout(sc->sc_map, umdp->map,
				umdp->maplen*sizeof(struct wscons_keymap));
		return(error);

	case WSKBDIO_GETENCODING:
		*((kbd_t *) data) = sc->sc_layout;
		return(0);

	case WSKBDIO_SETENCODING:
		if ((flag & FWRITE) == 0)
			return (EACCES);
		enc = *((kbd_t *)data);
		if (KB_ENCODING(enc) == KB_USER) {
			/* user map must already be loaded */
			if (KB_ENCODING(sc->sc_layout) != KB_USER)
				return (EINVAL);
			/* map variants make no sense */
			if (KB_VARIANT(enc) & ~KB_HANDLEDBYWSKBD)
				return (EINVAL);
		} else {
			md = *(sc->id->t_keymap); /* structure assignment */
			md.layout = enc;
			error = wskbd_load_keymap(&md, &sc->sc_map,
						  &sc->sc_maplen);
			if (error)
				return (error);
		}
		sc->sc_layout = enc;
		wskbd_update_layout(sc->id, enc);
		return (0);

	case WSKBDIO_SETVERSION:
		return wsevent_setversion(sc->sc_base.me_evp, *(int *)data);
	}

	/*
	 * Try the keyboard driver for WSKBDIO ioctls.  It returns -1
	 * if it didn't recognize the request, and in turn we return
	 * -1 if we didn't recognize the request.
	 */
/* printf("kbdaccess\n"); */
	error = (*sc->sc_accessops->ioctl)(sc->sc_accesscookie, cmd, data,
					   flag, l);
#ifdef WSDISPLAY_COMPAT_RAWKBD
	if (!error && cmd == WSKBDIO_SETMODE && *(int *)data == WSKBD_RAW) {
		int s = spltty();
		sc->id->t_modifiers &= ~(MOD_SHIFT_L | MOD_SHIFT_R
					 | MOD_CONTROL_L | MOD_CONTROL_R
					 | MOD_META_L | MOD_META_R
					 | MOD_COMMAND
					 | MOD_COMMAND1 | MOD_COMMAND2);
		if (sc->sc_repeating) {
			sc->sc_repeating = 0;
			callout_stop(&sc->sc_repeat_ch);
		}
		splx(s);
	}
#endif
	return (error);
}