1 /*
2 * PROJECT: ReactX Diagnosis Application
3 * LICENSE: LGPL - See COPYING in the top level directory
4 * FILE: base/applications/dxdiag/input.c
5 * PURPOSE: ReactX diagnosis input page
6 * COPYRIGHT: Copyright 2008 Johannes Anderwald
7 *
8 */
9
10 #include "precomp.h"
11
12 #include <dinput.h>
13
14 typedef struct
15 {
16 HWND hwndDlg;
17 IDirectInput8W * pObj;
18 HWND hDevList;
19 HWND hPortTree;
20 INT Count;
21 }INPUT_DIALOG_CONTEXT, *PINPUT_DIALOG_CONTEXT;
22
23
DirectInputEnumDevCb(LPCDIDEVICEINSTANCEW lpddi,LPVOID pvRef)24 BOOL CALLBACK DirectInputEnumDevCb(
25 LPCDIDEVICEINSTANCEW lpddi,
26 LPVOID pvRef
27 )
28 {
29 HRESULT hResult;
30 WCHAR szText[100];
31 IDirectInputDevice8W * pDev = NULL;
32 //DIPROPGUIDANDPATH GuidPath;
33 //DIPROPSTRING TypeName;
34 DIPROPDWORD VendorID;
35 DIDEVCAPS DevCaps;
36 DWORD dwProductID;
37 DWORD dwManufacturerID;
38 LVITEMW Item;
39 LRESULT lResult;
40
41 PINPUT_DIALOG_CONTEXT pContext = (PINPUT_DIALOG_CONTEXT)pvRef;
42
43 if (!pContext)
44 return DIENUM_STOP;
45
46 ZeroMemory(&Item, sizeof(LVITEMW));
47 Item.mask = LVIF_TEXT;
48 Item.pszText = (LPWSTR)lpddi->tszProductName;
49 Item.iItem = pContext->Count;
50 /* insert device item */
51 lResult = SendMessageW(pContext->hDevList, LVM_INSERTITEM, 0, (LPARAM)&Item);
52 if (lResult == -1)
53 return DIENUM_CONTINUE;
54
55 /* is the device attached */
56 szText[0] = L'\0';
57 hResult = pContext->pObj->lpVtbl->GetDeviceStatus(pContext->pObj, &lpddi->guidInstance);
58 if (hResult == DI_OK)
59 LoadStringW(hInst, IDS_DEVICE_STATUS_ATTACHED, szText, sizeof(szText) / sizeof(WCHAR));
60 else if (hResult == DI_NOTATTACHED)
61 LoadStringW(hInst, IDS_DEVICE_STATUS_MISSING, szText, sizeof(szText) / sizeof(WCHAR));
62 else
63 LoadStringW(hInst, IDS_DEVICE_STATUS_UNKNOWN, szText, sizeof(szText) / sizeof(WCHAR));
64
65 if (szText[0])
66 {
67 szText[(sizeof(szText) / sizeof(WCHAR))-1] = L'\0';
68 Item.iSubItem = 1;
69 Item.pszText = szText;
70 SendMessageW(pContext->hDevList, LVM_SETITEM, lResult, (LPARAM)&Item);
71 }
72
73 hResult = pContext->pObj->lpVtbl->CreateDevice(pContext->pObj, &lpddi->guidInstance, &pDev, NULL);
74
75 if (hResult != DI_OK)
76 return DIENUM_STOP;
77
78 ZeroMemory(&VendorID, sizeof(DIPROPDWORD));
79 VendorID.diph.dwSize = sizeof(DIPROPDWORD);
80 VendorID.diph.dwHeaderSize = sizeof(DIPROPHEADER);
81
82 hResult = pDev->lpVtbl->GetProperty(pDev, DIPROP_VIDPID, (LPDIPROPHEADER)&VendorID);
83 if (hResult == DI_OK)
84 {
85 /* set manufacturer id */
86 dwManufacturerID = LOWORD(VendorID.dwData);
87 wsprintfW(szText, L"0x%04X", dwManufacturerID);
88 Item.iSubItem = 3;
89 SendMessageW(pContext->hDevList, LVM_SETITEM, lResult, (LPARAM)&Item);
90 /* set product id */
91 dwProductID = HIWORD(VendorID.dwData);
92 wsprintfW(szText, L"0x%04X", dwProductID);
93 Item.iSubItem = 4;
94 SendMessageW(pContext->hDevList, LVM_SETITEM, lResult, (LPARAM)&Item);
95 }
96 else
97 {
98 szText[0] = L'\0';
99 LoadStringW(hInst, IDS_NOT_APPLICABLE, szText, sizeof(szText) / sizeof(WCHAR));
100 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
101 /* set manufacturer id */
102 Item.iSubItem = 3;
103 SendMessageW(pContext->hDevList, LVM_SETITEM, lResult, (LPARAM)&Item);
104 /* set product id */
105 Item.iSubItem = 4;
106 SendMessageW(pContext->hDevList, LVM_SETITEM, lResult, (LPARAM)&Item);
107 }
108
109 /* check for force feedback support */
110 DevCaps.dwSize = sizeof(DIDEVCAPS); // use DIDEVCAPS_DX3 for DX3 support
111 hResult = pDev->lpVtbl->GetCapabilities(pDev, &DevCaps);
112 szText[0] = L'\0';
113 if (hResult == DI_OK)
114 {
115 if (DevCaps.dwFlags & DIDC_FORCEFEEDBACK)
116 LoadStringW(hInst, IDS_OPTION_YES, szText, sizeof(szText)/sizeof(WCHAR));
117 else
118 LoadStringW(hInst, IDS_NOT_APPLICABLE, szText, sizeof(szText)/sizeof(WCHAR));
119 }
120 else
121 {
122 LoadStringW(hInst, IDS_NOT_APPLICABLE, szText, sizeof(szText)/sizeof(WCHAR));
123 }
124
125 Item.iSubItem = 5;
126 SendMessageW(pContext->hDevList, LVM_SETITEM, lResult, (LPARAM)&Item);
127
128
129 #if 0
130 ZeroMemory(&GuidPath, sizeof(DIPROPGUIDANDPATH));
131 GuidPath.diph.dwSize = sizeof(DIPROPGUIDANDPATH);
132 GuidPath.diph.dwHeaderSize = sizeof(DIPROPHEADER);
133 GuidPath.diph.dwHow = DIPH_DEVICE;
134 hResult = pDev->lpVtbl->GetProperty(pDev, DIPROP_GUIDANDPATH, (LPDIPROPHEADER)&GuidPath);
135
136 ZeroMemory(&TypeName, sizeof(TypeName));
137 TypeName.diph.dwSize = sizeof(TypeName);
138 TypeName.diph.dwHeaderSize = sizeof(DIPROPHEADER);
139 TypeName.diph.dwHow = DIPH_DEVICE;
140 hResult = pDev->lpVtbl->GetProperty(pDev, DIPROP_GETPORTDISPLAYNAME, (LPDIPROPHEADER)&TypeName);
141
142
143 #endif
144
145
146 pDev->lpVtbl->Release(pDev);
147 pContext->Count++;
148
149
150 return DIENUM_CONTINUE;
151 }
152
153 VOID
InputPageInitListViewColumns(PINPUT_DIALOG_CONTEXT pContext)154 InputPageInitListViewColumns(PINPUT_DIALOG_CONTEXT pContext)
155 {
156 WCHAR szText[256];
157 LVCOLUMNW lvcolumn;
158 INT Index;
159
160
161 pContext->hDevList = GetDlgItem(pContext->hwndDlg, IDC_LIST_DEVICE);
162
163 /* Highlights the entire row instead of just the selected item in the first column.
164 This increases readability on the selected item in the list. */
165 SendMessage(pContext->hDevList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
166
167 ZeroMemory(&lvcolumn, sizeof(LVCOLUMNW));
168 lvcolumn.pszText = szText;
169 lvcolumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
170 lvcolumn.fmt = LVCFMT_LEFT;
171 lvcolumn.cx = 100;
172
173 for(Index = 0; Index < 6; Index++)
174 {
175 szText[0] = L'\0';
176 LoadStringW(hInst, IDS_DEVICE_NAME + Index, szText, sizeof(szText) / sizeof(WCHAR));
177 szText[(sizeof(szText) / sizeof(WCHAR))-1] = L'\0';
178 if (SendMessageW(pContext->hDevList, LVM_INSERTCOLUMNW, Index, (LPARAM)&lvcolumn) == -1)
179 return;
180 }
181 }
182
183 static
184 void
InitializeDirectInputDialog(HWND hwndDlg)185 InitializeDirectInputDialog(HWND hwndDlg)
186 {
187 INPUT_DIALOG_CONTEXT Context;
188 HRESULT hResult;
189 IDirectInput8W * pObj;
190
191 hResult = DirectInput8Create(hInst, DIRECTINPUT_VERSION, &IID_IDirectInput8W, (LPVOID*)&pObj, NULL);
192 if (hResult != DI_OK)
193 return;
194
195 ZeroMemory(&Context, sizeof(Context));
196 Context.pObj = pObj;
197 Context.hwndDlg = hwndDlg;
198 InputPageInitListViewColumns(&Context);
199 pObj->lpVtbl->EnumDevices(pObj, DI8DEVCLASS_ALL, DirectInputEnumDevCb, (PVOID)&Context, DIEDFL_ALLDEVICES);
200
201 pObj->lpVtbl->Release(pObj);
202 }
203
204
205
206 INT_PTR CALLBACK
InputPageWndProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)207 InputPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
208 {
209 UNREFERENCED_PARAMETER(lParam);
210 UNREFERENCED_PARAMETER(wParam);
211 switch (message) {
212 case WM_INITDIALOG:
213 {
214 SetWindowPos(hDlg, NULL, 10, 32, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
215 InitializeDirectInputDialog(hDlg);
216 return TRUE;
217 }
218 }
219
220 return FALSE;
221 }
222