Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,38 @@ keyboard-types = { version = "0.6.1", default-features = false }
raw-window-handle = "0.5"

[target.'cfg(target_os="linux")'.dependencies]
x11rb = { version = "0.13.0", features = ["cursor", "resource_manager", "allow-unsafe-code"] }
x11rb = { version = "0.13.0", features = [
"cursor",
"resource_manager",
"allow-unsafe-code",
] }
x11 = { version = "2.21", features = ["xlib", "xlib_xcb"] }
nix = "0.22.0"

[target.'cfg(target_os="windows")'.dependencies]
winapi = { version = "0.3.8", features = ["libloaderapi", "winuser", "windef", "minwindef", "guiddef", "combaseapi", "wingdi", "errhandlingapi", "ole2", "oleidl", "shellapi", "winerror"] }
windows = { version = "0.62.2", features = [
"Win32_Graphics_Gdi",
"Win32_Graphics_OpenGL",
"Win32_System_Com_StructuredStorage",
"Win32_System_Ole",
"Win32_System_SystemServices",
"Win32_UI_WindowsAndMessaging",
] }
windows-sys = { version = "0.61.2", features = [
"Win32_Graphics_Gdi",
"Win32_Graphics_OpenGL",
"Win32_System_Com",
"Win32_System_LibraryLoader",
"Win32_System_Ole",
"Win32_System_SystemServices",
"Win32_System_Threading",
"Win32_UI_Controls",
"Win32_UI_HiDpi",
"Win32_UI_Input_KeyboardAndMouse",
"Win32_UI_Shell",
"Win32_UI_WindowsAndMessaging",
] }
windows-core = { version = "0.62.2" }
uuid = { version = "0.8", features = ["v4"], optional = true }

[target.'cfg(target_os="macos")'.dependencies]
Expand Down
109 changes: 50 additions & 59 deletions src/gl/win.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
use std::ffi::{c_void, CString, OsStr};
use std::os::windows::ffi::OsStrExt;

use raw_window_handle::RawWindowHandle;

