*** gui_mac_svn.c	Wed Sep 20 21:12:17 2006
--- gui_mac.c	Wed Sep 20 21:11:53 2006
***************
*** 54,60 ****
  # define SCRAPTEXTFLAVOR kScrapFlavorTypeText
  #endif
  
- static EventHandlerUPP mouseWheelHandlerUPP = NULL;
  SInt32 gMacSystemVersion;
  
  #ifdef MACOS_CONVERT
--- 54,59 ----
***************
*** 62,67 ****
--- 61,78 ----
  static EventHandlerUPP keyEventHandlerUPP = NULL;
  #endif
  
+ /* Carbon Event stuff */
+ int s_timed_out = FALSE;
+ int s_last_armed_timer = 0;
+ int s_last_disarmed_timer = 0;
+ EventLoopTimerProcPtr onTimerUPP = NULL;
+ EventHandlerUPP onMouseUPP = NULL;
+ EventHandlerUPP onUpdateUPP = NULL;
+ EventHandlerUPP onWindowUPP = NULL;
+ EventHandlerUPP onMenuUPP = NULL;
+ 
+ static int s_busy_processing = FALSE;
+ 
  
  /* Include some file. TODO: move into os_mac.h */
  #include <Menus.h>
***************
*** 100,115 ****
  #define botRight(r)	(((Point*)&(r))[1])
  
  
- /* Time of last mouse click, to detect double-click */
- static long lastMouseTick = 0;
- 
- /* ??? */
- static RgnHandle cursorRgn;
- static RgnHandle dragRgn;
- static Rect dragRect;
- static short dragRectEnbl;
- static short dragRectControl;
- 
  /* This variable is set when waiting for an event, which is the only moment
   * scrollbar dragging can be done directly.  It's not allowed while commands
   * are executed, because it may move the cursor and that may cause unexpected
--- 111,116 ----
***************
*** 117,131 ****
   */
  static int allow_scrollbar = FALSE;
  
- /* Last mouse click caused contextual menu, (to provide proper release) */
- static short clickIsPopup;
- 
  /* Feedback Action for Scrollbar */
  ControlActionUPP gScrollAction;
- ControlActionUPP gScrollDrag;
- 
- /* Keeping track of which scrollbar is being dragged */
- static ControlHandle dragged_sb = NULL;
  
  static struct
  {
--- 118,125 ----
***************
*** 1126,1134 ****
      setcursor();
      out_flush();
  
-     /* Fake mouse event to wake from stall */
-     PostEvent(mouseUp, 0);
- 
    finished:
      AEDisposeDesc(&theList); /* dispose what we allocated */
  
--- 1120,1125 ----
***************
*** 1536,1578 ****
   * MacOS Feedback procedures
   * ------------------------------------------------------------
   */
-     pascal
-     void
- gui_mac_drag_thumb(ControlHandle theControl, short partCode)
- {
-     scrollbar_T		*sb;
-     int			value, dragging;
-     ControlHandle	theControlToUse;
-     int			dont_scroll_save = dont_scroll;
- 
-     theControlToUse = dragged_sb;
- 
-     sb = gui_find_scrollbar((long) GetControlReference(theControlToUse));
- 
-     if (sb == NULL)
- 	return;
  
!     /* Need to find value by diff between Old Poss New Pos */
!     value = GetControl32BitValue(theControlToUse);
!     dragging = (partCode != 0);
! 
!     /* When "allow_scrollbar" is FALSE still need to remember the new
!      * position, but don't actually scroll by setting "dont_scroll". */
!     dont_scroll = !allow_scrollbar;
!     gui_drag_scrollbar(sb, value, dragging);
!     dont_scroll = dont_scroll_save;
! }
! 
!     pascal
!     void
  gui_mac_scroll_action(ControlHandle theControl, short partCode)
  {
!     /* TODO: have live support */
      scrollbar_T *sb, *sb_info;
      long	data;
      long	value;
      int		page;
!     int		dragging = FALSE;
      int		dont_scroll_save = dont_scroll;
  
      sb = gui_find_scrollbar((long)GetControlReference(theControl));
--- 1527,1542 ----
   * MacOS Feedback procedures
   * ------------------------------------------------------------
   */
  
! static void
  gui_mac_scroll_action(ControlHandle theControl, short partCode)
  {
!     /* partCode == 0 is sent to finish a drag */
      scrollbar_T *sb, *sb_info;
      long	data;
      long	value;
      int		page;
!     int         dragging = FALSE;
      int		dont_scroll_save = dont_scroll;
  
      sb = gui_find_scrollbar((long)GetControlReference(theControl));
***************
*** 1605,1628 ****
  	case  kControlUpButtonPart:   data = -1;    break;
  	case  kControlDownButtonPart: data = 1;     break;
  	case  kControlPageDownPart:   data = page;  break;
! 	case  kControlPageUpPart:     data = -page; break;
! 		    default: data = 0; break;
      }
  
!     value = sb_info->value + data;
! /*  if (value > sb_info->max)
! 	value = sb_info->max;
!     else if (value < 0)
! 	value = 0;*/
  
      /* When "allow_scrollbar" is FALSE still need to remember the new
       * position, but don't actually scroll by setting "dont_scroll". */
      dont_scroll = !allow_scrollbar;
      gui_drag_scrollbar(sb, value, dragging);
      dont_scroll = dont_scroll_save;
! 
!     out_flush();
!     gui_mch_set_scrollbar_thumb(sb, value, sb_info->size, sb_info->max);
  
  /*  if (sb_info->wp != NULL)
      {
--- 1569,1596 ----
  	case  kControlUpButtonPart:   data = -1;    break;
  	case  kControlDownButtonPart: data = 1;     break;
  	case  kControlPageDownPart:   data = page;  break;
!         case  kControlPageUpPart:     data = -page; break;
!         default: data = 0; break;
      }
  
!     if(partCode == kControlIndicatorPart)
!     {
!         value = GetControl32BitValue(theControl);
!         dragging = TRUE;
!     }
!     else
!     {
!         value = sb_info->value + data;
!         dragging = FALSE;
!     }
  
      /* When "allow_scrollbar" is FALSE still need to remember the new
       * position, but don't actually scroll by setting "dont_scroll". */
+     s_busy_processing = TRUE;
      dont_scroll = !allow_scrollbar;
      gui_drag_scrollbar(sb, value, dragging);
      dont_scroll = dont_scroll_save;
!     s_busy_processing = FALSE;
  
  /*  if (sb_info->wp != NULL)
      {
***************
*** 1643,1837 ****
      }*/
  }
  
! /*
!  * ------------------------------------------------------------
!  * MacOS Click Handling procedures
!  * ------------------------------------------------------------
!  */
! 
! 
! /*
!  * Handle a click inside the window, it may happens in the
!  * scrollbar or the contents.
!  *
!  * TODO: Add support for potential TOOLBAR
!  */
!     void
! gui_mac_doInContentClick(EventRecord *theEvent, WindowPtr whichWindow)
  {
!     Point		thePoint;
!     int_u		vimModifiers;
!     short		thePortion;
!     ControlHandle	theControl;
!     int			vimMouseButton;
!     short		dblClick;
! 
!     thePoint = theEvent->where;
!     GlobalToLocal(&thePoint);
!     SelectWindow(whichWindow);
! 
!     thePortion = FindControl(thePoint, whichWindow, &theControl);
! 
!     if (theControl != NUL)
!     {
! 	/* We hit a scollbar */
! 
! 	if (thePortion != kControlIndicatorPart)
! 	{
! 	    dragged_sb = theControl;
! 	    TrackControl(theControl, thePoint, gScrollAction);
! 	    dragged_sb = NULL;
! 	}
! 	else
! 	{
! 	    dragged_sb = theControl;
! #if 1
! 	    TrackControl(theControl, thePoint, gScrollDrag);
! #else
! 	    TrackControl(theControl, thePoint, NULL);
! #endif
! 	    /* pass 0 as the part to tell gui_mac_drag_thumb, that the mouse
! 	     * button has been released */
! 	    gui_mac_drag_thumb(theControl, 0); /* Should it be thePortion ? (Dany) */
! 	    dragged_sb = NULL;
! 	}
!     }
!     else
!     {
! 	/* We are inside the contents */
  
! 	/* Convert the CTRL, OPTION, SHIFT and CMD key */
! 	vimModifiers = EventModifiers2VimMouseModifiers(theEvent->modifiers);
  
! 	/* Defaults to MOUSE_LEFT as there's only one mouse button */
! 	vimMouseButton = MOUSE_LEFT;
  
! 	/* Convert the CTRL_MOUSE_LEFT to MOUSE_RIGHT */
! 	/* TODO: NEEDED? */
! 	clickIsPopup = FALSE;
  
! 	if ((gui.MacOSHaveCntxMenu) && (mouse_model_popup()))
! 	    if (IsShowContextualMenuClick(theEvent))
! 	    {
! 		vimMouseButton = MOUSE_RIGHT;
! 		vimModifiers &= ~MOUSE_CTRL;
! 		clickIsPopup = TRUE;
! 	    }
  
! 	/* Is it a double click ? */
! 	dblClick = ((theEvent->when - lastMouseTick) < GetDblTime());
  
! 	/* Send the mouse click to Vim */
! 	gui_send_mouse_event(vimMouseButton, thePoint.h,
! 					  thePoint.v, dblClick, vimModifiers);
  
! 	/* Create the rectangle around the cursor to detect
! 	 * the mouse dragging
! 	 */
! #if 0
! 	/* TODO: Do we need to this even for the contextual menu?
! 	 * It may be require for popup_setpos, but for popup?
! 	 */
! 	if (vimMouseButton == MOUSE_LEFT)
! #endif
! 	{
! 	    SetRect(&dragRect, FILL_X(X_2_COL(thePoint.h)),
! 				FILL_Y(Y_2_ROW(thePoint.v)),
! 				FILL_X(X_2_COL(thePoint.h)+1),
! 				FILL_Y(Y_2_ROW(thePoint.v)+1));
  
! 	    dragRectEnbl = TRUE;
! 	    dragRectControl = kCreateRect;
! 	}
      }
- }
  
! /*
!  * Handle the click in the titlebar (to move the window)
!  */
!     void
! gui_mac_doInDragClick(Point where, WindowPtr whichWindow)
! {
!     Rect	movingLimits;
!     Rect	*movingLimitsPtr = &movingLimits;
  
!     /* TODO: may try to prevent move outside screen? */
!     movingLimitsPtr = GetRegionBounds(GetGrayRgn(), &movingLimits);
!     DragWindow(whichWindow, where, movingLimitsPtr);
  }
  
- /*
-  * Handle the click in the grow box
-  */
-     void
- gui_mac_doInGrowClick(Point where, WindowPtr whichWindow)
- {
- 
-     long	    newSize;
-     unsigned short  newWidth;
-     unsigned short  newHeight;
-     Rect	    resizeLimits;
-     Rect	    *resizeLimitsPtr = &resizeLimits;
-     Rect	    NewContentRect;
- 
-     resizeLimitsPtr = GetRegionBounds(GetGrayRgn(), &resizeLimits);
- 
-     /* Set the minimun size */
-     /* TODO: Should this come from Vim? */
-     resizeLimits.top = 100;
-     resizeLimits.left = 100;
- 
-     newSize = ResizeWindow(whichWindow, where, &resizeLimits, &NewContentRect);
-     newWidth  = NewContentRect.right - NewContentRect.left;
-     newHeight = NewContentRect.bottom - NewContentRect.top;
-     gui_resize_shell(newWidth, newHeight);
-     gui_mch_set_bg_color(gui.back_pixel);
-     gui_set_shellsize(TRUE, FALSE, RESIZE_BOTH);
- }
- 
- /*
-  * Handle the click in the zoom box
-  */
-     static void
- gui_mac_doInZoomClick(EventRecord *theEvent, WindowPtr whichWindow)
- {
-     Rect	r;
-     Point	p;
-     short	thePart;
- 
-     /* ideal width is current */
-     p.h = Columns * gui.char_width + 2 * gui.border_offset;
-     if (gui.which_scrollbars[SBAR_LEFT])
- 	p.h += gui.scrollbar_width;
-     if (gui.which_scrollbars[SBAR_RIGHT])
- 	p.h += gui.scrollbar_width;
-     /* ideal height is as heigh as we can get */
-     p.v = 15 * 1024;
- 
-     thePart = IsWindowInStandardState(whichWindow, &p, &r)
- 						       ? inZoomIn : inZoomOut;
- 
-     if (!TrackBox(whichWindow, theEvent->where, thePart))
- 	return;
- 
-     /* use returned width */
-     p.h = r.right - r.left;
-     /* adjust returned height */
-     p.v = r.bottom - r.top - 2 * gui.border_offset;
-     if (gui.which_scrollbars[SBAR_BOTTOM])
- 	p.v -= gui.scrollbar_height;
-     p.v -= p.v % gui.char_height;
-     p.v += 2 * gui.border_width;
-     if (gui.which_scrollbars[SBAR_BOTTOM]);
- 	p.v += gui.scrollbar_height;
- 
-     ZoomWindowIdeal(whichWindow, thePart, &p);
- 
-     GetWindowBounds(whichWindow, kWindowContentRgn, &r);
-     gui_resize_shell(r.right - r.left, r.bottom - r.top);
-     gui_mch_set_bg_color(gui.back_pixel);
-     gui_set_shellsize(TRUE, FALSE, RESIZE_BOTH);
- }
  
  /*
   * ------------------------------------------------------------
--- 1611,1767 ----
      }*/
  }
  
! static OSStatus onMouse(EventHandlerCallRef handler, EventRef event,
!         void *data)
  {
!     Point mousePoint; //in screen coords
!     Rect bounds;
!     UInt32 modifiers, clickCount;
!     int_u vimModifiers, vimButton = MOUSE_LEFT;
!     EventMouseButton button;
  
!     WindowRef window;
!     WindowPartCode part;
!     ControlPartCode part2;
  
!     static int clickIsPopup = FALSE;
  
!     assert(GetEventClass(event) == kEventClassMouse);
  
!     GetEventParameter (event, kEventParamMouseLocation, typeQDPoint, NULL,
!             sizeof(mousePoint), NULL, &mousePoint);
  
!     GetEventParameter (event, kEventParamKeyModifiers, typeUInt32, NULL,
!             sizeof(modifiers), NULL, &modifiers);
  
!     GetEventParameter (event, kEventParamClickCount, typeUInt32, NULL,
!             sizeof(clickCount), NULL, &clickCount);
  
!     //check if click was in content region
!     /*
!     GetEventParameter (event, kEventParamWindowRef, typeWindowRef, NULL,
!             sizeof(window), NULL, &window);
  
!     GetEventParameter (event, kEventParamWindowPartCode, typeWindowPartCode,
!             NULL, sizeof(part), NULL, &part);
!             */
!     part = FindWindow(mousePoint, &window);
! 
!     if(window != gui.VimWindow || part != inContent)
!     {
!         return eventNotHandledErr;
!     }
! 
! 
!     //convert to window coords
!     GetWindowBounds(gui.VimWindow, kWindowContentRgn, &bounds);
!     mousePoint.h -= bounds.left;
!     mousePoint.v -= bounds.top;
! 
! 
!     ControlRef control = FindControlUnderMouse(mousePoint, gui.VimWindow,
!             &part2);
!     if(control != NULL && GetEventKind(event) != kEventMouseDown
!             && GetEventKind(event) != kEventMouseWheelMoved)
!     {
!         return noErr;
!     }
! 
!     //XXXNICO TODO: this is only valid for click, release and drag
!     GetEventParameter (event, kEventParamMouseButton, typeMouseButton, NULL,
!             sizeof(button), NULL, &button);
! 
!     vimModifiers = EventModifiers2VimMouseModifiers(modifiers);
! 
!     switch(button)
!     {
!         case kEventMouseButtonPrimary:
!             vimButton = MOUSE_LEFT;
!             break;
!         case kEventMouseButtonSecondary:
!             vimButton = MOUSE_RIGHT;
!             break;
!         case kEventMouseButtonTertiary:
!             vimButton = MOUSE_MIDDLE;
!             break;
!     }
! 
!     switch(GetEventKind(event))
!     {
!         case kEventMouseDown:
!             if(control != NULL)
!             {
!                 HandleControlClick(control, mousePoint, modifiers,
!                         gScrollAction);
! 
!                 //end scroller drag 
!                 gui_mac_scroll_action(control, 0);
!                 return noErr;
!             }
!             if ((gui.MacOSHaveCntxMenu) && (mouse_model_popup()))
!                 /*
!                  * From the docs:
!                  *
!                  * However, if your application uses the standard window
!                  * handler, you probably don't need to use
!                  * IsShowContextualMenuEvent, because the standard window
!                  * handler automatically detects contextual menu clicks and
!                  * sends the kEventWindowContextualMenuSelect and
!                  * kEventControlContextualMenuClick events.
!                  *
!                  * kEventWindowClickContentRegion
!                  *
!                  * -> XXXNICO TODO
!                  */
!                 if (IsShowContextualMenuEvent(event))
!                 {
!                     vimButton = MOUSE_RIGHT;
!                     vimModifiers &= ~MOUSE_CTRL;
!                     clickIsPopup = TRUE;
!                 }
!             break;
!         case kEventMouseUp:
!             if (clickIsPopup)
!             {
!                 vimModifiers &= ~MOUSE_CTRL;
!                 clickIsPopup = FALSE;
!             }
!             vimButton = MOUSE_RELEASE;
!             break;
!         case kEventMouseMoved:
!             if(!clickIsPopup)
!                 gui_mouse_moved(mousePoint.h, mousePoint.v);
!             return eventNotHandledErr;
!         case kEventMouseDragged:
!             vimButton = MOUSE_DRAG;
!             break;
!         case kEventMouseWheelMoved:
!         { 
!             SInt32	delta;
!             EventMouseWheelAxis axis;
! 
!             GetEventParameter(event, kEventParamMouseWheelAxis,
!                     typeMouseWheelAxis, NULL, sizeof(axis), NULL, &axis);
! 
!             if (axis != kEventMouseWheelAxisY) //only scroll with vertical movement
!                 return eventNotHandledErr;
! 
!             GetEventParameter(event, kEventParamMouseWheelDelta,
!                         typeSInt32, NULL, sizeof(SInt32), NULL, &delta);
! 
!             vimButton = (delta > 0) ? MOUSE_4 : MOUSE_5;
!         }break;
!         default:
!             return eventNotHandledErr;
      }
  
!     gui_send_mouse_event(vimButton, mousePoint.h, mousePoint.v,
!            clickCount > 1, vimModifiers);
  
!     //mouse events have to be propagated (for window activation for example):
!     return eventNotHandledErr;
  }
  
  
  /*
   * ------------------------------------------------------------
***************
*** 1944,2008 ****
      SetPort(savePort);
  }
  
- /*
-  * Handle the activate/deactivate event
-  * (apply to a window)
-  */
-     void
- gui_mac_doActivateEvent(EventRecord *event)
- {
-     WindowPtr	whichWindow;
- 
-     whichWindow = (WindowPtr) event->message;
-     if ((event->modifiers) & activeFlag)
- 	/* Activate */
- 	gui_focus_change(TRUE);
-     else
-     {
- 	/* Deactivate */
- 	gui_focus_change(FALSE);
- /*	DON'T KNOW what the code below was doing
- 	found in the deactivate clause, but the
- 	clause writting TRUE into in_focus (BUG)
-  */
- 
- #if 0	/* Removed by Dany as per above June 2001 */
- 	a_bool = false;
- 	SetPreserveGlyph(a_bool);
- 	SetOutlinePreferred(a_bool);
- #endif
-     }
- }
- 
- 
- /*
-  * Handle the suspend/resume event
-  * (apply to the application)
-  */
-     void
- gui_mac_doSuspendEvent(EventRecord *event)
- {
-     /* The frontmost application just changed */
- 
-     /* NOTE: the suspend may happen before the deactivate
-      *       seen on MacOS X
-      */
- 
-     /* May not need to change focus as the window will
-      * get an activate/desactivate event
-      */
-     if (event->message & 1)
- 	/* Resume */
- 	gui_focus_change(TRUE);
-     else
- 	/* Suspend */
- 	gui_focus_change(FALSE);
- }
  
  /*
   * Handle the key
   */
