xref: /reactos/dll/directx/wine/dinput/config.c (revision 98e62237)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Copyright (c) 2011 Lucas Fialho Zawacki
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
5c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
6c2c66affSColin Finck  * License as published by the Free Software Foundation; either
7c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
8c2c66affSColin Finck  *
9c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
10c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12c2c66affSColin Finck  * Lesser General Public License for more details.
13c2c66affSColin Finck  *
14c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
15c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
16c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17c2c66affSColin Finck  */
18c2c66affSColin Finck 
197016dd6dSAmine Khaldi #define NONAMELESSUNION
207016dd6dSAmine Khaldi 
217016dd6dSAmine Khaldi #include "wine/unicode.h"
227016dd6dSAmine Khaldi #include "objbase.h"
23c2c66affSColin Finck #include "dinput_private.h"
247016dd6dSAmine Khaldi #include "device_private.h"
25c2c66affSColin Finck #include "resource.h"
26c2c66affSColin Finck 
27c2c66affSColin Finck typedef struct {
28c2c66affSColin Finck     int nobjects;
29c2c66affSColin Finck     IDirectInputDevice8W *lpdid;
30c2c66affSColin Finck     DIDEVICEINSTANCEW ddi;
31c2c66affSColin Finck     DIDEVICEOBJECTINSTANCEW ddo[256];
32c2c66affSColin Finck } DeviceData;
33c2c66affSColin Finck 
34c2c66affSColin Finck typedef struct {
35c2c66affSColin Finck     int ndevices;
36c2c66affSColin Finck     DeviceData *devices;
37c2c66affSColin Finck } DIDevicesData;
38c2c66affSColin Finck 
39c2c66affSColin Finck typedef struct {
40c2c66affSColin Finck     IDirectInput8W *lpDI;
41c2c66affSColin Finck     LPDIACTIONFORMATW lpdiaf;
42c2c66affSColin Finck     LPDIACTIONFORMATW original_lpdiaf;
43c2c66affSColin Finck     DIDevicesData devices_data;
44c2c66affSColin Finck     int display_only;
45c2c66affSColin Finck } ConfigureDevicesData;
46c2c66affSColin Finck 
47c2c66affSColin Finck /*
48c2c66affSColin Finck  * Enumeration callback functions
49c2c66affSColin Finck  */
50c2c66affSColin Finck static BOOL CALLBACK collect_objects(LPCDIDEVICEOBJECTINSTANCEW lpddo, LPVOID pvRef)
51c2c66affSColin Finck {
52c2c66affSColin Finck     DeviceData *data = (DeviceData*) pvRef;
53c2c66affSColin Finck 
54c2c66affSColin Finck     data->ddo[data->nobjects] = *lpddo;
55c2c66affSColin Finck 
56c2c66affSColin Finck     data->nobjects++;
57c2c66affSColin Finck     return DIENUM_CONTINUE;
58c2c66affSColin Finck }
59c2c66affSColin Finck 
60c2c66affSColin Finck static BOOL CALLBACK count_devices(LPCDIDEVICEINSTANCEW lpddi, IDirectInputDevice8W *lpdid, DWORD dwFlags, DWORD dwRemaining, LPVOID pvRef)
61c2c66affSColin Finck {
62c2c66affSColin Finck     DIDevicesData *data = (DIDevicesData*) pvRef;
63c2c66affSColin Finck 
64c2c66affSColin Finck     data->ndevices++;
65c2c66affSColin Finck     return DIENUM_CONTINUE;
66c2c66affSColin Finck }
67c2c66affSColin Finck 
68c2c66affSColin Finck static BOOL CALLBACK collect_devices(LPCDIDEVICEINSTANCEW lpddi, IDirectInputDevice8W *lpdid, DWORD dwFlags, DWORD dwRemaining, LPVOID pvRef)
69c2c66affSColin Finck {
70c2c66affSColin Finck     DIDevicesData *data = (DIDevicesData*) pvRef;
71c2c66affSColin Finck     DeviceData *device = &data->devices[data->ndevices];
72c2c66affSColin Finck     device->lpdid = lpdid;
73c2c66affSColin Finck     device->ddi = *lpddi;
74c2c66affSColin Finck 
75c2c66affSColin Finck     IDirectInputDevice_AddRef(lpdid);
76c2c66affSColin Finck 
77c2c66affSColin Finck     device->nobjects = 0;
78c2c66affSColin Finck     IDirectInputDevice_EnumObjects(lpdid, collect_objects, (LPVOID) device, DIDFT_ALL);
79c2c66affSColin Finck 
80c2c66affSColin Finck     data->ndevices++;
81c2c66affSColin Finck     return DIENUM_CONTINUE;
82c2c66affSColin Finck }
83c2c66affSColin Finck 
84c2c66affSColin Finck /*
85c2c66affSColin Finck  * Listview utility functions
86c2c66affSColin Finck  */
87c2c66affSColin Finck static void init_listview_columns(HWND dialog)
88c2c66affSColin Finck {
89c2c66affSColin Finck     LVCOLUMNW listColumn;
90c2c66affSColin Finck     RECT viewRect;
91c2c66affSColin Finck     int width;
92c2c66affSColin Finck     WCHAR column[MAX_PATH];
93c2c66affSColin Finck 
94c2c66affSColin Finck     GetClientRect(GetDlgItem(dialog, IDC_DEVICEOBJECTSLIST), &viewRect);
95c2c66affSColin Finck     width = (viewRect.right - viewRect.left)/2;
96c2c66affSColin Finck 
97*98e62237SAmine Khaldi     LoadStringW(DINPUT_instance, IDS_OBJECTCOLUMN, column, ARRAY_SIZE(column));
98c2c66affSColin Finck     listColumn.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
99c2c66affSColin Finck     listColumn.pszText = column;
100c2c66affSColin Finck     listColumn.cchTextMax = lstrlenW(listColumn.pszText);
101c2c66affSColin Finck     listColumn.cx = width;
102c2c66affSColin Finck 
103c2c66affSColin Finck     SendDlgItemMessageW (dialog, IDC_DEVICEOBJECTSLIST, LVM_INSERTCOLUMNW, 0, (LPARAM) &listColumn);
104c2c66affSColin Finck 
105*98e62237SAmine Khaldi     LoadStringW(DINPUT_instance, IDS_ACTIONCOLUMN, column, ARRAY_SIZE(column));
106c2c66affSColin Finck     listColumn.cx = width;
107c2c66affSColin Finck     listColumn.pszText = column;
108c2c66affSColin Finck     listColumn.cchTextMax = lstrlenW(listColumn.pszText);
109c2c66affSColin Finck 
110c2c66affSColin Finck     SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_INSERTCOLUMNW, 1, (LPARAM) &listColumn);
111c2c66affSColin Finck }
112c2c66affSColin Finck 
113c2c66affSColin Finck static int lv_get_cur_item(HWND dialog)
114c2c66affSColin Finck {
115c2c66affSColin Finck     return SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_GETNEXTITEM, -1, LVNI_SELECTED);
116c2c66affSColin Finck }
117c2c66affSColin Finck 
118c2c66affSColin Finck static int lv_get_item_data(HWND dialog, int index)
119c2c66affSColin Finck {
120c2c66affSColin Finck     LVITEMW item;
121c2c66affSColin Finck 
122c2c66affSColin Finck     if (index < 0) return -1;
123c2c66affSColin Finck 
124c2c66affSColin Finck     item.mask = LVIF_PARAM;
125c2c66affSColin Finck     item.iItem = index;
126c2c66affSColin Finck     item.iSubItem = 0;
127c2c66affSColin Finck 
128c2c66affSColin Finck     SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_GETITEMW , 0, (LPARAM)&item);
129c2c66affSColin Finck 
130c2c66affSColin Finck     return item.lParam;
131c2c66affSColin Finck }
132c2c66affSColin Finck 
133c2c66affSColin Finck static void lv_set_action(HWND dialog, int item, int action, LPDIACTIONFORMATW lpdiaf)
134c2c66affSColin Finck {
135c2c66affSColin Finck     static const WCHAR no_action[] = {'-','\0'};
136c2c66affSColin Finck     const WCHAR *action_text = no_action;
137c2c66affSColin Finck     LVITEMW lvItem;
138c2c66affSColin Finck 
139c2c66affSColin Finck     if (item < 0) return;
140c2c66affSColin Finck 
141c2c66affSColin Finck     if (action != -1)
142c2c66affSColin Finck         action_text = lpdiaf->rgoAction[action].u.lptszActionName;
143c2c66affSColin Finck 
144c2c66affSColin Finck     /* Keep the action and text in the listview item */
145c2c66affSColin Finck     lvItem.iItem = item;
146c2c66affSColin Finck 
147c2c66affSColin Finck     lvItem.mask = LVIF_PARAM;
148c2c66affSColin Finck     lvItem.iSubItem = 0;
149c2c66affSColin Finck     lvItem.lParam = (LPARAM) action;
150c2c66affSColin Finck 
151c2c66affSColin Finck     /* Action index */
152c2c66affSColin Finck     SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_SETITEMW, 0, (LPARAM) &lvItem);
153c2c66affSColin Finck 
154c2c66affSColin Finck     lvItem.mask = LVIF_TEXT;
155c2c66affSColin Finck     lvItem.iSubItem = 1;
156c2c66affSColin Finck     lvItem.pszText = (WCHAR *)action_text;
157c2c66affSColin Finck     lvItem.cchTextMax = lstrlenW(lvItem.pszText);
158c2c66affSColin Finck 
159c2c66affSColin Finck     /* Text */
160c2c66affSColin Finck     SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_SETITEMW, 0, (LPARAM) &lvItem);
161c2c66affSColin Finck }
162c2c66affSColin Finck 
163c2c66affSColin Finck /*
164c2c66affSColin Finck  * Utility functions
165c2c66affSColin Finck  */
166c2c66affSColin Finck static DeviceData* get_cur_device(HWND dialog)
167c2c66affSColin Finck {
168c2c66affSColin Finck     ConfigureDevicesData *data = (ConfigureDevicesData*) GetWindowLongPtrW(dialog, DWLP_USER);
169c2c66affSColin Finck     int sel = SendDlgItemMessageW(dialog, IDC_CONTROLLERCOMBO, CB_GETCURSEL, 0, 0);
170c2c66affSColin Finck     return &data->devices_data.devices[sel];
171c2c66affSColin Finck }
172c2c66affSColin Finck 
173c2c66affSColin Finck static LPDIACTIONFORMATW get_cur_lpdiaf(HWND dialog)
174c2c66affSColin Finck {
175c2c66affSColin Finck     ConfigureDevicesData *data = (ConfigureDevicesData*) GetWindowLongPtrW(dialog, DWLP_USER);
176c2c66affSColin Finck     return data->lpdiaf;
177c2c66affSColin Finck }
178c2c66affSColin Finck 
179c2c66affSColin Finck static int dialog_display_only(HWND dialog)
180c2c66affSColin Finck {
181c2c66affSColin Finck     ConfigureDevicesData *data = (ConfigureDevicesData*) GetWindowLongPtrW(dialog, DWLP_USER);
182c2c66affSColin Finck     return data->display_only;
183c2c66affSColin Finck }
184c2c66affSColin Finck 
185c2c66affSColin Finck static void init_devices(HWND dialog, IDirectInput8W *lpDI, DIDevicesData *data, LPDIACTIONFORMATW lpdiaf)
186c2c66affSColin Finck {
187c2c66affSColin Finck     int i;
188c2c66affSColin Finck 
189c2c66affSColin Finck     /* Count devices */
190c2c66affSColin Finck     data->ndevices = 0;
191c2c66affSColin Finck     IDirectInput8_EnumDevicesBySemantics(lpDI, NULL, lpdiaf, count_devices, (LPVOID) data, 0);
192c2c66affSColin Finck 
193c2c66affSColin Finck     /* Allocate devices */
194c2c66affSColin Finck     data->devices = HeapAlloc(GetProcessHeap(), 0, sizeof(DeviceData) * data->ndevices);
195c2c66affSColin Finck 
196c2c66affSColin Finck     /* Collect and insert */
197c2c66affSColin Finck     data->ndevices = 0;
198c2c66affSColin Finck     IDirectInput8_EnumDevicesBySemantics(lpDI, NULL, lpdiaf, collect_devices, (LPVOID) data, 0);
199c2c66affSColin Finck 
200c2c66affSColin Finck     for (i=0; i < data->ndevices; i++)
201c2c66affSColin Finck         SendDlgItemMessageW(dialog, IDC_CONTROLLERCOMBO, CB_ADDSTRING, 0, (LPARAM) data->devices[i].ddi.tszProductName );
202c2c66affSColin Finck }
203c2c66affSColin Finck 
204c2c66affSColin Finck static void destroy_data(HWND dialog)
205c2c66affSColin Finck {
206c2c66affSColin Finck     int i;
207c2c66affSColin Finck     ConfigureDevicesData *data = (ConfigureDevicesData*) GetWindowLongPtrW(dialog, DWLP_USER);
208c2c66affSColin Finck     DIDevicesData *devices_data = &data->devices_data;
209c2c66affSColin Finck 
210c2c66affSColin Finck     /* Free the devices */
211c2c66affSColin Finck     for (i=0; i < devices_data->ndevices; i++)
212c2c66affSColin Finck         IDirectInputDevice8_Release(devices_data->devices[i].lpdid);
213c2c66affSColin Finck 
214c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, devices_data->devices);
215c2c66affSColin Finck 
216c2c66affSColin Finck     /* Free the backup LPDIACTIONFORMATW  */
217c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, data->original_lpdiaf->rgoAction);
218c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, data->original_lpdiaf);
219c2c66affSColin Finck }
220c2c66affSColin Finck 
221c2c66affSColin Finck static void fill_device_object_list(HWND dialog)
222c2c66affSColin Finck {
223c2c66affSColin Finck     DeviceData *device = get_cur_device(dialog);
224c2c66affSColin Finck     LPDIACTIONFORMATW lpdiaf = get_cur_lpdiaf(dialog);
225c2c66affSColin Finck     LVITEMW item;
226c2c66affSColin Finck     int i, j;
227c2c66affSColin Finck 
228c2c66affSColin Finck     /* Clean the listview */
229c2c66affSColin Finck     SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_DELETEALLITEMS, 0, 0);
230c2c66affSColin Finck 
231c2c66affSColin Finck     /* Add each object */
232c2c66affSColin Finck     for (i=0; i < device->nobjects; i++)
233c2c66affSColin Finck     {
234c2c66affSColin Finck         int action = -1;
235c2c66affSColin Finck 
236c2c66affSColin Finck         item.mask = LVIF_TEXT | LVIF_PARAM;
237c2c66affSColin Finck         item.iItem = i;
238c2c66affSColin Finck         item.iSubItem = 0;
239c2c66affSColin Finck         item.pszText = device->ddo[i].tszName;
240c2c66affSColin Finck         item.cchTextMax = lstrlenW(item.pszText);
241c2c66affSColin Finck 
242c2c66affSColin Finck         /* Add the item */
243c2c66affSColin Finck         SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_INSERTITEMW, 0, (LPARAM) &item);
244c2c66affSColin Finck 
245c2c66affSColin Finck         /* Search for an assigned action  for this device */
246c2c66affSColin Finck         for (j=0; j < lpdiaf->dwNumActions; j++)
247c2c66affSColin Finck         {
248c2c66affSColin Finck             if (IsEqualGUID(&lpdiaf->rgoAction[j].guidInstance, &device->ddi.guidInstance) &&
249c2c66affSColin Finck                 lpdiaf->rgoAction[j].dwObjID == device->ddo[i].dwType)
250c2c66affSColin Finck             {
251c2c66affSColin Finck                 action = j;
252c2c66affSColin Finck                 break;
253c2c66affSColin Finck             }
254c2c66affSColin Finck         }
255c2c66affSColin Finck 
256c2c66affSColin Finck         lv_set_action(dialog, i, action, lpdiaf);
257c2c66affSColin Finck     }
258c2c66affSColin Finck }
259c2c66affSColin Finck 
260c2c66affSColin Finck static void show_suitable_actions(HWND dialog)
261c2c66affSColin Finck {
262c2c66affSColin Finck     DeviceData *device = get_cur_device(dialog);
263c2c66affSColin Finck     LPDIACTIONFORMATW lpdiaf = get_cur_lpdiaf(dialog);
264c2c66affSColin Finck     int i, added = 0;
265c2c66affSColin Finck     int obj = lv_get_cur_item(dialog);
266c2c66affSColin Finck 
267c2c66affSColin Finck     if (obj < 0) return;
268c2c66affSColin Finck 
269c2c66affSColin Finck     SendDlgItemMessageW(dialog, IDC_ACTIONLIST, LB_RESETCONTENT, 0, 0);
270c2c66affSColin Finck 
271c2c66affSColin Finck     for (i=0; i < lpdiaf->dwNumActions; i++)
272c2c66affSColin Finck     {
273c2c66affSColin Finck         /* Skip keyboard actions for non keyboards */
274c2c66affSColin Finck         if (GET_DIDEVICE_TYPE(device->ddi.dwDevType) != DI8DEVTYPE_KEYBOARD &&
275c2c66affSColin Finck             (lpdiaf->rgoAction[i].dwSemantic & DIKEYBOARD_MASK) == DIKEYBOARD_MASK) continue;
276c2c66affSColin Finck 
277c2c66affSColin Finck         /* Skip mouse actions for non mouses */
278c2c66affSColin Finck         if (GET_DIDEVICE_TYPE(device->ddi.dwDevType) != DI8DEVTYPE_MOUSE &&
279c2c66affSColin Finck             (lpdiaf->rgoAction[i].dwSemantic & DIMOUSE_MASK) == DIMOUSE_MASK) continue;
280c2c66affSColin Finck 
281c2c66affSColin Finck         /* Add action string and index in the action format to the list entry */
282c2c66affSColin Finck         if (DIDFT_GETINSTANCE(lpdiaf->rgoAction[i].dwSemantic) & DIDFT_GETTYPE(device->ddo[obj].dwType))
283c2c66affSColin Finck         {
284c2c66affSColin Finck             SendDlgItemMessageW(dialog, IDC_ACTIONLIST, LB_ADDSTRING, 0, (LPARAM)lpdiaf->rgoAction[i].u.lptszActionName);
285c2c66affSColin Finck             SendDlgItemMessageW(dialog, IDC_ACTIONLIST, LB_SETITEMDATA, added, (LPARAM) i);
286c2c66affSColin Finck             added++;
287c2c66affSColin Finck         }
288c2c66affSColin Finck     }
289c2c66affSColin Finck }
290c2c66affSColin Finck 
291c2c66affSColin Finck static void assign_action(HWND dialog)
292c2c66affSColin Finck {
293c2c66affSColin Finck     DeviceData *device = get_cur_device(dialog);
294c2c66affSColin Finck     LPDIACTIONFORMATW lpdiaf = get_cur_lpdiaf(dialog);
295c2c66affSColin Finck     LVFINDINFOW lvFind;
296c2c66affSColin Finck     int sel = SendDlgItemMessageW(dialog, IDC_ACTIONLIST, LB_GETCURSEL, 0, 0);
297c2c66affSColin Finck     int action = SendDlgItemMessageW(dialog, IDC_ACTIONLIST, LB_GETITEMDATA, sel, 0);
298c2c66affSColin Finck     int obj = lv_get_cur_item(dialog);
299c2c66affSColin Finck     int old_action = lv_get_item_data(dialog, obj);
300c2c66affSColin Finck     int used_obj;
301c2c66affSColin Finck 
302c2c66affSColin Finck     DIDEVICEOBJECTINSTANCEW ddo = device->ddo[obj];
303c2c66affSColin Finck 
304c2c66affSColin Finck     if (old_action == action) return;
305c2c66affSColin Finck 
306c2c66affSColin Finck     /* Clear old action */
307c2c66affSColin Finck     if (old_action != -1)
308c2c66affSColin Finck     {
309c2c66affSColin Finck         lpdiaf->rgoAction[old_action].dwObjID = 0;
310c2c66affSColin Finck         lpdiaf->rgoAction[old_action].guidInstance = GUID_NULL;
311c2c66affSColin Finck         lpdiaf->rgoAction[old_action].dwHow = DIAH_UNMAPPED;
312c2c66affSColin Finck     }
313c2c66affSColin Finck 
314c2c66affSColin Finck     /* Find if action text is already set for other object and unset it */
315c2c66affSColin Finck     lvFind.flags = LVFI_PARAM;
316c2c66affSColin Finck     lvFind.lParam = action;
317c2c66affSColin Finck 
318c2c66affSColin Finck     used_obj = SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_FINDITEMW, -1, (LPARAM) &lvFind);
319c2c66affSColin Finck 
320c2c66affSColin Finck     lv_set_action(dialog, used_obj, -1, lpdiaf);
321c2c66affSColin Finck 
322c2c66affSColin Finck     /* Set new action */
323c2c66affSColin Finck     lpdiaf->rgoAction[action].dwObjID = ddo.dwType;
324c2c66affSColin Finck     lpdiaf->rgoAction[action].guidInstance = device->ddi.guidInstance;
325c2c66affSColin Finck     lpdiaf->rgoAction[action].dwHow = DIAH_USERCONFIG;
326c2c66affSColin Finck 
327c2c66affSColin Finck     /* Set new action in the list */
328c2c66affSColin Finck     lv_set_action(dialog, obj, action, lpdiaf);
329c2c66affSColin Finck }
330c2c66affSColin Finck 
331c2c66affSColin Finck static void copy_actions(LPDIACTIONFORMATW to, LPDIACTIONFORMATW from)
332c2c66affSColin Finck {
333c2c66affSColin Finck     DWORD i;
334c2c66affSColin Finck     for (i=0; i < from->dwNumActions; i++)
335c2c66affSColin Finck     {
336c2c66affSColin Finck         to->rgoAction[i].guidInstance = from->rgoAction[i].guidInstance;
337c2c66affSColin Finck         to->rgoAction[i].dwObjID = from->rgoAction[i].dwObjID;
338c2c66affSColin Finck         to->rgoAction[i].dwHow = from->rgoAction[i].dwHow;
339c2c66affSColin Finck         to->rgoAction[i].u.lptszActionName = from->rgoAction[i].u.lptszActionName;
340c2c66affSColin Finck     }
341c2c66affSColin Finck }
342c2c66affSColin Finck 
343c2c66affSColin Finck static void reset_actions(HWND dialog)
344c2c66affSColin Finck {
345c2c66affSColin Finck     ConfigureDevicesData *data = (ConfigureDevicesData*) GetWindowLongPtrW(dialog, DWLP_USER);
346c2c66affSColin Finck     LPDIACTIONFORMATW to = data->lpdiaf, from = data->original_lpdiaf;
347c2c66affSColin Finck 
348c2c66affSColin Finck     copy_actions(to, from);
349c2c66affSColin Finck }
350c2c66affSColin Finck 
351c2c66affSColin Finck static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM wParam, LPARAM lParam)
352c2c66affSColin Finck {
353c2c66affSColin Finck     switch(uMsg)
354c2c66affSColin Finck     {
355c2c66affSColin Finck         case WM_INITDIALOG:
356c2c66affSColin Finck         {
357c2c66affSColin Finck             ConfigureDevicesData *data = (ConfigureDevicesData*) lParam;
358c2c66affSColin Finck 
359c2c66affSColin Finck             /* Initialize action format and enumerate devices */
360c2c66affSColin Finck             init_devices(dialog, data->lpDI, &data->devices_data, data->lpdiaf);
361c2c66affSColin Finck 
362c2c66affSColin Finck             /* Store information in the window */
363c2c66affSColin Finck             SetWindowLongPtrW(dialog, DWLP_USER, (LONG_PTR) data);
364c2c66affSColin Finck 
365c2c66affSColin Finck             init_listview_columns(dialog);
366c2c66affSColin Finck 
367c2c66affSColin Finck             /* Create a backup action format for CANCEL and RESET operations */
368c2c66affSColin Finck             data->original_lpdiaf = HeapAlloc(GetProcessHeap(), 0, sizeof(*data->original_lpdiaf));
369c2c66affSColin Finck             data->original_lpdiaf->dwNumActions = data->lpdiaf->dwNumActions;
370c2c66affSColin Finck             data->original_lpdiaf->rgoAction = HeapAlloc(GetProcessHeap(), 0, sizeof(DIACTIONW)*data->lpdiaf->dwNumActions);
371c2c66affSColin Finck             copy_actions(data->original_lpdiaf, data->lpdiaf);
372c2c66affSColin Finck 
373c2c66affSColin Finck             /* Select the first device and show its actions */
374c2c66affSColin Finck             SendDlgItemMessageW(dialog, IDC_CONTROLLERCOMBO, CB_SETCURSEL, 0, 0);
375c2c66affSColin Finck             fill_device_object_list(dialog);
376c2c66affSColin Finck 
377c2c66affSColin Finck             break;
378c2c66affSColin Finck         }
379c2c66affSColin Finck 
380c2c66affSColin Finck         case WM_NOTIFY:
381c2c66affSColin Finck 
382c2c66affSColin Finck             switch (((LPNMHDR)lParam)->code)
383c2c66affSColin Finck             {
384c2c66affSColin Finck                 case LVN_ITEMCHANGED:
385c2c66affSColin Finck                     show_suitable_actions(dialog);
386c2c66affSColin Finck                     break;
387c2c66affSColin Finck             }
388c2c66affSColin Finck             break;
389c2c66affSColin Finck 
390c2c66affSColin Finck 
391c2c66affSColin Finck         case WM_COMMAND:
392c2c66affSColin Finck 
393c2c66affSColin Finck             switch(LOWORD(wParam))
394c2c66affSColin Finck             {
395c2c66affSColin Finck 
396c2c66affSColin Finck                 case IDC_ACTIONLIST:
397c2c66affSColin Finck 
398c2c66affSColin Finck                     switch (HIWORD(wParam))
399c2c66affSColin Finck                     {
400c2c66affSColin Finck                         case LBN_DBLCLK:
401c2c66affSColin Finck                             /* Ignore this if app did not ask for editing */
402c2c66affSColin Finck                             if (dialog_display_only(dialog)) break;
403c2c66affSColin Finck 
404c2c66affSColin Finck                             assign_action(dialog);
405c2c66affSColin Finck                             break;
406c2c66affSColin Finck                     }
407c2c66affSColin Finck                     break;
408c2c66affSColin Finck 
409c2c66affSColin Finck                 case IDC_CONTROLLERCOMBO:
410c2c66affSColin Finck 
411c2c66affSColin Finck                     switch (HIWORD(wParam))
412c2c66affSColin Finck                     {
413c2c66affSColin Finck                         case CBN_SELCHANGE:
414c2c66affSColin Finck                             fill_device_object_list(dialog);
415c2c66affSColin Finck                             break;
416c2c66affSColin Finck                     }
417c2c66affSColin Finck                     break;
418c2c66affSColin Finck 
419c2c66affSColin Finck                 case IDOK:
420c2c66affSColin Finck                     EndDialog(dialog, 0);
421c2c66affSColin Finck                     destroy_data(dialog);
422c2c66affSColin Finck                     break;
423c2c66affSColin Finck 
424c2c66affSColin Finck                 case IDCANCEL:
425c2c66affSColin Finck                     reset_actions(dialog);
426c2c66affSColin Finck                     EndDialog(dialog, 0);
427c2c66affSColin Finck                     destroy_data(dialog);
428c2c66affSColin Finck                     break;
429c2c66affSColin Finck 
430c2c66affSColin Finck                 case IDC_RESET:
431c2c66affSColin Finck                     reset_actions(dialog);
432c2c66affSColin Finck                     fill_device_object_list(dialog);
433c2c66affSColin Finck                     break;
434c2c66affSColin Finck             }
435c2c66affSColin Finck         break;
436c2c66affSColin Finck     }
437c2c66affSColin Finck 
438c2c66affSColin Finck     return FALSE;
439c2c66affSColin Finck }
440c2c66affSColin Finck 
441c2c66affSColin Finck HRESULT _configure_devices(IDirectInput8W *iface,
442c2c66affSColin Finck                            LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
443c2c66affSColin Finck                            LPDICONFIGUREDEVICESPARAMSW lpdiCDParams,
444c2c66affSColin Finck                            DWORD dwFlags,
445c2c66affSColin Finck                            LPVOID pvRefData
446c2c66affSColin Finck )
447c2c66affSColin Finck {
448c2c66affSColin Finck     ConfigureDevicesData data;
449c2c66affSColin Finck     data.lpDI = iface;
450c2c66affSColin Finck     data.lpdiaf = lpdiCDParams->lprgFormats;
451c2c66affSColin Finck     data.display_only = !(dwFlags & DICD_EDIT);
452c2c66affSColin Finck 
453c2c66affSColin Finck     InitCommonControls();
454c2c66affSColin Finck 
455*98e62237SAmine Khaldi     DialogBoxParamW(DINPUT_instance, (const WCHAR *)MAKEINTRESOURCE(IDD_CONFIGUREDEVICES),
456*98e62237SAmine Khaldi             lpdiCDParams->hwnd, ConfigureDevicesDlgProc, (LPARAM)&data);
457c2c66affSColin Finck 
458c2c66affSColin Finck     return DI_OK;
459c2c66affSColin Finck }
460