+
+#define OSX_DEBUG_DRAWING 0
+
+void wxWidgetCocoaImpl::drawRect(void* rect, WXWidget slf, void *WXUNUSED(_cmd))
+{
+ CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
+ CGContextSaveGState( context );
+
+#if OSX_DEBUG_DRAWING
+ CGContextBeginPath( context );
+ CGContextMoveToPoint(context, 0, 0);
+ NSRect bounds = [self bounds];
+ CGContextAddLineToPoint(context, 10, 0);
+ CGContextMoveToPoint(context, 0, 0);
+ CGContextAddLineToPoint(context, 0, 10);
+ CGContextMoveToPoint(context, bounds.size.width, bounds.size.height);
+ CGContextAddLineToPoint(context, bounds.size.width, bounds.size.height-10);
+ CGContextMoveToPoint(context, bounds.size.width, bounds.size.height);
+ CGContextAddLineToPoint(context, bounds.size.width-10, bounds.size.height);
+ CGContextClosePath( context );
+ CGContextStrokePath(context);
+#endif
+
+ if ( !m_isFlipped )
+ {
+ CGContextTranslateCTM( context, 0, [m_osxView bounds].size.height );
+ CGContextScaleCTM( context, 1, -1 );
+ }
+
+ wxRegion updateRgn;
+ const NSRect *rects;
+ NSInteger count;
+
+ [slf getRectsBeingDrawn:&rects count:&count];
+ for ( int i = 0 ; i < count ; ++i )
+ {
+ updateRgn.Union(wxFromNSRect(slf, rects[i]) );
+ }
+
+ wxWindow* wxpeer = GetWXPeer();
+ wxpeer->GetUpdateRegion() = updateRgn;
+ wxpeer->MacSetCGContextRef( context );
+
+ bool handled = wxpeer->MacDoRedraw( 0 );
+
+ CGContextRestoreGState( context );
+
+ CGContextSaveGState( context );
+ if ( !handled )
+ {
+ // call super
+ SEL _cmd = @selector(drawRect:);
+ wxOSX_DrawRectHandlerPtr superimpl = (wxOSX_DrawRectHandlerPtr) [[slf superclass] instanceMethodForSelector:_cmd];
+ superimpl(slf, _cmd, *(NSRect*)rect);
+ CGContextRestoreGState( context );
+ CGContextSaveGState( context );
+ }
+ wxpeer->MacPaintChildrenBorders();
+ wxpeer->MacSetCGContextRef( NULL );
+ CGContextRestoreGState( context );
+}
+
+void wxWidgetCocoaImpl::controlAction( WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd), void *WXUNUSED(sender))
+{
+ wxWindow* wxpeer = (wxWindow*) GetWXPeer();
+ if ( wxpeer )
+ wxpeer->OSXHandleClicked(0);
+}
+
+void wxWidgetCocoaImpl::controlDoubleAction( WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd), void *WXUNUSED(sender))
+{
+}
+
+//
+
+#if OBJC_API_VERSION >= 2
+
+#define wxOSX_CLASS_ADD_METHOD( c, s, i, t ) \
+ class_addMethod(c, s, i, t );
+
+#else
+
+#define wxOSX_CLASS_ADD_METHOD( c, s, i, t ) \
+ { s, t, i },
+
+#endif
+
+void wxOSXCocoaClassAddWXMethods(Class c)
+{
+
+#if OBJC_API_VERSION < 2
+ static objc_method wxmethods[] =
+ {
+#endif
+
+ wxOSX_CLASS_ADD_METHOD(c, @selector(mouseDown:), (IMP) wxOSX_mouseEvent, "v@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(rightMouseDown:), (IMP) wxOSX_mouseEvent, "v@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(otherMouseDown:), (IMP) wxOSX_mouseEvent, "v@:@" )
+
+ wxOSX_CLASS_ADD_METHOD(c, @selector(mouseUp:), (IMP) wxOSX_mouseEvent, "v@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(rightMouseUp:), (IMP) wxOSX_mouseEvent, "v@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(otherMouseUp:), (IMP) wxOSX_mouseEvent, "v@:@" )
+
+ wxOSX_CLASS_ADD_METHOD(c, @selector(mouseMoved:), (IMP) wxOSX_mouseEvent, "v@:@" )
+
+ wxOSX_CLASS_ADD_METHOD(c, @selector(mouseDragged:), (IMP) wxOSX_mouseEvent, "v@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(rightMouseDragged:), (IMP) wxOSX_mouseEvent, "v@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(otherMouseDragged:), (IMP) wxOSX_mouseEvent, "v@:@" )
+
+ wxOSX_CLASS_ADD_METHOD(c, @selector(scrollWheel:), (IMP) wxOSX_mouseEvent, "v@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(mouseEntered:), (IMP) wxOSX_mouseEvent, "v@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(mouseExited:), (IMP) wxOSX_mouseEvent, "v@:@" )
+
+ wxOSX_CLASS_ADD_METHOD(c, @selector(keyDown:), (IMP) wxOSX_keyEvent, "v@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(keyUp:), (IMP) wxOSX_keyEvent, "v@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(flagsChanged:), (IMP) wxOSX_keyEvent, "v@:@" )
+
+ wxOSX_CLASS_ADD_METHOD(c, @selector(insertText:), (IMP) wxOSX_insertText, "v@:@" )
+
+ wxOSX_CLASS_ADD_METHOD(c, @selector(performKeyEquivalent:), (IMP) wxOSX_performKeyEquivalent, "v@:@" )
+
+ wxOSX_CLASS_ADD_METHOD(c, @selector(acceptsFirstResponder), (IMP) wxOSX_acceptsFirstResponder, "c@:" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(becomeFirstResponder), (IMP) wxOSX_becomeFirstResponder, "c@:" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(resignFirstResponder), (IMP) wxOSX_resignFirstResponder, "c@:" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(resetCursorRects), (IMP) wxOSX_resetCursorRects, "v@:" )
+
+ wxOSX_CLASS_ADD_METHOD(c, @selector(isFlipped), (IMP) wxOSX_isFlipped, "c@:" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(drawRect:), (IMP) wxOSX_drawRect, "v@:{_NSRect={_NSPoint=ff}{_NSSize=ff}}" )
+
+ wxOSX_CLASS_ADD_METHOD(c, @selector(controlAction:), (IMP) wxOSX_controlAction, "v@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(controlDoubleAction:), (IMP) wxOSX_controlDoubleAction, "v@:@" )
+
+#if wxUSE_DRAG_AND_DROP
+ wxOSX_CLASS_ADD_METHOD(c, @selector(draggingEntered:), (IMP) wxOSX_draggingEntered, "I@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(draggingUpdated:), (IMP) wxOSX_draggingUpdated, "I@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(draggingExited:), (IMP) wxOSX_draggingExited, "v@:@" )
+ wxOSX_CLASS_ADD_METHOD(c, @selector(performDragOperation:), (IMP) wxOSX_performDragOperation, "c@:@" )
+#endif
+
+#if OBJC_API_VERSION < 2
+ } ;
+ static int method_count = WXSIZEOF( wxmethods );
+ static objc_method_list *wxmethodlist = NULL;
+ if ( wxmethodlist == NULL )
+ {
+ wxmethodlist = (objc_method_list*) malloc(sizeof(objc_method_list) + sizeof(wxmethods) );
+ memcpy( &wxmethodlist->method_list[0], &wxmethods[0], sizeof(wxmethods) );
+ wxmethodlist->method_count = method_count;
+ wxmethodlist->obsolete = 0;
+ }
+ class_addMethods( c, wxmethodlist );
+#endif
+}
+
+//
+// C++ implementation class
+//