OSDN Git Service

92afe98933195b7ec1eb0f3937a168a2ee787703
[yamy/yamy.git] / engine.cpp
1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 // engine.cpp
3
4
5 #include "misc.h"
6
7 #include "engine.h"
8 #include "errormessage.h"
9 #include "hook.h"
10 #include "mayurc.h"
11 #include "windowstool.h"
12
13 #include <iomanip>
14
15 #include <process.h>
16
17
18 // check focus window
19 void Engine::checkFocusWindow()
20 {
21   int count = 0;
22   
23   restart:
24   count ++;
25   
26   HWND hwndFore = GetForegroundWindow();
27   DWORD threadId = GetWindowThreadProcessId(hwndFore, NULL);
28
29   if (hwndFore)
30   {
31     {
32       Acquire a(&m_cs);
33       if (m_currentFocusOfThread &&
34           m_currentFocusOfThread->m_threadId == threadId &&
35           m_currentFocusOfThread->m_hwndFocus == m_hwndFocus)
36         return;
37
38       m_emacsEditKillLine.reset();
39       
40       // erase dead thread
41       if (!m_detachedThreadIds.empty())
42       {
43         for (DetachedThreadIds::iterator i = m_detachedThreadIds.begin();
44              i != m_detachedThreadIds.end(); i ++)
45         {
46           FocusOfThreads::iterator j = m_focusOfThreads.find((*i));
47           if (j != m_focusOfThreads.end())
48           {
49             FocusOfThread *fot = &((*j).second);
50             Acquire a(&m_log, 1);
51             m_log << _T("RemoveThread") << std::endl;
52             m_log << _T("\tHWND:\t") << std::hex << (int)fot->m_hwndFocus
53                   << std::dec << std::endl;
54             m_log << _T("\tTHREADID:") << fot->m_threadId << std::endl;
55             m_log << _T("\tCLASS:\t") << fot->m_className << std::endl;
56             m_log << _T("\tTITLE:\t") << fot->m_titleName << std::endl;
57             m_log << std::endl;
58             m_focusOfThreads.erase(j);
59           }
60         }
61         m_detachedThreadIds.erase
62           (m_detachedThreadIds.begin(), m_detachedThreadIds.end());
63       }
64       
65       FocusOfThreads::iterator i = m_focusOfThreads.find(threadId);
66       if (i != m_focusOfThreads.end())
67       {
68         m_currentFocusOfThread = &((*i).second);
69         if (!m_currentFocusOfThread->m_isConsole || 2 <= count)
70         {
71           if (m_currentFocusOfThread->m_keymaps.empty())
72             setCurrentKeymap(NULL);
73           else
74             setCurrentKeymap(*m_currentFocusOfThread->m_keymaps.begin());
75           m_hwndFocus = m_currentFocusOfThread->m_hwndFocus;
76           checkShow(m_hwndFocus);
77         
78           Acquire a(&m_log, 1);
79           m_log << _T("FocusChanged") << std::endl;
80           m_log << _T("\tHWND:\t")
81                 << std::hex << (int)m_currentFocusOfThread->m_hwndFocus
82                 << std::dec << std::endl;
83           m_log << _T("\tTHREADID:")
84                 << m_currentFocusOfThread->m_threadId << std::endl;
85           m_log << _T("\tCLASS:\t")
86                 << m_currentFocusOfThread->m_className << std::endl;
87           m_log << _T("\tTITLE:\t")
88                 << m_currentFocusOfThread->m_titleName << std::endl;
89           m_log << std::endl;
90           return;
91         }
92       }
93     }
94     
95     _TCHAR className[GANA_MAX_ATOM_LENGTH];
96     if (GetClassName(hwndFore, className, NUMBER_OF(className)))
97     {
98       if (_tcsicmp(className, _T("ConsoleWindowClass")) == 0)
99       {
100         _TCHAR titleName[1024];
101         if (GetWindowText(hwndFore, titleName, NUMBER_OF(titleName)) == 0)
102           titleName[0] = _T('\0');
103         setFocus(hwndFore, threadId, className, titleName, true);
104         Acquire a(&m_log, 1);
105         m_log << _T("HWND:\t") << std::hex << reinterpret_cast<int>(hwndFore)
106               << std::dec << std::endl;
107         m_log << _T("THREADID:") << threadId << std::endl;
108         m_log << _T("CLASS:\t") << className << std::endl;
109         m_log << _T("TITLE:\t") << titleName << std::endl << std::endl;
110         goto restart;
111       }
112     }
113   }
114   
115   Acquire a(&m_cs);
116   if (m_globalFocus.m_keymaps.empty())
117   {
118     Acquire a(&m_log, 1);
119     m_log << _T("NO GLOBAL FOCUS") << std::endl;
120     m_currentFocusOfThread = NULL;
121     setCurrentKeymap(NULL);
122   }
123   else
124   {
125     if (m_currentFocusOfThread != &m_globalFocus)
126     {
127       Acquire a(&m_log, 1);
128       m_log << _T("GLOBAL FOCUS") << std::endl;
129       m_currentFocusOfThread = &m_globalFocus;
130       setCurrentKeymap(m_globalFocus.m_keymaps.front());
131     }
132   }
133   m_hwndFocus = NULL;
134 }
135
136
137
138 // is modifier pressed ?
139 bool Engine::isPressed(Modifier::Type i_mt)
140 {
141   const Keymap::ModAssignments &ma = m_currentKeymap->getModAssignments(i_mt);
142   for (Keymap::ModAssignments::const_iterator i = ma.begin();
143        i != ma.end(); ++ i)
144     if ((*i).m_key->m_isPressed)
145       return true;
146   return false;
147 }
148
149
150 // fix modifier key (if fixed, return true)
151 bool Engine::fixModifierKey(ModifiedKey *io_mkey, Keymap::AssignMode *o_am)
152 {
153   // for all modifier ...
154   for (int i = Modifier::Type_begin; i != Modifier::Type_end; ++ i)
155   {
156     // get modifier assignments (list of modifier keys)
157     const Keymap::ModAssignments &ma =
158       m_currentKeymap->getModAssignments(static_cast<Modifier::Type>(i));
159     
160     for (Keymap::ModAssignments::const_iterator
161            j = ma.begin(); j != ma.end(); ++ j)
162       if (io_mkey->m_key == (*j).m_key) // is io_mkey a modifier ?
163       {
164         {
165           Acquire a(&m_log, 1);
166           m_log << _T("* Modifier Key") << std::endl;
167         }
168         // set dontcare for this modifier
169         io_mkey->m_modifier.dontcare(static_cast<Modifier::Type>(i));
170         *o_am = (*j).m_assignMode;
171         return true;
172       }
173   }
174   *o_am = Keymap::AM_notModifier;
175   return false;
176 }
177
178
179 // output to m_log
180 void Engine::outputToLog(const Key *i_key, const ModifiedKey &i_mkey,
181                          int i_debugLevel)
182 {
183   size_t i;
184   Acquire a(&m_log, i_debugLevel);
185
186   // output scan codes
187   for (i = 0; i < i_key->getScanCodesSize(); ++ i)
188   {
189     if (i_key->getScanCodes()[i].m_flags & ScanCode::E0) m_log << _T("E0-");
190     if (i_key->getScanCodes()[i].m_flags & ScanCode::E1) m_log << _T("E1-");
191     if (!(i_key->getScanCodes()[i].m_flags & ScanCode::E0E1))
192       m_log << _T("   ");
193     m_log << _T("0x") << std::hex << std::setw(2) << std::setfill(_T('0'))
194           << static_cast<int>(i_key->getScanCodes()[i].m_scan)
195           << std::dec << _T(" ");
196   }
197   
198   if (!i_mkey.m_key) // key corresponds to no phisical key
199   {
200     m_log << std::endl;
201     return;
202   }
203   
204   m_log << _T("  ") << i_mkey << std::endl;
205 }
206
207
208 // describe bindings
209 void Engine::describeBindings()
210 {
211   Acquire a(&m_log, 0);
212
213   Keymap::DescribeParam dp;
214   for (KeymapPtrList::iterator i = m_currentFocusOfThread->m_keymaps.begin();
215        i != m_currentFocusOfThread->m_keymaps.end(); ++ i)
216     (*i)->describe(m_log, &dp);
217   m_log << std::endl;
218 }
219
220
221 // update m_lastPressedKey
222 void Engine::updateLastPressedKey(Key *i_key)
223 {
224   m_lastPressedKey[1] = m_lastPressedKey[0];
225   m_lastPressedKey[0] = i_key;
226 }
227
228 // set current keymap
229 void Engine::setCurrentKeymap(const Keymap *i_keymap, bool i_doesAddToHistory)
230 {
231   if (i_doesAddToHistory)
232   {
233     m_keymapPrefixHistory.push_back(const_cast<Keymap *>(m_currentKeymap));
234     if (MAX_KEYMAP_PREFIX_HISTORY < m_keymapPrefixHistory.size())
235       m_keymapPrefixHistory.pop_front();
236   }
237   else
238     m_keymapPrefixHistory.clear();
239   m_currentKeymap = i_keymap;
240 }
241
242
243 // get current modifiers
244 Modifier Engine::getCurrentModifiers(Key *i_key, bool i_isPressed)
245 {
246   Modifier cmods;
247   cmods.add(m_currentLock);
248
249   cmods.press(Modifier::Type_Shift  , isPressed(Modifier::Type_Shift  ));
250   cmods.press(Modifier::Type_Alt    , isPressed(Modifier::Type_Alt    ));
251   cmods.press(Modifier::Type_Control, isPressed(Modifier::Type_Control));
252   cmods.press(Modifier::Type_Windows, isPressed(Modifier::Type_Windows));
253   cmods.press(Modifier::Type_Up     , !i_isPressed);
254   cmods.press(Modifier::Type_Down   , i_isPressed);
255
256   cmods.press(Modifier::Type_Repeat , false);
257   if (m_lastPressedKey[0] == i_key)
258   {
259     if (i_isPressed)
260       cmods.press(Modifier::Type_Repeat, true);
261     else
262       if (m_lastPressedKey[1] == i_key)
263         cmods.press(Modifier::Type_Repeat, true);
264   }
265
266   for (int i = Modifier::Type_Mod0; i <= Modifier::Type_Mod9; ++ i)
267     cmods.press(static_cast<Modifier::Type>(i),
268                 isPressed(static_cast<Modifier::Type>(i)));
269   
270   return cmods;
271 }
272
273
274 // generate keyboard event for a key
275 void Engine::generateKeyEvent(Key *i_key, bool i_doPress, bool i_isByAssign)
276 {
277   // check if key is event
278   bool isEvent = false;
279   for (Key **e = Event::events; *e; ++ e)
280     if (*e == i_key)
281     {
282       isEvent = true;
283       break;
284     }
285
286   bool isAlreadyReleased = false;
287     
288   if (!isEvent)
289   {
290     if (i_doPress && !i_key->m_isPressedOnWin32)
291       ++ m_currentKeyPressCountOnWin32;
292     else if (!i_doPress)
293     {
294       if (i_key->m_isPressedOnWin32)
295         -- m_currentKeyPressCountOnWin32;
296       else
297         isAlreadyReleased = true;
298     }
299     i_key->m_isPressedOnWin32 = i_doPress;
300     
301     if (i_isByAssign)
302       i_key->m_isPressedByAssign = i_doPress;
303
304     Key *sync = m_setting->m_keyboard.getSyncKey();
305     
306     if (!isAlreadyReleased || i_key == sync)
307     {
308       KEYBOARD_INPUT_DATA kid = { 0, 0, 0, 0, 0 };
309       const ScanCode *sc = i_key->getScanCodes();
310       for (size_t i = 0; i < i_key->getScanCodesSize(); ++ i)
311       {
312         kid.MakeCode = sc[i].m_scan;
313         kid.Flags = sc[i].m_flags;
314         if (!i_doPress)
315           kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;
316 #if defined(_WINNT)
317 #ifdef NO_DRIVER
318         injectInput(&kid, NULL);
319 #else // !NO_DRIVER
320         DWORD len;
321         WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol);
322         CHECK_TRUE( GetOverlappedResult(m_device, &m_ol, &len, TRUE) );
323 #endif // !NO_DRIVER
324 #elif defined(_WIN95)
325         DeviceIoControl(m_device, 2, &kid, sizeof(kid), NULL, 0, &len, NULL);
326 #else
327 #  error
328 #endif
329       }
330       
331       m_lastGeneratedKey = i_doPress ? i_key : NULL;
332     }
333   }
334   
335   {
336     Acquire a(&m_log, 1);
337     m_log << _T("\t\t    =>\t");
338     if (isAlreadyReleased)
339       m_log << _T("(already released) ");
340   }
341   ModifiedKey mkey(i_key);
342   mkey.m_modifier.on(Modifier::Type_Up, !i_doPress);
343   mkey.m_modifier.on(Modifier::Type_Down, i_doPress);
344   outputToLog(i_key, mkey, 1);
345 }
346
347
348 // genete event
349 void Engine::generateEvents(Current i_c, const Keymap *i_keymap, Key *i_event)
350 {
351   // generate
352   i_c.m_keymap = i_keymap;
353   i_c.m_mkey.m_key = i_event;
354   if (const Keymap::KeyAssignment *keyAssign =
355       i_c.m_keymap->searchAssignment(i_c.m_mkey))
356   {
357     {
358       Acquire a(&m_log, 1);
359       m_log << std::endl << _T("           ")
360             << i_event->getName() << std::endl;
361     }
362     generateKeySeqEvents(i_c, keyAssign->m_keySeq, Part_all);
363   }
364 }
365
366
367 // genete modifier events
368 void Engine::generateModifierEvents(const Modifier &i_mod)
369 {
370   {
371     Acquire a(&m_log, 1);
372     m_log << _T("* Gen Modifiers\t{") << std::endl;
373   }
374
375   for (int i = Modifier::Type_begin; i < Modifier::Type_BASIC; ++ i)
376   {
377     Keyboard::Mods &mods =
378       m_setting->m_keyboard.getModifiers(static_cast<Modifier::Type>(i));
379
380     if (i_mod.isDontcare(static_cast<Modifier::Type>(i)))
381       // no need to process
382       ;
383     else if (i_mod.isPressed(static_cast<Modifier::Type>(i)))
384       // we have to press this modifier
385     {
386       bool noneIsPressed = true;
387       bool noneIsPressedByAssign = true;
388       for (Keyboard::Mods::iterator i = mods.begin(); i != mods.end(); ++ i)
389       {
390         if ((*i)->m_isPressedOnWin32)
391           noneIsPressed = false;
392         if ((*i)->m_isPressedByAssign)
393           noneIsPressedByAssign = false;
394       }
395       if (noneIsPressed)
396       {
397         if (noneIsPressedByAssign)
398           generateKeyEvent(mods.front(), true, false);
399         else
400           for (Keyboard::Mods::iterator
401                  i = mods.begin(); i != mods.end(); ++ i)
402             if ((*i)->m_isPressedByAssign)
403               generateKeyEvent((*i), true, false);
404       }
405     }
406
407     else
408       // we have to release this modifier
409     {
410       // avoid such sequences as  "Alt U-ALt" or "Windows U-Windows"
411       if (i == Modifier::Type_Alt || i == Modifier::Type_Windows)
412       {
413         for (Keyboard::Mods::iterator j = mods.begin(); j != mods.end(); ++ j)
414           if ((*j) == m_lastGeneratedKey)
415           {
416             Keyboard::Mods *mods =
417               &m_setting->m_keyboard.getModifiers(Modifier::Type_Shift);
418             if (mods->size() == 0)
419               mods = &m_setting->m_keyboard.getModifiers(
420                 Modifier::Type_Control);
421             if (0 < mods->size())
422             {
423               generateKeyEvent(mods->front(), true, false);
424               generateKeyEvent(mods->front(), false, false);
425             }
426             break;
427           }
428       }
429       
430       for (Keyboard::Mods::iterator j = mods.begin(); j != mods.end(); ++ j)
431       {
432         if ((*j)->m_isPressedOnWin32)
433           generateKeyEvent((*j), false, false);
434       }
435     }
436   }
437   
438   {
439     Acquire a(&m_log, 1);
440     m_log << _T("\t\t}") << std::endl;
441   }
442 }
443
444
445 // generate keyboard events for action
446 void Engine::generateActionEvents(const Current &i_c, const Action *i_a,
447                                   bool i_doPress)
448 {
449   switch (i_a->getType())
450   {
451     // key
452     case Action::Type_key:
453     {
454       const ModifiedKey &mkey
455         = reinterpret_cast<ActionKey *>(
456           const_cast<Action *>(i_a))->m_modifiedKey;
457
458       // release
459       if (!i_doPress &&
460           (mkey.m_modifier.isOn(Modifier::Type_Up) ||
461            mkey.m_modifier.isDontcare(Modifier::Type_Up)))
462         generateKeyEvent(mkey.m_key, false, true);
463
464       // press
465       else if (i_doPress &&
466                (mkey.m_modifier.isOn(Modifier::Type_Down) ||
467                 mkey.m_modifier.isDontcare(Modifier::Type_Down)))
468       {
469         Modifier modifier = mkey.m_modifier;
470         modifier.add(i_c.m_mkey.m_modifier);
471         generateModifierEvents(modifier);
472         generateKeyEvent(mkey.m_key, true, true);
473       }
474       break;
475     }
476
477     // keyseq
478     case Action::Type_keySeq:
479     {
480       const ActionKeySeq *aks = reinterpret_cast<const ActionKeySeq *>(i_a);
481       generateKeySeqEvents(i_c, aks->m_keySeq,
482                            i_doPress ? Part_down : Part_up);
483       break;
484     }
485
486     // function
487     case Action::Type_function:
488     {
489       const ActionFunction *af = reinterpret_cast<const ActionFunction *>(i_a);
490       bool is_up = (!i_doPress &&
491                     (af->m_modifier.isOn(Modifier::Type_Up) ||
492                      af->m_modifier.isDontcare(Modifier::Type_Up)));
493       bool is_down = (i_doPress &&
494                       (af->m_modifier.isOn(Modifier::Type_Down) ||
495                        af->m_modifier.isDontcare(Modifier::Type_Down)));
496
497       if (!is_down && !is_up)
498         break;
499       
500       {
501         Acquire a(&m_log, 1);
502         m_log << _T("\t\t     >\t") << af->m_functionData;
503       }
504       
505       FunctionParam param;
506       param.m_isPressed = i_doPress;
507       param.m_hwnd = m_currentFocusOfThread->m_hwndFocus;
508       param.m_c = i_c;
509       param.m_doesNeedEndl = true;
510       param.m_af = af;
511       
512       param.m_c.m_mkey.m_modifier.on(Modifier::Type_Up, !i_doPress);
513       param.m_c.m_mkey.m_modifier.on(Modifier::Type_Down, i_doPress);
514
515       af->m_functionData->exec(this, &param);
516       
517       if (param.m_doesNeedEndl)
518       {
519         Acquire a(&m_log, 1);
520         m_log << std::endl;
521       }
522       break;
523     }
524   }
525 }
526
527
528 // generate keyboard events for keySeq
529 void Engine::generateKeySeqEvents(const Current &i_c, const KeySeq *i_keySeq,
530                                   Part i_part)
531 {
532   const KeySeq::Actions &actions = i_keySeq->getActions();
533   if (actions.empty())
534     return;
535   if (i_part == Part_up)
536     generateActionEvents(i_c, actions[actions.size() - 1], false);
537   else
538   {
539     size_t i;
540     for (i = 0 ; i < actions.size() - 1; ++ i)
541     {
542       generateActionEvents(i_c, actions[i], true);
543       generateActionEvents(i_c, actions[i], false);
544     }
545     generateActionEvents(i_c, actions[i], true);
546     if (i_part == Part_all)
547       generateActionEvents(i_c, actions[i], false);
548   }
549 }
550
551
552 // generate keyboard events for current key
553 void Engine::generateKeyboardEvents(const Current &i_c)
554 {
555   if (++ m_generateKeyboardEventsRecursionGuard ==
556       MAX_GENERATE_KEYBOARD_EVENTS_RECURSION_COUNT)
557   {
558     Acquire a(&m_log);
559     m_log << _T("error: too deep keymap recursion.  there may be a loop.")
560           << std::endl;
561     return;
562   }
563
564   const Keymap::KeyAssignment *keyAssign
565     = i_c.m_keymap->searchAssignment(i_c.m_mkey);
566   if (!keyAssign)
567   {
568     const KeySeq *keySeq = i_c.m_keymap->getDefaultKeySeq();
569     ASSERT( keySeq );
570     generateKeySeqEvents(i_c, keySeq, i_c.isPressed() ? Part_down : Part_up);
571   }
572   else
573   {
574     if (keyAssign->m_modifiedKey.m_modifier.isOn(Modifier::Type_Up) ||
575         keyAssign->m_modifiedKey.m_modifier.isOn(Modifier::Type_Down))
576       generateKeySeqEvents(i_c, keyAssign->m_keySeq, Part_all);
577     else
578       generateKeySeqEvents(i_c, keyAssign->m_keySeq,
579                            i_c.isPressed() ? Part_down : Part_up);
580   }
581   m_generateKeyboardEventsRecursionGuard --;
582 }
583
584
585 // generate keyboard events for current key
586 void Engine::beginGeneratingKeyboardEvents(
587   const Current &i_c, bool i_isModifier)
588 {
589   //             (1)             (2)             (3)  (4)   (1)
590   // up/down:    D-              U-              D-   U-    D-
591   // keymap:     m_currentKeymap m_currentKeymap X    X     m_currentKeymap
592   // memo:       &Prefix(X)      ...             ...  ...   ...
593   // m_isPrefix: false           true            true false false
594
595   Current cnew(i_c);
596
597   bool isPhysicallyPressed
598     = cnew.m_mkey.m_modifier.isPressed(Modifier::Type_Down);
599   
600   // substitute
601   ModifiedKey mkey = m_setting->m_keyboard.searchSubstitute(cnew.m_mkey);
602   if (mkey.m_key)
603   {
604     cnew.m_mkey = mkey;
605     if (isPhysicallyPressed)
606     {
607       cnew.m_mkey.m_modifier.off(Modifier::Type_Up);
608       cnew.m_mkey.m_modifier.on(Modifier::Type_Down);
609     }
610     else
611     {
612       cnew.m_mkey.m_modifier.on(Modifier::Type_Up);
613       cnew.m_mkey.m_modifier.off(Modifier::Type_Down);
614     }
615     for (int i = Modifier::Type_begin; i != Modifier::Type_end; ++ i)
616     {
617       Modifier::Type type = static_cast<Modifier::Type>(i);
618       if (cnew.m_mkey.m_modifier.isDontcare(type) &&
619           !i_c.m_mkey.m_modifier.isDontcare(type))
620         cnew.m_mkey.m_modifier.press(
621           type, i_c.m_mkey.m_modifier.isPressed(type));
622     }
623     
624     {
625       Acquire a(&m_log, 1);
626       m_log << _T("* substitute") << std::endl;
627     }
628     outputToLog(mkey.m_key, cnew.m_mkey, 1);
629   }
630   
631   // for prefix key
632   const Keymap *tmpKeymap = m_currentKeymap;
633   if (i_isModifier || !m_isPrefix) ; 
634   else if (isPhysicallyPressed)                 // when (3)
635     m_isPrefix = false;
636   else if (!isPhysicallyPressed)                // when (2)
637     m_currentKeymap = m_currentFocusOfThread->m_keymaps.front();
638   
639   // for m_emacsEditKillLine function
640   m_emacsEditKillLine.m_doForceReset = !i_isModifier;
641
642   // generate key event !
643   m_generateKeyboardEventsRecursionGuard = 0;
644   if (isPhysicallyPressed)
645     generateEvents(cnew, cnew.m_keymap, &Event::before_key_down);
646   generateKeyboardEvents(cnew);
647   if (!isPhysicallyPressed)
648     generateEvents(cnew, cnew.m_keymap, &Event::after_key_up);
649       
650   // for m_emacsEditKillLine function
651   if (m_emacsEditKillLine.m_doForceReset)
652     m_emacsEditKillLine.reset();
653
654   // for prefix key
655   if (i_isModifier)
656     ;
657   else if (!m_isPrefix)                         // when (1), (4)
658     m_currentKeymap = m_currentFocusOfThread->m_keymaps.front();
659   else if (!isPhysicallyPressed)                // when (2)
660     m_currentKeymap = tmpKeymap;
661 }
662
663
664 #ifdef NO_DRIVER
665 unsigned int Engine::injectInput(const KEYBOARD_INPUT_DATA *i_kid, const KBDLLHOOKSTRUCT *i_kidRaw)
666 {
667   INPUT kid;
668   kid.type = INPUT_KEYBOARD;
669   kid.ki.wVk = 0;
670   kid.ki.wScan = i_kid->MakeCode;
671   kid.ki.dwFlags = KEYEVENTF_SCANCODE;
672   kid.ki.time = i_kidRaw ? i_kidRaw->time : 0;
673   kid.ki.dwExtraInfo = i_kidRaw ? i_kidRaw->dwExtraInfo : 0;
674   if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK)
675   {
676     kid.ki.dwFlags |= KEYEVENTF_KEYUP;
677   }
678   if (i_kid->Flags & KEYBOARD_INPUT_DATA::E0)
679   {
680     kid.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
681   }
682   SendInput(1, &kid, sizeof(kid));
683   return 1;
684 }
685 #endif // NO_DRIVER
686
687
688 // pop all pressed key on win32
689 void Engine::keyboardResetOnWin32()
690 {
691   for (Keyboard::KeyIterator
692          i = m_setting->m_keyboard.getKeyIterator();  *i; ++ i)
693   {
694     if ((*i)->m_isPressedOnWin32)
695       generateKeyEvent((*i), false, true);
696   }
697 }
698
699
700 #ifdef NO_DRIVER
701 unsigned int WINAPI Engine::keyboardDetour(Engine *i_this, KBDLLHOOKSTRUCT *i_kid)
702 {
703   return i_this->keyboardDetour(i_kid);
704 }
705
706 unsigned int Engine::keyboardDetour(KBDLLHOOKSTRUCT *i_kid)
707 {
708 #if 0
709   Acquire a(&m_log, 1);
710   m_log << std::hex
711         << _T("keyboardDetour: vkCode=") << i_kid->vkCode
712         << _T(" scanCode=") << i_kid->scanCode
713         << _T(" flags=") << i_kid->flags << std::endl;
714 #endif
715   if (i_kid->flags & LLKHF_INJECTED)
716   {
717     return 0;
718   }
719   else
720   {
721     Key key;
722     KEYBOARD_INPUT_DATA kid;
723
724     kid.UnitId = 0;
725     kid.MakeCode = i_kid->scanCode;
726     kid.Flags = 0;
727     if (i_kid->flags & LLKHF_UP)
728     {
729       kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;
730     }
731     if (i_kid->flags & LLKHF_EXTENDED)
732     {
733           kid.Flags |= KEYBOARD_INPUT_DATA::E0;
734     }
735     kid.Reserved = 0;
736     kid.ExtraInformation = 0;
737
738     Acquire a(&m_cskidq);
739     m_kidq.push_back(kid);
740     SetEvent(m_readEvent);
741     return 1;
742   }
743 }
744 #endif // NO_DRIVER
745
746 // keyboard handler thread
747 unsigned int WINAPI Engine::keyboardHandler(void *i_this)
748 {
749   reinterpret_cast<Engine *>(i_this)->keyboardHandler();
750   _endthreadex(0);
751   return 0;
752 }
753 void Engine::keyboardHandler()
754 {
755   // initialize ok
756   CHECK_TRUE( SetEvent(m_threadEvent) );
757     
758   // loop
759   Key key;
760   while (!m_doForceTerminate)
761   {
762     KEYBOARD_INPUT_DATA kid;
763     
764 #ifndef NO_DRIVER
765     DWORD len;
766 #endif // !NO_DRIVER
767 #if defined(_WINNT)
768     {
769       Acquire a(&m_log, 1);
770       m_log << _T("begin ReadFile();") << std::endl;
771     }
772 #ifdef NO_DRIVER
773     if (1)
774     {
775 #else // !NO_DRIVER
776     if (!ReadFile(m_device, &kid, sizeof(kid), &len, &m_ol))
777     {
778       if (GetLastError() != ERROR_IO_PENDING)
779         continue;
780 #endif // !NO_DRIVER
781       
782       HANDLE handles[] = { m_readEvent, m_interruptThreadEvent };
783     rewait:
784       switch (MsgWaitForMultipleObjects(NUMBER_OF(handles), &handles[0],
785                                      FALSE, INFINITE, QS_POSTMESSAGE))
786       {
787         case WAIT_OBJECT_0:                     // m_readEvent
788 #ifdef NO_DRIVER
789         {
790           Acquire a(&m_cskidq);
791           if (m_kidq.empty())
792           {
793             goto rewait;
794           }
795           kid = m_kidq.front();
796           m_kidq.pop_front();
797           if (!m_kidq.empty())
798           {
799             SetEvent(m_readEvent);
800           }
801         }
802 #else // !NO_DRIVER
803           if (!GetOverlappedResult(m_device, &m_ol, &len, FALSE))
804             continue;
805 #endif // !NO_DRIVER
806           break;
807           
808         case WAIT_OBJECT_0 + 1:                 // m_interruptThreadEvent
809           CancelIo(m_device);
810           switch (m_interruptThreadReason) {
811             default: {
812               ASSERT( false );
813               Acquire a(&m_log, 0);
814               m_log << _T("internal error: m_interruptThreadReason == ")
815                     << m_interruptThreadReason << std::endl;
816               break;
817             }
818               
819             case InterruptThreadReason_Terminate:
820               goto break_while;
821               
822             case InterruptThreadReason_Pause: {
823               CHECK_TRUE( SetEvent(m_threadEvent) );
824               while (WaitForMultipleObjects(1, &m_interruptThreadEvent,
825                                             FALSE, INFINITE) != WAIT_OBJECT_0)
826                 ;
827               switch (m_interruptThreadReason) {
828                 case InterruptThreadReason_Terminate:
829                   goto break_while;
830
831                 case InterruptThreadReason_Resume:
832                   break;
833
834                 default:
835                   ASSERT( false );
836                   break;
837               }
838               CHECK_TRUE( SetEvent(m_threadEvent) );
839               break;
840             }
841           }
842           break;
843           
844         case WAIT_OBJECT_0 + NUMBER_OF(handles):
845         {
846           MSG message;
847
848           while (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
849           {
850             switch (message.message)
851             {
852               case WM_APP + 201:
853               {
854                 if (message.wParam)
855                 {
856                   m_currentLock.on(Modifier::Type_Touchpad);
857                   m_currentLock.on(Modifier::Type_TouchpadSticky);
858                 }
859                 else
860                   m_currentLock.off(Modifier::Type_Touchpad);
861                 Acquire a(&m_log, 1);
862                 m_log << _T("touchpad: ") << message.wParam
863                       << _T(".") << (message.lParam & 0xffff)
864                       << _T(".") << (message.lParam >> 16 & 0xffff)
865                       << std::endl;
866                 break;
867               }
868               default:
869                 break;
870             }
871           }
872           goto rewait;
873         }
874
875         default:
876           ASSERT( false );
877           continue;
878       }
879     }
880     {
881       Acquire a(&m_log, 1);
882       m_log << _T("end ReadFile();") << std::endl;
883     }
884 #elif defined(_WIN95)
885     if (!DeviceIoControl(m_device, 1, NULL, 0, &kid, sizeof(kid), &len, NULL))
886     {
887       continue; // TODO
888     }
889 #else
890 #  error
891 #endif
892
893     checkFocusWindow();
894
895     if (!m_setting ||   // m_setting has not been loaded
896         !m_isEnabled)   // disabled
897     {
898       if (m_isLogMode)
899       {
900         Key key;
901         key.addScanCode(ScanCode(kid.MakeCode, kid.Flags));
902         outputToLog(&key, ModifiedKey(), 0);
903       }
904       else
905       {
906 #if defined(_WINNT)
907 #ifdef NO_DRIVER
908         injectInput(&kid, NULL);
909 #else // !NO_DRIVER
910         WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol);
911         GetOverlappedResult(m_device, &m_ol, &len, TRUE);
912 #endif // !NO_DRIVER
913 #elif defined(_WIN95)
914         DeviceIoControl(m_device, 2, &kid, sizeof(kid), NULL, 0, &len, NULL);
915 #else
916 #  error
917 #endif
918       }
919       updateLastPressedKey(NULL);
920       continue;
921     }
922     
923     Acquire a(&m_cs);
924
925     if (!m_currentFocusOfThread ||
926         !m_currentKeymap)
927     {
928 #if defined(_WINNT)
929 #ifndef NO_DRIVER
930       WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol);
931       GetOverlappedResult(m_device, &m_ol, &len, TRUE);
932 #endif // !NO_DRIVER
933 #elif defined(_WIN95)
934       DeviceIoControl(m_device, 2, &kid, sizeof(kid), NULL, 0, &len, NULL);
935 #else
936 #  error
937 #endif
938       Acquire a(&m_log, 0);
939       if (!m_currentFocusOfThread)
940         m_log << _T("internal error: m_currentFocusOfThread == NULL")
941               << std::endl;
942       if (!m_currentKeymap)
943         m_log << _T("internal error: m_currentKeymap == NULL")
944               << std::endl;
945       updateLastPressedKey(NULL);
946       continue;
947     }
948     
949     Current c;
950     c.m_keymap = m_currentKeymap;
951     c.m_i = m_currentFocusOfThread->m_keymaps.begin();
952     
953     // search key
954     key.addScanCode(ScanCode(kid.MakeCode, kid.Flags));
955     c.m_mkey = m_setting->m_keyboard.searchKey(key);
956     if (!c.m_mkey.m_key)
957     {
958       c.m_mkey.m_key = m_setting->m_keyboard.searchPrefixKey(key);
959       if (c.m_mkey.m_key)
960         continue;
961     }
962
963     // press the key and update counter
964     bool isPhysicallyPressed
965       = !(key.getScanCodes()[0].m_flags & ScanCode::BREAK);
966     if (c.m_mkey.m_key)
967     {
968       if (!c.m_mkey.m_key->m_isPressed && isPhysicallyPressed)
969         ++ m_currentKeyPressCount;
970       else if (c.m_mkey.m_key->m_isPressed && !isPhysicallyPressed)
971         -- m_currentKeyPressCount;
972       c.m_mkey.m_key->m_isPressed = isPhysicallyPressed;
973     }
974     
975     // create modifiers
976     c.m_mkey.m_modifier = getCurrentModifiers(c.m_mkey.m_key,
977                                               isPhysicallyPressed);
978     Keymap::AssignMode am;
979     bool isModifier = fixModifierKey(&c.m_mkey, &am);
980     if (m_isPrefix)
981     {
982       if (isModifier && m_doesIgnoreModifierForPrefix)
983         am = Keymap::AM_true;
984       if (m_doesEditNextModifier)
985       {
986         Modifier modifier = m_modifierForNextKey;
987         modifier.add(c.m_mkey.m_modifier);
988         c.m_mkey.m_modifier = modifier;
989       }
990     }
991     
992     if (m_isLogMode)
993       outputToLog(&key, c.m_mkey, 0);
994     else if (am == Keymap::AM_true)
995     {
996       {
997         Acquire a(&m_log, 1);
998         m_log << _T("* true modifier") << std::endl;
999       }
1000       // true modifier doesn't generate scan code
1001       outputToLog(&key, c.m_mkey, 1);
1002     }
1003     else if (am == Keymap::AM_oneShot || am == Keymap::AM_oneShotRepeatable)
1004     {
1005       {
1006         Acquire a(&m_log, 1);
1007         if (am == Keymap::AM_oneShot)
1008           m_log << _T("* one shot modifier") << std::endl;
1009         else
1010           m_log << _T("* one shot repeatable modifier") << std::endl;
1011       }
1012       // oneShot modifier doesn't generate scan code
1013       outputToLog(&key, c.m_mkey, 1);
1014       if (isPhysicallyPressed)
1015       {
1016         if (am == Keymap::AM_oneShotRepeatable  // the key is repeating
1017             && m_oneShotKey.m_key == c.m_mkey.m_key)
1018         {
1019           if (m_oneShotRepeatableRepeatCount <
1020               m_setting->m_oneShotRepeatableDelay) {
1021             ; // delay
1022           } else {
1023             Current cnew = c;
1024             beginGeneratingKeyboardEvents(cnew, false);
1025           }
1026           ++ m_oneShotRepeatableRepeatCount;
1027         } else {
1028           m_oneShotKey = c.m_mkey;
1029           m_oneShotRepeatableRepeatCount = 0;
1030         }
1031       }
1032       else
1033       {
1034         if (m_oneShotKey.m_key)
1035         {
1036           Current cnew = c;
1037           cnew.m_mkey.m_modifier = m_oneShotKey.m_modifier;
1038           cnew.m_mkey.m_modifier.off(Modifier::Type_Up);
1039           cnew.m_mkey.m_modifier.on(Modifier::Type_Down);
1040           beginGeneratingKeyboardEvents(cnew, false);
1041           
1042           cnew = c;
1043           cnew.m_mkey.m_modifier = m_oneShotKey.m_modifier;
1044           cnew.m_mkey.m_modifier.on(Modifier::Type_Up);
1045           cnew.m_mkey.m_modifier.off(Modifier::Type_Down);
1046           beginGeneratingKeyboardEvents(cnew, false);
1047         }
1048         m_oneShotKey.m_key = NULL;
1049         m_oneShotRepeatableRepeatCount = 0;
1050       }
1051     }
1052     else if (c.m_mkey.m_key)
1053       // normal key
1054     {
1055       outputToLog(&key, c.m_mkey, 1);
1056       if (isPhysicallyPressed)
1057         m_oneShotKey.m_key = NULL;
1058       beginGeneratingKeyboardEvents(c, isModifier);
1059     }
1060     
1061     // if counter is zero, reset modifiers and keys on win32
1062     if (m_currentKeyPressCount <= 0)
1063     {
1064       {
1065         Acquire a(&m_log, 1);
1066         m_log << _T("* No key is pressed") << std::endl;
1067       }
1068       generateModifierEvents(Modifier());
1069       if (0 < m_currentKeyPressCountOnWin32)
1070         keyboardResetOnWin32();
1071       m_currentKeyPressCount = 0;
1072       m_currentKeyPressCountOnWin32 = 0;
1073       m_oneShotKey.m_key = NULL;
1074       if (m_currentLock.isOn(Modifier::Type_Touchpad) == false)
1075         m_currentLock.off(Modifier::Type_TouchpadSticky);
1076     }
1077     
1078     key.initialize();
1079     updateLastPressedKey(isPhysicallyPressed ? c.m_mkey.m_key : NULL);
1080   }
1081 #if defined(_WINNT)
1082   break_while:
1083 #endif
1084   CHECK_TRUE( SetEvent(m_threadEvent) );
1085 }
1086   
1087
1088 Engine::Engine(tomsgstream &i_log)
1089   : m_hwndAssocWindow(NULL),
1090     m_setting(NULL),
1091     m_device(INVALID_HANDLE_VALUE),
1092     m_didMayuStartDevice(false),
1093     m_threadEvent(NULL),
1094     m_mayudVersion(_T("unknown")),
1095 #if defined(_WINNT)
1096     m_readEvent(NULL),
1097     m_interruptThreadEvent(NULL),
1098     m_sts4mayu(NULL),
1099     m_cts4mayu(NULL),
1100 #endif // _WINNT
1101     m_doForceTerminate(false),
1102     m_isLogMode(false),
1103     m_isEnabled(true),
1104     m_isSynchronizing(false),
1105     m_eSync(NULL),
1106     m_generateKeyboardEventsRecursionGuard(0),
1107     m_currentKeyPressCount(0),
1108     m_currentKeyPressCountOnWin32(0),
1109     m_lastGeneratedKey(NULL),
1110     m_oneShotRepeatableRepeatCount(0),
1111     m_isPrefix(false),
1112     m_currentKeymap(NULL),
1113     m_currentFocusOfThread(NULL),
1114     m_hwndFocus(NULL),
1115     m_afShellExecute(NULL),
1116     m_variable(0),
1117     m_log(i_log)
1118 {
1119   for (size_t i = 0; i < NUMBER_OF(m_lastPressedKey); ++ i)
1120     m_lastPressedKey[i] = NULL;
1121     
1122   // set default lock state
1123   for (int i = 0; i < Modifier::Type_end; ++ i)
1124     m_currentLock.dontcare(static_cast<Modifier::Type>(i));
1125   for (int i = Modifier::Type_Lock0; i <= Modifier::Type_Lock9; ++ i)
1126     m_currentLock.release(static_cast<Modifier::Type>(i));
1127
1128 #ifndef NO_DRIVER
1129   if (!open()) {
1130       throw ErrorMessage() << loadString(IDS_driverNotInstalled);
1131   }
1132 #endif // !NO_DRIVER
1133   
1134 #ifndef NO_DRIVER
1135   {
1136     TCHAR versionBuf[256];
1137     DWORD length = 0;
1138
1139     if (DeviceIoControl(m_device, IOCTL_MAYU_GET_VERSION, NULL, 0,
1140                         versionBuf, sizeof(versionBuf), &length, NULL)
1141         && length
1142         && length < sizeof(versionBuf))                 // fail safe
1143         m_mayudVersion = tstring(versionBuf, length / 2);
1144   }
1145 #endif // !NO_DRIVER
1146   // create event for sync
1147   CHECK_TRUE( m_eSync = CreateEvent(NULL, FALSE, FALSE, NULL) );
1148 #if defined(_WINNT)
1149   // create named pipe for &SetImeString
1150   m_hookPipe = CreateNamedPipe(addSessionId(HOOK_PIPE_NAME).c_str(),
1151                                PIPE_ACCESS_OUTBOUND,
1152                                PIPE_TYPE_BYTE, 1,
1153                                0, 0, 0, NULL);
1154 #endif // _WINNT
1155   StrExprArg::setEngine(this);
1156 }
1157
1158
1159 // open mayu device
1160 bool Engine::open()
1161 {
1162   // open mayu m_device
1163 #if defined(_WINNT)
1164 #ifndef NO_DRIVER
1165   m_device = CreateFile(MAYU_DEVICE_FILE_NAME, GENERIC_READ | GENERIC_WRITE,
1166                         0, NULL, OPEN_EXISTING,
1167                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
1168 #endif // !NO_DRIVER
1169 #elif defined(_WIN95)
1170   m_device = CreateFile(MAYU_DEVICE_FILE_NAME, 0,
1171                         0, NULL, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
1172 #else
1173 #  error
1174 #endif
1175
1176   if (m_device != INVALID_HANDLE_VALUE) {
1177     return true;
1178   }
1179
1180 #if defined(_WINNT)
1181 #ifndef NO_DRIVER
1182   // start mayud
1183   SC_HANDLE hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
1184   if (hscm)
1185   {
1186     SC_HANDLE hs = OpenService(hscm, MAYU_DRIVER_NAME, SERVICE_START);
1187     if (hs)
1188     {
1189       StartService(hs, 0, NULL);
1190       CloseServiceHandle(hs);
1191       m_didMayuStartDevice = true;
1192     }
1193     CloseServiceHandle(hscm);
1194   }
1195   
1196   // open mayu m_device
1197   m_device = CreateFile(MAYU_DEVICE_FILE_NAME, GENERIC_READ | GENERIC_WRITE,
1198                         0, NULL, OPEN_EXISTING,
1199                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
1200 #endif // !NO_DRIVER
1201 #endif // _WINNT
1202   return (m_device != INVALID_HANDLE_VALUE);
1203 }
1204
1205
1206 // close mayu device
1207 void Engine::close()
1208 {
1209   if (m_device != INVALID_HANDLE_VALUE) {
1210 #ifndef NO_DRIVER
1211     CHECK_TRUE( CloseHandle(m_device) );
1212 #endif // !NO_DRIVER
1213   }
1214   m_device = INVALID_HANDLE_VALUE;
1215 }
1216
1217
1218 // start keyboard handler thread
1219 void Engine::start()
1220 {
1221   CHECK_TRUE( m_threadEvent = CreateEvent(NULL, FALSE, FALSE, NULL) );
1222   
1223 #if defined(_WINNT)
1224   CHECK_TRUE( m_readEvent = CreateEvent(NULL, FALSE, FALSE, NULL) );
1225   CHECK_TRUE( m_interruptThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL) );
1226   m_ol.Offset = 0;
1227   m_ol.OffsetHigh = 0;
1228   m_ol.hEvent = m_readEvent;
1229 #endif // _WINNT
1230   
1231   CHECK_TRUE( m_threadHandle = (HANDLE)_beginthreadex(NULL, 0, keyboardHandler, this, 0, &m_threadId) );
1232   CHECK( WAIT_OBJECT_0 ==, WaitForSingleObject(m_threadEvent, INFINITE) );
1233 }
1234
1235
1236 // stop keyboard handler thread
1237 void Engine::stop()
1238 {
1239   if (m_threadEvent)
1240   {
1241     m_doForceTerminate = true;
1242     do
1243     {
1244 #if defined(_WINNT)
1245       m_interruptThreadReason = InterruptThreadReason_Terminate;
1246       SetEvent(m_interruptThreadEvent);
1247 #elif defined(_WIN95)
1248       DeviceIoControl(m_device, 3, NULL, 0, NULL, 0, NULL, NULL);
1249 #endif
1250       //DWORD buf;
1251       //M_DeviceIoControl(m_device, IOCTL_MAYU_DETOUR_CANCEL,
1252       //                &buf, sizeof(buf), &buf, sizeof(buf), &buf, NULL);
1253       
1254       // wait for message handler thread terminate
1255     } while (WaitForSingleObject(m_threadEvent, 100) != WAIT_OBJECT_0);
1256     CHECK_TRUE( CloseHandle(m_threadEvent) );
1257     m_threadEvent = NULL;
1258     WaitForSingleObject(m_threadHandle, 100);
1259     CHECK_TRUE( CloseHandle(m_threadHandle) );
1260     m_threadHandle = NULL;
1261
1262 #if defined(_WINNT)
1263     // stop mayud
1264     if (m_didMayuStartDevice)
1265     {
1266       SC_HANDLE hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
1267       if (hscm)
1268       {
1269         SC_HANDLE hs = OpenService(hscm, MAYU_DRIVER_NAME, SERVICE_STOP);
1270         if (hs)
1271         {
1272           SERVICE_STATUS ss;
1273           ControlService(hs, SERVICE_CONTROL_STOP, &ss);
1274           CloseServiceHandle(hs);
1275         }
1276         CloseServiceHandle(hscm);
1277       }
1278     }
1279     
1280     CHECK_TRUE( CloseHandle(m_readEvent) );
1281     m_readEvent = NULL;
1282     CHECK_TRUE( CloseHandle(m_interruptThreadEvent) );
1283     m_interruptThreadEvent = NULL;
1284 #endif // _WINNT
1285   }
1286 }
1287
1288 bool Engine::pause()
1289 {
1290 #if defined(_WINNT)
1291   if (m_device != INVALID_HANDLE_VALUE) {
1292     do {
1293       m_interruptThreadReason = InterruptThreadReason_Pause;
1294       SetEvent(m_interruptThreadEvent);
1295     } while (WaitForSingleObject(m_threadEvent, 100) != WAIT_OBJECT_0);
1296 #ifndef NO_DRIVER
1297     close();
1298 #endif // !NO_DRIVER
1299   }
1300 #endif // _WINNT
1301   return true;
1302 }
1303
1304
1305 bool Engine::resume()
1306 {
1307 #if defined(_WINNT)
1308   if (m_device == INVALID_HANDLE_VALUE) {
1309 #ifndef NO_DRIVER
1310     if (!open()) {
1311       return false;                             // FIXME
1312     }
1313 #endif // !NO_DRIVER
1314     do {
1315       m_interruptThreadReason = InterruptThreadReason_Resume;
1316       SetEvent(m_interruptThreadEvent);
1317     } while (WaitForSingleObject(m_threadEvent, 100) != WAIT_OBJECT_0);
1318   }
1319 #endif // _WINNT
1320   return true;
1321 }
1322
1323
1324 bool Engine::prepairQuit()
1325 {
1326   // terminate and unload DLL for ThumbSense support if loaded
1327   manageTs4mayu(_T("sts4mayu.dll"), _T("SynCOM.dll"),
1328                 false, &m_sts4mayu);
1329   manageTs4mayu(_T("cts4mayu.dll"), _T("TouchPad.dll"),
1330                 false, &m_cts4mayu);
1331   return true;
1332 }
1333
1334
1335 Engine::~Engine()
1336 {
1337   stop();
1338   CHECK_TRUE( CloseHandle(m_eSync) );
1339   
1340   // close m_device
1341 #ifndef NO_DRIVER
1342   close();
1343 #endif // !NO_DRIVER
1344 #if defined(_WINNT)
1345   // destroy named pipe for &SetImeString
1346   if (m_hookPipe && m_hookPipe != INVALID_HANDLE_VALUE)
1347   {
1348     DisconnectNamedPipe(m_hookPipe);
1349     CHECK_TRUE( CloseHandle(m_hookPipe) );
1350   }
1351 #endif // _WINNT
1352 }
1353
1354
1355 void Engine::manageTs4mayu(TCHAR *i_ts4mayuDllName,
1356                            TCHAR *i_dependDllName,
1357                            bool i_load, HMODULE *i_pTs4mayu)
1358 {
1359   Acquire a(&m_log, 0);
1360
1361   if (i_load == false)
1362   {
1363     if (*i_pTs4mayu)
1364     {
1365       bool (WINAPI *pTs4mayuTerm)();
1366
1367       pTs4mayuTerm = (bool (WINAPI*)())GetProcAddress(*i_pTs4mayu, "ts4mayuTerm");
1368       if (pTs4mayuTerm() == true)
1369         FreeLibrary(*i_pTs4mayu);
1370       *i_pTs4mayu = NULL;
1371       m_log << i_ts4mayuDllName <<_T(" unloaded") << std::endl;
1372     }
1373   }
1374   else
1375   {
1376     if (*i_pTs4mayu)
1377     {
1378       m_log << i_ts4mayuDllName << _T(" already loaded") << std::endl;
1379     }
1380     else
1381     {
1382       if (SearchPath(NULL, i_dependDllName, NULL, 0, NULL, NULL) == 0)
1383       {
1384         m_log << _T("load ") << i_ts4mayuDllName
1385               << _T(" failed: can't find ") << i_dependDllName
1386               << std::endl;
1387       }
1388       else
1389       {
1390         *i_pTs4mayu = LoadLibrary(i_ts4mayuDllName);
1391         if (*i_pTs4mayu == NULL)
1392         {
1393           m_log << _T("load ") << i_ts4mayuDllName
1394                 << _T(" failed: can't find it") << std::endl;
1395         }
1396         else
1397         {
1398           bool (WINAPI *pTs4mayuInit)(UINT);    
1399
1400           pTs4mayuInit = (bool (WINAPI*)(UINT))GetProcAddress(*i_pTs4mayu, "ts4mayuInit");
1401           if (pTs4mayuInit(m_threadId) == true)
1402             m_log << i_ts4mayuDllName <<_T(" loaded") << std::endl;
1403           else
1404             m_log << i_ts4mayuDllName
1405                   <<_T(" load failed: can't initialize") << std::endl;
1406         }
1407       }
1408     }
1409   }
1410 }
1411
1412
1413 // set m_setting
1414 bool Engine::setSetting(Setting *i_setting)
1415 {
1416   Acquire a(&m_cs);
1417   if (m_isSynchronizing)
1418     return false;
1419
1420   if (m_setting)
1421   {
1422     for (Keyboard::KeyIterator i = m_setting->m_keyboard.getKeyIterator();
1423          *i; ++ i)
1424     {
1425       Key *key = i_setting->m_keyboard.searchKey(*(*i));
1426       if (key)
1427       {
1428         key->m_isPressed = (*i)->m_isPressed;
1429         key->m_isPressedOnWin32 = (*i)->m_isPressedOnWin32;
1430         key->m_isPressedByAssign = (*i)->m_isPressedByAssign;
1431       }
1432     }
1433     if (m_lastGeneratedKey)
1434       m_lastGeneratedKey =
1435         i_setting->m_keyboard.searchKey(*m_lastGeneratedKey);
1436     for (size_t i = 0; i < NUMBER_OF(m_lastPressedKey); ++ i)
1437       if (m_lastPressedKey[i])
1438         m_lastPressedKey[i] =
1439           i_setting->m_keyboard.searchKey(*m_lastPressedKey[i]);
1440   }
1441   
1442   m_setting = i_setting;
1443
1444   manageTs4mayu(_T("sts4mayu.dll"), _T("SynCOM.dll"),
1445                 m_setting->m_sts4mayu, &m_sts4mayu);
1446   manageTs4mayu(_T("cts4mayu.dll"), _T("TouchPad.dll"),
1447                 m_setting->m_cts4mayu, &m_cts4mayu);
1448
1449   g_hookData->m_correctKanaLockHandling = m_setting->m_correctKanaLockHandling;
1450   if (m_currentFocusOfThread)
1451   {
1452     for (FocusOfThreads::iterator i = m_focusOfThreads.begin();
1453          i != m_focusOfThreads.end(); i ++)
1454     {
1455       FocusOfThread *fot = &(*i).second;
1456       m_setting->m_keymaps.searchWindow(&fot->m_keymaps,
1457                                         fot->m_className, fot->m_titleName);
1458     }
1459   }
1460   m_setting->m_keymaps.searchWindow(&m_globalFocus.m_keymaps, _T(""), _T(""));
1461   if (m_globalFocus.m_keymaps.empty())
1462   {
1463     Acquire a(&m_log, 0);
1464     m_log << _T("internal error: m_globalFocus.m_keymap is empty")
1465           << std::endl;
1466   }
1467   m_currentFocusOfThread = &m_globalFocus;
1468   setCurrentKeymap(m_globalFocus.m_keymaps.front());
1469   m_hwndFocus = NULL;
1470   return true;
1471 }
1472
1473
1474 void Engine::checkShow(HWND i_hwnd)
1475 {
1476   // update show style of window
1477   // this update should be done in hook DLL, but to
1478   // avoid update-loss for some applications(such as
1479   // cmd.exe), we update here.
1480   bool isMaximized = false;
1481   bool isMinimized = false;
1482   bool isMDIMaximized = false;
1483   bool isMDIMinimized = false;
1484   while (i_hwnd)
1485   {
1486 #ifdef MAYU64
1487     LONG_PTR exStyle = GetWindowLongPtr(i_hwnd, GWL_EXSTYLE);
1488 #else
1489     LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);
1490 #endif
1491     if (exStyle & WS_EX_MDICHILD)
1492     {
1493       WINDOWPLACEMENT placement;
1494       placement.length = sizeof(WINDOWPLACEMENT);
1495       if (GetWindowPlacement(i_hwnd, &placement))
1496       {
1497          switch (placement.showCmd)
1498          {
1499            case SW_SHOWMAXIMIZED:
1500              isMDIMaximized = true;
1501              break;
1502            case SW_SHOWMINIMIZED:
1503              isMDIMinimized = true;
1504              break;
1505            case SW_SHOWNORMAL:
1506            default:
1507              break;
1508          }
1509       }
1510     }
1511
1512 #ifdef MAYU64
1513     LONG_PTR style = GetWindowLongPtr(i_hwnd, GWL_STYLE);
1514 #else
1515     LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
1516 #endif
1517     if ((style & WS_CHILD) == 0)
1518     {
1519       WINDOWPLACEMENT placement;
1520       placement.length = sizeof(WINDOWPLACEMENT);
1521       if (GetWindowPlacement(i_hwnd, &placement))
1522       {
1523          switch (placement.showCmd)
1524          {
1525            case SW_SHOWMAXIMIZED:
1526              isMaximized = true;
1527              break;
1528            case SW_SHOWMINIMIZED:
1529              isMinimized = true;
1530              break;
1531            case SW_SHOWNORMAL:
1532            default:
1533              break;
1534          }
1535       }
1536     }  
1537     i_hwnd = GetParent(i_hwnd);
1538   }
1539   setShow(isMDIMaximized, isMDIMinimized, true);
1540   setShow(isMaximized, isMinimized, false);
1541 }
1542
1543
1544 // focus
1545 bool Engine::setFocus(HWND i_hwndFocus, DWORD i_threadId, 
1546                       const tstringi &i_className, const tstringi &i_titleName,
1547                       bool i_isConsole)
1548 {
1549   Acquire a(&m_cs);
1550   if (m_isSynchronizing)
1551     return false;
1552   if (i_hwndFocus == NULL)
1553     return true;
1554
1555   // remove newly created thread's id from m_detachedThreadIds
1556   if (!m_detachedThreadIds.empty())
1557   {
1558     DetachedThreadIds::iterator i;
1559     bool retry;
1560     do
1561     {
1562       retry = false;
1563       for (i = m_detachedThreadIds.begin();
1564            i != m_detachedThreadIds.end(); ++ i)
1565         if (*i == i_threadId)
1566         {
1567           m_detachedThreadIds.erase(i);
1568           retry = true;
1569           break;
1570         }
1571     } while (retry);
1572   }
1573   
1574   FocusOfThread *fot;
1575   FocusOfThreads::iterator i = m_focusOfThreads.find(i_threadId);
1576   if (i != m_focusOfThreads.end())
1577   {
1578     fot = &(*i).second;
1579     if (fot->m_hwndFocus == i_hwndFocus &&
1580         fot->m_isConsole == i_isConsole &&
1581         fot->m_className == i_className &&
1582         fot->m_titleName == i_titleName)
1583       return true;
1584   }
1585   else
1586   {
1587     i = m_focusOfThreads.insert(
1588       FocusOfThreads::value_type(i_threadId, FocusOfThread())).first;
1589     fot = &(*i).second;
1590     fot->m_threadId = i_threadId;
1591   }
1592   fot->m_hwndFocus = i_hwndFocus;
1593   fot->m_isConsole = i_isConsole;
1594   fot->m_className = i_className;
1595   fot->m_titleName = i_titleName;
1596   
1597   if (m_setting)
1598   {
1599     m_setting->m_keymaps.searchWindow(&fot->m_keymaps,
1600                                       i_className, i_titleName);
1601     ASSERT(0 < fot->m_keymaps.size());
1602   }
1603   else
1604     fot->m_keymaps.clear();
1605   checkShow(i_hwndFocus);
1606   return true;
1607 }
1608
1609
1610 // lock state
1611 bool Engine::setLockState(bool i_isNumLockToggled,
1612                           bool i_isCapsLockToggled,
1613                           bool i_isScrollLockToggled,
1614                           bool i_isKanaLockToggled,
1615                           bool i_isImeLockToggled,
1616                           bool i_isImeCompToggled)
1617 {
1618   Acquire a(&m_cs);
1619   if (m_isSynchronizing)
1620     return false;
1621   m_currentLock.on(Modifier::Type_NumLock, i_isNumLockToggled);
1622   m_currentLock.on(Modifier::Type_CapsLock, i_isCapsLockToggled);
1623   m_currentLock.on(Modifier::Type_ScrollLock, i_isScrollLockToggled);
1624   m_currentLock.on(Modifier::Type_KanaLock, i_isKanaLockToggled);
1625   m_currentLock.on(Modifier::Type_ImeLock, i_isImeLockToggled);
1626   m_currentLock.on(Modifier::Type_ImeComp, i_isImeCompToggled);
1627   return true;
1628 }
1629
1630
1631 // show
1632 bool Engine::setShow(bool i_isMaximized, bool i_isMinimized,
1633                      bool i_isMDI)
1634 {
1635   Acquire a(&m_cs);
1636   if (m_isSynchronizing)
1637     return false;
1638   Acquire b(&m_log, 1);
1639   Modifier::Type max, min;
1640   if (i_isMDI == true) {
1641     max = Modifier::Type_MdiMaximized;
1642     min = Modifier::Type_MdiMinimized;
1643   }
1644   else
1645   {
1646     max = Modifier::Type_Maximized;
1647     min = Modifier::Type_Minimized;
1648   }
1649   m_currentLock.on(max, i_isMaximized);
1650   m_currentLock.on(min, i_isMinimized);
1651   m_log << _T("Set show to ") << (i_isMaximized ? _T("Maximized") :
1652                                   i_isMinimized ? _T("Minimized") : _T("Normal"));
1653   if (i_isMDI == true)
1654   {
1655     m_log << _T(" (MDI)");
1656   }
1657   m_log << std::endl;
1658   return true;
1659 }
1660
1661
1662 // sync
1663 bool Engine::syncNotify()
1664 {
1665   Acquire a(&m_cs);
1666   if (!m_isSynchronizing)
1667     return false;
1668   CHECK_TRUE( SetEvent(m_eSync) );
1669   return true;
1670 }
1671
1672
1673 // thread detach notify
1674 bool Engine::threadDetachNotify(DWORD i_threadId)
1675 {
1676   Acquire a(&m_cs);
1677   m_detachedThreadIds.push_back(i_threadId);
1678   return true;
1679 }
1680
1681
1682 // get help message
1683 void Engine::getHelpMessages(tstring *o_helpMessage, tstring *o_helpTitle)
1684 {
1685   Acquire a(&m_cs);
1686   *o_helpMessage = m_helpMessage;
1687   *o_helpTitle = m_helpTitle;
1688 }
1689
1690
1691 // command notify
1692 void Engine::commandNotify(
1693   HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam)
1694 {
1695   Acquire b(&m_log, 0);
1696   HWND hf = m_hwndFocus;
1697   if (!hf)
1698     return;
1699
1700   if (GetWindowThreadProcessId(hf, NULL) == 
1701       GetWindowThreadProcessId(m_hwndAssocWindow, NULL))
1702     return;     // inhibit the investigation of MADO TSUKAI NO YUUTSU
1703
1704   const _TCHAR *target = NULL;
1705   int number_target = 0;
1706   
1707   if (i_hwnd == hf)
1708     target = _T("ToItself");
1709   else if (i_hwnd == GetParent(hf))
1710     target = _T("ToParentWindow");
1711   else
1712   {
1713     // Function::toMainWindow
1714     HWND h = hf;
1715     while (true)
1716     {
1717       HWND p = GetParent(h);
1718       if (!p)
1719         break;
1720       h = p;
1721     }
1722     if (i_hwnd == h)
1723       target = _T("ToMainWindow");
1724     else
1725     {
1726       // Function::toOverlappedWindow
1727       HWND h = hf;
1728       while (h)
1729       {
1730 #ifdef MAYU64
1731         LONG_PTR style = GetWindowLongPtr(h, GWL_STYLE);
1732 #else
1733         LONG style = GetWindowLong(h, GWL_STYLE);
1734 #endif
1735         if ((style & WS_CHILD) == 0)
1736           break;
1737         h = GetParent(h);
1738       }
1739       if (i_hwnd == h)
1740         target = _T("ToOverlappedWindow");
1741       else
1742       {
1743         // number
1744         HWND h = hf;
1745         for (number_target = 0; h; number_target ++, h = GetParent(h))
1746           if (i_hwnd == h)
1747             break;
1748         return;
1749       }
1750     }
1751   }
1752
1753   m_log << _T("&PostMessage(");
1754   if (target)
1755     m_log << target;
1756   else
1757     m_log << number_target;
1758   m_log << _T(", ") << i_message
1759         << _T(", 0x") << std::hex << i_wParam
1760         << _T(", 0x") << i_lParam << _T(") # hwnd = ")
1761         << reinterpret_cast<int>(i_hwnd) << _T(", ")
1762         << _T("message = ") << std::dec;
1763   if (i_message == WM_COMMAND)
1764     m_log << _T("WM_COMMAND, ");
1765   else if (i_message == WM_SYSCOMMAND)
1766     m_log << _T("WM_SYSCOMMAND, ");
1767   else
1768     m_log << i_message << _T(", ");
1769   m_log << _T("wNotifyCode = ") << HIWORD(i_wParam) << _T(", ")
1770         << _T("wID = ") << LOWORD(i_wParam) << _T(", ")
1771         << _T("hwndCtrl = 0x") << std::hex << i_lParam << std::dec << std::endl;
1772 }