DEFINITION MODULE DMKeyChars;
(*******************************************************************
Module DMKeyChars ('Dialog Machine' DM_V3.0)
Copyright (c) 1995-2006 by Andreas Fischlin and ETH Zurich.
Purpose Routines to interpret keyboard user events
as received by the 'Dialog Machine'.
Remarks This module maps essential keys which are
not already part of the ASCII character set
of various computer platforms, in particular
between Macintosh and IBM PCs, for enhancing
the portability of code. This module belongs to
the "Dialog Machine" and is optional.
Using this module allows for the writing of
more portable applications, in particular
when programming keyboard handlers (see
also module DMMaster, procedure
AddKeyboardHandler) or preparing strings
to be displayed to the user containing
special characters, like bullets, mu, sigma
or other common scientific characters.
This module belongs to the 'Dialog Machine'.
Programming
o Design
Andreas Fischlin 24/10/1995
o Implementation
Andreas Fischlin 24/04/1996
ETH Zurich
Systems Ecology
CHN E 35.1
Universitaetstrasse 16
8092 Zurich
SWITZERLAND
URLs:
<mailto:RAMSES@env.ethz.ch>
<http://www.sysecol.ethz.ch>
<http://www.sysecol.ethz.ch/SimSoftware/RAMSES>
Last revision of definition: 09/04/1997 AF
*******************************************************************)
CONST
(* Mac *) (* Mac or IBM-PC *) (* IBM-PC *)
mouse = 0;
command = 1; (* = control *)
option = 2; alternate = 2;
shift = 3;
capslock = 4;
control = 5;
(*
Above constants denote modifier keys to handle keyboard events with
routine DMMaster.InspectKey.
IMPORTANT NOTE: Command corresponds to the control key. Since
the command key isn't available on the IBM-PC, the DM uses the
control key instead. As a consequence, the DM behaves on the
IBM-PC such that the two keys command and control collapse into
one, and that testing in InspectKey for any of these modifier
keys always implies the other one. To write portable programs,
you should refrain from programing keyboard handlers on the Mac
which rely on being able to differentiate between the keys
command and control, i.e. the pressing of either one of these
keys should already be sufficient for accepting the keyboard
event. For instance to detect in a portable way the pressing of
Control^'A' call DMMaster.InspectKey(ch,m) and then compare:
(CAP(ch)="A") AND ((m={command}) OR (m={control}))
*)
VAR
cursorUp, cursorDown, cursorLeft, cursorRight,
homeKey, endKey, pageUp, pageDown, helpKey,
enter, return, delete, backspace, tab, esc,
hardBlank: CHAR; (* READ ONLY! *)
(*
Above variables denote read only chars which are set by the 'Dialog
Machine' according to the computer system on which it is currently
running. IMPLEMENTATION RESTRICTION: Platforms such as Unix and Mac
OS X encode some of above keys as actually as a series of characters.
E.g. Unix encodes cursor keys as a 3 character sequence 'ESC', '[',
and 'A'..'D' (where A - up, B - down, C - right, D - left). Despite
this fact this module exports only single character encodings. It is
expected that 'Dialog Machine' client programs actually read such
series of key strokes to deduce the actual meaning. They use then
above values exported from this module, to encode the meaning of such
a series of keys. The resulting single key code, can then be handled
semantically by the DM program in a portable manner accross the
various platforms. Sample code to read a line (until EOL) while
interpreting cursor keys:
ch := 0C;
WHILE (i<=n) AND NOT IsEOL(ch) DO
Read(ch); ch1 := 0C;
IF (ch=ESC) AND ((RunsInMacOSX() OR RunsOnAUnixMachine()) THEN
Read(ch);
IF ch = "[" THEN (* is Unix cursor key *)
Read(ch1);
CASE ch1 OF
| "A": ch := cursorUp;
| "B": ch := cursorDown;
| "C": ch := cursorRight;
| "D": ch := cursorLeft;
ELSE
HandleChar(ESC); HandleChar(ch); ch := ch1;
END(*CASE*);
ELSE
HandleChar(ESC);
END(*IF*);
END(*IF*);
HandleChar(ch);
END(*WHILE*);
*)
(************************************************************************
To translate characters which do not belong to the ASCII char set
(>177C) the following routines provide support for programming optimally
portable code.
************************************************************************)
VAR
BestCH: PROCEDURE (CHAR): CHAR;
(*
Use this routine to obtain the best possible character on the
particular target machine. As the actual argument pass the character
as you define it on the machine on which you originally developed the
DM program. BestCH is for efficiency reasons only a procedure
variable. Refrain from overwriting it, it is only for READ ONLY.
Use the routine ProgrammedOn, which sets it according to the machine
on which you programmed the DM program. Example: BestCH('•') (fat
bullet) programmed on a Mac is again a fat bullet if the code is
executed on an IBM PC, but can't do better than 'o' on a plain
vanilla Unix machine. If ProgrammedOn is never called, BestCH
returns the same character as you passed to it, i.e. procedure
Identity (see also comment for procedure ProgrammedOn).
*)
TYPE
ComputerPlatform = (Mac,IBMPCCompatible,UNIXMachine);
PROCEDURE ProgrammedOn (c: ComputerPlatform);
(* Use this routine to assign BestCH a useful translation routine
according to the computer on which you programmed originally the
DM program. Besides, ProgrammedOn is implemented as follows (which
may explain better than words what it actually does:
PROCEDURE ProgrammedOn (c: ComputerPlatform);
BEGIN (* ProgrammedOn *)
CASE c OF
| Mac:
CASE ComputerSystem() OF
| IBMPC..IBMPS2: BestCH := PCCHAR;
| Mac512KE..stillAMac: BestCH := Identity;
ELSE (* SUN..SUNSparc *)
BestCH := MacASCII;
END(*CASE*);
| IBMPCCompatible:
CASE ComputerSystem() OF
| IBMPC..IBMPS2: BestCH := Identity;
| Mac512KE..stillAMac: BestCH := MacCHAR;
ELSE (* SUN..SUNSparc *)
BestCH := PCASCII;
END(*CASE*);
| UNIXMachine:
BestCH := Identity;
END(*CASE*);
END ProgrammedOn;
*)
PROCEDURE PCCHAR (macCh: CHAR): CHAR;
(*
Returns an IBM-PC equivalent of macCh by interpreting macCh as a
Macintosh character. E.g. '£' (Pound on Mac = 243C) becomes 'œ'
(Pound on IBM-PC = 234C) etc. Returns identity for all ASCII chars
<= 177C. Note translation may not always be satisfactory, since the
character sets deviate between the two computer platforms in some
cases too strongly and character resemblance may be very poor.
Furthermore, result may also differ, depending on current keyboard
layout or font in use.
*)
PROCEDURE MacCHAR (pcCh: CHAR): CHAR;
(*
Returns an Macintosh equivalent of pcCh by interpreting pcCh as an
IBM-PC character. E.g. 'œ' (j= Pound on IBM-PC = 234C) becomes '£'
(Pound on Mac = 243C) etc. Returns identity for all ASCII chars <=
177C. Note translation may not always be satisfactory, since the
character sets deviate between the two computer platforms in some
cases too strongly and character resemblance may be very poor.
Furthermore, result may also differ, depending on font in use.
*)
PROCEDURE MacASCII(macCh: CHAR): CHAR;
(*
Returns an ASCII equivalent of the character macCh by interpreting
macCh as a Macintosh character. E.g. '•' (fat bullet) becomes 'o',
or 'ü' (Umlaut) becomes 'u' etc. This routine tries to map any
characters > 177C as close as possible to a char <= 177C; however,
results may be poor and ambiguous and program behavior may become
unpredictable if depending on the mapping.
*)
PROCEDURE PCASCII(pcCh: CHAR): CHAR;
(*
Returns an ASCII equivalent of the character pcCh by interpreting
pcCh as an IBM-PC character. E.g. 'ƒ' (long dash) becomes '-'
(55C), or 'ü' (Umlaut, 232C) becomes 'u' etc. This routine tries to
map any characters > 177C as close as possible to a char <= 177C;
however, results may be poor and ambiguous and program behavior may
become unpredictable if depending on the mapping.
*)
END DMKeyChars.