mirror of
https://gitlab.com/marcandre.lureau/qemu-display.git
synced 2024-09-18 17:50:54 +00:00
Fix clone!() macro
This commit is contained in:
parent
15f63a920e
commit
56b38e54d7
@ -62,8 +62,10 @@ impl ClipboardHandler for InnerHandler {
|
|||||||
|
|
||||||
let p = p.clone();
|
let p = p.clone();
|
||||||
let mime = mime.to_string();
|
let mime = mime.to_string();
|
||||||
Some(Box::pin(
|
Some(Box::pin(clone!(
|
||||||
clone!(@strong stream => @default-return panic!(), async move {
|
#[strong]
|
||||||
|
stream,
|
||||||
|
async move {
|
||||||
match p.request(selection, &[&mime]).await {
|
match p.request(selection, &[&mime]).await {
|
||||||
Ok((_, data)) => {
|
Ok((_, data)) => {
|
||||||
let bytes = glib::Bytes::from(&data);
|
let bytes = glib::Bytes::from(&data);
|
||||||
@ -75,8 +77,8 @@ impl ClipboardHandler for InnerHandler {
|
|||||||
Err(glib::Error::new(gio::IOErrorEnum::Failed, &err))
|
Err(glib::Error::new(gio::IOErrorEnum::Failed, &err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}
|
||||||
))
|
)))
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Err(e) = clipboard.set_content(Some(&content)) {
|
if let Err(e) = clipboard.set_content(Some(&content)) {
|
||||||
|
@ -99,64 +99,122 @@ mod imp {
|
|||||||
|
|
||||||
self.obj().set_mouse_absolute(false);
|
self.obj().set_mouse_absolute(false);
|
||||||
|
|
||||||
self.obj().connect_key_event(
|
self.obj().connect_key_event(clone!(
|
||||||
clone!(@weak self as this => move |_, keyval, keycode, event| {
|
#[weak(rename_to = this)]
|
||||||
let mapped = this.keymap.get().and_then(|m| m.get(keycode as usize)).map(|x| *x as u32);
|
self,
|
||||||
|
move |_, keyval, keycode, event| {
|
||||||
|
let mapped = this
|
||||||
|
.keymap
|
||||||
|
.get()
|
||||||
|
.and_then(|m| m.get(keycode as usize))
|
||||||
|
.map(|x| *x as u32);
|
||||||
log::debug!("key-{event:?}: {keyval} {keycode} -> {mapped:?}");
|
log::debug!("key-{event:?}: {keyval} {keycode} -> {mapped:?}");
|
||||||
if let Some(qnum) = mapped {
|
if let Some(qnum) = mapped {
|
||||||
MainContext::default().spawn_local(clone!(@weak this => async move {
|
MainContext::default().spawn_local(clone!(
|
||||||
if event.contains(rdw::KeyEvent::PRESS) {
|
#[weak]
|
||||||
let _ = this.obj().console().keyboard.press(qnum).await;
|
this,
|
||||||
|
async move {
|
||||||
|
if event.contains(rdw::KeyEvent::PRESS) {
|
||||||
|
let _ = this.obj().console().keyboard.press(qnum).await;
|
||||||
|
}
|
||||||
|
if event.contains(rdw::KeyEvent::RELEASE) {
|
||||||
|
let _ = this.obj().console().keyboard.release(qnum).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if event.contains(rdw::KeyEvent::RELEASE) {
|
));
|
||||||
let _ = this.obj().console().keyboard.release(qnum).await;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}),
|
}
|
||||||
);
|
));
|
||||||
|
|
||||||
self.obj()
|
self.obj().connect_motion(clone!(
|
||||||
.connect_motion(clone!(@weak self as this => move |_, x, y| {
|
#[weak(rename_to = this)]
|
||||||
|
self,
|
||||||
|
move |_, x, y| {
|
||||||
log::trace!("motion: {:?}", (x, y));
|
log::trace!("motion: {:?}", (x, y));
|
||||||
MainContext::default().spawn_local(clone!(@weak this => async move {
|
MainContext::default().spawn_local(clone!(
|
||||||
if !this.obj().console().mouse.is_absolute().await.unwrap_or(false) {
|
#[weak]
|
||||||
return;
|
this,
|
||||||
|
async move {
|
||||||
|
if !this
|
||||||
|
.obj()
|
||||||
|
.console()
|
||||||
|
.mouse
|
||||||
|
.is_absolute()
|
||||||
|
.await
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if let Err(e) = this
|
||||||
|
.obj()
|
||||||
|
.console()
|
||||||
|
.mouse
|
||||||
|
.set_abs_position(x as _, y as _)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
log::warn!("{e}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let Err(e) = this.obj().console().mouse.set_abs_position(x as _, y as _).await {
|
));
|
||||||
log::warn!("{e}");
|
}
|
||||||
}
|
));
|
||||||
}));
|
|
||||||
}));
|
|
||||||
|
|
||||||
self.obj()
|
self.obj().connect_motion_relative(clone!(
|
||||||
.connect_motion_relative(clone!(@weak self as this => move |_, dx, dy| {
|
#[weak(rename_to = this)]
|
||||||
|
self,
|
||||||
|
move |_, dx, dy| {
|
||||||
log::trace!("motion-relative: {:?}", (dx, dy));
|
log::trace!("motion-relative: {:?}", (dx, dy));
|
||||||
MainContext::default().spawn_local(clone!(@weak this => async move {
|
MainContext::default().spawn_local(clone!(
|
||||||
let _ = this.obj().console().mouse.rel_motion(dx.round() as _, dy.round() as _).await;
|
#[weak]
|
||||||
}));
|
this,
|
||||||
}));
|
async move {
|
||||||
|
let _ = this
|
||||||
|
.obj()
|
||||||
|
.console()
|
||||||
|
.mouse
|
||||||
|
.rel_motion(dx.round() as _, dy.round() as _)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
self.obj()
|
self.obj().connect_mouse_press(clone!(
|
||||||
.connect_mouse_press(clone!(@weak self as this => move |_, button| {
|
#[weak(rename_to = this)]
|
||||||
|
self,
|
||||||
|
move |_, button| {
|
||||||
log::debug!("mouse-press: {:?}", button);
|
log::debug!("mouse-press: {:?}", button);
|
||||||
MainContext::default().spawn_local(clone!(@weak this => async move {
|
MainContext::default().spawn_local(clone!(
|
||||||
let button = from_gdk_button(button);
|
#[weak]
|
||||||
let _ = this.obj().console().mouse.press(button).await;
|
this,
|
||||||
}));
|
async move {
|
||||||
}));
|
let button = from_gdk_button(button);
|
||||||
|
let _ = this.obj().console().mouse.press(button).await;
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
self.obj()
|
self.obj().connect_mouse_release(clone!(
|
||||||
.connect_mouse_release(clone!(@weak self as this => move |_, button| {
|
#[weak(rename_to = this)]
|
||||||
|
self,
|
||||||
|
move |_, button| {
|
||||||
log::debug!("mouse-release: {:?}", button);
|
log::debug!("mouse-release: {:?}", button);
|
||||||
MainContext::default().spawn_local(clone!(@weak this => async move {
|
MainContext::default().spawn_local(clone!(
|
||||||
let button = from_gdk_button(button);
|
#[weak]
|
||||||
let _ = this.obj().console().mouse.release(button).await;
|
this,
|
||||||
}));
|
async move {
|
||||||
}));
|
let button = from_gdk_button(button);
|
||||||
|
let _ = this.obj().console().mouse.release(button).await;
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
self.obj()
|
self.obj().connect_scroll_discrete(clone!(
|
||||||
.connect_scroll_discrete(clone!(@weak self as this => move |_, scroll| {
|
#[weak(rename_to = this)]
|
||||||
|
self,
|
||||||
|
move |_, scroll| {
|
||||||
use qemu_display::MouseButton;
|
use qemu_display::MouseButton;
|
||||||
|
|
||||||
log::debug!("scroll-discrete: {:?}", scroll);
|
log::debug!("scroll-discrete: {:?}", scroll);
|
||||||
@ -169,18 +227,36 @@ mod imp {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
MainContext::default().spawn_local(clone!(@weak this => async move {
|
MainContext::default().spawn_local(clone!(
|
||||||
let _ = this.obj().console().mouse.press(button).await;
|
#[weak]
|
||||||
let _ = this.obj().console().mouse.release(button).await;
|
this,
|
||||||
}));
|
async move {
|
||||||
}));
|
let _ = this.obj().console().mouse.press(button).await;
|
||||||
|
let _ = this.obj().console().mouse.release(button).await;
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
self.obj().connect_resize_request(clone!(@weak self as this => move |_, width, height, wmm, hmm| {
|
self.obj().connect_resize_request(clone!(
|
||||||
log::debug!("resize-request: {:?}", (width, height, wmm, hmm));
|
#[weak(rename_to = this)]
|
||||||
MainContext::default().spawn_local(clone!(@weak this => async move {
|
self,
|
||||||
let _ = this.obj().console().proxy.set_ui_info(wmm as _, hmm as _, 0, 0, width, height).await;
|
move |_, width, height, wmm, hmm| {
|
||||||
}));
|
log::debug!("resize-request: {:?}", (width, height, wmm, hmm));
|
||||||
}));
|
MainContext::default().spawn_local(clone!(
|
||||||
|
#[weak]
|
||||||
|
this,
|
||||||
|
async move {
|
||||||
|
let _ = this
|
||||||
|
.obj()
|
||||||
|
.console()
|
||||||
|
.proxy
|
||||||
|
.set_ui_info(wmm as _, hmm as _, 0, 0, width, height)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,152 +266,216 @@ mod imp {
|
|||||||
|
|
||||||
self.keymap.set(rdw::keymap_qnum());
|
self.keymap.set(rdw::keymap_qnum());
|
||||||
|
|
||||||
MainContext::default().spawn_local(clone!(@weak self as this => async move {
|
MainContext::default().spawn_local(clone!(
|
||||||
let console = this.console.get().unwrap();
|
#[weak(rename_to = this)]
|
||||||
// we have to use a channel, because widget is not Send..
|
self,
|
||||||
let (sender, mut receiver) = futures::channel::mpsc::unbounded();
|
async move {
|
||||||
let handler = ConsoleHandler { sender };
|
let console = this.console.get().unwrap();
|
||||||
console.register_listener(handler.clone()).await.unwrap();
|
// we have to use a channel, because widget is not Send..
|
||||||
#[cfg(windows)]
|
let (sender, mut receiver) = futures::channel::mpsc::unbounded();
|
||||||
{
|
let handler = ConsoleHandler { sender };
|
||||||
console.set_map_listener(handler.clone()).await.unwrap();
|
console.register_listener(handler.clone()).await.unwrap();
|
||||||
console.set_d3d11_listener(handler.clone()).await.unwrap();
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
console.set_map_listener(handler.clone()).await.unwrap();
|
||||||
|
console.set_d3d11_listener(handler.clone()).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
MainContext::default().spawn_local(clone!(
|
||||||
|
#[weak]
|
||||||
|
this,
|
||||||
|
async move {
|
||||||
|
while let Some(e) = receiver.next().await {
|
||||||
|
use ConsoleEvent::*;
|
||||||
|
match e {
|
||||||
|
Scanout(s) => {
|
||||||
|
if s.format != 0x20020888 {
|
||||||
|
log::warn!("Format not yet supported: {:X}", s.format);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this.obj()
|
||||||
|
.set_display_size(Some((s.width as _, s.height as _)));
|
||||||
|
this.obj().update_area(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
s.width as _,
|
||||||
|
s.height as _,
|
||||||
|
s.stride as _,
|
||||||
|
Some(&s.data),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Update(u) => {
|
||||||
|
if u.format != 0x20020888 {
|
||||||
|
log::warn!("Format not yet supported: {:X}", u.format);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this.obj().update_area(
|
||||||
|
u.x as _,
|
||||||
|
u.y as _,
|
||||||
|
u.w as _,
|
||||||
|
u.h as _,
|
||||||
|
u.stride as _,
|
||||||
|
Some(&u.data),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[cfg(windows)]
|
||||||
|
ScanoutMap(s) => {
|
||||||
|
use windows::Win32::System::Memory::{
|
||||||
|
MapViewOfFile, FILE_MAP_READ,
|
||||||
|
};
|
||||||
|
|
||||||
|
log::debug!("{s:?}");
|
||||||
|
if s.format != 0x20020888 {
|
||||||
|
log::warn!("Format not yet supported: {:X}", s.format);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let handle = HANDLE(s.handle as _);
|
||||||
|
let size = s.height as usize * s.stride as usize;
|
||||||
|
let offset = s.offset as isize;
|
||||||
|
let ptr = unsafe {
|
||||||
|
MapViewOfFile(
|
||||||
|
handle,
|
||||||
|
FILE_MAP_READ,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
s.offset as usize + size,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
if ptr.is_null() {
|
||||||
|
log::warn!("Failed to map scanout!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let map = MemoryMap {
|
||||||
|
ptr,
|
||||||
|
handle,
|
||||||
|
offset,
|
||||||
|
size,
|
||||||
|
};
|
||||||
|
this.obj()
|
||||||
|
.set_display_size(Some((s.width as _, s.height as _)));
|
||||||
|
this.obj().update_area(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
s.width as _,
|
||||||
|
s.height as _,
|
||||||
|
s.stride as _,
|
||||||
|
Some(map.as_bytes()),
|
||||||
|
);
|
||||||
|
this.scanout_map.replace(Some((map, s.stride)));
|
||||||
|
}
|
||||||
|
#[cfg(windows)]
|
||||||
|
UpdateMap(u) => {
|
||||||
|
log::debug!("{u:?}");
|
||||||
|
let scanout_map = this.scanout_map.borrow();
|
||||||
|
let Some((map, stride)) = scanout_map.as_ref() else {
|
||||||
|
log::warn!("No mapped scanout!");
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let stride = *stride;
|
||||||
|
let bytes = map.as_bytes();
|
||||||
|
this.obj().update_area(
|
||||||
|
u.x as _,
|
||||||
|
u.y as _,
|
||||||
|
u.w as _,
|
||||||
|
u.h as _,
|
||||||
|
stride as _,
|
||||||
|
Some(
|
||||||
|
&bytes[u.y as usize * stride as usize
|
||||||
|
+ u.x as usize * 4..],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[cfg(windows)]
|
||||||
|
ScanoutD3dTexture2d(s) => {
|
||||||
|
log::debug!("{s:?}");
|
||||||
|
this.obj().set_display_size(Some((s.w as _, s.h as _)));
|
||||||
|
this.obj().set_d3d11_texture2d_scanout(Some(
|
||||||
|
rdw::RdwD3d11Texture2dScanout {
|
||||||
|
handle: s.handle as _,
|
||||||
|
tex_width: s.tex_width,
|
||||||
|
tex_height: s.tex_height,
|
||||||
|
y0_top: s.y0_top,
|
||||||
|
x: s.x,
|
||||||
|
y: s.y,
|
||||||
|
w: s.w,
|
||||||
|
h: s.h,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
#[cfg(windows)]
|
||||||
|
UpdateD3dTexture2d { wait_tx, update } => {
|
||||||
|
this.obj().set_d3d11_texture2d_can_acquire(true);
|
||||||
|
this.obj().update_area(
|
||||||
|
update.x, update.y, update.w, update.h, 0, None,
|
||||||
|
);
|
||||||
|
this.obj().set_d3d11_texture2d_can_acquire(false);
|
||||||
|
let _ = wait_tx.send(());
|
||||||
|
}
|
||||||
|
#[cfg(unix)]
|
||||||
|
ScanoutDMABUF(s) => {
|
||||||
|
log::trace!("{s:?}");
|
||||||
|
this.obj()
|
||||||
|
.set_display_size(Some((s.width as _, s.height as _)));
|
||||||
|
this.obj().set_dmabuf_scanout(rdw::RdwDmabufScanout {
|
||||||
|
width: s.width,
|
||||||
|
height: s.height,
|
||||||
|
stride: s.stride,
|
||||||
|
fourcc: s.fourcc,
|
||||||
|
y0_top: s.y0_top,
|
||||||
|
modifier: s.modifier,
|
||||||
|
fd: s.into_raw_fd(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[cfg(unix)]
|
||||||
|
UpdateDMABUF { wait_tx, update } => {
|
||||||
|
this.obj().update_area(
|
||||||
|
update.x, update.y, update.w, update.h, 0, None,
|
||||||
|
);
|
||||||
|
let _ = wait_tx.send(());
|
||||||
|
}
|
||||||
|
Disable => {
|
||||||
|
log::warn!("Display disabled");
|
||||||
|
}
|
||||||
|
Disconnected => {
|
||||||
|
log::warn!("Console disconnected");
|
||||||
|
}
|
||||||
|
CursorDefine(c) => {
|
||||||
|
log::debug!("{c:?}");
|
||||||
|
let cursor = rdw::Display::make_cursor(
|
||||||
|
&c.data, c.width, c.height, c.hot_x, c.hot_y, 1,
|
||||||
|
);
|
||||||
|
this.obj().define_cursor(Some(cursor));
|
||||||
|
}
|
||||||
|
MouseSet(m) => {
|
||||||
|
if m.on != 0 {
|
||||||
|
this.obj()
|
||||||
|
.set_cursor_position(Some((m.x as _, m.y as _)));
|
||||||
|
} else {
|
||||||
|
this.obj().set_cursor_position(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
let mut abs_changed = console.mouse.receive_is_absolute_changed().await;
|
||||||
|
this.obj()
|
||||||
|
.set_mouse_absolute(console.mouse.is_absolute().await.unwrap_or(false));
|
||||||
|
MainContext::default().spawn_local(clone!(
|
||||||
|
#[weak]
|
||||||
|
this,
|
||||||
|
async move {
|
||||||
|
while let Some(abs) = abs_changed.next().await {
|
||||||
|
if let Ok(abs) = abs.get().await {
|
||||||
|
this.obj().set_mouse_absolute(abs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
));
|
||||||
MainContext::default().spawn_local(clone!(@weak this => async move {
|
|
||||||
while let Some(e) = receiver.next().await {
|
|
||||||
use ConsoleEvent::*;
|
|
||||||
match e {
|
|
||||||
Scanout(s) => {
|
|
||||||
if s.format != 0x20020888 {
|
|
||||||
log::warn!("Format not yet supported: {:X}", s.format);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.obj().set_display_size(Some((s.width as _, s.height as _)));
|
|
||||||
this.obj().update_area(0, 0, s.width as _, s.height as _, s.stride as _, Some(&s.data));
|
|
||||||
}
|
|
||||||
Update(u) => {
|
|
||||||
if u.format != 0x20020888 {
|
|
||||||
log::warn!("Format not yet supported: {:X}", u.format);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.obj().update_area(u.x as _, u.y as _, u.w as _, u.h as _, u.stride as _, Some(&u.data));
|
|
||||||
}
|
|
||||||
#[cfg(windows)]
|
|
||||||
ScanoutMap(s) => {
|
|
||||||
use windows::Win32::System::Memory::{FILE_MAP_READ, MapViewOfFile};
|
|
||||||
|
|
||||||
log::debug!("{s:?}");
|
|
||||||
if s.format != 0x20020888 {
|
|
||||||
log::warn!("Format not yet supported: {:X}", s.format);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let handle = HANDLE(s.handle as _);
|
|
||||||
let size = s.height as usize * s.stride as usize;
|
|
||||||
let offset = s.offset as isize;
|
|
||||||
let ptr = unsafe { MapViewOfFile(handle, FILE_MAP_READ, 0, 0, s.offset as usize + size) };
|
|
||||||
if ptr.is_null() {
|
|
||||||
log::warn!("Failed to map scanout!");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let map = MemoryMap { ptr, handle, offset, size };
|
|
||||||
this.obj().set_display_size(Some((s.width as _, s.height as _)));
|
|
||||||
this.obj().update_area(0, 0, s.width as _, s.height as _, s.stride as _, Some(map.as_bytes()));
|
|
||||||
this.scanout_map.replace(Some((map, s.stride)));
|
|
||||||
}
|
|
||||||
#[cfg(windows)]
|
|
||||||
UpdateMap(u) => {
|
|
||||||
log::debug!("{u:?}");
|
|
||||||
let scanout_map = this.scanout_map.borrow();
|
|
||||||
let Some((map, stride)) = scanout_map.as_ref() else {
|
|
||||||
log::warn!("No mapped scanout!");
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
let stride = *stride;
|
|
||||||
let bytes = map.as_bytes();
|
|
||||||
this.obj().update_area(u.x as _, u.y as _, u.w as _, u.h as _, stride as _, Some(&bytes[u.y as usize * stride as usize + u.x as usize * 4..]));
|
|
||||||
}
|
|
||||||
#[cfg(windows)]
|
|
||||||
ScanoutD3dTexture2d(s) => {
|
|
||||||
log::debug!("{s:?}");
|
|
||||||
this.obj().set_display_size(Some((s.w as _, s.h as _)));
|
|
||||||
this.obj().set_d3d11_texture2d_scanout(Some(rdw::RdwD3d11Texture2dScanout {
|
|
||||||
handle: s.handle as _,
|
|
||||||
tex_width: s.tex_width,
|
|
||||||
tex_height: s.tex_height,
|
|
||||||
y0_top: s.y0_top,
|
|
||||||
x: s.x,
|
|
||||||
y: s.y,
|
|
||||||
w: s.w,
|
|
||||||
h: s.h,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
#[cfg(windows)]
|
|
||||||
UpdateD3dTexture2d { wait_tx, update } => {
|
|
||||||
this.obj().set_d3d11_texture2d_can_acquire(true);
|
|
||||||
this.obj().update_area(update.x, update.y, update.w, update.h, 0, None);
|
|
||||||
this.obj().set_d3d11_texture2d_can_acquire(false);
|
|
||||||
let _ = wait_tx.send(());
|
|
||||||
}
|
|
||||||
#[cfg(unix)]
|
|
||||||
ScanoutDMABUF(s) => {
|
|
||||||
log::trace!("{s:?}");
|
|
||||||
this.obj().set_display_size(Some((s.width as _, s.height as _)));
|
|
||||||
this.obj().set_dmabuf_scanout(rdw::RdwDmabufScanout {
|
|
||||||
width: s.width,
|
|
||||||
height: s.height,
|
|
||||||
stride: s.stride,
|
|
||||||
fourcc: s.fourcc,
|
|
||||||
y0_top: s.y0_top,
|
|
||||||
modifier: s.modifier,
|
|
||||||
fd: s.into_raw_fd(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
#[cfg(unix)]
|
|
||||||
UpdateDMABUF { wait_tx, update } => {
|
|
||||||
this.obj().update_area(update.x, update.y, update.w, update.h, 0, None);
|
|
||||||
let _ = wait_tx.send(());
|
|
||||||
}
|
|
||||||
Disable => {
|
|
||||||
log::warn!("Display disabled");
|
|
||||||
}
|
|
||||||
Disconnected => {
|
|
||||||
log::warn!("Console disconnected");
|
|
||||||
}
|
|
||||||
CursorDefine(c) => {
|
|
||||||
log::debug!("{c:?}");
|
|
||||||
let cursor = rdw::Display::make_cursor(
|
|
||||||
&c.data,
|
|
||||||
c.width,
|
|
||||||
c.height,
|
|
||||||
c.hot_x,
|
|
||||||
c.hot_y,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
this.obj().define_cursor(Some(cursor));
|
|
||||||
}
|
|
||||||
MouseSet(m) => {
|
|
||||||
if m.on != 0 {
|
|
||||||
this.obj().set_cursor_position(Some((m.x as _, m.y as _)));
|
|
||||||
} else {
|
|
||||||
this.obj().set_cursor_position(None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
let mut abs_changed = console.mouse.receive_is_absolute_changed().await;
|
|
||||||
this.obj().set_mouse_absolute(console.mouse.is_absolute().await.unwrap_or(false));
|
|
||||||
MainContext::default().spawn_local(clone!(@weak this => async move {
|
|
||||||
while let Some(abs) = abs_changed.next().await {
|
|
||||||
if let Ok(abs) = abs.get().await {
|
|
||||||
this.obj().set_mouse_absolute(abs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,16 +19,25 @@ impl Handler {
|
|||||||
let usbredir = self.usbredir.clone();
|
let usbredir = self.usbredir.clone();
|
||||||
widget
|
widget
|
||||||
.model()
|
.model()
|
||||||
.connect_items_changed(clone!(@weak widget => move |model, pos, _rm, add| {
|
.connect_items_changed(clone!(move |model, pos, _rm, add| {
|
||||||
let usbredir = usbredir.clone();
|
let usbredir = usbredir.clone();
|
||||||
MainContext::default().spawn_local(clone!(@weak model => async move {
|
MainContext::default().spawn_local(clone!(
|
||||||
for pos in pos..pos + add {
|
#[weak]
|
||||||
let item = model.item(pos).unwrap();
|
model,
|
||||||
if let Some(dev) = item.downcast_ref::<rdw::UsbDevice>().unwrap().device() {
|
async move {
|
||||||
item.set_property("active", usbredir.is_device_connected(&dev).await);
|
for pos in pos..pos + add {
|
||||||
|
let item = model.item(pos).unwrap();
|
||||||
|
if let Some(dev) =
|
||||||
|
item.downcast_ref::<rdw::UsbDevice>().unwrap().device()
|
||||||
|
{
|
||||||
|
item.set_property(
|
||||||
|
"active",
|
||||||
|
usbredir.is_device_connected(&dev).await,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let usbredir = self.usbredir.clone();
|
let usbredir = self.usbredir.clone();
|
||||||
@ -39,29 +48,38 @@ impl Handler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let usbredir = usbredir.clone();
|
let usbredir = usbredir.clone();
|
||||||
MainContext::default().spawn_local(clone!(@weak item, @weak widget => async move {
|
MainContext::default().spawn_local(clone!(
|
||||||
match usbredir.set_device_state(&device, state).await {
|
#[weak]
|
||||||
Ok(active) => item.set_property("active", active),
|
item,
|
||||||
Err(e) => {
|
#[weak]
|
||||||
if state {
|
widget,
|
||||||
item.set_property("active", false);
|
async move {
|
||||||
|
match usbredir.set_device_state(&device, state).await {
|
||||||
|
Ok(active) => item.set_property("active", active),
|
||||||
|
Err(e) => {
|
||||||
|
if state {
|
||||||
|
item.set_property("active", false);
|
||||||
|
}
|
||||||
|
widget.emit_by_name::<bool>("show-error", &[&e.to_string()]);
|
||||||
}
|
}
|
||||||
widget.emit_by_name::<bool>("show-error", &[&e.to_string()]);
|
}
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
let usbredir = self.usbredir.clone();
|
let usbredir = self.usbredir.clone();
|
||||||
MainContext::default().spawn_local(clone!(@weak widget => async move {
|
MainContext::default().spawn_local(clone!(
|
||||||
use futures::stream::StreamExt; // for `next`
|
#[weak]
|
||||||
widget
|
widget,
|
||||||
.set_property("free-channels", usbredir.n_free_channels().await);
|
async move {
|
||||||
let mut n = usbredir.receive_n_free_channels().await;
|
use futures::stream::StreamExt; // for `next`
|
||||||
while let Some(n) = n.next().await {
|
widget.set_property("free-channels", usbredir.n_free_channels().await);
|
||||||
widget.set_property("free-channels", n);
|
let mut n = usbredir.receive_n_free_channels().await;
|
||||||
|
while let Some(n) = n.next().await {
|
||||||
|
widget.set_property("free-channels", n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}));
|
));
|
||||||
|
|
||||||
widget
|
widget
|
||||||
}
|
}
|
||||||
|
@ -29,40 +29,46 @@ fn main() {
|
|||||||
window.set_child(Some(&term));
|
window.set_child(Some(&term));
|
||||||
|
|
||||||
let id = chardev_id.clone();
|
let id = chardev_id.clone();
|
||||||
MainContext::default().spawn_local(clone!(@strong window => async move {
|
MainContext::default().spawn_local(clone!(
|
||||||
let conn = Connection::session().await
|
#[strong]
|
||||||
.expect("Failed to connect to session D-Bus");
|
window,
|
||||||
|
async move {
|
||||||
|
let conn = Connection::session()
|
||||||
|
.await
|
||||||
|
.expect("Failed to connect to session D-Bus");
|
||||||
|
|
||||||
let c = Chardev::new(&conn, &id).await.unwrap();
|
let c = Chardev::new(&conn, &id).await.unwrap();
|
||||||
c.proxy.name().await.expect("Chardev not found");
|
c.proxy.name().await.expect("Chardev not found");
|
||||||
|
|
||||||
let (p0, p1) = UnixStream::pair().unwrap();
|
let (p0, p1) = UnixStream::pair().unwrap();
|
||||||
if c.proxy.register((&p1).into()).await.is_ok() {
|
if c.proxy.register((&p1).into()).await.is_ok() {
|
||||||
let ostream = unsafe { gio::UnixOutputStream::with_fd(p0.as_raw_fd()) };
|
let ostream = unsafe { gio::UnixOutputStream::with_fd(p0.as_raw_fd()) };
|
||||||
let istream = unsafe { gio::UnixInputStream::take_fd(p0) }
|
let istream = unsafe { gio::UnixInputStream::take_fd(p0) }
|
||||||
.dynamic_cast::<gio::PollableInputStream>()
|
.dynamic_cast::<gio::PollableInputStream>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut read = istream.into_async_read().unwrap();
|
let mut read = istream.into_async_read().unwrap();
|
||||||
term.connect_commit(move |_, text, _| {
|
term.connect_commit(move |_, text, _| {
|
||||||
let _res = ostream.write(text.as_bytes(), gio::Cancellable::NONE); // TODO cancellable and error
|
let _res = ostream.write(text.as_bytes(), gio::Cancellable::NONE);
|
||||||
});
|
// TODO cancellable and error
|
||||||
|
});
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut buffer = [0u8; 8192];
|
let mut buffer = [0u8; 8192];
|
||||||
match read.read(&mut buffer[..]).await {
|
match read.read(&mut buffer[..]).await {
|
||||||
Ok(0) => break,
|
Ok(0) => break,
|
||||||
Ok(len) => {
|
Ok(len) => {
|
||||||
term.feed(&buffer[..len]);
|
term.feed(&buffer[..len]);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("{}", e);
|
log::warn!("{}", e);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
));
|
||||||
|
|
||||||
window.show();
|
window.show();
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user