Subversion Repositories AndroidProjects

Rev

Rev 563 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * com_gebauz_Bauzoid_platform_windows_Win7TouchInput.cpp
 *
 *  Created on: 19.04.2013
 *      Author: chiu
 */


#include <iostream>
#include <Windows.h>
#include <windowsx.h>

#include "com_gebauz_Bauzoid_platform_windows_Win7TouchInput.h"

using namespace std;

#define WM_REGISTERTOUCH (WM_USER + 0x0001)

WNDPROC wpOrigEditProc = NULL;
JNIEnv* jniEnv = NULL;
jobject jInputObject = NULL;


void SetIntField(jobject obj, char* fieldName, int value)
{
        jclass cls = jniEnv->GetObjectClass(obj);
        jfieldID fid = jniEnv->GetFieldID(cls, fieldName, "I");
        jniEnv->SetIntField(obj, fid, value);

        /*jfieldID fieldId = env->GetFieldID(cls, fieldName, "I");
        if (fieldId == NULL)
        {
                cout << "Field '" << fieldName << "' not found!" << endl;
                return;
        }
        env->SetIntField(obj, fieldId, value);*/

}

void SendTouchInput(HWND hwnd, TOUCHINPUT& input)
{

        if ((jniEnv == NULL) || (jInputObject == NULL))
                return;

        // construct a Java WindowsTouchInfo object and send it to Win7TouchInput

        // find the class
        jclass touchInfoClass = jniEnv->FindClass("com/gebauz/Bauzoid/platform/windows/Win7TouchInput$WindowsTouchInfo");
        if (touchInfoClass == NULL)
        {
                cout << "WindowsTouchInfo class not found" << endl;
                return;
        }

        //cout << "1" << endl;

        // get constructor
        jmethodID methodConstructor = jniEnv->GetMethodID(touchInfoClass, "<init>", "()V");
        if (methodConstructor == NULL)
        {
                cout << "WindowsTouchInfo constructor not found" << endl;
                return;
        }

        //cout << "2" << endl;

        // invoke constructor
        jobject touchInfoInstance = jniEnv->NewObject(touchInfoClass, methodConstructor);
        if (touchInfoInstance == NULL)
        {
                cout << "Could not create WindowsTouchInfo instance!" << endl;
                return;
        }

        //cout << "3" << endl;

        POINT pt;
        pt.x = input.x/100;
        pt.y = input.y/100;

        ::ScreenToClient(hwnd, &pt);

        // set fields
        SetIntField(touchInfoInstance, "x", pt.x);
        SetIntField(touchInfoInstance, "y", pt.y);
        SetIntField(touchInfoInstance, "id", input.dwID);
        SetIntField(touchInfoInstance, "actionFlags", input.dwFlags);

        cout << "[C++] ID: " << input.dwID << " (" << pt.x << ", " << pt.y << ") - " << input.dwFlags << endl;


        //cout << "4" << endl;

        /*jclass cls = jniEnv->GetObjectClass(touchInfoInstance);
        jfieldID fid = jniEnv->GetFieldID(cls, "id", "I");
        jniEnv->SetIntField(touchInfoInstance, fid, 1337);*/


        // invoke method that takes WindowsTouchInfo as parameter
        jmethodID methodOnTouch = jniEnv->GetMethodID(jniEnv->GetObjectClass(jInputObject), "onTouch", "(Lcom/gebauz/Bauzoid/platform/windows/Win7TouchInput$WindowsTouchInfo;)V");
        if (methodOnTouch == NULL)
        {
                cout << "Win7TouchInput.onTouch() method not found!" << endl;
                return;
        }
        jniEnv->CallVoidMethod(jInputObject, methodOnTouch, touchInfoInstance);

        /*
        jmethodID methodTest = jniEnv->GetMethodID(jniEnv->GetObjectClass(jInputObject), "test", "(I)V");
        if (methodTest == NULL)
        {
                cout << "Win7TouchInput.onTouch() method not found!" << endl;
                return;
        }
        jniEnv->CallVoidMethod(jInputObject, methodTest, 1337);*/

       
        //jniEnv->DeleteLocalRef(touchInfoInstance);

        //cout << "6" << endl;
}

void HandleTouch(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
        UINT cInputs = LOWORD(wParam);
        PTOUCHINPUT pInputs = new TOUCHINPUT[cInputs];
        if (NULL != pInputs)
        {
                if (GetTouchInputInfo((HTOUCHINPUT)lParam,
                                                          cInputs,
                                                          pInputs,
                                                          sizeof(TOUCHINPUT)))
                {
                        // process pInputs
                        /*
                        wchar_t text[200];
                        wsprintf(text, L"WM_TOUCH %d", cInputs);

                        ::SetWindowText(hwnd, text);*/


                        for (UINT i = 0; i < cInputs; i++)
                        {
                                SendTouchInput(hwnd, pInputs[i]);
                        }

                        /*if (jniEnv != NULL)
                        {
                                jclass thisClass = jniEnv->GetObjectClass(jInputObject);
                                jmethodID midTest = jniEnv->GetMethodID(thisClass, "test", "()V");
                                if (NULL == midTest)
                                {
                                        cout << "test method not found" << endl;
                                }
                                else
                                {
                                        jniEnv->CallVoidMethod(jInputObject, midTest);
                                        cout << "Called back!!!" << endl;
                                }
                        }*/



                        if (!CloseTouchInputHandle((HTOUCHINPUT)lParam))
                        {
                                // error handling
                        }
                }
                else
                {
                        // GetLastError() and error handling
                }
                delete [] pInputs;
        }
        else
        {
                // error handling, presumably out of memory
        }
}

// Subclass procedure
LRESULT APIENTRY WindowSubClassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
        switch (uMsg)
        {
        case WM_REGISTERTOUCH:
                {
                        if (!RegisterTouchWindow(hwnd, TWF_WANTPALM))
                        {
                                cout << "error registering touch window: " << GetLastError() << endl;
                                break;
                        }
                        cout << "Registered touch" << endl;

                        /*if (jniEnv != NULL)
                        {
                                jclass thisClass = jniEnv->GetObjectClass(jInputObject);
                                jmethodID midTest = jniEnv->GetMethodID(thisClass, "test", "()V");
                                if (NULL == midTest)
                                {
                                        cout << "test method not found" << endl;
                                        break;
                                }
                                jniEnv->CallVoidMethod(jInputObject, midTest);
                                cout << "Called back!!!" << endl;
                        }*/

                }
                break;
        case WM_TOUCH:
                HandleTouch(hwnd, wParam, lParam);
                break;
        }

        return CallWindowProc(wpOrigEditProc, hwnd, uMsg, wParam, lParam);
}

// JNI exported method
JNIEXPORT void JNICALL Java_com_gebauz_Bauzoid_platform_windows_Win7TouchInput_initTouch(JNIEnv* env, jobject jthis, jlong jhwnd)
{
        HWND hwnd = (HWND)jhwnd;
        jniEnv = env;
        jInputObject = env->NewGlobalRef(jthis);

        wpOrigEditProc = (WNDPROC)::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)WindowSubClassProc);
        ::SendMessage(hwnd, WM_REGISTERTOUCH, 0, 0);

        cout << "Subclassed window" << endl;
}