OSDN Git Service

fix invalid file permission
[yamy/yamy.git] / engine.h
1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 // engine.h
3
4
5 #ifndef _ENGINE_H
6 #  define _ENGINE_H
7
8 #  include "multithread.h"
9 #  include "setting.h"
10 #  include "msgstream.h"
11 #  include <set>
12 #  include <queue>
13
14
15 enum
16 {
17   ///
18   WM_APP_engineNotify = WM_APP + 110,
19 };
20
21
22 ///
23 enum EngineNotify
24 {
25   EngineNotify_shellExecute,                    ///
26   EngineNotify_loadSetting,                     ///
27   EngineNotify_showDlg,                         ///
28   EngineNotify_helpMessage,                     ///
29   EngineNotify_setForegroundWindow,             ///
30   EngineNotify_clearLog,                        ///
31 };
32
33
34 ///
35 class Engine
36 {
37 private:
38   enum
39   {
40     MAX_GENERATE_KEYBOARD_EVENTS_RECURSION_COUNT = 64, ///
41     MAX_KEYMAP_PREFIX_HISTORY = 64, ///
42   };
43
44   typedef Keymaps::KeymapPtrList KeymapPtrList; /// 
45   
46   /// focus of a thread
47   class FocusOfThread
48   {
49   public:
50     DWORD m_threadId;                           /// thread id
51     HWND m_hwndFocus;                           /** window that has focus on
52                                                     the thread */
53     tstringi m_className;                       /// class name of hwndFocus
54     tstringi m_titleName;                       /// title name of hwndFocus
55     bool m_isConsole;                           /// is hwndFocus console ?
56     KeymapPtrList m_keymaps;                    /// keymaps
57
58   public:
59     ///
60     FocusOfThread() : m_threadId(0), m_hwndFocus(NULL), m_isConsole(false) { }
61   };
62   typedef std::map<DWORD /*ThreadId*/, FocusOfThread> FocusOfThreads;   ///
63
64   typedef std::list<DWORD /*ThreadId*/> DetachedThreadIds;      ///
65
66   /// current status in generateKeyboardEvents
67   class Current
68   {
69   public:
70     const Keymap *m_keymap;                     /// current keymap
71     ModifiedKey m_mkey;         /// current processing key that user inputed
72                                 /// index in currentFocusOfThread-&gt;keymaps
73     Keymaps::KeymapPtrList::iterator m_i;
74
75   public:
76     ///
77     bool isPressed() const
78     { return m_mkey.m_modifier.isOn(Modifier::Type_Down); }
79   };
80
81   friend class FunctionParam;
82   
83   /// part of keySeq
84   enum Part
85   {
86     Part_all,                                   ///
87     Part_up,                                    ///
88     Part_down,                                  ///
89   };
90
91   ///
92   class EmacsEditKillLine
93   {
94     tstring m_buf;      /// previous kill-line contents
95
96   public:
97     bool m_doForceReset;        ///
98   
99   private:
100     ///
101     HGLOBAL makeNewKillLineBuf(const _TCHAR *i_data, int *i_retval);
102
103   public:
104     ///
105     void reset() { m_buf.resize(0); }
106     /** EmacsEditKillLineFunc.
107         clear the contents of the clopboard
108         at that time, confirm if it is the result of the previous kill-line
109     */
110     void func();
111     /// EmacsEditKillLinePred
112     int pred();
113   };
114
115   /// window positon for &amp;WindowHMaximize, &amp;WindowVMaximize
116   class WindowPosition
117   {
118   public:
119     ///
120     enum Mode
121     {
122       Mode_normal,                              ///
123       Mode_H,                                   ///
124       Mode_V,                                   ///
125       Mode_HV,                                  ///
126     };
127
128   public:
129     HWND m_hwnd;                                ///
130     RECT m_rc;                                  ///
131     Mode m_mode;                                ///
132
133   public:
134     ///
135     WindowPosition(HWND i_hwnd, const RECT &i_rc, Mode i_mode)
136       : m_hwnd(i_hwnd), m_rc(i_rc), m_mode(i_mode) { }
137   };
138   typedef std::list<WindowPosition> WindowPositions;
139
140   typedef std::list<HWND> WindowsWithAlpha; /// windows for &amp;WindowSetAlpha
141
142   enum InterruptThreadReason
143   {
144     InterruptThreadReason_Terminate,
145     InterruptThreadReason_Pause,
146     InterruptThreadReason_Resume,
147   };
148
149 private:
150   CriticalSection m_cs;                         /// criticalSection
151   
152   // setting
153   HWND m_hwndAssocWindow;                       /** associated window (we post
154                                                     message to it) */
155   Setting * volatile m_setting;                 /// setting
156   
157   // engine thread state
158   HANDLE m_device;                              /// mayu device
159   bool m_didMayuStartDevice;                    /** Did the mayu start the
160                                                     mayu-device ? */
161   HANDLE m_threadEvent;                         /** 1. thread has been started
162                                                     2. thread is about to end*/
163   HANDLE m_threadHandle;
164   unsigned m_threadId;
165   tstring m_mayudVersion;                       /// version of mayud.sys
166 #if defined(_WINNT)
167 #ifdef NO_DRIVER
168   std::deque<KEYBOARD_INPUT_DATA> m_kidq;
169   CriticalSection m_cskidq;
170 #endif // NO_DRIVER
171   HANDLE m_readEvent;                           /** reading from mayu device
172                                                     has been completed */
173   HANDLE m_interruptThreadEvent;                /// interrupt thread event
174   volatile InterruptThreadReason
175   m_interruptThreadReason;                      /// interrupt thread reason
176   OVERLAPPED m_ol;                              /** for async read/write of
177                                                     mayu device */
178   HANDLE m_hookPipe;                            /// named pipe for &SetImeString
179   HMODULE m_sts4mayu;                           /// DLL module for ThumbSense
180   HMODULE m_cts4mayu;                           /// DLL module for ThumbSense
181 #endif // _WINNT
182   bool volatile m_doForceTerminate;             /// terminate engine thread
183   bool volatile m_isLogMode;                    /// is logging mode ?
184   bool volatile m_isEnabled;                    /// is enabled  ?
185   bool volatile m_isSynchronizing;              /// is synchronizing ?
186   HANDLE m_eSync;                               /// event for synchronization
187   int m_generateKeyboardEventsRecursionGuard;   /** guard against too many
188                                                     recursion */
189   
190   // current key state
191   Modifier m_currentLock;                       /// current lock key's state
192   int m_currentKeyPressCount;                   /** how many keys are pressed
193                                                     phisically ? */
194   int m_currentKeyPressCountOnWin32;            /** how many keys are pressed
195                                                     on win32 ? */
196   Key *m_lastGeneratedKey;                      /// last generated key
197   Key *m_lastPressedKey[2];                     /// last pressed key
198   ModifiedKey m_oneShotKey;                     /// one shot key
199   unsigned int m_oneShotRepeatableRepeatCount; /// repeat count of one shot key
200   bool m_isPrefix;                              /// is prefix ?
201   bool m_doesIgnoreModifierForPrefix;           /** does ignore modifier key
202                                                     when prefixed ? */
203   bool m_doesEditNextModifier;                  /** does edit next user input
204                                                     key's modifier ? */
205   Modifier m_modifierForNextKey;                /** modifier for next key if
206                                                     above is true */
207
208   /** current keymaps.
209       <dl>
210       <dt>when &amp;OtherWindowClass
211       <dd>currentKeymap becoms currentKeymaps[++ Current::i]
212       <dt>when &amp;KeymapParent
213       <dd>currentKeymap becoms currentKeyamp-&gt;parentKeymap
214       <dt>other
215       <dd>currentKeyamp becoms *Current::i
216       </dl>
217   */
218   const Keymap * volatile m_currentKeymap;      /// current keymap
219   FocusOfThreads /*volatile*/ m_focusOfThreads; ///
220   FocusOfThread * volatile m_currentFocusOfThread; ///
221   FocusOfThread m_globalFocus;                  ///
222   HWND m_hwndFocus;                             /// current focus window
223   DetachedThreadIds m_detachedThreadIds;        ///
224   
225   // for functions
226   KeymapPtrList m_keymapPrefixHistory;          /// for &amp;KeymapPrevPrefix
227   EmacsEditKillLine m_emacsEditKillLine;        /// for &amp;EmacsEditKillLine
228   const ActionFunction *m_afShellExecute;       /// for &amp;ShellExecute
229   
230   WindowPositions m_windowPositions;            ///
231   WindowsWithAlpha m_windowsWithAlpha;          ///
232   
233   tstring m_helpMessage;                        /// for &amp;HelpMessage
234   tstring m_helpTitle;                          /// for &amp;HelpMessage
235   int m_variable;                               /// for &amp;Variable,
236                                                 ///  &amp;Repeat
237
238 public:
239   tomsgstream &m_log;                           /** log stream (output to log
240                                                     dialog's edit) */
241   
242 public:
243 #ifdef NO_DRIVER
244   /// keyboard handler thread
245   static unsigned int WINAPI keyboardDetour(Engine *i_this, KBDLLHOOKSTRUCT *i_kid);
246 private:
247   ///
248   unsigned int keyboardDetour(KBDLLHOOKSTRUCT *i_kid);
249   ///
250   unsigned int injectInput(const KEYBOARD_INPUT_DATA *i_kid, const KBDLLHOOKSTRUCT *i_kidRaw);
251 #endif // NO_DRIVER
252   
253 private:
254   /// keyboard handler thread
255   static unsigned int WINAPI keyboardHandler(void *i_this);
256   ///
257   void keyboardHandler();
258
259   /// check focus window
260   void checkFocusWindow();
261   /// is modifier pressed ?
262   bool isPressed(Modifier::Type i_mt);
263   /// fix modifier key
264   bool fixModifierKey(ModifiedKey *io_mkey, Keymap::AssignMode *o_am);
265
266   /// output to log
267   void outputToLog(const Key *i_key, const ModifiedKey &i_mkey,
268                    int i_debugLevel);
269
270   /// genete modifier events
271   void generateModifierEvents(const Modifier &i_mod);
272   
273   /// genete event
274   void generateEvents(Current i_c, const Keymap *i_keymap, Key *i_event);
275   
276   /// generate keyboard event
277   void generateKeyEvent(Key *i_key, bool i_doPress, bool i_isByAssign);
278   ///
279   void generateActionEvents(const Current &i_c, const Action *i_a,
280                             bool i_doPress);
281   ///
282   void generateKeySeqEvents(const Current &i_c, const KeySeq *i_keySeq,
283                             Part i_part);
284   ///
285   void generateKeyboardEvents(const Current &i_c);
286   ///
287   void beginGeneratingKeyboardEvents(const Current &i_c, bool i_isModifier);
288   
289   /// pop all pressed key on win32
290   void keyboardResetOnWin32();
291   
292   /// get current modifiers
293   Modifier getCurrentModifiers(Key *i_key, bool i_isPressed);
294
295   /// describe bindings
296   void describeBindings();
297
298   /// update m_lastPressedKey
299   void updateLastPressedKey(Key *i_key);
300
301   /// set current keymap
302   void setCurrentKeymap(const Keymap *i_keymap,
303                         bool i_doesAddToHistory = false);
304   /** open mayu device
305       @return true if mayu device successfully is opened
306   */
307   bool open();
308
309   /// close mayu device
310   void close();
311
312   /// load/unload [sc]ts4mayu.dll
313   void manageTs4mayu(TCHAR *i_ts4mayuDllName, TCHAR *i_dependDllName,
314                      bool i_load, HMODULE *i_pTs4mayu);
315
316 private:
317   // BEGINING OF FUNCTION DEFINITION
318   /// send a default key to Windows
319   void funcDefault(FunctionParam *i_param);
320   /// use a corresponding key of a parent keymap
321   void funcKeymapParent(FunctionParam *i_param);
322   /// use a corresponding key of a current window
323   void funcKeymapWindow(FunctionParam *i_param);
324   /// use a corresponding key of the previous prefixed keymap
325   void funcKeymapPrevPrefix(FunctionParam *i_param, int i_previous);
326   /// use a corresponding key of an other window class, or use a default key
327   void funcOtherWindowClass(FunctionParam *i_param);
328   /// prefix key
329   void funcPrefix(FunctionParam *i_param, const Keymap *i_keymap,
330                   BooleanType i_doesIgnoreModifiers = BooleanType_true);
331   /// other keymap's key
332   void funcKeymap(FunctionParam *i_param, const Keymap *i_keymap);
333   /// sync
334   void funcSync(FunctionParam *i_param);
335   /// toggle lock
336   void funcToggle(FunctionParam *i_param, ModifierLockType i_lock,
337                   ToggleType i_toggle = ToggleType_toggle);
338   /// edit next user input key's modifier
339   void funcEditNextModifier(FunctionParam *i_param,
340                             const Modifier &i_modifier);
341   /// variable
342   void funcVariable(FunctionParam *i_param, int i_mag, int i_inc);
343   /// repeat N times
344   void funcRepeat(FunctionParam *i_param, const KeySeq *i_keySeq,
345                   int i_max = 10);
346   /// undefined (bell)
347   void funcUndefined(FunctionParam *i_param);
348   /// ignore
349   void funcIgnore(FunctionParam *i_param);
350   /// post message
351   void funcPostMessage(FunctionParam *i_param, ToWindowType i_window,
352                        UINT i_message, WPARAM i_wParam, LPARAM i_lParam);
353   /// ShellExecute
354   void funcShellExecute(FunctionParam *i_param, const StrExprArg &i_operation,
355                         const StrExprArg &i_file, const StrExprArg &i_parameters,
356                         const StrExprArg &i_directory,
357                         ShowCommandType i_showCommand);
358   /// SetForegroundWindow
359   void funcSetForegroundWindow(FunctionParam *i_param,
360                                const tregex &i_windowClassName,
361                                LogicalOperatorType i_logicalOp
362                                = LogicalOperatorType_and,
363                                const tregex &i_windowTitleName
364                                = tregex(_T(".*")));
365   /// load setting
366   void funcLoadSetting(FunctionParam *i_param,
367                        const StrExprArg &i_name = StrExprArg());
368   /// virtual key
369   void funcVK(FunctionParam *i_param, VKey i_vkey);
370   /// wait
371   void funcWait(FunctionParam *i_param, int i_milliSecond);
372   /// investigate WM_COMMAND, WM_SYSCOMMAND
373   void funcInvestigateCommand(FunctionParam *i_param);
374   /// show mayu dialog box
375   void funcMayuDialog(FunctionParam *i_param, MayuDialogType i_dialog,
376                       ShowCommandType i_showCommand);
377   /// describe bindings
378   void funcDescribeBindings(FunctionParam *i_param);
379   /// show help message
380   void funcHelpMessage(FunctionParam *i_param,
381                        const StrExprArg &i_title = StrExprArg(),
382                        const StrExprArg &i_message = StrExprArg());
383   /// show variable
384   void funcHelpVariable(FunctionParam *i_param, const StrExprArg &i_title);
385   /// raise window
386   void funcWindowRaise(FunctionParam *i_param,
387                        TargetWindowType i_twt = TargetWindowType_overlapped);
388   /// lower window
389   void funcWindowLower(FunctionParam *i_param, 
390                        TargetWindowType i_twt = TargetWindowType_overlapped);
391   /// minimize window
392   void funcWindowMinimize(FunctionParam *i_param, TargetWindowType i_twt
393                           = TargetWindowType_overlapped);
394   /// maximize window
395   void funcWindowMaximize(FunctionParam *i_param, TargetWindowType i_twt
396                           = TargetWindowType_overlapped);
397   /// maximize window horizontally
398   void funcWindowHMaximize(FunctionParam *i_param, TargetWindowType i_twt
399                            = TargetWindowType_overlapped);
400   /// maximize window virtically
401   void funcWindowVMaximize(FunctionParam *i_param, TargetWindowType i_twt
402                            = TargetWindowType_overlapped);
403   /// maximize window virtically or horizontally
404   void funcWindowHVMaximize(FunctionParam *i_param, BooleanType i_isHorizontal,
405                             TargetWindowType i_twt
406                             = TargetWindowType_overlapped);
407   /// move window
408   void funcWindowMove(FunctionParam *i_param, int i_dx, int i_dy,
409                       TargetWindowType i_twt
410                       = TargetWindowType_overlapped);
411   /// move window to ...
412   void funcWindowMoveTo(FunctionParam *i_param, GravityType i_gravityType,
413                         int i_dx, int i_dy, TargetWindowType i_twt
414                         = TargetWindowType_overlapped);
415   /// move window visibly
416   void funcWindowMoveVisibly(FunctionParam *i_param, 
417                              TargetWindowType i_twt
418                              = TargetWindowType_overlapped);
419   /// move window to other monitor
420   void funcWindowMonitorTo(FunctionParam *i_param,
421                            WindowMonitorFromType i_fromType, int i_monitor,
422                            BooleanType i_adjustPos = BooleanType_true,
423                            BooleanType i_adjustSize = BooleanType_false);
424   /// move window to other monitor
425   void funcWindowMonitor(FunctionParam *i_param, int i_monitor,
426                          BooleanType i_adjustPos = BooleanType_true,
427                          BooleanType i_adjustSize = BooleanType_false);
428   ///
429   void funcWindowClingToLeft(FunctionParam *i_param, 
430                              TargetWindowType i_twt
431                              = TargetWindowType_overlapped);
432   ///
433   void funcWindowClingToRight(FunctionParam *i_param, 
434                               TargetWindowType i_twt
435                               = TargetWindowType_overlapped);
436   ///
437   void funcWindowClingToTop(FunctionParam *i_param, 
438                             TargetWindowType i_twt
439                             = TargetWindowType_overlapped);
440   ///
441   void funcWindowClingToBottom(FunctionParam *i_param, 
442                                TargetWindowType i_twt
443                                = TargetWindowType_overlapped);
444   /// close window
445   void funcWindowClose(FunctionParam *i_param, 
446                        TargetWindowType i_twt = TargetWindowType_overlapped);
447   /// toggle top-most flag of the window
448   void funcWindowToggleTopMost(FunctionParam *i_param);
449   /// identify the window
450   void funcWindowIdentify(FunctionParam *i_param);
451   /// set alpha blending parameter to the window
452   void funcWindowSetAlpha(FunctionParam *i_param, int i_alpha);
453   /// redraw the window
454   void funcWindowRedraw(FunctionParam *i_param);
455   /// resize window to
456   void funcWindowResizeTo(FunctionParam *i_param, int i_width, int i_height, 
457                           TargetWindowType i_twt
458                           = TargetWindowType_overlapped);
459   /// move the mouse cursor
460   void funcMouseMove(FunctionParam *i_param, int i_dx, int i_dy);
461   /// send a mouse-wheel-message to Windows
462   void funcMouseWheel(FunctionParam *i_param, int i_delta);
463   /// convert the contents of the Clipboard to upper case or lower case
464   void funcClipboardChangeCase(FunctionParam *i_param,
465                                BooleanType i_doesConvertToUpperCase);
466   /// convert the contents of the Clipboard to upper case
467   void funcClipboardUpcaseWord(FunctionParam *i_param);
468   /// convert the contents of the Clipboard to lower case
469   void funcClipboardDowncaseWord(FunctionParam *i_param);
470   /// set the contents of the Clipboard to the string
471   void funcClipboardCopy(FunctionParam *i_param, const StrExprArg &i_text);
472   ///
473   void funcEmacsEditKillLinePred(FunctionParam *i_param,
474                                  const KeySeq *i_keySeq1,
475                                  const KeySeq *i_keySeq2);
476   ///
477   void funcEmacsEditKillLineFunc(FunctionParam *i_param);
478   /// clear log
479   void funcLogClear(FunctionParam *i_param);
480   /// recenter
481   void funcRecenter(FunctionParam *i_param);
482   /// Direct SSTP
483   void funcDirectSSTP(FunctionParam *i_param,
484                       const tregex &i_name,
485                       const StrExprArg &i_protocol,
486                       const std::list<tstringq> &i_headers);
487   /// PlugIn
488   void funcPlugIn(FunctionParam *i_param,
489                   const StrExprArg &i_dllName,
490                   const StrExprArg &i_funcName = StrExprArg(),
491                   const StrExprArg &i_funcParam = StrExprArg(),
492                   BooleanType i_doesCreateThread = BooleanType_false);
493   /// set IME open status
494   void funcSetImeStatus(FunctionParam *i_param, ToggleType i_toggle = ToggleType_toggle);
495   /// set string to IME
496   void funcSetImeString(FunctionParam *i_param, const StrExprArg &i_data);
497   /// enter to mouse event hook mode
498   void funcMouseHook(FunctionParam *i_param, MouseHookType i_hookType, int i_hookParam);
499
500   // END OF FUNCTION DEFINITION
501 #  define FUNCTION_FRIEND
502 #  include "functions.h"
503 #  undef FUNCTION_FRIEND
504   
505 public:
506   ///
507   Engine(tomsgstream &i_log);
508   ///
509   ~Engine();
510
511   /// start/stop keyboard handler thread
512   void start();
513   ///
514   void stop();
515
516   /// pause keyboard handler thread and close device
517   bool pause();
518   
519   /// resume keyboard handler thread and re-open device
520   bool resume();
521
522   /// do some procedure before quit which must be done synchronously
523   /// (i.e. not on WM_QUIT)
524   bool prepairQuit();
525
526   /// logging mode
527   void enableLogMode(bool i_isLogMode = true) { m_isLogMode = i_isLogMode; }
528   ///
529   void disableLogMode() { m_isLogMode = false; }
530   
531   /// enable/disable engine
532   void enable(bool i_isEnabled = true) { m_isEnabled = i_isEnabled; }
533   ///
534   void disable() { m_isEnabled = false; }
535   ///
536   bool getIsEnabled() const { return m_isEnabled; }
537
538   /// associated window
539   void setAssociatedWndow(HWND i_hwnd) { m_hwndAssocWindow = i_hwnd; }
540   
541   /// associated window
542   HWND getAssociatedWndow() const { return m_hwndAssocWindow; }
543   
544   /// setting
545   bool setSetting(Setting *i_setting);
546
547   /// focus
548   bool setFocus(HWND i_hwndFocus, DWORD i_threadId,
549                 const tstringi &i_className,
550                 const tstringi &i_titleName, bool i_isConsole);
551
552   /// lock state
553   bool setLockState(bool i_isNumLockToggled, bool i_isCapsLockToggled,
554                     bool i_isScrollLockToggled, bool i_isKanaLockToggled,
555                     bool i_isImeLockToggled, bool i_isImeCompToggled);
556
557   /// show
558   void checkShow(HWND i_hwnd);
559   bool setShow(bool i_isMaximized, bool i_isMinimized, bool i_isMDI);
560
561   /// sync
562   bool syncNotify();
563
564   /// thread detach notify
565   bool threadDetachNotify(DWORD i_threadId);
566
567   /// shell execute
568   void shellExecute();
569   
570   /// get help message
571   void getHelpMessages(tstring *o_helpMessage, tstring *o_helpTitle);
572
573   /// command notify
574   void commandNotify(HWND i_hwnd, UINT i_message, WPARAM i_wParam,
575                      LPARAM i_lParam);
576
577   /// get current window class name
578   const tstringi &getCurrentWindowClassName() const { return m_currentFocusOfThread->m_className; }
579
580   /// get current window title name
581   const tstringi &getCurrentWindowTitleName() const { return m_currentFocusOfThread->m_titleName; }
582
583   /// get mayud version
584   const tstring &getMayudVersion() const { return m_mayudVersion; }
585 };
586
587
588 ///
589 class FunctionParam
590 {
591 public:
592   bool m_isPressed;                             /// is key pressed ?
593   HWND m_hwnd;                                  /// 
594   Engine::Current m_c;                          /// new context
595   bool m_doesNeedEndl;                          /// need endl ?
596   const ActionFunction *m_af;                   /// 
597 };
598
599
600 #endif // !_ENGINE_H