Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
5be4a0e3
Commit
5be4a0e3
authored
May 31, 2017
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wineandroid: Add an event queue to support handling Java callbacks in the desktop thread.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
77d55905
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
188 additions
and
0 deletions
+188
-0
android.h
dlls/wineandroid.drv/android.h
+18
-0
window.c
dlls/wineandroid.drv/window.c
+168
-0
wineandroid.drv.spec
dlls/wineandroid.drv/wineandroid.drv.spec
+2
-0
No files found.
dlls/wineandroid.drv/android.h
View file @
5be4a0e3
...
...
@@ -57,6 +57,24 @@ extern void init_monitors( int width, int height ) DECLSPEC_HIDDEN;
/* JNI entry points */
extern
void
desktop_changed
(
JNIEnv
*
env
,
jobject
obj
,
jint
width
,
jint
height
)
DECLSPEC_HIDDEN
;
enum
event_type
{
DESKTOP_CHANGED
,
};
union
event_data
{
enum
event_type
type
;
struct
{
enum
event_type
type
;
unsigned
int
width
;
unsigned
int
height
;
}
desktop
;
};
int
send_event
(
const
union
event_data
*
data
);
extern
JavaVM
*
wine_get_java_vm
(
void
);
extern
jobject
wine_get_java_object
(
void
);
...
...
dlls/wineandroid.drv/window.c
View file @
5be4a0e3
...
...
@@ -44,6 +44,7 @@
#include "wine/unicode.h"
#include "android.h"
#include "wine/server.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
android
);
...
...
@@ -133,6 +134,35 @@ static void release_win_data( struct android_win_data *data )
}
/* Handling of events coming from the Java side */
struct
java_event
{
struct
list
entry
;
union
event_data
data
;
};
static
struct
list
event_queue
=
LIST_INIT
(
event_queue
);
static
struct
java_event
*
current_event
;
static
int
event_pipe
[
2
];
static
DWORD
desktop_tid
;
/***********************************************************************
* send_event
*/
int
send_event
(
const
union
event_data
*
data
)
{
int
res
;
if
((
res
=
write
(
event_pipe
[
1
],
data
,
sizeof
(
*
data
)
))
!=
sizeof
(
*
data
))
{
p__android_log_print
(
ANDROID_LOG_ERROR
,
"wine"
,
"failed to send event"
);
return
-
1
;
}
return
0
;
}
/***********************************************************************
* desktop_changed
*
...
...
@@ -140,7 +170,145 @@ static void release_win_data( struct android_win_data *data )
*/
void
desktop_changed
(
JNIEnv
*
env
,
jobject
obj
,
jint
width
,
jint
height
)
{
union
event_data
data
;
memset
(
&
data
,
0
,
sizeof
(
data
)
);
data
.
type
=
DESKTOP_CHANGED
;
data
.
desktop
.
width
=
width
;
data
.
desktop
.
height
=
height
;
p__android_log_print
(
ANDROID_LOG_INFO
,
"wine"
,
"desktop_changed: %ux%u"
,
width
,
height
);
send_event
(
&
data
);
}
/***********************************************************************
* init_event_queue
*/
static
void
init_event_queue
(
void
)
{
HANDLE
handle
;
int
ret
;
if
(
pipe2
(
event_pipe
,
O_CLOEXEC
|
O_NONBLOCK
)
==
-
1
)
{
ERR
(
"could not create data
\n
"
);
ExitProcess
(
1
);
}
if
(
wine_server_fd_to_handle
(
event_pipe
[
0
],
GENERIC_READ
|
SYNCHRONIZE
,
0
,
&
handle
))
{
ERR
(
"Can't allocate handle for event fd
\n
"
);
ExitProcess
(
1
);
}
SERVER_START_REQ
(
set_queue_fd
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
ret
)
{
ERR
(
"Can't store handle for event fd %x
\n
"
,
ret
);
ExitProcess
(
1
);
}
CloseHandle
(
handle
);
desktop_tid
=
GetCurrentThreadId
();
}
/***********************************************************************
* pull_events
*
* Pull events from the event pipe and add them to the queue
*/
static
void
pull_events
(
void
)
{
struct
java_event
*
event
;
int
res
;
for
(;;)
{
if
(
!
(
event
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
event
)
)))
break
;
res
=
read
(
event_pipe
[
0
],
&
event
->
data
,
sizeof
(
event
->
data
)
);
if
(
res
!=
sizeof
(
event
->
data
))
break
;
list_add_tail
(
&
event_queue
,
&
event
->
entry
);
}
HeapFree
(
GetProcessHeap
(),
0
,
event
);
}
/***********************************************************************
* process_events
*/
static
int
process_events
(
DWORD
mask
)
{
struct
java_event
*
event
,
*
next
,
*
previous
;
unsigned
int
count
=
0
;
assert
(
GetCurrentThreadId
()
==
desktop_tid
);
pull_events
();
previous
=
current_event
;
LIST_FOR_EACH_ENTRY_SAFE
(
event
,
next
,
&
event_queue
,
struct
java_event
,
entry
)
{
if
(
!
(
mask
&
QS_SENDMESSAGE
))
continue
;
/* skip it */
/* remove it first, in case we process events recursively */
list_remove
(
&
event
->
entry
);
current_event
=
event
;
switch
(
event
->
data
.
type
)
{
case
DESKTOP_CHANGED
:
TRACE
(
"DESKTOP_CHANGED %ux%u
\n
"
,
event
->
data
.
desktop
.
width
,
event
->
data
.
desktop
.
height
);
screen_width
=
event
->
data
.
desktop
.
width
;
screen_height
=
event
->
data
.
desktop
.
height
;
init_monitors
(
screen_width
,
screen_height
);
SetWindowPos
(
GetDesktopWindow
(),
0
,
0
,
0
,
screen_width
,
screen_height
,
SWP_NOZORDER
|
SWP_NOACTIVATE
|
SWP_NOREDRAW
);
break
;
default:
FIXME
(
"got event %u
\n
"
,
event
->
data
.
type
);
}
HeapFree
(
GetProcessHeap
(),
0
,
event
);
count
++
;
}
current_event
=
previous
;
return
count
;
}
/***********************************************************************
* ANDROID_MsgWaitForMultipleObjectsEx
*/
DWORD
CDECL
ANDROID_MsgWaitForMultipleObjectsEx
(
DWORD
count
,
const
HANDLE
*
handles
,
DWORD
timeout
,
DWORD
mask
,
DWORD
flags
)
{
if
(
GetCurrentThreadId
()
==
desktop_tid
)
{
/* don't process nested events */
if
(
current_event
)
mask
=
0
;
if
(
process_events
(
mask
))
return
count
-
1
;
}
return
WaitForMultipleObjectsEx
(
count
,
handles
,
flags
&
MWMO_WAITALL
,
timeout
,
flags
&
MWMO_ALERTABLE
);
}
/**********************************************************************
* ANDROID_CreateWindow
*/
BOOL
CDECL
ANDROID_CreateWindow
(
HWND
hwnd
)
{
TRACE
(
"%p
\n
"
,
hwnd
);
if
(
hwnd
==
GetDesktopWindow
())
{
init_event_queue
();
}
return
TRUE
;
}
...
...
dlls/wineandroid.drv/wineandroid.drv.spec
View file @
5be4a0e3
...
...
@@ -6,6 +6,8 @@
@ cdecl EnumDisplayMonitors(long ptr ptr long) ANDROID_EnumDisplayMonitors
@ cdecl GetMonitorInfo(long ptr) ANDROID_GetMonitorInfo
@ cdecl CreateWindow(long) ANDROID_CreateWindow
@ cdecl DestroyWindow(long) ANDROID_DestroyWindow
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) ANDROID_MsgWaitForMultipleObjectsEx
@ cdecl WindowPosChanging(long long long ptr ptr ptr ptr) ANDROID_WindowPosChanging
@ cdecl WindowPosChanged(long long long ptr ptr ptr ptr ptr) ANDROID_WindowPosChanged
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