Skip to content

Commit

Permalink
Merge branch 'rustdesk:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangbo8418 authored Nov 8, 2024
2 parents 837a942 + 740c535 commit 95abf3a
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -280,20 +280,20 @@ class InputService : AccessibilityService() {

var textToCommit: String? = null

if (keyboardMode == KeyboardMode.Legacy) {
if (keyEvent.hasChr() && keyEvent.getDown()) {
// [down] indicates the key's state(down or up).
// [press] indicates a click event(down and up).
// https://github.com/rustdesk/rustdesk/blob/3a7594755341f023f56fa4b6a43b60d6b47df88d/flutter/lib/models/input_model.dart#L688
if (keyEvent.hasSeq()) {
textToCommit = keyEvent.getSeq()
} else if (keyboardMode == KeyboardMode.Legacy) {
if (keyEvent.hasChr() && (keyEvent.getDown() || keyEvent.getPress())) {
val chr = keyEvent.getChr()
if (chr != null) {
textToCommit = String(Character.toChars(chr))
}
}
} else if (keyboardMode == KeyboardMode.Translate) {
if (keyEvent.hasSeq() && keyEvent.getDown()) {
val seq = keyEvent.getSeq()
if (seq != null) {
textToCommit = seq
}
}
} else {
}

Log.d(logTag, "onKeyEvent $keyEvent textToCommit:$textToCommit")
Expand All @@ -320,6 +320,10 @@ class InputService : AccessibilityService() {
} else {
ke?.let { event ->
inputConnection.sendKeyEvent(event)
if (keyEvent.getPress()) {
val actionUpEvent = KeyEventAndroid(KeyEventAndroid.ACTION_UP, event.keyCode)
inputConnection.sendKeyEvent(actionUpEvent)
}
}
}
}
Expand All @@ -333,6 +337,10 @@ class InputService : AccessibilityService() {
for (item in possibleNodes) {
val success = trySendKeyEvent(event, item, textToCommit)
if (success) {
if (keyEvent.getPress()) {
val actionUpEvent = KeyEventAndroid(KeyEventAndroid.ACTION_UP, event.keyCode)
trySendKeyEvent(actionUpEvent, item, textToCommit)
}
break
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,12 @@ object KeyEventConverter {
}

var action = 0
if (keyEventProto.getDown()) {
if (keyEventProto.getDown() || keyEventProto.getPress()) {
action = KeyEvent.ACTION_DOWN
} else {
action = KeyEvent.ACTION_UP
}

// FIXME: The last parameter is the repeat count, not modifiers ?
// https://developer.android.com/reference/android/view/KeyEvent#KeyEvent(long,%20long,%20int,%20int,%20int)
return KeyEvent(0, 0, action, chrValue, 0, modifiers)
}

Expand Down
8 changes: 8 additions & 0 deletions flutter/lib/mobile/pages/remote_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,14 @@ class _RemotePageState extends State<RemotePage> with WidgetsBindingObserver {
controller: _textController,
// trick way to make backspace work always
keyboardType: TextInputType.multiline,
// `onChanged` may be called depending on the input method if this widget is wrapped in
// `Focus(onKeyEvent: ..., child: ...)`
// For `Backspace` button in the soft keyboard:
// en/fr input method:
// 1. The button will not trigger `onKeyEvent` if the text field is not empty.
// 2. The button will trigger `onKeyEvent` if the text field is empty.
// ko/zh/ja input method: the button will trigger `onKeyEvent`
// and the event will not popup if `KeyEventResult.handled` is returned.
onChanged: handleSoftKeyboardInput,
),
),
Expand Down
242 changes: 228 additions & 14 deletions libs/scrap/src/dxgi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ use winapi::{
shared::{
dxgi::*,
dxgi1_2::*,
dxgiformat::DXGI_FORMAT_B8G8R8A8_UNORM,
dxgitype::*,
minwindef::{DWORD, FALSE, TRUE, UINT},
ntdef::LONG,
windef::HMONITOR,
windef::{HMONITOR, RECT},
winerror::*,
// dxgiformat::{DXGI_FORMAT, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_420_OPAQUE},
},
Expand Down Expand Up @@ -57,6 +58,7 @@ pub struct Capturer {
saved_raw_data: Vec<u8>, // for faster compare and copy
output_texture: bool,
adapter_desc1: DXGI_ADAPTER_DESC1,
rotate: Rotate,
}

impl Capturer {
Expand Down Expand Up @@ -151,6 +153,7 @@ impl Capturer {
(*duplication).GetDesc(&mut desc);
}
}
let rotate = Self::create_rotations(device.0, context.0, &display);

Ok(Capturer {
device,
Expand All @@ -168,9 +171,143 @@ impl Capturer {
saved_raw_data: Vec::new(),
output_texture: false,
adapter_desc1,
rotate,
})
}

fn create_rotations(
device: *mut ID3D11Device,
context: *mut ID3D11DeviceContext,
display: &Display,
) -> Rotate {
let mut video_context: *mut ID3D11VideoContext = ptr::null_mut();
let mut video_device: *mut ID3D11VideoDevice = ptr::null_mut();
let mut video_processor_enum: *mut ID3D11VideoProcessorEnumerator = ptr::null_mut();
let mut video_processor: *mut ID3D11VideoProcessor = ptr::null_mut();
let processor_rotation = match display.rotation() {
DXGI_MODE_ROTATION_ROTATE90 => Some(D3D11_VIDEO_PROCESSOR_ROTATION_90),
DXGI_MODE_ROTATION_ROTATE180 => Some(D3D11_VIDEO_PROCESSOR_ROTATION_180),
DXGI_MODE_ROTATION_ROTATE270 => Some(D3D11_VIDEO_PROCESSOR_ROTATION_270),
_ => None,
};
if let Some(processor_rotation) = processor_rotation {
println!("create rotations");
if !device.is_null() && !context.is_null() {
unsafe {
(*context).QueryInterface(
&IID_ID3D11VideoContext,
&mut video_context as *mut *mut _ as *mut *mut _,
);
if !video_context.is_null() {
(*device).QueryInterface(
&IID_ID3D11VideoDevice,
&mut video_device as *mut *mut _ as *mut *mut _,
);
if !video_device.is_null() {
let (input_width, input_height) = match display.rotation() {
DXGI_MODE_ROTATION_ROTATE90 | DXGI_MODE_ROTATION_ROTATE270 => {
(display.height(), display.width())
}
_ => (display.width(), display.height()),
};
let (output_width, output_height) = (display.width(), display.height());
let content_desc = D3D11_VIDEO_PROCESSOR_CONTENT_DESC {
InputFrameFormat: D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE,
InputFrameRate: DXGI_RATIONAL {
Numerator: 30,
Denominator: 1,
},
InputWidth: input_width as _,
InputHeight: input_height as _,
OutputFrameRate: DXGI_RATIONAL {
Numerator: 30,
Denominator: 1,
},
OutputWidth: output_width as _,
OutputHeight: output_height as _,
Usage: D3D11_VIDEO_USAGE_PLAYBACK_NORMAL,
};
(*video_device).CreateVideoProcessorEnumerator(
&content_desc,
&mut video_processor_enum,
);
if !video_processor_enum.is_null() {
let mut caps: D3D11_VIDEO_PROCESSOR_CAPS = mem::zeroed();
if S_OK == (*video_processor_enum).GetVideoProcessorCaps(&mut caps)
{
if caps.FeatureCaps
& D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_ROTATION
!= 0
{
(*video_device).CreateVideoProcessor(
video_processor_enum,
0,
&mut video_processor,
);
if !video_processor.is_null() {
(*video_context).VideoProcessorSetStreamRotation(
video_processor,
0,
TRUE,
processor_rotation,
);
(*video_context)
.VideoProcessorSetStreamAutoProcessingMode(
video_processor,
0,
FALSE,
);
(*video_context).VideoProcessorSetStreamFrameFormat(
video_processor,
0,
D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE,
);
(*video_context).VideoProcessorSetStreamSourceRect(
video_processor,
0,
TRUE,
&RECT {
left: 0,
top: 0,
right: input_width as _,
bottom: input_height as _,
},
);
(*video_context).VideoProcessorSetStreamDestRect(
video_processor,
0,
TRUE,
&RECT {
left: 0,
top: 0,
right: output_width as _,
bottom: output_height as _,
},
);
}
}
}
}
}
}
}
}
}

let video_context = ComPtr(video_context);
let video_device = ComPtr(video_device);
let video_processor_enum = ComPtr(video_processor_enum);
let video_processor = ComPtr(video_processor);
let rotated_texture = ComPtr(ptr::null_mut());
Rotate {
video_context,
video_device,
video_processor_enum,
video_processor,
texture: (rotated_texture, false),
}
}

pub fn is_gdi(&self) -> bool {
self.gdi_capturer.is_some()
}
Expand Down Expand Up @@ -253,17 +390,7 @@ impl Capturer {

pub fn frame<'a>(&'a mut self, timeout: UINT) -> io::Result<Frame<'a>> {
if self.output_texture {
let rotation = match self.display.rotation() {
DXGI_MODE_ROTATION_IDENTITY | DXGI_MODE_ROTATION_UNSPECIFIED => 0,
DXGI_MODE_ROTATION_ROTATE90 => 90,
DXGI_MODE_ROTATION_ROTATE180 => 180,
DXGI_MODE_ROTATION_ROTATE270 => 270,
_ => {
// Unsupported rotation, try anyway
0
}
};
Ok(Frame::Texture((self.get_texture(timeout)?, rotation)))
Ok(Frame::Texture(self.get_texture(timeout)?))
} else {
let width = self.width;
let height = self.height;
Expand Down Expand Up @@ -338,7 +465,7 @@ impl Capturer {
}
}

fn get_texture(&mut self, timeout: UINT) -> io::Result<*mut c_void> {
fn get_texture(&mut self, timeout: UINT) -> io::Result<(*mut c_void, usize)> {
unsafe {
if self.duplication.0.is_null() {
return Err(std::io::ErrorKind::AddrNotAvailable.into());
Expand All @@ -362,7 +489,86 @@ impl Capturer {
);
let texture = ComPtr(texture);
self.texture = texture;
Ok(self.texture.0 as *mut c_void)

let mut final_texture = self.texture.0 as *mut c_void;
let mut rotation = match self.display.rotation() {
DXGI_MODE_ROTATION_ROTATE90 => 90,
DXGI_MODE_ROTATION_ROTATE180 => 180,
DXGI_MODE_ROTATION_ROTATE270 => 270,
_ => 0,
};
if rotation != 0
&& !self.texture.is_null()
&& !self.rotate.video_context.is_null()
&& !self.rotate.video_device.is_null()
&& !self.rotate.video_processor_enum.is_null()
&& !self.rotate.video_processor.is_null()
{
let mut desc: D3D11_TEXTURE2D_DESC = mem::zeroed();
(*self.texture.0).GetDesc(&mut desc);
if rotation == 90 || rotation == 270 {
let tmp = desc.Width;
desc.Width = desc.Height;
desc.Height = tmp;
}
if !self.rotate.texture.1 {
self.rotate.texture.1 = true;
let mut rotated_texture: *mut ID3D11Texture2D = ptr::null_mut();
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
(*self.device.0).CreateTexture2D(&desc, ptr::null(), &mut rotated_texture);
self.rotate.texture.0 = ComPtr(rotated_texture);
}
if !self.rotate.texture.0.is_null()
&& desc.Width == self.width as u32
&& desc.Height == self.height as u32
{
let input_view_desc = D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC {
FourCC: 0,
ViewDimension: D3D11_VPIV_DIMENSION_TEXTURE2D,
Texture2D: D3D11_TEX2D_VPIV {
ArraySlice: 0,
MipSlice: 0,
},
};
let mut input_view = ptr::null_mut();
(*self.rotate.video_device.0).CreateVideoProcessorInputView(
self.texture.0 as *mut _,
self.rotate.video_processor_enum.0 as *mut _,
&input_view_desc,
&mut input_view,
);
if !input_view.is_null() {
let input_view = ComPtr(input_view);
let mut output_view_desc: D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC =
mem::zeroed();
output_view_desc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D;
output_view_desc.u.Texture2D_mut().MipSlice = 0;
let mut output_view = ptr::null_mut();
(*self.rotate.video_device.0).CreateVideoProcessorOutputView(
self.rotate.texture.0 .0 as *mut _,
self.rotate.video_processor_enum.0 as *mut _,
&output_view_desc,
&mut output_view,
);
if !output_view.is_null() {
let output_view = ComPtr(output_view);
let mut stream_data: D3D11_VIDEO_PROCESSOR_STREAM = mem::zeroed();
stream_data.Enable = TRUE;
stream_data.pInputSurface = input_view.0;
(*self.rotate.video_context.0).VideoProcessorBlt(
self.rotate.video_processor.0,
output_view.0,
0,
1,
&stream_data,
);
final_texture = self.rotate.texture.0 .0 as *mut c_void;
rotation = 0;
}
}
}
}
Ok((final_texture, rotation))
}
}

Expand Down Expand Up @@ -666,3 +872,11 @@ fn wrap_hresult(x: HRESULT) -> io::Result<()> {
})
.into())
}

struct Rotate {
video_context: ComPtr<ID3D11VideoContext>,
video_device: ComPtr<ID3D11VideoDevice>,
video_processor_enum: ComPtr<ID3D11VideoProcessorEnumerator>,
video_processor: ComPtr<ID3D11VideoProcessor>,
texture: (ComPtr<ID3D11Texture2D>, bool),
}
Loading

0 comments on commit 95abf3a

Please sign in to comment.