Skip to content

Mouse, Fake Cursors, and Touchpad

Ravbug edited this page Jan 12, 2019 · 3 revisions

Jump to Fake Cursors
Jump to Touchpad

Mouse

A computer can have several mice, track-pads, track-balls and other such devices attached. But it only has one real mouse cursor. Also most games only see a single mouse, called the “system mouse”. The system mouse is an imaginary combination of all the hardware mice and track-pads put together. Moving any mouse to the left will move the “system mouse” and the on-screen mouse pointer to the left. Pressing any mouse’s left button will be seen as clicking the left button on the “system mouse”.

The physical movement of each mouse on the desk is measured in units called “mickeys”. The size of this unit depends on the mouse. It is often listed on the box as Dots Per Inch, or DPI. “Dots” here refers to “mickeys”. My Microsoft wireless optical mouse has 400 DPI, meaning one mickey is 1/400 inches, or less then a tenth of a millimetre. There is no way of knowing the exact physical position of the mouse, but you can only tell how far it has moved from its starting position.

The location of the mouse pointer on the screen is measured in pixels. Windows uses a complicated algorithm called “mouse ballistics” to determine how far to move the cursor based on the physical movement of the mouse. It varies for different versions of Windows and for different control panel settings, and for different monitor sizes. Many people have multiple monitors attached to their computer, and the mouse pointer can move from one to the other. If the mouse is on a screen to the left of the primary monitor then it will have a negative pixel coordinate for its x position. If the mouse is on a screen to the right of the primary monitor it will have a pixel coordinate greater than the horizontal resolution of the screen.

Some games use the mouse pointer’s position on the screen. But other games, especially First Person Shooters like DooM, don’t use a mouse pointer, and instead just read the physical movement of the mouse in Mickeys. Just because a game has a mouse pointer, doesn’t mean it uses the normal Windows one. Sometimes it just reads the physical mouse movements and draws its own pointer in its own private location that it is impossible for GlovePIE to know about.

Mouse.DirectInputX and Mouse.DirectInputY

In GlovePIE, you can read and set the physical movement of the mouse, in mickeys, by using the mouse.DirectInputX and mouse.DirectInputY values. It is called DirectInput because games use Microsoft’s DirectInput to read these values directly from the mouse hardware.

If you have multiple mice, and you have Windows XP, you can read the positions of individual mice with mouse1.DirectInputX, mouse2.DirectInputX, etc. Otherwise you can just use mouse.DirectInputX (without any number) to get the combined location of all the mice representing the “System mouse”. You can’t set the position of individual mice (since most games can’t read individual mice), so you always have to set mouse.DirectInputX without a number before the dot. Note that laptops usually have multiple mice, since the track-pad counts as a mouse.

Mouse.DirectInputX is the left/right position, with negative values to the left and positive values to the right. Mouse.DirectInputY is the forwards/backwards position, with negative values meaning forwards and positive values meaning backwards.

Where-ever the mouse was when you pressed the Run button will be considered the point (0, 0) where both mouse.DirectInputX and mouse.DirectInputY are equal to 0.

If you then move the mouse 1 inch to the right, the mouse.DirectInputX value will go up to 400, or whatever DPI your mouse is.

You can read these values, to find out where the mouse is, or you can set them, to trick games into thinking that the mouse has been moved to a new physical location.

Because PIE supports different units, you can also read the value in normal units of distance, like centimetres or inches.

For example:

midi.BassDrum1 = mouse.DirectInputX < -0.5 inches midi.CrashCymbal1 = mouse.DirectInputX > 0.5 inches debug = mouse.DirectInputX in inches

This will play a drum when you move the mouse half an inch to the left of its starting point, and play a cymbal when you move the mouse half an inch to the right of its starting point. It will also display the physical location of the mouse in the debug box. Note that people are used to moving the mouse tiny amounts, so it feels weird moving the mouse large distances. But if you want to use the mouse as a physical tracking device like this you can.

Note that if your mouse is not the default 400 DPI, then you need to set the value Pie.MouseDPI to whatever your mouse’s DPI is. For example, for my mum’s new mouse:

Pie.MouseDPI = 800 midi.BassDrum1 = mouse.DirectInputX < -0.5 inches midi.CrashCymbal1 = mouse.DirectInputX > 0.5 inches debug = mouse.DirectInputX in inches

You can also check with a ruler to make sure you got it right.

You can also set the values to control the system mouse in any game or application. It doesn’t matter whether the game uses the mouse cursor or reads the mouse directly. For example if you want to control the mouse with a joystick, like this:

mouse.DirectInputX = mouse.DirectInputX + 100deadzone(joystick.x) mouse.DirectInputY = mouse.DirectInputY + 100deadzone(joystick.y)

Every frame (60 times per second) it will add or subtract a certain amount based on the position of the joystick. The deadzone function stops it from drifting if your joystick is not calibrated correctly.

FakeMouse.DirectInputX and RealMouse.DirectInputX

DirectInputX, DirectInputY, DirectInputZ, and DirectInputH now have 3 kinds:

Mouse.DirectInputX FakeMouse.DirectInputX RealMouse.DirectInputX

When you read mouse.DirectInputX it is a total of all the fake mouse motions plus all the real mouse motions. When you read RealMouse.DirectInputX it is the total of all the real mouse motions, without any of the fake ones. FakeMouse.DirectInputX is the total fake mouse motions, and doesn't include the real ones. You can also set Mouse.DirectInputX or FakeMouse.DirectInputX. For example:

Mouse.DirectInputX = MapRange(Wiimote.Roll,-90,90,-800,800)

The above will set the mouse to a position based on the Wiimote's roll. You will not be able to move it by moving, the real mouse.

FakeMouse.DirectInputX = MapRange(Wiimote.Roll,-90,90,-800,800)

The above will move the mouse relative to the real mouse position. The real mouse can also control it.

But if you use += or add to the DirectInputX value each time instead of setting it to an absolute value, then it makes no difference which one you use.

NEW! FakeMouse.DirectInputY is now fixed and working, as of GlovePIE 0.42. NEW! FakeMouse.DirectInput2D and RealMouse.DirectInput2D are now available.

Mouse.DirectInput2D

Because GlovePIE also supports vectors, you may want to set and read both the DirectInput values at once. For example:

Mouse.DirectInput2D = [200, -400]

DirectInput2D is also called DirectInputPos.

Will set the mouse to half an inch to the left and a whole inch forwards from its starting point. Or you can use real units:

Mouse.DirectInput2D = [0.5, -1] inches

You can also read them both at once. eg.

debug = mouse.DirectInput2D

You can read individual mice this way if you have multiple mice plugged into windows XP, by using Mouse1.DirectInput2D and Mouse2.DirectInput2D. But you can’t set individual mice.

The Scroll Wheel

Most mice these days also have a scroll wheel. This is considered to be the mouse’s Z axis. It has no units. But it normally jumps in increments of 120 per click. Some mice have continuous movement in their scroll wheels, but most click in jumps of 120.

Note that the wheel on my Microsoft mouse is extremely dodgy and often jumps in the wrong direction, and I expect many scroll wheels are like that. Some games go to a lot of trouble to compensate.

Mouse.DirectInputZ

You can read or set the scroll wheel position with Mouse.DirectInputZ.

The starting position of the scroll wheel is given the value 0. Negative means scrolled forwards. Positive means scrolled backwards. If you scroll it forwards two clicks it will have a value of -240.

Again this works with multiple mice.

Mouse.DirectInput3D

You can set or read the x, y, and z (scroll wheel) positions at once with Mouse.DirectInput3D. It is measured in Mickeys, even though technically z shouldn’t have units. It works with multiple mice. Mouse.WheelUp and Mouse.WheelDown

This will be true for an instant (well, a single frame, or a 40th of a second) when you scroll the wheel up or down. You can also set it, if you want to simulate the user scrolling the wheel up or down.

It does not work with multiple mice yet.

Mouse.DirectInputH

If the mouse has a horizontal scroll wheel, or a vertical scroll wheel that can tilt from side to side, then in theory you can read or set the horizontal scroll wheel position with Mouse.DirectInputH. I have no idea whether it works, since it is largely based on guess-work and I don’t have a mouse with horizontal scroll wheels.

I don’t know whether this works with multiple mice, or the system mouse, or both. If you do any experiments and find out, please let me know.

Mouse.WheelLeft and Mouse.WheelRight

