소스 검색

Functional .. OSX mouse, gl, keyboard and window wrappers....

Roger Hughston 20 년 전
부모
커밋
0752ccb35e

+ 27 - 0
panda/src/osxdisplay/Sources.pp

@@ -0,0 +1,27 @@
+#define BUILD_DIRECTORY $[IS_OSX]]
+
+#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
+                   dtoolutil:c dtoolbase:c dtool:m prc:c 
+
+#define OSX_SYS_FRAMEWORKS ApplicationServices Carbon AGL CoreServices  
+#define USE_PACKAGES gl cggl 
+
+#begin lib_target
+  #define TARGET osxdisplay
+  #define LOCAL_LIBS \
+    display putil glgsg
+    
+  
+  #define INSTALL_HEADERS \
+     config_osxdisplay.h \
+     osxGraphicsPipe.h \
+     osxGraphicsWindow.h \
+     osxGraphicsStateGuardian.h
+    
+  #define INCLUDED_SOURCES \
+    config_osxdisplay.cxx osxGraphicsPipe.cxx osxGraphicsWindow.cxx osxGraphicsStateGuardian.cxx osxGraphicsBuffer.cxx
+
+  #define SOURCES \
+    osxDisplay.xx $[INCLUDED_SOURCES] $[INSTALL_HEADERS]
+
+#end lib_target

+ 76 - 0
panda/src/osxdisplay/config_osxdisplay.cxx

@@ -0,0 +1,76 @@
+// Filename: config_glxdisplay.cxx
+// Created by:  cary (07Oct99)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+#include <Carbon/Carbon.h>
+
+#include "config_osxdisplay.h"
+#include "osxGraphicsBuffer.h"
+#include "osxGraphicsPipe.h"
+#include "osxGraphicsStateGuardian.h"
+#include "osxGraphicsWindow.h"
+
+#include "graphicsPipeSelection.h"
+#include "dconfig.h"
+#include "pandaSystem.h"
+
+
+Configure(config_osxdisplay);
+
+NotifyCategoryDef( osxdisplay , "display");
+
+ConfigureFn(config_osxdisplay) {
+  init_libosxdisplay();
+}
+
+ConfigVariableString display_cfg
+("display", "");
+
+////////////////////////////////////////////////////////////////////
+//     Function: init_libosxdisplay
+//  Description: Initializes the library.  This must be called at
+//               least once before any of the functions or classes in
+//               this library can be used.  Normally it will be
+//               called by the static initializers and need not be
+//               called explicitly, but special cases exist.
+////////////////////////////////////////////////////////////////////
+void
+init_libosxdisplay() {
+  static bool initialized = false;
+  if (initialized) {
+    return;
+  }
+  initialized = true;
+
+  printf("****** In libosx  init \n");
+
+  osxGraphicsStateGuardian::init_type();
+  osxGraphicsPipe::init_type();
+  osxGraphicsWindow::init_type();
+  osxGraphicsStateGuardian::init_type();
+
+
+
+  GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr();
+  selection->add_pipe_type(osxGraphicsPipe::get_class_type(), osxGraphicsPipe::pipe_constructor);
+
+  PandaSystem *ps = PandaSystem::get_global_ptr();
+  ps->set_system_tag("OpenGL", "window_system", "OSX");
+
+
+
+  printf("****** out libosx  init \n");
+}

+ 31 - 0
panda/src/osxdisplay/config_osxdisplay.h

@@ -0,0 +1,31 @@
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef __CONFIG_OSXDISPLAY_H__
+#define __CONFIG_OSXDISPLAY_H__
+
+#include "pandabase.h"
+#include "notifyCategoryProxy.h"
+#include "configVariableString.h"
+#include "configVariableBool.h"
+
+NotifyCategoryDecl( osxdisplay , EXPCL_PANDAGL, EXPTP_PANDAGL);
+
+extern EXPCL_PANDAGL void init_libosxdisplay();
+
+extern ConfigVariableString display_cfg;
+extern ConfigVariableBool osx_error_abort;
+
+#endif /* __CONFIG_OSXDISPLAY_H__ */

+ 156 - 0
panda/src/osxdisplay/osxGraphicsBuffer.cxx

