1 //####COPYRIGHTBEGIN####
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
6 // This program is part of the eCos host tools.
8 // This program is free software; you can redistribute it and/or modify it
9 // under the terms of the GNU General Public License as published by the Free
10 // Software Foundation; either version 2 of the License, or (at your option)
13 // This program is distributed in the hope that it will be useful, but WITHOUT
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 // You should have received a copy of the GNU General Public License along with
19 // this program; if not, write to the Free Software Foundation, Inc.,
20 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 // ----------------------------------------------------------------------------
24 //####COPYRIGHTEND####
25 // RunTestsSheet.cpp : implementation file
31 #include "eCosThreadUtils.h"
32 #include "eCosTrace.h"
33 #include "PropertiesDialog.h"
34 #include "ResetAttributes.h"
35 #include "RunTestsSheet.h"
36 #include "TestResource.h"
41 static const UINT arIds []={IDOK,IDCANCEL,ID_APPLY_NOW,IDHELP};
47 static char THIS_FILE[] = __FILE__;
51 /////////////////////////////////////////////////////////////////////////////
54 IMPLEMENT_DYNAMIC(CRunTestsSheet, CeCosPropertySheet)
56 CRunTestsSheet::CRunTestsSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage, CBFunc pInitFunc, CRunTestsSheet **ppSheet)
57 :CeCosPropertySheet(pszCaption, pParentWnd, iSelectPage),
59 m_pInitFunc(pInitFunc),
60 m_bAllowResizing(false),
65 m_bHideRemoteControls(false),
68 m_ep(CeCosTest::ExecutionParameters::RUN),
70 m_nDownloadTimeout(120),
71 m_nTimeoutType(TIMEOUT_AUTOMATIC),
72 m_nDownloadTimeoutType(TIMEOUT_SPECIFIED),
75 m_strPort(_T("COM1")),
78 m_nReset(RESET_MANUAL),
83 InitializeCriticalSection(&m_CS);
84 AddPage(&executionpage);
86 AddPage(&summarypage);
90 CRunTestsSheet::~CRunTestsSheet()
96 DeleteCriticalSection(&m_CS);
100 BEGIN_MESSAGE_MAP(CRunTestsSheet, CeCosPropertySheet)
101 //{{AFX_MSG_MAP(CRunTestsSheet)
102 ON_BN_CLICKED(IDOK, OnRun)
103 ON_BN_CLICKED(ID_APPLY_NOW, OnProperties)
104 ON_BN_CLICKED(IDCANCEL, OnClose)
105 ON_MESSAGE(WM_TESTOUTPUT, OnTestOutput)
106 ON_MESSAGE(WM_RUNCOMPLETE, OnTestsComplete)
109 ON_WM_GETMINMAXINFO()
111 ON_MESSAGE(WM_KICKIDLE, OnKickIdle)
116 /////////////////////////////////////////////////////////////////////////////
117 // CRunTestsSheet message handlers
119 BOOL CRunTestsSheet::OnInitDialog()
122 m_prop.Add(_T("Platform"),m_strTarget);
124 m_prop.Add(_T("Active timeout"),m_nTimeout);
125 m_prop.Add(_T("Download timeout"),m_nDownloadTimeout);
126 m_prop.Add(_T("Active timeout type"),m_nTimeoutType);
127 m_prop.Add(_T("Download timeout type"),m_nDownloadTimeoutType);
128 m_prop.Add(_T("Remote"),m_bRemote);
129 m_prop.Add(_T("Serial"),m_bSerial);
130 m_prop.Add(_T("Port"),m_strPort);
131 m_prop.Add(_T("Baud"),m_nBaud);
132 m_prop.Add(_T("Local TCPIP Host"),m_strLocalTCPIPHost);
133 m_prop.Add(_T("Local TCPIP Port"),m_nLocalTCPIPPort);
134 m_prop.Add(_T("Reset Type"),m_nReset);
135 m_prop.Add(_T("Reset String"),m_strReset);
136 m_prop.Add(_T("Resource Host"),m_strResourceHost);
137 m_prop.Add(_T("Resource Port"),m_nResourcePort);
138 m_prop.Add(_T("Remote Host"),m_strRemoteHost);
139 m_prop.Add(_T("Remote Port"),m_nRemotePort);
140 m_prop.Add(_T("Recurse"),executionpage.m_bRecurse);
141 //m_prop.Add(_T("Loadfromdir"),executionpage.m_strLoaddir);
142 m_prop.Add(_T("Farmed"),m_bFarmed);
143 m_prop.Add(_T("Extension"),executionpage.m_strExtension);
145 CeCosTrace::SetOutput(TestOutputCallback,this);
146 CeCosTrace::SetError (TestOutputCallback,this);
148 // m_psh can only be used to set the small icon. Set the large one here.
149 m_psh.hIcon=AfxGetApp()->LoadIcon(IDR_TT_MAINFRAME);
150 //sheet.m_psh.dwFlags|=PSH_USEHICON/*|PSH_HASHELP*/;
152 SetIcon(m_psh.hIcon,FALSE);
153 SetIcon(m_psh.hIcon,TRUE);
155 GetWindowRect(m_rcPrev);
157 CeCosTrace::EnableTracing(CeCosTrace::TRACE_LEVEL_TRACE);
159 CeCosTrace::SetInteractive(true);
162 m_pInitFunc(&m_prop,false);
165 GetDlgItem(IDCANCEL)->SetWindowText(_T("&Close"));
167 m_nTestsToComplete=0;
168 BOOL bResult = CeCosPropertySheet::OnInitDialog();
169 SetDlgItemText(IDOK,_T("&Run"));
170 SetDlgItemText(ID_APPLY_NOW,_T("&Properties"));
171 GetDlgItem(ID_APPLY_NOW)->EnableWindow(TRUE);
172 GetDlgItem(IDCANCEL)->EnableWindow(TRUE); // required for modeless case
174 SetActivePage(&outputpage);
175 SetActivePage(&summarypage);
176 SetActivePage(&executionpage);
179 m_pInitFunc(&m_prop,false);
180 outputpage.UpdateData(FALSE);
181 summarypage.UpdateData(FALSE);
182 executionpage.UpdateData(FALSE);
185 CString strCaption = _T("Output");
187 tcItem.mask = TCIF_TEXT;
188 tcItem.pszText = (LPTSTR)((LPCTSTR)strCaption);
189 GetTabControl()->SetItem(2, &tcItem );
190 strCaption=_T("Summary");
191 GetTabControl()->SetItem(3, &tcItem );
195 // WS_OVERLAPPEDWINDOW would preclude caption bar help button
196 ModifyStyle(0,WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME ,0);
202 m_cxMin=rect.Width();
203 m_cyMin=rect.Height();
205 m_bAllowResizing=true;
207 WINDOWPLACEMENT wndpl;
208 if (5==_stscanf(m_strPlacement,_T("%d %d %d %d %d"),&rect.left,&rect.top,&rect.right,&rect.bottom,&wndpl.showCmd)){
210 SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)(RECT *)rcMax, 0);
212 if(rect.Width()<100 || rect.Height()<100 || rect.Width()>rcMax.Width() || rect.Height()>rcMax.Height()){
213 rect=CFrameWnd::rectDefault;
216 wndpl.length = sizeof(WINDOWPLACEMENT);
219 wndpl.ptMinPosition = CPoint(0, 0);
220 wndpl.ptMaxPosition =CPoint(-::GetSystemMetrics(SM_CXBORDER),-::GetSystemMetrics(SM_CYBORDER));
221 wndpl.rcNormalPosition = rect;
223 // sets window's position and iconized/maximized status
224 SetWindowPlacement(&wndpl);
227 // Hack: force an initial sizing (without which the tab control is badly sized)
228 m_rcOffset.left=m_rcOffset.right=m_rcOffset.top=0;
230 m_rcOffset.bottom=m_bModal?50:-50;
231 MoveWindow(GetTabControl(),Stretch);
232 for(int i=0;i<GetPageCount();i++){
233 MoveWindow(GetPage(i),Stretch);
236 for(CWnd *p=GetWindow(GW_CHILD);p;p=p->GetWindow(GW_HWNDNEXT)){
238 ::GetClassName(p->m_hWnd,buf,sizeof buf);
239 TRACE(_T("Window %x id=%d class=%s\n"),p,p->GetDlgCtrlID(),buf);
242 for(i=0;i<sizeof(arIds)/sizeof(arIds[0]);i++){
243 CWnd *pWnd=GetDlgItem(arIds[i]);
245 MoveWindow(pWnd,BottomRight);
246 pWnd->ShowWindow(SW_SHOW); // necessary in the modeless case
248 TRACE(_T("Failed to find window id=%x\n"),arIds[i]);
252 // hack to lay buttons out correctly in application case
253 if(this==AfxGetMainWnd()){
255 GetDlgItem(IDOK)->GetWindowRect(rect1);
256 GetDlgItem(IDCANCEL)->GetWindowRect(rect2);
258 rect.left-=(rect2.left-rect1.left);
259 rect.right-=(rect2.right-rect1.right);
260 ScreenToClient(rect);
261 GetDlgItem(ID_APPLY_NOW)->MoveWindow(rect);
262 GetDlgItem(ID_APPLY_NOW)->ShowWindow(SW_SHOW);
272 void CRunTestsSheet::OnRun()
275 if(Running==m_Status){
276 outputpage.AddLogMsg(_T("Run canceled"));
278 EnterCriticalSection(&m_CS);
279 m_nNextToSubmit=0x7fffffff;
280 LeaveCriticalSection(&m_CS);
281 CeCosTest::CancelAllInstances();
283 outputpage.UpdateData(TRUE);
284 summarypage.UpdateData(TRUE);
285 executionpage.UpdateData(TRUE);
286 if(0==executionpage.SelectedTestCount()){
287 MessageBox(_T("No tests have selected for execution"));
289 m_ep=CeCosTest::ExecutionParameters(
290 CeCosTest::ExecutionParameters::RUN,
292 TIMEOUT_NONE==m_nTimeoutType?0x7fffffff:TIMEOUT_AUTOMATIC==m_nTimeoutType?900000:1000*m_nTimeout,
293 TIMEOUT_NONE==m_nDownloadTimeoutType?0x7fffffff:TIMEOUT_AUTOMATIC==m_nDownloadTimeoutType?0:1000*m_nDownloadTimeout);
295 CTestResource::SetResourceServer(CeCosSocket::HostPort(m_strResourceHost,m_nResourcePort));
296 if(!CTestResource::Load()){
297 MessageBox(_T("Could not connect to resource server"));
301 const String strPort(m_bSerial?(LPCTSTR)m_strPort:CeCosSocket::HostPort(m_strLocalTCPIPHost,m_nLocalTCPIPPort));
302 if(0==strPort.size()){
303 m_pResource=new CTestResource(_T(""),m_ep.PlatformName());
305 int nBaud=m_bSerial?m_nBaud:0;
306 if (RESET_X10!=m_nReset) {
307 m_pResource=new CTestResource(_T(""),m_ep.PlatformName(),strPort,nBaud);
309 m_pResource=new CTestResource(_T(""),m_ep.PlatformName(),strPort,nBaud,m_strReset);
314 SetDlgItemText(IDOK,_T("&Stop"));
316 outputpage.AddLogMsg(_T("Run started"));
323 CRunTestsSheet *pSheet;
327 DWORD CRunTestsSheet::X10ThreadFunc (void *pParam)
329 Info *pInfo=(Info *)pParam;
332 CResetAttributes::ResetResult n=pInfo->pSheet->m_pResource->Reset(str);
333 if(CResetAttributes::RESET_OK!=n){
334 str+=_T(">>> Could not reset target\n");
337 LPTSTR pszCopy=new TCHAR[1+str.size()];
338 _tcscpy(pszCopy,str);
339 pInfo->pSheet->PostMessage(WM_TESTOUTPUT,(WPARAM)pszCopy,0);
342 // we're already in a thread, so we can call the function directly
343 pInfo->pTest->RunLocal();
349 void CALLBACK CRunTestsSheet::RunLocalFunc(void *pParam)
351 ((Info *)pParam)->pTest->RunLocal();
354 void CALLBACK CRunTestsSheet::RunRemoteFunc(void *pParam)
356 ((Info *)pParam)->pTest->RunRemote(NULL);
359 void CRunTestsSheet::SubmitTests()
361 int nResources=m_bRemote?max(1,CTestResource::GetMatchCount (m_ep)):1;
362 if(nResources>CeCosTest::InstanceCount){
363 if(m_nNextToSubmit>=executionpage.SelectedTestCount()){
366 Info *pInfo=new Info;
367 pInfo->pTest=new CeCosTest(m_ep, executionpage.SelectedTest(m_nNextToSubmit++));
369 m_nTestsToComplete++;
371 CeCosThreadUtils::RunThread(RunRemoteFunc,pInfo,RunCallback,_T("RunRemoteFunc"));
374 switch((ResetType)m_nReset){
379 // Resetting can take a while, so spawn a thread
383 CloseHandle(CreateThread(0,0,X10ThreadFunc, pInfo, 0, &dwID));
387 bRun=(IDOK==MessageBox(_T("Press OK when target is reset - cancel to abort run"),NULL,MB_OKCANCEL));
389 m_nNextToSubmit=executionpage.SelectedTestCount();
395 CeCosThreadUtils::RunThread(RunLocalFunc,pInfo,RunCallback,_T("RunLocalFunc"));
401 void CRunTestsSheet::RunCallback(void *pParam)
403 Info *pInfo=(Info *)pParam;
404 CRunTestsSheet *pSheet=pInfo->pSheet;
405 if(::IsWindow(pSheet->m_hWnd)){ //FIXME
406 CeCosTest *pTest=pInfo->pTest;
407 EnterCriticalSection(&pSheet->m_CS);
409 pSheet->summarypage.AddResult(pTest);
412 pSheet->m_nTestsToComplete--;
413 pSheet->SubmitTests();
415 if(0==pSheet->m_nTestsToComplete){
416 // It would be nice to do this in the handler for WM_RUNCOMPLETE, but we must be in the CS
417 delete pSheet->m_pResource;
418 pSheet->m_pResource=0;
419 pSheet->PostMessage(WM_RUNCOMPLETE,0,0);
421 LeaveCriticalSection(&pSheet->m_CS);
426 LRESULT CRunTestsSheet::OnTestsComplete(WPARAM wParam, LPARAM lParam)
428 UNUSED_ALWAYS(wParam);
429 UNUSED_ALWAYS(lParam);
431 SetDlgItemText(IDOK,_T("&Run"));
432 outputpage.AddLogMsg(_T("Run complete"));
436 void CALLBACK CRunTestsSheet::TestOutputCallback(void *pParam,LPCTSTR psz)
438 CRunTestsSheet*pWnd=(CRunTestsSheet*)pParam;
439 if(::IsWindow(pWnd->m_hWnd)){ //FIXME
440 LPTSTR pszCopy=new TCHAR[1+_tcslen(psz)];
441 _tcscpy(pszCopy,psz);
442 pWnd->PostMessage(WM_TESTOUTPUT,(WPARAM)pszCopy,0);
446 LRESULT CRunTestsSheet::OnTestOutput(WPARAM wParam, LPARAM lParam)
448 UNUSED_ALWAYS(lParam);
449 LPTSTR psz=(LPTSTR)wParam;
450 outputpage.AddText(psz);
455 void CRunTestsSheet::OnProperties()
457 CPropertiesDialog dlg(m_bHideTarget,m_bHideRemoteControls);
458 dlg.m_strTarget=m_strTarget;
459 dlg.m_nTimeout=m_nTimeout;
460 dlg.m_nDownloadTimeout=m_nDownloadTimeout;
461 dlg.m_nTimeoutType=m_nTimeoutType;
462 dlg.m_nDownloadTimeoutType=m_nDownloadTimeoutType;
463 dlg.m_bRemote=m_bRemote;
464 dlg.m_bSerial=m_bSerial;
465 dlg.m_strPort=m_strPort;
467 dlg.m_strLocalTCPIPHost=m_strLocalTCPIPHost;
468 dlg.m_nLocalTCPIPPort=m_nLocalTCPIPPort;
469 dlg.m_nReset=m_nReset;
470 dlg.m_strReset=m_strReset;
471 dlg.m_strResourceHost=m_strResourceHost;
472 dlg.m_nResourcePort=m_nResourcePort;
473 dlg.m_strRemoteHost=m_strRemoteHost;
474 dlg.m_nRemotePort=m_nRemotePort;
475 dlg.m_strPort=m_strPort;
476 dlg.m_bFarmed=m_bFarmed;
477 if(IDOK==dlg.DoModal()){
478 m_strTarget=(LPCTSTR)dlg.m_strTarget;
479 m_nTimeout=dlg.m_nTimeout;
480 m_nDownloadTimeout=dlg.m_nDownloadTimeout;
481 m_nTimeoutType=dlg.m_nTimeoutType;
482 m_nDownloadTimeoutType=dlg.m_nDownloadTimeoutType;
483 m_bRemote=dlg.m_bRemote;
484 m_bSerial=dlg.m_bSerial;
485 m_strPort=(LPCTSTR)dlg.m_strPort;
487 m_strLocalTCPIPHost=(LPCTSTR)dlg.m_strLocalTCPIPHost;
488 m_nLocalTCPIPPort=dlg.m_nLocalTCPIPPort;
489 m_nReset=dlg.m_nReset;
490 m_strReset=(LPCTSTR)dlg.m_strReset;
491 m_strResourceHost=(LPCTSTR)dlg.m_strResourceHost;
492 m_nResourcePort=dlg.m_nResourcePort;
493 m_strRemoteHost=(LPCTSTR)dlg.m_strRemoteHost;
494 m_nRemotePort=dlg.m_nRemotePort;
495 m_bFarmed=dlg.m_bFarmed;
497 m_pInitFunc(&m_prop,true);
502 void CRunTestsSheet::OnClose()
505 WINDOWPLACEMENT wndpl;
506 wndpl.length = sizeof(WINDOWPLACEMENT);
507 GetWindowPlacement(&wndpl);
508 if(!IsWindowVisible()){
509 wndpl.showCmd=SW_HIDE;
511 m_strPlacement.Format(_T("%d %d %d %d %d"),
512 wndpl.rcNormalPosition.left,
513 wndpl.rcNormalPosition.top,
514 wndpl.rcNormalPosition.right,
515 wndpl.rcNormalPosition.bottom,
517 m_pInitFunc(&m_prop,true);
528 void CRunTestsSheet::OnSysCommand(UINT nID, LPARAM lParam)
533 CeCosPropertySheet::OnSysCommand(nID, lParam);
537 void CRunTestsSheet::OnSize(UINT nType, int cx, int cy)
539 // WS_OVERLAPPEDWINDOW would preclude caption bar help button
540 ModifyStyle(0,WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME ,0);
541 CeCosPropertySheet::OnSize(nType, cx, cy);
542 if(SIZE_MINIMIZED!=nType){
545 TRACE(_T("OnSize(%d) left=%d top=%d right=%d bottom=%d ar=%d\n"),nType,rect.left,rect.top,rect.right,rect.bottom,m_bAllowResizing);
547 m_rcOffset.left =rect.left-m_rcPrev.left;
548 m_rcOffset.right =rect.right-m_rcPrev.right;
549 m_rcOffset.top =rect.top-m_rcPrev.top;
550 m_rcOffset.bottom=rect.bottom-m_rcPrev.bottom;
554 if(m_bAllowResizing){
557 MoveWindow(GetTabControl(),Stretch);
558 CRect rc[sizeof(arIds)/sizeof(arIds[0])];
560 GetWindowRect(rcSheet);
561 for(int i=0;i<sizeof(arIds)/sizeof(arIds[0]);i++){
562 CWnd *pWnd=GetDlgItem(arIds[i]);
564 pWnd->GetWindowRect(rc[i]);
565 ScreenToClient(rc[i]);
566 MoveWindow(pWnd,BottomRight,FALSE);
570 for(i=0;i<sizeof(arIds)/sizeof(arIds[0]);i++){
571 CWnd *pWnd=GetDlgItem(arIds[i]);
574 InvalidateRect(rc[i]);
576 TRACE(_T("Failed to find window id=%x\n"),arIds[i]);
580 for(i=0;i<GetPageCount();i++){
581 MoveWindow(GetPage(i),Stretch);
588 void CRunTestsSheet::MoveWindow(CWnd *pWnd, AffinityType Affinity,bool bRepaint)
590 if(m_bAllowResizing&&pWnd){
591 TRACE(_T("MoveWindow left=%d top=%d right=%d bottom=%d\n"),m_rcOffset.left,m_rcOffset.top,m_rcOffset.right,m_rcOffset.bottom);
593 pWnd->GetWindowRect(rect);
594 pWnd->GetParent()->ScreenToClient(rect);
595 TRACE(_T(" left=%d top=%d right=%d bottom=%d"),rect.left,rect.top,rect.right,rect.bottom);
596 int nHeight=rect.Height();
597 int nWidth=rect.Width();
601 rect.right +=m_rcOffset.Width();
602 rect.bottom+=m_rcOffset.Height();
603 rect.top =rect.bottom-nHeight;
604 rect.left=rect.right -nWidth;
607 rect.right +=m_rcOffset.Width();
608 rect.left=rect.right -nWidth;
611 rect.top +=m_rcOffset.Height();
612 rect.right=rect.left+nWidth;
617 rect.right +=m_rcOffset.Width();
618 rect.bottom+=m_rcOffset.Height();
621 TRACE(_T(" -> left=%d top=%d right=%d bottom=%d\n"),rect.left,rect.top,rect.right,rect.bottom);
622 pWnd->MoveWindow(rect,bRepaint);
626 void CRunTestsSheet::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
628 lpMMI->ptMinTrackSize.x = m_cxMin;
629 lpMMI->ptMinTrackSize.y = 175;
630 CeCosPropertySheet::OnGetMinMaxInfo(lpMMI);
633 LRESULT CRunTestsSheet::OnKickIdle(WPARAM, LPARAM)
635 // We could use WM_KICKIDLE to drive CMDUI messages, but in fact we just
636 // use an OnKickIdle handler directly (here and in the pages) to control
638 bool bEnableRunStop=false;
639 bool bEnableProperties=false;
645 bEnableProperties=true;
648 bEnableRunStop=executionpage.SomeTestsSelected();
649 bEnableProperties=true;
652 GetDlgItem(IDOK)->EnableWindow(bEnableRunStop);
653 GetDlgItem(ID_APPLY_NOW)->EnableWindow(bEnableProperties);
654 SendMessageToDescendants(WM_KICKIDLE, 0, 0, FALSE, FALSE);
658 BOOL CRunTestsSheet::PreTranslateMessage(MSG* pMsg)
660 if(WM_KEYDOWN==pMsg->message && VK_ESCAPE==pMsg->wParam){
661 return TRUE;// escape character handled
663 return CeCosPropertySheet::PreTranslateMessage(pMsg);
666 void CRunTestsSheet::SetTarget(LPCTSTR pszTarget)
668 m_strTarget=pszTarget;
672 void CRunTestsSheet::HideRemoteControls()
674 m_bHideRemoteControls=true;
677 void CRunTestsSheet::Populate(LPCTSTR pszFile,bool bSelect/*=true*/)
679 executionpage.m_arstrPreLoad.SetAt(pszFile,bSelect?this:0);
683 int CRunTestsSheet::DoModal()
686 return CeCosPropertySheet::DoModal();
689 void CRunTestsSheet::PostNcDestroy()
694 CeCosPropertySheet::PostNcDestroy();
698 void CRunTestsSheet::OnTimer(UINT nIDEvent)
700 SendMessage(WM_KICKIDLE,0,0);
701 CeCosPropertySheet::OnTimer(nIDEvent);