This is the horizontal equivalent of Mouse.WheelUp and Mouse.WheelDown. It is purely theoretical, and probably doesn’t work.

Mouse.WheelPresent

Mouse.WheelPresent is true if one of your mice has a scroll wheel, or false if none of them do. It doesn’t work for individual mice yet. You can’t set it, you can only read it.

Mouse.WheelScrollLines

The mouse.WheelScrollLines value is equal to the number of lines of text that will be scrolled in most applications when you move the scroll wheel one click (or 120 units if it doesn’t click).

Mouse.CursorPosX and Mouse.CursorPosY

The other way of thinking about the mouse position is to use the cursor, rather than the physical movement of the mouse on the desk. The Cursor position is measured in pixels. The number of pixels on the screen in each direction is called the resolution. It is usually around about 1024 horizontally and 768 vertically.

Remember that many games ignore the position of the proper cursor, so for these games you need to use the DirectInputX and DirectInputY values above instead.

There is only one real mouse cursor, and it is shared between multiple mice. So you can’t use numbers before the dot to read or set the cursor position for individual mice. If you want more than one cursor you need to use Fake Cursors.

mouse.CursorPosX is the horizontal coordinate of the cursor. 0 is the left edge of the primary monitor. The right edge of the primary monitor is one less than the horizontal resolution of the screen. eg. 1023. You can tell what the resolution of the primary monitor is by reading screen.width.

Note that if the cursor is on a different monitor from the primary monitor then mouse.CursorPosX will be either less than 0 or greater than or equal to the width of the primary monitor. You can tell what the left edge of the left-most monitor is by reading screen.DesktopLeft. You can tell what the right edge of the right-most monitor is by reading screen.DesktopRight. You can also read screen2.left, screen3.left, etc. to find the left edges of individual screens. The same with the right hand sides.

mouse.CursorPosY is the vertical coordinate of the cursor. 0 is the top edge, and the bottom edge is one less than the vertical resolution. It will be outside this range for multiple monitors. Use screen.DesktopTop and screen.DesktopBottom to tell the top and bottom maximum values for all monitors.

You can also write Cursor.PosX and Cursor.PosY instead, to set the cursor position. It works the same as Mouse.CursorPosX and Mouse.CursorPosY. Don’t use a number after the word “cursor” though, or it will set fake cursors rather than the real one.

If you have a Plug & Play monitor, then GlovePIE can tell roughly what the physical size of your screen is. You can therefore set the location of the cursor in real world units. For example, to set the cursor to be 10 cm to the right of the left edge of the primary monitor, you would write this:

mouse.CursorPosX = 10 cm

You can also get the physical width of the screen like this:

debug = screen.width in cm

GlovePIE will automatically convert between pixels and real world units, so watch out! That may not be what you want.

For example: mouse.CursorPosX = mouse.DirectInputX

will make the cursor on the screen move the same physical distance that you moved the mouse. If you moved the mouse 1 inch, it will move the cursor 1 inch. That is fun to try, but a pain for people that are used to mice.

If you don’t want to convert the units, try this instead:

mouse.CursorPosX = RemoveUnits(mouse.DirectInputX)

Normally you just set the cursor position using pixels, eg.

mouse.CursorPosX = 512

Mouse.CursorPos

You can read both the horizontal and vertical position at once as a vector, using Mouse.CursorPos.

eg.

debug = mouse.CursorPos

or

mouse.CursorPos = [512, 300]

Mouse.X and Mouse.Y

Sometimes it is easier to specify the mouse pointer location as a fraction of the screen size. That is good if we don’t know how wide the screen is. Do that with mouse.x and mouse.y. Note that games which don’t use the cursor will still ignore these values, so for some games you need to use DirectInputX and DirectInputY instead. This also makes no sense for multiple mice individually, since they share the cursor.

Mouse.x is the horizontal position of the cursor, between 0 and 1. 0 is the left hand side of the primary monitor, and 1 is the right hand side. Note that if the cursor is on a different monitor it will be outside that range.

Mouse.y is the vertical position of the cursor, between 0 and 1. 0 is the top of the primary monitor, and 1 is the bottom. Again it may be outside this range if on another monitor.

Note that unlike the joystick, which goes from -1 to 1, the mouse only goes from 0 to 1. So to control the cursor based on the joystick position you need to use something like the MapRange function. eg…

