コミットメタ情報

リビジョンd56ffdae45e19c1775b04c76759e9fd0ee0f18e2 (tree)
日時2012-02-20 13:25:23
作者Kazuhiro Fujieda <fujieda@user...>
コミッターKazuhiro Fujieda

ログメッセージ

Share the hook state among 32bit and 64bit processes.
Rewrite the IPC stuff.

変更サマリ

差分

--- a/xkeymacs/mainfrm.cpp
+++ b/xkeymacs/mainfrm.cpp
@@ -22,7 +22,6 @@ HICON CMainFrame::m_hIcon[MAX_ICON_TYPE][MAX_STATUS];
2222 DWORD CMainFrame::m_dwOldMessage[MAX_ICON_TYPE];
2323 NOTIFYICONDATA CMainFrame::m_stNtfyIcon[MAX_ICON_TYPE];
2424 NOTIFYICONDATA CMainFrame::m_stOldNtfyIcon[MAX_ICON_TYPE];
25-bool CMainFrame::m_bPollIconMessage;
2625
2726 IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
2827
@@ -157,47 +156,62 @@ int CMainFrame::OnCreate(const LPCREATESTRUCT lpCreateStruct)
157156
158157 void CMainFrame::StartPollThread()
159158 {
160- m_bPollIconMessage = TRUE;
161- m_hThread = CreateThread(NULL, 0, PollIconMessage, this, 0, NULL);
159+ m_hThread = CreateThread(NULL, 0, PollMessage, this, 0, NULL);
162160 }
163161
164162 void CMainFrame::TerminatePollThread()
165163 {
166- m_bPollIconMessage = FALSE;
167- IconMsg nul = {MAIN_ICON,};
168- if (CXkeymacsDll::SendIconMessage(&nul, 1))
169- WaitForSingleObject(m_hThread, 5000);
164+ DWORD ack, read;
165+ IPC32Message msg;
166+ msg.Type = IPC32_TERMINATE;
167+ CallNamedPipe(XKEYMACS32_PIPE, &msg, sizeof(msg.Type), &ack, sizeof(DWORD), &read, NMPWAIT_NOWAIT);
170168 CloseHandle(m_hThread);
171169 }
172170
173-DWORD WINAPI CMainFrame::PollIconMessage(LPVOID)
171+bool SendAck(HANDLE pipe)
174172 {
175- HANDLE hPipe = CreateNamedPipe(ICON_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1,
176- sizeof(DWORD), sizeof(IconMsg) * MAX_ICON_TYPE, 0, NULL);
177- if (hPipe == INVALID_HANDLE_VALUE)
173+ DWORD written, ack = 0;
174+ return WriteFile(pipe, &ack, sizeof(DWORD), &written, NULL) && written == sizeof(DWORD) &&
175+ FlushFileBuffers(pipe) && DisconnectNamedPipe(pipe);
176+}
177+
178+DWORD WINAPI CMainFrame::PollMessage(LPVOID)
179+{
180+ HANDLE pipe = CreateNamedPipe(XKEYMACS32_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1,
181+ sizeof(DWORD), sizeof(IPC32Message), 0, NULL);
182+ if (pipe == INVALID_HANDLE_VALUE)
178183 return 1;
179184 for (; ;) {
180- if (ConnectNamedPipe(hPipe, NULL) ? FALSE : (GetLastError() != ERROR_PIPE_CONNECTED))
185+ if (ConnectNamedPipe(pipe, NULL) ? FALSE : (GetLastError() != ERROR_PIPE_CONNECTED))
181186 break;
182- IconMsg msg[MAX_ICON_TYPE];
187+ IPC32Message msg;
183188 DWORD read;
184- if (!ReadFile(hPipe, msg, sizeof(msg), &read, NULL))
189+ if (!ReadFile(pipe, &msg, sizeof(msg), &read, NULL))
185190 break;
186- DWORD written, ack = 0;
187- // return ack ASAP to release hooks from blocking state.
188- if (!WriteFile(hPipe, &ack, sizeof(DWORD), &written, NULL) || written != sizeof(DWORD) ||
189- !FlushFileBuffers(hPipe) || !DisconnectNamedPipe(hPipe))
190- break;
191- if (!m_bPollIconMessage)
192- break;
193- for (DWORD i = 0; i < read / sizeof(IconMsg); ++i) {
194- m_stNtfyIcon[msg[i].nType].hIcon = m_hIcon[msg[i].nType][msg[i].nState];
195- if (msg[i].nType == MX_ICON && msg[i].szTip[0] != 0)
196- memcpy(m_stNtfyIcon[MX_ICON].szTip, msg[i].szTip, 128);
197- DoShell_NotifyIcon(msg[i].nType, NIM_MODIFY);
191+ switch (msg.Type) {
192+ case IPC32_TERMINATE:
193+ SendAck(pipe);
194+ goto exit;
195+ case IPC32_HOOKSTATE:
196+ CXkeymacsDll::SetHookStateDirect(msg.Enable);
197+ static_cast<CXkeymacsApp *>(AfxGetApp())->SendIPC64Message(msg.Enable ? IPC64_ENABLE : IPC64_DISABLE);
198+ if (!SendAck(pipe))
199+ goto exit;
200+ continue;
201+ case IPC32_ICON:
202+ // return ack ASAP to release hooks from blocking state.
203+ if (!SendAck(pipe))
204+ goto exit;
205+ for (DWORD i = 0; i < (read - offsetof(IPC32Message, IconState)) / sizeof(IconState); ++i) {
206+ m_stNtfyIcon[msg.IconState[i].Type].hIcon = m_hIcon[msg.IconState[i].Type][msg.IconState[i].State];
207+ if (msg.IconState[i].Type == MX_ICON && msg.IconState[i].Tip[0] != 0)
208+ memcpy(m_stNtfyIcon[MX_ICON].szTip, msg.IconState[i].Tip, 128);
209+ DoShell_NotifyIcon(msg.IconState[i].Type, NIM_MODIFY);
210+ }
198211 }
199212 }
200- CloseHandle(hPipe);
213+exit:
214+ CloseHandle(pipe);
201215 return 0;
202216 }
203217
@@ -471,7 +485,7 @@ void CMainFrame::OnQuit()
471485
472486 CXkeymacsDll::ReleaseHooks();
473487 TerminatePollThread();
474- static_cast<CXkeymacsApp *>(AfxGetApp())->SendIPCMessage(XKEYMACS_EXIT);
488+ static_cast<CXkeymacsApp *>(AfxGetApp())->SendIPC64Message(IPC64_EXIT);
475489 DeleteAllShell_NotifyIcon();
476490
477491 PostQuitMessage(0);
@@ -522,9 +536,7 @@ void CMainFrame::OnReset()
522536 TerminatePollThread();
523537 CXkeymacsDll::ResetHooks();
524538 StartPollThread();
525- CXkeymacsApp *pApp = static_cast<CXkeymacsApp *>(AfxGetApp());
526- if (!pApp->SendIPCMessage(XKEYMACS_RESET))
527- pApp->Start64bitProcess(); // try to restart 64bit app
539+ static_cast<CXkeymacsApp *>(AfxGetApp())->SendIPC64Message(IPC64_RESET);
528540 }
529541
530542 void CMainFrame::OnHelpFinder()
--- a/xkeymacs/mainfrm.h
+++ b/xkeymacs/mainfrm.h
@@ -101,11 +101,10 @@ private:
101101 static void DoShell_NotifyIcon(ICON_TYPE icon, DWORD dwMessage);
102102 static void DeleteAllShell_NotifyIcon();
103103 static void AddAllShell_NotifyIcon();
104- static bool m_bPollIconMessage;
105104 HANDLE m_hThread;
106105 void StartPollThread();
107106 void TerminatePollThread();
108- static DWORD WINAPI PollIconMessage(LPVOID lpParam);
107+ static DWORD WINAPI PollMessage(LPVOID lpParam);
109108 public:
110109 void EnableShell_NotifyIcon(ICON_TYPE icon, BOOL bEnable);
111110 };
--- a/xkeymacs/profile.cpp
+++ b/xkeymacs/profile.cpp
@@ -281,7 +281,7 @@ void CProfile::SetDllData()
281281 return;
282282 if (!CXkeymacsDll::SaveConfig())
283283 return;
284- pApp->SendIPCMessage(XKEYMACS_RELOAD);
284+ pApp->SendIPC64Message(IPC64_RELOAD);
285285 }
286286
287287 void CProfile::SaveKeyBind(LPCTSTR appName, int comID, int type, int key)
--- a/xkeymacs/xkeymacs.cpp
+++ b/xkeymacs/xkeymacs.cpp
@@ -114,15 +114,14 @@ BOOL CXkeymacsApp::Start64bitProcess()
114114 return TRUE;
115115 }
116116
117-BOOL CXkeymacsApp::SendIPCMessage(DWORD msg)
117+void CXkeymacsApp::SendIPC64Message(DWORD msg)
118118 {
119119 if (!m_bIsWow64)
120- return TRUE;
120+ return;
121121 DWORD ack, read;
122122 for (int i = 0; i < 10; Sleep(100), ++i)
123- if (CallNamedPipe(IPC_PIPE, &msg, sizeof(msg), &ack, sizeof(DWORD), &read, NMPWAIT_WAIT_FOREVER))
124- return TRUE;
125- return FALSE;
123+ if (CallNamedPipe(XKEYMACS64_PIPE, &msg, sizeof(msg), &ack, sizeof(DWORD), &read, NMPWAIT_WAIT_FOREVER))
124+ return;;
126125 }
127126
128127 int CXkeymacsApp::ExitInstance()
--- a/xkeymacs/xkeymacs.h
+++ b/xkeymacs/xkeymacs.h
@@ -38,7 +38,7 @@ public:
3838 // DO NOT EDIT what you see in these blocks of generated code !
3939 //}}AFX_MSG
4040 BOOL IsWow64();
41- BOOL SendIPCMessage(DWORD msg);
41+ void SendIPC64Message(DWORD msg);
4242 BOOL Start64bitProcess();
4343 DECLARE_MESSAGE_MAP()
4444 private:
--- a/xkeymacs/xkeymacs64.cpp
+++ b/xkeymacs/xkeymacs64.cpp
@@ -39,7 +39,7 @@ BOOL CXkeymacsApp::InitInstance()
3939
4040 UINT PollIPCMessage(LPVOID param)
4141 {
42- HANDLE hPipe = CreateNamedPipe(IPC_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1, 512, 512, 0, NULL);
42+ HANDLE hPipe = CreateNamedPipe(XKEYMACS64_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1, 512, 512, 0, NULL);
4343 if (hPipe == INVALID_HANDLE_VALUE)
4444 return 1;
4545 for (; ;) {
@@ -49,22 +49,28 @@ UINT PollIPCMessage(LPVOID param)
4949 DWORD read;
5050 if (!ReadFile(hPipe, &msg, sizeof(msg), &read, NULL) || read != sizeof(msg))
5151 break;
52- DWORD written, nul = 0;
53- if (!WriteFile(hPipe, &nul, sizeof(DWORD), &written, NULL) || written != sizeof(DWORD)
54- || !FlushFileBuffers(hPipe) || !DisconnectNamedPipe(hPipe))
55- break;
5652 switch (msg)
5753 {
58- case XKEYMACS_EXIT:
54+ case IPC64_EXIT:
5955 goto exit;
6056 break;
61- case XKEYMACS_RELOAD:
57+ case IPC64_RELOAD:
6258 CXkeymacsDll::LoadConfig();
6359 break;
64- case XKEYMACS_RESET:
60+ case IPC64_RESET:
6561 CXkeymacsDll::ResetHooks();
6662 break;
63+ case IPC64_DISABLE:
64+ CXkeymacsDll::SetHookStateDirect(false);
65+ break;
66+ case IPC64_ENABLE:
67+ CXkeymacsDll::SetHookStateDirect(true);
68+ break;
6769 }
70+ DWORD written, ack = 0;
71+ if (!WriteFile(hPipe, &ack, sizeof(DWORD), &written, NULL) || written != sizeof(DWORD)
72+ || !FlushFileBuffers(hPipe) || !DisconnectNamedPipe(hPipe))
73+ break;
6874 }
6975 exit:
7076 CloseHandle(hPipe);
--- a/xkeymacsdll/ipc.h
+++ b/xkeymacsdll/ipc.h
@@ -7,12 +7,6 @@
77
88 #include "defs.h"
99
10-struct IconMsg {
11- ICON_TYPE nType;
12- int nState;
13- TCHAR szTip[128];
14-};
15-
1610 struct AppConfig {
1711 TCHAR AppName[CLASS_NAME_LENGTH];
1812 TCHAR WindowText[WINDOW_TEXT_LENGTH];
@@ -33,8 +27,23 @@ struct Config {
3327 bool Is106Keyboard;
3428 };
3529
36-enum XKEYMACS_IPC { XKEYMACS_EXIT, XKEYMACS_RELOAD, XKEYMACS_RESET };
30+enum XKEYMACS_IPC32 { IPC32_TERMINATE, IPC32_ICON, IPC32_HOOKSTATE };
31+enum XKEYMACS_IPC64 { IPC64_EXIT, IPC64_RELOAD, IPC64_RESET, IPC64_DISABLE, IPC64_ENABLE };
32+
33+struct IconState {
34+ ICON_TYPE Type;
35+ int State;
36+ TCHAR Tip[128];
37+};
38+
39+struct IPC32Message {
40+ XKEYMACS_IPC32 Type;
41+ union {
42+ bool Enable;
43+ IconState IconState[MAX_ICON_TYPE];
44+ };
45+};
3746
38-#define ICON_PIPE _T("\\\\.\\pipe\\XKEYMACS_ICON")
39-#define IPC_PIPE _T("\\\\.\\pipe\\XKEYMACS_IPC")
47+#define XKEYMACS32_PIPE _T("\\\\.\\pipe\\XKEYMACS_IPC32")
48+#define XKEYMACS64_PIPE _T("\\\\.\\pipe\\XKEYMACS_IPC64")
4049 #endif
--- a/xkeymacsdll/xkeymacsdll.cpp
+++ b/xkeymacsdll/xkeymacsdll.cpp
@@ -206,6 +206,11 @@ void CXkeymacsDll::ReleaseKeyboardHook()
206206 unhook(*phHook);
207207 }
208208
209+void CXkeymacsDll::SetHookStateDirect(bool enable)
210+{
211+ m_bHook = enable;
212+}
213+
209214 void CXkeymacsDll::ToggleHookState()
210215 {
211216 SetHookState(!m_bHook);
@@ -213,7 +218,12 @@ void CXkeymacsDll::ToggleHookState()
213218
214219 void CXkeymacsDll::SetHookState(bool enable)
215220 {
216- m_bHook = enable;
221+ DWORD ack, read;
222+ IPC32Message msg;
223+ msg.Type = IPC32_HOOKSTATE;
224+ msg.Enable = enable;
225+ CallNamedPipe(XKEYMACS32_PIPE, &msg, offsetof(IPC32Message, Enable) + sizeof(bool), &ack, sizeof(DWORD), &read, NMPWAIT_NOWAIT);
226+
217227 ShowHookState();
218228 }
219229
@@ -224,25 +234,23 @@ bool CXkeymacsDll::GetHookState()
224234
225235 void CXkeymacsDll::ShowHookState()
226236 {
227- IconMsg msg = {MAIN_ICON,};
237+ IconState main = { MAIN_ICON, STATUS_ENABLE };
228238 if (m_bHook) {
229239 if (CCommands::IsTemporarilyDisableXKeymacs()) {
230- msg.nState = STATUS_DISABLE_TMP;
240+ main.State = STATUS_DISABLE_TMP;
231241 m_hCurrentCursor = m_hCursor[STATUS_DISABLE_TMP];
232242 } else {
233- msg.nState = STATUS_ENABLE;
243+ main.State = STATUS_ENABLE;
234244 m_hCurrentCursor = m_hCursor[STATUS_ENABLE];
235245 }
236- } else {
237- msg.nState = STATUS_DISABLE_WOCQ;
238- }
239- if (m_CurrentConfig->SettingStyle == SETTING_DISABLE
240- || (!_tcsicmp(m_CurrentConfig->AppName, _T("Default"))
241- && CUtils::IsDefaultIgnoreApplication())) {
242- msg.nState = STATUS_DISABLE;
246+ } else
247+ main.State = STATUS_DISABLE_WOCQ;
248+ if (m_CurrentConfig->SettingStyle == SETTING_DISABLE ||
249+ (!_tcsicmp(m_CurrentConfig->AppName, _T("Default")) && CUtils::IsDefaultIgnoreApplication())) {
250+ main.State = STATUS_DISABLE;
243251 m_hCurrentCursor = m_hCursor[STATUS_DISABLE];
244252 }
245- SendIconMessage(&msg, 1);
253+ SendIconMessage(&main, 1);
246254 DoSetCursor();
247255 }
248256
@@ -364,7 +372,7 @@ void CXkeymacsDll::InitKeyboardProc()
364372 m_CmdID = m_CurrentConfig->CmdID;
365373 m_FuncID = m_CurrentConfig->FuncID;
366374
367- IconMsg msg[3] = {
375+ IconState msg[3] = {
368376 {CX_ICON, OFF_ICON, ""},
369377 {MX_ICON, OFF_ICON, ""},
370378 {META_ICON, OFF_ICON, ""}
@@ -743,7 +751,7 @@ void CXkeymacsDll::InvokeM_x(LPCTSTR szPath)
743751
744752 void CXkeymacsDll::SetModifierIcons()
745753 {
746- IconMsg msg[6] = {
754+ IconState icons[6] = {
747755 {MX_ICON, CCommands::bM_x(), ""},
748756 {CX_ICON, CCommands::bC_x(), ""},
749757 {META_ICON, CCommands::bM_(), ""},
@@ -751,8 +759,8 @@ void CXkeymacsDll::SetModifierIcons()
751759 {CTRL_ICON, IsControl(), ""},
752760 {ALT_ICON, IsDown(VK_MENU, FALSE), ""}
753761 };
754- _tcscpy_s(msg[0].szTip, m_M_xTip);
755- SendIconMessage(msg, 6);
762+ _tcscpy_s(icons[0].Tip, m_M_xTip);
763+ SendIconMessage(icons, 6);
756764 }
757765
758766 void CXkeymacsDll::SetM_xTip(LPCTSTR szPath)
@@ -762,10 +770,13 @@ void CXkeymacsDll::SetM_xTip(LPCTSTR szPath)
762770 _stprintf_s(m_M_xTip, "M-x %s", szPath);
763771 }
764772
765-BOOL CXkeymacsDll::SendIconMessage(IconMsg *pMsg, DWORD num)
773+void CXkeymacsDll::SendIconMessage(IconState *state, int num)
766774 {
767775 DWORD ack, read;
768- return CallNamedPipe(ICON_PIPE, pMsg, sizeof(IconMsg) * num, &ack, sizeof(DWORD), &read, NMPWAIT_NOWAIT) && read == sizeof(DWORD);
776+ IPC32Message msg;
777+ msg.Type = IPC32_ICON;
778+ memcpy(msg.IconState, state, num * sizeof(IconState));
779+ CallNamedPipe(XKEYMACS32_PIPE, &msg, offsetof(IPC32Message, IconState) + sizeof(IconState) * num, &ack, sizeof(DWORD), &read, NMPWAIT_NOWAIT);
769780 }
770781
771782 void CXkeymacsDll::Kdu(BYTE bVk, DWORD n, BOOL bOriginal)
--- a/xkeymacsdll/xkeymacsdll.h
+++ b/xkeymacsdll/xkeymacsdll.h
@@ -28,11 +28,12 @@ public:
2828 static void ResetHooks();
2929 static void ReleaseHooks();
3030 static void ReleaseKeyboardHook();
31+ static void SetHookStateDirect(bool enable);
3132 static void ToggleHookState();
3233 static bool GetHookState();
3334 static void ShowHookState();
3435 static void SetM_xTip(LPCTSTR szPath);
35- static BOOL SendIconMessage(IconMsg *pMsg, DWORD num);
36+ static void SendIconMessage(IconState *state, int num);
3637 static BOOL IsDown(BYTE bVk, BOOL bPhysicalKey = TRUE);
3738 static void Kdu(BYTE bVk, DWORD n = 1, BOOL bOriginal = TRUE);
3839 static void DepressKey(BYTE bVk, BOOL bOriginal = TRUE);
旧リポジトリブラウザで表示