Mouse Issue

Started by psiegel, June 19, 2003, 17:46:56

Previous topic - Next topic

psiegel

I noticed an odd problem with Mouse input.  I'll try to write up some demo code that exemplifies it, but I'll see if I can't describe it here first.

This issue only comes up if you're running the app in windowed mode, and you attempt to switch focus to another window by clicking it with the mouse.  Once this happens, you can continue polling the mouse and get updates on the location of the mouse.  However, Mouse.isButtonDown(0) now always returns true.  It seems like it captured that last mouse down just before losing focus, and now it's not getting any more updates concerning button state.

Whether or not I'm correct about this, I've found that I really want this function:

boolean Window.hasFocus()

The mouse handling code would then become a nice tight little test:

if (!window.isMinimized() && window.hasFocus()) {
 Mouse.poll();
 ...
}

Again, I'll try to whip up some sample code that exposes the above bug (or proves that my assumption is wrong.)

Paul

psiegel

Here's the code sample.  Sorry about the length.

Paul

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.nio.*;

import org.lwjgl.*;
import org.lwjgl.input.*;
import org.lwjgl.opengl.*;

public class MouseTest {
  protected GL gl;
  protected GLU glu;
  
  protected boolean running;
  
  protected boolean mousedown;
  protected int     mousex = 0;
  protected int     mousey = 0;
  
  protected Cursor  mouseupcursor;
  protected Cursor  mousedowncursor;
  
  public static void main(String[] args) {
    try {
      MouseTest test = new MouseTest();
      test.run();
      test.destroy();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public MouseTest() throws Exception {
    gl = new GL("Mouse Test", 50, 50, 640, 480, 16, 0, 0, 0);
    gl.create();
    glu = new GLU(gl);
    
    gl.viewport(0, 0, 640, 480);
    
    gl.matrixMode(GL.PROJECTION);
    gl.loadIdentity();
    glu.ortho2D(0, 640, 480, 0);
        
    gl.matrixMode(GL.MODELVIEW);
    gl.loadIdentity();

    gl.shadeModel(GL.SMOOTH);
    gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
    gl.clearDepth(1.0f);
    gl.enable(GL.DEPTH_TEST);
    gl.depthFunc(GL.LEQUAL);
        
    gl.hint(GL.PERSPECTIVE_CORRECTION_HINT, GL.NICEST);
    
    Keyboard.create();
    Mouse.create();
        
    mouseupcursor = createNativeCursor(0, 0, 255);
    mousedowncursor = createNativeCursor(255, 255, 0);
    Mouse.setNativeCursor(mouseupcursor);
  }
  
  public void destroy() {
    mouseupcursor.destroy();
    mousedowncursor.destroy();
    Mouse.destroy();
    Keyboard.destroy();
    gl.destroy();
  }
  
  public void stop() {
    running = false;
  }
  
  public void run() throws Exception {
    running = true;
    while(running) {
      render();
      gl.paint();
      gl.tick();
      
      processKeyboard();
      processMouse();
      
      if (gl.isCloseRequested()) {
        stop();
      }
    }
  }
  
  public void processKeyboard() {
    if (Keyboard.isCreated()) {
      Keyboard.poll();
      if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
        stop();
      }
    }
  }
  
  public void processMouse() throws Exception {
    if (Mouse.isCreated()) {
      Mouse.poll();
      mousex += Mouse.dx;
      mousey += Mouse.dy;

      if (mousedown && !Mouse.isButtonDown(0)) {
        Mouse.setNativeCursor(mouseupcursor);
      } else if (!mousedown && Mouse.isButtonDown(0)) {
        Mouse.setNativeCursor(mousedowncursor);
      }
      
      mousedown = Mouse.isButtonDown(0);      
    }
  }
  
  private void render() {
    gl.clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT);
    gl.loadIdentity();
        
    gl.translatef(0f, 0f, -1f);
        
    if (mousedown) {
      gl.color3f(1f, 0f, 0f);
    } else {
      gl.color3f(0f, 1f, 0f);
    }
    
    gl.begin(GL.QUADS);
    {
      gl.vertex2i(mousex-32, mousey-32);
      gl.vertex2i(mousex-32, mousey+32);
      gl.vertex2i(mousex+32, mousey+32);
      gl.vertex2i(mousex+32, mousey-32);
    }
    gl.end();
  }
  
  private Cursor createNativeCursor(int r, int g, int b) throws Exception {
    if ((Mouse.getNativeCursorCaps() & Mouse.CURSOR_ONE_BIT_TRANSPARANCY) == 0) 
    {
      System.out.println("No HW cursor support!");
      return null;
    }
    
    BufferedImage image = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB);
    Graphics graphics = image.getGraphics();
    graphics.setColor(new Color(r, g, b));
    graphics.fillOval(0, 0, 32, 32);
    graphics.dispose();

    IntBuffer cursorData = 
      ByteBuffer.allocateDirect(32*32*4).order(ByteOrder.nativeOrder()).asIntBuffer();
    Raster raster = image.getRaster();
    int[] intData = (int[])raster.getDataElements(0, 0, 32, 32, null);
    for (int i=0;i<intData.length;i++) {
      cursorData.put(intData[i]);
    }

    return new Cursor(32, 32, 16, 16, 1, Sys.getDirectBufferAddress(cursorData),
                      Sys.NULL);
  }
}

psiegel

Uh, is this thing on?  Tap - tap.  Can I get a "verified"?

Paul

Matzon

hmm I thought I had replied... oh well

I will verify this soon, but since I am doing a TON of refactoring on LWJGL right now, my setup is totally b0rked. Will check it though...

WVM

I can't verify it for you either, well not today, my editor is complaining about tons of invisible characters in the code.

But, I have had the phenomenon while playing ALienFlux that the mousecursor would move, but that the game would not react to my mousepresses. After quitting and restarting, I got this in my ALienFlux.log

1600 x 1200 x 32 @72Hz
Wed Jun 18 20:26:52 GMT 2003   Attempting to set displaymode: 800 x 600 x 16 @60Hz
Wed Jun 18 20:26:54 GMT 2003   Reserved 4194304 bytes of Nvidia RAM
Wed Jun 18 20:26:54 GMT 2003   Vertex array range @ 308936704 / length 4194304
Wed Jun 18 20:26:54 GMT 2003   Failed to create controller:java.lang.Exception: The controller could not be created.
java.lang.NoSuchFieldException: closeRequested
Wed Jun 18 20:27:15 GMT 2003   Cleanup com.shavenpuppy.jglib.MemoryBuffer@10da0c8
Wed Jun 18 20:27:15 GMT 2003   Cleanup null

I tried to recreate it, but it happended only once, WHILE playing and not while switching from window to fullscreen. So, don't know why.
Oops, while switching windows, mmm, I may have pressed the windows key