home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / source / thesource6.dms / thesource6.adf / Source / Misc / ReactDiff.lha / ReactionDiffusion / graphics.c next >
Encoding:
C/C++ Source or Header  |  1993-01-29  |  10.9 KB  |  456 lines

  1. /*
  2.  
  3. Simple (and slow) interface to X11.
  4.  
  5. Permission is granted to modify and/or distribute this program so long
  6. as the program is distributed free of charge and this header is retained
  7. as part of the program.
  8.  
  9. Copyright (c) Greg Turk, 1991
  10.  
  11. */
  12.  
  13. #include <stdio.h>
  14. #include <X11/Xlib.h>
  15. #include <X11/Xatom.h>
  16. #include <math.h>
  17.  
  18. static Display *display;
  19. static int screen;
  20. static Window root;
  21.  
  22. static unsigned long foreground, background;
  23. static Cursor root_cursor;
  24. static int defDepth;
  25. static Visual     *defVisual;
  26. static Colormap defColormap;
  27.  
  28. static XFontStruct *RegFont;
  29. static XFontStruct *SmallFont;
  30. static XFontStruct *BigFont;
  31.  
  32. static GC gc_reg_font;        /* graphics context with regular font */
  33. static GC gc_small_font;    /* graphics context with small font */
  34. static GC gc_big_font;        /* graphics context with big font */
  35.  
  36. static GC gc;
  37. static XGCValues gcvalues;
  38. static XColor colors[256];
  39.  
  40. static num_colors;        /* number of colors allocated to window */
  41. static int psize = 1;        /* size of pixels */
  42.  
  43. static int screen_x;        /* screen size */
  44. static int screen_y;
  45. static int corner_x = 20;
  46. static int corner_y = 20;
  47.  
  48. static void draw_proc();
  49.  
  50. int (*press1)() = NULL;
  51. int (*press2)() = NULL;
  52. int (*press3)() = NULL;
  53. int (*release1)() = NULL;
  54. int (*release2)() = NULL;
  55. int (*release3)() = NULL;
  56.  
  57.  
  58. /******************************************************************************
  59. Create a window for graphics.
  60.  
  61. Entry:
  62.   w,h     - width and height of screen in pixels
  63.   ncolors - number of colors to allocate
  64. ******************************************************************************/
  65.  
  66. init_graphics(w,h,ncolors)
  67.   int w,h;
  68.   int ncolors;
  69. {
  70.   XSetWindowAttributes    attrib;
  71.  
  72.   /* Open a connection to the display. */
  73.   if ((display = XOpenDisplay (NULL)) == NULL) {
  74.     printf ("Couldn't open display:\n");
  75.     printf ("Make sure X11 is running and DISPLAY is set correctly\n");
  76.     exit (-1);
  77.   }
  78.   screen = XDefaultScreen (display);
  79.   num_colors = ncolors;
  80.  
  81. /*
  82. XSetErrorHandler (my_error_handler);
  83. */
  84.  
  85.   /* set up foreground, background colors (to Xdefaults, if any) */
  86.   if (XDisplayCells (display, screen) > 2)    /* this is a color display */
  87.     defColormap = XDefaultColormap (display, screen);
  88.  
  89.   foreground = XWhitePixel (display, screen);
  90.   background = XBlackPixel (display, screen);
  91.  
  92.   /* set up default depth, visual params */
  93.   defDepth = XDefaultDepth (display, screen);
  94.   defVisual = XDefaultVisual (display, screen);
  95.  
  96.   /* set up fonts */
  97.  
  98.   RegFont   = XLoadQueryFont (display, "8x13");
  99.   SmallFont = XLoadQueryFont (display, "6x10");
  100.   BigFont   = XLoadQueryFont (display, "9x15");
  101.  
  102.   if (RegFont == NULL || SmallFont == NULL || BigFont == NULL) {
  103.     printf ("Couldn't find all fonts.\n");
  104.   }
  105.  
  106.   /* create root cursor (left arrow) */
  107.   root_cursor = XCreateFontCursor (display, 68);
  108.  
  109.   screen_x = w;
  110.   screen_y = h;
  111.  
  112.   /* create root window */
  113.   attrib.background_pixel = background;
  114.   attrib.border_pixel = foreground;
  115.   attrib.override_redirect = True;
  116.   attrib.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask |
  117.               StructureNotifyMask;
  118.   attrib.cursor = root_cursor;
  119.   root = XCreateWindow (display, RootWindow(display, screen),
  120.           corner_x, corner_y,
  121.           screen_x, screen_y, 1, defDepth, InputOutput,
  122.           defVisual, CWBackPixel|CWBorderPixel|CWOverrideRedirect|
  123.           CWEventMask|CWCursor, &attrib);
  124.   XChangeProperty (display, root, XA_WM_NAME, XA_STRING, 8, PropModeReplace,
  125.       "Icon", 5);
  126.  
  127.   /* mapping windows */
  128.   XMapWindow (display, root);
  129.  
  130.   /* set up some graphics contexts */
  131.  
  132.   gcvalues.foreground = foreground;
  133.   gcvalues.background = background;
  134.   gcvalues.line_width = 1;
  135.   gcvalues.font = RegFont->fid;
  136.   gc_reg_font = XCreateGC (display, root,
  137.           GCForeground|GCBackground|GCLineWidth|GCFont,
  138.           &gcvalues);
  139.   gcvalues.font = SmallFont->fid;
  140.   gc_small_font = XCreateGC (display, root,
  141.           GCForeground|GCBackground|GCLineWidth|GCFont,
  142.           &gcvalues);
  143.   gcvalues.font = BigFont->fid;
  144.   gc_big_font = XCreateGC (display, root,
  145.           GCForeground|GCBackground|GCLineWidth|GCFont,
  146.           &gcvalues);
  147.  
  148.   /* setup colors */
  149.   init_colormap();
  150. }
  151.  
  152.  
  153. /******************************************************************************
  154. Specify the text to appear on the main window's icon.
  155. ******************************************************************************/
  156.  
  157. window_name(name)
  158.   char *name;
  159. {
  160.   XChangeProperty (display, root, XA_WM_NAME, XA_STRING, 8, PropModeReplace,
  161.       name, strlen (name));
  162. }
  163.  
  164.  
  165. /******************************************************************************
  166. Specify upper left corner of window.
  167. ******************************************************************************/
  168.  
  169. window_corner(x,y)
  170.   int x,y;
  171. {
  172.   corner_x = x;
  173.   corner_y = y;
  174. }
  175.  
  176.  
  177. /******************************************************************************
  178. My own error handler.
  179. ******************************************************************************/
  180.  
  181. my_error_handler(disp,event)
  182.   Display *disp;
  183.   XErrorEvent *event;
  184. {
  185.   float x;
  186.  
  187.   printf ("You got an error.\n");
  188.   x = 0;
  189.   x = 1 / x;
  190. }
  191.  
  192.  
  193. /******************************************************************************
  194. Make grey ramp.
  195. ******************************************************************************/
  196.  
  197. grey_ramp()
  198. {
  199.   XStoreColors (display, defColormap, colors, num_colors);
  200. }
  201.  
  202.  
  203. /******************************************************************************
  204. Initialize the color map.
  205. ******************************************************************************/
  206.  
  207. init_colormap()
  208. {
  209.   int i;
  210.   int status;
  211.   float t;
  212.   unsigned long plane_masks[8];
  213.   unsigned long pixels[256];
  214.  
  215.   status = XAllocColorCells (display, defColormap,
  216.        0, plane_masks, 0, pixels, num_colors);
  217.  
  218.   if (status == 0) {
  219.     printf ("bad status from XAllocColorCells\n");
  220.     return;
  221.   }
  222.  
  223.   /* create grey ramp */
  224.  
  225.   for (i = 0; i < num_colors; i++) {
  226.     t = 65535 * i / (num_colors - 1.0);
  227.     colors[i].red   = t;
  228.     colors[i].green = t;
  229.     colors[i].blue  = t;
  230.     colors[i].pixel = pixels[i];
  231.     colors[i].flags = DoRed | DoGreen | DoBlue;
  232.   }
  233.  
  234.   XStoreColors (display, defColormap, colors, num_colors);
  235.  
  236.   gcvalues.foreground = foreground;
  237.   gcvalues.background = background;
  238.   gc = XCreateGC (display, root, GCForeground|GCBackground, &gcvalues);
  239. }
  240.  
  241.  
  242. /******************************************************************************
  243. Place a red,green,blue triple in the color lookup table.
  244.  
  245. Entry:
  246.   index - index to place color
  247.   r,g,b - red, green and blue values to place in table
  248. ******************************************************************************/
  249.  
  250. makecolor (index,r,g,b)
  251.   int index;
  252.   int r,g,b;
  253. {
  254.   XColor col;
  255.  
  256.   index = (index / 255.0) * (num_colors - 1);
  257.  
  258.   if (index < 0 || index >= num_colors) {
  259.     printf ("makecolor index out of bounds: %d\n", index);
  260.     return;
  261.   }
  262.  
  263.   col.red   = 65535 * (r / 255.0);
  264.   col.green = 65535 * (g / 255.0);
  265.   col.blue  = 65535 * (b / 255.0);
  266.   col.pixel = colors[index].pixel;
  267.   col.flags = DoRed | DoGreen | DoBlue;
  268.   XStoreColor (display, defColormap, &col);
  269. }
  270.  
  271.  
  272. /******************************************************************************
  273. Set the size of pixels.
  274. ******************************************************************************/
  275.  
  276. set_pixel_size (size)
  277. int size;
  278. {
  279.   psize = size;
  280. }
  281.  
  282.  
  283. /******************************************************************************
  284. Write a pixel to the screen.
  285. ******************************************************************************/
  286.  
  287. writepixel (x,y,color)
  288.   int x,y;
  289.   int color;
  290. {
  291.   color = (color / 255.0) * (num_colors - 1);
  292.  
  293.   gcvalues.foreground = colors[color].pixel;
  294.   XChangeGC (display, gc, GCForeground, &gcvalues);
  295.   XFillRectangle (display, root, gc, x * psize, y * psize, psize, psize);
  296. }
  297.  
  298.  
  299. /******************************************************************************
  300. Flush the pixel buffers.
  301. ******************************************************************************/
  302.  
  303. flushbuffers()
  304. {
  305.   XFlush (display);
  306. }
  307.  
  308.  
  309. /******************************************************************************
  310. Clear the screen.
  311. ******************************************************************************/
  312.  
  313. clear_screen()
  314. {
  315.   XClearWindow (display, root);
  316.   XFlush (display);
  317. }
  318.  
  319.  
  320. /******************************************************************************
  321. Draw a line.
  322.  
  323. Entry:
  324.   x,y   - one endpoint of line
  325.   x2,y2 - other endpoint
  326.   color - color of line
  327. ******************************************************************************/
  328.  
  329. line (x,y,x2,y2,color)
  330.   int x,y;
  331.   int x2,y2;
  332.   int color;
  333. {
  334.   if (abs(x - x2) > 4 * screen_x || abs(y - y2) > 4 * screen_y) {
  335.     printf ("error in line(), x y x2 y2: %d %d %d %d\n", x, y, x2, y2);
  336.     return;
  337.   }
  338.  
  339.   color = (color / 255.0) * (num_colors - 1);
  340.  
  341.   gcvalues.foreground = colors[color].pixel;
  342.   XChangeGC (display, gc, GCForeground, &gcvalues);
  343.   XDrawLine (display, root, gc, x * psize, y * psize, x2 * psize, y2 * psize);
  344. }
  345.  
  346.  
  347. /******************************************************************************
  348. Draw a string of text.
  349. ******************************************************************************/
  350.  
  351. draw_text(text,x,y)
  352.   char *text;
  353.   int x,y;
  354. {
  355.   XDrawString (display, root, gc_reg_font, x, y, text, strlen (text));
  356. }
  357.  
  358.  
  359. /******************************************************************************
  360. Event handler for drawing area.
  361. ******************************************************************************/
  362.  
  363. static void draw_proc (data,event)
  364.   char *data;
  365.   XEvent *event;
  366. {
  367.   XButtonEvent *button;
  368.  
  369.   button = (XButtonEvent *) event;
  370.   
  371.   switch(event->type) {
  372.  
  373.     case ButtonPress:
  374.       switch (button->button) {
  375.     case Button1:
  376.       if (press1)
  377.         (*press1)(button->x, button->y);
  378.       break;
  379.     case Button2:
  380.       if (press2)
  381.         (*press2)(button->x, button->y);
  382.       break;
  383.     case Button3:
  384.       if (press3)
  385.         (*press3)(button->x, button->y);
  386.       break;
  387.       }
  388.       break;
  389.  
  390.     case ButtonRelease:
  391.       switch (button->button) {
  392.     case Button1:
  393.       if (release1)
  394.         (*release1)(button->x, button->y);
  395.       break;
  396.     case Button2:
  397.       if (release2)
  398.         (*release2)(button->x, button->y);
  399.       break;
  400.     case Button3:
  401.       if (release3)
  402.         (*release3)(button->x, button->y);
  403.       break;
  404.       }
  405.       break;
  406.  
  407.     case Expose:
  408.       break;
  409.   }
  410. }
  411.  
  412.  
  413. /******************************************************************************
  414. Check to see if events need processing.
  415. ******************************************************************************/
  416.  
  417. check_events()
  418. {
  419.   XEvent event;
  420.   XAnyEvent *e;
  421.  
  422.   while (XPending (display)) {
  423.  
  424.     XNextEvent (display, &event);
  425.     e = (XAnyEvent *) &event;
  426.  
  427.     if (e->window == root)
  428.       draw_proc (NULL, &event);
  429.     else {
  430.       printf ("check_events(): Oops, unknown event.\n");
  431.     }
  432.   }
  433. }
  434.  
  435.  
  436. /******************************************************************************
  437. Set up callback functions for button presses.
  438. ******************************************************************************/
  439.  
  440. setup_buttons(p1,p2,p3,r1,r2,r3)
  441.   int (*p1)();
  442.   int (*p2)();
  443.   int (*p3)();
  444.   int (*r1)();
  445.   int (*r2)();
  446.   int (*r3)();
  447. {
  448.   press1 = p1;
  449.   press2 = p2;
  450.   press3 = p3;
  451.   release1 = r1;
  452.   release2 = r2;
  453.   release3 = r3;
  454. }
  455.  
  456.