mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-11 21:31:29 +11:00
Added fullscreen support for X11
This commit is contained in:
parent
d8171a0c73
commit
b149fca83d
|
@ -58,6 +58,7 @@ pub struct WindowBuilder {
|
||||||
title: String,
|
title: String,
|
||||||
monitor: Option<winimpl::MonitorID>,
|
monitor: Option<winimpl::MonitorID>,
|
||||||
gl_version: Option<(uint, uint)>,
|
gl_version: Option<(uint, uint)>,
|
||||||
|
is_fullscreen: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowBuilder {
|
impl WindowBuilder {
|
||||||
|
@ -68,6 +69,7 @@ impl WindowBuilder {
|
||||||
title: "gl-init-rs window".to_string(),
|
title: "gl-init-rs window".to_string(),
|
||||||
monitor: None,
|
monitor: None,
|
||||||
gl_version: None,
|
gl_version: None,
|
||||||
|
is_fullscreen: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +93,7 @@ impl WindowBuilder {
|
||||||
pub fn with_fullscreen(mut self, monitor: MonitorID) -> WindowBuilder {
|
pub fn with_fullscreen(mut self, monitor: MonitorID) -> WindowBuilder {
|
||||||
let MonitorID(monitor) = monitor;
|
let MonitorID(monitor) = monitor;
|
||||||
self.monitor = Some(monitor);
|
self.monitor = Some(monitor);
|
||||||
|
self.is_fullscreen = true;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1337,8 +1337,26 @@ pub struct XButtonEvent {
|
||||||
pub same_screen: Bool,
|
pub same_screen: Bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct XF86VidModeModeInfo {
|
||||||
|
pub dotclock: libc::c_uint,
|
||||||
|
pub hdisplay: libc::c_ushort,
|
||||||
|
pub hsyncstart: libc::c_ushort,
|
||||||
|
pub hsyncend: libc::c_ushort,
|
||||||
|
pub htotal: libc::c_ushort,
|
||||||
|
pub hskew: libc::c_ushort,
|
||||||
|
pub vdisplay: libc::c_ushort,
|
||||||
|
pub vsyncstart: libc::c_ushort,
|
||||||
|
pub vsyncend: libc::c_ushort,
|
||||||
|
pub vtotal: libc::c_ushort,
|
||||||
|
pub flags: libc::c_uint,
|
||||||
|
privsize: libc::c_int,
|
||||||
|
private: libc::c_long,
|
||||||
|
}
|
||||||
|
|
||||||
#[link(name = "GL")]
|
#[link(name = "GL")]
|
||||||
#[link(name = "X11")]
|
#[link(name = "X11")]
|
||||||
|
#[link(name = "Xxf86vm")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn XCloseDisplay(display: *mut Display);
|
pub fn XCloseDisplay(display: *mut Display);
|
||||||
pub fn XCheckMaskEvent(display: *mut Display, event_mask: libc::c_long,
|
pub fn XCheckMaskEvent(display: *mut Display, event_mask: libc::c_long,
|
||||||
|
@ -1408,6 +1426,12 @@ extern "C" {
|
||||||
pub fn glXSwapBuffers(dpy: *mut Display, drawable: GLXDrawable);
|
pub fn glXSwapBuffers(dpy: *mut Display, drawable: GLXDrawable);
|
||||||
|
|
||||||
pub fn XkbSetDetectableAutoRepeat(dpy: *mut Display, detectable: bool, supported_rtm: *mut bool) -> bool;
|
pub fn XkbSetDetectableAutoRepeat(dpy: *mut Display, detectable: bool, supported_rtm: *mut bool) -> bool;
|
||||||
|
pub fn XF86VidModeSwitchToMode(dpy: *mut Display, screen: libc::c_int,
|
||||||
|
modeline: *mut XF86VidModeModeInfo) -> Bool;
|
||||||
|
pub fn XF86VidModeSetViewPort(dpy: *mut Display, screen: libc::c_int,
|
||||||
|
x: libc::c_int, y: libc::c_int) -> Bool;
|
||||||
|
pub fn XF86VidModeGetAllModeLines(dpy: *mut Display, screen: libc::c_int,
|
||||||
|
modecount_return: *mut libc::c_int, modesinfo: *mut *mut *mut XF86VidModeModeInfo) -> Bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -14,16 +14,19 @@ pub struct Window {
|
||||||
context: ffi::GLXContext,
|
context: ffi::GLXContext,
|
||||||
is_closed: AtomicBool,
|
is_closed: AtomicBool,
|
||||||
wm_delete_window: ffi::Atom,
|
wm_delete_window: ffi::Atom,
|
||||||
|
xf86_desk_mode: *mut ffi::XF86VidModeModeInfo,
|
||||||
|
screen_id: libc::c_int,
|
||||||
|
is_fullscreen: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MonitorID(uint);
|
pub struct MonitorID(uint);
|
||||||
|
|
||||||
pub fn get_available_monitors() -> Vec<MonitorID> {
|
pub fn get_available_monitors() -> Vec<MonitorID> {
|
||||||
unimplemented!()
|
vec![get_primary_monitor()]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_primary_monitor() -> MonitorID {
|
pub fn get_primary_monitor() -> MonitorID {
|
||||||
unimplemented!()
|
MonitorID(0u)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MonitorID {
|
impl MonitorID {
|
||||||
|
@ -32,14 +35,15 @@ impl MonitorID {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_dimensions(&self) -> (uint, uint) {
|
pub fn get_dimensions(&self) -> (uint, uint) {
|
||||||
unimplemented!()
|
//unimplemented!()
|
||||||
|
// TODO: Get the real dimensions from the monitor
|
||||||
|
(1024, 768)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn new(builder: WindowBuilder) -> Result<Window, String> {
|
pub fn new(builder: WindowBuilder) -> Result<Window, String> {
|
||||||
// TODO: temporary
|
let dimensions = builder.dimensions.unwrap_or((800, 600));
|
||||||
let dimensions = builder.dimensions;
|
|
||||||
|
|
||||||
// calling XOpenDisplay
|
// calling XOpenDisplay
|
||||||
let display = unsafe {
|
let display = unsafe {
|
||||||
|
@ -50,7 +54,9 @@ impl Window {
|
||||||
display
|
display
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: set error handler?
|
let screen_id = unsafe {
|
||||||
|
ffi::XDefaultScreen(display)
|
||||||
|
};
|
||||||
|
|
||||||
// getting the FBConfig
|
// getting the FBConfig
|
||||||
let fb_config = unsafe {
|
let fb_config = unsafe {
|
||||||
|
@ -81,6 +87,31 @@ impl Window {
|
||||||
preferred_fb
|
preferred_fb
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut best_mode = -1;
|
||||||
|
let modes = unsafe {
|
||||||
|
let mut mode_num: libc::c_int = mem::uninitialized();
|
||||||
|
let mut modes: *mut *mut ffi::XF86VidModeModeInfo = mem::uninitialized();
|
||||||
|
if ffi::XF86VidModeGetAllModeLines(display, screen_id, &mut mode_num, &mut modes) == 0 {
|
||||||
|
return Err(format!("Could not query the video modes"));
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in range(0, mode_num) {
|
||||||
|
let mode: ffi::XF86VidModeModeInfo = **modes.offset(i as int);
|
||||||
|
if mode.hdisplay == dimensions.val0() as u16 && mode.vdisplay == dimensions.val1() as u16 {
|
||||||
|
best_mode = i;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if best_mode == -1 {
|
||||||
|
return Err(format!("Could not find a suitable graphics mode"));
|
||||||
|
}
|
||||||
|
|
||||||
|
modes
|
||||||
|
};
|
||||||
|
|
||||||
|
let xf86_desk_mode = unsafe {
|
||||||
|
*modes.offset(0)
|
||||||
|
};
|
||||||
|
|
||||||
// getting the visual infos
|
// getting the visual infos
|
||||||
let visual_infos = unsafe {
|
let visual_infos = unsafe {
|
||||||
let vi = ffi::glXGetVisualFromFBConfig(display, fb_config);
|
let vi = ffi::glXGetVisualFromFBConfig(display, fb_config);
|
||||||
|
@ -109,18 +140,28 @@ impl Window {
|
||||||
swa.colormap = cmap;
|
swa.colormap = cmap;
|
||||||
swa.event_mask = ffi::ExposureMask | ffi::ResizeRedirectMask |
|
swa.event_mask = ffi::ExposureMask | ffi::ResizeRedirectMask |
|
||||||
ffi::VisibilityChangeMask | ffi::KeyPressMask | ffi::PointerMotionMask |
|
ffi::VisibilityChangeMask | ffi::KeyPressMask | ffi::PointerMotionMask |
|
||||||
ffi::KeyPressMask | ffi::KeyReleaseMask | ffi::ButtonPressMask |
|
ffi::KeyReleaseMask | ffi::ButtonPressMask |
|
||||||
ffi::ButtonReleaseMask | ffi::KeymapStateMask;
|
ffi::ButtonReleaseMask | ffi::KeymapStateMask;
|
||||||
|
swa.border_pixel = 0;
|
||||||
|
swa.override_redirect = 0;
|
||||||
swa
|
swa
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut window_attributes = ffi::CWBorderPixel | ffi::CWColormap | ffi:: CWEventMask;
|
||||||
|
if builder.is_fullscreen {
|
||||||
|
window_attributes |= ffi::CWOverrideRedirect;
|
||||||
|
unsafe {
|
||||||
|
ffi::XF86VidModeSwitchToMode(display, screen_id, *modes.offset(best_mode as int));
|
||||||
|
ffi::XF86VidModeSetViewPort(display, screen_id, 0, 0);
|
||||||
|
set_win_attr.override_redirect = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// finally creating the window
|
// finally creating the window
|
||||||
let window = unsafe {
|
let window = unsafe {
|
||||||
let dimensions = dimensions.unwrap_or((800, 600));
|
|
||||||
|
|
||||||
let win = ffi::XCreateWindow(display, root, 50, 50, dimensions.val0() as libc::c_uint,
|
let win = ffi::XCreateWindow(display, root, 50, 50, dimensions.val0() as libc::c_uint,
|
||||||
dimensions.val1() as libc::c_uint, 0, visual_infos.depth, ffi::InputOutput,
|
dimensions.val1() as libc::c_uint, 0, visual_infos.depth, ffi::InputOutput,
|
||||||
visual_infos.visual, ffi::CWColormap | ffi::CWEventMask,
|
visual_infos.visual, window_attributes,
|
||||||
&mut set_win_attr);
|
&mut set_win_attr);
|
||||||
win
|
win
|
||||||
};
|
};
|
||||||
|
@ -208,7 +249,7 @@ impl Window {
|
||||||
create_context_attribs(display, fb_config, ptr::null(), 1,
|
create_context_attribs(display, fb_config, ptr::null(), 1,
|
||||||
attributes.as_ptr())
|
attributes.as_ptr())
|
||||||
} else {
|
} else {
|
||||||
ffi::glXCreateNewContext(display, fb_config, ffi::GLX_RGBA_TYPE, ptr::null(), 1)
|
ffi::glXCreateContext(display, &visual_infos, ptr::null(), 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
if context.is_null() {
|
if context.is_null() {
|
||||||
|
@ -227,6 +268,9 @@ impl Window {
|
||||||
context: context,
|
context: context,
|
||||||
is_closed: AtomicBool::new(false),
|
is_closed: AtomicBool::new(false),
|
||||||
wm_delete_window: wm_delete_window,
|
wm_delete_window: wm_delete_window,
|
||||||
|
xf86_desk_mode: xf86_desk_mode,
|
||||||
|
screen_id: screen_id,
|
||||||
|
is_fullscreen: builder.is_fullscreen,
|
||||||
};
|
};
|
||||||
|
|
||||||
// calling glViewport
|
// calling glViewport
|
||||||
|
@ -457,7 +501,14 @@ impl Window {
|
||||||
|
|
||||||
impl Drop for Window {
|
impl Drop for Window {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
unsafe { ffi::glXMakeCurrent(self.display, 0, ptr::null()); }
|
||||||
unsafe { ffi::glXDestroyContext(self.display, self.context); }
|
unsafe { ffi::glXDestroyContext(self.display, self.context); }
|
||||||
|
|
||||||
|
if self.is_fullscreen {
|
||||||
|
unsafe { ffi::XF86VidModeSwitchToMode(self.display, self.screen_id, self.xf86_desk_mode); }
|
||||||
|
unsafe { ffi::XF86VidModeSetViewPort(self.display, self.screen_id, 0, 0); }
|
||||||
|
}
|
||||||
|
|
||||||
unsafe { ffi::XDestroyIC(self.ic); }
|
unsafe { ffi::XDestroyIC(self.ic); }
|
||||||
unsafe { ffi::XCloseIM(self.im); }
|
unsafe { ffi::XCloseIM(self.im); }
|
||||||
unsafe { ffi::XDestroyWindow(self.display, self.window); }
|
unsafe { ffi::XDestroyWindow(self.display, self.window); }
|
||||||
|
|
Loading…
Reference in a new issue