17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5d8c870b0Sqz150045 * Common Development and Distribution License (the "License").
6d8c870b0Sqz150045 * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21*8600af92Sfei feng - Sun Microsystems - Beijing China
227c478bd9Sstevel@tonic-gate /*
23*8600af92Sfei feng - Sun Microsystems - Beijing China * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate /*
278ffc942dSrz201010 * Usage: kbd [-r] [-t] [-l] [-c on|off] [-a enable|disable|alternate]
288ffc942dSrz201010 * [-d keyboard device] [-D autorepeat dealy] [-R autorepeat
298ffc942dSrz201010 * rate]
308ffc942dSrz201010 * kbd [-i] [-d keyboard device]
318ffc942dSrz201010 * kbd -s [language]
328ffc942dSrz201010 * kbd -b [keyboard|console] frequency
337c478bd9Sstevel@tonic-gate * -r reset the keyboard as if power-up
347c478bd9Sstevel@tonic-gate * -t return the type of the keyboard being used
357c478bd9Sstevel@tonic-gate * -l return the layout of the keyboard being used,
367c478bd9Sstevel@tonic-gate * and the Autorepeat settings
377c478bd9Sstevel@tonic-gate * -i read in the default configuration file
387c478bd9Sstevel@tonic-gate * -c on|off turn on|off clicking
397c478bd9Sstevel@tonic-gate * -a enable|disable|alternate sets abort sequence
407c478bd9Sstevel@tonic-gate * -D autorepeat delay sets autorepeat dealy, unit in ms
417c478bd9Sstevel@tonic-gate * -R autorepeat rate sets autorepeat rate, unit in ms
427c478bd9Sstevel@tonic-gate * -d keyboard device chooses the kbd device, default /dev/kbd.
437db6e34eSqz150045 * -s keyboard layout sets keyboard layout
448ffc942dSrz201010 * -b [keyboard| console] frequency
458ffc942dSrz201010 * sets keyboard or console beeper frequency
467c478bd9Sstevel@tonic-gate */
477c478bd9Sstevel@tonic-gate
487c478bd9Sstevel@tonic-gate #include <sys/types.h>
497c478bd9Sstevel@tonic-gate #include <sys/ioctl.h>
507c478bd9Sstevel@tonic-gate #include <sys/kbio.h>
517c478bd9Sstevel@tonic-gate #include <sys/kbd.h>
527c478bd9Sstevel@tonic-gate #include <stdio.h>
537c478bd9Sstevel@tonic-gate #include <fcntl.h>
547c478bd9Sstevel@tonic-gate #include <deflt.h>
557c478bd9Sstevel@tonic-gate #include <unistd.h>
567c478bd9Sstevel@tonic-gate #include <string.h>
577c478bd9Sstevel@tonic-gate #include <stdlib.h>
587c478bd9Sstevel@tonic-gate #include <stropts.h>
59d8c870b0Sqz150045 #include <libintl.h>
60d8c870b0Sqz150045 #include <locale.h>
618ffc942dSrz201010 #include <errno.h>
628ffc942dSrz201010 #include <inttypes.h>
63*8600af92Sfei feng - Sun Microsystems - Beijing China #include <libscf.h>
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate #define KBD_DEVICE "/dev/kbd" /* default keyboard device */
667db6e34eSqz150045
677db6e34eSqz150045 #define KBD_LAYOUT_FILE "/usr/share/lib/keytables/type_6/kbd_layouts"
687db6e34eSqz150045 #define MAX_LAYOUT_NUM 128
697db6e34eSqz150045 #define MAX_LINE_SIZE 256
707db6e34eSqz150045 #define DEFAULT_KBD_LAYOUT 33
717db6e34eSqz150045
72*8600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_FMRI "svc:/system/keymap:default"
73*8600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PG "keymap"
74*8600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_LAYOUT "layout"
75*8600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_KEYCLICK "keyclick"
76*8600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_KEYBOARD_ABORT "keyboard_abort"
77*8600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_RPTDELAY "repeat_delay"
78*8600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_RPTRATE "repeat_rate"
79*8600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_FREQ "kbd_beeper_freq"
80*8600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_CONSFREQ "console_beeper_freq"
81*8600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_MAX_NAME_LEN 1024
82*8600af92Sfei feng - Sun Microsystems - Beijing China
837db6e34eSqz150045 char *layout_names[MAX_LAYOUT_NUM];
847db6e34eSqz150045 int layout_numbers[MAX_LAYOUT_NUM];
857db6e34eSqz150045 static int layout_count;
867db6e34eSqz150045 static int default_layout_number = 0;
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate static void reset(int);
893c333a60Svn210641 static int get_type(int);
907c478bd9Sstevel@tonic-gate static void get_layout(int);
917c478bd9Sstevel@tonic-gate static void kbd_defaults(int);
927c478bd9Sstevel@tonic-gate static void usage(void);
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate static int click(char *, int);
957c478bd9Sstevel@tonic-gate static int abort_enable(char *, int);
967c478bd9Sstevel@tonic-gate static int set_repeat_delay(char *, int);
97*8600af92Sfei feng - Sun Microsystems - Beijing China static int set_rptdelay(int, int);
987c478bd9Sstevel@tonic-gate static int set_repeat_rate(char *, int);
99*8600af92Sfei feng - Sun Microsystems - Beijing China static int set_rptrate(int, int);
1007c478bd9Sstevel@tonic-gate
1017db6e34eSqz150045 static int get_layout_number(char *);
1027db6e34eSqz150045 static int set_layout(int, int);
1037db6e34eSqz150045 static int get_layouts(void);
1047db6e34eSqz150045 static int set_kbd_layout(int, char *);
1058ffc942dSrz201010 static int set_beep_freq(int, char *, int);
1067db6e34eSqz150045
1077c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)1087c478bd9Sstevel@tonic-gate main(int argc, char **argv)
1097c478bd9Sstevel@tonic-gate {
1107c478bd9Sstevel@tonic-gate int c, error;
1117c478bd9Sstevel@tonic-gate int rflag, tflag, lflag, cflag, dflag, aflag, iflag, errflag,
1128ffc942dSrz201010 Dflag, Rflag, rtlacDRflag, sflag, bflag;
1138ffc942dSrz201010 char *copt, *aopt, *delay, *rate, *layout_name, *b_type, *freq_str;
1148ffc942dSrz201010 char *kbdname = KBD_DEVICE, *endptr = NULL;
1158ffc942dSrz201010 int kbd, freq_val;
1167c478bd9Sstevel@tonic-gate extern char *optarg;
1177c478bd9Sstevel@tonic-gate extern int optind;
1187c478bd9Sstevel@tonic-gate
1197c478bd9Sstevel@tonic-gate rflag = tflag = cflag = dflag = aflag = iflag = errflag = lflag =
1208ffc942dSrz201010 Dflag = Rflag = sflag = bflag = 0;
1217c478bd9Sstevel@tonic-gate copt = aopt = (char *)0;
1227c478bd9Sstevel@tonic-gate
123d8c870b0Sqz150045 (void) setlocale(LC_ALL, "");
124d8c870b0Sqz150045 #if !defined(TEXT_DOMAIN)
125d8c870b0Sqz150045 #define TEXT_DOMAIN "SYS_TEST"
126d8c870b0Sqz150045 #endif
127d8c870b0Sqz150045 (void) textdomain(TEXT_DOMAIN);
128d8c870b0Sqz150045
1298ffc942dSrz201010 while ((c = getopt(argc, argv, "rtlisc:a:d:D:R:b:")) != EOF) {
1307c478bd9Sstevel@tonic-gate switch (c) {
1317c478bd9Sstevel@tonic-gate case 'r':
1327c478bd9Sstevel@tonic-gate rflag++;
1337c478bd9Sstevel@tonic-gate break;
1347c478bd9Sstevel@tonic-gate case 't':
1357c478bd9Sstevel@tonic-gate tflag++;
1367c478bd9Sstevel@tonic-gate break;
1377c478bd9Sstevel@tonic-gate case 'l':
1387c478bd9Sstevel@tonic-gate lflag++;
1397c478bd9Sstevel@tonic-gate break;
1407c478bd9Sstevel@tonic-gate case 'i':
1417c478bd9Sstevel@tonic-gate iflag++;
1427c478bd9Sstevel@tonic-gate break;
1437db6e34eSqz150045 case 's':
1447db6e34eSqz150045 sflag++;
1457db6e34eSqz150045 break;
1467c478bd9Sstevel@tonic-gate case 'c':
1477c478bd9Sstevel@tonic-gate copt = optarg;
1487c478bd9Sstevel@tonic-gate cflag++;
1497c478bd9Sstevel@tonic-gate break;
1507c478bd9Sstevel@tonic-gate case 'a':
1517c478bd9Sstevel@tonic-gate aopt = optarg;
1527c478bd9Sstevel@tonic-gate aflag++;
1537c478bd9Sstevel@tonic-gate break;
1547c478bd9Sstevel@tonic-gate case 'd':
1557c478bd9Sstevel@tonic-gate kbdname = optarg;
1567c478bd9Sstevel@tonic-gate dflag++;
1577c478bd9Sstevel@tonic-gate break;
1587c478bd9Sstevel@tonic-gate case 'D':
1597c478bd9Sstevel@tonic-gate delay = optarg;
1607c478bd9Sstevel@tonic-gate Dflag++;
1617c478bd9Sstevel@tonic-gate break;
1627c478bd9Sstevel@tonic-gate case 'R':
1637c478bd9Sstevel@tonic-gate rate = optarg;
1647c478bd9Sstevel@tonic-gate Rflag++;
1657c478bd9Sstevel@tonic-gate break;
1668ffc942dSrz201010 case 'b':
1678ffc942dSrz201010 bflag++;
1688ffc942dSrz201010 break;
1697c478bd9Sstevel@tonic-gate case '?':
1707c478bd9Sstevel@tonic-gate errflag++;
1717c478bd9Sstevel@tonic-gate break;
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate
1757c478bd9Sstevel@tonic-gate /*
1767c478bd9Sstevel@tonic-gate * Check for valid arguments:
1777c478bd9Sstevel@tonic-gate *
1787c478bd9Sstevel@tonic-gate * If argument parsing failed or if there are left-over
1798ffc942dSrz201010 * command line arguments(except -s and -b option),
1808ffc942dSrz201010 * then we're done now.
1817c478bd9Sstevel@tonic-gate */
1828ffc942dSrz201010 if (errflag != 0 || (sflag == 0 && bflag == 0 && argc != optind)) {
1837c478bd9Sstevel@tonic-gate usage();
1847c478bd9Sstevel@tonic-gate exit(1);
1857c478bd9Sstevel@tonic-gate }
1867db6e34eSqz150045
1877c478bd9Sstevel@tonic-gate /*
1888ffc942dSrz201010 * kbd requires that the user specify either "-i" or "-s" or "-b" or
1898ffc942dSrz201010 * at least one of -[rtlacDR]. The "-d" option is, well, optional.
1907db6e34eSqz150045 * We don't care if it's there or not.
1917c478bd9Sstevel@tonic-gate */
1927c478bd9Sstevel@tonic-gate rtlacDRflag = rflag + tflag + lflag + aflag + cflag + Dflag + Rflag;
1938ffc942dSrz201010 if (!((iflag != 0 && sflag == 0 && bflag == 0 && rtlacDRflag == 0) ||
1948ffc942dSrz201010 (iflag == 0 && sflag != 0 && bflag == 0 && dflag == 0 &&
1958ffc942dSrz201010 rtlacDRflag == 0) ||
1968ffc942dSrz201010 (iflag == 0 && sflag == 0 && bflag == 0 && rtlacDRflag != 0) ||
1978ffc942dSrz201010 (iflag == 0 && sflag == 0 && bflag != 0 && rtlacDRflag == 0))) {
1987c478bd9Sstevel@tonic-gate usage();
1997c478bd9Sstevel@tonic-gate exit(1);
2007c478bd9Sstevel@tonic-gate }
2017c478bd9Sstevel@tonic-gate
2027c478bd9Sstevel@tonic-gate if (Dflag && atoi(delay) <= 0) {
2037c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid arguments: -D %s\n", delay);
2047c478bd9Sstevel@tonic-gate usage();
2057c478bd9Sstevel@tonic-gate exit(1);
2067c478bd9Sstevel@tonic-gate }
2077c478bd9Sstevel@tonic-gate
2087c478bd9Sstevel@tonic-gate if (Rflag && atoi(rate) <= 0) {
2097c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid arguments: -R %s\n", rate);
2107c478bd9Sstevel@tonic-gate usage();
2117c478bd9Sstevel@tonic-gate exit(1);
2127c478bd9Sstevel@tonic-gate }
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate /*
2157c478bd9Sstevel@tonic-gate * Open the keyboard device
2167c478bd9Sstevel@tonic-gate */
2177c478bd9Sstevel@tonic-gate if ((kbd = open(kbdname, O_RDWR)) < 0) {
2187c478bd9Sstevel@tonic-gate perror("opening the keyboard");
2197c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "kbd: Cannot open %s\n", kbdname);
2207c478bd9Sstevel@tonic-gate exit(1);
2217c478bd9Sstevel@tonic-gate }
2227c478bd9Sstevel@tonic-gate
2237c478bd9Sstevel@tonic-gate if (iflag) {
2247c478bd9Sstevel@tonic-gate kbd_defaults(kbd);
2257c478bd9Sstevel@tonic-gate exit(0); /* A mutually exclusive option */
2267c478bd9Sstevel@tonic-gate /*NOTREACHED*/
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate
2297c478bd9Sstevel@tonic-gate if (tflag)
2303c333a60Svn210641 (void) get_type(kbd);
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate if (lflag)
2337c478bd9Sstevel@tonic-gate get_layout(kbd);
2347c478bd9Sstevel@tonic-gate
2357c478bd9Sstevel@tonic-gate if (cflag && (error = click(copt, kbd)) != 0)
2367c478bd9Sstevel@tonic-gate exit(error);
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate if (rflag)
2397c478bd9Sstevel@tonic-gate reset(kbd);
2407c478bd9Sstevel@tonic-gate
2417c478bd9Sstevel@tonic-gate if (aflag && (error = abort_enable(aopt, kbd)) != 0)
2427c478bd9Sstevel@tonic-gate exit(error);
2437c478bd9Sstevel@tonic-gate
2447c478bd9Sstevel@tonic-gate if (Dflag && (error = set_repeat_delay(delay, kbd)) != 0)
2457c478bd9Sstevel@tonic-gate exit(error);
2467c478bd9Sstevel@tonic-gate
2477c478bd9Sstevel@tonic-gate if (Rflag && (error = set_repeat_rate(rate, kbd)) != 0)
2487c478bd9Sstevel@tonic-gate exit(error);
2497c478bd9Sstevel@tonic-gate
2507db6e34eSqz150045 if (sflag) {
2517db6e34eSqz150045 if (argc == optind) {
2527db6e34eSqz150045 layout_name = NULL;
2537db6e34eSqz150045 } else if (argc == (optind + 1)) {
2547db6e34eSqz150045 layout_name = argv[optind];
2557db6e34eSqz150045 } else {
2567db6e34eSqz150045 usage();
2577db6e34eSqz150045 exit(1);
2587db6e34eSqz150045 }
2597db6e34eSqz150045
2607db6e34eSqz150045 if ((error = set_kbd_layout(kbd, layout_name)) != 0)
2617db6e34eSqz150045 exit(error);
2627db6e34eSqz150045 }
2637db6e34eSqz150045
2648ffc942dSrz201010 if (bflag) {
2658ffc942dSrz201010 if (argc == optind) {
2668ffc942dSrz201010 b_type = "keyboard";
2678ffc942dSrz201010 } else if (argc == (optind + 1)) {
2688ffc942dSrz201010 b_type = argv[argc - 2];
2698ffc942dSrz201010 } else {
2708ffc942dSrz201010 usage();
2718ffc942dSrz201010 exit(1);
2728ffc942dSrz201010 }
2738ffc942dSrz201010
2748ffc942dSrz201010 if (strcmp(b_type, "keyboard") && strcmp(b_type, "console")) {
2758ffc942dSrz201010 usage();
2768ffc942dSrz201010 exit(1);
2778ffc942dSrz201010 }
2788ffc942dSrz201010
2798ffc942dSrz201010 freq_str = argv[argc - 1];
2808ffc942dSrz201010 errno = 0;
2818ffc942dSrz201010 freq_val = (int)strtol(freq_str, &endptr, 10);
2828ffc942dSrz201010 if (errno != 0 || endptr[0] != '\0') {
2838ffc942dSrz201010 usage();
2848ffc942dSrz201010 exit(1);
2858ffc942dSrz201010 }
2868ffc942dSrz201010
2878ffc942dSrz201010 if (freq_val < 0 || freq_val > INT16_MAX) {
2888ffc942dSrz201010 (void) fprintf(stderr, "Invalid arguments: -b %s\n",
2898ffc942dSrz201010 freq_str);
2908ffc942dSrz201010 (void) fprintf(stderr, "Frequency range: [0 - %d]\n",
2918ffc942dSrz201010 INT16_MAX);
2928ffc942dSrz201010 exit(1);
2938ffc942dSrz201010 }
2948ffc942dSrz201010
2958ffc942dSrz201010 if ((error = set_beep_freq(kbd, b_type, freq_val)) != 0)
2968ffc942dSrz201010 exit(1);
2978ffc942dSrz201010 }
2988ffc942dSrz201010
2997db6e34eSqz150045 return (0);
3007db6e34eSqz150045 }
3017db6e34eSqz150045
3027db6e34eSqz150045 /*
3037db6e34eSqz150045 * this routine gets the type of the keyboard being used
3047db6e34eSqz150045 */
3057db6e34eSqz150045 static int
set_kbd_layout(int kbd,char * layout_name)3067db6e34eSqz150045 set_kbd_layout(int kbd, char *layout_name)
3077db6e34eSqz150045 {
3087db6e34eSqz150045 int layout_num;
3097db6e34eSqz150045 int error = 1;
3107db6e34eSqz150045
3113c333a60Svn210641 /* layout setting is possible only for USB type keyboards */
3123c333a60Svn210641 if (get_type(kbd) != KB_USB) {
3133c333a60Svn210641 (void) fprintf(stderr, "The -s option does not apply for this"
3143c333a60Svn210641 " keyboard type.\n"
3153c333a60Svn210641 "Only USB/PS2 type keyboards support this option.\n");
3163c333a60Svn210641 return (error);
3173c333a60Svn210641 }
3183c333a60Svn210641
3197db6e34eSqz150045 /* get the language info from the layouts file */
3207db6e34eSqz150045 if (get_layouts() != 0)
3217db6e34eSqz150045 return (error);
3227db6e34eSqz150045
3237db6e34eSqz150045 if (layout_name != NULL) {
3247db6e34eSqz150045 if ((layout_num = get_layout_number(layout_name)) == -1) {
3257db6e34eSqz150045 (void) fprintf(stderr, "%s: unknown layout name\n"
3267db6e34eSqz150045 "Please refer to 'kbd -s' to get the "
3277db6e34eSqz150045 "supported layouts.\n", layout_name);
3287db6e34eSqz150045 return (error);
3297db6e34eSqz150045 }
3307db6e34eSqz150045 } else {
3317db6e34eSqz150045 int i, j, print_cnt, input_num;
3327db6e34eSqz150045 boolean_t input_right = B_TRUE;
3337db6e34eSqz150045 boolean_t default_input = B_FALSE;
3347db6e34eSqz150045 char input[8]; /* 8 chars is enough for numbers */
3357db6e34eSqz150045
3367db6e34eSqz150045 print_cnt = (layout_count % 2) ?
3377db6e34eSqz150045 layout_count/2+1 : layout_count/2;
3387db6e34eSqz150045
3397db6e34eSqz150045 for (i = 1; i <= print_cnt; i++) {
3407db6e34eSqz150045 (void) printf("%2d. %-30s", i,
3417db6e34eSqz150045 layout_names[i-1]);
3427db6e34eSqz150045 j = i + print_cnt;
3437db6e34eSqz150045 if (j <= layout_count) {
3447db6e34eSqz150045 (void) printf("%-2d. %-30s\n", j,
3457db6e34eSqz150045 layout_names[j-1]);
3467db6e34eSqz150045 }
3477db6e34eSqz150045 }
348d8c870b0Sqz150045 (void) printf(gettext("\nTo select the keyboard layout,"
349d8c870b0Sqz150045 " enter a number [default %d]:"),
3507db6e34eSqz150045 default_layout_number+1);
3517db6e34eSqz150045
3527db6e34eSqz150045 for (;;) {
3537db6e34eSqz150045 if (input_right == B_FALSE)
354d8c870b0Sqz150045 (void) printf(gettext("Invalid input. "
355d8c870b0Sqz150045 "Please input a number "
356d8c870b0Sqz150045 "(1,2,...):"));
3577db6e34eSqz150045 (void) memset(input, 0, 8);
3587db6e34eSqz150045 (void) fflush(stdin);
3597db6e34eSqz150045 (void) fgets(input, 8, stdin);
3607db6e34eSqz150045 if (strlen(input) > 4) {
3617db6e34eSqz150045 input_right = B_FALSE;
3627db6e34eSqz150045 continue;
3637db6e34eSqz150045 }
3647db6e34eSqz150045 if (input[0] == '\n') {
3657db6e34eSqz150045 default_input = B_TRUE;
3667db6e34eSqz150045 break;
3677db6e34eSqz150045 }
3687db6e34eSqz150045 input_right = B_TRUE;
3697db6e34eSqz150045 /* check if the inputs are numbers 0~9 */
3707db6e34eSqz150045 for (i = 0; i < (strlen(input) - 1); i++) {
3717db6e34eSqz150045 if ((input[i] < '0') ||
3727db6e34eSqz150045 (input[i] > '9')) {
3737db6e34eSqz150045 input_right = B_FALSE;
3747db6e34eSqz150045 break;
3757db6e34eSqz150045 }
3767db6e34eSqz150045 }
3777db6e34eSqz150045 if (input_right == B_FALSE)
3787db6e34eSqz150045 continue;
3797db6e34eSqz150045 input_num = atoi(input);
3807db6e34eSqz150045 if ((input_num > 0) &&
3817db6e34eSqz150045 (input_num <= layout_count))
3827db6e34eSqz150045 break;
3837db6e34eSqz150045 else
3847db6e34eSqz150045 input_right = B_FALSE;
3857db6e34eSqz150045 }
3867db6e34eSqz150045 if (default_input == B_TRUE)
3877db6e34eSqz150045 layout_num = DEFAULT_KBD_LAYOUT;
3887db6e34eSqz150045 else
3897db6e34eSqz150045 layout_num = layout_numbers[--input_num];
3907db6e34eSqz150045 }
3917db6e34eSqz150045
3927db6e34eSqz150045 if ((error = set_layout(kbd, layout_num)) != 0)
3937db6e34eSqz150045 return (error);
3947db6e34eSqz150045
3957c478bd9Sstevel@tonic-gate return (0);
3967c478bd9Sstevel@tonic-gate }
3977c478bd9Sstevel@tonic-gate
3987c478bd9Sstevel@tonic-gate /*
3998ffc942dSrz201010 * This routine sets keyboard or console beeper frequency
4008ffc942dSrz201010 */
4018ffc942dSrz201010 static int
set_beep_freq(int fd,char * type,int freq)4028ffc942dSrz201010 set_beep_freq(int fd, char *type, int freq)
4038ffc942dSrz201010 {
4048ffc942dSrz201010 struct freq_request fr_struct;
4058ffc942dSrz201010
4068ffc942dSrz201010 if (strcmp(type, "keyboard") == 0)
4078ffc942dSrz201010 fr_struct.type = KBD_BEEP;
4088ffc942dSrz201010 else if (strcmp(type, "console") == 0)
4098ffc942dSrz201010 fr_struct.type = CONSOLE_BEEP;
4108ffc942dSrz201010 else
4118ffc942dSrz201010 return (EINVAL);
4128ffc942dSrz201010
4138ffc942dSrz201010 fr_struct.freq = (int16_t)freq;
4148ffc942dSrz201010
4158ffc942dSrz201010 return (ioctl(fd, KIOCSETFREQ, &fr_struct));
4168ffc942dSrz201010 }
4178ffc942dSrz201010
4188ffc942dSrz201010 /*
4197c478bd9Sstevel@tonic-gate * this routine resets the state of the keyboard as if power-up
4207c478bd9Sstevel@tonic-gate */
4217c478bd9Sstevel@tonic-gate static void
reset(int kbd)4227c478bd9Sstevel@tonic-gate reset(int kbd)
4237c478bd9Sstevel@tonic-gate {
4247c478bd9Sstevel@tonic-gate int cmd;
4257c478bd9Sstevel@tonic-gate
4267c478bd9Sstevel@tonic-gate cmd = KBD_CMD_RESET;
4277c478bd9Sstevel@tonic-gate
4287c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCCMD, &cmd)) {
4297c478bd9Sstevel@tonic-gate perror("kbd: ioctl error");
4307c478bd9Sstevel@tonic-gate exit(1);
4317c478bd9Sstevel@tonic-gate }
4327c478bd9Sstevel@tonic-gate
4337c478bd9Sstevel@tonic-gate }
4347c478bd9Sstevel@tonic-gate
4357c478bd9Sstevel@tonic-gate /*
4367c478bd9Sstevel@tonic-gate * this routine gets the type of the keyboard being used
4377c478bd9Sstevel@tonic-gate */
4383c333a60Svn210641 static int
get_type(int kbd)4397c478bd9Sstevel@tonic-gate get_type(int kbd)
4407c478bd9Sstevel@tonic-gate {
4417c478bd9Sstevel@tonic-gate int kbd_type;
4427c478bd9Sstevel@tonic-gate
4437c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCTYPE, &kbd_type)) {
4447c478bd9Sstevel@tonic-gate perror("ioctl (kbd type)");
4457c478bd9Sstevel@tonic-gate exit(1);
4467c478bd9Sstevel@tonic-gate }
4477c478bd9Sstevel@tonic-gate
4487c478bd9Sstevel@tonic-gate switch (kbd_type) {
4497c478bd9Sstevel@tonic-gate
4507c478bd9Sstevel@tonic-gate case KB_SUN3:
4517c478bd9Sstevel@tonic-gate (void) printf("Type 3 Sun keyboard\n");
4527c478bd9Sstevel@tonic-gate break;
4537c478bd9Sstevel@tonic-gate
4547c478bd9Sstevel@tonic-gate case KB_SUN4:
4557c478bd9Sstevel@tonic-gate (void) printf("Type 4 Sun keyboard\n");
4567c478bd9Sstevel@tonic-gate break;
4577c478bd9Sstevel@tonic-gate
4587c478bd9Sstevel@tonic-gate case KB_ASCII:
4597c478bd9Sstevel@tonic-gate (void) printf("ASCII\n");
4607c478bd9Sstevel@tonic-gate break;
4617c478bd9Sstevel@tonic-gate
4627c478bd9Sstevel@tonic-gate case KB_PC:
4637c478bd9Sstevel@tonic-gate (void) printf("PC\n");
4647c478bd9Sstevel@tonic-gate break;
4657c478bd9Sstevel@tonic-gate
4667c478bd9Sstevel@tonic-gate case KB_USB:
4677c478bd9Sstevel@tonic-gate (void) printf("USB keyboard\n");
4687c478bd9Sstevel@tonic-gate break;
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate default:
4717c478bd9Sstevel@tonic-gate (void) printf("Unknown keyboard type\n");
4727c478bd9Sstevel@tonic-gate break;
4737c478bd9Sstevel@tonic-gate }
4743c333a60Svn210641 return (kbd_type);
4757c478bd9Sstevel@tonic-gate }
4767c478bd9Sstevel@tonic-gate
4777c478bd9Sstevel@tonic-gate /*
4787c478bd9Sstevel@tonic-gate * this routine gets the layout of the keyboard being used
4797c478bd9Sstevel@tonic-gate * also, included the autorepeat delay and rate being used
4807c478bd9Sstevel@tonic-gate */
4817c478bd9Sstevel@tonic-gate static void
get_layout(int kbd)4827c478bd9Sstevel@tonic-gate get_layout(int kbd)
4837c478bd9Sstevel@tonic-gate {
4847c478bd9Sstevel@tonic-gate int kbd_type;
4857c478bd9Sstevel@tonic-gate int kbd_layout;
4867c478bd9Sstevel@tonic-gate /* these two variables are used for getting delay&rate */
4877c478bd9Sstevel@tonic-gate int delay, rate;
4887c478bd9Sstevel@tonic-gate delay = rate = 0;
4897c478bd9Sstevel@tonic-gate
4907c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCTYPE, &kbd_type)) {
4917c478bd9Sstevel@tonic-gate perror("ioctl (kbd type)");
4927c478bd9Sstevel@tonic-gate exit(1);
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate
4957c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCLAYOUT, &kbd_layout)) {
4967c478bd9Sstevel@tonic-gate perror("ioctl (kbd layout)");
4977c478bd9Sstevel@tonic-gate exit(1);
4987c478bd9Sstevel@tonic-gate }
4997c478bd9Sstevel@tonic-gate
5007c478bd9Sstevel@tonic-gate (void) printf("type=%d\nlayout=%d (0x%.2x)\n",
5017c478bd9Sstevel@tonic-gate kbd_type, kbd_layout, kbd_layout);
5027c478bd9Sstevel@tonic-gate
5037c478bd9Sstevel@tonic-gate /* below code is used to get the autorepeat delay and rate */
5047c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCGRPTDELAY, &delay)) {
5057c478bd9Sstevel@tonic-gate perror("ioctl (kbd get repeat delay)");
5067c478bd9Sstevel@tonic-gate exit(1);
5077c478bd9Sstevel@tonic-gate }
5087c478bd9Sstevel@tonic-gate
5097c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCGRPTRATE, &rate)) {
5107c478bd9Sstevel@tonic-gate perror("ioctl (kbd get repeat rate)");
5117c478bd9Sstevel@tonic-gate exit(1);
5127c478bd9Sstevel@tonic-gate }
5137c478bd9Sstevel@tonic-gate
5147c478bd9Sstevel@tonic-gate (void) printf("delay(ms)=%d\n", delay);
5157c478bd9Sstevel@tonic-gate (void) printf("rate(ms)=%d\n", rate);
5167c478bd9Sstevel@tonic-gate }
5177c478bd9Sstevel@tonic-gate
5187c478bd9Sstevel@tonic-gate /*
5197c478bd9Sstevel@tonic-gate * this routine enables or disables clicking of the keyboard
5207c478bd9Sstevel@tonic-gate */
5217c478bd9Sstevel@tonic-gate static int
click(char * copt,int kbd)5227c478bd9Sstevel@tonic-gate click(char *copt, int kbd)
5237c478bd9Sstevel@tonic-gate {
5247c478bd9Sstevel@tonic-gate int cmd;
5257c478bd9Sstevel@tonic-gate
5267c478bd9Sstevel@tonic-gate if (strcmp(copt, "on") == 0)
5277c478bd9Sstevel@tonic-gate cmd = KBD_CMD_CLICK;
5287c478bd9Sstevel@tonic-gate else if (strcmp(copt, "off") == 0)
5297c478bd9Sstevel@tonic-gate cmd = KBD_CMD_NOCLICK;
5307c478bd9Sstevel@tonic-gate else {
5317c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "wrong option -- %s\n", copt);
5327c478bd9Sstevel@tonic-gate usage();
5337c478bd9Sstevel@tonic-gate return (1);
5347c478bd9Sstevel@tonic-gate }
5357c478bd9Sstevel@tonic-gate
5367c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCCMD, &cmd)) {
5377c478bd9Sstevel@tonic-gate perror("kbd ioctl (keyclick)");
5387c478bd9Sstevel@tonic-gate return (1);
5397c478bd9Sstevel@tonic-gate }
5407c478bd9Sstevel@tonic-gate return (0);
5417c478bd9Sstevel@tonic-gate }
5427c478bd9Sstevel@tonic-gate
5437c478bd9Sstevel@tonic-gate /*
5447c478bd9Sstevel@tonic-gate * this routine enables/disables/sets BRK or abort sequence feature
5457c478bd9Sstevel@tonic-gate */
5467c478bd9Sstevel@tonic-gate static int
abort_enable(char * aopt,int kbd)5477c478bd9Sstevel@tonic-gate abort_enable(char *aopt, int kbd)
5487c478bd9Sstevel@tonic-gate {
5497c478bd9Sstevel@tonic-gate int enable;
5507c478bd9Sstevel@tonic-gate
5517c478bd9Sstevel@tonic-gate if (strcmp(aopt, "alternate") == 0)
5527c478bd9Sstevel@tonic-gate enable = KIOCABORTALTERNATE;
5537c478bd9Sstevel@tonic-gate else if (strcmp(aopt, "enable") == 0)
5547c478bd9Sstevel@tonic-gate enable = KIOCABORTENABLE;
5557c478bd9Sstevel@tonic-gate else if (strcmp(aopt, "disable") == 0)
5567c478bd9Sstevel@tonic-gate enable = KIOCABORTDISABLE;
5577c478bd9Sstevel@tonic-gate else {
5587c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "wrong option -- %s\n", aopt);
5597c478bd9Sstevel@tonic-gate usage();
5607c478bd9Sstevel@tonic-gate return (1);
5617c478bd9Sstevel@tonic-gate }
5627c478bd9Sstevel@tonic-gate
5637c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSKABORTEN, &enable)) {
5647c478bd9Sstevel@tonic-gate perror("kbd ioctl (abort enable)");
5657c478bd9Sstevel@tonic-gate return (1);
5667c478bd9Sstevel@tonic-gate }
5677c478bd9Sstevel@tonic-gate return (0);
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate
5707c478bd9Sstevel@tonic-gate static int
set_rptdelay(int delay,int kbd)571*8600af92Sfei feng - Sun Microsystems - Beijing China set_rptdelay(int delay, int kbd)
5727c478bd9Sstevel@tonic-gate {
5737c478bd9Sstevel@tonic-gate /*
5747c478bd9Sstevel@tonic-gate * The error message depends on the different inputs.
5757c478bd9Sstevel@tonic-gate * a. the input is a invalid integer(unit in ms)
5767c478bd9Sstevel@tonic-gate * b. the input is a integer less than the minimal delay setting.
5774470e687Syx209491 * The condition (a) has been covered by main function and kbd_defaults
5787c478bd9Sstevel@tonic-gate * function.
5797c478bd9Sstevel@tonic-gate */
5807c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSRPTDELAY, &delay) == -1) {
5817c478bd9Sstevel@tonic-gate if (delay < KIOCRPTDELAY_MIN)
5827c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "kbd: specified delay %d is "
5837c478bd9Sstevel@tonic-gate "less than minimum %d\n", delay, KIOCRPTDELAY_MIN);
5847c478bd9Sstevel@tonic-gate else
5857c478bd9Sstevel@tonic-gate perror("kbd: set repeat delay");
5867c478bd9Sstevel@tonic-gate return (1);
5877c478bd9Sstevel@tonic-gate }
5887c478bd9Sstevel@tonic-gate
5897c478bd9Sstevel@tonic-gate return (0);
5907c478bd9Sstevel@tonic-gate }
5917c478bd9Sstevel@tonic-gate
5927c478bd9Sstevel@tonic-gate /*
593*8600af92Sfei feng - Sun Microsystems - Beijing China * this routine set autorepeat delay
5947c478bd9Sstevel@tonic-gate */
5957c478bd9Sstevel@tonic-gate static int
set_repeat_delay(char * delay_str,int kbd)596*8600af92Sfei feng - Sun Microsystems - Beijing China set_repeat_delay(char *delay_str, int kbd)
5977c478bd9Sstevel@tonic-gate {
598*8600af92Sfei feng - Sun Microsystems - Beijing China int delay = atoi(delay_str);
5997c478bd9Sstevel@tonic-gate
600*8600af92Sfei feng - Sun Microsystems - Beijing China return (set_rptdelay(delay, kbd));
601*8600af92Sfei feng - Sun Microsystems - Beijing China }
602*8600af92Sfei feng - Sun Microsystems - Beijing China
603*8600af92Sfei feng - Sun Microsystems - Beijing China static int
set_rptrate(int rate,int kbd)604*8600af92Sfei feng - Sun Microsystems - Beijing China set_rptrate(int rate, int kbd)
605*8600af92Sfei feng - Sun Microsystems - Beijing China {
6067c478bd9Sstevel@tonic-gate /*
6074470e687Syx209491 * The input validation check has been covered by main function
6084470e687Syx209491 * and kbd_defaults function.Here just give an error message if
6094470e687Syx209491 * the ioctl fails.
6107c478bd9Sstevel@tonic-gate */
6117c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSRPTRATE, &rate) == -1) {
6127c478bd9Sstevel@tonic-gate perror("kbd: set repeat rate");
6137c478bd9Sstevel@tonic-gate return (1);
6147c478bd9Sstevel@tonic-gate }
6157c478bd9Sstevel@tonic-gate return (0);
6167c478bd9Sstevel@tonic-gate }
6177c478bd9Sstevel@tonic-gate
618*8600af92Sfei feng - Sun Microsystems - Beijing China /*
619*8600af92Sfei feng - Sun Microsystems - Beijing China * this routine set autorepeat rate
620*8600af92Sfei feng - Sun Microsystems - Beijing China */
621*8600af92Sfei feng - Sun Microsystems - Beijing China static int
set_repeat_rate(char * rate_str,int kbd)622*8600af92Sfei feng - Sun Microsystems - Beijing China set_repeat_rate(char *rate_str, int kbd)
623*8600af92Sfei feng - Sun Microsystems - Beijing China {
624*8600af92Sfei feng - Sun Microsystems - Beijing China int rate = atoi(rate_str);
625*8600af92Sfei feng - Sun Microsystems - Beijing China
626*8600af92Sfei feng - Sun Microsystems - Beijing China return (set_rptrate(rate, kbd));
627*8600af92Sfei feng - Sun Microsystems - Beijing China }
628*8600af92Sfei feng - Sun Microsystems - Beijing China
629*8600af92Sfei feng - Sun Microsystems - Beijing China #define BAD_DEFAULT_STR "kbd: bad default value for %s: %s\n"
630*8600af92Sfei feng - Sun Microsystems - Beijing China #define BAD_DEFAULT_INT "kbd: bad default value for %s: %d\n"
631*8600af92Sfei feng - Sun Microsystems - Beijing China #define BAD_DEFAULT_LLINT "kbd: bad default value for %s: %lld\n"
6327c478bd9Sstevel@tonic-gate
6337c478bd9Sstevel@tonic-gate static void
kbd_defaults(int kbd)6347c478bd9Sstevel@tonic-gate kbd_defaults(int kbd)
6357c478bd9Sstevel@tonic-gate {
636*8600af92Sfei feng - Sun Microsystems - Beijing China scf_handle_t *h = NULL;
637*8600af92Sfei feng - Sun Microsystems - Beijing China scf_snapshot_t *snap = NULL;
638*8600af92Sfei feng - Sun Microsystems - Beijing China scf_instance_t *inst = NULL;
639*8600af92Sfei feng - Sun Microsystems - Beijing China scf_propertygroup_t *pg = NULL;
640*8600af92Sfei feng - Sun Microsystems - Beijing China scf_property_t *prop = NULL;
641*8600af92Sfei feng - Sun Microsystems - Beijing China scf_value_t *val = NULL;
6427c478bd9Sstevel@tonic-gate
643*8600af92Sfei feng - Sun Microsystems - Beijing China int layout_num;
644*8600af92Sfei feng - Sun Microsystems - Beijing China char *val_layout = NULL, *val_abort = NULL;
645*8600af92Sfei feng - Sun Microsystems - Beijing China uint8_t val_click;
646*8600af92Sfei feng - Sun Microsystems - Beijing China int64_t val_delay, val_rate;
647*8600af92Sfei feng - Sun Microsystems - Beijing China int64_t val_kbd_beeper, val_console_beeper;
648*8600af92Sfei feng - Sun Microsystems - Beijing China
649*8600af92Sfei feng - Sun Microsystems - Beijing China if ((h = scf_handle_create(SCF_VERSION)) == NULL ||
650*8600af92Sfei feng - Sun Microsystems - Beijing China scf_handle_bind(h) != 0 ||
651*8600af92Sfei feng - Sun Microsystems - Beijing China (inst = scf_instance_create(h)) == NULL ||
652*8600af92Sfei feng - Sun Microsystems - Beijing China (snap = scf_snapshot_create(h)) == NULL ||
653*8600af92Sfei feng - Sun Microsystems - Beijing China (pg = scf_pg_create(h)) == NULL ||
654*8600af92Sfei feng - Sun Microsystems - Beijing China (prop = scf_property_create(h)) == NULL ||
655*8600af92Sfei feng - Sun Microsystems - Beijing China (val = scf_value_create(h)) == NULL) {
656*8600af92Sfei feng - Sun Microsystems - Beijing China goto out;
6577c478bd9Sstevel@tonic-gate }
6587c478bd9Sstevel@tonic-gate
659*8600af92Sfei feng - Sun Microsystems - Beijing China if (scf_handle_decode_fmri(h, KBD_FMRI, NULL, NULL, inst,
660*8600af92Sfei feng - Sun Microsystems - Beijing China NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) {
661*8600af92Sfei feng - Sun Microsystems - Beijing China goto out;
662*8600af92Sfei feng - Sun Microsystems - Beijing China }
663*8600af92Sfei feng - Sun Microsystems - Beijing China
664*8600af92Sfei feng - Sun Microsystems - Beijing China if (scf_instance_get_snapshot(inst, "running", snap) != 0) {
665*8600af92Sfei feng - Sun Microsystems - Beijing China scf_snapshot_destroy(snap);
666*8600af92Sfei feng - Sun Microsystems - Beijing China snap = NULL;
667*8600af92Sfei feng - Sun Microsystems - Beijing China }
668*8600af92Sfei feng - Sun Microsystems - Beijing China
669*8600af92Sfei feng - Sun Microsystems - Beijing China if (scf_instance_get_pg_composed(inst, snap, KBD_PG, pg) != 0) {
670*8600af92Sfei feng - Sun Microsystems - Beijing China goto out;
671*8600af92Sfei feng - Sun Microsystems - Beijing China }
672*8600af92Sfei feng - Sun Microsystems - Beijing China
673*8600af92Sfei feng - Sun Microsystems - Beijing China if ((val_abort = malloc(KBD_MAX_NAME_LEN)) == NULL) {
674*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
675*8600af92Sfei feng - Sun Microsystems - Beijing China "Can not alloc memory for keyboard properties\n");
676*8600af92Sfei feng - Sun Microsystems - Beijing China goto out;
677*8600af92Sfei feng - Sun Microsystems - Beijing China }
678*8600af92Sfei feng - Sun Microsystems - Beijing China
679*8600af92Sfei feng - Sun Microsystems - Beijing China if ((val_layout = malloc(KBD_MAX_NAME_LEN)) == NULL) {
680*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
681*8600af92Sfei feng - Sun Microsystems - Beijing China "Can not alloc memory for keyboard properties\n");
682*8600af92Sfei feng - Sun Microsystems - Beijing China goto out;
683*8600af92Sfei feng - Sun Microsystems - Beijing China }
684*8600af92Sfei feng - Sun Microsystems - Beijing China
685*8600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_KEYCLICK, prop) != 0 ||
686*8600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
687*8600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_boolean(val, &val_click) == -1) {
688*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get KEYCLICK\n");
689*8600af92Sfei feng - Sun Microsystems - Beijing China }
690*8600af92Sfei feng - Sun Microsystems - Beijing China
691*8600af92Sfei feng - Sun Microsystems - Beijing China if (val_click == 1)
692*8600af92Sfei feng - Sun Microsystems - Beijing China (void) click("on", kbd);
693*8600af92Sfei feng - Sun Microsystems - Beijing China else if (val_click == 0)
694*8600af92Sfei feng - Sun Microsystems - Beijing China (void) click("off", kbd);
6957c478bd9Sstevel@tonic-gate else
696*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
697*8600af92Sfei feng - Sun Microsystems - Beijing China BAD_DEFAULT_INT, KBD_PROP_KEYCLICK, val_click);
698*8600af92Sfei feng - Sun Microsystems - Beijing China
699*8600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_KEYBOARD_ABORT, prop) != 0 ||
700*8600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
701*8600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_astring(val, val_abort, KBD_MAX_NAME_LEN) == -1) {
702*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get KEYBOARD_ABORT\n");
7037c478bd9Sstevel@tonic-gate }
7047c478bd9Sstevel@tonic-gate
705*8600af92Sfei feng - Sun Microsystems - Beijing China if (*val_abort != '\0') {
7067c478bd9Sstevel@tonic-gate /*
7077c478bd9Sstevel@tonic-gate * ABORT must equal "enable", "disable" or "alternate"
7087c478bd9Sstevel@tonic-gate */
709*8600af92Sfei feng - Sun Microsystems - Beijing China if ((strcmp(val_abort, "enable") == 0) ||
710*8600af92Sfei feng - Sun Microsystems - Beijing China (strcmp(val_abort, "alternate") == 0) ||
711*8600af92Sfei feng - Sun Microsystems - Beijing China (strcmp(val_abort, "disable") == 0))
712*8600af92Sfei feng - Sun Microsystems - Beijing China (void) abort_enable(val_abort, kbd);
7137c478bd9Sstevel@tonic-gate else
714*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, BAD_DEFAULT_STR,
715*8600af92Sfei feng - Sun Microsystems - Beijing China KBD_PROP_KEYBOARD_ABORT, val_abort);
7167c478bd9Sstevel@tonic-gate }
7177c478bd9Sstevel@tonic-gate
718*8600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_RPTDELAY, prop) != 0 ||
719*8600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
720*8600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_integer(val, &val_delay) == -1) {
721*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get RPTDELAY\n");
7227c478bd9Sstevel@tonic-gate }
7237c478bd9Sstevel@tonic-gate
724*8600af92Sfei feng - Sun Microsystems - Beijing China if (val_delay > 0)
725*8600af92Sfei feng - Sun Microsystems - Beijing China (void) set_rptdelay(val_delay, kbd);
7267c478bd9Sstevel@tonic-gate else
727*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
728*8600af92Sfei feng - Sun Microsystems - Beijing China BAD_DEFAULT_LLINT, KBD_PROP_RPTDELAY, val_delay);
729*8600af92Sfei feng - Sun Microsystems - Beijing China
730*8600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_RPTRATE, prop) != 0 ||
731*8600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
732*8600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_integer(val, &val_rate) == -1) {
733*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get RPTRATE\n");
7347c478bd9Sstevel@tonic-gate }
7357db6e34eSqz150045
736*8600af92Sfei feng - Sun Microsystems - Beijing China if (val_rate > 0)
737*8600af92Sfei feng - Sun Microsystems - Beijing China (void) set_rptrate(val_rate, kbd);
738*8600af92Sfei feng - Sun Microsystems - Beijing China else
739*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
740*8600af92Sfei feng - Sun Microsystems - Beijing China BAD_DEFAULT_LLINT, KBD_PROP_RPTRATE, val_rate);
741*8600af92Sfei feng - Sun Microsystems - Beijing China
742*8600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_LAYOUT, prop) != 0 ||
743*8600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
744*8600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_astring(val, val_layout, KBD_MAX_NAME_LEN) == -1) {
745*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get LAYOUT\n");
746*8600af92Sfei feng - Sun Microsystems - Beijing China }
747*8600af92Sfei feng - Sun Microsystems - Beijing China
748*8600af92Sfei feng - Sun Microsystems - Beijing China if (*val_layout != '\0') {
7497db6e34eSqz150045 /*
7507db6e34eSqz150045 * LAYOUT must be one of the layouts supported in kbd_layouts
7517db6e34eSqz150045 */
7527db6e34eSqz150045 if (get_layouts() != 0)
753*8600af92Sfei feng - Sun Microsystems - Beijing China goto out;
7547db6e34eSqz150045
755*8600af92Sfei feng - Sun Microsystems - Beijing China if ((layout_num = get_layout_number(val_layout)) == -1) {
756*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
757*8600af92Sfei feng - Sun Microsystems - Beijing China BAD_DEFAULT_STR, KBD_PROP_LAYOUT, val_layout);
758*8600af92Sfei feng - Sun Microsystems - Beijing China goto out;
7597db6e34eSqz150045 }
7607db6e34eSqz150045
7617db6e34eSqz150045 (void) set_layout(kbd, layout_num);
7627db6e34eSqz150045 }
7638ffc942dSrz201010
764*8600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_FREQ, prop) != 0 ||
765*8600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
766*8600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_integer(val, &val_kbd_beeper) == -1) {
767*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get FREQ\n");
7688ffc942dSrz201010 }
7698ffc942dSrz201010
770*8600af92Sfei feng - Sun Microsystems - Beijing China if (val_kbd_beeper >= 0 && val_kbd_beeper <= INT16_MAX)
771*8600af92Sfei feng - Sun Microsystems - Beijing China (void) set_beep_freq(kbd, "keyboard", val_kbd_beeper);
7728ffc942dSrz201010 else
773*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
774*8600af92Sfei feng - Sun Microsystems - Beijing China BAD_DEFAULT_LLINT, KBD_PROP_FREQ, val_kbd_beeper);
775*8600af92Sfei feng - Sun Microsystems - Beijing China
776*8600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_CONSFREQ, prop) != 0 ||
777*8600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
778*8600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_integer(val, &val_console_beeper) == -1) {
779*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get CONSFREQ\n");
7808ffc942dSrz201010 }
781*8600af92Sfei feng - Sun Microsystems - Beijing China
782*8600af92Sfei feng - Sun Microsystems - Beijing China if (val_console_beeper >= 0 && val_console_beeper <= INT16_MAX)
783*8600af92Sfei feng - Sun Microsystems - Beijing China (void) set_beep_freq(kbd, "console", val_console_beeper);
784*8600af92Sfei feng - Sun Microsystems - Beijing China else
785*8600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
786*8600af92Sfei feng - Sun Microsystems - Beijing China BAD_DEFAULT_LLINT, KBD_PROP_CONSFREQ, val_console_beeper);
787*8600af92Sfei feng - Sun Microsystems - Beijing China
788*8600af92Sfei feng - Sun Microsystems - Beijing China out:
789*8600af92Sfei feng - Sun Microsystems - Beijing China if (val_layout != NULL)
790*8600af92Sfei feng - Sun Microsystems - Beijing China free(val_layout);
791*8600af92Sfei feng - Sun Microsystems - Beijing China if (val_abort != NULL)
792*8600af92Sfei feng - Sun Microsystems - Beijing China free(val_abort);
793*8600af92Sfei feng - Sun Microsystems - Beijing China if (snap != NULL)
794*8600af92Sfei feng - Sun Microsystems - Beijing China scf_snapshot_destroy(snap);
795*8600af92Sfei feng - Sun Microsystems - Beijing China scf_value_destroy(val);
796*8600af92Sfei feng - Sun Microsystems - Beijing China scf_property_destroy(prop);
797*8600af92Sfei feng - Sun Microsystems - Beijing China scf_pg_destroy(pg);
798*8600af92Sfei feng - Sun Microsystems - Beijing China scf_instance_destroy(inst);
799*8600af92Sfei feng - Sun Microsystems - Beijing China scf_handle_destroy(h);
8007db6e34eSqz150045 }
8017db6e34eSqz150045
8027db6e34eSqz150045 static int
get_layout_number(char * layout)8037db6e34eSqz150045 get_layout_number(char *layout)
8047db6e34eSqz150045 {
8057db6e34eSqz150045 int i;
8067db6e34eSqz150045 int layout_number = -1;
8077db6e34eSqz150045
8087db6e34eSqz150045 for (i = 0; i < layout_count; i ++) {
8097db6e34eSqz150045 if (strcmp(layout, layout_names[i]) == 0) {
8107db6e34eSqz150045 layout_number = layout_numbers[i];
8117db6e34eSqz150045 break;
8127db6e34eSqz150045 }
8137db6e34eSqz150045 }
8147db6e34eSqz150045
8157db6e34eSqz150045 return (layout_number);
8167db6e34eSqz150045 }
8177db6e34eSqz150045
8187db6e34eSqz150045 static int
get_layouts()8197db6e34eSqz150045 get_layouts()
8207db6e34eSqz150045 {
8217db6e34eSqz150045 FILE *stream;
8227db6e34eSqz150045 char buffer[MAX_LINE_SIZE];
8237db6e34eSqz150045 char *result = NULL;
8247db6e34eSqz150045 int i = 0;
8257db6e34eSqz150045 char *tmpbuf;
8267db6e34eSqz150045
8277db6e34eSqz150045 if ((stream = fopen(KBD_LAYOUT_FILE, "r")) == 0) {
8287db6e34eSqz150045 perror(KBD_LAYOUT_FILE);
8297db6e34eSqz150045 return (1);
8307db6e34eSqz150045 }
8317db6e34eSqz150045
8327db6e34eSqz150045 while ((fgets(buffer, MAX_LINE_SIZE, stream) != NULL) &&
8337db6e34eSqz150045 (i < MAX_LAYOUT_NUM)) {
8347db6e34eSqz150045 if (buffer[0] == '#')
8357db6e34eSqz150045 continue;
8367db6e34eSqz150045 if ((result = strtok(buffer, "=")) == NULL)
8377db6e34eSqz150045 continue;
8387db6e34eSqz150045 if ((tmpbuf = strdup(result)) != NULL) {
8397db6e34eSqz150045 layout_names[i] = tmpbuf;
8407db6e34eSqz150045 } else {
8417db6e34eSqz150045 perror("out of memory getting layout names");
8427db6e34eSqz150045 return (1);
8437db6e34eSqz150045 }
8447db6e34eSqz150045 if ((result = strtok(NULL, "\n")) == NULL)
8457db6e34eSqz150045 continue;
8467db6e34eSqz150045 layout_numbers[i] = atoi(result);
8477db6e34eSqz150045 if (strcmp(tmpbuf, "US-English") == 0)
8487db6e34eSqz150045 default_layout_number = i;
8497db6e34eSqz150045 i++;
8507db6e34eSqz150045 }
8517db6e34eSqz150045 layout_count = i;
8527db6e34eSqz150045
8537db6e34eSqz150045 return (0);
8547db6e34eSqz150045 }
8557db6e34eSqz150045
8567db6e34eSqz150045 /*
8577db6e34eSqz150045 * this routine sets the layout of the keyboard being used
8587db6e34eSqz150045 */
8597db6e34eSqz150045 static int
set_layout(int kbd,int layout_num)8607db6e34eSqz150045 set_layout(int kbd, int layout_num)
8617db6e34eSqz150045 {
8627db6e34eSqz150045
8637db6e34eSqz150045 if (ioctl(kbd, KIOCSLAYOUT, layout_num)) {
8647db6e34eSqz150045 perror("ioctl (set kbd layout)");
8657db6e34eSqz150045 return (1);
8667db6e34eSqz150045 }
8677db6e34eSqz150045
8687db6e34eSqz150045 return (0);
8697c478bd9Sstevel@tonic-gate }
8707c478bd9Sstevel@tonic-gate
8717c478bd9Sstevel@tonic-gate static char *usage1 = "kbd [-r] [-t] [-l] [-a enable|disable|alternate]";
8727c478bd9Sstevel@tonic-gate static char *usage2 = " [-c on|off][-D delay][-R rate][-d keyboard device]";
8737c478bd9Sstevel@tonic-gate static char *usage3 = "kbd -i [-d keyboard device]";
8747db6e34eSqz150045 static char *usage4 = "kbd -s [language]";
8758ffc942dSrz201010 static char *usage5 = "kbd -b [keyboard|console] frequency";
8767c478bd9Sstevel@tonic-gate
8777c478bd9Sstevel@tonic-gate static void
usage(void)8787c478bd9Sstevel@tonic-gate usage(void)
8797c478bd9Sstevel@tonic-gate {
8808ffc942dSrz201010 (void) fprintf(stderr, "Usage:\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n", usage1,
8818ffc942dSrz201010 usage2, usage3, usage4, usage5);
8827c478bd9Sstevel@tonic-gate }
883