* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 	KeyConvert.asm - key conversion utilities					*
*	Written 22 Mar 88 by Talin									*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

					include		"exec/types.i"
					include		"exec/io.i"
					include		"devices/inputevent.i"
					include		"intuition/intuition.i"
					include		"keyconvert.i"

*WORD ConvertKey(msg, kbuffer, kbsize, kmap)
*	struct IntuiMessage *msg; UBYTE *kbuffer; int kbsize; struct KeyMap *kmap;
*{	static struct InputEvent ievent = {NULL, IECLASS_RAWKEY, 0, 0, 0};
*	register UBYTE code = msg->Code;
*
*	if (msg->Class != RAWKEY) return KEY_ERR_NOT_RAWKEY;
*
*	if (code >= 0x50 && code <= 0x59)
*	{	if (msg->Qualifier & SHIFT) kbuffer[0] = code + (S_FUNKEY1 - 0x50);
*		else kbuffer[0] = code + (FUNKEY1 - 0x50);
*		return 1;
*	}
*	else if (code >= 0x4c && code <= 0x4f)
*	{	kbuffer[0] = code + (UP_ARROW-0x4c); return 1; }
*	else if (code == HELP_KEY)
*	{	kbuffer[0] = 5; return 1; }
*	else if (code >= 0x60) return 0;
*	{	/* pack input event */
*		ievent.ie_Code = code;
*		ievent.ie_Qualifier = msg->Qualifier;
*
*		/* get previous codes from location pointed to by IAddress
*		 *  this pointer is valid until IntuiMessage is replied.
*		 */
*
*		ievent.ie_position.ie_addr = (_deadflag ? *(APTR *)msg->IAddress : NULL);
*		_deadflag = TRUE;
*		return RawKeyConvert(&ievent, kbuffer, kbsize, kmap);
*	}
*}


* note - we need a different one of these for converting IDCMP type
* key events as InputEvent type key events
					dseg
ievent				dc.l		0				; pointer to next event
					dc.b		IECLASS_RAWKEY	; event class
					dc.b		0				; subclass
					dc.w		0,0				; code and qualifier
					dc.w		0,0				; x and y
					dc.l		0,0				; time stamp

					cseg

; ConvertKey(msg, kbuffer, kbsize, kmap)

					public		_ConvertKey,_LVORawKeyConvert
					public		_ConsoleDevice,__deadflag

_ConvertKey
					move.l		4(sp),a0		; a0 = message address

					cmp.l		#RAWKEY,im_Class(a0)	; if not rawkey event
					bne			20$				; return an error

					move.w		im_Code(a0),d0	; get key code

					cmp.w		#$50,d0			; if code < 50 (F1)
					blt			2$				; then try next
					cmp.w		#$59,d0			; if code > 59 (F9)
					bgt			2$				; then try next
					move.w		im_Qualifier(a0),d1	; get qualifier
					and.w		#SHIFT,d1		; if shifted
					beq			1$
					add.w		#$10,d0			; then make keys 16 higher
1$					add.w		#(FUNKEY1-$50),d0
					bra			30$

2$					cmp.w		#$4c,d0			; if code < 4C (UP ARROW)
					blt			3$				; then try next
					cmp.w		#$4f,d0			; if code > 4F (LEFT ARROW)
					bgt			3$				; then try next
					add.w		#(UP_ARROW-$4c),d0
					bra			30$

3$					cmp.w		#$5f,d0			; if code != 5f (HELP)
					bhi			40$				; (if >= $60) then non-printable
					bne			4$				; then try next
					move.w		#HELP_KEY,d0
					bra			30$

4$					move.w		d0,ievent+ie_Code	; move key code to ievent
					move.w		im_Qualifier(a0),ievent+ie_Qualifier

					clr.l		ievent+ie_EventAddress
					tst.w		__deadflag			; if deadflag
					beq.s		15$					; then set deadflag fields
					move.l		im_IAddress(a0),a0	; a0 not needed any more
					move.l		(a0),ievent+ie_EventAddress
15$
					move.w		#-1,__deadflag		; deadflag = TRUE;
													; call RawKeyConvert()
					lea			ievent,a0			; address of input event
					movem.l		a2/a6,-(sp)
					move.l		8+8(sp),a1			; address of input buffer
					move.l		12+8(sp),d1			; size of input buffer
					move.l		16+8(sp),a2			; address of key map
					move.l		_ConsoleDevice,a6	; device address
					jsr			_LVORawKeyConvert(a6) ; convert the key
					movem.l		(sp)+,a2/a6
					rts

; an error occured, return error code.
20$					moveq.l		#KEY_ERR_NOT_RAWKEY,d0	; return -2
					rts

; return special key value
30$					move.l		8(sp),a1			; a1 = key buffer address
					move.b		d0,(a1)				; store d0 in key buffer
					moveq		#1,d0				; return length = 1
					rts

; key pressed was not a convertable key, return.
40$					clr.l		d0					; return length = 0
					rts

* _ConvertKeyEvent

					end

* End of KeyConvert.asm
