home *** CD-ROM | disk | FTP | other *** search
- -> rawkey.e - How to correctly convert from RAWKEY to keymapped ASCII
-
- MODULE 'console',
- 'devices/inputevent',
- 'devices/timer',
- 'exec/io',
- 'intuition/intuition'
-
- ENUM ERR_NONE, ERR_DEV, ERR_WIN
-
- RAISE ERR_DEV IF OpenDevice()<>0,
- ERR_WIN IF OpenWindowTagList()=NIL
-
- -> A buffer is created for RawKeyConvert() to put its output. BUFSIZE is the
- -> size of the buffer in bytes. NOTE that this program starts out with a
- -> buffer size of 2. This is only to show how the buffer is automatically
- -> increased in size by this example! In an application, start with a much
- -> larger buffer and you will probably never have to increase its size. 128
- -> bytes or so should do the trick, but always be able to change the size if
- -> required.
- CONST BUFSIZE=2
-
- PROC main() HANDLE
- DEF win=NIL, ioreq:iostd, ievent=NIL:PTR TO inputevent,
- buffer=NIL, bufsize=BUFSIZE
- -> Open the console device just to do keymapping. (unit -1 means any unit)
- OpenDevice('console.device', -1, ioreq, 0)
- consoledevice:=ioreq.device
- -> Allocate the initial character buffer used by deadKeyConvert() and
- -> RawKeyConvert() for returning translated characters. If the characters
- -> generated by these routines cannot fit into the buffer, the application
- -> must pass a larger buffer. This is done in this code by freeing the old
- -> buffer and allocating a new one.
- buffer:=NewR(bufsize)
- NEW ievent
- win:=OpenWindowTagList(NIL,
- [WA_WIDTH, 300,
- WA_HEIGHT, 50,
- WA_FLAGS, WFLG_DEPTHGADGET OR WFLG_CLOSEGADGET OR WFLG_ACTIVATE,
- WA_IDCMP, IDCMP_CLOSEWINDOW OR IDCMP_RAWKEY,
- WA_TITLE, 'Raw Key Example',
- NIL])
- WriteF('Press keyboard keys to see ASCII conversion from rawkey\n')
- WriteF('Unprintable characters will be shown as \c\n\n', $7F)
- process_window(win, ievent, {buffer}, {bufsize})
-
- EXCEPT DO
- IF win THEN CloseWindow(win)
- -> E-Note: don't need to free any memory -- automatically done
- IF consoledevice THEN CloseDevice(ioreq)
- SELECT exception
- CASE ERR_DEV; WriteF('Error: Failed to open console device.\n')
- CASE ERR_WIN; WriteF('Error: Failed to open window.\n')
- CASE "MEM"; WriteF('Error: Ran out of memory.\n')
- ENDSELECT
- ENDPROC
-
- -> Convert RAWKEYs into VANILLAKEYs, also shows special keys like HELP, Cursor
- -> Keys, FKeys, etc. It returns:
- -> -1 if not enough room in the buffer, try again with a bigger buffer.
- -> otherwise, returns the number of characters placed in the buffer.
- PROC deadKeyConvert(kbuffer, kbsize, kmap, ievent:PTR TO inputevent)
- ievent.class:=IECLASS_RAWKEY
- ievent.code:=MsgCode()
- ievent.qualifier:=MsgQualifier()
- ievent.eventaddress:=MsgIaddr()
- RETURN RawKeyConvert(ievent, kbuffer, kbsize, kmap)
- ENDPROC
-
- -> print_qualifiers() - Print out the values found in the qualifier bits of
- -> the message. This will print out all of the qualifier bits set.
- PROC print_qualifiers(qual)
- WriteF('Qual: ')
- IF qual AND IEQUALIFIER_LSHIFT THEN WriteF('LShft, ')
- IF qual AND IEQUALIFIER_RSHIFT THEN WriteF('RShft, ')
- IF qual AND IEQUALIFIER_CAPSLOCK THEN WriteF('CapLok, ')
- IF qual AND IEQUALIFIER_CONTROL THEN WriteF('Ctrl, ')
- IF qual AND IEQUALIFIER_LALT THEN WriteF('LAlt, ')
- IF qual AND IEQUALIFIER_RALT THEN WriteF('RAlt, ')
- IF qual AND IEQUALIFIER_LCOMMAND THEN WriteF('LCmd, ')
- IF qual AND IEQUALIFIER_RCOMMAND THEN WriteF('RCmd, ')
- IF qual AND IEQUALIFIER_NUMERICPAD THEN WriteF('NumPad, ')
- IF qual AND IEQUALIFIER_REPEAT THEN WriteF('Rpt, ')
- IF qual AND IEQUALIFIER_INTERRUPT THEN WriteF('Intrpt, ')
- IF qual AND IEQUALIFIER_MULTIBROADCAST THEN WriteF('Multi Broadcast, ')
- IF qual AND IEQUALIFIER_MIDBUTTON THEN WriteF('MidBtn, ')
- IF qual AND IEQUALIFIER_RBUTTON THEN WriteF('RBtn, ')
- IF qual AND IEQUALIFIER_LEFTBUTTON THEN WriteF('LBtn, ')
- IF qual AND IEQUALIFIER_RELATIVEMOUSE THEN WriteF('RelMouse, ')
- ENDPROC
-
- -> doKeys() - Show what keys were pressed.
- PROC doKeys(ievent, buffer:PTR TO LONG, bufsize:PTR TO LONG) HANDLE
- DEF char_pos, numchars, realc, c
-
- -> deadKeyConvert() returns -1 if there was not enough space in the buffer to
- -> convert the string. Here, the routine increases the size of the buffer on
- -> the fly... Set the return code to FALSE on failure.
- numchars:=deadKeyConvert(buffer[], bufsize[]-1, NIL, ievent)
- WHILE (numchars=-1) AND buffer[]
- -> Conversion failed, buffer too small. Try to double the size of the buffer.
- Dispose(buffer[])
- bufsize[]:=bufsize[]*2
- WriteF('Increasing buffer size to \d\n', bufsize[])
-
- buffer[]:=NewR(bufsize[])
- numchars:=deadKeyConvert(buffer[], bufsize[]-1, NIL, ievent)
- ENDWHILE
-
- -> numchars contains the number of characters placed within the buffer. Key
- -> up events and key sequences that do not generate any data for the program
- -> (like deadkeys) will return zero. Special keys (like HELP, the cursor
- -> keys, FKeys, etc.) return multiple characters that have to then be parsed
- -> by the application.
-
- -> If high bit set, then this is a key up otherwise this is a key down
- IF MsgCode() AND $80
- WriteF('Key Up: ')
- ELSE
- WriteF('Key Down: ')
- ENDIF
-
- print_qualifiers(MsgQualifier())
- WriteF(' rawkey #\d maps to \d ASCII character\s\n',
- $7F AND MsgCode(), numchars, IF numchars<>1 THEN 's' ELSE '')
- FOR char_pos:=0 TO numchars-1
- realc:=(c:=buffer[][char_pos])
- IF (c<=$1F) OR ((c>=$80) AND (c<$A0)) THEN c:=$7F
- WriteF(' \d[3] ($\z\h[2]) = \c\n', realc, realc, c)
- ENDFOR
- EXCEPT DO
- RETURN exception=ERR_NONE
- ENDPROC
-
- -> process_window() - Simple event loop. Note that the message is not replied
- -> to until the end of the loop so that it may be used in the doKeys() call.
- -> E-Note: we use WaitIMessage() so a lot of this and above is simplified
- PROC process_window(win, ievent, buffer, bufsize)
- DEF going=TRUE, class
- WHILE going
- class:=WaitIMessage(win)
- SELECT class
- CASE IDCMP_CLOSEWINDOW
- going:=FALSE
- CASE IDCMP_RAWKEY
- going:=doKeys(ievent, buffer, bufsize)
- ENDSELECT
- ENDWHILE
- ENDPROC
-