]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
(expose_window): Don't redraw the window that's
[gnu-emacs] / src / xterm.c
index 7a2260c682694c0f32a37996f1d8bf7e542b2b69..d45dfd8c7e1856b3a646848afb88773c1129d5cd 100644 (file)
@@ -1139,19 +1139,6 @@ static void x_produce_glyphs P_ ((struct it *));
 static void x_produce_image_glyph P_ ((struct it *it));
 
 
-/* Return a pointer to per-char metric information in FONT of a
-   character pointed by B which is a pointer to an XChar2b.  */
-
-#define PER_CHAR_METRIC(font, b)                                          \
-  ((font)->per_char                                                       \
-   ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2                   \
-      + (((font)->min_byte1 || (font)->max_byte1)                         \
-        ? (((b)->byte1 - (font)->min_byte1)                               \
-           * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
-        : 0))                                                             \
-   : &((font)->max_bounds))
-
-
 /* Get metrics of character CHAR2B in FONT.  Value is null if CHAR2B
    is not contained in the font.  */
 
@@ -2108,8 +2095,8 @@ x_produce_glyphs (it)
          cmp->font = (void *) font;
 
          /* Initialize the bounding box.  */
-         pcm = x_per_char_metric (font, &char2b);
-         if (pcm)
+         if (font_info
+             && (pcm = x_per_char_metric (font, &char2b)))
            {
              width = pcm->width;
              ascent = pcm->ascent;
@@ -2166,8 +2153,8 @@ x_produce_glyphs (it)
                    boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
                }
 