use winapi::shared::minwindef::{HINSTANCE, HMODULE};
use winapi::shared::ntdef::WCHAR;
use winapi::shared::windef::{HDC, HGLRC, HWND};
use winapi::um::libloaderapi::{FreeLibrary, GetProcAddress, LoadLibraryA};
use winapi::um::wingdi::{
wglCreateContext, wglDeleteContext, wglGetProcAddress, wglMakeCurrent, ChoosePixelFormat,
DescribePixelFormat, SetPixelFormat, SwapBuffers, PFD_DOUBLEBUFFER, PFD_DRAW_TO_WINDOW,
PFD_MAIN_PLANE, PFD_SUPPORT_OPENGL, PFD_TYPE_RGBA, PIXELFORMATDESCRIPTOR,
};
use winapi::um::winnt::IMAGE_DOS_HEADER;
use winapi::um::winuser::{
CreateWindowExW, DefWindowProcW, DestroyWindow, GetDC, RegisterClassW, ReleaseDC,
UnregisterClassW, CS_OWNDC, CW_USEDEFAULT, WNDCLASSW,
use windows_sys::{
core::s,
Win32::{
Foundation::{FreeLibrary, HINSTANCE, HMODULE, HWND},
Graphics::{
Gdi::{GetDC, ReleaseDC, HDC},
OpenGL::{
wglCreateContext, wglDeleteContext, wglGetProcAddress, wglMakeCurrent,
ChoosePixelFormat, DescribePixelFormat, SetPixelFormat, SwapBuffers, HGLRC,
PFD_DOUBLEBUFFER, PFD_DRAW_TO_WINDOW, PFD_MAIN_PLANE, PFD_SUPPORT_OPENGL,
PFD_TYPE_RGBA, PIXELFORMATDESCRIPTOR,
},
},
System::{
LibraryLoader::{GetProcAddress, LoadLibraryA},
SystemServices::IMAGE_DOS_HEADER,
},
UI::WindowsAndMessaging::{
CreateWindowExW, DefWindowProcW, DestroyWindow, RegisterClassW, UnregisterClassW,
CS_OWNDC, CW_USEDEFAULT, WNDCLASSW,
},
},
};

use raw_window_handle::RawWindowHandle;

use super::{GlConfig, GlError, Profile};

// See https://www.khronos.org/registry/OpenGL/extensions/ARB/WGL_ARB_create_context.txt
Expand Down Expand Up @@ -91,7 +100,7 @@ impl GlContext {
// Create temporary window and context to load function pointers

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

let hinstance = &__ImageBase as *const IMAGE_DOS_HEADER as HINSTANCE;
Expand All @@ -111,7 +120,7 @@ impl GlContext {

let hwnd_tmp = CreateWindowExW(
0,
class as *const WCHAR,
class as *const _,
[0].as_ptr(),
0,
CW_USEDEFAULT,
Expand Down Expand Up @@ -139,7 +148,7 @@ impl GlContext {
cAlphaBits: 8,
cDepthBits: 24,
cStencilBits: 8,
iLayerType: PFD_MAIN_PLANE,
iLayerType: PFD_MAIN_PLANE as u8,
..std::mem::zeroed()
};

Expand All @@ -148,7 +157,7 @@ impl GlContext {
let hglrc_tmp = wglCreateContext(hdc_tmp);
if hglrc_tmp.is_null() {
ReleaseDC(hwnd_tmp, hdc_tmp);
UnregisterClassW(class as *const WCHAR, hinstance);
UnregisterClassW(class as *const _, hinstance);
DestroyWindow(hwnd_tmp);
return Err(GlError::CreationFailed(()));
}
Expand All @@ -157,49 +166,28 @@ impl GlContext {

#[allow(non_snake_case)]
let wglCreateContextAttribsARB: Option<WglCreateContextAttribsARB> = {
let symbol = CString::new("wglCreateContextAttribsARB").unwrap();
let addr = wglGetProcAddress(symbol.as_ptr());
if !addr.is_null() {
#[allow(clippy::missing_transmute_annotations)]
Some(std::mem::transmute(addr))
} else {
None
}
wglGetProcAddress(s!("wglCreateContextAttribsARB"))
.map(|addr| std::mem::transmute(addr))
};

#[allow(non_snake_case)]
let wglChoosePixelFormatARB: Option<WglChoosePixelFormatARB> = {
let symbol = CString::new("wglChoosePixelFormatARB").unwrap();
let addr = wglGetProcAddress(symbol.as_ptr());
if !addr.is_null() {
#[allow(clippy::missing_transmute_annotations)]
Some(std::mem::transmute(addr))
} else {
None
}
wglGetProcAddress(s!("wglChoosePixelFormatARB")).map(|addr| std::mem::transmute(addr))
};

#[allow(non_snake_case)]
let wglSwapIntervalEXT: Option<WglSwapIntervalEXT> = {
let symbol = CString::new("wglSwapIntervalEXT").unwrap();
let addr = wglGetProcAddress(symbol.as_ptr());
if !addr.is_null() {
#[allow(clippy::missing_transmute_annotations)]
Some(std::mem::transmute(addr))
} else {
None
}
};
let wglSwapIntervalEXT: Option<WglSwapIntervalEXT> =
{ wglGetProcAddress(s!("wglSwapIntervalEXT")).map(|addr| std::mem::transmute(addr)) };

wglMakeCurrent(hdc_tmp, std::ptr::null_mut());
wglMakeCurrent(hdc_tmp, HGLRC::default());
wglDeleteContext(hglrc_tmp);
ReleaseDC(hwnd_tmp, hdc_tmp);
UnregisterClassW(class as *const WCHAR, hinstance);
UnregisterClassW(class as *const _, hinstance);
DestroyWindow(hwnd_tmp);

// Create actual context

let hwnd = handle.hwnd as HWND;
let hwnd = handle.hwnd;

let hdc = GetDC(hwnd);

Expand Down Expand Up @@ -295,17 +283,16 @@ impl GlContext {
];

let hglrc =
wglCreateContextAttribsARB.unwrap()(hdc, std::ptr::null_mut(), ctx_attribs.as_ptr());
wglCreateContextAttribsARB.unwrap()(hdc, HGLRC::default(), ctx_attribs.as_ptr());
if hglrc.is_null() {
return Err(GlError::CreationFailed(()));
}

let gl_library_name = CString::new("opengl32.dll").unwrap();
let gl_library = LoadLibraryA(gl_library_name.as_ptr());
let gl_library = LoadLibraryA(s!("opengl32.dll"));

wglMakeCurrent(hdc, hglrc);
wglSwapIntervalEXT.unwrap()(config.vsync as i32);
wglMakeCurrent(hdc, std::ptr::null_mut());
wglMakeCurrent(hdc, HGLRC::default());

Ok(GlContext { hwnd, hdc, hglrc, gl_library })
}
Expand All @@ -315,16 +302,20 @@ impl GlContext {
}

pub unsafe fn make_not_current(&self) {
wglMakeCurrent(self.hdc, std::ptr::null_mut());
wglMakeCurrent(self.hdc, HGLRC::default());
}

pub fn get_proc_address(&self, symbol: &str) -> *const c_void {
let symbol = CString::new(symbol).unwrap();
let addr = unsafe { wglGetProcAddress(symbol.as_ptr()) as *const c_void };
if !addr.is_null() {
addr
} else {
unsafe { GetProcAddress(self.gl_library, symbol.as_ptr()) as *const c_void }
let symbol_ptr = symbol.as_ptr().cast();

let addr = unsafe {
wglGetProcAddress(symbol_ptr).or_else(|| GetProcAddress(self.gl_library, symbol_ptr))
};

match addr {
Some(addr) => addr as *const c_void,
None => std::ptr::null(),
}
}

Expand All @@ -338,7 +329,7 @@ impl GlContext {
impl Drop for GlContext {
fn drop(&mut self) {
unsafe {
wglMakeCurrent(std::ptr::null_mut(), std::ptr::null_mut());
wglMakeCurrent(HDC::default(), HGLRC::default());
wglDeleteContext(self.hglrc);
ReleaseDC(self.hwnd, self.hdc);
FreeLibrary(self.gl_library);
Expand Down
8 changes: 4 additions & 4 deletions src/win/cursor.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::MouseCursor;
use winapi::{
shared::ntdef::LPCWSTR,
um::winuser::{
use windows_sys::{
core::PCWSTR,
Win32::UI::WindowsAndMessaging::{
IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, IDC_HELP, IDC_IBEAM, IDC_NO, IDC_SIZEALL,
IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE, IDC_SIZEWE, IDC_WAIT,
},
};

pub fn cursor_to_lpcwstr(cursor: MouseCursor) -> LPCWSTR {
pub fn cursor_to_lpcwstr(cursor: MouseCursor) -> PCWSTR {
match cursor {
MouseCursor::Default => IDC_ARROW,
MouseCursor::Hand => IDC_HAND,
Expand Down
Loading
Loading