EvanZhu0721 / 公开仓库
SBMS
SBMS complete the calculation rules for the default logical desktop topology relationship and the physical dimensions of the displays in the Windows multi-screen collaboration system.
文件
../ bininputuiconfig.rs81.2 KBcontrol.rs4.1 KBcontroller.rs43.6 KBdiagnostics.rs24.2 KBdisplay.rs29.8 KBgeometry.rs21.4 KBgpu_renderer.rs37.4 KBinput.rs79.7 KBlaunch_broker.rs10.3 KBlib.rs350 Blimits.rs714 Bmain.rs24.4 KBmapping.rs46.5 KBnetwork.rs9.2 KBrenderer.rs20.6 KBsession_gate.rs14.9 KBsunshine.rs12.2 KBui.rs68.5 KBvirtual_display.rs7.2 KBwin32_flyout.rs3.4 KBwin32_tray.rs22.3 KBwindow_migration.rs43.8 KBsrc/control.rs4.1 KB
1
use std::thread;2
3
use windows::Win32::Foundation::{4
CloseHandle, ERROR_ALREADY_EXISTS, ERROR_FILE_NOT_FOUND, GetLastError, HANDLE, WAIT_FAILED,5
};6
use windows::Win32::System::Threading::{7
CreateEventW, CreateMutexW, EVENT_MODIFY_STATE, INFINITE, OpenEventW, ReleaseMutex, SetEvent,8
WaitForSingleObject,9
};10
use windows::core::w;11
12
const TRAY_MUTEX: windows::core::PCWSTR = w!("Local\\SBMSTray-v1");13
const SHUTDOWN_EVENT: windows::core::PCWSTR = w!("Local\\SBMSShutdown-v1");14
const CONFIG_RELOAD_EVENT: windows::core::PCWSTR = w!("Local\\SBMSConfigReload-v1");15
16
pub struct TrayInstance(HANDLE);17
18
impl TrayInstance {19
pub fn acquire() -> Result<Option<Self>, String> {20
let handle = unsafe { CreateMutexW(None, true, TRAY_MUTEX) }21
.map_err(|error| format!("CreateMutexW(tray) failed: {error}"))?;22
if unsafe { GetLastError() } == ERROR_ALREADY_EXISTS {23
unsafe {24
let _ = CloseHandle(handle);25
}26
return Ok(None);27
}28
Ok(Some(Self(handle)))29
}30
}31
32
impl Drop for TrayInstance {33
fn drop(&mut self) {34
unsafe {35
let _ = ReleaseMutex(self.0);36
let _ = CloseHandle(self.0);37
}38
}39
}40
41
pub fn listen_for_shutdown(callback: impl FnOnce() + Send + 'static) -> Result<(), String> {42
let event = unsafe { CreateEventW(None, false, false, SHUTDOWN_EVENT) }43
.map_err(|error| format!("CreateEventW(shutdown) failed: {error}"))?;44
let event_value = event.0 as usize;45
thread::Builder::new()46
.name("sbms-shutdown-listener".into())47
.spawn(move || {48
let event = HANDLE(event_value as *mut _);49
unsafe {50
let _ = WaitForSingleObject(event, INFINITE);51
let _ = CloseHandle(event);52
}53
callback();54
})55
.map(|_| ())56
.map_err(|error| {57
unsafe {58
let _ = CloseHandle(event);59
}60
format!("failed to start shutdown listener: {error}")61
})62
}63
64
pub fn signal_shutdown() -> Result<bool, String> {65
let event = match unsafe { OpenEventW(EVENT_MODIFY_STATE, false, SHUTDOWN_EVENT) } {66
Ok(event) => event,67
Err(_error) if unsafe { GetLastError() } == ERROR_FILE_NOT_FOUND => return Ok(false),68
Err(error) => return Err(format!("OpenEventW(shutdown) failed: {error}")),69
};70
let result = unsafe { SetEvent(event) }71
.map(|()| true)72
.map_err(|error| format!("SetEvent(shutdown) failed: {error}"));73
unsafe {74
let _ = CloseHandle(event);75
}76
result77
}78
79
pub fn listen_for_config_reload(callback: impl Fn() + Send + 'static) -> Result<(), String> {80
let event = unsafe { CreateEventW(None, false, false, CONFIG_RELOAD_EVENT) }81
.map_err(|error| format!("CreateEventW(config reload) failed: {error}"))?;82
let event_value = event.0 as usize;83
thread::Builder::new()84
.name("sbms-config-reload-listener".into())85
.spawn(move || {86
let event = HANDLE(event_value as *mut _);87
loop {88
let wait = unsafe { WaitForSingleObject(event, INFINITE) };89
if wait == WAIT_FAILED {90
break;91
}92
callback();93
}94
unsafe {95
let _ = CloseHandle(event);96
}97
})98
.map(|_| ())99
.map_err(|error| {100
unsafe {101
let _ = CloseHandle(event);102
}103
format!("failed to start config reload listener: {error}")104
})105
}106
107
pub fn signal_config_reload() -> Result<bool, String> {108
let event = match unsafe { OpenEventW(EVENT_MODIFY_STATE, false, CONFIG_RELOAD_EVENT) } {109
Ok(event) => event,110
Err(_error) if unsafe { GetLastError() } == ERROR_FILE_NOT_FOUND => return Ok(false),111
Err(error) => return Err(format!("OpenEventW(config reload) failed: {error}")),112
};113
let result = unsafe { SetEvent(event) }114
.map(|()| true)115
.map_err(|error| format!("SetEvent(config reload) failed: {error}"));116
unsafe {117
let _ = CloseHandle(event);118
}119
result120
}121