/* -*-C-*- eopact.h */ /*-->eopact*/ /**********************************************************************/ /******************************* eopact *******************************/ /**********************************************************************/ #define MAXFRAC 8 /* maximum fractional step divisor */ #define MINFRAC 64 /* minimum fractional step divisor */ #define DIGVAL(c) (INT16)(c - '0') static void unload_fonts(); /* private routine to unload fonts on zoom */ void eopact() /* end-of-page action */ { int loop_count; /* loop count */ INT16 np; /* input page number */ BOOLEAN show_page; /* page redisplay flag */ char tc; /* temporary character */ /* Screen positioning control is done by obvious mnemonics given in the menu bar displayed by bopact(), but cursor keys and EMACS-like control keys are also recognized. Keyboard input causes an instant end-of-page action, to facilitate rapid page repositioning, and skimming through a document. All available commands are acted upon before screen display is reattempted. This makes repeated positioning commands cumulative. */ if (!quiet) OUTS(BELLS); /* wake up the user */ (void)fflush(plotfp); /* make sure display is up-to-date */ loop_count = 1; show_page = FALSE; while ((loop_count-- > 0) || kbinput()) { tc = (char)kbget(); if (tc == '\033') /* ESC sequence--function key */ { /* Expect ESC x, ESC O x or ESC [ x (x = A,B,C,D) */ tc = (char)kbget(); if ((tc == '[') || (tc == 'O')) tc = (char)kbget(); switch(tc) { case 'A': /* cursor up */ tc = 'u'; break; case 'B': /* cursor down */ tc = 'd'; break; case 'C': /* cursor right */ tc = 'r'; break; case 'D': /* cursor left */ tc = 'l'; break; case 'V': /* META-V -- previous page */ case 'v': tc = 'P'; break; default: /* none of these--accept it anyway */ break; } } switch (tc) { case '0': /* goto n-th page (recursively) */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': np = DIGVAL(tc); for (tc = (char)kbget(); ;tc = (char)kbget()) { if (isdigit(tc)) np = 10*np + DIGVAL(tc); else if ((tc == '\177') || (tc == '\b')) np /= 10; /* rubout last digit */ else break; } np = MIN(np,page_count); /* big numbers go to last page */ if (np > 0) /* got a page number */ { cur_index = np - 1; show_page = TRUE; /* out-of-sequence page */ } else show_page = FALSE; continue; case ' ': /* normal case - start next page */ case '\026': /* CTL-V */ case '\r': case '\n': case '\0': show_page = FALSE; continue; case '\f': /* redisplay current page */ case '.': show_page = TRUE; continue; case '@': /* reset to initial state */ xscreen = 0; /* 'i' is mnemonic, but too close to 'u' */ yscreen = 0; /* on keyboard */ show_page = TRUE; continue; case 'd': /* move down and redisplay */ case '\016': /* CTL-N */ yscreen -= (YSIZE/MINFRAC); show_page = TRUE; continue; case 'D': yscreen -= (YSIZE/MAXFRAC); show_page = TRUE; continue; case 'l': /* move left and redisplay */ case '\002': /* CTL-B */ xscreen -= (XSIZE/MINFRAC); show_page = TRUE; continue; case 'L': xscreen -= (XSIZE/MAXFRAC); show_page = TRUE; continue; case 'p': /* redisplay from previous page */ case 'P': case '\b': case '^': if (cur_index > 0) { cur_index--; show_page = TRUE; } else /* no previous page--ignore */ { OUTS(BELLS); loop_count = 1; show_page = FALSE; } continue; case 'q': /* quit */ case 'Q': case 'x': /* exit */ case 'X': case '\003': /* CTL-C */ case '\031': /* CTL-Y */ (void)devterm(); /* terminate device output */ (void)dviterm(); /* terminate DVI file processing */ (void)alldone(); /* this does not return */ continue; case 'r': /* move right and redisplay */ case '\006': /* CTL-F */ xscreen += (XSIZE/MINFRAC); show_page = TRUE; continue; case 'R': xscreen += (XSIZE/MAXFRAC); show_page = TRUE; continue; case 'u': /* move up and redisplay */ case '\020': /* CTL-P */ yscreen += (YSIZE/MINFRAC); show_page = TRUE; continue; case 'U': yscreen += (YSIZE/MAXFRAC); show_page = TRUE; continue; case 'z': /* zoom down one magstep (1.2) */ runmag = MAGSIZE(actfact((UNSIGN32)((5*runmag)/6))); conv = ((float)num/(float)den) * ((float)runmag/(float)STDMAG) * #if USEGLOBALMAG actfact(mag) * #endif ((float)RESOLUTION/254000.0); (void)unload_fonts(); show_page = TRUE; continue; case 'Z': /* zoom up one magstep (1.2) */ runmag = MAGSIZE(actfact((UNSIGN32)((runmag*6)/5))); conv = ((float)num/(float)den) * ((float)runmag/(float)STDMAG) * #if USEGLOBALMAG actfact(mag) * #endif ((float)RESOLUTION/254000.0); (void)unload_fonts(); show_page = TRUE; continue; default: /* unimplemented command */ OUTS(BELLS); /* beep to flag ignored input */ (void)kbflush(); /* clear any typeahead */ show_page = FALSE; loop_count = 1; continue; /* stay in read-loop */} } if (show_page) (void)prtpage(page_ptr[cur_index]); } static void unload_fonts() /* mark all fonts as not loaded */ { /* and set no current fonts */ INT16 k; for (fontptr = hfontptr; fontptr != (struct font_entry *)NULL; fontptr = fontptr->next) { for (k = 0; k < NPXLCHARS; ++k) fontptr->ch[k].isloaded = FALSE; if (fontptr->font_file_id != (FILE*)NULL) { (void)fclose(fontptr->font_file_id); fontptr->font_file_id = (FILE*)NULL; } } fontfp = (FILE*)NULL; /* no current font file */ for ( ; nopen > 0; --nopen) /* clear font file cache */ { font_files[nopen].font_id = (FILE*)NULL; font_files[nopen].use_count = (INT16)0; } /* NB: It is important here that the loop index be global; the relation of fontptr to pfontptr is used by openfont() to decide whether the font file is already open. */ for (fontptr = hfontptr; fontptr != (struct font_entry *)NULL; fontptr = fontptr->next) { pfontptr = (struct font_entry *)(NULL); /* so reldfont() calls openfont() */ (void)reldfont(fontptr); /* get new font metrics */ } }