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.

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