home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #2 / amigaacscoverdisc1998-021998.iso / utilities / shareware / dev / libx11 / graphics_examples / class5.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-31  |  27.1 KB  |  1,313 lines

  1.  
  2.  
  3. /*
  4.   Program Four 
  5.   Bert Nelson
  6.   Copyright 1992 Bert Nelson
  7.  
  8.   Compile Instructions:  cc file.c -lX11 -lm -o file
  9.  
  10.   Run Instructions:  type 'file' after compiling and click an item
  11.              from the menu bar to do an option
  12.     
  13.   Program Purpose:  Display how multiple graphical transformations
  14.                     are done.  The program will ask the user to
  15.                     draw the figure and then ask for transformations
  16.                     will display the original figure in red while
  17.                     the transformed figure is in blue.
  18.  
  19.  
  20.  
  21.    Permission to use, copy, modify, and distribute this software and its
  22.    documentation for any purpose and without fee is hereby granted,
  23.    provided that the above copyright notice appear in all copies and that
  24.    both that copyright notice and this permission notice appear in
  25.    supporting documentation.  It is provided "as is" without any express or
  26.    implied warranty.
  27.  
  28.    Bert Nelson DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  29.    ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  30.    Bert Nelson BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  31.    ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  32.    WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  33.    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  34.    SOFTWARE.
  35.  
  36.  
  37.   */
  38.  
  39. #define LEFT 1
  40. #define MIDDLE 2
  41. #define RIGHT 3
  42. #define XOFF 500
  43. #define YOFF 350
  44. #define TRUE 1
  45. #define FALSE 0
  46.  
  47. #include <X11/Xlib.h>
  48. #include <X11/Xutil.h>
  49. #include <X11/cursorfont.h>
  50. #include <string.h>
  51. #include <math.h>
  52. #include <X11/keysym.h>
  53. #define PI 3.141592654    /* set up PI defintion */
  54.  
  55. int  rotate_angle; /* of rotation */
  56. int rotate_x;
  57. int rotate_y;
  58.  
  59.  
  60. float scalef_x;
  61. float scalef_y;
  62. int   scale_x;
  63. int   scale_y;
  64.  
  65.  
  66. int x_off = 500;
  67. int y_off = 350;
  68.  
  69.  
  70. struct 
  71. trans
  72. {
  73.     int x;
  74.     int dummy;
  75.     int y;
  76. };
  77.  
  78.  
  79. /* set strings as global */
  80. int sides;
  81.  
  82. char hello[] = "Transformations II - by Bert Nelson";
  83. char enter_str[] = "Enter";
  84. char trans_str[] = "Translate";
  85. char scale_str[] = "Scale";
  86. char rotate_str[] = "Rotate";
  87. char view_str[] = "View";
  88. char reset_str[] = "Reset";
  89. char quit_str[] = "Quit";
  90. Font font;
  91. int number;
  92. struct trans translate;
  93.  
  94. XPoint points[9];
  95. XPoint newpoints[9];
  96.  
  97. unsigned long black,white;
  98. float matrix[3][3];
  99. float tmatrix[3][3];
  100.  
  101.  
  102.  
  103. static char *ncolors[9] = {
  104.     " ", "blue","red","green",
  105.     "magenta1","brown","chocolate",
  106.     "gold1","DarkOrchid4"};
  107. Colormap color_map;
  108. XColor colors[9];
  109. XColor exact_colors[9];
  110.  
  111.  
  112. main(argc,argv)
  113. int argc;
  114. char **argv;
  115. {
  116.     Display *mydisplay;
  117.     Window  mywindow,child1,child2,child3,child4,child5,child6,child7;
  118.     GC enter_gc,mygc;
  119.     XEvent myevent;
  120.     KeySym mykey;
  121.     XSizeHints myhint;
  122.     XGCValues gvalues;
  123.     XComposeStatus cs;
  124.     char string[20];
  125.     char newstring[20];
  126.     int nchar;
  127.     int count;
  128.  
  129.     int myscreen;
  130.     unsigned long myforeground, mybackground;
  131.     int i;
  132.     char text[10];
  133.     int done;
  134.  
  135.  
  136.     /* set up display and foreground/background */
  137.  
  138.     mydisplay = XOpenDisplay("");
  139.      make_identity2(mydisplay);
  140.  
  141.  
  142.  
  143.  
  144.     myscreen = DefaultScreen (mydisplay);
  145.     white = mybackground = WhitePixel (mydisplay, myscreen);
  146.     black = myforeground = BlackPixel (mydisplay, myscreen);
  147.  
  148.     /* create a window with a size of 1000 x 700 */
  149.  
  150.     myhint.x = 0;
  151.     myhint.y = 0;
  152.     myhint.width = 1000;
  153.     myhint.height = 700;
  154.     myhint.flags = PPosition | PSize;
  155.     mywindow = XCreateSimpleWindow (mydisplay,
  156.         DefaultRootWindow (mydisplay),
  157.         myhint.x, myhint.y, myhint.width, myhint.height,
  158.         5, myforeground, mybackground);
  159.  
  160.  
  161.     /* create children windows that will act as menu buttons */
  162.  
  163.     child1 = XCreateSimpleWindow (mydisplay,mywindow,
  164.         0,0,100,25,2,myforeground,mybackground);
  165.  
  166.  
  167.     child2 = XCreateSimpleWindow (mydisplay,mywindow,
  168.         100,0,100,25,2,myforeground,mybackground);
  169.  
  170.  
  171.     child3 = XCreateSimpleWindow (mydisplay,mywindow,
  172.         200,0,100,25,2,myforeground,mybackground);
  173.  
  174.  
  175.     child4 = XCreateSimpleWindow (mydisplay,mywindow,
  176.         300,0,100,25,2,myforeground,mybackground);
  177.  
  178.  
  179.     child5 = XCreateSimpleWindow (mydisplay,mywindow,
  180.         400,0,100,25,2,myforeground,mybackground);
  181.  
  182.  
  183.     child6 = XCreateSimpleWindow (mydisplay,mywindow,
  184.         500,0,100,25,2,myforeground,mybackground);
  185.  
  186.  
  187.     child7 = XCreateSimpleWindow (mydisplay,mywindow,
  188.         600,0,200,25,2,myforeground,mybackground);
  189.  
  190.     /* print program name at the top */
  191.  
  192.     XSetStandardProperties (mydisplay, mywindow, hello, hello,
  193.         None, argv, argc, &myhint);
  194.  
  195.     /* set up foreground/backgrounds and set up colors */
  196.  
  197.  
  198.     mygc = XCreateGC (mydisplay, mywindow, 0, 0);
  199.  
  200.     gvalues.foreground = myforeground;
  201.     gvalues.background = mybackground;
  202.  
  203.     enter_gc = XCreateGC(mydisplay,child1,0,0);
  204.  
  205.     color_set_up(mydisplay);
  206.  
  207.     XSetBackground (mydisplay, mygc, mybackground);
  208.     XSetForeground (mydisplay, mygc, myforeground);
  209.     XSetBackground (mydisplay,enter_gc,myforeground);
  210.     XSetForeground (mydisplay,enter_gc,mybackground);
  211.  
  212.  
  213.     /* Load up a font called 8x16 */
  214.  
  215.     font = XLoadFont(mydisplay,"8x16");
  216.     XSetFont(mydisplay,mygc,font);
  217.     XSetFont(mydisplay,enter_gc,font);
  218.  
  219.     /* Ask for input from the mouse and keyboard */
  220.  
  221.     XSelectInput (mydisplay, mywindow,
  222.         ButtonPressMask | KeyPressMask | ExposureMask);
  223.  
  224.     /* map window to the screen */
  225.     XMapRaised (mydisplay, mywindow);
  226.  
  227.     /* Map children windows to the screen */
  228.  
  229.     XMapRaised (mydisplay, child1);
  230.     XMapRaised (mydisplay, child2);
  231.     XMapRaised (mydisplay, child3);
  232.     XMapRaised (mydisplay, child4);
  233.     XMapRaised (mydisplay, child5);
  234.     XMapRaised (mydisplay, child6);
  235.     XMapRaised (mydisplay, child7);
  236.  
  237.     /* Display menu strings */
  238.  
  239.     XNextEvent(mydisplay,&myevent);
  240.  
  241.     XDrawImageString(mydisplay,child1,mygc,
  242.         25,20,enter_str,strlen(enter_str));
  243.  
  244.  
  245.     XDrawImageString(mydisplay,child2,mygc,
  246.         5,20,trans_str,strlen(trans_str));
  247.  
  248.  
  249.     XDrawImageString(mydisplay,child3,mygc,
  250.         25,20,scale_str,strlen(scale_str));
  251.  
  252.  
  253.     XDrawImageString(mydisplay,child4,mygc,
  254.         25,20,rotate_str,strlen(rotate_str));
  255.  
  256.  
  257.     XDrawImageString(mydisplay,child5,mygc,
  258.         25,20,view_str,strlen(view_str));
  259.  
  260.     XDrawImageString(mydisplay,child6,mygc,
  261.         25,20,reset_str,strlen(reset_str));
  262.  
  263.     XDrawImageString(mydisplay,child7,mygc,
  264.         85,20,quit_str,strlen(quit_str));
  265.  
  266.  
  267.     /* Loop through until a q is press when the cursor is in
  268.            the window, which will cause the application to quit */
  269.  
  270.     done = 0;
  271.     while (done == 0) {
  272.         XNextEvent (mydisplay, &myevent );
  273.  
  274.         if (myevent.type == ButtonPress)
  275.         {
  276.  
  277.             if (myevent.xbutton.subwindow == child1)
  278.             {
  279.                 make_identity2(mydisplay);
  280.                 process_enter(mydisplay,mywindow,
  281.                     child1,mygc,enter_gc);
  282.  
  283.             }
  284.  
  285.             if (myevent.xbutton.subwindow == child2)
  286.             
  287.                 process_translate(mydisplay,mywindow,child2,
  288.                     mygc,enter_gc);
  289.  
  290.             if (myevent.xbutton.subwindow == child3)
  291.                 process_scale(mydisplay,mywindow,child3,
  292.                     mygc,enter_gc);
  293.  
  294.             if (myevent.xbutton.subwindow == child4)
  295.                 process_rotate(mydisplay,mywindow,child4,
  296.                     mygc,enter_gc);
  297.  
  298.             if (myevent.xbutton.subwindow == child5)
  299.  
  300.                 process_view(mydisplay,mywindow,child5,
  301.                     mygc,enter_gc);
  302.  
  303.  
  304.             if (myevent.xbutton.subwindow == child6)
  305.  
  306.                 process_reset(mydisplay,mywindow,child6,
  307.                     mygc,enter_gc);
  308.  
  309.  
  310.             if (myevent.xbutton.subwindow == child7)
  311.  
  312.  
  313.             {
  314.                 done = 1;
  315.                 break;
  316.             }
  317.  
  318.         }
  319.  
  320.  
  321.         if (myevent.xany.window == mywindow)
  322.         {
  323.             switch (myevent.type) {
  324.  
  325.             case KeyPress:
  326.  
  327.                 {
  328.                     i = XLookupString (&myevent, 
  329.                         text, 10, &mykey, 0);
  330.                     if (i == 1 && text[0] == 'q')
  331.                         done = 1;
  332.                     break;
  333.  
  334.                 } /* case  */
  335.             } /* switch */
  336.  
  337.         } /* end if */
  338.     } /* while */
  339.  
  340.     /* Free up and clean up the windows created */
  341.  
  342.     XFreeGC (mydisplay, mygc);
  343.     XDestroyWindow (mydisplay, mywindow);
  344.     XCloseDisplay (mydisplay);
  345.  
  346.     exit(0);
  347.  
  348.  
  349. }
  350.  
  351. /* Ask for the user to enter the number of sides and the points
  352. for each side.  By definition there are n+1 sides in reality because
  353. you need to draw back to where you started from, so the last point
  354. is assigned to the first point, which makes entering the points
  355. in order important */
  356.  
  357.  
  358. process_enter(display,parent,child,parent_gc,child_gc)
  359.  
  360. Display *display;
  361. Window parent,child;
  362. GC parent_gc,child_gc;
  363. {
  364.  
  365.     int i,j,offy,offx;
  366.     Window enter_window;
  367.     XEvent enter_event;
  368.     Font enter_font;
  369.     GC enter_gc;
  370.     int count;
  371.     char text[10];
  372.     int string[10];
  373.     KeySym key;
  374.         int old_x;
  375.     int old_y;
  376.     Cursor curs;
  377.  
  378.     /* Flash the Enter button on and off */
  379.  
  380.     XClearWindow(display,child);
  381.     XFillRectangle(display,child,parent_gc,0,0,100,25);
  382.     XDrawImageString(display,child,child_gc,
  383.         25,20,enter_str,strlen(enter_str));
  384.     XFlush(display);
  385.     for (i=0; i<1000; i++)
  386.         XNoOp(display);
  387.     XClearWindow(display,child);
  388.     XDrawImageString(display,child,parent_gc,
  389.         25,20,enter_str,strlen(enter_str));
  390.  
  391.  
  392.     /* change cursor to a cross hair */
  393.  
  394.     curs = XCreateFontCursor(display,XC_crosshair);
  395.     XDefineCursor(display,parent,curs);  
  396.  
  397.  
  398.     XSelectInput(display,parent,ButtonPressMask|KeyPressMask);
  399.  
  400.   /* Draw x and y axis */
  401.  
  402.         XDrawLine(display,parent,parent_gc,XOFF,0,XOFF,YOFF*2);
  403.         XDrawLine(display,parent,parent_gc,0,YOFF,XOFF*2,YOFF);
  404.  
  405.         /* Draw notches in x and y axis */
  406.  
  407.         for (i=25; i<YOFF*2; i=i+25)
  408.                 XDrawLine(display,parent,parent_gc,
  409.                     XOFF-5,i,XOFF+5,i);
  410.  
  411.         for (i=25; i<XOFF*2; i= i+25)
  412.                 XDrawLine(display,parent,parent_gc,
  413.                     i,YOFF-5,i,YOFF+5);
  414.         do
  415.         {
  416.                 XNextEvent(display,&enter_event);
  417.  
  418.                 if (enter_event.type == ButtonPress && 
  419.                 enter_event.xbutton.button == LEFT)
  420.  
  421.                 {
  422.             old_x = enter_event.xbutton.x;
  423.             old_y = enter_event.xbutton.y;
  424.      
  425.         } 
  426.  
  427.  
  428.     } while (enter_event.type != ButtonPress);        
  429.  
  430.  
  431.         i = 0;
  432.  
  433.  
  434.  
  435.         do
  436.         {
  437.                 XNextEvent(display,&enter_event);
  438.  
  439.                 if (enter_event.type = ButtonPress && 
  440.             enter_event.xbutton.button == LEFT)
  441.  
  442.                 {
  443.  
  444.                         points[i].x = enter_event.xbutton.x ;
  445.                         points[i].y = enter_event.xbutton.y;
  446.                         XFlush(display);
  447.  
  448.  
  449.                 XDrawLine(display,parent,parent_gc,old_x,old_y,
  450.                                 points[i].x,points[i].y);
  451.  
  452.                 old_x = points[i].x;
  453.                 old_y = points[i].y;
  454.  
  455.  
  456.                 i = i + 1;
  457.  
  458.                 }
  459.         } while (enter_event.xbutton.button != RIGHT);
  460.  
  461.  
  462.                 sides = 0;
  463.  
  464.                 sides = i;
  465.  
  466.  
  467.         for (i=0; i<sides; i++)
  468.                 {
  469.  
  470.  
  471.                 if ( points[i].x > XOFF)
  472.                         points[i].x = points[i].x - XOFF;
  473.                 else
  474.              points[i].x = -1 * abs (points[i].x - XOFF); 
  475.                         
  476. /*
  477. points[i].x = -1 * abs(XOFF - points[i].x);
  478. */ 
  479.                 if ( points[i].y > YOFF)
  480.                         points[i].y = YOFF - points[i].y;
  481.                 else
  482.                         points[i].y = abs (YOFF - points[i].y);
  483.  
  484.  
  485.  
  486.  
  487.                 }
  488.  
  489.     /* clear screen and exit if less than 3 sides or greater than 8 */ 
  490.  
  491.     if (sides <3 || sides > 8)
  492.     {
  493.         XUndefineCursor(display,parent);
  494.  
  495.         sides = 0;
  496.         XClearWindow(display,parent);    
  497.         return(0);
  498.     }
  499.  
  500.     /* change the mouse pointer back to normal */
  501.  
  502.     XUndefineCursor(display,parent);
  503.  
  504. }
  505.  
  506. /* Ask user to enter in the x and y translation factors for the figure */
  507.  
  508.  
  509. process_translate(display,parent,child,parent_gc,child_gc)
  510.  
  511. Display *display;
  512. Window parent,child;
  513. GC parent_gc,child_gc;
  514. {
  515.  
  516.     int i,off;
  517.     Window trans_window;
  518.     XEvent trans_event;
  519.     Font trans_font;
  520.     GC trans_gc;
  521.     int count;
  522.     char text[10];
  523.     int string[10];
  524.     KeySym key=0;
  525.     Cursor curs;
  526.  
  527.     /* Flash the Translate button on and off */
  528.  
  529.     XClearWindow(display,child);
  530.     XFillRectangle(display,child,parent_gc,0,0,100,25);
  531.     XDrawImageString(display,child,child_gc,
  532.         5,20,trans_str,strlen(trans_str));
  533.     XFlush(display);
  534.     for (i=0; i<1000; i++)
  535.         XNoOp(display);
  536.     XClearWindow(display,child);
  537.     XDrawImageString(display,child,parent_gc,
  538.         5,20,trans_str,strlen(trans_str));
  539.  
  540.     
  541.     XClearWindow(display,parent);
  542.  
  543.  
  544.     /* Draw x and y axis */
  545.  
  546.         XDrawLine(display,parent,parent_gc,XOFF,0,XOFF,YOFF*2);
  547.         XDrawLine(display,parent,parent_gc,0,YOFF,XOFF*2,YOFF);
  548.  
  549.         /* Draw notches in x and y axis */
  550.  
  551.         for (i=25; i<YOFF*2; i=i+25)
  552.                 XDrawLine(display,parent,parent_gc,
  553.                     XOFF-5,i,XOFF+5,i);
  554.  
  555.         for (i=25; i<XOFF*2; i= i+25)
  556.                 XDrawLine(display,parent,parent_gc,
  557.                     i,YOFF-5,i,YOFF+5);
  558.  
  559.  
  560.  
  561.  
  562.     /* change the cursor to a crosss */
  563.  
  564.         curs = XCreateFontCursor(display,XC_cross);
  565.         XDefineCursor(display,parent,curs);
  566.  
  567.  
  568.  
  569.  
  570.  
  571.   do
  572.         {
  573.                 XNextEvent(display,&trans_event);
  574.  
  575.                 if (trans_event.type == ButtonPress &&
  576.                                 trans_event.xbutton.button == LEFT)
  577.  
  578.                 {
  579.                         translate.x = trans_event.xbutton.x;
  580.                         translate.y = trans_event.xbutton.y;
  581.  
  582.                 }
  583.  
  584.  
  585.         } while (trans_event.type != ButtonPress);
  586.  
  587.  
  588.                 if ( translate.x > XOFF)
  589.                         translate.x = translate.x - XOFF;
  590.                 else
  591.                         translate.x = -1 * abs (translate.x - XOFF);
  592.  
  593.                 if ( translate.y > YOFF)
  594.                         translate.y = YOFF - translate.y;
  595.                 else
  596.                         translate.y = abs (YOFF - translate.y);
  597.  
  598.  
  599.  
  600.  
  601.     /* do the translation */
  602.  
  603.     make_identity(display);
  604.  
  605.     matrix[2][0] = translate.x;
  606.     matrix[2][1] = translate.y;
  607.  
  608.     combine_transformations(display);
  609.  
  610.  
  611.     /* return the cursor to the default one */
  612.  
  613.     XUndefineCursor(display,parent);
  614.  
  615.  
  616. }
  617.  
  618.  
  619.  
  620. /* Prompt user to input scale factors and where to scale about.
  621.    Note:  A scale factor of 1 = current size, but a scale factor
  622.           of zero will cause nothing to be displayed */
  623.  
  624. process_scale(display,parent,child,parent_gc,child_gc)
  625.  
  626.  
  627. Display *display;
  628. Window parent,child;
  629. GC parent_gc,child_gc;
  630. {
  631.  
  632.     int i;
  633.  
  634.     Window scale_window;
  635.     XEvent scale_event;
  636.     Font scale_font;
  637.     GC scale_gc;
  638.     int count;
  639.     char text[10];
  640.     int string[10];
  641.     KeySym key=0;
  642.     Cursor curs;
  643.  
  644.  
  645.     /* turn on and off the scale button */
  646.  
  647.     XClearWindow(display,child);
  648.     XFillRectangle(display,child,parent_gc,0,0,100,25);
  649.     XDrawImageString(display,child,child_gc,
  650.         25,20,scale_str,strlen(scale_str));
  651.     XFlush(display);
  652.     for (i=0; i<10; i++)
  653.         XNoOp(display);
  654.     XClearWindow(display,child);
  655.     XDrawImageString(display,child,parent_gc,
  656.         25,20,scale_str,strlen(scale_str));
  657.  
  658.  
  659.     /* Create pop up window for the user */
  660.  
  661.     scale_window = XCreateSimpleWindow(display,parent,340,200,
  662.         300,200,3,black,white);
  663.  
  664.     scale_gc = parent_gc;
  665.  
  666.  
  667.     XMapRaised(display,scale_window);
  668.     XClearWindow(display,scale_window);
  669.  
  670.     XDrawString(display,scale_window,parent_gc,
  671.         95,25,"Scale Figure",12);
  672.  
  673.  
  674.     XSelectInput(display,scale_window,ButtonPressMask|KeyPressMask);
  675.  
  676.  
  677.  
  678.     /* Load up a smaller font */
  679.  
  680.     font = XLoadFont(display,"7x13");
  681.     XSetFont(display,scale_gc,font);
  682.  
  683.     /* prompt user for input */
  684.  
  685.  
  686.     XDrawString(display,scale_window,scale_gc,
  687.         15,75,"Enter X Factor of Scaling: ",
  688.         27);
  689.  
  690.  
  691.     /* set up values */
  692.  
  693.  
  694.     XFlush(display);
  695.     key = 0;
  696.     text[0] = '\0';
  697.     string[0] = '\0';
  698.     i = 195;
  699.  
  700.  
  701.     /* accept a series of characters until the RETURN key is pressed */
  702.  
  703.     do
  704.     {
  705.         i = i + 8;
  706.  
  707.         XNextEvent(display,&scale_event);
  708.  
  709.         count = XLookupString(&scale_event,text,10,&key,0);
  710.  
  711.         text[count] = '\0';
  712.         if (key != XK_Return)
  713.             XDrawString(display,scale_window,scale_gc,
  714.                 i,75,text,1);
  715.  
  716.         strcat(string,text);
  717.     }        while (key != XK_Return && scale_event.type == KeyPress);
  718.  
  719.     /* convert a string to a floating point number so fractional
  720.            values can be used e.g. .4, .25, 1.5 etc. */
  721.  
  722.     scalef_x = atof(string);
  723.  
  724.  
  725.     /* Clear the buffers and ask for a Y scale factor */
  726.  
  727.     XFlush(display);
  728.  
  729.     XDrawString(display,scale_window,scale_gc,
  730.         15,105,"Enter Y Factor of Scaling: ",
  731.         27);
  732.     while (scale_event.type != KeyPress)
  733.         XNextEvent(display,&scale_event);
  734.     key = 0;
  735.     text[0] = '\0';
  736.     string[0] = '\0';
  737.  
  738.  
  739.     /* ask for input until a RETURN key is pressed */
  740.  
  741.     i = 195;
  742.  
  743.     do
  744.     {
  745.         i = i + 8;
  746.         XNextEvent(display,&scale_event);
  747.         count = XLookupString(&scale_event,text,10,&key,0);
  748.         text[count] = '\0';
  749.         if (key != XK_Return)
  750.             XDrawString(display,scale_window,scale_gc,
  751.                 i,105,text,1);
  752.         strcat(string,text);
  753.     }        while (key != XK_Return && scale_event.type == KeyPress);
  754.  
  755.     /* convert input to a floating point number */
  756.  
  757.     scalef_y = atof(string);
  758.  
  759.     XFlush(display);
  760.  
  761.         font = XLoadFont(display,"8x16");
  762.         XSetFont(display,scale_gc,font);
  763.  
  764.  
  765.  
  766.         /* trash the window */
  767.  
  768.         XDestroyWindow(display,scale_window);
  769.  
  770.     XClearWindow(display,parent);
  771.  
  772.  
  773.         /* draw x and y axis */
  774.  
  775.         XDrawLine(display,parent,parent_gc,XOFF,0,XOFF,YOFF*2);
  776.         XDrawLine(display,parent,parent_gc,0,YOFF,XOFF*2,YOFF);
  777.  
  778.         /* Draw notches in x and y axis */
  779.  
  780.         for (i=25; i<YOFF*2; i=i+25)
  781.                 XDrawLine(display,parent,parent_gc,
  782.                     XOFF-5,i,XOFF+5,i);
  783.  
  784.         for (i=25; i<XOFF*2; i= i+25)
  785.                 XDrawLine(display,parent,parent_gc,
  786.                     i,YOFF-5,i,YOFF+5);
  787.  
  788.  
  789.           XSelectInput(display,parent,ButtonPressMask|KeyPressMask);
  790.  
  791.  
  792.     /* change the cursor to a crosss */
  793.  
  794.         curs = XCreateFontCursor(display,XC_cross_reverse);
  795.         XDefineCursor(display,parent,curs);
  796.  
  797.         /* ask user to enter a point to rotate about */
  798.  
  799.         do
  800.         {
  801.                 XNextEvent(display,&scale_event);
  802.  
  803.                 if (scale_event.type == ButtonPress &&
  804.                                 scale_event.xbutton.button == LEFT)
  805.                 {
  806.                         scale_x = scale_event.xbutton.x;
  807.                         scale_y = scale_event.xbutton.y;
  808.                 }
  809.         } while (scale_event.type != ButtonPress);
  810.  
  811.  
  812.     /* revert back to default cursor */
  813.  
  814.     XUndefineCursor(display,parent);
  815.  
  816.  
  817.     /* change the values back to something the program can use */
  818.  
  819.  
  820.         if ( scale_x > XOFF)
  821.                 scale_x = scale_x - XOFF;
  822.         else
  823.                 scale_x = -1 * abs (scale_x - XOFF);
  824.  
  825.  
  826.         if ( scale_y > YOFF)
  827.                 scale_y = YOFF - scale_y;
  828.         else
  829.             scale_y = abs (YOFF - scale_y);
  830.  
  831.         /* set up the identity matrix */
  832.  
  833.         make_identity(display);
  834.  
  835.  
  836.     /* Assign matrix values */
  837.  
  838.     matrix[0][0] = scalef_x;
  839.     matrix[1][1] = scalef_y;
  840.     matrix[2][0] = (1-scalef_x) * scale_x;
  841.     matrix[2][1] = (1-scalef_y) * scale_y;
  842.  
  843.     /* Multiply matrices */
  844.  
  845.     combine_transformations(display);
  846.  
  847. }
  848.  
  849. /* Promp the user to enter an angle in DEGREES! and a point to
  850.    rotate the figure about */
  851.  
  852.  
  853. process_rotate(display,parent,child,parent_gc,child_gc)
  854.  
  855.  
  856. Display *display;
  857. Window parent,child;
  858. GC parent_gc,child_gc;
  859. {
  860.  
  861.  
  862.     int i,off;
  863.     Window rotate_window;
  864.     XEvent rotate_event;
  865.     Font rotate_font;
  866.     GC rotate_gc;
  867.     int count;
  868.     char text[10];
  869.     int string[10];
  870.     KeySym key=0;
  871.     float radians;
  872.     double tempcos;
  873.     double tempsin;
  874.     Cursor curs;
  875.  
  876.     /* Flash rotate button on and off */
  877.  
  878.     XClearWindow(display,child);
  879.     XFillRectangle(display,child,parent_gc,0,0,100,25);
  880.     XDrawImageString(display,child,child_gc,
  881.         25,20,rotate_str,strlen(rotate_str));
  882.     XFlush(display);
  883.     for (i=0; i<1000; i++)
  884.         XNoOp(display);
  885.     XClearWindow(display,child);
  886.     XDrawImageString(display,child,parent_gc,
  887.         25,20,rotate_str,strlen(rotate_str));
  888.  
  889.  
  890.     XClearWindow(display,parent);
  891.  
  892.  
  893.     /* create a pop up window */
  894.  
  895.     rotate_window = XCreateSimpleWindow(display,parent,340,200,
  896.         300,100,3,black,white);
  897.  
  898.     rotate_gc = parent_gc;
  899.  
  900.  
  901.     XMapRaised(display,rotate_window);
  902.     XClearWindow(display,rotate_window);
  903.  
  904.     XDrawString(display,rotate_window,parent_gc,
  905.         35,25,"Rotate Figure (in Degrees)",27);
  906.  
  907.     XSelectInput(display,rotate_window,ButtonPressMask
  908.         |KeyPressMask);
  909.  
  910.     /* load up a small font */
  911.  
  912.     font = XLoadFont(display,"7x13");
  913.     XSetFont(display,rotate_gc,font);
  914.  
  915.     XDrawString(display,rotate_window,rotate_gc,
  916.         35,75,"Enter Angle of Rotation: ",
  917.         23);
  918.  
  919.     key = 0;
  920.     text[0] ='\0';
  921.  
  922.     /* input an angle, which is later converted to radians */
  923.  
  924.     i = 200;
  925.  
  926.     do
  927.     {
  928.         i = i + 8;
  929.         XNextEvent(display,&rotate_event);
  930.         count = XLookupString(&rotate_event,text,10,&key,0);
  931.         text[count] = '\0';
  932.         if (key != XK_Return)
  933.             XDrawString(display,rotate_window,rotate_gc,
  934.                 i,75,text,1);
  935.         strcat(string,text);
  936.     }        while (key != XK_Return && rotate_event.type == KeyPress);
  937.  
  938.     rotate_angle = strtol(string,NULL,10);
  939.  
  940.         font = XLoadFont(display,"8x16");
  941.         XSetFont(display,rotate_gc,font);
  942.  
  943.         XDestroyWindow(display,rotate_window);
  944.  
  945.  
  946.     /* draw x and y axis */
  947.  
  948.         XDrawLine(display,parent,parent_gc,XOFF,0,XOFF,YOFF*2);
  949.         XDrawLine(display,parent,parent_gc,0,YOFF,XOFF*2,YOFF);
  950.  
  951.         /* Draw notches in x and y axis */
  952.  
  953.         for (i=25; i<YOFF*2; i=i+25)
  954.                 XDrawLine(display,parent,parent_gc,
  955.                     XOFF-5,i,XOFF+5,i);
  956.  
  957.         for (i=25; i<XOFF*2; i= i+25)
  958.                 XDrawLine(display,parent,parent_gc,
  959.                     i,YOFF-5,i,YOFF+5);
  960.  
  961.         /* change the cursor to a crosss */
  962.  
  963.         curs = XCreateFontCursor(display,XC_diamond_cross);
  964.         XDefineCursor(display,parent,curs);
  965.  
  966.     /* ask user to enter a point to rotate about */
  967.  
  968.         do
  969.         {
  970.                 XNextEvent(display,&rotate_event);
  971.  
  972.                 if (rotate_event.type == ButtonPress &&
  973.                                 rotate_event.xbutton.button == LEFT)
  974.  
  975.                 {
  976.                         rotate_x = rotate_event.xbutton.x;
  977.                         rotate_y = rotate_event.xbutton.y;
  978.  
  979.                 }
  980.  
  981.  
  982.         } while (rotate_event.type != ButtonPress);
  983.  
  984.                 if ( rotate_x > XOFF)
  985.                         rotate_x = rotate_x - XOFF;
  986.                 else
  987.                         rotate_x = -1 * abs (rotate_x - XOFF);
  988.  
  989.  
  990.                 if ( rotate_y > YOFF)
  991.                         rotate_y = YOFF - rotate_y;
  992.                 else
  993.                         rotate_y = abs (YOFF - rotate_y);
  994.  
  995.  
  996.  
  997.  
  998.     XUndefineCursor(display,parent);
  999.     /* set up the identity */
  1000.  
  1001.     make_identity(display);
  1002.  
  1003.     /* assign values */
  1004.  
  1005.     radians = rotate_angle * (PI/180);
  1006.     tempcos = cos(radians);
  1007.     tempsin = sin(radians);
  1008.     matrix[0][0] = tempcos;
  1009.     matrix[0][1] = tempsin;
  1010.  
  1011.     radians = -1.0 * radians;
  1012.  
  1013.     matrix[1][0] = sin(radians);
  1014.     matrix[1][1] = tempcos;
  1015.  
  1016.     matrix[2][0] = rotate_x;
  1017.     matrix[2][1] = rotate_y;
  1018.  
  1019.     /* multiply matrices */
  1020.  
  1021.     combine_transformations(display);
  1022.  
  1023.  
  1024. }
  1025.  
  1026.  
  1027. /* Draw X and Y axis with notches every 25 pixels and display the
  1028.    original figure in red and the transformed figure in blue */
  1029.  
  1030.  
  1031.  
  1032. process_view(display,parent,child,parent_gc,child_gc)
  1033.  
  1034.  
  1035. Display *display;
  1036. Window parent,child;
  1037. GC parent_gc,child_gc;
  1038. {
  1039.  
  1040.         int i;
  1041.         int xoff;
  1042.         int yoff;
  1043.         XPoint temp_points[9];
  1044.  
  1045.         XClearWindow(display,child);
  1046.         XFillRectangle(display,child,parent_gc,0,0,100,25);
  1047.         XDrawImageString(display,child,child_gc,
  1048.             25,20,view_str,strlen(view_str));
  1049.         XFlush(display);
  1050.         for (i=0; i<1000; i++)
  1051.                 XNoOp(display);
  1052.         XClearWindow(display,child);
  1053.         XDrawImageString(display,child,parent_gc,
  1054.             25,20,view_str,strlen(view_str));
  1055.  
  1056.     /* Draw x and y axis */
  1057.  
  1058.         XDrawLine(display,parent,parent_gc,XOFF,0,XOFF,YOFF*2);
  1059.         XDrawLine(display,parent,parent_gc,0,YOFF,XOFF*2,YOFF);
  1060.  
  1061.         /* Draw notches in x and y axis */
  1062.  
  1063.         for (i=25; i<YOFF*2; i=i+25)
  1064.                 XDrawLine(display,parent,parent_gc,
  1065.                     XOFF-5,i,XOFF+5,i);
  1066.  
  1067.         for (i=25; i<XOFF*2; i= i+25)
  1068.                 XDrawLine(display,parent,parent_gc,
  1069.                     i,YOFF-5,i,YOFF+5);
  1070.  
  1071.  
  1072.  
  1073.  
  1074.         for (i=0; i<sides+1; i++)
  1075.                 {
  1076.                 temp_points[i].x = points[i].x + XOFF;
  1077.                 temp_points[i].y = YOFF - points[i].y;
  1078.                 }
  1079.     /* set foreground to blue */
  1080.  
  1081.         XSetForeground(display,parent_gc,colors[2].pixel);
  1082.  
  1083.         /* Draw the original figure */
  1084.  
  1085.         XFillPolygon(display,parent,parent_gc,temp_points,sides,Complex,
  1086.             CoordModeOrigin);
  1087.  
  1088.         /* Modify the original figure to a transformed one */
  1089.  
  1090.         transform_points(display);
  1091.  
  1092.         /* change foreground color to blue */
  1093.  
  1094.         XSetForeground(display,parent_gc,colors[1].pixel);
  1095.  
  1096.         XFillPolygon(display,parent,parent_gc,newpoints,sides,Complex,
  1097.             CoordModeOrigin);
  1098.  
  1099.         /* reset the color back to black */
  1100.  
  1101.         XSetForeground(display,parent_gc,black);
  1102.  
  1103.  
  1104.         for (xoff=0; xoff<sides+1; xoff++);  
  1105.                 printf("(x,y) = %d,%d\n",
  1106.             newpoints[xoff].x,newpoints[xoff].y);
  1107.  
  1108.  
  1109.  
  1110.  
  1111.  
  1112.  
  1113. }
  1114.  
  1115.  
  1116.  
  1117.  
  1118. /* clear the screen of the old figures and reset everything */
  1119.  
  1120.  
  1121. process_reset(display,parent,child,parent_gc,child_gc)
  1122.  
  1123.  
  1124. Display *display;
  1125. Window parent,child;
  1126. GC parent_gc,child_gc;
  1127. {
  1128.  
  1129.     int i;
  1130.  
  1131.     /* flash the reset button */
  1132.  
  1133.     XClearWindow(display,child);
  1134.     XFillRectangle(display,child,parent_gc,0,0,100,25);
  1135.     XDrawImageString(display,child,child_gc,
  1136.         25,20,reset_str,strlen(reset_str));
  1137.     XFlush(display);
  1138.     for (i=0; i<1000; i++)
  1139.         XNoOp(display);
  1140.     XClearWindow(display,child);
  1141.     XDrawImageString(display,child,parent_gc,
  1142.         25,20,reset_str,strlen(reset_str));
  1143.  
  1144.     XFlush(display);
  1145.  
  1146.     /* reset everything */
  1147.  
  1148.     for (i=0; i<sides+1; i++)
  1149.     {
  1150.         points[i].x = 0;
  1151.         points[i].y = 0;
  1152.         newpoints[i].x = 0;
  1153.         newpoints[i].y = 0;
  1154.  
  1155.     }
  1156.     sides = 0;
  1157.  
  1158.     translate.x = 0;
  1159.     translate.y = 0;
  1160.  
  1161.     rotate_angle = 0;
  1162.     rotate_x = 0;
  1163.     rotate_y = 0;
  1164.  
  1165.     scalef_x = 0;
  1166.     scalef_y = 0;
  1167.  
  1168.     scale_x = 0;
  1169.     scale_y = 0;
  1170.  
  1171.  
  1172.     XClearWindow(display,parent);
  1173.  
  1174.  
  1175.  
  1176. }
  1177.  
  1178.  
  1179.  
  1180. combine_transformations(display)
  1181. Display *display;
  1182.  
  1183. {
  1184.  
  1185.  
  1186.         int row,col;
  1187.         float temp[3][3];
  1188.  
  1189.  
  1190.         XFlush(display);
  1191.         for (row = 0; row<3; row++)
  1192.                 {
  1193.                 for (col=0; col<3; col++)
  1194.                 {
  1195.  
  1196.  
  1197.  
  1198.                         temp[row][col] = tmatrix[row][0]*matrix[0][col] +
  1199.                                 tmatrix[row][1] * matrix[1][col]
  1200.                                 + tmatrix[row][2]* matrix[2][col];
  1201.                 }
  1202.  
  1203.                 }
  1204.  
  1205.         for (row = 0; row<3; row++)
  1206.                 {
  1207.                 for (col = 0; col<3; col++)
  1208.                         {
  1209.                      
  1210.  
  1211.                tmatrix[row][col] = temp[row][col];
  1212.  
  1213.                         }
  1214.                 }
  1215. }
  1216. make_identity(display)
  1217. Display *display;
  1218.  
  1219. {
  1220.  
  1221.  
  1222.         int row,col;
  1223.  
  1224.         XFlush(display);
  1225.  
  1226.  
  1227.         for (row=0; row<3; row++)
  1228.                 for (col=0; col<3; col++)
  1229.                         if (row == col)
  1230.                                 matrix[row][col] = 1;
  1231.                         else
  1232.                                 matrix[row][col] = 0;
  1233.  
  1234.  
  1235.  
  1236. }
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242. make_identity2(display)
  1243. Display *display;
  1244.  
  1245. {
  1246.  
  1247.  
  1248.         int row,col;
  1249.  
  1250.         XFlush(display);
  1251.  
  1252.         for (row=0; row<3; row++)
  1253.                 for (col=0; col<3; col++)
  1254.                         if (row == col)
  1255.                                 tmatrix[row][col] = 1;
  1256.                         else
  1257.                                 tmatrix[row][col] = 0;
  1258.  
  1259.  
  1260.  
  1261. }
  1262.  
  1263.  
  1264. transform_points( display )
  1265. Display *display;
  1266. {
  1267.  
  1268.         int i;
  1269.         XFlush(display);
  1270.         for (i=0; i<sides+1; i++)
  1271.                 {
  1272.  
  1273.  
  1274.                 newpoints[i].x =  points[i].x * tmatrix[0][0] +
  1275.                         points[i].y * tmatrix[1][0] + tmatrix[2][0] + XOFF;
  1276.  
  1277.                 newpoints[i].y = YOFF - ( points[i].x * tmatrix[0][1] +
  1278.                         points[i].y * tmatrix[1][1] + tmatrix[2][1]);
  1279.  
  1280.  
  1281.  
  1282.  
  1283.                 }
  1284.  
  1285. }
  1286.  
  1287.  
  1288.  
  1289. /* Create a set of colors from named colors */
  1290.  
  1291. color_set_up(the_display)
  1292.  
  1293. Display *the_display;
  1294.  
  1295. {
  1296.  
  1297.     int i;
  1298.  
  1299.     color_map = DefaultColormap(the_display,0);
  1300.  
  1301.     /* get the colors from the color map for the colors named */
  1302.  
  1303.     for (i=1; i<5; i++)
  1304.     {
  1305.  
  1306.         XAllocNamedColor(the_display,color_map,ncolors[i],
  1307.             &exact_colors[i],&colors[i]);
  1308.  
  1309.     }
  1310.  
  1311.  
  1312. }
  1313.