/* 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);
}
}