]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
*** empty log message ***
[gnu-emacs] / src / xterm.c
index 8aa52b658c8b0e1b1b7332d645679527972a1977..0dafcfb0101a45589e1760b8f9669f7eb963a4d0 100644 (file)
@@ -357,7 +357,7 @@ static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
                                   enum text_cursor_kinds));
 
-static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC));
+static void x_clip_to_row P_ ((struct window *, struct glyph_row *, int, GC));
 static void x_flush P_ ((struct frame *f));
 static void x_update_begin P_ ((struct frame *));
 static void x_update_window_begin P_ ((struct window *));
@@ -709,12 +709,12 @@ x_draw_fringe_bitmap (w, row, p)
       int oldVH = row->visible_height;
       row->visible_height = p->h;
       row->y -= rowY - p->y;
-      x_clip_to_row (w, row, gc);
+      x_clip_to_row (w, row, -1, gc);
       row->y = oldY;
       row->visible_height = oldVH;
     }
   else
-    x_clip_to_row (w, row, gc);
+    x_clip_to_row (w, row, -1, gc);
 
   if (p->bx >= 0 && !p->overlay_p)
     {
@@ -2823,10 +2823,6 @@ x_clear_frame ()
 
   XFlush (FRAME_X_DISPLAY (f));
 
-#ifdef USE_GTK
-  xg_frame_cleared (f);
-#endif
-
   UNBLOCK_INPUT;
 }
 
@@ -3928,9 +3924,9 @@ x_window_to_scroll_bar (display, window_id)
 {
   Lisp_Object tail;
 
-#ifdef USE_GTK
+#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
   window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
-#endif /* USE_GTK */
+#endif /* USE_GTK  && USE_TOOLKIT_SCROLL_BARS */
 
   for (tail = Vframe_list;
        XGCTYPE (tail) == Lisp_Cons;
@@ -4287,8 +4283,6 @@ xg_scroll_callback (widget, data)
   int part = -1, whole = 0, portion = 0;
   GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (widget));
 
-  if (xg_ignore_gtk_scrollbar) return;
-
   position = gtk_adjustment_get_value (adj);
 
   p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA);
@@ -4302,6 +4296,8 @@ xg_scroll_callback (widget, data)
   previous = *p;
   *p = position;
 
+  if (xg_ignore_gtk_scrollbar) return;
+
   diff = (int) (position - previous);
 
   if (diff == (int) adj->step_increment)
@@ -4333,7 +4329,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);
@@ -4861,9 +4857,7 @@ x_scroll_bar_create (w, top, left, width, height)
                              top,
                              left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
                              width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
-                             max (height, 1),
-                             left,
-                             width);
+                             max (height, 1));
     xg_show_scroll_bar (SCROLL_BAR_X_WINDOW (bar));
 #else /* not USE_GTK */
     Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
@@ -5107,18 +5101,6 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 
 #ifdef USE_TOOLKIT_SCROLL_BARS
 
-#ifdef USE_GTK
-      if (mask)
-        xg_update_scrollbar_pos (f,
-                                 SCROLL_BAR_X_WINDOW (bar),
-                                 top,
-                                 sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
-                                 sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
-                                 max (height, 1),
-                                 left,
-                                 width);
-#else /* not USE_GTK */
-
       /* Move/size the scroll bar widget.  */
       if (mask)
        {
@@ -5127,13 +5109,21 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
          if (width > 0 && height > 0)
            x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                           left, top, width, height, False);
+#ifdef USE_GTK
+          xg_update_scrollbar_pos (f,
+                                   SCROLL_BAR_X_WINDOW (bar),
+                                   top,
+                                   sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
+                                   sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM *2,
+                                   max (height, 1));
+#else /* not USE_GTK */
           XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
                              sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
                              top,
                              sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
                              max (height, 1), 0);
-       }
 #endif /* not USE_GTK */
+       }
 #else /* not USE_TOOLKIT_SCROLL_BARS */
 
       /* Clear areas not covered by the scroll bar because of
@@ -5584,73 +5574,6 @@ x_scroll_bar_clear (f)
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 }
 
-\f
-/* Define a queue to save up SelectionRequest events for later handling.  */
-
-struct selection_event_queue
-  {
-    XEvent event;
-    struct selection_event_queue *next;
-  };
-
-static struct selection_event_queue *queue;
-
-/* Nonzero means queue up certain events--don't process them yet.  */
-
-static int x_queue_selection_requests;
-
-/* Queue up an X event *EVENT, to be processed later.  */
-
-static void
-x_queue_event (f, event)
-     FRAME_PTR f;
-     XEvent *event;
-{
-  struct selection_event_queue *queue_tmp
-    = (struct selection_event_queue *) xmalloc (sizeof (struct selection_event_queue));
-
-  if (queue_tmp != NULL)
-    {
-      queue_tmp->event = *event;
-      queue_tmp->next = queue;
-      queue = queue_tmp;
-    }
-}
-
-/* Take all the queued events and put them back
-   so that they get processed afresh.  */
-
-static void
-x_unqueue_events (display)
-     Display *display;
-{
-  while (queue != NULL)
-    {
-      struct selection_event_queue *queue_tmp = queue;
-      XPutBackEvent (display, &queue_tmp->event);
-      queue = queue_tmp->next;
-      xfree ((char *)queue_tmp);
-    }
-}
-
-/* Start queuing SelectionRequest events.  */
-
-void
-x_start_queuing_selection_requests (display)
-     Display *display;
-{
-  x_queue_selection_requests++;
-}
-
-/* Stop queuing SelectionRequest events.  */
-
-void
-x_stop_queuing_selection_requests (display)
-     Display *display;
-{
-  x_queue_selection_requests--;
-  x_unqueue_events (display);
-}
 \f
 /* The main X event-reading loop - XTread_socket.  */
 
@@ -6029,11 +5952,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
       if (!x_window_to_frame (dpyinfo, event.xselectionrequest.owner))
         goto OTHER;
 #endif /* USE_X_TOOLKIT */
-      if (x_queue_selection_requests)
-        x_queue_event (x_window_to_frame (dpyinfo, event.xselectionrequest.owner),
-                       &event);
-      else
-        {
+      {
           XSelectionRequestEvent *eventp
             = (XSelectionRequestEvent *) &event;
 
@@ -6045,7 +5964,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
           SELECTION_EVENT_PROPERTY (&inev) = eventp->property;
           SELECTION_EVENT_TIME (&inev) = eventp->time;
           inev.frame_or_window = Qnil;
-        }
+      }
       break;
 
     case PropertyNotify:
@@ -6081,6 +6000,14 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
         {
           x_check_fullscreen (f);
 
+#ifdef USE_GTK
+          /* This seems to be needed for GTK 2.6.  */
+          x_clear_area (event.xexpose.display,
+                        event.xexpose.window,
+                        event.xexpose.x, event.xexpose.y,
+                        event.xexpose.width, event.xexpose.height,
+                        FALSE);
+#endif
           if (f->async_visible == 0)
             {
               f->async_visible = 1;
@@ -7216,18 +7143,19 @@ XTread_socket (sd, expected, hold_quit)
    mode lines must be clipped to the whole window.  */
 
 static void
-x_clip_to_row (w, row, gc)
+x_clip_to_row (w, row, area, gc)
      struct window *w;
      struct glyph_row *row;
+     int area;
      GC gc;
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   XRectangle clip_rect;
-  int window_y, window_width;
+  int window_x, window_y, window_width;
 
-  window_box (w, -1, 0, &window_y, &window_width, 0);
+  window_box (w, area, &window_x, &window_y, &window_width, 0);
 
-  clip_rect.x = WINDOW_TO_FRAME_PIXEL_X (w, 0);
+  clip_rect.x = window_x;
   clip_rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
   clip_rect.y = max (clip_rect.y, window_y);
   clip_rect.width = window_width;
@@ -7293,7 +7221,7 @@ x_draw_hollow_cursor (w, row)
   gc = dpyinfo->scratch_cursor_gc;
 
   /* Set clipping, draw the rectangle, and reset clipping again.  */
-  x_clip_to_row (w, row, gc);
+  x_clip_to_row (w, row, TEXT_AREA, gc);
   XDrawRectangle (dpy, FRAME_X_WINDOW (f), gc, x, y, wd, h);
   XSetClipMask (dpy, gc, None);
 }
@@ -7365,7 +7293,7 @@ x_draw_bar_cursor (w, row, width, kind)
       width = min (cursor_glyph->pixel_width, width);
 
       w->phys_cursor_width = width;
-      x_clip_to_row (w, row, gc);
+      x_clip_to_row (w, row, TEXT_AREA, gc);
 
       if (kind == BAR_CURSOR)
          XFillRectangle (dpy, window, gc,
@@ -7629,7 +7557,11 @@ x_catch_errors_unwind (old_val)
   /* The display may have been closed before this function is called.
      Check if it is still open before calling XSync.  */
   if (x_display_info_for_display (dpy) != 0)
-    XSync (dpy, False);
+    {
+      BLOCK_INPUT;
+      XSync (dpy, False);
+      UNBLOCK_INPUT;
+    }
 
   x_error_message_string = XCDR (old_val);
   return Qnil;
@@ -7914,7 +7846,8 @@ x_new_font (f, fontname)
   FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
   FRAME_FONTSET (f) = -1;
 
-  FRAME_COLUMN_WIDTH (f) = FONT_WIDTH (FRAME_FONT (f));
+  FRAME_COLUMN_WIDTH (f) = fontp->average_width;
+  FRAME_SPACE_WIDTH (f) = fontp->space_width;
   FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (FRAME_FONT (f));
 
   compute_fringe_widths (f, 1);
@@ -8022,11 +7955,7 @@ xim_destroy_callback (xim, client_data, call_data)
       if (FRAME_X_DISPLAY_INFO (f) == dpyinfo)
        {
          FRAME_XIC (f) = NULL;
-         if (FRAME_XIC_FONTSET (f))
-           {
-             XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
-             FRAME_XIC_FONTSET (f) = NULL;
-           }
+          xic_free_xfontset (f);
        }
     }
 
@@ -8227,20 +8156,11 @@ x_calc_absolute_position (f)
   if (! ((flags & XNegative) || (flags & YNegative)))
     return;
 
-  /* Find the offsets of the outside upper-left corner of
-     the inner window, with respect to the outer window.
-     But do this only if we will need the results.  */
-  if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
-    /* This is to get *_pixels_outer_diff.  */
-    x_real_positions (f, &win_x, &win_y);
-
   /* Treat negative positions as relative to the leftmost bottommost
      position that fits on the screen.  */
   if (flags & XNegative)
     f->left_pos = (FRAME_X_DISPLAY_INFO (f)->width
-                   - 2 * FRAME_X_OUTPUT (f)->x_pixels_outer_diff
-                  - FRAME_PIXEL_WIDTH (f)
-                  + f->left_pos);
+                   - FRAME_PIXEL_WIDTH (f) + f->left_pos);
 
   {
     int height = FRAME_PIXEL_HEIGHT (f);
@@ -8262,15 +8182,7 @@ x_calc_absolute_position (f)
 #endif
 
   if (flags & YNegative)
-    f->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
-                  - FRAME_X_OUTPUT (f)->y_pixels_outer_diff
-
-                  /* Assume the window manager decorations are the same size on
-                     three sides, i.e. left, right and bottom.  This is to
-                     compensate for the bottom part.  */
-                  - FRAME_X_OUTPUT (f)->x_pixels_outer_diff
-                 - height
-                 + f->top_pos);
+    f->top_pos = (FRAME_X_DISPLAY_INFO (f)->height - height + f->top_pos);
   }
 
   /* The left_pos and top_pos
@@ -8386,7 +8298,9 @@ x_check_expected_move (f)
         FRAME_X_OUTPUT (f)->move_offset_left = expect_left - f->left_pos;
         FRAME_X_OUTPUT (f)->move_offset_top = expect_top - f->top_pos;
 
-        x_set_offset (f, expect_left, expect_top, 1);
+        f->left_pos = expect_left;
+        f->top_pos = expect_top;
+        x_set_offset (f, expect_left, expect_top, 0);
       }
     else if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN)
       FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B;
@@ -9877,6 +9791,43 @@ x_load_font (f, fontname, size)
     fontp->name = (char *) xmalloc (strlen (fontname) + 1);
     bcopy (fontname, fontp->name, strlen (fontname) + 1);
 
+    if (font->min_bounds.width == font->max_bounds.width)
+      {
+       /* Fixed width font.  */
+       fontp->average_width = fontp->space_width = font->min_bounds.width;
+      }
+    else
+      {
+       XChar2b char2b;
+       XCharStruct *pcm;
+
+       char2b.byte1 = 0x00, char2b.byte2 = 0x20;
+       pcm = x_per_char_metric (font, &char2b, 0);
+       if (pcm)
+         fontp->space_width = pcm->width;
+       else
+         fontp->space_width = FONT_WIDTH (font);
+
+       fontp->average_width
+         = (XGetFontProperty (font, dpyinfo->Xatom_AVERAGE_WIDTH, &value)
+            ? (long) value / 10 : 0);
+       if (fontp->average_width < 0)
+         fontp->average_width = - fontp->average_width;
+       if (fontp->average_width == 0)
+         {
+           if (pcm)
+             {
+               int width = pcm->width;
+               for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
+                 if ((pcm = x_per_char_metric (font, &char2b, 0)) != NULL)
+                   width += pcm->width;
+               fontp->average_width = width / 95;
+             }
+           else
+             fontp->average_width = FONT_WIDTH (font);
+         }
+      }
+
     /* Try to get the full name of FONT.  Put it in FULL_NAME.  */
     full_name = 0;
     if (XGetFontProperty (font, XA_FONT, &value))
@@ -10504,6 +10455,8 @@ x_term_init (display_name, xrm_option, resource_name)
   /* For properties of font.  */
   dpyinfo->Xatom_PIXEL_SIZE
     = XInternAtom (dpyinfo->display, "PIXEL_SIZE", False);
+  dpyinfo->Xatom_AVERAGE_WIDTH
+    = XInternAtom (dpyinfo->display, "AVERAGE_WIDTH", False);
   dpyinfo->Xatom_MULE_BASELINE_OFFSET
     = XInternAtom (dpyinfo->display, "_MULE_BASELINE_OFFSET", False);
   dpyinfo->Xatom_MULE_RELATIVE_COMPOSE