1 /* Functions for the X window system.
2 Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 99, 2000,01,02,03,04
3 Free Software Foundation.
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)
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., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
31 /* This makes the fields of a Display accessible, in Xlib header files. */
33 #define XLIB_ILLEGAL_ACCESS
40 #include "intervals.h"
41 #include "dispextern.h"
43 #include "blockinput.h"
49 #include "termhooks.h"
55 #include <sys/types.h>
59 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
60 #include "bitmaps/gray.xbm"
62 #include <X11/bitmaps/gray>
65 #include "[.bitmaps]gray.xbm"
73 #include <X11/Shell.h>
76 #include <X11/Xaw/Paned.h>
77 #include <X11/Xaw/Label.h>
78 #endif /* USE_MOTIF */
81 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
90 #include "../lwlib/lwlib.h"
94 #include <Xm/DialogS.h>
95 #include <Xm/FileSB.h>
98 /* Do the EDITRES protocol if running X11R5
99 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
101 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
103 extern void _XEditResCheckMessages ();
104 #endif /* R5 + Athena */
106 /* Unique id counter for widgets created by the Lucid Widget Library. */
108 extern LWLIB_ID widget_id_tick
;
111 /* This is part of a kludge--see lwlib/xlwmenu.c. */
112 extern XFontStruct
*xlwmenu_default_font
;
115 extern void free_frame_menubar ();
116 extern double atof ();
120 /* LessTif/Motif version info. */
122 static Lisp_Object Vmotif_version_string
;
124 #endif /* USE_MOTIF */
126 #endif /* USE_X_TOOLKIT */
130 /* GTK+ version info */
132 static Lisp_Object Vgtk_version_string
;
137 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
139 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
142 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
143 it, and including `bitmaps/gray' more than once is a problem when
144 config.h defines `static' as an empty replacement string. */
146 int gray_bitmap_width
= gray_width
;
147 int gray_bitmap_height
= gray_height
;
148 char *gray_bitmap_bits
= gray_bits
;
150 /* Non-zero means we're allowed to display an hourglass cursor. */
152 int display_hourglass_p
;
154 /* Non-zero means prompt with the old GTK file selection dialog. */
156 int x_use_old_gtk_file_dialog
;
158 /* The background and shape of the mouse pointer, and shape when not
159 over text or in the modeline. */
161 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
162 Lisp_Object Vx_hourglass_pointer_shape
;
164 /* The shape when over mouse-sensitive text. */
166 Lisp_Object Vx_sensitive_text_pointer_shape
;
168 /* If non-nil, the pointer shape to indicate that windows can be
169 dragged horizontally. */
171 Lisp_Object Vx_window_horizontal_drag_shape
;
173 /* Color of chars displayed in cursor box. */
175 Lisp_Object Vx_cursor_fore_pixel
;
177 /* Nonzero if using X. */
181 /* Non nil if no window manager is in use. */
183 Lisp_Object Vx_no_window_manager
;
185 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
187 Lisp_Object Vx_pixel_size_width_font_regexp
;
190 Lisp_Object Qsuppress_icon
;
191 Lisp_Object Qundefined_color
;
192 Lisp_Object Qcompound_text
, Qcancel_timer
;
196 extern Lisp_Object Vwindow_system_version
;
198 /* The below are defined in frame.c. */
201 int image_cache_refcount
, dpyinfo_refcount
;
206 /* Error if we are not connected to X. */
212 error ("X windows are not in use or not initialized");
215 /* Nonzero if we can use mouse menus.
216 You should not call this unless HAVE_MENUS is defined. */
224 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
225 and checking validity for X. */
228 check_x_frame (frame
)
234 frame
= selected_frame
;
235 CHECK_LIVE_FRAME (frame
);
238 error ("Non-X frame used");
242 /* Let the user specify an X display with a frame.
243 nil stands for the selected frame--or, if that is not an X frame,
244 the first X display on the list. */
246 struct x_display_info
*
247 check_x_display_info (frame
)
250 struct x_display_info
*dpyinfo
= NULL
;
254 struct frame
*sf
= XFRAME (selected_frame
);
256 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
257 dpyinfo
= FRAME_X_DISPLAY_INFO (sf
);
258 else if (x_display_list
!= 0)
259 dpyinfo
= x_display_list
;
261 error ("X windows are not in use or not initialized");
263 else if (STRINGP (frame
))
264 dpyinfo
= x_display_info_for_name (frame
);
267 FRAME_PTR f
= check_x_frame (frame
);
268 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
275 /* Return the Emacs frame-object corresponding to an X window.
276 It could be the frame's main window or an icon window. */
278 /* This function can be called during GC, so use GC_xxx type test macros. */
281 x_window_to_frame (dpyinfo
, wdesc
)
282 struct x_display_info
*dpyinfo
;
285 Lisp_Object tail
, frame
;
288 if (wdesc
== None
) return 0;
290 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
293 if (!GC_FRAMEP (frame
))
296 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
298 if (f
->output_data
.x
->hourglass_window
== wdesc
)
301 if ((f
->output_data
.x
->edit_widget
302 && XtWindow (f
->output_data
.x
->edit_widget
) == wdesc
)
303 /* A tooltip frame? */
304 || (!f
->output_data
.x
->edit_widget
305 && FRAME_X_WINDOW (f
) == wdesc
)
306 || f
->output_data
.x
->icon_desc
== wdesc
)
308 #else /* not USE_X_TOOLKIT */
310 if (f
->output_data
.x
->edit_widget
)
312 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
313 struct x_output
*x
= f
->output_data
.x
;
314 if (gwdesc
!= 0 && gwdesc
== x
->edit_widget
)
318 if (FRAME_X_WINDOW (f
) == wdesc
319 || f
->output_data
.x
->icon_desc
== wdesc
)
321 #endif /* not USE_X_TOOLKIT */
326 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
327 /* Like x_window_to_frame but also compares the window with the widget's
331 x_any_window_to_frame (dpyinfo
, wdesc
)
332 struct x_display_info
*dpyinfo
;
335 Lisp_Object tail
, frame
;
336 struct frame
*f
, *found
;
339 if (wdesc
== None
) return NULL
;
342 for (tail
= Vframe_list
; GC_CONSP (tail
) && !found
; tail
= XCDR (tail
))
345 if (!GC_FRAMEP (frame
))
349 if (FRAME_X_P (f
) && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
351 /* This frame matches if the window is any of its widgets. */
352 x
= f
->output_data
.x
;
353 if (x
->hourglass_window
== wdesc
)
358 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
360 && (gwdesc
== x
->widget
361 || gwdesc
== x
->edit_widget
362 || gwdesc
== x
->vbox_widget
363 || gwdesc
== x
->menubar_widget
))
366 if (wdesc
== XtWindow (x
->widget
)
367 || wdesc
== XtWindow (x
->column_widget
)
368 || wdesc
== XtWindow (x
->edit_widget
))
370 /* Match if the window is this frame's menubar. */
371 else if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
375 else if (FRAME_X_WINDOW (f
) == wdesc
)
376 /* A tooltip frame. */
384 /* Likewise, but exclude the menu bar widget. */
387 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
388 struct x_display_info
*dpyinfo
;
391 Lisp_Object tail
, frame
;
395 if (wdesc
== None
) return 0;
397 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
400 if (!GC_FRAMEP (frame
))
403 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
405 x
= f
->output_data
.x
;
406 /* This frame matches if the window is any of its widgets. */
407 if (x
->hourglass_window
== wdesc
)
412 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
414 && (gwdesc
== x
->widget
415 || gwdesc
== x
->edit_widget
416 || gwdesc
== x
->vbox_widget
))
419 if (wdesc
== XtWindow (x
->widget
)
420 || wdesc
== XtWindow (x
->column_widget
)
421 || wdesc
== XtWindow (x
->edit_widget
))
425 else if (FRAME_X_WINDOW (f
) == wdesc
)
426 /* A tooltip frame. */
432 /* Likewise, but consider only the menu bar widget. */
435 x_menubar_window_to_frame (dpyinfo
, wdesc
)
436 struct x_display_info
*dpyinfo
;
439 Lisp_Object tail
, frame
;
443 if (wdesc
== None
) return 0;
445 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
448 if (!GC_FRAMEP (frame
))
451 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
453 x
= f
->output_data
.x
;
454 /* Match if the window is this frame's menubar. */
456 if (x
->menubar_widget
)
458 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
463 && (gwdesc
== x
->menubar_widget
464 || gtk_widget_get_parent (gwdesc
) == x
->menubar_widget
))
470 if (x
->menubar_widget
471 && lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
478 /* Return the frame whose principal (outermost) window is WDESC.
479 If WDESC is some other (smaller) window, we return 0. */
482 x_top_window_to_frame (dpyinfo
, wdesc
)
483 struct x_display_info
*dpyinfo
;
486 Lisp_Object tail
, frame
;
490 if (wdesc
== None
) return 0;
492 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
495 if (!GC_FRAMEP (frame
))
498 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
500 x
= f
->output_data
.x
;
504 /* This frame matches if the window is its topmost widget. */
506 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
507 if (gwdesc
== x
->widget
)
510 if (wdesc
== XtWindow (x
->widget
))
512 #if 0 /* I don't know why it did this,
513 but it seems logically wrong,
514 and it causes trouble for MapNotify events. */
515 /* Match if the window is this frame's menubar. */
516 if (x
->menubar_widget
517 && wdesc
== XtWindow (x
->menubar_widget
))
522 else if (FRAME_X_WINDOW (f
) == wdesc
)
528 #endif /* USE_X_TOOLKIT || USE_GTK */
532 static Lisp_Object unwind_create_frame
P_ ((Lisp_Object
));
533 static Lisp_Object unwind_create_tip_frame
P_ ((Lisp_Object
));
535 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
536 static void x_set_wait_for_wm
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
537 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
538 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
539 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
540 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
541 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
542 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
543 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
544 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
545 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
546 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
547 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
548 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
550 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
552 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
559 /* Store the screen positions of frame F into XPTR and YPTR.
560 These are the positions of the containing window manager window,
561 not Emacs's own window. */
564 x_real_positions (f
, xptr
, yptr
)
568 int win_x
, win_y
, outer_x
, outer_y
;
569 int real_x
= 0, real_y
= 0;
571 Window win
= f
->output_data
.x
->parent_desc
;
577 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
579 if (win
== FRAME_X_DISPLAY_INFO (f
)->root_window
)
580 win
= FRAME_OUTER_WINDOW (f
);
582 /* This loop traverses up the containment tree until we hit the root
583 window. Window managers may intersect many windows between our window
584 and the root window. The window we find just before the root window
585 should be the outer WM window. */
588 Window wm_window
, rootw
;
589 Window
*tmp_children
;
590 unsigned int tmp_nchildren
;
593 success
= XQueryTree (FRAME_X_DISPLAY (f
), win
, &rootw
,
594 &wm_window
, &tmp_children
, &tmp_nchildren
);
596 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
598 /* Don't free tmp_children if XQueryTree failed. */
602 XFree ((char *) tmp_children
);
604 if (wm_window
== rootw
|| had_errors
)
615 /* Get the real coordinates for the WM window upper left corner */
616 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
617 &rootw
, &real_x
, &real_y
, &ign
, &ign
, &ign
, &ign
);
619 /* Translate real coordinates to coordinates relative to our
620 window. For our window, the upper left corner is 0, 0.
621 Since the upper left corner of the WM window is outside
622 our window, win_x and win_y will be negative:
624 ------------------ ---> x
626 | ----------------- v y
629 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
631 /* From-window, to-window. */
632 FRAME_X_DISPLAY_INFO (f
)->root_window
,
635 /* From-position, to-position. */
636 real_x
, real_y
, &win_x
, &win_y
,
641 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
648 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
650 /* From-window, to-window. */
651 FRAME_X_DISPLAY_INFO (f
)->root_window
,
652 FRAME_OUTER_WINDOW (f
),
654 /* From-position, to-position. */
655 real_x
, real_y
, &outer_x
, &outer_y
,
661 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
664 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
668 if (had_errors
) return;
670 f
->x_pixels_diff
= -win_x
;
671 f
->y_pixels_diff
= -win_y
;
673 FRAME_X_OUTPUT (f
)->x_pixels_outer_diff
= -outer_x
;
674 FRAME_X_OUTPUT (f
)->y_pixels_outer_diff
= -outer_y
;
683 /* Gamma-correct COLOR on frame F. */
686 gamma_correct (f
, color
)
692 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
693 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
694 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
699 /* Decide if color named COLOR_NAME is valid for use on frame F. If
700 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
701 allocate the color. Value is zero if COLOR_NAME is invalid, or
702 no color could be allocated. */
705 x_defined_color (f
, color_name
, color
, alloc_p
)
712 Display
*dpy
= FRAME_X_DISPLAY (f
);
713 Colormap cmap
= FRAME_X_COLORMAP (f
);
716 success_p
= XParseColor (dpy
, cmap
, color_name
, color
);
717 if (success_p
&& alloc_p
)
718 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
725 /* Return the pixel color value for color COLOR_NAME on frame F. If F
726 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
727 Signal an error if color can't be allocated. */
730 x_decode_color (f
, color_name
, mono_color
)
732 Lisp_Object color_name
;
737 CHECK_STRING (color_name
);
739 #if 0 /* Don't do this. It's wrong when we're not using the default
740 colormap, it makes freeing difficult, and it's probably not
741 an important optimization. */
742 if (strcmp (SDATA (color_name
), "black") == 0)
743 return BLACK_PIX_DEFAULT (f
);
744 else if (strcmp (SDATA (color_name
), "white") == 0)
745 return WHITE_PIX_DEFAULT (f
);
748 /* Return MONO_COLOR for monochrome frames. */
749 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
752 /* x_defined_color is responsible for coping with failures
753 by looking for a near-miss. */
754 if (x_defined_color (f
, SDATA (color_name
), &cdef
, 1))
757 Fsignal (Qerror
, Fcons (build_string ("Undefined color"),
758 Fcons (color_name
, Qnil
)));
764 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
765 the previous value of that parameter, NEW_VALUE is the new value.
766 See also the comment of wait_for_wm in struct x_output. */
769 x_set_wait_for_wm (f
, new_value
, old_value
)
771 Lisp_Object new_value
, old_value
;
773 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
778 /* Set icon from FILE for frame F. By using GTK functions the icon
779 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
782 xg_set_icon (f
, file
)
792 found
= x_find_image_file (file
);
800 filename
= SDATA (found
);
803 pixbuf
= gdk_pixbuf_new_from_file (filename
, &err
);
807 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
809 g_object_unref (pixbuf
);
825 /* Functions called only from `x_set_frame_param'
826 to set individual parameters.
828 If FRAME_X_WINDOW (f) is 0,
829 the frame is being created and its X-window does not exist yet.
830 In that case, just record the parameter's new value
831 in the standard place; do not attempt to change the window. */
834 x_set_foreground_color (f
, arg
, oldval
)
836 Lisp_Object arg
, oldval
;
838 struct x_output
*x
= f
->output_data
.x
;
839 unsigned long fg
, old_fg
;
841 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
842 old_fg
= x
->foreground_pixel
;
843 x
->foreground_pixel
= fg
;
845 if (FRAME_X_WINDOW (f
) != 0)
847 Display
*dpy
= FRAME_X_DISPLAY (f
);
850 XSetForeground (dpy
, x
->normal_gc
, fg
);
851 XSetBackground (dpy
, x
->reverse_gc
, fg
);
853 if (x
->cursor_pixel
== old_fg
)
855 unload_color (f
, x
->cursor_pixel
);
856 x
->cursor_pixel
= x_copy_color (f
, fg
);
857 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
862 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
864 if (FRAME_VISIBLE_P (f
))
868 unload_color (f
, old_fg
);
872 x_set_background_color (f
, arg
, oldval
)
874 Lisp_Object arg
, oldval
;
876 struct x_output
*x
= f
->output_data
.x
;
879 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
880 unload_color (f
, x
->background_pixel
);
881 x
->background_pixel
= bg
;
883 if (FRAME_X_WINDOW (f
) != 0)
885 Display
*dpy
= FRAME_X_DISPLAY (f
);
888 XSetBackground (dpy
, x
->normal_gc
, bg
);
889 XSetForeground (dpy
, x
->reverse_gc
, bg
);
890 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
891 XSetForeground (dpy
, x
->cursor_gc
, bg
);
894 xg_set_background_color (f
, bg
);
897 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
898 toolkit scroll bars. */
901 for (bar
= FRAME_SCROLL_BARS (f
);
903 bar
= XSCROLL_BAR (bar
)->next
)
905 Window window
= SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
));
906 XSetWindowBackground (dpy
, window
, bg
);
909 #endif /* USE_TOOLKIT_SCROLL_BARS */
912 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
914 if (FRAME_VISIBLE_P (f
))
920 x_set_mouse_color (f
, arg
, oldval
)
922 Lisp_Object arg
, oldval
;
924 struct x_output
*x
= f
->output_data
.x
;
925 Display
*dpy
= FRAME_X_DISPLAY (f
);
926 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
927 Cursor hourglass_cursor
, horizontal_drag_cursor
;
929 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
930 unsigned long mask_color
= x
->background_pixel
;
932 /* Don't let pointers be invisible. */
933 if (mask_color
== pixel
)
935 x_free_colors (f
, &pixel
, 1);
936 pixel
= x_copy_color (f
, x
->foreground_pixel
);
939 unload_color (f
, x
->mouse_pixel
);
940 x
->mouse_pixel
= pixel
;
944 /* It's not okay to crash if the user selects a screwy cursor. */
945 count
= x_catch_errors (dpy
);
947 if (!NILP (Vx_pointer_shape
))
949 CHECK_NUMBER (Vx_pointer_shape
);
950 cursor
= XCreateFontCursor (dpy
, XINT (Vx_pointer_shape
));
953 cursor
= XCreateFontCursor (dpy
, XC_xterm
);
954 x_check_errors (dpy
, "bad text pointer cursor: %s");
956 if (!NILP (Vx_nontext_pointer_shape
))
958 CHECK_NUMBER (Vx_nontext_pointer_shape
);
960 = XCreateFontCursor (dpy
, XINT (Vx_nontext_pointer_shape
));
963 nontext_cursor
= XCreateFontCursor (dpy
, XC_left_ptr
);
964 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
966 if (!NILP (Vx_hourglass_pointer_shape
))
968 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
970 = XCreateFontCursor (dpy
, XINT (Vx_hourglass_pointer_shape
));
973 hourglass_cursor
= XCreateFontCursor (dpy
, XC_watch
);
974 x_check_errors (dpy
, "bad hourglass pointer cursor: %s");
976 if (!NILP (Vx_mode_pointer_shape
))
978 CHECK_NUMBER (Vx_mode_pointer_shape
);
979 mode_cursor
= XCreateFontCursor (dpy
, XINT (Vx_mode_pointer_shape
));
982 mode_cursor
= XCreateFontCursor (dpy
, XC_xterm
);
983 x_check_errors (dpy
, "bad modeline pointer cursor: %s");
985 if (!NILP (Vx_sensitive_text_pointer_shape
))
987 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
989 = XCreateFontCursor (dpy
, XINT (Vx_sensitive_text_pointer_shape
));
992 hand_cursor
= XCreateFontCursor (dpy
, XC_hand2
);
994 if (!NILP (Vx_window_horizontal_drag_shape
))
996 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
997 horizontal_drag_cursor
998 = XCreateFontCursor (dpy
, XINT (Vx_window_horizontal_drag_shape
));
1001 horizontal_drag_cursor
1002 = XCreateFontCursor (dpy
, XC_sb_h_double_arrow
);
1004 /* Check and report errors with the above calls. */
1005 x_check_errors (dpy
, "can't set cursor shape: %s");
1006 x_uncatch_errors (dpy
, count
);
1009 XColor fore_color
, back_color
;
1011 fore_color
.pixel
= x
->mouse_pixel
;
1012 x_query_color (f
, &fore_color
);
1013 back_color
.pixel
= mask_color
;
1014 x_query_color (f
, &back_color
);
1016 XRecolorCursor (dpy
, cursor
, &fore_color
, &back_color
);
1017 XRecolorCursor (dpy
, nontext_cursor
, &fore_color
, &back_color
);
1018 XRecolorCursor (dpy
, mode_cursor
, &fore_color
, &back_color
);
1019 XRecolorCursor (dpy
, hand_cursor
, &fore_color
, &back_color
);
1020 XRecolorCursor (dpy
, hourglass_cursor
, &fore_color
, &back_color
);
1021 XRecolorCursor (dpy
, horizontal_drag_cursor
, &fore_color
, &back_color
);
1024 if (FRAME_X_WINDOW (f
) != 0)
1025 XDefineCursor (dpy
, FRAME_X_WINDOW (f
), cursor
);
1027 if (cursor
!= x
->text_cursor
1028 && x
->text_cursor
!= 0)
1029 XFreeCursor (dpy
, x
->text_cursor
);
1030 x
->text_cursor
= cursor
;
1032 if (nontext_cursor
!= x
->nontext_cursor
1033 && x
->nontext_cursor
!= 0)
1034 XFreeCursor (dpy
, x
->nontext_cursor
);
1035 x
->nontext_cursor
= nontext_cursor
;
1037 if (hourglass_cursor
!= x
->hourglass_cursor
1038 && x
->hourglass_cursor
!= 0)
1039 XFreeCursor (dpy
, x
->hourglass_cursor
);
1040 x
->hourglass_cursor
= hourglass_cursor
;
1042 if (mode_cursor
!= x
->modeline_cursor
1043 && x
->modeline_cursor
!= 0)
1044 XFreeCursor (dpy
, f
->output_data
.x
->modeline_cursor
);
1045 x
->modeline_cursor
= mode_cursor
;
1047 if (hand_cursor
!= x
->hand_cursor
1048 && x
->hand_cursor
!= 0)
1049 XFreeCursor (dpy
, x
->hand_cursor
);
1050 x
->hand_cursor
= hand_cursor
;
1052 if (horizontal_drag_cursor
!= x
->horizontal_drag_cursor
1053 && x
->horizontal_drag_cursor
!= 0)
1054 XFreeCursor (dpy
, x
->horizontal_drag_cursor
);
1055 x
->horizontal_drag_cursor
= horizontal_drag_cursor
;
1060 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1064 x_set_cursor_color (f
, arg
, oldval
)
1066 Lisp_Object arg
, oldval
;
1068 unsigned long fore_pixel
, pixel
;
1069 int fore_pixel_allocated_p
= 0, pixel_allocated_p
= 0;
1070 struct x_output
*x
= f
->output_data
.x
;
1072 if (!NILP (Vx_cursor_fore_pixel
))
1074 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1075 WHITE_PIX_DEFAULT (f
));
1076 fore_pixel_allocated_p
= 1;
1079 fore_pixel
= x
->background_pixel
;
1081 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1082 pixel_allocated_p
= 1;
1084 /* Make sure that the cursor color differs from the background color. */
1085 if (pixel
== x
->background_pixel
)
1087 if (pixel_allocated_p
)
1089 x_free_colors (f
, &pixel
, 1);
1090 pixel_allocated_p
= 0;
1093 pixel
= x
->mouse_pixel
;
1094 if (pixel
== fore_pixel
)
1096 if (fore_pixel_allocated_p
)
1098 x_free_colors (f
, &fore_pixel
, 1);
1099 fore_pixel_allocated_p
= 0;
1101 fore_pixel
= x
->background_pixel
;
1105 unload_color (f
, x
->cursor_foreground_pixel
);
1106 if (!fore_pixel_allocated_p
)
1107 fore_pixel
= x_copy_color (f
, fore_pixel
);
1108 x
->cursor_foreground_pixel
= fore_pixel
;
1110 unload_color (f
, x
->cursor_pixel
);
1111 if (!pixel_allocated_p
)
1112 pixel
= x_copy_color (f
, pixel
);
1113 x
->cursor_pixel
= pixel
;
1115 if (FRAME_X_WINDOW (f
) != 0)
1118 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
1119 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
1122 if (FRAME_VISIBLE_P (f
))
1124 x_update_cursor (f
, 0);
1125 x_update_cursor (f
, 1);
1129 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1132 /* Set the border-color of frame F to pixel value PIX.
1133 Note that this does not fully take effect if done before
1134 F has an x-window. */
1137 x_set_border_pixel (f
, pix
)
1141 unload_color (f
, f
->output_data
.x
->border_pixel
);
1142 f
->output_data
.x
->border_pixel
= pix
;
1144 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
1147 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1148 (unsigned long)pix
);
1151 if (FRAME_VISIBLE_P (f
))
1156 /* Set the border-color of frame F to value described by ARG.
1157 ARG can be a string naming a color.
1158 The border-color is used for the border that is drawn by the X server.
1159 Note that this does not fully take effect if done before
1160 F has an x-window; it must be redone when the window is created.
1162 Note: this is done in two routines because of the way X10 works.
1164 Note: under X11, this is normally the province of the window manager,
1165 and so emacs' border colors may be overridden. */
1168 x_set_border_color (f
, arg
, oldval
)
1170 Lisp_Object arg
, oldval
;
1175 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1176 x_set_border_pixel (f
, pix
);
1177 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1182 x_set_cursor_type (f
, arg
, oldval
)
1184 Lisp_Object arg
, oldval
;
1186 set_frame_cursor_types (f
, arg
);
1188 /* Make sure the cursor gets redrawn. */
1189 cursor_type_changed
= 1;
1193 x_set_icon_type (f
, arg
, oldval
)
1195 Lisp_Object arg
, oldval
;
1201 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1204 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1209 result
= x_text_icon (f
,
1210 (char *) SDATA ((!NILP (f
->icon_name
)
1214 result
= x_bitmap_icon (f
, arg
);
1219 error ("No icon window available");
1222 XFlush (FRAME_X_DISPLAY (f
));
1227 x_set_icon_name (f
, arg
, oldval
)
1229 Lisp_Object arg
, oldval
;
1235 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1238 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1243 if (f
->output_data
.x
->icon_bitmap
!= 0)
1248 result
= x_text_icon (f
,
1249 (char *) SDATA ((!NILP (f
->icon_name
)
1258 error ("No icon window available");
1261 XFlush (FRAME_X_DISPLAY (f
));
1267 x_set_menu_bar_lines (f
, value
, oldval
)
1269 Lisp_Object value
, oldval
;
1272 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1273 int olines
= FRAME_MENU_BAR_LINES (f
);
1276 /* Right now, menu bars don't work properly in minibuf-only frames;
1277 most of the commands try to apply themselves to the minibuffer
1278 frame itself, and get an error because you can't switch buffers
1279 in or split the minibuffer window. */
1280 if (FRAME_MINIBUF_ONLY_P (f
))
1283 if (INTEGERP (value
))
1284 nlines
= XINT (value
);
1288 /* Make sure we redisplay all windows in this frame. */
1289 windows_or_buffers_changed
++;
1291 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1292 FRAME_MENU_BAR_LINES (f
) = 0;
1295 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1296 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1297 /* Make sure next redisplay shows the menu bar. */
1298 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1302 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1303 free_frame_menubar (f
);
1304 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1306 f
->output_data
.x
->menubar_widget
= 0;
1308 #else /* not USE_X_TOOLKIT && not USE_GTK */
1309 FRAME_MENU_BAR_LINES (f
) = nlines
;
1310 change_window_heights (f
->root_window
, nlines
- olines
);
1311 #endif /* not USE_X_TOOLKIT */
1316 /* Set the number of lines used for the tool bar of frame F to VALUE.
1317 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1318 is the old number of tool bar lines. This function changes the
1319 height of all windows on frame F to match the new tool bar height.
1320 The frame's height doesn't change. */
1323 x_set_tool_bar_lines (f
, value
, oldval
)
1325 Lisp_Object value
, oldval
;
1327 int delta
, nlines
, root_height
;
1328 Lisp_Object root_window
;
1330 /* Treat tool bars like menu bars. */
1331 if (FRAME_MINIBUF_ONLY_P (f
))
1334 /* Use VALUE only if an integer >= 0. */
1335 if (INTEGERP (value
) && XINT (value
) >= 0)
1336 nlines
= XFASTINT (value
);
1341 FRAME_TOOL_BAR_LINES (f
) = 0;
1344 FRAME_EXTERNAL_TOOL_BAR (f
) = 1;
1345 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1346 /* Make sure next redisplay shows the tool bar. */
1347 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1348 update_frame_tool_bar (f
);
1352 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1353 free_frame_tool_bar (f
);
1354 FRAME_EXTERNAL_TOOL_BAR (f
) = 0;
1360 /* Make sure we redisplay all windows in this frame. */
1361 ++windows_or_buffers_changed
;
1363 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
1365 /* Don't resize the tool-bar to more than we have room for. */
1366 root_window
= FRAME_ROOT_WINDOW (f
);
1367 root_height
= WINDOW_TOTAL_LINES (XWINDOW (root_window
));
1368 if (root_height
- delta
< 1)
1370 delta
= root_height
- 1;
1371 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
1374 FRAME_TOOL_BAR_LINES (f
) = nlines
;
1375 change_window_heights (root_window
, delta
);
1378 /* We also have to make sure that the internal border at the top of
1379 the frame, below the menu bar or tool bar, is redrawn when the
1380 tool bar disappears. This is so because the internal border is
1381 below the tool bar if one is displayed, but is below the menu bar
1382 if there isn't a tool bar. The tool bar draws into the area
1383 below the menu bar. */
1384 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
1388 clear_current_matrices (f
);
1389 updating_frame
= NULL
;
1392 /* If the tool bar gets smaller, the internal border below it
1393 has to be cleared. It was formerly part of the display
1394 of the larger tool bar, and updating windows won't clear it. */
1397 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1398 int width
= FRAME_PIXEL_WIDTH (f
);
1399 int y
= nlines
* FRAME_LINE_HEIGHT (f
);
1402 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1403 0, y
, width
, height
, False
);
1406 if (WINDOWP (f
->tool_bar_window
))
1407 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1412 /* Set the foreground color for scroll bars on frame F to VALUE.
1413 VALUE should be a string, a color name. If it isn't a string or
1414 isn't a valid color name, do nothing. OLDVAL is the old value of
1415 the frame parameter. */
1418 x_set_scroll_bar_foreground (f
, value
, oldval
)
1420 Lisp_Object value
, oldval
;
1422 unsigned long pixel
;
1424 if (STRINGP (value
))
1425 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1429 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1430 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1432 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1433 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1435 /* Remove all scroll bars because they have wrong colors. */
1436 if (condemn_scroll_bars_hook
)
1437 (*condemn_scroll_bars_hook
) (f
);
1438 if (judge_scroll_bars_hook
)
1439 (*judge_scroll_bars_hook
) (f
);
1441 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1447 /* Set the background color for scroll bars on frame F to VALUE VALUE
1448 should be a string, a color name. If it isn't a string or isn't a
1449 valid color name, do nothing. OLDVAL is the old value of the frame
1453 x_set_scroll_bar_background (f
, value
, oldval
)
1455 Lisp_Object value
, oldval
;
1457 unsigned long pixel
;
1459 if (STRINGP (value
))
1460 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1464 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1465 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1467 #ifdef USE_TOOLKIT_SCROLL_BARS
1468 /* Scrollbar shadow colors. */
1469 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1471 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1472 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1474 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1476 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1477 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1479 #endif /* USE_TOOLKIT_SCROLL_BARS */
1481 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1482 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1484 /* Remove all scroll bars because they have wrong colors. */
1485 if (condemn_scroll_bars_hook
)
1486 (*condemn_scroll_bars_hook
) (f
);
1487 if (judge_scroll_bars_hook
)
1488 (*judge_scroll_bars_hook
) (f
);
1490 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1496 /* Encode Lisp string STRING as a text in a format appropriate for
1497 XICCC (X Inter Client Communication Conventions).
1499 If STRING contains only ASCII characters, do no conversion and
1500 return the string data of STRING. Otherwise, encode the text by
1501 CODING_SYSTEM, and return a newly allocated memory area which
1502 should be freed by `xfree' by a caller.
1504 SELECTIONP non-zero means the string is being encoded for an X
1505 selection, so it is safe to run pre-write conversions (which
1508 Store the byte length of resulting text in *TEXT_BYTES.
1510 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1511 which means that the `encoding' of the result can be `STRING'.
1512 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1513 the result should be `COMPOUND_TEXT'. */
1516 x_encode_text (string
, coding_system
, selectionp
, text_bytes
, stringp
)
1517 Lisp_Object string
, coding_system
;
1518 int *text_bytes
, *stringp
;
1521 unsigned char *str
= SDATA (string
);
1522 int chars
= SCHARS (string
);
1523 int bytes
= SBYTES (string
);
1527 struct coding_system coding
;
1528 extern Lisp_Object Qcompound_text_with_extensions
;
1530 charset_info
= find_charset_in_text (str
, chars
, bytes
, NULL
, Qnil
);
1531 if (charset_info
== 0)
1533 /* No multibyte character in OBJ. We need not encode it. */
1534 *text_bytes
= bytes
;
1539 setup_coding_system (coding_system
, &coding
);
1541 && SYMBOLP (coding
.pre_write_conversion
)
1542 && !NILP (Ffboundp (coding
.pre_write_conversion
)))
1544 string
= run_pre_post_conversion_on_str (string
, &coding
, 1);
1545 str
= SDATA (string
);
1546 chars
= SCHARS (string
);
1547 bytes
= SBYTES (string
);
1549 coding
.src_multibyte
= 1;
1550 coding
.dst_multibyte
= 0;
1551 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1552 if (coding
.type
== coding_type_iso2022
)
1553 coding
.flags
|= CODING_FLAG_ISO_SAFE
;
1554 /* We suppress producing escape sequences for composition. */
1555 coding
.composing
= COMPOSITION_DISABLED
;
1556 bufsize
= encoding_buffer_size (&coding
, bytes
);
1557 buf
= (unsigned char *) xmalloc (bufsize
);
1558 encode_coding (&coding
, str
, buf
, bytes
, bufsize
);
1559 *text_bytes
= coding
.produced
;
1560 *stringp
= (charset_info
== 1
1561 || (!EQ (coding_system
, Qcompound_text
)
1562 && !EQ (coding_system
, Qcompound_text_with_extensions
)));
1567 /* Set the WM name to NAME for frame F. Also set the icon name.
1568 If the frame already has an icon name, use that, otherwise set the
1569 icon name to NAME. */
1572 x_set_name_internal (f
, name
)
1576 if (FRAME_X_WINDOW (f
))
1581 XTextProperty text
, icon
;
1583 int do_free_icon_value
= 0, do_free_text_value
= 0;
1584 Lisp_Object coding_system
;
1586 coding_system
= Qcompound_text
;
1587 /* Note: Encoding strategy
1589 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1590 text.encoding. But, there are non-internationalized window
1591 managers which don't support that encoding. So, if NAME
1592 contains only ASCII and 8859-1 characters, encode it by
1593 iso-latin-1, and use "STRING" in text.encoding hoping that
1594 such window managers at least analyze this format correctly,
1595 i.e. treat 8-bit bytes as 8859-1 characters.
1597 We may also be able to use "UTF8_STRING" in text.encoding
1598 in the future which can encode all Unicode characters.
1599 But, for the moment, there's no way to know that the
1600 current window manager supports it or not. */
1601 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
1602 text
.encoding
= (stringp
? XA_STRING
1603 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1605 text
.nitems
= bytes
;
1607 /* Check early, because ENCODE_UTF_8 below may GC and name may be
1609 do_free_text_value
= text
.value
!= SDATA (name
);
1611 if (NILP (f
->icon_name
))
1617 /* See the above comment "Note: Encoding strategy". */
1618 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
1620 icon
.encoding
= (stringp
? XA_STRING
1621 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1623 icon
.nitems
= bytes
;
1624 do_free_icon_value
= icon
.value
!= SDATA (f
->icon_name
);
1628 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1629 SDATA (ENCODE_UTF_8 (name
)));
1630 #else /* not USE_GTK */
1631 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1632 #endif /* not USE_GTK */
1634 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1636 if (do_free_icon_value
)
1638 if (do_free_text_value
)
1641 #else /* not HAVE_X11R4 */
1642 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1644 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1646 #endif /* not HAVE_X11R4 */
1651 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1654 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1655 name; if NAME is a string, set F's name to NAME and set
1656 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1658 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1659 suggesting a new name, which lisp code should override; if
1660 F->explicit_name is set, ignore the new name; otherwise, set it. */
1663 x_set_name (f
, name
, explicit)
1668 /* Make sure that requests from lisp code override requests from
1669 Emacs redisplay code. */
1672 /* If we're switching from explicit to implicit, we had better
1673 update the mode lines and thereby update the title. */
1674 if (f
->explicit_name
&& NILP (name
))
1675 update_mode_lines
= 1;
1677 f
->explicit_name
= ! NILP (name
);
1679 else if (f
->explicit_name
)
1682 /* If NAME is nil, set the name to the x_id_name. */
1685 /* Check for no change needed in this very common case
1686 before we do any consing. */
1687 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1690 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1693 CHECK_STRING (name
);
1695 /* Don't change the name if it's already NAME. */
1696 if (! NILP (Fstring_equal (name
, f
->name
)))
1701 /* For setting the frame title, the title parameter should override
1702 the name parameter. */
1703 if (! NILP (f
->title
))
1706 x_set_name_internal (f
, name
);
1709 /* This function should be called when the user's lisp code has
1710 specified a name for the frame; the name will override any set by the
1713 x_explicitly_set_name (f
, arg
, oldval
)
1715 Lisp_Object arg
, oldval
;
1717 x_set_name (f
, arg
, 1);
1720 /* This function should be called by Emacs redisplay code to set the
1721 name; names set this way will never override names set by the user's
1724 x_implicitly_set_name (f
, arg
, oldval
)
1726 Lisp_Object arg
, oldval
;
1728 x_set_name (f
, arg
, 0);
1731 /* Change the title of frame F to NAME.
1732 If NAME is nil, use the frame name as the title.
1734 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1735 name; if NAME is a string, set F's name to NAME and set
1736 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1738 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1739 suggesting a new name, which lisp code should override; if
1740 F->explicit_name is set, ignore the new name; otherwise, set it. */
1743 x_set_title (f
, name
, old_name
)
1745 Lisp_Object name
, old_name
;
1747 /* Don't change the title if it's already NAME. */
1748 if (EQ (name
, f
->title
))
1751 update_mode_lines
= 1;
1758 CHECK_STRING (name
);
1760 x_set_name_internal (f
, name
);
1764 x_set_scroll_bar_default_width (f
)
1767 int wid
= FRAME_COLUMN_WIDTH (f
);
1769 #ifdef USE_TOOLKIT_SCROLL_BARS
1770 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1771 int width
= 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
1772 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (width
+ wid
- 1) / wid
;
1773 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = width
;
1775 /* Make the actual width at least 14 pixels and a multiple of a
1777 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
1779 /* Use all of that space (aside from required margins) for the
1781 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = 0;
1786 /* Record in frame F the specified or default value according to ALIST
1787 of the parameter named PROP (a Lisp symbol). If no value is
1788 specified for PROP, look for an X default for XPROP on the frame
1789 named NAME. If that is not found either, use the value DEFLT. */
1792 x_default_scroll_bar_color_parameter (f
, alist
, prop
, xprop
, xclass
,
1801 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
1804 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
1805 if (EQ (tem
, Qunbound
))
1807 #ifdef USE_TOOLKIT_SCROLL_BARS
1809 /* See if an X resource for the scroll bar color has been
1811 tem
= display_x_get_resource (dpyinfo
,
1812 build_string (foreground_p
1816 build_string ("verticalScrollBar"),
1820 /* If nothing has been specified, scroll bars will use a
1821 toolkit-dependent default. Because these defaults are
1822 difficult to get at without actually creating a scroll
1823 bar, use nil to indicate that no color has been
1828 #else /* not USE_TOOLKIT_SCROLL_BARS */
1832 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1835 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
1841 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
1844 XSetWMProtocols (dpy
, w
, protocols
, count
)
1851 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
1852 if (prop
== None
) return False
;
1853 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
1854 (unsigned char *) protocols
, count
);
1857 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
1859 #ifdef USE_X_TOOLKIT
1861 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1862 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1863 already be present because of the toolkit (Motif adds some of them,
1864 for example, but Xt doesn't). */
1867 hack_wm_protocols (f
, widget
)
1871 Display
*dpy
= XtDisplay (widget
);
1872 Window w
= XtWindow (widget
);
1873 int need_delete
= 1;
1879 Atom type
, *atoms
= 0;
1881 unsigned long nitems
= 0;
1882 unsigned long bytes_after
;
1884 if ((XGetWindowProperty (dpy
, w
,
1885 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1886 (long)0, (long)100, False
, XA_ATOM
,
1887 &type
, &format
, &nitems
, &bytes_after
,
1888 (unsigned char **) &atoms
)
1890 && format
== 32 && type
== XA_ATOM
)
1894 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
1896 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
1898 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
1901 if (atoms
) XFree ((char *) atoms
);
1907 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
1909 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
1911 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
1913 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1914 XA_ATOM
, 32, PropModeAppend
,
1915 (unsigned char *) props
, count
);
1923 /* Support routines for XIC (X Input Context). */
1927 static XFontSet xic_create_xfontset
P_ ((struct frame
*, char *));
1928 static XIMStyle best_xim_style
P_ ((XIMStyles
*, XIMStyles
*));
1931 /* Supported XIM styles, ordered by preference. */
1933 static XIMStyle supported_xim_styles
[] =
1935 XIMPreeditPosition
| XIMStatusArea
,
1936 XIMPreeditPosition
| XIMStatusNothing
,
1937 XIMPreeditPosition
| XIMStatusNone
,
1938 XIMPreeditNothing
| XIMStatusArea
,
1939 XIMPreeditNothing
| XIMStatusNothing
,
1940 XIMPreeditNothing
| XIMStatusNone
,
1941 XIMPreeditNone
| XIMStatusArea
,
1942 XIMPreeditNone
| XIMStatusNothing
,
1943 XIMPreeditNone
| XIMStatusNone
,
1948 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1951 xic_create_xfontset (f
, base_fontname
)
1953 char *base_fontname
;
1955 XFontSet xfs
= NULL
;
1956 char **missing_list
= NULL
;
1959 Lisp_Object rest
, frame
;
1961 /* See if there is another frame already using same fontset. */
1962 FOR_EACH_FRAME (rest
, frame
)
1964 struct frame
*cf
= XFRAME (frame
);
1965 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
1966 && FRAME_X_DISPLAY_INFO (cf
) == FRAME_X_DISPLAY_INFO (f
)
1967 && FRAME_XIC_BASE_FONTNAME (cf
)
1968 && !strcmp (FRAME_XIC_BASE_FONTNAME (cf
), base_fontname
))
1970 xfs
= FRAME_XIC_FONTSET (cf
);
1978 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
),
1979 base_fontname
, &missing_list
,
1980 &missing_count
, &def_string
);
1982 XFreeStringList (missing_list
);
1985 if (FRAME_XIC_BASE_FONTNAME (f
))
1986 xfree (FRAME_XIC_BASE_FONTNAME (f
));
1987 FRAME_XIC_BASE_FONTNAME (f
) = xstrdup (base_fontname
);
1989 /* No need to free def_string. */
1993 /* Free the X fontset of frame F if it is the last frame using it. */
1996 xic_free_xfontset (f
)
1999 Lisp_Object rest
, frame
;
2002 if (!FRAME_XIC_FONTSET (f
))
2005 /* See if there is another frame sharing the same fontset. */
2006 FOR_EACH_FRAME (rest
, frame
)
2008 struct frame
*cf
= XFRAME (frame
);
2009 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2010 && FRAME_X_DISPLAY_INFO (cf
) == FRAME_X_DISPLAY_INFO (f
)
2011 && FRAME_XIC_FONTSET (cf
) == FRAME_XIC_FONTSET (f
))
2019 /* The fontset is not used anymore. It is safe to free it. */
2020 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2022 if (FRAME_XIC_BASE_FONTNAME (f
))
2023 xfree (FRAME_XIC_BASE_FONTNAME (f
));
2024 FRAME_XIC_BASE_FONTNAME (f
) = NULL
;
2025 FRAME_XIC_FONTSET (f
) = NULL
;
2029 /* Value is the best input style, given user preferences USER (already
2030 checked to be supported by Emacs), and styles supported by the
2031 input method XIM. */
2034 best_xim_style (user
, xim
)
2040 for (i
= 0; i
< user
->count_styles
; ++i
)
2041 for (j
= 0; j
< xim
->count_styles
; ++j
)
2042 if (user
->supported_styles
[i
] == xim
->supported_styles
[j
])
2043 return user
->supported_styles
[i
];
2045 /* Return the default style. */
2046 return XIMPreeditNothing
| XIMStatusNothing
;
2049 /* Create XIC for frame F. */
2051 static XIMStyle xic_style
;
2054 create_frame_xic (f
)
2059 XFontSet xfs
= NULL
;
2064 xim
= FRAME_X_XIM (f
);
2069 XVaNestedList preedit_attr
;
2070 XVaNestedList status_attr
;
2071 char *base_fontname
;
2074 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2075 spot
.x
= 0; spot
.y
= 1;
2076 /* Create X fontset. */
2077 fontset
= FRAME_FONTSET (f
);
2079 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2082 /* Determine the base fontname from the ASCII font name of
2084 char *ascii_font
= (char *) SDATA (fontset_ascii (fontset
));
2085 char *p
= ascii_font
;
2088 for (i
= 0; *p
; p
++)
2091 /* As the font name doesn't conform to XLFD, we can't
2092 modify it to get a suitable base fontname for the
2094 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2097 int len
= strlen (ascii_font
) + 1;
2100 for (i
= 0, p
= ascii_font
; i
< 8; p
++)
2109 base_fontname
= (char *) alloca (len
);
2110 bzero (base_fontname
, len
);
2111 strcpy (base_fontname
, "-*-*-");
2112 bcopy (p1
, base_fontname
+ 5, p
- p1
);
2113 strcat (base_fontname
, "*-*-*-*-*-*-*");
2116 xfs
= xic_create_xfontset (f
, base_fontname
);
2118 /* Determine XIC style. */
2121 XIMStyles supported_list
;
2122 supported_list
.count_styles
= (sizeof supported_xim_styles
2123 / sizeof supported_xim_styles
[0]);
2124 supported_list
.supported_styles
= supported_xim_styles
;
2125 xic_style
= best_xim_style (&supported_list
,
2126 FRAME_X_XIM_STYLES (f
));
2129 preedit_attr
= XVaCreateNestedList (0,
2132 FRAME_FOREGROUND_PIXEL (f
),
2134 FRAME_BACKGROUND_PIXEL (f
),
2135 (xic_style
& XIMPreeditPosition
2140 status_attr
= XVaCreateNestedList (0,
2146 FRAME_FOREGROUND_PIXEL (f
),
2148 FRAME_BACKGROUND_PIXEL (f
),
2151 xic
= XCreateIC (xim
,
2152 XNInputStyle
, xic_style
,
2153 XNClientWindow
, FRAME_X_WINDOW (f
),
2154 XNFocusWindow
, FRAME_X_WINDOW (f
),
2155 XNStatusAttributes
, status_attr
,
2156 XNPreeditAttributes
, preedit_attr
,
2158 XFree (preedit_attr
);
2159 XFree (status_attr
);
2162 FRAME_XIC (f
) = xic
;
2163 FRAME_XIC_STYLE (f
) = xic_style
;
2164 FRAME_XIC_FONTSET (f
) = xfs
;
2168 /* Destroy XIC and free XIC fontset of frame F, if any. */
2174 if (FRAME_XIC (f
) == NULL
)
2177 XDestroyIC (FRAME_XIC (f
));
2178 xic_free_xfontset (f
);
2180 FRAME_XIC (f
) = NULL
;
2184 /* Place preedit area for XIC of window W's frame to specified
2185 pixel position X/Y. X and Y are relative to window W. */
2188 xic_set_preeditarea (w
, x
, y
)
2192 struct frame
*f
= XFRAME (w
->frame
);
2196 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2197 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2198 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2199 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2204 /* Place status area for XIC in bottom right corner of frame F.. */
2207 xic_set_statusarea (f
)
2210 XIC xic
= FRAME_XIC (f
);
2215 /* Negotiate geometry of status area. If input method has existing
2216 status area, use its current size. */
2217 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2218 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2219 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2222 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2223 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2226 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2228 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2229 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2233 area
.width
= needed
->width
;
2234 area
.height
= needed
->height
;
2235 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2236 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2237 - FRAME_MENUBAR_HEIGHT (f
)
2238 - FRAME_TOOLBAR_HEIGHT (f
)
2239 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2242 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2243 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2248 /* Set X fontset for XIC of frame F, using base font name
2249 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2252 xic_set_xfontset (f
, base_fontname
)
2254 char *base_fontname
;
2259 xic_free_xfontset (f
);
2261 xfs
= xic_create_xfontset (f
, base_fontname
);
2263 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2264 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2265 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2266 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2267 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2270 FRAME_XIC_FONTSET (f
) = xfs
;
2273 #endif /* HAVE_X_I18N */
2277 #ifdef USE_X_TOOLKIT
2279 /* Create and set up the X widget for frame F. */
2282 x_window (f
, window_prompting
, minibuffer_only
)
2284 long window_prompting
;
2285 int minibuffer_only
;
2287 XClassHint class_hints
;
2288 XSetWindowAttributes attributes
;
2289 unsigned long attribute_mask
;
2290 Widget shell_widget
;
2292 Widget frame_widget
;
2298 /* Use the resource name as the top-level widget name
2299 for looking up resources. Make a non-Lisp copy
2300 for the window manager, so GC relocation won't bother it.
2302 Elsewhere we specify the window name for the window manager. */
2305 char *str
= (char *) SDATA (Vx_resource_name
);
2306 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2307 strcpy (f
->namebuf
, str
);
2311 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2312 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2313 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2314 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2315 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2316 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2317 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2318 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2319 applicationShellWidgetClass
,
2320 FRAME_X_DISPLAY (f
), al
, ac
);
2322 f
->output_data
.x
->widget
= shell_widget
;
2323 /* maybe_set_screen_title_format (shell_widget); */
2325 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2326 (widget_value
*) NULL
,
2327 shell_widget
, False
,
2331 (lw_callback
) NULL
);
2334 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2335 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2336 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2337 XtSetValues (pane_widget
, al
, ac
);
2338 f
->output_data
.x
->column_widget
= pane_widget
;
2340 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2341 the emacs screen when changing menubar. This reduces flickering. */
2344 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2345 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2346 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2347 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2348 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2349 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2350 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2351 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2352 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2355 f
->output_data
.x
->edit_widget
= frame_widget
;
2357 XtManageChild (frame_widget
);
2359 /* Do some needed geometry management. */
2362 char *tem
, shell_position
[32];
2365 int extra_borders
= 0;
2367 = (f
->output_data
.x
->menubar_widget
2368 ? (f
->output_data
.x
->menubar_widget
->core
.height
2369 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2372 #if 0 /* Experimentally, we now get the right results
2373 for -geometry -0-0 without this. 24 Aug 96, rms. */
2374 if (FRAME_EXTERNAL_MENU_BAR (f
))
2377 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2378 menubar_size
+= ibw
;
2382 f
->output_data
.x
->menubar_height
= menubar_size
;
2385 /* Motif seems to need this amount added to the sizes
2386 specified for the shell widget. The Athena/Lucid widgets don't.
2387 Both conclusions reached experimentally. -- rms. */
2388 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2389 &extra_borders
, NULL
);
2393 /* Convert our geometry parameters into a geometry string
2395 Note that we do not specify here whether the position
2396 is a user-specified or program-specified one.
2397 We pass that information later, in x_wm_set_size_hints. */
2399 int left
= f
->left_pos
;
2400 int xneg
= window_prompting
& XNegative
;
2401 int top
= f
->top_pos
;
2402 int yneg
= window_prompting
& YNegative
;
2408 if (window_prompting
& USPosition
)
2409 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2410 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2411 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2412 (xneg
? '-' : '+'), left
,
2413 (yneg
? '-' : '+'), top
);
2416 sprintf (shell_position
, "=%dx%d",
2417 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2418 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2420 /* Setting x and y when the position is not specified in
2421 the geometry string will set program position in the WM hints.
2422 If Emacs had just one program position, we could set it in
2423 fallback resources, but since each make-frame call can specify
2424 different program positions, this is easier. */
2425 XtSetArg (al
[ac
], XtNx
, left
); ac
++;
2426 XtSetArg (al
[ac
], XtNy
, top
); ac
++;
2430 len
= strlen (shell_position
) + 1;
2431 /* We don't free this because we don't know whether
2432 it is safe to free it while the frame exists.
2433 It isn't worth the trouble of arranging to free it
2434 when the frame is deleted. */
2435 tem
= (char *) xmalloc (len
);
2436 strncpy (tem
, shell_position
, len
);
2437 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2438 XtSetValues (shell_widget
, al
, ac
);
2441 XtManageChild (pane_widget
);
2442 XtRealizeWidget (shell_widget
);
2444 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2446 validate_x_resource_name ();
2448 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2449 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2450 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2453 FRAME_XIC (f
) = NULL
;
2455 create_frame_xic (f
);
2458 f
->output_data
.x
->wm_hints
.input
= True
;
2459 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2460 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2461 &f
->output_data
.x
->wm_hints
);
2463 hack_wm_protocols (f
, shell_widget
);
2466 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2469 /* Do a stupid property change to force the server to generate a
2470 PropertyNotify event so that the event_stream server timestamp will
2471 be initialized to something relevant to the time we created the window.
2473 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2474 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2475 XA_ATOM
, 32, PropModeAppend
,
2476 (unsigned char*) NULL
, 0);
2478 /* Make all the standard events reach the Emacs frame. */
2479 attributes
.event_mask
= STANDARD_EVENT_SET
;
2484 /* XIM server might require some X events. */
2485 unsigned long fevent
= NoEventMask
;
2486 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2487 attributes
.event_mask
|= fevent
;
2489 #endif /* HAVE_X_I18N */
2491 attribute_mask
= CWEventMask
;
2492 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2493 attribute_mask
, &attributes
);
2495 XtMapWidget (frame_widget
);
2497 /* x_set_name normally ignores requests to set the name if the
2498 requested name is the same as the current name. This is the one
2499 place where that assumption isn't correct; f->name is set, but
2500 the X server hasn't been told. */
2503 int explicit = f
->explicit_name
;
2505 f
->explicit_name
= 0;
2508 x_set_name (f
, name
, explicit);
2511 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2512 f
->output_data
.x
->text_cursor
);
2516 /* This is a no-op, except under Motif. Make sure main areas are
2517 set to something reasonable, in case we get an error later. */
2518 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2521 #else /* not USE_X_TOOLKIT */
2527 if (! xg_create_frame_widgets (f
))
2528 error ("Unable to create window");
2531 FRAME_XIC (f
) = NULL
;
2535 create_frame_xic (f
);
2538 /* XIM server might require some X events. */
2539 unsigned long fevent
= NoEventMask
;
2540 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2542 if (fevent
!= NoEventMask
)
2544 XSetWindowAttributes attributes
;
2545 XWindowAttributes wattr
;
2546 unsigned long attribute_mask
;
2548 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2550 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2551 attribute_mask
= CWEventMask
;
2552 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2553 attribute_mask
, &attributes
);
2561 #else /*! USE_GTK */
2562 /* Create and set up the X window for frame F. */
2569 XClassHint class_hints
;
2570 XSetWindowAttributes attributes
;
2571 unsigned long attribute_mask
;
2573 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2574 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2575 attributes
.bit_gravity
= StaticGravity
;
2576 attributes
.backing_store
= NotUseful
;
2577 attributes
.save_under
= True
;
2578 attributes
.event_mask
= STANDARD_EVENT_SET
;
2579 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2580 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2585 = XCreateWindow (FRAME_X_DISPLAY (f
),
2586 f
->output_data
.x
->parent_desc
,
2589 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2591 CopyFromParent
, /* depth */
2592 InputOutput
, /* class */
2594 attribute_mask
, &attributes
);
2599 create_frame_xic (f
);
2602 /* XIM server might require some X events. */
2603 unsigned long fevent
= NoEventMask
;
2604 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2605 attributes
.event_mask
|= fevent
;
2606 attribute_mask
= CWEventMask
;
2607 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2608 attribute_mask
, &attributes
);
2611 #endif /* HAVE_X_I18N */
2613 validate_x_resource_name ();
2615 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2616 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2617 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2619 /* The menubar is part of the ordinary display;
2620 it does not count in addition to the height of the window. */
2621 f
->output_data
.x
->menubar_height
= 0;
2623 /* This indicates that we use the "Passive Input" input model.
2624 Unless we do this, we don't get the Focus{In,Out} events that we
2625 need to draw the cursor correctly. Accursed bureaucrats.
2626 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2628 f
->output_data
.x
->wm_hints
.input
= True
;
2629 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2630 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2631 &f
->output_data
.x
->wm_hints
);
2632 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2634 /* Request "save yourself" and "delete window" commands from wm. */
2637 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2638 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2639 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2642 /* x_set_name normally ignores requests to set the name if the
2643 requested name is the same as the current name. This is the one
2644 place where that assumption isn't correct; f->name is set, but
2645 the X server hasn't been told. */
2648 int explicit = f
->explicit_name
;
2650 f
->explicit_name
= 0;
2653 x_set_name (f
, name
, explicit);
2656 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2657 f
->output_data
.x
->text_cursor
);
2661 if (FRAME_X_WINDOW (f
) == 0)
2662 error ("Unable to create window");
2665 #endif /* not USE_GTK */
2666 #endif /* not USE_X_TOOLKIT */
2668 /* Verify that the icon position args for this window are valid. */
2671 x_icon_verify (f
, parms
)
2675 Lisp_Object icon_x
, icon_y
;
2677 /* Set the position of the icon. Note that twm groups all
2678 icons in an icon window. */
2679 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2680 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2681 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2683 CHECK_NUMBER (icon_x
);
2684 CHECK_NUMBER (icon_y
);
2686 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2687 error ("Both left and top icon corners of icon must be specified");
2690 /* Handle the icon stuff for this window. Perhaps later we might
2691 want an x_set_icon_position which can be called interactively as
2699 Lisp_Object icon_x
, icon_y
;
2700 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2702 /* Set the position of the icon. Note that twm groups all
2703 icons in an icon window. */
2704 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2705 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2706 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2708 CHECK_NUMBER (icon_x
);
2709 CHECK_NUMBER (icon_y
);
2711 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2712 error ("Both left and top icon corners of icon must be specified");
2716 if (! EQ (icon_x
, Qunbound
))
2717 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2719 /* Start up iconic or window? */
2720 x_wm_set_window_state
2721 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
2726 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
2733 /* Make the GCs needed for this window, setting the
2734 background, border and mouse colors; also create the
2735 mouse cursor and the gray border tile. */
2737 static char cursor_bits
[] =
2739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2742 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2749 XGCValues gc_values
;
2753 /* Create the GCs of this frame.
2754 Note that many default values are used. */
2757 gc_values
.font
= FRAME_FONT (f
)->fid
;
2758 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
2759 gc_values
.background
= f
->output_data
.x
->background_pixel
;
2760 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2761 f
->output_data
.x
->normal_gc
2762 = XCreateGC (FRAME_X_DISPLAY (f
),
2764 GCLineWidth
| GCFont
| GCForeground
| GCBackground
,
2767 /* Reverse video style. */
2768 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
2769 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
2770 f
->output_data
.x
->reverse_gc
2771 = XCreateGC (FRAME_X_DISPLAY (f
),
2773 GCFont
| GCForeground
| GCBackground
| GCLineWidth
,
2776 /* Cursor has cursor-color background, background-color foreground. */
2777 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
2778 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
2779 gc_values
.fill_style
= FillOpaqueStippled
;
2781 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
2782 FRAME_X_DISPLAY_INFO (f
)->root_window
,
2783 cursor_bits
, 16, 16);
2784 f
->output_data
.x
->cursor_gc
2785 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2786 (GCFont
| GCForeground
| GCBackground
2787 | GCFillStyle
/* | GCStipple */ | GCLineWidth
),
2791 f
->output_data
.x
->white_relief
.gc
= 0;
2792 f
->output_data
.x
->black_relief
.gc
= 0;
2794 /* Create the gray border tile used when the pointer is not in
2795 the frame. Since this depends on the frame's pixel values,
2796 this must be done on a per-frame basis. */
2797 f
->output_data
.x
->border_tile
2798 = (XCreatePixmapFromBitmapData
2799 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
2800 gray_bits
, gray_width
, gray_height
,
2801 f
->output_data
.x
->foreground_pixel
,
2802 f
->output_data
.x
->background_pixel
,
2803 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
2809 /* Free what was was allocated in x_make_gc. */
2815 Display
*dpy
= FRAME_X_DISPLAY (f
);
2819 if (f
->output_data
.x
->normal_gc
)
2821 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
2822 f
->output_data
.x
->normal_gc
= 0;
2825 if (f
->output_data
.x
->reverse_gc
)
2827 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
2828 f
->output_data
.x
->reverse_gc
= 0;
2831 if (f
->output_data
.x
->cursor_gc
)
2833 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
2834 f
->output_data
.x
->cursor_gc
= 0;
2837 if (f
->output_data
.x
->border_tile
)
2839 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
2840 f
->output_data
.x
->border_tile
= 0;
2847 /* Handler for signals raised during x_create_frame and
2848 x_create_top_frame. FRAME is the frame which is partially
2852 unwind_create_frame (frame
)
2855 struct frame
*f
= XFRAME (frame
);
2857 /* If frame is ``official'', nothing to do. */
2858 if (!CONSP (Vframe_list
) || !EQ (XCAR (Vframe_list
), frame
))
2861 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2864 x_free_frame_resources (f
);
2866 /* Check that reference counts are indeed correct. */
2867 xassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
2868 xassert (dpyinfo
->image_cache
->refcount
== image_cache_refcount
);
2876 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2878 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
2879 Returns an Emacs frame object.
2880 ALIST is an alist of frame parameters.
2881 If the parameters specify that the frame should not have a minibuffer,
2882 and do not specify a specific minibuffer window to use,
2883 then `default-minibuffer-frame' must be a frame whose minibuffer can
2884 be shared by the new frame.
2886 This function is an internal primitive--use `make-frame' instead. */)
2891 Lisp_Object frame
, tem
;
2893 int minibuffer_only
= 0;
2894 long window_prompting
= 0;
2896 int count
= SPECPDL_INDEX ();
2897 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
2898 Lisp_Object display
;
2899 struct x_display_info
*dpyinfo
= NULL
;
2905 /* Use this general default value to start with
2906 until we know if this frame has a specified name. */
2907 Vx_resource_name
= Vinvocation_name
;
2909 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
2910 if (EQ (display
, Qunbound
))
2912 dpyinfo
= check_x_display_info (display
);
2914 kb
= dpyinfo
->kboard
;
2916 kb
= &the_only_kboard
;
2919 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
2921 && ! EQ (name
, Qunbound
)
2923 error ("Invalid frame name--not a string or nil");
2926 Vx_resource_name
= name
;
2928 /* See if parent window is specified. */
2929 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
2930 if (EQ (parent
, Qunbound
))
2932 if (! NILP (parent
))
2933 CHECK_NUMBER (parent
);
2935 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2936 /* No need to protect DISPLAY because that's not used after passing
2937 it to make_frame_without_minibuffer. */
2939 GCPRO4 (parms
, parent
, name
, frame
);
2940 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
2942 if (EQ (tem
, Qnone
) || NILP (tem
))
2943 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
2944 else if (EQ (tem
, Qonly
))
2946 f
= make_minibuffer_frame ();
2947 minibuffer_only
= 1;
2949 else if (WINDOWP (tem
))
2950 f
= make_frame_without_minibuffer (tem
, kb
, display
);
2954 XSETFRAME (frame
, f
);
2956 /* Note that X Windows does support scroll bars. */
2957 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
2959 f
->output_method
= output_x_window
;
2960 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
2961 bzero (f
->output_data
.x
, sizeof (struct x_output
));
2962 f
->output_data
.x
->icon_bitmap
= -1;
2963 FRAME_FONTSET (f
) = -1;
2964 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
2965 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
2966 #ifdef USE_TOOLKIT_SCROLL_BARS
2967 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
2968 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
2969 #endif /* USE_TOOLKIT_SCROLL_BARS */
2970 record_unwind_protect (unwind_create_frame
, frame
);
2973 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
2975 if (! STRINGP (f
->icon_name
))
2976 f
->icon_name
= Qnil
;
2978 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
2980 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
2981 dpyinfo_refcount
= dpyinfo
->reference_count
;
2982 #endif /* GLYPH_DEBUG */
2984 FRAME_KBOARD (f
) = kb
;
2987 /* These colors will be set anyway later, but it's important
2988 to get the color reference counts right, so initialize them! */
2991 struct gcpro gcpro1
;
2993 /* Function x_decode_color can signal an error. Make
2994 sure to initialize color slots so that we won't try
2995 to free colors we haven't allocated. */
2996 f
->output_data
.x
->foreground_pixel
= -1;
2997 f
->output_data
.x
->background_pixel
= -1;
2998 f
->output_data
.x
->cursor_pixel
= -1;
2999 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3000 f
->output_data
.x
->border_pixel
= -1;
3001 f
->output_data
.x
->mouse_pixel
= -1;
3003 black
= build_string ("black");
3005 f
->output_data
.x
->foreground_pixel
3006 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3007 f
->output_data
.x
->background_pixel
3008 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3009 f
->output_data
.x
->cursor_pixel
3010 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3011 f
->output_data
.x
->cursor_foreground_pixel
3012 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3013 f
->output_data
.x
->border_pixel
3014 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3015 f
->output_data
.x
->mouse_pixel
3016 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3020 /* Specify the parent under which to make this X window. */
3024 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3025 f
->output_data
.x
->explicit_parent
= 1;
3029 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3030 f
->output_data
.x
->explicit_parent
= 0;
3033 /* Set the name; the functions to which we pass f expect the name to
3035 if (EQ (name
, Qunbound
) || NILP (name
))
3037 f
->name
= build_string (dpyinfo
->x_id_name
);
3038 f
->explicit_name
= 0;
3043 f
->explicit_name
= 1;
3044 /* use the frame's title when getting resources for this frame. */
3045 specbind (Qx_resource_name
, name
);
3048 /* Extract the window parameters from the supplied values
3049 that are needed to determine window geometry. */
3053 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3056 /* First, try whatever font the caller has specified. */
3059 tem
= Fquery_fontset (font
, Qnil
);
3061 font
= x_new_fontset (f
, SDATA (tem
));
3063 font
= x_new_font (f
, SDATA (font
));
3066 /* Try out a font which we hope has bold and italic variations. */
3067 if (!STRINGP (font
))
3068 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
3069 if (!STRINGP (font
))
3070 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3071 if (! STRINGP (font
))
3072 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3073 if (! STRINGP (font
))
3074 /* This was formerly the first thing tried, but it finds too many fonts
3075 and takes too long. */
3076 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3077 /* If those didn't work, look for something which will at least work. */
3078 if (! STRINGP (font
))
3079 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3081 if (! STRINGP (font
))
3082 font
= build_string ("fixed");
3084 x_default_parameter (f
, parms
, Qfont
, font
,
3085 "font", "Font", RES_TYPE_STRING
);
3089 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3090 whereby it fails to get any font. */
3091 xlwmenu_default_font
= FRAME_FONT (f
);
3094 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3095 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3097 /* This defaults to 1 in order to match xterm. We recognize either
3098 internalBorderWidth or internalBorder (which is what xterm calls
3100 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3104 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3105 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3106 if (! EQ (value
, Qunbound
))
3107 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3110 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3111 "internalBorderWidth", "internalBorderWidth",
3113 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3114 "verticalScrollBars", "ScrollBars",
3117 /* Also do the stuff which must be set before the window exists. */
3118 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3119 "foreground", "Foreground", RES_TYPE_STRING
);
3120 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3121 "background", "Background", RES_TYPE_STRING
);
3122 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3123 "pointerColor", "Foreground", RES_TYPE_STRING
);
3124 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3125 "cursorColor", "Foreground", RES_TYPE_STRING
);
3126 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3127 "borderColor", "BorderColor", RES_TYPE_STRING
);
3128 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3129 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3130 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3131 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3132 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3133 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3134 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3135 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3137 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3138 "scrollBarForeground",
3139 "ScrollBarForeground", 1);
3140 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3141 "scrollBarBackground",
3142 "ScrollBarBackground", 0);
3144 /* Init faces before x_default_parameter is called for scroll-bar
3145 parameters because that function calls x_set_scroll_bar_width,
3146 which calls change_frame_size, which calls Fset_window_buffer,
3147 which runs hooks, which call Fvertical_motion. At the end, we
3148 end up in init_iterator with a null face cache, which should not
3150 init_frame_faces (f
);
3152 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3153 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
3154 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (1),
3155 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
3156 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3157 "bufferPredicate", "BufferPredicate",
3159 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3160 "title", "Title", RES_TYPE_STRING
);
3161 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3162 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3163 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3164 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3166 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3168 /* Compute the size of the X window. */
3169 window_prompting
= x_figure_window_size (f
, parms
, 1);
3171 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3172 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3174 x_icon_verify (f
, parms
);
3176 /* Create the X widget or window. */
3177 #ifdef USE_X_TOOLKIT
3178 x_window (f
, window_prompting
, minibuffer_only
);
3186 /* Now consider the frame official. */
3187 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3188 Vframe_list
= Fcons (frame
, Vframe_list
);
3190 /* We need to do this after creating the X window, so that the
3191 icon-creation functions can say whose icon they're describing. */
3192 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3193 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
3195 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3196 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3197 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3198 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3199 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3200 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3201 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3202 "scrollBarWidth", "ScrollBarWidth",
3205 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3206 Change will not be effected unless different from the current
3208 width
= FRAME_COLS (f
);
3209 height
= FRAME_LINES (f
);
3211 SET_FRAME_COLS (f
, 0);
3212 FRAME_LINES (f
) = 0;
3213 change_frame_size (f
, height
, width
, 1, 0, 0);
3215 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3216 /* Create the menu bar. */
3217 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3219 /* If this signals an error, we haven't set size hints for the
3220 frame and we didn't make it visible. */
3221 initialize_frame_menubar (f
);
3224 /* This is a no-op, except under Motif where it arranges the
3225 main window for the widgets on it. */
3226 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3227 f
->output_data
.x
->menubar_widget
,
3228 f
->output_data
.x
->edit_widget
);
3229 #endif /* not USE_GTK */
3231 #endif /* USE_X_TOOLKIT || USE_GTK */
3233 /* Tell the server what size and position, etc, we want, and how
3234 badly we want them. This should be done after we have the menu
3235 bar so that its size can be taken into account. */
3237 x_wm_set_size_hint (f
, window_prompting
, 0);
3240 /* Make the window appear on the frame and enable display, unless
3241 the caller says not to. However, with explicit parent, Emacs
3242 cannot control visibility, so don't try. */
3243 if (! f
->output_data
.x
->explicit_parent
)
3245 Lisp_Object visibility
;
3247 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3249 if (EQ (visibility
, Qunbound
))
3252 if (EQ (visibility
, Qicon
))
3253 x_iconify_frame (f
);
3254 else if (! NILP (visibility
))
3255 x_make_frame_visible (f
);
3257 /* Must have been Qnil. */
3261 /* Set the WM leader property. GTK does this itself, so this is not
3262 needed when using GTK. */
3263 if (dpyinfo
->client_leader_window
!= 0)
3266 XChangeProperty (FRAME_X_DISPLAY (f
),
3267 FRAME_OUTER_WINDOW (f
),
3268 dpyinfo
->Xatom_wm_client_leader
,
3269 XA_WINDOW
, 32, PropModeReplace
,
3270 (char *) &dpyinfo
->client_leader_window
, 1);
3276 /* Make sure windows on this frame appear in calls to next-window
3277 and similar functions. */
3278 Vwindow_list
= Qnil
;
3280 return unbind_to (count
, frame
);
3284 /* FRAME is used only to get a handle on the X display. We don't pass the
3285 display info directly because we're called from frame.c, which doesn't
3286 know about that structure. */
3289 x_get_focus_frame (frame
)
3290 struct frame
*frame
;
3292 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3294 if (! dpyinfo
->x_focus_frame
)
3297 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3302 /* In certain situations, when the window manager follows a
3303 click-to-focus policy, there seems to be no way around calling
3304 XSetInputFocus to give another frame the input focus .
3306 In an ideal world, XSetInputFocus should generally be avoided so
3307 that applications don't interfere with the window manager's focus
3308 policy. But I think it's okay to use when it's clearly done
3309 following a user-command. */
3311 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 1, 0,
3312 doc
: /* Set the input focus to FRAME.
3313 FRAME nil means use the selected frame. */)
3317 struct frame
*f
= check_x_frame (frame
);
3318 Display
*dpy
= FRAME_X_DISPLAY (f
);
3322 count
= x_catch_errors (dpy
);
3323 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3324 RevertToParent
, CurrentTime
);
3325 x_uncatch_errors (dpy
, count
);
3332 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3333 doc
: /* Internal function called by `color-defined-p', which see. */)
3335 Lisp_Object color
, frame
;
3338 FRAME_PTR f
= check_x_frame (frame
);
3340 CHECK_STRING (color
);
3342 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3348 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3349 doc
: /* Internal function called by `color-values', which see. */)
3351 Lisp_Object color
, frame
;
3354 FRAME_PTR f
= check_x_frame (frame
);
3356 CHECK_STRING (color
);
3358 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3362 rgb
[0] = make_number (foo
.red
);
3363 rgb
[1] = make_number (foo
.green
);
3364 rgb
[2] = make_number (foo
.blue
);
3365 return Flist (3, rgb
);
3371 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3372 doc
: /* Internal function called by `display-color-p', which see. */)
3374 Lisp_Object display
;
3376 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3378 if (dpyinfo
->n_planes
<= 2)
3381 switch (dpyinfo
->visual
->class)
3394 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3396 doc
: /* Return t if the X display supports shades of gray.
3397 Note that color displays do support shades of gray.
3398 The optional argument DISPLAY specifies which display to ask about.
3399 DISPLAY should be either a frame or a display name (a string).
3400 If omitted or nil, that stands for the selected frame's display. */)
3402 Lisp_Object display
;
3404 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3406 if (dpyinfo
->n_planes
<= 1)
3409 switch (dpyinfo
->visual
->class)
3424 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3426 doc
: /* Returns the width in pixels of the X display DISPLAY.
3427 The optional argument DISPLAY specifies which display to ask about.
3428 DISPLAY should be either a frame or a display name (a string).
3429 If omitted or nil, that stands for the selected frame's display. */)
3431 Lisp_Object display
;
3433 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3435 return make_number (dpyinfo
->width
);
3438 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3439 Sx_display_pixel_height
, 0, 1, 0,
3440 doc
: /* Returns the height in pixels of the X display DISPLAY.
3441 The optional argument DISPLAY specifies which display to ask about.
3442 DISPLAY should be either a frame or a display name (a string).
3443 If omitted or nil, that stands for the selected frame's display. */)
3445 Lisp_Object display
;
3447 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3449 return make_number (dpyinfo
->height
);
3452 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3454 doc
: /* Returns the number of bitplanes of the X display DISPLAY.
3455 The optional argument DISPLAY specifies which display to ask about.
3456 DISPLAY should be either a frame or a display name (a string).
3457 If omitted or nil, that stands for the selected frame's display. */)
3459 Lisp_Object display
;
3461 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3463 return make_number (dpyinfo
->n_planes
);
3466 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3468 doc
: /* Returns the number of color cells of the X display DISPLAY.
3469 The optional argument DISPLAY specifies which display to ask about.
3470 DISPLAY should be either a frame or a display name (a string).
3471 If omitted or nil, that stands for the selected frame's display. */)
3473 Lisp_Object display
;
3475 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3477 int nr_planes
= DisplayPlanes (dpyinfo
->display
,
3478 XScreenNumberOfScreen (dpyinfo
->screen
));
3480 /* Truncate nr_planes to 24 to avoid integer overflow.
3481 Some displays says 32, but only 24 bits are actually significant.
3482 There are only very few and rare video cards that have more than
3483 24 significant bits. Also 24 bits is more than 16 million colors,
3484 it "should be enough for everyone". */
3485 if (nr_planes
> 24) nr_planes
= 24;
3487 return make_number (1 << nr_planes
);
3490 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3491 Sx_server_max_request_size
,
3493 doc
: /* Returns the maximum request size of the X server of display DISPLAY.
3494 The optional argument DISPLAY specifies which display to ask about.
3495 DISPLAY should be either a frame or a display name (a string).
3496 If omitted or nil, that stands for the selected frame's display. */)
3498 Lisp_Object display
;
3500 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3502 return make_number (MAXREQUEST (dpyinfo
->display
));
3505 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3506 doc
: /* Returns the "vendor ID" string of the X server of display DISPLAY.
3507 \(Labelling every distributor as a "vendor" embodies the false assumption
3508 that operating systems cannot be developed and distributed noncommercially.)
3509 The optional argument DISPLAY specifies which display to ask about.
3510 DISPLAY should be either a frame or a display name (a string).
3511 If omitted or nil, that stands for the selected frame's display. */)
3513 Lisp_Object display
;
3515 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3516 char *vendor
= ServerVendor (dpyinfo
->display
);
3518 if (! vendor
) vendor
= "";
3519 return build_string (vendor
);
3522 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3523 doc
: /* Returns the version numbers of the X server of display DISPLAY.
3524 The value is a list of three integers: the major and minor
3525 version numbers of the X Protocol in use, and the distributor-specific release
3526 number. See also the function `x-server-vendor'.
3528 The optional argument DISPLAY specifies which display to ask about.
3529 DISPLAY should be either a frame or a display name (a string).
3530 If omitted or nil, that stands for the selected frame's display. */)
3532 Lisp_Object display
;
3534 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3535 Display
*dpy
= dpyinfo
->display
;
3537 return Fcons (make_number (ProtocolVersion (dpy
)),
3538 Fcons (make_number (ProtocolRevision (dpy
)),
3539 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3542 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3543 doc
: /* Return the number of screens on the X server of display DISPLAY.
3544 The optional argument DISPLAY specifies which display to ask about.
3545 DISPLAY should be either a frame or a display name (a string).
3546 If omitted or nil, that stands for the selected frame's display. */)
3548 Lisp_Object display
;
3550 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3552 return make_number (ScreenCount (dpyinfo
->display
));
3555 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3556 doc
: /* Return the height in millimeters of the X display DISPLAY.
3557 The optional argument DISPLAY specifies which display to ask about.
3558 DISPLAY should be either a frame or a display name (a string).
3559 If omitted or nil, that stands for the selected frame's display. */)
3561 Lisp_Object display
;
3563 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3565 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3568 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3569 doc
: /* Return the width in millimeters of the X display DISPLAY.
3570 The optional argument DISPLAY specifies which display to ask about.
3571 DISPLAY should be either a frame or a display name (a string).
3572 If omitted or nil, that stands for the selected frame's display. */)
3574 Lisp_Object display
;
3576 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3578 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3581 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3582 Sx_display_backing_store
, 0, 1, 0,
3583 doc
: /* Returns an indication of whether X display DISPLAY does backing store.
3584 The value may be `always', `when-mapped', or `not-useful'.
3585 The optional argument DISPLAY specifies which display to ask about.
3586 DISPLAY should be either a frame or a display name (a string).
3587 If omitted or nil, that stands for the selected frame's display. */)
3589 Lisp_Object display
;
3591 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3594 switch (DoesBackingStore (dpyinfo
->screen
))
3597 result
= intern ("always");
3601 result
= intern ("when-mapped");
3605 result
= intern ("not-useful");
3609 error ("Strange value for BackingStore parameter of screen");
3616 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3617 Sx_display_visual_class
, 0, 1, 0,
3618 doc
: /* Return the visual class of the X display DISPLAY.
3619 The value is one of the symbols `static-gray', `gray-scale',
3620 `static-color', `pseudo-color', `true-color', or `direct-color'.
3622 The optional argument DISPLAY specifies which display to ask about.
3623 DISPLAY should be either a frame or a display name (a string).
3624 If omitted or nil, that stands for the selected frame's display. */)
3626 Lisp_Object display
;
3628 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3631 switch (dpyinfo
->visual
->class)
3634 result
= intern ("static-gray");
3637 result
= intern ("gray-scale");
3640 result
= intern ("static-color");
3643 result
= intern ("pseudo-color");
3646 result
= intern ("true-color");
3649 result
= intern ("direct-color");
3652 error ("Display has an unknown visual class");
3659 DEFUN ("x-display-save-under", Fx_display_save_under
,
3660 Sx_display_save_under
, 0, 1, 0,
3661 doc
: /* Returns t if the X display DISPLAY supports the save-under feature.
3662 The optional argument DISPLAY specifies which display to ask about.
3663 DISPLAY should be either a frame or a display name (a string).
3664 If omitted or nil, that stands for the selected frame's display. */)
3666 Lisp_Object display
;
3668 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3670 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3678 register struct frame
*f
;
3680 return FRAME_PIXEL_WIDTH (f
);
3685 register struct frame
*f
;
3687 return FRAME_PIXEL_HEIGHT (f
);
3692 register struct frame
*f
;
3694 return FRAME_COLUMN_WIDTH (f
);
3699 register struct frame
*f
;
3701 return FRAME_LINE_HEIGHT (f
);
3706 register struct frame
*f
;
3708 return FRAME_X_DISPLAY_INFO (f
)->n_planes
;
3713 /************************************************************************
3715 ************************************************************************/
3718 /* Mapping visual names to visuals. */
3720 static struct visual_class
3727 {"StaticGray", StaticGray
},
3728 {"GrayScale", GrayScale
},
3729 {"StaticColor", StaticColor
},
3730 {"PseudoColor", PseudoColor
},
3731 {"TrueColor", TrueColor
},
3732 {"DirectColor", DirectColor
},
3737 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3739 /* Value is the screen number of screen SCR. This is a substitute for
3740 the X function with the same name when that doesn't exist. */
3743 XScreenNumberOfScreen (scr
)
3744 register Screen
*scr
;
3746 Display
*dpy
= scr
->display
;
3749 for (i
= 0; i
< dpy
->nscreens
; ++i
)
3750 if (scr
== dpy
->screens
+ i
)
3756 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3759 /* Select the visual that should be used on display DPYINFO. Set
3760 members of DPYINFO appropriately. Called from x_term_init. */
3763 select_visual (dpyinfo
)
3764 struct x_display_info
*dpyinfo
;
3766 Display
*dpy
= dpyinfo
->display
;
3767 Screen
*screen
= dpyinfo
->screen
;
3770 /* See if a visual is specified. */
3771 value
= display_x_get_resource (dpyinfo
,
3772 build_string ("visualClass"),
3773 build_string ("VisualClass"),
3775 if (STRINGP (value
))
3777 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
3778 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
3779 depth, a decimal number. NAME is compared with case ignored. */
3780 char *s
= (char *) alloca (SBYTES (value
) + 1);
3785 strcpy (s
, SDATA (value
));
3786 dash
= index (s
, '-');
3789 dpyinfo
->n_planes
= atoi (dash
+ 1);
3793 /* We won't find a matching visual with depth 0, so that
3794 an error will be printed below. */
3795 dpyinfo
->n_planes
= 0;
3797 /* Determine the visual class. */
3798 for (i
= 0; visual_classes
[i
].name
; ++i
)
3799 if (xstricmp (s
, visual_classes
[i
].name
) == 0)
3801 class = visual_classes
[i
].class;
3805 /* Look up a matching visual for the specified class. */
3807 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
3808 dpyinfo
->n_planes
, class, &vinfo
))
3809 fatal ("Invalid visual specification `%s'", SDATA (value
));
3811 dpyinfo
->visual
= vinfo
.visual
;
3816 XVisualInfo
*vinfo
, vinfo_template
;
3818 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
3821 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
3823 vinfo_template
.visualid
= dpyinfo
->visual
->visualid
;
3825 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
3826 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
3827 &vinfo_template
, &n_visuals
);
3829 fatal ("Can't get proper X visual info");
3831 dpyinfo
->n_planes
= vinfo
->depth
;
3832 XFree ((char *) vinfo
);
3837 /* Return the X display structure for the display named NAME.
3838 Open a new connection if necessary. */
3840 struct x_display_info
*
3841 x_display_info_for_name (name
)
3845 struct x_display_info
*dpyinfo
;
3847 CHECK_STRING (name
);
3849 if (! EQ (Vwindow_system
, intern ("x")))
3850 error ("Not using X Windows");
3852 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
3854 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
3857 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
3862 /* Use this general default value to start with. */
3863 Vx_resource_name
= Vinvocation_name
;
3865 validate_x_resource_name ();
3867 dpyinfo
= x_term_init (name
, (char *)0,
3868 (char *) SDATA (Vx_resource_name
));
3871 error ("Cannot connect to X server %s", SDATA (name
));
3874 XSETFASTINT (Vwindow_system_version
, 11);
3880 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
3882 doc
: /* Open a connection to an X server.
3883 DISPLAY is the name of the display to connect to.
3884 Optional second arg XRM-STRING is a string of resources in xrdb format.
3885 If the optional third arg MUST-SUCCEED is non-nil,
3886 terminate Emacs if we can't open the connection. */)
3887 (display
, xrm_string
, must_succeed
)
3888 Lisp_Object display
, xrm_string
, must_succeed
;
3890 unsigned char *xrm_option
;
3891 struct x_display_info
*dpyinfo
;
3893 CHECK_STRING (display
);
3894 if (! NILP (xrm_string
))
3895 CHECK_STRING (xrm_string
);
3897 if (! EQ (Vwindow_system
, intern ("x")))
3898 error ("Not using X Windows");
3900 if (! NILP (xrm_string
))
3901 xrm_option
= (unsigned char *) SDATA (xrm_string
);
3903 xrm_option
= (unsigned char *) 0;
3905 validate_x_resource_name ();
3907 /* This is what opens the connection and sets x_current_display.
3908 This also initializes many symbols, such as those used for input. */
3909 dpyinfo
= x_term_init (display
, xrm_option
,
3910 (char *) SDATA (Vx_resource_name
));
3914 if (!NILP (must_succeed
))
3915 fatal ("Cannot connect to X server %s.\n\
3916 Check the DISPLAY environment variable or use `-d'.\n\
3917 Also use the `xauth' program to verify that you have the proper\n\
3918 authorization information needed to connect the X server.\n\
3919 An insecure way to solve the problem may be to use `xhost'.\n",
3922 error ("Cannot connect to X server %s", SDATA (display
));
3927 XSETFASTINT (Vwindow_system_version
, 11);
3931 DEFUN ("x-close-connection", Fx_close_connection
,
3932 Sx_close_connection
, 1, 1, 0,
3933 doc
: /* Close the connection to DISPLAY's X server.
3934 For DISPLAY, specify either a frame or a display name (a string).
3935 If DISPLAY is nil, that stands for the selected frame's display. */)
3937 Lisp_Object display
;
3939 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3942 if (dpyinfo
->reference_count
> 0)
3943 error ("Display still has frames on it");
3946 /* Free the fonts in the font table. */
3947 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
3948 if (dpyinfo
->font_table
[i
].name
)
3950 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
3953 x_destroy_all_bitmaps (dpyinfo
);
3954 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
3956 #ifdef USE_X_TOOLKIT
3957 XtCloseDisplay (dpyinfo
->display
);
3959 XCloseDisplay (dpyinfo
->display
);
3962 x_delete_display (dpyinfo
);
3968 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
3969 doc
: /* Return the list of display names that Emacs has connections to. */)
3972 Lisp_Object tail
, result
;
3975 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
3976 result
= Fcons (XCAR (XCAR (tail
)), result
);
3981 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
3982 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
3983 If ON is nil, allow buffering of requests.
3984 Turning on synchronization prohibits the Xlib routines from buffering
3985 requests and seriously degrades performance, but makes debugging much
3987 The optional second argument DISPLAY specifies which display to act on.
3988 DISPLAY should be either a frame or a display name (a string).
3989 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
3991 Lisp_Object display
, on
;
3993 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3995 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4000 /* Wait for responses to all X commands issued so far for frame F. */
4007 XSync (FRAME_X_DISPLAY (f
), False
);
4012 /***********************************************************************
4014 ***********************************************************************/
4016 DEFUN ("x-change-window-property", Fx_change_window_property
,
4017 Sx_change_window_property
, 2, 6, 0,
4018 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
4019 PROP must be a string.
4020 VALUE may be a string or a list of conses, numbers and/or strings.
4021 If an element in the list is a string, it is converted to
4022 an Atom and the value of the Atom is used. If an element is a cons,
4023 it is converted to a 32 bit number where the car is the 16 top bits and the
4024 cdr is the lower 16 bits.
4025 FRAME nil or omitted means use the selected frame.
4026 If TYPE is given and non-nil, it is the name of the type of VALUE.
4027 If TYPE is not given or nil, the type is STRING.
4028 FORMAT gives the size in bits of each element if VALUE is a list.
4029 It must be one of 8, 16 or 32.
4030 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4031 If OUTER_P is non-nil, the property is changed for the outer X window of
4032 FRAME. Default is to change on the edit X window.
4035 (prop
, value
, frame
, type
, format
, outer_p
)
4036 Lisp_Object prop
, value
, frame
, type
, format
, outer_p
;
4038 struct frame
*f
= check_x_frame (frame
);
4040 Atom target_type
= XA_STRING
;
4041 int element_format
= 8;
4042 unsigned char *data
;
4046 CHECK_STRING (prop
);
4048 if (! NILP (format
))
4050 CHECK_NUMBER (format
);
4051 element_format
= XFASTINT (format
);
4053 if (element_format
!= 8 && element_format
!= 16
4054 && element_format
!= 32)
4055 error ("FORMAT must be one of 8, 16 or 32");
4060 nelements
= x_check_property_data (value
);
4061 if (nelements
== -1)
4062 error ("Bad data in VALUE, must be number, string or cons");
4064 if (element_format
== 8)
4065 data
= (unsigned char *) xmalloc (nelements
);
4066 else if (element_format
== 16)
4067 data
= (unsigned char *) xmalloc (nelements
*2);
4069 data
= (unsigned char *) xmalloc (nelements
*4);
4071 x_fill_property_data (FRAME_X_DISPLAY (f
), value
, data
, element_format
);
4075 CHECK_STRING (value
);
4076 data
= SDATA (value
);
4077 nelements
= SCHARS (value
);
4081 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4084 CHECK_STRING (type
);
4085 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (type
), False
);
4088 if (! NILP (outer_p
)) w
= FRAME_OUTER_WINDOW (f
);
4089 else w
= FRAME_X_WINDOW (f
);
4091 XChangeProperty (FRAME_X_DISPLAY (f
), w
,
4092 prop_atom
, target_type
, element_format
, PropModeReplace
,
4095 if (CONSP (value
)) xfree (data
);
4097 /* Make sure the property is set when we return. */
4098 XFlush (FRAME_X_DISPLAY (f
));
4105 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
4106 Sx_delete_window_property
, 1, 2, 0,
4107 doc
: /* Remove window property PROP from X window of FRAME.
4108 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4110 Lisp_Object prop
, frame
;
4112 struct frame
*f
= check_x_frame (frame
);
4115 CHECK_STRING (prop
);
4117 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4118 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
4120 /* Make sure the property is removed when we return. */
4121 XFlush (FRAME_X_DISPLAY (f
));
4128 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
4130 doc
: /* Value is the value of window property PROP on FRAME.
4131 If FRAME is nil or omitted, use the selected frame.
4132 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4133 is the name of the Atom that denotes the type expected.
4134 If SOURCE is non-nil, get the property on that window instead of from
4135 FRAME. The number 0 denotes the root window.
4136 If DELETE_P is non-nil, delete the property after retreiving it.
4137 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4139 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4140 no value of TYPE. */)
4141 (prop
, frame
, type
, source
, delete_p
, vector_ret_p
)
4142 Lisp_Object prop
, frame
, type
, source
, delete_p
, vector_ret_p
;
4144 struct frame
*f
= check_x_frame (frame
);
4147 Lisp_Object prop_value
= Qnil
;
4148 char *tmp_data
= NULL
;
4150 Atom target_type
= XA_STRING
;
4152 unsigned long actual_size
, bytes_remaining
;
4153 Window target_window
= FRAME_X_WINDOW (f
);
4154 struct gcpro gcpro1
;
4156 GCPRO1 (prop_value
);
4157 CHECK_STRING (prop
);
4159 if (! NILP (source
))
4161 if (NUMBERP (source
))
4163 if (FLOATP (source
))
4164 target_window
= (Window
) XFLOAT (source
);
4166 target_window
= XFASTINT (source
);
4168 if (target_window
== 0)
4169 target_window
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4171 else if (CONSP (source
))
4172 target_window
= cons_to_long (source
);
4178 if (strcmp ("AnyPropertyType", SDATA (type
)) == 0)
4179 target_type
= AnyPropertyType
;
4181 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (type
), False
);
4184 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4185 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4186 prop_atom
, 0, 0, False
, target_type
,
4187 &actual_type
, &actual_format
, &actual_size
,
4188 &bytes_remaining
, (unsigned char **) &tmp_data
);
4191 int size
= bytes_remaining
;
4196 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4197 prop_atom
, 0, bytes_remaining
,
4198 ! NILP (delete_p
), target_type
,
4199 &actual_type
, &actual_format
,
4200 &actual_size
, &bytes_remaining
,
4201 (unsigned char **) &tmp_data
);
4202 if (rc
== Success
&& tmp_data
)
4204 if (NILP (vector_ret_p
))
4205 prop_value
= make_string (tmp_data
, size
);
4207 prop_value
= x_property_data_to_lisp (f
,
4208 (unsigned char *) tmp_data
,
4214 if (tmp_data
) XFree (tmp_data
);
4224 /***********************************************************************
4226 ***********************************************************************/
4228 /* If non-null, an asynchronous timer that, when it expires, displays
4229 an hourglass cursor on all frames. */
4231 static struct atimer
*hourglass_atimer
;
4233 /* Non-zero means an hourglass cursor is currently shown. */
4235 static int hourglass_shown_p
;
4237 /* Number of seconds to wait before displaying an hourglass cursor. */
4239 static Lisp_Object Vhourglass_delay
;
4241 /* Default number of seconds to wait before displaying an hourglass
4244 #define DEFAULT_HOURGLASS_DELAY 1
4246 /* Function prototypes. */
4248 static void show_hourglass
P_ ((struct atimer
*));
4249 static void hide_hourglass
P_ ((void));
4252 /* Cancel a currently active hourglass timer, and start a new one. */
4258 int secs
, usecs
= 0;
4260 cancel_hourglass ();
4262 if (INTEGERP (Vhourglass_delay
)
4263 && XINT (Vhourglass_delay
) > 0)
4264 secs
= XFASTINT (Vhourglass_delay
);
4265 else if (FLOATP (Vhourglass_delay
)
4266 && XFLOAT_DATA (Vhourglass_delay
) > 0)
4269 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
4270 secs
= XFASTINT (tem
);
4271 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
4274 secs
= DEFAULT_HOURGLASS_DELAY
;
4276 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
4277 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
4278 show_hourglass
, NULL
);
4282 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
4288 if (hourglass_atimer
)
4290 cancel_atimer (hourglass_atimer
);
4291 hourglass_atimer
= NULL
;
4294 if (hourglass_shown_p
)
4299 /* Timer function of hourglass_atimer. TIMER is equal to
4302 Display an hourglass pointer on all frames by mapping the frames'
4303 hourglass_window. Set the hourglass_p flag in the frames'
4304 output_data.x structure to indicate that an hourglass cursor is
4305 shown on the frames. */
4308 show_hourglass (timer
)
4309 struct atimer
*timer
;
4311 /* The timer implementation will cancel this timer automatically
4312 after this function has run. Set hourglass_atimer to null
4313 so that we know the timer doesn't have to be canceled. */
4314 hourglass_atimer
= NULL
;
4316 if (!hourglass_shown_p
)
4318 Lisp_Object rest
, frame
;
4322 FOR_EACH_FRAME (rest
, frame
)
4324 struct frame
*f
= XFRAME (frame
);
4326 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
) && FRAME_X_DISPLAY (f
))
4328 Display
*dpy
= FRAME_X_DISPLAY (f
);
4330 #ifdef USE_X_TOOLKIT
4331 if (f
->output_data
.x
->widget
)
4333 if (FRAME_OUTER_WINDOW (f
))
4336 f
->output_data
.x
->hourglass_p
= 1;
4338 if (!f
->output_data
.x
->hourglass_window
)
4340 unsigned long mask
= CWCursor
;
4341 XSetWindowAttributes attrs
;
4343 attrs
.cursor
= f
->output_data
.x
->hourglass_cursor
;
4345 f
->output_data
.x
->hourglass_window
4346 = XCreateWindow (dpy
, FRAME_OUTER_WINDOW (f
),
4347 0, 0, 32000, 32000, 0, 0,
4353 XMapRaised (dpy
, f
->output_data
.x
->hourglass_window
);
4359 hourglass_shown_p
= 1;
4365 /* Hide the hourglass pointer on all frames, if it is currently
4371 if (hourglass_shown_p
)
4373 Lisp_Object rest
, frame
;
4376 FOR_EACH_FRAME (rest
, frame
)
4378 struct frame
*f
= XFRAME (frame
);
4381 /* Watch out for newly created frames. */
4382 && f
->output_data
.x
->hourglass_window
)
4384 XUnmapWindow (FRAME_X_DISPLAY (f
),
4385 f
->output_data
.x
->hourglass_window
);
4386 /* Sync here because XTread_socket looks at the
4387 hourglass_p flag that is reset to zero below. */
4388 XSync (FRAME_X_DISPLAY (f
), False
);
4389 f
->output_data
.x
->hourglass_p
= 0;
4393 hourglass_shown_p
= 0;
4400 /***********************************************************************
4402 ***********************************************************************/
4404 static Lisp_Object x_create_tip_frame
P_ ((struct x_display_info
*,
4405 Lisp_Object
, Lisp_Object
));
4406 static void compute_tip_xy
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
4407 Lisp_Object
, int, int, int *, int *));
4409 /* The frame of a currently visible tooltip. */
4411 Lisp_Object tip_frame
;
4413 /* If non-nil, a timer started that hides the last tooltip when it
4416 Lisp_Object tip_timer
;
4419 /* If non-nil, a vector of 3 elements containing the last args
4420 with which x-show-tip was called. See there. */
4422 Lisp_Object last_show_tip_args
;
4424 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4426 Lisp_Object Vx_max_tooltip_size
;
4430 unwind_create_tip_frame (frame
)
4433 Lisp_Object deleted
;
4435 deleted
= unwind_create_frame (frame
);
4436 if (EQ (deleted
, Qt
))
4446 /* Create a frame for a tooltip on the display described by DPYINFO.
4447 PARMS is a list of frame parameters. TEXT is the string to
4448 display in the tip frame. Value is the frame.
4450 Note that functions called here, esp. x_default_parameter can
4451 signal errors, for instance when a specified color name is
4452 undefined. We have to make sure that we're in a consistent state
4453 when this happens. */
4456 x_create_tip_frame (dpyinfo
, parms
, text
)
4457 struct x_display_info
*dpyinfo
;
4458 Lisp_Object parms
, text
;
4461 Lisp_Object frame
, tem
;
4463 long window_prompting
= 0;
4465 int count
= SPECPDL_INDEX ();
4466 struct gcpro gcpro1
, gcpro2
, gcpro3
;
4468 int face_change_count_before
= face_change_count
;
4470 struct buffer
*old_buffer
;
4474 /* Use this general default value to start with until we know if
4475 this frame has a specified name. */
4476 Vx_resource_name
= Vinvocation_name
;
4479 kb
= dpyinfo
->kboard
;
4481 kb
= &the_only_kboard
;
4484 /* Get the name of the frame to use for resource lookup. */
4485 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
4487 && !EQ (name
, Qunbound
)
4489 error ("Invalid frame name--not a string or nil");
4490 Vx_resource_name
= name
;
4493 GCPRO3 (parms
, name
, frame
);
4495 XSETFRAME (frame
, f
);
4497 buffer
= Fget_buffer_create (build_string (" *tip*"));
4498 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
4499 old_buffer
= current_buffer
;
4500 set_buffer_internal_1 (XBUFFER (buffer
));
4501 current_buffer
->truncate_lines
= Qnil
;
4502 specbind (Qinhibit_read_only
, Qt
);
4503 specbind (Qinhibit_modification_hooks
, Qt
);
4506 set_buffer_internal_1 (old_buffer
);
4508 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
4509 record_unwind_protect (unwind_create_tip_frame
, frame
);
4511 /* By setting the output method, we're essentially saying that
4512 the frame is live, as per FRAME_LIVE_P. If we get a signal
4513 from this point on, x_destroy_window might screw up reference
4515 f
->output_method
= output_x_window
;
4516 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
4517 bzero (f
->output_data
.x
, sizeof (struct x_output
));
4518 f
->output_data
.x
->icon_bitmap
= -1;
4519 FRAME_FONTSET (f
) = -1;
4520 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
4521 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
4522 #ifdef USE_TOOLKIT_SCROLL_BARS
4523 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
4524 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
4525 #endif /* USE_TOOLKIT_SCROLL_BARS */
4526 f
->icon_name
= Qnil
;
4527 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
4529 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
4530 dpyinfo_refcount
= dpyinfo
->reference_count
;
4531 #endif /* GLYPH_DEBUG */
4533 FRAME_KBOARD (f
) = kb
;
4535 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4536 f
->output_data
.x
->explicit_parent
= 0;
4538 /* These colors will be set anyway later, but it's important
4539 to get the color reference counts right, so initialize them! */
4542 struct gcpro gcpro1
;
4544 black
= build_string ("black");
4546 f
->output_data
.x
->foreground_pixel
4547 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4548 f
->output_data
.x
->background_pixel
4549 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4550 f
->output_data
.x
->cursor_pixel
4551 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4552 f
->output_data
.x
->cursor_foreground_pixel
4553 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4554 f
->output_data
.x
->border_pixel
4555 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4556 f
->output_data
.x
->mouse_pixel
4557 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4561 /* Set the name; the functions to which we pass f expect the name to
4563 if (EQ (name
, Qunbound
) || NILP (name
))
4565 f
->name
= build_string (dpyinfo
->x_id_name
);
4566 f
->explicit_name
= 0;
4571 f
->explicit_name
= 1;
4572 /* use the frame's title when getting resources for this frame. */
4573 specbind (Qx_resource_name
, name
);
4576 /* Extract the window parameters from the supplied values that are
4577 needed to determine window geometry. */
4581 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
4584 /* First, try whatever font the caller has specified. */
4587 tem
= Fquery_fontset (font
, Qnil
);
4589 font
= x_new_fontset (f
, SDATA (tem
));
4591 font
= x_new_font (f
, SDATA (font
));
4594 /* Try out a font which we hope has bold and italic variations. */
4595 if (!STRINGP (font
))
4596 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
4597 if (!STRINGP (font
))
4598 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
4599 if (! STRINGP (font
))
4600 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
4601 if (! STRINGP (font
))
4602 /* This was formerly the first thing tried, but it finds too many fonts
4603 and takes too long. */
4604 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
4605 /* If those didn't work, look for something which will at least work. */
4606 if (! STRINGP (font
))
4607 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
4609 if (! STRINGP (font
))
4610 font
= build_string ("fixed");
4612 x_default_parameter (f
, parms
, Qfont
, font
,
4613 "font", "Font", RES_TYPE_STRING
);
4616 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
4617 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
4619 /* This defaults to 2 in order to match xterm. We recognize either
4620 internalBorderWidth or internalBorder (which is what xterm calls
4622 if (NILP (Fassq (Qinternal_border_width
, parms
)))
4626 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
4627 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
4628 if (! EQ (value
, Qunbound
))
4629 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
4633 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
4634 "internalBorderWidth", "internalBorderWidth",
4637 /* Also do the stuff which must be set before the window exists. */
4638 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
4639 "foreground", "Foreground", RES_TYPE_STRING
);
4640 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
4641 "background", "Background", RES_TYPE_STRING
);
4642 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
4643 "pointerColor", "Foreground", RES_TYPE_STRING
);
4644 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
4645 "cursorColor", "Foreground", RES_TYPE_STRING
);
4646 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
4647 "borderColor", "BorderColor", RES_TYPE_STRING
);
4649 /* Init faces before x_default_parameter is called for scroll-bar
4650 parameters because that function calls x_set_scroll_bar_width,
4651 which calls change_frame_size, which calls Fset_window_buffer,
4652 which runs hooks, which call Fvertical_motion. At the end, we
4653 end up in init_iterator with a null face cache, which should not
4655 init_frame_faces (f
);
4657 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4659 window_prompting
= x_figure_window_size (f
, parms
, 0);
4662 XSetWindowAttributes attrs
;
4666 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
4667 if (DoesSaveUnders (dpyinfo
->screen
))
4668 mask
|= CWSaveUnder
;
4670 /* Window managers look at the override-redirect flag to determine
4671 whether or net to give windows a decoration (Xlib spec, chapter
4673 attrs
.override_redirect
= True
;
4674 attrs
.save_under
= True
;
4675 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
4676 /* Arrange for getting MapNotify and UnmapNotify events. */
4677 attrs
.event_mask
= StructureNotifyMask
;
4679 = FRAME_X_WINDOW (f
)
4680 = XCreateWindow (FRAME_X_DISPLAY (f
),
4681 FRAME_X_DISPLAY_INFO (f
)->root_window
,
4682 /* x, y, width, height */
4686 CopyFromParent
, InputOutput
, CopyFromParent
,
4693 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
4694 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4695 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
4696 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4697 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
4698 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
4700 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4701 Change will not be effected unless different from the current
4703 width
= FRAME_COLS (f
);
4704 height
= FRAME_LINES (f
);
4705 SET_FRAME_COLS (f
, 0);
4706 FRAME_LINES (f
) = 0;
4707 change_frame_size (f
, height
, width
, 1, 0, 0);
4709 /* Add `tooltip' frame parameter's default value. */
4710 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
4711 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
4714 /* Set up faces after all frame parameters are known. This call
4715 also merges in face attributes specified for new frames.
4717 Frame parameters may be changed if .Xdefaults contains
4718 specifications for the default font. For example, if there is an
4719 `Emacs.default.attributeBackground: pink', the `background-color'
4720 attribute of the frame get's set, which let's the internal border
4721 of the tooltip frame appear in pink. Prevent this. */
4723 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
4725 /* Set tip_frame here, so that */
4727 call1 (Qface_set_after_frame_default
, frame
);
4729 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
4730 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qbackground_color
, bg
),
4738 /* It is now ok to make the frame official even if we get an error
4739 below. And the frame needs to be on Vframe_list or making it
4740 visible won't work. */
4741 Vframe_list
= Fcons (frame
, Vframe_list
);
4743 /* Now that the frame is official, it counts as a reference to
4745 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
4747 /* Setting attributes of faces of the tooltip frame from resources
4748 and similar will increment face_change_count, which leads to the
4749 clearing of all current matrices. Since this isn't necessary
4750 here, avoid it by resetting face_change_count to the value it
4751 had before we created the tip frame. */
4752 face_change_count
= face_change_count_before
;
4754 /* Discard the unwind_protect. */
4755 return unbind_to (count
, frame
);
4759 /* Compute where to display tip frame F. PARMS is the list of frame
4760 parameters for F. DX and DY are specified offsets from the current
4761 location of the mouse. WIDTH and HEIGHT are the width and height
4762 of the tooltip. Return coordinates relative to the root window of
4763 the display in *ROOT_X, and *ROOT_Y. */
4766 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, root_x
, root_y
)
4768 Lisp_Object parms
, dx
, dy
;
4770 int *root_x
, *root_y
;
4772 Lisp_Object left
, top
;
4777 /* User-specified position? */
4778 left
= Fcdr (Fassq (Qleft
, parms
));
4779 top
= Fcdr (Fassq (Qtop
, parms
));
4781 /* Move the tooltip window where the mouse pointer is. Resize and
4783 if (!INTEGERP (left
) || !INTEGERP (top
))
4786 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
4787 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
4792 *root_y
= XINT (top
);
4793 else if (*root_y
+ XINT (dy
) - height
< 0)
4794 *root_y
-= XINT (dy
);
4798 *root_y
+= XINT (dy
);
4801 if (INTEGERP (left
))
4802 *root_x
= XINT (left
);
4803 else if (*root_x
+ XINT (dx
) + width
<= FRAME_X_DISPLAY_INFO (f
)->width
)
4804 /* It fits to the right of the pointer. */
4805 *root_x
+= XINT (dx
);
4806 else if (width
+ XINT (dx
) <= *root_x
)
4807 /* It fits to the left of the pointer. */
4808 *root_x
-= width
+ XINT (dx
);
4810 /* Put it left-justified on the screen--it ought to fit that way. */
4815 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
4816 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
4817 A tooltip window is a small X window displaying a string.
4819 FRAME nil or omitted means use the selected frame.
4821 PARMS is an optional list of frame parameters which can be used to
4822 change the tooltip's appearance.
4824 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
4825 means use the default timeout of 5 seconds.
4827 If the list of frame parameters PARAMS contains a `left' parameters,
4828 the tooltip is displayed at that x-position. Otherwise it is
4829 displayed at the mouse position, with offset DX added (default is 5 if
4830 DX isn't specified). Likewise for the y-position; if a `top' frame
4831 parameter is specified, it determines the y-position of the tooltip
4832 window, otherwise it is displayed at the mouse position, with offset
4833 DY added (default is -10).
4835 A tooltip's maximum size is specified by `x-max-tooltip-size'.
4836 Text larger than the specified size is clipped. */)
4837 (string
, frame
, parms
, timeout
, dx
, dy
)
4838 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
4843 struct buffer
*old_buffer
;
4844 struct text_pos pos
;
4845 int i
, width
, height
;
4846 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
4847 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
4848 int count
= SPECPDL_INDEX ();
4850 specbind (Qinhibit_redisplay
, Qt
);
4852 GCPRO4 (string
, parms
, frame
, timeout
);
4854 CHECK_STRING (string
);
4855 f
= check_x_frame (frame
);
4857 timeout
= make_number (5);
4859 CHECK_NATNUM (timeout
);
4862 dx
= make_number (5);
4867 dy
= make_number (-10);
4871 if (NILP (last_show_tip_args
))
4872 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
4874 if (!NILP (tip_frame
))
4876 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
4877 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
4878 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
4880 if (EQ (frame
, last_frame
)
4881 && !NILP (Fequal (last_string
, string
))
4882 && !NILP (Fequal (last_parms
, parms
)))
4884 struct frame
*f
= XFRAME (tip_frame
);
4886 /* Only DX and DY have changed. */
4887 if (!NILP (tip_timer
))
4889 Lisp_Object timer
= tip_timer
;
4891 call1 (Qcancel_timer
, timer
);
4895 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
4896 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
4897 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4904 /* Hide a previous tip, if any. */
4907 ASET (last_show_tip_args
, 0, string
);
4908 ASET (last_show_tip_args
, 1, frame
);
4909 ASET (last_show_tip_args
, 2, parms
);
4911 /* Add default values to frame parameters. */
4912 if (NILP (Fassq (Qname
, parms
)))
4913 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
4914 if (NILP (Fassq (Qinternal_border_width
, parms
)))
4915 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
4916 if (NILP (Fassq (Qborder_width
, parms
)))
4917 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
4918 if (NILP (Fassq (Qborder_color
, parms
)))
4919 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
4920 if (NILP (Fassq (Qbackground_color
, parms
)))
4921 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
4924 /* Create a frame for the tooltip, and record it in the global
4925 variable tip_frame. */
4926 frame
= x_create_tip_frame (FRAME_X_DISPLAY_INFO (f
), parms
, string
);
4929 /* Set up the frame's root window. */
4930 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4931 w
->left_col
= w
->top_line
= make_number (0);
4933 if (CONSP (Vx_max_tooltip_size
)
4934 && INTEGERP (XCAR (Vx_max_tooltip_size
))
4935 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
4936 && INTEGERP (XCDR (Vx_max_tooltip_size
))
4937 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
4939 w
->total_cols
= XCAR (Vx_max_tooltip_size
);
4940 w
->total_lines
= XCDR (Vx_max_tooltip_size
);
4944 w
->total_cols
= make_number (80);
4945 w
->total_lines
= make_number (40);
4948 FRAME_TOTAL_COLS (f
) = XINT (w
->total_cols
);
4950 w
->pseudo_window_p
= 1;
4952 /* Display the tooltip text in a temporary buffer. */
4953 old_buffer
= current_buffer
;
4954 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->buffer
));
4955 current_buffer
->truncate_lines
= Qnil
;
4956 clear_glyph_matrix (w
->desired_matrix
);
4957 clear_glyph_matrix (w
->current_matrix
);
4958 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
4959 try_window (FRAME_ROOT_WINDOW (f
), pos
);
4961 /* Compute width and height of the tooltip. */
4963 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
4965 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
4969 /* Stop at the first empty row at the end. */
4970 if (!row
->enabled_p
|| !row
->displays_text_p
)
4973 /* Let the row go over the full width of the frame. */
4974 row
->full_width_p
= 1;
4976 /* There's a glyph at the end of rows that is used to place
4977 the cursor there. Don't include the width of this glyph. */
4978 if (row
->used
[TEXT_AREA
])
4980 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
4981 row_width
= row
->pixel_width
- last
->pixel_width
;
4984 row_width
= row
->pixel_width
;
4986 height
+= row
->height
;
4987 width
= max (width
, row_width
);
4990 /* Add the frame's internal border to the width and height the X
4991 window should have. */
4992 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
4993 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
4995 /* Move the tooltip window where the mouse pointer is. Resize and
4997 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5000 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5001 root_x
, root_y
, width
, height
);
5002 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5005 /* Draw into the window. */
5006 w
->must_be_updated_p
= 1;
5007 update_single_window (w
, 1);
5009 /* Restore original current buffer. */
5010 set_buffer_internal_1 (old_buffer
);
5011 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
5014 /* Let the tip disappear after timeout seconds. */
5015 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
5016 intern ("x-hide-tip"));
5019 return unbind_to (count
, Qnil
);
5023 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
5024 doc
: /* Hide the current tooltip window, if there is any.
5025 Value is t if tooltip was open, nil otherwise. */)
5029 Lisp_Object deleted
, frame
, timer
;
5030 struct gcpro gcpro1
, gcpro2
;
5032 /* Return quickly if nothing to do. */
5033 if (NILP (tip_timer
) && NILP (tip_frame
))
5038 GCPRO2 (frame
, timer
);
5039 tip_frame
= tip_timer
= deleted
= Qnil
;
5041 count
= SPECPDL_INDEX ();
5042 specbind (Qinhibit_redisplay
, Qt
);
5043 specbind (Qinhibit_quit
, Qt
);
5046 call1 (Qcancel_timer
, timer
);
5050 Fdelete_frame (frame
, Qnil
);
5054 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5055 redisplay procedure is not called when a tip frame over menu
5056 items is unmapped. Redisplay the menu manually... */
5058 struct frame
*f
= SELECTED_FRAME ();
5059 Widget w
= f
->output_data
.x
->menubar_widget
;
5060 extern void xlwmenu_redisplay
P_ ((Widget
));
5062 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f
)->screen
)
5066 xlwmenu_redisplay (w
);
5070 #endif /* USE_LUCID */
5074 return unbind_to (count
, deleted
);
5079 /***********************************************************************
5080 File selection dialog
5081 ***********************************************************************/
5085 /* Callback for "OK" and "Cancel" on file selection dialog. */
5088 file_dialog_cb (widget
, client_data
, call_data
)
5090 XtPointer call_data
, client_data
;
5092 int *result
= (int *) client_data
;
5093 XmAnyCallbackStruct
*cb
= (XmAnyCallbackStruct
*) call_data
;
5094 *result
= cb
->reason
;
5098 /* Callback for unmapping a file selection dialog. This is used to
5099 capture the case where a dialog is closed via a window manager's
5100 closer button, for example. Using a XmNdestroyCallback didn't work
5104 file_dialog_unmap_cb (widget
, client_data
, call_data
)
5106 XtPointer call_data
, client_data
;
5108 int *result
= (int *) client_data
;
5109 *result
= XmCR_CANCEL
;
5113 clean_up_file_dialog (arg
)
5116 struct Lisp_Save_Value
*p
= XSAVE_VALUE (arg
);
5117 Widget dialog
= (Widget
) p
->pointer
;
5121 XtUnmanageChild (dialog
);
5122 XtDestroyWidget (dialog
);
5123 x_menu_set_in_use (0);
5130 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5131 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5132 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5133 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5134 or directory must exist. ONLY-DIR-P is ignored." */)
5135 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
)
5136 Lisp_Object prompt
, dir
, default_filename
, mustmatch
, only_dir_p
;
5139 struct frame
*f
= SELECTED_FRAME ();
5140 Lisp_Object file
= Qnil
;
5141 Widget dialog
, text
, help
;
5144 extern XtAppContext Xt_app_con
;
5145 XmString dir_xmstring
, pattern_xmstring
;
5146 int count
= SPECPDL_INDEX ();
5147 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
5149 GCPRO6 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
, file
);
5151 if (popup_activated ())
5152 error ("Trying to use a menu from within a menu-entry");
5154 CHECK_STRING (prompt
);
5157 /* Prevent redisplay. */
5158 specbind (Qinhibit_redisplay
, Qt
);
5162 /* Create the dialog with PROMPT as title, using DIR as initial
5163 directory and using "*" as pattern. */
5164 dir
= Fexpand_file_name (dir
, Qnil
);
5165 dir_xmstring
= XmStringCreateLocalized (SDATA (dir
));
5166 pattern_xmstring
= XmStringCreateLocalized ("*");
5168 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
5169 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
5170 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
5171 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
5172 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
5173 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
5175 XmStringFree (dir_xmstring
);
5176 XmStringFree (pattern_xmstring
);
5178 /* Add callbacks for OK and Cancel. */
5179 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
5180 (XtPointer
) &result
);
5181 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
5182 (XtPointer
) &result
);
5183 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
5184 (XtPointer
) &result
);
5186 /* Remove the help button since we can't display help. */
5187 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
5188 XtUnmanageChild (help
);
5190 /* Mark OK button as default. */
5191 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
5192 XmNshowAsDefault
, True
, NULL
);
5194 /* If MUSTMATCH is non-nil, disable the file entry field of the
5195 dialog, so that the user must select a file from the files list
5196 box. We can't remove it because we wouldn't have a way to get at
5197 the result file name, then. */
5198 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
5199 if (!NILP (mustmatch
))
5202 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
5203 XtSetSensitive (text
, False
);
5204 XtSetSensitive (label
, False
);
5207 /* Manage the dialog, so that list boxes get filled. */
5208 XtManageChild (dialog
);
5210 if (STRINGP (default_filename
))
5212 XmString default_xmstring
;
5213 Widget wtext
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
5214 Widget list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
5216 XmTextPosition last_pos
= XmTextFieldGetLastPosition (wtext
);
5217 XmTextFieldReplace (wtext
, 0, last_pos
,
5218 (SDATA (Ffile_name_nondirectory (default_filename
))));
5220 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5221 must include the path for this to work. */
5223 default_xmstring
= XmStringCreateLocalized (SDATA (default_filename
));
5225 if (XmListItemExists (list
, default_xmstring
))
5227 int item_pos
= XmListItemPos (list
, default_xmstring
);
5228 /* Select the item and scroll it into view. */
5229 XmListSelectPos (list
, item_pos
, True
);
5230 XmListSetPos (list
, item_pos
);
5233 XmStringFree (default_xmstring
);
5236 record_unwind_protect (clean_up_file_dialog
, make_save_value (dialog
, 0));
5238 /* Process events until the user presses Cancel or OK. */
5239 x_menu_set_in_use (1);
5244 x_menu_wait_for_event (0);
5245 XtAppNextEvent (Xt_app_con
, &event
);
5246 if (event
.type
== KeyPress
5247 && FRAME_X_DISPLAY (f
) == event
.xkey
.display
)
5249 KeySym keysym
= XLookupKeysym (&event
.xkey
, 0);
5251 /* Pop down on C-g. */
5252 if (keysym
== XK_g
&& (event
.xkey
.state
& ControlMask
) != 0)
5253 XtUnmanageChild (dialog
);
5256 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
));
5259 /* Get the result. */
5260 if (result
== XmCR_OK
)
5265 XtVaGetValues (dialog
, XmNtextString
, &text
, NULL
);
5266 XmStringGetLtoR (text
, XmFONTLIST_DEFAULT_TAG
, &data
);
5267 XmStringFree (text
);
5268 file
= build_string (data
);
5277 /* Make "Cancel" equivalent to C-g. */
5279 Fsignal (Qquit
, Qnil
);
5281 return unbind_to (count
, file
);
5284 #endif /* USE_MOTIF */
5289 clean_up_dialog (arg
)
5292 x_menu_set_in_use (0);
5297 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5298 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5299 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5300 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5301 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5303 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
)
5304 Lisp_Object prompt
, dir
, default_filename
, mustmatch
, only_dir_p
;
5306 FRAME_PTR f
= SELECTED_FRAME ();
5308 Lisp_Object file
= Qnil
;
5309 int count
= SPECPDL_INDEX ();
5310 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
5313 GCPRO6 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
, file
);
5315 if (popup_activated ())
5316 error ("Trying to use a menu from within a menu-entry");
5318 CHECK_STRING (prompt
);
5321 /* Prevent redisplay. */
5322 specbind (Qinhibit_redisplay
, Qt
);
5323 record_unwind_protect (clean_up_dialog
, Qnil
);
5327 if (STRINGP (default_filename
))
5328 cdef_file
= SDATA (default_filename
);
5330 cdef_file
= SDATA (dir
);
5332 fn
= xg_get_file_name (f
, SDATA (prompt
), cdef_file
,
5334 ! NILP (only_dir_p
));
5338 file
= build_string (fn
);
5345 /* Make "Cancel" equivalent to C-g. */
5347 Fsignal (Qquit
, Qnil
);
5349 return unbind_to (count
, file
);
5352 #endif /* USE_GTK */
5355 /***********************************************************************
5357 ***********************************************************************/
5359 #ifdef HAVE_XKBGETKEYBOARD
5360 #include <X11/XKBlib.h>
5361 #include <X11/keysym.h>
5364 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
5365 Sx_backspace_delete_keys_p
, 0, 1, 0,
5366 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5367 FRAME nil means use the selected frame.
5368 Value is t if we know that both keys are present, and are mapped to the
5369 usual X keysyms. */)
5373 #ifdef HAVE_XKBGETKEYBOARD
5375 struct frame
*f
= check_x_frame (frame
);
5376 Display
*dpy
= FRAME_X_DISPLAY (f
);
5377 Lisp_Object have_keys
;
5378 int major
, minor
, op
, event
, error
;
5382 /* Check library version in case we're dynamically linked. */
5383 major
= XkbMajorVersion
;
5384 minor
= XkbMinorVersion
;
5385 if (!XkbLibraryVersion (&major
, &minor
))
5391 /* Check that the server supports XKB. */
5392 major
= XkbMajorVersion
;
5393 minor
= XkbMinorVersion
;
5394 if (!XkbQueryExtension (dpy
, &op
, &event
, &error
, &major
, &minor
))
5401 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
5404 int delete_keycode
= 0, backspace_keycode
= 0, i
;
5406 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
5408 for (i
= kb
->min_key_code
;
5409 (i
< kb
->max_key_code
5410 && (delete_keycode
== 0 || backspace_keycode
== 0));
5413 /* The XKB symbolic key names can be seen most easily in
5414 the PS file generated by `xkbprint -label name
5416 if (bcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
5418 else if (bcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
5419 backspace_keycode
= i
;
5422 XkbFreeNames (kb
, 0, True
);
5425 XkbFreeClientMap (kb
, 0, True
);
5428 && backspace_keycode
5429 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
5430 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
5435 #else /* not HAVE_XKBGETKEYBOARD */
5437 #endif /* not HAVE_XKBGETKEYBOARD */
5442 /***********************************************************************
5444 ***********************************************************************/
5446 /* Keep this list in the same order as frame_parms in frame.c.
5447 Use 0 for unsupported frame parameters. */
5449 frame_parm_handler x_frame_parm_handlers
[] =
5453 x_set_background_color
,
5459 x_set_foreground_color
,
5462 x_set_internal_border_width
,
5463 x_set_menu_bar_lines
,
5465 x_explicitly_set_name
,
5466 x_set_scroll_bar_width
,
5469 x_set_vertical_scroll_bars
,
5471 x_set_tool_bar_lines
,
5472 x_set_scroll_bar_foreground
,
5473 x_set_scroll_bar_background
,
5485 /* This is zero if not using X windows. */
5488 /* The section below is built by the lisp expression at the top of the file,
5489 just above where these variables are declared. */
5490 /*&&& init symbols here &&&*/
5491 Qnone
= intern ("none");
5493 Qsuppress_icon
= intern ("suppress-icon");
5494 staticpro (&Qsuppress_icon
);
5495 Qundefined_color
= intern ("undefined-color");
5496 staticpro (&Qundefined_color
);
5497 Qcompound_text
= intern ("compound-text");
5498 staticpro (&Qcompound_text
);
5499 Qcancel_timer
= intern ("cancel-timer");
5500 staticpro (&Qcancel_timer
);
5501 /* This is the end of symbol initialization. */
5503 /* Text property `display' should be nonsticky by default. */
5504 Vtext_property_default_nonsticky
5505 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
5508 Fput (Qundefined_color
, Qerror_conditions
,
5509 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
5510 Fput (Qundefined_color
, Qerror_message
,
5511 build_string ("Undefined color"));
5513 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
5514 doc
: /* The shape of the pointer when over text.
5515 Changing the value does not affect existing frames
5516 unless you set the mouse color. */);
5517 Vx_pointer_shape
= Qnil
;
5519 #if 0 /* This doesn't really do anything. */
5520 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
5521 doc
: /* The shape of the pointer when not over text.
5522 This variable takes effect when you create a new frame
5523 or when you set the mouse color. */);
5525 Vx_nontext_pointer_shape
= Qnil
;
5527 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
5528 doc
: /* The shape of the pointer when Emacs is busy.
5529 This variable takes effect when you create a new frame
5530 or when you set the mouse color. */);
5531 Vx_hourglass_pointer_shape
= Qnil
;
5533 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
5534 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
5535 display_hourglass_p
= 1;
5537 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
5538 doc
: /* *Seconds to wait before displaying an hourglass pointer.
5539 Value must be an integer or float. */);
5540 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
5542 #if 0 /* This doesn't really do anything. */
5543 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
5544 doc
: /* The shape of the pointer when over the mode line.
5545 This variable takes effect when you create a new frame
5546 or when you set the mouse color. */);
5548 Vx_mode_pointer_shape
= Qnil
;
5550 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5551 &Vx_sensitive_text_pointer_shape
,
5552 doc
: /* The shape of the pointer when over mouse-sensitive text.
5553 This variable takes effect when you create a new frame
5554 or when you set the mouse color. */);
5555 Vx_sensitive_text_pointer_shape
= Qnil
;
5557 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5558 &Vx_window_horizontal_drag_shape
,
5559 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
5560 This variable takes effect when you create a new frame
5561 or when you set the mouse color. */);
5562 Vx_window_horizontal_drag_shape
= Qnil
;
5564 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
5565 doc
: /* A string indicating the foreground color of the cursor box. */);
5566 Vx_cursor_fore_pixel
= Qnil
;
5568 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size
,
5569 doc
: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
5570 Text larger than this is clipped. */);
5571 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
5573 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
5574 doc
: /* Non-nil if no X window manager is in use.
5575 Emacs doesn't try to figure this out; this is always nil
5576 unless you set it to something else. */);
5577 /* We don't have any way to find this out, so set it to nil
5578 and maybe the user would like to set it to t. */
5579 Vx_no_window_manager
= Qnil
;
5581 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5582 &Vx_pixel_size_width_font_regexp
,
5583 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5585 Since Emacs gets width of a font matching with this regexp from
5586 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5587 such a font. This is especially effective for such large fonts as
5588 Chinese, Japanese, and Korean. */);
5589 Vx_pixel_size_width_font_regexp
= Qnil
;
5591 /* This is not ifdef:ed, so other builds than GTK can customize it. */
5592 DEFVAR_BOOL ("x-use-old-gtk-file-dialog", &x_use_old_gtk_file_dialog
,
5593 doc
: /* *Non-nil means prompt with the old GTK file selection dialog.
5594 If nil or if the file selection dialog is not available, the new GTK file
5595 chooser is used instead. To turn off all file dialogs set the
5596 variable `use-file-dialog'. */);
5597 x_use_old_gtk_file_dialog
= 0;
5599 #ifdef USE_X_TOOLKIT
5600 Fprovide (intern ("x-toolkit"), Qnil
);
5602 Fprovide (intern ("motif"), Qnil
);
5604 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
,
5605 doc
: /* Version info for LessTif/Motif. */);
5606 Vmotif_version_string
= build_string (XmVERSION_STRING
);
5607 #endif /* USE_MOTIF */
5608 #endif /* USE_X_TOOLKIT */
5611 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
5612 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
5613 But for a user it is a toolkit for X, and indeed, configure
5614 accepts --with-x-toolkit=gtk. */
5615 Fprovide (intern ("x-toolkit"), Qnil
);
5616 Fprovide (intern ("gtk"), Qnil
);
5618 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string
,
5619 doc
: /* Version info for GTK+. */);
5621 char gtk_version
[40];
5622 g_snprintf (gtk_version
, sizeof (gtk_version
), "%u.%u.%u",
5623 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
5624 Vgtk_version_string
= build_string (gtk_version
);
5626 #endif /* USE_GTK */
5628 /* X window properties. */
5629 defsubr (&Sx_change_window_property
);
5630 defsubr (&Sx_delete_window_property
);
5631 defsubr (&Sx_window_property
);
5633 defsubr (&Sxw_display_color_p
);
5634 defsubr (&Sx_display_grayscale_p
);
5635 defsubr (&Sxw_color_defined_p
);
5636 defsubr (&Sxw_color_values
);
5637 defsubr (&Sx_server_max_request_size
);
5638 defsubr (&Sx_server_vendor
);
5639 defsubr (&Sx_server_version
);
5640 defsubr (&Sx_display_pixel_width
);
5641 defsubr (&Sx_display_pixel_height
);
5642 defsubr (&Sx_display_mm_width
);
5643 defsubr (&Sx_display_mm_height
);
5644 defsubr (&Sx_display_screens
);
5645 defsubr (&Sx_display_planes
);
5646 defsubr (&Sx_display_color_cells
);
5647 defsubr (&Sx_display_visual_class
);
5648 defsubr (&Sx_display_backing_store
);
5649 defsubr (&Sx_display_save_under
);
5650 defsubr (&Sx_create_frame
);
5651 defsubr (&Sx_open_connection
);
5652 defsubr (&Sx_close_connection
);
5653 defsubr (&Sx_display_list
);
5654 defsubr (&Sx_synchronize
);
5655 defsubr (&Sx_focus_frame
);
5656 defsubr (&Sx_backspace_delete_keys_p
);
5658 /* Setting callback functions for fontset handler. */
5659 get_font_info_func
= x_get_font_info
;
5661 #if 0 /* This function pointer doesn't seem to be used anywhere.
5662 And the pointer assigned has the wrong type, anyway. */
5663 list_fonts_func
= x_list_fonts
;
5666 load_font_func
= x_load_font
;
5667 find_ccl_program_func
= x_find_ccl_program
;
5668 query_font_func
= x_query_font
;
5669 set_frame_fontset_func
= x_set_font
;
5670 check_window_system_func
= check_x
;
5672 hourglass_atimer
= NULL
;
5673 hourglass_shown_p
= 0;
5675 defsubr (&Sx_show_tip
);
5676 defsubr (&Sx_hide_tip
);
5678 staticpro (&tip_timer
);
5680 staticpro (&tip_frame
);
5682 last_show_tip_args
= Qnil
;
5683 staticpro (&last_show_tip_args
);
5685 #if defined (USE_MOTIF) || defined (USE_GTK)
5686 defsubr (&Sx_file_dialog
);
5690 #endif /* HAVE_X_WINDOWS */
5692 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
5693 (do not change this comment) */