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