]> code.delx.au - gnu-emacs/blobdiff - src/macterm.c
Merged in changes from CVS HEAD
[gnu-emacs] / src / macterm.c
index 8ef25e438564069e13db4e8f559a6eaf77dc5db3..8bcee4a86c3aefaeefcbce1c5378a50230bd6197 100644 (file)
@@ -1,5 +1,5 @@
 /* Implementation of GUI terminal on the Mac OS.
-   Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -467,15 +467,21 @@ XClearWindow (display, w)
 /* Mac replacement for XCopyArea.  */
 
 static void
-mac_draw_bitmap (display, w, gc, x, y, bitmap)
+mac_draw_bitmap (display, w, gc, x, y, width, height, bits, overlay_p)
      Display *display;
      WindowPtr w;
      GC gc;
-     int x, y;
-     BitMap *bitmap;
+     int x, y, width, height;
+     unsigned short *bits;
+     int overlay_p;
 {
+  BitMap bitmap;
   Rect r;
 
+  bitmap.rowBytes = sizeof(unsigned short);
+  bitmap.baseAddr = bits;
+  SetRect (&(bitmap.bounds), 0, 0, width, height);
+
 #if TARGET_API_MAC_CARBON
   SetPort (GetWindowPort (w));
 #else
@@ -483,7 +489,7 @@ mac_draw_bitmap (display, w, gc, x, y, bitmap)
 #endif
 
   mac_set_colors (gc);
-  SetRect (&r, x, y, x + bitmap->bounds.right, y + bitmap->bounds.bottom);
+  SetRect (&r, x, y, x + bitmap.bounds.right, y + bitmap.bounds.bottom);
 
 #if TARGET_API_MAC_CARBON
   {
@@ -491,11 +497,13 @@ mac_draw_bitmap (display, w, gc, x, y, bitmap)
 
     LockPortBits (GetWindowPort (w));
     pmh = GetPortPixMap (GetWindowPort (w));
-    CopyBits (bitmap, (BitMap *) *pmh, &(bitmap->bounds), &r, srcCopy, 0);
+    CopyBits (&bitmap, (BitMap *) *pmh, &(bitmap.bounds), &r,
+             overlay_p ? srcOr : srcCopy, 0);
     UnlockPortBits (GetWindowPort (w));
   }
 #else /* not TARGET_API_MAC_CARBON */
-  CopyBits (bitmap, &(w->portBits), &(bitmap->bounds), &r, srcCopy, 0);
+  CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r,
+           overlay_p ? srcOr : srcCopy, 0);
 #endif /* not TARGET_API_MAC_CARBON */
 }
 
@@ -1143,6 +1151,9 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
                                output_cursor.x, output_cursor.y);
 
       x_draw_vertical_border (w);
+
+      draw_window_fringes (w);
+
       UNBLOCK_INPUT;
     }
 
@@ -1239,11 +1250,7 @@ x_after_update_window_line (desired_row)
   xassert (w);
 
   if (!desired_row->mode_line_p && !w->pseudo_window_p)
-    {
-      BLOCK_INPUT;
-      draw_row_fringe_bitmaps (w, desired_row);
-      UNBLOCK_INPUT;
-    }
+    desired_row->redraw_fringe_bitmaps_p = 1;
 
   /* When a window has disappeared, make sure that no rest of
      full-width rows stays visible in the internal border.  Could
@@ -1295,11 +1302,26 @@ x_draw_fringe_bitmap (w, row, p)
   XGCValues gcv;
   GC gc = f->output_data.mac->normal_gc;
   struct face *face = p->face;
+  int rowY;
 
   /* Must clip because of partially visible lines.  */
-  x_clip_to_row (w, row, gc);
+  rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
+  if (p->y < rowY)
+    {
+      /* Adjust position of "bottom aligned" bitmap on partially
+        visible last row.  */
+      int oldY = row->y;
+      int oldVH = row->visible_height;
+      row->visible_height = p->h;
+      row->y -= rowY - p->y;
+      x_clip_to_row (w, row, gc);
+      row->y = oldY;
+      row->visible_height = oldVH;
+    }
+  else
+    x_clip_to_row (w, row, gc);
 
-  if (p->bx >= 0)
+  if (p->bx >= 0 && !p->overlay_p)
     {
       XGCValues gcv;
       gcv.foreground = face->background;
@@ -1325,18 +1347,18 @@ x_draw_fringe_bitmap (w, row, p)
 #endif
     }
 
