diff dwt/widgets/Display.d @ 45:d8635bb48c7c

Merge with SWT 3.5
author Jacob Carlborg <doob@me.com>
date Mon, 01 Dec 2008 17:07:00 +0100
parents 198549365851
children cfa563df4fdd
line wrap: on
line diff
--- a/dwt/widgets/Display.d	Tue Oct 21 15:20:04 2008 +0200
+++ b/dwt/widgets/Display.d	Mon Dec 01 17:07:00 2008 +0100
@@ -1,5 +1,5 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -9,7 +9,7 @@
  *     IBM Corporation - initial API and implementation
  *     
  * Port to the D programming language:
- *     Jacob Carlborg <jacob.carlborg@gmail.com>
+ *     Jacob Carlborg <doob@me.com>
  *******************************************************************************/
 module dwt.widgets.Display;
 
@@ -24,29 +24,42 @@
 import dwt.graphics.Image;
 import dwt.graphics.Point;
 import dwt.graphics.Rectangle;
+import dwt.internal.C;
 import dwt.internal.cocoa.CGPoint;
 import dwt.internal.cocoa.NSApplication;
 import dwt.internal.cocoa.NSArray;
 import dwt.internal.cocoa.NSAutoreleasePool;
 import dwt.internal.cocoa.NSBundle;
+import dwt.internal.cocoa.NSButton;
 import dwt.internal.cocoa.NSColor;
 import dwt.internal.cocoa.NSColorSpace;
+import dwt.internal.cocoa.NSComboBox;
 import dwt.internal.cocoa.NSDate;
 import dwt.internal.cocoa.NSDictionary;
 import dwt.internal.cocoa.NSEvent;
 import dwt.internal.cocoa.NSGraphicsContext;
 import dwt.internal.cocoa.NSImage;
+import dwt.internal.cocoa.NSImageView;
 import dwt.internal.cocoa.NSMenu;
 import dwt.internal.cocoa.NSMenuItem;
+import dwt.internal.cocoa.NSMutableDictionary;
 import dwt.internal.cocoa.NSNumber;
 import dwt.internal.cocoa.NSObject;
 import dwt.internal.cocoa.NSPoint;
+import dwt.internal.cocoa.NSPopUpButton;
+import dwt.internal.cocoa.NSRange;
 import dwt.internal.cocoa.NSRect;
 import dwt.internal.cocoa.NSResponder;
 import dwt.internal.cocoa.NSRunLoop;
 import dwt.internal.cocoa.NSScreen;
+import dwt.internal.cocoa.NSSearchField;
+import dwt.internal.cocoa.NSSize;
+import dwt.internal.cocoa.NSSlider;
+import dwt.internal.cocoa.NSStepper;
 import dwt.internal.cocoa.NSString;
-import dwt.internal.cocoa.NSText;
+import dwt.internal.cocoa.NSTextField;
+import dwt.internal.cocoa.NSTextView;
+import dwt.internal.cocoa.NSThread;
 import dwt.internal.cocoa.NSTimer;
 import dwt.internal.cocoa.NSView;
 import dwt.internal.cocoa.NSWindow;
@@ -55,6 +68,7 @@
 import dwt.internal.cocoa.SWTApplicationDelegate;
 import dwt.internal.cocoa.SWTWindowDelegate;
 import dwt.internal.cocoa.id;
+import dwt.internal.cocoa.objc_super;
 
 import tango.core.Thread;
 
@@ -158,6 +172,8 @@
  * @see #readAndDispatch
  * @see #sleep
  * @see Device#dispose
+ * @see <a href="http://www.eclipse.org/swt/snippets/#display">Display snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
  */
 public class Display : Device {
     
@@ -170,21 +186,41 @@
     Synchronizer synchronizer;
     Thread thread;
     bool allowTimers, runAsyncMessages_;
-    
-    int lastModifiers;
+
+    NSGraphicsContext[] contexts;
 
     Caret currentCaret;
     
+    bool dragging;
+    Control currentControl, grabControl, trackingControl;
+
+    NSDictionary markedAttributes;
+
+    Shell [] modalShells;
+    
     Menu menuBar;
+    Menu[] menus, popups;
 
     NSApplication application;
+    int /*long*/ applicationClass;
+    NSImage dockImage;
+    bool isEmbedded;
+    
+    Control focusControl;
+    
+    NSWindow screenWindow;
     NSAutoreleasePool pool;
+    int loopCounter = 0;
+    bool idle;
+    static final short DWT_IDLE_TYPE = 1;
 
-    NSPoint cascade = NSPoint();
+    int[] screenID = new int[32];
+    NSPoint[] screenCascade = new NSPoint[32];
+    static Callback dialogCallback3;
+    static Callback applicationCallback2, applicationCallback3, applicationCallback6;
     
     /* Menus */
 //  Menu menuBar;
-//  Menu [] menus, popups;
 //  static final int ID_TEMPORARY = 1000;
 //  static final int ID_START = 1001;
     
@@ -202,83 +238,84 @@
     static int [] [] KeyTable = [
 
          /* Keyboard and Mouse Masks */
-//       [58,    DWT.ALT],
-//       [56,    DWT.SHIFT],
-//       [59,    DWT.CONTROL],
-//       [55,    DWT.COMMAND],
+        {58,    DWT.ALT},
+        {56,    DWT.SHIFT},
+        {59,    DWT.CONTROL},
+        {55,    DWT.COMMAND},       
+        {61,    DWT.ALT},
+        {62,    DWT.CONTROL},
+        {60,    DWT.SHIFT},
+        {54,    DWT.COMMAND},
 
          /* Non-Numeric Keypad Keys */
-         [OS.NSUpArrowFunctionKey, DWT.ARROW_UP],
-         [OS.NSDownArrowFunctionKey, DWT.ARROW_DOWN],
-         [OS.NSLeftArrowFunctionKey, DWT.ARROW_LEFT],
-         [OS.NSRightArrowFunctionKey, DWT.ARROW_RIGHT],
-         [OS.NSPageUpFunctionKey, DWT.PAGE_UP],
-         [OS.NSPageDownFunctionKey, DWT.PAGE_DOWN],
-         [OS.NSHomeFunctionKey, DWT.HOME],
-         [OS.NSEndFunctionKey, DWT.END],
-         
+        {126, DWT.ARROW_UP},
+        {125, DWT.ARROW_DOWN},
+        {123, DWT.ARROW_LEFT},
+        {124, DWT.ARROW_RIGHT},
+        {116, DWT.PAGE_UP},
+        {121, DWT.PAGE_DOWN},
+        {115, DWT.HOME},
+        {119, DWT.END},
 //       [??,    DWT.INSERT],
 
          /* Virtual and Ascii Keys */
-         [OS.NSDeleteCharacter, DWT.BS],
-//       [36,    DWT.CR],
-         [OS.NSDeleteFunctionKey, DWT.DEL],
-//       [53,    DWT.ESC],
-//       [76,    DWT.LF],
-//       [48,    DWT.TAB],   
+        {51,    DWT.BS},
+        {36,    DWT.CR},
+        {117,   DWT.DEL},
+        {53,    DWT.ESC},
+        {76,    DWT.LF},
+        {48,    DWT.TAB},   
          
          /* Functions Keys */
-         [OS.NSF1FunctionKey, DWT.F1],
-         [OS.NSF2FunctionKey, DWT.F2],
-         [OS.NSF3FunctionKey, DWT.F3],
-         [OS.NSF4FunctionKey, DWT.F4],
-         [OS.NSF5FunctionKey, DWT.F5],
-         [OS.NSF6FunctionKey, DWT.F6],
-         [OS.NSF7FunctionKey, DWT.F7],
-         [OS.NSF8FunctionKey, DWT.F8],
-         [OS.NSF9FunctionKey, DWT.F9],
-         [OS.NSF10FunctionKey, DWT.F10],
-         [OS.NSF11FunctionKey, DWT.F11],
-         [OS.NSF12FunctionKey, DWT.F12],
-         [OS.NSF13FunctionKey, DWT.F13],
-         [OS.NSF14FunctionKey, DWT.F14],
-         [OS.NSF15FunctionKey, DWT.F15],
+        {122, DWT.F1},
+        {120, DWT.F2},
+        {99,    DWT.F3},
+        {118, DWT.F4},
+        {96,    DWT.F5},
+        {97,    DWT.F6},
+        {98,    DWT.F7},
+        {100, DWT.F8},
+        {101, DWT.F9},
+        {109, DWT.F10},
+        {103, DWT.F11},
+        {111, DWT.F12},
+        {105, DWT.F13},
+        {107, DWT.F14},
+        {113, DWT.F15},
          
          /* Numeric Keypad Keys */
-//       [67, DWT.KEYPAD_MULTIPLY],
-//       [69, DWT.KEYPAD_ADD],
-//       [76, DWT.KEYPAD_CR],
-//       [78, DWT.KEYPAD_SUBTRACT],
-//       [65, DWT.KEYPAD_DECIMAL],
-//       [75, DWT.KEYPAD_DIVIDE],
-//       [82, DWT.KEYPAD_0],
-//       [83, DWT.KEYPAD_1],
-//       [84, DWT.KEYPAD_2],
-//       [85, DWT.KEYPAD_3],
-//       [86, DWT.KEYPAD_4],
-//       [87, DWT.KEYPAD_5],
-//       [88, DWT.KEYPAD_6],
-//       [89, DWT.KEYPAD_7],
-//       [91, DWT.KEYPAD_8],
-//       [92, DWT.KEYPAD_9],
-//       [81, DWT.KEYPAD_EQUAL],
+        {67, DWT.KEYPAD_MULTIPLY},
+        {69, DWT.KEYPAD_ADD},
+        {76, DWT.KEYPAD_CR},
+        {78, DWT.KEYPAD_SUBTRACT},
+        {65, DWT.KEYPAD_DECIMAL},
+        {75, DWT.KEYPAD_DIVIDE},
+        {82, DWT.KEYPAD_0},
+        {83, DWT.KEYPAD_1},
+        {84, DWT.KEYPAD_2},
+        {85, DWT.KEYPAD_3},
+        {86, DWT.KEYPAD_4},
+        {87, DWT.KEYPAD_5},
+        {88, DWT.KEYPAD_6},
+        {89, DWT.KEYPAD_7},
+        {91, DWT.KEYPAD_8},
+        {92, DWT.KEYPAD_9},
+        {81, DWT.KEYPAD_EQUAL},
 
          /* Other keys */
-//       [??,    DWT.CAPS_LOCK],
-         
-//       [71,    DWT.NUM_LOCK],
-         
+        {57,    DWT.CAPS_LOCK},
+        {71,    DWT.NUM_LOCK},
 //       [??,    DWT.SCROLL_LOCK],
 //       [??,    DWT.PAUSE],
 //       [??,    DWT.BREAK],
 //       [??,    DWT.PRINT_SCREEN],
-         
-         [OS.NSHelpFunctionKey, DWT.HELP],
+        {114, DWT.HELP},
          
      ];
 
     static String APP_NAME = "DWT";
     static const String ADD_WIDGET_KEY = "dwt.internal.addWidget";
+    static const String DWT_OBJECT = "DWT_OBJECT"; //$NON-NLS-1$
 
     /* Multiple Displays. */
     static Display Default;
@@ -347,6 +384,20 @@
     return 0;
 }
 
+void addContext (NSGraphicsContext context) {
+    if (contexts is null) contexts = new NSGraphicsContext [12];
+    for (int i=0; i<contexts.length; i++) {
+        if (contexts[i] !is null && contexts [i].id is context.id) {
+            contexts [i] = context;
+            return;
+        }
+    }
+    NSGraphicsContext [] newContexts = new NSGraphicsContext [contexts.length + 12];
+    newContexts [contexts.length] = context;
+    System.arraycopy (contexts, 0, newContexts, 0, contexts.length);
+    contexts = newContexts;
+}
+
 /**
  * Adds the listener to the collection of listeners who will
  * be notified when an event of the given type occurs anywhere
@@ -421,40 +472,43 @@
     eventTable.hook (eventType, listener);
 }
 
-//void addMenu (Menu menu) {
-//  if (menus is null) menus = new Menu [12];
-//  for (int i=0; i<menus.length; i++) {
-//      if (menus [i] is null) {
-//          menu.id = cast(short)(ID_START + i);
-//          menus [i] = menu;
-//          return;
-//      }
-//  }
-//  Menu [] newMenus = new Menu [menus.length + 12];
-//  menu.id = cast(short)(ID_START + menus.length);
-//  newMenus [menus.length] = menu;
-//  System.arraycopy (menus, 0, newMenus, 0, menus.length);
-//  menus = newMenus;
-//}
-//
-//void addPopup (Menu menu) {
-//  if (popups is null) popups = new Menu [4];
-//  int length = popups.length;
-//  for (int i=0; i<length; i++) {
-//      if (popups [i] is menu) return;
-//  }
-//  int index = 0;
-//  while (index < length) {
-//      if (popups [index] is null) break;
-//      index++;
-//  }
-//  if (index is length) {
-//      Menu [] newPopups = new Menu [length + 4];
-//      System.arraycopy (popups, 0, newPopups, 0, length);
-//      popups = newPopups;
-//  }
-//  popups [index] = menu;
-//}
+void addMenu (Menu menu) {
+    if (menus is null) menus = new Menu [12];
+    for (int i=0; i<menus.length; i++) {
+        if (menus [i] is null) {
+            menus [i] = menu;
+            return;
+        }
+    }
+    Menu [] newMenus = new Menu [menus.length + 12];
+    newMenus [menus.length] = menu;
+    System.arraycopy (menus, 0, newMenus, 0, menus.length);
+    menus = newMenus;
+}
+
+void addPopup (Menu menu) {
+    if (popups is null) popups = new Menu [4];
+    int length = popups.length;
+    for (int i=0; i<length; i++) {
+        if (popups [i] is menu) return;
+    }
+    int index = 0;
+    while (index < length) {
+        if (popups [index] is null) break;
+        index++;
+    }
+    if (index is length) {
+        Menu [] newPopups = new Menu [length + 4];
+        System.arraycopy (popups, 0, newPopups, 0, length);
+        popups = newPopups;
+    }
+    popups [index] = menu;
+}
+
+void addWidget (NSObject view, Widget widget) {
+    if (view is null) return;
+    OS.object_setInstanceVariable (view.id, DWT_OBJECT, widget.jniRef);
+}
 
 /**
  * Causes the <code>run()</code> method of the runnable to
@@ -496,6 +550,23 @@
  */
 public void beep () {
     checkDevice ();
+    OS.NSBeep ();
+}
+
+void cascadeWindow (NSWindow window, NSScreen screen) {
+    NSDictionary dictionary = screen.deviceDescription();
+    int screenNumber = new NSNumber(dictionary.objectForKey(NSString.stringWith("NSScreenNumber")).id).intValue();
+    int index = 0;
+    while (screenID[index] !is 0 && screenID[index] !is screenNumber) index++;
+    screenID[index] = screenNumber;
+    NSPoint cascade = screenCascade[index];
+    if (cascade is null) {
+        NSRect frame = screen.frame();
+        cascade = new NSPoint();
+        cascade.x = frame.x;
+        cascade.y = frame.y + frame.height;
+    }
+    screenCascade[index] = window.cascadeTopLeftFromPoint(cascade);
 }
 
 protected void checkDevice () {
@@ -616,6 +687,22 @@
     return result.toString ();
 }
 
+void clearModal (Shell shell) {
+    if (modalShells is null) return;
+    int index = 0, length = modalShells.length;
+    while (index < length) {
+        if (modalShells [index] is shell) break;
+        if (modalShells [index] is null) return;
+        index++;
+    }
+    if (index is length) return;
+    System.arraycopy (modalShells, index + 1, modalShells, index, --length - index);
+    modalShells [length] = null;
+    if (index is 0 && modalShells [0] is null) modalShells = null;
+    Shell [] shells = getShells ();
+    for (int i=0; i<shells.length; i++) shells [i].updateModal ();
+}
+
 /**
  * Requests that the connection between DWT and the underlying
  * operating system be closed.
@@ -664,61 +751,77 @@
         error(DWT.ERROR_NOT_IMPLEMENTED);
     }
 
+    NSThread nsthread = NSThread.currentThread();
+    NSMutableDictionary dictionary = nsthread.threadDictionary();
+    NSString key = NSString.stringWith("DWT_NSAutoreleasePool");
+    pool = new NSAutoreleasePool(dictionary.objectForKey(key));
+
+    application = NSApplication.sharedApplication();
+
     /*
-    * Feature in the Macintosh.  On OS 10.2, it is necessary
-    * to explicitly check in with the Process Manager and set
-    * the current process to be the front process in order for
-    * windows to come to the front by default.  The fix is call
-    * both GetCurrentProcess() and SetFrontProcess().
-    * 
-    * NOTE: It is not actually necessary to use the process
-    * serial number returned by GetCurrentProcess() in the
-    * call to SetFrontProcess() (ie. kCurrentProcess can be
-    * used) but both functions must be called in order for
-    * windows to come to the front.
-    */
+     * TODO: If an NSApplication is already running we don't want to create another NSApplication.
+     * But if we don't we won't get mouse events, since we currently need to subclass NSApplication and intercept sendEvent to
+     * deliver mouse events correctly to widgets.   
+     */
+    if (!application.isRunning()) {
+        /*
+         * Feature in the Macintosh.  On OS 10.2, it is necessary
+         * to explicitly check in with the Process Manager and set
+         * the current process to be the front process in order for
+         * windows to come to the front by default.  The fix is call
+         * both GetCurrentProcess() and SetFrontProcess().
+         * 
+         * NOTE: It is not actually necessary to use the process
+         * serial number returned by GetCurrentProcess() in the
+         * call to SetFrontProcess() (ie. kCurrentProcess can be
+         * used) but both functions must be called in order for
+         * windows to come to the front.
+         */
     ProcessSerialNumber* psn;
-    if (OS.GetCurrentProcess (psn) is OS.noErr) {
-//      int pid = OS.getpid ();
-//      byte [] buffer = null;
-//      int ptr = OS.getenv (ascii ("APP_NAME_" + pid));
-//      if (ptr !is 0) {
-//          buffer = new byte [OS.strlen (ptr) + 1];
-//          OS.memmove (buffer, ptr, buffer.length);
-//      } else {
-//          if (APP_NAME !is null) {
-//              char [] chars = new char [APP_NAME.length ()];
-//              APP_NAME.getChars (0, chars.length, chars, 0);
-//              int cfstring = OS.CFStringCreateWithCharacters (OS.kCFAllocatorDefault, chars, chars.length);
-//              if (cfstring !is 0) {
-//                  CFRange range = new CFRange ();
-//                  range.length = chars.length;
-//                  int encoding = OS.CFStringGetSystemEncoding ();
-//                  int [] size = new int [1];
-//                  int numChars = OS.CFStringGetBytes (cfstring, range, encoding, cast(byte) '?', true, null, 0, size);
-//                  if (numChars !is 0) {
-//                      buffer = new byte [size [0] + 1];
-//                      numChars = OS.CFStringGetBytes (cfstring, range, encoding, cast(byte) '?', true, buffer, size [0], size);
-//                  }
-//                  OS.CFRelease (cfstring);
-//              }
-//          }
-//      }
-//      if (buffer !is null) OS.CPSSetProcessName (psn, buffer); 
-        OS.TransformProcessType (psn, OS.kProcessTransformToForegroundApplication);
-        OS.SetFrontProcess (psn);
-//      ptr = OS.getenv (ascii ("APP_ICON_" + pid));
-//      if (ptr !is 0) {
-//          int image = readImageRef (ptr);
-//          if (image !is 0) {
-//              dockImage = image;
-//              OS.SetApplicationDockTileImage (dockImage);
-//          }
-//      }
+        if (OS.GetCurrentProcess (psn) is OS.noErr) {
+            int pid = OS.getpid ();
+            int /*long*/ ptr = OS.getenv (ascii ("APP_NAME_" + pid));
+            if (ptr  is 0 && APP_NAME !is null) {
+                ptr = NSString.stringWith(APP_NAME).UTF8String();   
+            }
+            if (ptr !is 0) OS.CPSSetProcessName (psn, ptr);
+            OS.TransformProcessType (psn, OS.kProcessTransformToForegroundApplication);
+            OS.SetFrontProcess (psn);
+            ptr = OS.getenv (ascii ("APP_ICON_" + pid));
+            if (ptr !is 0) {
+                NSString path = NSString.stringWithUTF8String (ptr);
+                NSImage image = (NSImage) new NSImage().alloc();
+                image = image.initByReferencingFile(path);
+                dockImage = image;
+                application.setApplicationIconImage(image);
+            }
+        }
+
+        String className = "SWTApplication";
+        int /*long*/ cls;
+        if ((cls = OS.objc_lookUpClass (className)) is 0) {
+            Class clazz = getClass();
+            applicationCallback2 = new Callback(clazz, "applicationProc", 2);
+            int /*long*/ proc2 = applicationCallback2.getAddress();
+            if (proc2 is 0) error (DWT.ERROR_NO_MORE_CALLBACKS);
+            applicationCallback3 = new Callback(clazz, "applicationProc", 3);
+            int /*long*/ proc3 = applicationCallback3.getAddress();
+            if (proc3 is 0) error (DWT.ERROR_NO_MORE_CALLBACKS);
+            applicationCallback6 = new Callback(clazz, "applicationProc", 6);
+            int /*long*/ proc6 = applicationCallback6.getAddress();
+            if (proc6 is 0) error (DWT.ERROR_NO_MORE_CALLBACKS);
+            cls = OS.objc_allocateClassPair(OS.class_NSApplication, className, 0);
+            OS.class_addMethod(cls, OS.sel_sendEvent_, proc3, "@:@");
+            OS.class_addMethod(cls, OS.sel_nextEventMatchingMask_untilDate_inMode_dequeue_, proc6, "@:i@@B");
+            OS.class_addMethod(cls, OS.sel_isRunning, proc2, "@:");
+            OS.objc_registerClassPair(cls);
+        }
+        applicationClass = OS.object_setClass(application.id, cls);
+    } else {
+        isEmbedded = true;
     }
-    
-    pool = cast(NSAutoreleasePool)(new NSAutoreleasePool()).alloc().init();
-    application = NSApplication.sharedApplication();
+
+    //  application = new NSApplication(OS.objc_msgSend(cls, OS.sel_sharedApplication));
 }
 
 static void deregister (Display display) {
@@ -746,8 +849,6 @@
 }
 
 void destroyDisplay () {
-    if (pool !is null) pool.release();
-    pool = null;
     application = null;
 }
 