- #ifdef USE_CARBONKEYHANDLER
  
  static int dialog_busy = FALSE;	    /* TRUE when gui_mch_dialog() wants the keys */
  
--- 1874,1883 ----
***************
*** 2180,2188 ****
  	    vim_free(text);
  	    if (e == noErr)
  	    {
- 		/* Fake event to wake up WNE (required to get
- 		 * key repeat working */
- 		//PostEvent(keyUp, 0);
  		return noErr;
  	    }
  	}
--- 2055,2060 ----
***************
*** 2191,2576 ****
  
      return CallNextEventHandler(nextHandler, theEvent);
  }
- #else
-     void
- gui_mac_doKeyEvent(EventRecord *theEvent)
- {
-     /* TODO: add support for COMMAND KEY */
-     long		menu;
-     unsigned char	string[20];
-     short		num, i;
-     short		len = 0;
-     KeySym		key_sym;
-     int			key_char;
-     int			modifiers;
-     int			simplify = FALSE;
- 
-     /* Mask the mouse (as per user setting) */
-     if (p_mh)
- 	ObscureCursor();
- 
-     /* Get the key code and it's ASCII representation */
-     key_sym = ((theEvent->message & keyCodeMask) >> 8);
-     key_char = theEvent->message & charCodeMask;
-     num = 1;
- 
-     /* Intercept CTRL-C */
-     if (theEvent->modifiers & controlKey)
-     {
- 	if (key_char == Ctrl_C && ctrl_c_interrupts)
- 	    got_int = TRUE;
- 	else if ((theEvent->modifiers & ~(controlKey|shiftKey)) == 0
- 		&& (key_char == '2' || key_char == '6'))
- 	{
- 	    /* CTRL-^ and CTRL-@ don't work in the normal way. */
- 	    if (key_char == '2')
- 		key_char = Ctrl_AT;
- 	    else
- 		key_char = Ctrl_HAT;
- 	    theEvent->modifiers = 0;
- 	}
-     }
- 
-     /* Intercept CMD-. */
-     if (theEvent->modifiers & cmdKey)
- 	if (key_char == '.')
- 	    got_int = TRUE;
- 
-     /* Handle command key as per menu */
-     /* TODO: should override be allowed? Require YAO or could use 'winaltkey' */
-     if (theEvent->modifiers & cmdKey)
- 	/* Only accept CMD alone or with CAPLOCKS and the mouse button.
- 	 * Why the mouse button? */
- 	if ((theEvent->modifiers & (~(cmdKey | btnState | alphaLock))) == 0)
- 	{
- 	    menu = MenuKey(key_char);
- 	    if (HiWord(menu))
- 	    {
- 		gui_mac_handle_menu(menu);
- 		return;
- 	    }
- 	}
- 
-     /* Convert the modifiers */
-     modifiers = EventModifiers2VimModifiers(theEvent->modifiers);
- 
- 
-     /* Handle special keys. */
- #if 0
-     /* Why has this been removed? */
-     if	(!(theEvent->modifiers & (cmdKey | controlKey | rightControlKey)))
- #endif
-     {
- 	/* Find the special key (for non-printable keyt_char) */
- 	if  ((key_char < 0x20) || (key_char == 0x7f))
- 	    for (i = 0; special_keys[i].key_sym != (KeySym)0; i++)
- 		if (special_keys[i].key_sym == key_sym)
- 		{
- # if 0
- 		    /* We currently don't have not so special key */
- 		    if (special_keys[i].vim_code1 == NUL)
- 			key_char = special_keys[i].vim_code0;
- 		    else
- # endif
- 			key_char = TO_SPECIAL(special_keys[i].vim_code0,
- 						special_keys[i].vim_code1);
- 		    simplify = TRUE;
- 		    break;
- 		}
-     }
- 
-     /* For some keys the modifier is included in the char itself. */
-     if (simplify || key_char == TAB || key_char == ' ')
- 	key_char = simplify_key(key_char, &modifiers);
- 
-     /* Add the modifier to the input bu if needed */
-     /* Do not want SHIFT-A or CTRL-A with modifier */
-     if (!IS_SPECIAL(key_char)
- 	    && key_sym != vk_Space
- 	    && key_sym != vk_Tab
- 	    && key_sym != vk_Return
- 	    && key_sym != vk_Enter
- 	    && key_sym != vk_Esc)
-     {
- #if 1
-     /* Clear modifiers when only one modifier is set */
- 	if ((modifiers == MOD_MASK_SHIFT)
- 		|| (modifiers == MOD_MASK_CTRL)
- 		|| (modifiers == MOD_MASK_ALT))
- 	    modifiers = 0;
- #else
- 	if (modifiers & MOD_MASK_CTRL)
- 	    modifiers = modifiers & ~MOD_MASK_CTRL;
- 	if (modifiers & MOD_MASK_ALT)
- 	    modifiers = modifiers & ~MOD_MASK_ALT;
- 	if (modifiers & MOD_MASK_SHIFT)
- 	    modifiers = modifiers & ~MOD_MASK_SHIFT;
- #endif
-     }
- 	if (modifiers)
- 	{
- 	    string[len++] = CSI;
- 	    string[len++] = KS_MODIFIER;
- 	    string[len++] = modifiers;
- 	}
- 
- 	if (IS_SPECIAL(key_char))
- 	{
- 	    string[len++] = CSI;
- 	    string[len++] = K_SECOND(key_char);
- 	    string[len++] = K_THIRD(key_char);
- 	}
- 	else
- 	{
- #ifdef FEAT_MBYTE
- 	    /* Convert characters when needed (e.g., from MacRoman to latin1).
- 	     * This doesn't work for the NUL byte. */
- 	    if (input_conv.vc_type != CONV_NONE && key_char > 0)
- 	    {
- 		char_u	from[2], *to;
- 		int	l;
- 
- 		from[0] = key_char;
- 		from[1] = NUL;
- 		l = 1;
- 		to = string_convert(&input_conv, from, &l);
- 		if (to != NULL)
- 		{
- 		    for (i = 0; i < l && len < 19; i++)
- 		    {
- 			if (to[i] == CSI)
- 			{
- 			    string[len++] = KS_EXTRA;
- 			    string[len++] = KE_CSI;
- 			}
- 			else
- 			    string[len++] = to[i];
- 		    }
- 		    vim_free(to);
- 		}
- 		else
- 		    string[len++] = key_char;
- 	    }
- 	    else
- #endif
- 		string[len++] = key_char;
- 	}
- 
- 	if (len == 1 && string[0] == CSI)
- 	{
- 	    /* Turn CSI into K_CSI. */
- 	    string[ len++ ] = KS_EXTRA;
- 	    string[ len++ ] = KE_CSI;
- 	}
- 
-     add_to_input_buf(string, len);
- }
- #endif
- 
- /*
-  * Handle MouseClick
-  */
-     void
- gui_mac_doMouseDownEvent(EventRecord *theEvent)
- {
-     short		thePart;
-     WindowPtr		whichWindow;
- 
-     thePart = FindWindow(theEvent->where, &whichWindow);
- 
-     switch (thePart)
-     {
- 	case (inDesk):
- 	    /* TODO: what to do? */
- 	    break;
- 
- 	case (inMenuBar):
- 	    gui_mac_handle_menu(MenuSelect(theEvent->where));
- 	    break;
- 
- 	case (inContent):
- 	    gui_mac_doInContentClick(theEvent, whichWindow);
- 	    break;
- 
- 	case (inDrag):
- 	    gui_mac_doInDragClick(theEvent->where, whichWindow);
- 	    break;
- 
- 	case (inGrow):
- 	    gui_mac_doInGrowClick(theEvent->where, whichWindow);
- 	    break;
- 
- 	case (inGoAway):
- 	    if (TrackGoAway(whichWindow, theEvent->where))
- 		gui_shell_closed();
- 	    break;
- 
- 	case (inZoomIn):
- 	case (inZoomOut):
- 	    gui_mac_doInZoomClick(theEvent, whichWindow);
- 	    break;
-     }
- }
- 
- /*
-  * Handle MouseMoved
-  * [this event is a moving in and out of a region]
-  */
-     void
- gui_mac_doMouseMovedEvent(EventRecord *event)
- {
-     Point   thePoint;
-     int_u   vimModifiers;
- 
-     thePoint = event->where;
-     GlobalToLocal(&thePoint);
-     vimModifiers = EventModifiers2VimMouseModifiers(event->modifiers);
- 
-     if (!Button())
- 	gui_mouse_moved(thePoint.h, thePoint.v);
-     else
- 	if (!clickIsPopup)
- 	    gui_send_mouse_event(MOUSE_DRAG, thePoint.h,
- 					     thePoint.v, FALSE, vimModifiers);
- 
-     /* Reset the region from which we move in and out */
-     SetRect(&dragRect, FILL_X(X_2_COL(thePoint.h)),
- 			FILL_Y(Y_2_ROW(thePoint.v)),
- 			FILL_X(X_2_COL(thePoint.h)+1),
- 			FILL_Y(Y_2_ROW(thePoint.v)+1));
- 
-     if (dragRectEnbl)
- 	dragRectControl = kCreateRect;
- 
- }
- 
- /*
-  * Handle the mouse release
-  */
-     void
- gui_mac_doMouseUpEvent(EventRecord *theEvent)
- {
-     Point   thePoint;
-     int_u   vimModifiers;
- 
-     /* TODO: Properly convert the Contextual menu mouse-up */
-     /*       Potential source of the double menu */
-     lastMouseTick = theEvent->when;
-     dragRectEnbl = FALSE;
-     dragRectControl = kCreateEmpty;
-     thePoint = theEvent->where;
-     GlobalToLocal(&thePoint);
- 
-     vimModifiers = EventModifiers2VimMouseModifiers(theEvent->modifiers);
-     if (clickIsPopup)
-     {
- 	vimModifiers &= ~MOUSE_CTRL;
- 	clickIsPopup = FALSE;
-     }
-     gui_send_mouse_event(MOUSE_RELEASE, thePoint.h, thePoint.v, FALSE, vimModifiers);
- }
- 
-     static pascal OSStatus
- gui_mac_mouse_wheel(EventHandlerCallRef nextHandler, EventRef theEvent,
- 								   void *data)
- {
-     EventRef	bogusEvent;
-     Point	point;
-     Rect	bounds;
-     UInt32	mod;
-     SInt32	delta;
-     int_u	vim_mod;
-     EventMouseWheelAxis axis;
- 
-     if (noErr == GetEventParameter(theEvent, kEventParamMouseWheelAxis,
- 			  typeMouseWheelAxis, NULL, sizeof(axis), NULL, &axis)
- 	    && axis != kEventMouseWheelAxisY)
- 	goto bail; /* Vim only does up-down scrolling */
- 
-     if (noErr != GetEventParameter(theEvent, kEventParamMouseWheelDelta,
- 			      typeSInt32, NULL, sizeof(SInt32), NULL, &delta))
- 	goto bail;
-     if (noErr != GetEventParameter(theEvent, kEventParamMouseLocation,
- 			      typeQDPoint, NULL, sizeof(Point), NULL, &point))
- 	goto bail;
-     if (noErr != GetEventParameter(theEvent, kEventParamKeyModifiers,
- 				typeUInt32, NULL, sizeof(UInt32), NULL, &mod))
- 	goto bail;
- 
-     vim_mod = 0;
-     if (mod & shiftKey)
- 	vim_mod |= MOUSE_SHIFT;
-     if (mod & controlKey)
- 	vim_mod |= MOUSE_CTRL;
-     if (mod & optionKey)
- 	vim_mod |= MOUSE_ALT;
- 
-     /* post a bogus event to wake up WaitNextEvent */
-     if (noErr != CreateEvent(NULL, kEventClassMouse, kEventMouseMoved, 0,
- 					    kEventAttributeNone, &bogusEvent))
- 	goto bail;
-     if (noErr != PostEventToQueue(GetMainEventQueue(), bogusEvent,
- 							   kEventPriorityLow))
- 	goto bail;
- 
-     ReleaseEvent(bogusEvent);
- 
-     if (noErr == GetWindowBounds(gui.VimWindow, kWindowContentRgn, &bounds))
-     {
- 	point.h -= bounds.left;
- 	point.v -= bounds.top;
-     }
- 
-     gui_send_mouse_event((delta > 0) ? MOUSE_4 : MOUSE_5,
- 					    point.h, point.v, FALSE, vim_mod);
- 
-     return noErr;
- 
-   bail:
-     /*
-      * when we fail give any additional callback handler a chance to perform
-      * it's actions
-      */
-     return CallNextEventHandler(nextHandler, theEvent);
- }
- 
- #if 0
- 
- /*
-  * This would be the normal way of invoking the contextual menu
-  * but the Vim API doesn't seem to a support a request to get
-  * the menu that we should display
-  */
-     void
- gui_mac_handle_contextual_menu(event)
-     EventRecord *event;
- {
- /*
-  *  Clone PopUp to use menu
-  *  Create a object descriptor for the current selection
-  *  Call the procedure
-  */
- 
- //  Call to Handle Popup
-     OSStatus status = ContextualMenuSelect(CntxMenu, event->where, false, kCMHelpItemNoHelp, "", NULL, &CntxType, &CntxMenuID, &CntxMenuItem);
- 
-     if (status != noErr)
- 	return;
- 
-     if (CntxType == kCMMenuItemSelected)
-     {
- 	/* Handle the menu CntxMenuID, CntxMenuItem */
- 	/* The submenu can be handle directly by gui_mac_handle_menu */
- 	/* But what about the current menu, is the meny changed by ContextualMenuSelect */
- 	gui_mac_handle_menu((CntxMenuID << 16) + CntxMenuItem);
-     }
-     else if (CntxMenuID == kCMShowHelpSelected)
-     {
- 	/* Should come up with the help */
-     }
- 
- }
- #endif
  
  /*
   * Handle menubar selection
--- 2063,2068 ----
***************
*** 2597,2684 ****
      HiliteMenu(0);
  }
  
- /*
-  * Dispatch the event to proper handler
-  */
  
