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
db742a49
Commit
db742a49
authored
Jun 08, 2017
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wineandroid: Add support for mouse events.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
b0690b13
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
165 additions
and
0 deletions
+165
-0
WineActivity.java
dlls/wineandroid.drv/WineActivity.java
+39
-0
android.h
dlls/wineandroid.drv/android.h
+10
-0
init.c
dlls/wineandroid.drv/init.c
+1
-0
window.c
dlls/wineandroid.drv/window.c
+115
-0
No files found.
dlls/wineandroid.drv/WineActivity.java
View file @
db742a49
...
...
@@ -30,6 +30,8 @@ import android.os.Build;
import
android.os.Bundle
;
import
android.preference.PreferenceManager
;
import
android.util.Log
;
import
android.view.InputDevice
;
import
android.view.MotionEvent
;
import
android.view.Surface
;
import
android.view.TextureView
;
import
android.view.View
;
...
...
@@ -51,6 +53,7 @@ public class WineActivity extends Activity
private
native
String
wine_init
(
String
[]
cmdline
,
String
[]
env
);
public
native
void
wine_desktop_changed
(
int
width
,
int
height
);
public
native
void
wine_surface_changed
(
int
hwnd
,
Surface
surface
);
public
native
boolean
wine_motion_event
(
int
hwnd
,
int
action
,
int
x
,
int
y
,
int
state
,
int
vscroll
);
private
final
String
LOGTAG
=
"wine"
;
private
ProgressDialog
progress_dialog
;
...
...
@@ -365,6 +368,12 @@ public class WineActivity extends Activity
Log
.
i
(
LOGTAG
,
String
.
format
(
"set window surface hwnd %08x %s"
,
hwnd
,
window_surface
));
wine_surface_changed
(
hwnd
,
window_surface
);
}
public
void
get_event_pos
(
MotionEvent
event
,
int
[]
pos
)
{
pos
[
0
]
=
Math
.
round
(
event
.
getX
()
+
window_view
.
getLeft
()
);
pos
[
1
]
=
Math
.
round
(
event
.
getY
()
+
window_view
.
getTop
()
);
}
}
// View used for all Wine windows, backed by a TextureView
...
...
@@ -411,6 +420,36 @@ public class WineActivity extends Activity
public
void
onSurfaceTextureUpdated
(
SurfaceTexture
surftex
)
{
}
public
boolean
onGenericMotionEvent
(
MotionEvent
event
)
{
if
(
window
.
parent
!=
null
)
return
false
;
// let the parent handle it
if
((
event
.
getSource
()
&
InputDevice
.
SOURCE_CLASS_POINTER
)
!=
0
)
{
int
[]
pos
=
new
int
[
2
];
window
.
get_event_pos
(
event
,
pos
);
Log
.
i
(
LOGTAG
,
String
.
format
(
"view motion event win %08x action %d pos %d,%d buttons %04x view %d,%d"
,
window
.
hwnd
,
event
.
getAction
(),
pos
[
0
],
pos
[
1
],
event
.
getButtonState
(),
getLeft
(),
getTop
()
));
return
wine_motion_event
(
window
.
hwnd
,
event
.
getAction
(),
pos
[
0
],
pos
[
1
],
event
.
getButtonState
(),
(
int
)
event
.
getAxisValue
(
MotionEvent
.
AXIS_VSCROLL
)
);
}
return
super
.
onGenericMotionEvent
(
event
);
}
public
boolean
onTouchEvent
(
MotionEvent
event
)
{
if
(
window
.
parent
!=
null
)
return
false
;
// let the parent handle it
int
[]
pos
=
new
int
[
2
];
window
.
get_event_pos
(
event
,
pos
);
Log
.
i
(
LOGTAG
,
String
.
format
(
"view touch event win %08x action %d pos %d,%d buttons %04x view %d,%d"
,
window
.
hwnd
,
event
.
getAction
(),
pos
[
0
],
pos
[
1
],
event
.
getButtonState
(),
getLeft
(),
getTop
()
));
return
wine_motion_event
(
window
.
hwnd
,
event
.
getAction
(),
pos
[
0
],
pos
[
1
],
event
.
getButtonState
(),
0
);
}
}
// The top-level desktop view group
...
...
dlls/wineandroid.drv/android.h
View file @
db742a49
...
...
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <jni.h>
#include <android/log.h>
#include <android/input.h>
#include <android/native_window_jni.h>
#include "windef.h"
...
...
@@ -84,11 +85,14 @@ 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
;
extern
void
surface_changed
(
JNIEnv
*
env
,
jobject
obj
,
jint
win
,
jobject
surface
)
DECLSPEC_HIDDEN
;
extern
jboolean
motion_event
(
JNIEnv
*
env
,
jobject
obj
,
jint
win
,
jint
action
,
jint
x
,
jint
y
,
jint
state
,
jint
vscroll
)
DECLSPEC_HIDDEN
;
enum
event_type
{
DESKTOP_CHANGED
,
SURFACE_CHANGED
,
MOTION_EVENT
,
};
union
event_data
...
...
@@ -108,6 +112,12 @@ union event_data
unsigned
int
width
;
unsigned
int
height
;
}
surface
;
struct
{
enum
event_type
type
;
HWND
hwnd
;
INPUT
input
;
}
motion
;
};
int
send_event
(
const
union
event_data
*
data
);
...
...
dlls/wineandroid.drv/init.c
View file @
db742a49
...
...
@@ -391,6 +391,7 @@ static const JNINativeMethod methods[] =
{
{
"wine_desktop_changed"
,
"(II)V"
,
desktop_changed
},
{
"wine_surface_changed"
,
"(ILandroid/view/Surface;)V"
,
surface_changed
},
{
"wine_motion_event"
,
"(IIIIII)Z"
,
motion_event
},
};
#define DECL_FUNCPTR(f) typeof(f) * p##f = NULL
...
...
dlls/wineandroid.drv/window.c
View file @
db742a49
...
...
@@ -253,6 +253,74 @@ void surface_changed( JNIEnv *env, jobject obj, jint win, jobject surface )
/***********************************************************************
* motion_event
*
* JNI callback, runs in the context of the Java thread.
*/
jboolean
motion_event
(
JNIEnv
*
env
,
jobject
obj
,
jint
win
,
jint
action
,
jint
x
,
jint
y
,
jint
state
,
jint
vscroll
)
{
static
LONG
button_state
;
union
event_data
data
;
int
prev_state
;
int
mask
=
action
&
AMOTION_EVENT_ACTION_MASK
;
if
(
!
(
mask
==
AMOTION_EVENT_ACTION_DOWN
||
mask
==
AMOTION_EVENT_ACTION_UP
||
mask
==
AMOTION_EVENT_ACTION_SCROLL
||
mask
==
AMOTION_EVENT_ACTION_MOVE
||
mask
==
AMOTION_EVENT_ACTION_HOVER_MOVE
))
return
JNI_FALSE
;
prev_state
=
InterlockedExchange
(
&
button_state
,
state
);
data
.
type
=
MOTION_EVENT
;
data
.
motion
.
hwnd
=
LongToHandle
(
win
);
data
.
motion
.
input
.
type
=
INPUT_MOUSE
;
data
.
motion
.
input
.
u
.
mi
.
dx
=
x
;
data
.
motion
.
input
.
u
.
mi
.
dy
=
y
;
data
.
motion
.
input
.
u
.
mi
.
mouseData
=
0
;
data
.
motion
.
input
.
u
.
mi
.
time
=
0
;
data
.
motion
.
input
.
u
.
mi
.
dwExtraInfo
=
0
;
data
.
motion
.
input
.
u
.
mi
.
dwFlags
=
MOUSEEVENTF_MOVE
|
MOUSEEVENTF_ABSOLUTE
;
switch
(
action
&
AMOTION_EVENT_ACTION_MASK
)
{
case
AMOTION_EVENT_ACTION_DOWN
:
if
((
state
&
~
prev_state
)
&
AMOTION_EVENT_BUTTON_PRIMARY
)
data
.
motion
.
input
.
u
.
mi
.
dwFlags
|=
MOUSEEVENTF_LEFTDOWN
;
if
((
state
&
~
prev_state
)
&
AMOTION_EVENT_BUTTON_SECONDARY
)
data
.
motion
.
input
.
u
.
mi
.
dwFlags
|=
MOUSEEVENTF_RIGHTDOWN
;
if
((
state
&
~
prev_state
)
&
AMOTION_EVENT_BUTTON_TERTIARY
)
data
.
motion
.
input
.
u
.
mi
.
dwFlags
|=
MOUSEEVENTF_MIDDLEDOWN
;
if
(
!
(
state
&
~
prev_state
))
/* touch event */
data
.
motion
.
input
.
u
.
mi
.
dwFlags
|=
MOUSEEVENTF_LEFTDOWN
;
break
;
case
AMOTION_EVENT_ACTION_UP
:
if
((
prev_state
&
~
state
)
&
AMOTION_EVENT_BUTTON_PRIMARY
)
data
.
motion
.
input
.
u
.
mi
.
dwFlags
|=
MOUSEEVENTF_LEFTUP
;
if
((
prev_state
&
~
state
)
&
AMOTION_EVENT_BUTTON_SECONDARY
)
data
.
motion
.
input
.
u
.
mi
.
dwFlags
|=
MOUSEEVENTF_RIGHTUP
;
if
((
prev_state
&
~
state
)
&
AMOTION_EVENT_BUTTON_TERTIARY
)
data
.
motion
.
input
.
u
.
mi
.
dwFlags
|=
MOUSEEVENTF_MIDDLEUP
;
if
(
!
(
prev_state
&
~
state
))
/* touch event */
data
.
motion
.
input
.
u
.
mi
.
dwFlags
|=
MOUSEEVENTF_LEFTUP
;
break
;
case
AMOTION_EVENT_ACTION_SCROLL
:
data
.
motion
.
input
.
u
.
mi
.
dwFlags
|=
MOUSEEVENTF_WHEEL
;
data
.
motion
.
input
.
u
.
mi
.
mouseData
=
vscroll
<
0
?
-
WHEEL_DELTA
:
WHEEL_DELTA
;
break
;
case
AMOTION_EVENT_ACTION_MOVE
:
case
AMOTION_EVENT_ACTION_HOVER_MOVE
:
break
;
default:
return
JNI_FALSE
;
}
send_event
(
&
data
);
return
JNI_TRUE
;
}
/***********************************************************************
* init_event_queue
*/
static
void
init_event_queue
(
void
)
...
...
@@ -328,6 +396,15 @@ static int process_events( DWORD mask )
{
case
SURFACE_CHANGED
:
break
;
/* always process it to unblock other threads */
case
MOTION_EVENT
:
if
(
event
->
data
.
motion
.
input
.
u
.
mi
.
dwFlags
&
(
MOUSEEVENTF_LEFTDOWN
|
MOUSEEVENTF_RIGHTDOWN
|
MOUSEEVENTF_MIDDLEDOWN
|
MOUSEEVENTF_LEFTUP
|
MOUSEEVENTF_RIGHTUP
|
MOUSEEVENTF_MIDDLEUP
))
{
if
(
mask
&
QS_MOUSEBUTTON
)
break
;
}
else
if
(
mask
&
QS_MOUSEMOVE
)
break
;
continue
;
/* skip it */
default:
if
(
mask
&
QS_SENDMESSAGE
)
break
;
continue
;
/* skip it */
...
...
@@ -355,6 +432,44 @@ static int process_events( DWORD mask )
register_native_window
(
event
->
data
.
surface
.
hwnd
,
event
->
data
.
surface
.
window
);
break
;
case
MOTION_EVENT
:
{
HWND
capture
=
get_capture_window
();
if
(
event
->
data
.
motion
.
input
.
u
.
mi
.
dwFlags
&
(
MOUSEEVENTF_LEFTDOWN
|
MOUSEEVENTF_RIGHTDOWN
|
MOUSEEVENTF_MIDDLEDOWN
))
TRACE
(
"BUTTONDOWN pos %d,%d hwnd %p flags %x
\n
"
,
event
->
data
.
motion
.
input
.
u
.
mi
.
dx
,
event
->
data
.
motion
.
input
.
u
.
mi
.
dy
,
event
->
data
.
motion
.
hwnd
,
event
->
data
.
motion
.
input
.
u
.
mi
.
dwFlags
);
else
if
(
event
->
data
.
motion
.
input
.
u
.
mi
.
dwFlags
&
(
MOUSEEVENTF_LEFTUP
|
MOUSEEVENTF_RIGHTUP
|
MOUSEEVENTF_MIDDLEUP
))
TRACE
(
"BUTTONUP pos %d,%d hwnd %p flags %x
\n
"
,
event
->
data
.
motion
.
input
.
u
.
mi
.
dx
,
event
->
data
.
motion
.
input
.
u
.
mi
.
dy
,
event
->
data
.
motion
.
hwnd
,
event
->
data
.
motion
.
input
.
u
.
mi
.
dwFlags
);
else
TRACE
(
"MOUSEMOVE pos %d,%d hwnd %p flags %x
\n
"
,
event
->
data
.
motion
.
input
.
u
.
mi
.
dx
,
event
->
data
.
motion
.
input
.
u
.
mi
.
dy
,
event
->
data
.
motion
.
hwnd
,
event
->
data
.
motion
.
input
.
u
.
mi
.
dwFlags
);
if
(
!
capture
&&
(
event
->
data
.
motion
.
input
.
u
.
mi
.
dwFlags
&
MOUSEEVENTF_ABSOLUTE
))
{
RECT
rect
;
SetRect
(
&
rect
,
event
->
data
.
motion
.
input
.
u
.
mi
.
dx
,
event
->
data
.
motion
.
input
.
u
.
mi
.
dy
,
event
->
data
.
motion
.
input
.
u
.
mi
.
dx
+
1
,
event
->
data
.
motion
.
input
.
u
.
mi
.
dy
+
1
);
MapWindowPoints
(
0
,
event
->
data
.
motion
.
hwnd
,
(
POINT
*
)
&
rect
,
2
);
SERVER_START_REQ
(
update_window_zorder
)
{
req
->
window
=
wine_server_user_handle
(
event
->
data
.
motion
.
hwnd
);
req
->
rect
.
left
=
rect
.
left
;
req
->
rect
.
top
=
rect
.
top
;
req
->
rect
.
right
=
rect
.
right
;
req
->
rect
.
bottom
=
rect
.
bottom
;
wine_server_call
(
req
);
}
SERVER_END_REQ
;
}
__wine_send_input
(
capture
?
capture
:
event
->
data
.
motion
.
hwnd
,
&
event
->
data
.
motion
.
input
);
}
break
;
default:
FIXME
(
"got event %u
\n
"
,
event
->
data
.
type
);
}
...
...
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