ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhd_x11.c
(Generate patch)

Comparing ray/src/hd/rhd_x11.c (file contents):
Revision 3.1 by gregl, Wed Nov 19 18:01:03 1997 UTC vs.
Revision 3.12 by gregl, Tue Dec 9 14:04:11 1997 UTC

# Line 18 | Line 18 | static char SCCSid[] = "$SunId$ SGI";
18  
19   #include  "x11icon.h"
20  
21 + #ifndef FEQ
22 + #define FEQ(a,b)        ((a)-(b) <= FTINY && (a)-(b) >= -FTINY)
23 + #endif
24 +
25 + #define CTRL(c)         ((c)-'@')
26 +
27   #define GAMMA           2.2             /* default gamma correction */
28  
29 + #define MOVPCT          10              /* percent distance to move */
30 + #define MOVDIR(b)       ((b)==Button1 ? 1 : (b)==Button2 ? 0 : -1)
31 +
32   #define MINWIDTH        480             /* minimum graphics window width */
33   #define MINHEIGHT       400             /* minimum graphics window height */
34  
# Line 30 | Line 39 | static char SCCSid[] = "$SunId$ SGI";
39   #define  ourscreen      DefaultScreen(ourdisplay)
40   #define  ourroot        RootWindow(ourdisplay,ourscreen)
41   #define  ourmask        (StructureNotifyMask|ExposureMask|KeyPressMask|\
42 <                        ButtonPressMask)
42 >                        ButtonPressMask|ButtonReleaseMask)
43  
44   #define  levptr(etype)  ((etype *)&currentevent)
45  
# Line 44 | Line 53 | static unsigned long  *pixval = NULL;  /* allocated pix
53   static unsigned long  ourblack=0, ourwhite=1;
54  
55   static Display  *ourdisplay = NULL;     /* our display */
47
56   static XVisualInfo  ourvinfo;           /* our visual information */
49
57   static Window  gwind = 0;               /* our graphics window */
51
58   static GC  ourgc = 0;                   /* our graphics context for drawing */
53
59   static Colormap ourmap = 0;             /* our color map */
60  
61   static double   pwidth, pheight;        /* pixel dimensions (mm) */
62  
63   static int      inpresflags;            /* input result flags */
64  
65 < static int      heightlocked = 0;       /* lock vertical motion */
65 > static int      headlocked = 0;         /* lock vertical motion */
66  
67   static int  getpixels(), xnewcolr(), freepixels(), resizewindow(),
68 <                getevent(), getkey(), fixwindow();
68 >                getevent(), getkey(), moveview(), getmove(), fixwindow();
69   static unsigned long  true_pixel();
70  
71  
# Line 90 | Line 95 | char  *id;
95          char  *gv;
96          double  gamval = GAMMA;
97          int  nplanes;
93        int  n;
98          XSetWindowAttributes    ourwinattr;
99          XWMHints  ourxwmhints;
100          XSizeHints      oursizhints;
101 +                                        /* set quadtree globals */
102 +        qtMinNodesiz = 2;
103                                          /* open display server */
104          ourdisplay = XOpenDisplay(NULL);
105          if (ourdisplay == NULL)
# Line 155 | Line 161 | char  *id;
161                                          /* map the window and get its size */
162          XMapWindow(ourdisplay, gwind);
163          dev_input();
164 +                                        /* allocate our leaf pile */
165 +        if (!qtAllocLeaves(DisplayWidth(ourdisplay,ourscreen) *
166 +                        DisplayHeight(ourdisplay,ourscreen) /
167 +                        (qtMinNodesiz*qtMinNodesiz)))
168 +                error(SYSTEM, "insufficient memory for leaf storage");
169 +
170                                          /* figure out sensible view */
171          pwidth = (double)DisplayWidthMM(ourdisplay, ourscreen) /
172                          DisplayWidth(ourdisplay, ourscreen);
# Line 166 | Line 178 | char  *id;
178          odev.v.horiz = 2.*180./PI * atan(0.5/VIEWDIST*pwidth*odev.hres);
179          odev.v.vert = 2.*180./PI * atan(0.5/VIEWDIST*pheight*odev.vres);
180          odev.ifd = ConnectionNumber(ourdisplay);
169                                        /* allocate our leaf pile */
170        qtDepthEps = 0.02;
171        n = odev.hres < odev.vres ? odev.hres : odev.vres;
172        qtMinNodesiz = 1;
173        if (!qtAllocLeaves(n*n/(qtMinNodesiz*qtMinNodesiz)))
174                error(SYSTEM, "insufficient memory for leaf storage");
181   }
182  
183  
# Line 195 | Line 201 | dev_close()                    /* close our display */
201   dev_view(nv)                    /* assign new driver view */
202   VIEW    *nv;
203   {
204 <        if (nv != &odev.v)
204 >        if (nv != &odev.v) {
205 >                if (!FEQ(nv->horiz,odev.v.horiz) ||     /* resize window? */
206 >                                !FEQ(nv->vert,odev.v.vert)) {
207 >                        odev.hres = 2.*VIEWDIST/pwidth *
208 >                                        tan(PI/180./2.*nv->horiz);
209 >                        odev.vres = 2.*VIEWDIST/pheight *
210 >                                        tan(PI/180./2.*nv->vert);
211 >                        XResizeWindow(ourdisplay, gwind, odev.hres, odev.vres);
212 >                }
213                  copystruct(&odev.v, nv);
214 +        }
215          qtReplant();
216   }
217  
# Line 205 | Line 220 | int
220   dev_input()                     /* get X11 input */
221   {
222          inpresflags = 0;
223 +
224          do
225                  getevent();
226  
# Line 365 | Line 381 | getevent()                     /* get next event */
381                  getkey(levptr(XKeyPressedEvent));
382                  break;
383          case ButtonPress:
384 <                /* getmove(levptr(XButtonPressedEvent)); */
384 >                getmove(levptr(XButtonPressedEvent));
385                  break;
386          }
387   }
388  
389  
390   static
391 + ilclip(dp, wp)                  /* clip world coordinates to device */
392 + int     dp[2][2];
393 + FVECT   wp[2];
394 + {
395 +        static FVECT    vmin = {0.,0.,0.}, vmax = {1.,1.,FHUGE};
396 +        FVECT   ip[2];
397 +                                /* not exactly right, but who cares? */
398 +        viewloc(ip[0], &odev.v, wp[0]);
399 +        viewloc(ip[1], &odev.v, wp[1]);
400 +        if (!clip(ip[0], ip[1], vmin, vmax))
401 +                return(0);
402 +        dp[0][0] = ip[0][0]*odev.hres;
403 +        dp[0][1] = ip[0][1]*odev.vres;
404 +        dp[1][0] = ip[1][0]*odev.hres;
405 +        dp[1][1] = ip[1][1]*odev.vres;
406 +        return(1);
407 + }
408 +
409 +
410 + static
411 + draw3dline(wp)                  /* draw 3d line in world coordinates */
412 + FVECT   wp[2];
413 + {
414 +        int     dp[2][2];
415 +
416 +        if (!ilclip(dp, wp))
417 +                return;
418 +        XDrawLine(ourdisplay, gwind, ourgc,
419 +                        dp[0][0], odev.vres-1 - dp[0][1],
420 +                        dp[1][0], odev.vres-1 - dp[1][1]);
421 + }
422 +
423 +
424 + static
425 + draw_grids()                    /* draw holodeck section grids */
426 + {
427 +        static BYTE     gridrgb[3] = {0x0, 0xff, 0xff};
428 +        unsigned long  pixel;
429 +
430 +        if (!mapped || odev.v.type != VT_PER)
431 +                return;
432 +        if (ncolors > 0)
433 +                pixel = pixval[get_pixel(gridrgb, xnewcolr)];
434 +        else
435 +                pixel = true_pixel(gridrgb);
436 +        XSetForeground(ourdisplay, ourgc, pixel);
437 +                                        /* draw each grid line */
438 +        gridlines(draw3dline);
439 + }
440 +
441 +
442 + static
443 + moveview(dx, dy, move)          /* move our view */
444 + int     dx, dy, move;
445 + {
446 +        VIEW    nv;
447 +        double  d;
448 +        register int    i, li;
449 +                                /* start with old view */
450 +        copystruct(&nv, &odev.v);
451 +                                /* change view direction */
452 +        if (move) {
453 +                if ((li = qtFindLeaf(dx, dy)) < 0)
454 +                        return(0);      /* not on window */
455 +                for (i = 0; i < 3; i++)
456 +                        nv.vdir[i] = qtL.wp[li][i] - nv.vp[i];
457 +        } else {
458 +                if (viewray(nv.vp, nv.vdir, &odev.v,
459 +                                (dx+.5)/odev.hres, (dy+.5)/odev.vres) < -FTINY)
460 +                        return(0);      /* outside view */
461 +        }
462 +                                /* move viewpoint */
463 +        if (move > 0)
464 +                for (i = 0; i < 3; i++)
465 +                        nv.vp[i] += MOVPCT/100. * nv.vdir[i];
466 +        else if (move < 0)
467 +                for (i = 0; i < 3; i++)
468 +                        nv.vp[i] -= MOVPCT/100. * nv.vdir[i];
469 +        if (move && headlocked) {
470 +                d = 0;          /* bring head back to same height */
471 +                for (i = 0; i < 3; i++)
472 +                        d += odev.v.vup[i] * (odev.v.vp[i] - nv.vp[i]);
473 +                for (i = 0; i < 3; i++)
474 +                        nv.vp[i] += d * odev.v.vup[i];
475 +        }
476 +        if (setview(&nv) != NULL)
477 +                return(0);      /* illegal view */
478 +        dev_view(&nv);
479 +        inpresflags |= DEV_NEWVIEW;
480 +        return(1);
481 + }
482 +
483 +
484 + static
485 + getmove(ebut)                           /* get view change */
486 + XButtonPressedEvent     *ebut;
487 + {
488 +        int     whichbutton = ebut->button;
489 +        int     oldnodesiz = qtMinNodesiz;
490 +        Window  rootw, childw;
491 +        int     rootx, rooty, wx, wy;
492 +        unsigned int    statemask;
493 +
494 +        qtMinNodesiz = 16;              /* for quicker update */
495 +        XNoOp(ourdisplay);
496 +
497 +        while (!XCheckMaskEvent(ourdisplay,
498 +                        ButtonReleaseMask, levptr(XEvent))) {
499 +
500 +                if (!XQueryPointer(ourdisplay, gwind, &rootw, &childw,
501 +                                &rootx, &rooty, &wx, &wy, &statemask))
502 +                        break;          /* on another screen */
503 +
504 +                if (!moveview(wx, odev.vres-1-wy, MOVDIR(whichbutton))) {
505 +                        sleep(1);
506 +                        continue;
507 +                }
508 +                XClearWindow(ourdisplay, gwind);
509 +                qtUpdate();
510 +                draw_grids();
511 +        }
512 +        if (!(inpresflags & DEV_NEWVIEW)) {     /* do final motion */
513 +                whichbutton = levptr(XButtonReleasedEvent)->button;
514 +                wx = levptr(XButtonReleasedEvent)->x;
515 +                wy = levptr(XButtonReleasedEvent)->y;
516 +                moveview(wx, odev.vres-1-wy, MOVDIR(whichbutton));
517 +        }
518 +        dev_flush();
519 +
520 +        qtMinNodesiz = oldnodesiz;      /* restore quadtree resolution */
521 + }
522 +
523 +
524 + static
525   getkey(ekey)                            /* get input key */
526   register XKeyPressedEvent  *ekey;
527   {
# Line 383 | Line 533 | register XKeyPressedEvent  *ekey;
533                  return;
534          switch (buf[0]) {
535          case 'h':                       /* turn on height motion lock */
536 <                heightlocked = 1;
536 >                headlocked = 1;
537                  return;
538          case 'H':                       /* turn off height motion lock */
539 <                heightlocked = 0;
539 >                headlocked = 0;
540                  return;
541 +        case CTRL('S'):
542 +        case 'p':                       /* pause computation */
543 +                inpresflags |= DEV_WAIT;
544 +                return;
545 +        case 'v':                       /* spit out view */
546 +                inpresflags |= DEV_PUTVIEW;
547 +                return;
548 +        case CTRL('Q'):
549 +        case '\n':
550 +        case '\r':                      /* resume computation */
551 +                inpresflags |= DEV_RESUME;
552 +                return;
553 +        case CTRL('R'):                 /* redraw screen */
554 +                if (ncolors > 0)
555 +                        new_ctab(ncolors);
556 +                qtRedraw(0, 0, odev.hres, odev.vres);
557 +                return;
558 +        case CTRL('L'):                 /* refresh from server */
559 +                if (inpresflags & DEV_REDRAW)
560 +                        return;
561 +                XClearWindow(ourdisplay, gwind);
562 +                draw_grids();
563 +                XFlush(ourdisplay);
564 +                qtCompost(100);                 /* unload the old tree */
565 +                if (ncolors > 0)
566 +                        new_ctab(ncolors);
567 +                inpresflags |= DEV_REDRAW;      /* resend values from server */
568 +                return;
569 +        case CTRL('D'):
570          case 'Q':
571          case 'q':                       /* quit the program */
572                  inpresflags |= DEV_SHUTDOWN;
# Line 404 | Line 583 | fixwindow(eexp)                                /* repair damage to window */
583   register XExposeEvent  *eexp;
584   {
585          if (odev.hres == 0 || odev.vres == 0) { /* first exposure */
407 eputs("Resizing window in fixwindow\n");
586                  odev.hres = eexp->width;
587                  odev.vres = eexp->height;
588                  inpresflags |= DEV_NEWSIZE;
# Line 421 | Line 599 | register XConfigureEvent  *ersz;
599          if (ersz->width == odev.hres && ersz->height == odev.vres)
600                  return;
601  
424        if (odev.hres != 0 && odev.vres != 0) {
425                odev.v.horiz = 2.*180./PI * atan(
426                        tan(PI/180./2.*odev.v.horiz) * ersz->width/odev.hres );
427                odev.v.vert = 2.*180./PI * atan(
428                        tan(PI/180./2.*odev.v.vert) * ersz->height/odev.vres );
429                inpresflags |= DEV_NEWVIEW;
430        }
602          odev.hres = ersz->width;
603          odev.vres = ersz->height;
604  
605 <        inpresflags |= DEV_NEWSIZE;
605 >        odev.v.horiz = 2.*180./PI * atan(0.5/VIEWDIST*pwidth*odev.hres);
606 >        odev.v.vert = 2.*180./PI * atan(0.5/VIEWDIST*pheight*odev.vres);
607 >
608 >        inpresflags |= DEV_NEWSIZE|DEV_NEWVIEW;
609   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines