From 0fa5e541e8e11eb0ee47f9679e3a1e755e7c975a Mon Sep 17 00:00:00 2001 From: Ryan Stewart Date: Mon, 16 Mar 2015 13:51:15 -0700 Subject: handle retain/release on cocoa objects --- src/cocoa/mod.rs | 134 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 92 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/cocoa/mod.rs b/src/cocoa/mod.rs index ee3b03f..5aa34fa 100644 --- a/src/cocoa/mod.rs +++ b/src/cocoa/mod.rs @@ -29,6 +29,7 @@ use std::str::FromStr; use std::str::from_utf8; use std::sync::Mutex; use std::ascii::AsciiExt; +use std::ops::Deref; use events::Event::{MouseInput, MouseMoved, ReceivedCharacter, KeyboardInput, MouseWheel}; use events::ElementState::{Pressed, Released}; @@ -50,9 +51,9 @@ static mut alt_pressed: bool = false; struct DelegateState { is_closed: bool, - context: id, - view: id, - window: id, + context: IdRef, + view: IdRef, + window: IdRef, handler: Option, } @@ -89,11 +90,11 @@ impl WindowDelegate { let state = &mut *delegate.get_state(); mem::forget(delegate); - let _: id = msg_send()(state.context, selector("update")); + let _: id = msg_send()(*state.context, selector("update")); if let Some(handler) = state.handler { - let rect = NSView::frame(state.view); - let scale_factor = NSWindow::backingScaleFactor(state.window) as f32; + let rect = NSView::frame(*state.view); + let scale_factor = NSWindow::backingScaleFactor(*state.window) as f32; (handler)((scale_factor * rect.size.width as f32) as u32, (scale_factor * rect.size.height as f32) as u32); } @@ -160,9 +161,9 @@ impl WindowDelegate { } pub struct Window { - view: id, - window: id, - context: id, + view: IdRef, + window: IdRef, + context: IdRef, delegate: WindowDelegate, resize: Option, @@ -221,9 +222,9 @@ impl<'a> Iterator for PollEventsIterator<'a> { // to the user application, by passing handler through to the delegate state. let mut ds = DelegateState { is_closed: self.window.is_closed.get(), - context: self.window.context, - window: self.window.window, - view: self.window.view, + context: self.window.context.clone(), + window: self.window.window.clone(), + view: self.window.view.clone(), handler: self.window.resize, }; self.window.delegate.set_state(&mut ds); @@ -249,7 +250,7 @@ impl<'a> Iterator for PollEventsIterator<'a> { } else { self.window.view.convertPoint_fromView_(window_point, nil) }; - let view_rect = NSView::frame(self.window.view); + let view_rect = NSView::frame(*self.window.view); let scale_factor = self.window.hidpi_factor(); Some(MouseMoved(((scale_factor * view_point.x as f32) as i32, (scale_factor * (view_rect.size.height - view_point.y) as f32) as i32))) @@ -356,12 +357,12 @@ impl Window { Some(window) => window, None => { return Err(OsError(format!("Couldn't create NSWindow"))); }, }; - let view = match Window::create_view(window) { + let view = match Window::create_view(*window) { Some(view) => view, None => { return Err(OsError(format!("Couldn't create NSView"))); }, }; - let context = match Window::create_context(view, builder.vsync, builder.gl_version) { + let context = match Window::create_context(*view, builder.vsync, builder.gl_version) { Some(context) => context, None => { return Err(OsError(format!("Couldn't create OpenGL context"))); }, }; @@ -375,11 +376,12 @@ impl Window { } } + let window_id = *window; let window = Window { view: view, window: window, context: context, - delegate: WindowDelegate::new(window), + delegate: WindowDelegate::new(window_id), resize: None, is_closed: Cell::new(false), @@ -402,7 +404,7 @@ impl Window { } } - fn create_window(dimensions: (u32, u32), title: &str, monitor: Option) -> Option { + fn create_window(dimensions: (u32, u32), title: &str, monitor: Option) -> Option { unsafe { let frame = if monitor.is_some() { let screen = NSScreen::mainScreen(nil); @@ -421,18 +423,18 @@ impl Window { NSResizableWindowMask as NSUInteger }; - let window = NSWindow::alloc(nil).initWithContentRect_styleMask_backing_defer_( + let window = IdRef::new(NSWindow::alloc(nil).initWithContentRect_styleMask_backing_defer_( frame, masks, NSBackingStoreBuffered, NO, - ); + )); - if window == nil { + if *window == nil { None } else { - let title = NSString::alloc(nil).init_str(title); - window.setTitle_(title); + let title = IdRef::new(NSString::alloc(nil).init_str(title)); + window.setTitle_(*title); window.setAcceptsMouseMovedEvents_(YES); if monitor.is_some() { window.setLevel_(NSMainMenuWindowLevel as i64 + 1); @@ -445,20 +447,20 @@ impl Window { } } - fn create_view(window: id) -> Option { + fn create_view(window: id) -> Option { unsafe { - let view = NSView::alloc(nil).init(); - if view == nil { + let view = IdRef::new(NSView::alloc(nil).init()); + if *view == nil { None } else { view.setWantsBestResolutionOpenGLSurface_(YES); - window.setContentView_(view); + window.setContentView_(*view); Some(view) } } } - fn create_context(view: id, vsync: bool, gl_version: GlRequest) -> Option { + fn create_context(view: id, vsync: bool, gl_version: GlRequest) -> Option { let profile = match gl_version { GlRequest::Latest => NSOpenGLProfileVersion4_1Core as u32, GlRequest::Specific(Api::OpenGl, (1 ... 2, _)) => NSOpenGLProfileVersionLegacy as u32, @@ -483,13 +485,13 @@ impl Window { 0 ]; - let pixelformat = NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(&attributes); - if pixelformat == nil { + let pixelformat = IdRef::new(NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(&attributes)); + if *pixelformat == nil { return None; } - let context = NSOpenGLContext::alloc(nil).initWithFormat_shareContext_(pixelformat, nil); - if context == nil { + let context = IdRef::new(NSOpenGLContext::alloc(nil).initWithFormat_shareContext_(*pixelformat, nil)); + if *context == nil { None } else { context.setView_(view); @@ -508,22 +510,22 @@ impl Window { pub fn set_title(&self, title: &str) { unsafe { - let title = NSString::alloc(nil).init_str(title); - self.window.setTitle_(title); + let title = IdRef::new(NSString::alloc(nil).init_str(title)); + self.window.setTitle_(*title); } } pub fn show(&self) { - unsafe { NSWindow::makeKeyAndOrderFront_(self.window, nil); } + unsafe { NSWindow::makeKeyAndOrderFront_(*self.window, nil); } } pub fn hide(&self) { - unsafe { NSWindow::orderOut_(self.window, nil); } + unsafe { NSWindow::orderOut_(*self.window, nil); } } pub fn get_position(&self) -> Option<(i32, i32)> { unsafe { - let content_rect = NSWindow::contentRectForFrameRect_(self.window, NSWindow::frame(self.window)); + let content_rect = NSWindow::contentRectForFrameRect_(*self.window, NSWindow::frame(*self.window)); // NOTE: coordinate system might be inconsistent with other backends Some((content_rect.origin.x as i32, content_rect.origin.y as i32)) } @@ -532,27 +534,27 @@ impl Window { pub fn set_position(&self, x: i32, y: i32) { unsafe { // NOTE: coordinate system might be inconsistent with other backends - NSWindow::setFrameOrigin_(self.window, NSPoint::new(x as f64, y as f64)); + NSWindow::setFrameOrigin_(*self.window, NSPoint::new(x as f64, y as f64)); } } pub fn get_inner_size(&self) -> Option<(u32, u32)> { unsafe { - let view_frame = NSView::frame(self.view); + let view_frame = NSView::frame(*self.view); Some((view_frame.size.width as u32, view_frame.size.height as u32)) } } pub fn get_outer_size(&self) -> Option<(u32, u32)> { unsafe { - let window_frame = NSWindow::frame(self.window); + let window_frame = NSWindow::frame(*self.window); Some((window_frame.size.width as u32, window_frame.size.height as u32)) } } pub fn set_inner_size(&self, width: u32, height: u32) { unsafe { - NSWindow::setContentSize_(self.window, NSSize::new(width as f64, height as f64)); + NSWindow::setContentSize_(*self.window, NSSize::new(width as f64, height as f64)); } } @@ -583,7 +585,7 @@ impl Window { } pub unsafe fn make_current(&self) { - let _: id = msg_send()(self.context, selector("update")); + let _: id = msg_send()(*self.context, selector("update")); self.context.makeCurrentContext(); } @@ -661,7 +663,7 @@ impl Window { pub fn hidpi_factor(&self) -> f32 { unsafe { - NSWindow::backingScaleFactor(self.window) as f32 + NSWindow::backingScaleFactor(*self.window) as f32 } } @@ -669,3 +671,51 @@ impl Window { unimplemented!(); } } + +struct IdRef(id); + +impl IdRef { + fn new(i: id) -> IdRef { + IdRef(i) + } + + fn retain(i: id) -> IdRef { + unsafe { msg_send::<()>()(i, selector("retain")) }; + IdRef(i) + } +} + +impl Drop for IdRef { + fn drop(&mut self) { + if self.0 != nil { + unsafe { msg_send::<()>()(self.0, selector("release")) }; + } + } +} + +impl Deref for IdRef { + type Target = id; + fn deref<'a>(&'a self) -> &'a id { + &self.0 + } +} + +impl Clone for IdRef { + fn clone(&self) -> IdRef { + if self.0 != nil { + unsafe { msg_send::<()>()(self.0, selector("retain")) }; + } + IdRef(self.0) + } + + fn clone_from(&mut self, source: &IdRef) { + if source.0 != nil { + unsafe { msg_send::<()>()(source.0, selector("retain")) }; + } + if self.0 != nil { + unsafe { msg_send::<()>()(self.0, selector("release")) }; + } + self.0 = source.0; + } +} + -- cgit v1.2.3 From 9914d826b8c79f81c5ae4418b827da51d2bf4a4f Mon Sep 17 00:00:00 2001 From: Ryan Stewart Date: Mon, 16 Mar 2015 13:52:58 -0700 Subject: expose platform-native monitor identifier --- src/android/mod.rs | 5 +++++ src/cocoa/monitor.rs | 6 ++++++ src/lib.rs | 2 +- src/win32/monitor.rs | 7 +++++++ src/window.rs | 19 +++++++++++++++++++ src/x11/window/monitor.rs | 5 +++++ 6 files changed, 43 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/android/mod.rs b/src/android/mod.rs index 7979f09..c75878b 100644 --- a/src/android/mod.rs +++ b/src/android/mod.rs @@ -14,6 +14,7 @@ use std::collections::VecDeque; use Api; use BuilderAttribs; use GlRequest; +use NativeMonitorID; pub struct Window { display: ffi::egl::types::EGLDisplay, @@ -41,6 +42,10 @@ impl MonitorID { Some("Primary".to_string()) } + pub fn get_native_identifier(&self) -> NativeMonitorID { + NativeMonitorID::Unavailable + } + pub fn get_dimensions(&self) -> (u32, u32) { unimplemented!() } diff --git a/src/cocoa/monitor.rs b/src/cocoa/monitor.rs index 47adc03..1902f6a 100644 --- a/src/cocoa/monitor.rs +++ b/src/cocoa/monitor.rs @@ -1,5 +1,6 @@ use core_graphics::display; use std::collections::VecDeque; +use window::NativeMonitorID; pub struct MonitorID(u32); @@ -35,6 +36,11 @@ impl MonitorID { Some(format!("Monitor #{}", screen_num)) } + pub fn get_native_identifier(&self) -> NativeMonitorID { + let MonitorID(display_id) = *self; + NativeMonitorID::Numeric(display_id) + } + pub fn get_dimensions(&self) -> (u32, u32) { let MonitorID(display_id) = *self; let dimension = unsafe { diff --git a/src/lib.rs b/src/lib.rs index 916b699..20bd723 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,7 +50,7 @@ pub use headless::{HeadlessRendererBuilder, HeadlessContext}; #[cfg(feature = "window")] pub use window::{WindowBuilder, Window, WindowProxy, PollEventsIterator, WaitEventsIterator}; #[cfg(feature = "window")] -pub use window::{AvailableMonitorsIter, MonitorID, get_available_monitors, get_primary_monitor}; +pub use window::{AvailableMonitorsIter, NativeMonitorID, MonitorID, get_available_monitors, get_primary_monitor}; #[cfg(all(not(target_os = "windows"), not(target_os = "linux"), not(target_os = "macos"), not(target_os = "android")))] use this_platform_is_not_supported; diff --git a/src/win32/monitor.rs b/src/win32/monitor.rs index fc9f20d..5fbd5dd 100644 --- a/src/win32/monitor.rs +++ b/src/win32/monitor.rs @@ -3,6 +3,8 @@ use user32; use std::collections::VecDeque; +use NativeMonitorID; + /// Win32 implementation of the main `MonitorID` object. pub struct MonitorID { /// The system name of the monitor. @@ -113,6 +115,11 @@ impl MonitorID { Some(self.readable_name.clone()) } + /// See the docs of the crate root file. + pub fn get_native_identifier(&self) -> NativeMonitorID { + NativeMonitorID::Name(self.readable_name.clone()) + } + /// See the docs if the crate root file. pub fn get_dimensions(&self) -> (u32, u32) { // TODO: retreive the dimensions every time this is called diff --git a/src/window.rs b/src/window.rs index 56af494..4b02874 100644 --- a/src/window.rs +++ b/src/window.rs @@ -500,6 +500,19 @@ pub fn get_primary_monitor() -> MonitorID { MonitorID(winimpl::get_primary_monitor()) } +/// Native platform identifier for a monitor. Different platforms use fundamentally different types +/// to represent a monitor ID. +pub enum NativeMonitorID { + /// Cocoa and X11 use a numeric identifier to represent a monitor. + Numeric(u32), + + /// Win32 uses a Unicode string to represent a monitor. + Name(String), + + /// Other platforms (Android) don't support monitor identification. + Unavailable +} + /// Identifier for a monitor. pub struct MonitorID(winimpl::MonitorID); @@ -510,6 +523,12 @@ impl MonitorID { id.get_name() } + /// Returns the native platform identifier for this monitor. + pub fn get_native_identifier(&self) -> NativeMonitorID { + let &MonitorID(ref id) = self; + id.get_native_identifier() + } + /// Returns the number of pixels currently displayed on the monitor. pub fn get_dimensions(&self) -> (u32, u32) { let &MonitorID(ref id) = self; diff --git a/src/x11/window/monitor.rs b/src/x11/window/monitor.rs index 77ac4ec..a99f2f2 100644 --- a/src/x11/window/monitor.rs +++ b/src/x11/window/monitor.rs @@ -43,6 +43,11 @@ impl MonitorID { Some(format!("Monitor #{}", screen_num)) } + pub fn get_native_identifier(&self) -> NativeMonitorID { + let MonitorID(screen_num) = *self; + NativeMonitorID::Numeric(screen_num) + } + pub fn get_dimensions(&self) -> (u32, u32) { let dimensions = unsafe { let display = ffi::XOpenDisplay(ptr::null()); -- cgit v1.2.3 From 70776fab411a6b8f1b36d1f450b8cf9b56cfbd23 Mon Sep 17 00:00:00 2001 From: Ryan Stewart Date: Mon, 16 Mar 2015 14:09:45 -0700 Subject: honor the passed-in MonitorID when using with_fullscreen() in cocoa backend --- src/cocoa/mod.rs | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/cocoa/mod.rs b/src/cocoa/mod.rs index 5aa34fa..825f6f3 100644 --- a/src/cocoa/mod.rs +++ b/src/cocoa/mod.rs @@ -8,6 +8,7 @@ use libc; use Api; use BuilderAttribs; use GlRequest; +use NativeMonitorID; use cocoa::base::{Class, id, YES, NO, NSUInteger, nil, objc_allocateClassPair, class, objc_registerClassPair}; use cocoa::base::{selector, msg_send, msg_send_stret, class_addMethod, class_addIvar}; @@ -406,15 +407,41 @@ impl Window { fn create_window(dimensions: (u32, u32), title: &str, monitor: Option) -> Option { unsafe { - let frame = if monitor.is_some() { - let screen = NSScreen::mainScreen(nil); - NSScreen::frame(screen) - } else { - let (width, height) = dimensions; - NSRect::new(NSPoint::new(0., 0.), NSSize::new(width as f64, height as f64)) + let screen = monitor.map(|monitor_id| { + let native_id = match monitor_id.get_native_identifier() { + NativeMonitorID::Numeric(num) => num, + _ => panic!("OS X monitors should always have a numeric native ID") + }; + let matching_screen = { + let screens = NSScreen::screens(nil); + let count: NSUInteger = msg_send()(screens, selector("count")); + let key = IdRef::new(NSString::alloc(nil).init_str("NSScreenNumber")); + let mut matching_screen: Option = None; + for i in range(0, count) { + let screen = msg_send()(screens, selector("objectAtIndex:"), i as NSUInteger); + let device_description = NSScreen::deviceDescription(screen); + let value = msg_send()(device_description, selector("objectForKey:"), *key); + if value != nil { + let screen_number: NSUInteger = msg_send()(value, selector("unsignedIntValue")); + if screen_number as u32 == native_id { + matching_screen = Some(screen); + break; + } + } + } + matching_screen + }; + matching_screen.unwrap_or(NSScreen::mainScreen(nil)) + }); + let frame = match screen { + Some(screen) => NSScreen::frame(screen), + None => { + let (width, height) = dimensions; + NSRect::new(NSPoint::new(0., 0.), NSSize::new(width as f64, height as f64)) + } }; - let masks = if monitor.is_some() { + let masks = if screen.is_some() { NSBorderlessWindowMask as NSUInteger } else { NSTitledWindowMask as NSUInteger | @@ -436,7 +463,7 @@ impl Window { let title = IdRef::new(NSString::alloc(nil).init_str(title)); window.setTitle_(*title); window.setAcceptsMouseMovedEvents_(YES); - if monitor.is_some() { + if screen.is_some() { window.setLevel_(NSMainMenuWindowLevel as i64 + 1); } else { -- cgit v1.2.3 From 9cecb7ee558579f0b4ede97c53e3d7824a9810b6 Mon Sep 17 00:00:00 2001 From: Ryan Stewart Date: Mon, 16 Mar 2015 14:10:54 -0700 Subject: implement Window is_current() for cocoa backend --- src/cocoa/mod.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cocoa/mod.rs b/src/cocoa/mod.rs index 825f6f3..22ec4b4 100644 --- a/src/cocoa/mod.rs +++ b/src/cocoa/mod.rs @@ -617,7 +617,15 @@ impl Window { } pub fn is_current(&self) -> bool { - unimplemented!() + unsafe { + let current = NSOpenGLContext::currentContext(nil); + if current != nil { + let is_equal: bool = msg_send()(current, selector("isEqual:"), *self.context); + is_equal + } else { + false + } + } } pub fn get_proc_address(&self, _addr: &str) -> *const () { -- cgit v1.2.3 From 779f3ce888e0009bdbd14bc28a1e475b46df83ee Mon Sep 17 00:00:00 2001 From: Ryan Stewart Date: Mon, 16 Mar 2015 15:43:33 -0700 Subject: fix X11 build issue due to missing import --- src/x11/window/monitor.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/x11/window/monitor.rs b/src/x11/window/monitor.rs index a99f2f2..c1a4897 100644 --- a/src/x11/window/monitor.rs +++ b/src/x11/window/monitor.rs @@ -2,6 +2,7 @@ use std::ptr; use std::collections::VecDeque; use super::super::ffi; use super::ensure_thread_init; +use window::NativeMonitorID; pub struct MonitorID(pub u32); -- cgit v1.2.3 From 1b2fd6e6d01788922a90cd4e58adf371007f50a8 Mon Sep 17 00:00:00 2001 From: Ryan Stewart Date: Wed, 18 Mar 2015 14:16:35 -0700 Subject: fix headless build by ensuring NativeMonitorId enum is available internally even without the window feature; add Eq/PartialEq to NativeMonitorId --- src/android/mod.rs | 6 +++--- src/cocoa/mod.rs | 4 ++-- src/cocoa/monitor.rs | 6 +++--- src/lib.rs | 21 ++++++++++++++++++++- src/win32/monitor.rs | 6 +++--- src/window.rs | 16 ++-------------- src/x11/window/monitor.rs | 6 +++--- 7 files changed, 36 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/android/mod.rs b/src/android/mod.rs index c75878b..71dae54 100644 --- a/src/android/mod.rs +++ b/src/android/mod.rs @@ -14,7 +14,7 @@ use std::collections::VecDeque; use Api; use BuilderAttribs; use GlRequest; -use NativeMonitorID; +use native_monitor::NativeMonitorId; pub struct Window { display: ffi::egl::types::EGLDisplay, @@ -42,8 +42,8 @@ impl MonitorID { Some("Primary".to_string()) } - pub fn get_native_identifier(&self) -> NativeMonitorID { - NativeMonitorID::Unavailable + pub fn get_native_identifier(&self) -> NativeMonitorId { + NativeMonitorId::Unavailable } pub fn get_dimensions(&self) -> (u32, u32) { diff --git a/src/cocoa/mod.rs b/src/cocoa/mod.rs index 22ec4b4..f4b2726 100644 --- a/src/cocoa/mod.rs +++ b/src/cocoa/mod.rs @@ -8,7 +8,7 @@ use libc; use Api; use BuilderAttribs; use GlRequest; -use NativeMonitorID; +use native_monitor::NativeMonitorId; use cocoa::base::{Class, id, YES, NO, NSUInteger, nil, objc_allocateClassPair, class, objc_registerClassPair}; use cocoa::base::{selector, msg_send, msg_send_stret, class_addMethod, class_addIvar}; @@ -409,7 +409,7 @@ impl Window { unsafe { let screen = monitor.map(|monitor_id| { let native_id = match monitor_id.get_native_identifier() { - NativeMonitorID::Numeric(num) => num, + NativeMonitorId::Numeric(num) => num, _ => panic!("OS X monitors should always have a numeric native ID") }; let matching_screen = { diff --git a/src/cocoa/monitor.rs b/src/cocoa/monitor.rs index 1902f6a..bf15665 100644 --- a/src/cocoa/monitor.rs +++ b/src/cocoa/monitor.rs @@ -1,6 +1,6 @@ use core_graphics::display; use std::collections::VecDeque; -use window::NativeMonitorID; +use native_monitor::NativeMonitorId; pub struct MonitorID(u32); @@ -36,9 +36,9 @@ impl MonitorID { Some(format!("Monitor #{}", screen_num)) } - pub fn get_native_identifier(&self) -> NativeMonitorID { + pub fn get_native_identifier(&self) -> NativeMonitorId { let MonitorID(display_id) = *self; - NativeMonitorID::Numeric(display_id) + NativeMonitorId::Numeric(display_id) } pub fn get_dimensions(&self) -> (u32, u32) { diff --git a/src/lib.rs b/src/lib.rs index 20bd723..76f9fde 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,7 +50,9 @@ pub use headless::{HeadlessRendererBuilder, HeadlessContext}; #[cfg(feature = "window")] pub use window::{WindowBuilder, Window, WindowProxy, PollEventsIterator, WaitEventsIterator}; #[cfg(feature = "window")] -pub use window::{AvailableMonitorsIter, NativeMonitorID, MonitorID, get_available_monitors, get_primary_monitor}; +pub use window::{AvailableMonitorsIter, MonitorID, get_available_monitors, get_primary_monitor}; +#[cfg(feature = "window")] +pub use native_monitor::NativeMonitorId; #[cfg(all(not(target_os = "windows"), not(target_os = "linux"), not(target_os = "macos"), not(target_os = "android")))] use this_platform_is_not_supported; @@ -322,3 +324,20 @@ impl<'a> BuilderAttribs<'a> { .expect("Could not find compliant pixel format") } } + +mod native_monitor { + /// Native platform identifier for a monitor. Different platforms use fundamentally different types + /// to represent a monitor ID. + #[derive(PartialEq, Eq)] + pub enum NativeMonitorId { + /// Cocoa and X11 use a numeric identifier to represent a monitor. + Numeric(u32), + + /// Win32 uses a Unicode string to represent a monitor. + Name(String), + + /// Other platforms (Android) don't support monitor identification. + Unavailable + } +} + diff --git a/src/win32/monitor.rs b/src/win32/monitor.rs index 5fbd5dd..819aa7f 100644 --- a/src/win32/monitor.rs +++ b/src/win32/monitor.rs @@ -3,7 +3,7 @@ use user32; use std::collections::VecDeque; -use NativeMonitorID; +use native_monitor::NativeMonitorId; /// Win32 implementation of the main `MonitorID` object. pub struct MonitorID { @@ -116,8 +116,8 @@ impl MonitorID { } /// See the docs of the crate root file. - pub fn get_native_identifier(&self) -> NativeMonitorID { - NativeMonitorID::Name(self.readable_name.clone()) + pub fn get_native_identifier(&self) -> NativeMonitorId { + NativeMonitorId::Name(self.readable_name.clone()) } /// See the docs if the crate root file. diff --git a/src/window.rs b/src/window.rs index 4b02874..5cb6e5e 100644 --- a/src/window.rs +++ b/src/window.rs @@ -7,6 +7,7 @@ use CreationError; use Event; use GlRequest; use MouseCursor; +use native_monitor::NativeMonitorId; use gl_common; use libc; @@ -500,19 +501,6 @@ pub fn get_primary_monitor() -> MonitorID { MonitorID(winimpl::get_primary_monitor()) } -/// Native platform identifier for a monitor. Different platforms use fundamentally different types -/// to represent a monitor ID. -pub enum NativeMonitorID { - /// Cocoa and X11 use a numeric identifier to represent a monitor. - Numeric(u32), - - /// Win32 uses a Unicode string to represent a monitor. - Name(String), - - /// Other platforms (Android) don't support monitor identification. - Unavailable -} - /// Identifier for a monitor. pub struct MonitorID(winimpl::MonitorID); @@ -524,7 +512,7 @@ impl MonitorID { } /// Returns the native platform identifier for this monitor. - pub fn get_native_identifier(&self) -> NativeMonitorID { + pub fn get_native_identifier(&self) -> NativeMonitorId { let &MonitorID(ref id) = self; id.get_native_identifier() } diff --git a/src/x11/window/monitor.rs b/src/x11/window/monitor.rs index c1a4897..44c5e84 100644 --- a/src/x11/window/monitor.rs +++ b/src/x11/window/monitor.rs @@ -2,7 +2,7 @@ use std::ptr; use std::collections::VecDeque; use super::super::ffi; use super::ensure_thread_init; -use window::NativeMonitorID; +use native_monitor::NativeMonitorId; pub struct MonitorID(pub u32); @@ -44,9 +44,9 @@ impl MonitorID { Some(format!("Monitor #{}", screen_num)) } - pub fn get_native_identifier(&self) -> NativeMonitorID { + pub fn get_native_identifier(&self) -> NativeMonitorId { let MonitorID(screen_num) = *self; - NativeMonitorID::Numeric(screen_num) + NativeMonitorId::Numeric(screen_num) } pub fn get_dimensions(&self) -> (u32, u32) { -- cgit v1.2.3 From cf630ec0416d89bde9fcc6d8bd3674a7c55ac1a5 Mon Sep 17 00:00:00 2001 From: Ryan Stewart Date: Wed, 18 Mar 2015 14:49:16 -0700 Subject: add and use IdRef::non_nil() instead of doing deref'd comparisons against nil --- src/cocoa/mod.rs | 51 ++++++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/cocoa/mod.rs b/src/cocoa/mod.rs index f4b2726..62eedc6 100644 --- a/src/cocoa/mod.rs +++ b/src/cocoa/mod.rs @@ -456,10 +456,7 @@ impl Window { NSBackingStoreBuffered, NO, )); - - if *window == nil { - None - } else { + window.non_nil().map(|window| { let title = IdRef::new(NSString::alloc(nil).init_str(title)); window.setTitle_(*title); window.setAcceptsMouseMovedEvents_(YES); @@ -469,21 +466,19 @@ impl Window { else { window.center(); } - Some(window) - } + window + }) } } fn create_view(window: id) -> Option { unsafe { let view = IdRef::new(NSView::alloc(nil).init()); - if *view == nil { - None - } else { + view.non_nil().map(|view| { view.setWantsBestResolutionOpenGLSurface_(YES); window.setContentView_(*view); - Some(view) - } + view + }) } } @@ -513,21 +508,17 @@ impl Window { ]; let pixelformat = IdRef::new(NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(&attributes)); - if *pixelformat == nil { - return None; - } - - let context = IdRef::new(NSOpenGLContext::alloc(nil).initWithFormat_shareContext_(*pixelformat, nil)); - if *context == nil { - None - } else { - context.setView_(view); - if vsync { - let value = 1; - context.setValues_forParameter_(&value, NSOpenGLContextParameter::NSOpenGLCPSwapInterval); - } - Some(context) - } + pixelformat.non_nil().map(|pixelformat| { + let context = IdRef::new(NSOpenGLContext::alloc(nil).initWithFormat_shareContext_(*pixelformat, nil)); + context.non_nil().map(|context| { + context.setView_(view); + if vsync { + let value = 1; + context.setValues_forParameter_(&value, NSOpenGLContextParameter::NSOpenGLCPSwapInterval); + } + context + }) + }).unwrap_or(None) } } @@ -715,9 +706,15 @@ impl IdRef { } fn retain(i: id) -> IdRef { - unsafe { msg_send::<()>()(i, selector("retain")) }; + if i != nil { + unsafe { msg_send::<()>()(i, selector("retain")) }; + } IdRef(i) } + + fn non_nil(self) -> Option { + if self.0 == nil { None } else { Some(self) } + } } impl Drop for IdRef { -- cgit v1.2.3