home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / dtx9202 / dbase / serv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-26  |  13.8 KB  |  564 lines

  1. /********************************************************/
  2. /*            Modul: SERV.C            */
  3. /*    enthält alle Funktionen, die nicht direkt von    */
  4. /*    außen erreichbar sind.                */
  5. /********************************************************/
  6.  
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <conio.h>
  10. #include <dos.h>
  11. #include <alloc.h>
  12. #include "serv.h"
  13.  
  14. extern char *cmdstr;    /* siehe LOADER.C */
  15. extern struct text_info ti;
  16. extern windows *wptr;
  17. extern int *videoseg;
  18. extern unsigned *s_st,*s_st_top;
  19.  
  20. int stmax;        /* maximale Größe des Stackpuffers
  21.                (in Byte!) */
  22. int xchgw[2000];    /* dient _wscroll() als temporärer
  23.                Puffer */
  24.  
  25. /* screen_init : screenstack initialisation
  26.    legt die Adresse des Bildschirmadapters und des Stack-
  27.    puffers fest und setzt den Stacktoppointer auf den An-
  28.    fang des Puffers. */
  29. void screen_init ()
  30. {
  31.  if (ti.currmode==7)    /* Monochrome: Es wird angenommen,
  32.                daß eine Herkuleskarte ange-
  33.                schlossen ist. */
  34.  {
  35.   outportb(0x3BF,2);    /* Dieser Befehl setzt die Herkules
  36.                Karte in den sog. Full Mode, in
  37.                dem beide Bildschirmseiten zur
  38.                Verfügung stehen. Die 2. Seite
  39.                wird als Stackpuffer genutzt.
  40.                Falls jemand zwei Bildschirme
  41.                an seinem Rechner angeschlossen
  42.                hat z.B. MDA/HGC und CGA kann
  43.                diese Zeile entfallen, wenn von
  44.                der Monochrome-Konfiguration aus
  45.                gestartet wird. Das Programm
  46.                nutzt dann den Videospeicher der
  47.                CGA-Karte als Puffer. */
  48.   videoseg=(int *)0xB0000000L;
  49.   s_st=(unsigned *)0xB8000000L;
  50.   stmax=0x4000;        /* (Größe der 2. Seite der Herku-
  51.                les-Graphik-Karte: 32 kByte) */
  52.  }
  53.  else            /* nicht Monochrome: CGA, EGA und
  54.                VGA. Hier könnte wie oben ein
  55.                freier Speicherbereich außerhalb
  56.                des von der Textausgabe benutz-
  57.                ten für für den Puffer einge-
  58.                setzt werden. Zunächst wird hier
  59.                wie für eine einzelne CGA-Karte
  60.                erforderlich, dynamisch ein
  61.                Puffer alloziert. */
  62.  {
  63.   videoseg=(int *)0xB8000000L;
  64.   stmax=0x1000;        /* da dynamisch alloziert werden
  65.                habe ich hier einen kleineren
  66.                Wert gewählt. Hier muß Speicher
  67.                gespart werden. */
  68.   s_st=(unsigned *)farmalloc((unsigned long)(stmax*2));
  69.  }
  70.  s_st_top=s_st;
  71. }
  72.  
  73. /* getcurpos : get cursor position
  74.    holt sich über den BIOS interrupt 10h die absolute Cur-
  75.    sorposition */
  76. unsigned getcurpos (void)
  77. {
  78.  _BH=0;
  79.  _AH=3;
  80.  geninterrupt(0x10);
  81.  return(_DX);
  82. }
  83.  
  84. /* setcurpos : set cursor position
  85.    setzt über den BIOS interrupt 10h die Cursorposition.
  86.    Der übergebene Parameter hat die Form 0xYYXX, so daß
  87.    also der obere nibble (most significant byte, höchstwer-
  88.    tiges Byte) die Zeile und das untere nibble entsprechend
  89.    die Spalte definiert. Entsprechend ist auch die Übergabe
  90.    bzw. Übernahme der Position vom BIOS definiert. Dies
  91.    Format wird auch in getcurpos(), setwcurpos() und
  92.    getwcurpos() benutzt. */
  93. void setcurpos (unsigned pos)
  94. {
  95.  _BH=0;
  96.  _DX=pos;
  97.  _AH=2;
  98.  geninterrupt(0x10);
  99. }
  100.  
  101. /* getwcurpos : get window cursor position
  102.    ermittelt die window relative Position des Cursors falls
  103.    diese im Window liegt, sonst wird Position (0,0) zurück-
  104.    gegeben. */
  105. unsigned getwcurpos (void)
  106. {
  107.  int x,y;
  108.  int frame=(wptr->fr_type!=0);    /* frame wird hier 1 falls
  109.                    fr_type ungleich 1 ist,
  110.                    so daß ... */
  111.  int ulx=wptr->ulx+frame;    /* ... hier die beschreib-
  112.                    bare Window area */
  113.  int uly=wptr->uly+frame;    /* ermittelt werden kann.
  114.                    Diese Variablen */
  115.  int lrx=wptr->lrx-frame;    /* vermeiden eine wieder-
  116.                    holte umständliche */
  117.  int lry=wptr->lry-frame;    /* Berechnung der Variab-
  118.                    lenadressen. */
  119.  x=getcurpos();
  120.  y=x>>8;
  121.  x=x&0xF;
  122.  if (x>=ulx && y>=uly && x<=lrx && y<=lry)
  123.   return(((y-uly)<<8)|(x-ulx));
  124.  else
  125.   return(0);
  126. }
  127.  
  128. /* setwcurpos : set window cursor position
  129.    setzt die neue Cursorposition nach relativen Windowkoor-
  130.    dinaten, falls die Koordinaten im Window liegen */
  131. void setwcurpos (unsigned pos)
  132. {
  133.  int x,y;
  134.  int frame=(wptr->fr_type!=0);
  135.  int ulx=wptr->ulx+frame;
  136.  int uly=wptr->uly+frame;
  137.  int lrx=wptr->lrx-frame;
  138.  int lry=wptr->lry-frame;
  139.  x=pos;
  140.  y=x>>8;
  141.  x=x&0xF;
  142.  if (x<=lrx-ulx && y<=lry-uly)
  143.   setcurpos(((y+uly)<<8)|(x+ulx));
  144. }
  145.  
  146. /* getcurshape : get cursor shape
  147.    ermittelt über BIOS interrupt 10h die aktuelle Cursor-
  148.    form. Das Rückgabeformat enthält im oberen nibble (s.o.)
  149.    die Startzeile für den Scan und im unteren die Endzei-
  150.    le. */
  151. unsigned getcurshape (void)
  152. {
  153.  _BH=0;
  154.  _AH=3;
  155.  geninterrupt(0x10);
  156.  return(_CX);
  157. }
  158.  
  159. /* setcurshape : set cursor shape
  160.    setzt die gewünschte Cursorform. Zum Format siehe oben.
  161.    Z.B. liefert bei der Mono-Karte mit einer Zeichenhöhe
  162.    von 14 Zeile [0..13] die Startzeile 6 und Endzeile 6
  163.    einen Bindestrich als Cursor: sh=0x0606. Mit (0,13)
  164.    kann man einen Blockcursor erzeugen: sh=0x000C. Liegt
  165.    die Startzeile außerhalb des maximalen Bereichs ist gar
  166.    kein Cursor zu sehen: sh=0x0F00. Im Einzelfall sollte
  167.    man hier aber die Dokumentation für die eigene Grafik-
  168.    karte zu Rate ziehen. */
  169. void setcurshape (unsigned sh)
  170. {
  171.  _CX=sh;
  172.  _AH=1;
  173.  geninterrupt(0x10);
  174. }
  175.  
  176. /* _wscroll : window scroll (intern)
  177.    führt das eigentliche shiften einer Zeile nach oben oder
  178.    unten aus. */
  179. static void _wscroll (int dir)
  180. {
  181.  int i;
  182.  int frame=(wptr->fr_type!=0);
  183.  int ulx=wptr->ulx+frame;
  184.  int uly=wptr->uly+frame;
  185.  int lrx=wptr->lrx-frame;
  186.  int lry=wptr->lry-frame;
  187.  if (!dir)
  188.  {
  189.   /* nach oben srollen */
  190.   /* hole untere Zeile */
  191.   gettext(ulx+1,uly+2,lrx+1,lry+1,xchgw);
  192.   /* schreibe sie eine Zeile höher */
  193.   puttext(ulx+1,uly+1,lrx+1,lry,xchgw);
  194.   /* lösche untere Zeile */
  195.   for(i=ulx;i<=lrx;i++)
  196.    dispchar(' ',(int)i,(int)lry,wptr->attr);
  197.  }
  198.  else
  199.  {
  200.   /* nach unten scrollen */
  201.   /* hole obere Zeile */
  202.   gettext(ulx+1,uly+1,lrx+1,lry,xchgw);
  203.   /* schreibe sie eine Zeile tiefer */
  204.   puttext(ulx+1,uly+2,lrx+1,lry+1,xchgw);
  205.   /* lösche obere Zeile */
  206.   for(i=ulx;i<=lrx;i++)
  207.    dispchar(' ',(int)i,(int)uly,wptr->attr);
  208.  }
  209. }
  210.  
  211. /* wscroll : window scroll
  212.    führt einen scroll der Zeilen im aktiven Window um d
  213.    Zeilen nach oben (d positiv) oder nach unten (d negativ)
  214.    aus. */
  215. void wscroll (int d)
  216. {
  217.  int i;
  218.  if (d>0)
  219.  {
  220.   for(i=0;i<d;i++)
  221.    _wscroll(0);
  222.  }
  223.  else
  224.  {
  225.   d=abs(d);
  226.   for(i=0;i<d;i++)
  227.    _wscroll(1);
  228.  }
  229. }
  230.  
  231. /* wclear : window clear
  232.    löscht die beschreibare Fläche des aktiven Windows durch
  233.    Vollschreiben mit Blanks der definierten Textfarbe des
  234.    Windows. */
  235. void wclear (void)
  236. {
  237.  int i;
  238.  int frame=(wptr->fr_type!=0);
  239.  int ulx=wptr->ulx+frame;
  240.  int uly=wptr->uly+frame;
  241.  int lrx=wptr->lrx-frame;
  242.  int lry=wptr->lry-frame;
  243.  int sym=' '|(wptr->attr<<8);
  244.  for(i=ulx+uly*80;i<=lrx+lry*80;)
  245.  {
  246.   *(videoseg+i)=sym;
  247.   if (i%80==lrx)
  248.    i=((i/80)+1)*80+ulx;
  249.   else
  250.    i++;
  251.  }
  252. }
  253.  
  254. /* putccw : put char controlled in window
  255.    setzt an der aktuellen Cursorposition ein Zeichen und
  256.    setzt den Cursor auf den nächsten legalen Platz im
  257.    Window, notfalls wird ein Scroll durchgeführt. Die Zei-
  258.    chen werden zusätzlich auf Sonderfunktionen geprüft.
  259.    Folgende Zeichen lösen keine direkte
  260.    Zeichenausgabe aus:
  261.    '\f' (0x0F) dez. 15 (Form Feed):     scrolled das ganze
  262.                     Window hoch und po-
  263.                     sitioniert den Cur-
  264.                     sor auf (0,0) rela-
  265.                     tiv.
  266.    '\t' (0x09) dez  9  (Tabulator):    schreibt Blanks bis
  267.                     zur nächsten durch
  268.                     8 teilbaren relati-
  269.                     ven Spaltenposi-
  270.                     tion.
  271.    '\n' (0x0A) dez 10  (New Line):    führt einen Zeilen-
  272.                     vorschub und (!) da
  273.                     nach einen Wagen-
  274.                     rücklauf (Carriage
  275.                     Return) aus.
  276.    '\r' (0x0C) dez 13  (Return):    Wagenrücklauf, po-
  277.                     sitioniert den
  278.                     Cursor am linken
  279.                     Rand ses Windows.
  280.    '\a' (0x07) dez  7  (Audible Bell):    Piepser
  281.    '\b' (0x08) dez  8  (Backspace):    geht ein Zechen
  282.                     nach links zurück
  283.                     ohne das Zeichen
  284.                     zu löschen. */
  285. int putccw (char c)
  286. {
  287.  unsigned x,y,i;
  288.  int frame=(wptr->fr_type!=0);
  289.  int ulx=wptr->ulx+frame;
  290.  int uly=wptr->uly+frame;
  291.  int lrx=wptr->lrx-frame;
  292.  int lry=wptr->lry-frame;
  293.  int attr=wptr->attr;
  294.  x=getcurpos();        /* um ein Hin- und Hertransformie-
  295.                ren der Koordinaten zu vermei-*/
  296.  y=x>>8;        /* den, wird mit absoluten Werten*/
  297.  x&=0xFF;        /* gerechnet. */
  298.  switch (c)
  299.  {
  300.   case '\f' :
  301.    for (i=uly;i<=lry;i++)
  302.     _wscroll(0);
  303.    x=ulx;
  304.    y=lry;
  305.    setcurpos((y<<8)|x);
  306.    break;
  307.   case '\t' :
  308.    if (x+(8-(x-ulx)%8)<lrx)
  309.    {
  310.     while (((x-ulx)%8!=0)&&((x-lrx)%8!=0))
  311.     {
  312.      putccw(' ');        /* Whow! Rekursiv! */
  313.      x++;
  314.     }
  315.     break;
  316.    }
  317.   case '\n' :
  318.    if (y<lry)
  319.    {
  320.     if (x<lrx)
  321.      setcurpos(((++y)<<8)|(++x));
  322.     else
  323.      setcurpos(((++y)<<8)|ulx);
  324.    }
  325.    else
  326.    {
  327.     _wscroll(0);
  328.     if (x<lrx)
  329.      setcurpos((y<<8)|(++x));
  330.     else
  331.      setcurpos((y<<8)|ulx);
  332.    }            /* Das fehlende break bewirkt, daß auch
  333.                noch der return ausgeführt wird */
  334.   case '\r' :
  335.    setcurpos((y<<8)|ulx);
  336.    break;
  337.   case '\a' :
  338.    sound(440);        /* Kammerton a */
  339.    delay(20);
  340.    nosound();
  341.    break;
  342.   case '\b' :
  343.    if (x>ulx)
  344.     setcurpos((y<<8)|(x-1));
  345.    else
  346.     if (y>uly)
  347.      setcurpos(((y-1)<<8)|lrx);
  348.    break;
  349.   default :        /* Der Normalfall. Zeichenausgabe */
  350.    dispchar(c,x,y,attr);
  351.    if (x<lrx)
  352.    {
  353.     setcurpos((y<<8)|(x+1));
  354.    }
  355.    else
  356.     if (y<lry)
  357.     {
  358.      setcurpos(((y+1)<<8)|ulx);
  359.    }
  360.     else
  361.     {
  362.      _wscroll(0);
  363.      setcurpos((y<<8)|ulx);
  364.     }
  365.  }
  366.  return(c);
  367. }
  368.  
  369. /* dispstr : display string
  370.    Stringausgabe window relativ, allerdings (!) ohne die
  371.    Begrenzung des Windows zu beachten. Dient der schnellen
  372.    Stringausgabe. Kontrolle der Ausgabe wird bei wputs()
  373.    durchgeführt. */
  374. int dispstr (const char *str, int cy, int cx, int attr)
  375. {
  376.  int i,len=strlen(str);
  377.  int frame=(wptr->fr_type!=0);
  378.  int x=wptr->ulx+frame+cx;
  379.  int y=wptr->uly+frame+cy;
  380.  for(i=0;i<len;i++)
  381.   dispchar(*(str+i),x+i,y,attr);
  382.  return(*(str+i));
  383. }
  384.  
  385. /* wputs : window put string
  386.    kontrollierte Ausgabe von Strings im aktiven Window */
  387. int wputs (const char *str)
  388. {
  389.  int i,len=strlen(str);
  390.  for(i=0;i<len;i++)
  391.   putccw(*(str+i));
  392.  return(*(str+i));
  393. }
  394.  
  395. /* ccmdstr : clear commandstring (and set a)
  396.    löscht cmdstr (schreibt mit Blanks voll) und schreibt in
  397.    die erste Stelle die Ziffer (!) a. */
  398. void ccmdstr (int a, char *cmdstr)
  399. {
  400.  int i;
  401.  cmdstr[0]=a+48;
  402.  for(i=1;cmdstr[i]!=0;i++)
  403.   cmdstr[i]=' ';
  404. }
  405.  
  406. /* wopen : window open
  407.    öffnet ein Window mit den angegebenen Koordinaten ulx,
  408.    uly, lrx, lry schreibt den zu sichernden Bereich in den
  409.    Puffer wbptr, löscht den Windowbereich mit dem Attribut
  410.    attr, zeichnet einen Rahmen der Art fr_type mit der
  411.    Farbe fr_attr und trägt eventuell einen Header in der
  412.    Rahmenfarbe zentriert ein. */
  413. void wopen (unsigned *wbptr, int ulx, int uly, int lrx,
  414.     int lry, int attr, int fr_type, int fr_attr,
  415.     char *header)
  416. {
  417.  int i,j,frame=(fr_type!=0);
  418.  char ulc,urc,llc,lrc,hor,ver;
  419.  int hlen=strlen(header);
  420.  wptr->ulx=ulx;
  421.  wptr->uly=uly;
  422.  wptr->lrx=lrx;
  423.  wptr->lry=lry;
  424.  wptr->attr=attr;
  425.  wptr->fr_type=fr_type;
  426.  wptr->fr_attr=fr_attr;
  427.  wptr->header=header;
  428.  /* sichere zu überschreibenden Bereich des Windows */
  429.  gettext(ulx+1,uly+1,lrx+1,lry+1,wbptr);
  430.  if (fr_type)        /* wenn Rahmen gewünscht ... */
  431.  {
  432.   switch (fr_type)    /* definiere Rahmenformen */
  433.   {
  434.    case 2 :
  435.     ulc='╔';
  436.     urc='╗';
  437.     llc='╚';
  438.     lrc='╝';
  439.     hor='═';
  440.     ver='║';
  441.     break;
  442.    case 3 :
  443.     ulc='╓';
  444.     urc='╖';
  445.     llc='╙';
  446.     lrc='╜';
  447.     hor='─';
  448.     ver='║';
  449.     break;
  450.    case 4 :
  451.     ulc='╒';
  452.     urc='╕';
  453.     llc='╘';
  454.     lrc='╛';
  455.     hor='═';
  456.     ver='│';
  457.     break;
  458.    case 5 :
  459.     ulc='█';
  460.     urc='█';
  461.     llc='█';
  462.     lrc='█';
  463.     hor='█';
  464.     ver='█';
  465.     break;
  466.    default :
  467.     ulc='┌';
  468.     urc='┐';
  469.     llc='└';
  470.     lrc='┘';
  471.     hor='─';
  472.     ver='│';
  473.     break;
  474.   }
  475.   dispchar(ulc,ulx,uly,fr_attr); /* zeichne den Rahmen */
  476.   dispchar(urc,lrx,uly,fr_attr);
  477.   dispchar(llc,ulx,lry,fr_attr);
  478.   dispchar(lrc,lrx,lry,fr_attr);
  479.   for (i=ulx+1;i<lrx;i++)
  480.   {
  481.    dispchar(hor,i,uly,fr_attr);
  482.    dispchar(hor,i,lry,fr_attr);
  483.   }
  484.   for (i=uly+1;i<lry;i++)
  485.   {
  486.    dispchar(ver,ulx,i,fr_attr);
  487.    dispchar(ver,lrx,i,fr_attr);
  488.   }
  489.   if (*header!=0)    /* wenn Header gewünscht ... */
  490.   {
  491.    i=(lrx-ulx)/2-hlen/2+ulx;    /* zentriere */
  492.    if (i<ulx)
  493.     i=ulx;
  494.    if (i>ulx)
  495.     dispchar(' ',i-1,uly,fr_attr); /* zuerst ein Blank */
  496.    /* dann Header */
  497.    for(j=0;i<lrx&&*(header+j);i++,j++)
  498.     dispchar(*(header+j),i,uly,fr_attr);
  499.    if (i<=lrx)
  500.     dispchar(' ',i,uly,fr_attr); /* ein Blank anhängen */
  501.   }
  502.  }
  503.  wclear();
  504.  /* setze Cursor auf (0,0) relativ */
  505.  setcurpos(((uly+frame)<<8)|(ulx+frame));
  506. }
  507.  
  508. /* attr_string : attribute string (to attribute value)
  509.    wandelt den in dBASE/FoxBASE übergebenen Farbcode in
  510.    einen integer Wert um. Die Funktion wird von der Funk-
  511.    tion screenh() genutzt um ein Window zu öffnen, dessen
  512.    Farbcodes in dem Format übergeben werden, wie es für die
  513.    Anweisung SET COLOR TO üblich ist. Zum Beispiel: +B/W
  514.    (hellblau auf weiß) = 0111 1001 b = 0x79 (nachrech-
  515.    nen). */
  516. int attr_string (char *attrs)
  517. {
  518.  int i,attr=0,backflag=0;
  519.  for(i=0;i<3 && *(attrs+i)!=0;i++)
  520.   switch (*(attrs+i))
  521.   {
  522.    case '*' :
  523.     attr|=0x80<<(backflag*4);
  524.     break;
  525.    case '+' :
  526.     attr|=0x08<<(backflag*4);
  527.     break;
  528.    case 'x' :
  529.    case 'X' :
  530.     break;
  531.    case 'w' :
  532.    case 'W' :
  533.     attr|=0x07<<(backflag*4);
  534.     break;
  535.    case 'i' :
  536.    case 'I' :
  537.     attr|=0x70<<(backflag*4);
  538.     break;
  539.    case 'u' :
  540.    case 'U' :
  541.     attr|=0x01<<(backflag*4);
  542.     break;
  543.    case 'n' :
  544.    case 'N' :
  545.     attr|=0x00<<(backflag*4);
  546.     break;
  547.    case 'b' :
  548.    case 'B' :
  549.     attr|=0x01<<(backflag*4);
  550.     break;
  551.    case 'g' :
  552.    case 'G' :
  553.     attr|=0x02<<(backflag*4);
  554.     break;
  555.    case 'r' :
  556.    case 'R' :
  557.     attr|=0x04<<(backflag*4);
  558.     break;
  559.    case '/' :
  560.     backflag=1;
  561.     break;
  562.   }
  563.  return(attr);
  564. }