]> code.delx.au - gnu-emacs/blobdiff - src/macterm.c
(re_match_2_internal): Correct matching of eight bit
[gnu-emacs] / src / macterm.c
index 654afcf6b1ab4abe037e7d7bad0842ff2df90776..842e1844f50244260813802d1249a44e4f0324c0 100644 (file)
@@ -1,6 +1,6 @@
 /* Implementation of GUI terminal on the Mac OS.
    Copyright (C) 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006, 2007 Free Software Foundation, Inc.
+                 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -228,14 +228,14 @@ void x_raise_frame P_ ((struct frame *));
 void x_set_window_size P_ ((struct frame *, int, int, int));
 void x_wm_set_window_state P_ ((struct frame *, int));
 void x_wm_set_icon_pixmap P_ ((struct frame *, int));
-void mac_initialize P_ ((void));
+static 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 *));
 static void x_update_end P_ ((struct frame *));
 static void XTframe_up_to_date P_ ((struct frame *));
-static void XTset_terminal_modes P_ ((void));
-static void XTreset_terminal_modes P_ ((void));
-static void x_clear_frame P_ ((void));
+static void XTset_terminal_modes P_ ((struct terminal *));
+static void XTreset_terminal_modes P_ ((struct terminal *));
+static void x_clear_frame P_ ((struct frame *));
 static void frame_highlight P_ ((struct frame *));
 static void frame_unhighlight P_ ((struct frame *));
 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
@@ -263,6 +263,8 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
 static int is_emacs_window P_ ((WindowRef));
 static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
 static void XSetFont P_ ((Display *, GC, XFontStruct *));
+static struct terminal *mac_create_terminal P_ ((struct mac_display_info *dpyinfo));
+
 
 #define GC_FORE_COLOR(gc)      (&(gc)->fore_color)
 #define GC_BACK_COLOR(gc)      (&(gc)->back_color)
@@ -2360,6 +2362,9 @@ mac_define_fringe_bitmap (which, bits, h, wd)
 
   for (i = 0; i < h; i++)
     bits[i] = ~bits[i];
+
+  BLOCK_INPUT;
+
   provider = CGDataProviderCreateWithData (NULL, bits,
                                           sizeof (unsigned short) * h, NULL);
   if (provider)
@@ -2369,6 +2374,8 @@ mac_define_fringe_bitmap (which, bits, h, wd)
                                             provider, NULL, 0);
       CGDataProviderRelease (provider);
     }
+
+  UNBLOCK_INPUT;
 }
 
 static void
@@ -2379,7 +2386,11 @@ mac_destroy_fringe_bitmap (which)
     return;
 
   if (fringe_bmp[which])
-    CGImageRelease (fringe_bmp[which]);
+    {
+      BLOCK_INPUT;
+      CGImageRelease (fringe_bmp[which]);
+      UNBLOCK_INPUT;
+    }
   fringe_bmp[which] = 0;
 }
 #endif
@@ -2391,7 +2402,7 @@ mac_destroy_fringe_bitmap (which)
    rarely happens).  */
 
 static void
-XTset_terminal_modes ()
+XTset_terminal_modes (struct terminal *t)
 {
 }
 
@@ -2399,7 +2410,7 @@ XTset_terminal_modes ()
    the windows go away, and suspending requires no action.  */
 
 static void
-XTreset_terminal_modes ()
+XTreset_terminal_modes (struct terminal *t)
 {
 }
 
@@ -2959,7 +2970,7 @@ x_draw_glyph_string_foreground (s)
      of S to the right of that box line.  */
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p)
-    x = s->x + abs (s->face->box_line_width);
+    x = s->x + eabs (s->face->box_line_width);
   else
     x = s->x;
 
@@ -3038,7 +3049,7 @@ x_draw_composite_glyph_string_foreground (s)
      of S to the right of that box line.  */
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p)
-    x = s->x + abs (s->face->box_line_width);
+    x = s->x + eabs (s->face->box_line_width);
   else
     x = s->x;
 
@@ -3058,10 +3069,17 @@ x_draw_composite_glyph_string_foreground (s)
   else
     {
       for (i = 0; i < s->nchars; i++, ++s->gidx)
-       mac_draw_image_string_16 (s->f, s->gc,
-                                 x + s->cmp->offsets[s->gidx * 2],
-                                 s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
-                                 s->char2b + i, 1, 0, s->face->overstrike);
+       if (mac_per_char_metric (GC_FONT (s->gc), s->char2b + i, 0) == NULL)
+         /* This is a nonexistent or zero-width glyph such as a
+            combining diacritic.  Draw a rectangle.  */
+         mac_draw_rectangle (s->f, s->gc,
+                             x + s->cmp->offsets[s->gidx * 2], s->y,
+                             FONT_WIDTH (GC_FONT (s->gc)) - 1, s->height - 1);
+       else
+         mac_draw_image_string_16 (s->f, s->gc,
+                                   x + s->cmp->offsets[s->gidx * 2],
+                                   s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
+                                   s->char2b + i, 1, 0, s->face->overstrike);
     }
 }
 
