<commit_before>//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "SynComDefs.h"
#include <shlwapi.h>
#include <psapi.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "SYNCTRLLib_OCX"
#pragma link "SYNCOMLib_OCX"
#pragma resource "*.dfm"

static const UnicodeString regKey = "Software\\TwoFingerScroll";

struct TTapInfo {
	DWORD eventDown, eventUp, x;
};

static const TTapInfo tapInfo[] = {
	{MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP, 0},
	{MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP, 0},
	{MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP, 0},
	{MOUSEEVENTF_XDOWN, MOUSEEVENTF_XUP, XBUTTON1},
	{MOUSEEVENTF_XDOWN, MOUSEEVENTF_XUP, XBUTTON2}
};

TForm1 *Form1;
//---------------------------------------------------------------------------

UnicodeString __fastcall GetForegroundWindowBaseModuleName()
{
	HWND hWnd;

	hWnd = GetForegroundWindow();
	if (hWnd) {
		DWORD dwProcessId;
		HANDLE hProcess;

		GetWindowThreadProcessId(hWnd, &dwProcessId);
		hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
			PROCESS_VM_READ, false, dwProcessId);
		if (hProcess) {
			HMODULE hMod;
			DWORD cbNeeded;

			if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) {
				char szModule[MAX_PATH];

				GetModuleBaseName(hProcess, hMod, szModule, MAX_PATH);
				return UnicodeString(szModule);
			}

			CloseHandle(hProcess);
		}
	}

	return UnicodeString();
}
//---------------------------------------------------------------------------

int __fastcall GetScrollMode()
{
	UnicodeString name = GetForegroundWindowBaseModuleName();
	int mode = 1;

	if (name != "") {
		TRegistry *reg;

		reg = new TRegistry();
		reg->RootKey = HKEY_CURRENT_USER;
		if (reg->OpenKeyReadOnly(regKey + "\\scrollModeApps")) {
			if (reg->ValueExists(name)) {
				mode = reg->ReadInteger(name);
			}
			reg->CloseKey();
		}
	}
	return mode;
}
//---------------------------------------------------------------------------

