Files
msime-windows/src/IPC/Ipc.cpp
T

483 lines
10 KiB
C++

#include "Ipc.h"
#include <debugapi.h>
#include <handleapi.h>
#include <minwindef.h>
#include <winnt.h>
#include <winuser.h>
#include "fmt/xchar.h"
#include "spdlog/spdlog.h"
#include "Globals.h"
static HANDLE hMapFile = nullptr;
static void *pBuf;
static FanyImeSharedMemoryData *sharedData;
static bool canUseSharedMemory = true;
static HANDLE hPipe = nullptr;
static bool canUseNamedPipe = true;
static FanyImeNamedpipeData namedpipeData;
int InitIpc()
{
//
// Shared memory, open here
//
hMapFile = OpenFileMappingW( //
FILE_MAP_ALL_ACCESS, //
FALSE, //
FANY_IME_SHARED_MEMORY //
);
//
// Shared memory is not available, try to use namedpipe
//
InitNamedpipe();
if (!hMapFile)
{
OutputDebugString(L"CreateFileMapping failed\n");
// Error handling
canUseSharedMemory = false;
spdlog::info("CreateFileMapping error: {}", GetLastError());
return 0;
}
bool alreadyExists = (GetLastError() == ERROR_ALREADY_EXISTS);
pBuf = MapViewOfFile( //
hMapFile, //
FILE_MAP_ALL_ACCESS, //
0, //
0, //
BUFFER_SIZE //
); //
if (!pBuf)
{
// Error handling
spdlog::info("MapViewOfFile error when activated: {}", GetLastError());
}
sharedData = static_cast<FanyImeSharedMemoryData *>(pBuf);
// Only initialize the shared memory when first created
if (!alreadyExists)
{
// Initialize
*sharedData = {};
sharedData->point[0] = 100;
sharedData->point[1] = 100;
}
return 0;
}
int InitNamedpipe()
{
hPipe = CreateFile( //
FANY_IME_NAMED_PIPE, //
GENERIC_READ | GENERIC_WRITE, //
0, //
nullptr, //
OPEN_EXISTING, //
0, //
nullptr //
);
if (!hPipe)
{
canUseNamedPipe = false;
OutputDebugString(L"Connect to namedpipe failed\n");
return -1;
}
else
{
}
return 0;
}
int CloseIpc()
{
//
// Namedpipe
//
CloseNamedpipe();
if (!canUseSharedMemory)
{
return -1;
}
//
// Shared memory
//
if (pBuf)
{
UnmapViewOfFile(pBuf);
pBuf = nullptr;
}
if (hMapFile)
{
CloseHandle(hMapFile);
hMapFile = nullptr;
}
//
// Events
//
for (const auto &eventName : FANY_IME_EVENT_ARRAY)
{
HANDLE hEvent = OpenEventW( //
EVENT_ALL_ACCESS, //
FALSE, //
eventName.c_str() //
); //
if (hEvent)
{
CloseHandle(hEvent);
}
}
return 0;
}
int CloseNamedpipe()
{
if (hPipe)
{
CloseHandle(hPipe);
hPipe = nullptr;
}
return 0;
}
int WriteDataToSharedMemory( //
UINT keycode, //
UINT modifiers_down, //
const int point[2], //
int pinyin_length, //
const std::wstring &pinyin_string, //
UINT write_flag //
)
{
WriteDataToNamedPipe(keycode, modifiers_down, point, pinyin_length, pinyin_string, write_flag);
if (!canUseSharedMemory)
{
if (canUseNamedPipe)
{
return WriteDataToNamedPipe(keycode, modifiers_down, point, pinyin_length, pinyin_string, write_flag);
}
return -1;
}
if (write_flag >> 0 & 1u)
{
sharedData->keycode = keycode;
}
if (write_flag >> 1 & 1u)
{
sharedData->modifiers_down = modifiers_down;
}
if (write_flag >> 2 & 1u)
{
sharedData->point[0] = point[0];
sharedData->point[1] = point[1];
}
if (write_flag >> 3 & 1u)
{
sharedData->pinyin_length = pinyin_length;
}
if (write_flag >> 4 & 1u)
{
wcscpy_s(sharedData->pinyin_string, pinyin_string.c_str());
sharedData->pinyin_string[pinyin_length] = L'\0';
}
return 0;
}
/**
* @brief
*
* @param keycode
* @param modifiers_down
* @param point
* @param pinyin_length
* @param pinyin_string
* @param write_flag
* @return int
*/
int WriteDataToNamedPipe( //
UINT keycode, //
UINT modifiers_down, //
const int point[2], //
int pinyin_length, //
const std::wstring &pinyin_string, //
UINT write_flag //
)
{
if (!canUseNamedPipe)
{
return -1;
}
if (write_flag >> 0 & 1u)
{
namedpipeData.keycode = keycode;
}
if (write_flag >> 1 & 1u)
{
namedpipeData.modifiers_down = modifiers_down;
}
if (write_flag >> 2 & 1u)
{
namedpipeData.point[0] = point[0];
namedpipeData.point[1] = point[1];
}
if (write_flag >> 3 & 1u)
{
namedpipeData.pinyin_length = pinyin_length;
}
if (write_flag >> 4 & 1u)
{
wcscpy_s(namedpipeData.pinyin_string, pinyin_string.c_str());
namedpipeData.pinyin_string[pinyin_length] = L'\0';
}
return 0;
}
int SendKeyEventToUIProcess()
{
// OutputDebugString(fmt::format(L"SendKeyEventToUIProcess, canUseSharedMemory = {}, canUseNamedPipe = {}\n",
// canUseSharedMemory, canUseNamedPipe)
// .c_str());
if (!canUseSharedMemory)
{
// OutputDebugString(L"SendKeyEventToUIProcessViaNamedPipe\n");
if (canUseNamedPipe)
{
// OutputDebugString(L"Really SendKeyEventToUIProcessViaNamedPipe \n");
return SendKeyEventToUIProcessViaNamedPipe();
}
}
HANDLE hEvent = OpenEventW( //
EVENT_MODIFY_STATE, //
FALSE, //
FANY_IME_EVENT_ARRAY[0].c_str() //
); //
if (!hEvent)
{
// TODO: Error handling
}
if (!SetEvent(hEvent))
{
// TODO: Error handling
DWORD err = GetLastError();
spdlog::info("SetEvent error: {}", err);
}
CloseHandle(hEvent);
return 0;
}
int SendHideCandidateWndEventToUIProcess()
{
if (!canUseSharedMemory)
{
if (canUseNamedPipe)
{
return SendHideCandidateWndEventToUIProcessViaNamedPipe();
}
}
HANDLE hEvent = OpenEventW( //
EVENT_MODIFY_STATE, //
FALSE, //
FANY_IME_EVENT_ARRAY[1].c_str() // FanyHideCandidateWndEvent
); //
if (!hEvent)
{
// TODO: Error handling
}
if (!SetEvent(hEvent))
{
// TODO: Error handling
DWORD err = GetLastError();
spdlog::info("SetEvent error: {}", err);
}
CloseHandle(hEvent);
return 0;
}
int SendShowCandidateWndEventToUIProcess()
{
if (!canUseSharedMemory)
{
if (canUseNamedPipe)
{
return SendShowCandidateWndEventToUIProcessViaNamedPipe();
}
}
HANDLE hEvent = OpenEventW( //
EVENT_MODIFY_STATE, //
FALSE, //
FANY_IME_EVENT_ARRAY[2].c_str() // FanyShowCandidateWndEvent
); //
if (!hEvent)
{
// TODO: Error handling
}
if (!SetEvent(hEvent))
{
// TODO: Error handling
DWORD err = GetLastError();
spdlog::info("SetEvent error: {}", err);
}
CloseHandle(hEvent);
return 0;
}
int SendMoveCandidateWndEventToUIProcess()
{
if (!canUseSharedMemory)
{
if (canUseNamedPipe)
{
return SendMoveCandidateWndEventToUIProcessViaNamedPipe();
}
}
HANDLE hEvent = OpenEventW( //
EVENT_MODIFY_STATE, //
FALSE, //
FANY_IME_EVENT_ARRAY[3].c_str() // FanyMoveCandidateWndEvent
); //
if (!hEvent)
{
// TODO: Error handling
spdlog::info("Open FanyMoveCandidateWnd Event error");
}
if (!SetEvent(hEvent))
{
// TODO: Error handling
DWORD err = GetLastError();
spdlog::info("SetEvent error: {}", err);
}
CloseHandle(hEvent);
return 0;
}
//
// Named pipe
//
void SendToNamedpipe()
{
if (!canUseNamedPipe)
{
return;
}
if (!hPipe)
{
return;
}
DWORD bytesWritten = 0;
BOOL ret = WriteFile( //
hPipe, //
&namedpipeData, //
sizeof(namedpipeData), //
&bytesWritten, //
NULL //
);
if (!ret || bytesWritten != sizeof(namedpipeData))
{
// TODO: Error handling
DWORD err = GetLastError();
spdlog::info("WriteFile error: {}", err);
}
}
/**
* event_type
* 0: FanyImeKeyEvent
* 1: FanyHideCandidateWndEvent
* 2: FanyShowCandidateWndEvent
* 3: FanyMoveCandidateWndEvent
*/
int SendKeyEventToUIProcessViaNamedPipe()
{
// OutputDebugString(L"first SendKeyEventToUIProcessViaNamedPipe\n");
if (!canUseNamedPipe)
{
return -1;
}
namedpipeData.event_type = 0;
SendToNamedpipe();
return 0;
}
int SendHideCandidateWndEventToUIProcessViaNamedPipe()
{
if (!canUseNamedPipe)
{
return -1;
}
namedpipeData.event_type = 1;
SendToNamedpipe();
return 0;
}
int SendShowCandidateWndEventToUIProcessViaNamedPipe()
{
if (!canUseNamedPipe)
{
return -1;
}
namedpipeData.event_type = 2;
SendToNamedpipe();
return 0;
}
int SendMoveCandidateWndEventToUIProcessViaNamedPipe()
{
if (!canUseNamedPipe)
{
return -1;
}
namedpipeData.event_type = 3;
SendToNamedpipe();
return 0;
}