1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
30 /* This makes the fields of a Display accessible, in Xlib header files. */
32 #define XLIB_ILLEGAL_ACCESS
39 #include "intervals.h"
40 #include "dispextern.h"
42 #include "blockinput.h"
48 #include "termhooks.h"
54 #include <sys/types.h>
58 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
59 #include "bitmaps/gray.xbm"
61 #include <X11/bitmaps/gray>
64 #include "[.bitmaps]gray.xbm"
72 #include <X11/Shell.h>
76 #include <X11/Xaw3d/Paned.h>
77 #include <X11/Xaw3d/Label.h>
78 #else /* !HAVE_XAW3D */
79 #include <X11/Xaw/Paned.h>
80 #include <X11/Xaw/Label.h>
81 #endif /* HAVE_XAW3D */
82 #endif /* USE_MOTIF */
85 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
94 #include "../lwlib/lwlib.h"
98 #include <Xm/DialogS.h>
99 #include <Xm/FileSB.h>
102 /* Do the EDITRES protocol if running X11R5
103 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
105 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
107 extern void _XEditResCheckMessages ();
108 #endif /* R5 + Athena */
110 /* Unique id counter for widgets created by the Lucid Widget Library. */
112 extern LWLIB_ID widget_id_tick
;
115 /* This is part of a kludge--see lwlib/xlwmenu.c. */
116 extern XFontStruct
*xlwmenu_default_font
;
119 extern void free_frame_menubar ();
120 extern double atof ();
124 /* LessTif/Motif version info. */
126 static Lisp_Object Vmotif_version_string
;
128 #endif /* USE_MOTIF */
130 #endif /* USE_X_TOOLKIT */
134 /* GTK+ version info */
136 static Lisp_Object Vgtk_version_string
;
141 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
143 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
146 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
147 it, and including `bitmaps/gray' more than once is a problem when
148 config.h defines `static' as an empty replacement string. */
150 int gray_bitmap_width
= gray_width
;
151 int gray_bitmap_height
= gray_height
;
152 char *gray_bitmap_bits
= gray_bits
;
154 /* Non-zero means we're allowed to display an hourglass cursor. */
156 int display_hourglass_p
;
158 /* Non-zero means prompt with the old GTK file selection dialog. */
160 int x_gtk_use_old_file_dialog
;
162 /* If non-zero, by default show hidden files in the GTK file chooser. */
164 int x_gtk_show_hidden_files
;
166 /* If non-zero, don't show additional help text in the GTK file chooser. */
168 int x_gtk_file_dialog_help_text
;
170 /* If non-zero, don't collapse to tool bar when it is detached. */
172 int x_gtk_whole_detached_tool_bar
;
174 /* The background and shape of the mouse pointer, and shape when not
175 over text or in the modeline. */
177 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
178 Lisp_Object Vx_hourglass_pointer_shape
;
180 /* The shape when over mouse-sensitive text. */
182 Lisp_Object Vx_sensitive_text_pointer_shape
;
184 /* If non-nil, the pointer shape to indicate that windows can be
185 dragged horizontally. */
187 Lisp_Object Vx_window_horizontal_drag_shape
;
189 /* Color of chars displayed in cursor box. */
191 Lisp_Object Vx_cursor_fore_pixel
;
193 /* Nonzero if using X. */
197 /* Non nil if no window manager is in use. */
199 Lisp_Object Vx_no_window_manager
;
201 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
203 Lisp_Object Vx_pixel_size_width_font_regexp
;
206 Lisp_Object Qsuppress_icon
;
207 Lisp_Object Qundefined_color
;
208 Lisp_Object Qcompound_text
, Qcancel_timer
;
212 extern Lisp_Object Vwindow_system_version
;
214 /* The below are defined in frame.c. */
217 int image_cache_refcount
, dpyinfo_refcount
;
222 /* Error if we are not connected to X. */
228 error ("X windows are not in use or not initialized");
231 /* Nonzero if we can use mouse menus.
232 You should not call this unless HAVE_MENUS is defined. */
240 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
241 and checking validity for X. */
244 check_x_frame (frame
)
250 frame
= selected_frame
;
251 CHECK_LIVE_FRAME (frame
);
254 error ("Non-X frame used");
258 /* Let the user specify an X display with a frame.
259 nil stands for the selected frame--or, if that is not an X frame,
260 the first X display on the list. */
262 struct x_display_info
*
263 check_x_display_info (frame
)
266 struct x_display_info
*dpyinfo
= NULL
;
270 struct frame
*sf
= XFRAME (selected_frame
);
272 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
273 dpyinfo
= FRAME_X_DISPLAY_INFO (sf
);
274 else if (x_display_list
!= 0)
275 dpyinfo
= x_display_list
;
277 error ("X windows are not in use or not initialized");
279 else if (STRINGP (frame
))
280 dpyinfo
= x_display_info_for_name (frame
);
283 FRAME_PTR f
= check_x_frame (frame
);
284 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
291 /* Return the Emacs frame-object corresponding to an X window.
292 It could be the frame's main window or an icon window. */
294 /* This function can be called during GC, so use GC_xxx type test macros. */
297 x_window_to_frame (dpyinfo
, wdesc
)
298 struct x_display_info
*dpyinfo
;
301 Lisp_Object tail
, frame
;
304 if (wdesc
== None
) return 0;
306 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
309 if (!GC_FRAMEP (frame
))
312 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
314 if (f
->output_data
.x
->hourglass_window
== wdesc
)
317 if ((f
->output_data
.x
->edit_widget
318 && XtWindow (f
->output_data
.x
->edit_widget
) == wdesc
)
319 /* A tooltip frame? */
320 || (!f
->output_data
.x
->edit_widget
321 && FRAME_X_WINDOW (f
) == wdesc
)
322 || f
->output_data
.x
->icon_desc
== wdesc
)
324 #else /* not USE_X_TOOLKIT */
326 if (f
->output_data
.x
->edit_widget
)
328 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
329 struct x_output
*x
= f
->output_data
.x
;
330 if (gwdesc
!= 0 && gwdesc
== x
->edit_widget
)
334 if (FRAME_X_WINDOW (f
) == wdesc
335 || f
->output_data
.x
->icon_desc
== wdesc
)
337 #endif /* not USE_X_TOOLKIT */
342 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
343 /* Like x_window_to_frame but also compares the window with the widget's
347 x_any_window_to_frame (dpyinfo
, wdesc
)
348 struct x_display_info
*dpyinfo
;
351 Lisp_Object tail
, frame
;
352 struct frame
*f
, *found
;
355 if (wdesc
== None
) return NULL
;
358 for (tail
= Vframe_list
; GC_CONSP (tail
) && !found
; tail
= XCDR (tail
))
361 if (!GC_FRAMEP (frame
))
365 if (FRAME_X_P (f
) && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
367 /* This frame matches if the window is any of its widgets. */
368 x
= f
->output_data
.x
;
369 if (x
->hourglass_window
== wdesc
)
374 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
376 && (gwdesc
== x
->widget
377 || gwdesc
== x
->edit_widget
378 || gwdesc
== x
->vbox_widget
379 || gwdesc
== x
->menubar_widget
))
382 if (wdesc
== XtWindow (x
->widget
)
383 || wdesc
== XtWindow (x
->column_widget
)
384 || wdesc
== XtWindow (x
->edit_widget
))
386 /* Match if the window is this frame's menubar. */
387 else if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
391 else if (FRAME_X_WINDOW (f
) == wdesc
)
392 /* A tooltip frame. */
400 /* Likewise, but exclude the menu bar widget. */
403 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
404 struct x_display_info
*dpyinfo
;
407 Lisp_Object tail
, frame
;
411 if (wdesc
== None
) return 0;
413 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
416 if (!GC_FRAMEP (frame
))
419 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
421 x
= f
->output_data
.x
;
422 /* This frame matches if the window is any of its widgets. */
423 if (x
->hourglass_window
== wdesc
)
428 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
430 && (gwdesc
== x
->widget
431 || gwdesc
== x
->edit_widget
432 || gwdesc
== x
->vbox_widget
))
435 if (wdesc
== XtWindow (x
->widget
)
436 || wdesc
== XtWindow (x
->column_widget
)
437 || wdesc
== XtWindow (x
->edit_widget
))
441 else if (FRAME_X_WINDOW (f
) == wdesc
)
442 /* A tooltip frame. */
448 /* Likewise, but consider only the menu bar widget. */
451 x_menubar_window_to_frame (dpyinfo
, wdesc
)
452 struct x_display_info
*dpyinfo
;
455 Lisp_Object tail
, frame
;
459 if (wdesc
== None
) return 0;
461 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
464 if (!GC_FRAMEP (frame
))
467 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
469 x
= f
->output_data
.x
;
470 /* Match if the window is this frame's menubar. */
472 if (x
->menubar_widget
)
474 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
479 && (gwdesc
== x
->menubar_widget
480 || gtk_widget_get_parent (gwdesc
) == x
->menubar_widget
))
486 if (x
->menubar_widget
487 && lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
494 /* Return the frame whose principal (outermost) window is WDESC.
495 If WDESC is some other (smaller) window, we return 0. */
498 x_top_window_to_frame (dpyinfo
, wdesc
)
499 struct x_display_info
*dpyinfo
;
502 Lisp_Object tail
, frame
;
506 if (wdesc
== None
) return 0;
508 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
511 if (!GC_FRAMEP (frame
))
514 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
516 x
= f
->output_data
.x
;
520 /* This frame matches if the window is its topmost widget. */
522 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
523 if (gwdesc
== x
->widget
)
526 if (wdesc
== XtWindow (x
->widget
))
528 #if 0 /* I don't know why it did this,
529 but it seems logically wrong,
530 and it causes trouble for MapNotify events. */
531 /* Match if the window is this frame's menubar. */
532 if (x
->menubar_widget
533 && wdesc
== XtWindow (x
->menubar_widget
))
538 else if (FRAME_X_WINDOW (f
) == wdesc
)
544 #endif /* USE_X_TOOLKIT || USE_GTK */
548 static Lisp_Object unwind_create_frame
P_ ((Lisp_Object
));
549 static Lisp_Object unwind_create_tip_frame
P_ ((Lisp_Object
));
551 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
552 static void x_set_wait_for_wm
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
553 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
554 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
555 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
556 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
557 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
558 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
559 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
560 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
561 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
562 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
563 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
564 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
566 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
568 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
575 /* Store the screen positions of frame F into XPTR and YPTR.
576 These are the positions of the containing window manager window,
577 not Emacs's own window. */
580 x_real_positions (f
, xptr
, yptr
)
584 int win_x
, win_y
, outer_x
, outer_y
;
585 int real_x
= 0, real_y
= 0;
587 Window win
= f
->output_data
.x
->parent_desc
;
591 x_catch_errors (FRAME_X_DISPLAY (f
));
593 if (win
== FRAME_X_DISPLAY_INFO (f
)->root_window
)
594 win
= FRAME_OUTER_WINDOW (f
);
596 /* This loop traverses up the containment tree until we hit the root
597 window. Window managers may intersect many windows between our window
598 and the root window. The window we find just before the root window
599 should be the outer WM window. */
602 Window wm_window
, rootw
;
603 Window
*tmp_children
;
604 unsigned int tmp_nchildren
;
607 success
= XQueryTree (FRAME_X_DISPLAY (f
), win
, &rootw
,
608 &wm_window
, &tmp_children
, &tmp_nchildren
);
610 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
612 /* Don't free tmp_children if XQueryTree failed. */
616 XFree ((char *) tmp_children
);
618 if (wm_window
== rootw
|| had_errors
)
629 /* Get the real coordinates for the WM window upper left corner */
630 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
631 &rootw
, &real_x
, &real_y
, &ign
, &ign
, &ign
, &ign
);
633 /* Translate real coordinates to coordinates relative to our
634 window. For our window, the upper left corner is 0, 0.
635 Since the upper left corner of the WM window is outside
636 our window, win_x and win_y will be negative:
638 ------------------ ---> x
640 | ----------------- v y
643 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
645 /* From-window, to-window. */
646 FRAME_X_DISPLAY_INFO (f
)->root_window
,
649 /* From-position, to-position. */
650 real_x
, real_y
, &win_x
, &win_y
,
655 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
662 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
664 /* From-window, to-window. */
665 FRAME_X_DISPLAY_INFO (f
)->root_window
,
666 FRAME_OUTER_WINDOW (f
),
668 /* From-position, to-position. */
669 real_x
, real_y
, &outer_x
, &outer_y
,
675 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
682 if (had_errors
) return;
684 f
->x_pixels_diff
= -win_x
;
685 f
->y_pixels_diff
= -win_y
;
687 FRAME_X_OUTPUT (f
)->x_pixels_outer_diff
= -outer_x
;
688 FRAME_X_OUTPUT (f
)->y_pixels_outer_diff
= -outer_y
;
697 /* Gamma-correct COLOR on frame F. */
700 gamma_correct (f
, color
)
706 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
707 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
708 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
713 /* Decide if color named COLOR_NAME is valid for use on frame F. If
714 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
715 allocate the color. Value is zero if COLOR_NAME is invalid, or
716 no color could be allocated. */
719 x_defined_color (f
, color_name
, color
, alloc_p
)
726 Display
*dpy
= FRAME_X_DISPLAY (f
);
727 Colormap cmap
= FRAME_X_COLORMAP (f
);
730 success_p
= XParseColor (dpy
, cmap
, color_name
, color
);
731 if (success_p
&& alloc_p
)
732 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
739 /* Return the pixel color value for color COLOR_NAME on frame F. If F
740 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
741 Signal an error if color can't be allocated. */
744 x_decode_color (f
, color_name
, mono_color
)
746 Lisp_Object color_name
;
751 CHECK_STRING (color_name
);
753 #if 0 /* Don't do this. It's wrong when we're not using the default
754 colormap, it makes freeing difficult, and it's probably not
755 an important optimization. */
756 if (strcmp (SDATA (color_name
), "black") == 0)
757 return BLACK_PIX_DEFAULT (f
);
758 else if (strcmp (SDATA (color_name
), "white") == 0)
759 return WHITE_PIX_DEFAULT (f
);
762 /* Return MONO_COLOR for monochrome frames. */
763 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
766 /* x_defined_color is responsible for coping with failures
767 by looking for a near-miss. */
768 if (x_defined_color (f
, SDATA (color_name
), &cdef
, 1))
771 signal_error ("Undefined color", color_name
);
776 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
777 the previous value of that parameter, NEW_VALUE is the new value.
778 See also the comment of wait_for_wm in struct x_output. */
781 x_set_wait_for_wm (f
, new_value
, old_value
)
783 Lisp_Object new_value
, old_value
;
785 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
790 /* Set icon from FILE for frame F. By using GTK functions the icon
791 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
794 xg_set_icon (f
, file
)
801 found
= x_find_image_file (file
);
807 char *filename
= (char *) SDATA (found
);
810 pixbuf
= gdk_pixbuf_new_from_file (filename
, &err
);
814 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
816 g_object_unref (pixbuf
);
830 xg_set_icon_from_xpm_data (f
, data
)
835 GdkPixbuf
*pixbuf
= gdk_pixbuf_new_from_xpm_data ((const char **) data
);
840 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)), pixbuf
);
841 g_object_unref (pixbuf
);
847 /* Functions called only from `x_set_frame_param'
848 to set individual parameters.
850 If FRAME_X_WINDOW (f) is 0,
851 the frame is being created and its X-window does not exist yet.
852 In that case, just record the parameter's new value
853 in the standard place; do not attempt to change the window. */
856 x_set_foreground_color (f
, arg
, oldval
)
858 Lisp_Object arg
, oldval
;
860 struct x_output
*x
= f
->output_data
.x
;
861 unsigned long fg
, old_fg
;
863 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
864 old_fg
= x
->foreground_pixel
;
865 x
->foreground_pixel
= fg
;
867 if (FRAME_X_WINDOW (f
) != 0)
869 Display
*dpy
= FRAME_X_DISPLAY (f
);
872 XSetForeground (dpy
, x
->normal_gc
, fg
);
873 XSetBackground (dpy
, x
->reverse_gc
, fg
);
875 if (x
->cursor_pixel
== old_fg
)
877 unload_color (f
, x
->cursor_pixel
);
878 x
->cursor_pixel
= x_copy_color (f
, fg
);
879 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
884 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
886 if (FRAME_VISIBLE_P (f
))
890 unload_color (f
, old_fg
);
894 x_set_background_color (f
, arg
, oldval
)
896 Lisp_Object arg
, oldval
;
898 struct x_output
*x
= f
->output_data
.x
;
901 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
902 unload_color (f
, x
->background_pixel
);
903 x
->background_pixel
= bg
;
905 if (FRAME_X_WINDOW (f
) != 0)
907 Display
*dpy
= FRAME_X_DISPLAY (f
);
910 XSetBackground (dpy
, x
->normal_gc
, bg
);
911 XSetForeground (dpy
, x
->reverse_gc
, bg
);
912 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
913 XSetForeground (dpy
, x
->cursor_gc
, bg
);
916 xg_set_background_color (f
, bg
);
919 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
920 toolkit scroll bars. */
923 for (bar
= FRAME_SCROLL_BARS (f
);
925 bar
= XSCROLL_BAR (bar
)->next
)
927 Window window
= SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
));
928 XSetWindowBackground (dpy
, window
, bg
);
931 #endif /* USE_TOOLKIT_SCROLL_BARS */
934 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
936 if (FRAME_VISIBLE_P (f
))
942 x_set_mouse_color (f
, arg
, oldval
)
944 Lisp_Object arg
, oldval
;
946 struct x_output
*x
= f
->output_data
.x
;
947 Display
*dpy
= FRAME_X_DISPLAY (f
);
948 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
949 Cursor hourglass_cursor
, horizontal_drag_cursor
;
950 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
951 unsigned long mask_color
= x
->background_pixel
;
953 /* Don't let pointers be invisible. */
954 if (mask_color
== pixel
)
956 x_free_colors (f
, &pixel
, 1);
957 pixel
= x_copy_color (f
, x
->foreground_pixel
);
960 unload_color (f
, x
->mouse_pixel
);
961 x
->mouse_pixel
= pixel
;
965 /* It's not okay to crash if the user selects a screwy cursor. */
966 x_catch_errors (dpy
);
968 if (!NILP (Vx_pointer_shape
))
970 CHECK_NUMBER (Vx_pointer_shape
);
971 cursor
= XCreateFontCursor (dpy
, XINT (Vx_pointer_shape
));
974 cursor
= XCreateFontCursor (dpy
, XC_xterm
);
975 x_check_errors (dpy
, "bad text pointer cursor: %s");
977 if (!NILP (Vx_nontext_pointer_shape
))
979 CHECK_NUMBER (Vx_nontext_pointer_shape
);
981 = XCreateFontCursor (dpy
, XINT (Vx_nontext_pointer_shape
));
984 nontext_cursor
= XCreateFontCursor (dpy
, XC_left_ptr
);
985 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
987 if (!NILP (Vx_hourglass_pointer_shape
))
989 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
991 = XCreateFontCursor (dpy
, XINT (Vx_hourglass_pointer_shape
));
994 hourglass_cursor
= XCreateFontCursor (dpy
, XC_watch
);
995 x_check_errors (dpy
, "bad hourglass pointer cursor: %s");
997 if (!NILP (Vx_mode_pointer_shape
))
999 CHECK_NUMBER (Vx_mode_pointer_shape
);
1000 mode_cursor
= XCreateFontCursor (dpy
, XINT (Vx_mode_pointer_shape
));
1003 mode_cursor
= XCreateFontCursor (dpy
, XC_xterm
);
1004 x_check_errors (dpy
, "bad modeline pointer cursor: %s");
1006 if (!NILP (Vx_sensitive_text_pointer_shape
))
1008 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
1010 = XCreateFontCursor (dpy
, XINT (Vx_sensitive_text_pointer_shape
));
1013 hand_cursor
= XCreateFontCursor (dpy
, XC_hand2
);
1015 if (!NILP (Vx_window_horizontal_drag_shape
))
1017 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
1018 horizontal_drag_cursor
1019 = XCreateFontCursor (dpy
, XINT (Vx_window_horizontal_drag_shape
));
1022 horizontal_drag_cursor
1023 = XCreateFontCursor (dpy
, XC_sb_h_double_arrow
);
1025 /* Check and report errors with the above calls. */
1026 x_check_errors (dpy
, "can't set cursor shape: %s");
1027 x_uncatch_errors ();
1030 XColor fore_color
, back_color
;
1032 fore_color
.pixel
= x
->mouse_pixel
;
1033 x_query_color (f
, &fore_color
);
1034 back_color
.pixel
= mask_color
;
1035 x_query_color (f
, &back_color
);
1037 XRecolorCursor (dpy
, cursor
, &fore_color
, &back_color
);
1038 XRecolorCursor (dpy
, nontext_cursor
, &fore_color
, &back_color
);
1039 XRecolorCursor (dpy
, mode_cursor
, &fore_color
, &back_color
);
1040 XRecolorCursor (dpy
, hand_cursor
, &fore_color
, &back_color
);
1041 XRecolorCursor (dpy
, hourglass_cursor
, &fore_color
, &back_color
);
1042 XRecolorCursor (dpy
, horizontal_drag_cursor
, &fore_color
, &back_color
);
1045 if (FRAME_X_WINDOW (f
) != 0)
1046 XDefineCursor (dpy
, FRAME_X_WINDOW (f
), cursor
);
1048 if (cursor
!= x
->text_cursor
1049 && x
->text_cursor
!= 0)
1050 XFreeCursor (dpy
, x
->text_cursor
);
1051 x
->text_cursor
= cursor
;
1053 if (nontext_cursor
!= x
->nontext_cursor
1054 && x
->nontext_cursor
!= 0)
1055 XFreeCursor (dpy
, x
->nontext_cursor
);
1056 x
->nontext_cursor
= nontext_cursor
;
1058 if (hourglass_cursor
!= x
->hourglass_cursor
1059 && x
->hourglass_cursor
!= 0)
1060 XFreeCursor (dpy
, x
->hourglass_cursor
);
1061 x
->hourglass_cursor
= hourglass_cursor
;
1063 if (mode_cursor
!= x
->modeline_cursor
1064 && x
->modeline_cursor
!= 0)
1065 XFreeCursor (dpy
, f
->output_data
.x
->modeline_cursor
);
1066 x
->modeline_cursor
= mode_cursor
;
1068 if (hand_cursor
!= x
->hand_cursor
1069 && x
->hand_cursor
!= 0)
1070 XFreeCursor (dpy
, x
->hand_cursor
);
1071 x
->hand_cursor
= hand_cursor
;
1073 if (horizontal_drag_cursor
!= x
->horizontal_drag_cursor
1074 && x
->horizontal_drag_cursor
!= 0)
1075 XFreeCursor (dpy
, x
->horizontal_drag_cursor
);
1076 x
->horizontal_drag_cursor
= horizontal_drag_cursor
;
1081 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1085 x_set_cursor_color (f
, arg
, oldval
)
1087 Lisp_Object arg
, oldval
;
1089 unsigned long fore_pixel
, pixel
;
1090 int fore_pixel_allocated_p
= 0, pixel_allocated_p
= 0;
1091 struct x_output
*x
= f
->output_data
.x
;
1093 if (!NILP (Vx_cursor_fore_pixel
))
1095 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1096 WHITE_PIX_DEFAULT (f
));
1097 fore_pixel_allocated_p
= 1;
1100 fore_pixel
= x
->background_pixel
;
1102 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1103 pixel_allocated_p
= 1;
1105 /* Make sure that the cursor color differs from the background color. */
1106 if (pixel
== x
->background_pixel
)
1108 if (pixel_allocated_p
)
1110 x_free_colors (f
, &pixel
, 1);
1111 pixel_allocated_p
= 0;
1114 pixel
= x
->mouse_pixel
;
1115 if (pixel
== fore_pixel
)
1117 if (fore_pixel_allocated_p
)
1119 x_free_colors (f
, &fore_pixel
, 1);
1120 fore_pixel_allocated_p
= 0;
1122 fore_pixel
= x
->background_pixel
;
1126 unload_color (f
, x
->cursor_foreground_pixel
);
1127 if (!fore_pixel_allocated_p
)
1128 fore_pixel
= x_copy_color (f
, fore_pixel
);
1129 x
->cursor_foreground_pixel
= fore_pixel
;
1131 unload_color (f
, x
->cursor_pixel
);
1132 if (!pixel_allocated_p
)
1133 pixel
= x_copy_color (f
, pixel
);
1134 x
->cursor_pixel
= pixel
;
1136 if (FRAME_X_WINDOW (f
) != 0)
1139 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
1140 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
1143 if (FRAME_VISIBLE_P (f
))
1145 x_update_cursor (f
, 0);
1146 x_update_cursor (f
, 1);
1150 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1153 /* Set the border-color of frame F to pixel value PIX.
1154 Note that this does not fully take effect if done before
1155 F has an x-window. */
1158 x_set_border_pixel (f
, pix
)
1162 unload_color (f
, f
->output_data
.x
->border_pixel
);
1163 f
->output_data
.x
->border_pixel
= pix
;
1165 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
1168 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1169 (unsigned long)pix
);
1172 if (FRAME_VISIBLE_P (f
))
1177 /* Set the border-color of frame F to value described by ARG.
1178 ARG can be a string naming a color.
1179 The border-color is used for the border that is drawn by the X server.
1180 Note that this does not fully take effect if done before
1181 F has an x-window; it must be redone when the window is created.
1183 Note: this is done in two routines because of the way X10 works.
1185 Note: under X11, this is normally the province of the window manager,
1186 and so emacs' border colors may be overridden. */
1189 x_set_border_color (f
, arg
, oldval
)
1191 Lisp_Object arg
, oldval
;
1196 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1197 x_set_border_pixel (f
, pix
);
1198 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1203 x_set_cursor_type (f
, arg
, oldval
)
1205 Lisp_Object arg
, oldval
;
1207 set_frame_cursor_types (f
, arg
);
1209 /* Make sure the cursor gets redrawn. */
1210 cursor_type_changed
= 1;
1214 x_set_icon_type (f
, arg
, oldval
)
1216 Lisp_Object arg
, oldval
;
1222 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1225 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1230 result
= x_text_icon (f
,
1231 (char *) SDATA ((!NILP (f
->icon_name
)
1235 result
= x_bitmap_icon (f
, arg
);
1240 error ("No icon window available");
1243 XFlush (FRAME_X_DISPLAY (f
));
1248 x_set_icon_name (f
, arg
, oldval
)
1250 Lisp_Object arg
, oldval
;
1256 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1259 else if (!NILP (arg
) || NILP (oldval
))
1264 if (f
->output_data
.x
->icon_bitmap
!= 0)
1269 result
= x_text_icon (f
,
1270 (char *) SDATA ((!NILP (f
->icon_name
)
1279 error ("No icon window available");
1282 XFlush (FRAME_X_DISPLAY (f
));
1288 x_set_menu_bar_lines (f
, value
, oldval
)
1290 Lisp_Object value
, oldval
;
1293 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1294 int olines
= FRAME_MENU_BAR_LINES (f
);
1297 /* Right now, menu bars don't work properly in minibuf-only frames;
1298 most of the commands try to apply themselves to the minibuffer
1299 frame itself, and get an error because you can't switch buffers
1300 in or split the minibuffer window. */
1301 if (FRAME_MINIBUF_ONLY_P (f
))
1304 if (INTEGERP (value
))
1305 nlines
= XINT (value
);
1309 /* Make sure we redisplay all windows in this frame. */
1310 windows_or_buffers_changed
++;
1312 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1313 FRAME_MENU_BAR_LINES (f
) = 0;
1316 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1317 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1318 /* Make sure next redisplay shows the menu bar. */
1319 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1323 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1324 free_frame_menubar (f
);
1325 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1327 f
->output_data
.x
->menubar_widget
= 0;
1329 #else /* not USE_X_TOOLKIT && not USE_GTK */
1330 FRAME_MENU_BAR_LINES (f
) = nlines
;
1331 change_window_heights (f
->root_window
, nlines
- olines
);
1332 #endif /* not USE_X_TOOLKIT */
1337 /* Set the number of lines used for the tool bar of frame F to VALUE.
1338 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1339 is the old number of tool bar lines. This function changes the
1340 height of all windows on frame F to match the new tool bar height.
1341 The frame's height doesn't change. */
1344 x_set_tool_bar_lines (f
, value
, oldval
)
1346 Lisp_Object value
, oldval
;
1348 int delta
, nlines
, root_height
;
1349 Lisp_Object root_window
;
1351 /* Treat tool bars like menu bars. */
1352 if (FRAME_MINIBUF_ONLY_P (f
))
1355 /* Use VALUE only if an integer >= 0. */
1356 if (INTEGERP (value
) && XINT (value
) >= 0)
1357 nlines
= XFASTINT (value
);
1362 FRAME_TOOL_BAR_LINES (f
) = 0;
1365 FRAME_EXTERNAL_TOOL_BAR (f
) = 1;
1366 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1367 /* Make sure next redisplay shows the tool bar. */
1368 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1369 update_frame_tool_bar (f
);
1373 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1374 free_frame_tool_bar (f
);
1375 FRAME_EXTERNAL_TOOL_BAR (f
) = 0;
1381 /* Make sure we redisplay all windows in this frame. */
1382 ++windows_or_buffers_changed
;
1384 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
1386 /* Don't resize the tool-bar to more than we have room for. */
1387 root_window
= FRAME_ROOT_WINDOW (f
);
1388 root_height
= WINDOW_TOTAL_LINES (XWINDOW (root_window
));
1389 if (root_height
- delta
< 1)
1391 delta
= root_height
- 1;
1392 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
1395 FRAME_TOOL_BAR_LINES (f
) = nlines
;
1396 change_window_heights (root_window
, delta
);
1399 /* We also have to make sure that the internal border at the top of
1400 the frame, below the menu bar or tool bar, is redrawn when the
1401 tool bar disappears. This is so because the internal border is
1402 below the tool bar if one is displayed, but is below the menu bar
1403 if there isn't a tool bar. The tool bar draws into the area
1404 below the menu bar. */
1405 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
1409 clear_current_matrices (f
);
1410 updating_frame
= NULL
;
1413 /* If the tool bar gets smaller, the internal border below it
1414 has to be cleared. It was formerly part of the display
1415 of the larger tool bar, and updating windows won't clear it. */
1418 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1419 int width
= FRAME_PIXEL_WIDTH (f
);
1420 int y
= nlines
* FRAME_LINE_HEIGHT (f
);
1422 /* height can be zero here. */
1423 if (height
> 0 && width
> 0)
1426 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1427 0, y
, width
, height
, False
);
1431 if (WINDOWP (f
->tool_bar_window
))
1432 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1437 /* Set the foreground color for scroll bars on frame F to VALUE.
1438 VALUE should be a string, a color name. If it isn't a string or
1439 isn't a valid color name, do nothing. OLDVAL is the old value of
1440 the frame parameter. */
1443 x_set_scroll_bar_foreground (f
, value
, oldval
)
1445 Lisp_Object value
, oldval
;
1447 unsigned long pixel
;
1449 if (STRINGP (value
))
1450 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1454 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1455 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1457 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1458 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1460 /* Remove all scroll bars because they have wrong colors. */
1461 if (condemn_scroll_bars_hook
)
1462 (*condemn_scroll_bars_hook
) (f
);
1463 if (judge_scroll_bars_hook
)
1464 (*judge_scroll_bars_hook
) (f
);
1466 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1472 /* Set the background color for scroll bars on frame F to VALUE VALUE
1473 should be a string, a color name. If it isn't a string or isn't a
1474 valid color name, do nothing. OLDVAL is the old value of the frame
1478 x_set_scroll_bar_background (f
, value
, oldval
)
1480 Lisp_Object value
, oldval
;
1482 unsigned long pixel
;
1484 if (STRINGP (value
))
1485 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1489 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1490 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1492 #ifdef USE_TOOLKIT_SCROLL_BARS
1493 /* Scrollbar shadow colors. */
1494 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1496 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1497 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1499 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1501 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1502 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1504 #endif /* USE_TOOLKIT_SCROLL_BARS */
1506 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1507 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1509 /* Remove all scroll bars because they have wrong colors. */
1510 if (condemn_scroll_bars_hook
)
1511 (*condemn_scroll_bars_hook
) (f
);
1512 if (judge_scroll_bars_hook
)
1513 (*judge_scroll_bars_hook
) (f
);
1515 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1521 /* Encode Lisp string STRING as a text in a format appropriate for
1522 XICCC (X Inter Client Communication Conventions).
1524 This can call Lisp code, so callers must GCPRO.
1526 If STRING contains only ASCII characters, do no conversion and
1527 return the string data of STRING. Otherwise, encode the text by
1528 CODING_SYSTEM, and return a newly allocated memory area which
1529 should be freed by `xfree' by a caller.
1531 SELECTIONP non-zero means the string is being encoded for an X
1532 selection, so it is safe to run pre-write conversions (which
1535 Store the byte length of resulting text in *TEXT_BYTES.
1537 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1538 which means that the `encoding' of the result can be `STRING'.
1539 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1540 the result should be `COMPOUND_TEXT'. */
1542 static unsigned char *
1543 x_encode_text (string
, coding_system
, selectionp
, text_bytes
, stringp
, freep
)
1544 Lisp_Object string
, coding_system
;
1545 int *text_bytes
, *stringp
;
1549 unsigned char *str
= SDATA (string
);
1550 int chars
= SCHARS (string
);
1551 int bytes
= SBYTES (string
);
1555 struct coding_system coding
;
1556 extern Lisp_Object Qcompound_text_with_extensions
;
1558 charset_info
= find_charset_in_text (str
, chars
, bytes
, NULL
, Qnil
);
1559 if (charset_info
== 0)
1561 /* No multibyte character in OBJ. We need not encode it. */
1562 *text_bytes
= bytes
;
1568 setup_coding_system (coding_system
, &coding
);
1570 && SYMBOLP (coding
.pre_write_conversion
)
1571 && !NILP (Ffboundp (coding
.pre_write_conversion
)))
1573 struct gcpro gcpro1
;
1574 /* We don't need to GCPRO string. */
1575 GCPRO1 (coding_system
);
1576 string
= run_pre_post_conversion_on_str (string
, &coding
, 1);
1578 str
= SDATA (string
);
1579 chars
= SCHARS (string
);
1580 bytes
= SBYTES (string
);
1582 coding
.src_multibyte
= 1;
1583 coding
.dst_multibyte
= 0;
1584 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1585 if (coding
.type
== coding_type_iso2022
)
1586 coding
.flags
|= CODING_FLAG_ISO_SAFE
;
1587 /* We suppress producing escape sequences for composition. */
1588 coding
.composing
= COMPOSITION_DISABLED
;
1589 bufsize
= encoding_buffer_size (&coding
, bytes
);
1590 buf
= (unsigned char *) xmalloc (bufsize
);
1591 encode_coding (&coding
, str
, buf
, bytes
, bufsize
);
1592 *text_bytes
= coding
.produced
;
1593 *stringp
= (charset_info
== 1
1594 || (!EQ (coding_system
, Qcompound_text
)
1595 && !EQ (coding_system
, Qcompound_text_with_extensions
)));
1601 /* Set the WM name to NAME for frame F. Also set the icon name.
1602 If the frame already has an icon name, use that, otherwise set the
1603 icon name to NAME. */
1606 x_set_name_internal (f
, name
)
1610 if (FRAME_X_WINDOW (f
))
1615 XTextProperty text
, icon
;
1617 int do_free_icon_value
= 0, do_free_text_value
= 0;
1618 Lisp_Object coding_system
;
1620 Lisp_Object encoded_name
;
1621 struct gcpro gcpro1
;
1623 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1624 we use it before x_encode_text that may return string data. */
1626 encoded_name
= ENCODE_UTF_8 (name
);
1630 coding_system
= Qcompound_text
;
1631 /* Note: Encoding strategy
1633 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1634 text.encoding. But, there are non-internationalized window
1635 managers which don't support that encoding. So, if NAME
1636 contains only ASCII and 8859-1 characters, encode it by
1637 iso-latin-1, and use "STRING" in text.encoding hoping that
1638 such window managers at least analyze this format correctly,
1639 i.e. treat 8-bit bytes as 8859-1 characters.
1641 We may also be able to use "UTF8_STRING" in text.encoding
1642 in the future which can encode all Unicode characters.
1643 But, for the moment, there's no way to know that the
1644 current window manager supports it or not. */
1645 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
,
1646 &do_free_text_value
);
1647 text
.encoding
= (stringp
? XA_STRING
1648 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1650 text
.nitems
= bytes
;
1652 if (!STRINGP (f
->icon_name
))
1658 /* See the above comment "Note: Encoding strategy". */
1659 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
1660 &bytes
, &stringp
, &do_free_icon_value
);
1661 icon
.encoding
= (stringp
? XA_STRING
1662 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1664 icon
.nitems
= bytes
;
1668 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1669 (char *) SDATA (encoded_name
));
1670 #else /* not USE_GTK */
1671 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1672 #endif /* not USE_GTK */
1674 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1676 if (do_free_icon_value
)
1678 if (do_free_text_value
)
1681 #else /* not HAVE_X11R4 */
1682 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1684 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1686 #endif /* not HAVE_X11R4 */
1691 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1694 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1695 name; if NAME is a string, set F's name to NAME and set
1696 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1698 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1699 suggesting a new name, which lisp code should override; if
1700 F->explicit_name is set, ignore the new name; otherwise, set it. */
1703 x_set_name (f
, name
, explicit)
1708 /* Make sure that requests from lisp code override requests from
1709 Emacs redisplay code. */
1712 /* If we're switching from explicit to implicit, we had better
1713 update the mode lines and thereby update the title. */
1714 if (f
->explicit_name
&& NILP (name
))
1715 update_mode_lines
= 1;
1717 f
->explicit_name
= ! NILP (name
);
1719 else if (f
->explicit_name
)
1722 /* If NAME is nil, set the name to the x_id_name. */
1725 /* Check for no change needed in this very common case
1726 before we do any consing. */
1727 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1730 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1733 CHECK_STRING (name
);
1735 /* Don't change the name if it's already NAME. */
1736 if (! NILP (Fstring_equal (name
, f
->name
)))
1741 /* For setting the frame title, the title parameter should override
1742 the name parameter. */
1743 if (! NILP (f
->title
))
1746 x_set_name_internal (f
, name
);
1749 /* This function should be called when the user's lisp code has
1750 specified a name for the frame; the name will override any set by the
1753 x_explicitly_set_name (f
, arg
, oldval
)
1755 Lisp_Object arg
, oldval
;
1757 x_set_name (f
, arg
, 1);
1760 /* This function should be called by Emacs redisplay code to set the
1761 name; names set this way will never override names set by the user's
1764 x_implicitly_set_name (f
, arg
, oldval
)
1766 Lisp_Object arg
, oldval
;
1768 x_set_name (f
, arg
, 0);
1771 /* Change the title of frame F to NAME.
1772 If NAME is nil, use the frame name as the title.
1774 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1775 name; if NAME is a string, set F's name to NAME and set
1776 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1778 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1779 suggesting a new name, which lisp code should override; if
1780 F->explicit_name is set, ignore the new name; otherwise, set it. */
1783 x_set_title (f
, name
, old_name
)
1785 Lisp_Object name
, old_name
;
1787 /* Don't change the title if it's already NAME. */
1788 if (EQ (name
, f
->title
))
1791 update_mode_lines
= 1;
1798 CHECK_STRING (name
);
1800 x_set_name_internal (f
, name
);
1804 x_set_scroll_bar_default_width (f
)
1807 int wid
= FRAME_COLUMN_WIDTH (f
);
1809 #ifdef USE_TOOLKIT_SCROLL_BARS
1810 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1811 int width
= 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
1812 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (width
+ wid
- 1) / wid
;
1813 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = width
;
1815 /* Make the actual width at least 14 pixels and a multiple of a
1817 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
1819 /* Use all of that space (aside from required margins) for the
1821 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = 0;
1826 /* Record in frame F the specified or default value according to ALIST
1827 of the parameter named PROP (a Lisp symbol). If no value is
1828 specified for PROP, look for an X default for XPROP on the frame
1829 named NAME. If that is not found either, use the value DEFLT. */
1832 x_default_scroll_bar_color_parameter (f
, alist
, prop
, xprop
, xclass
,
1841 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
1844 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
1845 if (EQ (tem
, Qunbound
))
1847 #ifdef USE_TOOLKIT_SCROLL_BARS
1849 /* See if an X resource for the scroll bar color has been
1851 tem
= display_x_get_resource (dpyinfo
,
1852 build_string (foreground_p
1855 empty_unibyte_string
,
1856 build_string ("verticalScrollBar"),
1857 empty_unibyte_string
);
1860 /* If nothing has been specified, scroll bars will use a
1861 toolkit-dependent default. Because these defaults are
1862 difficult to get at without actually creating a scroll
1863 bar, use nil to indicate that no color has been
1868 #else /* not USE_TOOLKIT_SCROLL_BARS */
1872 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1875 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
1881 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
1884 XSetWMProtocols (dpy
, w
, protocols
, count
)
1891 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
1892 if (prop
== None
) return False
;
1893 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
1894 (unsigned char *) protocols
, count
);
1897 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
1899 #ifdef USE_X_TOOLKIT
1901 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1902 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1903 already be present because of the toolkit (Motif adds some of them,
1904 for example, but Xt doesn't). */
1907 hack_wm_protocols (f
, widget
)
1911 Display
*dpy
= XtDisplay (widget
);
1912 Window w
= XtWindow (widget
);
1913 int need_delete
= 1;
1920 unsigned char *catoms
;
1922 unsigned long nitems
= 0;
1923 unsigned long bytes_after
;
1925 if ((XGetWindowProperty (dpy
, w
,
1926 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1927 (long)0, (long)100, False
, XA_ATOM
,
1928 &type
, &format
, &nitems
, &bytes_after
,
1931 && format
== 32 && type
== XA_ATOM
)
1933 Atom
*atoms
= (Atom
*) catoms
;
1938 == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
1940 else if (atoms
[nitems
]
1941 == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
1943 else if (atoms
[nitems
]
1944 == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
1955 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
1957 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
1959 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
1961 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1962 XA_ATOM
, 32, PropModeAppend
,
1963 (unsigned char *) props
, count
);
1971 /* Support routines for XIC (X Input Context). */
1975 static XFontSet xic_create_xfontset
P_ ((struct frame
*, char *));
1976 static XIMStyle best_xim_style
P_ ((XIMStyles
*, XIMStyles
*));
1979 /* Supported XIM styles, ordered by preference. */
1981 static XIMStyle supported_xim_styles
[] =
1983 XIMPreeditPosition
| XIMStatusArea
,
1984 XIMPreeditPosition
| XIMStatusNothing
,
1985 XIMPreeditPosition
| XIMStatusNone
,
1986 XIMPreeditNothing
| XIMStatusArea
,
1987 XIMPreeditNothing
| XIMStatusNothing
,
1988 XIMPreeditNothing
| XIMStatusNone
,
1989 XIMPreeditNone
| XIMStatusArea
,
1990 XIMPreeditNone
| XIMStatusNothing
,
1991 XIMPreeditNone
| XIMStatusNone
,
1996 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1998 char xic_defaut_fontset
[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2000 /* Create an Xt fontset spec from the name of a base font.
2001 If `motif' is True use the Motif syntax. */
2003 xic_create_fontsetname (base_fontname
, motif
)
2004 char *base_fontname
;
2007 const char *sep
= motif
? ";" : ",";
2010 /* Make a fontset name from the base font name. */
2011 if (xic_defaut_fontset
== base_fontname
)
2012 { /* There is no base font name, use the default. */
2013 int len
= strlen (base_fontname
) + 2;
2014 fontsetname
= xmalloc (len
);
2015 bzero (fontsetname
, len
);
2016 strcpy (fontsetname
, base_fontname
);
2020 /* Make a fontset name from the base font name.
2021 The font set will be made of the following elements:
2023 - the base font where the charset spec is replaced by -*-*.
2024 - the same but with the family also replaced with -*-*-. */
2025 char *p
= base_fontname
;
2028 for (i
= 0; *p
; p
++)
2031 { /* As the font name doesn't conform to XLFD, we can't
2032 modify it to generalize it to allcs and allfamilies.
2033 Use the specified font plus the default. */
2034 int len
= strlen (base_fontname
) + strlen (xic_defaut_fontset
) + 3;
2035 fontsetname
= xmalloc (len
);
2036 bzero (fontsetname
, len
);
2037 strcpy (fontsetname
, base_fontname
);
2038 strcat (fontsetname
, sep
);
2039 strcat (fontsetname
, xic_defaut_fontset
);
2044 char *p1
= NULL
, *p2
= NULL
, *p3
= NULL
;
2045 char *font_allcs
= NULL
;
2046 char *font_allfamilies
= NULL
;
2047 char *font_all
= NULL
;
2048 char *allcs
= "*-*-*-*-*-*-*";
2049 char *allfamilies
= "-*-*-";
2050 char *all
= "*-*-*-*-";
2053 for (i
= 0, p
= base_fontname
; i
< 8; p
++)
2066 /* If base_fontname specifies ADSTYLE, make it a
2070 int diff
= (p2
- p3
) - 2;
2072 base
= alloca (strlen (base_fontname
) + 1);
2073 bcopy (base_fontname
, base
, p3
- base_fontname
);
2074 base
[p3
- base_fontname
] = '*';
2075 base
[(p3
- base_fontname
) + 1] = '-';
2076 strcpy (base
+ (p3
- base_fontname
) + 2, p2
);
2077 p
= base
+ (p
- base_fontname
) - diff
;
2078 p1
= base
+ (p1
- base_fontname
);
2079 p2
= base
+ (p2
- base_fontname
) - diff
;
2080 base_fontname
= base
;
2083 /* Build the font spec that matches all charsets. */
2084 len
= p
- base_fontname
+ strlen (allcs
) + 1;
2085 font_allcs
= (char *) alloca (len
);
2086 bzero (font_allcs
, len
);
2087 bcopy (base_fontname
, font_allcs
, p
- base_fontname
);
2088 strcat (font_allcs
, allcs
);
2090 /* Build the font spec that matches all families and
2092 len
= p
- p1
+ strlen (allcs
) + strlen (allfamilies
) + 1;
2093 font_allfamilies
= (char *) alloca (len
);
2094 bzero (font_allfamilies
, len
);
2095 strcpy (font_allfamilies
, allfamilies
);
2096 bcopy (p1
, font_allfamilies
+ strlen (allfamilies
), p
- p1
);
2097 strcat (font_allfamilies
, allcs
);
2099 /* Build the font spec that matches all. */
2100 len
= p
- p2
+ strlen (allcs
) + strlen (all
) + strlen (allfamilies
) + 1;
2101 font_all
= (char *) alloca (len
);
2102 bzero (font_all
, len
);
2103 strcpy (font_all
, allfamilies
);
2104 strcat (font_all
, all
);
2105 bcopy (p2
, font_all
+ strlen (all
) + strlen (allfamilies
), p
- p2
);
2106 strcat (font_all
, allcs
);
2108 /* Build the actual font set name. */
2109 len
= strlen (base_fontname
) + strlen (font_allcs
)
2110 + strlen (font_allfamilies
) + strlen (font_all
) + 5;
2111 fontsetname
= xmalloc (len
);
2112 bzero (fontsetname
, len
);
2113 strcpy (fontsetname
, base_fontname
);
2114 strcat (fontsetname
, sep
);
2115 strcat (fontsetname
, font_allcs
);
2116 strcat (fontsetname
, sep
);
2117 strcat (fontsetname
, font_allfamilies
);
2118 strcat (fontsetname
, sep
);
2119 strcat (fontsetname
, font_all
);
2123 strcat (fontsetname
, ":");
2128 xic_create_xfontset (f
, base_fontname
)
2130 char *base_fontname
;
2132 XFontSet xfs
= NULL
;
2133 char **missing_list
= NULL
;
2136 Lisp_Object rest
, frame
;
2139 base_fontname
= xic_defaut_fontset
;
2141 /* See if there is another frame already using same fontset. */
2142 FOR_EACH_FRAME (rest
, frame
)
2144 struct frame
*cf
= XFRAME (frame
);
2145 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2146 && FRAME_X_DISPLAY_INFO (cf
) == FRAME_X_DISPLAY_INFO (f
)
2147 && FRAME_XIC_BASE_FONTNAME (cf
)
2148 && !strcmp (FRAME_XIC_BASE_FONTNAME (cf
), base_fontname
))
2150 xfs
= FRAME_XIC_FONTSET (cf
);
2157 char *fontsetname
= xic_create_fontsetname (base_fontname
, False
);
2160 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
),
2161 fontsetname
, &missing_list
,
2162 &missing_count
, &def_string
);
2164 XFreeStringList (missing_list
);
2167 /* FONTSETNAME contains a list of font names (specific fonts
2168 first, general fonts last), but giving that to
2169 XCreateFontSet at once occasionally fails (bug of X?).
2170 So, we try to call XCreateFontSet for each fontname. */
2171 char *p0
= fontsetname
, *p1
;
2175 p1
= strchr (p0
, ',');
2178 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
),
2180 &missing_count
, &def_string
);
2182 XFreeStringList (missing_list
);
2185 p0
= p1
? p1
+ 1 : NULL
;
2188 xfree (fontsetname
);
2191 if (FRAME_XIC_BASE_FONTNAME (f
))
2192 xfree (FRAME_XIC_BASE_FONTNAME (f
));
2193 FRAME_XIC_BASE_FONTNAME (f
) = xstrdup (base_fontname
);
2195 /* No need to free def_string. */
2199 /* Free the X fontset of frame F if it is the last frame using it. */
2202 xic_free_xfontset (f
)
2205 Lisp_Object rest
, frame
;
2208 if (!FRAME_XIC_FONTSET (f
))
2211 /* See if there is another frame sharing the same fontset. */
2212 FOR_EACH_FRAME (rest
, frame
)
2214 struct frame
*cf
= XFRAME (frame
);
2215 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2216 && FRAME_X_DISPLAY_INFO (cf
) == FRAME_X_DISPLAY_INFO (f
)
2217 && FRAME_XIC_FONTSET (cf
) == FRAME_XIC_FONTSET (f
))
2225 /* The fontset is not used anymore. It is safe to free it. */
2226 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2228 if (FRAME_XIC_BASE_FONTNAME (f
))
2229 xfree (FRAME_XIC_BASE_FONTNAME (f
));
2230 FRAME_XIC_BASE_FONTNAME (f
) = NULL
;
2231 FRAME_XIC_FONTSET (f
) = NULL
;
2235 /* Value is the best input style, given user preferences USER (already
2236 checked to be supported by Emacs), and styles supported by the
2237 input method XIM. */
2240 best_xim_style (user
, xim
)
2246 for (i
= 0; i
< user
->count_styles
; ++i
)
2247 for (j
= 0; j
< xim
->count_styles
; ++j
)
2248 if (user
->supported_styles
[i
] == xim
->supported_styles
[j
])
2249 return user
->supported_styles
[i
];
2251 /* Return the default style. */
2252 return XIMPreeditNothing
| XIMStatusNothing
;
2255 /* Create XIC for frame F. */
2257 static XIMStyle xic_style
;
2260 create_frame_xic (f
)
2265 XFontSet xfs
= NULL
;
2270 /* Create X fontset. */
2271 xfs
= xic_create_xfontset
2272 (f
, (FRAME_FONTSET (f
) < 0) ? NULL
2273 : (char *) SDATA (fontset_ascii (FRAME_FONTSET (f
))));
2275 xim
= FRAME_X_XIM (f
);
2280 XVaNestedList preedit_attr
;
2281 XVaNestedList status_attr
;
2283 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2284 spot
.x
= 0; spot
.y
= 1;
2286 /* Determine XIC style. */
2289 XIMStyles supported_list
;
2290 supported_list
.count_styles
= (sizeof supported_xim_styles
2291 / sizeof supported_xim_styles
[0]);
2292 supported_list
.supported_styles
= supported_xim_styles
;
2293 xic_style
= best_xim_style (&supported_list
,
2294 FRAME_X_XIM_STYLES (f
));
2297 preedit_attr
= XVaCreateNestedList (0,
2300 FRAME_FOREGROUND_PIXEL (f
),
2302 FRAME_BACKGROUND_PIXEL (f
),
2303 (xic_style
& XIMPreeditPosition
2308 status_attr
= XVaCreateNestedList (0,
2314 FRAME_FOREGROUND_PIXEL (f
),
2316 FRAME_BACKGROUND_PIXEL (f
),
2319 xic
= XCreateIC (xim
,
2320 XNInputStyle
, xic_style
,
2321 XNClientWindow
, FRAME_X_WINDOW (f
),
2322 XNFocusWindow
, FRAME_X_WINDOW (f
),
2323 XNStatusAttributes
, status_attr
,
2324 XNPreeditAttributes
, preedit_attr
,
2326 XFree (preedit_attr
);
2327 XFree (status_attr
);
2330 FRAME_XIC (f
) = xic
;
2331 FRAME_XIC_STYLE (f
) = xic_style
;
2332 FRAME_XIC_FONTSET (f
) = xfs
;
2336 /* Destroy XIC and free XIC fontset of frame F, if any. */
2342 if (FRAME_XIC (f
) == NULL
)
2345 XDestroyIC (FRAME_XIC (f
));
2346 xic_free_xfontset (f
);
2348 FRAME_XIC (f
) = NULL
;
2352 /* Place preedit area for XIC of window W's frame to specified
2353 pixel position X/Y. X and Y are relative to window W. */
2356 xic_set_preeditarea (w
, x
, y
)
2360 struct frame
*f
= XFRAME (w
->frame
);
2364 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2365 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2366 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2367 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2372 /* Place status area for XIC in bottom right corner of frame F.. */
2375 xic_set_statusarea (f
)
2378 XIC xic
= FRAME_XIC (f
);
2383 /* Negotiate geometry of status area. If input method has existing
2384 status area, use its current size. */
2385 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2386 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2387 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2390 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2391 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2394 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2396 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2397 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2401 area
.width
= needed
->width
;
2402 area
.height
= needed
->height
;
2403 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2404 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2405 - FRAME_MENUBAR_HEIGHT (f
)
2406 - FRAME_TOOLBAR_HEIGHT (f
)
2407 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2410 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2411 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2416 /* Set X fontset for XIC of frame F, using base font name
2417 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2420 xic_set_xfontset (f
, base_fontname
)
2422 char *base_fontname
;
2427 xic_free_xfontset (f
);
2429 xfs
= xic_create_xfontset (f
, base_fontname
);
2431 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2432 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2433 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2434 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2435 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2438 FRAME_XIC_FONTSET (f
) = xfs
;
2441 #endif /* HAVE_X_I18N */
2445 #ifdef USE_X_TOOLKIT
2447 /* Create and set up the X widget for frame F. */
2450 x_window (f
, window_prompting
, minibuffer_only
)
2452 long window_prompting
;
2453 int minibuffer_only
;
2455 XClassHint class_hints
;
2456 XSetWindowAttributes attributes
;
2457 unsigned long attribute_mask
;
2458 Widget shell_widget
;
2460 Widget frame_widget
;
2466 /* Use the resource name as the top-level widget name
2467 for looking up resources. Make a non-Lisp copy
2468 for the window manager, so GC relocation won't bother it.
2470 Elsewhere we specify the window name for the window manager. */
2473 char *str
= (char *) SDATA (Vx_resource_name
);
2474 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2475 strcpy (f
->namebuf
, str
);
2479 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2480 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2481 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2482 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2483 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2484 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2485 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2486 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2487 applicationShellWidgetClass
,
2488 FRAME_X_DISPLAY (f
), al
, ac
);
2490 f
->output_data
.x
->widget
= shell_widget
;
2491 /* maybe_set_screen_title_format (shell_widget); */
2493 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2494 (widget_value
*) NULL
,
2495 shell_widget
, False
,
2499 (lw_callback
) NULL
);
2502 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2503 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2504 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2505 XtSetValues (pane_widget
, al
, ac
);
2506 f
->output_data
.x
->column_widget
= pane_widget
;
2508 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2509 the emacs screen when changing menubar. This reduces flickering. */
2512 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2513 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2514 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2515 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2516 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2517 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2518 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2519 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2520 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2523 f
->output_data
.x
->edit_widget
= frame_widget
;
2525 XtManageChild (frame_widget
);
2527 /* Do some needed geometry management. */
2530 char *tem
, shell_position
[32];
2533 int extra_borders
= 0;
2535 = (f
->output_data
.x
->menubar_widget
2536 ? (f
->output_data
.x
->menubar_widget
->core
.height
2537 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2540 #if 0 /* Experimentally, we now get the right results
2541 for -geometry -0-0 without this. 24 Aug 96, rms. */
2542 if (FRAME_EXTERNAL_MENU_BAR (f
))
2545 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2546 menubar_size
+= ibw
;
2550 f
->output_data
.x
->menubar_height
= menubar_size
;
2553 /* Motif seems to need this amount added to the sizes
2554 specified for the shell widget. The Athena/Lucid widgets don't.
2555 Both conclusions reached experimentally. -- rms. */
2556 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2557 &extra_borders
, NULL
);
2561 /* Convert our geometry parameters into a geometry string
2563 Note that we do not specify here whether the position
2564 is a user-specified or program-specified one.
2565 We pass that information later, in x_wm_set_size_hints. */
2567 int left
= f
->left_pos
;
2568 int xneg
= window_prompting
& XNegative
;
2569 int top
= f
->top_pos
;
2570 int yneg
= window_prompting
& YNegative
;
2576 if (window_prompting
& USPosition
)
2577 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2578 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2579 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2580 (xneg
? '-' : '+'), left
,
2581 (yneg
? '-' : '+'), top
);
2584 sprintf (shell_position
, "=%dx%d",
2585 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2586 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2588 /* Setting x and y when the position is not specified in
2589 the geometry string will set program position in the WM hints.
2590 If Emacs had just one program position, we could set it in
2591 fallback resources, but since each make-frame call can specify
2592 different program positions, this is easier. */
2593 XtSetArg (al
[ac
], XtNx
, left
); ac
++;
2594 XtSetArg (al
[ac
], XtNy
, top
); ac
++;
2598 len
= strlen (shell_position
) + 1;
2599 /* We don't free this because we don't know whether
2600 it is safe to free it while the frame exists.
2601 It isn't worth the trouble of arranging to free it
2602 when the frame is deleted. */
2603 tem
= (char *) xmalloc (len
);
2604 strncpy (tem
, shell_position
, len
);
2605 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2606 XtSetValues (shell_widget
, al
, ac
);
2609 XtManageChild (pane_widget
);
2610 XtRealizeWidget (shell_widget
);
2612 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2614 validate_x_resource_name ();
2616 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2617 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2618 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2621 FRAME_XIC (f
) = NULL
;
2623 create_frame_xic (f
);
2626 f
->output_data
.x
->wm_hints
.input
= True
;
2627 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2628 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2629 &f
->output_data
.x
->wm_hints
);
2631 hack_wm_protocols (f
, shell_widget
);
2634 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2637 /* Do a stupid property change to force the server to generate a
2638 PropertyNotify event so that the event_stream server timestamp will
2639 be initialized to something relevant to the time we created the window.
2641 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2642 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2643 XA_ATOM
, 32, PropModeAppend
,
2644 (unsigned char*) NULL
, 0);
2646 /* Make all the standard events reach the Emacs frame. */
2647 attributes
.event_mask
= STANDARD_EVENT_SET
;
2652 /* XIM server might require some X events. */
2653 unsigned long fevent
= NoEventMask
;
2654 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2655 attributes
.event_mask
|= fevent
;
2657 #endif /* HAVE_X_I18N */
2659 attribute_mask
= CWEventMask
;
2660 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2661 attribute_mask
, &attributes
);
2663 XtMapWidget (frame_widget
);
2665 /* x_set_name normally ignores requests to set the name if the
2666 requested name is the same as the current name. This is the one
2667 place where that assumption isn't correct; f->name is set, but
2668 the X server hasn't been told. */
2671 int explicit = f
->explicit_name
;
2673 f
->explicit_name
= 0;
2676 x_set_name (f
, name
, explicit);
2679 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2680 f
->output_data
.x
->text_cursor
);
2684 /* This is a no-op, except under Motif. Make sure main areas are
2685 set to something reasonable, in case we get an error later. */
2686 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2689 #else /* not USE_X_TOOLKIT */
2695 if (! xg_create_frame_widgets (f
))
2696 error ("Unable to create window");
2699 FRAME_XIC (f
) = NULL
;
2703 create_frame_xic (f
);
2706 /* XIM server might require some X events. */
2707 unsigned long fevent
= NoEventMask
;
2708 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2710 if (fevent
!= NoEventMask
)
2712 XSetWindowAttributes attributes
;
2713 XWindowAttributes wattr
;
2714 unsigned long attribute_mask
;
2716 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2718 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2719 attribute_mask
= CWEventMask
;
2720 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2721 attribute_mask
, &attributes
);
2729 #else /*! USE_GTK */
2730 /* Create and set up the X window for frame F. */
2737 XClassHint class_hints
;
2738 XSetWindowAttributes attributes
;
2739 unsigned long attribute_mask
;
2741 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2742 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2743 attributes
.bit_gravity
= StaticGravity
;
2744 attributes
.backing_store
= NotUseful
;
2745 attributes
.save_under
= True
;
2746 attributes
.event_mask
= STANDARD_EVENT_SET
;
2747 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2748 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2753 = XCreateWindow (FRAME_X_DISPLAY (f
),
2754 f
->output_data
.x
->parent_desc
,
2757 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2759 CopyFromParent
, /* depth */
2760 InputOutput
, /* class */
2762 attribute_mask
, &attributes
);
2767 create_frame_xic (f
);
2770 /* XIM server might require some X events. */
2771 unsigned long fevent
= NoEventMask
;
2772 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2773 attributes
.event_mask
|= fevent
;
2774 attribute_mask
= CWEventMask
;
2775 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2776 attribute_mask
, &attributes
);
2779 #endif /* HAVE_X_I18N */
2781 validate_x_resource_name ();
2783 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2784 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2785 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2787 /* The menubar is part of the ordinary display;
2788 it does not count in addition to the height of the window. */
2789 f
->output_data
.x
->menubar_height
= 0;
2791 /* This indicates that we use the "Passive Input" input model.
2792 Unless we do this, we don't get the Focus{In,Out} events that we
2793 need to draw the cursor correctly. Accursed bureaucrats.
2794 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2796 f
->output_data
.x
->wm_hints
.input
= True
;
2797 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2798 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2799 &f
->output_data
.x
->wm_hints
);
2800 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2802 /* Request "save yourself" and "delete window" commands from wm. */
2805 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2806 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2807 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2810 /* x_set_name normally ignores requests to set the name if the
2811 requested name is the same as the current name. This is the one
2812 place where that assumption isn't correct; f->name is set, but
2813 the X server hasn't been told. */
2816 int explicit = f
->explicit_name
;
2818 f
->explicit_name
= 0;
2821 x_set_name (f
, name
, explicit);
2824 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2825 f
->output_data
.x
->text_cursor
);
2829 if (FRAME_X_WINDOW (f
) == 0)
2830 error ("Unable to create window");
2833 #endif /* not USE_GTK */
2834 #endif /* not USE_X_TOOLKIT */
2836 /* Verify that the icon position args for this window are valid. */
2839 x_icon_verify (f
, parms
)
2843 Lisp_Object icon_x
, icon_y
;
2845 /* Set the position of the icon. Note that twm groups all
2846 icons in an icon window. */
2847 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2848 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2849 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2851 CHECK_NUMBER (icon_x
);
2852 CHECK_NUMBER (icon_y
);
2854 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2855 error ("Both left and top icon corners of icon must be specified");
2858 /* Handle the icon stuff for this window. Perhaps later we might
2859 want an x_set_icon_position which can be called interactively as
2867 Lisp_Object icon_x
, icon_y
;
2868 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2870 /* Set the position of the icon. Note that twm groups all
2871 icons in an icon window. */
2872 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2873 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2874 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2876 CHECK_NUMBER (icon_x
);
2877 CHECK_NUMBER (icon_y
);
2879 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2880 error ("Both left and top icon corners of icon must be specified");
2884 if (! EQ (icon_x
, Qunbound
))
2885 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2887 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2888 but x_create_frame still needs it. */
2889 /* Start up iconic or window? */
2890 x_wm_set_window_state
2891 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
2897 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
2904 /* Make the GCs needed for this window, setting the
2905 background, border and mouse colors; also create the
2906 mouse cursor and the gray border tile. */
2908 static char cursor_bits
[] =
2910 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2911 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2912 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2913 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2920 XGCValues gc_values
;
2924 /* Create the GCs of this frame.
2925 Note that many default values are used. */
2928 gc_values
.font
= FRAME_FONT (f
)->fid
;
2929 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
2930 gc_values
.background
= f
->output_data
.x
->background_pixel
;
2931 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2932 f
->output_data
.x
->normal_gc
2933 = XCreateGC (FRAME_X_DISPLAY (f
),
2935 GCLineWidth
| GCFont
| GCForeground
| GCBackground
,
2938 /* Reverse video style. */
2939 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
2940 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
2941 f
->output_data
.x
->reverse_gc
2942 = XCreateGC (FRAME_X_DISPLAY (f
),
2944 GCFont
| GCForeground
| GCBackground
| GCLineWidth
,
2947 /* Cursor has cursor-color background, background-color foreground. */
2948 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
2949 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
2950 gc_values
.fill_style
= FillOpaqueStippled
;
2952 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
2953 FRAME_X_DISPLAY_INFO (f
)->root_window
,
2954 cursor_bits
, 16, 16);
2955 f
->output_data
.x
->cursor_gc
2956 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2957 (GCFont
| GCForeground
| GCBackground
2958 | GCFillStyle
/* | GCStipple */ | GCLineWidth
),
2962 f
->output_data
.x
->white_relief
.gc
= 0;
2963 f
->output_data
.x
->black_relief
.gc
= 0;
2965 /* Create the gray border tile used when the pointer is not in
2966 the frame. Since this depends on the frame's pixel values,
2967 this must be done on a per-frame basis. */
2968 f
->output_data
.x
->border_tile
2969 = (XCreatePixmapFromBitmapData
2970 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
2971 gray_bits
, gray_width
, gray_height
,
2972 f
->output_data
.x
->foreground_pixel
,
2973 f
->output_data
.x
->background_pixel
,
2974 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
2980 /* Free what was was allocated in x_make_gc. */
2986 Display
*dpy
= FRAME_X_DISPLAY (f
);
2990 if (f
->output_data
.x
->normal_gc
)
2992 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
2993 f
->output_data
.x
->normal_gc
= 0;
2996 if (f
->output_data
.x
->reverse_gc
)
2998 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
2999 f
->output_data
.x
->reverse_gc
= 0;
3002 if (f
->output_data
.x
->cursor_gc
)
3004 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
3005 f
->output_data
.x
->cursor_gc
= 0;
3008 if (f
->output_data
.x
->border_tile
)
3010 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
3011 f
->output_data
.x
->border_tile
= 0;
3018 /* Handler for signals raised during x_create_frame and
3019 x_create_top_frame. FRAME is the frame which is partially
3023 unwind_create_frame (frame
)
3026 struct frame
*f
= XFRAME (frame
);
3028 /* If frame is ``official'', nothing to do. */
3029 if (!CONSP (Vframe_list
) || !EQ (XCAR (Vframe_list
), frame
))
3032 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3035 x_free_frame_resources (f
);
3038 /* Check that reference counts are indeed correct. */
3039 xassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
3040 xassert (dpyinfo
->image_cache
->refcount
== image_cache_refcount
);
3049 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3051 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
3052 Returns an Emacs frame object.
3053 ALIST is an alist of frame parameters.
3054 If the parameters specify that the frame should not have a minibuffer,
3055 and do not specify a specific minibuffer window to use,
3056 then `default-minibuffer-frame' must be a frame whose minibuffer can
3057 be shared by the new frame.
3059 This function is an internal primitive--use `make-frame' instead. */)
3064 Lisp_Object frame
, tem
;
3066 int minibuffer_only
= 0;
3067 long window_prompting
= 0;
3069 int count
= SPECPDL_INDEX ();
3070 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3071 Lisp_Object display
;
3072 struct x_display_info
*dpyinfo
= NULL
;
3078 parms
= Fcopy_alist (parms
);
3080 /* Use this general default value to start with
3081 until we know if this frame has a specified name. */
3082 Vx_resource_name
= Vinvocation_name
;
3084 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3085 if (EQ (display
, Qunbound
))
3087 dpyinfo
= check_x_display_info (display
);
3089 kb
= dpyinfo
->kboard
;
3091 kb
= &the_only_kboard
;
3094 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3096 && ! EQ (name
, Qunbound
)
3098 error ("Invalid frame name--not a string or nil");
3101 Vx_resource_name
= name
;
3103 /* See if parent window is specified. */
3104 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3105 if (EQ (parent
, Qunbound
))
3107 if (! NILP (parent
))
3108 CHECK_NUMBER (parent
);
3110 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3111 /* No need to protect DISPLAY because that's not used after passing
3112 it to make_frame_without_minibuffer. */
3114 GCPRO4 (parms
, parent
, name
, frame
);
3115 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3117 if (EQ (tem
, Qnone
) || NILP (tem
))
3118 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3119 else if (EQ (tem
, Qonly
))
3121 f
= make_minibuffer_frame ();
3122 minibuffer_only
= 1;
3124 else if (WINDOWP (tem
))
3125 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3129 XSETFRAME (frame
, f
);
3131 /* Note that X Windows does support scroll bars. */
3132 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3134 f
->output_method
= output_x_window
;
3135 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3136 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3137 f
->output_data
.x
->icon_bitmap
= -1;
3138 FRAME_FONTSET (f
) = -1;
3139 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3140 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3141 #ifdef USE_TOOLKIT_SCROLL_BARS
3142 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3143 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3144 #endif /* USE_TOOLKIT_SCROLL_BARS */
3147 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3149 if (! STRINGP (f
->icon_name
))
3150 f
->icon_name
= Qnil
;
3152 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3154 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3155 record_unwind_protect (unwind_create_frame
, frame
);
3157 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
3158 dpyinfo_refcount
= dpyinfo
->reference_count
;
3159 #endif /* GLYPH_DEBUG */
3161 FRAME_KBOARD (f
) = kb
;
3164 /* These colors will be set anyway later, but it's important
3165 to get the color reference counts right, so initialize them! */
3168 struct gcpro gcpro1
;
3170 /* Function x_decode_color can signal an error. Make
3171 sure to initialize color slots so that we won't try
3172 to free colors we haven't allocated. */
3173 f
->output_data
.x
->foreground_pixel
= -1;
3174 f
->output_data
.x
->background_pixel
= -1;
3175 f
->output_data
.x
->cursor_pixel
= -1;
3176 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3177 f
->output_data
.x
->border_pixel
= -1;
3178 f
->output_data
.x
->mouse_pixel
= -1;
3180 black
= build_string ("black");
3182 f
->output_data
.x
->foreground_pixel
3183 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3184 f
->output_data
.x
->background_pixel
3185 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3186 f
->output_data
.x
->cursor_pixel
3187 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3188 f
->output_data
.x
->cursor_foreground_pixel
3189 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3190 f
->output_data
.x
->border_pixel
3191 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3192 f
->output_data
.x
->mouse_pixel
3193 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3197 /* Specify the parent under which to make this X window. */
3201 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3202 f
->output_data
.x
->explicit_parent
= 1;
3206 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3207 f
->output_data
.x
->explicit_parent
= 0;
3210 /* Set the name; the functions to which we pass f expect the name to
3212 if (EQ (name
, Qunbound
) || NILP (name
))
3214 f
->name
= build_string (dpyinfo
->x_id_name
);
3215 f
->explicit_name
= 0;
3220 f
->explicit_name
= 1;
3221 /* use the frame's title when getting resources for this frame. */
3222 specbind (Qx_resource_name
, name
);
3225 /* Extract the window parameters from the supplied values
3226 that are needed to determine window geometry. */
3230 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3233 /* First, try whatever font the caller has specified. */
3236 tem
= Fquery_fontset (font
, Qnil
);
3238 font
= x_new_fontset (f
, SDATA (tem
));
3240 font
= x_new_font (f
, SDATA (font
));
3243 /* Try out a font which we hope has bold and italic variations. */
3244 if (!STRINGP (font
))
3245 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
3246 if (!STRINGP (font
))
3247 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3248 if (! STRINGP (font
))
3249 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3250 if (! STRINGP (font
))
3251 /* This was formerly the first thing tried, but it finds too many fonts
3252 and takes too long. */
3253 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3254 /* If those didn't work, look for something which will at least work. */
3255 if (! STRINGP (font
))
3256 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3258 if (! STRINGP (font
))
3259 font
= build_string ("fixed");
3261 x_set_frame_parameters (f
, Fcons (Fcons (Qfont
, font
), Qnil
));
3265 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3266 whereby it fails to get any font. */
3267 xlwmenu_default_font
= FRAME_FONT (f
);
3270 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3271 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3273 /* This defaults to 1 in order to match xterm. We recognize either
3274 internalBorderWidth or internalBorder (which is what xterm calls
3276 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3280 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3281 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3282 if (! EQ (value
, Qunbound
))
3283 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3286 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3287 "internalBorderWidth", "internalBorderWidth",
3289 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3290 "verticalScrollBars", "ScrollBars",
3293 /* Also do the stuff which must be set before the window exists. */
3294 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3295 "foreground", "Foreground", RES_TYPE_STRING
);
3296 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3297 "background", "Background", RES_TYPE_STRING
);
3298 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3299 "pointerColor", "Foreground", RES_TYPE_STRING
);
3300 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3301 "cursorColor", "Foreground", RES_TYPE_STRING
);
3302 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3303 "borderColor", "BorderColor", RES_TYPE_STRING
);
3304 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3305 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3306 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3307 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3308 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3309 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3310 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3311 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3313 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3314 "scrollBarForeground",
3315 "ScrollBarForeground", 1);
3316 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3317 "scrollBarBackground",
3318 "ScrollBarBackground", 0);
3320 /* Init faces before x_default_parameter is called for scroll-bar
3321 parameters because that function calls x_set_scroll_bar_width,
3322 which calls change_frame_size, which calls Fset_window_buffer,
3323 which runs hooks, which call Fvertical_motion. At the end, we
3324 end up in init_iterator with a null face cache, which should not
3326 init_frame_faces (f
);
3328 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3329 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
3330 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (1),
3331 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
3332 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3333 "bufferPredicate", "BufferPredicate",
3335 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3336 "title", "Title", RES_TYPE_STRING
);
3337 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3338 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3339 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3340 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3342 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3344 /* Compute the size of the X window. */
3345 window_prompting
= x_figure_window_size (f
, parms
, 1);
3347 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3348 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3350 x_icon_verify (f
, parms
);
3352 /* Create the X widget or window. */
3353 #ifdef USE_X_TOOLKIT
3354 x_window (f
, window_prompting
, minibuffer_only
);
3362 /* Now consider the frame official. */
3363 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3364 Vframe_list
= Fcons (frame
, Vframe_list
);
3366 /* We need to do this after creating the X window, so that the
3367 icon-creation functions can say whose icon they're describing. */
3368 x_default_parameter (f
, parms
, Qicon_type
, Qt
,
3369 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
3371 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3372 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3373 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3374 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3375 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3376 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3377 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3378 "scrollBarWidth", "ScrollBarWidth",
3381 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3382 Change will not be effected unless different from the current
3384 width
= FRAME_COLS (f
);
3385 height
= FRAME_LINES (f
);
3387 SET_FRAME_COLS (f
, 0);
3388 FRAME_LINES (f
) = 0;
3389 change_frame_size (f
, height
, width
, 1, 0, 0);
3391 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3392 /* Create the menu bar. */
3393 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3395 /* If this signals an error, we haven't set size hints for the
3396 frame and we didn't make it visible. */
3397 initialize_frame_menubar (f
);
3400 /* This is a no-op, except under Motif where it arranges the
3401 main window for the widgets on it. */
3402 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3403 f
->output_data
.x
->menubar_widget
,
3404 f
->output_data
.x
->edit_widget
);
3405 #endif /* not USE_GTK */
3407 #endif /* USE_X_TOOLKIT || USE_GTK */
3409 /* Tell the server what size and position, etc, we want, and how
3410 badly we want them. This should be done after we have the menu
3411 bar so that its size can be taken into account. */
3413 x_wm_set_size_hint (f
, window_prompting
, 0);
3416 /* Make the window appear on the frame and enable display, unless
3417 the caller says not to. However, with explicit parent, Emacs
3418 cannot control visibility, so don't try. */
3419 if (! f
->output_data
.x
->explicit_parent
)
3421 Lisp_Object visibility
;
3423 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3425 if (EQ (visibility
, Qunbound
))
3428 if (EQ (visibility
, Qicon
))
3429 x_iconify_frame (f
);
3430 else if (! NILP (visibility
))
3431 x_make_frame_visible (f
);
3433 /* Must have been Qnil. */
3437 /* Set the WM leader property. GTK does this itself, so this is not
3438 needed when using GTK. */
3439 if (dpyinfo
->client_leader_window
!= 0)
3442 XChangeProperty (FRAME_X_DISPLAY (f
),
3443 FRAME_OUTER_WINDOW (f
),
3444 dpyinfo
->Xatom_wm_client_leader
,
3445 XA_WINDOW
, 32, PropModeReplace
,
3446 (unsigned char *) &dpyinfo
->client_leader_window
, 1);
3450 /* Initialize `default-minibuffer-frame' in case this is the first
3451 frame on this display device. */
3452 if (FRAME_HAS_MINIBUF_P (f
)
3453 && (!FRAMEP (kb
->Vdefault_minibuffer_frame
)
3454 || !FRAME_LIVE_P (XFRAME (kb
->Vdefault_minibuffer_frame
))))
3455 kb
->Vdefault_minibuffer_frame
= frame
;
3457 /* All remaining specified parameters, which have not been "used"
3458 by x_get_arg and friends, now go in the misc. alist of the frame. */
3459 for (tem
= parms
; !NILP (tem
); tem
= XCDR (tem
))
3460 if (CONSP (XCAR (tem
)) && !NILP (XCAR (XCAR (tem
))))
3461 f
->param_alist
= Fcons (XCAR (tem
), f
->param_alist
);
3465 /* Make sure windows on this frame appear in calls to next-window
3466 and similar functions. */
3467 Vwindow_list
= Qnil
;
3469 return unbind_to (count
, frame
);
3473 /* FRAME is used only to get a handle on the X display. We don't pass the
3474 display info directly because we're called from frame.c, which doesn't
3475 know about that structure. */
3478 x_get_focus_frame (frame
)
3479 struct frame
*frame
;
3481 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3483 if (! dpyinfo
->x_focus_frame
)
3486 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3491 /* In certain situations, when the window manager follows a
3492 click-to-focus policy, there seems to be no way around calling
3493 XSetInputFocus to give another frame the input focus .
3495 In an ideal world, XSetInputFocus should generally be avoided so
3496 that applications don't interfere with the window manager's focus
3497 policy. But I think it's okay to use when it's clearly done
3498 following a user-command. */
3500 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 1, 0,
3501 doc
: /* Set the input focus to FRAME.
3502 FRAME nil means use the selected frame. */)
3506 struct frame
*f
= check_x_frame (frame
);
3507 Display
*dpy
= FRAME_X_DISPLAY (f
);
3510 x_catch_errors (dpy
);
3511 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3512 RevertToParent
, CurrentTime
);
3513 x_uncatch_errors ();
3520 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3521 doc
: /* Internal function called by `color-defined-p', which see. */)
3523 Lisp_Object color
, frame
;
3526 FRAME_PTR f
= check_x_frame (frame
);
3528 CHECK_STRING (color
);
3530 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3536 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3537 doc
: /* Internal function called by `color-values', which see. */)
3539 Lisp_Object color
, frame
;
3542 FRAME_PTR f
= check_x_frame (frame
);
3544 CHECK_STRING (color
);
3546 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3547 return list3 (make_number (foo
.red
),
3548 make_number (foo
.green
),
3549 make_number (foo
.blue
));
3554 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3555 doc
: /* Internal function called by `display-color-p', which see. */)
3557 Lisp_Object display
;
3559 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3561 if (dpyinfo
->n_planes
<= 2)
3564 switch (dpyinfo
->visual
->class)
3577 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3579 doc
: /* Return t if the X display supports shades of gray.
3580 Note that color displays do support shades of gray.
3581 The optional argument DISPLAY specifies which display to ask about.
3582 DISPLAY should be either a frame or a display name (a string).
3583 If omitted or nil, that stands for the selected frame's display. */)
3585 Lisp_Object display
;
3587 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3589 if (dpyinfo
->n_planes
<= 1)
3592 switch (dpyinfo
->visual
->class)
3607 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3609 doc
: /* Returns the width in pixels of the X display DISPLAY.
3610 The optional argument DISPLAY specifies which display to ask about.
3611 DISPLAY should be either a frame or a display name (a string).
3612 If omitted or nil, that stands for the selected frame's display. */)
3614 Lisp_Object display
;
3616 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3618 return make_number (dpyinfo
->width
);
3621 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3622 Sx_display_pixel_height
, 0, 1, 0,
3623 doc
: /* Returns the height in pixels of the X display DISPLAY.
3624 The optional argument DISPLAY specifies which display to ask about.
3625 DISPLAY should be either a frame or a display name (a string).
3626 If omitted or nil, that stands for the selected frame's display. */)
3628 Lisp_Object display
;
3630 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3632 return make_number (dpyinfo
->height
);
3635 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3637 doc
: /* Returns the number of bitplanes of the X display DISPLAY.
3638 The optional argument DISPLAY specifies which display to ask about.
3639 DISPLAY should be either a frame or a display name (a string).
3640 If omitted or nil, that stands for the selected frame's display. */)
3642 Lisp_Object display
;
3644 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3646 return make_number (dpyinfo
->n_planes
);
3649 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3651 doc
: /* Returns the number of color cells of the X display DISPLAY.
3652 The optional argument DISPLAY specifies which display to ask about.
3653 DISPLAY should be either a frame or a display name (a string).
3654 If omitted or nil, that stands for the selected frame's display. */)
3656 Lisp_Object display
;
3658 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3660 int nr_planes
= DisplayPlanes (dpyinfo
->display
,
3661 XScreenNumberOfScreen (dpyinfo
->screen
));
3663 /* Truncate nr_planes to 24 to avoid integer overflow.
3664 Some displays says 32, but only 24 bits are actually significant.
3665 There are only very few and rare video cards that have more than
3666 24 significant bits. Also 24 bits is more than 16 million colors,
3667 it "should be enough for everyone". */
3668 if (nr_planes
> 24) nr_planes
= 24;
3670 return make_number (1 << nr_planes
);
3673 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3674 Sx_server_max_request_size
,
3676 doc
: /* Returns the maximum request size of the X server of display DISPLAY.
3677 The optional argument DISPLAY specifies which display to ask about.
3678 DISPLAY should be either a frame or a display name (a string).
3679 If omitted or nil, that stands for the selected frame's display. */)
3681 Lisp_Object display
;
3683 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3685 return make_number (MAXREQUEST (dpyinfo
->display
));
3688 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3689 doc
: /* Returns the "vendor ID" string of the X server of display DISPLAY.
3690 \(Labelling every distributor as a "vendor" embodies the false assumption
3691 that operating systems cannot be developed and distributed noncommercially.)
3692 The optional argument DISPLAY specifies which display to ask about.
3693 DISPLAY should be either a frame or a display name (a string).
3694 If omitted or nil, that stands for the selected frame's display. */)
3696 Lisp_Object display
;
3698 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3699 char *vendor
= ServerVendor (dpyinfo
->display
);
3701 if (! vendor
) vendor
= "";
3702 return build_string (vendor
);
3705 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3706 doc
: /* Returns the version numbers of the X server of display DISPLAY.
3707 The value is a list of three integers: the major and minor
3708 version numbers of the X Protocol in use, and the distributor-specific release
3709 number. See also the function `x-server-vendor'.
3711 The optional argument DISPLAY specifies which display to ask about.
3712 DISPLAY should be either a frame or a display name (a string).
3713 If omitted or nil, that stands for the selected frame's display. */)
3715 Lisp_Object display
;
3717 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3718 Display
*dpy
= dpyinfo
->display
;
3720 return Fcons (make_number (ProtocolVersion (dpy
)),
3721 Fcons (make_number (ProtocolRevision (dpy
)),
3722 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3725 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3726 doc
: /* Return the number of screens on the X server of display DISPLAY.
3727 The optional argument DISPLAY specifies which display to ask about.
3728 DISPLAY should be either a frame or a display name (a string).
3729 If omitted or nil, that stands for the selected frame's display. */)
3731 Lisp_Object display
;
3733 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3735 return make_number (ScreenCount (dpyinfo
->display
));
3738 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3739 doc
: /* Return the height in millimeters of the X display DISPLAY.
3740 The optional argument DISPLAY specifies which display to ask about.
3741 DISPLAY should be either a frame or a display name (a string).
3742 If omitted or nil, that stands for the selected frame's display. */)
3744 Lisp_Object display
;
3746 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3748 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3751 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3752 doc
: /* Return the width in millimeters of the X display DISPLAY.
3753 The optional argument DISPLAY specifies which display to ask about.
3754 DISPLAY should be either a frame or a display name (a string).
3755 If omitted or nil, that stands for the selected frame's display. */)
3757 Lisp_Object display
;
3759 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3761 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3764 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3765 Sx_display_backing_store
, 0, 1, 0,
3766 doc
: /* Returns an indication of whether X display DISPLAY does backing store.
3767 The value may be `always', `when-mapped', or `not-useful'.
3768 The optional argument DISPLAY specifies which display to ask about.
3769 DISPLAY should be either a frame or a display name (a string).
3770 If omitted or nil, that stands for the selected frame's display. */)
3772 Lisp_Object display
;
3774 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3777 switch (DoesBackingStore (dpyinfo
->screen
))
3780 result
= intern ("always");
3784 result
= intern ("when-mapped");
3788 result
= intern ("not-useful");
3792 error ("Strange value for BackingStore parameter of screen");
3799 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3800 Sx_display_visual_class
, 0, 1, 0,
3801 doc
: /* Return the visual class of the X display DISPLAY.
3802 The value is one of the symbols `static-gray', `gray-scale',
3803 `static-color', `pseudo-color', `true-color', or `direct-color'.
3805 The optional argument DISPLAY specifies which display to ask about.
3806 DISPLAY should be either a frame or a display name (a string).
3807 If omitted or nil, that stands for the selected frame's display. */)
3809 Lisp_Object display
;
3811 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3814 switch (dpyinfo
->visual
->class)
3817 result
= intern ("static-gray");
3820 result
= intern ("gray-scale");
3823 result
= intern ("static-color");
3826 result
= intern ("pseudo-color");
3829 result
= intern ("true-color");
3832 result
= intern ("direct-color");
3835 error ("Display has an unknown visual class");
3842 DEFUN ("x-display-save-under", Fx_display_save_under
,
3843 Sx_display_save_under
, 0, 1, 0,
3844 doc
: /* Returns t if the X display DISPLAY supports the save-under feature.
3845 The optional argument DISPLAY specifies which display to ask about.
3846 DISPLAY should be either a frame or a display name (a string).
3847 If omitted or nil, that stands for the selected frame's display. */)
3849 Lisp_Object display
;
3851 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3853 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3861 register struct frame
*f
;
3863 return FRAME_PIXEL_WIDTH (f
);
3868 register struct frame
*f
;
3870 return FRAME_PIXEL_HEIGHT (f
);
3875 register struct frame
*f
;
3877 return FRAME_COLUMN_WIDTH (f
);
3882 register struct frame
*f
;
3884 return FRAME_LINE_HEIGHT (f
);
3889 register struct frame
*f
;
3891 return FRAME_X_DISPLAY_INFO (f
)->n_planes
;
3896 /************************************************************************
3898 ************************************************************************/
3901 /* Mapping visual names to visuals. */
3903 static struct visual_class
3910 {"StaticGray", StaticGray
},
3911 {"GrayScale", GrayScale
},
3912 {"StaticColor", StaticColor
},
3913 {"PseudoColor", PseudoColor
},
3914 {"TrueColor", TrueColor
},
3915 {"DirectColor", DirectColor
},
3920 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3922 /* Value is the screen number of screen SCR. This is a substitute for
3923 the X function with the same name when that doesn't exist. */
3926 XScreenNumberOfScreen (scr
)
3927 register Screen
*scr
;
3929 Display
*dpy
= scr
->display
;
3932 for (i
= 0; i
< dpy
->nscreens
; ++i
)
3933 if (scr
== dpy
->screens
+ i
)
3939 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3942 /* Select the visual that should be used on display DPYINFO. Set
3943 members of DPYINFO appropriately. Called from x_term_init. */
3946 select_visual (dpyinfo
)
3947 struct x_display_info
*dpyinfo
;
3949 Display
*dpy
= dpyinfo
->display
;
3950 Screen
*screen
= dpyinfo
->screen
;
3953 /* See if a visual is specified. */
3954 value
= display_x_get_resource (dpyinfo
,
3955 build_string ("visualClass"),
3956 build_string ("VisualClass"),
3958 if (STRINGP (value
))
3960 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
3961 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
3962 depth, a decimal number. NAME is compared with case ignored. */
3963 char *s
= (char *) alloca (SBYTES (value
) + 1);
3968 strcpy (s
, SDATA (value
));
3969 dash
= index (s
, '-');
3972 dpyinfo
->n_planes
= atoi (dash
+ 1);
3976 /* We won't find a matching visual with depth 0, so that
3977 an error will be printed below. */
3978 dpyinfo
->n_planes
= 0;
3980 /* Determine the visual class. */
3981 for (i
= 0; visual_classes
[i
].name
; ++i
)
3982 if (xstricmp (s
, visual_classes
[i
].name
) == 0)
3984 class = visual_classes
[i
].class;
3988 /* Look up a matching visual for the specified class. */
3990 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
3991 dpyinfo
->n_planes
, class, &vinfo
))
3992 fatal ("Invalid visual specification `%s'", SDATA (value
));
3994 dpyinfo
->visual
= vinfo
.visual
;
3999 XVisualInfo
*vinfo
, vinfo_template
;
4001 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4004 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4006 vinfo_template
.visualid
= dpyinfo
->visual
->visualid
;
4008 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4009 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4010 &vinfo_template
, &n_visuals
);
4012 fatal ("Can't get proper X visual info");
4014 dpyinfo
->n_planes
= vinfo
->depth
;
4015 XFree ((char *) vinfo
);
4020 /* Return the X display structure for the display named NAME.
4021 Open a new connection if necessary. */
4023 struct x_display_info
*
4024 x_display_info_for_name (name
)
4028 struct x_display_info
*dpyinfo
;
4030 CHECK_STRING (name
);
4032 if (! EQ (Vwindow_system
, intern ("x")))
4033 error ("Not using X Windows");
4035 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4037 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
4040 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
4045 /* Use this general default value to start with. */
4046 Vx_resource_name
= Vinvocation_name
;
4048 validate_x_resource_name ();
4050 dpyinfo
= x_term_init (name
, (char *)0,
4051 (char *) SDATA (Vx_resource_name
));
4054 error ("Cannot connect to X server %s", SDATA (name
));
4057 XSETFASTINT (Vwindow_system_version
, 11);
4063 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4065 doc
: /* Open a connection to an X server.
4066 DISPLAY is the name of the display to connect to.
4067 Optional second arg XRM-STRING is a string of resources in xrdb format.
4068 If the optional third arg MUST-SUCCEED is non-nil,
4069 terminate Emacs if we can't open the connection. */)
4070 (display
, xrm_string
, must_succeed
)
4071 Lisp_Object display
, xrm_string
, must_succeed
;
4073 unsigned char *xrm_option
;
4074 struct x_display_info
*dpyinfo
;
4076 CHECK_STRING (display
);
4077 if (! NILP (xrm_string
))
4078 CHECK_STRING (xrm_string
);
4080 if (! EQ (Vwindow_system
, intern ("x")))
4081 error ("Not using X Windows");
4083 if (! NILP (xrm_string
))
4084 xrm_option
= (unsigned char *) SDATA (xrm_string
);
4086 xrm_option
= (unsigned char *) 0;
4088 validate_x_resource_name ();
4090 /* This is what opens the connection and sets x_current_display.
4091 This also initializes many symbols, such as those used for input. */
4092 dpyinfo
= x_term_init (display
, xrm_option
,
4093 (char *) SDATA (Vx_resource_name
));
4097 if (!NILP (must_succeed
))
4098 fatal ("Cannot connect to X server %s.\n\
4099 Check the DISPLAY environment variable or use `-d'.\n\
4100 Also use the `xauth' program to verify that you have the proper\n\
4101 authorization information needed to connect the X server.\n\
4102 An insecure way to solve the problem may be to use `xhost'.\n",
4105 error ("Cannot connect to X server %s", SDATA (display
));
4110 XSETFASTINT (Vwindow_system_version
, 11);
4114 DEFUN ("x-close-connection", Fx_close_connection
,
4115 Sx_close_connection
, 1, 1, 0,
4116 doc
: /* Close the connection to DISPLAY's X server.
4117 For DISPLAY, specify either a frame or a display name (a string).
4118 If DISPLAY is nil, that stands for the selected frame's display. */)
4120 Lisp_Object display
;
4122 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4125 if (dpyinfo
->reference_count
> 0)
4126 error ("Display still has frames on it");
4129 /* Free the fonts in the font table. */
4130 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4131 if (dpyinfo
->font_table
[i
].name
)
4133 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4136 x_destroy_all_bitmaps (dpyinfo
);
4137 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4140 xg_display_close (dpyinfo
->display
);
4142 #ifdef USE_X_TOOLKIT
4143 XtCloseDisplay (dpyinfo
->display
);
4145 XCloseDisplay (dpyinfo
->display
);
4147 #endif /* ! USE_GTK */
4149 x_delete_display (dpyinfo
);
4155 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4156 doc
: /* Return the list of display names that Emacs has connections to. */)
4159 Lisp_Object tail
, result
;
4162 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
4163 result
= Fcons (XCAR (XCAR (tail
)), result
);
4168 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4169 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4170 If ON is nil, allow buffering of requests.
4171 Turning on synchronization prohibits the Xlib routines from buffering
4172 requests and seriously degrades performance, but makes debugging much
4174 The optional second argument DISPLAY specifies which display to act on.
4175 DISPLAY should be either a frame or a display name (a string).
4176 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4178 Lisp_Object display
, on
;
4180 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4182 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4187 /* Wait for responses to all X commands issued so far for frame F. */
4194 XSync (FRAME_X_DISPLAY (f
), False
);
4199 /***********************************************************************
4201 ***********************************************************************/
4203 DEFUN ("x-change-window-property", Fx_change_window_property
,
4204 Sx_change_window_property
, 2, 6, 0,
4205 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
4206 PROP must be a string.
4207 VALUE may be a string or a list of conses, numbers and/or strings.
4208 If an element in the list is a string, it is converted to
4209 an Atom and the value of the Atom is used. If an element is a cons,
4210 it is converted to a 32 bit number where the car is the 16 top bits and the
4211 cdr is the lower 16 bits.
4212 FRAME nil or omitted means use the selected frame.
4213 If TYPE is given and non-nil, it is the name of the type of VALUE.
4214 If TYPE is not given or nil, the type is STRING.
4215 FORMAT gives the size in bits of each element if VALUE is a list.
4216 It must be one of 8, 16 or 32.
4217 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4218 If OUTER_P is non-nil, the property is changed for the outer X window of
4219 FRAME. Default is to change on the edit X window.
4222 (prop
, value
, frame
, type
, format
, outer_p
)
4223 Lisp_Object prop
, value
, frame
, type
, format
, outer_p
;
4225 struct frame
*f
= check_x_frame (frame
);
4227 Atom target_type
= XA_STRING
;
4228 int element_format
= 8;
4229 unsigned char *data
;
4233 CHECK_STRING (prop
);
4235 if (! NILP (format
))
4237 CHECK_NUMBER (format
);
4238 element_format
= XFASTINT (format
);
4240 if (element_format
!= 8 && element_format
!= 16
4241 && element_format
!= 32)
4242 error ("FORMAT must be one of 8, 16 or 32");
4247 nelements
= x_check_property_data (value
);
4248 if (nelements
== -1)
4249 error ("Bad data in VALUE, must be number, string or cons");
4251 if (element_format
== 8)
4252 data
= (unsigned char *) xmalloc (nelements
);
4253 else if (element_format
== 16)
4254 data
= (unsigned char *) xmalloc (nelements
*2);
4255 else /* format == 32 */
4256 /* The man page for XChangeProperty:
4257 "If the specified format is 32, the property data must be a
4259 This applies even if long is more than 64 bits. The X library
4260 converts to 32 bits before sending to the X server. */
4261 data
= (unsigned char *) xmalloc (nelements
* sizeof(long));
4263 x_fill_property_data (FRAME_X_DISPLAY (f
), value
, data
, element_format
);
4267 CHECK_STRING (value
);
4268 data
= SDATA (value
);
4269 nelements
= SCHARS (value
);
4273 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4276 CHECK_STRING (type
);
4277 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (type
), False
);
4280 if (! NILP (outer_p
)) w
= FRAME_OUTER_WINDOW (f
);
4281 else w
= FRAME_X_WINDOW (f
);
4283 XChangeProperty (FRAME_X_DISPLAY (f
), w
,
4284 prop_atom
, target_type
, element_format
, PropModeReplace
,
4287 if (CONSP (value
)) xfree (data
);
4289 /* Make sure the property is set when we return. */
4290 XFlush (FRAME_X_DISPLAY (f
));
4297 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
4298 Sx_delete_window_property
, 1, 2, 0,
4299 doc
: /* Remove window property PROP from X window of FRAME.
4300 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4302 Lisp_Object prop
, frame
;
4304 struct frame
*f
= check_x_frame (frame
);
4307 CHECK_STRING (prop
);
4309 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4310 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
4312 /* Make sure the property is removed when we return. */
4313 XFlush (FRAME_X_DISPLAY (f
));
4320 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
4322 doc
: /* Value is the value of window property PROP on FRAME.
4323 If FRAME is nil or omitted, use the selected frame.
4324 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4325 is the name of the Atom that denotes the type expected.
4326 If SOURCE is non-nil, get the property on that window instead of from
4327 FRAME. The number 0 denotes the root window.
4328 If DELETE_P is non-nil, delete the property after retreiving it.
4329 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4331 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4332 no value of TYPE. */)
4333 (prop
, frame
, type
, source
, delete_p
, vector_ret_p
)
4334 Lisp_Object prop
, frame
, type
, source
, delete_p
, vector_ret_p
;
4336 struct frame
*f
= check_x_frame (frame
);
4339 Lisp_Object prop_value
= Qnil
;
4340 unsigned char *tmp_data
= NULL
;
4342 Atom target_type
= XA_STRING
;
4344 unsigned long actual_size
, bytes_remaining
;
4345 Window target_window
= FRAME_X_WINDOW (f
);
4346 struct gcpro gcpro1
;
4348 GCPRO1 (prop_value
);
4349 CHECK_STRING (prop
);
4351 if (! NILP (source
))
4353 if (NUMBERP (source
))
4355 if (FLOATP (source
))
4356 target_window
= (Window
) XFLOAT (source
);
4358 target_window
= XFASTINT (source
);
4360 if (target_window
== 0)
4361 target_window
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4363 else if (CONSP (source
))
4364 target_window
= cons_to_long (source
);
4370 if (strcmp ("AnyPropertyType", SDATA (type
)) == 0)
4371 target_type
= AnyPropertyType
;
4373 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (type
), False
);
4376 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4377 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4378 prop_atom
, 0, 0, False
, target_type
,
4379 &actual_type
, &actual_format
, &actual_size
,
4380 &bytes_remaining
, &tmp_data
);
4383 int size
= bytes_remaining
;
4388 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4389 prop_atom
, 0, bytes_remaining
,
4390 ! NILP (delete_p
), target_type
,
4391 &actual_type
, &actual_format
,
4392 &actual_size
, &bytes_remaining
,
4394 if (rc
== Success
&& tmp_data
)
4396 /* The man page for XGetWindowProperty says:
4397 "If the returned format is 32, the returned data is represented
4398 as a long array and should be cast to that type to obtain the
4400 This applies even if long is more than 32 bits, the X library
4401 converts from 32 bit elements received from the X server to long
4402 and passes the long array to us. Thus, for that case bcopy can not
4403 be used. We convert to a 32 bit type here, because so much code
4406 The bytes and offsets passed to XGetWindowProperty refers to the
4407 property and those are indeed in 32 bit quantities if format is
4410 if (actual_format
== 32 && actual_format
< BITS_PER_LONG
)
4413 int *idata
= (int *) tmp_data
;
4414 long *ldata
= (long *) tmp_data
;
4416 for (i
= 0; i
< actual_size
; ++i
)
4417 idata
[i
] = (int) ldata
[i
];
4420 if (NILP (vector_ret_p
))
4421 prop_value
= make_string (tmp_data
, size
);
4423 prop_value
= x_property_data_to_lisp (f
,
4430 if (tmp_data
) XFree (tmp_data
);
4440 /***********************************************************************
4442 ***********************************************************************/
4444 /* If non-null, an asynchronous timer that, when it expires, displays
4445 an hourglass cursor on all frames. */
4447 static struct atimer
*hourglass_atimer
;
4449 /* Non-zero means an hourglass cursor is currently shown. */
4451 static int hourglass_shown_p
;
4453 /* Number of seconds to wait before displaying an hourglass cursor. */
4455 static Lisp_Object Vhourglass_delay
;
4457 /* Default number of seconds to wait before displaying an hourglass
4460 #define DEFAULT_HOURGLASS_DELAY 1
4462 /* Function prototypes. */
4464 static void show_hourglass
P_ ((struct atimer
*));
4465 static void hide_hourglass
P_ ((void));
4467 /* Return non-zero if houglass timer has been started or hourglass is shown. */
4470 hourglass_started ()
4472 return hourglass_shown_p
|| hourglass_atimer
!= NULL
;
4476 /* Cancel a currently active hourglass timer, and start a new one. */
4482 int secs
, usecs
= 0;
4484 /* Don't bother for ttys. */
4485 if (NILP (Vwindow_system
))
4488 cancel_hourglass ();
4490 if (INTEGERP (Vhourglass_delay
)
4491 && XINT (Vhourglass_delay
) > 0)
4492 secs
= XFASTINT (Vhourglass_delay
);
4493 else if (FLOATP (Vhourglass_delay
)
4494 && XFLOAT_DATA (Vhourglass_delay
) > 0)
4497 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
4498 secs
= XFASTINT (tem
);
4499 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
4502 secs
= DEFAULT_HOURGLASS_DELAY
;
4504 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
4505 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
4506 show_hourglass
, NULL
);
4510 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
4516 if (hourglass_atimer
)
4518 cancel_atimer (hourglass_atimer
);
4519 hourglass_atimer
= NULL
;
4522 if (hourglass_shown_p
)
4527 /* Timer function of hourglass_atimer. TIMER is equal to
4530 Display an hourglass pointer on all frames by mapping the frames'
4531 hourglass_window. Set the hourglass_p flag in the frames'
4532 output_data.x structure to indicate that an hourglass cursor is
4533 shown on the frames. */
4536 show_hourglass (timer
)
4537 struct atimer
*timer
;
4539 /* The timer implementation will cancel this timer automatically
4540 after this function has run. Set hourglass_atimer to null
4541 so that we know the timer doesn't have to be canceled. */
4542 hourglass_atimer
= NULL
;
4544 if (!hourglass_shown_p
)
4546 Lisp_Object rest
, frame
;
4550 FOR_EACH_FRAME (rest
, frame
)
4552 struct frame
*f
= XFRAME (frame
);
4554 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
) && FRAME_X_DISPLAY (f
))
4556 Display
*dpy
= FRAME_X_DISPLAY (f
);
4558 #ifdef USE_X_TOOLKIT
4559 if (f
->output_data
.x
->widget
)
4561 if (FRAME_OUTER_WINDOW (f
))
4564 f
->output_data
.x
->hourglass_p
= 1;
4566 if (!f
->output_data
.x
->hourglass_window
)
4568 unsigned long mask
= CWCursor
;
4569 XSetWindowAttributes attrs
;
4571 Window parent
= FRAME_X_WINDOW (f
);
4573 Window parent
= FRAME_OUTER_WINDOW (f
);
4575 attrs
.cursor
= f
->output_data
.x
->hourglass_cursor
;
4577 f
->output_data
.x
->hourglass_window
4578 = XCreateWindow (dpy
, parent
,
4579 0, 0, 32000, 32000, 0, 0,
4585 XMapRaised (dpy
, f
->output_data
.x
->hourglass_window
);
4591 hourglass_shown_p
= 1;
4597 /* Hide the hourglass pointer on all frames, if it is currently
4603 if (hourglass_shown_p
)
4605 Lisp_Object rest
, frame
;
4608 FOR_EACH_FRAME (rest
, frame
)
4610 struct frame
*f
= XFRAME (frame
);
4613 /* Watch out for newly created frames. */
4614 && f
->output_data
.x
->hourglass_window
)
4616 XUnmapWindow (FRAME_X_DISPLAY (f
),
4617 f
->output_data
.x
->hourglass_window
);
4618 /* Sync here because XTread_socket looks at the
4619 hourglass_p flag that is reset to zero below. */
4620 XSync (FRAME_X_DISPLAY (f
), False
);
4621 f
->output_data
.x
->hourglass_p
= 0;
4625 hourglass_shown_p
= 0;
4632 /***********************************************************************
4634 ***********************************************************************/
4636 static Lisp_Object x_create_tip_frame
P_ ((struct x_display_info
*,
4637 Lisp_Object
, Lisp_Object
));
4638 static void compute_tip_xy
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
4639 Lisp_Object
, int, int, int *, int *));
4641 /* The frame of a currently visible tooltip. */
4643 Lisp_Object tip_frame
;
4645 /* If non-nil, a timer started that hides the last tooltip when it
4648 Lisp_Object tip_timer
;
4651 /* If non-nil, a vector of 3 elements containing the last args
4652 with which x-show-tip was called. See there. */
4654 Lisp_Object last_show_tip_args
;
4656 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4658 Lisp_Object Vx_max_tooltip_size
;
4662 unwind_create_tip_frame (frame
)
4665 Lisp_Object deleted
;
4667 deleted
= unwind_create_frame (frame
);
4668 if (EQ (deleted
, Qt
))
4678 /* Create a frame for a tooltip on the display described by DPYINFO.
4679 PARMS is a list of frame parameters. TEXT is the string to
4680 display in the tip frame. Value is the frame.
4682 Note that functions called here, esp. x_default_parameter can
4683 signal errors, for instance when a specified color name is
4684 undefined. We have to make sure that we're in a consistent state
4685 when this happens. */
4688 x_create_tip_frame (dpyinfo
, parms
, text
)
4689 struct x_display_info
*dpyinfo
;
4690 Lisp_Object parms
, text
;
4693 Lisp_Object frame
, tem
;
4695 long window_prompting
= 0;
4697 int count
= SPECPDL_INDEX ();
4698 struct gcpro gcpro1
, gcpro2
, gcpro3
;
4700 int face_change_count_before
= face_change_count
;
4702 struct buffer
*old_buffer
;
4706 parms
= Fcopy_alist (parms
);
4709 kb
= dpyinfo
->kboard
;
4711 kb
= &the_only_kboard
;
4714 /* Get the name of the frame to use for resource lookup. */
4715 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
4717 && !EQ (name
, Qunbound
)
4719 error ("Invalid frame name--not a string or nil");
4722 GCPRO3 (parms
, name
, frame
);
4724 XSETFRAME (frame
, f
);
4726 buffer
= Fget_buffer_create (build_string (" *tip*"));
4727 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
4728 old_buffer
= current_buffer
;
4729 set_buffer_internal_1 (XBUFFER (buffer
));
4730 current_buffer
->truncate_lines
= Qnil
;
4731 specbind (Qinhibit_read_only
, Qt
);
4732 specbind (Qinhibit_modification_hooks
, Qt
);
4735 set_buffer_internal_1 (old_buffer
);
4737 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
4738 record_unwind_protect (unwind_create_tip_frame
, frame
);
4740 /* By setting the output method, we're essentially saying that
4741 the frame is live, as per FRAME_LIVE_P. If we get a signal
4742 from this point on, x_destroy_window might screw up reference
4744 f
->output_method
= output_x_window
;
4745 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
4746 bzero (f
->output_data
.x
, sizeof (struct x_output
));
4747 f
->output_data
.x
->icon_bitmap
= -1;
4748 FRAME_FONTSET (f
) = -1;
4749 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
4750 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
4751 #ifdef USE_TOOLKIT_SCROLL_BARS
4752 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
4753 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
4754 #endif /* USE_TOOLKIT_SCROLL_BARS */
4755 f
->icon_name
= Qnil
;
4756 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
4758 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
4759 dpyinfo_refcount
= dpyinfo
->reference_count
;
4760 #endif /* GLYPH_DEBUG */
4762 FRAME_KBOARD (f
) = kb
;
4764 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4765 f
->output_data
.x
->explicit_parent
= 0;
4767 /* These colors will be set anyway later, but it's important
4768 to get the color reference counts right, so initialize them! */
4771 struct gcpro gcpro1
;
4773 black
= build_string ("black");
4775 f
->output_data
.x
->foreground_pixel
4776 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4777 f
->output_data
.x
->background_pixel
4778 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4779 f
->output_data
.x
->cursor_pixel
4780 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4781 f
->output_data
.x
->cursor_foreground_pixel
4782 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4783 f
->output_data
.x
->border_pixel
4784 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4785 f
->output_data
.x
->mouse_pixel
4786 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4790 /* Set the name; the functions to which we pass f expect the name to
4792 if (EQ (name
, Qunbound
) || NILP (name
))
4794 f
->name
= build_string (dpyinfo
->x_id_name
);
4795 f
->explicit_name
= 0;
4800 f
->explicit_name
= 1;
4801 /* use the frame's title when getting resources for this frame. */
4802 specbind (Qx_resource_name
, name
);
4805 /* Extract the window parameters from the supplied values that are
4806 needed to determine window geometry. */
4810 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
4813 /* First, try whatever font the caller has specified. */
4816 tem
= Fquery_fontset (font
, Qnil
);
4818 font
= x_new_fontset (f
, SDATA (tem
));
4820 font
= x_new_font (f
, SDATA (font
));
4823 /* Try out a font which we hope has bold and italic variations. */
4824 if (!STRINGP (font
))
4825 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
4826 if (!STRINGP (font
))
4827 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
4828 if (! STRINGP (font
))
4829 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
4830 if (! STRINGP (font
))
4831 /* This was formerly the first thing tried, but it finds too many fonts
4832 and takes too long. */
4833 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
4834 /* If those didn't work, look for something which will at least work. */
4835 if (! STRINGP (font
))
4836 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
4838 if (! STRINGP (font
))
4839 font
= build_string ("fixed");
4841 x_default_parameter (f
, parms
, Qfont
, font
,
4842 "font", "Font", RES_TYPE_STRING
);
4845 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
4846 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
4848 /* This defaults to 2 in order to match xterm. We recognize either
4849 internalBorderWidth or internalBorder (which is what xterm calls
4851 if (NILP (Fassq (Qinternal_border_width
, parms
)))
4855 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
4856 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
4857 if (! EQ (value
, Qunbound
))
4858 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
4862 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
4863 "internalBorderWidth", "internalBorderWidth",
4866 /* Also do the stuff which must be set before the window exists. */
4867 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
4868 "foreground", "Foreground", RES_TYPE_STRING
);
4869 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
4870 "background", "Background", RES_TYPE_STRING
);
4871 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
4872 "pointerColor", "Foreground", RES_TYPE_STRING
);
4873 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
4874 "cursorColor", "Foreground", RES_TYPE_STRING
);
4875 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
4876 "borderColor", "BorderColor", RES_TYPE_STRING
);
4878 /* Init faces before x_default_parameter is called for scroll-bar
4879 parameters because that function calls x_set_scroll_bar_width,
4880 which calls change_frame_size, which calls Fset_window_buffer,
4881 which runs hooks, which call Fvertical_motion. At the end, we
4882 end up in init_iterator with a null face cache, which should not
4884 init_frame_faces (f
);
4886 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4888 window_prompting
= x_figure_window_size (f
, parms
, 0);
4891 XSetWindowAttributes attrs
;
4895 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
4896 if (DoesSaveUnders (dpyinfo
->screen
))
4897 mask
|= CWSaveUnder
;
4899 /* Window managers look at the override-redirect flag to determine
4900 whether or net to give windows a decoration (Xlib spec, chapter
4902 attrs
.override_redirect
= True
;
4903 attrs
.save_under
= True
;
4904 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
4905 /* Arrange for getting MapNotify and UnmapNotify events. */
4906 attrs
.event_mask
= StructureNotifyMask
;
4908 = FRAME_X_WINDOW (f
)
4909 = XCreateWindow (FRAME_X_DISPLAY (f
),
4910 FRAME_X_DISPLAY_INFO (f
)->root_window
,
4911 /* x, y, width, height */
4915 CopyFromParent
, InputOutput
, CopyFromParent
,
4922 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
4923 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4924 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
4925 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4926 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
4927 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
4929 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4930 Change will not be effected unless different from the current
4932 width
= FRAME_COLS (f
);
4933 height
= FRAME_LINES (f
);
4934 SET_FRAME_COLS (f
, 0);
4935 FRAME_LINES (f
) = 0;
4936 change_frame_size (f
, height
, width
, 1, 0, 0);
4938 /* Add `tooltip' frame parameter's default value. */
4939 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
4940 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
4943 /* Set up faces after all frame parameters are known. This call
4944 also merges in face attributes specified for new frames.
4946 Frame parameters may be changed if .Xdefaults contains
4947 specifications for the default font. For example, if there is an
4948 `Emacs.default.attributeBackground: pink', the `background-color'
4949 attribute of the frame get's set, which let's the internal border
4950 of the tooltip frame appear in pink. Prevent this. */
4952 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
4954 /* Set tip_frame here, so that */
4956 call1 (Qface_set_after_frame_default
, frame
);
4958 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
4959 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qbackground_color
, bg
),
4967 /* It is now ok to make the frame official even if we get an error
4968 below. And the frame needs to be on Vframe_list or making it
4969 visible won't work. */
4970 Vframe_list
= Fcons (frame
, Vframe_list
);
4972 /* Now that the frame is official, it counts as a reference to
4974 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
4976 /* Setting attributes of faces of the tooltip frame from resources
4977 and similar will increment face_change_count, which leads to the
4978 clearing of all current matrices. Since this isn't necessary
4979 here, avoid it by resetting face_change_count to the value it
4980 had before we created the tip frame. */
4981 face_change_count
= face_change_count_before
;
4983 /* Discard the unwind_protect. */
4984 return unbind_to (count
, frame
);
4988 /* Compute where to display tip frame F. PARMS is the list of frame
4989 parameters for F. DX and DY are specified offsets from the current
4990 location of the mouse. WIDTH and HEIGHT are the width and height
4991 of the tooltip. Return coordinates relative to the root window of
4992 the display in *ROOT_X, and *ROOT_Y. */
4995 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, root_x
, root_y
)
4997 Lisp_Object parms
, dx
, dy
;
4999 int *root_x
, *root_y
;
5001 Lisp_Object left
, top
;
5006 /* User-specified position? */
5007 left
= Fcdr (Fassq (Qleft
, parms
));
5008 top
= Fcdr (Fassq (Qtop
, parms
));
5010 /* Move the tooltip window where the mouse pointer is. Resize and
5012 if (!INTEGERP (left
) || !INTEGERP (top
))
5015 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
5016 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
5021 *root_y
= XINT (top
);
5022 else if (*root_y
+ XINT (dy
) <= 0)
5023 *root_y
= 0; /* Can happen for negative dy */
5024 else if (*root_y
+ XINT (dy
) + height
<= FRAME_X_DISPLAY_INFO (f
)->height
)
5025 /* It fits below the pointer */
5026 *root_y
+= XINT (dy
);
5027 else if (height
+ XINT (dy
) <= *root_y
)
5028 /* It fits above the pointer. */
5029 *root_y
-= height
+ XINT (dy
);
5031 /* Put it on the top. */
5034 if (INTEGERP (left
))
5035 *root_x
= XINT (left
);
5036 else if (*root_x
+ XINT (dx
) <= 0)
5037 *root_x
= 0; /* Can happen for negative dx */
5038 else if (*root_x
+ XINT (dx
) + width
<= FRAME_X_DISPLAY_INFO (f
)->width
)
5039 /* It fits to the right of the pointer. */
5040 *root_x
+= XINT (dx
);
5041 else if (width
+ XINT (dx
) <= *root_x
)
5042 /* It fits to the left of the pointer. */
5043 *root_x
-= width
+ XINT (dx
);
5045 /* Put it left-justified on the screen--it ought to fit that way. */
5050 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
5051 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
5052 A tooltip window is a small X window displaying a string.
5054 This is an internal function; Lisp code should call `tooltip-show'.
5056 FRAME nil or omitted means use the selected frame.
5058 PARMS is an optional list of frame parameters which can be used to
5059 change the tooltip's appearance.
5061 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5062 means use the default timeout of 5 seconds.
5064 If the list of frame parameters PARAMS contains a `left' parameters,
5065 the tooltip is displayed at that x-position. Otherwise it is
5066 displayed at the mouse position, with offset DX added (default is 5 if
5067 DX isn't specified). Likewise for the y-position; if a `top' frame
5068 parameter is specified, it determines the y-position of the tooltip
5069 window, otherwise it is displayed at the mouse position, with offset
5070 DY added (default is -10).
5072 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5073 Text larger than the specified size is clipped. */)
5074 (string
, frame
, parms
, timeout
, dx
, dy
)
5075 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
5080 struct buffer
*old_buffer
;
5081 struct text_pos pos
;
5082 int i
, width
, height
;
5083 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
5084 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
5085 int count
= SPECPDL_INDEX ();
5087 specbind (Qinhibit_redisplay
, Qt
);
5089 GCPRO4 (string
, parms
, frame
, timeout
);
5091 CHECK_STRING (string
);
5092 f
= check_x_frame (frame
);
5094 timeout
= make_number (5);
5096 CHECK_NATNUM (timeout
);
5099 dx
= make_number (5);
5104 dy
= make_number (-10);
5108 if (NILP (last_show_tip_args
))
5109 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
5111 if (!NILP (tip_frame
))
5113 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
5114 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
5115 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
5117 if (EQ (frame
, last_frame
)
5118 && !NILP (Fequal (last_string
, string
))
5119 && !NILP (Fequal (last_parms
, parms
)))
5121 struct frame
*f
= XFRAME (tip_frame
);
5123 /* Only DX and DY have changed. */
5124 if (!NILP (tip_timer
))
5126 Lisp_Object timer
= tip_timer
;
5128 call1 (Qcancel_timer
, timer
);
5132 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
5133 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
5134 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5141 /* Hide a previous tip, if any. */
5144 ASET (last_show_tip_args
, 0, string
);
5145 ASET (last_show_tip_args
, 1, frame
);
5146 ASET (last_show_tip_args
, 2, parms
);
5148 /* Add default values to frame parameters. */
5149 if (NILP (Fassq (Qname
, parms
)))
5150 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
5151 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5152 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
5153 if (NILP (Fassq (Qborder_width
, parms
)))
5154 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
5155 if (NILP (Fassq (Qborder_color
, parms
)))
5156 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
5157 if (NILP (Fassq (Qbackground_color
, parms
)))
5158 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
5161 /* Create a frame for the tooltip, and record it in the global
5162 variable tip_frame. */
5163 frame
= x_create_tip_frame (FRAME_X_DISPLAY_INFO (f
), parms
, string
);
5166 /* Set up the frame's root window. */
5167 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
5168 w
->left_col
= w
->top_line
= make_number (0);
5170 if (CONSP (Vx_max_tooltip_size
)
5171 && INTEGERP (XCAR (Vx_max_tooltip_size
))
5172 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
5173 && INTEGERP (XCDR (Vx_max_tooltip_size
))
5174 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
5176 w
->total_cols
= XCAR (Vx_max_tooltip_size
);
5177 w
->total_lines
= XCDR (Vx_max_tooltip_size
);
5181 w
->total_cols
= make_number (80);
5182 w
->total_lines
= make_number (40);
5185 FRAME_TOTAL_COLS (f
) = XINT (w
->total_cols
);
5187 w
->pseudo_window_p
= 1;
5189 /* Display the tooltip text in a temporary buffer. */
5190 old_buffer
= current_buffer
;
5191 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->buffer
));
5192 current_buffer
->truncate_lines
= Qnil
;
5193 clear_glyph_matrix (w
->desired_matrix
);
5194 clear_glyph_matrix (w
->current_matrix
);
5195 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
5196 try_window (FRAME_ROOT_WINDOW (f
), pos
, 0);
5198 /* Compute width and height of the tooltip. */
5200 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5202 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5206 /* Stop at the first empty row at the end. */
5207 if (!row
->enabled_p
|| !row
->displays_text_p
)
5210 /* Let the row go over the full width of the frame. */
5211 row
->full_width_p
= 1;
5213 /* There's a glyph at the end of rows that is used to place
5214 the cursor there. Don't include the width of this glyph. */
5215 if (row
->used
[TEXT_AREA
])
5217 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5218 row_width
= row
->pixel_width
- last
->pixel_width
;
5221 row_width
= row
->pixel_width
;
5223 height
+= row
->height
;
5224 width
= max (width
, row_width
);
5227 /* Add the frame's internal border to the width and height the X
5228 window should have. */
5229 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5230 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5232 /* Move the tooltip window where the mouse pointer is. Resize and
5234 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5237 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5238 root_x
, root_y
, width
, height
);
5239 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5242 /* Draw into the window. */
5243 w
->must_be_updated_p
= 1;
5244 update_single_window (w
, 1);
5246 /* Restore original current buffer. */
5247 set_buffer_internal_1 (old_buffer
);
5248 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
5251 /* Let the tip disappear after timeout seconds. */
5252 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
5253 intern ("x-hide-tip"));
5256 return unbind_to (count
, Qnil
);
5260 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
5261 doc
: /* Hide the current tooltip window, if there is any.
5262 Value is t if tooltip was open, nil otherwise. */)
5266 Lisp_Object deleted
, frame
, timer
;
5267 struct gcpro gcpro1
, gcpro2
;
5269 /* Return quickly if nothing to do. */
5270 if (NILP (tip_timer
) && NILP (tip_frame
))
5275 GCPRO2 (frame
, timer
);
5276 tip_frame
= tip_timer
= deleted
= Qnil
;
5278 count
= SPECPDL_INDEX ();
5279 specbind (Qinhibit_redisplay
, Qt
);
5280 specbind (Qinhibit_quit
, Qt
);
5283 call1 (Qcancel_timer
, timer
);
5287 Fdelete_frame (frame
, Qnil
);
5291 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5292 redisplay procedure is not called when a tip frame over menu
5293 items is unmapped. Redisplay the menu manually... */
5295 struct frame
*f
= SELECTED_FRAME ();
5296 Widget w
= f
->output_data
.x
->menubar_widget
;
5297 extern void xlwmenu_redisplay
P_ ((Widget
));
5299 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f
)->screen
)
5303 xlwmenu_redisplay (w
);
5307 #endif /* USE_LUCID */
5311 return unbind_to (count
, deleted
);
5316 /***********************************************************************
5317 File selection dialog
5318 ***********************************************************************/
5320 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog
,
5321 Sx_uses_old_gtk_dialog
,
5323 doc
: /* Return t if the old Gtk+ file selection dialog is used. */)
5327 extern int use_dialog_box
;
5328 extern int use_file_dialog
;
5333 && xg_uses_old_file_dialog ())
5341 /* Callback for "OK" and "Cancel" on file selection dialog. */
5344 file_dialog_cb (widget
, client_data
, call_data
)
5346 XtPointer call_data
, client_data
;
5348 int *result
= (int *) client_data
;
5349 XmAnyCallbackStruct
*cb
= (XmAnyCallbackStruct
*) call_data
;
5350 *result
= cb
->reason
;
5354 /* Callback for unmapping a file selection dialog. This is used to
5355 capture the case where a dialog is closed via a window manager's
5356 closer button, for example. Using a XmNdestroyCallback didn't work
5360 file_dialog_unmap_cb (widget
, client_data
, call_data
)
5362 XtPointer call_data
, client_data
;
5364 int *result
= (int *) client_data
;
5365 *result
= XmCR_CANCEL
;
5369 clean_up_file_dialog (arg
)
5372 struct Lisp_Save_Value
*p
= XSAVE_VALUE (arg
);
5373 Widget dialog
= (Widget
) p
->pointer
;
5377 XtUnmanageChild (dialog
);
5378 XtDestroyWidget (dialog
);
5379 x_menu_set_in_use (0);
5386 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5387 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5388 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5389 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5390 or directory must exist. ONLY-DIR-P is ignored." */)
5391 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
)
5392 Lisp_Object prompt
, dir
, default_filename
, mustmatch
, only_dir_p
;
5395 struct frame
*f
= SELECTED_FRAME ();
5396 Lisp_Object file
= Qnil
;
5397 Lisp_Object decoded_file
;
5398 Widget dialog
, text
, help
;
5401 extern XtAppContext Xt_app_con
;
5402 XmString dir_xmstring
, pattern_xmstring
;
5403 int count
= SPECPDL_INDEX ();
5404 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
5408 GCPRO6 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
, file
);
5410 if (popup_activated ())
5411 error ("Trying to use a menu from within a menu-entry");
5413 CHECK_STRING (prompt
);
5416 /* Prevent redisplay. */
5417 specbind (Qinhibit_redisplay
, Qt
);
5421 /* Create the dialog with PROMPT as title, using DIR as initial
5422 directory and using "*" as pattern. */
5423 dir
= Fexpand_file_name (dir
, Qnil
);
5424 dir_xmstring
= XmStringCreateLocalized (SDATA (dir
));
5425 pattern_xmstring
= XmStringCreateLocalized ("*");
5427 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
5428 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
5429 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
5430 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
5431 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
5432 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
5434 XmStringFree (dir_xmstring
);
5435 XmStringFree (pattern_xmstring
);
5437 /* Add callbacks for OK and Cancel. */
5438 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
5439 (XtPointer
) &result
);
5440 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
5441 (XtPointer
) &result
);
5442 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
5443 (XtPointer
) &result
);
5445 /* Remove the help button since we can't display help. */
5446 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
5447 XtUnmanageChild (help
);
5449 /* Mark OK button as default. */
5450 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
5451 XmNshowAsDefault
, True
, NULL
);
5453 /* If MUSTMATCH is non-nil, disable the file entry field of the
5454 dialog, so that the user must select a file from the files list
5455 box. We can't remove it because we wouldn't have a way to get at
5456 the result file name, then. */
5457 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
5458 if (!NILP (mustmatch
))
5461 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
5462 XtSetSensitive (text
, False
);
5463 XtSetSensitive (label
, False
);
5466 /* Manage the dialog, so that list boxes get filled. */
5467 XtManageChild (dialog
);
5469 if (STRINGP (default_filename
))
5471 XmString default_xmstring
;
5472 Widget wtext
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
5473 Widget list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
5475 XmTextPosition last_pos
= XmTextFieldGetLastPosition (wtext
);
5476 XmTextFieldReplace (wtext
, 0, last_pos
,
5477 (SDATA (Ffile_name_nondirectory (default_filename
))));
5479 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5480 must include the path for this to work. */
5482 default_xmstring
= XmStringCreateLocalized (SDATA (default_filename
));
5484 if (XmListItemExists (list
, default_xmstring
))
5486 int item_pos
= XmListItemPos (list
, default_xmstring
);
5487 /* Select the item and scroll it into view. */
5488 XmListSelectPos (list
, item_pos
, True
);
5489 XmListSetPos (list
, item_pos
);
5492 XmStringFree (default_xmstring
);
5495 record_unwind_protect (clean_up_file_dialog
, make_save_value (dialog
, 0));
5497 /* Process events until the user presses Cancel or OK. */
5498 x_menu_set_in_use (1);
5503 x_menu_wait_for_event (0);
5504 XtAppNextEvent (Xt_app_con
, &event
);
5505 if (event
.type
== KeyPress
5506 && FRAME_X_DISPLAY (f
) == event
.xkey
.display
)
5508 KeySym keysym
= XLookupKeysym (&event
.xkey
, 0);
5510 /* Pop down on C-g. */
5511 if (keysym
== XK_g
&& (event
.xkey
.state
& ControlMask
) != 0)
5512 XtUnmanageChild (dialog
);
5515 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
));
5518 /* Get the result. */
5519 if (result
== XmCR_OK
)
5524 XtVaGetValues (dialog
, XmNtextString
, &text
, NULL
);
5525 XmStringGetLtoR (text
, XmFONTLIST_DEFAULT_TAG
, &data
);
5526 XmStringFree (text
);
5527 file
= build_string (data
);
5536 /* Make "Cancel" equivalent to C-g. */
5538 Fsignal (Qquit
, Qnil
);
5540 decoded_file
= DECODE_FILE (file
);
5542 return unbind_to (count
, decoded_file
);
5545 #endif /* USE_MOTIF */
5550 clean_up_dialog (arg
)
5553 x_menu_set_in_use (0);
5558 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5559 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5560 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5561 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5562 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5564 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
)
5565 Lisp_Object prompt
, dir
, default_filename
, mustmatch
, only_dir_p
;
5567 FRAME_PTR f
= SELECTED_FRAME ();
5569 Lisp_Object file
= Qnil
;
5570 Lisp_Object decoded_file
;
5571 int count
= SPECPDL_INDEX ();
5572 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
5577 GCPRO6 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
, file
);
5579 if (popup_activated ())
5580 error ("Trying to use a menu from within a menu-entry");
5582 CHECK_STRING (prompt
);
5585 /* Prevent redisplay. */
5586 specbind (Qinhibit_redisplay
, Qt
);
5587 record_unwind_protect (clean_up_dialog
, Qnil
);
5591 if (STRINGP (default_filename
))
5592 cdef_file
= SDATA (default_filename
);
5594 cdef_file
= SDATA (dir
);
5596 fn
= xg_get_file_name (f
, SDATA (prompt
), cdef_file
,
5598 ! NILP (only_dir_p
));
5602 file
= build_string (fn
);
5609 /* Make "Cancel" equivalent to C-g. */
5611 Fsignal (Qquit
, Qnil
);
5613 decoded_file
= DECODE_FILE (file
);
5615 return unbind_to (count
, decoded_file
);
5618 #endif /* USE_GTK */
5621 /***********************************************************************
5623 ***********************************************************************/
5625 #ifdef HAVE_XKBGETKEYBOARD
5626 #include <X11/XKBlib.h>
5627 #include <X11/keysym.h>
5630 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
5631 Sx_backspace_delete_keys_p
, 0, 1, 0,
5632 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5633 FRAME nil means use the selected frame.
5634 Value is t if we know that both keys are present, and are mapped to the
5635 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5636 present and mapped to the usual X keysyms. */)
5640 #ifdef HAVE_XKBGETKEYBOARD
5642 struct frame
*f
= check_x_frame (frame
);
5643 Display
*dpy
= FRAME_X_DISPLAY (f
);
5644 Lisp_Object have_keys
;
5645 int major
, minor
, op
, event
, error
;
5649 /* Check library version in case we're dynamically linked. */
5650 major
= XkbMajorVersion
;
5651 minor
= XkbMinorVersion
;
5652 if (!XkbLibraryVersion (&major
, &minor
))
5658 /* Check that the server supports XKB. */
5659 major
= XkbMajorVersion
;
5660 minor
= XkbMinorVersion
;
5661 if (!XkbQueryExtension (dpy
, &op
, &event
, &error
, &major
, &minor
))
5667 /* In this code we check that the keyboard has physical keys with names
5668 that start with BKSP (Backspace) and DELE (Delete), and that they
5669 generate keysym XK_BackSpace and XK_Delete respectively.
5670 This function is used to test if normal-erase-is-backspace should be
5672 An alternative approach would be to just check if XK_BackSpace and
5673 XK_Delete are mapped to any key. But if any of those are mapped to
5674 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5675 user doesn't know about it, it is better to return false here.
5676 It is more obvious to the user what to do if she/he has two keys
5677 clearly marked with names/symbols and one key does something not
5678 expected (i.e. she/he then tries the other).
5679 The cases where Backspace/Delete is mapped to some other key combination
5680 are rare, and in those cases, normal-erase-is-backspace can be turned on
5684 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
5687 int delete_keycode
= 0, backspace_keycode
= 0, i
;
5689 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
5691 for (i
= kb
->min_key_code
;
5692 (i
< kb
->max_key_code
5693 && (delete_keycode
== 0 || backspace_keycode
== 0));
5696 /* The XKB symbolic key names can be seen most easily in
5697 the PS file generated by `xkbprint -label name
5699 if (bcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
5701 else if (bcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
5702 backspace_keycode
= i
;
5705 XkbFreeNames (kb
, 0, True
);
5708 XkbFreeClientMap (kb
, 0, True
);
5711 && backspace_keycode
5712 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
5713 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
5718 #else /* not HAVE_XKBGETKEYBOARD */
5720 #endif /* not HAVE_XKBGETKEYBOARD */
5725 /***********************************************************************
5727 ***********************************************************************/
5729 /* Keep this list in the same order as frame_parms in frame.c.
5730 Use 0 for unsupported frame parameters. */
5732 frame_parm_handler x_frame_parm_handlers
[] =
5736 x_set_background_color
,
5742 x_set_foreground_color
,
5745 x_set_internal_border_width
,
5746 x_set_menu_bar_lines
,
5748 x_explicitly_set_name
,
5749 x_set_scroll_bar_width
,
5752 x_set_vertical_scroll_bars
,
5754 x_set_tool_bar_lines
,
5755 x_set_scroll_bar_foreground
,
5756 x_set_scroll_bar_background
,
5768 /* This is zero if not using X windows. */
5771 /* The section below is built by the lisp expression at the top of the file,
5772 just above where these variables are declared. */
5773 /*&&& init symbols here &&&*/
5774 Qnone
= intern ("none");
5776 Qsuppress_icon
= intern ("suppress-icon");
5777 staticpro (&Qsuppress_icon
);
5778 Qundefined_color
= intern ("undefined-color");
5779 staticpro (&Qundefined_color
);
5780 Qcompound_text
= intern ("compound-text");
5781 staticpro (&Qcompound_text
);
5782 Qcancel_timer
= intern ("cancel-timer");
5783 staticpro (&Qcancel_timer
);
5784 /* This is the end of symbol initialization. */
5786 /* Text property `display' should be nonsticky by default. */
5787 Vtext_property_default_nonsticky
5788 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
5791 Fput (Qundefined_color
, Qerror_conditions
,
5792 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
5793 Fput (Qundefined_color
, Qerror_message
,
5794 build_string ("Undefined color"));
5796 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
5797 doc
: /* The shape of the pointer when over text.
5798 Changing the value does not affect existing frames
5799 unless you set the mouse color. */);
5800 Vx_pointer_shape
= Qnil
;
5802 #if 0 /* This doesn't really do anything. */
5803 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
5804 doc
: /* The shape of the pointer when not over text.
5805 This variable takes effect when you create a new frame
5806 or when you set the mouse color. */);
5808 Vx_nontext_pointer_shape
= Qnil
;
5810 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
5811 doc
: /* The shape of the pointer when Emacs is busy.
5812 This variable takes effect when you create a new frame
5813 or when you set the mouse color. */);
5814 Vx_hourglass_pointer_shape
= Qnil
;
5816 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
5817 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
5818 display_hourglass_p
= 1;
5820 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
5821 doc
: /* *Seconds to wait before displaying an hourglass pointer.
5822 Value must be an integer or float. */);
5823 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
5825 #if 0 /* This doesn't really do anything. */
5826 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
5827 doc
: /* The shape of the pointer when over the mode line.
5828 This variable takes effect when you create a new frame
5829 or when you set the mouse color. */);
5831 Vx_mode_pointer_shape
= Qnil
;
5833 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5834 &Vx_sensitive_text_pointer_shape
,
5835 doc
: /* The shape of the pointer when over mouse-sensitive text.
5836 This variable takes effect when you create a new frame
5837 or when you set the mouse color. */);
5838 Vx_sensitive_text_pointer_shape
= Qnil
;
5840 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5841 &Vx_window_horizontal_drag_shape
,
5842 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
5843 This variable takes effect when you create a new frame
5844 or when you set the mouse color. */);
5845 Vx_window_horizontal_drag_shape
= Qnil
;
5847 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
5848 doc
: /* A string indicating the foreground color of the cursor box. */);
5849 Vx_cursor_fore_pixel
= Qnil
;
5851 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size
,
5852 doc
: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
5853 Text larger than this is clipped. */);
5854 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
5856 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
5857 doc
: /* Non-nil if no X window manager is in use.
5858 Emacs doesn't try to figure this out; this is always nil
5859 unless you set it to something else. */);
5860 /* We don't have any way to find this out, so set it to nil
5861 and maybe the user would like to set it to t. */
5862 Vx_no_window_manager
= Qnil
;
5864 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5865 &Vx_pixel_size_width_font_regexp
,
5866 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5868 Since Emacs gets width of a font matching with this regexp from
5869 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5870 such a font. This is especially effective for such large fonts as
5871 Chinese, Japanese, and Korean. */);
5872 Vx_pixel_size_width_font_regexp
= Qnil
;
5874 /* This is not ifdef:ed, so other builds than GTK can customize it. */
5875 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog
,
5876 doc
: /* *Non-nil means prompt with the old GTK file selection dialog.
5877 If nil or if the file selection dialog is not available, the new GTK file
5878 chooser is used instead. To turn off all file dialogs set the
5879 variable `use-file-dialog'. */);
5880 x_gtk_use_old_file_dialog
= 0;
5882 DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files
,
5883 doc
: /* *If non-nil, the GTK file chooser will by default show hidden files.
5884 Note that this is just the default, there is a toggle button on the file
5885 chooser to show or not show hidden files on a case by case basis. */);
5886 x_gtk_show_hidden_files
= 0;
5888 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text
,
5889 doc
: /* *If non-nil, the GTK file chooser will show additional help text.
5890 If more space for files in the file chooser dialog is wanted, set this to nil
5891 to turn the additional text off. */);
5892 x_gtk_file_dialog_help_text
= 1;
5894 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar
,
5895 doc
: /* *If non-nil, a detached tool bar is shown in full.
5896 The default is to just show an arrow and pressing on that arrow shows
5897 the tool bar buttons. */);
5898 x_gtk_whole_detached_tool_bar
= 0;
5900 Fprovide (intern ("x"), Qnil
);
5902 #ifdef USE_X_TOOLKIT
5903 Fprovide (intern ("x-toolkit"), Qnil
);
5905 Fprovide (intern ("motif"), Qnil
);
5907 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
,
5908 doc
: /* Version info for LessTif/Motif. */);
5909 Vmotif_version_string
= build_string (XmVERSION_STRING
);
5910 #endif /* USE_MOTIF */
5911 #endif /* USE_X_TOOLKIT */
5914 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
5915 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
5916 But for a user it is a toolkit for X, and indeed, configure
5917 accepts --with-x-toolkit=gtk. */
5918 Fprovide (intern ("x-toolkit"), Qnil
);
5919 Fprovide (intern ("gtk"), Qnil
);
5921 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string
,
5922 doc
: /* Version info for GTK+. */);
5924 char gtk_version
[40];
5925 g_snprintf (gtk_version
, sizeof (gtk_version
), "%u.%u.%u",
5926 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
5927 Vgtk_version_string
= build_string (gtk_version
);
5929 #endif /* USE_GTK */
5931 /* X window properties. */
5932 defsubr (&Sx_change_window_property
);
5933 defsubr (&Sx_delete_window_property
);
5934 defsubr (&Sx_window_property
);
5936 defsubr (&Sxw_display_color_p
);
5937 defsubr (&Sx_display_grayscale_p
);
5938 defsubr (&Sxw_color_defined_p
);
5939 defsubr (&Sxw_color_values
);
5940 defsubr (&Sx_server_max_request_size
);
5941 defsubr (&Sx_server_vendor
);
5942 defsubr (&Sx_server_version
);
5943 defsubr (&Sx_display_pixel_width
);
5944 defsubr (&Sx_display_pixel_height
);
5945 defsubr (&Sx_display_mm_width
);
5946 defsubr (&Sx_display_mm_height
);
5947 defsubr (&Sx_display_screens
);
5948 defsubr (&Sx_display_planes
);
5949 defsubr (&Sx_display_color_cells
);
5950 defsubr (&Sx_display_visual_class
);
5951 defsubr (&Sx_display_backing_store
);
5952 defsubr (&Sx_display_save_under
);
5953 defsubr (&Sx_create_frame
);
5954 defsubr (&Sx_open_connection
);
5955 defsubr (&Sx_close_connection
);
5956 defsubr (&Sx_display_list
);
5957 defsubr (&Sx_synchronize
);
5958 defsubr (&Sx_focus_frame
);
5959 defsubr (&Sx_backspace_delete_keys_p
);
5961 /* Setting callback functions for fontset handler. */
5962 get_font_info_func
= x_get_font_info
;
5964 #if 0 /* This function pointer doesn't seem to be used anywhere.
5965 And the pointer assigned has the wrong type, anyway. */
5966 list_fonts_func
= x_list_fonts
;
5969 load_font_func
= x_load_font
;
5970 find_ccl_program_func
= x_find_ccl_program
;
5971 query_font_func
= x_query_font
;
5972 set_frame_fontset_func
= x_set_font
;
5973 check_window_system_func
= check_x
;
5975 hourglass_atimer
= NULL
;
5976 hourglass_shown_p
= 0;
5978 defsubr (&Sx_show_tip
);
5979 defsubr (&Sx_hide_tip
);
5981 staticpro (&tip_timer
);
5983 staticpro (&tip_frame
);
5985 last_show_tip_args
= Qnil
;
5986 staticpro (&last_show_tip_args
);
5988 defsubr (&Sx_uses_old_gtk_dialog
);
5989 #if defined (USE_MOTIF) || defined (USE_GTK)
5990 defsubr (&Sx_file_dialog
);
5994 #endif /* HAVE_X_WINDOWS */
5996 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
5997 (do not change this comment) */