-             pcm = x_per_char_metric (font, &char2b);
-             if (pcm)
+             if (font_info
+                 && (pcm = x_per_char_metric (font, &char2b)))
                {
                  width = pcm->width;
                  ascent = pcm->ascent;
@@ -2176,8 +2163,8 @@ x_produce_glyphs (it)
              else
                {
                  width = FONT_WIDTH (font);
-                 ascent = font->ascent;
-                 descent = font->descent;
+                 ascent = 1;
+                 descent = 0;
                }
 
              if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
@@ -5709,31 +5696,31 @@ expose_area (w, row, r, area)
      XRectangle *r;
      enum glyph_row_area area;
 {
-  int x;
   struct glyph *first = row->glyphs[area];
   struct glyph *end = row->glyphs[area] + row->used[area];
   struct glyph *last;
-  int first_x;
-
-  /* Set x to the window-relative start position for drawing glyphs of
-     AREA.  The first glyph of the text area can be partially visible.
-     The first glyphs of other areas cannot.  */
-  if (area == LEFT_MARGIN_AREA)
-    x = 0;
-  else if (area == TEXT_AREA)
-    x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
-  else
-    x = (window_box_width (w, LEFT_MARGIN_AREA)
-        + window_box_width (w, TEXT_AREA));
+  int first_x, start_x, x;
 
   if (area == TEXT_AREA && row->fill_line_p)
     /* If row extends face to end of line write the whole line.  */
-    x_draw_glyphs (w, x, row, area,
+    x_draw_glyphs (w, 0, row, area,
                   0, row->used[area],
                   row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
                   NULL, NULL, 0);
   else
     {
+      /* Set START_X to the window-relative start position for drawing glyphs of
+        AREA.  The first glyph of the text area can be partially visible.
+        The first glyphs of other areas cannot.  */
+      if (area == LEFT_MARGIN_AREA)
+       start_x = 0;
+      else if (area == TEXT_AREA)
+       start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
+      else
+       start_x = (window_box_width (w, LEFT_MARGIN_AREA)
+                  + window_box_width (w, TEXT_AREA));
+      x = start_x;
+
       /* Find the first glyph that must be redrawn.  */
       while (first < end
             && x + first->pixel_width < r->x)
@@ -5754,7 +5741,7 @@ expose_area (w, row, r, area)
       
       /* Repaint.  */
       if (last > first)
-       x_draw_glyphs (w, first_x, row, area,
+       x_draw_glyphs (w, first_x - start_x, row, area,
                       first - row->glyphs[area],
                       last - row->glyphs[area],
                       row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
@@ -5832,7 +5819,7 @@ expose_window (w, r)
      happen when toolkit scroll bars are used and a window is split.
      Reconfiguring the scroll bar will generate an expose for a newly
      created window.  */
-  if (w->current_matrix == NULL)
+  if (w->current_matrix == NULL || w == updated_window)
     return;
 
   TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
@@ -7303,7 +7290,7 @@ void
 clear_mouse_face (dpyinfo)
      struct x_display_info *dpyinfo;
 {
-  if (tip_frame)
+  if (!NILP (tip_frame))
     return;
   
   if (! NILP (dpyinfo->mouse_face_window))
@@ -7650,7 +7637,7 @@ x_window_to_scroll_bar (window_id)
                         Toolkit scroll bars
  ************************************************************************/
 
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
 
 static void x_scroll_bar_to_input_event P_ ((XEvent *, struct input_event *));
 static void x_send_scroll_bar_event P_ ((Lisp_Object, int, int, int));
@@ -8326,7 +8313,7 @@ x_scroll_bar_create (w, top, left, width, height)
 
   BLOCK_INPUT;
 
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
   x_create_toolkit_scroll_bar (f, bar);
 #else /* not USE_TOOLKIT_SCROLL_BARS */
   {
@@ -8386,7 +8373,7 @@ x_scroll_bar_create (w, top, left, width, height)
     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 
   /* Map the window/widget.  */
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
  {
    Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
    XtConfigureWidget (scroll_bar,
@@ -8531,7 +8518,7 @@ x_scroll_bar_remove (bar)
   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   BLOCK_INPUT;
 
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
   XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
 #else
   XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
@@ -8676,7 +8663,7 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
       UNBLOCK_INPUT;
     }
 
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
   x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 #else /* not USE_TOOLKIT_SCROLL_BARS */
   /* Set the scroll bar's current state, unless we're currently being
@@ -9729,7 +9716,7 @@ XTread_socket (sd, bufp, numchars, expected)
            case KeyPress:
              f = x_any_window_to_frame (dpyinfo, event.xkey.window);
 
-#ifdef USE_MOTIF
+#if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
              /* I couldn't find a way to prevent LessTif scroll bars
                 from consuming key events.  */
              if (f == 0)
@@ -9742,7 +9729,7 @@ XTread_socket (sd, bufp, numchars, expected)
                      f = x_any_window_to_frame (dpyinfo, XtWindow (widget));
                    }
                }
-#endif /* USE_MOTIF */
+#endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
 
              if (f != 0)
                {
@@ -11276,14 +11263,26 @@ x_connection_closed (display, error_message)
   struct x_display_info *dpyinfo = x_display_info_for_display (display);
   Lisp_Object frame, tail;
 
-  /* Indicate that this display is dead.  */
+  /* We have to close the display to inform Xt that it doesn't
+     exist anymore.  If we don't, Xt will continue to wait for
+     events from the display.  As a consequence, a sequence of
+
+     M-x make-frame-on-display RET :1 RET
+     ...kill the new frame, so that we get an IO error...
+     M-x make-frame-on-display RET :1 RET
 
-#if 0 /* Closing the display caused a bus error on OpenWindows.  */
+     will indefinitely wait in Xt for events for display `:1', opened
+     in the first class to make-frame-on-display.
+
+     Closing the display is reported to lead to a bus error on
+     OpenWindows in certain situations.  I suspect that is a bug
+     in OpenWindows.  I don't know how to cicumvent it here.  */
+  
 #ifdef USE_X_TOOLKIT
   XtCloseDisplay (display);
-#endif
 #endif
 
+  /* Indicate that this display is dead.  */
   if (dpyinfo)
     dpyinfo->display = 0;
 
@@ -11671,11 +11670,13 @@ xim_close_dpy (dpyinfo)
 {
 #ifdef USE_XIM
 #ifdef HAVE_X11R6_XIM
-  XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
-                                   NULL, EMACS_CLASS,
-                                   xim_instantiate_callback, NULL);
+  if (dpyinfo->display)
+    XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
+                                     NULL, EMACS_CLASS,
+                                     xim_instantiate_callback, NULL);
 #endif /* not HAVE_X11R6_XIM */
-  XCloseIM (dpyinfo->xim);
+  if (dpyinfo->display)
+    XCloseIM (dpyinfo->xim);
   dpyinfo->xim = NULL;
   XFree (dpyinfo->xim_styles);
 #endif /* USE_XIM */
@@ -11761,25 +11762,33 @@ x_calc_absolute_position (f)
                                  - PIXEL_WIDTH (f)
                                  + f->output_data.x->left_pos);
 
-  if (flags & YNegative)
-    {
-      int menubar_height = 0;
+  {
+    int height = PIXEL_HEIGHT (f);
 
-#ifdef USE_X_TOOLKIT
-      if (f->output_data.x->menubar_widget)
-       menubar_height
-         = (f->output_data.x->menubar_widget->core.height
-            + f->output_data.x->menubar_widget->core.border_width);
+#if defined USE_X_TOOLKIT && defined USE_MOTIF
+    /* Something is fishy here.  When using Motif, starting Emacs with
+       `-g -0-0', the frame appears too low by a few pixels.
+
+       This seems to be so because initially, while Emacs is starting,
+       the column widget's height and the frame's pixel height are
+       different.  The column widget's height is the right one.  In
+       later invocations, when Emacs is up, the frame's pixel height
+       is right, though.
+
+       It's not obvious where the initial small difference comes from.
+       2000-12-01, gerd.  */
+    
+    XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL);
 #endif
-      
-      f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
-                                  - 2 * f->output_data.x->border_width
-                                  - win_y
-                                  - PIXEL_HEIGHT (f)
-                                  - menubar_height
-                                  + f->output_data.x->top_pos);
-    }
 
+  if (flags & YNegative)
+    f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
+                                - 2 * f->output_data.x->border_width
+                                - win_y
+                                - height
+                                + f->output_data.x->top_pos);
+  }
+  
   /* The left_pos and top_pos
      are now relative to the top and left screen edges,
      so the flags should correspond.  */
@@ -12397,11 +12406,12 @@ x_iconify_frame (f)
   UNBLOCK_INPUT;
 #endif /* not USE_X_TOOLKIT */
 }
+
 \f
-/* Destroy the X window of frame F.  */
+/* Free X resources of frame F.  */
 
 void
-x_destroy_window (f)
+x_free_frame_resources (f)
      struct frame *f;
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
@@ -12410,15 +12420,19 @@ x_destroy_window (f)
 
   /* If a display connection is dead, don't try sending more
      commands to the X server.  */
-  if (dpyinfo->display != 0)
+  if (dpyinfo->display)
     {
-      if (f->output_data.x->icon_desc != 0)
+      if (f->output_data.x->icon_desc)
        XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
+      
 #ifdef HAVE_X_I18N
       if (FRAME_XIC (f))
        free_frame_xic (f);
 #endif
-      XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->window_desc);
+      
+      if (FRAME_X_WINDOW (f))
+       XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+      
 #ifdef USE_X_TOOLKIT
       if (f->output_data.x->widget)
        XtDestroyWidget (f->output_data.x->widget);
@@ -12431,6 +12445,7 @@ x_destroy_window (f)
       unload_color (f, f->output_data.x->cursor_foreground_pixel);
       unload_color (f, f->output_data.x->border_pixel);
       unload_color (f, f->output_data.x->mouse_pixel);
+      
       if (f->output_data.x->scroll_bar_background_pixel != -1)
        unload_color (f, f->output_data.x->scroll_bar_background_pixel);
       if (f->output_data.x->scroll_bar_foreground_pixel != -1)
@@ -12439,8 +12454,11 @@ x_destroy_window (f)
        unload_color (f, f->output_data.x->white_relief.pixel);
       if (f->output_data.x->black_relief.allocated_p)
        unload_color (f, f->output_data.x->black_relief.pixel);
+
+      if (FRAME_FACE_CACHE (f))
+       free_frame_faces (f);
       
-      free_frame_faces (f);
+      x_free_gcs (f);
       XFlush (FRAME_X_DISPLAY (f));
     }
 
@@ -12448,7 +12466,8 @@ x_destroy_window (f)
     xfree (f->output_data.x->saved_menu_event);
 
   xfree (f->output_data.x);
-  f->output_data.x = 0;
+  f->output_data.x = NULL;
+  
   if (f == dpyinfo->x_focus_frame)
     dpyinfo->x_focus_frame = 0;
   if (f == dpyinfo->x_focus_event_frame)
@@ -12456,8 +12475,6 @@ x_destroy_window (f)
   if (f == dpyinfo->x_highlight_frame)
     dpyinfo->x_highlight_frame = 0;
 
-  dpyinfo->reference_count--;
-
   if (f == dpyinfo->mouse_face_mouse_frame)
     {
       dpyinfo->mouse_face_beg_row
@@ -12471,6 +12488,24 @@ x_destroy_window (f)
 
   UNBLOCK_INPUT;
 }
+
+
+/* Destroy the X window of frame F.  */
+
+void
+x_destroy_window (f)
+     struct frame *f;
+{
+  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+
+  /* If a display connection is dead, don't try sending more
+     commands to the X server.  */
+  if (dpyinfo->display != 0)
+    x_free_frame_resources (f);
+
+  dpyinfo->reference_count--;
+}
+
 \f
 /* Setting window manager hints.  */
 
@@ -13200,13 +13235,6 @@ x_load_font (f, fontname, size)
 
     fontp->size = font->max_bounds.width;
     fontp->height = FONT_HEIGHT (font);
-    {
-      /* For some font, ascent and descent in max_bounds field is
-        larger than the above value.  */
-      int max_height = font->max_bounds.ascent + font->max_bounds.descent;
-      if (max_height > fontp->height)
-       fontp->height = max_height;
-    }
 
     if (NILP (font_names))
       {
@@ -13695,7 +13723,7 @@ x_term_init (display_name, xrm_option, resource_name)
 
   {
     extern int gray_bitmap_width, gray_bitmap_height;
-    extern unsigned char *gray_bitmap_bits;
+    extern char *gray_bitmap_bits;
     dpyinfo->gray
       = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window,
                                     gray_bitmap_bits,
@@ -13917,7 +13945,7 @@ x_initialize ()
   }
 #endif
   
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
   xaw3d_arrow_scroll = False;
   xaw3d_pick_top = True;
 #endif
@@ -13972,7 +14000,7 @@ wide as that tab on the display.");
 
   DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p,
     "If not nil, Emacs uses toolkit scroll bars.");
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
   x_toolkit_scroll_bars_p = 1;
 #else
   x_toolkit_scroll_bars_p = 0;