]> code.delx.au - gnu-emacs/blobdiff - src/macterm.c
* macterm.c (XTread_socket): Call KeyTranslate for control and
[gnu-emacs] / src / macterm.c
index e9cb1b07de77f04495d9a83f1912042cca034358..0e97e6bbb30055e8e3a5a2776681f7ab610b894c 100644 (file)
@@ -366,6 +366,7 @@ extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *));
 
 extern Lisp_Object x_icon_type P_ ((struct frame *));
 
+extern int inhibit_window_system;
 
 #if __MRC__
 QDGlobals qd;  /* QuickDraw global information structure.  */
@@ -418,7 +419,6 @@ void x_wm_set_icon_pixmap P_ ((struct frame *, int));
 void mac_initialize P_ ((void));
 static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
 static int x_compute_min_glyph_bounds P_ ((struct frame *));
-enum text_cursor_kinds x_specified_cursor_type P_ ((Lisp_Object, int *));
 static void x_draw_phys_cursor_glyph P_ ((struct window *,
                                          struct glyph_row *,
                                          enum draw_glyphs_face));
@@ -443,6 +443,8 @@ static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int));
 static int x_intersect_rectangles P_ ((Rect *, Rect *, Rect *));
 static void expose_frame P_ ((struct frame *, int, int, int, int));
 static int expose_window_tree P_ ((struct window *, Rect *));
+static void expose_overlaps P_ ((struct window *, struct glyph_row *,
+                                struct glyph_row *));
 static int expose_window P_ ((struct window *, Rect *));
 static void expose_area P_ ((struct window *, struct glyph_row *,
                             Rect *, enum glyph_row_area));
@@ -474,6 +476,8 @@ static void x_produce_stretch_glyph P_ ((struct it *));
 static void activate_scroll_bars (FRAME_PTR);
 static void deactivate_scroll_bars (FRAME_PTR);
 
+static int is_emacs_window (WindowPtr);
+
 extern int image_ascent (struct image *, struct face *);
 void x_set_offset (struct frame *, int, int, int);
 int x_bitmap_icon (struct frame *, Lisp_Object);
@@ -6238,8 +6242,41 @@ x_phys_cursor_in_rect_p (w, r)
 }
 
 
-/* Redraw the part of window W intersection rectagle FR.  Pixel
-   coordinates in FR are frame relative.  Call this function with
+/* Redraw those parts of glyphs rows during expose event handling that
+   overlap other rows.  Redrawing of an exposed line writes over parts
+   of lines overlapping that exposed line; this function fixes that.
+
+   W is the window being exposed.  FIRST_OVERLAPPING_ROW is the first
+   row in W's current matrix that is exposed and overlaps other rows.
+   LAST_OVERLAPPING_ROW is the last such row.  */
+
+static void
+expose_overlaps (w, first_overlapping_row, last_overlapping_row)
+     struct window *w;
+     struct glyph_row *first_overlapping_row;
+     struct glyph_row *last_overlapping_row;
+{
+  struct glyph_row *row;
+  
+  for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
+    if (row->overlapping_p)
+      {
+       xassert (row->enabled_p && !row->mode_line_p);
+         
+       if (row->used[LEFT_MARGIN_AREA])
+         x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
+  
+       if (row->used[TEXT_AREA])
+         x_fix_overlapping_area (w, row, TEXT_AREA);
+  
+       if (row->used[RIGHT_MARGIN_AREA])
+         x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
+      }
+}
+
+
+/* Redraw the part of window W intersection rectangle FR.  Pixel
+   coordinates in FR are frame-relative.  Call this function with
    input blocked.  Value is non-zero if the exposure overwrites
    mouse-face.  */
 
@@ -6279,7 +6316,8 @@ expose_window (w, fr)
       int yb = window_text_bottom_y (w);
       struct glyph_row *row;
       int cursor_cleared_p;
-
+      struct glyph_row *first_overlapping_row, *last_overlapping_row;
+  
       TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
              r.left, r.top, r.right, r.bottom));
 