@@ -3526,7 +3544,7 @@ x_draw_glyph_string_box (s)
                ? s->first_glyph
                : s->first_glyph + s->nchars - 1);
 
-  width = abs (s->face->box_line_width);
+  width = eabs (s->face->box_line_width);
   raised_p = s->face->box == FACE_RAISED_BOX;
   left_x = s->x;
   right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
@@ -3572,7 +3590,7 @@ x_draw_image_foreground (s)
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p
       && s->slice.x == 0)
-    x += abs (s->face->box_line_width);
+    x += eabs (s->face->box_line_width);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
@@ -3645,7 +3663,7 @@ x_draw_image_relief (s)
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p
       && s->slice.x == 0)
-    x += abs (s->face->box_line_width);
+    x += eabs (s->face->box_line_width);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
@@ -3662,7 +3680,7 @@ x_draw_image_relief (s)
     }
   else
     {
-      thick = abs (s->img->relief);
+      thick = eabs (s->img->relief);
       raised_p = s->img->relief > 0;
     }
 
@@ -3723,7 +3741,7 @@ x_draw_image_glyph_string (s)
      struct glyph_string *s;
 {
   int x, y;
-  int box_line_hwidth = abs (s->face->box_line_width);
+  int box_line_hwidth = eabs (s->face->box_line_width);
   int box_line_vwidth = max (s->face->box_line_width, 0);
   int height;
 
@@ -3773,7 +3791,6 @@ x_draw_stretch_glyph_string (s)
      struct glyph_string *s;
 {
   xassert (s->first_glyph->type == STRETCH_GLYPH);
-  s->stippled_p = s->face->stipple != 0;
 
   if (s->hl == DRAW_CURSOR
       && !x_stretch_cursor_p)
@@ -4042,15 +4059,8 @@ x_delete_glyphs (n)
    frame.  Otherwise clear the selected frame.  */
 
 static void
-x_clear_frame ()
+x_clear_frame (struct frame *f)
 {
-  struct frame *f;
-
-  if (updating_frame)
-    f = updating_frame;
-  else
-    f = SELECTED_FRAME ();
-
   /* Clearing the frame will erase any cursor, so mark them all as no
      longer visible.  */
   mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
@@ -4568,7 +4578,7 @@ note_mouse_movement (frame, pos)
       clear_mouse_face (dpyinfo);
       dpyinfo->mouse_face_mouse_frame = 0;
       if (!dpyinfo->grabbed)
-       rif->define_frame_cursor (frame,
+       FRAME_RIF (frame)->define_frame_cursor (frame,
                                  frame->output_data.mac->nontext_cursor);
     }
 
@@ -5061,6 +5071,7 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
 #ifdef MAC_OSX
   bar->fringe_extended_p = Qnil;
 #endif
+  bar->redraw_needed_p = Qnil;
 #ifdef USE_TOOLKIT_SCROLL_BARS
   bar->track_top = Qnil;
   bar->track_height = Qnil;
@@ -5277,14 +5288,24 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
       BLOCK_INPUT;
 
       /* If already correctly positioned, do nothing.  */
-      if (!(XINT (bar->left) == sb_left
-           && XINT (bar->top) == top
-           && XINT (bar->width) == sb_width
-           && XINT (bar->height) == height
+      if (XINT (bar->left) == sb_left
+         && XINT (bar->top) == top
+         && XINT (bar->width) == sb_width
+         && XINT (bar->height) == height
 #ifdef MAC_OSX
-           && !NILP (bar->fringe_extended_p) == fringe_extended_p
+         && !NILP (bar->fringe_extended_p) == fringe_extended_p
 #endif
-           ))
+         )
+       {
+         if (!NILP (bar->redraw_needed_p))
+           {
+#if USE_CG_DRAWING
+             mac_prepare_for_quickdraw (f);
+#endif
+             Draw1Control (SCROLL_BAR_CONTROL_REF (bar));
+           }
+       }
+      else
        {
          /* Since toolkit scroll bars are smaller than the space reserved
             for them on the frame, we have to clear "under" them.  */
@@ -5326,6 +5347,8 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
   bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
 #endif
 
+  bar->redraw_needed_p = Qnil;
+
 #ifdef USE_TOOLKIT_SCROLL_BARS
   if (NILP (bar->track_top))
     {
@@ -5683,8 +5706,15 @@ void
 x_scroll_bar_clear (f)
      FRAME_PTR f;
 {
-  XTcondemn_scroll_bars (f);
-  XTjudge_scroll_bars (f);
+  Lisp_Object bar;
+
+  /* We can have scroll bars even if this is 0,
+     if we just turned off scroll bar mode.
+     But in that case we should not clear them.  */
+  if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+    for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
+        bar = XSCROLL_BAR (bar)->next)
+      XSCROLL_BAR (bar)->redraw_needed_p = Qt;
 }
 
 \f
@@ -8289,7 +8319,7 @@ init_font_name_table ()
          Lisp_Object rest = XCDR (XCDR (text_encoding_info));
 
          if (size > 0 || style == normal)
-           for (; !NILP (rest); rest = XCDR (rest))
+           for (; CONSP (rest); rest = XCDR (rest))
              add_mac_font_name (name, size, style, SDATA (XCAR (rest)));
        }
     }
@@ -8364,7 +8394,7 @@ init_font_name_table ()
                {
                  Lisp_Object rest = XCDR (XCDR (text_encoding_info));
 
-                 for (; !NILP (rest); rest = XCDR (rest))
+                 for (; CONSP (rest); rest = XCDR (rest))
                    add_mac_font_name (name, assc_entry->fontSize,
                                       assc_entry->fontStyle,
                                       SDATA (XCAR (rest)));
@@ -8774,7 +8804,7 @@ mac_load_query_font (f, fontname)
 
       font_id = atsu_find_font_from_family_name (family);
       if (font_id == kATSUInvalidFontID)
-       return;
+       return NULL;
       size_fixed = Long2Fix (size);
       bold_p = (fontface & bold) != 0;
       italic_p = (fontface & italic) != 0;
@@ -12167,7 +12197,13 @@ XTread_socket (sd, expected, hold_quit)
                             will be selected only when it is active.  */
                          if (WINDOWP (window)
                              && !EQ (window, last_window)
-                             && !EQ (window, selected_window))
+                             && !EQ (window, selected_window)
+                             /* For click-to-focus window managers
+                                create event iff we don't leave the
+                                selected frame.  */
+                             && (focus_follows_mouse
+                                 || (EQ (XWINDOW (window)->frame,
+                                         XWINDOW (selected_window)->frame))))
                            {
                              inev.kind = SELECT_WINDOW_EVENT;
                              inev.frame_or_window = window;
@@ -12545,6 +12581,7 @@ mac_term_init (display_name, xrm_option, resource_name)
      char *resource_name;
 {
   struct mac_display_info *dpyinfo;
+  struct terminal *terminal;
 
   BLOCK_INPUT;
 
@@ -12560,6 +12597,13 @@ mac_term_init (display_name, xrm_option, resource_name)
   dpyinfo = &one_mac_display_info;
   bzero (dpyinfo, sizeof (*dpyinfo));
 
+  terminal = mac_create_terminal (dpyinfo);
+
+  /* Set the name of the terminal. */
+  terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
+  strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
+  terminal->name[SBYTES (display_name)] = 0;
+
 #ifdef MAC_OSX
   dpyinfo->mac_id_name
     = (char *) xmalloc (SCHARS (Vinvocation_name)
@@ -12580,7 +12624,7 @@ mac_term_init (display_name, xrm_option, resource_name)
 
   dpyinfo->grabbed = 0;
   dpyinfo->root_window = NULL;
-  dpyinfo->image_cache = make_image_cache ();
+  dpyinfo->terminal->image_cache = make_image_cache ();
 
   dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
   dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
@@ -12601,6 +12645,14 @@ mac_term_init (display_name, xrm_option, resource_name)
                                x_display_name_list);
   dpyinfo->name_list_element = XCAR (x_display_name_list);
 
+  /* FIXME: Untested.
+     Add the default keyboard. */
+  add_keyboard_wait_descriptor (0);
+
+#if USE_CG_DRAWING
+  mac_init_fringe (terminal->rif);
+#endif
+
   UNBLOCK_INPUT;
 
   return dpyinfo;
@@ -12761,44 +12813,90 @@ static struct redisplay_interface x_redisplay_interface =
   mac_shift_glyphs_for_insert
 };
 
-void
+static struct terminal *
+mac_create_terminal (struct mac_display_info *dpyinfo)
+{
+  struct terminal *terminal;
+  
+  terminal = create_terminal ();
+
+  terminal->type = output_mac;
+  terminal->display_info.mac = dpyinfo;
+  dpyinfo->terminal = terminal;
+
+  terminal->clear_frame_hook = x_clear_frame;
+  terminal->ins_del_lines_hook = x_ins_del_lines;
+  terminal->delete_glyphs_hook = x_delete_glyphs;
+  terminal->ring_bell_hook = XTring_bell;
+  terminal->reset_terminal_modes_hook = XTreset_terminal_modes;
+  terminal->set_terminal_modes_hook = XTset_terminal_modes;
+  terminal->update_begin_hook = x_update_begin;
+  terminal->update_end_hook = x_update_end;
+  terminal->set_terminal_window_hook = XTset_terminal_window;
+  terminal->read_socket_hook = XTread_socket;
+  terminal->frame_up_to_date_hook = XTframe_up_to_date;
+  terminal->mouse_position_hook = XTmouse_position;
+  terminal->frame_rehighlight_hook = XTframe_rehighlight;
+  terminal->frame_raise_lower_hook = XTframe_raise_lower;
+  /* terminal->fullscreen_hook = XTfullscreen_hook; */
+  terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
+  terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
+  terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
+  terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
+  terminal->delete_frame_hook = x_destroy_window;
+  /* terminal->delete_terminal_hook = x_delete_terminal; */
+
+  terminal->rif = &x_redisplay_interface;
+#if 0
+  TTY_SCROLL_REGION_OK (CURTTY ()) = 1; /* we'll scroll partial frames */
+  TTY_CHAR_INS_DEL_OK (CURTTY ()) = 1;
+  TTY_LINE_INS_DEL_OK (CURTTY ()) = 1; /* we'll just blt 'em */
+  TTY_FAST_CLEAR_END_OF_LINE (CURTTY ()) = 1; /* X does this well */
+  TTY_MEMORY_BELOW_FRAME (CURTTY ()) = 0; /* we don't remember what
+                                                         scrolls off the
+                                                         bottom */
+#else
+  terminal->scroll_region_ok = 1;    /* We'll scroll partial frames. */
+  terminal->char_ins_del_ok = 1;
+  terminal->line_ins_del_ok = 1;         /* We'll just blt 'em. */
+  terminal->fast_clear_end_of_line = 1;  /* X does this well. */
+  terminal->memory_below_frame = 0;   /* We don't remember what scrolls
+                                        off the bottom. */
+
+#endif
+
+  /* FIXME: This keyboard setup is 100% untested, just copied from
+     w32_create_terminal in order to set window-system now that it's
+     a keyboard object.  */
+  /* We don't yet support separate terminals on Mac, so don't try to share
+     keyboards between virtual terminals that are on the same physical
+     terminal like X does.  */
+  terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+  init_kboard (terminal->kboard);
+  terminal->kboard->Vwindow_system = intern ("mac");
+  terminal->kboard->next_kboard = all_kboards;
+  all_kboards = terminal->kboard;
+  /* Don't let the initial kboard remain current longer than necessary.
+     That would cause problems if a file loaded on startup tries to
+     prompt in the mini-buffer.  */
+  if (current_kboard == initial_kboard)
+    current_kboard = terminal->kboard;
+  terminal->kboard->reference_count++;
+
+  return terminal;
+}
+
+static void
 mac_initialize ()
 {
-  rif = &x_redisplay_interface;
-
-  clear_frame_hook = x_clear_frame;
-  ins_del_lines_hook = x_ins_del_lines;
-  delete_glyphs_hook = x_delete_glyphs;
-  ring_bell_hook = XTring_bell;
-  reset_terminal_modes_hook = XTreset_terminal_modes;
-  set_terminal_modes_hook = XTset_terminal_modes;
-  update_begin_hook = x_update_begin;
-  update_end_hook = x_update_end;
-  set_terminal_window_hook = XTset_terminal_window;
-  read_socket_hook = XTread_socket;
-  frame_up_to_date_hook = XTframe_up_to_date;
-  mouse_position_hook = XTmouse_position;
-  frame_rehighlight_hook = XTframe_rehighlight;
-  frame_raise_lower_hook = XTframe_raise_lower;
-
-  set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
-  condemn_scroll_bars_hook = XTcondemn_scroll_bars;
-  redeem_scroll_bar_hook = XTredeem_scroll_bar;
-  judge_scroll_bars_hook = XTjudge_scroll_bars;
-
-  scroll_region_ok = 1;         /* we'll scroll partial frames */
-  char_ins_del_ok = 1;
-  line_ins_del_ok = 1;          /* we'll just blt 'em */
-  fast_clear_end_of_line = 1;   /* X does this well */
-  memory_below_frame = 0;       /* we don't remember what scrolls
-                                  off the bottom */
+
   baud_rate = 19200;
 
   last_tool_bar_item = -1;
   any_help_event_p = 0;
 
   /* Try to use interrupt input; if we can't, then start polling.  */
-  Fset_input_mode (Qt, Qnil, Qt, Qnil);
+  Fset_input_interrupt_mode (Qt);
 
   BLOCK_INPUT;
 
@@ -12830,11 +12928,10 @@ mac_initialize ()
 
 #if USE_CG_DRAWING
   init_cg_color ();
-
-  mac_init_fringe ();
 #endif
 
   UNBLOCK_INPUT;
+
 }