Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendevice.c
Go to the documentation of this file.
00001 /* DirectInput Device 00002 * 00003 * Copyright 1998 Marcus Meissner 00004 * Copyright 1998,1999 Lionel Ulmer 00005 * 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 /* This file contains all the Device specific functions that can be used as stubs 00023 by real device implementations. 00024 00025 It also contains all the helper functions. 00026 */ 00027 #include "config.h" 00028 00029 #include <stdarg.h> 00030 #include <string.h> 00031 #include "wine/debug.h" 00032 #include "wine/unicode.h" 00033 #include "windef.h" 00034 #include "winbase.h" 00035 #include "winreg.h" 00036 #include "winuser.h" 00037 #include "winerror.h" 00038 #include "dinput.h" 00039 #include "device_private.h" 00040 #include "dinput_private.h" 00041 00042 WINE_DEFAULT_DEBUG_CHANNEL(dinput); 00043 00044 /****************************************************************************** 00045 * Various debugging tools 00046 */ 00047 static void _dump_cooperativelevel_DI(DWORD dwFlags) { 00048 if (TRACE_ON(dinput)) { 00049 unsigned int i; 00050 static const struct { 00051 DWORD mask; 00052 const char *name; 00053 } flags[] = { 00054 #define FE(x) { x, #x} 00055 FE(DISCL_BACKGROUND), 00056 FE(DISCL_EXCLUSIVE), 00057 FE(DISCL_FOREGROUND), 00058 FE(DISCL_NONEXCLUSIVE), 00059 FE(DISCL_NOWINKEY) 00060 #undef FE 00061 }; 00062 TRACE(" cooperative level : "); 00063 for (i = 0; i < (sizeof(flags) / sizeof(flags[0])); i++) 00064 if (flags[i].mask & dwFlags) 00065 TRACE("%s ",flags[i].name); 00066 TRACE("\n"); 00067 } 00068 } 00069 00070 static void _dump_EnumObjects_flags(DWORD dwFlags) { 00071 if (TRACE_ON(dinput)) { 00072 unsigned int i; 00073 DWORD type, instance; 00074 static const struct { 00075 DWORD mask; 00076 const char *name; 00077 } flags[] = { 00078 #define FE(x) { x, #x} 00079 FE(DIDFT_RELAXIS), 00080 FE(DIDFT_ABSAXIS), 00081 FE(DIDFT_PSHBUTTON), 00082 FE(DIDFT_TGLBUTTON), 00083 FE(DIDFT_POV), 00084 FE(DIDFT_COLLECTION), 00085 FE(DIDFT_NODATA), 00086 FE(DIDFT_FFACTUATOR), 00087 FE(DIDFT_FFEFFECTTRIGGER), 00088 FE(DIDFT_OUTPUT), 00089 FE(DIDFT_VENDORDEFINED), 00090 FE(DIDFT_ALIAS), 00091 FE(DIDFT_OPTIONAL) 00092 #undef FE 00093 }; 00094 type = (dwFlags & 0xFF0000FF); 00095 instance = ((dwFlags >> 8) & 0xFFFF); 00096 TRACE("Type:"); 00097 if (type == DIDFT_ALL) { 00098 TRACE(" DIDFT_ALL"); 00099 } else { 00100 for (i = 0; i < (sizeof(flags) / sizeof(flags[0])); i++) { 00101 if (flags[i].mask & type) { 00102 type &= ~flags[i].mask; 00103 TRACE(" %s",flags[i].name); 00104 } 00105 } 00106 if (type) { 00107 TRACE(" (unhandled: %08x)", type); 00108 } 00109 } 00110 TRACE(" / Instance: "); 00111 if (instance == ((DIDFT_ANYINSTANCE >> 8) & 0xFFFF)) { 00112 TRACE("DIDFT_ANYINSTANCE"); 00113 } else { 00114 TRACE("%3d", instance); 00115 } 00116 } 00117 } 00118 00119 void _dump_DIPROPHEADER(LPCDIPROPHEADER diph) { 00120 if (TRACE_ON(dinput)) { 00121 TRACE(" - dwObj = 0x%08x\n", diph->dwObj); 00122 TRACE(" - dwHow = %s\n", 00123 ((diph->dwHow == DIPH_DEVICE) ? "DIPH_DEVICE" : 00124 ((diph->dwHow == DIPH_BYOFFSET) ? "DIPH_BYOFFSET" : 00125 ((diph->dwHow == DIPH_BYID)) ? "DIPH_BYID" : "unknown"))); 00126 } 00127 } 00128 00129 void _dump_OBJECTINSTANCEA(const DIDEVICEOBJECTINSTANCEA *ddoi) { 00130 TRACE(" - enumerating : %s ('%s') - %2d - 0x%08x - %s\n", 00131 debugstr_guid(&ddoi->guidType), _dump_dinput_GUID(&ddoi->guidType), ddoi->dwOfs, ddoi->dwType, ddoi->tszName); 00132 } 00133 00134 void _dump_OBJECTINSTANCEW(const DIDEVICEOBJECTINSTANCEW *ddoi) { 00135 TRACE(" - enumerating : %s ('%s'), - %2d - 0x%08x - %s\n", 00136 debugstr_guid(&ddoi->guidType), _dump_dinput_GUID(&ddoi->guidType), ddoi->dwOfs, ddoi->dwType, debugstr_w(ddoi->tszName)); 00137 } 00138 00139 /* This function is a helper to convert a GUID into any possible DInput GUID out there */ 00140 const char *_dump_dinput_GUID(const GUID *guid) { 00141 unsigned int i; 00142 static const struct { 00143 const GUID *guid; 00144 const char *name; 00145 } guids[] = { 00146 #define FE(x) { &x, #x} 00147 FE(GUID_XAxis), 00148 FE(GUID_YAxis), 00149 FE(GUID_ZAxis), 00150 FE(GUID_RxAxis), 00151 FE(GUID_RyAxis), 00152 FE(GUID_RzAxis), 00153 FE(GUID_Slider), 00154 FE(GUID_Button), 00155 FE(GUID_Key), 00156 FE(GUID_POV), 00157 FE(GUID_Unknown), 00158 FE(GUID_SysMouse), 00159 FE(GUID_SysKeyboard), 00160 FE(GUID_Joystick), 00161 FE(GUID_ConstantForce), 00162 FE(GUID_RampForce), 00163 FE(GUID_Square), 00164 FE(GUID_Sine), 00165 FE(GUID_Triangle), 00166 FE(GUID_SawtoothUp), 00167 FE(GUID_SawtoothDown), 00168 FE(GUID_Spring), 00169 FE(GUID_Damper), 00170 FE(GUID_Inertia), 00171 FE(GUID_Friction), 00172 FE(GUID_CustomForce) 00173 #undef FE 00174 }; 00175 if (guid == NULL) 00176 return "null GUID"; 00177 for (i = 0; i < (sizeof(guids) / sizeof(guids[0])); i++) { 00178 if (IsEqualGUID(guids[i].guid, guid)) { 00179 return guids[i].name; 00180 } 00181 } 00182 return debugstr_guid(guid); 00183 } 00184 00185 void _dump_DIDATAFORMAT(const DIDATAFORMAT *df) { 00186 unsigned int i; 00187 00188 TRACE("Dumping DIDATAFORMAT structure:\n"); 00189 TRACE(" - dwSize: %d\n", df->dwSize); 00190 if (df->dwSize != sizeof(DIDATAFORMAT)) { 00191 WARN("Non-standard DIDATAFORMAT structure size %d\n", df->dwSize); 00192 } 00193 TRACE(" - dwObjsize: %d\n", df->dwObjSize); 00194 if (df->dwObjSize != sizeof(DIOBJECTDATAFORMAT)) { 00195 WARN("Non-standard DIOBJECTDATAFORMAT structure size %d\n", df->dwObjSize); 00196 } 00197 TRACE(" - dwFlags: 0x%08x (", df->dwFlags); 00198 switch (df->dwFlags) { 00199 case DIDF_ABSAXIS: TRACE("DIDF_ABSAXIS"); break; 00200 case DIDF_RELAXIS: TRACE("DIDF_RELAXIS"); break; 00201 default: TRACE("unknown"); break; 00202 } 00203 TRACE(")\n"); 00204 TRACE(" - dwDataSize: %d\n", df->dwDataSize); 00205 TRACE(" - dwNumObjs: %d\n", df->dwNumObjs); 00206 00207 for (i = 0; i < df->dwNumObjs; i++) { 00208 TRACE(" - Object %d:\n", i); 00209 TRACE(" * GUID: %s ('%s')\n", debugstr_guid(df->rgodf[i].pguid), _dump_dinput_GUID(df->rgodf[i].pguid)); 00210 TRACE(" * dwOfs: %d\n", df->rgodf[i].dwOfs); 00211 TRACE(" * dwType: 0x%08x\n", df->rgodf[i].dwType); 00212 TRACE(" "); _dump_EnumObjects_flags(df->rgodf[i].dwType); TRACE("\n"); 00213 TRACE(" * dwFlags: 0x%08x\n", df->rgodf[i].dwFlags); 00214 } 00215 } 00216 00217 /****************************************************************************** 00218 * Get the default and the app-specific config keys. 00219 */ 00220 BOOL get_app_key(HKEY *defkey, HKEY *appkey) 00221 { 00222 char buffer[MAX_PATH+16]; 00223 DWORD len; 00224 00225 *appkey = 0; 00226 00227 /* @@ Wine registry key: HKCU\Software\Wine\DirectInput */ 00228 if (RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\DirectInput", defkey)) 00229 *defkey = 0; 00230 00231 len = GetModuleFileNameA(0, buffer, MAX_PATH); 00232 if (len && len < MAX_PATH) 00233 { 00234 HKEY tmpkey; 00235 00236 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\DirectInput */ 00237 if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey)) 00238 { 00239 char *p, *appname = buffer; 00240 if ((p = strrchr(appname, '/'))) appname = p + 1; 00241 if ((p = strrchr(appname, '\\'))) appname = p + 1; 00242 strcat(appname, "\\DirectInput"); 00243 00244 if (RegOpenKeyA(tmpkey, appname, appkey)) *appkey = 0; 00245 RegCloseKey(tmpkey); 00246 } 00247 } 00248 00249 return *defkey || *appkey; 00250 } 00251 00252 /****************************************************************************** 00253 * Get a config key from either the app-specific or the default config 00254 */ 00255 DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name, 00256 char *buffer, DWORD size ) 00257 { 00258 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) 00259 return 0; 00260 00261 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) 00262 return 0; 00263 00264 return ERROR_FILE_NOT_FOUND; 00265 } 00266 00267 /* Conversion between internal data buffer and external data buffer */ 00268 void fill_DataFormat(void *out, DWORD size, const void *in, const DataFormat *df) 00269 { 00270 int i; 00271 const char *in_c = in; 00272 char *out_c = out; 00273 00274 memset(out, 0, size); 00275 if (df->dt == NULL) { 00276 /* This means that the app uses Wine's internal data format */ 00277 memcpy(out, in, min(size, df->internal_format_size)); 00278 } else { 00279 for (i = 0; i < df->size; i++) { 00280 if (df->dt[i].offset_in >= 0) { 00281 switch (df->dt[i].size) { 00282 case 1: 00283 TRACE("Copying (c) to %d from %d (value %d)\n", 00284 df->dt[i].offset_out, df->dt[i].offset_in, *(in_c + df->dt[i].offset_in)); 00285 *(out_c + df->dt[i].offset_out) = *(in_c + df->dt[i].offset_in); 00286 break; 00287 00288 case 2: 00289 TRACE("Copying (s) to %d from %d (value %d)\n", 00290 df->dt[i].offset_out, df->dt[i].offset_in, *((const short *)(in_c + df->dt[i].offset_in))); 00291 *((short *)(out_c + df->dt[i].offset_out)) = *((const short *)(in_c + df->dt[i].offset_in)); 00292 break; 00293 00294 case 4: 00295 TRACE("Copying (i) to %d from %d (value %d)\n", 00296 df->dt[i].offset_out, df->dt[i].offset_in, *((const int *)(in_c + df->dt[i].offset_in))); 00297 *((int *)(out_c + df->dt[i].offset_out)) = *((const int *)(in_c + df->dt[i].offset_in)); 00298 break; 00299 00300 default: 00301 memcpy((out_c + df->dt[i].offset_out), (in_c + df->dt[i].offset_in), df->dt[i].size); 00302 break; 00303 } 00304 } else { 00305 switch (df->dt[i].size) { 00306 case 1: 00307 TRACE("Copying (c) to %d default value %d\n", 00308 df->dt[i].offset_out, df->dt[i].value); 00309 *(out_c + df->dt[i].offset_out) = (char) df->dt[i].value; 00310 break; 00311 00312 case 2: 00313 TRACE("Copying (s) to %d default value %d\n", 00314 df->dt[i].offset_out, df->dt[i].value); 00315 *((short *) (out_c + df->dt[i].offset_out)) = (short) df->dt[i].value; 00316 break; 00317 00318 case 4: 00319 TRACE("Copying (i) to %d default value %d\n", 00320 df->dt[i].offset_out, df->dt[i].value); 00321 *((int *) (out_c + df->dt[i].offset_out)) = df->dt[i].value; 00322 break; 00323 00324 default: 00325 memset((out_c + df->dt[i].offset_out), 0, df->dt[i].size); 00326 break; 00327 } 00328 } 00329 } 00330 } 00331 } 00332 00333 void release_DataFormat(DataFormat * format) 00334 { 00335 TRACE("Deleting DataFormat: %p\n", format); 00336 00337 HeapFree(GetProcessHeap(), 0, format->dt); 00338 format->dt = NULL; 00339 HeapFree(GetProcessHeap(), 0, format->offsets); 00340 format->offsets = NULL; 00341 HeapFree(GetProcessHeap(), 0, format->user_df); 00342 format->user_df = NULL; 00343 } 00344 00345 static inline LPDIOBJECTDATAFORMAT dataformat_to_odf(LPCDIDATAFORMAT df, int idx) 00346 { 00347 if (idx < 0 || idx >= df->dwNumObjs) return NULL; 00348 return (LPDIOBJECTDATAFORMAT)((LPBYTE)df->rgodf + idx * df->dwObjSize); 00349 } 00350 00351 static HRESULT create_DataFormat(LPCDIDATAFORMAT asked_format, DataFormat *format) 00352 { 00353 DataTransform *dt; 00354 unsigned int i, j; 00355 int same = 1; 00356 int *done; 00357 int index = 0; 00358 DWORD next = 0; 00359 00360 if (!format->wine_df) return DIERR_INVALIDPARAM; 00361 done = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, asked_format->dwNumObjs * sizeof(int)); 00362 dt = HeapAlloc(GetProcessHeap(), 0, asked_format->dwNumObjs * sizeof(DataTransform)); 00363 if (!dt || !done) goto failed; 00364 00365 if (!(format->offsets = HeapAlloc(GetProcessHeap(), 0, format->wine_df->dwNumObjs * sizeof(int)))) 00366 goto failed; 00367 00368 if (!(format->user_df = HeapAlloc(GetProcessHeap(), 0, asked_format->dwSize))) 00369 goto failed; 00370 memcpy(format->user_df, asked_format, asked_format->dwSize); 00371 00372 TRACE("Creating DataTransform :\n"); 00373 00374 for (i = 0; i < format->wine_df->dwNumObjs; i++) 00375 { 00376 format->offsets[i] = -1; 00377 00378 for (j = 0; j < asked_format->dwNumObjs; j++) { 00379 if (done[j] == 1) 00380 continue; 00381 00382 if (/* Check if the application either requests any GUID and if not, it if matches 00383 * the GUID of the Wine object. 00384 */ 00385 ((asked_format->rgodf[j].pguid == NULL) || 00386 (format->wine_df->rgodf[i].pguid == NULL) || 00387 (IsEqualGUID(format->wine_df->rgodf[i].pguid, asked_format->rgodf[j].pguid))) 00388 && 00389 (/* Then check if it accepts any instance id, and if not, if it matches Wine's 00390 * instance id. 00391 */ 00392 ((asked_format->rgodf[j].dwType & DIDFT_INSTANCEMASK) == DIDFT_ANYINSTANCE) || 00393 (DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType) == 0x00FF) || /* This is mentionned in no DX docs, but it works fine - tested on WinXP */ 00394 (DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType) == DIDFT_GETINSTANCE(format->wine_df->rgodf[i].dwType))) 00395 && 00396 ( /* Then if the asked type matches the one Wine provides */ 00397 DIDFT_GETTYPE(asked_format->rgodf[j].dwType) & format->wine_df->rgodf[i].dwType)) 00398 { 00399 done[j] = 1; 00400 00401 TRACE("Matching :\n"); 00402 TRACE(" - Asked (%d) :\n", j); 00403 TRACE(" * GUID: %s ('%s')\n", 00404 debugstr_guid(asked_format->rgodf[j].pguid), 00405 _dump_dinput_GUID(asked_format->rgodf[j].pguid)); 00406 TRACE(" * Offset: %3d\n", asked_format->rgodf[j].dwOfs); 00407 TRACE(" * dwType: %08x\n", asked_format->rgodf[j].dwType); 00408 TRACE(" "); _dump_EnumObjects_flags(asked_format->rgodf[j].dwType); TRACE("\n"); 00409 00410 TRACE(" - Wine (%d) :\n", i); 00411 TRACE(" * GUID: %s ('%s')\n", 00412 debugstr_guid(format->wine_df->rgodf[i].pguid), 00413 _dump_dinput_GUID(format->wine_df->rgodf[i].pguid)); 00414 TRACE(" * Offset: %3d\n", format->wine_df->rgodf[i].dwOfs); 00415 TRACE(" * dwType: %08x\n", format->wine_df->rgodf[i].dwType); 00416 TRACE(" "); _dump_EnumObjects_flags(format->wine_df->rgodf[i].dwType); TRACE("\n"); 00417 00418 if (format->wine_df->rgodf[i].dwType & DIDFT_BUTTON) 00419 dt[index].size = sizeof(BYTE); 00420 else 00421 dt[index].size = sizeof(DWORD); 00422 dt[index].offset_in = format->wine_df->rgodf[i].dwOfs; 00423 dt[index].offset_out = asked_format->rgodf[j].dwOfs; 00424 format->offsets[i] = asked_format->rgodf[j].dwOfs; 00425 dt[index].value = 0; 00426 next = next + dt[index].size; 00427 00428 if (format->wine_df->rgodf[i].dwOfs != dt[index].offset_out) 00429 same = 0; 00430 00431 index++; 00432 break; 00433 } 00434 } 00435 } 00436 00437 TRACE("Setting to default value :\n"); 00438 for (j = 0; j < asked_format->dwNumObjs; j++) { 00439 if (done[j] == 0) { 00440 TRACE(" - Asked (%d) :\n", j); 00441 TRACE(" * GUID: %s ('%s')\n", 00442 debugstr_guid(asked_format->rgodf[j].pguid), 00443 _dump_dinput_GUID(asked_format->rgodf[j].pguid)); 00444 TRACE(" * Offset: %3d\n", asked_format->rgodf[j].dwOfs); 00445 TRACE(" * dwType: %08x\n", asked_format->rgodf[j].dwType); 00446 TRACE(" "); _dump_EnumObjects_flags(asked_format->rgodf[j].dwType); TRACE("\n"); 00447 00448 if (asked_format->rgodf[j].dwType & DIDFT_BUTTON) 00449 dt[index].size = sizeof(BYTE); 00450 else 00451 dt[index].size = sizeof(DWORD); 00452 dt[index].offset_in = -1; 00453 dt[index].offset_out = asked_format->rgodf[j].dwOfs; 00454 if (asked_format->rgodf[j].dwType & DIDFT_POV) 00455 dt[index].value = -1; 00456 else 00457 dt[index].value = 0; 00458 index++; 00459 00460 same = 0; 00461 } 00462 } 00463 00464 format->internal_format_size = format->wine_df->dwDataSize; 00465 format->size = index; 00466 if (same) { 00467 HeapFree(GetProcessHeap(), 0, dt); 00468 dt = NULL; 00469 } 00470 format->dt = dt; 00471 00472 HeapFree(GetProcessHeap(), 0, done); 00473 00474 return DI_OK; 00475 00476 failed: 00477 HeapFree(GetProcessHeap(), 0, done); 00478 HeapFree(GetProcessHeap(), 0, dt); 00479 format->dt = NULL; 00480 HeapFree(GetProcessHeap(), 0, format->offsets); 00481 format->offsets = NULL; 00482 HeapFree(GetProcessHeap(), 0, format->user_df); 00483 format->user_df = NULL; 00484 00485 return DIERR_OUTOFMEMORY; 00486 } 00487 00488 /* find an object by it's offset in a data format */ 00489 static int offset_to_object(const DataFormat *df, int offset) 00490 { 00491 int i; 00492 00493 if (!df->offsets) return -1; 00494 00495 for (i = 0; i < df->wine_df->dwNumObjs; i++) 00496 if (df->offsets[i] == offset) return i; 00497 00498 return -1; 00499 } 00500 00501 int id_to_object(LPCDIDATAFORMAT df, int id) 00502 { 00503 int i; 00504 00505 id &= 0x00ffffff; 00506 for (i = 0; i < df->dwNumObjs; i++) 00507 if ((dataformat_to_odf(df, i)->dwType & 0x00ffffff) == id) 00508 return i; 00509 00510 return -1; 00511 } 00512 00513 int id_to_offset(const DataFormat *df, int id) 00514 { 00515 int obj = id_to_object(df->wine_df, id); 00516 00517 return obj >= 0 && df->offsets ? df->offsets[obj] : -1; 00518 } 00519 00520 int find_property(const DataFormat *df, LPCDIPROPHEADER ph) 00521 { 00522 switch (ph->dwHow) 00523 { 00524 case DIPH_BYID: return id_to_object(df->wine_df, ph->dwObj); 00525 case DIPH_BYOFFSET: return offset_to_object(df, ph->dwObj); 00526 } 00527 FIXME("Unhandled ph->dwHow=='%04X'\n", (unsigned int)ph->dwHow); 00528 00529 return -1; 00530 } 00531 00532 /****************************************************************************** 00533 * queue_event - add new event to the ring queue 00534 */ 00535 00536 void queue_event(LPDIRECTINPUTDEVICE8A iface, int ofs, DWORD data, DWORD time, DWORD seq) 00537 { 00538 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00539 int next_pos; 00540 00541 /* Event is being set regardless of the queue state */ 00542 if (This->hEvent) SetEvent(This->hEvent); 00543 00544 if (!This->queue_len || This->overflow || ofs < 0) return; 00545 00546 next_pos = (This->queue_head + 1) % This->queue_len; 00547 if (next_pos == This->queue_tail) 00548 { 00549 TRACE(" queue overflowed\n"); 00550 This->overflow = TRUE; 00551 return; 00552 } 00553 00554 TRACE(" queueing %d at offset %d (queue head %d / size %d)\n", 00555 data, ofs, This->queue_head, This->queue_len); 00556 00557 This->data_queue[This->queue_head].dwOfs = ofs; 00558 This->data_queue[This->queue_head].dwData = data; 00559 This->data_queue[This->queue_head].dwTimeStamp = time; 00560 This->data_queue[This->queue_head].dwSequence = seq; 00561 This->queue_head = next_pos; 00562 /* Send event if asked */ 00563 } 00564 00565 /****************************************************************************** 00566 * Acquire 00567 */ 00568 00569 HRESULT WINAPI IDirectInputDevice2AImpl_Acquire(LPDIRECTINPUTDEVICE8A iface) 00570 { 00571 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00572 HRESULT res; 00573 00574 if (!This->data_format.user_df) return DIERR_INVALIDPARAM; 00575 if (This->dwCoopLevel & DISCL_FOREGROUND && This->win != GetForegroundWindow()) 00576 return DIERR_OTHERAPPHASPRIO; 00577 00578 EnterCriticalSection(&This->crit); 00579 res = This->acquired ? S_FALSE : DI_OK; 00580 This->acquired = 1; 00581 if (res == DI_OK) 00582 { 00583 This->queue_head = This->queue_tail = This->overflow = 0; 00584 check_dinput_hooks(iface); 00585 } 00586 LeaveCriticalSection(&This->crit); 00587 00588 return res; 00589 } 00590 00591 /****************************************************************************** 00592 * Unacquire 00593 */ 00594 00595 HRESULT WINAPI IDirectInputDevice2AImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface) 00596 { 00597 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00598 HRESULT res; 00599 00600 EnterCriticalSection(&This->crit); 00601 res = !This->acquired ? DI_NOEFFECT : DI_OK; 00602 This->acquired = 0; 00603 if (res == DI_OK) 00604 check_dinput_hooks(iface); 00605 LeaveCriticalSection(&This->crit); 00606 00607 return res; 00608 } 00609 00610 /****************************************************************************** 00611 * IDirectInputDeviceA 00612 */ 00613 00614 HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat( 00615 LPDIRECTINPUTDEVICE8A iface, LPCDIDATAFORMAT df) 00616 { 00617 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00618 HRESULT res = DI_OK; 00619 00620 if (!df) return E_POINTER; 00621 TRACE("(%p) %p\n", This, df); 00622 _dump_DIDATAFORMAT(df); 00623 00624 if (df->dwSize != sizeof(DIDATAFORMAT)) return DIERR_INVALIDPARAM; 00625 if (This->acquired) return DIERR_ACQUIRED; 00626 00627 EnterCriticalSection(&This->crit); 00628 00629 release_DataFormat(&This->data_format); 00630 res = create_DataFormat(df, &This->data_format); 00631 00632 LeaveCriticalSection(&This->crit); 00633 return res; 00634 } 00635 00636 /****************************************************************************** 00637 * SetCooperativeLevel 00638 * 00639 * Set cooperative level and the source window for the events. 00640 */ 00641 HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel( 00642 LPDIRECTINPUTDEVICE8A iface, HWND hwnd, DWORD dwflags) 00643 { 00644 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00645 00646 TRACE("(%p) %p,0x%08x\n", This, hwnd, dwflags); 00647 _dump_cooperativelevel_DI(dwflags); 00648 00649 if ((dwflags & (DISCL_EXCLUSIVE | DISCL_NONEXCLUSIVE)) == 0 || 00650 (dwflags & (DISCL_EXCLUSIVE | DISCL_NONEXCLUSIVE)) == (DISCL_EXCLUSIVE | DISCL_NONEXCLUSIVE) || 00651 (dwflags & (DISCL_FOREGROUND | DISCL_BACKGROUND)) == 0 || 00652 (dwflags & (DISCL_FOREGROUND | DISCL_BACKGROUND)) == (DISCL_FOREGROUND | DISCL_BACKGROUND)) 00653 return DIERR_INVALIDPARAM; 00654 00655 if (dwflags == (DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)) 00656 hwnd = GetDesktopWindow(); 00657 00658 if (!hwnd) return E_HANDLE; 00659 00660 /* For security reasons native does not allow exclusive background level 00661 for mouse and keyboard only */ 00662 if (dwflags & DISCL_EXCLUSIVE && dwflags & DISCL_BACKGROUND && 00663 (IsEqualGUID(&This->guid, &GUID_SysMouse) || 00664 IsEqualGUID(&This->guid, &GUID_SysKeyboard))) 00665 return DIERR_UNSUPPORTED; 00666 00667 /* Store the window which asks for the mouse */ 00668 EnterCriticalSection(&This->crit); 00669 This->win = hwnd; 00670 This->dwCoopLevel = dwflags; 00671 LeaveCriticalSection(&This->crit); 00672 00673 return DI_OK; 00674 } 00675 00676 /****************************************************************************** 00677 * SetEventNotification : specifies event to be sent on state change 00678 */ 00679 HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification( 00680 LPDIRECTINPUTDEVICE8A iface, HANDLE event) 00681 { 00682 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00683 00684 TRACE("(%p) %p\n", This, event); 00685 00686 EnterCriticalSection(&This->crit); 00687 This->hEvent = event; 00688 LeaveCriticalSection(&This->crit); 00689 return DI_OK; 00690 } 00691 00692 ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface) 00693 { 00694 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00695 ULONG ref; 00696 00697 ref = InterlockedDecrement(&(This->ref)); 00698 if (ref) return ref; 00699 00700 IDirectInputDevice_Unacquire(iface); 00701 /* Reset the FF state, free all effects, etc */ 00702 IDirectInputDevice8_SendForceFeedbackCommand(iface, DISFFC_RESET); 00703 00704 HeapFree(GetProcessHeap(), 0, This->data_queue); 00705 00706 /* Free data format */ 00707 HeapFree(GetProcessHeap(), 0, This->data_format.wine_df->rgodf); 00708 HeapFree(GetProcessHeap(), 0, This->data_format.wine_df); 00709 release_DataFormat(&This->data_format); 00710 00711 EnterCriticalSection( &This->dinput->crit ); 00712 list_remove( &This->entry ); 00713 LeaveCriticalSection( &This->dinput->crit ); 00714 00715 IDirectInput_Release((LPDIRECTINPUTDEVICE8A)This->dinput); 00716 This->crit.DebugInfo->Spare[0] = 0; 00717 DeleteCriticalSection(&This->crit); 00718 00719 HeapFree(GetProcessHeap(), 0, This); 00720 00721 return DI_OK; 00722 } 00723 00724 HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface( 00725 LPDIRECTINPUTDEVICE8A iface,REFIID riid,LPVOID *ppobj 00726 ) 00727 { 00728 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00729 00730 TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); 00731 if (IsEqualGUID(&IID_IUnknown,riid)) { 00732 IDirectInputDevice2_AddRef(iface); 00733 *ppobj = This; 00734 return DI_OK; 00735 } 00736 if (IsEqualGUID(&IID_IDirectInputDeviceA,riid)) { 00737 IDirectInputDevice2_AddRef(iface); 00738 *ppobj = This; 00739 return DI_OK; 00740 } 00741 if (IsEqualGUID(&IID_IDirectInputDevice2A,riid)) { 00742 IDirectInputDevice2_AddRef(iface); 00743 *ppobj = This; 00744 return DI_OK; 00745 } 00746 if (IsEqualGUID(&IID_IDirectInputDevice7A,riid)) { 00747 IDirectInputDevice7_AddRef(iface); 00748 *ppobj = This; 00749 return DI_OK; 00750 } 00751 if (IsEqualGUID(&IID_IDirectInputDevice8A,riid)) { 00752 IDirectInputDevice8_AddRef(iface); 00753 *ppobj = This; 00754 return DI_OK; 00755 } 00756 TRACE("Unsupported interface !\n"); 00757 return E_FAIL; 00758 } 00759 00760 HRESULT WINAPI IDirectInputDevice2WImpl_QueryInterface( 00761 LPDIRECTINPUTDEVICE8W iface,REFIID riid,LPVOID *ppobj 00762 ) 00763 { 00764 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00765 00766 TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); 00767 if (IsEqualGUID(&IID_IUnknown,riid)) { 00768 IDirectInputDevice2_AddRef(iface); 00769 *ppobj = This; 00770 return DI_OK; 00771 } 00772 if (IsEqualGUID(&IID_IDirectInputDeviceW,riid)) { 00773 IDirectInputDevice2_AddRef(iface); 00774 *ppobj = This; 00775 return DI_OK; 00776 } 00777 if (IsEqualGUID(&IID_IDirectInputDevice2W,riid)) { 00778 IDirectInputDevice2_AddRef(iface); 00779 *ppobj = This; 00780 return DI_OK; 00781 } 00782 if (IsEqualGUID(&IID_IDirectInputDevice7W,riid)) { 00783 IDirectInputDevice7_AddRef(iface); 00784 *ppobj = This; 00785 return DI_OK; 00786 } 00787 if (IsEqualGUID(&IID_IDirectInputDevice8W,riid)) { 00788 IDirectInputDevice8_AddRef(iface); 00789 *ppobj = This; 00790 return DI_OK; 00791 } 00792 TRACE("Unsupported interface !\n"); 00793 return E_FAIL; 00794 } 00795 00796 ULONG WINAPI IDirectInputDevice2AImpl_AddRef( 00797 LPDIRECTINPUTDEVICE8A iface) 00798 { 00799 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00800 return InterlockedIncrement(&(This->ref)); 00801 } 00802 00803 HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(LPDIRECTINPUTDEVICE8A iface, 00804 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID lpvRef, DWORD dwFlags) 00805 { 00806 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00807 DIDEVICEOBJECTINSTANCEA ddoi; 00808 int i; 00809 00810 TRACE("(%p) %p,%p flags:%08x)\n", iface, lpCallback, lpvRef, dwFlags); 00811 TRACE(" - flags = "); 00812 _dump_EnumObjects_flags(dwFlags); 00813 TRACE("\n"); 00814 00815 /* Only the fields till dwFFMaxForce are relevant */ 00816 memset(&ddoi, 0, sizeof(ddoi)); 00817 ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA, dwFFMaxForce); 00818 00819 for (i = 0; i < This->data_format.wine_df->dwNumObjs; i++) 00820 { 00821 LPDIOBJECTDATAFORMAT odf = dataformat_to_odf(This->data_format.wine_df, i); 00822 00823 if (dwFlags != DIDFT_ALL && !(dwFlags & DIEFT_GETTYPE(odf->dwType))) continue; 00824 if (IDirectInputDevice_GetObjectInfo(iface, &ddoi, odf->dwType, DIPH_BYID) != DI_OK) 00825 continue; 00826 00827 if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) break; 00828 } 00829 00830 return DI_OK; 00831 } 00832 00833 HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects(LPDIRECTINPUTDEVICE8W iface, 00834 LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID lpvRef, DWORD dwFlags) 00835 { 00836 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00837 DIDEVICEOBJECTINSTANCEW ddoi; 00838 int i; 00839 00840 TRACE("(%p) %p,%p flags:%08x)\n", iface, lpCallback, lpvRef, dwFlags); 00841 TRACE(" - flags = "); 00842 _dump_EnumObjects_flags(dwFlags); 00843 TRACE("\n"); 00844 00845 /* Only the fields till dwFFMaxForce are relevant */ 00846 memset(&ddoi, 0, sizeof(ddoi)); 00847 ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEW, dwFFMaxForce); 00848 00849 for (i = 0; i < This->data_format.wine_df->dwNumObjs; i++) 00850 { 00851 LPDIOBJECTDATAFORMAT odf = dataformat_to_odf(This->data_format.wine_df, i); 00852 00853 if (dwFlags != DIDFT_ALL && !(dwFlags & DIEFT_GETTYPE(odf->dwType))) continue; 00854 if (IDirectInputDevice_GetObjectInfo(iface, &ddoi, odf->dwType, DIPH_BYID) != DI_OK) 00855 continue; 00856 00857 if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) break; 00858 } 00859 00860 return DI_OK; 00861 } 00862 00863 /****************************************************************************** 00864 * GetProperty 00865 */ 00866 00867 HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty( 00868 LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPDIPROPHEADER pdiph) 00869 { 00870 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00871 00872 TRACE("(%p) %s,%p\n", iface, debugstr_guid(rguid), pdiph); 00873 _dump_DIPROPHEADER(pdiph); 00874 00875 if (HIWORD(rguid)) return DI_OK; 00876 00877 switch (LOWORD(rguid)) 00878 { 00879 case (DWORD_PTR) DIPROP_BUFFERSIZE: 00880 { 00881 LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph; 00882 00883 if (pdiph->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; 00884 00885 pd->dwData = This->queue_len; 00886 TRACE("buffersize = %d\n", pd->dwData); 00887 break; 00888 } 00889 default: 00890 WARN("Unknown property %s\n", debugstr_guid(rguid)); 00891 break; 00892 } 00893 00894 return DI_OK; 00895 } 00896 00897 /****************************************************************************** 00898 * SetProperty 00899 */ 00900 00901 HRESULT WINAPI IDirectInputDevice2AImpl_SetProperty( 00902 LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPCDIPROPHEADER pdiph) 00903 { 00904 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00905 00906 TRACE("(%p) %s,%p\n", iface, debugstr_guid(rguid), pdiph); 00907 _dump_DIPROPHEADER(pdiph); 00908 00909 if (HIWORD(rguid)) return DI_OK; 00910 00911 switch (LOWORD(rguid)) 00912 { 00913 case (DWORD_PTR) DIPROP_AXISMODE: 00914 { 00915 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)pdiph; 00916 00917 if (pdiph->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; 00918 if (pdiph->dwHow == DIPH_DEVICE && pdiph->dwObj) return DIERR_INVALIDPARAM; 00919 if (This->acquired) return DIERR_ACQUIRED; 00920 if (pdiph->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED; 00921 if (!This->data_format.user_df) return DI_OK; 00922 00923 TRACE("Axis mode: %s\n", pd->dwData == DIPROPAXISMODE_ABS ? "absolute" : 00924 "relative"); 00925 00926 EnterCriticalSection(&This->crit); 00927 This->data_format.user_df->dwFlags &= ~DIDFT_AXIS; 00928 This->data_format.user_df->dwFlags |= pd->dwData == DIPROPAXISMODE_ABS ? 00929 DIDF_ABSAXIS : DIDF_RELAXIS; 00930 LeaveCriticalSection(&This->crit); 00931 break; 00932 } 00933 case (DWORD_PTR) DIPROP_BUFFERSIZE: 00934 { 00935 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)pdiph; 00936 00937 if (pdiph->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; 00938 if (This->acquired) return DIERR_ACQUIRED; 00939 00940 TRACE("buffersize = %d\n", pd->dwData); 00941 00942 EnterCriticalSection(&This->crit); 00943 HeapFree(GetProcessHeap(), 0, This->data_queue); 00944 00945 This->data_queue = !pd->dwData ? NULL : HeapAlloc(GetProcessHeap(), 0, 00946 pd->dwData * sizeof(DIDEVICEOBJECTDATA)); 00947 This->queue_head = This->queue_tail = This->overflow = 0; 00948 This->queue_len = pd->dwData; 00949 00950 LeaveCriticalSection(&This->crit); 00951 break; 00952 } 00953 default: 00954 WARN("Unknown property %s\n", debugstr_guid(rguid)); 00955 return DIERR_UNSUPPORTED; 00956 } 00957 00958 return DI_OK; 00959 } 00960 00961 HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo( 00962 LPDIRECTINPUTDEVICE8A iface, 00963 LPDIDEVICEOBJECTINSTANCEA pdidoi, 00964 DWORD dwObj, 00965 DWORD dwHow) 00966 { 00967 DIDEVICEOBJECTINSTANCEW didoiW; 00968 HRESULT res; 00969 00970 if (!pdidoi || 00971 (pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCEA) && 00972 pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCE_DX3A))) 00973 return DIERR_INVALIDPARAM; 00974 00975 didoiW.dwSize = sizeof(didoiW); 00976 res = IDirectInputDevice2WImpl_GetObjectInfo((LPDIRECTINPUTDEVICE8W)iface, &didoiW, dwObj, dwHow); 00977 if (res == DI_OK) 00978 { 00979 DWORD dwSize = pdidoi->dwSize; 00980 00981 memset(pdidoi, 0, pdidoi->dwSize); 00982 pdidoi->dwSize = dwSize; 00983 pdidoi->guidType = didoiW.guidType; 00984 pdidoi->dwOfs = didoiW.dwOfs; 00985 pdidoi->dwType = didoiW.dwType; 00986 pdidoi->dwFlags = didoiW.dwFlags; 00987 } 00988 00989 return res; 00990 } 00991 00992 HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo( 00993 LPDIRECTINPUTDEVICE8W iface, 00994 LPDIDEVICEOBJECTINSTANCEW pdidoi, 00995 DWORD dwObj, 00996 DWORD dwHow) 00997 { 00998 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 00999 DWORD dwSize; 01000 LPDIOBJECTDATAFORMAT odf; 01001 int idx = -1; 01002 01003 TRACE("(%p) %d(0x%08x) -> %p\n", This, dwHow, dwObj, pdidoi); 01004 01005 if (!pdidoi || 01006 (pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCEW) && 01007 pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCE_DX3W))) 01008 return DIERR_INVALIDPARAM; 01009 01010 switch (dwHow) 01011 { 01012 case DIPH_BYOFFSET: 01013 if (!This->data_format.offsets) break; 01014 for (idx = This->data_format.wine_df->dwNumObjs - 1; idx >= 0; idx--) 01015 if (This->data_format.offsets[idx] == dwObj) break; 01016 break; 01017 case DIPH_BYID: 01018 dwObj &= 0x00ffffff; 01019 for (idx = This->data_format.wine_df->dwNumObjs - 1; idx >= 0; idx--) 01020 if ((dataformat_to_odf(This->data_format.wine_df, idx)->dwType & 0x00ffffff) == dwObj) 01021 break; 01022 break; 01023 01024 case DIPH_BYUSAGE: 01025 FIXME("dwHow = DIPH_BYUSAGE not implemented\n"); 01026 break; 01027 default: 01028 WARN("invalid parameter: dwHow = %08x\n", dwHow); 01029 return DIERR_INVALIDPARAM; 01030 } 01031 if (idx < 0) return DIERR_OBJECTNOTFOUND; 01032 01033 odf = dataformat_to_odf(This->data_format.wine_df, idx); 01034 dwSize = pdidoi->dwSize; /* save due to memset below */ 01035 memset(pdidoi, 0, pdidoi->dwSize); 01036 pdidoi->dwSize = dwSize; 01037 if (odf->pguid) pdidoi->guidType = *odf->pguid; 01038 pdidoi->dwOfs = This->data_format.offsets ? This->data_format.offsets[idx] : odf->dwOfs; 01039 pdidoi->dwType = odf->dwType; 01040 pdidoi->dwFlags = odf->dwFlags; 01041 01042 return DI_OK; 01043 } 01044 01045 HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceData( 01046 LPDIRECTINPUTDEVICE8A iface, DWORD dodsize, LPDIDEVICEOBJECTDATA dod, 01047 LPDWORD entries, DWORD flags) 01048 { 01049 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 01050 HRESULT ret = DI_OK; 01051 int len; 01052 01053 TRACE("(%p) %p -> %p(%d) x%d, 0x%08x\n", 01054 This, dod, entries, entries ? *entries : 0, dodsize, flags); 01055 01056 if (!This->acquired) 01057 return DIERR_NOTACQUIRED; 01058 if (!This->queue_len) 01059 return DIERR_NOTBUFFERED; 01060 if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3)) 01061 return DIERR_INVALIDPARAM; 01062 01063 IDirectInputDevice2_Poll(iface); 01064 EnterCriticalSection(&This->crit); 01065 01066 len = This->queue_head - This->queue_tail; 01067 if (len < 0) len += This->queue_len; 01068 01069 if ((*entries != INFINITE) && (len > *entries)) len = *entries; 01070 01071 if (dod) 01072 { 01073 int i; 01074 for (i = 0; i < len; i++) 01075 { 01076 int n = (This->queue_tail + i) % This->queue_len; 01077 memcpy((char *)dod + dodsize * i, This->data_queue + n, dodsize); 01078 } 01079 } 01080 *entries = len; 01081 01082 if (This->overflow) 01083 ret = DI_BUFFEROVERFLOW; 01084 01085 if (!(flags & DIGDD_PEEK)) 01086 { 01087 /* Advance reading position */ 01088 This->queue_tail = (This->queue_tail + len) % This->queue_len; 01089 This->overflow = FALSE; 01090 } 01091 01092 LeaveCriticalSection(&This->crit); 01093 01094 TRACE("Returning %d events queued\n", *entries); 01095 return ret; 01096 } 01097 01098 HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel( 01099 LPDIRECTINPUTDEVICE8A iface, 01100 HWND hwndOwner, 01101 DWORD dwFlags) 01102 { 01103 FIXME("(this=%p,%p,0x%08x): stub!\n", 01104 iface, hwndOwner, dwFlags); 01105 01106 return DI_OK; 01107 } 01108 01109 HRESULT WINAPI IDirectInputDevice2AImpl_Initialize( 01110 LPDIRECTINPUTDEVICE8A iface, 01111 HINSTANCE hinst, 01112 DWORD dwVersion, 01113 REFGUID rguid) 01114 { 01115 FIXME("(this=%p,%p,%d,%s): stub!\n", 01116 iface, hinst, dwVersion, debugstr_guid(rguid)); 01117 return DI_OK; 01118 } 01119 01120 /****************************************************************************** 01121 * IDirectInputDevice2A 01122 */ 01123 01124 HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect( 01125 LPDIRECTINPUTDEVICE8A iface, 01126 REFGUID rguid, 01127 LPCDIEFFECT lpeff, 01128 LPDIRECTINPUTEFFECT *ppdef, 01129 LPUNKNOWN pUnkOuter) 01130 { 01131 FIXME("(this=%p,%s,%p,%p,%p): stub!\n", 01132 iface, debugstr_guid(rguid), lpeff, ppdef, pUnkOuter); 01133 return DI_OK; 01134 } 01135 01136 HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects( 01137 LPDIRECTINPUTDEVICE8A iface, 01138 LPDIENUMEFFECTSCALLBACKA lpCallback, 01139 LPVOID lpvRef, 01140 DWORD dwFlags) 01141 { 01142 FIXME("(this=%p,%p,%p,0x%08x): stub!\n", 01143 iface, lpCallback, lpvRef, dwFlags); 01144 01145 return DI_OK; 01146 } 01147 01148 HRESULT WINAPI IDirectInputDevice2WImpl_EnumEffects( 01149 LPDIRECTINPUTDEVICE8W iface, 01150 LPDIENUMEFFECTSCALLBACKW lpCallback, 01151 LPVOID lpvRef, 01152 DWORD dwFlags) 01153 { 01154 FIXME("(this=%p,%p,%p,0x%08x): stub!\n", 01155 iface, lpCallback, lpvRef, dwFlags); 01156 01157 return DI_OK; 01158 } 01159 01160 HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo( 01161 LPDIRECTINPUTDEVICE8A iface, 01162 LPDIEFFECTINFOA lpdei, 01163 REFGUID rguid) 01164 { 01165 FIXME("(this=%p,%p,%s): stub!\n", 01166 iface, lpdei, debugstr_guid(rguid)); 01167 return DI_OK; 01168 } 01169 01170 HRESULT WINAPI IDirectInputDevice2WImpl_GetEffectInfo( 01171 LPDIRECTINPUTDEVICE8W iface, 01172 LPDIEFFECTINFOW lpdei, 01173 REFGUID rguid) 01174 { 01175 FIXME("(this=%p,%p,%s): stub!\n", 01176 iface, lpdei, debugstr_guid(rguid)); 01177 return DI_OK; 01178 } 01179 01180 HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState( 01181 LPDIRECTINPUTDEVICE8A iface, 01182 LPDWORD pdwOut) 01183 { 01184 FIXME("(this=%p,%p): stub!\n", 01185 iface, pdwOut); 01186 return DI_OK; 01187 } 01188 01189 HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand( 01190 LPDIRECTINPUTDEVICE8A iface, 01191 DWORD dwFlags) 01192 { 01193 TRACE("(%p) 0x%08x:\n", iface, dwFlags); 01194 return DI_NOEFFECT; 01195 } 01196 01197 HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects( 01198 LPDIRECTINPUTDEVICE8A iface, 01199 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, 01200 LPVOID lpvRef, 01201 DWORD dwFlags) 01202 { 01203 FIXME("(this=%p,%p,%p,0x%08x): stub!\n", 01204 iface, lpCallback, lpvRef, dwFlags); 01205 return DI_OK; 01206 } 01207 01208 HRESULT WINAPI IDirectInputDevice2AImpl_Escape( 01209 LPDIRECTINPUTDEVICE8A iface, 01210 LPDIEFFESCAPE lpDIEEsc) 01211 { 01212 FIXME("(this=%p,%p): stub!\n", 01213 iface, lpDIEEsc); 01214 return DI_OK; 01215 } 01216 01217 HRESULT WINAPI IDirectInputDevice2AImpl_Poll( 01218 LPDIRECTINPUTDEVICE8A iface) 01219 { 01220 IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; 01221 01222 if (!This->acquired) return DIERR_NOTACQUIRED; 01223 /* Because wine devices do not need to be polled, just return DI_NOEFFECT */ 01224 return DI_NOEFFECT; 01225 } 01226 01227 HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData( 01228 LPDIRECTINPUTDEVICE8A iface, 01229 DWORD cbObjectData, 01230 LPCDIDEVICEOBJECTDATA rgdod, 01231 LPDWORD pdwInOut, 01232 DWORD dwFlags) 01233 { 01234 FIXME("(this=%p,0x%08x,%p,%p,0x%08x): stub!\n", 01235 iface, cbObjectData, rgdod, pdwInOut, dwFlags); 01236 01237 return DI_OK; 01238 } 01239 01240 HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8A iface, 01241 LPCSTR lpszFileName, 01242 LPDIENUMEFFECTSINFILECALLBACK pec, 01243 LPVOID pvRef, 01244 DWORD dwFlags) 01245 { 01246 FIXME("(%p)->(%s,%p,%p,%08x): stub !\n", iface, lpszFileName, pec, pvRef, dwFlags); 01247 01248 return DI_OK; 01249 } 01250 01251 HRESULT WINAPI IDirectInputDevice7WImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8W iface, 01252 LPCWSTR lpszFileName, 01253 LPDIENUMEFFECTSINFILECALLBACK pec, 01254 LPVOID pvRef, 01255 DWORD dwFlags) 01256 { 01257 FIXME("(%p)->(%s,%p,%p,%08x): stub !\n", iface, debugstr_w(lpszFileName), pec, pvRef, dwFlags); 01258 01259 return DI_OK; 01260 } 01261 01262 HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8A iface, 01263 LPCSTR lpszFileName, 01264 DWORD dwEntries, 01265 LPDIFILEEFFECT rgDiFileEft, 01266 DWORD dwFlags) 01267 { 01268 FIXME("(%p)->(%s,%08x,%p,%08x): stub !\n", iface, lpszFileName, dwEntries, rgDiFileEft, dwFlags); 01269 01270 return DI_OK; 01271 } 01272 01273 HRESULT WINAPI IDirectInputDevice7WImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8W iface, 01274 LPCWSTR lpszFileName, 01275 DWORD dwEntries, 01276 LPDIFILEEFFECT rgDiFileEft, 01277 DWORD dwFlags) 01278 { 01279 FIXME("(%p)->(%s,%08x,%p,%08x): stub !\n", iface, debugstr_w(lpszFileName), dwEntries, rgDiFileEft, dwFlags); 01280 01281 return DI_OK; 01282 } 01283 01284 HRESULT WINAPI IDirectInputDevice8AImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface, 01285 LPDIACTIONFORMATA lpdiaf, 01286 LPCSTR lpszUserName, 01287 DWORD dwFlags) 01288 { 01289 FIXME("(%p)->(%p,%s,%08x): stub !\n", iface, lpdiaf, lpszUserName, dwFlags); 01290 #define X(x) if (dwFlags & x) FIXME("\tdwFlags =|"#x"\n"); 01291 X(DIDBAM_DEFAULT) 01292 X(DIDBAM_PRESERVE) 01293 X(DIDBAM_INITIALIZE) 01294 X(DIDBAM_HWDEFAULTS) 01295 #undef X 01296 _dump_diactionformatA(lpdiaf); 01297 return DI_OK; 01298 } 01299 01300 HRESULT WINAPI IDirectInputDevice8WImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface, 01301 LPDIACTIONFORMATW lpdiaf, 01302 LPCWSTR lpszUserName, 01303 DWORD dwFlags) 01304 { 01305 FIXME("(%p)->(%p,%s,%08x): stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags); 01306 #define X(x) if (dwFlags & x) FIXME("\tdwFlags =|"#x"\n"); 01307 X(DIDBAM_DEFAULT) 01308 X(DIDBAM_PRESERVE) 01309 X(DIDBAM_INITIALIZE) 01310 X(DIDBAM_HWDEFAULTS) 01311 #undef X 01312 01313 return DI_OK; 01314 } 01315 01316 HRESULT WINAPI IDirectInputDevice8AImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface, 01317 LPDIACTIONFORMATA lpdiaf, 01318 LPCSTR lpszUserName, 01319 DWORD dwFlags) 01320 { 01321 FIXME("(%p)->(%p,%s,%08x): stub !\n", iface, lpdiaf, lpszUserName, dwFlags); 01322 01323 return DI_OK; 01324 } 01325 01326 HRESULT WINAPI IDirectInputDevice8WImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface, 01327 LPDIACTIONFORMATW lpdiaf, 01328 LPCWSTR lpszUserName, 01329 DWORD dwFlags) 01330 { 01331 FIXME("(%p)->(%p,%s,%08x): stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags); 01332 01333 return DI_OK; 01334 } 01335 01336 HRESULT WINAPI IDirectInputDevice8AImpl_GetImageInfo(LPDIRECTINPUTDEVICE8A iface, 01337 LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader) 01338 { 01339 FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader); 01340 01341 return DI_OK; 01342 } 01343 01344 HRESULT WINAPI IDirectInputDevice8WImpl_GetImageInfo(LPDIRECTINPUTDEVICE8W iface, 01345 LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader) 01346 { 01347 FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader); 01348 01349 return DI_OK; 01350 } Generated on Sun May 27 2012 04:21:17 for ReactOS by
1.7.6.1
|