To look for already opened device, or available device index.
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
This is a bit of refactoring prior to some more patches to make XInput
device enumeration and report reading asynchronous.
Currently every call to XInputGetState does an ioctl, which introduces a
very high load on wineserver and windevice (with multiple round trips to
satisfy the ioctl).
I intend to optimize this by using a thread queueing asynchronous reads
to get …
[View More]the HID reports, and update the state in background, as well as
refreshing the device list. XInputGetState would then only be about
acquiring the critical section and copying the state.
dlls/xinput1_3/hid.c | 39 +++++++++++++++++++--------------------
1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/dlls/xinput1_3/hid.c b/dlls/xinput1_3/hid.c
index 0f4dec44ee3..e7a77813c71 100644
--- a/dlls/xinput1_3/hid.c
+++ b/dlls/xinput1_3/hid.c
@@ -71,6 +71,20 @@ struct hid_platform_private {
static DWORD last_check = 0;
+static BOOL find_opened_device(xinput_controller *devices, SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail, int *free_slot)
+{
+ struct hid_platform_private *private;
+ int i;
+
+ *free_slot = XUSER_MAX_COUNT;
+ for (i = XUSER_MAX_COUNT; i > 0; i--)
+ {
+ if (!(private = devices[i - 1].platform_private)) *free_slot = i - 1;
+ else if (!wcscmp(detail->DevicePath, private->device_path)) return TRUE;
+ }
+ return FALSE;
+}
+
static void MarkUsage(struct hid_platform_private *private, WORD usage, LONG min, LONG max, USHORT bits)
{
struct axis_info info = {min, max-min, bits};
@@ -219,7 +233,7 @@ void HID_find_gamepads(xinput_controller *devices)
HIDP_CAPS caps;
NTSTATUS status;
DWORD idx;
- int i, open_device_idx;
+ int i;
idx = GetTickCount();
if ((idx - last_check) < 2000)
@@ -255,24 +269,9 @@ void HID_find_gamepads(xinput_controller *devices)
if (!wcsstr(data->DevicePath, L"IG_"))
continue;
- open_device_idx = -1;
- for (i = 0; i < XUSER_MAX_COUNT; i++)
- {
- struct hid_platform_private *private = devices[i].platform_private;
- if (devices[i].platform_private)
- {
- if (!wcscmp(data->DevicePath, private->device_path))
- break;
- }
- else if(open_device_idx < 0)
- open_device_idx = i;
- }
- if (i != XUSER_MAX_COUNT)
- /* this device is already opened */
- continue;
- if (open_device_idx < 0)
- /* no open device slots */
- break;
+ if (find_opened_device(devices, data, &i)) continue; /* already opened */
+ if (i == XUSER_MAX_COUNT) break; /* no more slots */
+
device = CreateFileW(data->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
if (device == INVALID_HANDLE_VALUE)
continue;
@@ -286,7 +285,7 @@ void HID_find_gamepads(xinput_controller *devices)
WARN("ignoring HID device, unsupported usage page %04x\n", caps.UsagePage);
else if (caps.Usage != HID_USAGE_GENERIC_GAMEPAD && caps.Usage != HID_USAGE_GENERIC_JOYSTICK && caps.Usage != HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER)
WARN("ignoring HID device, unsupported usage %04x:%04x\n", caps.UsagePage, caps.Usage);
- else if (!init_controller(&devices[open_device_idx], ppd, &caps, device, data->DevicePath))
+ else if (!init_controller(&devices[i], ppd, &caps, device, data->DevicePath))
WARN("ignoring HID device, failed to initialize\n");
else
goto done;
--
2.32.0
[View Less]
Over the years, Wine prefixes have gotten bigger and bigger, for a
number of reasons. Creating a new Wine prefix for each application is
still the current recommendation, as despite the best efforts of Wine
developers, some applications still require system-wide workarounds.
This leads to significant bloat for each application installed. With a
MinGW build of Wine without Mono or Gecko, new 32-bit prefixes are over
150 MB, and new 64-bit prefixes are over 300 MB. The vast majority of
these …
[View More]files are byte-for-byte identical to Wine's central DLL copies.
This patch set implements reflink support in Wine via the
copy_file_range syscall. The reasons for selecting copy_file_range over
FICLONE are outlined in patch 2. A previous unpublished version of this
patch set used FICLONERANGE, but it was less convenient to use from
setupapi and has inferior system support.
When reflink is supported by the underlying filesystem, new Wine prefix
sizes with Mono and Gecko disabled are reduced to less than 1 MB. The
resulting Wine prefix is byte-for-byte identical to one created without
reflink, but occupies less space on disk. If hard links or symlinks were
used, if an application such as winetricks writes to a system file, it
would overwrite the central copy. With reflink, the file blocks will be
transparently copied by the Linux kernel so that each Wine prefix can be
independent.
Some files cannot be deduplicated in the current Wine system, as they
are dynamically generated during the Wine prefix installation process.
These include 16-bit fake DLLs and manifest files. In theory, it should
be possible to pre-generate these files, but considering the Wine prefix
size is already reduced to less than 1 MB, the extra space savings are
likely not worth the effort.
Alex Xu (Hello71) (5):
ntdll: add support for IOCTL_COPYCHUNK.
kernelbase: use IOCTL_COPYCHUNK in CopyFile*
setupapi: Use IOCTL_COPYCHUNK, avoid buffering whole file
lmshare.h: define STYPE_TEMPORARY
kernel32/tests: add IOCTL_COPYCHUNK test
configure | 1 +
configure.ac | 1 +
dlls/kernel32/tests/file.c | 137 +++++++++++++++++++++++++
dlls/kernelbase/file.c | 44 ++++----
dlls/ntdll/unix/file.c | 121 ++++++++++++++++++++++
dlls/setupapi/fakedll.c | 202 ++++++++++++++++++++-----------------
include/config.h.in | 3 +
include/lmshare.h | 11 +-
include/winioctl.h | 34 +++++++
9 files changed, 431 insertions(+), 123 deletions(-)
--
2.32.0
[View Less]
Don't cache locale data coming from the registry because it could change
at any time.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
Previously the settings of the first VarParseNumFromStr(LOCALE_USER_DEFAULT)
call ended up being cached and used for all the remaining tests, thus
causing many of them to fail.
There's a comment that says the caching is because all these lookups are
slow. And I guess the common case it likely to be the one that's no
longer cached: i.e. …
[View More]getting the current user's preferences from the
registry.
But all in all that case does not seem that slow (roughly 1.1 us per
call) so unless it's called millions of times it should be ok. Also
checking the registry key's last modification time would not make it
much faster (I expect at most x2).
---
dlls/oleaut32/tests/vartest.c | 12 +++---------
dlls/oleaut32/variant.c | 16 +++++++++++-----
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/dlls/oleaut32/tests/vartest.c b/dlls/oleaut32/tests/vartest.c
index bed4de469df..89859988f1f 100644
--- a/dlls/oleaut32/tests/vartest.c
+++ b/dlls/oleaut32/tests/vartest.c
@@ -2198,7 +2198,7 @@ static void test_VarParseNumFromStrMisc(void)
/* But SMONDECIMALSEP has no default! */
SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L"");
hres = wconvert_str(L"3.9", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
- todo_wine EXPECTFAIL;
+ EXPECTFAIL;
SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, L".");
SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L".");
@@ -2206,9 +2206,7 @@ static void test_VarParseNumFromStrMisc(void)
SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L" ");
hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS, &np, rgb, LOCALE_USER_DEFAULT, 0);
- if (broken(1)) /* FIXME Reenable once Wine is less broken */
EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,3);
- todo_wine ok(np.dwOutFlags == NUMPRS_THOUSANDS, "Got dwOutFlags=%08x\n", np.dwOutFlags);
EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
EXPECTRGB(4,FAILDIG);
@@ -2225,9 +2223,7 @@ static void test_VarParseNumFromStrMisc(void)
SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L" ");
hres = wconvert_str(L"1|000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS, &np, rgb, LOCALE_USER_DEFAULT, 0);
- if (broken(1)) /* FIXME Reenable once Wine is less broken */
EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,3);
- todo_wine ok(np.dwOutFlags == NUMPRS_THOUSANDS, "Got dwOutFlags=%08x\n", np.dwOutFlags);
EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
EXPECTRGB(4,FAILDIG);
@@ -2235,9 +2231,7 @@ static void test_VarParseNumFromStrMisc(void)
EXPECTFAIL;
hres = wconvert_str(L"1|000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY, &np, rgb, LOCALE_USER_DEFAULT, 0);
- if (broken(1)) /* FIXME Reenable once Wine is less broken */
EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,NUMPRS_THOUSANDS,5,0,3);
- todo_wine ok(np.dwOutFlags == NUMPRS_THOUSANDS, "Got dwOutFlags=%08x\n", np.dwOutFlags);
EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
EXPECTRGB(4,FAILDIG);
@@ -2298,14 +2292,14 @@ static void test_VarParseNumFromStrMisc(void)
SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L"\xa0");
hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
- todo_wine EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,5,0,3);
+ EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,5,0,3);
EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
EXPECTRGB(4,FAILDIG);
/* Regular thousands separators also have precedence over the currency ones */
hres = wconvert_str(L"1\xa0\x30\x30\x30", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
- todo_wine EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,5,0,3);
+ EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,5,0,3);
EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
EXPECTRGB(4,FAILDIG);
diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c
index e4993de75a5..15fc7f9042e 100644
--- a/dlls/oleaut32/variant.c
+++ b/dlls/oleaut32/variant.c
@@ -1529,8 +1529,11 @@ static void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID
EnterCriticalSection(&cache_cs);
/* Asking for default locale entries is very expensive: It is a registry
- server call. So cache one locally, as Microsoft does it too */
- if(lcid == lastLcid && dwFlags == lastFlags)
+ * server call. So cache one locally, as Microsoft does it too.
+ * Note: Data in the registry could change at any time so only cache when
+ * LOCALE_NOUSEROVERRIDE is used.
+ */
+ if (lctype && lcid == lastLcid && dwFlags == lastFlags)
{
memcpy(lpChars, &lastChars, sizeof(defaultChars));
LeaveCriticalSection(&cache_cs);
@@ -1557,9 +1560,12 @@ static void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID
TRACE("lcid 0x%x, cCurrencyLocal=%d,%d %s\n", lcid, lpChars->cCurrencyLocal,
lpChars->cCurrencyLocal2, wine_dbgstr_w(buff));
- memcpy(&lastChars, lpChars, sizeof(defaultChars));
- lastLcid = lcid;
- lastFlags = dwFlags;
+ if (lctype)
+ {
+ memcpy(&lastChars, lpChars, sizeof(defaultChars));
+ lastLcid = lcid;
+ lastFlags = dwFlags;
+ }
LeaveCriticalSection(&cache_cs);
}
--
2.20.1
[View Less]