Просмотр исходного кода

further robustness for WxPandaWindow on Linux

David Rose 14 лет назад
Родитель
Сommit
1fd8a621ff

+ 27 - 14
direct/src/wxwidgets/WxPandaWindow.py

@@ -146,6 +146,7 @@ else:
                 
                 
             base.startWx()
             base.startWx()
             wxgl.GLCanvas.__init__(self, *args, **kw)
             wxgl.GLCanvas.__init__(self, *args, **kw)
+            self.visible = False
                 
                 
             # Can't share the GSG when a new wxgl.GLContext is created
             # Can't share the GSG when a new wxgl.GLContext is created
             # automatically.
             # automatically.
@@ -170,23 +171,27 @@ else:
             if pipe.getInterfaceName() != 'OpenGL':
             if pipe.getInterfaceName() != 'OpenGL':
                 raise StandardError, "Couldn't get an OpenGL pipe."
                 raise StandardError, "Couldn't get an OpenGL pipe."
 
 
-
             self.win = base.openWindow(callbackWindowDict = callbackWindowDict, pipe = pipe, gsg = gsg, type = 'onscreen')
             self.win = base.openWindow(callbackWindowDict = callbackWindowDict, pipe = pipe, gsg = gsg, type = 'onscreen')
-            self.inputDevice = self.win.getInputDevice(0)
+            self.inputDevice = None
+            if hasattr(self.win, 'getInputDevice'):
+                self.inputDevice = self.win.getInputDevice(0)
 
 
             self.Bind(wx.EVT_SIZE, self.onSize)
             self.Bind(wx.EVT_SIZE, self.onSize)
+            self.Bind(wx.EVT_PAINT, self.onPaint)
             self.Bind(wx.EVT_IDLE, self.onIdle)
             self.Bind(wx.EVT_IDLE, self.onIdle)
-            self.Bind(wx.EVT_LEFT_DOWN, lambda event: self.__buttonDown(MouseButton.one()))
-            self.Bind(wx.EVT_LEFT_UP, lambda event: self.__buttonUp(MouseButton.one()))
-            self.Bind(wx.EVT_MIDDLE_DOWN, lambda event: self.__buttonDown(MouseButton.two()))
-            self.Bind(wx.EVT_MIDDLE_UP, lambda event: self.__buttonUp(MouseButton.two()))
-            self.Bind(wx.EVT_RIGHT_DOWN, lambda event: self.__buttonDown(MouseButton.three()))
-            self.Bind(wx.EVT_RIGHT_UP, lambda event: self.__buttonUp(MouseButton.three()))
-            self.Bind(wx.EVT_MOTION, self.__mouseMotion)
-            self.Bind(wx.EVT_LEAVE_WINDOW, self.__mouseLeaveWindow)
-            self.Bind(wx.EVT_KEY_DOWN, self.__keyDown)
-            self.Bind(wx.EVT_KEY_UP, self.__keyUp)
-            self.Bind(wx.EVT_CHAR, self.__keystroke)
+
+            if self.inputDevice:
+                self.Bind(wx.EVT_LEFT_DOWN, lambda event: self.__buttonDown(MouseButton.one()))
+                self.Bind(wx.EVT_LEFT_UP, lambda event: self.__buttonUp(MouseButton.one()))
+                self.Bind(wx.EVT_MIDDLE_DOWN, lambda event: self.__buttonDown(MouseButton.two()))
+                self.Bind(wx.EVT_MIDDLE_UP, lambda event: self.__buttonUp(MouseButton.two()))
+                self.Bind(wx.EVT_RIGHT_DOWN, lambda event: self.__buttonDown(MouseButton.three()))
+                self.Bind(wx.EVT_RIGHT_UP, lambda event: self.__buttonUp(MouseButton.three()))
+                self.Bind(wx.EVT_MOTION, self.__mouseMotion)
+                self.Bind(wx.EVT_LEAVE_WINDOW, self.__mouseLeaveWindow)
+                self.Bind(wx.EVT_KEY_DOWN, self.__keyDown)
+                self.Bind(wx.EVT_KEY_UP, self.__keyUp)
+                self.Bind(wx.EVT_CHAR, self.__keystroke)
 
 
             # This doesn't actually do anything, since wx won't call
             # This doesn't actually do anything, since wx won't call
             # EVT_CLOSE on a child window, only on the toplevel window
             # EVT_CLOSE on a child window, only on the toplevel window
@@ -263,7 +268,7 @@ else:
         def __renderCallback(self, data):
         def __renderCallback(self, data):
             cbType = data.getCallbackType()
             cbType = data.getCallbackType()
             if cbType == CallbackGraphicsWindow.RCTBeginFrame:
             if cbType == CallbackGraphicsWindow.RCTBeginFrame:
-                if not self.IsShownOnScreen():
+                if not self.visible or not self.IsShownOnScreen():
                     data.setRenderFlag(False)
                     data.setRenderFlag(False)
                     return
                     return
                 self.SetCurrent()
                 self.SetCurrent()
@@ -291,6 +296,14 @@ else:
             
             
             event.Skip()
             event.Skip()
 
 
+        def onPaint(self, event):
+            """ This is called whenever we get the fisrt paint event,
+            at which point we can conclude that the window has
+            actually been manifested onscreen.  (In X11, there appears
+            to be no way to know this otherwise.) """
+            self.visible = True
+            event.Skip()
+
         def onIdle(self, event):
         def onIdle(self, event):
             size = None
             size = None
             properties = self.win.getProperties()
             properties = self.win.getProperties()

+ 2 - 0
panda/src/glxdisplay/Sources.pp

@@ -20,6 +20,8 @@
     glxGraphicsWindow.h glxGraphicsWindow.cxx \
     glxGraphicsWindow.h glxGraphicsWindow.cxx \
     glxGraphicsStateGuardian.h glxGraphicsStateGuardian.I \
     glxGraphicsStateGuardian.h glxGraphicsStateGuardian.I \
     glxGraphicsStateGuardian.cxx \
     glxGraphicsStateGuardian.cxx \
+    posixGraphicsStateGuardian.h posixGraphicsStateGuardian.I \
+    posixGraphicsStateGuardian.cxx \
     panda_glxext.h
     panda_glxext.h
 
 
   #define INSTALL_HEADERS \
   #define INSTALL_HEADERS \

+ 2 - 0
panda/src/glxdisplay/config_glxdisplay.cxx

@@ -19,6 +19,7 @@
 #include "glxGraphicsBuffer.h"
 #include "glxGraphicsBuffer.h"
 #include "glxGraphicsWindow.h"
 #include "glxGraphicsWindow.h"
 #include "glxGraphicsStateGuardian.h"
 #include "glxGraphicsStateGuardian.h"
+#include "posixGraphicsStateGuardian.h"
 #include "graphicsPipeSelection.h"
 #include "graphicsPipeSelection.h"
 #include "dconfig.h"
 #include "dconfig.h"
 #include "pandaSystem.h"
 #include "pandaSystem.h"
@@ -94,6 +95,7 @@ init_libglxdisplay() {
   glxGraphicsBuffer::init_type();
   glxGraphicsBuffer::init_type();
   glxGraphicsWindow::init_type();
   glxGraphicsWindow::init_type();
   glxGraphicsStateGuardian::init_type();
   glxGraphicsStateGuardian::init_type();
+  PosixGraphicsStateGuardian::init_type();
 
 
   GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr();
   GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr();
   selection->add_pipe_type(glxGraphicsPipe::get_class_type(),
   selection->add_pipe_type(glxGraphicsPipe::get_class_type(),

+ 5 - 1
panda/src/glxdisplay/glxGraphicsPipe.cxx

@@ -17,6 +17,7 @@
 #include "glxGraphicsBuffer.h"
 #include "glxGraphicsBuffer.h"
 #include "glxGraphicsPixmap.h"
 #include "glxGraphicsPixmap.h"
 #include "glxGraphicsStateGuardian.h"
 #include "glxGraphicsStateGuardian.h"
+#include "posixGraphicsStateGuardian.h"
 #include "config_glxdisplay.h"
 #include "config_glxdisplay.h"
 #include "frameBufferProperties.h"
 #include "frameBufferProperties.h"
 
 
@@ -217,5 +218,8 @@ make_output(const string &name,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(GraphicsStateGuardian) glxGraphicsPipe::
 PT(GraphicsStateGuardian) glxGraphicsPipe::
 make_callback_gsg(GraphicsEngine *engine) {
 make_callback_gsg(GraphicsEngine *engine) {
-  return new glxGraphicsStateGuardian(engine, this, NULL);
+  // We create a PosixGraphicsStateGuardian instead of a
+  // glxGraphicsStateGuardian, because the externally-created context
+  // might not have anything to do with the glx interface.
+  return new PosixGraphicsStateGuardian(engine, this);
 }
 }

+ 7 - 48
panda/src/glxdisplay/glxGraphicsStateGuardian.cxx

@@ -30,7 +30,7 @@ TypeHandle glxGraphicsStateGuardian::_type_handle;
 glxGraphicsStateGuardian::
 glxGraphicsStateGuardian::
 glxGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
 glxGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
                          glxGraphicsStateGuardian *share_with) :
                          glxGraphicsStateGuardian *share_with) :
-  GLGraphicsStateGuardian(engine, pipe)
+  PosixGraphicsStateGuardian(engine, pipe)
 {
 {
   _share_context=0;
   _share_context=0;
   _context=0;
   _context=0;
@@ -53,7 +53,6 @@ glxGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
     _share_context = share_with->_context;
     _share_context = share_with->_context;
   }
   }
   
   
-  _libgl_handle = NULL;
   _checked_get_proc_address = false;
   _checked_get_proc_address = false;
   _glXGetProcAddress = NULL;
   _glXGetProcAddress = NULL;
   _temp_context = (GLXContext)NULL;
   _temp_context = (GLXContext)NULL;
@@ -76,9 +75,6 @@ glxGraphicsStateGuardian::
     glXDestroyContext(_display, _context);
     glXDestroyContext(_display, _context);
     _context = (GLXContext)NULL;
     _context = (GLXContext)NULL;
   }
   }