!     void
! gui_mac_handle_event(EventRecord *event)
  {
!     OSErr	error;
! 
!     /* Handle contextual menu right now (if needed) */
!     if (gui.MacOSHaveCntxMenu)
! 	if (IsShowContextualMenuClick(event))
! 	{
! # if 0
! 	    gui_mac_handle_contextual_menu(event);
! # else
! 	    gui_mac_doMouseDownEvent(event);
! # endif
! 	    return;
! 	}
! 
!     /* Handle normal event */
!     switch (event->what)
!     {
! #ifndef USE_CARBONKEYHANDLER
! 	case (keyDown):
! 	case (autoKey):
! 	    gui_mac_doKeyEvent(event);
! 	    break;
! #endif
! 	case (keyUp):
! 	    /* We don't care about when the key is released */
! 	    break;
  
! 	case (mouseDown):
! 	    gui_mac_doMouseDownEvent(event);
! 	    break;
  
! 	case (mouseUp):
! 	    gui_mac_doMouseUpEvent(event);
! 	    break;
  
! 	case (updateEvt):
! 	    gui_mac_doUpdateEvent(event);
! 	    break;
  
! 	case (diskEvt):
! 	    /* We don't need special handling for disk insertion */
! 	    break;
  
! 	case (activateEvt):
! 	    gui_mac_doActivateEvent(event);
! 	    break;
  
! 	case (osEvt):
! 	    switch ((event->message >> 24) & 0xFF)
! 	    {
! 		case (0xFA): /* mouseMovedMessage */
! 		    gui_mac_doMouseMovedEvent(event);
! 		    break;
! 		case (0x01): /* suspendResumeMessage */
! 		    gui_mac_doSuspendEvent(event);
! 		    break;
! 	    }
! 	    break;
  
! #ifdef USE_AEVENT
! 	case (kHighLevelEvent):
! 	    /* Someone's talking to us, through AppleEvents */
! 	    error = AEProcessAppleEvent(event); /* TODO: Error Handling */
! 	    break;
! #endif
      }
  }
  
  /*
   * ------------------------------------------------------------
   * Unknown Stuff
   * ------------------------------------------------------------
   */
  
