1 /* Functions for the X window system.
   2    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
   3                  2001, 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 #include <config.h>
  22 #include <stdio.h>
  23 #include <math.h>
  24 #include <setjmp.h>
  25 #include <ctype.h>
  26 
  27 #ifdef HAVE_UNISTD_H
  28 #include <unistd.h>
  29 #endif
  30 
  31 /* This makes the fields of a Display accessible, in Xlib header files.  */
  32 
  33 #define XLIB_ILLEGAL_ACCESS
  34 
  35 #include "lisp.h"
  36 #include "xterm.h"
  37 #include "frame.h"
  38 #include "window.h"
  39 #include "buffer.h"
  40 #include "intervals.h"
  41 #include "dispextern.h"
  42 #include "keyboard.h"
  43 #include "blockinput.h"
  44 #include <epaths.h>
  45 #include "character.h"
  46 #include "charset.h"
  47 #include "coding.h"
  48 #include "fontset.h"
  49 #include "systime.h"
  50 #include "termhooks.h"
  51 #include "atimer.h"
  52 #include "termchar.h"
  53 #include "font.h"
  54 
  55 #ifdef HAVE_X_WINDOWS
  56 
  57 #include <ctype.h>
  58 #include <sys/types.h>
  59 #include <sys/stat.h>
  60 
  61 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work.  */
  62 #include "bitmaps/gray.xbm"
  63 #else
  64 #include <X11/bitmaps/gray>
  65 #endif
  66 
  67 #include "xsettings.h"
  68 
  69 #ifdef USE_GTK
  70 #include "gtkutil.h"
  71 #endif
  72 
  73 #ifdef USE_X_TOOLKIT
  74 #include <X11/Shell.h>
  75 
  76 #ifndef USE_MOTIF
  77 #ifdef HAVE_XAW3D
  78 #include <X11/Xaw3d/Paned.h>
  79 #include <X11/Xaw3d/Label.h>
  80 #else /* !HAVE_XAW3D */
  81 #include <X11/Xaw/Paned.h>
  82 #include <X11/Xaw/Label.h>
  83 #endif /* HAVE_XAW3D */
  84 #endif /* USE_MOTIF */
  85 
  86 #ifdef USG
  87 #undef USG      /* ####KLUDGE for Solaris 2.2 and up */
  88 #include <X11/Xos.h>
  89 #define USG
  90 #else
  91 #include <X11/Xos.h>
  92 #endif
  93 
  94 #include "widget.h"
  95 
  96 #include "../lwlib/lwlib.h"
  97 
  98 #ifdef USE_MOTIF
  99 #include <Xm/Xm.h>
 100 #include <Xm/DialogS.h>
 101 #include <Xm/FileSB.h>
 102 #endif
 103 
 104 #if !defined(NO_EDITRES)
 105 #define HACK_EDITRES
 106 extern void _XEditResCheckMessages ();
 107 #endif /* not defined NO_EDITRES */
 108 
 109 /* Unique id counter for widgets created by the Lucid Widget Library.  */
 110 
 111 extern LWLIB_ID widget_id_tick;
 112 
 113 extern void free_frame_menubar ();
 114 extern double atof ();
 115 
 116 #ifdef USE_MOTIF
 117 
 118 /* LessTif/Motif version info.  */
 119 
 120 static Lisp_Object Vmotif_version_string;
 121 
 122 #endif /* USE_MOTIF */
 123 
 124 #endif /* USE_X_TOOLKIT */
 125 
 126 #ifdef USE_GTK
 127 
 128 /* GTK+ version info */
 129 
 130 static Lisp_Object Vgtk_version_string;
 131 
 132 #endif /* USE_GTK */
 133 
 134 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
 135 
 136 /* The gray bitmap `bitmaps/gray'.  This is done because xterm.c uses
 137    it, and including `bitmaps/gray' more than once is a problem when
 138    config.h defines `static' as an empty replacement string.  */
 139 
 140 int gray_bitmap_width = gray_width;
 141 int gray_bitmap_height = gray_height;
 142 char *gray_bitmap_bits = gray_bits;
 143 
 144 /* Non-zero means prompt with the old GTK file selection dialog.  */
 145 
 146 int x_gtk_use_old_file_dialog;
 147 
 148 /* If non-zero, by default show hidden files in the GTK file chooser.  */
 149 
 150 int x_gtk_show_hidden_files;
 151 
 152 /* If non-zero, don't show additional help text in the GTK file chooser.  */
 153 
 154 int x_gtk_file_dialog_help_text;
 155 
 156 /* If non-zero, don't collapse to tool bar when it is detached.  */
 157 
 158 int x_gtk_whole_detached_tool_bar;
 159 
 160 /* The background and shape of the mouse pointer, and shape when not
 161    over text or in the modeline.  */
 162 
 163 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
 164 Lisp_Object Vx_hourglass_pointer_shape;
 165 
 166 /* The shape when over mouse-sensitive text.  */
 167 
 168 Lisp_Object Vx_sensitive_text_pointer_shape;
 169 
 170 /* If non-nil, the pointer shape to indicate that windows can be
 171    dragged horizontally.  */
 172 
 173 Lisp_Object Vx_window_horizontal_drag_shape;
 174 
 175 /* Color of chars displayed in cursor box.  */
 176 
 177 Lisp_Object Vx_cursor_fore_pixel;
 178 
 179 /* Nonzero if using X.  */
 180 
 181 static int x_in_use;
 182 
 183 /* Non nil if no window manager is in use.  */
 184 
 185 Lisp_Object Vx_no_window_manager;
 186 
 187 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.  */
 188 
 189 Lisp_Object Vx_pixel_size_width_font_regexp;
 190 
 191 Lisp_Object Qnone;
 192 Lisp_Object Qsuppress_icon;
 193 Lisp_Object Qundefined_color;
 194 Lisp_Object Qcompound_text, Qcancel_timer;
 195 Lisp_Object Qfont_param;
 196 
 197 /* In dispnew.c */
 198 
 199 extern Lisp_Object Vwindow_system_version;
 200 
 201 /* In editfns.c */
 202 
 203 extern Lisp_Object Vsystem_name;
 204 
 205 /* The below are defined in frame.c.  */
 206 
 207 #if GLYPH_DEBUG
 208 int image_cache_refcount, dpyinfo_refcount;
 209 #endif
 210 
 211 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
 212 char *x_last_font_name;
 213 #endif
 214 
 215 
 216 /* Error if we are not connected to X.  */
 217 
 218 void
 219 check_x ()
 220 {
 221   if (! x_in_use)
 222     error ("X windows are not in use or not initialized");
 223 }
 224 
 225 /* Nonzero if we can use mouse menus.
 226    You should not call this unless HAVE_MENUS is defined.  */
 227 
 228 int
 229 have_menus_p ()
 230 {
 231   return x_in_use;
 232 }
 233 
 234 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
 235    and checking validity for X.  */
 236 
 237 FRAME_PTR
 238 check_x_frame (frame)
 239      Lisp_Object frame;
 240 {
 241   FRAME_PTR f;
 242 
 243   if (NILP (frame))
 244     frame = selected_frame;
 245   CHECK_LIVE_FRAME (frame);
 246   f = XFRAME (frame);
 247   if (! FRAME_X_P (f))
 248     error ("Non-X frame used");
 249   return f;
 250 }
 251 
 252 /* Let the user specify an X display with a Lisp object.
 253    OBJECT may be nil, a frame or a terminal object.
 254    nil stands for the selected frame--or, if that is not an X frame,
 255    the first X display on the list.  */
 256 
 257 struct x_display_info *
 258 check_x_display_info (object)
 259      Lisp_Object object;
 260 {
 261   struct x_display_info *dpyinfo = NULL;
 262 
 263   if (NILP (object))
 264     {
 265       struct frame *sf = XFRAME (selected_frame);
 266 
 267       if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
 268         dpyinfo = FRAME_X_DISPLAY_INFO (sf);
 269       else if (x_display_list != 0)
 270         dpyinfo = x_display_list;
 271       else
 272         error ("X windows are not in use or not initialized");
 273     }
 274   else if (TERMINALP (object))
 275     {
 276       struct terminal *t = get_terminal (object, 1);
 277 
 278       if (t->type != output_x_window)
 279         error ("Terminal %d is not an X display", XINT (object));
 280 
 281       dpyinfo = t->display_info.x;
 282     }
 283   else if (STRINGP (object))
 284     dpyinfo = x_display_info_for_name (object);
 285   else
 286     {
 287       FRAME_PTR f = check_x_frame (object);
 288       dpyinfo = FRAME_X_DISPLAY_INFO (f);
 289     }
 290 
 291   return dpyinfo;
 292 }
 293 
 294 
 295 /* Return the Emacs frame-object corresponding to an X window.
 296    It could be the frame's main window or an icon window.  */
 297 
 298 /* This function can be called during GC, so use GC_xxx type test macros.  */
 299 
 300 struct frame *
 301 x_window_to_frame (dpyinfo, wdesc)
 302      struct x_display_info *dpyinfo;
 303      int wdesc;
 304 {
 305   Lisp_Object tail, frame;
 306   struct frame *f;
 307 
 308   if (wdesc == None) return 0;
 309 
 310   for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
 311     {
 312       frame = XCAR (tail);
 313       if (!FRAMEP (frame))
 314         continue;
 315       f = XFRAME (frame);
 316       if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
 317         continue;
 318       if (f->output_data.x->hourglass_window == wdesc)
 319         return f;
 320 #ifdef USE_X_TOOLKIT
 321       if ((f->output_data.x->edit_widget
 322            && XtWindow (f->output_data.x->edit_widget) == wdesc)
 323           /* A tooltip frame?  */
 324           || (!f->output_data.x->edit_widget
 325               && FRAME_X_WINDOW (f) == wdesc)
 326           || f->output_data.x->icon_desc == wdesc)
 327         return f;
 328 #else /* not USE_X_TOOLKIT */
 329 #ifdef USE_GTK
 330       if (f->output_data.x->edit_widget)
 331       {
 332         GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
 333         struct x_output *x = f->output_data.x;
 334         if (gwdesc != 0 && gwdesc == x->edit_widget)
 335           return f;
 336       }
 337 #endif /* USE_GTK */
 338       if (FRAME_X_WINDOW (f) == wdesc
 339           || f->output_data.x->icon_desc == wdesc)
 340         return f;
 341 #endif /* not USE_X_TOOLKIT */
 342     }
 343   return 0;
 344 }
 345 
 346 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 347 /* Like x_window_to_frame but also compares the window with the widget's
 348    windows.  */
 349 
 350 struct frame *
 351 x_any_window_to_frame (dpyinfo, wdesc)
 352      struct x_display_info *dpyinfo;
 353      int wdesc;
 354 {
 355   Lisp_Object tail, frame;
 356   struct frame *f, *found;
 357   struct x_output *x;
 358 
 359   if (wdesc == None) return NULL;
 360 
 361   found = NULL;
 362   for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail))
 363     {
 364       frame = XCAR (tail);
 365       if (!FRAMEP (frame))
 366         continue;
 367 
 368       f = XFRAME (frame);
 369       if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
 370         {
 371           /* This frame matches if the window is any of its widgets.  */
 372           x = f->output_data.x;
 373           if (x->hourglass_window == wdesc)
 374             found = f;
 375           else if (x->widget)
 376             {
 377 #ifdef USE_GTK
 378               GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
 379               if (gwdesc != 0
 380                   && gtk_widget_get_toplevel (gwdesc) == x->widget)
 381                 found = f;
 382 #else
 383               if (wdesc == XtWindow (x->widget)
 384                   || wdesc == XtWindow (x->column_widget)
 385                   || wdesc == XtWindow (x->edit_widget))
 386                 found = f;
 387               /* Match if the window is this frame's menubar.  */
 388               else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
 389                 found = f;
 390 #endif
 391             }
 392           else if (FRAME_X_WINDOW (f) == wdesc)
 393             /* A tooltip frame.  */
 394             found = f;
 395         }
 396     }
 397 
 398   return found;
 399 }
 400 
 401 /* Likewise, but consider only the menu bar widget.  */
 402 
 403 struct frame *
 404 x_menubar_window_to_frame (dpyinfo, wdesc)
 405      struct x_display_info *dpyinfo;
 406      int wdesc;
 407 {
 408   Lisp_Object tail, frame;
 409   struct frame *f;
 410   struct x_output *x;
 411 
 412   if (wdesc == None) return 0;
 413 
 414   for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
 415     {
 416       frame = XCAR (tail);
 417       if (!FRAMEP (frame))
 418         continue;
 419       f = XFRAME (frame);
 420       if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
 421         continue;
 422       x = f->output_data.x;
 423       /* Match if the window is this frame's menubar.  */
 424 #ifdef USE_GTK
 425       if (x->menubar_widget)
 426         {
 427           GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
 428 
 429           /* This gives false positives, but the rectangle check in xterm.c
 430              where this is called takes care of that.  */
 431           if (gwdesc != 0
 432               && (gwdesc == x->menubar_widget
 433                   || gtk_widget_is_ancestor (x->menubar_widget, gwdesc)
 434                   || gtk_widget_is_ancestor (gwdesc, x->menubar_widget)))
 435             return f;
 436         }
 437 #else
 438       if (x->menubar_widget
 439           && lw_window_is_in_menubar (wdesc, x->menubar_widget))
 440         return f;
 441 #endif
 442     }
 443   return 0;
 444 }
 445 
 446 /* Return the frame whose principal (outermost) window is WDESC.
 447    If WDESC is some other (smaller) window, we return 0.  */
 448 
 449 struct frame *
 450 x_top_window_to_frame (dpyinfo, wdesc)
 451      struct x_display_info *dpyinfo;
 452      int wdesc;
 453 {
 454   Lisp_Object tail, frame;
 455   struct frame *f;
 456   struct x_output *x;
 457 
 458   if (wdesc == None) return 0;
 459 
 460   for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
 461     {
 462       frame = XCAR (tail);
 463       if (!FRAMEP (frame))
 464         continue;
 465       f = XFRAME (frame);
 466       if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
 467         continue;
 468       x = f->output_data.x;
 469 
 470       if (x->widget)
 471         {
 472           /* This frame matches if the window is its topmost widget.  */
 473 #ifdef USE_GTK
 474           GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
 475           if (gwdesc == x->widget)
 476             return f;
 477 #else
 478           if (wdesc == XtWindow (x->widget))
 479             return f;
 480 #if 0 /* I don't know why it did this,
 481          but it seems logically wrong,
 482          and it causes trouble for MapNotify events.  */
 483           /* Match if the window is this frame's menubar.  */
 484           if (x->menubar_widget
 485               && wdesc == XtWindow (x->menubar_widget))
 486             return f;
 487 #endif
 488 #endif
 489         }
 490       else if (FRAME_X_WINDOW (f) == wdesc)
 491         /* Tooltip frame.  */
 492         return f;
 493     }
 494   return 0;
 495 }
 496 #endif /* USE_X_TOOLKIT || USE_GTK */
 497 
 498 
 499 
 500 static void x_default_font_parameter P_ ((struct frame *, Lisp_Object));
 501 
 502 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
 503 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
 504 
 505 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 506 static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object));
 507 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 508 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 509 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 510 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 511 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
 512 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
 513 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
 514 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
 515 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
 516 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
 517 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
 518 void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object,
 519                                       Lisp_Object));
 520 void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object,
 521                                       Lisp_Object));
 522 static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
 523                                                              Lisp_Object,
 524                                                              Lisp_Object,
 525                                                              char *, char *,
 526                                                              int));
 527 
 528 
 529 /* Store the screen positions of frame F into XPTR and YPTR.
 530    These are the positions of the containing window manager window,
 531    not Emacs's own window.  */
 532 
 533 void
 534 x_real_positions (f, xptr, yptr)
 535      FRAME_PTR f;
 536      int *xptr, *yptr;
 537 {
 538   int win_x, win_y, outer_x, outer_y;
 539   int real_x = 0, real_y = 0;
 540   int had_errors = 0;
 541   Window win = f->output_data.x->parent_desc;
 542 
 543   BLOCK_INPUT;
 544 
 545   x_catch_errors (FRAME_X_DISPLAY (f));
 546 
 547   if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
 548     win = FRAME_OUTER_WINDOW (f);
 549 
 550   /* This loop traverses up the containment tree until we hit the root
 551      window.  Window managers may intersect many windows between our window
 552      and the root window.  The window we find just before the root window
 553      should be the outer WM window. */
 554   for (;;)
 555     {
 556       Window wm_window, rootw;
 557       Window *tmp_children;
 558       unsigned int tmp_nchildren;
 559       int success;
 560 
 561       success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
 562                             &wm_window, &tmp_children, &tmp_nchildren);
 563 
 564       had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
 565 
 566       /* Don't free tmp_children if XQueryTree failed.  */
 567       if (! success)
 568         break;
 569 
 570       XFree ((char *) tmp_children);
 571 
 572       if (wm_window == rootw || had_errors)
 573         break;
 574 
 575       win = wm_window;
 576     }
 577 
 578   if (! had_errors)
 579     {
 580       unsigned int ign;
 581       Window child, rootw;
 582 
 583       /* Get the real coordinates for the WM window upper left corner */
 584       XGetGeometry (FRAME_X_DISPLAY (f), win,
 585                     &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
 586 
 587       /* Translate real coordinates to coordinates relative to our
 588          window.  For our window, the upper left corner is 0, 0.
 589          Since the upper left corner of the WM window is outside
 590          our window, win_x and win_y will be negative:
 591 
 592          ------------------          ---> x
 593          |      title                |
 594          | -----------------         v y
 595          | |  our window
 596       */
 597       XTranslateCoordinates (FRAME_X_DISPLAY (f),
 598 
 599                              /* From-window, to-window.  */
 600                              FRAME_X_DISPLAY_INFO (f)->root_window,
 601                              FRAME_X_WINDOW (f),
 602 
 603                              /* From-position, to-position.  */
 604                              real_x, real_y, &win_x, &win_y,
 605 
 606                              /* Child of win.  */
 607                              &child);
 608 
 609       if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
 610         {
 611           outer_x = win_x;
 612           outer_y = win_y;
 613         }
 614       else
 615         {
 616           XTranslateCoordinates (FRAME_X_DISPLAY (f),
 617 
 618                                  /* From-window, to-window.  */
 619                                  FRAME_X_DISPLAY_INFO (f)->root_window,
 620                                  FRAME_OUTER_WINDOW (f),
 621 
 622                                  /* From-position, to-position.  */
 623                                  real_x, real_y, &outer_x, &outer_y,
 624 
 625                                  /* Child of win.  */
 626                                  &child);
 627         }
 628 
 629       had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
 630     }
 631 
 632   x_uncatch_errors ();
 633 
 634   UNBLOCK_INPUT;
 635 
 636   if (had_errors) return;
 637 
 638   f->x_pixels_diff = -win_x;
 639   f->y_pixels_diff = -win_y;
 640 
 641   FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
 642   FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
 643 
 644   *xptr = real_x;
 645   *yptr = real_y;
 646 }
 647 
 648 
 649 
 650 
 651 /* Gamma-correct COLOR on frame F.  */
 652 
 653 void
 654 gamma_correct (f, color)
 655      struct frame *f;
 656      XColor *color;
 657 {
 658   if (f->gamma)
 659     {
 660       color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
 661       color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
 662       color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
 663     }
 664 }
 665 
 666 
 667 /* Decide if color named COLOR_NAME is valid for use on frame F.  If
 668    so, return the RGB values in COLOR.  If ALLOC_P is non-zero,
 669    allocate the color.  Value is zero if COLOR_NAME is invalid, or
 670    no color could be allocated.  */
 671 
 672 int
 673 x_defined_color (f, color_name, color, alloc_p)
 674      struct frame *f;
 675      char *color_name;
 676      XColor *color;
 677      int alloc_p;
 678 {
 679   int success_p;
 680   Display *dpy = FRAME_X_DISPLAY (f);
 681   Colormap cmap = FRAME_X_COLORMAP (f);
 682 
 683   BLOCK_INPUT;
 684   success_p = XParseColor (dpy, cmap, color_name, color);
 685   if (success_p && alloc_p)
 686     success_p = x_alloc_nearest_color (f, cmap, color);
 687   UNBLOCK_INPUT;
 688 
 689   return success_p;
 690 }
 691 
 692 
 693 /* Return the pixel color value for color COLOR_NAME on frame F.  If F
 694    is a monochrome frame, return MONO_COLOR regardless of what ARG says.
 695    Signal an error if color can't be allocated.  */
 696 
 697 int
 698 x_decode_color (f, color_name, mono_color)
 699      FRAME_PTR f;
 700      Lisp_Object color_name;
 701      int mono_color;
 702 {
 703   XColor cdef;
 704 
 705   CHECK_STRING (color_name);
 706 
 707 #if 0 /* Don't do this.  It's wrong when we're not using the default
 708          colormap, it makes freeing difficult, and it's probably not
 709          an important optimization.  */
 710   if (strcmp (SDATA (color_name), "black") == 0)
 711     return BLACK_PIX_DEFAULT (f);
 712   else if (strcmp (SDATA (color_name), "white") == 0)
 713     return WHITE_PIX_DEFAULT (f);
 714 #endif
 715 
 716   /* Return MONO_COLOR for monochrome frames.  */
 717   if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
 718     return mono_color;
 719 
 720   /* x_defined_color is responsible for coping with failures
 721      by looking for a near-miss.  */
 722   if (x_defined_color (f, SDATA (color_name), &cdef, 1))
 723     return cdef.pixel;
 724 
 725   signal_error ("Undefined color", color_name);
 726 }
 727 
 728 
 729 
 730 /* Change the `wait-for-wm' frame parameter of frame F.  OLD_VALUE is
 731    the previous value of that parameter, NEW_VALUE is the new value.
 732    See also the comment of wait_for_wm in struct x_output.  */
 733 
 734 static void
 735 x_set_wait_for_wm (f, new_value, old_value)
 736      struct frame *f;
 737      Lisp_Object new_value, old_value;
 738 {
 739   f->output_data.x->wait_for_wm = !NILP (new_value);
 740 }
 741 
 742 #ifdef USE_GTK
 743 
 744 /* Set icon from FILE for frame F.  By using GTK functions the icon
 745    may be any format that GdkPixbuf knows about, i.e. not just bitmaps.  */
 746 
 747 int
 748 xg_set_icon (f, file)
 749     FRAME_PTR f;
 750     Lisp_Object file;
 751 {
 752   int result = 0;
 753   Lisp_Object found;
 754 
 755   found = x_find_image_file (file);
 756 
 757   if (! NILP (found))
 758     {
 759       GdkPixbuf *pixbuf;
 760       GError *err = NULL;
 761       char *filename = (char *) SDATA (found);
 762       BLOCK_INPUT;
 763 
 764       pixbuf = gdk_pixbuf_new_from_file (filename, &err);
 765 
 766       if (pixbuf)
 767         {
 768           gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
 769                                pixbuf);
 770           g_object_unref (pixbuf);
 771 
 772           result = 1;
 773         }
 774       else
 775         g_error_free (err);
 776 
 777       UNBLOCK_INPUT;
 778     }
 779 
 780   return result;
 781 }
 782 
 783 int
 784 xg_set_icon_from_xpm_data (f, data)
 785     FRAME_PTR f;
 786     char **data;
 787 {
 788   int result = 0;
 789   GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data);
 790 
 791   if (!pixbuf)
 792     return 0;
 793 
 794   gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
 795   g_object_unref (pixbuf);
 796   return 1;
 797 }
 798 #endif /* USE_GTK */
 799 
 800 
 801 /* Functions called only from `x_set_frame_param'
 802    to set individual parameters.
 803 
 804    If FRAME_X_WINDOW (f) is 0,
 805    the frame is being created and its X-window does not exist yet.
 806    In that case, just record the parameter's new value
 807    in the standard place; do not attempt to change the window.  */
 808 
 809 void
 810 x_set_foreground_color (f, arg, oldval)
 811      struct frame *f;
 812      Lisp_Object arg, oldval;
 813 {
 814   struct x_output *x = f->output_data.x;
 815   unsigned long fg, old_fg;
 816 
 817   fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
 818   old_fg = FRAME_FOREGROUND_PIXEL (f);
 819   FRAME_FOREGROUND_PIXEL (f) = fg;
 820 
 821   if (FRAME_X_WINDOW (f) != 0)
 822     {
 823       Display *dpy = FRAME_X_DISPLAY (f);
 824 
 825       BLOCK_INPUT;
 826       XSetForeground (dpy, x->normal_gc, fg);
 827       XSetBackground (dpy, x->reverse_gc, fg);
 828 
 829       if (x->cursor_pixel == old_fg)
 830         {
 831           unload_color (f, x->cursor_pixel);
 832           x->cursor_pixel = x_copy_color (f, fg);
 833           XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
 834         }
 835 
 836       UNBLOCK_INPUT;
 837 
 838       update_face_from_frame_parameter (f, Qforeground_color, arg);
 839 
 840       if (FRAME_VISIBLE_P (f))
 841         redraw_frame (f);
 842     }
 843 
 844   unload_color (f, old_fg);
 845 }
 846 
 847 void
 848 x_set_background_color (f, arg, oldval)
 849      struct frame *f;
 850      Lisp_Object arg, oldval;
 851 {
 852   struct x_output *x = f->output_data.x;
 853   unsigned long bg;
 854 
 855   bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
 856   unload_color (f, FRAME_BACKGROUND_PIXEL (f));
 857   FRAME_BACKGROUND_PIXEL (f) = bg;
 858 
 859   if (FRAME_X_WINDOW (f) != 0)
 860     {
 861       Display *dpy = FRAME_X_DISPLAY (f);
 862 
 863       BLOCK_INPUT;
 864       XSetBackground (dpy, x->normal_gc, bg);
 865       XSetForeground (dpy, x->reverse_gc, bg);
 866       XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
 867       XSetForeground (dpy, x->cursor_gc, bg);
 868 
 869 #ifdef USE_GTK
 870       xg_set_background_color (f, bg);
 871 #endif
 872 
 873 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
 874                                    toolkit scroll bars.  */
 875       {
 876         Lisp_Object bar;
 877         for (bar = FRAME_SCROLL_BARS (f);
 878              !NILP (bar);
 879              bar = XSCROLL_BAR (bar)->next)
 880           {
 881             Window window = XSCROLL_BAR (bar)->x_window;
 882             XSetWindowBackground (dpy, window, bg);
 883           }
 884       }
 885 #endif /* USE_TOOLKIT_SCROLL_BARS */
 886 
 887       UNBLOCK_INPUT;
 888       update_face_from_frame_parameter (f, Qbackground_color, arg);
 889 
 890       if (FRAME_VISIBLE_P (f))
 891         redraw_frame (f);
 892     }
 893 }
 894 
 895 static Cursor
 896 make_invisible_cursor (f)
 897      struct frame *f;
 898 {
 899   Display *dpy = FRAME_X_DISPLAY (f);
 900   static char const no_data[] = { 0 };
 901   Pixmap pix;
 902   XColor col;
 903   Cursor c;
 904 
 905   x_catch_errors (dpy);
 906   pix = XCreateBitmapFromData (dpy, FRAME_X_DISPLAY_INFO (f)->root_window,
 907                                no_data, 1, 1);
 908   if (! x_had_errors_p (dpy) && pix != None)
 909     {
 910       col.pixel = 0;
 911       col.red = col.green = col.blue = 0;
 912       col.flags = DoRed | DoGreen | DoBlue;
 913       c = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
 914       if (x_had_errors_p (dpy) || c == None)
 915         c = 0;
 916       XFreePixmap (dpy, pix);
 917     }
 918 
 919   x_uncatch_errors ();
 920 
 921   return c;
 922 }
 923 
 924 void
 925 x_set_mouse_color (f, arg, oldval)
 926      struct frame *f;
 927      Lisp_Object arg, oldval;
 928 {
 929   struct x_output *x = f->output_data.x;
 930   Display *dpy = FRAME_X_DISPLAY (f);
 931   Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
 932   Cursor hourglass_cursor, horizontal_drag_cursor;
 933   unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
 934   unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
 935 
 936   /* Don't let pointers be invisible.  */
 937   if (mask_color == pixel)
 938     {
 939       x_free_colors (f, &pixel, 1);
 940       pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
 941     }
 942 
 943   unload_color (f, x->mouse_pixel);
 944   x->mouse_pixel = pixel;
 945 
 946   BLOCK_INPUT;
 947 
 948   /* It's not okay to crash if the user selects a screwy cursor.  */
 949   x_catch_errors (dpy);
 950 
 951   if (!NILP (Vx_pointer_shape))
 952     {
 953       CHECK_NUMBER (Vx_pointer_shape);
 954       cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
 955     }
 956   else
 957     cursor = XCreateFontCursor (dpy, XC_xterm);
 958   x_check_errors (dpy, "bad text pointer cursor: %s");
 959 
 960   if (!NILP (Vx_nontext_pointer_shape))
 961     {
 962       CHECK_NUMBER (Vx_nontext_pointer_shape);
 963       nontext_cursor
 964         = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
 965     }
 966   else
 967     nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
 968   x_check_errors (dpy, "bad nontext pointer cursor: %s");
 969 
 970   if (!NILP (Vx_hourglass_pointer_shape))
 971     {
 972       CHECK_NUMBER (Vx_hourglass_pointer_shape);
 973       hourglass_cursor
 974         = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
 975     }
 976   else
 977     hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
 978   x_check_errors (dpy, "bad hourglass pointer cursor: %s");
 979 
 980   if (!NILP (Vx_mode_pointer_shape))
 981     {
 982       CHECK_NUMBER (Vx_mode_pointer_shape);
 983       mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
 984     }
 985   else
 986     mode_cursor = XCreateFontCursor (dpy, XC_xterm);
 987   x_check_errors (dpy, "bad modeline pointer cursor: %s");
 988 
 989   if (!NILP (Vx_sensitive_text_pointer_shape))
 990     {
 991       CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
 992       hand_cursor
 993         = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
 994     }
 995   else
 996     hand_cursor = XCreateFontCursor (dpy, XC_hand2);
 997 
 998   if (!NILP (Vx_window_horizontal_drag_shape))
 999     {
1000       CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1001       horizontal_drag_cursor
1002         = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
1003     }
1004   else
1005     horizontal_drag_cursor
1006       = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
1007 
1008   /* Check and report errors with the above calls.  */
1009   x_check_errors (dpy, "can't set cursor shape: %s");
1010   x_uncatch_errors ();
1011 
1012   {
1013     XColor fore_color, back_color;
1014 
1015     fore_color.pixel = x->mouse_pixel;
1016     x_query_color (f, &fore_color);
1017     back_color.pixel = mask_color;
1018     x_query_color (f, &back_color);
1019 
1020     XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1021     XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1022     XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1023     XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1024     XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1025     XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1026   }
1027 
1028   if (FRAME_X_WINDOW (f) != 0)
1029     XDefineCursor (dpy, FRAME_X_WINDOW (f),
1030                    f->output_data.x->current_cursor = cursor);
1031 
1032   if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor == 0)
1033     FRAME_X_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
1034   
1035   if (cursor != x->text_cursor
1036       && x->text_cursor != 0)
1037     XFreeCursor (dpy, x->text_cursor);
1038   x->text_cursor = cursor;
1039 
1040   if (nontext_cursor != x->nontext_cursor
1041       && x->nontext_cursor != 0)
1042     XFreeCursor (dpy, x->nontext_cursor);
1043   x->nontext_cursor = nontext_cursor;
1044 
1045   if (hourglass_cursor != x->hourglass_cursor
1046       && x->hourglass_cursor != 0)
1047     XFreeCursor (dpy, x->hourglass_cursor);
1048   x->hourglass_cursor = hourglass_cursor;
1049 
1050   if (mode_cursor != x->modeline_cursor
1051       && x->modeline_cursor != 0)
1052     XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1053   x->modeline_cursor = mode_cursor;
1054 
1055   if (hand_cursor != x->hand_cursor
1056       && x->hand_cursor != 0)
1057     XFreeCursor (dpy, x->hand_cursor);
1058   x->hand_cursor = hand_cursor;
1059 
1060   if (horizontal_drag_cursor != x->horizontal_drag_cursor
1061       && x->horizontal_drag_cursor != 0)
1062     XFreeCursor (dpy, x->horizontal_drag_cursor);
1063   x->horizontal_drag_cursor = horizontal_drag_cursor;
1064 
1065   XFlush (dpy);
1066   UNBLOCK_INPUT;
1067 
1068   update_face_from_frame_parameter (f, Qmouse_color, arg);
1069 }
1070 
1071 void
1072 x_set_cursor_color (f, arg, oldval)
1073      struct frame *f;
1074      Lisp_Object arg, oldval;
1075 {
1076   unsigned long fore_pixel, pixel;
1077   int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
1078   struct x_output *x = f->output_data.x;
1079 
1080   if (!NILP (Vx_cursor_fore_pixel))
1081     {
1082       fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1083                                    WHITE_PIX_DEFAULT (f));
1084       fore_pixel_allocated_p = 1;
1085     }
1086   else
1087     fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1088 
1089   pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1090   pixel_allocated_p = 1;
1091 
1092   /* Make sure that the cursor color differs from the background color.  */
1093   if (pixel == FRAME_BACKGROUND_PIXEL (f))
1094     {
1095       if (pixel_allocated_p)
1096         {
1097           x_free_colors (f, &pixel, 1);
1098           pixel_allocated_p = 0;
1099         }
1100 
1101       pixel = x->mouse_pixel;
1102       if (pixel == fore_pixel)
1103         {
1104           if (fore_pixel_allocated_p)
1105             {
1106               x_free_colors (f, &fore_pixel, 1);
1107               fore_pixel_allocated_p = 0;
1108             }
1109           fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1110         }
1111     }
1112 
1113   unload_color (f, x->cursor_foreground_pixel);
1114   if (!fore_pixel_allocated_p)
1115     fore_pixel = x_copy_color (f, fore_pixel);
1116   x->cursor_foreground_pixel = fore_pixel;
1117 
1118   unload_color (f, x->cursor_pixel);
1119   if (!pixel_allocated_p)
1120     pixel = x_copy_color (f, pixel);
1121   x->cursor_pixel = pixel;
1122 
1123   if (FRAME_X_WINDOW (f) != 0)
1124     {
1125       BLOCK_INPUT;
1126       XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1127       XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1128       UNBLOCK_INPUT;
1129 
1130       if (FRAME_VISIBLE_P (f))
1131         {
1132           x_update_cursor (f, 0);
1133           x_update_cursor (f, 1);
1134         }
1135     }
1136 
1137   update_face_from_frame_parameter (f, Qcursor_color, arg);
1138 }
1139 
1140 /* Set the border-color of frame F to pixel value PIX.
1141    Note that this does not fully take effect if done before
1142    F has an x-window.  */
1143 
1144 void
1145 x_set_border_pixel (f, pix)
1146      struct frame *f;
1147      int pix;
1148 {
1149   unload_color (f, f->output_data.x->border_pixel);
1150   f->output_data.x->border_pixel = pix;
1151 
1152   if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1153     {
1154       BLOCK_INPUT;
1155       XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1156                         (unsigned long)pix);
1157       UNBLOCK_INPUT;
1158 
1159       if (FRAME_VISIBLE_P (f))
1160         redraw_frame (f);
1161     }
1162 }
1163 
1164 /* Set the border-color of frame F to value described by ARG.
1165    ARG can be a string naming a color.
1166    The border-color is used for the border that is drawn by the X server.
1167    Note that this does not fully take effect if done before
1168    F has an x-window; it must be redone when the window is created.
1169 
1170    Note: this is done in two routines because of the way X10 works.
1171 
1172    Note: under X11, this is normally the province of the window manager,
1173    and so emacs' border colors may be overridden.  */
1174 
1175 void
1176 x_set_border_color (f, arg, oldval)
1177      struct frame *f;
1178      Lisp_Object arg, oldval;
1179 {
1180   int pix;
1181 
1182   CHECK_STRING (arg);
1183   pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1184   x_set_border_pixel (f, pix);
1185   update_face_from_frame_parameter (f, Qborder_color, arg);
1186 }
1187 
1188 
1189 void
1190 x_set_cursor_type (f, arg, oldval)
1191      FRAME_PTR f;
1192      Lisp_Object arg, oldval;
1193 {
1194   set_frame_cursor_types (f, arg);
1195 
1196   /* Make sure the cursor gets redrawn.  */
1197   cursor_type_changed = 1;
1198 }
1199 
1200 void
1201 x_set_icon_type (f, arg, oldval)
1202      struct frame *f;
1203      Lisp_Object arg, oldval;
1204 {
1205   int result;
1206 
1207   if (STRINGP (arg))
1208     {
1209       if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1210         return;
1211     }
1212   else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1213     return;
1214 
1215   BLOCK_INPUT;
1216   if (NILP (arg))
1217     result = x_text_icon (f,
1218                           (char *) SDATA ((!NILP (f->icon_name)
1219                                              ? f->icon_name
1220                                              : f->name)));
1221   else
1222     result = x_bitmap_icon (f, arg);
1223 
1224   if (result)
1225     {
1226       UNBLOCK_INPUT;
1227       error ("No icon window available");
1228     }
1229 
1230   XFlush (FRAME_X_DISPLAY (f));
1231   UNBLOCK_INPUT;
1232 }
1233 
1234 void
1235 x_set_icon_name (f, arg, oldval)
1236      struct frame *f;
1237      Lisp_Object arg, oldval;
1238 {
1239   int result;
1240 
1241   if (STRINGP (arg))
1242     {
1243       if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1244         return;
1245     }
1246   else if (!NILP (arg) || NILP (oldval))
1247     return;
1248 
1249   f->icon_name = arg;
1250 
1251   if (f->output_data.x->icon_bitmap != 0)
1252     return;
1253 
1254   BLOCK_INPUT;
1255 
1256   result = x_text_icon (f,
1257                         (char *) SDATA ((!NILP (f->icon_name)
1258                                          ? f->icon_name
1259                                          : !NILP (f->title)
1260                                          ? f->title
1261                                          : f->name)));
1262 
1263   if (result)
1264     {
1265       UNBLOCK_INPUT;
1266       error ("No icon window available");
1267     }
1268 
1269   XFlush (FRAME_X_DISPLAY (f));
1270   UNBLOCK_INPUT;
1271 }
1272 
1273 
1274 void
1275 x_set_menu_bar_lines (f, value, oldval)
1276      struct frame *f;
1277      Lisp_Object value, oldval;
1278 {
1279   int nlines;
1280 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1281   int olines = FRAME_MENU_BAR_LINES (f);
1282 #endif
1283 
1284   /* Right now, menu bars don't work properly in minibuf-only frames;
1285      most of the commands try to apply themselves to the minibuffer
1286      frame itself, and get an error because you can't switch buffers
1287      in or split the minibuffer window.  */
1288   if (FRAME_MINIBUF_ONLY_P (f))
1289     return;
1290 
1291   if (INTEGERP (value))
1292     nlines = XINT (value);
1293   else
1294     nlines = 0;
1295 
1296   /* Make sure we redisplay all windows in this frame.  */
1297   windows_or_buffers_changed++;
1298 
1299 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1300   FRAME_MENU_BAR_LINES (f) = 0;
1301   if (nlines)
1302     {
1303       FRAME_EXTERNAL_MENU_BAR (f) = 1;
1304       if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1305         /* Make sure next redisplay shows the menu bar.  */
1306         XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1307     }
1308   else
1309     {
1310       if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1311         free_frame_menubar (f);
1312       FRAME_EXTERNAL_MENU_BAR (f) = 0;
1313       if (FRAME_X_P (f))
1314         f->output_data.x->menubar_widget = 0;
1315     }
1316 #else /* not USE_X_TOOLKIT && not USE_GTK */
1317   FRAME_MENU_BAR_LINES (f) = nlines;
1318   change_window_heights (f->root_window, nlines - olines);
1319 
1320   /* If the menu bar height gets changed, the internal border below
1321      the top margin has to be cleared.  Also, if the menu bar gets
1322      larger, the area for the added lines has to be cleared except for
1323      the first menu bar line that is to be drawn later.  */
1324   if (nlines != olines)
1325     {
1326       int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1327       int width = FRAME_PIXEL_WIDTH (f);
1328       int y;
1329 
1330       /* height can be zero here. */
1331       if (height > 0 && width > 0)
1332         {
1333           y = FRAME_TOP_MARGIN_HEIGHT (f);
1334 
1335           BLOCK_INPUT;
1336           x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1337                         0, y, width, height, False);
1338           UNBLOCK_INPUT;
1339         }
1340 
1341       if (nlines > 1 && nlines > olines)
1342         {
1343           y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
1344           height = nlines * FRAME_LINE_HEIGHT (f) - y;
1345 
1346           BLOCK_INPUT;
1347           x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1348                         0, y, width, height, False);
1349           UNBLOCK_INPUT;
1350         }
1351 
1352       if (nlines == 0 && WINDOWP (f->menu_bar_window))
1353         clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
1354     }
1355 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1356   adjust_glyphs (f);
1357 }
1358 
1359 
1360 /* Set the number of lines used for the tool bar of frame F to VALUE.
1361    VALUE not an integer, or < 0 means set the lines to zero.  OLDVAL
1362    is the old number of tool bar lines.  This function changes the
1363    height of all windows on frame F to match the new tool bar height.
1364    The frame's height doesn't change.  */
1365 
1366 void
1367 x_set_tool_bar_lines (f, value, oldval)
1368      struct frame *f;
1369      Lisp_Object value, oldval;
1370 {
1371   int delta, nlines, root_height;
1372   Lisp_Object root_window;
1373 
1374   /* Treat tool bars like menu bars.  */
1375   if (FRAME_MINIBUF_ONLY_P (f))
1376     return;
1377 
1378   /* Use VALUE only if an integer >= 0.  */
1379   if (INTEGERP (value) && XINT (value) >= 0)
1380     nlines = XFASTINT (value);
1381   else
1382     nlines = 0;
1383 
1384 #ifdef USE_GTK
1385   FRAME_TOOL_BAR_LINES (f) = 0;
1386   if (nlines)
1387     {
1388       FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1389       if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1390         /* Make sure next redisplay shows the tool bar.  */
1391         XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1392       update_frame_tool_bar (f);
1393     }
1394   else
1395     {
1396       if (FRAME_EXTERNAL_TOOL_BAR (f))
1397         free_frame_tool_bar (f);
1398       FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1399     }
1400 
1401   return;
1402 #endif
1403 
1404      /* Make sure we redisplay all windows in this frame.  */
1405   ++windows_or_buffers_changed;
1406 
1407   delta = nlines - FRAME_TOOL_BAR_LINES (f);
1408 
1409   /* Don't resize the tool-bar to more than we have room for.  */
1410   root_window = FRAME_ROOT_WINDOW (f);
1411   root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1412   if (root_height - delta < 1)
1413     {
1414       delta = root_height - 1;
1415       nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1416     }
1417 
1418   FRAME_TOOL_BAR_LINES (f) = nlines;
1419   change_window_heights (root_window, delta);
1420   adjust_glyphs (f);
1421 
1422   /* We also have to make sure that the internal border at the top of
1423      the frame, below the menu bar or tool bar, is redrawn when the
1424      tool bar disappears.  This is so because the internal border is
1425      below the tool bar if one is displayed, but is below the menu bar
1426      if there isn't a tool bar.  The tool bar draws into the area
1427      below the menu bar.  */
1428   if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1429     {
1430       clear_frame (f);
1431       clear_current_matrices (f);
1432     }
1433 
1434   /* If the tool bar gets smaller, the internal border below it
1435      has to be cleared.  It was formerly part of the display
1436      of the larger tool bar, and updating windows won't clear it.  */
1437   if (delta < 0)
1438     {
1439       int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1440       int width = FRAME_PIXEL_WIDTH (f);
1441       int y = (FRAME_MENU_BAR_LINES (f) + nlines) * FRAME_LINE_HEIGHT (f);
1442 
1443       /* height can be zero here. */
1444       if (height > 0 && width > 0)
1445         {
1446           BLOCK_INPUT;
1447           x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1448                         0, y, width, height, False);
1449           UNBLOCK_INPUT;
1450         }
1451 
1452       if (WINDOWP (f->tool_bar_window))
1453         clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1454     }
1455 }
1456 
1457 
1458 /* Set the foreground color for scroll bars on frame F to VALUE.
1459    VALUE should be a string, a color name.  If it isn't a string or
1460    isn't a valid color name, do nothing.  OLDVAL is the old value of
1461    the frame parameter.  */
1462 
1463 void
1464 x_set_scroll_bar_foreground (f, value, oldval)
1465      struct frame *f;
1466      Lisp_Object value, oldval;
1467 {
1468   unsigned long pixel;
1469 
1470   if (STRINGP (value))
1471     pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1472   else
1473     pixel = -1;
1474 
1475   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1476     unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1477 
1478   f->output_data.x->scroll_bar_foreground_pixel = pixel;
1479   if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1480     {
1481       /* Remove all scroll bars because they have wrong colors.  */
1482       if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1483         (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1484       if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1485         (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1486 
1487       update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1488       redraw_frame (f);
1489     }
1490 }
1491 
1492 
1493 /* Set the background color for scroll bars on frame F to VALUE VALUE
1494    should be a string, a color name.  If it isn't a string or isn't a
1495    valid color name, do nothing.  OLDVAL is the old value of the frame
1496    parameter.  */
1497 
1498 void
1499 x_set_scroll_bar_background (f, value, oldval)
1500      struct frame *f;
1501      Lisp_Object value, oldval;
1502 {
1503   unsigned long pixel;
1504 
1505   if (STRINGP (value))
1506     pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1507   else
1508     pixel = -1;
1509 
1510   if (f->output_data.x->scroll_bar_background_pixel != -1)
1511     unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1512 
1513 #ifdef USE_TOOLKIT_SCROLL_BARS
1514   /* Scrollbar shadow colors.  */
1515   if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1516     {
1517       unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1518       f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1519     }
1520   if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1521     {
1522       unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1523       f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1524     }
1525 #endif /* USE_TOOLKIT_SCROLL_BARS */
1526 
1527   f->output_data.x->scroll_bar_background_pixel = pixel;
1528   if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1529     {
1530       /* Remove all scroll bars because they have wrong colors.  */
1531       if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1532         (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1533       if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1534         (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1535 
1536       update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1537       redraw_frame (f);
1538     }
1539 }
1540 
1541 
1542 /* Encode Lisp string STRING as a text in a format appropriate for
1543    XICCC (X Inter Client Communication Conventions).
1544 
1545    This can call Lisp code, so callers must GCPRO.
1546 
1547    If STRING contains only ASCII characters, do no conversion and
1548    return the string data of STRING.  Otherwise, encode the text by
1549    CODING_SYSTEM, and return a newly allocated memory area which
1550    should be freed by `xfree' by a caller.
1551 
1552    SELECTIONP non-zero means the string is being encoded for an X
1553    selection, so it is safe to run pre-write conversions (which
1554    may run Lisp code).
1555 
1556    Store the byte length of resulting text in *TEXT_BYTES.
1557 
1558    If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1559    which means that the `encoding' of the result can be `STRING'.
1560    Otherwise store 0 in *STRINGP, which means that the `encoding' of
1561    the result should be `COMPOUND_TEXT'.  */
1562 
1563 static unsigned char *
1564 x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep)
1565      Lisp_Object string, coding_system;
1566      int *text_bytes, *stringp;
1567      int selectionp;
1568      int *freep;
1569 {
1570   int result = string_xstring_p (string);
1571   struct coding_system coding;
1572 
1573   if (result == 0)
1574     {
1575       /* No multibyte character in OBJ.  We need not encode it.  */
1576       *text_bytes = SBYTES (string);
1577       *stringp = 1;
1578       *freep = 0;
1579       return SDATA (string);
1580     }
1581 
1582   setup_coding_system (coding_system, &coding);
1583   coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1584   /* We suppress producing escape sequences for composition.  */
1585   coding.common_flags &= ~CODING_ANNOTATION_MASK;
1586   coding.dst_bytes = SCHARS (string) * 2;
1587   coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
1588   encode_coding_object (&coding, string, 0, 0,
1589                         SCHARS (string), SBYTES (string), Qnil);
1590   *text_bytes = coding.produced;
1591   *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1592   *freep = 1;
1593   return coding.destination;
1594 }
1595 
1596 
1597 /* Set the WM name to NAME for frame F. Also set the icon name.
1598    If the frame already has an icon name, use that, otherwise set the
1599    icon name to NAME.  */
1600 
1601 static void
1602 x_set_name_internal (f, name)
1603      FRAME_PTR f;
1604      Lisp_Object name;
1605 {
1606   if (FRAME_X_WINDOW (f))
1607     {
1608       BLOCK_INPUT;
1609       {
1610         XTextProperty text, icon;
1611         int bytes, stringp;
1612         int do_free_icon_value = 0, do_free_text_value = 0;
1613         Lisp_Object coding_system;
1614 #ifdef USE_GTK
1615         Lisp_Object encoded_name;
1616         struct gcpro gcpro1;
1617 
1618         /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1619            we use it before x_encode_text that may return string data.  */
1620         GCPRO1 (name);
1621         encoded_name = ENCODE_UTF_8 (name);
1622         UNGCPRO;
1623 #endif
1624 
1625         coding_system = Qcompound_text;
1626         /* Note: Encoding strategy
1627 
1628            We encode NAME by compound-text and use "COMPOUND-TEXT" in
1629            text.encoding.  But, there are non-internationalized window
1630            managers which don't support that encoding.  So, if NAME
1631            contains only ASCII and 8859-1 characters, encode it by
1632            iso-latin-1, and use "STRING" in text.encoding hoping that
1633            such window managers at least analyze this format correctly,
1634            i.e. treat 8-bit bytes as 8859-1 characters.
1635 
1636            We may also be able to use "UTF8_STRING" in text.encoding
1637            in the future which can encode all Unicode characters.
1638            But, for the moment, there's no way to know that the
1639            current window manager supports it or not.  */
1640         text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1641                                     &do_free_text_value);
1642         text.encoding = (stringp ? XA_STRING
1643                          : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1644         text.format = 8;
1645         text.nitems = bytes;
1646 
1647         if (!STRINGP (f->icon_name))
1648           {
1649             icon = text;
1650           }
1651         else
1652           {
1653             /* See the above comment "Note: Encoding strategy".  */
1654             icon.value = x_encode_text (f->icon_name, coding_system, 0,
1655                                         &bytes, &stringp, &do_free_icon_value);
1656             icon.encoding = (stringp ? XA_STRING
1657                              : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1658             icon.format = 8;
1659             icon.nitems = bytes;
1660           }
1661 
1662 #ifdef USE_GTK
1663         gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1664                               (char *) SDATA (encoded_name));
1665 #else /* not USE_GTK */
1666         XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1667 #endif /* not USE_GTK */
1668 
1669         XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1670 
1671         if (do_free_icon_value)
1672           xfree (icon.value);
1673         if (do_free_text_value)
1674           xfree (text.value);
1675       }
1676       UNBLOCK_INPUT;
1677     }
1678 }
1679 
1680 /* Change the name of frame F to NAME.  If NAME is nil, set F's name to
1681        x_id_name.
1682 
1683    If EXPLICIT is non-zero, that indicates that lisp code is setting the
1684        name; if NAME is a string, set F's name to NAME and set
1685        F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1686 
1687    If EXPLICIT is zero, that indicates that Emacs redisplay code is
1688        suggesting a new name, which lisp code should override; if
1689        F->explicit_name is set, ignore the new name; otherwise, set it.  */
1690 
1691 void
1692 x_set_name (f, name, explicit)
1693      struct frame *f;
1694      Lisp_Object name;
1695      int explicit;
1696 {
1697   /* Make sure that requests from lisp code override requests from
1698      Emacs redisplay code.  */
1699   if (explicit)
1700     {
1701       /* If we're switching from explicit to implicit, we had better
1702          update the mode lines and thereby update the title.  */
1703       if (f->explicit_name && NILP (name))
1704         update_mode_lines = 1;
1705 
1706       f->explicit_name = ! NILP (name);
1707     }
1708   else if (f->explicit_name)
1709     return;
1710 
1711   /* If NAME is nil, set the name to the x_id_name.  */
1712   if (NILP (name))
1713     {
1714       /* Check for no change needed in this very common case
1715          before we do any consing.  */
1716       if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1717                    SDATA (f->name)))
1718         return;
1719       name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1720     }
1721   else
1722     CHECK_STRING (name);
1723 
1724   /* Don't change the name if it's already NAME.  */
1725   if (! NILP (Fstring_equal (name, f->name)))
1726     return;
1727 
1728   f->name = name;
1729 
1730   /* For setting the frame title, the title parameter should override
1731      the name parameter.  */
1732   if (! NILP (f->title))
1733     name = f->title;
1734 
1735   x_set_name_internal (f, name);
1736 }
1737 
1738 /* This function should be called when the user's lisp code has
1739    specified a name for the frame; the name will override any set by the
1740    redisplay code.  */
1741 void
1742 x_explicitly_set_name (f, arg, oldval)
1743      FRAME_PTR f;
1744      Lisp_Object arg, oldval;
1745 {
1746   x_set_name (f, arg, 1);
1747 }
1748 
1749 /* This function should be called by Emacs redisplay code to set the
1750    name; names set this way will never override names set by the user's
1751    lisp code.  */
1752 void
1753 x_implicitly_set_name (f, arg, oldval)
1754      FRAME_PTR f;
1755      Lisp_Object arg, oldval;
1756 {
1757   x_set_name (f, arg, 0);
1758 }
1759 
1760 /* Change the title of frame F to NAME.
1761    If NAME is nil, use the frame name as the title.  */
1762 
1763 void
1764 x_set_title (f, name, old_name)
1765      struct frame *f;
1766      Lisp_Object name, old_name;
1767 {
1768   /* Don't change the title if it's already NAME.  */
1769   if (EQ (name, f->title))
1770     return;
1771 
1772   update_mode_lines = 1;
1773 
1774   f->title = name;
1775 
1776   if (NILP (name))
1777     name = f->name;
1778   else
1779     CHECK_STRING (name);
1780 
1781   x_set_name_internal (f, name);
1782 }
1783 
1784 void
1785 x_set_scroll_bar_default_width (f)
1786      struct frame *f;
1787 {
1788   int wid = FRAME_COLUMN_WIDTH (f);
1789 
1790 #ifdef USE_TOOLKIT_SCROLL_BARS
1791   /* A minimum width of 14 doesn't look good for toolkit scroll bars.  */
1792   int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1793   FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1794   FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1795 #else
1796   /* Make the actual width at least 14 pixels and a multiple of a
1797      character width.  */
1798   FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1799 
1800   /* Use all of that space (aside from required margins) for the
1801      scroll bar.  */
1802   FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1803 #endif
1804 }
1805 
1806 
1807 /* Record in frame F the specified or default value according to ALIST
1808    of the parameter named PROP (a Lisp symbol).  If no value is
1809    specified for PROP, look for an X default for XPROP on the frame
1810    named NAME.  If that is not found either, use the value DEFLT.  */
1811 
1812 static Lisp_Object
1813 x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
1814                                       foreground_p)
1815      struct frame *f;
1816      Lisp_Object alist;
1817      Lisp_Object prop;
1818      char *xprop;
1819      char *xclass;
1820      int foreground_p;
1821 {
1822   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1823   Lisp_Object tem;
1824 
1825   tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1826   if (EQ (tem, Qunbound))
1827     {
1828 #ifdef USE_TOOLKIT_SCROLL_BARS
1829 
1830       /* See if an X resource for the scroll bar color has been
1831          specified.  */
1832       tem = display_x_get_resource (dpyinfo,
1833                                     build_string (foreground_p
1834                                                   ? "foreground"
1835                                                   : "background"),
1836                                     empty_unibyte_string,
1837                                     build_string ("verticalScrollBar"),
1838                                     empty_unibyte_string);
1839       if (!STRINGP (tem))
1840         {
1841           /* If nothing has been specified, scroll bars will use a
1842              toolkit-dependent default.  Because these defaults are
1843              difficult to get at without actually creating a scroll
1844              bar, use nil to indicate that no color has been
1845              specified.  */
1846           tem = Qnil;
1847         }
1848 
1849 #else /* not USE_TOOLKIT_SCROLL_BARS */
1850 
1851       tem = Qnil;
1852 
1853 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1854     }
1855 
1856   x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1857   return tem;
1858 }
1859 
1860 
1861 
1862 
1863 #ifdef USE_X_TOOLKIT
1864 
1865 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1866    WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them.  (They may
1867    already be present because of the toolkit (Motif adds some of them,
1868    for example, but Xt doesn't).  */
1869 
1870 static void
1871 hack_wm_protocols (f, widget)
1872      FRAME_PTR f;
1873      Widget widget;
1874 {
1875   Display *dpy = XtDisplay (widget);
1876   Window w = XtWindow (widget);
1877   int need_delete = 1;
1878   int need_focus = 1;
1879   int need_save = 1;
1880 
1881   BLOCK_INPUT;
1882   {
1883     Atom type;
1884     unsigned char *catoms;
1885     int format = 0;
1886     unsigned long nitems = 0;
1887     unsigned long bytes_after;
1888 
1889     if ((XGetWindowProperty (dpy, w,
1890                              FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1891                              (long)0, (long)100, False, XA_ATOM,
1892                              &type, &format, &nitems, &bytes_after,
1893                              &catoms)
1894          == Success)
1895         && format == 32 && type == XA_ATOM)
1896       {
1897         Atom *atoms = (Atom *) catoms;
1898         while (nitems > 0)
1899           {
1900             nitems--;
1901             if (atoms[nitems]
1902                 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1903               need_delete = 0;
1904             else if (atoms[nitems]
1905                      == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1906               need_focus = 0;
1907             else if (atoms[nitems]
1908                      == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1909               need_save = 0;
1910           }
1911       }
1912     if (catoms)
1913       XFree (catoms);
1914   }
1915   {
1916     Atom props [10];
1917     int count = 0;
1918     if (need_delete)
1919       props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1920     if (need_focus)
1921       props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1922     if (need_save)
1923       props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1924     if (count)
1925       XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1926                        XA_ATOM, 32, PropModeAppend,
1927                        (unsigned char *) props, count);
1928   }
1929   UNBLOCK_INPUT;
1930 }
1931 #endif
1932 
1933 
1934 
1935 /* Support routines for XIC (X Input Context).  */
1936 
1937 #ifdef HAVE_X_I18N
1938 
1939 static XFontSet xic_create_xfontset P_ ((struct frame *));
1940 static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *));
1941 
1942 
1943 /* Supported XIM styles, ordered by preference.  */
1944 
1945 static XIMStyle supported_xim_styles[] =
1946 {
1947   XIMPreeditPosition | XIMStatusArea,
1948   XIMPreeditPosition | XIMStatusNothing,
1949   XIMPreeditPosition | XIMStatusNone,
1950   XIMPreeditNothing | XIMStatusArea,
1951   XIMPreeditNothing | XIMStatusNothing,
1952   XIMPreeditNothing | XIMStatusNone,
1953   XIMPreeditNone | XIMStatusArea,
1954   XIMPreeditNone | XIMStatusNothing,
1955   XIMPreeditNone | XIMStatusNone,
1956   0,
1957 };
1958 
1959 
1960 /* Create an X fontset on frame F with base font name BASE_FONTNAME.  */
1961 
1962 char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1963 
1964 /* Create an Xt fontset spec from the name of a base font.
1965    If `motif' is True use the Motif syntax.  */
1966 char *
1967 xic_create_fontsetname (base_fontname, motif)
1968      char *base_fontname;
1969      Bool motif;
1970 {
1971   const char *sep = motif ? ";" : ",";
1972   char *fontsetname;
1973 
1974   /* Make a fontset name from the base font name.  */
1975   if (xic_defaut_fontset == base_fontname)
1976     { /* There is no base font name, use the default.  */
1977       int len = strlen (base_fontname) + 2;
1978       fontsetname = xmalloc (len);
1979       bzero (fontsetname, len);
1980       strcpy (fontsetname, base_fontname);
1981     }
1982   else
1983     {
1984       /* Make a fontset name from the base font name.
1985          The font set will be made of the following elements:
1986          - the base font.
1987          - the base font where the charset spec is replaced by -*-*.
1988          - the same but with the family also replaced with -*-*-.  */
1989       char *p = base_fontname;
1990       int i;
1991 
1992       for (i = 0; *p; p++)
1993         if (*p == '-') i++;
1994       if (i != 14)
1995         { /* As the font name doesn't conform to XLFD, we can't
1996              modify it to generalize it to allcs and allfamilies.
1997              Use the specified font plus the default.  */
1998           int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3;
1999           fontsetname = xmalloc (len);
2000           bzero (fontsetname, len);
2001           strcpy (fontsetname, base_fontname);
2002           strcat (fontsetname, sep);
2003           strcat (fontsetname, xic_defaut_fontset);
2004         }
2005       else
2006         {
2007           int len;
2008           char *p1 = NULL, *p2 = NULL, *p3 = NULL;
2009           char *font_allcs = NULL;
2010           char *font_allfamilies = NULL;
2011           char *font_all = NULL;
2012           char *allcs = "*-*-*-*-*-*-*";
2013           char *allfamilies = "-*-*-";
2014           char *all = "*-*-*-*-";
2015           char *base;
2016 
2017           for (i = 0, p = base_fontname; i < 8; p++)
2018             {
2019               if (*p == '-')
2020                 {
2021                   i++;
2022                   if (i == 3)
2023                     p1 = p + 1;
2024                   else if (i == 7)
2025                     p2 = p + 1;
2026                   else if (i == 6)
2027                     p3 = p + 1;
2028                 }
2029             }
2030           /* If base_fontname specifies ADSTYLE, make it a
2031              wildcard.  */
2032           if (*p3 != '*')
2033             {
2034               int diff = (p2 - p3) - 2;
2035 
2036               base = alloca (strlen (base_fontname) + 1);
2037               bcopy (base_fontname, base, p3 - base_fontname);
2038               base[p3 - base_fontname] = '*';
2039               base[(p3 - base_fontname) + 1] = '-';
2040               strcpy (base + (p3 - base_fontname) + 2, p2);
2041               p = base + (p - base_fontname) - diff;
2042               p1 = base + (p1 - base_fontname);
2043               p2 = base + (p2 - base_fontname) - diff;
2044               base_fontname = base;
2045             }
2046 
2047           /* Build the font spec that matches all charsets.  */
2048           len = p - base_fontname + strlen (allcs) + 1;
2049           font_allcs = (char *) alloca (len);
2050           bzero (font_allcs, len);
2051           bcopy (base_fontname, font_allcs, p - base_fontname);
2052           strcat (font_allcs, allcs);
2053 
2054           /* Build the font spec that matches all families and
2055              add-styles.  */
2056           len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
2057           font_allfamilies = (char *) alloca (len);
2058           bzero (font_allfamilies, len);
2059           strcpy (font_allfamilies, allfamilies);
2060           bcopy (p1, font_allfamilies + strlen (allfamilies), p - p1);
2061           strcat (font_allfamilies, allcs);
2062 
2063           /* Build the font spec that matches all.  */
2064           len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
2065           font_all = (char *) alloca (len);
2066           bzero (font_all, len);
2067           strcpy (font_all, allfamilies);
2068           strcat (font_all, all);
2069           bcopy (p2, font_all + strlen (all) + strlen (allfamilies), p - p2);
2070           strcat (font_all, allcs);
2071 
2072           /* Build the actual font set name.  */
2073           len = strlen (base_fontname) + strlen (font_allcs)
2074             + strlen (font_allfamilies) + strlen (font_all) + 5;
2075           fontsetname = xmalloc (len);
2076           bzero (fontsetname, len);
2077           strcpy (fontsetname, base_fontname);
2078           strcat (fontsetname, sep);
2079           strcat (fontsetname, font_allcs);
2080           strcat (fontsetname, sep);
2081           strcat (fontsetname, font_allfamilies);
2082           strcat (fontsetname, sep);
2083           strcat (fontsetname, font_all);
2084         }
2085     }
2086   if (motif)
2087     strcat (fontsetname, ":");
2088   return fontsetname;
2089 }
2090 
2091 #ifdef DEBUG_XIC_FONTSET
2092 static void
2093 print_fontset_result (xfs, name, missing_list, missing_count)
2094      XFontSet xfs;
2095      char *name;
2096      char **missing_list;
2097      int missing_count;
2098 {
2099   if (xfs)
2100     fprintf (stderr, "XIC Fontset created: %s\n", name);
2101   else
2102     {
2103       fprintf (stderr, "XIC Fontset failed: %s\n", name);
2104       while (missing_count-- > 0)
2105         {
2106           fprintf (stderr, "  missing: %s\n", *missing_list);
2107           missing_list++;
2108         }
2109     }
2110 
2111 }
2112 #endif
2113 
2114 static XFontSet
2115 xic_create_xfontset (f)
2116      struct frame *f;
2117 {
2118   XFontSet xfs = NULL;
2119   struct font *font = FRAME_FONT (f);
2120   int pixel_size = font->pixel_size;
2121   Lisp_Object rest, frame;
2122 
2123   /* See if there is another frame already using same fontset.  */
2124   FOR_EACH_FRAME (rest, frame)
2125     {
2126       struct frame *cf = XFRAME (frame);
2127 
2128       if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2129           && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2130           && FRAME_FONT (f)
2131           && FRAME_FONT (f)->pixel_size == pixel_size)
2132         {
2133           xfs = FRAME_XIC_FONTSET (cf);
2134           break;
2135         }
2136     }
2137 
2138   if (! xfs)
2139     {
2140       char buf[256];
2141       char **missing_list;
2142       int missing_count;
2143       char *def_string;
2144       char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
2145 
2146       sprintf (buf, xlfd_format, pixel_size);
2147       missing_list = NULL;
2148       xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2149                             &missing_list, &missing_count, &def_string);
2150 #ifdef DEBUG_XIC_FONTSET
2151       print_fontset_result (xfs, buf, missing_list, missing_count);
2152 #endif
2153       if (missing_list)
2154         XFreeStringList (missing_list);
2155       if (! xfs)
2156         {
2157           /* List of pixel sizes most likely available.  Find one that
2158              is closest to pixel_size.  */
2159           int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2160           int *smaller, *larger;
2161 
2162           for (smaller = sizes; smaller[1]; smaller++)
2163             if (smaller[1] >= pixel_size)
2164               break;
2165           larger = smaller + 1;
2166           if (*larger == pixel_size)
2167             larger++;
2168           while (*smaller || *larger)
2169             {
2170               int this_size;
2171 
2172               if (! *larger)
2173                 this_size = *smaller--;
2174               else if (! *smaller)
2175                 this_size = *larger++;
2176               else if (pixel_size - *smaller < *larger - pixel_size)
2177                 this_size = *smaller--;
2178               else
2179                 this_size = *larger++;
2180               sprintf (buf, xlfd_format, this_size);
2181               missing_list = NULL;
2182               xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2183                                     &missing_list, &missing_count, &def_string);
2184 #ifdef DEBUG_XIC_FONTSET
2185               print_fontset_result (xfs, buf, missing_list, missing_count);
2186 #endif
2187               if (missing_list)
2188                 XFreeStringList (missing_list);
2189               if (xfs)
2190                 break;
2191             }
2192         }
2193       if (! xfs)
2194         {
2195           char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
2196 
2197           missing_list = NULL;
2198           xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
2199                                 &missing_list, &missing_count, &def_string);
2200 #ifdef DEBUG_XIC_FONTSET
2201           print_fontset_result (xfs, last_resort, missing_list, missing_count);
2202 #endif
2203           if (missing_list)
2204             XFreeStringList (missing_list);
2205         }
2206 
2207     }
2208 
2209   return xfs;
2210 }
2211 
2212 /* Free the X fontset of frame F if it is the last frame using it.  */
2213 
2214 void
2215 xic_free_xfontset (f)
2216      struct frame *f;
2217 {
2218   Lisp_Object rest, frame;
2219   int shared_p = 0;
2220 
2221   if (!FRAME_XIC_FONTSET (f))
2222     return;
2223 
2224   /* See if there is another frame sharing the same fontset.  */
2225   FOR_EACH_FRAME (rest, frame)
2226     {
2227       struct frame *cf = XFRAME (frame);
2228       if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2229           && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2230           && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
2231         {
2232           shared_p = 1;
2233           break;
2234         }
2235     }
2236 
2237   if (!shared_p)
2238     /* The fontset is not used anymore.  It is safe to free it.  */
2239     XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2240 
2241   if (FRAME_XIC_BASE_FONTNAME (f))
2242     xfree (FRAME_XIC_BASE_FONTNAME (f));
2243   FRAME_XIC_BASE_FONTNAME (f) = NULL;
2244   FRAME_XIC_FONTSET (f) = NULL;
2245 }
2246 
2247 
2248 /* Value is the best input style, given user preferences USER (already
2249    checked to be supported by Emacs), and styles supported by the
2250    input method XIM.  */
2251 
2252 static XIMStyle
2253 best_xim_style (user, xim)
2254      XIMStyles *user;
2255      XIMStyles *xim;
2256 {
2257   int i, j;
2258 
2259   for (i = 0; i < user->count_styles; ++i)
2260     for (j = 0; j < xim->count_styles; ++j)
2261       if (user->supported_styles[i] == xim->supported_styles[j])
2262         return user->supported_styles[i];
2263 
2264   /* Return the default style.  */
2265   return XIMPreeditNothing | XIMStatusNothing;
2266 }
2267 
2268 /* Create XIC for frame F. */
2269 
2270 static XIMStyle xic_style;
2271 
2272 void
2273 create_frame_xic (f)
2274      struct frame *f;
2275 {
2276   XIM xim;
2277   XIC xic = NULL;
2278   XFontSet xfs = NULL;
2279 
2280   if (FRAME_XIC (f))
2281     return;
2282 
2283   /* Create X fontset. */
2284   xfs = xic_create_xfontset (f);
2285   xim = FRAME_X_XIM (f);
2286   if (xim)
2287     {
2288       XRectangle s_area;
2289       XPoint spot;
2290       XVaNestedList preedit_attr;
2291       XVaNestedList status_attr;
2292 
2293       s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2294       spot.x = 0; spot.y = 1;
2295 
2296       /* Determine XIC style.  */
2297       if (xic_style == 0)
2298         {
2299           XIMStyles supported_list;
2300           supported_list.count_styles = (sizeof supported_xim_styles
2301                                          / sizeof supported_xim_styles[0]);
2302           supported_list.supported_styles = supported_xim_styles;
2303           xic_style = best_xim_style (&supported_list,
2304                                       FRAME_X_XIM_STYLES (f));
2305         }
2306 
2307       preedit_attr = XVaCreateNestedList (0,
2308                                           XNFontSet, xfs,
2309                                           XNForeground,
2310                                           FRAME_FOREGROUND_PIXEL (f),
2311                                           XNBackground,
2312                                           FRAME_BACKGROUND_PIXEL (f),
2313                                           (xic_style & XIMPreeditPosition
2314                                            ? XNSpotLocation
2315                                            : NULL),
2316                                           &spot,
2317                                           NULL);
2318       status_attr = XVaCreateNestedList (0,
2319                                          XNArea,
2320                                          &s_area,
2321                                          XNFontSet,
2322                                          xfs,
2323                                          XNForeground,
2324                                          FRAME_FOREGROUND_PIXEL (f),
2325                                          XNBackground,
2326                                          FRAME_BACKGROUND_PIXEL (f),
2327                                          NULL);
2328 
2329       xic = XCreateIC (xim,
2330                        XNInputStyle, xic_style,
2331                        XNClientWindow, FRAME_X_WINDOW (f),
2332                        XNFocusWindow, FRAME_X_WINDOW (f),
2333                        XNStatusAttributes, status_attr,
2334                        XNPreeditAttributes, preedit_attr,
2335                        NULL);
2336       XFree (preedit_attr);
2337       XFree (status_attr);
2338     }
2339 
2340   FRAME_XIC (f) = xic;
2341   FRAME_XIC_STYLE (f) = xic_style;
2342   FRAME_XIC_FONTSET (f) = xfs;
2343 }
2344 
2345 
2346 /* Destroy XIC and free XIC fontset of frame F, if any. */
2347 
2348 void
2349 free_frame_xic (f)
2350      struct frame *f;
2351 {
2352   if (FRAME_XIC (f) == NULL)
2353     return;
2354 
2355   XDestroyIC (FRAME_XIC (f));
2356   xic_free_xfontset (f);
2357 
2358   FRAME_XIC (f) = NULL;
2359 }
2360 
2361 
2362 /* Place preedit area for XIC of window W's frame to specified
2363    pixel position X/Y.  X and Y are relative to window W.  */
2364 
2365 void
2366 xic_set_preeditarea (w, x, y)
2367      struct window *w;
2368      int x, y;
2369 {
2370   struct frame *f = XFRAME (w->frame);
2371   XVaNestedList attr;
2372   XPoint spot;
2373 
2374   spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2375   spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2376   attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2377   XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2378   XFree (attr);
2379 }
2380 
2381 
2382 /* Place status area for XIC in bottom right corner of frame F.. */
2383 
2384 void
2385 xic_set_statusarea (f)
2386      struct frame *f;
2387 {
2388   XIC xic = FRAME_XIC (f);
2389   XVaNestedList attr;
2390   XRectangle area;
2391   XRectangle *needed;
2392 
2393   /* Negotiate geometry of status area.  If input method has existing
2394      status area, use its current size.  */
2395   area.x = area.y = area.width = area.height = 0;
2396   attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2397   XSetICValues (xic, XNStatusAttributes, attr, NULL);
2398   XFree (attr);
2399 
2400   attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2401   XGetICValues (xic, XNStatusAttributes, attr, NULL);
2402   XFree (attr);
2403 
2404   if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2405     {
2406       attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2407       XGetICValues (xic, XNStatusAttributes, attr, NULL);
2408       XFree (attr);
2409     }
2410 
2411   area.width  = needed->width;
2412   area.height = needed->height;
2413   area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2414   area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2415             - FRAME_MENUBAR_HEIGHT (f)
2416             - FRAME_TOOLBAR_HEIGHT (f)
2417             - FRAME_INTERNAL_BORDER_WIDTH (f));
2418   XFree (needed);
2419 
2420   attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2421   XSetICValues (xic, XNStatusAttributes, attr, NULL);
2422   XFree (attr);
2423 }
2424 
2425 
2426 /* Set X fontset for XIC of frame F, using base font name
2427    BASE_FONTNAME.  Called when a new Emacs fontset is chosen.  */
2428 
2429 void
2430 xic_set_xfontset (f, base_fontname)
2431      struct frame *f;
2432      char *base_fontname;
2433 {
2434   XVaNestedList attr;
2435   XFontSet xfs;
2436 
2437   xic_free_xfontset (f);
2438 
2439   xfs = xic_create_xfontset (f);
2440 
2441   attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2442   if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2443     XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2444   if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2445     XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2446   XFree (attr);
2447 
2448   FRAME_XIC_FONTSET (f) = xfs;
2449 }
2450 
2451 #endif /* HAVE_X_I18N */
2452 
2453 
2454 
2455 #ifdef USE_X_TOOLKIT
2456 
2457 /* Create and set up the X widget for frame F.  */
2458 
2459 static void
2460 x_window (f, window_prompting, minibuffer_only)
2461      struct frame *f;
2462      long window_prompting;
2463      int minibuffer_only;
2464 {
2465   XClassHint class_hints;
2466   XSetWindowAttributes attributes;
2467   unsigned long attribute_mask;
2468   Widget shell_widget;
2469   Widget pane_widget;
2470   Widget frame_widget;
2471   Arg al [25];
2472   int ac;
2473 
2474   BLOCK_INPUT;
2475 
2476   /* Use the resource name as the top-level widget name
2477      for looking up resources.  Make a non-Lisp copy
2478      for the window manager, so GC relocation won't bother it.
2479 
2480      Elsewhere we specify the window name for the window manager.  */
2481 
2482   {
2483     char *str = (char *) SDATA (Vx_resource_name);
2484     f->namebuf = (char *) xmalloc (strlen (str) + 1);
2485     strcpy (f->namebuf, str);
2486   }
2487 
2488   ac = 0;
2489   XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2490   XtSetArg (al[ac], XtNinput, 1); ac++;
2491   XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2492   XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2493   XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2494   XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2495   XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2496   shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2497                                    applicationShellWidgetClass,
2498                                    FRAME_X_DISPLAY (f), al, ac);
2499 
2500   f->output_data.x->widget = shell_widget;
2501   /* maybe_set_screen_title_format (shell_widget); */
2502 
2503   pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2504                                   (widget_value *) NULL,
2505                                   shell_widget, False,
2506                                   (lw_callback) NULL,
2507                                   (lw_callback) NULL,
2508                                   (lw_callback) NULL,
2509                                   (lw_callback) NULL);
2510 
2511   ac = 0;
2512   XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2513   XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2514   XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2515   XtSetValues (pane_widget, al, ac);
2516   f->output_data.x->column_widget = pane_widget;
2517 
2518   /* mappedWhenManaged to false tells to the paned window to not map/unmap
2519      the emacs screen when changing menubar.  This reduces flickering.  */
2520 
2521   ac = 0;
2522   XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2523   XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2524   XtSetArg (al[ac], XtNallowResize, 1); ac++;
2525   XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2526   XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2527   XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2528   XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2529   XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2530   frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2531                                  al, ac);
2532 
2533   f->output_data.x->edit_widget = frame_widget;
2534 
2535   XtManageChild (frame_widget);
2536 
2537   /* Do some needed geometry management.  */
2538   {
2539     int len;
2540     char *tem, shell_position[32];
2541     Arg al[10];
2542     int ac = 0;
2543     int extra_borders = 0;
2544     int menubar_size
2545       = (f->output_data.x->menubar_widget
2546          ? (f->output_data.x->menubar_widget->core.height
2547             + f->output_data.x->menubar_widget->core.border_width)
2548          : 0);
2549 
2550 #if 0 /* Experimentally, we now get the right results
2551          for -geometry -0-0 without this.  24 Aug 96, rms.  */
2552     if (FRAME_EXTERNAL_MENU_BAR (f))
2553       {
2554         Dimension ibw = 0;
2555         XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2556         menubar_size += ibw;
2557       }
2558 #endif
2559 
2560     f->output_data.x->menubar_height = menubar_size;
2561 
2562 #ifndef USE_LUCID
2563     /* Motif seems to need this amount added to the sizes
2564        specified for the shell widget.  The Athena/Lucid widgets don't.
2565        Both conclusions reached experimentally.  -- rms.  */
2566     XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2567                    &extra_borders, NULL);
2568     extra_borders *= 2;
2569 #endif
2570 
2571     /* Convert our geometry parameters into a geometry string
2572        and specify it.
2573        Note that we do not specify here whether the position
2574        is a user-specified or program-specified one.
2575        We pass that information later, in x_wm_set_size_hints.  */
2576     {
2577       int left = f->left_pos;
2578       int xneg = window_prompting & XNegative;
2579       int top = f->top_pos;
2580       int yneg = window_prompting & YNegative;
2581       if (xneg)
2582         left = -left;
2583       if (yneg)
2584         top = -top;
2585 
2586       if (window_prompting & USPosition)
2587         sprintf (shell_position, "=%dx%d%c%d%c%d",
2588                  FRAME_PIXEL_WIDTH (f) + extra_borders,
2589                  FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2590                  (xneg ? '-' : '+'), left,
2591                  (yneg ? '-' : '+'), top);
2592       else
2593         {
2594           sprintf (shell_position, "=%dx%d",
2595                    FRAME_PIXEL_WIDTH (f) + extra_borders,
2596                    FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2597 
2598           /* Setting x and y when the position is not specified in
2599              the geometry string will set program position in the WM hints.
2600              If Emacs had just one program position, we could set it in
2601              fallback resources, but since each make-frame call can specify
2602              different program positions, this is easier.  */
2603           XtSetArg (al[ac], XtNx, left); ac++;
2604           XtSetArg (al[ac], XtNy, top); ac++;
2605         }
2606     }
2607 
2608     len = strlen (shell_position) + 1;
2609     /* We don't free this because we don't know whether
2610        it is safe to free it while the frame exists.
2611        It isn't worth the trouble of arranging to free it
2612        when the frame is deleted.  */
2613     tem = (char *) xmalloc (len);
2614     strncpy (tem, shell_position, len);
2615     XtSetArg (al[ac], XtNgeometry, tem); ac++;
2616     XtSetValues (shell_widget, al, ac);
2617   }
2618 
2619   XtManageChild (pane_widget);
2620   XtRealizeWidget (shell_widget);
2621 
2622   if (FRAME_X_EMBEDDED_P (f))
2623     XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2624                      f->output_data.x->parent_desc, 0, 0);
2625 
2626   FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2627 
2628   validate_x_resource_name ();
2629 
2630   class_hints.res_name = (char *) SDATA (Vx_resource_name);
2631   class_hints.res_class = (char *) SDATA (Vx_resource_class);
2632   XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2633 
2634 #ifdef HAVE_X_I18N
2635   FRAME_XIC (f) = NULL;
2636   if (use_xim)
2637     create_frame_xic (f);
2638 #endif
2639 
2640   f->output_data.x->wm_hints.input = True;
2641   f->output_data.x->wm_hints.flags |= InputHint;
2642   XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2643                &f->output_data.x->wm_hints);
2644 
2645   hack_wm_protocols (f, shell_widget);
2646 
2647 #ifdef HACK_EDITRES
2648   XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2649 #endif
2650 
2651   /* Do a stupid property change to force the server to generate a
2652      PropertyNotify event so that the event_stream server timestamp will
2653      be initialized to something relevant to the time we created the window.
2654      */
2655   XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2656                    FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2657                    XA_ATOM, 32, PropModeAppend,
2658                    (unsigned char*) NULL, 0);
2659 
2660   /* Make all the standard events reach the Emacs frame.  */
2661   attributes.event_mask = STANDARD_EVENT_SET;
2662 
2663 #ifdef HAVE_X_I18N
2664   if (FRAME_XIC (f))
2665     {
2666       /* XIM server might require some X events. */
2667       unsigned long fevent = NoEventMask;
2668       XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2669       attributes.event_mask |= fevent;
2670     }
2671 #endif /* HAVE_X_I18N */
2672 
2673   attribute_mask = CWEventMask;
2674   XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2675                            attribute_mask, &attributes);
2676 
2677   XtMapWidget (frame_widget);
2678 
2679   /* x_set_name normally ignores requests to set the name if the
2680      requested name is the same as the current name.  This is the one
2681      place where that assumption isn't correct; f->name is set, but
2682      the X server hasn't been told.  */
2683   {
2684     Lisp_Object name;
2685     int explicit = f->explicit_name;
2686 
2687     f->explicit_name = 0;
2688     name = f->name;
2689     f->name = Qnil;
2690     x_set_name (f, name, explicit);
2691   }
2692 
2693   XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2694                  f->output_data.x->current_cursor
2695                  = f->output_data.x->text_cursor);
2696 
2697   UNBLOCK_INPUT;
2698 
2699   /* This is a no-op, except under Motif.  Make sure main areas are
2700      set to something reasonable, in case we get an error later.  */
2701   lw_set_main_areas (pane_widget, 0, frame_widget);
2702 }
2703 
2704 #else /* not USE_X_TOOLKIT */
2705 #ifdef USE_GTK
2706 void
2707 x_window (f)
2708      FRAME_PTR f;
2709 {
2710   if (! xg_create_frame_widgets (f))
2711     error ("Unable to create window");
2712 
2713 #ifdef HAVE_X_I18N
2714   FRAME_XIC (f) = NULL;
2715   if (use_xim)
2716   {
2717     BLOCK_INPUT;
2718     create_frame_xic (f);
2719     if (FRAME_XIC (f))
2720       {
2721         /* XIM server might require some X events. */
2722         unsigned long fevent = NoEventMask;
2723         XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2724 
2725         if (fevent != NoEventMask)
2726           {
2727             XSetWindowAttributes attributes;
2728             XWindowAttributes wattr;
2729             unsigned long attribute_mask;
2730 
2731             XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2732                                   &wattr);
2733             attributes.event_mask = wattr.your_event_mask | fevent;
2734             attribute_mask = CWEventMask;
2735             XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2736                                      attribute_mask, &attributes);
2737           }
2738       }
2739     UNBLOCK_INPUT;
2740   }
2741 #endif
2742 }
2743 
2744 #else /*! USE_GTK */
2745 /* Create and set up the X window for frame F.  */
2746 
2747 void
2748 x_window (f)
2749      struct frame *f;
2750 
2751 {
2752   XClassHint class_hints;
2753   XSetWindowAttributes attributes;
2754   unsigned long attribute_mask;
2755 
2756   attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2757   attributes.border_pixel = f->output_data.x->border_pixel;
2758   attributes.bit_gravity = StaticGravity;
2759   attributes.backing_store = NotUseful;
2760   attributes.save_under = True;
2761   attributes.event_mask = STANDARD_EVENT_SET;
2762   attributes.colormap = FRAME_X_COLORMAP (f);
2763   attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2764                     | CWColormap);
2765 
2766   BLOCK_INPUT;
2767   FRAME_X_WINDOW (f)
2768     = XCreateWindow (FRAME_X_DISPLAY (f),
2769                      f->output_data.x->parent_desc,
2770                      f->left_pos,
2771                      f->top_pos,
2772                      FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2773                      f->border_width,
2774                      CopyFromParent, /* depth */
2775                      InputOutput, /* class */
2776                      FRAME_X_VISUAL (f),
2777                      attribute_mask, &attributes);
2778 
2779 #ifdef HAVE_X_I18N
2780   if (use_xim)
2781     {
2782       create_frame_xic (f);
2783       if (FRAME_XIC (f))
2784         {
2785           /* XIM server might require some X events. */
2786           unsigned long fevent = NoEventMask;
2787           XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2788           attributes.event_mask |= fevent;
2789           attribute_mask = CWEventMask;
2790           XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2791                                    attribute_mask, &attributes);
2792         }
2793     }
2794 #endif /* HAVE_X_I18N */
2795 
2796   validate_x_resource_name ();
2797 
2798   class_hints.res_name = (char *) SDATA (Vx_resource_name);
2799   class_hints.res_class = (char *) SDATA (Vx_resource_class);
2800   XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2801 
2802   /* The menubar is part of the ordinary display;
2803      it does not count in addition to the height of the window.  */
2804   f->output_data.x->menubar_height = 0;
2805 
2806   /* This indicates that we use the "Passive Input" input model.
2807      Unless we do this, we don't get the Focus{In,Out} events that we
2808      need to draw the cursor correctly.  Accursed bureaucrats.
2809    XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack);  */
2810 
2811   f->output_data.x->wm_hints.input = True;
2812   f->output_data.x->wm_hints.flags |= InputHint;
2813   XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2814                &f->output_data.x->wm_hints);
2815   f->output_data.x->wm_hints.icon_pixmap = None;
2816 
2817   /* Request "save yourself" and "delete window" commands from wm.  */
2818   {
2819     Atom protocols[2];
2820     protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2821     protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2822     XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2823   }
2824 
2825   /* x_set_name normally ignores requests to set the name if the
2826      requested name is the same as the current name.  This is the one
2827      place where that assumption isn't correct; f->name is set, but
2828      the X server hasn't been told.  */
2829   {
2830     Lisp_Object name;
2831     int explicit = f->explicit_name;
2832 
2833     f->explicit_name = 0;
2834     name = f->name;
2835     f->name = Qnil;
2836     x_set_name (f, name, explicit);
2837   }
2838 
2839   XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2840                  f->output_data.x->current_cursor
2841                  = f->output_data.x->text_cursor);
2842 
2843   UNBLOCK_INPUT;
2844 
2845   if (FRAME_X_WINDOW (f) == 0)
2846     error ("Unable to create window");
2847 }
2848 
2849 #endif /* not USE_GTK */
2850 #endif /* not USE_X_TOOLKIT */
2851 
2852 /* Verify that the icon position args for this window are valid.  */
2853 
2854 static void
2855 x_icon_verify (f, parms)
2856      struct frame *f;
2857      Lisp_Object parms;
2858 {
2859   Lisp_Object icon_x, icon_y;
2860 
2861   /* Set the position of the icon.  Note that twm groups all
2862      icons in an icon window.  */
2863   icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2864   icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2865   if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2866     {
2867       CHECK_NUMBER (icon_x);
2868       CHECK_NUMBER (icon_y);
2869     }
2870   else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2871     error ("Both left and top icon corners of icon must be specified");
2872 }
2873 
2874 /* Handle the icon stuff for this window.  Perhaps later we might
2875    want an x_set_icon_position which can be called interactively as
2876    well.  */
2877 
2878 static void
2879 x_icon (f, parms)
2880      struct frame *f;
2881      Lisp_Object parms;
2882 {
2883   Lisp_Object icon_x, icon_y;
2884 #if 0
2885   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2886 #endif
2887 
2888   /* Set the position of the icon.  Note that twm groups all
2889      icons in an icon window.  */
2890   icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2891   icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2892   if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2893     {
2894       CHECK_NUMBER (icon_x);
2895       CHECK_NUMBER (icon_y);
2896     }
2897   else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2898     error ("Both left and top icon corners of icon must be specified");
2899 
2900   BLOCK_INPUT;
2901 
2902   if (! EQ (icon_x, Qunbound))
2903     x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2904 
2905 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2906          but x_create_frame still needs it.  */
2907   /* Start up iconic or window? */
2908   x_wm_set_window_state
2909     (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2910              Qicon)
2911          ? IconicState
2912          : NormalState));
2913 #endif
2914 
2915   x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2916                                      ? f->icon_name
2917                                      : f->name)));
2918 
2919   UNBLOCK_INPUT;
2920 }
2921 
2922 /* Make the GCs needed for this window, setting the
2923    background, border and mouse colors; also create the
2924    mouse cursor and the gray border tile.  */
2925 
2926 static void
2927 x_make_gc (f)
2928      struct frame *f;
2929 {
2930   XGCValues gc_values;
2931 
2932   BLOCK_INPUT;
2933 
2934   /* Create the GCs of this frame.
2935      Note that many default values are used.  */
2936 
2937   gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2938   gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2939   gc_values.line_width = 0;     /* Means 1 using fast algorithm.  */
2940   f->output_data.x->normal_gc
2941     = XCreateGC (FRAME_X_DISPLAY (f),
2942                  FRAME_X_WINDOW (f),
2943                  GCLineWidth | GCForeground | GCBackground,
2944                  &gc_values);
2945 
2946   /* Reverse video style.  */
2947   gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2948   gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2949   f->output_data.x->reverse_gc
2950     = XCreateGC (FRAME_X_DISPLAY (f),
2951                  FRAME_X_WINDOW (f),
2952                  GCForeground | GCBackground | GCLineWidth,
2953                  &gc_values);
2954 
2955   /* Cursor has cursor-color background, background-color foreground.  */
2956   gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2957   gc_values.background = f->output_data.x->cursor_pixel;
2958   gc_values.fill_style = FillOpaqueStippled;
2959   f->output_data.x->cursor_gc
2960     = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2961                  (GCForeground | GCBackground
2962                   | GCFillStyle | GCLineWidth),
2963                  &gc_values);
2964 
2965   /* Reliefs.  */
2966   f->output_data.x->white_relief.gc = 0;
2967   f->output_data.x->black_relief.gc = 0;
2968 
2969   /* Create the gray border tile used when the pointer is not in
2970      the frame.  Since this depends on the frame's pixel values,
2971      this must be done on a per-frame basis.  */
2972   f->output_data.x->border_tile
2973     = (XCreatePixmapFromBitmapData
2974        (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2975         gray_bits, gray_width, gray_height,
2976         FRAME_FOREGROUND_PIXEL (f),
2977         FRAME_BACKGROUND_PIXEL (f),
2978         DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2979 
2980   UNBLOCK_INPUT;
2981 }
2982 
2983 
2984 /* Free what was allocated in x_make_gc.  */
2985 
2986 void
2987 x_free_gcs (f)
2988      struct frame *f;
2989 {
2990   Display *dpy = FRAME_X_DISPLAY (f);
2991 
2992   BLOCK_INPUT;
2993 
2994   if (f->output_data.x->normal_gc)
2995     {
2996       XFreeGC (dpy, f->output_data.x->normal_gc);
2997       f->output_data.x->normal_gc = 0;
2998     }
2999 
3000   if (f->output_data.x->reverse_gc)
3001     {
3002       XFreeGC (dpy, f->output_data.x->reverse_gc);
3003       f->output_data.x->reverse_gc = 0;
3004     }
3005 
3006   if (f->output_data.x->cursor_gc)
3007     {
3008       XFreeGC (dpy, f->output_data.x->cursor_gc);
3009       f->output_data.x->cursor_gc = 0;
3010     }
3011 
3012   if (f->output_data.x->border_tile)
3013     {
3014       XFreePixmap (dpy, f->output_data.x->border_tile);
3015       f->output_data.x->border_tile = 0;
3016     }
3017 
3018   UNBLOCK_INPUT;
3019 }
3020 
3021 
3022 /* Handler for signals raised during x_create_frame and
3023    x_create_top_frame.  FRAME is the frame which is partially
3024    constructed.  */
3025 
3026 static Lisp_Object
3027 unwind_create_frame (frame)
3028      Lisp_Object frame;
3029 {
3030   struct frame *f = XFRAME (frame);
3031 
3032   /* If frame is already dead, nothing to do.  This can happen if the
3033      display is disconnected after the frame has become official, but
3034      before x_create_frame removes the unwind protect.  */
3035   if (!FRAME_LIVE_P (f))
3036     return Qnil;
3037 
3038   /* If frame is ``official'', nothing to do.  */
3039   if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
3040     {
3041 #if GLYPH_DEBUG
3042       struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3043 #endif
3044 
3045       x_free_frame_resources (f);
3046 
3047 #if GLYPH_DEBUG
3048       /* Check that reference counts are indeed correct.  */
3049       xassert (dpyinfo->reference_count == dpyinfo_refcount);
3050       xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
3051 #endif
3052       return Qt;
3053     }
3054 
3055   return Qnil;
3056 }
3057 
3058 
3059 static void
3060 x_default_font_parameter (f, parms)
3061      struct frame *f;
3062      Lisp_Object parms;
3063 {
3064   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3065   Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
3066                                       RES_TYPE_STRING);
3067   Lisp_Object font;
3068   int got_from_gconf = 0;
3069   if (EQ (font_param, Qunbound))
3070     font_param = Qnil;
3071 
3072   if (NILP (font_param))
3073     {
3074       /* System font takes precedendce over X resources.  We must suggest this
3075          regardless of font-use-system-font because .emacs may not have been
3076          read yet.  */
3077       const char *system_font = xsettings_get_system_font ();
3078       if (system_font) font_param = make_string (system_font,
3079                                                  strlen (system_font));
3080     }
3081   
3082   font = !NILP (font_param) ? font_param
3083     : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
3084 
3085   if (! STRINGP (font))
3086     {
3087       char *names[]
3088         = {
3089 #ifdef HAVE_XFT
3090             /* This will find the normal Xft font.  */
3091             "monospace-10",
3092 #endif
3093             "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3094             "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3095             "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3096             /* This was formerly the first thing tried, but it finds
3097                too many fonts and takes too long.  */
3098             "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3099             /* If those didn't work, look for something which will
3100                at least work.  */
3101             "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3102             "fixed",
3103             NULL };
3104       int i;
3105 
3106       for (i = 0; names[i]; i++)
3107         {
3108           font = font_open_by_name (f, names[i]);
3109           if (! NILP (font))
3110             break;
3111         }
3112       if (NILP (font))
3113         error ("No suitable font was found");
3114     }
3115   else if (!NILP (font_param))
3116     {
3117       /* Remember the explicit font parameter, so we can re-apply it after
3118          we've applied the `default' face settings.  */
3119       x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
3120     }
3121 
3122   x_default_parameter (f, parms, Qfont, font,
3123                        got_from_gconf ? NULL : "font",
3124                        got_from_gconf ? NULL : "Font",
3125                        RES_TYPE_STRING);
3126 }
3127 
3128 
3129 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
3130        0, 1, 0,
3131        doc: /* Send the size hints for frame FRAME to the window manager.
3132 If FRAME is nil, use the selected frame.  */)
3133      (frame)
3134      Lisp_Object frame;
3135 {
3136   struct frame *f;
3137   if (NILP (frame))
3138     frame = selected_frame;
3139   f = XFRAME (frame);
3140   BLOCK_INPUT;
3141   if (FRAME_X_P (f))
3142     x_wm_set_size_hint (f, 0, 0);
3143   UNBLOCK_INPUT;
3144   return Qnil;
3145 }
3146 
3147 static void
3148 set_machine_and_pid_properties (struct frame *f)
3149 {
3150   /* See the above comment "Note: Encoding strategy".  */
3151   XTextProperty text;
3152   int bytes, stringp;
3153   int do_free_text_value = 0;
3154   long pid = (long) getpid ();
3155 
3156   text.value = x_encode_text (Vsystem_name,
3157                               Qcompound_text, 0, &bytes, &stringp,
3158                               &do_free_text_value);
3159   text.encoding = (stringp ? XA_STRING
3160                    : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
3161   text.format = 8;
3162   text.nitems = bytes;
3163   XSetWMClientMachine (FRAME_X_DISPLAY (f),
3164                        FRAME_OUTER_WINDOW (f),
3165                        &text);
3166   if (do_free_text_value)
3167     xfree (text.value);
3168 
3169   XChangeProperty (FRAME_X_DISPLAY (f),
3170                    FRAME_OUTER_WINDOW (f),
3171                    XInternAtom (FRAME_X_DISPLAY (f),
3172                                 "_NET_WM_PID",
3173                                 False),
3174                    XA_CARDINAL, 32, PropModeReplace,
3175                    (unsigned char *) &pid, 1);
3176 }
3177 
3178 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3179        1, 1, 0,
3180        doc: /* Make a new X window, which is called a "frame" in Emacs terms.
3181 Return an Emacs frame object.
3182 PARMS is an alist of frame parameters.
3183 If the parameters specify that the frame should not have a minibuffer,
3184 and do not specify a specific minibuffer window to use,
3185 then `default-minibuffer-frame' must be a frame whose minibuffer can
3186 be shared by the new frame.
3187 
3188 This function is an internal primitive--use `make-frame' instead.  */)
3189      (parms)
3190      Lisp_Object parms;
3191 {
3192   struct frame *f;
3193   Lisp_Object frame, tem;
3194   Lisp_Object name;
3195   int minibuffer_only = 0;
3196   long window_prompting = 0;
3197   int width, height;
3198   int count = SPECPDL_INDEX ();
3199   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3200   Lisp_Object display;
3201   struct x_display_info *dpyinfo = NULL;
3202   Lisp_Object parent;
3203   struct kboard *kb;
3204 
3205   parms = Fcopy_alist (parms);
3206 
3207   /* Use this general default value to start with
3208      until we know if this frame has a specified name.  */
3209   Vx_resource_name = Vinvocation_name;
3210 
3211   display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
3212   if (EQ (display, Qunbound))
3213     display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
3214   if (EQ (display, Qunbound))
3215     display = Qnil;
3216   dpyinfo = check_x_display_info (display);
3217   kb = dpyinfo->terminal->kboard;
3218 
3219   if (!dpyinfo->terminal->name)
3220     error ("Terminal is not live, can't create new frames on it");
3221 
3222   name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
3223   if (!STRINGP (name)
3224       && ! EQ (name, Qunbound)
3225       && ! NILP (name))
3226     error ("Invalid frame name--not a string or nil");
3227 
3228   if (STRINGP (name))
3229     Vx_resource_name = name;
3230 
3231   /* See if parent window is specified.  */
3232   parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
3233   if (EQ (parent, Qunbound))
3234     parent = Qnil;
3235   if (! NILP (parent))
3236     CHECK_NUMBER (parent);
3237 
3238   /* make_frame_without_minibuffer can run Lisp code and garbage collect.  */
3239   /* No need to protect DISPLAY because that's not used after passing
3240      it to make_frame_without_minibuffer.  */
3241   frame = Qnil;
3242   GCPRO4 (parms, parent, name, frame);
3243   tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
3244                    RES_TYPE_SYMBOL);
3245   if (EQ (tem, Qnone) || NILP (tem))
3246     f = make_frame_without_minibuffer (Qnil, kb, display);
3247   else if (EQ (tem, Qonly))
3248     {
3249       f = make_minibuffer_frame ();
3250       minibuffer_only = 1;
3251     }
3252   else if (WINDOWP (tem))
3253     f = make_frame_without_minibuffer (tem, kb, display);
3254   else
3255     f = make_frame (1);
3256 
3257   XSETFRAME (frame, f);
3258 
3259   /* Note that X Windows does support scroll bars.  */
3260   FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3261 
3262   f->terminal = dpyinfo->terminal;
3263   f->terminal->reference_count++;
3264 
3265   f->output_method = output_x_window;
3266   f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
3267   bzero (f->output_data.x, sizeof (struct x_output));
3268   f->output_data.x->icon_bitmap = -1;
3269   FRAME_FONTSET (f) = -1;
3270   f->output_data.x->scroll_bar_foreground_pixel = -1;
3271   f->output_data.x->scroll_bar_background_pixel = -1;
3272 #ifdef USE_TOOLKIT_SCROLL_BARS
3273   f->output_data.x->scroll_bar_top_shadow_pixel = -1;
3274   f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
3275 #endif /* USE_TOOLKIT_SCROLL_BARS */
3276 
3277   f->icon_name
3278     = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3279                  RES_TYPE_STRING);
3280   if (! STRINGP (f->icon_name))
3281     f->icon_name = Qnil;
3282 
3283   FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3284 
3285   /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe.  */
3286   record_unwind_protect (unwind_create_frame, frame);
3287 #if GLYPH_DEBUG
3288   image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
3289   dpyinfo_refcount = dpyinfo->reference_count;
3290 #endif /* GLYPH_DEBUG */
3291 
3292   /* These colors will be set anyway later, but it's important
3293      to get the color reference counts right, so initialize them!  */
3294   {
3295     Lisp_Object black;
3296     struct gcpro gcpro1;
3297 
3298     /* Function x_decode_color can signal an error.  Make
3299        sure to initialize color slots so that we won't try
3300        to free colors we haven't allocated.  */
3301     FRAME_FOREGROUND_PIXEL (f) = -1;
3302     FRAME_BACKGROUND_PIXEL (f) = -1;
3303     f->output_data.x->cursor_pixel = -1;
3304     f->output_data.x->cursor_foreground_pixel = -1;
3305     f->output_data.x->border_pixel = -1;
3306     f->output_data.x->mouse_pixel = -1;
3307 
3308     black = build_string ("black");
3309     GCPRO1 (black);
3310     FRAME_FOREGROUND_PIXEL (f)
3311       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3312     FRAME_BACKGROUND_PIXEL (f)
3313       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3314     f->output_data.x->cursor_pixel
3315       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3316     f->output_data.x->cursor_foreground_pixel
3317       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3318     f->output_data.x->border_pixel
3319       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3320     f->output_data.x->mouse_pixel
3321       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3322     UNGCPRO;
3323   }
3324 
3325   /* Specify the parent under which to make this X window.  */
3326 
3327   if (!NILP (parent))
3328     {
3329       f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3330       f->output_data.x->explicit_parent = 1;
3331     }
3332   else
3333     {
3334       f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3335       f->output_data.x->explicit_parent = 0;
3336     }
3337 
3338   /* Set the name; the functions to which we pass f expect the name to
3339      be set.  */
3340   if (EQ (name, Qunbound) || NILP (name))
3341     {
3342       f->name = build_string (dpyinfo->x_id_name);
3343       f->explicit_name = 0;
3344     }
3345   else
3346     {
3347       f->name = name;
3348       f->explicit_name = 1;
3349       /* use the frame's title when getting resources for this frame.  */
3350       specbind (Qx_resource_name, name);
3351     }
3352 
3353   f->resx = dpyinfo->resx;
3354   f->resy = dpyinfo->resy;
3355 
3356 #ifdef HAVE_FREETYPE
3357 #ifdef HAVE_XFT
3358   register_font_driver (&xftfont_driver, f);
3359 #else   /* not HAVE_XFT */
3360   register_font_driver (&ftxfont_driver, f);
3361 #endif  /* not HAVE_XFT */
3362 #endif  /* HAVE_FREETYPE */
3363   register_font_driver (&xfont_driver, f);
3364 
3365   x_default_parameter (f, parms, Qfont_backend, Qnil,
3366                        "fontBackend", "FontBackend", RES_TYPE_STRING);
3367 
3368   /* Extract the window parameters from the supplied values
3369      that are needed to determine window geometry.  */
3370   x_default_font_parameter (f, parms);
3371   if (!FRAME_FONT (f))
3372     {
3373       delete_frame (frame, Qnoelisp);
3374       error ("Invalid frame font");
3375     }
3376 
3377   /* Frame contents get displaced if an embedded X window has a border.  */
3378   if (! FRAME_X_EMBEDDED_P (f))
3379     x_default_parameter (f, parms, Qborder_width, make_number (0),
3380                          "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3381 
3382   /* This defaults to 1 in order to match xterm.  We recognize either
3383      internalBorderWidth or internalBorder (which is what xterm calls
3384      it).  */
3385   if (NILP (Fassq (Qinternal_border_width, parms)))
3386     {
3387       Lisp_Object value;
3388 
3389       value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3390                          "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3391       if (! EQ (value, Qunbound))
3392         parms = Fcons (Fcons (Qinternal_border_width, value),
3393                        parms);
3394     }
3395   x_default_parameter (f, parms, Qinternal_border_width,
3396 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets.  */
3397                        make_number (0),
3398 #else
3399                        make_number (1),
3400 #endif
3401                        "internalBorderWidth", "internalBorderWidth",
3402                        RES_TYPE_NUMBER);
3403   x_default_parameter (f, parms, Qvertical_scroll_bars,
3404 #if defined(USE_GTK) && defined(USE_TOOLKIT_SCROLL_BARS)
3405                        Qright,
3406 #else
3407                        Qleft,
3408 #endif
3409                        "verticalScrollBars", "ScrollBars",
3410                        RES_TYPE_SYMBOL);
3411 
3412   /* Also do the stuff which must be set before the window exists.  */
3413   x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3414                        "foreground", "Foreground", RES_TYPE_STRING);
3415   x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3416                        "background", "Background", RES_TYPE_STRING);
3417   x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3418                        "pointerColor", "Foreground", RES_TYPE_STRING);
3419   x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3420                        "cursorColor", "Foreground", RES_TYPE_STRING);
3421   x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3422                        "borderColor", "BorderColor", RES_TYPE_STRING);
3423   x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3424                        "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3425   x_default_parameter (f, parms, Qline_spacing, Qnil,
3426                        "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3427   x_default_parameter (f, parms, Qleft_fringe, Qnil,
3428                        "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3429   x_default_parameter (f, parms, Qright_fringe, Qnil,
3430                        "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3431 
3432   x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3433                                         "scrollBarForeground",
3434                                         "ScrollBarForeground", 1);
3435   x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3436                                         "scrollBarBackground",
3437                                         "ScrollBarBackground", 0);
3438 
3439   /* Init faces before x_default_parameter is called for scroll-bar
3440      parameters because that function calls x_set_scroll_bar_width,
3441      which calls change_frame_size, which calls Fset_window_buffer,
3442      which runs hooks, which call Fvertical_motion.  At the end, we
3443      end up in init_iterator with a null face cache, which should not
3444      happen.  */
3445   init_frame_faces (f);
3446 
3447   x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
3448                        "menuBar", "MenuBar", RES_TYPE_BOOLEAN_NUMBER);
3449   x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
3450                        "toolBar", "ToolBar", RES_TYPE_NUMBER);
3451   x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3452                        "bufferPredicate", "BufferPredicate",
3453                        RES_TYPE_SYMBOL);
3454   x_default_parameter (f, parms, Qtitle, Qnil,
3455                        "title", "Title", RES_TYPE_STRING);
3456   x_default_parameter (f, parms, Qwait_for_wm, Qt,
3457                        "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3458   x_default_parameter (f, parms, Qfullscreen, Qnil,
3459                        "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3460 
3461   /* Compute the size of the X window.  */
3462   window_prompting = x_figure_window_size (f, parms, 1);
3463 
3464   tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3465   f->no_split = minibuffer_only || EQ (tem, Qt);
3466 
3467   x_icon_verify (f, parms);
3468 
3469   /* Create the X widget or window.  */
3470 #ifdef USE_X_TOOLKIT
3471   x_window (f, window_prompting, minibuffer_only);
3472 #else
3473   x_window (f);
3474 #endif
3475 
3476   x_icon (f, parms);
3477   x_make_gc (f);
3478 
3479   /* Now consider the frame official.  */
3480   FRAME_X_DISPLAY_INFO (f)->reference_count++;
3481   Vframe_list = Fcons (frame, Vframe_list);
3482 
3483   /* We need to do this after creating the X window, so that the
3484      icon-creation functions can say whose icon they're describing.  */
3485   x_default_parameter (f, parms, Qicon_type, Qt,
3486                        "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
3487 
3488   x_default_parameter (f, parms, Qauto_raise, Qnil,
3489                        "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3490   x_default_parameter (f, parms, Qauto_lower, Qnil,
3491                        "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3492   x_default_parameter (f, parms, Qcursor_type, Qbox,
3493                        "cursorType", "CursorType", RES_TYPE_SYMBOL);
3494   x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3495                        "scrollBarWidth", "ScrollBarWidth",
3496                        RES_TYPE_NUMBER);
3497   x_default_parameter (f, parms, Qalpha, Qnil,
3498                        "alpha", "Alpha", RES_TYPE_NUMBER);
3499 
3500   /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3501      Change will not be effected unless different from the current
3502      FRAME_LINES (f).  */
3503   width = FRAME_COLS (f);
3504   height = FRAME_LINES (f);
3505 
3506   SET_FRAME_COLS (f, 0);
3507   FRAME_LINES (f) = 0;
3508   change_frame_size (f, height, width, 1, 0, 0);
3509 
3510 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3511   /* Create the menu bar.  */
3512   if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3513     {
3514       /* If this signals an error, we haven't set size hints for the
3515          frame and we didn't make it visible.  */
3516       initialize_frame_menubar (f);
3517 
3518 #ifndef USE_GTK
3519       /* This is a no-op, except under Motif where it arranges the
3520          main window for the widgets on it.  */
3521       lw_set_main_areas (f->output_data.x->column_widget,
3522                          f->output_data.x->menubar_widget,
3523                          f->output_data.x->edit_widget);
3524 #endif /* not USE_GTK */
3525     }
3526 #endif /* USE_X_TOOLKIT || USE_GTK */
3527 
3528   /* Tell the server what size and position, etc, we want, and how
3529      badly we want them.  This should be done after we have the menu
3530      bar so that its size can be taken into account.  */
3531   BLOCK_INPUT;
3532   x_wm_set_size_hint (f, window_prompting, 0);
3533   UNBLOCK_INPUT;
3534 
3535   /* Make the window appear on the frame and enable display, unless
3536      the caller says not to.  However, with explicit parent, Emacs
3537      cannot control visibility, so don't try.  */
3538   if (! f->output_data.x->explicit_parent)
3539     {
3540       Lisp_Object visibility;
3541 
3542       visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3543                               RES_TYPE_SYMBOL);
3544       if (EQ (visibility, Qunbound))
3545         visibility = Qt;
3546 
3547       if (EQ (visibility, Qicon))
3548         x_iconify_frame (f);
3549       else if (! NILP (visibility))
3550         x_make_frame_visible (f);
3551       else
3552         /* Must have been Qnil.  */
3553         ;
3554     }
3555 
3556   BLOCK_INPUT;
3557                        
3558   /* Set machine name and pid for the purpose of window managers.  */
3559   set_machine_and_pid_properties(f);
3560 
3561   /* Set the WM leader property.  GTK does this itself, so this is not
3562      needed when using GTK.  */
3563   if (dpyinfo->client_leader_window != 0)
3564     {
3565       XChangeProperty (FRAME_X_DISPLAY (f),
3566                        FRAME_OUTER_WINDOW (f),
3567                        dpyinfo->Xatom_wm_client_leader,
3568                        XA_WINDOW, 32, PropModeReplace,
3569                        (unsigned char *) &dpyinfo->client_leader_window, 1);
3570     }
3571 
3572   UNBLOCK_INPUT;
3573 
3574   /* Initialize `default-minibuffer-frame' in case this is the first
3575      frame on this terminal.  */
3576   if (FRAME_HAS_MINIBUF_P (f)
3577       && (!FRAMEP (kb->Vdefault_minibuffer_frame)
3578           || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
3579     kb->Vdefault_minibuffer_frame = frame;
3580 
3581   /* All remaining specified parameters, which have not been "used"
3582      by x_get_arg and friends, now go in the misc. alist of the frame.  */
3583   for (tem = parms; CONSP (tem); tem = XCDR (tem))
3584     if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3585       f->param_alist = Fcons (XCAR (tem), f->param_alist);
3586 
3587   UNGCPRO;
3588 
3589   /* Make sure windows on this frame appear in calls to next-window
3590      and similar functions.  */
3591   Vwindow_list = Qnil;
3592 
3593   return unbind_to (count, frame);
3594 }
3595 
3596 
3597 /* FRAME is used only to get a handle on the X display.  We don't pass the
3598    display info directly because we're called from frame.c, which doesn't
3599    know about that structure.  */
3600 
3601 Lisp_Object
3602 x_get_focus_frame (frame)
3603      struct frame *frame;
3604 {
3605   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3606   Lisp_Object xfocus;
3607   if (! dpyinfo->x_focus_frame)
3608     return Qnil;
3609 
3610   XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3611   return xfocus;
3612 }
3613 
3614 
3615 /* In certain situations, when the window manager follows a
3616    click-to-focus policy, there seems to be no way around calling
3617    XSetInputFocus to give another frame the input focus .
3618 
3619    In an ideal world, XSetInputFocus should generally be avoided so
3620    that applications don't interfere with the window manager's focus
3621    policy.  But I think it's okay to use when it's clearly done
3622    following a user-command.  */
3623 
3624 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3625        doc: /* Set the input focus to FRAME.
3626 FRAME nil means use the selected frame.  */)
3627      (frame)
3628      Lisp_Object frame;
3629 {
3630   struct frame *f = check_x_frame (frame);
3631   Display *dpy = FRAME_X_DISPLAY (f);
3632 
3633   BLOCK_INPUT;
3634   x_catch_errors (dpy);
3635   XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3636                   RevertToParent, CurrentTime);
3637   x_ewmh_activate_frame (f);
3638   x_uncatch_errors ();
3639   UNBLOCK_INPUT;
3640 
3641   return Qnil;
3642 }
3643 
3644 
3645 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3646        doc: /* Internal function called by `color-defined-p', which see.  */)
3647      (color, frame)
3648      Lisp_Object color, frame;
3649 {
3650   XColor foo;
3651   FRAME_PTR f = check_x_frame (frame);
3652 
3653   CHECK_STRING (color);
3654 
3655   if (x_defined_color (f, SDATA (color), &foo, 0))
3656     return Qt;
3657   else
3658     return Qnil;
3659 }
3660 
3661 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3662        doc: /* Internal function called by `color-values', which see.  */)
3663      (color, frame)
3664      Lisp_Object color, frame;
3665 {
3666   XColor foo;
3667   FRAME_PTR f = check_x_frame (frame);
3668 
3669   CHECK_STRING (color);
3670 
3671   if (x_defined_color (f, SDATA (color), &foo, 0))
3672     return list3 (make_number (foo.red),
3673                   make_number (foo.green),
3674                   make_number (foo.blue));
3675   else
3676     return Qnil;
3677 }
3678 
3679 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3680        doc: /* Internal function called by `display-color-p', which see.  */)
3681      (terminal)
3682      Lisp_Object terminal;
3683 {
3684   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3685 
3686   if (dpyinfo->n_planes <= 2)
3687     return Qnil;
3688 
3689   switch (dpyinfo->visual->class)
3690     {
3691     case StaticColor:
3692     case PseudoColor:
3693     case TrueColor:
3694     case DirectColor:
3695       return Qt;
3696 
3697     default:
3698       return Qnil;
3699     }
3700 }
3701 
3702 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3703        0, 1, 0,
3704        doc: /* Return t if the X display supports shades of gray.
3705 Note that color displays do support shades of gray.
3706 The optional argument TERMINAL specifies which display to ask about.
3707 TERMINAL should be a terminal object, a frame or a display name (a string).
3708 If omitted or nil, that stands for the selected frame's display.  */)
3709      (terminal)
3710      Lisp_Object terminal;
3711 {
3712   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3713 
3714   if (dpyinfo->n_planes <= 1)
3715     return Qnil;
3716 
3717   switch (dpyinfo->visual->class)
3718     {
3719     case StaticColor:
3720     case PseudoColor:
3721     case TrueColor:
3722     case DirectColor:
3723     case StaticGray:
3724     case GrayScale:
3725       return Qt;
3726 
3727     default:
3728       return Qnil;
3729     }
3730 }
3731 
3732 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3733        0, 1, 0,
3734        doc: /* Return the width in pixels of the X display TERMINAL.
3735 The optional argument TERMINAL specifies which display to ask about.
3736 TERMINAL should be a terminal object, a frame or a display name (a string).
3737 If omitted or nil, that stands for the selected frame's display.  */)
3738      (terminal)
3739      Lisp_Object terminal;
3740 {
3741   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3742 
3743   return make_number (x_display_pixel_width (dpyinfo));
3744 }
3745 
3746 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3747        Sx_display_pixel_height, 0, 1, 0,
3748        doc: /* Return the height in pixels of the X display TERMINAL.
3749 The optional argument TERMINAL specifies which display to ask about.
3750 TERMINAL should be a terminal object, a frame or a display name (a string).
3751 If omitted or nil, that stands for the selected frame's display.  */)
3752      (terminal)
3753      Lisp_Object terminal;
3754 {
3755   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3756 
3757   return make_number (x_display_pixel_height (dpyinfo));
3758 }
3759 
3760 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3761        0, 1, 0,
3762        doc: /* Return the number of bitplanes of the X display TERMINAL.
3763 The optional argument TERMINAL specifies which display to ask about.
3764 TERMINAL should be a terminal object, a frame or a display name (a string).
3765 If omitted or nil, that stands for the selected frame's display.  */)
3766      (terminal)
3767      Lisp_Object terminal;
3768 {
3769   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3770 
3771   return make_number (dpyinfo->n_planes);
3772 }
3773 
3774 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3775        0, 1, 0,
3776        doc: /* Return the number of color cells of the X display TERMINAL.
3777 The optional argument TERMINAL specifies which display to ask about.
3778 TERMINAL should be a terminal object, a frame or a display name (a string).
3779 If omitted or nil, that stands for the selected frame's display.  */)
3780      (terminal)
3781      Lisp_Object terminal;
3782 {
3783   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3784 
3785   int nr_planes = DisplayPlanes (dpyinfo->display,
3786                                  XScreenNumberOfScreen (dpyinfo->screen));
3787 
3788   /* Truncate nr_planes to 24 to avoid integer overflow.
3789      Some displays says 32, but only 24 bits are actually significant.
3790      There are only very few and rare video cards that have more than
3791      24 significant bits.  Also 24 bits is more than 16 million colors,
3792      it "should be enough for everyone".  */
3793   if (nr_planes > 24) nr_planes = 24;
3794 
3795   return make_number (1 << nr_planes);
3796 }
3797 
3798 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3799        Sx_server_max_request_size,
3800        0, 1, 0,
3801        doc: /* Return the maximum request size of the X server of display TERMINAL.
3802 The optional argument TERMINAL specifies which display to ask about.
3803 TERMINAL should be a terminal object, a frame or a display name (a string).
3804 If omitted or nil, that stands for the selected frame's display.  */)
3805      (terminal)
3806      Lisp_Object terminal;
3807 {
3808   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3809 
3810   return make_number (MAXREQUEST (dpyinfo->display));
3811 }
3812 
3813 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3814        doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3815 \(Labelling every distributor as a "vendor" embodies the false assumption
3816 that operating systems cannot be developed and distributed noncommercially.)
3817 The optional argument TERMINAL specifies which display to ask about.
3818 TERMINAL should be a terminal object, a frame or a display name (a string).
3819 If omitted or nil, that stands for the selected frame's display.  */)
3820      (terminal)
3821      Lisp_Object terminal;
3822 {
3823   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3824   char *vendor = ServerVendor (dpyinfo->display);
3825 
3826   if (! vendor) vendor = "";
3827   return build_string (vendor);
3828 }
3829 
3830 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3831        doc: /* Return the version numbers of the X server of display TERMINAL.
3832 The value is a list of three integers: the major and minor
3833 version numbers of the X Protocol in use, and the distributor-specific release
3834 number.  See also the function `x-server-vendor'.
3835 
3836 The optional argument TERMINAL specifies which display to ask about.
3837 TERMINAL should be a terminal object, a frame or a display name (a string).
3838 If omitted or nil, that stands for the selected frame's display.  */)
3839      (terminal)
3840      Lisp_Object terminal;
3841 {
3842   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3843   Display *dpy = dpyinfo->display;
3844 
3845   return Fcons (make_number (ProtocolVersion (dpy)),
3846                 Fcons (make_number (ProtocolRevision (dpy)),
3847                        Fcons (make_number (VendorRelease (dpy)), Qnil)));
3848 }
3849 
3850 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3851        doc: /* Return the number of screens on the X server of display TERMINAL.
3852 The optional argument TERMINAL specifies which display to ask about.
3853 TERMINAL should be a terminal object, a frame or a display name (a string).
3854 If omitted or nil, that stands for the selected frame's display.  */)
3855      (terminal)
3856      Lisp_Object terminal;
3857 {
3858   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3859 
3860   return make_number (ScreenCount (dpyinfo->display));
3861 }
3862 
3863 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3864        doc: /* Return the height in millimeters of the X display TERMINAL.
3865 The optional argument TERMINAL specifies which display to ask about.
3866 TERMINAL should be a terminal object, a frame or a display name (a string).
3867 If omitted or nil, that stands for the selected frame's display.  */)
3868      (terminal)
3869      Lisp_Object terminal;
3870 {
3871   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3872 
3873   return make_number (HeightMMOfScreen (dpyinfo->screen));
3874 }
3875 
3876 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3877        doc: /* Return the width in millimeters of the X display TERMINAL.
3878 The optional argument TERMINAL specifies which display to ask about.
3879 TERMINAL should be a terminal object, a frame or a display name (a string).
3880 If omitted or nil, that stands for the selected frame's display.  */)
3881      (terminal)
3882      Lisp_Object terminal;
3883 {
3884   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3885 
3886   return make_number (WidthMMOfScreen (dpyinfo->screen));
3887 }
3888 
3889 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3890        Sx_display_backing_store, 0, 1, 0,
3891        doc: /* Return an indication of whether X display TERMINAL does backing store.
3892 The value may be `always', `when-mapped', or `not-useful'.
3893 The optional argument TERMINAL specifies which display to ask about.
3894 TERMINAL should be a terminal object, a frame or a display name (a string).
3895 If omitted or nil, that stands for the selected frame's display.  */)
3896      (terminal)
3897      Lisp_Object terminal;
3898 {
3899   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3900   Lisp_Object result;
3901 
3902   switch (DoesBackingStore (dpyinfo->screen))
3903     {
3904     case Always:
3905       result = intern ("always");
3906       break;
3907 
3908     case WhenMapped:
3909       result = intern ("when-mapped");
3910       break;
3911 
3912     case NotUseful:
3913       result = intern ("not-useful");
3914       break;
3915 
3916     default:
3917       error ("Strange value for BackingStore parameter of screen");
3918       result = Qnil;
3919     }
3920 
3921   return result;
3922 }
3923 
3924 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3925        Sx_display_visual_class, 0, 1, 0,
3926        doc: /* Return the visual class of the X display TERMINAL.
3927 The value is one of the symbols `static-gray', `gray-scale',
3928 `static-color', `pseudo-color', `true-color', or `direct-color'.
3929 
3930 The optional argument TERMINAL specifies which display to ask about.
3931 TERMINAL should a terminal object, a frame or a display name (a string).
3932 If omitted or nil, that stands for the selected frame's display.  */)
3933      (terminal)
3934      Lisp_Object terminal;
3935 {
3936   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3937   Lisp_Object result;
3938 
3939   switch (dpyinfo->visual->class)
3940     {
3941     case StaticGray:
3942       result = intern ("static-gray");
3943       break;
3944     case GrayScale:
3945       result = intern ("gray-scale");
3946       break;
3947     case StaticColor:
3948       result = intern ("static-color");
3949       break;
3950     case PseudoColor:
3951       result = intern ("pseudo-color");
3952       break;
3953     case TrueColor:
3954       result = intern ("true-color");
3955       break;
3956     case DirectColor:
3957       result = intern ("direct-color");
3958       break;
3959     default:
3960       error ("Display has an unknown visual class");
3961       result = Qnil;
3962     }
3963 
3964   return result;
3965 }
3966 
3967 DEFUN ("x-display-save-under", Fx_display_save_under,
3968        Sx_display_save_under, 0, 1, 0,
3969        doc: /* Return t if the X display TERMINAL supports the save-under feature.
3970 The optional argument TERMINAL specifies which display to ask about.
3971 TERMINAL should be a terminal object, a frame or a display name (a string).
3972 If omitted or nil, that stands for the selected frame's display.  */)
3973      (terminal)
3974      Lisp_Object terminal;
3975 {
3976   struct x_display_info *dpyinfo = check_x_display_info (terminal);
3977 
3978   if (DoesSaveUnders (dpyinfo->screen) == True)
3979     return Qt;
3980   else
3981     return Qnil;
3982 }
3983 
3984 int
3985 x_pixel_width (f)
3986      register struct frame *f;
3987 {
3988   return FRAME_PIXEL_WIDTH (f);
3989 }
3990 
3991 int
3992 x_pixel_height (f)
3993      register struct frame *f;
3994 {
3995   return FRAME_PIXEL_HEIGHT (f);
3996 }
3997 
3998 int
3999 x_char_width (f)
4000      register struct frame *f;
4001 {
4002   return FRAME_COLUMN_WIDTH (f);
4003 }
4004 
4005 int
4006 x_char_height (f)
4007      register struct frame *f;
4008 {
4009   return FRAME_LINE_HEIGHT (f);
4010 }
4011 
4012 int
4013 x_screen_planes (f)
4014      register struct frame *f;
4015 {
4016   return FRAME_X_DISPLAY_INFO (f)->n_planes;
4017 }
4018 
4019 
4020 
4021 /************************************************************************
4022                               X Displays
4023  ************************************************************************/
4024 
4025 
4026 /* Mapping visual names to visuals.  */
4027 
4028 static struct visual_class
4029 {
4030   char *name;
4031   int class;
4032 }
4033 visual_classes[] =
4034 {
4035   {"StaticGray",        StaticGray},
4036   {"GrayScale",         GrayScale},
4037   {"StaticColor",       StaticColor},
4038   {"PseudoColor",       PseudoColor},
4039   {"TrueColor",         TrueColor},
4040   {"DirectColor",       DirectColor},
4041   {NULL, 0}
4042 };
4043 
4044 
4045 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4046 
4047 /* Value is the screen number of screen SCR.  This is a substitute for
4048    the X function with the same name when that doesn't exist.  */
4049 
4050 int
4051 XScreenNumberOfScreen (scr)
4052     register Screen *scr;
4053 {
4054   Display *dpy = scr->display;
4055   int i;
4056 
4057   for (i = 0; i < dpy->nscreens; ++i)
4058     if (scr == dpy->screens + i)
4059       break;
4060 
4061   return i;
4062 }
4063 
4064 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4065 
4066 
4067 /* Select the visual that should be used on display DPYINFO.  Set
4068    members of DPYINFO appropriately.  Called from x_term_init.  */
4069 
4070 void
4071 select_visual (dpyinfo)
4072      struct x_display_info *dpyinfo;
4073 {
4074   Display *dpy = dpyinfo->display;
4075   Screen *screen = dpyinfo->screen;
4076   Lisp_Object value;
4077 
4078   /* See if a visual is specified.  */
4079   value = display_x_get_resource (dpyinfo,
4080                                   build_string ("visualClass"),
4081                                   build_string ("VisualClass"),
4082                                   Qnil, Qnil);
4083   if (STRINGP (value))
4084     {
4085       /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4086          of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4087          depth, a decimal number.  NAME is compared with case ignored.  */
4088       char *s = (char *) alloca (SBYTES (value) + 1);
4089       char *dash;
4090       int i, class = -1;
4091       XVisualInfo vinfo;
4092 
4093       strcpy (s, SDATA (value));
4094       dash = index (s, '-');
4095       if (dash)
4096         {
4097           dpyinfo->n_planes = atoi (dash + 1);
4098           *dash = '\0';
4099         }
4100       else
4101         /* We won't find a matching visual with depth 0, so that
4102            an error will be printed below.  */
4103         dpyinfo->n_planes = 0;
4104 
4105       /* Determine the visual class.  */
4106       for (i = 0; visual_classes[i].name; ++i)
4107         if (xstrcasecmp (s, visual_classes[i].name) == 0)
4108           {
4109             class = visual_classes[i].class;
4110             break;
4111           }
4112 
4113       /* Look up a matching visual for the specified class.  */
4114       if (class == -1
4115           || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4116                                 dpyinfo->n_planes, class, &vinfo))
4117         fatal ("Invalid visual specification `%s'", SDATA (value));
4118 
4119       dpyinfo->visual = vinfo.visual;
4120     }
4121   else
4122     {
4123       int n_visuals;
4124       XVisualInfo *vinfo, vinfo_template;
4125 
4126       dpyinfo->visual = DefaultVisualOfScreen (screen);
4127 
4128       vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4129       vinfo_template.screen = XScreenNumberOfScreen (screen);
4130       vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4131                               &vinfo_template, &n_visuals);
4132       if (n_visuals <= 0)
4133         fatal ("Can't get proper X visual info");
4134 
4135       dpyinfo->n_planes = vinfo->depth;
4136       XFree ((char *) vinfo);
4137     }
4138 }
4139 
4140 
4141 /* Return the X display structure for the display named NAME.
4142    Open a new connection if necessary.  */
4143 
4144 struct x_display_info *
4145 x_display_info_for_name (name)
4146      Lisp_Object name;
4147 {
4148   Lisp_Object names;
4149   struct x_display_info *dpyinfo;
4150 
4151   CHECK_STRING (name);
4152 
4153 #if 0
4154   if (! EQ (Vinitial_window_system, intern ("x")))
4155     error ("Not using X Windows"); /* That doesn't stop us anymore. */
4156 #endif
4157 
4158   for (dpyinfo = x_display_list, names = x_display_name_list;
4159        dpyinfo;
4160        dpyinfo = dpyinfo->next, names = XCDR (names))
4161     {
4162       Lisp_Object tem;
4163       tem = Fstring_equal (XCAR (XCAR (names)), name);
4164       if (!NILP (tem))
4165         return dpyinfo;
4166     }
4167 
4168   /* Use this general default value to start with.  */
4169   Vx_resource_name = Vinvocation_name;
4170 
4171   validate_x_resource_name ();
4172 
4173   dpyinfo = x_term_init (name, (char *)0,
4174                          (char *) SDATA (Vx_resource_name));
4175 
4176   if (dpyinfo == 0)
4177     error ("Cannot connect to X server %s", SDATA (name));
4178 
4179   x_in_use = 1;
4180   XSETFASTINT (Vwindow_system_version, 11);
4181 
4182   return dpyinfo;
4183 }
4184 
4185 
4186 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4187        1, 3, 0,
4188        doc: /* Open a connection to an X server.
4189 DISPLAY is the name of the display to connect to.
4190 Optional second arg XRM-STRING is a string of resources in xrdb format.
4191 If the optional third arg MUST-SUCCEED is non-nil,
4192 terminate Emacs if we can't open the connection.  */)
4193      (display, xrm_string, must_succeed)
4194      Lisp_Object display, xrm_string, must_succeed;
4195 {
4196   unsigned char *xrm_option;
4197   struct x_display_info *dpyinfo;
4198 
4199   CHECK_STRING (display);
4200   if (! NILP (xrm_string))
4201     CHECK_STRING (xrm_string);
4202 
4203 #if 0
4204   if (! EQ (Vinitial_window_system, intern ("x")))
4205     error ("Not using X Windows"); /* That doesn't stop us anymore. */
4206 #endif
4207 
4208   if (! NILP (xrm_string))
4209     xrm_option = (unsigned char *) SDATA (xrm_string);
4210   else
4211     xrm_option = (unsigned char *) 0;
4212 
4213   validate_x_resource_name ();
4214 
4215   /* This is what opens the connection and sets x_current_display.
4216      This also initializes many symbols, such as those used for input.  */
4217   dpyinfo = x_term_init (display, xrm_option,
4218                          (char *) SDATA (Vx_resource_name));
4219 
4220   if (dpyinfo == 0)
4221     {
4222       if (!NILP (must_succeed))
4223         fatal ("Cannot connect to X server %s.\n\
4224 Check the DISPLAY environment variable or use `-d'.\n\
4225 Also use the `xauth' program to verify that you have the proper\n\
4226 authorization information needed to connect the X server.\n\
4227 An insecure way to solve the problem may be to use `xhost'.\n",
4228                SDATA (display));
4229       else
4230         error ("Cannot connect to X server %s", SDATA (display));
4231     }
4232 
4233   x_in_use = 1;
4234 
4235   XSETFASTINT (Vwindow_system_version, 11);
4236   return Qnil;
4237 }
4238 
4239 DEFUN ("x-close-connection", Fx_close_connection,
4240        Sx_close_connection, 1, 1, 0,
4241        doc: /* Close the connection to TERMINAL's X server.
4242 For TERMINAL, specify a terminal object, a frame or a display name (a
4243 string).  If TERMINAL is nil, that stands for the selected frame's
4244 terminal.  */)
4245      (terminal)
4246      Lisp_Object terminal;
4247 {
4248   struct x_display_info *dpyinfo = check_x_display_info (terminal);
4249 
4250   if (dpyinfo->reference_count > 0)
4251     error ("Display still has frames on it");
4252 
4253   x_delete_terminal (dpyinfo->terminal);
4254 
4255   return Qnil;
4256 }
4257 
4258 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4259        doc: /* Return the list of display names that Emacs has connections to.  */)
4260      ()
4261 {
4262   Lisp_Object tail, result;
4263 
4264   result = Qnil;
4265   for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
4266     result = Fcons (XCAR (XCAR (tail)), result);
4267 
4268   return result;
4269 }
4270 
4271 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4272        doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4273 If ON is nil, allow buffering of requests.
4274 Turning on synchronization prohibits the Xlib routines from buffering
4275 requests and seriously degrades performance, but makes debugging much
4276 easier.
4277 The optional second argument TERMINAL specifies which display to act on.
4278 TERMINAL should be a terminal object, a frame or a display name (a string).
4279 If TERMINAL is omitted or nil, that stands for the selected frame's display.  */)
4280      (on, terminal)
4281     Lisp_Object terminal, on;
4282 {
4283   struct x_display_info *dpyinfo = check_x_display_info (terminal);
4284 
4285   XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4286 
4287   return Qnil;
4288 }
4289 
4290 /* Wait for responses to all X commands issued so far for frame F.  */
4291 
4292 void
4293 x_sync (f)
4294      FRAME_PTR f;
4295 {
4296   BLOCK_INPUT;
4297   XSync (FRAME_X_DISPLAY (f), False);
4298   UNBLOCK_INPUT;
4299 }
4300 
4301 
4302 /***********************************************************************
4303                            Window properties
4304  ***********************************************************************/
4305 
4306 DEFUN ("x-change-window-property", Fx_change_window_property,
4307        Sx_change_window_property, 2, 6, 0,
4308        doc: /* Change window property PROP to VALUE on the X window of FRAME.
4309 PROP must be a string.
4310 VALUE may be a string or a list of conses, numbers and/or strings.
4311 If an element in the list is a string, it is converted to
4312 an Atom and the value of the Atom is used.  If an element is a cons,
4313 it is converted to a 32 bit number where the car is the 16 top bits and the
4314 cdr is the lower 16 bits.
4315 FRAME nil or omitted means use the selected frame.
4316 If TYPE is given and non-nil, it is the name of the type of VALUE.
4317 If TYPE is not given or nil, the type is STRING.
4318 FORMAT gives the size in bits of each element if VALUE is a list.
4319 It must be one of 8, 16 or 32.
4320 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4321 If OUTER_P is non-nil, the property is changed for the outer X window of
4322 FRAME.  Default is to change on the edit X window.
4323 
4324 Value is VALUE.  */)
4325      (prop, value, frame, type, format, outer_p)
4326      Lisp_Object prop, value, frame, type, format, outer_p;
4327 {
4328   struct frame *f = check_x_frame (frame);
4329   Atom prop_atom;
4330   Atom target_type = XA_STRING;
4331   int element_format = 8;
4332   unsigned char *data;
4333   int nelements;
4334   Window w;
4335 
4336   CHECK_STRING (prop);
4337 
4338   if (! NILP (format))
4339     {
4340       CHECK_NUMBER (format);
4341       element_format = XFASTINT (format);
4342 
4343       if (element_format != 8 && element_format != 16
4344           && element_format != 32)
4345         error ("FORMAT must be one of 8, 16 or 32");
4346     }
4347 
4348   if (CONSP (value))
4349     {
4350       nelements = x_check_property_data (value);
4351       if (nelements == -1)
4352         error ("Bad data in VALUE, must be number, string or cons");
4353 
4354       if (element_format == 8)
4355         data = (unsigned char *) xmalloc (nelements);
4356       else if (element_format == 16)
4357         data = (unsigned char *) xmalloc (nelements*2);
4358       else /* format == 32 */
4359         /* The man page for XChangeProperty:
4360                "If the specified format is 32, the property data must be a
4361                 long array."
4362            This applies even if long is more than 64 bits.  The X library
4363            converts to 32 bits before sending to the X server.  */
4364         data = (unsigned char *) xmalloc (nelements * sizeof(long));
4365 
4366       x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4367     }
4368   else
4369     {
4370       CHECK_STRING (value);
4371       data = SDATA (value);
4372       nelements = SCHARS (value);
4373     }
4374 
4375   BLOCK_INPUT;
4376   prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4377   if (! NILP (type))
4378     {
4379       CHECK_STRING (type);
4380       target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4381     }
4382 
4383   if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4384   else w = FRAME_X_WINDOW (f);
4385 
4386   XChangeProperty (FRAME_X_DISPLAY (f), w,
4387                    prop_atom, target_type, element_format, PropModeReplace,
4388                    data, nelements);
4389 
4390   if (CONSP (value)) xfree (data);
4391 
4392   /* Make sure the property is set when we return.  */
4393   XFlush (FRAME_X_DISPLAY (f));
4394   UNBLOCK_INPUT;
4395 
4396   return value;
4397 }
4398 
4399 
4400 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4401        Sx_delete_window_property, 1, 2, 0,
4402        doc: /* Remove window property PROP from X window of FRAME.
4403 FRAME nil or omitted means use the selected frame.  Value is PROP.  */)
4404      (prop, frame)
4405      Lisp_Object prop, frame;
4406 {
4407   struct frame *f = check_x_frame (frame);
4408   Atom prop_atom;
4409 
4410   CHECK_STRING (prop);
4411   BLOCK_INPUT;
4412   prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4413   XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4414 
4415   /* Make sure the property is removed when we return.  */
4416   XFlush (FRAME_X_DISPLAY (f));
4417   UNBLOCK_INPUT;
4418 
4419   return prop;
4420 }
4421 
4422 
4423 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4424        1, 6, 0,
4425        doc: /* Value is the value of window property PROP on FRAME.
4426 If FRAME is nil or omitted, use the selected frame.
4427 If TYPE is nil or omitted, get the property as a string.  Otherwise TYPE
4428 is the name of the Atom that denotes the type expected.
4429 If SOURCE is non-nil, get the property on that window instead of from
4430 FRAME.  The number 0 denotes the root window.
4431 If DELETE_P is non-nil, delete the property after retreiving it.
4432 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4433 
4434 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4435 no value of TYPE.  */)
4436      (prop, frame, type, source, delete_p, vector_ret_p)
4437      Lisp_Object prop, frame, type, source, delete_p, vector_ret_p;
4438 {
4439   struct frame *f = check_x_frame (frame);
4440   Atom prop_atom;
4441   int rc;
4442   Lisp_Object prop_value = Qnil;
4443   unsigned char *tmp_data = NULL;
4444   Atom actual_type;
4445   Atom target_type = XA_STRING;
4446   int actual_format;
4447   unsigned long actual_size, bytes_remaining;
4448   Window target_window = FRAME_X_WINDOW (f);
4449   struct gcpro gcpro1;
4450 
4451   GCPRO1 (prop_value);
4452   CHECK_STRING (prop);
4453 
4454   if (! NILP (source))
4455     {
4456       if (NUMBERP (source))
4457         {
4458           if (FLOATP (source))
4459             target_window = (Window) XFLOAT (source);
4460           else
4461             target_window = XFASTINT (source);
4462 
4463           if (target_window == 0)
4464             target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4465         }
4466       else if (CONSP (source))
4467         target_window = cons_to_long (source);
4468     }
4469 
4470   BLOCK_INPUT;
4471   if (STRINGP (type))
4472     {
4473       if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
4474         target_type = AnyPropertyType;
4475       else
4476         target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4477     }
4478 
4479   prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4480   rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4481                            prop_atom, 0, 0, False, target_type,
4482                            &actual_type, &actual_format, &actual_size,
4483                            &bytes_remaining, &tmp_data);
4484   if (rc == Success)
4485     {
4486       int size = bytes_remaining;
4487 
4488       XFree (tmp_data);
4489       tmp_data = NULL;
4490 
4491       rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4492                                prop_atom, 0, bytes_remaining,
4493                                ! NILP (delete_p), target_type,
4494                                &actual_type, &actual_format,
4495                                &actual_size, &bytes_remaining,
4496                                &tmp_data);
4497       if (rc == Success && tmp_data)
4498         {
4499           /* The man page for XGetWindowProperty says:
4500              "If the returned format is 32, the returned data is represented
4501              as a long array and should be cast to that type to obtain the
4502              elements."
4503              This applies even if long is more than 32 bits, the X library
4504              converts from 32 bit elements received from the X server to long
4505              and passes the long array to us.  Thus, for that case bcopy can not
4506              be used.  We convert to a 32 bit type here, because so much code
4507              assume on that.
4508 
4509              The bytes and offsets passed to XGetWindowProperty refers to the
4510              property and those are indeed in 32 bit quantities if format is
4511              32.  */
4512 
4513           if (actual_format == 32 && actual_format < BITS_PER_LONG)
4514             {
4515               unsigned long i;
4516               int  *idata = (int *) tmp_data;
4517               long *ldata = (long *) tmp_data;
4518 
4519               for (i = 0; i < actual_size; ++i)
4520                 idata[i] = (int) ldata[i];
4521             }
4522 
4523           if (NILP (vector_ret_p))
4524             prop_value = make_string (tmp_data, size);
4525           else
4526             prop_value = x_property_data_to_lisp (f,
4527                                                   tmp_data,
4528                                                   actual_type,
4529                                                   actual_format,
4530                                                   actual_size);
4531         }
4532 
4533       if (tmp_data) XFree (tmp_data);
4534     }
4535 
4536   UNBLOCK_INPUT;
4537   UNGCPRO;
4538   return prop_value;
4539 }
4540 
4541 
4542 
4543 /***********************************************************************
4544                                 Busy cursor
4545  ***********************************************************************/
4546 
4547 /* Timer function of hourglass_atimer.  TIMER is equal to
4548    hourglass_atimer.
4549 
4550    Display an hourglass pointer on all frames by mapping the frames'
4551    hourglass_window.  Set the hourglass_p flag in the frames'
4552    output_data.x structure to indicate that an hourglass cursor is
4553    shown on the frames.  */
4554 
4555 void
4556 show_hourglass (timer)
4557      struct atimer *timer;
4558 {
4559   /* The timer implementation will cancel this timer automatically
4560      after this function has run.  Set hourglass_atimer to null
4561      so that we know the timer doesn't have to be canceled.  */
4562   hourglass_atimer = NULL;
4563 
4564   if (!hourglass_shown_p)
4565     {
4566       Lisp_Object rest, frame;
4567 
4568       BLOCK_INPUT;
4569 
4570       FOR_EACH_FRAME (rest, frame)
4571         {
4572           struct frame *f = XFRAME (frame);
4573 
4574           if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4575             {
4576               Display *dpy = FRAME_X_DISPLAY (f);
4577 
4578 #ifdef USE_X_TOOLKIT
4579               if (f->output_data.x->widget)
4580 #else
4581               if (FRAME_OUTER_WINDOW (f))
4582 #endif
4583                 {
4584                   f->output_data.x->hourglass_p = 1;
4585 
4586                   if (!f->output_data.x->hourglass_window)
4587                     {
4588                       unsigned long mask = CWCursor;
4589                       XSetWindowAttributes attrs;
4590 #ifdef USE_GTK
4591                       Window parent = FRAME_X_WINDOW (f);
4592 #else
4593                       Window parent = FRAME_OUTER_WINDOW (f);
4594 #endif
4595                       attrs.cursor = f->output_data.x->hourglass_cursor;
4596 
4597                       f->output_data.x->hourglass_window
4598                         = XCreateWindow (dpy, parent,
4599                                          0, 0, 32000, 32000, 0, 0,
4600                                          InputOnly,
4601                                          CopyFromParent,
4602                                          mask, &attrs);
4603                     }
4604 
4605                   XMapRaised (dpy, f->output_data.x->hourglass_window);
4606                   XFlush (dpy);
4607                 }
4608             }
4609         }
4610 
4611       hourglass_shown_p = 1;
4612       UNBLOCK_INPUT;
4613     }
4614 }
4615 
4616 
4617 /* Hide the hourglass pointer on all frames, if it is currently
4618    shown.  */
4619 
4620 void
4621 hide_hourglass ()
4622 {
4623   if (hourglass_shown_p)
4624     {
4625       Lisp_Object rest, frame;
4626 
4627       BLOCK_INPUT;
4628       FOR_EACH_FRAME (rest, frame)
4629         {
4630           struct frame *f = XFRAME (frame);
4631 
4632           if (FRAME_X_P (f)
4633               /* Watch out for newly created frames.  */
4634               && f->output_data.x->hourglass_window)
4635             {
4636               XUnmapWindow (FRAME_X_DISPLAY (f),
4637                             f->output_data.x->hourglass_window);
4638               /* Sync here because XTread_socket looks at the
4639                  hourglass_p flag that is reset to zero below.  */
4640               XSync (FRAME_X_DISPLAY (f), False);
4641               f->output_data.x->hourglass_p = 0;
4642             }
4643         }
4644 
4645       hourglass_shown_p = 0;
4646       UNBLOCK_INPUT;
4647     }
4648 }
4649 
4650 
4651 
4652 /***********************************************************************
4653                                 Tool tips
4654  ***********************************************************************/
4655 
4656 static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *,
4657                                            Lisp_Object, Lisp_Object));
4658 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
4659                                 Lisp_Object, int, int, int *, int *));
4660 
4661 /* The frame of a currently visible tooltip.  */
4662 
4663 Lisp_Object tip_frame;
4664 
4665 /* If non-nil, a timer started that hides the last tooltip when it
4666    fires.  */
4667 
4668 Lisp_Object tip_timer;
4669 Window tip_window;
4670 
4671 /* If non-nil, a vector of 3 elements containing the last args
4672    with which x-show-tip was called.  See there.  */
4673 
4674 Lisp_Object last_show_tip_args;
4675 
4676 /* Maximum size for tooltips; a cons (COLUMNS . ROWS).  */
4677 
4678 Lisp_Object Vx_max_tooltip_size;
4679 
4680 
4681 static Lisp_Object
4682 unwind_create_tip_frame (frame)
4683      Lisp_Object frame;
4684 {
4685   Lisp_Object deleted;
4686 
4687   deleted = unwind_create_frame (frame);
4688   if (EQ (deleted, Qt))
4689     {
4690       tip_window = None;
4691       tip_frame = Qnil;
4692     }
4693 
4694   return deleted;
4695 }
4696 
4697 
4698 /* Create a frame for a tooltip on the display described by DPYINFO.
4699    PARMS is a list of frame parameters.  TEXT is the string to
4700    display in the tip frame.  Value is the frame.
4701 
4702    Note that functions called here, esp. x_default_parameter can
4703    signal errors, for instance when a specified color name is
4704    undefined.  We have to make sure that we're in a consistent state
4705    when this happens.  */
4706 
4707 static Lisp_Object
4708 x_create_tip_frame (dpyinfo, parms, text)
4709      struct x_display_info *dpyinfo;
4710      Lisp_Object parms, text;
4711 {
4712   struct frame *f;
4713   Lisp_Object frame, tem;
4714   Lisp_Object name;
4715   long window_prompting = 0;
4716   int width, height;
4717   int count = SPECPDL_INDEX ();
4718   struct gcpro gcpro1, gcpro2, gcpro3;
4719   int face_change_count_before = face_change_count;
4720   Lisp_Object buffer;
4721   struct buffer *old_buffer;
4722 
4723   check_x ();
4724 
4725   if (!dpyinfo->terminal->name)
4726     error ("Terminal is not live, can't create new frames on it");
4727 
4728   parms = Fcopy_alist (parms);
4729 
4730   /* Get the name of the frame to use for resource lookup.  */
4731   name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4732   if (!STRINGP (name)
4733       && !EQ (name, Qunbound)
4734       && !NILP (name))
4735     error ("Invalid frame name--not a string or nil");
4736 
4737   frame = Qnil;
4738   GCPRO3 (parms, name, frame);
4739   f = make_frame (1);
4740   XSETFRAME (frame, f);
4741 
4742   buffer = Fget_buffer_create (build_string (" *tip*"));
4743   Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
4744   old_buffer = current_buffer;
4745   set_buffer_internal_1 (XBUFFER (buffer));
4746   current_buffer->truncate_lines = Qnil;
4747   specbind (Qinhibit_read_only, Qt);
4748   specbind (Qinhibit_modification_hooks, Qt);
4749   Ferase_buffer ();
4750   Finsert (1, &text);
4751   set_buffer_internal_1 (old_buffer);
4752 
4753   FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4754   record_unwind_protect (unwind_create_tip_frame, frame);
4755 
4756   f->terminal = dpyinfo->terminal;
4757   f->terminal->reference_count++;
4758 
4759   /* By setting the output method, we're essentially saying that
4760      the frame is live, as per FRAME_LIVE_P.  If we get a signal
4761      from this point on, x_destroy_window might screw up reference
4762      counts etc.  */
4763   f->output_method = output_x_window;
4764   f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
4765   bzero (f->output_data.x, sizeof (struct x_output));
4766   f->output_data.x->icon_bitmap = -1;
4767   FRAME_FONTSET (f) = -1;
4768   f->output_data.x->scroll_bar_foreground_pixel = -1;
4769   f->output_data.x->scroll_bar_background_pixel = -1;
4770 #ifdef USE_TOOLKIT_SCROLL_BARS
4771   f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4772   f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4773 #endif /* USE_TOOLKIT_SCROLL_BARS */
4774   f->icon_name = Qnil;
4775   FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4776 #if GLYPH_DEBUG
4777   image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
4778   dpyinfo_refcount = dpyinfo->reference_count;
4779 #endif /* GLYPH_DEBUG */
4780   f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4781   f->output_data.x->explicit_parent = 0;
4782 
4783   /* These colors will be set anyway later, but it's important
4784      to get the color reference counts right, so initialize them!  */
4785   {
4786     Lisp_Object black;
4787     struct gcpro gcpro1;
4788 
4789     /* Function x_decode_color can signal an error.  Make
4790        sure to initialize color slots so that we won't try
4791        to free colors we haven't allocated.  */
4792     FRAME_FOREGROUND_PIXEL (f) = -1;
4793     FRAME_BACKGROUND_PIXEL (f) = -1;
4794     f->output_data.x->cursor_pixel = -1;
4795     f->output_data.x->cursor_foreground_pixel = -1;
4796     f->output_data.x->border_pixel = -1;
4797     f->output_data.x->mouse_pixel = -1;
4798 
4799     black = build_string ("black");
4800     GCPRO1 (black);
4801     FRAME_FOREGROUND_PIXEL (f)
4802       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4803     FRAME_BACKGROUND_PIXEL (f)
4804       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4805     f->output_data.x->cursor_pixel
4806       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4807     f->output_data.x->cursor_foreground_pixel
4808       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4809     f->output_data.x->border_pixel
4810       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4811     f->output_data.x->mouse_pixel
4812       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4813     UNGCPRO;
4814   }
4815 
4816   /* Set the name; the functions to which we pass f expect the name to
4817      be set.  */
4818   if (EQ (name, Qunbound) || NILP (name))
4819     {
4820       f->name = build_string (dpyinfo->x_id_name);
4821       f->explicit_name = 0;
4822     }
4823   else
4824     {
4825       f->name = name;
4826       f->explicit_name = 1;
4827       /* use the frame's title when getting resources for this frame.  */
4828       specbind (Qx_resource_name, name);
4829     }
4830 
4831   f->resx = dpyinfo->resx;
4832   f->resy = dpyinfo->resy;
4833 
4834   register_font_driver (&xfont_driver, f);
4835 #ifdef HAVE_FREETYPE
4836 #ifdef HAVE_XFT
4837   register_font_driver (&xftfont_driver, f);
4838 #else   /* not HAVE_XFT */
4839   register_font_driver (&ftxfont_driver, f);
4840 #endif  /* not HAVE_XFT */
4841 #endif  /* HAVE_FREETYPE */
4842 
4843   x_default_parameter (f, parms, Qfont_backend, Qnil,
4844                        "fontBackend", "FontBackend", RES_TYPE_STRING);
4845 
4846   /* Extract the window parameters from the supplied values that are
4847      needed to determine window geometry.  */
4848   x_default_font_parameter (f, parms);
4849 
4850   x_default_parameter (f, parms, Qborder_width, make_number (0),
4851                        "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4852 
4853   /* This defaults to 2 in order to match xterm.  We recognize either
4854      internalBorderWidth or internalBorder (which is what xterm calls
4855      it).  */
4856   if (NILP (Fassq (Qinternal_border_width, parms)))
4857     {
4858       Lisp_Object value;
4859 
4860       value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4861                          "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4862       if (! EQ (value, Qunbound))
4863         parms = Fcons (Fcons (Qinternal_border_width, value),
4864                        parms);
4865     }
4866 
4867   x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4868                        "internalBorderWidth", "internalBorderWidth",
4869                        RES_TYPE_NUMBER);
4870 
4871   /* Also do the stuff which must be set before the window exists.  */
4872   x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4873                        "foreground", "Foreground", RES_TYPE_STRING);
4874   x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4875                        "background", "Background", RES_TYPE_STRING);
4876   x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4877                        "pointerColor", "Foreground", RES_TYPE_STRING);
4878   x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4879                        "cursorColor", "Foreground", RES_TYPE_STRING);
4880   x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4881                        "borderColor", "BorderColor", RES_TYPE_STRING);
4882 
4883   /* Init faces before x_default_parameter is called for scroll-bar
4884      parameters because that function calls x_set_scroll_bar_width,
4885      which calls change_frame_size, which calls Fset_window_buffer,
4886      which runs hooks, which call Fvertical_motion.  At the end, we
4887      end up in init_iterator with a null face cache, which should not
4888      happen.  */
4889   init_frame_faces (f);
4890 
4891   f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4892 
4893   window_prompting = x_figure_window_size (f, parms, 0);
4894 
4895   {
4896     XSetWindowAttributes attrs;
4897     unsigned long mask;
4898     Atom type = FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
4899 
4900     BLOCK_INPUT;
4901     mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
4902     if (DoesSaveUnders (dpyinfo->screen))
4903       mask |= CWSaveUnder;
4904 
4905     /* Window managers look at the override-redirect flag to determine
4906        whether or net to give windows a decoration (Xlib spec, chapter
4907        3.2.8).  */
4908     attrs.override_redirect = True;
4909     attrs.save_under = True;
4910     attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
4911     /* Arrange for getting MapNotify and UnmapNotify events.  */
4912     attrs.event_mask = StructureNotifyMask;
4913     tip_window
4914       = FRAME_X_WINDOW (f)
4915       = XCreateWindow (FRAME_X_DISPLAY (f),
4916                        FRAME_X_DISPLAY_INFO (f)->root_window,
4917                        /* x, y, width, height */
4918                        0, 0, 1, 1,
4919                        /* Border.  */
4920                        f->border_width,
4921                        CopyFromParent, InputOutput, CopyFromParent,
4922                        mask, &attrs);
4923     XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
4924                      FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type,
4925                      XA_ATOM, 32, PropModeReplace,
4926                      (unsigned char *)&type, 1);
4927     UNBLOCK_INPUT;
4928   }
4929 
4930   x_make_gc (f);
4931 
4932   x_default_parameter (f, parms, Qauto_raise, Qnil,
4933                        "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4934   x_default_parameter (f, parms, Qauto_lower, Qnil,
4935                        "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4936   x_default_parameter (f, parms, Qcursor_type, Qbox,
4937                        "cursorType", "CursorType", RES_TYPE_SYMBOL);
4938 
4939   /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4940      Change will not be effected unless different from the current
4941      FRAME_LINES (f).  */
4942   width = FRAME_COLS (f);
4943   height = FRAME_LINES (f);
4944   SET_FRAME_COLS (f, 0);
4945   FRAME_LINES (f) = 0;
4946   change_frame_size (f, height, width, 1, 0, 0);
4947 
4948   /* Add `tooltip' frame parameter's default value. */
4949   if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
4950     Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
4951                                             Qnil));
4952 
4953   /* FIXME - can this be done in a similar way to normal frames?
4954      http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
4955 
4956   /* Set the `display-type' frame parameter before setting up faces. */
4957   {
4958     Lisp_Object disptype;
4959 
4960     if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
4961       disptype = intern ("mono");
4962     else if (FRAME_X_DISPLAY_INFO (f)->visual->class == GrayScale
4963              || FRAME_X_DISPLAY_INFO (f)->visual->class == StaticGray)
4964       disptype = intern ("grayscale");
4965     else
4966       disptype = intern ("color");
4967 
4968     if (NILP (Fframe_parameter (frame, Qdisplay_type)))
4969       Fmodify_frame_parameters (frame, Fcons (Fcons (Qdisplay_type, disptype),
4970                                               Qnil));
4971   }
4972 
4973   /* Set up faces after all frame parameters are known.  This call
4974      also merges in face attributes specified for new frames.
4975 
4976      Frame parameters may be changed if .Xdefaults contains
4977      specifications for the default font.  For example, if there is an
4978      `Emacs.default.attributeBackground: pink', the `background-color'
4979      attribute of the frame get's set, which let's the internal border
4980      of the tooltip frame appear in pink.  Prevent this.  */
4981   {
4982     Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
4983 
4984     /* Set tip_frame here, so that */
4985     tip_frame = frame;
4986     call2 (Qface_set_after_frame_default, frame, Qnil);
4987 
4988     if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
4989       Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
4990                                               Qnil));
4991   }
4992 
4993   f->no_split = 1;
4994 
4995   UNGCPRO;
4996 
4997   /* It is now ok to make the frame official even if we get an error
4998      below.  And the frame needs to be on Vframe_list or making it
4999      visible won't work.  */
5000   Vframe_list = Fcons (frame, Vframe_list);
5001 
5002   /* Now that the frame is official, it counts as a reference to
5003      its display.  */
5004   FRAME_X_DISPLAY_INFO (f)->reference_count++;
5005 
5006   /* Setting attributes of faces of the tooltip frame from resources
5007      and similar will increment face_change_count, which leads to the
5008      clearing of all current matrices.  Since this isn't necessary
5009      here, avoid it by resetting face_change_count to the value it
5010      had before we created the tip frame.  */
5011   face_change_count = face_change_count_before;
5012 
5013   /* Discard the unwind_protect.  */
5014   return unbind_to (count, frame);
5015 }
5016 
5017 
5018 /* Compute where to display tip frame F.  PARMS is the list of frame
5019    parameters for F.  DX and DY are specified offsets from the current
5020    location of the mouse.  WIDTH and HEIGHT are the width and height
5021    of the tooltip.  Return coordinates relative to the root window of
5022    the display in *ROOT_X, and *ROOT_Y.  */
5023 
5024 static void
5025 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
5026      struct frame *f;
5027      Lisp_Object parms, dx, dy;
5028      int width, height;
5029      int *root_x, *root_y;
5030 {
5031   Lisp_Object left, top;
5032   int win_x, win_y;
5033   Window root, child;
5034   unsigned pmask;
5035 
5036   /* User-specified position?  */
5037   left = Fcdr (Fassq (Qleft, parms));
5038   top  = Fcdr (Fassq (Qtop, parms));
5039 
5040   /* Move the tooltip window where the mouse pointer is.  Resize and
5041      show it.  */
5042   if (!INTEGERP (left) || !INTEGERP (top))
5043     {
5044       BLOCK_INPUT;
5045       XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
5046                      &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
5047       UNBLOCK_INPUT;
5048     }
5049 
5050   if (INTEGERP (top))
5051     *root_y = XINT (top);
5052   else if (*root_y + XINT (dy) <= 0)
5053     *root_y = 0; /* Can happen for negative dy */
5054   else if (*root_y + XINT (dy) + height
5055            <= x_display_pixel_height (FRAME_X_DISPLAY_INFO (f)))
5056     /* It fits below the pointer */
5057     *root_y += XINT (dy);
5058   else if (height + XINT (dy) <= *root_y)
5059     /* It fits above the pointer.  */
5060     *root_y -= height + XINT (dy);
5061   else
5062     /* Put it on the top.  */
5063     *root_y = 0;
5064 
5065   if (INTEGERP (left))
5066     *root_x = XINT (left);
5067   else if (*root_x + XINT (dx) <= 0)
5068     *root_x = 0; /* Can happen for negative dx */
5069   else if (*root_x + XINT (dx) + width
5070            <= x_display_pixel_width (FRAME_X_DISPLAY_INFO (f)))
5071     /* It fits to the right of the pointer.  */
5072     *root_x += XINT (dx);
5073   else if (width + XINT (dx) <= *root_x)
5074     /* It fits to the left of the pointer.  */
5075     *root_x -= width + XINT (dx);
5076   else
5077     /* Put it left-justified on the screen--it ought to fit that way.  */
5078     *root_x = 0;
5079 }
5080 
5081 
5082 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5083        doc: /* Show STRING in a "tooltip" window on frame FRAME.
5084 A tooltip window is a small X window displaying a string.
5085 
5086 This is an internal function; Lisp code should call `tooltip-show'.
5087 
5088 FRAME nil or omitted means use the selected frame.
5089 
5090 PARMS is an optional list of frame parameters which can be used to
5091 change the tooltip's appearance.
5092 
5093 Automatically hide the tooltip after TIMEOUT seconds.  TIMEOUT nil
5094 means use the default timeout of 5 seconds.
5095 
5096 If the list of frame parameters PARAMS contains a `left' parameters,
5097 the tooltip is displayed at that x-position.  Otherwise it is
5098 displayed at the mouse position, with offset DX added (default is 5 if
5099 DX isn't specified).  Likewise for the y-position; if a `top' frame
5100 parameter is specified, it determines the y-position of the tooltip
5101 window, otherwise it is displayed at the mouse position, with offset
5102 DY added (default is -10).
5103 
5104 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5105 Text larger than the specified size is clipped.  */)
5106      (string, frame, parms, timeout, dx, dy)
5107      Lisp_Object string, frame, parms, timeout, dx, dy;
5108 {
5109   struct frame *f;
5110   struct window *w;
5111   int root_x, root_y;
5112   struct buffer *old_buffer;
5113   struct text_pos pos;
5114   int i, width, height;
5115   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5116   int old_windows_or_buffers_changed = windows_or_buffers_changed;
5117   int count = SPECPDL_INDEX ();
5118 
5119   specbind (Qinhibit_redisplay, Qt);
5120 
5121   GCPRO4 (string, parms, frame, timeout);
5122 
5123   CHECK_STRING (string);
5124   if (SCHARS (string) == 0)
5125     string = make_unibyte_string (" ", 1);
5126 
5127   f = check_x_frame (frame);
5128   if (NILP (timeout))
5129     timeout = make_number (5);
5130   else
5131     CHECK_NATNUM (timeout);
5132 
5133   if (NILP (dx))
5134     dx = make_number (5);
5135   else
5136     CHECK_NUMBER (dx);
5137 
5138   if (NILP (dy))
5139     dy = make_number (-10);
5140   else
5141     CHECK_NUMBER (dy);
5142 
5143   if (NILP (last_show_tip_args))
5144     last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5145 
5146   if (!NILP (tip_frame))
5147     {
5148       Lisp_Object last_string = AREF (last_show_tip_args, 0);
5149       Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5150       Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5151 
5152       if (EQ (frame, last_frame)
5153           && !NILP (Fequal (last_string, string))
5154           && !NILP (Fequal (last_parms, parms)))
5155         {
5156           struct frame *f = XFRAME (tip_frame);
5157 
5158           /* Only DX and DY have changed.  */
5159           if (!NILP (tip_timer))
5160             {
5161               Lisp_Object timer = tip_timer;
5162               tip_timer = Qnil;
5163               call1 (Qcancel_timer, timer);
5164             }
5165 
5166           BLOCK_INPUT;
5167           compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
5168                           FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
5169           XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5170                        root_x, root_y);
5171           UNBLOCK_INPUT;
5172           goto start_timer;
5173         }
5174     }
5175 
5176   /* Hide a previous tip, if any.  */
5177   Fx_hide_tip ();
5178 
5179   ASET (last_show_tip_args, 0, string);
5180   ASET (last_show_tip_args, 1, frame);
5181   ASET (last_show_tip_args, 2, parms);
5182 
5183   /* Add default values to frame parameters.  */
5184   if (NILP (Fassq (Qname, parms)))
5185     parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5186   if (NILP (Fassq (Qinternal_border_width, parms)))
5187     parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5188   if (NILP (Fassq (Qborder_width, parms)))
5189     parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5190   if (NILP (Fassq (Qborder_color, parms)))
5191     parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5192   if (NILP (Fassq (Qbackground_color, parms)))
5193     parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5194                    parms);
5195 
5196   /* Create a frame for the tooltip, and record it in the global
5197      variable tip_frame.  */
5198   frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
5199   f = XFRAME (frame);
5200 
5201   /* Set up the frame's root window.  */
5202   w = XWINDOW (FRAME_ROOT_WINDOW (f));
5203   w->left_col = w->top_line = make_number (0);
5204 
5205   if (CONSP (Vx_max_tooltip_size)
5206       && INTEGERP (XCAR (Vx_max_tooltip_size))
5207       && XINT (XCAR (Vx_max_tooltip_size)) > 0
5208       && INTEGERP (XCDR (Vx_max_tooltip_size))
5209       && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5210     {
5211       w->total_cols = XCAR (Vx_max_tooltip_size);
5212       w->total_lines = XCDR (Vx_max_tooltip_size);
5213     }
5214   else
5215     {
5216       w->total_cols = make_number (80);
5217       w->total_lines = make_number (40);
5218     }
5219 
5220   FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5221   adjust_glyphs (f);
5222   w->pseudo_window_p = 1;
5223 
5224   /* Display the tooltip text in a temporary buffer.  */
5225   old_buffer = current_buffer;
5226   set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5227   current_buffer->truncate_lines = Qnil;
5228   clear_glyph_matrix (w->desired_matrix);
5229   clear_glyph_matrix (w->current_matrix);
5230   SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5231   try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
5232 
5233   /* Compute width and height of the tooltip.  */
5234   width = height = 0;
5235   for (i = 0; i < w->desired_matrix->nrows; ++i)
5236     {
5237       struct glyph_row *row = &w->desired_matrix->rows[i];
5238       struct glyph *last;
5239       int row_width;
5240 
5241       /* Stop at the first empty row at the end.  */
5242       if (!row->enabled_p || !row->displays_text_p)
5243         break;
5244 
5245       /* Let the row go over the full width of the frame.  */
5246       row->full_width_p = 1;
5247 
5248       row_width = row->pixel_width;
5249       /* There's a glyph at the end of rows that is used to place
5250          the cursor there.  Don't include the width of this glyph.  */
5251       if (row->used[TEXT_AREA])
5252         {
5253           last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5254           if (INTEGERP (last->object))
5255             row_width -= last->pixel_width;
5256         }
5257 
5258       height += row->height;
5259       width = max (width, row_width);
5260     }
5261 
5262   /* Add the frame's internal border to the width and height the X
5263      window should have.  */
5264   height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5265   width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5266 
5267   /* Move the tooltip window where the mouse pointer is.  Resize and
5268      show it.  */
5269   compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5270 
5271   BLOCK_INPUT;
5272   XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5273                      root_x, root_y, width, height);
5274   XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5275   UNBLOCK_INPUT;
5276 
5277   /* Draw into the window.  */
5278   w->must_be_updated_p = 1;
5279   update_single_window (w, 1);
5280 
5281   /* Restore original current buffer.  */
5282   set_buffer_internal_1 (old_buffer);
5283   windows_or_buffers_changed = old_windows_or_buffers_changed;
5284 
5285  start_timer:
5286   /* Let the tip disappear after timeout seconds.  */
5287   tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5288                      intern ("x-hide-tip"));
5289 
5290   UNGCPRO;
5291   return unbind_to (count, Qnil);
5292 }
5293 
5294 
5295 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5296        doc: /* Hide the current tooltip window, if there is any.
5297 Value is t if tooltip was open, nil otherwise.  */)
5298      ()
5299 {
5300   int count;
5301   Lisp_Object deleted, frame, timer;
5302   struct gcpro gcpro1, gcpro2;
5303 
5304   /* Return quickly if nothing to do.  */
5305   if (NILP (tip_timer) && NILP (tip_frame))
5306     return Qnil;
5307 
5308   frame = tip_frame;
5309   timer = tip_timer;
5310   GCPRO2 (frame, timer);
5311   tip_frame = tip_timer = deleted = Qnil;
5312 
5313   count = SPECPDL_INDEX ();
5314   specbind (Qinhibit_redisplay, Qt);
5315   specbind (Qinhibit_quit, Qt);
5316 
5317   if (!NILP (timer))
5318     call1 (Qcancel_timer, timer);
5319 
5320   if (FRAMEP (frame))
5321     {
5322       delete_frame (frame, Qnil);
5323       deleted = Qt;
5324 
5325 #ifdef USE_LUCID
5326       /* Bloodcurdling hack alert: The Lucid menu bar widget's
5327          redisplay procedure is not called when a tip frame over menu
5328          items is unmapped.  Redisplay the menu manually...  */
5329       {
5330         struct frame *f = SELECTED_FRAME ();
5331         Widget w = f->output_data.x->menubar_widget;
5332         extern void xlwmenu_redisplay P_ ((Widget));
5333 
5334         if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5335             && w != NULL)
5336           {
5337             BLOCK_INPUT;
5338             xlwmenu_redisplay (w);
5339             UNBLOCK_INPUT;
5340           }
5341       }
5342 #endif /* USE_LUCID */
5343     }
5344 
5345   UNGCPRO;
5346   return unbind_to (count, deleted);
5347 }
5348 
5349 
5350 
5351 /***********************************************************************
5352                         File selection dialog
5353  ***********************************************************************/
5354 
5355 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5356        Sx_uses_old_gtk_dialog,
5357        0, 0, 0,
5358        doc: /* Return t if the old Gtk+ file selection dialog is used.  */)
5359      ()
5360 {
5361 #ifdef USE_GTK
5362   extern int use_dialog_box;
5363   extern int use_file_dialog;
5364 
5365   if (use_dialog_box
5366       && use_file_dialog
5367       && have_menus_p ()
5368       && xg_uses_old_file_dialog ())
5369     return Qt;
5370 #endif
5371   return Qnil;
5372 }
5373 
5374 
5375 #ifdef USE_MOTIF
5376 /* Callback for "OK" and "Cancel" on file selection dialog.  */
5377 
5378 static void
5379 file_dialog_cb (widget, client_data, call_data)
5380      Widget widget;
5381      XtPointer call_data, client_data;
5382 {
5383   int *result = (int *) client_data;
5384   XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5385   *result = cb->reason;
5386 }
5387 
5388 
5389 /* Callback for unmapping a file selection dialog.  This is used to
5390    capture the case where a dialog is closed via a window manager's
5391    closer button, for example. Using a XmNdestroyCallback didn't work
5392    in this case.  */
5393 
5394 static void
5395 file_dialog_unmap_cb (widget, client_data, call_data)
5396      Widget widget;
5397      XtPointer call_data, client_data;
5398 {
5399   int *result = (int *) client_data;
5400   *result = XmCR_CANCEL;
5401 }
5402 
5403 static Lisp_Object
5404 clean_up_file_dialog (arg)
5405      Lisp_Object arg;
5406 {
5407   struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5408   Widget dialog = (Widget) p->pointer;
5409 
5410   /* Clean up.  */
5411   BLOCK_INPUT;
5412   XtUnmanageChild (dialog);
5413   XtDestroyWidget (dialog);
5414   x_menu_set_in_use (0);
5415   UNBLOCK_INPUT;
5416 
5417   return Qnil;
5418 }
5419 
5420 
5421 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5422        doc: /* Read file name, prompting with PROMPT in directory DIR.
5423 Use a file selection dialog.  Select DEFAULT-FILENAME in the dialog's file
5424 selection box, if specified.  If MUSTMATCH is non-nil, the returned file
5425 or directory must exist.  ONLY-DIR-P is ignored."  */)
5426   (prompt, dir, default_filename, mustmatch, only_dir_p)
5427      Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5428 {
5429   int result;
5430   struct frame *f = SELECTED_FRAME ();
5431   Lisp_Object file = Qnil;
5432   Lisp_Object decoded_file;
5433   Widget dialog, text, help;
5434   Arg al[10];
5435   int ac = 0;
5436   extern XtAppContext Xt_app_con;
5437   XmString dir_xmstring, pattern_xmstring;
5438   int count = SPECPDL_INDEX ();
5439   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5440 
5441   check_x ();
5442 
5443   GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5444 
5445   if (popup_activated ())
5446     error ("Trying to use a menu from within a menu-entry");
5447 
5448   CHECK_STRING (prompt);
5449   CHECK_STRING (dir);
5450 
5451   /* Prevent redisplay.  */
5452   specbind (Qinhibit_redisplay, Qt);
5453 
5454   BLOCK_INPUT;
5455 
5456   /* Create the dialog with PROMPT as title, using DIR as initial
5457      directory and using "*" as pattern.  */
5458   dir = Fexpand_file_name (dir, Qnil);
5459   dir_xmstring = XmStringCreateLocalized (SDATA (dir));
5460   pattern_xmstring = XmStringCreateLocalized ("*");
5461 
5462   XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5463   XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5464   XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5465   XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5466   XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5467   dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5468                                         "fsb", al, ac);
5469   XmStringFree (dir_xmstring);
5470   XmStringFree (pattern_xmstring);
5471 
5472   /* Add callbacks for OK and Cancel.  */
5473   XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5474                  (XtPointer) &result);
5475   XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5476                  (XtPointer) &result);
5477   XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5478                  (XtPointer) &result);
5479 
5480   /* Remove the help button since we can't display help.  */
5481   help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5482   XtUnmanageChild (help);
5483 
5484   /* Mark OK button as default.  */
5485   XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5486                  XmNshowAsDefault, True, NULL);
5487 
5488   /* If MUSTMATCH is non-nil, disable the file entry field of the
5489      dialog, so that the user must select a file from the files list
5490      box.  We can't remove it because we wouldn't have a way to get at
5491      the result file name, then.  */
5492   text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5493   if (!NILP (mustmatch))
5494     {
5495       Widget label;
5496       label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5497       XtSetSensitive (text, False);
5498       XtSetSensitive (label, False);
5499     }
5500 
5501   /* Manage the dialog, so that list boxes get filled.  */
5502   XtManageChild (dialog);
5503 
5504   if (STRINGP (default_filename))
5505     {
5506       XmString default_xmstring;
5507       Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5508       Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5509 
5510       XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5511       XmTextFieldReplace (wtext, 0, last_pos,
5512                           (SDATA (Ffile_name_nondirectory (default_filename))));
5513 
5514       /* Select DEFAULT_FILENAME in the files list box.  DEFAULT_FILENAME
5515          must include the path for this to work.  */
5516 
5517       default_xmstring = XmStringCreateLocalized (SDATA (default_filename));
5518 
5519       if (XmListItemExists (list, default_xmstring))
5520         {
5521           int item_pos = XmListItemPos (list, default_xmstring);
5522           /* Select the item and scroll it into view.  */
5523           XmListSelectPos (list, item_pos, True);
5524           XmListSetPos (list, item_pos);
5525         }
5526 
5527       XmStringFree (default_xmstring);
5528     }
5529 
5530   record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5531 
5532   /* Process events until the user presses Cancel or OK.  */
5533   x_menu_set_in_use (1);
5534   result = 0;
5535   while (result == 0)
5536     {
5537       XEvent event;
5538       x_menu_wait_for_event (0);
5539       XtAppNextEvent (Xt_app_con, &event);
5540       if (event.type == KeyPress
5541           && FRAME_X_DISPLAY (f) == event.xkey.display)
5542         {
5543           KeySym keysym = XLookupKeysym (&event.xkey, 0);
5544 
5545           /* Pop down on C-g.  */
5546           if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5547             XtUnmanageChild (dialog);
5548         }
5549 
5550       (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5551     }
5552 
5553   /* Get the result.  */
5554   if (result == XmCR_OK)
5555     {
5556       XmString text;
5557       String data;
5558 
5559       XtVaGetValues (dialog, XmNtextString, &text, NULL);
5560       XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
5561       XmStringFree (text);
5562       file = build_string (data);
5563       XtFree (data);
5564     }
5565   else
5566     file = Qnil;
5567 
5568   UNBLOCK_INPUT;
5569   UNGCPRO;
5570 
5571   /* Make "Cancel" equivalent to C-g.  */
5572   if (NILP (file))
5573     Fsignal (Qquit, Qnil);
5574 
5575   decoded_file = DECODE_FILE (file);
5576 
5577   return unbind_to (count, decoded_file);
5578 }
5579 
5580 #endif /* USE_MOTIF */
5581 
5582 #ifdef USE_GTK
5583 
5584 static Lisp_Object
5585 clean_up_dialog (arg)
5586      Lisp_Object arg;
5587 {
5588   x_menu_set_in_use (0);
5589 
5590   return Qnil;
5591 }
5592 
5593 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5594        doc: /* Read file name, prompting with PROMPT in directory DIR.
5595 Use a file selection dialog.  Select DEFAULT-FILENAME in the dialog's file
5596 selection box, if specified.  If MUSTMATCH is non-nil, the returned file
5597 or directory must exist.  If ONLY-DIR-P is non-nil, the user can only select
5598 directories.  */)
5599   (prompt, dir, default_filename, mustmatch, only_dir_p)
5600      Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5601 {
5602   FRAME_PTR f = SELECTED_FRAME ();
5603   char *fn;
5604   Lisp_Object file = Qnil;
5605   Lisp_Object decoded_file;
5606   int count = SPECPDL_INDEX ();
5607   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5608   char *cdef_file;
5609 
5610   check_x ();
5611 
5612   GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5613 
5614   if (popup_activated ())
5615     error ("Trying to use a menu from within a menu-entry");
5616 
5617   CHECK_STRING (prompt);
5618   CHECK_STRING (dir);
5619 
5620   /* Prevent redisplay.  */
5621   specbind (Qinhibit_redisplay, Qt);
5622   record_unwind_protect (clean_up_dialog, Qnil);
5623 
5624   BLOCK_INPUT;
5625 
5626   if (STRINGP (default_filename))
5627     cdef_file = SDATA (default_filename);
5628   else
5629     cdef_file = SDATA (dir);
5630 
5631   fn = xg_get_file_name (f, SDATA (prompt), cdef_file,
5632                          ! NILP (mustmatch),
5633                          ! NILP (only_dir_p));
5634 
5635   if (fn)
5636     {
5637       file = build_string (fn);
5638       xfree (fn);
5639     }
5640 
5641   UNBLOCK_INPUT;
5642   UNGCPRO;
5643 
5644   /* Make "Cancel" equivalent to C-g.  */
5645   if (NILP (file))
5646     Fsignal (Qquit, Qnil);
5647 
5648   decoded_file = DECODE_FILE (file);
5649 
5650   return unbind_to (count, decoded_file);
5651 }
5652 
5653 
5654 #ifdef HAVE_FREETYPE
5655 
5656 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5657        doc: /* Read a font name using a GTK font selection dialog.
5658 Return a GTK-style font string corresponding to the selection.
5659 
5660 If FRAME is omitted or nil, it defaults to the selected frame. */)
5661   (frame, ignored)
5662      Lisp_Object frame, ignored;
5663 {
5664   FRAME_PTR f = check_x_frame (frame);
5665   char *name;
5666   Lisp_Object font;
5667   Lisp_Object font_param;
5668   char *default_name = NULL;
5669   struct gcpro gcpro1, gcpro2;
5670   int count = SPECPDL_INDEX ();
5671 
5672   check_x ();
5673 
5674   if (popup_activated ())
5675     error ("Trying to use a menu from within a menu-entry");
5676 
5677   /* Prevent redisplay.  */
5678   specbind (Qinhibit_redisplay, Qt);
5679   record_unwind_protect (clean_up_dialog, Qnil);
5680 
5681   BLOCK_INPUT;
5682 
5683   GCPRO2(font_param, font);
5684 
5685   XSETFONT (font, FRAME_FONT (f));
5686   font_param = Ffont_get (font, intern (":name"));
5687   if (STRINGP (font_param))
5688     default_name = xstrdup (SDATA (font_param));
5689   else 
5690     {
5691       font_param = Fframe_parameter (frame, Qfont_param);
5692       if (STRINGP (font_param))
5693         default_name = xstrdup (SDATA (font_param));
5694     }
5695 
5696   if (default_name == NULL && x_last_font_name != NULL)
5697     default_name = xstrdup (x_last_font_name);
5698 
5699   /* Convert fontconfig names to Gtk names, i.e. remove - before number */
5700   if (default_name) 
5701     {
5702       char *p = strrchr (default_name, '-');
5703       if (p)
5704         {
5705           char *ep = p+1;
5706           while (isdigit (*ep))
5707             ++ep;
5708           if (*ep == '\0') *p = ' ';
5709         }
5710     }
5711 
5712   name = xg_get_font_name (f, default_name);
5713   xfree (default_name);
5714 
5715   if (name)
5716     {
5717       font = build_string (name);
5718       g_free (x_last_font_name);
5719       x_last_font_name = name;
5720     }
5721 
5722   UNBLOCK_INPUT;
5723 
5724   if (NILP (font))
5725     Fsignal (Qquit, Qnil);
5726 
5727   return unbind_to (count, font);
5728 }
5729 #endif /* HAVE_FREETYPE */
5730 
5731 #endif /* USE_GTK */
5732 
5733 
5734 /***********************************************************************
5735                                Keyboard
5736  ***********************************************************************/
5737 
5738 #ifdef HAVE_XKBGETKEYBOARD
5739 #include <X11/XKBlib.h>
5740 #include <X11/keysym.h>
5741 #endif
5742 
5743 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5744        Sx_backspace_delete_keys_p, 0, 1, 0,
5745        doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5746 FRAME nil means use the selected frame.
5747 Value is t if we know that both keys are present, and are mapped to the
5748 usual X keysyms.  Value is `lambda' if we cannot determine if both keys are
5749 present and mapped to the usual X keysyms.  */)
5750      (frame)
5751      Lisp_Object frame;
5752 {
5753 #ifdef HAVE_XKBGETKEYBOARD
5754   XkbDescPtr kb;
5755   struct frame *f = check_x_frame (frame);
5756   Display *dpy = FRAME_X_DISPLAY (f);
5757   Lisp_Object have_keys;
5758   int major, minor, op, event, error;
5759 
5760   BLOCK_INPUT;
5761 
5762   /* Check library version in case we're dynamically linked.  */
5763   major = XkbMajorVersion;
5764   minor = XkbMinorVersion;
5765   if (!XkbLibraryVersion (&major, &minor))
5766     {
5767       UNBLOCK_INPUT;
5768       return Qlambda;
5769     }
5770 
5771   /* Check that the server supports XKB.  */
5772   major = XkbMajorVersion;
5773   minor = XkbMinorVersion;
5774   if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
5775     {
5776       UNBLOCK_INPUT;
5777       return Qlambda;
5778     }
5779 
5780   /* In this code we check that the keyboard has physical keys with names
5781      that start with BKSP (Backspace) and DELE (Delete), and that they
5782      generate keysym XK_BackSpace and XK_Delete respectively.
5783      This function is used to test if normal-erase-is-backspace should be
5784      turned on.
5785      An alternative approach would be to just check if XK_BackSpace and
5786      XK_Delete are mapped to any key.  But if any of those are mapped to
5787      some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5788      user doesn't know about it, it is better to return false here.
5789      It is more obvious to the user what to do if she/he has two keys
5790      clearly marked with names/symbols and one key does something not
5791      expected (i.e. she/he then tries the other).
5792      The cases where Backspace/Delete is mapped to some other key combination
5793      are rare, and in those cases, normal-erase-is-backspace can be turned on
5794      manually.  */
5795 
5796   have_keys = Qnil;
5797   kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5798   if (kb)
5799     {
5800       int delete_keycode = 0, backspace_keycode = 0, i;
5801 
5802       if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5803         {
5804           for (i = kb->min_key_code;
5805                (i < kb->max_key_code
5806                 && (delete_keycode == 0 || backspace_keycode == 0));
5807                ++i)
5808             {
5809               /* The XKB symbolic key names can be seen most easily in
5810                  the PS file generated by `xkbprint -label name
5811                  $DISPLAY'.  */
5812               if (bcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5813                 delete_keycode = i;
5814               else if (bcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5815                 backspace_keycode = i;
5816             }
5817 
5818           XkbFreeNames (kb, 0, True);
5819         }
5820 
5821       XkbFreeClientMap (kb, 0, True);
5822 
5823       if (delete_keycode
5824           && backspace_keycode
5825           && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5826           && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5827         have_keys = Qt;
5828     }
5829   UNBLOCK_INPUT;
5830   return have_keys;
5831 #else /* not HAVE_XKBGETKEYBOARD */
5832   return Qlambda;
5833 #endif /* not HAVE_XKBGETKEYBOARD */
5834 }
5835 
5836 
5837 
5838 /***********************************************************************
5839                             Initialization
5840  ***********************************************************************/
5841 
5842 /* Keep this list in the same order as frame_parms in frame.c.
5843    Use 0 for unsupported frame parameters.  */
5844 
5845 frame_parm_handler x_frame_parm_handlers[] =
5846 {
5847   x_set_autoraise,
5848   x_set_autolower,
5849   x_set_background_color,
5850   x_set_border_color,
5851   x_set_border_width,
5852   x_set_cursor_color,
5853   x_set_cursor_type,
5854   x_set_font,
5855   x_set_foreground_color,
5856   x_set_icon_name,
5857   x_set_icon_type,
5858   x_set_internal_border_width,
5859   x_set_menu_bar_lines,
5860   x_set_mouse_color,
5861   x_explicitly_set_name,
5862   x_set_scroll_bar_width,
5863   x_set_title,
5864   x_set_unsplittable,
5865   x_set_vertical_scroll_bars,
5866   x_set_visibility,
5867   x_set_tool_bar_lines,
5868   x_set_scroll_bar_foreground,
5869   x_set_scroll_bar_background,
5870   x_set_screen_gamma,
5871   x_set_line_spacing,
5872   x_set_fringe_width,
5873   x_set_fringe_width,
5874   x_set_wait_for_wm,
5875   x_set_fullscreen,
5876   x_set_font_backend,
5877   x_set_alpha,
5878   x_set_sticky,
5879 };
5880 
5881 void
5882 syms_of_xfns ()
5883 {
5884   /* This is zero if not using X windows.  */
5885   x_in_use = 0;
5886 
5887   /* The section below is built by the lisp expression at the top of the file,
5888      just above where these variables are declared.  */
5889   /*&&& init symbols here &&&*/
5890   Qnone = intern_c_string ("none");
5891   staticpro (&Qnone);
5892   Qsuppress_icon = intern_c_string ("suppress-icon");
5893   staticpro (&Qsuppress_icon);
5894   Qundefined_color = intern_c_string ("undefined-color");
5895   staticpro (&Qundefined_color);
5896   Qcompound_text = intern_c_string ("compound-text");
5897   staticpro (&Qcompound_text);
5898   Qcancel_timer = intern_c_string ("cancel-timer");
5899   staticpro (&Qcancel_timer);
5900   Qfont_param = intern_c_string ("font-parameter");
5901   staticpro (&Qfont_param);
5902   /* This is the end of symbol initialization.  */
5903 
5904   /* Text property `display' should be nonsticky by default.  */
5905   Vtext_property_default_nonsticky
5906     = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
5907 
5908 
5909   Fput (Qundefined_color, Qerror_conditions,
5910         pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
5911   Fput (Qundefined_color, Qerror_message,
5912         make_pure_c_string ("Undefined color"));
5913 
5914   DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
5915     doc: /* The shape of the pointer when over text.
5916 Changing the value does not affect existing frames
5917 unless you set the mouse color.  */);
5918   Vx_pointer_shape = Qnil;
5919 
5920 #if 0 /* This doesn't really do anything.  */
5921   DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
5922     doc: /* The shape of the pointer when not over text.
5923 This variable takes effect when you create a new frame
5924 or when you set the mouse color.  */);
5925 #endif
5926   Vx_nontext_pointer_shape = Qnil;
5927 
5928   DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
5929     doc: /* The shape of the pointer when Emacs is busy.
5930 This variable takes effect when you create a new frame
5931 or when you set the mouse color.  */);
5932   Vx_hourglass_pointer_shape = Qnil;
5933 
5934 #if 0 /* This doesn't really do anything.  */
5935   DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
5936     doc: /* The shape of the pointer when over the mode line.
5937 This variable takes effect when you create a new frame
5938 or when you set the mouse color.  */);
5939 #endif
5940   Vx_mode_pointer_shape = Qnil;
5941 
5942   DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5943               &Vx_sensitive_text_pointer_shape,
5944                doc: /* The shape of the pointer when over mouse-sensitive text.
5945 This variable takes effect when you create a new frame
5946 or when you set the mouse color.  */);
5947   Vx_sensitive_text_pointer_shape = Qnil;
5948 
5949   DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5950               &Vx_window_horizontal_drag_shape,
5951   doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
5952 This variable takes effect when you create a new frame
5953 or when you set the mouse color.  */);
5954   Vx_window_horizontal_drag_shape = Qnil;
5955 
5956   DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
5957     doc: /* A string indicating the foreground color of the cursor box.  */);
5958   Vx_cursor_fore_pixel = Qnil;
5959 
5960   DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
5961     doc: /* Maximum size for tooltips.  Value is a pair (COLUMNS . ROWS).
5962 Text larger than this is clipped.  */);
5963   Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
5964 
5965   DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
5966     doc: /* Non-nil if no X window manager is in use.
5967 Emacs doesn't try to figure this out; this is always nil
5968 unless you set it to something else.  */);
5969   /* We don't have any way to find this out, so set it to nil
5970      and maybe the user would like to set it to t.  */
5971   Vx_no_window_manager = Qnil;
5972 
5973   DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5974                &Vx_pixel_size_width_font_regexp,
5975     doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5976 
5977 Since Emacs gets width of a font matching with this regexp from
5978 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5979 such a font.  This is especially effective for such large fonts as
5980 Chinese, Japanese, and Korean.  */);
5981   Vx_pixel_size_width_font_regexp = Qnil;
5982 
5983 /* This is not ifdef:ed, so other builds than GTK can customize it.  */
5984   DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog,
5985     doc: /* *Non-nil means prompt with the old GTK file selection dialog.
5986 If nil or if the file selection dialog is not available, the new GTK file
5987 chooser is used instead.  To turn off all file dialogs set the
5988 variable `use-file-dialog'.  */);
5989   x_gtk_use_old_file_dialog = 0;
5990 
5991   DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files,
5992     doc: /* *If non-nil, the GTK file chooser will by default show hidden files.
5993 Note that this is just the default, there is a toggle button on the file
5994 chooser to show or not show hidden files on a case by case basis.  */);
5995   x_gtk_show_hidden_files = 0;
5996 
5997   DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text,
5998     doc: /* *If non-nil, the GTK file chooser will show additional help text.
5999 If more space for files in the file chooser dialog is wanted, set this to nil
6000 to turn the additional text off.  */);
6001   x_gtk_file_dialog_help_text = 1;
6002 
6003   DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar,
6004     doc: /* *If non-nil, a detached tool bar is shown in full.
6005 The default is to just show an arrow and pressing on that arrow shows
6006 the tool bar buttons.  */);
6007   x_gtk_whole_detached_tool_bar = 0;
6008 
6009   Fprovide (intern_c_string ("x"), Qnil);
6010 
6011 #ifdef USE_X_TOOLKIT
6012   Fprovide (intern_c_string ("x-toolkit"), Qnil);
6013 #ifdef USE_MOTIF
6014   Fprovide (intern_c_string ("motif"), Qnil);
6015 
6016   DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
6017                doc: /* Version info for LessTif/Motif.  */);
6018   Vmotif_version_string = build_string (XmVERSION_STRING);
6019 #endif /* USE_MOTIF */
6020 #endif /* USE_X_TOOLKIT */
6021 
6022 #ifdef USE_GTK
6023   /* Provide x-toolkit also for GTK.  Internally GTK does not use Xt so it
6024      is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6025      But for a user it is a toolkit for X, and indeed, configure
6026      accepts --with-x-toolkit=gtk.  */
6027   Fprovide (intern_c_string ("x-toolkit"), Qnil);
6028   Fprovide (intern_c_string ("gtk"), Qnil);
6029 
6030   DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
6031                doc: /* Version info for GTK+.  */);
6032   {
6033     char gtk_version[40];
6034     g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
6035                 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
6036     Vgtk_version_string = make_pure_string (gtk_version, strlen (gtk_version), strlen (gtk_version), 0);
6037   }
6038 #endif /* USE_GTK */
6039 
6040   /* X window properties.  */
6041   defsubr (&Sx_change_window_property);
6042   defsubr (&Sx_delete_window_property);
6043   defsubr (&Sx_window_property);
6044 
6045   defsubr (&Sxw_display_color_p);
6046   defsubr (&Sx_display_grayscale_p);
6047   defsubr (&Sxw_color_defined_p);
6048   defsubr (&Sxw_color_values);
6049   defsubr (&Sx_server_max_request_size);
6050   defsubr (&Sx_server_vendor);
6051   defsubr (&Sx_server_version);
6052   defsubr (&Sx_display_pixel_width);
6053   defsubr (&Sx_display_pixel_height);
6054   defsubr (&Sx_display_mm_width);
6055   defsubr (&Sx_display_mm_height);
6056   defsubr (&Sx_display_screens);
6057   defsubr (&Sx_display_planes);
6058   defsubr (&Sx_display_color_cells);
6059   defsubr (&Sx_display_visual_class);
6060   defsubr (&Sx_display_backing_store);
6061   defsubr (&Sx_display_save_under);
6062   defsubr (&Sx_wm_set_size_hint);
6063   defsubr (&Sx_create_frame);
6064   defsubr (&Sx_open_connection);
6065   defsubr (&Sx_close_connection);
6066   defsubr (&Sx_display_list);
6067   defsubr (&Sx_synchronize);
6068   defsubr (&Sx_focus_frame);
6069   defsubr (&Sx_backspace_delete_keys_p);
6070 
6071   /* Setting callback functions for fontset handler.  */
6072   check_window_system_func = check_x;
6073 
6074   defsubr (&Sx_show_tip);
6075   defsubr (&Sx_hide_tip);
6076   tip_timer = Qnil;
6077   staticpro (&tip_timer);
6078   tip_frame = Qnil;
6079   staticpro (&tip_frame);
6080 
6081   last_show_tip_args = Qnil;
6082   staticpro (&last_show_tip_args);
6083 
6084   defsubr (&Sx_uses_old_gtk_dialog);
6085 #if defined (USE_MOTIF) || defined (USE_GTK)
6086   defsubr (&Sx_file_dialog);
6087 #endif
6088 
6089 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6090   defsubr (&Sx_select_font);
6091   x_last_font_name = NULL;
6092 #endif
6093 }
6094 
6095 #endif /* HAVE_X_WINDOWS */
6096 
6097 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
6098    (do not change this comment) */