Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106102979
D821.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D821.diff
View Options
Index: head/sys/dev/vt/vt.h
===================================================================
--- head/sys/dev/vt/vt.h
+++ head/sys/dev/vt/vt.h
@@ -260,6 +260,7 @@
unsigned int vw_number; /* (c) Window number. */
int vw_kbdmode; /* (?) Keyboard mode. */
int vw_prev_kbdmode;/* (?) Previous mode. */
+ int vw_kbdstate; /* (?) Keyboard state. */
int vw_grabbed; /* (?) Grab count. */
char *vw_kbdsq; /* Escape sequence queue*/
unsigned int vw_flags; /* (d) Per-window flags. */
Index: head/sys/dev/vt/vt_core.c
===================================================================
--- head/sys/dev/vt/vt_core.c
+++ head/sys/dev/vt/vt_core.c
@@ -298,6 +298,97 @@
}
static int
+vt_save_kbd_mode(struct vt_window *vw, keyboard_t *kbd)
+{
+ int mode, ret;
+
+ mode = 0;
+ ret = kbdd_ioctl(kbd, KDGKBMODE, (caddr_t)&mode);
+ if (ret == ENOIOCTL)
+ ret = ENODEV;
+ if (ret != 0)
+ return (ret);
+
+ vw->vw_kbdmode = mode;
+
+ return (0);
+}
+
+static int
+vt_update_kbd_mode(struct vt_window *vw, keyboard_t *kbd)
+{
+ int ret;
+
+ ret = kbdd_ioctl(kbd, KDSKBMODE, (caddr_t)&vw->vw_kbdmode);
+ if (ret == ENOIOCTL)
+ ret = ENODEV;
+
+ return (ret);
+}
+
+static int
+vt_save_kbd_state(struct vt_window *vw, keyboard_t *kbd)
+{
+ int state, ret;
+
+ state = 0;
+ ret = kbdd_ioctl(kbd, KDGKBSTATE, (caddr_t)&state);
+ if (ret == ENOIOCTL)
+ ret = ENODEV;
+ if (ret != 0)
+ return (ret);
+
+ vw->vw_kbdstate &= ~LOCK_MASK;
+ vw->vw_kbdstate |= state & LOCK_MASK;
+
+ return (0);
+}
+
+static int
+vt_update_kbd_state(struct vt_window *vw, keyboard_t *kbd)
+{
+ int state, ret;
+
+ state = vw->vw_kbdstate & LOCK_MASK;
+ ret = kbdd_ioctl(kbd, KDSKBSTATE, (caddr_t)&state);
+ if (ret == ENOIOCTL)
+ ret = ENODEV;
+
+ return (ret);
+}
+
+static int
+vt_save_kbd_leds(struct vt_window *vw, keyboard_t *kbd)
+{
+ int leds, ret;
+
+ leds = 0;
+ ret = kbdd_ioctl(kbd, KDGETLED, (caddr_t)&leds);
+ if (ret == ENOIOCTL)
+ ret = ENODEV;
+ if (ret != 0)
+ return (ret);
+
+ vw->vw_kbdstate &= ~LED_MASK;
+ vw->vw_kbdstate |= leds & LED_MASK;
+
+ return (0);
+}
+
+static int
+vt_update_kbd_leds(struct vt_window *vw, keyboard_t *kbd)
+{
+ int leds, ret;
+
+ leds = vw->vw_kbdstate & LED_MASK;
+ ret = kbdd_ioctl(kbd, KDSETLED, (caddr_t)&leds);
+ if (ret == ENOIOCTL)
+ ret = ENODEV;
+
+ return (ret);
+}
+
+static int
vt_window_preswitch(struct vt_window *vw, struct vt_window *curvw)
{
@@ -409,7 +500,11 @@
mtx_lock(&Giant);
kbd = kbd_get_keyboard(vd->vd_keyboard);
if (kbd != NULL) {
- kbdd_ioctl(kbd, KDSKBMODE, (void *)&vw->vw_kbdmode);
+ if (curvw->vw_kbdmode == K_XLATE)
+ vt_save_kbd_state(curvw, kbd);
+
+ vt_update_kbd_mode(vw, kbd);
+ vt_update_kbd_state(vw, kbd);
}
mtx_unlock(&Giant);
DPRINTF(10, "%s(ttyv%d) done\n", __func__, vw->vw_number);
@@ -602,7 +697,6 @@
vt_processkey(keyboard_t *kbd, struct vt_device *vd, int c)
{
struct vt_window *vw = vd->vd_curwindow;
- int state = 0;
#if VT_ALT_TO_ESC_HACK
if (c & RELKEY) {
@@ -665,10 +759,9 @@
vt_proc_window_switch(vw);
return (0);
case SLK: {
-
- kbdd_ioctl(kbd, KDGKBSTATE, (caddr_t)&state);
+ vt_save_kbd_state(vw, kbd);
VT_LOCK(vd);
- if (state & SLKED) {
+ if (vw->vw_kbdstate & SLKED) {
/* Turn scrolling on. */
vw->vw_flags |= VWF_SCROLL;
VTBUF_SLCK_ENABLE(&vw->vw_buf);
@@ -1201,13 +1294,11 @@
struct vt_window *vw = tm->tm_softc;
struct vt_device *vd = vw->vw_device;
keyboard_t *kbd;
- int state;
u_int c;
if (vw->vw_kbdsq && *vw->vw_kbdsq)
return (*vw->vw_kbdsq++);
- state = 0;
/* Make sure the splash screen is not there. */
if (vd->vd_flags & VDF_SPLASH) {
/* Remove splash */
@@ -1223,8 +1314,8 @@
return (-1);
/* Force keyboard input mode to K_XLATE */
- c = K_XLATE;
- kbdd_ioctl(kbd, KDSKBMODE, (void *)&c);
+ vw->vw_kbdmode = K_XLATE;
+ vt_update_kbd_mode(vw, kbd);
/* Switch the keyboard to polling to make it work here. */
kbdd_poll(kbd, TRUE);
@@ -1243,8 +1334,8 @@
if (c & SPCLKEY) {
switch (c) {
case SPCLKEY | SLK:
- kbdd_ioctl(kbd, KDGKBSTATE, (caddr_t)&state);
- if (state & SLKED) {
+ vt_save_kbd_state(vw, kbd);
+ if (vw->vw_kbdstate & SLKED) {
/* Turn scrolling on. */
vw->vw_flags |= VWF_SCROLL;
VTBUF_SLCK_ENABLE(&vw->vw_buf);
@@ -1311,7 +1402,7 @@
/* We shall always use the keyboard in the XLATE mode here. */
vw->vw_prev_kbdmode = vw->vw_kbdmode;
vw->vw_kbdmode = K_XLATE;
- (void)kbdd_ioctl(kbd, KDSKBMODE, (caddr_t)&vw->vw_kbdmode);
+ vt_update_kbd_mode(vw, kbd);
kbdd_poll(kbd, TRUE);
}
@@ -1336,7 +1427,7 @@
kbdd_poll(kbd, FALSE);
vw->vw_kbdmode = vw->vw_prev_kbdmode;
- (void)kbdd_ioctl(kbd, KDSKBMODE, (caddr_t)&vw->vw_kbdmode);
+ vt_update_kbd_mode(vw, kbd);
kbdd_disable(kbd);
}
@@ -1890,12 +1981,8 @@
case SETFKEY:
case KDGKBINFO:
case KDGKBTYPE:
- case KDSKBSTATE: /* set keyboard state (locks) */
- case KDGKBSTATE: /* get keyboard state (locks) */
case KDGETREPEAT: /* get keyboard repeat & delay rates */
case KDSETREPEAT: /* set keyboard repeat & delay rates (new) */
- case KDSETLED: /* set keyboard LED status */
- case KDGETLED: /* get keyboard LED status */
case KBADDKBD: /* add/remove keyboard to/from mux */
case KBRELKBD: {
error = 0;
@@ -1915,18 +2002,101 @@
}
return (error);
}
+ case KDGKBSTATE: { /* get keyboard state (locks) */
+ error = 0;
+
+ if (vw == vd->vd_curwindow) {
+ mtx_lock(&Giant);
+ kbd = kbd_get_keyboard(vd->vd_keyboard);
+ if (kbd != NULL)
+ error = vt_save_kbd_state(vw, kbd);
+ mtx_unlock(&Giant);
+
+ if (error != 0)
+ return (error);
+ }
+
+ *(int *)data = vw->vw_kbdstate & LOCK_MASK;
+
+ return (error);
+ }
+ case KDSKBSTATE: { /* set keyboard state (locks) */
+ int state;
+
+ state = *(int *)data;
+ if (state & ~LOCK_MASK)
+ return (EINVAL);
+
+ vw->vw_kbdstate &= ~LOCK_MASK;
+ vw->vw_kbdstate |= state;
+
+ error = 0;
+ if (vw == vd->vd_curwindow) {
+ mtx_lock(&Giant);
+ kbd = kbd_get_keyboard(vd->vd_keyboard);
+ if (kbd != NULL)
+ error = vt_update_kbd_state(vw, kbd);
+ mtx_unlock(&Giant);
+ }
+
+ return (error);
+ }
+ case KDGETLED: { /* get keyboard LED status */
+ error = 0;
+
+ if (vw == vd->vd_curwindow) {
+ mtx_lock(&Giant);
+ kbd = kbd_get_keyboard(vd->vd_keyboard);
+ if (kbd != NULL)
+ error = vt_save_kbd_leds(vw, kbd);
+ mtx_unlock(&Giant);
+
+ if (error != 0)
+ return (error);
+ }
+
+ *(int *)data = vw->vw_kbdstate & LED_MASK;
+
+ return (error);
+ }
+ case KDSETLED: { /* set keyboard LED status */
+ int leds;
+
+ leds = *(int *)data;
+ if (leds & ~LED_MASK)
+ return (EINVAL);
+
+ vw->vw_kbdstate &= ~LED_MASK;
+ vw->vw_kbdstate |= leds;
+
+ error = 0;
+ if (vw == vd->vd_curwindow) {
+ mtx_lock(&Giant);
+ kbd = kbd_get_keyboard(vd->vd_keyboard);
+ if (kbd != NULL)
+ error = vt_update_kbd_leds(vw, kbd);
+ mtx_unlock(&Giant);
+ }
+
+ return (error);
+ }
case KDGKBMODE: {
- int mode = -1;
+ error = 0;
- mtx_lock(&Giant);
- kbd = kbd_get_keyboard(vd->vd_keyboard);
- if (kbd != NULL) {
- kbdd_ioctl(kbd, KDGKBMODE, (void *)&mode);
+ if (vw == vd->vd_curwindow) {
+ mtx_lock(&Giant);
+ kbd = kbd_get_keyboard(vd->vd_keyboard);
+ if (kbd != NULL)
+ error = vt_save_kbd_mode(vw, kbd);
+ mtx_unlock(&Giant);
+
+ if (error != 0)
+ return (error);
}
- mtx_unlock(&Giant);
- DPRINTF(20, "mode %d, vw_kbdmode %d\n", mode, vw->vw_kbdmode);
- *(int *)data = mode;
- return (0);
+
+ *(int *)data = vw->vw_kbdmode;
+
+ return (error);
}
case KDSKBMODE: {
int mode;
@@ -1937,19 +2107,17 @@
case K_RAW:
case K_CODE:
vw->vw_kbdmode = mode;
- if (vw == vd->vd_curwindow) {
- keyboard_t *kbd;
- error = 0;
+ error = 0;
+ if (vw == vd->vd_curwindow) {
mtx_lock(&Giant);
kbd = kbd_get_keyboard(vd->vd_keyboard);
- if (kbd != NULL) {
- error = kbdd_ioctl(kbd, KDSKBMODE,
- (void *)&mode);
- }
+ if (kbd != NULL)
+ error = vt_update_kbd_mode(vw, kbd);
mtx_unlock(&Giant);
}
- return (0);
+
+ return (error);
default:
return (EINVAL);
}
@@ -1977,8 +2145,17 @@
return (0);
case CONS_GETINFO: {
vid_info_t *vi = (vid_info_t *)data;
+ if (vi->size != sizeof(struct vid_info))
+ return (EINVAL);
+
+ if (vw == vd->vd_curwindow) {
+ kbd = kbd_get_keyboard(vd->vd_keyboard);
+ if (kbd != NULL)
+ vt_save_kbd_state(vw, kbd);
+ }
vi->m_num = vd->vd_curwindow->vw_number + 1;
+ vi->mk_keylock = vw->vw_kbdstate & LOCK_MASK;
/* XXX: other fields! */
return (0);
}
@@ -2093,13 +2270,14 @@
(void *)vd, vt_kbdevent, vd);
if (i >= 0) {
if (vd->vd_keyboard != -1) {
+ vt_save_kbd_state(vd->vd_curwindow, kbd);
kbd_release(kbd, (void *)vd);
}
kbd = kbd_get_keyboard(i);
vd->vd_keyboard = i;
- (void)kbdd_ioctl(kbd, KDSKBMODE,
- (caddr_t)&vd->vd_curwindow->vw_kbdmode);
+ vt_update_kbd_mode(vd->vd_curwindow, kbd);
+ vt_update_kbd_state(vd->vd_curwindow, kbd);
} else {
error = EPERM; /* XXX */
}
@@ -2115,6 +2293,7 @@
mtx_unlock(&Giant);
return (EINVAL);
}
+ vt_save_kbd_state(vd->vd_curwindow, kbd);
error = kbd_release(kbd, (void *)vd);
if (error == 0) {
vd->vd_keyboard = -1;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Dec 26, 11:01 AM (11 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15604054
Default Alt Text
D821.diff (9 KB)
Attached To
Mode
D821: Keep keyboard mode and state and restore it when switching window
Attached
Detach File
Event Timeline
Log In to Comment