diff options
-rw-r--r-- | src/x11/ffi.rs | 11 | ||||
-rw-r--r-- | src/x11/mod.rs | 45 |
2 files changed, 54 insertions, 2 deletions
diff --git a/src/x11/ffi.rs b/src/x11/ffi.rs index 2cd147f..d127a27 100644 --- a/src/x11/ffi.rs +++ b/src/x11/ffi.rs @@ -204,6 +204,15 @@ pub static GLX_PBUFFER: libc::c_int = 0x8023; pub static GLX_PBUFFER_HEIGHT: libc::c_int = 0x8040; pub static GLX_PBUFFER_WIDTH: libc::c_int = 0x8041; +pub static GLX_CONTEXT_MAJOR_VERSION: libc::c_int = 0x2091; +pub static GLX_CONTEXT_MINOR_VERSION: libc::c_int = 0x2092; +pub static GLX_CONTEXT_FLAGS: libc::c_int = 0x2094; +pub static GLX_CONTEXT_PROFILE_MASK: libc::c_int = 0x9126; +pub static GLX_CONTEXT_DEBUG_BIT: libc::c_int = 0x0001; +pub static GLX_CONTEXT_FORWARD_COMPATIBLE_BIT: libc::c_int = 0x0002; +pub static GLX_CONTEXT_CORE_PROFILE_BIT: libc::c_int = 0x00000001; +pub static GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT: libc::c_int = 0x00000002; + pub static XIMPreeditArea: libc::c_long = 0x0001; pub static XIMPreeditCallbacks: libc::c_long = 0x0002; pub static XIMPreeditPosition: libc::c_long = 0x0004; @@ -1385,6 +1394,8 @@ extern "C" { 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; diff --git a/src/x11/mod.rs b/src/x11/mod.rs index c384e1a..d2619c9 100644 --- a/src/x11/mod.rs +++ b/src/x11/mod.rs @@ -139,7 +139,24 @@ impl Window { wm_delete_window }; - // creating + // getting the pointer to glXCreateContextAttribs + let create_context_attribs = unsafe { + let mut addr = unsafe { ffi::glXGetProcAddress(b"glXCreateContextAttribs".as_ptr() + as *const u8) } as *const (); + + if addr.is_null() { + addr = unsafe { ffi::glXGetProcAddress(b"glXCreateContextAttribsARB".as_ptr() + as *const u8) } as *const (); + } + + addr.to_option().map(|addr| { + let addr: extern "system" fn(*mut ffi::Display, ffi::GLXFBConfig, ffi::GLXContext, + ffi::Bool, *const libc::c_int) -> ffi::GLXContext = unsafe { mem::transmute(addr) }; + addr + }) + }; + + // creating IM let im = unsafe { let im = ffi::XOpenIM(display, ptr::null(), ptr::mut_null(), ptr::mut_null()); if im.is_null() { @@ -164,7 +181,31 @@ impl Window { // creating GL context let context = unsafe { - ffi::glXCreateContext(display, &visual_infos, ptr::null(), 1) + let mut attributes = Vec::new(); + + if builder.gl_version.is_some() { + let version = builder.gl_version.as_ref().unwrap(); + attributes.push(ffi::GLX_CONTEXT_MAJOR_VERSION); + attributes.push(version.val0() as libc::c_int); + attributes.push(ffi::GLX_CONTEXT_MINOR_VERSION); + attributes.push(version.val1() as libc::c_int); + } + + 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()) + } else { + ffi::glXCreateNewContext(display, fb_config, ffi::GLX_RGBA_TYPE, ptr::null(), 1) + }; + + if context.is_null() { + return Err(format!("GL context creation failed")); + } + + context }; // returning |