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