Back to index

wims  3.65+svn20090927
clickzone.c
Go to the documentation of this file.
00001 /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
00002  *
00003  *  This program is free software; you can redistribute it and/or modify
00004  *  it under the terms of the GNU General Public License as published by
00005  *  the Free Software Foundation; either version 2 of the License, or
00006  *  (at your option) any later version.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00016  */
00017 
00018        /* Check the zone of click in an image */
00019 
00020        /* Return value: -1 if no condition is met.
00021         * n>0 for the line of condition meeting the click.
00022         * empty if condition has error. */
00023 
00024 /***************** Nothing should need change hereafter *****************/
00025 
00026 #include "../Lib/libwims.h"
00027 #include "../Flydraw/gd.h"
00028 
00029 #define VLEN 1024
00030 
00031 int clickx, clicky;
00032 int prec;
00033 double v[VLEN+2];
00034 char namebuf[2048];
00035 char oldfile[1024]="";
00036 char filebase[10240];
00037 gdImagePtr image=NULL;
00038 int testcolor;
00039 
00040 void fbase(void)
00041 {
00042     char *p, *m, *p1, *p2;
00043     p=getenv("w_insdraw_filebase");
00044     m=getenv("module_dir"); if(m==NULL) m="";
00045     if(strncmp(m,"modules/",strlen("modules/"))!=0) {
00046        snprintf(filebase,sizeof(filebase),"gifs"); return;
00047     }
00048     if(p==NULL || *p==0) {
00049        if(strncmp(m,"modules/adm/",strlen("modules/adm"))==0) 
00050          snprintf(filebase,sizeof(filebase),"%s/insdraw gifs",m);
00051        else
00052          snprintf(filebase,sizeof(filebase),"%s gifs",m);
00053        return;
00054     }
00055     for(p1=find_word_start(p); *p1; p1=find_word_start(p2)) {
00056        p2=find_word_end(p1); if(*p2) *p2++=0;
00057        if(strstr(p1,"..")!=NULL) continue;
00058        snprintf(filebase+strlen(filebase),
00059                sizeof(filebase)-strlen(filebase),
00060                " %s/%s",m,p1);
00061     }
00062     snprintf(filebase+strlen(filebase),
00063             sizeof(filebase)-strlen(filebase),
00064             " gifs");
00065 }
00066 
00067        /* File opening: with security */
00068 FILE *open4read(char *n)
00069 {
00070     char *p, *p1, *p2;
00071     int t;
00072     FILE *f;
00073     n=find_word_start(n);
00074     if(*n==0) return NULL;
00075     p=filebase;
00076     p1=n+strlen(n)-4;if(p1<n || strcasecmp(p1,".gif")!=0) t=1; else t=0;
00077     if(p!=NULL && *p!=0) {
00078        char pbuf[MAX_LINELEN+1];
00079        snprintf(pbuf,sizeof(pbuf),"%s",p);
00080        p=find_word_start(pbuf); if(strstr(p,"..")!=NULL) return NULL;
00081        if(*n=='/' || strstr(n,"..")!=NULL) return NULL;
00082               /* prohibit unusual file/dir names */
00083        for(p1=p;*p1;p1++)
00084          if(!isalnum(*p1) && !isspace(*p1) && strchr("~_-/.",*p1)==NULL)
00085            return NULL;
00086        for(p1=n;*p1;p1++)
00087          if(!isalnum(*p1) && !isspace(*p1) && strchr("~_-/.",*p1)==NULL)
00088            return NULL;
00089        f=NULL;
00090        for(p1=p; *p1; p1=find_word_start(p2)) {
00091            if(*p1=='/') return NULL;
00092            p2=find_word_end(p1);
00093            if(*p2) *p2++=0;
00094            snprintf(namebuf,sizeof(namebuf),"%s/%s",p1,n);
00095            f=fopen(namebuf,"r"); if(f!=NULL) goto imgtype;
00096        }
00097        p1=getenv("w_wims_session");
00098        if(p1!=NULL && strstr(p1,"..")==NULL && strncmp(n,"insert",6)==0) {
00099            snprintf(namebuf,sizeof(namebuf),"../s2/%s/%s",p1,n);
00100            f=fopen(namebuf,"r");
00101        }
00102     }
00103     else {
00104        snprintf(namebuf,sizeof(namebuf),"%s",n);
00105        f=fopen(namebuf,"r");
00106     }
00107     imgtype:
00108     if(t && f!=NULL) {
00109        char tbuf[1024],sbuf[4096];
00110        fclose(f); f=NULL;
00111        p1=getenv("TMPDIR"); if(p1==NULL || *p1==0) p1=".";
00112        snprintf(tbuf,sizeof(tbuf),"%s/drawfile_.gif",p1);
00113        snprintf(sbuf,sizeof(sbuf),"convert %s %s",namebuf,tbuf);
00114        system(sbuf); f=fopen(tbuf,"r");   
00115     }
00116     if(f!=NULL) snprintf(oldfile,sizeof(oldfile),"%s",n);
00117     return f;
00118 }
00119 
00120 int getvalue(char *p, int n)
00121 {
00122     int t;
00123     char *p1;
00124     if(n<0) n=VLEN;
00125     for(t=0; t<n; t++,p=p1) {
00126        p1=find_item_end(p); if(*p1) *p1++=0;
00127        p=find_word_start(p);
00128        if(*p==0) break;
00129        v[t]=strevalue(p);
00130        if(!finite(v[t])) exit(-1);
00131     }
00132     return t; 
00133 }
00134 
00135        /* test one condition. Returns 1 if met. */
00136 int test(char *p)
00137 {
00138     char *p1;
00139     int i,t;
00140     double d;
00141     p=find_word_start(p); p1=find_item_end(p);
00142     if(*p1) *p1++=0; else exit(-1);
00143     prec=0;
00144     *p=tolower(*p);
00145     if(strncasecmp(p,"polygon",3)==0 || *p=='g') {
00146        int cross;
00147        double x0,y0,a1,b1,c1,a2,b2,c2,s1,s2,s3,s4;
00148        t=getvalue(p1,-1); if(t<6) exit(-1);
00149        cross=0; x0=-19; y0=-19;
00150        a1=clicky-y0;b1=x0-clickx;c1=clickx*y0-x0*clicky;
00151        v[t]=v[0];v[t+1]=v[1];
00152        for(i=2;i<t+2;i+=2) {
00153            a2=v[i+1]-v[i-1];b2=v[i-2]-v[i];
00154            c2=v[i]*v[i-1]-v[i-2]*v[i+1];
00155            s1=a1*v[i-2]+b1*v[i-1]+c1;
00156            s2=a1*v[i]+b1*v[i+1]+c1;
00157            s3=a2*x0+b2*y0+c2;
00158            s4=a2*clickx+b2*clicky+c2;
00159            if(s1==0) continue;
00160            if(s1*s2<=0 && s3*s4<=0) cross++;
00161        }
00162        return cross&1;
00163     }
00164     if(*p=='p' || strncasecmp(p,"point",3)==0) {
00165        t=getvalue(p1,-1); if(t<2) exit(-1);
00166        for(i=0;i<t;i+=2) {
00167            d=sqrt(pow(v[i]-clickx,2)+pow(v[i+1]-clicky,2));
00168            if(d<=4) return 1;
00169            if(d<=7) {prec=1; return 1;}
00170        }
00171        return 0;
00172     }
00173     if(strncasecmp(p,"rectangle",1)==0) {
00174        double x1,x2,y1,y2;
00175        if(getvalue(p1,4)!=4) exit(-1);
00176        x1=min(v[0],v[2]); x2=max(v[0],v[2]);
00177        y1=min(v[1],v[3]); y2=max(v[1],v[3]);
00178        if(clickx<x1 || clickx>x2 || clicky<y1 || clicky>y2) return 0;
00179        else return 1;
00180     }
00181     if(strncasecmp(p,"circle",1)==0) {
00182        double dist;
00183        if(getvalue(p1,3)!=3 || v[2]<0) exit(-1);
00184        dist=sqrt(pow(v[0]-clickx,2)+pow(v[1]-clicky,2));
00185        if(dist>v[2]/2) return 0; else return 1;
00186     }
00187     if(strncasecmp(p,"ellipse",1)==0) {
00188        double dist;
00189        if(getvalue(p1,4)!=4) exit(-1);
00190        if(v[2]<=0 || v[3]<=0) exit(-1);
00191        dist=sqrt(pow(2*(v[0]-clickx)/v[2],2)+pow(2*(v[1]-clicky)/v[3],2));
00192        if(dist>1) return 0; else return 1;
00193        return 0;
00194     }
00195     if(strncasecmp(p,"bound",1)==0) {
00196        char *p2;
00197        FILE *f;
00198        int c, T;
00199        p2=find_item_end(p1); if(*p2) *p2++=0;
00200        T=getvalue(p2,2); if(T!=2 && T!=0) exit(-1);
00201        p1=find_word_start(p1); *find_word_end(p1)=0;
00202        if(*p1==0) exit(-1);
00203        if(strcmp(p1,oldfile)!=0) {
00204            if(image) gdImageDestroy(image);
00205            f=open4read(p1); if(f==NULL) exit(-1);
00206            image=gdImageCreateFromGif(f); fclose(f);
00207            if(T==0) {
00208               testcolor=gdImageGetPixel(image,1,1);
00209            }
00210            else {
00211               testcolor=gdImageColorAllocate(image,2,3,5);
00212               gdImageFill(image,clickx,clicky,testcolor);
00213            }
00214        }
00215        if(T==0) {
00216            c=gdImageGetPixel(image,clickx,clicky);
00217            if(c!=testcolor) return 1;
00218        }
00219        else {
00220            c=gdImageGetPixel(image,v[0],v[1]);
00221            if(c==testcolor) return 1;
00222        }
00223        return 0;
00224     }
00225     exit(-1);
00226 }
00227 
00228 int oneline(char *p)
00229 {
00230     char *p1, *p2;
00231     int t, rev;
00232 
00233     if(strparchr(p,'|')!=NULL) {
00234        t=0; for(p1=p;p1;p1=p2) {
00235            p2=strparchr(p1,'|'); if(p2!=NULL) *p2++=0;
00236            t|=oneline(p1);
00237        }
00238        return t;
00239     }
00240     if(strparchr(p,'&')!=NULL) {
00241        t=1; for(p1=p;p1;p1=p2) {
00242            p2=strparchr(p1,'&'); if(p2!=NULL) *p2++=0;
00243            t&=oneline(p1);
00244        }
00245        return t;
00246     }
00247     p1=find_word_start(p); rev=0;
00248     if(*p1=='^') {
00249        rev=1; p1=find_word_start(++p1);
00250     }
00251     if(*p1==0) return rev^1;
00252     if(*p1=='(') {
00253        p1++; p2=find_matching(p1,')');
00254        if(p2==NULL) exit(-1);
00255        *p2=0; return oneline(p1)^rev;
00256     }
00257     return test(p1)^rev;
00258 }
00259 
00260        /* Returns the number of line matching the click coordinates */
00261 int main()
00262 {
00263     char *p, *p2, *p3;
00264     int i,j;
00265 
00266     fbase();
00267     p=getenv("wims_exec_parm"); if(p==NULL || *p==0) return -1;
00268     p=find_word_start(p); p2=strchr(p,'\n'); 
00269     if(p2==NULL) p2=p+strlen(p); else *p2++=0;
00270     p3=strchr(p,','); if(p3==NULL) return -1; else *p3++=0;
00271     clickx=atoi(p); clicky=atoi(p3);
00272     for(i=1,p=find_word_start(p2);*p;i++, p=find_word_start(p2)) {
00273        fprintf(stderr,"Line %d.\n",i);
00274        p2=strchr(p,'\n'); if(p2==NULL) p2=p+strlen(p); else *p2++=0;
00275        if(*p==0) continue;
00276        j=oneline(p);
00277        if(j) {printf("%d %d",i,prec); return 0;}
00278     }
00279     printf("-1"); return 0;
00280 }
00281