/* @(#)tvutil.c 17.1.1.1 (ES0-DMD) 01/25/02 17:36:57 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Module .IDENTIFICATION tvutil.c .AUTHOR Francois Ochsenbein [ESO-IPG] .LANGUAGE C .KEYWORDS Termcap .ENVIRONMENT TermWindows .COMMENTS This module provides various utilities related to TERMCAPabilities or Terminal manipulations. .VERSION 2.0 12-Jun-1987: Creation. Extracted from full capability version. .VERSION 2.2 23-Jun-1987: Adapted to UNIX .VERSION 2.3 02-Dec-1987 Use of external function while waiting for input .VERSION 2.4 21-Feb-1990 Removed warning .VERSION 2.5 10-Jun-1991: Added %p formatting (for HP termcapfiles) ----------------------------------------------------------------------------*/ #define DEBUG 0 /* For debugging only */ #define PM_LEVEL LEVEL_TU #define TW_MACROS 0 /* Don't use TermWindows Macros */ #define TW_import 0 #define TW_STRUCT 0 /* Do not use window Structures */ #include MID_EXTERN TERM *terms; /* Macros just to improve readibility */ #define NCAPS (terms->ns) #define CAPLIST (terms->caplist) #define CAPSIZE (terms->size) #define CAPTOP (terms->captop) MONITOR(TVUTIL); /*========================================================================== * tu_format *==========================================================================*/ int tu_format (out, fm, coo) /*++++++++++++++ .PURPOSE Edits coordinates according to the coded TERMCAP format. .RETURNS Length of edited string .REMARKS No test on the length of edited string is performed. If the format designates more than 2 arguments, the 3rd is the repetition of the first, etc.. ---------------*/ unsigned char *out; /* OUT: The output buffer, receiving edited coordinates */ unsigned char *fm; /* IN: The coded TERMCAP format */ short int coo[2]; /* IN: Coordinates to edit */ { MID_STATIC short int arg[2] = {0,0}; /* Local copy of coordinates */ MID_STATIC char digitS[12] = " " ; /* Edition buffer */ MID_STATIC unsigned char *digit = (unsigned char *)digitS; register unsigned char *p, *pf; unsigned char *p_end; int j, narg, x, led; ENTER("+tu_format"); /* Local copy of arguments */ arg[0] = coo[0], arg[1] = coo[1]; narg=0; /* Scan the format string, performing the substitutions when the FORMAT char is found */ p = out; pf = fm + 4; p_end = pf + *fm; while (pf < p_end) { if (*pf != FORMAT) { *(p++) = *(pf++); continue; } /* --- Here, only if FORMAT char was found --- */ led = 9; /* Length of argument edition */ switch(*(++pf)) { case 'i': /* Increment all arguments */ arg[0]++, arg[1]++; pf++; break; case 'p': /* Argument number as %p[1-9] */ arg[narg] = coo[*(++pf) - '1']; pf++; break; case 'r': /* Swap arguments */ x = arg[0]; arg[0] = arg[1]; arg[1] = x; pf++; break; case 'n': /* Special arguments change */ arg[0] ^= 0140; arg[1] ^= 0140; pf++; break; case '>': /* >xy : if arg>x, add y */ if(arg[narg] > (short int)*(pf+1)) arg[narg] += *(pf+2); pf += 3; break; /* The following effectively edits arguments */ case '.': /* Straight transmit */ *(p++) = arg[narg]; narg ^= 1; pf++; break; case '+': /* Transmit argument + x */ *(p++) = arg[narg] + *(++pf); narg ^= 1; pf++; break; case '0': case '1': /* Edit with led chars */ case '2': case '3': case '4': led = *pf - '0'; case 'd': /* Identical with '0' */ if (led == 9) led = 0; x = arg[narg]; narg ^= 1; j=sizeof(digit); while((led>0) || x) /* Edit the argument */ { digit[--j] = '0' + x%10; x /= 10; led--; } while (j",(char *)pf,1); EXIT(0); } } #if DEBUG TRACE_ED_STR2("Output after formatting:",out,p-out); #endif EXIT(p-out); /* Length of edited string */ } /*========================================================================== * tu_scap *==========================================================================*/ char *tu_scap (cap2) /*++++++++++++++ .PURPOSE Retrieve a named capability. .RETURNS Address of the capability field (starting with a :); NULL if not found. .REMARKS Dichotomic search is performed via the index. ----------------*/ char cap2[2]; /* IN: The cap_code to look for */ { register INDEX *low, *high, *middle; INDEX *match; char *p; ENTER("*tu_scap"); TRACE_ED_STR2("... Searching capability =>",cap2,2); low = (INDEX * ) (CAPLIST + terms->index); high = low + (NCAPS-1); match= NULL_PTR(INDEX); /* Matching address */ while( high >= low) /* Check first byte */ { middle = low + ((high-low)/2); if ( cap2[0] < middle->cap[0] ) { high = middle-1; continue; } if ( cap2[0] > middle->cap[0] ) { low = middle+1; continue; } /* Check Second byte */ if ( cap2[1] < middle->cap[1] ) { high = middle-1; continue; } if ( cap2[1] > middle->cap[1] ) { low = middle+1; continue; } match = middle; break; } /* Entries followed by `@' mean "Not such a capability" */ if (match) { p = match->icap + CAPLIST; if (*(p+3) == '@') p = NULL_PTR(char); } else p = NULL_PTR(char); EXITp(p); } /*========================================================================== * tv_ac *==========================================================================*/ int tv_ac(source, len, dest) /*++++++++++++ .PURPOSE Converts Achars to ASCII chars. .RETURNS Number of Graphic Chars in the source string. .REMARKS The converted string is NOT terminated with an EOS. Graphic Characters are translated to '+', '-', '|', '~' -------------*/ ACHAR *source; /* IN: Source string of Achar's */ int len; /* IN: Length of strings */ char *dest; /* OUT: Converted string */ { register int l; register ACHAR *pa; register char *pc; ENTER_("+tv_at"); status = 0; /* Number of Graphic Characters */ for (pa = source, l = len, pc = dest; --l >=0; pa++, pc++) { *pc = *pa & 0177; if (isGraphic(*pa)) { status++; switch(*pc) { case RuleChar(_HORIZONTAL_): *pc = '-'; break; case RuleChar(_VERTICAL_): *pc = '|'; break; case RubbishChar(): *pc = '~'; break; default: *pc = '+'; break; } } } TRACE_ED_STR2("Converted =>", dest, len); EXIT(status); } /*========================================================================== * tv_aloc *==========================================================================*/ int tv_aloc(source, len, achar) /*++++++++++++ .PURPOSE Locate in source the position of first `ACHAR' having the same attribute as `achar' .RETURNS Index in source of found character, len if none found. .REMARKS -------------*/ ACHAR *source; /* IN: Source string of Achar's */ int len; /* IN: Length of strings */ ACHAR achar; /* IN: achar which attribute is to find */ { register int l; register ACHAR *pa, ac; ENTER_("+tv_aloc"); for (pa = source, l = len, ac = achar & 0xff00; (--l >=0) && ((*pa & 0xff00) != ac); pa++) ; EXIT(pa-source); } /*========================================================================== * tv_askip *==========================================================================*/ int tv_askip(source, len, achar) /*++++++++++++ .PURPOSE Skip in source all `ACHAR's having the same attribute as `achar' .RETURNS Index in source of differing character, len if none found. .REMARKS -------------*/ ACHAR *source; /* IN: Source string of Achar's */ int len; /* IN: Length of strings */ ACHAR achar; /* IN: achar which attribute is to find */ { register int l; register ACHAR *pa, ac; ENTER_("+tv_askip"); for (pa = source, l = len, ac = achar & 0xff00; (--l >=0) && ((*pa & 0xff00) == ac); pa++) ; EXIT(pa-source); } /*========================================================================== * tv_rb *==========================================================================*/ int tv_rb(coo, dimb, limits) /*+++++++++++++ .PURPOSE Verify and updates the coordinates / dimensions of a box defined on the screen. .RETURNS OK / NOK (dimension too large) .REMARKS Not traced. ---------------*/ short int coo[2]; /* MOD: Proposed position of upper left corner \ (<0 for position from right) */ short int dimb[2]; /* MOD: Proposed dimensions (0 for complete, \ <0 for Centered) */ short int limits[2]; /* IN: Total size of screen */ { register int i; status = OK; for (i = 2; --i >= 0; ) { if (dimb[i] < 0) /* Centered */ { dimb[i] = - dimb[i]; coo[i] = (limits[i] - dimb[i] + 1)/2; if (coo[i]< 0) coo[i] = 0, status = NOK; } if (coo[i] < 0) /* Position from bottom */ { coo[i] += limits[i]; if (coo[i] < 0) coo[i] = 0, status = NOK; } /* Compute size if not defined */ if (dimb[i] == 0) dimb[i] = limits[i] - coo[i]; if ((dimb[i]+coo[i]) > limits[i]) dimb[i] = limits[i] - coo[i], status = NOK; if (dimb[i] < 0) status = NOK; } if ( status == NOK) ERROR("Can't fit Box!"); return(status); }