1 /* X Communication module for terminals which understand the X protocol.
    2    Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
    3                  2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    4                  Free Software Foundation, Inc.
    5 
    6 This file is part of GNU Emacs.
    7 
    8 GNU Emacs is free software: you can redistribute it and/or modify
    9 it under the terms of the GNU General Public License as published by
   10 the Free Software Foundation, either version 3 of the License, or
   11 (at your option) any later version.
   12 
   13 GNU Emacs is distributed in the hope that it will be useful,
   14 but WITHOUT ANY WARRANTY; without even the implied warranty of
   15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16 GNU General Public License for more details.
   17 
   18 You should have received a copy of the GNU General Public License
   19 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
   20 
   21 /* New display code by Gerd Moellmann <gerd@gnu.org>.  */
   22 /* Xt features made by Fred Pierresteguy.  */
   23 
   24 #include <config.h>
   25 
   26 /* On 4.3 these lose if they come after xterm.h.  */
   27 /* Putting these at the beginning seems to be standard for other .c files.  */
   28 #include <signal.h>
   29 
   30 #include <stdio.h>
   31 #include <setjmp.h>
   32 
   33 #ifdef HAVE_X_WINDOWS
   34 
   35 #include "lisp.h"
   36 #include "blockinput.h"
   37 
   38 /* Need syssignal.h for various externs and definitions that may be required
   39    by some configurations for calls to signal later in this source file.  */
   40 #include "syssignal.h"
   41 
   42 /* This may include sys/types.h, and that somehow loses
   43    if this is not done before the other system files.  */
   44 #include "xterm.h"
   45 #include <X11/cursorfont.h>
   46 
   47 /* Load sys/types.h if not already loaded.
   48    In some systems loading it twice is suicidal.  */
   49 #ifndef makedev
   50 #include <sys/types.h>
   51 #endif /* makedev */
   52 
   53 #ifdef HAVE_SYS_IOCTL_H
   54 #include <sys/ioctl.h>
   55 #endif /* ! defined (HAVE_SYS_IOCTL_H) */
   56 
   57 #include "systime.h"
   58 
   59 #ifndef INCLUDED_FCNTL
   60 #include <fcntl.h>
   61 #endif
   62 #include <ctype.h>
   63 #include <errno.h>
   64 #include <setjmp.h>
   65 #include <sys/stat.h>
   66 /* Caused redefinition of DBL_DIG on Netbsd; seems not to be needed.  */
   67 /* #include <sys/param.h>  */
   68 
   69 #include "charset.h"
   70 #include "character.h"
   71 #include "coding.h"
   72 #include "frame.h"
   73 #include "dispextern.h"
   74 #include "fontset.h"
   75 #include "termhooks.h"
   76 #include "termopts.h"
   77 #include "termchar.h"
   78 #include "emacs-icon.h"
   79 #include "disptab.h"
   80 #include "buffer.h"
   81 #include "window.h"
   82 #include "keyboard.h"
   83 #include "intervals.h"
   84 #include "process.h"
   85 #include "atimer.h"
   86 #include "keymap.h"
   87 #include "font.h"
   88 #include "fontset.h"
   89 #include "xsettings.h"
   90 #include "xgselect.h"
   91 #include "sysselect.h"
   92 
   93 #ifdef USE_X_TOOLKIT
   94 #include <X11/Shell.h>
   95 #endif
   96 
   97 #ifdef HAVE_SYS_TIME_H
   98 #include <sys/time.h>
   99 #endif
  100 #ifdef HAVE_UNISTD_H
  101 #include <unistd.h>
  102 #endif
  103 
  104 #ifdef USE_GTK
  105 #include "gtkutil.h"
  106 #endif
  107 
  108 #ifdef USE_LUCID
  109 extern int xlwmenu_window_p P_ ((Widget w, Window window));
  110 extern void xlwmenu_redisplay P_ ((Widget));
  111 #endif
  112 
  113 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
  114 
  115 extern void free_frame_menubar P_ ((struct frame *));
  116 #endif
  117 
  118 #ifdef USE_X_TOOLKIT
  119 #if !defined(NO_EDITRES)
  120 #define HACK_EDITRES
  121 extern void _XEditResCheckMessages ();
  122 #endif /* not NO_EDITRES */
  123 
  124 /* Include toolkit specific headers for the scroll bar widget.  */
  125 
  126 #ifdef USE_TOOLKIT_SCROLL_BARS
  127 #if defined USE_MOTIF
  128 #include <Xm/Xm.h>              /* for LESSTIF_VERSION */
  129 #include <Xm/ScrollBar.h>
  130 #else /* !USE_MOTIF i.e. use Xaw */
  131 
  132 #ifdef HAVE_XAW3D
  133 #include <X11/Xaw3d/Simple.h>
  134 #include <X11/Xaw3d/Scrollbar.h>
  135 #include <X11/Xaw3d/ThreeD.h>
  136 #else /* !HAVE_XAW3D */
  137 #include <X11/Xaw/Simple.h>
  138 #include <X11/Xaw/Scrollbar.h>
  139 #endif /* !HAVE_XAW3D */
  140 #ifndef XtNpickTop
  141 #define XtNpickTop "pickTop"
  142 #endif /* !XtNpickTop */
  143 #endif /* !USE_MOTIF */
  144 #endif /* USE_TOOLKIT_SCROLL_BARS */
  145 
  146 #endif /* USE_X_TOOLKIT */
  147 
  148 #ifdef USE_X_TOOLKIT
  149 #include "widget.h"
  150 #ifndef XtNinitialState
  151 #define XtNinitialState "initialState"
  152 #endif
  153 #endif
  154 
  155 /* Default to using XIM if available.  */
  156 #ifdef USE_XIM
  157 int use_xim = 1;
  158 #else
  159 int use_xim = 0;  /* configure --without-xim */
  160 #endif
  161 
  162 
  163 
  164 /* Non-nil means Emacs uses toolkit scroll bars.  */
  165 
  166 Lisp_Object Vx_toolkit_scroll_bars;
  167 
  168 /* Non-zero means that a HELP_EVENT has been generated since Emacs
  169    start.  */
  170 
  171 static int any_help_event_p;
  172 
  173 /* Last window where we saw the mouse.  Used by mouse-autoselect-window.  */
  174 static Lisp_Object last_window;
  175 
  176 /* Non-zero means make use of UNDERLINE_POSITION font properties.  */
  177 
  178 int x_use_underline_position_properties;
  179 
  180 /* Non-zero means to draw the underline at the same place as the descent line.  */
  181 
  182 int x_underline_at_descent_line;
  183 
  184 /* This is a chain of structures for all the X displays currently in
  185    use.  */
  186 
  187 struct x_display_info *x_display_list;
  188 
  189 /* This is a list of cons cells, each of the form (NAME
  190    . FONT-LIST-CACHE), one for each element of x_display_list and in
  191    the same order.  NAME is the name of the frame.  FONT-LIST-CACHE
  192    records previous values returned by x-list-fonts.  */
  193 
  194 Lisp_Object x_display_name_list;
  195 
  196 /* Frame being updated by update_frame.  This is declared in term.c.
  197    This is set by update_begin and looked at by all the XT functions.
  198    It is zero while not inside an update.  In that case, the XT
  199    functions assume that `selected_frame' is the frame to apply to.  */
  200 
  201 extern struct frame *updating_frame;
  202 
  203 /* This is a frame waiting to be auto-raised, within XTread_socket.  */
  204 
  205 static struct frame *pending_autoraise_frame;
  206 
  207 /* This is a frame waiting for an event matching mask, within XTread_socket.  */
  208 
  209 static struct {
  210   struct frame *f;
  211   int eventtype;
  212 } pending_event_wait;
  213 
  214 #ifdef USE_X_TOOLKIT
  215 /* The application context for Xt use.  */
  216 XtAppContext Xt_app_con;
  217 static String Xt_default_resources[] = {0};
  218 #endif /* USE_X_TOOLKIT */
  219 
  220 /* Non-zero means user is interacting with a toolkit scroll bar.  */
  221 
  222 static int toolkit_scroll_bar_interaction;
  223 
  224 /* Non-zero means to not move point as a result of clicking on a
  225    frame to focus it (when focus-follows-mouse is nil).  */
  226 
  227 int x_mouse_click_focus_ignore_position;
  228 
  229 /* Non-zero timeout value means ignore next mouse click if it arrives
  230    before that timeout elapses (i.e. as part of the same sequence of
  231    events resulting from clicking on a frame to select it).  */
  232 
  233 static unsigned long ignore_next_mouse_click_timeout;
  234 
  235 /* Mouse movement.
  236 
  237    Formerly, we used PointerMotionHintMask (in standard_event_mask)
  238    so that we would have to call XQueryPointer after each MotionNotify
  239    event to ask for another such event.  However, this made mouse tracking
  240    slow, and there was a bug that made it eventually stop.
  241 
  242    Simply asking for MotionNotify all the time seems to work better.
  243 
  244    In order to avoid asking for motion events and then throwing most
  245    of them away or busy-polling the server for mouse positions, we ask
  246    the server for pointer motion hints.  This means that we get only
  247    one event per group of mouse movements.  "Groups" are delimited by
  248    other kinds of events (focus changes and button clicks, for
  249    example), or by XQueryPointer calls; when one of these happens, we
  250    get another MotionNotify event the next time the mouse moves.  This
  251    is at least as efficient as getting motion events when mouse
  252    tracking is on, and I suspect only negligibly worse when tracking
  253    is off.  */
  254 
  255 /* Where the mouse was last time we reported a mouse event.  */
  256 
  257 static XRectangle last_mouse_glyph;
  258 static FRAME_PTR last_mouse_glyph_frame;
  259 static Lisp_Object last_mouse_press_frame;
  260 
  261 /* The scroll bar in which the last X motion event occurred.
  262 
  263    If the last X motion event occurred in a scroll bar, we set this so
  264    XTmouse_position can know whether to report a scroll bar motion or
  265    an ordinary motion.
  266 
  267    If the last X motion event didn't occur in a scroll bar, we set
  268    this to Qnil, to tell XTmouse_position to return an ordinary motion
  269    event.  */
  270 
  271 static Lisp_Object last_mouse_scroll_bar;
  272 
  273 /* This is a hack.  We would really prefer that XTmouse_position would
  274    return the time associated with the position it returns, but there
  275    doesn't seem to be any way to wrest the time-stamp from the server
  276    along with the position query.  So, we just keep track of the time
  277    of the last movement we received, and return that in hopes that
  278    it's somewhat accurate.  */
  279 
  280 static Time last_mouse_movement_time;
  281 
  282 /* Time for last user interaction as returned in X events.  */
  283 
  284 static Time last_user_time;
  285 
  286 /* Incremented by XTread_socket whenever it really tries to read
  287    events.  */
  288 
  289 #ifdef __STDC__
  290 static int volatile input_signal_count;
  291 #else
  292 static int input_signal_count;
  293 #endif
  294 
  295 /* Used locally within XTread_socket.  */
  296 
  297 static int x_noop_count;
  298 
  299 /* Initial values of argv and argc.  */
  300 
  301 extern char **initial_argv;
  302 extern int initial_argc;
  303 
  304 extern Lisp_Object Vcommand_line_args, Vsystem_name;
  305 
  306 /* Tells if a window manager is present or not.  */
  307 
  308 extern Lisp_Object Vx_no_window_manager;
  309 
  310 extern Lisp_Object Qeql;
  311 
  312 /* A mask of extra modifier bits to put into every keyboard char.  */
  313 
  314 extern EMACS_INT extra_keyboard_modifiers;
  315 
  316 /* The keysyms to use for the various modifiers.  */
  317 
  318 Lisp_Object Vx_alt_keysym, Vx_hyper_keysym, Vx_meta_keysym, Vx_super_keysym;
  319 Lisp_Object Vx_keysym_table;
  320 static Lisp_Object Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value;
  321 
  322 static Lisp_Object Qvendor_specific_keysyms;
  323 static Lisp_Object Qlatin_1;
  324 
  325 #ifdef USE_GTK
  326 /* The name of the Emacs icon file.  */
  327 static Lisp_Object xg_default_icon_file;
  328 
  329 /* Used in gtkutil.c.  */
  330 Lisp_Object Qx_gtk_map_stock;
  331 #endif
  332 
  333 /* Used in x_flush.  */
  334 
  335 extern Lisp_Object Vinhibit_redisplay;
  336 
  337 extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *));
  338 extern int x_bitmap_mask P_ ((FRAME_PTR, int));
  339 
  340 static int x_alloc_nearest_color_1 P_ ((Display *, Colormap, XColor *));
  341 static void x_set_window_size_1 P_ ((struct frame *, int, int, int));
  342 static const XColor *x_color_cells P_ ((Display *, int *));
  343 static void x_update_window_end P_ ((struct window *, int, int));
  344 
  345 static int x_io_error_quitter P_ ((Display *));
  346 static struct terminal *x_create_terminal P_ ((struct x_display_info *));
  347 void x_delete_terminal P_ ((struct terminal *));
  348 static void x_update_end P_ ((struct frame *));
  349 static void XTframe_up_to_date P_ ((struct frame *));
  350 static void XTset_terminal_modes P_ ((struct terminal *));
  351 static void XTreset_terminal_modes P_ ((struct terminal *));
  352 static void x_clear_frame P_ ((struct frame *));
  353 static void frame_highlight P_ ((struct frame *));
  354 static void frame_unhighlight P_ ((struct frame *));
  355 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
  356 static void  x_focus_changed P_ ((int, int, struct x_display_info *,
  357                                   struct frame *, struct input_event *));
  358 static void x_detect_focus_change P_ ((struct x_display_info *,
  359                                        XEvent *, struct input_event *));
  360 static void XTframe_rehighlight P_ ((struct frame *));
  361 static void x_frame_rehighlight P_ ((struct x_display_info *));
  362 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
  363 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
  364                                    enum text_cursor_kinds));
  365 
  366 static void x_clip_to_row P_ ((struct window *, struct glyph_row *, int, GC));
  367 static void x_flush P_ ((struct frame *f));
  368 static void x_update_begin P_ ((struct frame *));
  369 static void x_update_window_begin P_ ((struct window *));
  370 static void x_after_update_window_line P_ ((struct glyph_row *));
  371 static struct scroll_bar *x_window_to_scroll_bar P_ ((Display *, Window));
  372 static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
  373                                             enum scroll_bar_part *,
  374                                             Lisp_Object *, Lisp_Object *,
  375                                             unsigned long *));
  376 static void x_handle_net_wm_state P_ ((struct frame *, XPropertyEvent *));
  377 static void x_check_fullscreen P_ ((struct frame *));
  378 static void x_check_expected_move P_ ((struct frame *, int, int));
  379 static void x_sync_with_move P_ ((struct frame *, int, int, int));
  380 static int handle_one_xevent P_ ((struct x_display_info *, XEvent *,
  381                                   int *, struct input_event *));
  382 /* Don't declare this NO_RETURN because we want no
  383    interference with debugging failing X calls.  */
  384 static SIGTYPE x_connection_closed P_ ((Display *, char *));
  385 
  386 
  387 /* Flush display of frame F, or of all frames if F is null.  */
  388 
  389 static void
  390 x_flush (f)
  391      struct frame *f;
  392 {
  393   /* Don't call XFlush when it is not safe to redisplay; the X
  394      connection may be broken.  */
  395   if (!NILP (Vinhibit_redisplay))
  396     return;
  397 
  398   BLOCK_INPUT;
  399   if (f == NULL)
  400     {
  401       Lisp_Object rest, frame;
  402       FOR_EACH_FRAME (rest, frame)
  403         if (FRAME_X_P (XFRAME (frame)))
  404           x_flush (XFRAME (frame));
  405     }
  406   else if (FRAME_X_P (f))
  407     XFlush (FRAME_X_DISPLAY (f));
  408   UNBLOCK_INPUT;
  409 }
  410 
  411 
  412 /* Remove calls to XFlush by defining XFlush to an empty replacement.
  413    Calls to XFlush should be unnecessary because the X output buffer
  414    is flushed automatically as needed by calls to XPending,
  415    XNextEvent, or XWindowEvent according to the XFlush man page.
  416    XTread_socket calls XPending.  Removing XFlush improves
  417    performance.  */
  418 
  419 #define XFlush(DISPLAY) (void) 0
  420 
  421 
  422 /***********************************************************************
  423                               Debugging
  424  ***********************************************************************/
  425 
  426 #if 0
  427 
  428 /* This is a function useful for recording debugging information about
  429    the sequence of occurrences in this file.  */
  430 
  431 struct record
  432 {
  433   char *locus;
  434   int type;
  435 };
  436 
  437 struct record event_record[100];
  438 
  439 int event_record_index;
  440 
  441 record_event (locus, type)
  442      char *locus;
  443      int type;
  444 {
  445   if (event_record_index == sizeof (event_record) / sizeof (struct record))
  446     event_record_index = 0;
  447 
  448   event_record[event_record_index].locus = locus;
  449   event_record[event_record_index].type = type;
  450   event_record_index++;
  451 }
  452 
  453 #endif /* 0 */
  454 
  455 
  456 
  457 /* Return the struct x_display_info corresponding to DPY.  */
  458 
  459 struct x_display_info *
  460 x_display_info_for_display (dpy)
  461      Display *dpy;
  462 {
  463   struct x_display_info *dpyinfo;
  464 
  465   for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
  466     if (dpyinfo->display == dpy)
  467       return dpyinfo;
  468 
  469   return 0;
  470 }
  471 
  472 #define OPAQUE  0xffffffff
  473 #define OPACITY "_NET_WM_WINDOW_OPACITY"
  474 
  475 void
  476 x_set_frame_alpha (f)
  477      struct frame *f;
  478 {
  479   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
  480   Display *dpy = FRAME_X_DISPLAY (f);
  481   Window win = FRAME_OUTER_WINDOW (f);
  482   double alpha = 1.0;
  483   double alpha_min = 1.0;
  484   unsigned long opac;
  485 
  486   if (FRAME_X_DISPLAY_INFO (f)->root_window != FRAME_X_OUTPUT (f)->parent_desc)
  487     /* Since the WM decoration lies under the FRAME_OUTER_WINDOW,
  488        we must treat the former instead of the latter. */
  489     win = FRAME_X_OUTPUT(f)->parent_desc;
  490 
  491   if (dpyinfo->x_highlight_frame == f)
  492     alpha = f->alpha[0];
  493   else
  494     alpha = f->alpha[1];
  495 
  496   if (FLOATP (Vframe_alpha_lower_limit))
  497     alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
  498   else if (INTEGERP (Vframe_alpha_lower_limit))
  499     alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
  500 
  501   if (alpha < 0.0)
  502     return;
  503   else if (alpha > 1.0)
  504     alpha = 1.0;
  505   else if (0.0 <= alpha && alpha < alpha_min && alpha_min <= 1.0)
  506     alpha = alpha_min;
  507 
  508   opac = alpha * OPAQUE;
  509 
  510   /* return unless necessary */
  511   {
  512     unsigned char *data;
  513     Atom actual;
  514     int rc, format;
  515     unsigned long n, left;
  516 
  517     x_catch_errors (dpy);
  518     rc = XGetWindowProperty(dpy, win, XInternAtom(dpy, OPACITY, False),
  519                             0L, 1L, False, XA_CARDINAL,
  520                             &actual, &format, &n, &left,
  521                             &data);
  522 
  523     if (rc == Success && actual != None)
  524       if (*(unsigned long *)data == opac)
  525         {
  526           XFree ((void *) data);
  527           x_uncatch_errors ();
  528           return;
  529         }
  530       else
  531         XFree ((void *) data);
  532     x_uncatch_errors ();
  533   }
  534 
  535   x_catch_errors (dpy);
  536   XChangeProperty (dpy, win, XInternAtom (dpy, OPACITY, False),
  537                    XA_CARDINAL, 32, PropModeReplace,
  538                    (unsigned char *) &opac, 1L);
  539   x_uncatch_errors ();
  540 }
  541 
  542 int
  543 x_display_pixel_height (dpyinfo)
  544      struct x_display_info *dpyinfo;
  545 {
  546   return HeightOfScreen (dpyinfo->screen);
  547 }
  548 
  549 int
  550 x_display_pixel_width (dpyinfo)
  551      struct x_display_info *dpyinfo;
  552 {
  553   return WidthOfScreen (dpyinfo->screen);
  554 }
  555 
  556 
  557 /***********************************************************************
  558                     Starting and ending an update
  559  ***********************************************************************/
  560 
  561 /* Start an update of frame F.  This function is installed as a hook
  562    for update_begin, i.e. it is called when update_begin is called.
  563    This function is called prior to calls to x_update_window_begin for
  564    each window being updated.  Currently, there is nothing to do here
  565    because all interesting stuff is done on a window basis.  */
  566 
  567 static void
  568 x_update_begin (f)
  569      struct frame *f;
  570 {
  571   /* Nothing to do.  */
  572 }
  573 
  574 
  575 /* Start update of window W.  Set the global variable updated_window
  576    to the window being updated and set output_cursor to the cursor
  577    position of W.  */
  578 
  579 static void
  580 x_update_window_begin (w)
  581      struct window *w;
  582 {
  583   struct frame *f = XFRAME (WINDOW_FRAME (w));
  584   struct x_display_info *display_info = FRAME_X_DISPLAY_INFO (f);
  585 
  586   updated_window = w;
  587   set_output_cursor (&w->cursor);
  588 
  589   BLOCK_INPUT;
  590 
  591   if (f == display_info->mouse_face_mouse_frame)
  592     {
  593       /* Don't do highlighting for mouse motion during the update.  */
  594       display_info->mouse_face_defer = 1;
  595 
  596       /* If F needs to be redrawn, simply forget about any prior mouse
  597          highlighting.  */
  598       if (FRAME_GARBAGED_P (f))
  599         display_info->mouse_face_window = Qnil;
  600     }
  601 
  602   UNBLOCK_INPUT;
  603 }
  604 
  605 
  606 /* Draw a vertical window border from (x,y0) to (x,y1)  */
  607 
  608 static void
  609 x_draw_vertical_window_border (w, x, y0, y1)
  610      struct window *w;
  611      int x, y0, y1;
  612 {
  613   struct frame *f = XFRAME (WINDOW_FRAME (w));
  614   struct face *face;
  615 
  616   face = FACE_FROM_ID (f, VERTICAL_BORDER_FACE_ID);
  617   if (face)
  618     XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
  619                     face->foreground);
  620 
  621   XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  622              f->output_data.x->normal_gc, x, y0, x, y1);
  623 }
  624 
  625 /* End update of window W (which is equal to updated_window).
  626 
  627    Draw vertical borders between horizontally adjacent windows, and
  628    display W's cursor if CURSOR_ON_P is non-zero.
  629 
  630    MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
  631    glyphs in mouse-face were overwritten.  In that case we have to
  632    make sure that the mouse-highlight is properly redrawn.
  633 
  634    W may be a menu bar pseudo-window in case we don't have X toolkit
  635    support.  Such windows don't have a cursor, so don't display it
  636    here.  */
  637 
  638 static void
  639 x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
  640      struct window *w;
  641      int cursor_on_p, mouse_face_overwritten_p;
  642 {
  643   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
  644 
  645   if (!w->pseudo_window_p)
  646     {
  647       BLOCK_INPUT;
  648 
  649       if (cursor_on_p)
  650         display_and_set_cursor (w, 1, output_cursor.hpos,
  651                                 output_cursor.vpos,
  652                                 output_cursor.x, output_cursor.y);
  653 
  654       if (draw_window_fringes (w, 1))
  655         x_draw_vertical_border (w);
  656 
  657       UNBLOCK_INPUT;
  658     }
  659 
  660   /* If a row with mouse-face was overwritten, arrange for
  661      XTframe_up_to_date to redisplay the mouse highlight.  */
  662   if (mouse_face_overwritten_p)
  663     {
  664       dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
  665       dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
  666       dpyinfo->mouse_face_window = Qnil;
  667     }
  668 
  669   updated_window = NULL;
  670 }
  671 
  672 
  673 /* End update of frame F.  This function is installed as a hook in
  674    update_end.  */
  675 
  676 static void
  677 x_update_end (f)
  678      struct frame *f;
  679 {
  680   /* Mouse highlight may be displayed again.  */
  681   FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0;
  682 
  683 #ifndef XFlush
  684   BLOCK_INPUT;
  685   XFlush (FRAME_X_DISPLAY (f));
  686   UNBLOCK_INPUT;
  687 #endif
  688 }
  689 
  690 
  691 /* This function is called from various places in xdisp.c whenever a
  692    complete update has been performed.  The global variable
  693    updated_window is not available here.  */
  694 
  695 static void
  696 XTframe_up_to_date (f)
  697      struct frame *f;
  698 {
  699   if (FRAME_X_P (f))
  700     {
  701       struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
  702 
  703       if (dpyinfo->mouse_face_deferred_gc
  704           || f == dpyinfo->mouse_face_mouse_frame)
  705         {
  706           BLOCK_INPUT;
  707           if (dpyinfo->mouse_face_mouse_frame)
  708             note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
  709                                   dpyinfo->mouse_face_mouse_x,
  710                                   dpyinfo->mouse_face_mouse_y);
  711           dpyinfo->mouse_face_deferred_gc = 0;
  712           UNBLOCK_INPUT;
  713         }
  714     }
  715 }
  716 
  717 
  718 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
  719    arrow bitmaps, or clear the fringes if no bitmaps are required
  720    before DESIRED_ROW is made current.  The window being updated is
  721    found in updated_window.  This function It is called from
  722    update_window_line only if it is known that there are differences
  723    between bitmaps to be drawn between current row and DESIRED_ROW.  */
  724 
  725 static void
  726 x_after_update_window_line (desired_row)
  727      struct glyph_row *desired_row;
  728 {
  729   struct window *w = updated_window;
  730   struct frame *f;
  731   int width, height;
  732 
  733   xassert (w);
  734 
  735   if (!desired_row->mode_line_p && !w->pseudo_window_p)
  736     desired_row->redraw_fringe_bitmaps_p = 1;
  737 
  738   /* When a window has disappeared, make sure that no rest of
  739      full-width rows stays visible in the internal border.  Could
  740      check here if updated_window is the leftmost/rightmost window,
  741      but I guess it's not worth doing since vertically split windows
  742      are almost never used, internal border is rarely set, and the
  743      overhead is very small.  */
  744   if (windows_or_buffers_changed
  745       && desired_row->full_width_p
  746       && (f = XFRAME (w->frame),
  747           width = FRAME_INTERNAL_BORDER_WIDTH (f),
  748           width != 0)
  749       && (height = desired_row->visible_height,
  750           height > 0))
  751     {
  752       int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
  753 
  754       BLOCK_INPUT;
  755       x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  756                     0, y, width, height, False);
  757       x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  758                     FRAME_PIXEL_WIDTH (f) - width,
  759                     y, width, height, False);
  760       UNBLOCK_INPUT;
  761     }
  762 }
  763 
  764 static void
  765 x_draw_fringe_bitmap (w, row, p)
  766      struct window *w;
  767      struct glyph_row *row;
  768      struct draw_fringe_bitmap_params *p;
  769 {
  770   struct frame *f = XFRAME (WINDOW_FRAME (w));
  771   Display *display = FRAME_X_DISPLAY (f);
  772   Window window = FRAME_X_WINDOW (f);
  773   GC gc = f->output_data.x->normal_gc;
  774   struct face *face = p->face;
  775   int rowY;
  776 
  777   /* Must clip because of partially visible lines.  */
  778   rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
  779   if (p->y < rowY)
  780     {
  781       /* Adjust position of "bottom aligned" bitmap on partially
  782          visible last row.  */
  783       int oldY = row->y;
  784       int oldVH = row->visible_height;
  785       row->visible_height = p->h;
  786       row->y -= rowY - p->y;
  787       x_clip_to_row (w, row, -1, gc);
  788       row->y = oldY;
  789       row->visible_height = oldVH;
  790     }
  791   else
  792     x_clip_to_row (w, row, -1, gc);
  793 
  794   if (!p->overlay_p)
  795     {
  796       int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
  797 
  798       /* In case the same realized face is used for fringes and
  799          for something displayed in the text (e.g. face `region' on
  800          mono-displays, the fill style may have been changed to
  801          FillSolid in x_draw_glyph_string_background.  */
  802       if (face->stipple)
  803         XSetFillStyle (display, face->gc, FillOpaqueStippled);
  804       else
  805         XSetForeground (display, face->gc, face->background);
  806 
  807 #ifdef USE_TOOLKIT_SCROLL_BARS
  808       /* If the fringe is adjacent to the left (right) scroll bar of a
  809          leftmost (rightmost, respectively) window, then extend its
  810          background to the gap between the fringe and the bar.  */
  811       if ((WINDOW_LEFTMOST_P (w)
  812            && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
  813           || (WINDOW_RIGHTMOST_P (w)
  814               && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
  815         {
  816           int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
  817 
  818           if (sb_width > 0)
  819             {
  820               int left = WINDOW_SCROLL_BAR_AREA_X (w);
  821               int width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
  822                            * FRAME_COLUMN_WIDTH (f));
  823 
  824               if (bx < 0)
  825                 {
  826                   /* Bitmap fills the fringe.  */
  827                   if (left + width == p->x)
  828                     bx = left + sb_width;
  829                   else if (p->x + p->wd == left)
  830                     bx = left;
  831                   if (bx >= 0)
  832                     {
  833                       int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
  834 
  835                       nx = width - sb_width;
  836                       by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
  837                                                             row->y));
  838                       ny = row->visible_height;
  839                     }
  840                 }
  841               else
  842                 {
  843                   if (left + width == bx)
  844                     {
  845                       bx = left + sb_width;
  846                       nx += width - sb_width;
  847                     }
  848                   else if (bx + nx == left)
  849                     nx += width - sb_width;
  850                 }
  851             }
  852         }
  853 #endif
  854       if (bx >= 0 && nx > 0)
  855         XFillRectangle (display, window, face->gc, bx, by, nx, ny);
  856 
  857       if (!face->stipple)
  858         XSetForeground (display, face->gc, face->foreground);
  859     }
  860 
  861   if (p->which)
  862     {
  863       unsigned char *bits;
  864       Pixmap pixmap, clipmask = (Pixmap) 0;
  865       int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
  866       XGCValues gcv;
  867 
  868       if (p->wd > 8)
  869         bits = (unsigned char *)(p->bits + p->dh);
  870       else
  871         bits = (unsigned char *)p->bits + p->dh;
  872 
  873       /* Draw the bitmap.  I believe these small pixmaps can be cached
  874          by the server.  */
  875       pixmap = XCreatePixmapFromBitmapData (display, window, bits, p->wd, p->h,
  876                                             (p->cursor_p
  877                                              ? (p->overlay_p ? face->background
  878                                                 : f->output_data.x->cursor_pixel)
  879                                              : face->foreground),
  880                                             face->background, depth);
  881 
  882       if (p->overlay_p)
  883         {
  884           clipmask = XCreatePixmapFromBitmapData (display,
  885                                                   FRAME_X_DISPLAY_INFO (f)->root_window,
  886                                                   bits, p->wd, p->h,
  887                                                   1, 0, 1);
  888           gcv.clip_mask = clipmask;
  889           gcv.clip_x_origin = p->x;
  890           gcv.clip_y_origin = p->y;
  891           XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
  892         }
  893 
  894       XCopyArea (display, pixmap, window, gc, 0, 0,
  895                  p->wd, p->h, p->x, p->y);
  896       XFreePixmap (display, pixmap);
  897 
  898       if (p->overlay_p)
  899         {
  900           gcv.clip_mask = (Pixmap) 0;
  901           XChangeGC (display, gc, GCClipMask, &gcv);
  902           XFreePixmap (display, clipmask);
  903         }
  904     }
  905 
  906   XSetClipMask (display, gc, None);
  907 }
  908 
  909 
  910 
  911 /* This is called when starting Emacs and when restarting after
  912    suspend.  When starting Emacs, no X window is mapped.  And nothing
  913    must be done to Emacs's own window if it is suspended (though that
  914    rarely happens).  */
  915 
  916 static void
  917 XTset_terminal_modes (struct terminal *terminal)
  918 {
  919 }
  920 
  921 /* This is called when exiting or suspending Emacs.  Exiting will make
  922    the X-windows go away, and suspending requires no action.  */
  923 
  924 static void
  925 XTreset_terminal_modes (struct terminal *terminal)
  926 {
  927 }
  928 
  929 
  930 /***********************************************************************
  931                             Glyph display
  932  ***********************************************************************/
  933 
  934 
  935 
  936 static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
  937 static void x_set_glyph_string_gc P_ ((struct glyph_string *));
  938 static void x_draw_glyph_string_background P_ ((struct glyph_string *,
  939                                                 int));
  940 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *));
  941 static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *));
  942 static void x_draw_glyph_string_box P_ ((struct glyph_string *));
  943 static void x_draw_glyph_string  P_ ((struct glyph_string *));
  944 static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *));
  945 static void x_set_cursor_gc P_ ((struct glyph_string *));
  946 static void x_set_mode_line_face_gc P_ ((struct glyph_string *));
  947 static void x_set_mouse_face_gc P_ ((struct glyph_string *));
  948 static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
  949                                       unsigned long *, double, int));
  950 static void x_setup_relief_color P_ ((struct frame *, struct relief *,
  951                                       double, int, unsigned long));
  952 static void x_setup_relief_colors P_ ((struct glyph_string *));
  953 static void x_draw_image_glyph_string P_ ((struct glyph_string *));
  954 static void x_draw_image_relief P_ ((struct glyph_string *));
  955 static void x_draw_image_foreground P_ ((struct glyph_string *));
  956 static void x_draw_image_foreground_1 P_ ((struct glyph_string *, Pixmap));
  957 static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
  958                                            int, int, int));
  959 static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int,
  960                                     int, int, int, int, int, int,
  961                                     XRectangle *));
  962 static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
  963                                  int, int, int, XRectangle *));
  964 
  965 #if GLYPH_DEBUG
  966 static void x_check_font P_ ((struct frame *, struct font *));
  967 #endif
  968 
  969 
  970 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
  971    face.  */
  972 
  973 static void
  974 x_set_cursor_gc (s)
  975      struct glyph_string *s;
  976 {
  977   if (s->font == FRAME_FONT (s->f)
  978       && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
  979       && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
  980       && !s->cmp)
  981     s->gc = s->f->output_data.x->cursor_gc;
  982   else
  983     {
  984       /* Cursor on non-default face: must merge.  */
  985       XGCValues xgcv;
  986       unsigned long mask;
  987 
  988       xgcv.background = s->f->output_data.x->cursor_pixel;
  989       xgcv.foreground = s->face->background;
  990 
  991       /* If the glyph would be invisible, try a different foreground.  */
  992       if (xgcv.foreground == xgcv.background)
  993         xgcv.foreground = s->face->foreground;
  994       if (xgcv.foreground == xgcv.background)
  995         xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
  996       if (xgcv.foreground == xgcv.background)
  997         xgcv.foreground = s->face->foreground;
  998 
  999       /* Make sure the cursor is distinct from text in this face.  */
 1000       if (xgcv.background == s->face->background
 1001           && xgcv.foreground == s->face->foreground)
 1002         {
 1003           xgcv.background = s->face->foreground;
 1004           xgcv.foreground = s->face->background;
 1005         }
 1006 
 1007       IF_DEBUG (x_check_font (s->f, s->font));
 1008       xgcv.graphics_exposures = False;
 1009       mask = GCForeground | GCBackground | GCGraphicsExposures;
 1010 
 1011       if (FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc)
 1012         XChangeGC (s->display, FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc,
 1013                    mask, &xgcv);
 1014       else
 1015         FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc
 1016           = XCreateGC (s->display, s->window, mask, &xgcv);
 1017 
 1018       s->gc = FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc;
 1019     }
 1020 }
 1021 
 1022 
 1023 /* Set up S->gc of glyph string S for drawing text in mouse face.  */
 1024 
 1025 static void
 1026 x_set_mouse_face_gc (s)
 1027      struct glyph_string *s;
 1028 {
 1029   int face_id;
 1030   struct face *face;
 1031 
 1032   /* What face has to be used last for the mouse face?  */
 1033   face_id = FRAME_X_DISPLAY_INFO (s->f)->mouse_face_face_id;
 1034   face = FACE_FROM_ID (s->f, face_id);
 1035   if (face == NULL)
 1036     face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
 1037 
 1038   if (s->first_glyph->type == CHAR_GLYPH)
 1039     face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
 1040   else
 1041     face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
 1042   s->face = FACE_FROM_ID (s->f, face_id);
 1043   PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
 1044 
 1045   if (s->font == s->face->font)
 1046     s->gc = s->face->gc;
 1047   else
 1048     {
 1049       /* Otherwise construct scratch_cursor_gc with values from FACE
 1050          except for FONT.  */
 1051       XGCValues xgcv;
 1052       unsigned long mask;
 1053 
 1054       xgcv.background = s->face->background;
 1055       xgcv.foreground = s->face->foreground;
 1056       xgcv.graphics_exposures = False;
 1057       mask = GCForeground | GCBackground | GCGraphicsExposures;
 1058 
 1059       if (FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc)
 1060         XChangeGC (s->display, FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc,
 1061                    mask, &xgcv);
 1062       else
 1063         FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc
 1064           = XCreateGC (s->display, s->window, mask, &xgcv);
 1065 
 1066       s->gc = FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc;
 1067 
 1068     }
 1069   xassert (s->gc != 0);
 1070 }
 1071 
 1072 
 1073 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
 1074    Faces to use in the mode line have already been computed when the
 1075    matrix was built, so there isn't much to do, here.  */
 1076 
 1077 static INLINE void
 1078 x_set_mode_line_face_gc (s)
 1079      struct glyph_string *s;
 1080 {
 1081   s->gc = s->face->gc;
 1082 }
 1083 
 1084 
 1085 /* Set S->gc of glyph string S for drawing that glyph string.  Set
 1086    S->stippled_p to a non-zero value if the face of S has a stipple
 1087    pattern.  */
 1088 
 1089 static INLINE void
 1090 x_set_glyph_string_gc (s)
 1091      struct glyph_string *s;
 1092 {
 1093   PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
 1094 
 1095   if (s->hl == DRAW_NORMAL_TEXT)
 1096     {
 1097       s->gc = s->face->gc;
 1098       s->stippled_p = s->face->stipple != 0;
 1099     }
 1100   else if (s->hl == DRAW_INVERSE_VIDEO)
 1101     {
 1102       x_set_mode_line_face_gc (s);
 1103       s->stippled_p = s->face->stipple != 0;
 1104     }
 1105   else if (s->hl == DRAW_CURSOR)
 1106     {
 1107       x_set_cursor_gc (s);
 1108       s->stippled_p = 0;
 1109     }
 1110   else if (s->hl == DRAW_MOUSE_FACE)
 1111     {
 1112       x_set_mouse_face_gc (s);
 1113       s->stippled_p = s->face->stipple != 0;
 1114     }
 1115   else if (s->hl == DRAW_IMAGE_RAISED
 1116            || s->hl == DRAW_IMAGE_SUNKEN)
 1117     {
 1118       s->gc = s->face->gc;
 1119       s->stippled_p = s->face->stipple != 0;
 1120     }
 1121   else
 1122     {
 1123       s->gc = s->face->gc;
 1124       s->stippled_p = s->face->stipple != 0;
 1125     }
 1126 
 1127   /* GC must have been set.  */
 1128   xassert (s->gc != 0);
 1129 }
 1130 
 1131 
 1132 /* Set clipping for output of glyph string S.  S may be part of a mode
 1133    line or menu if we don't have X toolkit support.  */
 1134 
 1135 static INLINE void
 1136 x_set_glyph_string_clipping (s)
 1137      struct glyph_string *s;
 1138 {
 1139   XRectangle *r = s->clip;
 1140   int n = get_glyph_string_clip_rects (s, r, 2);
 1141 
 1142   if (n > 0)
 1143     XSetClipRectangles (s->display, s->gc, 0, 0, r, n, Unsorted);
 1144   s->num_clips = n;
 1145 }
 1146 
 1147 
 1148 /* Set SRC's clipping for output of glyph string DST.  This is called
 1149    when we are drawing DST's left_overhang or right_overhang only in
 1150    the area of SRC.  */
 1151 
 1152 static void
 1153 x_set_glyph_string_clipping_exactly (src, dst)
 1154      struct glyph_string *src, *dst;
 1155 {
 1156   XRectangle r;
 1157 
 1158   r.x = src->x;
 1159   r.width = src->width;
 1160   r.y = src->y;
 1161   r.height = src->height;
 1162   dst->clip[0] = r;
 1163   dst->num_clips = 1;
 1164   XSetClipRectangles (dst->display, dst->gc, 0, 0, &r, 1, Unsorted);
 1165 }
 1166 
 1167 
 1168 /* RIF:
 1169    Compute left and right overhang of glyph string S.  */
 1170 
 1171 static void
 1172 x_compute_glyph_string_overhangs (s)
 1173      struct glyph_string *s;
 1174 {
 1175   if (s->cmp == NULL
 1176       && (s->first_glyph->type == CHAR_GLYPH
 1177           || s->first_glyph->type == COMPOSITE_GLYPH))
 1178     {
 1179       struct font_metrics metrics;
 1180 
 1181       if (s->first_glyph->type == CHAR_GLYPH)
 1182         {
 1183           unsigned *code = alloca (sizeof (unsigned) * s->nchars);
 1184           struct font *font = s->font;
 1185           int i;
 1186 
 1187           for (i = 0; i < s->nchars; i++)
 1188             code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
 1189           font->driver->text_extents (font, code, s->nchars, &metrics);
 1190         }
 1191       else
 1192         {
 1193           Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
 1194 
 1195           composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
 1196         }
 1197       s->right_overhang = (metrics.rbearing > metrics.width
 1198                            ? metrics.rbearing - metrics.width : 0);
 1199       s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
 1200     }
 1201   else if (s->cmp)
 1202     {
 1203       s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
 1204       s->left_overhang = - s->cmp->lbearing;
 1205     }
 1206 }
 1207 
 1208 
 1209 /* Fill rectangle X, Y, W, H with background color of glyph string S.  */
 1210 
 1211 static INLINE void
 1212 x_clear_glyph_string_rect (s, x, y, w, h)
 1213      struct glyph_string *s;
 1214      int x, y, w, h;
 1215 {
 1216   XGCValues xgcv;
 1217   XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv);
 1218   XSetForeground (s->display, s->gc, xgcv.background);
 1219   XFillRectangle (s->display, s->window, s->gc, x, y, w, h);
 1220   XSetForeground (s->display, s->gc, xgcv.foreground);
 1221 }
 1222 
 1223 
 1224 /* Draw the background of glyph_string S.  If S->background_filled_p
 1225    is non-zero don't draw it.  FORCE_P non-zero means draw the
 1226    background even if it wouldn't be drawn normally.  This is used
 1227    when a string preceding S draws into the background of S, or S
 1228    contains the first component of a composition.  */
 1229 
 1230 static void
 1231 x_draw_glyph_string_background (s, force_p)
 1232      struct glyph_string *s;
 1233      int force_p;
 1234 {
 1235   /* Nothing to do if background has already been drawn or if it
 1236      shouldn't be drawn in the first place.  */
 1237   if (!s->background_filled_p)
 1238     {
 1239       int box_line_width = max (s->face->box_line_width, 0);
 1240 
 1241       if (s->stippled_p)
 1242         {
 1243           /* Fill background with a stipple pattern.  */
 1244           XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
 1245           XFillRectangle (s->display, s->window, s->gc, s->x,
 1246                           s->y + box_line_width,
 1247                           s->background_width,
 1248                           s->height - 2 * box_line_width);
 1249           XSetFillStyle (s->display, s->gc, FillSolid);
 1250           s->background_filled_p = 1;
 1251         }
 1252       else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
 1253                || s->font_not_found_p
 1254                || s->extends_to_end_of_line_p
 1255                || force_p)
 1256         {
 1257           x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
 1258                                      s->background_width,
 1259                                      s->height - 2 * box_line_width);
 1260           s->background_filled_p = 1;
 1261         }
 1262     }
 1263 }
 1264 
 1265 
 1266 /* Draw the foreground of glyph string S.  */
 1267 
 1268 static void
 1269 x_draw_glyph_string_foreground (s)
 1270      struct glyph_string *s;
 1271 {
 1272   int i, x;
 1273 
 1274   /* If first glyph of S has a left box line, start drawing the text
 1275      of S to the right of that box line.  */
 1276   if (s->face->box != FACE_NO_BOX
 1277       && s->first_glyph->left_box_line_p)
 1278     x = s->x + eabs (s->face->box_line_width);
 1279   else
 1280     x = s->x;
 1281 
 1282   /* Draw characters of S as rectangles if S's font could not be
 1283      loaded.  */
 1284   if (s->font_not_found_p)
 1285     {
 1286       for (i = 0; i < s->nchars; ++i)
 1287         {
 1288           struct glyph *g = s->first_glyph + i;
 1289           XDrawRectangle (s->display, s->window,
 1290                           s->gc, x, s->y, g->pixel_width - 1,
 1291                           s->height - 1);
 1292           x += g->pixel_width;
 1293         }
 1294     }
 1295   else
 1296     {
 1297       struct font *font = s->font;
 1298       int boff = font->baseline_offset;
 1299       int y;
 1300 
 1301       if (font->vertical_centering)
 1302         boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
 1303 
 1304       y = s->ybase - boff;
 1305       if (s->for_overlaps
 1306           || (s->background_filled_p && s->hl != DRAW_CURSOR))
 1307         font->driver->draw (s, 0, s->nchars, x, y, 0);
 1308       else
 1309         font->driver->draw (s, 0, s->nchars, x, y, 1);
 1310       if (s->face->overstrike)
 1311         font->driver->draw (s, 0, s->nchars, x + 1, y, 0);
 1312     }
 1313 }
 1314 
 1315 /* Draw the foreground of composite glyph string S.  */
 1316 
 1317 static void
 1318 x_draw_composite_glyph_string_foreground (s)
 1319      struct glyph_string *s;
 1320 {
 1321   int i, j, x;
 1322   struct font *font = s->font;
 1323 
 1324   /* If first glyph of S has a left box line, start drawing the text
 1325      of S to the right of that box line.  */
 1326   if (s->face && s->face->box != FACE_NO_BOX
 1327       && s->first_glyph->left_box_line_p)
 1328     x = s->x + eabs (s->face->box_line_width);
 1329   else
 1330     x = s->x;
 1331 
 1332   /* S is a glyph string for a composition.  S->cmp_from is the index
 1333      of the first character drawn for glyphs of this composition.
 1334      S->cmp_from == 0 means we are drawing the very first character of
 1335      this composition.  */
 1336 
 1337   /* Draw a rectangle for the composition if the font for the very
 1338      first character of the composition could not be loaded.  */
 1339   if (s->font_not_found_p)
 1340     {
 1341       if (s->cmp_from == 0)
 1342         XDrawRectangle (s->display, s->window, s->gc, x, s->y,
 1343                         s->width - 1, s->height - 1);
 1344     }
 1345   else if (! s->first_glyph->u.cmp.automatic)
 1346     {
 1347       int y = s->ybase;
 1348 
 1349       for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
 1350         if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
 1351           {
 1352             int xx = x + s->cmp->offsets[j * 2];
 1353             int yy = y - s->cmp->offsets[j * 2 + 1];
 1354 
 1355             font->driver->draw (s, j, j + 1, xx, yy, 0);
 1356             if (s->face->overstrike)
 1357               font->driver->draw (s, j, j + 1, xx + 1, yy, 0);
 1358           }
 1359     }
 1360   else
 1361     {
 1362       Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
 1363       Lisp_Object glyph;
 1364       int y = s->ybase;
 1365       int width = 0;
 1366 
 1367       for (i = j = s->cmp_from; i < s->cmp_to; i++)
 1368         {
 1369           glyph = LGSTRING_GLYPH (gstring, i);
 1370           if (NILP (LGLYPH_ADJUSTMENT (glyph)))
 1371             width += LGLYPH_WIDTH (glyph);
 1372           else
 1373             {
 1374               int xoff, yoff, wadjust;
 1375 
 1376               if (j < i)
 1377                 {
 1378                   font->driver->draw (s, j, i, x, y, 0);
 1379                   if (s->face->overstrike)
 1380                     font->driver->draw (s, j, i, x + 1, y, 0);
 1381                   x += width;
 1382                 }
 1383               xoff = LGLYPH_XOFF (glyph);
 1384               yoff = LGLYPH_YOFF (glyph);
 1385               wadjust = LGLYPH_WADJUST (glyph);
 1386               font->driver->draw (s, i, i + 1, x + xoff, y + yoff, 0);
 1387               if (s->face->overstrike)
 1388                 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff, 0);
 1389               x += wadjust;
 1390               j = i + 1;
 1391               width = 0;
 1392             }
 1393         }
 1394       if (j < i)
 1395         {
 1396           font->driver->draw (s, j, i, x, y, 0);
 1397           if (s->face->overstrike)
 1398             font->driver->draw (s, j, i, x + 1, y, 0);
 1399         }
 1400     }
 1401 }
 1402 
 1403 
 1404 #ifdef USE_X_TOOLKIT
 1405 
 1406 static struct frame *x_frame_of_widget P_ ((Widget));
 1407 static Boolean cvt_string_to_pixel P_ ((Display *, XrmValue *, Cardinal *,
 1408                                         XrmValue *, XrmValue *, XtPointer *));
 1409 static void cvt_pixel_dtor P_ ((XtAppContext, XrmValue *, XtPointer,
 1410                                 XrmValue *, Cardinal *));
 1411 
 1412 
 1413 /* Return the frame on which widget WIDGET is used.. Abort if frame
 1414    cannot be determined.  */
 1415 
 1416 static struct frame *
 1417 x_frame_of_widget (widget)
 1418      Widget widget;
 1419 {
 1420   struct x_display_info *dpyinfo;
 1421   Lisp_Object tail;
 1422   struct frame *f;
 1423 
 1424   dpyinfo = x_display_info_for_display (XtDisplay (widget));
 1425 
 1426   /* Find the top-level shell of the widget.  Note that this function
 1427      can be called when the widget is not yet realized, so XtWindow
 1428      (widget) == 0.  That's the reason we can't simply use
 1429      x_any_window_to_frame.  */
 1430   while (!XtIsTopLevelShell (widget))
 1431     widget = XtParent (widget);
 1432 
 1433   /* Look for a frame with that top-level widget.  Allocate the color
 1434      on that frame to get the right gamma correction value.  */
 1435   for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
 1436     if (FRAMEP (XCAR (tail))
 1437         && (f = XFRAME (XCAR (tail)),
 1438             (FRAME_X_P (f)
 1439              && f->output_data.nothing != 1
 1440              && FRAME_X_DISPLAY_INFO (f) == dpyinfo))
 1441         && f->output_data.x->widget == widget)
 1442       return f;
 1443 
 1444   abort ();
 1445 }
 1446 
 1447 
 1448 /* Allocate the color COLOR->pixel on the screen and display of
 1449    widget WIDGET in colormap CMAP.  If an exact match cannot be
 1450    allocated, try the nearest color available.  Value is non-zero
 1451    if successful.  This is called from lwlib.  */
 1452 
 1453 int
 1454 x_alloc_nearest_color_for_widget (widget, cmap, color)
 1455      Widget widget;
 1456      Colormap cmap;
 1457      XColor *color;
 1458 {
 1459   struct frame *f = x_frame_of_widget (widget);
 1460   return x_alloc_nearest_color (f, cmap, color);
 1461 }
 1462 
 1463 
 1464 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
 1465    or DELTA.  Try a color with RGB values multiplied by FACTOR first.
 1466    If this produces the same color as PIXEL, try a color where all RGB
 1467    values have DELTA added.  Return the allocated color in *PIXEL.
 1468    DISPLAY is the X display, CMAP is the colormap to operate on.
 1469    Value is non-zero if successful.  */
 1470 
 1471 int
 1472 x_alloc_lighter_color_for_widget (widget, display, cmap, pixel, factor, delta)
 1473      Widget widget;
 1474      Display *display;
 1475      Colormap cmap;
 1476      unsigned long *pixel;
 1477      double factor;
 1478      int delta;
 1479 {
 1480   struct frame *f = x_frame_of_widget (widget);
 1481   return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
 1482 }
 1483 
 1484 
 1485 /* Structure specifying which arguments should be passed by Xt to
 1486    cvt_string_to_pixel.  We want the widget's screen and colormap.  */
 1487 
 1488 static XtConvertArgRec cvt_string_to_pixel_args[] =
 1489   {
 1490     {XtWidgetBaseOffset, (XtPointer) XtOffset (Widget, core.screen),
 1491      sizeof (Screen *)},
 1492     {XtWidgetBaseOffset, (XtPointer) XtOffset (Widget, core.colormap),
 1493      sizeof (Colormap)}
 1494   };
 1495 
 1496 
 1497 /* The address of this variable is returned by
 1498    cvt_string_to_pixel.  */
 1499 
 1500 static Pixel cvt_string_to_pixel_value;
 1501 
 1502 
 1503 /* Convert a color name to a pixel color.
 1504 
 1505    DPY is the display we are working on.
 1506 
 1507    ARGS is an array of *NARGS XrmValue structures holding additional
 1508    information about the widget for which the conversion takes place.
 1509    The contents of this array are determined by the specification
 1510    in cvt_string_to_pixel_args.
 1511 
 1512    FROM is a pointer to an XrmValue which points to the color name to
 1513    convert.  TO is an XrmValue in which to return the pixel color.
 1514 
 1515    CLOSURE_RET is a pointer to user-data, in which we record if
 1516    we allocated the color or not.
 1517 
 1518    Value is True if successful, False otherwise.  */
 1519 
 1520 static Boolean
 1521 cvt_string_to_pixel (dpy, args, nargs, from, to, closure_ret)
 1522      Display *dpy;
 1523      XrmValue *args;
 1524      Cardinal *nargs;
 1525      XrmValue *from, *to;
 1526      XtPointer *closure_ret;
 1527 {
 1528   Screen *screen;
 1529   Colormap cmap;
 1530   Pixel pixel;
 1531   String color_name;
 1532   XColor color;
 1533 
 1534   if (*nargs != 2)
 1535     {
 1536       XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
 1537                        "wrongParameters", "cvt_string_to_pixel",
 1538                        "XtToolkitError",
 1539                        "Screen and colormap args required", NULL, NULL);
 1540       return False;
 1541     }
 1542 
 1543   screen = *(Screen **) args[0].addr;
 1544   cmap = *(Colormap *) args[1].addr;
 1545   color_name = (String) from->addr;
 1546 
 1547   if (strcmp (color_name, XtDefaultBackground) == 0)
 1548     {
 1549       *closure_ret = (XtPointer) False;
 1550       pixel = WhitePixelOfScreen (screen);
 1551     }
 1552   else if (strcmp (color_name, XtDefaultForeground) == 0)
 1553     {
 1554       *closure_ret = (XtPointer) False;
 1555       pixel = BlackPixelOfScreen (screen);
 1556     }
 1557   else if (XParseColor (dpy, cmap, color_name, &color)
 1558            && x_alloc_nearest_color_1 (dpy, cmap, &color))
 1559     {
 1560       pixel = color.pixel;
 1561       *closure_ret = (XtPointer) True;
 1562     }
 1563   else
 1564     {
 1565       String params[1];
 1566       Cardinal nparams = 1;
 1567 
 1568       params[0] = color_name;
 1569       XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
 1570                        "badValue", "cvt_string_to_pixel",
 1571                        "XtToolkitError", "Invalid color `%s'",
 1572                        params, &nparams);
 1573       return False;
 1574     }
 1575 
 1576   if (to->addr != NULL)
 1577     {
 1578       if (to->size < sizeof (Pixel))
 1579         {
 1580           to->size = sizeof (Pixel);
 1581           return False;
 1582         }
 1583 
 1584       *(Pixel *) to->addr = pixel;
 1585     }
 1586   else
 1587     {
 1588       cvt_string_to_pixel_value = pixel;
 1589       to->addr = (XtPointer) &cvt_string_to_pixel_value;
 1590     }
 1591 
 1592   to->size = sizeof (Pixel);
 1593   return True;
 1594 }
 1595 
 1596 
 1597 /* Free a pixel color which was previously allocated via
 1598    cvt_string_to_pixel.  This is registered as the destructor
 1599    for this type of resource via XtSetTypeConverter.
 1600 
 1601    APP is the application context in which we work.
 1602 
 1603    TO is a pointer to an XrmValue holding the color to free.
 1604    CLOSURE is the value we stored in CLOSURE_RET for this color
 1605    in cvt_string_to_pixel.
 1606 
 1607    ARGS and NARGS are like for cvt_string_to_pixel.  */
 1608 
 1609 static void
 1610 cvt_pixel_dtor (app, to, closure, args, nargs)
 1611     XtAppContext app;
 1612     XrmValuePtr to;
 1613     XtPointer closure;
 1614     XrmValuePtr args;
 1615     Cardinal *nargs;
 1616 {
 1617   if (*nargs != 2)
 1618     {
 1619       XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
 1620                        "XtToolkitError",
 1621                        "Screen and colormap arguments required",
 1622                        NULL, NULL);
 1623     }
 1624   else if (closure != NULL)
 1625     {
 1626       /* We did allocate the pixel, so free it.  */
 1627       Screen *screen = *(Screen **) args[0].addr;
 1628       Colormap cmap = *(Colormap *) args[1].addr;
 1629       x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
 1630                          (Pixel *) to->addr, 1);
 1631     }
 1632 }
 1633 
 1634 
 1635 #endif /* USE_X_TOOLKIT */
 1636 
 1637 
 1638 /* Value is an array of XColor structures for the contents of the
 1639    color map of display DPY.  Set *NCELLS to the size of the array.
 1640    Note that this probably shouldn't be called for large color maps,
 1641    say a 24-bit TrueColor map.  */
 1642 
 1643 static const XColor *
 1644 x_color_cells (dpy, ncells)
 1645      Display *dpy;
 1646      int *ncells;
 1647 {
 1648   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
 1649 
 1650   if (dpyinfo->color_cells == NULL)
 1651     {
 1652       Screen *screen = dpyinfo->screen;
 1653       int i;
 1654 
 1655       dpyinfo->ncolor_cells
 1656         = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
 1657       dpyinfo->color_cells
 1658         = (XColor *) xmalloc (dpyinfo->ncolor_cells
 1659                               * sizeof *dpyinfo->color_cells);
 1660 
 1661       for (i = 0; i < dpyinfo->ncolor_cells; ++i)
 1662         dpyinfo->color_cells[i].pixel = i;
 1663 
 1664       XQueryColors (dpy, dpyinfo->cmap,
 1665                     dpyinfo->color_cells, dpyinfo->ncolor_cells);
 1666     }
 1667 
 1668   *ncells = dpyinfo->ncolor_cells;
 1669   return dpyinfo->color_cells;
 1670 }
 1671 
 1672 
 1673 /* On frame F, translate pixel colors to RGB values for the NCOLORS
 1674    colors in COLORS.  Use cached information, if available.  */
 1675 
 1676 void
 1677 x_query_colors (f, colors, ncolors)
 1678      struct frame *f;
 1679      XColor *colors;
 1680      int ncolors;
 1681 {
 1682   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
 1683 
 1684   if (dpyinfo->color_cells)
 1685     {
 1686       int i;
 1687       for (i = 0; i < ncolors; ++i)
 1688         {
 1689           unsigned long pixel = colors[i].pixel;
 1690           xassert (pixel < dpyinfo->ncolor_cells);
 1691           xassert (dpyinfo->color_cells[pixel].pixel == pixel);
 1692           colors[i] = dpyinfo->color_cells[pixel];
 1693         }
 1694     }
 1695   else
 1696     XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
 1697 }
 1698 
 1699 
 1700 /* On frame F, translate pixel color to RGB values for the color in
 1701    COLOR.  Use cached information, if available.  */
 1702 
 1703 void
 1704 x_query_color (f, color)
 1705      struct frame *f;
 1706      XColor *color;
 1707 {
 1708   x_query_colors (f, color, 1);
 1709 }
 1710 
 1711 
 1712 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP.  If an
 1713    exact match can't be allocated, try the nearest color available.
 1714    Value is non-zero if successful.  Set *COLOR to the color
 1715    allocated.  */
 1716 
 1717 static int
 1718 x_alloc_nearest_color_1 (dpy, cmap, color)
 1719      Display *dpy;
 1720      Colormap cmap;
 1721      XColor *color;
 1722 {
 1723   int rc;
 1724 
 1725   rc = XAllocColor (dpy, cmap, color);
 1726   if (rc == 0)
 1727     {
 1728       /* If we got to this point, the colormap is full, so we're going
 1729          to try to get the next closest color.  The algorithm used is
 1730          a least-squares matching, which is what X uses for closest
 1731          color matching with StaticColor visuals.  */
 1732       int nearest, i;
 1733       unsigned long nearest_delta = ~0;
 1734       int ncells;
 1735       const XColor *cells = x_color_cells (dpy, &ncells);
 1736 
 1737       for (nearest = i = 0; i < ncells; ++i)
 1738         {
 1739           long dred   = (color->red   >> 8) - (cells[i].red   >> 8);
 1740           long dgreen = (color->green >> 8) - (cells[i].green >> 8);
 1741           long dblue  = (color->blue  >> 8) - (cells[i].blue  >> 8);
 1742           unsigned long delta = dred * dred + dgreen * dgreen + dblue * dblue;
 1743 
 1744           if (delta < nearest_delta)
 1745             {
 1746               nearest = i;
 1747               nearest_delta = delta;
 1748             }
 1749         }
 1750 
 1751       color->red   = cells[nearest].red;
 1752       color->green = cells[nearest].green;
 1753       color->blue  = cells[nearest].blue;
 1754       rc = XAllocColor (dpy, cmap, color);
 1755     }
 1756   else
 1757     {
 1758       /* If allocation succeeded, and the allocated pixel color is not
 1759          equal to a cached pixel color recorded earlier, there was a
 1760          change in the colormap, so clear the color cache.  */
 1761       struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
 1762       XColor *cached_color;
 1763 
 1764       if (dpyinfo->color_cells
 1765           && (cached_color = &dpyinfo->color_cells[color->pixel],
 1766               (cached_color->red != color->red
 1767                || cached_color->blue != color->blue
 1768                || cached_color->green != color->green)))
 1769         {
 1770           xfree (dpyinfo->color_cells);
 1771           dpyinfo->color_cells = NULL;
 1772           dpyinfo->ncolor_cells = 0;
 1773         }
 1774     }
 1775 
 1776 #ifdef DEBUG_X_COLORS
 1777   if (rc)
 1778     register_color (color->pixel);
 1779 #endif /* DEBUG_X_COLORS */
 1780 
 1781   return rc;
 1782 }
 1783 
 1784 
 1785 /* Allocate the color COLOR->pixel on frame F, colormap CMAP.  If an
 1786    exact match can't be allocated, try the nearest color available.
 1787    Value is non-zero if successful.  Set *COLOR to the color
 1788    allocated.  */
 1789 
 1790 int
 1791 x_alloc_nearest_color (f, cmap, color)
 1792      struct frame *f;
 1793      Colormap cmap;
 1794      XColor *color;
 1795 {
 1796   gamma_correct (f, color);
 1797   return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
 1798 }
 1799 
 1800 
 1801 /* Allocate color PIXEL on frame F.  PIXEL must already be allocated.
 1802    It's necessary to do this instead of just using PIXEL directly to
 1803    get color reference counts right.  */
 1804 
 1805 unsigned long
 1806 x_copy_color (f, pixel)
 1807      struct frame *f;
 1808      unsigned long pixel;
 1809 {
 1810   XColor color;
 1811 
 1812   color.pixel = pixel;
 1813   BLOCK_INPUT;
 1814   x_query_color (f, &color);
 1815   XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
 1816   UNBLOCK_INPUT;
 1817 #ifdef DEBUG_X_COLORS
 1818   register_color (pixel);
 1819 #endif
 1820   return color.pixel;
 1821 }
 1822 
 1823 
 1824 /* Allocate color PIXEL on display DPY.  PIXEL must already be allocated.
 1825    It's necessary to do this instead of just using PIXEL directly to
 1826    get color reference counts right.  */
 1827 
 1828 unsigned long
 1829 x_copy_dpy_color (dpy, cmap, pixel)
 1830      Display *dpy;
 1831      Colormap cmap;
 1832      unsigned long pixel;
 1833 {
 1834   XColor color;
 1835 
 1836   color.pixel = pixel;
 1837   BLOCK_INPUT;
 1838   XQueryColor (dpy, cmap, &color);
 1839   XAllocColor (dpy, cmap, &color);
 1840   UNBLOCK_INPUT;
 1841 #ifdef DEBUG_X_COLORS
 1842   register_color (pixel);
 1843 #endif
 1844   return color.pixel;
 1845 }
 1846 
 1847 
 1848 /* Brightness beyond which a color won't have its highlight brightness
 1849    boosted.
 1850 
 1851    Nominally, highlight colors for `3d' faces are calculated by
 1852    brightening an object's color by a constant scale factor, but this
 1853    doesn't yield good results for dark colors, so for colors who's
 1854    brightness is less than this value (on a scale of 0-65535) have an
 1855    use an additional additive factor.
 1856 
 1857    The value here is set so that the default menu-bar/mode-line color
 1858    (grey75) will not have its highlights changed at all.  */
 1859 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
 1860 
 1861 
 1862 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
 1863    or DELTA.  Try a color with RGB values multiplied by FACTOR first.
 1864    If this produces the same color as PIXEL, try a color where all RGB
 1865    values have DELTA added.  Return the allocated color in *PIXEL.
 1866    DISPLAY is the X display, CMAP is the colormap to operate on.
 1867    Value is non-zero if successful.  */
 1868 
 1869 static int
 1870 x_alloc_lighter_color (f, display, cmap, pixel, factor, delta)
 1871      struct frame *f;
 1872      Display *display;
 1873      Colormap cmap;
 1874      unsigned long *pixel;
 1875      double factor;
 1876      int delta;
 1877 {
 1878   XColor color, new;
 1879   long bright;
 1880   int success_p;
 1881 
 1882   /* Get RGB color values.  */
 1883   color.pixel = *pixel;
 1884   x_query_color (f, &color);
 1885 
 1886   /* Change RGB values by specified FACTOR.  Avoid overflow!  */
 1887   xassert (factor >= 0);
 1888   new.red = min (0xffff, factor * color.red);
 1889   new.green = min (0xffff, factor * color.green);
 1890   new.blue = min (0xffff, factor * color.blue);
 1891 
 1892   /* Calculate brightness of COLOR.  */
 1893   bright = (2 * color.red + 3 * color.green + color.blue) / 6;
 1894 
 1895   /* We only boost colors that are darker than
 1896      HIGHLIGHT_COLOR_DARK_BOOST_LIMIT.  */
 1897   if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
 1898     /* Make an additive adjustment to NEW, because it's dark enough so
 1899        that scaling by FACTOR alone isn't enough.  */
 1900     {
 1901       /* How far below the limit this color is (0 - 1, 1 being darker).  */
 1902       double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
 1903       /* The additive adjustment.  */
 1904       int min_delta = delta * dimness * factor / 2;
 1905 
 1906       if (factor < 1)
 1907         {
 1908           new.red =   max (0, new.red -   min_delta);
 1909           new.green = max (0, new.green - min_delta);
 1910           new.blue =  max (0, new.blue -  min_delta);
 1911         }
 1912       else
 1913         {
 1914           new.red =   min (0xffff, min_delta + new.red);
 1915           new.green = min (0xffff, min_delta + new.green);
 1916           new.blue =  min (0xffff, min_delta + new.blue);
 1917         }
 1918     }
 1919 
 1920   /* Try to allocate the color.  */
 1921   success_p = x_alloc_nearest_color (f, cmap, &new);
 1922   if (success_p)
 1923     {
 1924       if (new.pixel == *pixel)
 1925         {
 1926           /* If we end up with the same color as before, try adding
 1927              delta to the RGB values.  */
 1928           x_free_colors (f, &new.pixel, 1);
 1929 
 1930           new.red = min (0xffff, delta + color.red);
 1931           new.green = min (0xffff, delta + color.green);
 1932           new.blue = min (0xffff, delta + color.blue);
 1933           success_p = x_alloc_nearest_color (f, cmap, &new);
 1934         }
 1935       else
 1936         success_p = 1;
 1937       *pixel = new.pixel;
 1938     }
 1939 
 1940   return success_p;
 1941 }
 1942 
 1943 
 1944 /* Set up the foreground color for drawing relief lines of glyph
 1945    string S.  RELIEF is a pointer to a struct relief containing the GC
 1946    with which lines will be drawn.  Use a color that is FACTOR or
 1947    DELTA lighter or darker than the relief's background which is found
 1948    in S->f->output_data.x->relief_background.  If such a color cannot
 1949    be allocated, use DEFAULT_PIXEL, instead.  */
 1950 
 1951 static void
 1952 x_setup_relief_color (f, relief, factor, delta, default_pixel)
 1953      struct frame *f;
 1954      struct relief *relief;
 1955      double factor;
 1956      int delta;
 1957      unsigned long default_pixel;
 1958 {
 1959   XGCValues xgcv;
 1960   struct x_output *di = f->output_data.x;
 1961   unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
 1962   unsigned long pixel;
 1963   unsigned long background = di->relief_background;
 1964   Colormap cmap = FRAME_X_COLORMAP (f);
 1965   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
 1966   Display *dpy = FRAME_X_DISPLAY (f);
 1967 
 1968   xgcv.graphics_exposures = False;
 1969   xgcv.line_width = 1;
 1970 
 1971   /* Free previously allocated color.  The color cell will be reused
 1972      when it has been freed as many times as it was allocated, so this
 1973      doesn't affect faces using the same colors.  */
 1974   if (relief->gc
 1975       && relief->allocated_p)
 1976     {
 1977       x_free_colors (f, &relief->pixel, 1);
 1978       relief->allocated_p = 0;
 1979     }
 1980 
 1981   /* Allocate new color.  */
 1982   xgcv.foreground = default_pixel;
 1983   pixel = background;
 1984   if (dpyinfo->n_planes != 1
 1985       && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
 1986     {
 1987       relief->allocated_p = 1;
 1988       xgcv.foreground = relief->pixel = pixel;
 1989     }
 1990 
 1991   if (relief->gc == 0)
 1992     {
 1993       xgcv.stipple = dpyinfo->gray;
 1994       mask |= GCStipple;
 1995       relief->gc = XCreateGC (dpy, FRAME_X_WINDOW (f), mask, &xgcv);
 1996     }
 1997   else
 1998     XChangeGC (dpy, relief->gc, mask, &xgcv);
 1999 }
 2000 
 2001 
 2002 /* Set up colors for the relief lines around glyph string S.  */
 2003 
 2004 static void
 2005 x_setup_relief_colors (s)
 2006      struct glyph_string *s;
 2007 {
 2008   struct x_output *di = s->f->output_data.x;
 2009   unsigned long color;
 2010 
 2011   if (s->face->use_box_color_for_shadows_p)
 2012     color = s->face->box_color;
 2013   else if (s->first_glyph->type == IMAGE_GLYPH
 2014            && s->img->pixmap
 2015            && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
 2016     color = IMAGE_BACKGROUND (s->img, s->f, 0);
 2017   else
 2018     {
 2019       XGCValues xgcv;
 2020 
 2021       /* Get the background color of the face.  */
 2022       XGetGCValues (s->display, s->gc, GCBackground, &xgcv);
 2023       color = xgcv.background;
 2024     }
 2025 
 2026   if (di->white_relief.gc == 0
 2027       || color != di->relief_background)
 2028     {
 2029       di->relief_background = color;
 2030       x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
 2031                             WHITE_PIX_DEFAULT (s->f));
 2032       x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
 2033                             BLACK_PIX_DEFAULT (s->f));
 2034     }
 2035 }
 2036 
 2037 
 2038 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
 2039    TOP_Y, RIGHT_X, and BOTTOM_Y.  WIDTH is the thickness of the relief
 2040    to draw, it must be >= 0.  RAISED_P non-zero means draw a raised
 2041    relief.  LEFT_P non-zero means draw a relief on the left side of
 2042    the rectangle.  RIGHT_P non-zero means draw a relief on the right
 2043    side of the rectangle.  CLIP_RECT is the clipping rectangle to use
 2044    when drawing.  */
 2045 
 2046 static void
 2047 x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
 2048                     raised_p, top_p, bot_p, left_p, right_p, clip_rect)
 2049      struct frame *f;
 2050      int left_x, top_y, right_x, bottom_y, width;
 2051      int top_p, bot_p, left_p, right_p, raised_p;
 2052      XRectangle *clip_rect;
 2053 {
 2054   Display *dpy = FRAME_X_DISPLAY (f);
 2055   Window window = FRAME_X_WINDOW (f);
 2056   int i;
 2057   GC gc;
 2058 
 2059   if (raised_p)
 2060     gc = f->output_data.x->white_relief.gc;
 2061   else
 2062     gc = f->output_data.x->black_relief.gc;
 2063   XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
 2064 
 2065   /* Top.  */
 2066   if (top_p)
 2067     for (i = 0; i < width; ++i)
 2068       XDrawLine (dpy, window, gc,
 2069                  left_x + i * left_p, top_y + i,
 2070                  right_x + 1 - i * right_p, top_y + i);
 2071 
 2072   /* Left.  */
 2073   if (left_p)
 2074     for (i = 0; i < width; ++i)
 2075       XDrawLine (dpy, window, gc,
 2076                  left_x + i, top_y + i, left_x + i, bottom_y - i + 1);
 2077 
 2078   XSetClipMask (dpy, gc, None);
 2079   if (raised_p)
 2080     gc = f->output_data.x->black_relief.gc;
 2081   else
 2082     gc = f->output_data.x->white_relief.gc;
 2083   XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
 2084 
 2085   /* Bottom.  */
 2086   if (bot_p)
 2087     for (i = 0; i < width; ++i)
 2088       XDrawLine (dpy, window, gc,
 2089                  left_x + i * left_p, bottom_y - i,
 2090                  right_x + 1 - i * right_p, bottom_y - i);
 2091 
 2092   /* Right.  */
 2093   if (right_p)
 2094     for (i = 0; i < width; ++i)
 2095       XDrawLine (dpy, window, gc,
 2096                  right_x - i, top_y + i + 1, right_x - i, bottom_y - i);
 2097 
 2098   XSetClipMask (dpy, gc, None);
 2099 }
 2100 
 2101 
 2102 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
 2103    RIGHT_X, and BOTTOM_Y.  WIDTH is the thickness of the lines to
 2104    draw, it must be >= 0.  LEFT_P non-zero means draw a line on the
 2105    left side of the rectangle.  RIGHT_P non-zero means draw a line
 2106    on the right side of the rectangle.  CLIP_RECT is the clipping
 2107    rectangle to use when drawing.  */
 2108 
 2109 static void
 2110 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
 2111                  left_p, right_p, clip_rect)
 2112      struct glyph_string *s;
 2113      int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
 2114      XRectangle *clip_rect;
 2115 {
 2116   XGCValues xgcv;
 2117 
 2118   XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
 2119   XSetForeground (s->display, s->gc, s->face->box_color);
 2120   XSetClipRectangles (s->display, s->gc, 0, 0, clip_rect, 1, Unsorted);
 2121 
 2122   /* Top.  */
 2123   XFillRectangle (s->display, s->window, s->gc,
 2124                   left_x, top_y, right_x - left_x + 1, width);
 2125 
 2126   /* Left.  */
 2127   if (left_p)
 2128     XFillRectangle (s->display, s->window, s->gc,
 2129                     left_x, top_y, width, bottom_y - top_y + 1);
 2130 
 2131   /* Bottom.  */
 2132   XFillRectangle (s->display, s->window, s->gc,
 2133                   left_x, bottom_y - width + 1, right_x - left_x + 1, width);
 2134 
 2135   /* Right.  */
 2136   if (right_p)
 2137     XFillRectangle (s->display, s->window, s->gc,
 2138                     right_x - width + 1, top_y, width, bottom_y - top_y + 1);
 2139 
 2140   XSetForeground (s->display, s->gc, xgcv.foreground);
 2141   XSetClipMask (s->display, s->gc, None);
 2142 }
 2143 
 2144 
 2145 /* Draw a box around glyph string S.  */
 2146 
 2147 static void
 2148 x_draw_glyph_string_box (s)
 2149      struct glyph_string *s;
 2150 {
 2151   int width, left_x, right_x, top_y, bottom_y, last_x, raised_p;
 2152   int left_p, right_p;
 2153   struct glyph *last_glyph;
 2154   XRectangle clip_rect;
 2155 
 2156   last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
 2157             ? WINDOW_RIGHT_EDGE_X (s->w)
 2158             : window_box_right (s->w, s->area));
 2159 
 2160   /* The glyph that may have a right box line.  */
 2161   last_glyph = (s->cmp || s->img
 2162                 ? s->first_glyph
 2163                 : s->first_glyph + s->nchars - 1);
 2164 
 2165   width = eabs (s->face->box_line_width);
 2166   raised_p = s->face->box == FACE_RAISED_BOX;
 2167   left_x = s->x;
 2168   right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
 2169              ? last_x - 1
 2170              : min (last_x, s->x + s->background_width) - 1);
 2171   top_y = s->y;
 2172   bottom_y = top_y + s->height - 1;
 2173 
 2174   left_p = (s->first_glyph->left_box_line_p
 2175             || (s->hl == DRAW_MOUSE_FACE
 2176                 && (s->prev == NULL
 2177                     || s->prev->hl != s->hl)));
 2178   right_p = (last_glyph->right_box_line_p
 2179              || (s->hl == DRAW_MOUSE_FACE
 2180                  && (s->next == NULL
 2181                      || s->next->hl != s->hl)));
 2182 
 2183   get_glyph_string_clip_rect (s, &clip_rect);
 2184 
 2185   if (s->face->box == FACE_SIMPLE_BOX)
 2186     x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
 2187                      left_p, right_p, &clip_rect);
 2188   else
 2189     {
 2190       x_setup_relief_colors (s);
 2191       x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
 2192                           width, raised_p, 1, 1, left_p, right_p, &clip_rect);
 2193     }
 2194 }
 2195 
 2196 
 2197 /* Draw foreground of image glyph string S.  */
 2198 
 2199 static void
 2200 x_draw_image_foreground (s)
 2201      struct glyph_string *s;
 2202 {
 2203   int x = s->x;
 2204   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
 2205 
 2206   /* If first glyph of S has a left box line, start drawing it to the
 2207      right of that line.  */
 2208   if (s->face->box != FACE_NO_BOX
 2209       && s->first_glyph->left_box_line_p
 2210       && s->slice.x == 0)
 2211     x += eabs (s->face->box_line_width);
 2212 
 2213   /* If there is a margin around the image, adjust x- and y-position
 2214      by that margin.  */
 2215   if (s->slice.x == 0)
 2216     x += s->img->hmargin;
 2217   if (s->slice.y == 0)
 2218     y += s->img->vmargin;
 2219 
 2220   if (s->img->pixmap)
 2221     {
 2222       if (s->img->mask)
 2223         {
 2224           /* We can't set both a clip mask and use XSetClipRectangles
 2225              because the latter also sets a clip mask.  We also can't
 2226              trust on the shape extension to be available
 2227              (XShapeCombineRegion).  So, compute the rectangle to draw
 2228              manually.  */
 2229           unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
 2230                                 | GCFunction);
 2231           XGCValues xgcv;
 2232           XRectangle clip_rect, image_rect, r;
 2233 
 2234           xgcv.clip_mask = s->img->mask;
 2235           xgcv.clip_x_origin = x;
 2236           xgcv.clip_y_origin = y;
 2237           xgcv.function = GXcopy;
 2238           XChangeGC (s->display, s->gc, mask, &xgcv);
 2239 
 2240           get_glyph_string_clip_rect (s, &clip_rect);
 2241           image_rect.x = x;
 2242           image_rect.y = y;
 2243           image_rect.width = s->slice.width;
 2244           image_rect.height = s->slice.height;
 2245           if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
 2246             XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
 2247                        s->slice.x + r.x - x, s->slice.y + r.y - y,
 2248                        r.width, r.height, r.x, r.y);
 2249         }
 2250       else
 2251         {
 2252           XRectangle clip_rect, image_rect, r;
 2253 
 2254           get_glyph_string_clip_rect (s, &clip_rect);
 2255           image_rect.x = x;
 2256           image_rect.y = y;
 2257           image_rect.width = s->slice.width;
 2258           image_rect.height = s->slice.height;
 2259           if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
 2260             XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
 2261                        s->slice.x + r.x - x, s->slice.y + r.y - y,
 2262                        r.width, r.height, r.x, r.y);
 2263 
 2264           /* When the image has a mask, we can expect that at
 2265              least part of a mouse highlight or a block cursor will
 2266              be visible.  If the image doesn't have a mask, make
 2267              a block cursor visible by drawing a rectangle around
 2268              the image.  I believe it's looking better if we do
 2269              nothing here for mouse-face.  */
 2270           if (s->hl == DRAW_CURSOR)
 2271             {
 2272               int r = s->img->relief;
 2273               if (r < 0) r = -r;
 2274               XDrawRectangle (s->display, s->window, s->gc,
 2275                               x - r, y - r,
 2276                               s->slice.width + r*2 - 1,
 2277                               s->slice.height + r*2 - 1);
 2278             }
 2279         }
 2280     }
 2281   else
 2282     /* Draw a rectangle if image could not be loaded.  */
 2283     XDrawRectangle (s->display, s->window, s->gc, x, y,
 2284                     s->slice.width - 1, s->slice.height - 1);
 2285 }
 2286 
 2287 
 2288 /* Draw a relief around the image glyph string S.  */
 2289 
 2290 static void
 2291 x_draw_image_relief (s)
 2292      struct glyph_string *s;
 2293 {
 2294   int x0, y0, x1, y1, thick, raised_p, extra;
 2295   XRectangle r;
 2296   int x = s->x;
 2297   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
 2298 
 2299   /* If first glyph of S has a left box line, start drawing it to the
 2300      right of that line.  */
 2301   if (s->face->box != FACE_NO_BOX
 2302       && s->first_glyph->left_box_line_p
 2303       && s->slice.x == 0)
 2304     x += eabs (s->face->box_line_width);
 2305 
 2306   /* If there is a margin around the image, adjust x- and y-position
 2307      by that margin.  */
 2308   if (s->slice.x == 0)
 2309     x += s->img->hmargin;
 2310   if (s->slice.y == 0)
 2311     y += s->img->vmargin;
 2312 
 2313   if (s->hl == DRAW_IMAGE_SUNKEN
 2314       || s->hl == DRAW_IMAGE_RAISED)
 2315     {
 2316       thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
 2317       raised_p = s->hl == DRAW_IMAGE_RAISED;
 2318     }
 2319   else
 2320     {
 2321       thick = eabs (s->img->relief);
 2322       raised_p = s->img->relief > 0;
 2323     }
 2324 
 2325   extra = s->face->id == TOOL_BAR_FACE_ID
 2326     ? XINT (Vtool_bar_button_margin) : 0;
 2327   
 2328   x0 = x - thick - extra;
 2329   y0 = y - thick - extra;
 2330   x1 = x + s->slice.width + thick - 1 + extra;
 2331   y1 = y + s->slice.height + thick - 1 + extra;
 2332 
 2333   x_setup_relief_colors (s);
 2334   get_glyph_string_clip_rect (s, &r);
 2335   x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p,
 2336                       s->slice.y == 0,
 2337                       s->slice.y + s->slice.height == s->img->height,
 2338                       s->slice.x == 0,
 2339                       s->slice.x + s->slice.width == s->img->width,
 2340                       &r);
 2341 }
 2342 
 2343 
 2344 /* Draw the foreground of image glyph string S to PIXMAP.  */
 2345 
 2346 static void
 2347 x_draw_image_foreground_1 (s, pixmap)
 2348      struct glyph_string *s;
 2349      Pixmap pixmap;
 2350 {
 2351   int x = 0;
 2352   int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
 2353 
 2354   /* If first glyph of S has a left box line, start drawing it to the
 2355      right of that line.  */
 2356   if (s->face->box != FACE_NO_BOX
 2357       && s->first_glyph->left_box_line_p
 2358       && s->slice.x == 0)
 2359     x += eabs (s->face->box_line_width);
 2360 
 2361   /* If there is a margin around the image, adjust x- and y-position
 2362      by that margin.  */
 2363   if (s->slice.x == 0)
 2364     x += s->img->hmargin;
 2365   if (s->slice.y == 0)
 2366     y += s->img->vmargin;
 2367 
 2368   if (s->img->pixmap)
 2369     {
 2370       if (s->img->mask)
 2371         {
 2372           /* We can't set both a clip mask and use XSetClipRectangles
 2373              because the latter also sets a clip mask.  We also can't
 2374              trust on the shape extension to be available
 2375              (XShapeCombineRegion).  So, compute the rectangle to draw
 2376              manually.  */
 2377           unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
 2378                                 | GCFunction);
 2379           XGCValues xgcv;
 2380 
 2381           xgcv.clip_mask = s->img->mask;
 2382           xgcv.clip_x_origin = x - s->slice.x;
 2383           xgcv.clip_y_origin = y - s->slice.y;
 2384           xgcv.function = GXcopy;
 2385           XChangeGC (s->display, s->gc, mask, &xgcv);
 2386 
 2387           XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
 2388                      s->slice.x, s->slice.y,
 2389                      s->slice.width, s->slice.height, x, y);
 2390           XSetClipMask (s->display, s->gc, None);
 2391         }
 2392       else
 2393         {
 2394           XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
 2395                      s->slice.x, s->slice.y,
 2396                      s->slice.width, s->slice.height, x, y);
 2397 
 2398           /* When the image has a mask, we can expect that at
 2399              least part of a mouse highlight or a block cursor will
 2400              be visible.  If the image doesn't have a mask, make
 2401              a block cursor visible by drawing a rectangle around
 2402              the image.  I believe it's looking better if we do
 2403              nothing here for mouse-face.  */
 2404           if (s->hl == DRAW_CURSOR)
 2405             {
 2406               int r = s->img->relief;
 2407               if (r < 0) r = -r;
 2408               XDrawRectangle (s->display, s->window, s->gc, x - r, y - r,
 2409                               s->slice.width + r*2 - 1,
 2410                               s->slice.height + r*2 - 1);
 2411             }
 2412         }
 2413     }
 2414   else
 2415     /* Draw a rectangle if image could not be loaded.  */
 2416     XDrawRectangle (s->display, pixmap, s->gc, x, y,
 2417                     s->slice.width - 1, s->slice.height - 1);
 2418 }
 2419 
 2420 
 2421 /* Draw part of the background of glyph string S.  X, Y, W, and H
 2422    give the rectangle to draw.  */
 2423 
 2424 static void
 2425 x_draw_glyph_string_bg_rect (s, x, y, w, h)
 2426      struct glyph_string *s;
 2427      int x, y, w, h;
 2428 {
 2429   if (s->stippled_p)
 2430     {
 2431       /* Fill background with a stipple pattern.  */
 2432       XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
 2433       XFillRectangle (s->display, s->window, s->gc, x, y, w, h);
 2434       XSetFillStyle (s->display, s->gc, FillSolid);
 2435     }
 2436   else
 2437     x_clear_glyph_string_rect (s, x, y, w, h);
 2438 }
 2439 
 2440 
 2441 /* Draw image glyph string S.
 2442 
 2443             s->y
 2444    s->x      +-------------------------
 2445              |   s->face->box
 2446              |
 2447              |     +-------------------------
 2448              |     |  s->img->margin
 2449              |     |
 2450              |     |       +-------------------
 2451              |     |       |  the image
 2452 
 2453  */
 2454 
 2455 static void
 2456 x_draw_image_glyph_string (s)
 2457      struct glyph_string *s;
 2458 {
 2459   int box_line_hwidth = eabs (s->face->box_line_width);
 2460   int box_line_vwidth = max (s->face->box_line_width, 0);
 2461   int height;
 2462   Pixmap pixmap = None;
 2463 
 2464   height = s->height;
 2465   if (s->slice.y == 0)
 2466     height -= box_line_vwidth;
 2467   if (s->slice.y + s->slice.height >= s->img->height)
 2468     height -= box_line_vwidth;
 2469 
 2470   /* Fill background with face under the image.  Do it only if row is
 2471      taller than image or if image has a clip mask to reduce
 2472      flickering.  */
 2473   s->stippled_p = s->face->stipple != 0;
 2474   if (height > s->slice.height
 2475       || s->img->hmargin
 2476       || s->img->vmargin
 2477       || s->img->mask
 2478       || s->img->pixmap == 0
 2479       || s->width != s->background_width)
 2480     {
 2481       if (s->img->mask)
 2482         {
 2483           /* Create a pixmap as large as the glyph string.  Fill it
 2484              with the background color.  Copy the image to it, using
 2485              its mask.  Copy the temporary pixmap to the display.  */
 2486           Screen *screen = FRAME_X_SCREEN (s->f);
 2487           int depth = DefaultDepthOfScreen (screen);
 2488 
 2489           /* Create a pixmap as large as the glyph string.  */
 2490           pixmap = XCreatePixmap (s->display, s->window,
 2491                                   s->background_width,
 2492                                   s->height, depth);
 2493 
 2494           /* Don't clip in the following because we're working on the
 2495              pixmap.  */
 2496           XSetClipMask (s->display, s->gc, None);
 2497 
 2498           /* Fill the pixmap with the background color/stipple.  */
 2499           if (s->stippled_p)
 2500             {
 2501               /* Fill background with a stipple pattern.  */
 2502               XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
 2503               XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
 2504               XFillRectangle (s->display, pixmap, s->gc,
 2505                               0, 0, s->background_width, s->height);
 2506               XSetFillStyle (s->display, s->gc, FillSolid);
 2507               XSetTSOrigin (s->display, s->gc, 0, 0);
 2508             }
 2509           else
 2510             {
 2511               XGCValues xgcv;
 2512               XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
 2513                             &xgcv);
 2514               XSetForeground (s->display, s->gc, xgcv.background);
 2515               XFillRectangle (s->display, pixmap, s->gc,
 2516                               0, 0, s->background_width, s->height);
 2517               XSetForeground (s->display, s->gc, xgcv.foreground);
 2518             }
 2519         }
 2520       else
 2521         {
 2522           int x = s->x;
 2523           int y = s->y;
 2524 
 2525           if (s->first_glyph->left_box_line_p
 2526               && s->slice.x == 0)
 2527             x += box_line_hwidth;
 2528 
 2529           if (s->slice.y == 0)
 2530             y += box_line_vwidth;
 2531 
 2532           x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
 2533         }
 2534 
 2535       s->background_filled_p = 1;
 2536     }
 2537 
 2538   /* Draw the foreground.  */
 2539   if (pixmap != None)
 2540     {
 2541       x_draw_image_foreground_1 (s, pixmap);
 2542       x_set_glyph_string_clipping (s);
 2543       XCopyArea (s->display, pixmap, s->window, s->gc,
 2544                  0, 0, s->background_width, s->height, s->x, s->y);
 2545       XFreePixmap (s->display, pixmap);
 2546     }
 2547   else
 2548     x_draw_image_foreground (s);
 2549 
 2550   /* If we must draw a relief around the image, do it.  */
 2551   if (s->img->relief
 2552       || s->hl == DRAW_IMAGE_RAISED
 2553       || s->hl == DRAW_IMAGE_SUNKEN)
 2554     x_draw_image_relief (s);
 2555 }
 2556 
 2557 
 2558 /* Draw stretch glyph string S.  */
 2559 
 2560 static void
 2561 x_draw_stretch_glyph_string (s)
 2562      struct glyph_string *s;
 2563 {
 2564   xassert (s->first_glyph->type == STRETCH_GLYPH);
 2565 
 2566   if (s->hl == DRAW_CURSOR
 2567       && !x_stretch_cursor_p)
 2568     {
 2569       /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
 2570          as wide as the stretch glyph.  */
 2571       int width, background_width = s->background_width;
 2572       int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
 2573 
 2574       if (x < left_x)
 2575         {
 2576           background_width -= left_x - x;
 2577           x = left_x;
 2578         }
 2579       width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
 2580 
 2581       /* Draw cursor.  */
 2582       x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
 2583 
 2584       /* Clear rest using the GC of the original non-cursor face.  */
 2585       if (width < background_width)
 2586         {
 2587           int y = s->y;
 2588           int w = background_width - width, h = s->height;
 2589           XRectangle r;
 2590           GC gc;
 2591 
 2592           x += width;
 2593           if (s->row->mouse_face_p
 2594               && cursor_in_mouse_face_p (s->w))
 2595             {
 2596               x_set_mouse_face_gc (s);
 2597               gc = s->gc;
 2598             }
 2599           else
 2600             gc = s->face->gc;
 2601 
 2602           get_glyph_string_clip_rect (s, &r);
 2603           XSetClipRectangles (s->display, gc, 0, 0, &r, 1, Unsorted);
 2604 
 2605           if (s->face->stipple)
 2606             {
 2607               /* Fill background with a stipple pattern.  */
 2608               XSetFillStyle (s->display, gc, FillOpaqueStippled);
 2609               XFillRectangle (s->display, s->window, gc, x, y, w, h);
 2610               XSetFillStyle (s->display, gc, FillSolid);
 2611             }
 2612           else
 2613             {
 2614               XGCValues xgcv;
 2615               XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
 2616               XSetForeground (s->display, gc, xgcv.background);
 2617               XFillRectangle (s->display, s->window, gc, x, y, w, h);
 2618               XSetForeground (s->display, gc, xgcv.foreground);
 2619             }
 2620         }
 2621     }
 2622   else if (!s->background_filled_p)
 2623     {
 2624       int background_width = s->background_width;
 2625       int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
 2626 
 2627       /* Don't draw into left margin, fringe or scrollbar area
 2628          except for header line and mode line.  */
 2629       if (x < left_x && !s->row->mode_line_p)
 2630         {
 2631           background_width -= left_x - x;
 2632           x = left_x;
 2633         }
 2634       if (background_width > 0)
 2635         x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
 2636     }
 2637 
 2638   s->background_filled_p = 1;
 2639 }
 2640 
 2641 
 2642 /* Draw glyph string S.  */
 2643 
 2644 static void
 2645 x_draw_glyph_string (s)
 2646      struct glyph_string *s;
 2647 {
 2648   int relief_drawn_p = 0;
 2649 
 2650   /* If S draws into the background of its successors, draw the
 2651      background of the successors first so that S can draw into it.
 2652      This makes S->next use XDrawString instead of XDrawImageString.  */
 2653   if (s->next && s->right_overhang && !s->for_overlaps)
 2654     {
 2655       int width;
 2656       struct glyph_string *next;
 2657 
 2658       for (width = 0, next = s->next;
 2659            next && width < s->right_overhang;
 2660            width += next->width, next = next->next)
 2661         if (next->first_glyph->type != IMAGE_GLYPH)
 2662           {
 2663             x_set_glyph_string_gc (next);
 2664             x_set_glyph_string_clipping (next);
 2665             if (next->first_glyph->type == STRETCH_GLYPH)
 2666               x_draw_stretch_glyph_string (next);
 2667             else
 2668               x_draw_glyph_string_background (next, 1);
 2669             next->num_clips = 0;
 2670           }
 2671     }
 2672 
 2673   /* Set up S->gc, set clipping and draw S.  */
 2674   x_set_glyph_string_gc (s);
 2675 
 2676   /* Draw relief (if any) in advance for char/composition so that the
 2677      glyph string can be drawn over it.  */
 2678   if (!s->for_overlaps
 2679       && s->face->box != FACE_NO_BOX
 2680       && (s->first_glyph->type == CHAR_GLYPH
 2681           || s->first_glyph->type == COMPOSITE_GLYPH))
 2682 
 2683     {
 2684       x_set_glyph_string_clipping (s);
 2685       x_draw_glyph_string_background (s, 1);
 2686       x_draw_glyph_string_box (s);
 2687       x_set_glyph_string_clipping (s);
 2688       relief_drawn_p = 1;
 2689     }
 2690   else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
 2691            && !s->clip_tail
 2692            && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
 2693                || (s->next && s->next->hl != s->hl && s->right_overhang)))
 2694     /* We must clip just this glyph.  left_overhang part has already
 2695        drawn when s->prev was drawn, and right_overhang part will be
 2696        drawn later when s->next is drawn. */
 2697     x_set_glyph_string_clipping_exactly (s, s);
 2698   else
 2699     x_set_glyph_string_clipping (s);
 2700 
 2701   switch (s->first_glyph->type)
 2702     {
 2703     case IMAGE_GLYPH:
 2704       x_draw_image_glyph_string (s);
 2705       break;
 2706 
 2707     case STRETCH_GLYPH:
 2708       x_draw_stretch_glyph_string (s);
 2709       break;
 2710 
 2711     case CHAR_GLYPH:
 2712       if (s->for_overlaps)
 2713         s->background_filled_p = 1;
 2714       else
 2715         x_draw_glyph_string_background (s, 0);
 2716       x_draw_glyph_string_foreground (s);
 2717       break;
 2718 
 2719     case COMPOSITE_GLYPH:
 2720       if (s->for_overlaps || (s->cmp_from > 0
 2721                               && ! s->first_glyph->u.cmp.automatic))
 2722         s->background_filled_p = 1;
 2723       else
 2724         x_draw_glyph_string_background (s, 1);
 2725       x_draw_composite_glyph_string_foreground (s);
 2726       break;
 2727 
 2728     default:
 2729       abort ();
 2730     }
 2731 
 2732   if (!s->for_overlaps)
 2733     {
 2734       /* Draw underline.  */
 2735       if (s->face->underline_p)
 2736         {
 2737           unsigned long thickness, position;
 2738           int y;
 2739 
 2740           if (s->prev && s->prev->face->underline_p)
 2741             {
 2742               /* We use the same underline style as the previous one.  */
 2743               thickness = s->prev->underline_thickness;
 2744               position = s->prev->underline_position;
 2745             }
 2746           else
 2747             {
 2748               /* Get the underline thickness.  Default is 1 pixel.  */
 2749               if (s->font && s->font->underline_thickness > 0)
 2750                 thickness = s->font->underline_thickness;
 2751               else
 2752                 thickness = 1;
 2753               if (x_underline_at_descent_line)
 2754                 position = (s->height - thickness) - (s->ybase - s->y);
 2755               else
 2756                 {
 2757                   /* Get the underline position.  This is the recommended
 2758                      vertical offset in pixels from the baseline to the top of
 2759                      the underline.  This is a signed value according to the
 2760                      specs, and its default is
 2761 
 2762                      ROUND ((maximum descent) / 2), with
 2763                      ROUND(x) = floor (x + 0.5)  */
 2764 
 2765                   if (x_use_underline_position_properties
 2766                       && s->font && s->font->underline_position >= 0)
 2767                     position = s->font->underline_position;
 2768                   else if (s->font)
 2769                     position = (s->font->descent + 1) / 2;
 2770                   else
 2771                     position = underline_minimum_offset;
 2772                 }
 2773               position = max (position, underline_minimum_offset);
 2774             }
 2775           /* Check the sanity of thickness and position.  We should
 2776              avoid drawing underline out of the current line area.  */
 2777           if (s->y + s->height <= s->ybase + position)
 2778             position = (s->height - 1) - (s->ybase - s->y);
 2779           if (s->y + s->height < s->ybase + position + thickness)
 2780             thickness = (s->y + s->height) - (s->ybase + position);
 2781           s->underline_thickness = thickness;
 2782           s->underline_position = position;
 2783           y = s->ybase + position;
 2784           if (s->face->underline_defaulted_p)
 2785             XFillRectangle (s->display, s->window, s->gc,
 2786                             s->x, y, s->width, thickness);
 2787           else
 2788             {
 2789               XGCValues xgcv;
 2790               XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
 2791               XSetForeground (s->display, s->gc, s->face->underline_color);
 2792               XFillRectangle (s->display, s->window, s->gc,
 2793                               s->x, y, s->width, thickness);
 2794               XSetForeground (s->display, s->gc, xgcv.foreground);
 2795             }
 2796         }
 2797 
 2798       /* Draw overline.  */
 2799       if (s->face->overline_p)
 2800         {
 2801           unsigned long dy = 0, h = 1;
 2802 
 2803           if (s->face->overline_color_defaulted_p)
 2804             XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
 2805                             s->width, h);
 2806           else
 2807             {
 2808               XGCValues xgcv;
 2809               XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
 2810               XSetForeground (s->display, s->gc, s->face->overline_color);
 2811               XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
 2812                               s->width, h);
 2813               XSetForeground (s->display, s->gc, xgcv.foreground);
 2814             }
 2815         }
 2816 
 2817       /* Draw strike-through.  */
 2818       if (s->face->strike_through_p)
 2819         {
 2820           unsigned long h = 1;
 2821           unsigned long dy = (s->height - h) / 2;
 2822 
 2823           if (s->face->strike_through_color_defaulted_p)
 2824             XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
 2825                             s->width, h);
 2826           else
 2827             {
 2828               XGCValues xgcv;
 2829               XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
 2830               XSetForeground (s->display, s->gc, s->face->strike_through_color);
 2831               XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
 2832                               s->width, h);
 2833               XSetForeground (s->display, s->gc, xgcv.foreground);
 2834             }
 2835         }
 2836 
 2837       /* Draw relief if not yet drawn.  */
 2838       if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
 2839         x_draw_glyph_string_box (s);
 2840 
 2841       if (s->prev)
 2842         {
 2843           struct glyph_string *prev;
 2844 
 2845           for (prev = s->prev; prev; prev = prev->prev)
 2846             if (prev->hl != s->hl
 2847                 && prev->x + prev->width + prev->right_overhang > s->x)
 2848               {
 2849                 /* As prev was drawn while clipped to its own area, we
 2850                    must draw the right_overhang part using s->hl now.  */
 2851                 enum draw_glyphs_face save = prev->hl;
 2852 
 2853                 prev->hl = s->hl;
 2854                 x_set_glyph_string_gc (prev);
 2855                 x_set_glyph_string_clipping_exactly (s, prev);
 2856                 if (prev->first_glyph->type == CHAR_GLYPH)
 2857                   x_draw_glyph_string_foreground (prev);
 2858                 else
 2859                   x_draw_composite_glyph_string_foreground (prev);
 2860                 XSetClipMask (prev->display, prev->gc, None);
 2861                 prev->hl = save;
 2862                 prev->num_clips = 0;
 2863               }
 2864         }
 2865 
 2866       if (s->next)
 2867         {
 2868           struct glyph_string *next;
 2869 
 2870           for (next = s->next; next; next = next->next)
 2871             if (next->hl != s->hl
 2872                 && next->x - next->left_overhang < s->x + s->width)
 2873               {
 2874                 /* As next will be drawn while clipped to its own area,
 2875                    we must draw the left_overhang part using s->hl now.  */
 2876                 enum draw_glyphs_face save = next->hl;
 2877 
 2878                 next->hl = s->hl;
 2879                 x_set_glyph_string_gc (next);
 2880                 x_set_glyph_string_clipping_exactly (s, next);
 2881                 if (next->first_glyph->type == CHAR_GLYPH)
 2882                   x_draw_glyph_string_foreground (next);
 2883                 else
 2884                   x_draw_composite_glyph_string_foreground (next);
 2885                 XSetClipMask (next->display, next->gc, None);
 2886                 next->hl = save;
 2887                 next->num_clips = 0;
 2888               }
 2889         }
 2890     }
 2891 
 2892   /* Reset clipping.  */
 2893   XSetClipMask (s->display, s->gc, None);
 2894   s->num_clips = 0;
 2895 }
 2896 
 2897 /* Shift display to make room for inserted glyphs.   */
 2898 
 2899 void
 2900 x_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
 2901      struct frame *f;
 2902      int x, y, width, height, shift_by;
 2903 {
 2904   XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), FRAME_X_WINDOW (f),
 2905              f->output_data.x->normal_gc,
 2906              x, y, width, height,
 2907              x + shift_by, y);
 2908 }
 2909 
 2910 /* Delete N glyphs at the nominal cursor position.  Not implemented
 2911    for X frames.  */
 2912 
 2913 static void
 2914 x_delete_glyphs (f, n)
 2915      struct frame *f;
 2916      register int n;
 2917 {
 2918   abort ();
 2919 }
 2920 
 2921 
 2922 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
 2923    If they are <= 0, this is probably an error.  */
 2924 
 2925 void
 2926 x_clear_area (dpy, window, x, y, width, height, exposures)
 2927      Display *dpy;
 2928      Window window;
 2929      int x, y;
 2930      int width, height;
 2931      int exposures;
 2932 {
 2933   xassert (width > 0 && height > 0);
 2934   XClearArea (dpy, window, x, y, width, height, exposures);
 2935 }
 2936 
 2937 
 2938 /* Clear an entire frame.  */
 2939 
 2940 static void
 2941 x_clear_frame (struct frame *f)
 2942 {
 2943   /* Clearing the frame will erase any cursor, so mark them all as no
 2944      longer visible.  */
 2945   mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
 2946   output_cursor.hpos = output_cursor.vpos = 0;
 2947   output_cursor.x = -1;
 2948 
 2949   /* We don't set the output cursor here because there will always
 2950      follow an explicit cursor_to.  */
 2951   BLOCK_INPUT;
 2952   XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 2953 
 2954   /* We have to clear the scroll bars, too.  If we have changed
 2955      colors or something like that, then they should be notified.  */
 2956   x_scroll_bar_clear (f);
 2957 
 2958 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
 2959   /* Make sure scroll bars are redrawn.  As they aren't redrawn by
 2960      redisplay, do it here.  */
 2961   gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
 2962 #endif
 2963   
 2964   XFlush (FRAME_X_DISPLAY (f));
 2965 
 2966   UNBLOCK_INPUT;
 2967 }
 2968 
 2969 
 2970 
 2971 /* Invert the middle quarter of the frame for .15 sec.  */
 2972 
 2973 /* We use the select system call to do the waiting, so we have to make
 2974    sure it's available.  If it isn't, we just won't do visual bells.  */
 2975 
 2976 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
 2977 
 2978 
 2979 /* Subtract the `struct timeval' values X and Y, storing the result in
 2980    *RESULT.  Return 1 if the difference is negative, otherwise 0.  */
 2981 
 2982 static int
 2983 timeval_subtract (result, x, y)
 2984      struct timeval *result, x, y;
 2985 {
 2986   /* Perform the carry for the later subtraction by updating y.  This
 2987      is safer because on some systems the tv_sec member is unsigned.  */
 2988   if (x.tv_usec < y.tv_usec)
 2989     {
 2990       int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
 2991       y.tv_usec -= 1000000 * nsec;
 2992       y.tv_sec += nsec;
 2993     }
 2994 
 2995   if (x.tv_usec - y.tv_usec > 1000000)
 2996     {
 2997       int nsec = (y.tv_usec - x.tv_usec) / 1000000;
 2998       y.tv_usec += 1000000 * nsec;
 2999       y.tv_sec -= nsec;
 3000     }
 3001 
 3002   /* Compute the time remaining to wait.  tv_usec is certainly
 3003      positive.  */
 3004   result->tv_sec = x.tv_sec - y.tv_sec;
 3005   result->tv_usec = x.tv_usec - y.tv_usec;
 3006 
 3007   /* Return indication of whether the result should be considered
 3008      negative.  */
 3009   return x.tv_sec < y.tv_sec;
 3010 }
 3011 
 3012 void
 3013 XTflash (f)
 3014      struct frame *f;
 3015 {
 3016   BLOCK_INPUT;
 3017 
 3018   {
 3019 #ifdef USE_GTK
 3020     /* Use Gdk routines to draw.  This way, we won't draw over scroll bars
 3021        when the scroll bars and the edit widget share the same X window.  */
 3022     GdkGCValues vals;
 3023     GdkGC *gc;
 3024     vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
 3025                              ^ FRAME_BACKGROUND_PIXEL (f));
 3026     vals.function = GDK_XOR;
 3027     gc = gdk_gc_new_with_values (FRAME_GTK_WIDGET (f)->window,
 3028                                  &vals,
 3029                                  GDK_GC_FUNCTION
 3030                                  | GDK_GC_FOREGROUND);
 3031 #define XFillRectangle(d, win, gc, x, y, w, h) \
 3032     gdk_draw_rectangle (FRAME_GTK_WIDGET (f)->window, \
 3033                         gc, TRUE, x, y, w, h)
 3034 #else
 3035     GC gc;
 3036 
 3037     /* Create a GC that will use the GXxor function to flip foreground
 3038        pixels into background pixels.  */
 3039     {
 3040       XGCValues values;
 3041 
 3042       values.function = GXxor;
 3043       values.foreground = (FRAME_FOREGROUND_PIXEL (f)
 3044                            ^ FRAME_BACKGROUND_PIXEL (f));
 3045 
 3046       gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 3047                       GCFunction | GCForeground, &values);
 3048     }
 3049 #endif
 3050     {
 3051       /* Get the height not including a menu bar widget.  */
 3052       int height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
 3053       /* Height of each line to flash.  */
 3054       int flash_height = FRAME_LINE_HEIGHT (f);
 3055       /* These will be the left and right margins of the rectangles.  */
 3056       int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
 3057       int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
 3058 
 3059       int width;
 3060 
 3061       /* Don't flash the area between a scroll bar and the frame
 3062          edge it is next to.  */
 3063       switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f))
 3064         {
 3065         case vertical_scroll_bar_left:
 3066           flash_left += VERTICAL_SCROLL_BAR_WIDTH_TRIM;
 3067           break;
 3068 
 3069         case vertical_scroll_bar_right:
 3070           flash_right -= VERTICAL_SCROLL_BAR_WIDTH_TRIM;
 3071           break;
 3072 
 3073         default:
 3074           break;
 3075         }
 3076 
 3077       width = flash_right - flash_left;
 3078 
 3079       /* If window is tall, flash top and bottom line.  */
 3080       if (height > 3 * FRAME_LINE_HEIGHT (f))
 3081         {
 3082           XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 3083                           flash_left,
 3084                           (FRAME_INTERNAL_BORDER_WIDTH (f)
 3085                            + FRAME_TOP_MARGIN_HEIGHT (f)),
 3086                           width, flash_height);
 3087           XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 3088                           flash_left,
 3089                           (height - flash_height
 3090                            - FRAME_INTERNAL_BORDER_WIDTH (f)),
 3091                           width, flash_height);
 3092 
 3093         }
 3094       else
 3095         /* If it is short, flash it all.  */
 3096         XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 3097                         flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
 3098                         width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
 3099 
 3100       x_flush (f);
 3101 
 3102       {
 3103         struct timeval wakeup;
 3104 
 3105         EMACS_GET_TIME (wakeup);
 3106 
 3107         /* Compute time to wait until, propagating carry from usecs.  */
 3108         wakeup.tv_usec += 150000;
 3109         wakeup.tv_sec += (wakeup.tv_usec / 1000000);
 3110         wakeup.tv_usec %= 1000000;
 3111 
 3112         /* Keep waiting until past the time wakeup or any input gets
 3113            available.  */
 3114         while (! detect_input_pending ())
 3115           {
 3116             struct timeval current;
 3117             struct timeval timeout;
 3118 
 3119             EMACS_GET_TIME (current);
 3120 
 3121             /* Break if result would be negative.  */
 3122             if (timeval_subtract (&current, wakeup, current))
 3123               break;
 3124 
 3125             /* How long `select' should wait.  */
 3126             timeout.tv_sec = 0;
 3127             timeout.tv_usec = 10000;
 3128 
 3129             /* Try to wait that long--but we might wake up sooner.  */
 3130             select (0, NULL, NULL, NULL, &timeout);
 3131           }
 3132       }
 3133 
 3134       /* If window is tall, flash top and bottom line.  */
 3135       if (height > 3 * FRAME_LINE_HEIGHT (f))
 3136         {
 3137           XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 3138                           flash_left,
 3139                           (FRAME_INTERNAL_BORDER_WIDTH (f)
 3140                            + FRAME_TOP_MARGIN_HEIGHT (f)),
 3141                           width, flash_height);
 3142           XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 3143                           flash_left,
 3144                           (height - flash_height
 3145                            - FRAME_INTERNAL_BORDER_WIDTH (f)),
 3146                           width, flash_height);
 3147         }
 3148       else
 3149         /* If it is short, flash it all.  */
 3150         XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 3151                         flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
 3152                         width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
 3153 
 3154 #ifdef USE_GTK
 3155       g_object_unref (G_OBJECT (gc));
 3156 #undef XFillRectangle
 3157 #else
 3158       XFreeGC (FRAME_X_DISPLAY (f), gc);
 3159 #endif
 3160       x_flush (f);
 3161     }
 3162   }
 3163 
 3164   UNBLOCK_INPUT;
 3165 }
 3166 
 3167 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
 3168 
 3169 
 3170 static void
 3171 XTtoggle_invisible_pointer (f, invisible)
 3172      FRAME_PTR f;
 3173      int invisible;
 3174 {
 3175   BLOCK_INPUT;
 3176   if (invisible) 
 3177     {
 3178       if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor != 0)
 3179         XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 3180                        FRAME_X_DISPLAY_INFO (f)->invisible_cursor);
 3181     }
 3182   else
 3183     XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 3184                    f->output_data.x->current_cursor);
 3185   f->pointer_invisible = invisible;
 3186   UNBLOCK_INPUT;
 3187 }
 3188 
 3189 
 3190 /* Make audible bell.  */
 3191 
 3192 void
 3193 XTring_bell ()
 3194 {
 3195   struct frame *f = SELECTED_FRAME ();
 3196 
 3197   if (FRAME_X_DISPLAY (f))
 3198     {
 3199 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
 3200       if (visible_bell)
 3201         XTflash (f);
 3202       else
 3203 #endif
 3204         {
 3205           BLOCK_INPUT;
 3206           XBell (FRAME_X_DISPLAY (f), 0);
 3207           XFlush (FRAME_X_DISPLAY (f));
 3208           UNBLOCK_INPUT;
 3209         }
 3210     }
 3211 }
 3212 
 3213 
 3214 /* Specify how many text lines, from the top of the window,
 3215    should be affected by insert-lines and delete-lines operations.
 3216    This, and those operations, are used only within an update
 3217    that is bounded by calls to x_update_begin and x_update_end.  */
 3218 
 3219 static void
 3220 XTset_terminal_window (n)
 3221      register int n;
 3222 {
 3223   /* This function intentionally left blank.  */
 3224 }
 3225 
 3226 
 3227 
 3228 /***********************************************************************
 3229                               Line Dance
 3230  ***********************************************************************/
 3231 
 3232 /* Perform an insert-lines or delete-lines operation, inserting N
 3233    lines or deleting -N lines at vertical position VPOS.  */
 3234 
 3235 static void
 3236 x_ins_del_lines (f, vpos, n)
 3237      struct frame *f;
 3238      int vpos, n;
 3239 {
 3240   abort ();
 3241 }
 3242 
 3243 
 3244 /* Scroll part of the display as described by RUN.  */
 3245 
 3246 static void
 3247 x_scroll_run (w, run)
 3248      struct window *w;
 3249      struct run *run;
 3250 {
 3251   struct frame *f = XFRAME (w->frame);
 3252   int x, y, width, height, from_y, to_y, bottom_y;
 3253 
 3254   /* Get frame-relative bounding box of the text display area of W,
 3255      without mode lines.  Include in this box the left and right
 3256      fringe of W.  */
 3257   window_box (w, -1, &x, &y, &width, &height);
 3258 
 3259   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
 3260   to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
 3261   bottom_y = y + height;
 3262 
 3263   if (to_y < from_y)
 3264     {
 3265       /* Scrolling up.  Make sure we don't copy part of the mode
 3266          line at the bottom.  */
 3267       if (from_y + run->height > bottom_y)
 3268         height = bottom_y - from_y;
 3269       else
 3270         height = run->height;
 3271     }
 3272   else
 3273     {
 3274       /* Scolling down.  Make sure we don't copy over the mode line.
 3275          at the bottom.  */
 3276       if (to_y + run->height > bottom_y)
 3277         height = bottom_y - to_y;
 3278       else
 3279         height = run->height;
 3280     }
 3281 
 3282   BLOCK_INPUT;
 3283 
 3284   /* Cursor off.  Will be switched on again in x_update_window_end.  */
 3285   updated_window = w;
 3286   x_clear_cursor (w);
 3287 
 3288   XCopyArea (FRAME_X_DISPLAY (f),
 3289              FRAME_X_WINDOW (f), FRAME_X_WINDOW (f),
 3290              f->output_data.x->normal_gc,
 3291              x, from_y,
 3292              width, height,
 3293              x, to_y);
 3294 
 3295   UNBLOCK_INPUT;
 3296 }
 3297 
 3298 
 3299 
 3300 /***********************************************************************
 3301                            Exposure Events
 3302  ***********************************************************************/
 3303 
 3304 
 3305 static void
 3306 frame_highlight (f)
 3307      struct frame *f;
 3308 {
 3309   /* We used to only do this if Vx_no_window_manager was non-nil, but
 3310      the ICCCM (section 4.1.6) says that the window's border pixmap
 3311      and border pixel are window attributes which are "private to the
 3312      client", so we can always change it to whatever we want.  */
 3313   BLOCK_INPUT;
 3314   XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 3315                     f->output_data.x->border_pixel);
 3316   UNBLOCK_INPUT;
 3317   x_update_cursor (f, 1);
 3318   x_set_frame_alpha (f);
 3319 }
 3320 
 3321 static void
 3322 frame_unhighlight (f)
 3323      struct frame *f;
 3324 {
 3325   /* We used to only do this if Vx_no_window_manager was non-nil, but
 3326      the ICCCM (section 4.1.6) says that the window's border pixmap
 3327      and border pixel are window attributes which are "private to the
 3328      client", so we can always change it to whatever we want.  */
 3329   BLOCK_INPUT;
 3330   XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 3331                           f->output_data.x->border_tile);
 3332   UNBLOCK_INPUT;
 3333   x_update_cursor (f, 1);
 3334   x_set_frame_alpha (f);
 3335 }
 3336 
 3337 /* The focus has changed.  Update the frames as necessary to reflect
 3338    the new situation.  Note that we can't change the selected frame
 3339    here, because the Lisp code we are interrupting might become confused.
 3340    Each event gets marked with the frame in which it occurred, so the
 3341    Lisp code can tell when the switch took place by examining the events.  */
 3342 
 3343 static void
 3344 x_new_focus_frame (dpyinfo, frame)
 3345      struct x_display_info *dpyinfo;
 3346      struct frame *frame;
 3347 {
 3348   struct frame *old_focus = dpyinfo->x_focus_frame;
 3349 
 3350   if (frame != dpyinfo->x_focus_frame)
 3351     {
 3352       /* Set this before calling other routines, so that they see
 3353          the correct value of x_focus_frame.  */
 3354       dpyinfo->x_focus_frame = frame;
 3355 
 3356       if (old_focus && old_focus->auto_lower)
 3357         x_lower_frame (old_focus);
 3358 
 3359       if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
 3360         pending_autoraise_frame = dpyinfo->x_focus_frame;
 3361       else
 3362         pending_autoraise_frame = 0;
 3363     }
 3364 
 3365   x_frame_rehighlight (dpyinfo);
 3366 }
 3367 
 3368 /* Handle FocusIn and FocusOut state changes for FRAME.
 3369    If FRAME has focus and there exists more than one frame, puts
 3370    a FOCUS_IN_EVENT into *BUFP.  */
 3371 
 3372 static void
 3373 x_focus_changed (type, state, dpyinfo, frame, bufp)
 3374      int type;
 3375      int state;
 3376      struct x_display_info *dpyinfo;
 3377      struct frame *frame;
 3378      struct input_event *bufp;
 3379 {
 3380   if (type == FocusIn)
 3381     {
 3382       if (dpyinfo->x_focus_event_frame != frame)
 3383         {
 3384           x_new_focus_frame (dpyinfo, frame);
 3385           dpyinfo->x_focus_event_frame = frame;
 3386 
 3387           /* Don't stop displaying the initial startup message
 3388              for a switch-frame event we don't need.  */
 3389           if (NILP (Vterminal_frame)
 3390               && CONSP (Vframe_list)
 3391               && !NILP (XCDR (Vframe_list)))
 3392             {
 3393               bufp->kind = FOCUS_IN_EVENT;
 3394               XSETFRAME (bufp->frame_or_window, frame);
 3395             }
 3396         }
 3397 
 3398       frame->output_data.x->focus_state |= state;
 3399 
 3400 #ifdef HAVE_X_I18N
 3401       if (FRAME_XIC (frame))
 3402         XSetICFocus (FRAME_XIC (frame));
 3403 #endif
 3404     }
 3405   else if (type == FocusOut)
 3406     {
 3407       frame->output_data.x->focus_state &= ~state;
 3408 
 3409       if (dpyinfo->x_focus_event_frame == frame)
 3410         {
 3411           dpyinfo->x_focus_event_frame = 0;
 3412           x_new_focus_frame (dpyinfo, 0);
 3413         }
 3414 
 3415 #ifdef HAVE_X_I18N
 3416       if (FRAME_XIC (frame))
 3417         XUnsetICFocus (FRAME_XIC (frame));
 3418 #endif
 3419       if (frame->pointer_invisible)
 3420         XTtoggle_invisible_pointer (frame, 0);
 3421     }
 3422 }
 3423 
 3424 /* The focus may have changed.  Figure out if it is a real focus change,
 3425    by checking both FocusIn/Out and Enter/LeaveNotify events.
 3426 
 3427    Returns FOCUS_IN_EVENT event in *BUFP. */
 3428 
 3429 static void
 3430 x_detect_focus_change (dpyinfo, event, bufp)
 3431      struct x_display_info *dpyinfo;
 3432      XEvent *event;
 3433      struct input_event *bufp;
 3434 {
 3435   struct frame *frame;
 3436 
 3437   frame = x_any_window_to_frame (dpyinfo, event->xany.window);
 3438   if (! frame)
 3439     return;
 3440 
 3441   switch (event->type)
 3442     {
 3443     case EnterNotify:
 3444     case LeaveNotify:
 3445       {
 3446         struct frame *focus_frame = dpyinfo->x_focus_event_frame;
 3447         int focus_state
 3448           = focus_frame ? focus_frame->output_data.x->focus_state : 0;
 3449 
 3450         if (event->xcrossing.detail != NotifyInferior
 3451             && event->xcrossing.focus
 3452             && ! (focus_state & FOCUS_EXPLICIT))
 3453           x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
 3454                            FOCUS_IMPLICIT,
 3455                            dpyinfo, frame, bufp);
 3456       }
 3457       break;
 3458 
 3459     case FocusIn:
 3460     case FocusOut:
 3461       x_focus_changed (event->type,
 3462                        (event->xfocus.detail == NotifyPointer ?
 3463                         FOCUS_IMPLICIT : FOCUS_EXPLICIT),
 3464                        dpyinfo, frame, bufp);
 3465       break;
 3466 
 3467     case ClientMessage:
 3468       if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
 3469         {
 3470           enum xembed_message msg = event->xclient.data.l[1];
 3471           x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
 3472                            FOCUS_EXPLICIT, dpyinfo, frame, bufp);
 3473         }
 3474       break;
 3475     }
 3476 }
 3477 
 3478 
 3479 /* Handle an event saying the mouse has moved out of an Emacs frame.  */
 3480 
 3481 void
 3482 x_mouse_leave (dpyinfo)
 3483      struct x_display_info *dpyinfo;
 3484 {
 3485   x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
 3486 }
 3487 
 3488 /* The focus has changed, or we have redirected a frame's focus to
 3489    another frame (this happens when a frame uses a surrogate
 3490    mini-buffer frame).  Shift the highlight as appropriate.
 3491 
 3492    The FRAME argument doesn't necessarily have anything to do with which
 3493    frame is being highlighted or un-highlighted; we only use it to find
 3494    the appropriate X display info.  */
 3495 
 3496 static void
 3497 XTframe_rehighlight (frame)
 3498      struct frame *frame;
 3499 {
 3500   x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame));
 3501 }
 3502 
 3503 static void
 3504 x_frame_rehighlight (dpyinfo)
 3505      struct x_display_info *dpyinfo;
 3506 {
 3507   struct frame *old_highlight = dpyinfo->x_highlight_frame;
 3508 
 3509   if (dpyinfo->x_focus_frame)
 3510     {
 3511       dpyinfo->x_highlight_frame
 3512         = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
 3513            ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
 3514            : dpyinfo->x_focus_frame);
 3515       if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
 3516         {
 3517           FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame) = Qnil;
 3518           dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame;
 3519         }
 3520     }
 3521   else
 3522     dpyinfo->x_highlight_frame = 0;
 3523 
 3524   if (dpyinfo->x_highlight_frame != old_highlight)
 3525     {
 3526       if (old_highlight)
 3527         frame_unhighlight (old_highlight);
 3528       if (dpyinfo->x_highlight_frame)
 3529         frame_highlight (dpyinfo->x_highlight_frame);
 3530     }
 3531 }
 3532 
 3533 
 3534 
 3535 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc.  */
 3536 
 3537 /* Initialize mode_switch_bit and modifier_meaning.  */
 3538 static void
 3539 x_find_modifier_meanings (dpyinfo)
 3540      struct x_display_info *dpyinfo;
 3541 {
 3542   int min_code, max_code;
 3543   KeySym *syms;
 3544   int syms_per_code;
 3545   XModifierKeymap *mods;
 3546 
 3547   dpyinfo->meta_mod_mask = 0;
 3548   dpyinfo->shift_lock_mask = 0;
 3549   dpyinfo->alt_mod_mask = 0;
 3550   dpyinfo->super_mod_mask = 0;
 3551   dpyinfo->hyper_mod_mask = 0;
 3552 
 3553   XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
 3554 
 3555   syms = XGetKeyboardMapping (dpyinfo->display,
 3556                               min_code, max_code - min_code + 1,
 3557                               &syms_per_code);
 3558   mods = XGetModifierMapping (dpyinfo->display);
 3559 
 3560   /* Scan the modifier table to see which modifier bits the Meta and
 3561      Alt keysyms are on.  */
 3562   {
 3563     int row, col;       /* The row and column in the modifier table.  */
 3564     int found_alt_or_meta;
 3565 
 3566     for (row = 3; row < 8; row++)
 3567     {
 3568       found_alt_or_meta = 0;
 3569       for (col = 0; col < mods->max_keypermod; col++)
 3570         {
 3571           KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
 3572 
 3573           /* Zeroes are used for filler.  Skip them.  */
 3574           if (code == 0)
 3575             continue;
 3576 
 3577           /* Are any of this keycode's keysyms a meta key?  */
 3578           {
 3579             int code_col;
 3580 
 3581             for (code_col = 0; code_col < syms_per_code; code_col++)
 3582               {
 3583                 int sym = syms[((code - min_code) * syms_per_code) + code_col];
 3584 
 3585                 switch (sym)
 3586                   {
 3587                   case XK_Meta_L:
 3588                   case XK_Meta_R:
 3589                     found_alt_or_meta = 1;
 3590                     dpyinfo->meta_mod_mask |= (1 << row);
 3591                     break;
 3592 
 3593                   case XK_Alt_L:
 3594                   case XK_Alt_R:
 3595                     found_alt_or_meta = 1;
 3596                     dpyinfo->alt_mod_mask |= (1 << row);
 3597                     break;
 3598 
 3599                   case XK_Hyper_L:
 3600                   case XK_Hyper_R:
 3601                     if (!found_alt_or_meta)
 3602                       dpyinfo->hyper_mod_mask |= (1 << row);
 3603                     code_col = syms_per_code;
 3604                     col = mods->max_keypermod;
 3605                     break;
 3606 
 3607                   case XK_Super_L:
 3608                   case XK_Super_R:
 3609                     if (!found_alt_or_meta)
 3610                       dpyinfo->super_mod_mask |= (1 << row);
 3611                     code_col = syms_per_code;
 3612                     col = mods->max_keypermod;
 3613                     break;
 3614 
 3615                   case XK_Shift_Lock:
 3616                     /* Ignore this if it's not on the lock modifier.  */
 3617                     if (!found_alt_or_meta && ((1 << row) == LockMask))
 3618                       dpyinfo->shift_lock_mask = LockMask;
 3619                     code_col = syms_per_code;
 3620                     col = mods->max_keypermod;
 3621                     break;
 3622                   }
 3623               }
 3624           }
 3625         }
 3626     }
 3627   }
 3628 
 3629   /* If we couldn't find any meta keys, accept any alt keys as meta keys.  */
 3630   if (! dpyinfo->meta_mod_mask)
 3631     {
 3632       dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
 3633       dpyinfo->alt_mod_mask = 0;
 3634     }
 3635 
 3636   /* If some keys are both alt and meta,
 3637      make them just meta, not alt.  */
 3638   if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
 3639     {
 3640       dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
 3641     }
 3642 
 3643   XFree ((char *) syms);
 3644   XFreeModifiermap (mods);
 3645 }
 3646 
 3647 /* Convert between the modifier bits X uses and the modifier bits
 3648    Emacs uses.  */
 3649 
 3650 unsigned int
 3651 x_x_to_emacs_modifiers (dpyinfo, state)
 3652      struct x_display_info *dpyinfo;
 3653      unsigned int state;
 3654 {
 3655   EMACS_UINT mod_meta = meta_modifier;
 3656   EMACS_UINT mod_alt  = alt_modifier;
 3657   EMACS_UINT mod_hyper = hyper_modifier;
 3658   EMACS_UINT mod_super = super_modifier;
 3659   Lisp_Object tem;
 3660 
 3661   tem = Fget (Vx_alt_keysym, Qmodifier_value);
 3662   if (! EQ (tem, Qnil)) mod_alt = XUINT (tem);
 3663   tem = Fget (Vx_meta_keysym, Qmodifier_value);
 3664   if (! EQ (tem, Qnil)) mod_meta = XUINT (tem);
 3665   tem = Fget (Vx_hyper_keysym, Qmodifier_value);
 3666   if (! EQ (tem, Qnil)) mod_hyper = XUINT (tem);
 3667   tem = Fget (Vx_super_keysym, Qmodifier_value);
 3668   if (! EQ (tem, Qnil)) mod_super = XUINT (tem);
 3669 
 3670 
 3671   return (  ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0)
 3672             | ((state & ControlMask)                    ? ctrl_modifier : 0)
 3673             | ((state & dpyinfo->meta_mod_mask)         ? mod_meta      : 0)
 3674             | ((state & dpyinfo->alt_mod_mask)          ? mod_alt       : 0)
 3675             | ((state & dpyinfo->super_mod_mask)        ? mod_super     : 0)
 3676             | ((state & dpyinfo->hyper_mod_mask)        ? mod_hyper     : 0));
 3677 }
 3678 
 3679 static unsigned int
 3680 x_emacs_to_x_modifiers (dpyinfo, state)
 3681      struct x_display_info *dpyinfo;
 3682      unsigned int state;
 3683 {
 3684   EMACS_UINT mod_meta = meta_modifier;
 3685   EMACS_UINT mod_alt  = alt_modifier;
 3686   EMACS_UINT mod_hyper = hyper_modifier;
 3687   EMACS_UINT mod_super = super_modifier;
 3688 
 3689   Lisp_Object tem;
 3690 
 3691   tem = Fget (Vx_alt_keysym, Qmodifier_value);
 3692   if (! EQ (tem, Qnil)) mod_alt = XUINT (tem);
 3693   tem = Fget (Vx_meta_keysym, Qmodifier_value);
 3694   if (! EQ (tem, Qnil)) mod_meta = XUINT (tem);
 3695   tem = Fget (Vx_hyper_keysym, Qmodifier_value);
 3696   if (! EQ (tem, Qnil)) mod_hyper = XUINT (tem);
 3697   tem = Fget (Vx_super_keysym, Qmodifier_value);
 3698   if (! EQ (tem, Qnil)) mod_super = XUINT (tem);
 3699 
 3700 
 3701   return (  ((state & mod_alt)          ? dpyinfo->alt_mod_mask   : 0)
 3702             | ((state & mod_super)      ? dpyinfo->super_mod_mask : 0)
 3703             | ((state & mod_hyper)      ? dpyinfo->hyper_mod_mask : 0)
 3704             | ((state & shift_modifier) ? ShiftMask        : 0)
 3705             | ((state & ctrl_modifier)  ? ControlMask      : 0)
 3706             | ((state & mod_meta)       ? dpyinfo->meta_mod_mask  : 0));
 3707 }
 3708 
 3709 /* Convert a keysym to its name.  */
 3710 
 3711 char *
 3712 x_get_keysym_name (keysym)
 3713      KeySym keysym;
 3714 {
 3715   char *value;
 3716 
 3717   BLOCK_INPUT;
 3718   value = XKeysymToString (keysym);
 3719   UNBLOCK_INPUT;
 3720 
 3721   return value;
 3722 }
 3723 
 3724 
 3725 
 3726 /* Mouse clicks and mouse movement.  Rah.  */
 3727 
 3728 /* Prepare a mouse-event in *RESULT for placement in the input queue.
 3729 
 3730    If the event is a button press, then note that we have grabbed
 3731    the mouse.  */
 3732 
 3733 static Lisp_Object
 3734 construct_mouse_click (result, event, f)
 3735      struct input_event *result;
 3736      XButtonEvent *event;
 3737      struct frame *f;
 3738 {
 3739   /* Make the event type NO_EVENT; we'll change that when we decide
 3740      otherwise.  */
 3741   result->kind = MOUSE_CLICK_EVENT;
 3742   result->code = event->button - Button1;
 3743   result->timestamp = event->time;
 3744   result->modifiers = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
 3745                                                event->state)
 3746                        | (event->type == ButtonRelease
 3747                           ? up_modifier
 3748                           : down_modifier));
 3749 
 3750   XSETINT (result->x, event->x);
 3751   XSETINT (result->y, event->y);
 3752   XSETFRAME (result->frame_or_window, f);
 3753   result->arg = Qnil;
 3754   return Qnil;
 3755 }
 3756 
 3757 
 3758 /* Function to report a mouse movement to the mainstream Emacs code.
 3759    The input handler calls this.
 3760 
 3761    We have received a mouse movement event, which is given in *event.
 3762    If the mouse is over a different glyph than it was last time, tell
 3763    the mainstream emacs code by setting mouse_moved.  If not, ask for
 3764    another motion event, so we can check again the next time it moves.  */
 3765 
 3766 static XMotionEvent last_mouse_motion_event;
 3767 static Lisp_Object last_mouse_motion_frame;
 3768 
 3769 static int
 3770 note_mouse_movement (frame, event)
 3771      FRAME_PTR frame;
 3772      XMotionEvent *event;
 3773 {
 3774   last_mouse_movement_time = event->time;
 3775   last_mouse_motion_event = *event;
 3776   XSETFRAME (last_mouse_motion_frame, frame);
 3777 
 3778   if (!FRAME_X_OUTPUT (frame))
 3779     return 0;
 3780 
 3781   if (event->window != FRAME_X_WINDOW (frame))
 3782     {
 3783       frame->mouse_moved = 1;
 3784       last_mouse_scroll_bar = Qnil;
 3785       note_mouse_highlight (frame, -1, -1);
 3786       last_mouse_glyph_frame = 0;
 3787       return 1;
 3788     }
 3789 
 3790 
 3791   /* Has the mouse moved off the glyph it was on at the last sighting?  */
 3792   if (frame != last_mouse_glyph_frame
 3793       || event->x < last_mouse_glyph.x
 3794       || event->x >= last_mouse_glyph.x + last_mouse_glyph.width
 3795       || event->y < last_mouse_glyph.y
 3796       || event->y >= last_mouse_glyph.y + last_mouse_glyph.height)
 3797     {
 3798       frame->mouse_moved = 1;
 3799       last_mouse_scroll_bar = Qnil;
 3800       note_mouse_highlight (frame, event->x, event->y);
 3801       /* Remember which glyph we're now on.  */
 3802       remember_mouse_glyph (frame, event->x, event->y, &last_mouse_glyph);
 3803       last_mouse_glyph_frame = frame;
 3804       return 1;
 3805     }
 3806 
 3807   return 0;
 3808 }
 3809 
 3810 
 3811 /************************************************************************
 3812                               Mouse Face
 3813  ************************************************************************/
 3814 
 3815 static void
 3816 redo_mouse_highlight ()
 3817 {
 3818   if (!NILP (last_mouse_motion_frame)
 3819       && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
 3820     note_mouse_highlight (XFRAME (last_mouse_motion_frame),
 3821                           last_mouse_motion_event.x,
 3822                           last_mouse_motion_event.y);
 3823 }
 3824 
 3825 
 3826 
 3827 /* Return the current position of the mouse.
 3828    *FP should be a frame which indicates which display to ask about.
 3829 
 3830    If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
 3831    and *PART to the frame, window, and scroll bar part that the mouse
 3832    is over.  Set *X and *Y to the portion and whole of the mouse's
 3833    position on the scroll bar.
 3834 
 3835    If the mouse movement started elsewhere, set *FP to the frame the
 3836    mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
 3837    the mouse is over.
 3838 
 3839    Set *TIME to the server time-stamp for the time at which the mouse
 3840    was at this position.
 3841 
 3842    Don't store anything if we don't have a valid set of values to report.
 3843 
 3844    This clears the mouse_moved flag, so we can wait for the next mouse
 3845    movement.  */
 3846 
 3847 static void
 3848 XTmouse_position (fp, insist, bar_window, part, x, y, time)
 3849      FRAME_PTR *fp;
 3850      int insist;
 3851      Lisp_Object *bar_window;
 3852      enum scroll_bar_part *part;
 3853      Lisp_Object *x, *y;
 3854      unsigned long *time;
 3855 {
 3856   FRAME_PTR f1;
 3857 
 3858   BLOCK_INPUT;
 3859 
 3860   if (! NILP (last_mouse_scroll_bar) && insist == 0)
 3861     x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
 3862   else
 3863     {
 3864       Window root;
 3865       int root_x, root_y;
 3866 
 3867       Window dummy_window;
 3868       int dummy;
 3869 
 3870       Lisp_Object frame, tail;
 3871 
 3872       /* Clear the mouse-moved flag for every frame on this display.  */
 3873       FOR_EACH_FRAME (tail, frame)
 3874         if (FRAME_X_P (XFRAME (frame))
 3875             && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
 3876           XFRAME (frame)->mouse_moved = 0;
 3877 
 3878       last_mouse_scroll_bar = Qnil;
 3879 
 3880       /* Figure out which root window we're on.  */
 3881       XQueryPointer (FRAME_X_DISPLAY (*fp),
 3882                      DefaultRootWindow (FRAME_X_DISPLAY (*fp)),
 3883 
 3884                      /* The root window which contains the pointer.  */
 3885                      &root,
 3886 
 3887                      /* Trash which we can't trust if the pointer is on
 3888                         a different screen.  */
 3889                      &dummy_window,
 3890 
 3891                      /* The position on that root window.  */
 3892                      &root_x, &root_y,
 3893 
 3894                      /* More trash we can't trust.  */
 3895                      &dummy, &dummy,
 3896 
 3897                      /* Modifier keys and pointer buttons, about which
 3898                         we don't care.  */
 3899                      (unsigned int *) &dummy);
 3900 
 3901       /* Now we have a position on the root; find the innermost window
 3902          containing the pointer.  */
 3903       {
 3904         Window win, child;
 3905         int win_x, win_y;
 3906         int parent_x = 0, parent_y = 0;
 3907 
 3908         win = root;
 3909 
 3910         /* XTranslateCoordinates can get errors if the window
 3911            structure is changing at the same time this function
 3912            is running.  So at least we must not crash from them.  */
 3913 
 3914         x_catch_errors (FRAME_X_DISPLAY (*fp));
 3915 
 3916         if (FRAME_X_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
 3917             && FRAME_LIVE_P (last_mouse_frame))
 3918           {
 3919             /* If mouse was grabbed on a frame, give coords for that frame
 3920                even if the mouse is now outside it.  */
 3921             XTranslateCoordinates (FRAME_X_DISPLAY (*fp),
 3922 
 3923                                    /* From-window, to-window.  */
 3924                                    root, FRAME_X_WINDOW (last_mouse_frame),
 3925 
 3926                                    /* From-position, to-position.  */
 3927                                    root_x, root_y, &win_x, &win_y,
 3928 
 3929                                    /* Child of win.  */
 3930                                    &child);
 3931             f1 = last_mouse_frame;
 3932           }
 3933         else
 3934           {
 3935             while (1)
 3936               {
 3937                 XTranslateCoordinates (FRAME_X_DISPLAY (*fp),
 3938 
 3939                                        /* From-window, to-window.  */
 3940                                        root, win,
 3941 
 3942                                        /* From-position, to-position.  */
 3943                                        root_x, root_y, &win_x, &win_y,
 3944 
 3945                                        /* Child of win.  */
 3946                                        &child);
 3947 
 3948                 if (child == None || child == win)
 3949                   break;
 3950 #ifdef USE_GTK
 3951                 /* We don't wan't to know the innermost window.  We
 3952                    want the edit window.  For non-Gtk+ the innermost
 3953                    window is the edit window.  For Gtk+ it might not
 3954                    be.  It might be the tool bar for example.  */
 3955                 if (x_window_to_frame (FRAME_X_DISPLAY_INFO (*fp), win))
 3956                   break;
 3957 #endif
 3958                 win = child;
 3959                 parent_x = win_x;
 3960                 parent_y = win_y;
 3961               }
 3962 
 3963             /* Now we know that:
 3964                win is the innermost window containing the pointer
 3965                (XTC says it has no child containing the pointer),
 3966                win_x and win_y are the pointer's position in it
 3967                (XTC did this the last time through), and
 3968                parent_x and parent_y are the pointer's position in win's parent.
 3969                (They are what win_x and win_y were when win was child.
 3970                If win is the root window, it has no parent, and
 3971                parent_{x,y} are invalid, but that's okay, because we'll
 3972                never use them in that case.)  */
 3973 
 3974 #ifdef USE_GTK
 3975             /* We don't wan't to know the innermost window.  We
 3976                want the edit window.  */
 3977             f1 = x_window_to_frame (FRAME_X_DISPLAY_INFO (*fp), win);
 3978 #else
 3979             /* Is win one of our frames?  */
 3980             f1 = x_any_window_to_frame (FRAME_X_DISPLAY_INFO (*fp), win);
 3981 #endif
 3982 
 3983 #ifdef USE_X_TOOLKIT
 3984             /* If we end up with the menu bar window, say it's not
 3985                on the frame.  */
 3986             if (f1 != NULL
 3987                 && f1->output_data.x->menubar_widget
 3988                 && win == XtWindow (f1->output_data.x->menubar_widget))
 3989               f1 = NULL;
 3990 #endif /* USE_X_TOOLKIT */
 3991           }
 3992 
 3993         if (x_had_errors_p (FRAME_X_DISPLAY (*fp)))
 3994           f1 = 0;
 3995 
 3996         x_uncatch_errors ();
 3997 
 3998         /* If not, is it one of our scroll bars?  */
 3999         if (! f1)
 4000           {
 4001             struct scroll_bar *bar;
 4002 
 4003             bar = x_window_to_scroll_bar (FRAME_X_DISPLAY (*fp), win);
 4004 
 4005             if (bar)
 4006               {
 4007                 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 4008                 win_x = parent_x;
 4009                 win_y = parent_y;
 4010               }
 4011           }
 4012 
 4013         if (f1 == 0 && insist > 0)
 4014           f1 = SELECTED_FRAME ();
 4015 
 4016         if (f1)
 4017           {
 4018             /* Ok, we found a frame.  Store all the values.
 4019                last_mouse_glyph is a rectangle used to reduce the
 4020                generation of mouse events.  To not miss any motion
 4021                events, we must divide the frame into rectangles of the
 4022                size of the smallest character that could be displayed
 4023                on it, i.e. into the same rectangles that matrices on
 4024                the frame are divided into.  */
 4025 
 4026             remember_mouse_glyph (f1, win_x, win_y, &last_mouse_glyph);
 4027             last_mouse_glyph_frame = f1;
 4028 
 4029             *bar_window = Qnil;
 4030             *part = 0;
 4031             *fp = f1;
 4032             XSETINT (*x, win_x);
 4033             XSETINT (*y, win_y);
 4034             *time = last_mouse_movement_time;
 4035           }
 4036       }
 4037     }
 4038 
 4039   UNBLOCK_INPUT;
 4040 }
 4041 
 4042 
 4043 
 4044 /***********************************************************************
 4045                                Scroll bars
 4046  ***********************************************************************/
 4047 
 4048 /* Scroll bar support.  */
 4049 
 4050 /* Given an X window ID and a DISPLAY, find the struct scroll_bar which
 4051    manages it.
 4052    This can be called in GC, so we have to make sure to strip off mark
 4053    bits.  */
 4054 
 4055 static struct scroll_bar *
 4056 x_window_to_scroll_bar (display, window_id)
 4057      Display *display;
 4058      Window window_id;
 4059 {
 4060   Lisp_Object tail;
 4061 
 4062 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
 4063   window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
 4064 #endif /* USE_GTK  && USE_TOOLKIT_SCROLL_BARS */
 4065 
 4066   for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
 4067     {
 4068       Lisp_Object frame, bar, condemned;
 4069 
 4070       frame = XCAR (tail);
 4071       /* All elements of Vframe_list should be frames.  */
 4072       if (! FRAMEP (frame))
 4073         abort ();
 4074 
 4075       if (! FRAME_X_P (XFRAME (frame)))
 4076         continue;
 4077 
 4078       /* Scan this frame's scroll bar list for a scroll bar with the
 4079          right window ID.  */
 4080       condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
 4081       for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
 4082            /* This trick allows us to search both the ordinary and
 4083               condemned scroll bar lists with one loop.  */
 4084            ! NILP (bar) || (bar = condemned,
 4085                                condemned = Qnil,
 4086                                ! NILP (bar));
 4087            bar = XSCROLL_BAR (bar)->next)
 4088         if (XSCROLL_BAR (bar)->x_window == window_id &&
 4089             FRAME_X_DISPLAY (XFRAME (frame)) == display)
 4090           return XSCROLL_BAR (bar);
 4091     }
 4092 
 4093   return 0;
 4094 }
 4095 
 4096 
 4097 #if defined USE_LUCID
 4098 
 4099 /* Return the Lucid menu bar WINDOW is part of.  Return null
 4100    if WINDOW is not part of a menu bar.  */
 4101 
 4102 static Widget
 4103 x_window_to_menu_bar (window)
 4104      Window window;
 4105 {
 4106   Lisp_Object tail;
 4107 
 4108   for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
 4109     {
 4110       if (FRAME_X_P (XFRAME (XCAR (tail))))
 4111         {
 4112           Lisp_Object frame = XCAR (tail);
 4113           Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
 4114 
 4115           if (menu_bar && xlwmenu_window_p (menu_bar, window))
 4116             return menu_bar;
 4117         }
 4118     }
 4119 
 4120   return NULL;
 4121 }
 4122 
 4123 #endif /* USE_LUCID */
 4124 
 4125 
 4126 /************************************************************************
 4127                          Toolkit scroll bars
 4128  ************************************************************************/
 4129 
 4130 #ifdef USE_TOOLKIT_SCROLL_BARS
 4131 
 4132 static void x_scroll_bar_to_input_event P_ ((XEvent *, struct input_event *));
 4133 static void x_send_scroll_bar_event P_ ((Lisp_Object, int, int, int));
 4134 static void x_create_toolkit_scroll_bar P_ ((struct frame *,
 4135                                              struct scroll_bar *));
 4136 static void x_set_toolkit_scroll_bar_thumb P_ ((struct scroll_bar *,
 4137                                                 int, int, int));
 4138 
 4139 
 4140 /* Lisp window being scrolled.  Set when starting to interact with
 4141    a toolkit scroll bar, reset to nil when ending the interaction.  */
 4142 
 4143 static Lisp_Object window_being_scrolled;
 4144 
 4145 /* Last scroll bar part sent in xm_scroll_callback.  */
 4146 
 4147 static int last_scroll_bar_part;
 4148 
 4149 /* Whether this is an Xaw with arrow-scrollbars.  This should imply
 4150    that movements of 1/20 of the screen size are mapped to up/down.  */
 4151 
 4152 #ifndef USE_GTK
 4153 /* Id of action hook installed for scroll bars.  */
 4154 
 4155 static XtActionHookId action_hook_id;
 4156 
 4157 static Boolean xaw3d_arrow_scroll;
 4158 
 4159 /* Whether the drag scrolling maintains the mouse at the top of the
 4160    thumb.  If not, resizing the thumb needs to be done more carefully
 4161    to avoid jerkyness.  */
 4162 
 4163 static Boolean xaw3d_pick_top;
 4164 
 4165 /* Action hook installed via XtAppAddActionHook when toolkit scroll
 4166    bars are used..  The hook is responsible for detecting when
 4167    the user ends an interaction with the scroll bar, and generates
 4168    a `end-scroll' SCROLL_BAR_CLICK_EVENT' event if so.  */
 4169 
 4170 static void
 4171 xt_action_hook (widget, client_data, action_name, event, params,
 4172                 num_params)
 4173      Widget widget;
 4174      XtPointer client_data;
 4175      String action_name;
 4176      XEvent *event;
 4177      String *params;
 4178      Cardinal *num_params;
 4179 {
 4180   int scroll_bar_p;
 4181   char *end_action;
 4182 
 4183 #ifdef USE_MOTIF
 4184   scroll_bar_p = XmIsScrollBar (widget);
 4185   end_action = "Release";
 4186 #else /* !USE_MOTIF i.e. use Xaw */
 4187   scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass);
 4188   end_action = "EndScroll";
 4189 #endif /* USE_MOTIF */
 4190 
 4191   if (scroll_bar_p
 4192       && strcmp (action_name, end_action) == 0
 4193       && WINDOWP (window_being_scrolled))
 4194     {
 4195       struct window *w;
 4196 
 4197       x_send_scroll_bar_event (window_being_scrolled,
 4198                                scroll_bar_end_scroll, 0, 0);
 4199       w = XWINDOW (window_being_scrolled);
 4200 
 4201       if (!NILP (XSCROLL_BAR (w->vertical_scroll_bar)->dragging))
 4202         {
 4203           XSCROLL_BAR (w->vertical_scroll_bar)->dragging = Qnil;
 4204           /* The thumb size is incorrect while dragging: fix it.  */
 4205           set_vertical_scroll_bar (w);
 4206         }
 4207       window_being_scrolled = Qnil;
 4208       last_scroll_bar_part = -1;
 4209 
 4210       /* Xt timeouts no longer needed.  */
 4211       toolkit_scroll_bar_interaction = 0;
 4212     }
 4213 }
 4214 #endif /* not USE_GTK */
 4215 
 4216 /* A vector of windows used for communication between
 4217    x_send_scroll_bar_event and x_scroll_bar_to_input_event.  */
 4218 
 4219 static struct window **scroll_bar_windows;
 4220 static int scroll_bar_windows_size;
 4221 
 4222 
 4223 /* Send a client message with message type Xatom_Scrollbar for a
 4224    scroll action to the frame of WINDOW.  PART is a value identifying
 4225    the part of the scroll bar that was clicked on.  PORTION is the
 4226    amount to scroll of a whole of WHOLE.  */
 4227 
 4228 static void
 4229 x_send_scroll_bar_event (window, part, portion, whole)
 4230      Lisp_Object window;
 4231      int part, portion, whole;
 4232 {
 4233   XEvent event;
 4234   XClientMessageEvent *ev = (XClientMessageEvent *) &event;
 4235   struct window *w = XWINDOW (window);
 4236   struct frame *f = XFRAME (w->frame);
 4237   int i;
 4238 
 4239   BLOCK_INPUT;
 4240 
 4241   /* Construct a ClientMessage event to send to the frame.  */
 4242   ev->type = ClientMessage;
 4243   ev->message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_Scrollbar;
 4244   ev->display = FRAME_X_DISPLAY (f);
 4245   ev->window = FRAME_X_WINDOW (f);
 4246   ev->format = 32;
 4247 
 4248   /* We can only transfer 32 bits in the XClientMessageEvent, which is
 4249      not enough to store a pointer or Lisp_Object on a 64 bit system.
 4250      So, store the window in scroll_bar_windows and pass the index
 4251      into that array in the event.  */
 4252   for (i = 0; i < scroll_bar_windows_size; ++i)
 4253     if (scroll_bar_windows[i] == NULL)
 4254       break;
 4255 
 4256   if (i == scroll_bar_windows_size)
 4257     {
 4258       int new_size = max (10, 2 * scroll_bar_windows_size);
 4259       size_t nbytes = new_size * sizeof *scroll_bar_windows;
 4260       size_t old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows;
 4261 
 4262       scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows,
 4263                                                         nbytes);
 4264       bzero (&scroll_bar_windows[i], nbytes - old_nbytes);
 4265       scroll_bar_windows_size = new_size;
 4266     }
 4267 
 4268   scroll_bar_windows[i] = w;
 4269   ev->data.l[0] = (long) i;
 4270   ev->data.l[1] = (long) part;
 4271   ev->data.l[2] = (long) 0;
 4272   ev->data.l[3] = (long) portion;
 4273   ev->data.l[4] = (long) whole;
 4274 
 4275   /* Make Xt timeouts work while the scroll bar is active.  */
 4276   toolkit_scroll_bar_interaction = 1;
 4277 #ifdef USE_X_TOOLKIT
 4278   x_activate_timeout_atimer ();
 4279 #endif
 4280 
 4281   /* Setting the event mask to zero means that the message will
 4282      be sent to the client that created the window, and if that
 4283      window no longer exists, no event will be sent.  */
 4284   XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), False, 0, &event);
 4285   UNBLOCK_INPUT;
 4286 }
 4287 
 4288 
 4289 /* Transform a scroll bar ClientMessage EVENT to an Emacs input event
 4290    in *IEVENT.  */
 4291 
 4292 static void
 4293 x_scroll_bar_to_input_event (event, ievent)
 4294      XEvent *event;
 4295      struct input_event *ievent;
 4296 {
 4297   XClientMessageEvent *ev = (XClientMessageEvent *) event;
 4298   Lisp_Object window;
 4299   struct frame *f;
 4300   struct window *w;
 4301 
 4302   w = scroll_bar_windows[ev->data.l[0]];
 4303   scroll_bar_windows[ev->data.l[0]] = NULL;
 4304 
 4305   XSETWINDOW (window, w);
 4306   f = XFRAME (w->frame);
 4307 
 4308   ievent->kind = SCROLL_BAR_CLICK_EVENT;
 4309   ievent->frame_or_window = window;
 4310   ievent->arg = Qnil;
 4311 #ifdef USE_GTK
 4312   ievent->timestamp = CurrentTime;
 4313 #else
 4314   ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f));
 4315 #endif
 4316   ievent->part = ev->data.l[1];
 4317   ievent->code = ev->data.l[2];
 4318   ievent->x = make_number ((int) ev->data.l[3]);
 4319   ievent->y = make_number ((int) ev->data.l[4]);
 4320   ievent->modifiers = 0;
 4321 }
 4322 
 4323 
 4324 #ifdef USE_MOTIF
 4325 
 4326 /* Minimum and maximum values used for Motif scroll bars.  */
 4327 
 4328 #define XM_SB_MAX 10000000
 4329 
 4330 
 4331 /* Scroll bar callback for Motif scroll bars.  WIDGET is the scroll
 4332    bar widget.  CLIENT_DATA is a pointer to the scroll_bar structure.
 4333    CALL_DATA is a pointer to a XmScrollBarCallbackStruct.  */
 4334 
 4335 static void
 4336 xm_scroll_callback (widget, client_data, call_data)
 4337      Widget widget;
 4338      XtPointer client_data, call_data;
 4339 {
 4340   struct scroll_bar *bar = (struct scroll_bar *) client_data;
 4341   XmScrollBarCallbackStruct *cs = (XmScrollBarCallbackStruct *) call_data;
 4342   int part = -1, whole = 0, portion = 0;
 4343 
 4344   switch (cs->reason)
 4345     {
 4346     case XmCR_DECREMENT:
 4347       bar->dragging = Qnil;
 4348       part = scroll_bar_up_arrow;
 4349       break;
 4350 
 4351     case XmCR_INCREMENT:
 4352       bar->dragging = Qnil;
 4353       part = scroll_bar_down_arrow;
 4354       break;
 4355 
 4356     case XmCR_PAGE_DECREMENT:
 4357       bar->dragging = Qnil;
 4358       part = scroll_bar_above_handle;
 4359       break;
 4360 
 4361     case XmCR_PAGE_INCREMENT:
 4362       bar->dragging = Qnil;
 4363       part = scroll_bar_below_handle;
 4364       break;
 4365 
 4366     case XmCR_TO_TOP:
 4367       bar->dragging = Qnil;
 4368       part = scroll_bar_to_top;
 4369       break;
 4370 
 4371     case XmCR_TO_BOTTOM:
 4372       bar->dragging = Qnil;
 4373       part = scroll_bar_to_bottom;
 4374       break;
 4375 
 4376     case XmCR_DRAG:
 4377       {
 4378         int slider_size;
 4379 
 4380         /* Get the slider size.  */
 4381         BLOCK_INPUT;
 4382         XtVaGetValues (widget, XmNsliderSize, &slider_size, NULL);
 4383         UNBLOCK_INPUT;
 4384 
 4385         whole = XM_SB_MAX - slider_size;
 4386         portion = min (cs->value, whole);
 4387         part = scroll_bar_handle;
 4388         bar->dragging = make_number (cs->value);
 4389       }
 4390       break;
 4391 
 4392     case XmCR_VALUE_CHANGED:
 4393       break;
 4394     };
 4395 
 4396   if (part >= 0)
 4397     {
 4398       window_being_scrolled = bar->window;
 4399       last_scroll_bar_part = part;
 4400       x_send_scroll_bar_event (bar->window, part, portion, whole);
 4401     }
 4402 }
 4403 
 4404 #elif defined USE_GTK
 4405 
 4406 /* Scroll bar callback for GTK scroll bars.  WIDGET is the scroll
 4407    bar widget.  DATA is a pointer to the scroll_bar structure. */
 4408 
 4409 static gboolean
 4410 xg_scroll_callback (GtkRange     *range,
 4411                     GtkScrollType scroll,
 4412                     gdouble       value,
 4413                     gpointer      user_data)
 4414 {
 4415   struct scroll_bar *bar = (struct scroll_bar *) user_data;
 4416   gdouble position;
 4417   int part = -1, whole = 0, portion = 0;
 4418   GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range));
 4419   FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (range), XG_FRAME_DATA);
 4420 
 4421   if (xg_ignore_gtk_scrollbar) return FALSE;
 4422   position = gtk_adjustment_get_value (adj);
 4423 
 4424 
 4425   switch (scroll)
 4426     {
 4427     case GTK_SCROLL_JUMP:
 4428       /* Buttons 1 2 or 3 must be grabbed.  */
 4429       if (FRAME_X_DISPLAY_INFO (f)->grabbed != 0
 4430           && FRAME_X_DISPLAY_INFO (f)->grabbed < (1 << 4))
 4431         {
 4432           part = scroll_bar_handle;
 4433           whole = adj->upper - adj->page_size;
 4434           portion = min ((int)position, whole);
 4435           bar->dragging = make_number ((int)portion);
 4436         }
 4437       break;
 4438     case GTK_SCROLL_STEP_BACKWARD:
 4439       part = scroll_bar_up_arrow;
 4440       bar->dragging = Qnil;
 4441       break;
 4442     case GTK_SCROLL_STEP_FORWARD:
 4443       part = scroll_bar_down_arrow;
 4444       bar->dragging = Qnil;
 4445       break;
 4446     case GTK_SCROLL_PAGE_BACKWARD:
 4447       part = scroll_bar_above_handle;
 4448       bar->dragging = Qnil;
 4449       break;
 4450     case GTK_SCROLL_PAGE_FORWARD:
 4451       part = scroll_bar_below_handle;
 4452       bar->dragging = Qnil;
 4453       break;
 4454     }
 4455 
 4456   if (part >= 0)
 4457     {
 4458       window_being_scrolled = bar->window;
 4459       last_scroll_bar_part = part;
 4460       x_send_scroll_bar_event (bar->window, part, portion, whole);
 4461     }
 4462 
 4463   return FALSE;
 4464 }
 4465 
 4466 /* Callback for button release. Sets dragging to Qnil when dragging is done.  */
 4467 
 4468 static gboolean
 4469 xg_end_scroll_callback (GtkWidget *widget,
 4470                         GdkEventButton *event,
 4471                         gpointer user_data)
 4472 {
 4473   struct scroll_bar *bar = (struct scroll_bar *) user_data;
 4474   bar->dragging = Qnil;
 4475   if (WINDOWP (window_being_scrolled))
 4476     {
 4477       x_send_scroll_bar_event (window_being_scrolled,
 4478                                scroll_bar_end_scroll, 0, 0);
 4479       window_being_scrolled = Qnil;
 4480     }
 4481 
 4482   return FALSE;
 4483 }
 4484 
 4485 
 4486 #else /* not USE_GTK and not USE_MOTIF */
 4487 
 4488 /* Xaw scroll bar callback.  Invoked when the thumb is dragged.
 4489    WIDGET is the scroll bar widget.  CLIENT_DATA is a pointer to the
 4490    scroll bar struct.  CALL_DATA is a pointer to a float saying where
 4491    the thumb is.  */
 4492 
 4493 static void
 4494 xaw_jump_callback (widget, client_data, call_data)
 4495      Widget widget;
 4496      XtPointer client_data, call_data;
 4497 {
 4498   struct scroll_bar *bar = (struct scroll_bar *) client_data;
 4499   float top = *(float *) call_data;
 4500   float shown;
 4501   int whole, portion, height;
 4502   int part;
 4503 
 4504   /* Get the size of the thumb, a value between 0 and 1.  */
 4505   BLOCK_INPUT;
 4506   XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL);
 4507   UNBLOCK_INPUT;
 4508 
 4509   whole = 10000000;
 4510   portion = shown < 1 ? top * whole : 0;
 4511 
 4512   if (shown < 1 && (eabs (top + shown - 1) < 1.0/height))
 4513     /* Some derivatives of Xaw refuse to shrink the thumb when you reach
 4514        the bottom, so we force the scrolling whenever we see that we're
 4515        too close to the bottom (in x_set_toolkit_scroll_bar_thumb
 4516        we try to ensure that we always stay two pixels away from the
 4517        bottom).  */
 4518     part = scroll_bar_down_arrow;
 4519   else
 4520     part = scroll_bar_handle;
 4521 
 4522   window_being_scrolled = bar->window;
 4523   bar->dragging = make_number (portion);
 4524   last_scroll_bar_part = part;
 4525   x_send_scroll_bar_event (bar->window, part, portion, whole);
 4526 }
 4527 
 4528 
 4529 /* Xaw scroll bar callback.  Invoked for incremental scrolling.,
 4530    i.e. line or page up or down.  WIDGET is the Xaw scroll bar
 4531    widget.  CLIENT_DATA is a pointer to the scroll_bar structure for
 4532    the scroll bar.  CALL_DATA is an integer specifying the action that
 4533    has taken place.  Its magnitude is in the range 0..height of the
 4534    scroll bar.  Negative values mean scroll towards buffer start.
 4535    Values < height of scroll bar mean line-wise movement.  */
 4536 
 4537 static void
 4538 xaw_scroll_callback (widget, client_data, call_data)
 4539      Widget widget;
 4540      XtPointer client_data, call_data;
 4541 {
 4542   struct scroll_bar *bar = (struct scroll_bar *) client_data;
 4543   /* The position really is stored cast to a pointer.  */
 4544   int position = (long) call_data;
 4545   Dimension height;
 4546   int part;
 4547 
 4548   /* Get the height of the scroll bar.  */
 4549   BLOCK_INPUT;
 4550   XtVaGetValues (widget, XtNheight, &height, NULL);
 4551   UNBLOCK_INPUT;
 4552 
 4553   if (eabs (position) >= height)
 4554     part = (position < 0) ? scroll_bar_above_handle : scroll_bar_below_handle;
 4555 
 4556   /* If Xaw3d was compiled with ARROW_SCROLLBAR,
 4557      it maps line-movement to call_data = max(5, height/20).  */
 4558   else if (xaw3d_arrow_scroll && eabs (position) <= max (5, height / 20))
 4559     part = (position < 0) ? scroll_bar_up_arrow : scroll_bar_down_arrow;
 4560   else
 4561     part = scroll_bar_move_ratio;
 4562 
 4563   window_being_scrolled = bar->window;
 4564   bar->dragging = Qnil;
 4565   last_scroll_bar_part = part;
 4566   x_send_scroll_bar_event (bar->window, part, position, height);
 4567 }
 4568 
 4569 #endif /* not USE_GTK and not USE_MOTIF */
 4570 
 4571 #define SCROLL_BAR_NAME "verticalScrollBar"
 4572 
 4573 /* Create the widget for scroll bar BAR on frame F.  Record the widget
 4574    and X window of the scroll bar in BAR.  */
 4575 
 4576 #ifdef USE_GTK
 4577 static void
 4578 x_create_toolkit_scroll_bar (f, bar)
 4579      struct frame *f;
 4580      struct scroll_bar *bar;
 4581 {
 4582   char *scroll_bar_name = SCROLL_BAR_NAME;
 4583 
 4584   BLOCK_INPUT;
 4585   xg_create_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
 4586                         G_CALLBACK (xg_end_scroll_callback),
 4587                         scroll_bar_name);
 4588   UNBLOCK_INPUT;
 4589 }
 4590 
 4591 #else /* not USE_GTK */
 4592 
 4593 static void
 4594 x_create_toolkit_scroll_bar (f, bar)
 4595      struct frame *f;
 4596      struct scroll_bar *bar;
 4597 {
 4598   Window xwindow;
 4599   Widget widget;
 4600   Arg av[20];
 4601   int ac = 0;
 4602   char *scroll_bar_name = SCROLL_BAR_NAME;
 4603   unsigned long pixel;
 4604 
 4605   BLOCK_INPUT;
 4606 
 4607 #ifdef USE_MOTIF
 4608   /* Set resources.  Create the widget.  */
 4609   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 4610   XtSetArg (av[ac], XmNminimum, 0); ++ac;
 4611   XtSetArg (av[ac], XmNmaximum, XM_SB_MAX); ++ac;
 4612   XtSetArg (av[ac], XmNorientation, XmVERTICAL); ++ac;
 4613   XtSetArg (av[ac], XmNprocessingDirection, XmMAX_ON_BOTTOM), ++ac;
 4614   XtSetArg (av[ac], XmNincrement, 1); ++ac;
 4615   XtSetArg (av[ac], XmNpageIncrement, 1); ++ac;
 4616 
 4617   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 4618   if (pixel != -1)
 4619     {
 4620       XtSetArg (av[ac], XmNforeground, pixel);
 4621       ++ac;
 4622     }
 4623 
 4624   pixel = f->output_data.x->scroll_bar_background_pixel;
 4625   if (pixel != -1)
 4626     {
 4627       XtSetArg (av[ac], XmNbackground, pixel);
 4628       ++ac;
 4629     }
 4630 
 4631   widget = XmCreateScrollBar (f->output_data.x->edit_widget,
 4632                               scroll_bar_name, av, ac);
 4633 
 4634   /* Add one callback for everything that can happen.  */
 4635   XtAddCallback (widget, XmNdecrementCallback, xm_scroll_callback,
 4636                  (XtPointer) bar);
 4637   XtAddCallback (widget, XmNdragCallback, xm_scroll_callback,
 4638                  (XtPointer) bar);
 4639   XtAddCallback (widget, XmNincrementCallback, xm_scroll_callback,
 4640                  (XtPointer) bar);
 4641   XtAddCallback (widget, XmNpageDecrementCallback, xm_scroll_callback,
 4642                  (XtPointer) bar);
 4643   XtAddCallback (widget, XmNpageIncrementCallback, xm_scroll_callback,
 4644                  (XtPointer) bar);
 4645   XtAddCallback (widget, XmNtoBottomCallback, xm_scroll_callback,
 4646                  (XtPointer) bar);
 4647   XtAddCallback (widget, XmNtoTopCallback, xm_scroll_callback,
 4648                  (XtPointer) bar);
 4649 
 4650   /* Realize the widget.  Only after that is the X window created.  */
 4651   XtRealizeWidget (widget);
 4652 
 4653   /* Set the cursor to an arrow.  I didn't find a resource to do that.
 4654      And I'm wondering why it hasn't an arrow cursor by default.  */
 4655   XDefineCursor (XtDisplay (widget), XtWindow (widget),
 4656                  f->output_data.x->nontext_cursor);
 4657 
 4658 #else /* !USE_MOTIF i.e. use Xaw */
 4659 
 4660   /* Set resources.  Create the widget.  The background of the
 4661      Xaw3d scroll bar widget is a little bit light for my taste.
 4662      We don't alter it here to let users change it according
 4663      to their taste with `emacs*verticalScrollBar.background: xxx'.  */
 4664   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 4665   XtSetArg (av[ac], XtNorientation, XtorientVertical); ++ac;
 4666   /* For smoother scrolling with Xaw3d   -sm */
 4667   /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
 4668 
 4669   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 4670   if (pixel != -1)
 4671     {
 4672       XtSetArg (av[ac], XtNforeground, pixel);
 4673       ++ac;
 4674     }
 4675 
 4676   pixel = f->output_data.x->scroll_bar_background_pixel;
 4677   if (pixel != -1)
 4678     {
 4679       XtSetArg (av[ac], XtNbackground, pixel);
 4680       ++ac;
 4681     }
 4682 
 4683   /* Top/bottom shadow colors.  */
 4684 
 4685   /* Allocate them, if necessary.  */
 4686   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1)
 4687     {
 4688       pixel = f->output_data.x->scroll_bar_background_pixel;
 4689       if (pixel != -1) 
 4690         {
 4691           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 4692                                       FRAME_X_COLORMAP (f),
 4693                                       &pixel, 1.2, 0x8000))
 4694             pixel = -1;
 4695           f->output_data.x->scroll_bar_top_shadow_pixel = pixel;
 4696         }
 4697     }
 4698   if (f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 4699     {
 4700       pixel = f->output_data.x->scroll_bar_background_pixel;
 4701       if (pixel != -1) 
 4702         {
 4703           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 4704                                       FRAME_X_COLORMAP (f),
 4705                                       &pixel, 0.6, 0x4000))
 4706             pixel = -1;
 4707           f->output_data.x->scroll_bar_bottom_shadow_pixel = pixel;
 4708         }
 4709     }
 4710 
 4711 #ifdef XtNbeNiceToColormap
 4712   /* Tell the toolkit about them.  */
 4713   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1
 4714       || f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 4715     /* We tried to allocate a color for the top/bottom shadow, and
 4716        failed, so tell Xaw3d to use dithering instead.   */
 4717     {
 4718       XtSetArg (av[ac], XtNbeNiceToColormap, True);
 4719       ++ac;
 4720     }
 4721   else
 4722     /* Tell what colors Xaw3d should use for the top/bottom shadow, to
 4723        be more consistent with other emacs 3d colors, and since Xaw3d is
 4724        not good at dealing with allocation failure.  */
 4725     {
 4726       /* This tells Xaw3d to use real colors instead of dithering for
 4727          the shadows.  */
 4728       XtSetArg (av[ac], XtNbeNiceToColormap, False);
 4729       ++ac;
 4730 
 4731       /* Specify the colors.  */
 4732       pixel = f->output_data.x->scroll_bar_top_shadow_pixel;
 4733       if (pixel != -1)
 4734         {
 4735           XtSetArg (av[ac], XtNtopShadowPixel, pixel);
 4736           ++ac;
 4737         }
 4738       pixel = f->output_data.x->scroll_bar_bottom_shadow_pixel;
 4739       if (pixel != -1)
 4740         {
 4741           XtSetArg (av[ac], XtNbottomShadowPixel, pixel);
 4742           ++ac;
 4743         }
 4744     }
 4745 #endif
 4746 
 4747   widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
 4748                            f->output_data.x->edit_widget, av, ac);
 4749 
 4750   {
 4751     char *initial = "";
 4752     char *val = initial;
 4753     XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val,
 4754 #ifdef XtNarrowScrollbars
 4755                    XtNarrowScrollbars, (XtPointer) &xaw3d_arrow_scroll,
 4756 #endif
 4757                    XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL);
 4758     if (xaw3d_arrow_scroll || val == initial)
 4759       { /* ARROW_SCROLL */
 4760         xaw3d_arrow_scroll = True;
 4761         /* Isn't that just a personal preference ?   --Stef */
 4762         XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL);
 4763       }
 4764   }
 4765 
 4766   /* Define callbacks.  */
 4767   XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar);
 4768   XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback,
 4769                  (XtPointer) bar);
 4770 
 4771   /* Realize the widget.  Only after that is the X window created.  */
 4772   XtRealizeWidget (widget);
 4773 
 4774 #endif /* !USE_MOTIF */
 4775 
 4776   /* Install an action hook that lets us detect when the user
 4777      finishes interacting with a scroll bar.  */
 4778   if (action_hook_id == 0)
 4779     action_hook_id = XtAppAddActionHook (Xt_app_con, xt_action_hook, 0);
 4780 
 4781   /* Remember X window and widget in the scroll bar vector.  */
 4782   SET_SCROLL_BAR_X_WIDGET (bar, widget);
 4783   xwindow = XtWindow (widget);
 4784   bar->x_window = xwindow;
 4785 
 4786   UNBLOCK_INPUT;
 4787 }
 4788 #endif /* not USE_GTK */
 4789 
 4790 
 4791 /* Set the thumb size and position of scroll bar BAR.  We are currently
 4792    displaying PORTION out of a whole WHOLE, and our position POSITION.  */
 4793 
 4794 #ifdef USE_GTK
 4795 static void
 4796 x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
 4797      struct scroll_bar *bar;
 4798      int portion, position, whole;
 4799 {
 4800   xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 4801 }
 4802 
 4803 #else /* not USE_GTK */
 4804 static void
 4805 x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
 4806      struct scroll_bar *bar;
 4807      int portion, position, whole;
 4808 {
 4809   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 4810   Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
 4811   float top, shown;
 4812 
 4813   BLOCK_INPUT;
 4814 
 4815 #ifdef USE_MOTIF
 4816 
 4817   /* We use an estimate of 30 chars per line rather than the real
 4818      `portion' value.  This has the disadvantage that the thumb size
 4819      is not very representative, but it makes our life a lot easier.
 4820      Otherwise, we have to constantly adjust the thumb size, which
 4821      we can't always do quickly enough: while dragging, the size of
 4822      the thumb might prevent the user from dragging the thumb all the
 4823      way to the end.  but Motif and some versions of Xaw3d don't allow
 4824      updating the thumb size while dragging.  Also, even if we can update
 4825      its size, the update will often happen too late.
 4826      If you don't believe it, check out revision 1.650 of xterm.c to see
 4827      what hoops we were going through and the still poor behavior we got.  */
 4828   portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30;
 4829   /* When the thumb is at the bottom, position == whole.
 4830      So we need to increase `whole' to make space for the thumb.  */
 4831   whole += portion;
 4832 
 4833   if (whole <= 0)
 4834     top = 0, shown = 1;
 4835   else
 4836     {
 4837       top = (float) position / whole;
 4838       shown = (float) portion / whole;
 4839     }
 4840 
 4841   if (NILP (bar->dragging))
 4842     {
 4843       int size, value;
 4844 
 4845       /* Slider size.  Must be in the range [1 .. MAX - MIN] where MAX
 4846          is the scroll bar's maximum and MIN is the scroll bar's minimum
 4847          value.  */
 4848       size = shown * XM_SB_MAX;
 4849       size = min (size, XM_SB_MAX);
 4850       size = max (size, 1);
 4851 
 4852       /* Position.  Must be in the range [MIN .. MAX - SLIDER_SIZE].  */
 4853       value = top * XM_SB_MAX;
 4854       value = min (value, XM_SB_MAX - size);
 4855 
 4856       XmScrollBarSetValues (widget, value, size, 0, 0, False);
 4857     }
 4858 #else /* !USE_MOTIF i.e. use Xaw */
 4859 
 4860   if (whole == 0)
 4861     top = 0, shown = 1;
 4862   else
 4863     {
 4864       top = (float) position / whole;
 4865       shown = (float) portion / whole;
 4866     }
 4867 
 4868   {
 4869     float old_top, old_shown;
 4870     Dimension height;
 4871     XtVaGetValues (widget,
 4872                    XtNtopOfThumb, &old_top,
 4873                    XtNshown, &old_shown,
 4874                    XtNheight, &height,
 4875                    NULL);
 4876 
 4877     /* Massage the top+shown values.  */
 4878     if (NILP (bar->dragging) || last_scroll_bar_part == scroll_bar_down_arrow)
 4879       top = max (0, min (1, top));
 4880     else
 4881       top = old_top;
 4882     /* Keep two pixels available for moving the thumb down.  */
 4883     shown = max (0, min (1 - top - (2.0 / height), shown));
 4884 
 4885     /* If the call to XawScrollbarSetThumb below doesn't seem to work,
 4886        check that your system's configuration file contains a define
 4887        for `NARROWPROTO'.  See s/freebsd.h for an example.  */
 4888     if (top != old_top || shown != old_shown)
 4889       {
 4890         if (NILP (bar->dragging))
 4891           XawScrollbarSetThumb (widget, top, shown);
 4892         else
 4893           {
 4894             /* Try to make the scrolling a tad smoother.  */
 4895             if (!xaw3d_pick_top)
 4896               shown = min (shown, old_shown);
 4897 
 4898             XawScrollbarSetThumb (widget, top, shown);
 4899           }
 4900       }
 4901   }
 4902 #endif /* !USE_MOTIF */
 4903 
 4904   UNBLOCK_INPUT;
 4905 }
 4906 #endif /* not USE_GTK */
 4907 
 4908 #endif /* USE_TOOLKIT_SCROLL_BARS */
 4909 
 4910 
 4911 
 4912 /************************************************************************
 4913                          Scroll bars, general
 4914  ************************************************************************/
 4915 
 4916 /* Create a scroll bar and return the scroll bar vector for it.  W is
 4917    the Emacs window on which to create the scroll bar. TOP, LEFT,
 4918    WIDTH and HEIGHT are the pixel coordinates and dimensions of the
 4919    scroll bar. */
 4920 
 4921 static struct scroll_bar *
 4922 x_scroll_bar_create (w, top, left, width, height)
 4923      struct window *w;
 4924      int top, left, width, height;
 4925 {
 4926   struct frame *f = XFRAME (w->frame);
 4927   struct scroll_bar *bar
 4928     = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, x_window, PVEC_OTHER);
 4929 
 4930   BLOCK_INPUT;
 4931 
 4932 #ifdef USE_TOOLKIT_SCROLL_BARS
 4933   x_create_toolkit_scroll_bar (f, bar);
 4934 #else /* not USE_TOOLKIT_SCROLL_BARS */
 4935   {
 4936     XSetWindowAttributes a;
 4937     unsigned long mask;
 4938     Window window;
 4939 
 4940     a.background_pixel = f->output_data.x->scroll_bar_background_pixel;
 4941     if (a.background_pixel == -1)
 4942       a.background_pixel = FRAME_BACKGROUND_PIXEL (f);
 4943 
 4944     a.event_mask = (ButtonPressMask | ButtonReleaseMask
 4945                     | ButtonMotionMask | PointerMotionHintMask
 4946                     | ExposureMask);
 4947     a.cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
 4948 
 4949     mask = (CWBackPixel | CWEventMask | CWCursor);
 4950 
 4951     /* Clear the area of W that will serve as a scroll bar.  This is
 4952        for the case that a window has been split horizontally.  In
 4953        this case, no clear_frame is generated to reduce flickering.  */
 4954     if (width > 0 && height > 0)
 4955       x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 4956                     left, top, width,
 4957                     window_box_height (w), False);
 4958 
 4959     window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 4960                             /* Position and size of scroll bar.  */
 4961                             left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
 4962                             top,
 4963                             width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
 4964                             height,
 4965                             /* Border width, depth, class, and visual.  */
 4966                              0,
 4967                             CopyFromParent,
 4968                             CopyFromParent,
 4969                             CopyFromParent,
 4970                              /* Attributes.  */
 4971                             mask, &a);
 4972     bar->x_window = window;
 4973   }
 4974 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 4975 
 4976   XSETWINDOW (bar->window, w);
 4977   bar->top = top;
 4978   bar->left = left;
 4979   bar->width = width;
 4980   bar->height = height;
 4981   bar->start = 0;
 4982   bar->end = 0;
 4983   bar->dragging = Qnil;
 4984   bar->fringe_extended_p = 0;
 4985 
 4986   /* Add bar to its frame's list of scroll bars.  */
 4987   bar->next = FRAME_SCROLL_BARS (f);
 4988   bar->prev = Qnil;
 4989   XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
 4990   if (!NILP (bar->next))
 4991     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 4992 
 4993   /* Map the window/widget.  */
 4994 #ifdef USE_TOOLKIT_SCROLL_BARS
 4995   {
 4996 #ifdef USE_GTK
 4997     xg_update_scrollbar_pos (f,
 4998                              bar->x_window,
 4999                              top,
 5000                              left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
 5001                              width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
 5002                              max (height, 1));
 5003     xg_show_scroll_bar (bar->x_window);
 5004 #else /* not USE_GTK */
 5005     Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
 5006     XtConfigureWidget (scroll_bar,
 5007                        left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
 5008                        top,
 5009                        width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
 5010                        max (height, 1), 0);
 5011     XtMapWidget (scroll_bar);
 5012 #endif /* not USE_GTK */
 5013     }
 5014 #else /* not USE_TOOLKIT_SCROLL_BARS */
 5015   XMapRaised (FRAME_X_DISPLAY (f), bar->x_window);
 5016 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 5017 
 5018   UNBLOCK_INPUT;
 5019   return bar;
 5020 }
 5021 
 5022 
 5023 #ifndef USE_TOOLKIT_SCROLL_BARS
 5024 
 5025 /* Draw BAR's handle in the proper position.
 5026 
 5027    If the handle is already drawn from START to END, don't bother
 5028    redrawing it, unless REBUILD is non-zero; in that case, always
 5029    redraw it.  (REBUILD is handy for drawing the handle after expose
 5030    events.)
 5031 
 5032    Normally, we want to constrain the start and end of the handle to
 5033    fit inside its rectangle, but if the user is dragging the scroll
 5034    bar handle, we want to let them drag it down all the way, so that
 5035    the bar's top is as far down as it goes; otherwise, there's no way
 5036    to move to the very end of the buffer.  */
 5037 
 5038 static void
 5039 x_scroll_bar_set_handle (bar, start, end, rebuild)
 5040      struct scroll_bar *bar;
 5041      int start, end;
 5042      int rebuild;
 5043 {
 5044   int dragging = ! NILP (bar->dragging);
 5045   Window w = bar->x_window;
 5046   FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 5047   GC gc = f->output_data.x->normal_gc;
 5048 
 5049   /* If the display is already accurate, do nothing.  */
 5050   if (! rebuild
 5051       && start == bar->start
 5052       && end == bar->end)
 5053     return;
 5054 
 5055   BLOCK_INPUT;
 5056 
 5057   {
 5058     int inside_width = VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f, bar->width);
 5059     int inside_height = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, bar->height);
 5060     int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
 5061 
 5062     /* Make sure the values are reasonable, and try to preserve
 5063        the distance between start and end.  */
 5064     {
 5065       int length = end - start;
 5066 
 5067       if (start < 0)
 5068         start = 0;
 5069       else if (start > top_range)
 5070         start = top_range;
 5071       end = start + length;
 5072 
 5073       if (end < start)
 5074         end = start;
 5075       else if (end > top_range && ! dragging)
 5076         end = top_range;
 5077     }
 5078 
 5079     /* Store the adjusted setting in the scroll bar.  */
 5080     bar->start = start;
 5081     bar->end = end;
 5082 
 5083     /* Clip the end position, just for display.  */
 5084     if (end > top_range)
 5085       end = top_range;
 5086 
 5087     /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels
 5088        below top positions, to make sure the handle is always at least
 5089        that many pixels tall.  */
 5090     end += VERTICAL_SCROLL_BAR_MIN_HANDLE;
 5091 
 5092     /* Draw the empty space above the handle.  Note that we can't clear
 5093        zero-height areas; that means "clear to end of window."  */
 5094     if (0 < start)
 5095       x_clear_area (FRAME_X_DISPLAY (f), w,
 5096                     /* x, y, width, height, and exposures.  */
 5097                     VERTICAL_SCROLL_BAR_LEFT_BORDER,
 5098                     VERTICAL_SCROLL_BAR_TOP_BORDER,
 5099                     inside_width, start,
 5100                     False);
 5101 
 5102     /* Change to proper foreground color if one is specified.  */
 5103     if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 5104       XSetForeground (FRAME_X_DISPLAY (f), gc,
 5105                       f->output_data.x->scroll_bar_foreground_pixel);
 5106 
 5107     /* Draw the handle itself.  */
 5108     XFillRectangle (FRAME_X_DISPLAY (f), w, gc,
 5109                     /* x, y, width, height */
 5110                     VERTICAL_SCROLL_BAR_LEFT_BORDER,
 5111                     VERTICAL_SCROLL_BAR_TOP_BORDER + start,
 5112                     inside_width, end - start);
 5113 
 5114     /* Restore the foreground color of the GC if we changed it above.  */
 5115     if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 5116       XSetForeground (FRAME_X_DISPLAY (f), gc,
 5117                       FRAME_FOREGROUND_PIXEL (f));
 5118 
 5119     /* Draw the empty space below the handle.  Note that we can't
 5120        clear zero-height areas; that means "clear to end of window." */
 5121     if (end < inside_height)
 5122       x_clear_area (FRAME_X_DISPLAY (f), w,
 5123                     /* x, y, width, height, and exposures.  */
 5124                     VERTICAL_SCROLL_BAR_LEFT_BORDER,
 5125                     VERTICAL_SCROLL_BAR_TOP_BORDER + end,
 5126                     inside_width, inside_height - end,
 5127                     False);
 5128 
 5129   }
 5130 
 5131   UNBLOCK_INPUT;
 5132 }
 5133 
 5134 #endif /* !USE_TOOLKIT_SCROLL_BARS */
 5135 
 5136 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
 5137    nil.  */
 5138 
 5139 static void
 5140 x_scroll_bar_remove (bar)
 5141      struct scroll_bar *bar;
 5142 {
 5143   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 5144   BLOCK_INPUT;
 5145 
 5146 #ifdef USE_TOOLKIT_SCROLL_BARS
 5147 #ifdef USE_GTK
 5148   xg_remove_scroll_bar (f, bar->x_window);
 5149 #else /* not USE_GTK */
 5150   XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
 5151 #endif /* not USE_GTK */
 5152 #else
 5153   XDestroyWindow (FRAME_X_DISPLAY (f), bar->x_window);
 5154 #endif
 5155 
 5156   /* Disassociate this scroll bar from its window.  */
 5157   XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
 5158 
 5159   UNBLOCK_INPUT;
 5160 }
 5161 
 5162 
 5163 /* Set the handle of the vertical scroll bar for WINDOW to indicate
 5164    that we are displaying PORTION characters out of a total of WHOLE
 5165    characters, starting at POSITION.  If WINDOW has no scroll bar,
 5166    create one.  */
 5167 
 5168 static void
 5169 XTset_vertical_scroll_bar (w, portion, whole, position)
 5170      struct window *w;
 5171      int portion, whole, position;
 5172 {
 5173   struct frame *f = XFRAME (w->frame);
 5174   struct scroll_bar *bar;
 5175   int top, height, left, sb_left, width, sb_width;
 5176   int window_y, window_height;
 5177 #ifdef USE_TOOLKIT_SCROLL_BARS
 5178   int fringe_extended_p;
 5179 #endif
 5180 
 5181   /* Get window dimensions.  */
 5182   window_box (w, -1, 0, &window_y, 0, &window_height);
 5183   top = window_y;
 5184   width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
 5185   height = window_height;
 5186 
 5187   /* Compute the left edge of the scroll bar area.  */
 5188   left = WINDOW_SCROLL_BAR_AREA_X (w);
 5189 
 5190   /* Compute the width of the scroll bar which might be less than
 5191      the width of the area reserved for the scroll bar.  */
 5192   if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) > 0)
 5193     sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
 5194   else
 5195     sb_width = width;
 5196 
 5197   /* Compute the left edge of the scroll bar.  */
 5198 #ifdef USE_TOOLKIT_SCROLL_BARS
 5199   if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
 5200     sb_left = left + (WINDOW_RIGHTMOST_P (w) ? width - sb_width : 0);
 5201   else
 5202     sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
 5203 #else
 5204   if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
 5205     sb_left = left + width - sb_width;
 5206   else
 5207     sb_left = left;
 5208 #endif
 5209 
 5210 #ifdef USE_TOOLKIT_SCROLL_BARS
 5211   if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
 5212     fringe_extended_p = (WINDOW_LEFTMOST_P (w)
 5213                          && WINDOW_LEFT_FRINGE_WIDTH (w)
 5214                          && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
 5215                              || WINDOW_LEFT_MARGIN_COLS (w) == 0));
 5216   else
 5217     fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
 5218                          && WINDOW_RIGHT_FRINGE_WIDTH (w)
 5219                          && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
 5220                              || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
 5221 #endif
 5222 
 5223   /* Does the scroll bar exist yet?  */
 5224   if (NILP (w->vertical_scroll_bar))
 5225     {
 5226       if (width > 0 && height > 0)
 5227         {
 5228           BLOCK_INPUT;
 5229 #ifdef USE_TOOLKIT_SCROLL_BARS
 5230           if (fringe_extended_p)
 5231             x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 5232                           sb_left, top, sb_width, height, False);
 5233           else
 5234 #endif
 5235             x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 5236                           left, top, width, height, False);
 5237           UNBLOCK_INPUT;
 5238         }
 5239 
 5240       bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
 5241     }
 5242   else
 5243     {
 5244       /* It may just need to be moved and resized.  */
 5245       unsigned int mask = 0;
 5246 
 5247       bar = XSCROLL_BAR (w->vertical_scroll_bar);
 5248 
 5249       BLOCK_INPUT;
 5250 
 5251       if (sb_left != bar->left)
 5252         mask |= CWX;
 5253       if (top != bar->top)
 5254         mask |= CWY;
 5255       if (sb_width != bar->width)
 5256         mask |= CWWidth;
 5257       if (height != bar->height)
 5258         mask |= CWHeight;
 5259 
 5260 #ifdef USE_TOOLKIT_SCROLL_BARS
 5261 
 5262       /* Move/size the scroll bar widget.  */
 5263       if (mask || bar->fringe_extended_p != fringe_extended_p)
 5264         {
 5265           /* Since toolkit scroll bars are smaller than the space reserved
 5266              for them on the frame, we have to clear "under" them.  */
 5267           if (width > 0 && height > 0)
 5268             {
 5269               if (fringe_extended_p)
 5270                 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 5271                               sb_left, top, sb_width, height, False);
 5272               else
 5273                 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 5274                               left, top, width, height, False);
 5275             }
 5276 #ifdef USE_GTK
 5277           xg_update_scrollbar_pos (f,
 5278                                    bar->x_window,
 5279                                    top,
 5280                                    sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
 5281                                    sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM *2,
 5282                                    max (height, 1));
 5283 #else /* not USE_GTK */
 5284           XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
 5285                              sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
 5286                              top,
 5287                              sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
 5288                              max (height, 1), 0);
 5289 #endif /* not USE_GTK */
 5290         }
 5291 #else /* not USE_TOOLKIT_SCROLL_BARS */
 5292 
 5293       /* Clear areas not covered by the scroll bar because of
 5294          VERTICAL_SCROLL_BAR_WIDTH_TRIM.  */
 5295       if (VERTICAL_SCROLL_BAR_WIDTH_TRIM)
 5296         {
 5297           x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 5298                         left, top, VERTICAL_SCROLL_BAR_WIDTH_TRIM,
 5299                         height, False);
 5300           x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 5301                         left + width - VERTICAL_SCROLL_BAR_WIDTH_TRIM,
 5302                         top, VERTICAL_SCROLL_BAR_WIDTH_TRIM,
 5303                         height, False);
 5304         }
 5305 
 5306       /* Clear areas not covered by the scroll bar because it's not as
 5307          wide as the area reserved for it.  This makes sure a
 5308          previous mode line display is cleared after C-x 2 C-x 1, for
 5309          example.  */
 5310       {
 5311         int area_width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
 5312         int rest = area_width - sb_width;
 5313         if (rest > 0 && height > 0)
 5314           {
 5315             if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
 5316               x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 5317                             left + area_width -  rest, top,
 5318                             rest, height, False);
 5319             else
 5320               x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 5321                             left, top, rest, height, False);
 5322           }
 5323       }
 5324 
 5325       /* Move/size the scroll bar window.  */
 5326       if (mask)
 5327         {
 5328           XWindowChanges wc;
 5329 
 5330           wc.x = sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM;
 5331           wc.y = top;
 5332           wc.width = sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2;
 5333           wc.height = height;
 5334           XConfigureWindow (FRAME_X_DISPLAY (f), bar->x_window,
 5335                             mask, &wc);
 5336         }
 5337 
 5338 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 5339 
 5340       /* Remember new settings.  */
 5341       bar->left = sb_left;
 5342       bar->top = top;
 5343       bar->width = sb_width;
 5344       bar->height = height;
 5345 
 5346       UNBLOCK_INPUT;
 5347     }
 5348 
 5349 #ifdef USE_TOOLKIT_SCROLL_BARS
 5350   bar->fringe_extended_p = fringe_extended_p;
 5351 
 5352   x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 5353 #else /* not USE_TOOLKIT_SCROLL_BARS */
 5354   /* Set the scroll bar's current state, unless we're currently being
 5355      dragged.  */
 5356   if (NILP (bar->dragging))
 5357     {
 5358       int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height);
 5359 
 5360       if (whole == 0)
 5361         x_scroll_bar_set_handle (bar, 0, top_range, 0);
 5362       else
 5363         {
 5364           int start = ((double) position * top_range) / whole;
 5365           int end = ((double) (position + portion) * top_range) / whole;
 5366           x_scroll_bar_set_handle (bar, start, end, 0);
 5367         }
 5368     }
 5369 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 5370 
 5371   XSETVECTOR (w->vertical_scroll_bar, bar);
 5372 }
 5373 
 5374 
 5375 /* The following three hooks are used when we're doing a thorough
 5376    redisplay of the frame.  We don't explicitly know which scroll bars
 5377    are going to be deleted, because keeping track of when windows go
 5378    away is a real pain - "Can you say set-window-configuration, boys
 5379    and girls?"  Instead, we just assert at the beginning of redisplay
 5380    that *all* scroll bars are to be removed, and then save a scroll bar
 5381    from the fiery pit when we actually redisplay its window.  */
 5382 
 5383 /* Arrange for all scroll bars on FRAME to be removed at the next call
 5384    to `*judge_scroll_bars_hook'.  A scroll bar may be spared if
 5385    `*redeem_scroll_bar_hook' is applied to its window before the judgment.  */
 5386 
 5387 static void
 5388 XTcondemn_scroll_bars (frame)
 5389      FRAME_PTR frame;
 5390 {
 5391   /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS.  */
 5392   while (! NILP (FRAME_SCROLL_BARS (frame)))
 5393     {
 5394       Lisp_Object bar;
 5395       bar = FRAME_SCROLL_BARS (frame);
 5396       FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
 5397       XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
 5398       XSCROLL_BAR (bar)->prev = Qnil;
 5399       if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
 5400         XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
 5401       FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
 5402     }
 5403 }
 5404 
 5405 
 5406 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
 5407    Note that WINDOW isn't necessarily condemned at all.  */
 5408 
 5409 static void
 5410 XTredeem_scroll_bar (window)
 5411      struct window *window;
 5412 {
 5413   struct scroll_bar *bar;
 5414   struct frame *f;
 5415 
 5416   /* We can't redeem this window's scroll bar if it doesn't have one.  */
 5417   if (NILP (window->vertical_scroll_bar))
 5418     abort ();
 5419 
 5420   bar = XSCROLL_BAR (window->vertical_scroll_bar);
 5421 
 5422   /* Unlink it from the condemned list.  */
 5423   f = XFRAME (WINDOW_FRAME (window));
 5424   if (NILP (bar->prev))
 5425     {
 5426       /* If the prev pointer is nil, it must be the first in one of
 5427          the lists.  */
 5428       if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
 5429         /* It's not condemned.  Everything's fine.  */
 5430         return;
 5431       else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
 5432                    window->vertical_scroll_bar))
 5433         FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
 5434       else
 5435         /* If its prev pointer is nil, it must be at the front of
 5436            one or the other!  */
 5437         abort ();
 5438     }
 5439   else
 5440     XSCROLL_BAR (bar->prev)->next = bar->next;
 5441 
 5442   if (! NILP (bar->next))
 5443     XSCROLL_BAR (bar->next)->prev = bar->prev;
 5444 
 5445   bar->next = FRAME_SCROLL_BARS (f);
 5446   bar->prev = Qnil;
 5447   XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
 5448   if (! NILP (bar->next))
 5449     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 5450 }
 5451 
 5452 /* Remove all scroll bars on FRAME that haven't been saved since the
 5453    last call to `*condemn_scroll_bars_hook'.  */
 5454 
 5455 static void
 5456 XTjudge_scroll_bars (f)
 5457      FRAME_PTR f;
 5458 {
 5459   Lisp_Object bar, next;
 5460 
 5461   bar = FRAME_CONDEMNED_SCROLL_BARS (f);
 5462 
 5463   /* Clear out the condemned list now so we won't try to process any
 5464      more events on the hapless scroll bars.  */
 5465   FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
 5466 
 5467   for (; ! NILP (bar); bar = next)
 5468     {
 5469       struct scroll_bar *b = XSCROLL_BAR (bar);
 5470 
 5471       x_scroll_bar_remove (b);
 5472 
 5473       next = b->next;
 5474       b->next = b->prev = Qnil;
 5475     }
 5476 
 5477   /* Now there should be no references to the condemned scroll bars,
 5478      and they should get garbage-collected.  */
 5479 }
 5480 
 5481 
 5482 #ifndef USE_TOOLKIT_SCROLL_BARS
 5483 /* Handle an Expose or GraphicsExpose event on a scroll bar.  This
 5484    is a no-op when using toolkit scroll bars.
 5485 
 5486    This may be called from a signal handler, so we have to ignore GC
 5487    mark bits.  */
 5488 
 5489 static void
 5490 x_scroll_bar_expose (bar, event)
 5491      struct scroll_bar *bar;
 5492      XEvent *event;
 5493 {
 5494   Window w = bar->x_window;
 5495   FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 5496   GC gc = f->output_data.x->normal_gc;
 5497   int width_trim = VERTICAL_SCROLL_BAR_WIDTH_TRIM;
 5498 
 5499   BLOCK_INPUT;
 5500 
 5501   x_scroll_bar_set_handle (bar, bar->start, bar->end, 1);
 5502 
 5503   /* Switch to scroll bar foreground color.  */
 5504   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 5505     XSetForeground (FRAME_X_DISPLAY (f), gc,
 5506                     f->output_data.x->scroll_bar_foreground_pixel);
 5507 
 5508   /* Draw a one-pixel border just inside the edges of the scroll bar.  */
 5509   XDrawRectangle (FRAME_X_DISPLAY (f), w, gc,
 5510 
 5511                   /* x, y, width, height */
 5512                   0, 0,
 5513