*** empty log message ***
[bpt/emacs.git] / src / xterm.c
index 0dafcfb..609ffef 100644 (file)
@@ -1,6 +1,6 @@
 /* X Communication module for terminals which understand the X protocol.
-   Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 1999, 2000,01,02,03,04
-   Free Software Foundation, Inc.
+   Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+     2002, 2003, 2004, 2005  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -2127,15 +2127,9 @@ x_draw_glyph_string_box (s)
   struct glyph *last_glyph;
   XRectangle clip_rect;
 
-  last_x = window_box_right (s->w, s->area);
-  if (s->row->full_width_p
-      && !s->w->pseudo_window_p)
-    {
-      last_x += WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (s->w);
-      if (s->area != RIGHT_MARGIN_AREA
-         || WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w))
-       last_x += WINDOW_RIGHT_FRINGE_WIDTH (s->w);
-    }
+  last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
+           ? WINDOW_RIGHT_EDGE_X (s->w)
+           : window_box_right (s->w, s->area));
 
   /* The glyph that may have a right box line.  */
   last_glyph = (s->cmp || s->img
@@ -4329,7 +4323,7 @@ xg_scroll_callback (widget, data)
     }
 
   if (part >= 0)
-    { 
+    {
       window_being_scrolled = bar->window;
       last_scroll_bar_part = part;
       x_send_scroll_bar_event (bar->window, part, portion, whole);
@@ -5625,8 +5619,8 @@ static struct x_display_info *next_noop_dpyinfo;
            f->output_data.x->saved_menu_event                          \
             = (XEvent *) xmalloc (sizeof (XEvent));                    \
          bcopy (&event, f->output_data.x->saved_menu_event, size);     \
-        inev.kind = MENU_BAR_ACTIVATE_EVENT;                           \
-        XSETFRAME (inev.frame_or_window, f);                           \
+        inev.ie.kind = MENU_BAR_ACTIVATE_EVENT;                        \
+        XSETFRAME (inev.ie.frame_or_window, f);                        \
        }                                                               \
      while (0)
 
@@ -5733,7 +5727,10 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
      int *finish;
      struct input_event *hold_quit;
 {
-  struct input_event inev;
+  union {
+    struct input_event ie;
+    struct selection_input_event sie;
+  } inev;
   int count = 0;
   int do_help = 0;
   int nbytes = 0;
@@ -5743,9 +5740,9 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
 
   *finish = X_EVENT_NORMAL;
 
-  EVENT_INIT (inev);
-  inev.kind = NO_EVENT;
-  inev.arg = Qnil;
+  EVENT_INIT (inev.ie);
+  inev.ie.kind = NO_EVENT;
+  inev.ie.arg = Qnil;
 
   switch (event.type)
     {
@@ -5843,8 +5840,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                 if (!f)
                  goto OTHER; /* May be a dialog that is to be removed  */
 
-               inev.kind = DELETE_WINDOW_EVENT;
-               XSETFRAME (inev.frame_or_window, f);
+               inev.ie.kind = DELETE_WINDOW_EVENT;
+               XSETFRAME (inev.ie.frame_or_window, f);
                goto done;
               }
 
@@ -5907,7 +5904,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
         if (event.xclient.message_type
            == dpyinfo->Xatom_Scrollbar)
           {
-            x_scroll_bar_to_input_event (&event, &inev);
+            x_scroll_bar_to_input_event (&event, &inev.ie);
            *finish = X_EVENT_GOTO_OUT;
             goto done;
           }
@@ -5918,7 +5915,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
        if (!f)
          goto OTHER;
 
-       if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev))
+       if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev.ie))
          *finish = X_EVENT_DROP;
       }
       break;
