NetBSD Problem Report #36762

From martin@duskware.de  Fri Aug 10 08:44:00 2007
Return-Path: <martin@duskware.de>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by narn.NetBSD.org (Postfix) with ESMTP id 9749863B8EA
	for <gnats-bugs@gnats.netbsd.org>; Fri, 10 Aug 2007 08:44:00 +0000 (UTC)
Message-Id: <20070810083804.0FCC163B8EA@narn.NetBSD.org>
Date: Fri, 10 Aug 2007 08:38:04 +0000 (UTC)
From: mishka@netbsd.org
Reply-To: mishka@netbsd.org
To: netbsd-bugs-owner@NetBSD.org
Subject: Locking alternative layouts for wskbd
X-Send-Pr-Version: www-1.0

>Number:         36762
>Category:       kern
>Synopsis:       Locking alternative layouts for wskbd
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri Aug 10 08:45:00 +0000 2007
>Last-Modified:  Fri May 16 10:10:02 +0000 2008
>Originator:     Mike M. Volokhov
>Release:        NetBSD-current, 4.x, 3.x
>Organization:
>Environment:
>Description:
Many languages (for example, Greek and Russian) are based on 
completely different alphabet. Such, typesetting with one of
modifiers pressed all the time is just a PITA. It would be good to
have a toogle behaviour of Mode Switch. Also, it's often convenient
to have an ability switch the mode temporarily.

>How-To-Repeat:
Try to use wsconsole with one of the mentioned alphabets. Feel the PITA.
>Fix:
The patch below implements this idea using two different methods
(names somewhat inconsistent in order to be consistent with names
used before):

1) KS_Mode_toggle (modifier, group 1). You can assign it on any
   key and mode will be fixed until you press the key next time.
   This looks exactly like Caps Lock behaviour. For example, F12
   may be used for this purpose:

        keycode 88 = Mode_toggle

2) KS_Cmd_ModeToggle (command, group 4). With this new command you
   can switch the mode by pressing a combination of two keys - any
   Command key (usually Alt or Ctrl) and assigned button. In my own
   setup I usually use the left Shift:

        keycode 42 = Cmd_ModeToggle Shift_L

Old mode switch is also available, but was improved to allow 
switching back from mode2 to mode1, and modes still switched until
the key released. For example, you can use right Alt for temporarily 
switch to the second layout:

        keycode 184 = Mode_switch Multi_key


-------- 8< -------- 8< -------- 8< -------- 8< --------

Index: wskbd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wskbd.c,v
retrieving revision 1.105
diff -u -r1.105 wskbd.c
--- wskbd.c     6 Aug 2007 03:07:52 -0000       1.105
+++ wskbd.c     10 Aug 2007 07:41:17 -0000
@@ -1406,16 +1406,22 @@
 }

 static inline void
