Back to index

radiance  4R0+20100331
xglaresrc.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: xglaresrc.c,v 2.9 2004/03/26 23:34:24 schorsch Exp $";
00003 #endif
00004 /*
00005  *  Circle sources in a displayed image.
00006  *
00007  *     18 Mar 1991   Greg Ward
00008  */
00009 
00010 #include "standard.h"
00011 
00012 #include <unistd.h>
00013 #include <signal.h>
00014 #include <X11/Xlib.h>
00015 #include <X11/Xutil.h>
00016 
00017 #include "view.h"
00018 
00019 #define XIM          "ximage"
00020 
00021 #define NSEG         30            /* number of segments per circle */
00022 
00023 #define  FONTNAME    "8x13"        /* text font we'll use */
00024 
00025 float  col[3] = {1.,0.,0.};        /* color */
00026 
00027 VIEW   ourview = STDVIEW;          /* view for picture */
00028 RESOLU pres;                       /* picture resolution */
00029 
00030 char   *progname;                  /* program name */
00031 
00032 Display       *theDisplay = NULL;         /* connection to server */
00033 
00034 #define rwind        RootWindow(theDisplay,ourScreen)
00035 #define ourScreen    DefaultScreen(theDisplay)
00036 
00037 GC     vecGC, strGC;
00038 Window gwind;
00039 
00040 static void init(char *pname, char *wname);
00041 static void circle_sources(FILE *fp);
00042 static void circle(FVECT dir, double dom);
00043 static void value(FVECT dir, double v);
00044 
00045 
00046 int
00047 main(
00048        int    argc,
00049        char   *argv[]
00050 )
00051 {
00052        char   *windowname = NULL;
00053        FILE   *fp;
00054 
00055        progname = *argv++; argc--;
00056        while (argc > 0 && argv[0][0] == '-') {
00057               switch (argv[0][1]) {
00058               case 'n':
00059                      windowname = *++argv;
00060                      argc--;
00061                      break;
00062               case 'c':
00063                      col[0] = atof(*++argv);
00064                      col[1] = atof(*++argv);
00065                      col[2] = atof(*++argv);
00066                      argc -= 3;
00067                      break;
00068               }
00069               argv++; argc--;
00070        }
00071        if (argc < 1 || argc > 2) {
00072               fprintf(stderr,
00073               "Usage: %s [-n windowname][-c color] picture [glaresrc]\n",
00074                             progname);
00075               exit(1);
00076        }
00077        init(argv[0], windowname);
00078        if (argc < 2)
00079               fp = stdin;
00080        else if ((fp = fopen(argv[1], "r")) == NULL) {
00081               fprintf(stderr, "%s: cannot open \"%s\"\n", progname, argv[1]);
00082               exit(1);
00083        }
00084        circle_sources(fp);
00085        exit(0);
00086 }
00087 
00088 
00089 static void
00090 init(         /* get view and find window */
00091        char   *pname,
00092        char   *wname
00093 )
00094 {
00095        extern Window xfindwind();
00096        XWindowAttributes    wa;
00097        XColor xc;
00098        XGCValues     gcv;
00099        register int  i;
00100                                    /* get the viewing parameters */
00101        if (viewfile(pname, &ourview, &pres) <= 0 ||
00102                      setview(&ourview) != NULL) {
00103               fprintf(stderr, "%s: cannot get view from \"%s\"\n",
00104                             progname, pname);
00105               exit(1);
00106        }
00107                                    /* open the display */
00108        if ((theDisplay = XOpenDisplay(NULL)) == NULL) {
00109               fprintf(stderr,
00110               "%s: cannot open display; DISPLAY variable set?\n",
00111                             progname);
00112               exit(1);
00113        }
00114                                    /* find our window */
00115        if (wname == NULL) {
00116                             /* remove directory prefix from name */
00117               for (i = strlen(pname); i-- > 0; )
00118                      if (pname[i] == '/')
00119                             break;
00120               wname = pname+i+1;
00121               i = 0;
00122        } else
00123               i = 1;
00124        gwind = xfindwind(theDisplay, rwind, wname, 4);
00125        if (gwind == None) {
00126               if (i) {
00127                      fprintf(stderr, "%s: cannot find \"%s\" window\n",
00128                                    progname, wname);
00129                      exit(2);
00130               }
00131                                    /* start ximage */
00132               if (fork() == 0) {
00133                      execlp(XIM, XIM, "-c", "256", pname, 0);
00134                      perror(XIM);
00135                      fprintf(stderr, "%s: cannot start %s\n",
00136                                    progname, XIM);
00137                      kill(getppid(), SIGPIPE);
00138                      _exit(1);
00139               }
00140               do
00141                      sleep(8);
00142               while ((gwind=xfindwind(theDisplay,rwind,wname,4)) == None);
00143        } else
00144               XMapRaised(theDisplay, gwind);
00145        do {
00146               XGetWindowAttributes(theDisplay, gwind, &wa);
00147               sleep(6);
00148        } while (wa.map_state != IsViewable);
00149        if (wa.width != scanlen(&pres) || wa.height != numscans(&pres)) {
00150               fprintf(stderr,
00151               "%s: warning -- window seems to be the wrong size!\n",
00152                             progname);
00153               if (pres.rt & YMAJOR) {
00154                      pres.xr = wa.width;
00155                      pres.yr = wa.height;
00156               } else {
00157                      pres.xr = wa.height;
00158                      pres.yr = wa.width;
00159               }
00160        }
00161                                    /* set graphics context */
00162        gcv.font = XLoadFont(theDisplay, FONTNAME);
00163        if (gcv.font == 0) {
00164               fprintf(stderr, "%s: cannot load font \"%s\"\n",
00165                             progname, FONTNAME);
00166               exit(1);
00167        }
00168        xc.red = col[0] >= 1.0 ? 65535 : (unsigned)(65536*col[0]);
00169        xc.green = col[1] >= 1.0 ? 65535 : (unsigned)(65536*col[1]);
00170        xc.blue = col[2] >= 1.0 ? 65535 : (unsigned)(65536*col[2]);
00171        xc.flags = DoRed|DoGreen|DoBlue;
00172        gcv.background = xc.green >= 32768 ?
00173                      BlackPixel(theDisplay,DefaultScreen(theDisplay)) :
00174                      WhitePixel(theDisplay,DefaultScreen(theDisplay)) ;
00175        if (XAllocColor(theDisplay, wa.colormap, &xc)) {
00176               gcv.foreground = xc.pixel;
00177               vecGC = XCreateGC(theDisplay,gwind,
00178                             GCForeground|GCBackground|GCFont,&gcv);
00179               strGC = vecGC;
00180        } else {
00181               gcv.function = GXinvert;
00182               vecGC = XCreateGC(theDisplay,gwind,GCFunction,&gcv);
00183               gcv.foreground = xc.green < 32768 ?
00184                      BlackPixel(theDisplay,DefaultScreen(theDisplay)) :
00185                      WhitePixel(theDisplay,DefaultScreen(theDisplay)) ;
00186               strGC = XCreateGC(theDisplay,gwind,
00187                             GCForeground|GCBackground|GCFont,&gcv);
00188        }
00189 }
00190 
00191 
00192 static void
00193 circle_sources(             /* circle sources listed in fp */
00194        FILE   *fp
00195 )
00196 {
00197        char   linbuf[256];
00198        int    reading = 0;
00199        FVECT  dir;
00200        double dom, lum;
00201 
00202        while (fgets(linbuf, sizeof(linbuf), fp) != NULL)
00203               if (reading) {
00204                      if (!strncmp(linbuf, "END", 3)) {
00205                             XFlush(theDisplay);
00206                             return;
00207                      }
00208                      if (sscanf(linbuf, "%lf %lf %lf %lf %lf",
00209                                    &dir[0], &dir[1], &dir[2],
00210                                    &dom, &lum) != 5)
00211                             break;
00212                      circle(dir, dom);
00213                      value(dir, lum);
00214               } else if (!strcmp(linbuf, "BEGIN glare source\n"))
00215                      reading++;
00216 
00217        fprintf(stderr, "%s: error reading glare sources\n", progname);
00218        exit(1);
00219 }
00220 
00221 
00222 static void
00223 circle(              /* indicate a solid angle on image */
00224        FVECT  dir,
00225        double dom
00226 )
00227 {
00228        FVECT  start, cur;
00229        XPoint pt[NSEG+1];
00230        FVECT  pp;
00231        int    ip[2];
00232        register int  i;
00233 
00234        fcross(cur, dir, ourview.vup);
00235        if (normalize(cur) == 0.0)
00236               goto fail;
00237        spinvector(start, dir, cur, acos(1.-dom/(2.*PI)));
00238        for (i = 0; i <= NSEG; i++) {
00239               spinvector(cur, start, dir, 2.*PI*i/NSEG);
00240               cur[0] += ourview.vp[0];
00241               cur[1] += ourview.vp[1];
00242               cur[2] += ourview.vp[2];
00243               viewloc(pp, &ourview, cur);
00244               if (pp[2] <= 0.0)
00245                      goto fail;
00246               loc2pix(ip, &pres, pp[0], pp[1]);
00247               pt[i].x = ip[0];
00248               pt[i].y = ip[1];
00249        }
00250        XDrawLines(theDisplay, gwind, vecGC, pt, NSEG+1, CoordModeOrigin);
00251        return;
00252 fail:
00253        fprintf(stderr, "%s: cannot draw source at (%f,%f,%f)\n",
00254                      progname, dir[0], dir[1], dir[2]);
00255 }
00256 
00257 
00258 static void
00259 value(               /* print value on image */
00260        FVECT  dir,
00261        double v
00262 )
00263 {
00264        FVECT  pos;
00265        FVECT  pp;
00266        int    ip[2];
00267        char   buf[32];
00268 
00269        pos[0] = ourview.vp[0] + dir[0];
00270        pos[1] = ourview.vp[1] + dir[1];
00271        pos[2] = ourview.vp[2] + dir[2];
00272        viewloc(pp, &ourview, pos);
00273        if (pp[2] <= 0.0)
00274               return;
00275        loc2pix(ip, &pres, pp[0], pp[1]);
00276        sprintf(buf, "%.0f", v);
00277        XDrawImageString(theDisplay, gwind, strGC,
00278                      ip[0], ip[1], buf, strlen(buf)); 
00279 }