@@ -6299,7 +6337,8 @@ expose_window (w, fr)
       else
        cursor_cleared_p = 0;
 
-      /* Find the first row intersecting the rectangle R.  */
+      /* Update lines intersecting rectangle R.  */
+      first_overlapping_row = last_overlapping_row = NULL;
       for (row = w->current_matrix->rows;
           row->enabled_p;
           ++row)
@@ -6312,10 +6351,17 @@ expose_window (w, fr)
              || (r.top >= y0 && r.top < y1)
              || (r.bottom > y0 && r.bottom < y1))
            {
+             if (row->overlapping_p)
+               {
+                 if (first_overlapping_row == NULL)
+                   first_overlapping_row = row;
+                 last_overlapping_row = row;
+               }
+             
              if (expose_line (w, row, &r))
                mouse_face_overwritten_p = 1;
            }
-
+             
          if (y1 >= yb)
            break;
        }
@@ -6332,9 +6378,13 @@ expose_window (w, fr)
 
       if (!w->pseudo_window_p)
        {
+         /* Fix the display of overlapping rows.  */
+         if (first_overlapping_row)
+           expose_overlaps (w, first_overlapping_row, last_overlapping_row);
+         
          /* Draw border between windows.  */
          x_draw_vertical_border (w);
-
+      
          /* Turn the cursor on again.  */
          if (cursor_cleared_p)
            x_update_window_cursor (w, 1);
@@ -7280,7 +7330,8 @@ note_mouse_highlight (f, x, y)
 
              dpyinfo->mouse_face_face_id
                = face_at_buffer_position (w, pos, 0, 0,
-                                          &ignore, pos + 1, 1);
+                                          &ignore, pos + 1,
+                                          !dpyinfo->mouse_face_hidden);
 
              /* Display it as active.  */
              show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
@@ -7322,7 +7373,8 @@ note_mouse_highlight (f, x, y)
              if (BUFFERP (object))
                dpyinfo->mouse_face_face_id
                  = face_at_buffer_position (w, pos, 0, 0,
-                                            &ignore, pos + 1, 1);
+                                            &ignore, pos + 1,
+                                            !dpyinfo->mouse_face_hidden);
 
              /* Display it as active.  */
              show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
@@ -7401,7 +7453,8 @@ note_mouse_highlight (f, x, y)
                  dpyinfo->mouse_face_window = window;
                  dpyinfo->mouse_face_face_id
                    = face_at_buffer_position (w, pos, 0, 0,
-                                              &ignore, pos + 1, 1);
+                                              &ignore, pos + 1,
+                                              !dpyinfo->mouse_face_hidden);
 
                  /* Display it as active.  */
                  show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
@@ -8250,9 +8303,12 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
   Point mouse_pos;
   int ignore1, ignore2;
   WindowPtr wp = FrontWindow ();
-  struct frame *f = ((mac_output *) GetWRefCon (wp))->mFP;            
+  struct frame *f;
   Lisp_Object frame, tail;
 
+  if (is_emacs_window(wp))
+    f = ((mac_output *) GetWRefCon (wp))->mFP;         
+
   BLOCK_INPUT;
 
   if (! NILP (last_mouse_scroll_bar) && insist == 0)
@@ -9043,7 +9099,7 @@ x_draw_bar_cursor (w, row, width)
        }
 
       if (width < 0)
-       width = f->output_data.mac->cursor_width;
+       width = FRAME_CURSOR_WIDTH (f);
 
       x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
       x_clip_to_row (w, row, gc, 0);
@@ -9245,11 +9301,10 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
   struct frame *f = XFRAME (w->frame);
   int new_cursor_type;
   int new_cursor_width;
+  int active_cursor;
   struct glyph_matrix *current_glyphs;
   struct glyph_row *glyph_row;
   struct glyph *glyph;
