/* * print-out DVI * * Copyright (c) 1993, 1994, 1995 * MATSUURA Syun syun@fuka.info.waseda.ac.jp * HIRAHARA Atsushi hirahara@fuka.info.waseda.ac.jp * ONO Kouichi onono@fuka.info.waseda.ac.jp * All rights reserved. */ #ifdef DVISEL /* * select DVI * * Copyright (c) 1999 * WATANABE Takeshi watanabe@komadori.planet.sci.kobe-u.ac.jp */ #endif /* DVISEL */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* #include "xdvi.h" */ #include "xdvi-config.h" /* added by Masahito Yamaga */ #ifdef PRINTDVI /* added by Masahito Yamaga */ #include "print.h" #ifdef MARKPAGE #include "markpage.h" #endif /* MARKPAGE */ #ifdef DVISEL #include "dvi.h" #endif /* DVISEL */ #include "paper.h" static String print_style[] = #ifdef MARKPAGE {LBLPRINTALL, LBLPRINTCUR, LBLPRINTMRK, LBLPRINTRGN, LBLPRINTAMK}; #else {LBLPRINTALL, LBLPRINTCUR}; #endif /* MARKPAGE */ static char printer_name[PRINTERNAMELEN]; static Boolean PrintMenuEnd = False; static Widget popup, dialog, print_button, print_menu; #ifndef DVISEL static void GetBaseName(pathname, basename) char pathname[STRLENGTH], basename[STRLENGTH]; { int len = 0; int i = 0; int found = -1; if(basename==NULL) return; if(pathname==NULL) { *basename = CHAR_NULL; return; } len = strlen(pathname); for(i = len-1; i>found; i--) { if(pathname[i]==PATH_DELIMITER) /* found it */ found = i; } if(found<=-1) /* not found */ found = -1; strcpy(basename, pathname+found+1); } static void GetDirName(pathname, dirname) char pathname[STRLENGTH], dirname[STRLENGTH]; { int len = 0; int i = 0; int found = -1; char copypathname[STRLENGTH]; if(dirname==NULL) return; if(pathname==NULL) { *dirname = CHAR_NULL; return; } strcpy(copypathname, pathname); len = strlen(copypathname); for(i = len-1; i>found; i--) { if(copypathname[i]==PATH_DELIMITER) /* found it */ found = i; } if(found==0) { /* found, and directory is "/" */ copypathname[0] = PATH_DELIMITER; copypathname[1] = CHAR_NULL; } else if(found>0) { /* found, and directory is "/xxx/yyy/zz..." */ copypathname[found] = CHAR_NULL; } else { /* not found, pathname may be plain filename */ /* copy current directory */ copypathname[0] = CHAR_PERIOD; copypathname[1] = CHAR_NULL; } strcpy(dirname, copypathname); } static char *MatchOption(line, paper) char* line; char* paper; { register char* c = line; register char* p = paper; static char option[STRLENGTH]; if(line==NULL || *line==CHAR_NULL || paper==NULL || *paper==CHAR_NULL) /* error */ return NULL; /* skip white spaces */ while(ISWHITESPACE(*c)) c++; while(ISWHITESPACE(*p)) p++; /* if the paper type is started by '=', the following string is returned */ if(*c==CHAR_EQUAL) { c++; while(ISWHITESPACE(*c)) c++; /* use the following option in the line */ p = option; while(!ISENDOFLINE(*c) && !ISCOMMENT(*c)) /* copy the option */ *p++ = *c++; /* temporal terminate symbol */ *p = CHAR_NULL; /* truncate whitespaces at the tail of option */ --p; while(p>=option && ISWHITESPACE(*p)) *p-- = CHAR_NULL; return option; } /* get paper size */ while(!ISWHITESPACE(*c) && !ISENDOFLINE(*c) && !ISCOMMENT(*c)) { if(ISENDOFLINE(*p)) /* not matched */ return NULL; if(*c++!=*p++) /* not matched */ return NULL; } if(!ISENDOFLINE(*p)) /* not matched */ return NULL; /*** paper size matched ***/ /* skip white spaces */ while(ISWHITESPACE(*c)) c++; if(ISENDOFLINE(*c) || ISCOMMENT(*c)) /* use the original paper size */ return paper; /* use the following option in the line */ p = option; while(!ISENDOFLINE(*c) && !ISCOMMENT(*c)) /* copy the option */ *p++ = *c++; /* temporal terminate symbol */ *p = CHAR_NULL; /* truncate whitespaces at the tail of option */ --p; while(p>=option && ISWHITESPACE(*p)) *p-- = CHAR_NULL; return option; } static char *FilterPaperOption(paper) char* paper; { FILE* fd = NULL; char* FilterOptionFile = NULL; char buff[STRLENGTH]; char* opt = NULL; /* open the filter option file */ if((FilterOptionFile = getenv(FILTOPTTBLFILEENVVARNAME))==NULL) /* use default value */ FilterOptionFile = FILTOPTTBLFILE; if((fd = fopen(FilterOptionFile, "r"))==NULL) /* file not found --> use the original paper size */ return paper; /* search the file */ while(fgets(buff, sizeof(buff), fd)!=NULL) if((opt = MatchOption(buff, paper))!=NULL) return opt; Fclose(fd); /* not found --> use the original paper size */ return paper; } static char *GetTranslatedPaperSize() { return FilterPaperOption(GetPaperSize()); } static void SubstitutePrintVar(ResultStr, SourceStr) char ResultStr[STRLENGTH], SourceStr[STRLENGTH]; { char SourceChar[STRLENGTH]; char DestStr[STRLENGTH]; char StrBuff[STRLENGTH]; char* envvar = NULL; char* pSource = SourceChar; PAGE PageList[LISTSIZE]; LIST_LOCATION LocList, EndLocList; strcpy(SourceChar, SourceStr); DestStr[0] = CHAR_NULL; #ifdef HTEX #define dvi_name urlocalize(dvi_name) #endif /* HTEX */ while(*pSource!=CHAR_NULL) { if(*pSource==VARMARK) { /* Is it a variable ? */ /* Probably it is a variable */ pSource++; if(*pSource!=CHAR_NULL) { /* Is the source string end ? */ /* No, the source string has more characters */ switch(*pSource) { case VARMARK: StrBuff[0] = VARMARK; StrBuff[1] = CHAR_NULL; strcat(DestStr, StrBuff); break; case VARDVIFILEFULLPATH: /* filename of DVI file (full pathname) */ strcat(DestStr, dvi_name); break; case VARDVIFILEBASENAME: /* filename of DVI file (basename of pathname) */ GetBaseName(dvi_name, StrBuff); strcat(DestStr, StrBuff); break; case VARDVIFILEDIRNAME: /* directory where DVI file is placed (directory of pathname) */ GetDirName(dvi_name, StrBuff); strcat(DestStr, StrBuff); break; case VARTEMPDIRECTORY: /* temp directory */ /* (if the environment variable TMPDIR is defined, use it) */ if((envvar = getenv(TEMPDIRENVVARNAME)) != NULL) { strcat(DestStr, envvar); } else { strcat(DestStr, TEMPDIR); } break; case VARPRINTERNAME: /* printer name */ /* (if the environment variable PRINTER is defined, use it) */ strcat(DestStr, printer_name); break; case VARPRINTCOMMAND: /* print command string */ /* (if the environment variable PRINTCMD is defined, use it) */ strcpy(StrBuff, pSource+1); if((envvar = getenv(PRINTCMDENVVARNAME))!=NULL) { strcpy(pSource+1, envvar); } else { strcpy(pSource+1, PRINTCMD); } strcat(SourceChar, StrBuff); break; case VARPAPERSIZE: /* paper size specified with -paper option (lower case) */ strcat(DestStr, GetPaperSize()); break; case VARPAPERSIZEFORFILTER: /* paper size translated from -paper option */ strcat(DestStr, GetTranslatedPaperSize()); break; case VARPROCESSID: /* proces id */ sprintf(StrBuff, "%d", getpid()); strcat(DestStr, StrBuff); break; case VARDVIFILTERCOMMAND: /* DVI filter command string */ /* (if the environment variable DVIFILTER is defined, use it) */ strcpy(StrBuff, pSource+1); if((envvar = getenv(DVIFILTERCMDENVVARNAME))!=NULL) { strcpy(pSource+1, envvar); } else { strcpy(pSource+1, DVIFILTERCMD); } strcat(SourceChar, StrBuff); break; case VARCURRENTPAGENUMBER: /* current page number */ sprintf(StrBuff, "%d", current_page+1); strcat(DestStr, StrBuff); break; #ifdef MARKPAGE case VARLASTMARKEDPAGENUMBER: /* last marked page number */ sprintf(StrBuff, "%d", LastMarkPage()+1); strcat(DestStr, StrBuff); break; case VARSTARTPAGENUMBEROFREGION: /* start page number of region; minimum of %c and %m */ sprintf(StrBuff, "%d", MIN(current_page+1, LastMarkPage()+1)); strcat(DestStr, StrBuff); break; case VARENDPAGENUMBEROFREGION: /* end page number of region; maximum of %c and %m */ sprintf(StrBuff, "%d", MAX(current_page+1, LastMarkPage()+1)); strcat(DestStr, StrBuff); break; case VARMARKEDPAGELISTMARKEDORDERBYCOMMA: /* marked page list; marked order; separated by "," */ GetMarkedPageListAsString(StrBuff, NULL, NULL, CHAR_COMMA); strcat(DestStr, StrBuff); break; case VARMARKEDPAGELISTMARKEDORDERBYSPACE: /* marked page list; marked order; separated by " " */ GetMarkedPageListAsString(StrBuff, NULL, NULL, CHAR_SPACE); strcat(DestStr, StrBuff); break; case VARMARKEDPAGELISTSORTEDBYCOMMA: /* marked page list; sorted; separated by "," */ GetSortedMarkedPageListAsString(StrBuff, NULL, NULL, CHAR_COMMA); strcat(DestStr, StrBuff); break; case VARMARKEDPAGELISTSORTEDBYSPACE: /* marked page list; sorted; separated by " " */ GetSortedMarkedPageListAsString(StrBuff, NULL, NULL, CHAR_SPACE); strcat(DestStr, StrBuff); break; case VARMARKEDPAGETOPAGELISTSORTEDBYCOMMA: /* marked page list; sorted; page-to-page form (p1-p2) */ /* separated by "," */ GetSortedMarkedPPListAsString(StrBuff, NULL, NULL, CHAR_HYPHEN, CHAR_COMMA); strcat(DestStr, StrBuff); break; case VARMARKEDPAGETOPAGELISTSORTEDBYSPACE: /* marked page list; sorted; page-to-page form (p1-p2) */ /* separated by " " */ GetSortedMarkedPPListAsString(StrBuff, NULL, NULL, CHAR_HYPHEN, CHAR_SPACE); strcat(DestStr, StrBuff); break; case VARMARKEDABSOLUTEPAGELISTMARKEDORDERBYCOMMA: /* like %l; "=" is put on each page number (assumed dviselect) */ GetMarkedPageListAsString(StrBuff, CHAR_EQUAL, NULL, CHAR_COMMA); strcat(DestStr, StrBuff); break; case VARMARKEDABSOLUTEPAGELISTMARKEDORDERBYSPACE: /* like %L; "=" is put on each page number (assumed dviselect) */ GetMarkedPageListAsString(StrBuff, CHAR_EQUAL, NULL, CHAR_SPACE); strcat(DestStr, StrBuff); break; case VARMARKEDABSOLUTEPAGELISTSORTEDBYCOMMA: /* like %t; "=" is put on each page number (assumed dviselect) */ GetSortedMarkedPageListAsString(StrBuff, CHAR_EQUAL, NULL, CHAR_COMMA); strcat(DestStr, StrBuff); break; case VARMARKEDABSOLUTEPAGELISTSORTEDBYSPACE: /* like %T; "=" is put on each page number (assumed dviselect) */ GetSortedMarkedPageListAsString(StrBuff, CHAR_EQUAL, NULL, CHAR_SPACE); strcat(DestStr, StrBuff); break; case VARMARKEDABSOLUTEPAGETOPAGELISTSORTEDBYCOMMA: /* like %o; page-to-page form (=p1:p2) (assumed dviselect) */ GetSortedMarkedPPListAsString(StrBuff, CHAR_EQUAL, NULL, CHAR_COLON, CHAR_COMMA); strcat(DestStr, StrBuff); break; case VARMARKEDABSOLUTEPAGETOPAGELISTSORTEDBYSPACE: /* like %O; page-to-page form (=p1:p2) (assumed dviselect) */ GetSortedMarkedPPListAsString(StrBuff, CHAR_EQUAL, NULL, CHAR_COLON, CHAR_SPACE); strcat(DestStr, StrBuff); break; #endif /* MARKPAGE */ default: StrBuff[0] = VARMARK; StrBuff[1] = *pSource; StrBuff[2] = CHAR_NULL; strcat(DestStr, StrBuff); break; } } else { /* The source string is end */ StrBuff[0] = VARMARK; StrBuff[1] = CHAR_NULL; strcat(DestStr, StrBuff); pSource--; } } else { /* It is not a variable */ StrBuff[0] = *pSource; StrBuff[1] = CHAR_NULL; strcat(DestStr, StrBuff); } pSource++; } #ifdef HTEX #undef dvi_name #endif /* HTEX */ strcpy(ResultStr, DestStr); } #endif /* ! DVISEL */ static void close_all_font_file() { struct font* fontp = NULL; for(fontp = font_head; fontp!=NULL; fontp = fontp->next) if(fontp->file!=NULL) { Fclose(fontp->file); } } extern char* resource_print_command(); #ifdef DVISEL static struct fontinfo { long TeXnumber; unsigned char info[14]; char *fontname; struct fontinfo *next; Boolean used; } *fontinfo_head; #define PutFour(num, fp) { \ putc(((num) >> 24) & 0xff, (fp)); putc(((num) >> 16) & 0xff, (fp)); \ putc(((num) >> 8) & 0xff, (fp)); putc((num) & 0xff, (fp)); } #define CopyNum(fin, fout, num) { \ int m = num; while (--m >= 0) putc(getc(fin), fout); } static FILE *fin, *fout; long fout_pos; static void FontWrite(fontp) struct fontinfo *fontp; { if (fontp->TeXnumber > 0xff) { if (fontp->TeXnumber > 0xffff) { if (fontp->TeXnumber > 0xffffff) { putc(FNTDEF4, fout); putc((fontp->TeXnumber >> 24) & 0xff, fout); fout_pos++; } else putc(FNTDEF3, fout); putc((fontp->TeXnumber >> 16) & 0xff, fout); fout_pos++; } else putc(FNTDEF2, fout); putc((fontp->TeXnumber >> 8) & 0xff, fout); fout_pos++; } else putc(FNTDEF1, fout); putc(fontp->TeXnumber & 0xff, fout); fwrite(fontp->info, sizeof(char), 14, fout); fwrite(fontp->fontname, sizeof(char), fontp->info[12] + fontp->info[13], fout); fout_pos += 2 + 14 + fontp->info[12] + fontp->info[13]; } #ifdef COLOR static void adj_color_stack(prev, cur) int prev, cur; { int i, j, stack_lim; if (scanned_page < cur) { int saved_page = current_page; current_page = cur; prescan(); current_page = saved_page; } if (memcmp((char *) &page_color[prev].background, (char *) &page_color[cur].background, sizeof(XColor)) != 0) { fprintf(fout, "%c%cbackground rgb %7.5lf %7.5lf %7.5lf", XXX1, 38, (double) page_color[cur].background.red / ((unsigned short)~0), (double) page_color[cur].background.green / ((unsigned short)~0), (double) page_color[cur].background.blue / ((unsigned short)~0)); fout_pos += 40; } stack_lim = MIN(page_color[prev].stack_top, page_color[cur].stack_top); for (i = 0; i <= stack_lim; i++) if (memcmp((char *) &page_color[prev].color_stack[i], (char *) &page_color[cur].color_stack[i], sizeof(XColor)) != 0) break; if (i == 0) return; for (j = page_color[prev].stack_top; j >= i; j--) { fprintf(fout, "%c%ccolor pop", XXX1, 9); fout_pos += 11; } for (j = i; j <= page_color[cur].stack_top; j++) { fprintf(fout, "%c%ccolor push rgb %7.5lf %7.5lf %7.5lf", XXX1, 38, (double) page_color[cur].color_stack[j].red / ((unsigned short)~0), (double) page_color[cur].color_stack[j].green / ((unsigned short)~0), (double) page_color[cur].color_stack[j].blue / ((unsigned short)~0)); fout_pos += 40; } } #endif /* COLOR */ static void WriteDVI(c) int c; { int i, n; struct fontinfo *fontp; if (c >= FNTNUM0 && c <= FNT4) { if (c >= FNT1) n = num(fin, c - FNT1 + 1); else n = c - FNTNUM0; for (fontp = fontinfo_head; fontp; fontp = fontp->next) if (n == fontp->TeXnumber) break; if (fontp && fontp->used == False) { fontp->used = True; FontWrite(fontp); } putc(c, fout); fout_pos++; switch (c) { case FNT4: putc((n >> 24) & 0xff, fout); fout_pos++; case FNT3: putc((n >> 16) & 0xff, fout); fout_pos++; case FNT2: putc((n >> 8) & 0xff, fout); fout_pos++; case FNT1: putc(n & 0xff, fout); fout_pos++; default: break; } } else if (c >= FNTDEF1 && c <= FNTDEF4) { n = num(fin, c - FNTDEF1 + 1); for (fontp = fontinfo_head; fontp; fontp = fontp->next) if (n == fontp->TeXnumber) break; if (fontp && fontp->used == False) { fontp->used = True; FontWrite(fontp); } (void) num(fin, 12); (void) num(fin, (int)(one(fin) + one(fin))); } else { putc(c, fout); fout_pos++; n = 0; if (c <= XXX4) for (i = 0; i < c - XXX1 + 1; i++) { int x = one(fin); putc(x, fout); fout_pos++; n = (n << 8) | x; } switch (c) { case SETRULE: case PUTRULE: n += 4; case RIGHT4: case W4: case X4: case DOWN4: case Y4: case Z4: n++; case RIGHT3: case W3: case X3: case DOWN3: case Y3: case Z3: n++; #if defined(Omega) || defined(KANJI) case SET2: case PUT2: #endif /* Omega || KANJI */ case RIGHT2: case W2: case X2: case DOWN2: case Y2: case Z2: n++; case SET1: case PUT1: case RIGHT1: case W1: case X1: case DOWN1: case Y1: case Z1: #ifdef PTEX case TDIR: #endif n++; case XXX1: case XXX2: case XXX3: case XXX4: CopyNum(fin, fout, n); fout_pos += n; default: break; } } } static void SelectDVI(fp, PrintStyle) FILE *fp; int PrintStyle; { extern long postamble_offset; int c, n, page, pagecnt; #ifdef COLOR int prev_page = -1; #endif /* COLOR */ long offset = 0xffffffff; struct fontinfo *fontp; #ifdef HTEX { int url_aware_save = URL_aware; URL_aware = True; fin = xfopen(dvi_name, "r"); URL_aware = url_aware_save; } if (fin == NULL) { #else /* HTEX */ if ((fin = xfopen(dvi_name, "r")) == NULL) { #endif /* HTEX */ Puts("Error: Cannot open DVI file."); return; } if (PrintStyle == PRINTALL) { while ((c = getc(fin)) != EOF) putc(c, fp); return; } /* get font list */ Fseek(fin, postamble_offset, 0); (void) num(fin, 1+4*6+2+2); fontinfo_head = NULL; for (;;) { if ((c = one(fin)) < FNTDEF1 || c > FNTDEF4) /* maybe POSTPOST */ break; fontp = (struct fontinfo *) xmalloc(sizeof(struct fontinfo)); fontp->TeXnumber = num(fin, c - FNTDEF1 + 1); fread(fontp->info, sizeof(char), 14, fin); n = fontp->info[12] + fontp->info[13]; fontp->fontname = xmalloc(n); fread(fontp->fontname, sizeof(char), n, fin); fontp->next = fontinfo_head; fontinfo_head = fontp; fontp->used = False; } /* preamble */ Fseek(fin, 0, 0); fout = fp; #ifdef PAGENUM fout_pos = page_index[0].offset; #else fout_pos = page_offset[0]; #endif /* PAGENUM */ CopyNum(fin, fout, fout_pos); /* each page */ pagecnt = 0; for (page = 0; page < total_pages; page++) { if (PrintStyle == PRINTCUR && page != current_page) continue; #ifdef MARKPAGE if (PrintStyle == PRINTMARKED && page != LastMarkPage()) continue; if (PrintStyle == PRINTREGION && ((page < current_page && page < LastMarkPage()) || (page > current_page && page > LastMarkPage()))) continue; if (PrintStyle == PRINTALLMARKED && ! ThisPageIsMarked(page)) continue; #endif /* MARKPAGE */ #ifdef PAGENUM (void) Fseek(fin, page_index[page].offset, 0); #else (void) Fseek(fin, page_offset[page], 0); #endif /* PAGENUM */ CopyNum(fin, fout, 1+4+9*4); /* BOP etc. */ (void) four(fin); PutFour(offset, fout); offset = fout_pos; fout_pos += 1+4+9*4+4; #ifdef COLOR if (use_color && page != ++prev_page) adj_color_stack(prev_page, page); #endif /* COLOR */ while ((c = getc(fin)) != EOF) { if (! (c & 0x80)) { /* nornal charactor */ putc(c, fout); fout_pos++; } else if (c == EOP) { /* End Of Page */ putc(c, fout); fout_pos++; break; } else WriteDVI(c); } pagecnt++; #ifdef COLOR prev_page = page; #endif /* COLOR */ } /* postamble */ Fseek(fin, postamble_offset, 0); putc(one(fin), fout); /* POST */ (void) four(fin); PutFour(offset, fout); offset = fout_pos; CopyNum(fin, fout, 4*5+2); (void) two(fin); putc((pagecnt >> 8) & 0xff, fout); putc(pagecnt & 0xff, fout); fout_pos += 1+4+4*5+2+2; /* put font list */ for (;;) { if ((c = one(fin)) < FNTDEF1 || c > FNTDEF4) /* maybe POSTPOST */ break; n = num(fin, c - FNTDEF1 + 1); for (fontp = fontinfo_head; fontp; fontp = fontp->next) if (n == fontp->TeXnumber) break; if (fontp && fontp->used == True) FontWrite(fontp); (void) num(fin, 12); (void) num(fin, (int)(one(fin) + one(fin))); } /* free list */ for (fontp = fontinfo_head; fontp;) { struct fontinfo *nextp; free(fontp->fontname); nextp = fontp->next; free(fontp); fontp = nextp; } /* POSTPOST */ putc(c, fout); (void) four(fin); PutFour(offset, fout); CopyNum(fin, fout, 1+4); for (fout_pos += 1+4+1+4; fout_pos & 3; fout_pos++) putc(TRAILER, fout); fclose(fin); } #endif /* DVISEL */ static void PrintDVI(widget, client_data, call_data) Widget widget; XtPointer client_data, call_data; { int PrintStyle = (int)client_data; int pid = 0; int status = 0; char* printCommand = NULL; #ifdef DVISEL int pdes[2]; FILE *fp; if (pipe(pdes) < 0) return; #endif /* DVISEL */ strcpy(printer_name, (char *)XawDialogGetValueString(dialog)); if(*printer_name==CHAR_NULL) { /* When the input of dialog widget as printer name is null string, */ /* Let it the default printer name */ strcpy(printer_name, DVIPRINTER); } if((pid = fork())<0) { perror("fork"); #ifdef DVISEL close(pdes[0]); close(pdes[1]); #endif /* DVISEL */ return; } /* Actual print-out work should be done with the child process */ /* Because the work takes long time */ if(pid==0) { /* The following is the work for the child process */ /* It is the actual print-out work */ #ifndef DVISEL char buff[STRLENGTH]; #endif /* DVISEL */ close_all_font_file(); /* Forcedly close all font files */ #ifdef DVISEL if (pdes[0]) { dup2(pdes[0], 0); close(pdes[0]); } close(pdes[1]); if ((printCommand = resource_print_command()) == NULL && (printCommand = getenv(ENVVARXDVIPRINTCMD)) == NULL) printCommand = XDVIPRINTCMD; execlp(printCommand, "xdvi print-out", printer_name, GetPaperSize(), NULL); #else /* DVISEL */ if((printCommand = resource_print_command(PrintStyle))!=NULL) { SubstitutePrintVar(buff, printCommand); execl("/bin/sh", "xdvi print-out", "-c", buff, (char *)0); } #endif /* DVISEL */ exit(0); } #ifdef DVISEL fp = fdopen(pdes[1], "w"); close(pdes[0]); SelectDVI(fp, PrintStyle); fclose(fp); close(pdes[1]); #endif /* DVISEL */ while(wait(&status)!=pid) /* empty */ ; PrintMenuEnd = True; /* Print-out pull down menu should be closed */ } static void DestroyPopupPrompt(widget, client_data, call_data) Widget widget; XtPointer client_data, call_data; { PrintMenuEnd = True; /* Print-out pull down menu should be closed */ } extern char* resource_printer(); static void get_printer_name(name) char* name; { char* p = NULL; if((p = resource_printer())!=NULL || (p = getenv(ENVVARPRINTER))!=NULL) strcpy(name, p); else strcpy(name, DVIPRINTER); } void InitPrintMenu() { get_printer_name(printer_name); } void print_DVI_file(top_level) Widget top_level; { Widget entry; Position x, y; Dimension width, height; int i; XtAppContext PrintApp; XEvent event; XtVaGetValues(top_level, XtNwidth, &width, XtNheight, &height, NULL); XtTranslateCoords(top_level, (Position) (width / 3), (Position) (height / 3), &x, &y); popup = XtVaCreatePopupShell(LBLPRINTSH, transientShellWidgetClass, top_level, XtNx, x, XtNy, y, XtNdepth, our_depth, XtNvisual, our_visual, #ifdef GREY XtNcolormap, our_colormap, #endif NULL); /* * The popup will contain a dialog box, prompting the user for input. */ dialog = XtVaCreateManagedWidget(LBLPRINTER, dialogWidgetClass, popup, XtNlabel, (String)LBLPRINTER, XtNvalue, (String)printer_name, NULL); /* * The prompting message's size is dynamic; allow it to request resize. */ print_button = XtVaCreateManagedWidget(LBLPRINTOUT, menuButtonWidgetClass, dialog, NULL); XtVaSetValues(print_button, XtNmenuName, LBLPRINTMENU, NULL); print_menu = XtVaCreatePopupShell(LBLPRINTMENU, simpleMenuWidgetClass, print_button, XtNdepth, our_depth, XtNvisual, our_visual, #ifdef GREY XtNcolormap, our_colormap, #endif NULL); for(i = 0; (int)XtNumber(print_style)>i; i++) { switch(i) { case PRINTALL: case PRINTCUR: entry = XtVaCreateManagedWidget(print_style[i], smeBSBObjectClass, print_menu, NULL); XtAddCallback(entry, XtNcallback, PrintDVI, (XtPointer)i); break; #ifdef MARKPAGE case PRINTMARKED: case PRINTREGION: case PRINTALLMARKED: if(EmptyPageMarkRing()) { entry = XtVaCreateManagedWidget(print_style[i], smeBSBObjectClass, print_menu, XtNsensitive, False, NULL); } else { entry = XtVaCreateManagedWidget(print_style[i], smeBSBObjectClass, print_menu, NULL); } XtAddCallback(entry, XtNcallback, PrintDVI, (XtPointer)i); break; #endif default: break; } } XawDialogAddButton(dialog, LBLCANCEL, DestroyPopupPrompt, (XtPointer)dialog); XtPopup(popup, XtGrabNone); PrintMenuEnd = False; XtAddGrab(popup, True, True); PrintApp = XtWidgetToApplicationContext(popup); while(! PrintMenuEnd) { XtAppNextEvent(PrintApp, &event); XtDispatchEvent(&event); }; XtDestroyWidget(popup); } #endif /* PRINTDVI added by Masahito Yamaga */