Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
c701734c
Commit
c701734c
authored
Jun 02, 2022
by
Jacek Caban
Committed by
Alexandre Julliard
Jun 03, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winemac: Use unixlib interface for macdrv_app_quit_request.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
parent
80e24bcc
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
202 additions
and
165 deletions
+202
-165
dllmain.c
dlls/winemac.drv/dllmain.c
+174
-0
macdrv_main.c
dlls/winemac.drv/macdrv_main.c
+9
-0
unixlib.h
dlls/winemac.drv/unixlib.h
+15
-1
window.c
dlls/winemac.drv/window.c
+4
-164
No files found.
dlls/winemac.drv/dllmain.c
View file @
c701734c
...
...
@@ -22,13 +22,187 @@
#include <stdarg.h>
#include "macdrv.h"
#include "shellapi.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
macdrv
);
HMODULE
macdrv_module
=
0
;
struct
quit_info
{
HWND
*
wins
;
UINT
capacity
;
UINT
count
;
UINT
done
;
DWORD
flags
;
BOOL
result
;
BOOL
replied
;
};
static
BOOL
CALLBACK
get_process_windows
(
HWND
hwnd
,
LPARAM
lp
)
{
struct
quit_info
*
qi
=
(
struct
quit_info
*
)
lp
;
DWORD
pid
;
NtUserGetWindowThread
(
hwnd
,
&
pid
);
if
(
pid
==
GetCurrentProcessId
())
{
if
(
qi
->
count
>=
qi
->
capacity
)
{
UINT
new_cap
=
qi
->
capacity
*
2
;
HWND
*
new_wins
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
qi
->
wins
,
new_cap
*
sizeof
(
*
qi
->
wins
));
if
(
!
new_wins
)
return
FALSE
;
qi
->
wins
=
new_wins
;
qi
->
capacity
=
new_cap
;
}
qi
->
wins
[
qi
->
count
++
]
=
hwnd
;
}
return
TRUE
;
}
static
void
quit_reply
(
int
reply
)
{
struct
quit_result_params
params
=
{
.
result
=
reply
};
MACDRV_CALL
(
quit_result
,
&
params
);
}
static
void
CALLBACK
quit_callback
(
HWND
hwnd
,
UINT
msg
,
ULONG_PTR
data
,
LRESULT
result
)
{
struct
quit_info
*
qi
=
(
struct
quit_info
*
)
data
;
qi
->
done
++
;
if
(
msg
==
WM_QUERYENDSESSION
)
{
TRACE
(
"got WM_QUERYENDSESSION result %ld from win %p (%u of %u done)
\n
"
,
result
,
hwnd
,
qi
->
done
,
qi
->
count
);
if
(
!
result
&&
!
IsWindow
(
hwnd
))
{
TRACE
(
"win %p no longer exists; ignoring apparent refusal
\n
"
,
hwnd
);
result
=
TRUE
;
}
if
(
!
result
&&
qi
->
result
)
{
qi
->
result
=
FALSE
;
/* On the first FALSE from WM_QUERYENDSESSION, we already know the
ultimate reply. Might as well tell Cocoa now. */
if
(
!
qi
->
replied
)
{
qi
->
replied
=
TRUE
;
TRACE
(
"giving quit reply %d
\n
"
,
qi
->
result
);
quit_reply
(
qi
->
result
);
}
}
if
(
qi
->
done
>=
qi
->
count
)
{
UINT
i
;
qi
->
done
=
0
;
for
(
i
=
0
;
i
<
qi
->
count
;
i
++
)
{
TRACE
(
"sending WM_ENDSESSION to win %p result %d flags 0x%08x
\n
"
,
qi
->
wins
[
i
],
qi
->
result
,
qi
->
flags
);
if
(
!
SendMessageCallbackW
(
qi
->
wins
[
i
],
WM_ENDSESSION
,
qi
->
result
,
qi
->
flags
,
quit_callback
,
(
ULONG_PTR
)
qi
))
{
WARN
(
"failed to send WM_ENDSESSION to win %p; error 0x%08x
\n
"
,
qi
->
wins
[
i
],
GetLastError
());
quit_callback
(
qi
->
wins
[
i
],
WM_ENDSESSION
,
(
ULONG_PTR
)
qi
,
0
);
}
}
}
}
else
/* WM_ENDSESSION */
{
TRACE
(
"finished WM_ENDSESSION for win %p (%u of %u done)
\n
"
,
hwnd
,
qi
->
done
,
qi
->
count
);
if
(
qi
->
done
>=
qi
->
count
)
{
if
(
!
qi
->
replied
)
{
TRACE
(
"giving quit reply %d
\n
"
,
qi
->
result
);
quit_reply
(
qi
->
result
);
}
TRACE
(
"%sterminating process
\n
"
,
qi
->
result
?
""
:
"not "
);
if
(
qi
->
result
)
TerminateProcess
(
GetCurrentProcess
(),
0
);
HeapFree
(
GetProcessHeap
(),
0
,
qi
->
wins
);
HeapFree
(
GetProcessHeap
(),
0
,
qi
);
}
}
}
/***********************************************************************
* macdrv_app_quit_request
*/
NTSTATUS
WINAPI
macdrv_app_quit_request
(
void
*
arg
,
ULONG
size
)
{
struct
app_quit_request_params
*
params
=
arg
;
struct
quit_info
*
qi
;
UINT
i
;
qi
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
qi
));
if
(
!
qi
)
goto
fail
;
qi
->
capacity
=
32
;
qi
->
wins
=
HeapAlloc
(
GetProcessHeap
(),
0
,
qi
->
capacity
*
sizeof
(
*
qi
->
wins
));
qi
->
count
=
qi
->
done
=
0
;
if
(
!
qi
->
wins
||
!
EnumWindows
(
get_process_windows
,
(
LPARAM
)
qi
))
goto
fail
;
qi
->
flags
=
params
->
flags
;
qi
->
result
=
TRUE
;
qi
->
replied
=
FALSE
;
for
(
i
=
0
;
i
<
qi
->
count
;
i
++
)
{
TRACE
(
"sending WM_QUERYENDSESSION to win %p
\n
"
,
qi
->
wins
[
i
]);
if
(
!
SendMessageCallbackW
(
qi
->
wins
[
i
],
WM_QUERYENDSESSION
,
0
,
qi
->
flags
,
quit_callback
,
(
ULONG_PTR
)
qi
))
{
DWORD
error
=
GetLastError
();
BOOL
invalid
=
(
error
==
ERROR_INVALID_WINDOW_HANDLE
);
if
(
invalid
)
TRACE
(
"failed to send WM_QUERYENDSESSION to win %p because it's invalid; assuming success
\n
"
,
qi
->
wins
[
i
]);
else
WARN
(
"failed to send WM_QUERYENDSESSION to win %p; error 0x%08x; assuming refusal
\n
"
,
qi
->
wins
[
i
],
error
);
quit_callback
(
qi
->
wins
[
i
],
WM_QUERYENDSESSION
,
(
ULONG_PTR
)
qi
,
invalid
);
}
}
/* quit_callback() will clean up qi */
return
0
;
fail:
WARN
(
"failed to allocate window list
\n
"
);
if
(
qi
)
{
HeapFree
(
GetProcessHeap
(),
0
,
qi
->
wins
);
HeapFree
(
GetProcessHeap
(),
0
,
qi
);
}
quit_reply
(
FALSE
);
return
0
;
}
typedef
NTSTATUS
(
WINAPI
*
kernel_callback
)(
void
*
params
,
ULONG
size
);
static
const
kernel_callback
kernel_callbacks
[]
=
{
macdrv_app_quit_request
,
macdrv_dnd_query_drag
,
macdrv_dnd_query_drop
,
macdrv_dnd_query_exited
,
...
...
dlls/winemac.drv/macdrv_main.c
View file @
c701734c
...
...
@@ -628,6 +628,14 @@ static NTSTATUS macdrv_ime_using_input_method(void *arg)
}
static
NTSTATUS
macdrv_quit_result
(
void
*
arg
)
{
struct
quit_result_params
*
params
=
arg
;
macdrv_quit_reply
(
params
->
result
);
return
0
;
}
const
unixlib_entry_t
__wine_unix_call_funcs
[]
=
{
macdrv_dnd_get_data
,
...
...
@@ -640,6 +648,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
macdrv_ime_using_input_method
,
macdrv_init
,
macdrv_notify_icon
,
macdrv_quit_result
,
};
C_ASSERT
(
ARRAYSIZE
(
__wine_unix_call_funcs
)
==
unix_funcs_count
);
...
...
dlls/winemac.drv/unixlib.h
View file @
c701734c
...
...
@@ -31,6 +31,7 @@ enum macdrv_funcs
unix_ime_using_input_method
,
unix_init
,
unix_notify_icon
,
unix_quit_result
,
unix_funcs_count
};
...
...
@@ -92,10 +93,17 @@ struct notify_icon_params
struct
_NOTIFYICONDATAW
*
data
;
};
/* macdrv_quit_result params */
struct
quit_result_params
{
int
result
;
};
/* driver client callbacks exposed with KernelCallbackTable interface */
enum
macdrv_client_funcs
{
client_func_dnd_query_drag
=
NtUserDriverCallbackFirst
,
client_func_app_quit_request
=
NtUserDriverCallbackFirst
,
client_func_dnd_query_drag
,
client_func_dnd_query_drop
,
client_func_dnd_query_exited
,
client_func_ime_query_char_rect
,
...
...
@@ -103,6 +111,12 @@ enum macdrv_client_funcs
client_func_last
};
/* macdrv_app_quit_request params */
struct
app_quit_request_params
{
UINT
flags
;
};
/* macdrv_dnd_query_drag params */
struct
dnd_query_drag_params
{
...
...
dlls/winemac.drv/window.c
View file @
c701734c
...
...
@@ -2653,114 +2653,6 @@ void macdrv_reassert_window_position(HWND hwnd)
}
struct
quit_info
{
HWND
*
wins
;
UINT
capacity
;
UINT
count
;
UINT
done
;
DWORD
flags
;
BOOL
result
;
BOOL
replied
;
};
static
BOOL
CALLBACK
get_process_windows
(
HWND
hwnd
,
LPARAM
lp
)
{
struct
quit_info
*
qi
=
(
struct
quit_info
*
)
lp
;
DWORD
pid
;
NtUserGetWindowThread
(
hwnd
,
&
pid
);
if
(
pid
==
GetCurrentProcessId
())
{
if
(
qi
->
count
>=
qi
->
capacity
)
{
UINT
new_cap
=
qi
->
capacity
*
2
;
HWND
*
new_wins
=
realloc
(
qi
->
wins
,
new_cap
*
sizeof
(
*
qi
->
wins
));
if
(
!
new_wins
)
return
FALSE
;
qi
->
wins
=
new_wins
;
qi
->
capacity
=
new_cap
;
}
qi
->
wins
[
qi
->
count
++
]
=
hwnd
;
}
return
TRUE
;
}
static
void
CALLBACK
quit_callback
(
HWND
hwnd
,
UINT
msg
,
ULONG_PTR
data
,
LRESULT
result
)
{
struct
quit_info
*
qi
=
(
struct
quit_info
*
)
data
;
qi
->
done
++
;
if
(
msg
==
WM_QUERYENDSESSION
)
{
TRACE
(
"got WM_QUERYENDSESSION result %ld from win %p (%u of %u done)
\n
"
,
result
,
hwnd
,
qi
->
done
,
qi
->
count
);
if
(
!
result
&&
!
IsWindow
(
hwnd
))
{
TRACE
(
"win %p no longer exists; ignoring apparent refusal
\n
"
,
hwnd
);
result
=
TRUE
;
}
if
(
!
result
&&
qi
->
result
)
{
qi
->
result
=
FALSE
;
/* On the first FALSE from WM_QUERYENDSESSION, we already know the
ultimate reply. Might as well tell Cocoa now. */
if
(
!
qi
->
replied
)
{
qi
->
replied
=
TRUE
;
TRACE
(
"giving quit reply %d
\n
"
,
qi
->
result
);
macdrv_quit_reply
(
qi
->
result
);
}
}
if
(
qi
->
done
>=
qi
->
count
)
{
UINT
i
;
qi
->
done
=
0
;
for
(
i
=
0
;
i
<
qi
->
count
;
i
++
)
{
TRACE
(
"sending WM_ENDSESSION to win %p result %d flags 0x%08x
\n
"
,
qi
->
wins
[
i
],
qi
->
result
,
qi
->
flags
);
if
(
!
SendMessageCallbackW
(
qi
->
wins
[
i
],
WM_ENDSESSION
,
qi
->
result
,
qi
->
flags
,
quit_callback
,
(
ULONG_PTR
)
qi
))
{
WARN
(
"failed to send WM_ENDSESSION to win %p; error 0x%08x
\n
"
,
qi
->
wins
[
i
],
GetLastError
());
quit_callback
(
qi
->
wins
[
i
],
WM_ENDSESSION
,
(
ULONG_PTR
)
qi
,
0
);
}
}
}
}
else
/* WM_ENDSESSION */
{
TRACE
(
"finished WM_ENDSESSION for win %p (%u of %u done)
\n
"
,
hwnd
,
qi
->
done
,
qi
->
count
);
if
(
qi
->
done
>=
qi
->
count
)
{
if
(
!
qi
->
replied
)
{
TRACE
(
"giving quit reply %d
\n
"
,
qi
->
result
);
macdrv_quit_reply
(
qi
->
result
);
}
TRACE
(
"%sterminating process
\n
"
,
qi
->
result
?
""
:
"not "
);
if
(
qi
->
result
)
TerminateProcess
(
GetCurrentProcess
(),
0
);
free
(
qi
->
wins
);
free
(
qi
);
}
}
}
/***********************************************************************
* macdrv_app_quit_requested
*
...
...
@@ -2768,66 +2660,14 @@ static void CALLBACK quit_callback(HWND hwnd, UINT msg, ULONG_PTR data, LRESULT
*/
void
macdrv_app_quit_requested
(
const
macdrv_event
*
event
)
{
struct
quit_info
*
qi
;
UINT
i
;
struct
app_quit_request_params
params
=
{
.
flags
=
0
};
TRACE
(
"reason %d
\n
"
,
event
->
app_quit_requested
.
reason
);
qi
=
malloc
(
sizeof
(
*
qi
));
if
(
!
qi
)
goto
fail
;
qi
->
capacity
=
32
;
qi
->
wins
=
malloc
(
qi
->
capacity
*
sizeof
(
*
qi
->
wins
));
qi
->
count
=
qi
->
done
=
0
;
if
(
!
qi
->
wins
||
!
EnumWindows
(
get_process_windows
,
(
LPARAM
)
qi
))
goto
fail
;
if
(
event
->
app_quit_requested
.
reason
==
QUIT_REASON_LOGOUT
)
params
.
flags
=
ENDSESSION_LOGOFF
;
switch
(
event
->
app_quit_requested
.
reason
)
{
case
QUIT_REASON_LOGOUT
:
default:
qi
->
flags
=
ENDSESSION_LOGOFF
;
break
;
case
QUIT_REASON_RESTART
:
case
QUIT_REASON_SHUTDOWN
:
qi
->
flags
=
0
;
break
;
}
qi
->
result
=
TRUE
;
qi
->
replied
=
FALSE
;
for
(
i
=
0
;
i
<
qi
->
count
;
i
++
)
{
TRACE
(
"sending WM_QUERYENDSESSION to win %p
\n
"
,
qi
->
wins
[
i
]);
if
(
!
SendMessageCallbackW
(
qi
->
wins
[
i
],
WM_QUERYENDSESSION
,
0
,
qi
->
flags
,
quit_callback
,
(
ULONG_PTR
)
qi
))
{
DWORD
error
=
GetLastError
();
BOOL
invalid
=
(
error
==
ERROR_INVALID_WINDOW_HANDLE
);
if
(
invalid
)
TRACE
(
"failed to send WM_QUERYENDSESSION to win %p because it's invalid; assuming success
\n
"
,
qi
->
wins
[
i
]);
else
WARN
(
"failed to send WM_QUERYENDSESSION to win %p; error 0x%08x; assuming refusal
\n
"
,
qi
->
wins
[
i
],
error
);
quit_callback
(
qi
->
wins
[
i
],
WM_QUERYENDSESSION
,
(
ULONG_PTR
)
qi
,
invalid
);
}
}
/* quit_callback() will clean up qi */
return
;
fail:
WARN
(
"failed to allocate window list
\n
"
);
if
(
qi
)
{
free
(
qi
->
wins
);
free
(
qi
);
}
macdrv_quit_reply
(
FALSE
);
macdrv_client_func
(
client_func_app_quit_request
,
&
params
,
sizeof
(
params
));
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment