From owner-freebsd-bugs Tue Jul 30 11: 0:32 2002 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C6D0437B400 for ; Tue, 30 Jul 2002 11:00:10 -0700 (PDT) Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1BB7E43E4A for ; Tue, 30 Jul 2002 11:00:10 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.4/8.12.4) with ESMTP id g6UI09JU026808 for ; Tue, 30 Jul 2002 11:00:09 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.4/8.12.4/Submit) id g6UI09WP026807; Tue, 30 Jul 2002 11:00:09 -0700 (PDT) Date: Tue, 30 Jul 2002 11:00:09 -0700 (PDT) Message-Id: <200207301800.g6UI09WP026807@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Yorick Hardy Subject: Re: misc/33965: Programmable keys of the keyboard (Olidata KB-9805) Reply-To: Yorick Hardy Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org The following reply was made to PR misc/33965; it has been noted by GNATS. From: Yorick Hardy 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 + #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