diff --git a/src/x11/ffi.rs b/src/x11/ffi.rs index 5b35e7b1..39a6ae5f 100644 --- a/src/x11/ffi.rs +++ b/src/x11/ffi.rs @@ -3,33 +3,30 @@ #![allow(non_camel_case_types)] #![allow(non_uppercase_statics)] +pub use self::glx::types::*; use libc; +/// GLX bindings +pub mod glx { + generate_gl_bindings!("glx", "core", "1.4", "static") +} + +/// Functions that are not necessarly always available +pub mod glx_extra { + generate_gl_bindings!("glx", "core", "1.4", "struct", [ "GLX_ARB_create_context" ]) +} + pub type Atom = libc::c_ulong; -pub type Bool = libc::c_int; pub type Colormap = XID; pub type Cursor = XID; -pub type Display = (); pub type Drawable = XID; // TODO: not sure -pub type GLXContext = *const (); -pub type GLXContextID = XID; -pub type GLXDrawable = XID; -pub type GLXFBConfig = *const (); -pub type GLXPbuffer = XID; -pub type GLXPixmap = XID; -pub type GLXWindow = XID; pub type KeyCode = libc::c_ulong; pub type KeySym = XID; pub type OSMesaContext = *const (); -pub type Pixmap = XID; pub type Status = libc::c_int; // TODO: not sure pub type Time = libc::c_ulong; -pub type Visual = (); // TODO: not sure -pub type VisualID = libc::c_ulong; // TODO: not sure -pub type Window = XID; pub type XrmDatabase = *const (); // TODO: not sure pub type XIC = *mut (); -pub type XID = libc::uintptr_t; pub type XIM = *mut (); pub type Screen = (); @@ -1221,19 +1218,6 @@ pub const XK_hebrew_taf: libc::c_uint = 0xcfa; pub const XK_Hebrew_switch: libc::c_uint = 0xFF7E; -#[repr(C)] -pub struct XVisualInfo { - pub visual: *mut Visual, - pub visualid: VisualID, - pub screen: libc::c_int, - pub depth: libc::c_int, - pub class: libc::c_int, - pub red_mask: libc::c_ulong, - pub green_mask: libc::c_ulong, - pub blue_mask: libc::c_ulong, - pub colormap_size: libc::c_int, - pub bits_per_rgb: libc::c_int, -} #[repr(C)] pub struct XSetWindowAttributes { @@ -1440,21 +1424,6 @@ extern "C" { buffer_return: *mut libc::c_char, bytes_buffer: libc::c_int, keysym_return: *mut KeySym, status_return: *mut Status) -> libc::c_int; - pub fn glXCreateContext(dpy: *mut Display, vis: *const XVisualInfo, - shareList: GLXContext, direct: Bool) -> GLXContext; - pub fn glXCreateNewContext(dpy: *mut Display, config: GLXFBConfig, render_type: libc::c_int, - shareList: GLXContext, direct: Bool) -> GLXContext; - pub fn glXDestroyContext(dpy: *mut Display, ctx: GLXContext); - pub fn glXChooseFBConfig(dpy: *mut Display, screen: libc::c_int, - attrib_list: *const libc::c_int, nelements: *mut libc::c_int) -> *mut GLXFBConfig; - pub fn glXChooseVisual(dpy: *mut Display, screen: libc::c_int, - attribList: *const libc::c_int) -> *const XVisualInfo; - pub fn glXGetProcAddress(procName: *const libc::c_uchar) -> *const (); - pub fn glXGetVisualFromFBConfig(dpy: *mut Display, config: GLXFBConfig) -> *mut XVisualInfo; - pub fn glXMakeCurrent(dpy: *mut Display, drawable: GLXDrawable, - ctx: GLXContext) -> Bool; - pub fn glXSwapBuffers(dpy: *mut Display, drawable: GLXDrawable); - pub fn XkbSetDetectableAutoRepeat(dpy: *mut Display, detectable: bool, supported_rtm: *mut bool) -> bool; pub fn XF86VidModeSwitchToMode(dpy: *mut Display, screen: libc::c_int, diff --git a/src/x11/window/mod.rs b/src/x11/window/mod.rs index c7ca7804..ad10e165 100644 --- a/src/x11/window/mod.rs +++ b/src/x11/window/mod.rs @@ -59,10 +59,10 @@ impl Window { let mut num_fb: libc::c_int = mem::uninitialized(); - let fb = ffi::glXChooseFBConfig(display, ffi::XDefaultScreen(display), + let fb = ffi::glx::ChooseFBConfig(display, ffi::XDefaultScreen(display), VISUAL_ATTRIBUTES.as_ptr(), &mut num_fb); if fb.is_null() { - return Err(format!("glXChooseFBConfig failed")); + return Err(format!("glx::ChooseFBConfig failed")); } let preferred_fb = *fb; // TODO: choose more wisely ffi::XFree(fb as *const libc::c_void); @@ -95,10 +95,10 @@ impl Window { }; // getting the visual infos - let visual_infos = unsafe { - let vi = ffi::glXGetVisualFromFBConfig(display, fb_config); + let mut visual_infos = unsafe { + let vi = ffi::glx::GetVisualFromFBConfig(display, fb_config); if vi.is_null() { - return Err(format!("glXChooseVisual failed")); + return Err(format!("glx::ChooseVisual failed")); } let vi_copy = *vi; ffi::XFree(vi as *const libc::c_void); @@ -162,23 +162,6 @@ impl Window { wm_delete_window }; - // getting the pointer to glXCreateContextAttribs - let create_context_attribs = unsafe { - let mut addr = ffi::glXGetProcAddress(b"glXCreateContextAttribs".as_ptr() - as *const u8) as *const (); - - if addr.is_null() { - addr = ffi::glXGetProcAddress(b"glXCreateContextAttribsARB".as_ptr() - as *const u8) as *const (); - } - - addr.as_ref().map(|addr| { - let addr: extern "system" fn(*mut ffi::Display, ffi::GLXFBConfig, ffi::GLXContext, - ffi::Bool, *const libc::c_int) -> ffi::GLXContext = mem::transmute(addr); - addr - }) - }; - // creating IM let im = unsafe { let im = ffi::XOpenIM(display, ptr::null(), ptr::null_mut(), ptr::null_mut()); @@ -226,12 +209,19 @@ impl Window { attributes.push(0); - let context = if create_context_attribs.is_some() { - let create_context_attribs = create_context_attribs.unwrap(); - create_context_attribs(display, fb_config, ptr::null(), 1, - attributes.as_ptr()) + // loading the extra GLX functions + let extra_functions = ffi::glx_extra::Glx::load_with(|addr| { + addr.with_c_str(|s| { + use libc; + ffi::glx::GetProcAddress(s as *const u8) as *const libc::c_void + }) + }); + + let context = if extra_functions.CreateContextAttribsARB.is_loaded() { + extra_functions.CreateContextAttribsARB(display as *mut ffi::glx_extra::types::Display, + fb_config, ptr::null(), 1, attributes.as_ptr()) } else { - ffi::glXCreateContext(display, &visual_infos, ptr::null(), 1) + ffi::glx::CreateContext(display, &mut visual_infos, ptr::null(), 1) }; if context.is_null() { @@ -459,9 +449,9 @@ impl Window { } pub unsafe fn make_current(&self) { - let res = ffi::glXMakeCurrent(self.display, self.window, self.context); + let res = ffi::glx::MakeCurrent(self.display, self.window, self.context); if res == 0 { - fail!("glXMakeCurrent failed"); + fail!("glx::MakeCurrent failed"); } } @@ -471,20 +461,20 @@ impl Window { unsafe { addr.with_c_str(|s| { - ffi::glXGetProcAddress(mem::transmute(s)) as *const () + ffi::glx::GetProcAddress(mem::transmute(s)) as *const () }) } } pub fn swap_buffers(&self) { - unsafe { ffi::glXSwapBuffers(self.display, self.window) } + unsafe { ffi::glx::SwapBuffers(self.display, self.window) } } } impl Drop for Window { fn drop(&mut self) { - unsafe { ffi::glXMakeCurrent(self.display, 0, ptr::null()); } - unsafe { ffi::glXDestroyContext(self.display, self.context); } + unsafe { ffi::glx::MakeCurrent(self.display, 0, ptr::null()); } + unsafe { ffi::glx::DestroyContext(self.display, self.context); } if self.is_fullscreen { unsafe { ffi::XF86VidModeSwitchToMode(self.display, self.screen_id, self.xf86_desk_mode); }