home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
new
/
util
/
edit
/
jade
/
src
/
amiga_keys.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-01
|
9KB
|
353 lines
/* amiga_keys.c -- Event translation for AmigaDOS
Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
This file is part of Jade.
Jade is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Jade is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jade; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "jade.h"
#include "jade_protos.h"
#define INTUI_V36_NAMES_ONLY
#include <clib/intuition_protos.h>
#include <clib/keymap_protos.h>
#include <string.h>
#define SHIFTQUALS (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)
#define ALTQUALS (IEQUALIFIER_LALT | IEQUALIFIER_RALT)
#define CMDQUALS (IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND)
_PR void translate_event(u_long *, u_long *, struct IntuiMessage *);
_PR int cook_key(struct IntuiMessage *, u_char *, int);
_PR bool lookup_event(u_long *, u_long *, u_char *);
_PR bool lookup_event_name(u_char *, u_long, u_long);
_PR u_long esc_code, esc_mods;
u_long esc_code = 0x45, esc_mods = EV_TYPE_KEYBD;
static u_long
translate_quals(u_long mods, u_short qual)
{
if(qual & SHIFTQUALS)
mods |= EV_MOD_SHIFT;
if(qual & ALTQUALS)
mods |= EV_MOD_META;
if(qual & CMDQUALS)
mods |= EV_MOD_MOD2; /* Amiga keys */
if(qual & IEQUALIFIER_CONTROL)
mods |= EV_MOD_CTRL;
if(qual & IEQUALIFIER_CAPSLOCK)
mods ^= EV_MOD_SHIFT;
if(qual & IEQUALIFIER_LEFTBUTTON)
mods |= EV_MOD_LMB;
if(qual & IEQUALIFIER_MIDBUTTON)
mods |= EV_MOD_MMB;
if(qual & IEQUALIFIER_RBUTTON)
mods |= EV_MOD_RMB;
return(mods);
}
static u_long
translate_mods(u_long mods)
{
u_long quals = 0;
if(mods & EV_MOD_SHIFT)
quals |= IEQUALIFIER_LSHIFT;
if(mods & EV_MOD_CTRL)
quals |= IEQUALIFIER_CONTROL;
if(mods & EV_MOD_META)
quals |= IEQUALIFIER_LALT;
if(mods & EV_MOD_MOD2)
quals |= IEQUALIFIER_LCOMMAND;
if(mods & EV_MOD_LMB)
quals |= IEQUALIFIER_LEFTBUTTON;
if(mods & EV_MOD_MMB)
quals |= IEQUALIFIER_MIDBUTTON;
if(mods & EV_MOD_RMB)
quals |= IEQUALIFIER_RBUTTON;
return(mods);
}
/* Takes an IntuiMsg and converts it's contents to an EVENT. */
void
translate_event(u_long *code, u_long *mods, struct IntuiMessage *im)
{
static u_long ClickMics, ClickSecs;
*mods = translate_quals(*mods, im->Qualifier);
switch(im->Class)
{
case IDCMP_RAWKEY:
/* This magic means that we disreguard all upcodes and qualifiers. */
if((im->Code > 0x7f) || ((im->Code >= 0x60) && (im->Code <= 0x67)))
return;
*code = (u_long)im->Code;
*mods |= EV_TYPE_KEYBD;
break;
case IDCMP_MOUSEBUTTONS:
*mods |= EV_TYPE_MOUSE;
if(im->Code & IECODE_UP_PREFIX)
{
*code = EV_CODE_MOUSE_UP;
switch(im->Code & ~IECODE_UP_PREFIX)
{
case IECODE_LBUTTON:
*mods |= EV_MOD_LMB;
break;
case IECODE_MBUTTON:
*mods |= EV_MOD_MMB;
break;
case IECODE_RBUTTON:
*mods |= EV_MOD_RMB;
break;
}
}
else
{
if(DoubleClick(ClickSecs, ClickMics, im->Seconds, im->Micros))
*code = EV_CODE_MOUSE_CLICK2;
else
*code = EV_CODE_MOUSE_CLICK1;
ClickSecs = im->Seconds;
ClickMics = im->Micros;
}
break;
case IDCMP_MOUSEMOVE:
if(im->Qualifier & (IEQUALIFIER_MIDBUTTON | IEQUALIFIER_RBUTTON
| IEQUALIFIER_LEFTBUTTON))
{
*mods |= EV_TYPE_MOUSE;
*code = EV_CODE_MOUSE_MOVE;
}
break;
}
}
int
cook_key(struct IntuiMessage *im, u_char *buf, int buflen)
{
struct InputEvent ie;
ie.ie_Class = IECLASS_RAWKEY;
ie.ie_SubClass = 0;
ie.ie_Code = im->Code;
ie.ie_Qualifier = im->Qualifier;
ie.ie_EventAddress = *((APTR *)im->IAddress);
return(MapRawKey(&ie, buf, buflen, NULL));
}
/*
* Stuff to translate textual key descriptions into key codes
*/
typedef struct KeyDesc
{
u_char *kd_Name;
u_long kd_Mods;
u_long kd_Code;
} KeyDesc;
static const KeyDesc KeyDescr[] =
{
"Shift", EV_MOD_SHIFT, 0,
"SFT", EV_MOD_SHIFT, 0,
"Ctrl", EV_MOD_CTRL, 0,
"Control", EV_MOD_CTRL, 0,
"CTL", EV_MOD_CTRL, 0,
"Meta", EV_MOD_META, 0,
"Mod1", EV_MOD_MOD1, 0,
"Mod2", EV_MOD_MOD2, 0,
"Amiga", EV_MOD_MOD2, 0,
"Mod3", EV_MOD_MOD3, 0,
"Mod4", EV_MOD_MOD4, 0,
"LMB", EV_MOD_LMB, 0,
"Button1", EV_MOD_BUTTON1, 0,
"MMB", EV_MOD_MMB, 0,
"Button2", EV_MOD_BUTTON2, 0,
"RMB", EV_MOD_RMB, 0,
"Button3", EV_MOD_BUTTON3, 0,
"Button4", EV_MOD_BUTTON4, 0,
"Button5", EV_MOD_BUTTON5, 0,
"SPC", EV_TYPE_KEYBD, 0x40,
"Space", EV_TYPE_KEYBD, 0x40,
"Spacebar", EV_TYPE_KEYBD, 0x40,
"BS", EV_TYPE_KEYBD, 0x41,
"Backspace", EV_TYPE_KEYBD, 0x41,
"TAB", EV_TYPE_KEYBD, 0x42,
"RET", EV_TYPE_KEYBD, 0x44,
"Return", EV_TYPE_KEYBD, 0x44,
"ESC", EV_TYPE_KEYBD, 0x45,
"Escape", EV_TYPE_KEYBD, 0x45,
"DEL", EV_TYPE_KEYBD, 0x46,
"Delete", EV_TYPE_KEYBD, 0x46,
"Help", EV_TYPE_KEYBD, 0x5f,
"Up", EV_TYPE_KEYBD, 0x4c,
"Down", EV_TYPE_KEYBD, 0x4d,
"Right", EV_TYPE_KEYBD, 0x4e,
"Left", EV_TYPE_KEYBD, 0x4f,
"F1", EV_TYPE_KEYBD, 0x50,
"F2", EV_TYPE_KEYBD, 0x51,
"F3", EV_TYPE_KEYBD, 0x52,
"F4", EV_TYPE_KEYBD, 0x53,
"F5", EV_TYPE_KEYBD, 0x54,
"F6", EV_TYPE_KEYBD, 0x55,
"F7", EV_TYPE_KEYBD, 0x56,
"F8", EV_TYPE_KEYBD, 0x57,
"F9", EV_TYPE_KEYBD, 0x58,
"F10", EV_TYPE_KEYBD, 0x59,
/* Numeric keypad */
"KP_Enter", EV_TYPE_KEYBD, 0x43,
"KP_Multiply",EV_TYPE_KEYBD, 0x5d,
"KP_Divide", EV_TYPE_KEYBD, 0x5c,
"KP_Minus", EV_TYPE_KEYBD, 0x4a,
"KP_Add", EV_TYPE_KEYBD, 0x5e,
"KP_Decimal", EV_TYPE_KEYBD, 0x39,
"KP_0", EV_TYPE_KEYBD, 0x0a,
"KP_1", EV_TYPE_KEYBD, 0x1d,
"KP_2", EV_TYPE_KEYBD, 0x1e,
"KP_3", EV_TYPE_KEYBD, 0x1f,
"KP_4", EV_TYPE_KEYBD, 0x2d,
"KP_5", EV_TYPE_KEYBD, 0x2e,
"KP_6", EV_TYPE_KEYBD, 0x2f,
"KP_7", EV_TYPE_KEYBD, 0x3d,
"KP_8", EV_TYPE_KEYBD, 0x3e,
"KP_9", EV_TYPE_KEYBD, 0x3f,
/* Mouse events */
"Click1", EV_TYPE_MOUSE, EV_CODE_MOUSE_CLICK1,
"Click2", EV_TYPE_MOUSE, EV_CODE_MOUSE_CLICK2,
"Off", EV_TYPE_MOUSE, EV_CODE_MOUSE_UP,
"Move", EV_TYPE_MOUSE, EV_CODE_MOUSE_MOVE,
NULL, 0, 0
};
/* Puts the integers defining the event described in DESC into CODE and
MODS. */
bool
lookup_event(u_long *code, u_long *mods, u_char *desc)
{
bool rc = TRUE;
u_char *str = desc;
*code = *mods = 0;
for(;;)
{
u_char buff[100];
u_char *tmp = buff;
u_char c = *str++;
const KeyDesc *kd = KeyDescr;
/* Get this one token. The first character is read separately to
allow minus characters to be used to represent itself as well as
to terminate a token. */
if(c != 0)
{
*tmp++ = c;
while((c = *str) && (c != '-'))
{
*tmp++ = c;
str++;
}
}
else
goto error;
*tmp = 0;
if(*str)
str++;
while(kd->kd_Name)
{
if(!stricmp(kd->kd_Name, buff))
{
*mods |= kd->kd_Mods;
*code |= kd->kd_Code;
if(*mods & EV_TYPE_MASK)
goto end;
break;
}
kd++;
}
if(!kd->kd_Name)
{
u_char coded[2];
if(MapANSI(buff, strlen(buff), coded, 1, NULL) == 1)
{
*mods |= EV_TYPE_KEYBD;
*mods = translate_quals(*mods, (UWORD)coded[1]);
*code = (u_long)coded[0];
goto end;
}
else
{
error:
cmd_signal(sym_bad_event_desc, LIST_1(string_dup(desc)));
rc = FALSE;
goto end;
}
}
}
end:
return(rc);
}
/* Constructs the name of the event defined by CODE and MODS in BUF. */
bool
lookup_event_name(u_char *buf,