xref: /reactos/base/applications/dxdiag/input.c (revision e3e46b2b)
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