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