home *** CD-ROM | disk | FTP | other *** search
- /*
- Routines for handling \special commands. Currently only supports
- inserting impress data from external files. Bitmap stuff is not
- complete.
-
- Allan Weber (Weber%Brand@USC-ECL.ARPA) - 9/12/86
- */
-
- /* #define DEBUG */
-
- #include <stdio.h>
- #include <ctype.h>
-
- extern char *malloc();
- extern int errno;
- extern int ImHH, ImVV, hh, vv;
-
- int S_bitmap();
- int S_impress();
- char *nb();
-
- struct spec {
- char *name;
- int (*func)();
- } spectbl[] = {
- "bitmap", S_bitmap,
- "impress", S_impress,
- "", NULL
- };
-
- /* Perform a \special */
- DoSpecial (len)
- int len; /* length of the \special string */
- {
- struct spec *s;
- char *p;
- register char ch, *p1, *p2;
- if (ImHH != hh || ImVV != vv) /* flush out any pending moves */
- ImSetPosition (hh, vv);
- p1 = p = malloc(len + 1);
- while (len--) /* read the special string */
- *p1++ = getc(stdin);
- *p1 = '\0';
- #ifdef DEBUG
- fprintf(stderr,"special: '%s'\n",p);
- #endif
- p1 = nb(p); /* skip leading blanks */
- if (*p1 == '\0') /* if nothing left, return */
- return;
- p2 = p1;
- while ((ch = *p2) != '\0' && !isspace(ch)) /* find end of 1st word */
- p2++;
- if (ch != '\0') { /* more than one word? */
- *p2++ = '\0'; /* mark end of first word */
- p2 = nb(p2); /* point to start of rest of string */
- }
- s = spectbl;
- while (s->func != NULL) {
- if (strcmp(p1,s->name) == 0) {
- (s->func)(p1,p2);
- return;
- }
- else
- s++;
- }
- free(p);
- }
-
- /*
- split - separate the words in string s, placing a '\0' after each one
- and setting the elements of tok to point to the beginning of each word.
- Only do this for up to max words. Return the number of words found.
- */
- static split(s,tok,max)
- register char *s;
- char *tok[];
- {
- int i, n;
- register char ch;
- n = 0;
- for (i = 0; i < max; i++) {
- s = nb(s); /* find word start */
- if ((ch = *s) != '\0') { /* did we find one? */
- tok[i] = s;
- n++;
- while ((ch = *s) != '\0' && !isspace(ch))
- s++; /* find end of word */
- if (ch != '\0') /* mark end of word */
- *s++ = '\0';
- }
- else
- tok[i] = NULL;
- }
- return(n);
- }
-
- char *nb(s)
- char *s;
- {
- register char ch;
- while ((ch = *s) != '\0' && isspace(ch))
- s++;
- return(s);
- }
-
- /* --------------------------------------------------------------------- */
-
- static S_bitmap(s1, s2)
- char *s1, *s2;
- {
- int i, n, fd;
- int rows, cols, wrows, wcols, wroff, wcoff;
- char *p, *word[7];
- #ifdef DEBUG
- fprintf(stderr,"in bitmap: s1='%s', s2='%s'\n",s1,s2);
- #endif
- p = malloc(strlen(s2) + 1);
- strcpy(p,s2);
- n = split(p,word,7);
- #ifdef DEBUG
- fprintf(stderr, "split into %d words\n",n);
- for (i = 0; i < n; i++)
- fprintf(stderr,"%d: '%s'\n",i,word[i]);
- #endif
- #ifndef DEBUG
- if ((fd = open(word[0], 0)) == -1) {
- error (1, errno, "can't open %s", s2);
-
- }
- if (n < 7) /* no window offset */
- word[6] = word[5] = "0";
- if (n < 5) { /* full window */
- word[3] = word[1];
- word[4] = word[2];
- }
- if (n < 3) { /* need at least the dimensions */
- error(1, 0, "\"\\special bitmap\" not enough arguments");
- free(p);
- return;
- }
- rows = atoi(word[1]); cols = atoi(word[2]);
- wrows = atoi(word[3]); wcols = atoi(word[4]);
- wroff = atoi(word[5]); wcoff = atoi(word[6]);
- close(fd);
- #endif
- free(p);
- }
-
- static S_impress(s1, s2)
- char *s1, *s2;
- {
- FILE *fp;
- int n, h, v, ch;
- char *p, *word[3];
- #ifdef DEBUG
- fprintf(stderr,"in impress: s1='%s', s2='%s'\n",s1,s2);
- #endif
- #ifndef DEBUG
- p = malloc(strlen(s2) + 1);
- strcpy(p,s2);
- n = split(p,word,3);
- if ((fp = fopen(word[0], "r")) == NULL) {
- error (1, errno, "can't open %s", word[0]);
- }
- putchar(211); /* push */
- if (n == 3) { /* absolute move specified */
- if (sscanf(word[1],"%d", &h) == 1) {
- putchar(135);
- putchar((h >> 8) & 255);
- putchar(h & 255);
- }
- if (sscanf(word[2],"%d", &v) == 1) {
- putchar(137);
- putchar((v >> 8) & 255);
- putchar(v & 255);
- }
- }
- while ((ch = getc(fp)) != EOF || !feof(fp))
- putchar(ch);
- putchar(212); /* pop */
- fclose(fp);
- #endif
- }
-
-