Article 9084 of comp.lang.perl: Xref: feenix.metronet.com comp.lang.perl:9084 Path: feenix.metronet.com!news.ecn.bgu.edu!usenet.ins.cwru.edu!howland.reston.ans.net!spool.mu.edu!bloom-beacon.mit.edu!senator-bedfellow.mit.edu!jbormel From: jbormel@athena.mit.edu (Joe Bormel) Newsgroups: comp.lang.perl Subject: CBREAK mode in MS-DOS ==== SAMPLE CODE ==== Date: 21 Dec 1993 22:58:51 GMT Organization: Massachusetts Institute of Technology Lines: 253 Distribution: world Message-ID: <2f7v3b$5f1@senator-bedfellow.MIT.EDU> NNTP-Posting-Host: hstbme.mit.edu Thanks to everyone who responded to my plea for help to get CBREAK functionality in PERL for MS-DOS. I've packaged up the results into an executable DOS batch file to serve as sample code for others. --------cut here and place in a file named keybd.bat---type: keybd at c> @REM=(qq! @perl %0.bat %1 %2 %3 %4 %5 %6 %7 %8 %9 @goto end !) if 0 ; # Name: keybd.bat # Purpose: MS-DOS program to demonstrate entering 'CBREAK' mode # and see keystrokes as they happen instead of a line # at a time after the ENTER key had been pressed. # Source: Source modified from usenet posting: # original by Dan Carson - dbc@tc.fluke.COM # generously re-posted by Bill Middleton - wjm@metronet.com # ANSI keycode elaboration, subroutine packaging and # sample code by Joe Bormel - jbormel@hstbme.mit.edu # Date: 1993 # Note: This will not work with BPERL because: # * The ioctl() is not supported because of problems translating data # structures between real and protected modes in BPERL. It does work # with PERL v4.0 patchlevel 36/ header below:] # # # $RCSfile: perl.c,v $$Revision: 4.0.1.8 $$Date: 1993/02/05 19:39:30 $ # Patch level: 36 # # Copyright (c) 1989, 1990, 1991, Larry Wall # MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis. # # It is ftp'able as bin4036.zip (148,895 bytes). # # Bugs/Peculiarities: You had to press ENTER or control/M twice to get # it to register once. #------------------------------------------------------------------------- &keymap_table; # Instantiate assoc array of keyboard mappings. &raw; print "Demonstration showing: &raw, &getkey, &cooked.\n"; print " Exit by typing control/Z\n"; while($c ne "0;0"){ $c= &getkey; print "<$c>" if ord($c) != 0; } &cooked; #------------------------------------------------------------------------- sub raw { $old_ioctl = ioctl(STDIN,0,0); # Gets device info $old_ioctl &= 0xff; ioctl(STDIN,1,$old_ioctl | 32); # Writes it back, setting bit 5 } #------------------------------------------------------------------------- sub cooked { ioctl(STDIN,1,$old_ioctl); # Sets PC back to cooked mode. } #------------------------------------------------------------------------- sub getkey { local($key,$td,$val); sysread(STDIN,$key,1); # Read a single character $val = ord($key); return $key if $val>=32; # Return simple typewriter keys. if ($val == 0) { # handle 2 code keys. sysread(STDIN,$key2,1); # Read the second character. $td = "0;" . ord($key2); if (defined $KBMap{$td}) { $key = $KBMap{$td}; } else { $key = $td;} } elsif ($val < 32) { $key = "Ctrl+" . pack("c",$val+64); } $key; } #------------------------------------------------------------------------- sub keymap_table { ## Load an associative array with names for keycodes ## # Note that the function key mapping is done below. If you need # any other keys, this program will show you what the codes coming # back from your keyboard really are. Below is a listing of how # the ANSI codes are defined. Just follow the format of the function # key definitions, e.g. $KBMap{"0;61"} = "F3"; to add any others you need. @Embedded_Documentation=(qq~ +======================================================================+ | Key Key Shft+Key Ctrl+Key Alt+Key | +======================================================================+ | F1 0;59 0;84 0;94 0;104 | | F2 0;60 0;85 0;95 0;105 | | F3 0;61 0;86 0;96 0;106 | | F4 0;62 0;87 0;97 0;107 | | F5 0;63 0;88 0;98 0;108 | | F6 0;64 0;89 0;99 0;109 | | F7 0;65 0;90 0;100 0;110 | | F8 0;66 0;91 0;101 0;111 | | F9 0;67 0;92 0;102 0;112 | | F10 0;68 0;93 0;103 0;113 | | F11 0;133 0;135 0;137 0;139 | | F12 0;134 0;136 0;138 0;140 | | Kp-Home 0;71 55 0;119 | | Kp-UpArrow 0;72 56 0;141 (Note: Kp = keypad | | Kp-PgUp 0;73 57 0;132 key with| | Kp-LftArrow 0;75 52 0;115 NumLock | | Kp-RtArrow 0;77 54 0;116 on) | | Kp-End 0;79 49 0;117 | | Kp-DnArrow 0;80 50 0;145 | | Kp-PgDn 0;81 51 0;118 | | Kp-Insert 0;82 48 0;146 | | Kp-Delete 0;83 46 0;147 | | Home 224;71 224;71 224;119 224;151 | | UpArrow 224;72 224;72 224;141 224;152 | | PgUp 224;73 224;73 224;132 224;153 | | LftArrow 224;75 224;75 224;115 224;155 | | RtArrow 224;77 224;77 224;116 224;157 | | End 224;79 224;79 224;117 224;159 | | DnArrow 224;80 224;80 224;145 224;160 | | PgDn 224;81 224;81 224;118 224;161 | | Insert 224;82 224;82 224;146 224;162 | | Delete 224;83 224;83 224;147 224;163 | | PrtScreen 0;114 | | Pause/Break 0;0 | | Backspace 8 8 127 0;14 | | Enter 13 13 10 0;28 | | Tab 9 0;15 0;148 0;165 | +======================================================================+ | Key Key Shft+Key Ctrl+Key Alt+Key | +======================================================================+ | A 97 65 1 0;30 | | B 98 66 2 0;48 | | C 99 67 3 0;46 | | D 100 68 4 0;32 | | E 101 69 5 0;18 | | F 102 70 6 0;33 | | G 103 71 7 0;34 | | H 104 72 8 0;35 | | I 105 73 9 0;23 | | J 106 74 10 0;36 | | K 107 75 11 0;37 | | L 108 76 12 0;38 | | M 109 77 13 0;50 | | N 110 78 14 0;49 | | O 111 79 15 0;24 | | P 112 80 16 0;25 | | Q 113 81 17 0;16 | | R 114 82 18 0;19 | | S 115 83 19 0;31 | | T 116 84 20 0;20 | | U 117 85 21 0;22 | | V 118 86 22 0;47 | | W 119 87 23 0;17 | | X 120 88 24 0;45 | | Y 121 89 25 0;21 | | Z 122 90 26 0;44 | +======================================================================+ | Key Key Shft+Key Ctrl+Key Alt+Key | +======================================================================+ | 1 49 33 0;120 | | 2 50 64 0;121 | | 3 51 35 0;122 | | 4 52 36 0;123 | | 5 53 37 0;124 | | 6 54 94 30 0;125 | | 7 55 38 0;126 | | 8 56 42 0;127 | | 9 57 40 0;128 | | 0 48 41 0;129 | | - 45 95 31 0;130 | | = 61 43 0;131 | | [ 91 123 27 0;26 | | \ 92 124 28 0;43 | | ] 93 125 29 0;27 | | ; 59 58 0;39 | | ' 39 34 0;40 | | , 44 60 0;51 | | . 46 62 0;52 | | / 47 63 0;53 | | Kp-Enter 13 13 10 0;166 | | Kp- / 47 47 0;149 0;164 | | Kp- * 42 42 0;150 0;55 | | Kp- - 45 45 0;142 0;74 | | Kp- + 43 43 0;144 0;78 | | Kp- 5 0;76 53 0;143 | +======================================================================+ ~) if 0 ; # End of: @Embedded_Documentation $KBMap{"0;59"} = "F1"; $KBMap{"0;60"} = "F2"; $KBMap{"0;61"} = "F3"; $KBMap{"0;62"} = "F4"; $KBMap{"0;63"} = "F5"; $KBMap{"0;64"} = "F6"; $KBMap{"0;65"} = "F7"; $KBMap{"0;66"} = "F8"; $KBMap{"0;67"} = "F9"; $KBMap{"0;68"} = "F10"; $KBMap{"0;133"} = "F11"; $KBMap{"0;134"} = "F12"; $KBMap{"0;84"} = "Shft+F1"; $KBMap{"0;85"} = "Shft+F2"; $KBMap{"0;86"} = "Shft+F3"; $KBMap{"0;87"} = "Shft+F4"; $KBMap{"0;88"} = "Shft+F5"; $KBMap{"0;89"} = "Shft+F6"; $KBMap{"0;90"} = "Shft+F7"; $KBMap{"0;91"} = "Shft+F8"; $KBMap{"0;92"} = "Shft+F9"; $KBMap{"0;93"} = "Shft+F10"; $KBMap{"0;135"} = "Shft+F11"; $KBMap{"0;136"} = "Shft+F12"; $KBMap{"0;94"} = "Ctrl+F1"; $KBMap{"0;95"} = "Ctrl+F2"; $KBMap{"0;96"} = "Ctrl+F3"; $KBMap{"0;97"} = "Ctrl+F4"; $KBMap{"0;98"} = "Ctrl+F5"; $KBMap{"0;99"} = "Ctrl+F6"; $KBMap{"0;100"} = "Ctrl+F7"; $KBMap{"0;101"} = "Ctrl+F8"; $KBMap{"0;102"} = "Ctrl+F9"; $KBMap{"0;103"} = "Ctrl+F10"; $KBMap{"0;137"} = "Ctrl+F11"; $KBMap{"0;138"} = "Ctrl+F12"; $KBMap{"0;104"} = "Alt+F1"; $KBMap{"0;105"} = "Alt+F2"; $KBMap{"0;106"} = "Alt+F3"; $KBMap{"0;107"} = "Alt+F4"; $KBMap{"0;108"} = "Alt+F5"; $KBMap{"0;109"} = "Alt+F6"; $KBMap{"0;110"} = "Alt+F7"; $KBMap{"0;111"} = "Alt+F8"; $KBMap{"0;112"} = "Alt+F9"; $KBMap{"0;113"} = "Alt+F10"; $KBMap{"0;139"} = "Alt+F11"; $KBMap{"0;140"} = "Alt+F12"; } @REM=(qq! :end !) if 0 ;