home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / openglso.zip / grsh.c < prev    next >
C/C++ Source or Header  |  2000-02-16  |  9KB  |  458 lines

  1. /***************************************************************************
  2.  * grsh.c:
  3.  *    Implement a "gr" shell that interprets Tcl/Tk with a few added
  4.  *    commands adequate to implement assignment 1.  See the assignment
  5.  *    spec for more information.
  6.  *
  7.  *    Note: students shouldn't have to touch this file.  Just implement
  8.  *    the functions specified in gr.h, then write a Tcl/Tk program with
  9.  *    the required interface and use grsh to interpret it. 
  10.  ***************************************************************************/
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. /* gr includes togl.h which then includes tcl.h, tk.h, X11/Xlib.h, GL/gl.h */
  15. #include "gr.h"
  16.  
  17. /***************************************************************************
  18.  * Here is the Tcl glue for all of the gr_* commands.  This "glue" converts
  19.  * from arguments of the form argc/argv and checks for the right number of 
  20.  * arguments, and if the first argument starts with "?" or the form is
  21.  * incorrect, returns a usage summary.
  22.  ***************************************************************************/
  23. static void
  24. Gr_modeCMD_Usage(
  25.     Tcl_Interp *ip, 
  26.     int argc,
  27.     char* argv[]
  28. ) {
  29.     Tcl_AppendResult(ip, 
  30.         "\nUsage: ",
  31.         argv[0], 
  32.         " <mode>",
  33.         (char *)0 
  34.     );
  35. }
  36.  
  37. static int
  38. Gr_modeCMD (
  39.     ClientData cd, 
  40.     Tcl_Interp *ip, 
  41.     int argc, 
  42.     char *argv[]
  43. ) {
  44.     char mode;
  45.     char *errmsg;
  46.  
  47.     if (2 == argc && '?' == argv[1][0]) {
  48.         Gr_modeCMD_Usage(ip,argc,argv);
  49.         return TCL_OK;
  50.     }
  51.  
  52.     if (2 != argc) {
  53.         Gr_modeCMD_Usage(ip,argc,argv);
  54.         return TCL_ERROR;
  55.     }
  56.  
  57.     /* obtain the mode identifier */
  58.     mode = argv[1][0];
  59.     
  60.     /* execute gr function */
  61.     errmsg = gr_mode(mode);
  62.  
  63.     /* report error, if any */
  64.     if (errmsg) {
  65.           Tcl_AppendResult(ip, 
  66.               argv[0], 
  67.                " ",  
  68.             errmsg,
  69.                (char *)0 
  70.           );
  71.         Gr_modeCMD_Usage(ip,argc,argv);
  72.           return TCL_ERROR;
  73.     }
  74.   
  75.     return TCL_OK;
  76. }
  77.  
  78. static void
  79. Gr_bufferCMD_Usage(
  80.     Tcl_Interp *ip, 
  81.     int argc,
  82.     char* argv[]
  83. ) {
  84.     Tcl_AppendResult(ip, 
  85.         "\nUsage: ",
  86.         argv[0], 
  87.         " <buffer>",
  88.         (char *)0 
  89.     );
  90. }
  91.  
  92. static int
  93. Gr_bufferCMD (
  94.     ClientData cd, 
  95.     Tcl_Interp *ip, 
  96.     int argc, 
  97.     char *argv[]
  98. ) {
  99.     char btype;
  100.     char *errmsg;
  101.  
  102.     if (2 == argc && '?' == argv[1][0]) {
  103.         Gr_bufferCMD_Usage(ip,argc,argv);
  104.           return TCL_OK;
  105.     }
  106.  
  107.     if (2 != argc) {
  108.         Gr_bufferCMD_Usage(ip,argc,argv);
  109.           return TCL_ERROR;
  110.     }
  111.  
  112.     /* get the buffer type */
  113.     btype = argv[1][0];
  114.  
  115.     /* execute gr function */
  116.     errmsg = gr_buffer(btype);
  117.     
  118.     if (errmsg) {
  119.         Tcl_AppendResult(ip, 
  120.             argv[0], 
  121.             " error: ",  
  122.             errmsg,
  123.             (char *)0 
  124.         );
  125.         Gr_bufferCMD_Usage(ip,argc,argv);
  126.         return TCL_ERROR;
  127.     }
  128.   
  129.     return TCL_OK;
  130. }
  131.  
  132. static void
  133. Gr_lightingCMD_Usage(
  134.     Tcl_Interp *ip, 
  135.     int argc,
  136.     char* argv[]
  137. ) {
  138.     Tcl_AppendResult(ip, 
  139.         "\nUsage: ",
  140.         argv[0], 
  141.         " <on/off>",
  142.         (char *)0 
  143.     );
  144. }
  145.  
  146. static int
  147. Gr_lightingCMD (
  148.     ClientData cd, 
  149.     Tcl_Interp *ip, 
  150.     int argc, 
  151.     char *argv[]
  152. ) {
  153.     char* lighting;
  154.     char* errmsg;
  155.  
  156.     if (2 == argc && '?' == argv[1][0]) {
  157.         Gr_lightingCMD_Usage(ip,argc,argv);
  158.           return TCL_OK;
  159.     }
  160.  
  161.     if (2 != argc) {
  162.         Gr_lightingCMD_Usage(ip,argc,argv);
  163.         return TCL_ERROR;
  164.     }
  165.  
  166.     /* get the lighting mode */
  167.     lighting = argv[1];
  168.  
  169.     /* execute gr function */
  170.     errmsg = gr_lighting(lighting);
  171.     
  172.     if (errmsg) {
  173.         Tcl_AppendResult(ip, 
  174.             argv[0], 
  175.             " error: ",  
  176.             errmsg,
  177.             (char *)0 
  178.         );
  179.         Gr_lightingCMD_Usage(ip,argc,argv);
  180.         return TCL_ERROR;
  181.     }
  182.   
  183.     return TCL_OK;
  184. }
  185.  
  186. static void
  187. Gr_saveCMD_Usage(
  188.     Tcl_Interp *ip, 
  189.     int argc,
  190.     char* argv[]
  191. ) {
  192.     Tcl_AppendResult(ip, 
  193.         "\nUsage: ",
  194.         argv[0], 
  195.         " <filename>",
  196.         (char *)0 
  197.     );
  198. }
  199.  
  200. static int
  201. Gr_saveCMD (
  202.     ClientData cd, 
  203.     Tcl_Interp *ip, 
  204.     int argc, 
  205.     char *argv[]
  206. ) {
  207.     char* filename;
  208.     char* errmsg;
  209.  
  210.     if (2 == argc && '?' == argv[1][0]) {
  211.         Gr_saveCMD_Usage(ip,argc,argv);
  212.         return TCL_OK;
  213.     }
  214.  
  215.     if (2 != argc) {
  216.         Gr_saveCMD_Usage(ip,argc,argv);
  217.         return TCL_ERROR;
  218.     }
  219.  
  220.     /* get the filename to save */
  221.     filename = argv[1];
  222.  
  223.     /* execute gr function */
  224.     errmsg = gr_save(filename);
  225.  
  226.     if (errmsg) {
  227.         Tcl_AppendResult(ip, 
  228.             argv[0], 
  229.             " error: ",  
  230.             errmsg,
  231.             (char *)0 
  232.         );
  233.         Gr_saveCMD_Usage(ip,argc,argv);
  234.         return TCL_ERROR;
  235.     }
  236.   
  237.     return TCL_OK;
  238. }
  239.  
  240. static void
  241. Gr_rotateCMD_Usage(
  242.     Tcl_Interp *ip, 
  243.     int argc,
  244.     char* argv[]
  245. ) {
  246.     Tcl_AppendResult(ip, 
  247.         "\nUsage: ",
  248.         argv[0], 
  249.         " <axis (x|y|z)> <angle (degrees)>",
  250.         (char *)0 
  251.     );
  252. }
  253.  
  254. static int 
  255. Gr_rotateCMD (
  256.     ClientData cd, 
  257.     Tcl_Interp *ip, 
  258.     int argc, 
  259.     char *argv[]
  260. ) {
  261.     char *path;
  262.     char axis;
  263.     GLdouble angle;
  264.     char* errmsg;
  265.  
  266.     if (2 == argc && '?' == argv[1][0]) {
  267.         Gr_rotateCMD_Usage(ip,argc,argv);
  268.         return TCL_OK;
  269.     }
  270.  
  271.     if (3 != argc) {
  272.         Gr_rotateCMD_Usage(ip,argc,argv);
  273.         return TCL_ERROR;
  274.     }
  275.  
  276.     /* get the axis */
  277.     axis = argv[1][0];
  278.     
  279.     /* get the angle */
  280.     if (TCL_OK != Tcl_GetDouble(ip, argv[2], &angle)) return TCL_ERROR;
  281.  
  282.     /* execute the gr function */
  283.     errmsg = gr_rotate(axis,angle);
  284.     
  285.     if (errmsg) {
  286.         Tcl_AppendResult(ip, 
  287.             argv[0], 
  288.             " error: ",  
  289.             errmsg,
  290.             (char *)0 
  291.         );
  292.         Gr_rotateCMD_Usage(ip,argc,argv);
  293.         return TCL_ERROR;
  294.     }
  295.   
  296.     return TCL_OK;
  297. }
  298.  
  299. static void
  300. Gr_scaleCMD_Usage(
  301.     Tcl_Interp *ip, 
  302.     int argc,
  303.     char* argv[]
  304. ) {
  305.     Tcl_AppendResult(ip, 
  306.         "\nUsage: ",
  307.         argv[0], 
  308.         " <factor>",
  309.         (char *)0 
  310.     );
  311. }
  312.  
  313. static int 
  314. Gr_scaleCMD (
  315.     ClientData cd, 
  316.     Tcl_Interp *ip, 
  317.     int argc, 
  318.     char *argv[]
  319. ) {
  320.     double factor;
  321.     char* errmsg;
  322.  
  323.     if (2 == argc && '?' == argv[1][0]) {
  324.         Gr_scaleCMD_Usage(ip,argc,argv);
  325.         return TCL_OK;
  326.     }
  327.  
  328.     if (2 != argc) {
  329.         Gr_scaleCMD_Usage(ip,argc,argv);
  330.         return TCL_ERROR;
  331.     }
  332.  
  333.     /* get scale factor */
  334.     if (TCL_OK != Tcl_GetDouble(ip, argv[1], &factor)) return TCL_ERROR;
  335.  
  336.     /* execute gr function */
  337.     errmsg = gr_scale(factor);
  338.     
  339.     if (errmsg) {
  340.         Tcl_AppendResult(ip, 
  341.             argv[0], 
  342.             " error: ",  
  343.             errmsg,
  344.             (char *)0 
  345.         );
  346.         Gr_scaleCMD_Usage(ip,argc,argv);
  347.         return TCL_ERROR;
  348.     }
  349.   
  350.     return TCL_OK;
  351. }
  352.  
  353. static void
  354. Gr_resetCMD_Usage(
  355.     Tcl_Interp *ip, 
  356.     int argc,
  357.     char* argv[]
  358. ) {
  359.     Tcl_AppendResult(ip, 
  360.         "\nUsage: ",
  361.         argv[0], 
  362.         (char *)0 
  363.     );
  364. }
  365.     
  366. static int 
  367. Gr_resetCMD (
  368.     ClientData cd, 
  369.     Tcl_Interp *ip, 
  370.     int argc, 
  371.     char *argv[]
  372. ) {
  373.     char *errmsg;
  374.  
  375.     if (2 == argc && '?' == argv[1][0]) {
  376.         Gr_resetCMD_Usage(ip,argc,argv);
  377.         return TCL_OK;
  378.     }
  379.  
  380.     if (1 != argc) {
  381.         Gr_resetCMD_Usage(ip,argc,argv);
  382.         return TCL_ERROR;
  383.     }
  384.  
  385.     /* execute gr function */
  386.     errmsg = gr_reset();
  387.  
  388.     if (errmsg) {
  389.         Tcl_AppendResult(ip, 
  390.             argv[0], 
  391.             " error: ",  
  392.             errmsg,
  393.             (char *)0 
  394.         );
  395.         Gr_resetCMD_Usage(ip,argc,argv);
  396.         return TCL_ERROR;
  397.     }
  398.   
  399.     return TCL_OK;
  400. }
  401.  
  402. /*************************************************************************
  403.  * Associate all the Tcl commands with the functions above...
  404.  *************************************************************************/
  405. static int 
  406. Gr_Init(Tcl_Interp *ip) 
  407. {
  408.     /* Register Gr commands with Tcl
  409.      */
  410.     Tcl_CreateCommand (ip, "gr_mode",        Gr_modeCMD,        0, 0);
  411.     Tcl_CreateCommand (ip, "gr_buffer",      Gr_bufferCMD,      0, 0);
  412.     Tcl_CreateCommand (ip, "gr_lighting",    Gr_lightingCMD,    0, 0);
  413.     Tcl_CreateCommand (ip, "gr_save",        Gr_saveCMD,        0, 0);
  414.     Tcl_CreateCommand (ip, "gr_rotate",      Gr_rotateCMD,      0, 0);
  415.     Tcl_CreateCommand (ip, "gr_scale",       Gr_scaleCMD,       0, 0);
  416.     Tcl_CreateCommand (ip, "gr_reset",       Gr_resetCMD,       0, 0);
  417.  
  418.     /* Register Gr Togl callbacks with Togl
  419.      */
  420.     Togl_CreateFunc(gr_initialize);
  421.     Togl_DisplayFunc(gr_render);
  422.     Togl_ReshapeFunc(gr_reshape);
  423.  
  424.     return TCL_OK;
  425. }
  426.  
  427. /*************************************************************************
  428.  * Tcl expects this function to be here.  The real main() is in the
  429.  * tcl library.  Note that we also initialize Tk, the Togl widget, and Gr.
  430.  *************************************************************************/
  431. int 
  432. Tcl_AppInit (
  433.     Tcl_Interp *ip
  434. ) {
  435.     /* Initialize various packages */
  436.     if (Tcl_Init(ip)  == TCL_ERROR) return TCL_ERROR;
  437.     if (Tk_Init(ip)   == TCL_ERROR) return TCL_ERROR;
  438.     if (Togl_Init(ip) == TCL_ERROR) return TCL_ERROR;
  439.     if (Gr_Init(ip)   == TCL_ERROR) return TCL_ERROR;
  440.  
  441.     /* Set up to read from a1 script file by default */
  442.     Tcl_SetVar(ip, "tcl_rcFileName", "./a1.gr", TCL_GLOBAL_ONLY);
  443.  
  444.     return TCL_OK;
  445. }
  446.  
  447. /*************************************************************************
  448.  * The main function just calls Tk_Main to initialize the system
  449.  *************************************************************************/
  450. int
  451. main (
  452.     int argc, 
  453.     char **argv
  454. ) {
  455.   Tk_Main(argc, argv, Tcl_AppInit);
  456.   return 0;           /* Needed only to prevent compiler warning. */
  457. }
  458.