(fix_submap_inheritance, get_keyelt, store_in_keymap,
[bpt/emacs.git] / src / xterm.c
index b79a329..9d8e40b 100644 (file)
@@ -1,5 +1,5 @@
 /* X Communication module for terminals which understand the X protocol.
-   Copyright (C) 1989, 93, 94, 95, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1989, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -421,9 +421,10 @@ XTframe_up_to_date (f)
   if (FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc
       || f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
     {
-      note_mouse_highlight (FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame,
-                           FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_x,
-                           FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y);
+      if (FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
+       note_mouse_highlight (FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame,
+                             FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_x,
+                             FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y);
       FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc = 0;
     }
   UNBLOCK_INPUT;
@@ -1013,17 +1014,32 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
                    if (relative_compose)
                      {
                        pcm = PER_CHAR_METRIC (font, x_2byte_buffer + i);
-                       if (- pcm->descent >= relative_compose)
+                       if (NILP (Vignore_relative_composition)
+                           || NILP (Faref (Vignore_relative_composition,
+                                           make_number (cmpcharp->glyph[gidx]))))
                          {
-                           /* Draw above the current glyphs.  */
-                           y_offset = highest + pcm->descent;
-                           highest += pcm->ascent + pcm->descent;
+                           if (- pcm->descent >= relative_compose)
+                             {
+                               /* Draw above the current glyphs.  */
+                               y_offset = highest + pcm->descent;
+                               highest += pcm->ascent + pcm->descent;
+                             }
+                           else if (pcm->ascent <= 0)
+                             {
+                               /* Draw beneath the current glyphs.  */
+                               y_offset = lowest - pcm->ascent;
+                               lowest -= pcm->ascent + pcm->descent;
+                             }
                          }
-                       else if (pcm->ascent <= 0)
+                       else
                          {
-                           /* Draw beneath the current glyphs.  */
-                           y_offset = lowest - pcm->ascent;
-                           lowest -= pcm->ascent + pcm->descent;
+                           /* Draw the glyph at normal position.  If
+                               it sticks out of HIGHEST or LOWEST,
+                               update them appropriately.  */
+                           if (pcm->ascent > highest)
+                             highest = pcm->ascent;
+                           else if (- pcm->descent < lowest)
+                             lowest = - pcm->descent;
                          }
                      }
                    else if (cmpcharp->cmp_rule)
@@ -2728,7 +2744,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
 
   BLOCK_INPUT;
 
-  if (! NILP (last_mouse_scroll_bar))
+  if (! NILP (last_mouse_scroll_bar) && insist == 0)
     x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
   else
     {
@@ -2857,7 +2873,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
              }
          }
 
-       if (f1 == 0 && insist)
+       if (f1 == 0 && insist > 0)
          f1 = selected_frame;
 
        if (f1)
@@ -4464,6 +4480,16 @@ XTread_socket (sd, bufp, numchars, expected)
                      f->output_data.x->win_gravity = NorthWestGravity;
                      x_wm_set_size_hint (f, (long) 0, 0);
                    }
+#ifdef USE_MOTIF
+                 /* Some window managers pass (0,0) as the location of
+                    the window, and the Motif event handler stores it
+                    in the emacs widget, which messes up Motif menus.  */
+                 if (event.xconfigure.x == 0 && event.xconfigure.y == 0)
+                   {
+                     event.xconfigure.x = f->output_data.x->widget->core.x;
+                     event.xconfigure.y = f->output_data.x->widget->core.y;
+                   }
+#endif
                }
              goto OTHER;
 
@@ -4877,6 +4903,10 @@ x_display_cursor (f, on, x, y)
 {
   BLOCK_INPUT;
 
+ if ((unsigned) x >= FRAME_WIDTH (f) + FRAME_LEFT_SCROLL_BAR_WIDTH (f)
+      || (unsigned) y >= FRAME_HEIGHT (f))
+    abort ();
+
   if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor)
     x_display_box_cursor (f, on, x, y);
   else if (FRAME_DESIRED_CURSOR (f) == bar_cursor)
@@ -5289,7 +5319,10 @@ x_new_font (f, fontname)
       f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
     }
   else
-    f->scroll_bar_cols = 2;
+    {
+      int wid = FONT_WIDTH (f->output_data.x->font);
+      f->scroll_bar_cols = (14 + wid - 1) / wid;
+    }
 
   /* Now make the frame display the given font.  */
   if (FRAME_X_WINDOW (f) != 0)
@@ -5818,7 +5851,7 @@ x_make_frame_visible (f)
            /* It could be confusing if a real alarm arrives while processing
               the fake one.  Turn it off and let the handler reset it.  */
            alarm (0);
