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   
C/C++ Source or Header  |  1989-07-10  |  13KB  |  594 lines

  1. #include <stdio.h>
  2. #include <exec/types.h>
  3. #include <exec/io.h>
  4. #include <exec/memory.h>
  5.  
  6. #include <graphics/gfxbase.h>
  7. #include <graphics/text.h>
  8. #include <graphics/gfxmacros.h>
  9. #include <devices/console.h>
  10. #include <devices/keymap.h>
  11. #include <libraries/dos.h>
  12. #include <libraries/dosextens.h>
  13. #include <intuition/intuition.h>
  14. #include <functions.h>
  15.  
  16. extern UBYTE filestring[];
  17.  
  18. UBYTE *LoTypes;
  19. ULONG *LoMap;
  20. UBYTE *LoCap;
  21. UBYTE *LoRep;
  22. UBYTE *HiTypes;
  23. ULONG *HiMap;
  24. UBYTE *HiCap;
  25. UBYTE *HiRep;
  26. int abort=0;
  27.  
  28. extern void FillKeyMap();
  29. extern long DLength();
  30. extern void NewStr();
  31.  
  32. long tlen;
  33. UBYTE *told,*tnew;
  34.  
  35. struct {
  36. UBYTE length;
  37. UBYTE string[127];
  38. } DStr[8]; /* one per each qualifier */
  39.  
  40. struct IOStdReq *WriteMsg;   /* I/O request block pointer */
  41. struct MsgPort  *WritePort;  /* a port at which to receive replies*/
  42. int DescLen[8]={2,4,4,8,4,8,8,16};
  43. struct KeyMap MyKeyMap;
  44.  
  45. /*      For writing to the console: */
  46. void MakeConWP()
  47. {
  48.    WritePort = CreatePort("mycon.write",0L);
  49.    if(WritePort == 0L) exit(100);    /* error in createport */
  50.    WriteMsg =  CreateStdIO(WritePort);
  51.    if(WriteMsg == 0L) exit(200);     /* error in createstdio */
  52. }
  53.  
  54.  
  55.  
  56. /* output a NULL-terminated string of characters to a console */
  57. void
  58. TurnCursorOff()
  59. {
  60.    WriteMsg->io_Command = CMD_WRITE;
  61.    WriteMsg->io_Data = (APTR)" p";
  62.    WriteMsg->io_Length = -1;
  63.    DoIO(WriteMsg);
  64.    return;
  65. }
  66.  
  67.  
  68.  
  69.  
  70. /* this function returns a value of 0 if the console
  71.  * device opened correctly and a nonzero value (the error
  72.  * returned from OpenDevice) if there was an error.
  73.  */
  74. long OpenConsole(window)
  75. struct Window *window;
  76. {
  77. /* Open a console device */
  78.    long error;
  79.  
  80.    MakeConWP(); /* make a write console port */
  81.    WriteMsg->io_Data   = (APTR) window;
  82.    WriteMsg->io_Length = (long)sizeof(*window);
  83.    error=OpenDevice("console.device", 0L, WriteMsg, 0L);
  84.    TurnCursorOff();
  85.    return(error);
  86. }
  87.  
  88.  
  89.  
  90. /* Set the current KeyMap with pointers in given keymap. */
  91.  
  92. void SetKeyMap(KeyMap)
  93. struct KeyMap *KeyMap;
  94. {
  95.    WriteMsg->io_Command = CD_SETKEYMAP;
  96.    WriteMsg->io_Length = 32L;
  97.    WriteMsg->io_Data = (APTR)KeyMap;
  98.    DoIO(WriteMsg);
  99. }
  100.  
  101.  
  102. /* Make a new string so the FreeMem does not crash */
  103. void FixDeadKey(key)
  104. int key;
  105. {
  106.    int i;
  107.    char *temp;
  108.  
  109.    told=(UBYTE *)LoMap[key];
  110.    tnew=(UBYTE *)&LoMap[key];
  111.    LoMap[key]=0;
  112.  
  113.    if(told[0]==0) tnew[3]=told[1];
  114.    else tnew[3]=*(told+told[1]);
  115.  
  116.    if(told[2]==0) tnew[2]=told[3];
  117.    else tnew[2]=*(told+told[3]);
  118.  
  119.    LoTypes[key]&=0x0F;
  120. }
  121.  
  122.  
  123.  
  124. /* Fill Default keymap and copy to MyKeyMap */
  125. void DefaultKeyMap()
  126. {
  127.    int i;
  128.  
  129.    FillKeyMap(&MyKeyMap);
  130.    for(i=0;i<64;i++)
  131.    {
  132.       LoTypes[i]=MyKeyMap.km_LoKeyMapTypes[i];
  133.       LoMap[i]=MyKeyMap.km_LoKeyMap[i];
  134.       if(LoTypes[i]&0x40) NewStr(i);
  135.       if(abort) return;
  136.       if(LoTypes[i]&0x20) FixDeadKey(i);
  137.    }
  138.    for(i=0;i<8;i++)
  139.    {
  140.       LoCap[i]=MyKeyMap.km_LoCapsable[i];
  141.       LoRep[i]=MyKeyMap.km_LoRepeatable[i];
  142.    }
  143.    for(i=0;i<56;i++)
  144.    {
  145.       HiTypes[i]=MyKeyMap.km_HiKeyMapTypes[i];
  146.       HiMap[i]=MyKeyMap.km_HiKeyMap[i];
  147.       if(HiTypes[i]&0x40) NewStr(i+0x40);
  148.       if(abort) return;
  149.       if(HiTypes[i]&0x20) FixDeadKey(i+0x40);
  150.    }
  151.    for(i=0;i<7;i++)
  152.    {
  153.       HiCap[i]=MyKeyMap.km_HiCapsable[i];
  154.       HiRep[i]=MyKeyMap.km_HiRepeatable[i];
  155.    }
  156. }
  157.  
  158.  
  159.  
  160. /* DeAlloc string mem before exit and before LoadKeyMap() */
  161. void ClearStr(key)
  162. int key;
  163. {
  164.    int i;
  165.    for(i=0;i<key;i++) /* deallocate strings both lo and hi*/
  166.    {
  167.       if(LoTypes[i]&0x40)
  168.       {
  169.          told=(UBYTE *)LoMap[i];
  170.          FreeMem(told,DLength(told));
  171.       }
  172.    }
  173. }
  174.  
  175.  
  176.  
  177. ULONG LoadKeyMap(string)
  178. char *string;
  179. {
  180.    int i;
  181.    ULONG segment;
  182.    UWORD *Ptr,*km;
  183.    ULONG *temp,*nptr,length;
  184.    char *name;
  185.  
  186.    segment=(ULONG)LoadSeg(string);
  187.    if(segment==0) return(0L);
  188.  
  189.    Ptr=(UWORD *)BADDR(segment);
  190.    temp=(ULONG *)Ptr;
  191.    length=*(temp-1);
  192.    nptr=(ULONG *)(Ptr+7);
  193.    name=(char *)*nptr;
  194.  
  195.    if((ULONG)name < (ULONG)temp || (ULONG)name > (length+(ULONG)temp))
  196.    {
  197.       UnLoadSeg(segment);
  198.       return(0L);
  199.    }
  200.    km=(UWORD *)&MyKeyMap.km_LoKeyMapTypes;
  201.    for(i=0;i<16;i++) km[i]=Ptr[i+9];
  202.    SetKeyMap(&MyKeyMap);
  203.    ClearStr();
  204.    DefaultKeyMap();
  205.  
  206.    UnLoadSeg(segment);
  207.    return(segment);
  208. }
  209.  
  210.  
  211.  
  212. /* Fill the given KeyMap with pointer to current keymap. */
  213. void FillKeyMap(KeyMap)
  214. struct KeyMap *KeyMap;
  215. {
  216.    WriteMsg->io_Command = CD_ASKKEYMAP;
  217.    WriteMsg->io_Length = 32L;
  218.    WriteMsg->io_Data = (APTR) KeyMap;
  219.    DoIO(WriteMsg);
  220. }
  221.  
  222.  
  223. /* strings are stored as sl0sO0sl1sO1...s0s1...
  224.  * where sl0 is length of string 0 and sO0 is offset from start of descriptor
  225.  * since descriptor overhead comes first sO0 is number of bytes in descriptor
  226.  * since contiguous and monotonically increasing the last string offset +
  227.  * length is the total length.
  228.  */
  229. long DLength(DString)
  230. UBYTE *DString;
  231. {
  232.    long temp;
  233.    int i,num;
  234.    temp=num=DString[1];   /* number of strings in descriptor */
  235.    for (i=0;i<num;i++,i++) temp+=DString[i];  /* total length of strings */
  236.    return(temp);
  237. }
  238.  
  239.  
  240. FreeKeyMap(which)
  241. int which;
  242. {
  243.    FreeMem(LoTypes,120L);
  244.    if(which>1)FreeMem(LoMap,480L);
  245.    if(which>2)FreeMem(LoCap,15L);
  246.    if(which>3)FreeMem(LoRep,15L);
  247. }
  248.  
  249.  
  250. /* Make a new string so the FreeMem does not crash */
  251. void NewStr(key)
  252. int key;
  253. {
  254.    int i,j,in,out,len,desc;
  255.    UBYTE type;
  256.  
  257.    told=(UBYTE *)LoMap[key];
  258.    tlen=DLength(told);       /* total length of strings + descriptor  */
  259.    tnew=(UBYTE *)AllocMem(tlen,0L);
  260.    if(tnew==0)
  261.    {
  262.       ClearStr(key);
  263.       FreeKeyMap(4);
  264.       abort=1;
  265.       return;
  266.    }
  267.  
  268.    type=LoTypes[key]&0x07;
  269.    desc=out=DescLen[type]; /* account for bytes in descriptor */
  270.    for(i=0;i<desc;i++)
  271.    {
  272.       len=tnew[i]=told[i];
  273.       i++;
  274.       in=told[i];
  275.       tnew[i]=out;
  276.       for(j=0;j<len;j++)tnew[out+j]=told[in+j];
  277.       out+=len;
  278.    }
  279.    LoMap[key]=(ULONG)tnew;
  280. }
  281.  
  282.  
  283.  
  284.  
  285.  
  286. void ConsoleCleanup()
  287. {
  288.    CloseDevice(WriteMsg);
  289.    DeleteStdIO(WriteMsg);
  290.    DeletePort(WritePort);
  291. }
  292.  
  293.  
  294. int ctrlflag;
  295. /* take string and put in DStr array for easy editing */
  296. void String(key)
  297. int key;
  298. {
  299.    int i,in,out,test,oldtest,offset;
  300.    UBYTE type;
  301.  
  302.    for (i=0;i<8;i++) DStr[i].length=DStr[i].string[0]=NULL;
  303.    type=LoTypes[key]&0x07;
  304.    if (LoTypes[key]&0x40) /* strings */
  305.    {
  306.       told=(UBYTE *)LoMap[key];
  307.       oldtest=-1;
  308.       in=0;
  309.       for(out=0;out<8;out++)
  310.       {
  311.          if ((test=(type&out))>oldtest)
  312.          {
  313.             oldtest=test;
  314.             DStr[out].length=told[(in<<1)];  /* length */
  315.             offset=told[(in<<1)+1];          /* offset */
  316.             for(i=0;i<DStr[out].length;i++)DStr[out].string[i]=told[offset+i];
  317.             DStr[out].string[i]=NULL;
  318.             in++;
  319.          }
  320.       }
  321.    }
  322.    else /* plain keys */
  323.    {
  324.       told=(UBYTE *)&LoMap[key];
  325.       ctrlflag=0;
  326.       if((type&7)==7)
  327.       {
  328.          ctrlflag=1;
  329.          type=3; /* special case of ctrl with bits 5&6 to 0 */
  330.       }
  331.       oldtest=-1;
  332.       in=3;
  333.       for(out=0;out<8;out++)
  334.       {
  335.          if ((test=(type&out))>oldtest)
  336.          {
  337.             oldtest=test;
  338.             DStr[out].length=1;            /* length    */
  339.             DStr[out].string[0]=told[in];  /* key value */
  340.             DStr[out].string[1]=NULL;
  341.             --in;
  342.          }
  343.       }
  344.       if (ctrlflag)
  345.       {
  346.          DStr[4].length=1;
  347.          DStr[4].string[0]=DStr[0].string[0] & 0x9F;
  348.          DStr[4].string[1]=NULL;
  349.       }
  350.    }
  351. } /* end of String */
  352.  
  353.  
  354.  
  355.  
  356. /* put string back in standard Descriptor format from DStr array */
  357. DeString(key)
  358. int key;
  359. {
  360.    int shift,alt,ctrl,i,offset,keyflag,sum,test,oldtest,in,out;
  361.    UBYTE type;
  362.  
  363.    shift =DStr[1].length+DStr[3].length+DStr[5].length+DStr[7].length;
  364.    alt   =DStr[2].length+DStr[3].length+DStr[6].length+DStr[7].length;
  365.    ctrl  =DStr[4].length+DStr[5].length+DStr[6].length+DStr[7].length;
  366.    ctrlflag=0;
  367.    if(ctrl==1 && DStr[4].string[0]==(DStr[0].string[0] & 0x9F))
  368.    {
  369.       ctrlflag=1;
  370.       ctrl=0;
  371.       DStr[4].length=0;
  372.       DStr[4].string[0]=NULL;
  373.    }
  374.    type=0;
  375.    if (shift) type|=1;
  376.    if (alt)   type|=2;
  377.    if (ctrl)  type|=4;
  378.    offset=tlen=DescLen[type]; /* account for bytes in descriptor */
  379.  
  380.    keyflag=1; /* true mean it is a key */
  381.    for (sum=0,i=0;i<8;i++)
  382.    {
  383.       if (DStr[i].length>1) keyflag=0;
  384.       sum+=DStr[i].length;
  385.    }
  386.    if (sum>4) keyflag=0;
  387.    
  388.    if (!keyflag) /* strings */
  389.    {
  390.       for (i=0;i<8;i++) tlen+=DStr[i].length;
  391.       tnew=AllocMem(tlen,0L);
  392.       if(tnew==0)
  393.       {
  394.          ClearStr(120);
  395.          FreeKeyMap(4);
  396.          abort=1;
  397.          return;
  398.       }
  399.       if (LoTypes[key]&0x40)
  400.       {
  401.          told=(UBYTE *)LoMap[key];
  402.          FreeMem(told,DLength(told));
  403.       }
  404.  
  405.       oldtest=-1;
  406.       in=0;
  407.       for(out=0;out<8;out++)
  408.       {
  409.          if ((test=(type&out))>oldtest)
  410.          {
  411.             oldtest=test;
  412.             tnew[(in<<1)]=DStr[out].length;  /* length */
  413.             tnew[(in<<1)+1]=offset;          /* offset */
  414.             for(i=0;i<DStr[out].length;i++)tnew[offset+i]=DStr[out].string[i];
  415.             offset+=DStr[out].length;
  416.             in++;
  417.          }
  418.       }
  419.       LoMap[key]=(ULONG)tnew;
  420.       LoTypes[key]=0x40|type;
  421.    }
  422.    else /* plain keys */
  423.    {
  424.       told=(UBYTE *)&LoMap[key];
  425.       oldtest=-1;
  426.       in=3;
  427.       for(out=0;out<8;out++)
  428.       {
  429.          if ((test=(type&out))>oldtest)
  430.          {
  431.             oldtest=test;
  432.             told[in]=DStr[out].string[0];  /* key value */
  433.             --in;
  434.          }
  435.       }
  436.       LoTypes[key]=type;
  437.       if (ctrlflag) LoTypes[key]|=4;
  438.    }
  439. }
  440.  
  441.  
  442. /* Save off current keymap in hunk format (not easy)*/
  443. ULONG
  444. SaveKeyMap(strng)
  445. char *strng;
  446. {
  447. long *fd,NumStr,StrOffset,len,HunkSize,name,string;
  448. ULONG *buffer;
  449. UBYTE *cbuf;
  450. int ind,i;
  451.  
  452.    len=708; /* size of fixed portion of buffer at front */
  453.  
  454.    NumStr=0;
  455.    for(ind=0;ind<120;ind++) /* Both Hi and Lo maps */ 
  456.    {
  457.       if(LoTypes[ind]&0x40)
  458.       {
  459.          NumStr++;
  460.          len+=DLength(LoMap[ind]);
  461.       }
  462.    }
  463.  
  464.    if(len&3) len=4+len&~3;                /* round up to mult of 4 (ULONG) */
  465.    name=len;
  466.    len+=strlen(filestring)+1;             /* account for keymap file name */
  467.    len+=11;                               /* account Serial Number + null */
  468.    if(len&3) len=4+len&~3;                /* round up to mult of 4 (ULONG) */
  469.    HunkSize=(len-0x20)>>2;
  470.  
  471.    NumStr+=9;         /* account for 9 offsets needed for keymap and name */
  472.    len+=(NumStr<<2);  /* allocate space for relocation table in buffer */
  473.    len+=20;           /* fixed size for reloc32_hunk stuff */
  474.    cbuf=(UBYTE *)AllocMem(len,0L);
  475.    if(cbuf==0)
  476.    {
  477.       ClearStr(120);
  478.       FreeKeyMap(4);
  479.       abort=1;
  480.       return;
  481.    }
  482.    buffer=(ULONG *)cbuf;
  483.    string=0x02C4;
  484.    if(buffer==0L)
  485.    {
  486.       puts("OH NO... not enough space for temp buffer\n");
  487.       exit(104);
  488.    }
  489.    buffer[0]=0x000003F3;
  490.    buffer[1]=0;
  491.    buffer[2]=1;
  492.    buffer[3]=buffer[4]=0;
  493.    buffer[5]=HunkSize;
  494.    buffer[6]=0x000003E9;
  495.    buffer[7]=HunkSize;
  496.    buffer[8]=buffer[9]=buffer[10]=0;
  497.    /* handle Node name */
  498.    buffer[HunkSize+7]=0; /* zero pad name at end */
  499.    buffer[11]=(name-0x20)<<16;
  500.    strcpy(cbuf+name,filestring);
  501.    strcat(cbuf+name,"/Serial No");
  502.    {UBYTE *c; c=cbuf+name; while(*c!='/')c++;*c=0;}
  503.    buffer[12]=0x004C0000;  /* KeyMap at constant offsets */
  504.    buffer[13]=0x00C40000;
  505.    buffer[14]=0x002E0000;
  506.    buffer[15]=0x003D0000;
  507.    buffer[16]=0x008C0000;
  508.    buffer[17]=0x01C40000;
  509.    buffer[18]=0x00360000;
  510.    buffer[19]=0x00450000;
  511.    for(ind=0;ind<15;ind++) /* Both Lo and Hi Cap & Rep */
  512.    {
  513.       cbuf[ind+0x4E]=LoCap[ind];
  514.       cbuf[ind+0x5D]=LoRep[ind];
  515.    }
  516. /* get ready for string relocation if needed */
  517.    buffer[HunkSize+8]=0x03EC;
  518.    buffer[HunkSize+9]=NumStr;
  519.    buffer[HunkSize+10]=0;
  520.    StrOffset=HunkSize+NumStr+1;
  521.    buffer[StrOffset+1]=0x002A;
  522.    buffer[StrOffset+2]=0x0026;
  523.    buffer[StrOffset+3]=0x0022;
  524.    buffer[StrOffset+4]=0x001E;
  525.    buffer[StrOffset+5]=0x001A;
  526.    buffer[StrOffset+6]=0x0016;
  527.    buffer[StrOffset+7]=0x0012;
  528.    buffer[StrOffset+8]=0x000E;
  529.    buffer[StrOffset+9]=0x000A;
  530.    buffer[StrOffset+10]=0;
  531.    buffer[StrOffset+11]=0x03F2;
  532.  
  533.    for(ind=0;ind<120;ind++) /* Both Lo and Hi maps */
  534.    {
  535.       cbuf[ind+0x6C]=LoTypes[ind];
  536.       if(LoTypes[ind]&0x40)
  537.       {
  538.          buffer[ind+0x39]=string-0x20;
  539.          told=(UBYTE *)LoMap[ind];
  540.          tlen=DLength(told);
  541.          for(i=0;i<tlen;i++) cbuf[string+i]=told[i]; /* assuming contiguous*/
  542.          buffer[StrOffset]=(ind<<2)+0xE4-0x20;
  543.          --StrOffset;
  544.          string+=tlen;
  545.       }
  546.       else
  547.          buffer[ind+0x39]=LoMap[ind];
  548.    }
  549.  
  550.    fd=(long *)Open(strng,MODE_NEWFILE);
  551.    if (fd==0L)
  552.    {
  553.       FreeMem(cbuf,len);
  554.       return(0);
  555.    }
  556.    Write(fd,cbuf,len);
  557.    Close(fd);
  558.    FreeMem(cbuf,len);
  559.    return(1);
  560. }
  561.  
  562. AllocKeyMap()
  563. {
  564.    LoTypes=(UBYTE *)AllocMem(120L,0L);
  565.    if(LoTypes==0) goto Cancel;
  566.    LoMap=  (ULONG *)AllocMem(480L,0L);
  567.    if(LoMap==0) 
  568.    {
  569.       FreeKeyMap(1);
  570.       goto Cancel;
  571.    }
  572.    LoCap=  (UBYTE *)AllocMem(15L,0L);
  573.    if(LoCap==0) 
  574.    {
  575.       FreeKeyMap(2);
  576.       goto Cancel;
  577.    }
  578.    LoRep=  (UBYTE *)AllocMem(15L,0L);
  579.    if(LoRep==0) 
  580.    {
  581.       FreeKeyMap(3);
  582.       goto Cancel;
  583.    }
  584.  
  585.    HiTypes=LoTypes+64;
  586.    HiMap=  LoMap+64;
  587.    HiCap=  LoCap+8;
  588.    HiRep=  LoRep+8;
  589.    return;
  590. Cancel:
  591.    abort=1;
  592.    return;
  593. }
  594.