home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ckc190.zip / ckomou.c < prev    next >
C/C++ Source or Header  |  1994-11-12  |  24KB  |  808 lines

  1. char *ckomouv = "OS/2 Mouse Support 5A(002), 5 Aug 94";
  2.  
  3. /* C K O M O U   --  Kermit mouse support for OS/2 systems */
  4.  
  5. /*
  6.   Author: Jeffrey Altman (p00118@psilink.com)
  7.  
  8.   Copyright (C) 1985, 1994, Trustees of Columbia University in the City of New
  9.   York.  The C-Kermit software may not be, in whole or in part, licensed or
  10.   sold for profit as a software product itself, nor may it be included in or
  11.   distributed with commercial products or otherwise distributed by commercial
  12.   concerns to their clients or customers without written permission of the
  13.   Office of Kermit Development and Distribution, Columbia University.  This
  14.   copyright notice must not be removed, altered, or obscured.
  15. */
  16.  
  17. #include "ckcdeb.h"
  18.  
  19. #ifdef OS2MOUSE
  20.  
  21. #define INCL_NOPM
  22. #define INCL_VIO
  23. #define INCL_MOU
  24. #define INCL_ERRORS
  25. #define INCL_DOSPROCESS
  26. #define INCL_DOSSEMAPHORES
  27. #define INCL_DOSDEVIOCTL
  28. #define INCL_WINCLIPBOARD
  29. #include <os2.h>
  30. #undef COMMENT                /* COMMENT is defined in os2.h */
  31.  
  32. HMOU hMouse = 0 ;
  33. NOPTRRECT SelectedArea = {65535,65535,65535,65535};
  34. BOOL SelectionValid = 0 ;
  35. TID mouthread = 0 ;
  36.  
  37. typedef struct ascreen_rec {    /* Structure for saving screen info */
  38.     unsigned char   ox;
  39.     unsigned char   oy;
  40.     unsigned char   att;
  41.     char            *scrncpy;
  42. } ascreen;
  43.  
  44. ascreen mousescreen ;
  45.  
  46. extern HMUX hmuxKeyStroke ;
  47. extern HMTX hmtxMouseSem = (HMTX) 0 ;
  48.  
  49. extern int tnlm;
  50. extern int wherex;                      /* Screen column, 1-based */
  51. extern int wherey;                      /* Screen row, 1-based    */
  52. extern int xsize;                       /* Screen width           */
  53. extern int ysize;                       /* Screen height          */
  54.  
  55. #define THRDSTKSIZ      131072  /* Needed for Mouse Thread */
  56.  
  57. #define MAXCOL 132                      /* Maximum screen columns */
  58. #define MAXROW 255                      /* Maximum screen rows */
  59.  
  60. /* Functions from ckocon.c */
  61. void savescreen(ascreen *, int, int);
  62. int  restorescreen(ascreen *);
  63. void reverserange( SHORT fromrow, SHORT fromcol, SHORT torow, SHORT tocol );
  64.  
  65. /* See ckocon.c for details on swapcolors macro */
  66. #define swapcolors(x) (((x)&(unsigned)0x88)|(((x)&0x70)>>4)|(((x)&0x07)<<4))
  67.  
  68.  
  69.  
  70. /*
  71. Potential mouse events:
  72.    MOUSE_MOTION
  73.    MOUSE_MOTION_WITH_BN1_DOWN
  74.    MOUSE_BN1_DOWN
  75.    MOUSE_MOTION_WITH_BN2_DOWN
  76.    MOUSE_BN2_DOWN
  77.    MOUSE_MOTION_WITH_BN3_DOWN
  78.    MOUSE_BN3_DOWN      
  79.  
  80. */
  81.  
  82. static BOOL ThreeButton = 0 ;  /* 0 -two buttons, 1 - three buttons */
  83.  
  84. APIRET
  85. CopyVioToKbdBuffer( USHORT bRow, USHORT bCol, USHORT eRow, USHORT eCol ) {
  86.    VIOMODEINFO VioModeInfo ;
  87.    USHORT Length = 0 ;
  88.    SHORT  i, j ;
  89.    BYTE   Buffer[ MAXCOL * MAXROW ] ;
  90.    USHORT tmpRow, tmpCol ;
  91.    /* This code does not work for Hebrew and other BiDi languages */
  92.  
  93.    memset( &VioModeInfo, 0, sizeof(VioModeInfo) ) ;
  94.    VioModeInfo.cb = sizeof(VioModeInfo) ;
  95.    VioGetMode( &VioModeInfo, NULL ) ;
  96.  
  97.    DosRequestMutexSem( hmuxKeyStroke, SEM_INDEFINITE_WAIT ) ;
  98.    os2_mousehide() ;
  99.  
  100.    if ( bRow == eRow && bCol > eCol ) {
  101.       tmpCol = bCol ;
  102.       bCol = eCol ;
  103.       eCol = tmpCol ;
  104.       }
  105.    else if ( bRow > eRow ) {
  106.       tmpRow = bRow ;
  107.       bRow = eRow ;
  108.       eRow = tmpRow ;
  109.       }
  110.    
  111.    if ( eRow - bRow == 0 ) {
  112.       /* copy selected text to KbdBuf clipping spaces */
  113.       Length = eCol - bCol + 1 ;
  114.       VioReadCharStr( Buffer, &Length, bRow, bCol, NULL ) ;
  115.       for ( i = Length - 1 ; i >= 0 ; i-- ) {
  116.          if ( Buffer[i] == ' ' ) {
  117.             Buffer[i] = '\0' ;
  118.             Length-- ;
  119.             }
  120.          else
  121.             break;
  122.          }
  123.       for ( i = 0 ; i < Length ; i++ ) {
  124.          putkey( Buffer[i] ) ;
  125.          }
  126.       }
  127.    else {
  128.       /* partial first line */
  129.       Length = VioModeInfo.col - bCol ;
  130.       VioReadCharStr( Buffer, &Length, bRow, bCol, NULL ) ;
  131.       for ( i = Length - 1 ; i >= 0 ; i-- ) {
  132.          if ( Buffer[i] == ' ' ) {
  133.             Buffer[i] = '\0' ;
  134.             Length-- ;
  135.             }
  136.          else
  137.             break;
  138.          }
  139.       for ( i = 0 ; i < Length ; i++ ) {
  140.          putkey( Buffer[i] ) ;
  141.          }
  142.       putkey( '\r' ) ;
  143.       if (tnlm)
  144.          putkey( '\n' ) ;
  145.  
  146.       /* complete middle rows */
  147.       for ( j = bRow + 1 ; j < eRow ; j++ ) {
  148.          Length = VioModeInfo.col ;
  149.          VioReadCharStr( Buffer, &Length, j, 0, NULL ) ;
  150.          for ( i = Length - 1 ; i >= 0 ; i-- ) {
  151.             if ( Buffer[i] == ' ' ) {
  152.                Buffer[i] = '\0' ;
  153.                Length-- ;
  154.                }
  155.             else
  156.                break;
  157.             }
  158.          for ( i = 0 ; i < Length ; i++ ) {
  159.             putkey( Buffer[i] ) ;
  160.             }
  161.          putkey( '\r' ) ;
  162.          if (tnlm)
  163.             putkey( '\n' ) ;
  164.  
  165.          }
  166.  
  167.       /* partial last line */
  168.       Length = eCol ;
  169.       VioReadCharStr( Buffer, &Length, eRow, 0, NULL ) ;
  170.       for ( i = Length - 1 ; i >= 0 ; i-- ) {
  171.          if ( Buffer[i] == ' ' ) {
  172.             Buffer[i] = '\0' ;
  173.             Length-- ;
  174.             }
  175.          else
  176.             break;
  177.          }
  178.       for ( i = 0 ; i < Length ; i++ ) {
  179.          putkey( Buffer[i] ) ;
  180.          }
  181.       }
  182.  
  183.    os2_mouseshow() ;
  184.    DosReleaseMutexSem( hmuxKeyStroke ) ;
  185. }
  186.  
  187. APIRET
  188. CopyClipboardToKbdBuffer( void )
  189. {
  190.    int i = 0 ;
  191.    APIRET rc = -1 ;
  192.    BYTE * hClipbrdData ;
  193.    BYTE * pData = 0 ;
  194.    BYTE * pClipboard ;
  195.    
  196.    if ( WinOpenClipbrd(0) )
  197.    {
  198.       hClipbrdData = (BYTE *) WinQueryClipbrdData( 0, CF_TEXT ) ;
  199.       if ( !DosGetSharedMem( hClipbrdData, PAG_READ ) )
  200.          {
  201.          pData = strdup( hClipbrdData ) ;
  202.  
  203.          /* We must copy the text back to the Clipboard because the   */
  204.          /* GetSharedMemory call screwed up the clipboard.  We're not */
  205.          /* supposed to do things like that.                          */
  206.          if ( !DosAllocSharedMem( (PPVOID) &pClipboard, 0, strlen(pData)+1,
  207.                    PAG_COMMIT | PAG_READ | PAG_WRITE |
  208.                    OBJ_GIVEABLE | OBJ_GETTABLE | OBJ_TILE ) )
  209.             {
  210.             strcpy( pClipboard, pData ) ;
  211.          WinSetClipbrdData( 0, (ULONG) pClipboard, CF_TEXT, CFI_POINTER ) ;
  212.             }
  213.          }
  214.       WinCloseClipbrd( 0 ) ;
  215.  
  216.       if ( pData )
  217.       {
  218.          DosRequestMutexSem( hmuxKeyStroke, SEM_INDEFINITE_WAIT ) ;
  219.          while ( pData[i] != '\0' ) {
  220.             if ( pData[i] != '\012' || ( pData[i] == '\012' && tnlm ) )
  221.                putkey( pData[i] ) ;
  222.             i++ ;
  223.          }
  224.          DosReleaseMutexSem( hmuxKeyStroke ) ;
  225.          rc = 0 ;
  226.       }
  227.    }
  228.    return rc ;
  229. }
  230.  
  231. APIRET
  232. CopyVioToClipboard( USHORT bRow, USHORT bCol, USHORT eRow, USHORT eCol )
  233. {
  234.    VIOMODEINFO VioModeInfo ;
  235.    USHORT Length = 0, ClipBoardSz ;
  236.    SHORT i, j ;
  237.    BYTE   Buffer[ MAXCOL * MAXROW ] ;
  238.    USHORT tmpRow, tmpCol ;
  239.    BYTE * pClipboard = 0 ;
  240.    APIRET rc = 0 ;
  241.  
  242.    /* This code does not work for Hebrew and other BiDi languages */
  243.    memset( &VioModeInfo, 0, sizeof(VioModeInfo) ) ;
  244.    VioModeInfo.cb = sizeof(VioModeInfo) ;
  245.    VioGetMode( &VioModeInfo, NULL ) ;
  246.  
  247.    if ( bRow == eRow && bCol > eCol ) {
  248.       tmpCol = bCol ;
  249.       bCol = eCol ;
  250.       eCol = tmpCol ;
  251.       }
  252.    else if ( bRow > eRow ) {
  253.       tmpRow = bRow ;
  254.       bRow = eRow ;
  255.       eRow = tmpRow ;
  256.       }
  257.  
  258.    /* Determine size of and allocate Clipboard */
  259.    if ( eRow - bRow == 0 ) {
  260.       ClipBoardSz = eCol - bCol + 4 ;
  261.       }
  262.    else {
  263.       ClipBoardSz = VioModeInfo.col - bCol + 2 ;
  264.       for ( j = bRow + 1 ; j < eRow ; j++ )
  265.          ClipBoardSz += VioModeInfo.col + 2 ;
  266.       ClipBoardSz += eCol + 4 ;
  267.       }
  268.  
  269.     if ( rc = DosAllocSharedMem( (PPVOID) &pClipboard, 0, ClipBoardSz,
  270.                    PAG_COMMIT | PAG_READ | PAG_WRITE |
  271.                    OBJ_GIVEABLE | OBJ_GETTABLE | OBJ_TILE ) )
  272.       {
  273.       return -1 ;
  274.       }
  275.    pClipboard[0] = '\0' ;
  276.    os2_mousehide() ;
  277.  
  278.    if ( eRow - bRow == 0 ) {
  279.       /* copy selected text to KbdBuf clipping spaces */
  280.       Length = eCol - bCol + 1 ;
  281.       VioReadCharStr( Buffer, &Length, bRow, bCol, NULL ) ;
  282.       for ( i = Length - 1 ; i >= 0 ; i-- ) {
  283.          if ( Buffer[i] == ' ' ) {
  284.             Buffer[i] = '\0' ;
  285.             Length-- ;
  286.             }
  287.          else
  288.             break;
  289.          }
  290.       strncat( pClipboard, Buffer, Length ) ;
  291.       }
  292.    else {
  293.       /* partial first line */
  294.       Length = VioModeInfo.col - bCol ;
  295.       VioReadCharStr( Buffer, &Length, bRow, bCol, NULL ) ;
  296.       for ( i = Length - 1 ; i >= 0 ; i-- ) {
  297.          if ( Buffer[i] == ' ' ) {
  298.             Buffer[i] = '\0' ;
  299.             Length-- ;
  300.             }
  301.          else
  302.             break;
  303.          }
  304.       strncat( pClipboard, Buffer, Length ) ;
  305.       strncat( pClipboard, "\r\n", 2 ) ;
  306.  
  307.       /* complete middle rows */
  308.       for ( j = bRow + 1 ; j < eRow ; j++ ) {
  309.          Length = VioModeInfo.col ;
  310.          VioReadCharStr( Buffer, &Length, j, 0, NULL ) ;
  311.          for ( i = Length - 1 ; i >= 0 ; i-- ) {
  312.             if ( Buffer[i] == ' ' ) {
  313.                Buffer[i] = '\0' ;
  314.                Length-- ;
  315.                }
  316.             else
  317.                break;
  318.             }
  319.          strncat( pClipboard, Buffer, Length ) ;
  320.          strncat( pClipboard, "\r\n", 2 ) ;
  321.          }
  322.  
  323.       /* partial last line */
  324.       Length = eCol ;
  325.       VioReadCharStr( Buffer, &Length, eRow, 0, NULL ) ;
  326.       for ( i = Length - 1 ; i >= 0 ; i-- ) {
  327.          if ( Buffer[i] == ' ' ) {
  328.             Buffer[i] = '\0' ;
  329.             Length-- ;
  330.             }
  331.          else
  332.             break;
  333.          }
  334.       strncat( pClipboard, Buffer, Length ) ;
  335.       }
  336.  
  337.    if ( WinOpenClipbrd( 0 ) )
  338.       {
  339.       if ( !WinSetClipbrdData( 0, (ULONG) pClipboard, CF_TEXT, CFI_POINTER ) )
  340.          DosFreeMem( pClipboard ) ;
  341.       WinCloseClipbrd( 0 ) ;
  342.       }
  343.    else
  344.       {
  345.       DosFreeMem( pClipboard ) ;
  346.       }
  347.  
  348.    os2_mouseshow() ;
  349.    return 0 ;
  350. }
  351.  
  352. APIRET
  353. os2_mouseshow( void )
  354. {
  355.   APIRET rc = 0 ;
  356.   NOPTRRECT PtrArea ;
  357.   VIOMODEINFO ModeData ;
  358.  
  359.    if ( hMouse )
  360.      {
  361.    ModeData.cb = sizeof(ModeData) ;
  362.      VioGetMode( &ModeData, 0 ) ;
  363.  
  364.    PtrArea.row = ModeData.row - 1 ;
  365.    PtrArea.col = 0 ;
  366.      PtrArea.cRow = ModeData.row - 1;
  367.    PtrArea.cCol = ModeData.col - 1 ;
  368.  
  369.    MouRemovePtr( &PtrArea, hMouse ) ;
  370.    }
  371.   return rc ;
  372. }
  373.  
  374. APIRET
  375. os2_mousehide( void )
  376. {
  377.   APIRET rc = 0 ;
  378.   NOPTRRECT PtrArea ;
  379.   VIOMODEINFO ModeData ;
  380.  
  381.   if (hMouse)
  382.    {
  383.    ModeData.cb = sizeof(ModeData) ;
  384.      VioGetMode( &ModeData, 0 ) ;
  385.  
  386.    PtrArea.row = 0 ;
  387.    PtrArea.col = 0 ;
  388.      PtrArea.cRow = ModeData.row - 1;
  389.    PtrArea.cCol = ModeData.col - 1 ;
  390.  
  391.    MouRemovePtr( &PtrArea, hMouse ) ;
  392.    }
  393.   return rc ;
  394. }
  395.  
  396. APIRET
  397. os2_mouseon( void ) {
  398.     APIRET rc = 0 ;
  399.     PTRLOC    PtrPos ; 
  400.     NOPTRRECT PtrArea ;
  401.     VIOMODEINFO ModeData ;
  402.     USHORT    ButtonCount ;
  403.     USHORT    EventMask ;
  404.  
  405.     if (!mouthread) {
  406.       rc = MouOpen( 0, &hMouse ) ;
  407.       debug(F101,"Mouse On","",rc) ;
  408.       }
  409.  
  410.     if ( !rc ) {
  411.       DosCreateMutexSem( 0, &hmtxMouseSem, 0, 0 ) ;
  412.  
  413.       rc = MouDrawPtr( hMouse ) ;
  414.        ModeData.cb = sizeof(ModeData) ;
  415.        VioGetMode( &ModeData, 0 ) ;
  416.  
  417.       PtrPos.row = ModeData.row - 1 ;
  418.       PtrPos.col = 0 ;
  419.       MouSetPtrPos( &PtrPos, hMouse ) ;
  420.  
  421.       PtrArea.row = ModeData.row - 1 ;
  422.        PtrArea.col = 0 ;
  423.        PtrArea.cRow = ModeData.row - 1;
  424.        PtrArea.cCol = ModeData.col - 1 ;
  425.  
  426.       MouRemovePtr( &PtrArea, hMouse ) ;
  427.  
  428.       MouGetNumButtons( &ButtonCount, hMouse ) ;
  429.       debug(F101,"os2_mouseon Button Count","",ButtonCount ) ;
  430.  
  431.       if ( ButtonCount == 3 )
  432.          {
  433.          ThreeButton = 1 ;
  434.          EventMask      = MOUSE_MOTION |
  435.                           MOUSE_BN1_DOWN |
  436.                           MOUSE_MOTION_WITH_BN1_DOWN |
  437.                           MOUSE_BN3_DOWN |
  438.                           MOUSE_MOTION_WITH_BN3_DOWN ;
  439.          }
  440.       else  /* 2 buttons */
  441.          {
  442.          ThreeButton = 0 ;
  443.          EventMask      = MOUSE_MOTION |
  444.                           MOUSE_BN1_DOWN |
  445.                           MOUSE_MOTION_WITH_BN1_DOWN |
  446.                           MOUSE_BN2_DOWN |
  447.                           MOUSE_MOTION_WITH_BN2_DOWN ;
  448.          }
  449.       MouSetEventMask( &EventMask, hMouse ) ;
  450.  
  451.       if (!mouthread) {
  452.          mouthread = _beginthread( &os2_mouseevt, 0, THRDSTKSIZ, 0 ) ;
  453.          }
  454.       }
  455.  
  456.     return rc ;
  457. }
  458.  
  459. static int
  460. selectiontype(void)
  461. {
  462.    int rc ;
  463.  
  464.    if ( !SelectionValid ||
  465.         SelectedArea.row == SelectedArea.cRow &&
  466.         SelectedArea.col == SelectedArea.cCol )
  467.       rc = 0 ;
  468.    else if ( SelectedArea.cRow > SelectedArea.row ||
  469.         SelectedArea.cRow == SelectedArea.row &&
  470.         SelectedArea.cCol > SelectedArea.col )
  471.       rc = 1 ;
  472.    else
  473.       rc = -1 ;
  474.  
  475.    debug(F101,"SelectionType","",rc) ;
  476.    return rc ;
  477. }
  478.  
  479. static int
  480. isselected( USHORT row, USHORT col )
  481. {
  482.    int rc ; 
  483.    if ( !SelectionValid )
  484.       rc = 0 ;
  485.    else 
  486.    switch( selectiontype() )
  487.    {
  488.       case 0:
  489.          rc = ( SelectedArea.row == row && SelectedArea.col == col ) ?
  490.              1 : 0 ;
  491.          break;
  492.       case 1:
  493.          if ( SelectedArea.row == SelectedArea.cRow &&
  494.               SelectedArea.row == row &&
  495.               col >= SelectedArea.col &&
  496.               col <= SelectedArea.cCol )
  497.             rc = 1 ;
  498.          else if ( SelectedArea.row == row &&
  499.               SelectedArea.col <= col &&
  500.               SelectedArea.cCol >= col )
  501.             rc = 1 ;
  502.          else if ( SelectedArea.row < row &&
  503.               SelectedArea.cRow > row )
  504.             rc = 1 ;
  505.          else if ( SelectedArea.cRow == row &&
  506.                    SelectedArea.cCol >= col )
  507.             rc = 1 ;
  508.          else
  509.             rc = 0 ;
  510.          break;
  511.  
  512.       case -1:
  513.          if ( SelectedArea.row == SelectedArea.cRow &&
  514.               SelectedArea.row == row &&
  515.               col <= SelectedArea.col &&
  516.               col >= SelectedArea.cCol )
  517.             rc = 1 ;
  518.          else if ( SelectedArea.row == row &&
  519.               SelectedArea.col >= col &&
  520.               SelectedArea.cCol <= col )
  521.             rc = 1 ;
  522.          else if ( SelectedArea.row > row &&
  523.               SelectedArea.cRow < row )
  524.             rc = 1 ;
  525.          else if ( SelectedArea.cRow == row &&
  526.                    SelectedArea.cCol <= col )
  527.             rc = 1 ;
  528.          else
  529.             rc = 0 ;
  530.          break;
  531.       default:
  532.          rc = 0 ;
  533.    }
  534.  
  535.    debug(F101,"isselected","",rc) ;
  536.    return rc ;
  537. }
  538.  
  539. void
  540. os2_mouseevt(void *pArgList) {
  541.     APIRET rc ;
  542.     MOUEVENTINFO MouseEventInfo ;
  543.     USHORT       ReadType = MOU_NOWAIT ;
  544.     USHORT Vrow, Vcol, n ;
  545.     BYTE   cell[MAXCOL * 2] ;
  546.     static int b1=0, b1time=0, b2=0, b2time=0, b3=0, b3time=0 ;
  547.     static USHORT lastrow=0, lastcol=0,
  548.                   b1row = 0, b1col = 0, b2row = 0, b2col = 0 ;
  549.     const DBCLICK = 1000 ;
  550.    
  551.    DosSetPriority( PRTYS_THREAD, PRTYC_NOCHANGE, PRTYD_MINIMUM, 0 ) ;
  552.    while (hMouse)
  553.    {
  554.       memset( &MouseEventInfo, 0, sizeof( MOUEVENTINFO ) ) ;   
  555.       rc = MouReadEventQue( &MouseEventInfo, &ReadType, hMouse ) ;
  556.       if ( rc == NO_ERROR && MouseEventInfo.time )
  557.       {
  558.          char buffer[1024] ;
  559.          sprintf(buffer, "  Event: fs:%3x time:%10d row:%3d col:%3d",
  560.                  MouseEventInfo.fs, MouseEventInfo.time,
  561.                  MouseEventInfo.row, MouseEventInfo.col) ;
  562.          debug(F110,"os2_mouseevt",buffer,0) ;
  563.  
  564.          VioGetCurPos( &Vrow, &Vcol, NULL ) ;
  565.  
  566.          if ( MouseEventInfo.row == ysize )
  567.             MouseEventInfo.row-- ;
  568.  
  569.          if ( MouseEventInfo.fs & MOUSE_BN1_DOWN )
  570.          {
  571.                if ( b1 == 1 &&
  572.                  MouseEventInfo.time - b1time < DBCLICK &&
  573.                      MouseEventInfo.row == b1row &&
  574.                     MouseEventInfo.col == b1col )
  575.             {
  576.                /* Double Click */
  577.                b1 = 2 ;
  578.                    DosRequestMutexSem(hmuxKeyStroke,SEM_INDEFINITE_WAIT);
  579.                   for (; Vcol > MouseEventInfo.col; Vcol-- )
  580.                {
  581.                       putkey( 587 ) ; /* LEFT */
  582.                }
  583.                   for (; Vrow > MouseEventInfo.row; Vrow-- )
  584.                {
  585.                       putkey( 584 ) ; /* UP */
  586.                   }
  587.                    for (; Vrow < MouseEventInfo.row; Vrow++ )
  588.                {
  589.                       putkey( 592 ) ; /* DOWN */
  590.                   }
  591.                    for (; Vcol < MouseEventInfo.col; Vcol++ )
  592.                {
  593.                       putkey( 589 ) ; /* RIGHT */
  594.                   }
  595.                    DosReleaseMutexSem( hmuxKeyStroke ) ;
  596.                SelectionValid = 0 ;
  597.             }
  598.             else if ( b1 == 0 )
  599.             {
  600.                    /* Single Click */
  601.                    b1 = 1 ;
  602.                    b1time = MouseEventInfo.time ;
  603.                b1row = MouseEventInfo.row ;
  604.                b1col = MouseEventInfo.col ;
  605.    
  606.                DosRequestMutexSem( hmtxMouseSem, SEM_INDEFINITE_WAIT ) ; 
  607.                savescreen(&mousescreen,wherex,wherey);
  608.                SelectionValid = 1 ;
  609.                SelectedArea.row = SelectedArea.cRow = MouseEventInfo.row ;
  610.                   SelectedArea.col = SelectedArea.cCol = MouseEventInfo.col ;
  611.  
  612.                n = 2 ;
  613.                os2_mousehide() ;
  614.                VioReadCellStr( cell, &n, MouseEventInfo.row, MouseEventInfo.col, 0 );
  615.                      cell[1] = swapcolors(cell[1]) ;
  616.                VioWrtCellStr( cell, n, MouseEventInfo.row, MouseEventInfo.col, 0 ) ;
  617.                os2_mouseshow() ;
  618.                }
  619.          }
  620.          else if ( MouseEventInfo.fs & MOUSE_MOTION_WITH_BN1_DOWN )
  621.          {
  622.             if ( b1 == 1 &&
  623.                  SelectionValid &&
  624.                  ( lastrow != MouseEventInfo.row ||
  625.                    lastcol != MouseEventInfo.col ) )
  626.             {
  627.                if ( isselected( MouseEventInfo.row, MouseEventInfo.col ) )
  628.                {
  629.                   if ( selectiontype() > 0 )
  630.                      {
  631.                         reverserange( SelectedArea.cRow, SelectedArea.cCol,
  632.                           MouseEventInfo.row, MouseEventInfo.col+1 );
  633.                      }
  634.                   else if ( selectiontype() < 0 )
  635.                      {
  636.                         reverserange( SelectedArea.cRow, SelectedArea.cCol,
  637.                           MouseEventInfo.row, MouseEventInfo.col-1 );
  638.                      }
  639.                }
  640.                else
  641.                {
  642.                   if ( selectiontype() > 0 )
  643.                      if ( MouseEventInfo.row >= SelectedArea.cRow )
  644.                         reverserange( SelectedArea.cRow, SelectedArea.cCol+1,
  645.                            MouseEventInfo.row, MouseEventInfo.col );
  646.                      else
  647.                         {
  648.                         reverserange( SelectedArea.cRow, SelectedArea.cCol,
  649.                            SelectedArea.row, SelectedArea.col+1);
  650.                         reverserange( SelectedArea.row, SelectedArea.col-1,
  651.                            MouseEventInfo.row, MouseEventInfo.col);
  652.                         }
  653.                   else if ( selectiontype() < 0 )
  654.                      if ( MouseEventInfo.row <= SelectedArea.cRow )
  655.                         reverserange( SelectedArea.cRow, SelectedArea.cCol-1,
  656.                            MouseEventInfo.row, MouseEventInfo.col );
  657.                      else
  658.                         {
  659.                         reverserange( SelectedArea.cRow, SelectedArea.cCol,
  660.                            SelectedArea.row, SelectedArea.col-1);
  661.                         reverserange( SelectedArea.row, SelectedArea.col+1,
  662.                            MouseEventInfo.row, MouseEventInfo.col);
  663.                         }
  664.                   else if ( MouseEventInfo.row < SelectedArea.cRow ||
  665.                             MouseEventInfo.row == SelectedArea.cRow &&
  666.                             MouseEventInfo.col < SelectedArea.cCol )
  667.                      reverserange( SelectedArea.cRow, SelectedArea.cCol-1,
  668.                           MouseEventInfo.row, MouseEventInfo.col );
  669.                   else if ( MouseEventInfo.row > SelectedArea.cRow ||
  670.                             MouseEventInfo.row == SelectedArea.cRow &&
  671.                             MouseEventInfo.col > SelectedArea.cCol )
  672.                      reverserange( SelectedArea.cRow, SelectedArea.cCol+1,
  673.                           MouseEventInfo.row, MouseEventInfo.col );
  674.                }
  675.                    SelectedArea.cRow = MouseEventInfo.row ;
  676.                    SelectedArea.cCol = MouseEventInfo.col ;
  677.             }
  678.          }
  679.          else
  680.          {  /* Button One Up */
  681.                if ( b1 == 1 )
  682.             {
  683.                if ( MouseEventInfo.time - b1time > DBCLICK )
  684.                {
  685.                   b1 = 0 ;
  686.                   b1time = 0 ;
  687.                   b1row = 0 ;
  688.                   b1col = 0 ;
  689.                }
  690.  
  691.                if ( SelectionValid ) {
  692.                       CopyVioToClipboard( SelectedArea.row, SelectedArea.col,
  693.                           SelectedArea.cRow, SelectedArea.cCol ) ;
  694.                   SelectionValid = 0 ;
  695.                   restorescreen(&mousescreen);
  696.                   DosReleaseMutexSem( hmtxMouseSem ) ; 
  697.                   }
  698.                 }
  699.             else if ( b1 == 2 )
  700.             {
  701.                b1 = 0 ;
  702.                b1time = 0 ;
  703.                b1row = 0 ;
  704.                b1col = 0 ;
  705.                DosReleaseMutexSem( hmtxMouseSem ) ; 
  706.             }
  707.          }
  708.  
  709.             if ( !ThreeButton && ( MouseEventInfo.fs & MOUSE_BN2_DOWN ) ||
  710.                ThreeButton && ( MouseEventInfo.fs & MOUSE_BN3_DOWN ) )
  711.          {
  712.                if ( b2 == 1 &&
  713.                  MouseEventInfo.time - b2time < DBCLICK &&
  714.                  MouseEventInfo.col == b2col &&
  715.                  MouseEventInfo.row == b2row )
  716.             {
  717.                    /* Double Click */
  718.                b2 = 2 ;
  719.                if ( b1 == 0 )
  720.                {
  721.                   CopyClipboardToKbdBuffer() ;
  722.                }
  723.                }
  724.             else if ( b2 == 0 )
  725.             {
  726.                b2 = 1 ;
  727.                   b2time = MouseEventInfo.time ;
  728.                b2row = MouseEventInfo.row ;
  729.                b2col = MouseEventInfo.col ;
  730.  
  731.                if ( b1 == 1 )
  732.                {
  733.                   if ( SelectionValid )
  734.                   {
  735.                          CopyVioToKbdBuffer(SelectedArea.row,
  736.                               SelectedArea.col,
  737.                               SelectedArea.cRow,
  738.                               SelectedArea.cCol );
  739.                      SelectionValid = 0 ;
  740.                      restorescreen(&mousescreen) ;
  741.                      DosReleaseMutexSem( hmtxMouseSem ) ;
  742.                   }
  743.                }
  744.               }
  745.          }
  746.          else if ( !ThreeButton &&
  747.                     ( MouseEventInfo.fs & MOUSE_MOTION_WITH_BN2_DOWN ) ||
  748.                     ThreeButton &&
  749.                     ( MouseEventInfo.fs & MOUSE_MOTION_WITH_BN3_DOWN ) )
  750.          {
  751.                 /* Do Nothing */
  752.          }
  753.          else /* Button Two Up */
  754.          {
  755.             if ( b2 == 1 )
  756.             {
  757.                if ( MouseEventInfo.time - b2time > DBCLICK )
  758.                   {
  759.                   b2time = b2 = 0 ;
  760.                   }
  761.             }
  762.                 if ( b2 == 2 )
  763.             {
  764.                b2 = 0 ;
  765.                b2time = 0 ;
  766.             }
  767.          }
  768.  
  769.          lastcol = MouseEventInfo.col ;
  770.          lastrow = MouseEventInfo.row ;
  771.       }
  772.       else /* No Mouse Event so release time slice */
  773.       {
  774. #ifdef COMMENT
  775.          char buffer[1024] ;
  776.          sprintf(buffer, "NoEvent: fs:%3x time:%10d row:%3d col:%3d",
  777.                  MouseEventInfo.fs, MouseEventInfo.time,
  778.                  MouseEventInfo.row, MouseEventInfo.col) ;
  779.          debug(F110,"os2_mouseevt",buffer,0) ;
  780. #endif /* COMMENT */
  781.          DosSleep(1) ;
  782.       }
  783.    }
  784.    _endthread();
  785. }
  786.  
  787. APIRET
  788. os2_mouseoff( void ) {
  789.     APIRET rc = 0 ;
  790.  
  791.  
  792.     if ( hMouse ) {
  793.     rc = MouClose( hMouse ) ;
  794.         debug(F101,"Mouse Off","",rc) ;
  795.         hMouse = 0 ;
  796.         DosWaitThread( &mouthread, DCWW_WAIT ) ;
  797.         debug(F100,"os2_mouevt() thread dead","",0) ;
  798.         mouthread = 0 ;
  799.       
  800.         DosCloseMutexSem( hmtxMouseSem ) ;
  801.         hmtxMouseSem = (HMTX) 0 ;
  802.     }
  803.     return rc ;
  804. }
  805. #endif /* OS2MOUSE */
  806.  
  807.  
  808.