-  if (p->which != NO_FRINGE_BITMAP)
+  if (p->which)
     {
-      unsigned char *bits = fringe_bitmaps[p->which].bits + p->dh;
-      BitMap bitmap;
+      unsigned short *bits = p->bits + p->dh;
 
-      mac_create_bitmap_from_bitmap_data (&bitmap, bits, p->wd, p->h);
-      gcv.foreground = face->foreground;
+      gcv.foreground = (p->cursor_p
+                       ? (p->overlay_p ? face->background
+                          : f->output_data.mac->cursor_pixel)
+                       : face->foreground);
       gcv.background = face->background;
 
-      mac_draw_bitmap (display, window, &gcv, p->x, p->y, &bitmap);
-
-      mac_free_bitmap (&bitmap);
+      mac_draw_bitmap (display, window, &gcv, p->x, p->y, 
+                      p->wd, p->h, bits, p->overlay_p);
     }
 
   mac_reset_clipping (display, window);
@@ -4546,6 +4568,14 @@ mac_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
       w->phys_cursor_width = cursor_width;
       w->phys_cursor_on_p = 1;
 
+      if (glyph_row->exact_window_width_line_p
+         && w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])
+       {
+         glyph_row->cursor_in_fringe_p = 1;
+         draw_fringe_bitmap (w, glyph_row, 0);
+         return;
+       }
+
       switch (cursor_type)
        {
        case HOLLOW_BOX_CURSOR:
@@ -6372,81 +6402,6 @@ x_find_ccl_program (fontp)
 
 
 \f
-/***********************************************************************
-                           Initialization
- ***********************************************************************/
-
-#ifdef USE_X_TOOLKIT
-static XrmOptionDescRec emacs_options[] = {
-  {"-geometry",        ".geometry", XrmoptionSepArg, NULL},
-  {"-iconic",  ".iconic", XrmoptionNoArg, (XtPointer) "yes"},
-
-  {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
-     XrmoptionSepArg, NULL},
-  {"-ib",      "*EmacsScreen.internalBorderWidth", XrmoptionSepArg, NULL},
-
-  {"-T",       "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
-  {"-wn",      "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
-  {"-title",   "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
-  {"-iconname",        "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
-  {"-in",      "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
-  {"-mc",      "*pointerColor", XrmoptionSepArg, (XtPointer) NULL},
-  {"-cr",      "*cursorColor", XrmoptionSepArg, (XtPointer) NULL}
-};
-#endif /* USE_X_TOOLKIT */
-
-static int x_initialized;
-
-#ifdef MULTI_KBOARD
-/* Test whether two display-name strings agree up to the dot that separates
-   the screen number from the server number.  */
-static int
-same_x_server (name1, name2)
-     char *name1, *name2;
-{
-  int seen_colon = 0;
-  unsigned char *system_name = SDATA (Vsystem_name);
-  int system_name_length = strlen (system_name);
-  int length_until_period = 0;
-
-  while (system_name[length_until_period] != 0
-        && system_name[length_until_period] != '.')
-    length_until_period++;
-
-  /* Treat `unix' like an empty host name.  */
-  if (! strncmp (name1, "unix:", 5))
-    name1 += 4;
-  if (! strncmp (name2, "unix:", 5))
-    name2 += 4;
-  /* Treat this host's name like an empty host name.  */
-  if (! strncmp (name1, system_name, system_name_length)
-      && name1[system_name_length] == ':')
-    name1 += system_name_length;
-  if (! strncmp (name2, system_name, system_name_length)
-      && name2[system_name_length] == ':')
-    name2 += system_name_length;
-  /* Treat this host's domainless name like an empty host name.  */
-  if (! strncmp (name1, system_name, length_until_period)
-      && name1[length_until_period] == ':')
-    name1 += length_until_period;
-  if (! strncmp (name2, system_name, length_until_period)
-      && name2[length_until_period] == ':')
-    name2 += length_until_period;
-
-  for (; *name1 != '\0' && *name1 == *name2; name1++, name2++)
-    {
-      if (*name1 == ':')
-       seen_colon++;
-      if (seen_colon && *name1 == '.')
-       return 1;
-    }
-  return (seen_colon
-         && (*name1 == '.' || *name1 == '\0')
-         && (*name2 == '.' || *name2 == '\0'));
-}
-#endif
-
-
 /* The Mac Event loop code */
 
 #ifndef MAC_OSX
@@ -6508,12 +6463,19 @@ static long app_sleep_time = WNE_SLEEP_AT_RESUME;
 
 Boolean        terminate_flag = false;
 
+/* Contains the string "reverse", which is a constant for mouse button emu.*/
+Lisp_Object Qreverse;
+
 /* True if using command key as meta key.  */
 Lisp_Object Vmac_command_key_is_meta;
 
 /* True if the ctrl and meta keys should be reversed.  */
 Lisp_Object Vmac_reverse_ctrl_meta;
 
+/* True if the option and command modifiers should be used to emulate
+   a three button mouse */
+Lisp_Object Vmac_emulate_three_button_mouse;
+
 #if USE_CARBON_EVENTS
 /* True if the mouse wheel button (i.e. button 4) should map to
    mouse-2, instead of mouse-3.  */
@@ -6586,6 +6548,20 @@ mac_to_emacs_modifiers (EventModifiers mods)
   return result;
 }
 
+static int
+mac_get_emulated_btn ( UInt32 modifiers )
+{
+  int result = 0;
+  if (Vmac_emulate_three_button_mouse != Qnil) {
+    int cmdIs3 = (Vmac_emulate_three_button_mouse != Qreverse);
+    if (modifiers & controlKey)
+      result = cmdIs3 ? 2 : 1;
+    else if (modifiers & optionKey)
+      result = cmdIs3 ? 1 : 2;      
+  }
+  return result;
+}
+
 #if USE_CARBON_EVENTS
 /* Obtains the event modifiers from the event ref and then calls
    mac_to_emacs_modifiers.  */
@@ -6595,6 +6571,11 @@ mac_event_to_emacs_modifiers (EventRef eventRef)
   UInt32 mods = 0;
   GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
                    sizeof (UInt32), NULL, &mods);
+  if (Vmac_emulate_three_button_mouse != Qnil &&
+      GetEventClass(eventRef) == kEventClassMouse)
+    {
+      mods &= ~(optionKey & cmdKey);
+    }
   return mac_to_emacs_modifiers (mods);
 }
 
@@ -6609,7 +6590,14 @@ mac_get_mouse_btn (EventRef ref)
   switch (result)
     {
     case kEventMouseButtonPrimary:
-      return 0;
+      if (Vmac_emulate_three_button_mouse == Qnil) 
+       return 0;
+      else {
+       UInt32 mods = 0;
+       GetEventParameter (ref, kEventParamKeyModifiers, typeUInt32, NULL,
+                          sizeof (UInt32), NULL, &mods);
+       return mac_get_emulated_btn(mods);
+      }
     case kEventMouseButtonSecondary:
       return NILP (Vmac_wheel_button_is_mouse_2) ? 1 : 2;
     case kEventMouseButtonTertiary:
@@ -6718,8 +6706,8 @@ do_check_ram_size (void)
 
   if (Gestalt (gestaltPhysicalRAMSize, &physical_ram_size) != noErr
       || Gestalt (gestaltLogicalRAMSize, &logical_ram_size) != noErr
-      || physical_ram_size > 256 * 1024 * 1024
-      || logical_ram_size > 256 * 1024 * 1024)
+      || physical_ram_size > (1 << VALBITS)
+      || logical_ram_size > (1 << VALBITS))
     {
       StopAlert (RAM_TOO_LARGE_ALERT_ID, NULL);
       exit (1);
@@ -7518,7 +7506,9 @@ main (void)
 
   do_get_menus ();
 
+#ifndef USE_LSB_TAG
   do_check_ram_size ();
+#endif
 
   init_emacs_passwd_dir ();
 
@@ -7596,7 +7586,7 @@ keycode_to_xkeysym (int keyCode, int *xKeySym)
 /* Emacs calls this whenever it wants to read an input event from the
    user. */
 int
-XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
+XTread_socket (struct input_event *bufp, int numchars, int expected)
 {
   int count = 0;
 #if USE_CARBON_EVENTS
@@ -7743,7 +7733,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
 #if USE_CARBON_EVENTS
              bufp->code = mac_get_mouse_btn (eventRef);
 #else
-             bufp->code = 0;  /* only one mouse button */
+             bufp_.code = mac_get_emulate_btn (er.modifiers);
 #endif
               bufp->kind = SCROLL_BAR_CLICK_EVENT;
               bufp->frame_or_window = tracked_scroll_bar->window;
@@ -7811,7 +7801,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
 #if USE_CARBON_EVENTS
                  bufp->code = mac_get_mouse_btn (eventRef);
 #else
-                 bufp->code = 0;  /* only one mouse button */
+                 bufp_.code = mac_get_emulate_btn (er.modifiers);
 #endif
                  XSETINT (bufp->x, mouse_loc.h);
                  XSETINT (bufp->y, mouse_loc.v);
@@ -8256,9 +8246,6 @@ NewMacWindow (FRAME_PTR fp)
 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);
@@ -8307,6 +8294,9 @@ make_mac_terminal_frame (struct frame *f)
   FRAME_COLS (f) = 96;
   FRAME_LINES (f) = 4;
 
+  FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
+  FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_right;
+
   make_mac_frame (f);
 
   x_make_gc (f);
@@ -8330,74 +8320,6 @@ make_mac_terminal_frame (struct frame *f)
                            Initialization
  ***********************************************************************/
 
-#ifdef USE_X_TOOLKIT
-static XrmOptionDescRec emacs_options[] = {
-  {"-geometry",        ".geometry", XrmoptionSepArg, NULL},
-  {"-iconic",  ".iconic", XrmoptionNoArg, (XtPointer) "yes"},
-
-  {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
-     XrmoptionSepArg, NULL},
-  {"-ib",      "*EmacsScreen.internalBorderWidth", XrmoptionSepArg, NULL},
-
-  {"-T",       "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
-  {"-wn",      "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
-  {"-title",   "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
-  {"-iconname",        "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
-  {"-in",      "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
-  {"-mc",      "*pointerColor", XrmoptionSepArg, (XtPointer) NULL},
-  {"-cr",      "*cursorColor", XrmoptionSepArg, (XtPointer) NULL}
-};
-#endif /* USE_X_TOOLKIT */
-
-#ifdef MULTI_KBOARD
-/* Test whether two display-name strings agree up to the dot that separates
-   the screen number from the server number.  */
-static int
-same_x_server (name1, name2)
-     char *name1, *name2;
-{
-  int seen_colon = 0;
-  unsigned char *system_name = SDATA (Vsystem_name);
-  int system_name_length = strlen (system_name);
-  int length_until_period = 0;
-
-  while (system_name[length_until_period] != 0
-        && system_name[length_until_period] != '.')
-    length_until_period++;
-
-  /* Treat `unix' like an empty host name.  */
-  if (! strncmp (name1, "unix:", 5))
-    name1 += 4;
-  if (! strncmp (name2, "unix:", 5))
-    name2 += 4;
-  /* Treat this host's name like an empty host name.  */
-  if (! strncmp (name1, system_name, system_name_length)
-      && name1[system_name_length] == ':')
-    name1 += system_name_length;
-  if (! strncmp (name2, system_name, system_name_length)
-      && name2[system_name_length] == ':')
-    name2 += system_name_length;
-  /* Treat this host's domainless name like an empty host name.  */
-  if (! strncmp (name1, system_name, length_until_period)
-      && name1[length_until_period] == ':')
-    name1 += length_until_period;
-  if (! strncmp (name2, system_name, length_until_period)
-      && name2[length_until_period] == ':')
-    name2 += length_until_period;
-
-  for (; *name1 != '\0' && *name1 == *name2; name1++, name2++)
-    {
-      if (*name1 == ':')
-       seen_colon++;
-      if (seen_colon && *name1 == '.')
-       return 1;
-    }
-  return (seen_colon
-         && (*name1 == '.' || *name1 == '\0')
-         && (*name2 == '.' || *name2 == '\0'));
-}
-#endif
-
 int mac_initialized = 0;
 
 void
@@ -8636,6 +8558,8 @@ static struct redisplay_interface x_redisplay_interface =
   x_get_glyph_overhangs,
   x_fix_overlapping_area,
   x_draw_fringe_bitmap,
+  0, /* define_fringe_bitmap */
+  0, /* destroy_fringe_bitmap */
   mac_per_char_metric,
   mac_encode_char,
   NULL, /* mac_compute_glyph_string_overhangs */
@@ -8672,12 +8596,13 @@ mac_initialize ()
   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 */
+  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 */
   baud_rate = 19200;
 
   x_noop_count = 0;
@@ -8754,6 +8679,9 @@ syms_of_macterm ()
 
   Fprovide (intern ("mac-carbon"), Qnil);
 
+  staticpro (&Qreverse);
+  Qreverse = intern ("reverse");
+
   staticpro (&x_display_name_list);
   x_display_name_list = Qnil;
 
@@ -8798,6 +8726,17 @@ Otherwise the option key is used.  */);
            useful for non-standard keyboard layouts.  */);
   Vmac_reverse_ctrl_meta = Qnil;
 
+  DEFVAR_LISP ("mac-emulate-three-button-mouse", 
+              &Vmac_emulate_three_button_mouse,
+    doc: /* t means that when the option-key is held down while pressing the
+    mouse button, the click will register as mouse-2 and while the 
+    command-key is held down, the click will register as mouse-3.
+    'reverse means that the the option-key will register for mouse-3
+    and the command-key will register for mouse-2.  nil means that
+    not emulation should be done and the modifiers should be placed
+    on the mouse-1 event. */);
+  Vmac_emulate_three_button_mouse = Qnil;
+
 #if USE_CARBON_EVENTS
   DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2,
    doc: /* Non-nil means that the wheel button will be treated as mouse-2 and