home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / panix / k95source.zip / ckoco2.c < prev    next >
C/C++ Source or Header  |  2006-07-05  |  195KB  |  5,529 lines

  1. /* C K O C O 2  --  Kermit connect command for OS/2 systems */
  2.  
  3. /*
  4.   Authors: Frank da Cruz (fdc@columbia.edu),
  5.              Columbia University Academic Information Systems, New York City.
  6.            Jeffrey E Altman (jaltman@secure-endpoints.com)
  7.              Secure Endpoints Inc., New York City
  8.  
  9.   Copyright (C) 1985, 2004, Trustees of Columbia University in the City of New
  10.   York.  All rights reserved.
  11. */
  12.  
  13. /*
  14.  * =============================#includes=====================================
  15.  */
  16.  
  17. #include "ckcdeb.h"             /* Typedefs, debug formats, etc */
  18. #include "ckcker.h"             /* Kermit definitions */
  19. #ifdef IKSD
  20. #include "ckctel.h"
  21. #endif /* IKSD */
  22. #include "ckcasc.h"             /* ASCII character symbols */
  23. #include "ckuusr.h"             /* For terminal type definitions, etc. */
  24. #ifndef NOLOCAL
  25. #include "ckcxla.h"             /* Character set translation */
  26. #include "ckopcf.h"             /* PC Fonts resource definitions */
  27.  
  28. #ifdef KUI
  29. #include "kui/ikui.h"
  30. #endif /* KUI */
  31.  
  32. #include <ctype.h>              /* Character types */
  33. #include <io.h>                 /* File io function declarations */
  34. #include <process.h>            /* Process-control function declarations */
  35. #include <stdlib.h>             /* Standard library declarations */
  36. #include <sys/types.h>
  37. #include <sys/stat.h>
  38. #include <stdio.h>
  39. #include <stdarg.h>
  40. #include <string.h>
  41. #include <assert.h>
  42. #include <signal.h>
  43.  
  44. #ifdef NT
  45. extern int OSVer;
  46. #else /* NT */
  47. #ifdef OS2MOUSE
  48. #define INCL_MOU
  49. #endif /* OS2MOUSE */
  50.  
  51. #define INCL_NOPM
  52. #define INCL_VIO
  53. #define INCL_ERRORS
  54. #define INCL_DOSFILEMGR
  55. #define INCL_DOSMISC
  56. #define INCL_DOSPROCESS
  57. #define INCL_DOSSEMAPHORES
  58. #define INCL_DOSDEVIOCTL
  59. #define INCL_DOSMODULEMGR
  60. #define INCL_DOSRESOURCES
  61. #define INCL_WINCLIPBOARD
  62. #define INCL_DOSDATETIME
  63. #include <os2.h>
  64. #undef COMMENT                          /* COMMENT is defined in os2.h */
  65. #endif /* NT */
  66.  
  67. #include "ckcuni.h"
  68. #include "ckocon.h"                     /* defs common to console routines */
  69. #include "ckokey.h"
  70.  
  71. videobuffer vscrn[VNUM]  = {{0,0,0,0,0,0,{0,0},0,-1,-1,-1,-1,{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},0,0},
  72.                             {0,0,0,0,0,0,{0,0},0,-1,-1,-1,-1,{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},0,0},
  73.                             {0,0,0,0,0,0,{0,0},0,-1,-1,-1,-1,{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},0,0},
  74.                             {0,0,0,0,0,0,{0,0},0,-1,-1,-1,-1,{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},0,0}};
  75. extern int tt_update, tt_updmode, tt_rows[], tt_cols[], tt_font, tt_roll[],
  76.            tt_cursor;
  77. int tt_attr_bug = 0;
  78. int tt_diff_upd = 1;
  79. int tt_url_hilite = 1;
  80. #ifdef KUI
  81. int tt_url_hilite_attr = VT_CHAR_ATTR_BOLD | VT_CHAR_ATTR_UNDERLINE;
  82. #else /* KUI */
  83. int tt_url_hilite_attr = VT_CHAR_ATTR_BOLD;
  84. #endif /* KUI */
  85. extern int updmode ;
  86. extern int priority ;
  87. extern int tt_modechg;
  88. extern unsigned char defaultattribute ;
  89. extern unsigned char colornormal;
  90. extern unsigned char reverseattribute ;
  91. extern unsigned char italicattribute;
  92. extern unsigned char graphicattribute ;
  93. extern unsigned char underlineattribute ;
  94. extern unsigned char borderattribute ;
  95.  
  96. extern vtattrib attrib, cmdattrib;
  97. extern bool cursoron[], cursorena[],scrollflag[], scrollstatus[], flipscrnflag[] ;
  98. extern TID tidTermScrnUpd ;
  99.  
  100. extern
  101. #ifdef NT
  102. HANDLE
  103. #else
  104. HVIO
  105. #endif
  106. VioHandle;
  107.  
  108. #ifdef OS2MOUSE
  109. extern int tt_mouse ;
  110. #endif /* OS2MOUSE */
  111. #ifdef IKSD
  112. extern int inserver;
  113. #endif /* IKSD */
  114.  
  115. extern int tt_cursor;                   /* Cursor type */
  116. extern int tt_status[];                 /* Status line displayed ? */
  117.  
  118. extern unsigned char     colorstatus     ;
  119. extern unsigned char     colorselect ;
  120. extern unsigned char     colorcmd;
  121.  
  122. extern enum markmodes markmodeflag[] ;
  123.  
  124. #ifdef PCFONTS
  125. HMODULE hPCFonts = 0 ;
  126. #define FONTBUFSIZE  16384
  127. VIOFONTINFO  SavedFontInfo ;
  128. BYTE    SavedFontBuffer[FONTBUFSIZE];
  129. BOOL    FontSaved = 0 ;
  130. #endif /* PCFONTS */
  131.  
  132. BYTE vmode = VCMD ;
  133. extern int decsasd ;
  134. int pwidth, pheight;            /* Physical screen width, height */
  135.  
  136. /*---------------------------------------------------------------------------*/
  137. /* ReadCellStr                                                               */
  138. /*---------------------------------------------------------------------------*/
  139. USHORT
  140. ReadCellStr( viocell * CellStr, PUSHORT Length, USHORT Row, USHORT Column )
  141. {
  142. #ifdef NT
  143.     static LPWSTR wchars = NULL ;
  144.     static LPTSTR tchars = NULL ;
  145.     static LPWORD attrs = NULL ;
  146.     static int charlen = 0 ;
  147.     static int attrlen = 0 ;
  148.     COORD coord ;
  149.     DWORD read ;
  150.     int len = *Length ;
  151.     USHORT rc = 0;
  152.     int i ;
  153.  
  154.     coord.X=Column ;
  155.     coord.Y=Row ;
  156.  
  157.     if ( len > attrlen )
  158.     {
  159.         if ( attrs )
  160.             free( attrs ) ;
  161.         attrs = malloc( len * sizeof(WORD) ) ;
  162.         if ( attrs )
  163.         {
  164.             attrlen = len ;
  165.         }
  166.         else
  167.         {
  168.             attrlen = 0 ;
  169.             return 1 ;
  170.         }
  171.     }
  172.     rc = ReadConsoleOutputAttribute( VioHandle, attrs, len, coord, &read ) ;
  173.     if ( !rc ) {
  174.         DWORD error = GetLastError();
  175.         if ( error == ERROR_INVALID_HANDLE ) {
  176.             debug(F101,"ReadCellStr VioHandle","",VioHandle);
  177.             VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  178.             debug(F101,"ReadCellStr GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  179.         }
  180.         return 3;
  181.     }
  182.  
  183.     if ( isunicode() ) {
  184.         if ( !wchars || len > charlen )
  185.         {
  186.             if ( wchars )
  187.                 free( wchars ) ;
  188.             wchars = malloc( len * sizeof(WCHAR) ) ;
  189.             if ( wchars )
  190.             {
  191.                 charlen = len ;
  192.             }
  193.             else
  194.             {
  195.                 charlen = 0 ;
  196.                 return 1 ;
  197.             }
  198.         }
  199.  
  200.         rc = ReadConsoleOutputCharacterW( VioHandle, wchars, len, coord, &read ) ;
  201.         if ( !rc ) {
  202.             DWORD error = GetLastError();
  203.         if ( error == ERROR_INVALID_HANDLE ) {
  204.             debug(F101,"ReadCellStr VioHandle","",VioHandle);
  205.             VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  206.             debug(F101,"ReadCellStr GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  207.         }
  208.             return 3;
  209.         }
  210.         if ( read != len )
  211.         {
  212.             rc = 2 ;
  213.         }
  214.         else
  215.         {
  216.             for ( i=0; i<len ; i++ )
  217.             {
  218.                 ((viocell *)CellStr)[i].c = wchars[i] ;
  219.                 ((viocell *)CellStr)[i].a = attrs[i] ;
  220.             }
  221.         }
  222.     }
  223.     else {
  224.         if ( !tchars || len > charlen )
  225.         {
  226.             if ( tchars )
  227.                 free( tchars ) ;
  228.             tchars = malloc( len * sizeof(TCHAR) ) ;
  229.             if ( tchars  )
  230.             {
  231.                 charlen = len ;
  232.             }
  233.             else
  234.             {
  235.                 charlen = 0 ;
  236.                 return 1 ;
  237.             }
  238.         }
  239.         rc = ReadConsoleOutputCharacter( VioHandle, tchars, len, coord, &read ) ;
  240.         if ( !rc ) {
  241.             DWORD error = GetLastError();
  242.             if ( error == ERROR_INVALID_HANDLE ) {
  243.                 debug(F101,"ReadCellStr VioHandle","",VioHandle);
  244.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  245.                 debug(F101,"ReadCellStr GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  246.             }
  247.             return 3;
  248.         }
  249.         if ( read != len )
  250.         {
  251.             rc = 2 ;
  252.         }
  253.         else
  254.         {
  255.             for ( i=0; i<len ; i++ )
  256.             {
  257.                 CellStr[i].c = tchars[i] ;
  258.                 CellStr[i].a = attrs[i] ;
  259.             }
  260.         }
  261.     }
  262.  
  263.     return rc ;
  264.  
  265. #else /* NT */
  266.     *Length *= sizeof(viocell) ;
  267.     return VioReadCellStr( (PCH) CellStr, Length, Row, Column, VioHandle ) ;
  268. #endif /* NT */
  269. }
  270.  
  271. /*---------------------------------------------------------------------------*/
  272. /* WrtCellStr                                                                */
  273. /*---------------------------------------------------------------------------*/
  274. #ifdef NT
  275. USHORT
  276. OldWin32WrtCellStr( viocell * CellStr, USHORT Length, USHORT Row, USHORT Column )
  277. {
  278.     static LPWSTR wchars = NULL;
  279.     static LPTSTR tchars = NULL ;
  280.     static LPWORD attrs = NULL ;
  281.     static int charlen = 0 ;
  282.     static int attrlen = 0 ;
  283.     COORD coord ;
  284.     DWORD written ;
  285.     int len = Length ;
  286.     USHORT rc = 0;
  287.     int i ;
  288.  
  289.     coord.X=Column ;
  290.     coord.Y=Row ;
  291.  
  292.     if ( len > attrlen )
  293.     {
  294.         if ( attrs )
  295.             free( attrs ) ;
  296.         attrs = malloc( len * sizeof(WORD) ) ;
  297.         if ( attrs )
  298.         {
  299.             attrlen = len ;
  300.         }
  301.         else
  302.         {
  303.             attrlen = 0 ;
  304.             return 1 ;
  305.         }
  306.     }
  307.  
  308.     if ( isunicode() ) {
  309.         if ( !wchars || len > charlen )
  310.         {
  311.             if ( wchars )
  312.                 free( wchars ) ;
  313.             wchars = malloc( len * sizeof(WCHAR) ) ;
  314.             if ( wchars )
  315.             {
  316.                 charlen = len ;
  317.             }
  318.             else
  319.             {
  320.                 charlen = 0 ;
  321.                 return 1 ;
  322.             }
  323.         }
  324.  
  325.         for ( i=0; i<len ; i++ )
  326.         {
  327.             wchars[i] = CellStr[i].c ;
  328.             attrs[i] = CellStr[i].a ;
  329.         }
  330.         rc = WriteConsoleOutputCharacterW( VioHandle, wchars, len, coord, &written ) ;
  331.         if ( !rc ) {
  332.             DWORD error = GetLastError();
  333.             if ( error == ERROR_INVALID_HANDLE ) {
  334.                 debug(F101,"OldWin32WrtCellStr VioHandle","",VioHandle);
  335.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  336.                 debug(F101,"OldWin32WrtCellStr GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  337.             }
  338.             return 3;
  339.         }
  340.     }
  341.     else {
  342.         if ( !tchars || len > charlen )
  343.         {
  344.             if ( tchars )
  345.                 free( tchars ) ;
  346.             tchars = malloc( len * sizeof(TCHAR) ) ;
  347.             if ( tchars )
  348.             {
  349.                 charlen = len ;
  350.             }
  351.             else
  352.             {
  353.                 charlen = 0 ;
  354.                 return 1 ;
  355.             }
  356.         }
  357.         for ( i=0; i<len ; i++ )
  358.         {
  359.             tchars[i] = ((viocell *)CellStr)[i].c ;
  360.             attrs[i] = ((viocell *)CellStr)[i].a ;
  361.         }
  362.         rc = WriteConsoleOutputCharacter( VioHandle, tchars, len, coord, &written ) ;
  363.         if ( !rc ) {
  364.             DWORD error = GetLastError();
  365.             if ( error == ERROR_INVALID_HANDLE ) {
  366.                 debug(F101,"OldWin32WrtCellStr VioHandle","",VioHandle);
  367.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  368.                 debug(F101,"OldWin32WrtCellStr GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  369.             }
  370.             return 3;
  371.         }
  372.     }
  373.  
  374.     /* This is to prevent a fatal bug in Win 95 Gold */
  375.     if ( !isWin95() ||
  376.          !tt_attr_bug ||
  377.          ( pwidth == 80 && ( pheight == 25 || pheight == 43 || pheight == 50 ) )
  378.          ) {
  379.         rc = WriteConsoleOutputAttribute( VioHandle, attrs, len, coord, &written ) ;
  380.         if ( !rc ) {
  381.             DWORD error = GetLastError();
  382.             if ( error == ERROR_INVALID_HANDLE ) {
  383.                 debug(F101,"OldWin32WrtCellStr VioHandle","",VioHandle);
  384.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  385.                 debug(F101,"OldWin32WrtCellStr GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  386.             }
  387.             return 3;
  388.         }
  389.     }
  390.     if ( written != len )
  391.     {
  392.         rc = 2 ;
  393.     }
  394.     return(0);
  395. }
  396. #endif /* NT */
  397.  
  398. USHORT
  399. WrtCellStr( viocell * CellStr, USHORT Length, USHORT Row, USHORT Column )
  400. {
  401. #ifdef NT
  402.     static CHAR_INFO *lpBuffer = NULL;  // pointer to buffer with data to write
  403.     static COORD dwBufferSize  = {0,0}; // column-row size of source buffer
  404.     COORD dwBufferCoord = {0,0};        // upper-left cell to write from
  405.     SMALL_RECT WriteRegion = {0,0,0,0}; // pointer to rectangle to write to
  406.     static int buflen = 0 ;
  407.  
  408.     int len = Length * sizeof(CHAR_INFO) ;
  409.     USHORT rc = 0;
  410.     int i ;
  411.  
  412.     if ( Row == 0 && Column == 0 && Length == pwidth * pheight) {
  413.         dwBufferSize.X=pwidth ;
  414.         dwBufferSize.Y=pheight ;
  415.         WriteRegion.Left=0;
  416.         WriteRegion.Top=0;
  417.         WriteRegion.Right=pwidth-1;
  418.         WriteRegion.Bottom=pheight-1;
  419.     }
  420.     else {
  421.         return OldWin32WrtCellStr( CellStr, Length, Row, Column );
  422.     }
  423.  
  424.     if ( len > buflen )
  425.     {
  426.         if ( lpBuffer )
  427.             free( lpBuffer ) ;
  428.         lpBuffer = malloc( len ) ;
  429.         if ( lpBuffer )
  430.         {
  431.             buflen = len ;
  432.         }
  433.         else
  434.         {
  435.             buflen = 0 ;
  436.             return 1 ;
  437.         }
  438.     }
  439.  
  440.     if ( isunicode() ) {
  441.         for ( i=0; i<Length ; i++ )
  442.         {
  443.             lpBuffer[i].Char.UnicodeChar = CellStr[i].c ;
  444.             lpBuffer[i].Attributes       = CellStr[i].a ;
  445.         }
  446.         rc = WriteConsoleOutputW( VioHandle, lpBuffer, dwBufferSize, dwBufferCoord,
  447.                              &WriteRegion ) ;
  448.         if ( !rc ) {
  449.             DWORD error = GetLastError();
  450.             if ( error == ERROR_INVALID_HANDLE ) {
  451.                 debug(F101,"WrtCellStr VioHandle","",VioHandle);
  452.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  453.                 debug(F101,"WrtCellStr GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  454.             }
  455.             return 3;
  456.         }
  457.     }
  458.     else {
  459.         for ( i=0; i<Length ; i++ )
  460.         {
  461.             lpBuffer[i].Char.AsciiChar = CellStr[i].c ;
  462.             lpBuffer[i].Attributes       = CellStr[i].a ;
  463.         }
  464.         rc = WriteConsoleOutput( VioHandle, lpBuffer, dwBufferSize, dwBufferCoord,
  465.                             &WriteRegion ) ;
  466.         if ( !rc ) {
  467.             DWORD error = GetLastError();
  468.             if ( error == ERROR_INVALID_HANDLE ) {
  469.                 debug(F101,"WrtCellStr VioHandle","",VioHandle);
  470.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  471.                 debug(F101,"WrtCellStr GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  472.             }
  473.             return 3;
  474.         }
  475.     }
  476.  
  477.     if ( WriteRegion.Top + WriteRegion.Left + WriteRegion.Right + WriteRegion.Bottom
  478.          != pheight + pwidth - 2 )
  479.     {
  480.         rc = 2 ;
  481.     }
  482.    return(0);
  483. #else /* NT */
  484.    return VioWrtCellStr( (PCH) CellStr, Length*sizeof(viocell), Row, Column, VioHandle ) ;
  485. #endif /* NT */
  486. }
  487.  
  488.  
  489.  
  490.  
  491. /* WrtCellStrDiff
  492.  *   only write the changes to the screen.
  493.  */
  494.  
  495. static viocell * last_vio = NULL;
  496. static int       last_len = 0, last_violen = 0;
  497. static USHORT    last_col = -1, last_row = -1;
  498.  
  499. void
  500. VscrnForceFullUpdate(void)
  501. {
  502.     last_len = 0;
  503.     os2settitle(NULL,1);                /* Force a Title update */
  504. }
  505.  
  506. USHORT
  507. WrtCellStrDiff( viocell * CellStr, USHORT Length, USHORT Row, USHORT Column,
  508.                 USHORT Height, USHORT Width )
  509. {
  510.     USHORT rc = 0;
  511.  
  512.     /* If we do not have anything to compare it to, or there was a  */
  513.     /* fundamental change write the entire string.                   */
  514.     if ( last_vio == NULL ||
  515.          last_len != Length ||
  516.          last_row != Row ||
  517.          last_col != Column )
  518.     {
  519.         rc = WrtCellStr(CellStr,Length,Row,Column);
  520.         if ( rc ) {                     /* failure */
  521.             last_len = 0;
  522.             last_col = -1;
  523.             last_row = -1;
  524.         } else {
  525.             if ( last_vio && last_violen < Length ) {
  526.                 free(last_vio);
  527.                 last_violen = 0;
  528.                 last_vio = NULL;
  529.             }
  530.             if ( last_vio == NULL ) {
  531.                 last_vio = (viocell *) malloc(Length*sizeof(viocell));
  532.                 if ( last_vio == NULL ) {
  533.                     last_len = 0;
  534.                     return rc;
  535.                 }
  536.             }
  537.             memcpy(last_vio,CellStr,Length*sizeof(viocell));
  538.             last_len = Length;
  539.             last_row = Row;
  540.             last_col = Column;
  541.         }
  542.     } else {
  543.         /* Now we start looking for changes */
  544.         viocell * vpo = last_vio;
  545.         viocell * vpn = CellStr, * vpnc=CellStr;
  546.         int count = 0, ccount=0;
  547.  
  548.         while ( count < Length ) {
  549.             if ( vpo->c == vpn->c &&
  550.                  vpo->a == vpn->a )
  551.             {
  552.                 count++;
  553.                 vpo++;
  554.                 vpn++;
  555.                 continue;
  556.             }
  557.  
  558.             /* we have found a change */
  559.             vpnc = vpn;
  560.             ccount = 1;
  561.             count++;;
  562.             vpo++;
  563.             vpn++;
  564.  
  565.             /* Find the length of the change */
  566.             while ( count < Length &&
  567.                 (vpn->c != vpo->c ||
  568.                     vpn->a != vpo->a) ) {
  569.                 count++;
  570.                 ccount++;
  571.                 vpo++;
  572.                 vpn++;
  573.  
  574.             }
  575.  
  576.             /* Write it */
  577.             WrtCellStr(vpnc,ccount,
  578.                         (Row*Width+Column+count-ccount)/Width,
  579.                         (Row*Width+Column+count-ccount)%Width);
  580.  
  581.             count++;
  582.             vpo++;
  583.             vpn++;
  584.  
  585.         }
  586.         memcpy(last_vio,CellStr,Length*sizeof(viocell));
  587.     }
  588.     return rc ;
  589.  
  590. }
  591.  
  592. /*---------------------------------------------------------------------------*/
  593. /* WrtNCell                                                                  */
  594. /*---------------------------------------------------------------------------*/
  595. USHORT
  596. WrtNCell( viocell Cell, USHORT Times, USHORT Row, USHORT Column )
  597. {
  598. #ifdef NT
  599.     static LPWSTR wchars = NULL;
  600.     static LPTSTR tchars = NULL ;
  601.     static LPWORD attrs = NULL ;
  602.     static int charlen = 0 ;
  603.     static int attrlen = 0 ;
  604.     COORD coord ;
  605.     DWORD written ;
  606.     USHORT rc = 0;
  607.     int i ;
  608.  
  609.     coord.X=Column ;
  610.     coord.Y=Row ;
  611.  
  612.     if ( Times > attrlen )
  613.     {
  614.         if ( attrs )
  615.             free( attrs ) ;
  616.         attrs = malloc( Times * sizeof(WORD) ) ;
  617.         if ( attrs )
  618.         {
  619.             attrlen = Times ;
  620.         }
  621.         else
  622.         {
  623.             attrlen = 0 ;
  624.             return 1 ;
  625.         }
  626.     }
  627.  
  628.     if ( isunicode() ) {
  629.         if ( !wchars || Times > charlen )
  630.         {
  631.             if ( wchars )
  632.                 free( wchars ) ;
  633.             wchars = malloc( Times * sizeof(WCHAR) ) ;
  634.             if ( wchars )
  635.             {
  636.                 charlen = Times ;
  637.             }
  638.             else
  639.             {
  640.                 charlen = 0 ;
  641.                 return 1 ;
  642.             }
  643.         }
  644.  
  645.         for ( i=0; i<Times ; i++ )
  646.         {
  647.             wchars[i] = Cell.c ;
  648.             attrs[i] = Cell.a ;
  649.         }
  650.         rc = WriteConsoleOutputCharacterW( VioHandle, wchars, Times, coord, &written ) ;
  651.         if ( !rc ) {
  652.             DWORD error = GetLastError();
  653.             if ( error == ERROR_INVALID_HANDLE ) {
  654.                 debug(F101,"WrtCellStr VioHandle","",VioHandle);
  655.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  656.                 debug(F101,"WrtCellStr GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  657.             }
  658.             return 3;
  659.         }
  660.     }
  661.     else {
  662.         if ( tchars || Times > charlen )
  663.         {
  664.             if ( tchars )
  665.                 free( tchars ) ;
  666.             tchars = malloc( Times * sizeof(TCHAR) ) ;
  667.             if ( tchars )
  668.             {
  669.                 charlen = Times ;
  670.             }
  671.             else
  672.             {
  673.                 charlen = 0 ;
  674.                 return 1 ;
  675.             }
  676.         }
  677.  
  678.         for ( i=0; i<Times ; i++ )
  679.         {
  680.             tchars[i] = Cell.c ;
  681.             attrs[i] = Cell.a ;
  682.         }
  683.         rc = WriteConsoleOutputCharacter( VioHandle, tchars, Times, coord, &written ) ;
  684.         if ( !rc ) {
  685.             DWORD error = GetLastError();
  686.             if ( error == ERROR_INVALID_HANDLE ) {
  687.                 debug(F101,"WrtNCell VioHandle","",VioHandle);
  688.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  689.                 debug(F101,"WrtNCell GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  690.             }
  691.             return 3;
  692.         }
  693.     }
  694.  
  695.     /* This is to prevent a fatal bug in Win 95 Gold */
  696.     if ( !isWin95() ||
  697.          !tt_attr_bug ||
  698.          tt_modechg != TVC_ENA ||
  699.          ( pwidth  == 80 && ( pheight == 25 || pheight == 43 || pheight == 50 ) )
  700.          ) {
  701.         rc = WriteConsoleOutputAttribute( VioHandle, attrs, Times, coord, &written ) ;
  702.         if ( !rc ) {
  703.             DWORD error = GetLastError();
  704.             if ( error == ERROR_INVALID_HANDLE ) {
  705.                 debug(F101,"WrtNCell VioHandle","",VioHandle);
  706.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  707.                 debug(F101,"WrtNCell GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  708.             }
  709.             return 3;
  710.         }
  711.     }
  712.     if ( written != Times )
  713.     {
  714.         rc = 2 ;
  715.     }
  716.     return rc ;
  717.  
  718. #else /* NT */
  719.    return VioWrtNCell( (PCH) &Cell, Times, Row, Column, VioHandle ) ;
  720. #endif /* NT */
  721. }
  722.  
  723. /*---------------------------------------------------------------------------*/
  724. /* WrtCharStrAtt                                                             */
  725. /*---------------------------------------------------------------------------*/
  726. USHORT
  727. WrtCharStrAtt( PCH CharStr, USHORT Length, USHORT Row, USHORT Column,
  728.                       PBYTE Attr )
  729. {
  730. #ifdef NT
  731.     static LPWSTR wchars = NULL;
  732.     static LPTSTR tchars = NULL ;
  733.     static LPWORD attrs = NULL ;
  734.     static int charlen = 0 ;
  735.     static int attrlen = 0 ;
  736.     COORD coord ;
  737.     DWORD written ;
  738.     USHORT rc = 0;
  739.     int i ;
  740.  
  741.     coord.X=Column ;
  742.     coord.Y=Row ;
  743.  
  744.     if ( Length > attrlen )
  745.     {
  746.         if ( attrs )
  747.             free( attrs ) ;
  748.         attrs = malloc( Length * sizeof(WORD) ) ;
  749.         if ( attrs )
  750.         {
  751.             attrlen = Length ;
  752.         }
  753.         else
  754.         {
  755.             attrlen = 0 ;
  756.             return 1 ;
  757.         }
  758.     }
  759.  
  760.     if ( isunicode() ) {
  761.         if ( !wchars || Length > charlen )
  762.         {
  763.             if ( wchars )
  764.                 free( wchars ) ;
  765.             wchars = malloc( Length * sizeof(WCHAR) ) ;
  766.             if ( wchars )
  767.             {
  768.                 charlen = Length ;
  769.             }
  770.             else
  771.             {
  772.                 charlen = 0 ;
  773.                 return 1 ;
  774.             }
  775.         }
  776.  
  777.         for ( i=0; i<Length ; i++ )
  778.         {
  779.             wchars[i] = CharStr[i] ;
  780.             attrs[i] = *Attr ;
  781.         }
  782.         rc = WriteConsoleOutputCharacterW( VioHandle, wchars, Length, coord, &written ) ;
  783.         if ( !rc ) {
  784.             DWORD error = GetLastError();
  785.             if ( error == ERROR_INVALID_HANDLE ) {
  786.                 debug(F101,"WrtCharStrAttr VioHandle","",VioHandle);
  787.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  788.                 debug(F101,"WrtCharStrAttr GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  789.             }
  790.             return 3;
  791.         }
  792.     }
  793.     else {
  794.         if ( !tchars || Length > charlen )
  795.         {
  796.             if ( tchars )
  797.                 free( tchars ) ;
  798.             tchars = malloc( Length * sizeof(TCHAR) ) ;
  799.             if ( tchars )
  800.             {
  801.                 charlen = Length ;
  802.             }
  803.             else
  804.             {
  805.                 charlen = 0 ;
  806.                 return 1 ;
  807.             }
  808.         }
  809.  
  810.         for ( i=0; i<Length ; i++ )
  811.         {
  812.             tchars[i] = CharStr[i] ;
  813.             attrs[i] = *Attr ;
  814.         }
  815.         rc = WriteConsoleOutputCharacter( VioHandle, tchars, Length, coord, &written ) ;
  816.         if ( !rc ) {
  817.             DWORD error = GetLastError();
  818.             if ( error == ERROR_INVALID_HANDLE ) {
  819.                 debug(F101,"WrtCharStrAttr VioHandle","",VioHandle);
  820.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  821.                 debug(F101,"WrtCharStrAttr GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  822.             }
  823.             return 3;
  824.         }
  825.     }
  826.  
  827.     /* This is to prevent a fatal bug in Win 95 Gold */
  828.     if ( !isWin95() ||
  829.         !tt_attr_bug ||
  830.          ( pwidth == 80 && ( pheight == 25 || pheight == 43 || pheight == 50 ) )
  831.          ) {
  832.         rc = WriteConsoleOutputAttribute( VioHandle, attrs, Length, coord, &written ) ;
  833.         if ( !rc ) {
  834.             DWORD error = GetLastError();
  835.             if ( error == ERROR_INVALID_HANDLE ) {
  836.                 debug(F101,"WrtCharStrAttr VioHandle","",VioHandle);
  837.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  838.                 debug(F101,"WrtCharStrAttr GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  839.             }
  840.             return 3;
  841.         }
  842.     }
  843.  
  844.     if ( written != Length )
  845.     {
  846.         rc = 2 ;
  847.     }
  848.     return rc ;
  849.  
  850. #else /* NT */
  851.    return VioWrtCharStrAtt( CharStr, Length, Row, Column, Attr, VioHandle ) ;
  852. #endif /* NT */
  853. }
  854.  
  855. #ifndef KUI
  856. /*---------------------------------------------------------------------------*/
  857. /* GetMode                                                                   */
  858. /*   Determines:                                                             */
  859. /*     VGA video mode */
  860. /*     number of colors */
  861. /*     number of columns */
  862. /*     number of rows */
  863. /*     horizontal and vertical resolution */
  864. /*---------------------------------------------------------------------------*/
  865. USHORT
  866. GetMode( PCK_VIDEOMODEINFO ModeData )
  867. {
  868.     USHORT rc ;
  869. #ifdef NT
  870.     CONSOLE_SCREEN_BUFFER_INFO mi ;
  871.  
  872.     rc = 1 ;
  873.     memset(ModeData,0,sizeof(CK_VIDEOMODEINFO));
  874.     if ( GetConsoleScreenBufferInfo( VioHandle, &mi ) )
  875.     {
  876.         rc = 0 ;
  877.  
  878.         ModeData->col      = mi.srWindow.Right-mi.srWindow.Left+1;
  879.         ModeData->row      = mi.srWindow.Bottom-mi.srWindow.Top+1;
  880.         ModeData->sbcol    = mi.dwSize.X ;
  881.         ModeData->sbrow    = mi.dwSize.Y ;
  882.         ModeData->color    = mi.wAttributes ;
  883.     }
  884.     else {
  885.         DWORD error = GetLastError();
  886.         if ( error == ERROR_INVALID_HANDLE ) {
  887.             debug(F101,"GetMode VioHandle","",VioHandle);
  888.             VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  889.             debug(F101,"GetMode GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  890.         }
  891.         return 3;
  892.     }
  893.     if (!rc) {
  894.         pwidth = ModeData->sbcol;
  895.         pheight = ModeData->sbrow;
  896.     }
  897. #else /* just OS/2 */
  898.     VIOMODEINFO mi ;
  899.     memset(ModeData,0,sizeof(CK_VIDEOMODEINFO));
  900.     mi.cb = 12 ;
  901.  
  902.     if ((rc = VioGetMode( &mi, VioHandle )) == 0)
  903.     {
  904.         ModeData->fbType = mi.fbType ;
  905.         ModeData->color  = mi.color ;
  906.         ModeData->col    = mi.col ;
  907.         ModeData->row    = mi.row ;
  908.         ModeData->hres   = mi.hres ;
  909.         ModeData->vres   = mi.vres ;
  910.         ModeData->wcol   = 0 ;
  911.         ModeData->wrow   = 0 ;
  912.     }
  913.     if (!rc) {
  914.         pwidth = ModeData->col;
  915.         pheight = ModeData->row;
  916.     }
  917. #endif /* NT */
  918.     return rc ;
  919. }
  920.  
  921. /*---------------------------------------------------------------------------*/
  922. /* SetMode                                                                   */
  923. /*---------------------------------------------------------------------------*/
  924. USHORT
  925. SetMode( PCK_VIDEOMODEINFO ModeData )
  926. {
  927.     USHORT rc=0 ;
  928. #ifdef NT
  929.     COORD wsize, sbsize;
  930.     SMALL_RECT rect;
  931.     RECT  rConsole, rClient ;
  932.     CONSOLE_SCREEN_BUFFER_INFO csbi ;
  933.     extern HWND hwndConsole;
  934.     extern int k95stdout;
  935.     int    fixedX=0, fixedY=0, pixelsX=0, pixelsY=0, desiredX=0, desiredY=0;
  936.     int    setwin=0;
  937.  
  938.     if ( k95stdout )                    /* do nothing if stdout */
  939.         return(0);
  940.  
  941. #ifdef COMMENT
  942.     BOOL MoveWindow( HWND hWnd,     // handle of window
  943.                      int X,         // horizontal position
  944.                      int Y,         // vertical position
  945.                      int nWidth,    // width
  946.                      int nHeight,   // height
  947.                      BOOL bRepaint  // repaint flag
  948.                      );
  949. #endif /* COMMENT */
  950.  
  951.     if ( ModeData->col <= 0 || ModeData->row <= 0 )
  952.         return -1 ;
  953.  
  954.     rc = RequestScreenMutex( 5000 );
  955.     if ( rc )
  956.     {
  957.         debug(F101,"SetMode() unable to retrieve Screen Mutex","",rc);
  958.         return -1;
  959.     }
  960.  
  961.     VscrnForceFullUpdate();
  962.  
  963.     /* Create a size structure for new specifications */
  964.     wsize.X = ModeData->col ;
  965.     wsize.Y = ModeData->row ;
  966.     sbsize.X = ModeData->sbcol ;
  967.     sbsize.Y = ModeData->sbrow ;
  968.     debug(F111,"SetMode","wsize.X",wsize.X) ;
  969.     debug(F111,"SetMode","wsize.Y",wsize.Y) ;
  970.     debug(F111,"SetMode","sbsize.X",sbsize.X) ;
  971.     debug(F111,"SetMode","sbsize.Y",sbsize.Y) ;
  972.  
  973.     /* Get current size of the window and screen buffer */
  974.     rc = GetConsoleScreenBufferInfo( VioHandle, &csbi ) ;
  975.     if ( !rc ) {
  976.         DWORD error = GetLastError();
  977.         if ( error == ERROR_INVALID_HANDLE ) {
  978.             debug(F101,"SetMode VioHandle","",VioHandle);
  979.             VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  980.             debug(F101,"SetMode GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  981.         }
  982.         ReleaseScreenMutex() ;
  983.         return 3;
  984.     }
  985.  
  986.     debug(F111,"SetMode GetConsoleScreenBufferInfo","dwSize.X",csbi.dwSize.X);
  987.     debug(F111,"SetMode GetConsoleScreenBufferInfo","dwSize.Y",csbi.dwSize.Y);
  988.     debug(F111,"SetMode GetConsoleScreenBufferInfo","dwCursorPosition.X",csbi.dwCursorPosition.X);
  989.     debug(F111,"SetMode GetConsoleScreenBufferInfo","dwCursorPosition.Y",csbi.dwCursorPosition.Y);
  990.     debug(F111,"SetMode GetConsoleScreenBufferInfo","wAttributes",csbi.wAttributes);
  991.     debug(F111,"SetMode GetConsoleScreenBufferInfo","srWindow.Top",csbi.srWindow.Top);
  992.     debug(F111,"SetMode GetConsoleScreenBufferInfo","srWindow.Bottom",csbi.srWindow.Bottom);
  993.     debug(F111,"SetMode GetConsoleScreenBufferInfo","srWindow.Left",csbi.srWindow.Left);
  994.     debug(F111,"SetMode GetConsoleScreenBufferInfo","srWindow.Right",csbi.srWindow.Right);
  995.     debug(F111,"SetMode GetConsoleScreenBufferInfo","dwMaximumWindowSize.X",csbi.dwMaximumWindowSize.X);
  996.     debug(F111,"SetMode GetConsoleScreenBufferInfo","dwMaximumWindowSize.Y",csbi.dwMaximumWindowSize.Y);
  997.  
  998.     if (GetWindowRect( hwndConsole, &rConsole )){
  999.         debug(F111,"SetMode GetWindowRect","rConsole.Top",   rConsole.top);
  1000.         debug(F111,"SetMode GetWindowRect","rConsole.Left",  rConsole.left);
  1001.         debug(F111,"SetMode GetWindowRect","rConsole.Bottom",rConsole.bottom);
  1002.         debug(F111,"SetMode GetWindowRect","rConsole.Right", rConsole.right);
  1003.     }
  1004.     if (GetClientRect( hwndConsole, &rClient )){
  1005.         debug(F111,"SetMode GetWindowRect","rClient.Top",   rClient.top);
  1006.         debug(F111,"SetMode GetWindowRect","rClient.Left",  rClient.left);
  1007.         debug(F111,"SetMode GetWindowRect","rClient.Bottom",rClient.bottom);
  1008.         debug(F111,"SetMode GetWindowRect","rClient.Right", rClient.right);
  1009.     }
  1010.  
  1011.     fixedX = rConsole.right - rConsole.left - rClient.right;
  1012.     fixedY = rConsole.bottom - rConsole.top - rClient.bottom;
  1013.     pixelsX = 1+ (rClient.right) / csbi.dwSize.X;
  1014.     pixelsY = 1+ (rClient.bottom) / csbi.dwSize.Y;
  1015.     desiredX = pixelsX * wsize.X + fixedX;
  1016.     desiredY = pixelsY * wsize.Y + fixedY;
  1017.  
  1018.     debug(F111,"SetMode","fixedX",fixedX);
  1019.     debug(F111,"SetMode","fixedY",fixedY);
  1020.     debug(F111,"SetMode","pixelsX",pixelsX);
  1021.     debug(F111,"SetMode","pixelsY",pixelsY);
  1022.     debug(F111,"SetMode","desired Right",desiredX);
  1023.     debug(F111,"SetMode","desired Bottom",desiredY);
  1024.  
  1025.     /*
  1026.     The rules that apply here are quite simple.  We are dealing
  1027.     with two boxes that we must keep in sync: window size and
  1028.     screen buffer size.  The window cannot be larger in any
  1029.     dimension than the screen buffer.  The screen buffer cannot
  1030.     be smaller in any dimension than the window.
  1031.     */
  1032.  
  1033.     /* Why do anything if there is no work to do? */
  1034.     if ( (csbi.srWindow.Right - csbi.srWindow.Left +1) == wsize.X  &&
  1035.          (csbi.srWindow.Bottom - csbi.srWindow.Top +1) == wsize.Y &&
  1036.          sbsize.X == csbi.dwSize.X && sbsize.Y == csbi.dwSize.Y ) {
  1037.         debug(F110,"SetMode","nothing to do",0);
  1038.         goto setattr;
  1039.     }
  1040.  
  1041.     /* Adjust the width of the window to the desired size */
  1042.     if ( (csbi.srWindow.Right - csbi.srWindow.Left +1) > wsize.X )
  1043.     {
  1044.         rect.Top = rect.Left = 0 ;
  1045.         rect.Right  = wsize.X - 1 ;
  1046.         rect.Bottom = (csbi.srWindow.Bottom - csbi.srWindow.Top);
  1047.         setwin++;
  1048.     }
  1049.  
  1050.     /* Now adjust the height of the window */
  1051.     if ( (csbi.srWindow.Bottom - csbi.srWindow.Top +1) > wsize.Y )
  1052.     {
  1053.         rect.Top = rect.Left = 0 ;
  1054.         rect.Right  = (wsize.X < csbi.dwMaximumWindowSize.X ? wsize.X :
  1055.                       csbi.dwMaximumWindowSize.X)-1;
  1056.         rect.Bottom = wsize.Y - 1 ;
  1057.         setwin++;
  1058.     }
  1059.  
  1060.     if (setwin) {
  1061.         if ( !SetConsoleWindowInfo( VioHandle, TRUE, &rect ) )
  1062.         {
  1063.             rc = GetLastError() ;
  1064.             debug(F101,"Set Mode SetConsoleWindowInfo failed","",rc ) ;
  1065.             if ( error == ERROR_INVALID_HANDLE ) {
  1066.                 debug(F101,"SetMode VioHandle","",VioHandle);
  1067.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  1068.                 debug(F101,"SetMode GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  1069.             }
  1070.             ReleaseScreenMutex() ;
  1071.             return 3;
  1072.         }
  1073.         if (isWin95())
  1074.             msleep(50);
  1075.         setwin = 0;
  1076.     }
  1077.  
  1078.     /* If the window was getting smaller the screen buffer will
  1079.        now be larger than the window size.  So it should be safe
  1080.        to decrease the screen buffer to match.   If the window
  1081.        is getting larger, the screen buffer must first be increased
  1082.        in size.
  1083.      */
  1084.     if (!(sbsize.X == csbi.dwSize.X && sbsize.Y == csbi.dwSize.Y)) {
  1085.         if ( !SetConsoleScreenBufferSize( VioHandle, sbsize ) )
  1086.         {
  1087.             rc = GetLastError() ;
  1088.             debug(F101,"SetMode SetConsoleScreenBufferSize failed","",rc ) ;
  1089.             if ( error == ERROR_INVALID_HANDLE ) {
  1090.                 debug(F101,"SetMode VioHandle","",VioHandle);
  1091.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  1092.                 debug(F101,"SetMode GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  1093.             }
  1094.             ReleaseScreenMutex() ;
  1095.             return 3;
  1096.         }
  1097.         if (isWin95())
  1098.             msleep(50);
  1099.     }
  1100.  
  1101.         /* Get the current Screen Buffer Info */
  1102.         rc = GetConsoleScreenBufferInfo( VioHandle, &csbi ) ;
  1103.         if ( !rc ) {
  1104.             DWORD error = GetLastError();
  1105.             if ( error == ERROR_INVALID_HANDLE ) {
  1106.                 debug(F101,"SetMode VioHandle","",VioHandle);
  1107.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  1108.                 debug(F101,"SetMode GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  1109.             }
  1110.             ReleaseScreenMutex() ;
  1111.             return 3;
  1112.         }
  1113.  
  1114. #ifdef COMMENT
  1115.     debug(F111,"SetMode GetConsoleScreenBufferInfo 2","dwSize.X",csbi.dwSize.X);
  1116.     debug(F111,"SetMode GetConsoleScreenBufferInfo 2","dwSize.Y",csbi.dwSize.Y);
  1117.     debug(F111,"SetMode GetConsoleScreenBufferInfo 2","dwCursorPosition.X",csbi.dwCursorPosition.X);
  1118.     debug(F111,"SetMode GetConsoleScreenBufferInfo 2","dwCursorPosition.Y",csbi.dwCursorPosition.Y);
  1119.     debug(F111,"SetMode GetConsoleScreenBufferInfo 2","wAttributes",csbi.wAttributes);
  1120.     debug(F111,"SetMode GetConsoleScreenBufferInfo 2","srWindow.Top",csbi.srWindow.Top);
  1121.     debug(F111,"SetMode GetConsoleScreenBufferInfo 2","srWindow.Bottom",csbi.srWindow.Bottom);
  1122.     debug(F111,"SetMode GetConsoleScreenBufferInfo 2","srWindow.Left",csbi.srWindow.Left);
  1123.     debug(F111,"SetMode GetConsoleScreenBufferInfo 2","srWindow.Right",csbi.srWindow.Right);
  1124.     debug(F111,"SetMode GetConsoleScreenBufferInfo 2","dwMaximumWindowSize.X",csbi.dwMaximumWindowSize.X);
  1125.     debug(F111,"SetMode GetConsoleScreenBufferInfo 2","dwMaximumWindowSize.Y",csbi.dwMaximumWindowSize.Y);
  1126. #endif
  1127.  
  1128.     /* Change the width of the window if necessary */
  1129.     if ( (csbi.srWindow.Right - csbi.srWindow.Left+1) < wsize.X )
  1130.     {
  1131.         rect.Top = rect.Left = 0 ;
  1132.         rect.Right = (csbi.dwMaximumWindowSize.X > wsize.X ?
  1133.                        wsize.X : csbi.dwMaximumWindowSize.X) - 1 ;
  1134.         rect.Bottom = (csbi.srWindow.Bottom - csbi.srWindow.Top);
  1135.         setwin++;
  1136.     }
  1137.  
  1138.     /* And now the window height if necessary */
  1139.     if ( (csbi.srWindow.Bottom - csbi.srWindow.Top+1) < wsize.Y )
  1140.     {
  1141.         rect.Top = rect.Left = 0 ;
  1142.         rect.Right = (csbi.dwMaximumWindowSize.X > wsize.X ?
  1143.                        wsize.X : csbi.dwMaximumWindowSize.X) - 1 ;
  1144.         rect.Bottom = (csbi.dwMaximumWindowSize.Y > wsize.Y ?
  1145.                         wsize.Y : csbi.dwMaximumWindowSize.Y) - 1 ;
  1146.         setwin++;
  1147.     }
  1148.  
  1149.     if (setwin) {
  1150.         if ( !SetConsoleWindowInfo( VioHandle, TRUE, &rect ) ) {
  1151.             DWORD error = GetLastError();
  1152.             debug( F101, "SetConsoleWindowInfo failed","",error);
  1153.             if ( error == ERROR_INVALID_HANDLE ) {
  1154.                 debug(F101,"SetMode VioHandle","",VioHandle);
  1155.                 VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  1156.                 debug(F101,"SetMode GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  1157.             }
  1158.             ReleaseScreenMutex() ;
  1159.             return 3;
  1160.         }
  1161.         if (isWin95())
  1162.             msleep(50);
  1163.         setwin = 0;
  1164.     }
  1165.  
  1166. #ifdef COMMENT
  1167.     /* Get the current Screen Buffer Info */
  1168.     rc = GetConsoleScreenBufferInfo( VioHandle, &csbi ) ;
  1169.     if ( !rc ) {
  1170.         DWORD error = GetLastError();
  1171.         if ( error == ERROR_INVALID_HANDLE ) {
  1172.             debug(F101,"SetMode VioHandle","",VioHandle);
  1173.             VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  1174.             debug(F101,"SetMode GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  1175.         }
  1176.         ReleaseScreenMutex() ;
  1177.         return 3;
  1178.     }
  1179.  
  1180.     debug(F111,"SetMode GetConsoleScreenBufferInfo 3","dwSize.X",csbi.dwSize.X);
  1181.     debug(F111,"SetMode GetConsoleScreenBufferInfo 3","dwSize.Y",csbi.dwSize.Y);
  1182.     debug(F111,"SetMode GetConsoleScreenBufferInfo 3","dwCursorPosition.X",csbi.dwCursorPosition.X);
  1183.     debug(F111,"SetMode GetConsoleScreenBufferInfo 3","dwCursorPosition.Y",csbi.dwCursorPosition.Y);
  1184.     debug(F111,"SetMode GetConsoleScreenBufferInfo 3","wAttributes",csbi.wAttributes);
  1185.     debug(F111,"SetMode GetConsoleScreenBufferInfo 3","srWindow.Top",csbi.srWindow.Top);
  1186.     debug(F111,"SetMode GetConsoleScreenBufferInfo 3","srWindow.Bottom",csbi.srWindow.Bottom);
  1187.     debug(F111,"SetMode GetConsoleScreenBufferInfo 3","srWindow.Left",csbi.srWindow.Left);
  1188.     debug(F111,"SetMode GetConsoleScreenBufferInfo 3","srWindow.Right",csbi.srWindow.Right);
  1189.     debug(F111,"SetMode GetConsoleScreenBufferInfo 3","dwMaximumWindowSize.X",csbi.dwMaximumWindowSize.X);
  1190.     debug(F111,"SetMode GetConsoleScreenBufferInfo 3","dwMaximumWindowSize.Y",csbi.dwMaximumWindowSize.Y);
  1191. #endif
  1192.  
  1193.     /* Put the proper color in place */
  1194.   setattr:
  1195.     rc = SetConsoleTextAttribute( VioHandle, (WORD) ModeData->color ) ;
  1196.     if ( !rc ) {
  1197.         DWORD error = GetLastError();
  1198.         if ( error == ERROR_INVALID_HANDLE ) {
  1199.             debug(F101,"SetMode VioHandle","",VioHandle);
  1200.             VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  1201.             debug(F101,"SetMode GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  1202.         }
  1203.         ReleaseScreenMutex() ;
  1204.         return 3;
  1205.     }
  1206.  
  1207. #ifdef COMMENT
  1208.     /* This is an attempt to preserve the Window Size when Win95 is using Auto */
  1209.     /* font sizing.                                                            */
  1210.  
  1211.     msleep(1);
  1212.     GetWindowRect(hwndConsole, &rConsole);
  1213.     MoveWindow( hwndConsole,
  1214.                   rConsole.left,
  1215.                   rConsole.top,
  1216.                   desiredX,
  1217.                   desiredY,
  1218.                   TRUE);
  1219.  
  1220.     if (GetWindowRect( hwndConsole, &rConsole )){
  1221.         debug(F111,"SetMode GetWindowRect 2","rConsole.Top",   rConsole.top);
  1222.         debug(F111,"SetMode GetWindowRect 2","rConsole.Left",  rConsole.left);
  1223.         debug(F111,"SetMode GetWindowRect 2","rConsole.Bottom",rConsole.bottom);
  1224.         debug(F111,"SetMode GetWindowRect 2","rConsole.Right", rConsole.right);
  1225.     }
  1226.     if (GetClientRect( hwndConsole, &rClient )){
  1227.         debug(F111,"SetMode GetWindowRect 2","rClient.Top",   rClient.top);
  1228.         debug(F111,"SetMode GetWindowRect 2","rClient.Left",  rClient.left);
  1229.         debug(F111,"SetMode GetWindowRect 2","rClient.Bottom",rClient.bottom);
  1230.         debug(F111,"SetMode GetWindowRect 2","rClient.Right", rClient.right);
  1231.     }
  1232. #endif /* COMMENT */
  1233.  
  1234.     pwidth = ModeData->sbcol;
  1235.     pheight = ModeData->sbrow;
  1236. #else /* just OS/2 */
  1237.     VIOMODEINFO mi ;
  1238.     mi.cb = 12 ;
  1239.     mi.fbType = ModeData->fbType ;
  1240.     mi.color  = ModeData->color ;
  1241.     mi.col    = ModeData->col ;
  1242.     mi.row    = ModeData->row ;
  1243.     mi.hres   = ModeData->hres ;
  1244.     mi.vres   = ModeData->vres ;
  1245.  
  1246.     rc = RequestScreenMutex( 1000 );
  1247.     if ( rc )
  1248.     {
  1249.         debug(F100,"SetMode() unable to retrieve Screen Mutex","",0);
  1250.         ReleaseScreenMutex() ;
  1251.         return -1;
  1252.     }
  1253.     rc = VioSetMode( &mi, VioHandle ) ;
  1254.     pwidth = ModeData->col;
  1255.     pheight = ModeData->row;
  1256. #endif /* NT */
  1257.  
  1258.     msleep(50);                 /* Give OS time to resize the screen */
  1259.     ReleaseScreenMutex() ;
  1260.     return rc ;
  1261. }
  1262. #endif /* KUI */
  1263.  
  1264. /*---------------------------------------------------------------------------*/
  1265. /* GetCurPos                                                                 */
  1266. /*---------------------------------------------------------------------------*/
  1267. USHORT GetCurPos( PUSHORT Row, PUSHORT Column )
  1268. {
  1269. #ifdef NT
  1270.     USHORT rc = 1 ;
  1271.     CONSOLE_SCREEN_BUFFER_INFO mi ;
  1272.  
  1273.     if ( GetConsoleScreenBufferInfo( VioHandle, &mi ) )
  1274.     {
  1275.         rc = 0 ;
  1276.         *Row = mi.dwCursorPosition.Y ;
  1277.         *Column = mi.dwCursorPosition.X ;
  1278.     }
  1279.     else {
  1280.         DWORD error = GetLastError();
  1281.         if ( error == ERROR_INVALID_HANDLE ) {
  1282.             debug(F101,"GetCurPos VioHandle","",VioHandle);
  1283.             VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  1284.             debug(F101,"GetCurPos GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  1285.         }
  1286.         return 3;
  1287.     }
  1288.     return rc ;
  1289. #else /* NT */
  1290.     return VioGetCurPos( Row, Column, VioHandle ) ;
  1291. #endif /* NT */
  1292. }
  1293.  
  1294. /*---------------------------------------------------------------------------*/
  1295. /* SetCurPos                                                                 */
  1296. /*---------------------------------------------------------------------------*/
  1297. USHORT SetCurPos( USHORT Row, USHORT Column )
  1298. {
  1299. #ifdef NT
  1300.     COORD pos ;
  1301.     int rc = 0;
  1302.  
  1303.     pos.X = Column ;
  1304.     pos.Y = Row ;
  1305.     if ( !SetConsoleCursorPosition( VioHandle, pos ) )
  1306.     {
  1307.         DWORD error = GetLastError();
  1308.         if ( error == ERROR_INVALID_HANDLE ) {
  1309.             debug(F101,"SetCurPos VioHandle","",VioHandle);
  1310.             VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  1311.             debug(F101,"SetCurPos GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  1312.         }
  1313.         return 3;
  1314.     }
  1315.     return rc ;
  1316. #else /* NT */
  1317.    return VioSetCurPos( Row, Column, VioHandle ) ;
  1318. #endif /* NT */
  1319. }
  1320.  
  1321. /*---------------------------------------------------------------------------*/
  1322. /* GetCurType                                                                */
  1323. /*---------------------------------------------------------------------------*/
  1324. USHORT GetCurType( PCK_CURSORINFO CursorData )
  1325. {
  1326.     USHORT rc = 0;
  1327. #ifdef NT
  1328.     CONSOLE_CURSOR_INFO ci ;
  1329.     rc = 1 ;
  1330.     if ( GetConsoleCursorInfo( VioHandle, &ci ) )
  1331.     {
  1332.         rc = 0 ;
  1333.         CursorData->yStart = ci.dwSize ;
  1334.         CursorData->attr   = ci.bVisible ;
  1335.     }
  1336.     else {
  1337.         DWORD error = GetLastError();
  1338.         if ( error == ERROR_INVALID_HANDLE ) {
  1339.             debug(F101,"SetCurPos VioHandle","",VioHandle);
  1340.             VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  1341.             debug(F101,"SetCurPos GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  1342.         }
  1343.         return 3;
  1344.     }
  1345.  
  1346. #else /* just OS/2 */
  1347.     VIOCURSORINFO ci ;
  1348.     if ((rc = VioGetCurType( &ci, VioHandle )) == 0)
  1349.         {
  1350.         CursorData->yStart = ci.yStart ;
  1351.         CursorData->cEnd   = ci.cEnd   ;
  1352.         CursorData->cx     = ci.cx     ;
  1353.         CursorData->attr   = ci.attr   ;
  1354.         }
  1355. #endif /* NT */
  1356.     return rc ;
  1357. }
  1358.  
  1359. /*---------------------------------------------------------------------------*/
  1360. /* SetCurType                                                                */
  1361. /*---------------------------------------------------------------------------*/
  1362. USHORT SetCurType( PCK_CURSORINFO CursorData )
  1363. {
  1364.     USHORT rc = 0 ;
  1365. #ifdef NT
  1366.     CONSOLE_CURSOR_INFO ci ;
  1367.  
  1368.     if ( CursorData->yStart >= 1 && CursorData->yStart <= 100 )
  1369.         ci.dwSize = CursorData->yStart ;
  1370.     else {
  1371.         debug(F101,"Illegal cursor size","",CursorData->yStart);
  1372.         ci.dwSize = 37;
  1373.     }
  1374.     ci.bVisible = (CursorData->attr == (USHORT) -1 || CursorData->attr == 0) ?
  1375.         FALSE : TRUE ;
  1376.     if ( !SetConsoleCursorInfo( VioHandle, &ci ) )
  1377.     {
  1378.         DWORD error = GetLastError();
  1379.         debug(F101,"SetConsoleCursorInfo fails","",error ) ;
  1380.         if ( error == ERROR_INVALID_HANDLE ) {
  1381.             debug(F101,"SetCurType VioHandle","",VioHandle);
  1382.             VioHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  1383.             debug(F101,"SetCurType GetStdHandle(STD_OUTPUT_HANDLE)","",VioHandle);
  1384.         }
  1385.         return 3;
  1386.     }
  1387.  
  1388. #else /* just OS/2 */
  1389.     VIOCURSORINFO ci ;
  1390.     ci.yStart = CursorData->yStart ;
  1391.     ci.cEnd   = CursorData->cEnd;
  1392.     ci.cx     = CursorData->cx ;
  1393.     ci.attr   = CursorData->attr ;
  1394.     rc = VioSetCurType( &ci, VioHandle ) ;
  1395. #endif /* NT */
  1396.     return rc ;
  1397. }
  1398.  
  1399. BOOL
  1400. IsOS2FullScreen( void )
  1401. {
  1402. #ifdef NT
  1403.    /* if Windows 95 then */
  1404. #ifdef COMMENT
  1405.     return (isWin95());
  1406. #else /* COMMENT */
  1407.     return FALSE ;
  1408. #endif /* COMMENT */
  1409. #else /* NT */
  1410.     VIOFONTINFO fi;
  1411.     static BOOL fs = 2 ;
  1412.  
  1413.     if ( fs == 2 ) {
  1414.         memset( &fi, 0, sizeof(fi) ) ;
  1415.         fi.cb = sizeof(fi) ;
  1416.         fs = ( VioGetFont( &fi, VioHandle ) != ERROR_VIO_EXTENDED_SG ) ;
  1417.     }
  1418.     return fs ;
  1419. #endif /* NT */
  1420. }
  1421.  
  1422.  
  1423. /*---------------------------------------------------------------------------*/
  1424. /* Set132Cols                                                                */
  1425. /*---------------------------------------------------------------------------*/
  1426. USHORT
  1427. Set132Cols( int mode )
  1428. {
  1429.     USHORT rc = 0 ;
  1430. #ifdef KUI
  1431.     VscrnSetWidth( mode, 132 );
  1432. #else /* KUI */
  1433.     CK_VIDEOMODEINFO mi;
  1434.     extern int tt_modechg;
  1435.  
  1436.     if ( tt_modechg == TVC_DIS ) {
  1437.         VscrnSetWidth( mode, 132 );
  1438.     } else {
  1439.         if (GetMode( &mi ))
  1440.             return 1;
  1441.  
  1442.         if (tt_modechg == TVC_ENA && mi.col == 132 &&
  1443.              mi.row == VscrnGetHeight(mode) )
  1444.             return rc ;
  1445.  
  1446.         if (tt_modechg == TVC_W95 &&
  1447.              mi.row == VscrnGetHeight(mode) ) {
  1448.             VscrnSetWidth(mode,132);
  1449.             return rc ;
  1450.         }
  1451.  
  1452. #ifdef OS2ONLY
  1453.         if ( IsOS2FullScreen() ) {
  1454.             if (tt_modechg == TVC_ENA)
  1455.                 mi.col = 132 ;
  1456.             mi.row = VscrnGetHeight(mode) ;
  1457.             mi.hres = 1056 ;
  1458.             if ( mode == vmode )
  1459.             rc = SetMode( &mi ) ;
  1460.         }
  1461.         else
  1462. #endif /* OS2ONLY */
  1463.         {
  1464.             if (tt_modechg == TVC_ENA)
  1465.                 mi.col = 132 ;
  1466.             mi.row = VscrnGetHeight(mode);
  1467. #ifdef NT
  1468.             mi.sbcol = mi.col;
  1469.             mi.sbrow = mi.row;
  1470. #endif /* NT */
  1471. #ifdef OS2ONLY
  1472.             mi.hres = 0 ;
  1473.             mi.vres = 0 ;
  1474. #endif /* OS2ONLY */
  1475.             if ( mode == vmode )
  1476.             rc = SetMode( &mi ) ;
  1477.         }
  1478.  
  1479.         if (mode == vmode) {
  1480.             if (GetMode( &mi ))
  1481.                 return 1;
  1482.         }
  1483.  
  1484.  
  1485.         if (mode == VTERM)
  1486.             VscrnSetWidth( VTERM, 132 );
  1487.         else if ( tt_modechg == TVC_ENA )
  1488.             VscrnSetWidth( mode, mi.col );
  1489.         else if ( tt_modechg == TVC_W95 )
  1490.             VscrnSetWidth(mode, 132);
  1491.         VscrnSetHeight( mode, mi.row );
  1492.     }
  1493. #endif /* KUI */
  1494.     VscrnIsDirty(mode) ;
  1495.     return rc ;
  1496. }
  1497.  
  1498. /*---------------------------------------------------------------------------*/
  1499. /* Set80Cols                                                                 */
  1500. /*---------------------------------------------------------------------------*/
  1501. USHORT
  1502. Set80Cols( int mode )
  1503. {
  1504.     USHORT rc = 0 ;
  1505. #ifdef KUI
  1506.     VscrnSetWidth( mode, 80 );
  1507. #else /* KUI */
  1508.     CK_VIDEOMODEINFO mi;
  1509.     extern int tt_modechg;
  1510.  
  1511.     if ( tt_modechg == TVC_DIS ) {
  1512.         VscrnSetWidth( mode, 80 );
  1513.     } else {
  1514.         if (GetMode( &mi ))
  1515.             return 1;
  1516.  
  1517.         if (tt_modechg == TVC_ENA && mi.col == 80 &&
  1518.              mi.row == VscrnGetHeight(mode) )
  1519.             return rc ;
  1520.  
  1521.         if (tt_modechg == TVC_W95 &&
  1522.              mi.row == VscrnGetHeight(mode) ) {
  1523.             VscrnSetWidth(mode,80);
  1524.             return rc ;
  1525.         }
  1526.  
  1527. #ifdef OS2ONLY
  1528.         if ( IsOS2FullScreen() ) {
  1529.             if (tt_modechg == TVC_ENA)
  1530.                 mi.col = 80 ;
  1531.             mi.row = VscrnGetHeight(mode) ;
  1532.             mi.hres = 720 ;
  1533.             if (mode == vmode)
  1534.                 rc = SetMode( &mi ) ;
  1535.         }
  1536.         else
  1537. #endif /* OS2ONLY */
  1538.         {
  1539.             if (tt_modechg == TVC_ENA)
  1540.                 mi.col = 80 ;
  1541.             mi.row = VscrnGetHeight(mode);
  1542. #ifdef NT
  1543.             mi.sbcol = mi.col;
  1544.             mi.sbrow = mi.row;
  1545. #endif /* NT */
  1546. #ifdef OS2ONLY
  1547.             mi.hres = 0 ;
  1548.             mi.vres = 0 ;
  1549. #endif /* OS2ONLY */
  1550.             if (mode == vmode)
  1551.                 rc = SetMode( &mi ) ;
  1552.         }
  1553.  
  1554.         if (mode == vmode) {
  1555.             if (GetMode( &mi ))
  1556.                 return 1;
  1557.         }
  1558.  
  1559.         if ( mode == VTERM )
  1560.             VscrnSetWidth( VTERM, 80 );
  1561.         else if ( tt_modechg == TVC_ENA )
  1562.             VscrnSetWidth( mode, mi.col );
  1563.         else if ( tt_modechg == TVC_W95 )
  1564.             VscrnSetWidth( mode, 80 );
  1565.         VscrnSetHeight( mode, mi.row ) ;
  1566.     }
  1567. #endif /* KUI */
  1568.     VscrnIsDirty(mode) ;
  1569.  
  1570.     return rc ;
  1571. }
  1572.  
  1573. /*---------------------------------------------------------------------------*/
  1574. /* SetCols                                                                   */
  1575. /*---------------------------------------------------------------------------*/
  1576. USHORT
  1577. SetCols( int mode )
  1578. {
  1579.     USHORT rc = 0 ;
  1580. #ifdef KUI
  1581.     /* do nothing */
  1582. #else /* KUI */
  1583.     CK_VIDEOMODEINFO mi;
  1584.     extern int tt_modechg;
  1585.  
  1586.     if ( tt_modechg != TVC_DIS ) {
  1587.         if (GetMode( &mi ))
  1588.             return 1;
  1589.  
  1590.         if ((tt_modechg == TVC_ENA && mi.col == VscrnGetWidth(mode) ||
  1591.               tt_modechg == TVC_W95) &&
  1592.              mi.row == VscrnGetHeight(mode) )
  1593.             return rc ;
  1594.  
  1595. #ifdef OS2ONLY
  1596.         if ( IsOS2FullScreen() ) {
  1597.             if (tt_modechg == TVC_ENA)
  1598.                 mi.col = VscrnGetWidth(mode)  ;
  1599.             else
  1600.                 mi.col = 80 ;
  1601.             mi.row = VscrnGetHeight(mode) ;
  1602.  
  1603.             if ( VscrnGetWidth(mode)  == 40 ) {
  1604.                 switch ( VscrnGetHeight(mode)) {
  1605.                 case 25:
  1606.                     mi.hres = 360 ;
  1607.                     mi.vres = 400 ;
  1608.                     break;
  1609.  
  1610.                 case 43:
  1611.                     mi.hres = 320 ;
  1612.                     mi.vres = 350 ;
  1613.                     break;
  1614.  
  1615.                 case 50:
  1616.                     mi.hres = 360 ;
  1617.                     mi.vres = 400 ;
  1618.                     break;
  1619.  
  1620.                 case 60:
  1621.                     mi.hres = 360 ;
  1622.                     mi.vres = 480 ;
  1623.                     break;
  1624.                 }
  1625.             }
  1626.             else if ( VscrnGetWidth(mode)  == 80 ) {
  1627.                 switch ( VscrnGetHeight(mode) ) {
  1628.                 case 25:
  1629.                     mi.hres = 720 ;
  1630.                     mi.vres = 400 ;
  1631.                     break;
  1632.  
  1633.                 case 43:
  1634.                     mi.hres = 640 ;
  1635.                     mi.vres = 350 ;
  1636.                     break;
  1637.  
  1638.                 case 50:
  1639.                     mi.hres = 720 ;
  1640.                     mi.vres = 400 ;
  1641.                     break;
  1642.  
  1643.                 case 60:
  1644.                     mi.hres = 720 ;
  1645.                     mi.vres = 480 ;
  1646.                     break;
  1647.                 }
  1648.             }
  1649.             else if ( VscrnGetWidth(mode)  == 132 ) {
  1650.                 switch ( VscrnGetHeight(mode) ) {
  1651.                 case 25:
  1652.                     mi.hres = 1056 ;
  1653.                     mi.vres = 400 ;
  1654.                     break;
  1655.  
  1656.                 case 43:
  1657.                     mi.hres = 1056 ;
  1658.                     mi.vres = 350 ;
  1659.                     break;
  1660.  
  1661.                 case 50:
  1662.                     mi.hres = 1056 ;
  1663.                     mi.vres = 400 ;
  1664.                     break;
  1665.  
  1666.                 case 60:
  1667.                     mi.hres = 1056 ;
  1668.                     mi.vres = 480 ;
  1669.                     break;
  1670.                 }
  1671.             }
  1672.             if ( vmode == mode )
  1673.             rc = SetMode( &mi ) ;
  1674.         }
  1675.         else
  1676. #endif /* OS2ONLY */
  1677.         {
  1678.             if ( tt_modechg == TVC_ENA )
  1679.                 mi.col = VscrnGetWidth(mode)  ;
  1680.             else
  1681.                 mi.col = 80;
  1682.             mi.row = VscrnGetHeight(mode);
  1683. #ifdef NT
  1684.             mi.sbcol = mi.col;
  1685.             mi.sbrow = mi.row;
  1686. #endif /* NT */
  1687. #ifdef OS2ONLY
  1688.             mi.hres = 0 ;
  1689.             mi.vres = 0 ;
  1690. #endif /* OS2ONLY */
  1691.             if ( vmode == mode )
  1692.             rc = SetMode( &mi ) ;
  1693.         }
  1694.  
  1695.         if (mode == vmode) {
  1696.             if (GetMode( &mi ))
  1697.                 return 1;
  1698.         }
  1699.  
  1700.         if (tt_modechg == TVC_ENA)
  1701.             VscrnSetWidth( mode, mi.col ) ;
  1702.         VscrnSetHeight( mode, mi.row );
  1703.     }
  1704. #endif /* KUI */
  1705.     VscrnIsDirty(mode) ;
  1706.  
  1707.     return rc ;
  1708. }
  1709.  
  1710. #ifdef OLDDIRTY
  1711. static int isdirty[VNUM] = {0,0,0,0} ;
  1712. #endif
  1713.  
  1714. /*---------------------------------------------------------------------------*/
  1715. /* VscrnIsDirty                                                              */
  1716. /*---------------------------------------------------------------------------*/
  1717. APIRET
  1718. VscrnIsDirty( int vmode )
  1719. {
  1720.     APIRET rc = 0 ;
  1721.     extern int k95stdout;
  1722.     if ( k95stdout )
  1723.         return 0;
  1724. #ifdef OLDDIRTY
  1725.    RequestVscrnDirtyMutex( vmode, SEM_INDEFINITE_WAIT );
  1726.    if ( !isdirty[vmode] )
  1727.    {
  1728.       isdirty[vmode]++;
  1729.       rc = PostVscrnDirtySem(vmode) ;
  1730.    }
  1731.    ReleaseVscrnDirtyMutex(vmode);
  1732. #else
  1733.     rc = PostVscrnDirtySem(vmode) ;
  1734. #endif 
  1735.    return rc ;
  1736. }
  1737.  
  1738.  
  1739. APIRET
  1740. IsVscrnDirty( int vmode )
  1741. {
  1742.     extern int k95stdout;
  1743.     if ( k95stdout )
  1744.         return 0;
  1745. #ifdef OLDDIRTY
  1746.     return isdirty[vmode];
  1747. #else
  1748.     return WaitVscrnDirtySem( vmode, 0 ) ? 0 : 1;
  1749. #endif
  1750. }
  1751.  
  1752. APIRET
  1753. VscrnClean( int vmode )
  1754. {
  1755.     APIRET rc = 0 ;
  1756.     extern int k95stdout;
  1757.     if ( k95stdout )
  1758.         return 0;
  1759. #ifdef OLDDIRTY
  1760.     RequestVscrnDirtyMutex( vmode, SEM_INDEFINITE_WAIT );
  1761.     rc = isdirty[vmode] ;
  1762.     ResetVscrnDirtySem(vmode) ;
  1763.     isdirty[vmode] = 0 ;
  1764.     ReleaseVscrnDirtyMutex(vmode);
  1765. #else
  1766.     rc = IsVscrnDirty(vmode);
  1767.     ResetVscrnDirtySem(vmode);
  1768. #endif 
  1769.     return rc ;
  1770. }
  1771. /*---------------------------------------------------------------------------*/
  1772. /* VscrnScrollLf                                                             */
  1773. /*---------------------------------------------------------------------------*/
  1774. USHORT
  1775. VscrnScrollLf( BYTE vmode, USHORT TopRow, USHORT LeftCol, USHORT BotRow,
  1776.                  USHORT RightCol, USHORT Columns, viocell Cell )
  1777. {
  1778.     /* all position values above start at zero like Vio functions */
  1779.     SHORT x=0,y=0 ;
  1780.     videoline * line = NULL ;
  1781.  
  1782.     if ( Columns == 0 )
  1783.         return NO_ERROR ;
  1784.     if ( BotRow > VscrnGetHeight(vmode)- (tt_status[vmode]?2:1) || TopRow > BotRow )
  1785.         return ERROR_VIO_ROW ;
  1786.     if ( RightCol > VscrnGetWidth(vmode) -1 || LeftCol > RightCol )
  1787.         return ERROR_VIO_COL ;
  1788.  
  1789.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  1790.         vmode = VSTATUS ;
  1791.  
  1792.     if ( vscrn[vmode].lines == NULL )
  1793.         return(3);
  1794.  
  1795.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  1796.  
  1797.     for ( y = TopRow ; y <= BotRow ; y++ ) {
  1798.         line = &vscrn[vmode].lines[(vscrn[vmode].top+y)%vscrn[vmode].linecount] ;
  1799.         for ( x = LeftCol ; x <= RightCol ; x++ ){
  1800.             if ( x - Columns < LeftCol )
  1801.                 continue ;
  1802.             line->cells[x-Columns] = line->cells[x] ;
  1803.             line->vt_char_attrs[x-Columns] = line->vt_char_attrs[x];
  1804.             }
  1805.         for ( x = RightCol - Columns + 1 ; x <= RightCol ; x++ ){
  1806.             line->cells[x] = Cell ;
  1807.             line->vt_char_attrs[x] = VT_CHAR_ATTR_NORMAL ;
  1808.             }
  1809.         }
  1810.  
  1811.     ReleaseVscrnMutex( vmode ) ;
  1812.     return NO_ERROR ;
  1813. }
  1814.  
  1815. /*---------------------------------------------------------------------------*/
  1816. /* VscrnScrollRt                                                             */
  1817. /*---------------------------------------------------------------------------*/
  1818. USHORT
  1819. VscrnScrollRt( BYTE vmode, USHORT TopRow, USHORT LeftCol, USHORT BotRow,
  1820.                  USHORT RightCol, USHORT Columns, viocell Cell )
  1821. {
  1822.     /* all position values above start at zero like Vio functions */
  1823.     SHORT x=0,y=0 ;
  1824.     videoline * line = NULL ;
  1825.  
  1826.     if ( Columns == 0 )
  1827.         return NO_ERROR ;
  1828.     if ( BotRow > VscrnGetHeight(vmode)-(tt_status[vmode]?2:1) || TopRow > BotRow )
  1829.         return ERROR_VIO_ROW ;
  1830.     if ( RightCol > VscrnGetWidth(vmode) -1 || LeftCol > RightCol )
  1831.         return ERROR_VIO_COL ;
  1832.  
  1833.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  1834.         vmode = VSTATUS ;
  1835.  
  1836.     if ( vscrn[vmode].lines == NULL )
  1837.         return(3);
  1838.  
  1839.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  1840.  
  1841.     for ( y = TopRow ; y <= BotRow ; y++ ) {
  1842.         line = &vscrn[vmode].lines[(vscrn[vmode].top+y)%vscrn[vmode].linecount] ;
  1843.         for ( x = RightCol ; x >= LeftCol ; x-- ){
  1844.             if ( x + Columns > RightCol )
  1845.                 continue ;
  1846.             line->cells[x+Columns] = line->cells[x] ;
  1847.             line->vt_char_attrs[x+Columns] = line->vt_char_attrs[x];
  1848.             }
  1849.         for ( x = LeftCol + Columns - 1 ; x >= LeftCol ; x-- ){
  1850.             line->cells[x] = Cell ;
  1851.             line->vt_char_attrs[x] = VT_CHAR_ATTR_NORMAL ;
  1852.             }
  1853.         }
  1854.  
  1855.     ReleaseVscrnMutex( vmode ) ;
  1856.     return NO_ERROR ;
  1857. }
  1858.  
  1859. /*---------------------------------------------------------------------------*/
  1860. /* VscrnScrollDn                                                             */
  1861. /*---------------------------------------------------------------------------*/
  1862. /* WARNING - Up and Dn not fully implemented */
  1863.  
  1864. USHORT
  1865. VscrnScrollDn( BYTE vmode, USHORT TopRow, USHORT LeftCol, USHORT BotRow,
  1866.                  USHORT RightCol, USHORT Rows, viocell Cell )
  1867. {
  1868.     /* all position values above start at zero like Vio functions */
  1869.     SHORT x=0,y=0 ;
  1870.     videoline * toline = NULL, * fromline = NULL ;
  1871.  
  1872.     if ( Rows == 0 )
  1873.         return NO_ERROR ;
  1874.     if ( BotRow > VscrnGetHeight(vmode)-(tt_status[vmode]?2:1) || TopRow > BotRow )
  1875.         return ERROR_VIO_ROW ;
  1876.     if ( RightCol > VscrnGetWidth(vmode) -1 || LeftCol > RightCol )
  1877.         return ERROR_VIO_COL ;
  1878.  
  1879.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  1880.         vmode = VSTATUS ;
  1881.  
  1882.     if ( vscrn[vmode].lines == NULL )
  1883.         return(3);
  1884.  
  1885.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  1886.  
  1887.     for ( y = BotRow ; y >= TopRow ; y-- ){
  1888.         if ( y + Rows > BotRow )
  1889.             continue ;
  1890.         toline = &vscrn[vmode].lines[(vscrn[vmode].top+y-Rows)%vscrn[vmode].linecount] ;
  1891.         fromline = &vscrn[vmode].lines[(vscrn[vmode].top+y)%vscrn[vmode].linecount] ;
  1892.         for ( x = LeftCol ; x <= RightCol ; x++ ) {
  1893.             toline->cells[x] = fromline->cells[x] ;
  1894.             toline->vt_char_attrs[x] = fromline->vt_char_attrs[x];
  1895.         }
  1896.     }
  1897.     for ( y = TopRow + Rows - 1 ; y >= TopRow ; y-- ){
  1898.         toline = &vscrn[vmode].lines[(vscrn[vmode].top+y)%vscrn[vmode].linecount] ;
  1899.         for ( x = LeftCol ; x <= RightCol ; x++ ) {
  1900.             toline->cells[x] = Cell ;
  1901.             toline->vt_char_attrs[x] = VT_CHAR_ATTR_NORMAL ;
  1902.         }
  1903.     }
  1904.  
  1905.     ReleaseVscrnMutex( vmode ) ;
  1906.  
  1907.     return NO_ERROR ;
  1908. }
  1909.  
  1910. /*---------------------------------------------------------------------------*/
  1911. /* VscrnScrollUp                                                             */
  1912. /*---------------------------------------------------------------------------*/
  1913. USHORT
  1914. VscrnScrollUp( BYTE vmode, USHORT TopRow, USHORT LeftCol, USHORT BotRow,
  1915.                  USHORT RightCol, USHORT Rows, viocell Cell )
  1916. {
  1917.     /* all position values above start at zero like Vio functions */
  1918.     SHORT x=0,y=0 ;
  1919.     videoline * toline = NULL, * fromline = NULL ;
  1920.  
  1921.     if ( Rows == 0 )
  1922.         return NO_ERROR ;
  1923.     if ( BotRow > VscrnGetHeight(vmode)-(tt_status[vmode]?2:1) || TopRow > BotRow )
  1924.         return ERROR_VIO_ROW ;
  1925.     if ( RightCol > VscrnGetWidth(vmode) -1 || LeftCol > RightCol )
  1926.         return ERROR_VIO_COL ;
  1927.  
  1928.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  1929.         vmode = VSTATUS ;
  1930.  
  1931.     if ( vscrn[vmode].lines == NULL )
  1932.         return(3);
  1933.  
  1934.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  1935.  
  1936.     for ( y = TopRow ; y <= BotRow ; y++ ){
  1937.         if ( y - Rows < TopRow )
  1938.             continue ;
  1939.         toline = &vscrn[vmode].lines[(vscrn[vmode].top+y-Rows)%vscrn[vmode].linecount] ;
  1940.         fromline = &vscrn[vmode].lines[(vscrn[vmode].top+y)%vscrn[vmode].linecount] ;
  1941.         for ( x = LeftCol ; x <= RightCol ; x++ ) {
  1942.             toline->cells[x] = fromline->cells[x] ;
  1943.             toline->vt_char_attrs[x] = fromline->vt_char_attrs[x];
  1944.             }
  1945.     }
  1946.     for ( y = BotRow - Rows + 1 ; y <= BotRow ; y++ ){
  1947.         toline = &vscrn[vmode].lines[(vscrn[vmode].top+y)%vscrn[vmode].linecount] ;
  1948.         for ( x = LeftCol ; x <= RightCol ; x++ ) {
  1949.             toline->cells[x] = Cell ;
  1950.             toline->vt_char_attrs[x] = VT_CHAR_ATTR_NORMAL ;
  1951.         }
  1952.     }
  1953.  
  1954.     ReleaseVscrnMutex( vmode ) ;
  1955.  
  1956.     return NO_ERROR ;
  1957. }
  1958.  
  1959. /*---------------------------------------------------------------------------*/
  1960. /* VscrnWrtCell                                                              */
  1961. /*---------------------------------------------------------------------------*/
  1962. USHORT
  1963. VscrnWrtCell( BYTE vmode, viocell Cell, vtattrib att, USHORT Row, USHORT Col )
  1964. {
  1965.     int i ;
  1966.     videoline * line ;
  1967.     unsigned char cellcolor = geterasecolor(vmode);
  1968.  
  1969.     if ( Row < 0 || Row > VscrnGetHeight(vmode)-(tt_status[vmode]?2:1) )
  1970.         return ERROR_VIO_ROW ;
  1971.  
  1972.     if ( Col < 0 || Col > VscrnGetWidth(vmode) -1 )
  1973.         return ERROR_VIO_COL ;
  1974.  
  1975.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  1976.         vmode = VSTATUS ;
  1977.  
  1978.     line = VscrnGetLineFromTop( vmode, Row ) ;
  1979.  
  1980.     if (line->width == 0) {
  1981.         line->width = VscrnGetWidth(vmode)  ;
  1982.         for ( i=0 ; i<MAXTERMCOL  ; i++ ) {
  1983.             line->cells[i].c = ' ' ;
  1984.             line->cells[i].a = cellcolor ;
  1985.             line->vt_char_attrs[i] = VT_CHAR_ATTR_NORMAL ;
  1986.         }
  1987.     }
  1988.  
  1989.     line->cells[Col] = Cell ;
  1990.     line->vt_char_attrs[Col] = VT_CHAR_ATTR_NORMAL |
  1991.         (att.bold       ? VT_CHAR_ATTR_BOLD      : 0) |
  1992.         (att.dim        ? VT_CHAR_ATTR_DIM       : 0) |
  1993.         (att.underlined ? VT_CHAR_ATTR_UNDERLINE : 0) |
  1994.         (att.blinking   ? VT_CHAR_ATTR_BLINK     : 0) |
  1995.         (att.reversed   ? VT_CHAR_ATTR_REVERSE   : 0) |
  1996.         (att.italic     ? VT_CHAR_ATTR_ITALIC    : 0) |
  1997.         (att.invisible  ? VT_CHAR_ATTR_INVISIBLE : 0) |
  1998.         (att.unerasable ? VT_CHAR_ATTR_PROTECTED : 0) |
  1999.         (att.graphic    ? VT_CHAR_ATTR_GRAPHIC   : 0) |
  2000.         (att.hyperlink  ? VT_CHAR_ATTR_HYPERLINK : 0) |
  2001.         (att.wyseattr   ? WY_CHAR_ATTR         : 0) ;
  2002.     line->hyperlinks[Col] = att.hyperlink ? att.linkid : 0;
  2003.     return NO_ERROR ;
  2004. }
  2005.  
  2006. /*---------------------------------------------------------------------------*/
  2007. /* VscrnWrtCharStrAtt                                                        */
  2008. /*---------------------------------------------------------------------------*/
  2009. USHORT
  2010. VscrnWrtCharStrAtt( BYTE vmode, PCH CharStr, USHORT Length,
  2011.                     USHORT Row, USHORT Column, PBYTE Attr )
  2012. {
  2013.     USHORT rc = 0;
  2014.     int i ;
  2015.     int height;
  2016.  
  2017.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2018.         vmode = VSTATUS ;
  2019.  
  2020.     height = VscrnGetHeight(vmode) - (tt_status[vmode]?1:0);
  2021.  
  2022.         if (height <= 0)
  2023.                 return(-1);
  2024.  
  2025.     /* write to a Vscrn function */
  2026.     for ( i = 0 ; i < Length ; i++ )
  2027.     {
  2028.         extern int tcsl;
  2029.         viocell cell;
  2030.  
  2031.         if ( CharStr[i] >= ' ' ) {
  2032.             if ( isunicode() ) {
  2033.                 cell.c = CharStr[i] >= 128 ?
  2034.                     (*xl_u[tcsl])(CharStr[i]) : CharStr[i] ;
  2035.             }
  2036.             else
  2037.                 cell.c = CharStr[i];
  2038.             cell.a = *Attr;
  2039.  
  2040.             if (Column > VscrnGetWidth(vmode==VSTATUS?VTERM:vmode)) {
  2041.                 Column = 1;
  2042.                 if (Row >= height) {
  2043.                     VscrnScroll(vmode,UPWARD, 0, height-1, 1, 1, SP) ;
  2044.                     Row = height;
  2045.                 } else {
  2046.                     Row++;
  2047.                 }
  2048.             }
  2049.             VscrnWrtCell(vmode, cell, (vmode == VTERM ? attrib : cmdattrib),
  2050.                           Row - 1, Column - 1);
  2051.             Column++;
  2052.         }
  2053.         else {                          /* Control character */
  2054.             switch (CharStr[i]) {
  2055.             case LF:
  2056.                 if (Row >= height) {
  2057.                     VscrnScroll(vmode,UPWARD, 0, height-1, 1, 1, SP);
  2058.                     Row = height;
  2059.                 } else {
  2060.                     Row++;
  2061.                 }
  2062.                 Column = 1 ;
  2063.                 break;
  2064.             case CR:
  2065.                 Column = 1 ;
  2066.                 break;
  2067.             case BS:
  2068.                 if (Column > 1)
  2069.                   Column--;
  2070.                 break;
  2071.             case 12:
  2072.                 if (Column < VscrnGetWidth(vmode))
  2073.                   Column++;
  2074.                 break;
  2075.             case BEL:
  2076. #ifdef IKSD
  2077.                 if ( !inserver )                /* Leads to infinite loop */
  2078. #endif /* IKSD */
  2079.                     bleep(BP_NOTE);
  2080.                 break;
  2081.             case 9: /* Tab */
  2082.                 Column += 8-(Column%8) ;
  2083.                 break;
  2084.             default: {           /* Don't ignore */
  2085.                 if ( isunicode() ) {
  2086.                     cell.c = (*xl_u[TX_IBMC0GRPH])(CharStr[i]);
  2087.                 }
  2088.                 else
  2089.                     cell.c = CharStr[i];
  2090.                 cell.a = *Attr;
  2091.  
  2092.                 VscrnWrtCell(vmode, cell, (vmode == VTERM ? attrib : cmdattrib),
  2093.                               Row - 1, Column - 1);
  2094.                 if (++Column > VscrnGetWidth(vmode)) {
  2095.                     Column = 1;
  2096.                     if (Row >= height) {
  2097.                         VscrnScroll(vmode,UPWARD, 0,height-1, 1, 1, SP) ;
  2098.                         Row = height;
  2099.                     }
  2100.                     else {
  2101.                         Row++;
  2102.                     }
  2103.                 }
  2104.             }
  2105.             }
  2106.         }
  2107.     }
  2108.     lgotoxy(vmode,Column,Row);
  2109.     VscrnIsDirty(vmode);
  2110.     return rc ;
  2111. }
  2112.  
  2113.  
  2114. /*---------------------------------------------------------------------------*/
  2115. /* VscrnWrtCharStrAtt                                                        */
  2116. /*---------------------------------------------------------------------------*/
  2117. USHORT
  2118. VscrnWrtUCS2StrAtt( BYTE vmode, PUSHORT UCS2Str, USHORT Length,
  2119.                     USHORT Row, USHORT Column, PBYTE Attr )
  2120. {
  2121.     USHORT rc = 0;
  2122.     int i ;
  2123.  
  2124.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2125.         vmode = VSTATUS ;
  2126.  
  2127.     /* write to a Vscrn function */
  2128.     for ( i = 0 ; i < Length ; i++ )
  2129.     {
  2130.         extern int tcsl;
  2131.         viocell cell;
  2132.  
  2133.         if ( UCS2Str[i] >= ' ' ) {
  2134.             if ( !isunicode() ) {
  2135.                 cell.c = UCS2Str[i] >= 128 ?
  2136.                     (*xl_tx[tcsl])(UCS2Str[i]) : UCS2Str[i] ;
  2137.             }
  2138.             else
  2139.                 cell.c = UCS2Str[i];
  2140.             cell.a = *Attr;
  2141.  
  2142.             if (Column > VscrnGetWidth(vmode==VSTATUS?VTERM:vmode)) {
  2143.                 Column = 1;
  2144.                 if (Row == VscrnGetHeight(vmode)
  2145.                      -(tt_status[vmode]?1:0)) {
  2146.                     VscrnScroll(vmode,UPWARD, 0,
  2147.                                  VscrnGetHeight(vmode)
  2148.                                  -(tt_status[vmode]?2:1), 1, 1, SP) ;
  2149.                 } else {
  2150.                     Row++;
  2151.                     if (Row == VscrnGetHeight(vmode)
  2152.                          -(tt_status[vmode]?1:0))
  2153.                       Row--;
  2154.                 }
  2155.             }
  2156.             VscrnWrtCell(vmode, cell, (vmode == VTERM ? attrib : cmdattrib),
  2157.                           Row - 1, Column - 1);
  2158.                         Column++;
  2159.         }
  2160.         else {                          /* Control character */
  2161.             switch (UCS2Str[i]) {
  2162.             case LF:
  2163.                 if (Row == VscrnGetHeight(vmode)-(tt_status[vmode]?1:0)) {
  2164.                     VscrnScroll(vmode,UPWARD, 0,
  2165.                                  VscrnGetHeight(vmode)-(tt_status[vmode]?2:1),
  2166.                                  1, 1, SP) ;
  2167.                 } else {
  2168.                     Row++;
  2169.                     if (Row > VscrnGetHeight(vmode)-(tt_status[vmode]?1:0))
  2170.                       Row = VscrnGetHeight(vmode)-(tt_status[vmode]?1:0);
  2171.                 }
  2172.                 Column = 1 ;
  2173.                 break;
  2174.             case CR:
  2175.                 Column = 1 ;
  2176.                 break;
  2177.             case BS:
  2178.                 if (Column > 1)
  2179.                   Column--;
  2180.                 break;
  2181.             case 12:
  2182.                 if (Column < VscrnGetWidth(vmode))
  2183.                   Column++;
  2184.                 break;
  2185.             case BEL:
  2186. #ifdef IKSD
  2187.                 if ( !inserver )                /* Leads to infinite loop */
  2188. #endif /* IKSD */
  2189.                     bleep(BP_NOTE);
  2190.                 break;
  2191.             case 9: /* Tab */
  2192.                 Column += 8-(Column%8) ;
  2193.                 break;
  2194.             default:{           /* Don't ignore */
  2195.                 if ( isunicode() ) {
  2196.                     cell.c = (*xl_u[TX_IBMC0GRPH])(UCS2Str[i]);
  2197.                 }
  2198.                 else
  2199.                     cell.c = UCS2Str[i];
  2200.                 cell.a = *Attr;
  2201.  
  2202.                 VscrnWrtCell(vmode, cell, (vmode == VTERM ? attrib : cmdattrib),
  2203.                               Row - 1, Column - 1);
  2204.                 if (++Column > VscrnGetWidth(vmode)) {
  2205.                     Column = 1;
  2206.                     if (Row == VscrnGetHeight(vmode)
  2207.                          -(tt_status[vmode]?1:0)) {
  2208.                         VscrnScroll(vmode,UPWARD, 0,
  2209.                                      VscrnGetHeight(vmode)
  2210.                                      -(tt_status[vmode]?2:1), 1, 1, SP) ;
  2211.                     }
  2212.                     else {
  2213.                         Row++;
  2214.                         if (Row == VscrnGetHeight(vmode)
  2215.                              -(tt_status[vmode]?1:0))
  2216.                             Row--;
  2217.                     }
  2218.                 }
  2219.             }
  2220.             }
  2221.         }
  2222.     }
  2223.     lgotoxy(vmode,Column,Row);
  2224.     VscrnIsDirty(vmode);
  2225.     return rc ;
  2226. }
  2227.  
  2228.  
  2229. /*---------------------------------------------------------------------------*/
  2230. /* VscrnGetLineFromTop                                                       */
  2231. /*---------------------------------------------------------------------------*/
  2232. videoline *
  2233. VscrnGetLineFromTop( BYTE vmode, SHORT y )  /* zero based */
  2234. {
  2235.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2236.         vmode = VSTATUS ;
  2237.  
  2238.     if ( vscrn[vmode].lines == NULL )
  2239.         return(NULL);
  2240.  
  2241.     while ( y < 0 )
  2242.         y += vscrn[vmode].linecount ;
  2243.  
  2244.     return &vscrn[vmode].lines[(vscrn[vmode].top+y)%vscrn[vmode].linecount] ;
  2245. }
  2246.  
  2247. /*---------------------------------------------------------------------------*/
  2248. /* VscrnGetLine                                                              */
  2249. /*---------------------------------------------------------------------------*/
  2250. videoline *
  2251. VscrnGetLine( BYTE vmode, SHORT y )  /* zero based */
  2252. {
  2253.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2254.         vmode = VSTATUS ;
  2255.  
  2256.     if ( vscrn[vmode].lines == NULL )
  2257.         return(NULL);
  2258.  
  2259.     while ( y < 0 )
  2260.         y += vscrn[vmode].linecount ;
  2261.  
  2262.     return &vscrn[vmode].lines[y%vscrn[vmode].linecount] ;
  2263. }
  2264.  
  2265. /*---------------------------------------------------------------------------*/
  2266. /* VscrnSetWidth                                                             */
  2267. /*---------------------------------------------------------------------------*/
  2268. VOID
  2269. VscrnSetWidth( BYTE vmode, int width )
  2270. {
  2271.     int y=0;
  2272.     videoline * pline = NULL;
  2273.  
  2274.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2275.         vmode = VSTATUS ;
  2276.  
  2277.     if ( vscrn[vmode].lines == NULL )
  2278.         return;
  2279.  
  2280.     vscrn[vmode].width = width ;
  2281.  
  2282.     if (vscrn[vmode].linecount && vscrn[vmode].lines != NULL) {
  2283.         for ( y=0;y<vscrn[vmode].height;y++ ) {
  2284.             pline = &vscrn[vmode].lines[(vscrn[vmode].top+y)%vscrn[vmode].linecount];
  2285.             pline->width = width;
  2286.         }
  2287.     }
  2288. #ifdef KUI
  2289.     {
  2290.         int cm = IsConnectMode();
  2291.         if ( cm && vmode == VTERM || !cm && vmode == VCMD ) {
  2292.             char buf[30];
  2293.             ckmakmsg(buf,30,ckitoa(vscrn[vmode].width)," x ",
  2294.                       ckitoa(vscrn[vmode].height-(tt_status[vmode]?1:0)),NULL);
  2295.             KuiSetTerminalStatusText(STATUS_HW, buf);
  2296.         }
  2297.     }
  2298. #endif /* KUI */
  2299. }
  2300.  
  2301. /*---------------------------------------------------------------------------*/
  2302. /* VscrnSetHeight                                                            */
  2303. /*---------------------------------------------------------------------------*/
  2304. VOID
  2305. VscrnSetHeight( BYTE vmode, int height )
  2306. {
  2307.  
  2308.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2309.         vmode = VSTATUS ;
  2310.  
  2311.     vscrn[vmode].height = height ;
  2312. #ifdef KUI
  2313.     {
  2314.         int cm = IsConnectMode();
  2315.         if ( cm && vmode == VTERM || !cm && vmode == VCMD ) {
  2316.             char buf[30];
  2317.             ckmakmsg(buf,30,ckitoa(vscrn[vmode].width)," x ",
  2318.                       ckitoa(vscrn[vmode].height-(tt_status[vmode]?1:0)),NULL);
  2319.             KuiSetTerminalStatusText(STATUS_HW, buf);
  2320.         }
  2321.     }
  2322. #endif /* KUI */
  2323. }
  2324.  
  2325. /*---------------------------------------------------------------------------*/
  2326. /* VscrnSetDisplayHeight                                                            */
  2327. /*---------------------------------------------------------------------------*/
  2328. VOID
  2329. VscrnSetDisplayHeight( BYTE vmode, int height )
  2330. {
  2331.  
  2332.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2333.         vmode = VSTATUS ;
  2334.  
  2335.     vscrn[vmode].display_height = height ;
  2336. }
  2337.  
  2338. /*---------------------------------------------------------------------------*/
  2339. /* VscrnGetWidth                                                             */
  2340. /*---------------------------------------------------------------------------*/
  2341. int
  2342. VscrnGetWidth( BYTE vmode )
  2343. {
  2344.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2345.         vmode = VSTATUS ;
  2346.  
  2347.    return vscrn[vmode].width ? vscrn[vmode].width : MAXTERMCOL;
  2348. }
  2349. /*---------------------------------------------------------------------------*/
  2350. /* VscrnGetHeight                                                            */
  2351. /*---------------------------------------------------------------------------*/
  2352. int
  2353. VscrnGetHeight( BYTE vmode )
  2354. {
  2355.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2356.         vmode = VSTATUS ;
  2357.  
  2358.    return vscrn[vmode].height ? vscrn[vmode].height : MAXTERMROW;
  2359. }
  2360. /*---------------------------------------------------------------------------*/
  2361. /* VscrnGetDisplayHeight                                                            */
  2362. /*---------------------------------------------------------------------------*/
  2363. int
  2364. VscrnGetDisplayHeight( BYTE vmode )
  2365. {
  2366.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2367.         vmode = VSTATUS ;
  2368.  
  2369.    return vscrn[vmode].display_height ? vscrn[vmode].display_height : VscrnGetHeight(vmode);
  2370. }
  2371.  
  2372. /*---------------------------------------------------------------------------*/
  2373. /* VscrnSetBookmark                                                          */
  2374. /*---------------------------------------------------------------------------*/
  2375. VOID
  2376. VscrnSetBookmark( BYTE vmode, int mark, int linenum )
  2377. {
  2378.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2379.         vmode = VSTATUS ;
  2380.  
  2381.    vscrn[vmode].bookmark[mark] = linenum ;
  2382. }
  2383.  
  2384. /*---------------------------------------------------------------------------*/
  2385. /* VscrnGetBookmark                                                          */
  2386. /*---------------------------------------------------------------------------*/
  2387. int
  2388. VscrnGetBookmark( BYTE vmode, int mark )
  2389. {
  2390.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2391.         vmode = VSTATUS ;
  2392.  
  2393.    return vscrn[vmode].bookmark[mark];
  2394. }
  2395. /*---------------------------------------------------------------------------*/
  2396. /* VscrnGetLineVtAttr                                                        */
  2397. /*---------------------------------------------------------------------------*/
  2398. USHORT
  2399. VscrnGetLineVtAttr( BYTE vmode, SHORT y ) /* zero based */
  2400. {
  2401.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2402.         vmode = VSTATUS ;
  2403.  
  2404.     return VscrnGetLineFromTop(vmode,y)->vt_line_attr ;
  2405. }
  2406.  
  2407. /*---------------------------------------------------------------------------*/
  2408. /* VscrnSetLineVtAttr                                                        */
  2409. /*---------------------------------------------------------------------------*/
  2410. USHORT
  2411. VscrnSetLineVtAttr( BYTE vmode, SHORT y, USHORT attr ) /* zero based */
  2412. {
  2413.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2414.         vmode = VSTATUS ;
  2415.  
  2416.     return (VscrnGetLineFromTop(vmode,y)->vt_line_attr = attr) ;
  2417. }
  2418.  
  2419. /*---------------------------------------------------------------------------*/
  2420. /* VscrnGetCells                                                             */
  2421. /*---------------------------------------------------------------------------*/
  2422. viocell *
  2423. VscrnGetCells( BYTE vmode, SHORT y )
  2424. {
  2425.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2426.         vmode = VSTATUS ;
  2427.  
  2428.     return VscrnGetLineFromTop(vmode,y)->cells ;
  2429. }
  2430.  
  2431. /*---------------------------------------------------------------------------*/
  2432. /* VscrnGetCell                                                              */
  2433. /*---------------------------------------------------------------------------*/
  2434. viocell *
  2435. VscrnGetCell( BYTE vmode, SHORT x, SHORT y )
  2436. {
  2437.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2438.         vmode = VSTATUS ;
  2439.  
  2440.     return &VscrnGetLineFromTop(vmode,y)->cells[x] ;
  2441. }
  2442.  
  2443. /*---------------------------------------------------------------------------*/
  2444. /* VscrnGetVtCharAttr                                                        */
  2445. /*---------------------------------------------------------------------------*/
  2446. vtattrib
  2447. VscrnGetVtCharAttr( BYTE vmode, SHORT x, SHORT y )
  2448. {
  2449.     static vtattrib vta ;
  2450.     USHORT attr ;
  2451.     videoline * line;
  2452.  
  2453.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2454.         vmode = VSTATUS ;
  2455.  
  2456.     line = VscrnGetLineFromTop(vmode,y);
  2457.     attr = line->vt_char_attrs[x] ;
  2458.  
  2459.     vta.bold            = attr & VT_CHAR_ATTR_BOLD ? 1 : 0 ;
  2460.     vta.dim             = attr & VT_CHAR_ATTR_DIM ? 1 : 0 ;
  2461.     vta.underlined      = attr & VT_CHAR_ATTR_UNDERLINE ? 1 : 0 ;
  2462.     vta.blinking        = attr & VT_CHAR_ATTR_BLINK ? 1 : 0 ;
  2463.     vta.reversed        = attr & VT_CHAR_ATTR_REVERSE ? 1 : 0 ;
  2464.     vta.italic          = attr & VT_CHAR_ATTR_ITALIC ? 1 : 0 ;
  2465.     vta.invisible       = attr & VT_CHAR_ATTR_INVISIBLE ? 1 : 0 ;
  2466.     vta.unerasable      = attr & VT_CHAR_ATTR_PROTECTED ? 1 : 0 ;
  2467.     vta.graphic         = attr & VT_CHAR_ATTR_GRAPHIC ? 1 : 0 ;
  2468.     vta.wyseattr        = attr & WY_CHAR_ATTR ? 1 : 0 ;
  2469.     vta.hyperlink       = attr & VT_CHAR_ATTR_HYPERLINK ? 1 : 0;
  2470.     vta.linkid          = attr & VT_CHAR_ATTR_HYPERLINK ? line->hyperlinks[x] : 0;
  2471.  
  2472.     return vta;
  2473. }
  2474.  
  2475. /*---------------------------------------------------------------------------*/
  2476. /* VscrnSetVtCharAttr                                                        */
  2477. /*---------------------------------------------------------------------------*/
  2478. USHORT
  2479. VscrnSetVtCharAttr( BYTE vmode, SHORT x, SHORT y, vtattrib vta )
  2480. {
  2481.     USHORT attr ;
  2482.     videoline * line;
  2483.  
  2484.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2485.         vmode = VSTATUS ;
  2486.  
  2487.     attr = VT_CHAR_ATTR_NORMAL |
  2488.                 (vta.bold       ? VT_CHAR_ATTR_BOLD      : 0) |
  2489.                 (vta.dim        ? VT_CHAR_ATTR_DIM       : 0) |
  2490.                 (vta.underlined ? VT_CHAR_ATTR_UNDERLINE : 0) |
  2491.                 (vta.blinking   ? VT_CHAR_ATTR_BLINK     : 0) |
  2492.                 (vta.reversed   ? VT_CHAR_ATTR_REVERSE   : 0) |
  2493.                 (vta.italic     ? VT_CHAR_ATTR_ITALIC    : 0) | 
  2494.                 (vta.invisible  ? VT_CHAR_ATTR_INVISIBLE : 0) |
  2495.                 (vta.unerasable ? VT_CHAR_ATTR_PROTECTED : 0) |
  2496.                 (vta.graphic    ? VT_CHAR_ATTR_GRAPHIC   : 0) |
  2497.                 (vta.hyperlink  ? VT_CHAR_ATTR_HYPERLINK : 0) |
  2498.                 (vta.wyseattr   ? WY_CHAR_ATTR         : 0) ;
  2499.     line = VscrnGetLineFromTop(vmode,y);
  2500.     line->vt_char_attrs[x] = attr;
  2501.     line->hyperlinks[x] = vta.linkid;
  2502.     return attr;
  2503. }
  2504.  
  2505. /*---------------------------------------------------------------------------*/
  2506. /* VscrnMoveTop                                                              */
  2507. /*---------------------------------------------------------------------------*/
  2508. LONG
  2509. VscrnMoveTop( BYTE vmode, LONG y )
  2510. {
  2511.     LONG newtop, beg, end ;
  2512.  
  2513.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2514.         vmode = VSTATUS ;
  2515.  
  2516.     end = vscrn[vmode].end ;
  2517.     beg = vscrn[vmode].beg ;
  2518.     newtop = vscrn[vmode].top + y ;
  2519.  
  2520.     if ( beg > end ) {
  2521.         end += vscrn[vmode].linecount ;
  2522.         if ( beg > vscrn[vmode].top )
  2523.             newtop += vscrn[vmode].linecount ;
  2524.         }
  2525.  
  2526.     if ( newtop < beg || newtop > end
  2527.          - VscrnGetHeight(vmode) + (tt_status[vmode]?2:2) )
  2528.         return -1 ;
  2529.  
  2530.     while ( newtop < 0 )
  2531.         newtop += vscrn[vmode].linecount ;
  2532.  
  2533.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  2534.     vscrn[vmode].top = (newtop)%vscrn[vmode].linecount ;
  2535.     ReleaseVscrnMutex( vmode );
  2536.     return vscrn[vmode].top ;
  2537. }
  2538.  
  2539. /*---------------------------------------------------------------------------*/
  2540. /* VscrnMoveScrollTop                                                        */
  2541. /*---------------------------------------------------------------------------*/
  2542. LONG
  2543. VscrnMoveScrollTop( BYTE vmode, LONG y )
  2544. {
  2545.     LONG newscrolltop, top, beg, end ;
  2546.  
  2547.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2548.         vmode = VSTATUS ;
  2549.  
  2550.     if (!scrollflag[vmode])
  2551.         vscrn[vmode].scrolltop = vscrn[vmode].top ;
  2552.  
  2553.     end = vscrn[vmode].end ;
  2554.     beg = vscrn[vmode].beg ;
  2555.     top = vscrn[vmode].top ;
  2556.     newscrolltop = vscrn[vmode].scrolltop + y ;
  2557.  
  2558.     if ( beg > end ) {
  2559.         end += vscrn[vmode].linecount ;
  2560.         if ( beg > vscrn[vmode].top )
  2561.             top += vscrn[vmode].linecount ;
  2562.         if ( beg > vscrn[vmode].scrolltop )
  2563.             newscrolltop += vscrn[vmode].linecount ;
  2564.         }
  2565.  
  2566.     debug(F111,"VscrnMoveScrollTop","newscrolltop",newscrolltop);
  2567.     debug(F111,"VscrnMoveScrollTop","end---",
  2568.            end-(VscrnGetHeight(vmode)-(tt_status[vmode]?1:0))+1);
  2569.     if ( newscrolltop < beg ||
  2570.          newscrolltop > end
  2571.          - (VscrnGetHeight(vmode)-(tt_status[vmode]?1:0)) + 1)
  2572.         return -1 ;
  2573.  
  2574.     while ( newscrolltop < 0 )
  2575.         newscrolltop += vscrn[vmode].linecount ;
  2576.  
  2577.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  2578.     vscrn[vmode].scrolltop = (newscrolltop)%vscrn[vmode].linecount ;
  2579.     ReleaseVscrnMutex( vmode ) ;
  2580.     return vscrn[vmode].scrolltop ;
  2581. }
  2582.  
  2583. /*---------------------------------------------------------------------------*/
  2584. /* VscrnMoveBegin                                                            */
  2585. /*---------------------------------------------------------------------------*/
  2586. LONG
  2587. VscrnMoveBegin( BYTE vmode, LONG y )
  2588. {
  2589.     if (y<0)
  2590.         return -1 ;
  2591.  
  2592.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2593.         vmode = VSTATUS ;
  2594.  
  2595.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  2596.     vscrn[vmode].beg = (vscrn[vmode].beg + y)%vscrn[vmode].linecount ;
  2597.     ReleaseVscrnMutex( vmode ) ;
  2598.     return vscrn[vmode].beg ;
  2599. }
  2600.  
  2601. /*---------------------------------------------------------------------------*/
  2602. /* VscrnMoveEnd                                                              */
  2603. /*---------------------------------------------------------------------------*/
  2604. LONG
  2605. VscrnMoveEnd( BYTE vmode, LONG y )
  2606. {
  2607.     LONG newend ;
  2608.  
  2609.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2610.         vmode = VSTATUS ;
  2611.  
  2612.     if (y<0)
  2613.         return -1 ;
  2614.  
  2615.     newend = vscrn[vmode].end + y ;
  2616.     if ( vscrn[vmode].beg < vscrn[vmode].end ) {
  2617.         if ( newend >= vscrn[vmode].linecount )
  2618.             vscrn[vmode].beg = newend - vscrn[vmode].linecount ;
  2619.         }
  2620.     else {
  2621.         vscrn[vmode].beg = (vscrn[vmode].beg + y)%vscrn[vmode].linecount ;
  2622.         }
  2623.  
  2624.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  2625.     vscrn[vmode].end = (newend)%vscrn[vmode].linecount ;
  2626.     ReleaseVscrnMutex( vmode ) ;
  2627.     return vscrn[vmode].end ;
  2628. }
  2629.  
  2630. /*---------------------------------------------------------------------------*/
  2631. /* VscrnGetLineWidth                                                         */
  2632. /*---------------------------------------------------------------------------*/
  2633. UCHAR
  2634. VscrnGetLineWidth( BYTE vmode, SHORT y )
  2635. {
  2636.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2637.         vmode = VSTATUS ;
  2638.  
  2639.     return VscrnGetLineFromTop(vmode,y)->width ;
  2640. }
  2641.  
  2642. /*---------------------------------------------------------------------------*/
  2643. /* VscrnGetTop                                                               */
  2644. /*---------------------------------------------------------------------------*/
  2645. ULONG
  2646. VscrnGetTop( BYTE vmode )
  2647. {
  2648.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2649.         vmode = VSTATUS ;
  2650.  
  2651.     return vscrn[vmode].top ;
  2652. }
  2653.  
  2654. /*---------------------------------------------------------------------------*/
  2655. /* VscrnGetScrollTop                                                         */
  2656. /*---------------------------------------------------------------------------*/
  2657. ULONG
  2658. VscrnGetScrollTop( BYTE vmode )
  2659. {
  2660.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2661.         vmode = VSTATUS ;
  2662.  
  2663.     return vscrn[vmode].scrolltop ;
  2664. }
  2665.  
  2666. /*---------------------------------------------------------------------------*/
  2667. /* VscrnGetScrollTop                                                         */
  2668. /*---------------------------------------------------------------------------*/
  2669. ULONG
  2670. VscrnGetScrollHorz( BYTE vmode )
  2671. {
  2672.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2673.         vmode = VSTATUS ;
  2674.  
  2675.     return vscrn[vmode].hscroll ;
  2676. }
  2677.  
  2678. /*---------------------------------------------------------------------------*/
  2679. /* VscrnGetBegin                                                             */
  2680. /*---------------------------------------------------------------------------*/
  2681. ULONG
  2682. VscrnGetBegin( BYTE vmode )
  2683. {
  2684.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2685.         vmode = VSTATUS ;
  2686.  
  2687.     return vscrn[vmode].beg ;
  2688. }
  2689.  
  2690. /*---------------------------------------------------------------------------*/
  2691. /* VscrnGetEnd                                                               */
  2692. /*---------------------------------------------------------------------------*/
  2693. ULONG
  2694. VscrnGetEnd( BYTE vmode )
  2695. {
  2696.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2697.         vmode = VSTATUS ;
  2698.  
  2699.     return vscrn[vmode].end ;
  2700. }
  2701.  
  2702. /*---------------------------------------------------------------------------*/
  2703. /* VscrnSetTop                                                               */
  2704. /*---------------------------------------------------------------------------*/
  2705. LONG
  2706. VscrnSetTop( BYTE vmode, LONG y )
  2707. {
  2708.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2709.         vmode = VSTATUS ;
  2710.  
  2711.     while ( y < 0 )
  2712.         y += vscrn[vmode].linecount ;
  2713.  
  2714.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  2715.     vscrn[vmode].top = y%vscrn[vmode].linecount ;
  2716.     ReleaseVscrnMutex( vmode );
  2717.     return vscrn[vmode].top ;
  2718. }
  2719.  
  2720. /*---------------------------------------------------------------------------*/
  2721. /* VscrnSetScrollTop                                                         */
  2722. /*---------------------------------------------------------------------------*/
  2723. LONG
  2724. VscrnSetScrollTop( BYTE vmode, LONG y )
  2725. {
  2726.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2727.         vmode = VSTATUS ;
  2728.  
  2729.     while ( y < 0 )
  2730.         y += vscrn[vmode].linecount ;
  2731.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  2732.     vscrn[vmode].scrolltop = y%vscrn[vmode].linecount ;
  2733.     ReleaseVscrnMutex( vmode );
  2734.     return vscrn[vmode].scrolltop ;
  2735. }
  2736.  
  2737. /*---------------------------------------------------------------------------*/
  2738. /* VscrnSetScrollHorz                                                         */
  2739. /*---------------------------------------------------------------------------*/
  2740. LONG
  2741. VscrnSetScrollHorz( BYTE vmode, LONG h )
  2742. {
  2743.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2744.         vmode = VSTATUS ;
  2745.  
  2746.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  2747.     vscrn[vmode].hscroll = h;
  2748.     ReleaseVscrnMutex( vmode );
  2749.     return vscrn[vmode].hscroll ;
  2750. }
  2751.  
  2752. /*---------------------------------------------------------------------------*/
  2753. /* VscrnSetBegin                                                             */
  2754. /*---------------------------------------------------------------------------*/
  2755. LONG
  2756. VscrnSetBegin( BYTE vmode, LONG y )
  2757. {
  2758.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2759.         vmode = VSTATUS ;
  2760.  
  2761.     while ( y < 0 )
  2762.         y += vscrn[vmode].linecount ;
  2763.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  2764.     vscrn[vmode].beg = y%vscrn[vmode].linecount ;
  2765.     ReleaseVscrnMutex( vmode );
  2766.     return vscrn[vmode].beg ;
  2767. }
  2768.  
  2769. /*---------------------------------------------------------------------------*/
  2770. /* VscrnSetEnd                                                               */
  2771. /*---------------------------------------------------------------------------*/
  2772. LONG
  2773. VscrnSetEnd( BYTE vmode, LONG y )
  2774. {
  2775.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2776.         vmode = VSTATUS ;
  2777.  
  2778.     while ( y < 0 )
  2779.         y += vscrn[vmode].linecount ;
  2780.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  2781.     vscrn[vmode].end = y%vscrn[vmode].linecount ;
  2782.     ReleaseVscrnMutex( vmode );
  2783.     return vscrn[vmode].end ;
  2784. }
  2785.  
  2786. /*---------------------------------------------------------------------------*/
  2787. /* VscrnGetBufferSize                                                        */
  2788. /*---------------------------------------------------------------------------*/
  2789. ULONG
  2790. VscrnGetBufferSize( BYTE vmode )
  2791. {
  2792.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2793.         vmode = VSTATUS ;
  2794.  
  2795.     return vscrn[vmode].linecount ;
  2796. }
  2797.  
  2798. /*---------------------------------------------------------------------------*/
  2799. /* VscrnSetCurPos                                                            */
  2800. /*---------------------------------------------------------------------------*/
  2801. position *
  2802. VscrnSetCurPos( BYTE vmode, SHORT x, SHORT y )
  2803. {
  2804. #ifdef KUI_COMMENT
  2805.     char buf[30];
  2806. #endif /* KUI */
  2807.  
  2808.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2809.         vmode = VSTATUS ;
  2810.  
  2811.     vscrn[vmode].cursor.x = x%VscrnGetWidth(vmode)  ;
  2812.     vscrn[vmode].cursor.y = y
  2813.       %(VscrnGetHeight(vmode)-(tt_status[vmode]?1:0)) ;
  2814.  
  2815. #ifdef KUI_COMMENT
  2816.     ckmakmsg(buf,30,ckitoa(vscrn[vmode].cursor.x+1),", ",
  2817.               ckitoa(vscrn[vmode].cursor.y+1),NULL);
  2818.     KuiSetTerminalStatusText(STATUS_CURPOS, buf);
  2819. #endif /* KUI */
  2820.  
  2821.     return &vscrn[vmode].cursor ;
  2822. }
  2823.  
  2824. /*---------------------------------------------------------------------------*/
  2825. /* VscrnGetCurPos                                                            */
  2826. /*---------------------------------------------------------------------------*/
  2827. position *
  2828. VscrnGetCurPos( BYTE vmode )
  2829. {
  2830.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2831.         vmode = VSTATUS ;
  2832.  
  2833.     return &vscrn[vmode].cursor ;
  2834. }
  2835.  
  2836.  
  2837. static viocell *        cellmem[VNUM] = { NULL, NULL, NULL, NULL } ;
  2838. static unsigned short * attrmem[VNUM] = { NULL, NULL, NULL, NULL } ;
  2839. static unsigned short * hyperlinkmem[VNUM] = { NULL, NULL, NULL, NULL } ;
  2840.  
  2841. /*---------------------------------------------------------------------------*/
  2842. /* VscrnSetBufferSize                                                        */
  2843. /*---------------------------------------------------------------------------*/
  2844. ULONG
  2845. VscrnSetBufferSize( BYTE vmode, ULONG newsize )
  2846. {
  2847.     static ULONG oldsize[VNUM]={0,0,0,0} ;
  2848.     int i ;
  2849.     videobuffer TmpScrn ;
  2850.     videoline * line ;
  2851.     ULONG rc = FALSE ;  /* Determines whether clearscreen needs to be called */
  2852.  
  2853.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  2854.         vmode = VSTATUS ;
  2855.  
  2856.     debug(F101,"SetBufferSize","",newsize);
  2857.     debug(F101,"SetBufferSize linecount","",vscrn[vmode].linecount);
  2858.  
  2859.     /* Wait for exclusive access to the screen */
  2860.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  2861.  
  2862.     if ( newsize < oldsize[vmode] ) { /* erase entire buffer and start again. */
  2863.         free(vscrn[vmode].lines) ;
  2864.         vscrn[vmode].linecount = 0 ;
  2865.         vscrn[vmode].lines = 0 ;
  2866.         vscrn[vmode].beg = 0 ;
  2867.         vscrn[vmode].top = 0 ;
  2868.         vscrn[vmode].scrolltop = 0 ;
  2869.         vscrn[vmode].end = 0 ;
  2870.         vscrn[vmode].cursor.x = vscrn[vmode].cursor.y = 0 ;
  2871.         vscrn[vmode].marktop = 0 ;
  2872.         vscrn[vmode].markbot = 0 ;
  2873.         for ( i=0 ; i < 10 ; i++ )
  2874.             vscrn[vmode].bookmark[i] = 0 ;
  2875.         free(cellmem[vmode]) ;
  2876.         cellmem[vmode]=NULL ;
  2877.         free(attrmem[vmode]) ;
  2878.         attrmem[vmode]=NULL ;
  2879.     }
  2880.  
  2881.     if ( vscrn[vmode].linecount == newsize ) {
  2882.         ReleaseVscrnMutex( vmode ) ;
  2883.         return rc ;
  2884.     }
  2885.     else if ( vscrn[vmode].linecount == 0 ) {
  2886.         debug( F101,"VscrnSetBufferSize malloc size","",
  2887.                newsize*sizeof(videoline) ) ;
  2888.         vscrn[vmode].linecount = newsize ;
  2889.         vscrn[vmode].lines = malloc(vscrn[vmode].linecount * sizeof(videoline)) ;
  2890.         if ( !vscrn[vmode].lines )
  2891.             fatal("VscrnSetBufferSize: unable to allocate memory for vscrn[].lines!");
  2892.         vscrn[vmode].top = 0 ;
  2893.         vscrn[vmode].scrolltop = 0 ;
  2894.         vscrn[vmode].beg = 0 ;
  2895.         vscrn[vmode].width = tt_cols[vmode] ;
  2896.         vscrn[vmode].height = tt_rows[vmode]+(tt_status[vmode]?1:0);
  2897.         vscrn[vmode].end = vscrn[vmode].height - 1 ;
  2898.         vscrn[vmode].cursor.x = 0 ;
  2899.         vscrn[vmode].cursor.y = 0 ;
  2900.         vscrn[vmode].marktop = -1 ;
  2901.         vscrn[vmode].markbot = -1 ;
  2902.         vscrn[vmode].popup = NULL ;
  2903.         for ( i=0 ; i<10 ; i++)
  2904.            vscrn[vmode].bookmark[i] = -1 ;
  2905.  
  2906.         cellmem[vmode] = malloc( (vscrn[vmode].linecount + 1) * MAXTERMCOL * sizeof(viocell) ) ;
  2907.         if ( !cellmem[vmode] )
  2908.             fatal("VscrnSetBufferSize: unable to allocate memory for cellmem[]!");
  2909.         attrmem[vmode] = malloc( (vscrn[vmode].linecount + 1) * MAXTERMCOL * sizeof(short) ) ;
  2910.         if ( !attrmem[vmode] )
  2911.             fatal("VscrnSetBufferSize: unable to allocate memory for attrmem[]!");
  2912.         hyperlinkmem[vmode] = malloc( (vscrn[vmode].linecount + 1) * MAXTERMCOL * sizeof(short) ) ;
  2913.         if ( !hyperlinkmem[vmode] )
  2914.             fatal("VscrnSetBufferSize: unable to allocate memory for hyperlinkmem[]!");
  2915.  
  2916.         for ( i=0 ; i<vscrn[vmode].linecount ; i++ ) {
  2917.             vscrn[vmode].lines[i].width = 0 ;
  2918.             vscrn[vmode].lines[i].cells = cellmem[vmode] + i * MAXTERMCOL ;
  2919.             vscrn[vmode].lines[i].vt_char_attrs = attrmem[vmode] + i * MAXTERMCOL ;
  2920.             vscrn[vmode].lines[i].vt_line_attr = VT_LINE_ATTR_NORMAL ;
  2921.             vscrn[vmode].lines[i].hyperlinks = hyperlinkmem[vmode] + i * MAXTERMCOL ;
  2922.             vscrn[vmode].lines[i].markbeg = -1 ;
  2923.             vscrn[vmode].lines[i].markshowend = -1 ;
  2924.             vscrn[vmode].lines[i].markend = -1 ;
  2925.             }
  2926.  
  2927.         rc = TRUE ;
  2928.         }
  2929.     else if ( vscrn[vmode].linecount < newsize ) {
  2930.         viocell *        oldcellmem = cellmem[vmode] ;
  2931.         unsigned short * oldattrmem = attrmem[vmode] ;
  2932.         unsigned short * oldhyperlinkmem = hyperlinkmem[vmode] ;
  2933.  
  2934.         memset(&TmpScrn,0,sizeof(TmpScrn));
  2935.         TmpScrn.linecount = newsize ;
  2936.         TmpScrn.lines = malloc(TmpScrn.linecount * sizeof(videoline)) ;
  2937.         if ( !TmpScrn.lines )
  2938.             fatal("VscrnSetBufferSize: unable to allocate memory for TmpScrn[].lines!");
  2939.         TmpScrn.beg = 0 ;
  2940.         TmpScrn.scrolltop = 0 ;
  2941.         TmpScrn.top = (vscrn[vmode].beg <= vscrn[vmode].top) ? (vscrn[vmode].top - vscrn[vmode].beg)
  2942.                             : (vscrn[vmode].top + vscrn[vmode].linecount - vscrn[vmode].beg) ;
  2943.         TmpScrn.end = (TmpScrn.top + vscrn[vmode].height - 1)%TmpScrn.linecount ;
  2944.         TmpScrn.cursor = vscrn[vmode].cursor ;
  2945.         TmpScrn.popup = vscrn[vmode].popup ;
  2946.         TmpScrn.marktop = TmpScrn.markbot = -1 ;
  2947.                 TmpScrn.width = vscrn[vmode].width ;
  2948.                 TmpScrn.height = vscrn[vmode].height ;
  2949.         for ( i = 0 ; i < 10 ; i++ )
  2950.            TmpScrn.bookmark[i] = (vscrn[vmode].beg <= vscrn[vmode].bookmark[i]) ?
  2951.               (vscrn[vmode].bookmark[i] - vscrn[vmode].beg) :
  2952.               ( vscrn[vmode].bookmark[i] + vscrn[vmode].linecount - vscrn[vmode].beg ) ;
  2953.  
  2954.         cellmem[vmode] = malloc( (TmpScrn.linecount + 1) * MAXTERMCOL * sizeof(viocell) ) ;
  2955.         if ( !cellmem[vmode] )
  2956.             fatal("VscrnSetBufferSize: unable to allocate memory for cellmem[]!");
  2957.         memcpy( cellmem[vmode], oldcellmem, (vscrn[vmode].linecount + 1)
  2958.                 * MAXTERMCOL * sizeof(viocell) ) ;
  2959.  
  2960.         attrmem[vmode] = malloc( (TmpScrn.linecount + 1) * MAXTERMCOL * sizeof(short) ) ;
  2961.         if ( !attrmem[vmode] )
  2962.             fatal("VscrnSetBufferSize: unable to allocate memory for attrmem[]!");
  2963.         memcpy( attrmem[vmode], oldattrmem, (vscrn[vmode].linecount + 1)
  2964.                 * MAXTERMCOL * sizeof(short) ) ;
  2965.  
  2966.         hyperlinkmem[vmode] = malloc( (TmpScrn.linecount + 1) * MAXTERMCOL * sizeof(short) ) ;
  2967.         if ( !hyperlinkmem[vmode] )
  2968.             fatal("VscrnSetBufferSize: unable to allocate memory for hyperlinkmem[]!");
  2969.         memcpy( hyperlinkmem[vmode], oldhyperlinkmem, (vscrn[vmode].linecount + 1)
  2970.                 * MAXTERMCOL * sizeof(short) ) ;
  2971.  
  2972.         for ( i=0 ; i<vscrn[vmode].linecount ; i++ ) {
  2973.             line = &vscrn[vmode].lines[(vscrn[vmode].beg+i)%vscrn[vmode].linecount] ;
  2974.             TmpScrn.lines[i].width = line->width ;
  2975.             line->width = 0 ;
  2976.             TmpScrn.lines[i].cells = line->cells + (cellmem[vmode] - oldcellmem) ;
  2977.             line->cells = NULL ;
  2978.             TmpScrn.lines[i].vt_char_attrs = line->vt_char_attrs
  2979.                 + (attrmem[vmode] - oldattrmem);
  2980.             line->vt_char_attrs = 0 ;
  2981.             TmpScrn.lines[i].hyperlinks = line->hyperlinks
  2982.                 + (hyperlinkmem[vmode] - oldhyperlinkmem);
  2983.             line->hyperlinks = 0 ;
  2984.             TmpScrn.lines[i].vt_line_attr = line->vt_line_attr ;
  2985.             line->vt_line_attr = 0 ;
  2986.             line->markbeg = -1 ;
  2987.             line->markshowend = -1 ;
  2988.             line->markend = -1 ;
  2989.         }
  2990.  
  2991.         for ( i ; i < TmpScrn.linecount ; i++ ) {
  2992.             TmpScrn.lines[i].width = 0 ;
  2993.             TmpScrn.lines[i].cells = cellmem[vmode] + (i+1) * MAXTERMCOL ;
  2994.             TmpScrn.lines[i].vt_char_attrs = attrmem[vmode] + (i+1) * MAXTERMCOL ;
  2995.             TmpScrn.lines[i].hyperlinks = hyperlinkmem[vmode] + (i+1) * MAXTERMCOL ;
  2996.             TmpScrn.lines[i].vt_line_attr = VT_LINE_ATTR_NORMAL ;
  2997.             TmpScrn.lines[i].markbeg = -1 ;
  2998.             TmpScrn.lines[i].markshowend = -1 ;
  2999.             TmpScrn.lines[i].markend = -1 ;
  3000.         }
  3001.  
  3002.         free(oldcellmem) ;
  3003.         free(oldattrmem) ;
  3004.         free(oldhyperlinkmem) ;
  3005.         free(vscrn[vmode].lines) ;
  3006.         vscrn[vmode] = TmpScrn ;
  3007.         }
  3008.  
  3009.     ReleaseVscrnMutex( vmode ) ;
  3010.  
  3011.     debug(F101,"SetBufferSize linecount","",vscrn[vmode].linecount);
  3012.     debug(F101,"SetBufferSize lines","",vscrn[vmode].lines);
  3013.     debug(F101,"SetBufferSize beg","",vscrn[vmode].beg);
  3014.     debug(F101,"SetBufferSize top","",vscrn[vmode].top);
  3015.     debug(F101,"SetBufferSize end","",vscrn[vmode].end);
  3016.     debug(F101,"SetBufferSize cursor.x","",vscrn[vmode].cursor.x);
  3017.     debug(F101,"SetBufferSize cursor.y","",vscrn[vmode].cursor.y);
  3018.  
  3019.     oldsize[vmode] = newsize ;
  3020.     return rc ;
  3021. }
  3022.  
  3023. /*---------------------------------------------------------------------------*/
  3024. /* VscrnScroll                                                               */
  3025. /*---------------------------------------------------------------------------*/
  3026. void
  3027. VscrnScroll(BYTE vmode, int updown, int topmargin, int bottommargin,
  3028.              int nlines, int savetobuffer, CHAR fillchar) {
  3029.     /* topmargin and bottommargin are zero based */
  3030.     viocell blankcell;
  3031.     videoline * line ;
  3032.     videoline   linetodelete ;
  3033.     int i,x;
  3034.     long  obeg, oend, otop, nbeg, nend, ntop ;
  3035.     unsigned char cellcolor = geterasecolor(vmode) ;
  3036.  
  3037.     if ( fillchar == NUL )
  3038.         fillchar = SP ;
  3039.  
  3040.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  3041.         vmode = VSTATUS ;
  3042.  
  3043.     blankcell.c = fillchar ;
  3044.     blankcell.a = cellcolor ;
  3045.  
  3046.     if ( updmode == TTU_SMOOTH )
  3047.         msleep(1) ;
  3048.  
  3049.     debug(F111,"VscrnScroll","vmode",vmode);
  3050.     debug(F111,"VscrnScroll","updown",updown);
  3051.     debug(F111,"VscrnScroll","topmargin",topmargin);
  3052.     debug(F111,"VscrnScroll","bottommargin",bottommargin);
  3053.  
  3054.     /* Wait for exclusive access to the screen */
  3055.     debug(F101,"VscrnScroll requests VscrnMutex","",vmode);
  3056.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  3057.  
  3058.     debug(F101,"VscrnScroll has VscrnMutex","",vmode);
  3059.     switch (updown) {
  3060.         case UPWARD:
  3061.             if (savetobuffer && topmargin == 0) {
  3062.                 if (topmargin)
  3063.                     {
  3064.                     debug(F101,"WARNING scroll: savetobuffer but topmargin not zero","",topmargin);
  3065.                     }
  3066.  
  3067.                 while ( scrollflag[vmode] && VscrnGetBegin(vmode) == VscrnGetScrollTop(vmode)
  3068.                     && (VscrnGetEnd(vmode)+1)%VscrnGetBufferSize(vmode) == VscrnGetBegin(vmode) ) {
  3069.                     ReleaseVscrnMutex(vmode);
  3070.                     msleep(1000);  /* give up time slice and wait for room */
  3071.                     RequestVscrnMutex(vmode,SEM_INDEFINITE_WAIT);
  3072.                     }
  3073.  
  3074.                 obeg = VscrnGetBegin(vmode) ;
  3075.                 oend = VscrnGetEnd(vmode) ;
  3076.                 if ( oend < obeg )
  3077.                     oend += VscrnGetBufferSize(vmode) ;
  3078.                 otop = VscrnGetTop(vmode) ;
  3079.                 if ( otop < obeg )
  3080.                     otop += VscrnGetBufferSize(vmode) ;
  3081.  
  3082.                 ntop = otop + nlines ;
  3083.  
  3084.                 if ( ntop + VscrnGetHeight(vmode)
  3085.                                         -(tt_status[vmode]?2:1) > oend ) {
  3086.                     nend = ntop + VscrnGetHeight(vmode)
  3087.                                                 -(tt_status[vmode]?2:1) ;
  3088.                     VscrnSetEnd( vmode, nend ) ;
  3089.                     if ( obeg > 0 || obeg == 0 && nend >= VscrnGetBufferSize(vmode) - 1 ) {
  3090.                         nbeg = VscrnSetBegin( vmode,nend + 1 ) ;
  3091.                         }
  3092.                     }
  3093.  
  3094.                 for ( i = 0 ; i < nlines ; i++ ) {
  3095.                     line = VscrnGetLineFromTop(vmode,VscrnGetHeight(vmode)+i
  3096.                                                 -(tt_status[vmode]?1:0)) ;
  3097.                     if (line == NULL || line->cells == NULL) {
  3098.                         debug(F100,"VscrnScroll to buffer - line->cells = NULL","",0);
  3099.                         break;
  3100.                         }
  3101.                     if (line->vt_char_attrs == NULL) {
  3102.                         debug(F100,"VscrnScroll to buffer - line->vt_char_attrs = NULL","",0);
  3103.                         break;
  3104.                         }
  3105.                     line->width = VscrnGetWidth(vmode)  ;
  3106.                     line->vt_line_attr = VT_LINE_ATTR_NORMAL ;
  3107.                     for ( x = 0 ; x < MAXTERMCOL ; x++ )
  3108.                         {
  3109.                         line->cells[x] = blankcell ;
  3110.                         line->vt_char_attrs[x] = VT_CHAR_ATTR_NORMAL ;
  3111.                         }
  3112.                     }
  3113.  
  3114.                 VscrnSetTop( vmode,ntop ) ;
  3115.                 if ( bottommargin != VscrnGetHeight(vmode)
  3116.                                         -(tt_status[vmode]?2:1) )
  3117.                     VscrnScroll(vmode,DOWNWARD, bottommargin, VscrnGetHeight(vmode)
  3118.                                  -(tt_status[vmode]?2:1), 1, FALSE, fillchar) ;
  3119.                 }
  3120.             else {
  3121.                 for ( i = topmargin ; i <= bottommargin - nlines ; i++ ) {
  3122.                     /* save line to be deleted */
  3123.                     linetodelete = *VscrnGetLineFromTop(vmode,i) ;
  3124.  
  3125.                     /* then copy back a line */
  3126.                     line = VscrnGetLineFromTop(vmode,nlines+i) ;
  3127.                     if ( line == NULL )
  3128.                         break;
  3129.                     vscrn[vmode].lines[(vscrn[vmode].top+i)%vscrn[vmode].linecount] = *line ;
  3130.                     line->cells = linetodelete.cells ;
  3131.                     line->vt_char_attrs = linetodelete.vt_char_attrs ;
  3132.                     }
  3133.  
  3134.                 for ( i = nlines-1 ; i >= 0 ; i-- ) {
  3135.                     line = VscrnGetLineFromTop(vmode,bottommargin-i) ;
  3136.                     if (line == NULL || line->cells == NULL) {
  3137.                         debug(F100,"VscrnScroll to buffer - line->cells = NULL","",0);
  3138.                         }
  3139.                     if (line->vt_char_attrs == NULL) {
  3140.                         debug(F100,"VscrnScroll to buffer - line->vt_char_attrs = NULL","",0);
  3141.                         }
  3142.                     line->width = VscrnGetWidth(vmode)  ;
  3143.                     line->vt_line_attr = VT_LINE_ATTR_NORMAL ;
  3144.                     for ( x = 0 ; x < MAXTERMCOL ; x++ )
  3145.                         {
  3146.                         line->cells[x] = blankcell ;
  3147.                         line->vt_char_attrs[x] = VT_CHAR_ATTR_NORMAL ;
  3148.                         }
  3149.                     }
  3150.                 }
  3151. #ifndef NOKVERBS
  3152.             if ( scrollstatus[vmode] && !tt_roll[vmode] && !markmodeflag[vmode] ) {
  3153.                 if ( (VscrnGetTop(vmode)+VscrnGetHeight(vmode)
  3154.                                         -(tt_status[vmode]?2:1))%VscrnGetBufferSize(vmode)
  3155.                     == VscrnGetEnd(vmode) )
  3156.                     putkverb( vmode, K_ENDSCN ) ;
  3157.                 }
  3158. #endif /* NOKVERBS */
  3159.             break;
  3160.  
  3161.         case DOWNWARD:
  3162.             for ( i = bottommargin ; i >= topmargin+nlines ; i-- ) {
  3163.                 /* save line to be deleted */
  3164.                 linetodelete = *VscrnGetLineFromTop(vmode,i) ;
  3165.  
  3166.                 /* then copy back a line */
  3167.                 line = VscrnGetLineFromTop(vmode,i-nlines) ;
  3168.                 if ( line == NULL )
  3169.                     break;
  3170.                 vscrn[vmode].lines[(vscrn[vmode].top+i)%vscrn[vmode].linecount] = *line ;
  3171.                 line->cells = linetodelete.cells ;
  3172.                 line->vt_char_attrs = linetodelete.vt_char_attrs ;
  3173.                 }
  3174.  
  3175.             for ( i = 0 ; i < nlines ; i++ ) {
  3176.                 line = VscrnGetLineFromTop(vmode,topmargin+i) ;
  3177.                 if (line == NULL || line->cells == NULL) {
  3178.                     debug(F100,"VscrnScroll to buffer - line->cells = NULL","",0);
  3179.                     }
  3180.                 if (line->vt_char_attrs == NULL) {
  3181.                     debug(F100,"VscrnScroll to buffer - line->vt_char_attrs = NULL","",0);
  3182.                     }
  3183.                 line->width = VscrnGetWidth(vmode)  ;
  3184.                 line->vt_line_attr = VT_LINE_ATTR_NORMAL ;
  3185.                 for ( x = 0 ; x < MAXTERMCOL ; x++ )
  3186.                     {
  3187.                     line->cells[x] = blankcell ;
  3188.                     line->vt_char_attrs[x] = VT_CHAR_ATTR_NORMAL ;
  3189.                     }
  3190.                 }
  3191.                 break;
  3192.  
  3193.         default: /* ignore */ ;
  3194.     }
  3195.     ReleaseVscrnMutex( vmode ) ;
  3196.     debug(F100,"VscrnScroll releases mutex","",0);
  3197. }
  3198.  
  3199.  
  3200. /*---------------------------------------------------------------------------*/
  3201. /* VscrnMark                                                                 */
  3202. /*---------------------------------------------------------------------------*/
  3203. void
  3204. VscrnMark( BYTE vmode, LONG y, SHORT xbeg, SHORT xend )
  3205. {
  3206.     int x ;
  3207.     LONG yy, marktop, markbot, beg, end ;
  3208.  
  3209.     if ( xbeg < 0 || xend < 0 )
  3210.         return ;
  3211.  
  3212.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  3213.         vmode = VSTATUS ;
  3214.  
  3215.     if ( vscrn[vmode].lines == NULL )
  3216.         return;
  3217.  
  3218.     while ( y < 0 )
  3219.         y += vscrn[vmode].linecount ;
  3220.     y = y%vscrn[vmode].linecount ;
  3221.  
  3222.     if ( xend >= vscrn[vmode].lines[y].width )
  3223.         xend = vscrn[vmode].lines[y].width-1 ;
  3224.  
  3225.     yy = ( y - vscrn[vmode].beg + vscrn[vmode].linecount ) % vscrn[vmode].linecount ;
  3226.     beg = 0 ;
  3227.     end = ( vscrn[vmode].end - vscrn[vmode].beg + vscrn[vmode].linecount ) % vscrn[vmode].linecount ;
  3228.     marktop = ( vscrn[vmode].marktop - vscrn[vmode].beg + vscrn[vmode].linecount ) % vscrn[vmode].linecount ;
  3229.     markbot = ( vscrn[vmode].markbot - vscrn[vmode].beg + vscrn[vmode].linecount ) % vscrn[vmode].linecount ;
  3230.  
  3231.     if ( vscrn[vmode].marktop == -1 || vscrn[vmode].markbot == -1 )
  3232.     {
  3233.        vscrn[vmode].marktop = vscrn[vmode].markbot = y ;
  3234.        vscrn[vmode].lines[y].markbeg = xbeg ;
  3235.        vscrn[vmode].lines[y].markend = xend ;
  3236.     }
  3237.     else
  3238.     {
  3239.         if ( yy >= marktop && yy <= markbot ) {
  3240.             if ( vscrn[vmode].lines[y].markbeg == -1 ||
  3241.                 xbeg < vscrn[vmode].lines[y].markbeg )
  3242.                 vscrn[vmode].lines[y].markbeg = xbeg ;
  3243.             if ( vscrn[vmode].lines[y].markend == -1 ||
  3244.                 xend > vscrn[vmode].lines[y].markend )
  3245.                 vscrn[vmode].lines[y].markend = xend ;
  3246.             }
  3247.         else {
  3248.             if ( yy < marktop ) {
  3249.                 vscrn[vmode].marktop = y ;
  3250.                 }
  3251.             else {
  3252.                 vscrn[vmode].markbot = y ;
  3253.                 }
  3254.             vscrn[vmode].lines[y].markbeg = xbeg ;
  3255.             vscrn[vmode].lines[y].markend = xend ;
  3256.             }
  3257.         }
  3258.  
  3259.     vscrn[vmode].lines[y].markshowend = vscrn[vmode].lines[y].markend ;
  3260.     if ( vscrn[vmode].lines[y].markend >= 0 &&
  3261.         vscrn[vmode].lines[y].markbeg >= 0 ) {
  3262.         for ( x = vscrn[vmode].lines[y].markend ; x >= vscrn[vmode].lines[y].markbeg ; x-- ) {
  3263.             if (vscrn[vmode].lines[y].cells[x].c == ' ')
  3264.                 vscrn[vmode].lines[y].markshowend-- ;
  3265.             else
  3266.                 break ;
  3267.             }
  3268.         }
  3269.  
  3270.     if ( vscrn[vmode].lines[y].markshowend < vscrn[vmode].lines[y].markbeg )
  3271.             vscrn[vmode].lines[y].markshowend = -1 ;
  3272. }
  3273.  
  3274. /*---------------------------------------------------------------------------*/
  3275. /* VscrnUnmark                                                               */
  3276. /*---------------------------------------------------------------------------*/
  3277. void
  3278. VscrnUnmark( BYTE vmode, LONG y, SHORT xbeg, SHORT xend )
  3279. {
  3280.     int x ;
  3281.  
  3282.     if ( xbeg < 0 || xend < 0 )
  3283.         return ;
  3284.  
  3285.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  3286.         vmode = VSTATUS ;
  3287.  
  3288.     if ( vscrn[vmode].lines == NULL )
  3289.         return;
  3290.  
  3291.     while ( y < 0 )
  3292.         y += vscrn[vmode].linecount ;
  3293.     y = y%vscrn[vmode].linecount ;
  3294.  
  3295.     if ( vscrn[vmode].marktop != -1 && vscrn[vmode].markbot != -1 ) {
  3296.         if ( vscrn[vmode].marktop <= vscrn[vmode].markbot ) {
  3297.             if ( y >= vscrn[vmode].marktop && y <= vscrn[vmode].markbot ) {
  3298.                 if ( xbeg <= vscrn[vmode].lines[y].markbeg && xend >= vscrn[vmode].lines[y].markend )
  3299.                     vscrn[vmode].lines[y].markbeg = vscrn[vmode].lines[y].markend = -1 ;
  3300.                 else if ( xbeg <= vscrn[vmode].lines[y].markbeg && xend < vscrn[vmode].lines[y].markend )
  3301.                     vscrn[vmode].lines[y].markbeg = xend + 1 ;
  3302.                 else if ( xbeg > vscrn[vmode].lines[y].markbeg && xend >= vscrn[vmode].lines[y].markend )
  3303.                     vscrn[vmode].lines[y].markend = xbeg - 1 ;
  3304.                 }
  3305.             }
  3306.         else {
  3307.             if ( y >= vscrn[vmode].marktop || y <= vscrn[vmode].markbot ) {
  3308.                 if ( xbeg <= vscrn[vmode].lines[y].markbeg && xend >= vscrn[vmode].lines[y].markend )
  3309.                     vscrn[vmode].lines[y].markbeg = vscrn[vmode].lines[y].markend = -1 ;
  3310.                 else if ( xbeg <= vscrn[vmode].lines[y].markbeg && xend < vscrn[vmode].lines[y].markend )
  3311.                     vscrn[vmode].lines[y].markbeg = xend + 1 ;
  3312.                 else if ( xbeg > vscrn[vmode].lines[y].markbeg && xend >= vscrn[vmode].lines[y].markend )
  3313.                     vscrn[vmode].lines[y].markend = xbeg - 1 ;
  3314.                 }
  3315.             }
  3316.  
  3317.         if ( y == vscrn[vmode].marktop &&
  3318.             y == vscrn[vmode].markbot &&
  3319.             vscrn[vmode].lines[y].markbeg == -1 &&
  3320.             vscrn[vmode].lines[y].markend == -1 )
  3321.             vscrn[vmode].marktop = vscrn[vmode].markbot = -1 ;  /* marktop,markbot are long */
  3322.         else if ( y == vscrn[vmode].marktop &&
  3323.             vscrn[vmode].lines[y].markbeg == -1 &&
  3324.             vscrn[vmode].lines[y].markend == -1 )
  3325.             vscrn[vmode].marktop = (vscrn[vmode].marktop+1)%vscrn[vmode].linecount ;
  3326.         else if ( y == vscrn[vmode].markbot &&
  3327.             vscrn[vmode].lines[y].markbeg == -1 &&
  3328.             vscrn[vmode].lines[y].markend == -1 )
  3329.             vscrn[vmode].markbot = (vscrn[vmode].markbot-1+vscrn[vmode].linecount)%vscrn[vmode].linecount ;
  3330.         }
  3331.  
  3332.     vscrn[vmode].lines[y].markshowend = vscrn[vmode].lines[y].markend ;
  3333.     if ( vscrn[vmode].lines[y].markend >= 0 &&
  3334.         vscrn[vmode].lines[y].markbeg >= 0 ) {
  3335.         for ( x = vscrn[vmode].lines[y].markend ; x >= vscrn[vmode].lines[y].markbeg ; x-- ) {
  3336.             if (vscrn[vmode].lines[y].cells[x].c == ' ')
  3337.                 vscrn[vmode].lines[y].markshowend-- ;
  3338.             else
  3339.                 break ;
  3340.             }
  3341.         }
  3342.  
  3343.     if ( vscrn[vmode].lines[y].markshowend < vscrn[vmode].lines[y].markbeg )
  3344.             vscrn[vmode].lines[y].markshowend = -1 ;
  3345. }
  3346.  
  3347. /*---------------------------------------------------------------------------*/
  3348. /* VscrnUnmarkAll                                                            */
  3349. /*---------------------------------------------------------------------------*/
  3350. void
  3351. VscrnUnmarkAll( BYTE vmode )
  3352. {
  3353.     long y ;
  3354.  
  3355.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  3356.         vmode = VSTATUS ;
  3357.  
  3358.     if ( vscrn[vmode].lines == NULL )
  3359.         return;
  3360.  
  3361.     if ( vscrn[vmode].marktop != -1 && vscrn[vmode].markbot != -1 ) {
  3362.         if ( vscrn[vmode].marktop <= vscrn[vmode].markbot ) {
  3363.             for ( y = vscrn[vmode].marktop ; y <= vscrn[vmode].markbot ; y++ )
  3364.                 vscrn[vmode].lines[y].markbeg =
  3365.                     vscrn[vmode].lines[y].markshowend =
  3366.                     vscrn[vmode].lines[y].markend = -1 ;
  3367.             }
  3368.         else {
  3369.             for ( y = vscrn[vmode].marktop ; y < vscrn[vmode].linecount ; y++ )
  3370.                 vscrn[vmode].lines[y].markbeg =
  3371.                     vscrn[vmode].lines[y].markshowend =
  3372.                     vscrn[vmode].lines[y].markend = -1 ;
  3373.             for ( y = 0 ; y <= vscrn[vmode].markbot ; y++ )
  3374.                 vscrn[vmode].lines[y].markbeg =
  3375.                     vscrn[vmode].lines[y].markshowend =
  3376.                     vscrn[vmode].lines[y].markend = -1 ;
  3377.             }
  3378.         }
  3379.     vscrn[vmode].marktop = vscrn[vmode].markbot = -1 ;
  3380. }
  3381.  
  3382. /*---------------------------------------------------------------------------*/
  3383. /* VscrnIsLineMarked                                                         */
  3384. /*---------------------------------------------------------------------------*/
  3385. BOOL
  3386. VscrnIsLineMarked( BYTE vmode, LONG y )
  3387. {
  3388.     BOOL rc = FALSE ;
  3389.  
  3390.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  3391.         vmode = VSTATUS ;
  3392.  
  3393.     if ( vscrn[vmode].lines == NULL )
  3394.         return rc;
  3395.  
  3396.     if ( vscrn[vmode].marktop != -1 && vscrn[vmode].markbot != -1 ) {
  3397.         while ( y < 0 )
  3398.             y += vscrn[vmode].linecount ;
  3399.         y = y%vscrn[vmode].linecount ;
  3400.  
  3401.         if ( vscrn[vmode].marktop <= vscrn[vmode].markbot ) {
  3402.             rc = ( y >= vscrn[vmode].marktop && y <= vscrn[vmode].markbot ) ;
  3403.             }
  3404.         else {
  3405.             rc = ( y >= vscrn[vmode].marktop || y <= vscrn[vmode].markbot ) ;
  3406.             }
  3407.         }
  3408.  
  3409.     return rc ;
  3410. }
  3411.  
  3412. /*---------------------------------------------------------------------------*/
  3413. /* VscrnIsMarked                                                             */
  3414. /*---------------------------------------------------------------------------*/
  3415. BOOL
  3416. VscrnIsMarked( BYTE vmode, LONG y, SHORT x )
  3417. {
  3418.     BOOL rc = FALSE ;
  3419.  
  3420.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  3421.         vmode = VSTATUS ;
  3422.  
  3423.     if ( vscrn[vmode].lines == NULL )
  3424.         return rc;
  3425.  
  3426.     if ( vscrn[vmode].marktop != -1 && vscrn[vmode].markbot != -1 ) {
  3427.         while ( y < 0 )
  3428.             y += vscrn[vmode].linecount ;
  3429.         y = y%vscrn[vmode].linecount ;
  3430.  
  3431.         if ( vscrn[vmode].marktop <= vscrn[vmode].markbot ) {
  3432.             rc = ( y >= vscrn[vmode].marktop && y <= vscrn[vmode].markbot &&
  3433.                 x >= vscrn[vmode].lines[y].markbeg && x <= vscrn[vmode].lines[y].markend ) ;
  3434.             }
  3435.         else {
  3436.             rc = ( ( y >= vscrn[vmode].marktop || y <= vscrn[vmode].markbot ) &&
  3437.                 x >= vscrn[vmode].lines[y].markbeg && x <= vscrn[vmode].lines[y].markend ) ;
  3438.             }
  3439.         }
  3440.  
  3441.     return rc ;
  3442. }
  3443.  
  3444. /*---------------------------------------------------------------------------*/
  3445. /* VscrnIsPopup                                                              */
  3446. /*---------------------------------------------------------------------------*/
  3447. bool
  3448. VscrnIsPopup( BYTE vmode )
  3449. {
  3450. #ifdef COMMENT
  3451.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  3452.         vmode = VSTATUS ;
  3453. #endif
  3454.     return ( vscrn[vmode].popup != NULL ) ;
  3455. }
  3456.  
  3457. /*---------------------------------------------------------------------------*/
  3458. /* VscrnSetPopup                                                             */
  3459. /*---------------------------------------------------------------------------*/
  3460. void
  3461. VscrnSetPopup( BYTE vmode, videopopup * pu )
  3462. {
  3463.     if ( vmode == VTERM && decsasd == SASD_STATUS )
  3464.         vmode = VSTATUS ;
  3465.  
  3466.     /* Wait for exclusive access to the screen */
  3467.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  3468.  
  3469.     if ( vscrn[vmode].popup != NULL )
  3470.         free(vscrn[vmode].popup);
  3471.     vscrn[vmode].popup = pu;
  3472.     ReleaseVscrnMutex(vmode);
  3473.     VscrnIsDirty(vmode);
  3474.  
  3475.     if ( vmode == VTERM )
  3476.         puterror(VTERM);
  3477.     msleep(1);
  3478. }
  3479.  
  3480. /*---------------------------------------------------------------------------*/
  3481. /* ResetPopup                                                                */
  3482. /*---------------------------------------------------------------------------*/
  3483. void
  3484. VscrnResetPopup( BYTE vmode )
  3485. {
  3486.     /* Wait for exclusive access to the screen */
  3487.     RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  3488.  
  3489.     if ( vscrn[vmode].popup != NULL )
  3490.         free(vscrn[vmode].popup) ;
  3491.     vscrn[vmode].popup = NULL ;
  3492.     ReleaseVscrnMutex(vmode) ;
  3493.     VscrnIsDirty(vmode) ;
  3494.     msleep(1);
  3495. }
  3496.  
  3497. /*
  3498.  * IsCellPartOfURL()
  3499.  */
  3500.  
  3501. int
  3502. IsURLChar( USHORT ch )
  3503. {
  3504. #ifdef COMMENT
  3505.     if (ch && (isalnum(ch) || ch == '/' || ch == ':' || ch == '.' || ch == '#' ||
  3506.                 ch == '|' || ch == '@' || ch == '!' || ch == '-' || ch == '_' ||
  3507.                 ch == '?' || ch == '%' || ch == '&' || ch == '+' || ch == '\\' ||
  3508.                 ch == '=' || ch == ';' || ch == '~' || ch == ',' || ch == '$'))
  3509.     {
  3510.         return 1;
  3511.     } else {
  3512.         return 0;
  3513.     }
  3514. #else /* COMMENT */
  3515.     if ( ch <= 32 )
  3516.         return 0;
  3517.     switch ( ch ) {
  3518.     case 127:
  3519.     case '<':
  3520.     case '>':
  3521.     case '[':
  3522.     case ']':
  3523.     case '{':
  3524.     case '}':
  3525.     case '\'':
  3526.     case '"':
  3527.     case '`':
  3528.     case '^':
  3529.         return 0;
  3530.     default:
  3531.         return 1;
  3532.     }
  3533. #endif /* COMMENT */
  3534. }
  3535.  
  3536. int
  3537. IsCellPartOfURL( BYTE mode, USHORT row, USHORT col )
  3538. {
  3539.     videoline * line=NULL;
  3540.     viocell * cells = NULL;
  3541.     register char ch;
  3542.     static char str[MAXTERMSIZE];
  3543.     int i,j,len=0, first=1, rc;
  3544.     extern bool scrollflag[] ;
  3545.     extern char browsurl[];
  3546.     /* Let's cache these values */
  3547.     static int retval = 0;
  3548.     static int brow=-1, bcol=-1, erow=-1, ecol=-1, _mode=-1;
  3549.  
  3550.     if ( mode == _mode ) {
  3551.         if ( row == brow && col >= bcol ) {
  3552.             if ( row == erow && col <= ecol || row < erow ) {
  3553.                 return(retval);
  3554.             }
  3555.         } else if ( row == erow && col <= ecol ) {
  3556.             if ( row > brow ) {
  3557.                 return(retval);
  3558.             }
  3559.             else if ( row > brow && row < erow ) {
  3560.                 return(retval);
  3561.             }
  3562.         }
  3563.     }
  3564.     /* From the current row,col we need to determine which line contains
  3565.        the beginning and end of the string we think might contain a URL.
  3566.  
  3567.        Compute the length of the string
  3568.  
  3569.        Then copy the whole string into a temporary buffer
  3570.  
  3571.      */
  3572.  
  3573.     /* Find the beginning of the URL */
  3574.  
  3575.     _mode = mode;
  3576.     brow = erow = row;
  3577.     bcol = ecol = col;
  3578.  
  3579.     rc = RequestVscrnMutex( mode, SEM_INDEFINITE_WAIT ) ;
  3580.     if ( scrollflag[mode] )
  3581.         line = VscrnGetLine( mode, VscrnGetScrollTop(mode) + brow );
  3582.     else
  3583.         line = VscrnGetLineFromTop( mode, brow );
  3584.     rc = ReleaseVscrnMutex( mode ) ;
  3585.     if ( !line || line->width == 0 )
  3586.         return(retval = 0);
  3587.     cells = line->cells;
  3588.  
  3589.     while(1) {
  3590.         while ( bcol >= 0 ) {
  3591.             if ( IsURLChar(cells[bcol].c) ) {
  3592.                 bcol--;
  3593.             } else {
  3594.                 if (first)
  3595.                     return(retval = 0);
  3596.  
  3597.                 bcol++;
  3598.                 if ( bcol >= line->width ) {
  3599.                     bcol = 0;
  3600.                     brow++;
  3601.                 }
  3602.                 goto bfound;
  3603.             }
  3604.             first = 0;
  3605.         }
  3606.  
  3607.         if ( brow == 0 ) {
  3608.             if ( bcol < 0 )
  3609.                 bcol = 0;
  3610.             goto bfound;
  3611.         }
  3612.  
  3613.         brow--;
  3614.         rc = RequestVscrnMutex( mode, SEM_INDEFINITE_WAIT ) ;
  3615.         if ( scrollflag[mode] )
  3616.             line = VscrnGetLine( mode, VscrnGetScrollTop(mode) + brow );
  3617.         else
  3618.             line = VscrnGetLineFromTop( mode, brow );
  3619.         rc = ReleaseVscrnMutex( mode ) ;
  3620.         if ( !line || line->width == 0 )
  3621.             return(retval = 0);
  3622.         cells = line->cells;
  3623.         bcol = line->width-1;
  3624.     }
  3625.   bfound:
  3626.  
  3627.     /* Find the end of the URL */
  3628.     rc = RequestVscrnMutex( mode, SEM_INDEFINITE_WAIT ) ;
  3629.     if ( scrollflag[mode] )
  3630.         line = VscrnGetLine( mode, VscrnGetScrollTop(mode) + erow );
  3631.     else
  3632.         line = VscrnGetLineFromTop( mode, erow );
  3633.     rc = ReleaseVscrnMutex( mode ) ;
  3634.     if ( !line || line->width == 0 )
  3635.         return(retval = 0);
  3636.     cells = line->cells;
  3637.  
  3638.     while(1) {
  3639.         while ( ecol < line->width ) {
  3640.             if (IsURLChar(cells[ecol].c)) {
  3641.                 ecol++;
  3642.             } else {
  3643.                 ecol--;
  3644.                 if ( ecol < 0 ) {
  3645.                     erow--;
  3646.                     rc = RequestVscrnMutex( mode, SEM_INDEFINITE_WAIT ) ;
  3647.                     if ( scrollflag[mode] )
  3648.                         line = VscrnGetLine( mode, VscrnGetScrollTop(mode) + erow );
  3649.                     else
  3650.                         line = VscrnGetLineFromTop( mode, erow );
  3651.                     rc = ReleaseVscrnMutex( mode ) ;
  3652.                     if ( !line || line->width == 0 )
  3653.                         return(retval = 0);
  3654.                     cells = line->cells;
  3655.                     ecol = line->width - 1;
  3656.                 }
  3657.                 ch  = (CHAR) cells[ecol].c;
  3658.                 if (ch == '.' || ch == ',' || ch == ';') {
  3659.                     ecol--;
  3660.                     if ( erow == row && ecol < col )
  3661.                         return(retval = 0);
  3662.                     if ( ecol < 0 ) {
  3663.                         erow--;
  3664.                         rc = RequestVscrnMutex( mode, SEM_INDEFINITE_WAIT ) ;
  3665.                         if ( scrollflag[mode] )
  3666.                             line = VscrnGetLine( mode, VscrnGetScrollTop(mode) + erow );
  3667.                         else
  3668.                             line = VscrnGetLineFromTop( mode, erow );
  3669.                         rc = ReleaseVscrnMutex( mode ) ;
  3670.                         if ( !line || line->width == 0 )
  3671.                             return(retval = 0);
  3672.                         cells = line->cells;
  3673.                         ecol = line->width - 1;
  3674.                     }
  3675.                 }
  3676.                 goto efound;
  3677.             }
  3678.         }
  3679.  
  3680.         if ( erow == VscrnGetHeight(vmode)-(tt_status[vmode]?1:0) )
  3681.             goto efound;
  3682.  
  3683.         erow++;
  3684.         rc = RequestVscrnMutex( mode, SEM_INDEFINITE_WAIT ) ;
  3685.         if ( scrollflag[mode] )
  3686.             line = VscrnGetLine( mode, VscrnGetScrollTop(mode) + erow );
  3687.         else
  3688.             line = VscrnGetLineFromTop( mode, erow );
  3689.         rc = ReleaseVscrnMutex( mode ) ;
  3690.         if ( !line || line->width == 0 )
  3691.             return(retval = 0);
  3692.         cells = line->cells;
  3693.         ecol = 0;
  3694.     }
  3695.   efound:
  3696.  
  3697.     /* We now copy the cells to a string buffer so that we can determine */
  3698.     /* whether or not the URL has the proper prefix.  But we are never   */
  3699.     /* going to need more than a dozen characters for the comparison, so */
  3700.     /* stop after 12. */
  3701. #define URL_PREFIX_LEN 12
  3702.  
  3703.     str[0] = '\0';
  3704.  
  3705.     if ( brow == erow ) {
  3706.         rc = RequestVscrnMutex( mode, SEM_INDEFINITE_WAIT ) ;
  3707.         if ( scrollflag[mode] )
  3708.             line = VscrnGetLine( mode, VscrnGetScrollTop(mode) + brow );
  3709.         else
  3710.             line = VscrnGetLineFromTop( mode, brow );
  3711.         rc = ReleaseVscrnMutex( mode ) ;
  3712.         cells = line->cells;
  3713.  
  3714.         for ( i=bcol,len=0;i<=ecol && len<URL_PREFIX_LEN;i++,len++ )
  3715.             str[len] = (CHAR) cells[i].c;
  3716.         str[len] = '\0';
  3717.     } else {
  3718.         /* handle the first row - bcol to end */
  3719.         rc = RequestVscrnMutex( mode, SEM_INDEFINITE_WAIT ) ;
  3720.         if ( scrollflag[mode] )
  3721.             line = VscrnGetLine( mode, VscrnGetScrollTop(mode) + brow );
  3722.         else
  3723.             line = VscrnGetLineFromTop( mode, brow );
  3724.         rc = ReleaseVscrnMutex( mode ) ;
  3725.         cells = line->cells;
  3726.  
  3727.         for ( i=bcol,len=0;i<line->width  && len<URL_PREFIX_LEN;i++,len++ )
  3728.             str[len] = (CHAR) cells[i].c;
  3729.  
  3730.         /* handle the complete rows if there are any */
  3731.         for ( j=brow+1; j<erow; j++ ) {
  3732.             rc = RequestVscrnMutex( mode, SEM_INDEFINITE_WAIT ) ;
  3733.             if ( scrollflag[mode] )
  3734.                 line = VscrnGetLine( mode, VscrnGetScrollTop(mode) + j );
  3735.             else
  3736.                 line = VscrnGetLineFromTop( mode, j );
  3737.             rc = ReleaseVscrnMutex( mode ) ;
  3738.             cells = line->cells;
  3739.  
  3740.             for ( i=0;i<line->width  && len<URL_PREFIX_LEN;i++,len++ )
  3741.                 str[len] = (CHAR) cells[i].c;
  3742.         }
  3743.  
  3744.         /* handle the last row - begin to ecol */
  3745.         rc = RequestVscrnMutex( mode, SEM_INDEFINITE_WAIT ) ;
  3746.         if ( scrollflag[mode] )
  3747.             line = VscrnGetLine( mode, VscrnGetScrollTop(mode) + erow );
  3748.         else
  3749.             line = VscrnGetLineFromTop( mode, erow );
  3750.         rc = ReleaseVscrnMutex( mode ) ;
  3751.         cells = line->cells;
  3752.  
  3753.         for ( i=0;i<=ecol && len<URL_PREFIX_LEN;i++,len++ )
  3754.             str[len] = (CHAR) cells[i].c;
  3755.         str[len] = '\0';
  3756.     }
  3757.  
  3758.     if (len == 0)
  3759.         return(retval = 0);
  3760.  
  3761.     if ( strnicmp(str,"telnet://",9) &&
  3762.          strnicmp(str,"ssh://",6)  &&
  3763.          strnicmp(str,"login://",8)  &&
  3764.          strnicmp(str,"http://",7) &&
  3765.          strnicmp(str,"gopher://",9) &&
  3766.          strnicmp(str,"news://",7) &&
  3767.          strnicmp(str,"snews://",8) &&
  3768.          strnicmp(str,"ftp://",6) &&
  3769.          strnicmp(str,"mailto:",7) &&
  3770.          strnicmp(str,"https://",8) &&
  3771.          strnicmp(str,"ftps://",7) &&
  3772.          strnicmp(str,"telnets://",10) &&
  3773.          strnicmp(str,"iksd://",7) &&
  3774.          strnicmp(str,"kermit://",9) )
  3775.     {
  3776. #ifdef HIGHLIGHT_MAILTO
  3777.         int mailto = 0;
  3778.  
  3779.         for ( i=0;i<len;i++ )
  3780.         {
  3781.             if ( !mailto && str[i] == '@' ) {
  3782.                 mailto = 1;
  3783.             }
  3784.             else if ( mailto ) {
  3785.                 switch ( str[i] ) {
  3786.                 case '@':
  3787.                 case ',':
  3788.                 case '/':
  3789.                 case '\\':
  3790.                 case '$':
  3791.                 case '?':
  3792.                 case '|':
  3793.                 case '!':
  3794.                     mailto = 0 ;
  3795.                     break;      /* switch */
  3796.                 }
  3797.                 if ( !mailto )
  3798.                     break;      /* for */
  3799.             }
  3800.         }
  3801.         if ( mailto && str[len-1] != '@' && str[0] != '@' )
  3802.             retval = 1;
  3803.         else
  3804. #endif /* HIGHLIGHT_MAILTO */
  3805.             retval = 0;
  3806.     } else
  3807.         retval = 1;
  3808.  
  3809.     return(retval);
  3810. }
  3811.  
  3812. /*---------------------------------------------------------------------------*/
  3813. /* TermScrnUpd                                                               */
  3814. /*---------------------------------------------------------------------------*/
  3815. #define URLMINCNT 4096
  3816. #define NEW_EXCLUSIVE 1
  3817. void
  3818. TermScrnUpd( void * threadinfo)
  3819. {
  3820.     viocell * thecells = NULL, defaultcell, defaultflipcell ;
  3821.     videoline * line ;
  3822.     viocell   *pScell, *pDcell;
  3823.     unsigned short vt_char_attrs;
  3824.     unsigned short xs, ys, c, x, y,
  3825.                    xho,                 /* horizontal scrolling offset */
  3826.                    xo, yo ;             /* offsets for Popup positioning */
  3827.     position cursor ;
  3828.     char buffer[MAXTERMCOL+1] ;
  3829.     APIRET rc ;
  3830.     char * status ;
  3831.     int cursor_offset = 0 ;
  3832.     int blinking = 0 ;          /* Screen contains something that blinks */
  3833.     int blinkon  = 0 ;          /* Blinking items are showing            */
  3834.     int dirty    = 0 ;          /* is vscrn dirty? */
  3835.     extern int colorreset;
  3836.     extern int trueblink;
  3837.     extern int screenon ;
  3838. #ifdef NT
  3839.     extern HANDLE KbdHandle ;
  3840.     DWORD conmode ;
  3841. #endif /* NT */
  3842.     extern int decssdt ;
  3843.     extern char hoststatusline[] ;
  3844.     extern int tt_modechg;
  3845.     int old_tt_update ;
  3846.     int avm ;                           /* Active vmode */
  3847.     int prty = priority;
  3848. #ifndef KUI
  3849.     CK_VIDEOMODEINFO mi;
  3850. #endif /* KUI */
  3851.     int incnt = 0;
  3852.  
  3853. #ifndef ONETERMUPD
  3854.     vmode = VTERM ;
  3855. #endif /* ONETERMUPD */
  3856.  
  3857.     PostTermScrnUpdThreadSem();
  3858. #ifdef NT
  3859.     setint();
  3860.     rc = SetThreadPrty(priority,isWin95() ? /* 3, 1 */ 2 : 11);
  3861. #else
  3862.     rc = SetThreadPrty(priority,4);
  3863. #endif
  3864.  
  3865.     rc = CreateVscrnTimerSem( TRUE );
  3866.     rc = CreateVscrnMuxWait(VCMD) ;
  3867.     rc = CreateVscrnMuxWait(VTERM) ;
  3868.     rc = CreateVscrnMuxWait(VCS) ;
  3869.  
  3870.     rc = StartVscrnTimer( tt_update );
  3871.     old_tt_update = tt_update ;
  3872.  
  3873.     /* Allocate buffer for screen writes and blank the screen */
  3874.     thecells = malloc( MAXTERMCOL * MAXTERMROW * sizeof(viocell) ) ;
  3875.     if (!thecells) {
  3876.         fatal("TermScrnUpd: Unable to allocate memory for Video Display Workspace");
  3877.     }
  3878.     defaultcell.c = ' ' ;
  3879.     defaultcell.a = vmode == VCMD ? colorcmd :
  3880.       (colorreset ? colornormal : defaultattribute) ;
  3881.     defaultflipcell = defaultcell ;
  3882.     byteswapcolors( defaultflipcell.a ) ;
  3883.     debug(F101,"VscrnGetWidth() ","",VscrnGetWidth(vmode) ) ;
  3884.     debug(F101,"VscrnGetDisplayHeight()","",VscrnGetDisplayHeight(vmode)) ;
  3885.     WrtNCell( defaultcell, VscrnGetWidth(vmode)  * (VscrnGetDisplayHeight(vmode)), 0, 0 ) ;
  3886.     debug(F110,"TermScrnUpd","WrtNCell defaultcell complete",0);
  3887. #ifdef NT
  3888.     /* we want to turn on processing of Window Events */
  3889.     GetConsoleMode( KbdHandle, &conmode ) ;
  3890.     conmode |= ENABLE_WINDOW_INPUT ;
  3891.     rc = SetConsoleMode( KbdHandle, conmode ) ;
  3892. #endif /* NT */
  3893.  
  3894. #ifndef ONETERMUPD
  3895.     while (IsConnectMode())
  3896. #else
  3897.     while ( 1 )
  3898. #endif /* ONETERMUPD */
  3899.     {
  3900.         /* Need to add some code in here to check variables such as  */
  3901.         /* tt_update so that the timers can be set at the new speed  */
  3902.         /* or move the timer creation to sysinit() and then have the */
  3903.         /* SET TERMINAL SCREEN-UPDATE command set the timer rates.   */
  3904.         if ( tt_update != old_tt_update ) {
  3905.             StopVscrnTimer();
  3906.             StartVscrnTimer(tt_update);
  3907.             old_tt_update = tt_update ;
  3908.         }
  3909.         avm = vmode ;
  3910.  
  3911. #ifdef NT
  3912.         if ( prty != priority ) {
  3913.             if ( isWin95() )
  3914.                 SetThreadPrty(priority,/* 3 */ 2 /* 1 */) ;
  3915.             else
  3916.                 SetThreadPrty(priority,9 /* 11 */) ;
  3917.             prty = priority;
  3918.         }
  3919. #else
  3920.         if ( prty != priority ) {
  3921.             SetThreadPrty(priority,3) ;
  3922.             prty = priority;
  3923.         }
  3924. #endif /* NT */
  3925.  
  3926.         /* wait for something to happen */
  3927.         if ( trueblink && blinking )
  3928.             msleep(200);
  3929.         else if ( updmode == TTU_FAST ) {
  3930.             if ( !WaitVscrnMuxWait( avm, SEM_INDEFINITE_WAIT ) ) {
  3931.                 /* returns semid if success */
  3932.                 /* reset the timer */
  3933.                 ResetVscrnTimerSem(avm) ;
  3934.                 continue;
  3935.             }
  3936.             else {
  3937.                 /* reset the timer */
  3938.                 ResetVscrnTimerSem(avm) ;
  3939.             }
  3940.         }
  3941.         else { /* updmode == TTU_SMOOTH */
  3942.             if ( WaitVscrnDirtySem( avm, SEM_INDEFINITE_WAIT ) ) {
  3943.                 /* returns 0 if success */
  3944.                 continue;
  3945.             }
  3946.         }
  3947.  
  3948.         /* has anything changed? */
  3949.         dirty = VscrnClean(avm) ;
  3950.         if ( !dirty && !trueblink && !blinking ) {
  3951.             continue ;
  3952.         }
  3953.  
  3954.         if ( avm != vmode ) {
  3955.             cursoron[avm] = 0;        /* Force it back on */
  3956.             continue;
  3957.         }
  3958.  
  3959.         if ( trueblink && blinking ) {
  3960.             blinking = 0 ;                      /* reset blinking flag */
  3961.             blinkon = (blinkon+1) % 4 ;         /* toggle blinking chars */
  3962.             if ( blinkon > 1 && !dirty )
  3963.             {
  3964.                 blinking = 1;                   /* remember we were blinking */
  3965.                 continue;                       /* don't paint the screen */
  3966.             }
  3967.         }
  3968.         else
  3969.             blinkon = 1 ;                               /* show blinking items */
  3970.  
  3971.         incnt = (avm == VTERM) ? ttchk() : 0;
  3972.  
  3973. #ifdef OLD_EXCLUSIVE
  3974.         /* Wait for exclusive access to the screen buffer */
  3975.         rc = RequestVscrnMutex( avm, SEM_INDEFINITE_WAIT ) ;
  3976.         if ( rc )
  3977.             continue ;
  3978. #endif /* OLD_EXCLUSIVE */
  3979.         xs = (tt_modechg == TVC_ENA ) ? vscrn[avm].width : pwidth ;
  3980.         xho = vscrn[avm].hscroll > (MAXTERMCOL-pwidth) ?
  3981.             (MAXTERMCOL-pwidth) : vscrn[avm].hscroll ;
  3982.         ys = (tt_modechg == TVC_ENA ? vscrn[avm].height : pheight)
  3983.             - ((avm==VTERM && tt_status[VTERM] && decssdt!=SSDT_BLANK ||
  3984.                 avm != VTERM && tt_status[avm]) ? 1 : 0 ) ;
  3985.         c = 0 ;
  3986.  
  3987.         /* Build the screen to paint */
  3988.  
  3989.         /* do we have a popup to display? */
  3990.         if ( vscrn[avm].popup == NULL) {
  3991.             xo = yo = -1 ;
  3992.         }
  3993.         else {
  3994.             xo = (xs - vscrn[avm].popup->width) / 2 ;
  3995.             yo = (ys - vscrn[avm].popup->height) / 2 ;
  3996.         }
  3997.  
  3998.         /* Handle the real data */
  3999.  
  4000.         if ( avm == VTERM && !screenon ) {
  4001.             /* Blank out the screen */
  4002.             for ( y=0 ; y < ys ; y++ )
  4003.                 for ( x= 0; x < xs ; x++ )
  4004.                     thecells[c++] = defaultcell ;
  4005.         }
  4006.         else if ( markmodeflag[avm] != marking ) {
  4007.             for ( y = 0 ; y < ys ; y++ ) {
  4008. #ifdef NEW_EXCLUSIVE
  4009.                 /* Wait for exclusive access to the screen buffer */
  4010.                 rc = RequestVscrnMutex( avm, SEM_INDEFINITE_WAIT ) ;
  4011.                 if ( rc )
  4012.                     continue ;
  4013. #endif /* NEW_EXCLUSIVE */
  4014.                 /* Get the next line */
  4015.                 if (!scrollflag[avm]) {
  4016.                     line = &vscrn[avm].lines[(vscrn[avm].top+y)%vscrn[avm].linecount] ;
  4017.                 }
  4018.                 else {
  4019.                     line = &vscrn[avm].lines[(vscrn[avm].scrolltop+y)%vscrn[avm].linecount] ;
  4020.                 }
  4021.  
  4022.                 /* copy the screen data to the buffer */
  4023.                 if (line != NULL && line->cells != NULL) {
  4024.                     if ( line->vt_line_attr & VT_LINE_ATTR_DOUBLE_WIDE )
  4025.                     {
  4026.                         for ( x = 0 ; x < xs ; x++ ) {
  4027.                             vt_char_attrs = line->vt_char_attrs[x+xho];
  4028.                             pScell = &line->cells[x+xho];
  4029.                             pDcell = &thecells[c+2*x];
  4030.  
  4031.                             if ( vt_char_attrs & VT_CHAR_ATTR_HYPERLINK )
  4032.                                 vt_char_attrs |= tt_url_hilite_attr;
  4033.                             else if ( tt_url_hilite && incnt < URLMINCNT) {
  4034.                                 if ( IsURLChar(pScell->c) && 
  4035.                                      IsCellPartOfURL(avm, y, x+xho ) )
  4036.                                     vt_char_attrs |= tt_url_hilite_attr;
  4037.                             }
  4038.                             if (vt_char_attrs & VT_CHAR_ATTR_BLINK)
  4039.                             {
  4040.                                 blinking = 1 ;
  4041.                                 if ( blinkon )
  4042.                                 {
  4043.                                     pDcell->c = pScell->c ;
  4044.                                     pDcell->a = (pDcell+1)->a =
  4045.                                         ComputeColorFromAttr( avm, pScell->a,
  4046.                                                              vt_char_attrs );
  4047.                                 }
  4048.                                 else
  4049.                                 {
  4050.                                     pDcell->c = ' ' ;
  4051.                                     pDcell->a = (pDcell+1)->a =
  4052.                                         ComputeColorFromAttr( avm, pScell->a,
  4053.                                                              vt_char_attrs );
  4054.                                 }
  4055.                             }
  4056.                             else
  4057.                             {
  4058.                                 pDcell->c = pScell->c ;
  4059.                                 pDcell->a = (pDcell+1)->a =
  4060.                                     ComputeColorFromAttr( avm, pScell->a,
  4061.                                                          vt_char_attrs );
  4062.                             }
  4063.                             (pDcell+1)->c = ' ' ;
  4064.                         }
  4065.                     }
  4066.                     else
  4067.                     {
  4068.                         for ( x = 0 ; x < xs ; x++ ) {
  4069.                             vt_char_attrs = line->vt_char_attrs[x+xho];
  4070.                             pScell = &line->cells[x+xho];
  4071.                             pDcell = &thecells[c+x];
  4072.  
  4073.                             if ( vt_char_attrs & VT_CHAR_ATTR_HYPERLINK )
  4074.                                 vt_char_attrs |= tt_url_hilite_attr;
  4075.                             else if ( tt_url_hilite && incnt < URLMINCNT) {
  4076.                                 if ( IsURLChar(pScell->c) && 
  4077.                                      IsCellPartOfURL(avm, y, x+xho ) )
  4078.                                     vt_char_attrs |= tt_url_hilite_attr;
  4079.                             }
  4080.                             if (vt_char_attrs & VT_CHAR_ATTR_BLINK)
  4081.                             {
  4082.                                 blinking = 1 ;
  4083.                                 if ( blinkon )
  4084.                                 {
  4085.                                     pDcell->c = pScell->c ;
  4086.                                     pDcell->a =
  4087.                                         ComputeColorFromAttr( avm, pScell->a,
  4088.                                                              vt_char_attrs );
  4089.                                 }
  4090.                                 else
  4091.                                 {
  4092.                                     pDcell->c = ' ' ;
  4093.                                     pDcell->a =
  4094.                                         ComputeColorFromAttr( avm, pScell->a,
  4095.                                                              vt_char_attrs );
  4096.                                 }
  4097.                             }
  4098.                             else
  4099.                             {
  4100.                                 pDcell->c = pScell->c ;
  4101.                                 pDcell->a =
  4102.                                     ComputeColorFromAttr( avm, pScell->a,
  4103.                                                          vt_char_attrs );
  4104.                             }
  4105.                         }
  4106.                     }
  4107.                 } else {
  4108.                     /* In case we are in the middle of a scroll */
  4109.                     for ( x = 0 ; x < xs ; x++ ) {
  4110.                         thecells[c+x] = defaultcell ;
  4111.                     }
  4112. #ifdef VSCRN_DEBUG
  4113.                     debug(F111,"TermScrnUpd","OUCH!",
  4114.                           (scrollflag[avm]?(vscrn[avm].scrolltop+y)
  4115.                            :(vscrn[avm].top+y))%vscrn[avm].linecount);
  4116. #endif /* VSCRN_DEBUG */
  4117.                 }
  4118.  
  4119. #ifdef NEW_EXCLUSIVE
  4120.                 rc = ReleaseVscrnMutex( avm ) ;
  4121. #endif /* NEW_EXCLUSIVE */
  4122.  
  4123.                 /* if there is a popup, display it */
  4124.                 if ( y >= yo &&
  4125.                     vscrn[avm].popup &&
  4126.                     y <= yo+vscrn[avm].popup->height-1 ) {
  4127.                     int i ;
  4128.                     for ( i = 0 ; i < vscrn[avm].popup->width ; i++ ) {
  4129.                         if ( isunicode() ) {
  4130.                             thecells[c+xo+i].c =
  4131.                                 vscrn[avm].popup->c[y-yo][i] < 32 ?
  4132.                                     (*xl_u[TX_IBMC0GRPH])(vscrn[avm].popup->c[y-yo][i]) :
  4133.                                         vscrn[avm].popup->c[y-yo][i] >= 128 ?
  4134.                                     (*xl_u[TX_CP437])(vscrn[avm].popup->c[y-yo][i]) :
  4135.                                         vscrn[avm].popup->c[y-yo][i] ;
  4136.                         }
  4137.                         else
  4138.                             thecells[c+xo+i].c = vscrn[avm].popup->c[y-yo][i];
  4139.                         thecells[c+xo+i].a = vscrn[avm].popup->a;
  4140.                     }
  4141.                 }
  4142.                 c += xs;        /* advance the pointer in the buffer */
  4143.             }
  4144.         }
  4145.         else {  /* were in marking mode */
  4146.             for ( y = 0 ; y < ys ; y++ ) {
  4147.                 line = &vscrn[avm].lines[(vscrn[avm].scrolltop+y)%vscrn[avm].linecount] ;
  4148.  
  4149.                 if (line != NULL && line->cells) {
  4150.                     if ( VscrnIsLineMarked(avm,vscrn[avm].scrolltop+y) ) {
  4151.                         if ( line->vt_line_attr & VT_LINE_ATTR_DOUBLE_WIDE )
  4152.                         {
  4153.                             for ( x = 0 ; x < xs/2 ; x++ ) {
  4154.                                 vt_char_attrs = line->vt_char_attrs[x+xho];
  4155.                                 pScell = &line->cells[x+xho];
  4156.                                 pDcell = &thecells[c+2*x];
  4157.                 
  4158.                                 if ( vt_char_attrs & VT_CHAR_ATTR_HYPERLINK )
  4159.                                     vt_char_attrs |= tt_url_hilite_attr;
  4160.                                 else if ( tt_url_hilite && incnt < URLMINCNT ) {
  4161.                                     if ( IsURLChar(pScell->c) && 
  4162.                                          IsCellPartOfURL(avm, y, x+xho ) )
  4163.                                         vt_char_attrs |= tt_url_hilite_attr;
  4164.                                 }
  4165.                                 if ( line->markshowend != -1 &&
  4166.                                     line->markend >= line->width-1 &&
  4167.                                     x >= line->markbeg*2 &&
  4168.                                     x <= line->markshowend ) {
  4169.                                     if (vt_char_attrs & VT_CHAR_ATTR_BLINK)
  4170.                                     {
  4171.                                         blinking = 1 ;
  4172.                                         pDcell->c = blinkon ?
  4173.                                             pScell->c : ' ' ;
  4174.                                     }
  4175.                                     else
  4176.                                         pDcell->c = pScell->c ;
  4177.                                     (pDcell+1)->c = ' ' ;
  4178.                                     pDcell->a =
  4179.                                         (pDcell+1)->a = colorselect ;
  4180.                                 }
  4181.                                 else if ( line->markshowend != -1 &&
  4182.                                          x+xho >= line->markbeg*2 &&
  4183.                                          x+xho <= line->markend/2 &&
  4184.                                          x+xho <= line->markshowend )
  4185.                                 {
  4186.                                     if (vt_char_attrs & VT_CHAR_ATTR_BLINK)
  4187.                                     {
  4188.                                         blinking = 1 ;
  4189.                                         pDcell->c = blinkon ?
  4190.                                             pScell->c : ' ' ;
  4191.                                     }
  4192.                                     else
  4193.                                         pDcell->c = pScell->c ;
  4194.                                     (pDcell+1)->c = ' ' ;
  4195.                                     pDcell->a =
  4196.                                         (pDcell+1)->a = colorselect ;
  4197.                                 }
  4198.                                 else
  4199.                                 {
  4200.                                     if (vt_char_attrs & VT_CHAR_ATTR_BLINK)
  4201.                                     {
  4202.                                         blinking = 1 ;
  4203.                                         if ( blinkon )
  4204.                                         {
  4205.                                             pDcell->c = pScell->c ;
  4206.                                             pDcell->a = (pDcell+1)->a =
  4207.                                                 ComputeColorFromAttr( avm, pScell->a,
  4208.                                                                      vt_char_attrs );
  4209.                                         }
  4210.                                         else
  4211.                                         {
  4212.                                             pDcell->a = (pDcell+1)->a =
  4213.                                                 ComputeColorFromAttr( avm, pScell->a,
  4214.                                                                      vt_char_attrs );
  4215.                                         }
  4216.                                     }
  4217.                                     else
  4218.                                     {
  4219.                                         pDcell->c = pScell->c ;
  4220.                                         pDcell->a = (pDcell+1)->a =
  4221.                                             ComputeColorFromAttr( avm, pScell->a,
  4222.                                                                  vt_char_attrs );
  4223.                                     }
  4224.                                     (pDcell+1)->c = ' ' ;
  4225.                                 }
  4226.                             }
  4227.                         }
  4228.                         else
  4229.                         {
  4230.                             for ( x = 0 ; x < xs ; x++ ) {
  4231.                                 vt_char_attrs = line->vt_char_attrs[x+xho];
  4232.                                 pScell = &line->cells[x+xho];
  4233.                                 pDcell = &thecells[c+x];
  4234.                                 
  4235.                                 if ( vt_char_attrs & VT_CHAR_ATTR_HYPERLINK )
  4236.                                     vt_char_attrs |= tt_url_hilite_attr;
  4237.                                 else if ( tt_url_hilite && incnt < URLMINCNT ) {
  4238.                                     if ( IsURLChar(pScell->c) && 
  4239.                                          IsCellPartOfURL(avm, y, x+xho ) )
  4240.                                         vt_char_attrs |= tt_url_hilite_attr;
  4241.                                 }
  4242.                                 if ( line->markshowend != -1 &&
  4243.                                     x+xho >= line->markbeg &&
  4244.                                     x+xho <= line->markshowend ) {
  4245.                                     if (vt_char_attrs & VT_CHAR_ATTR_BLINK)
  4246.                                     {
  4247.                                         blinking = 1 ;
  4248.                                         pDcell->c = blinkon ?
  4249.                                             pScell->c : ' ' ;
  4250.                                     }
  4251.                                     else
  4252.                                         pDcell->c = pScell->c ;
  4253.                                     pDcell->a = colorselect ;
  4254.                                 }
  4255.                                 else
  4256.                                 {
  4257.                                     if (vt_char_attrs & VT_CHAR_ATTR_BLINK)
  4258.                                     {
  4259.                                         blinking = 1 ;
  4260.                                         if ( blinkon )
  4261.                                         {
  4262.                                             pDcell->c = pScell->c ;
  4263.                                             pDcell->a =
  4264.                                                 ComputeColorFromAttr( avm, pScell->a,
  4265.                                                                      vt_char_attrs);
  4266.                                         }
  4267.                                         else
  4268.                                         {
  4269.                                             pDcell->c = ' ' ;
  4270.                                             pDcell->a =
  4271.                                                 ComputeColorFromAttr( avm, pScell->a,
  4272.                                                                      vt_char_attrs );
  4273.                                         }
  4274.                                     }
  4275.                                     else
  4276.                                     {
  4277.                                         pDcell->c = pScell->c ;
  4278.                                         pDcell->a =
  4279.                                             ComputeColorFromAttr( avm, pScell->a,
  4280.                                                                  vt_char_attrs );
  4281.                                     }
  4282.                                 }
  4283.                             }
  4284.                         }
  4285.                     }
  4286.                     else {      /* line is not marked */
  4287.                         if ( line->vt_line_attr & VT_LINE_ATTR_DOUBLE_WIDE )
  4288.                         {
  4289.                             {
  4290.                                 for ( x = 0 ; x < xs ; x++ ) {
  4291.                                     vt_char_attrs = line->vt_char_attrs[x+xho];
  4292.                                     pScell = &line->cells[x+xho];
  4293.                                     pDcell = &thecells[c+2*x];
  4294.                                 
  4295.                                     if ( vt_char_attrs & VT_CHAR_ATTR_HYPERLINK )
  4296.                                         vt_char_attrs |= tt_url_hilite_attr;
  4297.                                     else if ( tt_url_hilite && incnt < URLMINCNT ) {
  4298.                                         if ( IsURLChar(pScell->c) && 
  4299.                                              IsCellPartOfURL(avm, y, x+xho ) )
  4300.                                             vt_char_attrs |= tt_url_hilite_attr;
  4301.                                     }
  4302.                                     if (vt_char_attrs & VT_CHAR_ATTR_BLINK)
  4303.                                     {
  4304.                                         blinking = 1 ;
  4305.                                         if ( blinkon )
  4306.                                         {
  4307.                                             pDcell->c = pScell->c ;
  4308.                                             pDcell->a = (pDcell+1)->a =
  4309.                                                 ComputeColorFromAttr( avm, pScell->a,
  4310.                                                                      vt_char_attrs);
  4311.                                         }
  4312.                                         else
  4313.                                         {
  4314.                                             pDcell->c = ' ' ;
  4315.                                             pDcell->a = (pDcell+1)->a =
  4316.                                                 ComputeColorFromAttr( avm, pScell->a,
  4317.                                                                      vt_char_attrs );
  4318.                                         }
  4319.                                     }
  4320.                                     else
  4321.                                     {
  4322.                                         pDcell->c = pScell->c ;
  4323.                                         (pDcell+1)->c = ' ' ;
  4324.                                         pDcell->a = (pDcell+1)->a =
  4325.                                             ComputeColorFromAttr( avm, pScell->a,
  4326.                                                                  vt_char_attrs );                                    }
  4327.                                 }
  4328.                             }
  4329.                         }
  4330.                         else
  4331.                         {
  4332.                             {
  4333.                                 for ( x = 0 ; x < xs ; x++ ) {
  4334.                                     vt_char_attrs = line->vt_char_attrs[x+xho];
  4335.                                     pScell = &line->cells[x+xho];
  4336.                                     pDcell = &thecells[c+x];
  4337.                                     
  4338.                                     if ( vt_char_attrs & VT_CHAR_ATTR_HYPERLINK )
  4339.                                         vt_char_attrs |= tt_url_hilite_attr;
  4340.                                     else if ( tt_url_hilite && incnt < URLMINCNT ) {
  4341.                                         if ( IsURLChar(pScell->c) && 
  4342.                                              IsCellPartOfURL(avm, y, x+xho ) )
  4343.                                             vt_char_attrs |= tt_url_hilite_attr;
  4344.                                     }
  4345.                                     if (vt_char_attrs & VT_CHAR_ATTR_BLINK)
  4346.                                     {
  4347.                                         blinking = 1 ;
  4348.                                         pDcell->c = blinkon ?
  4349.                                             pScell->c : ' ' ;
  4350.                                     }
  4351.                                     else
  4352.                                         pDcell->c = pScell->c ;
  4353.                                     pDcell->a =
  4354.                                         ComputeColorFromAttr( avm, pScell->a,
  4355.                                                              vt_char_attrs );
  4356.                                 }
  4357.                             }
  4358.                         }
  4359.                     }
  4360.                 } else {
  4361.                     /* In case we are in the middle of a scroll */
  4362.                     for ( x = 0 ; x < xs ; x++ ) {
  4363.                         thecells[c+x] = flipscrnflag[avm] ?
  4364.                             defaultflipcell : defaultcell ;
  4365.                     }
  4366.                 }
  4367. #ifdef NEW_EXCLUSIVE
  4368.                 rc = ReleaseVscrnMutex( avm ) ;
  4369. #endif /* NEW_EXCLUSIVE */
  4370.  
  4371.                 /* if there is a popup, display it */
  4372.                 if ( y >= yo &&
  4373.                     vscrn[avm].popup &&
  4374.                     y <= yo+vscrn[avm].popup->height-1 ) {
  4375.                     int i ;
  4376.                     for ( i = 0 ; i < vscrn[avm].popup->width ; i++ ) {
  4377.                         if ( isunicode() ) {
  4378.                             thecells[c+xo+i].c =
  4379.                                 vscrn[avm].popup->c[y-yo][i] < 32 ?
  4380.                                     (*xl_u[TX_IBMC0GRPH])(vscrn[avm].popup->c[y-yo][i]) :
  4381.                                         vscrn[avm].popup->c[y-yo][i] >= 128 ?
  4382.                                             (*xl_u[TX_CP437])(vscrn[avm].popup->c[y-yo][i]) :
  4383.                                                 vscrn[avm].popup->c[y-yo][i] ;
  4384.                         }
  4385.                         else
  4386.                             thecells[c+xo+i].c = vscrn[avm].popup->c[y-yo][i];
  4387.                         thecells[c+xo+i].a = vscrn[avm].popup->a;
  4388.                     }
  4389.                 }
  4390.                 c += xs;
  4391.             }
  4392.         }
  4393. #ifdef OLD_EXCLUSIVE
  4394.         rc = ReleaseVscrnMutex( avm ) ;
  4395. #endif /* OLD_EXCLUSIVE */
  4396.         
  4397.         /* Status Line Display */
  4398.         if ( avm == VTERM && tt_status[VTERM] && decssdt != SSDT_BLANK ||
  4399.              avm != VTERM && tt_status[avm])
  4400.         {
  4401.             if ( avm == VTERM && decssdt == SSDT_HOST_WRITABLE && tt_status[VTERM] == 1) {
  4402.                 line = &vscrn[VSTATUS].lines[0] ;
  4403.                 if ( line != NULL )
  4404.                 for ( x = 0 ; x < xs ; x++ ) {
  4405.                     vt_char_attrs = line->vt_char_attrs[x];
  4406.                     pScell = &line->cells[x];
  4407.                     pDcell = &thecells[c+x];
  4408.  
  4409.                     if (vt_char_attrs & VT_CHAR_ATTR_BLINK)
  4410.                     {
  4411.                         blinking = 1 ;
  4412.                         if ( blinkon )
  4413.                         {
  4414.                             pDcell->c = pScell->c ;
  4415.                             pDcell->a =
  4416.                                 ComputeColorFromAttr( avm, pScell->a,
  4417.                                                      vt_char_attrs );
  4418.                         }
  4419.                         else
  4420.                         {
  4421.                             pDcell->c = ' ' ;
  4422.                             pDcell->a =
  4423.                                 ComputeColorFromAttr( avm, pScell->a,
  4424.                                                      vt_char_attrs );
  4425.                         }
  4426.                     }
  4427.                     else
  4428.                     {
  4429.                         pDcell->c = pScell->c ;
  4430.                         pDcell->a =
  4431.                             ComputeColorFromAttr( avm, pScell->a,
  4432.                                                  vt_char_attrs );
  4433.                     }
  4434.                 }
  4435.                 c += xs ;
  4436.             }
  4437.             else {/* SSDT_INDICATOR - Kermit Status Line */
  4438.                 status = line25(avm);
  4439.  
  4440.                 for ( x = 0 ; x < xs ; x++ ) {
  4441.                     if ( isunicode() ) {
  4442.                         thecells[c].c = status[x] < 32 ?
  4443.                             (*xl_u[TX_IBMC0GRPH])(status[x]) :
  4444.                                 status[x] >= 128 ?
  4445.                                     (*xl_u[TX_CP437])(status[x]) :
  4446.                                         status[x] ;
  4447.                     }
  4448.                     else
  4449.                         thecells[c].c = status[x] ;
  4450.                     thecells[c].a = colorstatus ;
  4451.                     c++ ;
  4452.                 }
  4453.             }
  4454.         }
  4455.  
  4456.         msleep(0);
  4457.         rc = RequestScreenMutex(-1);
  4458.         if ( rc )
  4459.         {
  4460.             continue ;
  4461.         }
  4462.  
  4463.         /* only calculated an offset if Roll mode is INSERT */
  4464.         cursor_offset = (scrollstatus[avm] && tt_roll[avm]
  4465.                          && markmodeflag[avm] == notmarking ) ?
  4466.                              (vscrn[avm].top + vscrn[avm].linecount
  4467.                               - vscrn[avm].scrolltop)%vscrn[avm].linecount : 0 ;
  4468.         if ( VscrnIsPopup(avm) || !cursorena[avm] ||
  4469.             vscrn[avm].cursor.x - xho < 0 ||  vscrn[avm].cursor.x - xho >= pwidth ||
  4470.             vscrn[avm].cursor.y + cursor_offset >= VscrnGetDisplayHeight(avm)
  4471.             -(tt_status[avm]?1:0) ) {
  4472.             killcursor(avm) ;
  4473.         }
  4474.         else {
  4475.             newcursor(avm) ;
  4476.             GetCurPos( &cursor.y, &cursor.x ) ;
  4477. #ifdef NEW_EXCLUSIVE
  4478.             /* Wait for exclusive access to the screen buffer */
  4479.             rc = RequestVscrnMutex( avm, SEM_INDEFINITE_WAIT ) ;
  4480.             if ( !rc ) {
  4481. #endif /* NEW_EXCLUSIVE */
  4482.                 line = &vscrn[avm].lines[(vscrn[avm].top+vscrn[avm].cursor.y)%vscrn[avm].linecount];
  4483.                 if ( line != NULL )
  4484.                 if ( line->vt_line_attr & VT_LINE_ATTR_DOUBLE_WIDE ) {
  4485.                     if ((vscrn[avm].cursor.x - xho)*2 != cursor.x ||
  4486.                          vscrn[avm].cursor.y + cursor_offset != cursor.y )
  4487.                         SetCurPos( vscrn[avm].cursor.y + cursor_offset,
  4488.                                    (vscrn[avm].cursor.x - xho)*2 ) ;
  4489.                 } else {
  4490.                     if ( vscrn[avm].cursor.x - xho != cursor.x ||
  4491.                          vscrn[avm].cursor.y + cursor_offset != cursor.y )
  4492.                         SetCurPos( vscrn[avm].cursor.y + cursor_offset,
  4493.                                    vscrn[avm].cursor.x - xho ) ;
  4494.                 }
  4495. #ifdef NEW_EXCLUSIVE
  4496.                 rc = ReleaseVscrnMutex( avm ) ;
  4497.             }
  4498. #endif /* NEW_EXCLUSIVE */
  4499.  
  4500.         }
  4501.         /* Paint the screen */
  4502.         if ( tt_diff_upd && (!isWin95() ||
  4503.              !tt_attr_bug ||
  4504.              ( pwidth == 80 &&
  4505.                ( pheight == 25 || pheight == 43 || pheight == 50 ) ))
  4506.              )
  4507.             WrtCellStrDiff( thecells, c, 0, 0,
  4508.                             (tt_modechg == TVC_ENA ) ? vscrn[avm].height : pheight,
  4509.                             (tt_modechg == TVC_ENA ) ? vscrn[avm].width : pwidth);
  4510.         else {
  4511.             WrtCellStr( thecells, c, 0, 0 );
  4512.         }
  4513.  
  4514.         ReleaseScreenMutex() ;
  4515.     }
  4516.  
  4517.     StopVscrnTimer() ;
  4518.  
  4519. #ifdef NT
  4520.     /* we want to turn on processing of Window Events */
  4521.     GetConsoleMode( KbdHandle, &conmode ) ;
  4522.     conmode &= ~ENABLE_WINDOW_INPUT ;
  4523.     rc = SetConsoleMode( KbdHandle, conmode ) ;
  4524. #endif /* NT */
  4525.  
  4526.     CloseVscrnMuxWait(VCMD) ;
  4527.     CloseVscrnMuxWait(VTERM) ;
  4528.     CloseVscrnMuxWait(VCS) ;
  4529.     CloseVscrnTimerSem() ;
  4530.     free(thecells) ;
  4531.     PostTermScrnUpdThreadDownSem();
  4532.     ckThreadEnd(threadinfo) ;
  4533. }
  4534.  
  4535. #ifdef PCFONTS
  4536. APIRET
  4537. os2LoadPCFonts( void )
  4538. {
  4539.     extern char exedir[];
  4540.     CHAR dll[_MAX_PATH], failure[_MAX_PATH] ;
  4541.     char *p, *q;
  4542.     APIRET rc = 0 ;
  4543.  
  4544.     if ( hPCFonts )  /* PC Fonts DLL already loaded */
  4545.         return 0 ;
  4546.  
  4547.     p = q = strdup( exedir ) ;
  4548.     if (p) {
  4549.         while (*p) {
  4550.             if (*p == '/') *p = '\\';
  4551.             if (islower(*p)) *p = toupper(*p);
  4552.             p++ ;
  4553.             }
  4554.         p = q ;
  4555.         }
  4556.     else {
  4557.         p = exedir;
  4558.         }
  4559.  
  4560.     ckstrncpy(dll,p,_MAX_PATH);
  4561.     ckstrncat(dll,"PCFONTS.DLL",_MAX_PATH);
  4562.     debug(F110,"os2LoadPCFonts dll",dll,0);
  4563.     rc = DosLoadModule( failure, _MAX_PATH, dll, &hPCFonts ) ;
  4564.     if ( rc )
  4565.     {
  4566.        debug(F111,"os2LoadPCFonts DosLoadModule failed",failure,rc) ;
  4567.        hPCFonts = 0 ;
  4568.     }
  4569.     if ( q )
  4570.        free(q) ;
  4571.     return rc ;
  4572. }
  4573.  
  4574. APIRET
  4575. os2SetFont( void )
  4576. {
  4577.     APIRET rc = 0 ;
  4578.     VIOFONTINFO fi;
  4579.     PBYTE pFont ;
  4580.     BYTE  buffer[FONTBUFSIZE] ;
  4581.     ULONG FontSize, FontID ;
  4582.  
  4583.     memset( &fi, 0, sizeof(fi) ) ;
  4584.     fi.cb = sizeof(fi) ;
  4585.  
  4586.     if ( tt_font == TTF_ROM ) {
  4587.         FontSaved = 0 ;
  4588.         }
  4589.     else {
  4590.         if ( !hPCFonts ) {
  4591.             rc = os2LoadPCFonts() ;
  4592.             if (rc) {
  4593.                 debug( F101, "os2LoadPCFonts failed rc","",rc) ;
  4594.                 return rc ;
  4595.             }
  4596.         }
  4597.  
  4598.         fi.type = VGFI_GETCURFONT ;
  4599.         fi.cxCell = 0 ;
  4600.         fi.cyCell = 0 ;
  4601.         fi.pbData = buffer ;
  4602.         fi.cbData = FONTBUFSIZE ;
  4603.         rc = VioGetFont( &fi, VioHandle ) ;
  4604.  
  4605.         memcpy( &SavedFontInfo, &fi, sizeof(VIOFONTINFO) ) ;
  4606.         SavedFontInfo.pbData=SavedFontBuffer ;
  4607.         memcpy( SavedFontBuffer, buffer, FONTBUFSIZE ) ;
  4608.         FontSaved = 1 ;
  4609.  
  4610.         debug( F101, "os2SetFont VioGetFont rc","",rc ) ;
  4611.         debug( F101, "type","",fi.type ) ;
  4612.         debug( F101, "cxCell","",fi.cxCell ) ;
  4613.         debug( F101, "cyCell","",fi.cyCell ) ;
  4614.         debug( F101, "cbData","",fi.cbData ) ;
  4615.         debug( F101, "loading font","",tt_font);
  4616.  
  4617.         FontID = fi.cyCell*1000+tt_font ;
  4618.         rc = DosGetResource( hPCFonts,
  4619.             (ULONG) PCFONT,
  4620.             (ULONG) FontID,
  4621.             (PPVOID) &pFont );
  4622.         if (!rc) {
  4623.             rc = DosQueryResourceSize( hPCFonts, PCFONT, FontID, &FontSize ) ;
  4624.  
  4625.             fi.pbData = pFont ;
  4626.             fi.cbData = FontSize ;
  4627.  
  4628.             rc = VioSetFont( &fi, VioHandle ) ;
  4629.             DosFreeResource( pFont ) ;
  4630.             debug( F101, "os2SetFont rc","",rc) ;
  4631.             }
  4632.         else {
  4633.             debug( F101, "DosGetResource failed rc","",rc ) ;
  4634.             }
  4635.         }
  4636.  
  4637.     return rc ;
  4638. }
  4639.  
  4640.  
  4641. APIRET
  4642. os2ResetFont( void )
  4643. {
  4644.     APIRET rc = 0 ;
  4645.  
  4646.     if ( FontSaved )
  4647.         rc = VioSetFont( &SavedFontInfo, VioHandle ) ;
  4648.     debug(F101,"os2ResetFont Set rc","",rc);
  4649.     return rc ;
  4650. }
  4651. #endif /* PCFONTS */
  4652.  
  4653. /*---------------------------------------------------------------------------*/
  4654. /* killcursor                                                                */
  4655. /*---------------------------------------------------------------------------*/
  4656. void
  4657. killcursor( BYTE vmode ) {
  4658.     CK_CURSORINFO crsr_info;
  4659.     debug(F100,"killcursor","",0);
  4660.     if (!cursoron[vmode])                       /* It's already off */
  4661.         return;
  4662.     GetCurType(&crsr_info);     /* Store current cursor type */
  4663.     crsr_info.attr = -1;
  4664.     if ( !SetCurType(&crsr_info) )      /* Hide cursor */
  4665.     {
  4666.         cursoron[vmode] = FALSE;
  4667.     }
  4668. }
  4669.  
  4670. /*---------------------------------------------------------------------------*/
  4671. /* newcursor                                                                 */
  4672. /*---------------------------------------------------------------------------*/
  4673. void
  4674. newcursor( BYTE vmode ) {
  4675.     CK_CURSORINFO vci;
  4676.     int cell, bottom, top;
  4677.  
  4678.     debug(F100,"newcursor","",0);
  4679.     if (cursoron[vmode])                        /* It's already on */
  4680.       return;
  4681.  
  4682.     GetCurType(&vci);
  4683.  
  4684. #ifdef NT
  4685.     switch (tt_cursor) {
  4686.         case 0:
  4687.             vci.yStart = 12 ;
  4688.             break;
  4689.         case 1:
  4690.             vci.yStart = 50 ;
  4691.             break;
  4692.         case 2:
  4693.             vci.yStart = 88 ;
  4694.             break;
  4695.         }
  4696. #else /* NT */
  4697.     vci.cEnd   = -100;
  4698.     switch (tt_cursor) {
  4699.         case 0:
  4700.             vci.yStart = -90 ;
  4701.             break;
  4702.         case 1:
  4703.             vci.yStart = -50 ;
  4704.             break;
  4705.         case 2:
  4706.             vci.yStart = -10 ;
  4707.             break;
  4708.         }
  4709. #endif /* NT */
  4710.     vci.attr = 1 ;
  4711.  
  4712.     if ( !SetCurType(&vci) )
  4713.     {
  4714.         cursoron[vmode] = TRUE;
  4715.         VscrnIsDirty(vmode);
  4716.     }
  4717. }
  4718.  
  4719. void
  4720. shovscrn(void)
  4721. {
  4722.     printf("\n");
  4723.     printf("Virtual Screen settings:\n");
  4724.     printf("                ____VCMD____ ___VTERM____ ____VCS_____\n");
  4725.     printf("     linecount: %12d %12d %12d\n", vscrn[VCMD].linecount,
  4726.             vscrn[VTERM].linecount, vscrn[VCS].linecount) ;
  4727.     printf("         lines: %12s %12s %12s\n",
  4728.             vscrn[VCMD].lines ? "allocated" : "Null",
  4729.             vscrn[VTERM].lines ? "allocated" : "Null",
  4730.             vscrn[VCS].lines ? "allocated" : "Null") ;
  4731.     printf("           beg: %12d %12d %12d\n", vscrn[VCMD].beg,
  4732.             vscrn[VTERM].beg, vscrn[VCS].beg ) ;
  4733.     printf("           top: %12d %12d %12d\n", vscrn[VCMD].top,
  4734.             vscrn[VTERM].top, vscrn[VCS].top ) ;
  4735.     printf("     scrolltop: %12d %12d %12d\n", vscrn[VCMD].scrolltop,
  4736.             vscrn[VTERM].scrolltop, vscrn[VCS].scrolltop) ;
  4737.     printf("           end: %12d %12d %12d\n", vscrn[VCMD].end,
  4738.             vscrn[VTERM].end, vscrn[VCS].end ) ;
  4739.     printf("        cursor:      %3d,%3d      %3d,%3d      %3d,%3d\n",
  4740.             vscrn[VCMD].cursor.x, vscrn[VCMD].cursor.y,
  4741.             vscrn[VTERM].cursor.x, vscrn[VTERM].cursor.y,
  4742.             vscrn[VCS].cursor.x, vscrn[VCS].cursor.y) ;
  4743.     printf("         popup: %12s %12s %12s\n",
  4744.             vscrn[VCMD].popup ? "yes" : "no",
  4745.             vscrn[VTERM].popup ? "yes" : "no",
  4746.             vscrn[VCS].popup ? "yes" : "no") ;
  4747.     printf("       marktop: %12d %12d %12d\n",
  4748.             vscrn[VCMD].marktop,
  4749.             vscrn[VTERM].marktop,
  4750.             vscrn[VCS].marktop) ;
  4751.     printf("       markbot: %12d %12d %12d\n",
  4752.             vscrn[VCMD].markbot,
  4753.             vscrn[VTERM].markbot,
  4754.             vscrn[VCS].markbot) ;
  4755.     printf("        height: %12d %12d %12d\n",
  4756.             vscrn[VCMD].height,
  4757.             vscrn[VTERM].height,
  4758.             vscrn[VCS].height) ;
  4759.     printf("         width: %12d %12d %12d\n",
  4760.             vscrn[VCMD].width,
  4761.             vscrn[VTERM].width,
  4762.             vscrn[VCS].width) ;
  4763.     printf("       hscroll: %12d %12d %12d\n",
  4764.             vscrn[VCMD].hscroll,
  4765.             vscrn[VTERM].hscroll,
  4766.             vscrn[VCS].hscroll) ;
  4767.     printf("display_height: %12d %12d %12d\n",
  4768.             vscrn[VCMD].display_height,
  4769.             vscrn[VTERM].display_height,
  4770.             vscrn[VCS].display_height) ;
  4771.     printf("\n");
  4772. }
  4773.  
  4774. APIRET
  4775. VscrnInit( BYTE vmode )
  4776. {
  4777.    extern int tt_szchng[], tt_scrsize[] ;
  4778.    extern int cmd_rows, cmd_cols, marginbot ;
  4779.    extern int updmode, tt_updmode, SysInited ;
  4780.    extern ascreen commandscreen, vt100screen ;
  4781.    extern unsigned char                 /* Video attribute bytes */
  4782.       attribute,                      /* Current video attribute byte */
  4783.       underlineattribute,
  4784.       savedattribute,                 /* Saved video attribute byte */
  4785.       defaultattribute;               /* Default video attribute byte */
  4786.    extern int scrninitialized[] ;
  4787.    extern unsigned char colornormal, colorunderline, colorborder,
  4788.     colorreverse, colorgraphic, colorcmd, coloritalic ;
  4789.    BYTE clrscr = 0 ;
  4790. #ifndef KUI
  4791.    CK_VIDEOMODEINFO m;
  4792. #endif /* KUI */
  4793.  
  4794.    debug(F111,"VscrnInit","vmode",vmode);
  4795. #ifndef KUI
  4796.    if (GetMode(&m))
  4797.    {
  4798.        debug(F111,"VscrnInit GetMode() fails","vmode",vmode);
  4799.    }
  4800. #endif /* KUI */
  4801.    if ( vmode == VCMD )
  4802.    {
  4803.        if ( cmd_rows < 0 || cmd_cols < 0 || tt_rows[VCMD] < 0 || tt_cols[VCMD] < 0 )
  4804.            ttgcwsz();
  4805.    }
  4806.  
  4807.    if ( VscrnGetBufferSize(vmode) != tt_scrsize[vmode] || VscrnGetWidth(vmode)  <= 0
  4808.         || VscrnGetHeight(vmode) <= 0 || tt_cols[vmode] <= 0 || tt_rows[vmode] <= 0 ) 
  4809.    {
  4810.        scrninitialized[vmode] = 0;
  4811.  
  4812.        debug(F101,"tt_cols","",tt_cols[vmode]);
  4813.        debug(F101,"tt_rows","",tt_rows[vmode]);
  4814. #ifndef KUI
  4815.        debug(F101,"m.row","",m.row);
  4816.        debug(F101,"m.col","",m.col);
  4817.        if ( tt_cols[vmode] <= 0 || tt_rows[vmode] <= 0 ) {
  4818.            tt_cols[vmode] = min(MAXTERMCOL, m.col);
  4819.            tt_rows[vmode] = min(MAXTERMROW, tt_status[vmode] ? m.row-1 : m.row);
  4820.        }
  4821. #else /* KUI */
  4822.        if ( tt_cols[vmode] <= 0 || tt_rows[vmode] <= 0 ) {
  4823.            tt_cols[vmode] = MAXTERMCOL;
  4824.            tt_rows[vmode] = MAXTERMROW;
  4825.        }
  4826. #endif /* KUI */
  4827.    }
  4828.  
  4829.    if ( vmode == VTERM )
  4830.    {
  4831.       if (!scrninitialized[VTERM]) {
  4832.           scrninitialized[VTERM] = 1;
  4833.           attribute = defaultattribute = colornormal;
  4834.           underlineattribute = colorunderline ;
  4835.           reverseattribute = colorreverse ;
  4836.           italicattribute = coloritalic;
  4837.           graphicattribute = colorgraphic ;
  4838.           borderattribute = colorborder ;
  4839.           updmode = tt_updmode ;  /* Set screen update mode */
  4840.       }
  4841.       if ( marginbot == VscrnGetHeight(VTERM)-(tt_status[vmode]?1:0) ||
  4842.            VscrnGetHeight(VTERM) < 0 ||
  4843.            marginbot > tt_rows[VTERM] )
  4844.          marginbot = tt_rows[VTERM];
  4845.    }
  4846.  
  4847.    VscrnSetWidth( vmode, tt_cols[vmode] ) ;
  4848.    VscrnSetHeight( vmode, tt_rows[vmode]+(tt_status[vmode]?1:0) );
  4849.  
  4850.     /* Initialize paging info */
  4851.     clrscr = VscrnSetBufferSize( vmode, tt_scrsize[vmode] ) ;
  4852.  
  4853.     if ( tt_szchng[vmode] ) {
  4854.         LONG sz ;
  4855.         /* Wait for exclusive access to the screen */
  4856.         RequestVscrnMutex( vmode, SEM_INDEFINITE_WAIT ) ;
  4857.         sz = (VscrnGetEnd(vmode) - VscrnGetTop(vmode)
  4858.                + VscrnGetBufferSize(vmode) + 1)%VscrnGetBufferSize(vmode) ;
  4859.         if ( !clrscr )
  4860.             if ( sz > tt_rows[vmode] )
  4861.             {
  4862.                 if ( !VscrnIsClear(vmode) ) {
  4863.                     VscrnScroll( vmode, UPWARD, 0, sz-1, sz-1, TRUE, SP ) ;
  4864.                     clrscr = 1 ;
  4865.                 }
  4866.             }
  4867. #ifdef COMMENT
  4868.             else if ( tt_szchng[vmode] == 2 ) /* Status Line Turned On */
  4869.             {
  4870.                 if (!VscrnIsClear(vmode)) {
  4871.                     VscrnScroll( vmode, UPWARD, 0, sz, sz, TRUE, SP ) ;
  4872.                     clrscr = 1 ;
  4873.                 }
  4874.                 else {
  4875.                 }
  4876.             }
  4877. #endif
  4878.             else
  4879.             {
  4880.                 int             x,y ;
  4881.                 videoline *     line ;
  4882.                 int             foo = 0;
  4883.  
  4884.                 if ( VscrnGetEnd(vmode) == VscrnGetBufferSize(vmode) ||
  4885.                      VscrnGetEnd(vmode) + 1 == VscrnGetBegin(vmode) )
  4886.                     foo++;
  4887.  
  4888.                 VscrnSetEnd( vmode, VscrnGetTop(vmode) +
  4889.                              VscrnGetHeight(vmode)-1
  4890.                              -(tt_status[vmode]?1:0)) ;
  4891.                 if ( foo )
  4892.                     VscrnSetBegin( vmode, VscrnGetEnd(vmode) + 1);
  4893.  
  4894.                 for ( y = sz ;
  4895.                       y < VscrnGetHeight(vmode)-(tt_status[vmode]?1:0) ;
  4896.                       y++ ) {
  4897.                     line = VscrnGetLineFromTop(vmode,y) ;
  4898.                     if ( line ) {
  4899.                         line->width = VscrnGetWidth(vmode)  ;
  4900.                         line->vt_line_attr = VT_LINE_ATTR_NORMAL ;
  4901.                         for ( x = 0 ; x < MAXTERMCOL ; x++ ) {
  4902.                             line->cells[x].c = ' ' ;
  4903.                             line->cells[x].a = vmode == VTERM ? attribute : colorcmd;
  4904.                             line->vt_char_attrs[x] = VT_CHAR_ATTR_NORMAL ;
  4905.                         }
  4906.                     }
  4907.                 }
  4908.             }
  4909.         ReleaseVscrnMutex(vmode) ;
  4910.         tt_szchng[vmode] = 0 ;
  4911.     }
  4912.  
  4913.     if ( clrscr ) {
  4914.         scrollflag[vmode] = FALSE ;
  4915.         scrollstatus[vmode] = FALSE ;
  4916.         cleartermscreen(vmode);
  4917.     }
  4918.     scrninitialized[vmode] = TRUE ;
  4919.     return 0;
  4920. }
  4921.  
  4922. BOOL
  4923. VscrnIsClear( BYTE vmode )
  4924. {
  4925.     int             x,y ;
  4926.     videoline *     line ;
  4927.     unsigned char cellcolor = geterasecolor(vmode);
  4928.  
  4929.     for ( y = 0 ; y < VscrnGetHeight(vmode)-(tt_status[vmode]?1:0) ; y++ ) {
  4930.         line = VscrnGetLineFromTop(vmode,y) ;
  4931.         if (line == NULL)
  4932.             return 0;
  4933.         for ( x = 0 ; x < line->width ; x++ ) {
  4934.             if ( line->cells[x].c != ' ' )
  4935.             {
  4936.                 debug(F100,"VscrnIsClear c!=' '","",0);
  4937.                 return 0;
  4938.             }
  4939.             if ( line->cells[x].a != cellcolor )
  4940.             {
  4941.                 debug(F100,"VscrnIsClear a != cellcolor","",0);
  4942.                 return 0;
  4943.             }
  4944.         }
  4945.     }
  4946.     debug(F100,"VscrnIsClear all clear","",0);
  4947.     return 1 ;
  4948. }
  4949. #endif /* NOLOCAL */
  4950.  
  4951. #undef printf
  4952. #undef fprintf
  4953. #undef putchar
  4954. extern int k95stdio,k95stdin,k95stdout;
  4955. #ifdef IKSD
  4956. extern int inserver;
  4957. #endif /* IKSD */
  4958.  
  4959. static char myprtfstr[2*CMDBL];
  4960. static char myprtfstr2[2*CMDBL];
  4961. /*
  4962. * printf for console
  4963. */
  4964. int
  4965. Vscrnprintf (const char *format, ...) {
  4966. #ifndef NOLOCAL
  4967.     extern unsigned char colorcmd ;
  4968.     BYTE vmode = VCMD ;
  4969.     extern int wherex[], wherey[];
  4970. #endif /* NOLOCAL */
  4971.     int i, len, rc=0;
  4972.     char *cp;
  4973.     va_list ap;
  4974.     static int printf_inprogress=0;
  4975.  
  4976.     va_start(ap, format);
  4977. #ifndef ONETERMUPD
  4978.     rc = vprintf( format, ap ) ;
  4979. #endif /* ONETERMUPD */
  4980. #ifdef NT
  4981.     rc = _vsnprintf(myprtfstr, sizeof(myprtfstr)-1, format, ap);
  4982. #else /* NT */
  4983.     rc = vsprintf(myprtfstr, format, ap);
  4984. #endif /* NT */
  4985.     va_end(ap);
  4986.  
  4987. /*
  4988.  *  if ((i = strlen(string)) >= sizeof(string))
  4989.  *     debug(F101,"Overran allocation for string in printf(), len:","",i);
  4990.  */
  4991.  
  4992. #ifdef IKSD
  4993.     if ( inserver ) {
  4994.         int i,j,len,got_cr;
  4995.         debug(F111,"Vscrnprintf inserver",
  4996.                "printf_inprogress",printf_inprogress);
  4997.         if (!printf_inprogress) {
  4998.             printf_inprogress = 1;
  4999.             for (i = 0, j = 0, len = strlen(myprtfstr), got_cr = 0;
  5000.                   i < len && j < 1022;
  5001.                   i++, j++ ) {
  5002.                 switch (myprtfstr[i]) {
  5003.                 case '\r':
  5004.                     if (got_cr && !TELOPT_ME(TELOPT_BINARY))
  5005.                         myprtfstr2[j++] = '\0';
  5006.                     myprtfstr2[j] = myprtfstr[i];
  5007.                     got_cr = 1;
  5008.                     break;
  5009.                 case '\n':
  5010.                     if (!got_cr)
  5011.                         myprtfstr2[j++] = '\r';
  5012.                     myprtfstr2[j] = myprtfstr[i];
  5013.                     got_cr = 0;
  5014.                     break;
  5015.                 default:
  5016.                     if (got_cr && !TELOPT_ME(TELOPT_BINARY))
  5017.                         myprtfstr2[j++] = '\0';
  5018.                     myprtfstr2[j] = myprtfstr[i];
  5019.                     got_cr = 0;
  5020.                 }
  5021.             }
  5022.             ttol(myprtfstr2,j);
  5023.             printf_inprogress = 0;
  5024.         }
  5025.     }
  5026. #endif /* IKSD */
  5027.  
  5028. #ifndef NOLOCAL
  5029.     if ( k95stdout )
  5030.         fwrite(myprtfstr,1,strlen(myprtfstr),stdout);
  5031.     else
  5032.         VscrnWrtCharStrAtt( vmode, myprtfstr, strlen(myprtfstr),
  5033.                             wherey[vmode],
  5034.                             wherex[vmode],
  5035.                             &colorcmd
  5036.                             ) ;
  5037. #endif /* NOLOCAL */
  5038.     return (rc);
  5039. }
  5040.  
  5041. /*
  5042. * fprintf for console
  5043. */
  5044. int
  5045. Vscrnfprintf (FILE * file, const char *format, ...) {
  5046. #ifndef NOLOCAL
  5047.     extern unsigned char colorcmd ;
  5048.     BYTE vmode = VCMD ;
  5049.     extern int wherex[], wherey[];
  5050. #endif /* NOLOCAL */
  5051.     int i, len, rc=0;
  5052.     char *cp;
  5053.     va_list ap;
  5054.     static int fprintf_inprogress = 0;
  5055.  
  5056.     va_start(ap, format);
  5057.  
  5058. #ifdef IKSD
  5059.     if ( inserver ) {
  5060.         int i,j,len,got_cr;
  5061. #ifdef NT
  5062.         rc = _vsnprintf(myprtfstr, sizeof(myprtfstr)-1, format, ap);
  5063. #else /* NT */
  5064.         rc = vsprintf(myprtfstr, format, ap);
  5065. #endif /* NT */
  5066.         debug(F111,"Vscrnfprintf inserver",
  5067.                "fprintf_inprogress",fprintf_inprogress);
  5068.         if (!fprintf_inprogress) {
  5069.             fprintf_inprogress = 1;
  5070.             for (i = 0, j = 0, len = strlen(myprtfstr), got_cr = 0;
  5071.                   i < len && j < 1022;
  5072.                   i++, j++ ) {
  5073.                 switch (myprtfstr[i]) {
  5074.                 case '\r':
  5075.                     if (got_cr && !TELOPT_ME(TELOPT_BINARY))
  5076.                         myprtfstr2[j++] = '\0';
  5077.                     myprtfstr2[j] = myprtfstr[i];
  5078.                     got_cr = 1;
  5079.                     break;
  5080.                 case '\n':
  5081.                     if (!got_cr)
  5082.                         myprtfstr2[j++] = '\r';
  5083.                     myprtfstr2[j] = myprtfstr[i];
  5084.                     got_cr = 0;
  5085.                     break;
  5086.                 default:
  5087.                     if (got_cr && !TELOPT_ME(TELOPT_BINARY))
  5088.                         myprtfstr2[j++] = '\0';
  5089.                     myprtfstr2[j] = myprtfstr[i];
  5090.                     got_cr = 0;
  5091.                 }
  5092.             }
  5093.             ttol(myprtfstr2,j);
  5094.             fprintf_inprogress = 0;
  5095.         }
  5096.     }
  5097. #endif /* IKSD */
  5098. #ifndef NOLOCAL
  5099.     if ( file == stdout || file == stderr )
  5100.     {
  5101. #ifdef NT
  5102.         rc = _vsnprintf(myprtfstr, sizeof(myprtfstr)-1, format, ap);
  5103. #else /* NT */
  5104.         rc = vsprintf(myprtfstr, format, ap);
  5105. #endif /* NT */
  5106.         /*
  5107.         *  if ((i = strlen(string)) >= sizeof(string))
  5108.         *     debug(F101,"Overran allocation for string in printf(), len:","",i);
  5109.         */
  5110.  
  5111.         if ( k95stdout )
  5112.             fwrite(myprtfstr,1,strlen(myprtfstr),stdout);
  5113.         else
  5114.             VscrnWrtCharStrAtt( vmode, myprtfstr, strlen(myprtfstr),
  5115.                                 wherey[vmode],
  5116.                                 wherex[vmode],
  5117.                                 &colorcmd
  5118.                                 ) ;
  5119.     }
  5120.     else
  5121.         rc = vfprintf(file, format, ap);
  5122. #endif /* NOLOCAL */
  5123.     va_end(ap);
  5124.     return (rc);
  5125. }
  5126.  
  5127. void
  5128. Vscrnperror( const char *str )
  5129. {
  5130.     char * errstr = ck_errstr() ;
  5131.     Vscrnprintf("%s%s %s\n",str,*errstr?":":"",errstr) ;
  5132. }
  5133.  
  5134. #ifdef KUI
  5135. int
  5136. Vscrnprintw (const char *format, ...) {
  5137. #ifndef NOLOCAL
  5138.     extern unsigned char colorcmd ;
  5139.     BYTE vmode = VCMD ;
  5140.     extern int wherex[], wherey[];
  5141. #endif /* NOLOCAL */
  5142.     int i, len, rc=0;
  5143.     char *cp;
  5144.     va_list ap;
  5145.     static int printf_inprogress=0;
  5146.  
  5147.     va_start(ap, format);
  5148. #ifndef ONETERMUPD
  5149.     rc = vprintf( format, ap ) ;
  5150. #endif /* ONETERMUPD */
  5151. #ifdef NT
  5152.     rc = _vsnprintf(myprtfstr, sizeof(myprtfstr)-1, format, ap);
  5153. #else /* NT */
  5154.     rc = vsprintf(myprtfstr, format, ap);
  5155. #endif /* NT */
  5156.     va_end(ap);
  5157.  
  5158. /*
  5159.  *  if ((i = strlen(string)) >= sizeof(string))
  5160.  *     debug(F101,"Overran allocation for string in printf(), len:","",i);
  5161.  */
  5162.  
  5163. #ifdef IKSD
  5164.     if ( inserver ) {
  5165.         int i,j,len,got_cr;
  5166.         debug(F111,"Vscrnprintf inserver",
  5167.                "printf_inprogress",printf_inprogress);
  5168.         if (!printf_inprogress) {
  5169.             printf_inprogress = 1;
  5170.             for (i = 0, j = 0, len = strlen(myprtfstr), got_cr = 0;
  5171.                   i < len && j < 1022;
  5172.                   i++, j++ ) {
  5173.                 switch (myprtfstr[i]) {
  5174.                 case '\r':
  5175.                     if (got_cr && !TELOPT_ME(TELOPT_BINARY))
  5176.                         myprtfstr2[j++] = '\0';
  5177.                     myprtfstr2[j] = myprtfstr[i];
  5178.                     got_cr = 1;
  5179.                     break;
  5180.                 case '\n':
  5181.                     if (!got_cr)
  5182.                         myprtfstr2[j++] = '\r';
  5183.                     myprtfstr2[j] = myprtfstr[i];
  5184.                     got_cr = 0;
  5185.                     break;
  5186.                 default:
  5187.                     if (got_cr && !TELOPT_ME(TELOPT_BINARY))
  5188.                         myprtfstr2[j++] = '\0';
  5189.                     myprtfstr2[j] = myprtfstr[i];
  5190.                     got_cr = 0;
  5191.                 }
  5192.             }
  5193.             ttol(myprtfstr2,j);
  5194.             printf_inprogress = 0;
  5195.         }
  5196.     }
  5197. #endif /* IKSD */
  5198.  
  5199. #ifndef NOLOCAL
  5200.     if ( k95stdout )
  5201.         fwrite(myprtfstr,1,strlen(myprtfstr),stdout);
  5202.     else {
  5203.         int tcsl_save;
  5204.         extern int tcsl;
  5205.  
  5206.         tcsl_save = tcsl;
  5207.         tcsl = TX_CP437;
  5208.         VscrnWrtCharStrAtt( vmode, myprtfstr, strlen(myprtfstr),
  5209.                             wherey[vmode],
  5210.                             wherex[vmode],
  5211.                             &colorcmd
  5212.                             ) ;
  5213.         tcsl = tcsl_save;
  5214.     }
  5215. #endif /* NOLOCAL */
  5216.     return (rc);
  5217. }
  5218. #endif /* KUI */
  5219.  
  5220. #ifndef NOLOCAL
  5221. #ifdef NT
  5222. #ifndef KUI
  5223. /* This code works by forcing the standard handles to be valid. */
  5224. /* If no console was allocated, the AllocConsole() will succeed */
  5225. /* if not, then, well, who cares.  The standard handles might   */
  5226. /* be invalid anyway.                                           */
  5227.  
  5228. void
  5229. Win32ConsoleInit( void )
  5230. {
  5231.     int hCrt,i;
  5232.     FILE *hf;
  5233.     HANDLE handle ;
  5234.     DWORD filetype;
  5235.     extern int k95stdout, k95stdin;
  5236.  
  5237.     handle = GetStdHandle(STD_INPUT_HANDLE);
  5238.     filetype = GetFileType(handle);
  5239.     debug(F111,"Win32ConsoleInit","GetFileType(stdin)",filetype);
  5240.     if ( filetype == FILE_TYPE_DISK || filetype == FILE_TYPE_PIPE ) {
  5241.         k95stdin = 1;
  5242.     }
  5243.  
  5244.     handle = GetStdHandle(STD_OUTPUT_HANDLE);
  5245.     filetype = GetFileType(handle);
  5246.     debug(F111,"Win32ConsoleInit","GetFileType(stdout)",filetype);
  5247.     if ( filetype == FILE_TYPE_DISK || filetype == FILE_TYPE_PIPE ) {
  5248.         k95stdout = 1;
  5249.     }
  5250.  
  5251.     if ( !isWin95() || k95stdout || k95stdin )
  5252.         return;
  5253.  
  5254.     AllocConsole();
  5255.     hCrt = _open_osfhandle((long) GetStdHandle(STD_OUTPUT_HANDLE),
  5256.                                 _O_BINARY);
  5257.     hf = _fdopen( hCrt, "wb" );
  5258.     *stdout = *hf;
  5259.     i = setvbuf( stdout, NULL, _IONBF, 0 );
  5260.  
  5261.     if ( filetype != FILE_TYPE_DISK && filetype != FILE_TYPE_PIPE ) {
  5262.         handle = CreateFile( "CONIN$",
  5263.                              GENERIC_READ | GENERIC_WRITE,
  5264.                              FILE_SHARE_READ | FILE_SHARE_WRITE,
  5265.                              NULL,
  5266.                              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) ;
  5267.         SetStdHandle( STD_INPUT_HANDLE, handle ) ;
  5268.     }
  5269.     hCrt = _open_osfhandle((long) handle, _O_BINARY);
  5270.     hf = _fdopen( hCrt, "rb" );
  5271.     *stdin = *hf;
  5272.     i = setvbuf( stdin, NULL, _IONBF, 0 );
  5273.  
  5274.     hCrt = _open_osfhandle((long) GetStdHandle(STD_ERROR_HANDLE), _O_BINARY);
  5275.     hf = _fdopen( hCrt, "wb" );
  5276.     *stderr = *hf;
  5277.     i = setvbuf( stderr, NULL, _IONBF, 0 );
  5278. }
  5279. #endif /* KUI */
  5280. #endif /* NT */
  5281.  
  5282. #ifdef KUI
  5283. #define MAXFNTS 1024
  5284. static struct _font_list {
  5285.     int count;
  5286.     char * name[MAXFNTS];
  5287. } * font_list = NULL;
  5288.  
  5289. static int CALLBACK
  5290. EnumFontFamProc( ENUMLOGFONT *lpelfe,    // logical-font data
  5291.                  NEWTEXTMETRICEX *lpntme,  // physical-font data
  5292.                  DWORD FontType,           // type of font
  5293.                  LPARAM lParam             // application-defined data
  5294.                  )
  5295. {
  5296.     int i;
  5297.     char * name;
  5298.  
  5299.     if ( font_list == NULL) {
  5300.         debug(F110,"EnumFontFamProc()","font_list == NULL",0);
  5301.         return(0);
  5302.     }
  5303.  
  5304.     if (font_list->count == MAXFNTS ) {
  5305.         debug(F111,"EnumFontFamProc()","font_list->count == MAXFNTS",MAXFNTS);
  5306.         return(MAXFNTS);
  5307.     }
  5308.  
  5309.     /* Windows 95/98 handles the font names different than NT/2000 */
  5310.     /* Why?  You know better than to ask that question.            */
  5311.     if ( isWin95() ) {
  5312.         if ( FontType == 4 /* True Type */ )
  5313.             name = lpelfe->elfFullName;
  5314.         else
  5315.             name = lpelfe->elfLogFont.lfFaceName;
  5316.     } else
  5317.         name = lpelfe->elfFullName;
  5318.  
  5319.     debug(F110,"EnumFontFamProc() name",name,0);
  5320.     for ( i=0; i < font_list->count; i++ ) {
  5321.         if ( !strcmp(name,font_list->name[i]) )
  5322.             return(font_list->count);
  5323.     }
  5324.     font_list->name[font_list->count++] = strdup(name);
  5325.     return(font_list->count);
  5326. }
  5327.  
  5328.  
  5329. static int CALLBACK
  5330. EnumFontFamExProc( ENUMLOGFONTEX *lpelfe,    // logical-font data
  5331.                    NEWTEXTMETRICEX *lpntme,  // physical-font data
  5332.                    DWORD FontType,           // type of font
  5333.                    LPARAM lParam             // application-defined data
  5334.                    )
  5335. {
  5336.     int i;
  5337.     char * name;
  5338.  
  5339.     if ( font_list == NULL) {
  5340.         debug(F110,"EnumFontFamExProc()","font_list == NULL",0);
  5341.         return(0);
  5342.     }
  5343.  
  5344.     if (font_list->count == MAXFNTS ) {
  5345.         debug(F111,"EnumFontFamExProc()","font_list->count == MAXFNTS",MAXFNTS);
  5346.         return(MAXFNTS);
  5347.     }
  5348.  
  5349.     /* Windows 95/98 handles the font names different than NT/2000 */
  5350.     /* Why?  You know better than to ask that question.            */
  5351.     if ( isWin95() ) {
  5352.         if ( FontType == 4 /* True Type */ )
  5353.             name = lpelfe->elfFullName;
  5354.         else
  5355.             name = lpelfe->elfLogFont.lfFaceName;
  5356.     } else
  5357.         name = lpelfe->elfFullName;
  5358.  
  5359.     debug(F110,"EnumFontFamExProc() name",name,0);
  5360.     for ( i=0; i < font_list->count; i++ ) {
  5361.         if ( !strcmp(name,font_list->name[i]) )
  5362.             return(font_list->count);
  5363.     }
  5364.     font_list->name[font_list->count++] = strdup(name);
  5365.     return(font_list->count);
  5366. }
  5367.  
  5368. static int
  5369. EnumerateFonts()
  5370. {
  5371.     LOGFONT lf;
  5372.     HDC hdc;
  5373.     int i,rc=0;
  5374.     extern int nt351;
  5375.  
  5376.     debug(F100,"EnumerateFonts() start","",0);
  5377.  
  5378.     if ( font_list != NULL ) {
  5379.         for ( i=0 ; i < font_list->count; i++ ) {
  5380.             free(font_list->name[i]);
  5381.             font_list->name[i] = NULL;
  5382.         }
  5383.         font_list->count = 0;
  5384.     } else {
  5385.         font_list = malloc(sizeof(struct _font_list));
  5386.         if ( !font_list )
  5387.             return(0);
  5388.         memset(font_list,0,sizeof(struct _font_list));
  5389.     }
  5390.  
  5391.     hdc = CreateDC("DISPLAY",NULL,NULL,NULL);
  5392.     debug(F111,"EnumerateFonts() CreateDC()","DISPLAY",hdc);
  5393.     if ( hdc ) {
  5394.         lf.lfCharSet = DEFAULT_CHARSET;
  5395.         lf.lfFaceName[0] = '\0';
  5396.         lf.lfPitchAndFamily = 0;
  5397.  
  5398.         if ( nt351 )
  5399.             rc = EnumFontFamilies( (HDC) hdc, NULL,
  5400.                                      (FONTENUMPROC) EnumFontFamProc,
  5401.                                      0);
  5402.         else
  5403.             rc = EnumFontFamiliesEx( (HDC) hdc, (LPLOGFONT)&lf,
  5404.                                  (FONTENUMPROC) EnumFontFamExProc,
  5405.                                  0, 0);
  5406.         debug(F111,"EnumerateFonts()","EnumFontFamiliesEx()",rc);
  5407.         DeleteDC(hdc);
  5408.     }
  5409.     debug(F111,"EnumerateFonts() end","rc",rc);
  5410.     return rc;
  5411. }
  5412.  
  5413.  
  5414. int
  5415. BuildFontTable( struct keytab ** pTable, struct keytab ** pTable2, int * pN )
  5416. {
  5417.     int i, n ;
  5418.     if ( *pTable )
  5419.     {
  5420.         for ( i=0 ; i < *pN ; i++ )
  5421.             free( (*pTable)[i].kwd ) ;
  5422.         free ( *pTable )  ;
  5423.     }
  5424.  
  5425.     if ( *pTable2 )
  5426.     {
  5427.         for ( i=0 ; i < *pN ; i++ )
  5428.             free( (*pTable2)[i].kwd ) ;
  5429.         free ( *pTable2 )  ;
  5430.     }
  5431.  
  5432.     *pTable = NULL ;
  5433.     *pTable2 = NULL ;
  5434.     *pN = 0 ;
  5435.  
  5436.     debug(F100,"BuildFontTable","",0);
  5437.     n = EnumerateFonts();
  5438.     if ( n )
  5439.     {
  5440.         *pTable = malloc( sizeof(struct keytab) * n ) ;
  5441.         *pTable2 = malloc( sizeof(struct keytab) * n ) ;
  5442.  
  5443.         for ( i=0 ; i < font_list->count ; i++ ) {
  5444.             if ( font_list->name[i] == NULL )
  5445.             {
  5446.                 debug(F111,"font_list name entry is NULL","i",i);
  5447.             }
  5448.             else
  5449.             {
  5450.  
  5451.                char * newstr = _strdup(font_list->name[i]) ;
  5452.                char * newstr2 = _strdup(font_list->name[i]) ;
  5453.                int    newval = i;
  5454.                int j = 0, len = 0;
  5455.  
  5456.                debug(F111,"Font Name",newstr,i);
  5457.  
  5458.                /* Make a version that uses Underscores instead of spaces */
  5459.                            /* And lowercases the letters */
  5460.                len = strlen(newstr2);
  5461.                for ( j=0 ; j<len ; j++) {
  5462.                    newstr2[j] = tolower(newstr2[j]);
  5463.                    switch ( newstr2[j] ) {
  5464.                    case ' ':
  5465.                        newstr2[j] = '_';
  5466.                        break;
  5467.                    case ',':
  5468.                        newstr2[j] = '.';
  5469.                        break;
  5470.                    case ';':
  5471.                        newstr2[j] = ':';
  5472.                        break;
  5473.                    case '\\':
  5474.                        newstr2[j] = '/';
  5475.                        break;
  5476.                    case '?':
  5477.                        newstr2[j] = '!';
  5478.                        break;
  5479.                    case '{':
  5480.                        newstr2[j] = '[';
  5481.                        break;
  5482.                    case '}':
  5483.                        newstr2[j] = ']';
  5484.                        break;
  5485.                    }
  5486.                }
  5487.  
  5488.                for ( j=0 ; j < (*pN) ; j++ ) {
  5489.                    int tempval=0;
  5490.                    char * tempstr=NULL,*tempstr2=NULL;
  5491.  
  5492.                    if ( _stricmp( (*pTable2)[j].kwd, newstr2 ) > 0 )
  5493.                    {
  5494.                        tempval = (*pTable)[j].kwval;
  5495.                        tempstr = (*pTable)[j].kwd;
  5496.                        tempstr2 = (*pTable2)[j].kwd;
  5497.                        (*pTable)[j].kwd = newstr ;
  5498.                        (*pTable)[j].kwval = newval;
  5499.                        (*pTable2)[j].kwd = newstr2 ;
  5500.                        (*pTable2)[j].kwval = newval;
  5501.                        newval = tempval;
  5502.                        newstr = tempstr;
  5503.                        (*pTable)[j].flgs = 0;
  5504.                        newstr2 = tempstr2;
  5505.                        (*pTable2)[j].flgs = 0;
  5506.                    }
  5507.                }
  5508.                (*pTable)[*pN].kwd = newstr ;
  5509.                (*pTable)[*pN].kwval = newval;
  5510.                (*pTable)[*pN].flgs = 0 ;
  5511.                (*pTable2)[*pN].kwd = newstr2 ;
  5512.                (*pTable2)[*pN].kwval = newval;
  5513.                (*pTable2)[*pN].flgs = 0 ;
  5514.                (*pN)++ ;
  5515.            }
  5516.        }
  5517.  
  5518.        if ( *pN == 0 ) {
  5519.            free ( *pTable )  ;
  5520.            free ( *pTable2 )  ;
  5521.            *pTable = NULL;
  5522.            *pTable2 = NULL;
  5523.        }
  5524.     }
  5525.     return(1);
  5526. }
  5527. #endif /* KUI */
  5528. #endif /* NOLOCAL */
  5529.