| 1 |
greg |
1.1 |
#ifndef lint
|
| 2 |
greg |
2.13 |
static const char RCSid[] = "$Id: xglaresrc.c,v 2.12 2020/05/14 20:58:03 greg Exp $";
|
| 3 |
greg |
1.1 |
#endif
|
| 4 |
|
|
/*
|
| 5 |
|
|
* Circle sources in a displayed image.
|
| 6 |
|
|
*
|
| 7 |
|
|
* 18 Mar 1991 Greg Ward
|
| 8 |
|
|
*/
|
| 9 |
|
|
|
| 10 |
|
|
#include "standard.h"
|
| 11 |
schorsch |
2.9 |
|
| 12 |
|
|
#include <unistd.h>
|
| 13 |
greg |
1.7 |
#include <signal.h>
|
| 14 |
greg |
1.1 |
#include <X11/Xlib.h>
|
| 15 |
|
|
#include <X11/Xutil.h>
|
| 16 |
greg |
1.7 |
|
| 17 |
schorsch |
2.9 |
#include "view.h"
|
| 18 |
|
|
|
| 19 |
greg |
1.7 |
#define XIM "ximage"
|
| 20 |
|
|
|
| 21 |
greg |
1.1 |
#define NSEG 30 /* number of segments per circle */
|
| 22 |
|
|
|
| 23 |
greg |
1.9 |
#define FONTNAME "8x13" /* text font we'll use */
|
| 24 |
|
|
|
| 25 |
|
|
float col[3] = {1.,0.,0.}; /* color */
|
| 26 |
|
|
|
| 27 |
greg |
1.1 |
VIEW ourview = STDVIEW; /* view for picture */
|
| 28 |
greg |
1.10 |
RESOLU pres; /* picture resolution */
|
| 29 |
greg |
1.1 |
|
| 30 |
|
|
Display *theDisplay = NULL; /* connection to server */
|
| 31 |
|
|
|
| 32 |
|
|
#define rwind RootWindow(theDisplay,ourScreen)
|
| 33 |
|
|
#define ourScreen DefaultScreen(theDisplay)
|
| 34 |
|
|
|
| 35 |
greg |
1.9 |
GC vecGC, strGC;
|
| 36 |
greg |
1.1 |
Window gwind;
|
| 37 |
|
|
|
| 38 |
schorsch |
2.9 |
static void init(char *pname, char *wname);
|
| 39 |
|
|
static void circle_sources(FILE *fp);
|
| 40 |
|
|
static void circle(FVECT dir, double dom);
|
| 41 |
|
|
static void value(FVECT dir, double v);
|
| 42 |
|
|
|
| 43 |
greg |
1.1 |
|
| 44 |
schorsch |
2.9 |
int
|
| 45 |
|
|
main(
|
| 46 |
|
|
int argc,
|
| 47 |
|
|
char *argv[]
|
| 48 |
|
|
)
|
| 49 |
greg |
1.1 |
{
|
| 50 |
greg |
1.9 |
char *windowname = NULL;
|
| 51 |
greg |
1.1 |
FILE *fp;
|
| 52 |
|
|
|
| 53 |
greg |
2.13 |
fixargv0(*argv++); argc--;
|
| 54 |
greg |
1.9 |
while (argc > 0 && argv[0][0] == '-') {
|
| 55 |
|
|
switch (argv[0][1]) {
|
| 56 |
|
|
case 'n':
|
| 57 |
|
|
windowname = *++argv;
|
| 58 |
|
|
argc--;
|
| 59 |
|
|
break;
|
| 60 |
|
|
case 'c':
|
| 61 |
|
|
col[0] = atof(*++argv);
|
| 62 |
|
|
col[1] = atof(*++argv);
|
| 63 |
|
|
col[2] = atof(*++argv);
|
| 64 |
|
|
argc -= 3;
|
| 65 |
|
|
break;
|
| 66 |
|
|
}
|
| 67 |
|
|
argv++; argc--;
|
| 68 |
|
|
}
|
| 69 |
|
|
if (argc < 1 || argc > 2) {
|
| 70 |
greg |
1.7 |
fprintf(stderr,
|
| 71 |
greg |
1.9 |
"Usage: %s [-n windowname][-c color] picture [glaresrc]\n",
|
| 72 |
greg |
1.1 |
progname);
|
| 73 |
|
|
exit(1);
|
| 74 |
|
|
}
|
| 75 |
greg |
1.9 |
init(argv[0], windowname);
|
| 76 |
|
|
if (argc < 2)
|
| 77 |
greg |
1.1 |
fp = stdin;
|
| 78 |
greg |
1.9 |
else if ((fp = fopen(argv[1], "r")) == NULL) {
|
| 79 |
|
|
fprintf(stderr, "%s: cannot open \"%s\"\n", progname, argv[1]);
|
| 80 |
greg |
1.1 |
exit(1);
|
| 81 |
|
|
}
|
| 82 |
|
|
circle_sources(fp);
|
| 83 |
|
|
exit(0);
|
| 84 |
|
|
}
|
| 85 |
|
|
|
| 86 |
|
|
|
| 87 |
schorsch |
2.9 |
static void
|
| 88 |
|
|
init( /* get view and find window */
|
| 89 |
|
|
char *pname,
|
| 90 |
|
|
char *wname
|
| 91 |
|
|
)
|
| 92 |
greg |
1.1 |
{
|
| 93 |
greg |
1.5 |
extern Window xfindwind();
|
| 94 |
greg |
1.1 |
XWindowAttributes wa;
|
| 95 |
|
|
XColor xc;
|
| 96 |
|
|
XGCValues gcv;
|
| 97 |
greg |
2.5 |
register int i;
|
| 98 |
greg |
1.1 |
/* get the viewing parameters */
|
| 99 |
greg |
1.10 |
if (viewfile(pname, &ourview, &pres) <= 0 ||
|
| 100 |
greg |
1.1 |
setview(&ourview) != NULL) {
|
| 101 |
|
|
fprintf(stderr, "%s: cannot get view from \"%s\"\n",
|
| 102 |
greg |
1.7 |
progname, pname);
|
| 103 |
greg |
1.1 |
exit(1);
|
| 104 |
|
|
}
|
| 105 |
|
|
/* open the display */
|
| 106 |
|
|
if ((theDisplay = XOpenDisplay(NULL)) == NULL) {
|
| 107 |
|
|
fprintf(stderr,
|
| 108 |
|
|
"%s: cannot open display; DISPLAY variable set?\n",
|
| 109 |
|
|
progname);
|
| 110 |
|
|
exit(1);
|
| 111 |
|
|
}
|
| 112 |
|
|
/* find our window */
|
| 113 |
greg |
2.5 |
if (wname == NULL) {
|
| 114 |
|
|
/* remove directory prefix from name */
|
| 115 |
|
|
for (i = strlen(pname); i-- > 0; )
|
| 116 |
|
|
if (pname[i] == '/')
|
| 117 |
|
|
break;
|
| 118 |
|
|
wname = pname+i+1;
|
| 119 |
|
|
i = 0;
|
| 120 |
|
|
} else
|
| 121 |
|
|
i = 1;
|
| 122 |
greg |
2.4 |
gwind = xfindwind(theDisplay, rwind, wname, 4);
|
| 123 |
greg |
1.5 |
if (gwind == None) {
|
| 124 |
greg |
2.5 |
if (i) {
|
| 125 |
greg |
1.7 |
fprintf(stderr, "%s: cannot find \"%s\" window\n",
|
| 126 |
|
|
progname, wname);
|
| 127 |
|
|
exit(2);
|
| 128 |
|
|
}
|
| 129 |
|
|
/* start ximage */
|
| 130 |
greg |
2.8 |
if (fork() == 0) {
|
| 131 |
greg |
2.4 |
execlp(XIM, XIM, "-c", "256", pname, 0);
|
| 132 |
greg |
1.7 |
perror(XIM);
|
| 133 |
|
|
fprintf(stderr, "%s: cannot start %s\n",
|
| 134 |
|
|
progname, XIM);
|
| 135 |
|
|
kill(getppid(), SIGPIPE);
|
| 136 |
|
|
_exit(1);
|
| 137 |
|
|
}
|
| 138 |
|
|
do
|
| 139 |
|
|
sleep(8);
|
| 140 |
greg |
2.5 |
while ((gwind=xfindwind(theDisplay,rwind,wname,4)) == None);
|
| 141 |
greg |
1.8 |
} else
|
| 142 |
greg |
1.7 |
XMapRaised(theDisplay, gwind);
|
| 143 |
greg |
1.8 |
do {
|
| 144 |
|
|
XGetWindowAttributes(theDisplay, gwind, &wa);
|
| 145 |
greg |
1.9 |
sleep(6);
|
| 146 |
greg |
1.8 |
} while (wa.map_state != IsViewable);
|
| 147 |
greg |
1.10 |
if (wa.width != scanlen(&pres) || wa.height != numscans(&pres)) {
|
| 148 |
greg |
1.1 |
fprintf(stderr,
|
| 149 |
|
|
"%s: warning -- window seems to be the wrong size!\n",
|
| 150 |
|
|
progname);
|
| 151 |
greg |
2.6 |
if (pres.rt & YMAJOR) {
|
| 152 |
greg |
1.10 |
pres.xr = wa.width;
|
| 153 |
|
|
pres.yr = wa.height;
|
| 154 |
|
|
} else {
|
| 155 |
|
|
pres.xr = wa.height;
|
| 156 |
|
|
pres.yr = wa.width;
|
| 157 |
|
|
}
|
| 158 |
greg |
1.1 |
}
|
| 159 |
|
|
/* set graphics context */
|
| 160 |
greg |
1.9 |
gcv.font = XLoadFont(theDisplay, FONTNAME);
|
| 161 |
|
|
if (gcv.font == 0) {
|
| 162 |
|
|
fprintf(stderr, "%s: cannot load font \"%s\"\n",
|
| 163 |
|
|
progname, FONTNAME);
|
| 164 |
|
|
exit(1);
|
| 165 |
|
|
}
|
| 166 |
|
|
xc.red = col[0] >= 1.0 ? 65535 : (unsigned)(65536*col[0]);
|
| 167 |
|
|
xc.green = col[1] >= 1.0 ? 65535 : (unsigned)(65536*col[1]);
|
| 168 |
|
|
xc.blue = col[2] >= 1.0 ? 65535 : (unsigned)(65536*col[2]);
|
| 169 |
greg |
1.1 |
xc.flags = DoRed|DoGreen|DoBlue;
|
| 170 |
greg |
1.9 |
gcv.background = xc.green >= 32768 ?
|
| 171 |
|
|
BlackPixel(theDisplay,DefaultScreen(theDisplay)) :
|
| 172 |
|
|
WhitePixel(theDisplay,DefaultScreen(theDisplay)) ;
|
| 173 |
greg |
1.1 |
if (XAllocColor(theDisplay, wa.colormap, &xc)) {
|
| 174 |
|
|
gcv.foreground = xc.pixel;
|
| 175 |
greg |
1.9 |
vecGC = XCreateGC(theDisplay,gwind,
|
| 176 |
|
|
GCForeground|GCBackground|GCFont,&gcv);
|
| 177 |
|
|
strGC = vecGC;
|
| 178 |
greg |
1.1 |
} else {
|
| 179 |
|
|
gcv.function = GXinvert;
|
| 180 |
|
|
vecGC = XCreateGC(theDisplay,gwind,GCFunction,&gcv);
|
| 181 |
greg |
1.9 |
gcv.foreground = xc.green < 32768 ?
|
| 182 |
|
|
BlackPixel(theDisplay,DefaultScreen(theDisplay)) :
|
| 183 |
|
|
WhitePixel(theDisplay,DefaultScreen(theDisplay)) ;
|
| 184 |
|
|
strGC = XCreateGC(theDisplay,gwind,
|
| 185 |
|
|
GCForeground|GCBackground|GCFont,&gcv);
|
| 186 |
greg |
1.1 |
}
|
| 187 |
|
|
}
|
| 188 |
|
|
|
| 189 |
|
|
|
| 190 |
schorsch |
2.9 |
static void
|
| 191 |
|
|
circle_sources( /* circle sources listed in fp */
|
| 192 |
|
|
FILE *fp
|
| 193 |
|
|
)
|
| 194 |
greg |
1.1 |
{
|
| 195 |
|
|
char linbuf[256];
|
| 196 |
|
|
int reading = 0;
|
| 197 |
|
|
FVECT dir;
|
| 198 |
greg |
1.9 |
double dom, lum;
|
| 199 |
greg |
1.1 |
|
| 200 |
|
|
while (fgets(linbuf, sizeof(linbuf), fp) != NULL)
|
| 201 |
|
|
if (reading) {
|
| 202 |
|
|
if (!strncmp(linbuf, "END", 3)) {
|
| 203 |
|
|
XFlush(theDisplay);
|
| 204 |
|
|
return;
|
| 205 |
|
|
}
|
| 206 |
greg |
2.11 |
if (sscanf(linbuf, FVFORMAT,
|
| 207 |
|
|
&dir[0], &dir[1], &dir[2]) != 3 ||
|
| 208 |
|
|
sscanf(sskip2(linbuf, 3), "%lf %lf",
|
| 209 |
|
|
&dom, &lum) != 2)
|
| 210 |
greg |
1.1 |
break;
|
| 211 |
|
|
circle(dir, dom);
|
| 212 |
greg |
1.9 |
value(dir, lum);
|
| 213 |
greg |
1.1 |
} else if (!strcmp(linbuf, "BEGIN glare source\n"))
|
| 214 |
|
|
reading++;
|
| 215 |
|
|
|
| 216 |
|
|
fprintf(stderr, "%s: error reading glare sources\n", progname);
|
| 217 |
|
|
exit(1);
|
| 218 |
|
|
}
|
| 219 |
|
|
|
| 220 |
|
|
|
| 221 |
schorsch |
2.9 |
static void
|
| 222 |
|
|
circle( /* indicate a solid angle on image */
|
| 223 |
|
|
FVECT dir,
|
| 224 |
|
|
double dom
|
| 225 |
|
|
)
|
| 226 |
greg |
1.1 |
{
|
| 227 |
|
|
FVECT start, cur;
|
| 228 |
|
|
XPoint pt[NSEG+1];
|
| 229 |
greg |
1.10 |
FVECT pp;
|
| 230 |
|
|
int ip[2];
|
| 231 |
greg |
1.1 |
register int i;
|
| 232 |
|
|
|
| 233 |
|
|
fcross(cur, dir, ourview.vup);
|
| 234 |
|
|
if (normalize(cur) == 0.0)
|
| 235 |
|
|
goto fail;
|
| 236 |
|
|
spinvector(start, dir, cur, acos(1.-dom/(2.*PI)));
|
| 237 |
|
|
for (i = 0; i <= NSEG; i++) {
|
| 238 |
|
|
spinvector(cur, start, dir, 2.*PI*i/NSEG);
|
| 239 |
|
|
cur[0] += ourview.vp[0];
|
| 240 |
|
|
cur[1] += ourview.vp[1];
|
| 241 |
|
|
cur[2] += ourview.vp[2];
|
| 242 |
greg |
2.12 |
if (viewloc(pp, &ourview, cur) != VL_GOOD)
|
| 243 |
greg |
1.1 |
goto fail;
|
| 244 |
greg |
1.10 |
loc2pix(ip, &pres, pp[0], pp[1]);
|
| 245 |
|
|
pt[i].x = ip[0];
|
| 246 |
|
|
pt[i].y = ip[1];
|
| 247 |
greg |
1.1 |
}
|
| 248 |
|
|
XDrawLines(theDisplay, gwind, vecGC, pt, NSEG+1, CoordModeOrigin);
|
| 249 |
|
|
return;
|
| 250 |
|
|
fail:
|
| 251 |
|
|
fprintf(stderr, "%s: cannot draw source at (%f,%f,%f)\n",
|
| 252 |
|
|
progname, dir[0], dir[1], dir[2]);
|
| 253 |
greg |
1.9 |
}
|
| 254 |
|
|
|
| 255 |
|
|
|
| 256 |
schorsch |
2.9 |
static void
|
| 257 |
|
|
value( /* print value on image */
|
| 258 |
|
|
FVECT dir,
|
| 259 |
|
|
double v
|
| 260 |
|
|
)
|
| 261 |
greg |
1.9 |
{
|
| 262 |
|
|
FVECT pos;
|
| 263 |
greg |
1.10 |
FVECT pp;
|
| 264 |
|
|
int ip[2];
|
| 265 |
greg |
1.9 |
char buf[32];
|
| 266 |
|
|
|
| 267 |
|
|
pos[0] = ourview.vp[0] + dir[0];
|
| 268 |
|
|
pos[1] = ourview.vp[1] + dir[1];
|
| 269 |
|
|
pos[2] = ourview.vp[2] + dir[2];
|
| 270 |
greg |
2.12 |
if (viewloc(pp, &ourview, pos) != VL_GOOD)
|
| 271 |
greg |
1.9 |
return;
|
| 272 |
greg |
1.10 |
loc2pix(ip, &pres, pp[0], pp[1]);
|
| 273 |
greg |
1.9 |
sprintf(buf, "%.0f", v);
|
| 274 |
|
|
XDrawImageString(theDisplay, gwind, strGC,
|
| 275 |
greg |
1.10 |
ip[0], ip[1], buf, strlen(buf));
|
| 276 |
greg |
1.1 |
}
|