/* 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 com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.Kernel32Util; import domain.libs.sjt.impl.TabletImplementationException; import domain.libs.sjt.misc.ConsoleLogger; public class WindowsImplWindow extends Thread implements WndProcCallback { private ConsoleLogger log = ConsoleLogger.newInstanceForCallingClass(); private final Memory sharedBuffer = new Memory(524288); // 512 KiB private String win_className; private String win_wndName; private volatile Pointer win_hwndMain; private WIN_structWNDCLASSEX win_WNDCLASSEX; private final WindowsTabletImplementation impl; public WindowsImplWindow(WindowsTabletImplementation impl) throws TabletImplementationException { this.impl = impl; sharedBuffer.clear(); win_className = String.format( "CLS.WIN.%X", Thread.currentThread().getId()); win_wndName = String.format( "SJT.WIN.%X", Thread.currentThread().getId()); win_WNDCLASSEX = new WIN_structWNDCLASSEX(sharedBuffer); fillWNDCLASSEX(); registerClass(); win_hwndMain = createWindow(); User32_Sjt.ShowWindow(win_hwndMain, WinDef_Sjt.SW_SHOWNORMAL); // User32_Sjt.UpdateWindow(win_hwndMain); // User32_Sjt.SetWindowLongPtrW( // win_hwndMain, // WinDef_Sjt.GWLP_WNDPROC, // this); // sharedBuffer.clear(); // // Return the exit code to the system. // return msg.wParam; } private void fillWNDCLASSEX() { win_WNDCLASSEX.cbSize = win_WNDCLASSEX.size(); win_WNDCLASSEX.style = 0; win_WNDCLASSEX.lpfnWndProc = this; win_WNDCLASSEX.cbClsExtra = 0; win_WNDCLASSEX.cbWndExtra = 0; win_WNDCLASSEX.hInstance = Kernel32_Sjt.GetModuleHandleW(Pointer.NULL); win_WNDCLASSEX.hInstance = null; win_WNDCLASSEX.hIcon = null; win_WNDCLASSEX.hCursor = User32_Sjt.LoadCursorW(Pointer.NULL, new Pointer(WinDef_Sjt.IDC_ARROW)); // win_WNDCLASSEX.hbrBackground = null; win_WNDCLASSEX.hbrBackground = new Pointer(WinDef_Sjt.COLOR_APPWORKSPACE + 1); win_WNDCLASSEX.lpszMenuName = null; win_WNDCLASSEX.hIconSm = null; Pointer classNameBuffer = sharedBuffer.share(1000); classNameBuffer.setString(0, win_className, true); win_WNDCLASSEX.lpszClassName = classNameBuffer; win_WNDCLASSEX.write(); } private void registerClass() throws TabletImplementationException { short classAtom = User32_Sjt.RegisterClassExW(win_WNDCLASSEX.getPointer()); if (classAtom == 0) throw new TabletImplementationException( "Could not register class \"%s\". GetLastError returned \"%s\"", win_className, Kernel32Util.formatMessageFromLastErrorCode( Native.getLastError() )); } private Pointer createWindow() throws TabletImplementationException { sharedBuffer.clear(); Pointer classNameBuffer = sharedBuffer.share(1000); classNameBuffer.setString(0, win_className, true); Pointer windowNameBuffer = sharedBuffer.share(2000); windowNameBuffer.setString(0, win_wndName, true); Pointer hwndMain = User32_Sjt.CreateWindowExW( // WinDef_Sjt.WS_EX_TRANSPARENT, 0, classNameBuffer, windowNameBuffer, WinDef_Sjt.WS_OVERLAPPEDWINDOW,// | WinDef_Sjt.WS_CLIPCHILDREN, WinDef_Sjt.CW_USEDEFAULT, WinDef_Sjt.CW_USEDEFAULT, WinDef_Sjt.CW_USEDEFAULT, WinDef_Sjt.CW_USEDEFAULT, null, null, Kernel32_Sjt.GetModuleHandleW(Pointer.NULL), null); if (hwndMain == Pointer.NULL) throw new TabletImplementationException( "Could not create window \"%s\". GetLastError returned \"%s\"", win_wndName, Kernel32Util.formatMessageFromLastErrorCode( Native.getLastError() )); return hwndMain; } public void enterMessageLoop() throws TabletImplementationException { int bRet; while((bRet = User32_Sjt.GetMessageW(sharedBuffer, Pointer.NULL, 0, 0)) != 0) { // bRet = (bRet & 0xFFffFFff); switch (bRet) { case -1: throw new TabletImplementationException( "GetMessage failed. GetLastError returned \"%s\"", Kernel32Util.formatMessageFromLastErrorCode( Native.getLastError() )); default: User32_Sjt.TranslateMessage(sharedBuffer); User32_Sjt.DispatchMessageW(sharedBuffer); } } // while } public Pointer getHWND() { return win_hwndMain; } public void postEnableTabletMessage() { User32_Sjt.PostMessageW(win_hwndMain, WinDef_Sjt.WM_USER1, Pointer.NULL, Pointer.NULL); } public void postDisableTabletMessage() { User32_Sjt.PostMessageW(win_hwndMain, WinDef_Sjt.WM_USER2, Pointer.NULL, Pointer.NULL); } @Override public Pointer callback(Pointer hWnd, int uMsg, Pointer wParam, Pointer lParam) { switch (uMsg) { case WinDef_Sjt.WM_CREATE: // /* // * Sent when an application requests that a window be created by calling // * the CreateWindowEx or CreateWindow function. // * (The message is sent before the function returns.) // * - courtesy of msdn // */ log.debug("WM_CREATE"); User32_Sjt.ShowWindow(win_hwndMain, WinDef_Sjt.SW_SHOWNORMAL); return WinDef_Sjt.POINTER_ZERO; // handled case WinTabDef.WT_PACKET: log.debug("WT_PACKET"); impl.getWindowsWinTab().handleWindowMessage(hWnd, WinTabDef.WT_PACKET, wParam, lParam); // return WinDef_Sjt.POINTER_ZERO; // handled? break; // case WinDef_Sjt.WM_USER1: // log.DEBUG("WT_USER+1 (enableTablet)"); // impl.getWindowsWinTab().enableTablet(); // return WinDef_Sjt.POINTER_ZERO; // handled? // // // case WinDef_Sjt.WM_USER2: // log.DEBUG("WT_USER+2 (disableTablet)"); // impl.getWindowsWinTab().disableTablet(); // return WinDef_Sjt.POINTER_ZERO; // handled? // // case WinDef_Sjt.WM_PAINT: // return WinDef_Sjt.POINTER_ZERO; // handled // // // case WinDef_Sjt.WM_ERASEBKGND: // return WinDef_Sjt.POINTER_ONE; // handled // case WinDef_Sjt.WM_CLOSE: User32_Sjt.DestroyWindow(hWnd); return WinDef_Sjt.POINTER_ZERO; // handled case WinDef_Sjt.WM_DESTROY: log.debug("WM_DESTROY"); impl.getWindowsWinTab().closeAndCleanup(); User32_Sjt.PostQuitMessage(0); return WinDef_Sjt.POINTER_ZERO; // handled } // default return User32_Sjt.DefWindowProcW(hWnd, uMsg, wParam, lParam); } // method public void closeAndCleanup() { log.debug("Close and cleanup."); User32_Sjt.PostMessageW(win_hwndMain, WinDef_Sjt.WM_CLOSE, Pointer.NULL, Pointer.NULL); } }