mouse.x = MapRange(joystick.x, -1, 1, 0, 1)

That will convert from the joystick’s range of -1, 1 to the mouse’s range of 0, 1.

Mouse.ScreenFraction

Mouse.ScreenFraction sets or reads both mouse.x and mouse.y at once, as a vector.

Mouse.VirtualDesktopX and Mouse.VirtualDesktopY

The problem with the mouse.x and mouse.y values is that you need to set them to less than 0 or greater than 1 to put the cursor on another monitor.

If you want to set or read the position as a fraction of the entire Virtual Desktop, then you should use mouse.VirtualDesktopX and mouse.VirtualDesktopY instead.

Mouse.x is the horizontal position, with 0 being the left side of the left-most monitor, and 1 being the right side of the right-most monitor.

As you can guess, Mouse.y is the vertical position.

Mouse.DesktopFraction

Mouse.DesktopFraction is the vector equivalent for setting or reading both mouse.VirtualDesktopX and mouse.VirtualDesktopY at once.

Mouse Buttons

PC Mice usually have between 2 and 5 buttons. You can read or set them in GlovePIE with:

mouse.LeftButton mouse.MiddleButton mouse.RightButton mouse.XButton1 mouse.XButton2

The X Buttons do various things like move backwards and forwards in a web browser, and they are only found on special mice. Most modern games will support them, so they are very useful.

In theory some things in windows also support mouse buttons 6, 7 and 8.

You can set or read them with these values:

mouse.button6 mouse.button7 mouse.button8

But current windows versions don’t seem to allow you to set them. Reading them may theoretically work though, although in practice mice with more than 5 buttons probably work a different way.

Note that if you have multiple mice connected to Windows XP, you can read the buttons individually, with mouse1.LeftButton, mouse2.LeftButton, mouse3.LeftButton, etc. Without a number it reads the combination of all the mice.

All the mouse buttons can be set to either True or False. True is equivalent to 1, and false is equivalent to 0, except when you add true/false values it means “and”, and when you divide, it means “or”.

For example:

midi.BassDrum1 = mouse.LeftButton+mouse.RightButton

will play the drum when you have both the left and right buttons held down at once.

Mouse.DoubleClickTime

Mouse.DoubleClickTime is the maximum time between the clicks in double clicks that will still be recognised as a double click. If clicks are further apart than this time, they are two single clicks. It is the same for all the mice connected to the computer.

Actually GlovePIE also uses this same value for keyboard and other double-clicks using it’s DoubleClicked( ) function.

It is in seconds by default, but in GlovePIE you can use any units you like and it will convert them.

Mouse.IsDragging

Mouse.IsDragging will be true while the mouse cursor is busy dragging something, and false when it isn’t.

Mouse.Count

Mouse.Count is the number of mice connected to the computer. It only works on Windows XP, otherwise it will always return 1. This value doesn’t count the extra Windows XP Pro Remote Desktop cursor, which can be accessed as Mouse0 on Windows XP Pro.

Mice are numbered from 1 to mouse.count. Plus an extra mostly useless mouse0 on XP Pro.

Mouse.CursorVisible

Mouse.CursorVisible is true when the cursor is visible, and false when it isn’t. At least, that’s the theory. Some programs and games can hide the cursor and this should tell you whether or not that’s the case. This can’t be used for individual mice. Use Fake Cursors for them instead.

Mouse.Cursor

Mouse.Cursor is equal to whatever cursor is currently being displayed. It can be the following values:

-2. Wii Hand

  1. Arrow
  2. Cross
  3. I Beam
  4. Icon
  5. Size
  6. Size Diagonal /
  7. Size Vertical |
  8. Size Diagonal \
  9. Size Horizontal –
  10. Up arrow
  11. Hourglass
  12. Symbol for no
  13. Arrow + Hourglass (Application starting)
  14. Arrow + ? (Help)
  15. Size All +
  16. Hand
  17. Drag
  18. Multi-Drag
  19. Symbol for no again
  20. SQL wait
  21. None of the above

Setting this value doesn’t really work yet, unless you keep setting it to different values like this:

Mouse.Cursor = Random(21)

Mouse.PermanentCursor

