Skip to content

Commit e2038fc

Browse files
committed
Replace winapi usage with windows
The winapi crate is no longer maintained. This change ports everything over to use the more maintained windows crate.
1 parent 237d323 commit e2038fc

File tree

7 files changed

+427
-471
lines changed

7 files changed

+427
-471
lines changed

Cargo.toml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,31 @@ keyboard-types = { version = "0.6.1", default-features = false }
2323
raw-window-handle = "0.5"
2424

2525
[target.'cfg(target_os="linux")'.dependencies]
26-
x11rb = { version = "0.13.0", features = ["cursor", "resource_manager", "allow-unsafe-code"] }
26+
x11rb = { version = "0.13.0", features = [
27+
"cursor",
28+
"resource_manager",
29+
"allow-unsafe-code",
30+
] }
2731
x11 = { version = "2.21", features = ["xlib", "xlib_xcb"] }
2832
nix = "0.22.0"
2933

3034
[target.'cfg(target_os="windows")'.dependencies]
31-
winapi = { version = "0.3.8", features = ["libloaderapi", "winuser", "windef", "minwindef", "guiddef", "combaseapi", "wingdi", "errhandlingapi", "ole2", "oleidl", "shellapi", "winerror"] }
35+
windows = { version = "0.62.2", features = [
36+
"Win32_Graphics_Gdi",
37+
"Win32_Graphics_OpenGL",
38+
"Win32_System_Com_StructuredStorage",
39+
"Win32_System_Com",
40+
"Win32_System_LibraryLoader",
41+
"Win32_System_Ole",
42+
"Win32_System_SystemServices",
43+
"Win32_System_Threading",
44+
"Win32_UI_Controls",
45+
"Win32_UI_HiDpi",
46+
"Win32_UI_Input_KeyboardAndMouse",
47+
"Win32_UI_Shell",
48+
"Win32_UI_WindowsAndMessaging",
49+
] }
50+
windows-core = { version = "0.62.2" }
3251
uuid = { version = "0.8", features = ["v4"], optional = true }
3352

3453
[target.'cfg(target_os="macos")'.dependencies]

src/gl/win.rs

Lines changed: 82 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
11
use std::ffi::{c_void, CString, OsStr};
22
use std::os::windows::ffi::OsStrExt;
33

4-
use raw_window_handle::RawWindowHandle;
5-
6-
use winapi::shared::minwindef::{HINSTANCE, HMODULE};
7-
use winapi::shared::ntdef::WCHAR;
8-
use winapi::shared::windef::{HDC, HGLRC, HWND};
9-
use winapi::um::libloaderapi::{FreeLibrary, GetProcAddress, LoadLibraryA};
10-
use winapi::um::wingdi::{
11-
wglCreateContext, wglDeleteContext, wglGetProcAddress, wglMakeCurrent, ChoosePixelFormat,
12-
DescribePixelFormat, SetPixelFormat, SwapBuffers, PFD_DOUBLEBUFFER, PFD_DRAW_TO_WINDOW,
13-
PFD_MAIN_PLANE, PFD_SUPPORT_OPENGL, PFD_TYPE_RGBA, PIXELFORMATDESCRIPTOR,
14-
};
15-
use winapi::um::winnt::IMAGE_DOS_HEADER;
16-
use winapi::um::winuser::{
17-
CreateWindowExW, DefWindowProcW, DestroyWindow, GetDC, RegisterClassW, ReleaseDC,
18-
UnregisterClassW, CS_OWNDC, CW_USEDEFAULT, WNDCLASSW,
4+
use windows::{
5+
core::{s, PCSTR, PCWSTR},
6+
Win32::{
7+
Foundation::{FreeLibrary, HINSTANCE, HMODULE, HWND, LPARAM, LRESULT, WPARAM},
8+
Graphics::{
9+
Gdi::{GetDC, ReleaseDC, HDC},
10+
OpenGL::{
11+
wglCreateContext, wglDeleteContext, wglGetProcAddress, wglMakeCurrent,
12+
ChoosePixelFormat, DescribePixelFormat, SetPixelFormat, SwapBuffers, HGLRC,
13+
PFD_DOUBLEBUFFER, PFD_DRAW_TO_WINDOW, PFD_MAIN_PLANE, PFD_SUPPORT_OPENGL,
14+
PFD_TYPE_RGBA, PIXELFORMATDESCRIPTOR,
15+
},
16+
},
17+
System::{
18+
LibraryLoader::{GetProcAddress, LoadLibraryA},
19+
SystemServices::IMAGE_DOS_HEADER,
20+
},
21+
UI::WindowsAndMessaging::{
22+
CreateWindowExW, DefWindowProcW, DestroyWindow, RegisterClassW, UnregisterClassW,
23+
CS_OWNDC, CW_USEDEFAULT, WINDOW_EX_STYLE, WINDOW_STYLE, WNDCLASSW,
24+
},
25+
},
1926
};
2027

28+
use raw_window_handle::RawWindowHandle;
29+
2130
use super::{GlConfig, GlError, Profile};
2231

2332
// See https://www.khronos.org/registry/OpenGL/extensions/ARB/WGL_ARB_create_context.txt
@@ -77,6 +86,7 @@ extern "C" {
7786
}
7887

7988
impl GlContext {
89+
#[allow(unused)]
8090
pub unsafe fn create(parent: &RawWindowHandle, config: GlConfig) -> Result<GlContext, GlError> {
8191
let handle = if let RawWindowHandle::Win32(handle) = parent {
8292
handle
@@ -91,16 +101,24 @@ impl GlContext {
91101
// Create temporary window and context to load function pointers
92102

93103
let class_name_str = format!("raw-gl-context-window-{}", uuid::Uuid::new_v4().to_simple());
94-
let mut class_name: Vec<WCHAR> = OsStr::new(&class_name_str).encode_wide().collect();
104+
let mut class_name: Vec<u16> = OsStr::new(&class_name_str).encode_wide().collect();
95105
class_name.push(0);
96106

97-
let hinstance = &__ImageBase as *const IMAGE_DOS_HEADER as HINSTANCE;
107+
let pcw_class_name = PCWSTR(class_name.as_ptr());
108+
109+
let hinstance = HINSTANCE(&__ImageBase as *const IMAGE_DOS_HEADER as *mut c_void);
110+
111+
extern "system" fn wndproc(
112+
hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM,
113+
) -> LRESULT {
114+
unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) }
115+
}
98116

99117
let wnd_class = WNDCLASSW {
100118
style: CS_OWNDC,
101-
lpfnWndProc: Some(DefWindowProcW),
119+
lpfnWndProc: Some(wndproc),
102120
hInstance: hinstance,
103-
lpszClassName: class_name.as_ptr(),
121+
lpszClassName: pcw_class_name,
104122
..std::mem::zeroed()
105123
};
106124

@@ -110,23 +128,24 @@ impl GlContext {
110128
}
111129

112130
let hwnd_tmp = CreateWindowExW(
113-
0,
114-
class as *const WCHAR,
115-
[0].as_ptr(),
116-
0,
131+
WINDOW_EX_STYLE(0),
132+
pcw_class_name,
133+
None,
134+
WINDOW_STYLE(0),
117135
CW_USEDEFAULT,
118136
CW_USEDEFAULT,
119137
CW_USEDEFAULT,
120138
CW_USEDEFAULT,
121-
std::ptr::null_mut(),
122-
std::ptr::null_mut(),
123-
hinstance,
124-
std::ptr::null_mut(),
139+
None,
140+
None,
141+
Some(hinstance),
142+
None,
125143
);
126144

127-
if hwnd_tmp.is_null() {
145+
if hwnd_tmp.is_err() {
128146
return Err(GlError::CreationFailed(()));
129147
}
148+
let hwnd_tmp = hwnd_tmp.ok();
130149

131150
let hdc_tmp = GetDC(hwnd_tmp);
132151

@@ -139,69 +158,49 @@ impl GlContext {
139158
cAlphaBits: 8,
140159
cDepthBits: 24,
141160
cStencilBits: 8,
142-
iLayerType: PFD_MAIN_PLANE,
161+
iLayerType: PFD_MAIN_PLANE.0 as u8,
143162
..std::mem::zeroed()
144163
};
145164

146165
SetPixelFormat(hdc_tmp, ChoosePixelFormat(hdc_tmp, &pfd_tmp), &pfd_tmp);
147166

148167
let hglrc_tmp = wglCreateContext(hdc_tmp);
149-
if hglrc_tmp.is_null() {
168+
if hglrc_tmp.is_err() {
150169
ReleaseDC(hwnd_tmp, hdc_tmp);
151-
UnregisterClassW(class as *const WCHAR, hinstance);
152-
DestroyWindow(hwnd_tmp);
170+
UnregisterClassW(pcw_class_name, Some(hinstance));
171+
DestroyWindow(hwnd_tmp.unwrap());
153172
return Err(GlError::CreationFailed(()));
154173
}
174+
let hglrc_tmp = hglrc_tmp.unwrap();
155175

156176
wglMakeCurrent(hdc_tmp, hglrc_tmp);
157177

158178
#[allow(non_snake_case)]
159179
let wglCreateContextAttribsARB: Option<WglCreateContextAttribsARB> = {
160-
let symbol = CString::new("wglCreateContextAttribsARB").unwrap();
161-
let addr = wglGetProcAddress(symbol.as_ptr());
162-
if !addr.is_null() {
163-
#[allow(clippy::missing_transmute_annotations)]
164-
Some(std::mem::transmute(addr))
165-
} else {
166-
None
167-
}
180+
wglGetProcAddress(s!("wglCreateContextAttribsARB"))
181+
.map(|addr| std::mem::transmute(addr))
168182
};
169183

170184
#[allow(non_snake_case)]
171185
let wglChoosePixelFormatARB: Option<WglChoosePixelFormatARB> = {
172-
let symbol = CString::new("wglChoosePixelFormatARB").unwrap();
173-
let addr = wglGetProcAddress(symbol.as_ptr());
174-
if !addr.is_null() {
175-
#[allow(clippy::missing_transmute_annotations)]
176-
Some(std::mem::transmute(addr))
177-
} else {
178-
None
179-
}
186+
wglGetProcAddress(s!("wglChoosePixelFormatARB")).map(|addr| std::mem::transmute(addr))
180187
};
181188

182189
#[allow(non_snake_case)]
183-
let wglSwapIntervalEXT: Option<WglSwapIntervalEXT> = {
184-
let symbol = CString::new("wglSwapIntervalEXT").unwrap();
185-
let addr = wglGetProcAddress(symbol.as_ptr());
186-
if !addr.is_null() {
187-
#[allow(clippy::missing_transmute_annotations)]
188-
Some(std::mem::transmute(addr))
189-
} else {
190-
None
191-
}
192-
};
190+
let wglSwapIntervalEXT: Option<WglSwapIntervalEXT> =
191+
{ wglGetProcAddress(s!("wglSwapIntervalEXT")).map(|addr| std::mem::transmute(addr)) };
193192

194-
wglMakeCurrent(hdc_tmp, std::ptr::null_mut());
193+
wglMakeCurrent(hdc_tmp, HGLRC::default());
195194
wglDeleteContext(hglrc_tmp);
196195
ReleaseDC(hwnd_tmp, hdc_tmp);
197-
UnregisterClassW(class as *const WCHAR, hinstance);
198-
DestroyWindow(hwnd_tmp);
196+
UnregisterClassW(wnd_class.lpszClassName, Some(hinstance));
197+
DestroyWindow(hwnd_tmp.unwrap());
199198

200199
// Create actual context
201200

202-
let hwnd = handle.hwnd as HWND;
201+
let hwnd = HWND(handle.hwnd);
203202

204-
let hdc = GetDC(hwnd);
203+
let hdc = GetDC(Some(hwnd));
205204

206205
#[rustfmt::skip]
207206
let pixel_format_attribs = [
@@ -238,7 +237,7 @@ impl GlContext {
238237
hdc,
239238
pixel_format,
240239
std::mem::size_of::<PIXELFORMATDESCRIPTOR>() as u32,
241-
&mut pfd,
240+
Some(&mut pfd),
242241
);
243242
SetPixelFormat(hdc, pixel_format, &pfd);
244243

@@ -256,40 +255,45 @@ impl GlContext {
256255
];
257256

258257
let hglrc =
259-
wglCreateContextAttribsARB.unwrap()(hdc, std::ptr::null_mut(), ctx_attribs.as_ptr());
260-
if hglrc.is_null() {
258+
wglCreateContextAttribsARB.unwrap()(hdc, HGLRC::default(), ctx_attribs.as_ptr());
259+
if hglrc.is_invalid() {
261260
return Err(GlError::CreationFailed(()));
262261
}
263262

264-
let gl_library_name = CString::new("opengl32.dll").unwrap();
265-
let gl_library = LoadLibraryA(gl_library_name.as_ptr());
263+
let gl_library = LoadLibraryA(s!("opengl32.dll")).unwrap_or_default();
266264

267265
wglMakeCurrent(hdc, hglrc);
268266
wglSwapIntervalEXT.unwrap()(config.vsync as i32);
269-
wglMakeCurrent(hdc, std::ptr::null_mut());
267+
wglMakeCurrent(hdc, HGLRC::default());
270268

271269
Ok(GlContext { hwnd, hdc, hglrc, gl_library })
272270
}
273271

272+
#[allow(unused)]
274273
pub unsafe fn make_current(&self) {
275274
wglMakeCurrent(self.hdc, self.hglrc);
276275
}
277276

277+
#[allow(unused)]
278278
pub unsafe fn make_not_current(&self) {
279-
wglMakeCurrent(self.hdc, std::ptr::null_mut());
279+
wglMakeCurrent(self.hdc, HGLRC::default());
280280
}
281281

282282
pub fn get_proc_address(&self, symbol: &str) -> *const c_void {
283283
let symbol = CString::new(symbol).unwrap();
284-
let addr = unsafe { wglGetProcAddress(symbol.as_ptr()) as *const c_void };
285-
if !addr.is_null() {
286-
addr
287-
} else {
288-
unsafe { GetProcAddress(self.gl_library, symbol.as_ptr()) as *const c_void }
284+
unsafe {
285+
wglGetProcAddress(PCSTR(symbol.as_ptr() as *const u8))
286+
.map(|p| p as *const c_void)
287+
.or_else(|| {
288+
GetProcAddress(self.gl_library, PCSTR(symbol.as_ptr() as *const u8))
289+
.map(|p| p as *const c_void)
290+
})
291+
.unwrap_or_default()
289292
}
290293
}
291294

292295
pub fn swap_buffers(&self) {
296+
#[allow(unused)]
293297
unsafe {
294298
SwapBuffers(self.hdc);
295299
}
@@ -298,10 +302,11 @@ impl GlContext {
298302

299303
impl Drop for GlContext {
300304
fn drop(&mut self) {
305+
#[allow(unused)]
301306
unsafe {
302-
wglMakeCurrent(std::ptr::null_mut(), std::ptr::null_mut());
307+
wglMakeCurrent(HDC::default(), HGLRC::default());
303308
wglDeleteContext(self.hglrc);
304-
ReleaseDC(self.hwnd, self.hdc);
309+
ReleaseDC(Some(self.hwnd), self.hdc);
305310
FreeLibrary(self.gl_library);
306311
}
307312
}

src/win/cursor.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
use crate::MouseCursor;
2-
use winapi::{
3-
shared::ntdef::LPCWSTR,
4-
um::winuser::{
2+
use windows::{
3+
core::PCWSTR,
4+
Win32::UI::WindowsAndMessaging::{
55
IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, IDC_HELP, IDC_IBEAM, IDC_NO, IDC_SIZEALL,
66
IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE, IDC_SIZEWE, IDC_WAIT,
77
},
88
};
99

10-
pub fn cursor_to_lpcwstr(cursor: MouseCursor) -> LPCWSTR {
10+
pub fn cursor_to_lpcwstr(cursor: MouseCursor) -> PCWSTR {
1111
match cursor {
1212
MouseCursor::Default => IDC_ARROW,
1313
MouseCursor::Hand => IDC_HAND,
1414
MouseCursor::HandGrabbing => IDC_SIZEALL,
1515
MouseCursor::Help => IDC_HELP,
1616
// an empty LPCWSTR results in the cursor being hidden
17-
MouseCursor::Hidden => std::ptr::null(),
17+
MouseCursor::Hidden => PCWSTR::null(),
1818

1919
MouseCursor::Text => IDC_IBEAM,
2020
MouseCursor::VerticalText => IDC_IBEAM,

0 commit comments

Comments
 (0)