home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume4 / xhpgl / part01 / xhpgl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-07-16  |  18.6 KB  |  520 lines

  1. /******************************************************************\
  2.  *                                                                *
  3.  *  File Name:  xhpgl.c    part of hpgl to Xwindows program       *
  4.  *                                                                *
  5.  *                                                                *
  6.  *  Author:  Randy L. Yach                                        *
  7.  *                                                                *
  8.  *  Functional description:                                       *
  9.  *                                                                *
  10.  *     This program will read a 7470a syntax HPGL file and        *
  11.  *     display it on an Xwindow display.                          *
  12.  *                                                                *
  13. \******************************************************************/
  14.  
  15.  
  16. #include <X/Xlib.h>
  17. #include <stdio.h>
  18. #include "black.bitmap"
  19.  
  20. #define DISCARD 1
  21. #define MAXX 1000
  22. #define MAXY 773
  23.  
  24. double xMin,xMax,yMin,yMax; /* user min/max coordinate boundaries */
  25. int last_x, last_y; /* last x and y coordinates for line drawing */
  26. int x,y;           /* current x and y coordinates for line drawing */
  27. int cur_pen,no_pen,line; /* current pen color */
  28. int pen_down;            /* pen status */
  29. int absolute;            /* ploter status */
  30. Font text_font;          /* LB font selection */
  31. short font_offset;       /* distance from lower left to upper left of font */
  32. Window main_window;      /* main window for plotting */
  33. Color pen[10];            /* all pen colors for plotting */
  34. int minWidth,minHeight;  /* size of X window for plotting */
  35. Pattern line_type;       /* line dash pattern */
  36. char font_name[32]; /* font name of user supplied font */
  37.  
  38. /* */
  39. /******************************************************************\
  40.  * prodedure select_font(x,y)                                     *
  41.  ******************************************************************
  42.  *    will pick a font based on the window size                   *
  43. \******************************************************************/
  44.  
  45. void get_text_font(user_font)
  46. int user_font;
  47. {
  48.      if (!user_font)
  49.      {
  50.          if ((minWidth < 350) || (minHeight < 350)) 
  51.          strcpy(font_name,"nil2");
  52.          else if ((minWidth < 700) || (minHeight < 700)) 
  53.          strcpy(font_name,"6x10");
  54.          else if ((minWidth < 800) || (minHeight < 800)) 
  55.          strcpy(font_name,"8x13");
  56.          else 
  57.          strcpy(font_name,"9x15");
  58.      }
  59.  
  60.     /* get the font and check if it is valid */
  61.     text_font = XGetFont(font_name);
  62.  
  63. }
  64.  
  65. /* */
  66. /******************************************************************\
  67.  * procedure reverse                                              *
  68.  ******************************************************************
  69.  *    used to revers a string s                                   *
  70. \******************************************************************/
  71. void reverse(s)
  72. /* reverse string s in place */
  73. char s[];
  74. { /* begin reverse */
  75. int c,i,j;
  76.  
  77.    for (i = 0, j = strlen(s)-1; i < j; i++, j--) 
  78.        { /* begin for string */
  79.        c = s[i];
  80.        s[i] = s[j];
  81.        s[j] = c;
  82.        } /* end for string */
  83.     } /* end reverse */
  84.  
  85. /* */
  86. /******************************************************************\
  87.  * procedure itoa                                                 *
  88.  ******************************************************************
  89.  *    converts an integer to a string.                            *
  90. \******************************************************************/
  91. void itoa(s,n) 
  92. /* convert n to characters in s */
  93. int n;
  94. char s[];
  95. { /* begin itoa */
  96. int i, sign;
  97.  
  98.    if ((sign = n) < 0)  /* record sign */
  99.       n = -n;
  100.    i = 0;
  101.    do {  /* generate digits in reverse order */
  102.       s[i++] = n % 10 + '0';  /* get next digit */
  103.    } while ((n /= 10) > 0);  /* delete it */
  104.    if (sign < 0)
  105.       s[i++] = '-';
  106.    s[i] = '\0';
  107.    reverse(s);
  108. } /* end itoa */
  109.  
  110. /* */
  111. /******************************************************************\
  112.  * procedure initialize_plotter                                   *
  113.  ******************************************************************
  114.  *    used to set up the default plotter conditions.              *
  115. \******************************************************************/
  116. void initialize_plotter()
  117. { /* begin initialize_plotter */
  118.     x=0;                  /* set current x plotter coordinate */
  119.     y=0;                  /* set current y plotter coordinate */
  120.     last_x=0;             /* set last x plotter coordinate */
  121.     last_y=0;             /* set last y plotter coordinate */
  122.     
  123.     xMin = 0;             /* set default x and y plotter scale */
  124.     yMin = 0;             /* user coordinates.  This assumes */
  125.     xMax = 10300;         /* that the 7470a is in US mode */
  126.     yMax = 7650;
  127.     
  128.     pen_down=0;           /* pot the pen in up position */
  129.     
  130.     cur_pen=pen[0].pixel; /* select no pen or no color */
  131.     no_pen=pen[0].pixel;  /* need a reference background color for text */
  132.     
  133.     line_type = XMakePattern(0xff,8,1); /* set up solid line pattern */
  134.     } /* end initialize_plotter */
  135. /* */
  136. /******************************************************************\
  137.  * procedure assign_color                                         *
  138.  ******************************************************************
  139.  *    used to assign a color to each plotter pen.                 *
  140. \******************************************************************/
  141. void assign_color(pen_num,color)
  142. int pen_num;
  143. char color[];
  144. { /* begin assign_color */
  145.     if ((pen_num <=0) || (pen_num >= 9))
  146.         { /* begin invalid pen */
  147.         fprintf(stderr,"pen numbers must be 1 to 8.\n");
  148.     exit(-1);
  149.     } /* end invalid pen */
  150.     else
  151.     { /* begin valid pen */
  152.         if (strcmp(color,"black")==0) 
  153.             { /* begin black */
  154.             pen[pen_num].red=0; 
  155.         pen[pen_num].green=0; pen[pen_num].blue=0;
  156.             } /* end black */
  157.         else if (strcmp(color,"red")==0) 
  158.             { /* begin red */
  159.             pen[pen_num].red=65535; 
  160.         pen[pen_num].green=0; pen[pen_num].blue=0;
  161.             } /* end red */
  162.         else if (strcmp(color,"gold")==0) 
  163.             { /* begin gold */
  164.             pen[pen_num].red=61500;pen[pen_num].green=36750; 
  165.         pen[pen_num].blue=25000;
  166.             } /* end gold */
  167.         else if (strcmp(color,"firebrick")==0) 
  168.             { /* begin firebrick */
  169.             pen[pen_num].red=42600;pen[pen_num].green=10500; 
  170.         pen[pen_num].blue=10500;
  171.             } /* end firebrick */
  172.         else if (strcmp(color,"maroon")==0) 
  173.             { /* begin maroon */
  174.             pen[pen_num].red=42600; pen[pen_num].green=10500; 
  175.         pen[pen_num].blue=32100;
  176.             } /* end maroon */
  177.         else if (strcmp(color,"orange")==0) 
  178.             { /* begin orange */
  179.             pen[pen_num].red=61200; pen[pen_num].green=15000; 
  180.         pen[pen_num].blue=15000;
  181.             } /* end orange */
  182.         else if (strcmp(color,"pink")==0) 
  183.             { /* begin pink */
  184.             pen[pen_num].red=56400; pen[pen_num].green=42900; 
  185.         pen[pen_num].blue=42900;
  186.             } /* end pink */
  187.         else if (strcmp(color,"turquoise")==0) 
  188.             { /* begin turquoise */
  189.             pen[pen_num].red=51900; pen[pen_num].green=65535; 
  190.         pen[pen_num].blue=65535;
  191.             } /* end turquoise */
  192.         else if (strcmp(color,"violet")==0) 
  193.             { /* begin violet */
  194.             pen[pen_num].red=23700; pen[pen_num].green=14100; 
  195.         pen[pen_num].blue=23700;
  196.             } /* end violet */
  197.         else if (strcmp(color,"green")==0) 
  198.             { /* begin green */
  199.             pen[pen_num].red=0; 
  200.         pen[pen_num].green=65535; pen[pen_num].blue=0;
  201.             } /* end green */
  202.         else if (strcmp(color,"blue")==0) 
  203.             { /* begin blue */
  204.             pen[pen_num].red=0; 
  205.         pen[pen_num].green=0; pen[pen_num].blue=65535;
  206.             } /* end blue */
  207.         else if (strcmp(color,"yellow")==0) 
  208.             { /* begin yellow */
  209.             pen[pen_num].red=65535; 
  210.         pen[pen_num].green=65535; pen[pen_num].blue=0;
  211.             } /* end yellow */
  212.         else if (strcmp(color,"cyan")==0) 
  213.             { /* begin cyan */
  214.             pen[pen_num].red=0; 
  215.         pen[pen_num].green=65535; pen[pen_num].blue=65535;
  216.             } /* end cyan */
  217.         else if (strcmp(color,"magenta")==0) 
  218.             { /* begin magenta */
  219.             pen[pen_num].red=65535; 
  220.         pen[pen_num].green=0; pen[pen_num].blue=65535;
  221.             } /* end magenta */
  222.         else if (strcmp(color,"white")==0) 
  223.             { /* begin white */
  224.             pen[pen_num].red=65535; 
  225.         pen[pen_num].green=65535; pen[pen_num].blue=65535;
  226.             } /* end white */
  227.         else 
  228.             { /* begin default white */
  229.         fprintf(stderr,"Color %s not supported, using white.\n",color);
  230.             pen[pen_num].red=65535; 
  231.         pen[pen_num].green=65535; pen[pen_num].blue=65535;
  232.         } /* begin default white */
  233.         } /* end valid pen */
  234.     } /* end assign_color */
  235.  
  236. /* */
  237. main (argc, argv)
  238. int argc;
  239. char *argv[];
  240. { /* begin main */
  241.  
  242.     /* variable declerations */
  243.     Pixmap pixmap,bpix; /* Used for frame and background of main window */
  244.     Bitmap blackB;      /* All 1's located in a 16 x 16 area for tiles */
  245.     OpaqueFrame frame;  /* Used for creating the frame for the window */
  246.     XEvent event;       /* used for watching for keys in main window */
  247.     WindowInfo window_info[1]; /* window information from XQueryWindow */
  248.     FontInfo text_font_info[1]; /* font information structure */
  249.     
  250.     char file_name[32]; /* file name of hpgl input file */
  251.     extern FILE *yyin;  /* File pointer for hpgl input file */
  252.     
  253.     char size_def[22];  /* is the default size used for creating the window */
  254.     char temp[22];      /* temporary string holder */
  255.     int user_font = 0;  /* need to know if the user entered a font */
  256.     
  257.     int i; /* general puropse counter */
  258.     char user_color[10]; /* string for user color name */
  259.     char *color_file_path; /* path to user color file */
  260.     char color_file[65]; /* color file name */
  261.     FILE *color_file_pointer; /* color file pointer */
  262.     
  263.     
  264.     /* set up default font_name and file_name */
  265.     *font_name='\0';
  266.     *file_name='\0';
  267.     
  268.     /* set up the default color file path and name */
  269.     color_file_path = (char *) getenv("HOME");
  270.     if (color_file_path == NULL)
  271.     *color_file_path = '\0';
  272.     strcpy(color_file,color_file_path);
  273.     strcat(color_file,"/.hpcolors");
  274.     
  275.     /* set up the default pixel size of the display window.  all plot
  276.        coordinates will be scaled to these coordinates */
  277.     minWidth=MAXX;
  278.     minHeight=MAXY;
  279.     strcpy(size_def,"=");
  280.     itoa(temp,MAXX);
  281.     strcat(size_def,temp);
  282.     strcat(size_def,"x");
  283.     itoa(temp,MAXY);
  284.     strcat(size_def,temp);
  285.     strcat(size_def,"+0+0");
  286.     
  287.     /* initialize all the pen colors to default value */
  288.     pen[1].red=65535; pen[1].green=0; pen[1].blue=0;
  289.     pen[2].red=0; pen[2].green=65535; pen[2].blue=0;
  290.     pen[3].red=0; pen[3].green=0; pen[3].blue=65535;
  291.     pen[4].red=0; pen[4].green=65535; pen[4].blue=65535;
  292.     pen[5].red=65535; pen[5].green=0; pen[5].blue=65535;
  293.     pen[6].red=65535; pen[6].green=65535; pen[6].blue=0;
  294.     pen[7].red=65535; pen[7].green=65535; pen[7].blue=65535;
  295.     pen[8].red=65535; pen[8].green=65535; pen[8].blue=65535;
  296.  
  297.     /* define the window black and white colors.  let the user
  298.        defint all the rest.  pen 0 is background black and pen 9
  299.        is frame white.  pens 1-8 are user definable */
  300.     pen[0].red=0; pen[0].green=0; pen[0].blue=0; /* background black */
  301.     pen[9].red=65535; pen[9].green=65535; pen[9].blue=65535; /* white */
  302.     
  303.     /* check to see if the user did not enter a file name and print
  304.        and error message */
  305.     if(argc == 1)
  306.         { /* begin error print */
  307.         fprintf(stderr,"\nusage: xhpgl -fn [font] file\n\n");
  308.         exit(-1);
  309.         } /* end error print */
  310.     
  311.     /* parse the input arguments and get the file name and font name.
  312.        all arguments passed that are not -fn font or -cf color_file
  313.        are assumed to be files.
  314.        This program will use the last arg sent as the file to plot. */
  315.     for(argc--,argv++;argc;argc--,argv++)
  316.         { /* begin input arg parseing */
  317.         if (!strcmp(*argv,"-fn"))
  318.             { /* begin arg fn */
  319.             argc--;
  320.             argv++;
  321.             strcpy(font_name,*argv);
  322.         user_font = 1;
  323.             } /* end arg fn */
  324.     if (!strcmp(*argv,"-cf"))
  325.             { /* begin color file */
  326.         argc--;
  327.         argv++;
  328.         strcpy(color_file,*argv);
  329.         } /* end color file */
  330.         else
  331.             strcpy(file_name,*argv);
  332.         } /* end input arg parseing */
  333.     
  334.     /* open the hpgl file and print error if not able to */
  335.     if((yyin=fopen(file_name,"r"))==NULL)
  336.         { /* begin open file error */
  337.         fprintf(stderr,"Could not open hpgl file -%s- for read.\n",
  338.                 file_name);
  339.         exit(-1);
  340.         } /* end open file error */
  341.     
  342.  
  343.     /* open the color definition file and print message of not found */
  344.     /* assign colors if file is found */
  345.     if((color_file_pointer=fopen(color_file,"r"))==NULL)
  346.     { /* begin no color file */
  347.     fprintf(stderr,"Could not open color file -%s- for read.\n",
  348.         color_file);
  349.     fprintf(stderr,"Using default internal values...\n");
  350.     } /* end no color file */
  351.     else
  352.         { /* begin assign colors */
  353.         while(fscanf(color_file_pointer,"%d %s",&i,user_color) != EOF)
  354.         assign_color(i,user_color);
  355.         fclose(color_file_pointer);
  356.         } /* begin assign colors */
  357.     
  358.     
  359.     /* connect to the Display as a client */
  360.     if (XOpenDisplay(NULL)==NULL)
  361.     {
  362.         fprintf(stderr,"Could not open Display\n");
  363.     exit(-1);
  364.     }
  365.     
  366.     /* allocate and create a hardware color for each of the pens */
  367.     for (i=0;i<10;i++)
  368.         if (!(XGetHardwareColor(&pen[i])))
  369.         {
  370.             fprintf(stderr,"Could not obtain color for pen %d\n",i);
  371.         exit(-1);
  372.         }
  373.     
  374.     
  375.     /* set up the pixmap and bitmaps for the background of the main
  376.        window and its frame. */
  377.     blackB = XStoreBitmap (black_width,black_height,black_bits);
  378.     pixmap = XMakePixmap (blackB,pen[0].pixel,pen[9].pixel);
  379.     bpix = XMakePixmap (blackB,pen[9].pixel,pen[0].pixel);
  380.     
  381.     /* set up the frame info for the default window */
  382.     frame.self=main_window;
  383.     frame.x=0;
  384.     frame.y=0;
  385.     frame.bdrwidth=3;
  386.     frame.border=bpix;
  387.     frame.background=pixmap;
  388.     frame.width=minWidth;
  389.     frame.height=minHeight;
  390.     
  391.     /* create the main window */
  392.     main_window = XCreate ("xhpgl",
  393.                            "xhpgl window",
  394.                            size_def,
  395.                            size_def,
  396.                            &frame,
  397.                            minWidth/10,minHeight/10);
  398.    
  399.     /* query window for size to see how big the actual window was
  400.        that was created. */
  401.     XQueryWindow (main_window,window_info);
  402.  
  403.     /* set the the window coordinate size to the actual window size */
  404.     minWidth = window_info[0].width;
  405.     minHeight = window_info[0].height;
  406.  
  407.     /* select the proper font for the window size.  minWidth and minHeight
  408.        must be assigned to the current window size before this call is made,
  409.        or the font will be the wrong size */
  410.     get_text_font(user_font);
  411.  
  412.     /* check to make sure that the font selected exists on the 
  413.        hardware */
  414.     if (text_font == 0)
  415.         {/* begin get font error */
  416.         fprintf(stderr,"Could not read font %s\n",font_name);
  417.         exit(-1);
  418.         }/* end get font error */
  419.  
  420.     /* get size of the font */
  421.     XQueryFont(text_font,text_font_info);
  422.     font_offset = text_font_info[0].height;
  423.  
  424.     /* map the window and flush all events */
  425.     XMapWindow(main_window);
  426.     XFlush();
  427.     
  428.     /* initialize the plotter and set it up to default conditions */
  429.     initialize_plotter();
  430.     
  431.     /* call the yacc parser to parse the hpgl file.  All plotting and line
  432.        drawing are done in the yacc file */
  433.     yyparse();
  434.     
  435.     /* close the hpgl file */
  436.     fclose(yyin);
  437.     
  438.     /* set up the window to watch key events */
  439.     XSelectInput(main_window,KeyPressed);
  440.     
  441.     while(1) 
  442.         { /* begin event handeling */
  443.     /* get the next pending event in the queue */
  444.         XNextEvent(&event);
  445.     
  446.     /* switch on the event type */
  447.         switch (event.type)
  448.             { /* begin event switch */
  449.             case KeyPressed:
  450.                 { /* begin key pressed */
  451.                 char *key_char;
  452.                 XKeyEvent *key_event = (XKeyEvent *) &event;
  453.  
  454.                 key_char = XLookupMapping(key_event,&i);
  455.  
  456.                 for (;i>0;i--) 
  457.                 switch(*key_char++)
  458.                     { /* begin key matching */
  459.                     case 'Q':
  460.                     case 'q': 
  461.                         { /* begin keys q and Q */
  462.                         exit(0);
  463.                         break;
  464.                         }/* end keys q and Q */
  465.                     case 'r':
  466.                     case 'R':
  467.                         { /* begin keys r and R */
  468.             /* if a redraw occures, open the file again
  469.                            and call the yacc parser.  then flush and
  470.                discard all other events.  this keeps multiple
  471.                events from clogging the queue while a long
  472.                plot is painting. */
  473.                         if((yyin=fopen(file_name,"r"))==NULL)
  474.                 { /* beign file error */
  475.                             fprintf(stderr,
  476.                                 "Could not open file %s for read access.\n"
  477.                                 ,file_name);
  478.                 exit(-1);
  479.                 } /* end file error */
  480.  
  481.             /* clear the display to get rid of any opbjects
  482.                that are not drawn to proper scale if the window
  483.                was resized */
  484.                         XClear(main_window);
  485.  
  486.             /* get window size information */
  487.                 XQueryWindow(main_window,window_info);
  488.                 minWidth = window_info[0].width;
  489.                 minHeight = window_info[0].height;
  490.  
  491.             /* select an appropriate font */
  492.             get_text_font(user_font);
  493.  
  494.                         if (text_font == 0)
  495.                             {/* begin get font error */
  496.                             fprintf(stderr,"Could not read font %s\n",
  497.                     font_name);
  498.                             exit(-1);
  499.                             }/* end get font error */
  500.  
  501.                         /* get size of the font */
  502.                         XQueryFont(text_font,text_font_info);
  503.                         font_offset = text_font_info[0].height;
  504.  
  505.             initialize_plotter();
  506.                         yyparse();
  507.                         fclose(yyin);
  508.                         XFlush();
  509.                         XSync(DISCARD);
  510.                         break;
  511.                         } /* end keys r and R */
  512.                     default: break;
  513.                     } /* end key matching */
  514.                 } /* end key pressed */
  515.             default:
  516.                 break;
  517.             } /* end event switch */
  518.         } /* end event handeling */
  519.     } /* end main */
  520.