home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / KEYSTR.C < prev    next >
Text File  |  1995-11-30  |  42KB  |  858 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   keystr.c                                                                */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*   Edit a screen field.                                                    */
  7. /*                                                                           */
  8. /* History:                                                                  */
  9. /*                                                                           */
  10. /*   02/08/91 Creation of 32-bit SD86, from 16-bit version.                  */
  11. /*                                                                           */
  12. /*...16->32 port.                                                            */
  13. /*...                                                                        */
  14. /*... 02/08/91  100   Philip    port to 32 bit.                              */
  15. /*... 02/08/91  101   Joe       port to 32 bit.                              */
  16. /*... 02/08/91  108   Dave      port to 32 bit.                              */
  17. /*                                                                           */
  18. /*...Release 1.00 (Pre-release 1)                                            */
  19. /*...                                                                        */
  20. /*... 08/16/91  227   srinivas  Insert key problems while entering user      */
  21. /*                              response.                                    */
  22. /*...                                                                        */
  23. /*...Release 1.00 (Pre-release 108 12/05/91)                                 */
  24. /*...                                                                        */
  25. /*... 02/13/92  525   Srinivas  Prompt for editing variables not working     */
  26. /*...                           properly when register display is on.        */
  27. /*...                                                                        */
  28. /*...Release 1.00 (03/03/92)                                                 */
  29. /*...                                                                        */
  30. /*... 03/10/92  602   Srinivas  Hooking up watch points.                     */
  31. /*...                                                                        */
  32. /*...Release 1.01 (04/03/92)                                                 */
  33. /*...                                                                        */
  34. /*... 05/08/92  701   Srinivas  Cua Interface.                               */
  35. /*...                                                                        */
  36. /*...Release 1.02 (10/22/92)                                                 */
  37. /*...                                                                        */
  38. /*... 04/14/93  820   Selwyn    Add /u option to not flush k/b buffer.       */
  39. /*... 04/15/93  821   Selwyn    Changes in processing clicks on buttons.     */
  40. /*... 12/10/93  910   Joe       Clear fields on cursor sensitive prompting.  */
  41. /*****************************************************************************/
  42. /**Includes*******************************************************************/
  43.                                         /*                                   */
  44. #define INCL_16                         /* for 16-bit API                 101*/
  45. #define INCL_SUB                        /* kbd, vio, mouse routines       101*/
  46. #include "all.h"                        /* SD86 include files                */
  47. static int iview=0;                     /*                                   */
  48. /**Externs********************************************************************/
  49. /*                                                                           */
  50. /*                                                                           */
  51. extern uchar*      VideoPtr;            /* Pointer to logical video buffer   */
  52. extern uint        VideoCols;           /* # of columns per row on screen    */
  53. extern uchar       *BoundPtr;           /* -> to screen bounds            525*/
  54. extern CmdParms     cmd;                /* pointer to CmdParms structure  701*/
  55. extern ushort       MouseRow;           /* Mouse Screen Row position      701*/
  56. extern ushort       MouseCol;           /* Mouse Screen Column position   701*/
  57.  
  58. extern VIOCURSORINFO      NormalCursor;
  59. extern VIOCURSORINFO      InsertCursor;
  60. extern VIOCURSORINFO      HiddenCursor;
  61.  
  62. #define RCBREAK  0x0001      /* exit field */
  63. #define RCREDRAW 0x0002      /* redraw screen */
  64. #define RCDATAXT 0x0004      /* data key exit */
  65.  
  66. static uchar    *FieldBase=NULL;        /*-> to 1st byte of fld in video buf */
  67. static uint      FieldType=0;           /* field type flags                  */
  68. static uint      RightScrollOffset;
  69. static uint      LeftScrollOffset;
  70. static uint      FieldDisplayLength;
  71. static uchar    *Buffer;
  72.  
  73. static PEVENT    Event;
  74.  
  75. /*****************************************************************************/
  76. /* GetString()                                                               */
  77. /*                                                                           */
  78. /* Description:                                                              */
  79. /*                                                                           */
  80. /* Get a string from the user of a specified length in a specified location  */
  81. /* in the screen. This function provides horizontal scrolling facility.      */
  82. /*                                                                           */
  83. /* Parameters:                                                               */
  84. /*                                                                           */
  85. /* FieldRow      (input) - Starting row of the string.                       */
  86. /* FieldCol      (input) - Starting column of the string.                    */
  87. /* length        (input) - Total length of the string buffer.                */
  88. /* displen       (input) - Length of the string to be displayed on screen.   */
  89. /* cursor (input/output) - Position of the cursor within the string.         */
  90. /* buffer       (output) - Buffer to hold the string typed in by the user.   */
  91. /* pShell        - -> to control structure for the popup.                 910*/
  92. /*                                                                           */
  93. /* Return:                                                                   */
  94. /*                                                                           */
  95. /* Mouse clicks in the form of keys.                                         */
  96. /*                                                                           */
  97. /* Assumptions:                                                              */
  98. /*                                                                           */
  99. /* This function assumes the memory needed for storing the user string has   */
  100. /* already been allocated by the caller.                                     */
  101. /*                                                                           */
  102. /*****************************************************************************/
  103. #define MOU_STATE_UP   1
  104. #define MOU_STATE_DOWN 2
  105. uint GetString( uint FieldRow, uint FieldCol, uint length, uint displen,
  106.                 uint *cursor, uchar *pInbuf, uint InFlags, POPUPSHELL *pShell)
  107. {
  108.   /***************************************************************************/
  109.   /* Diagram to explain local variables.                                     */
  110.   /*                                                                         */
  111.   /*  0  ...     10        ...                   40       ...          200   */
  112.   /*                                                                         */
  113.   /*             +-------------------------------+                           */
  114.   /*  +----------|                               |---------------------+     */
  115.   /*  |          |  Portion of the string shown  |                     |     */
  116.   /*  |          |  in the screen.               |                     |     */
  117.   /*  +----------|                               |---------------------+     */
  118.   /*             +-------------------------------+                           */
  119.   /*             |<---- Display Length --------->|                           */
  120.   /*                                                                         */
  121.   /*  |<------------ length (length of the entire buffer) ------------>|     */
  122.   /*                                                                         */
  123.   /*   In the above example:                                                 */
  124.   /*                                                                         */
  125.   /*   length            ===>  200                                           */
  126.   /*   DisplayLength     ===>  30                                            */
  127.   /*   DisplayOffset     ===>  10                                            */
  128.   /*                                                                         */
  129.   /***************************************************************************/
  130.   uint        key;
  131.   int         n, i;
  132.   ushort      rc;
  133.   int         voff;
  134.   uint        IsInsertMode = 0, scratch, BufLen;
  135.   uint        DisplayOffset;
  136.   uint        CursorRow, CursorCol;
  137.   int         FirstKeyEntry = TRUE;                                     /*910*/
  138.   uint        flags = InFlags;                                          /*910*/
  139.   int         state = MOU_STATE_UP; /* assume this! */                  /*910*/
  140.   int         NextState = 0;                                            /*910*/
  141.   BUTTON     *pButtonDown = NULL;                                       /*910*/
  142.  
  143.   /***************************************************************************/
  144.   /*                                                                         */
  145.   /* flags  - Flags which indicate type of the field.                        */
  146.   /*          (AUTOEXIT / HEXONLY / BINONLY)                                 */
  147.   /***************************************************************************/
  148.   if(pShell)
  149.    flags = pShell->Flags;                                               /*910*/
  150.  
  151.   /***************************************************************************/
  152.   /* - Set keyboard flush buffer flag to indiacte not to flush the keyboard  */
  153.   /*   buffer while we are in getstring.                                     */
  154.   /* - Initialise the local variables.                                       */
  155.   /***************************************************************************/
  156.   SetFlushBufferFlag( NOFLUSHNOW );                                     /*820*/
  157.   FieldDisplayLength = displen;
  158.   DisplayOffset = 0;
  159.   CursorRow = FieldRow;
  160.  
  161.   CursorCol = ( *cursor > displen ) ? FieldCol : FieldCol + *cursor;
  162.  
  163. #ifdef MSH
  164.   if(iview) {
  165.     CursorRow+=RowStart;
  166.     FieldRow+=RowStart;
  167.     CursorCol+=ColStart;
  168.     FieldCol+=ColStart;
  169.   }
  170. #endif
  171.  
  172.   /***************************************************************************/
  173.   /* Allocate memory for the local buffer.                                   */
  174.   /***************************************************************************/
  175.   Buffer = (uchar *)Talloc( (length+1) * sizeof( uchar ) );
  176.   memset( Buffer, '\0', length+1 );
  177.   if(!iview) {
  178.   /***************************************************************************/
  179.   /* Adjust display length if the length specified by the caller goes out of */
  180.   /* the screen.                                                             */
  181.   /***************************************************************************/
  182.   if( FieldCol + FieldDisplayLength > VideoCols )
  183.     FieldDisplayLength = VideoCols - FieldCol;
  184.  
  185.   /***************************************************************************/
  186.   /* Check to see if the field would over lap some other window, if so adjust*/
  187.   /* the display length accordingly.                                         */
  188.   /***************************************************************************/
  189.   if( FieldDisplayLength + FieldCol > BoundPtr[FieldRow] )
  190.     FieldDisplayLength = BoundPtr[FieldRow] - FieldCol;
  191.   }
  192.   else
  193.   {
  194. #ifdef MSH
  195.       if( FieldDisplayLength + FieldCol - ColStart> VideoWidth )
  196.         FieldDisplayLength = VideoWidth - FieldCol + ColStart;
  197. #endif
  198.  
  199.   }/* End if*/
  200.   /***************************************************************************/
  201.   /* RightScrollOffset is the amount of scrolling to be done when the user   */
  202.   /* goes out of the display length. It is 2/3 rds of the display length.    */
  203.   /***************************************************************************/
  204.   RightScrollOffset  = (FieldDisplayLength * 2)/3;
  205.   LeftScrollOffset   = FieldDisplayLength - RightScrollOffset;
  206.  
  207.   FieldBase = (uchar *)Sel2Flat( HiFlat(VideoPtr) ) +
  208.               ( voff = 2*(FieldRow*VideoCols + FieldCol) );
  209.   FieldType = flags;
  210.  
  211.   /***************************************************************************/
  212.   /* Depending on the type of the string copy the initial string to the local*/
  213.   /* buffer. Display the string.                                             */
  214.   /***************************************************************************/
  215.   if( (FieldType & HEXONLY) || (FieldType & BINONLY) )
  216.   {
  217.     for( i = 0; i < length; i++ )
  218.       Buffer[i] = FieldBase[i*2];
  219.   }
  220.   else
  221.     strcpy( Buffer, pInbuf );
  222.  
  223.   DisplayField( DisplayOffset );
  224.   VioShowBuf( (ushort)voff,(ushort) (2*FieldDisplayLength), 0 );
  225.  
  226.   VioSetCurType( &NormalCursor, 0 );
  227.  
  228.   for(;;)
  229.   {
  230.     VioSetCurPos( (ushort)CursorRow, (ushort)CursorCol, 0 );
  231.  
  232.     Event = GetEvent( SEM_INDEFINITE_WAIT );
  233.  
  234.     switch( Event->Type )
  235.     {
  236.       case TYPE_MOUSE_EVENT:                                            /*910*/
  237.       {                                                                 /*910*/
  238.        /******************************************************************910*/
  239.        /* Test for mouse event between the string brackets.               910*/
  240.        /******************************************************************910*/
  241.        if( ( Event->Row == (ushort)FieldRow ) &&                        /*910*/
  242.            ( Event->Col >= (ushort)FieldCol ) &&                        /*910*/
  243.            ( Event->Col <= ((ushort)FieldCol+(ushort)FieldDisplayLength-1))
  244.          )                                                              /*910*/
  245.        {                                                                /*910*/
  246.         /*****************************************************************910*/
  247.         /* - If it's a button down event then set the cursor at the       910*/
  248.         /*   end of the string or on the character that was clicked on.   910*/
  249.         /*****************************************************************910*/
  250.         if( Event->Value == EVENT_BUTTON_1_DOWN)                        /*910*/
  251.         {                                                               /*910*/
  252.           BufLen = strlen( Buffer );                                    /*910*/
  253.           if( (DisplayOffset + (Event->Col - FieldCol)) > BufLen )      /*910*/
  254.           {                                                             /*910*/
  255.             keybeep();                                                  /*910*/
  256.             CursorCol = FieldCol + (BufLen - DisplayOffset);            /*910*/
  257.           }                                                             /*910*/
  258.           else                                                          /*910*/
  259.             CursorCol = (uint)Event->Col;                               /*910*/
  260.         }                                                               /*910*/
  261.         /*****************************************************************910*/
  262.         /* - Ignore events between the brackets that are not button       910*/
  263.         /*   down events.                                                 910*/
  264.         /* - Any mouse event between []s turns off the erasure of a       910*/
  265.         /*   cursor sensitive prompt.                                     910*/
  266.         /*****************************************************************910*/
  267.         FieldType &= ~CLEAR1ST;                                         /*910*/
  268.         continue;                                                       /*910*/
  269.        }                                                                /*910*/
  270.                                                                         /*910*/
  271.        /**********************************************************************/
  272.        /* - handle strings that are not in the context of a popup.           */
  273.        /**********************************************************************/
  274.        if(pShell == NULL )                                              /*910*/
  275.        {                                                                /*910*/
  276.         NextState = GetMouseState( Event );                             /*910*/
  277.         if( (state == MOU_STATE_UP) &&                                  /*910*/
  278.             (NextState == MOU_STATE_DOWN)                               /*910*/
  279.           )                                                             /*910*/
  280.         {                                                               /*910*/
  281.          key = LEFTMOUSECLICK;                                          /*910*/
  282.          break;                                                         /*910*/
  283.         }                                                               /*910*/
  284.                                                                         /*910*/
  285.         state = NextState;                                              /*910*/
  286.         continue;                                                       /*910*/
  287.        }                                                                /*910*/
  288.        /******************************************************************910*/
  289.        /* - Now, handle mouse events outside the []s within the context   910*/
  290.        /*   of a popup.                                                   910*/
  291.        /*                                                                 910*/
  292.        /* - Button events are valid on the release event.                 910*/
  293.        /*                                                                 910*/
  294.        /* - Transitions from up to down "outside" the <>s and []s         910*/
  295.        /*   are returned to the caller as a LEFTMOUSECLICK.               910*/
  296.        /*                                                                 910*/
  297.        /*  ------------------------                                       910*/
  298.        /* |                        |                                      910*/
  299.        /* |                       -----------                             910*/
  300.        /* |         <------------|           |<----------------           910*/
  301.        /* |        |              -----------                  |          910*/
  302.        /* |      ----                                        ----         910*/
  303.        /* |     |    |---                                ---|    |---     910*/
  304.        /* |     | UP |   | BU,BUM                BD,BDM |   | DN |   |    910*/
  305.        /* |     |    |<--                                -->|    |<--     910*/
  306.        /* |      ----                                        ----         910*/
  307.        /* |        |                                           |          910*/
  308.        /* |        |                                           |          910*/
  309.        /* |        |              -----------                  |          910*/
  310.        /* |         ------------>|           |---------------->           910*/
  311.        /* |                       -----------                             910*/
  312.        /* |                               |                               910*/
  313.        /* |                               |                               910*/
  314.        /* | BU  - Button up event.        |                               910*/
  315.        /* | BUM - Button up move event.    -(1) If BD or BDM event        910*/
  316.        /* | BD  - Button down event.            occurs in a button(<>s),  910*/
  317.        /* | BDM - Button down move event.       then set pButtonDown      910*/
  318.        /* |                                     to point to the BUTTON    910*/
  319.        /* |                                     structure. This is        910*/
  320.        /* |                                     effectively a "pending"   910*/
  321.        /*  ----(1) If BU or BUM event           button event. If the      910*/
  322.        /*          && if the event occurs       up event occurs within    910*/
  323.        /*          in the same button as        the same <>s, then we've  910*/
  324.        /*          a "pending" button           got ourselves a valid     910*/
  325.        /*          then we have a button        button event.             910*/
  326.        /*          event.                                                 910*/
  327.        /*                                   (2) If BD or BDM do not       910*/
  328.        /*                                       occur within a button,    910*/
  329.        /*                                       then set pButtonDown=NULL 910*/
  330.        /*                                       and go back to the        910*/
  331.        /*                                       caller with a             910*/
  332.        /*                                       LEFTMOUSECLICK.           910*/
  333.        /*                                                                 910*/
  334.        /******************************************************************910*/
  335.        NextState = GetMouseState( Event );                              /*910*/
  336.        if( (state == MOU_STATE_DOWN) &&                                 /*910*/
  337.            (NextState == MOU_STATE_UP) &&                               /*910*/
  338.            (pButtonDown != NULL) &&                                     /*910*/
  339.            (pButtonDown == GetButtonPtr(pShell,Event))                  /*910*/
  340.          )                                                              /*910*/
  341.        {                                                                /*910*/
  342.         key = pButtonDown->Key;                                         /*910*/
  343.         break;                                                          /*910*/
  344.        }                                                                /*910*/
  345.                                                                         /*910*/
  346.        if( (state == MOU_STATE_UP) &&                                   /*910*/
  347.            (NextState == MOU_STATE_DOWN)                                /*910*/
  348.          )                                                              /*910*/
  349.        {                                                                /*910*/
  350.         pButtonDown = GetButtonPtr( pShell,Event);                      /*910*/
  351.         if( pButtonDown == NULL )                                       /*910*/
  352.         {                                                               /*910*/
  353.          key = LEFTMOUSECLICK;                                          /*910*/
  354.          break;                                                         /*910*/
  355.         }                                                               /*910*/
  356.        }                                                                /*910*/
  357.                                                                         /*910*/
  358.        state = NextState;                                               /*910*/
  359.        continue;                                                        /*910*/
  360.       }
  361.  
  362.       case TYPE_KBD_EVENT:
  363.       {
  364.         key = Event->Value;
  365.         break;
  366.       }
  367.     }
  368.  
  369.     if( (FieldType & CLEAR1ST) && (FirstKeyEntry == TRUE) )             /*910*/
  370.      FirstKeyEntry = FALSE;                                             /*910*/
  371.  
  372.     switch( key )
  373.     {
  374.       case F1:
  375.       case ESC:
  376.       case ENTER:
  377.       case UP:
  378.       case DOWN:
  379.       case A_ENTER:
  380.       case MOUSECLICK:
  381.       /***********************************************************************/
  382.       /* - these keys are specific to the watchpoint dialog.              910*/
  383.       /***********************************************************************/
  384.       case TYNEXT:                      /* watchpoint type button.        910*/
  385.       case SPNEXT:                      /* watchpoint scope button.       910*/
  386.       case SZNEXT:                      /* watchpoint size button.        910*/
  387.       case STNEXT:                      /* watchpoint status button.      910*/
  388.       {
  389.         /*********************************************************************/
  390.         /* All the above keys cannot be proccessed by getstring, so return   */
  391.         /* the key to the caller.                                            */
  392.         /*********************************************************************/
  393.         rc = RCBREAK;
  394.         break;
  395.       }
  396.  
  397.       case C_HOME:
  398.       {
  399.         /*********************************************************************/
  400.         /* Control-Home takes you to the start of the string.                */
  401.         /*********************************************************************/
  402.         DisplayOffset = 0;
  403.         CursorCol = FieldCol;
  404.         rc = RCREDRAW;
  405.         break;
  406.       }
  407.  
  408.       case C_END:
  409.       {
  410.         /*********************************************************************/
  411.         /* Control-End takes you to the end of the string (to the last char  */
  412.         /* the user has types in).                                           */
  413.         /*********************************************************************/
  414.         BufLen = strlen( Buffer );
  415.         if( BufLen > FieldDisplayLength )
  416.         {
  417.           DisplayOffset = BufLen - FieldDisplayLength;
  418.           CursorCol = FieldCol + FieldDisplayLength - 1;
  419.         }
  420.         else
  421.         {
  422.           DisplayOffset = 0;
  423.           CursorCol = FieldCol + BufLen;
  424.         }
  425.         rc = RCREDRAW;
  426.         break;
  427.       }
  428.  
  429.       case TAB:
  430.       case S_TAB:
  431.       {
  432.         /*********************************************************************/
  433.         /* If the user has keyed in a tab  and the field type is AUTOEXIT,   */
  434.         /* return to the caller.                                             */
  435.         /*********************************************************************/
  436.         if( FieldType & AUTOEXIT )
  437.           rc = RCBREAK;
  438.         else
  439.         {
  440.           keybeep();
  441.           rc = 0;
  442.         }
  443.         break;
  444.       }
  445.  
  446.       case LEFT:
  447.       {
  448.         /*********************************************************************/
  449.         /* The user has pressed the left arrow key.                          */
  450.         /*  - If the cursor is not in the starting column move the cursor    */
  451.         /*    one column to the left.                                        */
  452.         /*********************************************************************/
  453.         if( CursorCol > FieldCol )
  454.         {
  455.           CursorCol--;
  456.           rc = 0;
  457.         }
  458.         else
  459.         {
  460.           /*******************************************************************/
  461.           /* If the cursor is in the starting column, a non zero value in the*/
  462.           /* display offset would indicate we have some characters to the    */
  463.           /* left to be displayed (see diagram above). If you have enough    */
  464.           /* characters to scroll to LeftScrollOffset amount, do so. If not  */
  465.           /* scroll to the start of the string.                              */
  466.           /*******************************************************************/
  467.           if( DisplayOffset )
  468.           {
  469.             if( (int)(DisplayOffset - LeftScrollOffset) >= 0 )
  470.             {
  471.               DisplayOffset -= LeftScrollOffset;
  472.               CursorCol += (LeftScrollOffset - 1);
  473.             }
  474.             else
  475.             {
  476.               CursorCol += DisplayOffset;
  477.               DisplayOffset = 0;
  478.             }
  479.             rc = RCREDRAW;
  480.           }
  481.           else
  482.           {
  483.             if( FieldType & AUTOEXIT )
  484.               rc = RCBREAK;
  485.             else
  486.             {
  487.                keybeep();
  488.                rc = 0;
  489.             }
  490.           }
  491.         }
  492.         break;
  493.       }
  494.  
  495.       case RIGHT:
  496.       {
  497.         /*********************************************************************/
  498.         /* The user has pressed the right arrow key.                         */
  499.         /*  - If the cursor is not in the ending column of display and not   */
  500.         /*    end of the string, move the cursor one column to the right.    */
  501.         /*********************************************************************/
  502.         BufLen = strlen( Buffer );
  503.         if( CursorCol < ( FieldCol + FieldDisplayLength - 1 ) )
  504.         {
  505.           if( (DisplayOffset + (CursorCol - FieldCol)) < BufLen )
  506.           {
  507.             CursorCol++;
  508.             rc = 0;
  509.           }
  510.           else
  511.           {
  512.             keybeep();
  513.             rc = 0;
  514.           }
  515.         }
  516.         else
  517.         {
  518.           /*******************************************************************/
  519.           /* If the cursor is at the ending column of display, check to see  */
  520.           /* if we are within the buffer length. If we have enough space to  */
  521.           /* scroll by RightScrollOffset amount do so, if not scroll till the*/
  522.           /* end of the string.                                              */
  523.           /*******************************************************************/
  524.           if( DisplayOffset + FieldDisplayLength < BufLen )
  525.           {
  526.             DisplayOffset += (FieldDisplayLength - RightScrollOffset);
  527.             if( (DisplayOffset + (CursorCol - FieldCol)) > BufLen )
  528.               CursorCol = FieldCol + (BufLen - DisplayOffset);
  529.             else
  530.               CursorCol = FieldCol + RightScrollOffset;
  531.             rc = RCREDRAW;
  532.           }
  533.           else
  534.           {
  535.             /*****************************************************************/
  536.             /* If we reached the ending column and the end of the buffer, if */
  537.             /* the field type is AUTOEXIT return to the caller.              */
  538.             /*****************************************************************/
  539.             if( FieldType & AUTOEXIT )
  540.               rc = RCBREAK;
  541.             else
  542.             {
  543.               keybeep();
  544.               rc = 0;
  545.             }
  546.           }
  547.         }
  548.         break;
  549.       }
  550.  
  551.       case HOME:
  552.       {
  553.         /*********************************************************************/
  554.         /* Home takes to the starting column of the string.                  */
  555.         /*********************************************************************/
  556.         CursorCol = FieldCol;
  557.         break;
  558.       }
  559.  
  560.       case END:
  561.       {
  562.         /*********************************************************************/
  563.         /* End takes you to the ending column of the string. If the string   */
  564.         /* is not long enough till the ending column of the display, End     */
  565.         /* takes you to the end of the string.                               */
  566.         /*********************************************************************/
  567.         CursorCol = FieldCol + FieldDisplayLength - 1;
  568.         scratch = DisplayOffset + ( CursorCol - FieldCol );
  569.         BufLen = strlen( Buffer );
  570.         if( scratch > BufLen )
  571.           CursorCol = FieldCol + (BufLen - DisplayOffset);
  572.         break;
  573.       }
  574.  
  575.       case INS:
  576.       {
  577.         /*********************************************************************/
  578.         /* Insert key is pressed. This toggles the InsertMode flag. If the   */
  579.         /* current length of the string is less than the buffer length,      */
  580.         /* InsertMode could be allowed. Set the cusror type accordingly.     */
  581.         /*********************************************************************/
  582.         if( IsInsertMode )
  583.         {
  584.           IsInsertMode = 0;
  585.           VioSetCurType( &NormalCursor, 0 );
  586.         }
  587.         else
  588.         {
  589.           if( length != strlen( Buffer ) )
  590.           {
  591.             IsInsertMode = 1 - IsInsertMode;
  592.             IsInsertMode ? VioSetCurType( &InsertCursor, 0 ) :
  593.                            VioSetCurType( &NormalCursor, 0 );
  594.           }
  595.           else                           /* Display proper error message...   */
  596.             keybeep();
  597.         }
  598.         break;
  599.       }
  600.  
  601.       case DEL:
  602.       {
  603.         /*********************************************************************/
  604.         /* Delete the current character. The rest of the string is shifted   */
  605.         /* left.                                                             */
  606.         /*********************************************************************/
  607.         scratch = DisplayOffset + ( CursorCol - FieldCol );
  608.         ( scratch < strlen( Buffer ) ) ? ShiftLeft( scratch ) :
  609.                                        keybeep();
  610.         rc = RCREDRAW;
  611.         break;
  612.       }
  613.  
  614.       case BACKSPACE:
  615.       {
  616.         /*********************************************************************/
  617.         /* The previous character to the cursor is deleted. By default the   */
  618.         /* string is shifted left by one character. But if the cursor is on  */
  619.         /* the starting column then the string is shifted by LeftScrollOffset*/
  620.         /* amount.                                                           */
  621.         /*********************************************************************/
  622.         scratch = DisplayOffset + (CursorCol - FieldCol);
  623.         if( scratch )
  624.         {
  625.           ShiftLeft( scratch - 1 );
  626.           CursorCol--;
  627.           if( CursorCol < FieldCol )
  628.           {
  629.             if( (int)(DisplayOffset - LeftScrollOffset) >= 0 )
  630.             {
  631.               DisplayOffset -= LeftScrollOffset;
  632.               CursorCol += LeftScrollOffset;
  633.             }
  634.             else
  635.             {
  636.               CursorCol += (DisplayOffset + 1);
  637.               DisplayOffset = 0;
  638.             }
  639.           }
  640.         }
  641.         else
  642.           keybeep();
  643.         rc = RCREDRAW;
  644.         break;
  645.       }
  646.  
  647.       default:
  648.       {
  649.         /*********************************************************************/
  650.         /* Any other character key is pressed. Verify the validity of the    */
  651.         /* character depending on the type of the string (HEX/BIN).          */
  652.         /*********************************************************************/
  653.         key &= 0xFF;
  654.         if( key != 0x15 )
  655.         if( (key < 0x20) || (key > 0x7E) )
  656.         {
  657.           rc = RCBREAK;
  658.           break;
  659.         }
  660.  
  661.         if( FieldType & HEXONLY )
  662.         {
  663.           if( (key < '0') || (key > '9') )
  664.           {
  665.             key &= 0xDF;
  666.             if( (key < 'A') || (key > 'F') )
  667.             {
  668.               keybeep();
  669.               rc = 0;
  670.               break;
  671.             }
  672.           }
  673.         }
  674.  
  675.         if( FieldType & BINONLY )
  676.         {
  677.           if( (key != '0') && (key != '1') )
  678.           {
  679.             keybeep();
  680.             rc = 0;
  681.             break;
  682.           }
  683.         }
  684.  
  685.  
  686.         if( FieldType & CLEAR1ST )                                      /*910*/
  687.         {                                                               /*910*/
  688.          memset(Buffer,'\0',strlen(Buffer) );                           /*910*/
  689.          *cursor = 0;                                                   /*910*/
  690.          CursorCol = (*cursor > displen)?FieldCol : FieldCol + *cursor; /*910*/
  691.         }                                                               /*910*/
  692.  
  693.         /*********************************************************************/
  694.         /* Scratch gives you the exact number of characters so far typed in  */
  695.         /* by the user. Accept the last character only if scratch is less    */
  696.         /* than the total length of the string.                              */
  697.         /*********************************************************************/
  698.         scratch = DisplayOffset + ( CursorCol - FieldCol );
  699.         if( scratch < length )
  700.         {
  701.           if( IsInsertMode )
  702.           {
  703.             if( (strlen( Buffer ) + 1) > length )
  704.             {
  705.               keybeep();
  706.               rc = 0;
  707.               break;      /* reject */
  708.             }
  709.             else
  710.                ShiftRight( scratch );
  711.           }
  712.  
  713.           Buffer[scratch] = ( uchar )key;
  714.  
  715.           /*******************************************************************/
  716.           /* Adjust the cursor position accordingly so that it stays ahead   */
  717.           /* of the last character.                                          */
  718.           /*******************************************************************/
  719.           if( CursorCol >= (FieldCol + FieldDisplayLength) )
  720.           {
  721.             DisplayOffset += (FieldDisplayLength - RightScrollOffset - 1);
  722.             CursorCol = FieldCol + RightScrollOffset + 2;
  723.           }
  724.           else
  725.             CursorCol++;
  726.  
  727.           /*******************************************************************/
  728.           /* It the type of the field is AUTOEXIT return to the caller once  */
  729.           /* the buffer is full.                                             */
  730.           /*******************************************************************/
  731.           BufLen = strlen( Buffer );
  732.           if( (BufLen == length) &&
  733.               (FieldType & AUTOEXIT) &&
  734.               ((CursorCol - FieldCol) == FieldDisplayLength) )
  735.             rc = RCREDRAW + RCBREAK + RCDATAXT;
  736.           else
  737.             rc = RCREDRAW;
  738.           break;
  739.         }
  740.         else
  741.         {
  742.           keybeep();
  743.           rc = 0;
  744.           break;
  745.         }
  746.       }
  747.     }
  748.  
  749.     /*************************************************************************/
  750.     /* - Turn off the clear field flag after any event.                      */
  751.     /*************************************************************************/
  752.     FieldType &= ~CLEAR1ST;                                             /*910*/
  753.  
  754.    if( rc & RCREDRAW )
  755.    {
  756.      DisplayField( DisplayOffset );
  757.      VioShowBuf( (ushort)voff, (ushort)( 2 * FieldDisplayLength ), 0 );
  758.    }
  759.    if( rc & RCBREAK )
  760.      break;
  761.   }                                     /* end of for loop to handle keystrks*/
  762.     VioSetCurType( &HiddenCursor, 0 );
  763.  
  764.     /*************************************************************************/
  765.     /* - Copy the local buffer to the caller supplied buffer.                */
  766.     /* - Free the local buffer.                                              */
  767.     /* - Reset the keyboard buffer flush flag.                               */
  768.     /*************************************************************************/
  769.     for( n = 0; n < strlen( Buffer ); n++ )
  770.         *pInbuf++ = Buffer[n];
  771.  
  772.     *pInbuf = 0;
  773.     *cursor = CursorCol;
  774.     Tfree( Buffer );
  775.     ResetFlushBufferFlag();                                             /*820*/
  776.     return( (rc & RCDATAXT) ? DATAKEY : key );
  777. }
  778.  
  779. void ShiftRight( uint offset )
  780. {
  781.   int   i, BufLen;
  782.  
  783.   BufLen = strlen( Buffer );
  784.  
  785.   for( i = BufLen; i > 0 && i > offset; i-- )
  786.     Buffer[i] = Buffer[i-1];
  787.  
  788.   Buffer[i] = ' ';
  789. }
  790.  
  791. void ShiftLeft( uint offset )
  792. {
  793.   int   i, BufLen;
  794.  
  795.   BufLen = strlen( Buffer );
  796.  
  797.   for( i = offset; i < BufLen; i++ )
  798.     Buffer[i] = Buffer[i+1];
  799.  
  800.   Buffer[i] = '\0';
  801. }
  802.  
  803. void DisplayField( uint offset )
  804. {
  805.   int    i, j;
  806.   uchar *bp;
  807.  
  808.   bp = Buffer + offset;
  809.  
  810.   for( i = j = 0; j < FieldDisplayLength; i += 2, j++ )
  811.     FieldBase[i] = (*bp) ? *bp++ : '\0';
  812. }
  813.  
  814. void keybeep()
  815. {
  816.     DosBeep( 1000/*Hz*/, 1/*Milliseconds*/ );
  817. }
  818. /*****************************************************************************/
  819. /* GetMouseState()                                                           */
  820. /*                                                                           */
  821. /* Description:                                                              */
  822. /*                                                                           */
  823. /*   Get the next state of mouse button 1.                                   */
  824. /*                                                                           */
  825. /* Parameters:                                                               */
  826. /*                                                                           */
  827. /*   pEvent         -> the new event.                                        */
  828. /*                                                                           */
  829. /* Return:                                                                   */
  830. /*                                                                           */
  831. /*   NextState                                                               */
  832. /*                                                                           */
  833. /*****************************************************************************/
  834. int GetMouseState( PEVENT pEvent )
  835. {
  836.  int NextState;
  837.  
  838.  switch(pEvent->Value)
  839.  {
  840.   case EVENT_NO_BUTTONS_DOWN:
  841.   case EVENT_NO_BUTTONS_DOWN_MOVE:
  842.    NextState = MOU_STATE_UP;
  843.    break;
  844.  
  845.   case EVENT_BUTTON_1_DOWN:
  846.   case EVENT_BUTTON_1_DOWN_MOVE:
  847.    NextState = MOU_STATE_DOWN;
  848.    break;
  849.  
  850.   /***************************************************************************/
  851.   /* - any other events don't change the state.                              */
  852.   /***************************************************************************/
  853.   default:
  854.    break;
  855.  }
  856.  return(NextState);
  857. }
  858.