-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathDragonCode.h
More file actions
311 lines (253 loc) · 10.4 KB
/
DragonCode.h
File metadata and controls
311 lines (253 loc) · 10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
/*
Python Macro Language for Dragon NaturallySpeaking
(c) Copyright 1999 by Joel Gould
Portions (c) Copyright 1999 by Dragon Systems, Inc.
DragCode.h
CDragonCode is a class which encapusulates the main interface for
communicating with NatSpeak. This class also defined the functions
which implement the export Python natlink functions.
*/
struct CGrammarObject;
struct CResultObject;
struct CDictationObject;
class CDgnSRNotifySink;
class CDgnAppSupport;
class MessageWindow;
class CMessageStack;
typedef const char * PCCHAR;
//---------------------------------------------------------------------------
class CDragonCode
{
public:
CDragonCode() {
m_hMsgWnd = NULL;
m_dwKey = 0;
m_dragonMajorVersion = 13;
m_pBeginCallback = NULL;
m_pChangeCallback = NULL;
m_pFirstGramObj = NULL;
m_pFirstResObj = NULL;
m_pFirstDictObj = NULL;
m_pSecdThrd = NULL;
m_pAppClass = NULL;
m_bDuringInit = FALSE;
m_bDuringPaused = FALSE;
m_nCallbackDepth = 0;
m_dwPendingCallback = 0;
m_nPauseRecog = 0;
m_deferredCookie = 0;
m_pThreadState = NULL;
m_pTimerCallback = NULL;
m_nTimer = 0;
m_bSetTraining = FALSE;
m_pszLogFile = NULL;
m_bHasTrayIcon = FALSE;
m_pTrayIconCallback = NULL;
m_pMessageWindowCallback = NULL;
m_pMessageStack = NULL;
m_pIDgnSSvcOutputEventA=0;
m_pIDgnSSvcOutputEvent=0;
m_pIDgnSSvcInterpreter=0;
m_pIDgnSSvcInterpreterA=0;
}
~CDragonCode() {
natDisconnect();
}
// Each of these represents a function called from Python through
// wrapper code in PythWrap.cpp. If there is no return value, we
// return TRUE on success or FALSE on error. Otherwise, we return
// a Python object on success or NULL on error.
BOOL natConnect( IServiceProvider * pIDgnSite, BOOL bUseThreads = FALSE );
BOOL natDisconnect();
BOOL setBeginCallback( PyObject *pCallback );
BOOL setChangeCallback( PyObject *pCallback );
BOOL playString( const char * pszKeys, DWORD dwFlags );
BOOL displayText( const char * pszText, BOOL bError = TRUE, BOOL blogText = TRUE );
BOOL setMicState( const char * pszState );
BOOL recognitionMimic( PCCHAR * ppWords );
BOOL execScript(
const char * pszScript, PCCHAR * ppWords, const char * pszComment );
BOOL playEvents( DWORD dwCount, HOOK_EVENTMSG * pEvents );
BOOL waitForSpeech( int nTimeout );
BOOL inputFromFile(
const char * pszFileName, BOOL bRealTime,
DWORD dwPlayList, DWORD * adwPlayList, int nUttDetect );
BOOL setTimerCallback( PyObject * pCallback, int nMilliseconds = 0 );
BOOL startTraining( char * pMode );
BOOL finishTraining( BOOL bNoCancel );
BOOL createUser(
char * pszUserName, char * pszBaseModel, char * pszBaseTopic );
BOOL openUser( char * pszUserName );
BOOL saveUser();
BOOL deleteWord( char * wordName );
BOOL setWordInfo( char * wordName, DWORD wordInfo );
BOOL setTrayIcon( char * iconName, char * toolTip, PyObject * pCallback );
BOOL setMessageWindow( PyObject * pCallback, DWORD dwflags = 0 );
PyObject * getCurrentModule();
PyObject * getCurrentUser();
PyObject * getMicState();
PyObject * getCallbackDepth();
PyObject * getCursorPos();
PyObject * getScreenSize();
PyObject * getTrainingMode();
PyObject * getUserTraining();
PyObject * getClipboard();
PyObject * getAllUsers();
PyObject * getWordInfo( char * wordName, int flags );
PyObject * addWord( char * wordName, DWORD wordInfo, PCCHAR * ppProns );
PyObject * getWordProns( char * wordName );
// Also called from PythWrap.cpp but it never returns an error. Instead
// it returns TRUE or FALSE which is then needs to be converted into a
// Python object. We do this so this same routine can be called
// internally in natConnect.
BOOL isNatSpeakRunning();
// this is called from CDgnAppSupport at initialization time
void setAppClass( CDgnAppSupport * pAppClass ) { m_pAppClass = pAppClass; }
void setDuringInit( BOOL bState ) { m_bDuringInit = bState; }
// this is called when the natlink module (this class!) is deallocated from
// Python
void freeModule();
// these functions are called from CGrammarObject
ISRCentral * pISRCentral() { return m_pISRCentral; }
void addGramObj(CGrammarObject * pGramObj );
void removeGramObj(CGrammarObject * pGramObj );
// these functions are called from CResultObject
void addResObj(CResultObject * pResObj );
void removeResObj(CResultObject * pResObj );
// these functions are called from CDictationObject
void addDictObj(CDictationObject * pDictObj );
void removeDictObj(CDictationObject * pDictObj );
// when we need to post a message from a COM notify sink to the message
// window, make this call
void postMessage( UINT wMsg, WPARAM wParam, LPARAM lParam ) {
PostMessage( m_hMsgWnd, wMsg, wParam, lParam );
}
// these functions are called when a message is posted to our message
// window
void onMenuCommand( WPARAM wParam );
void onPaused( WPARAM wParam );
void onAttribChanged( WPARAM wParam );
void onSendResults( WPARAM wParam, LPARAM lParam );
void onTimer();
void onTrayIcon( WPARAM wParam, LPARAM lParam );
// these functions are called when we get a window message
void onSendResultsCallback( PyObject *pFunc, PyObject *pArgs );
// when the grammar object wants to make a results callback from a
// PhraseFinish notification it calls this function. We then post
// ourself a message to make the actual callback. The third argument
// is the type of callback
void makeResultsCallback( PyObject *pFunc, PyObject *pArgs );
// this is what we call to reset m_nPauseRecog and process any deferred
// pause request
void resetPauseRecog();
// access to the thread state
PyThreadState * getThreadState() { return m_pThreadState; }
// used in DictObj so we can create a VoiceDictation object
IServiceProvider * getSiteObj() { return m_pIServiceProvider; }
// use this to make a callback, this will catch any unhandled exceptions
// and report them
void makeCallback( PyObject *pFunc, PyObject *pArgs );
protected:
// these are our SAPI interface pointers. We use ATL smart pointers to
// avoid having to call AddRef and Release
ISRCentralPtr m_pISRCentral;
IDgnSREngineControlPtr m_pIDgnSREngineControl;
IDgnSSvcOutputEventPtr m_pIDgnSSvcOutputEvent;
IDgnSSvcOutputEventA * m_pIDgnSSvcOutputEventA;
IServiceProviderPtr m_pIServiceProvider;
IDgnExtModSupStringsPtr m_pIDgnExtModSupStrings;
IDgnSSvcInterpreterPtr m_pIDgnSSvcInterpreter;
IDgnSSvcInterpreterA * m_pIDgnSSvcInterpreterA;
IDgnSRTrainingPtr m_pIDgnSRTraining;
// the key for unregistering our engine sink (a SAPI thing)
DWORD m_dwKey;
// Dragon major version (e.g. 13, 15, 16). Detected at connect time
// via IDgnSREngineControl::GetVersion. DNS 16 has different COM
// calling conventions for PlayString and PlayEvents.
DWORD m_dragonMajorVersion;
// the name of the log file (or en empty string if not known). We
// assume that this will be less than the maximum path and file name
// under Windows.
char * m_pszLogFile;
// this is a pointer to the function set with setBeginCallback; it is
// NULL to avoid any callback
PyObject *m_pBeginCallback;
// this is a pointer to the function set with setChangeCallback; it is
// NULL to avoid any callback
PyObject *m_pChangeCallback;
// we keep a hidden window in this thread to which we can send windows
// messages
HWND m_hMsgWnd;
// The CGrammarObject instances are in a linked list and the head of that list
// is stored in the CDragonCode object. This allows us to unload all
// grammars when we call natDisconnect
CGrammarObject * m_pFirstGramObj;
// The CResultObject instances are also in a linked list for the same reason.
CResultObject * m_pFirstResObj;
// And also the CDictationObject instances
CDictationObject * m_pFirstDictObj;
// this is a pointer to the second thread where we can display messages
MessageWindow * m_pSecdThrd;
// we remember a pointer to the CDgnAppSupport class so we can handle
// the reinitialization function
CDgnAppSupport * m_pAppClass;
// during initialization we restrict some function calls to avoid
// deadlock
BOOL m_bDuringInit;
// during paused callback we restrict some function calls to avoid
// deadlock
BOOL m_bDuringPaused;
// this is incremented everytime we enter a callback and decremented
// when the callback returns
BOOL m_nCallbackDepth;
// we are not allowed to make a change callback when we are processing
// another callback. To get around this, we set a flag if there should
// be a pending change callback
DWORD m_dwPendingCallback;
// in order to delay recognition while we process other results, we set
// a flag (m_nPauseRecog). If this flag is set when a new recognition
// starts then we delay until that flag is cleared, remembering the
// cookie we need to resume
int m_nPauseRecog;
QWORD m_deferredCookie;
// this is a pointer to the Python thread state which we create so we
// can restore the thread state during callbacks; will be nULL if we are
// not supporting Python Thread safety
PyThreadState * m_pThreadState;
// this is a pointer to the function set with setTimerCallback; it is
// NULL to avoid any callback
PyObject * m_pTimerCallback;
// when we have installed a window timer, this is the timer number.
// Otherwise this will be 0
int m_nTimer;
// if the user set a training mode, we set this flag so we can turn off
// the training mode when we exit
int m_bSetTraining;
// set when we have installed a tray icon
BOOL m_bHasTrayIcon;
PyObject *m_pTrayIconCallback;
// set when the message window is started
PyObject * m_pMessageWindowCallback;
// This is what we call when we are ready to recume recognition
void doPausedProcessing( QWORD dwCookie );
// this is called when we shutdown or when we reload Python to release
// all COM pointer which may be lost
void releaseObjects();
// used to test a wave file
DWORD testFileName( const char * pszFileName );
// this is the standard windows message loop except that we look for
// a special exit message
LPARAM messageLoop( UINT message, WPARAM wParam );
// writes one line to the dragon.log file
public:
void logMessage( const char * pszText );
void logCookie( const char * pszText, QWORD qCookie );
protected:
// subroutines of natConnect
BOOL initGetSiteObject( IServiceProvider * & pIDgnSite );
BOOL initSecondWindow();
// this is a stack of the things we are looking for in a message loop
CMessageStack * m_pMessageStack;
void TriggerMessage( UINT message, WPARAM wParam, LPARAM lParam );
BOOL IsMessageTriggered( UINT message, WPARAM wParam, LPARAM & lParam );
};