-  int cursor_non_selected;
-  int active_cursor = 1;
 
   /* This is pointless on invisible frames, and dangerous on garbaged
      windows and frames; in the latter case, the frame or window may
@@ -9279,65 +9334,9 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
 
   xassert (interrupt_input_blocked);
 
-  /* Set new_cursor_type to the cursor we want to be displayed.  In a
-     mini-buffer window, we want the cursor only to appear if we are
-     reading input from this window.  For the selected window, we want
-     the cursor type given by the frame parameter.  If explicitly
-     marked off, draw no cursor.  In all other cases, we want a hollow
-     box cursor.  */
-  cursor_non_selected 
-    = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows,
-                                 w->buffer));
-  new_cursor_width = -1;
-  if (cursor_in_echo_area
-      && FRAME_HAS_MINIBUF_P (f)
-      && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
-    {
-      if (w == XWINDOW (echo_area_window))
-       new_cursor_type = FRAME_DESIRED_CURSOR (f);
-      else
-       {
-         if (cursor_non_selected)
-           new_cursor_type = HOLLOW_BOX_CURSOR;
-         else
-           new_cursor_type = NO_CURSOR;
-         active_cursor = 0;
-       }
-    }
-  else
-    {
-      if (f != FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame
-          || w != XWINDOW (f->selected_window))
-        {
-         active_cursor = 0;
+  /* Set new_cursor_type to the cursor we want to be displayed.  */
+  new_cursor_type = get_window_cursor_type (w, &new_cursor_width, &active_cursor);
 
-          if (MINI_WINDOW_P (w) 
-              || !cursor_non_selected
-              || NILP (XBUFFER (w->buffer)->cursor_type))
-            new_cursor_type = NO_CURSOR;
-          else
-            new_cursor_type = HOLLOW_BOX_CURSOR;
-        }
-      else
-        {
-         struct buffer *b = XBUFFER (w->buffer);
-
-         if (EQ (b->cursor_type, Qt))
-            new_cursor_type = FRAME_DESIRED_CURSOR (f);
-         else
-           new_cursor_type = x_specified_cursor_type (b->cursor_type, 
-                                                      &new_cursor_width);
-         if (w->cursor_off_p)
-           {
-             if (new_cursor_type == FILLED_BOX_CURSOR)
-               new_cursor_type = HOLLOW_BOX_CURSOR;
-             else if (new_cursor_type == BAR_CURSOR && new_cursor_width > 1)
-               new_cursor_width = 1;
-             else
-               new_cursor_type = NO_CURSOR;
-           }
-       }
-    }
 
   /* If cursor is currently being shown and we don't want it to be or
      it is in the wrong place, or the cursor type is not what we want,
@@ -9347,7 +9346,7 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
          || w->phys_cursor.x != x
          || w->phys_cursor.y != y
          || new_cursor_type != w->phys_cursor_type
-         || (new_cursor_type == BAR_CURSOR
+         || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
              && new_cursor_width != w->phys_cursor_width)))
     x_erase_phys_cursor (w);
 
@@ -9378,6 +9377,8 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
          x_draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
          break;
 
+       case HBAR_CURSOR:
+         /* TODO.  For now, just draw bar cursor. */
        case BAR_CURSOR:
          x_draw_bar_cursor (w, glyph_row, new_cursor_width);
          break;
@@ -11496,6 +11497,14 @@ Lisp_Object Vmac_reverse_ctrl_meta;
 /* True if the mouse wheel button (i.e. button 4) should map to
    mouse-2, instead of mouse-3.  */
 Lisp_Object Vmac_wheel_button_is_mouse_2;
+
+/* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
+   for processing before Emacs sees it.  */
+Lisp_Object Vmac_pass_command_to_system;
+
+/* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
+   for processing before Emacs sees it.  */
+Lisp_Object Vmac_pass_control_to_system;
 #endif
 
 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
@@ -11581,10 +11590,10 @@ mac_get_mouse_btn (EventRef ref)
     case kEventMouseButtonPrimary:
       return 0;
     case kEventMouseButtonSecondary:
-      return NILP (Vmac_wheel_button_is_mouse_2) ? 2 : 1
+      return NILP (Vmac_wheel_button_is_mouse_2) ? 1 : 2
     case kEventMouseButtonTertiary:
     case 4:  /* 4 is the number for the mouse wheel button */
-      return NILP (Vmac_wheel_button_is_mouse_2) ? 1 : 2
+      return NILP (Vmac_wheel_button_is_mouse_2) ? 2 : 1
     default:
       return 0;
     }
