home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tv20os2.zip / src / asm.cpp < prev    next >
C/C++ Source or Header  |  1999-05-26  |  27KB  |  963 lines

  1. /*
  2.  * asm.cc
  3.  *
  4.  * Turbo Vision - Version 2.0
  5.  *
  6.  * All the assembly functions are converted in C/C++ and placed here.
  7.  * This code was originally written by:
  8.  * - Tommy Andreasen
  9.  * - Jörn Sierwald
  10.  *
  11.  * Modified by Sergio Sigala <ssigala@globalnet.it>
  12.  *
  13.  * WARNING: very dirty code here... but it works :-)
  14.  */
  15.  
  16. #define Uses_TEditor
  17. #define Uses_TEvent
  18. #define Uses_TFrame
  19. #define Uses_TGroup
  20. #define Uses_TPoint
  21. #define Uses_TRect
  22. #define Uses_TScreen
  23. #define Uses_TTerminal
  24. #define Uses_TView
  25. #include <tvision/tv.h>
  26.  
  27. #include <ctype.h>
  28. #include <fcntl.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #ifndef __OS2__
  32. #include <unistd.h>
  33.  
  34. #include <config.h>        /* configuration file */
  35.  
  36. #ifdef HAVE_NCURSES_H
  37. #include <ncurses.h>
  38. #else
  39. #include <curses.h>
  40. #endif
  41. #endif
  42.  
  43. #ifdef ENABLE_VCS
  44. extern int vcsFd;        /* virtual console system descriptor */
  45. #endif
  46.  
  47. /*
  48.  * SS: this code is used to refresh the screen only if strictly necessary.
  49.  * Date: Mon Jun 23 10:26:09 MET DST 1997
  50.  */
  51. static int lockRefresh = 0;
  52.  
  53. inline void doRefresh(TView *p)
  54. {
  55. #ifdef ENABLE_VCS
  56.     if (vcsFd >= 0) return;        /* refresh is not necessary */
  57. #endif
  58.     if (lockRefresh != 0) return;    /* we can't do any refresh */
  59.     if (p->owner != NULL &&
  60.         p->owner->lockFlag) return;    /* the owner is locked */
  61. #ifndef __OS2__
  62.     refresh();
  63. #endif
  64. }
  65.  
  66. struct StaticVars1 {
  67.   ushort *buf;
  68. };
  69.  
  70. struct StaticVars2 {
  71.   TView*        target;
  72.   short         offset;
  73.   short         y;
  74. };
  75.  
  76. static StaticVars2 staticVars2;
  77.  
  78. int countLines( void *buf, size_t count )
  79. {
  80.   int anzahl=0;
  81.   char *str=(char*) buf;
  82.   for (unsigned int i=0; i<count; i++) {
  83. /* SS: 13 != '\n' */
  84. //    if (*(str++)==015) anzahl++;
  85.     if (*(str++)== '\n') anzahl++;
  86.   };
  87.   return anzahl;
  88. }
  89.   
  90. // These Routines are taken from Rogue Wave Tools++
  91. size_t scan( const void *block, size_t size, const char *str )
  92. {
  93.   const    long   q    = 33554393L;
  94.   const    long   q32    = q<<5;
  95.  
  96.   int    testLength    = size;
  97.   int    patternLength    = strlen(str);
  98.   if( testLength < patternLength) return UINT_MAX;
  99.  
  100.   long    patternHash    = 0;
  101.   long    testHash    = 0;
  102.  
  103.   register const char*  testP= (const char*)block;
  104.   register const char*  patP = str;
  105.   register long   x = 1;
  106.   int             i = patternLength-1;
  107.   while(i--) x =  (x<<5)%q;
  108.  
  109.   for (i=0; i<patternLength; i++) {
  110.     patternHash = ( (patternHash<<5) + *patP++  ) % q;
  111.     testHash    = ( (testHash   <<5) + *testP++ ) % q;
  112.   }
  113.  
  114.   testP = (const char*)block;
  115.   const char* end = testP + testLength - patternLength;
  116.  
  117.   while (1) {
  118.  
  119.      if(testHash == patternHash)
  120.      return testP-(const char*)block;
  121.  
  122.      if (testP >= end) break;
  123.  
  124.      // Advance & calculate the new hash value:
  125.      testHash = ( testHash + q32 - *testP * x                 ) % q;
  126.      testHash = ( (testHash<<5)  + *(patternLength + testP++) ) % q;
  127.   }
  128.   return UINT_MAX;        // Not found.
  129.  
  130. };
  131.  
  132. size_t iScan( const void *block, size_t size, const char *str )
  133. {
  134.   const    long   q    = 33554393L;
  135.   const    long   q32    = q<<5;
  136.  
  137.   int    testLength    = size;
  138.   int    patternLength    = strlen(str);
  139.   if( testLength < patternLength) return UINT_MAX;
  140.  
  141.   long    patternHash    = 0;
  142.   long    testHash    = 0;
  143.  
  144.   register const char*  testP= (const char*)block;
  145.   register const char*  patP = str;
  146.   register long   x = 1;
  147.   int             i = patternLength-1;
  148.   while(i--) x =  (x<<5)%q;
  149.  
  150.      char ch;
  151.     
  152.     if(hab != NULLHANDLE)
  153.     {
  154.         for (i=0; i<patternLength; i++) {
  155.             ch = *patP++;
  156.             ch = WinUpperChar( hab, Codepage, Country, ch );
  157.             patternHash = ( (patternHash<<5) + ch ) % q;
  158.             ch = *testP++;
  159.             ch = WinUpperChar( hab, Codepage, Country, ch );
  160.             testHash    = ( (testHash   <<5) + ch ) % q;
  161.         }
  162.     }
  163.     else
  164.     {
  165.         for (i=0; i<patternLength; i++) {
  166.             patternHash = ( (patternHash<<5) + toupper(*patP++)  ) % q;
  167.             testHash    = ( (testHash   <<5) + toupper(*testP++) ) % q;
  168.         }
  169.     }
  170.     
  171.   testP = (const char*)block;
  172.   const char* end = testP + testLength - patternLength;
  173.  
  174.   while (1) {
  175.  
  176.         if(testHash == patternHash)
  177.         {
  178.             return testP-(const char*)block;
  179.         }
  180.  
  181.      if (testP >= end) break;
  182.  
  183.      // Advance & calculate the new hash value:
  184.         if(hab != NULLHANDLE)
  185.         {
  186.             ch = *testP;
  187.             ch = WinUpperChar( hab, Codepage, Country, ch );
  188.             testHash = ( testHash + q32 - ch * x ) % q;
  189.             ch = *(patternLength + testP++);
  190.             ch = WinUpperChar( hab, Codepage, Country, ch );
  191.             testHash = ( (testHash<<5)  + ch ) % q;
  192.         }
  193.         else
  194.         {
  195.             testHash = ( testHash + q32 - toupper(*testP) * x                 ) % q;
  196.             testHash = ( (testHash<<5)  + toupper(*(patternLength + testP++)) ) % q;
  197.         }
  198.   }
  199.   return UINT_MAX;        // Not found.
  200. };
  201.  
  202. // edits.cpp defines functions previously found in edits.asm
  203. //
  204. // This file written by Jörn Sierwald based on a file
  205. // written by Tommy Andreasen
  206.  
  207. //char TEditor::bufChar( ushort p ) /* XXX */
  208. char TEditor::bufChar( uint p )    /* XXX */
  209. {
  210.     return buffer[p + ((p >= curPtr) ? gapLen : 0)];
  211. }
  212.  
  213. //ushort TEditor::bufPtr( ushort p ) /* XXX */
  214. uint TEditor::bufPtr( uint p ) /* XXX */
  215. {
  216.     return (p >= curPtr) ? p + gapLen : p;
  217. }
  218.  
  219. #if 0
  220. //void TEditor::formatLine( void *DrawBuf, ushort LinePtr, /* XXX */
  221. void TEditor::formatLine( void *DrawBuf, uint LinePtr, /* XXX */
  222.                           int Width, ushort Color )
  223. {
  224. //    ushort p = LinePtr; /* XXX */
  225.     uint p = LinePtr; /* XXX */
  226.     while ((p < curPtr) && (buffer[p] != 0x0D) && (p - LinePtr <= Width))
  227.     {
  228.         ((ushort *) DrawBuf) [p - LinePtr] = buffer[p] + ((Color & 0xFF) << 8);
  229.         p++;
  230.     }
  231.  
  232.     if (p >= curPtr)
  233.     {
  234.     p += gapLen;
  235.  
  236.     while ((p < bufSize) && (buffer[p] != 0x0D) &&
  237.            (p - gapLen - LinePtr <= Width))
  238.     {
  239.         ((ushort *) DrawBuf) [p - gapLen - LinePtr] =
  240.                                         buffer[p] + ((Color & 0xFF) << 8);
  241.         p++;
  242.     }
  243.     } else 
  244.         p += gapLen;
  245.  
  246.     while (p - gapLen - LinePtr <= Width)
  247.     {
  248.         ((ushort *) DrawBuf) [p - gapLen - LinePtr] =
  249.                                         ' ' + ((Color & 0xFF) << 8);
  250.         p++;
  251.     }
  252. }
  253. #endif
  254.  
  255. //void TEditor::formatLine( void *DrawBuf, ushort LinePtr, /* XXX */
  256. void TEditor::formatLine( void *DrawBuf, uint LinePtr, /* XXX */
  257.                           int Width, ushort Color )
  258. {
  259.   ushort i = 0;       // index in the DrawBuf
  260.   size_t p = LinePtr; // index in the Buffer
  261.   ushort curColor;
  262.  
  263.   /* draw the first part of the buffer */
  264.  
  265.   while ((p < curPtr) && (buffer[p] != '\n') && (i <= Width)) {
  266.     curColor = (p>=selStart && p<selEnd) ? (Color & 0xFF00) : ((Color & 0xFF) << 8);
  267.     if (buffer[p] == 0x9) {
  268.       do {
  269.         ((ushort *) DrawBuf) [i] = ' ' + curColor;
  270.         i++;
  271.       } while ((i % 8) && (i <= Width));
  272.       p++;
  273.     } else {
  274.       ((ushort *) DrawBuf) [i] = curColor | (uchar)buffer[p]; /* XXX */
  275.       p++; i++;
  276.     }
  277.   }
  278.  
  279.   /* draw the second part of the buffer */
  280.  
  281.   if (p >= curPtr)
  282.   {
  283.     p += gapLen;
  284.   
  285.     while ((p < bufSize) && (buffer[p] != '\n') && (i <= Width))
  286.     {
  287.       curColor = (p>=selStart && p<selEnd) ? (Color & 0xFF00) : ((Color & 0xFF) << 8);
  288.       if (buffer[p] == 0x9) {
  289.         do {
  290.           ((ushort *) DrawBuf) [i] = ' ' + curColor;
  291.           i++;
  292.         } while ((i % 8) && (i <= Width));
  293.         p++;
  294.       } else {
  295.         ((ushort *) DrawBuf) [i] = curColor | (uchar)buffer[p]; /* XXX */
  296.         p++; i++;
  297.       }
  298.     }
  299.   }
  300. //  } else
  301. //    p += gapLen; /* XXX */
  302.  
  303.   /* add some trailing spaces to fill the last part of the line */
  304.  
  305.   while (i <= Width)
  306.   {
  307.     curColor = (p>=selStart && p<selEnd) ? (Color & 0xFF00) :
  308.     ((Color & 0xFF) << 8);
  309.     ((ushort *) DrawBuf) [i] = ' ' + curColor;
  310. //    p++; i++; /* XXX */
  311.     i++;
  312.   }
  313. }
  314.  
  315. //ushort TEditor::lineEnd( ushort p ) /* XXX */
  316. uint TEditor::lineEnd( uint p ) /* XXX */
  317. {
  318. /*
  319.     while (p < curPtr)
  320.         if (buffer[p] == 0x0D)
  321.             return p;
  322.         else
  323.             p++;
  324.  
  325.     if (curPtr == bufLen)
  326.         return curPtr;
  327.  
  328.     while (p + gapLen < bufLen)
  329.         if (buffer[p + gapLen] == 0x0D)
  330.             return p;
  331.         else
  332.             p++;
  333.  
  334.     return p;
  335. */
  336.     if (p < curPtr)
  337.     {
  338.     /* SS: changed */
  339.  
  340.         while (p < curPtr)
  341.             if (buffer[p] == '\n')
  342. //            if (buffer[p] == 0x0D)
  343.                 return p;
  344.             else
  345.                 p++;
  346.  
  347.         if (curPtr == bufLen)
  348.             return bufLen;
  349.  
  350.  
  351.     }
  352.     else
  353.     {
  354.         if (p == bufLen)
  355.             return bufLen;
  356.     }
  357.  
  358. /* SS: changed */
  359.  
  360.     while (p + gapLen < bufSize)
  361.         if (buffer[p + gapLen] == '\n')
  362. //        if (buffer[p + gapLen] == 0x0D)
  363.             return p;
  364.         else
  365.             p++;
  366.  
  367.     return p;
  368.  
  369. }
  370.  
  371. //ushort TEditor::lineStart( ushort p ) /* XXX */
  372. uint TEditor::lineStart( uint p ) /* XXX */
  373. {
  374. /*
  375.     while (p - gapLen > curPtr)
  376.         if (buffer[--p + gapLen] == 0x0D)
  377.             return p + 2;
  378.  
  379.     if (curPtr == 0)
  380.         return 0;
  381.  
  382.     while (p > 0)
  383.         if (buffer[--p] == 0x0D)
  384.             return p + 2;
  385.  
  386.     return 0;
  387. */
  388. /* SS: changed */
  389.  
  390.     while (p > curPtr)
  391.         if (buffer[--p + gapLen] == '\n')
  392. //        if (buffer[--p + gapLen] == 0x0D)
  393. //            if (p+1 == bufLen || buffer[p+gapLen+1] != 0x0A)
  394.                 return p + 1;
  395. //            else
  396. //                return p + 2;
  397.  
  398.     if (curPtr == 0)
  399.         return 0;
  400.  
  401. /* SS: changed */
  402.  
  403.     while (p > 0)
  404.         if (buffer[--p] == '\n')
  405. //        if (buffer[--p] == 0x0D)
  406. //            if (p+1 == bufLen || p+1 == curPtr || buffer[p+1] != 0x0A)
  407.                 return p + 1;
  408. //            else
  409. //                return p + 2;
  410.  
  411.     return 0;
  412. }
  413.  
  414. //ushort TEditor::nextChar( ushort p ) /* XXX */
  415. uint TEditor::nextChar( uint p ) /* XXX */
  416. {
  417.     if (p == bufLen)   return p;
  418.     if (++p == bufLen) return p;
  419.  
  420.     /* SS: changed */
  421. //    int t = (p >= curPtr) ? p + gapLen : p; /* XXX */
  422. //    ulong t = (p >= curPtr) ? p + gapLen : p;
  423.  
  424.     return p;
  425. //    return ((buffer [t-1] == 0x0D) && (buffer [t] == 0x0A)) ? p + 1 : p;
  426. }
  427.  
  428. //ushort TEditor::prevChar( ushort p ) /* XXX */
  429. uint TEditor::prevChar( uint p ) /* XXX */
  430. {
  431.     if (p == 0)   return p;
  432.     if (--p == 0) return p;
  433.  
  434.     /* SS: changed */
  435. //    int t = (p >= curPtr) ? p + gapLen : p; /* XXX */
  436. //    uint t = (p >= curPtr) ? p + gapLen : p; /* XXX */
  437.  
  438.     return p;
  439. //    return ((buffer [t-1] == 0x0D) && (buffer [t] == 0x0A)) ? p - 1 : p;
  440. }
  441.  
  442. /*------------------------------------------------------------*/
  443. /* filename -       exposed.cpp                               */
  444. /*                                                            */
  445. /* function(s)                                                */
  446. /*                  Tview exposed member function             */
  447. /*------------------------------------------------------------*/
  448.  
  449. /*------------------------------------------------------------*/
  450. /*                                                            */
  451. /*    Turbo Vision -  Version 1.0                             */
  452. /*    Copyright (c) 1991 by Borland International             */
  453. /*    All Rights Reserved.                                    */
  454. /*                                                            */
  455. /*    This file Copyright (c) 1993 by Jörn Sierwald           */
  456. /*                                                            */
  457. /*                                                            */
  458. /*------------------------------------------------------------*/
  459.  
  460. int TView::exposedRec1(short x1, short x2, TView* p ) {
  461.   while (1) {
  462. /*20*/
  463.     p=p->next;
  464.     if (p==staticVars2.target) { // alle durch
  465.       return exposedRec2( x1, x2, p->owner );
  466.     };
  467.     if ( !(p->state & sfVisible) || staticVars2.y<p->origin.y) continue; // keine Verdeckung
  468.  
  469.     if ( staticVars2.y<p->origin.y+p->size.y ) {
  470.       // Überdeckung möglich.
  471.       if (x1<p->origin.x) { // fängt links vom Object an.
  472.         if (x2<=p->origin.x) continue; // links vorbei
  473.         if (x2>p->origin.x+p->size.x) {
  474.           if (exposedRec1( x1, p->origin.x, p )) return 1;
  475.           x1=p->origin.x+p->size.x;
  476.         }
  477.         else
  478.           x2=p->origin.x;
  479.       } else {
  480.         if ( x1<p->origin.x+p->size.x ) x1=p->origin.x+p->size.x;
  481.         if ( x1>=x2 ) return 0; // komplett verdeckt.
  482.       };
  483.     };
  484.  
  485.   }; // while
  486.  
  487. }
  488.  
  489. int TView::exposedRec2( short x1, short x2, TView* p ) {
  490.  
  491.   if (!(p->state & sfVisible)) return 0;
  492.   if ( !p->owner || p->owner->buffer ) return 1;
  493.  
  494.   StaticVars2 savedStatics = staticVars2;
  495.  
  496.   staticVars2.y += p->origin.y;
  497.   x1 += p->origin.x;
  498.   x2 += p->origin.x;
  499.   staticVars2.target=p;
  500.  
  501.   TGroup* g=p->owner;
  502.   if (staticVars2.y<g->clip.a.y || staticVars2.y >= g->clip.b.y) {
  503.     staticVars2 = savedStatics;
  504.     return 0;
  505.   };
  506.   if (x1<g->clip.a.x) x1 = g->clip.a.x;
  507.   if (x2>g->clip.b.x) x2 = g->clip.b.x;
  508.   if (x1>=x2) {
  509.     staticVars2 = savedStatics;
  510.     return 0;
  511.   };
  512.  
  513.   int retValue = exposedRec1( x1, x2, g->last );
  514.   staticVars2 = savedStatics;
  515.   return retValue;
  516. }
  517.  
  518. Boolean TView::exposed() {
  519.   if ( !(state & sfExposed) || size.x <= 0 || size.y <= 0 ) return Boolean(0);
  520.   for (short y=0; y<size.y; y++) {
  521.     staticVars2.y=y;
  522.     if (exposedRec2( 0, size.x, this )) return Boolean(1);
  523.   };
  524.   return Boolean(0);
  525. }
  526.  
  527. /*------------------------------------------------------------*/
  528. /* filename -       framelin.cpp                              */
  529. /*                                                            */
  530. /* function(s)                                                */
  531. /*                  TFrame frameLine member function          */
  532. /*------------------------------------------------------------*/
  533.  
  534. /*------------------------------------------------------------*/
  535. /*                                                            */
  536. /*    Turbo Vision -  Version 1.0                             */
  537. /*    Copyright (c) 1991 by Borland International             */
  538. /*    All Rights Reserved.                                    */
  539. /*                                                            */
  540. /*    This file Copyright (c) 1993 by Jörn Sierwald           */
  541. /*                                                            */
  542. /*                                                            */
  543. /*------------------------------------------------------------*/
  544.  
  545. /* Erklärung der Mask:
  546.  
  547.        Bit 0
  548.          |
  549.   Bit 3 - - Bit 1
  550.          |
  551.        Bit 2
  552.  
  553. Wenn z.B. sichergestellt werden soll, dass eine linke obere Ecke im
  554. Muster vorhanden ist, nimmt man :
  555.   mask |= 0x06 .
  556. */
  557.  
  558. void TFrame::frameLine( TDrawBuffer& frameBuf, short y, short n, uchar color )
  559. {
  560.   unsigned char frameMask[maxViewWidth];
  561.   short int i;
  562.   frameMask[0]=initFrame[n];
  563.   for (i=1; i+1<size.x; i++) {
  564.     frameMask[i]=initFrame[n+1];
  565.   };
  566.   frameMask[size.x-1]=initFrame[n+2];
  567.  
  568.   TView* p;
  569.   p=owner->last;
  570.   while (1) {
  571.     p=p->next;
  572.     if (p==this) break;
  573.     if ((p->options & ofFramed) && (p->state & sfVisible)) {
  574.       unsigned char mask1, mask2;
  575.       if (y+1<p->origin.y) continue;
  576.       else if (y+1==p->origin.y) { mask1=0x0A; mask2=0x06;}
  577.       else if (y==p->origin.y+p->size.y) { mask1=0x0A; mask2=0x03;}
  578.       else if (y<p->origin.y+p->size.y) { mask1=0; mask2=0x05;}
  579.       else continue;
  580.       unsigned short xMin=p->origin.x;
  581.       unsigned short xMax=p->origin.x+p->size.x;
  582.       if (xMin<1) xMin=1;
  583.       if (xMax>size.x-1) xMax=size.x-1;
  584.       if (xMax>xMin) {
  585.         if (mask1==0) {
  586.           frameMask[xMin-1] |= mask2;
  587.           frameMask[xMax]   |= mask2;
  588.         } else {
  589.           frameMask[xMin-1] |= mask2;
  590.           frameMask[xMax]   |= (mask2 ^ mask1);
  591.           for (i=xMin; i< xMax; i++) {
  592.             frameMask[i] |= mask1;
  593.           }
  594.         };
  595.       };
  596.     };
  597.   }; // while
  598. //  unsigned char* src=frameMask; /* XXX */
  599.   unsigned short* dest=frameBuf.data;
  600.   i=size.x;
  601.   short int i1=0;
  602.   while (i--) {
  603.     *dest++= ( ((unsigned short)color) << 8 ) + (unsigned char) frameChars[frameMask[i1]];
  604.     i1++;
  605.   } /* endwhile */
  606. };
  607.  
  608. /*------------------------------------------------------------*/
  609. /* filename -       tgrmv.cpp                                 */
  610. /*                                                            */
  611. /* function(s)                                                */
  612. /*                  TGroup removeView member function         */
  613. /*------------------------------------------------------------*/
  614.  
  615. /*------------------------------------------------------------*/
  616. /*                                                            */
  617. /*    Turbo Vision -  Version 1.0                             */
  618. /*    Copyright (c) 1991 by Borland International             */
  619. /*    All Rights Reserved.                                    */
  620. /*                                                            */
  621. /*    This file Copyright (c) 1993 by Jörn Sierwald           */
  622. /*                                                            */
  623. /*                                                            */
  624. /*------------------------------------------------------------*/
  625.  
  626. void TGroup::removeView( TView *p ) {
  627.   if (last) {
  628.     TView *cur=last;
  629.     while (1) {
  630.       if (p==cur->next) {
  631.         cur->next=p->next;
  632.         if (last==p) {
  633.           if (cur->next==p) last=0;
  634.           else last=cur;
  635.           break;
  636.         };
  637.       };
  638.       if (cur->next==last) break;
  639.       cur=cur->next;
  640.     };
  641.   }; // endif
  642. };
  643.  
  644. /*------------------------------------------------------------*/
  645. /* filename -       tvcursor.cpp                              */
  646. /*                                                            */
  647. /* function(s)                                                */
  648. /*                  Tview resetCursor member function         */
  649. /*------------------------------------------------------------*/
  650.  
  651. /*------------------------------------------------------------*/
  652. /*                                                            */
  653. /*    Turbo Vision -  Version 1.0                             */
  654. /*    Copyright (c) 1991 by Borland International             */
  655. /*    All Rights Reserved.                                    */
  656. /*                                                            */
  657. /*    This file Copyright (c) 1993 by Jörn Sierwald           */
  658. /*                                                            */
  659. /*                                                            */
  660. /*------------------------------------------------------------*/
  661.  
  662. void TView::resetCursor() {
  663.   TView *p,*p2;
  664.   TGroup *g;
  665.   TPoint cur;
  666.   if  ((state & (sfVisible | sfCursorVis | sfFocused))
  667.              == (sfVisible | sfCursorVis | sfFocused) )
  668.   {
  669.     p=this;
  670.     cur=cursor;
  671.     while (1) {
  672.       if (!(cur.x>=0 && cur.x<p->size.x
  673.           && cur.y>=0 && cur.y<p->size.y)) {
  674.         break;
  675.       };
  676.       cur.x += p->origin.x;
  677.       cur.y += p->origin.y;
  678.       p2 =p;
  679.       g=p->owner;
  680.       if (g==0) {
  681.         //cursor setzen
  682.  
  683.     /*
  684.      * SS: we should change the cursor size according to the sfCursorIns
  685.      * flag in the state variable:
  686.      *
  687.      * if (state & sfCursorIns) {
  688.          *     setBigCursor
  689.          * } else {
  690.          *     setSmallCursor
  691.          * }
  692.      *
  693.      * Is there a way to do it under linux ?
  694.      */
  695.     TScreen::moveCursor(cur.x, cur.y);
  696.     TScreen::drawCursor(1);
  697.         return;
  698.       };
  699.       if (!(g->state & sfVisible)) break;
  700.       p=g->last;
  701.       {
  702.         label1:
  703.         p=p->next;
  704.         if (p==p2) { // alle durchgesucht.
  705.           p=p->owner;
  706.           continue;
  707.         };
  708.         if ((p->state & sfVisible) 
  709.             && cur.x>=p->origin.x 
  710.             && cur.x<p->size.x+p->origin.x
  711.             && cur.y>=p->origin.y 
  712.             && cur.y<p->size.y+p->origin.y) {
  713.           break; // Cursor wird verdeckt.
  714.         };
  715.         goto label1;
  716.       };
  717.     };
  718.   } 
  719.   // no cursor, please.
  720.   TScreen::drawCursor(0);
  721. }
  722.  
  723. // TTPRVLNS.CPP
  724. // Copyright 1994 by Jörn Sierwald
  725. //
  726. // C++ Version of ttprvlns.asm
  727. // implementation of TTerminal::prevLines(...)
  728. //
  729. // "You don't need assembler to write obfuscated code."
  730.  
  731. ushort TTerminal::prevLines(ushort pos, ushort lines ) {
  732.   if (lines==0) { bufInc(pos); bufInc(pos); return pos; };
  733.   // I don't see the logic in the previous line. But that's what
  734.   // the .asm file says.
  735.  
  736.   if (pos==queBack) return queBack; // Nothing to do
  737.  
  738.   bufDec(pos); // pos might be pointing to a '\n'
  739.  
  740.   if (pos<queBack) {
  741.     while ( !( buffer[pos]=='\n' && !--lines ) && pos-- );
  742.     if (lines) pos=bufSize-1;
  743.   };
  744.  
  745.   if (lines)
  746. /* SS: we should check if there is an available character before read it */
  747. //    while ( !( buffer[pos]=='\n' && !--lines ) && pos---queBack );
  748.     while (pos > queBack && !( buffer[pos]=='\n' && !--lines ))
  749.     {
  750.         pos--;
  751.     }
  752.  
  753.   if (lines)
  754.     return queBack;
  755.   else 
  756.     bufInc(pos);
  757.  
  758.   return pos;
  759. };
  760.  
  761. // TVWRITE.CPP
  762. // Copyright 1993,1994 by Jörn Sierwald
  763. //
  764. // C++ Version of tvwrite.asm
  765. //
  766. // It doesn't look beautiful, but what the heck..
  767.  
  768. extern TPoint shadowSize;
  769. extern uchar shadowAttr;
  770.  
  771. static StaticVars1 staticVars1;
  772.  
  773. void TView::writeViewRec1(short x1, short x2, TView* p, int shadowCounter ) {
  774.   while (1) {
  775. /*20*/
  776.     p=p->next;
  777.     if (p==staticVars2.target) { // alle durch
  778.       // printit!
  779.       if (p->owner->buffer) {
  780.  
  781. /* 
  782.  * SS: now we should remove the mouse pointer from the screen.  This is
  783.  * not necessary because we have a copy of the screen.
  784.  *
  785.  * if (p->owner->buffer == TScreen::screenBuffer) TScreen::drawMouse(0);
  786.  */
  787.  
  788.     if (shadowCounter == 0)
  789.     {
  790.         /* SS: writes a row of data to the screen */
  791.  
  792.         if (p->owner->buffer == TScreen::screenBuffer)
  793.             TScreen::writeRow(
  794.             p->owner->size.x * staticVars2.y + x1,
  795.             staticVars1.buf + (x1 - staticVars2.offset),
  796.             x2 - x1);
  797.         memmove(p->owner->buffer + p->owner->size.x * staticVars2.y +
  798.             x1, staticVars1.buf + x1 - staticVars2.offset,
  799.             (x2 - x1) * 2);
  800.     } else { // paint with shadowAttr
  801.         int l = x2 - x1;
  802.         int dst1 = p->owner->size.x * staticVars2.y + x1;
  803.         ushort *dst = p->owner->buffer + dst1;
  804.         ushort *src= staticVars1.buf + (x1 - staticVars2.offset);
  805.         while (l--)
  806.         {
  807.             ushort d = *src++ & 0xff | (shadowAttr << 8);
  808.  
  809.             /* SS: writes a character on the screen */
  810.  
  811.             if (p->owner->buffer == TScreen::screenBuffer)
  812.                 TScreen::writeRow(dst1++, &d, 1);
  813.             *dst++ = d;
  814.             }
  815.     }
  816.  
  817. /* SS: draws mouse pointer */
  818.  
  819. if (p->owner->buffer == TScreen::screenBuffer) TScreen::drawMouse(1);
  820.       };
  821.       if (p->owner->lockFlag==0) writeViewRec2( x1, x2, p->owner, shadowCounter );
  822.       return ; // (p->owner->lockFlag==0);
  823.     };
  824.     if ( !(p->state & sfVisible) || staticVars2.y<p->origin.y) continue; // keine Verdeckung
  825.  
  826.     if ( staticVars2.y<p->origin.y+p->size.y ) {
  827.       // Überdeckung möglich.
  828.       if (x1<p->origin.x) { // fängt links vom Object an.
  829.         if (x2<=p->origin.x) continue; // links vorbei
  830.         writeViewRec1( x1, p->origin.x, p, shadowCounter );
  831.         x1=p->origin.x;
  832.       };
  833.                    //  if (x1>=p->origin.x) {
  834.       if ( x2<=p->origin.x+p->size.x ) return; // komplett verdeckt.
  835.       if ( x1<p->origin.x+p->size.x ) x1=p->origin.x+p->size.x;
  836.                   // if ( x1>=p->origin.x+p->size.x ) { // könnte höchstens im Schatten liegen
  837.       if ( (p->state & sfShadow) && (staticVars2.y>=p->origin.y+shadowSize.y)) {
  838.         if (x1>=p->origin.x+p->size.x+shadowSize.x) {
  839.           continue; // rechts vorbei
  840.         } else {
  841.           shadowCounter++;
  842.           if (x2<=p->origin.x+p->size.x+shadowSize.x) {
  843.             continue; // alles im Schatten
  844.           } else { // aufteilen Schattenteil, rechts daneben
  845.             writeViewRec1( x1, p->origin.x+p->size.x+shadowSize.x, p, shadowCounter );
  846.             x1=p->origin.x+p->size.x+shadowSize.x;
  847.             shadowCounter--;
  848.             continue;
  849.           };
  850.         };
  851.       } else {
  852.         continue; // rechts vorbei, 1.Zeile hat keinen Schatten
  853.       };
  854.     };
  855.     if ( (p->state & sfShadow) && (staticVars2.y < p->origin.y+p->size.y+shadowSize.y) ) {
  856.       // im y-Schatten von Object?
  857.       if (x1<p->origin.x+shadowSize.x) {
  858.         if (x2<= p->origin.x+shadowSize.x) continue; // links vorbei
  859.         writeViewRec1( x1, p->origin.x+shadowSize.x, p, shadowCounter );
  860.         x1 = p->origin.x+shadowSize.x;
  861.       };
  862.       if (x1>=p->origin.x+shadowSize.x+p->size.x) continue;
  863.       shadowCounter++;
  864.       if (x2<=p->origin.x+p->size.x+shadowSize.x) {
  865.         continue; // alles im Schatten
  866.       } else { // aufteilen Schattenteil, rechts daneben
  867.         writeViewRec1( x1, p->origin.x+p->size.x+shadowSize.x, p, shadowCounter );
  868.         x1=p->origin.x+p->size.x+shadowSize.x;
  869.         shadowCounter--;
  870.         continue;
  871.       };
  872.  
  873.     } else { // zu weit unten
  874.       continue;
  875.     };
  876.  
  877.   }; // while
  878.       
  879. }
  880.  
  881. void TView::writeViewRec2( short x1, short x2, TView* p, int shadowCounter ) {
  882.   if (!(p->state & sfVisible) || p->owner==0 ) return;
  883.  
  884.   StaticVars2 savedStatics = staticVars2;
  885.  
  886.   staticVars2.y += p->origin.y;
  887.   x1 += p->origin.x;
  888.   x2 += p->origin.x;
  889.   staticVars2.offset += p->origin.x;
  890.   staticVars2.target=p;
  891.  
  892.   TGroup* g=p->owner;
  893.   if (staticVars2.y<g->clip.a.y || staticVars2.y >= g->clip.b.y) {
  894.     staticVars2 = savedStatics;
  895.     return;
  896.   };
  897.   if (x1<g->clip.a.x) x1 = g->clip.a.x;
  898.   if (x2>g->clip.b.x) x2 = g->clip.b.x;
  899.   if (x1>=x2) {
  900.     staticVars2 = savedStatics;
  901.     return;
  902.   };
  903.  
  904.   writeViewRec1( x1, x2, g->last, shadowCounter );
  905.   staticVars2 = savedStatics;
  906. }
  907.  
  908. void TView::writeView( short x1, short x2, short y, const void* buf ) {
  909. //  cerr << "Output ";
  910.   if (y<0 || y>=size.y) return;
  911.   if (x1<0) x1=0;
  912.   if (x2>size.x) x2=size.x;
  913.   if (x1>=x2) return;
  914.   staticVars2.offset=x1;
  915.   staticVars1.buf= (ushort*) buf;
  916.   staticVars2.y=y;
  917.   writeViewRec2( x1, x2, this, 0 );
  918.     doRefresh(this);
  919. }
  920.  
  921. void TView::writeBuf( short x, short y, short w, short h, const void *buf) {
  922.     lockRefresh++;        /* stop the refresh */
  923.   for (int i=0; i<h; i++) {
  924.     writeView( x,x+w,y+i,(ushort*) buf + w*i );
  925.   } /* endfor */
  926.     lockRefresh--;        /* allow the refresh */
  927.     doRefresh(this);
  928. }
  929.  
  930. void TView::writeChar( short x, short y, char c, uchar color, short count) {
  931.   ushort b[maxViewWidth];
  932.   ushort myChar= ( ((ushort)mapColor(color))<<8 ) + (unsigned char) c;
  933.   short count2=count;
  934.   if (x<0) x=0;
  935.   if (x+count>maxViewWidth) return;
  936.   ushort* p = b;
  937.   while ( count-- ) *p++ = myChar;
  938.   writeView( x, x+count2, y, b);
  939. }
  940.  
  941. void TView::writeLine( short x, short y, short w, short h, const void *buf) {
  942.   if (h==0) return;
  943.     lockRefresh++;        /* stop the refresh */
  944.   for (int i=0; i<h; i++) {
  945.     writeView ( x, x+w, y+i, buf );
  946.   };
  947.     lockRefresh--;        /* allow the refresh */
  948.     doRefresh(this);
  949. }
  950.  
  951. void TView::writeStr( short x, short y, const char *str, uchar color) {
  952.   if (!str) return;
  953.   ushort l= strlen(str);
  954.   if (l==0) return;
  955.   if (l>maxViewWidth) l=maxViewWidth;
  956.   ushort l2=l;
  957.   ushort myColor=( (ushort)mapColor(color) ) << 8;
  958.   ushort b[maxViewWidth];
  959.   ushort* p = b;
  960.   while ( *p++ = myColor+(*(const unsigned char*)str++), --l );
  961.   writeView ( x, x+l2, y, b );
  962. }
  963.