From c38110cac77253761afc8cc616f645dc1ec4d3b8 Mon Sep 17 00:00:00 2001 From: David Partouche Date: Sat, 4 Oct 2014 15:49:39 +0200 Subject: Cocoa opens a window with OpenGL context inside --- src/lib.rs | 5 +++ src/osx/mod.rs | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 99 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index 3b1a586..e41d01e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,6 +22,11 @@ #[phase(plugin)] extern crate gl_generator; extern crate libc; +#[cfg(target_os = "macos")] +extern crate cocoa; +#[cfg(target_os = "macos")] +extern crate core_foundation; + pub use events::*; use std::default::Default; diff --git a/src/osx/mod.rs b/src/osx/mod.rs index 6960cc1..99a8b2b 100644 --- a/src/osx/mod.rs +++ b/src/osx/mod.rs @@ -1,12 +1,17 @@ -//! Dummy implementation for OS/X to make gl-init-rs compile on this platform - use {Event, WindowBuilder}; -pub struct Window; +use cocoa::base::{id, NSUInteger, nil}; +use cocoa::appkit::*; -pub struct MonitorID; +use core_foundation::base::TCFType; +use core_foundation::string::CFString; +use core_foundation::bundle::{CFBundleGetBundleWithIdentifier, CFBundleGetFunctionPointerForName}; + +pub struct Window { + context: id, +} -compile_warning!("The OS/X platform is not implemented yet") +pub struct MonitorID; pub fn get_available_monitors() -> Vec { unimplemented!() @@ -18,7 +23,7 @@ pub fn get_primary_monitor() -> MonitorID { impl MonitorID { pub fn get_name(&self) -> Option { - unimplemented!() + unimplemented!() } pub fn get_dimensions(&self) -> (uint, uint) { @@ -28,11 +33,68 @@ impl MonitorID { impl Window { pub fn new(_builder: WindowBuilder) -> Result { - unimplemented!() + let context = unsafe { + // Create the NSApplication + let app = NSApp(); + app.setActivationPolicy_(NSApplicationActivationPolicyRegular); + + app.finishLaunching(); + + // Create the window + let scr_frame = NSRect::new(NSPoint::new(0., 0.), NSSize::new(800., 600.)); + + let window = NSWindow::alloc(nil).initWithContentRect_styleMask_backing_defer_( + scr_frame, + NSTitledWindowMask as NSUInteger | NSClosableWindowMask as NSUInteger | NSMiniaturizableWindowMask as NSUInteger, + NSBackingStoreBuffered, + false + ); + let view = NSView::alloc(nil).init(); + view.setWantsBestResolutionOpenGLSurface_(true); + + let title = NSString::alloc(nil).init_str("Hello World!\0"); + window.setTitle_(title); + window.setContentView(view); + window.center(); + + // Create the context + let attributes = [ + NSOpenGLPFADoubleBuffer as uint, + NSOpenGLPFAClosestPolicy as uint, + NSOpenGLPFAColorSize as uint, 24, + NSOpenGLPFAAlphaSize as uint, 8, + NSOpenGLPFADepthSize as uint, 24, + NSOpenGLPFAStencilSize as uint, 8, + 0 + ]; + + let pixelformat = NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(attributes); + if pixelformat == nil { + return Err(format!("Couldn't create the pixel format")); + } + + let context = NSOpenGLContext::alloc(nil).initWithFormat_shareContext_(pixelformat, nil); + if context == nil { + return Err(format!("No valid OpenGL context can be created with that pixelformat")); + } + + context.setView_(view); + + app.activateIgnoringOtherApps_(true); + window.makeKeyAndOrderFront_(nil); + context + }; + + let window = Window { + context: context, + }; + + Ok(window) } pub fn is_closed(&self) -> bool { - unimplemented!() + // TODO: remove fake implementation + false } pub fn set_title(&self, _title: &str) { @@ -64,18 +126,38 @@ impl Window { } pub fn wait_events(&self) -> Vec { - unimplemented!() + loop { + unsafe { + let event = NSApp().nextEventMatchingMask_untilDate_inMode_dequeue_( + NSAnyEventMask as u64, + nil, + NSDefaultRunLoopMode, + true); + if event == nil { break; } + NSApp().sendEvent_(event); + } + } + // TODO: Remove fake implementation + Vec::new() } pub unsafe fn make_current(&self) { - unimplemented!() + self.context.makeCurrentContext(); } pub fn get_proc_address(&self, _addr: &str) -> *const () { - unimplemented!() + let symbol_name: CFString = from_str(_addr).unwrap(); + let framework_name: CFString = from_str("com.apple.opengl").unwrap(); + let framework = unsafe { + CFBundleGetBundleWithIdentifier(framework_name.as_concrete_TypeRef()) + }; + let symbol = unsafe { + CFBundleGetFunctionPointerForName(framework, symbol_name.as_concrete_TypeRef()) + }; + symbol as *const () } pub fn swap_buffers(&self) { - unimplemented!() + unsafe { self.context.flushBuffer(); } } } -- cgit v1.2.3