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
b734e8ae
Commit
b734e8ae
authored
Mar 12, 2022
by
fufesou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add virtual display
Signed-off-by:
fufesou
<
shuanglongchen@yeah.net
>
parent
e6bf858a
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
153 additions
and
13 deletions
+153
-13
Cargo.lock
Cargo.lock
+1
-0
lib.rs
libs/hbb_common/src/lib.rs
+2
-1
Cargo.toml
libs/virtual_display/Cargo.toml
+1
-0
idd_controller.rs
libs/virtual_display/examples/idd_controller.rs
+9
-8
lib.rs
libs/virtual_display/src/lib.rs
+101
-0
IddController.c
libs/virtual_display/src/win10/IddController.c
+2
-1
IddController.h
libs/virtual_display/src/win10/IddController.h
+4
-1
Public.h
libs/virtual_display/src/win10/Public.h
+4
-0
idd.rs
libs/virtual_display/src/win10/idd.rs
+1
-1
mod.rs
libs/virtual_display/src/win10/mod.rs
+4
-1
video_service.rs
src/server/video_service.rs
+7
-0
ui.rs
src/ui.rs
+14
-0
index.tis
src/ui/index.tis
+3
-0
No files found.
Cargo.lock
View file @
b734e8ae
...
...
@@ -4186,6 +4186,7 @@ name = "virtual_display"
version = "0.1.0"
dependencies = [
"cc",
"hbb_common",
"lazy_static",
"serde 1.0.136",
"serde_derive",
...
...
libs/hbb_common/src/lib.rs
View file @
b734e8ae
...
...
@@ -27,13 +27,14 @@ pub use anyhow::{self, bail};
pub
use
futures_util
;
pub
mod
config
;
pub
mod
fs
;
pub
use
lazy_static
;
pub
use
mac_address
;
pub
use
rand
;
pub
use
regex
;
pub
use
sodiumoxide
;
pub
use
tokio_socks
;
pub
use
tokio_socks
::
IntoTargetAddr
;
pub
use
tokio_socks
::
TargetAddr
;
pub
use
mac_address
;
#[cfg(feature
=
"quic"
)]
pub
type
Stream
=
quic
::
Connection
;
...
...
libs/virtual_display/Cargo.toml
View file @
b734e8ae
...
...
@@ -13,3 +13,4 @@ thiserror = "1.0.30"
lazy_static
=
"1.4"
serde
=
"1.0"
serde_derive
=
"1.0"
hbb_common
=
{
path
=
"../hbb_common"
}
\ No newline at end of file
libs/virtual_display/examples/idd_controller.rs
View file @
b734e8ae
#
[
cfg
(
windows
)]
use
virtual_display
::
win10
::
idd
;
use
virtual_display
::
win10
::
{
idd
,
DRIVER_INSTALL_PATH
}
;
use
std
::{
ffi
::{
CStr
,
CString
},
...
...
@@ -24,9 +24,9 @@ fn prompt_input() -> u8 {
.unwrap_or
(
0
)
}
unsafe
fn
plug_in
(
index
:
idd
::
UINT
)
{
unsafe
fn
plug_in
(
index
:
idd
::
UINT
,
edid
:
idd
::
UINT
)
{
println!
(
"Plug in monitor begin"
);
if
idd
::
FALSE
==
idd
::
MonitorPlugIn
(
index
,
25
)
{
if
idd
::
FALSE
==
idd
::
MonitorPlugIn
(
index
,
edid
,
25
)
{
println!
(
"{}"
,
CStr
::
from_ptr
(
idd
::
GetLastMsg
())
.to_str
()
.unwrap
());
}
else
{
println!
(
"Plug in monitor done"
);
...
...
@@ -58,8 +58,7 @@ unsafe fn plug_out(index: idd::UINT) {
}
fn
main
()
{
let
relative_path
=
"RustDeskIddDriver/RustDeskIddDriver.inf"
;
let
abs_path
=
Path
::
new
(
relative_path
)
.canonicalize
()
.unwrap
();
let
abs_path
=
Path
::
new
(
DRIVER_INSTALL_PATH
)
.canonicalize
()
.unwrap
();
let
full_inf_path
=
abs_path
.to_str
()
.unwrap
();
unsafe
{
...
...
@@ -121,9 +120,9 @@ fn main() {
h_sw_device
=
invalid_device
;
println!
(
"Close device done"
);
}
'1'
=>
plug_in
(
0
),
'2'
=>
plug_in
(
1
),
'3'
=>
plug_in
(
2
),
'1'
=>
plug_in
(
0
,
0
),
'2'
=>
plug_in
(
1
,
0
),
'3'
=>
plug_in
(
2
,
0
),
'4'
=>
plug_out
(
0
),
'5'
=>
plug_out
(
1
),
'6'
=>
plug_out
(
2
),
...
...
@@ -133,5 +132,7 @@ fn main() {
if
!
full_inf_path
.is_null
()
{
let
_
=
CString
::
from_raw
(
full_inf_path
);
}
idd
::
DeviceClose
(
h_sw_device
);
}
}
libs/virtual_display/src/lib.rs
View file @
b734e8ae
#
[
cfg
(
windows
)]
pub
mod
win10
;
use
hbb_common
::{
bail
,
lazy_static
,
ResultType
};
use
std
::{
ffi
::{
CStr
,
CString
},
path
::
Path
,
sync
::
Mutex
,
};
lazy_static
::
lazy_static!
{
#[cfg(windows)]
static
ref
H_SW_DEVICE
:
Mutex
<
u64
>
=
Mutex
::
new
(
0
);
}
pub
fn
download_driver
()
->
ResultType
<
()
>
{
#[cfg(windows)]
let
_download_url
=
win10
::
DRIVER_DOWNLOAD_URL
;
#[cfg(target_os
=
"linux"
)]
let
_download_url
=
""
;
// process download and report progress
Ok
(())
}
pub
fn
install_update_driver
()
->
ResultType
<
()
>
{
#[cfg(windows)]
let
install_path
=
win10
::
DRIVER_INSTALL_PATH
;
#[cfg(not(windows))]
let
install_path
=
""
;
let
abs_path
=
Path
::
new
(
install_path
)
.canonicalize
()
?
;
if
!
abs_path
.exists
()
{
bail!
(
"{} not exists"
,
install_path
)
}
let
full_install_path
=
match
abs_path
.to_str
()
{
Some
(
p
)
=>
CString
::
new
(
p
)
?
.into_raw
(),
None
=>
bail!
(
"{} not exists"
,
install_path
),
};
unsafe
{
#[cfg(windows)]
{
let
mut
reboot_required
=
win10
::
idd
::
FALSE
;
if
win10
::
idd
::
InstallUpdate
(
full_install_path
,
&
mut
reboot_required
)
==
win10
::
idd
::
FALSE
{
bail!
(
"{}"
,
CStr
::
from_ptr
(
win10
::
idd
::
GetLastMsg
())
.to_str
()
?
);
}
}
}
Ok
(())
}
pub
fn
is_device_created
()
->
bool
{
#[cfg(windows)]
return
*
H_SW_DEVICE
.lock
()
.unwrap
()
!=
0
;
#[cfg(not(windows))]
return
false
;
}
#[cfg(windows)]
pub
fn
create_device
()
->
ResultType
<
()
>
{
unsafe
{
let
mut
h_sw_device
=
*
H_SW_DEVICE
.lock
()
.unwrap
()
as
win10
::
idd
::
HSWDEVICE
;
if
win10
::
idd
::
DeviceCreate
(
&
mut
h_sw_device
)
==
win10
::
idd
::
FALSE
{
bail!
(
"{}"
,
CStr
::
from_ptr
(
win10
::
idd
::
GetLastMsg
())
.to_str
()
?
);
}
else
{
*
H_SW_DEVICE
.lock
()
.unwrap
()
=
h_sw_device
as
u64
;
Ok
(())
}
}
}
#[cfg(windows)]
pub
fn
close_device
()
{
unsafe
{
win10
::
idd
::
DeviceClose
(
*
H_SW_DEVICE
.lock
()
.unwrap
()
as
win10
::
idd
::
HSWDEVICE
);
}
}
#[cfg(windows)]
pub
fn
plug_in_monitor
()
->
ResultType
<
()
>
{
unsafe
{
if
win10
::
idd
::
MonitorPlugIn
(
0
,
0
,
30
)
==
win10
::
idd
::
FALSE
{
bail!
(
"{}"
,
CStr
::
from_ptr
(
win10
::
idd
::
GetLastMsg
())
.to_str
()
?
);
}
Ok
(())
}
}
#[cfg(windows)]
pub
fn
plug_out_monitor
()
->
ResultType
<
()
>
{
unsafe
{
if
win10
::
idd
::
MonitorPlugOut
(
0
)
==
win10
::
idd
::
FALSE
{
bail!
(
"{}"
,
CStr
::
from_ptr
(
win10
::
idd
::
GetLastMsg
())
.to_str
()
?
);
}
Ok
(())
}
}
libs/virtual_display/src/win10/IddController.c
View file @
b734e8ae
...
...
@@ -282,7 +282,7 @@ VOID DeviceClose(HSWDEVICE hSwDevice)
}
}
BOOL
MonitorPlugIn
(
UINT
index
,
INT
retries
)
BOOL
MonitorPlugIn
(
UINT
index
,
UINT
edid
,
INT
retries
)
{
SetLastMsg
(
"Sucess"
);
...
...
@@ -315,6 +315,7 @@ BOOL MonitorPlugIn(UINT index, INT retries)
DWORD
junk
=
0
;
CtlPlugIn
plugIn
;
plugIn
.
ConnectorIndex
=
index
;
plugIn
.
MonitorEDID
=
edid
;
HRESULT
hr
=
CoCreateGuid
(
&
plugIn
.
ContainerId
);
if
(
!
SUCCEEDED
(
hr
))
{
...
...
libs/virtual_display/src/win10/IddController.h
View file @
b734e8ae
...
...
@@ -70,6 +70,9 @@ VOID DeviceClose(HSWDEVICE hSwDevice);
* @brief Plug in monitor.
*
* @param index [in] Monitor index, should be 0, 1, 2.
* @param edid [in] Monitor edid.
* 0 Modified EDID from Dell S2719DGF
* 1 Modified EDID from Lenovo Y27fA
* @param retries [in] Retry times. Retry 1 time / sec. 25~30 seconds may be good choices.
* -1 is invalid.
* 0 means doing once and no retries.
...
...
@@ -83,7 +86,7 @@ VOID DeviceClose(HSWDEVICE hSwDevice);
* System need some time to prepare the device.
*
*/
BOOL
MonitorPlugIn
(
UINT
index
,
INT
retries
);
BOOL
MonitorPlugIn
(
UINT
index
,
UINT
edid
,
INT
retries
);
/**
* @brief Plug out monitor.
...
...
libs/virtual_display/src/win10/Public.h
View file @
b734e8ae
...
...
@@ -26,8 +26,12 @@
#define STATUS_ERROR_MONITOR_INVALID_PARAM (3 << 30) + 53
#define STATUS_ERROR_MONITOR_OOM (3 << 30) + 54
#define MONITOR_EDID_MOD_DELL_S2719DGF 0
#define MONITOR_EDID_MOD_LENOVO_Y27fA 1
typedef
struct
_CtlPlugIn
{
UINT
ConnectorIndex
;
UINT
MonitorEDID
;
GUID
ContainerId
;
}
CtlPlugIn
,
*
PCtlPlugIn
;
...
...
libs/virtual_display/src/win10/idd.rs
View file @
b734e8ae
...
...
@@ -206,7 +206,7 @@ extern "C" {
extern
"C"
{
pub
fn
Uninstall
(
fullInfPath
:
LPCTSTR
,
rebootRequired
:
PBOOL
)
->
BOOL
;
pub
fn
MonitorPlugIn
(
index
:
UINT
,
retries
:
INT
)
->
BOOL
;
pub
fn
MonitorPlugIn
(
index
:
UINT
,
edid
:
UINT
,
retries
:
INT
)
->
BOOL
;
pub
fn
MonitorPlugOut
(
index
:
UINT
)
->
BOOL
;
pub
fn
MonitorModesUpdate
(
index
:
UINT
,
modeCount
:
UINT
,
modes
:
PMonitorMode
)
->
BOOL
;
...
...
libs/virtual_display/src/win10/mod.rs
View file @
b734e8ae
pub
mod
idd
;
\ No newline at end of file
pub
mod
idd
;
pub
const
DRIVER_INSTALL_PATH
:
&
str
=
"RustDeskIddDriver/RustDeskIddDriver.inf"
;
pub
const
DRIVER_DOWNLOAD_URL
:
&
str
=
""
;
src/server/video_service.rs
View file @
b734e8ae
...
...
@@ -32,6 +32,7 @@ use std::{
io
::
ErrorKind
::
WouldBlock
,
time
::{
self
,
Duration
,
Instant
},
};
use
virtual_display
;
const
WAIT_BASE
:
i32
=
17
;
pub
const
NAME
:
&
'static
str
=
"video"
;
...
...
@@ -446,6 +447,12 @@ fn get_current_display() -> ResultType<(usize, usize, Display)> {
let
mut
current
=
*
CURRENT_DISPLAY
.lock
()
.unwrap
()
as
usize
;
let
mut
displays
=
Display
::
all
()
?
;
if
displays
.len
()
==
0
{
// try plugin monitor
if
virtual_display
::
is_device_created
()
{
if
let
Err
(
e
)
=
virtual_display
::
plug_in_monitor
()
{
log
::
error!
(
"plug in monitor failed {}"
,
e
)
}
}
bail!
(
"No displays"
);
}
let
n
=
displays
.len
();
...
...
src/ui.rs
View file @
b734e8ae
...
...
@@ -19,6 +19,7 @@ use std::{
process
::
Child
,
sync
::{
Arc
,
Mutex
},
};
use
virtual_display
;
pub
type
Childs
=
Arc
<
Mutex
<
(
bool
,
HashMap
<
(
String
,
String
),
Child
>
)
>>
;
...
...
@@ -364,6 +365,18 @@ impl UI {
}
}
// TODO: ui prompt
fn
install_virtual_display
(
&
self
)
{
match
virtual_display
::
install_update_driver
()
{
Ok
(
_
)
=>
{
log
::
info!
(
"Virtual Display: install virtual display done"
);
}
Err
(
e
)
=>
{
log
::
error!
(
"Virtual Display: install virtual display failed {}"
,
e
);
}
}
}
fn
install_path
(
&
mut
self
)
->
String
{
#[cfg(windows)]
return
crate
::
platform
::
windows
::
get_install_info
()
.
1
;
...
...
@@ -690,6 +703,7 @@ impl sciter::EventHandler for UI {
fn
get_sound_inputs
();
fn
set_options
(
Value
);
fn
set_option
(
String
,
String
);
fn
install_virtual_display
();
fn
get_software_update_url
();
fn
get_new_version
();
fn
get_version
();
...
...
src/ui/index.tis
View file @
b734e8ae
...
...
@@ -168,6 +168,7 @@ class MyIdMenu: Reactor.Component {
<li #custom-server>{translate('ID/Relay Server')}</li>
<li #whitelist title={translate('whitelist_tip')}>{translate('IP Whitelisting')}</li>
<li #socks5-server>{translate('Socks5 Proxy')}</li>
{is_win ? <li #install-virtual-display>Install virtual display</li> : ""}
<div .separator />
<li #stop-service class={service_stopped ? "line-through" : "selected"}><span>{svg_checkmark}</span>{translate("Enable Service")}</li>
<DirectServer />
...
...
@@ -268,6 +269,8 @@ class MyIdMenu: Reactor.Component {
}
handler.set_socks(proxy, username, password);
}, 240);
} else if (me.id == "install-virtual-display") {
handler.install_virtual_display();
} else if (me.id == "stop-service") {
handler.set_option("stop-service", service_stopped ? "" : "Y");
} else if (me.id == "about") {
...
...
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