ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

device.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.