Skip to content

Commit

Permalink
Implemented canvas re-grabbing, which allows you to send events when …
Browse files Browse the repository at this point in the history
…the canvas gets rebuild.
  • Loading branch information
patriq committed Sep 24, 2018
1 parent 5230915 commit 4b8b72c
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 10 deletions.
42 changes: 36 additions & 6 deletions KInput/KInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*/

#include "KInput.hpp"
#include <windows.h>
#include <vector>
#include <string>
#include <iostream>
Expand Down Expand Up @@ -78,7 +77,6 @@ void KInput::GrabCanvas() {
HMODULE JVMDLL = GetModuleHandle("jvm.dll");
if (!JVMDLL)
return;
typedef int (*ptr_GCJavaVMs)(JavaVM **vmBuf, jsize bufLen, jsize * nVMs);
ptr_GCJavaVMs GetJVMs = (ptr_GCJavaVMs)GetProcAddress(JVMDLL, "JNI_GetCreatedJavaVMs");
jobject TempCanvas = nullptr;
do {
Expand All @@ -90,16 +88,15 @@ void KInput::GrabCanvas() {
if (!AWTDLL)
break;

typedef jobject (JNICALL *ptr_GetComponent)(JNIEnv* env, void* platformInfo);
ptr_GetComponent GetComponent = (ptr_GetComponent)GetProcAddress(AWTDLL, "_DSGetComponent@8");
if (!(this->AttachThread() && GetComponent))
this->GetComponent = (ptr_GetComponent)GetProcAddress(AWTDLL, "_DSGetComponent@8");
if (!(this->AttachThread() && this->GetComponent))
break;

HWND CanvasHWND = GetCanvasHWND();
if (!CanvasHWND)
break;

TempCanvas = GetComponent(this->Thread, (void*)CanvasHWND);
TempCanvas = this->GetComponent(this->Thread, (void*)CanvasHWND);
if (!TempCanvas)
break;

Expand Down Expand Up @@ -127,6 +124,36 @@ void KInput::GrabCanvas() {
}
}

void KInput::NotifyCanvasUpdate(HWND CanvasHWND) {
this->CanvasUpdate = CanvasHWND;
}

void KInput::UpdateCanvas()
{
if (!CanvasUpdate)
return;
jobject TempCanvas = nullptr;
do
{
if (!(this->AttachThread() && this->GetComponent))
break;
TempCanvas = this->GetComponent(this->Thread, (void*) CanvasUpdate);
if (!TempCanvas)
break;
if (this->Canvas)
{
this->Thread->DeleteGlobalRef(this->Canvas);
this->Canvas = nullptr;
}
this->Canvas = this->Thread->NewGlobalRef(TempCanvas);
} while (false);
if (TempCanvas) {
this->Thread->DeleteLocalRef(TempCanvas);
TempCanvas = nullptr;
}
CanvasUpdate = nullptr;
}

KInput::KInput()
{
std::cout << "Starting a new KInput instance! o/" << std::endl;
Expand All @@ -135,6 +162,7 @@ KInput::KInput()
this->Thread = nullptr;
this->Client = nullptr;
this->Canvas = nullptr;
this->GetComponent = nullptr;
this->Canvas_Class = nullptr;
this->Canvas_DispatchEvent = nullptr;
this->FocusEvent_Class = nullptr;
Expand All @@ -145,6 +173,7 @@ KInput::KInput()
this->MouseEvent_Init = nullptr;
this->MouseWheelEvent_Class = nullptr;
this->MouseWheelEvent_Init = nullptr;
this->CanvasUpdate = nullptr;
this->GrabCanvas();
}

Expand Down Expand Up @@ -176,6 +205,7 @@ bool KInput::DispatchEvent(jobject Event)
this->Canvas_DispatchEvent = this->Thread->GetMethodID(this->Canvas_Class, "dispatchEvent", "(Ljava/awt/AWTEvent;)V");
if (this->Canvas_DispatchEvent)
{
UpdateCanvas();
this->Thread->CallVoidMethod(this->Canvas, this->Canvas_DispatchEvent, Event);
return true;
}
Expand Down
11 changes: 11 additions & 0 deletions KInput/KInput.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
#ifndef KINPUT_HPP_INCLUDED
#define KINPUT_HPP_INCLUDED

#include <windows.h>
#include <jni.h>
#include <cstdint>
#include <mutex>

typedef int (*ptr_GCJavaVMs)(JavaVM **vmBuf, jsize bufLen, jsize * nVMs);
typedef jobject (JNICALL *ptr_GetComponent)(JNIEnv* env, void* platformInfo);

class KInput
{
Expand All @@ -13,6 +18,8 @@ class KInput
jobject Client;
jobject Canvas;

ptr_GetComponent GetComponent;

jclass Canvas_Class;
jmethodID Canvas_DispatchEvent;

Expand All @@ -28,8 +35,11 @@ class KInput
jclass MouseWheelEvent_Class;
jmethodID MouseWheelEvent_Init;

HWND CanvasUpdate;

bool AttachThread();
void GrabCanvas();
void UpdateCanvas();
public:
KInput();

Expand All @@ -42,6 +52,7 @@ class KInput
bool MouseWheelEvent(std::int32_t ID, std::int64_t When, std::int32_t Modifiers, std::int32_t X,
std::int32_t Y, std::int32_t ClickCount, bool PopupTrigger, std::int32_t ScrollType,
std::int32_t ScrollAmount, std::int32_t WheelRotation);
void NotifyCanvasUpdate(HWND CanvasHWND);
~KInput();
};

Expand Down
54 changes: 54 additions & 0 deletions KInput/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,62 @@

#include <windows.h>
#include <iostream>
#include <MinHook.h>
#include "KInput.hpp"

KInput* Input = nullptr;

typedef HWND(__stdcall *ptr_CreateWindowExW)(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);

ptr_CreateWindowExW CreateWindowExW_Original = nullptr;
LPVOID *CreateWindowExW_Address = nullptr;

HWND __stdcall CreateWindowExW_Hook(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
{
HWND Temp = CreateWindowExW_Original(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
std::wstring WStr(lpClassName);
std::string ClassNameString(WStr.begin(), WStr.end());
if (ClassNameString == "SunAwtCanvas" && Input) {
Input->NotifyCanvasUpdate(Temp);
}
return Temp;
}

bool HookCreateWindow() {
HMODULE kernel = GetModuleHandle("user32.dll");
CreateWindowExW_Address = (LPVOID *) GetProcAddress(kernel, "CreateWindowExW");
if (!CreateWindowExW_Address) {
return false;
}

// Initialize MinHook.
if (MH_Initialize() != MH_OK)
{
return false;
}

// Create a hook for MessageBoxW, in disabled state.
if (MH_CreateHook(CreateWindowExW_Address, ((LPVOID *) &CreateWindowExW_Hook),
((LPVOID *) &CreateWindowExW_Original)) != MH_OK)
{
return false;
}

// Enable the hook for CreateWindowExW.
return MH_EnableHook(CreateWindowExW_Address) == MH_OK;
}

bool UnHookCreateWindow() {
// Disable the hook.
if (MH_DisableHook(CreateWindowExW_Address) != MH_OK)
{
return false;
}

// Uninitialize MinHook.
return MH_Uninitialize() == MH_OK;
}

extern "C"
__declspec(dllexport)
bool KInput_FocusEvent(void* Data)
Expand Down Expand Up @@ -109,13 +161,15 @@ bool __stdcall DllMain(HMODULE DLL, DWORD fdwReason, LPVOID lpvReserved)
case DLL_PROCESS_ATTACH:
{
DisableThreadLibraryCalls(DLL);
HookCreateWindow();
Input = new KInput();
}
break;
case DLL_PROCESS_DETACH:
{
if (Input)
{
UnHookCreateWindow();
delete Input;
Input = nullptr;
}
Expand Down
8 changes: 4 additions & 4 deletions KInput/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ AR = ar.exe
LD = g++.exe
WINDRES = windres.exe

INC =
INC = -I"minhook\include"
CFLAGS =
RESINC =
LIBDIR =
LIB =
LDFLAGS =
LIBDIR = -L"minhook\lib"
LIB = -l"MinHook"
LDFLAGS =

INC_RELEASE = $(INC) -I"C:\Program Files (x86)\Java\jdk1.8.0_171\include" -I"C:\Program Files (x86)\Java\jdk1.8.0_171\include\win32"
CFLAGS_RELEASE = $(CFLAGS) -Os -Wall -std=c++1z -m32 -DBUILD_DLL
Expand Down

0 comments on commit 4b8b72c

Please sign in to comment.