mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-25 14:05:41 -05:00
Migrate from winapi to windows-sys
This commit is contained in:
parent
c5ae05e810
commit
e9ee8dcd9f
9 changed files with 64 additions and 54 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -39,7 +39,7 @@ dependencies = [
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"wayland-client",
|
"wayland-client",
|
||||||
"winapi 0.3.9",
|
"windows-sys",
|
||||||
"x11-dl",
|
"x11-dl",
|
||||||
"xdg",
|
"xdg",
|
||||||
]
|
]
|
||||||
|
@ -91,7 +91,7 @@ dependencies = [
|
||||||
"signal-hook-mio",
|
"signal-hook-mio",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"vte",
|
"vte",
|
||||||
"winapi 0.3.9",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -62,7 +62,12 @@ x11-dl = { version = "2", optional = true }
|
||||||
wayland-client = { version = "0.29.0", features = ["dlopen"], optional = true }
|
wayland-client = { version = "0.29.0", features = ["dlopen"], optional = true }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = { version = "0.3.7", features = ["impl-default", "wincon"]}
|
windows-sys = { version = "0.36", features = [
|
||||||
|
"Win32_UI_WindowsAndMessaging",
|
||||||
|
"Win32_System_Threading",
|
||||||
|
"Win32_System_Console",
|
||||||
|
"Win32_Foundation",
|
||||||
|
]}
|
||||||
|
|
||||||
[target.'cfg(windows)'.build-dependencies]
|
[target.'cfg(windows)'.build-dependencies]
|
||||||
embed-resource = "1.7.2"
|
embed-resource = "1.7.2"
|
||||||
|
|
|
@ -18,7 +18,7 @@ use {
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
use libc::pid_t;
|
use libc::pid_t;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use winapi::um::winbase::{CREATE_NEW_PROCESS_GROUP, CREATE_NO_WINDOW};
|
use windows_sys::Win32::System::Threading::{CREATE_NEW_PROCESS_GROUP, CREATE_NO_WINDOW};
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
use crate::macos;
|
use crate::macos;
|
||||||
|
|
|
@ -47,8 +47,6 @@ use glutin::{self, ContextBuilder, PossiblyCurrent, Rect, WindowedContext};
|
||||||
use objc::{msg_send, sel, sel_impl};
|
use objc::{msg_send, sel, sel_impl};
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
||||||
#[cfg(windows)]
|
|
||||||
use winapi::shared::minwindef::WORD;
|
|
||||||
|
|
||||||
use alacritty_terminal::index::Point;
|
use alacritty_terminal::index::Point;
|
||||||
|
|
||||||
|
@ -63,7 +61,7 @@ static WINDOW_ICON: &[u8] = include_bytes!("../../extra/logo/compat/alacritty-te
|
||||||
|
|
||||||
/// This should match the definition of IDI_ICON from `alacritty.rc`.
|
/// This should match the definition of IDI_ICON from `alacritty.rc`.
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
const IDI_ICON: WORD = 0x101;
|
const IDI_ICON: u16 = 0x101;
|
||||||
|
|
||||||
/// Context creation flags from probing config.
|
/// Context creation flags from probing config.
|
||||||
static GL_CONTEXT_CREATION_FLAGS: AtomicU8 = AtomicU8::new(GlContextFlags::SRGB.bits);
|
static GL_CONTEXT_CREATION_FLAGS: AtomicU8 = AtomicU8::new(GlContextFlags::SRGB.bits);
|
||||||
|
|
|
@ -25,7 +25,7 @@ use glutin::event_loop::EventLoopBuilder as GlutinEventLoopBuilder;
|
||||||
use glutin::platform::unix::EventLoopWindowTargetExtUnix;
|
use glutin::platform::unix::EventLoopWindowTargetExtUnix;
|
||||||
use log::info;
|
use log::info;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use winapi::um::wincon::{AttachConsole, FreeConsole, ATTACH_PARENT_PROCESS};
|
use windows_sys::Win32::System::Console::{AttachConsole, FreeConsole, ATTACH_PARENT_PROCESS};
|
||||||
|
|
||||||
use alacritty_terminal::tty;
|
use alacritty_terminal::tty;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::{io, panic, ptr};
|
use std::{io, panic};
|
||||||
|
|
||||||
use winapi::um::winuser;
|
use windows_sys::Win32::UI::WindowsAndMessaging::{
|
||||||
|
MessageBoxW, MB_ICONERROR, MB_OK, MB_SETFOREGROUND, MB_TASKMODAL,
|
||||||
|
};
|
||||||
|
|
||||||
use alacritty_terminal::tty::windows::win32_string;
|
use alacritty_terminal::tty::windows::win32_string;
|
||||||
|
|
||||||
|
@ -12,14 +14,11 @@ pub fn attach_handler() {
|
||||||
let _ = writeln!(io::stderr(), "{}", panic_info);
|
let _ = writeln!(io::stderr(), "{}", panic_info);
|
||||||
let msg = format!("{}\n\nPress Ctrl-C to Copy", panic_info);
|
let msg = format!("{}\n\nPress Ctrl-C to Copy", panic_info);
|
||||||
unsafe {
|
unsafe {
|
||||||
winuser::MessageBoxW(
|
MessageBoxW(
|
||||||
ptr::null_mut(),
|
0isize,
|
||||||
win32_string(&msg).as_ptr(),
|
win32_string(&msg).as_ptr(),
|
||||||
win32_string("Alacritty: Runtime Error").as_ptr(),
|
win32_string("Alacritty: Runtime Error").as_ptr(),
|
||||||
winuser::MB_ICONERROR
|
MB_ICONERROR | MB_OK | MB_SETFOREGROUND | MB_TASKMODAL,
|
||||||
| winuser::MB_OK
|
|
||||||
| winuser::MB_SETFOREGROUND
|
|
||||||
| winuser::MB_TASKMODAL,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -39,11 +39,14 @@ signal-hook-mio = { version = "0.2.1", features = ["support-v0_6"] }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
miow = "0.3"
|
miow = "0.3"
|
||||||
winapi = { version = "0.3.7", features = [
|
|
||||||
"impl-default", "basetsd", "libloaderapi", "minwindef", "ntdef", "processthreadsapi", "winbase",
|
|
||||||
"wincon", "wincontypes", "winerror", "winnt", "winuser", "consoleapi",
|
|
||||||
]}
|
|
||||||
mio-anonymous-pipes = "0.2"
|
mio-anonymous-pipes = "0.2"
|
||||||
|
windows-sys = { version = "0.36", features = [
|
||||||
|
"Win32_System_Console",
|
||||||
|
"Win32_Foundation",
|
||||||
|
"Win32_Security",
|
||||||
|
"Win32_System_Threading",
|
||||||
|
"Win32_System_WindowsProgramming",
|
||||||
|
]}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = "1.0.0"
|
serde_json = "1.0.0"
|
||||||
|
|
|
@ -4,14 +4,16 @@ use std::sync::atomic::{AtomicPtr, Ordering};
|
||||||
|
|
||||||
use mio_extras::channel::{channel, Receiver, Sender};
|
use mio_extras::channel::{channel, Receiver, Sender};
|
||||||
|
|
||||||
use winapi::shared::ntdef::{BOOLEAN, HANDLE, PVOID};
|
use windows_sys::Win32::Foundation::{BOOLEAN, HANDLE};
|
||||||
use winapi::um::winbase::{RegisterWaitForSingleObject, UnregisterWait, INFINITE};
|
use windows_sys::Win32::System::Threading::{
|
||||||
use winapi::um::winnt::{WT_EXECUTEINWAITTHREAD, WT_EXECUTEONLYONCE};
|
RegisterWaitForSingleObject, UnregisterWait, WT_EXECUTEINWAITTHREAD, WT_EXECUTEONLYONCE,
|
||||||
|
};
|
||||||
|
use windows_sys::Win32::System::WindowsProgramming::INFINITE;
|
||||||
|
|
||||||
use crate::tty::ChildEvent;
|
use crate::tty::ChildEvent;
|
||||||
|
|
||||||
/// WinAPI callback to run when child process exits.
|
/// WinAPI callback to run when child process exits.
|
||||||
extern "system" fn child_exit_callback(ctx: PVOID, timed_out: BOOLEAN) {
|
extern "system" fn child_exit_callback(ctx: *mut c_void, timed_out: BOOLEAN) {
|
||||||
if timed_out != 0 {
|
if timed_out != 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +31,7 @@ impl ChildExitWatcher {
|
||||||
pub fn new(child_handle: HANDLE) -> Result<ChildExitWatcher, Error> {
|
pub fn new(child_handle: HANDLE) -> Result<ChildExitWatcher, Error> {
|
||||||
let (event_tx, event_rx) = channel::<ChildEvent>();
|
let (event_tx, event_rx) = channel::<ChildEvent>();
|
||||||
|
|
||||||
let mut wait_handle: HANDLE = 0 as HANDLE;
|
let mut wait_handle: HANDLE = 0;
|
||||||
let sender_ref = Box::new(event_tx);
|
let sender_ref = Box::new(event_tx);
|
||||||
|
|
||||||
let success = unsafe {
|
let success = unsafe {
|
||||||
|
@ -37,7 +39,7 @@ impl ChildExitWatcher {
|
||||||
&mut wait_handle,
|
&mut wait_handle,
|
||||||
child_handle,
|
child_handle,
|
||||||
Some(child_exit_callback),
|
Some(child_exit_callback),
|
||||||
Box::into_raw(sender_ref) as PVOID,
|
Box::into_raw(sender_ref).cast(),
|
||||||
INFINITE,
|
INFINITE,
|
||||||
WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE,
|
WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE,
|
||||||
)
|
)
|
||||||
|
@ -46,7 +48,10 @@ impl ChildExitWatcher {
|
||||||
if success == 0 {
|
if success == 0 {
|
||||||
Err(Error::last_os_error())
|
Err(Error::last_os_error())
|
||||||
} else {
|
} else {
|
||||||
Ok(ChildExitWatcher { wait_handle: AtomicPtr::from(wait_handle), event_rx })
|
Ok(ChildExitWatcher {
|
||||||
|
wait_handle: AtomicPtr::from(wait_handle as *mut c_void),
|
||||||
|
event_rx,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +63,7 @@ impl ChildExitWatcher {
|
||||||
impl Drop for ChildExitWatcher {
|
impl Drop for ChildExitWatcher {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
UnregisterWait(self.wait_handle.load(Ordering::Relaxed));
|
UnregisterWait(self.wait_handle.load(Ordering::Relaxed) as HANDLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +83,7 @@ mod tests {
|
||||||
const WAIT_TIMEOUT: Duration = Duration::from_millis(200);
|
const WAIT_TIMEOUT: Duration = Duration::from_millis(200);
|
||||||
|
|
||||||
let mut child = Command::new("cmd.exe").spawn().unwrap();
|
let mut child = Command::new("cmd.exe").spawn().unwrap();
|
||||||
let child_exit_watcher = ChildExitWatcher::new(child.as_raw_handle()).unwrap();
|
let child_exit_watcher = ChildExitWatcher::new(child.as_raw_handle() as HANDLE).unwrap();
|
||||||
|
|
||||||
let mut events = Events::with_capacity(1);
|
let mut events = Events::with_capacity(1);
|
||||||
let poll = Poll::new().unwrap();
|
let poll = Poll::new().unwrap();
|
||||||
|
|
|
@ -3,17 +3,17 @@ use std::os::windows::io::IntoRawHandle;
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
|
|
||||||
use mio_anonymous_pipes::{EventedAnonRead, EventedAnonWrite};
|
use mio_anonymous_pipes::{EventedAnonRead, EventedAnonWrite};
|
||||||
use winapi::shared::basetsd::{PSIZE_T, SIZE_T};
|
|
||||||
use winapi::shared::minwindef::BYTE;
|
use windows_sys::core::PWSTR;
|
||||||
use winapi::shared::ntdef::LPWSTR;
|
use windows_sys::Win32::Foundation::{HANDLE, S_OK};
|
||||||
use winapi::shared::winerror::S_OK;
|
use windows_sys::Win32::System::Console::{
|
||||||
use winapi::um::consoleapi::{ClosePseudoConsole, CreatePseudoConsole, ResizePseudoConsole};
|
ClosePseudoConsole, CreatePseudoConsole, ResizePseudoConsole, COORD, HPCON,
|
||||||
use winapi::um::processthreadsapi::{
|
};
|
||||||
CreateProcessW, InitializeProcThreadAttributeList, UpdateProcThreadAttribute,
|
use windows_sys::Win32::System::Threading::{
|
||||||
PROCESS_INFORMATION, STARTUPINFOW,
|
CreateProcessW, InitializeProcThreadAttributeList, UpdateProcThreadAttribute,
|
||||||
|
EXTENDED_STARTUPINFO_PRESENT, PROCESS_INFORMATION, PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
|
||||||
|
STARTF_USESTDHANDLES, STARTUPINFOEXW, STARTUPINFOW,
|
||||||
};
|
};
|
||||||
use winapi::um::winbase::{EXTENDED_STARTUPINFO_PRESENT, STARTF_USESTDHANDLES, STARTUPINFOEXW};
|
|
||||||
use winapi::um::wincontypes::{COORD, HPCON};
|
|
||||||
|
|
||||||
use crate::config::PtyConfig;
|
use crate::config::PtyConfig;
|
||||||
use crate::event::{OnResize, WindowSize};
|
use crate::event::{OnResize, WindowSize};
|
||||||
|
@ -39,7 +39,7 @@ impl Drop for Conpty {
|
||||||
unsafe impl Send for Conpty {}
|
unsafe impl Send for Conpty {}
|
||||||
|
|
||||||
pub fn new(config: &PtyConfig, window_size: WindowSize) -> Option<Pty> {
|
pub fn new(config: &PtyConfig, window_size: WindowSize) -> Option<Pty> {
|
||||||
let mut pty_handle = 0 as HPCON;
|
let mut pty_handle: HPCON = 0;
|
||||||
|
|
||||||
// Passing 0 as the size parameter allows the "system default" buffer
|
// Passing 0 as the size parameter allows the "system default" buffer
|
||||||
// size to be used. There may be small performance and memory advantages
|
// size to be used. There may be small performance and memory advantages
|
||||||
|
@ -52,10 +52,10 @@ pub fn new(config: &PtyConfig, window_size: WindowSize) -> Option<Pty> {
|
||||||
let result = unsafe {
|
let result = unsafe {
|
||||||
CreatePseudoConsole(
|
CreatePseudoConsole(
|
||||||
window_size.into(),
|
window_size.into(),
|
||||||
conin_pty_handle.into_raw_handle(),
|
conin_pty_handle.into_raw_handle() as HANDLE,
|
||||||
conout_pty_handle.into_raw_handle(),
|
conout_pty_handle.into_raw_handle() as HANDLE,
|
||||||
0,
|
0,
|
||||||
&mut pty_handle as *mut HPCON,
|
&mut pty_handle as *mut _,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -65,11 +65,11 @@ pub fn new(config: &PtyConfig, window_size: WindowSize) -> Option<Pty> {
|
||||||
|
|
||||||
// Prepare child process startup info.
|
// Prepare child process startup info.
|
||||||
|
|
||||||
let mut size: SIZE_T = 0;
|
let mut size: usize = 0;
|
||||||
|
|
||||||
let mut startup_info_ex: STARTUPINFOEXW = Default::default();
|
let mut startup_info_ex: STARTUPINFOEXW = unsafe { mem::zeroed() };
|
||||||
|
|
||||||
startup_info_ex.StartupInfo.lpTitle = std::ptr::null_mut() as LPWSTR;
|
startup_info_ex.StartupInfo.lpTitle = std::ptr::null_mut() as PWSTR;
|
||||||
|
|
||||||
startup_info_ex.StartupInfo.cb = mem::size_of::<STARTUPINFOEXW>() as u32;
|
startup_info_ex.StartupInfo.cb = mem::size_of::<STARTUPINFOEXW>() as u32;
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ pub fn new(config: &PtyConfig, window_size: WindowSize) -> Option<Pty> {
|
||||||
// Create the appropriately sized thread attribute list.
|
// Create the appropriately sized thread attribute list.
|
||||||
unsafe {
|
unsafe {
|
||||||
let failure =
|
let failure =
|
||||||
InitializeProcThreadAttributeList(ptr::null_mut(), 1, 0, &mut size as PSIZE_T) > 0;
|
InitializeProcThreadAttributeList(ptr::null_mut(), 1, 0, &mut size as *mut usize) > 0;
|
||||||
|
|
||||||
// This call was expected to return false.
|
// This call was expected to return false.
|
||||||
if failure {
|
if failure {
|
||||||
|
@ -88,7 +88,7 @@ pub fn new(config: &PtyConfig, window_size: WindowSize) -> Option<Pty> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut attr_list: Box<[BYTE]> = vec![0; size].into_boxed_slice();
|
let mut attr_list: Box<[u8]> = vec![0; size].into_boxed_slice();
|
||||||
|
|
||||||
// Set startup info's attribute list & initialize it
|
// Set startup info's attribute list & initialize it
|
||||||
//
|
//
|
||||||
|
@ -106,7 +106,7 @@ pub fn new(config: &PtyConfig, window_size: WindowSize) -> Option<Pty> {
|
||||||
startup_info_ex.lpAttributeList,
|
startup_info_ex.lpAttributeList,
|
||||||
1,
|
1,
|
||||||
0,
|
0,
|
||||||
&mut size as PSIZE_T,
|
&mut size as *mut usize,
|
||||||
) > 0;
|
) > 0;
|
||||||
|
|
||||||
if !success {
|
if !success {
|
||||||
|
@ -119,8 +119,8 @@ pub fn new(config: &PtyConfig, window_size: WindowSize) -> Option<Pty> {
|
||||||
success = UpdateProcThreadAttribute(
|
success = UpdateProcThreadAttribute(
|
||||||
startup_info_ex.lpAttributeList,
|
startup_info_ex.lpAttributeList,
|
||||||
0,
|
0,
|
||||||
22 | 0x0002_0000, // PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE.
|
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE as usize,
|
||||||
pty_handle,
|
pty_handle as *mut std::ffi::c_void,
|
||||||
mem::size_of::<HPCON>(),
|
mem::size_of::<HPCON>(),
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
|
@ -134,11 +134,11 @@ pub fn new(config: &PtyConfig, window_size: WindowSize) -> Option<Pty> {
|
||||||
let cmdline = win32_string(&cmdline(config));
|
let cmdline = win32_string(&cmdline(config));
|
||||||
let cwd = config.working_directory.as_ref().map(win32_string);
|
let cwd = config.working_directory.as_ref().map(win32_string);
|
||||||
|
|
||||||
let mut proc_info: PROCESS_INFORMATION = Default::default();
|
let mut proc_info: PROCESS_INFORMATION = unsafe { mem::zeroed() };
|
||||||
unsafe {
|
unsafe {
|
||||||
success = CreateProcessW(
|
success = CreateProcessW(
|
||||||
ptr::null(),
|
ptr::null(),
|
||||||
cmdline.as_ptr() as LPWSTR,
|
cmdline.as_ptr() as PWSTR,
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
false as i32,
|
false as i32,
|
||||||
|
@ -158,7 +158,7 @@ pub fn new(config: &PtyConfig, window_size: WindowSize) -> Option<Pty> {
|
||||||
let conout = EventedAnonRead::new(conout);
|
let conout = EventedAnonRead::new(conout);
|
||||||
|
|
||||||
let child_watcher = ChildExitWatcher::new(proc_info.hProcess).unwrap();
|
let child_watcher = ChildExitWatcher::new(proc_info.hProcess).unwrap();
|
||||||
let conpty = Conpty { handle: pty_handle };
|
let conpty = Conpty { handle: pty_handle as HPCON };
|
||||||
|
|
||||||
Some(Pty::new(conpty, conout, conin, child_watcher))
|
Some(Pty::new(conpty, conout, conin, child_watcher))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue