home *** CD-ROM | disk | FTP | other *** search
- /* ------------------------------------------------- */
- /* FFH-LIB.C */
- /* FFast-Help-Library */
- /* Die Routinen dieser Datei können in ein belie- */
- /* biges Programm eingebunden werden. Durch den */
- /* Aufruf der Funktionen können die mit FFHC compi- */
- /* lierten Hilfstexte verwendet werden. */
- /* (c) 1991 Axel Geßner & DMV-Verlag */
- /* ------------------------------------------------- */
-
- #include "ffh.h"
- #include "ffh-lib.h"
- #include <conio.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #include <alloc.h>
-
- #define FRAME_FORE WHITE
- #define FRAME_BACK BLACK
- #define TEXT_FORE LIGHTGRAY
- #define TEXT_BACK BLACK
- #define HIGH_FORE WHITE
- #define HIGH_BACK BLACK
- #define HIGH_SEL_FORE BLACK
- #define HIGH_SEL_BACK LIGHTGRAY
- #define WIN_X1 16
- #define WIN_Y1 5
- #define WIN_X2 68
- #define WIN_Y2 22
- #define WIN_STYLE 2
- #define MAX_HELP_V 10
- #define MAX_XREFS 50
- #define MAX_PAGES 20
-
- typedef struct list /* Schlüsselwortliste */
- {
- char *keyword; /* Schlüsselwort */
- long offs; /* Dateioffset */
- long textlen; /* Länge des Hilfstextes */
- struct list *prev, *next;
- } list_t;
-
- /* --- PROTOTYPEN ---------------------------------- */
- /* Listenverwaltung */
-
- list_t *search (char *name, list_t *list);
- /* sucht in der alphabetisch geordneten Liste */
- /* »list« nach »name« */
-
- list_t *insert (char *name, long offs,
- long textlen, list_t *at);
- /* ordnet die Daten als at->next in der Liste ein */
-
- list_t *dellist (list_t *list);
- /* löscht die Liste »list« vollständig */
-
- /* Fensterverwaltung */
-
- static void box(int x1,int y1,int x2,int y2,int style);
- /* zeichnet Rahmen mit den angeg. Koordinaten */
-
- static void mkwindow(int x1,int y1,int x2,int y2,
- int style,int fore,int back);
- /* Öffnet Fenster */
-
- static void rmwindow(void);
- /* schließt Fenster wieder */
-
- static void setheader(char *s);
- /* setzt eine Überschrift im Fenster */
-
- static void setfoot(char *s);
- /* setzt Fußnote im Fenster */
-
- /* System-Verwaltung */
-
- static int getindex (void);
- /* liefert den niedrigstmöglichen freien Index von */
- /* »help_v« zurück; bzw. -1 für »vollen« Vektor */
-
- static char *gethelptext (int handle, char *keyword);
- /* liefert in NEU ALLOKIERTEM Speicher den */
- /* eigentlichen Hilfstext zurück; ferner wird die */
- /* Liste eine Liste der Querverweise erzeugt */
-
- static char *outtext (char *s);
- /* gibt den Text ab s abwärts oder aufwärts */
- /* gerichtet aus */
-
- /* DATEN */
- struct
- {
- FILE *fp; /* Dateipointer auf die Hilfedatei */
- list_t *list; /* Liste für Inhaltsverzeichnis */
- } help_v [MAX_HELP_V];
- /* Vektor der verschiedenen Hilfedateien */
-
- struct
- {
- char name[MAX_KEYWORD+1]; /* Name des Bezeichners */
- int x, y; /* Position auf dem Bildschirm */
- } xref_v [MAX_XREFS]; /* Vektor der Crossreferences */
-
- struct
- {
- char *start; /* Start der aktuellen Seite */
- } page_v [MAX_PAGES];
- int maxpage = 0;
-
- static int initialized = 0;
- void *winback; /* Hintergrund für Hilfefenster */
- struct text_info ti;
- int (*cmpstr) (const char *s1, const char *s2);
- int tabsize = 2;
-
-
- /* ------------------------------------------------- */
- /* Globale Steuer-Prozeduren */
-
- void initFFHlib (void)
- {
- int i;
-
- for (i = 0; i < MAX_HELP_V; i++) {
- help_v[i].fp = NULL;
- help_v[i].list = NULL;
- }
- initialized = 1;
- cmpstr = stricmp;
- atexit (exitFFHlib);
- }
-
- void exitFFHlib (void)
- /* Exit-Func; von initFFHlib autom. installiert */
- {
- int i;
-
- for (i = 0; i < MAX_HELP_V; i++) {
- if (help_v[i].fp == NULL)
- continue;
- fclose (help_v[i].fp);
- help_v[i].list = dellist (help_v[i].list);
- help_v[i].fp = NULL;
- }
- initialized = 0;
- }
-
- int inithelp (char *fname)
- {
- FILE *fp;
- int ndx = getindex ();
-
- fp = fopen (fname, "rb");
- if (fp == NULL || !initialized || ndx == -1)
- return -1;
- help_v[ndx].fp = fp;
- fread ((void *) &header, sizeof (header), 1, fp);
- fseek (fp, header.offs, SEEK_SET);
- while (!feof (fp)) {
- char keyword[40] = {""};
- int c;
- long offs, textlen;
-
- fscanf (fp, "%s", keyword);
- c = fgetc (fp);
- fread ((void *) &offs, sizeof (offs), 1, fp);
- fread ((void *) &textlen, sizeof (textlen), 1, fp);
- help_v[ndx].list = insert (keyword, offs, textlen,
- help_v[ndx].list);
- c = fgetc (fp);
- if (c == 0)
- break; /* Abbruch, da Endekriterium */
- else
- ungetc (c, fp);
- }
- return ndx;
- }
-
- int exithelp (int handle)
- {
- if (handle > MAX_HELP_V || help_v[handle].fp == NULL)
- return -1;
- fclose (help_v[handle].fp);
- help_v[handle].fp = NULL;
- help_v[handle].list = dellist (help_v[handle].list);
- return handle;
- }
-
- int showhelp (int handle, char *keyword)
- {
- char *s = keyword;
-
- mkwindow (WIN_X1, WIN_Y1, WIN_X2, WIN_Y2,
- WIN_STYLE, FRAME_FORE, FRAME_BACK);
- setfoot ("PgUp/PgDn - Left/Right");
- setheader ("FFast-Help");
- do {
- char *ss = gethelptext (handle, s);
-
- if (!ss) break;
- textcolor (TEXT_FORE);
- textcolor (TEXT_BACK);
- s = outtext (ss);
- free ((void *) ss);
- } while (s);
-
- rmwindow ();
- return handle;
- }
-
- /* ------------------------------------------------- */
- /* System-Verwaltung */
-
- char *outtext (char *s)
- {
- int key = 0;
- int sel = 0; /* sel = selected */
- int aktpage = 0; /* momentan dargestellte Seite */
- int aktxref = 0; /* aktuelle xref */
-
- while (key != 27) {
- char *s_sav = s;
-
- clrscr ();
- while (*s) {
- if (wherey() == ti.winbottom-ti.wintop+1) {
- page_v[maxpage++].start = s_sav;
- goto end_while;
- }
- switch (*s) {
- case '\t' : {
- int i;
- for (i = 1; i <= tabsize; i++)
- putch (' ');
- }
- break;
- case 'Γ' :
- s++;
- if (aktxref != sel)
- textcolor (HIGH_FORE);
- textbackground (HIGH_BACK);
- else
- textcolor (HIGH_SEL_FORE);
- textbackground (HIGH_SEL_BACK);
- xref_v[aktxref].x = wherex();
- xref_v[aktxref].y = wherey ();
- cprintf ("%s", xref_v[aktxref].name);
- s += strlen (xref_v[aktxref].name);
- aktxref++;
- break;
- default :
- textcolor (TEXT_FORE);
- textbackground (TEXT_BACK);
- putch (*s);
- break;
- }
- s++;
- }
- end_while:
- key = getkey();
- switch (key) {
- case -77 : /* Cursor right */
- case -80 : /* Cursor down */
- if (sel < aktxref-1) sel++;
- /* aktxref höchst. bel. Element */
- s = s_sav;
- maxpage--;
- /* die Seite wird beibehalten */
- break;
- case -75 : /* Cursor left */
- case -72 : /* Cursor up */
- if (sel != 0) sel--;
- s = s_sav;
- maxpage--;
- /* die Seite wird beibehalten */
- break;
- case -73 : /* Page up */
- if (aktpage != 0) aktpage--;
- s = page_v[aktpage].start;
- maxpage--;
- break;
- case -81 : /* Page down */
- if (aktpage < maxpage)
- aktpage++;
- else
- s = s_sav;
- break;
- case 13 : /* Return */
- return xref_v[sel].name;
- case 27 : /* Esc */
- break;
- default : /* Andere Tasten: nichts tun */
- break;
- }
- aktxref = 0;
- }
- return NULL;
- }
-
- int getindex (void) /* liefert freien Index */
- {
- int i;
-
- for (i = 0; i < MAX_HELP_V; i++)
- if (help_v[i].fp == NULL) /* nicht verwendet */
- return i;
- return -1;
- }
-
- char *gethelptext (int handle, char *keyword)
- {
- list_t *l = search (keyword, help_v[handle].list);
- char *s = (char *) calloc (l->textlen + 1,
- sizeof (char)), *ss;
- FILE *fp = help_v[handle].fp;
- char aktxref = 0;
-
- if (l == NULL) {
- free ((void *) s);
- return NULL;
- }
- fseek (fp, l->offs, SEEK_SET);
- fread ((void *) s, l->textlen, 1, fp);
-
- for (ss = s; *s; s++) {
- if (*s == 'Γ') {
- char *org = ++s;
- while (*s != 'Γ') s++;
- strncpy (xref_v[aktxref].name,org, s-org);
- xref_v[aktxref].name[s-org] = '\0';
- aktxref++; s++;
- }
- }
- return ss;
- }
-
- int getkey (void)
- {
- union REGS r;
- r.h.ah = 0;
- int86(0x16,&r,&r);
- return (r.h.al == 0) ? -r.h.ah : r.h.al;
- }
-
- /* ------------------------------------------------- */
- /* Listen-Verwaltung */
-
- list_t *search (char *name, list_t *list)
- {
- list_t *l = list;
- char toleft;
-
- if (cmpstr (name, list->keyword) == 0)
- return list;
- else
- if (cmpstr (name, list->keyword) < 0)
- l = l->prev, toleft = 1;
- else
- l = l->next, toleft = 0;
-
- switch (toleft) {
- case 0 : /* nach rechts gehend */
- while (l != NULL) {
- if (!cmpstr (name, l->keyword))
- break;
- else
- l = l->next;
- }
- return l;
- case 1 : /* nach links gehend */
- while (l != NULL) {
- if (!cmpstr (name, l->keyword))
- break;
- else
- l = l->prev;
- }
- return l;
- }
- return NULL;
- }
-
- list_t *insert (char *name, long offs,
- long textlen, list_t *at)
- {
- if (at == NULL) { /* allererstes Element */
- at = (list_t *) calloc (1, sizeof (list_t));
- at->keyword = (char *) calloc (strlen(name)+1,
- sizeof (char));
- strcpy (at->keyword, name);
- at->offs = offs;
- at->textlen = textlen;
- } else {
- at->next = (list_t *) calloc (1, sizeof (list_t));
- at->next->prev = at;
- at = at->next;
- at->keyword = (char *) calloc (strlen(name)+1,
- sizeof (char));
- strcpy (at->keyword, name);
- at->offs = offs;
- at->textlen = textlen;
- }
- return at;
- }
-
- list_t *dellist (list_t *list)
- {
- list_t *n, *l = list;
- while (l->next != NULL)
- l = l->next;
- l = list;
- while (l != NULL) {
- n = l->prev;
- free ((void *) l->keyword);
- free ((void *) l);
- l = n;
- }
- return NULL;
- }
-
- /* ------------------------------------------------- */
- /* Window-Verwaltung */
-
- void box(int x1,int y1,int x2,int y2,int style)
- /* Zeichnet Rahmen */
- {
- unsigned i;
- unsigned hor,ver,lo,ro,lu,ru;
- /* horiz,vert,links/rechts oben,links/rechts unten */
-
- switch (style) {
- case 1 : hor = '─';
- ver = '│';
- lo = '┌';
- ro = '┐';
- lu = '└';
- ru = '┘';
- break;
- case 2 : hor = '═';
- ver = '║';
- lo = '╔';
- ro = '╗';
- lu = '╚';
- ru = '╝';
- break;
- }
- gotoxy(x1, y1); putch(lo);
- for (i = 1; i <= x2-x1-1; i++)
- putch(hor);
- putch(ro);
- for (i = 1; i <= y2-y1-1; i++) {
- gotoxy(x1, y1+i); putch(ver);
- gotoxy(x2, y1+i); putch(ver);
- }
- gotoxy(x1,y2);putch(lu);
- for (i = 1; i <= x2-x1-1; i++)
- putch(hor);
- putch(ru);
- }
-
- void mkwindow(int x1,int y1,int x2,int y2,int style,
- int fore,int back)
- {
- winback = malloc((y2-y1+1)*(x2-x1+1)*2);
- window(1,1,80,25);
- gettext(x1,y1,x2,y2,winback);
- textcolor (fore);
- textbackground (back);
- box (x1,y1,x2,y2,style);
- window (x1+1, y1+1, x2-1, y2-1);
- gettextinfo (&ti);
- clrscr();
- }
-
- void rmwindow(void)
- {
- puttext(ti.winleft-1,ti.wintop-1,
- ti.winright+1,ti.winbottom+1,winback);
- window(ti.winleft-1,ti.wintop-1,
- ti.winright+1,ti.winbottom+1);
- free ((void *) winback);
- }
-
- void setheader(char *s)
- {
- int x1 = ti.winleft;
- int x2 = ti.winright;
- window(1,1,80,25);
- gotoxy(x1+((x2-x1+1-strlen(s)) >> 1),ti.wintop-1);
- cprintf("%s",s);
- window(x1,ti.wintop,x2,ti.winbottom);
- }
-
- void setfoot(char *s)
- {
- window(1,1,80,25);
- gotoxy(ti.winright+1-strlen(s),ti.winbottom+1);
- cprintf("%s",s);
- window(ti.winleft,ti.wintop,
- ti.winright,ti.winbottom);
- }
- /* ------------------------------------------------- */
- /* Ende von FFH-LIB.C */
-
-