@@ -0,0 +1,156 @@
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "osxGraphicsBuffer.h"
+#include "osxGraphicsStateGuardian.h"
+#include "config_osxdisplay.h"
+#include "osxGraphicsPipe.h"
+
+#include "graphicsPipe.h"
+#include "glgsg.h"
+#include "pStatTimer.h"
+
+TypeHandle osxGraphicsBuffer::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsBuffer::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+osxGraphicsBuffer::
+osxGraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
+                  const string &name,
+                  int x_size, int y_size) :
+  GraphicsBuffer(pipe, gsg, name, x_size, y_size) 
+{
+  osxGraphicsPipe *osx_pipe;
+  DCAST_INTO_V(osx_pipe, _pipe);
+ 
+  // Since the pbuffer never gets flipped, we get screenshots from the
+  // same buffer we draw into.
+  _screenshot_buffer_type = _draw_buffer_type;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsBuffer::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+osxGraphicsBuffer::
+~osxGraphicsBuffer() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsBuffer::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 osxGraphicsBuffer::
+begin_frame(FrameMode mode) {
+  PStatTimer timer(_make_current_pcollector);
+
+  begin_frame_spam();
+  if (_gsg == (GraphicsStateGuardian *)NULL) {
+    return false;
+  }
+
+  osxGraphicsStateGuardian *osxgsg;
+  DCAST_INTO_R(osxgsg, _gsg, false);
+//  osxMakeCurrent(_display, _pbuffer, osxgsg->_context);
+
+  // 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.)
+  osxgsg->reset_if_new();
+
+  if (mode == FM_render) {
+    // begin_render_texture();
+    clear_cube_map_selection();
+  }
+  return _gsg->begin_frame();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsBuffer::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 osxGraphicsBuffer::
+end_frame(FrameMode mode) {
+  end_frame_spam();
+  nassertv(_gsg != (GraphicsStateGuardian *)NULL);
+
+  if (mode == FM_render) {
+    // end_render_texture();
+    copy_to_textures();
+  }
+
+  _gsg->end_frame();
+
+  if (mode == FM_render) {
+    trigger_flip();
+    if (_one_shot) {
+      prepare_for_deletion();
+    }
+    clear_cube_map_selection();
+  }
+}
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsBuffer::release_gsg
+//       Access: Public
+//  Description: Releases the current GSG pointer, if it is currently
+//               held, and resets the GSG to NULL.  The window will be
+//               permanently unable to render; this is normally called
+//               only just before destroying the window.  This should
+//               only be called from within the draw thread.
+////////////////////////////////////////////////////////////////////
+void osxGraphicsBuffer::
+release_gsg() {
+  //osxMakeCurrent(_display, None, NULL);
+  GraphicsBuffer::release_gsg();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsBuffer::close_buffer
+//       Access: Protected, Virtual
+//  Description: Closes the buffer right now.  Called from the window
+//               thread.
+////////////////////////////////////////////////////////////////////
+void osxGraphicsBuffer::
+close_buffer() {
+ 
+ // _is_valid = false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsBuffer::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 osxGraphicsBuffer::
+open_buffer() {
+
+  return false;
+}
+

+ 81 - 0
panda/src/osxdisplay/osxGraphicsBuffer.h

@@ -0,0 +1,81 @@
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef OSXGRAPHICSBUFFER_H
+#define OSXGRAPHICSBUFFER_H
+#include <Carbon/Carbon.h>
+
+#define __glext_h_
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#include <AGL/agl.h>
+
+#include "pandabase.h"
+#include "graphicsBuffer.h"
+#include "glgsg.h"
+
+// This must be included after we have included glgsg.h (which
+// includes gl.h).
+//#include "wglext.h"
+
+//#include <windows.h>
+
+////////////////////////////////////////////////////////////////////
+//       Class : OSXGraphicsBuffer
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDAGL osxGraphicsBuffer : public GraphicsBuffer {
+public:
+  osxGraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
+                    const string &name,
+                    int x_size, int y_size);
+  virtual ~osxGraphicsBuffer();
+
+  virtual bool begin_frame(FrameMode mode);
+  virtual void end_frame(FrameMode mode);
+
+  virtual void release_gsg();
+
+//  virtual void begin_render_texture();
+//  virtual void end_render_texture();
+  
+
+protected:
+  virtual void close_buffer();
+  virtual bool open_buffer();
+
+private:
+   
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    GraphicsBuffer::init_type();
+    register_type(_type_handle, "owsGraphicsBuffer",
+                  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;
+
+  friend class osxGraphicsStateGuardian;
+};
+
+
+#endif

+ 133 - 0
panda/src/osxdisplay/osxGraphicsPipe.cxx

@@ -0,0 +1,133 @@
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "osxGraphicsPipe.h"
+#include "config_osxdisplay.h"
+#include "osxGraphicsWindow.h"
+#include "osxGraphicsBuffer.h"
+#include "osxGraphicsStateGuardian.h"
+
+//typedef enum {Software, MCD, ICD} OGLDriverType;
+
+TypeHandle osxGraphicsPipe::_type_handle;
+  
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsPipe::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+osxGraphicsPipe::
+osxGraphicsPipe() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsPipe::Destructor
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+osxGraphicsPipe::
+~osxGraphicsPipe() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsPipe::get_interface_name
+//       Access: Published, Virtual
+//  Description: Returns the name of the rendering interface
+//               associated with this GraphicsPipe.  This is used to
+//               present to the user to allow him/her to choose
+//               between several possible GraphicsPipes available on a
+//               particular platform, so the name should be meaningful
+//               and unique for a given platform.
+////////////////////////////////////////////////////////////////////
+string osxGraphicsPipe::
+get_interface_name() const {
+  return "OpenGL";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsPipe::pipe_constructor
+//       Access: Public, Static
+//  Description: This function is passed to the GraphicsPipeSelection
+//               object to allow the user to make a default
+//               osxGraphicsPipe.
+////////////////////////////////////////////////////////////////////
+PT(GraphicsPipe) osxGraphicsPipe::
+pipe_constructor() {
+  return new osxGraphicsPipe;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsPipe::make_gsg
+//       Access: Protected, Virtual
+//  Description: Creates a new GSG to use the pipe (but no windows
+//               have been created yet for the GSG).  This method will
+//               be called in the draw thread for the GSG.
+////////////////////////////////////////////////////////////////////
+PT(GraphicsStateGuardian) osxGraphicsPipe::
+make_gsg(const FrameBufferProperties &properties, 
+         GraphicsStateGuardian *share_with) {
+		 
+		 
+  if (!_is_valid) {
+    return NULL;
+  }
+
+  osxGraphicsStateGuardian *share_gsg = NULL;
+
+  if (share_with != (GraphicsStateGuardian *)NULL) {
+    if (!share_with->is_exact_type(osxGraphicsStateGuardian::get_class_type())) 
+	{
+      osxdisplay_cat.error()
+        << "Cannot share context between osxGraphicsStateGuardian and "
+        << share_with->get_type() << "\n";
+      return NULL;
+    }
+
+    DCAST_INTO_R(share_gsg, share_with, NULL);
+  }
+
+  int frame_buffer_mode = 0;
+  if (properties.has_frame_buffer_mode()) {
+    frame_buffer_mode = properties.get_frame_buffer_mode();
+  }
+
+
+	PT(osxGraphicsStateGuardian) gsg1 = new osxGraphicsStateGuardian(properties,(osxGraphicsStateGuardian *)  share_with, 1);
+                          
+    return gsg1.p();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsPipe::make_window
+//       Access: Protected, Virtual
+//  Description: Creates a new window on the pipe, if possible.
+////////////////////////////////////////////////////////////////////
+PT(GraphicsWindow) osxGraphicsPipe::
+make_window(GraphicsStateGuardian *gsg, const string &name) {
+  return new osxGraphicsWindow(this, gsg, name);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsPipe::make_buffer
+//       Access: Protected, Virtual
+//  Description: Creates a new offscreen buffer on the pipe, if possible.
+////////////////////////////////////////////////////////////////////
+PT(GraphicsBuffer) osxGraphicsPipe::
+make_buffer(GraphicsStateGuardian *gsg, const string &name,
+            int x_size, int y_size) {
+  return new osxGraphicsBuffer(this, gsg, name, x_size, y_size);
+}
+
+

+ 69 - 0
panda/src/osxdisplay/osxGraphicsPipe.h

@@ -0,0 +1,69 @@
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef OSXGRAPHICSPIPE_H
+#define OSXGRAPHICSPIPE_H
+
+#include "pandabase.h"
+#include "graphicspipe.h"
+
+class osxGraphicsStateGuardian;
+
+////////////////////////////////////////////////////////////////////
+//       Class : osxGraphicsPipe
+// Description : This graphics pipe represents the interface for
+//               creating OpenGL graphics windows on the various
+//               OSX's.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDAGL osxGraphicsPipe : public GraphicsPipe {
+public:
+  osxGraphicsPipe();
+  virtual ~osxGraphicsPipe();
+
+  virtual string get_interface_name() const;
+  static PT(GraphicsPipe) pipe_constructor();
+
+protected:
+  virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
+                                             GraphicsStateGuardian *share_with);
+  virtual PT(GraphicsWindow) make_window(GraphicsStateGuardian *gsg,
+                                         const string &name);
+  virtual PT(GraphicsBuffer) make_buffer(GraphicsStateGuardian *gsg, 
+                                         const string &name,
+                                         int x_size, int y_size);
+private:
+ public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    GraphicsPipe::init_type();
+    register_type(_type_handle, "osxGraphicsPipe",
+                  GraphicsPipe::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;
+
+  friend class osxGraphicsBuffer;
+};
+
+//#include "osxGraphicsPipe.I"
+
+#endif

+ 134 - 0
panda/src/osxdisplay/osxGraphicsStateGuardian.cxx

@@ -0,0 +1,134 @@
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "osxGraphicsStateGuardian.h"
+#include "osxGraphicsBuffer.h"
+#include "string_utils.h"
+
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#import <mach-o/dyld.h>
+
+TypeHandle osxGraphicsStateGuardian::_type_handle;
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsStateGuardian::get_extension_func
+//       Access: Public, Virtual
+//  Description: Returns the pointer to the GL extension function with
+//               the indicated name.  It is the responsibility of the
+//               caller to ensure that the required extension is
+//               defined in the OpenGL runtime prior to calling this;
+//               it is an error to call this for a function that is
+//               not defined.
+////////////////////////////////////////////////////////////////////
+void *osxGraphicsStateGuardian::get_extension_func(const char *prefix, const char *name) 
+{	
+    string fullname = "_" + string(prefix) + string(name);
+    NSSymbol symbol = NULL;
+    
+    if (NSIsSymbolNameDefined (fullname.c_str()))
+        symbol = NSLookupAndBindSymbol (fullname.c_str());
+		
+		
+    return symbol ? NSAddressOfSymbol (symbol) : NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsStateGuardian::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+osxGraphicsStateGuardian::
+osxGraphicsStateGuardian(const FrameBufferProperties &properties,
+                         osxGraphicsStateGuardian *share_with,
+                         int pfnum) : 
+  GLGraphicsStateGuardian(properties),
+  _share_with(share_with),
+  _aglPixFmt(NULL),
+  _aglcontext(NULL)
+{
+
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsStateGuardian::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+osxGraphicsStateGuardian::
+~osxGraphicsStateGuardian() 
+{
+  if(_aglcontext != (AGLContext)NULL)
+  {
+     aglDestroyContext(_aglcontext);
+	 aglReportError();
+	 _aglcontext = (AGLContext)NULL;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsStateGuardian::reset
+//       Access: Public, Virtual
+//  Description: Resets all internal state as if the gsg were newly
+//               created.
+////////////////////////////////////////////////////////////////////
+void osxGraphicsStateGuardian::reset() 
+{
+/*
+  if(_aglcontext != (AGLContext)NULL)
+  {
+     aglDestroyContext(_aglcontext);
+	 aglReportError();
+	 _aglcontext = (AGLContext)NULL;
+  }
+  */
+
+  GLGraphicsStateGuardian::reset();
+ }
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsStateGuardian::buildGL
+//       Access: Public, Virtual
+//  Description: 
+//
+////////////////////////////////////////////////////////////////////
+OSStatus osxGraphicsStateGuardian::buildGL (osxGraphicsWindow  &window)
+{
+	OSStatus err = noErr;
+//	GLint attrib[] = { AGL_RGBA, AGL_DOUBLEBUFFER, AGL_DEPTH_SIZE, 16, AGL_NONE };
+	GLint attrib[] = { AGL_RGBA, AGL_NO_RECOVERY, AGL_FULLSCREEN, AGL_DOUBLEBUFFER, AGL_DEPTH_SIZE, 32, AGL_SAMPLE_BUFFERS_ARB, 1, AGL_SAMPLES_ARB, 0, 0 };
+    	
+	if (_aglcontext)
+		return noErr; // already built
+		
+	// build context
+	_aglcontext = NULL;
+	_aglPixFmt = aglChoosePixelFormat(NULL, 0, attrib);
+	err = aglReportError ();
+	if (_aglPixFmt)
+	 {
+	  if(_share_with == NULL)
+		_aglcontext = aglCreateContext(_aglPixFmt, NULL);
+	  else
+		_aglcontext = aglCreateContext(_aglPixFmt, ((osxGraphicsStateGuardian *)_share_with)->_aglcontext);
+
+	  err = aglReportError ();
+	}
+    return err;
+}
+
+
+

+ 87 - 0
panda/src/osxdisplay/osxGraphicsStateGuardian.h

@@ -0,0 +1,87 @@
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef OSXGRAPHICSSTATEGUARDIAN_H
+#define OSXGRAPHICSSTATEGUARDIAN_H
+#include <Carbon/Carbon.h>
+
+#define __glext_h_
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#include <AGL/agl.h>
+	
+#include "pandabase.h"
+#include "glgsg.h"
+
+#include "osxGraphicsWindow.h"
+
+class osxGraphicsWindow;
+
+////////////////////////////////////////////////////////////////////
+//       Class : wglGraphicsStateGuardian
+// Description : A tiny specialization on GLGraphicsStateGuardian to
+//               add some wgl-specific information.
+////////////////////////////////////////////////////////////////////
+class osxGraphicsStateGuardian : public GLGraphicsStateGuardian {
+public:
+  osxGraphicsStateGuardian(const FrameBufferProperties &properties, 
+                           osxGraphicsStateGuardian *share_with,
+                           int pfnum);
+  virtual ~osxGraphicsStateGuardian();
+
+   virtual void reset();
+
+
+
+	AGLContext  get_context(void) { return _aglcontext; };
+	
+	OSStatus buildGL (osxGraphicsWindow  &window);
+protected:
+  virtual void *get_extension_func(const char *prefix, const char *name);
+  
+private:
+
+  // We have to save a pointer to the GSG we intend to share texture
+  // context with, since we don't create our own context in the
+  // constructor.
+    PT(osxGraphicsStateGuardian) _share_with;
+  	AGLPixelFormat	_aglPixFmt;
+	AGLContext		_aglcontext;
+
+
+public:
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    GLGraphicsStateGuardian::init_type();
+    register_type(_type_handle, "osxGraphicsStateGuardian",
+                  GLGraphicsStateGuardian::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;
+
+  friend class osxGraphicsBuffer;
+};
+
+
+#endif

+ 1137 - 0
panda/src/osxdisplay/osxGraphicsWindow.cxx

@@ -0,0 +1,1137 @@
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+#include <Carbon/Carbon.h>
+
+#include "osxGraphicsWindow.h"
+#include "config_osxdisplay.h"
+#include "osxGraphicsPipe.h"
+#include "pStatTimer.h"
+#include "glgsg.h"
+#include "keyboardButton.h"
+#include "mouseButton.h"
+#include "osxGraphicsStateGuardian.h"
+
+#include <OpenGL/gl.h>
+#include <AGL/agl.h>
+#include <ApplicationServices/ApplicationServices.h>
+
+TypeHandle osxGraphicsWindow::_type_handle;
+
+ButtonHandle OSX_TranslateKey( UInt32 key,  EventRef event );
+
+EventHandlerUPP gEvtHandler;			// main event handler
+EventHandlerUPP gWinEvtHandler;			// window event handler
+//AbsoluteTime gStartTime;
+
+char gErrorMessage[256] = ""; // buffer for error message output
+float gErrorTime = 0.0;
+
+static osxGraphicsWindow  * FullScreenWindow = NULL;
+
+osxGraphicsWindow * GetCurrentOSxWindow (WindowRef window)
+{
+	if(FullScreenWindow != NULL)
+	   return FullScreenWindow;
+
+	if (NULL == window)  // HID use this path
+		window = FrontWindow ();
+	if (window)
+		return (osxGraphicsWindow *) GetWRefCon (window);
+	else
+		return NULL;
+}
+
+
+
+OSStatus aglReportError (void)
+{
+	GLenum err = aglGetError();
+	if (AGL_NO_ERROR != err) 
+		 osxdisplay_cat.error()<<"AGL Error " <<  aglErrorString(err) << "\n";
+
+	if (err == AGL_NO_ERROR)
+		return noErr;
+	else
+		return (OSStatus) err;
+}
+
+void InvertGLImage( char *imageData, size_t imageSize, size_t rowBytes )
+{
+	size_t i, j;
+	char *tBuffer = (char*) malloc (rowBytes);
+	if (NULL == tBuffer) return;
+		
+	// Copy by rows through temp buffer
+	for (i = 0, j = imageSize - rowBytes; i < imageSize >> 1; i += rowBytes, j -= rowBytes) {
+		memcpy( tBuffer, &imageData[i], rowBytes );
+		memcpy( &imageData[i], &imageData[j], rowBytes );
+		memcpy( &imageData[j], tBuffer, rowBytes );
+	}
+	free(tBuffer);
+}
+
+
+void CompositeGLBufferIntoWindow (AGLContext ctx, Rect *bufferRect, GrafPtr out_port)
+{
+	GWorldPtr pGWorld;
+	QDErr err;
+	// blit OpenGL content into window backing store
+	// allocate buffer to hold pane image
+	long width  = (bufferRect->right - bufferRect->left);
+	long height  = (bufferRect->bottom - bufferRect->top);
+	
+	
+	
+	Rect src_rect = {0, 0, height, width};
+	Rect ddrc_rect = {0, 0, height, width};
+	long rowBytes = width * 4;
+	long imageSize = rowBytes * height;
+	char *image = (char *) NewPtr (imageSize);
+	if (!image) {
+		osxdisplay_cat.error() << "Out of memory in CompositeGLBufferIntoWindow()!\n";
+		return;		// no harm in continuing
+	}
+	
+//	printf(" Reading aa Conte Data %d %d\n",height,width);
+	
+	// pull GL content down to our image buffer
+	aglSetCurrentContext( ctx );
+	glReadPixels (0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image);
+
+	// GL buffers are upside-down relative to QD buffers, so we need to flip it
+	InvertGLImage( image, imageSize, rowBytes );
+
+	// create a GWorld containing our image
+	err = NewGWorldFromPtr (&pGWorld, k32ARGBPixelFormat, &src_rect, 0, 0, 0, image, rowBytes);
+	if (err != noErr) {
+		osxdisplay_cat.error() << " error in NewGWorldFromPtr, called from CompositeGLBufferIntoWindow()\n";
+		free( image );
+		return;
+	}
+        GrafPtr portSave = NULL;
+        GetPort (&portSave);
+	
+	//SetPort( GetWindowPort (win));
+	SetPort(out_port);
+	CopyBits( GetPortBitMapForCopyBits (pGWorld), GetPortBitMapForCopyBits (out_port), &src_rect, &ddrc_rect, srcCopy, 0 );
+	
+	SetPort(portSave);
+	DisposeGWorld( pGWorld );
+	DisposePtr ( image );
+}
+
+void osxGraphicsWindow::SystemCloseWindow()
+{	
+	osxdisplay_cat.debug() << "System Closing Window \n";
+
+	ReleaseSystemResources();
+	
+};
+
+// window event handler
+static pascal OSStatus windowEvtHndlr (EventHandlerCallRef myHandler, EventRef event, void* userData)
+{
+#pragma unused (userData)
+    OSStatus			result = eventNotHandledErr;
+    UInt32 				the_class = GetEventClass (event);
+    UInt32 				kind = GetEventKind (event);
+ 
+	switch (the_class) {
+		case kEventClassWindow:
+		
+		    WindowRef window = NULL;		
+			GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &window);
+			osxGraphicsWindow * osx_win = GetCurrentOSxWindow(window);
+			if(osx_win == NULL)
+				return result;
+			 
+			switch (kind) {
+				case kEventWindowCollapsing:
+					Rect r;
+					GetWindowPortBounds (window, &r);					
+					CompositeGLBufferIntoWindow( osx_win->get_context(), &r, GetWindowPort (window));
+					result = UpdateCollapsedWindowDockTile (window);
+					osx_win->SystemSetWindowForground(false);
+					break;
+				case kEventWindowActivated: // called on click activation and initially
+						osx_win->SystemSetWindowForground(true);
+						osx_win->DoResize();
+					break;
+				case kEventWindowClose: // called when window is being closed (close box)
+						osx_win->SystemCloseWindow();
+					break;
+				case kEventWindowShown: // called on initial show (not on un-minimize)
+					if (window == FrontWindow ())
+						SetUserFocusWindow (window);
+					break;
+				case kEventWindowBoundsChanged: // called for resize and moves (drag)
+						osx_win->DoResize();
+					break;
+				case kEventWindowZoomed: // called when user clicks on zoom button (occurs after the window has been zoomed)
+					// use this if you need to some special here as you always get a kEventWindowBoundsChanged event
+					break;
+			}
+			break;
+	}
+    return result;
+}
+	
+void     osxGraphicsWindow::DoResize(void)
+{
+    if(_osx_window != NULL)
+	{
+	Rect				rectPort = {0,0,0,0};
+	CGRect 				viewRect = {{0.0f, 0.0f}, {0.0f, 0.0f}};
+	
+	GetWindowPortBounds (_osx_window, &rectPort); 
+	viewRect.size.width = (float) (rectPort.right - rectPort.left);
+	viewRect.size.height = (float) (rectPort.bottom - rectPort.top);
+	
+	  WindowProperties properties;
+	  properties.set_size((int)viewRect.size.width,(int)viewRect.size.height);
+	  properties.set_origin((int) rectPort.left,(int)rectPort.top);
+	  system_changed_properties(properties);
+	  osxdisplay_cat.debug() << " Resizing Window " << viewRect.size.width << " " << viewRect.size.height << "\n";
+	  
+	  aglUpdateContext (aglGetCurrentContext());
+	  aglReportError();
+	}						
+  
+	
+	//printf(" Setting Window Size to %d %d \n",(int)viewRect.size.width,(int)viewRect.size.height);
+};
+
+// application level event handler
+static pascal OSStatus appEvtHndlr (EventHandlerCallRef myHandler, EventRef event, void* userData)
+{
+#pragma unused (myHandler)
+    OSStatus result = eventNotHandledErr;
+    osxGraphicsWindow *osx_win = NULL;
+    WindowRef window = NULL;	
+    UInt32 the_class = GetEventClass (event);
+    UInt32 kind = GetEventKind (event);
+
+	GetEventParameter(event, kEventParamWindowRef,
+                        typeWindowRef, NULL, sizeof(WindowRef),
+                        NULL, (void*) &window);
+
+     osx_win = GetCurrentOSxWindow(window);
+
+    if(osx_win == NULL)
+	  return eventNotHandledErr;
+	  
+	
+	switch (the_class) {
+        case kEventClassTextInput:
+			  if(kind == kEventTextInputUnicodeForKeyEvent)
+				osx_win->handleTextInput(myHandler, event);
+				//
+				// can not report handled .. the os will not sent the raw key strokes then 
+				//	if(osx_win->handleTextInput(myHandler, event) == noErr)
+				//	      result = noErr;
+			  break;
+		case kEventClassKeyboard:
+			switch (kind) {
+			   printf(" Key Event \n");
+				case kEventRawKeyDown:
+					result = osx_win->handleKeyInput  (myHandler, event, true);
+					break;
+				case kEventRawKeyUp:
+					result = osx_win->handleKeyInput  (myHandler, event, false);
+					break;
+				case kEventRawKeyModifiersChanged:
+					{
+						UInt32 newModifiers;
+						OSStatus error = GetEventParameter(event, kEventParamKeyModifiers,typeUInt32, NULL,sizeof(UInt32), NULL, &newModifiers);
+						if(error == noErr)						   
+							osx_win->HandleModifireDeleta(newModifiers);
+					}
+					break;
+			}
+			break;
+
+		case kEventClassMouse:
+			osx_win->handleWindowMouseEvents (myHandler, event);
+			break;
+	}
+    return result;
+}
+
+
+OSStatus osxGraphicsWindow::handleTextInput (EventHandlerCallRef myHandler, EventRef theTextEvent)
+{
+	UniChar      *text = NULL;
+	UInt32       actualSize = 0; 
+ 
+	OSStatus ret = GetEventParameter (theTextEvent, kEventParamTextInputSendText, typeUnicodeText, NULL, 0, &actualSize, NULL);
+	if(ret != noErr)
+	   return ret;
+ 
+	text = (UniChar*) NewPtr(actualSize);
+	if(text!= NULL)
+	{
+ 
+		ret = GetEventParameter (theTextEvent, kEventParamTextInputSendText,typeUnicodeText, NULL, actualSize, NULL, text);
+		if(ret != noErr)
+			return ret;
+
+		for(unsigned int x = 0; x < actualSize/sizeof(UniChar); ++x)
+		{
+			printf(" Push KetStroke %x\n",(int)text[x]);
+			_input_devices[0].keystroke(text[x]);	
+		}
+		DisposePtr((char *)text);
+	
+	}
+	
+	return ret;
+}
+
+ void   osxGraphicsWindow::ReleaseSystemResources()
+ {
+		
+	if(_is_fullsreen)
+	{
+		if(_originalMode != NULL)
+			CGDisplaySwitchToMode( kCGDirectMainDisplay, _originalMode );
+
+		CGDisplayRelease( kCGDirectMainDisplay );
+		aglSetDrawable (get_context(), NULL);
+		_is_fullsreen = false;
+		FullScreenWindow = NULL;
+		_originalMode = NULL;
+	}
+	
+	
+	if(_osx_window != NULL && GetWindowPort (_osx_window) == (GrafPtr)aglGetDrawable(get_context()))
+		aglSetDrawable (get_context(),NULL);
+	
+			
+	if(aglGetCurrentContext() == get_context())			
+		aglSetCurrentContext (NULL);
+
+
+ 	if(_osx_window != NULL)  
+	{
+		HideWindow (_osx_window);
+		SetWRefCon (_osx_window, (long int) NULL);
+		DisposeWindow(_osx_window);
+		_osx_window = NULL;
+	}
+		
+
+				
+#ifdef HACK_SCREEN_HASH_CONTEXT  		 
+	if (_aglcontext)
+	 {
+		aglDestroyContext (_aglcontext);		
+		_aglcontext = NULL;
+	}
+#endif 		
+	
+	WindowProperties properties;
+    properties.set_foreground(false);
+	properties.set_open(false);
+	system_changed_properties(properties);
+				
+	_is_fullsreen = false;	
+	_osx_window = NULL;
+ }
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsWindow::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+osxGraphicsWindow::osxGraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
+                  const string &name) :
+  GraphicsWindow(pipe, gsg, name) ,
+  _osx_window(NULL),
+  _is_fullsreen(false),
+#ifdef HACK_SCREEN_HASH_CONTEXT  
+   _aglPixFmt(NULL),
+  _aglcontext(NULL),
+#endif  
+	_originalMode(NULL)
+{
+    printf("Create osxGraphicsWindow \n");
+
+  GraphicsWindowInputDevice device =
+    GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse");
+  _input_devices.push_back(device);
+  _input_devices[0].set_pointer_in_window(0, 0);
+  _last_key_modifiers = 0;
+  
+  }
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsWindow::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+osxGraphicsWindow::~osxGraphicsWindow()
+{
+
+	ReleaseSystemResources();
+	
+
+  cerr << " osxGraphicsWindow::~osxGraphicsWindow() \n";
+}
+
+void osxGraphicsWindow::make_current()
+{
+
+}
+
+AGLContext  osxGraphicsWindow::get_context(void)
+{
+	if(_aglcontext != NULL)
+	  return _aglcontext;
+
+    return get_ggs_context();
+ }
+
+AGLContext  osxGraphicsWindow::get_ggs_context(void)
+{
+	if(_gsg != NULL)
+	{
+		osxGraphicsStateGuardian *osxgsg = NULL;
+		osxgsg = DCAST(osxGraphicsStateGuardian, _gsg);	
+		return osxgsg->get_context();
+	}
+	return NULL;
+ }
+
+
+OSStatus osxGraphicsWindow::buildGL (void)
+{
+	// make sure the ggs is up and runnig..
+		osxGraphicsStateGuardian *osxgsg = NULL;
+		osxgsg = DCAST(osxGraphicsStateGuardian, _gsg);
+		osxgsg->buildGL(*this);
+
+	OSStatus err = noErr;
+	
+#ifdef HACK_SCREEN_HASH_CONTEXT  
+	
+//	GLint attrib[] = { AGL_RGBA, AGL_DOUBLEBUFFER, AGL_DEPTH_SIZE, 16, AGL_NONE,AGL_NONE,AGL_NONE,AGL_NONE };
+	GLint attrib[] = { AGL_RGBA, AGL_NO_RECOVERY,  AGL_DOUBLEBUFFER, AGL_DEPTH_SIZE, 32, AGL_SAMPLE_BUFFERS_ARB, 1, AGL_SAMPLES_ARB, 0, 0 };
+  
+	if(_properties.has_fullscreen() && _properties.get_fullscreen() == true)
+	{		
+		short i = 0;
+		while (attrib[i++] != AGL_NONE) {}
+		i--; // point to AGL_NONE
+		attrib [i++] = AGL_FULLSCREEN;
+		attrib [i++] = AGL_NONE;		
+		
+		printf(" Adding Full Screen To Pixel Format \n");
+	}
+	
+				
+	if (_aglcontext)
+		return noErr; // already built
+		
+	// build context
+	_aglcontext = NULL;
+	_aglPixFmt = aglChoosePixelFormat(NULL, 0, attrib);
+	aglReportError ();
+	if (_aglPixFmt)
+	 {
+		_aglcontext = aglCreateContext(_aglPixFmt, get_ggs_context());
+		aglReportError ();
+	}
+	
+#endif  // HACK_SCREEN_HASH_CONTEXT
+    return err;
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsWindow::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 osxGraphicsWindow::begin_frame(FrameMode mode) {
+  PStatTimer timer(_make_current_pcollector);
+   // printf("Do begin frame \n");
+
+  begin_frame_spam();
+  if (_gsg == (GraphicsStateGuardian *)NULL || (_osx_window == NULL && _is_fullsreen != true)) 
+  {
+		return false;
+  }
+
+
+  if(_is_fullsreen)
+  {
+		if (!aglSetCurrentContext(get_context()))
+				aglReportError ();	
+  
+//	  printf(" In Full Screen begin_frame\n");
+  
+  }
+  else
+  {
+	GrafPtr OtherWin = (GrafPtr)aglGetDrawable(get_context());
+	aglReportError();
+	WindowPtr other  = GetWindowFromPort(OtherWin);
+		
+	if(OtherWin != NULL && OtherWin != (GrafPtr)GetWindowPort (_osx_window))
+	{
+		Rect r;
+		GetWindowPortBounds (other, &r);
+	 //   printf(" Doint Composite %d  %d\n",(int)OtherWin,(int)GetWindowPort (_osx_window));
+		CompositeGLBufferIntoWindow(get_context(),& r,OtherWin);
+	}
+
+		aglSetDrawable (get_context(),GetWindowPort (_osx_window));
+		aglReportError();
+		
+		
+		if (!aglSetCurrentContext(get_context()))
+				aglReportError ();	
+  	
+  }
+ 
+ 
+	
+_gsg->reset_if_new();
+
+  return _gsg->begin_frame();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsWindow::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 osxGraphicsWindow::end_frame(FrameMode mode) 
+{
+  end_frame_spam();
+
+  nassertv(_gsg != (GraphicsStateGuardian *)NULL);
+
+  _gsg->end_frame();
+  trigger_flip();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsWindow::release_gsg
+//       Access: Public, Virtual
+//  Description: Releases the current GSG pointer, if it is currently
+//               held, and resets the GSG to NULL.  The window will be
+//               permanently unable to render; this is normally called
+//               only just before destroying the window.  This should
+//               only be called from within the draw thread.
+////////////////////////////////////////////////////////////////////
+void osxGraphicsWindow::release_gsg() 
+{
+	ReleaseSystemResources();
+		
+  GraphicsWindow::release_gsg();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsWindow::begin_flip
+//       Access: Public, Virtual
+//  Description: This function will be called within the draw thread
+//               after end_frame() has been called on all windows, to
+//               initiate the exchange of the front and back buffers.
+//
+//               This should instruct the window to prepare for the
+//               flip at the next video sync, but it should not wait.
+//
+//               We have the two separate functions, begin_flip() and
+//               end_flip(), to make it easier to flip all of the
+//               windows at the same time.
+////////////////////////////////////////////////////////////////////
+void osxGraphicsWindow::begin_flip() 
+{
+	aglSwapBuffers (get_context());
+	aglReportError();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsWindow::close_window
+//       Access: Protected, Virtual
+//  Description: Closes the window right now.  Called from the window
+//               thread.
+////////////////////////////////////////////////////////////////////
+void osxGraphicsWindow::close_window() {
+
+	ReleaseSystemResources();
+	GraphicsWindow::close_window();
+
+}
+
+//////////////////////////////////////////////////////////
+// HACK ALLERT ************ Undocumented OSX calls...
+// I can not find any other way to get the mouse focus to a window in OSX..
+//
+extern "C" {
+ struct  CPSProcessSerNum
+{
+UInt32 lo;
+UInt32 hi;
+};
+
+extern OSErr CPSGetCurrentProcess(CPSProcessSerNum *psn);
+extern OSErr CPSEnableForegroundOperation( struct CPSProcessSerNum *psn);
+extern OSErr CPSSetProcessName ( struct CPSProcessSerNum *psn, char *processname);
+extern OSErr CPSSetFrontProcess( struct CPSProcessSerNum *psn);
+};
+
+////////////////////////////////////////////////////////////////////
+//     Function: osxGraphicsWindow::open_window
+//       Access: Protected, Virtual
+//  Description: Opens the window right now.  Called from the window
+//               thread.  Returns true if the window is successfully
+//               opened, or false if there was a problem.
+////////////////////////////////////////////////////////////////////
+bool osxGraphicsWindow::open_window() {
+OSErr err;
+	printf(" In Open Window \n");
+	
+	
+	static bool GlobalInits = false;
+	if(GlobalInits != true)
+	{
+		EventHandlerRef	ref1;
+		EventTypeSpec	list1[] = { 
+					           //{ kEventClassCommand,  kEventProcessCommand },
+							   //{ kEventClassCommand,  kEventCommandUpdateStatus },
+							   { kEventClassMouse, kEventMouseDown },// handle trackball functionality globaly because there is only a single user
+							   { kEventClassMouse, kEventMouseUp }, 
+							   { kEventClassMouse, kEventMouseMoved },
+							   { kEventClassMouse, kEventMouseDragged },
+							   { kEventClassMouse, kEventMouseWheelMoved } ,
+                               { kEventClassKeyboard, kEventRawKeyDown },
+                               { kEventClassKeyboard, kEventRawKeyUp } ,
+	  		 				   { kEventClassKeyboard, kEventRawKeyModifiersChanged }	,
+							   {kEventClassTextInput,	kEventTextInputUnicodeForKeyEvent},				   
+							   };
+
+
+		gEvtHandler = NewEventHandlerUPP(appEvtHndlr);
+		err = InstallApplicationEventHandler (gEvtHandler, GetEventTypeCount (list1) , list1, this, &ref1 );
+		GlobalInits = true;
+		
+		struct CPSProcessSerNum PSN;
+		GetCurrentProcess((ProcessSerialNumber *)&PSN);
+		err = CPSGetCurrentProcess(&PSN);
+		
+		if(_properties.has_title())
+		{
+			err = CPSSetProcessName(&PSN,(char *)_properties.get_title().c_str());
+		}
+		else		
+			err = CPSSetProcessName(&PSN,"Panda3D");
+		
+		err = CPSEnableForegroundOperation(&PSN);
+		err = CPSSetFrontProcess(&PSN);
+		
+		
+		
+	}
+
+  
+
+    EventHandlerRef		ref;
+    EventTypeSpec list[] = { { kEventClassWindow, kEventWindowCollapsing },
+							 { kEventClassWindow, kEventWindowShown },
+                             { kEventClassWindow, kEventWindowActivated },
+                             { kEventClassWindow, kEventWindowClose },
+                             { kEventClassWindow, kEventWindowBoundsChanged },
+                             { kEventClassWindow, kEventWindowZoomed },
+    //                         { kEventClassKeyboard, kEventRawKeyDown },
+      //                       { kEventClassKeyboard, kEventRawKeyUp } ,
+		//					 { kEventClassKeyboard, kEventRawKeyModifiersChanged }
+							 };
+
+
+	Rect r;
+	if(_properties.has_origin())
+	{	
+		r.top = _properties.get_y_origin();
+		r.left =_properties.get_x_origin();
+	}
+	else
+	{
+	     r.top = 50;
+		 r.left = 10;
+	}
+		
+	if(_properties.has_size())
+	{
+		r.right = r.left + _properties.get_x_size();
+		r.bottom = r.top + _properties.get_y_size();
+	}
+	else
+	{			
+		r.right = r.left + 512;
+		r.bottom = r.top + 512;
+	}		
+
+if(_properties.has_fullscreen() && _properties.get_fullscreen() == true)
+{
+	// capture the main display
+	CGDisplayCapture( kCGDirectMainDisplay );
+	// if sized try and switch it..
+	if(_properties.has_size())
+	{
+		_originalMode = CGDisplayCurrentMode( kCGDirectMainDisplay );	
+		CGDisplaySwitchToMode( kCGDirectMainDisplay,
+                CGDisplayBestModeForParameters( kCGDirectMainDisplay, 32,  _properties.get_x_size(), _properties.get_y_size(), 0 ) );
+	}
+
+	buildGL();	
+		if (!aglSetCurrentContext(get_context()))
+			err = aglReportError ();
+	aglSetFullScreen(get_context(),0,0,0,0);
+	aglReportError ();
+		
+		// VBL SYNC
+		GLint swap = 1;	
+		if (!aglSetInteger (get_context(), AGL_SWAP_INTERVAL, &swap))
+			aglReportError ();
+	
+	
+ 
+	
+// CreateNewWindow(//
+// kOverlayWindowClass,
+//	kWindowStandardHandlerAttribute, 
+//	&r, &_osx_window); 
+	_is_fullsreen	=true;	
+	FullScreenWindow = this;
+}
+else
+{
+
+ CreateNewWindow(//
+// kUtilityWindowClass,
+	kDocumentWindowClass,   
+//	kWindowLiveResizeAttribute |
+	kWindowStandardDocumentAttributes |  
+	kWindowStandardHandlerAttribute, 
+	&r, &_osx_window);
+
+
+	if (_osx_window)
+	{
+	
+		SetWRefCon (_osx_window, (long) this); // point to the window record in the ref con of the window
+		gWinEvtHandler = NewEventHandlerUPP(windowEvtHndlr); 
+		InstallWindowEventHandler (_osx_window, gWinEvtHandler, GetEventTypeCount (list), list, (void*)this, &ref); // add event handler
+		ShowWindow (_osx_window);
+			
+		buildGL();	
+
+        GrafPtr portSave = NULL;
+        GetPort (&portSave);
+        SetPort ((GrafPtr) GetWindowPort (_osx_window));
+
+		if(!aglSetDrawable(get_context(), GetWindowPort (_osx_window)))
+			err = aglReportError ();
+			
+		if (!aglSetCurrentContext(get_context()))
+			err = aglReportError ();
+		
+		// VBL SYNC
+		GLint swap = 1;	
+		if (!aglSetInteger (get_context(), AGL_SWAP_INTERVAL, &swap))
+			aglReportError ();
+
+        SetPort (portSave);		
+	}
+}
+
+//RunApplicationEventLoop();
+   WindowProperties properties;
+   
+   _properties.set_foreground(true);
+   _properties.set_minimized(false);
+   _properties.set_open(true);
+   	Rect				rectPort = {0,0,0,0};
+	if(_is_fullsreen)
+	{
+		CGDirectDisplayID display =   CGMainDisplayID ();
+
+		osxdisplay_cat.debug() << "Full Screen Size ["<< 	CGDisplayPixelsWide (display) <<","<< CGDisplayPixelsHigh (display) << "\n";
+//	  _properties.set_size((int)800,(int) 600);
+	_properties.set_size((int)CGDisplayPixelsWide (display),(int) CGDisplayPixelsHigh (display));
+	  _properties.set_origin((int) 0,(int)0);
+	}
+	else
+	{
+		GetWindowPortBounds (_osx_window, &rectPort); 	
+	  _properties.set_size((int)(rectPort.right - rectPort.left),(int) (rectPort.bottom - rectPort.top));
+	  _properties.set_origin((int) rectPort.left,(int)rectPort.top);
+	
+	}
+	return true;
+}
+
+void osxGraphicsWindow::process_events()
+{
+	GraphicsWindow::process_events();
+	EventRef theEvent;
+	EventTargetRef theTarget;
+	theTarget = GetEventDispatcherTarget();
+ 
+//    while  (ReceiveNextEvent(0, NULL,kEventDurationForever,true, &theEvent)== noErr)
+    while  (ReceiveNextEvent(0, NULL,kEventDurationNoWait,true, &theEvent)== noErr)
+        {
+            SendEventToEventTarget (theEvent, theTarget);
+            ReleaseEvent(theEvent);
+        }
+
+};
+// ---------------------------------
+
+// handle display config changes meaing we need to update the GL context via the resize function and check for windwo dimension changes
+// also note we redraw the content here as it could be lost in a display config change
+void handleWindowDMEvent (void *userData, short theMessage, void *notifyData)
+{
+
+	if (kDMNotifyEvent == theMessage) { // post change notifications only
+		osxGraphicsWindow * osxwin = NULL;
+		WindowRef window = (WindowRef) userData;
+		if (window)
+			osxwin = GetCurrentOSxWindow (window);
+		if (osxwin) { // have a valid OpenGl window
+			Rect rectPort;
+			CGRect viewRect = {{0.0f, 0.0f}, {0.0f, 0.0f}};
+			GetWindowPortBounds (window, &rectPort);
+			viewRect.size.width = (float) (rectPort.right - rectPort.left);
+			viewRect.size.height = (float) (rectPort.bottom - rectPort.top);
+			//resizeGL (pContextInfo->aglContext, &pContextInfo->camera, pContextInfo->shapeSize, viewRect);
+			InvalWindowRect (window,  &rectPort); // force redrow
+		}
+	}
+}
+/*
+	
+
+EventRef     theTextEvent;
+UniChar      *text;
+UInt32       actualSize; 
+ 
+GetEventParameter (theTextEvent, kEventParamTextInputSendText,
+                typeUnicodeText, NULL, 0, &actualSize, NULL);
+ 
+text = (UniChar*) NewPtr(actualSize);
+ 
+ 
+GetEventParameter (theTextEvent, kEventParamTextInputSendText,
+                typeUnicodeText, NULL, actualSize, NULL, text);
+
+*/
+
+// key input handler
+OSStatus osxGraphicsWindow::handleKeyInput (EventHandlerCallRef myHandler, EventRef event, Boolean keyDown)
+{
+	OSStatus result = eventNotHandledErr;
+
+	result = CallNextEventHandler(myHandler, event);	
+	if (eventNotHandledErr == result) 
+	{ 
+			UInt32 newModifiers = 0;
+			OSStatus error = GetEventParameter(event, kEventParamKeyModifiers,typeUInt32, NULL,sizeof(UInt32), NULL, &newModifiers);
+			if(error == noErr)						   
+				HandleModifireDeleta(newModifiers);
+	
+			UInt32 keyCode;
+			GetEventParameter (event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
+			if(keyDown)
+			{
+			  SendKeyEvent(OSX_TranslateKey( keyCode , event ),true);
+			}
+			else
+			{
+			  SendKeyEvent(OSX_TranslateKey( keyCode , event ),false);
+			   
+			}
+	}	
+			
+	return result;
+}
+
+
+void osxGraphicsWindow::SystemSetWindowForground(bool forground)
+{
+	  WindowProperties properties;
+      properties.set_foreground(forground);
+	  system_changed_properties(properties);
+};		
+	
+ void osxGraphicsWindow::SystemPointToLocalPoint(Point &qdGlobalPoint)
+ {
+    GrafPtr savePort;
+    GetPort( &savePort );
+    SetPortWindowPort(_osx_window );
+    GlobalToLocal( &qdGlobalPoint );
+    SetPort( savePort );				
+ };
+	
+	
+OSStatus osxGraphicsWindow::handleWindowMouseEvents (EventHandlerCallRef myHandler, EventRef event)
+{
+    WindowRef			window = NULL;
+ //   pRecContext 		pContextInfo = NULL;
+	OSStatus			result = eventNotHandledErr;
+    UInt32 				kind = GetEventKind (event);
+	EventMouseButton	button = 0;
+//	HIPoint				location = {0.0f, 0.0f};
+	Point qdGlobalPoint = {0, 0};
+	UInt32				modifiers = 0;	
+	long				wheelDelta = 0;		
+	Rect 				rectPort;
+
+	// Mac OS X v10.1 and later
+	// should this be front window???
+	GetEventParameter(event, kEventParamWindowRef, typeWindowRef, NULL, sizeof(WindowRef), NULL, &window);
+//	if (window)
+//		pContextInfo = GetCurrentContextInfo (window);
+//	if (!pContextInfo)
+//		return result; // not an application GLWindow so do not process (there is an exception)
+	GetWindowPortBounds (window, &rectPort);
+		
+	//printf(" Got Mouse Event \n");	
+		
+	result = CallNextEventHandler(myHandler, event);	
+	if (eventNotHandledErr == result) 
+	{ // only handle events not already handled (prevents wierd resize interaction)
+		switch (kind) {
+			// start trackball, pan, or dolly
+			case kEventMouseDown:
+			{
+				GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &button);
+//				GetEventParameter(event, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(HIPoint), NULL, &location);	// Mac OS X v10.1 and later
+				GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
+				GetEventParameter(event, kEventParamMouseLocation,typeQDPoint, NULL, sizeof(Point),NULL	, (void*) &qdGlobalPoint);
+				SystemPointToLocalPoint(qdGlobalPoint);
+    
+				ButtonHandle button_h = MouseButton::one();
+				if(kEventMouseButtonSecondary == button)
+					button_h = MouseButton::two();
+				if(kEventMouseButtonTertiary == button)
+					button_h = MouseButton::three();
+				 
+//					cerr << " Mouse Down "	 <<  location.x << " " << location.y << " "<<  button_h << "\n" ;
+//					cerr << " Mouse Down "	 <<  qdGlobalPoint.h << " " << qdGlobalPoint.v << " "<<  button_h << "\n" ;		
+//					cerr << " Window Port " << 	rectPort.top << " " << rectPort.bottom ;
+//				    _input_devices[0].set_pointer_in_window((int)location.x, (int)location.y);
+				    _input_devices[0].set_pointer_in_window((int)qdGlobalPoint.h, (int)qdGlobalPoint.v);
+ 	 		 	   _input_devices[0].button_down(button_h);
+			}
+				break;
+			// stop trackball, pan, or dolly
+			case kEventMouseUp:
+				{
+				GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &button);
+//				GetEventParameter(event, kEventParamWindowMouseLocation, typeHIPoint, NULL, sizeof(HIPoint), NULL, &location);	// Mac OS X v10.1 and later
+				GetEventParameter(event, kEventParamMouseLocation,typeQDPoint, NULL, sizeof(Point),NULL	, (void*) &qdGlobalPoint);
+				SystemPointToLocalPoint(qdGlobalPoint);
+				
+				ButtonHandle button_h = MouseButton::one();
+				if(kEventMouseButtonSecondary == button)
+					button_h = MouseButton::two();
+				if(kEventMouseButtonTertiary == button)
+					button_h = MouseButton::three();
+					
+//					cerr << " Mouse Up "	 <<  location.x << " " << location.y << " "<< button_h << "\n";
+//					cerr << " Mouse up "	 <<  qdGlobalPoint.h << " " << qdGlobalPoint.v << " "<<  button_h << "\n" ;
+
+				    _input_devices[0].set_pointer_in_window((int)qdGlobalPoint.h, (int)qdGlobalPoint.v);
+				   _input_devices[0].button_up(button_h);
+				}
+				break;
+			case kEventMouseMoved:	
+			case kEventMouseDragged:
+//				GetEventParameter(event, kEventParamWindowMouseLocation, typeHIPoint, NULL, sizeof(HIPoint), NULL, &location);	// Mac OS X v10.1 and later
+//				GetEventParameter(event, kEventParamWindowMouseLocation, typeHIPoint, NULL, sizeof(HIPoint), NULL, &location);	// Mac OS X v10.1 and later
+//					_input_devices[0].set_pointer_in_window((int)location.x, (int)location.y);
+//				 _input_devices[0].set_pointer_in_window(event.xmotion.x, event.xmotion.y);
+				GetEventParameter(event, kEventParamMouseLocation,typeQDPoint, NULL, sizeof(Point),NULL	, (void*) &qdGlobalPoint);
+				SystemPointToLocalPoint(qdGlobalPoint);
+
+			    _input_devices[0].set_pointer_in_window((int)qdGlobalPoint.h, (int)qdGlobalPoint.v);
+				 
+				break;
+			case kEventMouseWheelMoved: 
+				GetEventParameter(event, kEventParamMouseWheelDelta, typeLongInteger, NULL, sizeof(long), NULL, &wheelDelta);
+				break;
+		}
+		result = noErr;
+	}	
+	return result;
+}
+
+
+ButtonHandle OSX_TranslateKey( UInt32 key,   EventRef event)
+{
+
+
+	ButtonHandle nk = ButtonHandle::none();
+	switch ( key )
+	{
+	case 0:    nk = KeyboardButton::ascii_key('a');       break;
+	case 11:   nk = KeyboardButton::ascii_key('b');       break;
+	case 8:    nk = KeyboardButton::ascii_key('c');       break;
+	case 2:    nk = KeyboardButton::ascii_key('d');       break;
+	case 14:   nk = KeyboardButton::ascii_key('e');       break;
+	case 3:    nk = KeyboardButton::ascii_key('f');       break;
+	case 5:    nk = KeyboardButton::ascii_key('g');       break;
+	case 4:    nk = KeyboardButton::ascii_key('h');       break;
+	case 34:   nk = KeyboardButton::ascii_key('i');       break;
+	case 38:   nk = KeyboardButton::ascii_key('j');       break;
+	case 40:   nk = KeyboardButton::ascii_key('k');       break;
+	case 37:   nk = KeyboardButton::ascii_key('l');       break;
+	case 46:   nk = KeyboardButton::ascii_key('m');       break;
+	case 45:   nk = KeyboardButton::ascii_key('n');       break;
+	case 31:   nk = KeyboardButton::ascii_key('o');       break;
+	case 35:   nk = KeyboardButton::ascii_key('p');       break;
+	case 12:   nk = KeyboardButton::ascii_key('q');       break;
+	case 15:   nk = KeyboardButton::ascii_key('r');       break;
+	case 1:    nk = KeyboardButton::ascii_key('s');       break;
+	case 17:   nk = KeyboardButton::ascii_key('t');       break;
+	case 32:   nk = KeyboardButton::ascii_key('u');       break;
+	case 9:    nk = KeyboardButton::ascii_key('v');       break;
+	case 13:   nk = KeyboardButton::ascii_key('w');       break;
+	case 7:    nk = KeyboardButton::ascii_key('x');       break;
+	case 16:   nk = KeyboardButton::ascii_key('y');       break;
+	case 6:    nk = KeyboardButton::ascii_key('z');       break;
+
+	// top row numbers
+	case 29:   nk = KeyboardButton::ascii_key('0');       break;
+	case 18:   nk = KeyboardButton::ascii_key('1');       break;
+	case 19:   nk = KeyboardButton::ascii_key('2');       break;
+	case 20:   nk = KeyboardButton::ascii_key('3');       break;
+	case 21:   nk = KeyboardButton::ascii_key('4');       break;
+	case 23:   nk = KeyboardButton::ascii_key('5');       break;
+	case 22:   nk = KeyboardButton::ascii_key('6');       break;
+	case 26:   nk = KeyboardButton::ascii_key('7');       break;
+	case 28:   nk = KeyboardButton::ascii_key('8');       break;
+	case 25:   nk = KeyboardButton::ascii_key('9');       break;
+	
+    // key pad ... do they really map to the top number in panda ?
+	case 82:   nk = KeyboardButton::ascii_key('0');       break;
+	case 83:   nk = KeyboardButton::ascii_key('1');       break;
+	case 84:   nk = KeyboardButton::ascii_key('2');       break;
+	case 85:   nk = KeyboardButton::ascii_key('3');       break;
+	case 86:   nk = KeyboardButton::ascii_key('4');       break;
+	case 87:   nk = KeyboardButton::ascii_key('5');       break;
+	case 88:   nk = KeyboardButton::ascii_key('6');       break;
+	case 89:   nk = KeyboardButton::ascii_key('7');       break;
+	case 91:   nk = KeyboardButton::ascii_key('8');       break;
+	case 92:   nk = KeyboardButton::ascii_key('9');       break;
+
+
+//	case 36:   nk = KeyboardButton::ret();			  break;   // no return  in panda ???
+	case 49:   nk = KeyboardButton::space();		 	  break;
+	case 51:   nk = KeyboardButton::backspace();		  break;
+	case 48:   nk = KeyboardButton::tab();				  break;
+	case 53:   nk = KeyboardButton::escape();			  break;
+	case 76:   nk = KeyboardButton::enter();			  break;	
+	case 36:   nk = KeyboardButton::enter();			  break;	
+	
+	case 123:  nk = KeyboardButton::left();				  break;
+	case 124:  nk = KeyboardButton::right();			  break;
+	case 125:  nk = KeyboardButton::down();				  break;
+	case 126:  nk = KeyboardButton::up();				  break;
+	case 116:  nk = KeyboardButton::page_up();				  break;
+	case 121:  nk = KeyboardButton::page_down();				  break;
+	case 115:  nk = KeyboardButton::home();				  break;
+	case 119:  nk = KeyboardButton::end();				  break;
+//	case    :  nk = KeyboardButton::insert();			  break;			
+	case 117:  nk = KeyboardButton::del();			  break;			
+	
+//	case  71:  nk = KeyboardButton::num_lock()        break; 
+
+	case 122:  nk = KeyboardButton::f1();				  break;
+	case 120:  nk = KeyboardButton::f2();				  break;
+	case  99:  nk = KeyboardButton::f3();				  break;
+	case 118:  nk = KeyboardButton::f4();				  break;
+	case  96:  nk = KeyboardButton::f5();				  break;
+	case  97:  nk = KeyboardButton::f6();				  break;
+	case  98:  nk = KeyboardButton::f7();				  break;
+	case 100:  nk = KeyboardButton::f8();				  break;
+//	case    :  nk = KeyboardButton::f9();				  break;  // seem to be used by the systems..
+//	case    :  nk = KeyboardButton::f10();				  break;
+//	case    :  nk = KeyboardButton::f11();				  break;
+//	case    :  nk = KeyboardButton::f12();				  break;
+//	case 105:  nk = KeyboardButton::f13();				  break;  // panda does not have a 13
+	
+	// shiftable chartablet 
+	case  50:  nk = KeyboardButton::ascii_key('`');				  break;
+	case  27:  nk = KeyboardButton::ascii_key('-');				  break;
+	case  24:  nk = KeyboardButton::ascii_key('=');				  break;
+	case  33:  nk = KeyboardButton::ascii_key('[');				  break;
+	case  30:  nk = KeyboardButton::ascii_key(']');				  break;
+	case  42:  nk = KeyboardButton::ascii_key('\\');			  break;
+	case  41:  nk = KeyboardButton::ascii_key(';');				  break;
+	case  39:  nk = KeyboardButton::ascii_key('\'');			  break;
+	case  43:  nk = KeyboardButton::ascii_key(',');				  break;
+	case  47:  nk = KeyboardButton::ascii_key('.');				  break;
+	case  44:  nk = KeyboardButton::ascii_key('/');				  break;
+	
+	default:
+//		 printf (" Untranslated KeyCode: %lu (0x%lX)\n", key, key);
+			// not sure this is right .. but no mapping for keypad and such
+			// this at least does a best gess..
+			
+        char charCode =  0;	
+        if(GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, nil, sizeof( charCode ), nil, &charCode ) == noErr)
+			nk = KeyboardButton::ascii_key(charCode);	
+	}
+	return nk;
+}
+
+
+ void     osxGraphicsWindow::HandleModifireDeleta(UInt32 newModifiers)
+ {
+	 UInt32 changed = _last_key_modifiers ^ newModifiers;
+	 
+	
+    if ((changed & (shiftKey | rightShiftKey)) != 0)
+		SendKeyEvent(KeyboardButton::shift(),(newModifiers & (shiftKey | rightShiftKey)) != 0) ;
+		
+    if ((changed & (optionKey | rightOptionKey)) != 0) 
+		SendKeyEvent(KeyboardButton::alt(),(newModifiers & (optionKey | rightOptionKey)) != 0);
+
+	
+	if ((changed & (controlKey | rightControlKey)) != 0) 
+		SendKeyEvent(KeyboardButton::control(),(newModifiers & (controlKey | rightControlKey)) != 0);
+	
+    if ((changed & alphaLock) != 0) 
+		SendKeyEvent(KeyboardButton::caps_lock(),(newModifiers & alphaLock) != 0);
+	
+	// save current state
+    _last_key_modifiers = newModifiers;						   
+								
+ };
+

+ 132 - 0
panda/src/osxdisplay/osxGraphicsWindow.h

@@ -0,0 +1,132 @@
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef OSXGRAPHICSWINDOW_H
+#define OSXGRAPHICSWINDOW_H
+#include <Carbon/Carbon.h>
+
+
+#define __glext_h_
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#include <AGL/agl.h>
+
+
+#include "pandabase.h"
+#include "graphicsWindow.h"
+#include "buttonHandle.h"
+
+
+#define HACK_SCREEN_HASH_CONTEXT true
+OSStatus aglReportError (void);
+
+////////////////////////////////////////////////////////////////////
+//       Class : osxGraphicsWindow
+// Description : An interface to the osx/ system for managing GL
+//               windows under X.
+////////////////////////////////////////////////////////////////////
+class osxGraphicsWindow : public GraphicsWindow {
+public:
+  osxGraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
+                    const string &name);
+  virtual ~osxGraphicsWindow();
+
+//  virtual bool move_pointer(int device, int x, int y);
+
+  //virtual bool make_context();
+  virtual void make_current();
+  virtual void release_gsg();
+
+  virtual bool begin_frame(FrameMode mode);
+  virtual void end_frame(FrameMode mode);
+
+  virtual void begin_flip();
+
+  virtual void process_events();
+
+
+  void   ReleaseSystemResources();
+
+
+protected:
+  virtual void close_window();
+  virtual bool open_window();
+
+private:
+
+public: // do not call direct ..
+  OSStatus handleKeyInput (EventHandlerCallRef myHandler, EventRef event, Boolean keyDown);
+  OSStatus handleTextInput (EventHandlerCallRef myHandler, EventRef event);
+  OSStatus handleWindowMouseEvents (EventHandlerCallRef myHandler, EventRef event);
+  void     HandleModifireDeleta(UInt32 modifiers);
+  void     DoResize(void);
+
+
+  void SystemCloseWindow();	
+  void SystemSetWindowForground(bool forground);	
+  void SystemPointToLocalPoint(Point &qdGlobalPoint);
+
+  AGLContext  osxGraphicsWindow::get_ggs_context(void);
+  AGLContext  get_context(void);
+  OSStatus	  buildGL(void);
+	
+	
+  inline void SendKeyEvent( ButtonHandle  key, bool down)
+  {
+     if(down)
+		_input_devices[0].button_down(key);
+	else
+		_input_devices[0].button_up(key);
+  }
+
+
+	inline bool IsAlive(void)
+	{
+	    return (_is_fullsreen || _osx_window != NULL);
+	}
+
+	WindowProperties & properties() { return _properties; };
+private:
+	UInt32			_last_key_modifiers;
+     WindowRef		_osx_window;
+	bool           _is_fullsreen;
+
+#ifdef HACK_SCREEN_HASH_CONTEXT
+  AGLPixelFormat	_aglPixFmt;
+  AGLContext		_aglcontext;
+#endif
+	CFDictionaryRef _originalMode;
+	 
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    GraphicsWindow::init_type();
+    register_type(_type_handle, "osxGraphicsWindow",
+                  GraphicsWindow::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
+