@@ -5939,11 +5936,11 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
       {
         XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event;
 
-        inev.kind = SELECTION_CLEAR_EVENT;
-        SELECTION_EVENT_DISPLAY (&inev) = eventp->display;
-        SELECTION_EVENT_SELECTION (&inev) = eventp->selection;
-        SELECTION_EVENT_TIME (&inev) = eventp->time;
-        inev.frame_or_window = Qnil;
+        inev.ie.kind = SELECTION_CLEAR_EVENT;
+        SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display;
+        SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
+        SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
+        inev.ie.frame_or_window = Qnil;
       }
       break;
 
@@ -5956,14 +5953,14 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
           XSelectionRequestEvent *eventp
             = (XSelectionRequestEvent *) &event;
 
-          inev.kind = SELECTION_REQUEST_EVENT;
-          SELECTION_EVENT_DISPLAY (&inev) = eventp->display;
-          SELECTION_EVENT_REQUESTOR (&inev) = eventp->requestor;
-          SELECTION_EVENT_SELECTION (&inev) = eventp->selection;
-          SELECTION_EVENT_TARGET (&inev) = eventp->target;
-          SELECTION_EVENT_PROPERTY (&inev) = eventp->property;
-          SELECTION_EVENT_TIME (&inev) = eventp->time;
-          inev.frame_or_window = Qnil;
+          inev.ie.kind = SELECTION_REQUEST_EVENT;
+          SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display;
+          SELECTION_EVENT_REQUESTOR (&inev.sie) = eventp->requestor;
+          SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
+          SELECTION_EVENT_TARGET (&inev.sie) = eventp->target;
+          SELECTION_EVENT_PROPERTY (&inev.sie) = eventp->property;
+          SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
+          inev.ie.frame_or_window = Qnil;
       }
       break;
 
@@ -6102,8 +6099,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
             {
               f->async_iconified = 1;
 
-              inev.kind = ICONIFY_EVENT;
-              XSETFRAME (inev.frame_or_window, f);
+              inev.ie.kind = ICONIFY_EVENT;
+              XSETFRAME (inev.ie.frame_or_window, f);
             }
         }
       goto OTHER;
@@ -6135,8 +6132,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
 
           if (f->iconified)
             {
-              inev.kind = DEICONIFY_EVENT;
-              XSETFRAME (inev.frame_or_window, f);
+              inev.ie.kind = DEICONIFY_EVENT;
+              XSETFRAME (inev.ie.frame_or_window, f);
             }
           else if (! NILP (Vframe_list)
                    && ! NILP (XCDR (Vframe_list)))
@@ -6302,18 +6299,18 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
           orig_keysym = keysym;
 
          /* Common for all keysym input events.  */
-         XSETFRAME (inev.frame_or_window, f);
-         inev.modifiers
+         XSETFRAME (inev.ie.frame_or_window, f);
+         inev.ie.modifiers
            = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
-         inev.timestamp = event.xkey.time;
+         inev.ie.timestamp = event.xkey.time;
 
          /* First deal with keysyms which have defined
             translations to characters.  */
          if (keysym >= 32 && keysym < 128)
            /* Avoid explicitly decoding each ASCII character.  */
            {
-             inev.kind = ASCII_KEYSTROKE_EVENT;
-             inev.code = keysym;
+             inev.ie.kind = ASCII_KEYSTROKE_EVENT;
+             inev.ie.code = keysym;
              goto done_keysym;
            }
 
@@ -6323,10 +6320,10 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                                         Vx_keysym_table,
                                         Qnil))))
            {
-             inev.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
-                           ? ASCII_KEYSTROKE_EVENT
-                           : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
-             inev.code = XFASTINT (c);
+             inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
+                             ? ASCII_KEYSTROKE_EVENT
+                             : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+             inev.ie.code = XFASTINT (c);
              goto done_keysym;
            }
 
@@ -6416,8 +6413,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
              STORE_KEYSYM_FOR_DEBUG (keysym);
              /* make_lispy_event will convert this to a symbolic
                 key.  */
-             inev.kind = NON_ASCII_KEYSTROKE_EVENT;
-             inev.code = keysym;
+             inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
+             inev.ie.code = keysym;
              goto done_keysym;
            }
 