This can be used to set the cursor which should always be displayed when the mouse is over the PIE window. It will even stay that way after your program exits, until you restart PIE, or write a script to set it back to 0. It uses the same numbers as above.

This isn’t all that useful, but may be useful for displaying what state your script is currently in. eg.

if joystick1.Button1 then mouse.PermanentCursor = 11 else mouse.PermanentCursor = 0 end if

Swallowing the Mouse

Not as tasty as it sounds. This is actually about stopping windows from receiving real messages from the System mouse (that is from all the real mice), but still receive those messages that are set by GlovePIE.

This only works on Windows 2000 or above. And I don’t think it works with DirectInput games.

It is mainly for use with fake cursors, or with multiple mice. But it can also be used to disable the mouse for any other purpose.

Mouse.Swallow can be set to true to disable the entire mouse, or false to not do that. This prevents the mouse from doing anything in Windows. But you can still set Mouse.LeftButton or Mouse.CursorPosX or whatever to control the mouse cursor. It just won’t be controlled by any of the real mice.

Mouse.SwallowButtons is the same, but it only disables the buttons.

Mouse.SwallowMovement only disables movement.

Mouse.SwallowWheels only disables scroll-wheels.

An unfortunate side-effect of swallowing the mouse is that clicking on GlovePIE’s title bar by controlling the mouse with GlovePIE will temporarily make it hang until you press Alt+Tab, or wait umpteen seconds.

Swallowing the mouse is good for when you want one mouse to control the real cursor, and all the other mice to only control fake cursors. The trick is the swallow the mouse, then set all the mouse values to match mouse1. Then you set the fake cursors to match mouse2.

See the MouseParty.PIE script for an example.

Mouse.Present

Last, but not least, you can tell if there actually is at least one mouse plugged in by using Mouse.Present. It will be true if there is a mouse (or track-pad, or other mouse-like device), and false if there isn’t.

Fake Cursors

In addition to the real mouse cursor, GlovePIE can show multiple fake cursors. These fake cursors look and behave just like the real cursor, and can do most of the same things. They are not quite perfected yet though.

Fake cursors will look funny (non-transparent) if you don’t have at least Windows 2000.

Fake cursors are identified by a coloured number in the bottom-right hand corner. Different numbers are different colours, but it repeats eventually.

Fake cursors could be controlled by multiple separate mice, or they could be controlled by other devices, like keyboards, joysticks, VR Gloves, speech, or whatever. They can even be used when you just want to display values graphically in GlovePIE, for debugging or whatever.

You can create fake cursors with a number between 0 and infinity. You don’t have to use them sequentially. You can show only fake cursor 3 and fake cursor 5 if you want. But using big numbers will waste memory.

See the MouseParty.PIE script for an example of using fake cursors.

Fake cursors have much the same properties as the ones for mouse.

Note that the special properties for fake cursors aren’t displayed in the code-completion box for cursor, the box only displays the same properties as for mouse because I was too lazy to fix it.

But some of the new properties are:

Cursor2.visible

Any fake cursors that you mention are visible by default. You don’t need to set a fake cursor to visible if you want to be able to see it. But you can set it if you want to hide it or show it again. Somewhere in your script write:

Cursor2.Visible = false

If you don’t want to see fake cursor number 2 anymore. You don’t have to use number 2, you can use any number. But using both fake cursor 1 and a real cursor is confusing, since people think of the real cursor as being cursor 1, even though it isn’t. You can even use fake cursor 0, which is also not the same as the real cursor.

Making a cursor visible doesn’t make it do anything. Fake cursors don’t respond to mouse movements. They only go where they are told to go, and click when they are told to click.

Cursor2.Roll

Fake cursors can rotate like on a Wii:

Cursor1.roll = Wiimote.Roll Cursor1.x = Wiimote.PointerX Cursor1.y = Wiimote.PointerY

Roll is measured in degrees, clockwise.

Cursor2.Colour

Fake cursors can change colour:

Cursor1.colour = [1, 0.5, 0] // red, green, blue

Cursor1.colour = 0xFF8000 // the same as above

Setting colour will only change the coloured parts of the image. The white and black parts of the cursor will stay the same.

Cursor2.WhiteColour