- 
      GuiFont
  gui_mac_find_font(char_u *font_name)
  {
--- 2089,2229 ----
      HiliteMenu(0);
  }
  
  
! static void onTimer(EventLoopTimerRef inTimer, void *inUserData)
  {
!     /*
!      * when wair_for_char is called, a timer is installed and the user presses
!      * a key, the timer is still armed and can fire the next time wait_for_char
!      * is called...check for that
!      */
!     ++s_last_disarmed_timer;
!     if(s_last_disarmed_timer == s_last_armed_timer)
!         s_timed_out = TRUE;
! }
  
! static void clampSize(Point *p)
! {
!     int	    base_width, base_height;
  
!     base_width = gui_get_base_width();
!     base_height = gui_get_base_height();
  
!     p->h = base_width +
!         ((p->h - base_width) / gui.char_width) * gui.char_width;
!     p->v = base_height +
!         ((p->v - base_height) / gui.char_height) * gui.char_height;
! }
  
! static OSStatus onUpdate(EventHandlerCallRef handler, EventRef event,
!         void *data)
! {
!     EventRecord rec;
!     if(ConvertEventRefToEventRecord(event, &rec))
!         gui_mac_doUpdateEvent(&rec);
!     return noErr;
! }
  
! static OSStatus onMenu(EventHandlerCallRef handler, EventRef event,
!         void *data)
! {
!     switch(GetEventKind(event))
!     {
!         case kEventMouseDown:
!         {
!             Point mousePoint;
!             GetEventParameter (event, kEventParamMouseLocation, typeQDPoint,
!                     NULL, sizeof(mousePoint), NULL, &mousePoint);
! 
!             //XXXNICO TODO: check that no mouse button is down (otherwise
!             //dragging doesn't work if the mouse is moved above the menu
!             //bar while dragging)...hmmm, seems, that this is not the reason
!             if(mousePoint.v <= GetMBarHeight())
!             {
!                 gui_mac_handle_menu(MenuSelect(mousePoint));
!                 return noErr;
!             }
!         }break;
!     }
!     return eventNotHandledErr;
! }
  
! static OSStatus onWindow(EventHandlerCallRef handler, EventRef event,
!         void *data)
! {
!     Rect bounds;
!     Point p;
  
!     UInt32 attributes;
!     GetEventParameter(event, kEventParamAttributes, typeUInt32, NULL,
!             sizeof(UInt32), NULL, &attributes);
! 
!     switch(GetEventKind(event))
!     {
!         case kEventWindowBoundsChanging:
!             //limit window size to multiples of character size
!             if(attributes & kWindowBoundsChangeSizeChanged)
!             {
!                 GetEventParameter(event, kEventParamCurrentBounds,
!                         typeQDRectangle, NULL, sizeof(bounds), NULL, &bounds);
!                 p.h = bounds.right - bounds.left;
!                 p.v = bounds.bottom - bounds.top;
!                 clampSize(&p);
!                 bounds.right = bounds.left + p.h;
!                 bounds.bottom = bounds.top + p.v;
!                 //bounds.top = bounds.bottom - p.v;
!                 SetEventParameter(event, kEventParamCurrentBounds,
!                         typeQDRectangle, sizeof(Rect), &bounds);
!             }
!             break;
! 
!         case kEventWindowBoundsChanged:
!             //limit window size to multiples of character size
!             if(attributes & kWindowBoundsChangeSizeChanged)
!             {
!                 GetEventParameter(event, kEventParamCurrentBounds,
!                         typeQDRectangle, NULL, sizeof(bounds), NULL, &bounds);
!                 gui_resize_shell(bounds.right - bounds.left,
!                         bounds.bottom - bounds.top);
!                 gui_set_shellsize(TRUE, FALSE, RESIZE_BOTH);
!             }
!             break;
! 
!         /* send by the standard window handler for a zoom box click */
!         case kEventWindowGetIdealSize:
!             /* ideal width is current */
!             p.h = Columns * gui.char_width + gui_get_base_width();
!             /* ideal height is as high as we can get */
!             p.v = 15 * 1024;
!             SetEventParameter(event, kEventParamDimensions, typeQDPoint,
!                     sizeof(p), &p);
!             break;
!             
!         case kEventWindowClose:
!             //currently only one window is supported, so quit the app when
!             //the window is closed
!             do_cmdline_cmd((char_u *)"confirm qa");
!             break;
! 
!         case kEventWindowActivated:
!             gui_focus_change(TRUE);
!             break;
! 
!         case kEventWindowDeactivated:
!             gui_focus_change(FALSE);
!             break;
      }
+ 
+     return noErr;
  }
  
+ 
  /*
   * ------------------------------------------------------------
   * Unknown Stuff
   * ------------------------------------------------------------
   */
  
      GuiFont
  gui_mac_find_font(char_u *font_name)
  {
***************
*** 2821,2882 ****
  # endif
  #endif
  
-     /* Why did I put that in? (Dany) */
-     MoreMasterPointers (0x40 * 3); /* we love handles */
- 
- #if 0
-     InitCursor();
- 
-     RegisterAppearanceClient();
- 
- #ifdef USE_AEVENT
-     (void) InstallAEHandlers();
- #endif
- 
-     if (Gestalt(gestaltContextualMenuAttr, &gestalt_rc) == noErr)
- 	gui.MacOSHaveCntxMenu = BitTst(&gestalt_rc, 31-gestaltContextualMenuTrapAvailable);
-     else
- 	gui.MacOSHaveCntxMenu = false;
- 
-     if (gui.MacOSHaveCntxMenu)
- 	gui.MacOSHaveCntxMenu = (InitContextualMenus()==noErr);
- 
-     pomme = NewMenu(256, "\p\024"); /* 0x14= = Apple Menu */
- 
-     AppendMenu(pomme, "\pAbout VIM");
- 
-     InsertMenu(pomme, 0);
- 
-     DrawMenuBar();
- 
- 
- #ifndef USE_OFFSETED_WINDOW
-     SetRect(&windRect, 10, 48, 10+80*7 + 16, 48+24*11);
- #else
-     SetRect(&windRect, 300, 40, 300+80*7 + 16, 40+24*11);
- #endif
- 
- 
-     CreateNewWindow(kDocumentWindowClass,
- 		kWindowResizableAttribute | kWindowCollapseBoxAttribute,
- 		&windRect, &gui.VimWindow);
-     SetPortWindowPort(gui.VimWindow);
- 
-     gui.char_width = 7;
-     gui.char_height = 11;
-     gui.char_ascent = 6;
-     gui.num_rows = 24;
-     gui.num_cols = 80;
-     gui.in_focus = TRUE; /* For the moment -> syn. of front application */
- 
-     gScrollAction = NewControlActionUPP(gui_mac_scroll_action);
-     gScrollDrag   = NewControlActionUPP(gui_mac_drag_thumb);
- 
-     dragRectEnbl = FALSE;
-     dragRgn = NULL;
-     dragRectControl = kCreateEmpty;
-     cursorRgn = NewRgn();
- #endif
  #ifdef USE_EXE_NAME
  # ifndef USE_FIND_BUNDLE_PATH
      HGetVol(volName, &applVRefNum, &applDirID);
--- 2366,2371 ----
***************
*** 2971,2977 ****
      gui_handle_drop(x, y, modifiers, fnames, count);
  
      /* Fake mouse event to wake from stall */
!     PostEvent(mouseUp, 0);
  
      return noErr;
  }
--- 2460,2466 ----
      gui_handle_drop(x, y, modifiers, fnames, count);
  
      /* Fake mouse event to wake from stall */
!     //PostEvent(mouseUp, 0);
  
      return noErr;
  }
***************
*** 2983,3010 ****
      int
  gui_mch_init(void)
  {
!     /* TODO: Move most of this stuff toward gui_mch_init */
      Rect	windRect;
      MenuHandle	pomme;
      long	gestalt_rc;
      EventTypeSpec   eventTypeSpec;
-     EventHandlerRef mouseWheelHandlerRef;
- #ifdef USE_CARBONKEYHANDLER
      EventHandlerRef keyEventHandlerRef;
- #endif
  
      if (Gestalt(gestaltSystemVersion, &gMacSystemVersion) != noErr)
  	gMacSystemVersion = 0x1000; /* TODO: Default to minimum sensible value */
  
- #if 1
-     InitCursor();
- 
      RegisterAppearanceClient();
  
  #ifdef USE_AEVENT
      (void) InstallAEHandlers();
  #endif
  
      /* Ctrl click */
      if (Gestalt(gestaltContextualMenuAttr, &gestalt_rc) == noErr)
  	gui.MacOSHaveCntxMenu = BitTst(&gestalt_rc, 31-gestaltContextualMenuTrapAvailable);
--- 2472,2502 ----
      int
  gui_mch_init(void)
  {
!     //XXXNICO TODO: require_noerr( err, CantCreateWindow );
! 
      Rect	windRect;
      MenuHandle	pomme;
      long	gestalt_rc;
      EventTypeSpec   eventTypeSpec;
      EventHandlerRef keyEventHandlerRef;
  
      if (Gestalt(gestaltSystemVersion, &gMacSystemVersion) != noErr)
  	gMacSystemVersion = 0x1000; /* TODO: Default to minimum sensible value */
  
      RegisterAppearanceClient();
  
  #ifdef USE_AEVENT
      (void) InstallAEHandlers();
  #endif
  
+     gScrollAction = NewControlActionUPP(gui_mac_scroll_action);
+     onTimerUPP = NewEventLoopTimerUPP(onTimer);
+     onMouseUPP = NewEventHandlerUPP(onMouse);
+     onWindowUPP = NewEventHandlerUPP(onWindow);
+     onUpdateUPP = NewEventHandlerUPP(onUpdate);
+     onMenuUPP = NewEventHandlerUPP(onMenu);
+ 
+ 
      /* Ctrl click */
      if (Gestalt(gestaltContextualMenuAttr, &gestalt_rc) == noErr)
  	gui.MacOSHaveCntxMenu = BitTst(&gestalt_rc, 31-gestaltContextualMenuTrapAvailable);
***************
*** 3029,3037 ****
--- 2521,2542 ----
      SetRect(&windRect, 300, 40, 300+80*7 + 16, 40+24*11);
  #endif
  
+     /*
      gui.VimWindow = NewCWindow(nil, &windRect, "\pgVim on Macintosh", true,
  			zoomDocProc,
  			(WindowPtr)-1L, true, 0);
+                         */
+     if(noErr != CreateNewWindow(kDocumentWindowClass,
+             kWindowStandardDocumentAttributes
+             | kWindowLiveResizeAttribute
+             //| kWindowCompositingAttribute
+             //Metal seems to imply compositing...doesn't work yet.
+             //Furthermore, clampSize() doesn't work with metal.
+             //| kWindowMetalAttribute
+             | kWindowStandardHandlerAttribute,
+             &windRect, &gui.VimWindow))
+         ; //XXXNICO TODO
+ 
      InstallReceiveHandler((DragReceiveHandlerUPP)receiveHandler,
  	    gui.VimWindow, NULL);
      SetPortWindowPort(gui.VimWindow);
***************
*** 3043,3059 ****
      gui.num_cols = 80;
      gui.in_focus = TRUE; /* For the moment -> syn. of front application */
  
-     gScrollAction = NewControlActionUPP(gui_mac_scroll_action);
-     gScrollDrag   = NewControlActionUPP(gui_mac_drag_thumb);
- 
      /* Install Carbon event callbacks. */
      (void)InstallFontPanelHandler();
  
-     dragRectEnbl = FALSE;
-     dragRgn = NULL;
-     dragRectControl = kCreateEmpty;
-     cursorRgn = NewRgn();
- #endif
      /* Display any pending error messages */
      display_errors();
  
--- 2548,2556 ----
***************
*** 3091,3119 ****
         gui_mch_draw_string() below), enable it for all font sizes. */
      vim_setenv((char_u *)"QDTEXT_MINSIZE", (char_u *)"1");
  
!     eventTypeSpec.eventClass = kEventClassMouse;
!     eventTypeSpec.eventKind = kEventMouseWheelMoved;
!     mouseWheelHandlerUPP = NewEventHandlerUPP(gui_mac_mouse_wheel);
!     if (noErr != InstallApplicationEventHandler(mouseWheelHandlerUPP, 1,
! 				 &eventTypeSpec, NULL, &mouseWheelHandlerRef))
!     {
! 	mouseWheelHandlerRef = NULL;
! 	DisposeEventHandlerUPP(mouseWheelHandlerUPP);
! 	mouseWheelHandlerUPP = NULL;
!     }
! 
! #ifdef USE_CARBONKEYHANDLER
!     eventTypeSpec.eventClass = kEventClassTextInput;
!     eventTypeSpec.eventKind = kEventUnicodeForKeyEvent;
!     keyEventHandlerUPP = NewEventHandlerUPP(gui_mac_doKeyEventCarbon);
!     if (noErr != InstallApplicationEventHandler(keyEventHandlerUPP, 1,
! 		&eventTypeSpec, NULL, &keyEventHandlerRef))
      {
! 	keyEventHandlerRef = NULL;
! 	DisposeEventHandlerUPP(keyEventHandlerUPP);
! 	keyEventHandlerUPP = NULL;
!     }
! #endif
  
  /*
  #ifdef FEAT_MBYTE
--- 2588,2652 ----
         gui_mch_draw_string() below), enable it for all font sizes. */
      vim_setenv((char_u *)"QDTEXT_MINSIZE", (char_u *)"1");
  
!     EventTypeSpec mouseEvents[] =
      {
!         {kEventClassMouse, kEventMouseDown},
!         {kEventClassMouse, kEventMouseUp},
!         {kEventClassMouse, kEventMouseMoved},
!         {kEventClassMouse, kEventMouseDragged},
!         {kEventClassMouse, kEventMouseWheelMoved}
!     };
! 
!     InstallWindowEventHandler(gui.VimWindow, onMouseUPP, 
!             GetEventTypeCount(mouseEvents), mouseEvents, NULL, NULL);
! 
!     EventTypeSpec windowEvents[] =
!     {
!         {kEventClassWindow, kEventWindowBoundsChanging},
!         {kEventClassWindow, kEventWindowBoundsChanged},
!         {kEventClassWindow, kEventWindowGetIdealSize},
!         {kEventClassWindow, kEventWindowClose},
!         {kEventClassWindow, kEventWindowActivated},
!         {kEventClassWindow, kEventWindowDeactivated}
!     };
! 
!     InstallWindowEventHandler(gui.VimWindow, onWindowUPP, 
!             GetEventTypeCount(windowEvents), windowEvents, NULL, NULL);
! 
!    EventTypeSpec updateEvents[] =
!    {
!        //{ kEventClassWindow, kEventWindowDrawContent }
!        //XXXNICO TODO: use drawcontent (needs modifications in the drawing
!        //code)
!        { kEventClassWindow, kEventWindowUpdate }
!    };
! 
!    InstallWindowEventHandler(gui.VimWindow, onUpdateUPP, 
!            GetEventTypeCount(updateEvents), updateEvents, NULL, NULL );
! 
! 
!    //Since we're not using RunApplicationEventLoop(), the application
!    //standard handler isn't installed - we have to track menus ourselves
!    //-- no longer needed with the new RunApplicationEventLoop() trick
!    EventTypeSpec menuEvents[] =
!    {
!         {kEventClassMouse, kEventMouseDown}
!    };
! 
!    //InstallApplicationEventHandler(onMenuUPP, GetEventTypeCount(menuEvents),
!    //        menuEvents, NULL, NULL);
! 
! 
!    eventTypeSpec.eventClass = kEventClassTextInput;
!    eventTypeSpec.eventKind = kEventUnicodeForKeyEvent;
!    keyEventHandlerUPP = NewEventHandlerUPP(gui_mac_doKeyEventCarbon);
!    if (noErr != InstallApplicationEventHandler(keyEventHandlerUPP, 1,
!                &eventTypeSpec, NULL, &keyEventHandlerRef))
!    {
!        keyEventHandlerRef = NULL;
!        DisposeEventHandlerUPP(keyEventHandlerUPP);
!        keyEventHandlerUPP = NULL;
!    }
  
  /*
  #ifdef FEAT_MBYTE
***************
*** 3165,3179 ****
  gui_mch_exit(int rc)
  {
      /* TODO: find out all what is missing here? */
-     DisposeRgn(cursorRgn);
  
! #ifdef USE_CARBONKEYHANDLER
      if (keyEventHandlerUPP)
  	DisposeEventHandlerUPP(keyEventHandlerUPP);
- #endif
- 
-     if (mouseWheelHandlerUPP != NULL)
- 	DisposeEventHandlerUPP(mouseWheelHandlerUPP);
  
  #ifdef USE_ATSUI_DRAWING
      if (p_macatsui && gFontStyle)
--- 2698,2713 ----
  gui_mch_exit(int rc)
  {
      /* TODO: find out all what is missing here? */
  
!     if(onTimerUPP != NULL)
!         DisposeEventLoopTimerUPP(onTimerUPP);
!     if(onMouseUPP != NULL)
!         DisposeEventHandlerUPP(onMouseUPP);
!     if(onUpdateUPP != NULL)
!         DisposeEventHandlerUPP(onUpdateUPP);
! 
      if (keyEventHandlerUPP)
  	DisposeEventHandlerUPP(keyEventHandlerUPP);
  
  #ifdef USE_ATSUI_DRAWING
      if (p_macatsui && gFontStyle)
***************
*** 4192,4197 ****
--- 3726,3743 ----
  }
  
  
+ void process_one_event(EventTargetRef theTarget)
+ {
+     EventRef theEvent;
+ 
+     if(ReceiveNextEvent(0, NULL, kEventDurationForever, true, &theEvent)
+             == noErr)
+     {
+         SendEventToEventTarget(theEvent, theTarget);
+         ReleaseEvent(theEvent);
+     }
+ }
+ 
  
  /*
   * Catch up with any queued X events.  This may put keyboard input into the
***************
*** 4202,4234 ****
      void
  gui_mch_update(void)
  {
!     /* TODO: find what to do
!      *	     maybe call gui_mch_wait_for_chars (0)
!      *	     more like look at EventQueue then
!      *	     call heart of gui_mch_wait_for_chars;
!      *
!      *	if (eventther)
!      *	    gui_mac_handle_event(&event);
!      */
!     EventRecord theEvent;
! 
!     if (EventAvail(everyEvent, &theEvent))
! 	if (theEvent.what != nullEvent)
! 	    gui_mch_wait_for_chars(0);
! }
  
! /*
!  * Simple wrapper to neglect more easily the time
!  * spent inside WaitNextEvent while profiling.
!  */
  
!     pascal
!     Boolean
! WaitNextEventWrp(EventMask eventMask, EventRecord *theEvent, UInt32 sleep, RgnHandle mouseRgn)
! {
!     if (((long) sleep) < -1)
! 	sleep = 32767;
!     return WaitNextEvent(eventMask, theEvent, sleep, mouseRgn);
  }
  
  /*
--- 3748,3764 ----
      void
  gui_mch_update(void)
  {
!     EventRef theEvent;
!     EventTargetRef theTarget;
  
!     theTarget = GetEventDispatcherTarget();
  
!     if (!s_busy_processing)
!         while(ReceiveNextEvent(0, NULL, 0, false, &theEvent) == noErr
!                 && !vim_is_input_buf_full())
!         {
!             process_one_event(theTarget);
!         }
  }
  
  /*
***************
*** 4241,4307 ****
   * or FAIL otherwise.
   */
      int
! gui_mch_wait_for_chars(int wtime)
  {
!     EventMask	mask  = (everyEvent);
!     EventRecord event;
!     long	entryTick;
!     long	currentTick;
!     long	sleeppyTick;
! 
!     /* If we are providing life feedback with the scrollbar,
!      * we don't want to try to wait for an event, or else
!      * there won't be any life feedback.
!      */
!     if (dragged_sb != NULL)
! 	return FAIL;
! 	/* TODO: Check if FAIL is the proper return code */
  
!     entryTick = TickCount();
  
      allow_scrollbar = TRUE;
  
!     do
      {
! /*	if (dragRectControl == kCreateEmpty)
! 	{
! 	    dragRgn = NULL;
! 	    dragRectControl = kNothing;
! 	}
! 	else*/ if (dragRectControl == kCreateRect)
  	{
! 	    dragRgn = cursorRgn;
! 	    RectRgn(dragRgn, &dragRect);
! 	    dragRectControl = kNothing;
  	}
  	/*
  	 * Don't use gui_mch_update() because then we will spin-lock until a
! 	 * char arrives, instead we use WaitNextEventWrp() to hang until an
  	 * event arrives.  No need to check for input_buf_full because we are
! 	 * returning as soon as it contains a single char.
  	 */
! 	/* TODO: reduce wtime accordinly???  */
! 	if (wtime > -1)
! 	    sleeppyTick = 60*wtime/1000;
! 	else
! 	    sleeppyTick = 32767;
! 	if (WaitNextEventWrp(mask, &event, sleeppyTick, dragRgn))
! 	{
! 		gui_mac_handle_event(&event);
! 	    if (input_available())
! 	    {
! 		allow_scrollbar = FALSE;
! 		return OK;
! 	    }
  	}
- 	currentTick = TickCount();
      }
-     while ((wtime == -1) || ((currentTick - entryTick) < 60*wtime/1000));
  
      allow_scrollbar = FALSE;
      return FAIL;
  }
  
  /*
   * Output routines.
   */
