Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
rustdesk
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
李朝发
rustdesk
Commits
a0c46c90
Unverified
Commit
a0c46c90
authored
Sep 12, 2022
by
RustDesk
Committed by
GitHub
Sep 12, 2022
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1497 from fufesou/flutter_desktop_cursors
Flutter desktop cursors
parents
d8f16a52
efe6d080
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
143 additions
and
105 deletions
+143
-105
common.dart
flutter/lib/common.dart
+2
-0
remote_page.dart
flutter/lib/desktop/pages/remote_page.dart
+15
-15
popup_menu.dart
flutter/lib/desktop/widgets/popup_menu.dart
+1
-1
main.dart
flutter/lib/main.dart
+2
-2
remote_page.dart
flutter/lib/mobile/pages/remote_page.dart
+2
-3
model.dart
flutter/lib/models/model.dart
+53
-65
native_model.dart
flutter/lib/models/native_model.dart
+17
-17
peer_model.dart
flutter/lib/models/peer_model.dart
+2
-2
image.dart
flutter/lib/utils/image.dart
+49
-0
No files found.
flutter/lib/common.dart
View file @
a0c46c90
...
...
@@ -33,6 +33,8 @@ late final DesktopType? desktopType;
typedef
F
=
String
Function
(
String
);
typedef
FMethod
=
String
Function
(
String
,
dynamic
);
typedef
StreamEventHandler
=
Future
<
void
>
Function
(
Map
<
String
,
dynamic
>);
late
final
iconKeyboard
=
MemoryImage
(
Uint8List
.
fromList
(
base64Decode
(
"iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAgVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9d3yJTAAAAKnRSTlMA0Gd/0y8ILZgbJffDPUwV2nvzt+TMqZxyU7CMb1pYQyzsvKunkXE4AwJnNC24AAAA+0lEQVQ4y83O2U7DMBCF4ZMxk9rZk26kpQs7nPd/QJy4EiLbLf01N5Y/2YP/qxDFQvGB5NPC/ZpVnfJx4b5xyGfF95rkHvNCWH1u+N6J6T0sC7gqRy8uGPfBLEbozPXUjlkQKwGaFPNizwQbwkx0TDvhCii34ExZCSQVBdzIOEOyeclSHgBGXkpeygXSQgStACtWx4Z8rr8COHOvfEP/IbbsQAToFUAAV1M408IIjIGYAPoCSNRP7DQutfQTqxuAiH7UUg1FaJR2AGrrx52sK2ye28LZ0wBAEyR6y8X+NADhm1B4fgiiHXbRrTrxpwEY9RdM9wsepnvFHfUDwYEeiwAJr/gAAAAASUVORK5CYII="
)));
late
final
iconClipboard
=
MemoryImage
(
Uint8List
.
fromList
(
base64Decode
(
...
...
flutter/lib/desktop/pages/remote_page.dart
View file @
a0c46c90
...
...
@@ -537,8 +537,17 @@ class ImagePaint extends StatelessWidget {
Widget
build
(
BuildContext
context
)
{
final
m
=
Provider
.
of
<
ImageModel
>(
context
);
var
c
=
Provider
.
of
<
CanvasModel
>(
context
);
final
s
=
c
.
scale
;
mouseRegion
({
child
})
=>
Obx
(()
=>
MouseRegion
(
cursor:
(
cursorOverImage
.
isTrue
&&
keyboardEnabled
.
isTrue
)
?
(
remoteCursorMoved
.
isTrue
?
SystemMouseCursors
.
none
:
_buildCustomCursorLinux
(
context
,
s
))
:
MouseCursor
.
defer
,
onHover:
(
evt
)
{},
child:
child
));
if
(
c
.
scrollStyle
==
ScrollStyle
.
scrollbar
)
{
final
imageWidget
=
SizedBox
(
width:
c
.
getDisplayWidth
()
*
s
,
...
...
@@ -547,7 +556,6 @@ class ImagePaint extends StatelessWidget {
painter:
ImagePainter
(
image:
m
.
image
,
x:
0
,
y:
0
,
scale:
s
),
));
Rx
<
Offset
>
pos
=
Rx
<
Offset
>(
const
Offset
(
0.0
,
0.0
));
return
Center
(
child:
NotificationListener
<
ScrollNotification
>(
onNotification:
(
notification
)
{
...
...
@@ -562,16 +570,8 @@ class ImagePaint extends StatelessWidget {
c
.
setScrollPercent
(
percentX
,
percentY
);
return
false
;
},
child:
Obx
(()
=>
MouseRegion
(
cursor:
(
cursorOverImage
.
isTrue
&&
keyboardEnabled
.
isTrue
)
?
(
remoteCursorMoved
.
isTrue
?
SystemMouseCursors
.
none
:
_buildCustomCursorLinux
(
context
,
s
))
:
MouseCursor
.
defer
,
onHover:
(
evt
)
{
pos
.
value
=
evt
.
position
;
},
child:
_buildCrossScrollbar
(
_buildListener
(
imageWidget
)))),
child:
mouseRegion
(
child:
_buildCrossScrollbar
(
_buildListener
(
imageWidget
))),
),
);
}
else
{
...
...
@@ -582,7 +582,7 @@ class ImagePaint extends StatelessWidget {
painter:
ImagePainter
(
image:
m
.
image
,
x:
c
.
x
/
s
,
y:
c
.
y
/
s
,
scale:
s
),
));
return
_buildListener
(
imageWidget
);
return
mouseRegion
(
child:
_buildListener
(
imageWidget
)
);
}
}
...
...
@@ -597,8 +597,8 @@ class ImagePaint extends StatelessWidget {
return
FlutterCustomMemoryImageCursor
(
pixbuf:
cacheLinux
.
data
,
key:
key
,
hotx:
cacheLinux
.
hotx
,
hoty:
cacheLinux
.
hoty
,
hotx:
0.0
,
hoty:
0.0
,
imageWidth:
(
cacheLinux
.
width
*
scale
).
toInt
(),
imageHeight:
(
cacheLinux
.
height
*
scale
).
toInt
(),
);
...
...
flutter/lib/desktop/widgets/popup_menu.dart
View file @
a0c46c90
...
...
@@ -8,7 +8,7 @@ import './material_mod_popup_menu.dart' as mod_menu;
// https://stackoverflow.com/questions/68318314/flutter-popup-menu-inside-popup-menu
class
PopupMenuChildrenItem
<
T
>
extends
mod_menu
.
PopupMenuEntry
<
T
>
{
PopupMenuChildrenItem
({
const
PopupMenuChildrenItem
({
key
,
this
.
height
=
kMinInteractiveDimension
,
this
.
padding
,
...
...
flutter/lib/main.dart
View file @
a0c46c90
...
...
@@ -273,13 +273,13 @@ _keepScaleBuilder() {
_registerEventHandler
()
{
if
(
desktopType
!=
DesktopType
.
main
)
{
platformFFI
.
registerEventHandler
(
'theme'
,
'theme'
,
(
evt
)
{
platformFFI
.
registerEventHandler
(
'theme'
,
'theme'
,
(
evt
)
async
{
String
?
dark
=
evt
[
'dark'
];
if
(
dark
!=
null
)
{
MyTheme
.
changeTo
(
dark
==
'true'
);
}
});
platformFFI
.
registerEventHandler
(
'language'
,
'language'
,
(
_
)
{
platformFFI
.
registerEventHandler
(
'language'
,
'language'
,
(
_
)
async
{
Get
.
forceAppUpdate
();
});
}
...
...
flutter/lib/mobile/pages/remote_page.dart
View file @
a0c46c90
...
...
@@ -1085,9 +1085,8 @@ void showOptions(String id, OverlayDialogManager dialogManager) async {
mainAxisSize:
MainAxisSize
.
min
,
children:
displays
+
<
Widget
>[
getRadio
(
'Original'
,
'original'
,
viewStyle
,
setViewStyle
),
getRadio
(
'Shrink'
,
'shrink'
,
viewStyle
,
setViewStyle
),
getRadio
(
'Stretch'
,
'stretch'
,
viewStyle
,
setViewStyle
),
getRadio
(
'Scale Original'
,
'original'
,
viewStyle
,
setViewStyle
),
getRadio
(
'Scale adaptive'
,
'adaptive'
,
viewStyle
,
setViewStyle
),
Divider
(
color:
MyTheme
.
border
),
getRadio
(
'Good image quality'
,
'best'
,
quality
,
setQuality
),
getRadio
(
'Balanced'
,
'balanced'
,
quality
,
setQuality
),
...
...
flutter/lib/models/model.dart
View file @
a0c46c90
...
...
@@ -4,7 +4,6 @@ import 'dart:io';
import
'dart:math'
;
import
'dart:typed_data'
;
import
'dart:ui'
as
ui
;
import
'dart:ui'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/services.dart'
;
...
...
@@ -21,6 +20,7 @@ import 'package:flutter_custom_cursor/flutter_custom_cursor.dart';
import
'../common.dart'
;
import
'../common/shared_state.dart'
;
import
'../utils/image.dart'
as
img
;
import
'../mobile/widgets/dialog.dart'
;
import
'peer_model.dart'
;
import
'platform_model.dart'
;
...
...
@@ -127,8 +127,8 @@ class FfiModel with ChangeNotifier {
_permissions
.
clear
();
}
void
Function
(
Map
<
String
,
dynamic
>)
startEventListener
(
String
peerId
)
{
return
(
evt
)
{
StreamEventHandler
startEventListener
(
String
peerId
)
{
return
(
evt
)
async
{
var
name
=
evt
[
'name'
];
if
(
name
==
'msgbox'
)
{
handleMsgBox
(
evt
,
peerId
);
...
...
@@ -140,11 +140,11 @@ class FfiModel with ChangeNotifier {
}
else
if
(
name
==
'switch_display'
)
{
handleSwitchDisplay
(
evt
);
}
else
if
(
name
==
'cursor_data'
)
{
parent
.
target
?.
cursorModel
.
updateCursorData
(
evt
);
await
parent
.
target
?.
cursorModel
.
updateCursorData
(
evt
);
}
else
if
(
name
==
'cursor_id'
)
{
parent
.
target
?.
cursorModel
.
updateCursorId
(
evt
);
await
parent
.
target
?.
cursorModel
.
updateCursorId
(
evt
);
}
else
if
(
name
==
'cursor_position'
)
{
parent
.
target
?.
cursorModel
.
updateCursorPosition
(
evt
,
peerId
);
await
parent
.
target
?.
cursorModel
.
updateCursorPosition
(
evt
,
peerId
);
}
else
if
(
name
==
'clipboard'
)
{
Clipboard
.
setData
(
ClipboardData
(
text:
evt
[
'content'
]));
}
else
if
(
name
==
'permission'
)
{
...
...
@@ -358,11 +358,11 @@ class ImageModel with ChangeNotifier {
});
}
void
update
(
ui
.
Image
?
image
,
double
tabBarHeight
)
{
void
update
(
ui
.
Image
?
image
,
double
tabBarHeight
)
async
{
if
(
_image
==
null
&&
image
!=
null
)
{
if
(
isWebDesktop
||
isDesktop
)
{
parent
.
target
?.
canvasModel
.
updateViewStyle
();
parent
.
target
?.
canvasModel
.
updateScrollStyle
();
await
parent
.
target
?.
canvasModel
.
updateViewStyle
();
await
parent
.
target
?.
canvasModel
.
updateScrollStyle
();
}
else
{
final
size
=
MediaQueryData
.
fromWindow
(
ui
.
window
).
size
;
final
canvasWidth
=
size
.
width
;
...
...
@@ -372,14 +372,12 @@ class ImageModel with ChangeNotifier {
parent
.
target
?.
canvasModel
.
scale
=
min
(
xscale
,
yscale
);
}
if
(
parent
.
target
!=
null
)
{
initializeCursorAndCanvas
(
parent
.
target
!);
await
initializeCursorAndCanvas
(
parent
.
target
!);
}
if
(
parent
.
target
?.
ffiModel
.
isPeerAndroid
??
false
)
{
bind
.
sessionPeerOption
(
id:
_id
,
name:
'view-style'
,
value:
'adaptive'
);
parent
.
target
?.
canvasModel
.
updateViewStyle
();
}
Future
.
delayed
(
Duration
(
milliseconds:
1
),
()
{
if
(
parent
.
target
?.
ffiModel
.
isPeerAndroid
??
false
)
{
bind
.
sessionPeerOption
(
id:
_id
,
name:
'view-style'
,
value:
'shrink'
);
parent
.
target
?.
canvasModel
.
updateViewStyle
();
}
});
}
_image
=
image
;
if
(
image
!=
null
)
notifyListeners
();
...
...
@@ -445,7 +443,7 @@ class CanvasModel with ChangeNotifier {
double
get
scrollX
=>
_scrollX
;
double
get
scrollY
=>
_scrollY
;
void
updateViewStyle
()
async
{
updateViewStyle
()
async
{
final
style
=
await
bind
.
sessionGetOption
(
id:
id
,
arg:
'view-style'
);
if
(
style
==
null
)
{
return
;
...
...
@@ -457,7 +455,6 @@ class CanvasModel with ChangeNotifier {
final
s2
=
size
.
height
/
getDisplayHeight
();
_scale
=
s1
<
s2
?
s1
:
s2
;
}
_x
=
(
size
.
width
-
getDisplayWidth
()
*
_scale
)
/
2
;
_y
=
(
size
.
height
-
getDisplayHeight
()
*
_scale
)
/
2
;
notifyListeners
();
...
...
@@ -475,7 +472,7 @@ class CanvasModel with ChangeNotifier {
notifyListeners
();
}
void
update
(
double
x
,
double
y
,
double
scale
)
{
update
(
double
x
,
double
y
,
double
scale
)
{
_x
=
x
;
_y
=
y
;
_scale
=
scale
;
...
...
@@ -508,19 +505,9 @@ class CanvasModel with ChangeNotifier {
var
dxOffset
=
0
;
var
dyOffset
=
0
;
if
(
dw
>
size
.
width
)
{
final
X_debugNanOrInfinite
=
x
-
dw
*
(
x
/
size
.
width
)
-
_x
;
if
(
X_debugNanOrInfinite
.
isInfinite
||
X_debugNanOrInfinite
.
isNaN
)
{
debugPrint
(
'REMOVE ME ============================ X_debugNanOrInfinite
$x
,
$dw
,
$_scale
,
${size.width}
,
$_x
'
);
}
dxOffset
=
(
x
-
dw
*
(
x
/
size
.
width
)
-
_x
).
toInt
();
}
if
(
dh
>
size
.
height
)
{
final
Y_debugNanOrInfinite
=
y
-
dh
*
(
y
/
size
.
height
)
-
_y
;
if
(
Y_debugNanOrInfinite
.
isInfinite
||
Y_debugNanOrInfinite
.
isNaN
)
{
debugPrint
(
'REMOVE ME ============================ Y_debugNanOrInfinite
$y
,
$dh
,
$_scale
,
${size.height}
,
$_y
'
);
}
dyOffset
=
(
y
-
dh
*
(
y
/
size
.
height
)
-
_y
).
toInt
();
}
_x
+=
dxOffset
;
...
...
@@ -619,7 +606,7 @@ class CursorData {
int
_doubleToInt
(
double
v
)
=>
(
v
*
10
e6
).
round
().
toInt
();
String
key
(
double
scale
)
=>
'
${peerId}
_
${id}
_
${_doubleToInt(
hotx)}
_
${_doubleToInt(hoty)}
_
${_doubleToInt(
width * scale)}
_
${_doubleToInt(height * scale)}
'
;
'
${peerId}
_
${id}
_
${_doubleToInt(width * scale)}
_
${_doubleToInt(height * scale)}
'
;
}
class
CursorModel
with
ChangeNotifier
{
...
...
@@ -780,7 +767,7 @@ class CursorModel with ChangeNotifier {
notifyListeners
();
}
void
updateCursorData
(
Map
<
String
,
dynamic
>
evt
)
{
updateCursorData
(
Map
<
String
,
dynamic
>
evt
)
async
{
var
id
=
int
.
parse
(
evt
[
'id'
]);
_hotx
=
double
.
parse
(
evt
[
'hotx'
]);
_hoty
=
double
.
parse
(
evt
[
'hoty'
]);
...
...
@@ -789,34 +776,25 @@ class CursorModel with ChangeNotifier {
List
<
dynamic
>
colors
=
json
.
decode
(
evt
[
'colors'
]);
final
rgba
=
Uint8List
.
fromList
(
colors
.
map
((
s
)
=>
s
as
int
).
toList
());
var
pid
=
parent
.
target
?.
id
;
ui
.
decodeImageFromPixels
(
rgba
,
width
,
height
,
ui
.
PixelFormat
.
rgba8888
,
(
image
)
{
()
async
{
if
(
parent
.
target
?.
id
!=
pid
)
return
;
_image
=
image
;
_images
[
id
]
=
Tuple3
(
image
,
_hotx
,
_hoty
);
_updateCacheLinux
(
image
,
id
,
width
,
height
);
try
{
// my throw exception, because the listener maybe already dispose
notifyListeners
();
}
catch
(
e
)
{
debugPrint
(
'notify cursor:
$e
'
);
}
}();
});
final
image
=
await
img
.
decodeImageFromPixels
(
rgba
,
width
,
height
,
ui
.
PixelFormat
.
rgba8888
);
if
(
parent
.
target
?.
id
!=
pid
)
return
;
_image
=
image
;
_images
[
id
]
=
Tuple3
(
image
,
_hotx
,
_hoty
);
await
_updateCacheLinux
(
image
,
id
,
width
,
height
);
try
{
// my throw exception, because the listener maybe already dispose
notifyListeners
();
}
catch
(
e
)
{
debugPrint
(
'notify cursor:
$e
'
);
}
}
void
_updateCacheLinux
(
ui
.
Image
image
,
int
id
,
int
w
,
int
h
)
async
{
final
data
=
await
image
.
toByteData
(
format:
ImageByteFormat
.
png
);
late
Uint8List
?
dataLinux
;
if
(
data
!=
null
)
{
dataLinux
=
data
.
buffer
.
asUint8List
();
}
else
{
dataLinux
=
null
;
}
_updateCacheLinux
(
ui
.
Image
image
,
int
id
,
int
w
,
int
h
)
async
{
final
data
=
await
image
.
toByteData
(
format:
ui
.
ImageByteFormat
.
png
);
_cacheLinux
=
CursorData
(
peerId:
this
.
id
,
data:
data
Linux
,
data:
data
?.
buffer
.
asUint8List
()
,
id:
id
,
hotx:
_hotx
,
hoty:
_hoty
,
...
...
@@ -826,9 +804,10 @@ class CursorModel with ChangeNotifier {
_cacheMapLinux
[
id
]
=
_cacheLinux
!;
}
void
updateCursorId
(
Map
<
String
,
dynamic
>
evt
)
{
_cacheLinux
=
_cacheMapLinux
[
int
.
parse
(
evt
[
'id'
])];
final
tmp
=
_images
[
int
.
parse
(
evt
[
'id'
])];
updateCursorId
(
Map
<
String
,
dynamic
>
evt
)
async
{
final
id
=
int
.
parse
(
evt
[
'id'
]);
_cacheLinux
=
_cacheMapLinux
[
id
];
final
tmp
=
_images
[
id
];
if
(
tmp
!=
null
)
{
_image
=
tmp
.
item1
;
_hotx
=
tmp
.
item2
;
...
...
@@ -838,7 +817,7 @@ class CursorModel with ChangeNotifier {
}
/// Update the cursor position.
void
updateCursorPosition
(
Map
<
String
,
dynamic
>
evt
,
String
id
)
{
updateCursorPosition
(
Map
<
String
,
dynamic
>
evt
,
String
id
)
async
{
_x
=
double
.
parse
(
evt
[
'x'
]);
_y
=
double
.
parse
(
evt
[
'y'
]);
try
{
...
...
@@ -1135,9 +1114,9 @@ class FFI {
if
(
message
is
Event
)
{
try
{
Map
<
String
,
dynamic
>
event
=
json
.
decode
(
message
.
field0
);
cb
(
event
);
await
cb
(
event
);
}
catch
(
e
)
{
p
rint
(
'json.decode fail():
$e
'
);
debugP
rint
(
'json.decode fail():
$e
'
);
}
}
else
if
(
message
is
Rgba
)
{
imageModel
.
onRgba
(
message
.
field0
,
tabBarHeight
);
...
...
@@ -1299,6 +1278,15 @@ class Display {
double
y
=
0
;
int
width
=
0
;
int
height
=
0
;
Display
()
{
width
=
(
isDesktop
||
isWebDesktop
)
?
kDesktopDefaultDisplayWidth
:
kMobileDefaultDisplayWidth
;
height
=
(
isDesktop
||
isWebDesktop
)
?
kDesktopDefaultDisplayHeight
:
kMobileDefaultDisplayHeight
;
}
}
class
PeerInfo
{
...
...
@@ -1311,8 +1299,8 @@ class PeerInfo {
List
<
Display
>
displays
=
[];
}
Future
<
void
>
savePreference
(
String
id
,
double
xCursor
,
double
yCursor
,
double
xCanvas
,
double
yCanvas
,
double
scale
,
int
currentDisplay
)
async
{
savePreference
(
String
id
,
double
xCursor
,
double
yCursor
,
double
xCanvas
,
double
yCanvas
,
double
scale
,
int
currentDisplay
)
async
{
SharedPreferences
prefs
=
await
SharedPreferences
.
getInstance
();
final
p
=
<
String
,
dynamic
>{};
p
[
'xCursor'
]
=
xCursor
;
...
...
@@ -1333,12 +1321,12 @@ Future<Map<String, dynamic>?> getPreference(String id) async {
return
m
;
}
void
removePreference
(
String
id
)
async
{
removePreference
(
String
id
)
async
{
SharedPreferences
prefs
=
await
SharedPreferences
.
getInstance
();
prefs
.
remove
(
'peer
$id
'
);
}
void
initializeCursorAndCanvas
(
FFI
ffi
)
async
{
initializeCursorAndCanvas
(
FFI
ffi
)
async
{
var
p
=
await
getPreference
(
ffi
.
id
);
int
currentDisplay
=
0
;
if
(
p
!=
null
)
{
...
...
flutter/lib/models/native_model.dart
View file @
a0c46c90
...
...
@@ -22,7 +22,7 @@ class RgbaFrame extends Struct {
typedef
F2
=
Pointer
<
Utf8
>
Function
(
Pointer
<
Utf8
>,
Pointer
<
Utf8
>);
typedef
F3
=
void
Function
(
Pointer
<
Utf8
>,
Pointer
<
Utf8
>);
typedef
HandleEvent
=
void
Function
(
Map
<
String
,
dynamic
>
evt
);
typedef
HandleEvent
=
Future
<
void
>
Function
(
Map
<
String
,
dynamic
>
evt
);
/// FFI wrapper around the native Rust core.
/// Hides the platform differences.
...
...
@@ -30,15 +30,15 @@ class PlatformFFI {
String
_dir
=
''
;
String
_homeDir
=
''
;
F2
?
_translate
;
final
_eventHandlers
=
Map
<
String
,
Map
<
String
,
HandleEvent
>>()
;
final
_eventHandlers
=
<
String
,
Map
<
String
,
HandleEvent
>>{}
;
late
RustdeskImpl
_ffiBind
;
late
String
_appType
;
void
Function
(
Map
<
String
,
dynamic
>)
?
_eventCallback
;
StreamEventHandler
?
_eventCallback
;
PlatformFFI
.
_
();
static
final
PlatformFFI
instance
=
PlatformFFI
.
_
();
final
_toAndroidChannel
=
MethodChannel
(
"mChannel"
);
final
_toAndroidChannel
=
const
MethodChannel
(
"mChannel"
);
RustdeskImpl
get
ffiBind
=>
_ffiBind
;
...
...
@@ -88,7 +88,7 @@ class PlatformFFI {
}
/// Init the FFI class, loads the native Rust core library.
Future
<
Null
>
init
(
String
appType
)
async
{
Future
<
void
>
init
(
String
appType
)
async
{
_appType
=
appType
;
// if (isDesktop) {
// // TODO
...
...
@@ -117,7 +117,7 @@ class PlatformFFI {
_homeDir
=
(
await
getDownloadsDirectory
())?.
path
??
""
;
}
}
catch
(
e
)
{
print
(
"initialize failed:
$e
"
);
debugPrint
(
'initialize failed:
$e
'
);
}
String
id
=
'NA'
;
String
name
=
'Flutter'
;
...
...
@@ -144,27 +144,27 @@ class PlatformFFI {
name
=
macOsInfo
.
computerName
;
id
=
macOsInfo
.
systemGUID
??
""
;
}
p
rint
(
"_appType:
$_appType
,info1-id:
$id
,info2-name:
$name
,dir:
$_dir
,homeDir:
$_homeDir
"
);
debugP
rint
(
'_appType:
$_appType
,info1-id:
$id
,info2-name:
$name
,dir:
$_dir
,homeDir:
$_homeDir
'
);
await
_ffiBind
.
mainDeviceId
(
id:
id
);
await
_ffiBind
.
mainDeviceName
(
name:
name
);
await
_ffiBind
.
mainSetHomeDir
(
home:
_homeDir
);
await
_ffiBind
.
mainInit
(
appDir:
_dir
);
}
catch
(
e
)
{
print
(
"initialize failed:
$e
"
);
debugPrint
(
'initialize failed:
$e
'
);
}
version
=
await
getVersion
();
}
bool
_tryHandle
(
Map
<
String
,
dynamic
>
evt
)
{
Future
<
bool
>
_tryHandle
(
Map
<
String
,
dynamic
>
evt
)
async
{
final
name
=
evt
[
'name'
];
if
(
name
!=
null
)
{
final
handlers
=
_eventHandlers
[
name
];
if
(
handlers
!=
null
)
{
if
(
handlers
.
isNotEmpty
)
{
handlers
.
values
.
forEach
((
handler
)
{
handler
(
evt
);
}
);
for
(
var
handler
in
handlers
.
values
)
{
await
handler
(
evt
);
}
return
true
;
}
}
...
...
@@ -180,19 +180,19 @@ class PlatformFFI {
try
{
Map
<
String
,
dynamic
>
event
=
json
.
decode
(
message
);
// _tryHandle here may be more flexible than _eventCallback
if
(!
_tryHandle
(
event
))
{
if
(!
await
_tryHandle
(
event
))
{
if
(
_eventCallback
!=
null
)
{
_eventCallback
!(
event
);
await
_eventCallback
!(
event
);
}
}
}
catch
(
e
)
{
p
rint
(
'json.decode fail():
$e
'
);
debugP
rint
(
'json.decode fail():
$e
'
);
}
}
}();
}
void
setEventCallback
(
void
Function
(
Map
<
String
,
dynamic
>)
fun
)
async
{
void
setEventCallback
(
StreamEventHandler
fun
)
async
{
_eventCallback
=
fun
;
}
...
...
flutter/lib/models/peer_model.dart
View file @
a0c46c90
...
...
@@ -40,10 +40,10 @@ class Peers extends ChangeNotifier {
static
const
_cbQueryOnlines
=
'callback_query_onlines'
;
Peers
({
required
this
.
name
,
required
this
.
peers
,
required
this
.
loadEvent
})
{
platformFFI
.
registerEventHandler
(
_cbQueryOnlines
,
name
,
(
evt
)
{
platformFFI
.
registerEventHandler
(
_cbQueryOnlines
,
name
,
(
evt
)
async
{
_updateOnlineState
(
evt
);
});
platformFFI
.
registerEventHandler
(
loadEvent
,
name
,
(
evt
)
{
platformFFI
.
registerEventHandler
(
loadEvent
,
name
,
(
evt
)
async
{
_updatePeers
(
evt
);
});
}
...
...
flutter/lib/utils/image.dart
0 → 100644
View file @
a0c46c90
import
'dart:typed_data'
;
import
'dart:ui'
as
ui
;
Future
<
ui
.
Image
>
decodeImageFromPixels
(
Uint8List
pixels
,
int
width
,
int
height
,
ui
.
PixelFormat
format
,
{
int
?
rowBytes
,
int
?
targetWidth
,
int
?
targetHeight
,
bool
allowUpscaling
=
true
,
})
async
{
if
(
targetWidth
!=
null
)
{
assert
(
allowUpscaling
||
targetWidth
<=
width
);
}
if
(
targetHeight
!=
null
)
{
assert
(
allowUpscaling
||
targetHeight
<=
height
);
}
final
ui
.
ImmutableBuffer
buffer
=
await
ui
.
ImmutableBuffer
.
fromUint8List
(
pixels
);
final
ui
.
ImageDescriptor
descriptor
=
ui
.
ImageDescriptor
.
raw
(
buffer
,
width:
width
,
height:
height
,
rowBytes:
rowBytes
,
pixelFormat:
format
,
);
if
(!
allowUpscaling
)
{
if
(
targetWidth
!=
null
&&
targetWidth
>
descriptor
.
width
)
{
targetWidth
=
descriptor
.
width
;
}
if
(
targetHeight
!=
null
&&
targetHeight
>
descriptor
.
height
)
{
targetHeight
=
descriptor
.
height
;
}
}
final
ui
.
Codec
codec
=
await
descriptor
.
instantiateCodec
(
targetWidth:
targetWidth
,
targetHeight:
targetHeight
,
);
final
ui
.
FrameInfo
frameInfo
=
await
codec
.
getNextFrame
();
codec
.
dispose
();
buffer
.
dispose
();
descriptor
.
dispose
();
return
frameInfo
.
image
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment