EKEY return values for some keyboard events

[ RfDs/CfVs | Other proposals ]

Poll standings

See below for voting instructions. The results will be shown here in late August 2006.
Systems
[ ] conforms to ANS Forth.
 iForth
 Gforth
 VFX Forth for Windows/DOS/Linux
 MPE Forth cross compilers
 PFE (Guido Draheim)
[ ] already implements the proposal in full since release [ ]:
 iForth 3.0
[ ] implements the proposal in full in a development version:
[ ] will implement the proposal in full in release [ ].
 Gforth 0.7
 PFE 33.67
[ ] will implement the proposal in full in some future release.
 VFX Forth for Windows/DOS/Linux
There are no plans to implement the proposal in full in [ ].
 4th V3.5a (no EKEY support)
[ ] will never implement the proposal in full:
 MPE Forth cross compilers 
Programmers
[ ] I have used (parts of) this proposal in my programs:
 Robert Epprecht
[ ] I would use (parts of) this proposal in my programs if the systems
    I am interested in implemented it:
 David N. Williams
 Graham Smith
[ ] I would use (parts of) this proposal in my programs if this
    proposal was in the Forth standard:
 Charles Melice
 David N. Williams
 Graham Smith
[ ] I would not use (parts of) this proposal in my programs.
 Hans Bezemer (does not use EKEY)

Change History

2006-06-23
Added EKEY>FKEY after private discussions with Neal Bridges. Wording change in the intro to the actual keys to make their optionality clear. Added some remarks and comments, and adapted title to satisfy commenters.
2006-05-28
Added K-INSERT, K-DELETE, K-F* and K-*-MASK. Added Sections Programming Advice and Shift Keys. Reported comments by various people.

Problem

How do I write a portable Forth program that reacts to key presses of cursor keys (and possibly other keys not represented by ASCII), e.g., an editor?

Proposal

EKEY>FKEY ( u1 -- u2 f ) facility ext
If the keyboard event u1 corresponds to a keypress in the
implementation-defined special key set, return that key's id u2 and
true. Otherwise return u1 and false.
The following words produce the same values that EKEY EKEY>FKEY may produce when the user presses the corresponding key. Note that, even if this extension is present, the keyboard may lack some of the keys, or the system the capability to report them, so programs should be written such that they also work (although less conveniently or with less functionality) if these key numbers cannot be produced.
K-LEFT  ( -- u ) facility ext
The "cursor left" key

K-RIGHT ( -- u ) facility ext
The "cursor right" key

K-UP    ( -- u ) facility ext
The "cursor up" key

K-DOWN  ( -- u ) facility ext
The "cursor down" key

K-HOME  ( -- u ) facility ext
The "home" or "Pos1" key

K-END   ( -- u ) facility ext
The "End" key

K-PRIOR ( -- u ) facility ext
The "PgUp" or "Prior" key

K-NEXT  ( -- u ) facility ext
The "PgDn" or "Next" key

K-INSERT  ( -- u ) facility ext
The "Insert" key

K-DELETE  ( -- u ) facility ext
The "Delete" key

K-F1    ( -- u ) facility ext
The "F1" key

K-F2    ( -- u ) facility ext
The "F2" key

K-F3    ( -- u ) facility ext
The "F3" key

K-F4    ( -- u ) facility ext
The "F4" key

K-F5    ( -- u ) facility ext
The "F5" key

K-F6    ( -- u ) facility ext
The "F6" key

K-F7    ( -- u ) facility ext
The "F7" key

K-F8    ( -- u ) facility ext
The "F8" key

K-F9    ( -- u ) facility ext
The "F9" key

K-F10    ( -- u ) facility ext
The "F10" key

K-F11    ( -- u ) facility ext
The "F11" key

K-F12    ( -- u ) facility ext
The "F12" key
The following words produce a mask, that you can OR with the key values above to produce a value that EKEY EKEY>FKEY may produce when the user presses the corresponding key combination.
K-SHIFT-MASK ( -- u ) facility ext
Mask for the shift key

K-CTRL-MASK ( -- u ) facility ext
Mask for the ctrl key

K-ALT-MASK ( -- u ) facility ext
Mask for the alt key

Typical Use

... ekey ekey>fkey if
 case
  k-up                                  of ... endof
  k-f1                                  of ... endof
  k-left k-shift-mask or k-ctrl-mask or of ... endof
  ...
 endcase
else
 ...
then

Remarks

EKEY>FKEY
Introducing that word leaves more freedom to implementations about the representation of EKEY results. In particular, based on private discussions, it would be easier for Neal Bridges to implement the proposal in Quartus Forth. Systems that do not need this additional freedom could use the same representation for the EKEY and EKEY>FKEY results; a simple implementation of EKEY>FKEY on such a system would be:
: EKEY>FKEY ( u1 -- u2 flag )
  dup ekey>char nip 0= ;
EKEY return values
There was a discussion about what the standard says about EKEY return values. In particular, I interpret the standard's non-specification of a lifetime for the return value as meaning that it has unlimited lifetime and thus an implementation where the return value is an address of an overwritable buffer is non-standard; whereas Elizabeth Rather believes that the implementation-defined nature of the result would make such an EKEY implementation standard. However, no such implementation of EKEY is known, and a clarification of that aspect is desirable. However, with the introduction of EKEY>FKEY the proposal could even be implemented on a system with such an EKEY implemenmtation, so the place for the clarification is probably not in this proposal (unless we take EKEY>FKEY out again).
Programming advice
Note that, even if a Forth system supports these words, many environments do not have or do not report all these keys and key combinations, so it is a good idea to write your program such that it is still useful even if these keys and key combinations cannot be pressed or are not recognized.
Shift keys
Note that, as defined, the shift key masks defined above are only useful for recognizing shifted cursor and function keys, because these are the only keys that EKEY return values are defined for. E.g., we cannot program Forth to recognize ALT-T, because no EKEY return value for T has been defined.
Other Keys
Gforth and PFE have words K1...K10 for the function/keypad keys; they also contain S-K1...S-K10 for shifted function/keypad keys, but they don't work as widely. Moreover, Gforth (but not PFE) also has K-INSERT K-DELETE K11 K12 S-K11 S-K12. Should any of these words be added to this proposal? After the first RfD, several people were in favour of adding such words and nobody spoke out against, so I added the words after K-NEXT. If you don't like such words in general, or would like them, but differently, please speak up now.

Experience

These words have been implemented for several years in PFE and Gforth. Several editors have been published in ANS Forth that would have profited from these words. Also, the original version of the MiniSpreadsheet hardcoded the values for the keys for one platform; I then fixed it to use the cursor-key words proposed above.

Implementation and Tests

The implementation is closely tied to the implementation of EKEY, and therefore unportable, so I don't provide a reference implementation. However, you can look at the Gforth implementation of EKEY and many of these words (based on ANSI terminal escape sequences).

Tests

Comments

Alex McDonald writes:
Win32Forth provides;

k_home k_up k_pgup k_left k_right  k_end k_down k_pgdn k_insert
k_delete k_scroll

plus k_1 through k_12 for function keys.

+k_control +k_alt +k_shift provide a mask when these keys are depressed
with any of the above.

Marcel Hendrix writes <13073534183561@frunobulax.edu> that iForth implements this functionality, but with different key names.

Mitch Bradley reports that the current proposal cannot be implemented in a useful way on the current Quartus Forth even though the platform has some arrow buttons. Quartus Forth implements an EKEY that just returns an event type (and requires the use of another word to get more information).

Charles Melice and Alex McDonald would prefer K-F1 etc. for function keys, and masks for shifted keys etc.

Charles Melice would also like to see some events defined for mouse events (<44734824$0$20278$ba620e4c@news.skynet.be> ff.). There was some discussion on how that should be done; however, it will not be done in this proposal.

Sam Falvo also has some interesting suggestions in this area <1149102251.881940.142140@j55g2000cwa.googlegroups.com> that might be interesting for a future RfD.

Charles Melice also proposed <447c27b5$0$23533$ba620e4c@news.skynet.be> having a word EKEY>FKEY and standardizing the numeric FKEY values to make it easier to save, exchange, and replay these keys between systems.

Robert Epprecht uses these words and would like to have them available in different Forth implementations. Also, he would like to see the words for the function keys.

Voting instructions

Fill out the appropriate ballot(s) below and mail it/them to me <anton@mips.complang.tuwien.ac.at>. Your vote will be published (including your name (without email address) and/or the name of your system) here. You can vote (or change your vote) at any time by mailing to me, and the results will be published here.

Note that you can be both a system implementor and a programmer, so you can submit both kinds of ballots.

Ballot for systems

If you maintain several systems, please mention the systems separately in the ballot. Insert the system name or version between the brackets. Multiple hits for the same system are possible (if they do not conflict).
[ ] conforms to ANS Forth.
[ ] already implements the proposal in full since release [ ].
[ ] implements the proposal in full in a development version.
[ ] will implement the proposal in full in release [ ].
[ ] will implement the proposal in full in some future release.
There are no plans to implement the proposal in full in [ ].
[ ] will never implement the proposal in full.
If you want to provide information on partial implementation, please do so informally, and I will aggregate this information in some way.

Ballot for programmers

Just mark the statements that are correct for you (e.g., by putting an "x" between the brackets). If some statements are true for some of your programs, but not others, please mark the statements for the dominating class of programs you write.
[ ] I have used (parts of) this proposal in my programs.
[ ] I would use (parts of) this proposal in my programs if the systems
    I am interested in implemented it.
[ ] I would use (parts of) this proposal in my programs if this
    proposal was in the Forth standard.
[ ] I would not use (parts of) this proposal in my programs.
If you feel that there is closely related functionality missing from the proposal (especially if you have used that in your programs), make an informal comment, and I will collect these, too. Note that the best time to voice such issues is the RfD stage.
Anton Ertl