mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
more changes
This commit is contained in:
parent
92caea4823
commit
e79c9aef46
@ -1,230 +0,0 @@
|
||||
// Filename: eglGraphicsBuffer.cxx
|
||||
// Created by: pro-rsoft (13Jun09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "eglGraphicsBuffer.h"
|
||||
#include "eglGraphicsStateGuardian.h"
|
||||
#include "config_egldisplay.h"
|
||||
#include "eglGraphicsPipe.h"
|
||||
|
||||
#include "graphicsPipe.h"
|
||||
#include "pStatTimer.h"
|
||||
|
||||
TypeHandle eglGraphicsBuffer::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: eglGraphicsBuffer::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
eglGraphicsBuffer::
|
||||
eglGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host) :
|
||||
GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
|
||||
{
|
||||
eglGraphicsPipe *egl_pipe;
|
||||
DCAST_INTO_V(egl_pipe, _pipe);
|
||||
_pbuffer = EGL_NO_SURFACE;
|
||||
|
||||
// Since the pbuffer never gets flipped, we get screenshots from the
|
||||
// same buffer we draw into.
|
||||
_screenshot_buffer_type = _draw_buffer_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: eglGraphicsBuffer::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
eglGraphicsBuffer::
|
||||
~eglGraphicsBuffer() {
|
||||
nassertv(_pbuffer == EGL_NO_SURFACE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: eglGraphicsBuffer::begin_frame
|
||||
// Access: Public, Virtual
|
||||
// Description: This function will be called within the draw thread
|
||||
// before beginning rendering for a given frame. It
|
||||
// should do whatever setup is required, and return true
|
||||
// if the frame should be rendered, or false if it
|
||||
// should be skipped.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool eglGraphicsBuffer::
|
||||
begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
PStatTimer timer(_make_current_pcollector, current_thread);
|
||||
|
||||
begin_frame_spam(mode);
|
||||
if (_gsg == (GraphicsStateGuardian *)NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
eglGraphicsStateGuardian *eglgsg;
|
||||
DCAST_INTO_R(eglgsg, _gsg, false);
|
||||
if (!eglMakeCurrent(eglgsg->_egl_display, _pbuffer, _pbuffer, eglgsg->_context)) {
|
||||
egldisplay_cat.error() << "Failed to call eglMakeCurrent: "
|
||||
<< get_egl_error_string(eglGetError()) << "\n";
|
||||
}
|
||||
|
||||
// Now that we have made the context current to a window, we can
|
||||
// reset the GSG state if this is the first time it has been used.
|
||||
// (We can't just call reset() when we construct the GSG, because
|
||||
// reset() requires having a current context.)
|
||||
eglgsg->reset_if_new();
|
||||
|
||||
if (mode == FM_render) {
|
||||
CDLockedReader cdata(_cycler);
|
||||
for (size_t i = 0; i != cdata->_textures.size(); ++i) {
|
||||
const RenderTexture &rt = cdata->_textures[i];
|
||||
RenderTextureMode rtm_mode = rt._rtm_mode;
|
||||
if (rtm_mode == RTM_bind_or_copy) {
|
||||
CDWriter cdataw(_cycler, cdata, false);
|
||||
nassertr(cdata->_textures.size() == cdataw->_textures.size(), false);
|
||||
cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
|
||||
}
|
||||
}
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame(current_thread);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: eglGraphicsBuffer::end_frame
|
||||
// Access: Public, Virtual
|
||||
// Description: This function will be called within the draw thread
|
||||
// after rendering is completed for a given frame. It
|
||||
// should do whatever finalization is required.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void eglGraphicsBuffer::
|
||||
end_frame(FrameMode mode, Thread *current_thread) {
|
||||
end_frame_spam(mode);
|
||||
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
||||
|
||||
if (mode == FM_render) {
|
||||
copy_to_textures();
|
||||
}
|
||||
|
||||
_gsg->end_frame(current_thread);
|
||||
|
||||
if (mode == FM_render) {
|
||||
trigger_flip();
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: eglGraphicsBuffer::close_buffer
|
||||
// Access: Protected, Virtual
|
||||
// Description: Closes the buffer right now. Called from the window
|
||||
// thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void eglGraphicsBuffer::
|
||||
close_buffer() {
|
||||
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
||||
eglGraphicsStateGuardian *eglgsg;
|
||||
DCAST_INTO_V(eglgsg, _gsg);
|
||||
if (!eglMakeCurrent(eglgsg->_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
|
||||
egldisplay_cat.error() << "Failed to call eglMakeCurrent: "
|
||||
<< get_egl_error_string(eglGetError()) << "\n";
|
||||
}
|
||||
_gsg.clear();
|
||||
|
||||
if (_pbuffer != EGL_NO_SURFACE) {
|
||||
if (!eglDestroySurface(_egl_display, _pbuffer)) {
|
||||
egldisplay_cat.error() << "Failed to destroy surface: "
|
||||
<< get_egl_error_string(eglGetError()) << "\n";
|
||||
}
|
||||
_pbuffer = EGL_NO_SURFACE;
|
||||
}
|
||||
}
|
||||
|
||||
_is_valid = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: eglGraphicsBuffer::open_buffer
|
||||
// Access: Protected, Virtual
|
||||
// Description: Opens the buffer right now. Called from the window
|
||||
// thread. Returns true if the buffer is successfully
|
||||
// opened, or false if there was a problem.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool eglGraphicsBuffer::
|
||||
open_buffer() {
|
||||
eglGraphicsPipe *egl_pipe;
|
||||
DCAST_INTO_R(egl_pipe, _pipe, false);
|
||||
|
||||
// GSG Creation/Initialization
|
||||
eglGraphicsStateGuardian *eglgsg;
|
||||
if (_gsg == 0) {
|
||||
// There is no old gsg. Create a new one.
|
||||
eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, NULL);
|
||||
eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), true, false);
|
||||
_gsg = eglgsg;
|
||||
} else {
|
||||
// If the old gsg has the wrong pixel format, create a
|
||||
// new one that shares with the old gsg.
|
||||
DCAST_INTO_R(eglgsg, _gsg, false);
|
||||
if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) {
|
||||
eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg);
|
||||
eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), true, false);
|
||||
_gsg = eglgsg;
|
||||
}
|
||||
}
|
||||
|
||||
if (eglgsg->_fbconfig == None) {
|
||||
// If we didn't use an fbconfig to create the GSG, we can't create
|
||||
// a PBuffer.
|
||||
return false;
|
||||
}
|
||||
|
||||
int attrib_list[] = {
|
||||
EGL_WIDTH, _x_size,
|
||||
EGL_HEIGHT, _y_size,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
_pbuffer = eglCreatePbufferSurface(eglgsg->_egl_display, eglgsg->_fbconfig, attrib_list);
|
||||
|
||||
if (_pbuffer == EGL_NO_SURFACE) {
|
||||
egldisplay_cat.error()
|
||||
<< "Failed to create EGL pbuffer surface: "
|
||||
<< get_egl_error_string(eglGetError()) << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!eglMakeCurrent(eglgsg->_egl_display, _pbuffer, _pbuffer, eglgsg->_context)) {
|
||||
egldisplay_cat.error() << "Failed to call eglMakeCurrent: "
|
||||
<< get_egl_error_string(eglGetError()) << "\n";
|
||||
}
|
||||
eglgsg->reset_if_new();
|
||||
if (!eglgsg->is_valid()) {
|
||||
close_buffer();
|
||||
return false;
|
||||
}
|
||||
if (!eglgsg->get_fb_properties().verify_hardware_software
|
||||
(_fb_properties, eglgsg->get_gl_renderer())) {
|
||||
close_buffer();
|
||||
return false;
|
||||
}
|
||||
_fb_properties = eglgsg->get_fb_properties();
|
||||
|
||||
_is_valid = true;
|
||||
return true;
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
// Filename: eglGraphicsBuffer.h
|
||||
// Created by: pro-rsoft (13Jun09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EGLGRAPHICSBUFFER_H
|
||||
#define EGLGRAPHICSBUFFER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "eglGraphicsPipe.h"
|
||||
#include "graphicsBuffer.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : eglGraphicsBuffer
|
||||
// Description : An offscreen buffer in the EGL environment. This
|
||||
// creates an EGL pbuffer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class eglGraphicsBuffer : public GraphicsBuffer {
|
||||
public:
|
||||
eglGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host);
|
||||
virtual ~eglGraphicsBuffer();
|
||||
|
||||
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_frame(FrameMode mode, Thread *current_thread);
|
||||
|
||||
protected:
|
||||
virtual void close_buffer();
|
||||
virtual bool open_buffer();
|
||||
|
||||
private:
|
||||
X11_Display *_display;
|
||||
EGLSurface _pbuffer;
|
||||
EGLDisplay _egl_display;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
GraphicsBuffer::init_type();
|
||||
register_type(_type_handle, "eglGraphicsBuffer",
|
||||
GraphicsBuffer::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#endif
|
@ -21,8 +21,12 @@
|
||||
#include "lightMutex.h"
|
||||
#include "lightReMutex.h"
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <AppKit/NSScreen.h>
|
||||
#import <ApplicationServices/ApplicationServices.h>
|
||||
#else
|
||||
struct NSScreen;
|
||||
#endif
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
class FrameBufferProperties;
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
#import <Foundation/NSAutoreleasePool.h>
|
||||
#import <AppKit/NSApplication.h>
|
||||
|
||||
#include <mach-o/arch.h>
|
||||
|
||||
TypeHandle CocoaGraphicsPipe::_type_handle;
|
||||
|
||||
static void init_app() {
|
||||
@ -50,7 +52,7 @@ CocoaGraphicsPipe() {
|
||||
|
||||
_screen = [NSScreen mainScreen];
|
||||
NSNumber *num = [[_screen deviceDescription] objectForKey: @"NSScreenNumber"];
|
||||
_display = (CGDirectDisplayID) [num pointerValue];
|
||||
_display = (CGDirectDisplayID) [num longValue];
|
||||
|
||||
_display_width = CGDisplayPixelsWide(_display);
|
||||
_display_height = CGDisplayPixelsHigh(_display);
|
||||
@ -78,7 +80,7 @@ CocoaGraphicsPipe(CGDirectDisplayID display) {
|
||||
NSEnumerator *e = [[NSScreen screens] objectEnumerator];
|
||||
while (NSScreen *screen = (NSScreen *) [e nextObject]) {
|
||||
NSNumber *num = [[screen deviceDescription] objectForKey: @"NSScreenNumber"];
|
||||
if (display == (CGDirectDisplayID) [num pointerValue]) {
|
||||
if (display == (CGDirectDisplayID) [num longValue]) {
|
||||
_screen = screen;
|
||||
break;
|
||||
}
|
||||
@ -111,7 +113,7 @@ CocoaGraphicsPipe(NSScreen *screen) {
|
||||
_screen = screen;
|
||||
}
|
||||
NSNumber *num = [[_screen deviceDescription] objectForKey: @"NSScreenNumber"];
|
||||
_display = (CGDirectDisplayID) [num pointerValue];
|
||||
_display = (CGDirectDisplayID) [num longValue];
|
||||
|
||||
_display_width = CGDisplayPixelsWide(_display);
|
||||
_display_height = CGDisplayPixelsHigh(_display);
|
||||
@ -129,7 +131,6 @@ CocoaGraphicsPipe(NSScreen *screen) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CocoaGraphicsPipe::
|
||||
load_display_information() {
|
||||
//TODO: read display modes and display information.
|
||||
_display_information->_vendor_id = CGDisplayVendorNumber(_display);
|
||||
//_display_information->_device_id = CGDisplayUnitNumber(_display);
|
||||
//_display_information->_device_id = CGDisplaySerialNumber(_display);
|
||||
@ -203,8 +204,18 @@ load_display_information() {
|
||||
}
|
||||
#endif
|
||||
|
||||
//XXX remove when done
|
||||
cerr << *_display_information << "\n";
|
||||
// Get processor information
|
||||
const NXArchInfo *ainfo = NXGetLocalArchInfo();
|
||||
_display_information->_cpu_brand_string = strdup(ainfo->description);
|
||||
|
||||
// Get version of Mac OS X
|
||||
SInt32 major, minor, bugfix;
|
||||
Gestalt(gestaltSystemVersionMajor, &major);
|
||||
Gestalt(gestaltSystemVersionMinor, &minor);
|
||||
Gestalt(gestaltSystemVersionBugFix, &bugfix);
|
||||
_display_information->_os_version_major = major;
|
||||
_display_information->_os_version_minor = minor;
|
||||
_display_information->_os_version_build = bugfix;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -73,8 +73,7 @@ protected:
|
||||
virtual void mouse_mode_relative();
|
||||
|
||||
private:
|
||||
void set_wm_properties(const WindowProperties &properties,
|
||||
bool already_mapped);
|
||||
NSImage *load_image(const Filename &filename);
|
||||
|
||||
ButtonHandle map_function_key(unsigned short keycode);
|
||||
|
||||
@ -88,6 +87,13 @@ private:
|
||||
bool _mouse_hidden;
|
||||
bool _context_needs_update;
|
||||
|
||||
typedef pmap<Filename, NSImage*> IconImages;
|
||||
IconImages _images;
|
||||
|
||||
public:
|
||||
// Just so CocoaPandaView can access it.
|
||||
NSCursor *_cursor;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "throw_event.h"
|
||||
#include "lightReMutexHolder.h"
|
||||
#include "nativeWindowHandle.h"
|
||||
#include "virtualFileSystem.h"
|
||||
|
||||
#import "cocoaPandaView.h"
|
||||
#import "cocoaPandaWindow.h"
|
||||
@ -35,6 +36,7 @@
|
||||
#import <AppKit/NSApplication.h>
|
||||
#import <AppKit/NSCursor.h>
|
||||
#import <AppKit/NSEvent.h>
|
||||
#import <AppKit/NSImage.h>
|
||||
#import <AppKit/NSScreen.h>
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
@ -58,6 +60,7 @@ CocoaGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
{
|
||||
_window = nil;
|
||||
_view = nil;
|
||||
_cursor = nil;
|
||||
_modifier_keys = 0;
|
||||
_mouse_hidden = false;
|
||||
_context_needs_update = true;
|
||||
@ -329,7 +332,6 @@ open_window() {
|
||||
|
||||
// Check if we have a parent view.
|
||||
NSView *parent_nsview = nil;
|
||||
HIViewRef parent_hiview = NULL;
|
||||
_parent_window_handle = NULL;
|
||||
|
||||
WindowHandle *window_handle = _properties.get_parent_window();
|
||||
@ -346,8 +348,8 @@ open_window() {
|
||||
|
||||
// Depending on whether the window handle comes from a Carbon or a Cocoa
|
||||
// application, it could be either a HIViewRef or an NSView or NSWindow.
|
||||
// We try to find out which it is, and if it is a HIView, we use the
|
||||
// HICocoaView functions to create a wrapper view to host our own Cocoa view.
|
||||
// Currently, we only support a Cocoa NSView, but we may in the future
|
||||
// add support for Carbon parents using HICocoaView.
|
||||
|
||||
if (os_handle->is_of_type(NativeWindowHandle::IntHandle::get_class_type())) {
|
||||
NativeWindowHandle::IntHandle *int_handle = DCAST(NativeWindowHandle::IntHandle, os_handle);
|
||||
@ -355,46 +357,16 @@ open_window() {
|
||||
}
|
||||
|
||||
if (ptr_handle != NULL) {
|
||||
// Check if it is actually a valid Carbon ControlRef.
|
||||
ControlRef control = (ControlRef)ptr_handle;
|
||||
ControlKind kind;
|
||||
if (IsValidControlHandle(control) &&
|
||||
GetControlKind(control, &kind) == 0 &&
|
||||
kind.signature == kControlKindSignatureApple) {
|
||||
|
||||
// Now verify that it is also a valid HIViewRef.
|
||||
parent_hiview = (HIViewRef)control;
|
||||
HIViewKind viewkind;
|
||||
if (HIViewIsValid(parent_hiview) &&
|
||||
HIViewGetKind(parent_hiview, &viewkind) == 0 &&
|
||||
viewkind.signature == kHIViewKindSignatureApple) {
|
||||
|
||||
_parent_window_handle = window_handle;
|
||||
cocoadisplay_cat.info()
|
||||
<< "Parent window handle is a valid HIViewRef\n";
|
||||
} else {
|
||||
parent_hiview = NULL;
|
||||
cocoadisplay_cat.error()
|
||||
<< "Parent window handle is a valid ControlRef, but not a valid HIViewRef!\n";
|
||||
return false;
|
||||
}
|
||||
NSObject *nsobj = (NSObject *)ptr_handle;
|
||||
if ([nsobj isKindOfClass:[NSView class]]) {
|
||||
parent_nsview = (NSView *)nsobj;
|
||||
_parent_window_handle = window_handle;
|
||||
cocoadisplay_cat.info()
|
||||
<< "Parent window handle is a valid NSView pointer\n";
|
||||
} else {
|
||||
// If it is not a Carbon ControlRef, perhaps it is a Cocoa NSView.
|
||||
// Unfortunately, there's no reliable way to check if it is actually
|
||||
// an NSObject in the first place, so this may crash - which is why
|
||||
// this case is a last resort.
|
||||
NSObject *nsobj = (NSObject *)ptr_handle;
|
||||
if ([nsobj isKindOfClass:[NSView class]]) {
|
||||
// Yep.
|
||||
parent_nsview = (NSView *)nsobj;
|
||||
_parent_window_handle = window_handle;
|
||||
cocoadisplay_cat.info()
|
||||
<< "Parent window handle is a valid NSView pointer\n";
|
||||
} else {
|
||||
cocoadisplay_cat.error()
|
||||
<< "Parent window handle is not a valid HIViewRef or NSView pointer!\n";
|
||||
return false;
|
||||
}
|
||||
cocoadisplay_cat.error()
|
||||
<< "Parent window handle is not a valid NSView pointer!\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -404,10 +376,6 @@ open_window() {
|
||||
NSRect container;
|
||||
if (parent_nsview != NULL) {
|
||||
container = [parent_nsview bounds];
|
||||
} else if (parent_hiview != NULL) {
|
||||
HIRect hirect;
|
||||
HIViewGetBounds(parent_hiview, &hirect);
|
||||
container = NSRectFromCGRect(hirect);
|
||||
} else {
|
||||
container = [cocoa_pipe->_screen frame];
|
||||
container.origin = NSMakePoint(0, 0);
|
||||
@ -477,29 +445,6 @@ open_window() {
|
||||
[_window makeFirstResponder:_view];
|
||||
}
|
||||
|
||||
// Check if we have a parent HIView to create a wrapper for.
|
||||
if (parent_hiview != NULL) {
|
||||
HIViewRef hiview;
|
||||
if (HICocoaViewCreate(_view, 0, &hiview) == 0) {
|
||||
cocoadisplay_cat.debug()
|
||||
<< "Successfully created HICocoaView " << hiview << ".\n";
|
||||
|
||||
if (HIViewAddSubview(parent_hiview, hiview) != 0) {
|
||||
cocoadisplay_cat.error()
|
||||
<< "Failed to attach HICocoaView " << hiview
|
||||
<< " to parent HIView " << parent_hiview << "!\n";
|
||||
return false;
|
||||
}
|
||||
HIViewSetVisible(hiview, TRUE);
|
||||
HIRect hirect;
|
||||
HIViewGetBounds(parent_hiview, &hirect);
|
||||
HIViewSetFrame(hiview, &hirect);
|
||||
} else {
|
||||
cocoadisplay_cat.error()
|
||||
<< "Failed to create HICocoaView.\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we have an NSView to attach our NSView to.
|
||||
if (parent_nsview != NULL) {
|
||||
[parent_nsview addSubview:_view];
|
||||
@ -515,6 +460,35 @@ open_window() {
|
||||
_parent_window_handle->attach_child(_window_handle);
|
||||
}
|
||||
|
||||
if (_properties.has_icon_filename()) {
|
||||
NSImage *image = load_image(_properties.get_icon_filename());
|
||||
if (image != nil) {
|
||||
// We're technically changing the application icon,
|
||||
// but this is most likely what the developer means.
|
||||
// There isn't really a "window icon" in Mac OS X.
|
||||
[NSApp setApplicationIconImage:image];
|
||||
} else {
|
||||
_properties.clear_icon_filename();
|
||||
}
|
||||
}
|
||||
|
||||
if (_properties.has_cursor_filename()) {
|
||||
NSImage *image = load_image(_properties.get_cursor_filename());
|
||||
NSCursor *cursor = nil;
|
||||
//TODO: allow setting the hotspot, read it from file when loading .cur.
|
||||
if (image != nil) {
|
||||
cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(0, 0)];
|
||||
}
|
||||
if (cursor != nil) {
|
||||
_cursor = cursor;
|
||||
} else {
|
||||
_properties.clear_cursor_filename();
|
||||
}
|
||||
// This will ensure that NSView's resetCursorRects gets
|
||||
// called, which sets the appropriate cursor rects.
|
||||
[[_view window] invalidateCursorRectsForView:_view];
|
||||
}
|
||||
|
||||
// Set the properties
|
||||
if (_window != nil) {
|
||||
if (_properties.has_title()) {
|
||||
@ -524,7 +498,7 @@ open_window() {
|
||||
[_window setShowsResizeIndicator: !_properties.get_fixed_size()];
|
||||
|
||||
if (_properties.get_fullscreen()) {
|
||||
[_window makeKeyAndOrderFront: nil];
|
||||
[_window makeKeyAndOrderFront: nil];
|
||||
} else if (_properties.get_minimized()) {
|
||||
[_window makeKeyAndOrderFront: nil];
|
||||
[_window miniaturize: nil];
|
||||
@ -593,11 +567,11 @@ open_window() {
|
||||
}
|
||||
_fb_properties = cocoagsg->get_fb_properties();
|
||||
|
||||
//TODO: update initial mouse position in the case that
|
||||
// the NSWindow delegate doesn't send the make key event, ie
|
||||
// if setParentWindow was used.
|
||||
|
||||
//TODO: cursor image, app icon
|
||||
// Get the initial mouse position.
|
||||
NSPoint pos = [_window mouseLocationOutsideOfEventStream];
|
||||
NSPoint loc = [_view convertPoint:pos fromView:nil];
|
||||
BOOL inside = [_view mouse:loc inRect:[_view bounds]];
|
||||
handle_mouse_moved_event(inside, loc.x, loc.y, true);
|
||||
|
||||
// Enable relative mouse mode, if this was requested.
|
||||
if (_properties.has_mouse_mode() &&
|
||||
@ -621,6 +595,11 @@ close_window() {
|
||||
_mouse_hidden = false;
|
||||
}
|
||||
|
||||
if (_cursor != nil) {
|
||||
[_cursor release];
|
||||
_cursor = nil;
|
||||
}
|
||||
|
||||
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
||||
CocoaGraphicsStateGuardian *cocoagsg;
|
||||
cocoagsg = DCAST(CocoaGraphicsStateGuardian, _gsg);
|
||||
@ -804,8 +783,6 @@ set_properties_now(WindowProperties &properties) {
|
||||
int x = properties.get_x_origin();
|
||||
int y = properties.get_y_origin();
|
||||
|
||||
//TODO: what if parent window was set
|
||||
|
||||
// Get the frame for the screen
|
||||
NSRect frame;
|
||||
NSRect container;
|
||||
@ -926,14 +903,50 @@ set_properties_now(WindowProperties &properties) {
|
||||
}
|
||||
|
||||
if (properties.has_icon_filename()) {
|
||||
//_properties.set_icon_filename(properties.get_icon_filename());
|
||||
//properties.clear_icon_filename();
|
||||
//TODO: setMiniwindowImage
|
||||
//You can also call this method as needed to change the minimized window image. Typically, you would specify a custom image immediately prior to a window being minimized—when the system posts an NSWindowWillMiniaturizeNotification. You can call this method while the window is minimized to update the current image in the Dock. However, this method is not recommended for creating complex animations in the Dock.
|
||||
//Support for custom images is disabled by default. To enable support, set the AppleDockIconEnabled key to YES when first registering your application’s user defaults. You must set this key prior to calling the init method of NSApplication, which reads the current value of the key.
|
||||
Filename icon_filename = properties.get_icon_filename();
|
||||
NSImage *image = load_image(icon_filename);
|
||||
|
||||
if (image != nil || icon_filename.empty()) {
|
||||
// We're technically changing the application icon,
|
||||
// but this is most likely what the developer means.
|
||||
// There isn't really a "window icon" in Mac OS X.
|
||||
[NSApp setApplicationIconImage:image];
|
||||
_properties.set_icon_filename(icon_filename);
|
||||
properties.clear_icon_filename();
|
||||
}
|
||||
}
|
||||
|
||||
//XXX cursor filename
|
||||
if (properties.has_cursor_filename()) {
|
||||
Filename cursor_filename = properties.get_cursor_filename();
|
||||
|
||||
if (cursor_filename.empty()) {
|
||||
// Release the existing cursor.
|
||||
if (_cursor != nil) {
|
||||
[_cursor release];
|
||||
_cursor = nil;
|
||||
}
|
||||
properties.set_cursor_filename(cursor_filename);
|
||||
properties.clear_cursor_filename();
|
||||
} else {
|
||||
NSImage *image = load_image(cursor_filename);
|
||||
if (image != nil) {
|
||||
NSCursor *cursor;
|
||||
cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(0, 0)];
|
||||
if (cursor != nil) {
|
||||
// Replace the existing cursor.
|
||||
if (_cursor != nil) {
|
||||
[_cursor release];
|
||||
}
|
||||
_cursor = cursor;
|
||||
_properties.set_cursor_filename(cursor_filename);
|
||||
properties.clear_cursor_filename();
|
||||
}
|
||||
}
|
||||
}
|
||||
// This will ensure that NSView's resetCursorRects gets
|
||||
// called, which sets the appropriate cursor rects.
|
||||
[[_view window] invalidateCursorRectsForView:_view];
|
||||
}
|
||||
|
||||
if (properties.has_z_order() && _window != nil) {
|
||||
_properties.set_z_order(properties.get_z_order());
|
||||
@ -955,12 +968,6 @@ set_properties_now(WindowProperties &properties) {
|
||||
}
|
||||
properties.clear_z_order();
|
||||
}
|
||||
|
||||
//TODO: parent window
|
||||
if (properties.has_parent_window()) {
|
||||
_properties.set_parent_window(properties.get_parent_window());
|
||||
properties.clear_parent_window();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1067,6 +1074,77 @@ do_switch_fullscreen(CGDisplayModeRef mode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsWindow::load_image
|
||||
// Access: Private
|
||||
// Description: Loads the indicated filename and returns an NSImage
|
||||
// pointer, or NULL on failure.
|
||||
// Must be called from the window thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
NSImage *CocoaGraphicsWindow::
|
||||
load_image(const Filename &filename) {
|
||||
if (filename.empty()) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Note: perhaps eventually we will need to create
|
||||
// an NSImageRep implementation, but for now, Apple
|
||||
// seems to support the major image formats.
|
||||
|
||||
// Resolve the filename on the model path.
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
Filename resolved (filename);
|
||||
if (!vfs->resolve_filename(resolved, get_model_path())) {
|
||||
// The filename doesn't exist.
|
||||
cocoadisplay_cat.warning()
|
||||
<< "Could not find filename " << filename << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Look in our index.
|
||||
NSImage *image = nil;
|
||||
IconImages::const_iterator it = _images.find(resolved);
|
||||
if (it != _images.end()) {
|
||||
// Found it.
|
||||
return (*it).second;
|
||||
}
|
||||
|
||||
cocoadisplay_cat.info()
|
||||
<< "Loading NSImage from file " << resolved << "\n";
|
||||
|
||||
PT(VirtualFile) vfile = vfs->get_file(filename);
|
||||
if (vfile == NULL) {
|
||||
return nil;
|
||||
}
|
||||
istream *str = vfile->open_read_file(true);
|
||||
if (str == NULL) {
|
||||
cocoadisplay_cat.error()
|
||||
<< "Could not open file " << filename << " for reading\n";
|
||||
return nil;
|
||||
}
|
||||
|
||||
size_t size = vfile->get_file_size(str);
|
||||
char* buffer = (char*) malloc(size);
|
||||
str->read(buffer, size);
|
||||
vfile->close_read_file(str);
|
||||
|
||||
NSData *data = [NSData dataWithBytesNoCopy:buffer length:size];
|
||||
if (data == nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
image = [[NSImage alloc] initWithData:data];
|
||||
[data release];
|
||||
if (image == nil) {
|
||||
cocoadisplay_cat.error()
|
||||
<< "Could not load image from file " << filename << "\n";
|
||||
return nil;
|
||||
}
|
||||
|
||||
_images[resolved] = image;
|
||||
return image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsWindow::handle_move_event
|
||||
// Access: Public
|
||||
@ -1261,6 +1339,12 @@ handle_close_event() {
|
||||
_mouse_hidden = false;
|
||||
}
|
||||
|
||||
// Release the cursor.
|
||||
if (_cursor != nil) {
|
||||
[_cursor release];
|
||||
_cursor = nil;
|
||||
}
|
||||
|
||||
WindowProperties properties;
|
||||
properties.set_open(false);
|
||||
properties.set_cursor_hidden(false);
|
||||
@ -1433,7 +1517,7 @@ handle_mouse_moved_event(bool in_window, int x, int y, bool absolute) {
|
||||
ClockObject::get_global_clock()->get_frame_time());
|
||||
|
||||
} else {
|
||||
//TODO: also get initial mouse position
|
||||
// We received deltas, so add it to the current mouse position.
|
||||
MouseData md = _input_devices[0].get_pointer();
|
||||
_input_devices[0].set_pointer_in_window(md.get_x() + x, md.get_y() + y);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ class CocoaGraphicsWindow;
|
||||
- (BOOL) acceptsFirstResponder;
|
||||
- (BOOL) becomeFirstResponder;
|
||||
- (BOOL) resignFirstResponder;
|
||||
- (void) resetCursorRects;
|
||||
|
||||
- (void) setFrame: (NSRect) frame;
|
||||
|
||||
|
@ -51,6 +51,12 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) resetCursorRects {
|
||||
if (_graphicsWindow->_cursor != nil) {
|
||||
[self addCursorRect:[self bounds] cursor:_graphicsWindow->_cursor];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setFrame: (NSRect) frame {
|
||||
[super setFrame: frame];
|
||||
//[_context update];
|
||||
|
Loading…
x
Reference in New Issue
Block a user