home *** CD-ROM | disk | FTP | other *** search
/ Chestnut's Multimedia Mania / MM_MANIA.ISO / graphics / paintoop / cmouse.pas < prev    next >
Pascal/Delphi Source File  |  1989-11-16  |  17KB  |  364 lines

  1. {$B-,F-,I+,R+}
  2.  
  3. unit CMouse;
  4.  
  5. { Define TMouse - a class for accessing the mouse }
  6.  
  7. { Copyright 1989
  8.   Scott Bussinger
  9.   110 South 131st Street
  10.   Tacoma, WA  98444
  11.   (206)531-8944
  12.   Compuserve 72247,2671 }
  13.  
  14. interface
  15.  
  16. uses Graph,CObject;
  17.  
  18. type MouseButton = (Left,Right,Middle);
  19.      MouseCursor = (DefaultCursor,PenCursor,BucketCursor,HandCursor);
  20.      MouseStatus = (Idle,Pressed,Released,Held);
  21.  
  22. type TMouse = object(TObject)
  23.        fCurrentCursor: MouseCursor;              { Current style of mouse cursor }
  24.        fLastButtonStatus: word;                  { Button status at last call to Update }
  25.        fLastLocationX: integer;                  { Horizontal cursor location at last call to Update }
  26.        fLastLocationY: integer;                  { Vertical cursor location at last call to Update }
  27.        fMouseFactor: integer;                    { Horizontal scaling factor for current video mode }
  28.        fMousePresent: boolean;                   { True if a mouse is present }
  29.        fPreviousButtonStatus: word;              { Button status at second to last call to Update }
  30.        fTextCursorEnabled: boolean;              { True if the text cursor is enabled }
  31.        fTextCursorHeight: integer;               { Height of text cursor in pixels }
  32.        fVisible: boolean;                        { True if the mouse cursor is currently visible }
  33.  
  34.        constructor Init;                         { Initialize the mouse }
  35.        procedure DisableTextCursor;              { Disable the text cursor }
  36.        procedure EnableTextCursor;               { Enable the text cursor display }
  37.        function GetLocationX: integer;           { Returns last horizontal location }
  38.        function GetLocationY: integer;           { Returns last vertical location }
  39.        function GetButton(Button: MouseButton): MouseStatus; { Returns last status of a mouse button }
  40.        procedure Hide;                           { Turn mouse cursor off }
  41.        function Present: boolean;                { Return true if mouse is present }
  42.        procedure SetCursor(NewCursor: MouseCursor); { Change to a new cursor shape }
  43.        procedure SetTextCursor(Height: integer); { Turn on the text cursor }
  44.        procedure Show;                           { Turn mouse cursor on }
  45.        procedure Update;                         { Update the currect mouse status }
  46.        end;
  47.  
  48. var Mouse: TMouse;
  49.  
  50. implementation
  51.  
  52. uses Dos,CWindow;
  53.  
  54. const Cursor: array[MouseCursor] of record
  55.         HotSpot: record
  56.           X: integer;
  57.           Y: integer
  58.           end;
  59.         ScreenMask: array[0..15] of word;
  60.         CursorMask: array[0..15] of word
  61.         end =
  62.          ((HotSpot:(X:0; Y:0);                   { Hot spot is tip of arrow }
  63.            ScreenMask:($3FFF,                    { 0011111111111111 } { DefaultCursor }
  64.                        $1FFF,                    { 0001111111111111 }
  65.                        $0FFF,                    { 0000111111111111 }
  66.                        $07FF,                    { 0000011111111111 }
  67.                        $03FF,                    { 0000001111111111 }
  68.                        $01FF,                    { 0000000111111111 }
  69.                        $00FF,                    { 0000000011111111 }
  70.                        $007F,                    { 0000000001111111 }
  71.                        $003F,                    { 0000000000111111 }
  72.                        $001F,                    { 0000000000011111 }
  73.                        $01FF,                    { 0000000111111111 }
  74.                        $10FF,                    { 0001000011111111 }
  75.                        $30FF,                    { 0011000011111111 }
  76.                        $F87F,                    { 1111100001111111 }
  77.                        $F87F,                    { 1111100001111111 }
  78.                        $FC3F);                   { 1111110000111111 }
  79.            CursorMask:($0000,                    { 0000000000000000 }
  80.                        $4000,                    { 0100000000000000 }
  81.                        $6000,                    { 0110000000000000 }
  82.                        $7000,                    { 0111000000000000 }
  83.                        $7800,                    { 0111100000000000 }
  84.                        $7C00,                    { 0111110000000000 }
  85.                        $7E00,                    { 0111111000000000 }
  86.                        $7F00,                    { 0111111100000000 }
  87.                        $7F80,                    { 0111111110000000 }
  88.                        $78C0,                    { 0111111111000000 }
  89.                        $7C00,                    { 0111110000000000 }
  90.                        $4600,                    { 0100011000000000 }
  91.                        $0600,                    { 0000011000000000 }
  92.                        $0300,                    { 0000001100000000 }
  93.                        $0300,                    { 0000001100000000 }
  94.                        $0180)),                  { 0000000110000000 }
  95.           (HotSpot:(X:1; Y:15);                  { Hot spot is just beyond tip of pen }
  96.            ScreenMask:($FFCF,                    { 1111111111001111 } { PenCursor}
  97.                        $FF87,                    { 1111111110000111 }
  98.                        $FF03,                    { 1111111100000011 }
  99.                        $FE01,                    { 1111111000000001 }
  100.                        $FC03,                    { 1111110000000011 }
  101.                        $F807,                    { 1111100000000111 }
  102.                        $F00F,                    { 1111000000001111 }
  103.                        $E01F,                    { 1110000000011111 }
  104.                        $C03F,                    { 1100000000111111 }
  105.                        $807F,                    { 1000000001111111 }
  106.                        $00FF,                    { 0000000011111111 }
  107.                        $01FF,                    { 0000000111111111 }
  108.                        $03FF,                    { 0000001111111111 }
  109.                        $07FF,                    { 0000011111111111 }
  110.                        $0FFF,                    { 0000111111111111 }
  111.                        $9FFF);                   { 1001111111111111 }
  112.            CursorMask:($0000,                    { 0000000000000000 }
  113.                        $0030,                    { 0000000000110000 }
  114.                        $0078,                    { 0000000001111000 }
  115.                        $009C,                    { 0000000010011100 }
  116.                        $01E8,                    { 0000000111101000 }
  117.                        $03F0,                    { 0000001111110000 }
  118.                        $07E0,                    { 0000011111100000 }
  119.                        $0FC0,                    { 0000111111000000 }
  120.                        $1F80,                    { 0001111110000000 }
  121.                        $2700,                    { 0010011100000000 }
  122.                        $7A00,                    { 0111101000000000 }
  123.                        $5C00,                    { 0101110000000000 }
  124.                        $4800,                    { 0100100000000000 }
  125.                        $5000,                    { 0101000000000000 }
  126.                        $6000,                    { 0110000000000000 }
  127.                        $0000)),                  { 0000000000000000 }
  128.           (HotSpot:(X:14; Y:14);                 { Hot spot is just beyond tip of pen }
  129.            ScreenMask:($FFCF,                    { 1111111111001111 } { BucketCursor }
  130.                        $FF87,                    { 1111111110000111 }
  131.                        $FE03,                    { 1111111000000011 }
  132.                        $F803,                    { 1111100000000011 }
  133.                        $E001,                    { 1110000000000001 }
  134.                        $C001,                    { 1100000000000001 }
  135.                        $8000,                    { 1000000000000000 }
  136.                        $0000,                    { 0000000000000000 }
  137.                        $0000,                    { 0000000000000000 }
  138.                        $8000,                    { 1000000000000000 }
  139.                        $8008,                    { 1000000000001000 }
  140.                        $8018,                    { 1000000000011000 }
  141.                        $C078,                    { 1100000001111000 }
  142.                        $C0F8,                    { 1100000011111000 }
  143.                        $C3F8,                    { 1100001111111000 }
  144.                        $E7F8);                   { 1110011111111000 }
  145.            CursorMask:($0000,                    { 0000000000000000 }
  146.                        $0030,                    { 0000000000110000 }
  147.                        $0048,                    { 0000000001001000 }
  148.                        $0188,                    { 0000000110001000 }
  149.                        $0604,                    { 0000011000000100 }
  150.                        $1804,                    { 0001100000000100 }
  151.                        $2002,                    { 0010000000000010 }
  152.                        $7FFE,                    { 0111111111111110 }
  153.                        $7FFA,                    { 0111111111111010 }
  154.                        $3FF2,                    { 0011111111110010 }
  155.                        $3FE2,                    { 0011111111100010 }
  156.                        $3F82,                    { 0011111110000010 }
  157.                        $1F02,                    { 0001111100000010 }
  158.                        $1C02,                    { 0001110000000010 }
  159.                        $1802,                    { 0001100000000010 }
  160.                        $0000)),                  { 0000000000000000 }
  161.           (HotSpot:(X:4; Y:0);                   { Hot spot is just beyond tip of pen }
  162.            ScreenMask:($F3FF,                    { 1111001111111111 } { HandCursor }
  163.                        $E1FF,                    { 1110000111111111 }
  164.                        $E1FF,                    { 1110000111111111 }
  165.                        $E1FF,                    { 1110000111111111 }
  166.                        $E001,                    { 1110000000000001 }
  167.                        $E000,                    { 1110000000000000 }
  168.                        $E000,                    { 1110000000000000 }
  169.                        $E000,                    { 1110000000000000 }
  170.                        $8000,                    { 1000000000000000 }
  171.                        $0000,                    { 0000000000000000 }
  172.                        $0000,                    { 0000000000000000 }
  173.                        $0000,                    { 0000000000000000 }
  174.                        $0000,                    { 0000000000000000 }
  175.                        $0000,                    { 0000000000000000 }
  176.                        $8001,                    { 1000000000000001 }
  177.                        $C003);                   { 1100000000000011 }
  178.            CursorMask:($0C00,                    { 0000110000000000 }
  179.                        $1200,                    { 0001001000000000 }
  180.                        $1200,                    { 0001001000000000 }
  181.                        $1200,                    { 0001001000000000 }
  182.                        $13FE,                    { 0001001111111110 }
  183.                        $1249,                    { 0001001001001001 }
  184.                        $1249,                    { 0001001001001001 }
  185.                        $1249,                    { 0001001001001001 }
  186.                        $7249,                    { 0111001001001001 }
  187.                        $9001,                    { 1001000000000001 }
  188.                        $9001,                    { 1001000000000001 }
  189.                        $9001,                    { 1001000000000001 }
  190.                        $8001,                    { 1000000000000001 }
  191.                        $8001,                    { 1000000000000001 }
  192.                        $4002,                    { 0100000000000010 }
  193.                        $3FFC)));                 { 0011111111111100 }
  194.  
  195. const CurrentTextCursorLineStyle: word = $FFFF;  { Line style for drawing text cursor }
  196.  
  197. procedure MouseCall(    AX: word;
  198.                     var MouseRegs: Registers);
  199.   { Execute a call to the mouse driver }
  200.   begin
  201.   MouseRegs.AX := AX;
  202.   Intr($33,MouseRegs)
  203.   end;
  204.  
  205. procedure XorTextCursor(Height: integer);
  206.   { Draw/Undraw the text cursor }
  207.   var SaveStatus: GraphicsStatus;
  208.   begin
  209.   CurrentCanvas^.Activate;                       { Make sure the text cursor stays in the drawing window }
  210.   GetGraphicsStatus(SaveStatus);
  211.   SetLineStyle(UserBitLn,CurrentTextCursorLineStyle,NormWidth);
  212.   ChangeWriteMode(XorPut);
  213.   ChangeColor(SystemWhite);
  214.   LineTo(SaveStatus.XCoord,SaveStatus.YCoord+Height);
  215.   SetGraphicsStatus(SaveStatus)
  216.   end;
  217.  
  218. constructor TMouse.Init;
  219.   { Initialize the mouse }
  220.   var MouseRegs: Registers;
  221.       MouseVector: pointer;
  222.   begin
  223.   GetIntVec($33,MouseVector);
  224.   if MouseVector <> nil
  225.    then
  226.     begin
  227.     MouseCall(0,MouseRegs);
  228.     if MouseRegs.AX = $FFFF
  229.      then
  230.       begin
  231.       fMousePresent := true;
  232.       if GetMaxX < 320                           { Watch out for these odd modes with the mouse }
  233.        then
  234.         fMouseFactor := 1
  235.        else
  236.         fMouseFactor := 0;
  237.  
  238.       fVisible := false;
  239.       fCurrentCursor := PenCursor;               { So the next statement works correctly }
  240.       SetCursor(DefaultCursor);
  241.       fTextCursorHeight := 1;
  242.       fTextCursorEnabled := false;               { Text cursor is off initially }
  243.       Update
  244.       end
  245.      else
  246.       fMousePresent := false
  247.     end
  248.    else
  249.     fMousePresent := false
  250.   end;
  251.  
  252. procedure TMouse.DisableTextCursor;
  253.   { Turn off the text cursor }
  254.   begin
  255.   if fTextCursorEnabled then
  256.     begin
  257.     Hide;                                        { So the old cursor gets erased }
  258.     fTextCursorEnabled := false                  { Don't display cursor anymore }
  259.     end
  260.   end;
  261.  
  262. procedure TMouse.EnableTextCursor;
  263.   { Turn on the text cursor }
  264.   begin
  265.   if not fTextCursorEnabled then
  266.     begin
  267.     Hide;
  268.     fTextCursorEnabled := true
  269.     end
  270.   end;
  271.  
  272. procedure TMouse.Hide;
  273.   { Turn mouse cursor off }
  274.   var MouseRegs: Registers;
  275.   begin
  276.   if fVisible then
  277.     begin
  278.     fVisible := false;
  279.     MouseCall(2,MouseRegs);
  280.     if fTextCursorEnabled then                   { Draw the text cursor }
  281.       XorTextCursor(fTextCursorHeight)
  282.     end
  283.   end;
  284.  
  285. function TMouse.Present: boolean;
  286.   { Return true if mouse is present }
  287.   begin
  288.   Present := fMousePresent
  289.   end;
  290.  
  291. procedure TMouse.SetCursor(NewCursor: MouseCursor);
  292.   { Change to a new cursor shape }
  293.   var MouseRegs: Registers;
  294.   begin
  295.   if fCurrentCursor <> NewCursor then            { Don't flicker the screen if the cursor style didn't change }
  296.     begin
  297.     fCurrentCursor := NewCursor;
  298.     with MouseRegs do
  299.       begin
  300.       BX := word(Cursor[NewCursor].HotSpot.X);
  301.       CX := word(Cursor[NewCursor].HotSpot.Y);
  302.       DX := ofs(Cursor[NewCursor].ScreenMask);
  303.       ES := seg(Cursor[NewCursor].ScreenMask)
  304.       end;
  305.     MouseCall(9,MouseRegs)
  306.     end
  307.   end;
  308.  
  309. procedure TMouse.SetTextCursor(Height: integer);
  310.   { Set the height of the text cursor }
  311.   begin
  312.   fTextCursorHeight := Height
  313.   end;
  314.  
  315. procedure TMouse.Show;
  316.   { Turn mouse cursor on }
  317.   var MouseRegs: Registers;
  318.   begin
  319.   if not fVisible then
  320.     begin
  321.     fVisible := true;
  322.     if fTextCursorEnabled then
  323.       XorTextCursor(fTextCursorHeight);
  324.     MouseCall(1,MouseRegs)
  325.     end
  326.   end;
  327.  
  328. procedure TMouse.Update;
  329.   { Update the currect mouse status }
  330.   var MouseRegs: Registers;
  331.   begin
  332.   MouseCall(3,MouseRegs);
  333.   with MouseRegs do
  334.     begin
  335.     fPreviousButtonStatus := fLastButtonStatus;
  336.     fLastButtonStatus := BX;
  337.     fLastLocationX := CX shr fMouseFactor;
  338.     fLastLocationY := DX
  339.     end
  340.   end;
  341.  
  342. function TMouse.GetLocationX: integer;
  343.   { Returns last horizontal location }
  344.   begin
  345.   GetLocationX := fLastLocationX
  346.   end;
  347.  
  348. function TMouse.GetLocationY: integer;
  349.   { Returns last vertical location }
  350.   begin
  351.   GetLocationY := fLastLocationY
  352.   end;
  353.  
  354. function TMouse.GetButton(Button: MouseButton): MouseStatus;
  355.   { Returns last status of a button }
  356.   var ButtonMask: word;
  357.   begin
  358.   ButtonMask := $0001 shl ord(Button);
  359.   GetButton := MouseStatus(2 * byte((fPreviousButtonStatus and ButtonMask)<>0) +
  360.                                byte((fLastButtonStatus and ButtonMask)<>0))
  361.   end;
  362.  
  363. end.
  364.