/* 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.winimpl; import com.sun.jna.Memory; import com.sun.jna.Pointer; import com.sun.jna.WString; import domain.libs.sjt.misc.ConsoleLogger; import domain.libs.sjt.winimpl.window.defs.Kernel32; import domain.libs.sjt.winimpl.window.defs.User32; import domain.libs.sjt.winimpl.window.defs.WNDCLASSEX; import domain.libs.sjt.winimpl.window.defs.WNDPROC; import domain.libs.sjt.winimpl.wintab.defs.Wintab32; public class TabletWinImplWinFuncs implements WNDPROC { private final ConsoleLogger log = ConsoleLogger.newInstanceForCallingClass(); private final TabletWinImpl impl; Pointer hWnd; final Pointer hInstance; final WString win_className; final WString win_wndName; public TabletWinImplWinFuncs(TabletWinImpl tabletWinImpl) { this.impl = tabletWinImpl; hInstance = Kernel32.INSTANCE.GetModuleHandleW(Pointer.NULL); win_className = new WString(String.format( "SJTC%X", Pointer.nativeValue(hInstance))); win_wndName = new WString(String.format( "SJTW%X", Pointer.nativeValue(hInstance))); } void registerClassEx() throws TabletWinImplException { WNDCLASSEX wc = new WNDCLASSEX(); wc.cbSize = wc.size(); wc.style = 0; wc.lpfnWndProc = this; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; // If this member is NULL, the system provides a default icon. wc.hIcon = Pointer.NULL; // If this member is NULL, an application must explicitly set the cursor shape whenever the mouse moves into the application's window. wc.hCursor = User32.INSTANCE.LoadCursorW(Pointer.NULL, new Pointer(User32.IDC_ARROW)); // When this member is NULL, an application must paint its own background whenever it is requested to paint in its client area. wc.hbrBackground = new Pointer(User32.COLOR_APPWORKSPACE + 1); wc.lpszMenuName = null; wc.lpszClassName = win_className; wc.hIconSm = Pointer.NULL; if (User32.INSTANCE.RegisterClassExW(wc) == 0) { throw new TabletWinImplException( "Failed to register class for window."); } } void createWindowEx() throws TabletWinImplException { hWnd = User32.INSTANCE.CreateWindowExW( 0, win_className, win_wndName, (int) User32.WS_OVERLAPPEDWINDOW, (int) User32.CW_USEDEFAULT, (int) User32.CW_USEDEFAULT, (int) User32.CW_USEDEFAULT, (int) User32.CW_USEDEFAULT, Pointer.NULL, Pointer.NULL, hInstance, Pointer.NULL); if (hWnd == Pointer.NULL) { throw new TabletWinImplException( "Failed to create window."); } } void windowMessageLoop() { final Memory msg = new Memory(1024); int ret; while((ret = User32.INSTANCE.GetMessageW(msg, Pointer.NULL, 0, 0 )) != 0) { if (ret == -1) { new TabletWinImplException( "GetMessageW() failed. Last error was '%s'").printStackTrace(); impl.wtFuncs.tabletCleanup(); return; } else { User32.INSTANCE.TranslateMessage(msg); User32.INSTANCE.DispatchMessageW(msg); } } // while } void sendWMDESTROY() { User32.INSTANCE.SendMessageW(hWnd, (int) User32.WM_DESTROY, Pointer.NULL, Pointer.NULL); } void windowCleanup() { /* * All window classes that an application registers are unregistered when it terminates. * -from msdn */ } @Override public Pointer callback(Pointer hWnd, int uMsg, Pointer wParam, Pointer lParam) { switch (uMsg) { // case (int) User32.WM_CREATE: // optional // break; /* should return zero to continue creation of the window*/ // case (int) User32.WM_ACTIVATE: // break; case (int) User32.WM_USER_CLOSE_IMPLEMENTATION: log.info("Close tablet implementation."); impl.wtFuncs.tabletCleanup(); windowCleanup(); break; case (int) User32.WM_USER_ACTIVATE_NEW_SETTINGS: impl.activateNewSettings(); break; case (int) User32.WM_USER_ENABLE_IMPLEMENTATION: log.debug("enabletTablets"); for (int i=0; i<impl.wtFuncs.wtDevices.length; i++) impl.wtFuncs.enableTablet(i); break; case (int) User32.WM_USER_DISABLE_IMPLEMENTATION: log.debug("disableTablets"); for (int i=0; i<impl.wtFuncs.wtDevices.length; i++) impl.wtFuncs.disableTablet(i); break; case (int) User32.WM_DESTROY: User32.INSTANCE.SendMessageW(hWnd, (int) User32.WM_USER_CLOSE_IMPLEMENTATION, Pointer.NULL, Pointer.NULL); User32.INSTANCE.PostQuitMessage(0); break; /* If an application processes this message, it should return zero. */ case (int) Wintab32.WT_PACKET: // System.out.println("WT_PACKET"); impl.wtFuncs.handleWTPACKET(lParam, Pointer.nativeValue(wParam)); break; /* i assume that default window processing doesn't know (thus care) about WT_PACKET */ default: return User32.INSTANCE.DefWindowProcW(hWnd, uMsg, wParam, lParam); } // switch return User32.POINTER_ZERO; } // method }