mobile & web rgba stream

This commit is contained in:
csf
2022-05-19 23:45:44 +08:00
parent 9ecacadd4a
commit 7c5a136b6b
6 changed files with 76 additions and 130 deletions

View File

@@ -17,12 +17,11 @@ import '../widgets/overlay.dart';
import 'native_model.dart' if (dart.library.html) 'web_model.dart';
typedef HandleMsgBox = void Function(Map<String, dynamic> evt, String id);
bool _waitForImage = false;
class FfiModel with ChangeNotifier {
PeerInfo _pi = PeerInfo();
Display _display = Display();
var _decoding = false;
bool _waitForImage = false;
var _inputBlocked = false;
final _permissions = Map<String, bool>();
bool? _secure;
@@ -122,7 +121,6 @@ class FfiModel with ChangeNotifier {
void updateEventListener(String peerId) {
final void Function(Map<String, dynamic>) cb = (evt) {
var pos;
var name = evt['name'];
if (name == 'msgbox') {
handleMsgBox(evt, peerId);
@@ -138,7 +136,7 @@ class FfiModel with ChangeNotifier {
} else if (name == 'cursor_id') {
FFI.cursorModel.updateCursorId(evt);
} else if (name == 'cursor_position') {
pos = evt;
FFI.cursorModel.updateCursorPosition(evt);
} else if (name == 'clipboard') {
Clipboard.setData(ClipboardData(text: evt['content']));
} else if (name == 'permission') {
@@ -165,31 +163,6 @@ class FfiModel with ChangeNotifier {
} else if (name == 'on_client_remove') {
FFI.serverModel.onClientRemove(evt);
}
if (pos != null) FFI.cursorModel.updateCursorPosition(pos);
if (!_decoding) {
var rgba = PlatformFFI.getRgba();
if (rgba != null) {
if (_waitForImage) {
_waitForImage = false;
SmartDialog.dismiss();
}
_decoding = true;
final pid = FFI.id;
ui.decodeImageFromPixels(rgba, _display.width, _display.height,
isWeb ? ui.PixelFormat.rgba8888 : ui.PixelFormat.bgra8888,
(image) {
PlatformFFI.clearRgbaFrame();
_decoding = false;
if (FFI.id != pid) return;
try {
// my throw exception, because the listener maybe already dispose
FFI.imageModel.update(image);
} catch (e) {
print('update image: $e');
}
});
}
}
};
PlatformFFI.setEventCallback(cb);
}
@@ -284,6 +257,29 @@ class ImageModel with ChangeNotifier {
ui.Image? get image => _image;
ImageModel() {
PlatformFFI.setRgbaCallback((rgba) {
if (_waitForImage) {
_waitForImage = false;
SmartDialog.dismiss();
}
final pid = FFI.id;
ui.decodeImageFromPixels(
rgba,
FFI.ffiModel.display.width,
FFI.ffiModel.display.height,
isWeb ? ui.PixelFormat.rgba8888 : ui.PixelFormat.bgra8888, (image) {
if (FFI.id != pid) return;
try {
// my throw exception, because the listener maybe already dispose
FFI.imageModel.update(image);
} catch (e) {
print('update image: $e');
}
});
});
}
void update(ui.Image? image) {
if (_image == null && image != null) {
if (isDesktop) {

View File

@@ -19,8 +19,6 @@ class RgbaFrame extends Struct {
typedef F2 = Pointer<Utf8> Function(Pointer<Utf8>, Pointer<Utf8>);
typedef F3 = void Function(Pointer<Utf8>, Pointer<Utf8>);
typedef F4 = void Function(Pointer<RgbaFrame>);
typedef F5 = Pointer<RgbaFrame> Function();
class PlatformFFI {
static Pointer<RgbaFrame>? _lastRgbaFrame;
@@ -28,23 +26,8 @@ class PlatformFFI {
static String _homeDir = '';
static F2? _getByName;
static F3? _setByName;
static F4? _freeRgba;
static F5? _getRgba;
static void Function(Map<String, dynamic>)? _eventCallback;
static void clearRgbaFrame() {
if (_lastRgbaFrame != null &&
_lastRgbaFrame != nullptr &&
_freeRgba != null) _freeRgba!(_lastRgbaFrame!);
}
static Uint8List? getRgba() {
if (_getRgba == null) return null;
_lastRgbaFrame = _getRgba!();
if (_lastRgbaFrame == null || _lastRgbaFrame == nullptr) return null;
final ref = _lastRgbaFrame!.ref;
return Uint8List.sublistView(ref.data.asTypedList(ref.len));
}
static void Function(Uint8List)? _rgbaCallback;
static Future<String> getVersion() async {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
@@ -85,9 +68,6 @@ class PlatformFFI {
_setByName =
dylib.lookupFunction<Void Function(Pointer<Utf8>, Pointer<Utf8>), F3>(
'set_by_name');
_freeRgba = dylib
.lookupFunction<Void Function(Pointer<RgbaFrame>), F4>('free_rgba');
_getRgba = dylib.lookupFunction<F5, F5>('get_rgba');
_dir = (await getApplicationDocumentsDirectory()).path;
_startListenEvent(RustdeskImpl(dylib));
try {
@@ -119,23 +99,38 @@ class PlatformFFI {
version = await getVersion();
}
static void _startListenEvent(RustdeskImpl rustdeskImpl) async {
await for (final message in rustdeskImpl.startEventStream()) {
if (_eventCallback != null) {
try {
Map<String, dynamic> event = json.decode(message);
_eventCallback!(event);
} catch (e) {
print('json.decode fail(): $e');
static void _startListenEvent(RustdeskImpl rustdeskImpl) {
() async {
await for (final message in rustdeskImpl.startEventStream()) {
if (_eventCallback != null) {
try {
Map<String, dynamic> event = json.decode(message);
_eventCallback!(event);
} catch (e) {
print('json.decode fail(): $e');
}
}
}
}
}();
() async {
await for (final rgba in rustdeskImpl.startRgbaStream()) {
if (_rgbaCallback != null) {
_rgbaCallback!(rgba);
} else {
rgba.clear();
}
}
}();
}
static void setEventCallback(void Function(Map<String, dynamic>) fun) async {
_eventCallback = fun;
}
static void setRgbaCallback(void Function(Uint8List) fun) async {
_rgbaCallback = fun;
}
static void startDesktopWebListener() {}
static void stopDesktopWebListener() {}

View File

@@ -10,12 +10,6 @@ final List<StreamSubscription<MouseEvent>> mouseListeners = [];
final List<StreamSubscription<KeyboardEvent>> keyListeners = [];
class PlatformFFI {
static void clearRgbaFrame() {}
static Uint8List? getRgba() {
return context.callMethod('getRgba');
}
static String getByName(String name, [String arg = '']) {
return context.callMethod('getByName', [name, arg]);
}
@@ -31,7 +25,7 @@ class PlatformFFI {
version = getByName('version');
}
static void setEventCallback(void Function(Map<String, dynamic>) fun) async {
static void setEventCallback(void Function(Map<String, dynamic>) fun) {
context["onGlobalEvent"] = (String message) {
try {
Map<String, dynamic> event = json.decode(message);
@@ -42,6 +36,14 @@ class PlatformFFI {
};
}
static void setRgbaCallback(void Function(Uint8List) fun) {
context["onRgba"] = (Uint8List? rgba) {
if (rgba != null) {
fun(rgba);
}
};
}
static void startDesktopWebListener() {
mouseListeners.add(
window.document.onContextMenu.listen((evt) => evt.preventDefault()));