summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO24
-rw-r--r--PKGBUILD51
-rw-r--r--nine-1.8.patch (renamed from nine-1.8rc2.patch)449
-rw-r--r--sni_support.patch2010
4 files changed, 20 insertions, 2514 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 75559fc27e59..e52761813e53 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,8 +1,8 @@
# Generated by mksrcinfo v8
-# Sat Dec 19 10:26:08 UTC 2015
+# Wed Dec 23 13:01:48 UTC 2015
pkgbase = wine-gaming-nine
pkgdesc = Based off wine-staging, including the gallium-nine patches and some more hacks
- pkgver = 1.8rc4
+ pkgver = 1.8
pkgrel = 1
url = http://www.wine-staging.com
install = wine.install
@@ -15,8 +15,8 @@ pkgbase = wine-gaming-nine
makedepends = perl
makedepends = fontforge
makedepends = flex
- makedepends = gcc>=4.5.0-2
- makedepends = gcc-multilib>=4.5.0-2
+ makedepends = gcc>=5.3.0-3
+ makedepends = gcc-multilib>=5.3.0-3
makedepends = giflib
makedepends = lib32-giflib
makedepends = libpng
@@ -130,31 +130,29 @@ pkgbase = wine-gaming-nine
optdepends = cups
optdepends = samba
optdepends = dosbox
- provides = wine=1.8rc4
- provides = wine-wow64=1.8rc4
- provides = wine-staging=1.8rc4
+ provides = wine=1.8
+ provides = wine-wow64=1.8
+ provides = wine-staging=1.8
conflicts = wine
conflicts = wine-wow64
conflicts = wine-staging
options = staticlibs
- source = https://github.com/wine-compholio/wine-patched/archive/staging-1.8-rc4.tar.gz
+ source = https://github.com/wine-compholio/wine-patched/archive/staging-1.8.tar.gz
source = 30-win32-aliases.conf
source = hd7700m_support.patch
source = heap_perf.patch
source = keybindings.patch
source = mipmap.patch
- source = nine-1.8rc2.patch
- source = sni_support.patch
+ source = nine-1.8.patch
source = steam.patch
source = wbemprox_query_v2.patch
- sha1sums = 7d42649e4574056ba71c6c3fff82bf1fad492eb9
+ sha1sums = 6aea600b850ac2ac4fed608d96c688c8d470222f
sha1sums = 023a5c901c6a091c56e76b6a62d141d87cce9fdb
sha1sums = 8fa4b03f68f18b4de80f10c7a43c0e99a5cb017c
sha1sums = 0f4ac455436d5714a2cf0b537ed25f4fa5c1a7fd
sha1sums = f3febb8836f38320742a546c667106608d4c4395
sha1sums = c3096fccbac23e520d03f592db7f23350cbbc0bc
- sha1sums = 2ef0002b9db25f6014cca83c5176e3fad60e4233
- sha1sums = 8193eadee7de2a4d89abe7ca8dff43e877878a52
+ sha1sums = a5832a96432979b6fc18019f931f80e4d3ecc240
sha1sums = a7da16c5fac7d74c665e7a76bddbcd6c8333830b
sha1sums = e26d369e9964657b481ac4b7b18c575786ec9c8c
diff --git a/PKGBUILD b/PKGBUILD
index c808d5e1f80f..4ff7d7b40c81 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -6,12 +6,11 @@
# -Keybind patch reversion
# -Heap allocation perfomance improvement patch
# -Wbemprox videocontroller query fix v2 (see https://bugs.winehq.org/show_bug.cgi?id=38879 )
-# -SNI support (see https://bugs.winehq.org/show_bug.cgi?id=38409 )
# -Steam patch, Crossover Hack version (see https://bugs.winehq.org/show_bug.cgi?id=39403 )
# -HD7700M support (not referenced in Wine)
pkgname=wine-gaming-nine
-pkgver=1.8rc4
+pkgver=1.8
pkgrel=1
_pkgbasever=${pkgver/rc/-rc}
@@ -23,19 +22,17 @@ source=("https://github.com/wine-compholio/wine-patched/archive/staging-$_pkgbas
heap_perf.patch
keybindings.patch
mipmap.patch
- nine-1.8rc2.patch
- sni_support.patch
+ nine-1.8.patch
steam.patch
wbemprox_query_v2.patch
)
-sha1sums=('7d42649e4574056ba71c6c3fff82bf1fad492eb9'
+sha1sums=('6aea600b850ac2ac4fed608d96c688c8d470222f'
'023a5c901c6a091c56e76b6a62d141d87cce9fdb'
'8fa4b03f68f18b4de80f10c7a43c0e99a5cb017c'
'0f4ac455436d5714a2cf0b537ed25f4fa5c1a7fd'
'f3febb8836f38320742a546c667106608d4c4395'
'c3096fccbac23e520d03f592db7f23350cbbc0bc'
- '2ef0002b9db25f6014cca83c5176e3fad60e4233'
- '8193eadee7de2a4d89abe7ca8dff43e877878a52'
+ 'a5832a96432979b6fc18019f931f80e4d3ecc240'
'a7da16c5fac7d74c665e7a76bddbcd6c8333830b'
'e26d369e9964657b481ac4b7b18c575786ec9c8c'
)
@@ -66,7 +63,7 @@ _depends=(
)
makedepends=(autoconf ncurses bison perl fontforge flex
- 'gcc>=4.5.0-2' 'gcc-multilib>=4.5.0-2'
+ 'gcc>=5.3.0-3' 'gcc-multilib>=5.3.0-3'
giflib lib32-giflib
libpng lib32-libpng
gnutls lib32-gnutls
@@ -131,44 +128,15 @@ else
conflicts=('wine' 'wine-wow64' 'wine-staging')
fi
-#Needed for testing gcc version
-check_gcc()
-{
- curver=($(gcc -dumpversion | sed 's/\./ /g'))
- minver=(5 3 0)
-
- for ((i=${#curver[@]}; i<${#minver[@]}; i++))
- do
- curver[i]=0
- done
-
- for ((i=0; i<${#curver[@]}; i++))
- do
- if [[ -z ${minver[i]} ]]
- then
- minver[i]=0
- fi
-
- if [ "${curver[i]}" -lt "${minver[i]}" ]; then
- return 1
- elif [ "${curver[i]}" -gt "${minver[i]}" ]; then
- return 0
- fi
- done
-
- return 0
-}
-
prepare()
{
cd wine-patched-staging-$_pkgbasever
- patch -p1 < ../nine-1.8rc2.patch
+ patch -p1 < ../nine-1.8.patch
patch -p1 < ../steam.patch
patch -p1 < ../mipmap.patch
patch -p1 < ../heap_perf.patch
patch -p1 < ../wbemprox_query_v2.patch
- patch -p1 < ../sni_support.patch
patch -p1 < ../hd7700m_support.patch
patch -p1 -R < ../keybindings.patch
@@ -177,13 +145,6 @@ prepare()
sed 's|OpenCL/opencl.h|CL/opencl.h|g' -i configure*
- if [ ! check_gcc ]; then
- # https://bugs.winehq.org/show_bug.cgi?id=38653 fixed sinced GCC 5.3.0
- echo "GCC Version <5.3.0 detected, using -O0 flag... You should upgrade!"
- export CFLAGS="${CFLAGS/-O2/} -O0"
- export CXXFLAGS="${CXXFLAGS/-O2/} -O0"
- fi
-
# These additional CPPFLAGS solve FS#27662 and FS#34195
export CPPFLAGS="${CPPFLAGS/-D_FORTIFY_SOURCE=2/} -D_FORTIFY_SOURCE=0"
diff --git a/nine-1.8rc2.patch b/nine-1.8.patch
index 8dbfe8614cb3..2f001ac3e5fe 100644
--- a/nine-1.8rc2.patch
+++ b/nine-1.8.patch
@@ -1,5 +1,5 @@
diff --git a/configure b/configure
-index 5ecd109..be2483f 100755
+index f52c979..ce20dab 100755
--- a/configure
+++ b/configure
@@ -681,6 +681,8 @@ XSLT_LIBS
@@ -734,7 +734,7 @@ index 5ecd109..be2483f 100755
wine_fn_config_dll d3dcompiler_34 enable_d3dcompiler_34
wine_fn_config_dll d3dcompiler_35 enable_d3dcompiler_35
diff --git a/configure.ac b/configure.ac
-index c548352..428e9ba 100644
+index aa829be..5b18b0a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -67,6 +67,8 @@ AC_ARG_WITH(openal, AS_HELP_STRING([--without-openal],[do not use OpenAL]),
@@ -809,34 +809,6 @@ index c548352..428e9ba 100644
WINE_CONFIG_DLL(d3dcompiler_33)
WINE_CONFIG_DLL(d3dcompiler_34)
WINE_CONFIG_DLL(d3dcompiler_35)
-diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
-index 8b98e4a..d6b2382 100644
---- a/dlls/advapi32/tests/security.c
-+++ b/dlls/advapi32/tests/security.c
-@@ -3448,7 +3448,6 @@ static void test_CreateDirectoryA(void)
- ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
- bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
- ok(bret, "GetAclInformation failed\n");
-- todo_wine
- ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
- acl_size.AceCount);
- LocalFree(pSD);
-@@ -3507,6 +3506,7 @@ static void test_CreateDirectoryA(void)
- ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
- bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
- ok(bret, "GetAclInformation failed\n");
-+ todo_wine
- ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
- acl_size.AceCount);
- LocalFree(pSD);
-@@ -3593,7 +3593,6 @@ static void test_CreateDirectoryA(void)
- ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
- bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
- ok(bret, "GetAclInformation failed\n");
-- todo_wine
- ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
- acl_size.AceCount);
- LocalFree(pSD);
diff --git a/dlls/d3d9/Makefile.in b/dlls/d3d9/Makefile.in
index 1c05f5a..dc06d68 100644
--- a/dlls/d3d9/Makefile.in
@@ -849,421 +821,6 @@ index 1c05f5a..dc06d68 100644
C_SRCS = \
buffer.c \
-diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c
-index 151db41..5314915 100644
---- a/dlls/d3d9/tests/d3d9ex.c
-+++ b/dlls/d3d9/tests/d3d9ex.c
-@@ -1410,6 +1410,7 @@ static void test_lost_device(void)
- HRESULT hr;
- BOOL ret;
- struct device_desc desc;
-+ IDirect3DSwapChain9 *swapchain;
-
- window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
- 0, 0, 640, 480, NULL, NULL, NULL, NULL);
-@@ -1434,6 +1435,12 @@ static void test_lost_device(void)
- hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
- ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
-
-+ hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
-+ ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
-+ hr = IDirect3DSwapChain9_Present(swapchain, NULL, NULL, NULL, NULL, 0);
-+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
-+ IDirect3DSwapChain9_Release(swapchain);
-+
- ret = SetForegroundWindow(GetDesktopWindow());
- ok(ret, "Failed to set foreground window.\n");
- hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
-@@ -1447,6 +1454,12 @@ static void test_lost_device(void)
- hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
- ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
-
-+ hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
-+ ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
-+ hr = IDirect3DSwapChain9_Present(swapchain, NULL, NULL, NULL, NULL, 0);
-+ ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
-+ IDirect3DSwapChain9_Release(swapchain);
-+
- ret = SetForegroundWindow(window);
- ok(ret, "Failed to set foreground window.\n");
- hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
-@@ -1460,6 +1473,12 @@ static void test_lost_device(void)
- hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
- ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
-
-+ hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
-+ ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
-+ hr = IDirect3DSwapChain9_Present(swapchain, NULL, NULL, NULL, NULL, 0);
-+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
-+ IDirect3DSwapChain9_Release(swapchain);
-+
- desc.width = 1024;
- desc.height = 768;
- hr = reset_device(device, &desc);
-@@ -1489,6 +1508,12 @@ static void test_lost_device(void)
- hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
- todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
-
-+ hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
-+ ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
-+ hr = IDirect3DSwapChain9_Present(swapchain, NULL, NULL, NULL, NULL, 0);
-+ ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
-+ IDirect3DSwapChain9_Release(swapchain);
-+
- hr = reset_device(device, &desc);
- ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
- hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
-@@ -1502,6 +1527,12 @@ static void test_lost_device(void)
- hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
- ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
-
-+ hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
-+ ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
-+ hr = IDirect3DSwapChain9_Present(swapchain, NULL, NULL, NULL, NULL, 0);
-+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
-+ IDirect3DSwapChain9_Release(swapchain);
-+
- ret = SetForegroundWindow(GetDesktopWindow());
- ok(ret, "Failed to set foreground window.\n");
- hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
-diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
-index 5579826..2cdf584 100644
---- a/dlls/d3d9/tests/device.c
-+++ b/dlls/d3d9/tests/device.c
-@@ -8229,10 +8229,10 @@ done:
-
- static void test_vidmem_accounting(void)
- {
-- IDirect3DDevice9 *device;
-+ IDirect3DDevice9 *device, *device2;
- IDirect3D9 *d3d9;
- ULONG refcount;
-- HWND window;
-+ HWND window, window2;
- HRESULT hr = D3D_OK;
- IDirect3DTexture9 *textures[20];
- unsigned int i;
-@@ -8240,6 +8240,8 @@ static void test_vidmem_accounting(void)
-
- window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
- 0, 0, 640, 480, 0, 0, 0, 0);
-+ window2 = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
-+ 0, 0, 640, 480, 0, 0, 0, 0);
- d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
- ok(!!d3d9, "Failed to create a D3D object.\n");
- if (!(device = create_device(d3d9, window, NULL)))
-@@ -8274,6 +8276,43 @@ static void test_vidmem_accounting(void)
- IDirect3DTexture9_Release(textures[i]);
- }
-
-+ /* Multi-device testing */
-+ if (!(device2 = create_device(d3d9, window2, NULL)))
-+ {
-+ skip("Failed to create a D3D device, skipping tests.\n");
-+ refcount = IDirect3DDevice9_Release(device);
-+ ok(!refcount, "Device has %u references left.\n", refcount);
-+ IDirect3D9_Release(d3d9);
-+ DestroyWindow(window2);
-+ DestroyWindow(window);
-+ return;
-+ }
-+
-+ vidmem_start = IDirect3DDevice9_GetAvailableTextureMem(device);
-+ memset(textures, 0, sizeof(textures));
-+ for (i = 0; (i < sizeof(textures) / sizeof(*textures)) && SUCCEEDED(hr); i++)
-+ {
-+ hr = IDirect3DDevice9_CreateTexture(device2, 1024, 1024, 1, D3DUSAGE_RENDERTARGET,
-+ D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &textures[i], NULL);
-+ /* D3DERR_OUTOFVIDEOMEMORY is returned when the card runs out of video memory
-+ * E_FAIL is returned on address space or system memory exhaustion */
-+ ok(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY,
-+ "Failed to create texture, hr %#x.\n", hr);
-+ }
-+ vidmem_end = IDirect3DDevice9_GetAvailableTextureMem(device);
-+
-+ /* Windows 7 uses device private counters */
-+ ok(vidmem_start > vidmem_end || broken(vidmem_start == vidmem_end), "Expected available texture memory to decrease during texture creation.\n");
-+ diff = vidmem_start - vidmem_end;
-+ ok(diff > 1024 * 1024 * 2 * i || broken(diff == 0), "Expected a video memory difference of at least %u MB, got %u MB.\n",
-+ 2 * i, diff / 1024 / 1024);
-+
-+ for (i = 0; i < sizeof(textures) / sizeof(*textures); i++)
-+ {
-+ if (textures[i])
-+ IDirect3DTexture9_Release(textures[i]);
-+ }
-+
- refcount = IDirect3DDevice9_Release(device);
- ok(!refcount, "Device has %u references left.\n", refcount);
- IDirect3D9_Release(d3d9);
-@@ -9999,6 +10038,7 @@ static void test_lost_device(void)
- HWND window;
- HRESULT hr;
- BOOL ret;
-+ IDirect3DSwapChain9 *swapchain;
-
- window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
- 0, 0, 640, 480, NULL, NULL, NULL, NULL);
-@@ -10026,6 +10066,12 @@ static void test_lost_device(void)
- hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
- ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
-
-+ hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
-+ ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
-+ hr = IDirect3DSwapChain9_Present(swapchain, NULL, NULL, NULL, NULL, 0);
-+ ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
-+ IDirect3DSwapChain9_Release(swapchain);
-+
- ret = ShowWindow(window, SW_RESTORE);
- ok(ret, "Failed to restore window.\n");
- ret = SetForegroundWindow(window);
-@@ -10035,6 +10081,12 @@ static void test_lost_device(void)
- hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
- ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
-
-+ hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
-+ ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
-+ hr = IDirect3DSwapChain9_Present(swapchain, NULL, NULL, NULL, NULL, 0);
-+ ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
-+ IDirect3DSwapChain9_Release(swapchain);
-+
- hr = reset_device(device, &device_desc);
- ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
- hr = IDirect3DDevice9_TestCooperativeLevel(device);
-@@ -10042,6 +10094,12 @@ static void test_lost_device(void)
- hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
- ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
-
-+ hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
-+ ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
-+ hr = IDirect3DSwapChain9_Present(swapchain, NULL, NULL, NULL, NULL, 0);
-+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
-+ IDirect3DSwapChain9_Release(swapchain);
-+
- device_desc.flags = 0;
- hr = reset_device(device, &device_desc);
- ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
-diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
-index 6fe9e56..99adde0 100644
---- a/dlls/d3d9/tests/visual.c
-+++ b/dlls/d3d9/tests/visual.c
-@@ -8539,6 +8539,167 @@ done:
- DestroyWindow(window);
- }
-
-+static void test_blend_invalid_arg(void)
-+{
-+ IDirect3DSurface9 *backbuffer, *offscreen;
-+ IDirect3DTexture9 *offscreenTexture;
-+ IDirect3DDevice9 *device;
-+ IDirect3D9 *d3d;
-+ D3DCOLOR color;
-+ ULONG refcount;
-+ HWND window;
-+ HRESULT hr;
-+ DWORD rs;
-+
-+ static const struct
-+ {
-+ struct vec3 position;
-+ DWORD diffuse;
-+ }
-+ quad1[] =
-+ {
-+ {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
-+ {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
-+ {{ 0.0f, -1.0f, 0.1f}, 0x4000ff00},
-+ {{ 0.0f, 0.0f, 0.1f}, 0x4000ff00},
-+ },
-+ quad2[] =
-+ {
-+ {{ 0.0f, 0.0f, 0.1f}, 0x4000ff00},
-+ {{ 0.0f, 1.0f, 0.1f}, 0x4000ff00},
-+ {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
-+ {{ 1.0f, 1.0f, 0.1f}, 0x4000ff00},
-+ },
-+ quad3[] =
-+ {
-+ {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
-+ {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
-+ {{ 0.0f, 0.0f, 0.1f}, 0xc00000ff},
-+ {{ 0.0f, 1.0f, 0.1f}, 0xc00000ff},
-+ },
-+ quad4[] =
-+ {
-+ {{ 0.0f, -1.0f, 0.1f}, 0xc00000ff},
-+ {{ 0.0f, 0.0f, 0.1f}, 0xc00000ff},
-+ {{ 1.0f, -1.0f, 0.1f}, 0xc00000ff},
-+ {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
-+ };
-+
-+ window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
-+ 0, 0, 640, 480, NULL, NULL, NULL, NULL);
-+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
-+ ok(!!d3d, "Failed to create a D3D object.\n");
-+ if (!(device = create_device(d3d, window, window, TRUE)))
-+ {
-+ skip("Failed to create a D3D device, skipping tests.\n");
-+ goto done;
-+ }
-+ /* Clear the render target with alpha = 0.5 */
-+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
-+ ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
-+
-+ hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
-+ D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
-+ ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
-+
-+ hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
-+ ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
-+
-+ hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
-+ ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
-+
-+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
-+ ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
-+
-+ hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
-+ ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
-+ hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
-+ ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
-+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
-+ ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
-+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
-+ ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
-+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
-+ ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
-+
-+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
-+ ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
-+ hr = IDirect3DDevice9_BeginScene(device);
-+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
-+
-+ /* draw quad to test default renderstate
-+ * expect D3DRS_SRCBLEND == D3DBLEND_ONE
-+ * expect D3DRS_DESTBLEND == D3DBLEND_ZERO */
-+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
-+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
-+
-+ /* set invalid value and expect D3DBLEND_ZERO instead */
-+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, 0);
-+ ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
-+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_SRCBLEND, &rs);
-+ ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
-+ ok(rs == 0, "Unexpected renderstate %#x.\n", rs);
-+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
-+ ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
-+
-+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
-+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
-+ /* set non default valid values */
-+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
-+ ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
-+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_SRCBLEND, &rs);
-+ ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
-+ ok(rs == D3DBLEND_SRCALPHA, "Unexpected renderstate %#x.\n", rs);
-+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
-+ ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
-+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_DESTBLEND, &rs);
-+ ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
-+ ok(rs == D3DBLEND_INVSRCALPHA, "Failed to get render state, hr %#x.\n", hr);
-+
-+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
-+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
-+
-+ /* set invalid value and expect D3DBLEND_ZERO instead */
-+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, 200);
-+ ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
-+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_DESTBLEND, &rs);
-+ ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
-+ ok(rs == 200, "Failed to get render state, hr %#x.\n", hr);
-+
-+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
-+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
-+
-+ hr = IDirect3DDevice9_EndScene(device);
-+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
-+
-+ color = getPixelColor(device, 160, 360);
-+ ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
-+ "D3DRS_SRCBLEND ONE returned color %08x, expected 0x0000FF00\n", color);
-+
-+ color = getPixelColor(device, 480, 120);
-+ ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x00, 0x00), 1),
-+ "invalid D3DRS_SRCBLEND returned color %08x, expected 0x00bf0000\n", color);
-+
-+ color = getPixelColor(device, 160, 120);
-+ ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x3f, 0x00, 0xC0), 1),
-+ "D3DRS_SRCBLEND SRCALPHA returned color %08x, expected 0x003f00C0\n", color);
-+
-+ color = getPixelColor(device, 480, 360);
-+ ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xC0), 1),
-+ "invalid D3DRS_DESTBLEND returned color %08x, expected 0x000000C0\n", color);
-+
-+ IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
-+
-+ IDirect3DSurface9_Release(backbuffer);
-+ IDirect3DTexture9_Release(offscreenTexture);
-+ IDirect3DSurface9_Release(offscreen);
-+ refcount = IDirect3DDevice9_Release(device);
-+ ok(!refcount, "Device has %u references left.\n", refcount);
-+done:
-+ IDirect3D9_Release(d3d);
-+ DestroyWindow(window);
-+}
-+
- static void fixed_function_decl_test(void)
- {
- IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
-@@ -12738,6 +12899,9 @@ static void alphatest_test(void)
- }
- testdata[] =
- {
-+ /* test invalid values, D3DCMP_NEVER for values less than D3DCMP_NEVER,
-+ * D3DCMP_ALWAYS for values greater than D3DCMP_ALWAYS */
-+ {D3DCMP_NEVER-1, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
- {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
- {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
- {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
-@@ -12746,6 +12910,10 @@ static void alphatest_test(void)
- {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
- {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
- {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
-+ {D3DCMP_ALWAYS+1, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
-+ {D3DCMP_ALWAYS+2, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
-+ {D3DCMP_ALWAYS+3, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
-+ {0xdeadbeef, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
- };
- static const struct
- {
-@@ -18095,6 +18263,27 @@ static void test_negative_fixedfunction_fog(void)
- D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
- {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
- D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
-+ /* test invalid values, expect a modulo 4 on samplerstate */
-+ {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
-+ D3DFOG_LINEAR+1, D3DFOG_NONE, 0x0000ff00, 0x009b6400, 0x009b6400},
-+ {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
-+ D3DFOG_LINEAR+2, D3DFOG_NONE, 0x00c73800, 0x009b6400, 0x009b6400},
-+ {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
-+ D3DFOG_LINEAR+3, D3DFOG_NONE, 0x00c73800, 0x009b6400, 0x009b6400},
-+ {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
-+ D3DFOG_LINEAR+4, D3DFOG_NONE, 0x007f7f00, 0x009b6400, 0x009b6400},
-+ {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
-+ D3DFOG_LINEAR+5, D3DFOG_NONE, 0x0000ff00, 0x009b6400, 0x009b6400},
-+ {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
-+ D3DFOG_LINEAR+6, D3DFOG_NONE, 0x00c73800, 0x009b6400, 0x009b6400},
-+ {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
-+ D3DFOG_LINEAR+7, D3DFOG_NONE, 0x00c73800, 0x009b6400, 0x009b6400},
-+ {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
-+ D3DFOG_LINEAR+8, D3DFOG_NONE, 0x007f7f00, 0x009b6400, 0x009b6400},
-+ {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
-+ D3DFOG_LINEAR+9, D3DFOG_NONE, 0x0000ff00, 0x009b6400, 0x009b6400},
-+ {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
-+ D3DFOG_LINEAR+10, D3DFOG_NONE, 0x00c73800, 0x009b6400, 0x009b6400},
- };
- D3DCAPS9 caps;
-
diff --git a/dlls/d3d9-nine/Makefile.in b/dlls/d3d9-nine/Makefile.in
new file mode 100644
index 0000000..a761cd7
@@ -5411,7 +4968,7 @@ index 81a4e24..96bc9a4 100644
break;
}
diff --git a/programs/winecfg/winecfg.rc b/programs/winecfg/winecfg.rc
-index a9c62ae..cbde6aa 100644
+index e2b35a2..7b444d0 100644
--- a/programs/winecfg/winecfg.rc
+++ b/programs/winecfg/winecfg.rc
@@ -320,6 +320,8 @@ BEGIN
diff --git a/sni_support.patch b/sni_support.patch
deleted file mode 100644
index ff801058af2d..000000000000
--- a/sni_support.patch
+++ /dev/null
@@ -1,2010 +0,0 @@
-@@ -, +, @@
----
- dlls/winex11.drv/Makefile.in | 3 +-
- dlls/winex11.drv/systray.c | 56 +-
- dlls/winex11.drv/systray.h | 77 ++
- dlls/winex11.drv/systray_dbus.c | 1814 +++++++++++++++++++++++++++++++++++++++
- 4 files changed, 1921 insertions(+), 29 deletions(-)
- create mode 100644 dlls/winex11.drv/systray.h
- create mode 100644 dlls/winex11.drv/systray_dbus.c
---- a/dlls/winex11.drv/Makefile.in
-+++ a/dlls/winex11.drv/Makefile.in
-@@ -1,7 +1,7 @@
- MODULE = winex11.drv
- IMPORTS = uuid user32 gdi32 advapi32
- DELAYIMPORTS = comctl32 ole32 shell32 imm32
--EXTRAINCL = $(X_CFLAGS)
-+EXTRAINCL = $(X_CFLAGS) $(DBUS_CFLAGS)
- EXTRALIBS = $(X_LIBS) $(X_EXTRA_LIBS)
-
- C_SRCS = \
-@@ -20,6 +20,7 @@ C_SRCS = \
- pen.c \
- settings.c \
- systray.c \
-+ systray_dbus.c \
- window.c \
- wintab.c \
- x11drv_main.c \
---- a/dlls/winex11.drv/systray.c
-+++ a/dlls/winex11.drv/systray.c
-@@ -44,28 +44,10 @@
- #include "wine/list.h"
- #include "wine/debug.h"
-
--WINE_DEFAULT_DEBUG_CHANNEL(systray);
-+#include "systray.h"
-
--/* an individual systray icon */
--struct tray_icon
--{
-- struct list entry;
-- HICON image; /* the image to render */
-- HWND owner; /* the HWND passed in to the Shell_NotifyIcon call */
-- HWND window; /* the adaptor window */
-- BOOL layered; /* whether we are using a layered window */
-- HWND tooltip; /* Icon tooltip */
-- UINT state; /* state flags */
-- UINT id; /* the unique id given by the app */
-- UINT callback_message;
-- int display; /* display index, or -1 if hidden */
-- WCHAR tiptext[128]; /* tooltip text */
-- WCHAR info_text[256]; /* info balloon text */
-- WCHAR info_title[64]; /* info balloon title */
-- UINT info_flags; /* flags for info balloon */
-- UINT info_timeout; /* timeout for info balloon */
-- HICON info_icon; /* info balloon icon */
--};
-+
-+WINE_DEFAULT_DEBUG_CHANNEL(systray);
-
- static struct list icon_list = LIST_INIT( icon_list );
-
-@@ -88,9 +70,6 @@ Atom systray_atom = 0;
- #define BALLOON_CREATE_TIMER 1
- #define BALLOON_SHOW_TIMER 2
-
--#define BALLOON_CREATE_TIMEOUT 2000
--#define BALLOON_SHOW_MIN_TIMEOUT 10000
--#define BALLOON_SHOW_MAX_TIMEOUT 30000
-
- static struct tray_icon *balloon_icon;
- static HWND balloon_window;
-@@ -825,14 +804,35 @@ int CDECL wine_notify_icon( DWORD msg, NOTIFYICONDATAW *data )
- switch (msg)
- {
- case NIM_ADD:
-- if (!init_systray()) return -1; /* fall back to default handling */
-- ret = add_icon( data );
-+ if (can_use_dbus_sni_systray())
-+ {
-+ ret = add_sni_icon( data );
-+ }
-+ else
-+ {
-+ if (!init_systray()) return -1; /* fall back to default handling */
-+ ret = add_icon( data );
-+ }
- break;
- case NIM_DELETE:
-- if ((icon = get_icon( data->hWnd, data->uID ))) ret = delete_icon( icon );
-+ if (can_use_dbus_sni_systray())
-+ {
-+ ret = delete_sni_icon( data );
-+ }
-+ else
-+ {
-+ if ((icon = get_icon( data->hWnd, data->uID ))) ret = delete_icon( icon );
-+ }
- break;
- case NIM_MODIFY:
-- if ((icon = get_icon( data->hWnd, data->uID ))) ret = modify_icon( icon, data );
-+ if (can_use_dbus_sni_systray())
-+ {
-+ ret = modify_sni_icon( data );
-+ }
-+ else
-+ {
-+ if ((icon = get_icon( data->hWnd, data->uID ))) ret = modify_icon( icon, data );
-+ }
- break;
- case 0xdead: /* Wine extension: owner window has died */
- cleanup_icons( data->hWnd );
---- a/dlls/winex11.drv/systray.h
-+++ a/dlls/winex11.drv/systray.h
-@@ -0,0 +1,77 @@
-+/*
-+ * X11 driver systray-specific definitions
-+ *
-+ * Copyright (C) 2004 Mike Hearn, for CodeWeavers
-+ * Copyright (C) 2005 Robert Shearman
-+ * Copyright (C) 2008 Alexandre Julliard
-+ * Copyright (C) 2015 Alexey Minnekhanov
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
-+ */
-+
-+#ifndef __WINE_SYSTRAY_H
-+#define __WINE_SYSTRAY_H
-+
-+
-+#include "windef.h"
-+#include "wine/list.h"
-+
-+
-+/* This file contains declarations shared between systray.c and
-+ * systray_dbus.c (to avoid modification of x11drv.h) */
-+
-+
-+#define BALLOON_CREATE_TIMEOUT 2000
-+#define BALLOON_SHOW_MIN_TIMEOUT 10000
-+#define BALLOON_SHOW_MAX_TIMEOUT 30000
-+
-+
-+/* an individual systray icon */
-+struct tray_icon
-+{
-+ struct list entry;
-+ HICON image; /* the image to render */
-+ HWND owner; /* the HWND passed in to the Shell_NotifyIcon call */
-+ HWND window; /* the adaptor window */
-+ BOOL layered; /* whether we are using a layered window */
-+ HWND tooltip; /* Icon tooltip */
-+ UINT state; /* state flags */
-+ UINT id; /* the unique id given by the app */
-+ UINT callback_message;
-+ int display; /* display index, or -1 if hidden */
-+ WCHAR tiptext[128]; /* tooltip text */
-+ WCHAR info_text[256]; /* info balloon text */
-+ WCHAR info_title[64]; /* info balloon title */
-+ UINT info_flags; /* flags for info balloon */
-+ UINT info_timeout; /* timeout for info balloon */
-+ HICON info_icon; /* info balloon icon */
-+ /* DBus SNI specific members */
-+ char dbus_name[64]; /* name of dbus object */
-+ char sni_title[64]; /* title of status notifier */
-+ /* For SNI we must keep icon image this way, as an array of bitmap bits */
-+ int icon_w; /* tray icon width */
-+ int icon_h; /* tray icon height */
-+ unsigned char *icon_data; /* tray icon pixels */
-+};
-+
-+
-+extern BOOL can_use_dbus_sni_systray(void) DECLSPEC_HIDDEN;
-+
-+extern BOOL add_sni_icon(NOTIFYICONDATAW *nid) DECLSPEC_HIDDEN;
-+extern BOOL modify_sni_icon(NOTIFYICONDATAW *nid) DECLSPEC_HIDDEN;
-+extern BOOL delete_sni_icon(NOTIFYICONDATAW *nid) DECLSPEC_HIDDEN;
-+
-+
-+#endif /* __WINE_SYSTRAY_H */
---- a/dlls/winex11.drv/systray_dbus.c
-+++ a/dlls/winex11.drv/systray_dbus.c
-@@ -0,0 +1,1814 @@
-+/*
-+ * DBus StatusNotifierItem system tray management,
-+ *
-+ * Copyright (C) 2004 Mike Hearn, for CodeWeavers
-+ * Copyright (C) 2005 Robert Shearman
-+ * Copyright (C) 2008 Alexandre Julliard
-+ * Copyright (C) 2015 Alexey Minnekhanov
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
-+ */
-+
-+/*
-+ * This file holds all functionality to implement all DBus-related
-+ * operations to implement StatusNotifierItem specification
-+ * (see http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/ )
-+ * Keep it separated from systray.c if possible.
-+ * Functions in this module will be called from systray.c,
-+ * from wine_notify_icon(). Module public module interface:
-+ *
-+ * - BOOL can_use_dbus_sni_systray(void) - checks if SNI systray can be used
-+ * in this system.
-+ * - BOOL add_sni_icon( NOTIFYICONDATAW* ) - add new systray icon
-+ * - BOOL modify_sni_icon( NOTIFYICONDATAW* ) - all edit icon operations
-+ * - BOOL delete_sni_icon( NOTIFYICONDATAW* ) - remove status notifier item
-+ */
-+
-+#include "config.h"
-+#include "wine/port.h"
-+
-+#include <assert.h>
-+#include <stdarg.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#ifdef HAVE_UNISTD_H
-+# include <unistd.h>
-+#endif
-+
-+#ifdef SONAME_LIBDBUS_1
-+# include <dbus/dbus.h>
-+#endif
-+
-+#define NONAMELESSUNION
-+#include "windef.h"
-+#include "winbase.h"
-+#include "wingdi.h"
-+#include "winuser.h"
-+#include "shellapi.h"
-+
-+#include "wine/debug.h"
-+#include "wine/library.h"
-+#include "wine/list.h"
-+#include "wine/unicode.h"
-+
-+#include "systray.h"
-+#include "x11drv.h"
-+
-+
-+WINE_DEFAULT_DEBUG_CHANNEL(systray);
-+
-+
-+#ifdef SONAME_LIBDBUS_1
-+
-+/* Similar code to load DBus is used in dlls/mountmgr.sys/dbus.c */
-+
-+#define DBUS_FUNCS \
-+ DO_FUNC(dbus_bus_get); \
-+ DO_FUNC(dbus_bus_get_unique_name); \
-+ DO_FUNC(dbus_bus_name_has_owner); \
-+ DO_FUNC(dbus_bus_release_name); \
-+ DO_FUNC(dbus_bus_request_name); \
-+ DO_FUNC(dbus_connection_read_write_dispatch); \
-+ DO_FUNC(dbus_connection_send); \
-+ DO_FUNC(dbus_connection_send_with_reply_and_block); \
-+ DO_FUNC(dbus_connection_set_exit_on_disconnect); \
-+ DO_FUNC(dbus_connection_try_register_fallback); \
-+ DO_FUNC(dbus_connection_unref); \
-+ DO_FUNC(dbus_connection_unregister_object_path); \
-+ DO_FUNC(dbus_error_free); \
-+ DO_FUNC(dbus_error_init); \
-+ DO_FUNC(dbus_message_append_args); \
-+ DO_FUNC(dbus_message_get_args); \
-+ DO_FUNC(dbus_message_get_destination); \
-+ DO_FUNC(dbus_message_get_interface); \
-+ DO_FUNC(dbus_message_get_member); \
-+ DO_FUNC(dbus_message_get_path); \
-+ DO_FUNC(dbus_message_get_signature); \
-+ DO_FUNC(dbus_message_is_method_call); \
-+ DO_FUNC(dbus_message_iter_append_basic); \
-+ DO_FUNC(dbus_message_iter_close_container); \
-+ DO_FUNC(dbus_message_iter_get_arg_type); \
-+ DO_FUNC(dbus_message_iter_get_basic); \
-+ DO_FUNC(dbus_message_iter_init); \
-+ DO_FUNC(dbus_message_iter_init_append); \
-+ DO_FUNC(dbus_message_iter_next); \
-+ DO_FUNC(dbus_message_iter_open_container); \
-+ DO_FUNC(dbus_message_iter_recurse); \
-+ DO_FUNC(dbus_message_new_error); \
-+ DO_FUNC(dbus_message_new_method_call); \
-+ DO_FUNC(dbus_message_new_method_return); \
-+ DO_FUNC(dbus_message_new_signal); \
-+ DO_FUNC(dbus_message_unref);
-+
-+/* libdbus function pointers */
-+#define DO_FUNC(f) static typeof(f) * p_##f
-+DBUS_FUNCS;
-+#undef DO_FUNC
-+
-+
-+/* DBus connection handle */
-+static DBusConnection *d_connection = NULL;
-+
-+/* structure to keep all managed icons */
-+static struct list icon_list = LIST_INIT( icon_list );
-+/* we need our own list, different from that one in systray.c
-+ * just to make as little modifications to existing code as possible */
-+static int g_icons_count = 0;
-+
-+/* global that indicates DBus message loop thread state */
-+static BOOL g_dbus_thread_running = FALSE;
-+
-+/* Critical section guarding DBus connection object */
-+CRITICAL_SECTION g_dconn_cs;
-+
-+/* local forwards */
-+static BOOL delete_icon(struct tray_icon *icon);
-+
-+
-+/* DBus introspection XMLs definitions */
-+/* For documentation of DBus introspection XML format,
-+ * see http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format */
-+
-+/* root object XML */
-+static const char *g_dbus_introspect_xml_root_with_SNI = ""
-+"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\""
-+" \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
-+"<node name=\"/\">\n"
-+" <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
-+" <method name=\"Introspect\">\n"
-+" <arg name=\"xml_data\" type=\"s\" direction=\"out\"/>\n"
-+" </method>\n"
-+" </interface>\n"
-+" <interface name=\"org.freedesktop.DBus.Properties\">\n"
-+" <method name=\"Get\">\n"
-+" <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\n"
-+" <arg name=\"property_name\" type=\"s\" direction=\"in\"/>\n"
-+" <arg name=\"value\" type=\"v\" direction=\"out\"/>\n"
-+" </method>\n"
-+" <method name=\"Set\">\n"
-+" <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\n"
-+" <arg name=\"property_name\" type=\"s\" direction=\"in\"/>\n"
-+" <arg name=\"value\" type=\"v\" direction=\"in\"/>\n"
-+" </method>\n"
-+" <method name=\"GetAll\">\n"
-+" <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\n"
-+" <arg name=\"props\" type=\"{sv}\" direction=\"out\"/>\n"
-+" </method>\n"
-+" </interface>\n"
-+" <node name=\"StatusNotifierItem\"/>\n"
-+"</node>";
-+
-+/* /StatusNotifierItem XML */
-+static const char *g_dbus_introspect_xml_SNI = "\
-+<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\
-+ \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\
-+<node name=\"/StatusNotifierItem\">\
-+ <interface name=\"org.freedesktop.DBus.Introspectable\">\
-+ <method name=\"Introspect\">\
-+ <arg name=\"xml_data\" type=\"s\" direction=\"out\"/>\
-+ </method>\
-+ </interface>\
-+ <interface name=\"org.freedesktop.DBus.Properties\">\
-+ <method name=\"Get\">\
-+ <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\
-+ <arg name=\"property_name\" type=\"s\" direction=\"in\"/>\
-+ <arg name=\"value\" type=\"v\" direction=\"out\"/>\
-+ </method>\
-+ <method name=\"Set\">\
-+ <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\
-+ <arg name=\"property_name\" type=\"s\" direction=\"in\"/>\
-+ <arg name=\"value\" type=\"v\" direction=\"in\"/>\
-+ </method>\
-+ <method name=\"GetAll\">\
-+ <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\
-+ <arg name=\"props\" type=\"{sv}\" direction=\"out\"/>\
-+ </method>\
-+ </interface>\
-+ <interface name=\"org.kde.StatusNotifierItem\">\
-+ <property name=\"Category\" type=\"s\" access=\"read\"/>\
-+ <property name=\"Id\" type=\"s\" access=\"read\"/>\
-+ <property name=\"Title\" type=\"s\" access=\"read\"/>\
-+ <property name=\"Status\" type=\"s\" access=\"read\"/>\
-+ <property name=\"WindowId\" type=\"u\" access=\"read\"/>\
-+ <property name=\"IconName\" type=\"s\" access=\"read\"/>\
-+ <property name=\"IconPixmap\" type=\"a(iiay)\" access=\"read\"/>\
-+ <property name=\"OverlayIconName\" type=\"s\" access=\"read\"/>\
-+ <property name=\"OverlayIconPixmap\" type=\"a(iiay)\" access=\"read\"/>\
-+ <property name=\"AttentionIconName\" type=\"s\" access=\"read\"/>\
-+ <property name=\"AttentionIconPixmap\" type=\"a(iiay)\" access=\"read\"/>\
-+ <property name=\"AttentionMovieName\" type=\"s\" access=\"read\"/>\
-+ <property name=\"ToolTip\" type=\"(sa(iiay)ss)\" access=\"read\"/>\
-+ <method name=\"ContextMenu\">\
-+ <arg name=\"x\" type=\"i\" direction=\"in\"/>\
-+ <arg name=\"y\" type=\"i\" direction=\"in\"/>\
-+ </method>\
-+ <method name=\"Activate\">\
-+ <arg name=\"x\" type=\"i\" direction=\"in\"/>\
-+ <arg name=\"y\" type=\"i\" direction=\"in\"/>\
-+ </method>\
-+ <method name=\"SecondaryActivate\">\
-+ <arg name=\"x\" type=\"i\" direction=\"in\"/>\
-+ <arg name=\"y\" type=\"i\" direction=\"in\"/>\
-+ </method>\
-+ <method name=\"Scroll\">\
-+ <arg name=\"delta\" type=\"i\" direction=\"in\"/>\
-+ <arg name=\"orientation\" type=\"s\" direction=\"in\"/>\
-+ </method>\
-+ <signal name=\"NewTitle\"></signal>\
-+ <signal name=\"NewIcon\"></signal>\
-+ <signal name=\"NewAttentionIcon\"></signal>\
-+ <signal name=\"NewOverlayIcon\"></signal>\
-+ <signal name=\"NewToolTip\"></signal>\
-+ <signal name=\"NewStatus\">\
-+ <arg name=\"status\" type=\"s\"/>\
-+ </signal>\
-+ </interface>\
-+</node>";
-+
-+
-+/**************************************************************
-+ icon_list management functions
-+***************************************************************/
-+
-+/* Retrieves icon record by owner window and ID */
-+static struct tray_icon *get_icon_from_list(HWND owner, UINT id)
-+{
-+ struct tray_icon *this;
-+
-+ LIST_FOR_EACH_ENTRY( this, &icon_list, struct tray_icon, entry )
-+ if ((this->id == id) && (this->owner == owner)) return this;
-+ return NULL;
-+}
-+
-+
-+/* Retrieves icon record by DBus name */
-+static struct tray_icon *get_icon_from_list_by_dname(const char *dname)
-+{
-+ struct tray_icon *this;
-+
-+ LIST_FOR_EACH_ENTRY( this, &icon_list, struct tray_icon, entry )
-+ if (strcmp(this->dbus_name, dname) == 0) return this;
-+ return NULL;
-+}
-+
-+
-+/* Allocates memory and adds a new icon to the list */
-+static struct tray_icon *add_new_icon_to_list(void)
-+{
-+ struct tray_icon *icon;
-+
-+ /* allocate memory */
-+ if (!(icon = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*icon))))
-+ {
-+ ERR("out of memory\n");
-+ return FALSE;
-+ }
-+ ZeroMemory(icon, sizeof(struct tray_icon));
-+
-+ /* add to list */
-+ list_add_tail(&icon_list, &icon->entry);
-+ g_icons_count++;
-+ return icon;
-+}
-+
-+
-+/* Removes icons from list and frees its memory */
-+static void delete_icon_from_list(struct tray_icon *icon)
-+{
-+ if (!icon) return;
-+ list_remove( &icon->entry );
-+ g_icons_count--;
-+ HeapFree( GetProcessHeap(), 0, icon );
-+}
-+
-+
-+
-+/**************************************************************
-+ DBus initialization functions
-+***************************************************************/
-+
-+static BOOL load_dbus_functions(void)
-+{
-+ void *handle;
-+ char error[128];
-+
-+ if (!(handle = wine_dlopen(SONAME_LIBDBUS_1, RTLD_NOW, error, sizeof(error))))
-+ goto failed;
-+
-+#define DO_FUNC(f) if (!(p_##f = wine_dlsym( handle, #f, error, sizeof(error) ))) goto failed
-+ DBUS_FUNCS;
-+#undef DO_FUNC
-+ return TRUE;
-+
-+failed:
-+ WARN( "failed to load DBus support: %s\n", error );
-+ return FALSE;
-+}
-+
-+
-+static BOOL initialize_dbus(void)
-+{
-+ static BOOL init_done = FALSE;
-+ if (init_done) return TRUE;
-+
-+ if (load_dbus_functions())
-+ {
-+ InitializeCriticalSection( &g_dconn_cs );
-+
-+ init_done = TRUE;
-+ d_connection = NULL;
-+ }
-+
-+ TRACE( "Initialize DBUS OK\n" );
-+ return TRUE;
-+}
-+
-+
-+/*************************************************************
-+ * DBus reply helper functions
-+**************************************************************/
-+
-+
-+/* Locks connection lock, sends message and unlocks the lock.
-+ * Safe to use with message loop thread running. */
-+static dbus_bool_t dbus_send_safe(DBusMessage *msg)
-+{
-+ dbus_bool_t resb;
-+
-+ if (!d_connection) return FALSE;
-+ if (!msg) return FALSE;
-+
-+ EnterCriticalSection( &g_dconn_cs );
-+ resb = p_dbus_connection_send(d_connection, msg, NULL);
-+ LeaveCriticalSection( &g_dconn_cs );
-+
-+ if (resb == FALSE)
-+ {
-+ WARN("dbus_connection_send() failed!\n");
-+ }
-+
-+ return resb;
-+}
-+
-+
-+/* this creates response message with simlple string value */
-+static DBusMessage *create_introspect_reply(
-+ DBusMessage *msg,
-+ const char *reply_xml)
-+{
-+ dbus_bool_t retb;
-+ DBusMessage *reply;
-+
-+ reply = p_dbus_message_new_method_return(msg);
-+ if( reply )
-+ {
-+ retb = p_dbus_message_append_args(reply,
-+ DBUS_TYPE_STRING, &reply_xml,
-+ DBUS_TYPE_INVALID);
-+ if( retb == FALSE )
-+ {
-+ p_dbus_message_unref(reply);
-+ reply = NULL;
-+ }
-+ }
-+ return reply;
-+}
-+
-+
-+/* this should reply DBUS_VARIANT type with internal STRING value */
-+static DBusMessage *create_reply_propget_s(DBusMessage *msg, const char *s)
-+{
-+ DBusMessage *reply;
-+ DBusMessageIter iter, sub_iter;
-+
-+ reply = p_dbus_message_new_method_return(msg);
-+ if( !reply ) return FALSE;
-+
-+ /* we can send VARIANT only with iterator */
-+ p_dbus_message_iter_init_append(reply, &iter);
-+ p_dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "s", &sub_iter);
-+ p_dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_STRING, &s);
-+ p_dbus_message_iter_close_container(&iter, &sub_iter);
-+ return reply;
-+}
-+
-+
-+/* this should reply DBUS_VARIANT type with internal UINT32 value */
-+static DBusMessage *create_reply_propget_u(DBusMessage *msg, dbus_uint32_t value)
-+{
-+ DBusMessage *reply;
-+ DBusMessageIter iter, sub_iter;
-+
-+ reply = p_dbus_message_new_method_return(msg);
-+ if( !reply ) return FALSE;
-+
-+ /* we can send VARIANT only with iterator */
-+ p_dbus_message_iter_init_append(reply, &iter);
-+ p_dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "u", &sub_iter);
-+ p_dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_UINT32, &value);
-+ p_dbus_message_iter_close_container(&iter, &sub_iter);
-+ return reply;
-+}
-+
-+
-+static DBusMessage *create_reply_propget_pixmap(
-+ DBusMessage *msg,
-+ int icon_width,
-+ int icon_height,
-+ const unsigned char *img_data )
-+{
-+ DBusMessage *reply;
-+ DBusMessageIter iter, v_iter, a_iter, st_iter, pixels_arr_iter;
-+ int num_pixels, i;
-+ unsigned char pixel_byte;
-+
-+ reply = p_dbus_message_new_method_return(msg);
-+ if( !reply ) return FALSE;
-+
-+ /* variant, containing array: a(iiay)
-+ * array of structures: (int, int, bytearray): width, height,
-+ * bits data in ARGB32 format (network byte order)
-+ * Reply can contain array of pixmaps in different sizes, but we send only one */
-+ p_dbus_message_iter_init_append(reply, &iter);
-+ p_dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "a(iiay)", &v_iter);
-+ p_dbus_message_iter_open_container(&v_iter, DBUS_TYPE_ARRAY, "(iiay)", &a_iter);
-+ if( (icon_height > 0) && (icon_width > 0) && (img_data)) {
-+ /* open structure container */
-+ p_dbus_message_iter_open_container(&a_iter, DBUS_TYPE_STRUCT, NULL, &st_iter);
-+ /* write icon width, height */
-+ p_dbus_message_iter_append_basic(&st_iter, DBUS_TYPE_INT32, &icon_width);
-+ p_dbus_message_iter_append_basic(&st_iter, DBUS_TYPE_INT32, &icon_height);
-+ /* write icon bytes data as array */
-+ /* open array */
-+ p_dbus_message_iter_open_container(&st_iter, DBUS_TYPE_ARRAY, "y", &pixels_arr_iter);
-+ /* write pixels */
-+ num_pixels = icon_width * icon_height;
-+ for( i=0; i<num_pixels * 4; i++ ) /* ARGB32 = 4 bytes per pixel */
-+ {
-+ pixel_byte = img_data[i];
-+ p_dbus_message_iter_append_basic(&pixels_arr_iter, DBUS_TYPE_BYTE, &pixel_byte);
-+ }
-+ p_dbus_message_iter_close_container(&st_iter, &pixels_arr_iter);
-+ p_dbus_message_iter_close_container(&a_iter, &st_iter);
-+ }
-+ p_dbus_message_iter_close_container(&v_iter, &a_iter);
-+ p_dbus_message_iter_close_container(&iter, &v_iter);
-+ return reply;
-+}
-+
-+
-+static DBusMessage *create_reply_propget_tooltip(
-+ DBusMessage *msg,
-+ const char *icon_name,
-+ int icon_width,
-+ int icon_height,
-+ const unsigned char *img_data,
-+ const char *tip_title,
-+ const char *tip_text)
-+{
-+ /* Format: (sa(iiay)ss)
-+ * Components are:
-+ * STRING: Freedesktop-compliant name for an icon.
-+ * ARRAY(INT, INT, ARRAY BYTE): icon data
-+ * STRING: title for this tooltip
-+ * STRING: descriptive text for this tooltip. */
-+ DBusMessage *reply;
-+ DBusMessageIter iter, v_iter, st_iter, arr_iter, ast_iter, pixels_arr_iter;
-+ int num_pixels, i;
-+ unsigned char pixel_byte;
-+
-+ reply = p_dbus_message_new_method_return(msg);
-+ if( !reply ) return FALSE;
-+
-+ p_dbus_message_iter_init_append(reply, &iter);
-+ p_dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "(sa(iiay)ss)", &v_iter);
-+ p_dbus_message_iter_open_container(&v_iter, DBUS_TYPE_STRUCT, NULL, &st_iter);
-+ p_dbus_message_iter_append_basic(&st_iter, DBUS_TYPE_STRING, &icon_name);
-+ p_dbus_message_iter_open_container(&st_iter, DBUS_TYPE_ARRAY, "(iiay)", &arr_iter);
-+ /* write icon data, if set */
-+ if( (icon_height > 0) && (icon_width > 0) && (img_data)) {
-+ p_dbus_message_iter_open_container(&arr_iter, DBUS_TYPE_STRUCT, NULL, &ast_iter);
-+ /* write icon width, height */
-+ p_dbus_message_iter_append_basic(&ast_iter, DBUS_TYPE_INT32, &icon_width);
-+ p_dbus_message_iter_append_basic(&ast_iter, DBUS_TYPE_INT32, &icon_height);
-+ /* write icon bytes data as array */
-+ p_dbus_message_iter_open_container(&ast_iter, DBUS_TYPE_ARRAY, "y", &pixels_arr_iter);
-+ /* write pixels */
-+ num_pixels = icon_width * icon_height;
-+ for( i=0; i<num_pixels * 4; i++ ) /* ARGB32 = 4 bytes per pixel */
-+ {
-+ pixel_byte = img_data[i];
-+ p_dbus_message_iter_append_basic(&pixels_arr_iter, DBUS_TYPE_BYTE, &pixel_byte);
-+ }
-+ p_dbus_message_iter_close_container(&ast_iter, &pixels_arr_iter);
-+ p_dbus_message_iter_close_container(&arr_iter, &ast_iter);
-+ }
-+ p_dbus_message_iter_close_container(&st_iter, &arr_iter);
-+ /* write tooltip title and text */
-+ p_dbus_message_iter_append_basic(&st_iter, DBUS_TYPE_STRING, &tip_title);
-+ p_dbus_message_iter_append_basic(&st_iter, DBUS_TYPE_STRING, &tip_text);
-+ p_dbus_message_iter_close_container(&v_iter, &st_iter);
-+ p_dbus_message_iter_close_container(&iter, &v_iter);
-+ return reply;
-+}
-+
-+
-+/* Appends dict value [attr_name] = variant(string value) to DBus
-+ * reply for Properties.GetAll() */
-+static void reply_propgetall_append_s(
-+ DBusMessageIter *piter,
-+ const char *attr_name,
-+ const char *value)
-+{
-+ DBusMessageIter dict_iter, var_iter;
-+ p_dbus_message_iter_open_container(piter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_iter); /* open dict */
-+ p_dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &attr_name); /* write attr name as dict key */
-+ p_dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_VARIANT, "s", &var_iter); /* open variant */
-+ p_dbus_message_iter_append_basic(&var_iter, DBUS_TYPE_STRING, &value); /* write attr value as Variant(string) */
-+ p_dbus_message_iter_close_container(&dict_iter, &var_iter); /* close variant */
-+ p_dbus_message_iter_close_container(piter, &dict_iter); /* close dict */
-+}
-+
-+
-+/* Appends dict value [attr_name] = variant(uint32 value) to DBus
-+ * reply for Properties.GetAll() */
-+static void reply_propgetall_append_u(
-+ DBusMessageIter *piter,
-+ const char *attr_name,
-+ dbus_uint32_t value)
-+{
-+ DBusMessageIter dict_iter, var_iter;
-+ p_dbus_message_iter_open_container(piter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_iter); /* open dict */
-+ p_dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &attr_name); /* write attr name as dict key */
-+ p_dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_VARIANT, "u", &var_iter); /* open variant */
-+ p_dbus_message_iter_append_basic(&var_iter, DBUS_TYPE_UINT32, &value); /* write attr value as Variant(uint32) */
-+ p_dbus_message_iter_close_container(&dict_iter, &var_iter); /* close variant */
-+ p_dbus_message_iter_close_container(piter, &dict_iter); /* close dict */
-+}
-+
-+
-+/* Appends dict value [attr_name] = variant(pixmap structure) to DBus
-+ * reply for Properties.GetAll() */
-+static void reply_propgetall_append_pixmap(
-+ DBusMessageIter *piter,
-+ const char *attr_name,
-+ int width,
-+ int height,
-+ const unsigned char *img_data)
-+{
-+ DBusMessageIter dict_iter, var_iter, arr_iter, st_iter, pixels_arr_iter;
-+ int num_pixels, i;
-+ unsigned char pixel_byte;
-+
-+ p_dbus_message_iter_open_container(piter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_iter); /* open dict */
-+ p_dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &attr_name); /* write attr name as dict key */
-+ p_dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_VARIANT, "a(iiay)", &var_iter); /* open variant */
-+ /* key value - pixmap array inside Variant
-+ * example: "AttentionIconPixmap" = [Variant: [Argument: a(iiay) {}]] */
-+ p_dbus_message_iter_open_container(&var_iter, DBUS_TYPE_ARRAY, "(iiay)", &arr_iter);
-+ if( (width > 0) && (height > 0) && (img_data)) {
-+ /* open structure container */
-+ p_dbus_message_iter_open_container(&arr_iter, DBUS_TYPE_STRUCT, NULL, &st_iter);
-+ /* write icon size: width, height */
-+ p_dbus_message_iter_append_basic(&st_iter, DBUS_TYPE_INT32, &width);
-+ p_dbus_message_iter_append_basic(&st_iter, DBUS_TYPE_INT32, &height);
-+ /* write icon bytes data as array */
-+ /* open array */
-+ p_dbus_message_iter_open_container(&st_iter, DBUS_TYPE_ARRAY, "y", &pixels_arr_iter);
-+ /* write pixels */
-+ num_pixels = width * height;
-+ for( i=0; i<num_pixels * 4; i++ ) /* ARGB32 = 4 bytes per pixel */
-+ {
-+ pixel_byte = img_data[i];
-+ p_dbus_message_iter_append_basic(&pixels_arr_iter, DBUS_TYPE_BYTE, &pixel_byte);
-+ }
-+ /* close array */
-+ p_dbus_message_iter_close_container(&st_iter, &pixels_arr_iter);
-+ /* close structure container */
-+ p_dbus_message_iter_close_container(&arr_iter, &st_iter);
-+ }
-+ p_dbus_message_iter_close_container(&var_iter, &arr_iter); /* close pixmaps array */
-+ p_dbus_message_iter_close_container(&dict_iter, &var_iter); /* close variant */
-+ p_dbus_message_iter_close_container(piter, &dict_iter); /* close dict */
-+}
-+
-+
-+/* Appends dict value [attr_name] = variant(tooltip structure) to DBus
-+ * reply for Properties.GetAll() */
-+static void reply_propgetall_append_tooltip(
-+ DBusMessageIter *piter,
-+ const char *attr_name,
-+ const char *icon_name,
-+ int width,
-+ int height,
-+ const unsigned char *img_data,
-+ const char *tt_title,
-+ const char *tt_text)
-+{
-+ DBusMessageIter dict_iter, var_iter, st_iter, arr_iter, st2_iter, pixels_arr_iter;
-+ int num_pixels, i;
-+ unsigned char pixel_byte;
-+
-+ p_dbus_message_iter_open_container(piter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_iter); /* open dict */
-+ p_dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &attr_name); /* write attr name as dict key */
-+ p_dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_VARIANT, "(sa(iiay)ss)", &var_iter); /* open variant */
-+ /* key value - struct (sa(iiay)ss) */
-+ p_dbus_message_iter_open_container(&var_iter, DBUS_TYPE_STRUCT, NULL, &st_iter); /* open struct */
-+ p_dbus_message_iter_append_basic(&st_iter, DBUS_TYPE_STRING, &icon_name); /* icon name */
-+ p_dbus_message_iter_open_container(&st_iter, DBUS_TYPE_ARRAY, "(iiay)", &arr_iter); /* open array */
-+ /* icon(s), but here only one */
-+ if( (width > 0) && (height > 0) && (img_data)) {
-+ /* open structure container */
-+ p_dbus_message_iter_open_container(&arr_iter, DBUS_TYPE_STRUCT, NULL, &st2_iter);
-+ /* write icon size: width, height */
-+ p_dbus_message_iter_append_basic(&st2_iter, DBUS_TYPE_INT32, &width);
-+ p_dbus_message_iter_append_basic(&st2_iter, DBUS_TYPE_INT32, &height);
-+ /* write icon bytes data as array */
-+ /* open array */
-+ p_dbus_message_iter_open_container(&st2_iter, DBUS_TYPE_ARRAY, "y", &pixels_arr_iter);
-+ /* write pixels */
-+ num_pixels = width * height;
-+ for( i=0; i<num_pixels * 4; i++ ) /* ARGB32 = 4 bytes per pixel */
-+ {
-+ pixel_byte = img_data[i];
-+ p_dbus_message_iter_append_basic(&pixels_arr_iter, DBUS_TYPE_BYTE, &pixel_byte);
-+ }
-+ /* close array */
-+ p_dbus_message_iter_close_container(&st2_iter, &pixels_arr_iter);
-+ /* close structure container */
-+ p_dbus_message_iter_close_container(&arr_iter, &st2_iter);
-+ }
-+ /* end icon */
-+ p_dbus_message_iter_close_container(&st_iter, &arr_iter); /* close array */
-+ p_dbus_message_iter_append_basic(&st_iter, DBUS_TYPE_STRING, &tt_title); /* tooltip title */
-+ p_dbus_message_iter_append_basic(&st_iter, DBUS_TYPE_STRING, &tt_text); /* tooltip text */
-+ p_dbus_message_iter_close_container(&var_iter, &st_iter); /* close struct */
-+
-+ p_dbus_message_iter_close_container(&dict_iter, &var_iter); /* close variant */
-+ p_dbus_message_iter_close_container(piter, &dict_iter); /* close dict */
-+}
-+
-+
-+/* DBus error replies */
-+
-+
-+static dbus_bool_t error_reply_failed(DBusMessage *message)
-+{
-+ DBusMessage *reply;
-+ dbus_bool_t ret;
-+ reply = p_dbus_message_new_error(message, DBUS_ERROR_FAILED, "operation failed");
-+ if (!reply) return FALSE;
-+ ret = dbus_send_safe(reply);
-+ p_dbus_message_unref(reply);
-+ return ret;
-+}
-+
-+
-+static dbus_bool_t error_reply_unknown_interface(DBusMessage *message, const char *iface)
-+{
-+ char error_message[256] = {0};
-+ DBusMessage *reply;
-+ dbus_bool_t ret;
-+ snprintf(error_message, sizeof(error_message)-1, "Unknown interface: [%s]", iface);
-+ reply = p_dbus_message_new_error(message, DBUS_ERROR_UNKNOWN_INTERFACE, error_message);
-+ if (!reply) return FALSE;
-+ ret = dbus_send_safe(reply);
-+ p_dbus_message_unref(reply);
-+ return ret;
-+}
-+
-+
-+static dbus_bool_t error_reply_invalid_args(DBusMessage *message)
-+{
-+ DBusMessage *reply;
-+ dbus_bool_t ret;
-+ reply = p_dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, "Invalid arguments!");
-+ if (!reply) return FALSE;
-+ ret = dbus_send_safe(reply);
-+ p_dbus_message_unref(reply);
-+ return ret;
-+}
-+
-+
-+static dbus_bool_t error_reply_unknown_property(DBusMessage *message, const char *prop_name)
-+{
-+ DBusMessage *reply;
-+ dbus_bool_t ret;
-+ char error_message[256];
-+ snprintf(error_message, sizeof(error_message)-1, "Unknown property: [%s]", prop_name);
-+ reply = p_dbus_message_new_error(message, DBUS_ERROR_UNKNOWN_PROPERTY, error_message);
-+ if (!reply) return FALSE;
-+ ret = dbus_send_safe(reply);
-+ p_dbus_message_unref(reply);
-+ return ret;
-+}
-+
-+
-+static dbus_bool_t error_reply_read_only_prop(DBusMessage *message, const char *prop_name)
-+{
-+ char error_message[256];
-+ DBusMessage *reply;
-+ dbus_bool_t ret;
-+ snprintf(error_message, sizeof(error_message)-1, "property: %s", prop_name);
-+ reply = p_dbus_message_new_error(message, DBUS_ERROR_PROPERTY_READ_ONLY, error_message);
-+ if (!reply) return FALSE;
-+ ret = dbus_send_safe(reply);
-+ p_dbus_message_unref(reply);
-+ return ret;
-+}
-+
-+
-+/* DBus signals */
-+/* Emits DBus signal named "signal_name" */
-+static dbus_bool_t send_signal_noargs(const char *signal_name)
-+{
-+ dbus_bool_t retb;
-+ DBusMessage *msg;
-+ msg = p_dbus_message_new_signal(
-+ "/StatusNotifierItem",
-+ "org.kde.StatusNotifierItem",
-+ signal_name);
-+ if (!msg) return FALSE;
-+ retb = dbus_send_safe(msg);
-+ p_dbus_message_unref(msg);
-+ return retb;
-+}
-+
-+
-+/* Emits DBus signal "NetStatus(status)" */
-+static dbus_bool_t send_signal_NewStatus(const char *status)
-+{
-+ dbus_bool_t retb;
-+ DBusMessage *msg;
-+ msg = p_dbus_message_new_signal(
-+ "/StatusNotifierItem",
-+ "org.kde.StatusNotifierItem",
-+ "NewStatus");
-+ if (!msg) return FALSE;
-+ /* apppend one argument - new status */
-+ p_dbus_message_append_args(msg,
-+ DBUS_TYPE_STRING, &status,
-+ DBUS_TYPE_INVALID);
-+ retb = dbus_send_safe(msg);
-+ p_dbus_message_unref(msg);
-+ return retb;
-+}
-+
-+
-+/* Posts callback windows message to icon owner about tray mouse event */
-+static void relay_windows_message(struct tray_icon *icon, UINT uMsg)
-+{
-+ BOOL ret;
-+ DWORD cur_time;
-+ /* store the last time mouse button was pressed */
-+ static DWORD last_L_time = 0;
-+ static DWORD last_M_time = 0;
-+ static DWORD last_R_time = 0;
-+
-+ if (!icon->callback_message) return;
-+
-+ TRACE("DBus: relaying 0x%x\n", uMsg);
-+
-+ /* uMsg - application-defined callback message,
-+ * wParam - icon id (defined by application,
-+ * lParam - mouse message, e.g. WM_LBUTTONDOWN */
-+ ret = PostMessageW(icon->owner, icon->callback_message, (WPARAM)icon->id, (LPARAM)uMsg);
-+ /* as in systray.c:469, check that window was valid */
-+ if (!ret && (GetLastError() == ERROR_INVALID_WINDOW_HANDLE))
-+ {
-+ WARN( "application window was destroyed, removing icon %s\n", icon->dbus_name );
-+ delete_icon( icon );
-+ }
-+
-+ /* Emulate mouse double button clicks */
-+ /* StatusNotifierItem does not have a notification for double clicks, but
-+ * we can detect 2 fast single clicks as one double */
-+ cur_time = GetTickCount();
-+ switch( uMsg )
-+ {
-+ case WM_LBUTTONDOWN:
-+ if (cur_time - last_L_time < GetDoubleClickTime())
-+ PostMessageW(icon->owner, icon->callback_message,
-+ (WPARAM)icon->id, (LPARAM)WM_LBUTTONDBLCLK);
-+ last_L_time = cur_time;
-+ break;
-+ case WM_RBUTTONDOWN:
-+ if (cur_time - last_R_time < GetDoubleClickTime())
-+ PostMessageW(icon->owner, icon->callback_message,
-+ (WPARAM)icon->id, (LPARAM)WM_RBUTTONDBLCLK);
-+ last_R_time = cur_time;
-+ break;
-+ case WM_MBUTTONDOWN:
-+ if (cur_time - last_M_time < GetDoubleClickTime())
-+ PostMessageW(icon->owner, icon->callback_message,
-+ (WPARAM)icon->id, (LPARAM)WM_MBUTTONDBLCLK);
-+ last_M_time = cur_time;
-+ break;
-+ }
-+}
-+
-+
-+/**************************************************************
-+ DBus message handlers
-+***************************************************************/
-+
-+static void root_message_handler_unreg(DBusConnection *conn, void *user_data)
-+{
-+ UNREFERENCED_PARAMETER(conn); /* unused */
-+ UNREFERENCED_PARAMETER(user_data); /* unused */
-+ TRACE("DBus: root object was unregistered\n");
-+}
-+
-+
-+static DBusHandlerResult root_message_handler(
-+ DBusConnection *conn,
-+ DBusMessage *msg,
-+ void *user_data )
-+{
-+ DBusHandlerResult ret;
-+ DBusMessage *reply;
-+ dbus_bool_t resb;
-+ DBusError derror;
-+ const char *mpath, *mintf, *mmemb, *mdest, *msig;
-+ char *req_intf, *req_prop;
-+ struct tray_icon *icon;
-+ char tiptext_a[128];
-+ DBusMessageIter iter, arr_iter;
-+
-+ UNREFERENCED_PARAMETER(user_data); /* unused */
-+
-+ /* probably, default fallback handler should always
-+ * mark message as handled, otherwise it will cause errors */
-+ ret = DBUS_HANDLER_RESULT_HANDLED;
-+
-+ /* Get message information */
-+ mpath = p_dbus_message_get_path(msg);
-+ mintf = p_dbus_message_get_interface(msg);
-+ mmemb = p_dbus_message_get_member(msg);
-+ mdest = p_dbus_message_get_destination(msg);
-+ msig = p_dbus_message_get_signature(msg);
-+
-+ TRACE("DBus: message for path [%s] dest [%s], intf [%s].[%s]\n",
-+ mpath, mdest, mintf, mmemb);
-+
-+ p_dbus_error_init( &derror );
-+
-+ if (p_dbus_message_is_method_call(msg, "org.freedesktop.DBus.Introspectable", "Introspect"))
-+ {
-+ reply = NULL;
-+ if (strcmp(mpath, "/") == 0) /* request for root object */
-+ {
-+ reply = create_introspect_reply(msg, g_dbus_introspect_xml_root_with_SNI);
-+ }
-+ else if (strcmp(mpath, "/StatusNotifierItem") == 0) /* request for SNI object */
-+ {
-+ reply = create_introspect_reply(msg, g_dbus_introspect_xml_SNI);
-+ }
-+ if (reply)
-+ {
-+ TRACE( "Introspect reply for path %s\n", mpath );
-+ dbus_send_safe(reply);
-+ p_dbus_message_unref(reply);
-+ }
-+ return ret;
-+ }
-+
-+ if (strcmp(mpath, "/StatusNotifierItem") == 0)
-+ {
-+ /* all messages for /StatusNotifierItem go here */
-+ /* Example:
-+ * DBus: message for path [/StatusNotifierItem]
-+ * dest [org.kde.StatusNotifierItem-19965-1],
-+ * intf [org.freedesktop.DBus.Properties].[GetAll]:
-+ * this is SNI host requesting all our icon properties */
-+
-+ /* try to find our icon that request was for */
-+ icon = get_icon_from_list_by_dname(mdest);
-+ if (!icon)
-+ {
-+ WARN( "DBus: cannot find icon struct for DBus name [%s]\n", mdest );
-+ error_reply_failed(msg);
-+ return ret;
-+ }
-+
-+ /* tests for which method is called */
-+ if (p_dbus_message_is_method_call(msg, "org.freedesktop.DBus.Properties", "Get") )
-+ {
-+ if (strcmp(msig, "ss"))
-+ {
-+ /* incorrect call signature, must be 2 string arguments */
-+ error_reply_invalid_args(msg);
-+ return ret;
-+ }
-+ resb = p_dbus_message_get_args(msg, &derror,
-+ DBUS_TYPE_STRING, &req_intf,
-+ DBUS_TYPE_STRING, &req_prop,
-+ DBUS_TYPE_INVALID );
-+ if (resb == FALSE)
-+ {
-+ error_reply_invalid_args(msg);
-+ return ret;
-+ }
-+ TRACE("DBus: call [%s] Properties.Get([%s], [%s])\n", mintf, req_intf, req_prop);
-+
-+ /* check that they request this interface */
-+ if (strcmp(req_intf, "org.kde.StatusNotifierItem"))
-+ {
-+ WARN( "DBus: Properties.Get(): unknown interface requested: [%s]\n", req_intf );
-+ error_reply_unknown_interface(msg, req_intf);
-+ return ret;
-+ }
-+
-+ reply = NULL;
-+
-+ if(strcmp(req_prop, "Category") == 0) {
-+ reply = create_reply_propget_s(msg, "ApplicationStatus");
-+ /* other categories: ApplicationStatus, Communications, SystemServices, Hardware */
-+ } else if(strcmp(req_prop, "Id") == 0) {
-+ reply = create_reply_propget_s(msg, icon->sni_title);
-+ } else if(strcmp(req_prop, "Title") == 0) {
-+ WideCharToMultiByte(CP_ACP, 0, icon->tiptext, -1, tiptext_a, sizeof(tiptext_a), NULL, NULL);
-+ reply = create_reply_propget_s(msg, tiptext_a);
-+ } else if(strcmp(req_prop, "Status") == 0) {
-+ reply = create_reply_propget_s(msg, "Active");
-+ /* other values: Active, Passive, NeedsAttention */
-+ } else if(strcmp(req_prop, "WindowId") == 0) {
-+ Window w = X11DRV_get_whole_window( icon->owner );
-+ reply = create_reply_propget_u(msg, (dbus_uint32_t)w);
-+ } else if(strcmp(req_prop, "IconName") == 0) {
-+ if (icon->icon_data && (icon->icon_w > 0) && (icon->icon_h > 0))
-+ {
-+ /* If we have actual icon image data, send empty icon name */
-+ reply = create_reply_propget_s(msg, "");
-+ }
-+ else
-+ {
-+ /* otherwise, as fallback, use wine icon */
-+ reply = create_reply_propget_s(msg, "wine");
-+ }
-+ } else if(strcmp(req_prop, "OverlayIconName") == 0) {
-+ reply = create_reply_propget_s(msg, "");
-+ } else if(strcmp(req_prop, "AttentionIconName") == 0) {
-+ reply = create_reply_propget_s(msg, "");
-+ } else if(strcmp(req_prop, "AttentionMovieName") == 0) {
-+ reply = create_reply_propget_s(msg, "");
-+ } else if(strcmp(req_prop, "IconPixmap") == 0) {
-+ /* send actual icon pixels */
-+ reply = create_reply_propget_pixmap(msg, icon->icon_w, icon->icon_h, icon->icon_data);
-+ } else if(strcmp(req_prop, "OverlayIconPixmap") == 0) {
-+ reply = create_reply_propget_pixmap(msg, 0, 0, NULL);
-+ } else if(strcmp(req_prop, "AttentionIconPixmap") == 0) {
-+ reply = create_reply_propget_pixmap(msg, 0, 0, NULL);
-+ } else if(strcmp(req_prop, "ToolTip") == 0) {
-+ WideCharToMultiByte(CP_ACP, 0, icon->tiptext, -1, tiptext_a, sizeof(tiptext_a), NULL, NULL);
-+ if (icon->icon_data && (icon->icon_w > 0) && (icon->icon_h > 0))
-+ {
-+ /* If we have actual icon image data, send empty icon name and real image data */
-+ reply = create_reply_propget_tooltip(msg,
-+ "", /* icon name */
-+ icon->icon_w, icon->icon_h, icon->icon_data, /* icon data */
-+ tiptext_a, /* tip title (szTip member of NOTIFYICONDATA) */
-+ ""); /* tip text, empty */
-+ }
-+ else
-+ {
-+ reply = create_reply_propget_tooltip(msg,
-+ "wine", /* icon name */
-+ 0, 0, NULL, /* icon data */
-+ tiptext_a, /* tip title (szTip member of NOTIFYICONDATA) */
-+ ""); /* tip text, empty */
-+ }
-+ } else {
-+ WARN("DBus: unknown property requested: [%s]\n", req_prop);
-+ error_reply_unknown_property(msg, req_prop);
-+ }
-+
-+ if (reply)
-+ {
-+ TRACE( "Propget reply for icon %s\n", icon->dbus_name );
-+ dbus_send_safe(reply);
-+ p_dbus_message_unref(reply);
-+ return ret;
-+ }
-+ }
-+ else if (p_dbus_message_is_method_call(msg, "org.freedesktop.DBus.Properties", "Set"))
-+ {
-+ if (strcmp(msig, "ssv"))
-+ {
-+ error_reply_invalid_args(msg);
-+ return ret;
-+ }
-+
-+ resb = p_dbus_message_get_args(msg, &derror,
-+ DBUS_TYPE_STRING, &req_intf,
-+ DBUS_TYPE_STRING, &req_prop,
-+ DBUS_TYPE_INVALID );
-+
-+ /* check that they request this interface */
-+ if (strcmp(req_intf, "org.kde.StatusNotifierItem"))
-+ {
-+ WARN( "DBus: Properties.Set(): unknown interface requested: [%s]\n", req_intf );
-+ error_reply_unknown_interface(msg, req_intf);
-+ return ret;
-+ }
-+
-+ if (resb == TRUE)
-+ {
-+ TRACE( "DBus: call [%s] Properties.Set([%s], [%s]): replying \"read-only\"\n", mintf, req_intf, req_prop);
-+ error_reply_read_only_prop(msg, req_prop);
-+ }
-+ else
-+ {
-+ error_reply_read_only_prop(msg, "FAILED_TO_GET_PROP_NAME");
-+ }
-+ return ret;
-+ }
-+ else if (p_dbus_message_is_method_call(msg, "org.freedesktop.DBus.Properties", "GetAll"))
-+ {
-+ if (strcmp(msig, "s"))
-+ {
-+ error_reply_invalid_args(msg);
-+ return ret;
-+ }
-+
-+ resb = p_dbus_message_get_args(msg, &derror,
-+ DBUS_TYPE_STRING, &req_intf,
-+ DBUS_TYPE_INVALID );
-+ if( resb == FALSE ) {
-+ ERR( "DBus: Properties.GetAll(): Failed to get message args!\n" );
-+ error_reply_failed(msg);
-+ return ret;
-+ }
-+ TRACE( "DBus: Properties.GetAll( \"%s\" )\n", req_intf );
-+
-+ /* check that they request this interface */
-+ if (strcmp(req_intf, "org.kde.StatusNotifierItem"))
-+ {
-+ WARN( "DBus: unknown interface requested: [%s]\n", req_intf );
-+ error_reply_unknown_interface(msg, req_intf);
-+ return ret;
-+ }
-+
-+ /* okay, respond with all our "properties" */
-+ reply = p_dbus_message_new_method_return(msg);
-+ if (!reply)
-+ {
-+ error_reply_failed(msg);
-+ return ret;
-+ }
-+
-+ WideCharToMultiByte(CP_ACP, 0, icon->tiptext, -1, tiptext_a, sizeof(tiptext_a), NULL, NULL);
-+
-+ /* create reply */
-+ p_dbus_message_iter_init_append(reply, &iter);
-+ p_dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &arr_iter); /* open array */
-+ /* insert all object properties, contained in Variants */
-+ reply_propgetall_append_s(&arr_iter, "Category", "ApplicationStatus");
-+ reply_propgetall_append_s(&arr_iter, "Id", icon->sni_title); /* seems to be unused by KDE 5 */
-+ reply_propgetall_append_s(&arr_iter, "Title", tiptext_a);
-+ /* ^^ this is also an icon identifier used by KDE Plasma 5 systray setting utility */
-+ reply_propgetall_append_s(&arr_iter, "Status", "Active");
-+ reply_propgetall_append_u(&arr_iter, "WindowId", 0);
-+ /* ^^ KDE sends this as int32, not uint32... what? */
-+ if (icon->icon_data && (icon->icon_w > 0) && (icon->icon_h > 0))
-+ {
-+ /* we have actual icon image data, send empty icon name */
-+ reply_propgetall_append_s(&arr_iter, "IconName", "");
-+ }
-+ else
-+ {
-+ /* we don't have icon pixels, fallback: use standard wine icon */
-+ /* this is used as icon name in freedesktop icon theme */
-+ reply_propgetall_append_s(&arr_iter, "IconName", "wine");
-+ }
-+ reply_propgetall_append_s(&arr_iter, "OverlayIconName", "");
-+ reply_propgetall_append_s(&arr_iter, "AttentionIconName", "");
-+ reply_propgetall_append_s(&arr_iter, "AttentionMovieName", "");
-+ reply_propgetall_append_pixmap(&arr_iter, "IconPixmap",
-+ icon->icon_w,
-+ icon->icon_h,
-+ icon->icon_data);
-+ reply_propgetall_append_pixmap(&arr_iter, "OverlayIconPixmap", 0, 0, NULL);
-+ reply_propgetall_append_pixmap(&arr_iter, "AttentionIconPixmap", 0, 0, NULL);
-+ if (icon->icon_data && (icon->icon_w > 0) && (icon->icon_h > 0))
-+ {
-+ /* we have actual image data, send empty icon name and real pixels */
-+ reply_propgetall_append_tooltip(
-+ &arr_iter,
-+ "ToolTip", /* attribute name */
-+ "", /* icon name */
-+ icon->icon_w, /* icon width, */
-+ icon->icon_h, /* icon height, */
-+ icon->icon_data, /* icon image pixels */
-+ tiptext_a, /* tooltip title (this is szTip member if NOTIFYICONDATA) */
-+ "" /* tooltip text, empty */
-+ );
-+ }
-+ else
-+ {
-+ /* we don't have actual image data, send "wine" icon name and no pixels */
-+ reply_propgetall_append_tooltip(
-+ &arr_iter,
-+ "ToolTip", /* attribute name */
-+ "wine", /* icon name */
-+ 0, /* icon width, */
-+ 0, /* icon height, */
-+ NULL, /* icon image pixels */
-+ tiptext_a, /* tooltip title (this is szTip member if NOTIFYICONDATA) */
-+ "" /* tooltip text, empty */
-+ );
-+ }
-+ /* close array */
-+ p_dbus_message_iter_close_container(&iter, &arr_iter);
-+
-+ TRACE( "Propgetall reply for icon %s\n", icon->dbus_name );
-+ dbus_send_safe(reply);
-+ p_dbus_message_unref(reply);
-+ return ret;
-+ }
-+ else if (p_dbus_message_is_method_call(msg, "org.kde.StatusNotifierItem", "Activate"))
-+ {
-+ /* Left click on status icon
-+ * VOID org.freedesktop.StatusNotifierItem.Activate (INT x, INT y); */
-+ TRACE( "org.kde.StatusNotifierItem:Activate()\n" );
-+ /* we ignore click coordinates here, because windows doesn't send it */
-+ relay_windows_message(icon, WM_LBUTTONDOWN);
-+ relay_windows_message(icon, WM_LBUTTONUP);
-+ /* TODO: should we emulate WM_MOUSEMOVE here? */
-+ }
-+ else if (p_dbus_message_is_method_call(msg, "org.kde.StatusNotifierItem", "ContextMenu"))
-+ {
-+ /* Right click on status icon
-+ * VOID org.freedesktop.StatusNotifierItem.ContextMenu (INT x, INT y); */
-+ TRACE( "org.kde.StatusNotifierItem:ContextMenu()\n" );
-+ relay_windows_message(icon, WM_RBUTTONDOWN);
-+ relay_windows_message(icon, WM_RBUTTONUP);
-+ }
-+ else if (p_dbus_message_is_method_call(msg, "org.kde.StatusNotifierItem", "SecondaryActivate"))
-+ {
-+ /* Middle click on status icon
-+ * VOID org.freedesktop.StatusNotifierItem.SecondaryActivate (INT x, INT y); */
-+ TRACE( "org.kde.StatusNotifierItem:SecondaryActivate()\n" );
-+ relay_windows_message(icon, WM_MBUTTONDOWN);
-+ relay_windows_message(icon, WM_MBUTTONUP);
-+ }
-+ else if (p_dbus_message_is_method_call(msg, "org.kde.StatusNotifierItem", "Scroll"))
-+ {
-+ /* Mouse scroll over StatusNotifierItem
-+ * VOID org.freedesktop.StatusNotifierItem.Scroll (INT delta, STRING orientation);
-+ * orientation can be one of: "horizontal", "vertical" */
-+ TRACE( "org.kde.StatusNotifierItem:Scroll()\n" );
-+ /* Windows does not send any mouse scroll events, or even WM_VSCROLL :( */
-+ }
-+ }
-+
-+ /* Message handler can return one of these values:
-+ * from enum DBusHandlerResult
-+ * DBUS_HANDLER_RESULT_HANDLED - Message has had its effect,
-+ no need to run more handlers.
-+ * DBUS_HANDLER_RESULT_NOT_YET_HANDLED - Message has not had any effect,
-+ see if other handlers want it.
-+ * DBUS_HANDLER_RESULT_NEED_MEMORY - Please try again later with more memory.
-+ */
-+ return ret;
-+}
-+
-+
-+/* DBus message loop thread function */
-+/* Infinite loop?? dlls/mountmgr.sys/dbus.c uses the similar approach! */
-+static DWORD WINAPI dbus_thread( void *arg )
-+{
-+ dbus_bool_t retb;
-+
-+ UNREFERENCED_PARAMETER(arg);
-+ if (!d_connection) return 1;
-+
-+ retb = TRUE;
-+ while (retb)
-+ {
-+ /* We call dbus_connection_send() when adding new icon,
-+ * for example, this can lead to race condition. That's why
-+ * there is a critical section here */
-+ EnterCriticalSection( &g_dconn_cs );
-+ /* reads data from socket (wait 100 ms) and calls message handler */
-+ retb = p_dbus_connection_read_write_dispatch( d_connection, 100 );
-+ LeaveCriticalSection( &g_dconn_cs );
-+ /* We need to release lock at least sometimes, that's why
-+ * here is Sleep() call here with timeout of 100 ms */
-+ Sleep(100);
-+ /* TODO: tweak timeouts? */
-+ }
-+
-+ /* This infinite loop can break if there was some DBus error
-+ * and connection was closed */
-+ WARN( "DBus: message loop has ended for some reason! Closing connection.\n" );
-+
-+ /* if we are here, we are probably not connected already */
-+ p_dbus_connection_unref(d_connection);
-+ d_connection = NULL;
-+
-+ /* mark as not running */
-+ g_dbus_thread_running = FALSE;
-+ return 0;
-+}
-+
-+
-+/* Starts dbus message loop thread, if it's not already running */
-+static void start_dbus_thread(void)
-+{
-+ HANDLE handle;
-+ if (g_dbus_thread_running) return;
-+
-+ handle = CreateThread( NULL, 0, dbus_thread, NULL, 0, NULL );
-+ if (handle)
-+ {
-+ g_dbus_thread_running = TRUE;
-+ CloseHandle( handle );
-+ TRACE( "started dbus_thread\n" );
-+ }
-+}
-+
-+
-+/* Establishes connection to DBus session bus.
-+ * Returns TRUE if connection is OK, FALSE otherwise.
-+ * Returns TRUE immediately if already connected. */
-+static BOOL connect_dbus(void)
-+{
-+ DBusError error;
-+ DBusObjectPathVTable vtable;
-+ dbus_bool_t resb;
-+
-+ if (d_connection) return TRUE; /* already connected */
-+ p_dbus_error_init( &error );
-+
-+ if (!(d_connection = p_dbus_bus_get( DBUS_BUS_SESSION, &error )))
-+ {
-+ WARN( "DBus: failed to connect to session bus: %s\n", error.message );
-+ p_dbus_error_free( &error );
-+ return FALSE;
-+ }
-+
-+ /* we do not want to exit(1) on any DBus error! */
-+ p_dbus_connection_set_exit_on_disconnect(d_connection, FALSE);
-+
-+ /* Register default message handler for root DBus object "/" */
-+ ZeroMemory(&vtable, sizeof(vtable));
-+ vtable.unregister_function = root_message_handler_unreg;
-+ vtable.message_function = root_message_handler;
-+ resb = p_dbus_connection_try_register_fallback(
-+ d_connection,
-+ "/", /* object path */
-+ &vtable, /* message handler functions */
-+ NULL, /* user_data */
-+ &error);
-+ if( resb == FALSE )
-+ {
-+ WARN("DBus: ERROR: Failed to register DBus root object "
-+ "message handler! Error: %s\n", error.message);
-+ p_dbus_error_free( &error );
-+ return FALSE;
-+ }
-+
-+ /* Run read/write dispatcher. This will actually call message handler,
-+ * if there are any messages incoming (and they are there).
-+ * The first message will be signal 'NameAcquired' from DBus
-+ * example: "DBus: message for path [/org/freedesktop/DBus] dest [:1.58],
-+ * intf [org.freedesktop.DBus].[NameAcquired]" */
-+ p_dbus_connection_read_write_dispatch(d_connection, 0);
-+ /* Of course, we will want real DBus message loop later, for real icons */
-+
-+ TRACE( "DBus: connected to SESSION bus as '%s'.\n",
-+ p_dbus_bus_get_unique_name(d_connection) );
-+ return TRUE;
-+}
-+
-+
-+static void disconnect_dbus(void)
-+{
-+ if (d_connection) {
-+ p_dbus_connection_unregister_object_path(d_connection, "/");
-+ p_dbus_connection_read_write_dispatch(d_connection, 0);
-+ p_dbus_connection_unref(d_connection);
-+ d_connection = NULL;
-+ TRACE( "DBus: disconnected.\n" );
-+ }
-+}
-+
-+
-+/* Check if org.kde.StatusNotifierWatcher is running on DBus, and read its
-+ * property IsStatusNotifierHostRegistered to determine if we can
-+ * use DBus StatusNotifierItem tray. */
-+static BOOL is_statusnotifier_host_running(void)
-+{
-+ DBusError error;
-+ DBusMessage *msg, *reply;
-+ const char *iface_name;
-+ const char *property_name;
-+ DBusMessageIter iter;
-+ DBusMessageIter sub_iter;
-+ dbus_bool_t is_sni_host_running = FALSE;
-+ int arg_type;
-+
-+ if (!d_connection) return FALSE;
-+ p_dbus_error_init( &error );
-+
-+ /* Check that there is StatusNotifierWatcher on bus.
-+ * According to DBus docs, this method can cause race condition,
-+ * StatusNotifierWatcher can disappear any time after this method
-+ * was called, but in that case the following DBus method call
-+ * will simply fail anyway. */
-+ if (p_dbus_bus_name_has_owner(
-+ d_connection, "org.kde.StatusNotifierWatcher", &error))
-+ {
-+ TRACE( "DBus: detected that org.kde.StatusNotifierWatcher present, "
-+ "will ask him about StatusNotifierHost!\n" );
-+ /* We need to read property "IsStatusNotifierHostRegistered"
-+ * of interface "org.kde.StatusNotifierWatcher"
-+ * which is on path "/StatusNotifierWatcher"
-+ * So, we need to call org.freedesktop.DBus.Properties.Get(...) on that
-+ * interface */
-+ msg = p_dbus_message_new_method_call(
-+ "org.kde.StatusNotifierWatcher", /* bus name */
-+ "/StatusNotifierWatcher", /* path */
-+ "org.freedesktop.DBus.Properties", /* interface */
-+ "Get"); /* method */
-+ if (msg)
-+ {
-+ /* Get() method has 2 parameters - interface name and
-+ * property name, set them */
-+ iface_name = "org.kde.StatusNotifierWatcher";
-+ property_name = "IsStatusNotifierHostRegistered";
-+ p_dbus_message_append_args(msg,
-+ DBUS_TYPE_STRING, &iface_name,
-+ DBUS_TYPE_STRING, &property_name,
-+ DBUS_TYPE_INVALID);
-+ /* send request and wait for reply for 1000 ms */
-+ reply = p_dbus_connection_send_with_reply_and_block(
-+ d_connection, msg,
-+ 1000, /* timeout in ms */
-+ &error);
-+ if (reply)
-+ {
-+ /* reply from org.kde.StatusNotifierWatcher will contain
-+ * Variant(bool), although in specification
-+ * org.freedesktop.StatusNotifierWatcher should return
-+ * simply bool, instead of Variant(bool) !!! */
-+ if (p_dbus_message_iter_init(reply, &iter))
-+ {
-+ /* Read only first message argument. Either it is
-+ * Bool, or Variant(bool) */
-+ arg_type = p_dbus_message_iter_get_arg_type(&iter);
-+ if (arg_type == DBUS_TYPE_VARIANT)
-+ {
-+ /* Variant(bool), recurse read iterator into Variant type */
-+ p_dbus_message_iter_recurse(&iter, &sub_iter);
-+ /* read its contained value */
-+ arg_type = p_dbus_message_iter_get_arg_type(&sub_iter);
-+ if (arg_type == DBUS_TYPE_BOOLEAN)
-+ {
-+ p_dbus_message_iter_get_basic(&sub_iter, &is_sni_host_running);
-+ TRACE( "DBus: OK: Got prop.get reply, "
-+ "IsStatusNotifierHostRegistered = %u\n",
-+ (unsigned)is_sni_host_running );
-+ }
-+ }
-+ else if (arg_type == DBUS_TYPE_BOOLEAN)
-+ {
-+ /* simply bool */
-+ p_dbus_message_iter_get_basic(&iter, &is_sni_host_running);
-+ TRACE( "DBus: OK: Got prop.get reply, "
-+ "IsStatusNotifierHostRegistered = %u\n",
-+ (unsigned)is_sni_host_running );
-+ }
-+ }
-+ p_dbus_message_unref(reply);
-+ p_dbus_message_unref(msg);
-+ return (is_sni_host_running ? TRUE : FALSE);
-+ }
-+ /* reply == NULL here, some error has happened */
-+ WARN( "DBus: error requesting property from StatusNotifierWatcher: "
-+ "%s", error.message );
-+ p_dbus_error_free( &error );
-+ p_dbus_message_unref(msg);
-+ return FALSE;
-+ }
-+ WARN( "DBus: Failed to create new DBus message!\n" );
-+ return FALSE;
-+ }
-+ TRACE( "DBus: name org.kde.StatusNotifierWatcher is not found on bus.\n" );
-+ return FALSE;
-+}
-+
-+
-+#endif /* SONAME_LIBDBUS_1 */
-+
-+
-+/* Check if Wine can use DBus StatusNotifierItem specification
-+ * to implement system tray icons. This should be called from
-+ * systray.c: wine_notify_icon() when performing tray icon operations.
-+ *
-+ * Returns TRUE, if compiled with DBus support and StatusNotifierHost
-+ * is detected running, FALSE otherwise. */
-+BOOL can_use_dbus_sni_systray(void)
-+{
-+#ifdef SONAME_LIBDBUS_1
-+ static int using_dbus_sni_systray = -1; /* -1 = unknown */
-+
-+ /* This environment variable can be set to completely disable
-+ * DBus-powered StatusNotifierItem systray support */
-+ if (getenv("WINE_DISABLE_SNI_SYSTRAY"))
-+ {
-+ TRACE( "env: WINE_DISABLE_SNI_SYSTRAY: DBus SNI systray disabled.\n");
-+ return FALSE;
-+ }
-+
-+ if (using_dbus_sni_systray == FALSE) return FALSE;
-+ if (using_dbus_sni_systray == TRUE) return TRUE;
-+
-+ /* check that we can at least load DBus library */
-+ if (!initialize_dbus())
-+ {
-+ using_dbus_sni_systray = FALSE;
-+ TRACE( "Not enabling DBus systray support: cannot load DBus library\n" );
-+ return FALSE;
-+ }
-+
-+ /* check that we can connect to session bus */
-+ if (!connect_dbus())
-+ {
-+ using_dbus_sni_systray = FALSE;
-+ return FALSE;
-+ }
-+
-+ /* check that there is a StatusNotifierHost present */
-+ if (is_statusnotifier_host_running())
-+ {
-+ TRACE( "DBus: detected that we can use DBus systray instead of XEmbed\n" );
-+ /* Do not disconnect from DBus here, we will probably use
-+ * this connection to manage status notifier items later ;) */
-+ using_dbus_sni_systray = TRUE;
-+ return TRUE;
-+ }
-+
-+ /* No DBus/SNI system tray detected, disconnect DBus and return FALSE */
-+ disconnect_dbus();
-+
-+ TRACE( "DBus: No DBus/SNI system tray was detected.\n" );
-+ return FALSE;
-+#else
-+ /* Compiled without DBus support? Cannot use DBus at all */
-+ TRACE( "Compiled without DBus support, cannot use DBus SNI systray\n" );
-+ return FALSE;
-+#endif
-+}
-+
-+
-+static void assign_tray_icon_data(struct tray_icon *icon, NOTIFYICONDATAW *nid)
-+{
-+ ICONINFO iconinfo;
-+ BITMAP bmColor;
-+ HBITMAP hbmColorCopy;
-+ DWORD icon_data_size;
-+
-+ /* copy state flags */
-+ if (nid->uFlags & NIF_STATE)
-+ {
-+ icon->state = (icon->state & ~nid->dwStateMask) | (nid->dwState & nid->dwStateMask);
-+ }
-+ /* copy icon */
-+ if (nid->uFlags & NIF_ICON)
-+ {
-+ /* delete old icon, if any */
-+ if (icon->image) DestroyIcon(icon->image);
-+ if (icon->icon_data) HeapFree(GetProcessHeap(), 0, icon->icon_data);
-+ icon->image = NULL;
-+ icon->icon_data = NULL;
-+ icon->icon_w = icon->icon_h = 0;
-+
-+ /* set new icon */
-+ if (nid->hIcon)
-+ {
-+ icon->image = CopyIcon(nid->hIcon);
-+ if (GetIconInfo(nid->hIcon, &iconinfo))
-+ {
-+ TRACE( "fIcon = %u, (hotspot %d, %d) mask = %p, color = %p\n", iconinfo.fIcon,
-+ iconinfo.xHotspot, iconinfo.yHotspot,
-+ iconinfo.hbmMask, iconinfo.hbmColor);
-+ TRACE( "System icon size: %d x %d\n", GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
-+
-+ ZeroMemory(&bmColor, sizeof(BITMAP));
-+
-+ if (iconinfo.hbmColor)
-+ {
-+ hbmColorCopy = CopyImage(iconinfo.hbmColor, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
-+ if (hbmColorCopy)
-+ {
-+ GetObjectW(hbmColorCopy, sizeof(BITMAP), &bmColor);
-+ /* MSDN: If hgdiobj is a handle to a bitmap created by any other means,
-+ * (not by CreateDIBSection) GetObject returns only the width, height,
-+ * and color format information of the bitmap. You can obtain the bitmap's
-+ * bit values by calling the GetDIBits or GetBitmapBits function.
-+ * But we created bitmap copy with LR_CREATEDIBSECTION, and we HAVE
-+ * bits pointer! */
-+ TRACE( "Got color bitmap: bmType = %d\n", bmColor.bmType );
-+ TRACE( " size = %d x %d\n", bmColor.bmWidth, bmColor.bmHeight );
-+ TRACE( " scanline bytes = %d\n", bmColor.bmWidthBytes );
-+ TRACE( " color planes = %d\n", (int)bmColor.bmPlanes );
-+ TRACE( " bits per pixel = %d\n", (int)bmColor.bmBitsPixel );
-+ TRACE( " bits pointer = %p\n", bmColor.bmBits );
-+
-+ /* SNI spec says image format must be ARGB32, so we handle only 32(24)-bit image */
-+ if (bmColor.bmBits && (bmColor.bmBitsPixel == 32))
-+ {
-+ /* image data size = w * h * (bits_per_pixel / 8) */
-+ icon_data_size = bmColor.bmWidth * bmColor.bmHeight * bmColor.bmBitsPixel / 8;
-+ icon->icon_data = (unsigned char *)HeapAlloc(GetProcessHeap(), 0, icon_data_size);
-+ if (icon->icon_data)
-+ {
-+ unsigned char *row_dst, *row_src;
-+ int irow, j;
-+ ZeroMemory(icon->icon_data, icon_data_size);
-+ row_dst = icon->icon_data;
-+ row_src = (unsigned char *)bmColor.bmBits;
-+ /* make row_src point to lat row, to flip image bottom to top */
-+ row_src += ((bmColor.bmHeight - 1) * bmColor.bmWidthBytes);
-+ for (irow = 0; irow < bmColor.bmHeight; irow++)
-+ {
-+ for (j=0; j<bmColor.bmWidthBytes; j+=4)
-+ {
-+ /* change byte order so that BGRA (as in RGBQUAD structure
-+ * becomes ARGB, as required by SNI spec */
-+ row_dst[j + 0] = row_src[j + 3]; /* B -> A */
-+ row_dst[j + 1] = row_src[j + 2]; /* G -> R */
-+ row_dst[j + 2] = row_src[j + 1]; /* R -> G */
-+ row_dst[j + 3] = row_src[j + 0]; /* A -> B */
-+ }
-+ row_src -= bmColor.bmWidthBytes; /* move 1 row backward */
-+ row_dst += bmColor.bmWidthBytes; /* move 1 row forward */
-+ }
-+ /* memcpy(icon->icon_data, bmColor.bmBits, icon_data_size); */
-+ icon->icon_w = (int)bmColor.bmWidth;
-+ icon->icon_h = (int)bmColor.bmHeight;
-+ TRACE( "Saved icon bitmap, %u bytes\n", icon_data_size );
-+ }
-+ }
-+
-+ DeleteObject(hbmColorCopy);
-+ }
-+ }
-+ if (iconinfo.hbmMask) DeleteObject(iconinfo.hbmMask);
-+ if (iconinfo.hbmColor) DeleteObject(iconinfo.hbmColor);
-+ }
-+ }
-+ }
-+ /* copy callback message */
-+ if (nid->uFlags & NIF_MESSAGE)
-+ {
-+ icon->callback_message = nid->uCallbackMessage;
-+ }
-+ /* copy tooltip data */
-+ if (nid->uFlags & NIF_TIP)
-+ {
-+ lstrcpynW(icon->tiptext, nid->szTip, sizeof(icon->tiptext)/sizeof(WCHAR));
-+ }
-+ /* copy balloon popup data */
-+ if (nid->uFlags & NIF_INFO && nid->cbSize >= NOTIFYICONDATAA_V2_SIZE)
-+ {
-+ /* has balloon popup members */
-+ lstrcpynW( icon->info_text, nid->szInfo, sizeof(icon->info_text)/sizeof(WCHAR) );
-+ lstrcpynW( icon->info_title, nid->szInfoTitle, sizeof(icon->info_title)/sizeof(WCHAR) );
-+ icon->info_flags = nid->dwInfoFlags;
-+ icon->info_timeout = max(min(nid->u.uTimeout, BALLOON_SHOW_MAX_TIMEOUT), BALLOON_SHOW_MIN_TIMEOUT);
-+ icon->info_icon = nid->hBalloonIcon;
-+ }
-+}
-+
-+
-+BOOL add_sni_icon(NOTIFYICONDATAW *nid)
-+{
-+#ifdef SONAME_LIBDBUS_1
-+ struct tray_icon *icon;
-+ int res;
-+ dbus_bool_t resb;
-+ DBusError derror;
-+ DBusMessage *req;
-+ char *NPE_FIX;
-+ DWORD owner_pid;
-+
-+ TRACE("id=0x%x, hwnd=%p\n", nid->uID, nid->hWnd);
-+
-+ /* check if icon already exists */
-+ if ((icon = get_icon_from_list(nid->hWnd, nid->uID)))
-+ {
-+ WARN("DBus: duplicate tray icon add, buggy app?\n");
-+ return FALSE;
-+ }
-+
-+ /* allocate new icon struct and add it to list */
-+ icon = add_new_icon_to_list();
-+ if (!icon) return FALSE;
-+
-+ /* init structure members */
-+ icon->id = nid->uID;
-+ icon->owner = nid->hWnd;
-+ icon->display = -1; /* display index, or -1 if hidden */
-+
-+ assign_tray_icon_data(icon, nid);
-+
-+ /* Ensure that dbus message loop is running */
-+ start_dbus_thread();
-+
-+ /* request some particular name on session bus */
-+ /* Format: org.kde.StatusNotifierItem-PID-ICONID */
-+ GetWindowThreadProcessId(icon->owner, &owner_pid);
-+ snprintf(icon->dbus_name, sizeof(icon->dbus_name)-1,
-+ "org.kde.StatusNotifierItem-%u-%u",
-+ owner_pid, nid->uID);
-+
-+ p_dbus_error_init( &derror );
-+
-+ TRACE( "Requesting name [%s]...\n", icon->dbus_name );
-+ EnterCriticalSection( &g_dconn_cs );
-+ res = p_dbus_bus_request_name(d_connection, icon->dbus_name,
-+ DBUS_NAME_FLAG_DO_NOT_QUEUE, &derror);
-+ LeaveCriticalSection( &g_dconn_cs );
-+ if( res != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER ) {
-+ ERR("DBus: Request name failed! Not primary owner! code=%d\n", res);
-+ ERR("DBus error: %s\n", derror.message);
-+ p_dbus_error_free( &derror );
-+ return FALSE;
-+ }
-+ TRACE( "Request name [%s] OK!\n", icon->dbus_name );
-+
-+ /* calculate and store title that will be used in several places
-+ * - as a tooltip title, popup title
-+ * - as icon identifier, maybe
-+ * ideally it should be process name */
-+ /*HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, owner_pid);
-+ if (hProcess)
-+ {
-+ GetProcessImageFileNameA(hProcess, icon->sni_title, sizeof(icon->sni_title)-1)
-+ CloseHandle(hProcess);
-+ } */
-+ /* This requires linking to psapi.dll and include "psapi.h" :/ */
-+
-+ /* GetModuleFileNameA(NULL, icon->sni_title, sizeof(icon->sni_title)-1); */
-+ /* ^^ This returns [C:\windows\system32\explorer.exe], because winex11.drv is loaded
-+ * by explorer.exe? But we cannot use it as icon identifier then :) */
-+
-+ /* TRACE( "command line: [%s]\n", GetCommandLineA() ); */
-+ /* [C:\windows\system32\explorer.exe /desktop], the same, cannot use */
-+
-+ lstrcpynA(icon->sni_title, "wine", sizeof(icon->sni_title)-1);
-+
-+ TRACE( "Using [%s] as application name\n", icon->sni_title );
-+
-+ /* Try to communicate with StatusNotifierWatcher:
-+ * tell him that we are here and we have a status icon! */
-+ req = p_dbus_message_new_method_call(
-+ "org.kde.StatusNotifierWatcher", /* dest */
-+ "/StatusNotifierWatcher", /* path */
-+ "org.kde.StatusNotifierWatcher", /* iface */
-+ "RegisterStatusNotifierItem" /* method */
-+ );
-+ /* we need to pass him our BUS NAME in message */
-+ NPE_FIX = strdup(icon->dbus_name);
-+ if( NPE_FIX ) {
-+ p_dbus_message_append_args(req,
-+ DBUS_TYPE_STRING, &NPE_FIX,
-+ DBUS_TYPE_INVALID);
-+ free(NPE_FIX);
-+ }
-+ resb = dbus_send_safe(req);
-+ if (resb == FALSE)
-+ {
-+ WARN("dbus_connection_send() failed: cannot register our SNI!\n");
-+ p_dbus_message_unref(req);
-+ return FALSE;
-+ }
-+
-+ return TRUE;
-+#else
-+ /* complied without DBus support */
-+ UNREFERENCED_PARAMETER(nid);
-+ return FALSE;
-+#endif
-+}
-+
-+
-+BOOL modify_sni_icon(NOTIFYICONDATAW *nid)
-+{
-+#ifdef SONAME_LIBDBUS_1
-+ struct tray_icon *icon;
-+
-+ TRACE("id=0x%x, hwnd=%p\n", nid->uID, nid->hWnd);
-+
-+ icon = get_icon_from_list(nid->hWnd, nid->uID);
-+ if (!icon) return FALSE;
-+
-+ /* update structure members */
-+ assign_tray_icon_data(icon, nid);
-+
-+ /* icon has changed? */
-+ if (nid->uFlags & NIF_ICON)
-+ {
-+ /* icon data was already updated by assign_tray_icon_data() */
-+ /* Notify SNI host about it */
-+ send_signal_noargs( "NewIcon" );
-+ }
-+
-+ /* szTip has changed? */
-+ if (nid->uFlags & NIF_TIP)
-+ {
-+ /* Notify SNI host about new tooltip */
-+ send_signal_noargs( "NewToolTip" );
-+ }
-+
-+ /* balloon popup was updated? */
-+ if (nid->uFlags & NIF_INFO && nid->cbSize >= NOTIFYICONDATAA_V2_SIZE)
-+ {
-+ /* Notify SNI host that our icon needs attention */
-+ /* actually it was active all the time, but maybe it will change in future */
-+ send_signal_NewStatus( "NeedsAttention" ); /* possible values: Active, Passive, NeedsAttention */
-+ /* TODO: deal with balloon */
-+ /* update_balloon( icon ); */
-+ }
-+
-+ /* TODO: implement hiding icon?
-+ if (icon->state & NIS_HIDDEN) hide_icon( icon );
-+ else show_icon( icon );
-+ */
-+
-+ /* We don't use these SNI signals: NewTitle, NewAttentionIcon, NewOverlayIcon */
-+
-+ return TRUE;
-+#else
-+ /* complied without DBus support */
-+ UNREFERENCED_PARAMETER(nid);
-+ return FALSE;
-+#endif
-+}
-+
-+
-+static BOOL delete_icon(struct tray_icon *icon)
-+{
-+ BOOL ret;
-+ int res;
-+ DBusError derror;
-+
-+ if (!d_connection) return FALSE;
-+
-+ /* Release dedicated SNI bus name */
-+ p_dbus_error_init( &derror );
-+ res = p_dbus_bus_release_name(d_connection, icon->dbus_name, &derror);
-+ if( res != DBUS_RELEASE_NAME_REPLY_RELEASED ) {
-+ WARN( "DBus: Release name failed! Err code=%d\n", res );
-+ WARN( "DBus error: %s\n", derror.message );
-+ ret = FALSE;
-+ } else {
-+ TRACE( "DBus: Name released [%s] OK!\n", icon->dbus_name );
-+ ret = TRUE;
-+ }
-+
-+ /* Do not forget to delete hIcon ? */
-+ if (icon->image) DestroyIcon(icon->image);
-+ if (icon->icon_data) HeapFree(GetProcessHeap(), 0, icon->icon_data);
-+ icon->image = NULL;
-+ icon->icon_data = NULL;
-+ icon->icon_w = icon->icon_h = 0;
-+
-+ delete_icon_from_list( icon );
-+ return ret;
-+}
-+
-+
-+
-+BOOL delete_sni_icon(NOTIFYICONDATAW *nid)
-+{
-+#ifdef SONAME_LIBDBUS_1
-+ struct tray_icon *icon;
-+
-+ TRACE("id=0x%x, hwnd=%p\n", nid->uID, nid->hWnd);
-+
-+ icon = get_icon_from_list(nid->hWnd, nid->uID);
-+ if (!icon) return FALSE;
-+
-+ return delete_icon( icon );
-+#else
-+ /* complied without DBus support */
-+ UNREFERENCED_PARAMETER(nid);
-+ return FALSE;
-+#endif
-+}
---