Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Jul 2002 11:00:09 -0700 (PDT)
From:      Yorick Hardy <yh@metroweb.co.za>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: misc/33965: Programmable keys of the keyboard (Olidata KB-9805)
Message-ID:  <200207301800.g6UI09WP026807@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR misc/33965; it has been noted by GNATS.

From: Yorick Hardy <yh@metroweb.co.za>
To: freebsd-gnats-submit@FreeBSD.org, nivit@libero.it
Cc:  
Subject: Re: misc/33965: Programmable keys of the keyboard (Olidata KB-9805)
Date: Sun, 28 Jul 2002 13:58:45 GMT

 I hope this patch is useful, it incorporates the original suggested patch
 in a form which is more flexible and adds an ioctl to wait for a function
 key press so that a program may act on special button presses (eg. volume,
 play cd etc.). It also supports the Logitech iTouch, Compaq easy internet
 access and a Microsoft keyboard mentioned on the hackers mailing list.
 kbdcontrol was also modified to enable the additional functionality.
 
 I also have a simplistic daemon and shell script to support volume
 and cd control when using an appropriate keymap, but that can come
 later if the patch is worthwhile in its current form.
 
 FreeBSD Yorick 4.5-STABLE FreeBSD 4.5-STABLE #1: Sat Jun  8 13:01:09 GMT 2002
      root@Yorick:/usr/obj/usr/src/sys/YORICK  i386
 
 *** sys/sys/kbio.h.orig	Sun Jun 30 15:17:33 2002
 --- sys/sys/kbio.h	Sat Jul 27 15:59:14 2002
 ***************
 *** 220,225 ****
 --- 220,235 ----
   #define PIO_DEADKEYMAP 	_IOW('k', 9, accentmap_t)
   #define GIO_KEYMAPENT 	_IOWR('k', 10, keyarg_t)
   #define PIO_KEYMAPENT 	_IOW('k', 11, keyarg_t)
 + /* obtain next function key (function number) pressed -- blocking */
 + #define WAITFORFKEY	_IOR('k', 12, int)
 + /* set extra keyboard functionality */
 + #define SETBUTTONTYPE   _IOW('k', 13, int)
 + 
 + /* extra keyboard functionality (buttons) identification */
 + #define ATKBD_NO_EXTRA_BUTTONS			0
 + #define ATKBD_LOGITECH_ITOUCH			1
 + #define ATKBD_COMPAQ_EASY_ACCESS_INTERNET	2
 + #define ATKBD_MICROSOFT				3
 + #define ATKBD_OLIDATA_KB9805			4
   
   /* flags set to the return value in the KD_XLATE mode */
   
 *** sys/dev/kbd/atkbd.c.orig	Tue Jul  2 10:54:10 2002
 --- sys/dev/kbd/atkbd.c	Sat Jul 27 16:12:02 2002
 ***************
 *** 185,190 ****
 --- 185,191 ----
   	int		ks_accents;	/* accent key index (> 0) */
   	u_int		ks_composed_char; /* composed char code (> 0) */
   	u_char		ks_prefix;	/* AT scan code prefix */
 + 	u_char		ks_buttons;	/* specify extra button support */
   } atkbd_state_t;
   
   /* keyboard driver declaration */
 ***************
 *** 252,257 ****
 --- 253,305 ----
   #endif
   #include <dev/kbd/kbdtables.h>
   
 + #define ATKBD_MAX_BUTTONS 15 /* the maximum number of extra buttons */
 + typedef struct atkbd_button_map {
 + 	int size;
 + 	unsigned char buttons[ATKBD_MAX_BUTTONS][2]; /* scancode -> keycode */
 + } atkbd_button_map_t;
 + 
 + /*
 +  *  The mapping to keycode is as follows
 +  *   sleep, suspend		->	0x6c
 +  *   mute			->	0x6d
 +  *   vol-			->	0x6e
 +  *   vol+			->	0x6f
 +  *   play, play/pause		->	0x70
 +  *   stop			->	0x71
 +  *   previous			->	0x72
 +  *   next			->	0x73
 +  *   e-mail			->	0x74
 +  *   search			->	0x75
 +  *   run, launch application	->	0x76
 +  *   home			->	0x77
 +  *   internet			->	0x78
 +  *   e-commerce			->	0x79
 +  *   favourites			->	0x7a
 +  *   computer			->	0x7b
 +  *   calculator			->	0x7c
 +  *   prompt			->	0x7d
 +  *   close			->	0x7e
 +  *   document			->	0x7f
 +  *   screen saver		->	0x80
 +  *   menu			->	0x6b
 +  */
 + 
 + #define ATKBD_MAX_BUTTON_TYPE 4  /* the number of button extensions defined */
 + static atkbd_button_map_t atkbd_buttons[ATKBD_MAX_BUTTON_TYPE] = {
 + 	{0},						/* no buttons */
 + 	/* Logitech iTouch */
 + 	{12, {{0x5f,0x6c},{0x20,0x6d},{0x2e,0x6e},
 + 	      {0x30,0x6f},{0x22,0x70},{0x24,0x71},
 + 	      {0x10,0x72},{0x19,0x73},{0x6c,0x74},
 + 	      {0x65,0x75},{0x66,0x76},{0x32,0x77}}},
 + 	/* Compaq easy internet access */
 + 	{13, {{0x5f,0x6c},{0x20,0x6d},{0x2e,0x6e},
 + 	      {0x30,0x6f},{0x22,0x70},{0x24,0x71},
 + 	      {0x10,0x72},{0x19,0x73},{0x1e,0x74},
 + 	      {0x21,0x75},{0x1f,0x76},{0x23,0x78},{0x32,0x79}}},
 + 	/* Microsoft */
 + 	{10, {{0x5f,0x6c},{0x68,0x71},{0x6a,0x72},
 + 	      {0x69,0x73},{0x6c,0x74},{0x65,0x75},
 + 	      {0x32,0x77},{0x66,0x7a},{0x6b,0x7b},
 + 	      {0x21,0x7c}}},
 + 	/* Olidata KB-9805 */
 + 	{14, {{0x25,0x6c},{0x17,0x6d},{0x1e,0x6e},
 + 	      {0x26,0x6f},{0x22,0x70},{0x24,0x71},
 + 	      {0x2e,0x72},{0x19,0x73},{0x20,0x78},
 + 	      {0x23,0x7d},{0x21,0x7e},{0x32,0x7f},
 + 	      {0x12,0x6b},{0x30,0x80}}}
 + };
 + 
   /* structures for the default keyboard */
   static keyboard_t	default_kbd;
   static atkbd_state_t	default_kbd_state;
 ***************
 *** 413,418 ****
 --- 461,467 ----
   		}
   		atkbd_clear_state(kbd);
   		state->ks_mode = K_XLATE;
 + 		state->ks_buttons = ATKBD_NO_EXTRA_BUTTONS;
   		/* 
   		 * FIXME: set the initial value for lock keys in ks_state
   		 * according to the BIOS data?
 ***************
 *** 564,569 ****
 --- 613,619 ----
   	u_int action;
   	int scancode;
   	int keycode;
 + 	int i;
   
   	state = (atkbd_state_t *)kbd->kb_data;
   next_code:
 ***************
 *** 681,687 ****
   		case 0x5d:	/* menu key */
   	    		keycode = 0x6b;
   	    		break;
 ! 		default:	/* ignore everything else */
   	    		goto next_code;
   		}
   		break;
 --- 731,744 ----
   		case 0x5d:	/* menu key */
   	    		keycode = 0x6b;
   	    		break;
 ! 		default:	/* check for extra buttons */
 ! 			for (i = 0; i < atkbd_buttons[state->ks_buttons].size; i++) {
 ! 				keycode = atkbd_buttons[state->ks_buttons].buttons[i][1];
 ! 				if (atkbd_buttons[state->ks_buttons].buttons[i][0] == scancode)
 ! 					break;
 ! 			}
 ! 			if (i < atkbd_buttons[state->ks_buttons].size)
 ! 				break;
   	    		goto next_code;
   		}
   		break;
 ***************
 *** 914,919 ****
 --- 971,985 ----
   			kbd->kb_delay2 = typematic_rate(*(int *)arg);
   		}
   		return error;
 + 
 + 	case SETBUTTONTYPE:	/* set extra functionality (buttons) */
 + 		if(*(int *)arg >= 0 && *(int *)arg <= ATKBD_MAX_BUTTON_TYPE)
 + 			state->ks_buttons = *(int *)arg;
 + 		else {
 + 			splx(s);
 + 			return EINVAL;
 + 		}
 + 		break;
   
   	case PIO_KEYMAP:	/* set keyboard translation table */
   	case PIO_KEYMAPENT:	/* set keyboard translation table entry */
 *** sys/dev/kbd/kbd.c.orig	Sun Jun 30 17:48:35 2002
 --- sys/dev/kbd/kbd.c	Fri Jul  5 15:55:43 2002
 ***************
 *** 140,145 ****
 --- 140,146 ----
   	kbd->kb_delay2 = KB_DELAY2;
   	kbd->kb_count = 0L;
   	bzero(kbd->kb_lastact, sizeof(kbd->kb_lastact));
 + 	kbd->kb_lfkey = -1; /* no function key pressed */
   }
   
   void
 ***************
 *** 874,880 ****
   		splx(s);
   		return ENODEV;
   #endif
 ! 
   	default:
   		splx(s);
   		return ENOIOCTL;
 --- 875,893 ----
   		splx(s);
   		return ENODEV;
   #endif
 ! 	case WAITFORFKEY:	/* obtain next function key pressed */
 ! 		i = tsleep((caddr_t)&(kbd->kb_lfkey),
 ! 			   PZERO | PCATCH, "kbdlfk", 0);
 ! 		if (i == EINTR) {
 ! 			splx(s);
 ! 			return EINTR;
 ! 		}
 ! 		if (!KBD_IS_VALID(kbd)) {
 ! 			splx(s);
 ! 			return ENXIO;	/* our keyboard has gone... */
 ! 		}
 ! 		*(int*)arg = kbd->kb_lfkey;
 ! 		break;
   	default:
   		splx(s);
   		return ENOIOCTL;
 ***************
 *** 1231,1237 ****
 --- 1244,1254 ----
   					return ERRKEY;
   				}
   				if (action >= F_FN && action <= L_FN)
 + 				{
 + 					kbd->kb_lfkey = action-F_FN+1;
   					action |= FKEY;
 + 					wakeup(&(kbd->kb_lfkey));
 + 				}
   				/* XXX: return fkey string for the FKEY? */
   				return (SPCLKEY | action);
   			}
 *** sys/dev/kbd/kbdreg.h.orig	Tue Jul  2 10:52:59 2002
 --- sys/dev/kbd/kbdreg.h	Sat Jul 27 12:51:32 2002
 ***************
 *** 83,88 ****
 --- 83,89 ----
   	struct accentmap *kb_accentmap;	/* accent map */
   	struct fkeytab	*kb_fkeytab;	/* function key strings */
   	int		kb_fkeytab_size;/* # of function key strings */
 + 	int		kb_lfkey;	/* the last function key pressed */
   	void		*kb_data;	/* the driver's private data */
   	int		kb_delay1;
   	int		kb_delay2;
 *** sys/dev/syscons/syscons.c.orig	Wed Jul  3 13:04:14 2002
 --- sys/dev/syscons/syscons.c	Sat Jul 27 13:22:03 2002
 ***************
 *** 1170,1175 ****
 --- 1170,1177 ----
       case PIO_DEADKEYMAP:	/* set accent key translation table */
       case GETFKEY:		/* get function key string */
       case SETFKEY:		/* set function key string */
 +     case WAITFORFKEY:		/* next function key pressed */
 +     case SETBUTTONTYPE:		/* specify extra functionality (buttons) */
   	error = kbd_ioctl(sc->kbd, cmd, data);
   	if (error == ENOIOCTL)
   	    error = ENODEV;
 *** usr.sbin/kbdcontrol/kbdcontrol.c.orig	Sat Jul 27 14:12:46 2002
 --- usr.sbin/kbdcontrol/kbdcontrol.c	Sat Jul 27 16:01:04 2002
 ***************
 *** 88,93 ****
 --- 88,102 ----
   /* 93-96 */	""      , ""      , ""      , ""      ,
   	};
   
 + char *atkbd_button_type[] = {
 +  "none",			/* ATKBD_NO_EXTRA_BUTTONS */
 +  "Logitech_iTouch",		/* ATKBD_LOGITECH_ITOUCH */
 +  "Compaq_Easy_Access_Internet",	/* ATKBD_COMPAQ_EASY_ACCESS_INTERNET */
 +  "Microsoft",			/* ATKBD_MICROSOFT */
 +  "Olidata_KB9805",		/* ATKBD_OLIDATA_KB9805 */
 +  NULL
 + };
 + 
 + 
   const int	delays[]  = {250, 500, 750, 1000};
   const int	repeats[] = { 34,  38,  42,  46,  50,  55,  59,  63,
   			      68,  76,  84,  92, 100, 110, 118, 126,
 ***************
 *** 1054,1059 ****
 --- 1063,1081 ----
   		warn("unable to release the keyboard");
   }
   
 + void
 + set_buttons(char *opt)
 + {
 + 	int i;
 + 
 + 	for (i = 0; atkbd_button_type[i] != NULL; i++)
 + 		if (!strcmp(atkbd_button_type[i], opt)) break;
 + 
 + 	/* The ioctl will give an error if i is too large anyway */
 + 	if (ioctl(0, SETBUTTONTYPE, &i) == -1)
 + 		warn("setting extensions (buttons)");
 + }
 + 
   
   void
   usage()
 ***************
 *** 1061,1067 ****
   	fprintf(stderr, "%s\n%s\n%s\n",
   "usage: kbdcontrol [-dFKix] [-b duration.pitch | [quiet.]belltype]",
   "                  [-r delay.repeat | speed] [-l mapfile] [-f # string]",
 ! "                  [-h size] [-k device] [-L mapfile]");
   	exit(1);
   }
   
 --- 1083,1089 ----
   	fprintf(stderr, "%s\n%s\n%s\n",
   "usage: kbdcontrol [-dFKix] [-b duration.pitch | [quiet.]belltype]",
   "                  [-r delay.repeat | speed] [-l mapfile] [-f # string]",
 ! "                  [-h size] [-k device] [-L mapfile] [-e extension]");
   	exit(1);
   }
   
 ***************
 *** 1071,1077 ****
   {
   	int		opt;
   
 ! 	while((opt = getopt(argc, argv, "b:df:h:iKk:Fl:L:r:x")) != -1)
   		switch(opt) {
   			case 'b':
   				set_bell_values(optarg);
 --- 1093,1099 ----
   {
   	int		opt;
   
 ! 	while((opt = getopt(argc, argv, "b:df:h:iKk:Fl:L:r:xe:")) != -1)
   		switch(opt) {
   			case 'b':
   				set_bell_values(optarg);
 ***************
 *** 1109,1114 ****
 --- 1131,1139 ----
   				break;
   			case 'x':
   				hex = 1;
 + 				break;
 + 			case 'e':
 + 				set_buttons(optarg);
   				break;
   			default:
   				usage();
 *** usr.sbin/kbdcontrol/kbdcontrol.1.orig	Sat Jul 27 14:15:06 2002
 --- usr.sbin/kbdcontrol/kbdcontrol.1	Sat Jul 27 14:41:20 2002
 ***************
 *** 145,150 ****
 --- 145,161 ----
   compiled from it to stdout.
   This option is primarily intended for programmers and is probably
   of little use under normal circumstances.
 + .It Fl e Xo
 + .Ar extension_type
 + .Xc
 + Set the keyboard extension (buttons) type. The currently recognised types are
 +   none
 +   Logitech_iTouch
 +   Compaq_Easy_Access_Internet
 +   Microsoft
 +   Olidata_KB9805
 + 
 + Note that an appropriate keymap should be loaded to define the actions of the
 + extra buttons.
   .El
   .Sh KEYBOARD CONFIGURATION
   .Ss Boot Time Configuration

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200207301800.g6UI09WP026807>