@@ -11839,17 +11848,22 @@ static void
 do_mouse_moved (Point mouse_pos)
 {
   WindowPtr wp = FrontWindow ();
-  struct frame *f = ((mac_output *) GetWRefCon (wp))->mFP;            
+  struct frame *f;
 
+  if (is_emacs_window (wp)) 
+    {
+      f = ((mac_output *) GetWRefCon (wp))->mFP;            
+      
 #if TARGET_API_MAC_CARBON
       SetPort (GetWindowPort (wp));
 #else
       SetPort (wp);
 #endif
 
-  GlobalToLocal (&mouse_pos);
-
-  note_mouse_movement (f, &mouse_pos);
+      GlobalToLocal (&mouse_pos);
+      
+      note_mouse_movement (f, &mouse_pos);
+    }
 }
 
 
@@ -12144,7 +12158,8 @@ init_required_apple_events ()
 
 #if USE_CARBON_EVENTS
 
-void init_service_handler()
+void
+init_service_handler ()
 {
   EventTypeSpec specs[] = {{kEventClassService, kEventServiceGetTypes},
                           {kEventClassService, kEventServiceCopy},
@@ -12156,8 +12171,9 @@ void init_service_handler()
 /*
    MAC_TODO: Check to see if this is called by AEProcessDesc...
  */
-OSStatus mac_handle_service_event (EventHandlerCallRef callRef,
-                                  EventRef event, void *data)
+OSStatus
+mac_handle_service_event (EventHandlerCallRef callRef,
+                         EventRef event, void *data)
 {
   OSStatus err = noErr; 
   switch (GetEventKind (event))
@@ -12333,8 +12349,9 @@ descriptor_error_exit:
 }
 
 
-static pascal OSErr mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
-                                        DragReference theDrag)
+static pascal OSErr
+mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
+                    DragReference theDrag)
 {
   short items;
   short index;
@@ -12521,7 +12538,7 @@ static unsigned char keycode_to_xkeysym_table[] = {
 /* 0x00 - 0x3f */
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, '\x0d', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 /* 0x40 */
   0, '\xae' /* kp. */, 0, '\xaa' /* kp* */, 
@@ -12613,7 +12630,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
                                expected
                                ? TicksToEventTime (app_sleep_time)
                                : 0,
-                               true, &eventRef);
+                               kEventRemoveFromQueue, &eventRef);
   if (!rneResult)
     {
       /* Handle new events */
@@ -12625,7 +12642,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
              {
                SInt32 delta;
                Point point;
-               WindowPtr window_ptr = FrontWindow ();
+               WindowPtr window_ptr = FrontNonFloatingWindow ();
                struct mac_output *mwp = (mac_output *) GetWRefCon (window_ptr);
                GetEventParameter(eventRef, kEventParamMouseWheelDelta,
                                  typeSInt32, NULL, sizeof (SInt32),
@@ -12644,7 +12661,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
                bufp->timestamp = EventTimeToTicks (GetEventTime (eventRef))*(1000/60);
                count++;
              }
-           else
+           else             
              SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
 
            break;
@@ -12665,8 +12682,14 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
          SInt16 part_code;
 
 #if USE_CARBON_EVENTS
-         /* This is needed to correctly */
-         SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
+         /* This is needed to send mouse events like aqua window buttons
+            to the correct handler.  */
+         if (eventNotHandledErr != SendEventToEventTarget (eventRef, GetEventDispatcherTarget ())) {
+           break;
+         }
+
+         if (!is_emacs_window(window_ptr))
+           break;
 #endif
 
           if (mouse_tracking_in_progress == mouse_tracking_scroll_bar
@@ -12860,7 +12883,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
       case osEvt:
       case activateEvt:
 #if USE_CARBON_EVENTS
-       SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
+       if (eventNotHandledErr == SendEventToEventTarget (eventRef, GetEventDispatcherTarget ()))
 #endif 
        do_events (&er);
        break;
@@ -12871,15 +12894,33 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
          int keycode = (er.message & keyCodeMask) >> 8;
          int xkeysym;
          
+#if USE_CARBON_EVENTS
+         /* When using Carbon Events, we need to pass raw keyboard events
+            to the TSM ourselves.  If TSM handles it, it will pass back
+            noErr, otherwise it will pass back "eventNotHandledErr" and
+            we can process it normally.   */
+         if ((!NILP (Vmac_pass_command_to_system)
+              || !(er.modifiers & cmdKey))
+             && (!NILP (Vmac_pass_control_to_system)
+                 || !(er.modifiers & controlKey)))
+           {
+             OSStatus err;
+             err = SendEventToEventTarget (eventRef,
+                                           GetEventDispatcherTarget ());
+             if (err != eventNotHandledErr)
+               break;
+           }
+#endif
+         
          if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
            {
              SysBeep (1);
              UNBLOCK_INPUT;
              return 0;
            }
-
+         
          ObscureCursor ();
-
+         
          if (keycode == 0x33)  /* delete key (charCode translated to 0x8) */
            {
              bufp->code = 0x7f;
@@ -12890,100 +12931,83 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
              bufp->code = 0xff00 | xkeysym;
              bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
            }      
-         else if (!NILP (Vmac_reverse_ctrl_meta) && (er.modifiers & controlKey))
-           {
-             /* This is a special case to deal with converting from
-                a control character to non-control character */
-             int new_modifiers = er.modifiers & ~controlKey;
-             int new_keycode = keycode | new_modifiers;              
-             Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
-             unsigned long some_state = 0;
-             bufp->code = KeyTranslate (kchr_ptr, new_keycode, &some_state) & 0xff;
-             bufp->kind = ASCII_KEYSTROKE_EVENT;
-           }
          else
            {
-             if (er.modifiers & macMetaKey)
-               {
-                 /* This code comes from Keyboard Resource, Appendix
+             if (er.modifiers & (controlKey | 
+                                 (NILP (Vmac_command_key_is_meta) ? optionKey 
+                                  : cmdKey)))
+               {
+                 /* This code comes from Keyboard Resource, Appendix
                     C of IM - Text.  This is necessary since shift is
                     ignored in KCHR table translation when option or
-                    command is pressed. */
-                 int new_modifiers = er.modifiers & 0xf600;
-                   /* mask off option and command */
-                 int new_keycode = keycode | new_modifiers;
-                 Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
-                 unsigned long some_state = 0;
-                 bufp->code = KeyTranslate (kchr_ptr, new_keycode,
+                    command is pressed.  It also does not translate 
+                    correctly control-shift chars like C-% so mask off
+                    shift here also */
+                 int new_modifiers = er.modifiers & 0xe600;
+                 /* mask off option and command */
+                 int new_keycode = keycode | new_modifiers;
+                 Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+                 unsigned long some_state = 0;
+                 bufp->code = KeyTranslate (kchr_ptr, new_keycode,
                                             &some_state) & 0xff;
-               }
-#if USE_CARBON_EVENTS
-             else if (er.modifiers & cmdKey &&
-                      (NILP (Vmac_command_key_is_meta)))
-               {
-                 /* If this is a command key (and we are not overriding it),
-                    send back to the operating system  */
-                 SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
-                 break;
                }
-#endif
              else
-               bufp->code = er.message & charCodeMask;
+               bufp->code = er.message & charCodeMask;
              bufp->kind = ASCII_KEYSTROKE_EVENT;
            }
        }
-
-        /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
-           convert non-ASCII characters typed at the Mac keyboard
-           (presumed to be in the Mac Roman encoding) to iso-latin-1
-           encoding before they are passed to Emacs.  This enables the
-           Mac keyboard to be used to enter non-ASCII iso-latin-1
-           characters directly.  */
-        if (mac_keyboard_text_encoding != kTextEncodingMacRoman
+       
+       /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
+          convert non-ASCII characters typed at the Mac keyboard
+          (presumed to be in the Mac Roman encoding) to iso-latin-1
+          encoding before they are passed to Emacs.  This enables the
+          Mac keyboard to be used to enter non-ASCII iso-latin-1
+          characters directly.  */
+       if (mac_keyboard_text_encoding != kTextEncodingMacRoman
            && bufp->kind == ASCII_KEYSTROKE_EVENT && bufp->code >= 128)
          {
-            static TECObjectRef converter = NULL;
-            OSStatus the_err = noErr;
-            OSStatus convert_status = noErr;
-
-            if (converter ==  NULL)
-              {
-                the_err = TECCreateConverter (&converter,
+           static TECObjectRef converter = NULL;
+           OSStatus the_err = noErr;
+           OSStatus convert_status = noErr;
+           
+           if (converter ==  NULL)
+             {
+               the_err = TECCreateConverter (&converter,
                                              kTextEncodingMacRoman,
                                              mac_keyboard_text_encoding);
-                current_mac_keyboard_text_encoding
+               current_mac_keyboard_text_encoding
                  = mac_keyboard_text_encoding;
-              }
-            else if (mac_keyboard_text_encoding
+             }
+           else if (mac_keyboard_text_encoding
                     != current_mac_keyboard_text_encoding)
-              {
-                /* Free the converter for the current encoding before
-                   creating a new one.  */
-                TECDisposeConverter (converter);
-                the_err = TECCreateConverter (&converter,
+             {
+               /* Free the converter for the current encoding before
+                  creating a new one.  */
+               TECDisposeConverter (converter);
+               the_err = TECCreateConverter (&converter,
                                              kTextEncodingMacRoman,
                                              mac_keyboard_text_encoding);
-                current_mac_keyboard_text_encoding
+               current_mac_keyboard_text_encoding
                  = mac_keyboard_text_encoding;
-              
-              
-            if (the_err == noErr)
-              {
-                unsigned char ch = bufp->code;
-                ByteCount actual_input_length, actual_output_length;
-                unsigned char outch;
-                  
-                convert_status = TECConvertText (converter, &ch, 1,
+             } 
+           
+           if (the_err == noErr)
+             {
+               unsigned char ch = bufp->code;
+               ByteCount actual_input_length, actual_output_length;
+               unsigned char outch;
+               
+               convert_status = TECConvertText (converter, &ch, 1,
                                                 &actual_input_length,
-                                                 &outch, 1,
+                                                &outch, 1,
                                                 &actual_output_length);
-                if (convert_status == noErr
+               if (convert_status == noErr
                    && actual_input_length == 1
                    && actual_output_length == 1)
-                  bufp->code = outch;
-              }
+                 bufp->code = outch;
+             }
          }
-
+       
 #if USE_CARBON_EVENTS
        bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
 #else
@@ -12995,7 +13019,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
            = (mac_output *) GetWRefCon (FrontNonFloatingWindow ());
          XSETFRAME (bufp->frame_or_window, mwp->mFP);
        }
-
+       
        bufp->timestamp = er.when * (1000 / 60);  /* ticks to milliseconds */
 
        count++;
@@ -13010,16 +13034,22 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
            constuct_drag_n_drop in w32term.c.  */
         if (!NILP (drag_and_drop_file_list))
           {
-            struct frame *f;
+            struct frame *f = NULL;
             WindowPtr wp;
             Lisp_Object frame;
 
-            wp = FrontWindow ();
-            if (!wp)
-              f = NULL;
-            else
-              f = ((mac_output *) GetWRefCon (wp))->mFP;            
-            
+            wp = FrontNonFloatingWindow ();
+           
+           if (!wp)
+             {
+               struct frame *f = XFRAME (XCAR (Vframe_list));
+               CollapseWindow (FRAME_MAC_WINDOW (f), false);
+               wp = FrontNonFloatingWindow ();
+             }
+
+            if (wp && is_emacs_window(wp))
+               f = ((mac_output *) GetWRefCon (wp))->mFP;            
+
             bufp->kind = DRAG_N_DROP_EVENT;
             bufp->code = 0;
             bufp->timestamp = er.when * (1000 / 60);
@@ -13190,11 +13220,14 @@ NewMacWindow (FRAME_PTR fp)
 }
 
 
-void make_mac_frame (struct frame *f)
+void
+make_mac_frame (struct frame *f)
 {
   FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
   FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_right;
-  
+
+  FRAME_DESIRED_CURSOR (f) = FILLED_BOX_CURSOR;
   NewMacWindow(f);
 
   f->output_data.mac->cursor_pixel = 0;
@@ -13202,8 +13235,6 @@ void make_mac_frame (struct frame *f)
   f->output_data.mac->mouse_pixel = 0xff00ff;
   f->output_data.mac->cursor_foreground_pixel = 0x0000ff;
 
-  f->output_data.mac->desired_cursor = FILLED_BOX_CURSOR;
-
   f->output_data.mac->fontset = -1;
   f->output_data.mac->scroll_bar_foreground_pixel = -1;
   f->output_data.mac->scroll_bar_background_pixel = -1;
@@ -13223,7 +13254,8 @@ void make_mac_frame (struct frame *f)
   f->new_height = 0;
 }
 
-void make_mac_terminal_frame (struct frame *f)
+void
+make_mac_terminal_frame (struct frame *f)
 {
   Lisp_Object frame;
 
@@ -13405,6 +13437,136 @@ mac_term_init (display_name, xrm_option, resource_name)
   return dpyinfo;
 }
 \f
+#ifdef MAC_OSX
+void
+mac_check_bundle()
+{
+  extern int inhibit_window_system;
+  extern int noninteractive;
+  CFBundleRef appsBundle;
+  pid_t child;
+
+  /* No need to test if already -nw*/
+  if (inhibit_window_system || noninteractive)
+    return;
+
+  appsBundle = CFBundleGetMainBundle();
+  if (appsBundle != NULL)
+    {
+      CFStringRef cfBI = CFSTR("CFBundleIdentifier");
+      CFTypeRef res = CFBundleGetValueForInfoDictionaryKey(appsBundle, cfBI);
+      /* We found the bundle identifier, now we know we are valid. */
+      if (res != NULL)
+       {
+         CFRelease(res);
+         return;
+       }
+    }
+  /* MAC_TODO:  Have this start the bundled executable */
+
+  /* For now, prevent the fatal error by bringing it up in the terminal */
+  inhibit_window_system = 1;
+}
+
+void
+MakeMeTheFrontProcess ()
+{
+  ProcessSerialNumber psn;
+  OSErr err;
+  
+  err = GetCurrentProcess (&psn);
+  if (err == noErr)
+    (void) SetFrontProcess (&psn);
+}
+
+/***** Code to handle C-g testing  *****/
+
+/* Contains the Mac modifier formed from quit_char */
+static mac_quit_char_modifiers = 0;
+static mac_quit_char_keycode;
+extern int quit_char;
+
+static void
+mac_determine_quit_char_modifiers()
+{
+  /* Todo: Determine modifiers from quit_char. */
+  UInt32 qc_modifiers = ctrl_modifier;
+
+  /* Map modifiers */
+  mac_quit_char_modifiers = 0;
+  if (qc_modifiers & ctrl_modifier)  mac_quit_char_modifiers |= macCtrlKey;
+  if (qc_modifiers & shift_modifier) mac_quit_char_modifiers |= macShiftKey;
+  if (qc_modifiers & meta_modifier)  mac_quit_char_modifiers |= macMetaKey;
+  if (qc_modifiers & alt_modifier)   mac_quit_char_modifiers |= macAltKey;
+}
+
+static void
+init_quit_char_handler ()
+{
+  /* TODO: Let this support keys other the 'g' */
+  mac_quit_char_keycode = 5;
+  /* Look at <architecture/adb_kb_map.h> for details */
+  /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
+  
+  mac_determine_quit_char_modifiers();
+}
+
+static Boolean
+quit_char_comp (EventRef inEvent, void *inCompData)
+{
+  if (GetEventClass(inEvent) != kEventClassKeyboard)
+    return false;
+  if (GetEventKind(inEvent) != kEventRawKeyDown)
+    return false;
+  {
+    UInt32 keyCode;
+    UInt32 keyModifiers;
+    GetEventParameter(inEvent, kEventParamKeyCode, 
+                     typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
+    if (keyCode != mac_quit_char_keycode)
+      return false;
+    GetEventParameter(inEvent, kEventParamKeyModifiers, 
+                     typeUInt32, NULL, sizeof(UInt32), NULL, &keyModifiers);
+    if (keyModifiers != mac_quit_char_modifiers)
+      return false;
+  }
+  return true;
+}
+
+void
+mac_check_for_quit_char()
+{
+  EventRef event;
+  /* If windows are not initialized, return immediately (keep it bouncin')*/
+  if (!mac_quit_char_modifiers)
+    return;
+
+  /* Redetermine modifiers because they are based on lisp variables */
+  mac_determine_quit_char_modifiers();
+
+  /* Fill the queue with events */
+  ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &event);
+  event = FindSpecificEventInQueue (GetMainEventQueue(), quit_char_comp, NULL);
+  if (event) 
+    {
+      struct input_event e;
+      struct mac_output *mwp = (mac_output*) GetWRefCon (FrontNonFloatingWindow ());
+      /* Use an input_event to emulate what the interrupt handler does. */
+      e.kind = ASCII_KEYSTROKE_EVENT;
+      e.code = quit_char;
+      e.arg = NULL;
+      e.modifiers = NULL;
+      e.timestamp = EventTimeToTicks(GetEventTime(event))*(1000/60);
+      XSETFRAME(e.frame_or_window, mwp->mFP);
+      /* Remove event from queue to prevent looping. */
+      RemoveEventFromQueue(GetMainEventQueue(), event);
+      ReleaseEvent(event);
+      kbd_buffer_store_event(&e);
+    }
+}
+
+#endif /* MAC_OSX */
+
 /* Set up use of X before we make the first connection.  */
 
 static struct redisplay_interface x_redisplay_interface =
@@ -13511,9 +13673,14 @@ mac_initialize ()
 
 #if USE_CARBON_EVENTS
   init_service_handler ();
+
+  init_quit_char_handler ();
 #endif
 
   DisableMenuCommand (NULL, kHICommandQuit);
+
+  if (!inhibit_window_system)
+    MakeMeTheFrontProcess ();
 #endif
 }
 
@@ -13593,7 +13760,17 @@ Otherwise the option key is used.  */);
    doc: /* Non-nil means that the wheel button will be treated as mouse-2 and
 the right click will be mouse-3.
 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
-  Vmac_wheel_button_is_mouse_2 = Qt;
+  Vmac_wheel_button_is_mouse_2 = Qnil;
+
+  DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system,
+   doc: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
+Toolbox for processing before Emacs sees it.  */);
+  Vmac_pass_command_to_system = Qt;
+
+  DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system,
+   doc: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
+Toolbox for processing before Emacs sees it.  */);
+  Vmac_pass_control_to_system = Qt;
 #endif
 
   DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding,