wineandroid: Create window groups inside every window to support a client area.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f77bbd45d6
commit
cd2b41a2b4
|
@ -61,6 +61,8 @@ public class WineActivity extends Activity
|
||||||
private final String LOGTAG = "wine";
|
private final String LOGTAG = "wine";
|
||||||
private ProgressDialog progress_dialog;
|
private ProgressDialog progress_dialog;
|
||||||
|
|
||||||
|
protected WineWindow desktop_window;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState)
|
public void onCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
|
@ -297,9 +299,10 @@ protected class WineWindow extends Object
|
||||||
protected Rect visible_rect;
|
protected Rect visible_rect;
|
||||||
protected Rect client_rect;
|
protected Rect client_rect;
|
||||||
protected WineWindow parent;
|
protected WineWindow parent;
|
||||||
protected WineView window_view;
|
|
||||||
protected Surface window_surface;
|
protected Surface window_surface;
|
||||||
protected Surface client_surface;
|
protected Surface client_surface;
|
||||||
|
protected WineWindowGroup window_group;
|
||||||
|
protected WineWindowGroup client_group;
|
||||||
|
|
||||||
public WineWindow( int w, WineWindow parent )
|
public WineWindow( int w, WineWindow parent )
|
||||||
{
|
{
|
||||||
|
@ -311,20 +314,63 @@ public WineWindow( int w, WineWindow parent )
|
||||||
visible_rect = client_rect = new Rect( 0, 0, 0, 0 );
|
visible_rect = client_rect = new Rect( 0, 0, 0, 0 );
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
win_map.put( w, this );
|
win_map.put( w, this );
|
||||||
if (parent == null)
|
|
||||||
{
|
|
||||||
window_view = new WineView( WineActivity.this, this, false );
|
|
||||||
window_view.layout( 0, 0, 1, 1 ); // make sure the surface gets created
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy()
|
public void destroy()
|
||||||
{
|
{
|
||||||
Log.i( LOGTAG, String.format( "destroy hwnd %08x", hwnd ));
|
Log.i( LOGTAG, String.format( "destroy hwnd %08x", hwnd ));
|
||||||
if (visible && window_view != null) top_view.removeView( window_view );
|
|
||||||
visible = false;
|
visible = false;
|
||||||
window_view = null;
|
|
||||||
win_map.remove( this );
|
win_map.remove( this );
|
||||||
|
destroy_window_groups();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WineWindowGroup create_window_groups()
|
||||||
|
{
|
||||||
|
if (client_group != null) return client_group;
|
||||||
|
window_group = new WineWindowGroup();
|
||||||
|
client_group = new WineWindowGroup();
|
||||||
|
window_group.addView( client_group );
|
||||||
|
client_group.set_layout( client_rect.left - visible_rect.left,
|
||||||
|
client_rect.top - visible_rect.top,
|
||||||
|
client_rect.right - visible_rect.left,
|
||||||
|
client_rect.bottom - visible_rect.top );
|
||||||
|
if (parent != null)
|
||||||
|
{
|
||||||
|
WineWindowGroup parent_group = parent.create_window_groups();
|
||||||
|
if (visible) parent_group.addView( window_group );
|
||||||
|
window_group.set_layout( visible_rect.left, visible_rect.top,
|
||||||
|
visible_rect.right, visible_rect.bottom );
|
||||||
|
window_group.bringToFront();
|
||||||
|
}
|
||||||
|
return client_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy_window_groups()
|
||||||
|
{
|
||||||
|
if (window_group != null)
|
||||||
|
{
|
||||||
|
if (parent != null) parent.client_group.removeView( window_group );
|
||||||
|
window_group.destroy_view();
|
||||||
|
}
|
||||||
|
if (client_group != null) client_group.destroy_view();
|
||||||
|
window_group = null;
|
||||||
|
client_group = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public View create_whole_view()
|
||||||
|
{
|
||||||
|
if (window_group == null) create_window_groups();
|
||||||
|
window_group.create_view( this, false ).layout( 0, 0, visible_rect.right - visible_rect.left,
|
||||||
|
visible_rect.bottom - visible_rect.top );
|
||||||
|
return window_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void create_client_view()
|
||||||
|
{
|
||||||
|
if (client_group == null) create_window_groups();
|
||||||
|
Log.i( "wine", String.format( "creating client view %08x %s", hwnd, client_rect ));
|
||||||
|
client_group.create_view( this, true ).layout( 0, 0, client_rect.right - client_rect.left,
|
||||||
|
client_rect.bottom - client_rect.top );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pos_changed( int flags, int insert_after, int owner, int style,
|
public void pos_changed( int flags, int insert_after, int owner, int style,
|
||||||
|
@ -337,27 +383,42 @@ public void pos_changed( int flags, int insert_after, int owner, int style,
|
||||||
Log.i( LOGTAG, String.format( "pos changed hwnd %08x after %08x owner %08x style %08x win %s client %s visible %s flags %08x",
|
Log.i( LOGTAG, String.format( "pos changed hwnd %08x after %08x owner %08x style %08x win %s client %s visible %s flags %08x",
|
||||||
hwnd, insert_after, owner, style, window_rect, client_rect, visible_rect, flags ));
|
hwnd, insert_after, owner, style, window_rect, client_rect, visible_rect, flags ));
|
||||||
|
|
||||||
if (parent == null)
|
if (window_group != null)
|
||||||
{
|
{
|
||||||
window_view.layout( visible_rect.left, visible_rect.top, visible_rect.right, visible_rect.bottom );
|
window_group.set_layout( visible_rect.left, visible_rect.top,
|
||||||
if (!visible && (style & WS_VISIBLE) != 0) top_view.addView( window_view );
|
visible_rect.right, visible_rect.bottom );
|
||||||
else if (visible && (style & WS_VISIBLE) == 0) top_view.removeView( window_view );
|
if (parent != null)
|
||||||
|
{
|
||||||
|
if (!visible && (style & WS_VISIBLE) != 0)
|
||||||
|
parent.client_group.addView( window_group );
|
||||||
|
else if (visible && (style & WS_VISIBLE) == 0)
|
||||||
|
parent.client_group.removeView( window_group );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (client_group != null)
|
||||||
|
client_group.set_layout( client_rect.left - visible_rect.left,
|
||||||
|
client_rect.top - visible_rect.top,
|
||||||
|
client_rect.right - visible_rect.left,
|
||||||
|
client_rect.bottom - visible_rect.top );
|
||||||
|
|
||||||
visible = (style & WS_VISIBLE) != 0;
|
visible = (style & WS_VISIBLE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_parent( WineWindow new_parent )
|
public void set_parent( WineWindow new_parent )
|
||||||
{
|
{
|
||||||
Log.i( LOGTAG, String.format( "set parent hwnd %08x parent %08x -> %08x",
|
Log.i( LOGTAG, String.format( "set parent hwnd %08x parent %08x -> %08x",
|
||||||
hwnd, parent == null ? 0 : parent.hwnd,
|
hwnd, parent.hwnd, new_parent.hwnd ));
|
||||||
new_parent == null ? 0 : new_parent.hwnd ));
|
if (window_group != null)
|
||||||
parent = new_parent;
|
|
||||||
if (new_parent == null)
|
|
||||||
{
|
{
|
||||||
window_view = new WineView( WineActivity.this, this, false );
|
if (visible) parent.client_group.removeView( window_group );
|
||||||
window_view.layout( 0, 0, 1, 1 ); // make sure the surface gets created
|
WineWindowGroup parent_group = new_parent.create_window_groups();
|
||||||
|
if (visible) parent_group.addView( window_group );
|
||||||
|
window_group.set_layout( visible_rect.left, visible_rect.top,
|
||||||
|
visible_rect.right, visible_rect.bottom );
|
||||||
|
window_group.bringToFront();
|
||||||
}
|
}
|
||||||
else window_view = null;
|
parent = new_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int get_hwnd()
|
public int get_hwnd()
|
||||||
|
@ -385,8 +446,70 @@ public void set_surface( SurfaceTexture surftex, boolean is_client )
|
||||||
|
|
||||||
public void get_event_pos( MotionEvent event, int[] pos )
|
public void get_event_pos( MotionEvent event, int[] pos )
|
||||||
{
|
{
|
||||||
pos[0] = Math.round( event.getX() + window_view.getLeft() );
|
pos[0] = Math.round( event.getX() + window_group.getLeft() );
|
||||||
pos[1] = Math.round( event.getY() + window_view.getTop() );
|
pos[1] = Math.round( event.getY() + window_group.getTop() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Window group for a Wine window, optionally containing a content view
|
||||||
|
//
|
||||||
|
|
||||||
|
protected class WineWindowGroup extends ViewGroup
|
||||||
|
{
|
||||||
|
private WineView content_view;
|
||||||
|
private WineWindow win;
|
||||||
|
|
||||||
|
WineWindowGroup()
|
||||||
|
{
|
||||||
|
super( WineActivity.this );
|
||||||
|
setVisibility( View.VISIBLE );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wrapper for layout() making sure that the view is not empty */
|
||||||
|
public void set_layout( int left, int top, int right, int bottom )
|
||||||
|
{
|
||||||
|
if (right <= left + 1) right = left + 2;
|
||||||
|
if (bottom <= top + 1) bottom = top + 2;
|
||||||
|
layout( left, top, right, bottom );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLayout( boolean changed, int left, int top, int right, int bottom )
|
||||||
|
{
|
||||||
|
if (content_view != null) content_view.layout( 0, 0, right - left, bottom - top );
|
||||||
|
}
|
||||||
|
|
||||||
|
public WineView create_view( WineWindow win, boolean is_client )
|
||||||
|
{
|
||||||
|
if (content_view != null) return content_view;
|
||||||
|
content_view = new WineView( WineActivity.this, win, is_client );
|
||||||
|
addView( content_view );
|
||||||
|
this.win = win;
|
||||||
|
if (!is_client)
|
||||||
|
{
|
||||||
|
content_view.setFocusable( true );
|
||||||
|
content_view.setFocusableInTouchMode( true );
|
||||||
|
}
|
||||||
|
return content_view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy_view()
|
||||||
|
{
|
||||||
|
if (content_view == null) return;
|
||||||
|
removeView( content_view );
|
||||||
|
content_view = null;
|
||||||
|
win = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WineView get_content_view()
|
||||||
|
{
|
||||||
|
return content_view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WineWindow get_window()
|
||||||
|
{
|
||||||
|
return win;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,7 +566,7 @@ public void onSurfaceTextureUpdated(SurfaceTexture surftex)
|
||||||
public boolean onGenericMotionEvent( MotionEvent event )
|
public boolean onGenericMotionEvent( MotionEvent event )
|
||||||
{
|
{
|
||||||
if (is_client) return false; // let the whole window handle it
|
if (is_client) return false; // let the whole window handle it
|
||||||
if (window.parent != null) return false; // let the parent handle it
|
if (window.parent != null && window.parent != desktop_window) return false; // let the parent handle it
|
||||||
|
|
||||||
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0)
|
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0)
|
||||||
{
|
{
|
||||||
|
@ -461,7 +584,7 @@ public boolean onGenericMotionEvent( MotionEvent event )
|
||||||
public boolean onTouchEvent( MotionEvent event )
|
public boolean onTouchEvent( MotionEvent event )
|
||||||
{
|
{
|
||||||
if (is_client) return false; // let the whole window handle it
|
if (is_client) return false; // let the whole window handle it
|
||||||
if (window.parent != null) return false; // let the parent handle it
|
if (window.parent != null && window.parent != desktop_window) return false; // let the parent handle it
|
||||||
|
|
||||||
int[] pos = new int[2];
|
int[] pos = new int[2];
|
||||||
window.get_event_pos( event, pos );
|
window.get_event_pos( event, pos );
|
||||||
|
@ -488,12 +611,12 @@ public boolean dispatchKeyEvent( KeyEvent event )
|
||||||
|
|
||||||
protected class TopView extends ViewGroup
|
protected class TopView extends ViewGroup
|
||||||
{
|
{
|
||||||
private int desktop_hwnd;
|
|
||||||
|
|
||||||
public TopView( Context context, int hwnd )
|
public TopView( Context context, int hwnd )
|
||||||
{
|
{
|
||||||
super( context );
|
super( context );
|
||||||
desktop_hwnd = hwnd;
|
desktop_window = new WineWindow( hwnd, null );
|
||||||
|
addView( desktop_window.create_whole_view() );
|
||||||
|
desktop_window.client_group.bringToFront();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -510,8 +633,6 @@ protected void onLayout( boolean changed, int left, int top, int right, int bott
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TopView top_view;
|
|
||||||
|
|
||||||
protected WineWindow get_window( int hwnd )
|
protected WineWindow get_window( int hwnd )
|
||||||
{
|
{
|
||||||
return win_map.get( hwnd );
|
return win_map.get( hwnd );
|
||||||
|
@ -522,8 +643,7 @@ protected WineWindow get_window( int hwnd )
|
||||||
public void create_desktop_window( int hwnd )
|
public void create_desktop_window( int hwnd )
|
||||||
{
|
{
|
||||||
Log.i( LOGTAG, String.format( "create desktop view %08x", hwnd ));
|
Log.i( LOGTAG, String.format( "create desktop view %08x", hwnd ));
|
||||||
top_view = new TopView( this, hwnd );
|
setContentView( new TopView( this, hwnd ));
|
||||||
setContentView( top_view );
|
|
||||||
progress_dialog.dismiss();
|
progress_dialog.dismiss();
|
||||||
wine_config_changed( getResources().getConfiguration().densityDpi );
|
wine_config_changed( getResources().getConfiguration().densityDpi );
|
||||||
}
|
}
|
||||||
|
@ -531,7 +651,13 @@ public void create_desktop_window( int hwnd )
|
||||||
public void create_window( int hwnd, boolean opengl, int parent, int pid )
|
public void create_window( int hwnd, boolean opengl, int parent, int pid )
|
||||||
{
|
{
|
||||||
WineWindow win = get_window( hwnd );
|
WineWindow win = get_window( hwnd );
|
||||||
if (win == null) win = new WineWindow( hwnd, get_window( parent ));
|
if (win == null)
|
||||||
|
{
|
||||||
|
win = new WineWindow( hwnd, get_window( parent ));
|
||||||
|
win.create_window_groups();
|
||||||
|
if (win.parent == desktop_window) win.create_whole_view();
|
||||||
|
}
|
||||||
|
if (opengl) win.create_client_view();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy_window( int hwnd )
|
public void destroy_window( int hwnd )
|
||||||
|
@ -545,6 +671,7 @@ public void set_window_parent( int hwnd, int parent, int pid )
|
||||||
WineWindow win = get_window( hwnd );
|
WineWindow win = get_window( hwnd );
|
||||||
if (win == null) return;
|
if (win == null) return;
|
||||||
win.set_parent( get_window( parent ));
|
win.set_parent( get_window( parent ));
|
||||||
|
if (win.parent == desktop_window) win.create_whole_view();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void window_pos_changed( int hwnd, int flags, int insert_after, int owner, int style,
|
public void window_pos_changed( int hwnd, int flags, int insert_after, int owner, int style,
|
||||||
|
|
|
@ -1378,7 +1378,7 @@ struct ANativeWindow *create_ioctl_window( HWND hwnd, BOOL opengl )
|
||||||
|
|
||||||
req.hdr.hwnd = HandleToLong( win->hwnd );
|
req.hdr.hwnd = HandleToLong( win->hwnd );
|
||||||
req.hdr.opengl = win->opengl;
|
req.hdr.opengl = win->opengl;
|
||||||
req.parent = parent == GetDesktopWindow() ? 0 : HandleToLong( parent );
|
req.parent = HandleToLong( parent );
|
||||||
android_ioctl( IOCTL_CREATE_WINDOW, &req, sizeof(req), NULL, NULL );
|
android_ioctl( IOCTL_CREATE_WINDOW, &req, sizeof(req), NULL, NULL );
|
||||||
|
|
||||||
return &win->win;
|
return &win->win;
|
||||||
|
@ -1438,7 +1438,7 @@ int ioctl_set_window_parent( HWND hwnd, HWND parent )
|
||||||
|
|
||||||
req.hdr.hwnd = HandleToLong( hwnd );
|
req.hdr.hwnd = HandleToLong( hwnd );
|
||||||
req.hdr.opengl = FALSE;
|
req.hdr.opengl = FALSE;
|
||||||
req.parent = parent == GetDesktopWindow() ? 0 : HandleToLong( parent );
|
req.parent = HandleToLong( parent );
|
||||||
return android_ioctl( IOCTL_SET_WINDOW_PARENT, &req, sizeof(req), NULL, NULL );
|
return android_ioctl( IOCTL_SET_WINDOW_PARENT, &req, sizeof(req), NULL, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue