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 /* 30*8ffc942dSrz201010 * Usage: kbd [-r] [-t] [-l] [-c on|off] [-a enable|disable|alternate] 31*8ffc942dSrz201010 * [-d keyboard device] [-D autorepeat dealy] [-R autorepeat 32*8ffc942dSrz201010 * rate] 33*8ffc942dSrz201010 * kbd [-i] [-d keyboard device] 34*8ffc942dSrz201010 * kbd -s [language] 35*8ffc942dSrz201010 * 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 47*8ffc942dSrz201010 * -b [keyboard| console] frequency 48*8ffc942dSrz201010 * 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> 64*8ffc942dSrz201010 #include <errno.h> 65*8ffc942dSrz201010 #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=" 74*8ffc942dSrz201010 #define DEF_KBDFREQ "KBD_BEEPER_FREQ=" 75*8ffc942dSrz201010 #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 82*8ffc942dSrz201010 int errno; 837db6e34eSqz150045 char *layout_names[MAX_LAYOUT_NUM]; 847db6e34eSqz150045 int layout_numbers[MAX_LAYOUT_NUM]; 857db6e34eSqz150045 static int layout_count; 867db6e34eSqz150045 static int default_layout_number = 0; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate static void reset(int); 897c478bd9Sstevel@tonic-gate static void get_type(int); 907c478bd9Sstevel@tonic-gate static void get_layout(int); 917c478bd9Sstevel@tonic-gate static void kbd_defaults(int); 927c478bd9Sstevel@tonic-gate static void usage(void); 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate static int click(char *, int); 957c478bd9Sstevel@tonic-gate static int abort_enable(char *, int); 967c478bd9Sstevel@tonic-gate static int set_repeat_delay(char *, int); 977c478bd9Sstevel@tonic-gate static int set_repeat_rate(char *, int); 987c478bd9Sstevel@tonic-gate 997db6e34eSqz150045 static int get_layout_number(char *); 1007db6e34eSqz150045 static int set_layout(int, int); 1017db6e34eSqz150045 static int get_layouts(void); 1027db6e34eSqz150045 static int set_kbd_layout(int, char *); 103*8ffc942dSrz201010 static int set_beep_freq(int, char *, int); 1047db6e34eSqz150045 1057c478bd9Sstevel@tonic-gate int 1067c478bd9Sstevel@tonic-gate main(int argc, char **argv) 1077c478bd9Sstevel@tonic-gate { 1087c478bd9Sstevel@tonic-gate int c, error; 1097c478bd9Sstevel@tonic-gate int rflag, tflag, lflag, cflag, dflag, aflag, iflag, errflag, 110*8ffc942dSrz201010 Dflag, Rflag, rtlacDRflag, sflag, bflag; 111*8ffc942dSrz201010 char *copt, *aopt, *delay, *rate, *layout_name, *b_type, *freq_str; 112*8ffc942dSrz201010 char *kbdname = KBD_DEVICE, *endptr = NULL; 113*8ffc942dSrz201010 int kbd, freq_val; 1147c478bd9Sstevel@tonic-gate extern char *optarg; 1157c478bd9Sstevel@tonic-gate extern int optind; 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate rflag = tflag = cflag = dflag = aflag = iflag = errflag = lflag = 118*8ffc942dSrz201010 Dflag = Rflag = sflag = bflag = 0; 1197c478bd9Sstevel@tonic-gate copt = aopt = (char *)0; 1207c478bd9Sstevel@tonic-gate 121d8c870b0Sqz150045 (void) setlocale(LC_ALL, ""); 122d8c870b0Sqz150045 #if !defined(TEXT_DOMAIN) 123d8c870b0Sqz150045 #define TEXT_DOMAIN "SYS_TEST" 124d8c870b0Sqz150045 #endif 125d8c870b0Sqz150045 (void) textdomain(TEXT_DOMAIN); 126d8c870b0Sqz150045 127*8ffc942dSrz201010 while ((c = getopt(argc, argv, "rtlisc:a:d:D:R:b:")) != EOF) { 1287c478bd9Sstevel@tonic-gate switch (c) { 1297c478bd9Sstevel@tonic-gate case 'r': 1307c478bd9Sstevel@tonic-gate rflag++; 1317c478bd9Sstevel@tonic-gate break; 1327c478bd9Sstevel@tonic-gate case 't': 1337c478bd9Sstevel@tonic-gate tflag++; 1347c478bd9Sstevel@tonic-gate break; 1357c478bd9Sstevel@tonic-gate case 'l': 1367c478bd9Sstevel@tonic-gate lflag++; 1377c478bd9Sstevel@tonic-gate break; 1387c478bd9Sstevel@tonic-gate case 'i': 1397c478bd9Sstevel@tonic-gate iflag++; 1407c478bd9Sstevel@tonic-gate break; 1417db6e34eSqz150045 case 's': 1427db6e34eSqz150045 sflag++; 1437db6e34eSqz150045 break; 1447c478bd9Sstevel@tonic-gate case 'c': 1457c478bd9Sstevel@tonic-gate copt = optarg; 1467c478bd9Sstevel@tonic-gate cflag++; 1477c478bd9Sstevel@tonic-gate break; 1487c478bd9Sstevel@tonic-gate case 'a': 1497c478bd9Sstevel@tonic-gate aopt = optarg; 1507c478bd9Sstevel@tonic-gate aflag++; 1517c478bd9Sstevel@tonic-gate break; 1527c478bd9Sstevel@tonic-gate case 'd': 1537c478bd9Sstevel@tonic-gate kbdname = optarg; 1547c478bd9Sstevel@tonic-gate dflag++; 1557c478bd9Sstevel@tonic-gate break; 1567c478bd9Sstevel@tonic-gate case 'D': 1577c478bd9Sstevel@tonic-gate delay = optarg; 1587c478bd9Sstevel@tonic-gate Dflag++; 1597c478bd9Sstevel@tonic-gate break; 1607c478bd9Sstevel@tonic-gate case 'R': 1617c478bd9Sstevel@tonic-gate rate = optarg; 1627c478bd9Sstevel@tonic-gate Rflag++; 1637c478bd9Sstevel@tonic-gate break; 164*8ffc942dSrz201010 case 'b': 165*8ffc942dSrz201010 bflag++; 166*8ffc942dSrz201010 break; 1677c478bd9Sstevel@tonic-gate case '?': 1687c478bd9Sstevel@tonic-gate errflag++; 1697c478bd9Sstevel@tonic-gate break; 1707c478bd9Sstevel@tonic-gate } 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate /* 1747c478bd9Sstevel@tonic-gate * Check for valid arguments: 1757c478bd9Sstevel@tonic-gate * 1767c478bd9Sstevel@tonic-gate * If argument parsing failed or if there are left-over 177*8ffc942dSrz201010 * command line arguments(except -s and -b option), 178*8ffc942dSrz201010 * then we're done now. 1797c478bd9Sstevel@tonic-gate */ 180*8ffc942dSrz201010 if (errflag != 0 || (sflag == 0 && bflag == 0 && argc != optind)) { 1817c478bd9Sstevel@tonic-gate usage(); 1827c478bd9Sstevel@tonic-gate exit(1); 1837c478bd9Sstevel@tonic-gate } 1847db6e34eSqz150045 1857c478bd9Sstevel@tonic-gate /* 186*8ffc942dSrz201010 * kbd requires that the user specify either "-i" or "-s" or "-b" or 187*8ffc942dSrz201010 * at least one of -[rtlacDR]. The "-d" option is, well, optional. 1887db6e34eSqz150045 * We don't care if it's there or not. 1897c478bd9Sstevel@tonic-gate */ 1907c478bd9Sstevel@tonic-gate rtlacDRflag = rflag + tflag + lflag + aflag + cflag + Dflag + Rflag; 191*8ffc942dSrz201010 if (!((iflag != 0 && sflag == 0 && bflag == 0 && rtlacDRflag == 0) || 192*8ffc942dSrz201010 (iflag == 0 && sflag != 0 && bflag == 0 && dflag == 0 && 193*8ffc942dSrz201010 rtlacDRflag == 0) || 194*8ffc942dSrz201010 (iflag == 0 && sflag == 0 && bflag == 0 && rtlacDRflag != 0) || 195*8ffc942dSrz201010 (iflag == 0 && sflag == 0 && bflag != 0 && rtlacDRflag == 0))) { 1967c478bd9Sstevel@tonic-gate usage(); 1977c478bd9Sstevel@tonic-gate exit(1); 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate if (Dflag && atoi(delay) <= 0) { 2017c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid arguments: -D %s\n", delay); 2027c478bd9Sstevel@tonic-gate usage(); 2037c478bd9Sstevel@tonic-gate exit(1); 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate if (Rflag && atoi(rate) <= 0) { 2077c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Invalid arguments: -R %s\n", rate); 2087c478bd9Sstevel@tonic-gate usage(); 2097c478bd9Sstevel@tonic-gate exit(1); 2107c478bd9Sstevel@tonic-gate } 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate /* 2137c478bd9Sstevel@tonic-gate * Open the keyboard device 2147c478bd9Sstevel@tonic-gate */ 2157c478bd9Sstevel@tonic-gate if ((kbd = open(kbdname, O_RDWR)) < 0) { 2167c478bd9Sstevel@tonic-gate perror("opening the keyboard"); 2177c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "kbd: Cannot open %s\n", kbdname); 2187c478bd9Sstevel@tonic-gate exit(1); 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate if (iflag) { 2227c478bd9Sstevel@tonic-gate kbd_defaults(kbd); 2237c478bd9Sstevel@tonic-gate exit(0); /* A mutually exclusive option */ 2247c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate if (tflag) 2287c478bd9Sstevel@tonic-gate get_type(kbd); 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate if (lflag) 2317c478bd9Sstevel@tonic-gate get_layout(kbd); 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate if (cflag && (error = click(copt, kbd)) != 0) 2347c478bd9Sstevel@tonic-gate exit(error); 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate if (rflag) 2377c478bd9Sstevel@tonic-gate reset(kbd); 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate if (aflag && (error = abort_enable(aopt, kbd)) != 0) 2407c478bd9Sstevel@tonic-gate exit(error); 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate if (Dflag && (error = set_repeat_delay(delay, kbd)) != 0) 2437c478bd9Sstevel@tonic-gate exit(error); 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate if (Rflag && (error = set_repeat_rate(rate, kbd)) != 0) 2467c478bd9Sstevel@tonic-gate exit(error); 2477c478bd9Sstevel@tonic-gate 2487db6e34eSqz150045 if (sflag) { 2497db6e34eSqz150045 if (argc == optind) { 2507db6e34eSqz150045 layout_name = NULL; 2517db6e34eSqz150045 } else if (argc == (optind + 1)) { 2527db6e34eSqz150045 layout_name = argv[optind]; 2537db6e34eSqz150045 } else { 2547db6e34eSqz150045 usage(); 2557db6e34eSqz150045 exit(1); 2567db6e34eSqz150045 } 2577db6e34eSqz150045 2587db6e34eSqz150045 if ((error = set_kbd_layout(kbd, layout_name)) != 0) 2597db6e34eSqz150045 exit(error); 2607db6e34eSqz150045 } 2617db6e34eSqz150045 262*8ffc942dSrz201010 if (bflag) { 263*8ffc942dSrz201010 if (argc == optind) { 264*8ffc942dSrz201010 b_type = "keyboard"; 265*8ffc942dSrz201010 } else if (argc == (optind + 1)) { 266*8ffc942dSrz201010 b_type = argv[argc - 2]; 267*8ffc942dSrz201010 } else { 268*8ffc942dSrz201010 usage(); 269*8ffc942dSrz201010 exit(1); 270*8ffc942dSrz201010 } 271*8ffc942dSrz201010 272*8ffc942dSrz201010 if (strcmp(b_type, "keyboard") && strcmp(b_type, "console")) { 273*8ffc942dSrz201010 usage(); 274*8ffc942dSrz201010 exit(1); 275*8ffc942dSrz201010 } 276*8ffc942dSrz201010 277*8ffc942dSrz201010 freq_str = argv[argc - 1]; 278*8ffc942dSrz201010 errno = 0; 279*8ffc942dSrz201010 freq_val = (int)strtol(freq_str, &endptr, 10); 280*8ffc942dSrz201010 if (errno != 0 || endptr[0] != '\0') { 281*8ffc942dSrz201010 usage(); 282*8ffc942dSrz201010 exit(1); 283*8ffc942dSrz201010 } 284*8ffc942dSrz201010 285*8ffc942dSrz201010 if (freq_val < 0 || freq_val > INT16_MAX) { 286*8ffc942dSrz201010 (void) fprintf(stderr, "Invalid arguments: -b %s\n", 287*8ffc942dSrz201010 freq_str); 288*8ffc942dSrz201010 (void) fprintf(stderr, "Frequency range: [0 - %d]\n", 289*8ffc942dSrz201010 INT16_MAX); 290*8ffc942dSrz201010 exit(1); 291*8ffc942dSrz201010 } 292*8ffc942dSrz201010 293*8ffc942dSrz201010 if ((error = set_beep_freq(kbd, b_type, freq_val)) != 0) 294*8ffc942dSrz201010 exit(1); 295*8ffc942dSrz201010 } 296*8ffc942dSrz201010 2977db6e34eSqz150045 return (0); 2987db6e34eSqz150045 } 2997db6e34eSqz150045 3007db6e34eSqz150045 /* 3017db6e34eSqz150045 * this routine gets the type of the keyboard being used 3027db6e34eSqz150045 */ 3037db6e34eSqz150045 static int 3047db6e34eSqz150045 set_kbd_layout(int kbd, char *layout_name) 3057db6e34eSqz150045 { 3067db6e34eSqz150045 int layout_num; 3077db6e34eSqz150045 int error = 1; 3087db6e34eSqz150045 3097db6e34eSqz150045 /* get the language info from the layouts file */ 3107db6e34eSqz150045 if (get_layouts() != 0) 3117db6e34eSqz150045 return (error); 3127db6e34eSqz150045 3137db6e34eSqz150045 if (layout_name != NULL) { 3147db6e34eSqz150045 if ((layout_num = get_layout_number(layout_name)) == -1) { 3157db6e34eSqz150045 (void) fprintf(stderr, "%s: unknown layout name\n" 3167db6e34eSqz150045 "Please refer to 'kbd -s' to get the " 3177db6e34eSqz150045 "supported layouts.\n", layout_name); 3187db6e34eSqz150045 return (error); 3197db6e34eSqz150045 } 3207db6e34eSqz150045 } else { 3217db6e34eSqz150045 int i, j, print_cnt, input_num; 3227db6e34eSqz150045 boolean_t input_right = B_TRUE; 3237db6e34eSqz150045 boolean_t default_input = B_FALSE; 3247db6e34eSqz150045 char input[8]; /* 8 chars is enough for numbers */ 3257db6e34eSqz150045 3267db6e34eSqz150045 print_cnt = (layout_count % 2) ? 3277db6e34eSqz150045 layout_count/2+1 : layout_count/2; 3287db6e34eSqz150045 3297db6e34eSqz150045 for (i = 1; i <= print_cnt; i++) { 3307db6e34eSqz150045 (void) printf("%2d. %-30s", i, 3317db6e34eSqz150045 layout_names[i-1]); 3327db6e34eSqz150045 j = i + print_cnt; 3337db6e34eSqz150045 if (j <= layout_count) { 3347db6e34eSqz150045 (void) printf("%-2d. %-30s\n", j, 3357db6e34eSqz150045 layout_names[j-1]); 3367db6e34eSqz150045 } 3377db6e34eSqz150045 } 338d8c870b0Sqz150045 (void) printf(gettext("\nTo select the keyboard layout," 339d8c870b0Sqz150045 " enter a number [default %d]:"), 3407db6e34eSqz150045 default_layout_number+1); 3417db6e34eSqz150045 3427db6e34eSqz150045 for (;;) { 3437db6e34eSqz150045 if (input_right == B_FALSE) 344d8c870b0Sqz150045 (void) printf(gettext("Invalid input. " 345d8c870b0Sqz150045 "Please input a number " 346d8c870b0Sqz150045 "(1,2,...):")); 3477db6e34eSqz150045 (void) memset(input, 0, 8); 3487db6e34eSqz150045 (void) fflush(stdin); 3497db6e34eSqz150045 (void) fgets(input, 8, stdin); 3507db6e34eSqz150045 if (strlen(input) > 4) { 3517db6e34eSqz150045 input_right = B_FALSE; 3527db6e34eSqz150045 continue; 3537db6e34eSqz150045 } 3547db6e34eSqz150045 if (input[0] == '\n') { 3557db6e34eSqz150045 default_input = B_TRUE; 3567db6e34eSqz150045 break; 3577db6e34eSqz150045 } 3587db6e34eSqz150045 input_right = B_TRUE; 3597db6e34eSqz150045 /* check if the inputs are numbers 0~9 */ 3607db6e34eSqz150045 for (i = 0; i < (strlen(input) - 1); i++) { 3617db6e34eSqz150045 if ((input[i] < '0') || 3627db6e34eSqz150045 (input[i] > '9')) { 3637db6e34eSqz150045 input_right = B_FALSE; 3647db6e34eSqz150045 break; 3657db6e34eSqz150045 } 3667db6e34eSqz150045 } 3677db6e34eSqz150045 if (input_right == B_FALSE) 3687db6e34eSqz150045 continue; 3697db6e34eSqz150045 input_num = atoi(input); 3707db6e34eSqz150045 if ((input_num > 0) && 3717db6e34eSqz150045 (input_num <= layout_count)) 3727db6e34eSqz150045 break; 3737db6e34eSqz150045 else 3747db6e34eSqz150045 input_right = B_FALSE; 3757db6e34eSqz150045 } 3767db6e34eSqz150045 if (default_input == B_TRUE) 3777db6e34eSqz150045 layout_num = DEFAULT_KBD_LAYOUT; 3787db6e34eSqz150045 else 3797db6e34eSqz150045 layout_num = layout_numbers[--input_num]; 3807db6e34eSqz150045 } 3817db6e34eSqz150045 3827db6e34eSqz150045 if ((error = set_layout(kbd, layout_num)) != 0) 3837db6e34eSqz150045 return (error); 3847db6e34eSqz150045 3857c478bd9Sstevel@tonic-gate return (0); 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate /* 389*8ffc942dSrz201010 * This routine sets keyboard or console beeper frequency 390*8ffc942dSrz201010 */ 391*8ffc942dSrz201010 static int 392*8ffc942dSrz201010 set_beep_freq(int fd, char *type, int freq) 393*8ffc942dSrz201010 { 394*8ffc942dSrz201010 struct freq_request fr_struct; 395*8ffc942dSrz201010 396*8ffc942dSrz201010 if (strcmp(type, "keyboard") == 0) 397*8ffc942dSrz201010 fr_struct.type = KBD_BEEP; 398*8ffc942dSrz201010 else if (strcmp(type, "console") == 0) 399*8ffc942dSrz201010 fr_struct.type = CONSOLE_BEEP; 400*8ffc942dSrz201010 else 401*8ffc942dSrz201010 return (EINVAL); 402*8ffc942dSrz201010 403*8ffc942dSrz201010 fr_struct.freq = (int16_t)freq; 404*8ffc942dSrz201010 405*8ffc942dSrz201010 return (ioctl(fd, KIOCSETFREQ, &fr_struct)); 406*8ffc942dSrz201010 } 407*8ffc942dSrz201010 408*8ffc942dSrz201010 /* 4097c478bd9Sstevel@tonic-gate * this routine resets the state of the keyboard as if power-up 4107c478bd9Sstevel@tonic-gate */ 4117c478bd9Sstevel@tonic-gate static void 4127c478bd9Sstevel@tonic-gate reset(int kbd) 4137c478bd9Sstevel@tonic-gate { 4147c478bd9Sstevel@tonic-gate int cmd; 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate cmd = KBD_CMD_RESET; 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCCMD, &cmd)) { 4197c478bd9Sstevel@tonic-gate perror("kbd: ioctl error"); 4207c478bd9Sstevel@tonic-gate exit(1); 4217c478bd9Sstevel@tonic-gate } 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate } 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate /* 4267c478bd9Sstevel@tonic-gate * this routine gets the type of the keyboard being used 4277c478bd9Sstevel@tonic-gate */ 4287c478bd9Sstevel@tonic-gate static void 4297c478bd9Sstevel@tonic-gate get_type(int kbd) 4307c478bd9Sstevel@tonic-gate { 4317c478bd9Sstevel@tonic-gate int kbd_type; 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCTYPE, &kbd_type)) { 4347c478bd9Sstevel@tonic-gate perror("ioctl (kbd type)"); 4357c478bd9Sstevel@tonic-gate exit(1); 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate switch (kbd_type) { 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate case KB_SUN3: 4417c478bd9Sstevel@tonic-gate (void) printf("Type 3 Sun keyboard\n"); 4427c478bd9Sstevel@tonic-gate break; 4437c478bd9Sstevel@tonic-gate 4447c478bd9Sstevel@tonic-gate case KB_SUN4: 4457c478bd9Sstevel@tonic-gate (void) printf("Type 4 Sun keyboard\n"); 4467c478bd9Sstevel@tonic-gate break; 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate case KB_ASCII: 4497c478bd9Sstevel@tonic-gate (void) printf("ASCII\n"); 4507c478bd9Sstevel@tonic-gate break; 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate case KB_PC: 4537c478bd9Sstevel@tonic-gate (void) printf("PC\n"); 4547c478bd9Sstevel@tonic-gate break; 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate case KB_USB: 4577c478bd9Sstevel@tonic-gate (void) printf("USB keyboard\n"); 4587c478bd9Sstevel@tonic-gate break; 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate default: 4617c478bd9Sstevel@tonic-gate (void) printf("Unknown keyboard type\n"); 4627c478bd9Sstevel@tonic-gate break; 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate 4667c478bd9Sstevel@tonic-gate /* 4677c478bd9Sstevel@tonic-gate * this routine gets the layout of the keyboard being used 4687c478bd9Sstevel@tonic-gate * also, included the autorepeat delay and rate being used 4697c478bd9Sstevel@tonic-gate */ 4707c478bd9Sstevel@tonic-gate static void 4717c478bd9Sstevel@tonic-gate get_layout(int kbd) 4727c478bd9Sstevel@tonic-gate { 4737c478bd9Sstevel@tonic-gate int kbd_type; 4747c478bd9Sstevel@tonic-gate int kbd_layout; 4757c478bd9Sstevel@tonic-gate /* these two variables are used for getting delay&rate */ 4767c478bd9Sstevel@tonic-gate int delay, rate; 4777c478bd9Sstevel@tonic-gate delay = rate = 0; 4787c478bd9Sstevel@tonic-gate 4797c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCTYPE, &kbd_type)) { 4807c478bd9Sstevel@tonic-gate perror("ioctl (kbd type)"); 4817c478bd9Sstevel@tonic-gate exit(1); 4827c478bd9Sstevel@tonic-gate } 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCLAYOUT, &kbd_layout)) { 4857c478bd9Sstevel@tonic-gate perror("ioctl (kbd layout)"); 4867c478bd9Sstevel@tonic-gate exit(1); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate (void) printf("type=%d\nlayout=%d (0x%.2x)\n", 4907c478bd9Sstevel@tonic-gate kbd_type, kbd_layout, kbd_layout); 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate /* below code is used to get the autorepeat delay and rate */ 4937c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCGRPTDELAY, &delay)) { 4947c478bd9Sstevel@tonic-gate perror("ioctl (kbd get repeat delay)"); 4957c478bd9Sstevel@tonic-gate exit(1); 4967c478bd9Sstevel@tonic-gate } 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCGRPTRATE, &rate)) { 4997c478bd9Sstevel@tonic-gate perror("ioctl (kbd get repeat rate)"); 5007c478bd9Sstevel@tonic-gate exit(1); 5017c478bd9Sstevel@tonic-gate } 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gate (void) printf("delay(ms)=%d\n", delay); 5047c478bd9Sstevel@tonic-gate (void) printf("rate(ms)=%d\n", rate); 5057c478bd9Sstevel@tonic-gate } 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate /* 5087c478bd9Sstevel@tonic-gate * this routine enables or disables clicking of the keyboard 5097c478bd9Sstevel@tonic-gate */ 5107c478bd9Sstevel@tonic-gate static int 5117c478bd9Sstevel@tonic-gate click(char *copt, int kbd) 5127c478bd9Sstevel@tonic-gate { 5137c478bd9Sstevel@tonic-gate int cmd; 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate if (strcmp(copt, "on") == 0) 5167c478bd9Sstevel@tonic-gate cmd = KBD_CMD_CLICK; 5177c478bd9Sstevel@tonic-gate else if (strcmp(copt, "off") == 0) 5187c478bd9Sstevel@tonic-gate cmd = KBD_CMD_NOCLICK; 5197c478bd9Sstevel@tonic-gate else { 5207c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "wrong option -- %s\n", copt); 5217c478bd9Sstevel@tonic-gate usage(); 5227c478bd9Sstevel@tonic-gate return (1); 5237c478bd9Sstevel@tonic-gate } 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCCMD, &cmd)) { 5267c478bd9Sstevel@tonic-gate perror("kbd ioctl (keyclick)"); 5277c478bd9Sstevel@tonic-gate return (1); 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate return (0); 5307c478bd9Sstevel@tonic-gate } 5317c478bd9Sstevel@tonic-gate 5327c478bd9Sstevel@tonic-gate /* 5337c478bd9Sstevel@tonic-gate * this routine enables/disables/sets BRK or abort sequence feature 5347c478bd9Sstevel@tonic-gate */ 5357c478bd9Sstevel@tonic-gate static int 5367c478bd9Sstevel@tonic-gate abort_enable(char *aopt, int kbd) 5377c478bd9Sstevel@tonic-gate { 5387c478bd9Sstevel@tonic-gate int enable; 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate if (strcmp(aopt, "alternate") == 0) 5417c478bd9Sstevel@tonic-gate enable = KIOCABORTALTERNATE; 5427c478bd9Sstevel@tonic-gate else if (strcmp(aopt, "enable") == 0) 5437c478bd9Sstevel@tonic-gate enable = KIOCABORTENABLE; 5447c478bd9Sstevel@tonic-gate else if (strcmp(aopt, "disable") == 0) 5457c478bd9Sstevel@tonic-gate enable = KIOCABORTDISABLE; 5467c478bd9Sstevel@tonic-gate else { 5477c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "wrong option -- %s\n", aopt); 5487c478bd9Sstevel@tonic-gate usage(); 5497c478bd9Sstevel@tonic-gate return (1); 5507c478bd9Sstevel@tonic-gate } 5517c478bd9Sstevel@tonic-gate 5527c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSKABORTEN, &enable)) { 5537c478bd9Sstevel@tonic-gate perror("kbd ioctl (abort enable)"); 5547c478bd9Sstevel@tonic-gate return (1); 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate return (0); 5577c478bd9Sstevel@tonic-gate } 5587c478bd9Sstevel@tonic-gate 5597c478bd9Sstevel@tonic-gate /* 5607c478bd9Sstevel@tonic-gate * this routine set autorepeat delay 5617c478bd9Sstevel@tonic-gate */ 5627c478bd9Sstevel@tonic-gate static int 5637c478bd9Sstevel@tonic-gate set_repeat_delay(char *delay_str, int kbd) 5647c478bd9Sstevel@tonic-gate { 5657c478bd9Sstevel@tonic-gate int delay = atoi(delay_str); 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate /* 5687c478bd9Sstevel@tonic-gate * The error message depends on the different inputs. 5697c478bd9Sstevel@tonic-gate * a. the input is a invalid integer(unit in ms) 5707c478bd9Sstevel@tonic-gate * b. the input is a integer less than the minimal delay setting. 5717c478bd9Sstevel@tonic-gate * The condition (a) has been covered by main function and set_default 5727c478bd9Sstevel@tonic-gate * function. 5737c478bd9Sstevel@tonic-gate */ 5747c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSRPTDELAY, &delay) == -1) { 5757c478bd9Sstevel@tonic-gate if (delay < KIOCRPTDELAY_MIN) 5767c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "kbd: specified delay %d is " 5777c478bd9Sstevel@tonic-gate "less than minimum %d\n", delay, KIOCRPTDELAY_MIN); 5787c478bd9Sstevel@tonic-gate else 5797c478bd9Sstevel@tonic-gate perror("kbd: set repeat delay"); 5807c478bd9Sstevel@tonic-gate return (1); 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate return (0); 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate /* 5877c478bd9Sstevel@tonic-gate * this routine set autorepeat rate 5887c478bd9Sstevel@tonic-gate */ 5897c478bd9Sstevel@tonic-gate static int 5907c478bd9Sstevel@tonic-gate set_repeat_rate(char *rate_str, int kbd) 5917c478bd9Sstevel@tonic-gate { 5927c478bd9Sstevel@tonic-gate int rate = atoi(rate_str); 5937c478bd9Sstevel@tonic-gate 5947c478bd9Sstevel@tonic-gate /* 5957c478bd9Sstevel@tonic-gate * The error message depends on the different inputs. 5967c478bd9Sstevel@tonic-gate * a. the input is a invalid integer(unit in ms) 5977c478bd9Sstevel@tonic-gate * b. the input is a integer less than the minimal rate setting. 5987c478bd9Sstevel@tonic-gate * The condition (a) has been covered by main function and set_default 5997c478bd9Sstevel@tonic-gate * function. 6007c478bd9Sstevel@tonic-gate */ 6017c478bd9Sstevel@tonic-gate if (ioctl(kbd, KIOCSRPTRATE, &rate) == -1) { 6027c478bd9Sstevel@tonic-gate if (rate < KIOCRPTRATE_MIN) 6037c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "kbd: specified rate %d is " 6047c478bd9Sstevel@tonic-gate "less than minimum %d\n", rate, KIOCRPTRATE_MIN); 6057c478bd9Sstevel@tonic-gate else 6067c478bd9Sstevel@tonic-gate perror("kbd: set repeat rate"); 6077c478bd9Sstevel@tonic-gate return (1); 6087c478bd9Sstevel@tonic-gate } 6097c478bd9Sstevel@tonic-gate 6107c478bd9Sstevel@tonic-gate return (0); 6117c478bd9Sstevel@tonic-gate } 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate #define BAD_DEFAULT "kbd: bad default value for %s: %s\n" 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate static void 6167c478bd9Sstevel@tonic-gate kbd_defaults(int kbd) 6177c478bd9Sstevel@tonic-gate { 618*8ffc942dSrz201010 char *p, *endptr; 619*8ffc942dSrz201010 int layout_num, freq; 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate if (defopen(DEF_FILE) != 0) { 6227c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Can't open default file: %s\n", 6237c478bd9Sstevel@tonic-gate DEF_FILE); 6247c478bd9Sstevel@tonic-gate exit(1); 6257c478bd9Sstevel@tonic-gate } 6267c478bd9Sstevel@tonic-gate 6277c478bd9Sstevel@tonic-gate p = defread(DEF_CLICK); 6287c478bd9Sstevel@tonic-gate if (p != NULL) { 6297c478bd9Sstevel@tonic-gate /* 6307c478bd9Sstevel@tonic-gate * KEYCLICK must equal "on" or "off" 6317c478bd9Sstevel@tonic-gate */ 6327c478bd9Sstevel@tonic-gate if ((strcmp(p, "on") == 0) || (strcmp(p, "off") == 0)) 6337c478bd9Sstevel@tonic-gate (void) click(p, kbd); 6347c478bd9Sstevel@tonic-gate else 6357c478bd9Sstevel@tonic-gate (void) fprintf(stderr, BAD_DEFAULT, DEF_CLICK, p); 6367c478bd9Sstevel@tonic-gate } 6377c478bd9Sstevel@tonic-gate 6387c478bd9Sstevel@tonic-gate p = defread(DEF_ABORT); 6397c478bd9Sstevel@tonic-gate if (p != NULL) { 6407c478bd9Sstevel@tonic-gate /* 6417c478bd9Sstevel@tonic-gate * ABORT must equal "enable", "disable" or "alternate" 6427c478bd9Sstevel@tonic-gate */ 6437c478bd9Sstevel@tonic-gate if ((strcmp(p, "enable") == 0) || 6447c478bd9Sstevel@tonic-gate (strcmp(p, "alternate") == 0) || 6457c478bd9Sstevel@tonic-gate (strcmp(p, "disable") == 0)) 6467c478bd9Sstevel@tonic-gate (void) abort_enable(p, kbd); 6477c478bd9Sstevel@tonic-gate else 6487c478bd9Sstevel@tonic-gate (void) fprintf(stderr, BAD_DEFAULT, DEF_ABORT, p); 6497c478bd9Sstevel@tonic-gate } 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate p = defread(DEF_RPTDELAY); 6527c478bd9Sstevel@tonic-gate if (p != NULL) { 6537c478bd9Sstevel@tonic-gate /* 6547c478bd9Sstevel@tonic-gate * REPEAT_DELAY unit in ms 6557c478bd9Sstevel@tonic-gate */ 6567c478bd9Sstevel@tonic-gate if (atoi(p) > 0) 6577c478bd9Sstevel@tonic-gate (void) set_repeat_delay(p, kbd); 6587c478bd9Sstevel@tonic-gate else 6597c478bd9Sstevel@tonic-gate (void) fprintf(stderr, BAD_DEFAULT, DEF_RPTDELAY, p); 6607c478bd9Sstevel@tonic-gate } 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate p = defread(DEF_RPTRATE); 6637c478bd9Sstevel@tonic-gate if (p != NULL) { 6647c478bd9Sstevel@tonic-gate /* 6657c478bd9Sstevel@tonic-gate * REPEAT_RATE unit in ms 6667c478bd9Sstevel@tonic-gate */ 6677c478bd9Sstevel@tonic-gate if (atoi(p) > 0) 6687c478bd9Sstevel@tonic-gate (void) set_repeat_rate(p, kbd); 6697c478bd9Sstevel@tonic-gate else 6707c478bd9Sstevel@tonic-gate (void) fprintf(stderr, BAD_DEFAULT, DEF_RPTRATE, p); 6717c478bd9Sstevel@tonic-gate } 6727db6e34eSqz150045 6737db6e34eSqz150045 p = defread(DEF_LAYOUT); 6747db6e34eSqz150045 if (p != NULL) { 6757db6e34eSqz150045 /* 6767db6e34eSqz150045 * LAYOUT must be one of the layouts supported in kbd_layouts 6777db6e34eSqz150045 */ 6787db6e34eSqz150045 if (get_layouts() != 0) 6797db6e34eSqz150045 return; 6807db6e34eSqz150045 6817db6e34eSqz150045 if ((layout_num = get_layout_number(p)) == -1) { 6827db6e34eSqz150045 (void) fprintf(stderr, BAD_DEFAULT, DEF_LAYOUT, p); 6837db6e34eSqz150045 return; 6847db6e34eSqz150045 } 6857db6e34eSqz150045 6867db6e34eSqz150045 (void) set_layout(kbd, layout_num); 6877db6e34eSqz150045 } 688*8ffc942dSrz201010 689*8ffc942dSrz201010 p = defread(DEF_KBDFREQ); 690*8ffc942dSrz201010 if (p != NULL) { 691*8ffc942dSrz201010 /* 692*8ffc942dSrz201010 * Keyboard beeper frequency unit in Hz 693*8ffc942dSrz201010 */ 694*8ffc942dSrz201010 endptr = NULL; 695*8ffc942dSrz201010 errno = 0; 696*8ffc942dSrz201010 freq = (int)strtol(p, &endptr, 10); 697*8ffc942dSrz201010 if (errno == 0 && endptr[0] == '\0' && 698*8ffc942dSrz201010 freq >= 0 && freq <= INT16_MAX) 699*8ffc942dSrz201010 (void) set_beep_freq(kbd, "keyboard", freq); 700*8ffc942dSrz201010 else 701*8ffc942dSrz201010 (void) fprintf(stderr, BAD_DEFAULT, DEF_KBDFREQ, p); 702*8ffc942dSrz201010 } 703*8ffc942dSrz201010 704*8ffc942dSrz201010 p = defread(DEF_CONSFREQ); 705*8ffc942dSrz201010 if (p != NULL) { 706*8ffc942dSrz201010 /* 707*8ffc942dSrz201010 * Console beeper frequency unit in Hz 708*8ffc942dSrz201010 */ 709*8ffc942dSrz201010 endptr = NULL; 710*8ffc942dSrz201010 errno = 0; 711*8ffc942dSrz201010 freq = (int)strtol(p, &endptr, 10); 712*8ffc942dSrz201010 if (errno == 0 && endptr[0] == '\0' && 713*8ffc942dSrz201010 freq >= 0 && freq <= INT16_MAX) 714*8ffc942dSrz201010 (void) set_beep_freq(kbd, "console", freq); 715*8ffc942dSrz201010 else 716*8ffc942dSrz201010 (void) fprintf(stderr, BAD_DEFAULT, DEF_CONSFREQ, p); 717*8ffc942dSrz201010 } 7187db6e34eSqz150045 } 7197db6e34eSqz150045 7207db6e34eSqz150045 static int 7217db6e34eSqz150045 get_layout_number(char *layout) 7227db6e34eSqz150045 { 7237db6e34eSqz150045 int i; 7247db6e34eSqz150045 int layout_number = -1; 7257db6e34eSqz150045 7267db6e34eSqz150045 for (i = 0; i < layout_count; i ++) { 7277db6e34eSqz150045 if (strcmp(layout, layout_names[i]) == 0) { 7287db6e34eSqz150045 layout_number = layout_numbers[i]; 7297db6e34eSqz150045 break; 7307db6e34eSqz150045 } 7317db6e34eSqz150045 } 7327db6e34eSqz150045 7337db6e34eSqz150045 return (layout_number); 7347db6e34eSqz150045 } 7357db6e34eSqz150045 7367db6e34eSqz150045 static int 7377db6e34eSqz150045 get_layouts() 7387db6e34eSqz150045 { 7397db6e34eSqz150045 FILE *stream; 7407db6e34eSqz150045 char buffer[MAX_LINE_SIZE]; 7417db6e34eSqz150045 char *result = NULL; 7427db6e34eSqz150045 int i = 0; 7437db6e34eSqz150045 char *tmpbuf; 7447db6e34eSqz150045 7457db6e34eSqz150045 if ((stream = fopen(KBD_LAYOUT_FILE, "r")) == 0) { 7467db6e34eSqz150045 perror(KBD_LAYOUT_FILE); 7477db6e34eSqz150045 return (1); 7487db6e34eSqz150045 } 7497db6e34eSqz150045 7507db6e34eSqz150045 while ((fgets(buffer, MAX_LINE_SIZE, stream) != NULL) && 7517db6e34eSqz150045 (i < MAX_LAYOUT_NUM)) { 7527db6e34eSqz150045 if (buffer[0] == '#') 7537db6e34eSqz150045 continue; 7547db6e34eSqz150045 if ((result = strtok(buffer, "=")) == NULL) 7557db6e34eSqz150045 continue; 7567db6e34eSqz150045 if ((tmpbuf = strdup(result)) != NULL) { 7577db6e34eSqz150045 layout_names[i] = tmpbuf; 7587db6e34eSqz150045 } else { 7597db6e34eSqz150045 perror("out of memory getting layout names"); 7607db6e34eSqz150045 return (1); 7617db6e34eSqz150045 } 7627db6e34eSqz150045 if ((result = strtok(NULL, "\n")) == NULL) 7637db6e34eSqz150045 continue; 7647db6e34eSqz150045 layout_numbers[i] = atoi(result); 7657db6e34eSqz150045 if (strcmp(tmpbuf, "US-English") == 0) 7667db6e34eSqz150045 default_layout_number = i; 7677db6e34eSqz150045 i++; 7687db6e34eSqz150045 } 7697db6e34eSqz150045 layout_count = i; 7707db6e34eSqz150045 7717db6e34eSqz150045 return (0); 7727db6e34eSqz150045 } 7737db6e34eSqz150045 7747db6e34eSqz150045 /* 7757db6e34eSqz150045 * this routine sets the layout of the keyboard being used 7767db6e34eSqz150045 */ 7777db6e34eSqz150045 static int 7787db6e34eSqz150045 set_layout(int kbd, int layout_num) 7797db6e34eSqz150045 { 7807db6e34eSqz150045 7817db6e34eSqz150045 if (ioctl(kbd, KIOCSLAYOUT, layout_num)) { 7827db6e34eSqz150045 perror("ioctl (set kbd layout)"); 7837db6e34eSqz150045 return (1); 7847db6e34eSqz150045 } 7857db6e34eSqz150045 7867db6e34eSqz150045 return (0); 7877c478bd9Sstevel@tonic-gate } 7887c478bd9Sstevel@tonic-gate 7897c478bd9Sstevel@tonic-gate static char *usage1 = "kbd [-r] [-t] [-l] [-a enable|disable|alternate]"; 7907c478bd9Sstevel@tonic-gate static char *usage2 = " [-c on|off][-D delay][-R rate][-d keyboard device]"; 7917c478bd9Sstevel@tonic-gate static char *usage3 = "kbd -i [-d keyboard device]"; 7927db6e34eSqz150045 static char *usage4 = "kbd -s [language]"; 793*8ffc942dSrz201010 static char *usage5 = "kbd -b [keyboard|console] frequency"; 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate static void 7967c478bd9Sstevel@tonic-gate usage(void) 7977c478bd9Sstevel@tonic-gate { 798*8ffc942dSrz201010 (void) fprintf(stderr, "Usage:\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n", usage1, 799*8ffc942dSrz201010 usage2, usage3, usage4, usage5); 8007c478bd9Sstevel@tonic-gate } 801