Update the changelog
[opencv] / apps / Hawk / HawkDoc.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of Intel Corporation may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/// HawkDoc.cpp : implementation of the CHawkDoc class
41 //
42
43 #include "stdafx.h"
44 #include "Hawk.h"
45
46 #include "MainFrm.h"
47 #include "HawkDoc.h"
48 #include "HawkView.h"
49 #include "LogView.h"
50 #include "DSWnd.h"
51 #include "HawkOptions.h"
52 #include "QuickWatch.h"
53 #include "wordcolors.h"
54
55 #include "convert.h"
56
57 #include <io.h>
58 #include <fcntl.h>
59 #include <process.h>
60 #include <setjmp.h>
61
62
63 extern "C"
64 {
65 /*#include "eic.h"
66 #ifdef malloc
67 #undef malloc
68 #endif
69 #ifdef realloc
70 #undef realloc
71 #endif
72 #ifdef free
73 #undef free
74 #endif*/
75 #include "CVEiCL\EiC\src\error.h"
76 #include "CVEiCL\EiC\src\preproc.h"
77 #include "HighGUI.h"
78 void set_highgui_mark(jmp_buf* mark);
79 }
80
81 void init_signal_handlers();
82
83 int __cdecl DS_ON_SIZE(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, int* ret);
84 unsigned long __stdcall ProcessEicErr(void* hawkDoc, int show = 1);
85 unsigned long __stdcall ProcessEicOut(void* hawkDoc);
86 unsigned long __stdcall RunScript(void*);
87 unsigned long _stdcall ReadPipeStream(void* data);
88 void __cdecl ImageTransform(void* in);
89
90 typedef struct
91 {
92     stream_pipe pipe;
93     char* text;
94 } data_pipe;
95
96 #define EIC_OUT ((CHawkApp*)AfxGetApp())->m_eicOut
97 #define EIC_ERR ((CHawkApp*)AfxGetApp())->m_eicErr
98
99 #ifdef _DEBUG
100 #define new DEBUG_NEW
101 #undef THIS_FILE
102 static char THIS_FILE[] = __FILE__;
103 #endif
104
105 /////////////////////////////////////////////////////////////////////////////
106 // CHawkDoc
107
108 IMPLEMENT_DYNCREATE(CHawkDoc, CDocument)
109
110 BEGIN_MESSAGE_MAP(CHawkDoc, CDocument)
111     //{{AFX_MSG_MAP(CHawkDoc)
112     ON_COMMAND(ID_RUN, OnRun)
113     ON_UPDATE_COMMAND_UI(ID_RUN, OnUpdateRun)
114     ON_COMMAND(ID_RUNDS, OnRunds)
115     ON_UPDATE_COMMAND_UI(ID_RUNDS, OnUpdateRunds)
116     ON_COMMAND(ID_STOPDS, OnStopds)
117     ON_UPDATE_COMMAND_UI(ID_STOPDS, OnUpdateStopds)
118     ON_COMMAND(ID_OPTIONS_CONFIGURATION, OnOptionsConfiguration)
119     ON_COMMAND(ID_OPTIONS_COLORS, OnOptionsColors)
120     ON_UPDATE_COMMAND_UI(ID_OPTIONS_COLORS, OnUpdateOptionsColors)
121         ON_COMMAND(ID_FILE_CLOSE, OnFileClose)
122         ON_UPDATE_COMMAND_UI(ID_FILE_CLOSE, OnUpdateFileClose)
123         ON_COMMAND(ID_FILE_SAVE, OnFileSave)
124         ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
125         ON_COMMAND(ID_EIC_QWATCH, OnEicQwatch)
126         //}}AFX_MSG_MAP
127 END_MESSAGE_MAP()
128
129 /////////////////////////////////////////////////////////////////////////////
130 // CHawkDoc construction/destruction
131
132 CHawkDoc::CHawkDoc() /*: m_DSWnd(new CDSWnd)*/
133 {
134     m_pHawkView = NULL;
135     m_pLogView = NULL;
136     m_pScript = NULL;
137     m_hThread = NULL;
138     m_hScriptMutex = NULL;
139     m_hScriptExec = NULL;
140     SetModifiedFlag(FALSE);
141 }
142
143 CHawkDoc::~CHawkDoc()
144 {
145     /* Close the therad... */
146     CHawkApp* app = (CHawkApp*)AfxGetApp();
147 //    app->CloseEiCHandles();
148     if(WaitForSingleObject(m_hScriptExec, 0) == WAIT_TIMEOUT)
149     {
150         TerminateThread(m_hScriptExec, 0);
151     }
152     if(WaitForSingleObject( m_hThread, 0) == WAIT_TIMEOUT)
153     {
154         TerminateThread(m_hThread, 0);
155     }
156     CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
157     frame->SetIntRun(FALSE);
158     frame->SetDocRun();
159     delete m_pScript;
160     if(m_hScriptExec) CloseHandle(m_hScriptExec);
161     if(m_hScriptMutex) CloseHandle(m_hScriptMutex);
162 }
163
164 BOOL CHawkDoc::OnNewDocument()
165 {
166         if (!CDocument::OnNewDocument())
167                 return FALSE;
168
169     // TODO: add reinitialization code here
170         // (SDI documents will reuse this document)
171
172     return Initialize();
173 }
174
175
176
177 /////////////////////////////////////////////////////////////////////////////
178 // CHawkDoc serialization
179
180 void CHawkDoc::Serialize(CArchive& ar)
181 {
182     CEditView* pView = GetHawkView();
183     pView->SerializeRaw(ar);
184
185     if(ar.IsLoading())
186     {
187         Initialize();
188     }
189     else
190     {
191         pView->GetEditCtrl().SetModify(FALSE);
192     }
193 }
194
195 /////////////////////////////////////////////////////////////////////////////
196 // CHawkDoc diagnostics
197
198 #ifdef _DEBUG
199 void CHawkDoc::AssertValid() const
200 {
201         CDocument::AssertValid();
202 }
203
204 void CHawkDoc::Dump(CDumpContext& dc) const
205 {
206         CDocument::Dump(dc);
207 }
208 #endif //_DEBUG
209
210 /////////////////////////////////////////////////////////////////////////////
211 // CHawkDoc commands
212
213 void CHawkDoc::OnRun() 
214 {
215     if(IsRunning())
216     {
217         return;
218     }
219
220     CHawkApp* app = (CHawkApp*)AfxGetApp();
221     CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
222
223     if(app->GetSBRun() && IsModified())
224     {
225         OnFileSave();
226         SetModifiedFlag(FALSE);
227         if(IsModified())
228         {
229             return;
230         }
231     }
232
233     frame->SetIntRun(TRUE);
234     frame->m_pRunDoc = this;
235
236     DWORD threadID;
237
238     if(!m_hScriptMutex)
239     {
240         CString mname;
241         mname.Format("Script semaphore,doc=0x%p", this);
242         m_hScriptMutex = CreateMutex(0, TRUE, LPCTSTR(mname));
243     }
244     m_execState = TRUE;
245
246     if(!m_hScriptExec)
247     {
248         m_hScriptExec = CreateThread(0, 0, RunScript, this, 0, &threadID);
249     }
250 //    m_hThread = CreateThread(0, 0, ProcessEicOut, this, 0, &threadID);
251
252     // Let the script execution start...
253     ReleaseMutex(m_hScriptMutex);
254     while(m_execState  == TRUE);
255
256     WaitForSingleObject(m_hScriptMutex, INFINITE);
257     m_execState = TRUE;
258 }
259
260 void CHawkDoc::OnUpdateRun(CCmdUI* pCmdUI) 
261 {
262     CHawkView* pHawkView = GetHawkView();
263     if(!::IsWindow(pHawkView->m_hWnd) || IsRunning())
264     {
265         pCmdUI->Enable(FALSE);
266     }
267     else
268     {
269         pCmdUI->Enable(pHawkView->GetBufferLength());
270     }
271 }
272
273 CHawkView* CHawkDoc::GetHawkView()
274 {
275     if(m_pHawkView)
276     {
277         return m_pHawkView;
278     }
279
280     POSITION pos = GetFirstViewPosition();
281     CView* pView;
282     while(pos)
283     {
284         pView = GetNextView(pos);
285         if(pView->IsKindOf(RUNTIME_CLASS(CHawkView)))
286         {
287             m_pHawkView = static_cast<CHawkView*>(pView);
288             return m_pHawkView;
289         }
290     }
291
292     ASSERT(0);
293
294     return NULL;
295 }
296
297 void GenerateExceptionString(DWORD code, char* buffer)
298 {
299     switch(code)
300     {
301     case EXCEPTION_ACCESS_VIOLATION:
302          strcpy(buffer, "The thread attempted to read from or write to a virtual address \
303 for which it does not have the appropriate access.");
304
305     case EXCEPTION_BREAKPOINT: strcpy(buffer, "A breakpoint was encountered.");
306     case EXCEPTION_FLT_DIVIDE_BY_ZERO: strcpy(buffer, "The thread attempted to divide a floating-point \
307 value by a floating-point divisor of zero.");
308     case EXCEPTION_FLT_INVALID_OPERATION: strcpy(buffer, "This exception represents any floating-point \
309 exception not included in this list.");
310     case EXCEPTION_FLT_OVERFLOW: strcpy(buffer, "The exponent of a floating-point operation is greater \
311 than the magnitude allowed by the corresponding type.");
312     case EXCEPTION_FLT_UNDERFLOW: strcpy(buffer, "The exponent of a floating-point operation is less \
313 than the magnitude allowed by the corresponding type.");
314     case EXCEPTION_INT_DIVIDE_BY_ZERO: strcpy(buffer, "The thread attempted to divide an integer value \
315 by an integer divisor of zero.");
316     case EXCEPTION_INT_OVERFLOW: strcpy(buffer, "The result of an integer operation caused a carry out \
317 of the most significant bit of the result.");
318
319     default:
320         {
321             sprintf(buffer, "Code 0x%08x.", code);
322         }
323     }
324 }
325
326 extern "C"
327 {
328 extern char* EiC_CurrentFile;
329 extern int EiC_CurrentLine;
330 }
331 int _Hawk_EiC_parseString(char* str, void* hawkDoc)
332 {
333 #ifndef HAWK_TEST
334     __try
335     {
336         EiC_parseString(str);
337     }
338     __except(EXCEPTION_EXECUTE_HANDLER)
339     {
340         char info[18256];
341         char ex_info[9128];
342         CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
343         CHawkDoc* pDoc = (CHawkDoc*)hawkDoc;
344         frame->SetIntRun(FALSE);
345         frame->SetDocRun();
346         pDoc->m_hScriptExec = 0;
347         GenerateExceptionString(GetExceptionCode(), ex_info);
348         sprintf(info, "Exception in file %s, line %d: \n%s", EiC_CurrentFile, EiC_CurrentLine, 
349             ex_info);
350         AfxMessageBox(info);
351         EiC_parseString(":reset");
352         return FALSE;
353     }
354 #else
355     EiC_parseString(str);
356 #endif /* HAWK_TEST */
357
358         return TRUE;
359 }
360 unsigned long __stdcall RunScript(void* hawkDoc)
361 {
362         int retval = TRUE;
363         CHawkApp* app = (CHawkApp*)AfxGetApp();
364     CHawkDoc* pDoc = (CHawkDoc*)hawkDoc;
365     CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
366     CString fileName = pDoc->GetPathName();
367     char drive[_MAX_DRIVE], path[_MAX_PATH], file[_MAX_PATH], ext[_MAX_PATH];
368     _splitpath(LPCTSTR(fileName), drive, path, file, ext);
369     CString spath = CString(drive) + path;
370     fileName = CString(file) + ext;
371
372     char curDir[_MAX_PATH];
373     GetCurrentDirectory(_MAX_PATH, curDir);
374     init_signal_handlers();
375
376 //    pDoc->m_readMutex = CreateMutex(NULL, TRUE, "EiC read mutex(for threads)");
377     while(retval)
378     {
379         frame->SetIntRun(FALSE);
380         frame->SetDocRun();
381         while(pDoc->m_execState == FALSE);
382         while(WaitForSingleObject(pDoc->m_hScriptMutex, 10) != WAIT_OBJECT_0)
383         {
384             MSG message;
385             if(PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
386             {
387                 TranslateMessage(&message);
388                 DispatchMessage(&message);
389             }
390         }
391         pDoc->m_execState = FALSE;
392         ReleaseMutex(pDoc->m_hScriptMutex);
393
394         /* Starting the execution... */
395         frame->SetIntRun(TRUE);
396         frame->SetDocRun(pDoc);
397
398         /* Clean the error stream */
399         ProcessEicErr(pDoc, 0);
400
401         EiC_parseString("#pragma push_unsafeptr");
402         CString inString = CString("#include \"") + fileName + CString("\"");
403
404         int ret = setjmp(app->m_mark);
405         if(!ret)
406         {
407             // Execute the script
408             LPTSTR pstr = const_cast<char*>(LPCTSTR(inString));
409             SetCurrentDirectory(spath);
410             retval = _Hawk_EiC_parseString(pstr, hawkDoc);
411             SetCurrentDirectory(curDir);
412         }
413         else
414         {
415             SetCurrentDirectory(curDir);
416             // Catched long jump:
417             wrapexcept_t* err = (wrapexcept_t*)ret;
418             switch(err->result_code)
419             {
420             case result_string:
421                 AfxMessageBox(err->message);
422                 free(err->message);
423                 free(err);
424                 break;
425
426             case result_empty:
427                 break;
428
429             default:
430                 ASSERT(0);
431             }
432             cvDestroyAllWindows();
433         }
434         
435         
436         // Clean the space
437         if(!EiC_ParseError)
438         {
439             //detach_all_controls();
440             inString = CString(":clear ") + fileName;//pDoc->GetPathName();
441             EiC_parseString(const_cast<char*>(LPCTSTR(inString)));
442             EiC_parseString("#pragma pop_ptr");
443 //            EiC_parseString(":reset");
444         }
445         else
446         {
447             if(ProcessEicErr(pDoc))
448             {
449                 // An error has been detected
450         //        return;
451             }
452             // Return to the initial state of EiC
453 //            EiC_parseString(":reset");// Commented because of possible EiC reset bug
454         }
455     }
456     
457     return 0;
458 }
459
460 /* This function should not be called... */
461 unsigned long __stdcall ProcessEicOut(void* hawkDoc)
462 {
463     CHawkDoc* pDoc = (CHawkDoc*)hawkDoc;
464     CHawkApp* app = (CHawkApp*)AfxGetApp();
465     HANDLE mutices[2]; /* Great spelling! */
466     mutices[0] = app->m_printfMutex;
467     mutices[1] = pDoc->m_readMutex;
468 //    long pos = tell(EIC_OUT.read);
469
470 //    fputc(0, EIC_OUT.write);
471 //    fflush(EIC_OUT.write);
472
473     long buffer_size = 2048;
474 //    char* textBuffer = (char*)malloc(buffer_size + 2);
475 //    char* temp = textBuffer;
476 //    int out;
477     while(1)
478     {
479
480         DWORD ret = WaitForMultipleObjects(2, mutices, FALSE, INFINITE);
481         if(ret != WAIT_OBJECT_0)
482         {
483             break;
484         }
485
486         CString buf = app->m_EiCOut;
487         app->m_EiCOut.Empty();
488         ReleaseMutex(app->m_printfMutex);
489         pDoc->GetLogView()->AddString(LPCTSTR(buf));
490
491 /*        if(textBuffer[out - 1] == 0)
492         {
493             break;
494         }*/
495     }
496
497 //    free(textBuffer);
498
499     // Now it is safe to close the application
500     ((CMainFrame*)AfxGetMainWnd())->SetIntRun(FALSE);
501
502     return 1;
503 }
504
505 unsigned long __stdcall ProcessEicErr(void* hawkDoc, int show)
506 {
507     CHawkDoc* pDoc = (CHawkDoc*)hawkDoc;
508     int ret = 0;
509
510     rewind(EIC_ERR.read);
511
512     long buffer_size = 2048;
513     char* textBuffer = (char*)malloc(buffer_size);
514     char* temp = textBuffer;
515     int err, err_total = 0;
516     while(1)
517     {
518         err = _read(_fileno(EIC_ERR.read), temp, buffer_size);
519         err_total += err;
520         if(err < buffer_size)
521         {
522             break;
523         }
524         buffer_size *= 2;
525         temp = (char*)malloc(buffer_size + err_total);
526         memcpy(temp, textBuffer, err_total);
527         free(textBuffer);
528         textBuffer = temp;
529         temp = &textBuffer[err_total];
530     }
531
532     if(err_total > 0)
533     {
534         if(textBuffer[err_total-1] == 26 || textBuffer[err_total-1] == 0)
535         {
536             textBuffer[--err_total] = 0;
537         }
538         if(err_total > 0)
539         {
540             textBuffer[err_total] = 0;
541             if(show)
542                 AfxMessageBox(textBuffer);
543             ret = err_total - 1;
544         }
545     }
546
547     free(textBuffer);
548     /* Clear the file... */
549     _chsize(_fileno(EIC_ERR.read), 0);
550     rewind(EIC_ERR.read);
551     return ret;
552 }
553
554 unsigned long _stdcall ReadPipeStream(void* pdata)
555 {
556     data_pipe* data = static_cast<data_pipe*>(pdata);
557     CString OutText;
558
559     do
560     {
561         OutText += fgetc(data->pipe.read);
562     }
563     while(OutText.GetAt(OutText.GetLength()) != 26);
564
565     data->text = _strdup(LPCTSTR(OutText));
566
567     return 0;
568 }
569
570 CLogView* CHawkDoc::GetLogView()
571 {
572     if(m_pLogView)
573     {
574         return m_pLogView;
575     }
576
577     POSITION pos = GetFirstViewPosition();
578     CView* pView;
579     while(pos)
580     {
581         pView = GetNextView(pos);
582         if(pView->IsKindOf(RUNTIME_CLASS(CLogView)))
583         {
584             m_pLogView = static_cast<CLogView*>(pView);
585             return m_pLogView;
586         }
587     }
588
589     ASSERT(0);
590
591     return NULL;
592 }
593
594 BOOL CHawkDoc::Initialize()
595 {
596     GetHawkView()->UpdateCursorPos();
597     return TRUE;
598 }
599
600 // An example of a bad idea. I tried to divide a C source into parts 
601 // that can be accepted by EiC, for instance, single lines finished by a semicolon
602 // Put off to be on the safe side. Hope I'll never return to this idea.
603 void CHawkDoc::ParseString()
604 {
605     unsigned int i;
606     int braceCount = 0;
607     int bracketCount = 0;
608     int start = 0;
609     char* text = new char[strlen(m_pScript)];
610     CString str;
611
612     m_parsedStrings.RemoveAll();
613     for(i = 0; i < strlen(m_pScript); i++)
614     {
615         switch(m_pScript[i])
616         {
617         case '{':
618             braceCount++;
619             break;
620         case '(':
621             bracketCount++;
622             break;
623
624         case '}':
625             braceCount--;
626             if(!braceCount && !bracketCount)
627             {
628                 memcpy(text, m_pScript + start, i - start + 1);
629                 text[i - start + 1] = 0;
630                 str = CString(text);
631                 str.Remove(10);
632                 str.Remove(13);
633                 m_parsedStrings.Add(str);
634                 start = i + 1;
635             }
636             break;
637
638         case ')':
639             bracketCount--;
640             break;
641
642         case ';':
643             if(!braceCount && !bracketCount)
644             {
645                 memcpy(text, m_pScript + start, i - start + 1);
646                 text[i - start + 1] = 0;
647                 str = CString(text);
648                 str.Remove(10);
649                 str.Remove(13);
650                 if(str.GetLength())
651                     m_parsedStrings.Add(str);
652                 start = i + 1;
653             }
654             break;
655
656         case '#':
657             if(i == 0 || text[i - 1] == 10 || text[i - 1] == 13)
658             {
659                 
660             }
661         }
662     }
663
664     delete text;
665 }
666
667 void CHawkDoc::OnRunds() 
668 {
669     if(IsRunning())
670     {
671         // We're already running
672         return;
673     }
674
675     CHawkApp* app = (CHawkApp*)AfxGetApp();
676     if(app->GetSBRun() && IsModified())
677     {
678         OnFileSave();
679         if(IsModified())
680         {
681             return;
682         }
683     }
684
685         if(ParseTransformFunction())
686         {
687         m_dsSimpleMode = TRUE;
688         CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
689         frame->SetIntRun(TRUE);
690         frame->m_pRunDoc = this;
691         frame->RunDS(ImageTransform);
692         }
693 }
694
695 void CHawkDoc::OnUpdateRunds(CCmdUI* pCmdUI) 
696 {
697         pCmdUI->Enable(0/*((CMainFrame*)AfxGetMainWnd())->IsDirectShowOn()*/);
698 }
699
700 static void __cdecl ImageTransform(void* in)
701 {
702     CHawkApp* app = (CHawkApp*)AfxGetApp();
703
704     WaitForSingleObject(app->m_printfMutex, INFINITE);
705     TRACE0("\nCaptured printf mutex...");
706         IplImage* image = static_cast<IplImage*>(in);
707
708         CString inString;
709         inString.Format("__HAWK_IMAGE_TRANSFORM((IPLIMAGE)0x%x);", (int)in);
710         EiC_parseString(const_cast<char*>(LPCTSTR(inString)));
711     TRACE0("Preparing to release printf mutex...");
712     ReleaseMutex(app->m_printfMutex);
713     TRACE0("\nReleased printf mutex...");
714 }
715
716 BOOL CHawkDoc::ParseTransformFunction()
717 {
718         const char* dir = ((CHawkApp*)AfxGetApp())->GetModulePath();
719         char* tmpname = _strdup(_tempnam(dir, ""));
720         if(tmpname == NULL)
721         {
722                 AfxMessageBox("Could not create a temporary file name");
723                 return FALSE;
724         }
725
726         m_tempName = CString(tmpname);
727         FILE* fp = fopen(tmpname, "wt");
728         if(fp == NULL)
729         {
730                 AfxMessageBox("Could not open a temporary file");
731                 return FALSE;
732         }
733
734         fprintf(fp, "void __HAWK_IMAGE_TRANSFORM(IPPIIMAGE ds_image)\n");
735         fprintf(fp, "{\n");
736         fprintf(fp, "#include \"%s\"\n", GetPathName());
737         fprintf(fp, "}");
738         fclose(fp);
739
740     EiC_parseString("#pragma push_unsafeptr");
741         CString str;
742         str.Format("#include \"%s\"", tmpname);
743         free(tmpname);
744         EiC_parseString(const_cast<char*>(LPCTSTR(str)));
745     EiC_parseString("#pragma pop_ptr");
746
747         return !ProcessEicErr(this);
748 }
749
750 void CHawkDoc::ClearTransformFunction()
751 {
752         CString inString;
753         inString.Format(":clear %s", LPCTSTR(m_tempName));
754         EiC_parseString(const_cast<char*>(LPCTSTR(inString)));
755         remove(const_cast<char*>(LPCTSTR(m_tempName)));
756         m_tempName.Empty();
757 }
758
759 unsigned long __stdcall _StopDS(void* doc)
760 {
761     CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
762     CHawkApp* app = (CHawkApp*)AfxGetApp();
763     CHawkDoc* pDoc = (CHawkDoc*)doc;
764     WaitForSingleObject(app->m_printfMutex, INFINITE);
765         frame->StopGraph();
766 //      VERIFY(m_DSWnd->DestroyWindow());
767         cvDestroyWindow("DirectShow");
768         // Clear the CVEiCL scope
769     if(pDoc->m_dsSimpleMode)
770             pDoc->ClearTransformFunction();
771     ReleaseMutex(app->m_printfMutex);
772 /*      FILE* out = ((CHawkApp*)AfxGetApp())->m_eicOut.write;
773         fputc(0, out);
774         fflush(out);*/
775     if(pDoc->m_dsSimpleMode)
776     {
777         frame->SetIntRun(FALSE);
778         frame->SetDocRun();
779     }
780
781     return 0;
782 }
783
784 void CHawkDoc::OnStopds() 
785 {
786     DWORD tID;
787     CreateThread(NULL, 0, _StopDS, this, 0, &tID);
788 }
789
790 void CHawkDoc::OnUpdateStopds(CCmdUI* pCmdUI) 
791 {
792         pCmdUI->Enable(((CMainFrame*)AfxGetMainWnd())->IsDSRunning());  
793 }
794
795 BOOL CHawkDoc::IsRunning()
796 {
797     CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
798     if(frame->IsIntRun() || frame->IsDSRunning())
799     {
800         // We're already running
801         return TRUE;
802     }
803     else
804     {
805         return FALSE;
806     }
807 }
808
809 BOOL CHawkDoc::CanCloseFrame(CFrameWnd* pFrame) 
810 {
811         return !IsRunning() && !((CMainFrame*)AfxGetMainWnd())->IsDSRunning();
812 }
813
814 void CHawkDoc::OnOptionsConfiguration() 
815 {
816     CHawkApp* app = (CHawkApp*)AfxGetApp();
817     CHawkOptions dlg(app->GetErrLevel(), app->GetSBRun());
818     if(dlg.DoModal() == IDOK)
819     {
820         app->SetErrLevel(dlg.m_errLevel ? safe : unsafe);
821         app->SetSBRun(dlg.m_sbRun);
822     }
823 }
824
825 BOOL CHawkDoc::IsModified()
826 {
827 //    return GetHawkView()->m_edit.GetModify();
828     return CDocument::IsModified();
829 }
830
831
832 void CHawkDoc::OnOptionsColors() 
833 {
834     CWordColors wc;
835     GetHawkView()->Scheme = wc.DoModal(GetHawkView()->Scheme);
836 }
837
838 void CHawkDoc::OnUpdateOptionsColors(CCmdUI* pCmdUI) 
839 {
840         pCmdUI->Enable();
841 }
842
843 BOOL CHawkDoc::OnOpenDocument(LPCTSTR lpszPathName) 
844 {
845         if (!CDocument::OnOpenDocument(lpszPathName))
846                 return FALSE;
847
848     char drive[_MAX_DRIVE];
849     char path[_MAX_DIR];
850     char fname[_MAX_FNAME];
851     char fext[_MAX_EXT];
852     _splitpath(lpszPathName, drive, path, fname, fext);
853     
854     VERIFY(::SetCurrentDirectory(LPCTSTR(CString(drive) + CString(path))));     
855         return TRUE;
856 }
857
858 /* Currently this function should not be called! */
859 void CHawkDoc::OnFileClose() 
860 {
861     /* Close the therad... */
862     CHawkApp* app = (CHawkApp*)AfxGetApp();
863     app->CloseEiCHandles();
864     if(WaitForSingleObject(m_hScriptExec, 0) == WAIT_TIMEOUT)
865     {
866         TerminateThread(m_hScriptExec, 0);
867     }
868     if(WaitForSingleObject( m_hThread, 0) == WAIT_TIMEOUT)
869     {
870         TerminateThread(m_hThread, 0);
871     }
872     app->InitEiCHandles();
873     
874     CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
875     frame->SetIntRun(FALSE);
876     frame->SetDocRun();
877     
878     CDocument::OnFileClose();   
879 }
880
881 void CHawkDoc::OnUpdateFileClose(CCmdUI* pCmdUI) 
882 {
883     pCmdUI->Enable(!IsRunning());
884 }
885
886 int play_ds(void (*transform_image)(IplImage*))
887 {
888     CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
889     if(!frame->IsDirectShowOn())
890     {
891         return -1;
892     }
893     frame->m_pRunDoc->m_dsSimpleMode = FALSE;
894     frame->RunDS((void(*)(void*))transform_image, FALSE);
895     return 0;
896 }
897
898 void CHawkDoc::OnFileSave() 
899 {
900     CDocument::OnFileSave();
901     SetModifiedFlag(FALSE);
902 }
903
904 void CHawkDoc::OnFileSaveAs() 
905 {
906     CDocument::OnFileSaveAs();  
907     SetModifiedFlag(FALSE);
908 }
909
910 void CHawkDoc::OnEicQwatch() 
911 {
912     CQuickWatch dlg;
913     dlg.DoModal();
914 }