Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

601 lines
23 KiB

  1. /*----------------------------------------------------------------------------*\
  2. | |
  3. | ta.c - Timer Device Driver Test Application |
  4. | |
  5. | |
  6. | History: |
  7. | |
  8. | Created Glenn Steffler (w-GlennS) 24-Jan-1990 |
  9. | |
  10. \*----------------------------------------------------------------------------*/
  11. /*----------------------------------------------------------------------------*\
  12. | |
  13. | i n c l u d e f i l e s |
  14. | |
  15. \*----------------------------------------------------------------------------*/
  16. #include <windows.h>
  17. #include <mmsystem.h>
  18. #include <port1632.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include "ta.h"
  22. /*----------------------------------------------------------------------------*\
  23. | |
  24. | g l o b a l v a r i a b l e s |
  25. | |
  26. \*----------------------------------------------------------------------------*/
  27. extern HWND hdlgDelay;
  28. static char szAppName[]="Timer Device Test Application";
  29. HANDLE hInstApp;
  30. HWND hwndApp;
  31. WORD wHandlerError = 0;
  32. BOOL bHandlerHit = FALSE; // was timer event handler hit since last
  33. int dyFont;
  34. int dxFont;
  35. HFONT hfontApp;
  36. HBRUSH hbrWindow;
  37. extern int nEvents;
  38. extern EVENTLIST EventList[];
  39. extern HWND hdlgModeless;
  40. LPTIMECALLBACK lpTimeCallback; // timer callback function
  41. FARPROC lpfnDelayDlg = NULL; // modeless Delay dialog function pointer
  42. BOOL fSystemTime = TRUE;
  43. BOOL fRealTime = TRUE;
  44. BOOL fFirstTime = TRUE;
  45. /*----------------------------------------------------------------------------*\
  46. | |
  47. | f u n c t i o n d e f i n i t i o n s |
  48. | |
  49. \*----------------------------------------------------------------------------*/
  50. LONG FAR PASCAL AppWndProc (HWND hwnd, unsigned uiMessage, UINT wParam, LONG lParam);
  51. BOOL fDialog(int id,HWND hwnd,FARPROC lpfn);
  52. LONG NEAR PASCAL AppCommand(HWND hwnd, unsigned msg, UINT wParam, LONG lParam);
  53. extern BOOL FAR PASCAL fnAboutDlg(
  54. HWND hDlg, unsigned uiMessage, UINT wParam, LONG lParam );
  55. extern BOOL FAR PASCAL fnDelayDlg(
  56. HWND hDlg, unsigned uiMessage, UINT wParam, LONG lParam );
  57. extern BOOL FAR PASCAL fnFileDlg(
  58. HWND hDlg, unsigned uiMessage, UINT wParam, LONG lParam );
  59. /*----------------------------------------------------------------------------*\
  60. | AppInit( hInst, hPrev) |
  61. | |
  62. | Description: |
  63. | This is called when the application is first loaded into |
  64. | memory. It performs all initialization that doesn't need to be done |
  65. | once per instance. |
  66. | |
  67. | Arguments: |
  68. | hInstance instance handle of current instance |
  69. | hPrev instance handle of previous instance |
  70. | |
  71. | Returns: |
  72. | TRUE if successful, FALSE if not |
  73. | |
  74. \*----------------------------------------------------------------------------*/
  75. BOOL AppInit(HANDLE hInst,HANDLE hPrev,UINT sw,LPSTR szCmdLine)
  76. {
  77. WNDCLASS cls;
  78. int dx,dy;
  79. char ach[80];
  80. HMENU hmenu;
  81. TEXTMETRIC tm;
  82. HDC hdc;
  83. /* Save instance handle for DialogBoxs */
  84. hInstApp = hInst;
  85. if (!hPrev) {
  86. /*
  87. * Register a class for the main application window
  88. */
  89. cls.hCursor = LoadCursor(NULL,IDC_ARROW);
  90. cls.hIcon = LoadIcon(hInst,MAKEINTATOM(ID_APP));
  91. cls.lpszMenuName = MAKEINTATOM(ID_APP);
  92. cls.lpszClassName = MAKEINTATOM(ID_APP);
  93. cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  94. cls.hInstance = hInst;
  95. cls.style = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  96. cls.lpfnWndProc = AppWndProc;
  97. cls.cbWndExtra = 0;
  98. cls.cbClsExtra = 0;
  99. if (!RegisterClass(&cls))
  100. return FALSE;
  101. }
  102. dx = GetSystemMetrics (SM_CXSCREEN);
  103. dy = GetSystemMetrics (SM_CYSCREEN);
  104. ////hfontApp = GetStockObject(ANSI_VAR_FONT);
  105. hfontApp = GetStockObject(ANSI_FIXED_FONT);
  106. hdc = GetDC(NULL);
  107. SelectObject(hdc, hfontApp);
  108. GetTextMetrics(hdc, &tm);
  109. dxFont = tm.tmAveCharWidth;
  110. dyFont = tm.tmHeight;
  111. ReleaseDC(NULL,hdc);
  112. hbrWindow = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  113. hwndApp = CreateWindow (MAKEINTATOM(ID_APP), // Class name
  114. szAppName, // Caption
  115. WS_OVERLAPPEDWINDOW, // Style bits
  116. CW_USEDEFAULT, 0, // Position
  117. ((2*dx)/3),dy/2, // Size
  118. (HWND)NULL, // Parent window (no parent)
  119. (HMENU)NULL, // use class menu
  120. (HANDLE)hInst, // handle to window instance
  121. (LPSTR)NULL // no params to pass on
  122. );
  123. ShowWindow(hwndApp,sw);
  124. lpTimeCallback = (LPTIMECALLBACK)MakeProcInstance(TimeCallback,hInst);
  125. return TRUE;
  126. }
  127. /*----------------------------------------------------------------------------*\
  128. | WinMain( hInst, hPrev, lpszCmdLine, cmdShow ) |
  129. | |
  130. | Description: |
  131. | The main procedure for the App. After initializing, it just goes |
  132. | into a message-processing loop qntil it gets a WM_QUIT message |
  133. | (meaning the app was closed). |
  134. | |
  135. | Arguments: |
  136. | hInst instance handle of this instance of the app |
  137. | hPrev instance handle of previous instance, NULL if first |
  138. | szCmdLine ->null-terminated command line |
  139. | cmdShow specifies how the window is initially displayed |
  140. | |
  141. | Returns: |
  142. | The exit code as specified in the WM_QUIT message. |
  143. | |
  144. \*----------------------------------------------------------------------------*/
  145. MMain(hInst, hPrev, szCmdLine, sw)
  146. {
  147. MSG msg;
  148. /* Call initialization procedure */
  149. if (!AppInit(hInst,hPrev,sw,szCmdLine))
  150. return FALSE;
  151. /* check for messages from Windows and process them */
  152. /* if no messages, perform some idle function */
  153. while(1) {
  154. if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) {
  155. if( hdlgModeless == 0 || !IsDialogMessage( hdlgModeless, &msg ) ) {
  156. /* got a message to process */
  157. if( msg.message == WM_QUIT ) break;
  158. TranslateMessage(&msg);
  159. DispatchMessage(&msg);
  160. }
  161. }
  162. else {
  163. Idle();
  164. }
  165. }
  166. DeleteObject(hbrWindow);
  167. return (msg.wParam);
  168. }
  169. }
  170. static LONG lError2=0l;
  171. static LONG lDelta=0l;
  172. static LONG lTDelta=0l;
  173. static LONG lErrorMax=0l;
  174. static LONG lErrorMin=0l;
  175. /*----------------------------------------------------------------------------*\
  176. | AppPaint(hwnd) |
  177. | |
  178. | Description: |
  179. | The paint function. Right now this does nothing. |
  180. | |
  181. | Arguments: |
  182. | hwnd window painting into |
  183. | |
  184. | Returns: |
  185. | nothing |
  186. | |
  187. \*----------------------------------------------------------------------------*/
  188. void PASCAL AppPaint(HWND hwnd, HDC hdc)
  189. {
  190. typedef struct tag_booga {
  191. int *pnValue;
  192. char *szDescription;
  193. } BOOGA;
  194. static BOOGA bgTell[] ={ { &wHandlerError, "Handler Error" },
  195. { &nEvents, "Number Of Events" }};
  196. RECT rc;
  197. char szText[100];
  198. int i;
  199. MMTIME mmt;
  200. DWORD ms;
  201. DWORD dw,dwRTC;
  202. LONG lError,lTError;
  203. BOOL fGetDC;
  204. int len;
  205. int hrs, min, sec;
  206. SYSTEMTIME Time;
  207. if (fGetDC = (hdc == NULL))
  208. hdc = GetDC(hwnd);
  209. SelectObject(hdc, hfontApp);
  210. GetClientRect(hwnd,&rc);
  211. SetTextColor(hdc,GetSysColor(COLOR_WINDOWTEXT));
  212. SetBkColor(hdc,GetSysColor(COLOR_WINDOW));
  213. rc.top = dxFont;
  214. rc.left = dxFont;
  215. rc.bottom = rc.top+dyFont;
  216. GetSystemTime(&Time);
  217. if (fSystemTime)
  218. {
  219. timeGetSystemTime(&mmt, sizeof(mmt));
  220. dwRTC = (Time.wSecond * 1000l) +
  221. (Time.wMinute * 1000l * 60l) +
  222. (Time.wHour * 1000l * 60l * 60l);
  223. if (fRealTime)
  224. {
  225. len = wsprintf(szText, "RealTime = [%08ld ms] %02d hrs %02d min %02d.000 sec",
  226. dwRTC,
  227. Time.wHour,
  228. Time.wMinute,
  229. Time.wSecond);
  230. ExtTextOut( hdc, rc.left, rc.top, ETO_OPAQUE, &rc, szText, len, NULL);
  231. rc.top = rc.bottom;
  232. rc.bottom += dyFont;
  233. dw = dwRTC;
  234. }
  235. mmt.u.ms += lDelta;
  236. lError = (long)dwRTC - (long)mmt.u.ms;
  237. if (lDelta == 0l)
  238. {
  239. lDelta = lError;
  240. mmt.u.ms += lDelta;
  241. }
  242. hrs = (WORD)(mmt.u.ms / (1000l*60l*60l));
  243. min = (WORD)(mmt.u.ms / (1000*60l)) % 60;
  244. sec = (WORD)(mmt.u.ms / 1000l) % 60;
  245. len = wsprintf( szText, "SysTime = [%08ld ms] %02d hrs %02d min %02d.%03d sec",
  246. mmt.u.ms,
  247. hrs,min,sec,
  248. (int)(mmt.u.ms % 1000L) );
  249. ExtTextOut( hdc, rc.left, rc.top, ETO_OPAQUE, &rc, szText, len, NULL);
  250. rc.top = rc.bottom;
  251. rc.bottom += dyFont;
  252. if (fFirstTime)
  253. {
  254. fFirstTime = FALSE;
  255. }
  256. else
  257. {
  258. lErrorMin = min(lErrorMin,lError);
  259. lErrorMax = max(lErrorMax,lError);
  260. }
  261. len = wsprintf( szText, "SysTime Error:%8ld ms Max:%8ld Min:%8ld delta: %8ld",
  262. -lError,
  263. -lErrorMin,
  264. -lErrorMax,
  265. lError-lError2);
  266. lError2 = lError;
  267. ExtTextOut( hdc, rc.left, rc.top, ETO_OPAQUE, &rc, szText, len, NULL);
  268. rc.top = rc.bottom;
  269. rc.bottom += dyFont;
  270. }
  271. for( i=0; i < sizeof(bgTell)/sizeof(BOOGA); i++ ) {
  272. if( *(bgTell[i].pnValue) ) {
  273. len = wsprintf( szText, "%ls = [%d] ",
  274. (LPSTR)bgTell[i].szDescription, *(bgTell[i].pnValue) );
  275. ExtTextOut( hdc, rc.left, rc.top, ETO_OPAQUE, &rc, szText, len, NULL);
  276. rc.top = rc.bottom;
  277. rc.bottom += dyFont;
  278. }
  279. }
  280. for( i=0; i < MAXEVENTS; i++ ) {
  281. if( EventList[i].bActive ) {
  282. len = wsprintf( szText, "Event %2.2x Count=[%ld]%c Errors=%ld (%d%%) dtime=%ld Min=%ld Max=%ld",
  283. (int)EventList[i].nID,
  284. EventList[i].dwCount,
  285. (char)(EventList[i].bHit ? '*' : '-'),
  286. EventList[i].dwError,
  287. EventList[i].dwCount ? (int)(EventList[i].dwError * 100 / EventList[i].dwCount) : 0,
  288. EventList[i].dtime,
  289. EventList[i].dtimeMin,
  290. EventList[i].dtimeMax );
  291. EventList[i].bHit = FALSE;
  292. ExtTextOut( hdc, rc.left, rc.top, ETO_OPAQUE, &rc, szText, len, NULL);
  293. rc.top = rc.bottom;
  294. rc.bottom += dyFont;
  295. }
  296. }
  297. i = rc.top;
  298. GetClientRect(hwnd,&rc);
  299. rc.top = i;
  300. FillRect(hdc, &rc, hbrWindow);
  301. ////ExtTextOut( hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
  302. if (fGetDC)
  303. ReleaseDC(hwnd,hdc);
  304. return;
  305. #undef BOOGA
  306. }
  307. /*----------------------------------------------------------------------------*\
  308. | Idle( void ) |
  309. | |
  310. | Description: |
  311. | Idle loop function...displays time values while windows idles |
  312. | |
  313. | Arguments: |
  314. | none |
  315. | |
  316. | Returns: |
  317. | nothing |
  318. | |
  319. \*----------------------------------------------------------------------------*/
  320. void PASCAL Idle( )
  321. {
  322. if(hwndApp && bHandlerHit || fSystemTime) {
  323. AppPaint( hwndApp, NULL );
  324. bHandlerHit = FALSE;
  325. }
  326. else
  327. WaitMessage();
  328. return;
  329. }
  330. /*----------------------------------------------------------------------------*\
  331. | |
  332. | w i n d o w p r o c s |
  333. | |
  334. \*----------------------------------------------------------------------------*/
  335. /*----------------------------------------------------------------------------*\
  336. | AppWndProc( hwnd, uiMessage, wParam, lParam ) |
  337. | |
  338. | Description: |
  339. | The window proc for the app's main (tiled) window. This processes all |
  340. | of the parent window's messages. |
  341. | |
  342. | Arguments: |
  343. | hwnd window handle for the window |
  344. | uiMessage message number |
  345. | wParam message-dependent |
  346. | lParam message-dependent |
  347. | |
  348. | Returns: |
  349. | 0 if processed, nonzero if ignored |
  350. | |
  351. \*----------------------------------------------------------------------------*/
  352. LONG FAR PASCAL AppWndProc(hwnd, msg, wParam, lParam)
  353. HWND hwnd;
  354. unsigned msg;
  355. UINT wParam;
  356. long lParam;
  357. {
  358. BOOL f;
  359. HDC hdc;
  360. PAINTSTRUCT ps;
  361. switch (msg) {
  362. case WM_CREATE:
  363. break;
  364. case WM_COMMAND:
  365. return AppCommand(hwnd,msg,wParam,lParam);
  366. case WM_CLOSE:
  367. hwndApp = NULL;
  368. if (hdlgDelay) {
  369. PostMessage (hdlgDelay,WM_CLOSE,0,0l);
  370. }
  371. break;
  372. case WM_DESTROY:
  373. PostQuitMessage (0);
  374. // FALL THRU AND DESTROY ALL REMAINING OBJECTS / TIMER EVENTS
  375. case WM_ENDSESSION:
  376. KillAllEvents();
  377. if( lpTimeCallback ) {
  378. FreeProcInstance(lpTimeCallback);
  379. lpTimeCallback = NULL;
  380. }
  381. if( lpfnDelayDlg ) {
  382. FreeProcInstance(lpfnDelayDlg);
  383. }
  384. break;
  385. case WM_ERASEBKGND:
  386. break;
  387. case WM_PAINT:
  388. BeginPaint(hwnd, &ps);
  389. AppPaint( hwnd, ps.hdc );
  390. EndPaint(hwnd, &ps);
  391. return 0L;
  392. case MM_TIMEEVENT:
  393. if( hdlgDelay != NULL )
  394. SendMessage(hdlgDelay,msg,wParam,lParam);
  395. break;
  396. }
  397. return DefWindowProc(hwnd,msg,wParam,lParam);
  398. }
  399. LONG NEAR PASCAL AppCommand (hwnd, msg, wParam, lParam)
  400. HWND hwnd;
  401. unsigned msg;
  402. UINT wParam;
  403. long lParam;
  404. {
  405. HANDLE hInst;
  406. switch(LOWORD(wParam))
  407. {
  408. case MENU_ABOUT:
  409. fDialog(ABOUTDLG,hwnd,fnAboutDlg);
  410. break;
  411. case MENU_DELAY:
  412. if( hdlgDelay ) {
  413. ShowWindow( hdlgDelay, SW_SHOWNORMAL );
  414. SetFocus( hdlgDelay );
  415. } else {
  416. hInst = GetWindowLong(hwnd,GWL_HINSTANCE);
  417. lpfnDelayDlg = MakeProcInstance(fnDelayDlg,hInst);
  418. hdlgModeless = CreateDialog(hInst,
  419. MAKEINTRESOURCE(DELAYDLG),hwnd,lpfnDelayDlg);
  420. }
  421. break;
  422. case MENU_TIME:
  423. fSystemTime = !fSystemTime;
  424. if (!fSystemTime)
  425. {
  426. fFirstTime = TRUE;
  427. }
  428. lTDelta = 0l;
  429. lDelta = lErrorMin = lErrorMax = 0l;
  430. break;
  431. case MENU_LOAD:
  432. case MENU_SAVE:
  433. if( fDialog(FILEDLG,hwnd,fnFileDlg) )
  434. // call function to Save/Load session
  435. break;
  436. break;
  437. case MENU_EXIT:
  438. PostMessage(hwnd,WM_CLOSE,0,0L);
  439. break;
  440. }
  441. return 0L;
  442. }
  443. /*----------------------------------------------------------------------------*\
  444. | fDialog(id,hwnd,lpfn) |
  445. | |
  446. | Description: |
  447. | This function displays a dialog box and returns the exit code. |
  448. | the function passed will have a proc instance made for it. |
  449. | |
  450. | Arguments: |
  451. | id resource id of dialog to display |
  452. | hwnd parent window of dialog |
  453. | lpfn dialog message function |
  454. | |
  455. | Returns: |
  456. | exit code of dialog (what was passed to EndDialog) |
  457. | |
  458. \*----------------------------------------------------------------------------*/
  459. BOOL fDialog(int id,HWND hwnd,FARPROC lpfn)
  460. {
  461. BOOL f;
  462. HANDLE hInst;
  463. hInst = GetWindowLong(hwnd,GWL_HINSTANCE);
  464. lpfn = MakeProcInstance(lpfn,hInst);
  465. f = DialogBox(hInst,MAKEINTRESOURCE(id),hwnd,lpfn);
  466. FreeProcInstance (lpfn);
  467. return f;
  468. }
  469. /*----------------------------------------------------------------------------*\
  470. \*----------------------------------------------------------------------------*/
  471. void FAR PASCAL PeriodicCallback( UINT wID, UINT msg, DWORD dwUser, DWORD dwTime, DWORD dw2)
  472. {
  473. int i = LOWORD(dwUser);
  474. DWORD time;
  475. bHandlerHit = TRUE;
  476. time = timeGetTime();
  477. EventList[i].dtime = time - EventList[i].time;
  478. EventList[i].dtimeMin = min(EventList[i].dtime,EventList[i].dtimeMin);
  479. EventList[i].dtimeMax = max(EventList[i].dtime,EventList[i].dtimeMax);
  480. EventList[i].time = time;
  481. EventList[i].dwCount++;
  482. EventList[i].bHit = TRUE;
  483. // if (abs((int)EventList[i].dtime-(int)EventList[i].teEvent.wDelay) > (int)EventList[i].teEvent.wResolution)
  484. // EventList[i].dwError++;
  485. }
  486. /*----------------------------------------------------------------------------*\
  487. \*----------------------------------------------------------------------------*/
  488. void FAR PASCAL OneShotCallback( UINT wID, UINT msg, DWORD dwUser, DWORD dwTime, DWORD dw2)
  489. {
  490. int i = LOWORD(dwUser);
  491. DWORD time;
  492. bHandlerHit = TRUE;
  493. time = timeGetTime();
  494. EventList[i].dtime = time - EventList[i].time;
  495. EventList[i].dtimeMin = min(EventList[i].dtime,EventList[i].dtimeMin);
  496. EventList[i].dtimeMax = max(EventList[i].dtime,EventList[i].dtimeMax);
  497. EventList[i].time = time;
  498. EventList[i].dwCount++;
  499. EventList[i].bHit = TRUE;
  500. // if (abs((int)EventList[i].dtime-(int)EventList[i].teEvent.wDelay) > (int)EventList[i].teEvent.wResolution)
  501. // EventList[i].dwError++;
  502. }