Merge from emacs--devo--0
[emacs.git] / src / xfns.c
blobb48a5432a8665eb789c5f6766f310d3103deb1cd
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.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 #include <config.h>
23 #include <stdio.h>
24 #include <math.h>
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
30 /* This makes the fields of a Display accessible, in Xlib header files. */
32 #define XLIB_ILLEGAL_ACCESS
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 "character.h"
45 #include "charset.h"
46 #include "coding.h"
47 #include "fontset.h"
48 #include "systime.h"
49 #include "termhooks.h"
50 #include "atimer.h"
52 #ifdef USE_FONT_BACKEND
53 #include "font.h"
54 #endif /* USE_FONT_BACKEND */
56 #ifdef HAVE_X_WINDOWS
58 #include <ctype.h>
59 #include <sys/types.h>
60 #include <sys/stat.h>
62 #ifndef VMS
63 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
64 #include "bitmaps/gray.xbm"
65 #else
66 #include <X11/bitmaps/gray>
67 #endif
68 #else
69 #include "[.bitmaps]gray.xbm"
70 #endif
72 #ifdef USE_GTK
73 #include "gtkutil.h"
74 #endif
76 #ifdef USE_X_TOOLKIT
77 #include <X11/Shell.h>
79 #ifndef USE_MOTIF
80 #ifdef HAVE_XAW3D
81 #include <X11/Xaw3d/Paned.h>
82 #include <X11/Xaw3d/Label.h>
83 #else /* !HAVE_XAW3D */
84 #include <X11/Xaw/Paned.h>
85 #include <X11/Xaw/Label.h>
86 #endif /* HAVE_XAW3D */
87 #endif /* USE_MOTIF */
89 #ifdef USG
90 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
91 #include <X11/Xos.h>
92 #define USG
93 #else
94 #include <X11/Xos.h>
95 #endif
97 #include "widget.h"
99 #include "../lwlib/lwlib.h"
101 #ifdef USE_MOTIF
102 #include <Xm/Xm.h>
103 #include <Xm/DialogS.h>
104 #include <Xm/FileSB.h>
105 #endif
107 /* Do the EDITRES protocol if running X11R5
108 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
110 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
111 #define HACK_EDITRES
112 extern void _XEditResCheckMessages ();
113 #endif /* R5 + Athena */
115 /* Unique id counter for widgets created by the Lucid Widget Library. */
117 extern LWLIB_ID widget_id_tick;
119 #ifdef USE_LUCID
120 /* This is part of a kludge--see lwlib/xlwmenu.c. */
121 extern XFontStruct *xlwmenu_default_font;
122 #endif
124 extern void free_frame_menubar ();
125 extern double atof ();
127 #ifdef USE_MOTIF
129 /* LessTif/Motif version info. */
131 static Lisp_Object Vmotif_version_string;
133 #endif /* USE_MOTIF */
135 #endif /* USE_X_TOOLKIT */
137 #ifdef USE_GTK
139 /* GTK+ version info */
141 static Lisp_Object Vgtk_version_string;
143 #endif /* USE_GTK */
145 #ifdef HAVE_X11R4
146 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
147 #else
148 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
149 #endif
151 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
152 it, and including `bitmaps/gray' more than once is a problem when
153 config.h defines `static' as an empty replacement string. */
155 int gray_bitmap_width = gray_width;
156 int gray_bitmap_height = gray_height;
157 char *gray_bitmap_bits = gray_bits;
159 /* Non-zero means we're allowed to display an hourglass cursor. */
161 int display_hourglass_p;
163 /* Non-zero means prompt with the old GTK file selection dialog. */
165 int x_gtk_use_old_file_dialog;
167 /* If non-zero, by default show hidden files in the GTK file chooser. */
169 int x_gtk_show_hidden_files;
171 /* If non-zero, don't show additional help text in the GTK file chooser. */
173 int x_gtk_file_dialog_help_text;
175 /* If non-zero, don't collapse to tool bar when it is detached. */
177 int x_gtk_whole_detached_tool_bar;
179 /* The background and shape of the mouse pointer, and shape when not
180 over text or in the modeline. */
182 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
183 Lisp_Object Vx_hourglass_pointer_shape;
185 /* The shape when over mouse-sensitive text. */
187 Lisp_Object Vx_sensitive_text_pointer_shape;
189 /* If non-nil, the pointer shape to indicate that windows can be
190 dragged horizontally. */
192 Lisp_Object Vx_window_horizontal_drag_shape;
194 /* Color of chars displayed in cursor box. */
196 Lisp_Object Vx_cursor_fore_pixel;
198 /* Nonzero if using X. */
200 static int x_in_use;
202 /* Non nil if no window manager is in use. */
204 Lisp_Object Vx_no_window_manager;
206 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
208 Lisp_Object Vx_pixel_size_width_font_regexp;
210 Lisp_Object Qnone;
211 Lisp_Object Qsuppress_icon;
212 Lisp_Object Qundefined_color;
213 Lisp_Object Qcompound_text, Qcancel_timer;
215 /* In dispnew.c */
217 extern Lisp_Object Vwindow_system_version;
219 /* The below are defined in frame.c. */
221 #if GLYPH_DEBUG
222 int image_cache_refcount, dpyinfo_refcount;
223 #endif
227 /* Error if we are not connected to X. */
229 void
230 check_x ()
232 if (! x_in_use)
233 error ("X windows are not in use or not initialized");
236 /* Nonzero if we can use mouse menus.
237 You should not call this unless HAVE_MENUS is defined. */
240 have_menus_p ()
242 return x_in_use;
245 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
246 and checking validity for X. */
248 FRAME_PTR
249 check_x_frame (frame)
250 Lisp_Object frame;
252 FRAME_PTR f;
254 if (NILP (frame))
255 frame = selected_frame;
256 CHECK_LIVE_FRAME (frame);
257 f = XFRAME (frame);
258 if (! FRAME_X_P (f))
259 error ("Non-X frame used");
260 return f;
263 /* Let the user specify an X display with a frame.
264 nil stands for the selected frame--or, if that is not an X frame,
265 the first X display on the list. */
267 struct x_display_info *
268 check_x_display_info (frame)
269 Lisp_Object frame;
271 struct x_display_info *dpyinfo = NULL;
273 if (NILP (frame))
275 struct frame *sf = XFRAME (selected_frame);
277 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
278 dpyinfo = FRAME_X_DISPLAY_INFO (sf);
279 else if (x_display_list != 0)
280 dpyinfo = x_display_list;
281 else
282 error ("X windows are not in use or not initialized");
284 else if (STRINGP (frame))
285 dpyinfo = x_display_info_for_name (frame);
286 else
288 FRAME_PTR f = check_x_frame (frame);
289 dpyinfo = FRAME_X_DISPLAY_INFO (f);
292 return dpyinfo;
296 /* Return the Emacs frame-object corresponding to an X window.
297 It could be the frame's main window or an icon window. */
299 /* This function can be called during GC, so use GC_xxx type test macros. */
301 struct frame *
302 x_window_to_frame (dpyinfo, wdesc)
303 struct x_display_info *dpyinfo;
304 int wdesc;
306 Lisp_Object tail, frame;
307 struct frame *f;
309 if (wdesc == None) return 0;
311 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
313 frame = XCAR (tail);
314 if (!FRAMEP (frame))
315 continue;
316 f = XFRAME (frame);
317 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
318 continue;
319 if (f->output_data.x->hourglass_window == wdesc)
320 return f;
321 #ifdef USE_X_TOOLKIT
322 if ((f->output_data.x->edit_widget
323 && XtWindow (f->output_data.x->edit_widget) == wdesc)
324 /* A tooltip frame? */
325 || (!f->output_data.x->edit_widget
326 && FRAME_X_WINDOW (f) == wdesc)
327 || f->output_data.x->icon_desc == wdesc)
328 return f;
329 #else /* not USE_X_TOOLKIT */
330 #ifdef USE_GTK
331 if (f->output_data.x->edit_widget)
333 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
334 struct x_output *x = f->output_data.x;
335 if (gwdesc != 0 && gwdesc == x->edit_widget)
336 return f;
338 #endif /* USE_GTK */
339 if (FRAME_X_WINDOW (f) == wdesc
340 || f->output_data.x->icon_desc == wdesc)
341 return f;
342 #endif /* not USE_X_TOOLKIT */
344 return 0;
347 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
348 /* Like x_window_to_frame but also compares the window with the widget's
349 windows. */
351 struct frame *
352 x_any_window_to_frame (dpyinfo, wdesc)
353 struct x_display_info *dpyinfo;
354 int wdesc;
356 Lisp_Object tail, frame;
357 struct frame *f, *found;
358 struct x_output *x;
360 if (wdesc == None) return NULL;
362 found = NULL;
363 for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail))
365 frame = XCAR (tail);
366 if (!FRAMEP (frame))
367 continue;
369 f = XFRAME (frame);
370 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
372 /* This frame matches if the window is any of its widgets. */
373 x = f->output_data.x;
374 if (x->hourglass_window == wdesc)
375 found = f;
376 else if (x->widget)
378 #ifdef USE_GTK
379 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
380 if (gwdesc != 0
381 && (gwdesc == x->widget
382 || gwdesc == x->edit_widget
383 || gwdesc == x->vbox_widget
384 || gwdesc == x->menubar_widget))
385 found = f;
386 #else
387 if (wdesc == XtWindow (x->widget)
388 || wdesc == XtWindow (x->column_widget)
389 || wdesc == XtWindow (x->edit_widget))
390 found = f;
391 /* Match if the window is this frame's menubar. */
392 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
393 found = f;
394 #endif
396 else if (FRAME_X_WINDOW (f) == wdesc)
397 /* A tooltip frame. */
398 found = f;
402 return found;
405 /* Likewise, but exclude the menu bar widget. */
407 struct frame *
408 x_non_menubar_window_to_frame (dpyinfo, wdesc)
409 struct x_display_info *dpyinfo;
410 int wdesc;
412 Lisp_Object tail, frame;
413 struct frame *f;
414 struct x_output *x;
416 if (wdesc == None) return 0;
418 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
420 frame = XCAR (tail);
421 if (!FRAMEP (frame))
422 continue;
423 f = XFRAME (frame);
424 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
425 continue;
426 x = f->output_data.x;
427 /* This frame matches if the window is any of its widgets. */
428 if (x->hourglass_window == wdesc)
429 return f;
430 else if (x->widget)
432 #ifdef USE_GTK
433 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
434 if (gwdesc != 0
435 && (gwdesc == x->widget
436 || gwdesc == x->edit_widget
437 || gwdesc == x->vbox_widget))
438 return f;
439 #else
440 if (wdesc == XtWindow (x->widget)
441 || wdesc == XtWindow (x->column_widget)
442 || wdesc == XtWindow (x->edit_widget))
443 return f;
444 #endif
446 else if (FRAME_X_WINDOW (f) == wdesc)
447 /* A tooltip frame. */
448 return f;
450 return 0;
453 /* Likewise, but consider only the menu bar widget. */
455 struct frame *
456 x_menubar_window_to_frame (dpyinfo, wdesc)
457 struct x_display_info *dpyinfo;
458 int wdesc;
460 Lisp_Object tail, frame;
461 struct frame *f;
462 struct x_output *x;
464 if (wdesc == None) return 0;
466 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
468 frame = XCAR (tail);
469 if (!FRAMEP (frame))
470 continue;
471 f = XFRAME (frame);
472 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
473 continue;
474 x = f->output_data.x;
475 /* Match if the window is this frame's menubar. */
476 #ifdef USE_GTK
477 if (x->menubar_widget)
479 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
480 int found = 0;
482 BLOCK_INPUT;
483 if (gwdesc != 0
484 && (gwdesc == x->menubar_widget
485 || gtk_widget_get_parent (gwdesc) == x->menubar_widget))
486 found = 1;
487 UNBLOCK_INPUT;
488 if (found) return f;
490 #else
491 if (x->menubar_widget
492 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
493 return f;
494 #endif
496 return 0;
499 /* Return the frame whose principal (outermost) window is WDESC.
500 If WDESC is some other (smaller) window, we return 0. */
502 struct frame *
503 x_top_window_to_frame (dpyinfo, wdesc)
504 struct x_display_info *dpyinfo;
505 int wdesc;
507 Lisp_Object tail, frame;
508 struct frame *f;
509 struct x_output *x;
511 if (wdesc == None) return 0;
513 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
515 frame = XCAR (tail);
516 if (!FRAMEP (frame))
517 continue;
518 f = XFRAME (frame);
519 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
520 continue;
521 x = f->output_data.x;
523 if (x->widget)
525 /* This frame matches if the window is its topmost widget. */
526 #ifdef USE_GTK
527 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
528 if (gwdesc == x->widget)
529 return f;
530 #else
531 if (wdesc == XtWindow (x->widget))
532 return f;
533 #if 0 /* I don't know why it did this,
534 but it seems logically wrong,
535 and it causes trouble for MapNotify events. */
536 /* Match if the window is this frame's menubar. */
537 if (x->menubar_widget
538 && wdesc == XtWindow (x->menubar_widget))
539 return f;
540 #endif
541 #endif
543 else if (FRAME_X_WINDOW (f) == wdesc)
544 /* Tooltip frame. */
545 return f;
547 return 0;
549 #endif /* USE_X_TOOLKIT || USE_GTK */
553 static void x_default_font_parameter P_ ((struct frame *, Lisp_Object));
555 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
556 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
558 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
559 static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object));
560 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
561 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
562 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
563 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
564 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
565 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
566 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
567 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
568 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
569 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
570 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
571 void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object,
572 Lisp_Object));
573 void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object,
574 Lisp_Object));
575 static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
576 Lisp_Object,
577 Lisp_Object,
578 char *, char *,
579 int));
582 /* Store the screen positions of frame F into XPTR and YPTR.
583 These are the positions of the containing window manager window,
584 not Emacs's own window. */
586 void
587 x_real_positions (f, xptr, yptr)
588 FRAME_PTR f;
589 int *xptr, *yptr;
591 int win_x, win_y, outer_x, outer_y;
592 int real_x = 0, real_y = 0;
593 int had_errors = 0;
594 Window win = f->output_data.x->parent_desc;
596 BLOCK_INPUT;
598 x_catch_errors (FRAME_X_DISPLAY (f));
600 if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
601 win = FRAME_OUTER_WINDOW (f);
603 /* This loop traverses up the containment tree until we hit the root
604 window. Window managers may intersect many windows between our window
605 and the root window. The window we find just before the root window
606 should be the outer WM window. */
607 for (;;)
609 Window wm_window, rootw;
610 Window *tmp_children;
611 unsigned int tmp_nchildren;
612 int success;
614 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
615 &wm_window, &tmp_children, &tmp_nchildren);
617 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
619 /* Don't free tmp_children if XQueryTree failed. */
620 if (! success)
621 break;
623 XFree ((char *) tmp_children);
625 if (wm_window == rootw || had_errors)
626 break;
628 win = wm_window;
631 if (! had_errors)
633 unsigned int ign;
634 Window child, rootw;
636 /* Get the real coordinates for the WM window upper left corner */
637 XGetGeometry (FRAME_X_DISPLAY (f), win,
638 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
640 /* Translate real coordinates to coordinates relative to our
641 window. For our window, the upper left corner is 0, 0.
642 Since the upper left corner of the WM window is outside
643 our window, win_x and win_y will be negative:
645 ------------------ ---> x
646 | title |
647 | ----------------- v y
648 | | our window
650 XTranslateCoordinates (FRAME_X_DISPLAY (f),
652 /* From-window, to-window. */
653 FRAME_X_DISPLAY_INFO (f)->root_window,
654 FRAME_X_WINDOW (f),
656 /* From-position, to-position. */
657 real_x, real_y, &win_x, &win_y,
659 /* Child of win. */
660 &child);
662 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
664 outer_x = win_x;
665 outer_y = win_y;
667 else
669 XTranslateCoordinates (FRAME_X_DISPLAY (f),
671 /* From-window, to-window. */
672 FRAME_X_DISPLAY_INFO (f)->root_window,
673 FRAME_OUTER_WINDOW (f),
675 /* From-position, to-position. */
676 real_x, real_y, &outer_x, &outer_y,
678 /* Child of win. */
679 &child);
682 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
685 x_uncatch_errors ();
687 UNBLOCK_INPUT;
689 if (had_errors) return;
691 f->x_pixels_diff = -win_x;
692 f->y_pixels_diff = -win_y;
694 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
695 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
697 *xptr = real_x;
698 *yptr = real_y;
704 /* Gamma-correct COLOR on frame F. */
706 void
707 gamma_correct (f, color)
708 struct frame *f;
709 XColor *color;
711 if (f->gamma)
713 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
714 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
715 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
720 /* Decide if color named COLOR_NAME is valid for use on frame F. If
721 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
722 allocate the color. Value is zero if COLOR_NAME is invalid, or
723 no color could be allocated. */
726 x_defined_color (f, color_name, color, alloc_p)
727 struct frame *f;
728 char *color_name;
729 XColor *color;
730 int alloc_p;
732 int success_p;
733 Display *dpy = FRAME_X_DISPLAY (f);
734 Colormap cmap = FRAME_X_COLORMAP (f);
736 BLOCK_INPUT;
737 success_p = XParseColor (dpy, cmap, color_name, color);
738 if (success_p && alloc_p)
739 success_p = x_alloc_nearest_color (f, cmap, color);
740 UNBLOCK_INPUT;
742 return success_p;
746 /* Return the pixel color value for color COLOR_NAME on frame F. If F
747 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
748 Signal an error if color can't be allocated. */
751 x_decode_color (f, color_name, mono_color)
752 FRAME_PTR f;
753 Lisp_Object color_name;
754 int mono_color;
756 XColor cdef;
758 CHECK_STRING (color_name);
760 #if 0 /* Don't do this. It's wrong when we're not using the default
761 colormap, it makes freeing difficult, and it's probably not
762 an important optimization. */
763 if (strcmp (SDATA (color_name), "black") == 0)
764 return BLACK_PIX_DEFAULT (f);
765 else if (strcmp (SDATA (color_name), "white") == 0)
766 return WHITE_PIX_DEFAULT (f);
767 #endif
769 /* Return MONO_COLOR for monochrome frames. */
770 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
771 return mono_color;
773 /* x_defined_color is responsible for coping with failures
774 by looking for a near-miss. */
775 if (x_defined_color (f, SDATA (color_name), &cdef, 1))
776 return cdef.pixel;
778 signal_error ("Undefined color", color_name);
783 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
784 the previous value of that parameter, NEW_VALUE is the new value.
785 See also the comment of wait_for_wm in struct x_output. */
787 static void
788 x_set_wait_for_wm (f, new_value, old_value)
789 struct frame *f;
790 Lisp_Object new_value, old_value;
792 f->output_data.x->wait_for_wm = !NILP (new_value);
795 #ifdef USE_GTK
797 /* Set icon from FILE for frame F. By using GTK functions the icon
798 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
801 xg_set_icon (f, file)
802 FRAME_PTR f;
803 Lisp_Object file;
805 int result = 0;
806 Lisp_Object found;
808 found = x_find_image_file (file);
810 if (! NILP (found))
812 GdkPixbuf *pixbuf;
813 GError *err = NULL;
814 char *filename = (char *) SDATA (found);
815 BLOCK_INPUT;
817 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
819 if (pixbuf)
821 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
822 pixbuf);
823 g_object_unref (pixbuf);
825 result = 1;
827 else
828 g_error_free (err);
830 UNBLOCK_INPUT;
833 return result;
837 xg_set_icon_from_xpm_data (f, data)
838 FRAME_PTR f;
839 char **data;
841 int result = 0;
842 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data);
844 if (!pixbuf)
845 return 0;
847 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
848 g_object_unref (pixbuf);
849 return 1;
851 #endif /* USE_GTK */
854 /* Functions called only from `x_set_frame_param'
855 to set individual parameters.
857 If FRAME_X_WINDOW (f) is 0,
858 the frame is being created and its X-window does not exist yet.
859 In that case, just record the parameter's new value
860 in the standard place; do not attempt to change the window. */
862 void
863 x_set_foreground_color (f, arg, oldval)
864 struct frame *f;
865 Lisp_Object arg, oldval;
867 struct x_output *x = f->output_data.x;
868 unsigned long fg, old_fg;
870 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
871 old_fg = x->foreground_pixel;
872 x->foreground_pixel = fg;
874 if (FRAME_X_WINDOW (f) != 0)
876 Display *dpy = FRAME_X_DISPLAY (f);
878 BLOCK_INPUT;
879 XSetForeground (dpy, x->normal_gc, fg);
880 XSetBackground (dpy, x->reverse_gc, fg);
882 if (x->cursor_pixel == old_fg)
884 unload_color (f, x->cursor_pixel);
885 x->cursor_pixel = x_copy_color (f, fg);
886 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
889 UNBLOCK_INPUT;
891 update_face_from_frame_parameter (f, Qforeground_color, arg);
893 if (FRAME_VISIBLE_P (f))
894 redraw_frame (f);
897 unload_color (f, old_fg);
900 void
901 x_set_background_color (f, arg, oldval)
902 struct frame *f;
903 Lisp_Object arg, oldval;
905 struct x_output *x = f->output_data.x;
906 unsigned long bg;
908 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
909 unload_color (f, x->background_pixel);
910 x->background_pixel = bg;
912 if (FRAME_X_WINDOW (f) != 0)
914 Display *dpy = FRAME_X_DISPLAY (f);
916 BLOCK_INPUT;
917 XSetBackground (dpy, x->normal_gc, bg);
918 XSetForeground (dpy, x->reverse_gc, bg);
919 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
920 XSetForeground (dpy, x->cursor_gc, bg);
922 #ifdef USE_GTK
923 xg_set_background_color (f, bg);
924 #endif
926 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
927 toolkit scroll bars. */
929 Lisp_Object bar;
930 for (bar = FRAME_SCROLL_BARS (f);
931 !NILP (bar);
932 bar = XSCROLL_BAR (bar)->next)
934 Window window = SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar));
935 XSetWindowBackground (dpy, window, bg);
938 #endif /* USE_TOOLKIT_SCROLL_BARS */
940 UNBLOCK_INPUT;
941 update_face_from_frame_parameter (f, Qbackground_color, arg);
943 if (FRAME_VISIBLE_P (f))
944 redraw_frame (f);
948 void
949 x_set_mouse_color (f, arg, oldval)
950 struct frame *f;
951 Lisp_Object arg, oldval;
953 struct x_output *x = f->output_data.x;
954 Display *dpy = FRAME_X_DISPLAY (f);
955 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
956 Cursor hourglass_cursor, horizontal_drag_cursor;
957 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
958 unsigned long mask_color = x->background_pixel;
960 /* Don't let pointers be invisible. */
961 if (mask_color == pixel)
963 x_free_colors (f, &pixel, 1);
964 pixel = x_copy_color (f, x->foreground_pixel);
967 unload_color (f, x->mouse_pixel);
968 x->mouse_pixel = pixel;
970 BLOCK_INPUT;
972 /* It's not okay to crash if the user selects a screwy cursor. */
973 x_catch_errors (dpy);
975 if (!NILP (Vx_pointer_shape))
977 CHECK_NUMBER (Vx_pointer_shape);
978 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
980 else
981 cursor = XCreateFontCursor (dpy, XC_xterm);
982 x_check_errors (dpy, "bad text pointer cursor: %s");
984 if (!NILP (Vx_nontext_pointer_shape))
986 CHECK_NUMBER (Vx_nontext_pointer_shape);
987 nontext_cursor
988 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
990 else
991 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
992 x_check_errors (dpy, "bad nontext pointer cursor: %s");
994 if (!NILP (Vx_hourglass_pointer_shape))
996 CHECK_NUMBER (Vx_hourglass_pointer_shape);
997 hourglass_cursor
998 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
1000 else
1001 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
1002 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
1004 if (!NILP (Vx_mode_pointer_shape))
1006 CHECK_NUMBER (Vx_mode_pointer_shape);
1007 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
1009 else
1010 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
1011 x_check_errors (dpy, "bad modeline pointer cursor: %s");
1013 if (!NILP (Vx_sensitive_text_pointer_shape))
1015 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1016 hand_cursor
1017 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
1019 else
1020 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
1022 if (!NILP (Vx_window_horizontal_drag_shape))
1024 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1025 horizontal_drag_cursor
1026 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
1028 else
1029 horizontal_drag_cursor
1030 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
1032 /* Check and report errors with the above calls. */
1033 x_check_errors (dpy, "can't set cursor shape: %s");
1034 x_uncatch_errors ();
1037 XColor fore_color, back_color;
1039 fore_color.pixel = x->mouse_pixel;
1040 x_query_color (f, &fore_color);
1041 back_color.pixel = mask_color;
1042 x_query_color (f, &back_color);
1044 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1045 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1046 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1047 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1048 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1049 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1052 if (FRAME_X_WINDOW (f) != 0)
1053 XDefineCursor (dpy, FRAME_X_WINDOW (f), cursor);
1055 if (cursor != x->text_cursor
1056 && x->text_cursor != 0)
1057 XFreeCursor (dpy, x->text_cursor);
1058 x->text_cursor = cursor;
1060 if (nontext_cursor != x->nontext_cursor
1061 && x->nontext_cursor != 0)
1062 XFreeCursor (dpy, x->nontext_cursor);
1063 x->nontext_cursor = nontext_cursor;
1065 if (hourglass_cursor != x->hourglass_cursor
1066 && x->hourglass_cursor != 0)
1067 XFreeCursor (dpy, x->hourglass_cursor);
1068 x->hourglass_cursor = hourglass_cursor;
1070 if (mode_cursor != x->modeline_cursor
1071 && x->modeline_cursor != 0)
1072 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1073 x->modeline_cursor = mode_cursor;
1075 if (hand_cursor != x->hand_cursor
1076 && x->hand_cursor != 0)
1077 XFreeCursor (dpy, x->hand_cursor);
1078 x->hand_cursor = hand_cursor;
1080 if (horizontal_drag_cursor != x->horizontal_drag_cursor
1081 && x->horizontal_drag_cursor != 0)
1082 XFreeCursor (dpy, x->horizontal_drag_cursor);
1083 x->horizontal_drag_cursor = horizontal_drag_cursor;
1085 XFlush (dpy);
1086 UNBLOCK_INPUT;
1088 update_face_from_frame_parameter (f, Qmouse_color, arg);
1091 void
1092 x_set_cursor_color (f, arg, oldval)
1093 struct frame *f;
1094 Lisp_Object arg, oldval;
1096 unsigned long fore_pixel, pixel;
1097 int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
1098 struct x_output *x = f->output_data.x;
1100 if (!NILP (Vx_cursor_fore_pixel))
1102 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1103 WHITE_PIX_DEFAULT (f));
1104 fore_pixel_allocated_p = 1;
1106 else
1107 fore_pixel = x->background_pixel;
1109 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1110 pixel_allocated_p = 1;
1112 /* Make sure that the cursor color differs from the background color. */
1113 if (pixel == x->background_pixel)
1115 if (pixel_allocated_p)
1117 x_free_colors (f, &pixel, 1);
1118 pixel_allocated_p = 0;
1121 pixel = x->mouse_pixel;
1122 if (pixel == fore_pixel)
1124 if (fore_pixel_allocated_p)
1126 x_free_colors (f, &fore_pixel, 1);
1127 fore_pixel_allocated_p = 0;
1129 fore_pixel = x->background_pixel;
1133 unload_color (f, x->cursor_foreground_pixel);
1134 if (!fore_pixel_allocated_p)
1135 fore_pixel = x_copy_color (f, fore_pixel);
1136 x->cursor_foreground_pixel = fore_pixel;
1138 unload_color (f, x->cursor_pixel);
1139 if (!pixel_allocated_p)
1140 pixel = x_copy_color (f, pixel);
1141 x->cursor_pixel = pixel;
1143 if (FRAME_X_WINDOW (f) != 0)
1145 BLOCK_INPUT;
1146 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1147 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1148 UNBLOCK_INPUT;
1150 if (FRAME_VISIBLE_P (f))
1152 x_update_cursor (f, 0);
1153 x_update_cursor (f, 1);
1157 update_face_from_frame_parameter (f, Qcursor_color, arg);
1160 /* Set the border-color of frame F to pixel value PIX.
1161 Note that this does not fully take effect if done before
1162 F has an x-window. */
1164 void
1165 x_set_border_pixel (f, pix)
1166 struct frame *f;
1167 int pix;
1169 unload_color (f, f->output_data.x->border_pixel);
1170 f->output_data.x->border_pixel = pix;
1172 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1174 BLOCK_INPUT;
1175 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1176 (unsigned long)pix);
1177 UNBLOCK_INPUT;
1179 if (FRAME_VISIBLE_P (f))
1180 redraw_frame (f);
1184 /* Set the border-color of frame F to value described by ARG.
1185 ARG can be a string naming a color.
1186 The border-color is used for the border that is drawn by the X server.
1187 Note that this does not fully take effect if done before
1188 F has an x-window; it must be redone when the window is created.
1190 Note: this is done in two routines because of the way X10 works.
1192 Note: under X11, this is normally the province of the window manager,
1193 and so emacs' border colors may be overridden. */
1195 void
1196 x_set_border_color (f, arg, oldval)
1197 struct frame *f;
1198 Lisp_Object arg, oldval;
1200 int pix;
1202 CHECK_STRING (arg);
1203 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1204 x_set_border_pixel (f, pix);
1205 update_face_from_frame_parameter (f, Qborder_color, arg);
1209 void
1210 x_set_cursor_type (f, arg, oldval)
1211 FRAME_PTR f;
1212 Lisp_Object arg, oldval;
1214 set_frame_cursor_types (f, arg);
1216 /* Make sure the cursor gets redrawn. */
1217 cursor_type_changed = 1;
1220 void
1221 x_set_icon_type (f, arg, oldval)
1222 struct frame *f;
1223 Lisp_Object arg, oldval;
1225 int result;
1227 if (STRINGP (arg))
1229 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1230 return;
1232 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1233 return;
1235 BLOCK_INPUT;
1236 if (NILP (arg))
1237 result = x_text_icon (f,
1238 (char *) SDATA ((!NILP (f->icon_name)
1239 ? f->icon_name
1240 : f->name)));
1241 else
1242 result = x_bitmap_icon (f, arg);
1244 if (result)
1246 UNBLOCK_INPUT;
1247 error ("No icon window available");
1250 XFlush (FRAME_X_DISPLAY (f));
1251 UNBLOCK_INPUT;
1254 void
1255 x_set_icon_name (f, arg, oldval)
1256 struct frame *f;
1257 Lisp_Object arg, oldval;
1259 int result;
1261 if (STRINGP (arg))
1263 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1264 return;
1266 else if (!NILP (arg) || NILP (oldval))
1267 return;
1269 f->icon_name = arg;
1271 if (f->output_data.x->icon_bitmap != 0)
1272 return;
1274 BLOCK_INPUT;
1276 result = x_text_icon (f,
1277 (char *) SDATA ((!NILP (f->icon_name)
1278 ? f->icon_name
1279 : !NILP (f->title)
1280 ? f->title
1281 : f->name)));
1283 if (result)
1285 UNBLOCK_INPUT;
1286 error ("No icon window available");
1289 XFlush (FRAME_X_DISPLAY (f));
1290 UNBLOCK_INPUT;
1294 void
1295 x_set_menu_bar_lines (f, value, oldval)
1296 struct frame *f;
1297 Lisp_Object value, oldval;
1299 int nlines;
1300 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1301 int olines = FRAME_MENU_BAR_LINES (f);
1302 #endif
1304 /* Right now, menu bars don't work properly in minibuf-only frames;
1305 most of the commands try to apply themselves to the minibuffer
1306 frame itself, and get an error because you can't switch buffers
1307 in or split the minibuffer window. */
1308 if (FRAME_MINIBUF_ONLY_P (f))
1309 return;
1311 if (INTEGERP (value))
1312 nlines = XINT (value);
1313 else
1314 nlines = 0;
1316 /* Make sure we redisplay all windows in this frame. */
1317 windows_or_buffers_changed++;
1319 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1320 FRAME_MENU_BAR_LINES (f) = 0;
1321 if (nlines)
1323 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1324 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1325 /* Make sure next redisplay shows the menu bar. */
1326 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1328 else
1330 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1331 free_frame_menubar (f);
1332 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1333 if (FRAME_X_P (f))
1334 f->output_data.x->menubar_widget = 0;
1336 #else /* not USE_X_TOOLKIT && not USE_GTK */
1337 FRAME_MENU_BAR_LINES (f) = nlines;
1338 change_window_heights (f->root_window, nlines - olines);
1339 #endif /* not USE_X_TOOLKIT */
1340 adjust_glyphs (f);
1344 /* Set the number of lines used for the tool bar of frame F to VALUE.
1345 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1346 is the old number of tool bar lines. This function changes the
1347 height of all windows on frame F to match the new tool bar height.
1348 The frame's height doesn't change. */
1350 void
1351 x_set_tool_bar_lines (f, value, oldval)
1352 struct frame *f;
1353 Lisp_Object value, oldval;
1355 int delta, nlines, root_height;
1356 Lisp_Object root_window;
1358 /* Treat tool bars like menu bars. */
1359 if (FRAME_MINIBUF_ONLY_P (f))
1360 return;
1362 /* Use VALUE only if an integer >= 0. */
1363 if (INTEGERP (value) && XINT (value) >= 0)
1364 nlines = XFASTINT (value);
1365 else
1366 nlines = 0;
1368 #ifdef USE_GTK
1369 FRAME_TOOL_BAR_LINES (f) = 0;
1370 if (nlines)
1372 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1373 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1374 /* Make sure next redisplay shows the tool bar. */
1375 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1376 update_frame_tool_bar (f);
1378 else
1380 if (FRAME_EXTERNAL_TOOL_BAR (f))
1381 free_frame_tool_bar (f);
1382 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1385 return;
1386 #endif
1388 /* Make sure we redisplay all windows in this frame. */
1389 ++windows_or_buffers_changed;
1391 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1393 /* Don't resize the tool-bar to more than we have room for. */
1394 root_window = FRAME_ROOT_WINDOW (f);
1395 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1396 if (root_height - delta < 1)
1398 delta = root_height - 1;
1399 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1402 FRAME_TOOL_BAR_LINES (f) = nlines;
1403 change_window_heights (root_window, delta);
1404 adjust_glyphs (f);
1406 /* We also have to make sure that the internal border at the top of
1407 the frame, below the menu bar or tool bar, is redrawn when the
1408 tool bar disappears. This is so because the internal border is
1409 below the tool bar if one is displayed, but is below the menu bar
1410 if there isn't a tool bar. The tool bar draws into the area
1411 below the menu bar. */
1412 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1414 updating_frame = f;
1415 clear_frame ();
1416 clear_current_matrices (f);
1417 updating_frame = NULL;
1420 /* If the tool bar gets smaller, the internal border below it
1421 has to be cleared. It was formerly part of the display
1422 of the larger tool bar, and updating windows won't clear it. */
1423 if (delta < 0)
1425 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1426 int width = FRAME_PIXEL_WIDTH (f);
1427 int y = nlines * FRAME_LINE_HEIGHT (f);
1429 /* height can be zero here. */
1430 if (height > 0 && width > 0)
1432 BLOCK_INPUT;
1433 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1434 0, y, width, height, False);
1435 UNBLOCK_INPUT;
1438 if (WINDOWP (f->tool_bar_window))
1439 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1444 /* Set the foreground color for scroll bars on frame F to VALUE.
1445 VALUE should be a string, a color name. If it isn't a string or
1446 isn't a valid color name, do nothing. OLDVAL is the old value of
1447 the frame parameter. */
1449 void
1450 x_set_scroll_bar_foreground (f, value, oldval)
1451 struct frame *f;
1452 Lisp_Object value, oldval;
1454 unsigned long pixel;
1456 if (STRINGP (value))
1457 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1458 else
1459 pixel = -1;
1461 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1462 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1464 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1465 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1467 /* Remove all scroll bars because they have wrong colors. */
1468 if (condemn_scroll_bars_hook)
1469 (*condemn_scroll_bars_hook) (f);
1470 if (judge_scroll_bars_hook)
1471 (*judge_scroll_bars_hook) (f);
1473 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1474 redraw_frame (f);
1479 /* Set the background color for scroll bars on frame F to VALUE VALUE
1480 should be a string, a color name. If it isn't a string or isn't a
1481 valid color name, do nothing. OLDVAL is the old value of the frame
1482 parameter. */
1484 void
1485 x_set_scroll_bar_background (f, value, oldval)
1486 struct frame *f;
1487 Lisp_Object value, oldval;
1489 unsigned long pixel;
1491 if (STRINGP (value))
1492 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1493 else
1494 pixel = -1;
1496 if (f->output_data.x->scroll_bar_background_pixel != -1)
1497 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1499 #ifdef USE_TOOLKIT_SCROLL_BARS
1500 /* Scrollbar shadow colors. */
1501 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1503 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1504 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1506 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1508 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1509 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1511 #endif /* USE_TOOLKIT_SCROLL_BARS */
1513 f->output_data.x->scroll_bar_background_pixel = pixel;
1514 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1516 /* Remove all scroll bars because they have wrong colors. */
1517 if (condemn_scroll_bars_hook)
1518 (*condemn_scroll_bars_hook) (f);
1519 if (judge_scroll_bars_hook)
1520 (*judge_scroll_bars_hook) (f);
1522 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1523 redraw_frame (f);
1528 /* Encode Lisp string STRING as a text in a format appropriate for
1529 XICCC (X Inter Client Communication Conventions).
1531 This can call Lisp code, so callers must GCPRO.
1533 If STRING contains only ASCII characters, do no conversion and
1534 return the string data of STRING. Otherwise, encode the text by
1535 CODING_SYSTEM, and return a newly allocated memory area which
1536 should be freed by `xfree' by a caller.
1538 SELECTIONP non-zero means the string is being encoded for an X
1539 selection, so it is safe to run pre-write conversions (which
1540 may run Lisp code).
1542 Store the byte length of resulting text in *TEXT_BYTES.
1544 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1545 which means that the `encoding' of the result can be `STRING'.
1546 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1547 the result should be `COMPOUND_TEXT'. */
1549 static unsigned char *
1550 x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep)
1551 Lisp_Object string, coding_system;
1552 int *text_bytes, *stringp;
1553 int selectionp;
1554 int *freep;
1556 int result = string_xstring_p (string);
1557 struct coding_system coding;
1559 if (result == 0)
1561 /* No multibyte character in OBJ. We need not encode it. */
1562 *text_bytes = SBYTES (string);
1563 *stringp = 1;
1564 *freep = 0;
1565 return SDATA (string);
1568 setup_coding_system (coding_system, &coding);
1569 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1570 /* We suppress producing escape sequences for composition. */
1571 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1572 coding.dst_bytes = SCHARS (string) * 2;
1573 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
1574 encode_coding_object (&coding, string, 0, 0,
1575 SCHARS (string), SBYTES (string), Qnil);
1576 *text_bytes = coding.produced;
1577 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1578 *freep = 1;
1579 return coding.destination;
1583 /* Set the WM name to NAME for frame F. Also set the icon name.
1584 If the frame already has an icon name, use that, otherwise set the
1585 icon name to NAME. */
1587 static void
1588 x_set_name_internal (f, name)
1589 FRAME_PTR f;
1590 Lisp_Object name;
1592 if (FRAME_X_WINDOW (f))
1594 BLOCK_INPUT;
1595 #ifdef HAVE_X11R4
1597 XTextProperty text, icon;
1598 int bytes, stringp;
1599 int do_free_icon_value = 0, do_free_text_value = 0;
1600 Lisp_Object coding_system;
1601 #ifdef USE_GTK
1602 Lisp_Object encoded_name;
1603 struct gcpro gcpro1;
1605 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1606 we use it before x_encode_text that may return string data. */
1607 GCPRO1 (name);
1608 encoded_name = ENCODE_UTF_8 (name);
1609 UNGCPRO;
1610 #endif
1612 coding_system = Qcompound_text;
1613 /* Note: Encoding strategy
1615 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1616 text.encoding. But, there are non-internationalized window
1617 managers which don't support that encoding. So, if NAME
1618 contains only ASCII and 8859-1 characters, encode it by
1619 iso-latin-1, and use "STRING" in text.encoding hoping that
1620 such window managers at least analyze this format correctly,
1621 i.e. treat 8-bit bytes as 8859-1 characters.
1623 We may also be able to use "UTF8_STRING" in text.encoding
1624 in the future which can encode all Unicode characters.
1625 But, for the moment, there's no way to know that the
1626 current window manager supports it or not. */
1627 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1628 &do_free_text_value);
1629 text.encoding = (stringp ? XA_STRING
1630 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1631 text.format = 8;
1632 text.nitems = bytes;
1634 if (!STRINGP (f->icon_name))
1636 icon = text;
1638 else
1640 /* See the above comment "Note: Encoding strategy". */
1641 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1642 &bytes, &stringp, &do_free_icon_value);
1643 icon.encoding = (stringp ? XA_STRING
1644 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1645 icon.format = 8;
1646 icon.nitems = bytes;
1649 #ifdef USE_GTK
1650 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1651 (char *) SDATA (encoded_name));
1652 #else /* not USE_GTK */
1653 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1654 #endif /* not USE_GTK */
1656 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1658 if (do_free_icon_value)
1659 xfree (icon.value);
1660 if (do_free_text_value)
1661 xfree (text.value);
1663 #else /* not HAVE_X11R4 */
1664 XSetIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1665 SDATA (name));
1666 XStoreName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1667 SDATA (name));
1668 #endif /* not HAVE_X11R4 */
1669 UNBLOCK_INPUT;
1673 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1674 x_id_name.
1676 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1677 name; if NAME is a string, set F's name to NAME and set
1678 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1680 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1681 suggesting a new name, which lisp code should override; if
1682 F->explicit_name is set, ignore the new name; otherwise, set it. */
1684 void
1685 x_set_name (f, name, explicit)
1686 struct frame *f;
1687 Lisp_Object name;
1688 int explicit;
1690 /* Make sure that requests from lisp code override requests from
1691 Emacs redisplay code. */
1692 if (explicit)
1694 /* If we're switching from explicit to implicit, we had better
1695 update the mode lines and thereby update the title. */
1696 if (f->explicit_name && NILP (name))
1697 update_mode_lines = 1;
1699 f->explicit_name = ! NILP (name);
1701 else if (f->explicit_name)
1702 return;
1704 /* If NAME is nil, set the name to the x_id_name. */
1705 if (NILP (name))
1707 /* Check for no change needed in this very common case
1708 before we do any consing. */
1709 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1710 SDATA (f->name)))
1711 return;
1712 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1714 else
1715 CHECK_STRING (name);
1717 /* Don't change the name if it's already NAME. */
1718 if (! NILP (Fstring_equal (name, f->name)))
1719 return;
1721 f->name = name;
1723 /* For setting the frame title, the title parameter should override
1724 the name parameter. */
1725 if (! NILP (f->title))
1726 name = f->title;
1728 x_set_name_internal (f, name);
1731 /* This function should be called when the user's lisp code has
1732 specified a name for the frame; the name will override any set by the
1733 redisplay code. */
1734 void
1735 x_explicitly_set_name (f, arg, oldval)
1736 FRAME_PTR f;
1737 Lisp_Object arg, oldval;
1739 x_set_name (f, arg, 1);
1742 /* This function should be called by Emacs redisplay code to set the
1743 name; names set this way will never override names set by the user's
1744 lisp code. */
1745 void
1746 x_implicitly_set_name (f, arg, oldval)
1747 FRAME_PTR f;
1748 Lisp_Object arg, oldval;
1750 x_set_name (f, arg, 0);
1753 /* Change the title of frame F to NAME.
1754 If NAME is nil, use the frame name as the title.
1756 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1757 name; if NAME is a string, set F's name to NAME and set
1758 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1760 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1761 suggesting a new name, which lisp code should override; if
1762 F->explicit_name is set, ignore the new name; otherwise, set it. */
1764 void
1765 x_set_title (f, name, old_name)
1766 struct frame *f;
1767 Lisp_Object name, old_name;
1769 /* Don't change the title if it's already NAME. */
1770 if (EQ (name, f->title))
1771 return;
1773 update_mode_lines = 1;
1775 f->title = name;
1777 if (NILP (name))
1778 name = f->name;
1779 else
1780 CHECK_STRING (name);
1782 x_set_name_internal (f, name);
1785 void
1786 x_set_scroll_bar_default_width (f)
1787 struct frame *f;
1789 int wid = FRAME_COLUMN_WIDTH (f);
1791 #ifdef USE_TOOLKIT_SCROLL_BARS
1792 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1793 int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1794 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1795 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1796 #else
1797 /* Make the actual width at least 14 pixels and a multiple of a
1798 character width. */
1799 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1801 /* Use all of that space (aside from required margins) for the
1802 scroll bar. */
1803 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1804 #endif
1808 /* Record in frame F the specified or default value according to ALIST
1809 of the parameter named PROP (a Lisp symbol). If no value is
1810 specified for PROP, look for an X default for XPROP on the frame
1811 named NAME. If that is not found either, use the value DEFLT. */
1813 static Lisp_Object
1814 x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
1815 foreground_p)
1816 struct frame *f;
1817 Lisp_Object alist;
1818 Lisp_Object prop;
1819 char *xprop;
1820 char *xclass;
1821 int foreground_p;
1823 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1824 Lisp_Object tem;
1826 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1827 if (EQ (tem, Qunbound))
1829 #ifdef USE_TOOLKIT_SCROLL_BARS
1831 /* See if an X resource for the scroll bar color has been
1832 specified. */
1833 tem = display_x_get_resource (dpyinfo,
1834 build_string (foreground_p
1835 ? "foreground"
1836 : "background"),
1837 empty_unibyte_string,
1838 build_string ("verticalScrollBar"),
1839 empty_unibyte_string);
1840 if (!STRINGP (tem))
1842 /* If nothing has been specified, scroll bars will use a
1843 toolkit-dependent default. Because these defaults are
1844 difficult to get at without actually creating a scroll
1845 bar, use nil to indicate that no color has been
1846 specified. */
1847 tem = Qnil;
1850 #else /* not USE_TOOLKIT_SCROLL_BARS */
1852 tem = Qnil;
1854 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1857 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1858 return tem;
1863 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
1865 Status
1866 XSetWMProtocols (dpy, w, protocols, count)
1867 Display *dpy;
1868 Window w;
1869 Atom *protocols;
1870 int count;
1872 Atom prop;
1873 prop = XInternAtom (dpy, "WM_PROTOCOLS", False);
1874 if (prop == None) return False;
1875 XChangeProperty (dpy, w, prop, XA_ATOM, 32, PropModeReplace,
1876 (unsigned char *) protocols, count);
1877 return True;
1879 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
1881 #ifdef USE_X_TOOLKIT
1883 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1884 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1885 already be present because of the toolkit (Motif adds some of them,
1886 for example, but Xt doesn't). */
1888 static void
1889 hack_wm_protocols (f, widget)
1890 FRAME_PTR f;
1891 Widget widget;
1893 Display *dpy = XtDisplay (widget);
1894 Window w = XtWindow (widget);
1895 int need_delete = 1;
1896 int need_focus = 1;
1897 int need_save = 1;
1899 BLOCK_INPUT;
1901 Atom type;
1902 unsigned char *catoms;
1903 int format = 0;
1904 unsigned long nitems = 0;
1905 unsigned long bytes_after;
1907 if ((XGetWindowProperty (dpy, w,
1908 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1909 (long)0, (long)100, False, XA_ATOM,
1910 &type, &format, &nitems, &bytes_after,
1911 &catoms)
1912 == Success)
1913 && format == 32 && type == XA_ATOM)
1915 Atom *atoms = (Atom *) catoms;
1916 while (nitems > 0)
1918 nitems--;
1919 if (atoms[nitems]
1920 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1921 need_delete = 0;
1922 else if (atoms[nitems]
1923 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1924 need_focus = 0;
1925 else if (atoms[nitems]
1926 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1927 need_save = 0;
1930 if (catoms)
1931 XFree (catoms);
1934 Atom props [10];
1935 int count = 0;
1936 if (need_delete)
1937 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1938 if (need_focus)
1939 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1940 if (need_save)
1941 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1942 if (count)
1943 XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1944 XA_ATOM, 32, PropModeAppend,
1945 (unsigned char *) props, count);
1947 UNBLOCK_INPUT;
1949 #endif
1953 /* Support routines for XIC (X Input Context). */
1955 #ifdef HAVE_X_I18N
1957 static XFontSet xic_create_xfontset P_ ((struct frame *, char *));
1958 static XFontSet xic_create_xfontset2 P_ ((struct frame *));
1959 static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *));
1962 /* Supported XIM styles, ordered by preference. */
1964 static XIMStyle supported_xim_styles[] =
1966 XIMPreeditPosition | XIMStatusArea,
1967 XIMPreeditPosition | XIMStatusNothing,
1968 XIMPreeditPosition | XIMStatusNone,
1969 XIMPreeditNothing | XIMStatusArea,
1970 XIMPreeditNothing | XIMStatusNothing,
1971 XIMPreeditNothing | XIMStatusNone,
1972 XIMPreeditNone | XIMStatusArea,
1973 XIMPreeditNone | XIMStatusNothing,
1974 XIMPreeditNone | XIMStatusNone,
1979 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1981 char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1983 /* Create an Xt fontset spec from the name of a base font.
1984 If `motif' is True use the Motif syntax. */
1985 char *
1986 xic_create_fontsetname (base_fontname, motif)
1987 char *base_fontname;
1988 Bool motif;
1990 const char *sep = motif ? ";" : ",";
1991 char *fontsetname;
1993 /* Make a fontset name from the base font name. */
1994 if (xic_defaut_fontset == base_fontname)
1995 { /* There is no base font name, use the default. */
1996 int len = strlen (base_fontname) + 2;
1997 fontsetname = xmalloc (len);
1998 bzero (fontsetname, len);
1999 strcpy (fontsetname, base_fontname);
2001 else
2003 /* Make a fontset name from the base font name.
2004 The font set will be made of the following elements:
2005 - the base font.
2006 - the base font where the charset spec is replaced by -*-*.
2007 - the same but with the family also replaced with -*-*-. */
2008 char *p = base_fontname;
2009 int i;
2011 for (i = 0; *p; p++)
2012 if (*p == '-') i++;
2013 if (i != 14)
2014 { /* As the font name doesn't conform to XLFD, we can't
2015 modify it to generalize it to allcs and allfamilies.
2016 Use the specified font plus the default. */
2017 int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3;
2018 fontsetname = xmalloc (len);
2019 bzero (fontsetname, len);
2020 strcpy (fontsetname, base_fontname);
2021 strcat (fontsetname, sep);
2022 strcat (fontsetname, xic_defaut_fontset);
2024 else
2026 int len;
2027 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
2028 char *font_allcs = NULL;
2029 char *font_allfamilies = NULL;
2030 char *font_all = NULL;
2031 char *allcs = "*-*-*-*-*-*-*";
2032 char *allfamilies = "-*-*-";
2033 char *all = "*-*-*-*-";
2034 char *base;
2036 for (i = 0, p = base_fontname; i < 8; p++)
2038 if (*p == '-')
2040 i++;
2041 if (i == 3)
2042 p1 = p + 1;
2043 else if (i == 7)
2044 p2 = p + 1;
2045 else if (i == 6)
2046 p3 = p + 1;
2049 /* If base_fontname specifies ADSTYLE, make it a
2050 wildcard. */
2051 if (*p3 != '*')
2053 int diff = (p2 - p3) - 2;
2055 base = alloca (strlen (base_fontname) + 1);
2056 bcopy (base_fontname, base, p3 - base_fontname);
2057 base[p3 - base_fontname] = '*';
2058 base[(p3 - base_fontname) + 1] = '-';
2059 strcpy (base + (p3 - base_fontname) + 2, p2);
2060 p = base + (p - base_fontname) - diff;
2061 p1 = base + (p1 - base_fontname);
2062 p2 = base + (p2 - base_fontname) - diff;
2063 base_fontname = base;
2066 /* Build the font spec that matches all charsets. */
2067 len = p - base_fontname + strlen (allcs) + 1;
2068 font_allcs = (char *) alloca (len);
2069 bzero (font_allcs, len);
2070 bcopy (base_fontname, font_allcs, p - base_fontname);
2071 strcat (font_allcs, allcs);
2073 /* Build the font spec that matches all families and
2074 add-styles. */
2075 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
2076 font_allfamilies = (char *) alloca (len);
2077 bzero (font_allfamilies, len);
2078 strcpy (font_allfamilies, allfamilies);
2079 bcopy (p1, font_allfamilies + strlen (allfamilies), p - p1);
2080 strcat (font_allfamilies, allcs);
2082 /* Build the font spec that matches all. */
2083 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
2084 font_all = (char *) alloca (len);
2085 bzero (font_all, len);
2086 strcpy (font_all, allfamilies);
2087 strcat (font_all, all);
2088 bcopy (p2, font_all + strlen (all) + strlen (allfamilies), p - p2);
2089 strcat (font_all, allcs);
2091 /* Build the actual font set name. */
2092 len = strlen (base_fontname) + strlen (font_allcs)
2093 + strlen (font_allfamilies) + strlen (font_all) + 5;
2094 fontsetname = xmalloc (len);
2095 bzero (fontsetname, len);
2096 strcpy (fontsetname, base_fontname);
2097 strcat (fontsetname, sep);
2098 strcat (fontsetname, font_allcs);
2099 strcat (fontsetname, sep);
2100 strcat (fontsetname, font_allfamilies);
2101 strcat (fontsetname, sep);
2102 strcat (fontsetname, font_all);
2105 if (motif)
2106 strcat (fontsetname, ":");
2107 return fontsetname;
2110 #ifdef DEBUG_XIC_FONTSET
2111 static void
2112 print_fontset_result (xfs, name, missing_list, missing_count)
2113 XFontSet xfs;
2114 char *name;
2115 char **missing_list;
2116 int missing_count;
2118 if (xfs)
2119 fprintf (stderr, "XIC Fontset created: %s\n", name);
2120 else
2122 fprintf (stderr, "XIC Fontset failed: %s\n", name);
2123 while (missing_count-- > 0)
2125 fprintf (stderr, " missing: %s\n", *missing_list);
2126 missing_list++;
2131 #endif
2133 static XFontSet
2134 xic_create_xfontset (f, base_fontname)
2135 struct frame *f;
2136 char *base_fontname;
2138 XFontSet xfs = NULL;
2139 char **missing_list = NULL;
2140 int missing_count;
2141 char *def_string;
2142 Lisp_Object rest, frame;
2144 if (!base_fontname)
2145 base_fontname = xic_defaut_fontset;
2147 /* See if there is another frame already using same fontset. */
2148 FOR_EACH_FRAME (rest, frame)
2150 struct frame *cf = XFRAME (frame);
2151 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2152 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2153 && FRAME_XIC_BASE_FONTNAME (cf)
2154 && !strcmp (FRAME_XIC_BASE_FONTNAME (cf), base_fontname))
2156 xfs = FRAME_XIC_FONTSET (cf);
2157 break;
2161 if (!xfs)
2163 char *fontsetname = xic_create_fontsetname (base_fontname, False);
2165 /* New fontset. */
2166 xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
2167 fontsetname, &missing_list,
2168 &missing_count, &def_string);
2169 #ifdef DEBUG_XIC_FONTSET
2170 print_fontset_result (xfs, fontsetname, missing_list, missing_count);
2171 #endif
2172 if (missing_list)
2173 XFreeStringList (missing_list);
2174 if (! xfs)
2176 /* FONTSETNAME contains a list of font names (specific fonts
2177 first, general fonts last), but giving that to
2178 XCreateFontSet at once occasionally fails (bug of X?).
2179 So, we try to call XCreateFontSet for each fontname. */
2180 char *p0 = fontsetname, *p1;
2182 while (p0)
2184 p1 = strchr (p0, ',');
2185 if (p1)
2186 *p1 = '\0';
2187 xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
2188 p0, &missing_list,
2189 &missing_count, &def_string);
2190 #ifdef DEBUG_XIC_FONTSET
2191 print_fontset_result (xfs, p0, missing_list, missing_count);
2192 #endif
2193 if (missing_list)
2194 XFreeStringList (missing_list);
2195 if (xfs)
2196 break;
2197 p0 = p1 ? p1 + 1 : NULL;
2200 xfree (fontsetname);
2201 if (! xfs && base_fontname != xic_defaut_fontset)
2203 /* Try the default fontset name at a last resort. */
2204 fontsetname = xic_create_fontsetname (xic_defaut_fontset, False);
2205 xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
2206 fontsetname, &missing_list,
2207 &missing_count, &def_string);
2208 #ifdef DEBUG_XIC_FONTSET
2209 print_fontset_result (xfs, fontsetname, missing_list, missing_count);
2210 #endif
2211 if (missing_list)
2212 XFreeStringList (missing_list);
2213 xfree (fontsetname);
2217 if (FRAME_XIC_BASE_FONTNAME (f))
2218 xfree (FRAME_XIC_BASE_FONTNAME (f));
2219 FRAME_XIC_BASE_FONTNAME (f) = xstrdup (base_fontname);
2221 /* No need to free def_string. */
2222 return xfs;
2225 #ifdef USE_FONT_BACKEND
2227 static XFontSet
2228 xic_create_xfontset2 (f)
2229 struct frame *f;
2231 XFontSet xfs = NULL;
2232 struct font *font = FRAME_FONT_OBJECT (f);
2233 int pixel_size = font->pixel_size;
2234 Lisp_Object rest, frame;
2236 /* See if there is another frame already using same fontset. */
2237 FOR_EACH_FRAME (rest, frame)
2239 struct frame *cf = XFRAME (frame);
2241 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2242 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2243 && FRAME_FONT_OBJECT (f)
2244 && FRAME_FONT_OBJECT (f)->pixel_size == pixel_size)
2246 xfs = FRAME_XIC_FONTSET (cf);
2247 break;
2251 if (! xfs)
2253 char buf[256];
2254 char **missing_list;
2255 int missing_count;
2256 char *def_string;
2257 char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
2259 sprintf (buf, xlfd_format, pixel_size);
2260 missing_list = NULL;
2261 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2262 &missing_list, &missing_count, &def_string);
2263 #ifdef DEBUG_XIC_FONTSET
2264 print_fontset_result (xfs, buf, missing_list, missing_count);
2265 #endif
2266 if (missing_list)
2267 XFreeStringList (missing_list);
2268 if (! xfs)
2270 /* List of pixel sizes most likely available. Find one that
2271 is closest to pixel_size. */
2272 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2273 int *smaller, *larger;
2275 for (smaller = sizes; smaller[1]; smaller++)
2276 if (smaller[1] >= pixel_size)
2277 break;
2278 larger = smaller + 1;
2279 if (*larger == pixel_size)
2280 larger++;
2281 while (*smaller || *larger)
2283 int this_size;
2285 if (! *larger)
2286 this_size = *smaller--;
2287 else if (! *smaller)
2288 this_size = *larger++;
2289 else if (pixel_size - *smaller < *larger - pixel_size)
2290 this_size = *smaller--;
2291 else
2292 this_size = *larger++;
2293 sprintf (buf, xlfd_format, this_size);
2294 missing_list = NULL;
2295 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2296 &missing_list, &missing_count, &def_string);
2297 #ifdef DEBUG_XIC_FONTSET
2298 print_fontset_result (xfs, buf, missing_list, missing_count);
2299 #endif
2300 if (missing_list)
2301 XFreeStringList (missing_list);
2302 if (xfs)
2303 break;
2306 if (! xfs)
2308 char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
2310 missing_list = NULL;
2311 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
2312 &missing_list, &missing_count, &def_string);
2313 #ifdef DEBUG_XIC_FONTSET
2314 print_fontset_result (xfs, last_resort, missing_list, missing_count);
2315 #endif
2316 if (missing_list)
2317 XFreeStringList (missing_list);
2322 return xfs;
2324 #endif /* USE_FONT_BACKEND */
2326 /* Free the X fontset of frame F if it is the last frame using it. */
2328 void
2329 xic_free_xfontset (f)
2330 struct frame *f;
2332 Lisp_Object rest, frame;
2333 int shared_p = 0;
2335 if (!FRAME_XIC_FONTSET (f))
2336 return;
2338 /* See if there is another frame sharing the same fontset. */
2339 FOR_EACH_FRAME (rest, frame)
2341 struct frame *cf = XFRAME (frame);
2342 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2343 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2344 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
2346 shared_p = 1;
2347 break;
2351 if (!shared_p)
2352 /* The fontset is not used anymore. It is safe to free it. */
2353 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2355 if (FRAME_XIC_BASE_FONTNAME (f))
2356 xfree (FRAME_XIC_BASE_FONTNAME (f));
2357 FRAME_XIC_BASE_FONTNAME (f) = NULL;
2358 FRAME_XIC_FONTSET (f) = NULL;
2362 /* Value is the best input style, given user preferences USER (already
2363 checked to be supported by Emacs), and styles supported by the
2364 input method XIM. */
2366 static XIMStyle
2367 best_xim_style (user, xim)
2368 XIMStyles *user;
2369 XIMStyles *xim;
2371 int i, j;
2373 for (i = 0; i < user->count_styles; ++i)
2374 for (j = 0; j < xim->count_styles; ++j)
2375 if (user->supported_styles[i] == xim->supported_styles[j])
2376 return user->supported_styles[i];
2378 /* Return the default style. */
2379 return XIMPreeditNothing | XIMStatusNothing;
2382 /* Create XIC for frame F. */
2384 static XIMStyle xic_style;
2386 void
2387 create_frame_xic (f)
2388 struct frame *f;
2390 XIM xim;
2391 XIC xic = NULL;
2392 XFontSet xfs = NULL;
2394 if (FRAME_XIC (f))
2395 return;
2397 /* Create X fontset. */
2398 #ifdef USE_FONT_BACKEND
2399 if (enable_font_backend)
2400 xfs = xic_create_xfontset2 (f);
2401 else
2402 #endif
2403 xfs = xic_create_xfontset
2404 (f, (FRAME_FONTSET (f) < 0) ? NULL
2405 : (char *) SDATA (fontset_ascii (FRAME_FONTSET (f))));
2407 xim = FRAME_X_XIM (f);
2408 if (xim)
2410 XRectangle s_area;
2411 XPoint spot;
2412 XVaNestedList preedit_attr;
2413 XVaNestedList status_attr;
2415 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2416 spot.x = 0; spot.y = 1;
2418 /* Determine XIC style. */
2419 if (xic_style == 0)
2421 XIMStyles supported_list;
2422 supported_list.count_styles = (sizeof supported_xim_styles
2423 / sizeof supported_xim_styles[0]);
2424 supported_list.supported_styles = supported_xim_styles;
2425 xic_style = best_xim_style (&supported_list,
2426 FRAME_X_XIM_STYLES (f));
2429 preedit_attr = XVaCreateNestedList (0,
2430 XNFontSet, xfs,
2431 XNForeground,
2432 FRAME_FOREGROUND_PIXEL (f),
2433 XNBackground,
2434 FRAME_BACKGROUND_PIXEL (f),
2435 (xic_style & XIMPreeditPosition
2436 ? XNSpotLocation
2437 : NULL),
2438 &spot,
2439 NULL);
2440 status_attr = XVaCreateNestedList (0,
2441 XNArea,
2442 &s_area,
2443 XNFontSet,
2444 xfs,
2445 XNForeground,
2446 FRAME_FOREGROUND_PIXEL (f),
2447 XNBackground,
2448 FRAME_BACKGROUND_PIXEL (f),
2449 NULL);
2451 xic = XCreateIC (xim,
2452 XNInputStyle, xic_style,
2453 XNClientWindow, FRAME_X_WINDOW (f),
2454 XNFocusWindow, FRAME_X_WINDOW (f),
2455 XNStatusAttributes, status_attr,
2456 XNPreeditAttributes, preedit_attr,
2457 NULL);
2458 XFree (preedit_attr);
2459 XFree (status_attr);
2462 FRAME_XIC (f) = xic;
2463 FRAME_XIC_STYLE (f) = xic_style;
2464 FRAME_XIC_FONTSET (f) = xfs;
2468 /* Destroy XIC and free XIC fontset of frame F, if any. */
2470 void
2471 free_frame_xic (f)
2472 struct frame *f;
2474 if (FRAME_XIC (f) == NULL)
2475 return;
2477 XDestroyIC (FRAME_XIC (f));
2478 xic_free_xfontset (f);
2480 FRAME_XIC (f) = NULL;
2484 /* Place preedit area for XIC of window W's frame to specified
2485 pixel position X/Y. X and Y are relative to window W. */
2487 void
2488 xic_set_preeditarea (w, x, y)
2489 struct window *w;
2490 int x, y;
2492 struct frame *f = XFRAME (w->frame);
2493 XVaNestedList attr;
2494 XPoint spot;
2496 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2497 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2498 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2499 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2500 XFree (attr);
2504 /* Place status area for XIC in bottom right corner of frame F.. */
2506 void
2507 xic_set_statusarea (f)
2508 struct frame *f;
2510 XIC xic = FRAME_XIC (f);
2511 XVaNestedList attr;
2512 XRectangle area;
2513 XRectangle *needed;
2515 /* Negotiate geometry of status area. If input method has existing
2516 status area, use its current size. */
2517 area.x = area.y = area.width = area.height = 0;
2518 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2519 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2520 XFree (attr);
2522 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2523 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2524 XFree (attr);
2526 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2528 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2529 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2530 XFree (attr);
2533 area.width = needed->width;
2534 area.height = needed->height;
2535 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2536 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2537 - FRAME_MENUBAR_HEIGHT (f)
2538 - FRAME_TOOLBAR_HEIGHT (f)
2539 - FRAME_INTERNAL_BORDER_WIDTH (f));
2540 XFree (needed);
2542 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2543 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2544 XFree (attr);
2548 /* Set X fontset for XIC of frame F, using base font name
2549 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2551 void
2552 xic_set_xfontset (f, base_fontname)
2553 struct frame *f;
2554 char *base_fontname;
2556 XVaNestedList attr;
2557 XFontSet xfs;
2559 xic_free_xfontset (f);
2561 #ifdef USE_FONT_BACKEND
2562 if (enable_font_backend)
2563 xfs = xic_create_xfontset2 (f);
2564 else
2565 #endif
2566 xfs = xic_create_xfontset (f, base_fontname);
2568 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2569 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2570 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2571 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2572 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2573 XFree (attr);
2575 FRAME_XIC_FONTSET (f) = xfs;
2578 #endif /* HAVE_X_I18N */
2582 #ifdef USE_X_TOOLKIT
2584 /* Create and set up the X widget for frame F. */
2586 static void
2587 x_window (f, window_prompting, minibuffer_only)
2588 struct frame *f;
2589 long window_prompting;
2590 int minibuffer_only;
2592 XClassHint class_hints;
2593 XSetWindowAttributes attributes;
2594 unsigned long attribute_mask;
2595 Widget shell_widget;
2596 Widget pane_widget;
2597 Widget frame_widget;
2598 Arg al [25];
2599 int ac;
2601 BLOCK_INPUT;
2603 /* Use the resource name as the top-level widget name
2604 for looking up resources. Make a non-Lisp copy
2605 for the window manager, so GC relocation won't bother it.
2607 Elsewhere we specify the window name for the window manager. */
2610 char *str = (char *) SDATA (Vx_resource_name);
2611 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2612 strcpy (f->namebuf, str);
2615 ac = 0;
2616 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2617 XtSetArg (al[ac], XtNinput, 1); ac++;
2618 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2619 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2620 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2621 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2622 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2623 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2624 applicationShellWidgetClass,
2625 FRAME_X_DISPLAY (f), al, ac);
2627 f->output_data.x->widget = shell_widget;
2628 /* maybe_set_screen_title_format (shell_widget); */
2630 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2631 (widget_value *) NULL,
2632 shell_widget, False,
2633 (lw_callback) NULL,
2634 (lw_callback) NULL,
2635 (lw_callback) NULL,
2636 (lw_callback) NULL);
2638 ac = 0;
2639 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2640 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2641 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2642 XtSetValues (pane_widget, al, ac);
2643 f->output_data.x->column_widget = pane_widget;
2645 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2646 the emacs screen when changing menubar. This reduces flickering. */
2648 ac = 0;
2649 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2650 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2651 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2652 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2653 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2654 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2655 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2656 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2657 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2658 al, ac);
2660 f->output_data.x->edit_widget = frame_widget;
2662 XtManageChild (frame_widget);
2664 /* Do some needed geometry management. */
2666 int len;
2667 char *tem, shell_position[32];
2668 Arg al[10];
2669 int ac = 0;
2670 int extra_borders = 0;
2671 int menubar_size
2672 = (f->output_data.x->menubar_widget
2673 ? (f->output_data.x->menubar_widget->core.height
2674 + f->output_data.x->menubar_widget->core.border_width)
2675 : 0);
2677 #if 0 /* Experimentally, we now get the right results
2678 for -geometry -0-0 without this. 24 Aug 96, rms. */
2679 if (FRAME_EXTERNAL_MENU_BAR (f))
2681 Dimension ibw = 0;
2682 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2683 menubar_size += ibw;
2685 #endif
2687 f->output_data.x->menubar_height = menubar_size;
2689 #ifndef USE_LUCID
2690 /* Motif seems to need this amount added to the sizes
2691 specified for the shell widget. The Athena/Lucid widgets don't.
2692 Both conclusions reached experimentally. -- rms. */
2693 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2694 &extra_borders, NULL);
2695 extra_borders *= 2;
2696 #endif
2698 /* Convert our geometry parameters into a geometry string
2699 and specify it.
2700 Note that we do not specify here whether the position
2701 is a user-specified or program-specified one.
2702 We pass that information later, in x_wm_set_size_hints. */
2704 int left = f->left_pos;
2705 int xneg = window_prompting & XNegative;
2706 int top = f->top_pos;
2707 int yneg = window_prompting & YNegative;
2708 if (xneg)
2709 left = -left;
2710 if (yneg)
2711 top = -top;
2713 if (window_prompting & USPosition)
2714 sprintf (shell_position, "=%dx%d%c%d%c%d",
2715 FRAME_PIXEL_WIDTH (f) + extra_borders,
2716 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2717 (xneg ? '-' : '+'), left,
2718 (yneg ? '-' : '+'), top);
2719 else
2721 sprintf (shell_position, "=%dx%d",
2722 FRAME_PIXEL_WIDTH (f) + extra_borders,
2723 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2725 /* Setting x and y when the position is not specified in
2726 the geometry string will set program position in the WM hints.
2727 If Emacs had just one program position, we could set it in
2728 fallback resources, but since each make-frame call can specify
2729 different program positions, this is easier. */
2730 XtSetArg (al[ac], XtNx, left); ac++;
2731 XtSetArg (al[ac], XtNy, top); ac++;
2735 len = strlen (shell_position) + 1;
2736 /* We don't free this because we don't know whether
2737 it is safe to free it while the frame exists.
2738 It isn't worth the trouble of arranging to free it
2739 when the frame is deleted. */
2740 tem = (char *) xmalloc (len);
2741 strncpy (tem, shell_position, len);
2742 XtSetArg (al[ac], XtNgeometry, tem); ac++;
2743 XtSetValues (shell_widget, al, ac);
2746 XtManageChild (pane_widget);
2747 XtRealizeWidget (shell_widget);
2749 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2751 validate_x_resource_name ();
2753 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2754 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2755 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2757 #ifdef HAVE_X_I18N
2758 FRAME_XIC (f) = NULL;
2759 if (use_xim)
2760 create_frame_xic (f);
2761 #endif
2763 f->output_data.x->wm_hints.input = True;
2764 f->output_data.x->wm_hints.flags |= InputHint;
2765 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2766 &f->output_data.x->wm_hints);
2768 hack_wm_protocols (f, shell_widget);
2770 #ifdef HACK_EDITRES
2771 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2772 #endif
2774 /* Do a stupid property change to force the server to generate a
2775 PropertyNotify event so that the event_stream server timestamp will
2776 be initialized to something relevant to the time we created the window.
2778 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2779 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2780 XA_ATOM, 32, PropModeAppend,
2781 (unsigned char*) NULL, 0);
2783 /* Make all the standard events reach the Emacs frame. */
2784 attributes.event_mask = STANDARD_EVENT_SET;
2786 #ifdef HAVE_X_I18N
2787 if (FRAME_XIC (f))
2789 /* XIM server might require some X events. */
2790 unsigned long fevent = NoEventMask;
2791 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2792 attributes.event_mask |= fevent;
2794 #endif /* HAVE_X_I18N */
2796 attribute_mask = CWEventMask;
2797 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2798 attribute_mask, &attributes);
2800 XtMapWidget (frame_widget);
2802 /* x_set_name normally ignores requests to set the name if the
2803 requested name is the same as the current name. This is the one
2804 place where that assumption isn't correct; f->name is set, but
2805 the X server hasn't been told. */
2807 Lisp_Object name;
2808 int explicit = f->explicit_name;
2810 f->explicit_name = 0;
2811 name = f->name;
2812 f->name = Qnil;
2813 x_set_name (f, name, explicit);
2816 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2817 f->output_data.x->text_cursor);
2819 UNBLOCK_INPUT;
2821 /* This is a no-op, except under Motif. Make sure main areas are
2822 set to something reasonable, in case we get an error later. */
2823 lw_set_main_areas (pane_widget, 0, frame_widget);
2826 #else /* not USE_X_TOOLKIT */
2827 #ifdef USE_GTK
2828 void
2829 x_window (f)
2830 FRAME_PTR f;
2832 if (! xg_create_frame_widgets (f))
2833 error ("Unable to create window");
2835 #ifdef HAVE_X_I18N
2836 FRAME_XIC (f) = NULL;
2837 if (use_xim)
2839 BLOCK_INPUT;
2840 create_frame_xic (f);
2841 if (FRAME_XIC (f))
2843 /* XIM server might require some X events. */
2844 unsigned long fevent = NoEventMask;
2845 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2847 if (fevent != NoEventMask)
2849 XSetWindowAttributes attributes;
2850 XWindowAttributes wattr;
2851 unsigned long attribute_mask;
2853 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2854 &wattr);
2855 attributes.event_mask = wattr.your_event_mask | fevent;
2856 attribute_mask = CWEventMask;
2857 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2858 attribute_mask, &attributes);
2861 UNBLOCK_INPUT;
2863 #endif
2866 #else /*! USE_GTK */
2867 /* Create and set up the X window for frame F. */
2869 void
2870 x_window (f)
2871 struct frame *f;
2874 XClassHint class_hints;
2875 XSetWindowAttributes attributes;
2876 unsigned long attribute_mask;
2878 attributes.background_pixel = f->output_data.x->background_pixel;
2879 attributes.border_pixel = f->output_data.x->border_pixel;
2880 attributes.bit_gravity = StaticGravity;
2881 attributes.backing_store = NotUseful;
2882 attributes.save_under = True;
2883 attributes.event_mask = STANDARD_EVENT_SET;
2884 attributes.colormap = FRAME_X_COLORMAP (f);
2885 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2886 | CWColormap);
2888 BLOCK_INPUT;
2889 FRAME_X_WINDOW (f)
2890 = XCreateWindow (FRAME_X_DISPLAY (f),
2891 f->output_data.x->parent_desc,
2892 f->left_pos,
2893 f->top_pos,
2894 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2895 f->border_width,
2896 CopyFromParent, /* depth */
2897 InputOutput, /* class */
2898 FRAME_X_VISUAL (f),
2899 attribute_mask, &attributes);
2901 #ifdef HAVE_X_I18N
2902 if (use_xim)
2904 create_frame_xic (f);
2905 if (FRAME_XIC (f))
2907 /* XIM server might require some X events. */
2908 unsigned long fevent = NoEventMask;
2909 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2910 attributes.event_mask |= fevent;
2911 attribute_mask = CWEventMask;
2912 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2913 attribute_mask, &attributes);
2916 #endif /* HAVE_X_I18N */
2918 validate_x_resource_name ();
2920 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2921 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2922 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2924 /* The menubar is part of the ordinary display;
2925 it does not count in addition to the height of the window. */
2926 f->output_data.x->menubar_height = 0;
2928 /* This indicates that we use the "Passive Input" input model.
2929 Unless we do this, we don't get the Focus{In,Out} events that we
2930 need to draw the cursor correctly. Accursed bureaucrats.
2931 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2933 f->output_data.x->wm_hints.input = True;
2934 f->output_data.x->wm_hints.flags |= InputHint;
2935 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2936 &f->output_data.x->wm_hints);
2937 f->output_data.x->wm_hints.icon_pixmap = None;
2939 /* Request "save yourself" and "delete window" commands from wm. */
2941 Atom protocols[2];
2942 protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2943 protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2944 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2947 /* x_set_name normally ignores requests to set the name if the
2948 requested name is the same as the current name. This is the one
2949 place where that assumption isn't correct; f->name is set, but
2950 the X server hasn't been told. */
2952 Lisp_Object name;
2953 int explicit = f->explicit_name;
2955 f->explicit_name = 0;
2956 name = f->name;
2957 f->name = Qnil;
2958 x_set_name (f, name, explicit);
2961 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2962 f->output_data.x->text_cursor);
2964 UNBLOCK_INPUT;
2966 if (FRAME_X_WINDOW (f) == 0)
2967 error ("Unable to create window");
2970 #endif /* not USE_GTK */
2971 #endif /* not USE_X_TOOLKIT */
2973 /* Verify that the icon position args for this window are valid. */
2975 static void
2976 x_icon_verify (f, parms)
2977 struct frame *f;
2978 Lisp_Object parms;
2980 Lisp_Object icon_x, icon_y;
2982 /* Set the position of the icon. Note that twm groups all
2983 icons in an icon window. */
2984 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2985 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2986 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2988 CHECK_NUMBER (icon_x);
2989 CHECK_NUMBER (icon_y);
2991 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2992 error ("Both left and top icon corners of icon must be specified");
2995 /* Handle the icon stuff for this window. Perhaps later we might
2996 want an x_set_icon_position which can be called interactively as
2997 well. */
2999 static void
3000 x_icon (f, parms)
3001 struct frame *f;
3002 Lisp_Object parms;
3004 Lisp_Object icon_x, icon_y;
3005 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3007 /* Set the position of the icon. Note that twm groups all
3008 icons in an icon window. */
3009 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
3010 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
3011 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
3013 CHECK_NUMBER (icon_x);
3014 CHECK_NUMBER (icon_y);
3016 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
3017 error ("Both left and top icon corners of icon must be specified");
3019 BLOCK_INPUT;
3021 if (! EQ (icon_x, Qunbound))
3022 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
3024 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
3025 but x_create_frame still needs it. */
3026 /* Start up iconic or window? */
3027 x_wm_set_window_state
3028 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
3029 Qicon)
3030 ? IconicState
3031 : NormalState));
3032 #endif
3034 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
3035 ? f->icon_name
3036 : f->name)));
3038 UNBLOCK_INPUT;
3041 /* Make the GCs needed for this window, setting the
3042 background, border and mouse colors; also create the
3043 mouse cursor and the gray border tile. */
3045 static char cursor_bits[] =
3047 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3048 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3049 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3050 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3053 static void
3054 x_make_gc (f)
3055 struct frame *f;
3057 XGCValues gc_values;
3059 BLOCK_INPUT;
3061 /* Create the GCs of this frame.
3062 Note that many default values are used. */
3064 /* Normal video */
3065 gc_values.font = FRAME_FONT (f)->fid;
3066 gc_values.foreground = f->output_data.x->foreground_pixel;
3067 gc_values.background = f->output_data.x->background_pixel;
3068 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
3069 f->output_data.x->normal_gc
3070 = XCreateGC (FRAME_X_DISPLAY (f),
3071 FRAME_X_WINDOW (f),
3072 GCLineWidth | GCFont | GCForeground | GCBackground,
3073 &gc_values);
3075 /* Reverse video style. */
3076 gc_values.foreground = f->output_data.x->background_pixel;
3077 gc_values.background = f->output_data.x->foreground_pixel;
3078 f->output_data.x->reverse_gc
3079 = XCreateGC (FRAME_X_DISPLAY (f),
3080 FRAME_X_WINDOW (f),
3081 GCFont | GCForeground | GCBackground | GCLineWidth,
3082 &gc_values);
3084 /* Cursor has cursor-color background, background-color foreground. */
3085 gc_values.foreground = f->output_data.x->background_pixel;
3086 gc_values.background = f->output_data.x->cursor_pixel;
3087 gc_values.fill_style = FillOpaqueStippled;
3088 gc_values.stipple
3089 = XCreateBitmapFromData (FRAME_X_DISPLAY (f),
3090 FRAME_X_DISPLAY_INFO (f)->root_window,
3091 cursor_bits, 16, 16);
3092 f->output_data.x->cursor_gc
3093 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3094 (GCFont | GCForeground | GCBackground
3095 | GCFillStyle /* | GCStipple */ | GCLineWidth),
3096 &gc_values);
3098 /* Reliefs. */
3099 f->output_data.x->white_relief.gc = 0;
3100 f->output_data.x->black_relief.gc = 0;
3102 /* Create the gray border tile used when the pointer is not in
3103 the frame. Since this depends on the frame's pixel values,
3104 this must be done on a per-frame basis. */
3105 f->output_data.x->border_tile
3106 = (XCreatePixmapFromBitmapData
3107 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
3108 gray_bits, gray_width, gray_height,
3109 f->output_data.x->foreground_pixel,
3110 f->output_data.x->background_pixel,
3111 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
3113 UNBLOCK_INPUT;
3117 /* Free what was was allocated in x_make_gc. */
3119 void
3120 x_free_gcs (f)
3121 struct frame *f;
3123 Display *dpy = FRAME_X_DISPLAY (f);
3125 BLOCK_INPUT;
3127 if (f->output_data.x->normal_gc)
3129 XFreeGC (dpy, f->output_data.x->normal_gc);
3130 f->output_data.x->normal_gc = 0;
3133 if (f->output_data.x->reverse_gc)
3135 XFreeGC (dpy, f->output_data.x->reverse_gc);
3136 f->output_data.x->reverse_gc = 0;
3139 if (f->output_data.x->cursor_gc)
3141 XFreeGC (dpy, f->output_data.x->cursor_gc);
3142 f->output_data.x->cursor_gc = 0;
3145 if (f->output_data.x->border_tile)
3147 XFreePixmap (dpy, f->output_data.x->border_tile);
3148 f->output_data.x->border_tile = 0;
3151 UNBLOCK_INPUT;
3155 /* Handler for signals raised during x_create_frame and
3156 x_create_top_frame. FRAME is the frame which is partially
3157 constructed. */
3159 static Lisp_Object
3160 unwind_create_frame (frame)
3161 Lisp_Object frame;
3163 struct frame *f = XFRAME (frame);
3165 /* If frame is ``official'', nothing to do. */
3166 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
3168 #if GLYPH_DEBUG
3169 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3170 #endif
3172 x_free_frame_resources (f);
3174 #if GLYPH_DEBUG
3175 /* Check that reference counts are indeed correct. */
3176 xassert (dpyinfo->reference_count == dpyinfo_refcount);
3177 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
3178 #endif
3179 return Qt;
3182 return Qnil;
3185 #ifdef USE_FONT_BACKEND
3186 static void
3187 x_default_font_parameter (f, parms)
3188 struct frame *f;
3189 Lisp_Object parms;
3191 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3192 Lisp_Object font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font",
3193 RES_TYPE_STRING);
3195 if (! STRINGP (font))
3197 char *names[]
3198 = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3199 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3200 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3201 /* This was formerly the first thing tried, but it finds
3202 too many fonts and takes too long. */
3203 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3204 /* If those didn't work, look for something which will
3205 at least work. */
3206 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3207 "fixed",
3208 NULL };
3209 int i;
3211 for (i = 0; names[i]; i++)
3213 font = font_open_by_name (f, names[i]);
3214 if (! NILP (font))
3215 break;
3217 if (NILP (font))
3218 error ("No suitable font was found");
3220 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
3222 #endif /* USE_FONT_BACKEND */
3224 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3225 1, 1, 0,
3226 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
3227 Returns an Emacs frame object.
3228 ALIST is an alist of frame parameters.
3229 If the parameters specify that the frame should not have a minibuffer,
3230 and do not specify a specific minibuffer window to use,
3231 then `default-minibuffer-frame' must be a frame whose minibuffer can
3232 be shared by the new frame.
3234 This function is an internal primitive--use `make-frame' instead. */)
3235 (parms)
3236 Lisp_Object parms;
3238 struct frame *f;
3239 Lisp_Object frame, tem;
3240 Lisp_Object name;
3241 int minibuffer_only = 0;
3242 long window_prompting = 0;
3243 int width, height;
3244 int count = SPECPDL_INDEX ();
3245 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3246 Lisp_Object display;
3247 struct x_display_info *dpyinfo = NULL;
3248 Lisp_Object parent;
3249 struct kboard *kb;
3251 check_x ();
3253 parms = Fcopy_alist (parms);
3255 /* Use this general default value to start with
3256 until we know if this frame has a specified name. */
3257 Vx_resource_name = Vinvocation_name;
3259 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
3260 if (EQ (display, Qunbound))
3261 display = Qnil;
3262 dpyinfo = check_x_display_info (display);
3263 #ifdef MULTI_KBOARD
3264 kb = dpyinfo->kboard;
3265 #else
3266 kb = &the_only_kboard;
3267 #endif
3269 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
3270 if (!STRINGP (name)
3271 && ! EQ (name, Qunbound)
3272 && ! NILP (name))
3273 error ("Invalid frame name--not a string or nil");
3275 if (STRINGP (name))
3276 Vx_resource_name = name;
3278 /* See if parent window is specified. */
3279 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
3280 if (EQ (parent, Qunbound))
3281 parent = Qnil;
3282 if (! NILP (parent))
3283 CHECK_NUMBER (parent);
3285 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3286 /* No need to protect DISPLAY because that's not used after passing
3287 it to make_frame_without_minibuffer. */
3288 frame = Qnil;
3289 GCPRO4 (parms, parent, name, frame);
3290 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
3291 RES_TYPE_SYMBOL);
3292 if (EQ (tem, Qnone) || NILP (tem))
3293 f = make_frame_without_minibuffer (Qnil, kb, display);
3294 else if (EQ (tem, Qonly))
3296 f = make_minibuffer_frame ();
3297 minibuffer_only = 1;
3299 else if (WINDOWP (tem))
3300 f = make_frame_without_minibuffer (tem, kb, display);
3301 else
3302 f = make_frame (1);
3304 XSETFRAME (frame, f);
3306 /* Note that X Windows does support scroll bars. */
3307 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3309 f->output_method = output_x_window;
3310 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
3311 bzero (f->output_data.x, sizeof (struct x_output));
3312 f->output_data.x->icon_bitmap = -1;
3313 FRAME_FONTSET (f) = -1;
3314 f->output_data.x->scroll_bar_foreground_pixel = -1;
3315 f->output_data.x->scroll_bar_background_pixel = -1;
3316 #ifdef USE_TOOLKIT_SCROLL_BARS
3317 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
3318 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
3319 #endif /* USE_TOOLKIT_SCROLL_BARS */
3321 f->icon_name
3322 = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3323 RES_TYPE_STRING);
3324 if (! STRINGP (f->icon_name))
3325 f->icon_name = Qnil;
3327 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3329 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3330 record_unwind_protect (unwind_create_frame, frame);
3331 #if GLYPH_DEBUG
3332 image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
3333 dpyinfo_refcount = dpyinfo->reference_count;
3334 #endif /* GLYPH_DEBUG */
3335 #ifdef MULTI_KBOARD
3336 FRAME_KBOARD (f) = kb;
3337 #endif
3339 /* These colors will be set anyway later, but it's important
3340 to get the color reference counts right, so initialize them! */
3342 Lisp_Object black;
3343 struct gcpro gcpro1;
3345 /* Function x_decode_color can signal an error. Make
3346 sure to initialize color slots so that we won't try
3347 to free colors we haven't allocated. */
3348 f->output_data.x->foreground_pixel = -1;
3349 f->output_data.x->background_pixel = -1;
3350 f->output_data.x->cursor_pixel = -1;
3351 f->output_data.x->cursor_foreground_pixel = -1;
3352 f->output_data.x->border_pixel = -1;
3353 f->output_data.x->mouse_pixel = -1;
3355 black = build_string ("black");
3356 GCPRO1 (black);
3357 f->output_data.x->foreground_pixel
3358 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3359 f->output_data.x->background_pixel
3360 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3361 f->output_data.x->cursor_pixel
3362 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3363 f->output_data.x->cursor_foreground_pixel
3364 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3365 f->output_data.x->border_pixel
3366 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3367 f->output_data.x->mouse_pixel
3368 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3369 UNGCPRO;
3372 /* Specify the parent under which to make this X window. */
3374 if (!NILP (parent))
3376 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3377 f->output_data.x->explicit_parent = 1;
3379 else
3381 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3382 f->output_data.x->explicit_parent = 0;
3385 /* Set the name; the functions to which we pass f expect the name to
3386 be set. */
3387 if (EQ (name, Qunbound) || NILP (name))
3389 f->name = build_string (dpyinfo->x_id_name);
3390 f->explicit_name = 0;
3392 else
3394 f->name = name;
3395 f->explicit_name = 1;
3396 /* use the frame's title when getting resources for this frame. */
3397 specbind (Qx_resource_name, name);
3400 f->resx = dpyinfo->resx;
3401 f->resy = dpyinfo->resy;
3403 #ifdef USE_FONT_BACKEND
3404 if (enable_font_backend)
3406 /* Perhaps, we must allow frame parameter, say `font-backend',
3407 to specify which font backends to use. */
3408 #ifdef HAVE_FREETYPE
3409 #ifdef HAVE_XFT
3410 register_font_driver (&xftfont_driver, f);
3411 #else /* not HAVE_XFT */
3412 register_font_driver (&ftxfont_driver, f);
3413 #endif /* not HAVE_XFT */
3414 #endif /* HAVE_FREETYPE */
3415 register_font_driver (&xfont_driver, f);
3417 x_default_parameter (f, parms, Qfont_backend, Qnil,
3418 "fontBackend", "FontBackend", RES_TYPE_STRING);
3420 #endif /* USE_FONT_BACKEND */
3422 /* Extract the window parameters from the supplied values
3423 that are needed to determine window geometry. */
3424 #ifdef USE_FONT_BACKEND
3425 if (enable_font_backend)
3426 x_default_font_parameter (f, parms);
3427 else
3428 #endif /* USE_FONT_BACKEND */
3430 Lisp_Object font;
3432 font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
3434 /* If the caller has specified no font, try out fonts which we
3435 hope have bold and italic variations. */
3436 if (!STRINGP (font))
3438 char *names[]
3439 = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3440 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3441 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3442 /* This was formerly the first thing tried, but it finds
3443 too many fonts and takes too long. */
3444 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3445 /* If those didn't work, look for something which will
3446 at least work. */
3447 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3448 NULL };
3449 int i;
3451 BLOCK_INPUT;
3452 for (i = 0; names[i]; i++)
3454 Lisp_Object list;
3456 list = x_list_fonts (f, build_string (names[i]), 0, 1);
3457 if (CONSP (list))
3459 font = XCAR (list);
3460 break;
3463 UNBLOCK_INPUT;
3464 if (! STRINGP (font))
3465 font = build_string ("fixed");
3467 x_default_parameter (f, parms, Qfont, font,
3468 "font", "Font", RES_TYPE_STRING);
3471 #ifdef USE_LUCID
3472 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3473 whereby it fails to get any font. */
3474 xlwmenu_default_font = FRAME_FONT (f);
3475 #endif
3477 x_default_parameter (f, parms, Qborder_width, make_number (2),
3478 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3480 /* This defaults to 1 in order to match xterm. We recognize either
3481 internalBorderWidth or internalBorder (which is what xterm calls
3482 it). */
3483 if (NILP (Fassq (Qinternal_border_width, parms)))
3485 Lisp_Object value;
3487 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3488 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3489 if (! EQ (value, Qunbound))
3490 parms = Fcons (Fcons (Qinternal_border_width, value),
3491 parms);
3493 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
3494 "internalBorderWidth", "internalBorderWidth",
3495 RES_TYPE_NUMBER);
3496 x_default_parameter (f, parms, Qvertical_scroll_bars, Qleft,
3497 "verticalScrollBars", "ScrollBars",
3498 RES_TYPE_SYMBOL);
3500 /* Also do the stuff which must be set before the window exists. */
3501 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3502 "foreground", "Foreground", RES_TYPE_STRING);
3503 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3504 "background", "Background", RES_TYPE_STRING);
3505 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3506 "pointerColor", "Foreground", RES_TYPE_STRING);
3507 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3508 "cursorColor", "Foreground", RES_TYPE_STRING);
3509 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3510 "borderColor", "BorderColor", RES_TYPE_STRING);
3511 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3512 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3513 x_default_parameter (f, parms, Qline_spacing, Qnil,
3514 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3515 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3516 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3517 x_default_parameter (f, parms, Qright_fringe, Qnil,
3518 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3520 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3521 "scrollBarForeground",
3522 "ScrollBarForeground", 1);
3523 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3524 "scrollBarBackground",
3525 "ScrollBarBackground", 0);
3527 /* Init faces before x_default_parameter is called for scroll-bar
3528 parameters because that function calls x_set_scroll_bar_width,
3529 which calls change_frame_size, which calls Fset_window_buffer,
3530 which runs hooks, which call Fvertical_motion. At the end, we
3531 end up in init_iterator with a null face cache, which should not
3532 happen. */
3533 init_frame_faces (f);
3535 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
3536 "menuBar", "MenuBar", RES_TYPE_NUMBER);
3537 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
3538 "toolBar", "ToolBar", RES_TYPE_NUMBER);
3539 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3540 "bufferPredicate", "BufferPredicate",
3541 RES_TYPE_SYMBOL);
3542 x_default_parameter (f, parms, Qtitle, Qnil,
3543 "title", "Title", RES_TYPE_STRING);
3544 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3545 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3546 x_default_parameter (f, parms, Qfullscreen, Qnil,
3547 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3549 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3551 /* Compute the size of the X window. */
3552 window_prompting = x_figure_window_size (f, parms, 1);
3554 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3555 f->no_split = minibuffer_only || EQ (tem, Qt);
3557 x_icon_verify (f, parms);
3559 /* Create the X widget or window. */
3560 #ifdef USE_X_TOOLKIT
3561 x_window (f, window_prompting, minibuffer_only);
3562 #else
3563 x_window (f);
3564 #endif
3566 x_icon (f, parms);
3567 x_make_gc (f);
3569 /* Now consider the frame official. */
3570 FRAME_X_DISPLAY_INFO (f)->reference_count++;
3571 Vframe_list = Fcons (frame, Vframe_list);
3573 /* We need to do this after creating the X window, so that the
3574 icon-creation functions can say whose icon they're describing. */
3575 x_default_parameter (f, parms, Qicon_type, Qt,
3576 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
3578 x_default_parameter (f, parms, Qauto_raise, Qnil,
3579 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3580 x_default_parameter (f, parms, Qauto_lower, Qnil,
3581 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3582 x_default_parameter (f, parms, Qcursor_type, Qbox,
3583 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3584 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3585 "scrollBarWidth", "ScrollBarWidth",
3586 RES_TYPE_NUMBER);
3588 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3589 Change will not be effected unless different from the current
3590 FRAME_LINES (f). */
3591 width = FRAME_COLS (f);
3592 height = FRAME_LINES (f);
3594 SET_FRAME_COLS (f, 0);
3595 FRAME_LINES (f) = 0;
3596 change_frame_size (f, height, width, 1, 0, 0);
3598 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3599 /* Create the menu bar. */
3600 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3602 /* If this signals an error, we haven't set size hints for the
3603 frame and we didn't make it visible. */
3604 initialize_frame_menubar (f);
3606 #ifndef USE_GTK
3607 /* This is a no-op, except under Motif where it arranges the
3608 main window for the widgets on it. */
3609 lw_set_main_areas (f->output_data.x->column_widget,
3610 f->output_data.x->menubar_widget,
3611 f->output_data.x->edit_widget);
3612 #endif /* not USE_GTK */
3614 #endif /* USE_X_TOOLKIT || USE_GTK */
3616 /* Tell the server what size and position, etc, we want, and how
3617 badly we want them. This should be done after we have the menu
3618 bar so that its size can be taken into account. */
3619 BLOCK_INPUT;
3620 x_wm_set_size_hint (f, window_prompting, 0);
3621 UNBLOCK_INPUT;
3623 /* Make the window appear on the frame and enable display, unless
3624 the caller says not to. However, with explicit parent, Emacs
3625 cannot control visibility, so don't try. */
3626 if (! f->output_data.x->explicit_parent)
3628 Lisp_Object visibility;
3630 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3631 RES_TYPE_SYMBOL);
3632 if (EQ (visibility, Qunbound))
3633 visibility = Qt;
3635 if (EQ (visibility, Qicon))
3636 x_iconify_frame (f);
3637 else if (! NILP (visibility))
3638 x_make_frame_visible (f);
3639 else
3640 /* Must have been Qnil. */
3644 /* Set the WM leader property. GTK does this itself, so this is not
3645 needed when using GTK. */
3646 if (dpyinfo->client_leader_window != 0)
3648 BLOCK_INPUT;
3649 XChangeProperty (FRAME_X_DISPLAY (f),
3650 FRAME_OUTER_WINDOW (f),
3651 dpyinfo->Xatom_wm_client_leader,
3652 XA_WINDOW, 32, PropModeReplace,
3653 (unsigned char *) &dpyinfo->client_leader_window, 1);
3654 UNBLOCK_INPUT;
3657 /* Initialize `default-minibuffer-frame' in case this is the first
3658 frame on this display device. */
3659 if (FRAME_HAS_MINIBUF_P (f)
3660 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
3661 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
3662 kb->Vdefault_minibuffer_frame = frame;
3664 /* All remaining specified parameters, which have not been "used"
3665 by x_get_arg and friends, now go in the misc. alist of the frame. */
3666 for (tem = parms; !NILP (tem); tem = XCDR (tem))
3667 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3668 f->param_alist = Fcons (XCAR (tem), f->param_alist);
3670 UNGCPRO;
3672 /* Make sure windows on this frame appear in calls to next-window
3673 and similar functions. */
3674 Vwindow_list = Qnil;
3676 return unbind_to (count, frame);
3680 /* FRAME is used only to get a handle on the X display. We don't pass the
3681 display info directly because we're called from frame.c, which doesn't
3682 know about that structure. */
3684 Lisp_Object
3685 x_get_focus_frame (frame)
3686 struct frame *frame;
3688 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3689 Lisp_Object xfocus;
3690 if (! dpyinfo->x_focus_frame)
3691 return Qnil;
3693 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3694 return xfocus;
3698 /* In certain situations, when the window manager follows a
3699 click-to-focus policy, there seems to be no way around calling
3700 XSetInputFocus to give another frame the input focus .
3702 In an ideal world, XSetInputFocus should generally be avoided so
3703 that applications don't interfere with the window manager's focus
3704 policy. But I think it's okay to use when it's clearly done
3705 following a user-command. */
3707 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3708 doc: /* Set the input focus to FRAME.
3709 FRAME nil means use the selected frame. */)
3710 (frame)
3711 Lisp_Object frame;
3713 struct frame *f = check_x_frame (frame);
3714 Display *dpy = FRAME_X_DISPLAY (f);
3716 BLOCK_INPUT;
3717 x_catch_errors (dpy);
3718 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3719 RevertToParent, CurrentTime);
3720 x_ewmh_activate_frame (f);
3721 x_uncatch_errors ();
3722 UNBLOCK_INPUT;
3724 return Qnil;
3728 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3729 doc: /* Internal function called by `color-defined-p', which see. */)
3730 (color, frame)
3731 Lisp_Object color, frame;
3733 XColor foo;
3734 FRAME_PTR f = check_x_frame (frame);
3736 CHECK_STRING (color);
3738 if (x_defined_color (f, SDATA (color), &foo, 0))
3739 return Qt;
3740 else
3741 return Qnil;
3744 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3745 doc: /* Internal function called by `color-values', which see. */)
3746 (color, frame)
3747 Lisp_Object color, frame;
3749 XColor foo;
3750 FRAME_PTR f = check_x_frame (frame);
3752 CHECK_STRING (color);
3754 if (x_defined_color (f, SDATA (color), &foo, 0))
3755 return list3 (make_number (foo.red),
3756 make_number (foo.green),
3757 make_number (foo.blue));
3758 else
3759 return Qnil;
3762 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3763 doc: /* Internal function called by `display-color-p', which see. */)
3764 (display)
3765 Lisp_Object display;
3767 struct x_display_info *dpyinfo = check_x_display_info (display);
3769 if (dpyinfo->n_planes <= 2)
3770 return Qnil;
3772 switch (dpyinfo->visual->class)
3774 case StaticColor:
3775 case PseudoColor:
3776 case TrueColor:
3777 case DirectColor:
3778 return Qt;
3780 default:
3781 return Qnil;
3785 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3786 0, 1, 0,
3787 doc: /* Return t if the X display supports shades of gray.
3788 Note that color displays do support shades of gray.
3789 The optional argument DISPLAY specifies which display to ask about.
3790 DISPLAY should be either a frame or a display name (a string).
3791 If omitted or nil, that stands for the selected frame's display. */)
3792 (display)
3793 Lisp_Object display;
3795 struct x_display_info *dpyinfo = check_x_display_info (display);
3797 if (dpyinfo->n_planes <= 1)
3798 return Qnil;
3800 switch (dpyinfo->visual->class)
3802 case StaticColor:
3803 case PseudoColor:
3804 case TrueColor:
3805 case DirectColor:
3806 case StaticGray:
3807 case GrayScale:
3808 return Qt;
3810 default:
3811 return Qnil;
3815 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3816 0, 1, 0,
3817 doc: /* Returns the width in pixels of the X display DISPLAY.
3818 The optional argument DISPLAY specifies which display to ask about.
3819 DISPLAY should be either a frame or a display name (a string).
3820 If omitted or nil, that stands for the selected frame's display. */)
3821 (display)
3822 Lisp_Object display;
3824 struct x_display_info *dpyinfo = check_x_display_info (display);
3826 return make_number (dpyinfo->width);
3829 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3830 Sx_display_pixel_height, 0, 1, 0,
3831 doc: /* Returns the height in pixels of the X display DISPLAY.
3832 The optional argument DISPLAY specifies which display to ask about.
3833 DISPLAY should be either a frame or a display name (a string).
3834 If omitted or nil, that stands for the selected frame's display. */)
3835 (display)
3836 Lisp_Object display;
3838 struct x_display_info *dpyinfo = check_x_display_info (display);
3840 return make_number (dpyinfo->height);
3843 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3844 0, 1, 0,
3845 doc: /* Returns the number of bitplanes of the X display DISPLAY.
3846 The optional argument DISPLAY specifies which display to ask about.
3847 DISPLAY should be either a frame or a display name (a string).
3848 If omitted or nil, that stands for the selected frame's display. */)
3849 (display)
3850 Lisp_Object display;
3852 struct x_display_info *dpyinfo = check_x_display_info (display);
3854 return make_number (dpyinfo->n_planes);
3857 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3858 0, 1, 0,
3859 doc: /* Returns the number of color cells of the X display DISPLAY.
3860 The optional argument DISPLAY specifies which display to ask about.
3861 DISPLAY should be either a frame or a display name (a string).
3862 If omitted or nil, that stands for the selected frame's display. */)
3863 (display)
3864 Lisp_Object display;
3866 struct x_display_info *dpyinfo = check_x_display_info (display);
3868 int nr_planes = DisplayPlanes (dpyinfo->display,
3869 XScreenNumberOfScreen (dpyinfo->screen));
3871 /* Truncate nr_planes to 24 to avoid integer overflow.
3872 Some displays says 32, but only 24 bits are actually significant.
3873 There are only very few and rare video cards that have more than
3874 24 significant bits. Also 24 bits is more than 16 million colors,
3875 it "should be enough for everyone". */
3876 if (nr_planes > 24) nr_planes = 24;
3878 return make_number (1 << nr_planes);
3881 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3882 Sx_server_max_request_size,
3883 0, 1, 0,
3884 doc: /* Returns the maximum request size of the X server of display DISPLAY.
3885 The optional argument DISPLAY specifies which display to ask about.
3886 DISPLAY should be either a frame or a display name (a string).
3887 If omitted or nil, that stands for the selected frame's display. */)
3888 (display)
3889 Lisp_Object display;
3891 struct x_display_info *dpyinfo = check_x_display_info (display);
3893 return make_number (MAXREQUEST (dpyinfo->display));
3896 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3897 doc: /* Returns the "vendor ID" string of the X server of display DISPLAY.
3898 \(Labelling every distributor as a "vendor" embodies the false assumption
3899 that operating systems cannot be developed and distributed noncommercially.)
3900 The optional argument DISPLAY specifies which display to ask about.
3901 DISPLAY should be either a frame or a display name (a string).
3902 If omitted or nil, that stands for the selected frame's display. */)
3903 (display)
3904 Lisp_Object display;
3906 struct x_display_info *dpyinfo = check_x_display_info (display);
3907 char *vendor = ServerVendor (dpyinfo->display);
3909 if (! vendor) vendor = "";
3910 return build_string (vendor);
3913 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3914 doc: /* Returns the version numbers of the X server of display DISPLAY.
3915 The value is a list of three integers: the major and minor
3916 version numbers of the X Protocol in use, and the distributor-specific release
3917 number. See also the function `x-server-vendor'.
3919 The optional argument DISPLAY specifies which display to ask about.
3920 DISPLAY should be either a frame or a display name (a string).
3921 If omitted or nil, that stands for the selected frame's display. */)
3922 (display)
3923 Lisp_Object display;
3925 struct x_display_info *dpyinfo = check_x_display_info (display);
3926 Display *dpy = dpyinfo->display;
3928 return Fcons (make_number (ProtocolVersion (dpy)),
3929 Fcons (make_number (ProtocolRevision (dpy)),
3930 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3933 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3934 doc: /* Return the number of screens on the X server of display DISPLAY.
3935 The optional argument DISPLAY specifies which display to ask about.
3936 DISPLAY should be either a frame or a display name (a string).
3937 If omitted or nil, that stands for the selected frame's display. */)
3938 (display)
3939 Lisp_Object display;
3941 struct x_display_info *dpyinfo = check_x_display_info (display);
3943 return make_number (ScreenCount (dpyinfo->display));
3946 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3947 doc: /* Return the height in millimeters of the X display DISPLAY.
3948 The optional argument DISPLAY specifies which display to ask about.
3949 DISPLAY should be either a frame or a display name (a string).
3950 If omitted or nil, that stands for the selected frame's display. */)
3951 (display)
3952 Lisp_Object display;
3954 struct x_display_info *dpyinfo = check_x_display_info (display);
3956 return make_number (HeightMMOfScreen (dpyinfo->screen));
3959 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3960 doc: /* Return the width in millimeters of the X display DISPLAY.
3961 The optional argument DISPLAY specifies which display to ask about.
3962 DISPLAY should be either a frame or a display name (a string).
3963 If omitted or nil, that stands for the selected frame's display. */)
3964 (display)
3965 Lisp_Object display;
3967 struct x_display_info *dpyinfo = check_x_display_info (display);
3969 return make_number (WidthMMOfScreen (dpyinfo->screen));
3972 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3973 Sx_display_backing_store, 0, 1, 0,
3974 doc: /* Returns an indication of whether X display DISPLAY does backing store.
3975 The value may be `always', `when-mapped', or `not-useful'.
3976 The optional argument DISPLAY specifies which display to ask about.
3977 DISPLAY should be either a frame or a display name (a string).
3978 If omitted or nil, that stands for the selected frame's display. */)
3979 (display)
3980 Lisp_Object display;
3982 struct x_display_info *dpyinfo = check_x_display_info (display);
3983 Lisp_Object result;
3985 switch (DoesBackingStore (dpyinfo->screen))
3987 case Always:
3988 result = intern ("always");
3989 break;
3991 case WhenMapped:
3992 result = intern ("when-mapped");
3993 break;
3995 case NotUseful:
3996 result = intern ("not-useful");
3997 break;
3999 default:
4000 error ("Strange value for BackingStore parameter of screen");
4001 result = Qnil;
4004 return result;
4007 DEFUN ("x-display-visual-class", Fx_display_visual_class,
4008 Sx_display_visual_class, 0, 1, 0,
4009 doc: /* Return the visual class of the X display DISPLAY.
4010 The value is one of the symbols `static-gray', `gray-scale',
4011 `static-color', `pseudo-color', `true-color', or `direct-color'.
4013 The optional argument DISPLAY specifies which display to ask about.
4014 DISPLAY should be either a frame or a display name (a string).
4015 If omitted or nil, that stands for the selected frame's display. */)
4016 (display)
4017 Lisp_Object display;
4019 struct x_display_info *dpyinfo = check_x_display_info (display);
4020 Lisp_Object result;
4022 switch (dpyinfo->visual->class)
4024 case StaticGray:
4025 result = intern ("static-gray");
4026 break;
4027 case GrayScale:
4028 result = intern ("gray-scale");
4029 break;
4030 case StaticColor:
4031 result = intern ("static-color");
4032 break;
4033 case PseudoColor:
4034 result = intern ("pseudo-color");
4035 break;
4036 case TrueColor:
4037 result = intern ("true-color");
4038 break;
4039 case DirectColor:
4040 result = intern ("direct-color");
4041 break;
4042 default:
4043 error ("Display has an unknown visual class");
4044 result = Qnil;
4047 return result;
4050 DEFUN ("x-display-save-under", Fx_display_save_under,
4051 Sx_display_save_under, 0, 1, 0,
4052 doc: /* Returns t if the X display DISPLAY supports the save-under feature.
4053 The optional argument DISPLAY specifies which display to ask about.
4054 DISPLAY should be either a frame or a display name (a string).
4055 If omitted or nil, that stands for the selected frame's display. */)
4056 (display)
4057 Lisp_Object display;
4059 struct x_display_info *dpyinfo = check_x_display_info (display);
4061 if (DoesSaveUnders (dpyinfo->screen) == True)
4062 return Qt;
4063 else
4064 return Qnil;
4068 x_pixel_width (f)
4069 register struct frame *f;
4071 return FRAME_PIXEL_WIDTH (f);
4075 x_pixel_height (f)
4076 register struct frame *f;
4078 return FRAME_PIXEL_HEIGHT (f);
4082 x_char_width (f)
4083 register struct frame *f;
4085 return FRAME_COLUMN_WIDTH (f);
4089 x_char_height (f)
4090 register struct frame *f;
4092 return FRAME_LINE_HEIGHT (f);
4096 x_screen_planes (f)
4097 register struct frame *f;
4099 return FRAME_X_DISPLAY_INFO (f)->n_planes;
4104 /************************************************************************
4105 X Displays
4106 ************************************************************************/
4109 /* Mapping visual names to visuals. */
4111 static struct visual_class
4113 char *name;
4114 int class;
4116 visual_classes[] =
4118 {"StaticGray", StaticGray},
4119 {"GrayScale", GrayScale},
4120 {"StaticColor", StaticColor},
4121 {"PseudoColor", PseudoColor},
4122 {"TrueColor", TrueColor},
4123 {"DirectColor", DirectColor},
4124 {NULL, 0}
4128 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4130 /* Value is the screen number of screen SCR. This is a substitute for
4131 the X function with the same name when that doesn't exist. */
4134 XScreenNumberOfScreen (scr)
4135 register Screen *scr;
4137 Display *dpy = scr->display;
4138 int i;
4140 for (i = 0; i < dpy->nscreens; ++i)
4141 if (scr == dpy->screens + i)
4142 break;
4144 return i;
4147 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4150 /* Select the visual that should be used on display DPYINFO. Set
4151 members of DPYINFO appropriately. Called from x_term_init. */
4153 void
4154 select_visual (dpyinfo)
4155 struct x_display_info *dpyinfo;
4157 Display *dpy = dpyinfo->display;
4158 Screen *screen = dpyinfo->screen;
4159 Lisp_Object value;
4161 /* See if a visual is specified. */
4162 value = display_x_get_resource (dpyinfo,
4163 build_string ("visualClass"),
4164 build_string ("VisualClass"),
4165 Qnil, Qnil);
4166 if (STRINGP (value))
4168 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4169 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4170 depth, a decimal number. NAME is compared with case ignored. */
4171 char *s = (char *) alloca (SBYTES (value) + 1);
4172 char *dash;
4173 int i, class = -1;
4174 XVisualInfo vinfo;
4176 strcpy (s, SDATA (value));
4177 dash = index (s, '-');
4178 if (dash)
4180 dpyinfo->n_planes = atoi (dash + 1);
4181 *dash = '\0';
4183 else
4184 /* We won't find a matching visual with depth 0, so that
4185 an error will be printed below. */
4186 dpyinfo->n_planes = 0;
4188 /* Determine the visual class. */
4189 for (i = 0; visual_classes[i].name; ++i)
4190 if (xstricmp (s, visual_classes[i].name) == 0)
4192 class = visual_classes[i].class;
4193 break;
4196 /* Look up a matching visual for the specified class. */
4197 if (class == -1
4198 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4199 dpyinfo->n_planes, class, &vinfo))
4200 fatal ("Invalid visual specification `%s'", SDATA (value));
4202 dpyinfo->visual = vinfo.visual;
4204 else
4206 int n_visuals;
4207 XVisualInfo *vinfo, vinfo_template;
4209 dpyinfo->visual = DefaultVisualOfScreen (screen);
4211 #ifdef HAVE_X11R4
4212 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4213 #else
4214 vinfo_template.visualid = dpyinfo->visual->visualid;
4215 #endif
4216 vinfo_template.screen = XScreenNumberOfScreen (screen);
4217 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4218 &vinfo_template, &n_visuals);
4219 if (n_visuals != 1)
4220 fatal ("Can't get proper X visual info");
4222 dpyinfo->n_planes = vinfo->depth;
4223 XFree ((char *) vinfo);
4228 /* Return the X display structure for the display named NAME.
4229 Open a new connection if necessary. */
4231 struct x_display_info *
4232 x_display_info_for_name (name)
4233 Lisp_Object name;
4235 Lisp_Object names;
4236 struct x_display_info *dpyinfo;
4238 CHECK_STRING (name);
4240 if (! EQ (Vwindow_system, intern ("x")))
4241 error ("Not using X Windows");
4243 for (dpyinfo = x_display_list, names = x_display_name_list;
4244 dpyinfo;
4245 dpyinfo = dpyinfo->next, names = XCDR (names))
4247 Lisp_Object tem;
4248 tem = Fstring_equal (XCAR (XCAR (names)), name);
4249 if (!NILP (tem))
4250 return dpyinfo;
4253 /* Use this general default value to start with. */
4254 Vx_resource_name = Vinvocation_name;
4256 validate_x_resource_name ();
4258 dpyinfo = x_term_init (name, (char *)0,
4259 (char *) SDATA (Vx_resource_name));
4261 if (dpyinfo == 0)
4262 error ("Cannot connect to X server %s", SDATA (name));
4264 x_in_use = 1;
4265 XSETFASTINT (Vwindow_system_version, 11);
4267 return dpyinfo;
4271 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4272 1, 3, 0,
4273 doc: /* Open a connection to an X server.
4274 DISPLAY is the name of the display to connect to.
4275 Optional second arg XRM-STRING is a string of resources in xrdb format.
4276 If the optional third arg MUST-SUCCEED is non-nil,
4277 terminate Emacs if we can't open the connection. */)
4278 (display, xrm_string, must_succeed)
4279 Lisp_Object display, xrm_string, must_succeed;
4281 unsigned char *xrm_option;
4282 struct x_display_info *dpyinfo;
4284 CHECK_STRING (display);
4285 if (! NILP (xrm_string))
4286 CHECK_STRING (xrm_string);
4288 if (! EQ (Vwindow_system, intern ("x")))
4289 error ("Not using X Windows");
4291 if (! NILP (xrm_string))
4292 xrm_option = (unsigned char *) SDATA (xrm_string);
4293 else
4294 xrm_option = (unsigned char *) 0;
4296 validate_x_resource_name ();
4298 /* This is what opens the connection and sets x_current_display.
4299 This also initializes many symbols, such as those used for input. */
4300 dpyinfo = x_term_init (display, xrm_option,
4301 (char *) SDATA (Vx_resource_name));
4303 if (dpyinfo == 0)
4305 if (!NILP (must_succeed))
4306 fatal ("Cannot connect to X server %s.\n\
4307 Check the DISPLAY environment variable or use `-d'.\n\
4308 Also use the `xauth' program to verify that you have the proper\n\
4309 authorization information needed to connect the X server.\n\
4310 An insecure way to solve the problem may be to use `xhost'.\n",
4311 SDATA (display));
4312 else
4313 error ("Cannot connect to X server %s", SDATA (display));
4316 x_in_use = 1;
4318 XSETFASTINT (Vwindow_system_version, 11);
4319 return Qnil;
4322 DEFUN ("x-close-connection", Fx_close_connection,
4323 Sx_close_connection, 1, 1, 0,
4324 doc: /* Close the connection to DISPLAY's X server.
4325 For DISPLAY, specify either a frame or a display name (a string).
4326 If DISPLAY is nil, that stands for the selected frame's display. */)
4327 (display)
4328 Lisp_Object display;
4330 struct x_display_info *dpyinfo = check_x_display_info (display);
4331 int i;
4333 if (dpyinfo->reference_count > 0)
4334 error ("Display still has frames on it");
4336 BLOCK_INPUT;
4337 /* Free the fonts in the font table. */
4338 for (i = 0; i < dpyinfo->n_fonts; i++)
4339 if (dpyinfo->font_table[i].name)
4341 XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font);
4344 x_destroy_all_bitmaps (dpyinfo);
4345 XSetCloseDownMode (dpyinfo->display, DestroyAll);
4347 #ifdef USE_GTK
4348 xg_display_close (dpyinfo->display);
4349 #else
4350 #ifdef USE_X_TOOLKIT
4351 XtCloseDisplay (dpyinfo->display);
4352 #else
4353 XCloseDisplay (dpyinfo->display);
4354 #endif
4355 #endif /* ! USE_GTK */
4357 x_delete_display (dpyinfo);
4358 UNBLOCK_INPUT;
4360 return Qnil;
4363 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4364 doc: /* Return the list of display names that Emacs has connections to. */)
4367 Lisp_Object tail, result;
4369 result = Qnil;
4370 for (tail = x_display_name_list; ! NILP (tail); tail = XCDR (tail))
4371 result = Fcons (XCAR (XCAR (tail)), result);
4373 return result;
4376 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4377 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4378 If ON is nil, allow buffering of requests.
4379 Turning on synchronization prohibits the Xlib routines from buffering
4380 requests and seriously degrades performance, but makes debugging much
4381 easier.
4382 The optional second argument DISPLAY specifies which display to act on.
4383 DISPLAY should be either a frame or a display name (a string).
4384 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4385 (on, display)
4386 Lisp_Object display, on;
4388 struct x_display_info *dpyinfo = check_x_display_info (display);
4390 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4392 return Qnil;
4395 /* Wait for responses to all X commands issued so far for frame F. */
4397 void
4398 x_sync (f)
4399 FRAME_PTR f;
4401 BLOCK_INPUT;
4402 XSync (FRAME_X_DISPLAY (f), False);
4403 UNBLOCK_INPUT;
4407 /***********************************************************************
4408 Window properties
4409 ***********************************************************************/
4411 DEFUN ("x-change-window-property", Fx_change_window_property,
4412 Sx_change_window_property, 2, 6, 0,
4413 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4414 PROP must be a string.
4415 VALUE may be a string or a list of conses, numbers and/or strings.
4416 If an element in the list is a string, it is converted to
4417 an Atom and the value of the Atom is used. If an element is a cons,
4418 it is converted to a 32 bit number where the car is the 16 top bits and the
4419 cdr is the lower 16 bits.
4420 FRAME nil or omitted means use the selected frame.
4421 If TYPE is given and non-nil, it is the name of the type of VALUE.
4422 If TYPE is not given or nil, the type is STRING.
4423 FORMAT gives the size in bits of each element if VALUE is a list.
4424 It must be one of 8, 16 or 32.
4425 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4426 If OUTER_P is non-nil, the property is changed for the outer X window of
4427 FRAME. Default is to change on the edit X window.
4429 Value is VALUE. */)
4430 (prop, value, frame, type, format, outer_p)
4431 Lisp_Object prop, value, frame, type, format, outer_p;
4433 struct frame *f = check_x_frame (frame);
4434 Atom prop_atom;
4435 Atom target_type = XA_STRING;
4436 int element_format = 8;
4437 unsigned char *data;
4438 int nelements;
4439 Window w;
4441 CHECK_STRING (prop);
4443 if (! NILP (format))
4445 CHECK_NUMBER (format);
4446 element_format = XFASTINT (format);
4448 if (element_format != 8 && element_format != 16
4449 && element_format != 32)
4450 error ("FORMAT must be one of 8, 16 or 32");
4453 if (CONSP (value))
4455 nelements = x_check_property_data (value);
4456 if (nelements == -1)
4457 error ("Bad data in VALUE, must be number, string or cons");
4459 if (element_format == 8)
4460 data = (unsigned char *) xmalloc (nelements);
4461 else if (element_format == 16)
4462 data = (unsigned char *) xmalloc (nelements*2);
4463 else /* format == 32 */
4464 /* The man page for XChangeProperty:
4465 "If the specified format is 32, the property data must be a
4466 long array."
4467 This applies even if long is more than 64 bits. The X library
4468 converts to 32 bits before sending to the X server. */
4469 data = (unsigned char *) xmalloc (nelements * sizeof(long));
4471 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4473 else
4475 CHECK_STRING (value);
4476 data = SDATA (value);
4477 nelements = SCHARS (value);
4480 BLOCK_INPUT;
4481 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4482 if (! NILP (type))
4484 CHECK_STRING (type);
4485 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4488 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4489 else w = FRAME_X_WINDOW (f);
4491 XChangeProperty (FRAME_X_DISPLAY (f), w,
4492 prop_atom, target_type, element_format, PropModeReplace,
4493 data, nelements);
4495 if (CONSP (value)) xfree (data);
4497 /* Make sure the property is set when we return. */
4498 XFlush (FRAME_X_DISPLAY (f));
4499 UNBLOCK_INPUT;
4501 return value;
4505 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4506 Sx_delete_window_property, 1, 2, 0,
4507 doc: /* Remove window property PROP from X window of FRAME.
4508 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4509 (prop, frame)
4510 Lisp_Object prop, frame;
4512 struct frame *f = check_x_frame (frame);
4513 Atom prop_atom;
4515 CHECK_STRING (prop);
4516 BLOCK_INPUT;
4517 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4518 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4520 /* Make sure the property is removed when we return. */
4521 XFlush (FRAME_X_DISPLAY (f));
4522 UNBLOCK_INPUT;
4524 return prop;
4528 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4529 1, 6, 0,
4530 doc: /* Value is the value of window property PROP on FRAME.
4531 If FRAME is nil or omitted, use the selected frame.
4532 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4533 is the name of the Atom that denotes the type expected.
4534 If SOURCE is non-nil, get the property on that window instead of from
4535 FRAME. The number 0 denotes the root window.
4536 If DELETE_P is non-nil, delete the property after retreiving it.
4537 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4539 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4540 no value of TYPE. */)
4541 (prop, frame, type, source, delete_p, vector_ret_p)
4542 Lisp_Object prop, frame, type, source, delete_p, vector_ret_p;
4544 struct frame *f = check_x_frame (frame);
4545 Atom prop_atom;
4546 int rc;
4547 Lisp_Object prop_value = Qnil;
4548 unsigned char *tmp_data = NULL;
4549 Atom actual_type;
4550 Atom target_type = XA_STRING;
4551 int actual_format;
4552 unsigned long actual_size, bytes_remaining;
4553 Window target_window = FRAME_X_WINDOW (f);
4554 struct gcpro gcpro1;
4556 GCPRO1 (prop_value);
4557 CHECK_STRING (prop);
4559 if (! NILP (source))
4561 if (NUMBERP (source))
4563 if (FLOATP (source))
4564 target_window = (Window) XFLOAT (source);
4565 else
4566 target_window = XFASTINT (source);
4568 if (target_window == 0)
4569 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4571 else if (CONSP (source))
4572 target_window = cons_to_long (source);
4575 BLOCK_INPUT;
4576 if (STRINGP (type))
4578 if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
4579 target_type = AnyPropertyType;
4580 else
4581 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4584 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4585 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4586 prop_atom, 0, 0, False, target_type,
4587 &actual_type, &actual_format, &actual_size,
4588 &bytes_remaining, &tmp_data);
4589 if (rc == Success)
4591 int size = bytes_remaining;
4593 XFree (tmp_data);
4594 tmp_data = NULL;
4596 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4597 prop_atom, 0, bytes_remaining,
4598 ! NILP (delete_p), target_type,
4599 &actual_type, &actual_format,
4600 &actual_size, &bytes_remaining,
4601 &tmp_data);
4602 if (rc == Success && tmp_data)
4604 /* The man page for XGetWindowProperty says:
4605 "If the returned format is 32, the returned data is represented
4606 as a long array and should be cast to that type to obtain the
4607 elements."
4608 This applies even if long is more than 32 bits, the X library
4609 converts from 32 bit elements received from the X server to long
4610 and passes the long array to us. Thus, for that case bcopy can not
4611 be used. We convert to a 32 bit type here, because so much code
4612 assume on that.
4614 The bytes and offsets passed to XGetWindowProperty refers to the
4615 property and those are indeed in 32 bit quantities if format is
4616 32. */
4618 if (actual_format == 32 && actual_format < BITS_PER_LONG)
4620 unsigned long i;
4621 int *idata = (int *) tmp_data;
4622 long *ldata = (long *) tmp_data;
4624 for (i = 0; i < actual_size; ++i)
4625 idata[i] = (int) ldata[i];
4628 if (NILP (vector_ret_p))
4629 prop_value = make_string (tmp_data, size);
4630 else
4631 prop_value = x_property_data_to_lisp (f,
4632 tmp_data,
4633 actual_type,
4634 actual_format,
4635 actual_size);
4638 if (tmp_data) XFree (tmp_data);
4641 UNBLOCK_INPUT;
4642 UNGCPRO;
4643 return prop_value;
4648 /***********************************************************************
4649 Busy cursor
4650 ***********************************************************************/
4652 /* If non-null, an asynchronous timer that, when it expires, displays
4653 an hourglass cursor on all frames. */
4655 static struct atimer *hourglass_atimer;
4657 /* Non-zero means an hourglass cursor is currently shown. */
4659 static int hourglass_shown_p;
4661 /* Number of seconds to wait before displaying an hourglass cursor. */
4663 static Lisp_Object Vhourglass_delay;
4665 /* Default number of seconds to wait before displaying an hourglass
4666 cursor. */
4668 #define DEFAULT_HOURGLASS_DELAY 1
4670 /* Function prototypes. */
4672 static void show_hourglass P_ ((struct atimer *));
4673 static void hide_hourglass P_ ((void));
4675 /* Return non-zero if houglass timer has been started or hourglass is shown. */
4678 hourglass_started ()
4680 return hourglass_shown_p || hourglass_atimer != NULL;
4684 /* Cancel a currently active hourglass timer, and start a new one. */
4686 void
4687 start_hourglass ()
4689 EMACS_TIME delay;
4690 int secs, usecs = 0;
4692 /* Don't bother for ttys. */
4693 if (NILP (Vwindow_system))
4694 return;
4696 cancel_hourglass ();
4698 if (INTEGERP (Vhourglass_delay)
4699 && XINT (Vhourglass_delay) > 0)
4700 secs = XFASTINT (Vhourglass_delay);
4701 else if (FLOATP (Vhourglass_delay)
4702 && XFLOAT_DATA (Vhourglass_delay) > 0)
4704 Lisp_Object tem;
4705 tem = Ftruncate (Vhourglass_delay, Qnil);
4706 secs = XFASTINT (tem);
4707 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
4709 else
4710 secs = DEFAULT_HOURGLASS_DELAY;
4712 EMACS_SET_SECS_USECS (delay, secs, usecs);
4713 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
4714 show_hourglass, NULL);
4718 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
4719 shown. */
4721 void
4722 cancel_hourglass ()
4724 if (hourglass_atimer)
4726 cancel_atimer (hourglass_atimer);
4727 hourglass_atimer = NULL;
4730 if (hourglass_shown_p)
4731 hide_hourglass ();
4735 /* Timer function of hourglass_atimer. TIMER is equal to
4736 hourglass_atimer.
4738 Display an hourglass pointer on all frames by mapping the frames'
4739 hourglass_window. Set the hourglass_p flag in the frames'
4740 output_data.x structure to indicate that an hourglass cursor is
4741 shown on the frames. */
4743 static void
4744 show_hourglass (timer)
4745 struct atimer *timer;
4747 /* The timer implementation will cancel this timer automatically
4748 after this function has run. Set hourglass_atimer to null
4749 so that we know the timer doesn't have to be canceled. */
4750 hourglass_atimer = NULL;
4752 if (!hourglass_shown_p)
4754 Lisp_Object rest, frame;
4756 BLOCK_INPUT;
4758 FOR_EACH_FRAME (rest, frame)
4760 struct frame *f = XFRAME (frame);
4762 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4764 Display *dpy = FRAME_X_DISPLAY (f);
4766 #ifdef USE_X_TOOLKIT
4767 if (f->output_data.x->widget)
4768 #else
4769 if (FRAME_OUTER_WINDOW (f))
4770 #endif
4772 f->output_data.x->hourglass_p = 1;
4774 if (!f->output_data.x->hourglass_window)
4776 unsigned long mask = CWCursor;
4777 XSetWindowAttributes attrs;
4778 #ifdef USE_GTK
4779 Window parent = FRAME_X_WINDOW (f);
4780 #else
4781 Window parent = FRAME_OUTER_WINDOW (f);
4782 #endif
4783 attrs.cursor = f->output_data.x->hourglass_cursor;
4785 f->output_data.x->hourglass_window
4786 = XCreateWindow (dpy, parent,
4787 0, 0, 32000, 32000, 0, 0,
4788 InputOnly,
4789 CopyFromParent,
4790 mask, &attrs);
4793 XMapRaised (dpy, f->output_data.x->hourglass_window);
4794 XFlush (dpy);
4799 hourglass_shown_p = 1;
4800 UNBLOCK_INPUT;
4805 /* Hide the hourglass pointer on all frames, if it is currently
4806 shown. */
4808 static void
4809 hide_hourglass ()
4811 if (hourglass_shown_p)
4813 Lisp_Object rest, frame;
4815 BLOCK_INPUT;
4816 FOR_EACH_FRAME (rest, frame)
4818 struct frame *f = XFRAME (frame);
4820 if (FRAME_X_P (f)
4821 /* Watch out for newly created frames. */
4822 && f->output_data.x->hourglass_window)
4824 XUnmapWindow (FRAME_X_DISPLAY (f),
4825 f->output_data.x->hourglass_window);
4826 /* Sync here because XTread_socket looks at the
4827 hourglass_p flag that is reset to zero below. */
4828 XSync (FRAME_X_DISPLAY (f), False);
4829 f->output_data.x->hourglass_p = 0;
4833 hourglass_shown_p = 0;
4834 UNBLOCK_INPUT;
4840 /***********************************************************************
4841 Tool tips
4842 ***********************************************************************/
4844 static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *,
4845 Lisp_Object, Lisp_Object));
4846 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
4847 Lisp_Object, int, int, int *, int *));
4849 /* The frame of a currently visible tooltip. */
4851 Lisp_Object tip_frame;
4853 /* If non-nil, a timer started that hides the last tooltip when it
4854 fires. */
4856 Lisp_Object tip_timer;
4857 Window tip_window;
4859 /* If non-nil, a vector of 3 elements containing the last args
4860 with which x-show-tip was called. See there. */
4862 Lisp_Object last_show_tip_args;
4864 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4866 Lisp_Object Vx_max_tooltip_size;
4869 static Lisp_Object
4870 unwind_create_tip_frame (frame)
4871 Lisp_Object frame;
4873 Lisp_Object deleted;
4875 deleted = unwind_create_frame (frame);
4876 if (EQ (deleted, Qt))
4878 tip_window = None;
4879 tip_frame = Qnil;
4882 return deleted;
4886 /* Create a frame for a tooltip on the display described by DPYINFO.
4887 PARMS is a list of frame parameters. TEXT is the string to
4888 display in the tip frame. Value is the frame.
4890 Note that functions called here, esp. x_default_parameter can
4891 signal errors, for instance when a specified color name is
4892 undefined. We have to make sure that we're in a consistent state
4893 when this happens. */
4895 static Lisp_Object
4896 x_create_tip_frame (dpyinfo, parms, text)
4897 struct x_display_info *dpyinfo;
4898 Lisp_Object parms, text;
4900 struct frame *f;
4901 Lisp_Object frame, tem;
4902 Lisp_Object name;
4903 long window_prompting = 0;
4904 int width, height;
4905 int count = SPECPDL_INDEX ();
4906 struct gcpro gcpro1, gcpro2, gcpro3;
4907 struct kboard *kb;
4908 int face_change_count_before = face_change_count;
4909 Lisp_Object buffer;
4910 struct buffer *old_buffer;
4912 check_x ();
4914 parms = Fcopy_alist (parms);
4916 #ifdef MULTI_KBOARD
4917 kb = dpyinfo->kboard;
4918 #else
4919 kb = &the_only_kboard;
4920 #endif
4922 /* Get the name of the frame to use for resource lookup. */
4923 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4924 if (!STRINGP (name)
4925 && !EQ (name, Qunbound)
4926 && !NILP (name))
4927 error ("Invalid frame name--not a string or nil");
4929 frame = Qnil;
4930 GCPRO3 (parms, name, frame);
4931 f = make_frame (1);
4932 XSETFRAME (frame, f);
4934 buffer = Fget_buffer_create (build_string (" *tip*"));
4935 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
4936 old_buffer = current_buffer;
4937 set_buffer_internal_1 (XBUFFER (buffer));
4938 current_buffer->truncate_lines = Qnil;
4939 specbind (Qinhibit_read_only, Qt);
4940 specbind (Qinhibit_modification_hooks, Qt);
4941 Ferase_buffer ();
4942 Finsert (1, &text);
4943 set_buffer_internal_1 (old_buffer);
4945 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4946 record_unwind_protect (unwind_create_tip_frame, frame);
4948 /* By setting the output method, we're essentially saying that
4949 the frame is live, as per FRAME_LIVE_P. If we get a signal
4950 from this point on, x_destroy_window might screw up reference
4951 counts etc. */
4952 f->output_method = output_x_window;
4953 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
4954 bzero (f->output_data.x, sizeof (struct x_output));
4955 f->output_data.x->icon_bitmap = -1;
4956 FRAME_FONTSET (f) = -1;
4957 f->output_data.x->scroll_bar_foreground_pixel = -1;
4958 f->output_data.x->scroll_bar_background_pixel = -1;
4959 #ifdef USE_TOOLKIT_SCROLL_BARS
4960 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4961 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4962 #endif /* USE_TOOLKIT_SCROLL_BARS */
4963 f->icon_name = Qnil;
4964 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4965 #if GLYPH_DEBUG
4966 image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
4967 dpyinfo_refcount = dpyinfo->reference_count;
4968 #endif /* GLYPH_DEBUG */
4969 #ifdef MULTI_KBOARD
4970 FRAME_KBOARD (f) = kb;
4971 #endif
4972 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4973 f->output_data.x->explicit_parent = 0;
4975 /* These colors will be set anyway later, but it's important
4976 to get the color reference counts right, so initialize them! */
4978 Lisp_Object black;
4979 struct gcpro gcpro1;
4981 black = build_string ("black");
4982 GCPRO1 (black);
4983 f->output_data.x->foreground_pixel
4984 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4985 f->output_data.x->background_pixel
4986 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4987 f->output_data.x->cursor_pixel
4988 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4989 f->output_data.x->cursor_foreground_pixel
4990 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4991 f->output_data.x->border_pixel
4992 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4993 f->output_data.x->mouse_pixel
4994 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4995 UNGCPRO;
4998 /* Set the name; the functions to which we pass f expect the name to
4999 be set. */
5000 if (EQ (name, Qunbound) || NILP (name))
5002 f->name = build_string (dpyinfo->x_id_name);
5003 f->explicit_name = 0;
5005 else
5007 f->name = name;
5008 f->explicit_name = 1;
5009 /* use the frame's title when getting resources for this frame. */
5010 specbind (Qx_resource_name, name);
5013 f->resx = dpyinfo->resx;
5014 f->resy = dpyinfo->resy;
5016 #ifdef USE_FONT_BACKEND
5017 if (enable_font_backend)
5019 /* Perhaps, we must allow frame parameter, say `font-backend',
5020 to specify which font backends to use. */
5021 #ifdef HAVE_FREETYPE
5022 #ifdef HAVE_XFT
5023 register_font_driver (&xftfont_driver, f);
5024 #else /* not HAVE_XFT */
5025 register_font_driver (&ftxfont_driver, f);
5026 #endif /* not HAVE_XFT */
5027 #endif /* HAVE_FREETYPE */
5028 register_font_driver (&xfont_driver, f);
5030 x_default_parameter (f, parms, Qfont_backend, Qnil,
5031 "fontBackend", "FontBackend", RES_TYPE_STRING);
5033 #endif /* USE_FONT_BACKEND */
5035 /* Extract the window parameters from the supplied values that are
5036 needed to determine window geometry. */
5037 #ifdef USE_FONT_BACKEND
5038 if (enable_font_backend)
5039 x_default_font_parameter (f, parms);
5040 else
5041 #endif /* USE_FONT_BACKEND */
5043 Lisp_Object font;
5045 font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
5047 BLOCK_INPUT;
5048 /* First, try whatever font the caller has specified. */
5049 if (STRINGP (font))
5051 tem = Fquery_fontset (font, Qnil);
5052 if (STRINGP (tem))
5053 font = x_new_fontset (f, tem);
5054 else
5055 font = x_new_font (f, SDATA (font));
5058 /* Try out a font which we hope has bold and italic variations. */
5059 if (!STRINGP (font))
5060 font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
5061 if (!STRINGP (font))
5062 font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
5063 if (! STRINGP (font))
5064 font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
5065 if (! STRINGP (font))
5066 /* This was formerly the first thing tried, but it finds too many fonts
5067 and takes too long. */
5068 font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
5069 /* If those didn't work, look for something which will at least work. */
5070 if (! STRINGP (font))
5071 font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
5072 UNBLOCK_INPUT;
5073 if (! STRINGP (font))
5074 font = build_string ("fixed");
5076 x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil));
5079 x_default_parameter (f, parms, Qborder_width, make_number (2),
5080 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
5082 /* This defaults to 2 in order to match xterm. We recognize either
5083 internalBorderWidth or internalBorder (which is what xterm calls
5084 it). */
5085 if (NILP (Fassq (Qinternal_border_width, parms)))
5087 Lisp_Object value;
5089 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
5090 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
5091 if (! EQ (value, Qunbound))
5092 parms = Fcons (Fcons (Qinternal_border_width, value),
5093 parms);
5096 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
5097 "internalBorderWidth", "internalBorderWidth",
5098 RES_TYPE_NUMBER);
5100 /* Also do the stuff which must be set before the window exists. */
5101 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
5102 "foreground", "Foreground", RES_TYPE_STRING);
5103 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
5104 "background", "Background", RES_TYPE_STRING);
5105 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
5106 "pointerColor", "Foreground", RES_TYPE_STRING);
5107 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
5108 "cursorColor", "Foreground", RES_TYPE_STRING);
5109 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
5110 "borderColor", "BorderColor", RES_TYPE_STRING);
5112 /* Init faces before x_default_parameter is called for scroll-bar
5113 parameters because that function calls x_set_scroll_bar_width,
5114 which calls change_frame_size, which calls Fset_window_buffer,
5115 which runs hooks, which call Fvertical_motion. At the end, we
5116 end up in init_iterator with a null face cache, which should not
5117 happen. */
5118 init_frame_faces (f);
5120 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
5122 window_prompting = x_figure_window_size (f, parms, 0);
5125 XSetWindowAttributes attrs;
5126 unsigned long mask;
5128 BLOCK_INPUT;
5129 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
5130 if (DoesSaveUnders (dpyinfo->screen))
5131 mask |= CWSaveUnder;
5133 /* Window managers look at the override-redirect flag to determine
5134 whether or net to give windows a decoration (Xlib spec, chapter
5135 3.2.8). */
5136 attrs.override_redirect = True;
5137 attrs.save_under = True;
5138 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
5139 /* Arrange for getting MapNotify and UnmapNotify events. */
5140 attrs.event_mask = StructureNotifyMask;
5141 tip_window
5142 = FRAME_X_WINDOW (f)
5143 = XCreateWindow (FRAME_X_DISPLAY (f),
5144 FRAME_X_DISPLAY_INFO (f)->root_window,
5145 /* x, y, width, height */
5146 0, 0, 1, 1,
5147 /* Border. */
5149 CopyFromParent, InputOutput, CopyFromParent,
5150 mask, &attrs);
5151 UNBLOCK_INPUT;
5154 x_make_gc (f);
5156 x_default_parameter (f, parms, Qauto_raise, Qnil,
5157 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5158 x_default_parameter (f, parms, Qauto_lower, Qnil,
5159 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5160 x_default_parameter (f, parms, Qcursor_type, Qbox,
5161 "cursorType", "CursorType", RES_TYPE_SYMBOL);
5163 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5164 Change will not be effected unless different from the current
5165 FRAME_LINES (f). */
5166 width = FRAME_COLS (f);
5167 height = FRAME_LINES (f);
5168 SET_FRAME_COLS (f, 0);
5169 FRAME_LINES (f) = 0;
5170 change_frame_size (f, height, width, 1, 0, 0);
5172 /* Add `tooltip' frame parameter's default value. */
5173 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
5174 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
5175 Qnil));
5177 /* Set up faces after all frame parameters are known. This call
5178 also merges in face attributes specified for new frames.
5180 Frame parameters may be changed if .Xdefaults contains
5181 specifications for the default font. For example, if there is an
5182 `Emacs.default.attributeBackground: pink', the `background-color'
5183 attribute of the frame get's set, which let's the internal border
5184 of the tooltip frame appear in pink. Prevent this. */
5186 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
5188 /* Set tip_frame here, so that */
5189 tip_frame = frame;
5190 call1 (Qface_set_after_frame_default, frame);
5192 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
5193 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
5194 Qnil));
5197 f->no_split = 1;
5199 UNGCPRO;
5201 /* It is now ok to make the frame official even if we get an error
5202 below. And the frame needs to be on Vframe_list or making it
5203 visible won't work. */
5204 Vframe_list = Fcons (frame, Vframe_list);
5206 /* Now that the frame is official, it counts as a reference to
5207 its display. */
5208 FRAME_X_DISPLAY_INFO (f)->reference_count++;
5210 /* Setting attributes of faces of the tooltip frame from resources
5211 and similar will increment face_change_count, which leads to the
5212 clearing of all current matrices. Since this isn't necessary
5213 here, avoid it by resetting face_change_count to the value it
5214 had before we created the tip frame. */
5215 face_change_count = face_change_count_before;
5217 /* Discard the unwind_protect. */
5218 return unbind_to (count, frame);
5222 /* Compute where to display tip frame F. PARMS is the list of frame
5223 parameters for F. DX and DY are specified offsets from the current
5224 location of the mouse. WIDTH and HEIGHT are the width and height
5225 of the tooltip. Return coordinates relative to the root window of
5226 the display in *ROOT_X, and *ROOT_Y. */
5228 static void
5229 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
5230 struct frame *f;
5231 Lisp_Object parms, dx, dy;
5232 int width, height;
5233 int *root_x, *root_y;
5235 Lisp_Object left, top;
5236 int win_x, win_y;
5237 Window root, child;
5238 unsigned pmask;
5240 /* User-specified position? */
5241 left = Fcdr (Fassq (Qleft, parms));
5242 top = Fcdr (Fassq (Qtop, parms));
5244 /* Move the tooltip window where the mouse pointer is. Resize and
5245 show it. */
5246 if (!INTEGERP (left) || !INTEGERP (top))
5248 BLOCK_INPUT;
5249 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
5250 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
5251 UNBLOCK_INPUT;
5254 if (INTEGERP (top))
5255 *root_y = XINT (top);
5256 else if (*root_y + XINT (dy) <= 0)
5257 *root_y = 0; /* Can happen for negative dy */
5258 else if (*root_y + XINT (dy) + height <= FRAME_X_DISPLAY_INFO (f)->height)
5259 /* It fits below the pointer */
5260 *root_y += XINT (dy);
5261 else if (height + XINT (dy) <= *root_y)
5262 /* It fits above the pointer. */
5263 *root_y -= height + XINT (dy);
5264 else
5265 /* Put it on the top. */
5266 *root_y = 0;
5268 if (INTEGERP (left))
5269 *root_x = XINT (left);
5270 else if (*root_x + XINT (dx) <= 0)
5271 *root_x = 0; /* Can happen for negative dx */
5272 else if (*root_x + XINT (dx) + width <= FRAME_X_DISPLAY_INFO (f)->width)
5273 /* It fits to the right of the pointer. */
5274 *root_x += XINT (dx);
5275 else if (width + XINT (dx) <= *root_x)
5276 /* It fits to the left of the pointer. */
5277 *root_x -= width + XINT (dx);
5278 else
5279 /* Put it left-justified on the screen--it ought to fit that way. */
5280 *root_x = 0;
5284 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5285 doc: /* Show STRING in a "tooltip" window on frame FRAME.
5286 A tooltip window is a small X window displaying a string.
5288 This is an internal function; Lisp code should call `tooltip-show'.
5290 FRAME nil or omitted means use the selected frame.
5292 PARMS is an optional list of frame parameters which can be used to
5293 change the tooltip's appearance.
5295 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5296 means use the default timeout of 5 seconds.
5298 If the list of frame parameters PARAMS contains a `left' parameters,
5299 the tooltip is displayed at that x-position. Otherwise it is
5300 displayed at the mouse position, with offset DX added (default is 5 if
5301 DX isn't specified). Likewise for the y-position; if a `top' frame
5302 parameter is specified, it determines the y-position of the tooltip
5303 window, otherwise it is displayed at the mouse position, with offset
5304 DY added (default is -10).
5306 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5307 Text larger than the specified size is clipped. */)
5308 (string, frame, parms, timeout, dx, dy)
5309 Lisp_Object string, frame, parms, timeout, dx, dy;
5311 struct frame *f;
5312 struct window *w;
5313 int root_x, root_y;
5314 struct buffer *old_buffer;
5315 struct text_pos pos;
5316 int i, width, height;
5317 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5318 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5319 int count = SPECPDL_INDEX ();
5321 specbind (Qinhibit_redisplay, Qt);
5323 GCPRO4 (string, parms, frame, timeout);
5325 CHECK_STRING (string);
5326 f = check_x_frame (frame);
5327 if (NILP (timeout))
5328 timeout = make_number (5);
5329 else
5330 CHECK_NATNUM (timeout);
5332 if (NILP (dx))
5333 dx = make_number (5);
5334 else
5335 CHECK_NUMBER (dx);
5337 if (NILP (dy))
5338 dy = make_number (-10);
5339 else
5340 CHECK_NUMBER (dy);
5342 if (NILP (last_show_tip_args))
5343 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5345 if (!NILP (tip_frame))
5347 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5348 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5349 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5351 if (EQ (frame, last_frame)
5352 && !NILP (Fequal (last_string, string))
5353 && !NILP (Fequal (last_parms, parms)))
5355 struct frame *f = XFRAME (tip_frame);
5357 /* Only DX and DY have changed. */
5358 if (!NILP (tip_timer))
5360 Lisp_Object timer = tip_timer;
5361 tip_timer = Qnil;
5362 call1 (Qcancel_timer, timer);
5365 BLOCK_INPUT;
5366 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
5367 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
5368 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5369 root_x, root_y);
5370 UNBLOCK_INPUT;
5371 goto start_timer;
5375 /* Hide a previous tip, if any. */
5376 Fx_hide_tip ();
5378 ASET (last_show_tip_args, 0, string);
5379 ASET (last_show_tip_args, 1, frame);
5380 ASET (last_show_tip_args, 2, parms);
5382 /* Add default values to frame parameters. */
5383 if (NILP (Fassq (Qname, parms)))
5384 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5385 if (NILP (Fassq (Qinternal_border_width, parms)))
5386 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5387 if (NILP (Fassq (Qborder_width, parms)))
5388 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5389 if (NILP (Fassq (Qborder_color, parms)))
5390 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5391 if (NILP (Fassq (Qbackground_color, parms)))
5392 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5393 parms);
5395 /* Create a frame for the tooltip, and record it in the global
5396 variable tip_frame. */
5397 frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
5398 f = XFRAME (frame);
5400 /* Set up the frame's root window. */
5401 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5402 w->left_col = w->top_line = make_number (0);
5404 if (CONSP (Vx_max_tooltip_size)
5405 && INTEGERP (XCAR (Vx_max_tooltip_size))
5406 && XINT (XCAR (Vx_max_tooltip_size)) > 0
5407 && INTEGERP (XCDR (Vx_max_tooltip_size))
5408 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5410 w->total_cols = XCAR (Vx_max_tooltip_size);
5411 w->total_lines = XCDR (Vx_max_tooltip_size);
5413 else
5415 w->total_cols = make_number (80);
5416 w->total_lines = make_number (40);
5419 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5420 adjust_glyphs (f);
5421 w->pseudo_window_p = 1;
5423 /* Display the tooltip text in a temporary buffer. */
5424 old_buffer = current_buffer;
5425 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5426 current_buffer->truncate_lines = Qnil;
5427 clear_glyph_matrix (w->desired_matrix);
5428 clear_glyph_matrix (w->current_matrix);
5429 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5430 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
5432 /* Compute width and height of the tooltip. */
5433 width = height = 0;
5434 for (i = 0; i < w->desired_matrix->nrows; ++i)
5436 struct glyph_row *row = &w->desired_matrix->rows[i];
5437 struct glyph *last;
5438 int row_width;
5440 /* Stop at the first empty row at the end. */
5441 if (!row->enabled_p || !row->displays_text_p)
5442 break;
5444 /* Let the row go over the full width of the frame. */
5445 row->full_width_p = 1;
5447 /* There's a glyph at the end of rows that is used to place
5448 the cursor there. Don't include the width of this glyph. */
5449 if (row->used[TEXT_AREA])
5451 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5452 row_width = row->pixel_width - last->pixel_width;
5454 else
5455 row_width = row->pixel_width;
5457 height += row->height;
5458 width = max (width, row_width);
5461 /* Add the frame's internal border to the width and height the X
5462 window should have. */
5463 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5464 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5466 /* Move the tooltip window where the mouse pointer is. Resize and
5467 show it. */
5468 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5470 BLOCK_INPUT;
5471 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5472 root_x, root_y, width, height);
5473 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5474 UNBLOCK_INPUT;
5476 /* Draw into the window. */
5477 w->must_be_updated_p = 1;
5478 update_single_window (w, 1);
5480 /* Restore original current buffer. */
5481 set_buffer_internal_1 (old_buffer);
5482 windows_or_buffers_changed = old_windows_or_buffers_changed;
5484 start_timer:
5485 /* Let the tip disappear after timeout seconds. */
5486 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5487 intern ("x-hide-tip"));
5489 UNGCPRO;
5490 return unbind_to (count, Qnil);
5494 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5495 doc: /* Hide the current tooltip window, if there is any.
5496 Value is t if tooltip was open, nil otherwise. */)
5499 int count;
5500 Lisp_Object deleted, frame, timer;
5501 struct gcpro gcpro1, gcpro2;
5503 /* Return quickly if nothing to do. */
5504 if (NILP (tip_timer) && NILP (tip_frame))
5505 return Qnil;
5507 frame = tip_frame;
5508 timer = tip_timer;
5509 GCPRO2 (frame, timer);
5510 tip_frame = tip_timer = deleted = Qnil;
5512 count = SPECPDL_INDEX ();
5513 specbind (Qinhibit_redisplay, Qt);
5514 specbind (Qinhibit_quit, Qt);
5516 if (!NILP (timer))
5517 call1 (Qcancel_timer, timer);
5519 if (FRAMEP (frame))
5521 Fdelete_frame (frame, Qnil);
5522 deleted = Qt;
5524 #ifdef USE_LUCID
5525 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5526 redisplay procedure is not called when a tip frame over menu
5527 items is unmapped. Redisplay the menu manually... */
5529 struct frame *f = SELECTED_FRAME ();
5530 Widget w = f->output_data.x->menubar_widget;
5531 extern void xlwmenu_redisplay P_ ((Widget));
5533 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5534 && w != NULL)
5536 BLOCK_INPUT;
5537 xlwmenu_redisplay (w);
5538 UNBLOCK_INPUT;
5541 #endif /* USE_LUCID */
5544 UNGCPRO;
5545 return unbind_to (count, deleted);
5550 /***********************************************************************
5551 File selection dialog
5552 ***********************************************************************/
5554 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5555 Sx_uses_old_gtk_dialog,
5556 0, 0, 0,
5557 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5560 #ifdef USE_GTK
5561 extern int use_dialog_box;
5562 extern int use_file_dialog;
5564 if (use_dialog_box
5565 && use_file_dialog
5566 && have_menus_p ()
5567 && xg_uses_old_file_dialog ())
5568 return Qt;
5569 #endif
5570 return Qnil;
5574 #ifdef USE_MOTIF
5575 /* Callback for "OK" and "Cancel" on file selection dialog. */
5577 static void
5578 file_dialog_cb (widget, client_data, call_data)
5579 Widget widget;
5580 XtPointer call_data, client_data;
5582 int *result = (int *) client_data;
5583 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5584 *result = cb->reason;
5588 /* Callback for unmapping a file selection dialog. This is used to
5589 capture the case where a dialog is closed via a window manager's
5590 closer button, for example. Using a XmNdestroyCallback didn't work
5591 in this case. */
5593 static void
5594 file_dialog_unmap_cb (widget, client_data, call_data)
5595 Widget widget;
5596 XtPointer call_data, client_data;
5598 int *result = (int *) client_data;
5599 *result = XmCR_CANCEL;
5602 static Lisp_Object
5603 clean_up_file_dialog (arg)
5604 Lisp_Object arg;
5606 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5607 Widget dialog = (Widget) p->pointer;
5609 /* Clean up. */
5610 BLOCK_INPUT;
5611 XtUnmanageChild (dialog);
5612 XtDestroyWidget (dialog);
5613 x_menu_set_in_use (0);
5614 UNBLOCK_INPUT;
5616 return Qnil;
5620 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5621 doc: /* Read file name, prompting with PROMPT in directory DIR.
5622 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5623 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5624 or directory must exist. ONLY-DIR-P is ignored." */)
5625 (prompt, dir, default_filename, mustmatch, only_dir_p)
5626 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5628 int result;
5629 struct frame *f = SELECTED_FRAME ();
5630 Lisp_Object file = Qnil;
5631 Lisp_Object decoded_file;
5632 Widget dialog, text, help;
5633 Arg al[10];
5634 int ac = 0;
5635 extern XtAppContext Xt_app_con;
5636 XmString dir_xmstring, pattern_xmstring;
5637 int count = SPECPDL_INDEX ();
5638 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5640 check_x ();
5642 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5644 if (popup_activated ())
5645 error ("Trying to use a menu from within a menu-entry");
5647 CHECK_STRING (prompt);
5648 CHECK_STRING (dir);
5650 /* Prevent redisplay. */
5651 specbind (Qinhibit_redisplay, Qt);
5653 BLOCK_INPUT;
5655 /* Create the dialog with PROMPT as title, using DIR as initial
5656 directory and using "*" as pattern. */
5657 dir = Fexpand_file_name (dir, Qnil);
5658 dir_xmstring = XmStringCreateLocalized (SDATA (dir));
5659 pattern_xmstring = XmStringCreateLocalized ("*");
5661 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5662 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5663 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5664 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5665 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5666 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5667 "fsb", al, ac);
5668 XmStringFree (dir_xmstring);
5669 XmStringFree (pattern_xmstring);
5671 /* Add callbacks for OK and Cancel. */
5672 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5673 (XtPointer) &result);
5674 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5675 (XtPointer) &result);
5676 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5677 (XtPointer) &result);
5679 /* Remove the help button since we can't display help. */
5680 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5681 XtUnmanageChild (help);
5683 /* Mark OK button as default. */
5684 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5685 XmNshowAsDefault, True, NULL);
5687 /* If MUSTMATCH is non-nil, disable the file entry field of the
5688 dialog, so that the user must select a file from the files list
5689 box. We can't remove it because we wouldn't have a way to get at
5690 the result file name, then. */
5691 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5692 if (!NILP (mustmatch))
5694 Widget label;
5695 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5696 XtSetSensitive (text, False);
5697 XtSetSensitive (label, False);
5700 /* Manage the dialog, so that list boxes get filled. */
5701 XtManageChild (dialog);
5703 if (STRINGP (default_filename))
5705 XmString default_xmstring;
5706 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5707 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5709 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5710 XmTextFieldReplace (wtext, 0, last_pos,
5711 (SDATA (Ffile_name_nondirectory (default_filename))));
5713 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5714 must include the path for this to work. */
5716 default_xmstring = XmStringCreateLocalized (SDATA (default_filename));
5718 if (XmListItemExists (list, default_xmstring))
5720 int item_pos = XmListItemPos (list, default_xmstring);
5721 /* Select the item and scroll it into view. */
5722 XmListSelectPos (list, item_pos, True);
5723 XmListSetPos (list, item_pos);
5726 XmStringFree (default_xmstring);
5729 record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5731 /* Process events until the user presses Cancel or OK. */
5732 x_menu_set_in_use (1);
5733 result = 0;
5734 while (result == 0)
5736 XEvent event;
5737 x_menu_wait_for_event (0);
5738 XtAppNextEvent (Xt_app_con, &event);
5739 if (event.type == KeyPress
5740 && FRAME_X_DISPLAY (f) == event.xkey.display)
5742 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5744 /* Pop down on C-g. */
5745 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5746 XtUnmanageChild (dialog);
5749 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5752 /* Get the result. */
5753 if (result == XmCR_OK)
5755 XmString text;
5756 String data;
5758 XtVaGetValues (dialog, XmNtextString, &text, NULL);
5759 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
5760 XmStringFree (text);
5761 file = build_string (data);
5762 XtFree (data);
5764 else
5765 file = Qnil;
5767 UNBLOCK_INPUT;
5768 UNGCPRO;
5770 /* Make "Cancel" equivalent to C-g. */
5771 if (NILP (file))
5772 Fsignal (Qquit, Qnil);
5774 decoded_file = DECODE_FILE (file);
5776 return unbind_to (count, decoded_file);
5779 #endif /* USE_MOTIF */
5781 #ifdef USE_GTK
5783 static Lisp_Object
5784 clean_up_dialog (arg)
5785 Lisp_Object arg;
5787 x_menu_set_in_use (0);
5789 return Qnil;
5792 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5793 doc: /* Read file name, prompting with PROMPT in directory DIR.
5794 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5795 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5796 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5797 directories. */)
5798 (prompt, dir, default_filename, mustmatch, only_dir_p)
5799 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5801 FRAME_PTR f = SELECTED_FRAME ();
5802 char *fn;
5803 Lisp_Object file = Qnil;
5804 Lisp_Object decoded_file;
5805 int count = SPECPDL_INDEX ();
5806 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5807 char *cdef_file;
5809 check_x ();
5811 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5813 if (popup_activated ())
5814 error ("Trying to use a menu from within a menu-entry");
5816 CHECK_STRING (prompt);
5817 CHECK_STRING (dir);
5819 /* Prevent redisplay. */
5820 specbind (Qinhibit_redisplay, Qt);
5821 record_unwind_protect (clean_up_dialog, Qnil);
5823 BLOCK_INPUT;
5825 if (STRINGP (default_filename))
5826 cdef_file = SDATA (default_filename);
5827 else
5828 cdef_file = SDATA (dir);
5830 fn = xg_get_file_name (f, SDATA (prompt), cdef_file,
5831 ! NILP (mustmatch),
5832 ! NILP (only_dir_p));
5834 if (fn)
5836 file = build_string (fn);
5837 xfree (fn);
5840 UNBLOCK_INPUT;
5841 UNGCPRO;
5843 /* Make "Cancel" equivalent to C-g. */
5844 if (NILP (file))
5845 Fsignal (Qquit, Qnil);
5847 decoded_file = DECODE_FILE (file);
5849 return unbind_to (count, decoded_file);
5852 #endif /* USE_GTK */
5855 /***********************************************************************
5856 Keyboard
5857 ***********************************************************************/
5859 #ifdef HAVE_XKBGETKEYBOARD
5860 #include <X11/XKBlib.h>
5861 #include <X11/keysym.h>
5862 #endif
5864 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5865 Sx_backspace_delete_keys_p, 0, 1, 0,
5866 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5867 FRAME nil means use the selected frame.
5868 Value is t if we know that both keys are present, and are mapped to the
5869 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5870 present and mapped to the usual X keysyms. */)
5871 (frame)
5872 Lisp_Object frame;
5874 #ifdef HAVE_XKBGETKEYBOARD
5875 XkbDescPtr kb;
5876 struct frame *f = check_x_frame (frame);
5877 Display *dpy = FRAME_X_DISPLAY (f);
5878 Lisp_Object have_keys;
5879 int major, minor, op, event, error;
5881 BLOCK_INPUT;
5883 /* Check library version in case we're dynamically linked. */
5884 major = XkbMajorVersion;
5885 minor = XkbMinorVersion;
5886 if (!XkbLibraryVersion (&major, &minor))
5888 UNBLOCK_INPUT;
5889 return Qlambda;
5892 /* Check that the server supports XKB. */
5893 major = XkbMajorVersion;
5894 minor = XkbMinorVersion;
5895 if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
5897 UNBLOCK_INPUT;
5898 return Qlambda;
5901 /* In this code we check that the keyboard has physical keys with names
5902 that start with BKSP (Backspace) and DELE (Delete), and that they
5903 generate keysym XK_BackSpace and XK_Delete respectively.
5904 This function is used to test if normal-erase-is-backspace should be
5905 turned on.
5906 An alternative approach would be to just check if XK_BackSpace and
5907 XK_Delete are mapped to any key. But if any of those are mapped to
5908 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5909 user doesn't know about it, it is better to return false here.
5910 It is more obvious to the user what to do if she/he has two keys
5911 clearly marked with names/symbols and one key does something not
5912 expected (i.e. she/he then tries the other).
5913 The cases where Backspace/Delete is mapped to some other key combination
5914 are rare, and in those cases, normal-erase-is-backspace can be turned on
5915 manually. */
5917 have_keys = Qnil;
5918 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5919 if (kb)
5921 int delete_keycode = 0, backspace_keycode = 0, i;
5923 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5925 for (i = kb->min_key_code;
5926 (i < kb->max_key_code
5927 && (delete_keycode == 0 || backspace_keycode == 0));
5928 ++i)
5930 /* The XKB symbolic key names can be seen most easily in
5931 the PS file generated by `xkbprint -label name
5932 $DISPLAY'. */
5933 if (bcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5934 delete_keycode = i;
5935 else if (bcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5936 backspace_keycode = i;
5939 XkbFreeNames (kb, 0, True);
5942 XkbFreeClientMap (kb, 0, True);
5944 if (delete_keycode
5945 && backspace_keycode
5946 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5947 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5948 have_keys = Qt;
5950 UNBLOCK_INPUT;
5951 return have_keys;
5952 #else /* not HAVE_XKBGETKEYBOARD */
5953 return Qlambda;
5954 #endif /* not HAVE_XKBGETKEYBOARD */
5959 /***********************************************************************
5960 Initialization
5961 ***********************************************************************/
5963 /* Keep this list in the same order as frame_parms in frame.c.
5964 Use 0 for unsupported frame parameters. */
5966 frame_parm_handler x_frame_parm_handlers[] =
5968 x_set_autoraise,
5969 x_set_autolower,
5970 x_set_background_color,
5971 x_set_border_color,
5972 x_set_border_width,
5973 x_set_cursor_color,
5974 x_set_cursor_type,
5975 x_set_font,
5976 x_set_foreground_color,
5977 x_set_icon_name,
5978 x_set_icon_type,
5979 x_set_internal_border_width,
5980 x_set_menu_bar_lines,
5981 x_set_mouse_color,
5982 x_explicitly_set_name,
5983 x_set_scroll_bar_width,
5984 x_set_title,
5985 x_set_unsplittable,
5986 x_set_vertical_scroll_bars,
5987 x_set_visibility,
5988 x_set_tool_bar_lines,
5989 x_set_scroll_bar_foreground,
5990 x_set_scroll_bar_background,
5991 x_set_screen_gamma,
5992 x_set_line_spacing,
5993 x_set_fringe_width,
5994 x_set_fringe_width,
5995 x_set_wait_for_wm,
5996 x_set_fullscreen,
5997 #ifdef USE_FONT_BACKEND
5998 x_set_font_backend
5999 #endif /* USE_FONT_BACKEND */
6002 void
6003 syms_of_xfns ()
6005 /* This is zero if not using X windows. */
6006 x_in_use = 0;
6008 /* The section below is built by the lisp expression at the top of the file,
6009 just above where these variables are declared. */
6010 /*&&& init symbols here &&&*/
6011 Qnone = intern ("none");
6012 staticpro (&Qnone);
6013 Qsuppress_icon = intern ("suppress-icon");
6014 staticpro (&Qsuppress_icon);
6015 Qundefined_color = intern ("undefined-color");
6016 staticpro (&Qundefined_color);
6017 Qcompound_text = intern ("compound-text");
6018 staticpro (&Qcompound_text);
6019 Qcancel_timer = intern ("cancel-timer");
6020 staticpro (&Qcancel_timer);
6021 /* This is the end of symbol initialization. */
6023 /* Text property `display' should be nonsticky by default. */
6024 Vtext_property_default_nonsticky
6025 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
6028 Fput (Qundefined_color, Qerror_conditions,
6029 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
6030 Fput (Qundefined_color, Qerror_message,
6031 build_string ("Undefined color"));
6033 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
6034 doc: /* The shape of the pointer when over text.
6035 Changing the value does not affect existing frames
6036 unless you set the mouse color. */);
6037 Vx_pointer_shape = Qnil;
6039 #if 0 /* This doesn't really do anything. */
6040 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
6041 doc: /* The shape of the pointer when not over text.
6042 This variable takes effect when you create a new frame
6043 or when you set the mouse color. */);
6044 #endif
6045 Vx_nontext_pointer_shape = Qnil;
6047 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
6048 doc: /* The shape of the pointer when Emacs is busy.
6049 This variable takes effect when you create a new frame
6050 or when you set the mouse color. */);
6051 Vx_hourglass_pointer_shape = Qnil;
6053 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
6054 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
6055 display_hourglass_p = 1;
6057 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
6058 doc: /* *Seconds to wait before displaying an hourglass pointer.
6059 Value must be an integer or float. */);
6060 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
6062 #if 0 /* This doesn't really do anything. */
6063 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
6064 doc: /* The shape of the pointer when over the mode line.
6065 This variable takes effect when you create a new frame
6066 or when you set the mouse color. */);
6067 #endif
6068 Vx_mode_pointer_shape = Qnil;
6070 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6071 &Vx_sensitive_text_pointer_shape,
6072 doc: /* The shape of the pointer when over mouse-sensitive text.
6073 This variable takes effect when you create a new frame
6074 or when you set the mouse color. */);
6075 Vx_sensitive_text_pointer_shape = Qnil;
6077 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6078 &Vx_window_horizontal_drag_shape,
6079 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
6080 This variable takes effect when you create a new frame
6081 or when you set the mouse color. */);
6082 Vx_window_horizontal_drag_shape = Qnil;
6084 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
6085 doc: /* A string indicating the foreground color of the cursor box. */);
6086 Vx_cursor_fore_pixel = Qnil;
6088 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
6089 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
6090 Text larger than this is clipped. */);
6091 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
6093 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
6094 doc: /* Non-nil if no X window manager is in use.
6095 Emacs doesn't try to figure this out; this is always nil
6096 unless you set it to something else. */);
6097 /* We don't have any way to find this out, so set it to nil
6098 and maybe the user would like to set it to t. */
6099 Vx_no_window_manager = Qnil;
6101 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6102 &Vx_pixel_size_width_font_regexp,
6103 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6105 Since Emacs gets width of a font matching with this regexp from
6106 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6107 such a font. This is especially effective for such large fonts as
6108 Chinese, Japanese, and Korean. */);
6109 Vx_pixel_size_width_font_regexp = Qnil;
6111 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6112 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog,
6113 doc: /* *Non-nil means prompt with the old GTK file selection dialog.
6114 If nil or if the file selection dialog is not available, the new GTK file
6115 chooser is used instead. To turn off all file dialogs set the
6116 variable `use-file-dialog'. */);
6117 x_gtk_use_old_file_dialog = 0;
6119 DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files,
6120 doc: /* *If non-nil, the GTK file chooser will by default show hidden files.
6121 Note that this is just the default, there is a toggle button on the file
6122 chooser to show or not show hidden files on a case by case basis. */);
6123 x_gtk_show_hidden_files = 0;
6125 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text,
6126 doc: /* *If non-nil, the GTK file chooser will show additional help text.
6127 If more space for files in the file chooser dialog is wanted, set this to nil
6128 to turn the additional text off. */);
6129 x_gtk_file_dialog_help_text = 1;
6131 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar,
6132 doc: /* *If non-nil, a detached tool bar is shown in full.
6133 The default is to just show an arrow and pressing on that arrow shows
6134 the tool bar buttons. */);
6135 x_gtk_whole_detached_tool_bar = 0;
6137 Fprovide (intern ("x"), Qnil);
6139 #ifdef USE_X_TOOLKIT
6140 Fprovide (intern ("x-toolkit"), Qnil);
6141 #ifdef USE_MOTIF
6142 Fprovide (intern ("motif"), Qnil);
6144 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
6145 doc: /* Version info for LessTif/Motif. */);
6146 Vmotif_version_string = build_string (XmVERSION_STRING);
6147 #endif /* USE_MOTIF */
6148 #endif /* USE_X_TOOLKIT */
6150 #ifdef USE_GTK
6151 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6152 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6153 But for a user it is a toolkit for X, and indeed, configure
6154 accepts --with-x-toolkit=gtk. */
6155 Fprovide (intern ("x-toolkit"), Qnil);
6156 Fprovide (intern ("gtk"), Qnil);
6158 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
6159 doc: /* Version info for GTK+. */);
6161 char gtk_version[40];
6162 g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
6163 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
6164 Vgtk_version_string = build_string (gtk_version);
6166 #endif /* USE_GTK */
6168 /* X window properties. */
6169 defsubr (&Sx_change_window_property);
6170 defsubr (&Sx_delete_window_property);
6171 defsubr (&Sx_window_property);
6173 defsubr (&Sxw_display_color_p);
6174 defsubr (&Sx_display_grayscale_p);
6175 defsubr (&Sxw_color_defined_p);
6176 defsubr (&Sxw_color_values);
6177 defsubr (&Sx_server_max_request_size);
6178 defsubr (&Sx_server_vendor);
6179 defsubr (&Sx_server_version);
6180 defsubr (&Sx_display_pixel_width);
6181 defsubr (&Sx_display_pixel_height);
6182 defsubr (&Sx_display_mm_width);
6183 defsubr (&Sx_display_mm_height);
6184 defsubr (&Sx_display_screens);
6185 defsubr (&Sx_display_planes);
6186 defsubr (&Sx_display_color_cells);
6187 defsubr (&Sx_display_visual_class);
6188 defsubr (&Sx_display_backing_store);
6189 defsubr (&Sx_display_save_under);
6190 defsubr (&Sx_create_frame);
6191 defsubr (&Sx_open_connection);
6192 defsubr (&Sx_close_connection);
6193 defsubr (&Sx_display_list);
6194 defsubr (&Sx_synchronize);
6195 defsubr (&Sx_focus_frame);
6196 defsubr (&Sx_backspace_delete_keys_p);
6198 /* Setting callback functions for fontset handler. */
6199 get_font_info_func = x_get_font_info;
6201 #if 0 /* This function pointer doesn't seem to be used anywhere.
6202 And the pointer assigned has the wrong type, anyway. */
6203 list_fonts_func = x_list_fonts;
6204 #endif
6206 load_font_func = x_load_font;
6207 find_ccl_program_func = x_find_ccl_program;
6208 query_font_func = x_query_font;
6209 set_frame_fontset_func = x_set_font;
6210 get_font_repertory_func = x_get_font_repertory;
6211 check_window_system_func = check_x;
6213 hourglass_atimer = NULL;
6214 hourglass_shown_p = 0;
6216 defsubr (&Sx_show_tip);
6217 defsubr (&Sx_hide_tip);
6218 tip_timer = Qnil;
6219 staticpro (&tip_timer);
6220 tip_frame = Qnil;
6221 staticpro (&tip_frame);
6223 last_show_tip_args = Qnil;
6224 staticpro (&last_show_tip_args);
6226 defsubr (&Sx_uses_old_gtk_dialog);
6227 #if defined (USE_MOTIF) || defined (USE_GTK)
6228 defsubr (&Sx_file_dialog);
6229 #endif
6232 #endif /* HAVE_X_WINDOWS */
6234 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
6235 (do not change this comment) */