aboutsummaryrefslogtreecommitdiffstats
path: root/src/api/cocoa
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/cocoa')
-rw-r--r--src/api/cocoa/headless.rs8
-rw-r--r--src/api/cocoa/mod.rs77
2 files changed, 59 insertions, 26 deletions
diff --git a/src/api/cocoa/headless.rs b/src/api/cocoa/headless.rs
index 7cd0f88..f9bbffd 100644
--- a/src/api/cocoa/headless.rs
+++ b/src/api/cocoa/headless.rs
@@ -1,8 +1,9 @@
use ContextError;
use CreationError;
use CreationError::OsError;
-use BuilderAttribs;
+use GlAttributes;
use GlContext;
+use PixelFormatRequirements;
use libc;
use std::ptr;
@@ -27,8 +28,9 @@ pub struct HeadlessContext {
}
impl HeadlessContext {
- pub fn new(builder: BuilderAttribs) -> Result<HeadlessContext, CreationError> {
- let (width, height) = builder.dimensions.unwrap_or((1024, 768));
+ pub fn new((width, height): (u32, u32), pf_reqs: &PixelFormatRequirements,
+ opengl: &GlAttributes<&HeadlessContext>) -> Result<HeadlessContext, CreationError>
+ {
let context = unsafe {
let attributes = [
NSOpenGLPFAAccelerated as u32,
diff --git a/src/api/cocoa/mod.rs b/src/api/cocoa/mod.rs
index 0314dd3..539545c 100644
--- a/src/api/cocoa/mod.rs
+++ b/src/api/cocoa/mod.rs
@@ -7,13 +7,15 @@ use CreationError::OsError;
use libc;
use Api;
-use BuilderAttribs;
use ContextError;
+use GlAttributes;
use GlContext;
use GlProfile;
use GlRequest;
use PixelFormat;
+use PixelFormatRequirements;
use Robustness;
+use WindowAttributes;
use native_monitor::NativeMonitorId;
use objc::runtime::{Class, Object, Sel, BOOL, YES, NO};
@@ -44,7 +46,7 @@ use std::sync::Mutex;
use std::ascii::AsciiExt;
use std::ops::Deref;
-use events::Event::{Awakened, MouseInput, MouseMoved, ReceivedCharacter, KeyboardInput, MouseWheel, Closed};
+use events::Event::{Awakened, MouseInput, MouseMoved, ReceivedCharacter, KeyboardInput, MouseWheel, Closed, Focused};
use events::ElementState::{Pressed, Released};
use events::MouseButton;
use events;
@@ -105,6 +107,25 @@ impl WindowDelegate {
}
}
+ extern fn window_did_become_key(this: &Object, _: Sel, _: id) {
+ unsafe {
+ // TODO: center the cursor if the window had mouse grab when it
+ // lost focus
+
+ let state: *mut libc::c_void = *this.get_ivar("glutinState");
+ let state = state as *mut DelegateState;
+ (*state).pending_events.lock().unwrap().push_back(Focused(true));
+ }
+ }
+
+ extern fn window_did_resign_key(this: &Object, _: Sel, _: id) {
+ unsafe {
+ let state: *mut libc::c_void = *this.get_ivar("glutinState");
+ let state = state as *mut DelegateState;
+ (*state).pending_events.lock().unwrap().push_back(Focused(false));
+ }
+ }
+
static mut delegate_class: *const Class = 0 as *const Class;
static INIT: Once = ONCE_INIT;
@@ -118,6 +139,11 @@ impl WindowDelegate {
window_should_close as extern fn(&Object, Sel, id) -> BOOL);
decl.add_method(sel!(windowDidResize:),
window_did_resize as extern fn(&Object, Sel, id));
+
+ decl.add_method(sel!(windowDidBecomeKey:),
+ window_did_become_key as extern fn(&Object, Sel, id));
+ decl.add_method(sel!(windowDidResignKey:),
+ window_did_resign_key as extern fn(&Object, Sel, id));
// Store internal state as user data
decl.add_ivar::<*mut libc::c_void>("glutinState");
@@ -242,12 +268,14 @@ impl<'a> Iterator for WaitEventsIterator<'a> {
impl Window {
#[cfg(feature = "window")]
- pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
- if builder.sharing.is_some() {
+ pub fn new(win_attribs: &WindowAttributes, pf_reqs: &PixelFormatRequirements,
+ opengl: &GlAttributes<&Window>) -> Result<Window, CreationError>
+ {
+ if opengl.sharing.is_some() {
unimplemented!()
}
- match builder.gl_robustness {
+ match opengl.robustness {
Robustness::RobustNoResetNotification | Robustness::RobustLoseContextOnReset => {
return Err(CreationError::RobustnessNotSupported);
},
@@ -259,7 +287,7 @@ impl Window {
None => { return Err(OsError(format!("Couldn't create NSApplication"))); },
};
- let window = match Window::create_window(&builder)
+ let window = match Window::create_window(win_attribs)
{
Some(window) => window,
None => { return Err(OsError(format!("Couldn't create NSWindow"))); },
@@ -271,13 +299,13 @@ impl Window {
// TODO: perhaps we should return error from create_context so we can
// determine the cause of failure and possibly recover?
- let (context, pf) = match Window::create_context(*view, &builder) {
+ let (context, pf) = match Window::create_context(*view, pf_reqs, opengl) {
Ok((context, pf)) => (context, pf),
Err(e) => { return Err(OsError(format!("Couldn't create OpenGL context: {}", e))); },
};
unsafe {
- if builder.transparent {
+ if win_attribs.transparent {
let clear_col = {
let cls = Class::get("NSColor").unwrap();
@@ -293,7 +321,7 @@ impl Window {
}
app.activateIgnoringOtherApps_(YES);
- if builder.visible {
+ if win_attribs.visible {
window.makeKeyAndOrderFront_(nil);
} else {
window.makeKeyWindow();
@@ -332,9 +360,9 @@ impl Window {
}
}
- fn create_window(builder: &BuilderAttribs) -> Option<IdRef> {
+ fn create_window(attrs: &WindowAttributes) -> Option<IdRef> {
unsafe {
- let screen = match builder.monitor {
+ let screen = match attrs.monitor {
Some(ref monitor_id) => {
let native_id = match monitor_id.get_native_identifier() {
NativeMonitorId::Numeric(num) => num,
@@ -366,13 +394,14 @@ impl Window {
let frame = match screen {
Some(screen) => NSScreen::frame(screen),
None => {
- let (width, height) = builder.dimensions.unwrap_or((800, 600));
+ let (width, height) = attrs.dimensions.unwrap_or((800, 600));
NSRect::new(NSPoint::new(0., 0.), NSSize::new(width as f64, height as f64))
}
};
- let masks = if screen.is_some() || !builder.decorations {
- NSBorderlessWindowMask as NSUInteger
+ let masks = if screen.is_some() || !attrs.decorations {
+ NSBorderlessWindowMask as NSUInteger |
+ NSResizableWindowMask as NSUInteger
} else {
NSTitledWindowMask as NSUInteger |
NSClosableWindowMask as NSUInteger |
@@ -387,7 +416,7 @@ impl Window {
NO,
));
window.non_nil().map(|window| {
- let title = IdRef::new(NSString::alloc(nil).init_str(&builder.title));
+ let title = IdRef::new(NSString::alloc(nil).init_str(&attrs.title));
window.setTitle_(*title);
window.setAcceptsMouseMovedEvents_(YES);
if screen.is_some() {
@@ -412,8 +441,10 @@ impl Window {
}
}
- fn create_context(view: id, builder: &BuilderAttribs) -> Result<(IdRef, PixelFormat), CreationError> {
- let profile = match (builder.gl_version, builder.gl_version.to_gl_version(), builder.gl_profile) {
+ fn create_context(view: id, pf_reqs: &PixelFormatRequirements, opengl: &GlAttributes<&Window>)
+ -> Result<(IdRef, PixelFormat), CreationError>
+ {
+ let profile = match (opengl.version, opengl.version.to_gl_version(), opengl.profile) {
// Note: we are not using ranges because of a rust bug that should be fixed here:
// https://github.com/rust-lang/rust/pull/27050
@@ -446,16 +477,16 @@ impl Window {
// full color size and hope for the best. Another hiccup is that
// `NSOpenGLPFAColorSize` also includes `NSOpenGLPFAAlphaSize`,
// so we have to account for that as well.
- let alpha_depth = builder.alpha_bits.unwrap_or(8);
- let color_depth = builder.color_bits.unwrap_or(24) + alpha_depth;
+ let alpha_depth = pf_reqs.alpha_bits.unwrap_or(8);
+ let color_depth = pf_reqs.color_bits.unwrap_or(24) + alpha_depth;
let mut attributes = vec![
NSOpenGLPFADoubleBuffer as u32,
NSOpenGLPFAClosestPolicy as u32,
NSOpenGLPFAColorSize as u32, color_depth as u32,
NSOpenGLPFAAlphaSize as u32, alpha_depth as u32,
- NSOpenGLPFADepthSize as u32, builder.depth_bits.unwrap_or(24) as u32,
- NSOpenGLPFAStencilSize as u32, builder.stencil_bits.unwrap_or(8) as u32,
+ NSOpenGLPFADepthSize as u32, pf_reqs.depth_bits.unwrap_or(24) as u32,
+ NSOpenGLPFAStencilSize as u32, pf_reqs.stencil_bits.unwrap_or(8) as u32,
NSOpenGLPFAOpenGLProfile as u32, profile,
];
@@ -466,7 +497,7 @@ impl Window {
attributes.push(NSOpenGLPFAColorFloat as u32);
}
- builder.multisampling.map(|samples| {
+ pf_reqs.multisampling.map(|samples| {
attributes.push(NSOpenGLPFAMultisample as u32);
attributes.push(NSOpenGLPFASampleBuffers as u32); attributes.push(1);
attributes.push(NSOpenGLPFASamples as u32); attributes.push(samples as u32);
@@ -515,7 +546,7 @@ impl Window {
};
cxt.setView_(view);
- let value = if builder.vsync { 1 } else { 0 };
+ let value = if opengl.vsync { 1 } else { 0 };
cxt.setValues_forParameter_(&value, NSOpenGLContextParameter::NSOpenGLCPSwapInterval);
CGLEnable(cxt.CGLContextObj(), kCGLCECrashOnRemovedFunctions);