/* Keyboard.c by Fabbian G. Dufoe, III This is a public domain file. You may use it any way you wish. The functions in this file take an Intuition RAWKEY class message and return the value of the key which was pressed. For standard ASCII characters ReadKey() returns the character. For function keys it returns a zero and places a code representing the key in a buffer supplied by the calling program. The codes are defined in Keys.h. */ #include "Keyboard.h" struct Device *ConsoleDevice = NULL; static struct IOStdReq ConsoleMsg; void CloseReadConsole() /* FUNCTION This function closes the Console Device opened by OpenReadConsole(). If the Console Device was not successfully opened CloseReadConsole() will return without doing anything. INPUT None RESULTS None */ { if (ConsoleDevice != NULL) CloseDevice(&ConsoleMsg); } #ifdef LATTICE int DeadKeyConvert(struct IntuiMessage *Message, UBYTE *KeyBuffer, int BufferSize, struct KeyMap *KeyMap) #else int DeadKeyConvert(Message, KeyBuffer, BufferSize, KeyMap) struct IntuiMessage *Message; UBYTE *KeyBuffer; int BufferSize; struct KeyMap *KeyMap; #endif /* FUNCTION This function converts an Intuition RAWKEY message to the kind of keycodes returned by the Console Device. It uses the Console Device's RawKeyConvert() function. INPUT Message - a pointer to the intuition message KeyBuffer - a pointer to the buffer the user supplied for keycodes BufferSize - the size of KeyBuffer KeyMap - a pointer to a KeyMap structure to be used for the conversion. A NULL value selects the default KeyMap. RESULTS The function returns -2 if the message was not a RAWKEY class message. If the number of keycodes produced was greater than BufferSize the function returns -1. Otherwise the function returns the number of keycodes it placed in the buffer. */ { static struct InputEvent InputEvent = { NULL, /* struct InputEvent *ie_NextEvent; */ IECLASS_RAWKEY, /* UBYTE ie_Class; */ 0, /* UBYTE ie_SubClass; */ 0, /* UWORD ie_Code; */ 0 /* UWORD ie_Qualifier; */ /* union */ /* { */ /* struct */ /* { */ /* WORD ie_x; */ /* WORD ie_y; */ /* } ie_xy; */ /* APTR ie_addr; */ /* } ie_position; */ /* struct timeval ie_TimeStamp; */ }; if (Message->Class != RAWKEY) return(-2); /* if (Message->Code & IECODE_UP_PREFIX) return(0); */ InputEvent.ie_Code = Message->Code; InputEvent.ie_Qualifier = Message->Qualifier; InputEvent.ie_position.ie_addr = (APTR)*(Message->IAddress); return(RawKeyConvert(&InputEvent, KeyBuffer, BufferSize, KeyMap)); } int OpenReadConsole() /* FUNCTION This function gets a pointer to the Console Device by opening a Console Device without attaching it to any window. Its purpose is to make the Console Device function RawKeyConvert() available. INPUT None RESULTS The function returns 0 if it succeeds, -1 if it failed to open the Console Device. */ { if (OpenDevice("console.device", -1L, &ConsoleMsg, 0) != 0) return(-1); ConsoleDevice = (struct Device *)ConsoleMsg.io_Device; return(0); } #ifdef LATTICE char ReadKey(struct IntuiMessage *Message, unsigned short int *KeyID, struct KeyMap *KeyMap) #else char ReadKey(Message, KeyID, KeyMap) struct IntuiMessage *Message; unsigned short int *KeyID; struct KeyMap *KeyMap; #endif /* FUNCTION This function converts an Intuition RAWKEY message to an ASCII character or an integer code identifying the special key pressed. INPUT Message - a pointer to the Intuition message KeyID - a pointer used to return the ID code of a function key KeyMap - a pointer to the keymap structure to be used for the conversion. A NULL pointer specifies the default keymap. RETURNS If the function converts a RAWKEY message to an ASCII character it returns that character. It returns zero if a special key was pressed and it places the key's ID code in the integer pointed to by KeyID. If the message was not a RAWKEY class message or if it was a "key up" message ReadKey() returns -2. The calling program can ignore any calls which return -2. If it fails it returns -1. */ { int actual; UBYTE KeyBuffer[10]; *KeyID = 0; if (Message->Class != RAWKEY) return(-2); /* If it's not a RAWKEY message we'll just ignore it. We tell the caller it can ignore it, too. */ if (Message->Code & IECODE_UP_PREFIX) return(-2); /* If it's a key up message we'll ignore it and tell the caller to ignore it, too. */ actual = DeadKeyConvert(Message, KeyBuffer, sizeof(KeyBuffer), KeyMap); if (actual == 1) return((char)KeyBuffer[0]); /* If DeadKeyConvert() converted the message to a single code we can return it to the caller. */ switch (KeyBuffer[0]) { case 0x9b: switch (KeyBuffer[1]) { case ' ': switch (KeyBuffer[2]) { case '@': *KeyID = K_S_RIGHT; break; case 'A': *KeyID = K_S_LEFT; break; default: break; } break; case '?': switch (KeyBuffer[2]) { case '~': *KeyID = K_HELP; break; default: break; } break; case '0': switch (KeyBuffer[2]) { case '~': *KeyID = K_F1; break; default: break; } break; case '1': switch (KeyBuffer[2]) { case '~': *KeyID = K_F2; break; case '0': switch (KeyBuffer[3]) { case '~': *KeyID = K_S_F1; break; default: break; } break; case '1': switch (KeyBuffer[3]) { case '~': *KeyID = K_S_F2; break; default: break; } break; case '2': switch (KeyBuffer[3]) { case '~': *KeyID = K_S_F3; break; default: break; } break; case '3': switch (KeyBuffer[3]) { case '~': *KeyID = K_S_F4; break; default: break; } break; case '4': switch (KeyBuffer[3]) { case '~': *KeyID = K_S_F5; break; default: break; } break; case '5': switch (KeyBuffer[3]) { case '~': *KeyID = K_S_F6; break; default: break; } break; case '6': switch (KeyBuffer[3]) { case '~': *KeyID = K_S_F7; break; default: break; } break; case '7': switch (KeyBuffer[3]) { case '~': *KeyID = K_S_F8; break; default: break; } break; case '8': switch (KeyBuffer[3]) { case '~': *KeyID = K_S_F9; break; default: break; } break; case '9': switch (KeyBuffer[3]) { case '~': *KeyID = K_S_F10; break; default: break; } break; default: break; } break; case '2': switch (KeyBuffer[2]) { case '~': *KeyID = K_F3; break; default: break; } break; case '3': switch (KeyBuffer[2]) { case '~': *KeyID = K_F4; break; default: break; } break; case '4': switch (KeyBuffer[2]) { case '~': *KeyID = K_F5; break; default: break; } break; case '5': switch (KeyBuffer[2]) { case '~': *KeyID = K_F6; break; default: break; } break; case '6': switch (KeyBuffer[2]) { case '~': *KeyID = K_F7; break; default: break; } break; case '7': switch (KeyBuffer[2]) { case '~': *KeyID = K_F8; break; default: break; } break; case '8': switch (KeyBuffer[2]) { case '~': *KeyID = K_F9; break; default: break; } break; case '9': switch (KeyBuffer[2]) { case '~': *KeyID = K_F10; break; default: break; } break; case 'A': *KeyID = K_UP; break; case 'B': *KeyID = K_DOWN; break; case 'C': *KeyID = K_RIGHT; break; case 'D': *KeyID = K_LEFT; break; case 'S': *KeyID = K_S_DOWN; break; case 'T': *KeyID = K_S_UP; break; default: break; } break; default: break; } if (*KeyID == 0) return(-1); else return(0); }