001/* [{
002Copyright 2007, 2008 Nicolas Carranza <nicarran at gmail.com>
003
004This file is part of jpen.
005
006jpen is free software: you can redistribute it and/or modify
007it under the terms of the GNU Lesser General Public License as published by
008the Free Software Foundation, either version 3 of the License,
009or (at your option) any later version.
010
011jpen is distributed in the hope that it will be useful,
012but WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014GNU Lesser General Public License for more details.
015
016You should have received a copy of the GNU Lesser General Public License
017along with jpen.  If not, see <http://www.gnu.org/licenses/>.
018}] */
019package jpen.provider.xinput;
020
021import java.util.ArrayList;
022import java.util.Collection;
023import java.util.Collections;
024import java.util.List;
025import java.util.logging.Logger;
026import jpen.PenDevice;
027import jpen.PenManager;
028import jpen.PenProvider;
029import jpen.PKind;
030import jpen.provider.AbstractPenProvider;
031import jpen.provider.NativeLibraryLoader;
032import jpen.provider.VirtualScreenBounds;
033import jpen.internal.BuildInfo;
034
035public final class XinputProvider
036        extends AbstractPenProvider {
037
038        private static final Logger L=Logger.getLogger(XinputProvider.class.getName());
039
040        private static final NativeLibraryLoader LIB_LOADER=new NativeLibraryLoader(new String[] {""},
041                        new String[] {"x86_64"},
042                        Integer.valueOf(BuildInfo.getProperties().getString("jpen.provider.xinput.nativeVersion")));
043
044        static void loadLibrary() {
045                LIB_LOADER.load();
046        }
047
048        private final XinputDevice[] xinputDevices;
049        final VirtualScreenBounds screenBounds=VirtualScreenBounds.getInstance();
050
051        public static class Constructor
052                extends AbstractPenProvider.AbstractConstructor {
053
054                //@Override
055                public String getName() {
056                        return "XInput";
057                }
058                //@Override
059                public boolean constructable(PenManager penManager) {
060                        String os = System.getProperty("os.name").toLowerCase();
061                        return os.contains("linux") || os.contains("bsd");
062                }
063
064                @Override
065                public PenProvider constructProvider() throws Throwable {
066                        loadLibrary();
067                        return new XinputProvider(this);
068                }
069                @Override
070                public int getNativeVersion() {
071                        return LIB_LOADER.nativeVersion;
072                }
073                @Override
074                public int getNativeBuild() {
075                        loadLibrary();
076                        return XiBus.getNativeBuild();
077                }
078                @Override
079                public int getExpectedNativeBuild() {
080                        return Integer.valueOf(BuildInfo.getProperties().getString("jpen.provider.xinput.nativeBuild"));
081                }
082        }
083
084        private XinputProvider(Constructor constructor) throws Exception {
085                super(constructor);
086                L.fine("start");
087
088                XiBus xiBus=new XiBus();
089
090                for(int xiDeviceIndex=xiBus.getXiDevicesSize(); --xiDeviceIndex>=0; ) {
091                        XiBus xiBus2=new XiBus(); // each XiBus opens a connection to the X server.
092                        try {
093                                xiBus2.setXiDevice(xiDeviceIndex);
094                        } catch(Exception ex) {
095                                continue;
096                        }
097                        XinputDevice xinputDevice=new XinputDevice(this, xiBus2.getXiDevice());
098                        devices.add(xinputDevice);
099                }
100
101                xinputDevices=devices.toArray(new XinputDevice[devices.size()]);
102                if(devices.size()==1) {
103                        xinputDevices[0].setKindTypeNumber(PKind.Type.STYLUS.ordinal());
104                }
105                L.fine("end");
106        }
107
108        private void resetXinputDevices() {
109                for(int i=xinputDevices.length; --i>=0;)
110                        xinputDevices[i].reset();
111        }
112
113        private void pauseXinputDevices(boolean paused) {
114                for(int i=xinputDevices.length; --i>=0;)
115                        xinputDevices[i].setIsListening(!paused);
116        }
117
118        //@Override
119        public void penManagerPaused(boolean paused) {
120                pauseXinputDevices(paused);
121                if(!paused) {
122                        screenBounds.reset();
123                        resetXinputDevices();
124                }
125        }
126
127        /*
128        //v EXPERIMENTAL:
129        @Override
130        public boolean getUseRelativeLocationFilter(){
131                return true;
132        }
133        //^
134        */
135}