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
5d8c870b0Sqz * Common Development and Distribution License (the "License").
6d8c870b0Sqz * 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 */
218600af92Sfei feng - Sun Microsystems - Beijing China
227c478bd9Sstevel@tonic-gate /*
238600af92Sfei 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 /*
278ffc942dSrz * Usage: kbd [-r] [-t] [-l] [-c on|off] [-a enable|disable|alternate]
28*c0423dd8SToomas Soome * [-d keyboard device] [-A autorepeat count]
29*c0423dd8SToomas Soome * [-D autorepeat delay] [-R autorepeat rate]
308ffc942dSrz * kbd [-i] [-d keyboard device]
318ffc942dSrz * kbd -s [language]
328ffc942dSrz * 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
40*c0423dd8SToomas Soome * -A autorepeat count sets autorepeat sequence length in chars.
41*c0423dd8SToomas Soome * -D autorepeat delay sets autorepeat delay, unit in ms
427c478bd9Sstevel@tonic-gate * -R autorepeat rate sets autorepeat rate, unit in ms
437c478bd9Sstevel@tonic-gate * -d keyboard device chooses the kbd device, default /dev/kbd.
447db6e34eSqz * -s keyboard layout sets keyboard layout
458ffc942dSrz * -b [keyboard| console] frequency
468ffc942dSrz * sets keyboard or console beeper frequency
477c478bd9Sstevel@tonic-gate */
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate #include <sys/types.h>
507c478bd9Sstevel@tonic-gate #include <sys/ioctl.h>
517c478bd9Sstevel@tonic-gate #include <sys/kbio.h>
527c478bd9Sstevel@tonic-gate #include <sys/kbd.h>
537c478bd9Sstevel@tonic-gate #include <stdio.h>
547c478bd9Sstevel@tonic-gate #include <fcntl.h>
557c478bd9Sstevel@tonic-gate #include <deflt.h>
567c478bd9Sstevel@tonic-gate #include <unistd.h>
577c478bd9Sstevel@tonic-gate #include <string.h>
587c478bd9Sstevel@tonic-gate #include <stdlib.h>
597c478bd9Sstevel@tonic-gate #include <stropts.h>
60d8c870b0Sqz #include <libintl.h>
61d8c870b0Sqz #include <locale.h>
628ffc942dSrz #include <errno.h>
638ffc942dSrz #include <inttypes.h>
648600af92Sfei feng - Sun Microsystems - Beijing China #include <libscf.h>
65*c0423dd8SToomas Soome #include <limits.h>
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate #define KBD_DEVICE "/dev/kbd" /* default keyboard device */
687db6e34eSqz
697db6e34eSqz #define KBD_LAYOUT_FILE "/usr/share/lib/keytables/type_6/kbd_layouts"
707db6e34eSqz #define MAX_LAYOUT_NUM 128
717db6e34eSqz #define MAX_LINE_SIZE 256
727db6e34eSqz #define DEFAULT_KBD_LAYOUT 33
737db6e34eSqz
748600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_FMRI "svc:/system/keymap:default"
758600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PG "keymap"
768600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_LAYOUT "layout"
778600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_KEYCLICK "keyclick"
788600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_KEYBOARD_ABORT "keyboard_abort"
798600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_RPTDELAY "repeat_delay"
808600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_RPTRATE "repeat_rate"
81*c0423dd8SToomas Soome #define KBD_PROP_RPTCOUNT "repeat_count"
828600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_FREQ "kbd_beeper_freq"
838600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_PROP_CONSFREQ "console_beeper_freq"
848600af92Sfei feng - Sun Microsystems - Beijing China #define KBD_MAX_NAME_LEN 1024
858600af92Sfei feng - Sun Microsystems - Beijing China
867db6e34eSqz char *layout_names[MAX_LAYOUT_NUM];
877db6e34eSqz int layout_numbers[MAX_LAYOUT_NUM];
887db6e34eSqz static int layout_count;
897db6e34eSqz static int default_layout_number = 0;
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate static void reset(int);
923c333a60Svn static int get_type(int);
937c478bd9Sstevel@tonic-gate static void get_layout(int);
947c478bd9Sstevel@tonic-gate static void kbd_defaults(int);
957c478bd9Sstevel@tonic-gate static void usage(void);
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate static int click(char *, int);
987c478bd9Sstevel@tonic-gate static int abort_enable(char *, int);
99*c0423dd8SToomas Soome static int set_repeat_count(char *, int);
100*c0423dd8SToomas Soome static int set_rptcount(int, int);
1017c478bd9Sstevel@tonic-gate static int set_repeat_delay(char *, int);
1028600af92Sfei feng - Sun Microsystems - Beijing China static int set_rptdelay(int, int);
1037c478bd9Sstevel@tonic-gate static int set_repeat_rate(char *, int);
1048600af92Sfei feng - Sun Microsystems - Beijing China static int set_rptrate(int, int);
1057c478bd9Sstevel@tonic-gate
1067db6e34eSqz static int get_layout_number(char *);
1077db6e34eSqz static int set_layout(int, int);
1087db6e34eSqz static int get_layouts(void);
1097db6e34eSqz static int set_kbd_layout(int, char *);
1108ffc942dSrz static int set_beep_freq(int, char *, int);
1117db6e34eSqz
1127c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)1137c478bd9Sstevel@tonic-gate main(int argc, char **argv)
1147c478bd9Sstevel@tonic-gate {
1157c478bd9Sstevel@tonic-gate int c, error;
1167c478bd9Sstevel@tonic-gate int rflag, tflag, lflag, cflag, dflag, aflag, iflag, errflag,
117*c0423dd8SToomas Soome Aflag, Dflag, Rflag, rtlacADRflag, sflag, bflag;
118*c0423dd8SToomas Soome char *copt, *aopt, *count, *delay, *rate, *layout_name, *b_type;
119*c0423dd8SToomas Soome char *freq_str;
1208ffc942dSrz char *kbdname = KBD_DEVICE, *endptr = NULL;
1218ffc942dSrz int kbd, freq_val;
1227c478bd9Sstevel@tonic-gate extern char *optarg;
1237c478bd9Sstevel@tonic-gate extern int optind;
1247c478bd9Sstevel@tonic-gate
1257c478bd9Sstevel@tonic-gate rflag = tflag = cflag = dflag = aflag = iflag = errflag = lflag =
126*c0423dd8SToomas Soome Aflag = Dflag = Rflag = sflag = bflag = 0;
127*c0423dd8SToomas Soome copt = aopt = NULL;
1287c478bd9Sstevel@tonic-gate
129d8c870b0Sqz (void) setlocale(LC_ALL, "");
130d8c870b0Sqz #if !defined(TEXT_DOMAIN)
131d8c870b0Sqz #define TEXT_DOMAIN "SYS_TEST"
132d8c870b0Sqz #endif
133d8c870b0Sqz (void) textdomain(TEXT_DOMAIN);
134d8c870b0Sqz
135*c0423dd8SToomas Soome while ((c = getopt(argc, argv, "rtlisc:a:d:A:D:R:b:")) != EOF) {
1367c478bd9Sstevel@tonic-gate switch (c) {
1377c478bd9Sstevel@tonic-gate case 'r':
1387c478bd9Sstevel@tonic-gate rflag++;
1397c478bd9Sstevel@tonic-gate break;
1407c478bd9Sstevel@tonic-gate case 't':
1417c478bd9Sstevel@tonic-gate tflag++;
1427c478bd9Sstevel@tonic-gate break;
1437c478bd9Sstevel@tonic-gate case 'l':
1447c478bd9Sstevel@tonic-gate lflag++;
1457c478bd9Sstevel@tonic-gate break;
1467c478bd9Sstevel@tonic-gate case 'i':
1477c478bd9Sstevel@tonic-gate iflag++;
1487c478bd9Sstevel@tonic-gate break;
1497db6e34eSqz case 's':
1507db6e34eSqz sflag++;
1517db6e34eSqz break;
1527c478bd9Sstevel@tonic-gate case 'c':
1537c478bd9Sstevel@tonic-gate copt = optarg;
1547c478bd9Sstevel@tonic-gate cflag++;
1557c478bd9Sstevel@tonic-gate break;
1567c478bd9Sstevel@tonic-gate case 'a':
1577c478bd9Sstevel@tonic-gate aopt = optarg;
1587c478bd9Sstevel@tonic-gate aflag++;
1597c478bd9Sstevel@tonic-gate break;
1607c478bd9Sstevel@tonic-gate case 'd':
1617c478bd9Sstevel@tonic-gate kbdname = optarg;
1627c478bd9Sstevel@tonic-gate dflag++;
1637c478bd9Sstevel@tonic-gate break;
164*c0423dd8SToomas Soome case 'A':
165*c0423dd8SToomas Soome count = optarg;
166*c0423dd8SToomas Soome Aflag++;
167*c0423dd8SToomas Soome break;
1687c478bd9Sstevel@tonic-gate case 'D':
1697c478bd9Sstevel@tonic-gate delay = optarg;
1707c478bd9Sstevel@tonic-gate Dflag++;
1717c478bd9Sstevel@tonic-gate break;
1727c478bd9Sstevel@tonic-gate case 'R':
1737c478bd9Sstevel@tonic-gate rate = optarg;
1747c478bd9Sstevel@tonic-gate Rflag++;
1757c478bd9Sstevel@tonic-gate break;
1768ffc942dSrz case 'b':
1778ffc942dSrz bflag++;
1788ffc942dSrz break;
1797c478bd9Sstevel@tonic-gate case '?':
1807c478bd9Sstevel@tonic-gate errflag++;
1817c478bd9Sstevel@tonic-gate break;
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate }
1847c478bd9Sstevel@tonic-gate
1857c478bd9Sstevel@tonic-gate /*
1867c478bd9Sstevel@tonic-gate * Check for valid arguments:
1877c478bd9Sstevel@tonic-gate *
1887c478bd9Sstevel@tonic-gate * If argument parsing failed or if there are left-over
1898ffc942dSrz * command line arguments(except -s and -b option),
1908ffc942dSrz * then we're done now.
1917c478bd9Sstevel@tonic-gate */
1928ffc942dSrz if (errflag != 0 || (sflag == 0 && bflag == 0 && argc != optind)) {
1937c478bd9Sstevel@tonic-gate usage();
1947c478bd9Sstevel@tonic-gate exit(1);
1957c478bd9Sstevel@tonic-gate }
1967db6e34eSqz
1977c478bd9Sstevel@tonic-gate /*
1988ffc942dSrz * kbd requires that the user specify either "-i" or "-s" or "-b" or
199*c0423dd8SToomas Soome * at least one of -[rtlacADR]. The "-d" option is, well, optional.
2007db6e34eSqz * We don't care if it's there or not.
2017c478bd9Sstevel@tonic-gate */
202*c0423dd8SToomas Soome rtlacADRflag = rflag + tflag + lflag + aflag + cflag + Aflag +
203*c0423dd8SToomas Soome Dflag + Rflag;
204*c0423dd8SToomas Soome if (!((iflag != 0 && sflag == 0 && bflag == 0 && rtlacADRflag == 0) ||
2058ffc942dSrz (iflag == 0 && sflag != 0 && bflag == 0 && dflag == 0 &&
206*c0423dd8SToomas Soome rtlacADRflag == 0) ||
207*c0423dd8SToomas Soome (iflag == 0 && sflag == 0 && bflag == 0 && rtlacADRflag != 0) ||
208*c0423dd8SToomas Soome (iflag == 0 && sflag == 0 && bflag != 0 && rtlacADRflag == 0))) {
209*c0423dd8SToomas Soome usage();
210*c0423dd8SToomas Soome exit(1);
211*c0423dd8SToomas Soome }
212*c0423dd8SToomas Soome
213*c0423dd8SToomas Soome if (Aflag && atoi(count) < -1) {
214*c0423dd8SToomas Soome (void) fprintf(stderr, "Invalid arguments: -A %s\n", count);
2157c478bd9Sstevel@tonic-gate usage();
2167c478bd9Sstevel@tonic-gate exit(1);
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate
2197c478bd9Sstevel@tonic-gate if (Dflag && atoi(delay) <= 0) {
2207c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid arguments: -D %s\n", delay);
2217c478bd9Sstevel@tonic-gate usage();
2227c478bd9Sstevel@tonic-gate exit(1);
2237c478bd9Sstevel@tonic-gate }
2247c478bd9Sstevel@tonic-gate
2257c478bd9Sstevel@tonic-gate if (Rflag && atoi(rate) <= 0) {
2267c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid arguments: -R %s\n", rate);
2277c478bd9Sstevel@tonic-gate usage();
2287c478bd9Sstevel@tonic-gate exit(1);
2297c478bd9Sstevel@tonic-gate }
2307c478bd9Sstevel@tonic-gate
2317c478bd9Sstevel@tonic-gate /*
2327c478bd9Sstevel@tonic-gate * Open the keyboard device
2337c478bd9Sstevel@tonic-gate */
2347c478bd9Sstevel@tonic-gate if ((kbd = open(kbdname, O_RDWR)) < 0) {
2357c478bd9Sstevel@tonic-gate perror("opening the keyboard");
2367c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "kbd: Cannot open %s\n", kbdname);
2377c478bd9Sstevel@tonic-gate exit(1);
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate if (iflag) {
2417c478bd9Sstevel@tonic-gate kbd_defaults(kbd);
2427c478bd9Sstevel@tonic-gate exit(0); /* A mutually exclusive option */
2437c478bd9Sstevel@tonic-gate /*NOTREACHED*/
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate if (tflag)
2473c333a60Svn (void) get_type(kbd);
2487c478bd9Sstevel@tonic-gate
2497c478bd9Sstevel@tonic-gate if (lflag)
2507c478bd9Sstevel@tonic-gate get_layout(kbd);
2517c478bd9Sstevel@tonic-gate
2527c478bd9Sstevel@tonic-gate if (cflag && (error = click(copt, kbd)) != 0)
2537c478bd9Sstevel@tonic-gate exit(error);
2547c478bd9Sstevel@tonic-gate
2557c478bd9Sstevel@tonic-gate if (rflag)
2567c478bd9Sstevel@tonic-gate reset(kbd);
2577c478bd9Sstevel@tonic-gate
2587c478bd9Sstevel@tonic-gate if (aflag && (error = abort_enable(aopt, kbd)) != 0)
2597c478bd9Sstevel@tonic-gate exit(error);
2607c478bd9Sstevel@tonic-gate
261*c0423dd8SToomas Soome if (Aflag && (error = set_repeat_count(count, kbd)) != 0)
262*c0423dd8SToomas Soome exit(error);
263*c0423dd8SToomas Soome
2647c478bd9Sstevel@tonic-gate if (Dflag && (error = set_repeat_delay(delay, kbd)) != 0)
2657c478bd9Sstevel@tonic-gate exit(error);
2667c478bd9Sstevel@tonic-gate
2677c478bd9Sstevel@tonic-gate if (Rflag && (error = set_repeat_rate(rate, kbd)) != 0)
2687c478bd9Sstevel@tonic-gate exit(error);
2697c478bd9Sstevel@tonic-gate
2707db6e34eSqz if (sflag) {
2717db6e34eSqz if (argc == optind) {
2727db6e34eSqz layout_name = NULL;
2737db6e34eSqz } else if (argc == (optind + 1)) {
2747db6e34eSqz layout_name = argv[optind];
2757db6e34eSqz } else {
2767db6e34eSqz usage();
2777db6e34eSqz exit(1);
2787db6e34eSqz }
2797db6e34eSqz
2807db6e34eSqz if ((error = set_kbd_layout(kbd, layout_name)) != 0)
2817db6e34eSqz exit(error);
2827db6e34eSqz }
2837db6e34eSqz
2848ffc942dSrz if (bflag) {
2858ffc942dSrz if (argc == optind) {
2868ffc942dSrz b_type = "keyboard";
2878ffc942dSrz } else if (argc == (optind + 1)) {
2888ffc942dSrz b_type = argv[argc - 2];
2898ffc942dSrz } else {
2908ffc942dSrz usage();
2918ffc942dSrz exit(1);
2928ffc942dSrz }
2938ffc942dSrz
2948ffc942dSrz if (strcmp(b_type, "keyboard") && strcmp(b_type, "console")) {
2958ffc942dSrz usage();
2968ffc942dSrz exit(1);
2978ffc942dSrz }
2988ffc942dSrz
2998ffc942dSrz freq_str = argv[argc - 1];
3008ffc942dSrz errno = 0;
3018ffc942dSrz freq_val = (int)strtol(freq_str, &endptr, 10);
3028ffc942dSrz if (errno != 0 || endptr[0] != '\0') {
3038ffc942dSrz usage();
3048ffc942dSrz exit(1);
3058ffc942dSrz }
3068ffc942dSrz
3078ffc942dSrz if (freq_val < 0 || freq_val > INT16_MAX) {
3088ffc942dSrz (void) fprintf(stderr, "Invalid arguments: -b %s\n",
3098ffc942dSrz freq_str);
3108ffc942dSrz (void) fprintf(stderr, "Frequency range: [0 - %d]\n",
3118ffc942dSrz INT16_MAX);
3128ffc942dSrz exit(1);
3138ffc942dSrz }
3148ffc942dSrz
3158ffc942dSrz if ((error = set_beep_freq(kbd, b_type, freq_val)) != 0)
3168ffc942dSrz exit(1);
3178ffc942dSrz }
3188ffc942dSrz
3197db6e34eSqz return (0);
3207db6e34eSqz }
3217db6e34eSqz
3227db6e34eSqz /*
3237db6e34eSqz * this routine gets the type of the keyboard being used
3247db6e34eSqz */
3257db6e34eSqz static int
set_kbd_layout(int kbd,char * layout_name)3267db6e34eSqz set_kbd_layout(int kbd, char *layout_name)
3277db6e34eSqz {
3287db6e34eSqz int layout_num;
3297db6e34eSqz int error = 1;
3307db6e34eSqz
3313c333a60Svn /* layout setting is possible only for USB type keyboards */
3323c333a60Svn if (get_type(kbd) != KB_USB) {
3333c333a60Svn (void) fprintf(stderr, "The -s option does not apply for this"
3348600af92Sfei feng - Sun Microsystems - Beijing China " keyboard type.\n"
3358600af92Sfei feng - Sun Microsystems - Beijing China "Only USB/PS2 type keyboards support this option.\n");
3363c333a60Svn return (error);
3373c333a60Svn }
3383c333a60Svn
3397db6e34eSqz /* get the language info from the layouts file */
3407db6e34eSqz if (get_layouts() != 0)
3417db6e34eSqz return (error);
3427db6e34eSqz
3437db6e34eSqz if (layout_name != NULL) {
3447db6e34eSqz if ((layout_num = get_layout_number(layout_name)) == -1) {
3457db6e34eSqz (void) fprintf(stderr, "%s: unknown layout name\n"
3468600af92Sfei feng - Sun Microsystems - Beijing China "Please refer to 'kbd -s' to get the "
3478600af92Sfei feng - Sun Microsystems - Beijing China "supported layouts.\n", layout_name);
3487db6e34eSqz return (error);
3497db6e34eSqz }
3507db6e34eSqz } else {
3517db6e34eSqz int i, j, print_cnt, input_num;
3527db6e34eSqz boolean_t input_right = B_TRUE;
3537db6e34eSqz boolean_t default_input = B_FALSE;
3547db6e34eSqz char input[8]; /* 8 chars is enough for numbers */
3557db6e34eSqz
3567db6e34eSqz print_cnt = (layout_count % 2) ?
3578600af92Sfei feng - Sun Microsystems - Beijing China layout_count/2+1 : layout_count/2;
3587db6e34eSqz
3597db6e34eSqz for (i = 1; i <= print_cnt; i++) {
3607db6e34eSqz (void) printf("%2d. %-30s", i,
3618600af92Sfei feng - Sun Microsystems - Beijing China layout_names[i-1]);
3627db6e34eSqz j = i + print_cnt;
3637db6e34eSqz if (j <= layout_count) {
3647db6e34eSqz (void) printf("%-2d. %-30s\n", j,
3658600af92Sfei feng - Sun Microsystems - Beijing China layout_names[j-1]);
3667db6e34eSqz }
3677db6e34eSqz }
368d8c870b0Sqz (void) printf(gettext("\nTo select the keyboard layout,"
3698600af92Sfei feng - Sun Microsystems - Beijing China " enter a number [default %d]:"),
3708600af92Sfei feng - Sun Microsystems - Beijing China default_layout_number+1);
3717db6e34eSqz
3727db6e34eSqz for (;;) {
3737db6e34eSqz if (input_right == B_FALSE)
374d8c870b0Sqz (void) printf(gettext("Invalid input. "
375d8c870b0Sqz "Please input a number "
376d8c870b0Sqz "(1,2,...):"));
3777db6e34eSqz (void) memset(input, 0, 8);
3787db6e34eSqz (void) fflush(stdin);
3797db6e34eSqz (void) fgets(input, 8, stdin);
3807db6e34eSqz if (strlen(input) > 4) {
3817db6e34eSqz input_right = B_FALSE;
3827db6e34eSqz continue;
3837db6e34eSqz }
3847db6e34eSqz if (input[0] == '\n') {
3857db6e34eSqz default_input = B_TRUE;
3867db6e34eSqz break;
3877db6e34eSqz }
3887db6e34eSqz input_right = B_TRUE;
3897db6e34eSqz /* check if the inputs are numbers 0~9 */
3907db6e34eSqz for (i = 0; i < (strlen(input) - 1); i++) {
3917db6e34eSqz if ((input[i] < '0') ||
3927db6e34eSqz (input[i] > '9')) {
3937db6e34eSqz input_right = B_FALSE;
3947db6e34eSqz break;
3957db6e34eSqz }
3967db6e34eSqz }
3977db6e34eSqz if (input_right == B_FALSE)
3987db6e34eSqz continue;
3997db6e34eSqz input_num = atoi(input);
4007db6e34eSqz if ((input_num > 0) &&
4017db6e34eSqz (input_num <= layout_count))
4027db6e34eSqz break;
4037db6e34eSqz else
4047db6e34eSqz input_right = B_FALSE;
4057db6e34eSqz }
4067db6e34eSqz if (default_input == B_TRUE)
4077db6e34eSqz layout_num = DEFAULT_KBD_LAYOUT;
4087db6e34eSqz else
4097db6e34eSqz layout_num = layout_numbers[--input_num];
4107db6e34eSqz }
4117db6e34eSqz
4127db6e34eSqz if ((error = set_layout(kbd, layout_num)) != 0)
4137db6e34eSqz return (error);
4147db6e34eSqz
4157c478bd9Sstevel@tonic-gate return (0);
4167c478bd9Sstevel@tonic-gate }
4177c478bd9Sstevel@tonic-gate
4188ffc942dSrz /*
4198ffc942dSrz * This routine sets keyboard or console beeper frequency
4208ffc942dSrz */
4218ffc942dSrz static int
set_beep_freq(int fd,char * type,int freq)4228ffc942dSrz set_beep_freq(int fd, char *type, int freq)
4238ffc942dSrz {
4248ffc942dSrz struct freq_request fr_struct;
4258ffc942dSrz
4268ffc942dSrz if (strcmp(type, "keyboard") == 0)
4278ffc942dSrz fr_struct.type = KBD_BEEP;
4288ffc942dSrz else if (strcmp(type, "console") == 0)
4298ffc942dSrz fr_struct.type = CONSOLE_BEEP;
4308ffc942dSrz else
4318ffc942dSrz return (EINVAL);
4328ffc942dSrz
4338ffc942dSrz fr_struct.freq = (int16_t)freq;
4348ffc942dSrz
4358ffc942dSrz return (ioctl(fd, KIOCSETFREQ, &fr_struct));
4368ffc942dSrz }
4378ffc942dSrz
4387c478bd9Sstevel@tonic-gate /*
4397c478bd9Sstevel@tonic-gate * this routine resets the state of the keyboard as if power-up
4407c478bd9Sstevel@tonic-gate */
4417c478bd9Sstevel@tonic-gate static void
reset(int kbd)4427c478bd9Sstevel@tonic-gate reset(int kbd)
4437c478bd9Sstevel@tonic-gate {
4447c478bd9Sstevel@tonic-gate int cmd;
4457c478bd9Sstevel@tonic-gate
4467c478bd9Sstevel@tonic-gate cmd = KBD_CMD_RESET;
4477c478bd9Sstevel@tonic-gate
4487c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCCMD, &cmd)) {
4497c478bd9Sstevel@tonic-gate perror("kbd: ioctl error");
4507c478bd9Sstevel@tonic-gate exit(1);
4517c478bd9Sstevel@tonic-gate }
4527c478bd9Sstevel@tonic-gate
4537c478bd9Sstevel@tonic-gate }
4547c478bd9Sstevel@tonic-gate
4557c478bd9Sstevel@tonic-gate /*
4567c478bd9Sstevel@tonic-gate * this routine gets the type of the keyboard being used
4577c478bd9Sstevel@tonic-gate */
4583c333a60Svn static int
get_type(int kbd)4597c478bd9Sstevel@tonic-gate get_type(int kbd)
4607c478bd9Sstevel@tonic-gate {
4617c478bd9Sstevel@tonic-gate int kbd_type;
4627c478bd9Sstevel@tonic-gate
4637c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCTYPE, &kbd_type)) {
4647c478bd9Sstevel@tonic-gate perror("ioctl (kbd type)");
4657c478bd9Sstevel@tonic-gate exit(1);
4667c478bd9Sstevel@tonic-gate }
4677c478bd9Sstevel@tonic-gate
4687c478bd9Sstevel@tonic-gate switch (kbd_type) {
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate case KB_SUN3:
4717c478bd9Sstevel@tonic-gate (void) printf("Type 3 Sun keyboard\n");
4727c478bd9Sstevel@tonic-gate break;
4737c478bd9Sstevel@tonic-gate
4747c478bd9Sstevel@tonic-gate case KB_SUN4:
4757c478bd9Sstevel@tonic-gate (void) printf("Type 4 Sun keyboard\n");
4767c478bd9Sstevel@tonic-gate break;
4777c478bd9Sstevel@tonic-gate
4787c478bd9Sstevel@tonic-gate case KB_ASCII:
4797c478bd9Sstevel@tonic-gate (void) printf("ASCII\n");
4807c478bd9Sstevel@tonic-gate break;
4817c478bd9Sstevel@tonic-gate
4827c478bd9Sstevel@tonic-gate case KB_PC:
4837c478bd9Sstevel@tonic-gate (void) printf("PC\n");
4847c478bd9Sstevel@tonic-gate break;
4857c478bd9Sstevel@tonic-gate
4867c478bd9Sstevel@tonic-gate case KB_USB:
4877c478bd9Sstevel@tonic-gate (void) printf("USB keyboard\n");
4887c478bd9Sstevel@tonic-gate break;
4897c478bd9Sstevel@tonic-gate
4907c478bd9Sstevel@tonic-gate default:
4917c478bd9Sstevel@tonic-gate (void) printf("Unknown keyboard type\n");
4927c478bd9Sstevel@tonic-gate break;
4937c478bd9Sstevel@tonic-gate }
4943c333a60Svn return (kbd_type);
4957c478bd9Sstevel@tonic-gate }
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate /*
4987c478bd9Sstevel@tonic-gate * this routine gets the layout of the keyboard being used
4997c478bd9Sstevel@tonic-gate * also, included the autorepeat delay and rate being used
5007c478bd9Sstevel@tonic-gate */
5017c478bd9Sstevel@tonic-gate static void
get_layout(int kbd)5027c478bd9Sstevel@tonic-gate get_layout(int kbd)
5037c478bd9Sstevel@tonic-gate {
5047c478bd9Sstevel@tonic-gate int kbd_type;
5057c478bd9Sstevel@tonic-gate int kbd_layout;
506*c0423dd8SToomas Soome /* these three variables are used for getting delay&rate&count */
507*c0423dd8SToomas Soome int delay, rate, count = -1;
5087c478bd9Sstevel@tonic-gate delay = rate = 0;
5097c478bd9Sstevel@tonic-gate
5107c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCTYPE, &kbd_type)) {
5117c478bd9Sstevel@tonic-gate perror("ioctl (kbd type)");
5127c478bd9Sstevel@tonic-gate exit(1);
5137c478bd9Sstevel@tonic-gate }
5147c478bd9Sstevel@tonic-gate
5157c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCLAYOUT, &kbd_layout)) {
5167c478bd9Sstevel@tonic-gate perror("ioctl (kbd layout)");
5177c478bd9Sstevel@tonic-gate exit(1);
5187c478bd9Sstevel@tonic-gate }
5197c478bd9Sstevel@tonic-gate
5207c478bd9Sstevel@tonic-gate (void) printf("type=%d\nlayout=%d (0x%.2x)\n",
5217c478bd9Sstevel@tonic-gate kbd_type, kbd_layout, kbd_layout);
5227c478bd9Sstevel@tonic-gate
5237c478bd9Sstevel@tonic-gate /* below code is used to get the autorepeat delay and rate */
5247c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCGRPTDELAY, &delay)) {
5257c478bd9Sstevel@tonic-gate perror("ioctl (kbd get repeat delay)");
5267c478bd9Sstevel@tonic-gate exit(1);
5277c478bd9Sstevel@tonic-gate }
5287c478bd9Sstevel@tonic-gate
5297c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCGRPTRATE, &rate)) {
5307c478bd9Sstevel@tonic-gate perror("ioctl (kbd get repeat rate)");
5317c478bd9Sstevel@tonic-gate exit(1);
5327c478bd9Sstevel@tonic-gate }
5337c478bd9Sstevel@tonic-gate
534*c0423dd8SToomas Soome if (ioctl(kbd, KIOCGRPTCOUNT, &count)) {
535*c0423dd8SToomas Soome perror("ioctl (kbd get repeat count)");
536*c0423dd8SToomas Soome exit(1);
537*c0423dd8SToomas Soome }
538*c0423dd8SToomas Soome
5397c478bd9Sstevel@tonic-gate (void) printf("delay(ms)=%d\n", delay);
5407c478bd9Sstevel@tonic-gate (void) printf("rate(ms)=%d\n", rate);
541*c0423dd8SToomas Soome if (count == -1)
542*c0423dd8SToomas Soome (void) printf("count=unlimited\n");
543*c0423dd8SToomas Soome else
544*c0423dd8SToomas Soome (void) printf("count=%d\n", count);
5457c478bd9Sstevel@tonic-gate }
5467c478bd9Sstevel@tonic-gate
5477c478bd9Sstevel@tonic-gate /*
5487c478bd9Sstevel@tonic-gate * this routine enables or disables clicking of the keyboard
5497c478bd9Sstevel@tonic-gate */
5507c478bd9Sstevel@tonic-gate static int
click(char * copt,int kbd)5517c478bd9Sstevel@tonic-gate click(char *copt, int kbd)
5527c478bd9Sstevel@tonic-gate {
5537c478bd9Sstevel@tonic-gate int cmd;
5547c478bd9Sstevel@tonic-gate
5557c478bd9Sstevel@tonic-gate if (strcmp(copt, "on") == 0)
5567c478bd9Sstevel@tonic-gate cmd = KBD_CMD_CLICK;
5577c478bd9Sstevel@tonic-gate else if (strcmp(copt, "off") == 0)
5587c478bd9Sstevel@tonic-gate cmd = KBD_CMD_NOCLICK;
5597c478bd9Sstevel@tonic-gate else {
5607c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "wrong option -- %s\n", copt);
5617c478bd9Sstevel@tonic-gate usage();
5627c478bd9Sstevel@tonic-gate return (1);
5637c478bd9Sstevel@tonic-gate }
5647c478bd9Sstevel@tonic-gate
5657c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCCMD, &cmd)) {
5667c478bd9Sstevel@tonic-gate perror("kbd ioctl (keyclick)");
5677c478bd9Sstevel@tonic-gate return (1);
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate return (0);
5707c478bd9Sstevel@tonic-gate }
5717c478bd9Sstevel@tonic-gate
5727c478bd9Sstevel@tonic-gate /*
5737c478bd9Sstevel@tonic-gate * this routine enables/disables/sets BRK or abort sequence feature
5747c478bd9Sstevel@tonic-gate */
5757c478bd9Sstevel@tonic-gate static int
abort_enable(char * aopt,int kbd)5767c478bd9Sstevel@tonic-gate abort_enable(char *aopt, int kbd)
5777c478bd9Sstevel@tonic-gate {
5787c478bd9Sstevel@tonic-gate int enable;
5797c478bd9Sstevel@tonic-gate
5807c478bd9Sstevel@tonic-gate if (strcmp(aopt, "alternate") == 0)
5817c478bd9Sstevel@tonic-gate enable = KIOCABORTALTERNATE;
5827c478bd9Sstevel@tonic-gate else if (strcmp(aopt, "enable") == 0)
5837c478bd9Sstevel@tonic-gate enable = KIOCABORTENABLE;
5847c478bd9Sstevel@tonic-gate else if (strcmp(aopt, "disable") == 0)
5857c478bd9Sstevel@tonic-gate enable = KIOCABORTDISABLE;
5867c478bd9Sstevel@tonic-gate else {
5877c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "wrong option -- %s\n", aopt);
5887c478bd9Sstevel@tonic-gate usage();
5897c478bd9Sstevel@tonic-gate return (1);
5907c478bd9Sstevel@tonic-gate }
5917c478bd9Sstevel@tonic-gate
5927c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSKABORTEN, &enable)) {
5937c478bd9Sstevel@tonic-gate perror("kbd ioctl (abort enable)");
5947c478bd9Sstevel@tonic-gate return (1);
5957c478bd9Sstevel@tonic-gate }
5967c478bd9Sstevel@tonic-gate return (0);
5977c478bd9Sstevel@tonic-gate }
5987c478bd9Sstevel@tonic-gate
599*c0423dd8SToomas Soome static int
set_rptcount(int count,int kbd)600*c0423dd8SToomas Soome set_rptcount(int count, int kbd)
601*c0423dd8SToomas Soome {
602*c0423dd8SToomas Soome if (ioctl(kbd, KIOCSRPTCOUNT, &count) == -1) {
603*c0423dd8SToomas Soome perror("kbd: set repeat count");
604*c0423dd8SToomas Soome return (1);
605*c0423dd8SToomas Soome }
606*c0423dd8SToomas Soome return (0);
607*c0423dd8SToomas Soome }
608*c0423dd8SToomas Soome
609*c0423dd8SToomas Soome static int
set_repeat_count(char * count_str,int kbd)610*c0423dd8SToomas Soome set_repeat_count(char *count_str, int kbd)
611*c0423dd8SToomas Soome {
612*c0423dd8SToomas Soome int count = atoi(count_str);
613*c0423dd8SToomas Soome
614*c0423dd8SToomas Soome return (set_rptcount(count, kbd));
615*c0423dd8SToomas Soome }
616*c0423dd8SToomas Soome
6177c478bd9Sstevel@tonic-gate static int
set_rptdelay(int delay,int kbd)6188600af92Sfei feng - Sun Microsystems - Beijing China set_rptdelay(int delay, int kbd)
6197c478bd9Sstevel@tonic-gate {
6207c478bd9Sstevel@tonic-gate /*
6217c478bd9Sstevel@tonic-gate * The error message depends on the different inputs.
6227c478bd9Sstevel@tonic-gate * a. the input is a invalid integer(unit in ms)
6237c478bd9Sstevel@tonic-gate * b. the input is a integer less than the minimal delay setting.
6244470e687Syx * The condition (a) has been covered by main function and kbd_defaults
6257c478bd9Sstevel@tonic-gate * function.
6267c478bd9Sstevel@tonic-gate */
6277c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSRPTDELAY, &delay) == -1) {
6287c478bd9Sstevel@tonic-gate if (delay < KIOCRPTDELAY_MIN)
6297c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "kbd: specified delay %d is "
6307c478bd9Sstevel@tonic-gate "less than minimum %d\n", delay, KIOCRPTDELAY_MIN);
6317c478bd9Sstevel@tonic-gate else
6327c478bd9Sstevel@tonic-gate perror("kbd: set repeat delay");
6337c478bd9Sstevel@tonic-gate return (1);
6347c478bd9Sstevel@tonic-gate }
6357c478bd9Sstevel@tonic-gate
6367c478bd9Sstevel@tonic-gate return (0);
6377c478bd9Sstevel@tonic-gate }
6387c478bd9Sstevel@tonic-gate
6397c478bd9Sstevel@tonic-gate /*
6408600af92Sfei feng - Sun Microsystems - Beijing China * this routine set autorepeat delay
6417c478bd9Sstevel@tonic-gate */
6427c478bd9Sstevel@tonic-gate static int
set_repeat_delay(char * delay_str,int kbd)6438600af92Sfei feng - Sun Microsystems - Beijing China set_repeat_delay(char *delay_str, int kbd)
6447c478bd9Sstevel@tonic-gate {
6458600af92Sfei feng - Sun Microsystems - Beijing China int delay = atoi(delay_str);
6468600af92Sfei feng - Sun Microsystems - Beijing China
6478600af92Sfei feng - Sun Microsystems - Beijing China return (set_rptdelay(delay, kbd));
6488600af92Sfei feng - Sun Microsystems - Beijing China }
6497c478bd9Sstevel@tonic-gate
6508600af92Sfei feng - Sun Microsystems - Beijing China static int
set_rptrate(int rate,int kbd)6518600af92Sfei feng - Sun Microsystems - Beijing China set_rptrate(int rate, int kbd)
6528600af92Sfei feng - Sun Microsystems - Beijing China {
6537c478bd9Sstevel@tonic-gate /*
6544470e687Syx * The input validation check has been covered by main function
6554470e687Syx * and kbd_defaults function.Here just give an error message if
6564470e687Syx * the ioctl fails.
6577c478bd9Sstevel@tonic-gate */
6587c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSRPTRATE, &rate) == -1) {
6594470e687Syx perror("kbd: set repeat rate");
6607c478bd9Sstevel@tonic-gate return (1);
6617c478bd9Sstevel@tonic-gate }
6627c478bd9Sstevel@tonic-gate return (0);
6637c478bd9Sstevel@tonic-gate }
6647c478bd9Sstevel@tonic-gate
6658600af92Sfei feng - Sun Microsystems - Beijing China /*
6668600af92Sfei feng - Sun Microsystems - Beijing China * this routine set autorepeat rate
6678600af92Sfei feng - Sun Microsystems - Beijing China */
6688600af92Sfei feng - Sun Microsystems - Beijing China static int
set_repeat_rate(char * rate_str,int kbd)6698600af92Sfei feng - Sun Microsystems - Beijing China set_repeat_rate(char *rate_str, int kbd)
6708600af92Sfei feng - Sun Microsystems - Beijing China {
6718600af92Sfei feng - Sun Microsystems - Beijing China int rate = atoi(rate_str);
6728600af92Sfei feng - Sun Microsystems - Beijing China
6738600af92Sfei feng - Sun Microsystems - Beijing China return (set_rptrate(rate, kbd));
6748600af92Sfei feng - Sun Microsystems - Beijing China }
6758600af92Sfei feng - Sun Microsystems - Beijing China
6768600af92Sfei feng - Sun Microsystems - Beijing China #define BAD_DEFAULT_STR "kbd: bad default value for %s: %s\n"
6778600af92Sfei feng - Sun Microsystems - Beijing China #define BAD_DEFAULT_INT "kbd: bad default value for %s: %d\n"
6788600af92Sfei feng - Sun Microsystems - Beijing China #define BAD_DEFAULT_LLINT "kbd: bad default value for %s: %lld\n"
6797c478bd9Sstevel@tonic-gate
6807c478bd9Sstevel@tonic-gate static void
kbd_defaults(int kbd)6817c478bd9Sstevel@tonic-gate kbd_defaults(int kbd)
6827c478bd9Sstevel@tonic-gate {
6838600af92Sfei feng - Sun Microsystems - Beijing China scf_handle_t *h = NULL;
6848600af92Sfei feng - Sun Microsystems - Beijing China scf_snapshot_t *snap = NULL;
6858600af92Sfei feng - Sun Microsystems - Beijing China scf_instance_t *inst = NULL;
6868600af92Sfei feng - Sun Microsystems - Beijing China scf_propertygroup_t *pg = NULL;
6878600af92Sfei feng - Sun Microsystems - Beijing China scf_property_t *prop = NULL;
6888600af92Sfei feng - Sun Microsystems - Beijing China scf_value_t *val = NULL;
6897c478bd9Sstevel@tonic-gate
6908600af92Sfei feng - Sun Microsystems - Beijing China int layout_num;
6918600af92Sfei feng - Sun Microsystems - Beijing China char *val_layout = NULL, *val_abort = NULL;
6928600af92Sfei feng - Sun Microsystems - Beijing China uint8_t val_click;
693*c0423dd8SToomas Soome int64_t val_delay, val_rate, val_count;
6948600af92Sfei feng - Sun Microsystems - Beijing China int64_t val_kbd_beeper, val_console_beeper;
6958600af92Sfei feng - Sun Microsystems - Beijing China
6968600af92Sfei feng - Sun Microsystems - Beijing China if ((h = scf_handle_create(SCF_VERSION)) == NULL ||
6978600af92Sfei feng - Sun Microsystems - Beijing China scf_handle_bind(h) != 0 ||
6988600af92Sfei feng - Sun Microsystems - Beijing China (inst = scf_instance_create(h)) == NULL ||
6998600af92Sfei feng - Sun Microsystems - Beijing China (snap = scf_snapshot_create(h)) == NULL ||
7008600af92Sfei feng - Sun Microsystems - Beijing China (pg = scf_pg_create(h)) == NULL ||
7018600af92Sfei feng - Sun Microsystems - Beijing China (prop = scf_property_create(h)) == NULL ||
7028600af92Sfei feng - Sun Microsystems - Beijing China (val = scf_value_create(h)) == NULL) {
7038600af92Sfei feng - Sun Microsystems - Beijing China goto out;
7047c478bd9Sstevel@tonic-gate }
7057c478bd9Sstevel@tonic-gate
7068600af92Sfei feng - Sun Microsystems - Beijing China if (scf_handle_decode_fmri(h, KBD_FMRI, NULL, NULL, inst,
7078600af92Sfei feng - Sun Microsystems - Beijing China NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) {
7088600af92Sfei feng - Sun Microsystems - Beijing China goto out;
7098600af92Sfei feng - Sun Microsystems - Beijing China }
7108600af92Sfei feng - Sun Microsystems - Beijing China
7118600af92Sfei feng - Sun Microsystems - Beijing China if (scf_instance_get_snapshot(inst, "running", snap) != 0) {
7128600af92Sfei feng - Sun Microsystems - Beijing China scf_snapshot_destroy(snap);
7138600af92Sfei feng - Sun Microsystems - Beijing China snap = NULL;
7148600af92Sfei feng - Sun Microsystems - Beijing China }
7158600af92Sfei feng - Sun Microsystems - Beijing China
7168600af92Sfei feng - Sun Microsystems - Beijing China if (scf_instance_get_pg_composed(inst, snap, KBD_PG, pg) != 0) {
7178600af92Sfei feng - Sun Microsystems - Beijing China goto out;
7188600af92Sfei feng - Sun Microsystems - Beijing China }
7198600af92Sfei feng - Sun Microsystems - Beijing China
7208600af92Sfei feng - Sun Microsystems - Beijing China if ((val_abort = malloc(KBD_MAX_NAME_LEN)) == NULL) {
7218600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
7228600af92Sfei feng - Sun Microsystems - Beijing China "Can not alloc memory for keyboard properties\n");
7238600af92Sfei feng - Sun Microsystems - Beijing China goto out;
7247c478bd9Sstevel@tonic-gate }
7257c478bd9Sstevel@tonic-gate
7268600af92Sfei feng - Sun Microsystems - Beijing China if ((val_layout = malloc(KBD_MAX_NAME_LEN)) == NULL) {
7278600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
7288600af92Sfei feng - Sun Microsystems - Beijing China "Can not alloc memory for keyboard properties\n");
7298600af92Sfei feng - Sun Microsystems - Beijing China goto out;
7308600af92Sfei feng - Sun Microsystems - Beijing China }
7318600af92Sfei feng - Sun Microsystems - Beijing China
7328600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_KEYCLICK, prop) != 0 ||
7338600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
7348600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_boolean(val, &val_click) == -1) {
7358600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get KEYCLICK\n");
7368600af92Sfei feng - Sun Microsystems - Beijing China }
7378600af92Sfei feng - Sun Microsystems - Beijing China
7388600af92Sfei feng - Sun Microsystems - Beijing China if (val_click == 1)
7398600af92Sfei feng - Sun Microsystems - Beijing China (void) click("on", kbd);
7408600af92Sfei feng - Sun Microsystems - Beijing China else if (val_click == 0)
7418600af92Sfei feng - Sun Microsystems - Beijing China (void) click("off", kbd);
7428600af92Sfei feng - Sun Microsystems - Beijing China else
7438600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
7448600af92Sfei feng - Sun Microsystems - Beijing China BAD_DEFAULT_INT, KBD_PROP_KEYCLICK, val_click);
7458600af92Sfei feng - Sun Microsystems - Beijing China
7468600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_KEYBOARD_ABORT, prop) != 0 ||
7478600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
7488600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_astring(val, val_abort, KBD_MAX_NAME_LEN) == -1) {
7498600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get KEYBOARD_ABORT\n");
7508600af92Sfei feng - Sun Microsystems - Beijing China }
7518600af92Sfei feng - Sun Microsystems - Beijing China
7528600af92Sfei feng - Sun Microsystems - Beijing China if (*val_abort != '\0') {
7537c478bd9Sstevel@tonic-gate /*
7547c478bd9Sstevel@tonic-gate * ABORT must equal "enable", "disable" or "alternate"
7557c478bd9Sstevel@tonic-gate */
7568600af92Sfei feng - Sun Microsystems - Beijing China if ((strcmp(val_abort, "enable") == 0) ||
7578600af92Sfei feng - Sun Microsystems - Beijing China (strcmp(val_abort, "alternate") == 0) ||
7588600af92Sfei feng - Sun Microsystems - Beijing China (strcmp(val_abort, "disable") == 0))
7598600af92Sfei feng - Sun Microsystems - Beijing China (void) abort_enable(val_abort, kbd);
7607c478bd9Sstevel@tonic-gate else
7618600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, BAD_DEFAULT_STR,
7628600af92Sfei feng - Sun Microsystems - Beijing China KBD_PROP_KEYBOARD_ABORT, val_abort);
7637c478bd9Sstevel@tonic-gate }
7647c478bd9Sstevel@tonic-gate
765*c0423dd8SToomas Soome if (scf_pg_get_property(pg, KBD_PROP_RPTCOUNT, prop) != 0 ||
766*c0423dd8SToomas Soome scf_property_get_value(prop, val) != 0 ||
767*c0423dd8SToomas Soome scf_value_get_integer(val, &val_count) == -1) {
768*c0423dd8SToomas Soome (void) fprintf(stderr, "Can not get RPTCOUNT\n");
769*c0423dd8SToomas Soome }
770*c0423dd8SToomas Soome
771*c0423dd8SToomas Soome if (val_count == -1 || (val_count > 0 && val_count < INT_MAX))
772*c0423dd8SToomas Soome (void) set_rptcount(val_count, kbd);
773*c0423dd8SToomas Soome else
774*c0423dd8SToomas Soome (void) fprintf(stderr,
775*c0423dd8SToomas Soome BAD_DEFAULT_LLINT, KBD_PROP_RPTCOUNT, val_count);
776*c0423dd8SToomas Soome
7778600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_RPTDELAY, prop) != 0 ||
7788600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
7798600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_integer(val, &val_delay) == -1) {
7808600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get RPTDELAY\n");
7817c478bd9Sstevel@tonic-gate }
7827c478bd9Sstevel@tonic-gate
7838600af92Sfei feng - Sun Microsystems - Beijing China if (val_delay > 0)
7848600af92Sfei feng - Sun Microsystems - Beijing China (void) set_rptdelay(val_delay, kbd);
7858600af92Sfei feng - Sun Microsystems - Beijing China else
7868600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
7878600af92Sfei feng - Sun Microsystems - Beijing China BAD_DEFAULT_LLINT, KBD_PROP_RPTDELAY, val_delay);
7888600af92Sfei feng - Sun Microsystems - Beijing China
7898600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_RPTRATE, prop) != 0 ||
7908600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
7918600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_integer(val, &val_rate) == -1) {
7928600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get RPTRATE\n");
7937c478bd9Sstevel@tonic-gate }
7947db6e34eSqz
7958600af92Sfei feng - Sun Microsystems - Beijing China if (val_rate > 0)
7968600af92Sfei feng - Sun Microsystems - Beijing China (void) set_rptrate(val_rate, kbd);
7978600af92Sfei feng - Sun Microsystems - Beijing China else
7988600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
7998600af92Sfei feng - Sun Microsystems - Beijing China BAD_DEFAULT_LLINT, KBD_PROP_RPTRATE, val_rate);
8008600af92Sfei feng - Sun Microsystems - Beijing China
8018600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_LAYOUT, prop) != 0 ||
8028600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
8038600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_astring(val, val_layout, KBD_MAX_NAME_LEN) == -1) {
8048600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get LAYOUT\n");
8058600af92Sfei feng - Sun Microsystems - Beijing China }
8068600af92Sfei feng - Sun Microsystems - Beijing China
8078600af92Sfei feng - Sun Microsystems - Beijing China if (*val_layout != '\0') {
8087db6e34eSqz /*
8097db6e34eSqz * LAYOUT must be one of the layouts supported in kbd_layouts
8107db6e34eSqz */
8117db6e34eSqz if (get_layouts() != 0)
8128600af92Sfei feng - Sun Microsystems - Beijing China goto out;
8137db6e34eSqz
8148600af92Sfei feng - Sun Microsystems - Beijing China if ((layout_num = get_layout_number(val_layout)) == -1) {
8158600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
8168600af92Sfei feng - Sun Microsystems - Beijing China BAD_DEFAULT_STR, KBD_PROP_LAYOUT, val_layout);
8178600af92Sfei feng - Sun Microsystems - Beijing China goto out;
8187db6e34eSqz }
8197db6e34eSqz
8207db6e34eSqz (void) set_layout(kbd, layout_num);
8217db6e34eSqz }
8228ffc942dSrz
8238600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_FREQ, prop) != 0 ||
8248600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
8258600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_integer(val, &val_kbd_beeper) == -1) {
8268600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get FREQ\n");
8278ffc942dSrz }
8288ffc942dSrz
8298600af92Sfei feng - Sun Microsystems - Beijing China if (val_kbd_beeper >= 0 && val_kbd_beeper <= INT16_MAX)
8308600af92Sfei feng - Sun Microsystems - Beijing China (void) set_beep_freq(kbd, "keyboard", val_kbd_beeper);
8318600af92Sfei feng - Sun Microsystems - Beijing China else
8328600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
8338600af92Sfei feng - Sun Microsystems - Beijing China BAD_DEFAULT_LLINT, KBD_PROP_FREQ, val_kbd_beeper);
8348600af92Sfei feng - Sun Microsystems - Beijing China
8358600af92Sfei feng - Sun Microsystems - Beijing China if (scf_pg_get_property(pg, KBD_PROP_CONSFREQ, prop) != 0 ||
8368600af92Sfei feng - Sun Microsystems - Beijing China scf_property_get_value(prop, val) != 0 ||
8378600af92Sfei feng - Sun Microsystems - Beijing China scf_value_get_integer(val, &val_console_beeper) == -1) {
8388600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr, "Can not get CONSFREQ\n");
8398ffc942dSrz }
8408600af92Sfei feng - Sun Microsystems - Beijing China
8418600af92Sfei feng - Sun Microsystems - Beijing China if (val_console_beeper >= 0 && val_console_beeper <= INT16_MAX)
8428600af92Sfei feng - Sun Microsystems - Beijing China (void) set_beep_freq(kbd, "console", val_console_beeper);
8438600af92Sfei feng - Sun Microsystems - Beijing China else
8448600af92Sfei feng - Sun Microsystems - Beijing China (void) fprintf(stderr,
8458600af92Sfei feng - Sun Microsystems - Beijing China BAD_DEFAULT_LLINT, KBD_PROP_CONSFREQ, val_console_beeper);
8468600af92Sfei feng - Sun Microsystems - Beijing China
8478600af92Sfei feng - Sun Microsystems - Beijing China out:
8488600af92Sfei feng - Sun Microsystems - Beijing China if (val_layout != NULL)
8498600af92Sfei feng - Sun Microsystems - Beijing China free(val_layout);
8508600af92Sfei feng - Sun Microsystems - Beijing China if (val_abort != NULL)
8518600af92Sfei feng - Sun Microsystems - Beijing China free(val_abort);
8528600af92Sfei feng - Sun Microsystems - Beijing China if (snap != NULL)
8538600af92Sfei feng - Sun Microsystems - Beijing China scf_snapshot_destroy(snap);
8548600af92Sfei feng - Sun Microsystems - Beijing China scf_value_destroy(val);
8558600af92Sfei feng - Sun Microsystems - Beijing China scf_property_destroy(prop);
8568600af92Sfei feng - Sun Microsystems - Beijing China scf_pg_destroy(pg);
8578600af92Sfei feng - Sun Microsystems - Beijing China scf_instance_destroy(inst);
8588600af92Sfei feng - Sun Microsystems - Beijing China scf_handle_destroy(h);
8597db6e34eSqz }
8607db6e34eSqz
8617db6e34eSqz static int
get_layout_number(char * layout)8627db6e34eSqz get_layout_number(char *layout)
8637db6e34eSqz {
8647db6e34eSqz int i;
8657db6e34eSqz int layout_number = -1;
8667db6e34eSqz
8677db6e34eSqz for (i = 0; i < layout_count; i ++) {
8687db6e34eSqz if (strcmp(layout, layout_names[i]) == 0) {
8697db6e34eSqz layout_number = layout_numbers[i];
8707db6e34eSqz break;
8717db6e34eSqz }
8727db6e34eSqz }
8737db6e34eSqz
8747db6e34eSqz return (layout_number);
8757db6e34eSqz }
8767db6e34eSqz
8777db6e34eSqz static int
get_layouts()8787db6e34eSqz get_layouts()
8797db6e34eSqz {
8807db6e34eSqz FILE *stream;
8817db6e34eSqz char buffer[MAX_LINE_SIZE];
8827db6e34eSqz char *result = NULL;
8837db6e34eSqz int i = 0;
8847db6e34eSqz char *tmpbuf;
8857db6e34eSqz
8867db6e34eSqz if ((stream = fopen(KBD_LAYOUT_FILE, "r")) == 0) {
8877db6e34eSqz perror(KBD_LAYOUT_FILE);
8887db6e34eSqz return (1);
8897db6e34eSqz }
8907db6e34eSqz
8917db6e34eSqz while ((fgets(buffer, MAX_LINE_SIZE, stream) != NULL) &&
8927db6e34eSqz (i < MAX_LAYOUT_NUM)) {
8937db6e34eSqz if (buffer[0] == '#')
8947db6e34eSqz continue;
8957db6e34eSqz if ((result = strtok(buffer, "=")) == NULL)
8967db6e34eSqz continue;
8977db6e34eSqz if ((tmpbuf = strdup(result)) != NULL) {
8987db6e34eSqz layout_names[i] = tmpbuf;
8997db6e34eSqz } else {
9007db6e34eSqz perror("out of memory getting layout names");
9017db6e34eSqz return (1);
9027db6e34eSqz }
9037db6e34eSqz if ((result = strtok(NULL, "\n")) == NULL)
9047db6e34eSqz continue;
9057db6e34eSqz layout_numbers[i] = atoi(result);
9067db6e34eSqz if (strcmp(tmpbuf, "US-English") == 0)
9077db6e34eSqz default_layout_number = i;
9087db6e34eSqz i++;
9097db6e34eSqz }
9107db6e34eSqz layout_count = i;
9117db6e34eSqz
9127db6e34eSqz return (0);
9137db6e34eSqz }
9147db6e34eSqz
9157db6e34eSqz /*
9167db6e34eSqz * this routine sets the layout of the keyboard being used
9177db6e34eSqz */
9187db6e34eSqz static int
set_layout(int kbd,int layout_num)9197db6e34eSqz set_layout(int kbd, int layout_num)
9207db6e34eSqz {
9217db6e34eSqz
9227db6e34eSqz if (ioctl(kbd, KIOCSLAYOUT, layout_num)) {
9237db6e34eSqz perror("ioctl (set kbd layout)");
9247db6e34eSqz return (1);
9257db6e34eSqz }
9266d75a680SToomas Soome (void) system("/usr/bin/loadkeys");
9277db6e34eSqz
9287db6e34eSqz return (0);
9297c478bd9Sstevel@tonic-gate }
9307c478bd9Sstevel@tonic-gate
931*c0423dd8SToomas Soome static char *usage1 =
932*c0423dd8SToomas Soome "kbd [-r] [-t] [-l] [-a enable|disable|alternate] [-c on|off]\n"
933*c0423dd8SToomas Soome "\t [-d keyboard device] [-A count] [-D delay] [-R rate]";
934*c0423dd8SToomas Soome static char *usage2 = "kbd -i [-d keyboard device]";
935*c0423dd8SToomas Soome static char *usage3 = "kbd -s [language]";
936*c0423dd8SToomas Soome static char *usage4 = "kbd -b [keyboard|console] frequency";
9377c478bd9Sstevel@tonic-gate
9387c478bd9Sstevel@tonic-gate static void
usage(void)9397c478bd9Sstevel@tonic-gate usage(void)
9407c478bd9Sstevel@tonic-gate {
941*c0423dd8SToomas Soome (void) fprintf(stderr, "Usage:\t%s\n\t%s\n\t%s\n\t%s\n", usage1,
942*c0423dd8SToomas Soome usage2, usage3, usage4);
9437c478bd9Sstevel@tonic-gate }
944