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