home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / demos / xgas / chamber.c next >
Encoding:
C/C++ Source or Header  |  1991-05-12  |  6.5 KB  |  227 lines

  1. /*
  2.  * chamber.c -- Larry Medwin -- Dec. 18, 1989
  3.  *   xgas: Copyright 1990 Larry Medwin: @(#)chamber.c    1.5 2/9/90
  4.  *   Larry Medwin -- Dec. 18, 1989, April 14, 1991
  5.  */
  6.  
  7. #include "xgas.h"
  8. static void initWall();
  9. static void getLabDimensions();
  10.  
  11. /*
  12.  * Create Graphics Contexts
  13.  * Initialize client data structure
  14.  * Initialize allPos array of XRectangles
  15.  */
  16. void labInit(w, data)
  17.     Widget w;
  18.     LabData *data;
  19. {
  20.     int i, k;
  21.     Display *dpy = XtDisplay(w);
  22.     int scr = DefaultScreen(dpy);
  23.     unsigned long valuemask;
  24.     XGCValues values;
  25.  
  26.     /* Create GC for walls */
  27.     data->WallGC = XCreateGC( dpy, DefaultRootWindow(dpy), NULL, NULL);
  28.     XSetForeground( dpy, data->WallGC, data->foreground);
  29.  
  30.     /* Create GC for molecules */
  31.     valuemask = GCFunction | GCPlaneMask | GCForeground | GCBackground;
  32.     values.function = GXxor;
  33.     values.plane_mask = values.foreground =
  34.     data->background^data->foreground;
  35.     values.background = data->background;
  36.     data->MoleculeGC = XCreateGC( dpy, DefaultRootWindow(dpy),
  37.         valuemask, &values);
  38.  
  39.     /* Initialize the client data structure */
  40.     data->lab = w;
  41.     data->nmolecules = 0;
  42.     data->timestep = 0;
  43.     data->timer = 0;
  44.     data->time = 0;
  45.     
  46.     for (i=0; i<2; i++) data->chamber[i].temperature = (float)INITTEMP;
  47.  
  48.     /* Initialize the allPos array of molecule positions */
  49.     for( i=0; i<data->maxMolecules; i++) {
  50.     for( k=0; k<2; k++) {
  51.         data->allPos[2*i + k].width = (unsigned short) MOLECULE_SIZE;
  52.         data->allPos[2*i + k].height = (unsigned short) MOLECULE_SIZE;
  53.         }
  54.     }
  55.  
  56. }
  57.  
  58. /*
  59.  * LAB RESIZE -- handle resize events.  Makeing this a callback was the
  60.  *               sole reason for creating the gas widget.
  61.  */
  62. void labResize(w, data, call_data) /* ARGSUSED */
  63.     Widget w;
  64.     LabData *data;
  65.     caddr_t call_data;
  66. {
  67.     Coord p[8];
  68.  
  69.     /*
  70.      * Have to clear out the array of molecules, since some of them
  71.      * may be outside the walls or in the other box.
  72.      */
  73.     data->nmolecules = 0;
  74.  
  75.     /* Get dimensions of window in cm */
  76.     getLabDimensions( w, data);
  77.  
  78.     /* Init wall endpoints */
  79.     p[0].x = 0.0;        p[0].y = 0.0;
  80.     p[1].x = 0.0;        p[1].y = data->heightMM;
  81.     p[2].x = data->widthMM/2.0;    p[2].y = 0.0;
  82.     p[3].x = data->widthMM/2.0;    p[3].y = data->heightMM;
  83.     p[4].x = data->widthMM;    p[4].y = 0.0;
  84.     p[5].x = data->widthMM;    p[5].y = data->heightMM;
  85.     p[6].x = data->widthMM/2.0;    p[6].y = 0.4 * data->heightMM;
  86.     p[7].x = data->widthMM/2.0;    p[7].y = 0.6 * data->heightMM;
  87.  
  88.     initWall( &data->chamber[0].walls[0], p[6], p[7], RIGHT);
  89.     initWall( &data->chamber[0].walls[1], p[2], p[6], RIGHT);
  90.     initWall( &data->chamber[0].walls[2], p[0], p[2], TOP);
  91.     initWall( &data->chamber[0].walls[3], p[0], p[1], LEFT);
  92.     initWall( &data->chamber[0].walls[4], p[1], p[3], BOTTOM);
  93.     initWall( &data->chamber[0].walls[5], p[7], p[3], RIGHT);
  94.  
  95.     initWall( &data->chamber[1].walls[0], p[6], p[7], LEFT);
  96.     initWall( &data->chamber[1].walls[1], p[2], p[6], LEFT);
  97.     initWall( &data->chamber[1].walls[2], p[2], p[4], TOP);
  98.     initWall( &data->chamber[1].walls[3], p[4], p[5], RIGHT);
  99.     initWall( &data->chamber[1].walls[4], p[3], p[5], BOTTOM);
  100.     initWall( &data->chamber[1].walls[5], p[7], p[3], LEFT);
  101. }
  102.  
  103. /* INIT WALL */
  104. static void initWall( wall, end0, end1, type)
  105.     Wall *wall;
  106.     Coord end0, end1;
  107.     int type;
  108. {
  109.     wall->end[0].x = end0.x;
  110.     wall->end[0].y = end0.y;
  111.     wall->end[1].x = end1.x;
  112.     wall->end[1].y = end1.y;
  113.     wall->type = type;
  114. }
  115.  
  116. /*
  117.  * WHICH CORNER
  118.  *    return corner type or 0 if not a corner
  119.  */
  120. int whichCorner( x, y, box, data )
  121.     int x, y, box;
  122.     LabData *data;
  123. {
  124. int xmid = data->chamber[0].walls[0].end[0].x;
  125. int xend = data->widthMM;
  126. int ybot = data->heightMM;
  127.  
  128.     /* Check for each box: */
  129.     if (box == 0) {
  130.  
  131.     /* Check all four corner locations */
  132.     if (y == 0 && x == 0) return NW;
  133.     if (y == 0 && x == xmid) return NE;
  134.     if (y == ybot && x == 0) return SW;
  135.     if (y == ybot && x == xmid) return SE;
  136.  
  137.     /* Guess it's not a corner */
  138.     return 0;
  139.     }
  140.     else { /* box = 1 */
  141.     /* Check all four corner locations */
  142.     if (y == 0 && x == xmid) return NW;
  143.     if (y == 0 && x == xend) return NE;
  144.     if (y == ybot && x == xmid) return SW;
  145.     if (y == ybot && x == xend) return SE;
  146.  
  147.     /* Not a corner */
  148.     return 0;
  149.     }
  150. }
  151.  
  152. /* GET LAB DIMENSIONS */
  153. static void getLabDimensions( w, data)
  154.     Widget w;
  155.     LabData *data;
  156. {
  157.     Arg wargs[2];
  158.     int wPix, hPix;
  159.     float wMM, hMM;
  160.  
  161.     /* Get dimensions of lab Widget */
  162.     XtSetArg( wargs[0], XtNwidth, &data->width);
  163.     XtSetArg( wargs[1], XtNheight, &data->height);
  164.     XtGetValues( w, wargs, 2);
  165.  
  166.     /* Decrement height and width so that we can draw on these borders */
  167.     data->width --;
  168.     data->height --;
  169.  
  170.     /* Get scale factor in pixels/cm */
  171.     wPix = DisplayWidth( XtDisplay(w), DefaultScreen(XtDisplay(w)));
  172.     wMM = DisplayWidthMM( XtDisplay(w), DefaultScreen(XtDisplay(w)));
  173.     hPix = DisplayHeight( XtDisplay(w), DefaultScreen(XtDisplay(w)));
  174.     hMM = DisplayHeightMM( XtDisplay(w), DefaultScreen(XtDisplay(w)));
  175.  
  176.     data->scale.x = (int) ( wPix / wMM);
  177.     data->scale.y = (int) ( hPix / hMM);
  178.  
  179.     /* Get dimensions of Chamber in mm */
  180.     data->widthMM = (float)data->width / (float)data->scale.x;
  181.     data->heightMM = (float)data->height / (float)data->scale.y;
  182. }
  183.  
  184. /*
  185.  * LAB EXPOSE -- handle expose events
  186.  *
  187.  * drawing molecules with XOR
  188.  *   This event handler must guarantee that molecules are drawn
  189.  *   exactly once in their current positions, so that they will
  190.  *   be properly erased by the next XOR.
  191.  */
  192. void labExpose( w, data, event)    /* ARGSUSED */
  193.     Widget w;
  194.     LabData *data;
  195.     XEvent *event;
  196. {
  197.     int i, j;
  198.  
  199.     /*
  200.      * Clear the window first
  201.      *   to make sure that molecules are drawn an even # of times
  202.      *   on an exposed window
  203.      */
  204.     XClearWindow( XtDisplay(w), XtWindow(w));
  205.  
  206.     /* Redraw walls */
  207.     for( i=0; i<2; i++) {
  208.  
  209.     /* Draw walls of Chamber[i] */
  210.     for( j=1; j<NWALLS; j++) {
  211.         XDrawLine( XtDisplay(w), XtWindow(w), data->WallGC,
  212.             (int) (data->chamber[i].walls[j].end[0].x * data->scale.x),
  213.             (int) (data->chamber[i].walls[j].end[0].y * data->scale.y),
  214.             (int) (data->chamber[i].walls[j].end[1].x * data->scale.x),
  215.             (int) (data->chamber[i].walls[j].end[1].y * data->scale.y));
  216.         }
  217.     }
  218.  
  219.     /* Redraw molecules */
  220.     for( i=0; i<data->nmolecules; i++ ) {
  221.     XFillRectangle( XtDisplay(w), XtWindow(w), data->MoleculeGC,
  222.         (int) data->allPos[2*i + data->timestep % 2 ].x,
  223.         (int) data->allPos[2*i + data->timestep % 2 ].y,
  224.         (int) MOLECULE_SIZE, (int) MOLECULE_SIZE);
  225.     }
  226. }
  227.