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 */ 217c478bd9Sstevel@tonic-gate /* 22d8c870b0Sqz150045 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 308ffc942dSrz201010 * Usage: kbd [-r] [-t] [-l] [-c on|off] [-a enable|disable|alternate] 318ffc942dSrz201010 * [-d keyboard device] [-D autorepeat dealy] [-R autorepeat 328ffc942dSrz201010 * rate] 338ffc942dSrz201010 * kbd [-i] [-d keyboard device] 348ffc942dSrz201010 * kbd -s [language] 358ffc942dSrz201010 * kbd -b [keyboard|console] frequency 367c478bd9Sstevel@tonic-gate * -r reset the keyboard as if power-up 377c478bd9Sstevel@tonic-gate * -t return the type of the keyboard being used 387c478bd9Sstevel@tonic-gate * -l return the layout of the keyboard being used, 397c478bd9Sstevel@tonic-gate * and the Autorepeat settings 407c478bd9Sstevel@tonic-gate * -i read in the default configuration file 417c478bd9Sstevel@tonic-gate * -c on|off turn on|off clicking 427c478bd9Sstevel@tonic-gate * -a enable|disable|alternate sets abort sequence 437c478bd9Sstevel@tonic-gate * -D autorepeat delay sets autorepeat dealy, unit in ms 447c478bd9Sstevel@tonic-gate * -R autorepeat rate sets autorepeat rate, unit in ms 457c478bd9Sstevel@tonic-gate * -d keyboard device chooses the kbd device, default /dev/kbd. 467db6e34eSqz150045 * -s keyboard layout sets keyboard layout 478ffc942dSrz201010 * -b [keyboard| console] frequency 488ffc942dSrz201010 * sets keyboard or console beeper frequency 497c478bd9Sstevel@tonic-gate */ 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate #include <sys/types.h> 527c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 537c478bd9Sstevel@tonic-gate #include <sys/kbio.h> 547c478bd9Sstevel@tonic-gate #include <sys/kbd.h> 557c478bd9Sstevel@tonic-gate #include <stdio.h> 567c478bd9Sstevel@tonic-gate #include <fcntl.h> 577c478bd9Sstevel@tonic-gate #include <deflt.h> 587c478bd9Sstevel@tonic-gate #include <unistd.h> 597c478bd9Sstevel@tonic-gate #include <string.h> 607c478bd9Sstevel@tonic-gate #include <stdlib.h> 617c478bd9Sstevel@tonic-gate #include <stropts.h> 62d8c870b0Sqz150045 #include <libintl.h> 63d8c870b0Sqz150045 #include <locale.h> 648ffc942dSrz201010 #include <errno.h> 658ffc942dSrz201010 #include <inttypes.h> 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate #define KBD_DEVICE "/dev/kbd" /* default keyboard device */ 687c478bd9Sstevel@tonic-gate #define DEF_FILE "/etc/default/kbd" /* kbd defaults file */ 697c478bd9Sstevel@tonic-gate #define DEF_ABORT "KEYBOARD_ABORT=" 707c478bd9Sstevel@tonic-gate #define DEF_CLICK "KEYCLICK=" 717c478bd9Sstevel@tonic-gate #define DEF_RPTDELAY "REPEAT_DELAY=" 727c478bd9Sstevel@tonic-gate #define DEF_RPTRATE "REPEAT_RATE=" 737db6e34eSqz150045 #define DEF_LAYOUT "LAYOUT=" 748ffc942dSrz201010 #define DEF_KBDFREQ "KBD_BEEPER_FREQ=" 758ffc942dSrz201010 #define DEF_CONSFREQ "CONSOLE_BEEPER_FREQ=" 767db6e34eSqz150045 777db6e34eSqz150045 #define KBD_LAYOUT_FILE "/usr/share/lib/keytables/type_6/kbd_layouts" 787db6e34eSqz150045 #define MAX_LAYOUT_NUM 128 797db6e34eSqz150045 #define MAX_LINE_SIZE 256 807db6e34eSqz150045 #define DEFAULT_KBD_LAYOUT 33 817db6e34eSqz150045 827db6e34eSqz150045 char *layout_names[MAX_LAYOUT_NUM]; 837db6e34eSqz150045 int layout_numbers[MAX_LAYOUT_NUM]; 847db6e34eSqz150045 static int layout_count; 857db6e34eSqz150045 static int default_layout_number = 0; 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate static void reset(int); 88*3c333a60Svn210641 static int get_type(int); 897c478bd9Sstevel@tonic-gate static void get_layout(int); 907c478bd9Sstevel@tonic-gate static void kbd_defaults(int); 917c478bd9Sstevel@tonic-gate static void usage(void); 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate static int click(char *, int); 947c478bd9Sstevel@tonic-gate static int abort_enable(char *, int); 957c478bd9Sstevel@tonic-gate static int set_repeat_delay(char *, int); 967c478bd9Sstevel@tonic-gate static int set_repeat_rate(char *, int); 977c478bd9Sstevel@tonic-gate 987db6e34eSqz150045 static int get_layout_number(char *); 997db6e34eSqz150045 static int set_layout(int, int); 1007db6e34eSqz150045 static int get_layouts(void); 1017db6e34eSqz150045 static int set_kbd_layout(int, char *); 1028ffc942dSrz201010 static int set_beep_freq(int, char *, int); 1037db6e34eSqz150045 1047c478bd9Sstevel@tonic-gate int 1057c478bd9Sstevel@tonic-gate main(int argc, char **argv) 1067c478bd9Sstevel@tonic-gate { 1077c478bd9Sstevel@tonic-gate int c, error; 1087c478bd9Sstevel@tonic-gate int rflag, tflag, lflag, cflag, dflag, aflag, iflag, errflag, 1098ffc942dSrz201010 Dflag, Rflag, rtlacDRflag, sflag, bflag; 1108ffc942dSrz201010 char *copt, *aopt, *delay, *rate, *layout_name, *b_type, *freq_str; 1118ffc942dSrz201010 char *kbdname = KBD_DEVICE, *endptr = NULL; 1128ffc942dSrz201010 int kbd, freq_val; 1137c478bd9Sstevel@tonic-gate extern char *optarg; 1147c478bd9Sstevel@tonic-gate extern int optind; 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate rflag = tflag = cflag = dflag = aflag = iflag = errflag = lflag = 1178ffc942dSrz201010 Dflag = Rflag = sflag = bflag = 0; 1187c478bd9Sstevel@tonic-gate copt = aopt = (char *)0; 1197c478bd9Sstevel@tonic-gate 120d8c870b0Sqz150045 (void) setlocale(LC_ALL, ""); 121d8c870b0Sqz150045 #if !defined(TEXT_DOMAIN) 122d8c870b0Sqz150045 #define TEXT_DOMAIN "SYS_TEST" 123d8c870b0Sqz150045 #endif 124d8c870b0Sqz150045 (void) textdomain(TEXT_DOMAIN); 125d8c870b0Sqz150045 1268ffc942dSrz201010 while ((c = getopt(argc, argv, "rtlisc:a:d:D:R:b:")) != EOF) { 1277c478bd9Sstevel@tonic-gate switch (c) { 1287c478bd9Sstevel@tonic-gate case 'r': 1297c478bd9Sstevel@tonic-gate rflag++; 1307c478bd9Sstevel@tonic-gate break; 1317c478bd9Sstevel@tonic-gate case 't': 1327c478bd9Sstevel@tonic-gate tflag++; 1337c478bd9Sstevel@tonic-gate break; 1347c478bd9Sstevel@tonic-gate case 'l': 1357c478bd9Sstevel@tonic-gate lflag++; 1367c478bd9Sstevel@tonic-gate break; 1377c478bd9Sstevel@tonic-gate case 'i': 1387c478bd9Sstevel@tonic-gate iflag++; 1397c478bd9Sstevel@tonic-gate break; 1407db6e34eSqz150045 case 's': 1417db6e34eSqz150045 sflag++; 1427db6e34eSqz150045 break; 1437c478bd9Sstevel@tonic-gate case 'c': 1447c478bd9Sstevel@tonic-gate copt = optarg; 1457c478bd9Sstevel@tonic-gate cflag++; 1467c478bd9Sstevel@tonic-gate break; 1477c478bd9Sstevel@tonic-gate case 'a': 1487c478bd9Sstevel@tonic-gate aopt = optarg; 1497c478bd9Sstevel@tonic-gate aflag++; 1507c478bd9Sstevel@tonic-gate break; 1517c478bd9Sstevel@tonic-gate case 'd': 1527c478bd9Sstevel@tonic-gate kbdname = optarg; 1537c478bd9Sstevel@tonic-gate dflag++; 1547c478bd9Sstevel@tonic-gate break; 1557c478bd9Sstevel@tonic-gate case 'D': 1567c478bd9Sstevel@tonic-gate delay = optarg; 1577c478bd9Sstevel@tonic-gate Dflag++; 1587c478bd9Sstevel@tonic-gate break; 1597c478bd9Sstevel@tonic-gate case 'R': 1607c478bd9Sstevel@tonic-gate rate = optarg; 1617c478bd9Sstevel@tonic-gate Rflag++; 1627c478bd9Sstevel@tonic-gate break; 1638ffc942dSrz201010 case 'b': 1648ffc942dSrz201010 bflag++; 1658ffc942dSrz201010 break; 1667c478bd9Sstevel@tonic-gate case '?': 1677c478bd9Sstevel@tonic-gate errflag++; 1687c478bd9Sstevel@tonic-gate break; 1697c478bd9Sstevel@tonic-gate } 1707c478bd9Sstevel@tonic-gate } 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate /* 1737c478bd9Sstevel@tonic-gate * Check for valid arguments: 1747c478bd9Sstevel@tonic-gate * 1757c478bd9Sstevel@tonic-gate * If argument parsing failed or if there are left-over 1768ffc942dSrz201010 * command line arguments(except -s and -b option), 1778ffc942dSrz201010 * then we're done now. 1787c478bd9Sstevel@tonic-gate */ 1798ffc942dSrz201010 if (errflag != 0 || (sflag == 0 && bflag == 0 && argc != optind)) { 1807c478bd9Sstevel@tonic-gate usage(); 1817c478bd9Sstevel@tonic-gate exit(1); 1827c478bd9Sstevel@tonic-gate } 1837db6e34eSqz150045 1847c478bd9Sstevel@tonic-gate /* 1858ffc942dSrz201010 * kbd requires that the user specify either "-i" or "-s" or "-b" or 1868ffc942dSrz201010 * at least one of -[rtlacDR]. The "-d" option is, well, optional. 1877db6e34eSqz150045 * We don't care if it's there or not. 1887c478bd9Sstevel@tonic-gate */ 1897c478bd9Sstevel@tonic-gate rtlacDRflag = rflag + tflag + lflag + aflag + cflag + Dflag + Rflag; 1908ffc942dSrz201010 if (!((iflag != 0 && sflag == 0 && bflag == 0 && rtlacDRflag == 0) || 1918ffc942dSrz201010 (iflag == 0 && sflag != 0 && bflag == 0 && dflag == 0 && 1928ffc942dSrz201010 rtlacDRflag == 0) || 1938ffc942dSrz201010 (iflag == 0 && sflag == 0 && bflag == 0 && rtlacDRflag != 0) || 1948ffc942dSrz201010 (iflag == 0 && sflag == 0 && bflag != 0 && rtlacDRflag == 0))) { 1957c478bd9Sstevel@tonic-gate usage(); 1967c478bd9Sstevel@tonic-gate exit(1); 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate if (Dflag && atoi(delay) <= 0) { 2007c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid arguments: -D %s\n", delay); 2017c478bd9Sstevel@tonic-gate usage(); 2027c478bd9Sstevel@tonic-gate exit(1); 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate if (Rflag && atoi(rate) <= 0) { 2067c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid arguments: -R %s\n", rate); 2077c478bd9Sstevel@tonic-gate usage(); 2087c478bd9Sstevel@tonic-gate exit(1); 2097c478bd9Sstevel@tonic-gate } 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate /* 2127c478bd9Sstevel@tonic-gate * Open the keyboard device 2137c478bd9Sstevel@tonic-gate */ 2147c478bd9Sstevel@tonic-gate if ((kbd = open(kbdname, O_RDWR)) < 0) { 2157c478bd9Sstevel@tonic-gate perror("opening the keyboard"); 2167c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "kbd: Cannot open %s\n", kbdname); 2177c478bd9Sstevel@tonic-gate exit(1); 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate if (iflag) { 2217c478bd9Sstevel@tonic-gate kbd_defaults(kbd); 2227c478bd9Sstevel@tonic-gate exit(0); /* A mutually exclusive option */ 2237c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate if (tflag) 227*3c333a60Svn210641 (void) get_type(kbd); 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate if (lflag) 2307c478bd9Sstevel@tonic-gate get_layout(kbd); 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate if (cflag && (error = click(copt, kbd)) != 0) 2337c478bd9Sstevel@tonic-gate exit(error); 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate if (rflag) 2367c478bd9Sstevel@tonic-gate reset(kbd); 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate if (aflag && (error = abort_enable(aopt, kbd)) != 0) 2397c478bd9Sstevel@tonic-gate exit(error); 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate if (Dflag && (error = set_repeat_delay(delay, kbd)) != 0) 2427c478bd9Sstevel@tonic-gate exit(error); 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate if (Rflag && (error = set_repeat_rate(rate, kbd)) != 0) 2457c478bd9Sstevel@tonic-gate exit(error); 2467c478bd9Sstevel@tonic-gate 2477db6e34eSqz150045 if (sflag) { 2487db6e34eSqz150045 if (argc == optind) { 2497db6e34eSqz150045 layout_name = NULL; 2507db6e34eSqz150045 } else if (argc == (optind + 1)) { 2517db6e34eSqz150045 layout_name = argv[optind]; 2527db6e34eSqz150045 } else { 2537db6e34eSqz150045 usage(); 2547db6e34eSqz150045 exit(1); 2557db6e34eSqz150045 } 2567db6e34eSqz150045 2577db6e34eSqz150045 if ((error = set_kbd_layout(kbd, layout_name)) != 0) 2587db6e34eSqz150045 exit(error); 2597db6e34eSqz150045 } 2607db6e34eSqz150045 2618ffc942dSrz201010 if (bflag) { 2628ffc942dSrz201010 if (argc == optind) { 2638ffc942dSrz201010 b_type = "keyboard"; 2648ffc942dSrz201010 } else if (argc == (optind + 1)) { 2658ffc942dSrz201010 b_type = argv[argc - 2]; 2668ffc942dSrz201010 } else { 2678ffc942dSrz201010 usage(); 2688ffc942dSrz201010 exit(1); 2698ffc942dSrz201010 } 2708ffc942dSrz201010 2718ffc942dSrz201010 if (strcmp(b_type, "keyboard") && strcmp(b_type, "console")) { 2728ffc942dSrz201010 usage(); 2738ffc942dSrz201010 exit(1); 2748ffc942dSrz201010 } 2758ffc942dSrz201010 2768ffc942dSrz201010 freq_str = argv[argc - 1]; 2778ffc942dSrz201010 errno = 0; 2788ffc942dSrz201010 freq_val = (int)strtol(freq_str, &endptr, 10); 2798ffc942dSrz201010 if (errno != 0 || endptr[0] != '\0') { 2808ffc942dSrz201010 usage(); 2818ffc942dSrz201010 exit(1); 2828ffc942dSrz201010 } 2838ffc942dSrz201010 2848ffc942dSrz201010 if (freq_val < 0 || freq_val > INT16_MAX) { 2858ffc942dSrz201010 (void) fprintf(stderr, "Invalid arguments: -b %s\n", 2868ffc942dSrz201010 freq_str); 2878ffc942dSrz201010 (void) fprintf(stderr, "Frequency range: [0 - %d]\n", 2888ffc942dSrz201010 INT16_MAX); 2898ffc942dSrz201010 exit(1); 2908ffc942dSrz201010 } 2918ffc942dSrz201010 2928ffc942dSrz201010 if ((error = set_beep_freq(kbd, b_type, freq_val)) != 0) 2938ffc942dSrz201010 exit(1); 2948ffc942dSrz201010 } 2958ffc942dSrz201010 2967db6e34eSqz150045 return (0); 2977db6e34eSqz150045 } 2987db6e34eSqz150045 2997db6e34eSqz150045 /* 3007db6e34eSqz150045 * this routine gets the type of the keyboard being used 3017db6e34eSqz150045 */ 3027db6e34eSqz150045 static int 3037db6e34eSqz150045 set_kbd_layout(int kbd, char *layout_name) 3047db6e34eSqz150045 { 3057db6e34eSqz150045 int layout_num; 3067db6e34eSqz150045 int error = 1; 3077db6e34eSqz150045 308*3c333a60Svn210641 /* layout setting is possible only for USB type keyboards */ 309*3c333a60Svn210641 if (get_type(kbd) != KB_USB) { 310*3c333a60Svn210641 (void) fprintf(stderr, "The -s option does not apply for this" 311*3c333a60Svn210641 " keyboard type.\n" 312*3c333a60Svn210641 "Only USB/PS2 type keyboards support this option.\n"); 313*3c333a60Svn210641 return (error); 314*3c333a60Svn210641 } 315*3c333a60Svn210641 3167db6e34eSqz150045 /* get the language info from the layouts file */ 3177db6e34eSqz150045 if (get_layouts() != 0) 3187db6e34eSqz150045 return (error); 3197db6e34eSqz150045 3207db6e34eSqz150045 if (layout_name != NULL) { 3217db6e34eSqz150045 if ((layout_num = get_layout_number(layout_name)) == -1) { 3227db6e34eSqz150045 (void) fprintf(stderr, "%s: unknown layout name\n" 3237db6e34eSqz150045 "Please refer to 'kbd -s' to get the " 3247db6e34eSqz150045 "supported layouts.\n", layout_name); 3257db6e34eSqz150045 return (error); 3267db6e34eSqz150045 } 3277db6e34eSqz150045 } else { 3287db6e34eSqz150045 int i, j, print_cnt, input_num; 3297db6e34eSqz150045 boolean_t input_right = B_TRUE; 3307db6e34eSqz150045 boolean_t default_input = B_FALSE; 3317db6e34eSqz150045 char input[8]; /* 8 chars is enough for numbers */ 3327db6e34eSqz150045 3337db6e34eSqz150045 print_cnt = (layout_count % 2) ? 3347db6e34eSqz150045 layout_count/2+1 : layout_count/2; 3357db6e34eSqz150045 3367db6e34eSqz150045 for (i = 1; i <= print_cnt; i++) { 3377db6e34eSqz150045 (void) printf("%2d. %-30s", i, 3387db6e34eSqz150045 layout_names[i-1]); 3397db6e34eSqz150045 j = i + print_cnt; 3407db6e34eSqz150045 if (j <= layout_count) { 3417db6e34eSqz150045 (void) printf("%-2d. %-30s\n", j, 3427db6e34eSqz150045 layout_names[j-1]); 3437db6e34eSqz150045 } 3447db6e34eSqz150045 } 345d8c870b0Sqz150045 (void) printf(gettext("\nTo select the keyboard layout," 346d8c870b0Sqz150045 " enter a number [default %d]:"), 3477db6e34eSqz150045 default_layout_number+1); 3487db6e34eSqz150045 3497db6e34eSqz150045 for (;;) { 3507db6e34eSqz150045 if (input_right == B_FALSE) 351d8c870b0Sqz150045 (void) printf(gettext("Invalid input. " 352d8c870b0Sqz150045 "Please input a number " 353d8c870b0Sqz150045 "(1,2,...):")); 3547db6e34eSqz150045 (void) memset(input, 0, 8); 3557db6e34eSqz150045 (void) fflush(stdin); 3567db6e34eSqz150045 (void) fgets(input, 8, stdin); 3577db6e34eSqz150045 if (strlen(input) > 4) { 3587db6e34eSqz150045 input_right = B_FALSE; 3597db6e34eSqz150045 continue; 3607db6e34eSqz150045 } 3617db6e34eSqz150045 if (input[0] == '\n') { 3627db6e34eSqz150045 default_input = B_TRUE; 3637db6e34eSqz150045 break; 3647db6e34eSqz150045 } 3657db6e34eSqz150045 input_right = B_TRUE; 3667db6e34eSqz150045 /* check if the inputs are numbers 0~9 */ 3677db6e34eSqz150045 for (i = 0; i < (strlen(input) - 1); i++) { 3687db6e34eSqz150045 if ((input[i] < '0') || 3697db6e34eSqz150045 (input[i] > '9')) { 3707db6e34eSqz150045 input_right = B_FALSE; 3717db6e34eSqz150045 break; 3727db6e34eSqz150045 } 3737db6e34eSqz150045 } 3747db6e34eSqz150045 if (input_right == B_FALSE) 3757db6e34eSqz150045 continue; 3767db6e34eSqz150045 input_num = atoi(input); 3777db6e34eSqz150045 if ((input_num > 0) && 3787db6e34eSqz150045 (input_num <= layout_count)) 3797db6e34eSqz150045 break; 3807db6e34eSqz150045 else 3817db6e34eSqz150045 input_right = B_FALSE; 3827db6e34eSqz150045 } 3837db6e34eSqz150045 if (default_input == B_TRUE) 3847db6e34eSqz150045 layout_num = DEFAULT_KBD_LAYOUT; 3857db6e34eSqz150045 else 3867db6e34eSqz150045 layout_num = layout_numbers[--input_num]; 3877db6e34eSqz150045 } 3887db6e34eSqz150045 3897db6e34eSqz150045 if ((error = set_layout(kbd, layout_num)) != 0) 3907db6e34eSqz150045 return (error); 3917db6e34eSqz150045 3927c478bd9Sstevel@tonic-gate return (0); 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate /* 3968ffc942dSrz201010 * This routine sets keyboard or console beeper frequency 3978ffc942dSrz201010 */ 3988ffc942dSrz201010 static int 3998ffc942dSrz201010 set_beep_freq(int fd, char *type, int freq) 4008ffc942dSrz201010 { 4018ffc942dSrz201010 struct freq_request fr_struct; 4028ffc942dSrz201010 4038ffc942dSrz201010 if (strcmp(type, "keyboard") == 0) 4048ffc942dSrz201010 fr_struct.type = KBD_BEEP; 4058ffc942dSrz201010 else if (strcmp(type, "console") == 0) 4068ffc942dSrz201010 fr_struct.type = CONSOLE_BEEP; 4078ffc942dSrz201010 else 4088ffc942dSrz201010 return (EINVAL); 4098ffc942dSrz201010 4108ffc942dSrz201010 fr_struct.freq = (int16_t)freq; 4118ffc942dSrz201010 4128ffc942dSrz201010 return (ioctl(fd, KIOCSETFREQ, &fr_struct)); 4138ffc942dSrz201010 } 4148ffc942dSrz201010 4158ffc942dSrz201010 /* 4167c478bd9Sstevel@tonic-gate * this routine resets the state of the keyboard as if power-up 4177c478bd9Sstevel@tonic-gate */ 4187c478bd9Sstevel@tonic-gate static void 4197c478bd9Sstevel@tonic-gate reset(int kbd) 4207c478bd9Sstevel@tonic-gate { 4217c478bd9Sstevel@tonic-gate int cmd; 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate cmd = KBD_CMD_RESET; 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCCMD, &cmd)) { 4267c478bd9Sstevel@tonic-gate perror("kbd: ioctl error"); 4277c478bd9Sstevel@tonic-gate exit(1); 4287c478bd9Sstevel@tonic-gate } 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate /* 4337c478bd9Sstevel@tonic-gate * this routine gets the type of the keyboard being used 4347c478bd9Sstevel@tonic-gate */ 435*3c333a60Svn210641 static int 4367c478bd9Sstevel@tonic-gate get_type(int kbd) 4377c478bd9Sstevel@tonic-gate { 4387c478bd9Sstevel@tonic-gate int kbd_type; 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCTYPE, &kbd_type)) { 4417c478bd9Sstevel@tonic-gate perror("ioctl (kbd type)"); 4427c478bd9Sstevel@tonic-gate exit(1); 4437c478bd9Sstevel@tonic-gate } 4447c478bd9Sstevel@tonic-gate 4457c478bd9Sstevel@tonic-gate switch (kbd_type) { 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate case KB_SUN3: 4487c478bd9Sstevel@tonic-gate (void) printf("Type 3 Sun keyboard\n"); 4497c478bd9Sstevel@tonic-gate break; 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate case KB_SUN4: 4527c478bd9Sstevel@tonic-gate (void) printf("Type 4 Sun keyboard\n"); 4537c478bd9Sstevel@tonic-gate break; 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate case KB_ASCII: 4567c478bd9Sstevel@tonic-gate (void) printf("ASCII\n"); 4577c478bd9Sstevel@tonic-gate break; 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate case KB_PC: 4607c478bd9Sstevel@tonic-gate (void) printf("PC\n"); 4617c478bd9Sstevel@tonic-gate break; 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate case KB_USB: 4647c478bd9Sstevel@tonic-gate (void) printf("USB keyboard\n"); 4657c478bd9Sstevel@tonic-gate break; 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate default: 4687c478bd9Sstevel@tonic-gate (void) printf("Unknown keyboard type\n"); 4697c478bd9Sstevel@tonic-gate break; 4707c478bd9Sstevel@tonic-gate } 471*3c333a60Svn210641 return (kbd_type); 4727c478bd9Sstevel@tonic-gate } 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate /* 4757c478bd9Sstevel@tonic-gate * this routine gets the layout of the keyboard being used 4767c478bd9Sstevel@tonic-gate * also, included the autorepeat delay and rate being used 4777c478bd9Sstevel@tonic-gate */ 4787c478bd9Sstevel@tonic-gate static void 4797c478bd9Sstevel@tonic-gate get_layout(int kbd) 4807c478bd9Sstevel@tonic-gate { 4817c478bd9Sstevel@tonic-gate int kbd_type; 4827c478bd9Sstevel@tonic-gate int kbd_layout; 4837c478bd9Sstevel@tonic-gate /* these two variables are used for getting delay&rate */ 4847c478bd9Sstevel@tonic-gate int delay, rate; 4857c478bd9Sstevel@tonic-gate delay = rate = 0; 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCTYPE, &kbd_type)) { 4887c478bd9Sstevel@tonic-gate perror("ioctl (kbd type)"); 4897c478bd9Sstevel@tonic-gate exit(1); 4907c478bd9Sstevel@tonic-gate } 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCLAYOUT, &kbd_layout)) { 4937c478bd9Sstevel@tonic-gate perror("ioctl (kbd layout)"); 4947c478bd9Sstevel@tonic-gate exit(1); 4957c478bd9Sstevel@tonic-gate } 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate (void) printf("type=%d\nlayout=%d (0x%.2x)\n", 4987c478bd9Sstevel@tonic-gate kbd_type, kbd_layout, kbd_layout); 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate /* below code is used to get the autorepeat delay and rate */ 5017c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCGRPTDELAY, &delay)) { 5027c478bd9Sstevel@tonic-gate perror("ioctl (kbd get repeat delay)"); 5037c478bd9Sstevel@tonic-gate exit(1); 5047c478bd9Sstevel@tonic-gate } 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCGRPTRATE, &rate)) { 5077c478bd9Sstevel@tonic-gate perror("ioctl (kbd get repeat rate)"); 5087c478bd9Sstevel@tonic-gate exit(1); 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate (void) printf("delay(ms)=%d\n", delay); 5127c478bd9Sstevel@tonic-gate (void) printf("rate(ms)=%d\n", rate); 5137c478bd9Sstevel@tonic-gate } 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate /* 5167c478bd9Sstevel@tonic-gate * this routine enables or disables clicking of the keyboard 5177c478bd9Sstevel@tonic-gate */ 5187c478bd9Sstevel@tonic-gate static int 5197c478bd9Sstevel@tonic-gate click(char *copt, int kbd) 5207c478bd9Sstevel@tonic-gate { 5217c478bd9Sstevel@tonic-gate int cmd; 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate if (strcmp(copt, "on") == 0) 5247c478bd9Sstevel@tonic-gate cmd = KBD_CMD_CLICK; 5257c478bd9Sstevel@tonic-gate else if (strcmp(copt, "off") == 0) 5267c478bd9Sstevel@tonic-gate cmd = KBD_CMD_NOCLICK; 5277c478bd9Sstevel@tonic-gate else { 5287c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "wrong option -- %s\n", copt); 5297c478bd9Sstevel@tonic-gate usage(); 5307c478bd9Sstevel@tonic-gate return (1); 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCCMD, &cmd)) { 5347c478bd9Sstevel@tonic-gate perror("kbd ioctl (keyclick)"); 5357c478bd9Sstevel@tonic-gate return (1); 5367c478bd9Sstevel@tonic-gate } 5377c478bd9Sstevel@tonic-gate return (0); 5387c478bd9Sstevel@tonic-gate } 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate /* 5417c478bd9Sstevel@tonic-gate * this routine enables/disables/sets BRK or abort sequence feature 5427c478bd9Sstevel@tonic-gate */ 5437c478bd9Sstevel@tonic-gate static int 5447c478bd9Sstevel@tonic-gate abort_enable(char *aopt, int kbd) 5457c478bd9Sstevel@tonic-gate { 5467c478bd9Sstevel@tonic-gate int enable; 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate if (strcmp(aopt, "alternate") == 0) 5497c478bd9Sstevel@tonic-gate enable = KIOCABORTALTERNATE; 5507c478bd9Sstevel@tonic-gate else if (strcmp(aopt, "enable") == 0) 5517c478bd9Sstevel@tonic-gate enable = KIOCABORTENABLE; 5527c478bd9Sstevel@tonic-gate else if (strcmp(aopt, "disable") == 0) 5537c478bd9Sstevel@tonic-gate enable = KIOCABORTDISABLE; 5547c478bd9Sstevel@tonic-gate else { 5557c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "wrong option -- %s\n", aopt); 5567c478bd9Sstevel@tonic-gate usage(); 5577c478bd9Sstevel@tonic-gate return (1); 5587c478bd9Sstevel@tonic-gate } 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSKABORTEN, &enable)) { 5617c478bd9Sstevel@tonic-gate perror("kbd ioctl (abort enable)"); 5627c478bd9Sstevel@tonic-gate return (1); 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate return (0); 5657c478bd9Sstevel@tonic-gate } 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate /* 5687c478bd9Sstevel@tonic-gate * this routine set autorepeat delay 5697c478bd9Sstevel@tonic-gate */ 5707c478bd9Sstevel@tonic-gate static int 5717c478bd9Sstevel@tonic-gate set_repeat_delay(char *delay_str, int kbd) 5727c478bd9Sstevel@tonic-gate { 5737c478bd9Sstevel@tonic-gate int delay = atoi(delay_str); 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate /* 5767c478bd9Sstevel@tonic-gate * The error message depends on the different inputs. 5777c478bd9Sstevel@tonic-gate * a. the input is a invalid integer(unit in ms) 5787c478bd9Sstevel@tonic-gate * b. the input is a integer less than the minimal delay setting. 5794470e687Syx209491 * The condition (a) has been covered by main function and kbd_defaults 5807c478bd9Sstevel@tonic-gate * function. 5817c478bd9Sstevel@tonic-gate */ 5827c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSRPTDELAY, &delay) == -1) { 5837c478bd9Sstevel@tonic-gate if (delay < KIOCRPTDELAY_MIN) 5847c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "kbd: specified delay %d is " 5857c478bd9Sstevel@tonic-gate "less than minimum %d\n", delay, KIOCRPTDELAY_MIN); 5867c478bd9Sstevel@tonic-gate else 5877c478bd9Sstevel@tonic-gate perror("kbd: set repeat delay"); 5887c478bd9Sstevel@tonic-gate return (1); 5897c478bd9Sstevel@tonic-gate } 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate return (0); 5927c478bd9Sstevel@tonic-gate } 5937c478bd9Sstevel@tonic-gate 5947c478bd9Sstevel@tonic-gate /* 5957c478bd9Sstevel@tonic-gate * this routine set autorepeat rate 5967c478bd9Sstevel@tonic-gate */ 5977c478bd9Sstevel@tonic-gate static int 5987c478bd9Sstevel@tonic-gate set_repeat_rate(char *rate_str, int kbd) 5997c478bd9Sstevel@tonic-gate { 6007c478bd9Sstevel@tonic-gate int rate = atoi(rate_str); 6017c478bd9Sstevel@tonic-gate 6027c478bd9Sstevel@tonic-gate /* 6034470e687Syx209491 * The input validation check has been covered by main function 6044470e687Syx209491 * and kbd_defaults function.Here just give an error message if 6054470e687Syx209491 * the ioctl fails. 6067c478bd9Sstevel@tonic-gate */ 6077c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSRPTRATE, &rate) == -1) { 6087c478bd9Sstevel@tonic-gate perror("kbd: set repeat rate"); 6097c478bd9Sstevel@tonic-gate return (1); 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate return (0); 6127c478bd9Sstevel@tonic-gate } 6137c478bd9Sstevel@tonic-gate 6147c478bd9Sstevel@tonic-gate #define BAD_DEFAULT "kbd: bad default value for %s: %s\n" 6157c478bd9Sstevel@tonic-gate 6167c478bd9Sstevel@tonic-gate static void 6177c478bd9Sstevel@tonic-gate kbd_defaults(int kbd) 6187c478bd9Sstevel@tonic-gate { 6198ffc942dSrz201010 char *p, *endptr; 6208ffc942dSrz201010 int layout_num, freq; 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate if (defopen(DEF_FILE) != 0) { 6237c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Can't open default file: %s\n", 6247c478bd9Sstevel@tonic-gate DEF_FILE); 6257c478bd9Sstevel@tonic-gate exit(1); 6267c478bd9Sstevel@tonic-gate } 6277c478bd9Sstevel@tonic-gate 6287c478bd9Sstevel@tonic-gate p = defread(DEF_CLICK); 6297c478bd9Sstevel@tonic-gate if (p != NULL) { 6307c478bd9Sstevel@tonic-gate /* 6317c478bd9Sstevel@tonic-gate * KEYCLICK must equal "on" or "off" 6327c478bd9Sstevel@tonic-gate */ 6337c478bd9Sstevel@tonic-gate if ((strcmp(p, "on") == 0) || (strcmp(p, "off") == 0)) 6347c478bd9Sstevel@tonic-gate (void) click(p, kbd); 6357c478bd9Sstevel@tonic-gate else 6367c478bd9Sstevel@tonic-gate (void) fprintf(stderr, BAD_DEFAULT, DEF_CLICK, p); 6377c478bd9Sstevel@tonic-gate } 6387c478bd9Sstevel@tonic-gate 6397c478bd9Sstevel@tonic-gate p = defread(DEF_ABORT); 6407c478bd9Sstevel@tonic-gate if (p != NULL) { 6417c478bd9Sstevel@tonic-gate /* 6427c478bd9Sstevel@tonic-gate * ABORT must equal "enable", "disable" or "alternate" 6437c478bd9Sstevel@tonic-gate */ 6447c478bd9Sstevel@tonic-gate if ((strcmp(p, "enable") == 0) || 6457c478bd9Sstevel@tonic-gate (strcmp(p, "alternate") == 0) || 6467c478bd9Sstevel@tonic-gate (strcmp(p, "disable") == 0)) 6477c478bd9Sstevel@tonic-gate (void) abort_enable(p, kbd); 6487c478bd9Sstevel@tonic-gate else 6497c478bd9Sstevel@tonic-gate (void) fprintf(stderr, BAD_DEFAULT, DEF_ABORT, p); 6507c478bd9Sstevel@tonic-gate } 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate p = defread(DEF_RPTDELAY); 6537c478bd9Sstevel@tonic-gate if (p != NULL) { 6547c478bd9Sstevel@tonic-gate /* 6557c478bd9Sstevel@tonic-gate * REPEAT_DELAY unit in ms 6567c478bd9Sstevel@tonic-gate */ 6577c478bd9Sstevel@tonic-gate if (atoi(p) > 0) 6587c478bd9Sstevel@tonic-gate (void) set_repeat_delay(p, kbd); 6597c478bd9Sstevel@tonic-gate else 6607c478bd9Sstevel@tonic-gate (void) fprintf(stderr, BAD_DEFAULT, DEF_RPTDELAY, p); 6617c478bd9Sstevel@tonic-gate } 6627c478bd9Sstevel@tonic-gate 6637c478bd9Sstevel@tonic-gate p = defread(DEF_RPTRATE); 6647c478bd9Sstevel@tonic-gate if (p != NULL) { 6657c478bd9Sstevel@tonic-gate /* 6667c478bd9Sstevel@tonic-gate * REPEAT_RATE unit in ms 6677c478bd9Sstevel@tonic-gate */ 6687c478bd9Sstevel@tonic-gate if (atoi(p) > 0) 6697c478bd9Sstevel@tonic-gate (void) set_repeat_rate(p, kbd); 6707c478bd9Sstevel@tonic-gate else 6717c478bd9Sstevel@tonic-gate (void) fprintf(stderr, BAD_DEFAULT, DEF_RPTRATE, p); 6727c478bd9Sstevel@tonic-gate } 6737db6e34eSqz150045 6747db6e34eSqz150045 p = defread(DEF_LAYOUT); 6757db6e34eSqz150045 if (p != NULL) { 6767db6e34eSqz150045 /* 6777db6e34eSqz150045 * LAYOUT must be one of the layouts supported in kbd_layouts 6787db6e34eSqz150045 */ 6797db6e34eSqz150045 if (get_layouts() != 0) 6807db6e34eSqz150045 return; 6817db6e34eSqz150045 6827db6e34eSqz150045 if ((layout_num = get_layout_number(p)) == -1) { 6837db6e34eSqz150045 (void) fprintf(stderr, BAD_DEFAULT, DEF_LAYOUT, p); 6847db6e34eSqz150045 return; 6857db6e34eSqz150045 } 6867db6e34eSqz150045 6877db6e34eSqz150045 (void) set_layout(kbd, layout_num); 6887db6e34eSqz150045 } 6898ffc942dSrz201010 6908ffc942dSrz201010 p = defread(DEF_KBDFREQ); 6918ffc942dSrz201010 if (p != NULL) { 6928ffc942dSrz201010 /* 6938ffc942dSrz201010 * Keyboard beeper frequency unit in Hz 6948ffc942dSrz201010 */ 6958ffc942dSrz201010 endptr = NULL; 6968ffc942dSrz201010 errno = 0; 6978ffc942dSrz201010 freq = (int)strtol(p, &endptr, 10); 6988ffc942dSrz201010 if (errno == 0 && endptr[0] == '\0' && 6998ffc942dSrz201010 freq >= 0 && freq <= INT16_MAX) 7008ffc942dSrz201010 (void) set_beep_freq(kbd, "keyboard", freq); 7018ffc942dSrz201010 else 7028ffc942dSrz201010 (void) fprintf(stderr, BAD_DEFAULT, DEF_KBDFREQ, p); 7038ffc942dSrz201010 } 7048ffc942dSrz201010 7058ffc942dSrz201010 p = defread(DEF_CONSFREQ); 7068ffc942dSrz201010 if (p != NULL) { 7078ffc942dSrz201010 /* 7088ffc942dSrz201010 * Console beeper frequency unit in Hz 7098ffc942dSrz201010 */ 7108ffc942dSrz201010 endptr = NULL; 7118ffc942dSrz201010 errno = 0; 7128ffc942dSrz201010 freq = (int)strtol(p, &endptr, 10); 7138ffc942dSrz201010 if (errno == 0 && endptr[0] == '\0' && 7148ffc942dSrz201010 freq >= 0 && freq <= INT16_MAX) 7158ffc942dSrz201010 (void) set_beep_freq(kbd, "console", freq); 7168ffc942dSrz201010 else 7178ffc942dSrz201010 (void) fprintf(stderr, BAD_DEFAULT, DEF_CONSFREQ, p); 7188ffc942dSrz201010 } 7197db6e34eSqz150045 } 7207db6e34eSqz150045 7217db6e34eSqz150045 static int 7227db6e34eSqz150045 get_layout_number(char *layout) 7237db6e34eSqz150045 { 7247db6e34eSqz150045 int i; 7257db6e34eSqz150045 int layout_number = -1; 7267db6e34eSqz150045 7277db6e34eSqz150045 for (i = 0; i < layout_count; i ++) { 7287db6e34eSqz150045 if (strcmp(layout, layout_names[i]) == 0) { 7297db6e34eSqz150045 layout_number = layout_numbers[i]; 7307db6e34eSqz150045 break; 7317db6e34eSqz150045 } 7327db6e34eSqz150045 } 7337db6e34eSqz150045 7347db6e34eSqz150045 return (layout_number); 7357db6e34eSqz150045 } 7367db6e34eSqz150045 7377db6e34eSqz150045 static int 7387db6e34eSqz150045 get_layouts() 7397db6e34eSqz150045 { 7407db6e34eSqz150045 FILE *stream; 7417db6e34eSqz150045 char buffer[MAX_LINE_SIZE]; 7427db6e34eSqz150045 char *result = NULL; 7437db6e34eSqz150045 int i = 0; 7447db6e34eSqz150045 char *tmpbuf; 7457db6e34eSqz150045 7467db6e34eSqz150045 if ((stream = fopen(KBD_LAYOUT_FILE, "r")) == 0) { 7477db6e34eSqz150045 perror(KBD_LAYOUT_FILE); 7487db6e34eSqz150045 return (1); 7497db6e34eSqz150045 } 7507db6e34eSqz150045 7517db6e34eSqz150045 while ((fgets(buffer, MAX_LINE_SIZE, stream) != NULL) && 7527db6e34eSqz150045 (i < MAX_LAYOUT_NUM)) { 7537db6e34eSqz150045 if (buffer[0] == '#') 7547db6e34eSqz150045 continue; 7557db6e34eSqz150045 if ((result = strtok(buffer, "=")) == NULL) 7567db6e34eSqz150045 continue; 7577db6e34eSqz150045 if ((tmpbuf = strdup(result)) != NULL) { 7587db6e34eSqz150045 layout_names[i] = tmpbuf; 7597db6e34eSqz150045 } else { 7607db6e34eSqz150045 perror("out of memory getting layout names"); 7617db6e34eSqz150045 return (1); 7627db6e34eSqz150045 } 7637db6e34eSqz150045 if ((result = strtok(NULL, "\n")) == NULL) 7647db6e34eSqz150045 continue; 7657db6e34eSqz150045 layout_numbers[i] = atoi(result); 7667db6e34eSqz150045 if (strcmp(tmpbuf, "US-English") == 0) 7677db6e34eSqz150045 default_layout_number = i; 7687db6e34eSqz150045 i++; 7697db6e34eSqz150045 } 7707db6e34eSqz150045 layout_count = i; 7717db6e34eSqz150045 7727db6e34eSqz150045 return (0); 7737db6e34eSqz150045 } 7747db6e34eSqz150045 7757db6e34eSqz150045 /* 7767db6e34eSqz150045 * this routine sets the layout of the keyboard being used 7777db6e34eSqz150045 */ 7787db6e34eSqz150045 static int 7797db6e34eSqz150045 set_layout(int kbd, int layout_num) 7807db6e34eSqz150045 { 7817db6e34eSqz150045 7827db6e34eSqz150045 if (ioctl(kbd, KIOCSLAYOUT, layout_num)) { 7837db6e34eSqz150045 perror("ioctl (set kbd layout)"); 7847db6e34eSqz150045 return (1); 7857db6e34eSqz150045 } 7867db6e34eSqz150045 7877db6e34eSqz150045 return (0); 7887c478bd9Sstevel@tonic-gate } 7897c478bd9Sstevel@tonic-gate 7907c478bd9Sstevel@tonic-gate static char *usage1 = "kbd [-r] [-t] [-l] [-a enable|disable|alternate]"; 7917c478bd9Sstevel@tonic-gate static char *usage2 = " [-c on|off][-D delay][-R rate][-d keyboard device]"; 7927c478bd9Sstevel@tonic-gate static char *usage3 = "kbd -i [-d keyboard device]"; 7937db6e34eSqz150045 static char *usage4 = "kbd -s [language]"; 7948ffc942dSrz201010 static char *usage5 = "kbd -b [keyboard|console] frequency"; 7957c478bd9Sstevel@tonic-gate 7967c478bd9Sstevel@tonic-gate static void 7977c478bd9Sstevel@tonic-gate usage(void) 7987c478bd9Sstevel@tonic-gate { 7998ffc942dSrz201010 (void) fprintf(stderr, "Usage:\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n", usage1, 8008ffc942dSrz201010 usage2, usage3, usage4, usage5); 8017c478bd9Sstevel@tonic-gate } 802