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
61888e00
Commit
61888e00
authored
Nov 26, 2018
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wineandroid: Support for setting the cursor on Android >= N.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
2b8d787b
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
371 additions
and
2 deletions
+371
-2
WineActivity.java
dlls/wineandroid.drv/WineActivity.java
+28
-0
android.h
dlls/wineandroid.drv/android.h
+3
-1
build.gradle.in
dlls/wineandroid.drv/build.gradle.in
+1
-1
device.c
dlls/wineandroid.drv/device.c
+72
-0
window.c
dlls/wineandroid.drv/window.c
+266
-0
wineandroid.drv.spec
dlls/wineandroid.drv/wineandroid.drv.spec
+1
-0
No files found.
dlls/wineandroid.drv/WineActivity.java
View file @
61888e00
...
...
@@ -25,6 +25,7 @@ import android.app.Activity;
import
android.app.ProgressDialog
;
import
android.content.Context
;
import
android.content.SharedPreferences
;
import
android.graphics.Bitmap
;
import
android.graphics.Rect
;
import
android.graphics.SurfaceTexture
;
import
android.os.Build
;
...
...
@@ -34,6 +35,7 @@ import android.util.Log;
import
android.view.InputDevice
;
import
android.view.KeyEvent
;
import
android.view.MotionEvent
;
import
android.view.PointerIcon
;
import
android.view.Surface
;
import
android.view.TextureView
;
import
android.view.View
;
...
...
@@ -64,6 +66,7 @@ public class WineActivity extends Activity
protected
WineWindow
desktop_window
;
protected
WineWindow
message_window
;
private
PointerIcon
current_cursor
;
@Override
public
void
onCreate
(
Bundle
savedInstanceState
)
...
...
@@ -684,6 +687,12 @@ public class WineActivity extends Activity
{
}
@TargetApi
(
24
)
public
PointerIcon
onResolvePointerIcon
(
MotionEvent
event
,
int
index
)
{
return
current_cursor
;
}
public
boolean
onGenericMotionEvent
(
MotionEvent
event
)
{
if
(
is_client
)
return
false
;
// let the whole window handle it
...
...
@@ -799,6 +808,18 @@ public class WineActivity extends Activity
if
(
win
.
parent
==
desktop_window
)
win
.
create_whole_view
();
}
@TargetApi
(
24
)
public
void
set_cursor
(
int
id
,
int
width
,
int
height
,
int
hotspotx
,
int
hotspoty
,
int
bits
[]
)
{
Log
.
i
(
LOGTAG
,
String
.
format
(
"set_cursor id %d size %dx%d hotspot %dx%d"
,
id
,
width
,
height
,
hotspotx
,
hotspoty
));
if
(
bits
!=
null
)
{
Bitmap
bitmap
=
Bitmap
.
createBitmap
(
bits
,
width
,
height
,
Bitmap
.
Config
.
ARGB_8888
);
current_cursor
=
PointerIcon
.
create
(
bitmap
,
hotspotx
,
hotspoty
);
}
else
current_cursor
=
PointerIcon
.
getSystemIcon
(
this
,
id
);
}
public
void
window_pos_changed
(
int
hwnd
,
int
flags
,
int
insert_after
,
int
owner
,
int
style
,
Rect
window_rect
,
Rect
client_rect
,
Rect
visible_rect
)
{
...
...
@@ -827,6 +848,13 @@ public class WineActivity extends Activity
runOnUiThread
(
new
Runnable
()
{
public
void
run
()
{
set_window_parent
(
hwnd
,
parent
,
scale
,
pid
);
}}
);
}
public
void
setCursor
(
final
int
id
,
final
int
width
,
final
int
height
,
final
int
hotspotx
,
final
int
hotspoty
,
final
int
bits
[]
)
{
if
(
Build
.
VERSION
.
SDK_INT
<
24
)
return
;
runOnUiThread
(
new
Runnable
()
{
public
void
run
()
{
set_cursor
(
id
,
width
,
height
,
hotspotx
,
hotspoty
,
bits
);
}}
);
}
public
void
windowPosChanged
(
final
int
hwnd
,
final
int
flags
,
final
int
insert_after
,
final
int
owner
,
final
int
style
,
final
int
window_left
,
final
int
window_top
,
...
...
dlls/wineandroid.drv/android.h
View file @
61888e00
...
...
@@ -72,6 +72,8 @@ extern int ioctl_window_pos_changed( HWND hwnd, const RECT *window_rect, const R
HWND
after
,
HWND
owner
)
DECLSPEC_HIDDEN
;
extern
int
ioctl_set_window_parent
(
HWND
hwnd
,
HWND
parent
,
float
scale
)
DECLSPEC_HIDDEN
;
extern
int
ioctl_set_capture
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
extern
int
ioctl_set_cursor
(
int
id
,
int
width
,
int
height
,
int
hotspotx
,
int
hotspoty
,
const
unsigned
int
*
bits
)
DECLSPEC_HIDDEN
;
/**************************************************************************
...
...
@@ -151,7 +153,7 @@ union event_data
}
kbd
;
};
int
send_event
(
const
union
event_data
*
data
);
int
send_event
(
const
union
event_data
*
data
)
DECLSPEC_HIDDEN
;
extern
JavaVM
*
wine_get_java_vm
(
void
);
extern
jobject
wine_get_java_object
(
void
);
...
...
dlls/wineandroid.drv/build.gradle.in
View file @
61888e00
...
...
@@ -58,7 +58,7 @@ tasks.whenTaskAdded { t ->
android
{
compileSdkVersion 2
1
compileSdkVersion 2
5
buildToolsVersion "25.0.3"
defaultConfig
...
...
dlls/wineandroid.drv/device.c
View file @
61888e00
...
...
@@ -70,6 +70,7 @@ enum android_ioctl
IOCTL_PERFORM
,
IOCTL_SET_SWAP_INT
,
IOCTL_SET_CAPTURE
,
IOCTL_SET_CURSOR
,
NB_IOCTLS
};
...
...
@@ -212,6 +213,17 @@ struct ioctl_android_set_capture
struct
ioctl_header
hdr
;
};
struct
ioctl_android_set_cursor
{
struct
ioctl_header
hdr
;
int
id
;
int
width
;
int
height
;
int
hotspotx
;
int
hotspoty
;
int
bits
[
1
];
};
static
struct
gralloc_module_t
*
gralloc_module
;
static
struct
gralloc1_device
*
gralloc1_device
;
static
BOOL
gralloc1_caps
[
GRALLOC1_LAST_CAPABILITY
+
1
];
...
...
@@ -1041,6 +1053,44 @@ static NTSTATUS setCapture_ioctl( void *data, DWORD in_size, DWORD out_size, ULO
return
STATUS_SUCCESS
;
}
static
NTSTATUS
setCursor_ioctl
(
void
*
data
,
DWORD
in_size
,
DWORD
out_size
,
ULONG_PTR
*
ret_size
)
{
static
jmethodID
method
;
jobject
object
;
int
size
;
struct
ioctl_android_set_cursor
*
res
=
data
;
if
(
in_size
<
offsetof
(
struct
ioctl_android_set_cursor
,
bits
))
return
STATUS_INVALID_PARAMETER
;
if
(
res
->
width
<
0
||
res
->
height
<
0
||
res
->
width
>
256
||
res
->
height
>
256
)
return
STATUS_INVALID_PARAMETER
;
size
=
res
->
width
*
res
->
height
;
if
(
in_size
!=
offsetof
(
struct
ioctl_android_set_cursor
,
bits
[
size
]
))
return
STATUS_INVALID_PARAMETER
;
TRACE
(
"hwnd %08x size %d
\n
"
,
res
->
hdr
.
hwnd
,
size
);
if
(
!
(
object
=
load_java_method
(
&
method
,
"setCursor"
,
"(IIIII[I)V"
)))
return
STATUS_NOT_SUPPORTED
;
wrap_java_call
();
if
(
size
)
{
jintArray
array
=
(
*
jni_env
)
->
NewIntArray
(
jni_env
,
size
);
(
*
jni_env
)
->
SetIntArrayRegion
(
jni_env
,
array
,
0
,
size
,
(
jint
*
)
res
->
bits
);
(
*
jni_env
)
->
CallVoidMethod
(
jni_env
,
object
,
method
,
0
,
res
->
width
,
res
->
height
,
res
->
hotspotx
,
res
->
hotspoty
,
array
);
(
*
jni_env
)
->
DeleteLocalRef
(
jni_env
,
array
);
}
else
(
*
jni_env
)
->
CallVoidMethod
(
jni_env
,
object
,
method
,
res
->
id
,
0
,
0
,
0
,
0
,
0
);
unwrap_java_call
();
return
STATUS_SUCCESS
;
}
typedef
NTSTATUS
(
*
ioctl_func
)(
void
*
in
,
DWORD
in_size
,
DWORD
out_size
,
ULONG_PTR
*
ret_size
);
static
const
ioctl_func
ioctl_funcs
[]
=
{
...
...
@@ -1055,6 +1105,7 @@ static const ioctl_func ioctl_funcs[] =
perform_ioctl
,
/* IOCTL_PERFORM */
setSwapInterval_ioctl
,
/* IOCTL_SET_SWAP_INT */
setCapture_ioctl
,
/* IOCTL_SET_CAPTURE */
setCursor_ioctl
,
/* IOCTL_SET_CURSOR */
};
static
NTSTATUS
WINAPI
ioctl_callback
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
...
...
@@ -1584,3 +1635,24 @@ int ioctl_set_capture( HWND hwnd )
req
.
hdr
.
opengl
=
FALSE
;
return
android_ioctl
(
IOCTL_SET_CAPTURE
,
&
req
,
sizeof
(
req
),
NULL
,
NULL
);
}
int
ioctl_set_cursor
(
int
id
,
int
width
,
int
height
,
int
hotspotx
,
int
hotspoty
,
const
unsigned
int
*
bits
)
{
struct
ioctl_android_set_cursor
*
req
;
unsigned
int
size
=
offsetof
(
struct
ioctl_android_set_cursor
,
bits
[
width
*
height
]
);
int
ret
;
if
(
!
(
req
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
)))
return
-
ENOMEM
;
req
->
hdr
.
hwnd
=
0
;
/* unused */
req
->
hdr
.
opengl
=
FALSE
;
req
->
id
=
id
;
req
->
width
=
width
;
req
->
height
=
height
;
req
->
hotspotx
=
hotspotx
;
req
->
hotspoty
=
hotspoty
;
memcpy
(
req
->
bits
,
bits
,
width
*
height
*
sizeof
(
req
->
bits
[
0
])
);
ret
=
android_ioctl
(
IOCTL_SET_CURSOR
,
req
,
size
,
NULL
,
NULL
);
HeapFree
(
GetProcessHeap
(),
0
,
req
);
return
ret
;
}
dlls/wineandroid.drv/window.c
View file @
61888e00
...
...
@@ -37,6 +37,7 @@
# include <unistd.h>
#endif
#define OEMRESOURCE
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
...
...
@@ -966,6 +967,226 @@ static void set_surface_layered( struct window_surface *window_surface, BYTE alp
window_surface
->
funcs
->
unlock
(
window_surface
);
}
/***********************************************************************
* get_mono_icon_argb
*
* Return a monochrome icon/cursor bitmap bits in ARGB format.
*/
static
unsigned
int
*
get_mono_icon_argb
(
HDC
hdc
,
HBITMAP
bmp
,
unsigned
int
*
width
,
unsigned
int
*
height
)
{
BITMAP
bm
;
char
*
mask
;
unsigned
int
i
,
j
,
stride
,
mask_size
,
bits_size
,
*
bits
=
NULL
,
*
ptr
;
if
(
!
GetObjectW
(
bmp
,
sizeof
(
bm
),
&
bm
))
return
NULL
;
stride
=
((
bm
.
bmWidth
+
15
)
>>
3
)
&
~
1
;
mask_size
=
stride
*
bm
.
bmHeight
;
if
(
!
(
mask
=
HeapAlloc
(
GetProcessHeap
(),
0
,
mask_size
)))
return
NULL
;
if
(
!
GetBitmapBits
(
bmp
,
mask_size
,
mask
))
goto
done
;
bm
.
bmHeight
/=
2
;
bits_size
=
bm
.
bmWidth
*
bm
.
bmHeight
*
sizeof
(
*
bits
);
if
(
!
(
bits
=
HeapAlloc
(
GetProcessHeap
(),
0
,
bits_size
)))
goto
done
;
ptr
=
bits
;
for
(
i
=
0
;
i
<
bm
.
bmHeight
;
i
++
)
for
(
j
=
0
;
j
<
bm
.
bmWidth
;
j
++
,
ptr
++
)
{
int
and
=
((
mask
[
i
*
stride
+
j
/
8
]
<<
(
j
%
8
))
&
0x80
);
int
xor
=
((
mask
[(
i
+
bm
.
bmHeight
)
*
stride
+
j
/
8
]
<<
(
j
%
8
))
&
0x80
);
if
(
!
xor
&&
and
)
*
ptr
=
0
;
else
if
(
xor
&&
!
and
)
*
ptr
=
0xffffffff
;
else
/* we can't draw "invert" pixels, so render them as black instead */
*
ptr
=
0xff000000
;
}
*
width
=
bm
.
bmWidth
;
*
height
=
bm
.
bmHeight
;
done:
HeapFree
(
GetProcessHeap
(),
0
,
mask
);
return
bits
;
}
/***********************************************************************
* get_bitmap_argb
*
* Return the bitmap bits in ARGB format. Helper for setting icons and cursors.
*/
static
unsigned
int
*
get_bitmap_argb
(
HDC
hdc
,
HBITMAP
color
,
HBITMAP
mask
,
unsigned
int
*
width
,
unsigned
int
*
height
)
{
char
buffer
[
FIELD_OFFSET
(
BITMAPINFO
,
bmiColors
[
256
]
)];
BITMAPINFO
*
info
=
(
BITMAPINFO
*
)
buffer
;
BITMAP
bm
;
unsigned
int
*
ptr
,
*
bits
=
NULL
;
unsigned
char
*
mask_bits
=
NULL
;
int
i
,
j
;
BOOL
has_alpha
=
FALSE
;
if
(
!
color
)
return
get_mono_icon_argb
(
hdc
,
mask
,
width
,
height
);
if
(
!
GetObjectW
(
color
,
sizeof
(
bm
),
&
bm
))
return
NULL
;
info
->
bmiHeader
.
biSize
=
sizeof
(
BITMAPINFOHEADER
);
info
->
bmiHeader
.
biWidth
=
bm
.
bmWidth
;
info
->
bmiHeader
.
biHeight
=
-
bm
.
bmHeight
;
info
->
bmiHeader
.
biPlanes
=
1
;
info
->
bmiHeader
.
biBitCount
=
32
;
info
->
bmiHeader
.
biCompression
=
BI_RGB
;
info
->
bmiHeader
.
biSizeImage
=
bm
.
bmWidth
*
bm
.
bmHeight
*
4
;
info
->
bmiHeader
.
biXPelsPerMeter
=
0
;
info
->
bmiHeader
.
biYPelsPerMeter
=
0
;
info
->
bmiHeader
.
biClrUsed
=
0
;
info
->
bmiHeader
.
biClrImportant
=
0
;
if
(
!
(
bits
=
HeapAlloc
(
GetProcessHeap
(),
0
,
bm
.
bmWidth
*
bm
.
bmHeight
*
sizeof
(
unsigned
int
)
)))
goto
failed
;
if
(
!
GetDIBits
(
hdc
,
color
,
0
,
bm
.
bmHeight
,
bits
,
info
,
DIB_RGB_COLORS
))
goto
failed
;
*
width
=
bm
.
bmWidth
;
*
height
=
bm
.
bmHeight
;
for
(
i
=
0
;
i
<
bm
.
bmWidth
*
bm
.
bmHeight
;
i
++
)
if
((
has_alpha
=
(
bits
[
i
]
&
0xff000000
)
!=
0
))
break
;
if
(
!
has_alpha
)
{
unsigned
int
width_bytes
=
(
bm
.
bmWidth
+
31
)
/
32
*
4
;
/* generate alpha channel from the mask */
info
->
bmiHeader
.
biBitCount
=
1
;
info
->
bmiHeader
.
biSizeImage
=
width_bytes
*
bm
.
bmHeight
;
if
(
!
(
mask_bits
=
HeapAlloc
(
GetProcessHeap
(),
0
,
info
->
bmiHeader
.
biSizeImage
)))
goto
failed
;
if
(
!
GetDIBits
(
hdc
,
mask
,
0
,
bm
.
bmHeight
,
mask_bits
,
info
,
DIB_RGB_COLORS
))
goto
failed
;
ptr
=
bits
;
for
(
i
=
0
;
i
<
bm
.
bmHeight
;
i
++
)
for
(
j
=
0
;
j
<
bm
.
bmWidth
;
j
++
,
ptr
++
)
if
(
!
((
mask_bits
[
i
*
width_bytes
+
j
/
8
]
<<
(
j
%
8
))
&
0x80
))
*
ptr
|=
0xff000000
;
HeapFree
(
GetProcessHeap
(),
0
,
mask_bits
);
}
return
bits
;
failed:
HeapFree
(
GetProcessHeap
(),
0
,
bits
);
HeapFree
(
GetProcessHeap
(),
0
,
mask_bits
);
*
width
=
*
height
=
0
;
return
NULL
;
}
enum
android_system_cursors
{
TYPE_ARROW
=
1000
,
TYPE_CONTEXT_MENU
=
1001
,
TYPE_HAND
=
1002
,
TYPE_HELP
=
1003
,
TYPE_WAIT
=
1004
,
TYPE_CELL
=
1006
,
TYPE_CROSSHAIR
=
1007
,
TYPE_TEXT
=
1008
,
TYPE_VERTICAL_TEXT
=
1009
,
TYPE_ALIAS
=
1010
,
TYPE_COPY
=
1011
,
TYPE_NO_DROP
=
1012
,
TYPE_ALL_SCROLL
=
1013
,
TYPE_HORIZONTAL_DOUBLE_ARROW
=
1014
,
TYPE_VERTICAL_DOUBLE_ARROW
=
1015
,
TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW
=
1016
,
TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW
=
1017
,
TYPE_ZOOM_IN
=
1018
,
TYPE_ZOOM_OUT
=
1019
,
TYPE_GRAB
=
1020
,
TYPE_GRABBING
=
1021
,
};
struct
system_cursors
{
WORD
id
;
enum
android_system_cursors
android_id
;
};
static
const
struct
system_cursors
user32_cursors
[]
=
{
{
OCR_NORMAL
,
TYPE_ARROW
},
{
OCR_IBEAM
,
TYPE_TEXT
},
{
OCR_WAIT
,
TYPE_WAIT
},
{
OCR_CROSS
,
TYPE_CROSSHAIR
},
{
OCR_SIZE
,
TYPE_ALL_SCROLL
},
{
OCR_SIZEALL
,
TYPE_ALL_SCROLL
},
{
OCR_SIZENWSE
,
TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW
},
{
OCR_SIZENESW
,
TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW
},
{
OCR_SIZEWE
,
TYPE_HORIZONTAL_DOUBLE_ARROW
},
{
OCR_SIZENS
,
TYPE_VERTICAL_DOUBLE_ARROW
},
{
OCR_NO
,
TYPE_NO_DROP
},
{
OCR_HAND
,
TYPE_HAND
},
{
OCR_HELP
,
TYPE_HELP
},
{
0
}
};
static
const
struct
system_cursors
comctl32_cursors
[]
=
{
/* 102 TYPE_MOVE doesn't exist */
{
104
,
TYPE_COPY
},
{
105
,
TYPE_ARROW
},
{
106
,
TYPE_HORIZONTAL_DOUBLE_ARROW
},
{
107
,
TYPE_HORIZONTAL_DOUBLE_ARROW
},
{
108
,
TYPE_GRABBING
},
{
135
,
TYPE_VERTICAL_DOUBLE_ARROW
},
{
0
}
};
static
const
struct
system_cursors
ole32_cursors
[]
=
{
{
1
,
TYPE_NO_DROP
},
/* 2 TYPE_MOVE doesn't exist */
{
3
,
TYPE_COPY
},
{
4
,
TYPE_ALIAS
},
{
0
}
};
static
const
struct
system_cursors
riched20_cursors
[]
=
{
{
105
,
TYPE_GRABBING
},
{
109
,
TYPE_COPY
},
/* 110 TYPE_MOVE doesn't exist */
{
111
,
TYPE_NO_DROP
},
{
0
}
};
static
const
struct
{
const
struct
system_cursors
*
cursors
;
WCHAR
name
[
16
];
}
module_cursors
[]
=
{
{
user32_cursors
,
{
'u'
,
's'
,
'e'
,
'r'
,
'3'
,
'2'
,
'.'
,
'd'
,
'l'
,
'l'
,
0
}
},
{
comctl32_cursors
,
{
'c'
,
'o'
,
'm'
,
'c'
,
't'
,
'l'
,
'3'
,
'2'
,
'.'
,
'd'
,
'l'
,
'l'
,
0
}
},
{
ole32_cursors
,
{
'o'
,
'l'
,
'e'
,
'3'
,
'2'
,
'.'
,
'd'
,
'l'
,
'l'
,
0
}
},
{
riched20_cursors
,
{
'r'
,
'i'
,
'c'
,
'h'
,
'e'
,
'd'
,
'2'
,
'0'
,
'.'
,
'd'
,
'l'
,
'l'
,
0
}
}
};
static
int
get_cursor_system_id
(
const
ICONINFOEXW
*
info
)
{
const
struct
system_cursors
*
cursors
;
unsigned
int
i
;
HMODULE
module
;
if
(
info
->
szResName
[
0
])
return
0
;
/* only integer resources are supported here */
if
(
!
(
module
=
GetModuleHandleW
(
info
->
szModName
)))
return
0
;
for
(
i
=
0
;
i
<
sizeof
(
module_cursors
)
/
sizeof
(
module_cursors
[
0
]);
i
++
)
if
(
GetModuleHandleW
(
module_cursors
[
i
].
name
)
==
module
)
break
;
if
(
i
==
sizeof
(
module_cursors
)
/
sizeof
(
module_cursors
[
0
]))
return
0
;
cursors
=
module_cursors
[
i
].
cursors
;
for
(
i
=
0
;
cursors
[
i
].
id
;
i
++
)
if
(
cursors
[
i
].
id
==
info
->
wResID
)
return
cursors
[
i
].
android_id
;
return
0
;
}
static
WNDPROC
desktop_orig_wndproc
;
...
...
@@ -1205,6 +1426,51 @@ void CDECL ANDROID_SetCapture( HWND hwnd, UINT flags )
/***********************************************************************
* ANDROID_SetCursor
*/
void
CDECL
ANDROID_SetCursor
(
HCURSOR
handle
)
{
static
HCURSOR
last_cursor
;
static
DWORD
last_cursor_change
;
if
(
InterlockedExchangePointer
(
(
void
**
)
&
last_cursor
,
handle
)
!=
handle
||
GetTickCount
()
-
last_cursor_change
>
100
)
{
last_cursor_change
=
GetTickCount
();
if
(
handle
)
{
unsigned
int
width
=
0
,
height
=
0
,
*
bits
=
NULL
;
ICONINFOEXW
info
;
int
id
;
info
.
cbSize
=
sizeof
(
info
);
if
(
!
GetIconInfoExW
(
handle
,
&
info
))
return
;
if
(
!
(
id
=
get_cursor_system_id
(
&
info
)))
{
HDC
hdc
=
CreateCompatibleDC
(
0
);
bits
=
get_bitmap_argb
(
hdc
,
info
.
hbmColor
,
info
.
hbmMask
,
&
width
,
&
height
);
DeleteDC
(
hdc
);
/* make sure hotspot is valid */
if
(
info
.
xHotspot
>=
width
||
info
.
yHotspot
>=
height
)
{
info
.
xHotspot
=
width
/
2
;
info
.
yHotspot
=
height
/
2
;
}
}
ioctl_set_cursor
(
id
,
width
,
height
,
info
.
xHotspot
,
info
.
yHotspot
,
bits
);
HeapFree
(
GetProcessHeap
(),
0
,
bits
);
DeleteObject
(
info
.
hbmColor
);
DeleteObject
(
info
.
hbmMask
);
}
else
ioctl_set_cursor
(
0
,
0
,
0
,
0
,
0
,
NULL
);
}
}
/***********************************************************************
* ANDROID_SetWindowStyle
*/
void
CDECL
ANDROID_SetWindowStyle
(
HWND
hwnd
,
INT
offset
,
STYLESTRUCT
*
style
)
...
...
dlls/wineandroid.drv/wineandroid.drv.spec
View file @
61888e00
...
...
@@ -9,6 +9,7 @@
@ cdecl MapVirtualKeyEx(long long long) ANDROID_MapVirtualKeyEx
@ cdecl ToUnicodeEx(long long ptr ptr long long long) ANDROID_ToUnicodeEx
@ cdecl VkKeyScanEx(long long) ANDROID_VkKeyScanEx
@ cdecl SetCursor(long) ANDROID_SetCursor
@ cdecl ChangeDisplaySettingsEx(ptr ptr long long long) ANDROID_ChangeDisplaySettingsEx
@ cdecl EnumDisplayMonitors(long ptr ptr long) ANDROID_EnumDisplayMonitors
@ cdecl EnumDisplaySettingsEx(ptr long ptr long) ANDROID_EnumDisplaySettingsEx
...
...
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