diff --git a/flutter_hbb/lib/common.dart b/flutter_hbb/lib/common.dart index 9099a53ed..a9cf38f5a 100644 --- a/flutter_hbb/lib/common.dart +++ b/flutter_hbb/lib/common.dart @@ -62,6 +62,54 @@ class ImageModel with ChangeNotifier { } } +class CursorModel with ChangeNotifier { + ui.Image _image; + final _images = Map(); + double _x = 0; + double _y = 0; + double _hotx = 0; + double _hoty = 0; + + ui.Image get image => _image; + double get x => _x; + double get y => _y; + + void updateCursorData(Map evt) { + var id = int.parse(evt['id']); + _hotx = double.parse(evt['hotx']); + _hoty = double.parse(evt['hoty']); + var width = int.parse(evt['width']); + var height = int.parse(evt['height']); + List colors = json.decode(evt['colors']); + final rgba = Uint8List.fromList(colors.map((s) => s as int).toList()); + ui.decodeImageFromPixels(rgba, width, height, ui.PixelFormat.rgba8888, + (image) { + _image = image; + _images[id] = image; + notifyListeners(); + }); + } + + void updateCursorId(Map evt) { + final tmp = _images[int.parse(evt['id'])]; + if (tmp != null) { + _image = tmp; + notifyListeners(); + } + } + + void updateCursorPosition(Map evt) { + _x = double.parse(evt['x']); + _y = double.parse(evt['y']); + notifyListeners(); + } + + void clear() { + _image = null; + _images.clear(); + } +} + class FFI { static F1 _freeCString; static F2 _getByName; @@ -71,6 +119,7 @@ class FFI { static Pointer _lastRgbaFrame; static final imageModel = ImageModel(); static final ffiModel = FfiModel(); + static final cursorModel = CursorModel(); static String getId() { return getByName('remote_id'); @@ -130,6 +179,7 @@ class FFI { static void close() { setByName('close', ''); FFI.imageModel.update(null); + FFI.cursorModel.clear(); } static void setByName(String name, String value) { diff --git a/flutter_hbb/lib/main.dart b/flutter_hbb/lib/main.dart index e0589f04a..9e32c5bf5 100644 --- a/flutter_hbb/lib/main.dart +++ b/flutter_hbb/lib/main.dart @@ -14,13 +14,15 @@ class App extends StatelessWidget { value: FFI.ffiModel, child: ChangeNotifierProvider.value( value: FFI.imageModel, - child: MaterialApp( - title: 'RustDesk', - theme: ThemeData( - primarySwatch: Colors.blue, - visualDensity: VisualDensity.adaptivePlatformDensity, - ), - home: HomePage(title: 'RustDesk'), - ))); + child: ChangeNotifierProvider.value( + value: FFI.cursorModel, + child: MaterialApp( + title: 'RustDesk', + theme: ThemeData( + primarySwatch: Colors.blue, + visualDensity: VisualDensity.adaptivePlatformDensity, + ), + home: HomePage(title: 'RustDesk'), + )))); } } diff --git a/flutter_hbb/lib/remote_page.dart b/flutter_hbb/lib/remote_page.dart index 009fd0085..d1a16a921 100644 --- a/flutter_hbb/lib/remote_page.dart +++ b/flutter_hbb/lib/remote_page.dart @@ -56,6 +56,12 @@ class _RemotePageState extends State { handlePeerInfo(evt); } else if (name == 'switch_display') { handleSwitchDisplay(evt); + } else if (name == 'cursor_data') { + FFI.cursorModel.updateCursorData(evt); + } else if (name == 'cursor_id') { + FFI.cursorModel.updateCursorId(evt); + } else if (name == 'cursor_position') { + FFI.cursorModel.updateCursorPosition(evt); } } if (!_decoding) {