-  if (_libgl_handle != (void *)NULL) {
-    dlclose(_libgl_handle);
-  }
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -399,7 +395,7 @@ choose_pixel_format(const FrameBufferProperties &properties,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void glxGraphicsStateGuardian::
 void glxGraphicsStateGuardian::
 reset() {
 reset() {
-  GLGraphicsStateGuardian::reset();
+  PosixGraphicsStateGuardian::reset();
 
 
   _supports_swap_control = has_extension("GLX_SGI_swap_control");
   _supports_swap_control = has_extension("GLX_SGI_swap_control");
 
 
@@ -564,7 +560,7 @@ void glxGraphicsStateGuardian::
 gl_flush() const {
 gl_flush() const {
   // This call requires synchronization with X.
   // This call requires synchronization with X.
   LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
   LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
-  GLGraphicsStateGuardian::gl_flush();
+  PosixGraphicsStateGuardian::gl_flush();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -576,7 +572,7 @@ GLenum glxGraphicsStateGuardian::
 gl_get_error() const {
 gl_get_error() const {
   // This call requires synchronization with X.
   // This call requires synchronization with X.
   LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
   LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
-  return GLGraphicsStateGuardian::gl_get_error();
+  return PosixGraphicsStateGuardian::gl_get_error();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -586,7 +582,7 @@ gl_get_error() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void glxGraphicsStateGuardian::
 void glxGraphicsStateGuardian::
 query_gl_version() {
 query_gl_version() {
-  GLGraphicsStateGuardian::query_gl_version();
+  PosixGraphicsStateGuardian::query_gl_version();
 
 
   show_glx_client_string("GLX_VENDOR", GLX_VENDOR);
   show_glx_client_string("GLX_VENDOR", GLX_VENDOR);
   show_glx_client_string("GLX_VERSION", GLX_VERSION);
   show_glx_client_string("GLX_VERSION", GLX_VERSION);
@@ -683,45 +679,8 @@ do_get_extension_func(const char *prefix, const char *name) {
 #endif // HAVE_GLXGETPROCADDRESS
 #endif // HAVE_GLXGETPROCADDRESS
   }
   }
 
 
-  if (glx_get_os_address) {
-    // Otherwise, fall back to the OS-provided calls.
-    return get_system_func(fullname.c_str());
-  }
-
-  return NULL;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: glxGraphicsStateGuardian::get_system_func
-//       Access: Private
-//  Description: Support for get_extension_func(), above, that uses
-//               system calls to find a GL or GLX function (in the
-//               absence of a working glxGetProcAddress() function to
-//               call).
-////////////////////////////////////////////////////////////////////
-void *glxGraphicsStateGuardian::
-get_system_func(const char *name) {
-  if (_libgl_handle == (void *)NULL) {
-    // We open the current executable, rather than naming a particular
-    // library.  Presumably libGL.so (or whatever the library should
-    // be called) is already available in the current executable
-    // address space, so this is more portable than insisting on a
-    // particular shared library name.
-    _libgl_handle = dlopen(NULL, RTLD_LAZY);
-    nassertr(_libgl_handle != (void *)NULL, NULL);
-
-    // If that doesn't locate the symbol we expected, then fall back
-    // to loading the GL library by its usual name.
-    if (dlsym(_libgl_handle, name) == NULL) {
-      dlclose(_libgl_handle);
-      glxdisplay_cat.warning()
-        << name << " not found in executable; looking in libGL.so instead.\n";
-      _libgl_handle = dlopen("libGL.so", RTLD_LAZY);
-      nassertr(_libgl_handle != (void *)NULL, NULL);
-    }
-  }
-
-  return dlsym(_libgl_handle, name);
+  // Otherwise, fall back to the OS-provided calls.
+  return PosixGraphicsStateGuardian::do_get_extension_func(prefix, name);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 4 - 5
panda/src/glxdisplay/glxGraphicsStateGuardian.h

@@ -19,6 +19,7 @@
 
 
 #include "glgsg.h"
 #include "glgsg.h"
 #include "glxGraphicsPipe.h"
 #include "glxGraphicsPipe.h"
+#include "posixGraphicsStateGuardian.h"
 
 
 #if defined(GLX_VERSION_1_4)
 #if defined(GLX_VERSION_1_4)
 // If the system header files give us version 1.4, we can assume it's
 // If the system header files give us version 1.4, we can assume it's
@@ -74,7 +75,7 @@ typedef void (* PFNGLXDESTROYPBUFFERPROC) (X11_Display *dpy, GLXPbuffer pbuf);
 // Description : A tiny specialization on GLGraphicsStateGuardian to
 // Description : A tiny specialization on GLGraphicsStateGuardian to
 //               add some glx-specific information.
 //               add some glx-specific information.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-class glxGraphicsStateGuardian : public GLGraphicsStateGuardian {
+class glxGraphicsStateGuardian : public PosixGraphicsStateGuardian {
 public:
 public:
   INLINE const FrameBufferProperties &get_fb_properties() const;
   INLINE const FrameBufferProperties &get_fb_properties() const;
   void get_properties(FrameBufferProperties &properties, XVisualInfo *visual);
   void get_properties(FrameBufferProperties &properties, XVisualInfo *visual);
@@ -134,7 +135,6 @@ protected:
   virtual void *do_get_extension_func(const char *prefix, const char *name);
   virtual void *do_get_extension_func(const char *prefix, const char *name);
 
 
 private:
 private:
-  void *get_system_func(const char *name);
   void show_glx_client_string(const string &name, int id);
   void show_glx_client_string(const string &name, int id);
   void show_glx_server_string(const string &name, int id);
   void show_glx_server_string(const string &name, int id);
   void choose_temp_visual(const FrameBufferProperties &properties);
   void choose_temp_visual(const FrameBufferProperties &properties);
@@ -143,7 +143,6 @@ private:
 
 
   int _glx_version_major, _glx_version_minor;
   int _glx_version_major, _glx_version_minor;
 
 
-  void *_libgl_handle;
   bool _checked_get_proc_address;
   bool _checked_get_proc_address;
   PFNGLXGETPROCADDRESSPROC _glXGetProcAddress;
   PFNGLXGETPROCADDRESSPROC _glXGetProcAddress;
 
 
@@ -156,9 +155,9 @@ public:
     return _type_handle;
     return _type_handle;
   }
   }
   static void init_type() {
   static void init_type() {
-    GLGraphicsStateGuardian::init_type();
+    PosixGraphicsStateGuardian::init_type();
     register_type(_type_handle, "glxGraphicsStateGuardian",
     register_type(_type_handle, "glxGraphicsStateGuardian",
-                  GLGraphicsStateGuardian::get_class_type());
+                  PosixGraphicsStateGuardian::get_class_type());
   }
   }
   virtual TypeHandle get_type() const {
   virtual TypeHandle get_type() const {
     return get_class_type();
     return get_class_type();

+ 13 - 0
panda/src/glxdisplay/posixGraphicsStateGuardian.I

@@ -0,0 +1,13 @@
+// Filename: posixGraphicsStateGuardian.I
+// Created by:  drose (14Jan12)
+//
+////////////////////////////////////////////////////////////////////
+//
+// 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."
+//
+////////////////////////////////////////////////////////////////////

+ 99 - 0
panda/src/glxdisplay/posixGraphicsStateGuardian.cxx

@@ -0,0 +1,99 @@
+// Filename: posixGraphicsStateGuardian.cxx
+// Created by:  drose (14Jan12)
+//
+////////////////////////////////////////////////////////////////////
+//
+// 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 "posixGraphicsStateGuardian.h"
+#include "config_glxdisplay.h"
+#include <dlfcn.h>
+
+TypeHandle PosixGraphicsStateGuardian::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: PosixGraphicsStateGuardian::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+PosixGraphicsStateGuardian::
+PosixGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe) :
+  GLGraphicsStateGuardian(engine, pipe)
+{
+  _libgl_handle = NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PosixGraphicsStateGuardian::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+PosixGraphicsStateGuardian::
+~PosixGraphicsStateGuardian() {
+  if (_libgl_handle != (void *)NULL) {
+    dlclose(_libgl_handle);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PosixGraphicsStateGuardian::do_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 *PosixGraphicsStateGuardian::
+do_get_extension_func(const char *prefix, const char *name) {
+  nassertr(prefix != NULL, NULL);
+  nassertr(name != NULL, NULL);
+  string fullname = string(prefix) + string(name);
+
+  if (glx_get_os_address) {
+    return get_system_func(fullname.c_str());
+  }
+
+  return NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PosixGraphicsStateGuardian::get_system_func
+//       Access: Protected
+//  Description: Support for get_extension_func(), above, that uses
+//               system calls to find a GL or GLX function (in the
+//               absence of a working glxGetProcAddress() function to
+//               call).
+////////////////////////////////////////////////////////////////////
+void *PosixGraphicsStateGuardian::
+get_system_func(const char *name) {
+  if (_libgl_handle == (void *)NULL) {
+    // We open the current executable, rather than naming a particular
+    // library.  Presumably libGL.so (or whatever the library should
+    // be called) is already available in the current executable
+    // address space, so this is more portable than insisting on a
+    // particular shared library name.
+    _libgl_handle = dlopen(NULL, RTLD_LAZY);
+    nassertr(_libgl_handle != (void *)NULL, NULL);
+
+    // If that doesn't locate the symbol we expected, then fall back
+    // to loading the GL library by its usual name.
+    if (dlsym(_libgl_handle, name) == NULL) {
+      dlclose(_libgl_handle);
+      glxdisplay_cat.warning()
+        << name << " not found in executable; looking in libGL.so instead.\n";
+      _libgl_handle = dlopen("libGL.so", RTLD_LAZY);
+      nassertr(_libgl_handle != (void *)NULL, NULL);
+    }
+  }
+
+  return dlsym(_libgl_handle, name);
+}

+ 61 - 0
panda/src/glxdisplay/posixGraphicsStateGuardian.h

@@ -0,0 +1,61 @@
+// Filename: posixGraphicsStateGuardian.h
+// Created by:  drose (14Jan12)
+//
+////////////////////////////////////////////////////////////////////
+//
+// 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 POSIXGRAPHICSSTATEGUARDIAN_H
+#define POSIXGRAPHICSSTATEGUARDIAN_H
+
+#include "pandabase.h"
+
+#include "glgsg.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : PosixGraphicsStateGuardian
+// Description : This GSG is used only for CallbackGraphicsWindow
+//               (which might not be using the glx interfaces), to add
+//               the ability to peek in libGL.so to find the extension
+//               functions.
+////////////////////////////////////////////////////////////////////
+class PosixGraphicsStateGuardian : public GLGraphicsStateGuardian {
+public:
+  PosixGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe);
+  ~PosixGraphicsStateGuardian();
+
+protected:
+  virtual void *do_get_extension_func(const char *prefix, const char *name);
+  void *get_system_func(const char *name);
+
+private:
+  void *_libgl_handle;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    GLGraphicsStateGuardian::init_type();
+    register_type(_type_handle, "PosixGraphicsStateGuardian",
+                  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;
+};
+
+#include "posixGraphicsStateGuardian.I"
+
+#endif