You can also change the colour of the white that is in the image by setting Cursor1.WhiteColour. This doesn't just affect the white and grey parts of the image. It also affects the white that is mixed into other colours to make them paler. So for example you could make the white make colours redder instead of paler.

Cursor2.Caption

You can also set the caption. By default the caption is the fake cursor's number. But you can set it to anything you want:

Cursor1.caption = "the fake is a lie"

Cursor2.PermanentCursor = -2

If you want the cursor to look like a Wii hand cursor, set Cursor1.PermanentCursor = -2

You can also change the cursor image to a cursor loaded from a file:

Cursor2.Image

Cursor1.image = "c:\data\mycursor.cur"

If you use an animated cursor, it will not be animated.

Cursor2.Shift and Cursor2.Ctrl

Sometimes applications respond differently to Shift-clicks or Ctrl-clicks. That is when you hold down shift or control, or both, while you click.

Most non-game applications don’t read the keyboard to check this though. Instead they rely on the information that comes with the mouse message to determine whether shift was held down or not.

The good thing about that is that fake cursors can have their own Shift-Click and Control-Click features without using the real shift or control keys. It also means multiple users can be regular-clicking and shift-clicking at the same time without interfering with each other.

So to shift-click with a fake cursor you need to set Cursor2.Shift to true before the mouse button is set. It isn’t enough to hold down the real shift key.

Cursor2.shift and Cursor2.ctrl can be either true or false.

For example, to control cursor2 with a joystick you might write:

Cursor2.Visible = true Cursor2.Shift = joystick.Button4 Cursor2.Ctrl = joystick.Button5 Cursor2.LeftButton = joystick.Button1 Cursor2.RightButton = joystick.Button2 Cursor2.MiddleButton = joystick.Button3 Cursor2.x = MapRange(joystick.x, -1, 1, 0, 1) Cursor2.y = MapRange(joystick.y, -1, 1, 0, 1)

To shift click you would need to hold down button 4 while you click button 1.

Touchpad

The touchpad can be read as a mouse. But if you’re the kind of person who thinks a touchpad is just a mouse, GlovePIE isn’t for you.

A touchpad can measure the absolute position of your finger, and how hard you are pushing it. It also normally comes with buttons. Mine has a LeftButton, RightButton and a DPad in the middle.

GlovePIE can only read Synaptics brand touchpads. They are the most common.

Touchpad.FingerPresent is true when your finger is touching the touchpad, and false when it is not.

Touchpad.x is the horizontal position of your finger. It is between 0 and 1. The right hand edge will be 1. If your finger is not touching the touchpad it will be the same position as last time you touched it.

Touchpad.y is the vertical position of your finger. It is between 0 and 1. It is 0 at the top, and 1 at the bottom. If your finger is not touching it, it will remember the last position.

Touchpad.z and Touchpad.w are how hard you are pushing down with your finger. It is NOT between 0 and 1. W and Z both measure almost the same thing, but they are in different units. Z is much more precise. Sometimes it will be slightly above zero even when you are not touching the touchpad.

Warning! Touchpads don’t bend when you push them, your finger does! Touchpads are a solid object that measures how much electricity your finger can store. That changes depending on how much of your finger is touching the touchpad, and how squashed your finger is.

Touchpad.LeftButton is the touchpad’s left “mouse” button. It does not include left-clicks caused by taps. Touchpad.RightButton is the touchpad’s right “mouse” button. Touchpad.MiddleButton is the touchpad’s middle mouse button, which may or may not exist.

If your touchpad has a DPad between the left and right buttons (for scrolling) like mine, then you can use the Touchpad.DPadUp, Touchpad.DPadDown, TouchPad.DPadLeft, and Touchpad.DPadRight buttons. It is possible for DPadUp and DPadDown to both be true if you push the whole DPad in, and the same goes for DPadLeft and DPadRight.

Your touchpad might also have other Up and Down buttons. Mine doesn’t. They will be touchpad.UpButton and touchpad.DownButton.

If you want your touchpad to stop controlling the mouse, you need to set Touchpad.swallow = true. Then only GlovePIE, and other programs that know how to read a touchpad will read it.

If your touchpad can work with a stylus then you can read touchpad.StylusPresent to detect when the stylus is touching it. Mine doesn’t work with a stylus.

There are also some other touchpad values you can experiment with.

Clone this wiki locally