Subversion Repositories wimsdev

Rev

Rev 10 | Rev 7676 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
  2.  *
  3.  *  This program is free software; you can redistribute it and/or modify
  4.  *  it under the terms of the GNU General Public License as published by
  5.  *  the Free Software Foundation; either version 2 of the License, or
  6.  *  (at your option) any later version.
  7.  *
  8.  *  This program is distributed in the hope that it will be useful,
  9.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  *  GNU General Public License for more details.
  12.  *
  13.  *  You should have received a copy of the GNU General Public License
  14.  *  along with this program; if not, write to the Free Software
  15.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17.  
  18.         /* Check the zone of click in an image */
  19.  
  20.         /* Return value: -1 if no condition is met.
  21.          * n>0 for the line of condition meeting the click.
  22.          * empty if condition has error. */
  23.  
  24. /***************** Nothing should need change hereafter *****************/
  25.  
  26. #include "../Lib/libwims.h"
  27. #include "../Flydraw/gd.h"
  28.  
  29. #define VLEN 1024
  30.  
  31. int clickx, clicky;
  32. int prec;
  33. double v[VLEN+2];
  34. char namebuf[2048];
  35. char oldfile[1024]="";
  36. char filebase[10240];
  37. gdImagePtr image=NULL;
  38. int testcolor;
  39.  
  40. void fbase(void)
  41. {
  42.     char *p, *m, *p1, *p2;
  43.     p=getenv("w_insdraw_filebase");
  44.     m=getenv("module_dir"); if(m==NULL) m="";
  45.     if(strncmp(m,"modules/",strlen("modules/"))!=0) {
  46.         snprintf(filebase,sizeof(filebase),"gifs"); return;
  47.     }
  48.     if(p==NULL || *p==0) {
  49.         if(strncmp(m,"modules/adm/",strlen("modules/adm"))==0)
  50.           snprintf(filebase,sizeof(filebase),"%s/insdraw gifs",m);
  51.         else
  52.           snprintf(filebase,sizeof(filebase),"%s gifs",m);
  53.         return;
  54.     }
  55.     for(p1=find_word_start(p); *p1; p1=find_word_start(p2)) {
  56.         p2=find_word_end(p1); if(*p2) *p2++=0;
  57.         if(strstr(p1,"..")!=NULL) continue;
  58.         snprintf(filebase+strlen(filebase),
  59.                  sizeof(filebase)-strlen(filebase),
  60.                  " %s/%s",m,p1);
  61.     }
  62.     snprintf(filebase+strlen(filebase),
  63.              sizeof(filebase)-strlen(filebase),
  64.              " gifs");
  65. }
  66.  
  67.         /* File opening: with security */
  68. FILE *open4read(char *n)
  69. {
  70.     char *p, *p1, *p2;
  71.     int t;
  72.     FILE *f;
  73.     n=find_word_start(n);
  74.     if(*n==0) return NULL;
  75.     p=filebase;
  76.     p1=n+strlen(n)-4;if(p1<n || strcasecmp(p1,".gif")!=0) t=1; else t=0;
  77.     if(p!=NULL && *p!=0) {
  78.         char pbuf[MAX_LINELEN+1];
  79.         snprintf(pbuf,sizeof(pbuf),"%s",p);
  80.         p=find_word_start(pbuf); if(strstr(p,"..")!=NULL) return NULL;
  81.         if(*n=='/' || strstr(n,"..")!=NULL) return NULL;
  82.                 /* prohibit unusual file/dir names */
  83.         for(p1=p;*p1;p1++)
  84.           if(!isalnum(*p1) && !isspace(*p1) && strchr("~_-/.",*p1)==NULL)
  85.             return NULL;
  86.         for(p1=n;*p1;p1++)
  87.           if(!isalnum(*p1) && !isspace(*p1) && strchr("~_-/.",*p1)==NULL)
  88.             return NULL;
  89.         f=NULL;
  90.         for(p1=p; *p1; p1=find_word_start(p2)) {
  91.             if(*p1=='/') return NULL;
  92.             p2=find_word_end(p1);
  93.             if(*p2) *p2++=0;
  94.             snprintf(namebuf,sizeof(namebuf),"%s/%s",p1,n);
  95.             f=fopen(namebuf,"r"); if(f!=NULL) goto imgtype;
  96.         }
  97.         p1=getenv("w_wims_session");
  98.         if(p1!=NULL && strstr(p1,"..")==NULL && strncmp(n,"insert",6)==0) {
  99.             snprintf(namebuf,sizeof(namebuf),"../s2/%s/%s",p1,n);
  100.             f=fopen(namebuf,"r");
  101.         }
  102.     }
  103.     else {
  104.         snprintf(namebuf,sizeof(namebuf),"%s",n);
  105.         f=fopen(namebuf,"r");
  106.     }
  107.     imgtype:
  108.     if(t && f!=NULL) {
  109.         char tbuf[1024],sbuf[4096];
  110.         fclose(f); f=NULL;
  111.         p1=getenv("TMPDIR"); if(p1==NULL || *p1==0) p1=".";
  112.         snprintf(tbuf,sizeof(tbuf),"%s/drawfile_.gif",p1);
  113.         snprintf(sbuf,sizeof(sbuf),"convert %s %s",namebuf,tbuf);
  114.         if (system(sbuf)) fprintf(stderr,"system failed");
  115.         f=fopen(tbuf,"r");     
  116.     }
  117.     if(f!=NULL) snprintf(oldfile,sizeof(oldfile),"%s",n);
  118.     return f;
  119. }
  120.  
  121. int getvalue(char *p, int n)
  122. {
  123.     int t;
  124.     char *p1;
  125.     if(n<0) n=VLEN;
  126.     for(t=0; t<n; t++,p=p1) {
  127.         p1=find_item_end(p); if(*p1) *p1++=0;
  128.         p=find_word_start(p);
  129.         if(*p==0) break;
  130.         v[t]=strevalue(p);
  131.         if(!finite(v[t])) exit(-1);
  132.     }
  133.     return t;
  134. }
  135.  
  136.         /* test one condition. Returns 1 if met. */
  137. int test(char *p)
  138. {
  139.     char *p1;
  140.     int i,t;
  141.     double d;
  142.     p=find_word_start(p); p1=find_item_end(p);
  143.     if(*p1) *p1++=0; else exit(-1);
  144.     prec=0;
  145.     *p=tolower(*p);
  146.     if(strncasecmp(p,"polygon",3)==0 || *p=='g') {
  147.         int cross;
  148.         double x0,y0,a1,b1,c1,a2,b2,c2,s1,s2,s3,s4;
  149.         t=getvalue(p1,-1); if(t<6) exit(-1);
  150.         cross=0; x0=-19; y0=-19;
  151.         a1=clicky-y0;b1=x0-clickx;c1=clickx*y0-x0*clicky;
  152.         v[t]=v[0];v[t+1]=v[1];
  153.         for(i=2;i<t+2;i+=2) {
  154.             a2=v[i+1]-v[i-1];b2=v[i-2]-v[i];
  155.             c2=v[i]*v[i-1]-v[i-2]*v[i+1];
  156.             s1=a1*v[i-2]+b1*v[i-1]+c1;
  157.             s2=a1*v[i]+b1*v[i+1]+c1;
  158.             s3=a2*x0+b2*y0+c2;
  159.             s4=a2*clickx+b2*clicky+c2;
  160.             if(s1==0) continue;
  161.             if(s1*s2<=0 && s3*s4<=0) cross++;
  162.         }
  163.         return cross&1;
  164.     }
  165.     if(*p=='p' || strncasecmp(p,"point",3)==0) {
  166.         t=getvalue(p1,-1); if(t<2) exit(-1);
  167.         for(i=0;i<t;i+=2) {
  168.             d=sqrt(pow(v[i]-clickx,2)+pow(v[i+1]-clicky,2));
  169.             if(d<=4) return 1;
  170.             if(d<=7) {prec=1; return 1;}
  171.         }
  172.         return 0;
  173.     }
  174.     if(strncasecmp(p,"rectangle",1)==0) {
  175.         double x1,x2,y1,y2;
  176.         if(getvalue(p1,4)!=4) exit(-1);
  177.         x1=min(v[0],v[2]); x2=max(v[0],v[2]);
  178.         y1=min(v[1],v[3]); y2=max(v[1],v[3]);
  179.         if(clickx<x1 || clickx>x2 || clicky<y1 || clicky>y2) return 0;
  180.         else return 1;
  181.     }
  182.     if(strncasecmp(p,"circle",1)==0) {
  183.         double dist;
  184.         if(getvalue(p1,3)!=3 || v[2]<0) exit(-1);
  185.         dist=sqrt(pow(v[0]-clickx,2)+pow(v[1]-clicky,2));
  186.         if(dist>v[2]/2) return 0; else return 1;
  187.     }
  188.     if(strncasecmp(p,"ellipse",1)==0) {
  189.         double dist;
  190.         if(getvalue(p1,4)!=4) exit(-1);
  191.         if(v[2]<=0 || v[3]<=0) exit(-1);
  192.         dist=sqrt(pow(2*(v[0]-clickx)/v[2],2)+pow(2*(v[1]-clicky)/v[3],2));
  193.         if(dist>1) return 0; else return 1;
  194.         return 0;
  195.     }
  196.     if(strncasecmp(p,"bound",1)==0) {
  197.         char *p2;
  198.         FILE *f;
  199.         int c, T;
  200.         p2=find_item_end(p1); if(*p2) *p2++=0;
  201.         T=getvalue(p2,2); if(T!=2 && T!=0) exit(-1);
  202.         p1=find_word_start(p1); *find_word_end(p1)=0;
  203.         if(*p1==0) exit(-1);
  204.         if(strcmp(p1,oldfile)!=0) {
  205.             if(image) gdImageDestroy(image);
  206.             f=open4read(p1); if(f==NULL) exit(-1);
  207.             image=gdImageCreateFromGif(f); fclose(f);
  208.             if(T==0) {
  209.                 testcolor=gdImageGetPixel(image,1,1);
  210.             }
  211.             else {
  212.                 testcolor=gdImageColorAllocate(image,2,3,5);
  213.                 gdImageFill(image,clickx,clicky,testcolor);
  214.             }
  215.         }
  216.         if(T==0) {
  217.             c=gdImageGetPixel(image,clickx,clicky);
  218.             if(c!=testcolor) return 1;
  219.         }
  220.         else {
  221.             c=gdImageGetPixel(image,v[0],v[1]);
  222.             if(c==testcolor) return 1;
  223.         }
  224.         return 0;
  225.     }
  226.     exit(-1);
  227. }
  228.  
  229. int oneline(char *p)
  230. {
  231.     char *p1, *p2;
  232.     int t, rev;
  233.  
  234.     if(strparchr(p,'|')!=NULL) {
  235.         t=0; for(p1=p;p1;p1=p2) {
  236.             p2=strparchr(p1,'|'); if(p2!=NULL) *p2++=0;
  237.             t|=oneline(p1);
  238.         }
  239.         return t;
  240.     }
  241.     if(strparchr(p,'&')!=NULL) {
  242.         t=1; for(p1=p;p1;p1=p2) {
  243.             p2=strparchr(p1,'&'); if(p2!=NULL) *p2++=0;
  244.             t&=oneline(p1);
  245.         }
  246.         return t;
  247.     }
  248.     p1=find_word_start(p); rev=0;
  249.     if(*p1=='^') {
  250.         rev=1; p1=find_word_start(++p1);
  251.     }
  252.     if(*p1==0) return rev^1;
  253.     if(*p1=='(') {
  254.         p1++; p2=find_matching(p1,')');
  255.         if(p2==NULL) exit(-1);
  256.         *p2=0; return oneline(p1)^rev;
  257.     }
  258.     return test(p1)^rev;
  259. }
  260.  
  261.         /* Returns the number of line matching the click coordinates */
  262. int main()
  263. {
  264.     char *p, *p2, *p3;
  265.     int i,j;
  266.  
  267.     fbase();
  268.     p=getenv("wims_exec_parm"); if(p==NULL || *p==0) return -1;
  269.     p=find_word_start(p); p2=strchr(p,'\n');
  270.     if(p2==NULL) p2=p+strlen(p); else *p2++=0;
  271.     p3=strchr(p,','); if(p3==NULL) return -1; else *p3++=0;
  272.     clickx=atoi(p); clicky=atoi(p3);
  273.     for(i=1,p=find_word_start(p2);*p;i++, p=find_word_start(p2)) {
  274.         fprintf(stderr,"Line %d.\n",i);
  275.         p2=strchr(p,'\n'); if(p2==NULL) p2=p+strlen(p); else *p2++=0;
  276.         if(*p==0) continue;
  277.         j=oneline(p);
  278.         if(j) {printf("%d %d",i,prec); return 0;}
  279.     }
  280.     printf("-1"); return 0;
  281. }
  282.  
  283.