@@ -6468,18 +6465,18 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                else
                  c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
                                              nbytes - i, len);
-               inev.kind = (SINGLE_BYTE_CHAR_P (c)
+               inev.ie.kind = (SINGLE_BYTE_CHAR_P (c)
                              ? ASCII_KEYSTROKE_EVENT
                              : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
-               inev.code = c;
-               kbd_buffer_store_event_hold (&inev, hold_quit);
+               inev.ie.code = c;
+               kbd_buffer_store_event_hold (&inev.ie, hold_quit);
              }
 
            /* Previous code updated count by nchars rather than nbytes,
               but that seems bogus to me.  ++kfs  */
            count += nbytes;
 
-           inev.kind = NO_EVENT;  /* Already stored above.  */
+           inev.ie.kind = NO_EVENT;  /* Already stored above.  */
 
            if (keysym == NoSymbol)
              break;
@@ -6506,7 +6503,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
 #endif
 
     case EnterNotify:
-      x_detect_focus_change (dpyinfo, &event, &inev);
+      x_detect_focus_change (dpyinfo, &event, &inev.ie);
 
       f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
 
@@ -6536,11 +6533,11 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
       goto OTHER;
 
     case FocusIn:
-      x_detect_focus_change (dpyinfo, &event, &inev);
+      x_detect_focus_change (dpyinfo, &event, &inev.ie);
       goto OTHER;
 
     case LeaveNotify:
-      x_detect_focus_change (dpyinfo, &event, &inev);
+      x_detect_focus_change (dpyinfo, &event, &inev.ie);
 
       f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
       if (f)
@@ -6563,7 +6560,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
       goto OTHER;
 
     case FocusOut:
-      x_detect_focus_change (dpyinfo, &event, &inev);
+      x_detect_focus_change (dpyinfo, &event, &inev.ie);
       goto OTHER;
 
     case MotionNotify:
@@ -6603,8 +6600,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                     && !EQ (window, last_window)
                     && !EQ (window, selected_window))
                   {
-                    inev.kind = SELECT_WINDOW_EVENT;
-                    inev.frame_or_window = window;
+                    inev.ie.kind = SELECT_WINDOW_EVENT;
+                    inev.ie.frame_or_window = window;
                   }
 
                 last_window=window;
@@ -6763,13 +6760,13 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                              && (int)(event.xbutton.time - ignore_next_mouse_click_timeout) > 0)
                            {
                              ignore_next_mouse_click_timeout = 0;
-                             construct_mouse_click (&inev, &event, f);
+                             construct_mouse_click (&inev.ie, &event, f);
                            }
                          if (event.type == ButtonRelease)
                            ignore_next_mouse_click_timeout = 0;
                        }
                      else
-                       construct_mouse_click (&inev, &event, f);
+                       construct_mouse_click (&inev.ie, &event, f);
                    }
                 }
           }
@@ -6784,12 +6781,12 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                scroll bars.  */
             if (bar && event.xbutton.state & ControlMask)
               {
-                x_scroll_bar_handle_click (bar, &event, &inev);
+                x_scroll_bar_handle_click (bar, &event, &inev.ie);
                 *finish = X_EVENT_DROP;
               }
 #else /* not USE_TOOLKIT_SCROLL_BARS */
             if (bar)
-              x_scroll_bar_handle_click (bar, &event, &inev);
+              x_scroll_bar_handle_click (bar, &event, &inev.ie);
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
           }
 
@@ -6897,9 +6894,9 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
     }
 
  done:
-  if (inev.kind != NO_EVENT)
+  if (inev.ie.kind != NO_EVENT)
     {
-      kbd_buffer_store_event_hold (&inev, hold_quit);
+      kbd_buffer_store_event_hold (&inev.ie, hold_quit);
       count++;
     }
 
