Logo Search packages:      
Sourcecode: jinput version File versions  Download package

LinuxJoystickDevice.java

/**
 * Copyright (C) 2003 Jeremy Booth (jeremy@newdawnsoftware.com)
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this 
 * list of conditions and the following disclaimer. Redistributions in binary 
 * form must reproduce the above copyright notice, this list of conditions and 
 * the following disclaimer in the documentation and/or other materials provided
 * with the distribution. 
 * The name of the author may not be used to endorse or promote products derived
 * from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
 */
package net.java.games.input;

import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;

/**
 * @author elias
 */
00037 final class LinuxJoystickDevice implements LinuxDevice {
      public final static int JS_EVENT_BUTTON     = 0x01;    /* button pressed/released */
      public final static int JS_EVENT_AXIS       = 0x02;    /* joystick moved */
      public final static int JS_EVENT_INIT       = 0x80;    /* initial state of device */

      public final static int AXIS_MAX_VALUE = 32767;

      private final long fd;
      private final String name;

      private final LinuxJoystickEvent joystick_event = new LinuxJoystickEvent();
      private final Event event = new Event();
      private final LinuxJoystickButton[] buttons;
      private final LinuxJoystickAxis[] axes;
      private final Map povXs = new HashMap(); 
      private final Map povYs = new HashMap(); 
      private final byte[] axisMap;
      private final char[] buttonMap;

      private EventQueue event_queue;

      /* Closed state variable that protects the validity of the file descriptor.
       *  Access to the closed state must be synchronized
       */
      private boolean closed;

    public LinuxJoystickDevice(String filename) throws IOException {
            this.fd = nOpen(filename);
            try {
                  this.name = getDeviceName();
                  setBufferSize(AbstractController.EVENT_QUEUE_DEPTH);
                  buttons = new LinuxJoystickButton[getNumDeviceButtons()];
                  axes = new LinuxJoystickAxis[getNumDeviceAxes()];
                  axisMap = getDeviceAxisMap();
                  buttonMap = getDeviceButtonMap();
            } catch (IOException e) {
                  close();
                  throw e;
            }
    }
      private final static native long nOpen(String filename) throws IOException;

      public final synchronized void setBufferSize(int size) {
            event_queue = new EventQueue(size);
      }

      private final void processEvent(LinuxJoystickEvent joystick_event) {
            int index = joystick_event.getNumber();
            // Filter synthetic init event flag
            int type = joystick_event.getType() & ~JS_EVENT_INIT;
            switch (type) {
                  case JS_EVENT_BUTTON:
                        if (index < getNumButtons()) {
                              LinuxJoystickButton button = buttons[index];
                              if (button != null) {
                                    float value = joystick_event.getValue();
                                    button.setValue(value);
                                    event.set(button, value, joystick_event.getNanos());
                                    break;
                              }
                        }
                        return;
                  case JS_EVENT_AXIS:
                        if (index < getNumAxes()) {
                              LinuxJoystickAxis axis = axes[index];
                              if (axis != null) {
                                    float value = (float)joystick_event.getValue()/AXIS_MAX_VALUE;
                                    axis.setValue(value);
                                    if(povXs.containsKey(new Integer(index))) {
                                          LinuxJoystickPOV pov = (LinuxJoystickPOV)(povXs.get(new Integer(index)));
                                          pov.updateValue();
                                          event.set(pov, pov.getPollData(), joystick_event.getNanos());
                                    } else if(povYs.containsKey(new Integer(index))) {
                                          LinuxJoystickPOV pov = (LinuxJoystickPOV)(povYs.get(new Integer(index)));
                                          pov.updateValue();
                                          event.set(pov, pov.getPollData(), joystick_event.getNanos());
                                    } else {
                                          event.set(axis, value, joystick_event.getNanos());
                                    }
                                    break;
                              }
                        }
                        return;
                  default:
                        // Unknown component type
                        return;
            }
            if (!event_queue.isFull()) {
                  event_queue.add(event);
            }
      }

      public final void registerAxis(int index, LinuxJoystickAxis axis) {
            axes[index] = axis;
      }

      public final void registerButton(int index, LinuxJoystickButton button) {
            buttons[index] = button;
      }
      
      public final void registerPOV(LinuxJoystickPOV pov) {
            // The x and y on a joystick device are not the same as on an event device
            LinuxJoystickAxis xAxis = pov.getYAxis();
            LinuxJoystickAxis yAxis = pov.getXAxis(); 
            int xIndex;
            int yIndex;
            for(xIndex=0;xIndex<axes.length;xIndex++) {
                  if(axes[xIndex]==xAxis) {
                        break;
                  }
            }
            for(yIndex=0;yIndex<axes.length;yIndex++) {
                  if(axes[yIndex]==yAxis) {
                        break;
                  }
            }
            povXs.put(new Integer(xIndex),pov);
            povYs.put(new Integer(yIndex),pov);
      }

      public final synchronized boolean getNextEvent(Event event) throws IOException {
            return event_queue.getNextEvent(event);
      }

      public final synchronized void poll() throws IOException {
            checkClosed();
            while (getNextDeviceEvent(joystick_event)) {
                  processEvent(joystick_event);
            }
      }

      private final boolean getNextDeviceEvent(LinuxJoystickEvent joystick_event) throws IOException {
            return nGetNextEvent(fd, joystick_event);
      }
      private final static native boolean nGetNextEvent(long fd, LinuxJoystickEvent joystick_event) throws IOException;

      public final int getNumAxes() {
            return axes.length;
      }

      public final int getNumButtons() {
            return buttons.length;
      }
      
      public final byte[] getAxisMap() {
            return axisMap;
      }

      public final char[] getButtonMap() {
            return buttonMap;
      }

      private final int getNumDeviceButtons() throws IOException {
            return nGetNumButtons(fd);
      }
      private final static native int nGetNumButtons(long fd) throws IOException;

      private final int getNumDeviceAxes() throws IOException {
            return nGetNumAxes(fd);
      }
      private final static native int nGetNumAxes(long fd) throws IOException;
      
      private final byte[] getDeviceAxisMap() throws IOException {
            return nGetAxisMap(fd);
      }
      private final static native byte[] nGetAxisMap(long fd) throws IOException;

      private final char[] getDeviceButtonMap() throws IOException {
            return nGetButtonMap(fd);
      }
      private final static native char[] nGetButtonMap(long fd) throws IOException;

      private final int getVersion() throws IOException {
            return nGetVersion(fd);
      }
      private final static native int nGetVersion(long fd) throws IOException;

      public final String getName() {
            return name;
      }
      
      private final String getDeviceName() throws IOException {
            return nGetName(fd);
      }
      private final static native String nGetName(long fd) throws IOException;

      public final synchronized void close() throws IOException {
            if (!closed) {
                  closed = true;
                  nClose(fd);
            }
      }
      private final static native void nClose(long fd) throws IOException;

      private final void checkClosed() throws IOException {
            if (closed)
                  throw new IOException("Device is closed");
      }

      protected void finalize() throws IOException {
            close();
      }
}

Generated by  Doxygen 1.6.0   Back to index