Commits

Ronald Oussoren committed 4d43208

2 major changes:
- Support for GNUstep
- Support for PEP311

Also:
- Add wrappers for SecurityInterface framework
- Add simple unittests for all frameworks, to be sure that the wrappers
can be used.
- Add wrappers for newly introduced difficult methods (and some old)
- Add annotation to method signatures (in, out, inout) where applicable.
- Add partial support for PEP311: it is now always save to call from Objective-C
into Python using easy methods (e.g. those not handled by code in the
*Mapping modules)
- NSKeyValueCoding now uses 'setValue:forKey:' instead of 'takeValue:forKey:'
(and simular changes for 'setValue:forKeyPath:' and
'setValuesForKeysWithDictionary:'). Added support in OC_PythonObject.m,
class-builder.m and the unittests in objc/test/test_keyvalue.py
[Still no notifications on changes...]
- Fix objc_support.m w.r.t. runtime rules for structured types, and add
testcases for them in test_methods2.
- Disable some NSInvocation based tests when one of the argument is one of the
'difficult' structs, NSInvocation garbles these values which would lead to
spurious unittest errors. The tests are only disabled when NSInvocation
has the bug, some C code is used to check if NSInvocation has this problem.
The corresponding C test is disabled on GNUstep, due to GNUstep crashing on
this code...
- Add some C-level unittests, this makes debugging lowlevel conversion
routines easier.
- Modernized ObjCPointer.m, it still used tp_getattr (!)
- Add __attribute__((__unused__)) in autoGil.c, to avoid compiler warnings.
- Accept arbitrary sequences instead of only tuples when converting to
Objective-C structs and arrays, both using PySequence_Fast.
- Restructure runtime support, the core bridge now compiles on GNUstep, and
mostly works.
- Fix type in objc module: recyleAutoreleasePool -> recycleAutoreleasePool
- Don't let -respondsToSelector: answer YES if the python implementation is
for a class method.
- Fix bugs in error-path in pointer-support.m
- Fix some faulty error-returns throughout the bridge (found because NULL
is a pointer "literal" on GNUstep and an int literal on MacOS X)
- Reduce usage of NSMethodSignature class, the new code should be slightly
faster and more importantly has exactly the same interface on GNUstep and
MacOS X.
- Move (Obj)C code closer to our coding-style.

Comments (0)

Files changed (146)

   int PyObjC_PythonToObjC(const char* typespec, PyObject* value, void* buffer);
 
 Convert the value to an Objective-C value of type ``typespec``. The buffer must
-be at least ``PyObjC_SizeOfType(typespec)`` bytes long.
+be at least ``PyObjCRT_SizeOfType(typespec)`` bytes long.
 
 NOTE: The ``typespec`` is a type specifier as described in the runtime 
 reference of the Objective-C manual from Apple. Use ``@encode(mytype)`` if to
 
 ::
 
-  int PyObjC_SizeOfType(const char* typespec);
+  int PyObjCRT_SizeOfType(const char* typespec);
 
 Return the size of variables of the specified type.
 
 ::
 
+  int PyObjCRT_AlignOfType(const char* typespec);
+
+Return the alignment of variables of the specified type.
+
+::
+
   Class PyObjCSelector_GetClass(PyObject* sel);
 
 Return the class containing the definition of ``sel``.
   raise a python exception if the conversion fails, instead of returning an
   error-string.
 