--- 3771,3883 ----
   * or FAIL otherwise.
   */
      int
! gui_mch_wait_for_chars2(int wtime)
  {
!     EventTargetRef theTarget;
!     //XXNICO TODO: make these global
!     static EventLoopTimerRef s_timer = NULL;
!     static int s_button_pending, s_timer_set = FALSE;
!     static int focus;
! 
!     theTarget = GetEventDispatcherTarget();
  
!     s_timed_out = FALSE;
! 
!     if (wtime > 0)
!     {
! 	/* Don't do anything while processing a (scroll) message. */
! 	if (s_busy_processing)
! 	    return FAIL;
! 
!         s_timer_set = TRUE;
!         ++s_last_armed_timer;
!         if (s_timer == NULL)
!         {
!             InstallEventLoopTimer(GetCurrentEventLoop(), wtime/1000.0,
!                     kEventDurationForever, onTimerUPP, NULL, &s_timer);
!         }
!         else
!             SetEventLoopTimerNextFireTime(s_timer, wtime/1000.0);
!     }
  
      allow_scrollbar = TRUE;
+     focus = gui.in_focus;
  
!     while (!s_timed_out)
      {
! 	/* Stop or start blinking when focus changes */
! 	if (gui.in_focus != focus)
  	{
! 	    if (gui.in_focus)
! 		gui_mch_start_blink();
! 	    else
! 		gui_mch_stop_blink();
! 	    focus = gui.in_focus;
  	}
+ 
  	/*
  	 * Don't use gui_mch_update() because then we will spin-lock until a
! 	 * char arrives, instead we use GetMessage() to hang until an
  	 * event arrives.  No need to check for input_buf_full because we are
! 	 * returning as soon as it contains a single char -- webb
  	 */
! 
!         /*
!          * process_message() blocks until an event occurs. this is no problem
!          * because we've installed a timer that fires after wtime
!          */
!         process_one_event(theTarget);
! 
! 	if (input_available())
! 	{
! 	    allow_scrollbar = FALSE;
! 
! 	    /* Clear pending mouse button, the release event may have been
! 	     * taken by the dialog window. */
! 	    s_button_pending = -1;
! 
! 	    return OK;
  	}
      }
  
      allow_scrollbar = FALSE;
      return FAIL;
  }
  
+ int g_wtime, g_result;
+ 
+ static void rael(EventLoopTimerRef inTimer, void *inUserData)
+ {
+     g_result = gui_mch_wait_for_chars2(g_wtime);
+     //printf("asdf1\n");
+     QuitApplicationEventLoop();
+     //printf("asdf2\n");
+ }
+ 
+     int
+ gui_mch_wait_for_chars(int wtime)
+ {
+     static EventLoopTimerProcPtr s_raelupp = NULL;
+     static EventLoopTimerRef s_timer = NULL;
+ 
+     if(s_raelupp == NULL)
+       s_raelupp = NewEventLoopTimerUPP(rael);
+ 
+     if (s_timer == NULL)
+     {
+         InstallEventLoopTimer(GetCurrentEventLoop(), 0,
+                 kEventDurationForever, s_raelupp, NULL, &s_timer);
+     }
+     else
+         SetEventLoopTimerNextFireTime(s_timer, 0);
+ 
+     g_wtime = wtime;
+     //printf("bla1\n");
+     RunApplicationEventLoop(); //calls rael
+     //printf("bla2\n");
+     return g_result;
+ }
+ 
  /*
   * Output routines.
   */
***************
*** 4987,4992 ****
--- 4563,4569 ----
      SetControl32BitMaximum (sb->id, max);
      SetControl32BitMinimum (sb->id, 0);
      SetControl32BitValue   (sb->id, val);
+     SetControlViewSize     (sb->id, size);
  #ifdef DEBUG_MAC_SB
      printf("thumb_sb (%x) %x, %x,%x\n",sb->id, val, size, max);
  #endif
***************
*** 5047,5052 ****
--- 4624,4634 ----
  			 0, /* bottom */
  			 kControlScrollBarLiveProc,
  			 (long) sb->ident);
+ 
+     //SetControlAction(sb->id, gScrollAction);
+     //XXXNICO TODO:
+     //InstallControlEventHandler
+     //SetControlAction
  #ifdef DEBUG_MAC_SB
      printf("create_sb (%x) %x\n",sb->id, orient);
  #endif
***************
*** 5579,5588 ****
      SetPortDialogPort(theDialog);
  #endif
  
- #ifdef USE_CARBONKEYHANDLER
      /* Avoid that we use key events for the main window. */
      dialog_busy = TRUE;
- #endif
  
      /* Hang until one of the button is hit */
      do
--- 5161,5168 ----
***************
*** 5590,5598 ****
  	ModalDialog(nil, &itemHit);
      } while ((itemHit < 1) || (itemHit > lastButton));
  
- #ifdef USE_CARBONKEYHANDLER
      dialog_busy = FALSE;
- #endif
  
      /* Copy back the text entered by the user into the param */
      if (textfield != NULL)
--- 5170,5176 ----
***************
*** 5748,5784 ****
      /* TODO: Get the text selection from Vim */
  
      /* Call to Handle Popup */
!     status = ContextualMenuSelect(CntxMenu, where, false, kCMHelpItemNoHelp, HelpName, NULL, &CntxType, &CntxMenuID, &CntxMenuItem);
  
!     if (status == noErr)
      {
! 	if (CntxType == kCMMenuItemSelected)
! 	{
! 	    /* Handle the menu CntxMenuID, CntxMenuItem */
! 	    /* The submenu can be handle directly by gui_mac_handle_menu */
! 	    /* But what about the current menu, is the menu changed by ContextualMenuSelect */
! 	    gui_mac_handle_menu((CntxMenuID << 16) + CntxMenuItem);
! 	}
! 	else if (CntxMenuID == kCMShowHelpSelected)
! 	{
! 	    /* Should come up with the help */
! 	}
      }
  
      /* Restore original Port */
      SetPort(savePort); /*OSX*/
  }
  
- #if defined(FEAT_CW_EDITOR) || defined(PROTO)
- /* TODO: Is it need for MACOS_X? (Dany) */
-     void
- mch_post_buffer_write(buf_T *buf)
- {
-     GetFSSpecFromPath(buf->b_ffname, &buf->b_FSSpec);
-     Send_KAHL_MOD_AE(buf);
- }
- #endif
- 
  #ifdef FEAT_TITLE
  /*
   * Set the window title and icon.
--- 5326,5347 ----
      /* TODO: Get the text selection from Vim */
  
      /* Call to Handle Popup */
!     status = ContextualMenuSelect(CntxMenu, where, false, kCMHelpItemRemoveHelp,
!             HelpName, NULL, &CntxType, &CntxMenuID, &CntxMenuItem);
  
!     if (status == noErr && CntxType == kCMMenuItemSelected)
      {
!         /* Handle the menu CntxMenuID, CntxMenuItem */
!         /* The submenu can be handle directly by gui_mac_handle_menu */
!         /* But what about the current menu, is the menu changed by
!          * ContextualMenuSelect */
!         gui_mac_handle_menu((CntxMenuID << 16) + CntxMenuItem);
      }
  
      /* Restore original Port */
      SetPort(savePort); /*OSX*/
  }
  
  #ifdef FEAT_TITLE
  /*
   * Set the window title and icon.
***************
*** 6114,6117 ****
--- 5677,5682 ----
      return (script != smRoman
  	    && script == GetScriptManagerVariable(smSysScript)) ? 1 : 0;
  }
+ 
  #endif /* defined(USE_IM_CONTROL) || defined(PROTO) */
+ 