@@ -7156,7 +7153,7 @@ x_clip_to_row (w, row, area, gc)
   window_box (w, area, &window_x, &window_y, &window_width, 0);
 
   clip_rect.x = window_x;
-  clip_rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
+  clip_rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
   clip_rect.y = max (clip_rect.y, window_y);
   clip_rect.width = window_width;
   clip_rect.height = row->visible_height;
@@ -7186,29 +7183,10 @@ x_draw_hollow_cursor (w, row)
   if (cursor_glyph == NULL)
     return;
 
-  /* Compute the width of the rectangle to draw.  If on a stretch
-     glyph, and `x-stretch-block-cursor' is nil, don't draw a
-     rectangle as wide as the glyph, but use a canonical character
-     width instead.  */
-  wd = cursor_glyph->pixel_width - 1;
-  if (cursor_glyph->type == STRETCH_GLYPH
-      && !x_stretch_cursor_p)
-    wd = min (FRAME_COLUMN_WIDTH (f), wd);
-  w->phys_cursor_width = wd;
-
-  /* Compute frame-relative coordinates from window-relative
-     coordinates.  */
+  /* Compute frame-relative coordinates for phys cursor.  */
   x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
-  y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
-
-  /* Compute the proper height and ascent of the rectangle, based
-     on the actual glyph.  Using the full height of the row looks
-     bad when there are tall images on that row.  */
-  h = max (min (FRAME_LINE_HEIGHT (f), row->height),
-          cursor_glyph->ascent + cursor_glyph->descent);
-  if (h < row->height)
-    y += row->ascent /* - w->phys_cursor_ascent */ + cursor_glyph->descent - h;
-  h--;
+  y = get_phys_cursor_geometry (w, row, cursor_glyph, &h);
+  wd = w->phys_cursor_width;
 
   /* The foreground of cursor_gc is typically the same as the normal
      background color, which can cause the cursor box to be invisible.  */
@@ -7772,12 +7750,41 @@ x_connection_closed (dpy, error_message)
   error ("%s", error_msg);
 }
 
+/* We specifically use it before defining it, so that gcc doesn't inline it,
+   otherwise gdb doesn't know how to properly put a breakpoint on it.  */
+static void x_error_quitter (Display *display, XErrorEvent *error);
+
+/* This is the first-level handler for X protocol errors.
+   It calls x_error_quitter or x_error_catcher.  */
+
+static int
+x_error_handler (display, error)
+     Display *display;
+     XErrorEvent *error;
+{
+  if (! NILP (x_error_message_string))
+    x_error_catcher (display, error);
+  else
+    x_error_quitter (display, error);
+  return 0;
+}
 
 /* This is the usual handler for X protocol errors.
    It kills all frames on the display that we got the error for.
    If that was the only one, it prints an error message and kills Emacs.  */
 
-static void
+/* .gdbinit puts a breakpoint here, so make sure it is not inlined.  */
+
+#if __GNUC__ >= 3  /* On GCC 3.0 we might get a warning.  */
+#define NO_INLINE __attribute__((noinline))
+#else
+#define NO_INLINE
+#endif
+
+/* On older GCC versions, just putting x_error_quitter
+   after x_error_handler prevents inlining into the former.  */
+
+static void NO_INLINE
 x_error_quitter (display, error)
      Display *display;
      XErrorEvent *error;
@@ -7794,21 +7801,6 @@ x_error_quitter (display, error)
 }
 
 
-/* This is the first-level handler for X protocol errors.
-   It calls x_error_quitter or x_error_catcher.  */
-
-static int
-x_error_handler (display, error)
-     Display *display;
-     XErrorEvent *error;
-{
-  if (! NILP (x_error_message_string))
-    x_error_catcher (display, error);
-  else
-    x_error_quitter (display, error);
-  return 0;
-}
-
 /* This is the handler for X IO errors, always.
    It kills all frames on the display that we lost touch with.
    If that was the only one, it prints an error message and kills Emacs.  */