@@ -813,16 +914,7 @@
  */
 public Widget findWidget (objc.id handle) {
     checkDevice ();
-    if (handle !is null && OS.objc_msgSend(handle, OS.sel_respondsToSelector_1, OS.sel_tag) !is null) {
-        NSInteger tag = cast(NSInteger) OS.objc_msgSend(handle, OS.sel_tag);
-        if (tag !is -1) {
-            Object object = OS.JNIGetObject(tag);
-            if (cast(Widget) object) {
-                return cast(Widget)object;
-            }
-        }
-    }
-    return null;
+    return getWidget (handle);
 }
 
 /**
@@ -849,7 +941,7 @@
  */
 public Widget findWidget (objc.id handle, int id) {
     checkDevice ();
-    return null;
+    return getWidget (handle);
 }
 
 /**
@@ -910,16 +1002,14 @@
  */
 public Shell getActiveShell () {
     checkDevice ();
-    NSWindow window = application.keyWindow();
-    if (window !is null) {
-        NSView view = window.contentView();
-        if (view !is null && view.respondsToSelector(OS.sel_tag)) {
-            NSInteger tag = cast(NSInteger) OS.objc_msgSend(view.id_, OS.sel_tag);
-            if (tag !is -1) {
-                Object object = OS.JNIGetObject(tag);
-                if (cast(Shell) object) {
-                    return cast(Shell)object;
-                }
+    NSArray windows = application.windows();
+    int count = (int)/*64*/windows.count();
+    for (int i = 0; i < count; i++) {
+        NSWindow win = new NSWindow(windows.objectAtIndex(i));
+        if (win.isKeyWindow()) {
+            Widget widget = getWidget(win.contentView());
+            if (widget instanceof Shell) {
+                return cast(Shell)widget;
             }
         }
     }
@@ -927,7 +1017,8 @@
 }
 
 /**
- * Returns a rectangle describing the receiver's size and location.
+ * Returns a rectangle describing the receiver's size and location. Note that
+ * on multi-monitor systems the origin can be negative.
  *
  * @return the bounding rectangle
  *
@@ -938,7 +1029,30 @@
  */
 public Rectangle getBounds () {
     checkDevice ();
-    return super.getBounds ();
+    NSArray screens = NSScreen.screens();
+    return getBounds (screens);
+}
+
+Rectangle getBounds (NSArray screens) {
+    NSRect primaryFrame = new NSScreen(screens.objectAtIndex(0)).frame();
+    float /*double*/ minX = Float.MAX_VALUE, maxX = Float.MIN_VALUE;
+    float /*double*/ minY = Float.MAX_VALUE, maxY = Float.MIN_VALUE;
+    int /*long*/ count = screens.count();
+    for (int i = 0; i < count; i++) {
+        NSScreen screen = new NSScreen(screens.objectAtIndex(i));
+        NSRect frame = screen.frame();
+        float /*double*/ x1 = frame.x, x2 = frame.x + frame.width;
+        float /*double*/ y1 = primaryFrame.height - frame.y, y2 = primaryFrame.height - (frame.y + frame.height);
+        if (x1 < minX) minX = x1;
+        if (x2 < minX) minX = x2;
+        if (x1 > maxX) maxX = x1;
+        if (x2 > maxX) maxX = x2;
+        if (y1 < minY) minY = y1;
+        if (y2 < minY) minY = y2;
+        if (y1 > maxY) maxY = y1;
+        if (y2 > maxY) maxY = y2;
+    }
+    return new Rectangle ((int)minX, (int)minY, (int)(maxX - minX), (int)(maxY - minY));
 }
 
 /**
@@ -972,7 +1086,13 @@
  */
 public Rectangle getClientArea () {
     checkDevice ();
-    return super.getClientArea ();
+    NSArray screens = NSScreen.screens();
+    if (screens.count() !is 1) return getBounds (screens);
+    NSScreen screen = new NSScreen(screens.objectAtIndex(0));
+    NSRect frame = screen.frame();
+    NSRect visibleFrame = screen.visibleFrame();
+    float /*double*/ y = frame.height - (visibleFrame.y + visibleFrame.height);
+    return new Rectangle((int)visibleFrame.x, (int)y, (int)visibleFrame.width, (int)visibleFrame.height);
 }
 
 /**
@@ -989,7 +1109,7 @@
  */
 public Control getCursorControl () {
     checkDevice();
-    return null;
+    return findControl(null, false, false, true);
 }
 
 /**
@@ -1006,9 +1126,8 @@
 public Point getCursorLocation () {
     checkDevice ();
     NSPoint location = NSEvent.mouseLocation();
-    //TODO bad for other screens
-    NSRect rect = NSScreen.mainScreen().frame();
-    return new Point (cast(int) location.x, cast(int) (rect.height - location.y));
+    NSRect primaryFrame = getPrimaryFrame();
+    return new Point (cast(int) location.x, cast(int) (primaryFrame.height - location.y));
 }
 
 /**
@@ -1161,46 +1280,29 @@
 public Control getFocusControl () {
     checkDevice ();
     NSWindow window = application.keyWindow();
+    return GetFocusControl(window);
+}
+
+static Control GetFocusControl(NSWindow window) {
     if (window !is null) {
-        NSResponder view = window.firstResponder();
-        if (view !is null && view.respondsToSelector(OS.sel_tag)) {
-            NSInteger tag = cast(NSInteger) OS.objc_msgSend(view.id_, OS.sel_tag);
-            if (tag !is -1) {
-                Object object = OS.JNIGetObject(tag);
-                if (cast(Control) object) {
-                    //TODO go up hierarchy
-                    return cast(Control)object;
+        NSResponder responder = window.firstResponder();
+        if (responder !is null && !responder.respondsToSelector(OS.sel_superview)) {
+            return null;
+        }
+        NSView view = new NSView(responder.id);
+        if (view !is null) {
+            do {
+                Widget widget = GetWidget (view.id);
+                if (widget instanceof Control) {
+                    return (Control)widget;
                 }
-            } else {
-                /*
-                * If the first responder is the shared field editor then answer its
-                * delegate as the focus control.
-                */
-                if (view.isKindOfClass(NSText.static_class())) {
-                    NSText text = new NSText(view.id_);
-                    if (text.isFieldEditor()) {
-                        id delegateId = text.delegate_();
-                        if (delegateId !is null) {
-                            NSObject delegate_ = new NSObject(delegateId.id_);
-                            if (delegate_.respondsToSelector(OS.sel_tag)) {
-                                tag = cast(NSInteger) OS.objc_msgSend(delegate_.id_, OS.sel_tag);
-                                if (tag !is 0 && tag !is -1) {
-                                    Object object = OS.JNIGetObject(tag);
-                                    if (cast(Control) object) {
-                                        return cast(Control)object;
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
+                view = view.superview();
+            } while (view !is null);
         }
     }
     return null;
 }
 
-
 /**
  * Returns true when the high contrast mode is enabled.
  * Otherwise, false is returned.
@@ -1270,34 +1372,23 @@
     return cast(int) System.currentTimeMillis ();
 }
 
-//Menu [] getMenus (Decorations shell) {
-//  if (menus is null) return new Menu [0];
-//  int count = 0;
-//  for (int i = 0; i < menus.length; i++) {
-//      Menu menu = menus[i];
-//      if (menu !is null && menu.parent is shell) count++;
-//  }
-//  int index = 0;
-//  Menu[] result = new Menu[count];
-//  for (int i = 0; i < menus.length; i++) {
-//      Menu menu = menus[i];
-//      if (menu !is null && menu.parent is shell) {
-//          result[index++] = menu;
-//      }
-//  }
-//  return result;
-//}
-//
-//Menu getMenu (int id) {
-//  if (menus is null) return null;
-//  int index = id - ID_START;
-//  if (0 <= index && index < menus.length) return menus [index];
-//  return null;
-//}
-//
-//Menu getMenuBar () {
-//  return menuBar;
-//}
+Menu [] getMenus (Decorations shell) {
+    if (menus is null) return new Menu [0];
+    int count = 0;
+    for (int i = 0; i < menus.length; i++) {
+        Menu menu = menus[i];
+        if (menu !is null && menu.parent is shell) count++;
+    }
+    int index = 0;
+    Menu[] result = new Menu[count];
+    for (int i = 0; i < menus.length; i++) {
+        Menu menu = menus[i];
+        if (menu !is null && menu.parent is shell) {
+            result[index++] = menu;
+        }
+    }
+    return result;
+}
 
 int getMessageCount () {
     return synchronizer.getMessageCount ();
@@ -1313,19 +1404,19 @@
 public dwt.widgets.Monitor.Monitor [] getMonitors () {
     checkDevice ();
     NSArray screens = NSScreen.screens();
-    int count = screens.count();
-    dwt.widgets.Monitor.Monitor [] monitors = new dwt.widgets.Monitor.Monitor [count];
+    NSRect primaryFrame = new NSScreen(screens.objectAtIndex(0)).frame();
+    int count = (int)/*64*/screens.count();
     for (int i=0; i<count; i++) {
         dwt.widgets.Monitor.Monitor monitor = new dwt.widgets.Monitor.Monitor ();
         NSScreen screen = new NSScreen(screens.objectAtIndex(i));
         NSRect frame = screen.frame();
         monitor.x = cast(int)frame.x;
-        monitor.y = cast(int)frame.y;
+        monitor.y = (int)(primaryFrame.height - (frame.y + frame.height));
         monitor.width = cast(int)frame.width;
         monitor.height = cast(int)frame.height;
         NSRect visibleFrame = screen.visibleFrame();
         monitor.clientX = cast(int)visibleFrame.x;
-        monitor.clientY = cast(int)visibleFrame.y;
+        monitor.clientY = (int)(primaryFrame.height - (visibleFrame.y + visibleFrame.height));
         monitor.clientWidth = cast(int)visibleFrame.width;
         monitor.clientHeight = cast(int)visibleFrame.height;
         monitors [i] = monitor;
@@ -1333,6 +1424,11 @@
     return monitors;
 }
 
+NSRect getPrimaryFrame () {
+    NSArray screens = NSScreen.screens();
+    return new NSScreen(screens.objectAtIndex(0)).frame();
+}
+
 /**
  * Returns the primary monitor for that device.
  * 
@@ -1343,15 +1439,16 @@
 public dwt.widgets.Monitor.Monitor getPrimaryMonitor () {
     checkDevice ();
     dwt.widgets.Monitor.Monitor monitor = new dwt.widgets.Monitor.Monitor ();
-    NSScreen screen = NSScreen.mainScreen();
+    NSArray screens = NSScreen.screens();
+    NSScreen screen = new NSScreen(screens.objectAtIndex(0));
     NSRect frame = screen.frame();
     monitor.x = cast(int)frame.x;
-    monitor.y = cast(int)frame.y;
+    monitor.y = (int)(frame.height - (frame.y + frame.height));
     monitor.width = cast(int)frame.width;
     monitor.height = cast(int)frame.height;
     NSRect visibleFrame = screen.visibleFrame();
     monitor.clientX = cast(int)visibleFrame.x;
-    monitor.clientY = cast(int)visibleFrame.y;
+    monitor.clientY = (int)(frame.height - (visibleFrame.y + visibleFrame.height));
     monitor.clientWidth = cast(int)visibleFrame.width;
     monitor.clientHeight = cast(int)visibleFrame.height;
     return monitor;
@@ -1372,18 +1469,12 @@
     checkDevice ();
     NSArray windows = application.windows();
     int index = 0;
-    Shell [] result = new Shell [windows.count()];
+    Shell [] result = new Shell [(int)/*64*/windows.count()];
     for (int i = 0; i < result.length; i++) {
         NSWindow window = new NSWindow(windows.objectAtIndex(i));
-        NSView view = window.contentView();
-        if (view !is null) {
-            NSInteger jniRef = cast(NSInteger) OS.objc_msgSend(view.id_, OS.sel_tag);
-            if (jniRef !is 0 && jniRef !is -1) {
-                Object object = OS.JNIGetObject(jniRef);
-                if (cast(Shell) object) {
-                    result[index++] = cast(Shell)object;
-                }
-            }
+        Widget widget = getWidget(window.contentView());
+        if (widget instanceof Shell) {
+            result[index++] = (Shell)widget;
         }
     }
     if (index is result.length) return result;
@@ -1479,9 +1570,9 @@
     if (color is null) return super.getSystemColor(id);
     color = color.colorUsingColorSpace(NSColorSpace.deviceRGBColorSpace());
     if (color is null) return super.getSystemColor(id);
-    float[] components = new float[color.numberOfComponents()];
+    float /*double*/[] components = new float /*double*/[(int)/*64*/color.numberOfComponents()];
     color.getComponents(components);    
-    return Color.cocoa_new (this, [components[0], components[1], components[2], components[3]]);
+    return Color.cocoa_new (this, [cast(float)/*64*/ components[0], cast(float)/*64*/ components[1], cast(float)/*64*/ components[2], cast(float)/*64*/ components[3]]);
 }
 
 /**
@@ -1563,25 +1654,32 @@
  */
 public Image getSystemImage (int id) {
     checkDevice ();
-    int code;
     switch(id) {
-        case DWT.ICON_ERROR:
-            code = OS.kAlertStopIcon;
-            break;
+        case DWT.ICON_ERROR: {  
+            if (errorImage !is null) return errorImage;
+            NSImage nsImage = NSWorkspace.sharedWorkspace ().iconForFileType (new NSString (OS.NSFileTypeForHFSTypeCode (OS.kAlertStopIcon)));
+            if (nsImage is null) return null;
+            nsImage.retain ();
+            return errorImage = Image.cocoa_new (this, DWT.ICON, nsImage);
+        }
         case DWT.ICON_INFORMATION:
-        case DWT.ICON_WORKING:
         case DWT.ICON_QUESTION:
-            code = OS.kAlertNoteIcon;
-            break;
-        case DWT.ICON_WARNING:
-            code = OS.kAlertCautionIcon;
-            break;
-        default:
-            return null;
+        case DWT.ICON_WORKING: {
+            if (infoImage !is null) return infoImage;
+            NSImage nsImage = NSWorkspace.sharedWorkspace ().iconForFileType (new NSString (OS.NSFileTypeForHFSTypeCode (OS.kAlertNoteIcon)));
+            if (nsImage is null) return null;
+            nsImage.retain ();
+            return infoImage = Image.cocoa_new (this, DWT.ICON, nsImage);
+        }
+        case DWT.ICON_WARNING: {
+            if (warningImage !is null) return warningImage;
+            NSImage nsImage = NSWorkspace.sharedWorkspace ().iconForFileType (new NSString (OS.NSFileTypeForHFSTypeCode (OS.kAlertCautionIcon)));
+            if (nsImage is null) return null;
+            nsImage.retain ();
+            return warningImage = Image.cocoa_new (this, DWT.ICON, nsImage);
+        }
     }
-    NSImage nsImage = NSWorkspace.sharedWorkspace().iconForFileType(OS.NSFileTypeForHFSTypeCode(code));
-    if (nsImage is null) return null;
-    return Image.cocoa_new(this, DWT.ICON, nsImage);
+    return null;
 }
 
 /**
@@ -1618,6 +1716,29 @@
     }
 }
 
+int getToolTipTime () {
+    checkDevice ();
+    //TODO get OS value (NSTooltipManager?)
+    return 560;
+}
+
+Widget getWidget (int /*long*/ id) {
+    return GetWidget (id);
+}
+
+static Widget GetWidget (int /*long*/ id) {
+    if (id is 0) return null;
+    int /*long*/ [] jniRef = new int /*long*/ [1];
+    OS.object_getInstanceVariable(id, DWT_OBJECT, jniRef);
+    if (jniRef[0] is 0) return null;
+    return (Widget)OS.JNIGetObject(jniRef[0]);
+}
+
+Widget getWidget (NSView view) {
+    if (view is null) return null;
+    return getWidget(view.id);
+}
+
 /**
  * Initializes any internal resources needed by the
  * device.
@@ -1630,264 +1751,455 @@
 protected void init_ () {
     super.init_ ();
     initClasses ();
-    initApplicationDelegate();  
-    application.finishLaunching();
+    
+    if (!isEmbedded) {
+        initApplicationDelegate();  
+        application.finishLaunching();
+    }
+        
+    timerDelegate = (SWTWindowDelegate)new SWTWindowDelegate().alloc().init();
+    
+    NSTextView textView = cast(NSTextView)(new NSTextView()).alloc();
+    textView.initWithFrame (NSRect ());
+    markedAttributes = textView.markedTextAttributes ();
+    markedAttributes.retain ();
+    textView.release ();
 }
 
 void initApplicationDelegate() {
-    objc.IMP appProc3 = cast(objc.IMP) &applicationDelegateProc;
-
     String className = "SWTApplicationDelegate";
-    objc.Class cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSObject, className, 0);
-    OS.class_addMethod(cls, OS.sel_applicationWillFinishLaunching_1, appProc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_terminate_1, appProc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_orderFrontStandardAboutPanel_1, appProc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_hideOtherApplications_1, appProc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_hide_1, appProc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_unhideAllApplications_1, appProc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_applicationShouldTerminate_1, appProc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_applicationWillTerminate_1, appProc3, "@:@");
-    OS.objc_registerClassPair(cls);
-    
+    if (OS.objc_lookUpClass (className) is null) {
+        Class clazz = getClass ();
+        applicationDelegateCallback3 = new Callback(clazz, "applicationDelegateProc", 3);
+        int /*long*/ appProc3 = applicationDelegateCallback3.getAddress();
+        if (appProc3 is 0) error (DWT.ERROR_NO_MORE_CALLBACKS);
+        int /*long*/ cls = OS.objc_allocateClassPair(OS.class_NSObject, className, 0);
+        OS.class_addMethod(cls, OS.sel_applicationWillFinishLaunching_, appProc3, "@:@");
+        OS.class_addMethod(cls, OS.sel_terminate_, appProc3, "@:@");
+        OS.class_addMethod(cls, OS.sel_orderFrontStandardAboutPanel_, appProc3, "@:@");
+        OS.class_addMethod(cls, OS.sel_hideOtherApplications_, appProc3, "@:@");
+        OS.class_addMethod(cls, OS.sel_hide_, appProc3, "@:@");
+        OS.class_addMethod(cls, OS.sel_unhideAllApplications_, appProc3, "@:@");
+        OS.class_addMethod(cls, OS.sel_applicationShouldTerminate_, appProc3, "@:@");
+        OS.class_addMethod(cls, OS.sel_applicationWillTerminate_, appProc3, "@:@");
+        OS.class_addMethod(cls, OS.sel_applicationWillResignActive_, appProc3, "@:@");
+        OS.objc_registerClassPair(cls);
+    }   
     applicationDelegate = cast(SWTApplicationDelegate)(new SWTApplicationDelegate()).alloc().init();    
     application.setDelegate(applicationDelegate);
 }
 
+void addEventMethods (int /*long*/ cls, int /*long*/ proc2, int /*long*/ proc3, int /*long*/ drawRectProc) {
+    OS.class_addMethod(cls, OS.sel_mouseDown_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_mouseUp_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_scrollWheel_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_rightMouseDown_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_rightMouseUp_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_otherMouseDown_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_otherMouseUp_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_mouseDragged_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_mouseMoved_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_mouseEntered_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_mouseExited_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_menuForEvent_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_resignFirstResponder, proc2, "@:");
+    OS.class_addMethod(cls, OS.sel_becomeFirstResponder, proc2, "@:");
+    OS.class_addMethod(cls, OS.sel_keyDown_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_keyUp_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_flagsChanged_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_drawRect_, drawRectProc, "@:{NSRect}");
+}
+
+void addFrameMethods(int /*long*/ cls, int /*long*/ setFrameOriginProc, int /*long*/ setFrameSizeProc) {
+    OS.class_addMethod(cls, OS.sel_setFrameOrigin_, setFrameOriginProc, "@:{NSPoint}"); 
+    OS.class_addMethod(cls, OS.sel_setFrameSize_, setFrameSizeProc, "@:{NSSize}");  
+}
+
+void addAccessibilityMethods(int /*long*/ cls, int /*long*/ proc2, int /*long*/ proc3, int /*long*/ proc4, int /*long*/ accessibilityHitTestProc) {
+    OS.class_addMethod(cls, OS.sel_accessibilityActionNames, proc2, "@:");
+    OS.class_addMethod(cls, OS.sel_accessibilityAttributeNames, proc2, "@:");
+    OS.class_addMethod(cls, OS.sel_accessibilityParameterizedAttributeNames, proc2, "@:");
+    OS.class_addMethod(cls, OS.sel_accessibilityFocusedUIElement, proc2, "@:");
+    OS.class_addMethod(cls, OS.sel_accessibilityIsIgnored, proc2, "@:");
+    OS.class_addMethod(cls, OS.sel_accessibilityAttributeValue_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_accessibilityIsAttributeSettable_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_accessibilityHitTest_, accessibilityHitTestProc, "@:{NSPoint}");
+    OS.class_addMethod(cls, OS.sel_accessibilityAttributeValue_forParameter_, proc4, "@:@@");   
+    OS.class_addMethod(cls, OS.sel_accessibilityPerformAction_, proc3, "@:@");  
+    OS.class_addMethod(cls, OS.sel_accessibilityActionDescription_, proc3, "@:@");  
+}
+
+int registerCellSubclass(int cellClass, int size, int align, String types) {
+    String cellClassName = OS.class_getName(cellClass);
+    int cls = OS.objc_allocateClassPair(cellClass, "DWT" + cellClassName, 0);   
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    OS.objc_registerClassPair(cls);
+    return cls;
+}
+
 void initClasses () {
-    objc.IMP dialogProc3 = cast(objc.IMP) &dialogProc;
+    if (OS.objc_lookUpClass ("SWTView") !is null) return;
     
-    objc.IMP proc3 = cast(objc.IMP) &windowDelegateProc3;
-    objc.IMP proc2 = cast(objc.IMP) &windowDelegateProc2;
-    objc.IMP proc4 = cast(objc.IMP) &windowDelegateProc4;
-    objc.IMP proc5 = cast(objc.IMP) &windowDelegateProc5;
-    objc.IMP proc6 = cast(objc.IMP) &windowDelegateProc6;
+    Class clazz = getClass ();
+    dialogCallback3 = new Callback(clazz, "dialogProc", 3);
+    int /*long*/ dialogProc3 = dialogCallback3.getAddress();
+    if (dialogProc3 is 0) error (DWT.ERROR_NO_MORE_CALLBACKS);  
+    windowDelegateCallback3 = new Callback(clazz, "windowDelegateProc", 3);
+    int /*long*/ proc3 = windowDelegateCallback3.getAddress();
+
+    objc.IMP drawRectProc = OS.drawRect_CALLBACK(proc3);
+    int /*long*/ drawInteriorWithFrameInViewProc = OS.drawInteriorWithFrame_inView_CALLBACK (proc4);
+    int /*long*/ setFrameOriginProc = OS.setFrameOrigin_CALLBACK(proc3);
+    int /*long*/ setFrameSizeProc = OS.setFrameSize_CALLBACK(proc3);
+    int /*long*/ hitTestProc = OS.hitTest_CALLBACK(proc3);
+    int /*long*/ markedRangeProc = OS.markedRange_CALLBACK(proc2);
+    int /*long*/ selectedRangeProc = OS.selectedRange_CALLBACK(proc2);
+    int /*long*/ highlightSelectionInClipRectProc = OS.highlightSelectionInClipRect_CALLBACK(proc3);
+    int /*long*/ setMarkedText_selectedRangeProc = OS.setMarkedText_selectedRange_CALLBACK(proc4);
+    int /*long*/ attributedSubstringFromRangeProc = OS.attributedSubstringFromRange_CALLBACK(proc3);
+    int /*long*/ characterIndexForPointProc = OS.characterIndexForPoint_CALLBACK(proc3);
+    int /*long*/ firstRectForCharacterRangeProc = OS.firstRectForCharacterRange_CALLBACK(proc3);    
+    int /*long*/ textWillChangeSelectionProc = OS.textView_willChangeSelectionFromCharacterRange_toCharacterRange_CALLBACK(proc5);
+    int /*long*/ accessibilityHitTestProc = OS.accessibilityHitTest_CALLBACK(proc3);
     
-    objc.IMP drawRectProc = OS.drawRect_CALLBACK(proc3);
+    String types = "*";
+    int size = C.PTR_SIZEOF, align = C.PTR_SIZEOF is 4 ? 2 : 3;
 
     String className = "SWTWindowDelegate";
-    objc.Class cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSObject, className, 0);
-    
-    static if ((void*).sizeof > int.sizeof) // 64bit target
-        OS.class_addIvar(cls, "dObject", OS.PTR_SIZEOF, cast(byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "q");
-    else
-        OS.class_addIvar(cls, "dObject", OS.PTR_SIZEOF, cast(byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
-    
-    OS.class_addMethod(cls, OS.sel_windowDidResize_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_windowShouldClose_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_windowWillClose_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_windowWillClose_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_windowDidResignKey_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_windowDidBecomeKey_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_tag, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_setTag_1, proc3, "@:i");
-    OS.class_addMethod(cls, OS.sel_timerProc_1, proc3, "@:@");
+    int /*long*/ cls = OS.objc_allocateClassPair(OS.class_NSObject, className, 0);
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    OS.class_addMethod(cls, OS.sel_windowDidResize_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_windowDidMove_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_windowShouldClose_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_windowWillClose_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_windowDidResignKey_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_windowDidBecomeKey_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_timerProc_, proc3, "@:@");
     OS.objc_registerClassPair(cls);
     
     className = "SWTPanelDelegate";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSObject, className, 0);
-    OS.class_addIvar(cls, "tag", OS.PTR_SIZEOF, cast(byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
-    OS.class_addMethod(cls, OS.sel_windowWillClose_1, dialogProc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_changeColor_1, dialogProc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_changeFont_1, dialogProc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_tag, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_setTag_1, proc3, "@:i");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    OS.class_addMethod(cls, OS.sel_windowWillClose_, dialogProc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_changeColor_, dialogProc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_changeFont_, dialogProc3, "@:@");
     OS.objc_registerClassPair(cls);
     
     className = "SWTMenu";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSMenu, className, 0);
-    OS.class_addIvar(cls, "tag", OS.PTR_SIZEOF, cast(byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
-    OS.class_addMethod(cls, OS.sel_tag, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_setTag_1, proc3, "@:i");
-//  OS.class_addMethod(cls, OS.sel_menuWillOpen_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_menuWillClose_1, proc3, "@:@");
-//  OS.class_addMethod(cls, OS.sel_numberOfItemsInMenu_1, proc3, "@:@");    
-    OS.class_addMethod(cls, OS.sel_menu_1willHighlightItem_1, proc4, "@:@@");
-    OS.class_addMethod(cls, OS.sel_menuNeedsUpdate_1, proc3, "@:@");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    OS.class_addMethod(cls, OS.sel_menuWillOpen_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_menuDidClose_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_menu_willHighlightItem_, proc4, "@:@@");
+    OS.class_addMethod(cls, OS.sel_menuNeedsUpdate_, proc3, "@:@");
     OS.objc_registerClassPair(cls);
 
     className = "SWTView";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSView, className, 0);
-    OS.class_addIvar(cls, "tag", OS.PTR_SIZEOF, cast(byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
-    OS.class_addMethod(cls, OS.sel_tag, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_setTag_1, proc3, "@:i");
+    OS.class_addProtocol(cls, OS.objc_getProtocol("NSTextInput"));
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
     OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_drawRect_1, drawRectProc, "@:i");
-    OS.class_addMethod(cls, OS.sel_mouseDown_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_mouseDragged_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_mouseEntered_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_mouseUp_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
     OS.class_addMethod(cls, OS.sel_acceptsFirstResponder, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_resignFirstResponder, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_becomeFirstResponder, proc2, "@:");
+    OS.class_addMethod(cls, OS.sel_isOpaque, proc2, "@:");
+    OS.class_addMethod(cls, OS.sel_hitTest_, hitTestProc, "@:{NSPoint}");
+    
+    //NSTextInput protocol
+    OS.class_addMethod(cls, OS.sel_hasMarkedText, proc2, "@:");
+    OS.class_addMethod(cls, OS.sel_markedRange, markedRangeProc, "@:");
+    OS.class_addMethod(cls, OS.sel_selectedRange, selectedRangeProc, "@:");
+    OS.class_addMethod(cls, OS.sel_setMarkedText_selectedRange_, setMarkedText_selectedRangeProc, "@:@{NSRange}");
+    OS.class_addMethod(cls, OS.sel_unmarkText, proc2, "@:");
+    OS.class_addMethod(cls, OS.sel_validAttributesForMarkedText, proc2, "@:");
+    OS.class_addMethod(cls, OS.sel_attributedSubstringFromRange_, attributedSubstringFromRangeProc, "@:{NSRange}");
+    OS.class_addMethod(cls, OS.sel_insertText_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_characterIndexForPoint_, characterIndexForPointProc, "@:{NSPoint}");
+    OS.class_addMethod(cls, OS.sel_firstRectForCharacterRange_, firstRectForCharacterRangeProc, "@:{NSRange}");
+    OS.class_addMethod(cls, OS.sel_doCommandBySelector_, proc3, "@::");
+    
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
     
     className = "SWTScrollView";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSScrollView, className, 0);
-    OS.class_addIvar(cls, "tag", OS.PTR_SIZEOF, cast(byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
-    OS.class_addMethod(cls, OS.sel_tag, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_setTag_1, proc3, "@:i");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
     OS.class_addMethod(cls, OS.sel_sendVerticalSelection, proc2, "@:");
     OS.class_addMethod(cls, OS.sel_sendHorizontalSelection, proc2, "@:");
-//  OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_pageDown_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_pageUp_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_reflectScrolledClipView_, proc3, "@:@");
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
     
     className = "SWTButton";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSButton, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
-//  OS.class_addMethod(cls, OS.sel_mouseDown_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_drawRect_1, drawRectProc, "@:i");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
     OS.class_addMethod(cls, OS.sel_sendSelection, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_sendArrowSelection, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
     
+    cls = registerCellSubclass(NSButton.cellClass(), size, align, types);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);    
+    NSButton.setCellClass(cls);
+
     className = "SWTTableView";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSTableView, className, 0);
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    OS.class_addMethod(cls, OS.sel_highlightSelectionInClipRect_, highlightSelectionInClipRectProc, "@:{NSRect}");
     OS.class_addMethod(cls, OS.sel_sendDoubleSelection, proc2, "@:");
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_numberOfRowsInTableView_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_tableView_1objectValueForTableColumn_1row_1, proc5, "@:@:@:@");
-    OS.class_addMethod(cls, OS.sel_tableView_1shouldEditTableColumn_1row_1, proc5, "@:@:@:@");
-    OS.class_addMethod(cls, OS.sel_tableViewSelectionDidChange_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_tableView_1willDisplayCell_1forTableColumn_1row_1, proc6, "@:@@@i");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_tableView_1setObjectValue_1forTableColumn_1row_1, proc6, "@:@@@i");
+    OS.class_addMethod(cls, OS.sel_numberOfRowsInTableView_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_tableView_objectValueForTableColumn_row_, proc5, "@:@:@:@");
+    OS.class_addMethod(cls, OS.sel_tableView_shouldEditTableColumn_row_, proc5, "@:@:@:@");
+    OS.class_addMethod(cls, OS.sel_tableViewSelectionDidChange_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_tableView_willDisplayCell_forTableColumn_row_, proc6, "@:@@@i");
+    OS.class_addMethod(cls, OS.sel_tableView_setObjectValue_forTableColumn_row_, proc6, "@:@@@i");
+    OS.class_addMethod(cls, OS.sel_tableViewColumnDidMove_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_tableViewColumnDidResize_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_tableView_didClickTableColumn_, proc4, "@:@");
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
-    
+
+    className = "SWTTableHeaderCell";
+    cls = OS.objc_allocateClassPair (OS.class_NSTableHeaderCell, className, 0);
+    OS.class_addIvar (cls, DWT_OBJECT, size, (byte)align, types);
+    OS.class_addMethod (cls, OS.sel_drawInteriorWithFrame_inView_, drawInteriorWithFrameInViewProc, "@:{NSRect}@");
+    OS.objc_registerClassPair (cls);
+
+    className = "SWTBrowserCell";
+    cls = OS.objc_allocateClassPair (OS.class_NSBrowserCell, className, 0);
+    OS.class_addIvar (cls, DWT_OBJECT, size, (byte)align, types);
+    OS.class_addMethod (cls, OS.sel_drawInteriorWithFrame_inView_, drawInteriorWithFrameInViewProc, "@:{NSRect}@");
+    OS.objc_registerClassPair (cls);
+
+    className = "SWTTableHeaderView";
+    cls = OS.objc_allocateClassPair(OS.class_NSTableHeaderView, className, 0);
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    OS.class_addMethod(cls, OS.sel_mouseDown_, proc3, "@:@");
+    OS.objc_registerClassPair(cls);
+
     className = "SWTOutlineView";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSOutlineView, className, 0);
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    OS.class_addMethod(cls, OS.sel_highlightSelectionInClipRect_, highlightSelectionInClipRectProc, "@:{NSRect}");
     OS.class_addMethod(cls, OS.sel_sendDoubleSelection, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_outlineViewSelectionDidChange_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_outlineView_1shouldCollapseItem_1, proc4, "@:@@");
-    OS.class_addMethod(cls, OS.sel_outlineView_1shouldExpandItem_1, proc4, "@:@@");
-    OS.class_addMethod(cls, OS.sel_outlineView_1child_1ofItem_1, proc5, "@:@i@");
-    OS.class_addMethod(cls, OS.sel_outlineView_1isItemExpandable_1, proc4, "@:@@");
-    OS.class_addMethod(cls, OS.sel_outlineView_1numberOfChildrenOfItem_1, proc4, "@:@@");
-    OS.class_addMethod(cls, OS.sel_outlineView_1objectValueForTableColumn_1byItem_1, proc5, "@:@@@");
-    OS.class_addMethod(cls, OS.sel_outlineView_1willDisplayCell_1forTableColumn_1item_1, proc6, "@:@@@@");
-    OS.class_addMethod(cls, OS.sel_outlineView_1setObjectValue_1forTableColumn_1byItem_1, proc6, "@:@@@@");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_outlineViewSelectionDidChange_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_outlineViewItemDidExpand_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_outlineView_shouldCollapseItem_, proc4, "@:@@");
+    OS.class_addMethod(cls, OS.sel_outlineView_shouldExpandItem_, proc4, "@:@@");
+    OS.class_addMethod(cls, OS.sel_outlineView_child_ofItem_, proc5, "@:@i@");
+    OS.class_addMethod(cls, OS.sel_outlineView_isItemExpandable_, proc4, "@:@@");
+    OS.class_addMethod(cls, OS.sel_outlineView_numberOfChildrenOfItem_, proc4, "@:@@");
+    OS.class_addMethod(cls, OS.sel_outlineView_objectValueForTableColumn_byItem_, proc5, "@:@@@");
+    OS.class_addMethod(cls, OS.sel_outlineView_willDisplayCell_forTableColumn_item_, proc6, "@:@@@@");
+    OS.class_addMethod(cls, OS.sel_outlineView_setObjectValue_forTableColumn_byItem_, proc6, "@:@@@@");
+    OS.class_addMethod(cls, OS.sel_outlineViewColumnDidMove_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_outlineViewColumnDidResize_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_outlineView_didClickTableColumn_, proc4, "@:@");
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
 
     className = "SWTTreeItem";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSObject, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
-    OS.class_addIvar(cls, "tag", OS.PTR_SIZEOF, cast(byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
-    OS.class_addMethod(cls, OS.sel_tag, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_setTag_1, proc3, "@:i");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
     OS.objc_registerClassPair(cls);
 
     className = "SWTTabView";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSTabView, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
-    OS.class_addIvar(cls, "tag", OS.PTR_SIZEOF, cast(byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
-    OS.class_addMethod(cls, OS.sel_tabView_1willSelectTabViewItem_1, proc4, "@:@@");
-    OS.class_addMethod(cls, OS.sel_tag, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_setTag_1, proc3, "@:i");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    OS.class_addMethod(cls, OS.sel_tabView_willSelectTabViewItem_, proc4, "@:@@");
+    OS.class_addMethod(cls, OS.sel_tabView_didSelectTabViewItem_, proc4, "@:@@");
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
     
     className = "SWTBox";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSBox, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
-    OS.class_addIvar(cls, "tag", OS.PTR_SIZEOF, cast(byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
-    OS.class_addMethod(cls, OS.sel_tag, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_setTag_1, proc3, "@:i");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
     
     className = "SWTProgressIndicator";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSProgressIndicator, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
-    OS.class_addIvar(cls, "tag", OS.PTR_SIZEOF, cast(byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
-    OS.class_addMethod(cls, OS.sel_tag, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_setTag_1, proc3, "@:i");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls); 
 
     className = "SWTSlider";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSSlider, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls); 
     
+    cls = registerCellSubclass(NSSlider.cellClass(), size, align, types);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);    
+    NSSlider.setCellClass(cls);
+
     className = "SWTPopUpButton";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSPopUpButton, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
     OS.class_addMethod(cls, OS.sel_sendSelection, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
     
+    cls = registerCellSubclass(NSPopUpButton.cellClass(), size, align, types);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);    
+    NSPopUpButton.setCellClass(cls);
+
     className = "SWTComboBox";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSComboBox, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_comboBoxSelectionDidChange_1, proc3, "@:@");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    OS.class_addMethod(cls, OS.sel_comboBoxSelectionDidChange_, proc3, "@:@");
     OS.class_addMethod(cls, OS.sel_sendSelection, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_textDidChange_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_textViewDidChangeSelection_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_textView_willChangeSelectionFromCharacterRange_toCharacterRange_, textWillChangeSelectionProc, "@:@{NSRange}{NSRange}");
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
     
+    cls = registerCellSubclass(NSComboBox.cellClass(), size, align, types);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);    
+    NSComboBox.setCellClass(cls);
+
     className = "SWTDatePicker";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSDatePicker, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
     OS.class_addMethod(cls, OS.sel_sendSelection, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
 
     className = "SWTImageView";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSImageView, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_drawRect_1, OS.drawRect_CALLBACK(proc3), "@:i");
-    OS.class_addMethod(cls, OS.sel_mouseDown_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_mouseUp_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_rightMouseDown_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
 
+    cls = registerCellSubclass(NSImageView.cellClass(), size, align, types);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);    
+    NSImageView.setCellClass(cls);
+
     className = "SWTStepper";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSStepper, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
     OS.class_addMethod(cls, OS.sel_sendSelection, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
 
+    cls = registerCellSubclass(NSStepper.cellClass(), size, align, types);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);    
+    NSStepper.setCellClass(cls);
+
     className = "SWTScroller";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSScroller, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
     OS.class_addMethod(cls, OS.sel_sendSelection, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
-
+    
     className = "SWTMenuItem";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSMenuItem, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
     OS.class_addMethod(cls, OS.sel_sendSelection, proc2, "@:");
     OS.objc_registerClassPair(cls);
 
     className = "SWTTextView";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSTextView, className, 0);
-//  OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
-//  OS.class_addMethod(cls, OS.sel_sendSelection, proc2, "@:");
-    OS.class_addIvar(cls, "tag", OS.PTR_SIZEOF, cast(byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
-    OS.class_addMethod(cls, OS.sel_tag, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_setTag_1, proc3, "@:i");
-    OS.class_addMethod(cls, OS.sel_menuForEvent_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_textView_1clickedOnLink_1atIndex_1, proc5, "@:@@i");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
+    OS.class_addMethod(cls, OS.sel_insertText_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_doCommandBySelector_, proc3, "@::");
+    OS.class_addMethod(cls, OS.sel_textDidChange_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_textView_clickedOnLink_atIndex_, proc5, "@:@@@");
+    OS.objc_registerClassPair(cls);
+    
+    className = "SWTEditorView";
+    cls = OS.objc_allocateClassPair(OS.class_NSTextView, className, 0);
+    OS.class_addMethod(cls, OS.sel_keyDown_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_keyUp_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_insertText_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_doCommandBySelector_, proc3, "@::");
     OS.objc_registerClassPair(cls);
     
     className = "SWTTextField";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSTextField, className, 0);
-    OS.class_addMethod(cls, OS.sel_drawRect_1, drawRectProc, "@:i");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
+    OS.class_addMethod(cls, OS.sel_textDidChange_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_textViewDidChangeSelection_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_textView_willChangeSelectionFromCharacterRange_toCharacterRange_, textWillChangeSelectionProc, "@:@{NSRange}{NSRange}");
+    OS.objc_registerClassPair(cls);
+    
+    cls = registerCellSubclass(NSTextField.cellClass(), size, align, types);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);    
+    NSTextField.setCellClass(cls);
+
+    className = "SWTSearchField";
+    cls = OS.objc_allocateClassPair(OS.class_NSSearchField, className, 0);
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
+    OS.class_addMethod(cls, OS.sel_textDidChange_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_textViewDidChangeSelection_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_textView_willChangeSelectionFromCharacterRange_toCharacterRange_, textWillChangeSelectionProc, "@:@{NSRange}{NSRange}");
+    OS.objc_registerClassPair(cls);
+    
+    cls = registerCellSubclass(NSSearchField.cellClass(), size, align, types);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);    
+    NSSearchField.setCellClass(cls);
+
+    className = "SWTSecureTextField";
+    cls = OS.objc_allocateClassPair(OS.class_NSSecureTextField, className, 0);
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    addEventMethods(cls, proc2, proc3, drawRectProc);
+    addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
+    OS.class_addMethod(cls, OS.sel_textDidChange_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_textViewDidChangeSelection_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_textView_willChangeSelectionFromCharacterRange_toCharacterRange_, textWillChangeSelectionProc, "@:@{NSRange}{NSRange}");
     OS.objc_registerClassPair(cls);
 
+    // Don't subclass NSSecureTextFieldCell -- you'll get an NSException from [NSSecureTextField setCellClass:]!
+    
     className = "SWTWindow";
     cls = OS.objc_allocateClassPair(cast(objc.Class) OS.class_NSWindow, className, 0);
-    OS.class_addIvar(cls, "tag", OS.PTR_SIZEOF, cast(byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
-    OS.class_addMethod(cls, OS.sel_tag, proc2, "@:");
-    OS.class_addMethod(cls, OS.sel_setTag_1, proc3, "@:i");
-    OS.class_addMethod(cls, OS.sel_sendEvent_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_flagsChanged_1, proc3, "@:@");
-    OS.class_addMethod(cls, OS.sel_helpRequested_1, proc3, "@:@");
+    OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
+    OS.class_addMethod(cls, OS.sel_sendEvent_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_helpRequested_, proc3, "@:@");
+    OS.class_addMethod(cls, OS.sel_canBecomeKeyWindow, proc2, "@:");
+    OS.class_addMethod(cls, OS.sel_makeFirstResponder_, proc3, "@:@");
+    addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
     OS.objc_registerClassPair(cls);
 }
 
@@ -1913,7 +2225,14 @@
  */
 public objc.id internal_new_GC (GCData data) {
     if (isDisposed()) DWT.error(DWT.ERROR_DEVICE_DISPOSED);
-    NSGraphicsContext context = application.context();
+    if (screenWindow is null) {
+        NSWindow window = (NSWindow) new NSWindow ().alloc ();
+        NSRect rect = new NSRect();
+        window = window.initWithContentRect(rect, OS.NSBorderlessWindowMask, OS.NSBackingStoreBuffered, false);
+        window.setReleasedWhenClosed(false);
+        screenWindow = window;
+    }
+    NSGraphicsContext context = screenWindow.graphicsContext();
 //  NSAffineTransform transform = NSAffineTransform.transform();
 //  NSSize size = handle.size();
 //  transform.translateXBy(0, size.height);
@@ -1945,7 +2264,7 @@
  * @param hDC the platform specific GC handle
  * @param data the platform specific GC data 
  */
-public override void internal_dispose_GC (objc.id context, GCData data) {
+public void internal_dispose_GC (objc.id context, GCData data) {
     if (isDisposed()) DWT.error(DWT.ERROR_DEVICE_DISPOSED);
     
 }
@@ -2245,15 +2564,18 @@
     if (toWindow !is null && fromWindow !is null && toWindow.id_ is fromWindow.id_) {
         pt = from.view.convertPoint_toView_(pt, to.view);
     } else {
+        NSRect primaryFrame = getPrimaryFrame();
         if (from !is null) {
-            pt = from.view.convertPoint_toView_(pt, null);
+            NSView view = from.contentView ();
+            pt = view.convertPoint_toView_(pt, null);
             pt = fromWindow.convertBaseToScreen(pt);
-            pt.y = fromWindow.screen().frame().height - pt.y;
+            pt.y = primaryFrame.height - pt.y;
         }
         if (to !is null) {
-            pt.y = toWindow.screen().frame().height - pt.y;
+            NSView view = to.contentView ();
+            pt.y = primaryFrame.height - pt.y;
             pt = toWindow.convertScreenToBase(pt);
-            pt = to.view.convertPoint_fromView_(pt, null);
+            pt = view.convertPoint_fromView_(pt, null);
         }
     }
     point.x = cast(int)pt.x;
@@ -2355,15 +2677,18 @@
     if (toWindow !is null && fromWindow !is null && toWindow.id_ is fromWindow.id_) {
         pt = from.view.convertPoint_toView_(pt, to.view);
     } else {
+        NSRect primaryFrame = getPrimaryFrame();
         if (from !is null) {
-            pt = from.view.convertPoint_toView_(pt, null);
+            NSView view = from.contentView ();
+            pt = view.convertPoint_toView_(pt, null);
             pt = fromWindow.convertBaseToScreen(pt);
-            pt.y = fromWindow.screen().frame().height - pt.y;
+            pt.y = primaryFrame.height - pt.y;
         }
         if (to !is null) {
-            pt.y = toWindow.screen().frame().height - pt.y;
+            NSView view = to.contentView ();
+            pt.y = primaryFrame.height - pt.y;
             pt = toWindow.convertScreenToBase(pt);
-            pt = to.view.convertPoint_fromView_(pt, null);
+            pt = view.convertPoint_fromView_(pt, null);
         }
     }
     rectangle.x = cast(int)pt.x;
@@ -2397,23 +2722,36 @@
  */
 public bool readAndDispatch () {
     checkDevice ();
-    NSAutoreleasePool pool = cast(NSAutoreleasePool)(new NSAutoreleasePool()).alloc().init();
+    if (loopCounter is 0) {
+        pool.release();
+        pool = (NSAutoreleasePool)new NSAutoreleasePool().alloc().init();
+    }
+    loopCounter ++;
+    bool events = false;
+    events |= runTimers ();
+    events |= runContexts ();
+    events |= runPopups ();
+    NSEvent event = application.nextEventMatchingMask(0, null, OS.NSDefaultRunLoopMode, true);
+    
     try {
-        bool events = false;
-        events |= runTimers ();
-        NSEvent event = application.nextEventMatchingMask(0, null, OS.NSDefaultRunLoopMode, true);
-        if (event !is null) {
-            events = true;
-            application.sendEvent(event);
-        }
+    if (event !is null) {
+        events = true;
+        application.sendEvent(event);
+    }
+//      NSEvent event = NSEvent.otherEventWithType(OS.NSApplicationDefined, new NSPoint(), 0, 0, 0, null, DWT_IDLE_TYPE, 0, 0);
+//      application.postEvent(event, false);
+//      idle = true;
+//      application.run();
+//      events |= !idle;
         if (events) {
             runDeferredEvents ();
             return true;
         }
         return runAsyncMessages (false);
     } finally {
-        pool.release();
+        loopCounter --;
     }
+    
 }
 
 static void register (Display display) {
@@ -2465,7 +2803,7 @@
     }
     if (tray !is null) tray.dispose ();
     tray = null;
-//  while (readAndDispatch ()) {}
+    while (readAndDispatch ()) {}
     if (disposeList !is null) {
         for (int i=0; i<disposeList.length; i++) {
             if (disposeList [i] !is null) disposeList [i].run ();
@@ -2485,26 +2823,69 @@
     if (warningImage !is null) warningImage.dispose ();
     errorImage = infoImage = warningImage = null;
     
-    //TODO - stop caret
     currentCaret = null;
     
     /* Release Timers */
+    if (hoverTimer !is null) timerExec(-1, hoverTimer);
+    hoverTimer = null;
+    if (caretTimer !is null) timerExec(-1, caretTimer);
+    caretTimer = null;
     if (nsTimers !is null) {
         for (int i=0; i<nsTimers.length; i++) {
-            //TODO - check -1 as sentinal
-            if (nsTimers [i] !is null /*&& timerIds [i] !is -1*/) {
+            if (nsTimers [i] !is null) {
                 nsTimers [i].invalidate();
                 nsTimers [i].release();
             }
         }
     }
     nsTimers = null;
+    if (timerDelegate !is null) timerDelegate.release();
+    timerDelegate = null;
     
     /* Release the System Cursors */
     for (int i = 0; i < cursors.length; i++) {
         if (cursors [i] !is null) cursors [i].dispose ();
     }
     cursors = null;
+    
+    /* Release Dock image */
+    if (dockImage !is null) dockImage.release();
+    dockImage = null;
+
+    if (screenWindow !is null) screenWindow.release();
+    screenWindow = null;
+    
+    modalShells = null;
+    menuBar = null;
+    menus = null;
+    
+    if (markedAttributes !is null) markedAttributes.release();
+    markedAttributes = null;
+
+    /* The release pool needs to be released before the call backs. */
+    if (pool !is null) pool.release();
+    pool = null;
+
+    if (application !is null && applicationClass !is 0) {
+        OS.object_setClass (application.id, applicationClass);
+    }
+    application = null;
+    applicationClass = 0;
+}
+
+void removeContext (NSGraphicsContext context) {
+    if (contexts is null) return;
+    int count = 0;
+    for (int i = 0; i < contexts.length; i++) {
+        if (contexts[i] !is null) {
+            if (contexts [i].id is context.id) {
+                contexts[i] = null;
+            } else {
+                count++;
+            }
+        }
+    }
+    if (count is 0) contexts = null;
 }
 
 /**
@@ -2544,7 +2925,7 @@
  * is one of the event constants defined in class <code>DWT</code>.
  *
  * @param eventType the type of event to listen for
- * @param listener the listener which should no longer be notified when the event occurs
+ * @param listener the listener which should no longer be notified
  *
  * @exception IllegalArgumentException <ul>
  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
@@ -2567,25 +2948,49 @@
     eventTable.unhook (eventType, listener);
 }
 
-//void removeMenu (Menu menu) {
-//  if (menus is null) return;
-//  menus [menu.id - ID_START] = null;
-//}
-//
-//void removePopup (Menu menu) {
-//  if (popups is null) return;
-//  for (int i=0; i<popups.length; i++) {
-//      if (popups [i] is menu) {
-//          popups [i] = null;
-//          return;
-//      }
-//  }
-//}
+Widget removeWidget (NSObject view) {
+    if (view is null) return null;
+    int /*long*/ [] jniRef = new int /*long*/ [1];
+    OS.object_getInstanceVariable(view.id, DWT_OBJECT, jniRef);
+    if (jniRef[0] is 0) return null;
+    Widget widget = (Widget)OS.JNIGetObject(jniRef[0]);
+    OS.object_setInstanceVariable(view.id, DWT_OBJECT, 0);
+    return widget;
+}
+
+void removeMenu (Menu menu) {
+    if (menus is null) return;
+    for (int i = 0; i < menus.length; i++) {
+        if (menus [i] is menu) {
+            menus[i] = null;
+            break;
+        }
+    }
+}
+
+void removePopup (Menu menu) {
+    if (popups is null) return;
+    for (int i=0; i<popups.length; i++) {
+        if (popups [i] is menu) {
+            popups [i] = null;
+            return;
+        }
+    }
+}
 
 bool runAsyncMessages (bool all) {
     return synchronizer.runAsyncMessages (all);
 }
 
+bool runContexts () {
+    if (contexts !is null) {
+        for (int i = 0; i < contexts.length; i++) {
+            if (contexts[i] !is null) contexts[i].flushGraphics();
+        }
+    }
+    return false;
+}
+
 bool runDeferredEvents () {
     /*
     * Run deferred events.  This code is always
@@ -2622,6 +3027,25 @@
     return true;
 }
 
+bool runPopups () {
+    if (popups is null) return false;
+    bool result = false;
+    while (popups !is null) {
+        Menu menu = popups [0];
+        if (menu is null) break;
+        int length = popups.length;
+        System.arraycopy (popups, 1, popups, 0, --length);
+        popups [length] = null;
+//      clearMenuFlags ();
+        runDeferredEvents ();
+        if (!menu.isDisposed ()) menu._setVisible (true);
+//      clearMenuFlags ();
+        result = true;
+    }
+    popups = null;
+    return result;
+}
+
 bool runTimers () {
     if (timerList is null) return false;
     bool result = false;
@@ -2663,6 +3087,14 @@
     APP_NAME = name;
 }
 
+//TODO use custom timer instead of timerExec
+Runnable hoverTimer = new Runnable () {
+    public void run () {
+        if (currentControl !is null && !currentControl.isDisposed()) {
+            currentControl.sendMouseEvent (null, DWT.MouseHover, trackingControl !is null);
+        }
+    }
+};
 //TODO - use custom timer instead of timerExec
 Runnable caretTimer;
     
@@ -2676,6 +3108,13 @@
     }
 }
 
+void setCursor (Control control) {
+    Cursor cursor = null;
+    if (control !is null) cursor = control.findCursor ();
+    if (cursor is null) cursor = getSystemCursor (DWT.CURSOR_ARROW);
+    cursor.handle.set ();
+}
+
 /**
  * Sets the location of the on-screen pointer relative to the top left corner
  * of the screen.  <b>Note: It is typically considered bad practice for a
@@ -2748,6 +3187,17 @@
     checkDevice ();
     //if (key is null) error (DWT.ERROR_NULL_ARGUMENT);
     
+    if (key.equals (ADD_WIDGET_KEY)) {
+        Object [] data = (Object [])value;
+        NSObject object = (NSObject)data [0];
+        Widget widget = (Widget)data [1];
+        if (widget is null) {
+            removeWidget (object);
+        } else {
+            addWidget (object, widget);
+        }
+    }
+    
     /* Remove the key/value pair */
     if (value is null) {
         if (keys is null) return;
@@ -2793,13 +3243,6 @@
 }
 
 void setMenuBar (Menu menu) {
-    /*
-    * Feature in the Macintosh.  SetRootMenu() does not
-    * accept NULL to indicate that their should be no
-    * menu bar. The fix is to create a temporary empty
-    * menu, set that to be the menu bar, clear the menu
-    * bar and then delete the temporary menu.
-    */
     if (menu is menuBar) return;
     menuBar = menu;
     //remove all existing menu items except the application menu
@@ -2819,6 +3262,24 @@
     }
 }
 
+void setModalShell (Shell shell) {
+    if (modalShells is null) modalShells = new Shell [4];
+    int index = 0, length = modalShells.length;
+    while (index < length) {
+        if (modalShells [index] is shell) return;
+        if (modalShells [index] is null) break;
+        index++;
+    }
+    if (index is length) {
+        Shell [] newModalShells = new Shell [length + 4];
+        System.arraycopy (modalShells, 0, newModalShells, 0, length);
+        modalShells = newModalShells;
+    }
+    modalShells [index] = shell;
+    Shell [] shells = getShells ();
+    for (int i=0; i<shells.length; i++) shells [i].updateModal ();
+}
+
 /**
  * Sets the application defined, display specific data
  * associated with the receiver, to the argument.
@@ -2893,15 +3354,14 @@
 public bool sleep () {
     checkDevice ();
     if (getMessageCount () !is 0) return true;
-    NSAutoreleasePool pool = cast(NSAutoreleasePool)(new NSAutoreleasePool()).alloc().init();
-    try {
-        allowTimers = runAsyncMessages_ = false;
-        NSRunLoop.currentRunLoop().runMode(OS.NSDefaultRunLoopMode, NSDate.distantFuture());
-        allowTimers = runAsyncMessages_ = true;
-        return true;
-    } finally {
+    if (loopCounter is 0) {
         pool.release();
+        pool = cast(NSAutoreleasePool)(new NSAutoreleasePool()).alloc().init();
     }
+    allowTimers = runAsyncMessages = false;
+    NSRunLoop.currentRunLoop().runMode(OS.NSDefaultRunLoopMode, NSDate.distantFuture());
+    allowTimers = runAsyncMessages = true;
+    return true;
 }
 
 int sourceProc (int info) {
@@ -2977,14 +3437,18 @@
     }
     if (index !is timerList.length) {
         NSTimer timer = nsTimers [index];
-        if (milliseconds < 0) {
-            timer.invalidate();
+        if (timer is null) {
             timerList [index] = null;
-            nsTimers [index] = null;
         } else {
-            timer.setFireDate(NSDate.dateWithTimeIntervalSinceNow (milliseconds / 1000.0));
+            if (milliseconds < 0) {
+                timer.invalidate();
+                timerList [index] = null;
+                nsTimers [index] = null;
+            } else {
+                timer.setFireDate(NSDate.dateWithTimeIntervalSinceNow (milliseconds / 1000.0));
+            }
+            return;
         }
-        return;
     } 
     if (milliseconds < 0) return;
     index = 0;
@@ -3001,7 +3465,7 @@
         nsTimers = newTimerIds;
     }
     NSNumber userInfo = NSNumber.numberWithInt(index);
-    NSTimer timer = NSTimer.static_scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(milliseconds / 1000.0, timerDelegate, OS.sel_timerProc_1, userInfo.id_, false);
+    NSTimer timer = NSTimer.scheduledTimerWithTimeInterval(milliseconds / 1000.0, timerDelegate, OS.sel_timerProc_, userInfo, false);
     timer.retain();
     if (timer !is null) {
         nsTimers [index] = timer;
@@ -3009,8 +3473,8 @@
     }
 }
 
-objc.id timerProc (objc.id ID) {
-    NSTimer timer = new NSTimer (ID);
+objc.id timerProc (objc.id id, objc.SEL sel, objc.id timerID) {
+    NSTimer timer = new NSTimer (timerID);
     NSNumber number = new NSNumber(timer.userInfo());
     int index = number.intValue();
     if (timerList is null) return null;
@@ -3071,23 +3535,204 @@
 
 void wakeThread () {
     NSObject object = (new NSObject()).alloc().init();
-    object.performSelectorOnMainThread_withObject_waitUntilDone_(OS.sel_release, null, false);
+    object.performSelectorOnMainThread(OS.sel_release, null, false);
+}
+
+Control findControl (NSEvent nsEvent, bool checkGrab, bool checkTrim, bool checkWindows) {
+    if (checkGrab && grabControl !is null && !grabControl.isDisposed()) return grabControl;
+    NSPoint point = NSEvent.mouseLocation();
+    NSView view = null;
+    NSWindow window = nsEvent !is null ? nsEvent.window() : null;
+    if (window !is null) {
+        view = window.contentView().hitTest (window.convertScreenToBase(point));
+    }
+    if (view is null && checkWindows) {
+        NSArray windows = application.orderedWindows();
+        for (int i = 0; i < windows.count() && view is null; i++) {
+            window = new NSWindow(windows.objectAtIndex(i));
+            NSView contentView = window.contentView();
+            if (contentView !is null) view = contentView.hitTest (window.convertScreenToBase(point));
+        }
+    }
+    Control control = null;
+    if (view !is null) {
+        do {
+            Widget widget = getWidget (view);
+            if (widget instanceof Control) {
+                control = (Control)widget;
+                break;
+            }
+            view = view.superview();
+        } while (view !is null);
+    }
+    if (checkTrim) {
+        if (control !is null && control.isTrim (view)) control = null;
+    }
+    return control;
+}
+
+int /*long*/ applicationNextEventMatchingMask (int /*long*/ id, int /*long*/ sel, int /*long*/ mask, int /*long*/ expiration, int /*long*/ mode, int /*long*/ dequeue) {
+    objc_super super_struct = new objc_super();
+    super_struct.receiver = id;
+    super_struct.super_class = OS.objc_msgSend(id, OS.sel_superclass);
+    int /*long*/ result = OS.objc_msgSendSuper(super_struct, sel, mask, expiration, mode, dequeue !is 0);
+    if (result !is 0) {
+        if (trackingControl !is null && dequeue !is 0) {
+            NSEvent nsEvent = new NSEvent(result);
+            applicationSendMouseEvent(nsEvent, true);
+        }
+    }
+    return result;
 }
 
-extern (C) private static:
+void applicationSendMouseEvent (NSEvent nsEvent, bool send) {
+    if (send) runDeferredEvents();
+    bool up = false;
+    int type = (int)/*64*/nsEvent.type();
+    switch (type) {
+        case OS.NSLeftMouseDown:
+        case OS.NSRightMouseDown:
+        case OS.NSOtherMouseDown: {
+            Control control = grabControl = findControl(nsEvent, false, true, false);
+            if (control !is null) {
+                if (nsEvent.clickCount() is 1 && (control.state & Widget.DRAG_DETECT) !is 0 && control.hooks (DWT.DragDetect) && control.dragDetect()) {
+                    dragging = true;
+                }
+                control.sendMouseEvent (nsEvent, DWT.MouseDown, send);
+                if (nsEvent.clickCount() is 2) {
+                    control.sendMouseEvent (nsEvent, DWT.MouseDoubleClick, send);
+                }
+            }
+            break;
+        }
+        case OS.NSLeftMouseUp:
+        case OS.NSRightMouseUp:
+        case OS.NSOtherMouseUp: {
+            Control control = findControl(nsEvent, true, true, false);
+            if (control !is null) {
+                control.sendMouseEvent (nsEvent, DWT.MouseUp, send);
+            }
+            grabControl = null;
+            up = true;
+            //FALL THROUGH
+        }
+        case OS.NSLeftMouseDragged:
+        case OS.NSRightMouseDragged:
+        case OS.NSOtherMouseDragged:
+        case OS.NSMouseMoved: {
+            Control control = findControl(nsEvent, true, true, type is OS.NSMouseMoved);
+            if (dragging) {
+                dragging = false;
+                control.sendDragEvent(nsEvent);
+            }
+            if (control !is currentControl) {
+                if (currentControl !is null) {
+                    currentControl.sendMouseEvent (nsEvent, DWT.MouseExit, send);
+                }
+                currentControl = control;
+                if (control !is null) {
+                    control.sendMouseEvent (nsEvent, DWT.MouseEnter, send);
+                    if (up) timerExec (getToolTipTime (), hoverTimer);
+                }
+                setCursor (control);
+            }
+            if (!up && control !is null) {
+                timerExec (getToolTipTime (), hoverTimer);
+                control.sendMouseEvent (nsEvent, DWT.MouseMove, send);
+            }
+            break;
+        }
+    }
+}
 
-objc.id applicationDelegateProc(objc.id ID, objc.SEL selector, objc.id arg0_) {
-    Display display = Display.findDisplay(Thread.getThis);
-    int arg0 = cast(int) arg0_;
-    String sel = fromStringz(selector);
-    with (display) {
-    
-    if (sel == OS.sel_applicationWillFinishLaunching_1) {
-        id dict = NSDictionary.dictionaryWithObject(applicationDelegate, NSString.stringWith("NSOwner"));
+void applicationSendEvent (int /*long*/ id, int /*long*/ sel, int /*long*/ event) {
+    NSEvent nsEvent = new NSEvent(event);
+    int type = nsEvent.type ();
+    bool beep = false;
+    switch (type) {
+        case OS.NSLeftMouseDown:
+        case OS.NSRightMouseDown:
+        case OS.NSOtherMouseDown:
+            beep = true;
+        case OS.NSLeftMouseUp:
+        case OS.NSRightMouseUp:
+        case OS.NSMouseMoved:
+        case OS.NSLeftMouseDragged:
+        case OS.NSRightMouseDragged:
+        case OS.NSMouseEntered:
+        case OS.NSMouseExited:
+        case OS.NSKeyDown:
+        case OS.NSKeyUp:
+        case OS.NSOtherMouseUp:
+        case OS.NSOtherMouseDragged:
+        case OS.NSScrollWheel:
+            NSWindow window = nsEvent.window ();
+            if (window !is null) {
+                Shell shell = (Shell) getWidget (window.id);
+                if (shell !is null && shell.getModalShell () !is null) {
+                    if (beep) beep ();  
+                    return;
+                }
+            }
+            break;
+    }
+    applicationSendMouseEvent (nsEvent, false);
+    objc_super super_struct = new objc_super ();
+    super_struct.receiver = id;
+    super_struct.super_class = OS.objc_msgSend (id, OS.sel_superclass);
+    OS.objc_msgSendSuper (super_struct, sel, event);
+//  if (nsEvent.type() is OS.NSApplicationDefined && nsEvent.subtype() is DWT_IDLE_TYPE) {
+//      idle = true;
+//  } else {
+//      idle = false;
+//  }
+//  application.stop(null);
+}
+
+// #245724: [NSApplication isRunning] must return true to allow the AWT to load correctly.
+static int /*long*/ applicationProc(int /*long*/ id, int /*long*/ sel) {
+    //TODO optimize getting the display
+    Display display = getCurrent ();
+    if (display is null) return 0;
+    if (sel is OS.sel_isRunning) {
+        return display.isDisposed() ? 0 : 1;
+    }
+    return 0;
+}
+
+static int /*long*/ applicationProc(int /*long*/ id, int /*long*/ sel, int /*long*/ event) {
+    //TODO optimize getting the display
+    Display display = getCurrent ();
+    if (display is null) return 0;
+    if (sel is OS.sel_sendEvent_) {
+        display.applicationSendEvent (id, sel, event);
+        return 0;
+    }
+    return 0;
+}
+
+static objc.id applicationProc(objc.id id, objc.SEL sel, objc.id arg0, objc.id arg1, objc.id arg2, objc.id arg3) {
+    //TODO optimize getting the display
+    Display display = getCurrent ();
+    if (display is null) return null;
+    if (sel is OS.sel_nextEventMatchingMask_untilDate_inMode_dequeue_) {
+        return display.applicationNextEventMatchingMask(id, sel, arg0, arg1, arg2, arg3);
+    }
+    return 0;
+}
+
+static objc.id applicationDelegateProc(objc.id id, objc.SEL sel, objc.id arg0) {
+    //TODO optimize getting the display
+    Display display = getCurrent ();
+    if (display is null) return 0;
+    id applicationDelegate = display.applicationDelegate;
+    NSApplication application = display.application;
+    if (sel is OS.sel_applicationWillFinishLaunching_) {
+        NSDictionary dict = NSDictionary.dictionaryWithObject(applicationDelegate, NSString.stringWith("NSOwner"));
         NSString nibFile = NSString.stringWith("/System/Library/Frameworks/JavaVM.framework/Resources/English.lproj/DefaultApp.nib");
-        if (!NSBundle.loadNibFile(nibFile, dict, null)) {
+        if (!NSBundle.loadNibFile(nibFile, dict, 0)) {
             nibFile = NSString.stringWith("/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Resources/English.lproj/DefaultApp.nib");
-            NSBundle.loadNibFile(nibFile, dict, null);  
+            NSBundle.loadNibFile(nibFile, dict, 0); 
         }
         //replace %@ with application name
         NSMenu mainmenu = application.mainMenu();
@@ -3097,251 +3742,341 @@
             NSArray ia = sm.itemArray();
             for(int i = 0; i < ia.count(); i++) {
                 NSMenuItem ni = new NSMenuItem(ia.objectAtIndex(i));
-                NSString title = ni.title().stringByReplacingOccurrencesOfString_withString_(NSString.stringWith("%@"), NSString.stringWith(APP_NAME));
+                NSString title = ni.title().stringByReplacingOccurrencesOfString(NSString.stringWith("%@"), NSString.stringWith(APP_NAME));
                 ni.setTitle(title);
             }
         }
-    } else if (sel == OS.sel_terminate_1) {
+    } else if (sel == OS.sel_terminate_) {
         application.terminate(application);
-    } else if (sel == OS.sel_orderFrontStandardAboutPanel_1) {
-        Event event = new Event ();
-        sendEvent (DWT.ABORT, event);
-    } else if (sel == OS.sel_hideOtherApplications_1) {
+    } else if (sel == OS.sel_orderFrontStandardAboutPanel_) {
+//      Event event = new Event ();
+//      sendEvent (DWT.ABORT, event);
+    } else if (sel == OS.sel_hideOtherApplications_) {
         application.hideOtherApplications(application);
-    } else if (sel == OS.sel_hide_1) {
+    } else if (sel == OS.sel_hide_) {
         application.hide(application);
-    } else if (sel == OS.sel_unhideAllApplications_1) {
+    } else if (sel == OS.sel_unhideAllApplications_) {
         application.unhideAllApplications(application);
-    } else if (sel == OS.sel_applicationShouldTerminate_1) {
-        if (!disposing) {
+    } else if (sel == OS.sel_applicationShouldTerminate_) {
+        if (!display.disposing) {
             Event event = new Event ();
-            sendEvent (DWT.Close, event);
+            display.sendEvent (DWT.Close, event);
             if (event.doit) {
                 return cast(objc.id) OS.NSTerminateNow;
             }
         }
         return cast(objc.id) OS.NSTerminateCancel;
-    } else if (sel == OS.sel_applicationWillTerminate_1) {
-        dispose();
-    } 
-    return null;
+    } else if (sel == OS.sel_applicationWillTerminate_) {
+        display.dispose();
+    } else if (sel == OS.sel_applicationWillResignActive_) {
+        Shell[] shells = display.getShells();
+        for (int i = 0; i < shells.length; i++) {
+            shells[i].clearLevel();
+        }
+    }
     }
 }
 
-
-objc.id dialogProc(objc.id id, objc.SEL selector, objc.id arg0_) {
+static objc.id dialogProc(objc.id id, objc.SEL selector, objc.id arg0) {
     String sel = fromStringz(selector);
-    int arg0 = cast(int) arg0_;
-        
-    NSInteger jniRef = cast(NSInteger) OS.objc_msgSend(id, OS.sel_tag);
-    if (jniRef is 0 || jniRef is -1) return null;
-    if (sel == OS.sel_changeColor_1) {
-        ColorDialog dialog = cast(ColorDialog)OS.JNIGetObject(jniRef);
+    
+    objc.id jniRef;
+    OS.object_getInstanceVariable(id, DWT_OBJECT, jniRef);
+    if (jniRef is null) return 0;
+    if (sel == OS.sel_changeColor_) {
+        ColorDialog dialog = (ColorDialog)OS.JNIGetObject(jniRef);
+    if (jniRef is null) return null;
+        dialog.changeColor(id, sel, arg0);
+    } else if (sel == OS.sel_changeFont_) {
+        FontDialog dialog = cast(FontDialog)OS.JNIGetObject(jniRef);
         if (dialog is null) return null;
-        dialog.changeColor(arg0);
-    } else if (sel == OS.sel_changeFont_1) {
-        FontDialog dialog = cast(FontDialog )OS.JNIGetObject(jniRef);
-        if (dialog is null) return null;
-        dialog.changeFont(arg0);
-    } else if (sel == OS.sel_windowWillClose_1) {
-        Object object = OS.JNIGetObject(jniRef);
+        dialog.changeFont(id, sel, arg0);
+    } else if (sel == OS.sel_windowWillClose_) {
+        Object object = OS.JNIGetObject(jniRef[0]);
         if (cast(FontDialog) object) {
-            (cast(FontDialog)object).windowWillClose(arg0);
+            (cast(FontDialog)object).windowWillClose(id, sel, arg0);
         } else if (cast(ColorDialog) object) {
-            (cast(ColorDialog)object).windowWillClose(arg0);
+            (cast(ColorDialog)object).windowWillClose(id, sel, arg0);
         }
     }
     return null;
 }
 	
-objc.id windowDelegateProc2(objc.id delegate_, objc.SEL selector) { 
+static int objc.id windowDelegateProc2(objc.id id, objc.SEL selector) {
     String sel = fromStringz(selector);
-    
-    /*if (sel == OS.sel_tag) {
-        NSInteger* tag;
-        OS.object_getInstanceVariable(delegate_, "tag", cast(void**) &tag);    
-        return cast(objc.id) tag[0];
-    }
-    NSInteger jniRef = cast(NSInteger) OS.objc_msgSend(delegate_, OS.sel_tag);
-    if (jniRef is 0 || jniRef is -1) return null;*/
-    Widget widget = getWidget(delegate_);//cast(Widget)OS.JNIGetObject(jniRef);
+
+    Widget widget = GetWidget(id);
     if (widget is null) return null;
-    if (sel == OS.sel_isFlipped) {
-        return widget.isFlipped() ? cast(objc.id) 1 : null;
-    }
     if (sel == OS.sel_sendSelection) {
         widget.sendSelection();
-        return null;
-    }
-    if (sel == OS.sel_sendArrowSelection) {
-        widget.sendArrowSelection();
-        return null;
-    }
-    if (sel == OS.sel_sendDoubleSelection) {
+    } else if (sel == OS.sel_sendDoubleSelection) {
         widget.sendDoubleSelection();
-        return null;
-    }
-    if (sel == OS.sel_sendVerticalSelection) {
+    } else if (sel == OS.sel_sendVerticalSelection) {
         widget.sendVerticalSelection();
-        return null;
-    }
-    if (sel == OS.sel_sendHorizontalSelection) {
+    } else if (sel == OS.sel_sendHorizontalSelection) {
         widget.sendHorizontalSelection();
-        return null;
-    }
-    if (sel == OS.sel_acceptsFirstResponder) {
-        return widget.acceptsFirstResponder() ? cast(objc.id) 1 : null;
-    }
-    if (sel == OS.sel_becomeFirstResponder) {
-        return widget.becomeFirstResponder() ? cast(objc.id) 1 : null;
-    }
-    if (sel == OS.sel_resignFirstResponder) {
-        return widget.resignFirstResponder() ? cast(objc.id) 1 : null;
+    } else if (sel == OS.sel_acceptsFirstResponder) {
+        return widget.acceptsFirstResponder(id, sel) ? cast(objc.id) 1 : null;
+    } else if (sel is OS.sel_becomeFirstResponder) {
+        return widget.becomeFirstResponder(id, sel) ? cast(objc.id) 1 : null;
+    } else if (sel is OS.sel_resignFirstResponder) {
+        return widget.resignFirstResponder(id, sel) ? cast(objc.id) 1 : null;
+    } else  if (sel == OS.sel_isFlipped) {
+        return widget.isFlipped(id, sel) ? cast(objc.id) 1 : null;
+    } else if (sel == OS.sel_isOpaque) {
+        return widget.isOpaque(id, sel) ? cast(objc.id) 1 : null;
+    } else if (sel is OS.sel_unmarkText) {
+        //TODO not called?
+    } else if (sel is OS.sel_validAttributesForMarkedText) {
+        return widget.validAttributesForMarkedText (id, sel);
+    } else if (sel is OS.sel_markedRange) {
+        NSRange range = widget.markedRange (id, sel);
+        /* NOTE that this is freed in C */
+        int /*long*/ result = OS.malloc (NSRange.sizeof);
+        OS.memmove (result, range, NSRange.sizeof);
+        return result;
+    } else if (sel is OS.sel_selectedRange) {
+        NSRange range = widget.selectedRange (id, sel);
+        /* NOTE that this is freed in C */
+        int /*long*/ result = OS.malloc (NSRange.sizeof);
+        OS.memmove (result, range, NSRange.sizeof);
+        return result;
+    } else if (sel is OS.sel_hasMarkedText) {
+        return widget.hasMarkedText (id, sel) ? 1 : 0;
+    } else if (sel is OS.sel_canBecomeKeyWindow) {
+        return widget.canBecomeKeyWindow (id, sel) ? 1 : 0;
+    } else if (sel is OS.sel_accessibilityActionNames) {
+        return widget.accessibilityActionNames(id, sel);
+    } else if (sel is OS.sel_accessibilityAttributeNames) {
+        return widget.accessibilityAttributeNames(id, sel);
+    } else if (sel is OS.sel_accessibilityParameterizedAttributeNames) {
+        return widget.accessibilityParameterizedAttributeNames(id, sel);
+    } else if (sel is OS.sel_accessibilityFocusedUIElement) {
+        return widget.accessibilityFocusedUIElement(id, sel);
+    } else if (sel is OS.sel_accessibilityIsIgnored) {
+        return (widget.accessibilityIsIgnored(id, sel) ? 1 : 0);
     }
     return null;
 }
 
-objc.id windowDelegateProc3(objc.id ID, objc.SEL selector, objc.id arg0_) {
-    Display display = Display.findDisplay(Thread.getThis);
+static objc.id windowDelegateProc3(objc.id ID, objc.SEL selector, objc.id arg0) {
     String sel = fromStringz(selector);
-    int arg0 = cast(int) arg0_;
-    
-    with (display) {
+
+    if (sel == OS.sel_timerProc_) {
+        //TODO optimize getting the display
+        Display display = getCurrent ();
+        if (display is null) return null;
+        return display.timerProc (id, sel, arg0);
     
     if (sel == OS.sel_timerProc_1) {
         return timerProc (arg0_);
     }
-    if (sel == OS.sel_setTag_1) {
-        OS.object_setInstanceVariable(ID, "tag", &arg0);
-        return null;
+    Widget widget = GetWidget(id);
+    if (widget is null && (sel == OS.sel_keyDown_ ||sel == OS.sel_keyUp_ ||sel == OS.sel_insertText_ ||sel == OS.sel_doCommandBySelector_))  {
+        widget = GetFocusControl (new NSView (id).window ());
     }
-    NSInteger jniRef = cast(NSInteger) OS.objc_msgSend(ID, OS.sel_tag);
-    if (jniRef is 0 || jniRef is -1) return null;
-    Widget widget = cast(Widget)OS.JNIGetObject(jniRef);
     if (widget is null) return null;
-    if (sel == OS.sel_windowWillClose_1) {
-        widget.windowWillClose(arg0);
-    } else if (sel == OS.sel_drawRect_1) {
+    if (sel == OS.sel_windowWillClose_) {
+        widget.windowWillClose(id, sel, arg0);
+    } else if (sel == OS.sel_drawRect_) {
         NSRect rect = NSRect();
         OS.memmove(&rect, arg0_, NSRect.sizeof);
-        widget.drawRect(ID, rect);
-    } else if (sel == OS.sel_windowShouldClose_1) {
-        return widget.windowShouldClose(arg0) ? cast(objc.id) 1 : null;
-    } else if (sel == OS.sel_mouseDown_1) {
-        widget.mouseDown(arg0);
-    } else if (sel == OS.sel_rightMouseDown_1) {
-        widget.rightMouseDown(arg0);
-    } else if (sel == OS.sel_mouseDragged_1) {
-        widget.mouseDragged(arg0);
-    } else if (sel == OS.sel_mouseUp_1) {
-        widget.mouseUp(arg0);
-    } else if (sel == OS.sel_mouseEntered_1) {
-        widget.mouseEntered(arg0);
-    } else if (sel == OS.sel_flagsChanged_1) {
-        widget.flagsChanged(arg0);
-    } else if (sel == OS.sel_numberOfRowsInTableView_1) {
-        return cast(objc.id) widget.numberOfRowsInTableView(arg0);
-    } else if (sel == OS.sel_comboBoxSelectionDidChange_1) {
-        widget.comboBoxSelectionDidChange(arg0);
-    } else if (sel == OS.sel_tableViewSelectionDidChange_1) {
-        widget.tableViewSelectionDidChange(arg0);
-    } else if (sel == OS.sel_windowDidResignKey_1) {
-        widget.windowDidResignKey(arg0);
-    } else if (sel == OS.sel_windowDidBecomeKey_1) {
-        widget.windowDidBecomeKey(arg0);
-    } else if (sel == OS.sel_windowDidResize_1) {
-        widget.windowDidResize(arg0);
-    } else if (sel == OS.sel_windowDidMove_1) {
-        widget.windowDidMove(arg0);
-    } else if (sel == OS.sel_menuForEvent_1) {
-        return cast(objc.id) widget.menuForEvent(arg0);
-    } else if (sel == OS.sel_menuWillOpen_1) {
-        widget.menuWillOpen(arg0);
-    } else if (sel == OS.sel_menuWillClose_1) {
-        widget.menuWillClose(arg0);
-    } else if (sel == OS.sel_menuNeedsUpdate_1) {
-        widget.menuNeedsUpdate(arg0);
-    } else if (sel == OS.sel_outlineViewSelectionDidChange_1) {
-        widget.outlineViewSelectionDidChange(arg0);
-    } else if (sel == OS.sel_sendEvent_1) {
-        widget.windowSendEvent(ID, arg0_);
-    } else if (sel == OS.sel_helpRequested_1) {
-        widget.helpRequested(arg0);
-    }
-    return null;
+        widget.drawRect(id, sel, rect);
+    } else if (sel == OS.sel_setFrameOrigin_) {
+        NSPoint point = NSPoint();
+        OS.memmove(point, arg0, NSPoint.sizeof);
+        widget.setFrameOrigin(id, sel, point);
+    } else if (sel == OS.sel_setFrameSize_) {
+        NSSize size = new NSSize();
+        OS.memmove(size, arg0, NSSize.sizeof);
+        widget.setFrameSize(id, sel, size);
+    } else if (sel == OS.sel_hitTest_) {
+        NSPoint point = new NSPoint();
+        OS.memmove(point, arg0, NSPoint.sizeof);
+        return widget.hitTest(id, sel, point);
+    } else if (sel == OS.sel_windowShouldClose_) {
+        return widget.windowShouldClose(id, sel, arg0) ? 1 : 0;
+    } else if (sel == OS.sel_mouseDown_) {
+        widget.mouseDown(id, sel, arg0);
+    } else if (sel == OS.sel_keyDown_) {
+        widget.keyDown(id, sel, arg0);
+    } else if (sel == OS.sel_keyUp_) {
+        widget.keyUp(id, sel, arg0);
+    } else if (sel == OS.sel_flagsChanged_) {
+        widget.flagsChanged(id, sel, arg0);
+    } else if (sel == OS.sel_mouseUp_) {
+        widget.mouseUp(id, sel, arg0);
+    } else if (sel == OS.sel_rightMouseDown_) {
+        widget.rightMouseDown(id, sel, arg0);
+    } else if (sel == OS.sel_rightMouseUp_) {
+        widget.rightMouseUp(id, sel, arg0);
+    } else if (sel == OS.sel_otherMouseDown_) {
+        widget.otherMouseDown(id, sel, arg0);
+    } else if (sel == OS.sel_otherMouseUp_) {
+        widget.otherMouseUp(id, sel, arg0);
+    } else if (sel == OS.sel_mouseMoved_) {
+        widget.mouseMoved(id, sel, arg0);
+    } else if (sel == OS.sel_mouseDragged_) {
+        widget.mouseDragged(id, sel, arg0);
+    } else if (sel == OS.sel_mouseEntered_) {
+        widget.mouseEntered(id, sel, arg0);
+    } else if (sel == OS.sel_mouseExited_) {
+        widget.mouseExited(id, sel, arg0);
+    } else if (sel == OS.sel_menuForEvent_) {
+        return widget.menuForEvent(id, sel, arg0);
+    } else if (sel == OS.sel_numberOfRowsInTableView_) {
+        return widget.numberOfRowsInTableView(id, sel, arg0);
+    } else if (sel is OS.sel_comboBoxSelectionDidChange_) {
+        widget.comboBoxSelectionDidChange(id, sel, arg0);
+    } else if (sel is OS.sel_tableViewSelectionDidChange_) {
+        widget.tableViewSelectionDidChange(id, sel, arg0);
+    } else if (sel is OS.sel_windowDidResignKey_) {
+        widget.windowDidResignKey(id, sel, arg0);
+    } else if (sel is OS.sel_windowDidBecomeKey_) {
+        widget.windowDidBecomeKey(id, sel, arg0);
+    } else if (sel is OS.sel_windowDidResize_) {
+        widget.windowDidResize(id, sel, arg0);
+    } else if (sel is OS.sel_windowDidMove_) {
+        widget.windowDidMove(id, sel, arg0);
+    } else if (sel is OS.sel_menuWillOpen_) {
+        widget.menuWillOpen(id, sel, arg0);
+    } else if (sel is OS.sel_menuDidClose_) {
+        widget.menuDidClose(id, sel, arg0);
+    } else if (sel is OS.sel_menuNeedsUpdate_) {
+        widget.menuNeedsUpdate(id, sel, arg0);
+    } else if (sel is OS.sel_outlineViewSelectionDidChange_) {
+        widget.outlineViewSelectionDidChange(id, sel, arg0);
+    } else if (sel is OS.sel_outlineViewItemDidExpand_) {
+        widget.outlineViewItemDidExpand(id, sel, arg0);
+    } else if (sel is OS.sel_sendEvent_) {
+        widget.windowSendEvent(id, sel, arg0);
+    } else if (sel is OS.sel_helpRequested_) {
+        widget.helpRequested(id, sel, arg0);
+    } else if (sel is OS.sel_scrollWheel_) {
+        widget.scrollWheel(id, sel, arg0);
+    } else if (sel is OS.sel_pageDown_) {
+        widget.pageDown(id, sel, arg0);
+    } else if (sel is OS.sel_pageUp_) {
+        widget.pageUp(id, sel, arg0);
+    } else if (sel is OS.sel_textViewDidChangeSelection_) {
+        widget.textViewDidChangeSelection(id, sel, arg0);
+    } else if (sel is OS.sel_textDidChange_) {
+        widget.textDidChange(id, sel, arg0);
+    } else if (sel is OS.sel_attributedSubstringFromRange_) {
+        return widget.attributedSubstringFromRange (id, sel, arg0);
+    } else if (sel is OS.sel_characterIndexForPoint_) {
+        return widget.characterIndexForPoint (id, sel, arg0);
+    } else if (sel is OS.sel_firstRectForCharacterRange_) {
+        NSRect rect = widget.firstRectForCharacterRange (id, sel, arg0);
+        /* NOTE that this is freed in C */
+        int /*long*/ result = OS.malloc (NSRect.sizeof);
+        OS.memmove (result, rect, NSRect.sizeof);
+        return result;
+    } else if (sel is OS.sel_insertText_) {
+        widget.insertText (id, sel, arg0);
+    } else if (sel is OS.sel_doCommandBySelector_) {
+        widget.doCommandBySelector (id, sel, arg0);
+    } else if (sel is OS.sel_highlightSelectionInClipRect_) {
+        widget.highlightSelectionInClipRect (id, sel, arg0);
+    } else if (sel is OS.sel_reflectScrolledClipView_) {
+        widget.reflectScrolledClipView (id, sel, arg0);
+    } else if (sel is OS.sel_accessibilityHitTest_) {
+        NSPoint point = new NSPoint();
+        OS.memmove(point, arg0, NSPoint.sizeof);
+        return widget.accessibilityHitTest(id, sel, point);
+    } else if (sel is OS.sel_accessibilityAttributeValue_) {
+        return widget.accessibilityAttributeValue(id, sel, arg0);
+    } else if (sel is OS.sel_accessibilityIsAttributeSettable_) {
+        return (widget.accessibilityIsAttributeSettable(id, sel, arg0) ? 1 : 0);
+    } else if (sel is OS.sel_accessibilityPerformAction_) {
+        widget.accessibilityPerformAction(id, sel, arg0);
+    } else if (sel is OS.sel_accessibilityActionDescription_) {
+        widget.accessibilityActionDescription(id, sel, arg0);
+    } else if (sel is OS.sel_makeFirstResponder_) {
+        return widget.makeFirstResponder(id, sel, arg0) ? 1 : 0;
+    } else if (sel is OS.sel_tableViewColumnDidMove_) {
+        widget.tableViewColumnDidMove(id, sel, arg0);
+    } else if (sel is OS.sel_tableViewColumnDidResize_) {
+        widget.tableViewColumnDidResize(id, sel, arg0);
+    } else if (sel is OS.sel_outlineViewColumnDidMove_) {
+        widget.outlineViewColumnDidMove(id, sel, arg0);
+    } else if (sel is OS.sel_outlineViewColumnDidResize_) {
+        widget.outlineViewColumnDidResize(id, sel, arg0);
     }
 }
 
-
-objc.id windowDelegateProc4(objc.id delegate_, objc.SEL selector, objc.id arg0_, objc.id arg1_) {
+static objc.id windowDelegateProc4(objc.id id, objc.SEL selector, objc.id arg0, objc.id arg1) {
     String sel = fromStringz(selector);
-    int arg0 = cast(int) arg0_;
-    int arg1 = cast(int) arg1_;
+    
+    Widget widget = GetWidget(id);    
     
-    NSInteger jniRef = cast(NSInteger) OS.objc_msgSend(delegate_, OS.sel_tag);
-    if (jniRef is 0 || jniRef is -1) return null;
-    Widget widget = cast(Widget)OS.JNIGetObject(jniRef);
-    if (widget is null) return null;
-    if (sel == OS.sel_tabView_1willSelectTabViewItem_1) {
-        widget.willSelectTabViewItem(arg0, arg1);
-    } else if (sel == OS.sel_outlineView_1isItemExpandable_1) {
-        return widget.outlineView_isItemExpandable(arg0, arg1) ? cast(objc.id) 1 : null;
-    } else if (sel == OS.sel_outlineView_1numberOfChildrenOfItem_1) {
-        return cast(objc.id) widget.outlineView_numberOfChildrenOfItem(arg0, arg1);
-    } else if (sel == OS.sel_outlineView_1shouldCollapseItem_1) {
-        return widget.outlineView_shouldCollapseItem(arg0, arg1) ? cast(objc.id) 1 : null;
-    } else if (sel == OS.sel_outlineView_1shouldExpandItem_1) {
-        return widget.outlineView_shouldExpandItem(arg0, arg1) ? cast(objc.id) 1 : null;
-    } else if (sel == OS.sel_menu_1willHighlightItem_1) {
-        widget.menu_willHighlightItem(arg0, arg1);
+    if (sel == OS.sel_tabView_willSelectTabViewItem_) {
+        widget.tabView_willSelectTabViewItem(id, sel, arg0, arg1);
+    } else if (sel ==is OS.sel_tabView_didSelectTabViewItem_) {
+        widget.tabView_didSelectTabViewItem(id, sel, arg0, arg1);
+    } else if (sel == OS.sel_outlineView_isItemExpandable_) {
+        return widget.outlineView_isItemExpandable(id, sel, arg0, arg1) ? 1 : 0;
+    } else if (sel == OS.sel_outlineView_numberOfChildrenOfItem_) {
+        return widget.outlineView_numberOfChildrenOfItem(id, sel, arg0, arg1);
+    } else if (sel == OS.sel_outlineView_shouldCollapseItem_) {
+        return widget.outlineView_shouldCollapseItem(id, sel, arg0, arg1) ? 1 : 0;
+    } else if (sel == OS.sel_outlineView_shouldExpandItem_) {
+        return widget.outlineView_shouldExpandItem(id, sel, arg0, arg1) ? 1 : 0;
+    } else if (sel == OS.sel_menu_willHighlightItem_) {
+        widget.menu_willHighlightItem(id, sel, arg0, arg1);
+    } else if (sel == OS.sel_setMarkedText_selectedRange_) {
+        widget.setMarkedText_selectedRange (id, sel, arg0, arg1);
+    } else if (sel is OS.sel_drawInteriorWithFrame_inView_) {
+        widget.drawInteriorWithFrame_inView (id, sel, arg0, arg1);
+    } else if (sel is OS.sel_accessibilityAttributeValue_forParameter_) {
+        return widget.accessibilityAttributeValue_forParameter(id, sel, arg0, arg1);
+    } else if (sel is OS.sel_tableView_didClickTableColumn_) {
+        widget.tableView_didClickTableColumn (id, sel, arg0, arg1);
+    } else if (sel is OS.sel_outlineView_didClickTableColumn_) {
+        widget.outlineView_didClickTableColumn (id, sel, arg0, arg1);
     }
     return null;
 }
 
-objc.id windowDelegateProc5(objc.id delegate_, objc.SEL selector, objc.id arg0_, objc.id arg1_, objc.id arg2_) {
+objc.id windowDelegateProc5(objc.id id, objc.SEL selector, objc.id arg0, objc.id arg1, objc.id arg2) {
     String sel = fromStringz(selector);
-    int arg0 = cast(int) arg0_;
-    int arg1 = cast(int) arg1_;
-    int arg2 = cast(int) arg2_;
     
-    NSInteger jniRef = cast(NSInteger) OS.objc_msgSend(delegate_, OS.sel_tag);
-    if (jniRef is 0 || jniRef is -1) return null;
-    Widget widget = cast(Widget)OS.JNIGetObject(jniRef);
-    if (widget is null) return null;
-    if (sel == OS.sel_tableView_1objectValueForTableColumn_1row_1) {
-        return cast(objc.id) widget.tableView_objectValueForTableColumn_row(arg0, arg1, arg2);
-    }
-    if (sel == OS.sel_tableView_1shouldEditTableColumn_1row_1) {
-        return cast(objc.id) widget.tableView_shouldEditTableColumn_row(arg0, arg1, arg2) ? cast(objc.id) 1 : null;
-    } else if (sel == OS.sel_textView_1clickedOnLink_1atIndex_1) {
-         return cast(objc.id) widget.clickOnLink(arg0, arg1, arg2) ? cast(objc.id) 1 : null;
-    } else if (sel == OS.sel_outlineView_1child_1ofItem_1) {
-         return cast(objc.id) widget.outlineView_child_ofItem(arg0, arg1, arg2);
-    } else if (sel == OS.sel_outlineView_1objectValueForTableColumn_1byItem_1) {
-         return cast(objc.id) widget.outlineView_objectValueForTableColumn_byItem(arg0, arg1, arg2);
+    Widget widget = GetWidget(id); 
+      
+    if (sel == OS.sel_tableView_objectValueForTableColumn_row_) {
+        return widget.tableView_objectValueForTableColumn_row(id, sel, arg0, arg1, arg2);
+    } else if (sel == OS.sel_tableView_shouldEditTableColumn_row_) {
+        return widget.tableView_shouldEditTableColumn_row(id, sel, arg0, arg1, arg2) ? cast(objc.id) 1 : null;
+    } else if (sel == OS.sel_textView_clickedOnLink_atIndex_) {
+         return widget.textView_clickOnLink_atIndex(id, sel, arg0, arg1, arg2) ? cast(objc.id) 1 : null;
+    } else if (sel == OS.sel_outlineView_child_ofItem_) {
+         return widget.outlineView_child_ofItem(id, sel, arg0, arg1, arg2);
+    } else if (sel == OS.sel_outlineView_objectValueForTableColumn_byItem_) {
+         return widget.outlineView_objectValueForTableColumn_byItem(id, sel, arg0, arg1, arg2);
+    } else if (sel == OS.sel_textView_willChangeSelectionFromCharacterRange_toCharacterRange_) {
+        NSRange range = widget.textView_willChangeSelectionFromCharacterRange_toCharacterRange(id, sel, arg0, arg1, arg2);
+        /* NOTE that this is freed in C */
+        void* result = OS.malloc (NSRange.sizeof);
+        OS.memmove (result, range, NSRange.sizeof);
+        return result;
     }
     return null;
 }
 
-objc.id windowDelegateProc6(objc.id delegate_, objc.SEL selector, objc.id arg0_, objc.id arg1_, objc.id arg2_, objc.id arg3_) {
+objc.id windowDelegateProc6(objc.id id, objc.SEL selector, objc.id arg0, objc.id arg1, objc.id arg2, objc.id arg3) {
     String sel = fromStringz(selector);
-    int arg0 = cast(int) arg0_;
-    int arg1 = cast(int) arg1_;
-    int arg2 = cast(int) arg2_;
-    int arg3 = cast(int) arg3_;
     
-    NSInteger jniRef = cast(NSInteger) OS.objc_msgSend(delegate_, OS.sel_tag);
-    if (jniRef is 0 || jniRef is -1) return null;
-    Widget widget = cast(Widget)OS.JNIGetObject(jniRef);
-    if (widget is null) return null;
-    if (sel == OS.sel_tableView_1willDisplayCell_1forTableColumn_1row_1) {
-        widget.tableView_willDisplayCell_forTableColumn_row(arg0, arg1, arg2, cast(NSInteger) arg3);
+    Widget widget = GetWidget(id);
+
+    if (sel == OS.sel_tableView_willDisplayCell_forTableColumn_row_) {
+        widget.tableView_willDisplayCell_forTableColumn_row(id, sel, arg0, arg1, arg2, arg3);
+    } else if (sel == OS.sel_outlineView_willDisplayCell_forTableColumn_item_) {
+        widget.outlineView_willDisplayCell_forTableColumn_item(id, sel, arg0, arg1, arg2, arg3);
+    } else  if (sel == OS.sel_outlineView_setObjectValue_forTableColumn_byItem_) {
+        widget.outlineView_setObjectValue_forTableColumn_byItem(id, sel, arg0, arg1, arg2, arg3);
+    } else if (sel == OS.sel_tableView_setObjectValue_forTableColumn_row_) {
+        widget.tableView_setObjectValue_forTableColumn_row(id, sel, arg0, arg1, arg2, arg3);
     } else if (sel == OS.sel_outlineView_1willDisplayCell_1forTableColumn_1item_1) {
-        widget.outlineView_willDisplayCell_forTableColumn_item(arg0, arg1, arg2, arg3);
-    } else  if (sel == OS.sel_outlineView_1setObjectValue_1forTableColumn_1byItem_1) {
-        widget.outlineView_setObjectValue_forTableColumn_byItem(arg0, arg1, arg2, arg3);
-    } else if (sel == OS.sel_tableView_1setObjectValue_1forTableColumn_1row_1) {
-        widget.tableView_setObjectValue_forTableColumn_row(arg0, arg1, arg2, cast(NSInteger) arg3);
     }
     return null;
 }