home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
266.lha
/
SetKey_v2.0
/
src
/
testsubs.c
< prev
Wrap
C/C++ Source or Header
|
1989-07-10
|
13KB
|
594 lines
#include <stdio.h>
#include <exec/types.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <graphics/gfxmacros.h>
#include <devices/console.h>
#include <devices/keymap.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <intuition/intuition.h>
#include <functions.h>
extern UBYTE filestring[];
UBYTE *LoTypes;
ULONG *LoMap;
UBYTE *LoCap;
UBYTE *LoRep;
UBYTE *HiTypes;
ULONG *HiMap;
UBYTE *HiCap;
UBYTE *HiRep;
int abort=0;
extern void FillKeyMap();
extern long DLength();
extern void NewStr();
long tlen;
UBYTE *told,*tnew;
struct {
UBYTE length;
UBYTE string[127];
} DStr[8]; /* one per each qualifier */
struct IOStdReq *WriteMsg; /* I/O request block pointer */
struct MsgPort *WritePort; /* a port at which to receive replies*/
int DescLen[8]={2,4,4,8,4,8,8,16};
struct KeyMap MyKeyMap;
/* For writing to the console: */
void MakeConWP()
{
WritePort = CreatePort("mycon.write",0L);
if(WritePort == 0L) exit(100); /* error in createport */
WriteMsg = CreateStdIO(WritePort);
if(WriteMsg == 0L) exit(200); /* error in createstdio */
}
/* output a NULL-terminated string of characters to a console */
void
TurnCursorOff()
{
WriteMsg->io_Command = CMD_WRITE;
WriteMsg->io_Data = (APTR)" p";
WriteMsg->io_Length = -1;
DoIO(WriteMsg);
return;
}
/* this function returns a value of 0 if the console
* device opened correctly and a nonzero value (the error
* returned from OpenDevice) if there was an error.
*/
long OpenConsole(window)
struct Window *window;
{
/* Open a console device */
long error;
MakeConWP(); /* make a write console port */
WriteMsg->io_Data = (APTR) window;
WriteMsg->io_Length = (long)sizeof(*window);
error=OpenDevice("console.device", 0L, WriteMsg, 0L);
TurnCursorOff();
return(error);
}
/* Set the current KeyMap with pointers in given keymap. */
void SetKeyMap(KeyMap)
struct KeyMap *KeyMap;
{
WriteMsg->io_Command = CD_SETKEYMAP;
WriteMsg->io_Length = 32L;
WriteMsg->io_Data = (APTR)KeyMap;
DoIO(WriteMsg);
}
/* Make a new string so the FreeMem does not crash */
void FixDeadKey(key)
int key;
{
int i;
char *temp;
told=(UBYTE *)LoMap[key];
tnew=(UBYTE *)&LoMap[key];
LoMap[key]=0;
if(told[0]==0) tnew[3]=told[1];
else tnew[3]=*(told+told[1]);
if(told[2]==0) tnew[2]=told[3];
else tnew[2]=*(told+told[3]);
LoTypes[key]&=0x0F;
}
/* Fill Default keymap and copy to MyKeyMap */
void DefaultKeyMap()
{
int i;
FillKeyMap(&MyKeyMap);
for(i=0;i<64;i++)
{
LoTypes[i]=MyKeyMap.km_LoKeyMapTypes[i];
LoMap[i]=MyKeyMap.km_LoKeyMap[i];
if(LoTypes[i]&0x40) NewStr(i);
if(abort) return;
if(LoTypes[i]&0x20) FixDeadKey(i);
}
for(i=0;i<8;i++)
{
LoCap[i]=MyKeyMap.km_LoCapsable[i];
LoRep[i]=MyKeyMap.km_LoRepeatable[i];
}
for(i=0;i<56;i++)
{
HiTypes[i]=MyKeyMap.km_HiKeyMapTypes[i];
HiMap[i]=MyKeyMap.km_HiKeyMap[i];
if(HiTypes[i]&0x40) NewStr(i+0x40);
if(abort) return;
if(HiTypes[i]&0x20) FixDeadKey(i+0x40);
}
for(i=0;i<7;i++)
{
HiCap[i]=MyKeyMap.km_HiCapsable[i];
HiRep[i]=MyKeyMap.km_HiRepeatable[i];
}
}
/* DeAlloc string mem before exit and before LoadKeyMap() */
void ClearStr(key)
int key;
{
int i;
for(i=0;i<key;i++) /* deallocate strings both lo and hi*/
{
if(LoTypes[i]&0x40)
{
told=(UBYTE *)LoMap[i];
FreeMem(told,DLength(told));
}
}
}
ULONG LoadKeyMap(string)
char *string;
{
int i;
ULONG segment;
UWORD *Ptr,*km;
ULONG *temp,*nptr,length;
char *name;
segment=(ULONG)LoadSeg(string);
if(segment==0) return(0L);
Ptr=(UWORD *)BADDR(segment);
temp=(ULONG *)Ptr;
length=*(temp-1);
nptr=(ULONG *)(Ptr+7);
name=(char *)*nptr;
if((ULONG)name < (ULONG)temp || (ULONG)name > (length+(ULONG)temp))
{
UnLoadSeg(segment);
return(0L);
}
km=(UWORD *)&MyKeyMap.km_LoKeyMapTypes;
for(i=0;i<16;i++) km[i]=Ptr[i+9];
SetKeyMap(&MyKeyMap);
ClearStr();
DefaultKeyMap();
UnLoadSeg(segment);
return(segment);
}
/* Fill the given KeyMap with pointer to current keymap. */
void FillKeyMap(KeyMap)
struct KeyMap *KeyMap;
{
WriteMsg->io_Command = CD_ASKKEYMAP;
WriteMsg->io_Length = 32L;
WriteMsg->io_Data = (APTR) KeyMap;
DoIO(WriteMsg);
}
/* strings are stored as sl0sO0sl1sO1...s0s1...
* where sl0 is length of string 0 and sO0 is offset from start of descriptor
* since descriptor overhead comes first sO0 is number of bytes in descriptor
* since contiguous and monotonically increasing the last string offset +
* length is the total length.
*/
long DLength(DString)
UBYTE *DString;
{
long temp;
int i,num;
temp=num=DString[1]; /* number of strings in descriptor */
for (i=0;i<num;i++,i++) temp+=DString[i]; /* total length of strings */
return(temp);
}
FreeKeyMap(which)
int which;
{
FreeMem(LoTypes,120L);
if(which>1)FreeMem(LoMap,480L);
if(which>2)FreeMem(LoCap,15L);
if(which>3)FreeMem(LoRep,15L);
}
/* Make a new string so the FreeMem does not crash */
void NewStr(key)
int key;
{
int i,j,in,out,len,desc;
UBYTE type;
told=(UBYTE *)LoMap[key];
tlen=DLength(told); /* total length of strings + descriptor */
tnew=(UBYTE *)AllocMem(tlen,0L);
if(tnew==0)
{
ClearStr(key);
FreeKeyMap(4);
abort=1;
return;
}
type=LoTypes[key]&0x07;
desc=out=DescLen[type]; /* account for bytes in descriptor */
for(i=0;i<desc;i++)
{
len=tnew[i]=told[i];
i++;
in=told[i];
tnew[i]=out;
for(j=0;j<len;j++)tnew[out+j]=told[in+j];
out+=len;
}
LoMap[key]=(ULONG)tnew;
}
void ConsoleCleanup()
{
CloseDevice(WriteMsg);
DeleteStdIO(WriteMsg);
DeletePort(WritePort);
}
int ctrlflag;
/* take string and put in DStr array for easy editing */
void String(key)
int key;
{
int i,in,out,test,oldtest,offset;
UBYTE type;
for (i=0;i<8;i++) DStr[i].length=DStr[i].string[0]=NULL;
type=LoTypes[key]&0x07;
if (LoTypes[key]&0x40) /* strings */
{
told=(UBYTE *)LoMap[key];
oldtest=-1;
in=0;
for(out=0;out<8;out++)
{
if ((test=(type&out))>oldtest)
{
oldtest=test;
DStr[out].length=told[(in<<1)]; /* length */
offset=told[(in<<1)+1]; /* offset */
for(i=0;i<DStr[out].length;i++)DStr[out].string[i]=told[offset+i];
DStr[out].string[i]=NULL;
in++;
}
}
}
else /* plain keys */
{
told=(UBYTE *)&LoMap[key];
ctrlflag=0;
if((type&7)==7)
{
ctrlflag=1;
type=3; /* special case of ctrl with bits 5&6 to 0 */
}
oldtest=-1;
in=3;
for(out=0;out<8;out++)
{
if ((test=(type&out))>oldtest)
{
oldtest=test;
DStr[out].length=1; /* length */
DStr[out].string[0]=told[in]; /* key value */
DStr[out].string[1]=NULL;
--in;
}
}
if (ctrlflag)
{
DStr[4].length=1;
DStr[4].string[0]=DStr[0].string[0] & 0x9F;
DStr[4].string[1]=NULL;
}
}
} /* end of String */
/* put string back in standard Descriptor format from DStr array */
DeString(key)
int key;
{
int shift,alt,ctrl,i,offset,keyflag,sum,test,oldtest,in,out;
UBYTE type;
shift =DStr[1].length+DStr[3].length+DStr[5].length+DStr[7].length;
alt =DStr[2].length+DStr[3].length+DStr[6].length+DStr[7].length;
ctrl =DStr[4].length+DStr[5].length+DStr[6].length+DStr[7].length;
ctrlflag=0;
if(ctrl==1 && DStr[4].string[0]==(DStr[0].string[0] & 0x9F))
{
ctrlflag=1;
ctrl=0;
DStr[4].length=0;
DStr[4].string[0]=NULL;
}
type=0;
if (shift) type|=1;
if (alt) type|=2;
if (ctrl) type|=4;
offset=tlen=DescLen[type]; /* account for bytes in descriptor */
keyflag=1; /* true mean it is a key */
for (sum=0,i=0;i<8;i++)
{
if (DStr[i].length>1) keyflag=0;
sum+=DStr[i].length;
}
if (sum>4) keyflag=0;
if (!keyflag) /* strings */
{
for (i=0;i<8;i++) tlen+=DStr[i].length;
tnew=AllocMem(tlen,0L);
if(tnew==0)
{
ClearStr(120);
FreeKeyMap(4);
abort=1;
return;
}
if (LoTypes[key]&0x40)
{
told=(UBYTE *)LoMap[key];
FreeMem(told,DLength(told));
}
oldtest=-1;
in=0;
for(out=0;out<8;out++)
{
if ((test=(type&out))>oldtest)
{
oldtest=test;
tnew[(in<<1)]=DStr[out].length; /* length */
tnew[(in<<1)+1]=offset; /* offset */
for(i=0;i<DStr[out].length;i++)tnew[offset+i]=DStr[out].string[i];
offset+=DStr[out].length;
in++;
}
}
LoMap[key]=(ULONG)tnew;
LoTypes[key]=0x40|type;
}
else /* plain keys */
{
told=(UBYTE *)&LoMap[key];
oldtest=-1;
in=3;
for(out=0;out<8;out++)
{
if ((test=(type&out))>oldtest)
{
oldtest=test;
told[in]=DStr[out].string[0]; /* key value */
--in;
}
}
LoTypes[key]=type;
if (ctrlflag) LoTypes[key]|=4;
}
}
/* Save off current keymap in hunk format (not easy)*/
ULONG
SaveKeyMap(strng)
char *strng;
{
long *fd,NumStr,StrOffset,len,HunkSize,name,string;
ULONG *buffer;
UBYTE *cbuf;
int ind,i;
len=708; /* size of fixed portion of buffer at front */
NumStr=0;
for(ind=0;ind<120;ind++) /* Both Hi and Lo maps */
{
if(LoTypes[ind]&0x40)
{
NumStr++;
len+=DLength(LoMap[ind]);
}
}
if(len&3) len=4+len&~3; /* round up to mult of 4 (ULONG) */
name=len;
len+=strlen(filestring)+1; /* account for keymap file name */
len+=11; /* account Serial Number + null */
if(len&3) len=4+len&~3; /* round up to mult of 4 (ULONG) */
HunkSize=(len-0x20)>>2;
NumStr+=9; /* account for 9 offsets needed for keymap and name */
len+=(NumStr<<2); /* allocate space for relocation table in buffer */
len+=20; /* fixed size for reloc32_hunk stuff */
cbuf=(UBYTE *)AllocMem(len,0L);
if(cbuf==0)
{
ClearStr(120);
FreeKeyMap(4);
abort=1;
return;
}
buffer=(ULONG *)cbuf;
string=0x02C4;
if(buffer==0L)
{
puts("OH NO... not enough space for temp buffer\n");
exit(104);
}
buffer[0]=0x000003F3;
buffer[1]=0;
buffer[2]=1;
buffer[3]=buffer[4]=0;
buffer[5]=HunkSize;
buffer[6]=0x000003E9;
buffer[7]=HunkSize;
buffer[8]=buffer[9]=buffer[10]=0;
/* handle Node name */
buffer[HunkSize+7]=0; /* zero pad name at end */
buffer[11]=(name-0x20)<<16;
strcpy(cbuf+name,filestring);
strcat(cbuf+name,"/Serial No");
{UBYTE *c; c=cbuf+name; while(*c!='/')c++;*c=0;}
buffer[12]=0x004C0000; /* KeyMap at constant offsets */
buffer[13]=0x00C40000;
buffer[14]=0x002E0000;
buffer[15]=0x003D0000;
buffer[16]=0x008C0000;
buffer[17]=0x01C40000;
buffer[18]=0x00360000;
buffer[19]=0x00450000;
for(ind=0;ind<15;ind++) /* Both Lo and Hi Cap & Rep */
{
cbuf[ind+0x4E]=LoCap[ind];
cbuf[ind+0x5D]=LoRep[ind];
}
/* get ready for string relocation if needed */
buffer[HunkSize+8]=0x03EC;
buffer[HunkSize+9]=NumStr;
buffer[HunkSize+10]=0;
StrOffset=HunkSize+NumStr+1;
buffer[StrOffset+1]=0x002A;
buffer[StrOffset+2]=0x0026;
buffer[StrOffset+3]=0x0022;
buffer[StrOffset+4]=0x001E;
buffer[StrOffset+5]=0x001A;
buffer[StrOffset+6]=0x0016;
buffer[StrOffset+7]=0x0012;
buffer[StrOffset+8]=0x000E;
buffer[StrOffset+9]=0x000A;
buffer[StrOffset+10]=0;
buffer[StrOffset+11]=0x03F2;
for(ind=0;ind<120;ind++) /* Both Lo and Hi maps */
{
cbuf[ind+0x6C]=LoTypes[ind];
if(LoTypes[ind]&0x40)
{
buffer[ind+0x39]=string-0x20;
told=(UBYTE *)LoMap[ind];
tlen=DLength(told);
for(i=0;i<tlen;i++) cbuf[string+i]=told[i]; /* assuming contiguous*/
buffer[StrOffset]=(ind<<2)+0xE4-0x20;
--StrOffset;
string+=tlen;
}
else
buffer[ind+0x39]=LoMap[ind];
}
fd=(long *)Open(strng,MODE_NEWFILE);
if (fd==0L)
{
FreeMem(cbuf,len);
return(0);
}
Write(fd,cbuf,len);
Close(fd);
FreeMem(cbuf,len);
return(1);
}
AllocKeyMap()
{
LoTypes=(UBYTE *)AllocMem(120L,0L);
if(LoTypes==0) goto Cancel;
LoMap= (ULONG *)AllocMem(480L,0L);
if(LoMap==0)
{
FreeKeyMap(1);
goto Cancel;
}
LoCap= (UBYTE *)AllocMem(15L,0L);
if(LoCap==0)
{
FreeKeyMap(2);
goto Cancel;
}
LoRep= (UBYTE *)AllocMem(15L,0L);
if(LoRep==0)
{
FreeKeyMap(3);
goto Cancel;
}
HiTypes=LoTypes+64;
HiMap= LoMap+64;
HiCap= LoCap+8;
HiRep= LoRep+8;
return;
Cancel:
abort=1;
return;
}