diff --git a/flutter_hbb/lib/common.dart b/flutter_hbb/lib/common.dart index dd6be65ba..ea69756ff 100644 --- a/flutter_hbb/lib/common.dart +++ b/flutter_hbb/lib/common.dart @@ -6,6 +6,7 @@ import 'dart:ffi'; import 'dart:async'; import 'dart:convert'; import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'dart:typed_data'; class RgbaFrame extends Struct { @Uint32() @@ -55,14 +56,15 @@ class FFI { static F3 _setByName; static F4 _freeRgba; static F5 _getRgba; + static Pointer _lastRgbaFrame; static String getId() { - return getByName("remote_id"); + return getByName('remote_id'); } static List peers() { try { - List peers = json.decode(getByName("peers")); + List peers = json.decode(getByName('peers')); return peers .map((s) => s as List) .map((s) => @@ -75,12 +77,25 @@ class FFI { } static void connect(String id) { - setByName("connect", id); + setByName('connect', id); + } + + static void _clearRgbaFrame() { + if (_lastRgbaFrame != null && _lastRgbaFrame != nullptr) + _freeRgba(_lastRgbaFrame); + } + + static Uint8List getRgba() { + _clearRgbaFrame(); + _lastRgbaFrame = _getRgba(); + if (_lastRgbaFrame == null || _lastRgbaFrame == nullptr) return null; + final ref = _lastRgbaFrame.ref; + return Uint8List.sublistView(ref.data.asTypedList(ref.len)); } static Map popEvent() { - var s = getByName("event"); - if (s == "") return null; + var s = getByName('event'); + if (s == '') return null; try { Map event = json.decode(s); return event; @@ -92,24 +107,25 @@ class FFI { static void login(String password, bool remember) { setByName( - "login", + 'login', json.encode({ - "password": password, - "remember": remember ? "true" : "false", + 'password': password, + 'remember': remember ? 'true' : 'false', })); } static void close() { - setByName("close", ""); + _clearRgbaFrame(); + setByName('close', ''); } static void setByName(String name, String value) { _setByName(Utf8.toUtf8(name), Utf8.toUtf8(value)); } - static String getByName(String name, {String arg = ""}) { + static String getByName(String name, {String arg = ''}) { var p = _getByName(Utf8.toUtf8(name), Utf8.toUtf8(arg)); - assert(p != null); + assert(p != nullptr && p != null); var res = Utf8.fromUtf8(p); // https://github.com/brickpop/flutter-rust-ffi _freeCString(p); @@ -130,7 +146,7 @@ class FFI { .lookupFunction), F4>('free_rgba'); _getRgba = dylib.lookupFunction('get_rgba'); final dir = (await getApplicationDocumentsDirectory()).path; - setByName("init", dir); + setByName('init', dir); } } @@ -162,7 +178,7 @@ void showSuccess(String text) { // https://material.io/develop/flutter/components/dialogs void enterPasswordDialog(String id, BuildContext context) { - var remember = FFI.getByName("remember", arg: id) == "true"; + var remember = FFI.getByName('remember', arg: id) == 'true'; var dialog = AlertDialog( title: Text('Please enter your password'), contentPadding: EdgeInsets.zero, diff --git a/flutter_hbb/lib/home_page.dart b/flutter_hbb/lib/home_page.dart index ffc346305..d6a36b5a4 100644 --- a/flutter_hbb/lib/home_page.dart +++ b/flutter_hbb/lib/home_page.dart @@ -45,7 +45,7 @@ class _HomePageState extends State { void onConnect() { var id = _idController.text.trim(); - if (id == "") return; + if (id == '') return; Navigator.push( context, MaterialPageRoute( diff --git a/flutter_hbb/lib/remote_page.dart b/flutter_hbb/lib/remote_page.dart index f6a1e2985..853bc0f2a 100644 --- a/flutter_hbb/lib/remote_page.dart +++ b/flutter_hbb/lib/remote_page.dart @@ -17,13 +17,18 @@ class RemotePage extends StatefulWidget { // https://github.com/hanxu317317/flutter_plan_demo/blob/master/lib/src/enter.dart class _RemotePageState extends State { Timer _interval; + int x = 0; + int y = 0; + int width = 0; + int height = 0; + ui.Image image; @override void initState() { super.initState(); FFI.connect(widget.id); WidgetsBinding.instance.addPostFrameCallback((_) { - showLoading("Connecting..."); + showLoading('Connecting...'); _interval = Timer.periodic(Duration(milliseconds: 30), (timer) => interval()); }); @@ -38,22 +43,33 @@ class _RemotePageState extends State { } void interval() { - print(DateTime.now()); var evt = FFI.popEvent(); if (evt == null) return; - var name = evt["name"]; - if (name == "msgbox") { + var name = evt['name']; + if (name == 'msgbox') { handleMsgbox(evt); } + var rgba = FFI.getRgba(); + if (rgba != null) { + ui.decodeImageFromPixels(rgba, width, height, ui.PixelFormat.rgba8888, + (_image) { + setState(() { + image = _image; + }); + }); + } } void handleMsgbox(evt) { - var type = evt["type"]; - var title = evt["title"]; - var text = evt["text"]; - if (type == "error") { - } else if (type == "re-input-password") { - } else if (type == "input-password") {} + var type = evt['type']; + var title = evt['title']; + var text = evt['text']; + if (type == 'error') { + } else if (type == 're-input-password') { + wrongPasswordDialog(widget.id, context); + } else if (type == 'input-password') { + enterPasswordDialog(widget.id, context); + } } @override @@ -65,14 +81,14 @@ class _RemotePageState extends State { return FlutterEasyLoading( child: GestureDetector( child: CustomPaint( - painter: new ImageEditor(image: null), + painter: new ImageEditor(image: image), ), onPanStart: (DragDownDetails) { - print("onPanStart $DragDownDetails"); + print('onPanStart $DragDownDetails'); // hero.moveTo(DragDownDetails.globalPosition.dx, DragDownDetails.globalPosition.dy); }, onPanUpdate: (DragDownDetails) { - print("onPanUpdate $DragDownDetails"); + print('onPanUpdate $DragDownDetails'); // hero.moveTo(DragDownDetails.globalPosition.dx, DragDownDetails.globalPosition.dy); })); }