/* Copyright 2010 Fictive (Fictive's public key's fingerprint is "44:1a:41:70:b1:22:d4:93:3a:bb:84:62:60:0b:e4:a3") This file is part of Sane Java Tablet. Sane Java Tablet is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Sane Java Tablet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Sane Java Tablet. If not, see <http://www.gnu.org/licenses/>. */ package domain.libs.sjt.garbage; import java.awt.Window; import net.screwbox.libs.sjt.ConsoleLogger; import net.screwbox.libs.sjt.TabletImplementation; import net.screwbox.libs.sjt.TabletImplementationException; import net.screwbox.libs.sjt.TabletInterface; import net.screwbox.libs.sjt.windows.wintab.WinTab; import net.screwbox.libs.sjt.windows.wintab.structs.WinTab_tagLOGCONTEXTW; import com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.Kernel32Util; import com.sun.jna.ptr.IntByReference; public class ErrWindowsTabletImplementation extends TabletImplementation { private static final String classId = ErrWindowsTabletImplementation.class.getSimpleName(); private ConsoleLogger log = new ConsoleLogger(classId); final Memory buffer = new Memory(1048576); // 1 MiB buffer private WinTab_tagLOGCONTEXTW wt_tagLogContextW; Pointer wt_hCtx; private WinTabPacketThread winTabPacketThread; public ErrWindowsTabletImplementation( Window tabletWindow, TabletInterface tabletInterface ) throws TabletImplementationException { super(tabletWindow, tabletInterface); try { if (WinTab.WTInfoW(0, 0, Pointer.NULL) == 0) { throw new TabletImplementationException(classId, "wintab implementation isn't present."); } } catch (UnsatisfiedLinkError e) { throw new TabletImplementationException(classId, e, "failed to load wintab dll."); } initialize(); } private void initialize() throws TabletImplementationException { // acquire a template of the system context (moves system mouse cursor) if (WinTab.WTInfoW(WinTab.WTI_DEFSYSCTX, 0, buffer) == 0) { throw new TabletImplementationException(classId, "unable to get system context."); } wt_tagLogContextW = new WinTab_tagLOGCONTEXTW(buffer); // fill in the context /* * Although the documentation says you can not include items in the packet that are not supported by the tablet, * it appears that this is incorrect. * Unsupported items may be included and will be set to zero. */ // personal note: api = stupid by design // DO ME! TRUNC TO LCNAMELEN String lcName = String.format( "SaneJavaTablet, %s", Long.toString(Thread.currentThread().getId(),16) ); int lcNameLengthCapped = lcName.length(); if (lcNameLengthCapped > WinTab.LCNAMELEN) lcNameLengthCapped = WinTab.LCNAMELEN; lcName.getChars(0, lcNameLengthCapped, wt_tagLogContextW.lcName, 0); wt_tagLogContextW.lcOptions ^= WinTab.CXO_MESSAGES | WinTab.CXO_CSRMESSAGES; // wt_tagLogContextW.lcPktData = // WinTab.PK_CONTEXT | // WinTab.PK_STATUS | // WinTab.PK_TIME | // WinTab.PK_CHANGED | // WinTab.PK_SERIAL_NUMBER | // WinTab.PK_CURSOR | // WinTab.PK_BUTTONS | // WinTab.PK_X | // WinTab.PK_Y | // WinTab.PK_Z | // WinTab.PK_NORMAL_PRESSURE | // WinTab.PK_TANGENT_PRESSURE | // WinTab.PK_ORIENTATION | // WinTab.PK_ROTATION; wt_tagLogContextW.lcStatus |= WinTab.CXS_ONTOP; wt_tagLogContextW.lcPktMode = 0; // absolute mode for all wt_tagLogContextW.lcMoveMask = Integer.MAX_VALUE; wt_tagLogContextW.lcBtnUpMask = Integer.MAX_VALUE; // Iterate through Wintab extension indices Memory extName = new Memory(255); for ( int i=0, thisTag = 0; WinTab.WTInfoW(WinTab.WTI_EXTENSIONS+i, WinTab.EXT_NAME, extName) != 0; i++) { // looking for the specified tag IntByReference j = new IntByReference(); WinTab.WTInfoW(WinTab.WTI_EXTENSIONS+i, WinTab.EXT_TAG, j.getPointer()); System.out.println("ext #"+i+": "+extName.getString(0, true)+", tag: "+j.getValue()); extName.clear(); } // System.out.println(Native.POINTER_SIZE); wt_hCtx = WinTab.WTOpenW( Native.getWindowPointer(getTabletWindow()), wt_tagLogContextW, true); wt_tagLogContextW = new WinTab_tagLOGCONTEXTW(buffer); // wt_tagLogContextW.read(); // System.out.println("PK_CONTEXT == " + ((wt_tagLogContextW.lcPktData & WinTab.PK_CONTEXT) > 0)); // System.out.println("PK_STATUS == " + ((wt_tagLogContextW.lcPktData & WinTab.PK_STATUS) > 0)); // System.out.println("PK_TIME == " + ((wt_tagLogContextW.lcPktData & WinTab.PK_TIME) > 0)); // System.out.println("PK_CHANGED == " + ((wt_tagLogContextW.lcPktData & WinTab.PK_CHANGED) > 0)); // System.out.println("PK_SERIAL_NUMBER == " + ((wt_tagLogContextW.lcPktData & WinTab.PK_SERIAL_NUMBER) > 0)); // System.out.println("PK_BUTTONS == " + ((wt_tagLogContextW.lcPktData & WinTab.PK_BUTTONS) > 0)); // System.out.println("PK_X == " + ((wt_tagLogContextW.lcPktData & WinTab.PK_X) > 0)); // System.out.println("PK_Y == " + ((wt_tagLogContextW.lcPktData & WinTab.PK_Y) > 0)); // System.out.println("PK_Z == " + ((wt_tagLogContextW.lcPktData & WinTab.PK_Z) > 0)); // System.out.println("PK_NORMAL_PRESSURE == " + ((wt_tagLogContextW.lcPktData & WinTab.PK_NORMAL_PRESSURE) > 0)); // System.out.println("PK_TANGENT_PRESSURE == " + ((wt_tagLogContextW.lcPktData & WinTab.PK_TANGENT_PRESSURE) > 0)); // System.out.println("PK_ORIENTATION == " + ((wt_tagLogContextW.lcPktData & WinTab.PK_ORIENTATION) > 0)); int lastErrCode = Native.getLastError(); if (wt_hCtx == Pointer.NULL) { /* * Kernel32.getLastError() might not be the best as an error code, * but I can't find any error codes being returned from WinTab. */ throw new TabletImplementationException(classId, "failed to open wintab context. (" + Kernel32Util.formatMessageFromLastErrorCode( lastErrCode) + ")"); } // set wintab packet queue size WinTab.WTQueueSizeSet(wt_hCtx, 150); // start packet receiving thread winTabPacketThread = new WinTabPacketThread(this); // winTabPacketThread.start(); } // method @Override protected void close() { log.info("close"); winTabPacketThread.requestShutdown(); while (winTabPacketThread.isAlive()) { Thread.yield(); } /* * Kernel32.getLastError() might not be the best as an error code, * but I can't find any error codes being returned from WinTab. */ if (WinTab.WTClose(wt_hCtx) != true) { log.error("failed to close wintab context: " + Kernel32Util.formatMessageFromLastErrorCode( Kernel32.INSTANCE.GetLastError() )); } } // method } // class //new Memory() //int i = CWinTab.WTInfoW(CWinTab.WTI_INTERFACE, CWinTab.IFC_NDEVICES, m); //System.out.println(m.getInt(0)); //final String lastErrorMsg = Kernel32Util.formatMessageFromLastErrorCode( //Kernel32.INSTANCE.GetLastError()); //final String exceptionMessage = String.format( //"Windows tablet implementation failed to load. Kernel32.GetLastError() returned \"%s\"", //lastErrorMsg); //throw new TabletImplementationException(exceptionMessage); //CWinTab.WTClose(hCtx) == 0 //CWinTab.WTInfoW(CWinTab.WTI_DEFCONTEXT, CWinTab.CTX_SYSEXTX, CWinTab.buffer); //System.out.println("'" + CWinTab.buffer.getInt(0) + "'"); //Memory m = new Memory(64); //int i = CWinTab.WTInfoW(CWinTab.WTI_INTERFACE, CWinTab.IFC_WINTABID, m); //System.out.println(m.getString(0, true));// Structure.setAutoSynch(boolean) //User32.INSTANCE.setw //Native.getComponentPointer(c) //WindowsTabletImplementation wti = WindowsTabletImplementation.getInstance(); //wti.numTabletsAvailable(); //IntByReference r;