-update_modifier(struct wskbd_internal *id, u_int type, int toggle, int mask)
+update_modifier(struct wskbd_internal *id, u_int type, int togglemode, int mask
)
 {
-       if (toggle) {
-               if (type == WSCONS_EVENT_KEY_DOWN)
-                       id->t_modifiers ^= mask;
-       } else {
+       switch (togglemode) {
+       case 0: /* down - on, up - off */
                if (type == WSCONS_EVENT_KEY_DOWN)
                        id->t_modifiers |= mask;
                else
                        id->t_modifiers &= ~mask;
+               break;
+       case 1: /* down - invert */
+               if (type == WSCONS_EVENT_KEY_DOWN)
+                       id->t_modifiers ^= mask;
+               break;
+       case 2: /* either down or up - invert */
+               id->t_modifiers ^= mask;
+               break;
        }
 }

@@ -1503,6 +1509,17 @@
        case KS_Cmd2:
                update_modifier(sc->id, *type, 0, MOD_COMMAND2);
                break;
+
+       case KS_Cmd_ModeToggle:
+               if (*type == WSCONS_EVENT_KEY_DOWN) {
+                   if (MOD_ONESET(sc->id, MOD_COMMAND1 | MOD_COMMAND2)) {
+                       update_modifier(sc->id, *type, 1, MOD_MODESHIFT);
+                       return (1);
+                   } else {
+                       return (0);
+                   }
+               }
+               break;
        }

        if (*type != WSCONS_EVENT_KEY_DOWN ||
@@ -1648,7 +1665,11 @@
                break;

        case KS_Mode_switch:
-               update_modifier(id, type, 0, MOD_MODESHIFT);
+               update_modifier(id, type, 2, MOD_MODESHIFT);
+               break;
+
+       case KS_Mode_toggle:
+               update_modifier(id, type, 1, MOD_MODESHIFT);
                break;

        case KS_Num_Lock:
Index: wsksymdef.h
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wsksymdef.h,v
retrieving revision 1.58
diff -u -r1.58 wsksymdef.h
--- wsksymdef.h 4 Apr 2007 14:50:21 -0000       1.58
+++ wsksymdef.h 10 Aug 2007 07:41:17 -0000
@@ -377,6 +377,7 @@
 #define KS_Henkan_Mode         0xf114  /* Start/Stop Conversion */
 #define KS_Henkan              0xf115  /* Alias for Henkan_Mode */
 #define KS_Muhenkan            0xf116  /* Cancel Conversion */
+#define KS_Mode_toggle         0xf117

 /*
  * Group 2 (keypad) character in low byte
@@ -524,6 +525,7 @@
 #define KS_Cmd_ScrollFastDown  0xf42d
 #define KS_Cmd_ScrollSlowUp    0xf42e
 #define KS_Cmd_ScrollSlowDown  0xf42f
+#define KS_Cmd_ModeToggle      0xf430

 /*
  * Group 5 (internal)
-------- 8< -------- 8< -------- 8< -------- 8< --------

P.S. I've committed extended version of patch some time ago, but it
was known to cause some problems (unwanted entering into ddb, etc).
In this version any unrelated code was removed and functionality was
extensively tested on DEBUG / DIAGNOSTIC kernels; testing for X11 vs
wscons layout switchers correlation was done on Xorg 6.9.

>Audit-Trail:
From: "Mike M. Volokhov" <mishka@NetBSD.org>
To: gnats-bugs@NetBSD.org
Cc: netbsd-bugs@NetBSD.org
Subject: Re: kern/36762: Locking alternative layouts for wskbd
Date: Fri, 10 Aug 2007 12:11:40 +0300

 Grrr, copy-pasting... Original patch is:

 Index: wskbd.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/wscons/wskbd.c,v
 retrieving revision 1.105
 diff -u -r1.105 wskbd.c
 --- wskbd.c	6 Aug 2007 03:07:52 -0000	1.105
 +++ wskbd.c	10 Aug 2007 07:41:17 -0000
 @@ -1406,16 +1406,22 @@
  }

  static inline void
 -update_modifier(struct wskbd_internal *id, u_int type, int toggle, int mask)
 +update_modifier(struct wskbd_internal *id, u_int type, int togglemode, int mask)
  {
 -	if (toggle) {
 -		if (type == WSCONS_EVENT_KEY_DOWN)
 -			id->t_modifiers ^= mask;
 -	} else {
 +	switch (togglemode) {
 +	case 0:	/* down - on, up - off */
  		if (type == WSCONS_EVENT_KEY_DOWN)
  			id->t_modifiers |= mask;
  		else
  			id->t_modifiers &= ~mask;
 +		break;
 +	case 1: /* down - invert */
 +		if (type == WSCONS_EVENT_KEY_DOWN)
 +			id->t_modifiers ^= mask;
 +		break;
 +	case 2: /* either down or up - invert */
 +		id->t_modifiers ^= mask;
 +		break;
  	}
  }

 @@ -1503,6 +1509,17 @@
  	case KS_Cmd2:
  		update_modifier(sc->id, *type, 0, MOD_COMMAND2);
  		break;
 +
 +	case KS_Cmd_ModeToggle:
 +		if (*type == WSCONS_EVENT_KEY_DOWN) {
 +		    if (MOD_ONESET(sc->id, MOD_COMMAND1 | MOD_COMMAND2)) {
 +			update_modifier(sc->id, *type, 1, MOD_MODESHIFT);
 +			return (1);
 +		    } else {
 +			return (0);
 +		    }
 +		}
 +		break;
  	}

  	if (*type != WSCONS_EVENT_KEY_DOWN ||
 @@ -1648,7 +1665,11 @@
  		break;

  	case KS_Mode_switch:
 -		update_modifier(id, type, 0, MOD_MODESHIFT);
 +		update_modifier(id, type, 2, MOD_MODESHIFT);
 +		break;
 +
 +	case KS_Mode_toggle:
 +		update_modifier(id, type, 1, MOD_MODESHIFT);
  		break;

  	case KS_Num_Lock:
 Index: wsksymdef.h
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/wscons/wsksymdef.h,v
 retrieving revision 1.58
 diff -u -r1.58 wsksymdef.h
 --- wsksymdef.h	4 Apr 2007 14:50:21 -0000	1.58
 +++ wsksymdef.h	10 Aug 2007 07:41:17 -0000
 @@ -377,6 +377,7 @@
  #define KS_Henkan_Mode		0xf114	/* Start/Stop Conversion */
  #define KS_Henkan		0xf115	/* Alias for Henkan_Mode */
  #define KS_Muhenkan		0xf116	/* Cancel Conversion */
 +#define KS_Mode_toggle		0xf117

  /*
   * Group 2 (keypad) character in low byte
 @@ -524,6 +525,7 @@
  #define KS_Cmd_ScrollFastDown	0xf42d
  #define KS_Cmd_ScrollSlowUp	0xf42e
  #define KS_Cmd_ScrollSlowDown	0xf42f
 +#define KS_Cmd_ModeToggle	0xf430

  /*
   * Group 5 (internal)

From: "Mike M. Volokhov" <mishka@NetBSD.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/36762: Locking alternative layouts for wskbd
Date: Fri, 16 May 2008 10:05:10 +0000

 Hello,

 I successfully using the patch since its posting to this PR, and it
 works for me very well on 4.0 and current. 

 Any chances to get it committed before 5.0?

 --
 Mishka.

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.