home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * grsh.c:
- * Implement a "gr" shell that interprets Tcl/Tk with a few added
- * commands adequate to implement assignment 1. See the assignment
- * spec for more information.
- *
- * Note: students shouldn't have to touch this file. Just implement
- * the functions specified in gr.h, then write a Tcl/Tk program with
- * the required interface and use grsh to interpret it.
- ***************************************************************************/
- #include <stdlib.h>
- #include <string.h>
-
- /* gr includes togl.h which then includes tcl.h, tk.h, X11/Xlib.h, GL/gl.h */
- #include "gr.h"
-
- /***************************************************************************
- * Here is the Tcl glue for all of the gr_* commands. This "glue" converts
- * from arguments of the form argc/argv and checks for the right number of
- * arguments, and if the first argument starts with "?" or the form is
- * incorrect, returns a usage summary.
- ***************************************************************************/
- static void
- Gr_modeCMD_Usage(
- Tcl_Interp *ip,
- int argc,
- char* argv[]
- ) {
- Tcl_AppendResult(ip,
- "\nUsage: ",
- argv[0],
- " <mode>",
- (char *)0
- );
- }
-
- static int
- Gr_modeCMD (
- ClientData cd,
- Tcl_Interp *ip,
- int argc,
- char *argv[]
- ) {
- char mode;
- char *errmsg;
-
- if (2 == argc && '?' == argv[1][0]) {
- Gr_modeCMD_Usage(ip,argc,argv);
- return TCL_OK;
- }
-
- if (2 != argc) {
- Gr_modeCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- /* obtain the mode identifier */
- mode = argv[1][0];
-
- /* execute gr function */
- errmsg = gr_mode(mode);
-
- /* report error, if any */
- if (errmsg) {
- Tcl_AppendResult(ip,
- argv[0],
- " ",
- errmsg,
- (char *)0
- );
- Gr_modeCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- return TCL_OK;
- }
-
- static void
- Gr_bufferCMD_Usage(
- Tcl_Interp *ip,
- int argc,
- char* argv[]
- ) {
- Tcl_AppendResult(ip,
- "\nUsage: ",
- argv[0],
- " <buffer>",
- (char *)0
- );
- }
-
- static int
- Gr_bufferCMD (
- ClientData cd,
- Tcl_Interp *ip,
- int argc,
- char *argv[]
- ) {
- char btype;
- char *errmsg;
-
- if (2 == argc && '?' == argv[1][0]) {
- Gr_bufferCMD_Usage(ip,argc,argv);
- return TCL_OK;
- }
-
- if (2 != argc) {
- Gr_bufferCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- /* get the buffer type */
- btype = argv[1][0];
-
- /* execute gr function */
- errmsg = gr_buffer(btype);
-
- if (errmsg) {
- Tcl_AppendResult(ip,
- argv[0],
- " error: ",
- errmsg,
- (char *)0
- );
- Gr_bufferCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- return TCL_OK;
- }
-
- static void
- Gr_lightingCMD_Usage(
- Tcl_Interp *ip,
- int argc,
- char* argv[]
- ) {
- Tcl_AppendResult(ip,
- "\nUsage: ",
- argv[0],
- " <on/off>",
- (char *)0
- );
- }
-
- static int
- Gr_lightingCMD (
- ClientData cd,
- Tcl_Interp *ip,
- int argc,
- char *argv[]
- ) {
- char* lighting;
- char* errmsg;
-
- if (2 == argc && '?' == argv[1][0]) {
- Gr_lightingCMD_Usage(ip,argc,argv);
- return TCL_OK;
- }
-
- if (2 != argc) {
- Gr_lightingCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- /* get the lighting mode */
- lighting = argv[1];
-
- /* execute gr function */
- errmsg = gr_lighting(lighting);
-
- if (errmsg) {
- Tcl_AppendResult(ip,
- argv[0],
- " error: ",
- errmsg,
- (char *)0
- );
- Gr_lightingCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- return TCL_OK;
- }
-
- static void
- Gr_saveCMD_Usage(
- Tcl_Interp *ip,
- int argc,
- char* argv[]
- ) {
- Tcl_AppendResult(ip,
- "\nUsage: ",
- argv[0],
- " <filename>",
- (char *)0
- );
- }
-
- static int
- Gr_saveCMD (
- ClientData cd,
- Tcl_Interp *ip,
- int argc,
- char *argv[]
- ) {
- char* filename;
- char* errmsg;
-
- if (2 == argc && '?' == argv[1][0]) {
- Gr_saveCMD_Usage(ip,argc,argv);
- return TCL_OK;
- }
-
- if (2 != argc) {
- Gr_saveCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- /* get the filename to save */
- filename = argv[1];
-
- /* execute gr function */
- errmsg = gr_save(filename);
-
- if (errmsg) {
- Tcl_AppendResult(ip,
- argv[0],
- " error: ",
- errmsg,
- (char *)0
- );
- Gr_saveCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- return TCL_OK;
- }
-
- static void
- Gr_rotateCMD_Usage(
- Tcl_Interp *ip,
- int argc,
- char* argv[]
- ) {
- Tcl_AppendResult(ip,
- "\nUsage: ",
- argv[0],
- " <axis (x|y|z)> <angle (degrees)>",
- (char *)0
- );
- }
-
- static int
- Gr_rotateCMD (
- ClientData cd,
- Tcl_Interp *ip,
- int argc,
- char *argv[]
- ) {
- char *path;
- char axis;
- GLdouble angle;
- char* errmsg;
-
- if (2 == argc && '?' == argv[1][0]) {
- Gr_rotateCMD_Usage(ip,argc,argv);
- return TCL_OK;
- }
-
- if (3 != argc) {
- Gr_rotateCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- /* get the axis */
- axis = argv[1][0];
-
- /* get the angle */
- if (TCL_OK != Tcl_GetDouble(ip, argv[2], &angle)) return TCL_ERROR;
-
- /* execute the gr function */
- errmsg = gr_rotate(axis,angle);
-
- if (errmsg) {
- Tcl_AppendResult(ip,
- argv[0],
- " error: ",
- errmsg,
- (char *)0
- );
- Gr_rotateCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- return TCL_OK;
- }
-
- static void
- Gr_scaleCMD_Usage(
- Tcl_Interp *ip,
- int argc,
- char* argv[]
- ) {
- Tcl_AppendResult(ip,
- "\nUsage: ",
- argv[0],
- " <factor>",
- (char *)0
- );
- }
-
- static int
- Gr_scaleCMD (
- ClientData cd,
- Tcl_Interp *ip,
- int argc,
- char *argv[]
- ) {
- double factor;
- char* errmsg;
-
- if (2 == argc && '?' == argv[1][0]) {
- Gr_scaleCMD_Usage(ip,argc,argv);
- return TCL_OK;
- }
-
- if (2 != argc) {
- Gr_scaleCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- /* get scale factor */
- if (TCL_OK != Tcl_GetDouble(ip, argv[1], &factor)) return TCL_ERROR;
-
- /* execute gr function */
- errmsg = gr_scale(factor);
-
- if (errmsg) {
- Tcl_AppendResult(ip,
- argv[0],
- " error: ",
- errmsg,
- (char *)0
- );
- Gr_scaleCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- return TCL_OK;
- }
-
- static void
- Gr_resetCMD_Usage(
- Tcl_Interp *ip,
- int argc,
- char* argv[]
- ) {
- Tcl_AppendResult(ip,
- "\nUsage: ",
- argv[0],
- (char *)0
- );
- }
-
- static int
- Gr_resetCMD (
- ClientData cd,
- Tcl_Interp *ip,
- int argc,
- char *argv[]
- ) {
- char *errmsg;
-
- if (2 == argc && '?' == argv[1][0]) {
- Gr_resetCMD_Usage(ip,argc,argv);
- return TCL_OK;
- }
-
- if (1 != argc) {
- Gr_resetCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- /* execute gr function */
- errmsg = gr_reset();
-
- if (errmsg) {
- Tcl_AppendResult(ip,
- argv[0],
- " error: ",
- errmsg,
- (char *)0
- );
- Gr_resetCMD_Usage(ip,argc,argv);
- return TCL_ERROR;
- }
-
- return TCL_OK;
- }
-
- /*************************************************************************
- * Associate all the Tcl commands with the functions above...
- *************************************************************************/
- static int
- Gr_Init(Tcl_Interp *ip)
- {
- /* Register Gr commands with Tcl
- */
- Tcl_CreateCommand (ip, "gr_mode", Gr_modeCMD, 0, 0);
- Tcl_CreateCommand (ip, "gr_buffer", Gr_bufferCMD, 0, 0);
- Tcl_CreateCommand (ip, "gr_lighting", Gr_lightingCMD, 0, 0);
- Tcl_CreateCommand (ip, "gr_save", Gr_saveCMD, 0, 0);
- Tcl_CreateCommand (ip, "gr_rotate", Gr_rotateCMD, 0, 0);
- Tcl_CreateCommand (ip, "gr_scale", Gr_scaleCMD, 0, 0);
- Tcl_CreateCommand (ip, "gr_reset", Gr_resetCMD, 0, 0);
-
- /* Register Gr Togl callbacks with Togl
- */
- Togl_CreateFunc(gr_initialize);
- Togl_DisplayFunc(gr_render);
- Togl_ReshapeFunc(gr_reshape);
-
- return TCL_OK;
- }
-
- /*************************************************************************
- * Tcl expects this function to be here. The real main() is in the
- * tcl library. Note that we also initialize Tk, the Togl widget, and Gr.
- *************************************************************************/
- int
- Tcl_AppInit (
- Tcl_Interp *ip
- ) {
- /* Initialize various packages */
- if (Tcl_Init(ip) == TCL_ERROR) return TCL_ERROR;
- if (Tk_Init(ip) == TCL_ERROR) return TCL_ERROR;
- if (Togl_Init(ip) == TCL_ERROR) return TCL_ERROR;
- if (Gr_Init(ip) == TCL_ERROR) return TCL_ERROR;
-
- /* Set up to read from a1 script file by default */
- Tcl_SetVar(ip, "tcl_rcFileName", "./a1.gr", TCL_GLOBAL_ONLY);
-
- return TCL_OK;
- }
-
- /*************************************************************************
- * The main function just calls Tk_Main to initialize the system
- *************************************************************************/
- int
- main (
- int argc,
- char **argv
- ) {
- Tk_Main(argc, argv, Tcl_AppInit);
- return 0; /* Needed only to prevent compiler warning. */
- }
-