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