Slick's mouse Y is one pixel off. Instead we should use the following code to get the right value:
Code:
Display.getHeight() - Mouse.getY() - 1
And Rectangle.contains should be changed like so:
Code:
public boolean contains(float xp, float yp) {
if (xp < getX()) { //changed from <=
return false;
}
if (yp < getY()) { //changed from <=
return false;
}
if (xp >= maxX) {
return false;
}
if (yp >= maxY) {
return false;
}
Here's a test to prove it. Please try it out and let me know that I'm not crazy before I push the updates.

There has been lots of debate on Rectangle.contains in the past. It's a "big change" in the sense that a lot of users rely on these pixels differences, so they'll need to know about it to change their code accordingly.
Code:
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Cursor;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;
public class OnePixelTest extends BasicGame {
/** The image we're currently displaying */
private Image image;
private Rectangle rect;
/**
* Create a new image rendering test
*/
public OnePixelTest() {
super("Transparent Color Test");
}
/**
* @see org.newdawn.slick.BasicGame#init(org.newdawn.slick.GameContainer)
*/
public void init(GameContainer container) throws SlickException {
container.getGraphics().setBackground(Color.gray);
image = new Image("testdata/transtest.png");
rect = new Rectangle(0, 0, image.getWidth(), image.getHeight());
//set an empty cursor
int minCursorSize = Cursor.getMinCursorSize();
IntBuffer tmp = BufferUtils.createIntBuffer(minCursorSize * minCursorSize);
Cursor emptyCursor;
try {
emptyCursor = new Cursor(minCursorSize, minCursorSize, minCursorSize/2, minCursorSize/2, 1, tmp, null);
Mouse.setNativeCursor(emptyCursor);
} catch (LWJGLException e) {
e.printStackTrace();
}
}
/**
* @see org.newdawn.slick.BasicGame#render(org.newdawn.slick.GameContainer, org.newdawn.slick.Graphics)
*/
public void render(GameContainer container, Graphics g) {
//mouse coords
int mx = container.getInput().getMouseX();
int my = container.getInput().getMouseY();
//uncomment to fix Y problem
// my--;
boolean inside = rect.contains(mx, my);
image.draw(0,0, inside ? Color.red : Color.white);
//just to be sure our driver is indeed drawing the pixel at the exact location...
//this green pixel should appear exactly at (0, 0)
g.setColor(Color.green);
g.fillRect(0, 0, 1, 1);
//one pixel software cursor
g.setColor(Color.white);
g.fillRect(mx, my, 1, 1);
g.drawString("Mouse Y coordinate: "+my+"\nExpected coordinate: "+(Display.getHeight()-Mouse.getY()-1), 10, image.getHeight()+20);
}
/**
* @see org.newdawn.slick.BasicGame#update(org.newdawn.slick.GameContainer, int)
*/
public void update(GameContainer container, int delta) {
}
/**
* Entry point to our test
*
* @param argv The arguments to pass into the test
*/
public static void main(String[] argv) throws SlickException {
new AppGameContainer(new OnePixelTest(), 800, 600, false).start();
}
/**
* @see org.newdawn.slick.BasicGame#keyPressed(int, char)
*/
public void keyPressed(int key, char c) {
}
}