-NOTE: If we don't mind doing this only for Python 2.3 we can use the interface
-defined by PEP 311
-
-NOTE2: The autoGIL is quite usefull, but unless our code gets called from a
-different thread, that does not yet have a Python thread context. This may 
-happen when embedding a PyObjC solution in an existing Cocoa application.
-
-NOTE3: This is not really an important item.
-
-XXX (Ronald): I'll probably add PEP311 support after we do a release  with
-Panther support. This would make it safer to use PyObjC embedded in an 
-multithreaded application. Specifically: grab the GIL when going from ObjC
-to python, and release it when going back again. This is a half-way solution.
+This version has limited multithreading safety: it is possible to call from
+Objective-C to python from arbitrary threads. This only works when using 
+Python 2.3, because this uses the interfaces defined in PEP 311. This is only
+meant to make it safer to embed a PyObjC in existing applications, and not
+a solution for finegrained threading.
 
 Test suite
 ..........
 
 * tests for all functions in ``Modules/*/*Mapping*.m``
 
-* tests for all non-generated function wrappers
+* tests for all non-generated function wrappers (and some for the generated
+  functions as well, just in case the generator script is buggy)
 
 * tests where Python implementation of method with output arguments returns
   the wrong value (type, number of values)
 
+* Add tests for accepting any sequence when depythonifying structs and arrays.
+
+* Add more tests for objc_support.m to unittest.c
+
+* Add tests for OC_PythonArray, OC_PythonDict to unittest.c
+
+
 The first two bullets require at least some GUI tests.
 
 
 Support for GNUstep
 ...................
 
-We currently don't support GNUstep. Modules/objc/objc_support.h contains 
-some definitions that help in supporting GNUstep, we should use those where
-applicable. 
-
-Support beyond that requires someone that actually tries to perform the 
-port to GNUstep (and after that maintains it). 
+The current CVS version contains some support for GNUstep, this needs to
+be enhanced.
 
 Naming convention / coding style
 ................................
 Key-Value Encoding
 ..................
 
-Implement the Key-Value encoding protocol for Py-ObjC hybrids, in a Pythonic
-way. Do the same in OC_PythonObject (e.g. for pure-python objects used from
-Objective-C)
+Implement the 10.3 changes for Key-Value coding (observation).
 
 Formal Protocols, Distributed Objects
 .....................................
 
 But: we should also provide links to locally installed documetation, especially
 in the documentation that will be installed on the users machine.
+
+Efficient conversion of arrays of C-types
+.........................................
+
+Make it possible to represent arrays for NSPoints/NSRects/... as (numeric) 
+arrays. This should be implemented as a genericly as possible, a possible
+interface in pyobjc-api.h::
+
+	void*	PyObjC_PythonArrayToObjC(
+			char* typestr, PyObject* array, PyObject* count);
+
+	PyObject* PyObjC_ObjCArrayToPython(
+		char* typestr, void* array, int count);
+
+If the ``count`` argument for PythonArrayToObjC is NULL or Py_None, all objects
+in the array are converted. This should accept:
+
+1) a python sequence (list, array, iterator, ...) containing Python objects
+   representing the elements of the array (e.g. [ (1,2), (3,4), (4,5) ] as a 
+   list of 3 points).
+2) an array.array of suitable dimensions/types
+3) a numeric array of suitable dimensions/types
+
+Items 2 and 3 must be checked for correctness (e.g. don't blindly convert a
+array.array containing bytes to an array of NSPoints).
+
+Installer support for OSX 10.3
+..............................
+
+There should be at least two installers: one for Jaguar and one for Panther,
+they should share as much source-code as possible.
+
+Related to this: it would probably be usefull to rewrite buildpkg.py, this
+module has been hacked up to support new-style packages. It should be rewritten
+based on the Apple documentation on the layout of packages, there is no need
+to support 10.1-style packages. This new module should be donated to
+MacPython).

Doc/api-notes-macosx.txt

 
 TODO: Add documentation about weak linking (see intro.txt).
 
-
 Introduction
 ------------
 
 ..............
 
 * ``descriptionForClassMethod:``, ``descriptionForInstanceMethod``
+
   These methods are not supported, protocols are hardly ever used explicitly
   in Cocoa therefore this should not be a problem.
 
 ..................
 
 * ``getLineDash:count:phase:``
-  This method is not supported, I (Ronald) could not find a way to detect the
-  required size for the pattern buffer. 
+
+  Use ``getLineDash_count_phase_(0)`` to get the length of the pattern, and
+  then use ``getLineDash_count_phase_(actualCount)`` to fetch all information.
+  Both return ``(pattern, actualCount, phase)``. The ``pattern`` is ``None``
+  when the input argument is ``0``.
 
 * ``appendBezierPathWithGlyphs:count:inFont:``
+
   The first argument is a list of integers, count should be at most the lenght
   of the first argument.
 
 * ``appendBezierPathWithPoints:count:``
+
   The first argument is a list of points, count should be at most the lenght
   of the first argument. 
 
 * ``setAssociatedPoints:atIndex:``
+
   Implementing this method in Python is not yet supported.
 
 Class ``NSBitmapImageRep``
 ..........................
 
 * ``getBitMapDataPlanes``
+
   This method is not supported (yet)
 
 * ``getTIFFCompressionTypes:count:``
+
   This method is not supported (yet)
 
 * ``initWithBitmapDataPlanes:pixesWide:pixelsHigh:bitPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bytesPerRow:bitsPerPixel:``
+
   This method is not supported (yet)
 
 Class ``NSFont``
 ................
 
 * ``positionsForCompositeSequence:numberOfGlyphs:pointArray:``
+
   This method is not supported (yet)
 
 
 ...........................
 
 * ``focusStack``
+
   This method is not supported.
 
 * ``setFocusStack``
+
   This method is not supported.
 
 * ``graphicsPort``
+
   This method is not yet supported, MacPython doesn't wrap ``CGContextRef``
   at the moment.
 
 .........................
 
 * ``getGlyphs:range:``
+
   This method is not yet supported
 
 * ``getGlyphsInRange:glyphs:characterIndexes:glyphInscriptions:elasticBits:``
+
   This method is not yet supported
 
 * ``getGlyphsInRange:glyphs:characterIndexes:glyphInscriptions:elasticBits:bidiLevels:``
+
   This method is not yet supported
 
 * ``rectArrayForCharacterRange:withinSelectedCharacterRange:inTextContainer:rectCount:``
+
   This method is not yet supported
 
 * ``rectArrayForGlyphRange:withinSelectedGlyphRange:inTextContainer:rectCount:``
+
   This method is not yet supported
 
 Class ``NSMatrix``
 ..................
 
 * ``sortUsingFunction:context``
+
   Calling this method from Python is supported, overriding it in Python
   is not. The ``context`` can be an arbitrary python object.
 
 .........................
 
 * ``getValues:forParameter:``
+
   This method is not yet supported.
 
 * ``setValues:forParameter:``
+
   This method is not yet supported.
 
 * ``setOffScreen:width:height:rowbytes:``
+
   This method is not yet supported.
 
 Class ``NSOpenGLPixelFormat``
 ......................................
 
 * ``baseOfTypesetterGlyphInfo``
+
   This method is not yet supported
 
 * ``layoutGlyphsInHorizontalLineFragment:baseline:``
+
   This method is not yet supported
 
 
 ................
 
 * ``sortSubviewsUsingFunction:context:``
+
   Calling this method from Python is supported, overriding it in Python
   is not. The ``context`` can be an arbitrary python object.
 
 ..................
 
 * ``graphicsPort``
+
   This method is not yet supported
 
 * ``initWithWindowRef:``
+
   This method is not yet supported
 
 * ``windowRef``
+
   This method is not yet supported
 
 Foundation framework
 .................
 
 * ``initWithObjects:``, ``arrayWithObjects:``
+
   These methods are not supported, use ``initWithArray:`` instead.
 
 * ``getObjects:``
+
   This method is not supported, accessing the objects using the usual
   accessor methods is just as efficient as using this method.
 
 * ``getObjects:inRange:``
+
   This method is not supported, accessing the objects using the usual
   accessor methods is just as efficient as using this method.
 
 * ``sortedArrayUsingFunction:context:`` and ``sortedArrayUsingFunction:context:hint``
+
   These methods can be called from Python, but you cannot override them
   from Python. This limitation will be lifted in a future version of PyObjC.
 
   The ``context`` can be an arbitrary python object.
 
+* ``addObserver:toObjectsAtIndexes:forKeyPath:options:context:``
+
+  The context is an integer, not a ``void*``.
+
 Class ``NSBundle``
 ..................
 
 * ``bundleForClass:``
+
   This method does not work correctly for classes defined in Python, these
   all seem be defined in the ``mainBundle()``. As a workaround you can use
   the function ``objc.pluginBundle(name)`` to find the NSBundle for your
 ................
 
 * ``initWithBytesNoCopy:length:``
+
   This method is not supported, use ``initWithBytes:length:`` instead.
 
 * ``initWithBytesNoCopy:length:freeWhenDone:``
+
   This method is not supported, use ``initWithBytes:length:`` instead.
 
 * ``dataWithBytesNoCopy:length:``
+
   This method is not supported, use ``dataWithBytes:length:`` instead.
 
 * ``dataWithBytesNoCopy:length:freeWhenDone:``
+
   This method is not supported, use ``dataWithBytes:length:`` instead.
 
 * ``deserializeAlignedBytesLengthAtCursor:``
+
   This is a depricated method, see Apple documentation.
 
 * ``deserializeBytes:length:atCursor:``
+
   This is a depricated method, see Apple documentation.
 
 * ``deserializeDataAt:ofObjCType:atCursor:context:``
+
   This is a depricated method, see Apple documentation.
 
 * ``deserializeIntAtCursor:``
+
   This is a depricated method, see Apple documentation.
 
 * ``deserializeInts:count:atCursor:``
+
   This is a depricated method, see Apple documentation.
 
 * ``deserializeInts:count:atIndex:``
+
   This is a depricated method, see Apple documentation.
 
 * ``getBytes:``, ``getBytes:length:``, ``getBytes:range:``
 The ``extraData`` argument/return value for ``-extraData`` and 
 ``setTargetClassextraData:`` is represented as an integer.
 
+Class ``NSIndexSet``
+....................
+
+* ``getIndexes:maxCount:inIndexRange:``
+  The usage is::
+
+  	(realCount, indices, newRange) = obj.getIndexes_maxCount_inIndexRange(
+		maxCount, inRange)		
+
+Class ``NSInvocation``
+......................
+
+In some versions of MacOS X, NSInvocation doesn't work properly with structs
+that contain padding. Such structs are not used in the MacOS X API, but may
+be present in 3th party code. This leads to problems when ``forwardInvocation:``
+is used to call a method that has such a struct as one of its arguments.
+
 Class ``NSMutableArray``
 ........................
 
 * ``sortUsingFunction:context:``, ``sortUsingFunction:context:range:``
+
   Calling this method from Python is supported, overriding it in a subclass
   is not. This limitation will be fixed in a later version of PyObjC.
 
 ......................
 
 * ``addresses``
+
   When calling this from Python this methods returns a tuple of adress-info
   tuples, like the values returned by ``socket.getpeeraddr()``. 
 
+Class ``NSObject``
+..................
+
+* ``observationInfo``, ``setObservationInfo:``
+
+  These methods can be used from Python, but the ``observationInfo`` is 
+  represented by an integer instead of ``void*``. This probably makes it
+  impossible to do anything usefull with these methods.
+
+* ``addObserver:forKeyPath:options:context:``
+
+  The context is an integer.
+
+* ``observeValueForKeyPath:ofObject:change:context:``
+
+  The context is an integer
+
+
 Class ``NSScriptObjectSpecifier``
 .................................
 
 * ``indicesOfObjectsByEvaluatingWithContainer:count:``
+
   Implementing this in Python is not supported yet. We're looking for a way
   to avoid leaking the returned buffer, as we cannot return a pointer to an
   internal datastructure.
 ...............
 
 * ``initWithObjects:``, ``setWithObjects:``
+
   This method is not supported, use ``initWithArray:`` instead.
 
 
 have a Python equivalent.
 
 * ``initWithCharactersNoCopy:length:freeWhenDone:`` 
+
   This method is unsupported because we cannot guarantee that the buffer wil
   be available as long as the string is. Use ``initWithCharacters:`` instead.
 
 * ``getCharacters:`` and ``getCharacters:range:``
+
   These methods are not supported at the moment. This limitation will be liften
   in a future version of the bridge.
 
 * ``getCString:maxLength:range:remainingRange:`` and ``getCString:maxLength:``
+
   Calling these methods from Python is supported, overriding them from 
   Python is not. This limitation will be liften in a future version of the
   bridge.
 
 * ``getCString:``
+
   This method is not supported. Use ``getCString:maxLength:`` instead (using
   the length of the string as the maximum length). This limitation will be
   liften in a future version of the bridge.
+ 
+
+class ``NSThread``
+..................
+
+When you're using Python 2.3 or later it is save to call from Objective-C to
+Python on any thread. Otherwise you must be sure that the current thread has
+acquired the GIL. This means you shouldn't use API's that will call back on
+an arbitrary thread unless you're using Python 2.3 or later. It is safe to 
+start new threads using the Python threading API and run non-Cocoa code on 
+those threads, PyObjC contains code that acquires the GIL whenever the runloop
+in the main thread runs.
+
+* ``detachNewThreadSelector:toTarget:withObject:``
+
+  This method can safely be used when using Python 2.3 or later, on earlier
+  releases this will crash the interpreter.
+
+  Make sure that you've either created a thread from Python using the 
+  ``thread`` or ``threading`` module, or called ``objc.enableThreading`` before
+  using this API. This is necessary to enable threading in the Python 
+  interpreter. We don't do this by default because this has a negative 
+  performance impact.
 
 InterfaceBuilder framework
 --------------------------
 ................
 
 * ``objectAtPoint:rect:``
+
   Defined in a catagory on ``NSView``.
 
 Class ``NSIBObjectData``
+=========================
+GNUstep support in PyObjC
+=========================
+
+PyObjC has limited support for GNUstep, the 'objc' and 'Foundation' packages
+build and pass some, but by far not all, unittests. More work is needed to
+make the GNUstep port as stable as the MacOS X "port".
+
+The GNUstep port was primarily developed on Linux i86 (specifically 
+the Debian testing distribution), using python 2.2.3, gcc 3.3.2 and 
+gnustep-base 1.7.3-1. The code in setup.py works for this configuration,
+but probably not for other configurations.
+
+TODO
+----
+
+* Fix bugs found using the unittests
+
+* Port the AppKit wrappers
+
+* Extract more CFLAGS and LDFLAGS information from the GNUstep build system,
+  instead of hard-coding the information

Examples/00ReadMe.txt

 * `Todo`_
 
   A more complex NIB based applications. This is a document-based application.
-  The code is a translation into pyton of an example project in 
+  The code is a translation into Python of an example project in 
   'Learning Cocoa' from O'Reilly
 
 * `WebServicesTool`_
 
-  Another Project Builder Cocoa project.  Quiries an XML-RPC enabled web
+  Another Project Builder Cocoa project.  Queries an XML-RPC enabled web
   server for the methods that it implements.  Demonstrates a more advanced
   use of an NSTableView, how to make a toolbar as well as how to use
   multi-threading.

Examples/subclassing-objective-c.py

 obj = None
 print "Done"
 
-objc.recyleAutoreleasePool()
+objc.recycleAutoreleasePool()

Lib/AddressBook/__init__.py

 objc.loadBundle("AddressBook", globals(), bundle_path="/System/Library/Frameworks/AddressBook.framework")
 
 from _AddressBook import *
-del _AddressBook, objc
+del _AddressBook
 
 import protocols  # no need to export these, just register with PyObjC
 
 # Define useful utility methods here
+
+objc.setSignatureForSelector('NSImagePickerController', 'setTarget:selector:userInfo:', 'v@:@:i')
+
+# Not entirely correct...
+objc.setSignatureForSelector('ABAuthenticationInfo', 'appliesToRequest:', 'c@:@')
+objc.setSignatureForSelector('ABAuthenticationInfo', 'applyToRequest:', 'c@:@')
+objc.setSignatureForSelector('ABDAVQuery', 'buildRequest', '@@:')
+
+del objc

Lib/AddressBook/protocols.py

 import objc as _objc
 
 
+ABActionDelegate = _objc.informal_protocol(
+    "ABActionDelegate",
+    [
+# (NSString *)actionProperty
+        _objc.selector(
+            None,
+            selector='actionProperty',
+            signature='@@:',
+            isRequired=0,
+        ),
+# (void)performActionForPerson:(ABPerson *)person identifier:(NSString *)identifier
+        _objc.selector(
+            None,
+            selector='performActionForPerson:identifier:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
+# (BOOL)shouldEnableActionForPerson:(ABPerson *)person identifier:(NSString *)identifier
+        _objc.selector(
+            None,
+            selector='shouldEnableActionForPerson:identifier:',
+            signature='c@:@@',
+            isRequired=0,
+        ),
+# (NSString *)titleForPerson:(ABPerson *)person identifier:(NSString *)identifier
+        _objc.selector(
+            None,
+            selector='titleForPerson:identifier:',
+            signature='@@:@@',
+            isRequired=0,
+        ),
+    ]
+)
+
 ABImageClient = _objc.informal_protocol(
     "ABImageClient",
     [
-# (void)consumeImageData:(NSData*)data forTag:(int)tag
+# (void)consumeImageData:(NSData *)data forTag:(int)tag
         _objc.selector(
             None,
             selector='consumeImageData:forTag:',

Lib/AppKit/_AppKitSignatures.py

 setSignatureForSelector("NSSurface", "surfaceID", "i@:")
 setSignatureForSelector("NSInputManager", "getMarkedText:selectedRange:", "v@:o^@o^{_NSRange=II}")
 setSignatureForSelector("NSToolbar", "_configSheetDidEnd:returnCode:contextInfo:", "v16@4:8@12i16i20")
+setSignatureForSelector("NSAlert", "didEndAlert:returnCode:contextInfo:", "v16@4:8@12i16i20")
 setSignatureForSelector("NSEvent", "enterExitEventWithType:location:modifierFlags:timestamp:windowNumber:context:eventNumber:trackingNumber:userData:", "@52@4:8i12{_NSPoint=ff}16I24d36i40@44i48i52i56")
 setSignatureForSelector("NSEvent", "userData", "i@:")
 setSignatureForSelector("NSPSMatrix", "invTransformRect:", "@@:N^{_NSRect={_NSPoint=ff}{_NSSize=ff}}")
 setSignatureForSelector("NSTextContainer", "lineFragmentRectForProposedRect:sweepDirection:movementDirection:remainingRect:", "{_NSRect={_NSPoint=ff}{_NSSize=ff}}@:{_NSRect={_NSPoint=ff}{_NSSize=ff}}iio^{_NSRect={_NSPoint=ff}{_NSSize=ff}}")
 setSignatureForSelector("NSApplication", "_commonBeginModalSessionForWindow:relativeToWindow:modalDelegate:didEndSelector:contextInfo:", "^{_NSModalSession=@@^{_NSModalSession}iciI^vi@@:^vi}24@4:8@12@16@20:24i28")
 setSignatureForSelector("NSApplication", "beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo:", "v@:@@@:i")
+setSignatureForSelector("NSAlert", "beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo:", "v@:@@@:i")
 setSignatureForSelector("NSApplication", "contextID", "i4@4:8")
 setSignatureForSelector("NSApplication", "openFile:ok:", "i12@4:8@12o^i16")
 setSignatureForSelector("NSApplication", "openTempFile:ok:", "i12@4:8@12o^i16")
 setSignatureForSelector("NSView", "adjustPageHeightNew:top:bottom:limit:", "v@:o^ffff")
 setSignatureForSelector("NSView", "adjustPageWidthNew:left:right:limit:", "v@:o^ffff")
 setSignatureForSelector("NSView", "knowsPageRange:", "v@:N^{_NSRange=II}")
+setSignatureForSelector("NSNib", "instantiateNibWithOwner:topLevelObjects:", "c@:@o^@")
+setSignatureForSelector("NSWorkspace", "launchAppWithBundleIdentifier:options:additionalEventParamDescriptor:launchIdentifier:", "c24@0:4@8I12@16o^@20")
+setSignatureForSelector("NSWorkspace", "openURLs:withAppBundleIdentifier:options:additionalEventParamDescriptor:launchIdentifiers:", "c28@0:4@8@12I16@20o^@24")
+setSignatureForSelector("NSTextRulerOptions", "sheetDidEnd:returnCode:contextInfo:", "v@:@ii")
+setSignatureForSelector("NSAlert", "beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:", "v28@4:8@12@16@20@24:28i32")
+setSignatureForSelector("NSATSTypesetter", "characterRangeForGlyphRange:actualGlyphRange:", "{_NSRange=II}@:{_NSRange=II}o^{_NSRange=II}")
+setSignatureForSelector("NSATSTypesetter", "glyphRangeForGlyphRange:actualGlyphRange:", "{_NSRange=II}@:{_NSRange=II}o^{_NSRange=II}")
+setSignatureForSelector("NSATSTypesetter", "layoutParagraphAtPoint:", "I@:{_NSPoint=ff}")
+setSignatureForSelector("NSATSTypesetter", "lineFragmentRectForProposedRect:remainingRect:", "{_NSRect={_NSPoint=ff}{_NSSize=ff}}@:{_NSRect={_NSPoint=ff}{_NSSize=ff}}o^{_NSRect={_NSPoint=ff}{_NSSize=ff}}")
+setSignatureForSelector("NSATSTypesetter", "getLineFragmentRect:usedRect:forParagraphSeparatorGlyphRange:atProposedOrigin:", "v@:o^{_NSRect={_NSPoint=ff}{_NSSize=ff}}o^{_NSRect={_NSPoint=ff}{_NSSize=ff}}{_NSRange=II}{_NSPoint=ff}")
+setSignatureForSelector("NSATSTypesetter", "glyphRangeForCharacterRange:actualCharacterRange:", "{_NSRange=II}@:{_NSRange=II}o^{_NSRange=II}")
+setSignatureForSelector("NSSavePanel", "beginForDirectory:file:types:modelessDelegate:didEndSelector:contextInfo:", 'v@:@@@@:i')
+

Lib/AppKit/__init__.py

 import _AppKitSignatures 
 import objc as _objc
 
-# We first register special methods signatures with the runtime. The module
-# is not used for anything else.
-
+# Import contansts and global functions.
 from _AppKit import *
 
-
-# We try to import a module containing support code, the code
-# is only ever used from the C side.
-import _AppKitMapping 
-
 # Load the Cocoa bundle, and gather all classes defined there
 _objc.loadBundle("AppKit", globals(), bundle_path="/System/Library/Frameworks/AppKit.framework")
-_objc.recyleAutoreleasePool()
+_objc.recycleAutoreleasePool()
 
 
 # Define usefull utility methods here

Lib/AppKit/protocols.py

             signature='@@:@',
             isRequired=0,
         ),
+# (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter
+        _objc.selector(
+            None,
+            selector='accessibilityAttributeValue:forParameter:',
+            signature='@@:@@',
+            isRequired=0,
+        ),
 # (id)accessibilityFocusedUIElement
         _objc.selector(
             None,
             signature='c@:',
             isRequired=0,
         ),
+# (NSArray *)accessibilityParameterizedAttributeNames
+        _objc.selector(
+            None,
+            selector='accessibilityParameterizedAttributeNames',
+            signature='@@:',
+            isRequired=0,
+        ),
 # (void)accessibilityPerformAction:(NSString *)action
         _objc.selector(
             None,
     ]
 )
 
+NSAlertDelegate = _objc.informal_protocol(
+    "NSAlertDelegate",
+    [
+# (BOOL)alertShowHelp:(NSAlert *)alert
+        _objc.selector(
+            None,
+            selector='alertShowHelp:',
+            signature='c@:@',
+            isRequired=0,
+        ),
+    ]
+)
+
 NSApplicationDelegate = _objc.informal_protocol(
     "NSApplicationDelegate",
     [
             signature='c@:@@',
             isRequired=0,
         ),
+# (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
+        _objc.selector(
+            None,
+            selector='application:openFiles:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
 # (BOOL)application:(NSApplication *)sender openTempFile:(NSString *)filename
         _objc.selector(
             None,
             signature='c@:@@',
             isRequired=0,
         ),
+# (void)application:(NSApplication *)sender printFiles:(NSArray *)filenames
+        _objc.selector(
+            None,
+            selector='application:printFiles:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
 # (NSMenu *)applicationDockMenu:(NSApplication *)sender
         _objc.selector(
             None,
             signature='c@:@ii',
             isRequired=0,
         ),
+# (float)browser:(NSBrowser *)browser shouldSizeColumn:(int)columnIndex forUserResize:(BOOL)forUserResize toWidth:(float)suggestedWidth
+        _objc.selector(
+            None,
+            selector='browser:shouldSizeColumn:forUserResize:toWidth:',
+            signature='f@:@icf',
+            isRequired=0,
+        ),
+# (float)browser:(NSBrowser *)browser sizeToFitWidthOfColumn:(int)columnIndex
+        _objc.selector(
+            None,
+            selector='browser:sizeToFitWidthOfColumn:',
+            signature='f@:@i',
+            isRequired=0,
+        ),
 # (NSString *)browser:(NSBrowser *)sender titleOfColumn:(int)column
         _objc.selector(
             None,
             signature='v@:@@ii',
             isRequired=0,
         ),
+# (void)browserColumnConfigurationDidChange:(NSNotification *)notification
+        _objc.selector(
+            None,
+            selector='browserColumnConfigurationDidChange:',
+            signature='v@:@',
+            isRequired=0,
+        ),
 # (void)browserDidScroll:(NSBrowser *)sender
         _objc.selector(
             None,
             signature='c@:@@',
             isRequired=0,
         ),
+# (NSArray *)control:(NSControl *)control textView:(NSTextView *)textView completions:(NSArray *)words forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(int *)index
+        _objc.selector(
+            None,
+            selector='control:textView:completions:forPartialWordRange:indexOfSelectedItem:',
+            signature='@@:@@@{_NSRange=II}^i',
+            isRequired=0,
+        ),
 # (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector
         _objc.selector(
             None,
     ]
 )
 
+NSEditor = _objc.informal_protocol(
+    "NSEditor",
+    [
+# (BOOL)commitEditing
+        _objc.selector(
+            None,
+            selector='commitEditing',
+            signature='c@:',
+            isRequired=0,
+        ),
+# (void)discardEditing
+        _objc.selector(
+            None,
+            selector='discardEditing',
+            signature='v@:',
+            isRequired=0,
+        ),
+    ]
+)
+
+NSEditorRegistration = _objc.informal_protocol(
+    "NSEditorRegistration",
+    [
+# (void)objectDidBeginEditing:(id)editor
+        _objc.selector(
+            None,
+            selector='objectDidBeginEditing:',
+            signature='v@:@',
+            isRequired=0,
+        ),
+# (void)objectDidEndEditing:(id)editor
+        _objc.selector(
+            None,
+            selector='objectDidEndEditing:',
+            signature='v@:@',
+            isRequired=0,
+        ),
+    ]
+)
+
 NSFontManagerDelegate = _objc.informal_protocol(
     "NSFontManagerDelegate",
     [
     ]
 )
 
+NSFontPanelValidationAdditions = _objc.informal_protocol(
+    "NSFontPanelValidationAdditions",
+    [
+# (unsigned int) validModesForFontPanel: (NSFontPanel *) fontPanel
+        _objc.selector(
+            None,
+            selector='validModesForFontPanel:',
+            signature='I@:@',
+            isRequired=0,
+        ),
+    ]
+)
+
+NSGlyphStorage = _objc.informal_protocol(
+    "NSGlyphStorage",
+    [
+# (NSAttributedString *)attributedString
+        _objc.selector(
+            None,
+            selector='attributedString',
+            signature='@@:',
+            isRequired=0,
+        ),
+# (void)insertGlyphs:(const NSGlyph *)glyphs length:(unsigned int)length forStartingGlyphAtIndex:(unsigned int)glyphIndex characterIndex:(unsigned int)charIndex
+        _objc.selector(
+            None,
+            selector='insertGlyphs:length:forStartingGlyphAtIndex:characterIndex:',
+            signature='v@:^IIII',
+            isRequired=0,
+        ),
+# (unsigned int)layoutOptions
+        _objc.selector(
+            None,
+            selector='layoutOptions',
+            signature='I@:',
+            isRequired=0,
+        ),
+# (void)setIntAttribute:(int)attributeTag value:(int)val forGlyphAtIndex:(unsigned)glyphIndex
+        _objc.selector(
+            None,
+            selector='setIntAttribute:value:forGlyphAtIndex:',
+            signature='v@:iiI',
+            isRequired=0,
+        ),
+    ]
+)
+
 NSIgnoreMisspelledWords = _objc.informal_protocol(
     "NSIgnoreMisspelledWords",
     [
     ]
 )
 
+NSKeyValueBindingCreation = _objc.informal_protocol(
+    "NSKeyValueBindingCreation",
+    [
+# (void)bind:(NSString *)binding toObject:(id)observable withKeyPath:(NSString *)keyPath options:(NSDictionary *)options
+        _objc.selector(
+            None,
+            selector='bind:toObject:withKeyPath:options:',
+            signature='v@:@@@@',
+            isRequired=0,
+        ),
+# (NSArray *)exposedBindings
+        _objc.selector(
+            None,
+            selector='exposedBindings',
+            signature='@@:',
+            isRequired=0,
+        ),
+# (void)unbind:(NSString *)binding
+        _objc.selector(
+            None,
+            selector='unbind:',
+            signature='v@:@',
+            isRequired=0,
+        ),
+# (Class)valueClassForBinding:(NSString *)binding
+        _objc.selector(
+            None,
+            selector='valueClassForBinding:',
+            signature='#@:@',
+            isRequired=0,
+        ),
+    ]
+)
+
 NSLayoutManagerDelegate = _objc.informal_protocol(
     "NSLayoutManagerDelegate",
     [
     ]
 )
 
+NSMenuDelegate = _objc.informal_protocol(
+    "NSMenuDelegate",
+    [
+# (BOOL)menu:(NSMenu*)menu updateItem:(NSMenuItem*)item atIndex:(int)index shouldCancel:(BOOL)shouldCancel
+        _objc.selector(
+            None,
+            selector='menu:updateItem:atIndex:shouldCancel:',
+            signature='c@:@@ic',
+            isRequired=0,
+        ),
+# (BOOL)menuHasKeyEquivalent:(NSMenu*)menu forEvent:(NSEvent*)event target:(id*)target action:(SEL*)action
+        _objc.selector(
+            None,
+            selector='menuHasKeyEquivalent:forEvent:target:action:',
+            signature='c@:@@^@^:',
+            isRequired=0,
+        ),
+# (void)menuNeedsUpdate:(NSMenu*)menu
+        _objc.selector(
+            None,
+            selector='menuNeedsUpdate:',
+            signature='v@:@',
+            isRequired=0,
+        ),
+# (int)numberOfItemsInMenu:(NSMenu*)menu
+        _objc.selector(
+            None,
+            selector='numberOfItemsInMenu:',
+            signature='i@:@',
+            isRequired=0,
+        ),
+    ]
+)
+
 NSMenuItem = _objc.informal_protocol(
     "NSMenuItem",
     [
-# (SEL)action
+# (void)add:(id)sender
         _objc.selector(
             None,
-            selector='action',
-            signature=':@:',
+            selector='add:',
+            signature='v@:@',
             isRequired=0,
         ),
-# (BOOL)hasSubmenu
+# (void)addObject:(id)object
         _objc.selector(
             None,
-            selector='hasSubmenu',
+            selector='addObject:',
+            signature='v@:@',
+            isRequired=0,
+        ),
+# (BOOL)automaticallyPreparesContent
+        _objc.selector(
+            None,
+            selector='automaticallyPreparesContent',
             signature='c@:',
             isRequired=0,
         ),
-# (NSImage *)image
+# (BOOL)canAdd
         _objc.selector(
             None,
-            selector='image',
+            selector='canAdd',
+            signature='c@:',
+            isRequired=0,
+        ),
+# (BOOL)canRemove
+        _objc.selector(
+            None,
+            selector='canRemove',
+            signature='c@:',
+            isRequired=0,
+        ),
+# (id)content
+        _objc.selector(
+            None,
+            selector='content',
             signature='@@:',
             isRequired=0,
         ),
-# (id)initWithTitle:(NSString *)aString action:(SEL)aSelector keyEquivalent:(NSString *)charCode
+# (id)initWithContent:(id)content
         _objc.selector(
             None,
-            selector='initWithTitle:action:keyEquivalent:',
-            signature='@@:@:@',
+            selector='initWithContent:',
+            signature='@@:@',
             isRequired=0,
         ),
-# (BOOL)isEnabled
+# (BOOL)isEditable
         _objc.selector(
             None,
-            selector='isEnabled',
+            selector='isEditable',
             signature='c@:',
             isRequired=0,
         ),
-# (BOOL)isSeparatorItem
+# (id)newObject
         _objc.selector(
             None,
-            selector='isSeparatorItem',
-            signature='c@:',
-            isRequired=0,
-        ),
-# (NSString *)keyEquivalent
-        _objc.selector(
-            None,
-            selector='keyEquivalent',
+            selector='newObject',
             signature='@@:',
             isRequired=0,
         ),
-# (unsigned int)keyEquivalentModifierMask
+# (Class)objectClass
         _objc.selector(
             None,
-            selector='keyEquivalentModifierMask',
-            signature='I@:',
+            selector='objectClass',
+            signature='#@:',
             isRequired=0,
         ),
-# (NSMenu *)menu
+# (void)prepareContent
         _objc.selector(
             None,
-            selector='menu',
+            selector='prepareContent',
+            signature='v@:',
+            isRequired=0,
+        ),
+# (void)remove:(id)sender
+        _objc.selector(
+            None,
+            selector='remove:',
+            signature='v@:@',
+            isRequired=0,
+        ),
+# (void)removeObject:(id)object
+        _objc.selector(
+            None,
+            selector='removeObject:',
+            signature='v@:@',
+            isRequired=0,
+        ),
+# (NSArray *)selectedObjects
+        _objc.selector(
+            None,
+            selector='selectedObjects',
             signature='@@:',
             isRequired=0,
         ),
-# (NSImage *)mixedStateImage
+# (id)selection
         _objc.selector(
             None,
-            selector='mixedStateImage',
+            selector='selection',
             signature='@@:',
             isRequired=0,
         ),
-# (NSString *)mnemonic
+# (void)setAutomaticallyPreparesContent:(BOOL)flag
         _objc.selector(
             None,
-            selector='mnemonic',
-            signature='@@:',
-            isRequired=0,
-        ),
-# (unsigned)mnemonicLocation
-        _objc.selector(
-            None,
-            selector='mnemonicLocation',
-            signature='I@:',
-            isRequired=0,
-        ),
-# (NSImage *)offStateImage
-        _objc.selector(
-            None,
-            selector='offStateImage',
-            signature='@@:',
-            isRequired=0,
-        ),
-# (NSImage *)onStateImage
-        _objc.selector(
-            None,
-            selector='onStateImage',
-            signature='@@:',
-            isRequired=0,
-        ),
-# (id)representedObject
-        _objc.selector(
-            None,
-            selector='representedObject',
-            signature='@@:',
-            isRequired=0,
-        ),
-# (void)setAction:(SEL)aSelector
-        _objc.selector(
-            None,
-            selector='setAction:',
-            signature='v@::',
-            isRequired=0,
-        ),
-# (void)setEnabled:(BOOL)flag
-        _objc.selector(
-            None,
-            selector='setEnabled:',
+            selector='setAutomaticallyPreparesContent:',
             signature='v@:c',
             isRequired=0,
         ),
-# (void)setImage:(NSImage *)menuImage
+# (void)setContent:(id)content
         _objc.selector(
             None,
-            selector='setImage:',
+            selector='setContent:',
             signature='v@:@',
             isRequired=0,
         ),
-# (void)setKeyEquivalent:(NSString *)aKeyEquivalent
+# (void)setEditable:(BOOL)flag
         _objc.selector(
             None,
-            selector='setKeyEquivalent:',
-            signature='v@:@',
+            selector='setEditable:',
+            signature='v@:c',
             isRequired=0,
         ),
-# (void)setKeyEquivalentModifierMask:(unsigned int)mask
+# (void)setObjectClass:(Class)objectClass
         _objc.selector(
             None,
-            selector='setKeyEquivalentModifierMask:',
-            signature='v@:I',
+            selector='setObjectClass:',
+            signature='v@:#',
             isRequired=0,
         ),
-# (void)setMenu:(NSMenu *)menu
+# (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem
         _objc.selector(
             None,
-            selector='setMenu:',
-            signature='v@:@',
-            isRequired=0,
-        ),
-# (void)setMixedStateImage:(NSImage *)image
-        _objc.selector(
-            None,
-            selector='setMixedStateImage:',
-            signature='v@:@',
-            isRequired=0,
-        ),
-# (void)setMnemonicLocation:(unsigned)location
-        _objc.selector(
-            None,
-            selector='setMnemonicLocation:',
-            signature='v@:I',
-            isRequired=0,
-        ),
-# (void)setOffStateImage:(NSImage *)image
-        _objc.selector(
-            None,
-            selector='setOffStateImage:',
-            signature='v@:@',
-            isRequired=0,
-        ),
-# (void)setOnStateImage:(NSImage *)image
-        _objc.selector(
-            None,
-            selector='setOnStateImage:',
-            signature='v@:@',
-            isRequired=0,
-        ),
-# (void)setRepresentedObject:(id)anObject
-        _objc.selector(
-            None,
-            selector='setRepresentedObject:',
-            signature='v@:@',
-            isRequired=0,
-        ),
-# (void)setState:(int)state
-        _objc.selector(
-            None,
-            selector='setState:',
-            signature='v@:i',
-            isRequired=0,
-        ),
-# (void)setSubmenu:(NSMenu *)submenu
-        _objc.selector(
-            None,
-            selector='setSubmenu:',
-            signature='v@:@',
-            isRequired=0,
-        ),
-# (void)setTag:(int)anInt
-        _objc.selector(
-            None,
-            selector='setTag:',
-            signature='v@:i',
-            isRequired=0,
-        ),
-# (void)setTarget:(id)anObject
-        _objc.selector(
-            None,
-            selector='setTarget:',
-            signature='v@:@',
-            isRequired=0,
-        ),
-# (void)setTitle:(NSString *)aString
-        _objc.selector(
-            None,
-            selector='setTitle:',
-            signature='v@:@',
-            isRequired=0,
-        ),
-# (void)setTitleWithMnemonic:(NSString *)stringWithAmpersand
-        _objc.selector(
-            None,
-            selector='setTitleWithMnemonic:',
-            signature='v@:@',
-            isRequired=0,
-        ),
-# (int)state
-        _objc.selector(
-            None,
-            selector='state',
-            signature='i@:',
-            isRequired=0,
-        ),
-# (NSMenu *)submenu
-        _objc.selector(
-            None,
-            selector='submenu',
-            signature='@@:',
-            isRequired=0,
-        ),
-# (int)tag
-        _objc.selector(
-            None,
-            selector='tag',
-            signature='i@:',
-            isRequired=0,
-        ),
-# (id)target
-        _objc.selector(
-            None,
-            selector='target',
-            signature='@@:',
-            isRequired=0,
-        ),
-# (NSString *)title
-        _objc.selector(
-            None,
-            selector='title',
-            signature='@@:',
-            isRequired=0,
-        ),
-# (NSString *)userKeyEquivalent
-        _objc.selector(
-            None,
-            selector='userKeyEquivalent',
-            signature='@@:',
-            isRequired=0,
-        ),
-# (unsigned int)userKeyEquivalentModifierMask
-        _objc.selector(
-            None,
-            selector='userKeyEquivalentModifierMask',
-            signature='I@:',
+            selector='validateMenuItem:',
+            signature='c@:@',
             isRequired=0,
         ),
     ]
             signature='v@:@@@@',
             isRequired=0,
         ),
+# (void)outlineView:(NSOutlineView *)outlineView sortDescriptorsDidChange:(NSArray *)oldDescriptors
+        _objc.selector(
+            None,
+            selector='outlineView:sortDescriptorsDidChange:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
 # (NSDragOperation)outlineView:(NSOutlineView*)olv validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)index
         _objc.selector(
             None,
 NSOutlineViewDelegate = _objc.informal_protocol(
     "NSOutlineViewDelegate",
     [
+# (void)outlineView:(NSOutlineView *)outlineView didClickTableColumn:(NSTableColumn *)tableColumn
+        _objc.selector(
+            None,
+            selector='outlineView:didClickTableColumn:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
+# (void)outlineView:(NSOutlineView *)outlineView didDragTableColumn:(NSTableColumn *)tableColumn
+        _objc.selector(
+            None,
+            selector='outlineView:didDragTableColumn:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
+# (void)outlineView:(NSOutlineView *)outlineView mouseDownInHeaderOfTableColumn:(NSTableColumn *)tableColumn
+        _objc.selector(
+            None,
+            selector='outlineView:mouseDownInHeaderOfTableColumn:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
 # (BOOL)outlineView:(NSOutlineView *)outlineView shouldCollapseItem:(id)item
         _objc.selector(
             None,
     ]
 )
 
+NSPlaceholders = _objc.informal_protocol(
+    "NSPlaceholders",
+    [
+    ]
+)
+
 NSSavePanelDelegate = _objc.informal_protocol(
     "NSSavePanelDelegate",
     [
-# (NSComparisonResult)panel:(id)sender compareFilename:(NSString *)file1 with:(NSString *)file2 caseSensitive:(BOOL)caseSensitive
+# (NSComparisonResult)panel:(id)sender compareFilename:(NSString *)name1 with:(NSString *)name2 caseSensitive:(BOOL)caseSensitive
         _objc.selector(
             None,
             selector='panel:compareFilename:with:caseSensitive:',
             signature='i@:@@@c',
             isRequired=0,
         ),
+# (void)panel:(id)sender directoryDidChange:(NSString *)path
+        _objc.selector(
+            None,
+            selector='panel:directoryDidChange:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
 # (BOOL)panel:(id)sender isValidFilename:(NSString *)filename
         _objc.selector(
             None,
             signature='v@:@c',
             isRequired=0,
         ),
+# (void)panelSelectionDidChange:(id)sender
+        _objc.selector(
+            None,
+            selector='panelSelectionDidChange:',
+            signature='v@:@',
+            isRequired=0,
+        ),
     ]
 )
 
     ]
 )
 
+NSSpeechRecognizerDelegate = _objc.informal_protocol(
+    "NSSpeechRecognizerDelegate",
+    [
+# (void)speechRecognizer:(NSSpeechRecognizer *)sender didRecognizeCommand:(id)command
+        _objc.selector(
+            None,
+            selector='speechRecognizer:didRecognizeCommand:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
+    ]
+)
+
+NSSpeechSynthesizerDelegate = _objc.informal_protocol(
+    "NSSpeechSynthesizerDelegate",
+    [
+# (void)speechSynthesizer:(NSSpeechSynthesizer *)sender didFinishSpeaking:(BOOL)finishedSpeaking
+        _objc.selector(
+            None,
+            selector='speechSynthesizer:didFinishSpeaking:',
+            signature='v@:@c',
+            isRequired=0,
+        ),
+# (void)speechSynthesizer:(NSSpeechSynthesizer *)sender willSpeakPhoneme:(short)phonemeOpcode
+        _objc.selector(
+            None,
+            selector='speechSynthesizer:willSpeakPhoneme:',
+            signature='v@:@s',
+            isRequired=0,
+        ),
+# (void)speechSynthesizer:(NSSpeechSynthesizer *)sender willSpeakWord:(NSRange)characterRange ofString:(NSString *)string
+        _objc.selector(
+            None,
+            selector='speechSynthesizer:willSpeakWord:ofString:',
+            signature='v@:@{_NSRange=II}@',
+            isRequired=0,
+        ),
+    ]
+)
+
 NSSplitViewDelegate = _objc.informal_protocol(
     "NSSplitViewDelegate",
     [
             signature='v@:@@@i',
             isRequired=0,
         ),
+# (void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray *)oldDescriptors
+        _objc.selector(
+            None,
+            selector='tableView:sortDescriptorsDidChange:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
 # (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op
         _objc.selector(
             None,
             signature='c@:@@I',
             isRequired=0,
         ),
+# (NSArray *)textView:(NSTextView *)textView completions:(NSArray *)words forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(int *)index
+        _objc.selector(
+            None,
+            selector='textView:completions:forPartialWordRange:indexOfSelectedItem:',
+            signature='@@:@@{_NSRange=II}^i',
+            isRequired=0,
+        ),
 # (BOOL)textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector
         _objc.selector(
             None,
             signature='{_NSRange=II}@:@{_NSRange=II}{_NSRange=II}',
             isRequired=0,
         ),
+# (NSString *)textView:(NSTextView *)textView willDisplayToolTip:(NSString *)tooltip forCharacterAtIndex:(unsigned)characterIndex
+        _objc.selector(
+            None,
+            selector='textView:willDisplayToolTip:forCharacterAtIndex:',
+            signature='@@:@@I',
+            isRequired=0,
+        ),
 # (NSArray *)textView:(NSTextView *)view writablePasteboardTypesForCell:(id <NSTextAttachmentCell>)cell atIndex:(unsigned)charIndex
         _objc.selector(
             None,
             signature='v@:@',
             isRequired=0,
         ),
+# (void)textViewDidChangeTypingAttributes:(NSNotification *)notification
+        _objc.selector(
+            None,
+            selector='textViewDidChangeTypingAttributes:',
+            signature='v@:@',
+            isRequired=0,
+        ),
 # (NSUndoManager *)undoManagerForTextView:(NSTextView *)view
         _objc.selector(
             None,
             signature='@@:@',
             isRequired=0,
         ),
+# (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
+        _objc.selector(
+            None,
+            selector='toolbarSelectableItemIdentifiers:',
+            signature='@@:@',
+            isRequired=0,
+        ),
     ]
 )
 
 NSWindowDelegate = _objc.informal_protocol(
     "NSWindowDelegate",
     [
+# (NSRect)window:(NSWindow *)window willPositionSheet:(NSWindow *)sheet usingRect:(NSRect)rect
+        _objc.selector(
+            None,
+            selector='window:willPositionSheet:usingRect:',
+            signature='{_NSRect={_NSPoint=ff}{_NSSize=ff}}@:@@{_NSRect={_NSPoint=ff}{_NSSize=ff}}',
+            isRequired=0,
+        ),
 # (BOOL)windowShouldClose:(id)sender
         _objc.selector(
             None,

Lib/AppKit/test/guitest_graphics.py

+"""
+Some tests for difficult wrapped graphics functions and methods
+
+NOTE: These require a WindowServer connection on MacOS X
+"""
+import unittest
+from AppKit import *
+from Foundation import *
+import array
+import sys
+
+
+class SimpleImage:
+    """
+    Helper class that makes it easier to access individual pixels in
+    a bitmap image
+    """
+    def __init__(self, image):
+        data = image.TIFFRepresentation()
+        bitmap = NSBitmapImageRep.imageRepWithData_(data)
+        self.bitmap = bitmap
+        self.data = bitmap.bitmapData()
+        self.rowbytes = bitmap.bytesPerRow()
+        self.pixbytes = bitmap.bitsPerPixel() / 8
+        self.rowCount = bitmap.pixelsHigh()
+
+        if bitmap.isPlanar():
+            raise ValueError, "Planar image!"
+        if (bitmap.bitsPerPixel() % 8) != 0:
+            raise ValueError, "bits per pixel isn't multiple of 8"
+
+    def width(self):
+        return self.bitmap.pixelsWide()
+
+    def height(self):
+        return self.bitmap.pixelsHigh()
+
+    def getPixel(self, x, y):
+        x = self.rowCount - 1 - x
+        rowOffset = x * self.rowbytes
+        pixelOffset = y * self.pixbytes
+        offset = rowOffset + pixelOffset
+       
+        pixel = self.data[offset:offset + self.pixbytes]
+        return pixel
+
+class RectTest (unittest.TestCase):
+    def setUp(self):
+
+        
+        self.points = (
+            ((10,  0), ( 1,  1)), 
+            ((10, 10), ( 1,  1)), 
+            (( 0, 10), ( 1,  1)), 
+            (( 0,  0), ( 1,  1)), 
+            ((70, 70), (10, 10))
+        )
+
+        self.image = NSImage.alloc().initWithSize_((100, 100))
+
+    def makeArray(self, points):
+
+        a = array.array('f', len(points) * (0, 0, 0, 0))
+        for i in range(len(points)):
+            p = points[i]
+            a[(i*4) + 0] = p[0][0]
+            a[(i*4) + 1] = p[0][1]
+            a[(i*4) + 2] = p[1][0]
+            a[(i*4) + 3] = p[1][1]
+
+        return a
+
+    def assertImagePoints(self, image, points):
+        """
+        Check that the image contains white pixels everywhere but at the
+        specified locations points is sequence of NSRect values.
+        """
+
+        img = SimpleImage(image)
+
+        allpoints = [ (x, y) 
+                for x in range(img.width())
+                for y in range(img.height())
+        ]
+
+        # Check black points
+        for ((x, y), (h, w)) in points:
+            for ox in range(w):
+                for oy in range(h):
+                    allpoints.remove((x+ox, y+oy))
+                    self.assertEquals(
+                        img.getPixel(x+ox, y+oy),
+                        '\x00\x00\x00\xff',
+                        'Black pixel at %d,%d'%(x+ox, y+oy))
+
+        # And white points
+        for x, y in allpoints:
+            self.assertEquals(
+                img.getPixel(x, y),
+                '\x00\x00\x00\x00',
+                'White pixel at %d,%d'%(x, y))
+
+    
+    def tearDown(self):
+        pass
+
+
+    def test_NSRectFillList_tuple(self):
+        """
+        Check NSRectFillList with a tuple of NSRects
+        """
+        self.image.lockFocus()
+        NSRectFillList(self.points, len(self.points))
+        self.image.unlockFocus()
+
+        self.assertImagePoints(self.image, self.points)
+
+    def test_NSRectFillList_array(self):
+        """
+        Check NSRectFillList with a array.array of NSRects
+        """
+        self.image.lockFocus()
+        NSRectFillList(self.makeArray(self.points), len(self.points))
+        self.image.unlockFocus()
+
+
+if __name__ == "__main__":
+    # Force NSApp initialisation.
+    NSApplication.sharedApplication().activateIgnoringOtherApps_(0)
+    unittest.main()

Lib/AppKit/test/test_nsbezierpath.py

         self.assertEquals(p.elementCount(), 3)
 
     def test_setLineDash(self):
-        # We can barely test this, as we don't support the reverse call.
         p = NSBezierPath.bezierPath()
         p.setLineDash_count_phase_((10, 10, 20, 5), 4, 45.0)
 
+        pattern, count, phase = p.getLineDash_count_phase_(0)
+        self.assertEquals(pattern, None)
+        self.assertEquals(count, 4)
+        self.assertAlmostEquals(phase, 45.0)
+
+        pattern, count, phase = p.getLineDash_count_phase_(4)
+        self.assertAlmostEquals(pattern[0], 10)
+        self.assertAlmostEquals(pattern[1], 10)
+        self.assertAlmostEquals(pattern[2], 20)
+        self.assertAlmostEquals(pattern[3], 5)
+        self.assertEquals(count, 4)
+        self.assertAlmostEquals(phase, 45.0)
+
     def test_elementAtIndex(self):
         p = NSBezierPath.bezierPath()
         p.moveToPoint_((10, 10))

Lib/Foundation/__init__.py

 try:
     import autoGIL
 except ImportError:
+    # We don't have an autoGIL module on GNUstep
     pass
 else:
     # Install an observer callback in the current CFRunLoop that will

Lib/Foundation/protocols.py

     ]
 )
 
+NSDeprecatedKeyValueCoding = _objc.informal_protocol(
+    "NSDeprecatedKeyValueCoding",
+    [
+# (id)handleQueryWithUnboundKey:(NSString *)key
+        _objc.selector(
+            None,
+            selector='handleQueryWithUnboundKey:',
+            signature='@@:@',
+            isRequired=0,
+        ),
+# (void)handleTakeValue:(id)value forUnboundKey:(NSString *)key
+        _objc.selector(
+            None,
+            selector='handleTakeValue:forUnboundKey:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
+# (void)takeValue:(id)value forKey:(NSString *)key
+        _objc.selector(
+            None,
+            selector='takeValue:forKey:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
+# (void)takeValue:(id)value forKeyPath:(NSString *)keyPath
+        _objc.selector(
+            None,
+            selector='takeValue:forKeyPath:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
+# (void)takeValuesFromDictionary:(NSDictionary *)properties
+        _objc.selector(
+            None,
+            selector='takeValuesFromDictionary:',
+            signature='v@:@',
+            isRequired=0,
+        ),
+# (void)unableToSetNilForKey:(NSString *)key
+        _objc.selector(
+            None,
+            selector='unableToSetNilForKey:',
+            signature='v@:@',
+            isRequired=0,
+        ),
+# (NSDictionary *)valuesForKeys:(NSArray *)keys
+        _objc.selector(
+            None,
+            selector='valuesForKeys:',
+            signature='@@:@',
+            isRequired=0,
+        ),
+    ]
+)
+
 NSDistantObjectRequestMethods = _objc.informal_protocol(
     "NSDistantObjectRequestMethods",
     [
 NSKeyValueCoding = _objc.informal_protocol(
     "NSKeyValueCoding",
     [
+# (NSMutableArray *)mutableArrayValueForKey:(NSString *)key
+        _objc.selector(
+            None,
+            selector='mutableArrayValueForKey:',
+            signature='@@:@',
+            isRequired=0,
+        ),
+# (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath
+        _objc.selector(
+            None,
+            selector='mutableArrayValueForKeyPath:',
+            signature='@@:@',
+            isRequired=0,
+        ),
+# (void)setNilValueForKey:(NSString *)key
+        _objc.selector(
+            None,
+            selector='setNilValueForKey:',
+            signature='v@:@',
+            isRequired=0,
+        ),
+# (void)setValue:(id)value forKey:(NSString *)key
+        _objc.selector(
+            None,
+            selector='setValue:forKey:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
+# (void)setValue:(id)value forKeyPath:(NSString *)keyPath
+        _objc.selector(
+            None,
+            selector='setValue:forKeyPath:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
+# (void)setValue:(id)value forUndefinedKey:(NSString *)key
+        _objc.selector(
+            None,
+            selector='setValue:forUndefinedKey:',
+            signature='v@:@@',
+            isRequired=0,
+        ),
+# (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues
+        _objc.selector(
+            None,
+            selector='setValuesForKeysWithDictionary:',
+            signature='v@:@',
+            isRequired=0,
+        ),
 # (id)storedValueForKey:(NSString *)key
         _objc.selector(
             None,
             signature='v@:@@',
             isRequired=0,
         ),
-# (void)takeValue:(id)value forKey:(NSString *)key
+# (BOOL)validateValue:(id *)ioValue forKey:(NSString *)inKey error:(NSError **)outError
         _objc.selector(
             None,
-            selector='takeValue:forKey:',
-            signature='v@:@@',
+            selector='validateValue:forKey:error:',
+            signature='c@:^@@^@',
+            isRequired=0,
+        ),
+# (BOOL)validateValue:(id *)ioValue forKeyPath:(NSString *)inKeyPath error:(NSError **)outError
+        _objc.selector(
+            None,
+            selector='validateValue:forKeyPath:error:',
+            signature='c@:^@@^@',
             isRequired=0,
         ),
 # (id)valueForKey:(NSString *)key
             signature='@@:@',
             isRequired=0,
         ),
+# (id)valueForKeyPath:(NSString *)keyPath
+        _objc.selector(
+            None,
+            selector='valueForKeyPath:',
+            signature='@@:@',
+            isRequired=0,
+        ),
+# (id)valueForUndefinedKey:(NSString *)key
+        _objc.selector(
+            None,
+            selector='valueForUndefinedKey:',
+            signature='@@:@',
+            isRequired=0,
+        ),
     ]
 )
 
-NSKeyValueCodingException = _objc.informal_protocol(
-    "NSKeyValueCodingException",
+NSKeyValueObserverNotification = _objc.informal_protocol(
+    "NSKeyValueObserverNotification",
     [
-# (id)handleQueryWithUnboundKey:(NSString *)key
+# (void)didChange:(NSKeyValueChange)change valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key
         _objc.selector(
             None,
-            selector='handleQueryWithUnboundKey:',
-            signature='@@:@',
+            selector='didChange:valuesAtIndexes:forKey:',
+            signature='v@:i@@',
             isRequired=0,
         ),
-# (void)handleTakeValue:(id)value forUnboundKey:(NSString *)key
+# (void)didChangeValueForKey:(NSString *)key
         _objc.selector(
             None,
-            selector='handleTakeValue:forUnboundKey:',
-            signature='v@:@@',
+            selector='didChangeValueForKey:',
+            signature='v@:@',
             isRequired=0,
         ),
-# (void)unableToSetNilForKey:(NSString *)key
+# (void)willChange:(NSKeyValueChange)change valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key
         _objc.selector(
             None,
-            selector='unableToSetNilForKey:',
+            selector='willChange:valuesAtIndexes:forKey:',
+            signature='v@:i@@',
+            isRequired=0,
+        ),
+# (void)willChangeValueForKey:(NSString *)key
+        _objc.selector(
+            None,
+            selector='willChangeValueForKey:',
             signature='v@:@',
             isRequired=0,
         ),
     ]