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:
[email protected] (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: <
[email protected]>
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 -
[email protected]
# generously re-posted by Bill Middleton -
[email protected]
# ANSI keycode elaboration, subroutine packaging and
# sample code by Joe Bormel -
[email protected]
# 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 ;