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); 887c478bd9Sstevel@tonic-gate static void 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) 2277c478bd9Sstevel@tonic-gate 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 3087db6e34eSqz150045 /* get the language info from the layouts file */ 3097db6e34eSqz150045 if (get_layouts() != 0) 3107db6e34eSqz150045 return (error); 3117db6e34eSqz150045 3127db6e34eSqz150045 if (layout_name != NULL) { 3137db6e34eSqz150045 if ((layout_num = get_layout_number(layout_name)) == -1) { 3147db6e34eSqz150045 (void) fprintf(stderr, "%s: unknown layout name\n" 3157db6e34eSqz150045 "Please refer to 'kbd -s' to get the " 3167db6e34eSqz150045 "supported layouts.\n", layout_name); 3177db6e34eSqz150045 return (error); 3187db6e34eSqz150045 } 3197db6e34eSqz150045 } else { 3207db6e34eSqz150045 int i, j, print_cnt, input_num; 3217db6e34eSqz150045 boolean_t input_right = B_TRUE; 3227db6e34eSqz150045 boolean_t default_input = B_FALSE; 3237db6e34eSqz150045 char input[8]; /* 8 chars is enough for numbers */ 3247db6e34eSqz150045 3257db6e34eSqz150045 print_cnt = (layout_count % 2) ? 3267db6e34eSqz150045 layout_count/2+1 : layout_count/2; 3277db6e34eSqz150045 3287db6e34eSqz150045 for (i = 1; i <= print_cnt; i++) { 3297db6e34eSqz150045 (void) printf("%2d. %-30s", i, 3307db6e34eSqz150045 layout_names[i-1]); 3317db6e34eSqz150045 j = i + print_cnt; 3327db6e34eSqz150045 if (j <= layout_count) { 3337db6e34eSqz150045 (void) printf("%-2d. %-30s\n", j, 3347db6e34eSqz150045 layout_names[j-1]); 3357db6e34eSqz150045 } 3367db6e34eSqz150045 } 337d8c870b0Sqz150045 (void) printf(gettext("\nTo select the keyboard layout," 338d8c870b0Sqz150045 " enter a number [default %d]:"), 3397db6e34eSqz150045 default_layout_number+1); 3407db6e34eSqz150045 3417db6e34eSqz150045 for (;;) { 3427db6e34eSqz150045 if (input_right == B_FALSE) 343d8c870b0Sqz150045 (void) printf(gettext("Invalid input. " 344d8c870b0Sqz150045 "Please input a number " 345d8c870b0Sqz150045 "(1,2,...):")); 3467db6e34eSqz150045 (void) memset(input, 0, 8); 3477db6e34eSqz150045 (void) fflush(stdin); 3487db6e34eSqz150045 (void) fgets(input, 8, stdin); 3497db6e34eSqz150045 if (strlen(input) > 4) { 3507db6e34eSqz150045 input_right = B_FALSE; 3517db6e34eSqz150045 continue; 3527db6e34eSqz150045 } 3537db6e34eSqz150045 if (input[0] == '\n') { 3547db6e34eSqz150045 default_input = B_TRUE; 3557db6e34eSqz150045 break; 3567db6e34eSqz150045 } 3577db6e34eSqz150045 input_right = B_TRUE; 3587db6e34eSqz150045 /* check if the inputs are numbers 0~9 */ 3597db6e34eSqz150045 for (i = 0; i < (strlen(input) - 1); i++) { 3607db6e34eSqz150045 if ((input[i] < '0') || 3617db6e34eSqz150045 (input[i] > '9')) { 3627db6e34eSqz150045 input_right = B_FALSE; 3637db6e34eSqz150045 break; 3647db6e34eSqz150045 } 3657db6e34eSqz150045 } 3667db6e34eSqz150045 if (input_right == B_FALSE) 3677db6e34eSqz150045 continue; 3687db6e34eSqz150045 input_num = atoi(input); 3697db6e34eSqz150045 if ((input_num > 0) && 3707db6e34eSqz150045 (input_num <= layout_count)) 3717db6e34eSqz150045 break; 3727db6e34eSqz150045 else 3737db6e34eSqz150045 input_right = B_FALSE; 3747db6e34eSqz150045 } 3757db6e34eSqz150045 if (default_input == B_TRUE) 3767db6e34eSqz150045 layout_num = DEFAULT_KBD_LAYOUT; 3777db6e34eSqz150045 else 3787db6e34eSqz150045 layout_num = layout_numbers[--input_num]; 3797db6e34eSqz150045 } 3807db6e34eSqz150045 3817db6e34eSqz150045 if ((error = set_layout(kbd, layout_num)) != 0) 3827db6e34eSqz150045 return (error); 3837db6e34eSqz150045 3847c478bd9Sstevel@tonic-gate return (0); 3857c478bd9Sstevel@tonic-gate } 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate /* 3888ffc942dSrz201010 * This routine sets keyboard or console beeper frequency 3898ffc942dSrz201010 */ 3908ffc942dSrz201010 static int 3918ffc942dSrz201010 set_beep_freq(int fd, char *type, int freq) 3928ffc942dSrz201010 { 3938ffc942dSrz201010 struct freq_request fr_struct; 3948ffc942dSrz201010 3958ffc942dSrz201010 if (strcmp(type, "keyboard") == 0) 3968ffc942dSrz201010 fr_struct.type = KBD_BEEP; 3978ffc942dSrz201010 else if (strcmp(type, "console") == 0) 3988ffc942dSrz201010 fr_struct.type = CONSOLE_BEEP; 3998ffc942dSrz201010 else 4008ffc942dSrz201010 return (EINVAL); 4018ffc942dSrz201010 4028ffc942dSrz201010 fr_struct.freq = (int16_t)freq; 4038ffc942dSrz201010 4048ffc942dSrz201010 return (ioctl(fd, KIOCSETFREQ, &fr_struct)); 4058ffc942dSrz201010 } 4068ffc942dSrz201010 4078ffc942dSrz201010 /* 4087c478bd9Sstevel@tonic-gate * this routine resets the state of the keyboard as if power-up 4097c478bd9Sstevel@tonic-gate */ 4107c478bd9Sstevel@tonic-gate static void 4117c478bd9Sstevel@tonic-gate reset(int kbd) 4127c478bd9Sstevel@tonic-gate { 4137c478bd9Sstevel@tonic-gate int cmd; 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate cmd = KBD_CMD_RESET; 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCCMD, &cmd)) { 4187c478bd9Sstevel@tonic-gate perror("kbd: ioctl error"); 4197c478bd9Sstevel@tonic-gate exit(1); 4207c478bd9Sstevel@tonic-gate } 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate /* 4257c478bd9Sstevel@tonic-gate * this routine gets the type of the keyboard being used 4267c478bd9Sstevel@tonic-gate */ 4277c478bd9Sstevel@tonic-gate static void 4287c478bd9Sstevel@tonic-gate get_type(int kbd) 4297c478bd9Sstevel@tonic-gate { 4307c478bd9Sstevel@tonic-gate int kbd_type; 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCTYPE, &kbd_type)) { 4337c478bd9Sstevel@tonic-gate perror("ioctl (kbd type)"); 4347c478bd9Sstevel@tonic-gate exit(1); 4357c478bd9Sstevel@tonic-gate } 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate switch (kbd_type) { 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate case KB_SUN3: 4407c478bd9Sstevel@tonic-gate (void) printf("Type 3 Sun keyboard\n"); 4417c478bd9Sstevel@tonic-gate break; 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate case KB_SUN4: 4447c478bd9Sstevel@tonic-gate (void) printf("Type 4 Sun keyboard\n"); 4457c478bd9Sstevel@tonic-gate break; 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate case KB_ASCII: 4487c478bd9Sstevel@tonic-gate (void) printf("ASCII\n"); 4497c478bd9Sstevel@tonic-gate break; 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate case KB_PC: 4527c478bd9Sstevel@tonic-gate (void) printf("PC\n"); 4537c478bd9Sstevel@tonic-gate break; 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate case KB_USB: 4567c478bd9Sstevel@tonic-gate (void) printf("USB keyboard\n"); 4577c478bd9Sstevel@tonic-gate break; 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate default: 4607c478bd9Sstevel@tonic-gate (void) printf("Unknown keyboard type\n"); 4617c478bd9Sstevel@tonic-gate break; 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate /* 4667c478bd9Sstevel@tonic-gate * this routine gets the layout of the keyboard being used 4677c478bd9Sstevel@tonic-gate * also, included the autorepeat delay and rate being used 4687c478bd9Sstevel@tonic-gate */ 4697c478bd9Sstevel@tonic-gate static void 4707c478bd9Sstevel@tonic-gate get_layout(int kbd) 4717c478bd9Sstevel@tonic-gate { 4727c478bd9Sstevel@tonic-gate int kbd_type; 4737c478bd9Sstevel@tonic-gate int kbd_layout; 4747c478bd9Sstevel@tonic-gate /* these two variables are used for getting delay&rate */ 4757c478bd9Sstevel@tonic-gate int delay, rate; 4767c478bd9Sstevel@tonic-gate delay = rate = 0; 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCTYPE, &kbd_type)) { 4797c478bd9Sstevel@tonic-gate perror("ioctl (kbd type)"); 4807c478bd9Sstevel@tonic-gate exit(1); 4817c478bd9Sstevel@tonic-gate } 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCLAYOUT, &kbd_layout)) { 4847c478bd9Sstevel@tonic-gate perror("ioctl (kbd layout)"); 4857c478bd9Sstevel@tonic-gate exit(1); 4867c478bd9Sstevel@tonic-gate } 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate (void) printf("type=%d\nlayout=%d (0x%.2x)\n", 4897c478bd9Sstevel@tonic-gate kbd_type, kbd_layout, kbd_layout); 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate /* below code is used to get the autorepeat delay and rate */ 4927c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCGRPTDELAY, &delay)) { 4937c478bd9Sstevel@tonic-gate perror("ioctl (kbd get repeat delay)"); 4947c478bd9Sstevel@tonic-gate exit(1); 4957c478bd9Sstevel@tonic-gate } 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCGRPTRATE, &rate)) { 4987c478bd9Sstevel@tonic-gate perror("ioctl (kbd get repeat rate)"); 4997c478bd9Sstevel@tonic-gate exit(1); 5007c478bd9Sstevel@tonic-gate } 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate (void) printf("delay(ms)=%d\n", delay); 5037c478bd9Sstevel@tonic-gate (void) printf("rate(ms)=%d\n", rate); 5047c478bd9Sstevel@tonic-gate } 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate /* 5077c478bd9Sstevel@tonic-gate * this routine enables or disables clicking of the keyboard 5087c478bd9Sstevel@tonic-gate */ 5097c478bd9Sstevel@tonic-gate static int 5107c478bd9Sstevel@tonic-gate click(char *copt, int kbd) 5117c478bd9Sstevel@tonic-gate { 5127c478bd9Sstevel@tonic-gate int cmd; 5137c478bd9Sstevel@tonic-gate 5147c478bd9Sstevel@tonic-gate if (strcmp(copt, "on") == 0) 5157c478bd9Sstevel@tonic-gate cmd = KBD_CMD_CLICK; 5167c478bd9Sstevel@tonic-gate else if (strcmp(copt, "off") == 0) 5177c478bd9Sstevel@tonic-gate cmd = KBD_CMD_NOCLICK; 5187c478bd9Sstevel@tonic-gate else { 5197c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "wrong option -- %s\n", copt); 5207c478bd9Sstevel@tonic-gate usage(); 5217c478bd9Sstevel@tonic-gate return (1); 5227c478bd9Sstevel@tonic-gate } 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCCMD, &cmd)) { 5257c478bd9Sstevel@tonic-gate perror("kbd ioctl (keyclick)"); 5267c478bd9Sstevel@tonic-gate return (1); 5277c478bd9Sstevel@tonic-gate } 5287c478bd9Sstevel@tonic-gate return (0); 5297c478bd9Sstevel@tonic-gate } 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate /* 5327c478bd9Sstevel@tonic-gate * this routine enables/disables/sets BRK or abort sequence feature 5337c478bd9Sstevel@tonic-gate */ 5347c478bd9Sstevel@tonic-gate static int 5357c478bd9Sstevel@tonic-gate abort_enable(char *aopt, int kbd) 5367c478bd9Sstevel@tonic-gate { 5377c478bd9Sstevel@tonic-gate int enable; 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate if (strcmp(aopt, "alternate") == 0) 5407c478bd9Sstevel@tonic-gate enable = KIOCABORTALTERNATE; 5417c478bd9Sstevel@tonic-gate else if (strcmp(aopt, "enable") == 0) 5427c478bd9Sstevel@tonic-gate enable = KIOCABORTENABLE; 5437c478bd9Sstevel@tonic-gate else if (strcmp(aopt, "disable") == 0) 5447c478bd9Sstevel@tonic-gate enable = KIOCABORTDISABLE; 5457c478bd9Sstevel@tonic-gate else { 5467c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "wrong option -- %s\n", aopt); 5477c478bd9Sstevel@tonic-gate usage(); 5487c478bd9Sstevel@tonic-gate return (1); 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate 5517c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSKABORTEN, &enable)) { 5527c478bd9Sstevel@tonic-gate perror("kbd ioctl (abort enable)"); 5537c478bd9Sstevel@tonic-gate return (1); 5547c478bd9Sstevel@tonic-gate } 5557c478bd9Sstevel@tonic-gate return (0); 5567c478bd9Sstevel@tonic-gate } 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate /* 5597c478bd9Sstevel@tonic-gate * this routine set autorepeat delay 5607c478bd9Sstevel@tonic-gate */ 5617c478bd9Sstevel@tonic-gate static int 5627c478bd9Sstevel@tonic-gate set_repeat_delay(char *delay_str, int kbd) 5637c478bd9Sstevel@tonic-gate { 5647c478bd9Sstevel@tonic-gate int delay = atoi(delay_str); 5657c478bd9Sstevel@tonic-gate 5667c478bd9Sstevel@tonic-gate /* 5677c478bd9Sstevel@tonic-gate * The error message depends on the different inputs. 5687c478bd9Sstevel@tonic-gate * a. the input is a invalid integer(unit in ms) 5697c478bd9Sstevel@tonic-gate * b. the input is a integer less than the minimal delay setting. 570*4470e687Syx209491 * The condition (a) has been covered by main function and kbd_defaults 5717c478bd9Sstevel@tonic-gate * function. 5727c478bd9Sstevel@tonic-gate */ 5737c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSRPTDELAY, &delay) == -1) { 5747c478bd9Sstevel@tonic-gate if (delay < KIOCRPTDELAY_MIN) 5757c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "kbd: specified delay %d is " 5767c478bd9Sstevel@tonic-gate "less than minimum %d\n", delay, KIOCRPTDELAY_MIN); 5777c478bd9Sstevel@tonic-gate else 5787c478bd9Sstevel@tonic-gate perror("kbd: set repeat delay"); 5797c478bd9Sstevel@tonic-gate return (1); 5807c478bd9Sstevel@tonic-gate } 5817c478bd9Sstevel@tonic-gate 5827c478bd9Sstevel@tonic-gate return (0); 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate /* 5867c478bd9Sstevel@tonic-gate * this routine set autorepeat rate 5877c478bd9Sstevel@tonic-gate */ 5887c478bd9Sstevel@tonic-gate static int 5897c478bd9Sstevel@tonic-gate set_repeat_rate(char *rate_str, int kbd) 5907c478bd9Sstevel@tonic-gate { 5917c478bd9Sstevel@tonic-gate int rate = atoi(rate_str); 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate /* 594*4470e687Syx209491 * The input validation check has been covered by main function 595*4470e687Syx209491 * and kbd_defaults function.Here just give an error message if 596*4470e687Syx209491 * the ioctl fails. 5977c478bd9Sstevel@tonic-gate */ 5987c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSRPTRATE, &rate) == -1) { 5997c478bd9Sstevel@tonic-gate perror("kbd: set repeat rate"); 6007c478bd9Sstevel@tonic-gate return (1); 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate return (0); 6037c478bd9Sstevel@tonic-gate } 6047c478bd9Sstevel@tonic-gate 6057c478bd9Sstevel@tonic-gate #define BAD_DEFAULT "kbd: bad default value for %s: %s\n" 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate static void 6087c478bd9Sstevel@tonic-gate kbd_defaults(int kbd) 6097c478bd9Sstevel@tonic-gate { 6108ffc942dSrz201010 char *p, *endptr; 6118ffc942dSrz201010 int layout_num, freq; 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate if (defopen(DEF_FILE) != 0) { 6147c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Can't open default file: %s\n", 6157c478bd9Sstevel@tonic-gate DEF_FILE); 6167c478bd9Sstevel@tonic-gate exit(1); 6177c478bd9Sstevel@tonic-gate } 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate p = defread(DEF_CLICK); 6207c478bd9Sstevel@tonic-gate if (p != NULL) { 6217c478bd9Sstevel@tonic-gate /* 6227c478bd9Sstevel@tonic-gate * KEYCLICK must equal "on" or "off" 6237c478bd9Sstevel@tonic-gate */ 6247c478bd9Sstevel@tonic-gate if ((strcmp(p, "on") == 0) || (strcmp(p, "off") == 0)) 6257c478bd9Sstevel@tonic-gate (void) click(p, kbd); 6267c478bd9Sstevel@tonic-gate else 6277c478bd9Sstevel@tonic-gate (void) fprintf(stderr, BAD_DEFAULT, DEF_CLICK, p); 6287c478bd9Sstevel@tonic-gate } 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate p = defread(DEF_ABORT); 6317c478bd9Sstevel@tonic-gate if (p != NULL) { 6327c478bd9Sstevel@tonic-gate /* 6337c478bd9Sstevel@tonic-gate * ABORT must equal "enable", "disable" or "alternate" 6347c478bd9Sstevel@tonic-gate */ 6357c478bd9Sstevel@tonic-gate if ((strcmp(p, "enable") == 0) || 6367c478bd9Sstevel@tonic-gate (strcmp(p, "alternate") == 0) || 6377c478bd9Sstevel@tonic-gate (strcmp(p, "disable") == 0)) 6387c478bd9Sstevel@tonic-gate (void) abort_enable(p, kbd); 6397c478bd9Sstevel@tonic-gate else 6407c478bd9Sstevel@tonic-gate (void) fprintf(stderr, BAD_DEFAULT, DEF_ABORT, p); 6417c478bd9Sstevel@tonic-gate } 6427c478bd9Sstevel@tonic-gate 6437c478bd9Sstevel@tonic-gate p = defread(DEF_RPTDELAY); 6447c478bd9Sstevel@tonic-gate if (p != NULL) { 6457c478bd9Sstevel@tonic-gate /* 6467c478bd9Sstevel@tonic-gate * REPEAT_DELAY unit in ms 6477c478bd9Sstevel@tonic-gate */ 6487c478bd9Sstevel@tonic-gate if (atoi(p) > 0) 6497c478bd9Sstevel@tonic-gate (void) set_repeat_delay(p, kbd); 6507c478bd9Sstevel@tonic-gate else 6517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, BAD_DEFAULT, DEF_RPTDELAY, p); 6527c478bd9Sstevel@tonic-gate } 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate p = defread(DEF_RPTRATE); 6557c478bd9Sstevel@tonic-gate if (p != NULL) { 6567c478bd9Sstevel@tonic-gate /* 6577c478bd9Sstevel@tonic-gate * REPEAT_RATE unit in ms 6587c478bd9Sstevel@tonic-gate */ 6597c478bd9Sstevel@tonic-gate if (atoi(p) > 0) 6607c478bd9Sstevel@tonic-gate (void) set_repeat_rate(p, kbd); 6617c478bd9Sstevel@tonic-gate else 6627c478bd9Sstevel@tonic-gate (void) fprintf(stderr, BAD_DEFAULT, DEF_RPTRATE, p); 6637c478bd9Sstevel@tonic-gate } 6647db6e34eSqz150045 6657db6e34eSqz150045 p = defread(DEF_LAYOUT); 6667db6e34eSqz150045 if (p != NULL) { 6677db6e34eSqz150045 /* 6687db6e34eSqz150045 * LAYOUT must be one of the layouts supported in kbd_layouts 6697db6e34eSqz150045 */ 6707db6e34eSqz150045 if (get_layouts() != 0) 6717db6e34eSqz150045 return; 6727db6e34eSqz150045 6737db6e34eSqz150045 if ((layout_num = get_layout_number(p)) == -1) { 6747db6e34eSqz150045 (void) fprintf(stderr, BAD_DEFAULT, DEF_LAYOUT, p); 6757db6e34eSqz150045 return; 6767db6e34eSqz150045 } 6777db6e34eSqz150045 6787db6e34eSqz150045 (void) set_layout(kbd, layout_num); 6797db6e34eSqz150045 } 6808ffc942dSrz201010 6818ffc942dSrz201010 p = defread(DEF_KBDFREQ); 6828ffc942dSrz201010 if (p != NULL) { 6838ffc942dSrz201010 /* 6848ffc942dSrz201010 * Keyboard beeper frequency unit in Hz 6858ffc942dSrz201010 */ 6868ffc942dSrz201010 endptr = NULL; 6878ffc942dSrz201010 errno = 0; 6888ffc942dSrz201010 freq = (int)strtol(p, &endptr, 10); 6898ffc942dSrz201010 if (errno == 0 && endptr[0] == '\0' && 6908ffc942dSrz201010 freq >= 0 && freq <= INT16_MAX) 6918ffc942dSrz201010 (void) set_beep_freq(kbd, "keyboard", freq); 6928ffc942dSrz201010 else 6938ffc942dSrz201010 (void) fprintf(stderr, BAD_DEFAULT, DEF_KBDFREQ, p); 6948ffc942dSrz201010 } 6958ffc942dSrz201010 6968ffc942dSrz201010 p = defread(DEF_CONSFREQ); 6978ffc942dSrz201010 if (p != NULL) { 6988ffc942dSrz201010 /* 6998ffc942dSrz201010 * Console beeper frequency unit in Hz 7008ffc942dSrz201010 */ 7018ffc942dSrz201010 endptr = NULL; 7028ffc942dSrz201010 errno = 0; 7038ffc942dSrz201010 freq = (int)strtol(p, &endptr, 10); 7048ffc942dSrz201010 if (errno == 0 && endptr[0] == '\0' && 7058ffc942dSrz201010 freq >= 0 && freq <= INT16_MAX) 7068ffc942dSrz201010 (void) set_beep_freq(kbd, "console", freq); 7078ffc942dSrz201010 else 7088ffc942dSrz201010 (void) fprintf(stderr, BAD_DEFAULT, DEF_CONSFREQ, p); 7098ffc942dSrz201010 } 7107db6e34eSqz150045 } 7117db6e34eSqz150045 7127db6e34eSqz150045 static int 7137db6e34eSqz150045 get_layout_number(char *layout) 7147db6e34eSqz150045 { 7157db6e34eSqz150045 int i; 7167db6e34eSqz150045 int layout_number = -1; 7177db6e34eSqz150045 7187db6e34eSqz150045 for (i = 0; i < layout_count; i ++) { 7197db6e34eSqz150045 if (strcmp(layout, layout_names[i]) == 0) { 7207db6e34eSqz150045 layout_number = layout_numbers[i]; 7217db6e34eSqz150045 break; 7227db6e34eSqz150045 } 7237db6e34eSqz150045 } 7247db6e34eSqz150045 7257db6e34eSqz150045 return (layout_number); 7267db6e34eSqz150045 } 7277db6e34eSqz150045 7287db6e34eSqz150045 static int 7297db6e34eSqz150045 get_layouts() 7307db6e34eSqz150045 { 7317db6e34eSqz150045 FILE *stream; 7327db6e34eSqz150045 char buffer[MAX_LINE_SIZE]; 7337db6e34eSqz150045 char *result = NULL; 7347db6e34eSqz150045 int i = 0; 7357db6e34eSqz150045 char *tmpbuf; 7367db6e34eSqz150045 7377db6e34eSqz150045 if ((stream = fopen(KBD_LAYOUT_FILE, "r")) == 0) { 7387db6e34eSqz150045 perror(KBD_LAYOUT_FILE); 7397db6e34eSqz150045 return (1); 7407db6e34eSqz150045 } 7417db6e34eSqz150045 7427db6e34eSqz150045 while ((fgets(buffer, MAX_LINE_SIZE, stream) != NULL) && 7437db6e34eSqz150045 (i < MAX_LAYOUT_NUM)) { 7447db6e34eSqz150045 if (buffer[0] == '#') 7457db6e34eSqz150045 continue; 7467db6e34eSqz150045 if ((result = strtok(buffer, "=")) == NULL) 7477db6e34eSqz150045 continue; 7487db6e34eSqz150045 if ((tmpbuf = strdup(result)) != NULL) { 7497db6e34eSqz150045 layout_names[i] = tmpbuf; 7507db6e34eSqz150045 } else { 7517db6e34eSqz150045 perror("out of memory getting layout names"); 7527db6e34eSqz150045 return (1); 7537db6e34eSqz150045 } 7547db6e34eSqz150045 if ((result = strtok(NULL, "\n")) == NULL) 7557db6e34eSqz150045 continue; 7567db6e34eSqz150045 layout_numbers[i] = atoi(result); 7577db6e34eSqz150045 if (strcmp(tmpbuf, "US-English") == 0) 7587db6e34eSqz150045 default_layout_number = i; 7597db6e34eSqz150045 i++; 7607db6e34eSqz150045 } 7617db6e34eSqz150045 layout_count = i; 7627db6e34eSqz150045 7637db6e34eSqz150045 return (0); 7647db6e34eSqz150045 } 7657db6e34eSqz150045 7667db6e34eSqz150045 /* 7677db6e34eSqz150045 * this routine sets the layout of the keyboard being used 7687db6e34eSqz150045 */ 7697db6e34eSqz150045 static int 7707db6e34eSqz150045 set_layout(int kbd, int layout_num) 7717db6e34eSqz150045 { 7727db6e34eSqz150045 7737db6e34eSqz150045 if (ioctl(kbd, KIOCSLAYOUT, layout_num)) { 7747db6e34eSqz150045 perror("ioctl (set kbd layout)"); 7757db6e34eSqz150045 return (1); 7767db6e34eSqz150045 } 7777db6e34eSqz150045 7787db6e34eSqz150045 return (0); 7797c478bd9Sstevel@tonic-gate } 7807c478bd9Sstevel@tonic-gate 7817c478bd9Sstevel@tonic-gate static char *usage1 = "kbd [-r] [-t] [-l] [-a enable|disable|alternate]"; 7827c478bd9Sstevel@tonic-gate static char *usage2 = " [-c on|off][-D delay][-R rate][-d keyboard device]"; 7837c478bd9Sstevel@tonic-gate static char *usage3 = "kbd -i [-d keyboard device]"; 7847db6e34eSqz150045 static char *usage4 = "kbd -s [language]"; 7858ffc942dSrz201010 static char *usage5 = "kbd -b [keyboard|console] frequency"; 7867c478bd9Sstevel@tonic-gate 7877c478bd9Sstevel@tonic-gate static void 7887c478bd9Sstevel@tonic-gate usage(void) 7897c478bd9Sstevel@tonic-gate { 7908ffc942dSrz201010 (void) fprintf(stderr, "Usage:\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n", usage1, 7918ffc942dSrz201010 usage2, usage3, usage4, usage5); 7927c478bd9Sstevel@tonic-gate } 793