void __fastcall SetScrollMode(int mode)
{
	UnicodeString name = GetForegroundWindowBaseModuleName();

	if (name != "") {
		TRegistry *reg;

		reg = new TRegistry();
		reg->RootKey = HKEY_CURRENT_USER;
		reg->Access = KEY_ALL_ACCESS;
		if (reg->OpenKey(regKey + "\\scrollModeApps", true)) {
			if (mode != 1) {
				reg->WriteInteger(name, mode);
			}
			else {
				reg->DeleteValue(name);
            }
			reg->CloseKey();
		}
	}
}
//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	synAPI = new TSynAPI(this);
	synTouchPad = new TSynDevice(this);

	synAPI->Initialize();

	long devHandle = -1;

	synAPI->FindDevice(SE_ConnectionAny,
		SE_DeviceTouchPad,
		&devHandle);

	if (devHandle < 0) {
		Application->MessageBox(L"No Synaptics TouchPad found!",
			L"TwoFingerScroll");
		Application->Terminate();
	}

	synTouchPad->Select(devHandle);
	synTouchPad->CreatePacket(&synPacket);

	long multi;

	synTouchPad->GetProperty(SP_IsMultiFingerCapable, &multi);
	if (!multi) {
		TRegistry *reg = new TRegistry();
		reg->RootKey = HKEY_LOCAL_MACHINE;
		reg->Access = KEY_ALL_ACCESS;
		if (!reg->OpenKey("System\\CurrentControlSet\\Services\\SynTP\\Parameters", false)) {
			Application->MessageBox(L"Synaptics driver registry key missing. Reinstall drivers.",
				L"TwoFingerScroll");
			Application->Terminate();
		}
		unsigned int mask = 0;
		if (reg->ValueExists("CapabilitiesMask")) {
			mask = reg->ReadInteger("CapabilitiesMask");
			if (mask == 0xFFFFFFFF) {
				Application->MessageBox(L"This TouchPad doesn't support multiple fingers.",
					L"TwoFingerScroll");
				Application->Terminate();
			}
		}
		if (mask != 0xFFFFFFFF) {
			reg->WriteInteger("CapabilitiesMask", 0xFFFFFFFF);
			reg->CloseKey();
			if (Application->MessageBox(L"Driver support for multiple fingers has been enabled.\n"
				"System restart is required for the changes to take effect.\n"
				"\n"
				"Restart now?",
				L"TwoFingerScroll", MB_YESNO) == IDYES)
			{
				ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_APPLICATION);
			}
			Application->Terminate();
		}
		reg->CloseKey();
	}

	// activate the OnPacket event
	synTouchPad->SetSynchronousNotification(this);

	settings = new TRegistry();

	SettingsLoad();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::SettingsLoad(bool defaults)
{
	settings->RootKey = HKEY_CURRENT_USER;
	if (!defaults)
		settings->OpenKeyReadOnly(regKey);

	if (settings->ValueExists("scroll")) {
		switch (settings->ReadInteger("scroll")) {
		case 1:<commit_msg>Improved code responsible for detection of driver multiple finger support.<commit_after>//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "SynComDefs.h"
#include <shlwapi.h>
#include <psapi.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "SYNCTRLLib_OCX"
#pragma link "SYNCOMLib_OCX"
#pragma resource "*.dfm"

static const UnicodeString regKey = "Software\\TwoFingerScroll";

struct TTapInfo {
	DWORD eventDown, eventUp, x;
};

static const TTapInfo tapInfo[] = {
	{MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP, 0},
	{MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP, 0},
	{MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP, 0},
	{MOUSEEVENTF_XDOWN, MOUSEEVENTF_XUP, XBUTTON1},
	{MOUSEEVENTF_XDOWN, MOUSEEVENTF_XUP, XBUTTON2}
};

TForm1 *Form1;
//---------------------------------------------------------------------------

UnicodeString __fastcall GetForegroundWindowBaseModuleName()
{
	HWND hWnd;

	hWnd = GetForegroundWindow();
	if (hWnd) {
		DWORD dwProcessId;
		HANDLE hProcess;

		GetWindowThreadProcessId(hWnd, &dwProcessId);
		hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
			PROCESS_VM_READ, false, dwProcessId);
		if (hProcess) {
			HMODULE hMod;
			DWORD cbNeeded;

			if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) {
				char szModule[MAX_PATH];

				GetModuleBaseName(hProcess, hMod, szModule, MAX_PATH);
				return UnicodeString(szModule);
			}

			CloseHandle(hProcess);
		}
	}

	return UnicodeString();
}
//---------------------------------------------------------------------------

int __fastcall GetScrollMode()
{
	UnicodeString name = GetForegroundWindowBaseModuleName();
	int mode = 1;

	if (name != "") {
		TRegistry *reg;

		reg = new TRegistry();
		reg->RootKey = HKEY_CURRENT_USER;
		if (reg->OpenKeyReadOnly(regKey + "\\scrollModeApps")) {
			if (reg->ValueExists(name)) {
				mode = reg->ReadInteger(name);
			}
			reg->CloseKey();
		}
	}
	return mode;
}
//---------------------------------------------------------------------------

void __fastcall SetScrollMode(int mode)
{
	UnicodeString name = GetForegroundWindowBaseModuleName();

	if (name != "") {
		TRegistry *reg;

		reg = new TRegistry();
		reg->RootKey = HKEY_CURRENT_USER;
		reg->Access = KEY_ALL_ACCESS;
		if (reg->OpenKey(regKey + "\\scrollModeApps", true)) {
			if (mode != 1) {
				reg->WriteInteger(name, mode);
			}
			else {
				reg->DeleteValue(name);
            }
			reg->CloseKey();
		}
	}
}
//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	synAPI = new TSynAPI(this);
	synTouchPad = new TSynDevice(this);

	synAPI->Initialize();

	long devHandle = -1;

	synAPI->FindDevice(SE_ConnectionAny,
		SE_DeviceTouchPad,
		&devHandle);

	if (devHandle < 0) {
		Application->MessageBox(L"No Synaptics TouchPad device found!",
			L"TwoFingerScroll");
		Application->Terminate();
	}

	synTouchPad->Select(devHandle);
	synTouchPad->CreatePacket(&synPacket);

	long multi;

	synTouchPad->GetProperty(SP_IsMultiFingerCapable, &multi);
	if (!multi) {
		TRegistry *reg = new TRegistry();
		reg->RootKey = HKEY_LOCAL_MACHINE;
		reg->Access = KEY_ALL_ACCESS;
		if (!reg->OpenKey("System\\CurrentControlSet\\Services\\SynTP\\Parameters", false)) {
			Application->MessageBox(L"Synaptics kernel driver registry keys missing. Reinstall drivers.",
				L"TwoFingerScroll");
			Application->Terminate();
		}
		unsigned int mask = 0;
		if (reg->ValueExists("CapabilitiesMask")) {
			mask = reg->ReadInteger("CapabilitiesMask");
			if (mask == 0xFFFFFFFF) {
				Application->MessageBox(L"Driver support for multiple fingers is already enabled but\n"
					"the driver still doesn't report multiple fingers. Either you haven't restarted\n"
					"the system yet or your TouchPad doesn't support multiple fingers."
					L"TwoFingerScroll");
				Application->Terminate();
			}
		}
		if (mask != 0xFFFFFFFF) {
			reg->WriteInteger("CapabilitiesMask", 0xFFFFFFFF);
			reg->CloseKey();
			Application->MessageBox(L"Driver support for multiple fingers has been enabled.\n"
            	"\n"
				"Restart system for the changes to take effect.",
				L"TwoFingerScroll");
			Application->Terminate();
		}
		reg->CloseKey();
	}

	// activate the OnPacket event
	synTouchPad->SetSynchronousNotification(this);

	settings = new TRegistry();

	SettingsLoad();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::SettingsLoad(bool defaults)
{
	settings->RootKey = HKEY_CURRENT_USER;
	if (!defaults)
		settings->OpenKeyReadOnly(regKey);

	if (settings->ValueExists("scroll")) {
		switch (settings->ReadInteger("scroll")) {
		case 1:
{'fraction_non_alphanumeric': 0.2306395532609841, 'fraction_numerical': 0.004214519018017069, 'mean_word_length': 2.6733746130030958, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 6, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1934514', 'n_tokens_mistral': 3326, 'n_tokens_neox': 2994, 'n_words': 601}