mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-19 17:06:04 -07:00
Compare commits
88 commits
f69a2b69f6
...
c9d3eea192
Author | SHA1 | Date | |
---|---|---|---|
|
c9d3eea192 | ||
|
ae6366b33c | ||
|
d9cf4678a1 | ||
|
da936bcf35 | ||
|
e75192fe72 | ||
|
0dc7e40468 | ||
|
700ee59470 | ||
|
c76a192bf6 | ||
|
9acdc03128 | ||
|
8b121591be | ||
|
5a23afb34d | ||
|
6a01532899 | ||
|
e5b0ead2b5 | ||
|
b9c06c4474 | ||
|
a57eedec86 | ||
|
9212706ede | ||
|
40b314cf34 | ||
|
aa24458086 | ||
|
576d7e24cd | ||
|
305ec347dc | ||
|
4c0103e58c | ||
|
1137a10ef7 | ||
|
eae7db4fa4 | ||
|
75e2ec479b | ||
|
45953cdbec | ||
|
126c54cd25 | ||
|
ab40b7fd86 | ||
|
0bd49a68dc | ||
|
50683f7b32 | ||
|
48bb5f90a2 | ||
|
7352196f6a | ||
|
4eefc0b9a9 | ||
|
51f6839395 | ||
|
b240f8ea93 | ||
|
54b9f68b8e | ||
|
5a7a4b7f1a | ||
|
698ab75a59 | ||
|
8e2442584c | ||
|
6d1df55bf3 | ||
|
9f8ef43991 | ||
|
5c597119a0 | ||
|
c20bf25556 | ||
|
194ada7583 | ||
|
8a87ce3c4f | ||
|
f47da4307f | ||
|
0f84798246 | ||
|
0eda6a76c7 | ||
|
38f1ce3210 | ||
|
9b264c948f | ||
|
055bf9f5a2 | ||
|
18aefb5dcf | ||
|
85331da430 | ||
|
5947a66f4c | ||
|
12755eeb1c | ||
|
e3258e7620 | ||
|
968ab4e79a | ||
|
b1dd7da806 | ||
|
199274d420 | ||
|
7ac35f13cb | ||
|
1f42d452aa | ||
|
96c37c23f6 | ||
|
f588fec26c | ||
|
70258a160f | ||
|
b02b73673b | ||
|
a5de8d85d3 | ||
|
5b10f924fa | ||
|
ea3c73b12d | ||
|
a93623eced | ||
|
194901b592 | ||
|
484c43c9e9 | ||
|
1125bb8f71 | ||
|
19018abf86 | ||
|
32be056558 | ||
|
e3db89aa9d | ||
|
61d8e74e72 | ||
|
427f8fae20 | ||
|
71b4377e68 | ||
|
a7b1e5d5dc | ||
|
dd6e73428d | ||
|
3181ae039e | ||
|
786cf5a20b | ||
|
9accb76341 | ||
|
6208d61055 | ||
|
966cec7a63 | ||
|
23db166ec8 | ||
|
6dd7cd59d9 | ||
|
083102cd83 | ||
|
375ff622d1 |
121 changed files with 10342 additions and 8292 deletions
64
.gitattributes
vendored
Normal file
64
.gitattributes
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
[attr]generated gitlab-generated linguist-generated=true
|
||||
|
||||
# generated by autotools
|
||||
configure generated
|
||||
include/config.h.in generated
|
||||
|
||||
# generated by dlls/dsound/make_fir
|
||||
dlls/dsound/fir.h generated
|
||||
|
||||
# generated by dlls/opencl/make_opencl
|
||||
dlls/opencl/opencl.spec generated
|
||||
dlls/opencl/opencl_types.h generated
|
||||
dlls/opencl/pe_thunks.c generated
|
||||
dlls/opencl/unix_thunks.c generated
|
||||
dlls/opencl/unixlib.h generated
|
||||
|
||||
# generated by dlls/opengl32/make_opengl
|
||||
dlls/opengl32/opengl32.spec generated
|
||||
dlls/opengl32/thunks.c generated
|
||||
dlls/opengl32/unix_thunks.c generated
|
||||
dlls/opengl32/unixlib.h generated
|
||||
include/wine/wgl.h generated
|
||||
include/wine/wgl_driver.h generated
|
||||
|
||||
# generated by dlls/winevulkan/make_vulkan
|
||||
dlls/vulkan-1/vulkan-1.spec generated
|
||||
dlls/winevulkan/loader_thunks.c generated
|
||||
dlls/winevulkan/loader_thunks.h generated
|
||||
dlls/winevulkan/vulkan_thunks.c generated
|
||||
dlls/winevulkan/vulkan_thunks.h generated
|
||||
dlls/winevulkan/winevulkan.json generated
|
||||
dlls/winevulkan/winevulkan.spec generated
|
||||
include/wine/vulkan.h generated
|
||||
include/wine/vulkan_driver.h generated
|
||||
|
||||
# generated by tools/make_requests
|
||||
include/wine/server_protocol.h generated
|
||||
server/request_handlers.h generated
|
||||
server/request_trace.h generated
|
||||
|
||||
# generated by tools/make_specfiles
|
||||
dlls/ntdll/ntsyscalls.h generated
|
||||
dlls/win32u/win32syscalls.h generated
|
||||
|
||||
# generated by tools/make_unicode
|
||||
dlls/dwrite/bracket.c generated
|
||||
dlls/dwrite/direction.c generated
|
||||
dlls/dwrite/linebreak.c generated
|
||||
dlls/dwrite/mirror.c generated
|
||||
dlls/dwrite/scripts.c generated
|
||||
dlls/dwrite/scripts.h generated
|
||||
dlls/dwrite/shapers/arabic_table.c generated
|
||||
dlls/gdi32/uniscribe/bracket.c generated
|
||||
dlls/gdi32/uniscribe/direction.c generated
|
||||
dlls/gdi32/uniscribe/indicsyllable.c generated
|
||||
dlls/gdi32/uniscribe/linebreak.c generated
|
||||
dlls/gdi32/uniscribe/mirror.c generated
|
||||
dlls/gdi32/uniscribe/shaping.c generated
|
||||
dlls/kernelbase/kernelbase.rgs generated
|
||||
dlls/tzres/tzres.rc generated
|
||||
dlls/win32u/vertical.c generated
|
||||
dlls/wineps.drv/direction.c generated
|
||||
dlls/wineps.drv/vertical.c generated
|
||||
nls/*.nls generated
|
3
aclocal.m4
vendored
3
aclocal.m4
vendored
|
@ -198,6 +198,9 @@ ac_wine_try_cflags_saved_exeext=$ac_exeext
|
|||
CFLAGS="$CFLAGS -nostdlib -nodefaultlibs $1"
|
||||
ac_exeext=".exe"
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }]])],
|
||||
[AS_VAR_SET(ac_var,yes)], [AS_VAR_SET(ac_var,no)])
|
||||
CFLAGS=$ac_wine_try_cflags_saved
|
||||
|
|
185
configure
generated
vendored
185
configure
generated
vendored
|
@ -10407,6 +10407,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10444,6 +10447,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10660,6 +10666,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10696,6 +10705,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10732,6 +10744,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10768,6 +10783,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10804,6 +10822,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10840,6 +10861,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10876,6 +10900,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10912,6 +10939,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10948,6 +10978,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10984,6 +11017,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11020,6 +11056,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11056,6 +11095,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11092,6 +11134,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11128,6 +11173,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11164,6 +11212,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11200,6 +11251,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11236,6 +11290,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11272,6 +11329,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11308,6 +11368,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11344,6 +11407,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11380,6 +11446,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11403,6 +11472,86 @@ then :
|
|||
as_fn_append ${wine_arch}_EXTRACFLAGS " -Wenum-conversion"
|
||||
fi } ;;
|
||||
esac
|
||||
fi }
|
||||
{ as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-ffunction-sections" | sed "$as_sed_sh"`
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -ffunction-sections" >&5
|
||||
printf %s "checking whether $CC supports -ffunction-sections... " >&6; }
|
||||
if eval test \${$as_ac_var+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else case e in #(
|
||||
e) ac_wine_try_cflags_saved=$CFLAGS
|
||||
ac_wine_try_cflags_saved_exeext=$ac_exeext
|
||||
CFLAGS="$CFLAGS -nostdlib -nodefaultlibs -ffunction-sections"
|
||||
ac_exeext=".exe"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
eval "$as_ac_var=yes"
|
||||
else case e in #(
|
||||
e) eval "$as_ac_var=no" ;;
|
||||
esac
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
CFLAGS=$ac_wine_try_cflags_saved
|
||||
ac_exeext=$ac_wine_try_cflags_saved_exeext ;;
|
||||
esac
|
||||
fi
|
||||
eval ac_res=\$$as_ac_var
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
printf "%s\n" "$ac_res" >&6; }
|
||||
if eval test \"x\$"$as_ac_var"\" = x"yes"
|
||||
then :
|
||||
as_fn_append ${wine_arch}_EXTRACFLAGS " -ffunction-sections"
|
||||
fi }
|
||||
|
||||
{ as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-fms-hotpatch -DMIN_CLANG_VERSION=18" | sed "$as_sed_sh"`
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -fms-hotpatch -DMIN_CLANG_VERSION=18" >&5
|
||||
printf %s "checking whether $CC supports -fms-hotpatch -DMIN_CLANG_VERSION=18... " >&6; }
|
||||
if eval test \${$as_ac_var+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else case e in #(
|
||||
e) ac_wine_try_cflags_saved=$CFLAGS
|
||||
ac_wine_try_cflags_saved_exeext=$ac_exeext
|
||||
CFLAGS="$CFLAGS -nostdlib -nodefaultlibs -fms-hotpatch -DMIN_CLANG_VERSION=18"
|
||||
ac_exeext=".exe"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
eval "$as_ac_var=yes"
|
||||
else case e in #(
|
||||
e) eval "$as_ac_var=no" ;;
|
||||
esac
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
CFLAGS=$ac_wine_try_cflags_saved
|
||||
ac_exeext=$ac_wine_try_cflags_saved_exeext ;;
|
||||
esac
|
||||
fi
|
||||
eval ac_res=\$$as_ac_var
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
printf "%s\n" "$ac_res" >&6; }
|
||||
if eval test \"x\$"$as_ac_var"\" = x"yes"
|
||||
then :
|
||||
as_fn_append ${wine_arch}_EXTRACFLAGS " -fms-hotpatch"
|
||||
as_fn_append ${wine_arch}_LDFLAGS " -fms-hotpatch"
|
||||
fi }
|
||||
|
||||
{ as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-flarge-source-files -Wmisleading-indentation" | sed "$as_sed_sh"`
|
||||
|
@ -11419,6 +11568,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11457,6 +11609,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11493,6 +11648,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11529,6 +11687,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11565,6 +11726,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11601,6 +11765,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11637,6 +11804,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11673,6 +11843,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11732,6 +11905,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11768,6 +11944,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11808,6 +11987,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11844,6 +12026,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
|
|
@ -961,6 +961,12 @@ This is an error since --enable-archs=$wine_arch was requested.])])
|
|||
WINE_TRY_PE_CFLAGS([-Wlogical-op])
|
||||
WINE_TRY_PE_CFLAGS([-Wabsolute-value])
|
||||
WINE_TRY_PE_CFLAGS([-Wenum-enum-conversion],[:],WINE_TRY_PE_CFLAGS([-Wenum-conversion]))
|
||||
WINE_TRY_PE_CFLAGS([-ffunction-sections])
|
||||
|
||||
dnl clang had broken -fms-hotpatch support before version 18 (https://github.com/llvm/llvm-project/pull/77245)
|
||||
WINE_TRY_PE_CFLAGS([-fms-hotpatch -DMIN_CLANG_VERSION=18],
|
||||
[AS_VAR_APPEND([${wine_arch}_EXTRACFLAGS],[" -fms-hotpatch"])
|
||||
AS_VAR_APPEND([${wine_arch}_LDFLAGS],[" -fms-hotpatch"])])
|
||||
|
||||
dnl GCC can't handle large files when -Wmisleading-indentation is enabled (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89549)
|
||||
WINE_TRY_PE_CFLAGS([-flarge-source-files -Wmisleading-indentation],[AS_VAR_APPEND(${wine_arch}_EXTRACFLAGS,[" -Wno-misleading-indentation"])])
|
||||
|
|
|
@ -4150,6 +4150,7 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN
|
|||
/* see if we are supposed to be tracking mouse hovering */
|
||||
if (LISTVIEW_IsHotTracking(infoPtr)) {
|
||||
TRACKMOUSEEVENT trackinfo;
|
||||
NMLISTVIEW nmlv = { 0 };
|
||||
DWORD flags;
|
||||
|
||||
trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||
|
@ -4170,6 +4171,15 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN
|
|||
/* call TRACKMOUSEEVENT so we receive WM_MOUSEHOVER messages */
|
||||
_TrackMouseEvent(&trackinfo);
|
||||
}
|
||||
|
||||
ht.pt = pt;
|
||||
LISTVIEW_HitTest(infoPtr, &ht, TRUE, TRUE);
|
||||
|
||||
nmlv.iItem = ht.iItem;
|
||||
nmlv.iSubItem = ht.iSubItem;
|
||||
nmlv.ptAction = pt;
|
||||
|
||||
notify_listview(infoPtr, LVN_HOTTRACK, &nmlv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -9585,6 +9595,7 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, WPARAM wParam, const CREATESTRUCTW *
|
|||
infoPtr->iVersion = COMCTL32_VERSION;
|
||||
infoPtr->colRectsDirty = FALSE;
|
||||
infoPtr->selected_column = -1;
|
||||
infoPtr->hHotCursor = LoadCursorW(NULL, (LPWSTR)IDC_HAND);
|
||||
|
||||
/* get default font (icon title) */
|
||||
SystemParametersInfoW(SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
|
||||
|
|
|
@ -7255,6 +7255,19 @@ static void test_LVM_GETNEXTITEM(void)
|
|||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void test_LVM_GETHOTCURSOR(void)
|
||||
{
|
||||
HCURSOR cursor;
|
||||
HWND hwnd;
|
||||
|
||||
hwnd = create_listview_control(LVS_REPORT);
|
||||
|
||||
cursor = (HCURSOR)SendMessageA(hwnd, LVM_GETHOTCURSOR, 0, 0);
|
||||
ok(!!cursor, "Unexpected cursor %p.\n", cursor);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
START_TEST(listview)
|
||||
{
|
||||
ULONG_PTR ctx_cookie;
|
||||
|
@ -7322,6 +7335,7 @@ START_TEST(listview)
|
|||
test_LVM_SETBKIMAGE(FALSE);
|
||||
test_custom_sort();
|
||||
test_LVM_GETNEXTITEM();
|
||||
test_LVM_GETHOTCURSOR();
|
||||
|
||||
if (!load_v6_module(&ctx_cookie, &hCtx))
|
||||
{
|
||||
|
@ -7372,6 +7386,7 @@ START_TEST(listview)
|
|||
test_LVM_GETNEXTITEMINDEX();
|
||||
test_LVM_GETNEXTITEM();
|
||||
test_LVM_SETBKIMAGE(TRUE);
|
||||
test_LVM_GETHOTCURSOR();
|
||||
|
||||
unload_v6_module(ctx_cookie, hCtx);
|
||||
|
||||
|
|
|
@ -4379,7 +4379,13 @@ static BOOL codeview_process_info(const struct process *pcs,
|
|||
|
||||
TRACE("Got RSDS type of PDB file: guid=%s age=%08x name=%s\n",
|
||||
wine_dbgstr_guid(&rsds->guid), rsds->age, debugstr_a(rsds->name));
|
||||
ret = pdb_process_file(pcs, msc_dbg, rsds->name, &rsds->guid, 0, rsds->age);
|
||||
/* gcc/mingw and clang can emit build-id information, but with an empty PDB filename.
|
||||
* Don't search for the .pdb file in that case.
|
||||
*/
|
||||
if (rsds->name[0])
|
||||
ret = pdb_process_file(pcs, msc_dbg, rsds->name, &rsds->guid, 0, rsds->age);
|
||||
else
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -4487,7 +4493,7 @@ typedef struct _FPO_DATA
|
|||
__ENDTRY
|
||||
|
||||
/* we haven't found yet any debug information, fallback to unmatched pdb */
|
||||
if (module->module.SymType == SymDeferred)
|
||||
if (!ret && module->module.SymType == SymDeferred)
|
||||
{
|
||||
SYMSRV_INDEX_INFOW info = {.sizeofstruct = sizeof(info)};
|
||||
char buffer[MAX_PATH];
|
||||
|
@ -4549,38 +4555,35 @@ DWORD msc_get_file_indexinfo(void* image, const IMAGE_DEBUG_DIRECTORY* debug_dir
|
|||
num_misc_records++;
|
||||
}
|
||||
}
|
||||
return info->stripped && !num_misc_records ? ERROR_BAD_EXE_FORMAT : ERROR_SUCCESS;
|
||||
return (!num_dir || (info->stripped && !num_misc_records)) ? ERROR_BAD_EXE_FORMAT : ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info)
|
||||
{
|
||||
const IMAGE_SEPARATE_DEBUG_HEADER *header;
|
||||
IMAGE_DEBUG_DIRECTORY *dbg;
|
||||
DWORD num_directories;
|
||||
|
||||
if (size < sizeof(*header)) return ERROR_BAD_EXE_FORMAT;
|
||||
if (size < sizeof(*header)) return ERROR_BAD_FORMAT;
|
||||
header = image;
|
||||
if (header->Signature != 0x4944 /* DI */ ||
|
||||
size < sizeof(*header) + header->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) + header->ExportedNamesSize + header->DebugDirectorySize)
|
||||
return ERROR_BAD_EXE_FORMAT;
|
||||
return ERROR_BAD_FORMAT;
|
||||
|
||||
info->size = header->SizeOfImage;
|
||||
/* seems to use header's timestamp, not debug_directory one */
|
||||
info->timestamp = header->TimeDateStamp;
|
||||
info->stripped = FALSE; /* FIXME */
|
||||
|
||||
/* header is followed by:
|
||||
* - header->NumberOfSections of IMAGE_SECTION_HEADER
|
||||
* - header->ExportedNameSize
|
||||
* - then num_directories of IMAGE_DEBUG_DIRECTORY
|
||||
*/
|
||||
dbg = (IMAGE_DEBUG_DIRECTORY*)((char*)(header + 1) +
|
||||
header->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
|
||||
header->ExportedNamesSize);
|
||||
num_directories = header->DebugDirectorySize / sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
|
||||
if (!num_directories) return ERROR_BAD_EXE_FORMAT;
|
||||
|
||||
info->age = 0;
|
||||
memset(&info->guid, 0, sizeof(info->guid));
|
||||
info->sig = 0;
|
||||
info->dbgfile[0] = L'\0';
|
||||
info->pdbfile[0] = L'\0';
|
||||
info->size = header->SizeOfImage;
|
||||
/* seems to use header's timestamp, not debug_directory one */
|
||||
info->timestamp = header->TimeDateStamp;
|
||||
info->stripped = FALSE; /* FIXME */
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
return msc_get_file_indexinfo(image, dbg, num_directories, info);
|
||||
}
|
||||
|
|
|
@ -832,7 +832,7 @@ BOOL WINAPI SymSrvGetFileIndexInfoW(const WCHAR *file, SYMSRV_INDEX_INFOW* info,
|
|||
if (hMap) CloseHandle(hMap);
|
||||
if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
|
||||
|
||||
if (ret == ERROR_SUCCESS) wcscpy(info->file, file_name(file)); /* overflow? */
|
||||
if (ret == ERROR_SUCCESS || ret == ERROR_BAD_EXE_FORMAT) wcscpy(info->file, file_name(file)); /* overflow? */
|
||||
SetLastError(ret);
|
||||
return ret == ERROR_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -656,8 +656,8 @@ static BOOL pe_load_msc_debug_info(const struct process* pcs, struct module* mod
|
|||
if (nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC ||
|
||||
misc->DataType != IMAGE_DEBUG_MISC_EXENAME)
|
||||
{
|
||||
ERR("-Debug info stripped, but no .DBG file in module %s\n",
|
||||
debugstr_w(module->modulename));
|
||||
WARN("-Debug info stripped, but no .DBG file in module %s\n",
|
||||
debugstr_w(module->modulename));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1019,7 +1019,7 @@ DWORD pe_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info)
|
|||
if (!(nthdr = RtlImageNtHeader(image))) return ERROR_BAD_FORMAT;
|
||||
|
||||
dbg = RtlImageDirectoryEntryToData(image, FALSE, IMAGE_DIRECTORY_ENTRY_DEBUG, &dirsize);
|
||||
if (!dbg || dirsize < sizeof(dbg)) return ERROR_BAD_EXE_FORMAT;
|
||||
if (!dbg) dirsize = 0;
|
||||
|
||||
/* fill in information from NT header */
|
||||
info->timestamp = nthdr->FileHeader.TimeDateStamp;
|
||||
|
|
|
@ -671,20 +671,22 @@ static BOOL create_test_pdb_ds(const WCHAR* pdb_name, const GUID* guid, DWORD ag
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL create_test_dbg(const WCHAR* dbg_name, WORD machine, DWORD timestamp, DWORD size)
|
||||
static BOOL create_test_dbg(const WCHAR* dbg_name, WORD machine, DWORD charac, DWORD timestamp, DWORD size, struct debug_directory_blob *blob)
|
||||
{
|
||||
HANDLE hfile;
|
||||
|
||||
/* minimalistic .dbg made of a header and a DEBUG_DIRECTORY without any data */
|
||||
const IMAGE_SEPARATE_DEBUG_HEADER header = {.Signature = 0x4944 /* DI */,
|
||||
.Flags = 0, .Machine = machine, .Characteristics = 0x010E, .TimeDateStamp = timestamp,
|
||||
IMAGE_SEPARATE_DEBUG_HEADER header =
|
||||
{
|
||||
.Signature = 0x4944 /* DI */,
|
||||
.Flags = 0, .Machine = machine, .Characteristics = charac, .TimeDateStamp = timestamp,
|
||||
.CheckSum = 0, .ImageBase = 0x00040000, .SizeOfImage = size, .NumberOfSections = 0,
|
||||
.ExportedNamesSize = 0, .DebugDirectorySize = sizeof(IMAGE_DEBUG_DIRECTORY)};
|
||||
const IMAGE_DEBUG_DIRECTORY debug_dir = {.Characteristics = 0, .TimeDateStamp = timestamp + 1,
|
||||
.MajorVersion = 0, .MinorVersion = 0, .Type = IMAGE_DEBUG_TYPE_CODEVIEW,
|
||||
.SizeOfData = 0, .AddressOfRawData = 0,
|
||||
.PointerToRawData = sizeof(header) + header.NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
|
||||
header.DebugDirectorySize};
|
||||
.ExportedNamesSize = 0, .DebugDirectorySize = 0
|
||||
};
|
||||
DWORD where, expected_size;
|
||||
|
||||
if (blob)
|
||||
header.DebugDirectorySize = sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
|
||||
hfile = CreateFileW(dbg_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0);
|
||||
ok(hfile != INVALID_HANDLE_VALUE, "failed to create %ls err %lu\n", dbg_name, GetLastError());
|
||||
|
@ -692,8 +694,18 @@ static BOOL create_test_dbg(const WCHAR* dbg_name, WORD machine, DWORD timestamp
|
|||
|
||||
check_write_file(hfile, &header, sizeof(header));
|
||||
/* FIXME: 0 sections... as header.NumberOfSections */
|
||||
check_write_file(hfile, &debug_dir, sizeof(debug_dir));
|
||||
ok(SetFilePointer(hfile, 0, NULL, FILE_CURRENT) == debug_dir.PointerToRawData, "mismatch\n");
|
||||
if (blob)
|
||||
{
|
||||
where = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
|
||||
blob->debug_directory.PointerToRawData = (blob->debug_directory.SizeOfData) ?
|
||||
where + sizeof(IMAGE_DEBUG_DIRECTORY) : 0;
|
||||
check_write_file(hfile, &blob->debug_directory, sizeof(IMAGE_DEBUG_DIRECTORY));
|
||||
check_write_file(hfile, blob->content, blob->debug_directory.SizeOfData);
|
||||
}
|
||||
expected_size = sizeof(header) + header.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
|
||||
if (blob)
|
||||
expected_size += sizeof(IMAGE_DEBUG_DIRECTORY) + blob->debug_directory.SizeOfData;
|
||||
ok(SetFilePointer(hfile, 0, NULL, FILE_CURRENT) == expected_size, "Incorrect file length\n");
|
||||
|
||||
CloseHandle(hfile);
|
||||
return TRUE;
|
||||
|
@ -725,16 +737,16 @@ static void test_srvgetindexes_pe(void)
|
|||
DWORD sig;
|
||||
WCHAR pdb_name[16];
|
||||
WCHAR dbg_name[16];
|
||||
BOOL in_error;
|
||||
DWORD last_error;
|
||||
}
|
||||
indexes[] =
|
||||
{
|
||||
/* error cases */
|
||||
/* 0 */{0, {-1, -1, -1}, .in_error = TRUE},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 0, -1, -1}, .in_error = TRUE},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 1, -1, -1}, .in_error = TRUE},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 2, -1, -1}, .in_error = TRUE},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, {-1, -1, -1}, .in_error = TRUE}, /* not 100% logical ! */
|
||||
/* 0 */{0, {-1, -1, -1}, 0, &null_guid, 0, .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 0, -1, -1}, 0, &null_guid, 0, .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 1, -1, -1}, 123, &null_guid, 0xaaaabbbb, .pdb_name = L"pdbjg.pdb", .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 2, -1, -1}, 124, &guid1, 0, .pdb_name = L"pdbds.pdb", .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, {-1, -1, -1}, 0, &null_guid, 0, .last_error = ERROR_BAD_EXE_FORMAT}, /* not 100% logical ! */
|
||||
/* success */
|
||||
/* 5 */{0, { 0, -1, -1}, 0, &null_guid, 0 },
|
||||
{0, { 1, -1, -1}, 123, &null_guid, 0xaaaabbbb, .pdb_name = L"pdbjg.pdb"},
|
||||
|
@ -796,16 +808,16 @@ static void test_srvgetindexes_pe(void)
|
|||
memset(&ssii, 0xa5, sizeof(ssii));
|
||||
ssii.sizeofstruct = sizeof(ssii);
|
||||
ret = SymSrvGetFileIndexInfoW(filename, &ssii, 0);
|
||||
if (indexes[i].in_error)
|
||||
if (indexes[i].last_error)
|
||||
{
|
||||
ok(!ret, "SymSrvGetFileIndexInfo should have failed\n");
|
||||
ok(GetLastError() == ERROR_BAD_EXE_FORMAT, "Mismatch in GetLastError: %lu\n", GetLastError());
|
||||
ok(GetLastError() == indexes[i].last_error, "Mismatch in GetLastError: %lu\n", GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(ret, "SymSrvGetFileIndexInfo failed: %lu\n", GetLastError());
|
||||
|
||||
ok(ssii.age == indexes[i].age, "Mismatch in age: %lx\n", ssii.age);
|
||||
if (ret || indexes[i].last_error == ERROR_BAD_EXE_FORMAT)
|
||||
{
|
||||
ok(ssii.age == indexes[i].age, "Mismatch in age: %lu\n", ssii.age);
|
||||
ok(IsEqualGUID(&ssii.guid, indexes[i].guid),
|
||||
"Mismatch in guid: guid=%s\n", wine_dbgstr_guid(&ssii.guid));
|
||||
|
||||
|
@ -882,48 +894,69 @@ static void test_srvgetindexes_dbg(void)
|
|||
WCHAR filename[128];
|
||||
SYMSRV_INDEX_INFOW ssii;
|
||||
BOOL ret;
|
||||
struct debug_directory_blob *blob_refs[1];
|
||||
|
||||
static struct
|
||||
{
|
||||
/* input parameters */
|
||||
WORD machine;
|
||||
DWORD timestamp;
|
||||
DWORD imagesize;
|
||||
WORD machine;
|
||||
DWORD characteristics;
|
||||
DWORD timestamp;
|
||||
DWORD imagesize;
|
||||
int blob;
|
||||
/* output parameters */
|
||||
DWORD age;
|
||||
const GUID *guid;
|
||||
WCHAR pdbname[16];
|
||||
WCHAR dbgname[16];
|
||||
DWORD last_error;
|
||||
}
|
||||
indexes[] =
|
||||
{
|
||||
{IMAGE_FILE_MACHINE_I386, 0x1234, 0x00560000},
|
||||
{IMAGE_FILE_MACHINE_AMD64, 0x1235, 0x00570000},
|
||||
{IMAGE_FILE_MACHINE_I386, 0, 0x1234, 0x00560000, -1, 0, &null_guid, .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_MACHINE_AMD64, 0, 0x1235, 0x00570000, -1, 0, &null_guid, .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_MACHINE_I386, 0, 0x1234, 0x00560000, 0, 123, &guid1, .pdbname=L"foo.pdb"},
|
||||
{IMAGE_FILE_MACHINE_AMD64, 0, 0x1235, 0x00570000, 0, 123, &guid1, .pdbname=L"foo.pdb"},
|
||||
};
|
||||
|
||||
blob_refs[0] = make_pdb_ds_blob(0x1226, &guid1, 123, "foo.pdb");
|
||||
for (i = 0; i < ARRAY_SIZE(indexes); i++)
|
||||
{
|
||||
winetest_push_context("dbg#%02u", i);
|
||||
|
||||
/* create dll */
|
||||
swprintf(filename, ARRAY_SIZE(filename), L"winetest%02u.dbg", i);
|
||||
ret = create_test_dbg(filename, indexes[i].machine, indexes[i].timestamp, indexes[i].imagesize);
|
||||
ret = create_test_dbg(filename, indexes[i].machine, indexes[i].characteristics,
|
||||
indexes[i].timestamp, indexes[i].imagesize,
|
||||
indexes[i].blob == -1 ? NULL : blob_refs[indexes[i].blob]);
|
||||
ok(ret, "Couldn't create dbg file %ls\n", filename);
|
||||
|
||||
memset(&ssii, 0x45, sizeof(ssii));
|
||||
ssii.sizeofstruct = sizeof(ssii);
|
||||
ret = SymSrvGetFileIndexInfoW(filename, &ssii, 0);
|
||||
ok(ret, "SymSrvGetFileIndexInfo failed: %lu\n", GetLastError());
|
||||
if (indexes[i].last_error)
|
||||
{
|
||||
ok(!ret, "SymSrvGetFileIndexInfo should have\n");
|
||||
ok(GetLastError() == ERROR_BAD_EXE_FORMAT, "Unexpected last error: %lu\n", GetLastError());
|
||||
}
|
||||
else
|
||||
ok(ret, "SymSrvGetFileIndexInfo failed: %lu\n", GetLastError());
|
||||
|
||||
ok(ssii.age == 0, "Mismatch in age: %lx\n", ssii.age);
|
||||
ok(!memcmp(&ssii.guid, &null_guid, sizeof(GUID)),
|
||||
ok(ssii.age == indexes[i].age, "Mismatch in age: %lx\n", ssii.age);
|
||||
ok(IsEqualGUID(&ssii.guid, indexes[i].guid),
|
||||
"Mismatch in guid: guid=%s\n", wine_dbgstr_guid(&ssii.guid));
|
||||
|
||||
ok(ssii.sig == 0, "Mismatch in sig: %lx\n", ssii.sig);
|
||||
ok(ssii.size == indexes[i].imagesize, "Mismatch in size: %lx\n", ssii.size);
|
||||
ok(!ssii.stripped, "Mismatch in stripped: %x\n", ssii.stripped);
|
||||
ok(ssii.timestamp == indexes[i].timestamp, "Mismatch in timestamp: %lx\n", ssii.timestamp);
|
||||
ok(!wcscmp(ssii.file, filename), "Mismatch in file: %ls\n", ssii.file);
|
||||
ok(!ssii.pdbfile[0], "Mismatch in pdbfile: %ls\n", ssii.pdbfile);
|
||||
ok(!ssii.dbgfile[0], "Mismatch in dbgfile: %ls\n", ssii.dbgfile);
|
||||
ok(!wcscmp(ssii.pdbfile, indexes[i].pdbname), "Mismatch in pdbfile: %ls\n", ssii.pdbfile);
|
||||
ok(!wcscmp(ssii.dbgfile, indexes[i].dbgname), "Mismatch in dbgfile: %ls\n", ssii.dbgfile);
|
||||
|
||||
DeleteFileW(filename);
|
||||
winetest_pop_context();
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(blob_refs); i++) free(blob_refs[i]);
|
||||
}
|
||||
|
||||
static void make_path(WCHAR file[MAX_PATH], const WCHAR* topdir, const WCHAR* subdir, const WCHAR* base)
|
||||
|
@ -1533,7 +1566,8 @@ static void test_load_modules_path(void)
|
|||
if (test_files[val].guid)
|
||||
create_test_pdb_ds(filename, test_files[val].guid, test_files[val].age_or_timestamp);
|
||||
else
|
||||
create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64 /* FIXME */, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000);
|
||||
/*create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64, 0x10E, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000, blob); */
|
||||
ok(0, "not supported yet\n");
|
||||
}
|
||||
else ok(0, "Unrecognized file reference %c\n", *ptr);
|
||||
}
|
||||
|
@ -1754,7 +1788,7 @@ static void test_load_modules_details(void)
|
|||
if (test_files[val].guid)
|
||||
create_test_pdb_ds(filename, test_files[val].guid, test_files[val].age_or_timestamp);
|
||||
else
|
||||
create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64 /* FIXME */, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000);
|
||||
create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64 /* FIXME */, 0x10E, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000, NULL);
|
||||
}
|
||||
else ok(0, "Unrecognized file reference %c\n", *ptr);
|
||||
}
|
||||
|
|
|
@ -897,7 +897,7 @@ static HRESULT layout_shape_get_user_features(const struct dwrite_textlayout *la
|
|||
feature_count = IDWriteTypography_GetFontFeatureCount(typography);
|
||||
if (!feature_count)
|
||||
{
|
||||
i = range->h.range.length - i + 1;
|
||||
i = range->h.range.startPosition + range->h.range.length;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -656,7 +656,13 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val)
|
|||
TRACE("no prop_put\n");
|
||||
return S_OK;
|
||||
}
|
||||
return This->builtin_info->prop_put(This, prop->u.id, val);
|
||||
hres = This->builtin_info->prop_put(This, prop->u.id, val);
|
||||
if(hres != S_FALSE)
|
||||
return hres;
|
||||
prop->type = PROP_JSVAL;
|
||||
prop->flags = PROPF_ENUMERABLE | PROPF_CONFIGURABLE | PROPF_WRITABLE;
|
||||
prop->u.val = jsval_undefined();
|
||||
break;
|
||||
default:
|
||||
ERR("type %d\n", prop->type);
|
||||
return E_FAIL;
|
||||
|
@ -2322,8 +2328,21 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IWineJSDispatch *iface, DI
|
|||
static HRESULT WINAPI DispatchEx_GetMemberProperties(IWineJSDispatch *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
|
||||
{
|
||||
jsdisp_t *This = impl_from_IWineJSDispatch(iface);
|
||||
FIXME("(%p)->(%lx %lx %p)\n", This, id, grfdexFetch, pgrfdex);
|
||||
return E_NOTIMPL;
|
||||
dispex_prop_t *prop;
|
||||
|
||||
TRACE("(%p)->(%lx %lx %p)\n", This, id, grfdexFetch, pgrfdex);
|
||||
|
||||
prop = get_prop(This, id);
|
||||
if(!prop)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
*pgrfdex = 0;
|
||||
|
||||
if(grfdexFetch) {
|
||||
FIXME("unimplemented flags %08lx\n", grfdexFetch);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_GetMemberName(IWineJSDispatch *iface, DISPID id, BSTR *pbstrName)
|
||||
|
|
|
@ -3641,6 +3641,85 @@ static void test_invokeex(void)
|
|||
IActiveScript_Release(script);
|
||||
}
|
||||
|
||||
static void test_members(void)
|
||||
{
|
||||
DISPID func_id, prop_id;
|
||||
IActiveScript *script;
|
||||
IDispatchEx *dispex;
|
||||
DWORD propflags;
|
||||
HRESULT hres;
|
||||
VARIANT v;
|
||||
BSTR str;
|
||||
|
||||
hres = parse_script_expr(L"var o = { func: function() {}, prop: 1 }; o", &v, &script);
|
||||
ok(hres == S_OK, "parse_script_expr failed: %08lx\n", hres);
|
||||
ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
|
||||
|
||||
hres = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IDispatchEx, (void**)&dispex);
|
||||
ok(hres == S_OK, "Could not get IDispatchEx iface: %08lx\n", hres);
|
||||
VariantClear(&v);
|
||||
|
||||
str = SysAllocString(L"func");
|
||||
hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id);
|
||||
SysFreeString(str);
|
||||
ok(hres == S_OK, "GetDispID failed: %08lx\n", hres);
|
||||
|
||||
str = SysAllocString(L"prop");
|
||||
hres = IDispatchEx_GetDispID(dispex, str, 0, &prop_id);
|
||||
SysFreeString(str);
|
||||
ok(hres == S_OK, "GetDispID failed: %08lx\n", hres);
|
||||
|
||||
hres = IDispatchEx_GetMemberName(dispex, func_id, &str);
|
||||
ok(hres == S_OK, "GetMemberName failed: %08lx\n", hres);
|
||||
ok(!wcscmp(str, L"func"), "GetMemberName returned %s\n", wine_dbgstr_w(str));
|
||||
SysFreeString(str);
|
||||
|
||||
hres = IDispatchEx_GetMemberName(dispex, prop_id, &str);
|
||||
ok(hres == S_OK, "GetMemberName failed: %08lx\n", hres);
|
||||
ok(!wcscmp(str, L"prop"), "GetMemberName returned %s\n", wine_dbgstr_w(str));
|
||||
SysFreeString(str);
|
||||
|
||||
propflags = 0xdeadbeef;
|
||||
hres = IDispatchEx_GetMemberProperties(dispex, func_id, 0, &propflags);
|
||||
ok(hres == S_OK, "GetMemberProperties failed: %08lx\n", hres);
|
||||
ok(propflags == 0, "propflags = %08lx", propflags);
|
||||
|
||||
propflags = 0xdeadbeef;
|
||||
hres = IDispatchEx_GetMemberProperties(dispex, prop_id, 0, &propflags);
|
||||
ok(hres == S_OK, "GetMemberProperties failed: %08lx\n", hres);
|
||||
ok(propflags == 0, "propflags = %08lx", propflags);
|
||||
|
||||
hres = IDispatchEx_DeleteMemberByDispID(dispex, func_id);
|
||||
ok(hres == S_OK, "DeleteMemberByDispID failed: %08lx\n", hres);
|
||||
|
||||
hres = IDispatchEx_GetMemberName(dispex, func_id, &str);
|
||||
ok(hres == DISP_E_MEMBERNOTFOUND, "GetMemberName failed: %08lx\n", hres);
|
||||
hres = IDispatchEx_GetMemberProperties(dispex, func_id, 0, &propflags);
|
||||
ok(hres == DISP_E_MEMBERNOTFOUND, "GetMemberProperties failed: %08lx\n", hres);
|
||||
|
||||
hres = IDispatchEx_GetMemberName(dispex, prop_id, &str);
|
||||
ok(hres == S_OK, "GetMemberName failed: %08lx\n", hres);
|
||||
ok(!wcscmp(str, L"prop"), "GetMemberName returned %s\n", wine_dbgstr_w(str));
|
||||
SysFreeString(str);
|
||||
propflags = 0xdeadbeef;
|
||||
hres = IDispatchEx_GetMemberProperties(dispex, prop_id, 0, &propflags);
|
||||
ok(hres == S_OK, "GetMemberProperties failed: %08lx\n", hres);
|
||||
ok(propflags == 0, "propflags = %08lx", propflags);
|
||||
|
||||
str = SysAllocString(L"prop");
|
||||
hres = IDispatchEx_DeleteMemberByName(dispex, str, 0);
|
||||
ok(hres == S_OK, "DeleteMemberByName failed: %08lx\n", hres);
|
||||
SysFreeString(str);
|
||||
|
||||
hres = IDispatchEx_GetMemberName(dispex, prop_id, &str);
|
||||
ok(hres == DISP_E_MEMBERNOTFOUND, "GetMemberName failed: %08lx\n", hres);
|
||||
hres = IDispatchEx_GetMemberProperties(dispex, prop_id, 0, &propflags);
|
||||
ok(hres == DISP_E_MEMBERNOTFOUND, "GetMemberProperties failed: %08lx\n", hres);
|
||||
|
||||
IDispatchEx_Release(dispex);
|
||||
IActiveScript_Release(script);
|
||||
}
|
||||
|
||||
static void test_destructors(void)
|
||||
{
|
||||
static const WCHAR cyclic_refs[] = L"(function() {\n"
|
||||
|
@ -4299,6 +4378,7 @@ static BOOL run_tests(void)
|
|||
|
||||
test_script_exprs();
|
||||
test_invokeex();
|
||||
test_members();
|
||||
test_destructors();
|
||||
test_eval();
|
||||
test_error_reports();
|
||||
|
|
|
@ -217,7 +217,6 @@ static void test_HeapCreate(void)
|
|||
count = GetProcessHeaps( ARRAY_SIZE(heaps), heaps );
|
||||
ok( count == heap_count + 2, "GetProcessHeaps returned %lu\n", count );
|
||||
ok( heaps[0] == GetProcessHeap(), "got wrong heap\n" );
|
||||
todo_wine
|
||||
ok( heaps[heap_count + 0] == heap, "got wrong heap\n" );
|
||||
todo_wine
|
||||
ok( heaps[heap_count + 1] == heap1, "got wrong heap\n" );
|
||||
|
|
|
@ -18,12 +18,15 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "wine/test.h"
|
||||
#include "winbase.h"
|
||||
#include "winternl.h"
|
||||
#include "appmodel.h"
|
||||
|
||||
static BOOL (WINAPI * pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD *);
|
||||
static UINT (WINAPI * pEnumSystemFirmwareTables)(DWORD, void *, DWORD);
|
||||
static UINT (WINAPI * pGetSystemFirmwareTable)(DWORD, DWORD, void *, DWORD);
|
||||
static LONG (WINAPI * pPackageIdFromFullName)(const WCHAR *, UINT32, UINT32 *, BYTE *);
|
||||
static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, void *, ULONG, ULONG *);
|
||||
|
@ -44,6 +47,7 @@ static void init_function_pointers(void)
|
|||
hmod = GetModuleHandleA("kernel32.dll");
|
||||
|
||||
GET_PROC(GetProductInfo);
|
||||
GET_PROC(EnumSystemFirmwareTables);
|
||||
GET_PROC(GetSystemFirmwareTable);
|
||||
GET_PROC(PackageIdFromFullName);
|
||||
|
||||
|
@ -701,17 +705,18 @@ static void test_VerifyVersionInfo(void)
|
|||
ok(ret, "VerifyVersionInfoA failed with error %ld\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_GetSystemFirmwareTable(void)
|
||||
static void test_SystemFirmwareTable(void)
|
||||
{
|
||||
static const ULONG min_sfti_len = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
|
||||
ULONG expected_len;
|
||||
UINT len;
|
||||
NTSTATUS status;
|
||||
SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti;
|
||||
UCHAR *smbios_table;
|
||||
|
||||
if (!pGetSystemFirmwareTable)
|
||||
if (!pGetSystemFirmwareTable || !pEnumSystemFirmwareTables)
|
||||
{
|
||||
win_skip("GetSystemFirmwareTable not available\n");
|
||||
win_skip("SystemFirmwareTable functions not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -720,18 +725,21 @@ static void test_GetSystemFirmwareTable(void)
|
|||
sfti->ProviderSignature = RSMB;
|
||||
sfti->Action = SystemFirmwareTable_Get;
|
||||
sfti->TableID = 0;
|
||||
pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, min_sfti_len, &expected_len);
|
||||
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, min_sfti_len, &expected_len);
|
||||
if (expected_len == 0) /* xp, 2003 */
|
||||
{
|
||||
win_skip("SystemFirmwareTableInformation is not available\n");
|
||||
HeapFree(GetProcessHeap(), 0, sfti);
|
||||
return;
|
||||
}
|
||||
ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySystemInformation failed %lx\n", status );
|
||||
sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len);
|
||||
ok(!!sfti, "Failed to allocate memory\n");
|
||||
pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
|
||||
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
|
||||
ok( !status, "NtQuerySystemInformation failed %lx\n", status );
|
||||
|
||||
expected_len -= min_sfti_len;
|
||||
ok( sfti->TableBufferLength == expected_len, "wrong len %lu/%lx\n",
|
||||
sfti->TableBufferLength, expected_len );
|
||||
len = pGetSystemFirmwareTable(RSMB, 0, NULL, 0);
|
||||
ok(len == expected_len, "Expected length %lu, got %u\n", expected_len, len);
|
||||
|
||||
|
@ -744,9 +752,27 @@ static void test_GetSystemFirmwareTable(void)
|
|||
sfti->TableBuffer[3], sfti->TableBuffer[4], sfti->TableBuffer[5],
|
||||
smbios_table[0], smbios_table[1], smbios_table[2],
|
||||
smbios_table[3], smbios_table[4], smbios_table[5]);
|
||||
HeapFree(GetProcessHeap(), 0, smbios_table);
|
||||
|
||||
sfti->Action = SystemFirmwareTable_Enumerate;
|
||||
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, min_sfti_len, &expected_len);
|
||||
ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySystemInformation failed %lx\n", status );
|
||||
sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len);
|
||||
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
|
||||
ok( !status, "NtQuerySystemInformation failed %lx\n", status );
|
||||
ok( expected_len == min_sfti_len + sizeof(UINT), "wrong len %lu\n", expected_len );
|
||||
ok( sfti->TableBufferLength == sizeof(UINT), "wrong len %lu\n", sfti->TableBufferLength );
|
||||
ok( *(UINT *)sfti->TableBuffer == 0, "wrong table id %x\n", *(UINT *)sfti->TableBuffer );
|
||||
|
||||
len = pEnumSystemFirmwareTables( RSMB, NULL, 0 );
|
||||
ok( len == sizeof(UINT), "wrong len %u\n", len );
|
||||
smbios_table = malloc( len );
|
||||
len = pEnumSystemFirmwareTables( RSMB, smbios_table, len );
|
||||
ok( len == sizeof(UINT), "wrong len %u\n", len );
|
||||
ok( *(UINT *)smbios_table == 0, "wrong table id %x\n", *(UINT *)smbios_table );
|
||||
free( smbios_table );
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, sfti);
|
||||
HeapFree(GetProcessHeap(), 0, smbios_table);
|
||||
}
|
||||
|
||||
static const struct
|
||||
|
@ -1100,6 +1126,6 @@ START_TEST(version)
|
|||
test_GetVersionEx();
|
||||
test_VerifyVersionInfo();
|
||||
test_pe_os_version();
|
||||
test_GetSystemFirmwareTable();
|
||||
test_SystemFirmwareTable();
|
||||
test_PackageIdFromFullName();
|
||||
}
|
||||
|
|
|
@ -1785,27 +1785,12 @@ BOOL WINAPI GetXStateFeaturesMask( CONTEXT *context, DWORD64 *feature_mask )
|
|||
* Firmware functions
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* EnumSystemFirmwareTable (kernelbase.@)
|
||||
*/
|
||||
UINT WINAPI EnumSystemFirmwareTables( DWORD provider, void *buffer, DWORD size )
|
||||
{
|
||||
FIXME( "(0x%08lx, %p, %ld)\n", provider, buffer, size );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetSystemFirmwareTable (kernelbase.@)
|
||||
*/
|
||||
UINT WINAPI GetSystemFirmwareTable( DWORD provider, DWORD id, void *buffer, DWORD size )
|
||||
static UINT get_firmware_table( DWORD provider, SYSTEM_FIRMWARE_TABLE_ACTION action, DWORD id,
|
||||
void *buffer, DWORD size )
|
||||
{
|
||||
SYSTEM_FIRMWARE_TABLE_INFORMATION *info;
|
||||
ULONG buffer_size = offsetof( SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer ) + size;
|
||||
|
||||
TRACE( "(0x%08lx, 0x%08lx, %p, %ld)\n", provider, id, buffer, size );
|
||||
|
||||
if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, buffer_size )))
|
||||
{
|
||||
SetLastError( ERROR_OUTOFMEMORY );
|
||||
|
@ -1813,7 +1798,7 @@ UINT WINAPI GetSystemFirmwareTable( DWORD provider, DWORD id, void *buffer, DWOR
|
|||
}
|
||||
|
||||
info->ProviderSignature = provider;
|
||||
info->Action = SystemFirmwareTable_Get;
|
||||
info->Action = action;
|
||||
info->TableID = id;
|
||||
|
||||
set_ntstatus( NtQuerySystemInformation( SystemFirmwareTableInformation,
|
||||
|
@ -1824,3 +1809,23 @@ UINT WINAPI GetSystemFirmwareTable( DWORD provider, DWORD id, void *buffer, DWOR
|
|||
HeapFree( GetProcessHeap(), 0, info );
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* EnumSystemFirmwareTables (kernelbase.@)
|
||||
*/
|
||||
UINT WINAPI EnumSystemFirmwareTables( DWORD provider, void *buffer, DWORD size )
|
||||
{
|
||||
TRACE( "(0x%08lx, %p, %ld)\n", provider, buffer, size );
|
||||
|
||||
return get_firmware_table( provider, SystemFirmwareTable_Enumerate, 0, buffer, size );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetSystemFirmwareTable (kernelbase.@)
|
||||
*/
|
||||
UINT WINAPI GetSystemFirmwareTable( DWORD provider, DWORD id, void *buffer, DWORD size )
|
||||
{
|
||||
TRACE( "(0x%08lx, 0x%08lx, %p, %ld)\n", provider, id, buffer, size );
|
||||
|
||||
return get_firmware_table( provider, SystemFirmwareTable_Get, id, buffer, size );
|
||||
}
|
||||
|
|
|
@ -1764,6 +1764,26 @@ HRESULT dispex_call_builtin(DispatchEx *dispex, DISPID id, DISPPARAMS *dp,
|
|||
return call_builtin_function(dispex, func, dp, res, ei, caller);
|
||||
}
|
||||
|
||||
static VARIANT_BOOL reset_builtin_func(DispatchEx *dispex, func_info_t *func)
|
||||
{
|
||||
func_obj_entry_t *entry;
|
||||
|
||||
if(!dispex->dynamic_data || !dispex->dynamic_data->func_disps ||
|
||||
!dispex->dynamic_data->func_disps[func->func_disp_idx].func_obj)
|
||||
return VARIANT_FALSE;
|
||||
|
||||
entry = dispex->dynamic_data->func_disps + func->func_disp_idx;
|
||||
if(V_VT(&entry->val) == VT_DISPATCH &&
|
||||
V_DISPATCH(&entry->val) == (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface)
|
||||
return VARIANT_FALSE;
|
||||
|
||||
VariantClear(&entry->val);
|
||||
V_VT(&entry->val) = VT_DISPATCH;
|
||||
V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface;
|
||||
IDispatch_AddRef(V_DISPATCH(&entry->val));
|
||||
return VARIANT_TRUE;
|
||||
}
|
||||
|
||||
HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
|
||||
{
|
||||
switch(get_dispid_type(id)) {
|
||||
|
@ -1793,26 +1813,7 @@ HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
|
|||
|
||||
/* For builtin functions, we set their value to the original function. */
|
||||
if(func->func_disp_idx >= 0) {
|
||||
func_obj_entry_t *entry;
|
||||
|
||||
if(!This->dynamic_data || !This->dynamic_data->func_disps
|
||||
|| !This->dynamic_data->func_disps[func->func_disp_idx].func_obj) {
|
||||
*success = VARIANT_FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
entry = This->dynamic_data->func_disps + func->func_disp_idx;
|
||||
if(V_VT(&entry->val) == VT_DISPATCH
|
||||
&& V_DISPATCH(&entry->val) == (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface) {
|
||||
*success = VARIANT_FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
VariantClear(&entry->val);
|
||||
V_VT(&entry->val) = VT_DISPATCH;
|
||||
V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface;
|
||||
IDispatch_AddRef(V_DISPATCH(&entry->val));
|
||||
*success = VARIANT_TRUE;
|
||||
*success = reset_builtin_func(This, func);
|
||||
return S_OK;
|
||||
}
|
||||
*success = VARIANT_TRUE;
|
||||
|
@ -2304,7 +2305,8 @@ static HRESULT dispex_prop_delete(DispatchEx *dispex, DISPID id)
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if(is_dynamic_dispid(id)) {
|
||||
switch(get_dispid_type(id)) {
|
||||
case DISPEXPROP_DYNAMIC: {
|
||||
DWORD idx = id - DISPID_DYNPROP_0;
|
||||
dynamic_prop_t *prop;
|
||||
|
||||
|
@ -2316,6 +2318,24 @@ static HRESULT dispex_prop_delete(DispatchEx *dispex, DISPID id)
|
|||
prop->flags |= DYNPROP_DELETED;
|
||||
return S_OK;
|
||||
}
|
||||
case DISPEXPROP_BUILTIN: {
|
||||
func_info_t *func;
|
||||
HRESULT hres;
|
||||
|
||||
if(!ensure_real_info(dispex))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
hres = get_builtin_func(dispex->info, id, &func);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(func->func_disp_idx >= 0)
|
||||
reset_builtin_func(dispex, func);
|
||||
return S_OK;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ IDispatch *script_parse_event(HTMLInnerWindow*,LPCWSTR);
|
|||
HRESULT exec_script(HTMLInnerWindow*,const WCHAR*,const WCHAR*,VARIANT*);
|
||||
void update_browser_script_mode(GeckoBrowser*,IUri*);
|
||||
BOOL find_global_prop(HTMLInnerWindow*,const WCHAR*,DWORD,ScriptHost**,DISPID*);
|
||||
HRESULT global_prop_still_exists(HTMLInnerWindow*,global_prop_t*);
|
||||
IDispatch *get_script_disp(ScriptHost*);
|
||||
IActiveScriptSite *get_first_script_site(HTMLInnerWindow*);
|
||||
void initialize_script_global(HTMLInnerWindow*);
|
||||
|
|
|
@ -3302,7 +3302,7 @@ static global_prop_t *alloc_global_prop(HTMLInnerWindow *This, global_prop_type_
|
|||
This->global_prop_size = new_size;
|
||||
}
|
||||
|
||||
This->global_props[This->global_prop_cnt].name = wcsdup(name);
|
||||
This->global_props[This->global_prop_cnt].name = SysAllocString(name);
|
||||
if(!This->global_props[This->global_prop_cnt].name)
|
||||
return NULL;
|
||||
|
||||
|
@ -3324,8 +3324,10 @@ HRESULT search_window_props(HTMLInnerWindow *This, const WCHAR *name, DWORD grfd
|
|||
for(i=0; i < This->global_prop_cnt; i++) {
|
||||
/* FIXME: case sensitivity */
|
||||
if(!wcscmp(This->global_props[i].name, name)) {
|
||||
*pid = MSHTML_DISPID_CUSTOM_MIN+i;
|
||||
return S_OK;
|
||||
HRESULT hres = global_prop_still_exists(This, &This->global_props[i]);
|
||||
if(hres == S_OK)
|
||||
*pid = MSHTML_DISPID_CUSTOM_MIN + i;
|
||||
return (hres == DISP_E_MEMBERNOTFOUND) ? DISP_E_UNKNOWNNAME : hres;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3364,18 +3366,34 @@ static HRESULT WINAPI WindowDispEx_InvokeEx(IWineJSDispatchHost *iface, DISPID i
|
|||
static HRESULT WINAPI WindowDispEx_DeleteMemberByName(IWineJSDispatchHost *iface, BSTR bstrName, DWORD grfdex)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
compat_mode_t compat_mode = dispex_compat_mode(&This->base.inner_window->event_target.dispex);
|
||||
|
||||
TRACE("(%p)->(%s %lx)\n", This, debugstr_w(bstrName), grfdex);
|
||||
|
||||
if(compat_mode < COMPAT_MODE_IE8) {
|
||||
/* Not implemented by IE */
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
if(compat_mode == COMPAT_MODE_IE8)
|
||||
return MSHTML_E_INVALID_ACTION;
|
||||
|
||||
return IWineJSDispatchHost_DeleteMemberByName(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, bstrName, grfdex);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WindowDispEx_DeleteMemberByDispID(IWineJSDispatchHost *iface, DISPID id)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
compat_mode_t compat_mode = dispex_compat_mode(&This->base.inner_window->event_target.dispex);
|
||||
|
||||
TRACE("(%p)->(%lx)\n", This, id);
|
||||
|
||||
if(compat_mode < COMPAT_MODE_IE8) {
|
||||
/* Not implemented by IE */
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
if(compat_mode == COMPAT_MODE_IE8)
|
||||
return MSHTML_E_INVALID_ACTION;
|
||||
|
||||
return IWineJSDispatchHost_DeleteMemberByDispID(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, id);
|
||||
}
|
||||
|
||||
|
@ -3763,7 +3781,7 @@ static void HTMLWindow_destructor(DispatchEx *dispex)
|
|||
VariantClear(&This->performance);
|
||||
|
||||
for(i = 0; i < This->global_prop_cnt; i++)
|
||||
free(This->global_props[i].name);
|
||||
SysFreeString(This->global_props[i].name);
|
||||
free(This->global_props);
|
||||
|
||||
if(This->mon)
|
||||
|
@ -3910,6 +3928,9 @@ HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags,
|
|||
case DISPATCH_PROPERTYPUT: {
|
||||
DISPID dispex_id;
|
||||
|
||||
if(This->event_target.dispex.jsdisp)
|
||||
return S_FALSE;
|
||||
|
||||
hres = dispex_get_dynid(&This->event_target.dispex, prop->name, TRUE, &dispex_id);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -3953,6 +3974,44 @@ HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags,
|
|||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT HTMLWindow_delete(DispatchEx *dispex, DISPID id)
|
||||
{
|
||||
HTMLInnerWindow *This = impl_from_DispatchEx(dispex);
|
||||
DWORD idx = id - MSHTML_DISPID_CUSTOM_MIN;
|
||||
global_prop_t *prop;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
if(idx >= This->global_prop_cnt)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
|
||||
prop = This->global_props + idx;
|
||||
switch(prop->type) {
|
||||
case GLOBAL_SCRIPTVAR: {
|
||||
IDispatchEx *iface;
|
||||
IDispatch *disp;
|
||||
|
||||
disp = get_script_disp(prop->script_host);
|
||||
if(!disp)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&iface);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IDispatchEx_DeleteMemberByDispID(iface, prop->id);
|
||||
IDispatchEx_Release(iface);
|
||||
}else {
|
||||
WARN("No IDispatchEx, so can't delete\n");
|
||||
hres = S_OK;
|
||||
}
|
||||
IDispatch_Release(disp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT HTMLWindow_next_dispid(DispatchEx *dispex, DISPID id, DISPID *pid)
|
||||
{
|
||||
DWORD idx = (id == DISPID_STARTENUM) ? 0 : id - MSHTML_DISPID_CUSTOM_MIN + 1;
|
||||
|
@ -4179,6 +4238,7 @@ static const event_target_vtbl_t HTMLWindow_event_target_vtbl = {
|
|||
.lookup_dispid = HTMLWindow_lookup_dispid,
|
||||
.find_dispid = HTMLWindow_find_dispid,
|
||||
.invoke = HTMLWindow_invoke,
|
||||
.delete = HTMLWindow_delete,
|
||||
.next_dispid = HTMLWindow_next_dispid,
|
||||
.get_prop_desc = HTMLWindow_get_prop_desc,
|
||||
.get_script_global = HTMLWindow_get_script_global,
|
||||
|
|
|
@ -656,7 +656,7 @@ typedef enum {
|
|||
|
||||
typedef struct {
|
||||
global_prop_type_t type;
|
||||
WCHAR *name;
|
||||
BSTR name;
|
||||
ScriptHost *script_host;
|
||||
DISPID id;
|
||||
} global_prop_t;
|
||||
|
|
|
@ -85,6 +85,7 @@ struct ScriptHost {
|
|||
SCRIPTSTATE script_state;
|
||||
|
||||
HTMLInnerWindow *window;
|
||||
IDispatchEx *script_dispex;
|
||||
|
||||
GUID guid;
|
||||
struct list entry;
|
||||
|
@ -255,6 +256,18 @@ static BOOL init_script_engine(ScriptHost *script_host, IActiveScript *script)
|
|||
if(is_second_init)
|
||||
set_script_prop(first_host->script, SCRIPTPROP_ABBREVIATE_GLOBALNAME_RESOLUTION, &var);
|
||||
}
|
||||
|
||||
if(IsEqualGUID(&script_host->guid, &CLSID_JScript)) {
|
||||
IDispatch *script_disp;
|
||||
|
||||
hres = IActiveScript_GetScriptDispatch(script, NULL, &script_disp);
|
||||
if(FAILED(hres))
|
||||
WARN("GetScriptDispatch failed: %08lx\n", hres);
|
||||
else {
|
||||
IDispatch_QueryInterface(script_disp, &IID_IDispatchEx, (void**)&script_host->script_dispex);
|
||||
IDispatch_Release(script_disp);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
WARN("AddNamedItem failed: %08lx\n", hres);
|
||||
}
|
||||
|
@ -288,6 +301,8 @@ static void release_script_engine(ScriptHost *This)
|
|||
unlink_ref(&This->parse);
|
||||
}
|
||||
|
||||
if(This->script_dispex)
|
||||
IDispatchEx_Release(This->script_dispex);
|
||||
IActiveScript_Release(This->script);
|
||||
This->script = NULL;
|
||||
This->script_state = SCRIPTSTATE_UNINITIALIZED;
|
||||
|
@ -1825,6 +1840,48 @@ BOOL find_global_prop(HTMLInnerWindow *window, const WCHAR *name, DWORD flags, S
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
HRESULT global_prop_still_exists(HTMLInnerWindow *window, global_prop_t *prop)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
switch(prop->type) {
|
||||
case GLOBAL_SCRIPTVAR: {
|
||||
DWORD properties;
|
||||
|
||||
if(!prop->script_host->script)
|
||||
return E_UNEXPECTED;
|
||||
if(!prop->script_host->script_dispex)
|
||||
return S_OK;
|
||||
return IDispatchEx_GetMemberProperties(prop->script_host->script_dispex, prop->id, 0, &properties);
|
||||
}
|
||||
case GLOBAL_ELEMENTVAR: {
|
||||
IHTMLElement *elem;
|
||||
|
||||
hres = IHTMLDocument3_getElementById(&window->doc->IHTMLDocument3_iface, prop->name, &elem);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(!elem)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
IHTMLElement_Release(elem);
|
||||
return S_OK;
|
||||
}
|
||||
case GLOBAL_FRAMEVAR: {
|
||||
HTMLOuterWindow *frame;
|
||||
|
||||
hres = get_frame_by_name(window->base.outer_window, prop->name, FALSE, &frame);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
return frame ? S_OK : DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static BOOL is_jscript_available(void)
|
||||
{
|
||||
static BOOL available, checked;
|
||||
|
|
|
@ -1301,7 +1301,7 @@ sync_test("navigator", function() {
|
|||
|
||||
sync_test("delete_prop", function() {
|
||||
var v = document.documentMode;
|
||||
var obj = document.createElement("div"), r, obj2;
|
||||
var obj = document.createElement("div"), r, obj2, func, prop;
|
||||
|
||||
obj.prop1 = true;
|
||||
r = false;
|
||||
|
@ -1317,6 +1317,40 @@ sync_test("delete_prop", function() {
|
|||
ok(!r, "got an unexpected exception");
|
||||
ok(!("prop1" in obj), "prop1 is still in obj");
|
||||
|
||||
/* builtin properties don't throw any exception, but are not really deleted */
|
||||
r = (delete obj.tagName);
|
||||
ok(r, "delete returned " + r);
|
||||
ok("tagName" in obj, "tagName deleted from obj");
|
||||
ok(obj.tagName === "DIV", "tagName = " + obj.tagName);
|
||||
|
||||
prop = obj.id;
|
||||
r = (delete obj.id);
|
||||
ok(r, "delete returned " + r);
|
||||
ok("id" in obj, "id deleted from obj");
|
||||
ok(obj.id === prop, "id = " + obj.id);
|
||||
|
||||
obj.id = "1234";
|
||||
ok(obj.id === "1234", "id after set to 1234 = " + obj.id);
|
||||
r = (delete obj.id);
|
||||
ok(r, "delete returned " + r);
|
||||
ok("id" in obj, "id deleted from obj");
|
||||
ok(obj.id === "1234", "id = " + obj.id);
|
||||
|
||||
/* builtin functions get reset to their original values */
|
||||
func = function() { }
|
||||
prop = obj.setAttribute;
|
||||
r = (delete obj.setAttribute);
|
||||
ok(r, "delete returned " + r);
|
||||
ok("setAttribute" in obj, "setAttribute deleted from obj");
|
||||
ok(obj.setAttribute === prop, "setAttribute = " + obj.setAttribute);
|
||||
|
||||
obj.setAttribute = func;
|
||||
ok(obj.setAttribute === func, "setAttribute after set to func = " + obj.setAttribute);
|
||||
r = (delete obj.setAttribute);
|
||||
ok(r, "delete returned " + r);
|
||||
ok("setAttribute" in obj, "setAttribute deleted from obj");
|
||||
ok(obj.setAttribute === prop, "setAttribute = " + obj.setAttribute);
|
||||
|
||||
/* again, this time prop1 does not exist */
|
||||
r = false;
|
||||
try {
|
||||
|
@ -1326,7 +1360,6 @@ sync_test("delete_prop", function() {
|
|||
}
|
||||
if(v < 9) {
|
||||
ok(r, "did not get an expected exception");
|
||||
return;
|
||||
}else {
|
||||
ok(!r, "got an unexpected exception");
|
||||
ok(!("prop1" in obj), "prop1 is still in obj");
|
||||
|
@ -1337,12 +1370,6 @@ sync_test("delete_prop", function() {
|
|||
ok("className" in obj, "className deleted from obj");
|
||||
ok(obj.className === "", "className = " + obj.className);
|
||||
|
||||
/* builtin propertiles don't throw any exception, but are not really deleted */
|
||||
r = (delete obj.tagName);
|
||||
ok(r, "delete returned " + r);
|
||||
ok("tagName" in obj, "tagName deleted from obj");
|
||||
ok(obj.tagName === "DIV", "tagName = " + obj.tagName);
|
||||
|
||||
obj = document.querySelectorAll("*");
|
||||
ok("0" in obj, "0 is not in obj");
|
||||
obj2 = obj[0];
|
||||
|
@ -1353,12 +1380,27 @@ sync_test("delete_prop", function() {
|
|||
/* test window object and its global scope handling */
|
||||
obj = window;
|
||||
|
||||
ok("encodeURIComponent" in obj, "encodeURIComponent not in obj");
|
||||
try {
|
||||
prop = window.encodeURIComponent;
|
||||
r = (delete window.encodeURIComponent);
|
||||
ok(v >= 9, "did not get an expect exception deleting encodeURIComponent");
|
||||
ok(r, "delete returned " + r);
|
||||
ok(!("encodeURIComponent" in obj), "encodeURIComponent is still in obj");
|
||||
window.encodeURIComponent = prop;
|
||||
}catch(ex) {
|
||||
ok(v < 9, "expected exception deleting encodeURIComponent");
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting encodeURIComponent threw " + ex.number);
|
||||
ok("encodeURIComponent" in obj, "encodeURIComponent is not in obj");
|
||||
}
|
||||
|
||||
obj.globalprop1 = true;
|
||||
ok(globalprop1, "globalprop1 = " + globalprop1);
|
||||
r = false;
|
||||
try {
|
||||
delete obj.globalprop1;
|
||||
}catch(ex) {
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting globalprop1 threw " + ex.number);
|
||||
r = true;
|
||||
}
|
||||
if(v < 9) {
|
||||
|
@ -1374,13 +1416,13 @@ sync_test("delete_prop", function() {
|
|||
try {
|
||||
delete obj.globalprop2;
|
||||
}catch(ex) {
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting globalprop2 threw " + ex.number);
|
||||
r = true;
|
||||
}
|
||||
if(v < 9) {
|
||||
ok(r, "did not get an expected globalprop2 exception");
|
||||
}else {
|
||||
ok(!r, "got an unexpected exception");
|
||||
todo_wine.
|
||||
ok(!("globalprop2" in obj), "globalprop2 is still in obj");
|
||||
}
|
||||
|
||||
|
@ -1390,6 +1432,7 @@ sync_test("delete_prop", function() {
|
|||
try {
|
||||
delete globalprop3;
|
||||
}catch(ex) {
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting globalprop3 threw " + ex.number);
|
||||
r = true;
|
||||
}
|
||||
if(v < 9) {
|
||||
|
@ -1404,8 +1447,88 @@ sync_test("delete_prop", function() {
|
|||
ok(obj.globalprop4, "globalprop4 = " + globalprop4);
|
||||
r = (delete globalprop4);
|
||||
ok(r, "delete returned " + r);
|
||||
todo_wine.
|
||||
ok(!("globalprop4" in obj), "globalprop4 is still in obj");
|
||||
|
||||
globalprop5 = true;
|
||||
ok(obj.globalprop5, "globalprop5 = " + globalprop5);
|
||||
try {
|
||||
r = (delete window.globalprop5);
|
||||
ok(v >= 9, "did not get an expected exception deleting globalprop5");
|
||||
ok(r, "delete returned " + r);
|
||||
ok(!("globalprop5" in obj), "globalprop5 is still in obj");
|
||||
}catch(ex) {
|
||||
ok(v < 9, "expected exception deleting globalprop5");
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting globalprop5 threw " + ex.number);
|
||||
ok("globalprop5" in obj, "globalprop5 is not in obj");
|
||||
}
|
||||
|
||||
document.body.innerHTML = '<div id="winetest"/>';
|
||||
ok("winetest" in obj, "winetest not in obj");
|
||||
try {
|
||||
r = (delete window.winetest);
|
||||
ok(v >= 9, "did not get an expected exception deleting winetest");
|
||||
ok(r, "delete returned " + r);
|
||||
}catch(ex) {
|
||||
ok(v < 9, "expected exception deleting winetest");
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting winetest threw " + ex.number);
|
||||
}
|
||||
ok("winetest" in obj, "winetest is not in obj");
|
||||
document.body.innerHTML = "";
|
||||
ok(!("winetest" in obj), "winetest is still in obj");
|
||||
|
||||
document.body.innerHTML = '<div id="foobar"/>';
|
||||
ok("foobar" in obj, "foobar not in obj");
|
||||
window.foobar = "1234";
|
||||
ok(obj.foobar === "1234", "foobar = " + obj.foobar);
|
||||
document.body.innerHTML = "";
|
||||
ok("foobar" in obj, "foobar is not in obj");
|
||||
ok(obj.foobar === "1234", "foobar = " + obj.foobar);
|
||||
try {
|
||||
r = (delete window.foobar);
|
||||
ok(v >= 9, "did not get an expected exception deleting foobar");
|
||||
ok(r, "delete returned " + r);
|
||||
ok(!("foobar" in obj), "foobar is still in obj");
|
||||
}catch(ex) {
|
||||
ok(v < 9, "expected exception deleting foobar");
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting foobar threw " + ex.number);
|
||||
ok("foobar" in obj, "foobar is not in obj");
|
||||
}
|
||||
|
||||
document.body.innerHTML = '<div id="barfoo"/>';
|
||||
ok("barfoo" in obj, "barfoo not in obj");
|
||||
window.barfoo = "5678";
|
||||
ok(obj.barfoo === "5678", "barfoo = " + obj.barfoo);
|
||||
try {
|
||||
r = (delete window.barfoo);
|
||||
ok(v >= 9, "did not get an expected exception deleting barfoo");
|
||||
ok(r, "delete returned " + r);
|
||||
ok(obj.barfoo !== "5678", "barfoo is still 5678");
|
||||
}catch(ex) {
|
||||
ok(v < 9, "expected exception deleting barfoo");
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting barfoo threw " + ex.number);
|
||||
ok(obj.barfoo === "5678", "barfoo = " + obj.barfoo);
|
||||
}
|
||||
ok("barfoo" in obj, "barfoo is not in obj");
|
||||
document.body.innerHTML = "";
|
||||
if(v < 9)
|
||||
ok("barfoo" in obj, "barfoo is not in obj");
|
||||
else
|
||||
ok(!("barfoo" in obj), "barfoo is still in obj");
|
||||
|
||||
document.body.innerHTML = '<iframe id="testwine"/>';
|
||||
ok("testwine" in obj, "testwine not in obj");
|
||||
try {
|
||||
r = (delete window.testwine);
|
||||
ok(v >= 9, "did not get an expected exception deleting testwine");
|
||||
ok(r, "delete returned " + r);
|
||||
}catch(ex) {
|
||||
ok(v < 9, "expected exception deleting testwine");
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting testwine threw " + ex.number);
|
||||
}
|
||||
ok("testwine" in obj, "testwine is not in obj");
|
||||
|
||||
document.body.innerHTML = "";
|
||||
ok(!("testwine" in obj), "testwine is still in obj");
|
||||
});
|
||||
|
||||
sync_test("detached arguments", function() {
|
||||
|
|
|
@ -400,6 +400,7 @@
|
|||
@ stdcall -syscall NtSetInformationVirtualMemory(long long ptr ptr ptr long)
|
||||
@ stdcall -syscall NtSetIntervalProfile(long long)
|
||||
@ stdcall -syscall NtSetIoCompletion(ptr long long long long)
|
||||
@ stdcall -syscall NtSetIoCompletionEx(ptr ptr long long long long)
|
||||
@ stdcall -syscall NtSetLdtEntries(long int64 long int64)
|
||||
# @ stub NtSetLowEventPair
|
||||
# @ stub NtSetLowWaitHighEventPair
|
||||
|
@ -1460,6 +1461,7 @@
|
|||
@ stdcall -private -syscall ZwSetInformationVirtualMemory(long long ptr ptr ptr long) NtSetInformationVirtualMemory
|
||||
@ stdcall -private -syscall ZwSetIntervalProfile(long long) NtSetIntervalProfile
|
||||
@ stdcall -private -syscall ZwSetIoCompletion(ptr long long long long) NtSetIoCompletion
|
||||
@ stdcall -private -syscall ZwSetIoCompletionEx(ptr ptr long long long long) NtSetIoCompletionEx
|
||||
@ stdcall -private -syscall ZwSetLdtEntries(long int64 long int64) NtSetLdtEntries
|
||||
# @ stub ZwSetLowEventPair
|
||||
# @ stub ZwSetLowWaitHighEventPair
|
||||
|
|
158
dlls/ntdll/ntsyscalls.h
generated
158
dlls/ntdll/ntsyscalls.h
generated
|
@ -203,48 +203,49 @@
|
|||
SYSCALL_ENTRY( 0x00c7, NtSetInformationVirtualMemory, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00c8, NtSetIntervalProfile, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00c9, NtSetIoCompletion, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00ca, NtSetLdtEntries, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00cb, NtSetSecurityObject, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00cc, NtSetSystemInformation, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00cd, NtSetSystemTime, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00ce, NtSetThreadExecutionState, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00cf, NtSetTimer, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00d0, NtSetTimerResolution, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00d1, NtSetValueKey, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00d2, NtSetVolumeInformationFile, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00d3, NtShutdownSystem, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00d4, NtSignalAndWaitForSingleObject, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00d5, NtSuspendProcess, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00d6, NtSuspendThread, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d7, NtSystemDebugControl, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00d8, NtTerminateJobObject, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d9, NtTerminateProcess, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00da, NtTerminateThread, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00db, NtTestAlert, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00dc, NtTraceControl, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00dd, NtUnloadDriver, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00de, NtUnloadKey, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00df, NtUnlockFile, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00e0, NtUnlockVirtualMemory, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e1, NtUnmapViewOfSection, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00e2, NtUnmapViewOfSectionEx, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00e3, NtWaitForAlertByThreadId, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00e4, NtWaitForDebugEvent, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e5, NtWaitForKeyedEvent, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e6, NtWaitForMultipleObjects, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00e7, NtWaitForSingleObject, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00e8, NtWow64AllocateVirtualMemory64, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00e9, NtWow64GetNativeSystemInformation, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00ea, NtWow64IsProcessorFeaturePresent, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00eb, NtWow64QueryInformationProcess64, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00ec, NtWow64ReadVirtualMemory64, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00ed, NtWow64WriteVirtualMemory64, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00ee, NtWriteFile, 36 ) \
|
||||
SYSCALL_ENTRY( 0x00ef, NtWriteFileGather, 36 ) \
|
||||
SYSCALL_ENTRY( 0x00f0, NtWriteVirtualMemory, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00f1, NtYieldExecution, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00f2, wine_nt_to_unix_file_name, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00f3, wine_unix_to_nt_file_name, 12 )
|
||||
SYSCALL_ENTRY( 0x00ca, NtSetIoCompletionEx, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00cb, NtSetLdtEntries, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00cc, NtSetSecurityObject, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00cd, NtSetSystemInformation, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00ce, NtSetSystemTime, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00cf, NtSetThreadExecutionState, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d0, NtSetTimer, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00d1, NtSetTimerResolution, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00d2, NtSetValueKey, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00d3, NtSetVolumeInformationFile, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00d4, NtShutdownSystem, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00d5, NtSignalAndWaitForSingleObject, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00d6, NtSuspendProcess, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00d7, NtSuspendThread, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d8, NtSystemDebugControl, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00d9, NtTerminateJobObject, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00da, NtTerminateProcess, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00db, NtTerminateThread, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00dc, NtTestAlert, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00dd, NtTraceControl, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00de, NtUnloadDriver, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00df, NtUnloadKey, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00e0, NtUnlockFile, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00e1, NtUnlockVirtualMemory, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e2, NtUnmapViewOfSection, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00e3, NtUnmapViewOfSectionEx, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00e4, NtWaitForAlertByThreadId, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00e5, NtWaitForDebugEvent, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e6, NtWaitForKeyedEvent, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e7, NtWaitForMultipleObjects, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00e8, NtWaitForSingleObject, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00e9, NtWow64AllocateVirtualMemory64, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00ea, NtWow64GetNativeSystemInformation, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00eb, NtWow64IsProcessorFeaturePresent, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00ec, NtWow64QueryInformationProcess64, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00ed, NtWow64ReadVirtualMemory64, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00ee, NtWow64WriteVirtualMemory64, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00ef, NtWriteFile, 36 ) \
|
||||
SYSCALL_ENTRY( 0x00f0, NtWriteFileGather, 36 ) \
|
||||
SYSCALL_ENTRY( 0x00f1, NtWriteVirtualMemory, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00f2, NtYieldExecution, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00f3, wine_nt_to_unix_file_name, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00f4, wine_unix_to_nt_file_name, 12 )
|
||||
|
||||
#define ALL_SYSCALLS64 \
|
||||
SYSCALL_ENTRY( 0x0000, NtAcceptConnectPort, 48 ) \
|
||||
|
@ -449,39 +450,40 @@
|
|||
SYSCALL_ENTRY( 0x00c7, NtSetInformationVirtualMemory, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00c8, NtSetIntervalProfile, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00c9, NtSetIoCompletion, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00ca, NtSetLdtEntries, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00cb, NtSetSecurityObject, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00cc, NtSetSystemInformation, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00cd, NtSetSystemTime, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00ce, NtSetThreadExecutionState, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00cf, NtSetTimer, 56 ) \
|
||||
SYSCALL_ENTRY( 0x00d0, NtSetTimerResolution, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00d1, NtSetValueKey, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00d2, NtSetVolumeInformationFile, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00d3, NtShutdownSystem, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d4, NtSignalAndWaitForSingleObject, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00d5, NtSuspendProcess, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d6, NtSuspendThread, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00d7, NtSystemDebugControl, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00d8, NtTerminateJobObject, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00d9, NtTerminateProcess, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00da, NtTerminateThread, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00db, NtTestAlert, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00dc, NtTraceControl, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00dd, NtUnloadDriver, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00de, NtUnloadKey, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00df, NtUnlockFile, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00e0, NtUnlockVirtualMemory, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00e1, NtUnmapViewOfSection, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e2, NtUnmapViewOfSectionEx, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00e3, NtWaitForAlertByThreadId, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e4, NtWaitForDebugEvent, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00e5, NtWaitForKeyedEvent, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00e6, NtWaitForMultipleObjects, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00e7, NtWaitForSingleObject, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00e8, NtWriteFile, 72 ) \
|
||||
SYSCALL_ENTRY( 0x00e9, NtWriteFileGather, 72 ) \
|
||||
SYSCALL_ENTRY( 0x00ea, NtWriteVirtualMemory, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00eb, NtYieldExecution, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00ec, wine_nt_to_unix_file_name, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00ed, wine_unix_to_nt_file_name, 24 )
|
||||
SYSCALL_ENTRY( 0x00ca, NtSetIoCompletionEx, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00cb, NtSetLdtEntries, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00cc, NtSetSecurityObject, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00cd, NtSetSystemInformation, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00ce, NtSetSystemTime, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00cf, NtSetThreadExecutionState, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00d0, NtSetTimer, 56 ) \
|
||||
SYSCALL_ENTRY( 0x00d1, NtSetTimerResolution, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00d2, NtSetValueKey, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00d3, NtSetVolumeInformationFile, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00d4, NtShutdownSystem, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d5, NtSignalAndWaitForSingleObject, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00d6, NtSuspendProcess, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d7, NtSuspendThread, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00d8, NtSystemDebugControl, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00d9, NtTerminateJobObject, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00da, NtTerminateProcess, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00db, NtTerminateThread, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00dc, NtTestAlert, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00dd, NtTraceControl, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00de, NtUnloadDriver, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00df, NtUnloadKey, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00e0, NtUnlockFile, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00e1, NtUnlockVirtualMemory, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00e2, NtUnmapViewOfSection, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e3, NtUnmapViewOfSectionEx, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00e4, NtWaitForAlertByThreadId, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e5, NtWaitForDebugEvent, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00e6, NtWaitForKeyedEvent, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00e7, NtWaitForMultipleObjects, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00e8, NtWaitForSingleObject, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00e9, NtWriteFile, 72 ) \
|
||||
SYSCALL_ENTRY( 0x00ea, NtWriteFileGather, 72 ) \
|
||||
SYSCALL_ENTRY( 0x00eb, NtWriteVirtualMemory, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00ec, NtYieldExecution, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00ed, wine_nt_to_unix_file_name, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00ee, wine_unix_to_nt_file_name, 24 )
|
||||
|
|
|
@ -443,6 +443,7 @@ DEFINE_SYSCALL(NtSetInformationToken, (HANDLE token, TOKEN_INFORMATION_CLASS cla
|
|||
DEFINE_SYSCALL(NtSetInformationVirtualMemory, (HANDLE process, VIRTUAL_MEMORY_INFORMATION_CLASS info_class, ULONG_PTR count, PMEMORY_RANGE_ENTRY addresses, PVOID ptr, ULONG size))
|
||||
DEFINE_SYSCALL(NtSetIntervalProfile, (ULONG interval, KPROFILE_SOURCE source))
|
||||
DEFINE_SYSCALL(NtSetIoCompletion, (HANDLE handle, ULONG_PTR key, ULONG_PTR value, NTSTATUS status, SIZE_T count))
|
||||
DEFINE_SYSCALL(NtSetIoCompletionEx, (HANDLE completion_handle, HANDLE completion_reserve_handle, ULONG_PTR key, ULONG_PTR value, NTSTATUS status, SIZE_T count))
|
||||
DEFINE_SYSCALL(NtSetLdtEntries, (ULONG sel1, LDT_ENTRY entry1, ULONG sel2, LDT_ENTRY entry2))
|
||||
DEFINE_SYSCALL(NtSetSecurityObject, (HANDLE handle, SECURITY_INFORMATION info, PSECURITY_DESCRIPTOR descr))
|
||||
DEFINE_SYSCALL(NtSetSystemInformation, (SYSTEM_INFORMATION_CLASS class, void *info, ULONG length))
|
||||
|
|
|
@ -51,6 +51,7 @@ static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
|
|||
static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)( LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR* );
|
||||
static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG, ULONG * );
|
||||
|
||||
static NTSTATUS (WINAPI *pNtAllocateReserveObject)( HANDLE *, const OBJECT_ATTRIBUTES *, MEMORY_RESERVE_OBJECT_TYPE );
|
||||
static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
|
||||
ULONG, ULONG, ULONG, PLARGE_INTEGER );
|
||||
static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,PLARGE_INTEGER,ULONG,ULONG,ULONG,ULONG,PVOID,ULONG);
|
||||
|
@ -76,6 +77,7 @@ static NTSTATUS (WINAPI *pNtQueryIoCompletion)(HANDLE, IO_COMPLETION_INFORMATION
|
|||
static NTSTATUS (WINAPI *pNtRemoveIoCompletion)(HANDLE, PULONG_PTR, PULONG_PTR, PIO_STATUS_BLOCK, PLARGE_INTEGER);
|
||||
static NTSTATUS (WINAPI *pNtRemoveIoCompletionEx)(HANDLE,FILE_IO_COMPLETION_INFORMATION*,ULONG,ULONG*,LARGE_INTEGER*,BOOLEAN);
|
||||
static NTSTATUS (WINAPI *pNtSetIoCompletion)(HANDLE, ULONG_PTR, ULONG_PTR, NTSTATUS, SIZE_T);
|
||||
static NTSTATUS (WINAPI *pNtSetIoCompletionEx)(HANDLE, HANDLE, ULONG_PTR, ULONG_PTR, NTSTATUS, SIZE_T);
|
||||
static NTSTATUS (WINAPI *pNtSetInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
|
||||
static NTSTATUS (WINAPI *pNtQueryAttributesFile)(const OBJECT_ATTRIBUTES*,FILE_BASIC_INFORMATION*);
|
||||
static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
|
||||
|
@ -5932,6 +5934,62 @@ static void test_reparse_points(void)
|
|||
CloseHandle( handle );
|
||||
}
|
||||
|
||||
static void test_set_io_completion_ex(void)
|
||||
{
|
||||
HANDLE completion, completion_reserve, apc_reserve;
|
||||
LARGE_INTEGER timeout = {{0}};
|
||||
IO_STATUS_BLOCK iosb;
|
||||
ULONG_PTR key, value;
|
||||
NTSTATUS status;
|
||||
SIZE_T size = 3;
|
||||
|
||||
if (!pNtSetIoCompletionEx || !pNtAllocateReserveObject)
|
||||
{
|
||||
win_skip("NtSetIoCompletionEx() or NtAllocateReserveObject() is unavailable.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sizeof(size) > 4) size |= (ULONGLONG)0x12345678 << 32;
|
||||
|
||||
status = pNtCreateIoCompletion(&completion, IO_COMPLETION_ALL_ACCESS, NULL, 0);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
|
||||
status = pNtAllocateReserveObject(&completion_reserve, NULL, MemoryReserveObjectTypeIoCompletion);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
|
||||
status = pNtAllocateReserveObject(&apc_reserve, NULL, MemoryReserveObjectTypeUserApc);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
/* Parameter checks */
|
||||
status = pNtSetIoCompletionEx(NULL, completion_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
|
||||
ok(status == STATUS_INVALID_HANDLE, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
status = pNtSetIoCompletionEx(INVALID_HANDLE_VALUE, completion_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
|
||||
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
status = pNtSetIoCompletionEx(completion, NULL, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
|
||||
ok(status == STATUS_INVALID_HANDLE, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
status = pNtSetIoCompletionEx(completion, INVALID_HANDLE_VALUE, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
|
||||
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
status = pNtSetIoCompletionEx(completion, apc_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
|
||||
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
/* Normal call */
|
||||
status = pNtSetIoCompletionEx(completion, completion_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
status = pNtRemoveIoCompletion(completion, &key, &value, &iosb, &timeout);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
|
||||
ok(key == CKEY_FIRST, "Invalid completion key: %#Ix\n", key);
|
||||
ok(iosb.Information == size, "Invalid iosb.Information: %Iu\n", iosb.Information);
|
||||
ok(iosb.Status == STATUS_INVALID_DEVICE_REQUEST, "Invalid iosb.Status: %#lx\n", iosb.Status);
|
||||
ok(value == CVALUE_FIRST, "Invalid completion value: %#Ix\n", value);
|
||||
|
||||
CloseHandle(apc_reserve);
|
||||
CloseHandle(completion_reserve);
|
||||
CloseHandle(completion);
|
||||
}
|
||||
|
||||
START_TEST(file)
|
||||
{
|
||||
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
|
||||
|
@ -5949,6 +6007,7 @@ START_TEST(file)
|
|||
pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
|
||||
pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U");
|
||||
pRtlWow64EnableFsRedirectionEx = (void *)GetProcAddress(hntdll, "RtlWow64EnableFsRedirectionEx");
|
||||
pNtAllocateReserveObject= (void *)GetProcAddress(hntdll, "NtAllocateReserveObject");
|
||||
pNtCreateMailslotFile = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile");
|
||||
pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile");
|
||||
pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
|
||||
|
@ -5965,6 +6024,7 @@ START_TEST(file)
|
|||
pNtRemoveIoCompletion = (void *)GetProcAddress(hntdll, "NtRemoveIoCompletion");
|
||||
pNtRemoveIoCompletionEx = (void *)GetProcAddress(hntdll, "NtRemoveIoCompletionEx");
|
||||
pNtSetIoCompletion = (void *)GetProcAddress(hntdll, "NtSetIoCompletion");
|
||||
pNtSetIoCompletionEx = (void *)GetProcAddress(hntdll, "NtSetIoCompletionEx");
|
||||
pNtSetInformationFile = (void *)GetProcAddress(hntdll, "NtSetInformationFile");
|
||||
pNtQueryAttributesFile = (void *)GetProcAddress(hntdll, "NtQueryAttributesFile");
|
||||
pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile");
|
||||
|
@ -5983,6 +6043,7 @@ START_TEST(file)
|
|||
append_file_test();
|
||||
nt_mailslot_test();
|
||||
test_set_io_completion();
|
||||
test_set_io_completion_ex();
|
||||
test_file_io_completion();
|
||||
test_file_basic_information();
|
||||
test_file_all_information();
|
||||
|
|
|
@ -4052,10 +4052,9 @@ static void test_user_procs(void)
|
|||
status = pRtlInitializeNtUserPfn( dummy, size_A, dummy + 1, size_W, dummy + 2, size_workers );
|
||||
if (!status) break;
|
||||
ok( status == STATUS_INVALID_PARAMETER, "RtlInitializeNtUserPfn failed %lx\n", status );
|
||||
status = pRtlResetNtUserPfn();
|
||||
ok( status == STATUS_INVALID_PARAMETER, "RtlResetNtUserPfn failed %lx\n", status );
|
||||
}
|
||||
trace( "got sizes %lx %lx %lx\n", size_A, size_W, size_workers );
|
||||
if (!size_workers) return; /* something went wrong */
|
||||
ok( !memcmp( ptrs, ptr_A, size_A ), "pointers changed by init\n" );
|
||||
|
||||
/* can't set twice without a reset */
|
||||
|
|
|
@ -354,7 +354,7 @@ static int wait_select_reply( void *cookie )
|
|||
/***********************************************************************
|
||||
* invoke_user_apc
|
||||
*/
|
||||
static NTSTATUS invoke_user_apc( CONTEXT *context, const user_apc_t *apc, NTSTATUS status )
|
||||
static NTSTATUS invoke_user_apc( CONTEXT *context, const struct user_apc *apc, NTSTATUS status )
|
||||
{
|
||||
return call_user_apc_dispatcher( context, apc->args[0], apc->args[1], apc->args[2],
|
||||
wine_server_get_ptr( apc->func ), status );
|
||||
|
@ -364,7 +364,7 @@ static NTSTATUS invoke_user_apc( CONTEXT *context, const user_apc_t *apc, NTSTAT
|
|||
/***********************************************************************
|
||||
* invoke_system_apc
|
||||
*/
|
||||
static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOOL self )
|
||||
static void invoke_system_apc( const union apc_call *call, union apc_result *result, BOOL self )
|
||||
{
|
||||
SIZE_T size, bits;
|
||||
void *addr;
|
||||
|
@ -688,19 +688,19 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO
|
|||
* server_select
|
||||
*/
|
||||
unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags,
|
||||
timeout_t abs_timeout, context_t *context, user_apc_t *user_apc )
|
||||
timeout_t abs_timeout, context_t *context, struct user_apc *user_apc )
|
||||
{
|
||||
unsigned int ret;
|
||||
int cookie;
|
||||
obj_handle_t apc_handle = 0;
|
||||
BOOL suspend_context = !!context;
|
||||
apc_result_t result;
|
||||
union apc_result result;
|
||||
sigset_t old_set;
|
||||
int signaled;
|
||||
data_size_t reply_size;
|
||||
struct
|
||||
{
|
||||
apc_call_t call;
|
||||
union apc_call call;
|
||||
context_t context[2];
|
||||
} reply_data;
|
||||
|
||||
|
@ -768,7 +768,7 @@ unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT f
|
|||
{
|
||||
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
|
||||
unsigned int ret;
|
||||
user_apc_t apc;
|
||||
struct user_apc apc;
|
||||
|
||||
if (abs_timeout < 0)
|
||||
{
|
||||
|
@ -794,7 +794,7 @@ unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT f
|
|||
*/
|
||||
NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable )
|
||||
{
|
||||
user_apc_t apc;
|
||||
struct user_apc apc;
|
||||
NTSTATUS status;
|
||||
|
||||
if (alertable)
|
||||
|
@ -811,7 +811,7 @@ NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable )
|
|||
*/
|
||||
NTSTATUS WINAPI NtTestAlert(void)
|
||||
{
|
||||
user_apc_t apc;
|
||||
struct user_apc apc;
|
||||
NTSTATUS status;
|
||||
|
||||
status = server_select( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, 0, NULL, &apc );
|
||||
|
@ -823,7 +823,7 @@ NTSTATUS WINAPI NtTestAlert(void)
|
|||
/***********************************************************************
|
||||
* server_queue_process_apc
|
||||
*/
|
||||
unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call, apc_result_t *result )
|
||||
unsigned int server_queue_process_apc( HANDLE process, const union apc_call *call, union apc_result *result )
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1759,8 +1759,8 @@ NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source, HANDLE
|
|||
|
||||
if ((options & DUPLICATE_CLOSE_SOURCE) && source_process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
|
|
@ -1992,6 +1992,35 @@ NTSTATUS WINAPI NtSetIoCompletion( HANDLE handle, ULONG_PTR key, ULONG_PTR value
|
|||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtSetIoCompletionEx (NTDLL.@)
|
||||
*
|
||||
* completion_reserve_handle is a handle allocated by NtAllocateReserveObject() for pre-allocating
|
||||
* memory for completion objects to deal with low-memory situations. It's not in use for now.
|
||||
*/
|
||||
NTSTATUS WINAPI NtSetIoCompletionEx( HANDLE completion_handle, HANDLE completion_reserve_handle,
|
||||
ULONG_PTR key, ULONG_PTR value, NTSTATUS status, SIZE_T count )
|
||||
{
|
||||
unsigned int ret;
|
||||
|
||||
TRACE( "(%p, %p, %lx, %lx, %x, %lx)\n", completion_handle, completion_reserve_handle,
|
||||
key, value, (int)status, count );
|
||||
|
||||
if (!completion_reserve_handle) return STATUS_INVALID_HANDLE;
|
||||
|
||||
SERVER_START_REQ( add_completion )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( completion_handle );
|
||||
req->ckey = key;
|
||||
req->cvalue = value;
|
||||
req->status = status;
|
||||
req->information = count;
|
||||
req->reserve_handle = wine_server_obj_handle( completion_reserve_handle );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtRemoveIoCompletion (NTDLL.@)
|
||||
|
|
|
@ -2131,6 +2131,26 @@ static struct smbios_prologue *create_smbios_data(void)
|
|||
|
||||
#endif
|
||||
|
||||
static NTSTATUS enum_firmware_info( SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti, ULONG available_len,
|
||||
ULONG *required_len )
|
||||
{
|
||||
ULONG len;
|
||||
|
||||
switch (sfti->ProviderSignature)
|
||||
{
|
||||
case RSMB:
|
||||
sfti->TableBufferLength = len = sizeof(UINT);
|
||||
*required_len = offsetof( SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer[len] );
|
||||
if (available_len < *required_len) return STATUS_BUFFER_TOO_SMALL;
|
||||
*(UINT *)sfti->TableBuffer = 0;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
default:
|
||||
FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION provider %08x\n", (unsigned int)sfti->ProviderSignature);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
static NTSTATUS get_firmware_info( SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti, ULONG available_len,
|
||||
ULONG *required_len )
|
||||
{
|
||||
|
@ -3459,14 +3479,17 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
|
|||
ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||
break;
|
||||
}
|
||||
len = 0;
|
||||
|
||||
switch (sfti->Action)
|
||||
{
|
||||
case SystemFirmwareTable_Enumerate:
|
||||
ret = enum_firmware_info(sfti, size, &len);
|
||||
break;
|
||||
case SystemFirmwareTable_Get:
|
||||
ret = get_firmware_info(sfti, size, &len);
|
||||
break;
|
||||
default:
|
||||
len = 0;
|
||||
ret = STATUS_NOT_IMPLEMENTED;
|
||||
FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION action %d\n", sfti->Action);
|
||||
}
|
||||
|
|
|
@ -1323,8 +1323,8 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -1712,7 +1712,7 @@ NTSTATUS WINAPI NtQueueApcThread( HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1
|
|||
ULONG_PTR arg2, ULONG_PTR arg3 )
|
||||
{
|
||||
unsigned int ret;
|
||||
apc_call_t call;
|
||||
union apc_call call;
|
||||
|
||||
SERVER_START_REQ( queue_apc )
|
||||
{
|
||||
|
|
|
@ -209,11 +209,11 @@ extern unsigned int server_call_unlocked( void *req_ptr );
|
|||
extern void server_enter_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset );
|
||||
extern void server_leave_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset );
|
||||
extern unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags,
|
||||
timeout_t abs_timeout, context_t *context, user_apc_t *user_apc );
|
||||
timeout_t abs_timeout, context_t *context, struct user_apc *user_apc );
|
||||
extern unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT flags,
|
||||
const LARGE_INTEGER *timeout );
|
||||
extern unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call,
|
||||
apc_result_t *result );
|
||||
extern unsigned int server_queue_process_apc( HANDLE process, const union apc_call *call,
|
||||
union apc_result *result );
|
||||
extern int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
|
||||
int *needs_close, enum server_fd_type *type, unsigned int *options );
|
||||
extern void wine_server_send_fd( int fd );
|
||||
|
@ -436,10 +436,10 @@ static inline void mutex_unlock( pthread_mutex_t *mutex )
|
|||
if (!process_exiting) pthread_mutex_unlock( mutex );
|
||||
}
|
||||
|
||||
static inline async_data_t server_async( HANDLE handle, struct async_fileio *user, HANDLE event,
|
||||
PIO_APC_ROUTINE apc, void *apc_context, client_ptr_t iosb )
|
||||
static inline struct async_data server_async( HANDLE handle, struct async_fileio *user, HANDLE event,
|
||||
PIO_APC_ROUTINE apc, void *apc_context, client_ptr_t iosb )
|
||||
{
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
async.handle = wine_server_obj_handle( handle );
|
||||
async.user = wine_server_client_ptr( user );
|
||||
async.iosb = iosb;
|
||||
|
|
|
@ -4671,8 +4671,8 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR z
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
unsigned int status;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
@ -4817,8 +4817,8 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -4864,8 +4864,8 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -4962,8 +4962,8 @@ NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5146,8 +5146,8 @@ static unsigned int get_basic_memory_info( HANDLE process, LPCVOID addr,
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5559,8 +5559,8 @@ NTSTATUS WINAPI NtLockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size,
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5596,8 +5596,8 @@ NTSTATUS WINAPI NtUnlockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5672,8 +5672,8 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5744,8 +5744,8 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5788,8 +5788,8 @@ static NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr, ULONG flags )
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5973,8 +5973,8 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HANDLE process, LPCVOID *addr_ptr,
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -6359,8 +6359,8 @@ NTSTATUS WINAPI NtWow64AllocateVirtualMemory64( HANDLE process, ULONG64 *ret, UL
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
|
|
@ -1525,6 +1525,7 @@
|
|||
@ stdcall -private ZwSetInformationToken(long long ptr long) NtSetInformationToken
|
||||
@ stdcall -private ZwSetIntervalProfile(long long) NtSetIntervalProfile
|
||||
@ stdcall -private ZwSetIoCompletion(ptr long long long long) NtSetIoCompletion
|
||||
@ stdcall -private ZwSetIoCompletionEx(ptr ptr long long long long) NtSetIoCompletionEx
|
||||
@ stdcall -private ZwSetSecurityObject(long long ptr) NtSetSecurityObject
|
||||
@ stdcall -private ZwSetSystemInformation(long ptr long) NtSetSystemInformation
|
||||
@ stdcall -private ZwSetSystemTime(ptr ptr) NtSetSystemTime
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -525,11 +525,19 @@ void find_domain_name(const WCHAR *host, DWORD host_len,
|
|||
return;
|
||||
}
|
||||
} else if(last_tld-host < 3)
|
||||
/* Anything less than 3 characters is considered part
|
||||
{
|
||||
/* Anything less than 3 ASCII characters is considered part
|
||||
* of the TLD name.
|
||||
* Ex: ak.uk -> Has no domain name.
|
||||
*/
|
||||
return;
|
||||
for(p = host; p < last_tld; p++) {
|
||||
if(!is_ascii(*p))
|
||||
break;
|
||||
}
|
||||
|
||||
if(p == last_tld)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise the domain name is the whole host name. */
|
||||
*domain_start = 0;
|
||||
|
@ -1339,11 +1347,21 @@ static BOOL parse_reg_name(const WCHAR **ptr, parse_data *data, DWORD extras) {
|
|||
/* If the host is empty, then it's an unknown host type. */
|
||||
if(data->host_len == 0 || is_res)
|
||||
data->host_type = Uri_HOST_UNKNOWN;
|
||||
else
|
||||
else {
|
||||
unsigned int i;
|
||||
|
||||
data->host_type = Uri_HOST_DNS;
|
||||
|
||||
TRACE("(%p %p %lx): Parsed reg-name. host=%s len=%ld\n", ptr, data, extras,
|
||||
debugstr_wn(data->host, data->host_len), data->host_len);
|
||||
for(i = 0; i < data->host_len; i++) {
|
||||
if(!is_ascii(data->host[i])) {
|
||||
data->host_type = Uri_HOST_IDN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("(%p %p %lx): Parsed reg-name. host=%s len=%ld type=%d\n", ptr, data, extras,
|
||||
debugstr_wn(data->host, data->host_len), data->host_len, data->host_type);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -2276,6 +2294,13 @@ static BOOL canonicalize_host(const parse_data *data, Uri *uri, DWORD flags, BOO
|
|||
|
||||
uri->host_type = Uri_HOST_IPV6;
|
||||
break;
|
||||
|
||||
case Uri_HOST_IDN:
|
||||
uri->host_type = Uri_HOST_IDN;
|
||||
if(!canonicalize_reg_name(data, uri, flags, computeOnly))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
case Uri_HOST_UNKNOWN:
|
||||
if(data->host_len > 0 || data->scheme_type != URL_SCHEME_FILE) {
|
||||
uri->host_start = uri->canon_len;
|
||||
|
@ -3873,17 +3898,37 @@ static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BST
|
|||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
/* Don't have support for flags yet. */
|
||||
if(dwFlags) {
|
||||
FIXME("(%p)->(%d %p %lx)\n", This, uriProp, pbstrProperty, dwFlags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
if(dwFlags != 0 && dwFlags != Uri_DISPLAY_NO_FRAGMENT && dwFlags != Uri_PUNYCODE_IDN_HOST
|
||||
&& dwFlags != Uri_DISPLAY_IDN_HOST)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if((dwFlags == Uri_DISPLAY_NO_FRAGMENT && uriProp != Uri_PROPERTY_DISPLAY_URI)
|
||||
|| (dwFlags == Uri_PUNYCODE_IDN_HOST && uriProp != Uri_PROPERTY_ABSOLUTE_URI
|
||||
&& uriProp != Uri_PROPERTY_DOMAIN && uriProp != Uri_PROPERTY_HOST)
|
||||
|| (dwFlags == Uri_DISPLAY_IDN_HOST && uriProp != Uri_PROPERTY_ABSOLUTE_URI
|
||||
&& uriProp != Uri_PROPERTY_DOMAIN && uriProp != Uri_PROPERTY_HOST))
|
||||
return E_INVALIDARG;
|
||||
|
||||
switch(uriProp) {
|
||||
case Uri_PROPERTY_ABSOLUTE_URI:
|
||||
if(This->display_modifiers & URI_DISPLAY_NO_ABSOLUTE_URI) {
|
||||
*pbstrProperty = SysAllocStringLen(NULL, 0);
|
||||
hres = S_FALSE;
|
||||
}
|
||||
/* Uri_PUNYCODE_IDN_HOST doesn't remove user info containing only "@" and ":@" */
|
||||
else if (dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN && This->host_start > -1) {
|
||||
unsigned int punycode_host_len;
|
||||
|
||||
punycode_host_len = IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, NULL, 0);
|
||||
*pbstrProperty = SysAllocStringLen(NULL, This->canon_len-This->host_len+punycode_host_len);
|
||||
hres = S_OK;
|
||||
if(*pbstrProperty) {
|
||||
memcpy(*pbstrProperty, This->canon_uri, This->host_start*sizeof(WCHAR));
|
||||
IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, *pbstrProperty+This->host_start, punycode_host_len);
|
||||
memcpy(*pbstrProperty+This->host_start+punycode_host_len,
|
||||
This->canon_uri+This->host_start+This->host_len,
|
||||
(This->canon_len-This->host_start-This->host_len)*sizeof(WCHAR));
|
||||
}
|
||||
} else {
|
||||
if(This->scheme_type != URL_SCHEME_UNKNOWN && This->userinfo_start > -1) {
|
||||
if(This->userinfo_len == 0) {
|
||||
|
@ -3944,18 +3989,32 @@ static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BST
|
|||
* scheme types.
|
||||
*/
|
||||
if(This->scheme_type != URL_SCHEME_UNKNOWN && This->userinfo_start > -1) {
|
||||
*pbstrProperty = SysAllocStringLen(NULL, This->canon_len-This->userinfo_len);
|
||||
unsigned int length = This->canon_len-This->userinfo_len;
|
||||
|
||||
/* Skip fragment if Uri_DISPLAY_NO_FRAGMENT is specified */
|
||||
if(dwFlags == Uri_DISPLAY_NO_FRAGMENT && This->fragment_start > -1)
|
||||
length -= This->fragment_len;
|
||||
|
||||
*pbstrProperty = SysAllocStringLen(NULL, length);
|
||||
|
||||
if(*pbstrProperty) {
|
||||
/* Copy everything before the userinfo over. */
|
||||
memcpy(*pbstrProperty, This->canon_uri, This->userinfo_start*sizeof(WCHAR));
|
||||
|
||||
/* Copy everything after the userinfo over. */
|
||||
length -= This->userinfo_start+1;
|
||||
memcpy(*pbstrProperty+This->userinfo_start,
|
||||
This->canon_uri+This->userinfo_start+This->userinfo_len+1,
|
||||
(This->canon_len-(This->userinfo_start+This->userinfo_len+1))*sizeof(WCHAR));
|
||||
This->canon_uri+This->userinfo_start+This->userinfo_len+1, length*sizeof(WCHAR));
|
||||
}
|
||||
} else
|
||||
*pbstrProperty = SysAllocString(This->canon_uri);
|
||||
} else {
|
||||
unsigned int length = This->canon_len;
|
||||
|
||||
/* Skip fragment if Uri_DISPLAY_NO_FRAGMENT is specified */
|
||||
if(dwFlags == Uri_DISPLAY_NO_FRAGMENT && This->fragment_start > -1)
|
||||
length -= This->fragment_len;
|
||||
|
||||
*pbstrProperty = SysAllocStringLen(This->canon_uri, length);
|
||||
}
|
||||
|
||||
if(!(*pbstrProperty))
|
||||
hres = E_OUTOFMEMORY;
|
||||
|
@ -3965,8 +4024,20 @@ static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BST
|
|||
break;
|
||||
case Uri_PROPERTY_DOMAIN:
|
||||
if(This->domain_offset > -1) {
|
||||
*pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start+This->domain_offset,
|
||||
This->host_len-This->domain_offset);
|
||||
if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN) {
|
||||
unsigned int punycode_length;
|
||||
|
||||
punycode_length = IdnToAscii(0, This->canon_uri+This->host_start+This->domain_offset,
|
||||
This->host_len-This->domain_offset, NULL, 0);
|
||||
*pbstrProperty = SysAllocStringLen(NULL, punycode_length);
|
||||
if (*pbstrProperty)
|
||||
IdnToAscii(0, This->canon_uri+This->host_start+This->domain_offset,
|
||||
This->host_len-This->domain_offset, *pbstrProperty, punycode_length);
|
||||
} else {
|
||||
*pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start+This->domain_offset,
|
||||
This->host_len-This->domain_offset);
|
||||
}
|
||||
|
||||
hres = S_OK;
|
||||
} else {
|
||||
*pbstrProperty = SysAllocStringLen(NULL, 0);
|
||||
|
@ -4009,6 +4080,14 @@ static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BST
|
|||
/* The '[' and ']' aren't included for IPv6 addresses. */
|
||||
if(This->host_type == Uri_HOST_IPV6)
|
||||
*pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start+1, This->host_len-2);
|
||||
else if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN) {
|
||||
unsigned int punycode_length;
|
||||
|
||||
punycode_length = IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, NULL, 0);
|
||||
*pbstrProperty = SysAllocStringLen(NULL, punycode_length);
|
||||
if (*pbstrProperty)
|
||||
IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, *pbstrProperty, punycode_length);
|
||||
}
|
||||
else
|
||||
*pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start, This->host_len);
|
||||
|
||||
|
@ -4156,10 +4235,10 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
|
|||
if(uriProp > Uri_PROPERTY_STRING_LAST)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* Don't have support for flags yet. */
|
||||
if(dwFlags) {
|
||||
FIXME("(%p)->(%d %p %lx)\n", This, uriProp, pcchProperty, dwFlags);
|
||||
return E_NOTIMPL;
|
||||
if(dwFlags != 0 && dwFlags != Uri_DISPLAY_NO_FRAGMENT && dwFlags != Uri_PUNYCODE_IDN_HOST
|
||||
&& dwFlags != Uri_DISPLAY_IDN_HOST) {
|
||||
*pcchProperty = 0;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
switch(uriProp) {
|
||||
|
@ -4167,6 +4246,12 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
|
|||
if(This->display_modifiers & URI_DISPLAY_NO_ABSOLUTE_URI) {
|
||||
*pcchProperty = 0;
|
||||
hres = S_FALSE;
|
||||
}
|
||||
/* Uri_PUNYCODE_IDN_HOST doesn't remove user info containing only "@" and ":@" */
|
||||
else if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN && This->host_start > -1) {
|
||||
unsigned int punycode_host_len = IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, NULL, 0);
|
||||
*pcchProperty = This->canon_len - This->host_len + punycode_host_len;
|
||||
hres = S_OK;
|
||||
} else {
|
||||
if(This->scheme_type != URL_SCHEME_UNKNOWN) {
|
||||
if(This->userinfo_start > -1 && This->userinfo_len == 0)
|
||||
|
@ -4201,11 +4286,18 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
|
|||
else
|
||||
*pcchProperty = This->canon_len;
|
||||
|
||||
if(dwFlags == Uri_DISPLAY_NO_FRAGMENT && This->fragment_start > -1)
|
||||
*pcchProperty -= This->fragment_len;
|
||||
|
||||
hres = S_OK;
|
||||
break;
|
||||
case Uri_PROPERTY_DOMAIN:
|
||||
if(This->domain_offset > -1)
|
||||
*pcchProperty = This->host_len - This->domain_offset;
|
||||
if(This->domain_offset > -1) {
|
||||
if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN)
|
||||
*pcchProperty = IdnToAscii(0, This->canon_uri+This->host_start+This->domain_offset, This->host_len-This->domain_offset, NULL, 0);
|
||||
else
|
||||
*pcchProperty = This->host_len - This->domain_offset;
|
||||
}
|
||||
else
|
||||
*pcchProperty = 0;
|
||||
|
||||
|
@ -4231,6 +4323,8 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
|
|||
/* '[' and ']' aren't included in the length. */
|
||||
if(This->host_type == Uri_HOST_IPV6)
|
||||
*pcchProperty -= 2;
|
||||
else if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN && This->host_start > -1)
|
||||
*pcchProperty = IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, NULL, 0);
|
||||
|
||||
hres = (This->host_start > -1) ? S_OK : S_FALSE;
|
||||
break;
|
||||
|
@ -4274,6 +4368,16 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
|
|||
hres = E_NOTIMPL;
|
||||
}
|
||||
|
||||
if(hres == S_OK
|
||||
&& ((dwFlags == Uri_DISPLAY_NO_FRAGMENT && uriProp != Uri_PROPERTY_DISPLAY_URI)
|
||||
|| (dwFlags == Uri_PUNYCODE_IDN_HOST && uriProp != Uri_PROPERTY_ABSOLUTE_URI
|
||||
&& uriProp != Uri_PROPERTY_DOMAIN && uriProp != Uri_PROPERTY_HOST)
|
||||
|| (dwFlags == Uri_DISPLAY_IDN_HOST && uriProp != Uri_PROPERTY_ABSOLUTE_URI
|
||||
&& uriProp != Uri_PROPERTY_DOMAIN && uriProp != Uri_PROPERTY_HOST))) {
|
||||
*pcchProperty = 0;
|
||||
hres = E_INVALIDARG;
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,11 @@ struct ThreadWindows
|
|||
HWND *handles;
|
||||
};
|
||||
|
||||
/* Index the order the buttons need to appear to an ID* constant */
|
||||
static const int buttonOrder[10] = { IDYES, IDNO, IDOK, IDABORT, IDRETRY,
|
||||
IDCANCEL, IDIGNORE, IDTRYAGAIN,
|
||||
IDCONTINUE, IDHELP };
|
||||
|
||||
static BOOL CALLBACK MSGBOX_EnumProc(HWND hwnd, LPARAM lParam)
|
||||
{
|
||||
struct ThreadWindows *threadWindows = (struct ThreadWindows *)lParam;
|
||||
|
@ -74,11 +79,6 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
|
|||
WCHAR *buffer = NULL;
|
||||
const WCHAR *ptr;
|
||||
|
||||
/* Index the order the buttons need to appear to an ID* constant */
|
||||
static const int buttonOrder[10] = { IDYES, IDNO, IDOK, IDABORT, IDRETRY,
|
||||
IDCANCEL, IDIGNORE, IDTRYAGAIN,
|
||||
IDCONTINUE, IDHELP };
|
||||
|
||||
nclm.cbSize = sizeof(nclm);
|
||||
SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
|
||||
|
||||
|
@ -320,6 +320,95 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
|
|||
HeapFree( GetProcessHeap(), 0, buffer );
|
||||
}
|
||||
|
||||
static void MSGBOX_CopyToClipbaord( HWND hwnd )
|
||||
{
|
||||
int i;
|
||||
static const WCHAR line[] = L"---------------------------\r\n";
|
||||
static const WCHAR carriage[] = L"\r\n";
|
||||
static const WCHAR spaces[] = L" ";
|
||||
int lenTitle = GetWindowTextLengthW(hwnd) + 1;
|
||||
int lenMsg = GetWindowTextLengthW(GetDlgItem(hwnd, MSGBOX_IDTEXT)) + 1;
|
||||
HGLOBAL hMem;
|
||||
WCHAR *data;
|
||||
|
||||
|
||||
/*
|
||||
---------------------------
|
||||
Dialog Title
|
||||
---------------------------
|
||||
Dialog Message
|
||||
---------------------------
|
||||
Button(s) Text. OK
|
||||
---------------------------
|
||||
*/
|
||||
int len = ((wcslen(carriage) * 3) + (wcslen(line) * 4) + lenTitle + lenMsg) * sizeof(WCHAR);
|
||||
WCHAR *text = malloc(len);
|
||||
if (!text)
|
||||
return;
|
||||
|
||||
lstrcpyW(text, line);
|
||||
if (!GetWindowTextW(hwnd, text + lstrlenW(text), lenTitle))
|
||||
{
|
||||
free(text);
|
||||
return;
|
||||
}
|
||||
|
||||
lstrcatW(text, carriage);
|
||||
lstrcatW(text, line);
|
||||
GetWindowTextW(GetDlgItem(hwnd, MSGBOX_IDTEXT), text + lstrlenW(text), lenMsg);
|
||||
lstrcatW(text, carriage);
|
||||
lstrcatW(text, line);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(buttonOrder); i++)
|
||||
{
|
||||
HWND hItem = GetDlgItem(hwnd, buttonOrder[i]);
|
||||
if (GetWindowLongW(hItem, GWL_STYLE) & WS_VISIBLE)
|
||||
{
|
||||
WCHAR buffer[1024] = {0};
|
||||
int j = 0, k = lstrlenW(text);
|
||||
GetWindowTextW(hItem, buffer, 1024);
|
||||
while(buffer[j] != 0)
|
||||
{
|
||||
if(buffer[j] != '&')
|
||||
text[k++] = buffer[j];
|
||||
j++;
|
||||
}
|
||||
text[k] = 0;
|
||||
lstrcatW(text, spaces);
|
||||
}
|
||||
}
|
||||
|
||||
lstrcatW(text, carriage);
|
||||
lstrcatW(text, line);
|
||||
|
||||
hMem = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, len);
|
||||
data = GlobalLock(hMem);
|
||||
lstrcpyW(data, text);
|
||||
GlobalUnlock(hMem);
|
||||
|
||||
OpenClipboard(hwnd);
|
||||
NtUserEmptyClipboard();
|
||||
SetClipboardData(CF_UNICODETEXT, hMem);
|
||||
NtUserCloseClipboard();
|
||||
|
||||
free(text);
|
||||
}
|
||||
|
||||
HHOOK msghook_handle;
|
||||
|
||||
LRESULT CALLBACK msg_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
MSG *msg = (MSG *)lParam;
|
||||
if (nCode == MSGF_DIALOGBOX && msg->message == WM_KEYUP)
|
||||
{
|
||||
if ( (msg->wParam == 'C' || msg->wParam == 'c') && (NtUserGetKeyState(VK_CONTROL) & 0x8000))
|
||||
{
|
||||
MSGBOX_CopyToClipbaord(GetParent(msg->hwnd));
|
||||
}
|
||||
}
|
||||
|
||||
return NtUserCallNextHookEx(msghook_handle, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* MSGBOX_DlgProc
|
||||
|
@ -336,9 +425,18 @@ static INT_PTR CALLBACK MSGBOX_DlgProc( HWND hwnd, UINT message,
|
|||
SetWindowContextHelpId(hwnd, mbp->dwContextHelpId);
|
||||
MSGBOX_OnInit(hwnd, mbp);
|
||||
SetPropA(hwnd, "WINE_MSGBOX_HELPCALLBACK", mbp->lpfnMsgBoxCallback);
|
||||
msghook_handle = SetWindowsHookExA(WH_MSGFILTER, msg_hook_proc, NULL, GetCurrentThreadId());
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_COPY:
|
||||
MSGBOX_CopyToClipbaord(hwnd);
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
NtUserUnhookWindowsHookEx(msghook_handle);
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
|
|
|
@ -6187,6 +6187,13 @@ static const struct message WmMove_mouse[] = {
|
|||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message WmMove_mouse2[] = {
|
||||
{ WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOACTIVATE },
|
||||
{ WM_GETTEXT, sent|optional },
|
||||
{ WM_GETMINMAXINFO, sent|defwinproc },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void test_setwindowpos(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
|
@ -6253,6 +6260,11 @@ static void test_setwindowpos(void)
|
|||
ok(res == TRUE, "SetWindowPos expected TRUE, got %Id.\n", res);
|
||||
flush_events();
|
||||
ok_sequence(WmMove_mouse, "MouseMove", FALSE);
|
||||
/* if the window and client rects were not changed WM_MOUSEMOVE is not sent. */
|
||||
res = SetWindowPos( hwnd, 0, 205, 205, 200, 200, SWP_NOZORDER | SWP_NOACTIVATE );
|
||||
ok(res == TRUE, "SetWindowPos expected TRUE, got %Id.\n", res);
|
||||
flush_events();
|
||||
ok_sequence(WmMove_mouse2, "MouseMove2", FALSE);
|
||||
ignore_mouse_messages = TRUE;
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
|
|
|
@ -558,7 +558,7 @@
|
|||
@ stdcall GetDlgItemTextA(long long ptr long)
|
||||
@ stdcall GetDlgItemTextW(long long ptr long)
|
||||
@ stdcall GetDoubleClickTime() NtUserGetDoubleClickTime
|
||||
# @ stub GetDpiAwarenessContextForProcess
|
||||
@ stdcall GetDpiAwarenessContextForProcess(ptr)
|
||||
@ stdcall GetDpiForMonitorInternal(long long ptr ptr) NtUserGetDpiForMonitor
|
||||
@ stdcall GetDpiForSystem()
|
||||
@ stdcall GetDpiForWindow(long)
|
||||
|
|
|
@ -615,6 +615,13 @@ DPI_AWARENESS_CONTEXT WINAPI GetWindowDpiAwarenessContext( HWND hwnd )
|
|||
return LongToHandle( NtUserGetWindowDpiAwarenessContext( hwnd ) );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetDpiAwarenessContextForProcess (USER32.@)
|
||||
*/
|
||||
DPI_AWARENESS_CONTEXT WINAPI GetDpiAwarenessContextForProcess(HANDLE process)
|
||||
{
|
||||
return LongToHandle( NtUserGetProcessDpiAwarenessContext( process ) );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetWindowDpiHostingBehavior (USER32.@)
|
||||
|
|
|
@ -7366,7 +7366,7 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl
|
|||
}
|
||||
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
|
||||
{
|
||||
shader_addline(buffer, "%s = clamp(outputs[%u].%c, 0.0, 1.0);\n",
|
||||
shader_addline(buffer, "%s = outputs[%u].%c;\n",
|
||||
legacy_syntax ? "gl_FogFragCoord" : "ffp_varying_fogcoord",
|
||||
output->register_idx, reg_mask[1]);
|
||||
}
|
||||
|
@ -11402,6 +11402,8 @@ static void shader_glsl_get_caps(const struct wined3d_adapter *adapter, struct s
|
|||
|
||||
TRACE("Shader model %u.\n", shader_model);
|
||||
|
||||
memset(caps, 0, sizeof(*caps));
|
||||
|
||||
caps->vs_version = min(wined3d_settings.max_sm_vs, shader_model);
|
||||
caps->hs_version = min(wined3d_settings.max_sm_hs, shader_model);
|
||||
caps->ds_version = min(wined3d_settings.max_sm_ds, shader_model);
|
||||
|
@ -11743,6 +11745,8 @@ static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_adapter *adapter,
|
|||
{
|
||||
const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl_const(adapter)->gl_info;
|
||||
|
||||
memset(caps, 0, sizeof(*caps));
|
||||
|
||||
caps->emulated_flatshading = !needs_legacy_glsl_syntax(gl_info);
|
||||
caps->max_active_lights = WINED3D_MAX_ACTIVE_LIGHTS;
|
||||
caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS;
|
||||
|
|
|
@ -1065,6 +1065,8 @@ static void shader_spirv_init_context_state(struct wined3d_context *context)
|
|||
|
||||
static void shader_spirv_get_caps(const struct wined3d_adapter *adapter, struct shader_caps *caps)
|
||||
{
|
||||
memset(caps, 0, sizeof(*caps));
|
||||
|
||||
caps->vs_version = min(wined3d_settings.max_sm_vs, 5);
|
||||
caps->hs_version = min(wined3d_settings.max_sm_hs, 5);
|
||||
caps->ds_version = min(wined3d_settings.max_sm_ds, 5);
|
||||
|
@ -1196,6 +1198,7 @@ static void spirv_fragment_pipe_vk_fp_disable(const struct wined3d_context *cont
|
|||
static void spirv_fragment_pipe_vk_fp_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps)
|
||||
{
|
||||
memset(caps, 0, sizeof(*caps));
|
||||
caps->max_blend_stages = WINED3D_MAX_FFP_TEXTURES;
|
||||
}
|
||||
|
||||
static unsigned int spirv_fragment_pipe_vk_fp_get_emul_mask(const struct wined3d_adapter *adapter)
|
||||
|
|
|
@ -3697,14 +3697,9 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
|
|||
if (changed->texture_matrices)
|
||||
{
|
||||
struct wined3d_ffp_vs_constants constants;
|
||||
struct wined3d_stream_info si;
|
||||
|
||||
/* FIXME: This is a bit fragile. Ideally we should be calculating
|
||||
* stream info from the stateblock state. */
|
||||
wined3d_stream_info_from_declaration(&si, context->state, &device->adapter->d3d_info);
|
||||
|
||||
for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i)
|
||||
get_texture_matrix(&si, state, i, &constants.texture_matrices[i]);
|
||||
get_texture_matrix(state, i, &constants.texture_matrices[i]);
|
||||
wined3d_device_context_push_constants(context,
|
||||
WINED3D_PUSH_CONSTANTS_VS_FFP, WINED3D_SHADER_CONST_FFP_TEXMATRIX,
|
||||
offsetof(struct wined3d_ffp_vs_constants, texture_matrices),
|
||||
|
|
|
@ -5608,38 +5608,43 @@ static void compute_texture_matrix(const struct wined3d_matrix *matrix, uint32_t
|
|||
|
||||
mat = *matrix;
|
||||
|
||||
/* Under Direct3D the R/Z coord can be used for translation, under
|
||||
* OpenGL we use the Q coord instead. */
|
||||
/* When less than 4 components are provided for an attribute, the remaining
|
||||
* components are filled with (..., 0, 0, 1). This is the case when using
|
||||
* shaders in Direct3D as well as in GL and Vulkan.
|
||||
*
|
||||
* However, when using the Direct3D fixed function vertex pipeline, the
|
||||
* texture coordinates transformed by texture matrices effectively have
|
||||
* 1 in the first "default" component and 0 in the others (e.g. for
|
||||
* R32_FLOAT the coordinates are (..., 1, 0, 0).
|
||||
*
|
||||
* We could approximate this by modifying the shader, but modifying uniforms
|
||||
* is generally cheaper, so instead we change the matrix, copying the 2nd or
|
||||
* 3rd column to the 4th. That is, whichever coefficients expect a value of
|
||||
* 1 will instead be used as the coefficients for the 4th column, which
|
||||
* actually has a value of 1. The coefficients for other columns don't need
|
||||
* to be modified, since the corresponding texcoord components are zero. */
|
||||
|
||||
if (!(flags & WINED3D_TTFF_PROJECTED) && !calculated_coords)
|
||||
{
|
||||
switch (format_id)
|
||||
{
|
||||
/* Direct3D passes the default 1.0 in the 2nd coord, while GL
|
||||
* passes it in the 4th. Swap 2nd and 4th coord. No need to
|
||||
* store the value of mat._41 in mat._21 because the input
|
||||
* value to the transformation will be 0, so the matrix value
|
||||
* is irrelevant. */
|
||||
case WINED3DFMT_R32_FLOAT:
|
||||
mat._41 = mat._21;
|
||||
mat._42 = mat._22;
|
||||
mat._43 = mat._23;
|
||||
mat._44 = mat._24;
|
||||
break;
|
||||
/* See above, just 3rd and 4th coord. */
|
||||
|
||||
case WINED3DFMT_R32G32_FLOAT:
|
||||
mat._41 = mat._31;
|
||||
mat._42 = mat._32;
|
||||
mat._43 = mat._33;
|
||||
mat._44 = mat._34;
|
||||
break;
|
||||
case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
|
||||
case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
|
||||
|
||||
/* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
|
||||
* into a bad place. The division elimination below will apply to make sure the
|
||||
* 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
|
||||
*/
|
||||
case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
|
||||
case WINED3DFMT_R32G32B32_FLOAT:
|
||||
case WINED3DFMT_R32G32B32A32_FLOAT:
|
||||
case WINED3DFMT_UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
FIXME("Unexpected fixed function texture coord input\n");
|
||||
|
@ -5649,23 +5654,29 @@ static void compute_texture_matrix(const struct wined3d_matrix *matrix, uint32_t
|
|||
*out_matrix = mat;
|
||||
}
|
||||
|
||||
void get_texture_matrix(const struct wined3d_stream_info *si,
|
||||
const struct wined3d_stateblock_state *state, const unsigned int tex, struct wined3d_matrix *mat)
|
||||
static enum wined3d_format_id get_texcoord_format(const struct wined3d_vertex_declaration *decl, unsigned int index)
|
||||
{
|
||||
for (unsigned int i = 0; i < decl->element_count; ++i)
|
||||
{
|
||||
if (decl->elements[i].usage == WINED3D_DECL_USAGE_TEXCOORD
|
||||
&& decl->elements[i].usage_idx == index)
|
||||
return decl->elements[i].format->id;
|
||||
}
|
||||
|
||||
return WINED3DFMT_UNKNOWN;
|
||||
}
|
||||
|
||||
void get_texture_matrix(const struct wined3d_stateblock_state *state,
|
||||
const unsigned int tex, struct wined3d_matrix *mat)
|
||||
{
|
||||
BOOL generated = (state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
|
||||
!= WINED3DTSS_TCI_PASSTHRU;
|
||||
unsigned int coord_idx = min(state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0x0000ffff,
|
||||
WINED3D_MAX_FFP_TEXTURES - 1);
|
||||
enum wined3d_format_id attribute_format;
|
||||
|
||||
if (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))
|
||||
attribute_format = si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->id;
|
||||
else
|
||||
attribute_format = WINED3DFMT_UNKNOWN;
|
||||
|
||||
compute_texture_matrix(&state->transforms[WINED3D_TS_TEXTURE0 + tex],
|
||||
state->texture_states[tex][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
|
||||
generated, attribute_format, mat);
|
||||
generated, get_texcoord_format(state->vertex_declaration, coord_idx), mat);
|
||||
}
|
||||
|
||||
void get_pointsize_minmax(const struct wined3d_context *context, const struct wined3d_state *state,
|
||||
|
|
|
@ -4376,8 +4376,8 @@ static inline BOOL shader_sampler_is_shadow(const struct wined3d_shader *shader,
|
|||
|
||||
void get_identity_matrix(struct wined3d_matrix *mat);
|
||||
void get_modelview_matrix(const struct wined3d_stateblock_state *state, unsigned int index, struct wined3d_matrix *mat);
|
||||
void get_texture_matrix(const struct wined3d_stream_info *si,
|
||||
const struct wined3d_stateblock_state *state, const unsigned int tex, struct wined3d_matrix *mat);
|
||||
void get_texture_matrix(const struct wined3d_stateblock_state *state,
|
||||
const unsigned int tex, struct wined3d_matrix *mat);
|
||||
void get_pointsize_minmax(const struct wined3d_context *context, const struct wined3d_state *state,
|
||||
float *out_min, float *out_max);
|
||||
void get_fog_start_end(const struct wined3d_context *context, const struct wined3d_state *state,
|
||||
|
|
|
@ -696,57 +696,72 @@ void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data)
|
|||
static const struct {
|
||||
WCHAR wchar;
|
||||
DWORD vkey;
|
||||
/* Mac virtual key code that must match wchar under the current layout.
|
||||
* A value of -1 means match-any.
|
||||
* TODO: replace -1 with the actual mac virtual key codes for all mappings
|
||||
* and their respective layouts to avoid false matches, when possible. */
|
||||
int mac_keyc;
|
||||
} symbol_vkeys[] = {
|
||||
{ '-', VK_OEM_MINUS },
|
||||
{ '+', VK_OEM_PLUS },
|
||||
{ '_', VK_OEM_MINUS },
|
||||
{ ',', VK_OEM_COMMA },
|
||||
{ '.', VK_OEM_PERIOD },
|
||||
{ '=', VK_OEM_PLUS },
|
||||
{ '>', VK_OEM_PERIOD },
|
||||
{ '<', VK_OEM_COMMA },
|
||||
{ '|', VK_OEM_5 },
|
||||
{ '\\', VK_OEM_5 },
|
||||
{ '`', VK_OEM_3 },
|
||||
{ '[', VK_OEM_4 },
|
||||
{ '~', VK_OEM_3 },
|
||||
{ 0x00DF, VK_OEM_4 }, /* 0x00DF is ESZETT */
|
||||
{ 0x00FC, VK_OEM_1 }, /* 0x00FC is German U Umlaut */
|
||||
{ 0x00F6, VK_OEM_3 }, /* 0x00F6 is German O Umlaut */
|
||||
{ 0x00E4, VK_OEM_7 }, /* 0x00B4 is German A Umlaut */
|
||||
{ '?', VK_OEM_2 },
|
||||
{ ']', VK_OEM_6 },
|
||||
{ '/', VK_OEM_2 },
|
||||
{ ':', VK_OEM_1 },
|
||||
{ '}', VK_OEM_6 },
|
||||
{ '{', VK_OEM_4 },
|
||||
{ ';', VK_OEM_1 },
|
||||
{ '\'', VK_OEM_7 },
|
||||
{ ':', VK_OEM_PERIOD },
|
||||
{ ';', VK_OEM_COMMA },
|
||||
{ '"', VK_OEM_7 },
|
||||
{ 0x00B4, VK_OEM_4 }, /* 0x00B4 is ACUTE ACCENT */
|
||||
{ '\'', VK_OEM_2 },
|
||||
{ 0x00A7, VK_OEM_5 }, /* 0x00A7 is SECTION SIGN */
|
||||
{ '*', VK_OEM_PLUS },
|
||||
{ 0x00B4, VK_OEM_7 },
|
||||
{ '`', VK_OEM_4 },
|
||||
{ '[', VK_OEM_6 },
|
||||
{ '/', VK_OEM_5 },
|
||||
{ '^', VK_OEM_6 },
|
||||
{ '*', VK_OEM_2 },
|
||||
{ '{', VK_OEM_6 },
|
||||
{ 0x00B4, VK_OEM_6 },
|
||||
{ '~', VK_OEM_1 },
|
||||
{ '?', VK_OEM_PLUS },
|
||||
{ '?', VK_OEM_4 },
|
||||
{ 0x00B4, VK_OEM_3 },
|
||||
{ '?', VK_OEM_COMMA },
|
||||
{ '~', VK_OEM_PLUS },
|
||||
{ ']', VK_OEM_4 },
|
||||
{ '\'', VK_OEM_3 },
|
||||
{ 0x00A7, VK_OEM_7 },
|
||||
{ '<', VK_OEM_102 },
|
||||
{ '-', VK_OEM_PLUS, kVK_ANSI_Equal },
|
||||
{ '-', VK_OEM_MINUS, -1 },
|
||||
{ '+', VK_OEM_PLUS, -1 },
|
||||
{ '_', VK_OEM_MINUS, -1 },
|
||||
{ ',', VK_OEM_COMMA, -1 },
|
||||
{ '.', VK_OEM_PERIOD, -1 },
|
||||
{ '=', VK_OEM_8, kVK_ANSI_Slash },
|
||||
{ '=', VK_OEM_PLUS, -1 },
|
||||
{ '!', VK_OEM_8, kVK_ANSI_Slash },
|
||||
{ 0x00F9, VK_OEM_3, kVK_ANSI_Quote }, /* 0x00F9 is French U accent grave */
|
||||
{ '$', VK_OEM_1, kVK_ANSI_RightBracket },
|
||||
{ ':', VK_OEM_2, kVK_ANSI_Period },
|
||||
{ '*', VK_OEM_5, kVK_ANSI_Backslash },
|
||||
{ '`', VK_OEM_5, kVK_ANSI_Backslash },
|
||||
{ ';', VK_OEM_PERIOD, kVK_ANSI_Comma },
|
||||
{ ')', VK_OEM_4, kVK_ANSI_Minus },
|
||||
{ '>', VK_OEM_PERIOD, -1 },
|
||||
{ '<', VK_OEM_COMMA, -1 },
|
||||
{ '|', VK_OEM_5, -1 },
|
||||
{ '\\', VK_OEM_5, -1 },
|
||||
{ '`', VK_OEM_3, -1 },
|
||||
{ '[', VK_OEM_4, -1 },
|
||||
{ '~', VK_OEM_3, -1 },
|
||||
{ 0x00DF, VK_OEM_4, kVK_ANSI_Minus }, /* 0x00DF is ESZETT */
|
||||
{ 0x00FC, VK_OEM_1, kVK_ANSI_LeftBracket }, /* 0x00FC is German U Umlaut */
|
||||
{ 0x00F6, VK_OEM_3, kVK_ANSI_Semicolon }, /* 0x00F6 is German O Umlaut */
|
||||
{ 0x00E4, VK_OEM_7, kVK_ANSI_Quote }, /* 0x00B4 is German A Umlaut */
|
||||
{ '?', VK_OEM_2, -1 },
|
||||
{ ']', VK_OEM_6, -1 },
|
||||
{ '/', VK_OEM_2, -1 },
|
||||
{ ':', VK_OEM_1, -1 },
|
||||
{ '}', VK_OEM_6, -1 },
|
||||
{ '{', VK_OEM_4, },
|
||||
{ ';', VK_OEM_1, -1 },
|
||||
{ '\'', VK_OEM_7, -1 },
|
||||
{ ':', VK_OEM_PERIOD, -1 },
|
||||
{ ';', VK_OEM_COMMA, -1 },
|
||||
{ '"', VK_OEM_7, -1 },
|
||||
{ 0x00B4, VK_OEM_4, kVK_ANSI_Equal }, /* 0x00B4 is ACUTE ACCENT */
|
||||
{ '\'', VK_OEM_2, -1 },
|
||||
{ 0x00A7, VK_OEM_5, -1 }, /* 0x00A7 is SECTION SIGN */
|
||||
{ '*', VK_OEM_PLUS, -1 },
|
||||
{ 0x00B4, VK_OEM_7, -1 },
|
||||
{ '`', VK_OEM_4, -1 },
|
||||
{ '[', VK_OEM_6, -1 },
|
||||
{ '/', VK_OEM_5, -1 },
|
||||
{ '^', VK_OEM_6, -1 },
|
||||
{ '*', VK_OEM_2, -1 },
|
||||
{ '{', VK_OEM_6, -1 },
|
||||
{ 0x00B4, VK_OEM_6, -1 },
|
||||
{ '~', VK_OEM_1, -1 },
|
||||
{ '?', VK_OEM_PLUS, -1 },
|
||||
{ '?', VK_OEM_4, -1 },
|
||||
{ 0x00B4, VK_OEM_3, -1 },
|
||||
{ '?', VK_OEM_COMMA, -1 },
|
||||
{ '~', VK_OEM_PLUS, -1 },
|
||||
{ ']', VK_OEM_4, -1 },
|
||||
{ '\'', VK_OEM_3, -1 },
|
||||
{ 0x00A7, VK_OEM_7, -1 },
|
||||
{ '<', VK_OEM_102, -1 },
|
||||
};
|
||||
int i;
|
||||
|
||||
|
@ -915,6 +930,8 @@ void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data)
|
|||
if (!thread_data->keyc2scan[keyc]) continue; /* not a known Mac key code */
|
||||
if (thread_data->keyc2vkey[keyc] || !map[keyc][combo][0])
|
||||
continue;
|
||||
if (symbol_vkeys[i].mac_keyc != -1 && symbol_vkeys[i].mac_keyc != keyc)
|
||||
continue;
|
||||
|
||||
if (char_matches_string(symbol_vkeys[i].wchar, map[keyc][combo], collatorRef))
|
||||
{
|
||||
|
|
|
@ -171,13 +171,49 @@ static inline void free_event_data( XEvent *event )
|
|||
#endif
|
||||
}
|
||||
|
||||
static BOOL host_window_filter_event( XEvent *event )
|
||||
static void host_window_send_configure_events( struct host_window *win, Display *display, unsigned long serial, XEvent *previous )
|
||||
{
|
||||
XConfigureEvent configure = {.type = ConfigureNotify, .serial = serial, .display = display};
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < win->children_count; i++)
|
||||
{
|
||||
RECT rect = win->children[i].rect;
|
||||
struct x11drv_win_data *data;
|
||||
HWND hwnd;
|
||||
|
||||
configure.event = win->children[i].window;
|
||||
configure.window = configure.event;
|
||||
configure.x = rect.left;
|
||||
configure.y = rect.top;
|
||||
configure.width = rect.right - rect.left;
|
||||
configure.height = rect.bottom - rect.top;
|
||||
configure.send_event = 0;
|
||||
|
||||
/* Only send a fake event if we're not expecting one from a state/config request.
|
||||
* We may know what was requested, but not what the WM will decide to reply, and our
|
||||
* fake event might trigger some undesired changes before the real ConfigureNotify.
|
||||
*/
|
||||
if (!XFindContext( configure.display, configure.window, winContext, (char **)&hwnd ) &&
|
||||
(data = get_win_data( hwnd )))
|
||||
{
|
||||
/* embedded windows won't receive synthetic ConfigureNotify and are positioned by the WM */
|
||||
BOOL has_serial = !data->embedded && (data->wm_state_serial || data->configure_serial);
|
||||
release_win_data( data );
|
||||
if (has_serial) continue;
|
||||
}
|
||||
|
||||
if (previous->type == ConfigureNotify && previous->xconfigure.window == configure.window) continue;
|
||||
TRACE( "generating ConfigureNotify for window %p/%lx, rect %s\n", hwnd, configure.window, wine_dbgstr_rect(&rect) );
|
||||
XPutBackEvent( configure.display, (XEvent *)&configure );
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL host_window_filter_event( XEvent *event, XEvent *previous )
|
||||
{
|
||||
struct host_window *win;
|
||||
RECT old_rect;
|
||||
|
||||
if (!(win = get_host_window( event->xany.window, FALSE ))) return FALSE;
|
||||
old_rect = win->rect;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
|
@ -190,6 +226,7 @@ static BOOL host_window_filter_event( XEvent *event )
|
|||
XReparentEvent *reparent = (XReparentEvent *)event;
|
||||
TRACE( "host window %p/%lx ReparentNotify, parent %lx\n", win, win->window, reparent->parent );
|
||||
host_window_set_parent( win, reparent->parent );
|
||||
host_window_send_configure_events( win, event->xany.display, event->xany.serial, previous );
|
||||
break;
|
||||
}
|
||||
case GravityNotify:
|
||||
|
@ -198,6 +235,7 @@ static BOOL host_window_filter_event( XEvent *event )
|
|||
OffsetRect( &win->rect, gravity->x - win->rect.left, gravity->y - win->rect.top );
|
||||
if (win->parent) win->rect = host_window_configure_child( win->parent, win->window, win->rect, FALSE );
|
||||
TRACE( "host window %p/%lx GravityNotify, rect %s\n", win, win->window, wine_dbgstr_rect(&win->rect) );
|
||||
host_window_send_configure_events( win, event->xany.display, event->xany.serial, previous );
|
||||
break;
|
||||
}
|
||||
case ConfigureNotify:
|
||||
|
@ -206,44 +244,11 @@ static BOOL host_window_filter_event( XEvent *event )
|
|||
SetRect( &win->rect, configure->x, configure->y, configure->x + configure->width, configure->y + configure->height );
|
||||
if (win->parent) win->rect = host_window_configure_child( win->parent, win->window, win->rect, configure->send_event );
|
||||
TRACE( "host window %p/%lx ConfigureNotify, rect %s\n", win, win->window, wine_dbgstr_rect(&win->rect) );
|
||||
host_window_send_configure_events( win, event->xany.display, event->xany.serial, previous );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (old_rect.left != win->rect.left || old_rect.top != win->rect.top)
|
||||
{
|
||||
XConfigureEvent configure = {.type = ConfigureNotify, .serial = event->xany.serial, .display = event->xany.display};
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < win->children_count; i++)
|
||||
{
|
||||
RECT rect = win->children[i].rect;
|
||||
struct x11drv_win_data *data;
|
||||
BOOL has_serial;
|
||||
HWND hwnd;
|
||||
|
||||
/* Only send a fake event if we're not expecting one from a state/config request.
|
||||
* We may know what was requested, but not what the WM will decide to reply, and our
|
||||
* fake event might trigger some undesired changes before the real ConfigureNotify.
|
||||
*/
|
||||
if (XFindContext( event->xany.display, event->xany.window, winContext, (char **)&hwnd )) continue;
|
||||
if (!(data = get_win_data( hwnd ))) continue;
|
||||
has_serial = data->wm_state_serial || data->configure_serial;
|
||||
release_win_data( data );
|
||||
if (has_serial) continue;
|
||||
|
||||
configure.event = win->children[i].window;
|
||||
configure.window = configure.event;
|
||||
configure.x = rect.left;
|
||||
configure.y = rect.top;
|
||||
configure.width = rect.right - rect.left;
|
||||
configure.height = rect.bottom - rect.top;
|
||||
configure.send_event = 0;
|
||||
|
||||
XPutBackEvent( configure.display, (XEvent *)&configure );
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -521,7 +526,7 @@ static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,X
|
|||
continue; /* filtered, ignore it */
|
||||
}
|
||||
|
||||
if (host_window_filter_event( &event )) continue;
|
||||
if (host_window_filter_event( &event, &prev_event )) continue;
|
||||
|
||||
get_event_data( &event );
|
||||
if (prev_event.type) action = merge_events( &prev_event, &event );
|
||||
|
@ -756,12 +761,20 @@ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event )
|
|||
}
|
||||
else if (protocol == x11drv_atom(WM_TAKE_FOCUS))
|
||||
{
|
||||
HWND last_focus = x11drv_thread_data()->last_focus;
|
||||
HWND last_focus = x11drv_thread_data()->last_focus, foreground = NtUserGetForegroundWindow();
|
||||
|
||||
TRACE( "got take focus msg for %p, enabled=%d, visible=%d (style %08x), focus=%p, active=%p, fg=%p, last=%p\n",
|
||||
hwnd, NtUserIsWindowEnabled(hwnd), NtUserIsWindowVisible(hwnd),
|
||||
(int)NtUserGetWindowLongW(hwnd, GWL_STYLE),
|
||||
get_focus(), get_active_window(), NtUserGetForegroundWindow(), last_focus );
|
||||
if (window_has_pending_wm_state( hwnd, -1 ))
|
||||
{
|
||||
WARN( "Ignoring window %p/%lx WM_TAKE_FOCUS serial %lu, event_time %ld, foreground %p during WM_STATE change\n",
|
||||
hwnd, event->window, event->serial, event_time, foreground );
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE( "window %p/%lx WM_TAKE_FOCUS serial %lu, event_time %ld, foreground %p\n", hwnd, event->window,
|
||||
event->serial, event_time, foreground );
|
||||
TRACE( " enabled %u, visible %u, style %#x, focus %p, active %p, last %p\n",
|
||||
NtUserIsWindowEnabled( hwnd ), NtUserIsWindowVisible( hwnd ), (int)NtUserGetWindowLongW( hwnd, GWL_STYLE ),
|
||||
get_focus(), get_active_window(), last_focus );
|
||||
|
||||
if (can_activate_window(hwnd))
|
||||
{
|
||||
|
@ -778,7 +791,7 @@ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event )
|
|||
}
|
||||
else if (hwnd == NtUserGetDesktopWindow())
|
||||
{
|
||||
hwnd = NtUserGetForegroundWindow();
|
||||
hwnd = foreground;
|
||||
if (!hwnd) hwnd = last_focus;
|
||||
if (!hwnd) hwnd = NtUserGetDesktopWindow();
|
||||
set_focus( event->display, hwnd, event_time );
|
||||
|
@ -840,14 +853,23 @@ BOOL is_current_process_focused(void)
|
|||
*/
|
||||
static BOOL X11DRV_FocusIn( HWND hwnd, XEvent *xev )
|
||||
{
|
||||
HWND foreground = NtUserGetForegroundWindow();
|
||||
XFocusChangeEvent *event = &xev->xfocus;
|
||||
BOOL was_grabbed;
|
||||
|
||||
if (event->detail == NotifyPointer) return FALSE;
|
||||
if (!hwnd) return FALSE;
|
||||
|
||||
TRACE( "win %p xwin %lx detail=%s mode=%s\n", hwnd, event->window, focus_details[event->detail], focus_modes[event->mode] );
|
||||
if (window_has_pending_wm_state( hwnd, -1 ))
|
||||
{
|
||||
WARN( "Ignoring window %p/%lx FocusIn serial %lu, detail %s, mode %s, foreground %p during WM_STATE change\n",
|
||||
hwnd, event->window, event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE( "window %p/%lx FocusIn serial %lu, detail %s, mode %s, foreground %p\n", hwnd, event->window,
|
||||
event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
|
||||
|
||||
if (event->detail == NotifyPointer) return FALSE;
|
||||
/* when focusing in the virtual desktop window, re-apply the cursor clipping rect */
|
||||
if (is_virtual_desktop() && hwnd == NtUserGetDesktopWindow()) reapply_cursor_clipping();
|
||||
if (hwnd == NtUserGetDesktopWindow()) return FALSE;
|
||||
|
@ -916,10 +938,9 @@ static void focus_out( Display *display , HWND hwnd )
|
|||
*/
|
||||
static BOOL X11DRV_FocusOut( HWND hwnd, XEvent *xev )
|
||||
{
|
||||
HWND foreground = NtUserGetForegroundWindow();
|
||||
XFocusChangeEvent *event = &xev->xfocus;
|
||||
|
||||
TRACE( "win %p xwin %lx detail=%s mode=%s\n", hwnd, event->window, focus_details[event->detail], focus_modes[event->mode] );
|
||||
|
||||
if (event->detail == NotifyPointer)
|
||||
{
|
||||
if (!hwnd && event->window == x11drv_thread_data()->clip_window)
|
||||
|
@ -933,6 +954,16 @@ static BOOL X11DRV_FocusOut( HWND hwnd, XEvent *xev )
|
|||
}
|
||||
if (!hwnd) return FALSE;
|
||||
|
||||
if (window_has_pending_wm_state( hwnd, NormalState )) /* ignore FocusOut only if the window is being shown */
|
||||
{
|
||||
WARN( "Ignoring window %p/%lx FocusOut serial %lu, detail %s, mode %s, foreground %p during WM_STATE change\n",
|
||||
hwnd, event->window, event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE( "window %p/%lx FocusOut serial %lu, detail %s, mode %s, foreground %p\n", hwnd, event->window,
|
||||
event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
|
||||
|
||||
/* in virtual desktop mode or when keyboard is grabbed, release any cursor grab but keep the clipping rect */
|
||||
keyboard_grabbed = event->mode == NotifyGrab || event->mode == NotifyWhileGrabbed;
|
||||
if (is_virtual_desktop() || keyboard_grabbed) ungrab_clipping_window();
|
||||
|
@ -1073,9 +1104,7 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
|
|||
struct x11drv_win_data *data;
|
||||
RECT rect;
|
||||
POINT pos = {event->x, event->y};
|
||||
UINT flags;
|
||||
int cx, cy, x, y;
|
||||
DWORD style;
|
||||
UINT config_cmd;
|
||||
|
||||
if (!hwnd) return FALSE;
|
||||
if (!(data = get_win_data( hwnd ))) return FALSE;
|
||||
|
@ -1094,80 +1123,17 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
|
|||
SetRect( &rect, pos.x, pos.y, pos.x + event->width, pos.y + event->height );
|
||||
window_configure_notify( data, event->serial, &rect );
|
||||
|
||||
if (!data->mapped || data->iconic) goto done;
|
||||
if (!data->whole_window || !data->managed) goto done;
|
||||
if (data->configure_serial && (long)(data->configure_serial - event->serial) > 0)
|
||||
{
|
||||
TRACE( "win %p/%lx event %d,%d,%dx%d ignoring old serial %lu/%lu\n",
|
||||
hwnd, data->whole_window, event->x, event->y, event->width, event->height,
|
||||
event->serial, data->configure_serial );
|
||||
goto done;
|
||||
}
|
||||
|
||||
rect = window_rect_from_visible( &data->rects, rect );
|
||||
|
||||
TRACE( "win %p/%lx new X rect %d,%d,%dx%d (event %d,%d,%dx%d)\n",
|
||||
hwnd, data->whole_window, (int)rect.left, (int)rect.top,
|
||||
(int)(rect.right-rect.left), (int)(rect.bottom-rect.top),
|
||||
event->x, event->y, event->width, event->height );
|
||||
|
||||
/* Compare what has changed */
|
||||
|
||||
x = rect.left;
|
||||
y = rect.top;
|
||||
cx = rect.right - rect.left;
|
||||
cy = rect.bottom - rect.top;
|
||||
flags = SWP_NOACTIVATE | SWP_NOZORDER;
|
||||
|
||||
if (!data->whole_window) flags |= SWP_NOCOPYBITS; /* we can't copy bits of foreign windows */
|
||||
|
||||
if (data->rects.window.left == x && data->rects.window.top == y) flags |= SWP_NOMOVE;
|
||||
else
|
||||
TRACE( "%p moving from (%d,%d) to (%d,%d)\n",
|
||||
hwnd, (int)data->rects.window.left, (int)data->rects.window.top, x, y );
|
||||
|
||||
if ((data->rects.window.right - data->rects.window.left == cx &&
|
||||
data->rects.window.bottom - data->rects.window.top == cy) ||
|
||||
IsRectEmpty( &data->rects.window ))
|
||||
flags |= SWP_NOSIZE;
|
||||
else
|
||||
TRACE( "%p resizing from (%dx%d) to (%dx%d)\n",
|
||||
hwnd, (int)(data->rects.window.right - data->rects.window.left),
|
||||
(int)(data->rects.window.bottom - data->rects.window.top), cx, cy );
|
||||
|
||||
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
||||
if ((style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen)
|
||||
{
|
||||
data->net_wm_state = get_window_net_wm_state( event->display, data->whole_window );
|
||||
if ((data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)))
|
||||
{
|
||||
if (!(style & WS_MAXIMIZE))
|
||||
{
|
||||
TRACE( "win %p/%lx is maximized\n", data->hwnd, data->whole_window );
|
||||
release_win_data( data );
|
||||
send_message( data->hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (style & WS_MAXIMIZE)
|
||||
{
|
||||
TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window );
|
||||
release_win_data( data );
|
||||
send_message( data->hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & (SWP_NOSIZE | SWP_NOMOVE)) != (SWP_NOSIZE | SWP_NOMOVE))
|
||||
{
|
||||
release_win_data( data );
|
||||
NtUserSetRawWindowPos( hwnd, rect, flags, FALSE );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
done:
|
||||
config_cmd = window_update_client_config( data );
|
||||
rect = window_rect_from_visible( &data->rects, data->current_state.rect );
|
||||
release_win_data( data );
|
||||
return FALSE;
|
||||
|
||||
if (config_cmd)
|
||||
{
|
||||
if (LOWORD(config_cmd) == SC_MOVE) NtUserSetRawWindowPos( hwnd, rect, HIWORD(config_cmd), FALSE );
|
||||
else send_message( hwnd, WM_SYSCOMMAND, LOWORD(config_cmd), 0 );
|
||||
}
|
||||
|
||||
return !!config_cmd;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1230,7 +1196,7 @@ static int get_window_xembed_info( Display *display, Window window )
|
|||
static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL update_window )
|
||||
{
|
||||
struct x11drv_win_data *data;
|
||||
UINT style, value = 0;
|
||||
UINT value = 0, state_cmd = 0;
|
||||
|
||||
if (!(data = get_win_data( hwnd ))) return;
|
||||
if (event->state == PropertyNewValue) value = get_window_wm_state( event->display, event->window );
|
||||
|
@ -1251,61 +1217,20 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat
|
|||
TRACE( "%p/%lx: new WM_STATE %d from %d\n",
|
||||
data->hwnd, data->whole_window, new_state, old_state );
|
||||
data->wm_state = new_state;
|
||||
/* ignore the initial state transition out of withdrawn state */
|
||||
/* metacity does Withdrawn->NormalState->IconicState when mapping an iconic window */
|
||||
if (!old_state) goto done;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!update_window || !data->managed || !data->mapped) goto done;
|
||||
if (update_window) state_cmd = window_update_client_state( data );
|
||||
|
||||
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
||||
|
||||
if (data->iconic && data->wm_state == NormalState) /* restore window */
|
||||
{
|
||||
data->iconic = FALSE;
|
||||
data->net_wm_state = get_window_net_wm_state( event->display, data->whole_window );
|
||||
if ((style & WS_CAPTION) == WS_CAPTION && (data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)))
|
||||
{
|
||||
if ((style & WS_MAXIMIZEBOX) && !(style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "restoring to max %p/%lx\n", data->hwnd, data->whole_window );
|
||||
release_win_data( data );
|
||||
send_message( hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
|
||||
return;
|
||||
}
|
||||
TRACE( "not restoring to max win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
|
||||
{
|
||||
TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
release_win_data( data );
|
||||
if ((style & (WS_MINIMIZE | WS_VISIBLE)) == (WS_MINIMIZE | WS_VISIBLE))
|
||||
NtUserSetActiveWindow( hwnd );
|
||||
send_message( hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 );
|
||||
return;
|
||||
}
|
||||
TRACE( "not restoring win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
|
||||
}
|
||||
}
|
||||
else if (!data->iconic && data->wm_state == IconicState)
|
||||
{
|
||||
data->iconic = TRUE;
|
||||
if ((style & WS_MINIMIZEBOX) && !(style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
release_win_data( data );
|
||||
send_message( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0 );
|
||||
return;
|
||||
}
|
||||
TRACE( "not minimizing win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
|
||||
}
|
||||
done:
|
||||
release_win_data( data );
|
||||
|
||||
if (state_cmd)
|
||||
{
|
||||
if (LOWORD(state_cmd) == SC_RESTORE && HIWORD(state_cmd)) NtUserSetActiveWindow( hwnd );
|
||||
send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_xembed_info_notify( HWND hwnd, XPropertyEvent *event )
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "winuser.h"
|
||||
#include "winreg.h"
|
||||
#include "winnls.h"
|
||||
#include "ime.h"
|
||||
#include "kbd.h"
|
||||
#include "wine/server.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
|
|
@ -1160,7 +1160,7 @@ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data )
|
|||
long monitors[4];
|
||||
XEvent xev;
|
||||
|
||||
if (!(data->net_wm_state & (1 << NET_WM_STATE_FULLSCREEN)) || is_virtual_desktop()
|
||||
if (!(data->pending_state.net_wm_state & (1 << NET_WM_STATE_FULLSCREEN)) || is_virtual_desktop()
|
||||
|| NtUserGetWindowLongW( data->hwnd, GWL_STYLE ) & WS_MINIMIZE)
|
||||
return;
|
||||
|
||||
|
@ -1211,10 +1211,12 @@ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data )
|
|||
|
||||
static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_state )
|
||||
{
|
||||
UINT i, count;
|
||||
UINT i, count, old_state = data->pending_state.net_wm_state;
|
||||
|
||||
if (!data->whole_window) return; /* no window, nothing to update */
|
||||
if (old_state == new_state) return; /* states are the same, nothing to update */
|
||||
|
||||
if (data->pending_state.wm_state == IconicState) return; /* window is iconic, don't update its state now */
|
||||
if (!data->mapped) /* set the _NET_WM_STATE atom directly */
|
||||
{
|
||||
Atom atoms[NB_NET_WM_STATES + 1];
|
||||
|
@ -1250,6 +1252,8 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat
|
|||
|
||||
for (i = 0; i < NB_NET_WM_STATES; i++)
|
||||
{
|
||||
if (!((old_state ^ new_state) & (1 << i))) continue;
|
||||
|
||||
xev.xclient.data.l[0] = (new_state & (1 << i)) ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
|
||||
xev.xclient.data.l[1] = X11DRV_Atoms[net_wm_state_atoms[i] - FIRST_XATOM];
|
||||
xev.xclient.data.l[2] = ((net_wm_state_atoms[i] == XATOM__NET_WM_STATE_MAXIMIZED_VERT) ?
|
||||
|
@ -1268,9 +1272,11 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat
|
|||
static void window_set_config( struct x11drv_win_data *data, const RECT *new_rect, BOOL above )
|
||||
{
|
||||
UINT style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ), mask = 0;
|
||||
const RECT *old_rect = &data->pending_state.rect;
|
||||
XWindowChanges changes;
|
||||
|
||||
if (!data->whole_window) return; /* no window, nothing to update */
|
||||
if (EqualRect( old_rect, new_rect )) return; /* rects are the same, nothing to update */
|
||||
|
||||
/* resizing a managed maximized window is not allowed */
|
||||
if (!(style & WS_MAXIMIZE) || !data->managed)
|
||||
|
@ -1322,7 +1328,7 @@ static void update_net_wm_states( struct x11drv_win_data *data )
|
|||
|
||||
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
||||
if (style & WS_MINIMIZE)
|
||||
new_state |= data->net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED));
|
||||
new_state |= data->pending_state.net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED));
|
||||
if (data->is_fullscreen)
|
||||
{
|
||||
if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION)
|
||||
|
@ -1346,7 +1352,6 @@ static void update_net_wm_states( struct x11drv_win_data *data )
|
|||
}
|
||||
|
||||
window_set_net_wm_state( data, new_state );
|
||||
data->net_wm_state = new_state;
|
||||
update_net_wm_fullscreen_monitors( data );
|
||||
}
|
||||
|
||||
|
@ -1412,8 +1417,8 @@ static void window_set_wm_state( struct x11drv_win_data *data, UINT new_state )
|
|||
|
||||
data->pending_state.wm_state = new_state;
|
||||
data->wm_state_serial = NextRequest( data->display );
|
||||
TRACE( "window %p/%lx, requesting WM_STATE %#x -> %#x serial %lu\n", data->hwnd, data->whole_window,
|
||||
old_state, new_state, data->wm_state_serial );
|
||||
TRACE( "window %p/%lx, requesting WM_STATE %#x -> %#x serial %lu, foreground %p\n", data->hwnd, data->whole_window,
|
||||
old_state, new_state, data->wm_state_serial, NtUserGetForegroundWindow() );
|
||||
|
||||
switch (MAKELONG(old_state, new_state))
|
||||
{
|
||||
|
@ -1484,11 +1489,87 @@ static void unmap_window( HWND hwnd )
|
|||
TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
window_set_wm_state( data, WithdrawnState );
|
||||
data->mapped = FALSE;
|
||||
data->net_wm_state = 0;
|
||||
}
|
||||
release_win_data( data );
|
||||
}
|
||||
|
||||
UINT window_update_client_state( struct x11drv_win_data *data )
|
||||
{
|
||||
UINT old_style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
||||
|
||||
if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */
|
||||
if (!data->mapped) return 0; /* ignore state changes on invisible windows */
|
||||
|
||||
if (data->iconic && data->current_state.wm_state == NormalState) /* restore window */
|
||||
{
|
||||
data->iconic = FALSE;
|
||||
if ((old_style & WS_CAPTION) == WS_CAPTION && (data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)))
|
||||
{
|
||||
if ((old_style & WS_MAXIMIZEBOX) && !(old_style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "restoring to max %p/%lx\n", data->hwnd, data->whole_window );
|
||||
return SC_MAXIMIZE;
|
||||
}
|
||||
}
|
||||
else if (old_style & (WS_MINIMIZE | WS_MAXIMIZE))
|
||||
{
|
||||
BOOL activate = (old_style & (WS_MINIMIZE | WS_VISIBLE)) == (WS_MINIMIZE | WS_VISIBLE);
|
||||
TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
return MAKELONG(SC_RESTORE, activate);
|
||||
}
|
||||
}
|
||||
else if (!data->iconic && data->current_state.wm_state == IconicState)
|
||||
{
|
||||
data->iconic = TRUE;
|
||||
if ((old_style & WS_MINIMIZEBOX) && !(old_style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
return SC_MINIMIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT window_update_client_config( struct x11drv_win_data *data )
|
||||
{
|
||||
UINT old_style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ), flags;
|
||||
RECT rect, old_rect = data->rects.window, new_rect;
|
||||
|
||||
if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */
|
||||
if (!data->mapped) return 0; /* ignore config changes on invisible windows */
|
||||
if (data->iconic) return 0; /* ignore config changes on minimized windows */
|
||||
|
||||
if (data->configure_serial) return 0; /* another config update is pending, wait for it to complete */
|
||||
|
||||
if ((old_style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen)
|
||||
{
|
||||
if ((data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && !(old_style & WS_MAXIMIZE))
|
||||
{
|
||||
TRACE( "window %p/%lx is maximized\n", data->hwnd, data->whole_window );
|
||||
return SC_MAXIMIZE;
|
||||
}
|
||||
if (!(data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && (old_style & WS_MAXIMIZE))
|
||||
{
|
||||
TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window );
|
||||
return SC_RESTORE;
|
||||
}
|
||||
}
|
||||
|
||||
flags = SWP_NOACTIVATE | SWP_NOZORDER;
|
||||
rect = new_rect = window_rect_from_visible( &data->rects, data->current_state.rect );
|
||||
if (new_rect.left == old_rect.left && new_rect.top == old_rect.top) flags |= SWP_NOMOVE;
|
||||
else OffsetRect( &rect, old_rect.left - new_rect.left, old_rect.top - new_rect.top );
|
||||
if (rect.right == old_rect.right && rect.bottom == old_rect.bottom) flags |= SWP_NOSIZE;
|
||||
else if (IsRectEmpty( &rect )) flags |= SWP_NOSIZE;
|
||||
|
||||
if ((flags & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE)) return 0;
|
||||
|
||||
TRACE( "window %p/%lx config changed %s -> %s, flags %#x\n", data->hwnd, data->whole_window,
|
||||
wine_dbgstr_rect(&old_rect), wine_dbgstr_rect(&new_rect), flags );
|
||||
return MAKELONG(SC_MOVE, flags);
|
||||
}
|
||||
|
||||
void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value )
|
||||
{
|
||||
UINT *pending = &data->pending_state.wm_state, *current = &data->current_state.wm_state;
|
||||
|
@ -1587,6 +1668,19 @@ void window_configure_notify( struct x11drv_win_data *data, unsigned long serial
|
|||
*expect_serial = 0;
|
||||
}
|
||||
|
||||
BOOL window_has_pending_wm_state( HWND hwnd, UINT state )
|
||||
{
|
||||
struct x11drv_win_data *data;
|
||||
BOOL pending;
|
||||
|
||||
if (!(data = get_win_data( hwnd ))) return FALSE;
|
||||
if (state != -1 && data->pending_state.wm_state != state) pending = FALSE;
|
||||
else pending = !!data->wm_state_serial;
|
||||
release_win_data( data );
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* make_window_embedded
|
||||
*/
|
||||
|
@ -1594,7 +1688,6 @@ void make_window_embedded( struct x11drv_win_data *data )
|
|||
{
|
||||
/* the window cannot be mapped before being embedded */
|
||||
window_set_wm_state( data, WithdrawnState );
|
||||
data->net_wm_state = 0;
|
||||
data->embedded = TRUE;
|
||||
data->managed = TRUE;
|
||||
sync_window_style( data );
|
||||
|
@ -2006,7 +2099,6 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des
|
|||
data->whole_window = data->client_window = 0;
|
||||
data->whole_colormap = 0;
|
||||
data->wm_state = WithdrawnState;
|
||||
data->net_wm_state = 0;
|
||||
data->mapped = FALSE;
|
||||
|
||||
memset( &data->pending_state, 0, sizeof(data->pending_state) );
|
||||
|
@ -2314,7 +2406,12 @@ void set_window_parent( struct x11drv_win_data *data, Window parent )
|
|||
if (!data->whole_window) return; /* only keep track of parent if we have a toplevel */
|
||||
TRACE( "window %p/%lx, parent %lx\n", data->hwnd, data->whole_window, parent );
|
||||
host_window_reparent( &data->parent, parent, data->whole_window );
|
||||
if (data->parent) host_window_configure_child( data->parent, data->whole_window, data->rects.visible, TRUE );
|
||||
if (data->parent)
|
||||
{
|
||||
RECT rect = data->rects.visible;
|
||||
OffsetRect( &rect, -rect.left, -rect.top );
|
||||
host_window_configure_child( data->parent, data->whole_window, rect, TRUE );
|
||||
}
|
||||
data->parent_invalid = 0;
|
||||
}
|
||||
|
||||
|
@ -2468,6 +2565,7 @@ BOOL X11DRV_SystrayDockInsert( HWND hwnd, UINT cx, UINT cy, void *icon )
|
|||
window = data->whole_window;
|
||||
release_win_data( data );
|
||||
|
||||
NtUserSetWindowPos( hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOZORDER );
|
||||
NtUserShowWindow( hwnd, SW_SHOWNA );
|
||||
|
||||
TRACE_(systray)( "icon window %p/%lx\n", hwnd, window );
|
||||
|
|
|
@ -236,7 +236,7 @@ typedef struct tagWTI_DEVICES_INFO
|
|||
#define CSR_TYPE_OTHER 0x000
|
||||
|
||||
typedef struct tagWTPACKET {
|
||||
HCTX pkContext;
|
||||
UINT pkContext;
|
||||
UINT pkStatus;
|
||||
LONG pkTime;
|
||||
WTPKT pkChanged;
|
||||
|
|
|
@ -634,7 +634,6 @@ struct x11drv_win_data
|
|||
UINT is_fullscreen : 1; /* is the window visible rect fullscreen */
|
||||
UINT parent_invalid : 1; /* is the parent host window possibly invalid */
|
||||
int wm_state; /* current value of the WM_STATE property */
|
||||
DWORD net_wm_state; /* bit mask of active x11drv_net_wm_state values */
|
||||
Window embedder; /* window id of embedder */
|
||||
Pixmap icon_pixmap;
|
||||
Pixmap icon_mask;
|
||||
|
@ -659,9 +658,13 @@ extern void set_gl_drawable_parent( HWND hwnd, HWND parent );
|
|||
extern void destroy_gl_drawable( HWND hwnd );
|
||||
extern void destroy_vk_surface( HWND hwnd );
|
||||
|
||||
extern BOOL window_has_pending_wm_state( HWND hwnd, UINT state );
|
||||
extern void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value );
|
||||
extern void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value );
|
||||
extern void window_configure_notify( struct x11drv_win_data *data, unsigned long serial, const RECT *rect );
|
||||
extern UINT window_update_client_state( struct x11drv_win_data *data );
|
||||
extern UINT window_update_client_config( struct x11drv_win_data *data );
|
||||
|
||||
extern void wait_for_withdrawn_state( HWND hwnd, BOOL set );
|
||||
extern Window init_clip_window(void);
|
||||
extern void update_user_time( Time time );
|
||||
|
|
|
@ -811,12 +811,6 @@ C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count );
|
|||
|
||||
#ifdef _WIN64
|
||||
|
||||
static NTSTATUS x11drv_wow64_tablet_get_packet( void *arg )
|
||||
{
|
||||
FIXME( "%p\n", arg );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static NTSTATUS x11drv_wow64_tablet_info( void *arg )
|
||||
{
|
||||
struct
|
||||
|
@ -837,7 +831,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
|
|||
{
|
||||
x11drv_init,
|
||||
x11drv_tablet_attach_queue,
|
||||
x11drv_wow64_tablet_get_packet,
|
||||
x11drv_tablet_get_packet,
|
||||
x11drv_wow64_tablet_info,
|
||||
x11drv_tablet_load_info,
|
||||
};
|
||||
|
|
|
@ -3886,26 +3886,23 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
|
|||
}
|
||||
else if (dwInfoLevel & HTTP_QUERY_FLAG_SYSTEMTIME && lpBuffer)
|
||||
{
|
||||
time_t tmpTime;
|
||||
struct tm tmpTM;
|
||||
SYSTEMTIME *STHook;
|
||||
SYSTEMTIME st;
|
||||
|
||||
tmpTime = ConvertTimeString(lphttpHdr->lpszValue);
|
||||
|
||||
tmpTM = *gmtime(&tmpTime);
|
||||
STHook = (SYSTEMTIME *)lpBuffer;
|
||||
STHook->wDay = tmpTM.tm_mday;
|
||||
STHook->wHour = tmpTM.tm_hour;
|
||||
STHook->wMilliseconds = 0;
|
||||
STHook->wMinute = tmpTM.tm_min;
|
||||
STHook->wDayOfWeek = tmpTM.tm_wday;
|
||||
STHook->wMonth = tmpTM.tm_mon + 1;
|
||||
STHook->wSecond = tmpTM.tm_sec;
|
||||
STHook->wYear = 1900+tmpTM.tm_year;
|
||||
|
||||
TRACE(" returning time: %04d/%02d/%02d - %d - %02d:%02d:%02d.%02d\n",
|
||||
STHook->wYear, STHook->wMonth, STHook->wDay, STHook->wDayOfWeek,
|
||||
STHook->wHour, STHook->wMinute, STHook->wSecond, STHook->wMilliseconds);
|
||||
if (!InternetTimeToSystemTimeW(lphttpHdr->lpszValue, &st, 0))
|
||||
{
|
||||
LeaveCriticalSection( &request->headers_section );
|
||||
return ERROR_HTTP_INVALID_HEADER;
|
||||
}
|
||||
if (*lpdwBufferLength < sizeof(st))
|
||||
{
|
||||
*lpdwBufferLength = sizeof(st);
|
||||
LeaveCriticalSection( &request->headers_section );
|
||||
return ERROR_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
TRACE(" returning time: %04u/%02u/%02u - %u - %02u:%02u:%02u.%02u\n",
|
||||
st.wYear, st.wMonth, st.wDay, st.wDayOfWeek, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
|
||||
memcpy(lpBuffer, &st, sizeof(st));
|
||||
*lpdwBufferLength = sizeof(st);
|
||||
}
|
||||
else if (lphttpHdr->lpszValue)
|
||||
{
|
||||
|
@ -4521,7 +4518,7 @@ static BOOL HTTP_ParseDateAsAsctime(LPCWSTR value, FILETIME *ft)
|
|||
/* asctime() doesn't report a timezone, but some web servers do, so accept
|
||||
* with or without GMT.
|
||||
*/
|
||||
if (*ptr && wcscmp(ptr, L"GMT"))
|
||||
if (*ptr && (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC")))
|
||||
{
|
||||
ERR("unexpected timezone %s\n", debugstr_w(ptr));
|
||||
return FALSE;
|
||||
|
@ -4598,7 +4595,7 @@ static BOOL HTTP_ParseRfc1123Date(LPCWSTR value, FILETIME *ft)
|
|||
while (iswspace(*ptr))
|
||||
ptr++;
|
||||
|
||||
if (wcscmp(ptr, L"GMT"))
|
||||
if (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC"))
|
||||
{
|
||||
ERR("unexpected time zone %s\n", debugstr_w(ptr));
|
||||
return FALSE;
|
||||
|
@ -4715,7 +4712,7 @@ static BOOL HTTP_ParseRfc850Date(LPCWSTR value, FILETIME *ft)
|
|||
while (iswspace(*ptr))
|
||||
ptr++;
|
||||
|
||||
if (wcscmp(ptr, L"GMT"))
|
||||
if (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC"))
|
||||
{
|
||||
ERR("unexpected time zone %s\n", debugstr_w(ptr));
|
||||
return FALSE;
|
||||
|
|
|
@ -2412,6 +2412,7 @@ static const char okmsg2[] =
|
|||
"Content-Length: 0\r\n"
|
||||
"Set-Cookie: one\r\n"
|
||||
"Set-Cookie: two\r\n"
|
||||
"Last-Modified: Mon, 01 Dec 2008 13:44:34 UTC\r\n"
|
||||
"\r\n";
|
||||
|
||||
static DWORD64 content_length;
|
||||
|
@ -4566,9 +4567,11 @@ static void test_head_request(int port)
|
|||
|
||||
static void test_HttpQueryInfo(int port)
|
||||
{
|
||||
static const SYSTEMTIME expect = {2008, 12, 1, 1, 13, 44, 34};
|
||||
test_request_t req;
|
||||
DWORD size, index, error;
|
||||
char buffer[1024];
|
||||
SYSTEMTIME st;
|
||||
BOOL ret;
|
||||
|
||||
open_simple_request(&req, "localhost", port, NULL, "/testD");
|
||||
|
@ -4589,9 +4592,27 @@ static void test_HttpQueryInfo(int port)
|
|||
ok(index == 1, "expected 1 got %lu\n", index);
|
||||
|
||||
index = 0;
|
||||
size = sizeof(buffer);
|
||||
ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, buffer, &size, &index);
|
||||
size = 0;
|
||||
ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index);
|
||||
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError());
|
||||
ok(size == sizeof(st), "got %lu\n", size);
|
||||
|
||||
index = 0;
|
||||
size = sizeof(st) + 1;
|
||||
memset(&st, 0, sizeof(st));
|
||||
ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index);
|
||||
ok(ret, "HttpQueryInfo failed %lu\n", GetLastError());
|
||||
ok(!memcmp(&st, &expect, sizeof(st)), "wrong time\n");
|
||||
ok(size == sizeof(st), "got %lu\n", size);
|
||||
ok(index == 1, "expected 1 got %lu\n", index);
|
||||
|
||||
index = 0;
|
||||
size = sizeof(st);
|
||||
memset(&st, 0, sizeof(st));
|
||||
ret = HttpQueryInfoA(req.request, HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index);
|
||||
ok(ret, "HttpQueryInfo failed %lu\n", GetLastError());
|
||||
ok(!memcmp(&st, &expect, sizeof(st)), "wrong time\n");
|
||||
ok(size == sizeof(st), "got %lu\n", size);
|
||||
ok(index == 1, "expected 1 got %lu\n", index);
|
||||
|
||||
index = 0;
|
||||
|
|
|
@ -1116,9 +1116,11 @@ static void test_InternetTimeToSystemTime(void)
|
|||
test_data[] =
|
||||
{
|
||||
{ "Fri, 07 Jan 2005 12:06:35 GMT", &expect1, TRUE },
|
||||
{ "Fri, 07 Jan 2005 12:06:35 UTC", &expect1, TRUE },
|
||||
{ " fri, 7 jan 2005 12 06 35", &expect1, TRUE },
|
||||
{ "Fri, 07-01-2005 12:06:35", &expect1, TRUE },
|
||||
{ "5, 07-01-2005 12:06:35 GMT", &expect1, TRUE },
|
||||
{ "5, 07-01-2005 12:06:35 UTC", &expect1, TRUE },
|
||||
{ "5, 07-01-2005 12:06:35 GMT;", &expect1, TRUE },
|
||||
{ "5, 07-01-2005 12:06:35 GMT123", &expect1, TRUE },
|
||||
{ "2, 11 01 2022 11 13 05", &expect2, TRUE },
|
||||
|
@ -1126,6 +1128,9 @@ static void test_InternetTimeToSystemTime(void)
|
|||
{ "2, 11*01/2022 11+13=05", &expect2, TRUE },
|
||||
{ "2, 11-Jan-2022 11:13:05", &expect2, TRUE },
|
||||
{ "Fr", NULL, FALSE },
|
||||
{ "Fri Jan 7 12:06:35 2005", &expect1, TRUE, TRUE },
|
||||
{ "Fri Jan 7 12:06:35 2005 GMT", &expect1, TRUE, TRUE },
|
||||
{ "Fri Jan 7 12:06:35 2005 UTC", &expect1, TRUE, TRUE },
|
||||
};
|
||||
|
||||
ret = pInternetTimeToSystemTimeA(NULL, NULL, 0);
|
||||
|
|
|
@ -39,92 +39,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
|
||||
|
||||
#define TIME_STRING_LEN 30
|
||||
|
||||
time_t ConvertTimeString(LPCWSTR asctime)
|
||||
{
|
||||
WCHAR tmpChar[TIME_STRING_LEN];
|
||||
WCHAR *tmpChar2;
|
||||
struct tm t;
|
||||
int timelen = lstrlenW(asctime);
|
||||
|
||||
if(!timelen)
|
||||
return 0;
|
||||
|
||||
/* FIXME: the atoiWs below rely on that tmpChar is \0 padded */
|
||||
memset( tmpChar, 0, sizeof(tmpChar) );
|
||||
lstrcpynW(tmpChar, asctime, TIME_STRING_LEN);
|
||||
|
||||
/* Assert that the string is the expected length */
|
||||
if (lstrlenW(asctime) >= TIME_STRING_LEN) FIXME("\n");
|
||||
|
||||
/* Convert a time such as 'Mon, 15 Nov 1999 16:09:35 GMT' into a SYSTEMTIME structure
|
||||
* We assume the time is in this format
|
||||
* and divide it into easy to swallow chunks
|
||||
*/
|
||||
tmpChar[3]='\0';
|
||||
tmpChar[7]='\0';
|
||||
tmpChar[11]='\0';
|
||||
tmpChar[16]='\0';
|
||||
tmpChar[19]='\0';
|
||||
tmpChar[22]='\0';
|
||||
tmpChar[25]='\0';
|
||||
|
||||
memset( &t, 0, sizeof(t) );
|
||||
t.tm_year = wcstol(tmpChar+12, NULL, 10) - 1900;
|
||||
t.tm_mday = wcstol(tmpChar+5, NULL, 10);
|
||||
t.tm_hour = wcstol(tmpChar+17, NULL, 10);
|
||||
t.tm_min = wcstol(tmpChar+20, NULL, 10);
|
||||
t.tm_sec = wcstol(tmpChar+23, NULL, 10);
|
||||
|
||||
/* and month */
|
||||
tmpChar2 = tmpChar + 8;
|
||||
switch(tmpChar2[2])
|
||||
{
|
||||
case 'n':
|
||||
if(tmpChar2[1]=='a')
|
||||
t.tm_mon = 0;
|
||||
else
|
||||
t.tm_mon = 5;
|
||||
break;
|
||||
case 'b':
|
||||
t.tm_mon = 1;
|
||||
break;
|
||||
case 'r':
|
||||
if(tmpChar2[1]=='a')
|
||||
t.tm_mon = 2;
|
||||
else
|
||||
t.tm_mon = 3;
|
||||
break;
|
||||
case 'y':
|
||||
t.tm_mon = 4;
|
||||
break;
|
||||
case 'l':
|
||||
t.tm_mon = 6;
|
||||
break;
|
||||
case 'g':
|
||||
t.tm_mon = 7;
|
||||
break;
|
||||
case 'p':
|
||||
t.tm_mon = 8;
|
||||
break;
|
||||
case 't':
|
||||
t.tm_mon = 9;
|
||||
break;
|
||||
case 'v':
|
||||
t.tm_mon = 10;
|
||||
break;
|
||||
case 'c':
|
||||
t.tm_mon = 11;
|
||||
break;
|
||||
default:
|
||||
FIXME("\n");
|
||||
}
|
||||
|
||||
return mktime(&t);
|
||||
}
|
||||
|
||||
|
||||
BOOL GetAddress(const WCHAR *name, INTERNET_PORT port, struct sockaddr *psa, int *sa_len, char *addr_str)
|
||||
{
|
||||
ADDRINFOW *res, hints;
|
||||
|
|
|
@ -102,7 +102,7 @@ static const char* DUMPBITS(int x)
|
|||
|
||||
static inline void DUMPPACKET(WTPACKET packet)
|
||||
{
|
||||
TRACE("pkContext: %p pkStatus: 0x%x pkTime : 0x%lx pkChanged: 0x%lx pkSerialNumber: 0x%x pkCursor : %i pkButtons: %lx pkX: %li pkY: %li pkZ: %li pkNormalPressure: %i pkTangentPressure: %i pkOrientation: (%i,%i,%i) pkRotation: (%i,%i,%i)\n",
|
||||
TRACE("pkContext: 0x%x pkStatus: 0x%x pkTime : 0x%lx pkChanged: 0x%lx pkSerialNumber: 0x%x pkCursor : %i pkButtons: %lx pkX: %li pkY: %li pkZ: %li pkNormalPressure: %i pkTangentPressure: %i pkOrientation: (%i,%i,%i) pkRotation: (%i,%i,%i)\n",
|
||||
packet.pkContext, packet.pkStatus, packet.pkTime, packet.pkChanged, packet.pkSerialNumber,
|
||||
packet.pkCursor, packet.pkButtons, packet.pkX, packet.pkY, packet.pkZ,
|
||||
packet.pkNormalPressure, packet.pkTangentPressure,
|
||||
|
@ -205,7 +205,7 @@ LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd)
|
|||
|
||||
tgt = ptr->PacketsQueued;
|
||||
|
||||
packet->pkContext = ptr->handle;
|
||||
packet->pkContext = HandleToULong(ptr->handle);
|
||||
|
||||
/* translate packet data to the context */
|
||||
packet->pkChanged = packet->pkChanged & ptr->context.lcPktData;
|
||||
|
@ -296,12 +296,15 @@ static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt,
|
|||
LPWTPACKET wtp)
|
||||
{
|
||||
LPBYTE ptr;
|
||||
HCTX ctx;
|
||||
|
||||
ptr = lpPkt;
|
||||
TRACE("Packet Bits %s\n",DUMPBITS(context->context.lcPktData));
|
||||
|
||||
ctx = ULongToHandle(wtp->pkContext);
|
||||
|
||||
if (context->context.lcPktData & PK_CONTEXT)
|
||||
ptr+=CopyTabletData(ptr,&wtp->pkContext,sizeof(HCTX));
|
||||
ptr+=CopyTabletData(ptr,&ctx,sizeof(HCTX));
|
||||
if (context->context.lcPktData & PK_STATUS)
|
||||
ptr+=CopyTabletData(ptr,&wtp->pkStatus,sizeof(UINT));
|
||||
if (context->context.lcPktData & PK_TIME)
|
||||
|
|
|
@ -117,7 +117,7 @@ typedef struct tagWTI_EXTENSIONS_INFO
|
|||
} WTI_EXTENSIONS_INFO, *LPWTI_EXTENSIONS_INFO;
|
||||
|
||||
typedef struct tagWTPACKET {
|
||||
HCTX pkContext;
|
||||
UINT pkContext;
|
||||
UINT pkStatus;
|
||||
LONG pkTime;
|
||||
WTPKT pkChanged;
|
||||
|
|
|
@ -1449,6 +1449,22 @@ NTSTATUS WINAPI wow64_NtSetIoCompletion( UINT *args )
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtSetIoCompletionEx
|
||||
*/
|
||||
NTSTATUS WINAPI wow64_NtSetIoCompletionEx( UINT *args )
|
||||
{
|
||||
HANDLE completion_handle = get_handle( &args );
|
||||
HANDLE completion_reserve_handle = get_handle( &args );
|
||||
ULONG_PTR key = get_ulong( &args );
|
||||
ULONG_PTR value = get_ulong( &args );
|
||||
NTSTATUS status = get_ulong( &args );
|
||||
SIZE_T count = get_ulong( &args );
|
||||
|
||||
return NtSetIoCompletionEx( completion_handle, completion_reserve_handle, key, value, status, count );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtSetTimer
|
||||
*/
|
||||
|
|
|
@ -343,4 +343,19 @@ typedef struct tagKbdLayer
|
|||
#error "Unsupported KBD_TYPE"
|
||||
#endif
|
||||
|
||||
#define VK_DBE_ALPHANUMERIC 0x0f0
|
||||
#define VK_DBE_KATAKANA 0x0f1
|
||||
#define VK_DBE_HIRAGANA 0x0f2
|
||||
#define VK_DBE_SBCSCHAR 0x0f3
|
||||
#define VK_DBE_DBCSCHAR 0x0f4
|
||||
#define VK_DBE_ROMAN 0x0f5
|
||||
#define VK_DBE_NOROMAN 0x0f6
|
||||
#define VK_DBE_ENTERWORDREGISTERMODE 0x0f7
|
||||
#define VK_DBE_ENTERIMECONFIGMODE 0x0f8
|
||||
#define VK_DBE_FLUSHSTRING 0x0f9
|
||||
#define VK_DBE_CODEINPUT 0x0fa
|
||||
#define VK_DBE_NOCODEINPUT 0x0fb
|
||||
#define VK_DBE_DETERMINESTRING 0x0fc
|
||||
#define VK_DBE_ENTERDLGCONVERSIONMODE 0x0fd
|
||||
|
||||
#endif /* __WINE_KBD_H */
|
||||
|
|
|
@ -430,6 +430,36 @@ library UIAutomationClient {
|
|||
const long UIA_AppBarControlTypeId = 50040;
|
||||
}
|
||||
|
||||
[dllname("<no entry points>")]
|
||||
module UIA_AnnotationTypes
|
||||
{
|
||||
const long AnnotationType_Unknown = 60000;
|
||||
const long AnnotationType_SpellingError = 60001;
|
||||
const long AnnotationType_GrammarError = 60002;
|
||||
const long AnnotationType_Comment = 60003;
|
||||
const long AnnotationType_FormulaError = 60004;
|
||||
const long AnnotationType_TrackChanges = 60005;
|
||||
const long AnnotationType_Header = 60006;
|
||||
const long AnnotationType_Footer = 60007;
|
||||
const long AnnotationType_Highlighted = 60008;
|
||||
const long AnnotationType_Endnote = 60009;
|
||||
const long AnnotationType_Footnote = 60010;
|
||||
const long AnnotationType_InsertionChange = 60011;
|
||||
const long AnnotationType_DeletionChange = 60012;
|
||||
const long AnnotationType_MoveChange = 60013;
|
||||
const long AnnotationType_FormatChange = 60014;
|
||||
const long AnnotationType_UnsyncedChange = 60015;
|
||||
const long AnnotationType_EditingLockedChange = 60016;
|
||||
const long AnnotationType_ExternalChange = 60017;
|
||||
const long AnnotationType_ConflictingChange = 60018;
|
||||
const long AnnotationType_Author = 60019;
|
||||
const long AnnotationType_AdvancedProofingIssue = 60020;
|
||||
const long AnnotationType_DataValidationError = 60021;
|
||||
const long AnnotationType_CircularReferenceError = 60022;
|
||||
const long AnnotationType_Mathematics = 60023;
|
||||
const long AnnotationType_Sensitive = 60024;
|
||||
}
|
||||
|
||||
[dllname("<no entry points>")]
|
||||
module UIA_LandmarkTypeIds
|
||||
{
|
||||
|
|
46
include/wine/server_protocol.h
generated
46
include/wine/server_protocol.h
generated
|
@ -260,7 +260,7 @@ typedef struct
|
|||
} rectangle_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
struct async_data
|
||||
{
|
||||
obj_handle_t handle;
|
||||
obj_handle_t event;
|
||||
|
@ -268,7 +268,7 @@ typedef struct
|
|||
client_ptr_t user;
|
||||
client_ptr_t apc;
|
||||
apc_param_t apc_context;
|
||||
} async_data_t;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -488,18 +488,18 @@ enum apc_type
|
|||
APC_DUP_HANDLE
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct user_apc
|
||||
{
|
||||
enum apc_type type;
|
||||
int __pad;
|
||||
client_ptr_t func;
|
||||
apc_param_t args[3];
|
||||
} user_apc_t;
|
||||
};
|
||||
|
||||
typedef union
|
||||
union apc_call
|
||||
{
|
||||
enum apc_type type;
|
||||
user_apc_t user;
|
||||
struct user_apc user;
|
||||
struct
|
||||
{
|
||||
enum apc_type type;
|
||||
|
@ -620,9 +620,9 @@ typedef union
|
|||
unsigned int attributes;
|
||||
unsigned int options;
|
||||
} dup_handle;
|
||||
} apc_call_t;
|
||||
};
|
||||
|
||||
typedef union
|
||||
union apc_result
|
||||
{
|
||||
enum apc_type type;
|
||||
struct
|
||||
|
@ -732,7 +732,7 @@ typedef union
|
|||
enum apc_type type;
|
||||
unsigned int status;
|
||||
} break_process;
|
||||
} apc_result_t;
|
||||
};
|
||||
|
||||
enum irp_type
|
||||
{
|
||||
|
@ -1343,7 +1343,7 @@ struct get_apc_result_request
|
|||
struct get_apc_result_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
apc_result_t result;
|
||||
union apc_result result;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1829,7 +1829,7 @@ struct flush_request
|
|||
{
|
||||
struct request_header __header;
|
||||
char __pad_12[4];
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
};
|
||||
struct flush_reply
|
||||
{
|
||||
|
@ -1857,7 +1857,7 @@ struct get_volume_info_request
|
|||
{
|
||||
struct request_header __header;
|
||||
obj_handle_t handle;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
unsigned int info_class;
|
||||
char __pad_60[4];
|
||||
};
|
||||
|
@ -1906,7 +1906,7 @@ struct recv_socket_request
|
|||
{
|
||||
struct request_header __header;
|
||||
int oob;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
int force_async;
|
||||
char __pad_60[4];
|
||||
};
|
||||
|
@ -1925,7 +1925,7 @@ struct send_socket_request
|
|||
{
|
||||
struct request_header __header;
|
||||
unsigned int flags;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
};
|
||||
struct send_socket_reply
|
||||
{
|
||||
|
@ -2016,7 +2016,7 @@ struct read_directory_changes_request
|
|||
unsigned int filter;
|
||||
int subtree;
|
||||
int want_data;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
};
|
||||
struct read_directory_changes_reply
|
||||
{
|
||||
|
@ -3152,7 +3152,7 @@ struct register_async_request
|
|||
{
|
||||
struct request_header __header;
|
||||
int type;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
int count;
|
||||
char __pad_60[4];
|
||||
};
|
||||
|
@ -3216,7 +3216,7 @@ struct read_request
|
|||
{
|
||||
struct request_header __header;
|
||||
char __pad_12[4];
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
file_pos_t pos;
|
||||
};
|
||||
struct read_reply
|
||||
|
@ -3233,7 +3233,7 @@ struct write_request
|
|||
{
|
||||
struct request_header __header;
|
||||
char __pad_12[4];
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
file_pos_t pos;
|
||||
/* VARARG(data,bytes); */
|
||||
};
|
||||
|
@ -3252,7 +3252,7 @@ struct ioctl_request
|
|||
{
|
||||
struct request_header __header;
|
||||
ioctl_code_t code;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
/* VARARG(in_data,bytes); */
|
||||
};
|
||||
struct ioctl_reply
|
||||
|
@ -5412,8 +5412,8 @@ struct add_completion_request
|
|||
apc_param_t ckey;
|
||||
apc_param_t cvalue;
|
||||
apc_param_t information;
|
||||
obj_handle_t reserve_handle;
|
||||
unsigned int status;
|
||||
char __pad_44[4];
|
||||
};
|
||||
struct add_completion_reply
|
||||
{
|
||||
|
@ -6758,10 +6758,6 @@ union generic_reply
|
|||
struct set_keyboard_repeat_reply set_keyboard_repeat_reply;
|
||||
};
|
||||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 847
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
#define SERVER_PROTOCOL_VERSION 848
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -4675,6 +4675,7 @@ NTSYSAPI NTSTATUS WINAPI NtSetInformationToken(HANDLE,TOKEN_INFORMATION_CLASS,P
|
|||
NTSYSAPI NTSTATUS WINAPI NtSetInformationVirtualMemory(HANDLE,VIRTUAL_MEMORY_INFORMATION_CLASS,ULONG_PTR,PMEMORY_RANGE_ENTRY,PVOID,ULONG);
|
||||
NTSYSAPI NTSTATUS WINAPI NtSetIntervalProfile(ULONG,KPROFILE_SOURCE);
|
||||
NTSYSAPI NTSTATUS WINAPI NtSetIoCompletion(HANDLE,ULONG_PTR,ULONG_PTR,NTSTATUS,SIZE_T);
|
||||
NTSYSAPI NTSTATUS WINAPI NtSetIoCompletionEx(HANDLE,HANDLE,ULONG_PTR,ULONG_PTR,NTSTATUS,SIZE_T);
|
||||
NTSYSAPI NTSTATUS WINAPI NtSetLdtEntries(ULONG,LDT_ENTRY,ULONG,LDT_ENTRY);
|
||||
NTSYSAPI NTSTATUS WINAPI NtSetLowEventPair(HANDLE);
|
||||
NTSYSAPI NTSTATUS WINAPI NtSetLowWaitHighEventPair(HANDLE);
|
||||
|
|
|
@ -40,8 +40,11 @@ summary of contributions.
|
|||
changes and bug fixes and got the synthesizer to actually work. Most
|
||||
importantly, he used it on stage to make music.
|
||||
|
||||
* S. Christian Collins did much testing of FluidSynth in regards to
|
||||
EMU10K1 compatibility and provided many synthesis fixes in that regard.
|
||||
* S. Christian Collins provided many tests and fixes on EMU10K1
|
||||
compatibility. He also supplied reference chorus and reverb settings for
|
||||
developing the default ones.
|
||||
|
||||
* Alberto Salvia Novella developed the default chorus and reverb settings.
|
||||
|
||||
* Stephane Letz from Grame wrote most of the MidiShare driver, all of
|
||||
the PortAudio driver, ported iiwusynth to MacOS X, and sent in many
|
||||
|
|
|
@ -57,6 +57,15 @@ enum fluid_mod_flags
|
|||
FLUID_MOD_SIN = 0x80, /**< Custom non-standard sinus mapping function */
|
||||
};
|
||||
|
||||
/**
|
||||
* Transform types for the SoundFont2 modulators as defined by SoundFont 2.04 section 8.3.
|
||||
*/
|
||||
enum fluid_mod_transforms
|
||||
{
|
||||
FLUID_MOD_TRANSFORM_LINEAR = 0, /**< Linear: directly add the computed value to summing node */
|
||||
FLUID_MOD_TRANSFORM_ABS = 2 /**< Abs: add the absolute value of the computed to summing node */
|
||||
};
|
||||
|
||||
/**
|
||||
* General controller (if #FLUID_MOD_GC in flags). This
|
||||
* corresponds to SoundFont 2.04 PDF section 8.2.1
|
||||
|
@ -83,6 +92,7 @@ FLUIDSYNTH_API void fluid_mod_set_source1(fluid_mod_t *mod, int src, int flags);
|
|||
FLUIDSYNTH_API void fluid_mod_set_source2(fluid_mod_t *mod, int src, int flags);
|
||||
FLUIDSYNTH_API void fluid_mod_set_dest(fluid_mod_t *mod, int dst);
|
||||
FLUIDSYNTH_API void fluid_mod_set_amount(fluid_mod_t *mod, double amount);
|
||||
FLUIDSYNTH_API void fluid_mod_set_transform(fluid_mod_t *mod, int type);
|
||||
|
||||
FLUIDSYNTH_API int fluid_mod_get_source1(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_flags1(const fluid_mod_t *mod);
|
||||
|
@ -90,6 +100,7 @@ FLUIDSYNTH_API int fluid_mod_get_source2(const fluid_mod_t *mod);
|
|||
FLUIDSYNTH_API int fluid_mod_get_flags2(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_dest(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API double fluid_mod_get_amount(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_transform(fluid_mod_t *mod);
|
||||
|
||||
FLUIDSYNTH_API int fluid_mod_test_identity(const fluid_mod_t *mod1, const fluid_mod_t *mod2);
|
||||
FLUIDSYNTH_API int fluid_mod_has_source(const fluid_mod_t *mod, int cc, int ctrl);
|
||||
|
|
|
@ -357,8 +357,13 @@ fluid_midi_file_read_mthd(fluid_midi_file *mf)
|
|||
}
|
||||
|
||||
mf->type = mthd[9];
|
||||
mf->ntracks = (unsigned) mthd[11];
|
||||
mf->ntracks += (unsigned int)(mthd[10]) << 16;
|
||||
if(!(mf->type == 0 || mf->type == 1))
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR,
|
||||
"Sorry, but MIDI Format %d is not supported by this player", mf->type);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
mf->ntracks = (signed)((unsigned)(mthd[10]) << 8 | (unsigned) mthd[11]);
|
||||
|
||||
if((signed char)mthd[12] < 0)
|
||||
{
|
||||
|
@ -1062,7 +1067,7 @@ fluid_midi_file_get_division(fluid_midi_file *midifile)
|
|||
* @return New MIDI event structure or NULL when out of memory.
|
||||
*/
|
||||
fluid_midi_event_t *
|
||||
new_fluid_midi_event()
|
||||
new_fluid_midi_event(void)
|
||||
{
|
||||
fluid_midi_event_t *evt;
|
||||
evt = FLUID_NEW(fluid_midi_event_t);
|
||||
|
@ -2696,7 +2701,7 @@ int fluid_player_get_midi_tempo(fluid_player_t *player)
|
|||
* new_fluid_midi_parser
|
||||
*/
|
||||
fluid_midi_parser_t *
|
||||
new_fluid_midi_parser()
|
||||
new_fluid_midi_parser(void)
|
||||
{
|
||||
fluid_midi_parser_t *parser;
|
||||
parser = FLUID_NEW(fluid_midi_parser_t);
|
||||
|
|
|
@ -65,7 +65,6 @@ fluid_iir_filter_apply(fluid_iir_filter_t *iir_filter,
|
|||
fluid_real_t dsp_a2 = iir_filter->a2;
|
||||
fluid_real_t dsp_b02 = iir_filter->b02;
|
||||
fluid_real_t dsp_b1 = iir_filter->b1;
|
||||
int dsp_filter_coeff_incr_count = iir_filter->filter_coeff_incr_count;
|
||||
|
||||
fluid_real_t dsp_centernode;
|
||||
int dsp_i;
|
||||
|
@ -83,51 +82,18 @@ fluid_iir_filter_apply(fluid_iir_filter_t *iir_filter,
|
|||
* doesn't change.
|
||||
*/
|
||||
|
||||
if(dsp_filter_coeff_incr_count > 0)
|
||||
for(dsp_i = 0; dsp_i < count; dsp_i++)
|
||||
{
|
||||
fluid_real_t dsp_a1_incr = iir_filter->a1_incr;
|
||||
fluid_real_t dsp_a2_incr = iir_filter->a2_incr;
|
||||
fluid_real_t dsp_b02_incr = iir_filter->b02_incr;
|
||||
fluid_real_t dsp_b1_incr = iir_filter->b1_incr;
|
||||
|
||||
|
||||
/* Increment is added to each filter coefficient filter_coeff_incr_count times. */
|
||||
for(dsp_i = 0; dsp_i < count; dsp_i++)
|
||||
{
|
||||
/* The filter is implemented in Direct-II form. */
|
||||
dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2;
|
||||
dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1;
|
||||
dsp_hist2 = dsp_hist1;
|
||||
dsp_hist1 = dsp_centernode;
|
||||
|
||||
if(dsp_filter_coeff_incr_count-- > 0)
|
||||
{
|
||||
fluid_real_t old_b02 = dsp_b02;
|
||||
dsp_a1 += dsp_a1_incr;
|
||||
dsp_a2 += dsp_a2_incr;
|
||||
dsp_b02 += dsp_b02_incr;
|
||||
dsp_b1 += dsp_b1_incr;
|
||||
|
||||
/* Compensate history to avoid the filter going havoc with large frequency changes */
|
||||
if(iir_filter->compensate_incr && FLUID_FABS(dsp_b02) > 0.001f)
|
||||
{
|
||||
fluid_real_t compensate = old_b02 / dsp_b02;
|
||||
dsp_hist1 *= compensate;
|
||||
dsp_hist2 *= compensate;
|
||||
}
|
||||
}
|
||||
} /* for dsp_i */
|
||||
}
|
||||
else /* The filter parameters are constant. This is duplicated to save time. */
|
||||
{
|
||||
for(dsp_i = 0; dsp_i < count; dsp_i++)
|
||||
{
|
||||
/* The filter is implemented in Direct-II form. */
|
||||
dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2;
|
||||
dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1;
|
||||
dsp_hist2 = dsp_hist1;
|
||||
dsp_hist1 = dsp_centernode;
|
||||
}
|
||||
/* The filter is implemented in Direct-II form. */
|
||||
dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2;
|
||||
dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1;
|
||||
dsp_hist2 = dsp_hist1;
|
||||
dsp_hist1 = dsp_centernode;
|
||||
/* Alternatively, it could be implemented in Transposed Direct Form II */
|
||||
// fluid_real_t dsp_input = dsp_buf[dsp_i];
|
||||
// dsp_buf[dsp_i] = dsp_b02 * dsp_input + dsp_hist1;
|
||||
// dsp_hist1 = dsp_b1 * dsp_input - dsp_a1 * dsp_buf[dsp_i] + dsp_hist2;
|
||||
// dsp_hist2 = dsp_b02 * dsp_input - dsp_a2 * dsp_buf[dsp_i];
|
||||
}
|
||||
|
||||
iir_filter->hist1 = dsp_hist1;
|
||||
|
@ -136,7 +102,6 @@ fluid_iir_filter_apply(fluid_iir_filter_t *iir_filter,
|
|||
iir_filter->a2 = dsp_a2;
|
||||
iir_filter->b02 = dsp_b02;
|
||||
iir_filter->b1 = dsp_b1;
|
||||
iir_filter->filter_coeff_incr_count = dsp_filter_coeff_incr_count;
|
||||
|
||||
fluid_check_fpe("voice_filter");
|
||||
}
|
||||
|
@ -320,47 +285,11 @@ fluid_iir_filter_calculate_coefficients(fluid_iir_filter_t *iir_filter,
|
|||
return;
|
||||
}
|
||||
|
||||
iir_filter->compensate_incr = 0;
|
||||
|
||||
if(iir_filter->filter_startup || (transition_samples == 0))
|
||||
{
|
||||
/* The filter is calculated, because the voice was started up.
|
||||
* In this case set the filter coefficients without delay.
|
||||
*/
|
||||
iir_filter->a1 = a1_temp;
|
||||
iir_filter->a2 = a2_temp;
|
||||
iir_filter->b02 = b02_temp;
|
||||
iir_filter->b1 = b1_temp;
|
||||
iir_filter->filter_coeff_incr_count = 0;
|
||||
iir_filter->filter_startup = 0;
|
||||
// printf("Setting initial filter coefficients.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* The filter frequency is changed. Calculate an increment
|
||||
* factor, so that the new setting is reached after one buffer
|
||||
* length. x_incr is added to the current value FLUID_BUFSIZE
|
||||
* times. The length is arbitrarily chosen. Longer than one
|
||||
* buffer will sacrifice some performance, though. Note: If
|
||||
* the filter is still too 'grainy', then increase this number
|
||||
* at will.
|
||||
*/
|
||||
|
||||
iir_filter->a1_incr = (a1_temp - iir_filter->a1) / transition_samples;
|
||||
iir_filter->a2_incr = (a2_temp - iir_filter->a2) / transition_samples;
|
||||
iir_filter->b02_incr = (b02_temp - iir_filter->b02) / transition_samples;
|
||||
iir_filter->b1_incr = (b1_temp - iir_filter->b1) / transition_samples;
|
||||
|
||||
if(FLUID_FABS(iir_filter->b02) > 0.0001f)
|
||||
{
|
||||
fluid_real_t quota = b02_temp / iir_filter->b02;
|
||||
iir_filter->compensate_incr = quota < 0.5f || quota > 2.f;
|
||||
}
|
||||
|
||||
/* Have to add the increments filter_coeff_incr_count times. */
|
||||
iir_filter->filter_coeff_incr_count = transition_samples;
|
||||
}
|
||||
iir_filter->a1 = a1_temp;
|
||||
iir_filter->a2 = a2_temp;
|
||||
iir_filter->b02 = b02_temp;
|
||||
iir_filter->b1 = b1_temp;
|
||||
iir_filter->filter_startup = 0;
|
||||
|
||||
fluid_check_fpe("voice_write filter calculation");
|
||||
}
|
||||
|
@ -376,9 +305,6 @@ void fluid_iir_filter_calc(fluid_iir_filter_t *iir_filter,
|
|||
/* calculate the frequency of the resonant filter in Hz */
|
||||
fres = fluid_ct2hz(iir_filter->fres + fres_mod);
|
||||
|
||||
/* FIXME - Still potential for a click during turn on, can we interpolate
|
||||
between 20khz cutoff and 0 Q? */
|
||||
|
||||
/* I removed the optimization of turning the filter off when the
|
||||
* resonance frequency is above the maximum frequency. Instead, the
|
||||
* filter frequency is set to a maximum of 0.45 times the sampling
|
||||
|
@ -398,6 +324,7 @@ void fluid_iir_filter_calc(fluid_iir_filter_t *iir_filter,
|
|||
fres = 5.f;
|
||||
}
|
||||
|
||||
// FLUID_LOG(FLUID_INFO, "%f + %f cents = %f cents = %f Hz | Q: %f", iir_filter->fres, fres_mod, iir_filter->fres + fres_mod, fres, iir_filter->q_lin);
|
||||
/* if filter enabled and there is a significant frequency change.. */
|
||||
if(iir_filter->type != FLUID_IIR_DISABLED && FLUID_FABS(fres - iir_filter->last_fres) > 0.01f)
|
||||
{
|
||||
|
|
|
@ -53,12 +53,6 @@ struct _fluid_iir_filter_t
|
|||
fluid_real_t a1; /* a0 / a0 */
|
||||
fluid_real_t a2; /* a1 / a0 */
|
||||
|
||||
fluid_real_t b02_incr;
|
||||
fluid_real_t b1_incr;
|
||||
fluid_real_t a1_incr;
|
||||
fluid_real_t a2_incr;
|
||||
int filter_coeff_incr_count;
|
||||
int compensate_incr; /* Flag: If set, must compensate history */
|
||||
fluid_real_t hist1, hist2; /* Sample history for the IIR filter */
|
||||
int filter_startup; /* Flag: If set, the filter will be set directly.
|
||||
Else it changes smoothly. */
|
||||
|
|
|
@ -354,11 +354,13 @@ fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf)
|
|||
/******************* amplitude **********************/
|
||||
|
||||
count = fluid_rvoice_calc_amp(voice);
|
||||
|
||||
if(count <= 0)
|
||||
if(count == 0)
|
||||
{
|
||||
return count; /* return -1 if voice is quiet, 0 if voice has finished */
|
||||
// Voice has finished, remove from dsp loop
|
||||
return 0;
|
||||
}
|
||||
// else if count is negative, still process the voice
|
||||
|
||||
|
||||
/******************* phase **********************/
|
||||
|
||||
|
@ -420,6 +422,14 @@ fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf)
|
|||
voice->dsp.phase_incr = 1;
|
||||
}
|
||||
|
||||
/* loop mode release? if not in release, the voice is silent
|
||||
* note: this intentionally processes the volenv before returning silence,
|
||||
* since that's what polyphone does (PR #1400) */
|
||||
if(voice->dsp.samplemode == FLUID_START_ON_RELEASE && fluid_adsr_env_get_section(&voice->envlfo.volenv) < FLUID_VOICE_ENVRELEASE)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* voice is currently looping? */
|
||||
is_looping = voice->dsp.samplemode == FLUID_LOOP_DURING_RELEASE
|
||||
|| (voice->dsp.samplemode == FLUID_LOOP_UNTIL_RELEASE
|
||||
|
@ -431,6 +441,19 @@ fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf)
|
|||
* Depending on the position in the loop and the loop size, this
|
||||
* may require several runs. */
|
||||
|
||||
if(count < 0)
|
||||
{
|
||||
// The voice is quite, i.e. either in delay phase or zero volume.
|
||||
// We need to update the rvoice's dsp phase, as the delay phase shall not "postpone" the sound, rather
|
||||
// it should be played silently, see https://github.com/FluidSynth/fluidsynth/issues/1312
|
||||
//
|
||||
// Currently, this does access the sample buffers, which is redundant and could be optimized away.
|
||||
// On the other hand, entering this if-clause is not supposed to happen often.
|
||||
//
|
||||
// Also note, that we're returning directly without running the IIR filter below.
|
||||
return fluid_rvoice_dsp_interpolate_none(&voice->dsp, dsp_buf, is_looping);
|
||||
}
|
||||
|
||||
switch(voice->dsp.interp_method)
|
||||
{
|
||||
case FLUID_INTERP_NONE:
|
||||
|
@ -455,6 +478,7 @@ fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf)
|
|||
|
||||
if(count == 0)
|
||||
{
|
||||
// voice has finished
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ enum fluid_loop
|
|||
{
|
||||
FLUID_UNLOOPED = 0,
|
||||
FLUID_LOOP_DURING_RELEASE = 1,
|
||||
FLUID_NOTUSED = 2,
|
||||
FLUID_START_ON_RELEASE = 2, /* this is a looping mode introduced by Polyphone, see #1398 for more info */
|
||||
FLUID_LOOP_UNTIL_RELEASE = 3
|
||||
};
|
||||
|
||||
|
|
|
@ -954,7 +954,6 @@ fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int c
|
|||
|
||||
for(i = 0; i < GEN_LAST; i++)
|
||||
{
|
||||
|
||||
/* SF 2.01 section 9.4 'bullet' 4:
|
||||
*
|
||||
* A generator in a local instrument zone supersedes a
|
||||
|
@ -977,7 +976,6 @@ fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int c
|
|||
* Do nothing, leave it at the default.
|
||||
*/
|
||||
}
|
||||
|
||||
} /* for all generators */
|
||||
|
||||
/* Adds instrument zone modulators (global and local) to the voice.*/
|
||||
|
@ -991,7 +989,7 @@ fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int c
|
|||
|
||||
for(i = 0; i < GEN_LAST; i++)
|
||||
{
|
||||
|
||||
fluid_real_t awe_val;
|
||||
/* SF 2.01 section 8.5 page 58: If some generators are
|
||||
encountered at preset level, they should be ignored.
|
||||
However this check is not necessary when the soundfont
|
||||
|
@ -1026,6 +1024,12 @@ fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int c
|
|||
* Do nothing, leave it unchanged.
|
||||
*/
|
||||
}
|
||||
|
||||
/* ...unless the default value has been overridden by an AWE32 NRPN */
|
||||
if (fluid_channel_get_override_gen_default(synth->channel[chan], i, &awe_val))
|
||||
{
|
||||
fluid_voice_gen_set(voice, i, awe_val);
|
||||
}
|
||||
} /* for all generators */
|
||||
|
||||
/* Adds preset zone modulators (global and local) to the voice.*/
|
||||
|
@ -1614,18 +1618,6 @@ fluid_zone_mod_import_sfont(char *zone_name, fluid_mod_t **mod, SFZone *sfzone)
|
|||
mod_dest->amount = 0;
|
||||
}
|
||||
|
||||
/* Note: When primary source input (src1) is set to General Controller 'No Controller',
|
||||
output will be forced to 0.0 at synthesis time (see fluid_mod_get_value()).
|
||||
That means that the minimum value of the modulator will be always 0.0.
|
||||
We need to force amount value to 0 to ensure a correct evaluation of the minimum
|
||||
value later (see fluid_voice_get_lower_boundary_for_attenuation()).
|
||||
*/
|
||||
if(((mod_dest->flags1 & FLUID_MOD_CC) == FLUID_MOD_GC) &&
|
||||
(mod_dest->src1 == FLUID_MOD_NONE))
|
||||
{
|
||||
mod_dest->amount = 0;
|
||||
}
|
||||
|
||||
/* *** Dest *** */
|
||||
mod_dest->dest = mod_src->dest; /* index of controlled generator */
|
||||
|
||||
|
@ -1636,25 +1628,20 @@ fluid_zone_mod_import_sfont(char *zone_name, fluid_mod_t **mod, SFZone *sfzone)
|
|||
* Deactivate the modulator by setting the amount to 0. */
|
||||
mod_dest->amount = 0;
|
||||
}
|
||||
/* Note: When secondary source input (src2) is set to General Controller 'No Controller',
|
||||
output will be forced to +1.0 at synthesis time (see fluid_mod_get_value()).
|
||||
That means that this source will behave unipolar only. We need to force the
|
||||
unipolar flag to ensure to ensure a correct evaluation of the minimum
|
||||
value later (see fluid_voice_get_lower_boundary_for_attenuation()).
|
||||
*/
|
||||
if(((mod_dest->flags2 & FLUID_MOD_CC) == FLUID_MOD_GC) &&
|
||||
(mod_dest->src2 == FLUID_MOD_NONE))
|
||||
{
|
||||
mod_dest->flags2 &= ~FLUID_MOD_BIPOLAR;
|
||||
}
|
||||
|
||||
/* *** Transform *** */
|
||||
/* SF2.01 only uses the 'linear' transform (0).
|
||||
* Deactivate the modulator by setting the amount to 0 in any other case.
|
||||
/**
|
||||
* *** Transform Type ***
|
||||
* Only 2 types of transform are defined in the sf2 specification.
|
||||
*/
|
||||
if(mod_src->trans != 0)
|
||||
if(mod_src->trans != FLUID_MOD_TRANSFORM_LINEAR && mod_src->trans != FLUID_MOD_TRANSFORM_ABS)
|
||||
{
|
||||
/* disable the modulator as the transform is invalid */
|
||||
mod_dest->amount = 0;
|
||||
mod_dest->trans = FLUID_MOD_TRANSFORM_LINEAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
mod_dest->trans = mod_src->trans;
|
||||
}
|
||||
|
||||
/* Store the new modulator in the zone The order of modulators
|
||||
|
|
|
@ -66,7 +66,7 @@ struct _fluid_zone_range_t
|
|||
};
|
||||
|
||||
/* Stored on a preset zone to keep track of the inst zones that could start a voice
|
||||
* and their combined preset zone/instument zone ranges */
|
||||
* and their combined preset zone/instrument zone ranges */
|
||||
struct _fluid_voice_zone_t
|
||||
{
|
||||
fluid_inst_zone_t *inst_zone;
|
||||
|
|
|
@ -2500,6 +2500,12 @@ static int fluid_sffile_read_vorbis(SFData *sf, unsigned int start_byte, unsigne
|
|||
goto error_exit;
|
||||
}
|
||||
|
||||
// Avoid clipping for loud samples, see
|
||||
// https://github.com/FluidSynth/fluidsynth/issues/1380
|
||||
// and
|
||||
// https://github.com/libsndfile/libsndfile/issues/194
|
||||
sf_command(sndfile, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE);
|
||||
|
||||
/* Automatically decompresses the Ogg Vorbis data to 16-bit PCM */
|
||||
if(sf_readf_short(sndfile, wav_data, sfinfo.frames) < sfinfo.frames)
|
||||
{
|
||||
|
|
|
@ -128,7 +128,12 @@ fluid_channel_init_ctrl(fluid_channel_t *chan, int is_all_ctrl_off)
|
|||
for(i = 0; i < GEN_LAST; i++)
|
||||
{
|
||||
chan->gen[i] = 0.0f;
|
||||
chan->override_gen_default[i].flags = GEN_UNUSED;
|
||||
chan->override_gen_default[i].val = 0.0f;
|
||||
}
|
||||
// Not all MIDIs initialize the IIR filter coefficient, e.g. Uplift.mid.
|
||||
// A default value is not documented, hence I'm assuming zero here.
|
||||
chan->awe32_filter_coeff = 0;
|
||||
|
||||
if(is_all_ctrl_off)
|
||||
{
|
||||
|
@ -730,3 +735,20 @@ void fluid_channel_cc_breath_note_on_off(fluid_channel_t *chan, int value)
|
|||
|
||||
chan->previous_cc_breath = value;
|
||||
}
|
||||
|
||||
int fluid_channel_get_override_gen_default(fluid_channel_t *chan, int gen, fluid_real_t* val)
|
||||
{
|
||||
if(chan->override_gen_default[gen].flags != GEN_UNUSED)
|
||||
{
|
||||
*val = chan->override_gen_default[gen].val;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void fluid_channel_set_override_gen_default(fluid_channel_t *chan, int gen, fluid_real_t val)
|
||||
{
|
||||
chan->override_gen_default[gen].flags = GEN_SET;
|
||||
chan->override_gen_default[gen].val = val;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "fluidsynth_priv.h"
|
||||
#include "fluid_midi.h"
|
||||
#include "fluid_tuning.h"
|
||||
#include "fluid_gen.h"
|
||||
|
||||
/* The mononophonic list is part of the legato detector for monophonic mode */
|
||||
/* see fluid_synth_monopoly.c about a description of the legato detector device */
|
||||
|
@ -124,11 +125,20 @@ struct _fluid_channel_t
|
|||
enum fluid_gen_type nrpn_select; /* Generator ID of SoundFont NRPN message */
|
||||
char nrpn_active; /* 1 if data entry CCs are for NRPN, 0 if RPN */
|
||||
|
||||
char awe32_filter_coeff;
|
||||
|
||||
/* The values of the generators, set by NRPN messages, or by
|
||||
* fluid_synth_set_gen(), are cached in the channel so they can be
|
||||
* applied to future notes. They are copied to a voice's generators
|
||||
* in fluid_voice_init(), which calls fluid_gen_init(). */
|
||||
fluid_real_t gen[GEN_LAST];
|
||||
|
||||
/* Same for AWE32 NRPNs, however they override the gen's default values */
|
||||
struct
|
||||
{
|
||||
enum fluid_gen_flags flags;
|
||||
fluid_real_t val;
|
||||
} override_gen_default[GEN_LAST];
|
||||
};
|
||||
|
||||
fluid_channel_t *new_fluid_channel(fluid_synth_t *synth, int num);
|
||||
|
@ -272,5 +282,7 @@ void fluid_channel_invalid_prev_note_staccato(fluid_channel_t *chan);
|
|||
void fluid_channel_cc_legato(fluid_channel_t *chan, int value);
|
||||
void fluid_channel_cc_breath_note_on_off(fluid_channel_t *chan, int value);
|
||||
|
||||
int fluid_channel_get_override_gen_default(fluid_channel_t *chan, int gen, fluid_real_t *val);
|
||||
void fluid_channel_set_override_gen_default(fluid_channel_t *chan, int gen, fluid_real_t val);
|
||||
|
||||
#endif /* _FLUID_CHAN_H */
|
||||
|
|
|
@ -39,6 +39,7 @@ fluid_mod_clone(fluid_mod_t *mod, const fluid_mod_t *src)
|
|||
mod->src2 = src->src2;
|
||||
mod->flags2 = src->flags2;
|
||||
mod->amount = src->amount;
|
||||
mod->trans = src->trans;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -97,6 +98,24 @@ fluid_mod_set_amount(fluid_mod_t *mod, double amount)
|
|||
mod->amount = (double) amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the transform type of a modulator.
|
||||
*
|
||||
* @param mod The modulator instance
|
||||
* @param type Transform type, see #fluid_mod_transforms
|
||||
*/
|
||||
void
|
||||
fluid_mod_set_transform(fluid_mod_t *mod, int type)
|
||||
{
|
||||
unsigned char flag = (unsigned char) type;
|
||||
if(flag != FLUID_MOD_TRANSFORM_LINEAR && flag != FLUID_MOD_TRANSFORM_ABS)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "fluid_mod_set_transform() called with invalid transform type %d", type);
|
||||
return;
|
||||
}
|
||||
mod->trans = flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the primary source value from a modulator.
|
||||
*
|
||||
|
@ -169,6 +188,18 @@ fluid_mod_get_amount(const fluid_mod_t *mod)
|
|||
return (double) mod->amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the transform type of a modulator.
|
||||
*
|
||||
* @param mod The modulator instance
|
||||
* @param type Transform type, see #fluid_mod_transforms
|
||||
*/
|
||||
int
|
||||
fluid_mod_get_transform(fluid_mod_t *mod)
|
||||
{
|
||||
return (int) mod->trans;
|
||||
}
|
||||
|
||||
/*
|
||||
* retrieves the initial value from the given source of the modulator
|
||||
*/
|
||||
|
@ -188,7 +219,7 @@ fluid_mod_get_source_value(const unsigned char mod_src,
|
|||
|
||||
if(mod_src == PORTAMENTO_CTRL)
|
||||
{
|
||||
// an invalid portamento fromkey should be treated as 0 when it's actually used for moulating
|
||||
// an invalid portamento fromkey should be treated as 0 when it's actually used for modulating
|
||||
if(!fluid_channel_is_valid_note(val))
|
||||
{
|
||||
val = 0;
|
||||
|
@ -240,7 +271,7 @@ fluid_mod_get_source_value(const unsigned char mod_src,
|
|||
/**
|
||||
* transforms the initial value retrieved by \c fluid_mod_get_source_value into [0.0;1.0]
|
||||
*/
|
||||
static fluid_real_t
|
||||
fluid_real_t
|
||||
fluid_mod_transform_source_value(fluid_real_t val, unsigned char mod_flags, const fluid_real_t range)
|
||||
{
|
||||
/* normalized value, i.e. usually in the range [0;1] */
|
||||
|
@ -365,23 +396,18 @@ fluid_mod_transform_source_value(fluid_real_t val, unsigned char mod_flags, cons
|
|||
*
|
||||
* Output = Transform(Amount * Map(primary source input) * Map(secondary source input))
|
||||
*
|
||||
* Notes:
|
||||
* 1)fluid_mod_get_value, ignores the Transform operator. The result is:
|
||||
* Note:
|
||||
* fluid_mod_get_value ignores the Transform operator. The result is:
|
||||
*
|
||||
* Output = Amount * Map(primary source input) * Map(secondary source input)
|
||||
*
|
||||
* 2)When primary source input (src1) is set to General Controller 'No Controller',
|
||||
* output is forced to 0.
|
||||
*
|
||||
* 3)When secondary source input (src2) is set to General Controller 'No Controller',
|
||||
* output is forced to +1.0
|
||||
*/
|
||||
fluid_real_t
|
||||
fluid_mod_get_value(fluid_mod_t *mod, fluid_voice_t *voice)
|
||||
{
|
||||
extern fluid_mod_t default_vel2filter_mod;
|
||||
|
||||
fluid_real_t v1 = 0.0, v2 = 1.0;
|
||||
fluid_real_t v1, v2;
|
||||
fluid_real_t final_value;
|
||||
/* The wording of the default modulators refers to a range of 127/128.
|
||||
* And the table in section 9.5.3 suggests, that this mapping should be applied
|
||||
* to all unipolar and bipolar mappings respectively.
|
||||
|
@ -419,59 +445,42 @@ fluid_mod_get_value(fluid_mod_t *mod, fluid_voice_t *voice)
|
|||
* */
|
||||
if(fluid_mod_test_identity(mod, &default_vel2filter_mod))
|
||||
{
|
||||
// S. Christian Collins' mod, to stop forcing velocity based filtering
|
||||
/*
|
||||
if (voice->vel < 64){
|
||||
return (fluid_real_t) mod->amount / 2.0;
|
||||
} else {
|
||||
return (fluid_real_t) mod->amount * (127 - voice->vel) / 127;
|
||||
}
|
||||
return (fluid_real_t) mod->amount / 2.0;
|
||||
*/
|
||||
return 0; // (fluid_real_t) mod->amount / 2.0;
|
||||
// S. Christian Collins' mod, to stop forcing velocity based filtering
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end S. Christian Collins' mod
|
||||
/* Get the initial value of the first source.
|
||||
*
|
||||
* Even if the src is FLUID_MOD_NONE, the value has to be transformed, see #1389
|
||||
*/
|
||||
v1 = fluid_mod_get_source_value(mod->src1, mod->flags1, &range1, voice);
|
||||
|
||||
/* get the initial value of the first source */
|
||||
if(mod->src1 > 0)
|
||||
{
|
||||
v1 = fluid_mod_get_source_value(mod->src1, mod->flags1, &range1, voice);
|
||||
|
||||
/* transform the input value */
|
||||
v1 = fluid_mod_transform_source_value(v1, mod->flags1, range1);
|
||||
}
|
||||
/* When primary source input (src1) is set to General Controller 'No Controller',
|
||||
output is forced to 0.0
|
||||
*/
|
||||
else
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* no need to go further */
|
||||
if(v1 == 0.0f)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
/* transform the input value */
|
||||
v1 = fluid_mod_transform_source_value(v1, mod->flags1, range1);
|
||||
|
||||
/* get the second input source */
|
||||
if(mod->src2 > 0)
|
||||
{
|
||||
v2 = fluid_mod_get_source_value(mod->src2, mod->flags2, &range2, voice);
|
||||
v2 = fluid_mod_get_source_value(mod->src2, mod->flags2, &range2, voice);
|
||||
|
||||
/* transform the second input value */
|
||||
v2 = fluid_mod_transform_source_value(v2, mod->flags2, range2);
|
||||
}
|
||||
/* When secondary source input (src2) is set to General Controller 'No Controller',
|
||||
output is forced to +1.0
|
||||
*/
|
||||
else
|
||||
{
|
||||
v2 = 1.0f;
|
||||
}
|
||||
/* transform the second input value */
|
||||
v2 = fluid_mod_transform_source_value(v2, mod->flags2, range2);
|
||||
|
||||
/* it's as simple as that: */
|
||||
return (fluid_real_t) mod->amount * v1 * v2;
|
||||
/* it indeed is as simple as that: */
|
||||
final_value = (fluid_real_t) mod->amount * v1 * v2;
|
||||
|
||||
/* check for absolute value transform */
|
||||
if(mod->trans == FLUID_MOD_TRANSFORM_ABS)
|
||||
{
|
||||
final_value = FLUID_FABS(final_value);
|
||||
}
|
||||
return final_value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -480,7 +489,7 @@ fluid_mod_get_value(fluid_mod_t *mod, fluid_voice_t *voice)
|
|||
* @return New allocated modulator or NULL if out of memory
|
||||
*/
|
||||
fluid_mod_t *
|
||||
new_fluid_mod()
|
||||
new_fluid_mod(void)
|
||||
{
|
||||
fluid_mod_t *mod = FLUID_NEW(fluid_mod_t);
|
||||
|
||||
|
@ -489,7 +498,8 @@ new_fluid_mod()
|
|||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// for the sake of backward compatibility
|
||||
mod->trans = FLUID_MOD_TRANSFORM_LINEAR;
|
||||
return mod;
|
||||
}
|
||||
|
||||
|
@ -511,7 +521,7 @@ delete_fluid_mod(fluid_mod_t *mod)
|
|||
*
|
||||
* Useful in low latency scenarios e.g. to allocate a modulator on the stack.
|
||||
*/
|
||||
size_t fluid_mod_sizeof()
|
||||
size_t fluid_mod_sizeof(void)
|
||||
{
|
||||
return sizeof(fluid_mod_t);
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ struct _fluid_mod_t
|
|||
unsigned char flags1; /**< Source controller 1 flags */
|
||||
unsigned char src2; /**< Source controller 2 */
|
||||
unsigned char flags2; /**< Source controller 2 flags */
|
||||
unsigned char trans; /**< Output transform flag */
|
||||
double amount; /**< Multiplier amount */
|
||||
/* The 'next' field allows to link modulators into a list. It is
|
||||
* not used in fluid_voice.c, there each voice allocates memory for a
|
||||
|
@ -45,6 +46,8 @@ struct _fluid_mod_t
|
|||
|
||||
fluid_real_t fluid_mod_get_value(fluid_mod_t *mod, fluid_voice_t *voice);
|
||||
int fluid_mod_check_sources(const fluid_mod_t *mod, char *name);
|
||||
fluid_real_t fluid_mod_transform_source_value(fluid_real_t val, unsigned char mod_flags, const fluid_real_t range);
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
void fluid_dump_modulator(fluid_mod_t *mod);
|
||||
|
|
|
@ -129,6 +129,7 @@ static void fluid_synth_stop_LOCAL(fluid_synth_t *synth, unsigned int id);
|
|||
|
||||
static int fluid_synth_set_important_channels(fluid_synth_t *synth, const char *channels);
|
||||
|
||||
static void fluid_synth_process_awe32_nrpn_LOCAL(fluid_synth_t *synth, int chan, int gen, int data, int data_lsb);
|
||||
|
||||
/* Callback handlers for real-time settings */
|
||||
static void fluid_synth_handle_gain(void *data, const char *name, double value);
|
||||
|
@ -229,7 +230,7 @@ void fluid_synth_settings(fluid_settings_t *settings)
|
|||
fluid_settings_register_int(settings, "synth.effects-channels", 2, 2, 2, 0);
|
||||
fluid_settings_register_int(settings, "synth.effects-groups", 1, 1, 128, 0);
|
||||
fluid_settings_register_num(settings, "synth.sample-rate", 44100.0, 8000.0, 96000.0, 0);
|
||||
fluid_settings_register_int(settings, "synth.device-id", 0, 0, 127, 0);
|
||||
fluid_settings_register_int(settings, "synth.device-id", 16, 0, 127, 0);
|
||||
#ifdef ENABLE_MIXER_THREADS
|
||||
fluid_settings_register_int(settings, "synth.cpu-cores", 1, 1, 256, 0);
|
||||
#else
|
||||
|
@ -1600,7 +1601,7 @@ fluid_synth_cc(fluid_synth_t *synth, int chan, int num, int val)
|
|||
/* chan is enabled */
|
||||
if(synth->verbose)
|
||||
{
|
||||
FLUID_LOG(FLUID_INFO, "cc\t%d\t%d\t%d", chan, num, val);
|
||||
FLUID_LOG(FLUID_INFO, "cc\t\t%d\t%d\t%d", chan, num, val);
|
||||
}
|
||||
|
||||
fluid_channel_set_cc(channel, num, val);
|
||||
|
@ -1634,7 +1635,7 @@ fluid_synth_cc(fluid_synth_t *synth, int chan, int num, int val)
|
|||
{
|
||||
if(synth->verbose)
|
||||
{
|
||||
FLUID_LOG(FLUID_INFO, "cc\t%d\t%d\t%d", i, num, val);
|
||||
FLUID_LOG(FLUID_INFO, "cc\t\t%d\t%d\t%d", i, num, val);
|
||||
}
|
||||
|
||||
fluid_channel_set_cc(synth->channel[i], num, val);
|
||||
|
@ -1840,6 +1841,26 @@ fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
|
|||
|
||||
chan->nrpn_select = 0; /* Reset to 0 */
|
||||
}
|
||||
else if(fluid_channel_get_cc(chan, NRPN_MSB) == 127) // indicates AWE32 NRPNs
|
||||
{
|
||||
// ALTITUDE.MID also manipulates AWE32 NRPNs by only using DATA LSB events - seems to be legal
|
||||
if(fluid_channel_get_cc(chan, NRPN_MSB) == 127) // indicates AWE32 NRPNs
|
||||
{
|
||||
int gen = fluid_channel_get_cc(chan, NRPN_LSB);
|
||||
if(synth->verbose)
|
||||
{
|
||||
FLUID_LOG(FLUID_INFO, "AWE32 NRPN RAW: Chan %d, Gen %d, data %d | 0x%X, MSB: %d, LSB: %d", channum, gen, data, data, msb_value, lsb_value);
|
||||
}
|
||||
if(gen <= 26) // Effect 26 (reverb) is the last effect to select
|
||||
{
|
||||
fluid_synth_process_awe32_nrpn_LOCAL(synth, channum, gen, data, lsb_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
FLUID_LOG(FLUID_INFO, "Ignoring unknown AWE32 NRPN targetting effect %d", gen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(fluid_channel_get_cc(chan, RPN_MSB) == 0) /* RPN is active: MSB = 0? */
|
||||
{
|
||||
|
@ -2859,7 +2880,7 @@ fluid_synth_pitch_bend(fluid_synth_t *synth, int chan, int val)
|
|||
|
||||
if(synth->verbose)
|
||||
{
|
||||
FLUID_LOG(FLUID_INFO, "pitchb\t%d\t%d", chan, val);
|
||||
FLUID_LOG(FLUID_INFO, "pitchb\t\t%d\t%d", chan, val);
|
||||
}
|
||||
|
||||
fluid_channel_set_pitch_bend(synth->channel[chan], val);
|
||||
|
@ -3091,7 +3112,7 @@ fluid_synth_program_change(fluid_synth_t *synth, int chan, int prognum)
|
|||
|
||||
if(synth->verbose)
|
||||
{
|
||||
FLUID_LOG(FLUID_INFO, "prog\t%d\t%d\t%d", chan, banknum, prognum);
|
||||
FLUID_LOG(FLUID_INFO, "prog\t\t%d\t%d\t%d", chan, banknum, prognum);
|
||||
}
|
||||
|
||||
/* I think this is a hack for MIDI files that do bank changes in GM mode.
|
||||
|
@ -6852,15 +6873,30 @@ fluid_synth_release_voice_on_same_note_LOCAL(fluid_synth_t *synth, int chan,
|
|||
&& (fluid_voice_get_key(voice) == key)
|
||||
&& (fluid_voice_get_id(voice) != synth->noteid))
|
||||
{
|
||||
enum fluid_midi_channel_type type = synth->channel[chan]->channel_type;
|
||||
|
||||
/* Id of voices that was sustained by sostenuto */
|
||||
if(fluid_voice_is_sostenuto(voice))
|
||||
{
|
||||
synth->storeid = fluid_voice_get_id(voice);
|
||||
}
|
||||
|
||||
/* Force the voice into release stage except if pedaling
|
||||
(sostenuto or sustain) is active */
|
||||
fluid_voice_noteoff(voice);
|
||||
switch(type)
|
||||
{
|
||||
case CHANNEL_TYPE_DRUM:
|
||||
/* release the voice, this should make riding hi-hats or snares sound more
|
||||
* realistic (Discussion #1196) */
|
||||
fluid_voice_off(voice);
|
||||
break;
|
||||
case CHANNEL_TYPE_MELODIC:
|
||||
/* Force the voice into release stage except if pedaling (sostenuto or sustain) is active.
|
||||
* This gives a more realistic sound to pianos and possibly other instruments (see PR #905). */
|
||||
fluid_voice_noteoff(voice);
|
||||
break;
|
||||
default:
|
||||
FLUID_LOG(FLUID_ERR, "This should never happen: unknown channel type %d", (int)type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7572,6 +7608,272 @@ fluid_synth_set_gen_LOCAL(fluid_synth_t *synth, int chan, int param, float value
|
|||
}
|
||||
}
|
||||
|
||||
// The "SB AWE32 Developer's Information Pack" provides a lookup table for the filter resonance.
|
||||
// Instead of a single Q value, a high and low Q value is given. This suggests a variable-Q filter design, which is
|
||||
// incompatible to fluidsynth's IIR filter. Therefore we need to somehow derive a single Q value.
|
||||
// Options are:
|
||||
// * mean
|
||||
// * geometric distance (sqrt(q_lo * q_hi))
|
||||
// * either q_lo or q_hi
|
||||
// * linear interpolation between low and high fc
|
||||
// * log interpolation between low and high fc
|
||||
static fluid_real_t
|
||||
calc_awe32_filter_q(int data, fluid_real_t* fc)
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
fluid_real_t fc_lo;
|
||||
fluid_real_t fc_hi;
|
||||
fluid_real_t q_lo;
|
||||
fluid_real_t q_hi;
|
||||
fluid_real_t dc_atten;
|
||||
} awe32_q;
|
||||
|
||||
// Q in dB
|
||||
static const awe32_q awe32_q_table[] =
|
||||
{
|
||||
{92, 22000, 5.f, 0.f, -0.0f }, /* coef 0 */
|
||||
{93, 8500, 6.f, 0.5f, -0.5f }, /* coef 1 */
|
||||
{94, 8300, 8.f, 1.f, -1.2f }, /* coef 2 */
|
||||
{95, 8200, 10.f, 2.f, -1.8f }, /* coef 3 */
|
||||
{96, 8100, 11.f, 3.f, -2.5f }, /* coef 4 */
|
||||
{97, 8000, 13.f, 4.f, -3.3f }, /* coef 5 */
|
||||
{98, 7900, 14.f, 5.f, -4.1f }, /* coef 6 */
|
||||
{99, 7800, 16.f, 6.f, -5.5f}, /* coef 7 */
|
||||
{100, 7700, 17.f, 7.f, -6.0f }, /* coef 8 */
|
||||
{100, 7500, 19.f, 9.f, -6.6f }, /* coef 9 */
|
||||
{100, 7400, 20.f, 10.f, -7.2f }, /* coef 10 */
|
||||
{100, 7300, 22.f, 11.f, -7.9f }, /* coef 11 */
|
||||
{100, 7200, 23.f, 13.f, -8.5f }, /* coef 12 */
|
||||
{100, 7100, 25.f, 15.f, -9.3f }, /* coef 13 */
|
||||
{100, 7100, 26.f, 16.f, -10.1f },/* coef 14 */
|
||||
{100, 7000, 28.f, 18.f, -11.0f}, /* coef 15 */
|
||||
};
|
||||
|
||||
const awe32_q* tab;
|
||||
fluid_real_t alpha;
|
||||
|
||||
fluid_clip(data, 0, 127);
|
||||
data /= 8;
|
||||
tab = &awe32_q_table[data];
|
||||
|
||||
fluid_clip(*fc, tab->fc_lo, tab->fc_hi);
|
||||
|
||||
alpha = (*fc - tab->fc_lo) / (tab->fc_hi - tab->fc_lo);
|
||||
|
||||
// linearly interpolate between high and low Q
|
||||
return 10 * /* cB */ (tab->q_lo * (1.0f - alpha) + tab->q_hi * alpha);
|
||||
|
||||
// alternatively: log interpolation
|
||||
// return 10 * /* cB */ FLUID_POW(tab->q_hi, alpha) * FLUID_POW(tab->q_lo, 1.0f - alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation is based on "Frequently Asked Questions for SB AWE32" http://archive.gamedev.net/archive/reference/articles/article445.html
|
||||
* as well as on the "SB AWE32 Developer's Information Pack" https://github.com/user-attachments/files/15757220/adip301.pdf
|
||||
*
|
||||
* @param gen the AWE32 effect or generator to manipulate
|
||||
* @param data the composed value of DATA_MSB and DATA_LSB
|
||||
*/
|
||||
static void fluid_synth_process_awe32_nrpn_LOCAL(fluid_synth_t *synth, int chan, int gen, int data, int data_lsb)
|
||||
{
|
||||
static const enum fluid_gen_type awe32_to_sf2_gen[] =
|
||||
{
|
||||
// assuming LFO1 maps to MODLFO and LFO2 maps to VIBLFO
|
||||
// observe how nicely most of the AWE32 generators here match up with the order of SF2 generators in fluid_gen_type
|
||||
GEN_MODLFODELAY, /**< Modulation LFO delay */
|
||||
GEN_MODLFOFREQ, /**< Modulation LFO frequency */
|
||||
GEN_VIBLFODELAY, /**< Vibrato LFO delay */
|
||||
GEN_VIBLFOFREQ, /**< Vibrato LFO frequency */
|
||||
GEN_MODENVDELAY, /**< Modulation envelope delay */
|
||||
GEN_MODENVATTACK, /**< Modulation envelope attack */
|
||||
GEN_MODENVHOLD, /**< Modulation envelope hold */
|
||||
GEN_MODENVDECAY, /**< Modulation envelope decay */
|
||||
GEN_MODENVSUSTAIN, /**< Modulation envelope sustain */
|
||||
GEN_MODENVRELEASE, /**< Modulation envelope release */
|
||||
GEN_VOLENVDELAY, /**< Volume envelope delay */
|
||||
GEN_VOLENVATTACK, /**< Volume envelope attack */
|
||||
GEN_VOLENVHOLD, /**< Volume envelope hold */
|
||||
GEN_VOLENVDECAY, /**< Volume envelope decay */
|
||||
GEN_VOLENVSUSTAIN, /**< Volume envelope sustain */
|
||||
GEN_VOLENVRELEASE, /**< Volume envelope release */
|
||||
GEN_PITCH, /**< Initial Pitch */
|
||||
GEN_MODLFOTOPITCH, /**< Modulation LFO to pitch */
|
||||
GEN_VIBLFOTOPITCH, /**< Vibrato LFO to pitch */
|
||||
GEN_MODENVTOPITCH, /**< Modulation envelope to pitch */
|
||||
GEN_MODLFOTOVOL, /**< Modulation LFO to volume */
|
||||
GEN_FILTERFC, /**< Filter cutoff */
|
||||
GEN_FILTERQ, /**< Filter Q */
|
||||
GEN_MODLFOTOFILTERFC, /**< Modulation LFO to filter cutoff */
|
||||
GEN_MODENVTOFILTERFC, /**< Modulation envelope to filter cutoff */
|
||||
GEN_CHORUSSEND, /**< Chorus send amount */
|
||||
GEN_REVERBSEND, /**< Reverb send amount */
|
||||
};
|
||||
|
||||
enum fluid_gen_type sf2_gen = awe32_to_sf2_gen[gen];
|
||||
int is_realtime = FALSE, i, coef;
|
||||
fluid_real_t converted_sf2_generator_value, q;
|
||||
|
||||
// The AWE32 NRPN docs say that a value of 8192 is considered to be the middle, i.e. zero.
|
||||
// However, it looks like for those generators which work in range [0,127], the AWE32 only inspects the DATA_LSB, i.e. and not doing this subtraction. Found while investigating Uplift.mid.
|
||||
data -= 8192;
|
||||
|
||||
switch(sf2_gen)
|
||||
{
|
||||
case GEN_MODLFODELAY:
|
||||
case GEN_VIBLFODELAY:
|
||||
case GEN_MODENVDELAY:
|
||||
case GEN_VOLENVDELAY:
|
||||
fluid_clip(data, 0, 5900);
|
||||
converted_sf2_generator_value = fluid_sec2tc(data * (fluid_real_t)(4.0 / 1000.0));
|
||||
break;
|
||||
|
||||
case GEN_MODLFOFREQ:
|
||||
case GEN_VIBLFOFREQ:
|
||||
fluid_clip(data_lsb, 0, 127);
|
||||
converted_sf2_generator_value = fluid_hz2ct(data_lsb * (fluid_real_t)0.084 /* Hz */);
|
||||
is_realtime = TRUE;
|
||||
break;
|
||||
|
||||
case GEN_MODENVATTACK:
|
||||
case GEN_VOLENVATTACK:
|
||||
fluid_clip(data, 0, 5940);
|
||||
converted_sf2_generator_value = fluid_sec2tc(data * (fluid_real_t)(1.0 / 1000.0));
|
||||
break;
|
||||
|
||||
case GEN_MODENVHOLD:
|
||||
case GEN_VOLENVHOLD:
|
||||
fluid_clip(data, 0, 8191);
|
||||
converted_sf2_generator_value = fluid_sec2tc(data * (fluid_real_t)(1.0 / 1000.0));
|
||||
break;
|
||||
|
||||
case GEN_MODENVDECAY:
|
||||
case GEN_MODENVRELEASE:
|
||||
case GEN_VOLENVDECAY:
|
||||
case GEN_VOLENVRELEASE:
|
||||
fluid_clip(data, 0, 5940);
|
||||
converted_sf2_generator_value = fluid_sec2tc(data * (fluid_real_t)(4.0 / 1000.0));
|
||||
break;
|
||||
|
||||
case GEN_MODENVSUSTAIN:
|
||||
case GEN_VOLENVSUSTAIN:
|
||||
fluid_clip(data_lsb, 0, 127);
|
||||
converted_sf2_generator_value = data_lsb * (fluid_real_t)(0.75 /* dB */ * 10) /* cB */;
|
||||
break;
|
||||
|
||||
case GEN_PITCH:
|
||||
converted_sf2_generator_value = data + 8192;
|
||||
// This has the side effect of manipulating the modulation state of the channel's pitchwheel, but
|
||||
// I'll buy it, since pitch bend is not a regular SF2 generator and we do a bit of magic there to
|
||||
// make it work
|
||||
fluid_synth_pitch_bend(synth, chan, converted_sf2_generator_value);
|
||||
return;
|
||||
|
||||
case GEN_MODLFOTOPITCH:
|
||||
case GEN_VIBLFOTOPITCH:
|
||||
is_realtime = TRUE;
|
||||
/* fallthrough */
|
||||
case GEN_MODENVTOPITCH:
|
||||
fluid_clip(data, -127, 127);
|
||||
converted_sf2_generator_value = data * (fluid_real_t)9.375 /* cents */;
|
||||
break;
|
||||
|
||||
case GEN_MODLFOTOVOL:
|
||||
fluid_clip(data_lsb, 0, 127);
|
||||
converted_sf2_generator_value = data_lsb * (fluid_real_t)(0.1875 /* dB */ * 10.0) /* cB */;
|
||||
is_realtime = TRUE;
|
||||
break;
|
||||
|
||||
case GEN_FILTERFC:
|
||||
fluid_clip(data_lsb, 0, 127);
|
||||
// Yes, DO NOT use data here, Uplift.mid doesn't set MSB=64, therefore we would always get a negative value after subtracting 8192.
|
||||
// Since Uplift.mid sounds fine on hardware though, it seems like AWE32 only inspects DATA_LSB in this case.
|
||||
// conversion continues below!
|
||||
converted_sf2_generator_value = (data_lsb * 62 /* Hz */);
|
||||
FLUID_LOG(FLUID_DBG, "AWE32 IIR Fc: %f Hz",converted_sf2_generator_value);
|
||||
is_realtime = TRUE;
|
||||
break;
|
||||
|
||||
case GEN_FILTERQ:
|
||||
FLUID_LOG(FLUID_DBG, "AWE32 IIR Q Tab: %d",data_lsb);
|
||||
synth->channel[chan]->awe32_filter_coeff = data_lsb;
|
||||
return;
|
||||
|
||||
case GEN_MODLFOTOFILTERFC:
|
||||
fluid_clip(data, -64, 63);
|
||||
converted_sf2_generator_value = data * (fluid_real_t)56.25 /* cents */;
|
||||
FLUID_LOG(FLUID_DBG, "AWE32 MOD LFO TO FILTER Fc: %f cents", converted_sf2_generator_value);
|
||||
is_realtime = TRUE;
|
||||
// not supported, as this modulates the "phase" rather than the filters cutoff frequency
|
||||
return;
|
||||
|
||||
case GEN_MODENVTOFILTERFC:
|
||||
fluid_clip(data, -127, 127);
|
||||
converted_sf2_generator_value = data * (fluid_real_t)56.25 /* cents */;
|
||||
FLUID_LOG(FLUID_DBG, "AWE32 MOD ENV TO FILTER Fc: %f cents", converted_sf2_generator_value);
|
||||
// not supported, as this modulates the "phase" rather than the filters cutoff frequency
|
||||
return;
|
||||
|
||||
case GEN_REVERBSEND:
|
||||
fluid_clip(data, 0, 255);
|
||||
/* transform the input value */
|
||||
converted_sf2_generator_value = fluid_mod_transform_source_value(data, default_reverb_mod.flags1, 256);
|
||||
FLUID_LOG(FLUID_DBG, "AWE32 Reverb: %f", converted_sf2_generator_value);
|
||||
converted_sf2_generator_value*= fluid_mod_get_amount(&default_reverb_mod);
|
||||
break;
|
||||
|
||||
case GEN_CHORUSSEND:
|
||||
fluid_clip(data, 0, 255);
|
||||
/* transform the input value */
|
||||
converted_sf2_generator_value = fluid_mod_transform_source_value(data, default_chorus_mod.flags1, 256);
|
||||
FLUID_LOG(FLUID_DBG, "AWE32 Chorus: %f", converted_sf2_generator_value);
|
||||
converted_sf2_generator_value*= fluid_mod_get_amount(&default_chorus_mod);
|
||||
break;
|
||||
|
||||
default:
|
||||
// should not happen
|
||||
FLUID_LOG(FLUID_WARN, "AWE32 NPRN %d conversion not implemented", gen);
|
||||
return;
|
||||
}
|
||||
|
||||
coef = synth->channel[chan]->awe32_filter_coeff;
|
||||
if(sf2_gen == GEN_FILTERFC)
|
||||
{
|
||||
// The cutoff at fc seems to be very steep for SoundBlaster! hardware. Listening tests have shown that lowering the cutoff frequency by 1000Hz gives a closer signal to the SB! hardware filter...
|
||||
converted_sf2_generator_value -= 1000;
|
||||
q = calc_awe32_filter_q(coef, &converted_sf2_generator_value);
|
||||
FLUID_LOG(FLUID_DBG, "AWE32 IIR Fc (corrected): %f Hz", converted_sf2_generator_value);
|
||||
FLUID_LOG(FLUID_DBG, "AWE32 IIR Q: %f cB", q);
|
||||
|
||||
converted_sf2_generator_value = fluid_hz2ct(converted_sf2_generator_value /* Hz */);
|
||||
|
||||
// Safe the "true initial Q"
|
||||
fluid_channel_set_override_gen_default(synth->channel[chan], GEN_FILTERQ, q);
|
||||
}
|
||||
|
||||
fluid_channel_set_override_gen_default(synth->channel[chan], sf2_gen, converted_sf2_generator_value);
|
||||
|
||||
for (i = 0; is_realtime && i < synth->polyphony; i++)
|
||||
{
|
||||
fluid_voice_t* voice = synth->voice[i];
|
||||
|
||||
if (fluid_voice_is_playing(voice) && fluid_voice_get_channel(voice) == chan)
|
||||
{
|
||||
// sets the adjusted generator
|
||||
fluid_voice_gen_set(voice, sf2_gen, converted_sf2_generator_value);
|
||||
fluid_voice_update_param(voice, sf2_gen);
|
||||
|
||||
FLUID_LOG(FLUID_DBG, "AWE32 Realtime: adjusting voice id %d, generator %d, chan %d", fluid_voice_get_id(voice), sf2_gen, chan);
|
||||
if(sf2_gen == GEN_FILTERFC)
|
||||
{
|
||||
// also sets the calculated Q
|
||||
fluid_voice_gen_set(voice, GEN_FILTERQ, q);
|
||||
fluid_voice_update_param(voice, GEN_FILTERQ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the generator NRPN offset assigned to a MIDI channel.
|
||||
*
|
||||
|
|
|
@ -41,21 +41,21 @@
|
|||
*
|
||||
* DEFINES
|
||||
*/
|
||||
#define FLUID_NUM_PROGRAMS 128
|
||||
#define DRUM_INST_BANK 128
|
||||
#define FLUID_NUM_PROGRAMS 128
|
||||
#define DRUM_INST_BANK 128
|
||||
|
||||
#define FLUID_UNSET_PROGRAM 128 /* Program number used to unset a preset */
|
||||
#define FLUID_UNSET_PROGRAM 128 /* Program number used to unset a preset */
|
||||
|
||||
#define FLUID_REVERB_DEFAULT_ROOMSIZE 0.2f /**< Default reverb room size */
|
||||
#define FLUID_REVERB_DEFAULT_DAMP 0.0f /**< Default reverb damping */
|
||||
#define FLUID_REVERB_DEFAULT_WIDTH 0.5f /**< Default reverb width */
|
||||
#define FLUID_REVERB_DEFAULT_LEVEL 0.9f /**< Default reverb level */
|
||||
#define FLUID_REVERB_DEFAULT_DAMP 0.3f /**< Default reverb damping */
|
||||
#define FLUID_REVERB_DEFAULT_LEVEL 0.7f /**< Default reverb level */
|
||||
#define FLUID_REVERB_DEFAULT_ROOMSIZE 0.5f /**< Default reverb room size */
|
||||
#define FLUID_REVERB_DEFAULT_WIDTH 0.8f /**< Default reverb width */
|
||||
|
||||
#define FLUID_CHORUS_DEFAULT_N 3 /**< Default chorus voice count */
|
||||
#define FLUID_CHORUS_DEFAULT_LEVEL 2.0f /**< Default chorus level */
|
||||
#define FLUID_CHORUS_DEFAULT_SPEED 0.3f /**< Default chorus speed */
|
||||
#define FLUID_CHORUS_DEFAULT_DEPTH 8.0f /**< Default chorus depth */
|
||||
#define FLUID_CHORUS_DEFAULT_TYPE FLUID_CHORUS_MOD_SINE /**< Default chorus waveform type */
|
||||
#define FLUID_CHORUS_DEFAULT_DEPTH 4.25f /**< Default chorus depth */
|
||||
#define FLUID_CHORUS_DEFAULT_LEVEL 0.6f /**< Default chorus level */
|
||||
#define FLUID_CHORUS_DEFAULT_N 3 /**< Default chorus voice count */
|
||||
#define FLUID_CHORUS_DEFAULT_SPEED 0.2f /**< Default chorus speed */
|
||||
#define FLUID_CHORUS_DEFAULT_TYPE FLUID_CHORUS_MOD_SINE /**< Default chorus waveform type */
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
|
|
|
@ -1791,7 +1791,7 @@ fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t *voice)
|
|||
3)absolute value of amount.
|
||||
|
||||
When at least one source mapping is bipolar:
|
||||
min_val is -|amount| regardless the sign of amount.
|
||||
min_val is -|amount| regardless the sign of amount.
|
||||
When both sources mapping are unipolar:
|
||||
min_val is -|amount|, if amount is negative.
|
||||
min_val is 0, if amount is positive
|
||||
|
@ -1834,9 +1834,6 @@ fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t *voice)
|
|||
return lower_bound;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int fluid_voice_set_param(fluid_voice_t *voice, int gen, fluid_real_t nrpn_value)
|
||||
{
|
||||
voice->gen[gen].nrpn = nrpn_value;
|
||||
|
|
|
@ -111,9 +111,20 @@ fluid_cb2amp(fluid_real_t cb)
|
|||
*/
|
||||
|
||||
/* minimum attenuation: 0 dB */
|
||||
if(cb < 0)
|
||||
if(FLUID_UNLIKELY(cb < 0))
|
||||
{
|
||||
return 1.0;
|
||||
/* Issue #1374: it seems that by using modLfoToVolEnv, the attenuation can become negative and
|
||||
* therefore the signal needs to be amplified.
|
||||
* In such a rare case, calculate the attenuation on the fly.
|
||||
*
|
||||
* This behavior is backed by the spec saying:
|
||||
* modLfoToVolume: "A positive number indicates a positive LFO excursion increases volume;
|
||||
* a negative number indicates a positive excursion decreases volume.
|
||||
* [...] For example, a value of 100 indicates that the volume will first rise ten dB, then fall ten dB."
|
||||
*
|
||||
* And in order to rise, a negative attenuation must be permitted.
|
||||
*/
|
||||
return FLUID_POW(10.0f, cb / -200.0f);
|
||||
}
|
||||
|
||||
if(cb >= FLUID_CB_AMP_SIZE)
|
||||
|
@ -150,7 +161,7 @@ fluid_tc2sec_delay(fluid_real_t tc)
|
|||
tc = (fluid_real_t) 5000.0f;
|
||||
}
|
||||
|
||||
return FLUID_POW(2.f, tc / 1200.f);
|
||||
return fluid_tc2sec(tc);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -178,7 +189,7 @@ fluid_tc2sec_attack(fluid_real_t tc)
|
|||
tc = (fluid_real_t) 8000.f;
|
||||
};
|
||||
|
||||
return FLUID_POW(2.f, tc / 1200.f);
|
||||
return fluid_tc2sec(tc);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -191,6 +202,29 @@ fluid_tc2sec(fluid_real_t tc)
|
|||
return FLUID_POW(2.f, tc / 1200.f);
|
||||
}
|
||||
|
||||
/*
|
||||
* fluid_sec2tc
|
||||
*
|
||||
* seconds to timecents
|
||||
*/
|
||||
fluid_real_t
|
||||
fluid_sec2tc(fluid_real_t sec)
|
||||
{
|
||||
fluid_real_t res;
|
||||
if(sec < 0)
|
||||
{
|
||||
// would require a complex solution of fluid_tc2sec(), but this is real-only
|
||||
return -32768.f;
|
||||
}
|
||||
|
||||
res = (1200.f / M_LN2) * FLUID_LOGF(sec);
|
||||
if(res < -32768.f)
|
||||
{
|
||||
res = -32768.f;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* fluid_tc2sec_release
|
||||
*/
|
||||
|
@ -216,20 +250,21 @@ fluid_tc2sec_release(fluid_real_t tc)
|
|||
tc = (fluid_real_t) 8000.f;
|
||||
};
|
||||
|
||||
return FLUID_POW(2.f, tc / 1200.f);
|
||||
return fluid_tc2sec(tc);
|
||||
}
|
||||
|
||||
/**
|
||||
* The inverse operation, converting from Hertz to cents
|
||||
*/
|
||||
fluid_real_t fluid_hz2ct(fluid_real_t f)
|
||||
{
|
||||
return 6900.f + (1200.f / FLUID_M_LN2) * FLUID_LOGF(f / 440.0f);
|
||||
}
|
||||
|
||||
/*
|
||||
* fluid_act2hz
|
||||
*
|
||||
* Convert from absolute cents to Hertz
|
||||
*
|
||||
* The inverse operation, converting from Hertz to cents, was unused and implemented as
|
||||
*
|
||||
fluid_hz2ct(fluid_real_t f)
|
||||
{
|
||||
return 6900.f + (1200.f / FLUID_M_LN2) * FLUID_LOGF(f / 440.0f));
|
||||
}
|
||||
*/
|
||||
double
|
||||
fluid_act2hz(double c)
|
||||
|
|
|
@ -27,10 +27,12 @@
|
|||
fluid_real_t fluid_ct2hz_real(fluid_real_t cents);
|
||||
fluid_real_t fluid_ct2hz(fluid_real_t cents);
|
||||
fluid_real_t fluid_cb2amp(fluid_real_t cb);
|
||||
fluid_real_t fluid_sec2tc(fluid_real_t sec);
|
||||
fluid_real_t fluid_tc2sec(fluid_real_t tc);
|
||||
fluid_real_t fluid_tc2sec_delay(fluid_real_t tc);
|
||||
fluid_real_t fluid_tc2sec_attack(fluid_real_t tc);
|
||||
fluid_real_t fluid_tc2sec_release(fluid_real_t tc);
|
||||
fluid_real_t fluid_hz2ct(fluid_real_t f);
|
||||
double fluid_act2hz(double c);
|
||||
fluid_real_t fluid_pan(fluid_real_t c, int left);
|
||||
fluid_real_t fluid_balance(fluid_real_t balance, int left);
|
||||
|
|
|
@ -30,6 +30,7 @@ The creator: Michael Hipp (email: hippm@informatik.uni-tuebingen.de - please bot
|
|||
|
||||
Contributions/ideas Thomas Orgis era (includes backports from mhipp trunk):
|
||||
|
||||
Bill Roberts <bill.roberts@arm.com>: PAC/BTI for aarch64
|
||||
Dave Yeo <dave.r.yeo@gmail.com>: continued OS/2 fixing
|
||||
madebr and manx: github mirror and CI
|
||||
Vitaly Kirsanov <krokoziabla@gmail.com>: ports/cmake (optional CMake build)
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
/* Define if FIFO support is enabled. */
|
||||
#define FIFO 1
|
||||
|
||||
/* System setup enforces 64 bit offsets where 32 bit would be native. */
|
||||
/* #undef FORCED_OFF_64 */
|
||||
|
||||
/* Define if frame index should be used. */
|
||||
#define FRAME_INDEX 1
|
||||
|
||||
|
@ -436,7 +439,7 @@
|
|||
#define PACKAGE_NAME "mpg123"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "mpg123 1.32.7"
|
||||
#define PACKAGE_STRING "mpg123 1.32.9"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "mpg123"
|
||||
|
@ -445,7 +448,7 @@
|
|||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.32.7"
|
||||
#define PACKAGE_VERSION "1.32.9"
|
||||
|
||||
/* Define to only include portable library API (no off_t, no internal I/O). */
|
||||
/* #undef PORTABLE_API */
|
||||
|
@ -477,7 +480,7 @@
|
|||
/* #undef USE_YASM_FOR_AVX */
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.32.7"
|
||||
#define VERSION "1.32.9"
|
||||
|
||||
/* Define to use Win32 named pipes */
|
||||
#define WANT_WIN32_FIFO 1
|
||||
|
|
|
@ -88,7 +88,7 @@ int INT123_compat_open(const char *filename, int flags)
|
|||
open_fallback:
|
||||
#endif
|
||||
|
||||
#if (defined(WIN32) && !defined (__CYGWIN__))
|
||||
#if defined(MPG123_COMPAT_MSVCRT_IO)
|
||||
/* MSDN says POSIX function is deprecated beginning in Visual C++ 2005 */
|
||||
/* Try plain old _open(), if it fails, do nothing */
|
||||
ret = _open(filename, flags|_O_BINARY, _S_IREAD | _S_IWRITE);
|
||||
|
@ -138,12 +138,16 @@ fopen_ok:
|
|||
|
||||
FILE* INT123_compat_fdopen(int fd, const char *mode)
|
||||
{
|
||||
#if defined(MPG123_COMPAT_MSVCRT_IO)
|
||||
return _fdopen(fd, mode);
|
||||
#else
|
||||
return fdopen(fd, mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
int INT123_compat_close(int infd)
|
||||
{
|
||||
#if (defined(WIN32) && !defined (__CYGWIN__)) /* MSDN says POSIX function is deprecated beginning in Visual C++ 2005 */
|
||||
#if defined(MPG123_COMPAT_MSVCRT_IO)
|
||||
return _close(infd);
|
||||
#else
|
||||
return close(infd);
|
||||
|
|
|
@ -110,7 +110,42 @@
|
|||
|
||||
typedef unsigned char byte;
|
||||
|
||||
#if (defined(_UCRT) || defined(_MSC_VER) || (defined(__MINGW32__) || defined(__MINGW64__)) || (defined(__WATCOMC__) && defined(__NT__))) && !defined(__CYGWIN__)
|
||||
#define MPG123_COMPAT_MSVCRT_IO
|
||||
#endif
|
||||
|
||||
#if defined(MPG123_COMPAT_MSVCRT_IO)
|
||||
#if defined(_UCRT)
|
||||
// needs to get checked separately from MSVC and MinGW becuase it is also used by native Clang on Windows
|
||||
#ifndef MPG123_COMPAT_MSVCRT_IO_64
|
||||
#define MPG123_COMPAT_MSVCRT_IO_64
|
||||
#endif
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
#if (_MSC_VER >= 1200)
|
||||
// >= VC6
|
||||
#ifndef MPG123_COMPAT_MSVCRT_IO_64
|
||||
#define MPG123_COMPAT_MSVCRT_IO_64
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#if (defined(__MSVCRT__) || defined(_UCRT)) && !defined(__CRTDLL__)
|
||||
#ifndef MPG123_COMPAT_MSVCRT_IO_64
|
||||
#define MPG123_COMPAT_MSVCRT_IO_64
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__WATCOMC__) && defined(__NT__)
|
||||
#if (__WATCOMC__ >= 1100)
|
||||
#ifndef MPG123_COMPAT_MSVCRT_IO_64
|
||||
#define MPG123_COMPAT_MSVCRT_IO_64
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE__SETMODE) || defined(HAVE_SETMODE) || defined(MPG123_COMPAT_MSVCRT_IO)
|
||||
// For _setmode(), at least.
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
*/
|
||||
#define MPG123_API_VERSION 48
|
||||
/** library patch level at client build time */
|
||||
#define MPG123_PATCHLEVEL 2
|
||||
#define MPG123_PATCHLEVEL 3
|
||||
|
||||
#ifndef MPG123_EXPORT
|
||||
/** Defines needed for MS Visual Studio(tm) DLL builds.
|
||||
|
|
|
@ -511,6 +511,7 @@ static void frame_fixed_reset(mpg123_handle *fr)
|
|||
{
|
||||
frame_icy_reset(fr);
|
||||
INT123_open_bad(fr);
|
||||
memset(&(fr->hdr), 0, sizeof(fr->hdr));
|
||||
fr->to_decode = FALSE;
|
||||
fr->to_ignore = FALSE;
|
||||
fr->metaflags = 0;
|
||||
|
@ -524,15 +525,12 @@ static void frame_fixed_reset(mpg123_handle *fr)
|
|||
fr->clip = 0;
|
||||
fr->oldhead = 0;
|
||||
fr->firsthead = 0;
|
||||
fr->lay = 0;
|
||||
fr->vbr = MPG123_CBR;
|
||||
fr->abr_rate = 0;
|
||||
fr->track_frames = 0;
|
||||
fr->track_samples = -1;
|
||||
fr->framesize=0;
|
||||
fr->mean_frames = 0;
|
||||
fr->mean_framesize = 0;
|
||||
fr->freesize = 0;
|
||||
fr->lastscale = -1;
|
||||
fr->rva.level[0] = -1;
|
||||
fr->rva.level[1] = -1;
|
||||
|
@ -567,8 +565,7 @@ static void frame_fixed_reset(mpg123_handle *fr)
|
|||
fr->icy.next = 0;
|
||||
#endif
|
||||
fr->halfphase = 0; /* here or indeed only on first-time init? */
|
||||
fr->error_protection = 0;
|
||||
fr->freeformat_framesize = fr->p.freeformat_framesize;
|
||||
fr->hdr.freeformat_framesize = fr->p.freeformat_framesize;
|
||||
fr->enc_delay = -1;
|
||||
fr->enc_padding = -1;
|
||||
memset(fr->id3buf, 0, sizeof(fr->id3buf));
|
||||
|
@ -627,7 +624,7 @@ int attribute_align_arg mpg123_framedata(mpg123_handle *mh, unsigned long *heade
|
|||
|
||||
if(header != NULL) *header = mh->oldhead;
|
||||
if(bodydata != NULL) *bodydata = mh->bsbuf;
|
||||
if(bodybytes != NULL) *bodybytes = mh->framesize;
|
||||
if(bodybytes != NULL) *bodybytes = mh->hdr.framesize;
|
||||
|
||||
return MPG123_OK;
|
||||
}
|
||||
|
@ -900,9 +897,9 @@ static int64_t ignoreframe(mpg123_handle *fr)
|
|||
{
|
||||
int64_t preshift = fr->p.preframes;
|
||||
/* Layer 3 _really_ needs at least one frame before. */
|
||||
if(fr->lay==3 && preshift < 1) preshift = 1;
|
||||
if(fr->hdr.lay==3 && preshift < 1) preshift = 1;
|
||||
/* Layer 1 & 2 reall do not need more than 2. */
|
||||
if(fr->lay!=3 && preshift > 2) preshift = 2;
|
||||
if(fr->hdr.lay!=3 && preshift > 2) preshift = 2;
|
||||
|
||||
return fr->firstframe - preshift;
|
||||
}
|
||||
|
@ -949,7 +946,7 @@ void INT123_frame_set_frameseek(mpg123_handle *fr, int64_t fe)
|
|||
void INT123_frame_skip(mpg123_handle *fr)
|
||||
{
|
||||
#ifndef NO_LAYER3
|
||||
if(fr->lay == 3) INT123_set_pointer(fr, 1, 512);
|
||||
if(fr->hdr.lay == 3) INT123_set_pointer(fr, 1, 512);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -96,6 +96,33 @@ enum frame_state_flags
|
|||
,FRAME_DECODER_LIVE = 0x8 /**< 1000 Decoder can be used. */
|
||||
};
|
||||
|
||||
// separate frame header structure for safe decoding of headers without
|
||||
// modifying the main frame struct before we are sure that we can read a
|
||||
// frame into it
|
||||
struct frame_header
|
||||
{
|
||||
int lay;
|
||||
// lots of flags that could share storage, should reform that
|
||||
int lsf; /* 0: MPEG 1.0; 1: MPEG 2.0/2.5 -- both used as bool and array index! */
|
||||
int mpeg25;
|
||||
int error_protection;
|
||||
int bitrate_index;
|
||||
int sampling_frequency;
|
||||
int padding;
|
||||
int extension;
|
||||
int mode;
|
||||
int mode_ext;
|
||||
int copyright;
|
||||
int original;
|
||||
int emphasis;
|
||||
// Even 16 bit int is enough for MAXFRAMESIZE
|
||||
int framesize; /* computed framesize */
|
||||
int freeformat;
|
||||
int freeformat_framesize;
|
||||
// Derived from header and checked against the above.
|
||||
int ssize;
|
||||
};
|
||||
|
||||
/* There is a lot to condense here... many ints can be merged as flags; though the main space is still consumed by buffers. */
|
||||
struct mpg123_handle_struct
|
||||
{
|
||||
|
@ -197,26 +224,12 @@ struct mpg123_handle_struct
|
|||
int single;
|
||||
int II_sblimit;
|
||||
int down_sample_sblimit;
|
||||
int lsf; /* 0: MPEG 1.0; 1: MPEG 2.0/2.5 -- both used as bool and array index! */
|
||||
/* Many flags in disguise as integers... wasting bytes. */
|
||||
int mpeg25;
|
||||
int down_sample;
|
||||
int header_change;
|
||||
int lay;
|
||||
struct frame_header hdr;
|
||||
long spf; /* cached count of samples per frame */
|
||||
int (*do_layer)(mpg123_handle *);
|
||||
int error_protection;
|
||||
int bitrate_index;
|
||||
int sampling_frequency;
|
||||
int padding;
|
||||
int extension;
|
||||
int mode;
|
||||
int mode_ext;
|
||||
int copyright;
|
||||
int original;
|
||||
int emphasis;
|
||||
int framesize; /* computed framesize */
|
||||
int freesize; /* free format frame size */
|
||||
enum mpg123_vbr vbr; /* 1 if variable bitrate was detected */
|
||||
int64_t num; /* frame offset ... */
|
||||
int64_t input_offset; /* byte offset of this frame in input stream */
|
||||
|
@ -225,8 +238,6 @@ struct mpg123_handle_struct
|
|||
int state_flags;
|
||||
char silent_resync; /* Do not complain for the next n resyncs. */
|
||||
unsigned char* xing_toc; /* The seek TOC from Xing header. */
|
||||
int freeformat;
|
||||
long freeformat_framesize;
|
||||
|
||||
/* bitstream info; bsi */
|
||||
int bitindex;
|
||||
|
@ -253,7 +264,6 @@ struct mpg123_handle_struct
|
|||
double mean_framesize;
|
||||
int64_t mean_frames;
|
||||
int fsizeold;
|
||||
int ssize;
|
||||
unsigned int bitreservoir;
|
||||
unsigned char bsspace[2][MAXFRAMESIZE+512+4]; /* MAXFRAMESIZE */
|
||||
unsigned char *bsbuf;
|
||||
|
|
|
@ -217,7 +217,7 @@ int INT123_do_layer1(mpg123_handle *fr)
|
|||
real (*fraction)[SBLIMIT] = fr->layer1.fraction; /* fraction[2][SBLIMIT] */
|
||||
int single = fr->single;
|
||||
|
||||
fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext<<2)+4 : 32;
|
||||
fr->jsbound = (fr->hdr.mode == MPG_MD_JOINT_STEREO) ? (fr->hdr.mode_ext<<2)+4 : 32;
|
||||
|
||||
if(stereo == 1 || single == SINGLE_MIX) /* I don't see mixing handled here */
|
||||
single = SINGLE_LEFT;
|
||||
|
|
|
@ -313,10 +313,10 @@ static void II_select_table(mpg123_handle *fr)
|
|||
const struct al_table *tables[5] = { alloc_0, alloc_1, alloc_2, alloc_3 , alloc_4 };
|
||||
const int sblims[5] = { 27 , 30 , 8, 12 , 30 };
|
||||
|
||||
if(fr->sampling_frequency >= 3) /* Or equivalent: (fr->lsf == 1) */
|
||||
if(fr->hdr.sampling_frequency >= 3) /* Or equivalent: (fr->lsf == 1) */
|
||||
table = 4;
|
||||
else
|
||||
table = translate[fr->sampling_frequency][2-fr->stereo][fr->bitrate_index];
|
||||
table = translate[fr->hdr.sampling_frequency][2-fr->stereo][fr->hdr.bitrate_index];
|
||||
|
||||
sblim = sblims[table];
|
||||
fr->alloc = tables[table];
|
||||
|
@ -337,7 +337,7 @@ int INT123_do_layer2(mpg123_handle *fr)
|
|||
int single = fr->single;
|
||||
|
||||
II_select_table(fr);
|
||||
fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext<<2)+4 : fr->II_sblimit;
|
||||
fr->jsbound = (fr->hdr.mode == MPG_MD_JOINT_STEREO) ? (fr->hdr.mode_ext<<2)+4 : fr->II_sblimit;
|
||||
|
||||
if(fr->jsbound > fr->II_sblimit)
|
||||
{
|
||||
|
|
|
@ -135,16 +135,16 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
|
|||
int powdiff = (single == SINGLE_MIX) ? 4 : 0;
|
||||
|
||||
const int tabs[2][5] = { { 2,9,5,3,4 } , { 1,8,1,2,9 } };
|
||||
const int *tab = tabs[fr->lsf];
|
||||
const int *tab = tabs[fr->hdr.lsf];
|
||||
|
||||
{ /* First ensure we got enough bits available. */
|
||||
unsigned int needbits = 0;
|
||||
needbits += tab[1]; /* main_data_begin */
|
||||
needbits += stereo == 1 ? tab[2] : tab[3]; /* private */
|
||||
if(!fr->lsf)
|
||||
if(!fr->hdr.lsf)
|
||||
needbits += stereo*4; /* scfsi */
|
||||
/* For each granule for each channel ... */
|
||||
needbits += tab[0]*stereo*(29+tab[4]+1+22+(!fr->lsf?1:0)+2);
|
||||
needbits += tab[0]*stereo*(29+tab[4]+1+22+(!fr->hdr.lsf?1:0)+2);
|
||||
if(fr->bits_avail < needbits) \
|
||||
{
|
||||
if(NOQUIET)
|
||||
|
@ -162,7 +162,7 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
|
|||
|
||||
/* overwrite main_data_begin for the really available bit reservoir */
|
||||
backbits(fr, tab[1]);
|
||||
if(fr->lsf == 0)
|
||||
if(fr->hdr.lsf == 0)
|
||||
{
|
||||
fr->wordpointer[0] = (unsigned char) (fr->bitreservoir >> 1);
|
||||
fr->wordpointer[1] = (unsigned char) ((fr->bitreservoir & 1) << 7);
|
||||
|
@ -171,7 +171,7 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
|
|||
|
||||
/* zero "side-info" data for a silence-frame
|
||||
without touching audio data used as bit reservoir for following frame */
|
||||
memset(fr->wordpointer+2, 0, fr->ssize-2);
|
||||
memset(fr->wordpointer+2, 0, fr->hdr.ssize-2);
|
||||
|
||||
/* reread the new bit reservoir offset */
|
||||
si->main_data_begin = getbits(fr, tab[1]);
|
||||
|
@ -179,11 +179,11 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
|
|||
|
||||
/* Keep track of the available data bytes for the bit reservoir.
|
||||
CRC is included in ssize already. */
|
||||
fr->bitreservoir = fr->bitreservoir + fr->framesize - fr->ssize;
|
||||
fr->bitreservoir = fr->bitreservoir + fr->hdr.framesize - fr->hdr.ssize;
|
||||
|
||||
/* Limit the reservoir to the max for MPEG 1.0 or 2.x . */
|
||||
if(fr->bitreservoir > (unsigned int) (fr->lsf == 0 ? 511 : 255))
|
||||
fr->bitreservoir = (fr->lsf == 0 ? 511 : 255);
|
||||
if(fr->bitreservoir > (unsigned int) (fr->hdr.lsf == 0 ? 511 : 255))
|
||||
fr->bitreservoir = (fr->hdr.lsf == 0 ? 511 : 255);
|
||||
|
||||
/* Now back into less commented territory. It's code. It works. */
|
||||
|
||||
|
@ -192,7 +192,7 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
|
|||
else
|
||||
si->private_bits = getbits(fr, tab[3]);
|
||||
|
||||
if(!fr->lsf) for(ch=0; ch<stereo; ch++)
|
||||
if(!fr->hdr.lsf) for(ch=0; ch<stereo; ch++)
|
||||
{
|
||||
si->ch[ch].gr[0].scfsi = -1;
|
||||
si->ch[ch].gr[1].scfsi = getbits(fr, 4);
|
||||
|
@ -257,14 +257,14 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
|
|||
}
|
||||
|
||||
/* region_count/start parameters are implicit in this case. */
|
||||
if( (!fr->lsf || (gr_info->block_type == 2)) && !fr->mpeg25)
|
||||
if( (!fr->hdr.lsf || (gr_info->block_type == 2)) && !fr->hdr.mpeg25)
|
||||
{
|
||||
gr_info->region1start = 36>>1;
|
||||
gr_info->region2start = 576>>1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fr->mpeg25)
|
||||
if(fr->hdr.mpeg25)
|
||||
{
|
||||
int r0c,r1c;
|
||||
if((gr_info->block_type == 2) && (!gr_info->mixed_block_flag) ) r0c = 5;
|
||||
|
@ -299,7 +299,7 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
|
|||
gr_info->block_type = 0;
|
||||
gr_info->mixed_block_flag = 0;
|
||||
}
|
||||
if(!fr->lsf) gr_info->preflag = get1bit(fr);
|
||||
if(!fr->hdr.lsf) gr_info->preflag = get1bit(fr);
|
||||
|
||||
gr_info->scalefac_scale = get1bit(fr);
|
||||
gr_info->count1table_select = get1bit(fr);
|
||||
|
@ -1824,7 +1824,7 @@ int INT123_do_layer3(mpg123_handle *fr)
|
|||
int stereo = fr->stereo;
|
||||
int single = fr->single;
|
||||
int ms_stereo,i_stereo;
|
||||
int sfreq = fr->sampling_frequency;
|
||||
int sfreq = fr->hdr.sampling_frequency;
|
||||
int stereo1,granules;
|
||||
|
||||
if(stereo == 1)
|
||||
|
@ -1837,14 +1837,14 @@ int INT123_do_layer3(mpg123_handle *fr)
|
|||
else
|
||||
stereo1 = 2;
|
||||
|
||||
if(fr->mode == MPG_MD_JOINT_STEREO)
|
||||
if(fr->hdr.mode == MPG_MD_JOINT_STEREO)
|
||||
{
|
||||
ms_stereo = (fr->mode_ext & 0x2)>>1;
|
||||
i_stereo = fr->mode_ext & 0x1;
|
||||
ms_stereo = (fr->hdr.mode_ext & 0x2)>>1;
|
||||
i_stereo = fr->hdr.mode_ext & 0x1;
|
||||
}
|
||||
else ms_stereo = i_stereo = 0;
|
||||
|
||||
granules = fr->lsf ? 1 : 2;
|
||||
granules = fr->hdr.lsf ? 1 : 2;
|
||||
|
||||
/* quick hack to keep the music playing */
|
||||
/* after having seen this nasty test file... */
|
||||
|
@ -1859,7 +1859,7 @@ int INT123_do_layer3(mpg123_handle *fr)
|
|||
if(fr->pinfo)
|
||||
{
|
||||
fr->pinfo->maindata = sideinfo.main_data_begin;
|
||||
fr->pinfo->padding = fr->padding;
|
||||
fr->pinfo->padding = fr->hdr.padding;
|
||||
}
|
||||
#endif
|
||||
for(gr=0;gr<granules;gr++)
|
||||
|
@ -1880,7 +1880,7 @@ int INT123_do_layer3(mpg123_handle *fr)
|
|||
, gr_info->part2_3_length, fr->bits_avail );
|
||||
return clip;
|
||||
}
|
||||
if(fr->lsf)
|
||||
if(fr->hdr.lsf)
|
||||
part2bits = III_get_scale_factors_2(fr, scalefacs[0],gr_info,0);
|
||||
else
|
||||
part2bits = III_get_scale_factors_1(fr, scalefacs[0],gr_info,0,gr);
|
||||
|
@ -1920,7 +1920,7 @@ int INT123_do_layer3(mpg123_handle *fr)
|
|||
{
|
||||
struct gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]);
|
||||
long part2bits;
|
||||
if(fr->lsf)
|
||||
if(fr->hdr.lsf)
|
||||
part2bits = III_get_scale_factors_2(fr, scalefacs[1],gr_info,i_stereo);
|
||||
else
|
||||
part2bits = III_get_scale_factors_1(fr, scalefacs[1],gr_info,1,gr);
|
||||
|
@ -1970,7 +1970,7 @@ int INT123_do_layer3(mpg123_handle *fr)
|
|||
}
|
||||
}
|
||||
|
||||
if(i_stereo) III_i_stereo(hybridIn,scalefacs[1],gr_info,sfreq,ms_stereo,fr->lsf);
|
||||
if(i_stereo) III_i_stereo(hybridIn,scalefacs[1],gr_info,sfreq,ms_stereo,fr->hdr.lsf);
|
||||
|
||||
if(ms_stereo || i_stereo || (single == SINGLE_MIX) )
|
||||
{
|
||||
|
|
|
@ -137,7 +137,11 @@ static void wrap_io_cleanup(void *handle)
|
|||
if(ioh->my_fd >= 0)
|
||||
{
|
||||
mdebug("closing my fd %d", ioh->my_fd);
|
||||
#if defined(MPG123_COMPAT_MSVCRT_IO)
|
||||
_close(ioh->my_fd);
|
||||
#else
|
||||
close(ioh->my_fd);
|
||||
#endif
|
||||
ioh->my_fd = -1;
|
||||
}
|
||||
}
|
||||
|
@ -699,6 +703,35 @@ static int64_t wrap_lseek(void *handle, int64_t offset, int whence)
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Defining a wrapper to the native read to be sure the prototype matches.
|
||||
// There are platforms where it is read(int, void*, unsigned int).
|
||||
// We know that we read small chunks where the difference does not matter. Could
|
||||
// apply specific hackery, use a common compat_read() (INT123_unintr_read()?) with system
|
||||
// specifics.
|
||||
static mpg123_ssize_t fallback_read(int fd, void *buf, size_t count)
|
||||
{
|
||||
#if defined(MPG123_COMPAT_MSVCRT_IO)
|
||||
if(count > UINT_MAX)
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
return _read(fd, buf, (unsigned int)count);
|
||||
#else
|
||||
return read(fd, buf, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
static off_t fallback_lseek(int fd, off_t offset, int whence)
|
||||
{
|
||||
#if defined(MPG123_COMPAT_MSVCRT_IO)
|
||||
// Off_t is 32 bit and does fit into long. We know that.
|
||||
return _lseek(fd, (long)offset, whence);
|
||||
#else
|
||||
return lseek(fd, offset, whence);
|
||||
#endif
|
||||
}
|
||||
|
||||
// This is assuming an internally opened file, which usually will be
|
||||
// using 64 bit offsets. It keeps reading on on trivial interruptions.
|
||||
// I guess any file descriptor that matches the libc should work fine.
|
||||
|
@ -730,7 +763,7 @@ static int internal_read64(void *handle, void *buf, size_t bytes, size_t *got_by
|
|||
}
|
||||
#endif
|
||||
errno = 0;
|
||||
ptrdiff_t part = read(fd, (char*)buf+got, bytes);
|
||||
ptrdiff_t part = fallback_read(fd, (char*)buf+got, bytes);
|
||||
if(part > 0) // == 0 is end of file
|
||||
{
|
||||
SATURATE_SUB(bytes, part, 0)
|
||||
|
@ -755,13 +788,15 @@ static int64_t internal_lseek64(void *handle, int64_t offset, int whence)
|
|||
struct wrap_data* ioh = handle;
|
||||
#ifdef LFS_LARGEFILE_64
|
||||
return lseek64(ioh->fd, offset, whence);
|
||||
#elif defined(MPG123_COMPAT_MSVCRT_IO_64)
|
||||
return _lseeki64(ioh->fd, offset, whence);
|
||||
#else
|
||||
if(offset < OFF_MIN || offset > OFF_MAX)
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
return lseek(ioh->fd, (off_t)offset, whence);
|
||||
return fallback_lseek(ioh->fd, (off_t)offset, whence);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -861,16 +896,6 @@ int INT123_wrap_open(mpg123_handle *mh, void *handle, const char *path, int fd,
|
|||
|
||||
// So, native off_t reader replacement.
|
||||
|
||||
// Defining a wrapper to the native read to be sure the prototype matches.
|
||||
// There are platforms where it is read(int, void*, unsigned int).
|
||||
// We know that we read small chunks where the difference does not matter. Could
|
||||
// apply specific hackery, use a common compat_read() (INT123_unintr_read()?) with system
|
||||
// specifics.
|
||||
static mpg123_ssize_t fallback_read(int fd, void *buf, size_t count)
|
||||
{
|
||||
return read(fd, buf, count);
|
||||
}
|
||||
|
||||
// In forced 64 bit offset mode, the only definitions of these are
|
||||
// the _64 ones.
|
||||
#ifdef FORCED_OFF_64
|
||||
|
@ -902,7 +927,7 @@ int attribute_align_arg mpg123_replace_reader(mpg123_handle *mh, mpg123_ssize_t
|
|||
ioh->iotype = IO_FD;
|
||||
ioh->fd = -1; /* On next mpg123_open_fd(), this gets a value. */
|
||||
ioh->r_read = r_read != NULL ? r_read : fallback_read;
|
||||
ioh->r_lseek = r_lseek != NULL ? (void *)r_lseek : (void *)lseek;
|
||||
ioh->r_lseek = r_lseek != NULL ? r_lseek : fallback_lseek;
|
||||
}
|
||||
|
||||
/* The real reader replacement will happen while opening. */
|
||||
|
|
|
@ -457,7 +457,7 @@ int attribute_align_arg mpg123_getstate(mpg123_handle *mh, enum mpg123_state key
|
|||
theval = mh->enc_padding;
|
||||
break;
|
||||
case MPG123_DEC_DELAY:
|
||||
theval = mh->lay == 3 ? GAPLESS_DELAY : -1;
|
||||
theval = mh->hdr.lay == 3 ? GAPLESS_DELAY : -1;
|
||||
break;
|
||||
default:
|
||||
mh->err = MPG123_BAD_KEY;
|
||||
|
@ -1241,10 +1241,10 @@ static int init_track(mpg123_handle *mh)
|
|||
b = init_track(mh); \
|
||||
if(b < 0) return b; \
|
||||
\
|
||||
mi->version = mh->mpeg25 ? MPG123_2_5 : (mh->lsf ? MPG123_2_0 : MPG123_1_0); \
|
||||
mi->layer = mh->lay; \
|
||||
mi->version = mh->hdr.mpeg25 ? MPG123_2_5 : (mh->hdr.lsf ? MPG123_2_0 : MPG123_1_0); \
|
||||
mi->layer = mh->hdr.lay; \
|
||||
mi->rate = INT123_frame_freq(mh); \
|
||||
switch(mh->mode) \
|
||||
switch(mh->hdr.mode) \
|
||||
{ \
|
||||
case 0: mi->mode = MPG123_M_STEREO; break; \
|
||||
case 1: mi->mode = MPG123_M_JOINT; break; \
|
||||
|
@ -1252,14 +1252,14 @@ static int init_track(mpg123_handle *mh)
|
|||
case 3: mi->mode = MPG123_M_MONO; break; \
|
||||
default: mi->mode = 0; /* Nothing good to do here. */ \
|
||||
} \
|
||||
mi->mode_ext = mh->mode_ext; \
|
||||
mi->framesize = mh->framesize+4; /* Include header. */ \
|
||||
mi->mode_ext = mh->hdr.mode_ext; \
|
||||
mi->framesize = mh->hdr.framesize+4; /* Include header. */ \
|
||||
mi->flags = 0; \
|
||||
if(mh->error_protection) mi->flags |= MPG123_CRC; \
|
||||
if(mh->copyright) mi->flags |= MPG123_COPYRIGHT; \
|
||||
if(mh->extension) mi->flags |= MPG123_PRIVATE; \
|
||||
if(mh->original) mi->flags |= MPG123_ORIGINAL; \
|
||||
mi->emphasis = mh->emphasis; \
|
||||
if(mh->hdr.error_protection) mi->flags |= MPG123_CRC; \
|
||||
if(mh->hdr.copyright) mi->flags |= MPG123_COPYRIGHT; \
|
||||
if(mh->hdr.extension) mi->flags |= MPG123_PRIVATE; \
|
||||
if(mh->hdr.original) mi->flags |= MPG123_ORIGINAL; \
|
||||
mi->emphasis = mh->hdr.emphasis; \
|
||||
mi->bitrate = INT123_frame_bitrate(mh); \
|
||||
mi->abr_rate = mh->abr_rate; \
|
||||
mi->vbr = mh->vbr; \
|
||||
|
|
|
@ -63,9 +63,10 @@ static const int tabsel_123[2][3][16] =
|
|||
|
||||
static const long freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 };
|
||||
|
||||
static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeformat_count);
|
||||
static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount);
|
||||
static int do_readahead(mpg123_handle *fr, unsigned long newhead);
|
||||
static int decode_header(mpg123_handle *fr, struct frame_header *hdr, unsigned long newhead, int *freeformat_count);
|
||||
static void apply_header(mpg123_handle *fr, struct frame_header *hdr);
|
||||
static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount, struct frame_header *nhdr);
|
||||
static int do_readahead(mpg123_handle *fr, struct frame_header *nhdr, unsigned long newhead);
|
||||
static int wetwork(mpg123_handle *fr, unsigned long *newheadp);
|
||||
|
||||
/* These two are to be replaced by one function that gives all the frame parameters (for outsiders).*/
|
||||
|
@ -73,12 +74,12 @@ static int wetwork(mpg123_handle *fr, unsigned long *newheadp);
|
|||
|
||||
int INT123_frame_bitrate(mpg123_handle *fr)
|
||||
{
|
||||
return tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index];
|
||||
return tabsel_123[fr->hdr.lsf][fr->hdr.lay-1][fr->hdr.bitrate_index];
|
||||
}
|
||||
|
||||
long INT123_frame_freq(mpg123_handle *fr)
|
||||
{
|
||||
return freqs[fr->sampling_frequency];
|
||||
return freqs[fr->hdr.sampling_frequency];
|
||||
}
|
||||
|
||||
/* compiler is smart enought to inline this one or should I really do it as macro...? */
|
||||
|
@ -141,8 +142,8 @@ static int check_lame_tag(mpg123_handle *fr)
|
|||
Mono 17 9
|
||||
*/
|
||||
int lame_offset = (fr->stereo == 2)
|
||||
? (fr->lsf ? 17 : 32)
|
||||
: (fr->lsf ? 9 : 17);
|
||||
? (fr->hdr.lsf ? 17 : 32)
|
||||
: (fr->hdr.lsf ? 9 : 17);
|
||||
|
||||
if(fr->p.flags & MPG123_IGNORE_INFOFRAME) goto check_lame_tag_no;
|
||||
|
||||
|
@ -154,7 +155,7 @@ static int check_lame_tag(mpg123_handle *fr)
|
|||
for the actual data, have to check if each byte of information is present.
|
||||
But: 4 B Info/Xing + 4 B flags is bare minimum.
|
||||
*/
|
||||
if(fr->framesize < lame_offset+8) goto check_lame_tag_no;
|
||||
if(fr->hdr.framesize < lame_offset+8) goto check_lame_tag_no;
|
||||
|
||||
/* only search for tag when all zero before it (apart from checksum) */
|
||||
for(i=2; i < lame_offset; ++i) if(fr->bsbuf[i] != 0) goto check_lame_tag_no;
|
||||
|
@ -190,7 +191,7 @@ static int check_lame_tag(mpg123_handle *fr)
|
|||
|
||||
/* From now on, I have to carefully check if the announced data is actually
|
||||
there! I'm always returning 'yes', though. */
|
||||
#define check_bytes_left(n) if(fr->framesize < lame_offset+n) \
|
||||
#define check_bytes_left(n) if(fr->hdr.framesize < lame_offset+n) \
|
||||
goto check_lame_tag_yes
|
||||
if(xing_flags & 1) /* total bitstream frames */
|
||||
{
|
||||
|
@ -443,10 +444,10 @@ static int head_compatible(unsigned long fred, unsigned long bret)
|
|||
static void halfspeed_prepare(mpg123_handle *fr)
|
||||
{
|
||||
/* save for repetition */
|
||||
if(fr->p.halfspeed && fr->lay == 3)
|
||||
if(fr->p.halfspeed && fr->hdr.lay == 3)
|
||||
{
|
||||
debug("halfspeed - reusing old bsbuf ");
|
||||
memcpy (fr->ssave, fr->bsbuf, fr->ssize);
|
||||
memcpy (fr->ssave, fr->bsbuf, fr->hdr.ssize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -462,8 +463,8 @@ static int halfspeed_do(mpg123_handle *fr)
|
|||
fr->to_decode = fr->to_ignore = TRUE;
|
||||
--fr->halfphase;
|
||||
INT123_set_pointer(fr, 0, 0);
|
||||
if(fr->lay == 3) memcpy (fr->bsbuf, fr->ssave, fr->ssize);
|
||||
if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */
|
||||
if(fr->hdr.lay == 3) memcpy (fr->bsbuf, fr->ssave, fr->hdr.ssize);
|
||||
if(fr->hdr.error_protection) fr->crc = getbits(fr, 16); /* skip crc */
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
|
@ -496,10 +497,11 @@ int INT123_read_frame(mpg123_handle *fr)
|
|||
/* TODO: rework this thing */
|
||||
int freeformat_count = 0;
|
||||
unsigned long newhead;
|
||||
// Start with current frame header state as copy for roll-back ability.
|
||||
struct frame_header nhdr = fr->hdr;
|
||||
int64_t framepos;
|
||||
int ret;
|
||||
/* stuff that needs resetting if complete frame reading fails */
|
||||
int oldsize = fr->framesize;
|
||||
int oldphase = fr->halfphase;
|
||||
|
||||
/* The counter for the search-first-header loop.
|
||||
|
@ -507,11 +509,12 @@ int INT123_read_frame(mpg123_handle *fr)
|
|||
when repeatedly headers are found that do not have valid followup headers. */
|
||||
long headcount = 0;
|
||||
|
||||
fr->fsizeold=fr->framesize; /* for Layer3 */
|
||||
fr->fsizeold=fr->hdr.framesize; /* for Layer3 */
|
||||
|
||||
if(halfspeed_do(fr) == 1) return 1;
|
||||
|
||||
/* From now on, old frame data is tainted by parsing attempts. */
|
||||
// Handling premature effects of decode_header now, more decoupling would be welcome.
|
||||
fr->to_decode = fr->to_ignore = FALSE;
|
||||
|
||||
if( fr->p.flags & MPG123_NO_FRANKENSTEIN &&
|
||||
|
@ -540,13 +543,13 @@ init_resync:
|
|||
#ifdef SKIP_JUNK
|
||||
if(!fr->firsthead && !head_check(newhead))
|
||||
{
|
||||
ret = skip_junk(fr, &newhead, &headcount);
|
||||
ret = skip_junk(fr, &newhead, &headcount, &nhdr);
|
||||
JUMP_CONCLUSION(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = head_check(newhead);
|
||||
if(ret) ret = decode_header(fr, newhead, &freeformat_count);
|
||||
if(ret) ret = decode_header(fr, &nhdr, newhead, &freeformat_count);
|
||||
|
||||
JUMP_CONCLUSION(ret); /* That only continues for ret == PARSE_BAD or PARSE_GOOD. */
|
||||
if(ret == PARSE_BAD)
|
||||
|
@ -561,7 +564,7 @@ init_resync:
|
|||
{
|
||||
ret = fr->p.flags & MPG123_NO_READAHEAD
|
||||
? PARSE_GOOD
|
||||
: do_readahead(fr, newhead);
|
||||
: do_readahead(fr, &nhdr, newhead);
|
||||
/* readahead can fail mit NEED_MORE, in which case we must also make the just read header available again for next go */
|
||||
if(ret < 0) fr->rd->back_bytes(fr, 4);
|
||||
JUMP_CONCLUSION(ret);
|
||||
|
@ -585,8 +588,8 @@ init_resync:
|
|||
{
|
||||
unsigned char *newbuf = fr->bsspace[fr->bsnum]+512;
|
||||
/* read main data into memory */
|
||||
debug2("read frame body of %i at %"PRIi64, fr->framesize, framepos+4);
|
||||
if((ret=fr->rd->read_frame_body(fr,newbuf,fr->framesize))<0)
|
||||
debug2("read frame body of %i at %"PRIi64, nhdr.framesize, framepos+4);
|
||||
if((ret=fr->rd->read_frame_body(fr,newbuf,nhdr.framesize))<0)
|
||||
{
|
||||
/* if failed: flip back */
|
||||
debug1("%s", ret == MPG123_NEED_MORE ? "need more" : "read error");
|
||||
|
@ -597,6 +600,10 @@ init_resync:
|
|||
}
|
||||
fr->bsnum = (fr->bsnum + 1) & 1;
|
||||
|
||||
// We read the frame body, time to apply the matching header.
|
||||
// Even if erroring out later, the header state needs to match the body.
|
||||
apply_header(fr, &nhdr);
|
||||
|
||||
if(!fr->firsthead)
|
||||
{
|
||||
fr->firsthead = newhead; /* _now_ it's time to store it... the first real header */
|
||||
|
@ -608,7 +615,7 @@ init_resync:
|
|||
fr->audio_start = framepos;
|
||||
/* Only check for LAME tag at beginning of whole stream
|
||||
... when there indeed is one in between, it's the user's problem. */
|
||||
if(fr->lay == 3 && check_lame_tag(fr) == 1)
|
||||
if(fr->hdr.lay == 3 && check_lame_tag(fr) == 1)
|
||||
{ /* ...in practice, Xing/LAME tags are layer 3 only. */
|
||||
if(fr->rd->forget != NULL) fr->rd->forget(fr);
|
||||
|
||||
|
@ -624,6 +631,8 @@ init_resync:
|
|||
|
||||
INT123_set_pointer(fr, 0, 0);
|
||||
|
||||
// No use of nhdr from here on. It is fr->hdr now!
|
||||
|
||||
/* Question: How bad does the floating point value get with repeated recomputation?
|
||||
Also, considering that we can play the file or parts of many times. */
|
||||
if(++fr->mean_frames != 0)
|
||||
|
@ -631,7 +640,7 @@ init_resync:
|
|||
fr->mean_framesize = ((fr->mean_frames-1)*fr->mean_framesize+INT123_compute_bpf(fr)) / fr->mean_frames ;
|
||||
}
|
||||
++fr->num; /* 0 for first frame! */
|
||||
debug4("Frame %"PRIi64" %08lx %i, next filepos=%"PRIi64, fr->num, newhead, fr->framesize, fr->rd->tell(fr));
|
||||
debug4("Frame %"PRIi64" %08lx %i, next filepos=%"PRIi64, fr->num, newhead, fr->hdr.framesize, fr->rd->tell(fr));
|
||||
if(!(fr->state_flags & FRAME_FRANKENSTEIN) && (
|
||||
(fr->track_frames > 0 && fr->num >= fr->track_frames)
|
||||
#ifdef GAPLESS
|
||||
|
@ -665,7 +674,7 @@ init_resync:
|
|||
if(fr->rd->forget != NULL) fr->rd->forget(fr);
|
||||
|
||||
fr->to_decode = fr->to_ignore = TRUE;
|
||||
if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */
|
||||
if(fr->hdr.error_protection) fr->crc = getbits(fr, 16); /* skip crc */
|
||||
|
||||
/*
|
||||
Let's check for header change after deciding that the new one is good
|
||||
|
@ -712,7 +721,6 @@ read_frame_bad:
|
|||
|
||||
fr->silent_resync = 0;
|
||||
if(fr->err == MPG123_OK) fr->err = MPG123_ERR_READER;
|
||||
fr->framesize = oldsize;
|
||||
fr->halfphase = oldphase;
|
||||
/* That return code might be inherited from some feeder action, or reader error. */
|
||||
return ret;
|
||||
|
@ -726,9 +734,9 @@ read_frame_bad:
|
|||
* <0: error codes, possibly from feeder buffer (NEED_MORE)
|
||||
* PARSE_BAD: cannot get the framesize for some reason and shall silentry try the next possible header (if this is no free format stream after all...)
|
||||
*/
|
||||
static int guess_freeformat_framesize(mpg123_handle *fr, unsigned long oldhead)
|
||||
static int guess_freeformat_framesize(mpg123_handle *fr, unsigned long oldhead, int *framesize)
|
||||
{
|
||||
long i;
|
||||
int i;
|
||||
int ret;
|
||||
unsigned long head;
|
||||
if(!(fr->rdat.flags & (READER_SEEKABLE|READER_BUFFERED)))
|
||||
|
@ -749,7 +757,7 @@ static int guess_freeformat_framesize(mpg123_handle *fr, unsigned long oldhead)
|
|||
if((head & HDR_SAMEMASK) == (oldhead & HDR_SAMEMASK))
|
||||
{
|
||||
fr->rd->back_bytes(fr,i+1);
|
||||
fr->framesize = i-3;
|
||||
*framesize = i-3;
|
||||
return PARSE_GOOD; /* Success! */
|
||||
}
|
||||
}
|
||||
|
@ -766,8 +774,13 @@ static int guess_freeformat_framesize(mpg123_handle *fr, unsigned long oldhead)
|
|||
* 0: no valid header
|
||||
* <0: some error
|
||||
* You are required to do a head_check() before calling!
|
||||
*
|
||||
* This now only operates on a frame header struct, not the full frame structure.
|
||||
* The scope is limited to parsing header information and determining the size of
|
||||
* the frame body to read. Everything else belongs into a later stage of applying
|
||||
* header information to the main decoder frame structure.
|
||||
*/
|
||||
static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeformat_count)
|
||||
static int decode_header(mpg123_handle *fr, struct frame_header *fh, unsigned long newhead, int *freeformat_count)
|
||||
{
|
||||
#ifdef DEBUG /* Do not waste cycles checking the header twice all the time. */
|
||||
if(!head_check(newhead))
|
||||
|
@ -778,43 +791,42 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeforma
|
|||
/* For some reason, the layer and sampling freq settings used to be wrapped
|
||||
in a weird conditional including MPG123_NO_RESYNC. What was I thinking?
|
||||
This information has to be consistent. */
|
||||
fr->lay = 4 - HDR_LAYER_VAL(newhead);
|
||||
fh->lay = 4 - HDR_LAYER_VAL(newhead);
|
||||
|
||||
if(HDR_VERSION_VAL(newhead) & 0x2)
|
||||
{
|
||||
fr->lsf = (HDR_VERSION_VAL(newhead) & 0x1) ? 0 : 1;
|
||||
fr->mpeg25 = 0;
|
||||
fr->sampling_frequency = HDR_SAMPLERATE_VAL(newhead) + (fr->lsf*3);
|
||||
fh->lsf = (HDR_VERSION_VAL(newhead) & 0x1) ? 0 : 1;
|
||||
fh->mpeg25 = 0;
|
||||
fh->sampling_frequency = HDR_SAMPLERATE_VAL(newhead) + (fh->lsf*3);
|
||||
}
|
||||
else
|
||||
{
|
||||
fr->lsf = 1;
|
||||
fr->mpeg25 = 1;
|
||||
fr->sampling_frequency = 6 + HDR_SAMPLERATE_VAL(newhead);
|
||||
fh->lsf = 1;
|
||||
fh->mpeg25 = 1;
|
||||
fh->sampling_frequency = 6 + HDR_SAMPLERATE_VAL(newhead);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* seen a file where this varies (old lame tag without crc, track with crc) */
|
||||
if((HDR_CRC_VAL(newhead)^0x1) != fr->error_protection) debug("changed crc bit!");
|
||||
if((HDR_CRC_VAL(newhead)^0x1) != fh->error_protection) debug("changed crc bit!");
|
||||
#endif
|
||||
fr->error_protection = HDR_CRC_VAL(newhead)^0x1;
|
||||
fr->bitrate_index = HDR_BITRATE_VAL(newhead);
|
||||
fr->padding = HDR_PADDING_VAL(newhead);
|
||||
fr->extension = HDR_PRIVATE_VAL(newhead);
|
||||
fr->mode = HDR_CHANNEL_VAL(newhead);
|
||||
fr->mode_ext = HDR_CHANEX_VAL(newhead);
|
||||
fr->copyright = HDR_COPYRIGHT_VAL(newhead);
|
||||
fr->original = HDR_ORIGINAL_VAL(newhead);
|
||||
fr->emphasis = HDR_EMPHASIS_VAL(newhead);
|
||||
fr->freeformat = !(newhead & HDR_BITRATE);
|
||||
fh->error_protection = HDR_CRC_VAL(newhead)^0x1;
|
||||
fh->bitrate_index = HDR_BITRATE_VAL(newhead);
|
||||
fh->padding = HDR_PADDING_VAL(newhead);
|
||||
fh->extension = HDR_PRIVATE_VAL(newhead);
|
||||
fh->mode = HDR_CHANNEL_VAL(newhead);
|
||||
fh->mode_ext = HDR_CHANEX_VAL(newhead);
|
||||
fh->copyright = HDR_COPYRIGHT_VAL(newhead);
|
||||
fh->original = HDR_ORIGINAL_VAL(newhead);
|
||||
fh->emphasis = HDR_EMPHASIS_VAL(newhead);
|
||||
fh->freeformat = !(newhead & HDR_BITRATE);
|
||||
|
||||
fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
|
||||
|
||||
/* we can't use tabsel_123 for freeformat, so trying to guess framesize... */
|
||||
if(fr->freeformat)
|
||||
if(fh->freeformat)
|
||||
{
|
||||
/* when we first encounter the frame with freeformat, guess framesize */
|
||||
if(fr->freeformat_framesize < 0)
|
||||
if(fh->freeformat_framesize < 0)
|
||||
{
|
||||
int ret;
|
||||
if(fr->p.flags & MPG123_NO_READAHEAD)
|
||||
|
@ -829,12 +841,12 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeforma
|
|||
if(VERBOSE3) error("You fooled me too often. Refusing to guess free format frame size _again_.");
|
||||
return PARSE_BAD;
|
||||
}
|
||||
ret = guess_freeformat_framesize(fr, newhead);
|
||||
ret = guess_freeformat_framesize(fr, newhead, &(fh->framesize));
|
||||
if(ret == PARSE_GOOD)
|
||||
{
|
||||
fr->freeformat_framesize = fr->framesize - fr->padding;
|
||||
fh->freeformat_framesize = fh->framesize - fh->padding;
|
||||
if(VERBOSE2)
|
||||
fprintf(stderr, "Note: free format frame size %li\n", fr->freeformat_framesize);
|
||||
fprintf(stderr, "Note: free format frame size %i\n", fh->freeformat_framesize);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -849,81 +861,109 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeforma
|
|||
/* freeformat should be CBR, so the same framesize can be used at the 2nd reading or later */
|
||||
else
|
||||
{
|
||||
fr->framesize = fr->freeformat_framesize + fr->padding;
|
||||
fh->framesize = fh->freeformat_framesize + fh->padding;
|
||||
}
|
||||
}
|
||||
switch(fh->lay)
|
||||
{
|
||||
#ifndef NO_LAYER1
|
||||
case 1:
|
||||
if(!fh->freeformat)
|
||||
{
|
||||
long fs = (long) tabsel_123[fh->lsf][0][fh->bitrate_index] * 12000;
|
||||
fs /= freqs[fh->sampling_frequency];
|
||||
fs = ((fs+fh->padding)<<2)-4;
|
||||
fh->framesize = (int)fs;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_LAYER2
|
||||
case 2:
|
||||
if(!fh->freeformat)
|
||||
{
|
||||
debug2("bitrate index: %i (%i)", fh->bitrate_index, tabsel_123[fh->lsf][1][fh->bitrate_index] );
|
||||
long fs = (long) tabsel_123[fh->lsf][1][fh->bitrate_index] * 144000;
|
||||
fs /= freqs[fh->sampling_frequency];
|
||||
fs += fh->padding - 4;
|
||||
fh->framesize = (int)fs;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_LAYER3
|
||||
case 3:
|
||||
if(fh->lsf)
|
||||
fh->ssize = (fh->mode == MPG_MD_MONO) ? 9 : 17;
|
||||
else
|
||||
fh->ssize = (fh->mode == MPG_MD_MONO) ? 17 : 32;
|
||||
|
||||
switch(fr->lay)
|
||||
if(fh->error_protection)
|
||||
fh->ssize += 2;
|
||||
|
||||
if(!fh->freeformat)
|
||||
{
|
||||
long fs = (long) tabsel_123[fh->lsf][2][fh->bitrate_index] * 144000;
|
||||
fs /= freqs[fh->sampling_frequency]<<(fh->lsf);
|
||||
fs += fh->padding - 4;
|
||||
fh->framesize = fs;
|
||||
}
|
||||
if(fh->framesize < fh->ssize)
|
||||
{
|
||||
if(NOQUIET)
|
||||
error2( "Frame smaller than mandatory side info (%i < %i)!"
|
||||
, fh->framesize, fh->ssize );
|
||||
return PARSE_BAD;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if(NOQUIET) error1("Layer type %i not supported in this build!", fh->lay);
|
||||
|
||||
return PARSE_BAD;
|
||||
}
|
||||
if (fh->framesize > MAXFRAMESIZE)
|
||||
{
|
||||
if(NOQUIET) error1("Frame size too big: %d", fh->framesize+4-fh->padding);
|
||||
|
||||
return PARSE_BAD;
|
||||
}
|
||||
return PARSE_GOOD;
|
||||
}
|
||||
|
||||
// Apply decoded header structure to frame struct, including
|
||||
// main decoder function pointer.
|
||||
static void apply_header(mpg123_handle *fr, struct frame_header *hdr)
|
||||
{
|
||||
// copy the whole struct, do some postprocessing
|
||||
fr->hdr = *hdr;
|
||||
fr->stereo = (fr->hdr.mode == MPG_MD_MONO) ? 1 : 2;
|
||||
switch(fr->hdr.lay)
|
||||
{
|
||||
#ifndef NO_LAYER1
|
||||
case 1:
|
||||
fr->spf = 384;
|
||||
fr->do_layer = INT123_do_layer1;
|
||||
if(!fr->freeformat)
|
||||
{
|
||||
long fs = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
|
||||
fs /= freqs[fr->sampling_frequency];
|
||||
fs = ((fs+fr->padding)<<2)-4;
|
||||
fr->framesize = (int)fs;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_LAYER2
|
||||
case 2:
|
||||
fr->spf = 1152;
|
||||
fr->do_layer = INT123_do_layer2;
|
||||
if(!fr->freeformat)
|
||||
{
|
||||
debug2("bitrate index: %i (%i)", fr->bitrate_index, tabsel_123[fr->lsf][1][fr->bitrate_index] );
|
||||
long fs = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
|
||||
fs /= freqs[fr->sampling_frequency];
|
||||
fs += fr->padding - 4;
|
||||
fr->framesize = (int)fs;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_LAYER3
|
||||
case 3:
|
||||
fr->spf = fr->lsf ? 576 : 1152; /* MPEG 2.5 implies LSF.*/
|
||||
fr->spf = fr->hdr.lsf ? 576 : 1152; /* MPEG 2.5 implies LSF.*/
|
||||
fr->do_layer = INT123_do_layer3;
|
||||
if(fr->lsf)
|
||||
fr->ssize = (fr->stereo == 1) ? 9 : 17;
|
||||
else
|
||||
fr->ssize = (fr->stereo == 1) ? 17 : 32;
|
||||
|
||||
if(fr->error_protection)
|
||||
fr->ssize += 2;
|
||||
|
||||
if(!fr->freeformat)
|
||||
{
|
||||
long fs = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
|
||||
fs /= freqs[fr->sampling_frequency]<<(fr->lsf);
|
||||
fs += fr->padding - 4;
|
||||
fr->framesize = fs;
|
||||
}
|
||||
if(fr->framesize < fr->ssize)
|
||||
{
|
||||
if(NOQUIET)
|
||||
error2( "Frame smaller than mandatory side info (%i < %i)!"
|
||||
, fr->framesize, fr->ssize );
|
||||
return PARSE_BAD;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if(NOQUIET) error1("Layer type %i not supported in this build!", fr->lay);
|
||||
|
||||
return PARSE_BAD;
|
||||
// No error checking/message here, been done in decode_header().
|
||||
fr->spf = 0;
|
||||
fr->do_layer = NULL;
|
||||
}
|
||||
if (fr->framesize > MAXFRAMESIZE)
|
||||
{
|
||||
if(NOQUIET) error1("Frame size too big: %d", fr->framesize+4-fr->padding);
|
||||
|
||||
return PARSE_BAD;
|
||||
}
|
||||
return PARSE_GOOD;
|
||||
}
|
||||
|
||||
|
||||
/* Prepare for bit reading. Two stages:
|
||||
0. Layers 1 and 2, side info for layer 3
|
||||
1. Second call for possible bit reservoir for layer 3 part 2,3.
|
||||
|
@ -935,26 +975,26 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeforma
|
|||
void INT123_set_pointer(mpg123_handle *fr, int part2, long backstep)
|
||||
{
|
||||
fr->bitindex = 0;
|
||||
if(fr->lay == 3)
|
||||
if(fr->hdr.lay == 3)
|
||||
{
|
||||
if(part2)
|
||||
{
|
||||
fr->wordpointer = fr->bsbuf + fr->ssize - backstep;
|
||||
fr->wordpointer = fr->bsbuf + fr->hdr.ssize - backstep;
|
||||
if(backstep)
|
||||
memcpy( fr->wordpointer, fr->bsbufold+fr->fsizeold-backstep
|
||||
, backstep );
|
||||
fr->bits_avail = (long)(fr->framesize - fr->ssize + backstep)*8;
|
||||
fr->bits_avail = (long)(fr->hdr.framesize - fr->hdr.ssize + backstep)*8;
|
||||
}
|
||||
else
|
||||
{
|
||||
fr->wordpointer = fr->bsbuf;
|
||||
fr->bits_avail = fr->ssize*8;
|
||||
fr->bits_avail = fr->hdr.ssize*8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fr->wordpointer = fr->bsbuf;
|
||||
fr->bits_avail = fr->framesize*8;
|
||||
fr->bits_avail = fr->hdr.framesize*8;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -962,7 +1002,7 @@ void INT123_set_pointer(mpg123_handle *fr, int part2, long backstep)
|
|||
|
||||
double INT123_compute_bpf(mpg123_handle *fr)
|
||||
{
|
||||
return (fr->framesize > 0) ? fr->framesize + 4.0 : 1.0;
|
||||
return (fr->hdr.framesize > 0) ? fr->hdr.framesize + 4.0 : 1.0;
|
||||
}
|
||||
|
||||
int attribute_align_arg mpg123_spf(mpg123_handle *mh)
|
||||
|
@ -978,8 +1018,8 @@ double attribute_align_arg mpg123_tpf(mpg123_handle *fr)
|
|||
double tpf;
|
||||
if(fr == NULL || !fr->firsthead) return MPG123_ERR;
|
||||
|
||||
tpf = (double) bs[fr->lay];
|
||||
tpf /= freqs[fr->sampling_frequency] << (fr->lsf);
|
||||
tpf = (double) bs[fr->hdr.lay];
|
||||
tpf /= freqs[fr->hdr.sampling_frequency] << (fr->hdr.lsf);
|
||||
return tpf;
|
||||
}
|
||||
|
||||
|
@ -1046,7 +1086,7 @@ int attribute_align_arg mpg123_position64(mpg123_handle *fr, int64_t no, int64_t
|
|||
}
|
||||
|
||||
/* first attempt of read ahead check to find the real first header; cannot believe what junk is out there! */
|
||||
static int do_readahead(mpg123_handle *fr, unsigned long newhead)
|
||||
static int do_readahead(mpg123_handle *fr, struct frame_header *nhdr, unsigned long newhead)
|
||||
{
|
||||
unsigned long nexthead = 0;
|
||||
int hd = 0;
|
||||
|
@ -1058,9 +1098,9 @@ static int do_readahead(mpg123_handle *fr, unsigned long newhead)
|
|||
|
||||
start = fr->rd->tell(fr);
|
||||
|
||||
debug2("doing ahead check with BPF %d at %"PRIi64, fr->framesize+4, start);
|
||||
debug2("doing ahead check with BPF %d at %"PRIi64, nhdr->framesize+4, start);
|
||||
/* step framesize bytes forward and read next possible header*/
|
||||
if((oret=fr->rd->skip_bytes(fr, fr->framesize))<0)
|
||||
if((oret=fr->rd->skip_bytes(fr, nhdr->framesize))<0)
|
||||
{
|
||||
if(oret==READER_ERROR && NOQUIET) error("cannot seek!");
|
||||
|
||||
|
@ -1195,7 +1235,7 @@ static int forget_head_shift(mpg123_handle *fr, unsigned long *newheadp, int for
|
|||
}
|
||||
|
||||
/* watch out for junk/tags on beginning of stream by invalid header */
|
||||
static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount)
|
||||
static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount, struct frame_header *nhdr)
|
||||
{
|
||||
int ret;
|
||||
int freeformat_count = 0;
|
||||
|
@ -1251,7 +1291,7 @@ static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount
|
|||
if(++forgetcount > FORGET_INTERVAL) forgetcount = 0;
|
||||
if((ret=forget_head_shift(fr, &newhead, !forgetcount))<=0) return ret;
|
||||
|
||||
if(head_check(newhead) && (ret=decode_header(fr, newhead, &freeformat_count))) break;
|
||||
if(head_check(newhead) && (ret=decode_header(fr, nhdr, newhead, &freeformat_count))) break;
|
||||
} while(1);
|
||||
if(ret<0) return ret;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
// only single spaces as separator to ease parsing by build scripts
|
||||
#define MPG123_MAJOR 1
|
||||
#define MPG123_MINOR 32
|
||||
#define MPG123_PATCH 7
|
||||
#define MPG123_PATCH 9
|
||||
// Don't get too wild with that to avoid confusing m4. No brackets.
|
||||
// Also, it should fit well into a sane file name for the tarball.
|
||||
#define MPG123_SUFFIX ""
|
||||
|
|
|
@ -2338,7 +2338,7 @@ Description="Device mounting service"
|
|||
DisplayName="Mount Manager"
|
||||
ServiceBinary="%12%\mountmgr.sys"
|
||||
ServiceType=1
|
||||
StartType=2
|
||||
StartType=0
|
||||
ErrorControl=1
|
||||
LoadOrderGroup="System Bus Extender"
|
||||
|
||||
|
|
BIN
nls/locale.nls
generated
BIN
nls/locale.nls
generated
Binary file not shown.
4
po/lt.po
4
po/lt.po
|
@ -5,7 +5,7 @@ msgstr ""
|
|||
"Project-Id-Version: Wine\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.winehq.org\n"
|
||||
"POT-Creation-Date: N/A\n"
|
||||
"PO-Revision-Date: 2024-11-08 00:18+0200\n"
|
||||
"PO-Revision-Date: 2024-11-13 23:36+0200\n"
|
||||
"Last-Translator: Aurimas Fišeras <aurimas@members.fsf.org>\n"
|
||||
"Language-Team: Lithuanian <komp_lt@konf.lt>\n"
|
||||
"Language: lt\n"
|
||||
|
@ -3166,7 +3166,7 @@ msgstr "&Atkurti"
|
|||
|
||||
#: dlls/desk.cpl/desk.rc:42
|
||||
msgid "Emulate display mode changes (requires restart)"
|
||||
msgstr ""
|
||||
msgstr "Emuliuoti rodymo veiksenos pakeitimus (reikia perleisti)"
|
||||
|
||||
#: dlls/desk.cpl/desk.rc:29
|
||||
msgid "Display Settings"
|
||||
|
|
|
@ -39,7 +39,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(explorer);
|
|||
#define DESKTOP_CLASS_ATOM ((LPCWSTR)MAKEINTATOM(32769))
|
||||
#define DESKTOP_ALL_ACCESS 0x01ff
|
||||
|
||||
static const WCHAR default_driver[] = {'m','a','c',',','x','1','1',0};
|
||||
static const WCHAR default_driver[] = L"mac,x11,wayland";
|
||||
|
||||
static BOOL using_root = TRUE;
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue