示例#1
0
void
wskbd_cnattach(const struct wskbd_consops *consops, void *conscookie,
	const struct wskbd_mapdata *mapdata)
{
	KASSERT(!wskbd_console_initted);

	wskbd_console_data.t_keymap = mapdata;
	wskbd_update_layout(&wskbd_console_data, mapdata->layout);

	wskbd_console_data.t_consops = consops;
	wskbd_console_data.t_consaccesscookie = conscookie;

#if NWSDISPLAY > 0
	wsdisplay_set_cons_kbd(wskbd_cngetc, wskbd_cnpollc, wskbd_cnbell);
#endif

	wskbd_console_initted = 1;
}
示例#2
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);
}
示例#3
0
void
wskbd_attach(struct device *parent, struct device *self, void *aux)
{
	struct wskbd_softc *sc = (struct wskbd_softc *)self;
	struct wskbddev_attach_args *ap = aux;
	kbd_t layout;
#if NWSMUX > 0
	struct wsmux_softc *wsmux_sc;
	int mux, error;
#endif

	sc->sc_isconsole = ap->console;

#if NWSMUX > 0 || NWSDISPLAY > 0
	sc->sc_base.me_ops = &wskbd_srcops;
#endif
#if NWSMUX > 0
	mux = sc->sc_base.me_dv.dv_cfdata->wskbddevcf_mux;
	if (ap->console) {
		/* Ignore mux for console; it always goes to the console mux. */
		/* printf(" (mux %d ignored for console)", mux); */
		mux = -1;
	}
	if (mux >= 0) {
		printf(" mux %d", mux);
		wsmux_sc = wsmux_getmux(mux);
	} else
		wsmux_sc = NULL;
#else
#if 0	/* not worth keeping, especially since the default value is not -1... */
	if (sc->sc_base.me_dv.dv_cfdata->wskbddevcf_mux >= 0)
		printf(" (mux ignored)");
#endif
#endif	/* NWSMUX > 0 */

	if (ap->console) {
		sc->id = &wskbd_console_data;
	} else {
		sc->id = malloc(sizeof(struct wskbd_internal),
		    M_DEVBUF, M_WAITOK | M_ZERO);
		bcopy(ap->keymap, &sc->id->t_keymap, sizeof(sc->id->t_keymap));
	}

#if NWSDISPLAY > 0
	timeout_set(&sc->sc_repeat_ch, wskbd_repeat, sc);
#endif

	sc->id->t_sc = sc;

	sc->sc_accessops = ap->accessops;
	sc->sc_accesscookie = ap->accesscookie;
	sc->sc_repeating = 0;
	sc->sc_translating = 1;
	sc->sc_ledstate = -1; /* force update */

	/*
	 * If this layout is the default choice of the driver (i.e. the
	 * driver doesn't know better), pick the existing layout of the
	 * current mux, if any.
	 */
	layout = sc->id->t_keymap.layout;
#if NWSMUX > 0
	if (layout & KB_DEFAULT) {
		if (wsmux_sc != NULL && wsmux_get_layout(wsmux_sc) != KB_NONE)
			layout = wsmux_get_layout(wsmux_sc);
	}
#endif
	for (;;) {
		if (wskbd_load_keymap(&sc->id->t_keymap, layout, &sc->sc_map,
		    &sc->sc_maplen) == 0)
			break;
#if NWSMUX > 0
		if (layout == sc->id->t_keymap.layout)
			panic("cannot load keymap");
		if (wsmux_sc != NULL && wsmux_get_layout(wsmux_sc) != KB_NONE) {
			printf("\n%s: cannot load keymap, "
			    "falling back to default\n%s",
			    sc->sc_base.me_dv.dv_xname,
			    sc->sc_base.me_dv.dv_xname);
			layout = wsmux_get_layout(wsmux_sc);
		} else
#endif
			panic("cannot load keymap");
	}
	wskbd_update_layout(sc->id, layout);

	/* set default bell and key repeat data */
	sc->sc_bell_data = wskbd_default_bell_data;
	sc->sc_keyrepeat_data = wskbd_default_keyrepeat_data;

	if (ap->console) {
		KASSERT(wskbd_console_initted); 
		KASSERT(wskbd_console_device == NULL);

		wskbd_console_device = sc;

		printf(": console keyboard");

#if NWSDISPLAY > 0
		wsdisplay_set_console_kbd(&sc->sc_base); /* sets sc_displaydv */
		if (sc->sc_displaydv != NULL)
			printf(", using %s", sc->sc_displaydv->dv_xname);
#endif
	}
	printf("\n");

#if NWSMUX > 0
	if (wsmux_sc != NULL) {
		error = wsmux_attach_sc(wsmux_sc, &sc->sc_base);
		if (error)
			printf("%s: attach error=%d\n",
			    sc->sc_base.me_dv.dv_xname, error);

		/*
		 * Try and set this encoding as the mux default if it
		 * hasn't any yet, and if this is not a driver default
		 * layout (i.e. parent driver pretends to know better).
		 * Note that wsmux_set_layout() rejects layouts with
		 * KB_DEFAULT set.
		 */
		if (wsmux_get_layout(wsmux_sc) == KB_NONE)
			wsmux_set_layout(wsmux_sc, layout);
	}
#endif

#if NWSDISPLAY > 0 && NWSMUX == 0
	if (ap->console == 0) {
		/*
		 * In the non-wsmux world, always connect wskbd0 and wsdisplay0
		 * together.
		 */
		extern struct cfdriver wsdisplay_cd;

		if (wsdisplay_cd.cd_ndevs != 0 && self->dv_unit == 0) {
			if (wskbd_set_display(self,
			    wsdisplay_cd.cd_devs[0]) == 0)
				wsdisplay_set_kbd(wsdisplay_cd.cd_devs[0],
				    (struct wsevsrc *)sc);
		}
	}
#endif
}
示例#4
0
void
wskbd_attach(device_t parent, device_t self, void *aux)
{
	struct wskbd_softc *sc = device_private(self);
	struct wskbddev_attach_args *ap = aux;
#if NWSMUX > 0
	int mux, error;
#endif

 	sc->sc_base.me_dv = self;
	sc->sc_isconsole = ap->console;
	sc->sc_hotkey = NULL;
	sc->sc_hotkeycookie = NULL;
	sc->sc_evtrans_len = 0;
	sc->sc_evtrans = NULL;

#if NWSMUX > 0 || NWSDISPLAY > 0
	sc->sc_base.me_ops = &wskbd_srcops;
#endif
#if NWSMUX > 0
	mux = device_cfdata(sc->sc_base.me_dv)->wskbddevcf_mux;
	if (ap->console) {
		/* Ignore mux for console; it always goes to the console mux. */
		/* printf(" (mux %d ignored for console)", mux); */
		mux = -1;
	}
	if (mux >= 0)
		aprint_normal(" mux %d", mux);
#else
	if (device_cfdata(sc->sc_base.me_dv)->wskbddevcf_mux >= 0)
		aprint_normal(" (mux ignored)");
#endif

	if (ap->console) {
		sc->id = &wskbd_console_data;
	} else {
		sc->id = malloc(sizeof(struct wskbd_internal),
				M_DEVBUF, M_WAITOK|M_ZERO);
		sc->id->t_keymap = ap->keymap;
		wskbd_update_layout(sc->id, ap->keymap->layout);
	}

	callout_init(&sc->sc_repeat_ch, 0);
	callout_setfunc(&sc->sc_repeat_ch, wskbd_repeat, sc);

	sc->id->t_sc = sc;

	sc->sc_accessops = ap->accessops;
	sc->sc_accesscookie = ap->accesscookie;
	sc->sc_repeating = 0;
	sc->sc_translating = 1;
	sc->sc_ledstate = -1; /* force update */

	if (wskbd_load_keymap(sc->id->t_keymap,
			      &sc->sc_map, &sc->sc_maplen) != 0)
		panic("cannot load keymap");

	sc->sc_layout = sc->id->t_keymap->layout;

	/* set default bell and key repeat data */
	sc->sc_bell_data = wskbd_default_bell_data;
	sc->sc_keyrepeat_data = wskbd_default_keyrepeat_data;

#ifdef WSDISPLAY_SCROLLSUPPORT
	sc->sc_scroll_data = wskbd_default_scroll_data;
#endif

	if (ap->console) {
		KASSERT(wskbd_console_initted);
		KASSERT(wskbd_console_device == NULL);

		wskbd_console_device = sc;

		aprint_naive(": console keyboard");
		aprint_normal(": console keyboard");

#if NWSDISPLAY > 0
		wsdisplay_set_console_kbd(&sc->sc_base); /* sets me_dispv */
		if (sc->sc_base.me_dispdv != NULL)
			aprint_normal(", using %s",
			    device_xname(sc->sc_base.me_dispdv));
#endif
	}
	aprint_naive("\n");
	aprint_normal("\n");

#if NWSMUX > 0
	if (mux >= 0) {
		error = wsmux_attach_sc(wsmux_getmux(mux), &sc->sc_base);
		if (error)
			aprint_error_dev(sc->sc_base.me_dv,
			    "attach error=%d\n", error);
	}
#endif

	if (!pmf_device_register(self, wskbd_suspend, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");
	else if (!pmf_class_input_register(self))
		aprint_error_dev(self, "couldn't register as input device\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);
}
示例#6
0
void
wskbd_attach(struct device *parent, struct device *self, void *aux)
{
	struct wskbd_softc *sc = (struct wskbd_softc *)self;
	struct wskbddev_attach_args *ap = aux;
#if NWSMUX > 0
	int mux, error;
#endif

	sc->sc_isconsole = ap->console;

#if NWSMUX > 0 || NWSDISPLAY > 0
	sc->sc_base.me_ops = &wskbd_srcops;
#endif
#if NWSMUX > 0
	mux = sc->sc_base.me_dv.dv_cfdata->wskbddevcf_mux;
	if (ap->console) {
		/* Ignore mux for console; it always goes to the console mux. */
		/* printf(" (mux %d ignored for console)", mux); */
		mux = -1;
	}
	if (mux >= 0)
		printf(" mux %d", mux);
#else
#if 0	/* not worth keeping, especially since the default value is not -1... */
	if (sc->sc_base.me_dv.dv_cfdata->wskbddevcf_mux >= 0)
		printf(" (mux ignored)");
#endif
#endif	/* NWSMUX > 0 */

	if (ap->console) {
		sc->id = &wskbd_console_data;
	} else {
		sc->id = malloc(sizeof(struct wskbd_internal),
		    M_DEVBUF, M_WAITOK | M_ZERO);
		sc->id->t_keymap = ap->keymap;
		wskbd_update_layout(sc->id, ap->keymap->layout);
	}

#if NWSDISPLAY > 0
	timeout_set(&sc->sc_repeat_ch, wskbd_repeat, sc);
#endif

	sc->id->t_sc = sc;

	sc->sc_accessops = ap->accessops;
	sc->sc_accesscookie = ap->accesscookie;
	sc->sc_repeating = 0;
	sc->sc_translating = 1;
	sc->sc_ledstate = -1; /* force update */

	if (wskbd_load_keymap(sc->id->t_keymap,
	    &sc->sc_map, &sc->sc_maplen) != 0)
		panic("cannot load keymap");

	sc->sc_layout = sc->id->t_keymap->layout;

	/* set default bell and key repeat data */
	sc->sc_bell_data = wskbd_default_bell_data;
	sc->sc_keyrepeat_data = wskbd_default_keyrepeat_data;

	if (ap->console) {
		KASSERT(wskbd_console_initted); 
		KASSERT(wskbd_console_device == NULL);

		wskbd_console_device = sc;

		printf(": console keyboard");

#if NWSDISPLAY > 0
		wsdisplay_set_console_kbd(&sc->sc_base); /* sets sc_displaydv */
		if (sc->sc_displaydv != NULL)
			printf(", using %s", sc->sc_displaydv->dv_xname);
#endif
	}
	printf("\n");

#if NWSMUX > 0
	if (mux >= 0) {
		error = wsmux_attach_sc(wsmux_getmux(mux), &sc->sc_base);
		if (error)
			printf("%s: attach error=%d\n",
			    sc->sc_base.me_dv.dv_xname, error);
	}
#endif

#if WSDISPLAY > 0 && NWSMUX == 0
	if (ap->console == 0) {
		/*
		 * In the non-wsmux world, always connect wskbd0 and wsdisplay0
		 * together.
		 */
		extern struct cfdriver wsdisplay_cd;

		if (wsdisplay_cd.cd_ndevs != 0 && self->dv_unit == 0) {
			if (wskbd_set_display(self,
			    wsdisplay_cd.cd_devs[0]) == 0)
				wsdisplay_set_kbd(wsdisplay_cd.cd_devs[0],
				    (struct wsevsrc *)sc);
		}
	}
#endif

}