1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005 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
);
1401 /* height can be zero here. */
1402 if (height
> 0 && width
> 0)
1405 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1406 0, y
, width
, height
, False
);
1410 if (WINDOWP (f
->tool_bar_window
))
1411 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1416 /* Set the foreground color for scroll bars on frame F to VALUE.
1417 VALUE should be a string, a color name. If it isn't a string or
1418 isn't a valid color name, do nothing. OLDVAL is the old value of
1419 the frame parameter. */
1422 x_set_scroll_bar_foreground (f
, value
, oldval
)
1424 Lisp_Object value
, oldval
;
1426 unsigned long pixel
;
1428 if (STRINGP (value
))
1429 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1433 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1434 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1436 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1437 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1439 /* Remove all scroll bars because they have wrong colors. */
1440 if (condemn_scroll_bars_hook
)
1441 (*condemn_scroll_bars_hook
) (f
);
1442 if (judge_scroll_bars_hook
)
1443 (*judge_scroll_bars_hook
) (f
);
1445 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1451 /* Set the background color for scroll bars on frame F to VALUE VALUE
1452 should be a string, a color name. If it isn't a string or isn't a
1453 valid color name, do nothing. OLDVAL is the old value of the frame
1457 x_set_scroll_bar_background (f
, value
, oldval
)
1459 Lisp_Object value
, oldval
;
1461 unsigned long pixel
;
1463 if (STRINGP (value
))
1464 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1468 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1469 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1471 #ifdef USE_TOOLKIT_SCROLL_BARS
1472 /* Scrollbar shadow colors. */
1473 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1475 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1476 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1478 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1480 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1481 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1483 #endif /* USE_TOOLKIT_SCROLL_BARS */
1485 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1486 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1488 /* Remove all scroll bars because they have wrong colors. */
1489 if (condemn_scroll_bars_hook
)
1490 (*condemn_scroll_bars_hook
) (f
);
1491 if (judge_scroll_bars_hook
)
1492 (*judge_scroll_bars_hook
) (f
);
1494 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1500 /* Encode Lisp string STRING as a text in a format appropriate for
1501 XICCC (X Inter Client Communication Conventions).
1503 If STRING contains only ASCII characters, do no conversion and
1504 return the string data of STRING. Otherwise, encode the text by
1505 CODING_SYSTEM, and return a newly allocated memory area which
1506 should be freed by `xfree' by a caller.
1508 SELECTIONP non-zero means the string is being encoded for an X
1509 selection, so it is safe to run pre-write conversions (which
1512 Store the byte length of resulting text in *TEXT_BYTES.
1514 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1515 which means that the `encoding' of the result can be `STRING'.
1516 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1517 the result should be `COMPOUND_TEXT'. */
1520 x_encode_text (string
, coding_system
, selectionp
, text_bytes
, stringp
)
1521 Lisp_Object string
, coding_system
;
1522 int *text_bytes
, *stringp
;
1525 unsigned char *str
= SDATA (string
);
1526 int chars
= SCHARS (string
);
1527 int bytes
= SBYTES (string
);
1531 struct coding_system coding
;
1532 extern Lisp_Object Qcompound_text_with_extensions
;
1534 charset_info
= find_charset_in_text (str
, chars
, bytes
, NULL
, Qnil
);
1535 if (charset_info
== 0)
1537 /* No multibyte character in OBJ. We need not encode it. */
1538 *text_bytes
= bytes
;
1543 setup_coding_system (coding_system
, &coding
);
1545 && SYMBOLP (coding
.pre_write_conversion
)
1546 && !NILP (Ffboundp (coding
.pre_write_conversion
)))
1548 string
= run_pre_post_conversion_on_str (string
, &coding
, 1);
1549 str
= SDATA (string
);
1550 chars
= SCHARS (string
);
1551 bytes
= SBYTES (string
);
1553 coding
.src_multibyte
= 1;
1554 coding
.dst_multibyte
= 0;
1555 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1556 if (coding
.type
== coding_type_iso2022
)
1557 coding
.flags
|= CODING_FLAG_ISO_SAFE
;
1558 /* We suppress producing escape sequences for composition. */
1559 coding
.composing
= COMPOSITION_DISABLED
;
1560 bufsize
= encoding_buffer_size (&coding
, bytes
);
1561 buf
= (unsigned char *) xmalloc (bufsize
);
1562 encode_coding (&coding
, str
, buf
, bytes
, bufsize
);
1563 *text_bytes
= coding
.produced
;
1564 *stringp
= (charset_info
== 1
1565 || (!EQ (coding_system
, Qcompound_text
)
1566 && !EQ (coding_system
, Qcompound_text_with_extensions
)));
1571 /* Set the WM name to NAME for frame F. Also set the icon name.
1572 If the frame already has an icon name, use that, otherwise set the
1573 icon name to NAME. */
1576 x_set_name_internal (f
, name
)
1580 if (FRAME_X_WINDOW (f
))
1585 XTextProperty text
, icon
;
1587 int do_free_icon_value
= 0, do_free_text_value
= 0;
1588 Lisp_Object coding_system
;
1590 coding_system
= Qcompound_text
;
1591 /* Note: Encoding strategy
1593 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1594 text.encoding. But, there are non-internationalized window
1595 managers which don't support that encoding. So, if NAME
1596 contains only ASCII and 8859-1 characters, encode it by
1597 iso-latin-1, and use "STRING" in text.encoding hoping that
1598 such window managers at least analyze this format correctly,
1599 i.e. treat 8-bit bytes as 8859-1 characters.
1601 We may also be able to use "UTF8_STRING" in text.encoding
1602 in the future which can encode all Unicode characters.
1603 But, for the moment, there's no way to know that the
1604 current window manager supports it or not. */
1605 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
1606 text
.encoding
= (stringp
? XA_STRING
1607 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1609 text
.nitems
= bytes
;
1611 /* Check early, because ENCODE_UTF_8 below may GC and name may be
1613 do_free_text_value
= text
.value
!= SDATA (name
);
1615 if (NILP (f
->icon_name
))
1621 /* See the above comment "Note: Encoding strategy". */
1622 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
1624 icon
.encoding
= (stringp
? XA_STRING
1625 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1627 icon
.nitems
= bytes
;
1628 do_free_icon_value
= icon
.value
!= SDATA (f
->icon_name
);
1632 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1633 SDATA (ENCODE_UTF_8 (name
)));
1634 #else /* not USE_GTK */
1635 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1636 #endif /* not USE_GTK */
1638 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1640 if (do_free_icon_value
)
1642 if (do_free_text_value
)
1645 #else /* not HAVE_X11R4 */
1646 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1648 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1650 #endif /* not HAVE_X11R4 */
1655 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1658 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1659 name; if NAME is a string, set F's name to NAME and set
1660 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1662 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1663 suggesting a new name, which lisp code should override; if
1664 F->explicit_name is set, ignore the new name; otherwise, set it. */
1667 x_set_name (f
, name
, explicit)
1672 /* Make sure that requests from lisp code override requests from
1673 Emacs redisplay code. */
1676 /* If we're switching from explicit to implicit, we had better
1677 update the mode lines and thereby update the title. */
1678 if (f
->explicit_name
&& NILP (name
))
1679 update_mode_lines
= 1;
1681 f
->explicit_name
= ! NILP (name
);
1683 else if (f
->explicit_name
)
1686 /* If NAME is nil, set the name to the x_id_name. */
1689 /* Check for no change needed in this very common case
1690 before we do any consing. */
1691 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1694 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1697 CHECK_STRING (name
);
1699 /* Don't change the name if it's already NAME. */
1700 if (! NILP (Fstring_equal (name
, f
->name
)))
1705 /* For setting the frame title, the title parameter should override
1706 the name parameter. */
1707 if (! NILP (f
->title
))
1710 x_set_name_internal (f
, name
);
1713 /* This function should be called when the user's lisp code has
1714 specified a name for the frame; the name will override any set by the
1717 x_explicitly_set_name (f
, arg
, oldval
)
1719 Lisp_Object arg
, oldval
;
1721 x_set_name (f
, arg
, 1);
1724 /* This function should be called by Emacs redisplay code to set the
1725 name; names set this way will never override names set by the user's
1728 x_implicitly_set_name (f
, arg
, oldval
)
1730 Lisp_Object arg
, oldval
;
1732 x_set_name (f
, arg
, 0);
1735 /* Change the title of frame F to NAME.
1736 If NAME is nil, use the frame name as the title.
1738 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1739 name; if NAME is a string, set F's name to NAME and set
1740 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1742 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1743 suggesting a new name, which lisp code should override; if
1744 F->explicit_name is set, ignore the new name; otherwise, set it. */
1747 x_set_title (f
, name
, old_name
)
1749 Lisp_Object name
, old_name
;
1751 /* Don't change the title if it's already NAME. */
1752 if (EQ (name
, f
->title
))
1755 update_mode_lines
= 1;
1762 CHECK_STRING (name
);
1764 x_set_name_internal (f
, name
);
1768 x_set_scroll_bar_default_width (f
)
1771 int wid
= FRAME_COLUMN_WIDTH (f
);
1773 #ifdef USE_TOOLKIT_SCROLL_BARS
1774 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1775 int width
= 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
1776 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (width
+ wid
- 1) / wid
;
1777 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = width
;
1779 /* Make the actual width at least 14 pixels and a multiple of a
1781 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
1783 /* Use all of that space (aside from required margins) for the
1785 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = 0;
1790 /* Record in frame F the specified or default value according to ALIST
1791 of the parameter named PROP (a Lisp symbol). If no value is
1792 specified for PROP, look for an X default for XPROP on the frame
1793 named NAME. If that is not found either, use the value DEFLT. */
1796 x_default_scroll_bar_color_parameter (f
, alist
, prop
, xprop
, xclass
,
1805 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
1808 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
1809 if (EQ (tem
, Qunbound
))
1811 #ifdef USE_TOOLKIT_SCROLL_BARS
1813 /* See if an X resource for the scroll bar color has been
1815 tem
= display_x_get_resource (dpyinfo
,
1816 build_string (foreground_p
1820 build_string ("verticalScrollBar"),
1824 /* If nothing has been specified, scroll bars will use a
1825 toolkit-dependent default. Because these defaults are
1826 difficult to get at without actually creating a scroll
1827 bar, use nil to indicate that no color has been
1832 #else /* not USE_TOOLKIT_SCROLL_BARS */
1836 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1839 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
1845 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
1848 XSetWMProtocols (dpy
, w
, protocols
, count
)
1855 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
1856 if (prop
== None
) return False
;
1857 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
1858 (unsigned char *) protocols
, count
);
1861 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
1863 #ifdef USE_X_TOOLKIT
1865 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1866 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1867 already be present because of the toolkit (Motif adds some of them,
1868 for example, but Xt doesn't). */
1871 hack_wm_protocols (f
, widget
)
1875 Display
*dpy
= XtDisplay (widget
);
1876 Window w
= XtWindow (widget
);
1877 int need_delete
= 1;
1884 unsigned char *catoms
;
1886 unsigned long nitems
= 0;
1887 unsigned long bytes_after
;
1889 if ((XGetWindowProperty (dpy
, w
,
1890 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1891 (long)0, (long)100, False
, XA_ATOM
,
1892 &type
, &format
, &nitems
, &bytes_after
,
1895 && format
== 32 && type
== XA_ATOM
)
1897 Atom
*atoms
= (Atom
*) catoms
;
1902 == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
1904 else if (atoms
[nitems
]
1905 == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
1907 else if (atoms
[nitems
]
1908 == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
1919 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
1921 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
1923 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
1925 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1926 XA_ATOM
, 32, PropModeAppend
,
1927 (unsigned char *) props
, count
);
1935 /* Support routines for XIC (X Input Context). */
1939 static XFontSet xic_create_xfontset
P_ ((struct frame
*, char *));
1940 static XIMStyle best_xim_style
P_ ((XIMStyles
*, XIMStyles
*));
1943 /* Supported XIM styles, ordered by preference. */
1945 static XIMStyle supported_xim_styles
[] =
1947 XIMPreeditPosition
| XIMStatusArea
,
1948 XIMPreeditPosition
| XIMStatusNothing
,
1949 XIMPreeditPosition
| XIMStatusNone
,
1950 XIMPreeditNothing
| XIMStatusArea
,
1951 XIMPreeditNothing
| XIMStatusNothing
,
1952 XIMPreeditNothing
| XIMStatusNone
,
1953 XIMPreeditNone
| XIMStatusArea
,
1954 XIMPreeditNone
| XIMStatusNothing
,
1955 XIMPreeditNone
| XIMStatusNone
,
1960 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1963 xic_create_xfontset (f
, base_fontname
)
1965 char *base_fontname
;
1967 XFontSet xfs
= NULL
;
1968 char **missing_list
= NULL
;
1971 Lisp_Object rest
, frame
;
1973 /* See if there is another frame already using same fontset. */
1974 FOR_EACH_FRAME (rest
, frame
)
1976 struct frame
*cf
= XFRAME (frame
);
1977 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
1978 && FRAME_X_DISPLAY_INFO (cf
) == FRAME_X_DISPLAY_INFO (f
)
1979 && FRAME_XIC_BASE_FONTNAME (cf
)
1980 && !strcmp (FRAME_XIC_BASE_FONTNAME (cf
), base_fontname
))
1982 xfs
= FRAME_XIC_FONTSET (cf
);
1990 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
),
1991 base_fontname
, &missing_list
,
1992 &missing_count
, &def_string
);
1994 XFreeStringList (missing_list
);
1997 if (FRAME_XIC_BASE_FONTNAME (f
))
1998 xfree (FRAME_XIC_BASE_FONTNAME (f
));
1999 FRAME_XIC_BASE_FONTNAME (f
) = xstrdup (base_fontname
);
2001 /* No need to free def_string. */
2005 /* Free the X fontset of frame F if it is the last frame using it. */
2008 xic_free_xfontset (f
)
2011 Lisp_Object rest
, frame
;
2014 if (!FRAME_XIC_FONTSET (f
))
2017 /* See if there is another frame sharing the same fontset. */
2018 FOR_EACH_FRAME (rest
, frame
)
2020 struct frame
*cf
= XFRAME (frame
);
2021 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2022 && FRAME_X_DISPLAY_INFO (cf
) == FRAME_X_DISPLAY_INFO (f
)
2023 && FRAME_XIC_FONTSET (cf
) == FRAME_XIC_FONTSET (f
))
2031 /* The fontset is not used anymore. It is safe to free it. */
2032 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2034 if (FRAME_XIC_BASE_FONTNAME (f
))
2035 xfree (FRAME_XIC_BASE_FONTNAME (f
));
2036 FRAME_XIC_BASE_FONTNAME (f
) = NULL
;
2037 FRAME_XIC_FONTSET (f
) = NULL
;
2041 /* Value is the best input style, given user preferences USER (already
2042 checked to be supported by Emacs), and styles supported by the
2043 input method XIM. */
2046 best_xim_style (user
, xim
)
2052 for (i
= 0; i
< user
->count_styles
; ++i
)
2053 for (j
= 0; j
< xim
->count_styles
; ++j
)
2054 if (user
->supported_styles
[i
] == xim
->supported_styles
[j
])
2055 return user
->supported_styles
[i
];
2057 /* Return the default style. */
2058 return XIMPreeditNothing
| XIMStatusNothing
;
2061 /* Create XIC for frame F. */
2063 static XIMStyle xic_style
;
2066 create_frame_xic (f
)
2071 XFontSet xfs
= NULL
;
2076 xim
= FRAME_X_XIM (f
);
2081 XVaNestedList preedit_attr
;
2082 XVaNestedList status_attr
;
2083 char *base_fontname
;
2086 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2087 spot
.x
= 0; spot
.y
= 1;
2088 /* Create X fontset. */
2089 fontset
= FRAME_FONTSET (f
);
2091 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2094 /* Determine the base fontname from the ASCII font name of
2096 char *ascii_font
= (char *) SDATA (fontset_ascii (fontset
));
2097 char *p
= ascii_font
;
2100 for (i
= 0; *p
; p
++)
2103 /* As the font name doesn't conform to XLFD, we can't
2104 modify it to get a suitable base fontname for the
2106 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2109 int len
= strlen (ascii_font
) + 1;
2112 for (i
= 0, p
= ascii_font
; i
< 8; p
++)
2121 base_fontname
= (char *) alloca (len
);
2122 bzero (base_fontname
, len
);
2123 strcpy (base_fontname
, "-*-*-");
2124 bcopy (p1
, base_fontname
+ 5, p
- p1
);
2125 strcat (base_fontname
, "*-*-*-*-*-*-*");
2128 xfs
= xic_create_xfontset (f
, base_fontname
);
2130 /* Determine XIC style. */
2133 XIMStyles supported_list
;
2134 supported_list
.count_styles
= (sizeof supported_xim_styles
2135 / sizeof supported_xim_styles
[0]);
2136 supported_list
.supported_styles
= supported_xim_styles
;
2137 xic_style
= best_xim_style (&supported_list
,
2138 FRAME_X_XIM_STYLES (f
));
2141 preedit_attr
= XVaCreateNestedList (0,
2144 FRAME_FOREGROUND_PIXEL (f
),
2146 FRAME_BACKGROUND_PIXEL (f
),
2147 (xic_style
& XIMPreeditPosition
2152 status_attr
= XVaCreateNestedList (0,
2158 FRAME_FOREGROUND_PIXEL (f
),
2160 FRAME_BACKGROUND_PIXEL (f
),
2163 xic
= XCreateIC (xim
,
2164 XNInputStyle
, xic_style
,
2165 XNClientWindow
, FRAME_X_WINDOW (f
),
2166 XNFocusWindow
, FRAME_X_WINDOW (f
),
2167 XNStatusAttributes
, status_attr
,
2168 XNPreeditAttributes
, preedit_attr
,
2170 XFree (preedit_attr
);
2171 XFree (status_attr
);
2174 FRAME_XIC (f
) = xic
;
2175 FRAME_XIC_STYLE (f
) = xic_style
;
2176 FRAME_XIC_FONTSET (f
) = xfs
;
2180 /* Destroy XIC and free XIC fontset of frame F, if any. */
2186 if (FRAME_XIC (f
) == NULL
)
2189 XDestroyIC (FRAME_XIC (f
));
2190 xic_free_xfontset (f
);
2192 FRAME_XIC (f
) = NULL
;
2196 /* Place preedit area for XIC of window W's frame to specified
2197 pixel position X/Y. X and Y are relative to window W. */
2200 xic_set_preeditarea (w
, x
, y
)
2204 struct frame
*f
= XFRAME (w
->frame
);
2208 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2209 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2210 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2211 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2216 /* Place status area for XIC in bottom right corner of frame F.. */
2219 xic_set_statusarea (f
)
2222 XIC xic
= FRAME_XIC (f
);
2227 /* Negotiate geometry of status area. If input method has existing
2228 status area, use its current size. */
2229 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2230 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2231 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2234 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2235 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2238 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2240 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2241 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2245 area
.width
= needed
->width
;
2246 area
.height
= needed
->height
;
2247 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2248 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2249 - FRAME_MENUBAR_HEIGHT (f
)
2250 - FRAME_TOOLBAR_HEIGHT (f
)
2251 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2254 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2255 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2260 /* Set X fontset for XIC of frame F, using base font name
2261 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2264 xic_set_xfontset (f
, base_fontname
)
2266 char *base_fontname
;
2271 xic_free_xfontset (f
);
2273 xfs
= xic_create_xfontset (f
, base_fontname
);
2275 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2276 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2277 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2278 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2279 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2282 FRAME_XIC_FONTSET (f
) = xfs
;
2285 #endif /* HAVE_X_I18N */
2289 #ifdef USE_X_TOOLKIT
2291 /* Create and set up the X widget for frame F. */
2294 x_window (f
, window_prompting
, minibuffer_only
)
2296 long window_prompting
;
2297 int minibuffer_only
;
2299 XClassHint class_hints
;
2300 XSetWindowAttributes attributes
;
2301 unsigned long attribute_mask
;
2302 Widget shell_widget
;
2304 Widget frame_widget
;
2310 /* Use the resource name as the top-level widget name
2311 for looking up resources. Make a non-Lisp copy
2312 for the window manager, so GC relocation won't bother it.
2314 Elsewhere we specify the window name for the window manager. */
2317 char *str
= (char *) SDATA (Vx_resource_name
);
2318 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2319 strcpy (f
->namebuf
, str
);
2323 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2324 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2325 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2326 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2327 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2328 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2329 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2330 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2331 applicationShellWidgetClass
,
2332 FRAME_X_DISPLAY (f
), al
, ac
);
2334 f
->output_data
.x
->widget
= shell_widget
;
2335 /* maybe_set_screen_title_format (shell_widget); */
2337 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2338 (widget_value
*) NULL
,
2339 shell_widget
, False
,
2343 (lw_callback
) NULL
);
2346 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2347 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2348 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2349 XtSetValues (pane_widget
, al
, ac
);
2350 f
->output_data
.x
->column_widget
= pane_widget
;
2352 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2353 the emacs screen when changing menubar. This reduces flickering. */
2356 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2357 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2358 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2359 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2360 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2361 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2362 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2363 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2364 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2367 f
->output_data
.x
->edit_widget
= frame_widget
;
2369 XtManageChild (frame_widget
);
2371 /* Do some needed geometry management. */
2374 char *tem
, shell_position
[32];
2377 int extra_borders
= 0;
2379 = (f
->output_data
.x
->menubar_widget
2380 ? (f
->output_data
.x
->menubar_widget
->core
.height
2381 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2384 #if 0 /* Experimentally, we now get the right results
2385 for -geometry -0-0 without this. 24 Aug 96, rms. */
2386 if (FRAME_EXTERNAL_MENU_BAR (f
))
2389 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2390 menubar_size
+= ibw
;
2394 f
->output_data
.x
->menubar_height
= menubar_size
;
2397 /* Motif seems to need this amount added to the sizes
2398 specified for the shell widget. The Athena/Lucid widgets don't.
2399 Both conclusions reached experimentally. -- rms. */
2400 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2401 &extra_borders
, NULL
);
2405 /* Convert our geometry parameters into a geometry string
2407 Note that we do not specify here whether the position
2408 is a user-specified or program-specified one.
2409 We pass that information later, in x_wm_set_size_hints. */
2411 int left
= f
->left_pos
;
2412 int xneg
= window_prompting
& XNegative
;
2413 int top
= f
->top_pos
;
2414 int yneg
= window_prompting
& YNegative
;
2420 if (window_prompting
& USPosition
)
2421 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2422 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2423 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2424 (xneg
? '-' : '+'), left
,
2425 (yneg
? '-' : '+'), top
);
2428 sprintf (shell_position
, "=%dx%d",
2429 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2430 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2432 /* Setting x and y when the position is not specified in
2433 the geometry string will set program position in the WM hints.
2434 If Emacs had just one program position, we could set it in
2435 fallback resources, but since each make-frame call can specify
2436 different program positions, this is easier. */
2437 XtSetArg (al
[ac
], XtNx
, left
); ac
++;
2438 XtSetArg (al
[ac
], XtNy
, top
); ac
++;
2442 len
= strlen (shell_position
) + 1;
2443 /* We don't free this because we don't know whether
2444 it is safe to free it while the frame exists.
2445 It isn't worth the trouble of arranging to free it
2446 when the frame is deleted. */
2447 tem
= (char *) xmalloc (len
);
2448 strncpy (tem
, shell_position
, len
);
2449 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2450 XtSetValues (shell_widget
, al
, ac
);
2453 XtManageChild (pane_widget
);
2454 XtRealizeWidget (shell_widget
);
2456 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2458 validate_x_resource_name ();
2460 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2461 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2462 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2465 FRAME_XIC (f
) = NULL
;
2467 create_frame_xic (f
);
2470 f
->output_data
.x
->wm_hints
.input
= True
;
2471 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2472 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2473 &f
->output_data
.x
->wm_hints
);
2475 hack_wm_protocols (f
, shell_widget
);
2478 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2481 /* Do a stupid property change to force the server to generate a
2482 PropertyNotify event so that the event_stream server timestamp will
2483 be initialized to something relevant to the time we created the window.
2485 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2486 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2487 XA_ATOM
, 32, PropModeAppend
,
2488 (unsigned char*) NULL
, 0);
2490 /* Make all the standard events reach the Emacs frame. */
2491 attributes
.event_mask
= STANDARD_EVENT_SET
;
2496 /* XIM server might require some X events. */
2497 unsigned long fevent
= NoEventMask
;
2498 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2499 attributes
.event_mask
|= fevent
;
2501 #endif /* HAVE_X_I18N */
2503 attribute_mask
= CWEventMask
;
2504 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2505 attribute_mask
, &attributes
);
2507 XtMapWidget (frame_widget
);
2509 /* x_set_name normally ignores requests to set the name if the
2510 requested name is the same as the current name. This is the one
2511 place where that assumption isn't correct; f->name is set, but
2512 the X server hasn't been told. */
2515 int explicit = f
->explicit_name
;
2517 f
->explicit_name
= 0;
2520 x_set_name (f
, name
, explicit);
2523 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2524 f
->output_data
.x
->text_cursor
);
2528 /* This is a no-op, except under Motif. Make sure main areas are
2529 set to something reasonable, in case we get an error later. */
2530 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2533 #else /* not USE_X_TOOLKIT */
2539 if (! xg_create_frame_widgets (f
))
2540 error ("Unable to create window");
2543 FRAME_XIC (f
) = NULL
;
2547 create_frame_xic (f
);
2550 /* XIM server might require some X events. */
2551 unsigned long fevent
= NoEventMask
;
2552 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2554 if (fevent
!= NoEventMask
)
2556 XSetWindowAttributes attributes
;
2557 XWindowAttributes wattr
;
2558 unsigned long attribute_mask
;
2560 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2562 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2563 attribute_mask
= CWEventMask
;
2564 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2565 attribute_mask
, &attributes
);
2573 #else /*! USE_GTK */
2574 /* Create and set up the X window for frame F. */
2581 XClassHint class_hints
;
2582 XSetWindowAttributes attributes
;
2583 unsigned long attribute_mask
;
2585 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2586 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2587 attributes
.bit_gravity
= StaticGravity
;
2588 attributes
.backing_store
= NotUseful
;
2589 attributes
.save_under
= True
;
2590 attributes
.event_mask
= STANDARD_EVENT_SET
;
2591 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2592 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2597 = XCreateWindow (FRAME_X_DISPLAY (f
),
2598 f
->output_data
.x
->parent_desc
,
2601 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2603 CopyFromParent
, /* depth */
2604 InputOutput
, /* class */
2606 attribute_mask
, &attributes
);
2611 create_frame_xic (f
);
2614 /* XIM server might require some X events. */
2615 unsigned long fevent
= NoEventMask
;
2616 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2617 attributes
.event_mask
|= fevent
;
2618 attribute_mask
= CWEventMask
;
2619 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2620 attribute_mask
, &attributes
);
2623 #endif /* HAVE_X_I18N */
2625 validate_x_resource_name ();
2627 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2628 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2629 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2631 /* The menubar is part of the ordinary display;
2632 it does not count in addition to the height of the window. */
2633 f
->output_data
.x
->menubar_height
= 0;
2635 /* This indicates that we use the "Passive Input" input model.
2636 Unless we do this, we don't get the Focus{In,Out} events that we
2637 need to draw the cursor correctly. Accursed bureaucrats.
2638 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2640 f
->output_data
.x
->wm_hints
.input
= True
;
2641 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2642 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2643 &f
->output_data
.x
->wm_hints
);
2644 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2646 /* Request "save yourself" and "delete window" commands from wm. */
2649 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2650 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2651 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2654 /* x_set_name normally ignores requests to set the name if the
2655 requested name is the same as the current name. This is the one
2656 place where that assumption isn't correct; f->name is set, but
2657 the X server hasn't been told. */
2660 int explicit = f
->explicit_name
;
2662 f
->explicit_name
= 0;
2665 x_set_name (f
, name
, explicit);
2668 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2669 f
->output_data
.x
->text_cursor
);
2673 if (FRAME_X_WINDOW (f
) == 0)
2674 error ("Unable to create window");
2677 #endif /* not USE_GTK */
2678 #endif /* not USE_X_TOOLKIT */
2680 /* Verify that the icon position args for this window are valid. */
2683 x_icon_verify (f
, parms
)
2687 Lisp_Object icon_x
, icon_y
;
2689 /* Set the position of the icon. Note that twm groups all
2690 icons in an icon window. */
2691 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2692 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2693 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2695 CHECK_NUMBER (icon_x
);
2696 CHECK_NUMBER (icon_y
);
2698 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2699 error ("Both left and top icon corners of icon must be specified");
2702 /* Handle the icon stuff for this window. Perhaps later we might
2703 want an x_set_icon_position which can be called interactively as
2711 Lisp_Object icon_x
, icon_y
;
2712 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2714 /* Set the position of the icon. Note that twm groups all
2715 icons in an icon window. */
2716 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2717 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2718 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2720 CHECK_NUMBER (icon_x
);
2721 CHECK_NUMBER (icon_y
);
2723 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2724 error ("Both left and top icon corners of icon must be specified");
2728 if (! EQ (icon_x
, Qunbound
))
2729 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2731 /* Start up iconic or window? */
2732 x_wm_set_window_state
2733 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
2738 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
2745 /* Make the GCs needed for this window, setting the
2746 background, border and mouse colors; also create the
2747 mouse cursor and the gray border tile. */
2749 static char cursor_bits
[] =
2751 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2752 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2753 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2761 XGCValues gc_values
;
2765 /* Create the GCs of this frame.
2766 Note that many default values are used. */
2769 gc_values
.font
= FRAME_FONT (f
)->fid
;
2770 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
2771 gc_values
.background
= f
->output_data
.x
->background_pixel
;
2772 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2773 f
->output_data
.x
->normal_gc
2774 = XCreateGC (FRAME_X_DISPLAY (f
),
2776 GCLineWidth
| GCFont
| GCForeground
| GCBackground
,
2779 /* Reverse video style. */
2780 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
2781 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
2782 f
->output_data
.x
->reverse_gc
2783 = XCreateGC (FRAME_X_DISPLAY (f
),
2785 GCFont
| GCForeground
| GCBackground
| GCLineWidth
,
2788 /* Cursor has cursor-color background, background-color foreground. */
2789 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
2790 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
2791 gc_values
.fill_style
= FillOpaqueStippled
;
2793 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
2794 FRAME_X_DISPLAY_INFO (f
)->root_window
,
2795 cursor_bits
, 16, 16);
2796 f
->output_data
.x
->cursor_gc
2797 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2798 (GCFont
| GCForeground
| GCBackground
2799 | GCFillStyle
/* | GCStipple */ | GCLineWidth
),
2803 f
->output_data
.x
->white_relief
.gc
= 0;
2804 f
->output_data
.x
->black_relief
.gc
= 0;
2806 /* Create the gray border tile used when the pointer is not in
2807 the frame. Since this depends on the frame's pixel values,
2808 this must be done on a per-frame basis. */
2809 f
->output_data
.x
->border_tile
2810 = (XCreatePixmapFromBitmapData
2811 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
2812 gray_bits
, gray_width
, gray_height
,
2813 f
->output_data
.x
->foreground_pixel
,
2814 f
->output_data
.x
->background_pixel
,
2815 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
2821 /* Free what was was allocated in x_make_gc. */
2827 Display
*dpy
= FRAME_X_DISPLAY (f
);
2831 if (f
->output_data
.x
->normal_gc
)
2833 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
2834 f
->output_data
.x
->normal_gc
= 0;
2837 if (f
->output_data
.x
->reverse_gc
)
2839 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
2840 f
->output_data
.x
->reverse_gc
= 0;
2843 if (f
->output_data
.x
->cursor_gc
)
2845 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
2846 f
->output_data
.x
->cursor_gc
= 0;
2849 if (f
->output_data
.x
->border_tile
)
2851 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
2852 f
->output_data
.x
->border_tile
= 0;
2859 /* Handler for signals raised during x_create_frame and
2860 x_create_top_frame. FRAME is the frame which is partially
2864 unwind_create_frame (frame
)
2867 struct frame
*f
= XFRAME (frame
);
2869 /* If frame is ``official'', nothing to do. */
2870 if (!CONSP (Vframe_list
) || !EQ (XCAR (Vframe_list
), frame
))
2873 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2876 x_free_frame_resources (f
);
2879 /* Check that reference counts are indeed correct. */
2880 xassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
2881 xassert (dpyinfo
->image_cache
->refcount
== image_cache_refcount
);
2890 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2892 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
2893 Returns an Emacs frame object.
2894 ALIST is an alist of frame parameters.
2895 If the parameters specify that the frame should not have a minibuffer,
2896 and do not specify a specific minibuffer window to use,
2897 then `default-minibuffer-frame' must be a frame whose minibuffer can
2898 be shared by the new frame.
2900 This function is an internal primitive--use `make-frame' instead. */)
2905 Lisp_Object frame
, tem
;
2907 int minibuffer_only
= 0;
2908 long window_prompting
= 0;
2910 int count
= SPECPDL_INDEX ();
2911 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
2912 Lisp_Object display
;
2913 struct x_display_info
*dpyinfo
= NULL
;
2919 /* Use this general default value to start with
2920 until we know if this frame has a specified name. */
2921 Vx_resource_name
= Vinvocation_name
;
2923 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
2924 if (EQ (display
, Qunbound
))
2926 dpyinfo
= check_x_display_info (display
);
2928 kb
= dpyinfo
->kboard
;
2930 kb
= &the_only_kboard
;
2933 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
2935 && ! EQ (name
, Qunbound
)
2937 error ("Invalid frame name--not a string or nil");
2940 Vx_resource_name
= name
;
2942 /* See if parent window is specified. */
2943 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
2944 if (EQ (parent
, Qunbound
))
2946 if (! NILP (parent
))
2947 CHECK_NUMBER (parent
);
2949 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2950 /* No need to protect DISPLAY because that's not used after passing
2951 it to make_frame_without_minibuffer. */
2953 GCPRO4 (parms
, parent
, name
, frame
);
2954 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
2956 if (EQ (tem
, Qnone
) || NILP (tem
))
2957 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
2958 else if (EQ (tem
, Qonly
))
2960 f
= make_minibuffer_frame ();
2961 minibuffer_only
= 1;
2963 else if (WINDOWP (tem
))
2964 f
= make_frame_without_minibuffer (tem
, kb
, display
);
2968 XSETFRAME (frame
, f
);
2970 /* Note that X Windows does support scroll bars. */
2971 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
2973 f
->output_method
= output_x_window
;
2974 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
2975 bzero (f
->output_data
.x
, sizeof (struct x_output
));
2976 f
->output_data
.x
->icon_bitmap
= -1;
2977 FRAME_FONTSET (f
) = -1;
2978 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
2979 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
2980 #ifdef USE_TOOLKIT_SCROLL_BARS
2981 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
2982 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
2983 #endif /* USE_TOOLKIT_SCROLL_BARS */
2984 record_unwind_protect (unwind_create_frame
, frame
);
2987 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
2989 if (! STRINGP (f
->icon_name
))
2990 f
->icon_name
= Qnil
;
2992 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
2994 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
2995 dpyinfo_refcount
= dpyinfo
->reference_count
;
2996 #endif /* GLYPH_DEBUG */
2998 FRAME_KBOARD (f
) = kb
;
3001 /* These colors will be set anyway later, but it's important
3002 to get the color reference counts right, so initialize them! */
3005 struct gcpro gcpro1
;
3007 /* Function x_decode_color can signal an error. Make
3008 sure to initialize color slots so that we won't try
3009 to free colors we haven't allocated. */
3010 f
->output_data
.x
->foreground_pixel
= -1;
3011 f
->output_data
.x
->background_pixel
= -1;
3012 f
->output_data
.x
->cursor_pixel
= -1;
3013 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3014 f
->output_data
.x
->border_pixel
= -1;
3015 f
->output_data
.x
->mouse_pixel
= -1;
3017 black
= build_string ("black");
3019 f
->output_data
.x
->foreground_pixel
3020 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3021 f
->output_data
.x
->background_pixel
3022 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3023 f
->output_data
.x
->cursor_pixel
3024 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3025 f
->output_data
.x
->cursor_foreground_pixel
3026 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3027 f
->output_data
.x
->border_pixel
3028 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3029 f
->output_data
.x
->mouse_pixel
3030 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3034 /* Specify the parent under which to make this X window. */
3038 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3039 f
->output_data
.x
->explicit_parent
= 1;
3043 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3044 f
->output_data
.x
->explicit_parent
= 0;
3047 /* Set the name; the functions to which we pass f expect the name to
3049 if (EQ (name
, Qunbound
) || NILP (name
))
3051 f
->name
= build_string (dpyinfo
->x_id_name
);
3052 f
->explicit_name
= 0;
3057 f
->explicit_name
= 1;
3058 /* use the frame's title when getting resources for this frame. */
3059 specbind (Qx_resource_name
, name
);
3062 /* Extract the window parameters from the supplied values
3063 that are needed to determine window geometry. */
3067 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3070 /* First, try whatever font the caller has specified. */
3073 tem
= Fquery_fontset (font
, Qnil
);
3075 font
= x_new_fontset (f
, SDATA (tem
));
3077 font
= x_new_font (f
, SDATA (font
));
3080 /* Try out a font which we hope has bold and italic variations. */
3081 if (!STRINGP (font
))
3082 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
3083 if (!STRINGP (font
))
3084 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3085 if (! STRINGP (font
))
3086 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3087 if (! STRINGP (font
))
3088 /* This was formerly the first thing tried, but it finds too many fonts
3089 and takes too long. */
3090 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3091 /* If those didn't work, look for something which will at least work. */
3092 if (! STRINGP (font
))
3093 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3095 if (! STRINGP (font
))
3096 font
= build_string ("fixed");
3098 x_default_parameter (f
, parms
, Qfont
, font
,
3099 "font", "Font", RES_TYPE_STRING
);
3103 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3104 whereby it fails to get any font. */
3105 xlwmenu_default_font
= FRAME_FONT (f
);
3108 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3109 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3111 /* This defaults to 1 in order to match xterm. We recognize either
3112 internalBorderWidth or internalBorder (which is what xterm calls
3114 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3118 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3119 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3120 if (! EQ (value
, Qunbound
))
3121 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3124 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3125 "internalBorderWidth", "internalBorderWidth",
3127 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3128 "verticalScrollBars", "ScrollBars",
3131 /* Also do the stuff which must be set before the window exists. */
3132 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3133 "foreground", "Foreground", RES_TYPE_STRING
);
3134 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3135 "background", "Background", RES_TYPE_STRING
);
3136 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3137 "pointerColor", "Foreground", RES_TYPE_STRING
);
3138 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3139 "cursorColor", "Foreground", RES_TYPE_STRING
);
3140 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3141 "borderColor", "BorderColor", RES_TYPE_STRING
);
3142 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3143 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3144 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3145 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3146 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3147 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3148 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3149 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3151 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3152 "scrollBarForeground",
3153 "ScrollBarForeground", 1);
3154 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3155 "scrollBarBackground",
3156 "ScrollBarBackground", 0);
3158 /* Init faces before x_default_parameter is called for scroll-bar
3159 parameters because that function calls x_set_scroll_bar_width,
3160 which calls change_frame_size, which calls Fset_window_buffer,
3161 which runs hooks, which call Fvertical_motion. At the end, we
3162 end up in init_iterator with a null face cache, which should not
3164 init_frame_faces (f
);
3166 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3167 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
3168 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (1),
3169 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
3170 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3171 "bufferPredicate", "BufferPredicate",
3173 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3174 "title", "Title", RES_TYPE_STRING
);
3175 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3176 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3177 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3178 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3180 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3182 /* Compute the size of the X window. */
3183 window_prompting
= x_figure_window_size (f
, parms
, 1);
3185 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3186 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3188 x_icon_verify (f
, parms
);
3190 /* Create the X widget or window. */
3191 #ifdef USE_X_TOOLKIT
3192 x_window (f
, window_prompting
, minibuffer_only
);
3200 /* Now consider the frame official. */
3201 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3202 Vframe_list
= Fcons (frame
, Vframe_list
);
3204 /* We need to do this after creating the X window, so that the
3205 icon-creation functions can say whose icon they're describing. */
3206 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3207 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
3209 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3210 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3211 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3212 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3213 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3214 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3215 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3216 "scrollBarWidth", "ScrollBarWidth",
3219 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3220 Change will not be effected unless different from the current
3222 width
= FRAME_COLS (f
);
3223 height
= FRAME_LINES (f
);
3225 SET_FRAME_COLS (f
, 0);
3226 FRAME_LINES (f
) = 0;
3227 change_frame_size (f
, height
, width
, 1, 0, 0);
3229 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3230 /* Create the menu bar. */
3231 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3233 /* If this signals an error, we haven't set size hints for the
3234 frame and we didn't make it visible. */
3235 initialize_frame_menubar (f
);
3238 /* This is a no-op, except under Motif where it arranges the
3239 main window for the widgets on it. */
3240 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3241 f
->output_data
.x
->menubar_widget
,
3242 f
->output_data
.x
->edit_widget
);
3243 #endif /* not USE_GTK */
3245 #endif /* USE_X_TOOLKIT || USE_GTK */
3247 /* Tell the server what size and position, etc, we want, and how
3248 badly we want them. This should be done after we have the menu
3249 bar so that its size can be taken into account. */
3251 x_wm_set_size_hint (f
, window_prompting
, 0);
3254 /* Make the window appear on the frame and enable display, unless
3255 the caller says not to. However, with explicit parent, Emacs
3256 cannot control visibility, so don't try. */
3257 if (! f
->output_data
.x
->explicit_parent
)
3259 Lisp_Object visibility
;
3261 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3263 if (EQ (visibility
, Qunbound
))
3266 if (EQ (visibility
, Qicon
))
3267 x_iconify_frame (f
);
3268 else if (! NILP (visibility
))
3269 x_make_frame_visible (f
);
3271 /* Must have been Qnil. */
3275 /* Set the WM leader property. GTK does this itself, so this is not
3276 needed when using GTK. */
3277 if (dpyinfo
->client_leader_window
!= 0)
3280 XChangeProperty (FRAME_X_DISPLAY (f
),
3281 FRAME_OUTER_WINDOW (f
),
3282 dpyinfo
->Xatom_wm_client_leader
,
3283 XA_WINDOW
, 32, PropModeReplace
,
3284 (char *) &dpyinfo
->client_leader_window
, 1);
3290 /* Make sure windows on this frame appear in calls to next-window
3291 and similar functions. */
3292 Vwindow_list
= Qnil
;
3294 return unbind_to (count
, frame
);
3298 /* FRAME is used only to get a handle on the X display. We don't pass the
3299 display info directly because we're called from frame.c, which doesn't
3300 know about that structure. */
3303 x_get_focus_frame (frame
)
3304 struct frame
*frame
;
3306 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3308 if (! dpyinfo
->x_focus_frame
)
3311 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3316 /* In certain situations, when the window manager follows a
3317 click-to-focus policy, there seems to be no way around calling
3318 XSetInputFocus to give another frame the input focus .
3320 In an ideal world, XSetInputFocus should generally be avoided so
3321 that applications don't interfere with the window manager's focus
3322 policy. But I think it's okay to use when it's clearly done
3323 following a user-command. */
3325 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 1, 0,
3326 doc
: /* Set the input focus to FRAME.
3327 FRAME nil means use the selected frame. */)
3331 struct frame
*f
= check_x_frame (frame
);
3332 Display
*dpy
= FRAME_X_DISPLAY (f
);
3336 count
= x_catch_errors (dpy
);
3337 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3338 RevertToParent
, CurrentTime
);
3339 x_uncatch_errors (dpy
, count
);
3346 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3347 doc
: /* Internal function called by `color-defined-p', which see. */)
3349 Lisp_Object color
, frame
;
3352 FRAME_PTR f
= check_x_frame (frame
);
3354 CHECK_STRING (color
);
3356 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3362 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3363 doc
: /* Internal function called by `color-values', which see. */)
3365 Lisp_Object color
, frame
;
3368 FRAME_PTR f
= check_x_frame (frame
);
3370 CHECK_STRING (color
);
3372 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3376 rgb
[0] = make_number (foo
.red
);
3377 rgb
[1] = make_number (foo
.green
);
3378 rgb
[2] = make_number (foo
.blue
);
3379 return Flist (3, rgb
);
3385 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3386 doc
: /* Internal function called by `display-color-p', which see. */)
3388 Lisp_Object display
;
3390 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3392 if (dpyinfo
->n_planes
<= 2)
3395 switch (dpyinfo
->visual
->class)
3408 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3410 doc
: /* Return t if the X display supports shades of gray.
3411 Note that color displays do support shades of gray.
3412 The optional argument DISPLAY specifies which display to ask about.
3413 DISPLAY should be either a frame or a display name (a string).
3414 If omitted or nil, that stands for the selected frame's display. */)
3416 Lisp_Object display
;
3418 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3420 if (dpyinfo
->n_planes
<= 1)
3423 switch (dpyinfo
->visual
->class)
3438 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3440 doc
: /* Returns the width 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
->width
);
3452 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3453 Sx_display_pixel_height
, 0, 1, 0,
3454 doc
: /* Returns the height in pixels 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
->height
);
3466 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3468 doc
: /* Returns the number of bitplanes 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 return make_number (dpyinfo
->n_planes
);
3480 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3482 doc
: /* Returns the number of color cells of the X display DISPLAY.
3483 The optional argument DISPLAY specifies which display to ask about.
3484 DISPLAY should be either a frame or a display name (a string).
3485 If omitted or nil, that stands for the selected frame's display. */)
3487 Lisp_Object display
;
3489 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3491 int nr_planes
= DisplayPlanes (dpyinfo
->display
,
3492 XScreenNumberOfScreen (dpyinfo
->screen
));
3494 /* Truncate nr_planes to 24 to avoid integer overflow.
3495 Some displays says 32, but only 24 bits are actually significant.
3496 There are only very few and rare video cards that have more than
3497 24 significant bits. Also 24 bits is more than 16 million colors,
3498 it "should be enough for everyone". */
3499 if (nr_planes
> 24) nr_planes
= 24;
3501 return make_number (1 << nr_planes
);
3504 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3505 Sx_server_max_request_size
,
3507 doc
: /* Returns the maximum request size of the X server of display DISPLAY.
3508 The optional argument DISPLAY specifies which display to ask about.
3509 DISPLAY should be either a frame or a display name (a string).
3510 If omitted or nil, that stands for the selected frame's display. */)
3512 Lisp_Object display
;
3514 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3516 return make_number (MAXREQUEST (dpyinfo
->display
));
3519 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3520 doc
: /* Returns the "vendor ID" string of the X server of display DISPLAY.
3521 \(Labelling every distributor as a "vendor" embodies the false assumption
3522 that operating systems cannot be developed and distributed noncommercially.)
3523 The optional argument DISPLAY specifies which display to ask about.
3524 DISPLAY should be either a frame or a display name (a string).
3525 If omitted or nil, that stands for the selected frame's display. */)
3527 Lisp_Object display
;
3529 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3530 char *vendor
= ServerVendor (dpyinfo
->display
);
3532 if (! vendor
) vendor
= "";
3533 return build_string (vendor
);
3536 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3537 doc
: /* Returns the version numbers of the X server of display DISPLAY.
3538 The value is a list of three integers: the major and minor
3539 version numbers of the X Protocol in use, and the distributor-specific release
3540 number. See also the function `x-server-vendor'.
3542 The optional argument DISPLAY specifies which display to ask about.
3543 DISPLAY should be either a frame or a display name (a string).
3544 If omitted or nil, that stands for the selected frame's display. */)
3546 Lisp_Object display
;
3548 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3549 Display
*dpy
= dpyinfo
->display
;
3551 return Fcons (make_number (ProtocolVersion (dpy
)),
3552 Fcons (make_number (ProtocolRevision (dpy
)),
3553 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3556 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3557 doc
: /* Return the number of screens on the X server of display DISPLAY.
3558 The optional argument DISPLAY specifies which display to ask about.
3559 DISPLAY should be either a frame or a display name (a string).
3560 If omitted or nil, that stands for the selected frame's display. */)
3562 Lisp_Object display
;
3564 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3566 return make_number (ScreenCount (dpyinfo
->display
));
3569 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3570 doc
: /* Return the height in millimeters of the X display DISPLAY.
3571 The optional argument DISPLAY specifies which display to ask about.
3572 DISPLAY should be either a frame or a display name (a string).
3573 If omitted or nil, that stands for the selected frame's display. */)
3575 Lisp_Object display
;
3577 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3579 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3582 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3583 doc
: /* Return the width in millimeters of the X display DISPLAY.
3584 The optional argument DISPLAY specifies which display to ask about.
3585 DISPLAY should be either a frame or a display name (a string).
3586 If omitted or nil, that stands for the selected frame's display. */)
3588 Lisp_Object display
;
3590 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3592 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3595 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3596 Sx_display_backing_store
, 0, 1, 0,
3597 doc
: /* Returns an indication of whether X display DISPLAY does backing store.
3598 The value may be `always', `when-mapped', or `not-useful'.
3599 The optional argument DISPLAY specifies which display to ask about.
3600 DISPLAY should be either a frame or a display name (a string).
3601 If omitted or nil, that stands for the selected frame's display. */)
3603 Lisp_Object display
;
3605 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3608 switch (DoesBackingStore (dpyinfo
->screen
))
3611 result
= intern ("always");
3615 result
= intern ("when-mapped");
3619 result
= intern ("not-useful");
3623 error ("Strange value for BackingStore parameter of screen");
3630 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3631 Sx_display_visual_class
, 0, 1, 0,
3632 doc
: /* Return the visual class of the X display DISPLAY.
3633 The value is one of the symbols `static-gray', `gray-scale',
3634 `static-color', `pseudo-color', `true-color', or `direct-color'.
3636 The optional argument DISPLAY specifies which display to ask about.
3637 DISPLAY should be either a frame or a display name (a string).
3638 If omitted or nil, that stands for the selected frame's display. */)
3640 Lisp_Object display
;
3642 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3645 switch (dpyinfo
->visual
->class)
3648 result
= intern ("static-gray");
3651 result
= intern ("gray-scale");
3654 result
= intern ("static-color");
3657 result
= intern ("pseudo-color");
3660 result
= intern ("true-color");
3663 result
= intern ("direct-color");
3666 error ("Display has an unknown visual class");
3673 DEFUN ("x-display-save-under", Fx_display_save_under
,
3674 Sx_display_save_under
, 0, 1, 0,
3675 doc
: /* Returns t if the X display DISPLAY supports the save-under feature.
3676 The optional argument DISPLAY specifies which display to ask about.
3677 DISPLAY should be either a frame or a display name (a string).
3678 If omitted or nil, that stands for the selected frame's display. */)
3680 Lisp_Object display
;
3682 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3684 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3692 register struct frame
*f
;
3694 return FRAME_PIXEL_WIDTH (f
);
3699 register struct frame
*f
;
3701 return FRAME_PIXEL_HEIGHT (f
);
3706 register struct frame
*f
;
3708 return FRAME_COLUMN_WIDTH (f
);
3713 register struct frame
*f
;
3715 return FRAME_LINE_HEIGHT (f
);
3720 register struct frame
*f
;
3722 return FRAME_X_DISPLAY_INFO (f
)->n_planes
;
3727 /************************************************************************
3729 ************************************************************************/
3732 /* Mapping visual names to visuals. */
3734 static struct visual_class
3741 {"StaticGray", StaticGray
},
3742 {"GrayScale", GrayScale
},
3743 {"StaticColor", StaticColor
},
3744 {"PseudoColor", PseudoColor
},
3745 {"TrueColor", TrueColor
},
3746 {"DirectColor", DirectColor
},
3751 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3753 /* Value is the screen number of screen SCR. This is a substitute for
3754 the X function with the same name when that doesn't exist. */
3757 XScreenNumberOfScreen (scr
)
3758 register Screen
*scr
;
3760 Display
*dpy
= scr
->display
;
3763 for (i
= 0; i
< dpy
->nscreens
; ++i
)
3764 if (scr
== dpy
->screens
+ i
)
3770 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3773 /* Select the visual that should be used on display DPYINFO. Set
3774 members of DPYINFO appropriately. Called from x_term_init. */
3777 select_visual (dpyinfo
)
3778 struct x_display_info
*dpyinfo
;
3780 Display
*dpy
= dpyinfo
->display
;
3781 Screen
*screen
= dpyinfo
->screen
;
3784 /* See if a visual is specified. */
3785 value
= display_x_get_resource (dpyinfo
,
3786 build_string ("visualClass"),
3787 build_string ("VisualClass"),
3789 if (STRINGP (value
))
3791 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
3792 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
3793 depth, a decimal number. NAME is compared with case ignored. */
3794 char *s
= (char *) alloca (SBYTES (value
) + 1);
3799 strcpy (s
, SDATA (value
));
3800 dash
= index (s
, '-');
3803 dpyinfo
->n_planes
= atoi (dash
+ 1);
3807 /* We won't find a matching visual with depth 0, so that
3808 an error will be printed below. */
3809 dpyinfo
->n_planes
= 0;
3811 /* Determine the visual class. */
3812 for (i
= 0; visual_classes
[i
].name
; ++i
)
3813 if (xstricmp (s
, visual_classes
[i
].name
) == 0)
3815 class = visual_classes
[i
].class;
3819 /* Look up a matching visual for the specified class. */
3821 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
3822 dpyinfo
->n_planes
, class, &vinfo
))
3823 fatal ("Invalid visual specification `%s'", SDATA (value
));
3825 dpyinfo
->visual
= vinfo
.visual
;
3830 XVisualInfo
*vinfo
, vinfo_template
;
3832 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
3835 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
3837 vinfo_template
.visualid
= dpyinfo
->visual
->visualid
;
3839 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
3840 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
3841 &vinfo_template
, &n_visuals
);
3843 fatal ("Can't get proper X visual info");
3845 dpyinfo
->n_planes
= vinfo
->depth
;
3846 XFree ((char *) vinfo
);
3851 /* Return the X display structure for the display named NAME.
3852 Open a new connection if necessary. */
3854 struct x_display_info
*
3855 x_display_info_for_name (name
)
3859 struct x_display_info
*dpyinfo
;
3861 CHECK_STRING (name
);
3863 if (! EQ (Vwindow_system
, intern ("x")))
3864 error ("Not using X Windows");
3866 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
3868 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
3871 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
3876 /* Use this general default value to start with. */
3877 Vx_resource_name
= Vinvocation_name
;
3879 validate_x_resource_name ();
3881 dpyinfo
= x_term_init (name
, (char *)0,
3882 (char *) SDATA (Vx_resource_name
));
3885 error ("Cannot connect to X server %s", SDATA (name
));
3888 XSETFASTINT (Vwindow_system_version
, 11);
3894 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
3896 doc
: /* Open a connection to an X server.
3897 DISPLAY is the name of the display to connect to.
3898 Optional second arg XRM-STRING is a string of resources in xrdb format.
3899 If the optional third arg MUST-SUCCEED is non-nil,
3900 terminate Emacs if we can't open the connection. */)
3901 (display
, xrm_string
, must_succeed
)
3902 Lisp_Object display
, xrm_string
, must_succeed
;
3904 unsigned char *xrm_option
;
3905 struct x_display_info
*dpyinfo
;
3907 CHECK_STRING (display
);
3908 if (! NILP (xrm_string
))
3909 CHECK_STRING (xrm_string
);
3911 if (! EQ (Vwindow_system
, intern ("x")))
3912 error ("Not using X Windows");
3914 if (! NILP (xrm_string
))
3915 xrm_option
= (unsigned char *) SDATA (xrm_string
);
3917 xrm_option
= (unsigned char *) 0;
3919 validate_x_resource_name ();
3921 /* This is what opens the connection and sets x_current_display.
3922 This also initializes many symbols, such as those used for input. */
3923 dpyinfo
= x_term_init (display
, xrm_option
,
3924 (char *) SDATA (Vx_resource_name
));
3928 if (!NILP (must_succeed
))
3929 fatal ("Cannot connect to X server %s.\n\
3930 Check the DISPLAY environment variable or use `-d'.\n\
3931 Also use the `xauth' program to verify that you have the proper\n\
3932 authorization information needed to connect the X server.\n\
3933 An insecure way to solve the problem may be to use `xhost'.\n",
3936 error ("Cannot connect to X server %s", SDATA (display
));
3941 XSETFASTINT (Vwindow_system_version
, 11);
3945 DEFUN ("x-close-connection", Fx_close_connection
,
3946 Sx_close_connection
, 1, 1, 0,
3947 doc
: /* Close the connection to DISPLAY's X server.
3948 For DISPLAY, specify either a frame or a display name (a string).
3949 If DISPLAY is nil, that stands for the selected frame's display. */)
3951 Lisp_Object display
;
3953 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3956 if (dpyinfo
->reference_count
> 0)
3957 error ("Display still has frames on it");
3960 /* Free the fonts in the font table. */
3961 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
3962 if (dpyinfo
->font_table
[i
].name
)
3964 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
3967 x_destroy_all_bitmaps (dpyinfo
);
3968 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
3970 #ifdef USE_X_TOOLKIT
3971 XtCloseDisplay (dpyinfo
->display
);
3973 XCloseDisplay (dpyinfo
->display
);
3976 x_delete_display (dpyinfo
);
3982 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
3983 doc
: /* Return the list of display names that Emacs has connections to. */)
3986 Lisp_Object tail
, result
;
3989 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
3990 result
= Fcons (XCAR (XCAR (tail
)), result
);
3995 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
3996 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
3997 If ON is nil, allow buffering of requests.
3998 Turning on synchronization prohibits the Xlib routines from buffering
3999 requests and seriously degrades performance, but makes debugging much
4001 The optional second argument DISPLAY specifies which display to act on.
4002 DISPLAY should be either a frame or a display name (a string).
4003 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4005 Lisp_Object display
, on
;
4007 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4009 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4014 /* Wait for responses to all X commands issued so far for frame F. */
4021 XSync (FRAME_X_DISPLAY (f
), False
);
4026 /***********************************************************************
4028 ***********************************************************************/
4030 DEFUN ("x-change-window-property", Fx_change_window_property
,
4031 Sx_change_window_property
, 2, 6, 0,
4032 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
4033 PROP must be a string.
4034 VALUE may be a string or a list of conses, numbers and/or strings.
4035 If an element in the list is a string, it is converted to
4036 an Atom and the value of the Atom is used. If an element is a cons,
4037 it is converted to a 32 bit number where the car is the 16 top bits and the
4038 cdr is the lower 16 bits.
4039 FRAME nil or omitted means use the selected frame.
4040 If TYPE is given and non-nil, it is the name of the type of VALUE.
4041 If TYPE is not given or nil, the type is STRING.
4042 FORMAT gives the size in bits of each element if VALUE is a list.
4043 It must be one of 8, 16 or 32.
4044 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4045 If OUTER_P is non-nil, the property is changed for the outer X window of
4046 FRAME. Default is to change on the edit X window.
4049 (prop
, value
, frame
, type
, format
, outer_p
)
4050 Lisp_Object prop
, value
, frame
, type
, format
, outer_p
;
4052 struct frame
*f
= check_x_frame (frame
);
4054 Atom target_type
= XA_STRING
;
4055 int element_format
= 8;
4056 unsigned char *data
;
4060 CHECK_STRING (prop
);
4062 if (! NILP (format
))
4064 CHECK_NUMBER (format
);
4065 element_format
= XFASTINT (format
);
4067 if (element_format
!= 8 && element_format
!= 16
4068 && element_format
!= 32)
4069 error ("FORMAT must be one of 8, 16 or 32");
4074 nelements
= x_check_property_data (value
);
4075 if (nelements
== -1)
4076 error ("Bad data in VALUE, must be number, string or cons");
4078 if (element_format
== 8)
4079 data
= (unsigned char *) xmalloc (nelements
);
4080 else if (element_format
== 16)
4081 data
= (unsigned char *) xmalloc (nelements
*2);
4082 else /* format == 32 */
4083 /* The man page for XChangeProperty:
4084 "If the specified format is 32, the property data must be a
4086 This applies even if long is more than 64 bits. The X library
4087 converts to 32 bits before sending to the X server. */
4088 data
= (unsigned char *) xmalloc (nelements
* sizeof(long));
4090 x_fill_property_data (FRAME_X_DISPLAY (f
), value
, data
, element_format
);
4094 CHECK_STRING (value
);
4095 data
= SDATA (value
);
4096 nelements
= SCHARS (value
);
4100 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4103 CHECK_STRING (type
);
4104 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (type
), False
);
4107 if (! NILP (outer_p
)) w
= FRAME_OUTER_WINDOW (f
);
4108 else w
= FRAME_X_WINDOW (f
);
4110 XChangeProperty (FRAME_X_DISPLAY (f
), w
,
4111 prop_atom
, target_type
, element_format
, PropModeReplace
,
4114 if (CONSP (value
)) xfree (data
);
4116 /* Make sure the property is set when we return. */
4117 XFlush (FRAME_X_DISPLAY (f
));
4124 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
4125 Sx_delete_window_property
, 1, 2, 0,
4126 doc
: /* Remove window property PROP from X window of FRAME.
4127 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4129 Lisp_Object prop
, frame
;
4131 struct frame
*f
= check_x_frame (frame
);
4134 CHECK_STRING (prop
);
4136 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4137 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
4139 /* Make sure the property is removed when we return. */
4140 XFlush (FRAME_X_DISPLAY (f
));
4147 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
4149 doc
: /* Value is the value of window property PROP on FRAME.
4150 If FRAME is nil or omitted, use the selected frame.
4151 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4152 is the name of the Atom that denotes the type expected.
4153 If SOURCE is non-nil, get the property on that window instead of from
4154 FRAME. The number 0 denotes the root window.
4155 If DELETE_P is non-nil, delete the property after retreiving it.
4156 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4158 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4159 no value of TYPE. */)
4160 (prop
, frame
, type
, source
, delete_p
, vector_ret_p
)
4161 Lisp_Object prop
, frame
, type
, source
, delete_p
, vector_ret_p
;
4163 struct frame
*f
= check_x_frame (frame
);
4166 Lisp_Object prop_value
= Qnil
;
4167 unsigned char *tmp_data
= NULL
;
4169 Atom target_type
= XA_STRING
;
4171 unsigned long actual_size
, bytes_remaining
;
4172 Window target_window
= FRAME_X_WINDOW (f
);
4173 struct gcpro gcpro1
;
4175 GCPRO1 (prop_value
);
4176 CHECK_STRING (prop
);
4178 if (! NILP (source
))
4180 if (NUMBERP (source
))
4182 if (FLOATP (source
))
4183 target_window
= (Window
) XFLOAT (source
);
4185 target_window
= XFASTINT (source
);
4187 if (target_window
== 0)
4188 target_window
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4190 else if (CONSP (source
))
4191 target_window
= cons_to_long (source
);
4197 if (strcmp ("AnyPropertyType", SDATA (type
)) == 0)
4198 target_type
= AnyPropertyType
;
4200 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (type
), False
);
4203 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4204 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4205 prop_atom
, 0, 0, False
, target_type
,
4206 &actual_type
, &actual_format
, &actual_size
,
4207 &bytes_remaining
, &tmp_data
);
4210 int size
= bytes_remaining
;
4215 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4216 prop_atom
, 0, bytes_remaining
,
4217 ! NILP (delete_p
), target_type
,
4218 &actual_type
, &actual_format
,
4219 &actual_size
, &bytes_remaining
,
4221 if (rc
== Success
&& tmp_data
)
4223 /* The man page for XGetWindowProperty says:
4224 "If the returned format is 32, the returned data is represented
4225 as a long array and should be cast to that type to obtain the
4227 This applies even if long is more than 32 bits, the X library
4228 converts from 32 bit elements received from the X server to long
4229 and passes the long array to us. Thus, for that case bcopy can not
4230 be used. We convert to a 32 bit type here, because so much code
4233 The bytes and offsets passed to XGetWindowProperty refers to the
4234 property and those are indeed in 32 bit quantities if format is
4237 if (actual_format
== 32 && actual_format
< BITS_PER_LONG
)
4240 int *idata
= (int *) tmp_data
;
4241 long *ldata
= (long *) tmp_data
;
4243 for (i
= 0; i
< actual_size
; ++i
)
4244 idata
[i
] = (int) ldata
[i
];
4247 if (NILP (vector_ret_p
))
4248 prop_value
= make_string (tmp_data
, size
);
4250 prop_value
= x_property_data_to_lisp (f
,
4257 if (tmp_data
) XFree (tmp_data
);
4267 /***********************************************************************
4269 ***********************************************************************/
4271 /* If non-null, an asynchronous timer that, when it expires, displays
4272 an hourglass cursor on all frames. */
4274 static struct atimer
*hourglass_atimer
;
4276 /* Non-zero means an hourglass cursor is currently shown. */
4278 static int hourglass_shown_p
;
4280 /* Number of seconds to wait before displaying an hourglass cursor. */
4282 static Lisp_Object Vhourglass_delay
;
4284 /* Default number of seconds to wait before displaying an hourglass
4287 #define DEFAULT_HOURGLASS_DELAY 1
4289 /* Function prototypes. */
4291 static void show_hourglass
P_ ((struct atimer
*));
4292 static void hide_hourglass
P_ ((void));
4295 /* Cancel a currently active hourglass timer, and start a new one. */
4301 int secs
, usecs
= 0;
4303 cancel_hourglass ();
4305 if (INTEGERP (Vhourglass_delay
)
4306 && XINT (Vhourglass_delay
) > 0)
4307 secs
= XFASTINT (Vhourglass_delay
);
4308 else if (FLOATP (Vhourglass_delay
)
4309 && XFLOAT_DATA (Vhourglass_delay
) > 0)
4312 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
4313 secs
= XFASTINT (tem
);
4314 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
4317 secs
= DEFAULT_HOURGLASS_DELAY
;
4319 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
4320 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
4321 show_hourglass
, NULL
);
4325 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
4331 if (hourglass_atimer
)
4333 cancel_atimer (hourglass_atimer
);
4334 hourglass_atimer
= NULL
;
4337 if (hourglass_shown_p
)
4342 /* Timer function of hourglass_atimer. TIMER is equal to
4345 Display an hourglass pointer on all frames by mapping the frames'
4346 hourglass_window. Set the hourglass_p flag in the frames'
4347 output_data.x structure to indicate that an hourglass cursor is
4348 shown on the frames. */
4351 show_hourglass (timer
)
4352 struct atimer
*timer
;
4354 /* The timer implementation will cancel this timer automatically
4355 after this function has run. Set hourglass_atimer to null
4356 so that we know the timer doesn't have to be canceled. */
4357 hourglass_atimer
= NULL
;
4359 if (!hourglass_shown_p
)
4361 Lisp_Object rest
, frame
;
4365 FOR_EACH_FRAME (rest
, frame
)
4367 struct frame
*f
= XFRAME (frame
);
4369 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
) && FRAME_X_DISPLAY (f
))
4371 Display
*dpy
= FRAME_X_DISPLAY (f
);
4373 #ifdef USE_X_TOOLKIT
4374 if (f
->output_data
.x
->widget
)
4376 if (FRAME_OUTER_WINDOW (f
))
4379 f
->output_data
.x
->hourglass_p
= 1;
4381 if (!f
->output_data
.x
->hourglass_window
)
4383 unsigned long mask
= CWCursor
;
4384 XSetWindowAttributes attrs
;
4386 Window parent
= FRAME_X_WINDOW (f
);
4388 Window parent
= FRAME_OUTER_WINDOW (f
);
4390 attrs
.cursor
= f
->output_data
.x
->hourglass_cursor
;
4392 f
->output_data
.x
->hourglass_window
4393 = XCreateWindow (dpy
, parent
,
4394 0, 0, 32000, 32000, 0, 0,
4400 XMapRaised (dpy
, f
->output_data
.x
->hourglass_window
);
4406 hourglass_shown_p
= 1;
4412 /* Hide the hourglass pointer on all frames, if it is currently
4418 if (hourglass_shown_p
)
4420 Lisp_Object rest
, frame
;
4423 FOR_EACH_FRAME (rest
, frame
)
4425 struct frame
*f
= XFRAME (frame
);
4428 /* Watch out for newly created frames. */
4429 && f
->output_data
.x
->hourglass_window
)
4431 XUnmapWindow (FRAME_X_DISPLAY (f
),
4432 f
->output_data
.x
->hourglass_window
);
4433 /* Sync here because XTread_socket looks at the
4434 hourglass_p flag that is reset to zero below. */
4435 XSync (FRAME_X_DISPLAY (f
), False
);
4436 f
->output_data
.x
->hourglass_p
= 0;
4440 hourglass_shown_p
= 0;
4447 /***********************************************************************
4449 ***********************************************************************/
4451 static Lisp_Object x_create_tip_frame
P_ ((struct x_display_info
*,
4452 Lisp_Object
, Lisp_Object
));
4453 static void compute_tip_xy
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
4454 Lisp_Object
, int, int, int *, int *));
4456 /* The frame of a currently visible tooltip. */
4458 Lisp_Object tip_frame
;
4460 /* If non-nil, a timer started that hides the last tooltip when it
4463 Lisp_Object tip_timer
;
4466 /* If non-nil, a vector of 3 elements containing the last args
4467 with which x-show-tip was called. See there. */
4469 Lisp_Object last_show_tip_args
;
4471 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4473 Lisp_Object Vx_max_tooltip_size
;
4477 unwind_create_tip_frame (frame
)
4480 Lisp_Object deleted
;
4482 deleted
= unwind_create_frame (frame
);
4483 if (EQ (deleted
, Qt
))
4493 /* Create a frame for a tooltip on the display described by DPYINFO.
4494 PARMS is a list of frame parameters. TEXT is the string to
4495 display in the tip frame. Value is the frame.
4497 Note that functions called here, esp. x_default_parameter can
4498 signal errors, for instance when a specified color name is
4499 undefined. We have to make sure that we're in a consistent state
4500 when this happens. */
4503 x_create_tip_frame (dpyinfo
, parms
, text
)
4504 struct x_display_info
*dpyinfo
;
4505 Lisp_Object parms
, text
;
4508 Lisp_Object frame
, tem
;
4510 long window_prompting
= 0;
4512 int count
= SPECPDL_INDEX ();
4513 struct gcpro gcpro1
, gcpro2
, gcpro3
;
4515 int face_change_count_before
= face_change_count
;
4517 struct buffer
*old_buffer
;
4521 /* Use this general default value to start with until we know if
4522 this frame has a specified name. */
4523 Vx_resource_name
= Vinvocation_name
;
4526 kb
= dpyinfo
->kboard
;
4528 kb
= &the_only_kboard
;
4531 /* Get the name of the frame to use for resource lookup. */
4532 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
4534 && !EQ (name
, Qunbound
)
4536 error ("Invalid frame name--not a string or nil");
4537 Vx_resource_name
= name
;
4540 GCPRO3 (parms
, name
, frame
);
4542 XSETFRAME (frame
, f
);
4544 buffer
= Fget_buffer_create (build_string (" *tip*"));
4545 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
4546 old_buffer
= current_buffer
;
4547 set_buffer_internal_1 (XBUFFER (buffer
));
4548 current_buffer
->truncate_lines
= Qnil
;
4549 specbind (Qinhibit_read_only
, Qt
);
4550 specbind (Qinhibit_modification_hooks
, Qt
);
4553 set_buffer_internal_1 (old_buffer
);
4555 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
4556 record_unwind_protect (unwind_create_tip_frame
, frame
);
4558 /* By setting the output method, we're essentially saying that
4559 the frame is live, as per FRAME_LIVE_P. If we get a signal
4560 from this point on, x_destroy_window might screw up reference
4562 f
->output_method
= output_x_window
;
4563 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
4564 bzero (f
->output_data
.x
, sizeof (struct x_output
));
4565 f
->output_data
.x
->icon_bitmap
= -1;
4566 FRAME_FONTSET (f
) = -1;
4567 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
4568 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
4569 #ifdef USE_TOOLKIT_SCROLL_BARS
4570 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
4571 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
4572 #endif /* USE_TOOLKIT_SCROLL_BARS */
4573 f
->icon_name
= Qnil
;
4574 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
4576 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
4577 dpyinfo_refcount
= dpyinfo
->reference_count
;
4578 #endif /* GLYPH_DEBUG */
4580 FRAME_KBOARD (f
) = kb
;
4582 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4583 f
->output_data
.x
->explicit_parent
= 0;
4585 /* These colors will be set anyway later, but it's important
4586 to get the color reference counts right, so initialize them! */
4589 struct gcpro gcpro1
;
4591 black
= build_string ("black");
4593 f
->output_data
.x
->foreground_pixel
4594 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4595 f
->output_data
.x
->background_pixel
4596 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4597 f
->output_data
.x
->cursor_pixel
4598 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4599 f
->output_data
.x
->cursor_foreground_pixel
4600 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4601 f
->output_data
.x
->border_pixel
4602 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4603 f
->output_data
.x
->mouse_pixel
4604 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4608 /* Set the name; the functions to which we pass f expect the name to
4610 if (EQ (name
, Qunbound
) || NILP (name
))
4612 f
->name
= build_string (dpyinfo
->x_id_name
);
4613 f
->explicit_name
= 0;
4618 f
->explicit_name
= 1;
4619 /* use the frame's title when getting resources for this frame. */
4620 specbind (Qx_resource_name
, name
);
4623 /* Extract the window parameters from the supplied values that are
4624 needed to determine window geometry. */
4628 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
4631 /* First, try whatever font the caller has specified. */
4634 tem
= Fquery_fontset (font
, Qnil
);
4636 font
= x_new_fontset (f
, SDATA (tem
));
4638 font
= x_new_font (f
, SDATA (font
));
4641 /* Try out a font which we hope has bold and italic variations. */
4642 if (!STRINGP (font
))
4643 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
4644 if (!STRINGP (font
))
4645 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
4646 if (! STRINGP (font
))
4647 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
4648 if (! STRINGP (font
))
4649 /* This was formerly the first thing tried, but it finds too many fonts
4650 and takes too long. */
4651 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
4652 /* If those didn't work, look for something which will at least work. */
4653 if (! STRINGP (font
))
4654 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
4656 if (! STRINGP (font
))
4657 font
= build_string ("fixed");
4659 x_default_parameter (f
, parms
, Qfont
, font
,
4660 "font", "Font", RES_TYPE_STRING
);
4663 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
4664 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
4666 /* This defaults to 2 in order to match xterm. We recognize either
4667 internalBorderWidth or internalBorder (which is what xterm calls
4669 if (NILP (Fassq (Qinternal_border_width
, parms
)))
4673 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
4674 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
4675 if (! EQ (value
, Qunbound
))
4676 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
4680 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
4681 "internalBorderWidth", "internalBorderWidth",
4684 /* Also do the stuff which must be set before the window exists. */
4685 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
4686 "foreground", "Foreground", RES_TYPE_STRING
);
4687 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
4688 "background", "Background", RES_TYPE_STRING
);
4689 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
4690 "pointerColor", "Foreground", RES_TYPE_STRING
);
4691 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
4692 "cursorColor", "Foreground", RES_TYPE_STRING
);
4693 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
4694 "borderColor", "BorderColor", RES_TYPE_STRING
);
4696 /* Init faces before x_default_parameter is called for scroll-bar
4697 parameters because that function calls x_set_scroll_bar_width,
4698 which calls change_frame_size, which calls Fset_window_buffer,
4699 which runs hooks, which call Fvertical_motion. At the end, we
4700 end up in init_iterator with a null face cache, which should not
4702 init_frame_faces (f
);
4704 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4706 window_prompting
= x_figure_window_size (f
, parms
, 0);
4709 XSetWindowAttributes attrs
;
4713 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
4714 if (DoesSaveUnders (dpyinfo
->screen
))
4715 mask
|= CWSaveUnder
;
4717 /* Window managers look at the override-redirect flag to determine
4718 whether or net to give windows a decoration (Xlib spec, chapter
4720 attrs
.override_redirect
= True
;
4721 attrs
.save_under
= True
;
4722 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
4723 /* Arrange for getting MapNotify and UnmapNotify events. */
4724 attrs
.event_mask
= StructureNotifyMask
;
4726 = FRAME_X_WINDOW (f
)
4727 = XCreateWindow (FRAME_X_DISPLAY (f
),
4728 FRAME_X_DISPLAY_INFO (f
)->root_window
,
4729 /* x, y, width, height */
4733 CopyFromParent
, InputOutput
, CopyFromParent
,
4740 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
4741 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4742 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
4743 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4744 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
4745 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
4747 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4748 Change will not be effected unless different from the current
4750 width
= FRAME_COLS (f
);
4751 height
= FRAME_LINES (f
);
4752 SET_FRAME_COLS (f
, 0);
4753 FRAME_LINES (f
) = 0;
4754 change_frame_size (f
, height
, width
, 1, 0, 0);
4756 /* Add `tooltip' frame parameter's default value. */
4757 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
4758 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
4761 /* Set up faces after all frame parameters are known. This call
4762 also merges in face attributes specified for new frames.
4764 Frame parameters may be changed if .Xdefaults contains
4765 specifications for the default font. For example, if there is an
4766 `Emacs.default.attributeBackground: pink', the `background-color'
4767 attribute of the frame get's set, which let's the internal border
4768 of the tooltip frame appear in pink. Prevent this. */
4770 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
4772 /* Set tip_frame here, so that */
4774 call1 (Qface_set_after_frame_default
, frame
);
4776 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
4777 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qbackground_color
, bg
),
4785 /* It is now ok to make the frame official even if we get an error
4786 below. And the frame needs to be on Vframe_list or making it
4787 visible won't work. */
4788 Vframe_list
= Fcons (frame
, Vframe_list
);
4790 /* Now that the frame is official, it counts as a reference to
4792 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
4794 /* Setting attributes of faces of the tooltip frame from resources
4795 and similar will increment face_change_count, which leads to the
4796 clearing of all current matrices. Since this isn't necessary
4797 here, avoid it by resetting face_change_count to the value it
4798 had before we created the tip frame. */
4799 face_change_count
= face_change_count_before
;
4801 /* Discard the unwind_protect. */
4802 return unbind_to (count
, frame
);
4806 /* Compute where to display tip frame F. PARMS is the list of frame
4807 parameters for F. DX and DY are specified offsets from the current
4808 location of the mouse. WIDTH and HEIGHT are the width and height
4809 of the tooltip. Return coordinates relative to the root window of
4810 the display in *ROOT_X, and *ROOT_Y. */
4813 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, root_x
, root_y
)
4815 Lisp_Object parms
, dx
, dy
;
4817 int *root_x
, *root_y
;
4819 Lisp_Object left
, top
;
4824 /* User-specified position? */
4825 left
= Fcdr (Fassq (Qleft
, parms
));
4826 top
= Fcdr (Fassq (Qtop
, parms
));
4828 /* Move the tooltip window where the mouse pointer is. Resize and
4830 if (!INTEGERP (left
) || !INTEGERP (top
))
4833 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
4834 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
4839 *root_y
= XINT (top
);
4840 else if (*root_y
+ XINT (dy
) - height
< 0)
4841 *root_y
-= XINT (dy
);
4845 *root_y
+= XINT (dy
);
4848 if (INTEGERP (left
))
4849 *root_x
= XINT (left
);
4850 else if (*root_x
+ XINT (dx
) + width
<= FRAME_X_DISPLAY_INFO (f
)->width
)
4851 /* It fits to the right of the pointer. */
4852 *root_x
+= XINT (dx
);
4853 else if (width
+ XINT (dx
) <= *root_x
)
4854 /* It fits to the left of the pointer. */
4855 *root_x
-= width
+ XINT (dx
);
4857 /* Put it left-justified on the screen--it ought to fit that way. */
4862 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
4863 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
4864 A tooltip window is a small X window displaying a string.
4866 FRAME nil or omitted means use the selected frame.
4868 PARMS is an optional list of frame parameters which can be used to
4869 change the tooltip's appearance.
4871 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
4872 means use the default timeout of 5 seconds.
4874 If the list of frame parameters PARAMS contains a `left' parameters,
4875 the tooltip is displayed at that x-position. Otherwise it is
4876 displayed at the mouse position, with offset DX added (default is 5 if
4877 DX isn't specified). Likewise for the y-position; if a `top' frame
4878 parameter is specified, it determines the y-position of the tooltip
4879 window, otherwise it is displayed at the mouse position, with offset
4880 DY added (default is -10).
4882 A tooltip's maximum size is specified by `x-max-tooltip-size'.
4883 Text larger than the specified size is clipped. */)
4884 (string
, frame
, parms
, timeout
, dx
, dy
)
4885 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
4890 struct buffer
*old_buffer
;
4891 struct text_pos pos
;
4892 int i
, width
, height
;
4893 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
4894 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
4895 int count
= SPECPDL_INDEX ();
4897 specbind (Qinhibit_redisplay
, Qt
);
4899 GCPRO4 (string
, parms
, frame
, timeout
);
4901 CHECK_STRING (string
);
4902 f
= check_x_frame (frame
);
4904 timeout
= make_number (5);
4906 CHECK_NATNUM (timeout
);
4909 dx
= make_number (5);
4914 dy
= make_number (-10);
4918 if (NILP (last_show_tip_args
))
4919 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
4921 if (!NILP (tip_frame
))
4923 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
4924 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
4925 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
4927 if (EQ (frame
, last_frame
)
4928 && !NILP (Fequal (last_string
, string
))
4929 && !NILP (Fequal (last_parms
, parms
)))
4931 struct frame
*f
= XFRAME (tip_frame
);
4933 /* Only DX and DY have changed. */
4934 if (!NILP (tip_timer
))
4936 Lisp_Object timer
= tip_timer
;
4938 call1 (Qcancel_timer
, timer
);
4942 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
4943 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
4944 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4951 /* Hide a previous tip, if any. */
4954 ASET (last_show_tip_args
, 0, string
);
4955 ASET (last_show_tip_args
, 1, frame
);
4956 ASET (last_show_tip_args
, 2, parms
);
4958 /* Add default values to frame parameters. */
4959 if (NILP (Fassq (Qname
, parms
)))
4960 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
4961 if (NILP (Fassq (Qinternal_border_width
, parms
)))
4962 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
4963 if (NILP (Fassq (Qborder_width
, parms
)))
4964 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
4965 if (NILP (Fassq (Qborder_color
, parms
)))
4966 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
4967 if (NILP (Fassq (Qbackground_color
, parms
)))
4968 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
4971 /* Create a frame for the tooltip, and record it in the global
4972 variable tip_frame. */
4973 frame
= x_create_tip_frame (FRAME_X_DISPLAY_INFO (f
), parms
, string
);
4976 /* Set up the frame's root window. */
4977 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4978 w
->left_col
= w
->top_line
= make_number (0);
4980 if (CONSP (Vx_max_tooltip_size
)
4981 && INTEGERP (XCAR (Vx_max_tooltip_size
))
4982 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
4983 && INTEGERP (XCDR (Vx_max_tooltip_size
))
4984 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
4986 w
->total_cols
= XCAR (Vx_max_tooltip_size
);
4987 w
->total_lines
= XCDR (Vx_max_tooltip_size
);
4991 w
->total_cols
= make_number (80);
4992 w
->total_lines
= make_number (40);
4995 FRAME_TOTAL_COLS (f
) = XINT (w
->total_cols
);
4997 w
->pseudo_window_p
= 1;
4999 /* Display the tooltip text in a temporary buffer. */
5000 old_buffer
= current_buffer
;
5001 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->buffer
));
5002 current_buffer
->truncate_lines
= Qnil
;
5003 clear_glyph_matrix (w
->desired_matrix
);
5004 clear_glyph_matrix (w
->current_matrix
);
5005 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
5006 try_window (FRAME_ROOT_WINDOW (f
), pos
);
5008 /* Compute width and height of the tooltip. */
5010 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5012 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5016 /* Stop at the first empty row at the end. */
5017 if (!row
->enabled_p
|| !row
->displays_text_p
)
5020 /* Let the row go over the full width of the frame. */
5021 row
->full_width_p
= 1;
5023 /* There's a glyph at the end of rows that is used to place
5024 the cursor there. Don't include the width of this glyph. */
5025 if (row
->used
[TEXT_AREA
])
5027 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5028 row_width
= row
->pixel_width
- last
->pixel_width
;
5031 row_width
= row
->pixel_width
;
5033 height
+= row
->height
;
5034 width
= max (width
, row_width
);
5037 /* Add the frame's internal border to the width and height the X
5038 window should have. */
5039 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5040 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5042 /* Move the tooltip window where the mouse pointer is. Resize and
5044 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5047 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5048 root_x
, root_y
, width
, height
);
5049 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5052 /* Draw into the window. */
5053 w
->must_be_updated_p
= 1;
5054 update_single_window (w
, 1);
5056 /* Restore original current buffer. */
5057 set_buffer_internal_1 (old_buffer
);
5058 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
5061 /* Let the tip disappear after timeout seconds. */
5062 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
5063 intern ("x-hide-tip"));
5066 return unbind_to (count
, Qnil
);
5070 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
5071 doc
: /* Hide the current tooltip window, if there is any.
5072 Value is t if tooltip was open, nil otherwise. */)
5076 Lisp_Object deleted
, frame
, timer
;
5077 struct gcpro gcpro1
, gcpro2
;
5079 /* Return quickly if nothing to do. */
5080 if (NILP (tip_timer
) && NILP (tip_frame
))
5085 GCPRO2 (frame
, timer
);
5086 tip_frame
= tip_timer
= deleted
= Qnil
;
5088 count
= SPECPDL_INDEX ();
5089 specbind (Qinhibit_redisplay
, Qt
);
5090 specbind (Qinhibit_quit
, Qt
);
5093 call1 (Qcancel_timer
, timer
);
5097 Fdelete_frame (frame
, Qnil
);
5101 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5102 redisplay procedure is not called when a tip frame over menu
5103 items is unmapped. Redisplay the menu manually... */
5105 struct frame
*f
= SELECTED_FRAME ();
5106 Widget w
= f
->output_data
.x
->menubar_widget
;
5107 extern void xlwmenu_redisplay
P_ ((Widget
));
5109 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f
)->screen
)
5113 xlwmenu_redisplay (w
);
5117 #endif /* USE_LUCID */
5121 return unbind_to (count
, deleted
);
5126 /***********************************************************************
5127 File selection dialog
5128 ***********************************************************************/
5132 /* Callback for "OK" and "Cancel" on file selection dialog. */
5135 file_dialog_cb (widget
, client_data
, call_data
)
5137 XtPointer call_data
, client_data
;
5139 int *result
= (int *) client_data
;
5140 XmAnyCallbackStruct
*cb
= (XmAnyCallbackStruct
*) call_data
;
5141 *result
= cb
->reason
;
5145 /* Callback for unmapping a file selection dialog. This is used to
5146 capture the case where a dialog is closed via a window manager's
5147 closer button, for example. Using a XmNdestroyCallback didn't work
5151 file_dialog_unmap_cb (widget
, client_data
, call_data
)
5153 XtPointer call_data
, client_data
;
5155 int *result
= (int *) client_data
;
5156 *result
= XmCR_CANCEL
;
5160 clean_up_file_dialog (arg
)
5163 struct Lisp_Save_Value
*p
= XSAVE_VALUE (arg
);
5164 Widget dialog
= (Widget
) p
->pointer
;
5168 XtUnmanageChild (dialog
);
5169 XtDestroyWidget (dialog
);
5170 x_menu_set_in_use (0);
5177 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5178 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5179 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5180 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5181 or directory must exist. ONLY-DIR-P is ignored." */)
5182 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
)
5183 Lisp_Object prompt
, dir
, default_filename
, mustmatch
, only_dir_p
;
5186 struct frame
*f
= SELECTED_FRAME ();
5187 Lisp_Object file
= Qnil
;
5188 Widget dialog
, text
, help
;
5191 extern XtAppContext Xt_app_con
;
5192 XmString dir_xmstring
, pattern_xmstring
;
5193 int count
= SPECPDL_INDEX ();
5194 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
5196 GCPRO6 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
, file
);
5198 if (popup_activated ())
5199 error ("Trying to use a menu from within a menu-entry");
5201 CHECK_STRING (prompt
);
5204 /* Prevent redisplay. */
5205 specbind (Qinhibit_redisplay
, Qt
);
5209 /* Create the dialog with PROMPT as title, using DIR as initial
5210 directory and using "*" as pattern. */
5211 dir
= Fexpand_file_name (dir
, Qnil
);
5212 dir_xmstring
= XmStringCreateLocalized (SDATA (dir
));
5213 pattern_xmstring
= XmStringCreateLocalized ("*");
5215 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
5216 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
5217 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
5218 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
5219 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
5220 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
5222 XmStringFree (dir_xmstring
);
5223 XmStringFree (pattern_xmstring
);
5225 /* Add callbacks for OK and Cancel. */
5226 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
5227 (XtPointer
) &result
);
5228 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
5229 (XtPointer
) &result
);
5230 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
5231 (XtPointer
) &result
);
5233 /* Remove the help button since we can't display help. */
5234 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
5235 XtUnmanageChild (help
);
5237 /* Mark OK button as default. */
5238 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
5239 XmNshowAsDefault
, True
, NULL
);
5241 /* If MUSTMATCH is non-nil, disable the file entry field of the
5242 dialog, so that the user must select a file from the files list
5243 box. We can't remove it because we wouldn't have a way to get at
5244 the result file name, then. */
5245 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
5246 if (!NILP (mustmatch
))
5249 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
5250 XtSetSensitive (text
, False
);
5251 XtSetSensitive (label
, False
);
5254 /* Manage the dialog, so that list boxes get filled. */
5255 XtManageChild (dialog
);
5257 if (STRINGP (default_filename
))
5259 XmString default_xmstring
;
5260 Widget wtext
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
5261 Widget list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
5263 XmTextPosition last_pos
= XmTextFieldGetLastPosition (wtext
);
5264 XmTextFieldReplace (wtext
, 0, last_pos
,
5265 (SDATA (Ffile_name_nondirectory (default_filename
))));
5267 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5268 must include the path for this to work. */
5270 default_xmstring
= XmStringCreateLocalized (SDATA (default_filename
));
5272 if (XmListItemExists (list
, default_xmstring
))
5274 int item_pos
= XmListItemPos (list
, default_xmstring
);
5275 /* Select the item and scroll it into view. */
5276 XmListSelectPos (list
, item_pos
, True
);
5277 XmListSetPos (list
, item_pos
);
5280 XmStringFree (default_xmstring
);
5283 record_unwind_protect (clean_up_file_dialog
, make_save_value (dialog
, 0));
5285 /* Process events until the user presses Cancel or OK. */
5286 x_menu_set_in_use (1);
5291 x_menu_wait_for_event (0);
5292 XtAppNextEvent (Xt_app_con
, &event
);
5293 if (event
.type
== KeyPress
5294 && FRAME_X_DISPLAY (f
) == event
.xkey
.display
)
5296 KeySym keysym
= XLookupKeysym (&event
.xkey
, 0);
5298 /* Pop down on C-g. */
5299 if (keysym
== XK_g
&& (event
.xkey
.state
& ControlMask
) != 0)
5300 XtUnmanageChild (dialog
);
5303 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
));
5306 /* Get the result. */
5307 if (result
== XmCR_OK
)
5312 XtVaGetValues (dialog
, XmNtextString
, &text
, NULL
);
5313 XmStringGetLtoR (text
, XmFONTLIST_DEFAULT_TAG
, &data
);
5314 XmStringFree (text
);
5315 file
= build_string (data
);
5324 /* Make "Cancel" equivalent to C-g. */
5326 Fsignal (Qquit
, Qnil
);
5328 return unbind_to (count
, file
);
5331 #endif /* USE_MOTIF */
5336 clean_up_dialog (arg
)
5339 x_menu_set_in_use (0);
5344 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5345 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5346 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5347 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5348 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5350 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
)
5351 Lisp_Object prompt
, dir
, default_filename
, mustmatch
, only_dir_p
;
5353 FRAME_PTR f
= SELECTED_FRAME ();
5355 Lisp_Object file
= Qnil
;
5356 int count
= SPECPDL_INDEX ();
5357 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
5360 GCPRO6 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
, file
);
5362 if (popup_activated ())
5363 error ("Trying to use a menu from within a menu-entry");
5365 CHECK_STRING (prompt
);
5368 /* Prevent redisplay. */
5369 specbind (Qinhibit_redisplay
, Qt
);
5370 record_unwind_protect (clean_up_dialog
, Qnil
);
5374 if (STRINGP (default_filename
))
5375 cdef_file
= SDATA (default_filename
);
5377 cdef_file
= SDATA (dir
);
5379 fn
= xg_get_file_name (f
, SDATA (prompt
), cdef_file
,
5381 ! NILP (only_dir_p
));
5385 file
= build_string (fn
);
5392 /* Make "Cancel" equivalent to C-g. */
5394 Fsignal (Qquit
, Qnil
);
5396 return unbind_to (count
, file
);
5399 #endif /* USE_GTK */
5402 /***********************************************************************
5404 ***********************************************************************/
5406 #ifdef HAVE_XKBGETKEYBOARD
5407 #include <X11/XKBlib.h>
5408 #include <X11/keysym.h>
5411 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
5412 Sx_backspace_delete_keys_p
, 0, 1, 0,
5413 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5414 FRAME nil means use the selected frame.
5415 Value is t if we know that both keys are present, and are mapped to the
5416 usual X keysyms. */)
5420 #ifdef HAVE_XKBGETKEYBOARD
5422 struct frame
*f
= check_x_frame (frame
);
5423 Display
*dpy
= FRAME_X_DISPLAY (f
);
5424 Lisp_Object have_keys
;
5425 int major
, minor
, op
, event
, error
;
5429 /* Check library version in case we're dynamically linked. */
5430 major
= XkbMajorVersion
;
5431 minor
= XkbMinorVersion
;
5432 if (!XkbLibraryVersion (&major
, &minor
))
5438 /* Check that the server supports XKB. */
5439 major
= XkbMajorVersion
;
5440 minor
= XkbMinorVersion
;
5441 if (!XkbQueryExtension (dpy
, &op
, &event
, &error
, &major
, &minor
))
5447 /* In this code we check that the keyboard has physical keys with names
5448 that start with BKSP (Backspace) and DELE (Delete), and that they
5449 generate keysym XK_BackSpace and XK_Delete respectively.
5450 This function is used to test if normal-erase-is-backspace should be
5452 An alternative approach would be to just check if XK_BackSpace and
5453 XK_Delete are mapped to any key. But if any of those are mapped to
5454 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5455 user doesn't know about it, it is better to return false here.
5456 It is more obvious to the user what to do if she/he has two keys
5457 clearly marked with names/symbols and one key does something not
5458 expected (i.e. she/he then tries the other).
5459 The cases where Backspace/Delete is mapped to some other key combination
5460 are rare, and in those cases, normal-erase-is-backspace can be turned on
5464 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
5467 int delete_keycode
= 0, backspace_keycode
= 0, i
;
5469 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
5471 for (i
= kb
->min_key_code
;
5472 (i
< kb
->max_key_code
5473 && (delete_keycode
== 0 || backspace_keycode
== 0));
5476 /* The XKB symbolic key names can be seen most easily in
5477 the PS file generated by `xkbprint -label name
5479 if (bcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
5481 else if (bcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
5482 backspace_keycode
= i
;
5485 XkbFreeNames (kb
, 0, True
);
5488 XkbFreeClientMap (kb
, 0, True
);
5491 && backspace_keycode
5492 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
5493 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
5498 #else /* not HAVE_XKBGETKEYBOARD */
5500 #endif /* not HAVE_XKBGETKEYBOARD */
5505 /***********************************************************************
5507 ***********************************************************************/
5509 /* Keep this list in the same order as frame_parms in frame.c.
5510 Use 0 for unsupported frame parameters. */
5512 frame_parm_handler x_frame_parm_handlers
[] =
5516 x_set_background_color
,
5522 x_set_foreground_color
,
5525 x_set_internal_border_width
,
5526 x_set_menu_bar_lines
,
5528 x_explicitly_set_name
,
5529 x_set_scroll_bar_width
,
5532 x_set_vertical_scroll_bars
,
5534 x_set_tool_bar_lines
,
5535 x_set_scroll_bar_foreground
,
5536 x_set_scroll_bar_background
,
5548 /* This is zero if not using X windows. */
5551 /* The section below is built by the lisp expression at the top of the file,
5552 just above where these variables are declared. */
5553 /*&&& init symbols here &&&*/
5554 Qnone
= intern ("none");
5556 Qsuppress_icon
= intern ("suppress-icon");
5557 staticpro (&Qsuppress_icon
);
5558 Qundefined_color
= intern ("undefined-color");
5559 staticpro (&Qundefined_color
);
5560 Qcompound_text
= intern ("compound-text");
5561 staticpro (&Qcompound_text
);
5562 Qcancel_timer
= intern ("cancel-timer");
5563 staticpro (&Qcancel_timer
);
5564 /* This is the end of symbol initialization. */
5566 /* Text property `display' should be nonsticky by default. */
5567 Vtext_property_default_nonsticky
5568 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
5571 Fput (Qundefined_color
, Qerror_conditions
,
5572 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
5573 Fput (Qundefined_color
, Qerror_message
,
5574 build_string ("Undefined color"));
5576 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
5577 doc
: /* The shape of the pointer when over text.
5578 Changing the value does not affect existing frames
5579 unless you set the mouse color. */);
5580 Vx_pointer_shape
= Qnil
;
5582 #if 0 /* This doesn't really do anything. */
5583 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
5584 doc
: /* The shape of the pointer when not over text.
5585 This variable takes effect when you create a new frame
5586 or when you set the mouse color. */);
5588 Vx_nontext_pointer_shape
= Qnil
;
5590 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
5591 doc
: /* The shape of the pointer when Emacs is busy.
5592 This variable takes effect when you create a new frame
5593 or when you set the mouse color. */);
5594 Vx_hourglass_pointer_shape
= Qnil
;
5596 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
5597 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
5598 display_hourglass_p
= 1;
5600 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
5601 doc
: /* *Seconds to wait before displaying an hourglass pointer.
5602 Value must be an integer or float. */);
5603 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
5605 #if 0 /* This doesn't really do anything. */
5606 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
5607 doc
: /* The shape of the pointer when over the mode line.
5608 This variable takes effect when you create a new frame
5609 or when you set the mouse color. */);
5611 Vx_mode_pointer_shape
= Qnil
;
5613 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5614 &Vx_sensitive_text_pointer_shape
,
5615 doc
: /* The shape of the pointer when over mouse-sensitive text.
5616 This variable takes effect when you create a new frame
5617 or when you set the mouse color. */);
5618 Vx_sensitive_text_pointer_shape
= Qnil
;
5620 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5621 &Vx_window_horizontal_drag_shape
,
5622 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
5623 This variable takes effect when you create a new frame
5624 or when you set the mouse color. */);
5625 Vx_window_horizontal_drag_shape
= Qnil
;
5627 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
5628 doc
: /* A string indicating the foreground color of the cursor box. */);
5629 Vx_cursor_fore_pixel
= Qnil
;
5631 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size
,
5632 doc
: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
5633 Text larger than this is clipped. */);
5634 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
5636 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
5637 doc
: /* Non-nil if no X window manager is in use.
5638 Emacs doesn't try to figure this out; this is always nil
5639 unless you set it to something else. */);
5640 /* We don't have any way to find this out, so set it to nil
5641 and maybe the user would like to set it to t. */
5642 Vx_no_window_manager
= Qnil
;
5644 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5645 &Vx_pixel_size_width_font_regexp
,
5646 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5648 Since Emacs gets width of a font matching with this regexp from
5649 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5650 such a font. This is especially effective for such large fonts as
5651 Chinese, Japanese, and Korean. */);
5652 Vx_pixel_size_width_font_regexp
= Qnil
;
5654 /* This is not ifdef:ed, so other builds than GTK can customize it. */
5655 DEFVAR_BOOL ("x-use-old-gtk-file-dialog", &x_use_old_gtk_file_dialog
,
5656 doc
: /* *Non-nil means prompt with the old GTK file selection dialog.
5657 If nil or if the file selection dialog is not available, the new GTK file
5658 chooser is used instead. To turn off all file dialogs set the
5659 variable `use-file-dialog'. */);
5660 x_use_old_gtk_file_dialog
= 0;
5662 #ifdef USE_X_TOOLKIT
5663 Fprovide (intern ("x-toolkit"), Qnil
);
5665 Fprovide (intern ("motif"), Qnil
);
5667 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
,
5668 doc
: /* Version info for LessTif/Motif. */);
5669 Vmotif_version_string
= build_string (XmVERSION_STRING
);
5670 #endif /* USE_MOTIF */
5671 #endif /* USE_X_TOOLKIT */
5674 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
5675 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
5676 But for a user it is a toolkit for X, and indeed, configure
5677 accepts --with-x-toolkit=gtk. */
5678 Fprovide (intern ("x-toolkit"), Qnil
);
5679 Fprovide (intern ("gtk"), Qnil
);
5681 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string
,
5682 doc
: /* Version info for GTK+. */);
5684 char gtk_version
[40];
5685 g_snprintf (gtk_version
, sizeof (gtk_version
), "%u.%u.%u",
5686 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
5687 Vgtk_version_string
= build_string (gtk_version
);
5689 #endif /* USE_GTK */
5691 /* X window properties. */
5692 defsubr (&Sx_change_window_property
);
5693 defsubr (&Sx_delete_window_property
);
5694 defsubr (&Sx_window_property
);
5696 defsubr (&Sxw_display_color_p
);
5697 defsubr (&Sx_display_grayscale_p
);
5698 defsubr (&Sxw_color_defined_p
);
5699 defsubr (&Sxw_color_values
);
5700 defsubr (&Sx_server_max_request_size
);
5701 defsubr (&Sx_server_vendor
);
5702 defsubr (&Sx_server_version
);
5703 defsubr (&Sx_display_pixel_width
);
5704 defsubr (&Sx_display_pixel_height
);
5705 defsubr (&Sx_display_mm_width
);
5706 defsubr (&Sx_display_mm_height
);
5707 defsubr (&Sx_display_screens
);
5708 defsubr (&Sx_display_planes
);
5709 defsubr (&Sx_display_color_cells
);
5710 defsubr (&Sx_display_visual_class
);
5711 defsubr (&Sx_display_backing_store
);
5712 defsubr (&Sx_display_save_under
);
5713 defsubr (&Sx_create_frame
);
5714 defsubr (&Sx_open_connection
);
5715 defsubr (&Sx_close_connection
);
5716 defsubr (&Sx_display_list
);
5717 defsubr (&Sx_synchronize
);
5718 defsubr (&Sx_focus_frame
);
5719 defsubr (&Sx_backspace_delete_keys_p
);
5721 /* Setting callback functions for fontset handler. */
5722 get_font_info_func
= x_get_font_info
;
5724 #if 0 /* This function pointer doesn't seem to be used anywhere.
5725 And the pointer assigned has the wrong type, anyway. */
5726 list_fonts_func
= x_list_fonts
;
5729 load_font_func
= x_load_font
;
5730 find_ccl_program_func
= x_find_ccl_program
;
5731 query_font_func
= x_query_font
;
5732 set_frame_fontset_func
= x_set_font
;
5733 check_window_system_func
= check_x
;
5735 hourglass_atimer
= NULL
;
5736 hourglass_shown_p
= 0;
5738 defsubr (&Sx_show_tip
);
5739 defsubr (&Sx_hide_tip
);
5741 staticpro (&tip_timer
);
5743 staticpro (&tip_frame
);
5745 last_show_tip_args
= Qnil
;
5746 staticpro (&last_show_tip_args
);
5748 #if defined (USE_MOTIF) || defined (USE_GTK)
5749 defsubr (&Sx_file_dialog
);
5753 #endif /* HAVE_X_WINDOWS */
5755 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
5756 (do not change this comment) */