mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Rebase against 797df8df394d81a165328f9ac6b4039253a78718.
This commit is contained in:
parent
0d4b9f2f62
commit
0e802db66f
@ -1,4 +1,4 @@
|
||||
From 1e7b6a812b248a8344076a402fc97bd60da495d1 Mon Sep 17 00:00:00 2001
|
||||
From 0173ca4b3352506b76801619ae5a05f338d6ff6e Mon Sep 17 00:00:00 2001
|
||||
From: Jason Edmeades <us@edmeades.me.uk>
|
||||
Date: Tue, 16 Jul 2019 13:49:18 +1000
|
||||
Subject: [PATCH] cmd: Support for launching programs based on file association
|
||||
@ -15,10 +15,10 @@ Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=36646
|
||||
1 file changed, 102 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
|
||||
index 12d3db1b012..0f222f3640b 100644
|
||||
index ce48b16d7ec..2d20ee299fa 100644
|
||||
--- a/programs/cmd/wcmdmain.c
|
||||
+++ b/programs/cmd/wcmdmain.c
|
||||
@@ -1494,8 +1494,10 @@ void WCMD_run_program (WCHAR *command, BOOL called)
|
||||
@@ -1541,8 +1541,10 @@ void WCMD_run_program (WCHAR *command, BOOL called)
|
||||
|
||||
/* 1. If extension supplied, see if that file exists */
|
||||
if (extensionsupplied) {
|
||||
@ -30,7 +30,7 @@ index 12d3db1b012..0f222f3640b 100644
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1525,6 +1527,7 @@ void WCMD_run_program (WCHAR *command, BOOL called)
|
||||
@@ -1572,6 +1574,7 @@ void WCMD_run_program (WCHAR *command, BOOL called)
|
||||
}
|
||||
|
||||
if (GetFileAttributesW(thisDir) != INVALID_FILE_ATTRIBUTES) {
|
||||
@ -38,17 +38,17 @@ index 12d3db1b012..0f222f3640b 100644
|
||||
found = TRUE;
|
||||
thisExt = NULL;
|
||||
}
|
||||
@@ -1546,6 +1549,7 @@ void WCMD_run_program (WCHAR *command, BOOL called)
|
||||
/* Special case BAT and CMD */
|
||||
if (ext && (!wcsicmp(ext, L".bat") || !wcsicmp(ext, L".cmd"))) {
|
||||
@@ -1595,6 +1598,7 @@ void WCMD_run_program (WCHAR *command, BOOL called)
|
||||
RETURN_CODE return_code;
|
||||
BOOL oldinteractive = interactive;
|
||||
|
||||
+ WINE_TRACE("Calling batch program\n");
|
||||
interactive = FALSE;
|
||||
WCMD_batch(thisDir, command, NULL, INVALID_HANDLE_VALUE);
|
||||
return_code = WCMD_batch(thisDir, command, NULL, INVALID_HANDLE_VALUE);
|
||||
interactive = oldinteractive;
|
||||
@@ -1554,48 +1558,109 @@ void WCMD_run_program (WCHAR *command, BOOL called)
|
||||
context->skip_rest = TRUE;
|
||||
}
|
||||
@@ -1605,48 +1609,109 @@ void WCMD_run_program (WCHAR *command, BOOL called)
|
||||
if (return_code != RETURN_CODE_ABORTED && return_code != RETURN_CODE_OLD_CHAINING)
|
||||
errorlevel = return_code;
|
||||
return;
|
||||
- } else {
|
||||
- DWORD exit_code;
|
||||
@ -193,5 +193,5 @@ index 12d3db1b012..0f222f3640b 100644
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
2.45.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From f6d47bb4eb5747fde7059271a560268080756791 Mon Sep 17 00:00:00 2001
|
||||
From 96af775034dae1c0b133b315c45b7172090d3498 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Costa <titan.costa@gmail.com>
|
||||
Date: Sun, 11 Jan 2015 16:29:30 +0100
|
||||
Subject: [PATCH] d3dx9_36: Improve D3DXSaveTextureToFile to save simple
|
||||
@ -6,15 +6,15 @@ Subject: [PATCH] d3dx9_36: Improve D3DXSaveTextureToFile to save simple
|
||||
|
||||
---
|
||||
dlls/d3dx9_36/d3dx9_private.h | 2 ++
|
||||
dlls/d3dx9_36/surface.c | 62 +++++++++++++++++++++++++++++++++++
|
||||
dlls/d3dx9_36/surface.c | 63 +++++++++++++++++++++++++++++++++++
|
||||
dlls/d3dx9_36/texture.c | 5 +--
|
||||
3 files changed, 65 insertions(+), 4 deletions(-)
|
||||
3 files changed, 66 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h
|
||||
index 001a7f26f4f..b322765d164 100644
|
||||
index 34a9f6eec7f..878dff3fc01 100644
|
||||
--- a/dlls/d3dx9_36/d3dx9_private.h
|
||||
+++ b/dlls/d3dx9_36/d3dx9_private.h
|
||||
@@ -182,6 +182,8 @@ HRESULT lock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, D3DLO
|
||||
@@ -178,6 +178,8 @@ HRESULT lock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, D3DLO
|
||||
IDirect3DSurface9 **temp_surface, BOOL write);
|
||||
HRESULT unlock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect,
|
||||
IDirect3DSurface9 *temp_surface, BOOL update);
|
||||
@ -24,10 +24,10 @@ index 001a7f26f4f..b322765d164 100644
|
||||
const PALETTEENTRY *palette, D3DFORMAT format, uint32_t left, uint32_t top, uint32_t right, uint32_t bottom,
|
||||
uint32_t front, uint32_t back, struct d3dx_pixels *pixels);
|
||||
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
|
||||
index fb49ca5665a..2a8bd97fe2d 100644
|
||||
index 31bce97bbab..212d452c654 100644
|
||||
--- a/dlls/d3dx9_36/surface.c
|
||||
+++ b/dlls/d3dx9_36/surface.c
|
||||
@@ -560,6 +560,68 @@ static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSur
|
||||
@@ -574,6 +574,69 @@ static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSur
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
@ -93,14 +93,15 @@ index fb49ca5665a..2a8bd97fe2d 100644
|
||||
+
|
||||
+ return hr;
|
||||
+}
|
||||
HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette,
|
||||
const D3DBOX *dst_box, const void *src_data, const D3DBOX *src_box, DWORD filter, D3DCOLOR color_key,
|
||||
const D3DXIMAGE_INFO *src_info)
|
||||
+
|
||||
HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const void *src_data,
|
||||
const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info)
|
||||
{
|
||||
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c
|
||||
index 52cfb1e8c34..ccbe1fcef20 100644
|
||||
index b42c9db3f2d..d84bac25cfe 100644
|
||||
--- a/dlls/d3dx9_36/texture.c
|
||||
+++ b/dlls/d3dx9_36/texture.c
|
||||
@@ -1858,10 +1858,7 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE
|
||||
@@ -1847,10 +1847,7 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE
|
||||
if (!dst_buffer || !src_texture) return D3DERR_INVALIDCALL;
|
||||
|
||||
if (file_format == D3DXIFF_DDS)
|
||||
@ -113,5 +114,5 @@ index 52cfb1e8c34..ccbe1fcef20 100644
|
||||
type = IDirect3DBaseTexture9_GetType(src_texture);
|
||||
switch (type)
|
||||
--
|
||||
2.43.0
|
||||
2.45.2
|
||||
|
||||
|
@ -1,88 +0,0 @@
|
||||
From 702145ee9253eb9c92225118830e3d9d999a803a Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Wed, 18 Mar 2015 23:03:01 +0100
|
||||
Subject: [PATCH] ntdll: Implement virtual_map_shared_memory.
|
||||
|
||||
Preparation for shared memory wineserver communication.
|
||||
---
|
||||
dlls/ntdll/ntdll_misc.h | 1 +
|
||||
dlls/ntdll/virtual.c | 51 +++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 52 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
|
||||
index 76e8ec284e8..7e7ce5413dd 100644
|
||||
--- a/dlls/ntdll/ntdll_misc.h
|
||||
+++ b/dlls/ntdll/ntdll_misc.h
|
||||
@@ -204,6 +204,7 @@ extern NTSTATUS virtual_alloc_teb( TEB **teb ) DECLSPEC_HIDDEN;
|
||||
extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size,
|
||||
SIZE_T commit_size, SIZE_T *pthread_size ) DECLSPEC_HIDDEN;
|
||||
+extern NTSTATUS virtual_map_shared_memory( int fd, PVOID *addr_ptr, ULONG zero_bits, SIZE_T *size_ptr, ULONG protect ) DECLSPEC_HIDDEN;
|
||||
extern void virtual_clear_thread_stack( void *stack_end ) DECLSPEC_HIDDEN;
|
||||
extern int virtual_handle_stack_fault( void *addr ) DECLSPEC_HIDDEN;
|
||||
extern BOOL virtual_is_valid_code_address( const void *addr, SIZE_T size ) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
|
||||
index 7700385eb7b..cf08937cb14 100644
|
||||
--- a/dlls/ntdll/virtual.c
|
||||
+++ b/dlls/ntdll/virtual.c
|
||||
@@ -3551,6 +3551,57 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
||||
}
|
||||
|
||||
|
||||
+/***********************************************************************
|
||||
+ * virtual_map_shared_memory
|
||||
+ */
|
||||
+NTSTATUS virtual_map_shared_memory( int fd, PVOID *addr_ptr, ULONG zero_bits,
|
||||
+ SIZE_T *size_ptr, ULONG protect )
|
||||
+{
|
||||
+ SIZE_T size;
|
||||
+ struct file_view *view;
|
||||
+ unsigned int vprot;
|
||||
+ sigset_t sigset;
|
||||
+ NTSTATUS res;
|
||||
+ int prot;
|
||||
+
|
||||
+ size = ROUND_SIZE( 0, *size_ptr );
|
||||
+ if (size < *size_ptr)
|
||||
+ return STATUS_INVALID_PARAMETER;
|
||||
+
|
||||
+ server_enter_uninterrupted_section( &csVirtual, &sigset );
|
||||
+
|
||||
+ get_vprot_flags( protect, &vprot, FALSE );
|
||||
+ vprot |= VPROT_COMMITTED;
|
||||
+ res = map_view( &view, *addr_ptr, size, FALSE, vprot, 0 );
|
||||
+ if (!res)
|
||||
+ {
|
||||
+ /* Map the shared memory */
|
||||
+
|
||||
+ prot = VIRTUAL_GetUnixProt( vprot );
|
||||
+ if (force_exec_prot && (vprot & VPROT_READ))
|
||||
+ {
|
||||
+ TRACE( "forcing exec permission on mapping %p-%p\n",
|
||||
+ (char *)view->base, (char *)view->base + size - 1 );
|
||||
+ prot |= PROT_EXEC;
|
||||
+ }
|
||||
+
|
||||
+ if (mmap( view->base, size, prot, MAP_FIXED | MAP_SHARED, fd, 0 ) != (void *)-1)
|
||||
+ {
|
||||
+ *addr_ptr = view->base;
|
||||
+ *size_ptr = size;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ERR( "virtual_map_shared_memory %p %lx failed\n", view->base, size );
|
||||
+ delete_view( view );
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ server_leave_uninterrupted_section( &csVirtual, &sigset );
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/***********************************************************************
|
||||
* NtUnmapViewOfSection (NTDLL.@)
|
||||
* ZwUnmapViewOfSection (NTDLL.@)
|
||||
--
|
||||
2.26.2
|
||||
|
@ -1,424 +0,0 @@
|
||||
From 0329ba2101bf6667bdfaa66bd70253b57ca4fdd1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Thu, 19 Mar 2015 01:22:34 +0100
|
||||
Subject: [PATCH] server: Implement support for global and local shared memory
|
||||
blocks based on memfd.
|
||||
|
||||
---
|
||||
dlls/ntdll/ntdll_misc.h | 1 +
|
||||
dlls/ntdll/server.c | 64 +++++++++++++++++++++++++++++++++++
|
||||
dlls/ntdll/thread.c | 4 +++
|
||||
include/wine/server.h | 11 ++++++
|
||||
include/winternl.h | 2 +-
|
||||
server/fd.c | 27 +++++++++++++++
|
||||
server/file.h | 8 +++++
|
||||
server/main.c | 1 +
|
||||
server/mapping.c | 74 +++++++++++++++++++++++++++++++++++++++++
|
||||
server/protocol.def | 15 +++++++++
|
||||
server/thread.c | 7 ++++
|
||||
server/thread.h | 2 ++
|
||||
12 files changed, 215 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
|
||||
index d83166a0ffc9..f57189112a0c 100644
|
||||
--- a/dlls/ntdll/ntdll_misc.h
|
||||
+++ b/dlls/ntdll/ntdll_misc.h
|
||||
@@ -140,6 +140,7 @@ extern int server_pipe( int fd[2] ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret,
|
||||
data_size_t *ret_len ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS validate_open_object_attributes( const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN;
|
||||
+extern void *server_get_shared_memory( HANDLE thread ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* module handling */
|
||||
extern LIST_ENTRY tls_links DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
|
||||
index 2ebc39e03e25..f004ed07d27e 100644
|
||||
--- a/dlls/ntdll/server.c
|
||||
+++ b/dlls/ntdll/server.c
|
||||
@@ -1149,6 +1149,66 @@ done:
|
||||
}
|
||||
|
||||
|
||||
+/***********************************************************************
|
||||
+ * server_get_shared_memory_fd
|
||||
+ *
|
||||
+ * Receive a file descriptor to a server shared memory block.
|
||||
+ */
|
||||
+static int server_get_shared_memory_fd( HANDLE thread, int *unix_fd )
|
||||
+{
|
||||
+ obj_handle_t dummy;
|
||||
+ sigset_t sigset;
|
||||
+ int ret;
|
||||
+
|
||||
+ server_enter_uninterrupted_section( &fd_cache_section, &sigset );
|
||||
+
|
||||
+ SERVER_START_REQ( get_shared_memory )
|
||||
+ {
|
||||
+ req->tid = HandleToULong(thread);
|
||||
+ if (!(ret = wine_server_call( req )))
|
||||
+ {
|
||||
+ *unix_fd = receive_fd( &dummy );
|
||||
+ if (*unix_fd == -1) ret = STATUS_NOT_SUPPORTED;
|
||||
+ }
|
||||
+ }
|
||||
+ SERVER_END_REQ;
|
||||
+
|
||||
+ server_leave_uninterrupted_section( &fd_cache_section, &sigset );
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/***********************************************************************
|
||||
+ * server_get_shared_memory
|
||||
+ *
|
||||
+ * Get address of a shared memory block.
|
||||
+ */
|
||||
+void *server_get_shared_memory( HANDLE thread )
|
||||
+{
|
||||
+ static shmglobal_t *shmglobal = (void *)-1;
|
||||
+ void *mem = NULL;
|
||||
+ int fd = -1;
|
||||
+
|
||||
+ /* The global memory block is only requested once. No locking is
|
||||
+ * required because this function is called very early during the
|
||||
+ * process initialization for the first time. */
|
||||
+ if (!thread && shmglobal != (void *)-1)
|
||||
+ return shmglobal;
|
||||
+
|
||||
+ if (!server_get_shared_memory_fd( thread, &fd ))
|
||||
+ {
|
||||
+ SIZE_T size = thread ? sizeof(shmlocal_t) : sizeof(shmglobal_t);
|
||||
+ virtual_map_shared_memory( fd, &mem, 0, &size, PAGE_READONLY );
|
||||
+ close( fd );
|
||||
+ }
|
||||
+
|
||||
+ if (!thread)
|
||||
+ shmglobal = mem;
|
||||
+
|
||||
+ return mem;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/***********************************************************************
|
||||
* wine_server_fd_to_handle (NTDLL.@)
|
||||
*
|
||||
@@ -2011,6 +2071,10 @@ size_t server_init_thread( void *entry_point, BOOL *suspend )
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
+ /* initialize thread shared memory pointers */
|
||||
+ NtCurrentTeb()->Reserved5[1] = server_get_shared_memory( 0 );
|
||||
+ NtCurrentTeb()->Reserved5[2] = server_get_shared_memory( NtCurrentTeb()->ClientId.UniqueThread );
|
||||
+
|
||||
is_wow64 = !is_win64 && (server_cpus & ((1 << CPU_x86_64) | (1 << CPU_ARM64))) != 0;
|
||||
ntdll_get_thread_data()->wow64_redir = is_wow64;
|
||||
|
||||
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
|
||||
index 8a0b612b39a4..464e01b1e305 100644
|
||||
--- a/dlls/ntdll/thread.c
|
||||
+++ b/dlls/ntdll/thread.c
|
||||
@@ -429,6 +429,7 @@ void exit_thread( int status )
|
||||
void WINAPI RtlExitUserThread( ULONG status )
|
||||
{
|
||||
static void *prev_teb;
|
||||
+ shmlocal_t *shmlocal;
|
||||
sigset_t sigset;
|
||||
TEB *teb;
|
||||
|
||||
@@ -453,6 +454,9 @@ void WINAPI RtlExitUserThread( ULONG status )
|
||||
LdrShutdownThread();
|
||||
RtlFreeThreadActivationContextStack();
|
||||
|
||||
+ shmlocal = InterlockedExchangePointer( &NtCurrentTeb()->Reserved5[2], NULL );
|
||||
+ if (shmlocal) NtUnmapViewOfSection( NtCurrentProcess(), shmlocal );
|
||||
+
|
||||
pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
|
||||
|
||||
if ((teb = InterlockedExchangePointer( &prev_teb, NtCurrentTeb() )))
|
||||
diff --git a/include/wine/server.h b/include/wine/server.h
|
||||
index ac5dcc6f8bcd..5a845f424c28 100644
|
||||
--- a/include/wine/server.h
|
||||
+++ b/include/wine/server.h
|
||||
@@ -120,6 +120,17 @@ static inline void *wine_server_get_ptr( client_ptr_t ptr )
|
||||
return (void *)(ULONG_PTR)ptr;
|
||||
}
|
||||
|
||||
+/* returns a pointer to the wineserver global shared memory block */
|
||||
+static inline shmglobal_t *wine_get_shmglobal(void)
|
||||
+{
|
||||
+ return (shmglobal_t *)NtCurrentTeb()->Reserved5[1];
|
||||
+}
|
||||
+
|
||||
+/* returns a pointer to the wineserver local shared memory block */
|
||||
+static inline shmlocal_t *wine_get_shmlocal(void)
|
||||
+{
|
||||
+ return (shmlocal_t *)NtCurrentTeb()->Reserved5[2];
|
||||
+}
|
||||
|
||||
/* macros for server requests */
|
||||
|
||||
diff --git a/include/winternl.h b/include/winternl.h
|
||||
index 1d2d49414448..39c269d29163 100644
|
||||
--- a/include/winternl.h
|
||||
+++ b/include/winternl.h
|
||||
@@ -403,7 +403,7 @@ typedef struct _TEB
|
||||
PVOID ReservedForPerf; /* f7c/1750 */
|
||||
PVOID ReservedForOle; /* f80/1758 */
|
||||
ULONG WaitingOnLoaderLock; /* f84/1760 */
|
||||
- PVOID Reserved5[3]; /* f88/1768 */
|
||||
+ PVOID Reserved5[3]; /* f88/1768 used for x86_64 OSX and wineserver shared memory */
|
||||
PVOID *TlsExpansionSlots; /* f94/1780 */
|
||||
#ifdef _WIN64
|
||||
PVOID DeallocationBStore; /* /1788 */
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index 405240e14d84..cc8df828a653 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -2704,6 +2704,33 @@ DECL_HANDLER(write)
|
||||
release_object( fd );
|
||||
}
|
||||
|
||||
+/* get file descriptor to shared memory block */
|
||||
+DECL_HANDLER(get_shared_memory)
|
||||
+{
|
||||
+ if (req->tid)
|
||||
+ {
|
||||
+ struct thread *thread = get_thread_from_id( req->tid );
|
||||
+ if (thread)
|
||||
+ {
|
||||
+ if (thread->shm_fd != -1 || allocate_shared_memory( &thread->shm_fd,
|
||||
+ (void **)&thread->shm, sizeof(*thread->shm) ))
|
||||
+ {
|
||||
+ send_client_fd( current->process, thread->shm_fd, 0 );
|
||||
+ }
|
||||
+ else
|
||||
+ set_error( STATUS_NOT_SUPPORTED );
|
||||
+ release_object( thread );
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (shmglobal_fd != -1)
|
||||
+ send_client_fd( current->process, shmglobal_fd, 0 );
|
||||
+ else
|
||||
+ set_error( STATUS_NOT_SUPPORTED );
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* perform an ioctl on a file */
|
||||
DECL_HANDLER(ioctl)
|
||||
{
|
||||
diff --git a/server/file.h b/server/file.h
|
||||
index d577aaed3cfa..399f512cf49e 100644
|
||||
--- a/server/file.h
|
||||
+++ b/server/file.h
|
||||
@@ -182,6 +182,14 @@ extern struct object *create_mailslot_device( struct object *root, const struct
|
||||
extern struct object *create_unix_device( struct object *root, const struct unicode_str *name,
|
||||
const char *unix_path );
|
||||
|
||||
+/* shared memory functions */
|
||||
+
|
||||
+extern int allocate_shared_memory( int *fd, void **memory, size_t size );
|
||||
+extern void release_shared_memory( int fd, void *memory, size_t size );
|
||||
+extern void init_shared_memory( void );
|
||||
+extern shmglobal_t *shmglobal;
|
||||
+extern int shmglobal_fd;
|
||||
+
|
||||
/* change notification functions */
|
||||
|
||||
extern void do_change_notify( int unix_fd );
|
||||
diff --git a/server/main.c b/server/main.c
|
||||
index 2b5065e18526..483a0c855808 100644
|
||||
--- a/server/main.c
|
||||
+++ b/server/main.c
|
||||
@@ -146,6 +146,7 @@ int main( int argc, char *argv[] )
|
||||
init_signals();
|
||||
init_directories();
|
||||
init_registry();
|
||||
+ init_shared_memory();
|
||||
main_loop();
|
||||
return 0;
|
||||
}
|
||||
diff --git a/server/mapping.c b/server/mapping.c
|
||||
index d73d8de9c283..6c79f7d18a6f 100644
|
||||
--- a/server/mapping.c
|
||||
+++ b/server/mapping.c
|
||||
@@ -29,8 +29,32 @@
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
# include <sys/mman.h>
|
||||
#endif
|
||||
+#ifdef HAVE_SYS_SYSCALL_H
|
||||
+# include <sys/syscall.h>
|
||||
+#endif
|
||||
#include <unistd.h>
|
||||
|
||||
+#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
|
||||
+
|
||||
+/* __NR_memfd_create might not yet be available when buildservers use an old kernel */
|
||||
+#ifndef __NR_memfd_create
|
||||
+#ifdef __x86_64__
|
||||
+#define __NR_memfd_create 319
|
||||
+#else
|
||||
+#define __NR_memfd_create 356
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
+/* the following declarations are only available in linux/fcntl.h, but not fcntl.h */
|
||||
+#define F_LINUX_SPECIFIC_BASE 1024
|
||||
+#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
|
||||
+#define MFD_ALLOW_SEALING 0x0002U
|
||||
+#define F_SEAL_SEAL 0x0001
|
||||
+#define F_SEAL_SHRINK 0x0002
|
||||
+#define F_SEAL_GROW 0x0004
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
@@ -191,6 +215,10 @@ static const struct fd_ops mapping_fd_ops =
|
||||
|
||||
static size_t page_mask;
|
||||
|
||||
+/* global shared memory */
|
||||
+shmglobal_t *shmglobal;
|
||||
+int shmglobal_fd;
|
||||
+
|
||||
#define ROUND_SIZE(size) (((size) + page_mask) & ~page_mask)
|
||||
|
||||
|
||||
@@ -262,6 +290,52 @@ static int check_current_dir_for_exec(void)
|
||||
return (ret != MAP_FAILED);
|
||||
}
|
||||
|
||||
+/* allocates a block of shared memory */
|
||||
+int allocate_shared_memory( int *fd, void **memory, size_t size )
|
||||
+{
|
||||
+#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
|
||||
+ void *shm_mem;
|
||||
+ int shm_fd;
|
||||
+
|
||||
+ shm_fd = syscall( __NR_memfd_create, "wineserver_shm", MFD_ALLOW_SEALING );
|
||||
+ if (shm_fd == -1) goto err;
|
||||
+ if (grow_file( shm_fd, size ))
|
||||
+ {
|
||||
+ if (fcntl( shm_fd, F_ADD_SEALS, F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW ) >= 0)
|
||||
+ {
|
||||
+ shm_mem = mmap( 0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0 );
|
||||
+ if (shm_mem != MAP_FAILED)
|
||||
+ {
|
||||
+ memset( shm_mem, 0, size );
|
||||
+ *fd = shm_fd;
|
||||
+ *memory = shm_mem;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ close( shm_fd );
|
||||
+err:
|
||||
+#endif
|
||||
+ *memory = NULL;
|
||||
+ *fd = -1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* releases a block of shared memory */
|
||||
+void release_shared_memory( int fd, void *memory, size_t size )
|
||||
+{
|
||||
+#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
|
||||
+ if (memory) munmap( memory, size );
|
||||
+ if (fd != -1) close( fd );
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+/* intialize shared memory management */
|
||||
+void init_shared_memory( void )
|
||||
+{
|
||||
+ allocate_shared_memory( &shmglobal_fd, (void **)&shmglobal, sizeof(*shmglobal) );
|
||||
+}
|
||||
+
|
||||
/* create a temp file for anonymous mappings */
|
||||
static int create_temp_file( file_pos_t size )
|
||||
{
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index 197a48592e0a..99651c9ed534 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -69,6 +69,15 @@ struct request_max_size
|
||||
#define FIRST_USER_HANDLE 0x0020 /* first possible value for low word of user handle */
|
||||
#define LAST_USER_HANDLE 0xffef /* last possible value for low word of user handle */
|
||||
|
||||
+typedef struct
|
||||
+{
|
||||
+ int dummy;
|
||||
+} shmglobal_t;
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ int dummy;
|
||||
+} shmlocal_t;
|
||||
|
||||
/* debug event data */
|
||||
typedef union
|
||||
@@ -1335,6 +1344,12 @@ enum server_fd_type
|
||||
@END
|
||||
|
||||
|
||||
+/* Get file descriptor for shared memory */
|
||||
+@REQ(get_shared_memory)
|
||||
+ thread_id_t tid; /* thread id or 0 */
|
||||
+@END
|
||||
+
|
||||
+
|
||||
/* Flush a file buffers */
|
||||
@REQ(flush)
|
||||
async_data_t async; /* async I/O parameters */
|
||||
diff --git a/server/thread.c b/server/thread.c
|
||||
index 987da2f7c4ff..233320c78ad5 100644
|
||||
--- a/server/thread.c
|
||||
+++ b/server/thread.c
|
||||
@@ -239,6 +239,8 @@ static inline void init_thread_structure( struct thread *thread )
|
||||
thread->desc = NULL;
|
||||
thread->desc_len = 0;
|
||||
thread->exit_poll = NULL;
|
||||
+ thread->shm_fd = -1;
|
||||
+ thread->shm = NULL;
|
||||
|
||||
thread->creation_time = current_time;
|
||||
thread->exit_time = 0;
|
||||
@@ -409,7 +411,10 @@ static void cleanup_thread( struct thread *thread )
|
||||
thread->inflight[i].client = thread->inflight[i].server = -1;
|
||||
}
|
||||
}
|
||||
+
|
||||
free( thread->desc );
|
||||
+ release_shared_memory( thread->shm_fd, thread->shm, sizeof(*thread->shm) );
|
||||
+
|
||||
thread->req_data = NULL;
|
||||
thread->reply_data = NULL;
|
||||
thread->request_fd = NULL;
|
||||
@@ -418,6 +423,8 @@ static void cleanup_thread( struct thread *thread )
|
||||
thread->desktop = 0;
|
||||
thread->desc = NULL;
|
||||
thread->desc_len = 0;
|
||||
+ thread->shm_fd = -1;
|
||||
+ thread->shm = NULL;
|
||||
}
|
||||
|
||||
/* destroy a thread when its refcount is 0 */
|
||||
diff --git a/server/thread.h b/server/thread.h
|
||||
index 912df68eaf63..00f6f7c64a93 100644
|
||||
--- a/server/thread.h
|
||||
+++ b/server/thread.h
|
||||
@@ -91,6 +91,8 @@ struct thread
|
||||
data_size_t desc_len; /* thread description length in bytes */
|
||||
WCHAR *desc; /* thread description string */
|
||||
struct timeout_user *exit_poll; /* poll if the thread/process has exited already */
|
||||
+ int shm_fd; /* file descriptor for thread local shared memory */
|
||||
+ shmlocal_t *shm; /* thread local shared memory pointer */
|
||||
};
|
||||
|
||||
struct thread_snapshot
|
||||
--
|
||||
2.26.2
|
||||
|
@ -1,120 +0,0 @@
|
||||
From dc483d01e1493b319aecd409ce4e65223c18b5bd Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Thu, 19 Mar 2015 01:32:51 +0100
|
||||
Subject: user32: Get rid of wineserver call for GetInputState.
|
||||
|
||||
---
|
||||
dlls/user32/input.c | 14 +++++++++++++-
|
||||
server/protocol.def | 2 +-
|
||||
server/queue.c | 14 ++++++++++++++
|
||||
3 files changed, 28 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
|
||||
index 130aacc..4cf6b61 100644
|
||||
--- a/dlls/user32/input.c
|
||||
+++ b/dlls/user32/input.c
|
||||
@@ -454,17 +454,29 @@ DWORD WINAPI GetQueueStatus( UINT flags )
|
||||
*/
|
||||
BOOL WINAPI GetInputState(void)
|
||||
{
|
||||
+ shmlocal_t *shm = wine_get_shmlocal();
|
||||
DWORD ret;
|
||||
|
||||
check_for_events( QS_INPUT );
|
||||
|
||||
+ /* req->clear is not set, so we can safely get the
|
||||
+ * wineserver status without an additional call. */
|
||||
+ if (shm)
|
||||
+ {
|
||||
+ ret = shm->queue_bits;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
SERVER_START_REQ( get_queue_status )
|
||||
{
|
||||
req->clear_bits = 0;
|
||||
wine_server_call( req );
|
||||
- ret = reply->wake_bits & (QS_KEY | QS_MOUSEBUTTON);
|
||||
+ ret = reply->wake_bits;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
+
|
||||
+done:
|
||||
+ ret &= (QS_KEY | QS_MOUSEBUTTON);
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index ea2e231..4872251 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -76,7 +76,7 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
- int dummy;
|
||||
+ int queue_bits; /* queue wake bits */
|
||||
} shmlocal_t;
|
||||
|
||||
/* debug event data */
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index c318fc3..3a1d2b7 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -118,6 +118,7 @@ struct thread_input
|
||||
struct msg_queue
|
||||
{
|
||||
struct object obj; /* object header */
|
||||
+ struct thread *thread; /* reference to the thread owning the queue */
|
||||
struct fd *fd; /* optional file descriptor to poll */
|
||||
unsigned int wake_bits; /* wakeup bits */
|
||||
unsigned int wake_mask; /* wakeup mask */
|
||||
@@ -282,6 +283,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
|
||||
if ((queue = alloc_object( &msg_queue_ops )))
|
||||
{
|
||||
queue->fd = NULL;
|
||||
+ queue->thread = thread;
|
||||
queue->wake_bits = 0;
|
||||
queue->wake_mask = 0;
|
||||
queue->changed_bits = 0;
|
||||
@@ -315,6 +317,7 @@ void free_msg_queue( struct thread *thread )
|
||||
{
|
||||
remove_thread_hooks( thread );
|
||||
if (!thread->queue) return;
|
||||
+ thread->queue->thread = NULL;
|
||||
release_object( thread->queue );
|
||||
thread->queue = NULL;
|
||||
}
|
||||
@@ -427,11 +430,21 @@ static inline int is_signaled( struct msg_queue *queue )
|
||||
return ((queue->wake_bits & queue->wake_mask) || (queue->changed_bits & queue->changed_mask));
|
||||
}
|
||||
|
||||
+/* synchronize the queue state with the shared memory */
|
||||
+static inline void update_shm_queue_bits( struct msg_queue *queue )
|
||||
+{
|
||||
+ shmlocal_t *shm;
|
||||
+ if (!queue->thread) return;
|
||||
+ if ((shm = queue->thread->shm))
|
||||
+ shm->queue_bits = queue->wake_bits;
|
||||
+}
|
||||
+
|
||||
/* set some queue bits */
|
||||
static inline void set_queue_bits( struct msg_queue *queue, unsigned int bits )
|
||||
{
|
||||
queue->wake_bits |= bits;
|
||||
queue->changed_bits |= bits;
|
||||
+ update_shm_queue_bits( queue );
|
||||
if (is_signaled( queue )) wake_up( &queue->obj, 0 );
|
||||
}
|
||||
|
||||
@@ -440,6 +453,7 @@ static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits
|
||||
{
|
||||
queue->wake_bits &= ~bits;
|
||||
queue->changed_bits &= ~bits;
|
||||
+ update_shm_queue_bits( queue );
|
||||
}
|
||||
|
||||
/* check whether msg is a keyboard message */
|
||||
--
|
||||
2.3.5
|
||||
|
@ -1,68 +0,0 @@
|
||||
From 3225fc5b602f25a2d17ee68b732ec2a59fb29c0f Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Thu, 19 Mar 2015 02:55:36 +0100
|
||||
Subject: [PATCH] ntdll: Only enable wineserver shared memory communication
|
||||
when a special environment variable is set.
|
||||
|
||||
---
|
||||
dlls/ntdll/server.c | 22 ++++++++++++++++++++++
|
||||
1 file changed, 22 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
|
||||
index 749e753ae5a..c3f9d11c760 100644
|
||||
--- a/dlls/ntdll/server.c
|
||||
+++ b/dlls/ntdll/server.c
|
||||
@@ -100,6 +100,7 @@
|
||||
#include "ddk/wdm.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(server);
|
||||
+WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
||||
|
||||
/* just in case... */
|
||||
#undef EXT2_IOC_GETFLAGS
|
||||
@@ -1177,6 +1178,21 @@ static int server_get_shared_memory_fd( HANDLE thread, int *unix_fd )
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/* The shared memory wineserver communication is still highly experimental
|
||||
+ * and might cause unexpected results when the client/server status gets
|
||||
+ * out of synchronization. The feature will be disabled by default until it
|
||||
+ * is tested a bit more. */
|
||||
+static inline BOOL experimental_SHARED_MEMORY( void )
|
||||
+{
|
||||
+ static int enabled = -1;
|
||||
+ if (enabled == -1)
|
||||
+ {
|
||||
+ const char *str = getenv( "STAGING_SHARED_MEMORY" );
|
||||
+ enabled = str && (atoi(str) != 0);
|
||||
+ }
|
||||
+ return enabled;
|
||||
+}
|
||||
+
|
||||
|
||||
/***********************************************************************
|
||||
* server_get_shared_memory
|
||||
@@ -1189,6 +1205,9 @@ void *server_get_shared_memory( HANDLE thread )
|
||||
void *mem = NULL;
|
||||
int fd = -1;
|
||||
|
||||
+ if (!experimental_SHARED_MEMORY())
|
||||
+ return NULL;
|
||||
+
|
||||
/* The global memory block is only requested once. No locking is
|
||||
* required because this function is called very early during the
|
||||
* process initialization for the first time. */
|
||||
@@ -1203,7 +1222,10 @@ void *server_get_shared_memory( HANDLE thread )
|
||||
}
|
||||
|
||||
if (!thread)
|
||||
+ {
|
||||
+ if (mem) WARN_(winediag)("Using shared memory wineserver communication\n");
|
||||
shmglobal = mem;
|
||||
+ }
|
||||
|
||||
return mem;
|
||||
}
|
||||
--
|
||||
2.26.2
|
||||
|
@ -1,79 +0,0 @@
|
||||
From cb18df88215aa555e89a877ee5ede75706c170f9 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 21 Mar 2015 09:00:17 +0100
|
||||
Subject: server: Store a list of associated queues for each thread input.
|
||||
|
||||
Required by the following patches, splitted as a separate patch for easier
|
||||
reviewing.
|
||||
---
|
||||
server/queue.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 418a2b1..1b80348 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -99,6 +99,7 @@ struct thread_input
|
||||
{
|
||||
struct object obj; /* object header */
|
||||
struct desktop *desktop; /* desktop that this thread input belongs to */
|
||||
+ struct list queues; /* list of all queues this input belongs to */
|
||||
user_handle_t focus; /* focus window */
|
||||
user_handle_t capture; /* capture window */
|
||||
user_handle_t active; /* active window */
|
||||
@@ -139,6 +140,7 @@ struct msg_queue
|
||||
lparam_t next_timer_id; /* id for the next timer with a 0 window */
|
||||
struct timeout_user *timeout; /* timeout for next timer to expire */
|
||||
struct thread_input *input; /* thread input descriptor */
|
||||
+ struct list input_entry; /* entry in input->queues */
|
||||
struct hook_table *hooks; /* hook table */
|
||||
timeout_t last_get_msg; /* time of last get message call */
|
||||
unsigned int ignore_post_msg; /* ignore post messages newer than this unique id */
|
||||
@@ -254,6 +256,7 @@ static struct thread_input *create_thread_input( struct thread *thread )
|
||||
input->cursor = 0;
|
||||
input->cursor_count = 0;
|
||||
input->lock_count = 0;
|
||||
+ list_init( &input->queues );
|
||||
list_init( &input->msg_list );
|
||||
set_caret_window( input, 0 );
|
||||
memset( input->keystate, 0, sizeof(input->keystate) );
|
||||
@@ -297,6 +300,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
|
||||
queue->next_timer_id = 0x7fff;
|
||||
queue->timeout = NULL;
|
||||
queue->input = (struct thread_input *)grab_object( input );
|
||||
+ list_add_tail( &input->queues, &queue->input_entry );
|
||||
queue->hooks = NULL;
|
||||
queue->last_get_msg = current_time;
|
||||
queue->ignore_post_msg = 0;
|
||||
@@ -336,10 +340,12 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_
|
||||
{
|
||||
if (queue->keystate_locked) queue->input->lock_count--;
|
||||
queue->input->cursor_count -= queue->cursor_count;
|
||||
+ list_remove( &queue->input_entry );
|
||||
release_object( queue->input );
|
||||
queue->keystate_locked = 0;
|
||||
}
|
||||
queue->input = (struct thread_input *)grab_object( new_input );
|
||||
+ list_add_tail( &new_input->queues, &queue->input_entry );
|
||||
new_input->cursor_count += queue->cursor_count;
|
||||
return 1;
|
||||
}
|
||||
@@ -1003,6 +1009,7 @@ static void msg_queue_destroy( struct object *obj )
|
||||
if (queue->timeout) remove_timeout_user( queue->timeout );
|
||||
if (queue->keystate_locked) queue->input->lock_count--;
|
||||
queue->input->cursor_count -= queue->cursor_count;
|
||||
+ list_remove( &queue->input_entry );
|
||||
release_object( queue->input );
|
||||
if (queue->hooks) release_object( queue->hooks );
|
||||
if (queue->fd) release_object( queue->fd );
|
||||
@@ -1029,6 +1036,7 @@ static void thread_input_destroy( struct object *obj )
|
||||
{
|
||||
struct thread_input *input = (struct thread_input *)obj;
|
||||
|
||||
+ assert( list_empty(&input->queues) );
|
||||
empty_msg_list( &input->msg_list );
|
||||
if (input->desktop)
|
||||
{
|
||||
--
|
||||
2.3.5
|
||||
|
@ -1,156 +0,0 @@
|
||||
From 452f8d47d7cd63f0fe5270d8ec6a7062544d3903 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 21 Mar 2015 09:45:54 +0100
|
||||
Subject: user32: Get rid of wineserver call for GetActiveWindow, GetFocus,
|
||||
GetCapture.
|
||||
|
||||
---
|
||||
dlls/user32/focus.c | 4 ++++
|
||||
dlls/user32/input.c | 2 ++
|
||||
server/protocol.def | 5 ++++-
|
||||
server/queue.c | 30 +++++++++++++++++++++++++++++-
|
||||
4 files changed, 39 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/focus.c b/dlls/user32/focus.c
|
||||
index c47a82d..35fe89b 100644
|
||||
--- a/dlls/user32/focus.c
|
||||
+++ b/dlls/user32/focus.c
|
||||
@@ -329,8 +329,10 @@ BOOL WINAPI SetForegroundWindow( HWND hwnd )
|
||||
*/
|
||||
HWND WINAPI GetActiveWindow(void)
|
||||
{
|
||||
+ shmlocal_t *shm = wine_get_shmlocal();
|
||||
HWND ret = 0;
|
||||
|
||||
+ if (shm) return wine_server_ptr_handle( shm->input_active );
|
||||
SERVER_START_REQ( get_thread_input )
|
||||
{
|
||||
req->tid = GetCurrentThreadId();
|
||||
@@ -346,8 +348,10 @@ HWND WINAPI GetActiveWindow(void)
|
||||
*/
|
||||
HWND WINAPI GetFocus(void)
|
||||
{
|
||||
+ shmlocal_t *shm = wine_get_shmlocal();
|
||||
HWND ret = 0;
|
||||
|
||||
+ if (shm) return wine_server_ptr_handle( shm->input_focus );
|
||||
SERVER_START_REQ( get_thread_input )
|
||||
{
|
||||
req->tid = GetCurrentThreadId();
|
||||
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
|
||||
index e63c8cf..0943d01 100644
|
||||
--- a/dlls/user32/input.c
|
||||
+++ b/dlls/user32/input.c
|
||||
@@ -342,8 +342,10 @@ BOOL WINAPI DECLSPEC_HOTPATCH ReleaseCapture(void)
|
||||
*/
|
||||
HWND WINAPI GetCapture(void)
|
||||
{
|
||||
+ shmlocal_t *shm = wine_get_shmlocal();
|
||||
HWND ret = 0;
|
||||
|
||||
+ if (shm) return wine_server_ptr_handle( shm->input_capture );
|
||||
SERVER_START_REQ( get_thread_input )
|
||||
{
|
||||
req->tid = GetCurrentThreadId();
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index f12109f..5ec2485 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -76,7 +76,10 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
- int queue_bits; /* queue wake bits */
|
||||
+ int queue_bits; /* queue wake bits */
|
||||
+ user_handle_t input_focus; /* focus window */
|
||||
+ user_handle_t input_capture; /* capture window */
|
||||
+ user_handle_t input_active; /* active window */
|
||||
} shmlocal_t;
|
||||
|
||||
/* debug event data */
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 3f52656..33c2758 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -270,6 +270,25 @@ static struct thread_input *create_thread_input( struct thread *thread )
|
||||
return input;
|
||||
}
|
||||
|
||||
+/* synchronize the input state with the shared memory */
|
||||
+static void update_shm_thread_input( struct thread_input *input )
|
||||
+{
|
||||
+ struct msg_queue *queue;
|
||||
+
|
||||
+ /* the loop doesn't matter, usually it should only have one or a few entries */
|
||||
+ LIST_FOR_EACH_ENTRY( queue, &input->queues, struct msg_queue, input_entry )
|
||||
+ {
|
||||
+ shmlocal_t *shm;
|
||||
+ if (!queue->thread) continue;
|
||||
+ if ((shm = queue->thread->shm))
|
||||
+ {
|
||||
+ shm->input_active = input->active;
|
||||
+ shm->input_focus = input->focus;
|
||||
+ shm->input_capture = input->capture;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* create a message queue object */
|
||||
static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_input *input )
|
||||
{
|
||||
@@ -312,7 +331,11 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
|
||||
|
||||
thread->queue = queue;
|
||||
}
|
||||
- if (new_input) release_object( new_input );
|
||||
+ if (new_input)
|
||||
+ {
|
||||
+ update_shm_thread_input( new_input );
|
||||
+ release_object( new_input );
|
||||
+ }
|
||||
return queue;
|
||||
}
|
||||
|
||||
@@ -347,6 +370,7 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_
|
||||
queue->input = (struct thread_input *)grab_object( new_input );
|
||||
list_add_tail( &new_input->queues, &queue->input_entry );
|
||||
new_input->cursor_count += queue->cursor_count;
|
||||
+ update_shm_thread_input( new_input );
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1056,6 +1080,7 @@ static inline void thread_input_cleanup_window( struct msg_queue *queue, user_ha
|
||||
if (window == input->menu_owner) input->menu_owner = 0;
|
||||
if (window == input->move_size) input->move_size = 0;
|
||||
if (window == input->caret) set_caret_window( input, 0 );
|
||||
+ update_shm_thread_input( input );
|
||||
}
|
||||
|
||||
/* check if the specified window can be set in the input data of a given queue */
|
||||
@@ -2985,6 +3010,7 @@ DECL_HANDLER(set_focus_window)
|
||||
{
|
||||
reply->previous = queue->input->focus;
|
||||
queue->input->focus = get_user_full_handle( req->handle );
|
||||
+ update_shm_thread_input( queue->input );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3001,6 +3027,7 @@ DECL_HANDLER(set_active_window)
|
||||
{
|
||||
reply->previous = queue->input->active;
|
||||
queue->input->active = get_user_full_handle( req->handle );
|
||||
+ update_shm_thread_input( queue->input );
|
||||
}
|
||||
else set_error( STATUS_INVALID_HANDLE );
|
||||
}
|
||||
@@ -3027,6 +3054,7 @@ DECL_HANDLER(set_capture_window)
|
||||
input->capture = get_user_full_handle( req->handle );
|
||||
input->menu_owner = (req->flags & CAPTURE_MENU) ? input->capture : 0;
|
||||
input->move_size = (req->flags & CAPTURE_MOVESIZE) ? input->capture : 0;
|
||||
+ update_shm_thread_input( input );
|
||||
reply->full_handle = input->capture;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.3.5
|
||||
|
@ -1 +1 @@
|
||||
17f052c36a414a05fcb6a6e67bd3aac824fbed3e
|
||||
797df8df394d81a165328f9ac6b4039253a78718
|
||||
|
Loading…
Reference in New Issue
Block a user