wagner@iaoobelix.UUCP (04/16/87)
Subject: Bell on SUN-3 Workstation Apparently, it is impossible to let the Sun console beep without using `window_bell'. Does anybody out there know of a possiblity other than this function (e.g. by accessing the keyboard bell) to generate a beep? Juergen Wagner, (USENET) ...seismo!unido!iaoobel!wagner ("Gandalf") Fraunhofer Institute IAO, Stuttgart
guy%gorodish@Sun.COM (Guy Harris) (04/21/87)
> Apparently, it is impossible to let the Sun console beep without using > `window_bell'. Does anybody out there know of a possiblity other than this > function (e.g. by accessing the keyboard bell) to generate a beep? As the saying goes, "seek and ye shall find". Seek in the documentation first, and you stand a good chance of finding without having to ask. Quoting from our documentation (KB(4S) in the 3.2 UNIX Interface Reference, although it's in the 3.0 documentation as well): Keyboard Commands The call KIOCCMD sends a command to the keyboard: /* * Commands to the Sun-2 keyboard. */ #define KBD_CMD_RESET 0x01 /* Reset keyboard as if power-up */ #define KBD_CMD_BELL 0x02 /* Turn on the bell */ #define KBD_CMD_NOBELL 0x03 /* Turn off the bell */ /* * Commands to the Sun-3 keyboard. KBD_CMD_BELL & KBD_CMD_NOBELL * work as well. */ #define KBD_CMD_CLICK 0x0A /* Turn on the click annunciator */ #define KBD_CMD_NOCLICK 0x0B /* Turn off the click annunciator */ int x; err = ioctl(fd, KIOCCMD, &x); Inappropriate commands for particular keyboard types are ignored. Since there is no reliable way to get the state of the bell or click (because we can't query the keyboard, and also because a process could do writes to the appropriate serial driver -- thus going around this 'ioctl') we don't provide an equivalent "ioctl" to query its state. The "ioctl"s are defined in <sys/kbio.h> and the commands are defined in <sys/kbd.h>. This "ioctl" should be issued on "/dev/kbd" or whatever keyboard you're running from. All "win_bell" does to generate an audible bell is to: open the keyboard for the current screen do a KIOCCMD with a pointer to a variable containing KBD_CMD_BELL sleep for the specified interval of time do a KIOCCMD with a pointer to a variable containing KBD_CMD_NOBELL close the keyboard (The KBD_CMD_CLICK/KBD_CMD_NOCLICK stuff is for turning keyclick mode on and off.) No muss, no fuss, and *especially* no need for "/dev/bell" (which is not a supported item, so there's no guarantee that it will work on future keyboards).
jpn@teddy.UUCP (04/23/87)
>Apparently, it is impossible to let the Sun console beep without using >`window_bell'. Does anybody out there know of a possiblity other than this >function (e.g. by accessing the keyboard bell) to generate a beep? For your beeping pleasure: beep.c ------------------ #include <ctype.h> #include <sys/types.h> #include <sys/time.h> #include <sundev/kbd.h> #include <sundev/kbio.h> #define BELL 0x07 /* Control-G */ #define NULL 0 main(argc, argv) int argc; char **argv; { int bell; int cmd; int iterations = 1; static struct timeval ring_time = {0, 100000}; static struct timeval pause_time = {0, 50000}; if ( argc > 1 && isdigit(argv[1][0])) { iterations = atoi(argv[1]); } if ( (bell = open("/dev/kbd",2)) < 0 ) { /* no /dev/kbd. Fail gracefully */ char out; out = BELL; write(1, &out, 1); exit(0); } do { cmd = KBD_CMD_BELL; ioctl(bell, KIOCCMD, &cmd); select(0, NULL, NULL, NULL, &ring_time); cmd = KBD_CMD_NOBELL; ioctl(bell, KIOCCMD, &cmd); if (iterations > 1) select(0, NULL, NULL, NULL, &pause_time); } while (--iterations > 0); exit(0); }
watson@ames.UUCP (04/30/87)
Here is a morse code program for Sun workstations. I wrote this after reading the discusion of Sun's bell in in the news group comp.unix.questions. Have fun. # #--------------- cut here ------------------------------------------ # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by kirin!watson on Wed Apr 29 17:21:44 PDT 1987 # Contents: morse.c echo x - morse.c sed 's/^@//' > "morse.c" <<'@//E*O*F morse.c//' /* * Morse Code Program for Suns Version 1.0 * * Here is a little program I wrote that converts standard input * to morse code. The Sun's bell is used to beep the code. * The speed of the generated beeps vary, depending on the model of Sun. * Speed can be changed with the optional first argument on the command * line: * * % morse 2 # is twice as fast * % morse 4 # is 3 times a fast * % morse -2 # is twice as slow * % morse -3 # is 3 times a slow * * It can be used across a network with remote shell: * * % rsh remote_host morse * * Or with pipes: * * % fortune | morse * * I have not include all the character set. ( ?, !, -, etc. ) * New characters can be easily added to the big case statement in main. * * I don't have time to work with this anymore so don't send the bugs to me. * Send me better versions though :^) * * Oh yeah, this works on Suns version 3.2 of the UNIX4.3bsd operating system. * compile with: * % cc morse.c -o morse -O * * * Have fun! * John S. Watson 4/29/87 */ #include <stdio.h> #include <sys/types.h> #include <sys/file.h> #include <sundev/kbd.h> #include <sundev/kbio.h> int keyboard; int scale = 3000; int factor = 1; unit_pause( number) int number; { int i; for ( i = 0; i < number* (int) scale; i++); } dit() { int on = KBD_CMD_BELL; int off = KBD_CMD_NOBELL; int i; ioctl(keyboard, KIOCCMD, &on); unit_pause(1); ioctl(keyboard, KIOCCMD, &off); unit_pause(1); } da() { int on = KBD_CMD_BELL; int off = KBD_CMD_NOBELL; int i; ioctl(keyboard, KIOCCMD, &on); unit_pause( 3); ioctl(keyboard, KIOCCMD, &off); unit_pause( 1); } read_line( buffer) char buffer[]; { char character; int i = 0; do { character = getchar(); if ( feof(stdin) ) exit(0); buffer[i] = character; ++i; } while( character != '\n' ); buffer[ i - 1 ] = '\0'; } init_keyboard() { keyboard = open("/dev/kbd", O_RDWR, 0666); if (keyboard < 0) { perror("/dev/kbd"); exit(1); } return( keyboard); } main(argc, argv) int argc; char **argv; { int i; char line[81]; if ( argc == 2 ) { factor = atoi( argv[1]); if ( factor > 0) scale /= factor; else scale *= -factor; if ( (int) scale == 0) { fprintf(stderr, "can't go that fast\n"); exit(0); } } init_keyboard(); while ( 1) { read_line( line); for ( i = 0; i < strlen( line) ; i++) { unit_pause( 2); switch( line[i] ) { case 'A' : case 'a' : dit(); da(); break; case 'B' : case 'b' : da(); dit(); dit(); break; case 'C' : case 'c' : da(); dit(); da(); dit(); break; case 'D' : case 'd' : da(); dit(); dit(); break; case 'E' : case 'e' : dit(); break; case 'F' : case 'f' : dit(); dit(); da(); dit(); break; case 'G' : case 'g' : da(); da(); dit(); break; case 'H' : case 'h' : dit(); dit(); dit(); dit(); break; case 'I' : case 'i' : dit(); dit(); break; case 'J' : case 'j' : dit(); da(); da(); da(); break; case 'K' : case 'k' : da(); dit(); da(); break; case 'L' : case 'l' : dit(); da(); dit(); dit(); break; case 'M' : case 'm' : da(); da(); break; case 'N' : case 'n' : da(); dit(); break; case 'O' : case 'o' : da(); da(); da(); break; case 'P' : case 'p' : dit(); da(); da(); dit(); break; case 'Q' : case 'q' : da(); da(); dit(); da(); break; case 'R' : case 'r' : dit(); da(); dit(); break; case 'S' : case 's' : dit(); dit(); dit(); break; case 'T' : case 't' : da(); break; case 'U' : case 'u' : dit(); dit(); da(); break; case 'V' : case 'v' : dit(); dit(); dit(); da(); break; case 'W' : case 'w' : dit(); da(); da(); break; case 'X' : case 'x' : da(); dit(); dit(); da(); break; case 'Y' : case 'y' : da(); dit(); da(); da(); break; case 'Z' : case 'z' : da(); da(); dit(); dit(); break; case '0' : da(); da(); da(); da(); da(); break; case '1' : dit(); da(); da(); da(); da(); break; case '2' : dit(); dit(); da(); da(); da(); break; case '3' : dit(); dit(); dit(); da(); da(); break; case '4' : dit(); dit(); dit(); dit(); da(); break; case '5' : dit(); dit(); dit(); dit(); dit(); break; case '6' : da(); dit(); dit(); dit(); dit(); break; case '7' : da(); da(); dit(); dit(); dit(); break; case '8' : da(); da(); da(); dit(); dit(); break; case '9' : da(); da(); da(); da(); dit(); break; case ',' : da(); da(); dit(); dit(); da(); da(); break; case '.' : dit(); da(); dit(); da(); dit(); da(); break; /* * add new characters here! */ case ' ' : default : unit_pause(5); break; } } } } @//E*O*F morse.c// chmod u=rw,g=r,o=r morse.c exit 0 -- John S. Watson NASA Ames Research Center ARPA: watson@ames.arpa UUCP: ...!ames!watson
chris@mimsy.UUCP (04/30/87)
In article <1415@ames.UUCP> watson@ames.UUCP (John S. Watson) writes: >Here is a morse code program for Sun workstations. John's program works, but, being a fan of data structures, I had to rewrite it. Also, his tends to use inordinate amounts of CPU time, to run at different speeds on different kinds of Suns, and to sound somewhat lopsided if you had something in the background. Moreover, if you interrupted it, it might leave the bell on, which is decidedly annoying. This version's output is essentially identical. The single optional argument specifies the number of milliseconds for the basic time unit (default 30). The Sun timer resolution is somewhat low, and values between 21 and 30 all act the same, and 20 runs 50% faster than these; this is an annoyance, but it does keep the CPU time down. /* * Morse Code Program for Suns * * Inspired by version by: * John S. Watson 4/29/87 * NASA Ames Research Center * ARPA: watson@ames.arpa * UUCP: ...!ames!watson * * This version by: * Chris Torek 4/29/87 * University of Maryland * Department of Computer Science * (chris@mimsy.umd.edu) */ #include <stdio.h> #include <ctype.h> #include <signal.h> #include <sys/types.h> #include <sys/file.h> #include <sys/time.h> #include <sundev/kbd.h> #include <sundev/kbio.h> /* * Morsetab[] contains the `visual form' rendition of each known * character. All other characters act as word separators, hence * there is no need for an entry for space. * * The encode() function puts a pointer to the valid codes in the * table codetab[]; the invalid ones remain NULL. The code translation * table is 256 entries, and the initialisation of the array is * portable to EBCDIC (among others). * * N.B.: all of the code values in morsetab[] must be valid input * character codes. */ struct morse { int m_code; /* the input character (lowercase) */ char *m_rend; /* and its rendition */ } morsetab[] = { 'a', ".-", 'b', "-..", 'c', "-.-.", 'd', "-..", 'e', ".", 'f', "..-.", 'g', "--.", 'h', "....", 'i', "..", 'j', ".---", 'k', "-.-", 'l', ".-..", 'm', "--", 'n', "-.", 'o', "---", 'p', ".--.", 'q', "--.-", 'r', ".-.", 's', "...", 't', "-", 'u', "..-", 'v', "...-", 'w', ".--", 'x', "-..-", 'y', "-.--", 'z', "--..", '0', "-----", '1', ".----", '2', "..---", '3', "...--", '4', "....-", '5', ".....", '6', "-....", '7', "--...", '8', "---..", '9', "----.", ',', "--..--", '.', ".-.-.-", -1, NULL /* end marker */ }; char *codetab[256]; /* convert X to milliseconds (in scale factors) */ #define MS(x) ((x) * 1000) char *progname; long scale = MS(30); int keyboard; int bell_on = KBD_CMD_BELL; int bell_off = KBD_CMD_NOBELL; #define FEEP() (void) ioctl(keyboard, KIOCCMD, (char *) &bell_on) #define UNFEEP() (void) ioctl(keyboard, KIOCCMD, (char *) &bell_off) /* * Pause for number counts. Number must not be `large'. */ unit_pause(number) int number; { struct timeval tv; #define USEC 1000000 /* microseconds per second */ /* this value may be >= 1e6 */ tv.tv_usec = number * scale; tv.tv_sec = tv.tv_usec / USEC; tv.tv_usec -= tv.tv_sec * USEC; (void) select(0, (int *)0, (int *)0, (int *)0, &tv); } /* * Do a dit (if it) or dah (if not). */ d(it) int it; { FEEP(); unit_pause(it ? 1 : 3); UNFEEP(); unit_pause(1); } /* * Build the input character translation table. */ encode() { register struct morse *p; register int i; for (p = morsetab; p->m_rend != NULL; p++) { i = p->m_code; if (codetab[i] != NULL) goto bug; codetab[i] = p->m_rend; if (islower(i)) { i = toupper(i); if (codetab[i] != NULL) { bug: (void) fprintf(stderr, "%s: panic: codetab[%d] != NULL\n", progname, i); exit(1); } codetab[i] = p->m_rend; } } } init_keyboard() { keyboard = open("/dev/kbd", O_RDWR, 0666); if (keyboard < 0) { (void) fprintf(stderr, "%s: cannot open ", progname); perror("/dev/kbd"); exit(1); } } /* * `Print' the contents of file f in morse code. */ morse(f) register FILE *f; { register int c; register char *mp; int inword = 0; while ((c = getc(f)) != EOF) { if ((mp = codetab[c]) == NULL) { if (inword) { unit_pause(5); inword = 0; } continue; } inword = 1; while ((c = *mp++) != 0) d(c == '.'); unit_pause(2); } } catch() { UNFEEP(); exit(1); } set(sig, disp) int sig, (*disp)(); { #if defined(sun) && defined(lint) /* Sun 3.0 lint library is wrong */ if (signal(sig, (void (*)()) SIG_IGN) != SIG_IGN) (void) signal(sig, (void (*)()) disp); #else if (signal(sig, SIG_IGN) != SIG_IGN) (void) signal(sig, disp); #endif } main(argc, argv) int argc; char **argv; { progname = argv[0]; set(SIGHUP, catch); set(SIGQUIT, catch); set(SIGINT, catch); set(SIGTERM, catch); if (argc >= 2) { scale = MS(atoi(argv[1])); if (scale < MS(1)) { (void) fprintf(stderr, "%s: can't go that fast\n", progname); exit(1); } } init_keyboard(); encode(); morse(stdin); exit(0); } -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: seismo!mimsy!chris
hp@beta.UUCP (Akkana) (04/30/87)
I'm new to this newsgroup, so I may have missed a posting, but ... I know about KBD_CMD_BELL and all that -- found it in the manual and wrote a quickie beep routine for the Sun console -- but am I the only one in the world bothered by the fact that ^G doesn't beep a Sun console the way it does (practically) ever other terminal ever made? I've complained to Sun numerous times about how my 3/160 console doesn't beep when I print a ^G -- which means that programs like talk and vi can't notify me, because THEY don't do the kbd ioctl, and also that I won't be notified if I'm rlogged in from another Sun, because if I try to do the ioctl it will come out on the wrong screen. Finally, it means that in all my programs I have to do something like #ifdef sun #include <sundev/kbd.h> #include <sundev/kbio.h> #endif . . #ifdev KBD_CMD_BELL /* if we're on a Sun3, or at least 3.x */ if (on_console) /* Need to check at beginning of program * to make sure we're on the console so * we don't beep it if someone else is on it */ ioctl( ...etc ) else #else putchar('\07'); #endif I mean, it wasn't that hard to figure out, but it's a little inelegant to have to put that into every single program, and Sun didn't do it when they wrote talk and vi. After six months of hearing me talk about it, the local Sun reps finally told me that there was an ECO which would fix the problem, and came out to install a new CPU board (note that I had to be on hardware maintenance to get this fixed). A week and two CPU boards later (the first one they sent out didn't work, and it took several hours to get the second one working, for some reason) I finally had a machine which supposedly beeped -- and guess what? It's still barely audible -- too short and too quiet to be heard when I'm standing across the room (i.e. talk still can't notify me when someone's trying to talk to me). And echoing several ^G's is even less audible than echoing just one. The Sun2/170 (2.2) I used to use had a wonderful ^G -- it was nice and loud without being too obnoxious, and if I wanted something really obnoxious I could always say "echo ^G^G^G^G^G^G^G^G^G^G^G^G^G^G" and get a long, continuous bell which I couldn't fail to hear. I'd like to be able to do that on my Sun3 without having to write a C program (and compile it into all the system programs and PD programs off the net and so forth) to do it. Isn't anyone else bothered by it? I'm sure it's an easy fix -- I've asked Sun several times why it isn't possible simply to take the source for the console driver, find the part where it interprets a ^G, lengthen the time before the KBD_CMD_NOBELL ioctl, and recompile; Sun is convinced that it's a hardware problem and changing software won't help it. Has anybody with source tried it? (We're in the process of trying to get source, but it hasn't happened yet.) Is there something wrong with my reasoning? Is it really a hardware problem? Do other 3.x Sun3's beep loudly, and mine just happens to have a strange problem? .. ...Akkana Center for Nonlinear Studies, LANL akkana%cnls@lanl.arpa hp@lanl.arpa ihnp4!lanl!hp "I think I'll take a walk. Hmm, wonder where this wire goes?" -- Max Headroom