-           input_poll_signal ();
+           input_poll_signal (0);
          }
        /* Once we have handled input events,
           we should have received the MapNotify if one is coming.
@@ -6082,6 +6115,8 @@ x_destroy_window (f)
       dpyinfo->mouse_face_end_row
        = dpyinfo->mouse_face_end_col = -1;
       dpyinfo->mouse_face_window = Qnil;
+      dpyinfo->mouse_face_deferred_gc = 0;
+      dpyinfo->mouse_face_mouse_frame = 0;
     }
 
   UNBLOCK_INPUT;
@@ -6352,17 +6387,24 @@ x_list_fonts (f, pattern, size, maxnames)
   Lisp_Object list = Qnil, patterns, newlist = Qnil, key, tem, second_best;
   Display *dpy = f != NULL ? FRAME_X_DISPLAY (f) : x_display_list->display;
 
-  patterns = Fassoc (pattern, Valternative_fontname_alist);
+  patterns = Fassoc (pattern, Valternate_fontname_alist);
   if (NILP (patterns))
     patterns = Fcons (pattern, Qnil);
 
+  /* We try at least 10 fonts because X server will return auto-scaled
+     fonts at the head.  */
+  if (maxnames < 10) maxnames = 10;
+
   for (; CONSP (patterns); patterns = XCONS (patterns)->cdr)
     {
       int num_fonts;
       char **names;
 
       pattern = XCONS (patterns)->car;
-      /* See if we cached the result for this particular query.  */
+      /* See if we cached the result for this particular query.
+         The cache is an alist of the form:
+          (((PATTERN . MAXNAMES) (FONTNAME . WIDTH) ...) ...)
+      */
       if (f && (tem = XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr,
                key = Fcons (pattern, make_number (maxnames)),
                !NILP (list = Fassoc (key, tem))))
@@ -6436,6 +6478,8 @@ x_list_fonts (f, pattern, size, maxnames)
       /* Make a list of the fonts that have the right width.  */
       for (; CONSP (list); list = XCONS (list)->cdr)
        {
+         int found_size;
+
          tem = XCONS (list)->car;
 
          if (!CONSP (tem) || NILP (XCONS (tem)->car))
@@ -6459,7 +6503,10 @@ x_list_fonts (f, pattern, size, maxnames)
 
              if (thisinfo)
                {
-                 XCONS (tem)->cdr =  make_number (thisinfo->max_bounds.width);
+                 XCONS (tem)->cdr
+                   = (thisinfo->min_bounds.width == 0
+                      ? make_number (0)
+                      : make_number (thisinfo->max_bounds.width));
                  XFreeFont (dpy, thisinfo);
                }
              else
@@ -6468,21 +6515,26 @@ x_list_fonts (f, pattern, size, maxnames)
                  as 0 not to try to open it again.  */
                XCONS (tem)->cdr = make_number (0);
            }
-         if (XINT (XCONS (tem)->cdr) == size)
+
+         found_size = XINT (XCONS (tem)->cdr);
+         if (found_size == size)
            newlist = Fcons (XCONS (tem)->car, newlist);
-         else if (NILP (second_best))
-           second_best = tem;
-         else if (XINT (XCONS (tem)->cdr) < size)
-           {
-             if (XINT (XCONS (second_best)->cdr) > size
-                 || XINT (XCONS (second_best)->cdr) < XINT (XCONS (tem)->cdr))
-               second_best = tem;
-           }
-         else
+         else if (found_size > 0)
            {
-             if (XINT (XCONS (second_best)->cdr) > size
-                 && XINT (XCONS (second_best)->cdr) > XINT (XCONS (tem)->cdr))
+             if (NILP (second_best))
                second_best = tem;
+             else if (found_size < size)
+               {
+                 if (XINT (XCONS (second_best)->cdr) > size
+                     || XINT (XCONS (second_best)->cdr) < found_size)
+                   second_best = tem;
+               }
+             else
+               {
+                 if (XINT (XCONS (second_best)->cdr) > size
+                     && XINT (XCONS (second_best)->cdr) > found_size)
+                   second_best = tem;
+               }
            }
        }
       if (!NILP (newlist))
@@ -6881,8 +6933,8 @@ x_term_init (display_name, xrm_option, resource_name)
 #endif /* ! 0 */
 
   dpyinfo->x_id_name
-    = (char *) xmalloc (XSTRING (Vinvocation_name)->size
-                       + XSTRING (Vsystem_name)->size
+    = (char *) xmalloc (XSTRING (Vinvocation_name)->size_byte
+                       + XSTRING (Vsystem_name)->size_byte
                        + 2);
   sprintf (dpyinfo->x_id_name, "%s@%s",
           XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
@@ -7020,6 +7072,7 @@ x_term_init (display_name, xrm_option, resource_name)
 #endif /* ! defined (SIGIO) */
 
 #ifdef USE_LUCID
+#ifdef HAVE_X11R5 /* It seems X11R4 lacks XtCvtStringToFont, and XPointer.  */
   /* Make sure that we have a valid font for dialog boxes
      so that Xt does not crash.  */
   {
@@ -7042,6 +7095,7 @@ x_term_init (display_name, xrm_option, resource_name)
     x_uncatch_errors (dpy, count);
   }
 #endif
+#endif
 
 
   UNBLOCK_INPUT;