wineandroid: Add support for scaling window contents based on DPI.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
240edd3fa3
commit
e658c73aed
|
@ -308,6 +308,7 @@ protected class WineWindow extends Object
|
|||
protected int hwnd;
|
||||
protected int owner;
|
||||
protected int style;
|
||||
protected float scale;
|
||||
protected boolean visible;
|
||||
protected Rect visible_rect;
|
||||
protected Rect client_rect;
|
||||
|
@ -326,6 +327,7 @@ public WineWindow( int w, WineWindow parent )
|
|||
hwnd = w;
|
||||
owner = 0;
|
||||
style = 0;
|
||||
scale = 1.0f;
|
||||
visible = false;
|
||||
visible_rect = client_rect = new Rect( 0, 0, 0, 0 );
|
||||
this.parent = parent;
|
||||
|
@ -378,8 +380,10 @@ public void destroy_window_groups()
|
|||
public View create_whole_view()
|
||||
{
|
||||
if (window_group == null) create_window_groups();
|
||||
window_group.create_view( false ).layout( 0, 0, visible_rect.right - visible_rect.left,
|
||||
visible_rect.bottom - visible_rect.top );
|
||||
window_group.create_view( false ).layout( 0, 0,
|
||||
Math.round( (visible_rect.right - visible_rect.left) * scale ),
|
||||
Math.round( (visible_rect.bottom - visible_rect.top) * scale ));
|
||||
window_group.set_scale( scale );
|
||||
return window_group;
|
||||
}
|
||||
|
||||
|
@ -476,10 +480,11 @@ public void pos_changed( int flags, int insert_after, int owner, int style,
|
|||
client_rect.bottom - visible_rect.top );
|
||||
}
|
||||
|
||||
public void set_parent( WineWindow new_parent )
|
||||
public void set_parent( WineWindow new_parent, float scale )
|
||||
{
|
||||
Log.i( LOGTAG, String.format( "set parent hwnd %08x parent %08x -> %08x",
|
||||
hwnd, parent.hwnd, new_parent.hwnd ));
|
||||
this.scale = scale;
|
||||
if (window_group != null)
|
||||
{
|
||||
if (visible) remove_view_from_parent();
|
||||
|
@ -526,8 +531,8 @@ else if (surftex != window_surftex)
|
|||
|
||||
public void get_event_pos( MotionEvent event, int[] pos )
|
||||
{
|
||||
pos[0] = Math.round( event.getX() + window_group.getLeft() );
|
||||
pos[1] = Math.round( event.getY() + window_group.getTop() );
|
||||
pos[0] = Math.round( event.getX() * scale + window_group.getLeft() );
|
||||
pos[1] = Math.round( event.getY() * scale + window_group.getTop() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -550,6 +555,10 @@ protected class WineWindowGroup extends ViewGroup
|
|||
/* wrapper for layout() making sure that the view is not empty */
|
||||
public void set_layout( int left, int top, int right, int bottom )
|
||||
{
|
||||
left *= win.scale;
|
||||
top *= win.scale;
|
||||
right *= win.scale;
|
||||
bottom *= win.scale;
|
||||
if (right <= left + 1) right = left + 2;
|
||||
if (bottom <= top + 1) bottom = top + 2;
|
||||
layout( left, top, right, bottom );
|
||||
|
@ -561,6 +570,15 @@ protected void onLayout( boolean changed, int left, int top, int right, int bott
|
|||
if (content_view != null) content_view.layout( 0, 0, right - left, bottom - top );
|
||||
}
|
||||
|
||||
public void set_scale( float scale )
|
||||
{
|
||||
if (content_view == null) return;
|
||||
content_view.setPivotX( 0 );
|
||||
content_view.setPivotY( 0 );
|
||||
content_view.setScaleX( scale );
|
||||
content_view.setScaleY( scale );
|
||||
}
|
||||
|
||||
public WineView create_view( boolean is_client )
|
||||
{
|
||||
if (content_view != null) return content_view;
|
||||
|
@ -730,12 +748,13 @@ public void create_desktop_window( int hwnd )
|
|||
wine_config_changed( getResources().getConfiguration().densityDpi );
|
||||
}
|
||||
|
||||
public void create_window( int hwnd, boolean opengl, int parent, int pid )
|
||||
public void create_window( int hwnd, boolean opengl, int parent, float scale, int pid )
|
||||
{
|
||||
WineWindow win = get_window( hwnd );
|
||||
if (win == null)
|
||||
{
|
||||
win = new WineWindow( hwnd, get_window( parent ));
|
||||
win.scale = scale;
|
||||
win.create_window_groups();
|
||||
if (win.parent == desktop_window) win.create_whole_view();
|
||||
}
|
||||
|
@ -748,11 +767,11 @@ public void destroy_window( int hwnd )
|
|||
if (win != null) win.destroy();
|
||||
}
|
||||
|
||||
public void set_window_parent( int hwnd, int parent, int pid )
|
||||
public void set_window_parent( int hwnd, int parent, float scale, int pid )
|
||||
{
|
||||
WineWindow win = get_window( hwnd );
|
||||
if (win == null) return;
|
||||
win.set_parent( get_window( parent ));
|
||||
win.set_parent( get_window( parent ), scale );
|
||||
if (win.parent == desktop_window) win.create_whole_view();
|
||||
}
|
||||
|
||||
|
@ -769,9 +788,9 @@ public void createDesktopWindow( final int hwnd )
|
|||
runOnUiThread( new Runnable() { public void run() { create_desktop_window( hwnd ); }} );
|
||||
}
|
||||
|
||||
public void createWindow( final int hwnd, final boolean opengl, final int parent, final int pid )
|
||||
public void createWindow( final int hwnd, final boolean opengl, final int parent, final float scale, final int pid )
|
||||
{
|
||||
runOnUiThread( new Runnable() { public void run() { create_window( hwnd, opengl, parent, pid ); }} );
|
||||
runOnUiThread( new Runnable() { public void run() { create_window( hwnd, opengl, parent, scale, pid ); }} );
|
||||
}
|
||||
|
||||
public void destroyWindow( final int hwnd )
|
||||
|
@ -779,9 +798,9 @@ public void destroyWindow( final int hwnd )
|
|||
runOnUiThread( new Runnable() { public void run() { destroy_window( hwnd ); }} );
|
||||
}
|
||||
|
||||
public void setParent( final int hwnd, final int parent, final int pid )
|
||||
public void setParent( final int hwnd, final int parent, final float scale, final int pid )
|
||||
{
|
||||
runOnUiThread( new Runnable() { public void run() { set_window_parent( hwnd, parent, pid ); }} );
|
||||
runOnUiThread( new Runnable() { public void run() { set_window_parent( hwnd, parent, scale, pid ); }} );
|
||||
}
|
||||
|
||||
public void windowPosChanged( final int hwnd, final int flags, final int insert_after,
|
||||
|
|
|
@ -63,14 +63,14 @@ extern struct opengl_funcs *get_wgl_driver( UINT version ) DECLSPEC_HIDDEN;
|
|||
|
||||
extern void start_android_device(void) DECLSPEC_HIDDEN;
|
||||
extern void register_native_window( HWND hwnd, struct ANativeWindow *win, BOOL client ) DECLSPEC_HIDDEN;
|
||||
extern struct ANativeWindow *create_ioctl_window( HWND hwnd, BOOL opengl ) DECLSPEC_HIDDEN;
|
||||
extern struct ANativeWindow *create_ioctl_window( HWND hwnd, BOOL opengl, float scale ) DECLSPEC_HIDDEN;
|
||||
extern struct ANativeWindow *grab_ioctl_window( struct ANativeWindow *window ) DECLSPEC_HIDDEN;
|
||||
extern void release_ioctl_window( struct ANativeWindow *window ) DECLSPEC_HIDDEN;
|
||||
extern void destroy_ioctl_window( HWND hwnd, BOOL opengl ) DECLSPEC_HIDDEN;
|
||||
extern int ioctl_window_pos_changed( HWND hwnd, const RECT *window_rect, const RECT *client_rect,
|
||||
const RECT *visible_rect, UINT style, UINT flags,
|
||||
HWND after, HWND owner ) DECLSPEC_HIDDEN;
|
||||
extern int ioctl_set_window_parent( HWND hwnd, HWND parent ) 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;
|
||||
|
||||
|
||||
|
|
|
@ -132,6 +132,7 @@ struct ioctl_android_create_window
|
|||
{
|
||||
struct ioctl_header hdr;
|
||||
int parent;
|
||||
float scale;
|
||||
};
|
||||
|
||||
struct ioctl_android_destroy_window
|
||||
|
@ -203,6 +204,7 @@ struct ioctl_android_set_window_parent
|
|||
{
|
||||
struct ioctl_header hdr;
|
||||
int parent;
|
||||
float scale;
|
||||
};
|
||||
|
||||
struct ioctl_android_set_capture
|
||||
|
@ -595,10 +597,10 @@ static NTSTATUS createWindow_ioctl( void *data, DWORD in_size, DWORD out_size, U
|
|||
|
||||
TRACE( "hwnd %08x opengl %u parent %08x\n", res->hdr.hwnd, res->hdr.opengl, res->parent );
|
||||
|
||||
if (!(object = load_java_method( &method, "createWindow", "(IZII)V" ))) return STATUS_NOT_SUPPORTED;
|
||||
if (!(object = load_java_method( &method, "createWindow", "(IZIFI)V" ))) return STATUS_NOT_SUPPORTED;
|
||||
|
||||
wrap_java_call();
|
||||
(*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->hdr.opengl, res->parent, pid );
|
||||
(*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->hdr.opengl, res->parent, res->scale, pid );
|
||||
unwrap_java_call();
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -891,10 +893,10 @@ static NTSTATUS setWindowParent_ioctl( void *data, DWORD in_size, DWORD out_size
|
|||
|
||||
TRACE( "hwnd %08x parent %08x\n", res->hdr.hwnd, res->parent );
|
||||
|
||||
if (!(object = load_java_method( &method, "setParent", "(III)V" ))) return STATUS_NOT_SUPPORTED;
|
||||
if (!(object = load_java_method( &method, "setParent", "(IIFI)V" ))) return STATUS_NOT_SUPPORTED;
|
||||
|
||||
wrap_java_call();
|
||||
(*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->parent, pid );
|
||||
(*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->parent, res->scale, pid );
|
||||
unwrap_java_call();
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -1370,7 +1372,7 @@ static int perform( ANativeWindow *window, int operation, ... )
|
|||
return android_ioctl( IOCTL_PERFORM, &perf, sizeof(perf), NULL, NULL );
|
||||
}
|
||||
|
||||
struct ANativeWindow *create_ioctl_window( HWND hwnd, BOOL opengl )
|
||||
struct ANativeWindow *create_ioctl_window( HWND hwnd, BOOL opengl, float scale )
|
||||
{
|
||||
struct ioctl_android_create_window req;
|
||||
struct native_win_wrapper *win = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*win) );
|
||||
|
@ -1399,6 +1401,7 @@ struct ANativeWindow *create_ioctl_window( HWND hwnd, BOOL opengl )
|
|||
req.hdr.hwnd = HandleToLong( win->hwnd );
|
||||
req.hdr.opengl = win->opengl;
|
||||
req.parent = get_ioctl_win_parent( GetAncestor( hwnd, GA_PARENT ));
|
||||
req.scale = scale;
|
||||
android_ioctl( IOCTL_CREATE_WINDOW, &req, sizeof(req), NULL, NULL );
|
||||
|
||||
return &win->win;
|
||||
|
@ -1452,13 +1455,14 @@ int ioctl_window_pos_changed( HWND hwnd, const RECT *window_rect, const RECT *cl
|
|||
return android_ioctl( IOCTL_WINDOW_POS_CHANGED, &req, sizeof(req), NULL, NULL );
|
||||
}
|
||||
|
||||
int ioctl_set_window_parent( HWND hwnd, HWND parent )
|
||||
int ioctl_set_window_parent( HWND hwnd, HWND parent, float scale )
|
||||
{
|
||||
struct ioctl_android_set_window_parent req;
|
||||
|
||||
req.hdr.hwnd = HandleToLong( hwnd );
|
||||
req.hdr.opengl = FALSE;
|
||||
req.parent = get_ioctl_win_parent( parent );
|
||||
req.scale = scale;
|
||||
return android_ioctl( IOCTL_SET_WINDOW_PARENT, &req, sizeof(req), NULL, NULL );
|
||||
}
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format )
|
|||
gl->hwnd = hwnd;
|
||||
gl->hdc = hdc;
|
||||
gl->format = format;
|
||||
gl->window = create_ioctl_window( hwnd, TRUE );
|
||||
gl->window = create_ioctl_window( hwnd, TRUE, 1.0f );
|
||||
gl->surface = 0;
|
||||
gl->pbuffer = p_eglCreatePbufferSurface( display, pixel_formats[gl->format - 1].config, attribs );
|
||||
EnterCriticalSection( &drawable_section );
|
||||
|
|
|
@ -103,6 +103,21 @@ static inline int get_dib_image_size( const BITMAPINFO *info )
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* get_win_monitor_dpi
|
||||
*/
|
||||
static UINT get_win_monitor_dpi( HWND hwnd )
|
||||
{
|
||||
DPI_AWARENESS_CONTEXT context;
|
||||
UINT ret;
|
||||
|
||||
context = SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
|
||||
ret = GetDpiForSystem(); /* FIXME: get monitor dpi */
|
||||
SetThreadDpiAwarenessContext( context );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* alloc_win_data
|
||||
*/
|
||||
|
@ -113,7 +128,8 @@ static struct android_win_data *alloc_win_data( HWND hwnd )
|
|||
if ((data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data))))
|
||||
{
|
||||
data->hwnd = hwnd;
|
||||
data->window = create_ioctl_window( hwnd, FALSE );
|
||||
data->window = create_ioctl_window( hwnd, FALSE,
|
||||
(float)get_win_monitor_dpi( hwnd ) / GetDpiForWindow( hwnd ));
|
||||
EnterCriticalSection( &win_data_section );
|
||||
win_data_context[context_idx(hwnd)] = data;
|
||||
}
|
||||
|
@ -1176,7 +1192,7 @@ void CDECL ANDROID_SetParent( HWND hwnd, HWND parent, HWND old_parent )
|
|||
TRACE( "win %p parent %p -> %p\n", hwnd, old_parent, parent );
|
||||
|
||||
data->parent = (parent == GetDesktopWindow()) ? 0 : parent;
|
||||
ioctl_set_window_parent( hwnd, parent );
|
||||
ioctl_set_window_parent( hwnd, parent, (float)get_win_monitor_dpi( hwnd ) / GetDpiForWindow( hwnd ));
|
||||
release_win_data( data );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue