home *** CD-ROM | disk | FTP | other *** search
/ RISCWORLD 5 / RISCWORLD_VOL5.iso / SOFTWARE / Issue1 / PD / SFX / Source / SpecialFX / c / main
Encoding:
Text File  |  2001-09-26  |  9.5 KB  |  733 lines

  1. /*->c.main */
  2.  
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8.  
  9.  
  10. #include "kernel.h"
  11. #include "swis.h"
  12.  
  13.  
  14. #include "h.etc"
  15.  
  16.  
  17. #include "h.header"
  18.  
  19.  
  20. #include "h.main"
  21.  
  22.  
  23.  
  24. #define Message_TaskInitialise 0x400C2
  25. #define Message_TaskCloseDown  0x400C3
  26.  
  27.  
  28.  
  29.        void * xprivate_word;
  30.  
  31.  
  32. extern void claimvectors(void);
  33. extern void relvectors(void);
  34. extern void setfixmode(int newmode);
  35. extern void fixprintservice(int mode);
  36.  
  37.  
  38. static char * xstrcpy(char *s1, const char *s2)
  39. {
  40.  while((*s1++=*s2++)>=32);
  41.  *(s1-1)=0;
  42.  return(s1);
  43. }
  44.  
  45.  
  46.  
  47. static int xcstrncmp(char * first,char * second,int n)
  48. {
  49.  int f;
  50.  int s;
  51.  
  52.  while(n--)
  53.  {
  54.   f=toupper(*first++);
  55.   s=toupper(*second++);
  56.   if(f<32 && s<32) return(0);
  57.   if(f!=s) return(f-s);
  58.  }
  59.  
  60.  return(0);
  61. }
  62.  
  63.  
  64.  
  65. static int xcstrcmp(char * first,char * second)
  66. {
  67.  return(xcstrncmp(first,second,-1));
  68. }
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75. static char * xstrncpy(char *s1,char *s2,int n)
  76. {
  77.  
  78.  while(n-->0)
  79.    if((*s1++=*s2++)<32) break;
  80.  *(s1-1)=0;
  81.  
  82.  return(s1);
  83. }
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90. #define BLENDBIT 0x1
  91. #define LOWBIT   0x2
  92. #define GDRAWBIT 0x4
  93.  
  94.  
  95.  
  96. #define MAXTASKNAME 64
  97.  
  98.  
  99. typedef struct taskdatastr
  100. {
  101.  char   name[MAXTASKNAME];
  102.  int    flags;
  103.  struct taskdatastr * next;
  104.  
  105. } taskdatastr;
  106.  
  107.  
  108.  
  109.  
  110. typedef struct filterstr
  111. {
  112.  taskdatastr      * data;
  113.  int                taskhandle;
  114.  struct filterstr * next;
  115.  
  116. } filterstr;
  117.  
  118.  
  119. static int defaultflags=BLENDBIT|GDRAWBIT;
  120.  
  121. static taskdatastr * firsttask=NULL;
  122. static filterstr   * firstfilter=NULL;
  123.  
  124.  
  125. static taskdatastr * findtask(char * name)
  126. {
  127.  taskdatastr * taskp;
  128.  
  129.  taskp=firsttask;
  130.  
  131.  while(taskp)
  132.  {
  133.   if(xcstrcmp(taskp->name,name)==0) break;
  134.   taskp=taskp->next;
  135.  }
  136.  
  137.  return(taskp);
  138. }
  139.  
  140.  
  141. static taskdatastr * addtask(char * name,int flags)
  142. {
  143.  taskdatastr * taskp;
  144.  
  145.  taskp=malloc(sizeof(taskdatastr));
  146.  if(taskp)
  147.  {
  148.   taskp->next=firsttask;
  149.   firsttask=taskp;
  150.  
  151.   xstrncpy(taskp->name,name,MAXTASKNAME);
  152.   taskp->flags=flags;
  153.  }
  154.  
  155.  return(taskp);
  156. }
  157.  
  158.  
  159.  
  160. static void listtasks(void)
  161. {
  162.  taskdatastr * taskp;
  163.  char          flags[32];
  164.  
  165.  taskp=firsttask;
  166.  
  167.  
  168.  printf("Default setting %s%s%s\n",(defaultflags&BLENDBIT)?"B":"~B",
  169.                                    (defaultflags&LOWBIT)?"L":"~L",
  170.                                    (defaultflags&GDRAWBIT)?"G":"~G");
  171.  
  172.  while(taskp)
  173.  {
  174.   sprintf(flags,"%s%s%s",(taskp->flags&BLENDBIT)?"B":"~B",
  175.                          (taskp->flags&LOWBIT)?"L":"~L",
  176.                          (taskp->flags&GDRAWBIT)?"G":"~G");
  177.  
  178.  
  179.   printf("%6s    %s\n",flags,taskp->name);
  180.   taskp=taskp->next;
  181.  }
  182. }
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189. static filterstr * findfilter(int taskhandle)
  190. {
  191.  filterstr * filterp;
  192.  
  193.  filterp=firstfilter;
  194.  
  195.  while(filterp)
  196.  {
  197.   if(filterp->taskhandle==taskhandle) break;
  198.   filterp=filterp->next;
  199.  }
  200.  
  201.  return(filterp);
  202. }
  203.  
  204.  
  205. static void listfilters(void)
  206. {
  207.  filterstr * filterp;
  208.  
  209.  filterp=firstfilter;
  210.  
  211.  while(filterp)
  212.  {
  213.   printf("&%08x    %s\n",filterp->taskhandle,filterp->data->name);
  214.  
  215.   filterp=filterp->next;
  216.  }
  217. }
  218.  
  219.  
  220. static void addfilter(int taskhandle,taskdatastr * taskp)
  221. {
  222.  filterstr * filterp;
  223.  
  224.  filterp=malloc(sizeof(filterstr));
  225.  if(filterp)
  226.  {
  227.   filterp->next=firstfilter;
  228.   firstfilter=filterp;
  229.  
  230.   filterp->taskhandle=taskhandle;
  231.   filterp->data=taskp;
  232.  }
  233. }
  234.  
  235.  
  236. static void remfilter(int taskhandle)
  237. {
  238.  filterstr * filterp;
  239.  filterstr * prev;
  240.  
  241.  prev=NULL;
  242.  filterp=firstfilter;
  243.  
  244.  while(filterp)
  245.  {
  246.   if(filterp->taskhandle==taskhandle) break;
  247.   prev=filterp;
  248.   filterp=filterp->next;
  249.  }
  250.  
  251.  if(filterp)
  252.  {
  253.   if(prev) prev->next=filterp->next;
  254.   else     firstfilter=filterp->next;
  255.  
  256.   free(filterp);
  257.  }
  258. }
  259.  
  260.  
  261.  
  262.  
  263.  
  264. static void remfiltertask(taskdatastr * taskp)
  265. {
  266.  filterstr * filterp;
  267.  filterstr * prev;
  268.  filterstr * next;
  269.  
  270.  prev=NULL;
  271.  filterp=firstfilter;
  272.  
  273.  while(filterp)
  274.  {
  275.   while(filterp)
  276.   {
  277.    if(filterp->data==taskp) break;
  278.    prev=filterp;
  279.    filterp=filterp->next;
  280.   }
  281.  
  282.   if(filterp)
  283.   {
  284.    if(prev) prev->next=filterp->next;
  285.    else     firstfilter=filterp->next;
  286.  
  287.    next=filterp->next;
  288.  
  289.    free(filterp);
  290.  
  291.    filterp=next;
  292.   }
  293.  }
  294. }
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302. typedef struct taskliststr
  303. {
  304.  int    taskhandle;
  305.  char * taskname;
  306.  int    memory;
  307.  int    flags;
  308.  
  309.  
  310. } taskliststr;
  311.  
  312.  
  313.  
  314. static void addfiltersfortask(taskdatastr * taskp)
  315. {
  316.  _kernel_swi_regs  rx;
  317.  _kernel_oserror * err;
  318.  taskliststr       tasklist;
  319.  taskliststr     * limit;
  320.  taskliststr     * p;
  321.  filterstr       * filterp;
  322.  
  323.  rx.r[0]=0;
  324.  
  325.  
  326.  while(1)
  327.  {
  328.   rx.r[1]=(int)&tasklist;
  329.   rx.r[2]=sizeof(tasklist);
  330.  
  331.   err=_kernel_swi(TaskManager_EnumerateTasks,&rx,&rx);
  332.   if(err) break;
  333.  
  334.   limit=(taskliststr*)rx.r[1];
  335.   p=&tasklist;
  336.  
  337.   while(p<limit)
  338.   {
  339.    if(!xcstrcmp(p->taskname,taskp->name))
  340.    {
  341.     filterp=findfilter(p->taskhandle);
  342.     if(!filterp) addfilter(p->taskhandle,taskp);
  343.    }
  344.  
  345.    p++;
  346.   }
  347.  
  348.   if(rx.r[0]<0) break;
  349.  }
  350.  
  351. }
  352.  
  353.  
  354.  
  355. static _kernel_oserror * addcommand(char * args[],int argc)
  356. {
  357.  int           flags;
  358.  char        * p;
  359.  int           ch;
  360.  int           not;
  361.  taskdatastr * taskp;
  362.  
  363.  flags=defaultflags;
  364.  not=0;
  365.  taskp=NULL;
  366.  
  367.  if(argc==2)
  368.  {
  369.   taskp=findtask(args[1]);
  370.   if(taskp) flags=taskp->flags;
  371.   else
  372.   {
  373.    taskp=addtask(args[1],flags);
  374.    if(taskp) addfiltersfortask(taskp);
  375.   }
  376.  }
  377.  
  378.  p=args[0];
  379.  while((ch=*p++)!=0)
  380.  {
  381.   if(ch=='~') not=1;
  382.   else
  383.   {
  384.    ch=toupper(ch);
  385.    if(ch=='B')
  386.    {
  387.     if(not) flags&=~BLENDBIT;
  388.     else    flags|=BLENDBIT;
  389.    }
  390.    else
  391.    if(ch=='L')
  392.    {
  393.     if(not) flags&=~LOWBIT;
  394.     else    flags|=LOWBIT;
  395.    }
  396.    else
  397.    if(ch=='G')
  398.    {
  399.     if(not) flags&=~GDRAWBIT;
  400.     else    flags|=GDRAWBIT;
  401.    }
  402.    not=0;
  403.   }
  404.  }
  405.  
  406.  if(taskp)
  407.  {
  408.   taskp->flags=flags;
  409.  }
  410.  else
  411.  {
  412.   defaultflags=flags;
  413.  }
  414.  
  415.  return(NULL);
  416. }
  417.  
  418.  
  419.  
  420.  
  421.  
  422. static _kernel_oserror * remcommand(char * args[],int argc)
  423. {
  424.  taskdatastr * taskp;
  425.  taskdatastr * prev;
  426.  
  427.  prev=NULL;
  428.  taskp=firsttask;
  429.  
  430.  while(taskp)
  431.  {
  432.   if(xcstrcmp(taskp->name,args[0])==0) break;
  433.   prev=taskp;
  434.   taskp=taskp->next;
  435.  }
  436.  
  437.  if(taskp)
  438.  {
  439.   remfiltertask(taskp);
  440.  
  441.   if(prev) prev->next=taskp->next;
  442.   else     firsttask=taskp->next;
  443.  
  444.   free(taskp);
  445.  }
  446.  
  447.  return(NULL);
  448.  USE(argc);
  449. }
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457. /* we're entering a task */
  458.  
  459. _kernel_oserror * postfilter_handler(_kernel_swi_regs *r, void *pw)
  460. {
  461.  filterstr       * filterp;
  462.  int             * p;
  463.  taskdatastr     * taskp;
  464.  int               currenttask;
  465.  _kernel_swi_regs  rx;
  466.  
  467.  
  468.  rx.r[0]=5;
  469.  _kernel_swi(Wimp_ReadSysInfo,&rx,&rx);
  470.  currenttask=rx.r[0];
  471.  
  472.  
  473.  if(r->r[0]==17 || r->r[0]==18)
  474.  {
  475.   p=(int*)r->r[1];
  476.  
  477.   if(p[4]==Message_TaskInitialise)
  478.   {
  479.    taskp=findtask((char*)(p+7));
  480.    if(taskp)
  481.    {
  482.     filterp=findfilter(p[1]);
  483.     if(!filterp) addfilter(p[1],taskp);
  484.    }
  485.   }
  486.   else
  487.   if(p[4]==Message_TaskCloseDown)
  488.   {
  489.    remfilter(p[1]);
  490.   }
  491.  }
  492.  
  493.  filterp=findfilter(currenttask);
  494.  if(filterp)
  495.  {
  496.   setfixmode(filterp->data->flags);
  497.  }
  498.  
  499.  return(NULL);
  500.  USE(pw);
  501. }
  502.  
  503.  
  504. /* we're leaving a task */
  505.  
  506.  
  507. _kernel_oserror * prefilter_handler(_kernel_swi_regs *r, void *pw)
  508. {
  509.  
  510.  /* so set up default flags */
  511.  
  512.  setfixmode(defaultflags);
  513.  
  514.  
  515.  return(NULL);
  516.  USE(r);
  517.  USE(pw);
  518. }
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525. static char * filtername="SpecialFX";
  526.  
  527.  
  528. static _kernel_oserror * xregister(void *private_word)
  529. {
  530.  _kernel_oserror * err;
  531.  _kernel_swi_regs  rx;
  532.  
  533.  
  534.  rx.r[0]=(int)filtername;
  535.  rx.r[1]=(int)postfilter_entry;
  536.  rx.r[2]=(int)private_word;
  537.  rx.r[3]=0; /* all tasks */
  538.  rx.r[4]=0;
  539.  
  540.  err=_kernel_swi(Filter_RegisterPostFilter,&rx,&rx);
  541.  
  542.  if(!err)
  543.  {
  544.   rx.r[0]=(int)filtername;
  545.   rx.r[1]=(int)prefilter_entry;
  546.   rx.r[2]=(int)private_word;
  547.   rx.r[3]=0; /* all tasks */
  548.   rx.r[4]=0;
  549.  
  550.   err=_kernel_swi(Filter_RegisterPreFilter,&rx,&rx);
  551.  }
  552.  
  553.  return(err);
  554. }
  555.  
  556.  
  557.  
  558.  
  559. static _kernel_oserror * deregister(void *private_word)
  560. {
  561.  _kernel_oserror * err;
  562.  _kernel_swi_regs  rx;
  563.  
  564.  
  565.  rx.r[0]=(int)filtername;
  566.  rx.r[1]=(int)postfilter_entry;
  567.  rx.r[2]=(int)private_word;
  568.  rx.r[3]=0;  /* all tasks */
  569.  rx.r[4]=0;
  570.  
  571.  err=_kernel_swi(Filter_DeRegisterPostFilter,&rx,&rx);
  572.  
  573.  if(!err)
  574.  {
  575.   rx.r[0]=(int)filtername;
  576.   rx.r[1]=(int)prefilter_entry;
  577.   rx.r[2]=(int)private_word;
  578.   rx.r[3]=0; /* all tasks */
  579.   rx.r[4]=0;
  580.  
  581.   err=_kernel_swi(Filter_DeRegisterPreFilter,&rx,&rx);
  582.  }
  583.  
  584.  return(err);
  585. }
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593. _kernel_oserror * SpecialFXFinalise(int fatal, int podule,void * pw)
  594. {
  595.  
  596.  relvectors();
  597.  
  598.  deregister(pw);
  599.  
  600.  return(NULL);
  601.  
  602.  USE(fatal);
  603.  USE(podule);
  604.  USE(pw);
  605. }
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615. void SpecialFXService(int service_number,_kernel_swi_regs *r,
  616.                                                   void *private_word)
  617. {
  618.  if(service_number==0x41) fixprintservice(r->r[2]);
  619.  
  620.  USE(private_word);
  621.  USE(r);
  622. }
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631. #define MAXARG 8
  632. #define CLEN   256
  633.  
  634.  
  635.  
  636. _kernel_oserror *SpecialFXCommand(const char *arg_string,int argc,
  637.                                       int cmd_no,void *private_word)
  638. {
  639.  _kernel_oserror   * err;
  640.  char              * argv[MAXARG];
  641.  char                cmd[CLEN];
  642.  char              * p;
  643.  int                 inquotes;
  644.  char              * s;
  645.  char              * e;
  646.  
  647.  
  648.  err=NULL;
  649.  
  650.  xstrcpy(cmd,arg_string);
  651.  
  652.  argc=0;
  653.  p=cmd;
  654.  inquotes=0;
  655.  
  656.  while(1)
  657.  {
  658.   while(*p==' ') p++;
  659.   if(*p==0) break;
  660.   s=p;
  661.  
  662.   while(1)
  663.   {
  664.    if(*p=='\"')
  665.    {
  666.     inquotes^=1;
  667.    }
  668.  
  669.    if((!inquotes && *p==' ') || *p==0)
  670.    {
  671.     e=p;
  672.     if(*p!=0) p++;
  673.  
  674.     if(*s=='\"') s++;
  675.     if(e>s && *(e-1)=='\"') e--;
  676.     *e=0;
  677.     argv[argc++]=s;
  678.  
  679.     break;
  680.    }
  681.    p++;
  682.   }
  683.  }
  684.  
  685.  switch(cmd_no)
  686.  {
  687.    case 0:
  688.           err=addcommand(argv,argc);
  689.           break;
  690.  
  691.    case 1:
  692.           err=remcommand(argv,argc);
  693.           break;
  694.  
  695.    case 2:
  696.           listtasks();
  697.           break;
  698.  
  699.    case 3:
  700.           listfilters();
  701.           break;
  702.  
  703.  }
  704.  
  705.  return(err);
  706.  
  707.  USE(private_word);
  708. }
  709.  
  710.  
  711.  
  712. _kernel_oserror * SpecialFXInitialise(const char *cmd_tail,int podule_base,
  713.                                                    void *private_word)
  714. {
  715.  _kernel_oserror * err;
  716.  
  717.  err=NULL;
  718.  
  719.  xprivate_word=private_word;
  720.  
  721.  claimvectors();
  722.  err=xregister(private_word);
  723.  if(!err)
  724.  {
  725.   SpecialFXCommand(cmd_tail,0,0,private_word);
  726.  }
  727.  
  728.  return(err);
  729.  
  730.  USE(podule_base);
  731. }
  732.  
  733.