mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
mobile & web rgba stream
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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()));
|
||||
|
||||
Reference in New Issue
Block a user