View Javadoc

1   /*
2    * @(#)$Id: WacomUtils.java 689 2009-07-22 00:10:27Z bsigner $
3    *
4    * Author       :   Croci Michele, mcroci@gmail.com
5    *
6    * Purpose      :   Provide access to a Wacom Tablet PC.
7    *
8    * -----------------------------------------------------------------------
9    *
10   * Revision Information:
11   *
12   * Date             Who         Reason
13   *
14   * Nov 14, 2007    crocimi     Initial Release
15   *
16   * -----------------------------------------------------------------------
17   *
18   * Copyright 1999-2009 ETH Zurich. All Rights Reserved.
19   *
20   * This software is the proprietary information of ETH Zurich.
21   * Use is subject to license terms.
22   * 
23   */
24  
25  
26  package org.ximtec.igesture.io.wacom;
27  
28  import org.ximtec.igesture.io.wacom.Wintab32.LOGCONTEXTW;
29  import org.ximtec.igesture.io.wacom.Wintab32.PACKET;
30  import org.ximtec.igesture.io.win32.User32;
31  import org.ximtec.igesture.io.win32.Win32;
32  import org.ximtec.igesture.io.win32.User32.MSG;
33  import org.ximtec.igesture.io.win32.W32API.HANDLE;
34  import org.ximtec.igesture.io.win32.W32API.HDC;
35  import org.ximtec.igesture.io.win32.W32API.HINSTANCE;
36  import org.ximtec.igesture.io.win32.W32API.HWND;
37  import org.ximtec.igesture.io.win32.W32API.LPARAM;
38  import org.ximtec.igesture.io.win32.W32API.LRESULT;
39  import org.ximtec.igesture.io.win32.W32API.WPARAM;
40  
41  import com.sun.jna.ptr.IntByReference;
42  import com.sun.jna.win32.StdCallLibrary.StdCallCallback;
43  
44  public class WacomUtils extends Thread{
45  
46  	/** Provide access to a Wacom Tablet PC.
47  	 * 
48  	 * @author Michele Croci
49  	 */
50  	
51  	Wintab32 lib = Win32.WINTAB32_INSTANCE;
52  	HDC hdc = new HDC();
53  	TabletProc tabletListener;
54  	HANDLE handle;
55  	HINSTANCE hinst;
56  	
57  	private WacomCallback wCallback;
58  
59  	
60  	public WacomUtils() {}
61  	
62      public WacomUtils(WacomCallback wCallback) {
63         this.wCallback = wCallback;
64      }
65  	
66  	   
67  	   private void init(){
68            hinst = Win32.KERNEL32_INSTANCE.GetModuleHandle(null);
69  
70            tabletListener = new TabletProc() {
71  
72               public LRESULT callback(int code, WPARAM wParam, LPARAM lParam) {
73                  PACKET p = getPacket();
74                  if((p!=null)){
75                      fireEvent(p);
76                  }
77                  
78                  //discard 2 packets, otherwise too slow!
79                  PACKET[] arr = new PACKET[2];
80                  getPackets(2, arr);
81                 
82                  return Win32.USER32_INSTANCE.CallNextHookEx(handle, code, wParam, lParam);
83               }
84            };
85             handle = Win32.USER32_INSTANCE.SetWindowsHookExW(User32.WH_MOUSE_LL, tabletListener, hinst,0);
86  	   }
87  	   
88  	   private void fireEvent(PACKET p){
89  	      wCallback.callbackFunction(p.pkX, p.pkY, p.pkZ, p.pkStatus, p.pkNormalPressure, p.pkTangentPressure,
90  	             p.pkTime, p.pkOrientation, p.pkRotation, p.pkButtons);
91  	   }
92  
93  
94  	    
95  	 /**
96       * Open session with wacom Tablet PC
97       */
98  	    public void open() {
99  
100 	    	HWND hwnd = new HWND();
101 	    	hwnd.setPointer(new IntByReference(Wintab32.HWND_BROADCAST).getPointer());//getPointer(0)
102 	    	int packetmode = 0;
103 	    	
104 	    	LOGCONTEXTW lg =  new LOGCONTEXTW();
105 	    	lib.WTInfoW(Wintab32.WTI_DEFSYSCTX, 0, lg);
106 	    	lg.lcPktMode= packetmode;
107 	    	//information to be retrieved, see wintab.h for values
108 	    	lg.lcPktData = 0x3FFF;
109 	    	lg.lcMoveMask = 0x3FFF; //0x180
110 	    	lg.lcBtnUpMask = lg.lcBtnDnMask;
111 
112 	        hdc=lib.WTOpenW(hwnd, lg, true);
113 	      //  lib.WacomDoSpecialContextHandling(true);
114 	    }
115 	    
116 	    /**
117 	     * Close session with wacom Tablet PC
118 	     */
119 	    public void close() {
120 	    	lib.WTClose(hdc);
121 	    	lib.WacomDoSpecialContextHandling(false);
122 	    }
123 	    
124 	    
125 	    /**
126 	     * Get single packet
127 	     * 
128 	     * @return the packet (saved in an array)
129 	     */
130 	    public PACKET getPacket(){
131 	    	if (hdc == null)
132 	    		return null;
133 	    	
134 	    	PACKET p = new PACKET();
135 	    	lib.WTPacketsGet(hdc, 1,p);
136 	    	return p;
137 
138 	    } 
139 	    
140 	    /**
141          * Get single packet, discard 3
142          * 
143          * @return the packet (saved in an array)
144          */
145         public PACKET getOnePacket(){
146            PACKET[] arr = new PACKET[10];
147            if (hdc == null)
148               return null;
149           
150           PACKET p = new PACKET();
151           lib.WTPacketsGet(hdc, 1,p);
152           lib.WTPacketsGet(hdc, 3,arr);//discard 3 packets
153           return p;
154 
155         } 
156 	    
157 	    /**
158          * Get n packets
159          * 
160          * @param number
161          *      the maximal number of packets to be retrieved
162          * 
163          * @param arr
164          *      the array where packets have to be saved
165          * 
166          * @return the received packets
167          */
168 	    
169 	    public int getPackets(int number, PACKET[] arr){
170 	    	if (hdc == null)
171 	    		return -1;
172 
173 	    	int ret = lib.WTPacketsGet(hdc, number,arr);
174 	    	return ret;
175 	    } 
176 	    
177 	    
178 	    public interface TabletProc extends StdCallCallback {
179 
180 	       LRESULT callback(int code, WPARAM wParam, LPARAM lParam);
181 	    }
182 
183 	    
184 	    /**
185          * Register callback function
186          */
187 	    private void registerHook(){
188 	       handle = Win32.USER32_INSTANCE.SetWindowsHookExW(User32.WH_KEYBOARD_LL, tabletListener, hinst, 0); 
189 	    }
190 	    
191 	    
192         /**
193          * Run method
194          */
195 	    public void run(){
196 
197 	          init();
198 	     
199 	          registerHook();
200 	          open();
201 	           MSG msg = new MSG();
202 	           while(Win32.USER32_INSTANCE.GetMessageW(msg,null,0,0)!=0){
203 	               //User32.INSTANCE.DispatchMessage(msg);
204 	           }
205 	       close();
206 	   }
207 	    
208 	     /**
209          * Determine if a particular type of data can be retrieved or not
210          * 
211          * @param datatype
212          *      the type representing the data
213          * 
214          * @return true if the data is supported, false otherwise
215          */
216 	    
217 	    public boolean isDataSupported(int dataTypeId){
218 	    	int test;
219 	    	HWND hwnd = new HWND();
220 	    	hwnd.setPointer(new IntByReference(Wintab32.HWND_BROADCAST).getPointer());//getPointer(0)
221 	    	
222 	    	LOGCONTEXTW lg =  new LOGCONTEXTW();
223 	    	
224 	    	test = lib.WTInfoW(Wintab32.WTI_DEVICES, dataTypeId, lg);
225 	    	return test!=0;
226 	    }
227 	    
228 	    
229 	    //data types
230 		public static final int DVC_X			= 	12;
231 		public static final int DVC_Y			=	13;
232 		public static final int DVC_Z			=	14;
233 		public static final int DVC_NPRESSURE	=	15;
234 		public static final int DVC_TPRESSURE	=	16;
235 		public static final int DVC_ORIENTATION	=	17;
236 		public static final int DVC_ROTATION	=	18; /* 1.1 */
237 		
238 	}
239