home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / df3os2.zip / MOUSE.CPP < prev    next >
C/C++ Source or Header  |  1993-10-30  |  12KB  |  409 lines

  1. // ------------- mouse.cpp
  2. //
  3. // rewritten for OS/2 operation - jw26sep93
  4.  
  5. #include <stdio.h>
  6. #include "desktop.h"
  7.  
  8. // removed Moved(), LeftButton() and ButtonReleased() as these are only used 
  9. // internally by the mouse, and should not really ever have been public.
  10. // Possibly the same should happen for GetPosition.
  11.  
  12. Mouse::Mouse()
  13.     {
  14.     USHORT EventMask = MOUSE_MOTION | 
  15.                        MOUSE_BN1_DOWN | 
  16.                        MOUSE_MOTION_WITH_BN1_DOWN;
  17.  
  18.     installed = False;
  19.  
  20.     if (MouOpen(NULL, &hMou) == NO_ERROR)
  21.         {
  22.         installed = True;
  23.         MouFlushQue(hMou);
  24.  
  25.         // should probably save and restore mouse state
  26.  
  27.         repeatticks = REPEAT;
  28.         delayticks  = DELAY;
  29.         doubleticks = DOUBLE;
  30.  
  31.         previnfo.col = 
  32.         previnfo.row = -1;
  33.  
  34.         curState = STATE_MOUSE_IDLE;
  35.  
  36.         MouSetEventMask(&EventMask, hMou);
  37.  
  38.         SetTravel(0,
  39.                   desktop.screen().Width()-1,
  40.                   0,
  41.                   desktop.screen().Height()-1);
  42.         }
  43.     }
  44.  
  45.  
  46. Mouse::~Mouse()
  47.     {
  48.     if (installed)    
  49.         {
  50.         Hide();
  51.         }
  52.     }
  53.  
  54.  
  55. // ------ get the window to send mouse events
  56. DFWindow *Mouse::MouseWindow(int mx, int my)
  57.     {
  58.     DFWindow *Mwnd = desktop.inWindow(mx, my);
  59.  
  60.     if (Mwnd == 0)
  61.         {
  62.         Mwnd = desktop.FocusCapture();
  63.         }
  64.     else if (desktop.FocusCapture() != 0)
  65.         {
  66.         if (!Mwnd->isDescendedFrom(desktop.FocusCapture()))
  67.             {
  68.             Mwnd = desktop.FocusCapture();
  69.             }
  70.         }
  71.     return Mwnd;
  72.     }
  73.  
  74. void Mouse::GetPosition(int &mx, int &my)
  75.     {
  76.     mx = currinfo.col;
  77.     my = currinfo.row;
  78.     }
  79.  
  80.  
  81. void Mouse::SetPosition(int x, int y)
  82.     {
  83.     PTRLOC  loc;
  84.  
  85.     if (installed)    
  86.         {
  87.         loc.row = (USHORT)y;
  88.         loc.col = (USHORT)x;
  89.         MouSetPtrPos(&loc, hMou);
  90.         }
  91.     }
  92.  
  93.  
  94. void Mouse::Show()
  95.     {
  96.     MouDrawPtr(hMou);
  97.     }
  98.  
  99. void Mouse::Hide()
  100.     {
  101.     NOPTRRECT   rect;
  102.  
  103.     if (installed) 
  104.         {
  105.         rect.row = 0;
  106.         rect.col = 0;
  107.         rect.cRow = (USHORT)(desktop.screen().Height()-1);
  108.         rect.cCol = (USHORT)(desktop.screen().Width()-1);
  109.         MouRemovePtr(&rect, hMou);
  110.         }
  111.     }
  112.  
  113. void Mouse::SetTravel(int minx, int maxx, int miny, int maxy)
  114.     {
  115.     inclRect.col = (USHORT)minx;
  116.     inclRect.row = (USHORT)miny;
  117.     inclRect.cCol = (USHORT)maxx;
  118.     inclRect.cRow = (USHORT)maxy;
  119.     }
  120.  
  121.  
  122. // -------- Event dispatch and handling -----
  123.  
  124. void Mouse::DispatchEvent()
  125.     {
  126.     MOUQUEINFO  qi;
  127.     USHORT      wait = MOU_NOWAIT;
  128.  
  129.     if (installed)
  130.         {
  131.         MouGetNumQueEl(&qi, hMou);
  132.     
  133.         if(qi.cEvents != 0)
  134.             {
  135.             previnfo = currinfo;                      
  136.             MouReadEventQue(&currinfo, &wait, hMou);
  137.  
  138.  
  139.             // if moved: ensure coordinates are
  140.             //           within inclusion rectangle
  141.             if ((currinfo.row != previnfo.row) ||
  142.                 (currinfo.col != previnfo.col))
  143.                 {
  144.                 // handle inclusion rectangle
  145.                 if (currinfo.row < inclRect.row)
  146.                     {
  147.                     currinfo.row = inclRect.row;
  148.                     }
  149.  
  150.                 if (currinfo.col < inclRect.col)
  151.                     {
  152.                     currinfo.col = inclRect.col;
  153.                     }
  154.  
  155.                 if (currinfo.row > inclRect.cRow)
  156.                     {
  157.                     currinfo.row = inclRect.cRow;
  158.                     }
  159.  
  160.                 if (currinfo.col > inclRect.cCol)
  161.                     {
  162.                     currinfo.col = inclRect.cCol;
  163.                     }
  164.  
  165.                 HandleEvent(EVENT_MOUSE_MOVED);
  166.                 }
  167.  
  168.             // Handle changes in button state
  169.             int DepressedNow    = ((currinfo.fs & Depression) != 0);
  170.             int DepressedBefore = ((previnfo.fs & Depression) != 0);
  171.  
  172.             if (!DepressedNow && DepressedBefore) 
  173.                 {
  174.                 HandleEvent(EVENT_MOUSE_RELEASED);
  175.                 }
  176.  
  177.             if (DepressedNow && !DepressedBefore) 
  178.                 {
  179.                 HandleEvent(EVENT_MOUSE_DEPRESSED);
  180.                 }
  181.  
  182.             }
  183.  
  184.         // Handle timer events
  185.         if (timerRunning && timer.TimedOut())
  186.             {
  187.             HandleEvent(EVENT_MOUSE_TIMEREXPIRED);
  188.             timerRunning = False;
  189.             }
  190.         else if (!timerRunning && timer.TimerRunning())
  191.             {
  192.             timerRunning = True;
  193.             }
  194.         }
  195.     return;
  196.     }
  197.  
  198.  
  199. void Mouse::HandleEvent(Event event)
  200.     {
  201.     DFWindow *Mwnd;
  202.  
  203.     if ((Mwnd = MouseWindow(currinfo.col, currinfo.row)) == NULL)
  204.         {
  205.         return;
  206.         }
  207.  
  208.     switch(curState)
  209.         {
  210.         case STATE_MOUSE_IDLE:
  211.             {
  212.             switch(event)
  213.                 {
  214.                 case EVENT_MOUSE_MOVED:
  215.                     {
  216.                     // dispatch MouseMoved message to window
  217.                     Mwnd->MouseMoved(currinfo.col, currinfo.row);
  218.                     break;
  219.                     }
  220.                 case EVENT_MOUSE_DEPRESSED:
  221.                     {
  222.                     // change to 'depressed' state
  223.                     curState = STATE_MOUSE_DEPRESSED;
  224.                     if (Mwnd->SetFocus())
  225.                         {
  226.                         Mwnd->LeftButton(currinfo.col, currinfo.row);
  227.                         }
  228.                     timer.SetTimer(delayticks);
  229.                     break;
  230.                     }
  231.                 case EVENT_MOUSE_RELEASED:
  232.                     {
  233.                     // Error - cannot happen !
  234.                     DosBeep(1000, 200);
  235.                     DosBeep(500, 500);
  236.                     break;
  237.                     }
  238.                 case EVENT_MOUSE_TIMEREXPIRED:
  239.                     {
  240.                     // Ignore
  241.                     break;
  242.                     }
  243.                 }
  244.             break;
  245.             }
  246.  
  247.         case STATE_MOUSE_DEPRESSED:
  248.             {
  249.             switch(event)
  250.                 {
  251.                 case EVENT_MOUSE_MOVED:
  252.                     {
  253.                     // dispatch MouseMoved message to window
  254.                     Mwnd->MouseMoved(currinfo.col, currinfo.row);
  255.                     break;
  256.                     }
  257.                 case EVENT_MOUSE_DEPRESSED:
  258.                     {
  259.                     // Error - cannot happen !
  260.                     DosBeep(1000, 500);
  261.                     DosBeep(500, 500);
  262.                     break;
  263.                     }
  264.                 case EVENT_MOUSE_RELEASED:
  265.                     {
  266.                     // Possible double click
  267.                     curState = STATE_MOUSE_RELEASED;
  268.                     timer.SetTimer(doubleticks);
  269.                     Mwnd->ButtonReleased(currinfo.col, currinfo.row);
  270.                     break;
  271.                     }
  272.                 case EVENT_MOUSE_TIMEREXPIRED:
  273.                     {
  274.                     // Held down a while; start typematic
  275.                     curState = STATE_MOUSE_REPEAT;
  276.                     timer.SetTimer(repeatticks);
  277.                     Mwnd->LeftButton(currinfo.col, currinfo.row);
  278.                     break;
  279.                     }
  280.                 }
  281.             break;
  282.             }
  283.     
  284.         case STATE_MOUSE_RELEASED:
  285.             {
  286.             switch(event)
  287.                 {
  288.                 case EVENT_MOUSE_MOVED:
  289.                     {
  290.                     // dispatch MouseMoved message to window
  291.                     curState=STATE_MOUSE_IDLE;
  292.                     Mwnd->MouseMoved(currinfo.col, currinfo.row);
  293.                     break;
  294.                     }
  295.                 case EVENT_MOUSE_DEPRESSED:
  296.                     {
  297.                     // Probably a double-click
  298.                     curState=STATE_MOUSE_DWAIT;
  299.                     Mwnd->LeftButton(currinfo.col, currinfo.row);
  300.                     break;
  301.                     }
  302.                 case EVENT_MOUSE_RELEASED:
  303.                     {
  304.                     // Error - cannot happen !
  305.                     DosBeep(500, 500);
  306.                     DosBeep(1000, 500);
  307.                     break;
  308.                     }
  309.                 case EVENT_MOUSE_TIMEREXPIRED:
  310.                     {
  311.                     // OK, not a double click, so go to Idle state
  312.                     curState=STATE_MOUSE_IDLE;
  313.                     break;
  314.                     }
  315.                 }
  316.             break;
  317.             }
  318.  
  319.         case STATE_MOUSE_DWAIT:
  320.             {
  321.             switch(event)
  322.                 {
  323.                 case EVENT_MOUSE_MOVED:
  324.                     {
  325.                     // dispatch MouseMoved message to window
  326.                     curState = STATE_MOUSE_DEPRESSED;
  327.                     Mwnd->MouseMoved(currinfo.col, currinfo.row);
  328.                     // not a double-click, so go to depressed state
  329.                     timer.SetTimer(delayticks);
  330.                     break;
  331.                     }
  332.                 case EVENT_MOUSE_DEPRESSED:
  333.                     {
  334.                     // Error - cannot happen !
  335.                     DosBeep(500, 500);
  336.                     DosBeep(1000, 500);
  337.                     DosBeep(500, 500);
  338.                     break;
  339.                     }
  340.                 case EVENT_MOUSE_RELEASED:
  341.                     {
  342.                     curState = STATE_MOUSE_IDLE;
  343.                     Mwnd->DoubleClick(currinfo.col, currinfo.row);
  344.  
  345.                     // test needed, or might post to nonexistent window
  346.                     if ((Mwnd = MouseWindow(currinfo.col, currinfo.row)) 
  347.                         != NULL)
  348.                         {
  349.                         Mwnd->ButtonReleased(currinfo.col, currinfo.row);
  350.                         }
  351.                     break;
  352.                     }
  353.  
  354.                 case EVENT_MOUSE_TIMEREXPIRED:
  355.                     {
  356.                     // not a double-click, so go to depressed state
  357.                     curState = STATE_MOUSE_DEPRESSED;
  358.                     timer.SetTimer(delayticks);
  359.                     break;
  360.                     }
  361.                 }
  362.             break;
  363.             }
  364.     
  365.         case STATE_MOUSE_REPEAT:
  366.             {
  367.             switch(event)
  368.                 {
  369.                 case EVENT_MOUSE_MOVED:
  370.                     {
  371.                     // no longer in typematic repeat mode
  372.                     curState = STATE_MOUSE_DEPRESSED;
  373.                     timer.SetTimer(repeatticks);
  374.                     // dispatch MouseMoved message to window
  375.                     Mwnd->MouseMoved(currinfo.col, currinfo.row);
  376.     
  377.                     break;
  378.                     }
  379.                 case EVENT_MOUSE_DEPRESSED:
  380.                     {
  381.                     // Error - cannot happen !
  382.                     DosBeep(1000, 500);
  383.                     break;
  384.                     }
  385.                 case EVENT_MOUSE_RELEASED:
  386.                     {
  387.                     // no longer in typematic repeat mode
  388.                     curState=STATE_MOUSE_IDLE;
  389.                     // test needed, or might post to nonexistent window
  390. //                    if ((Mwnd = MouseWindow(currinfo.col, currinfo.row)) 
  391. //                            != NULL)
  392. //                        {
  393.                         Mwnd->ButtonReleased(currinfo.col, currinfo.row);
  394. //                        }
  395.                     break;
  396.                     }
  397.                 case EVENT_MOUSE_TIMEREXPIRED:
  398.                     {
  399.                     // dispatch click message & reset
  400.                     timer.SetTimer(repeatticks);
  401.                     Mwnd->LeftButton(currinfo.col, currinfo.row);
  402.                     break;
  403.                     }
  404.                 }
  405.             break;
  406.             }
  407.         }
  408.     }
  409.