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.

515 lines
13 KiB

  1. //****************************************************************************
  2. //
  3. // File: joymisc.c
  4. // Content: Misc routines used by calibration and testing dialogs
  5. // History:
  6. // Date By Reason
  7. // ==== == ======
  8. // 11-dec-94 craige split out of joycpl.c
  9. // 15-dec-94 craige allow N joysticks
  10. // 18-dec-94 craige process U&V
  11. // 04-mar-95 craige bug 13147: crosshair should erase background color
  12. //
  13. // Copyright (c) Microsoft Corporation 1994-1995
  14. //
  15. //****************************************************************************
  16. #pragma pack (8)
  17. #include "stdafx.h"
  18. #include "joycpl.h"
  19. #include "assert.h"
  20. #include "baseids.h"
  21. #include "comstr.h"
  22. #include "pov.h"
  23. #define DELTA 5
  24. // ADJ_VAL is used to convert a joystick position into a value in a new range
  25. #define ADJ_VAL( a, pos, range ) (((pos-(pgv->joyRange.jpMin.dw##a))*range) / (pgv->joyRange.jpMax.dw##a-pgv->joyRange.jpMin.dw##a+1))
  26. DWORD ADJ_VALX( DWORD pos, DWORD range, DWORD dwMaxX)
  27. {
  28. if (dwMaxX == 0)
  29. dwMaxX++;
  30. DWORD nRet = (pos*range) / dwMaxX;
  31. nRet += DELTA;
  32. return nRet;
  33. }
  34. DWORD ADJ_VALY( DWORD pos, DWORD range, DWORD dwMaxY )
  35. {
  36. if (dwMaxY == 0)
  37. dwMaxY++;
  38. DWORD nRet = (pos*range) / dwMaxY;
  39. nRet += DELTA;
  40. return nRet;
  41. }
  42. // setOEMWindowText - set window text with an OEM string
  43. static void setOEMWindowText( HWND hwnd, int id, LPSTR str )
  44. {
  45. assert(hwnd);
  46. HWND hwndctl;
  47. if( str[0] != 0 )
  48. {
  49. hwndctl = GetDlgItem( hwnd, id );
  50. ASSERT (::IsWindow(hwndctl));
  51. if( hwndctl != NULL )
  52. {
  53. SetWindowText( hwndctl, str );
  54. }
  55. }
  56. } /* setOEMWindowText */
  57. // SetOEMText - set OEM defined text in the dialogs
  58. void SetOEMText( LPGLOBALVARS pgv, HWND hwnd, BOOL istest )
  59. {
  60. ASSERT(pgv);
  61. ASSERT (::IsWindow(hwnd));
  62. DWORD type;
  63. char str[MAX_STR];
  64. char res[MAX_STR];
  65. HINSTANCE hinst;
  66. int id;
  67. LPSTR pwincap;
  68. LPJOYDATA pjd;
  69. pjd = pgv->pjd;
  70. ASSERT(pjd);
  71. // get the default window caption. this will be replaced by an OEM string if it is avaliable.
  72. hinst = GetResourceInstance();
  73. if( istest )
  74. {
  75. id = IDS_JOYTESTCAPN;
  76. }
  77. else
  78. {
  79. id = IDS_JOYCALCAPN;
  80. }
  81. if( !LoadString( hinst, id, str, sizeof( str ) ) )
  82. res[0] = 0;
  83. else
  84. wsprintf( res, str, pgv->iJoyId+1 );
  85. pwincap = res;
  86. // if this is an OEM joystick, use any strings that they may have defined
  87. if( pgv->joyHWCurr.dwUsageSettings & JOY_US_ISOEM )
  88. {
  89. type = pgv->joyHWCurr.dwType - JOY_HW_LASTENTRY;
  90. // set up labels under each of the controls
  91. setOEMWindowText( hwnd, IDC_JOYLIST1_LABEL, pjd->oemList[type].xy_label );
  92. setOEMWindowText( hwnd, IDC_JOYLIST2_LABEL, pjd->oemList[type].z_label );
  93. setOEMWindowText( hwnd, IDC_JOYLIST3_LABEL, pjd->oemList[type].r_label );
  94. setOEMWindowText( hwnd, IDC_JOYLIST4_LABEL, pjd->oemList[type].u_label );
  95. setOEMWindowText( hwnd, IDC_JOYLIST5_LABEL, pjd->oemList[type].v_label );
  96. setOEMWindowText( hwnd, IDC_JOYPOV_LABEL, pjd->oemList[type].pov_label );
  97. if( istest )
  98. {
  99. // set the various caption and description fields in the test dlg
  100. // setOEMWindowText( hwnd, IDC_TEXT_1, pjd->oemList[type].testmove_desc );
  101. // setOEMWindowText( hwnd, IDC_TEXT_2, pjd->oemList[type].testbutton_desc );
  102. // setOEMWindowText( hwnd, IDC_GROUPBOX, pjd->oemList[type].testmove_cap );
  103. // setOEMWindowText( hwnd, IDC_GROUPBOX_2, pjd->oemList[type].testbutton_cap );
  104. if( pjd->oemList[type].testwin_cap[0] != 0 )
  105. {
  106. pwincap = pjd->oemList[type].testwin_cap;
  107. }
  108. }
  109. else
  110. {
  111. // set the various caption and description fields in the calibration dialog
  112. setOEMWindowText( hwnd, IDC_GROUPBOX, pjd->oemList[type].cal_cap );
  113. if( pjd->oemList[type].calwin_cap[0] != 0 )
  114. pwincap = pjd->oemList[type].calwin_cap;
  115. }
  116. }
  117. // set the window caption
  118. if( pwincap[0] != 0 )
  119. SetWindowText( hwnd, pwincap );
  120. } /* SetOEMText */
  121. // ShowControls - show Z and R controls, based on configuration info
  122. void ShowControls( LPJOYREGHWCONFIG pcfg, HWND hwnd )
  123. {
  124. assert(pcfg);
  125. // ADDED BY CML 2/21/96: added window *enabling*
  126. HWND hwndctl;
  127. UINT nShow;
  128. // Z axis
  129. nShow = pcfg->hws.dwFlags & JOY_HWS_HASZ ? SW_SHOW : SW_HIDE;
  130. hwndctl = GetDlgItem(hwnd, IDC_JOYLIST2);
  131. ASSERT (::IsWindow(hwndctl));
  132. ShowWindow(hwndctl, nShow);
  133. hwndctl = GetDlgItem(hwnd, IDC_JOYLIST2_LABEL);
  134. ASSERT (::IsWindow(hwndctl));
  135. ShowWindow(hwndctl, nShow);
  136. // R axis
  137. nShow = pcfg->hws.dwFlags & JOY_HWS_HASR
  138. || pcfg->dwUsageSettings & JOY_US_HASRUDDER
  139. ? SW_SHOW
  140. : SW_HIDE;
  141. hwndctl = GetDlgItem(hwnd, IDC_JOYLIST3);
  142. ASSERT (::IsWindow(hwndctl));
  143. ShowWindow(hwndctl, nShow);
  144. hwndctl = GetDlgItem(hwnd, IDC_JOYLIST3_LABEL);
  145. ASSERT (::IsWindow(hwndctl));
  146. ShowWindow(hwndctl, nShow);
  147. // POV
  148. nShow = pcfg->hws.dwFlags & JOY_HWS_HASPOV ? SW_SHOW : SW_HIDE;
  149. hwndctl = GetDlgItem( hwnd, IDC_JOYPOV );
  150. ASSERT (::IsWindow(hwndctl));
  151. ShowWindow( hwndctl, nShow);
  152. // U axis
  153. nShow = pcfg->hws.dwFlags & JOY_HWS_HASU ? SW_SHOW : SW_HIDE;
  154. if (hwndctl = GetDlgItem(hwnd, IDC_JOYLIST4))
  155. {
  156. ASSERT (::IsWindow(hwndctl));
  157. ShowWindow(hwndctl, nShow);
  158. hwndctl = GetDlgItem(hwnd, IDC_JOYLIST4_LABEL);
  159. ASSERT (::IsWindow(hwndctl));
  160. ShowWindow(hwndctl, nShow);
  161. }
  162. // V axis
  163. nShow = pcfg->hws.dwFlags & JOY_HWS_HASV ? SW_SHOW : SW_HIDE;
  164. if (hwndctl = GetDlgItem(hwnd, IDC_JOYLIST5))
  165. {
  166. ASSERT (::IsWindow(hwndctl));
  167. ShowWindow(hwndctl, nShow);
  168. hwndctl = GetDlgItem(hwnd, IDC_JOYLIST5_LABEL);
  169. ASSERT (::IsWindow(hwndctl));
  170. ShowWindow(hwndctl, nShow);
  171. }
  172. // END ADD
  173. } /* ShowControls */
  174. /*
  175. * JoyError - error reading the joystick
  176. */
  177. BOOL JoyError( HWND hwnd )
  178. {
  179. assert(hwnd);
  180. char szTitle[STR_LEN_32];
  181. char szMessage[STR_LEN_128];
  182. if (pszCommonString->LoadString(IDS_JOYREADERROR) == 0)
  183. {
  184. OutputDebugString("GCDEF.DLL: WARING: Unable to load string IDS_JOYREADERROR!\n");
  185. return FALSE;
  186. }
  187. lstrcpy( szTitle, (LPCTSTR)*pszCommonString);
  188. if (pszCommonString->LoadString(IDS_JOYUNPLUGGED) == 0)
  189. {
  190. OutputDebugString("GCDEF.DLL: WARING: Unable to load string IDS_JOYREADERROR!\n");
  191. return FALSE;
  192. }
  193. lstrcpy( szMessage, (LPCTSTR)*pszCommonString);
  194. if (MessageBox( hwnd, szMessage, szTitle,
  195. MB_RETRYCANCEL | MB_ICONERROR | MB_TASKMODAL ) == IDCANCEL)
  196. {
  197. // terminate the dialog if we give up
  198. PostMessage( GetParent(hwnd), WM_COMMAND, IDCANCEL, 0 );
  199. return FALSE;
  200. }
  201. return TRUE;
  202. } // JoyError
  203. /*
  204. * ChangeIcon - change the icon of a static control
  205. */
  206. void ChangeIcon( HWND hwnd, int idi, int idc )
  207. {
  208. assert(hwnd);
  209. HINSTANCE hinst;
  210. HICON hicon;
  211. HICON holdicon;
  212. hinst = GetResourceInstance();
  213. assert(hinst);
  214. hicon = LoadIcon( hinst, MAKEINTRESOURCE(idi) );
  215. assert(hicon);
  216. if( hicon != NULL )
  217. {
  218. HWND hDlgItem = GetDlgItem(hwnd,idc);
  219. ASSERT (::IsWindow(hDlgItem));
  220. holdicon = Static_SetIcon( hDlgItem, hicon );
  221. if( holdicon != NULL )
  222. DestroyIcon( holdicon );
  223. }
  224. } /* ChangeIcon */
  225. /*
  226. * CauseRedraw - cause test or calibrate dialogs to redraw their controls
  227. */
  228. void CauseRedraw( LPJOYINFOEX pji, BOOL do_buttons )
  229. {
  230. assert(pji);
  231. pji->dwXpos = (DWORD) -1;
  232. pji->dwYpos = (DWORD) -1;
  233. pji->dwZpos = (DWORD) -1;
  234. pji->dwRpos = (DWORD) -1;
  235. pji->dwPOV = JOY_POVCENTERED;
  236. if( do_buttons ) {
  237. pji->dwButtons = ALL_BUTTONS;
  238. }
  239. } /* CauseRedraw */
  240. /*
  241. * fillBar - fill the bar for indicating Z or R info
  242. */
  243. static void fillBar( LPGLOBALVARS pgv, HWND hwnd, DWORD pos, int id )
  244. {
  245. assert(pgv);
  246. HWND hwlb;
  247. RECT r;
  248. HDC hdc;
  249. int height;
  250. LPJOYDATA pjd;
  251. pjd = pgv->pjd;
  252. assert(pjd);
  253. // scale the height to be inside the bar window
  254. hwlb = GetDlgItem( hwnd, id );
  255. ASSERT (::IsWindow(hwlb));
  256. if( hwlb == NULL )
  257. return;
  258. hdc = GetDC( hwlb );
  259. if( hdc == NULL )
  260. return;
  261. GetClientRect( hwlb, &r );
  262. switch( id )
  263. {
  264. case IDC_JOYLIST2:
  265. height = ADJ_VAL( Z, pos, r.bottom );
  266. break;
  267. case IDC_JOYLIST3:
  268. height = ADJ_VAL( R, pos, r.bottom );
  269. break;
  270. case IDC_JOYLIST4:
  271. height = ADJ_VAL( U, pos, r.bottom );
  272. break;
  273. case IDC_JOYLIST5:
  274. height = ADJ_VAL( V, pos, r.bottom );
  275. break;
  276. }
  277. // fill in the inactive area
  278. r.top = height;
  279. FillRect( hdc, &r, pjd->hbUp );
  280. // fill in the active area
  281. r.top = 0;
  282. r.bottom = height;
  283. FillRect( hdc, &r, pjd->hbDown );
  284. ReleaseDC( hwlb, hdc );
  285. } /* fillBar */
  286. // drawCross - draw a cross in the position box
  287. static void drawCross( HDC hdc, int x, int y, int obj )
  288. {
  289. HPEN hpen;
  290. HPEN holdpen;
  291. assert(hdc);
  292. if( hdc == NULL )
  293. return;
  294. if( obj )
  295. {
  296. COLORREF cr;
  297. cr = GetSysColor( obj ); // was COLOR_WINDOW
  298. hpen = CreatePen( PS_SOLID, 0, cr );
  299. }
  300. else
  301. {
  302. hpen = (struct HPEN__ *) GetStockObject( obj );
  303. }
  304. if ( hpen == NULL )
  305. {
  306. return;
  307. }
  308. holdpen = (struct HPEN__ *) SelectObject( hdc, hpen );
  309. MoveToEx( hdc, x-(DELTA-1), y, NULL );
  310. LineTo( hdc, x+DELTA, y );
  311. MoveToEx( hdc, x, y-(DELTA-1), NULL );
  312. LineTo( hdc, x, y+DELTA );
  313. SelectObject( hdc, holdpen );
  314. if( obj ) {
  315. DeleteObject( hpen );
  316. }
  317. } /* drawCross */
  318. #define FILLBAR( a, id ) \
  319. /* \
  320. * make sure we aren't out of alleged range \
  321. */ \
  322. if( pji->dw##a##pos > pgv->joyRange.jpMax.dw##a ) { \
  323. pji->dw##a##pos = pgv->joyRange.jpMax.dw##a; \
  324. } else if( pji->dw##a##pos < pgv->joyRange.jpMin.dw##a ) { \
  325. pji->dw##a##pos = pgv->joyRange.jpMin.dw##a; \
  326. } \
  327. \
  328. /* \
  329. * fill the bar if we haven't moved since last time \
  330. */ \
  331. if( pji->dw##a##pos != poji->dw##a##pos ) { \
  332. fillBar( pgv, hwnd, pji->dw##a##pos, id ); \
  333. poji->dw##a##pos = pji->dw##a##pos; \
  334. }
  335. // DoJoyMove - process movement for the joystick
  336. void DoJoyMove( LPGLOBALVARS pgv, HWND hwnd, LPJOYINFOEX pji, LPJOYINFOEX poji, DWORD drawflags )
  337. {
  338. HWND hwlb;
  339. RECT rc;
  340. int width, height;
  341. int x,y;
  342. static BOOL bFirstPoll = TRUE;
  343. assert(pgv);
  344. assert(hwnd);
  345. assert(pji);
  346. assert(poji);
  347. // draw the cross in the XY box if needed
  348. if( drawflags & JOYMOVE_DRAWXY )
  349. {
  350. // make sure we aren't out of alleged range
  351. if( pji->dwXpos > pgv->joyRange.jpMax.dwX )
  352. pji->dwXpos = pgv->joyRange.jpMax.dwX;
  353. else if( pji->dwXpos < pgv->joyRange.jpMin.dwX )
  354. pji->dwXpos = pgv->joyRange.jpMin.dwX;
  355. if( pji->dwYpos > pgv->joyRange.jpMax.dwY )
  356. pji->dwYpos = pgv->joyRange.jpMax.dwY;
  357. else if( pji->dwYpos < pgv->joyRange.jpMin.dwY )
  358. pji->dwYpos = pgv->joyRange.jpMin.dwY;
  359. // convert info to (x,y) position in window
  360. hwlb = GetDlgItem( hwnd, IDC_JOYLIST1 );
  361. ASSERT(::IsWindow(hwlb));
  362. GetClientRect( hwlb, &rc );
  363. height = rc.bottom - rc.top-2*DELTA;
  364. width = rc.right - rc.left-2*DELTA;
  365. x = ADJ_VALX( pji->dwXpos, width, pgv->joyRange.jpMax.dwX );
  366. y = ADJ_VALY( pji->dwYpos, height, pgv->joyRange.jpMax.dwY );
  367. // only draw the cross if it has moved since last time
  368. if( x != (int) poji->dwXpos || y != (int) poji->dwYpos )
  369. {
  370. HDC hwlbDC;
  371. hwlbDC = GetDC( hwlb );
  372. if( hwlbDC == NULL ) {
  373. return;
  374. }
  375. if( poji->dwXpos != (DWORD) -1 )
  376. {
  377. drawCross( hwlbDC, (int) poji->dwXpos, (int) poji->dwYpos, COLOR_WINDOW );
  378. } else {
  379. FillRect( hwlbDC, &rc, (HBRUSH)(COLOR_WINDOW+1) );
  380. }
  381. if( !bFirstPoll ) {
  382. drawCross( hwlbDC, (int) x, (int) y, COLOR_WINDOWTEXT );
  383. } else {
  384. bFirstPoll = FALSE;
  385. }
  386. ReleaseDC( hwlb, hwlbDC );
  387. poji->dwXpos = x;
  388. poji->dwYpos = y;
  389. }
  390. }
  391. // draw Z bar if needed
  392. if ( drawflags & JOYMOVE_DRAWZ )
  393. {
  394. FILLBAR( Z, IDC_JOYLIST2 );
  395. }
  396. // draw R bar if needed
  397. if( drawflags & JOYMOVE_DRAWR )
  398. {
  399. FILLBAR( R, IDC_JOYLIST3 );
  400. }
  401. // draw U bar if needed
  402. if( drawflags & JOYMOVE_DRAWU )
  403. {
  404. FILLBAR( U, IDC_JOYLIST4 );
  405. }
  406. // draw V bar if needed
  407. if( drawflags & JOYMOVE_DRAWV )
  408. {
  409. FILLBAR( V, IDC_JOYLIST5 );
  410. }
  411. } /* DoJoyMove */