Add emacs-xtra.
[emacs.git] / src / xfns.c
blob931d31bcedf5a14d33e0039e8350b32a0312276d
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 /* The background and shape of the mouse pointer, and shape when not
155 over text or in the modeline. */
157 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
158 Lisp_Object Vx_hourglass_pointer_shape;
160 /* The shape when over mouse-sensitive text. */
162 Lisp_Object Vx_sensitive_text_pointer_shape;
164 /* If non-nil, the pointer shape to indicate that windows can be
165 dragged horizontally. */
167 Lisp_Object Vx_window_horizontal_drag_shape;
169 /* Color of chars displayed in cursor box. */
171 Lisp_Object Vx_cursor_fore_pixel;
173 /* Nonzero if using X. */
175 static int x_in_use;
177 /* Non nil if no window manager is in use. */
179 Lisp_Object Vx_no_window_manager;
181 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
183 Lisp_Object Vx_pixel_size_width_font_regexp;
185 Lisp_Object Qnone;
186 Lisp_Object Qsuppress_icon;
187 Lisp_Object Qundefined_color;
188 Lisp_Object Qcompound_text, Qcancel_timer;
190 /* In dispnew.c */
192 extern Lisp_Object Vwindow_system_version;
194 /* The below are defined in frame.c. */
196 #if GLYPH_DEBUG
197 int image_cache_refcount, dpyinfo_refcount;
198 #endif
202 /* Error if we are not connected to X. */
204 void
205 check_x ()
207 if (! x_in_use)
208 error ("X windows are not in use or not initialized");
211 /* Nonzero if we can use mouse menus.
212 You should not call this unless HAVE_MENUS is defined. */
215 have_menus_p ()
217 return x_in_use;
220 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
221 and checking validity for X. */
223 FRAME_PTR
224 check_x_frame (frame)
225 Lisp_Object frame;
227 FRAME_PTR f;
229 if (NILP (frame))
230 frame = selected_frame;
231 CHECK_LIVE_FRAME (frame);
232 f = XFRAME (frame);
233 if (! FRAME_X_P (f))
234 error ("Non-X frame used");
235 return f;
238 /* Let the user specify an X display with a frame.
239 nil stands for the selected frame--or, if that is not an X frame,
240 the first X display on the list. */
242 struct x_display_info *
243 check_x_display_info (frame)
244 Lisp_Object frame;
246 struct x_display_info *dpyinfo = NULL;
248 if (NILP (frame))
250 struct frame *sf = XFRAME (selected_frame);
252 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
253 dpyinfo = FRAME_X_DISPLAY_INFO (sf);
254 else if (x_display_list != 0)
255 dpyinfo = x_display_list;
256 else
257 error ("X windows are not in use or not initialized");
259 else if (STRINGP (frame))
260 dpyinfo = x_display_info_for_name (frame);
261 else
263 FRAME_PTR f = check_x_frame (frame);
264 dpyinfo = FRAME_X_DISPLAY_INFO (f);
267 return dpyinfo;
271 /* Return the Emacs frame-object corresponding to an X window.
272 It could be the frame's main window or an icon window. */
274 /* This function can be called during GC, so use GC_xxx type test macros. */
276 struct frame *
277 x_window_to_frame (dpyinfo, wdesc)
278 struct x_display_info *dpyinfo;
279 int wdesc;
281 Lisp_Object tail, frame;
282 struct frame *f;
284 for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
286 frame = XCAR (tail);
287 if (!GC_FRAMEP (frame))
288 continue;
289 f = XFRAME (frame);
290 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
291 continue;
292 if (f->output_data.x->hourglass_window == wdesc)
293 return f;
294 #ifdef USE_X_TOOLKIT
295 if ((f->output_data.x->edit_widget
296 && XtWindow (f->output_data.x->edit_widget) == wdesc)
297 /* A tooltip frame? */
298 || (!f->output_data.x->edit_widget
299 && FRAME_X_WINDOW (f) == wdesc)
300 || f->output_data.x->icon_desc == wdesc)
301 return f;
302 #else /* not USE_X_TOOLKIT */
303 #ifdef USE_GTK
304 if (f->output_data.x->edit_widget)
306 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
307 struct x_output *x = f->output_data.x;
308 if (gwdesc != 0 && gwdesc == x->edit_widget)
309 return f;
311 #endif /* USE_GTK */
312 if (FRAME_X_WINDOW (f) == wdesc
313 || f->output_data.x->icon_desc == wdesc)
314 return f;
315 #endif /* not USE_X_TOOLKIT */
317 return 0;
320 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
321 /* Like x_window_to_frame but also compares the window with the widget's
322 windows. */
324 struct frame *
325 x_any_window_to_frame (dpyinfo, wdesc)
326 struct x_display_info *dpyinfo;
327 int wdesc;
329 Lisp_Object tail, frame;
330 struct frame *f, *found;
331 struct x_output *x;
333 found = NULL;
334 for (tail = Vframe_list; GC_CONSP (tail) && !found; tail = XCDR (tail))
336 frame = XCAR (tail);
337 if (!GC_FRAMEP (frame))
338 continue;
340 f = XFRAME (frame);
341 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
343 /* This frame matches if the window is any of its widgets. */
344 x = f->output_data.x;
345 if (x->hourglass_window == wdesc)
346 found = f;
347 else if (x->widget)
349 #ifdef USE_GTK
350 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
351 if (gwdesc != 0
352 && (gwdesc == x->widget
353 || gwdesc == x->edit_widget
354 || gwdesc == x->vbox_widget
355 || gwdesc == x->menubar_widget))
356 found = f;
357 #else
358 if (wdesc == XtWindow (x->widget)
359 || wdesc == XtWindow (x->column_widget)
360 || wdesc == XtWindow (x->edit_widget))
361 found = f;
362 /* Match if the window is this frame's menubar. */
363 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
364 found = f;
365 #endif
367 else if (FRAME_X_WINDOW (f) == wdesc)
368 /* A tooltip frame. */
369 found = f;
373 return found;
376 /* Likewise, but exclude the menu bar widget. */
378 struct frame *
379 x_non_menubar_window_to_frame (dpyinfo, wdesc)
380 struct x_display_info *dpyinfo;
381 int wdesc;
383 Lisp_Object tail, frame;
384 struct frame *f;
385 struct x_output *x;
387 for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
389 frame = XCAR (tail);
390 if (!GC_FRAMEP (frame))
391 continue;
392 f = XFRAME (frame);
393 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
394 continue;
395 x = f->output_data.x;
396 /* This frame matches if the window is any of its widgets. */
397 if (x->hourglass_window == wdesc)
398 return f;
399 else if (x->widget)
401 #ifdef USE_GTK
402 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
403 if (gwdesc != 0
404 && (gwdesc == x->widget
405 || gwdesc == x->edit_widget
406 || gwdesc == x->vbox_widget))
407 return f;
408 #else
409 if (wdesc == XtWindow (x->widget)
410 || wdesc == XtWindow (x->column_widget)
411 || wdesc == XtWindow (x->edit_widget))
412 return f;
413 #endif
415 else if (FRAME_X_WINDOW (f) == wdesc)
416 /* A tooltip frame. */
417 return f;
419 return 0;
422 /* Likewise, but consider only the menu bar widget. */
424 struct frame *
425 x_menubar_window_to_frame (dpyinfo, wdesc)
426 struct x_display_info *dpyinfo;
427 int wdesc;
429 Lisp_Object tail, frame;
430 struct frame *f;
431 struct x_output *x;
433 for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
435 frame = XCAR (tail);
436 if (!GC_FRAMEP (frame))
437 continue;
438 f = XFRAME (frame);
439 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
440 continue;
441 x = f->output_data.x;
442 /* Match if the window is this frame's menubar. */
443 #ifdef USE_GTK
444 if (x->menubar_widget)
446 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
447 int found = 0;
449 BLOCK_INPUT;
450 if (gwdesc != 0
451 && (gwdesc == x->menubar_widget
452 || gtk_widget_get_parent (gwdesc) == x->menubar_widget))
453 found = 1;
454 UNBLOCK_INPUT;
455 if (found) return f;
457 #else
458 if (x->menubar_widget
459 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
460 return f;
461 #endif
463 return 0;
466 /* Return the frame whose principal (outermost) window is WDESC.
467 If WDESC is some other (smaller) window, we return 0. */
469 struct frame *
470 x_top_window_to_frame (dpyinfo, wdesc)
471 struct x_display_info *dpyinfo;
472 int wdesc;
474 Lisp_Object tail, frame;
475 struct frame *f;
476 struct x_output *x;
478 for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
480 frame = XCAR (tail);
481 if (!GC_FRAMEP (frame))
482 continue;
483 f = XFRAME (frame);
484 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
485 continue;
486 x = f->output_data.x;
488 if (x->widget)
490 /* This frame matches if the window is its topmost widget. */
491 #ifdef USE_GTK
492 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
493 if (gwdesc == x->widget)
494 return f;
495 #else
496 if (wdesc == XtWindow (x->widget))
497 return f;
498 #if 0 /* I don't know why it did this,
499 but it seems logically wrong,
500 and it causes trouble for MapNotify events. */
501 /* Match if the window is this frame's menubar. */
502 if (x->menubar_widget
503 && wdesc == XtWindow (x->menubar_widget))
504 return f;
505 #endif
506 #endif
508 else if (FRAME_X_WINDOW (f) == wdesc)
509 /* Tooltip frame. */
510 return f;
512 return 0;
514 #endif /* USE_X_TOOLKIT || USE_GTK */
518 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
519 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
521 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
522 static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object));
523 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
524 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
525 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
526 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
527 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
528 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
529 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
530 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
531 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
532 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
533 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
534 void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object,
535 Lisp_Object));
536 void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object,
537 Lisp_Object));
538 static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
539 Lisp_Object,
540 Lisp_Object,
541 char *, char *,
542 int));
545 /* Store the screen positions of frame F into XPTR and YPTR.
546 These are the positions of the containing window manager window,
547 not Emacs's own window. */
549 void
550 x_real_positions (f, xptr, yptr)
551 FRAME_PTR f;
552 int *xptr, *yptr;
554 int win_x, win_y, outer_x, outer_y;
555 int real_x = 0, real_y = 0;
556 int had_errors = 0;
557 Window win = f->output_data.x->parent_desc;
559 int count;
561 BLOCK_INPUT;
563 count = x_catch_errors (FRAME_X_DISPLAY (f));
565 if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
566 win = FRAME_OUTER_WINDOW (f);
568 /* This loop traverses up the containment tree until we hit the root
569 window. Window managers may intersect many windows between our window
570 and the root window. The window we find just before the root window
571 should be the outer WM window. */
572 for (;;)
574 Window wm_window, rootw;
575 Window *tmp_children;
576 unsigned int tmp_nchildren;
577 int success;
579 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
580 &wm_window, &tmp_children, &tmp_nchildren);
582 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
584 /* Don't free tmp_children if XQueryTree failed. */
585 if (! success)
586 break;
588 XFree ((char *) tmp_children);
590 if (wm_window == rootw || had_errors)
591 break;
593 win = wm_window;
596 if (! had_errors)
598 int ign;
599 Window child, rootw;
601 /* Get the real coordinates for the WM window upper left corner */
602 XGetGeometry (FRAME_X_DISPLAY (f), win,
603 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
605 /* Translate real coordinates to coordinates relative to our
606 window. For our window, the upper left corner is 0, 0.
607 Since the upper left corner of the WM window is outside
608 our window, win_x and win_y will be negative:
610 ------------------ ---> x
611 | title |
612 | ----------------- v y
613 | | our window
615 XTranslateCoordinates (FRAME_X_DISPLAY (f),
617 /* From-window, to-window. */
618 FRAME_X_DISPLAY_INFO (f)->root_window,
619 FRAME_X_WINDOW (f),
621 /* From-position, to-position. */
622 real_x, real_y, &win_x, &win_y,
624 /* Child of win. */
625 &child);
627 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
629 outer_x = win_x;
630 outer_y = win_y;
632 else
634 XTranslateCoordinates (FRAME_X_DISPLAY (f),
636 /* From-window, to-window. */
637 FRAME_X_DISPLAY_INFO (f)->root_window,
638 FRAME_OUTER_WINDOW (f),
640 /* From-position, to-position. */
641 real_x, real_y, &outer_x, &outer_y,
643 /* Child of win. */
644 &child);
647 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
650 x_uncatch_errors (FRAME_X_DISPLAY (f), count);
652 UNBLOCK_INPUT;
654 if (had_errors) return;
656 f->x_pixels_diff = -win_x;
657 f->y_pixels_diff = -win_y;
659 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
660 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
662 *xptr = real_x;
663 *yptr = real_y;
669 /* Gamma-correct COLOR on frame F. */
671 void
672 gamma_correct (f, color)
673 struct frame *f;
674 XColor *color;
676 if (f->gamma)
678 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
679 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
680 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
685 /* Decide if color named COLOR_NAME is valid for use on frame F. If
686 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
687 allocate the color. Value is zero if COLOR_NAME is invalid, or
688 no color could be allocated. */
691 x_defined_color (f, color_name, color, alloc_p)
692 struct frame *f;
693 char *color_name;
694 XColor *color;
695 int alloc_p;
697 int success_p;
698 Display *dpy = FRAME_X_DISPLAY (f);
699 Colormap cmap = FRAME_X_COLORMAP (f);
701 BLOCK_INPUT;
702 success_p = XParseColor (dpy, cmap, color_name, color);
703 if (success_p && alloc_p)
704 success_p = x_alloc_nearest_color (f, cmap, color);
705 UNBLOCK_INPUT;
707 return success_p;
711 /* Return the pixel color value for color COLOR_NAME on frame F. If F
712 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
713 Signal an error if color can't be allocated. */
716 x_decode_color (f, color_name, mono_color)
717 FRAME_PTR f;
718 Lisp_Object color_name;
719 int mono_color;
721 XColor cdef;
723 CHECK_STRING (color_name);
725 #if 0 /* Don't do this. It's wrong when we're not using the default
726 colormap, it makes freeing difficult, and it's probably not
727 an important optimization. */
728 if (strcmp (SDATA (color_name), "black") == 0)
729 return BLACK_PIX_DEFAULT (f);
730 else if (strcmp (SDATA (color_name), "white") == 0)
731 return WHITE_PIX_DEFAULT (f);
732 #endif
734 /* Return MONO_COLOR for monochrome frames. */
735 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
736 return mono_color;
738 /* x_defined_color is responsible for coping with failures
739 by looking for a near-miss. */
740 if (x_defined_color (f, SDATA (color_name), &cdef, 1))
741 return cdef.pixel;
743 Fsignal (Qerror, Fcons (build_string ("Undefined color"),
744 Fcons (color_name, Qnil)));
745 return 0;
750 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
751 the previous value of that parameter, NEW_VALUE is the new value.
752 See also the comment of wait_for_wm in struct x_output. */
754 static void
755 x_set_wait_for_wm (f, new_value, old_value)
756 struct frame *f;
757 Lisp_Object new_value, old_value;
759 f->output_data.x->wait_for_wm = !NILP (new_value);
762 #ifdef USE_GTK
764 /* Set icon from FILE for frame F. By using GTK functions the icon
765 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
768 xg_set_icon (f, file)
769 FRAME_PTR f;
770 Lisp_Object file;
772 struct gcpro gcpro1;
773 int result = 0;
774 Lisp_Object found;
776 GCPRO1 (found);
778 found = x_find_image_file (file);
780 if (! NILP (found))
782 GdkPixbuf *pixbuf;
783 GError *err = NULL;
784 char *filename;
786 filename = SDATA (found);
787 BLOCK_INPUT;
789 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
791 if (pixbuf)
793 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
794 pixbuf);
795 g_object_unref (pixbuf);
797 result = 1;
799 else
800 g_error_free (err);
802 UNBLOCK_INPUT;
805 UNGCPRO;
806 return result;
808 #endif /* USE_GTK */
811 /* Functions called only from `x_set_frame_param'
812 to set individual parameters.
814 If FRAME_X_WINDOW (f) is 0,
815 the frame is being created and its X-window does not exist yet.
816 In that case, just record the parameter's new value
817 in the standard place; do not attempt to change the window. */
819 void
820 x_set_foreground_color (f, arg, oldval)
821 struct frame *f;
822 Lisp_Object arg, oldval;
824 struct x_output *x = f->output_data.x;
825 unsigned long fg, old_fg;
827 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
828 old_fg = x->foreground_pixel;
829 x->foreground_pixel = fg;
831 if (FRAME_X_WINDOW (f) != 0)
833 Display *dpy = FRAME_X_DISPLAY (f);
835 BLOCK_INPUT;
836 XSetForeground (dpy, x->normal_gc, fg);
837 XSetBackground (dpy, x->reverse_gc, fg);
839 if (x->cursor_pixel == old_fg)
841 unload_color (f, x->cursor_pixel);
842 x->cursor_pixel = x_copy_color (f, fg);
843 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
846 UNBLOCK_INPUT;
848 update_face_from_frame_parameter (f, Qforeground_color, arg);
850 if (FRAME_VISIBLE_P (f))
851 redraw_frame (f);
854 unload_color (f, old_fg);
857 void
858 x_set_background_color (f, arg, oldval)
859 struct frame *f;
860 Lisp_Object arg, oldval;
862 struct x_output *x = f->output_data.x;
863 unsigned long bg;
865 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
866 unload_color (f, x->background_pixel);
867 x->background_pixel = bg;
869 if (FRAME_X_WINDOW (f) != 0)
871 Display *dpy = FRAME_X_DISPLAY (f);
873 BLOCK_INPUT;
874 XSetBackground (dpy, x->normal_gc, bg);
875 XSetForeground (dpy, x->reverse_gc, bg);
876 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
877 XSetForeground (dpy, x->cursor_gc, bg);
879 #ifdef USE_GTK
880 xg_set_background_color (f, bg);
881 #endif
883 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
884 toolkit scroll bars. */
886 Lisp_Object bar;
887 for (bar = FRAME_SCROLL_BARS (f);
888 !NILP (bar);
889 bar = XSCROLL_BAR (bar)->next)
891 Window window = SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar));
892 XSetWindowBackground (dpy, window, bg);
895 #endif /* USE_TOOLKIT_SCROLL_BARS */
897 UNBLOCK_INPUT;
898 update_face_from_frame_parameter (f, Qbackground_color, arg);
900 if (FRAME_VISIBLE_P (f))
901 redraw_frame (f);
905 void
906 x_set_mouse_color (f, arg, oldval)
907 struct frame *f;
908 Lisp_Object arg, oldval;
910 struct x_output *x = f->output_data.x;
911 Display *dpy = FRAME_X_DISPLAY (f);
912 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
913 Cursor hourglass_cursor, horizontal_drag_cursor;
914 int count;
915 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
916 unsigned long mask_color = x->background_pixel;
918 /* Don't let pointers be invisible. */
919 if (mask_color == pixel)
921 x_free_colors (f, &pixel, 1);
922 pixel = x_copy_color (f, x->foreground_pixel);
925 unload_color (f, x->mouse_pixel);
926 x->mouse_pixel = pixel;
928 BLOCK_INPUT;
930 /* It's not okay to crash if the user selects a screwy cursor. */
931 count = x_catch_errors (dpy);
933 if (!NILP (Vx_pointer_shape))
935 CHECK_NUMBER (Vx_pointer_shape);
936 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
938 else
939 cursor = XCreateFontCursor (dpy, XC_xterm);
940 x_check_errors (dpy, "bad text pointer cursor: %s");
942 if (!NILP (Vx_nontext_pointer_shape))
944 CHECK_NUMBER (Vx_nontext_pointer_shape);
945 nontext_cursor
946 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
948 else
949 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
950 x_check_errors (dpy, "bad nontext pointer cursor: %s");
952 if (!NILP (Vx_hourglass_pointer_shape))
954 CHECK_NUMBER (Vx_hourglass_pointer_shape);
955 hourglass_cursor
956 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
958 else
959 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
960 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
962 if (!NILP (Vx_mode_pointer_shape))
964 CHECK_NUMBER (Vx_mode_pointer_shape);
965 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
967 else
968 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
969 x_check_errors (dpy, "bad modeline pointer cursor: %s");
971 if (!NILP (Vx_sensitive_text_pointer_shape))
973 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
974 hand_cursor
975 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
977 else
978 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
980 if (!NILP (Vx_window_horizontal_drag_shape))
982 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
983 horizontal_drag_cursor
984 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
986 else
987 horizontal_drag_cursor
988 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
990 /* Check and report errors with the above calls. */
991 x_check_errors (dpy, "can't set cursor shape: %s");
992 x_uncatch_errors (dpy, count);
995 XColor fore_color, back_color;
997 fore_color.pixel = x->mouse_pixel;
998 x_query_color (f, &fore_color);
999 back_color.pixel = mask_color;
1000 x_query_color (f, &back_color);
1002 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1003 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1004 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1005 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1006 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1007 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1010 if (FRAME_X_WINDOW (f) != 0)
1011 XDefineCursor (dpy, FRAME_X_WINDOW (f), cursor);
1013 if (cursor != x->text_cursor
1014 && x->text_cursor != 0)
1015 XFreeCursor (dpy, x->text_cursor);
1016 x->text_cursor = cursor;
1018 if (nontext_cursor != x->nontext_cursor
1019 && x->nontext_cursor != 0)
1020 XFreeCursor (dpy, x->nontext_cursor);
1021 x->nontext_cursor = nontext_cursor;
1023 if (hourglass_cursor != x->hourglass_cursor
1024 && x->hourglass_cursor != 0)
1025 XFreeCursor (dpy, x->hourglass_cursor);
1026 x->hourglass_cursor = hourglass_cursor;
1028 if (mode_cursor != x->modeline_cursor
1029 && x->modeline_cursor != 0)
1030 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1031 x->modeline_cursor = mode_cursor;
1033 if (hand_cursor != x->hand_cursor
1034 && x->hand_cursor != 0)
1035 XFreeCursor (dpy, x->hand_cursor);
1036 x->hand_cursor = hand_cursor;
1038 if (horizontal_drag_cursor != x->horizontal_drag_cursor
1039 && x->horizontal_drag_cursor != 0)
1040 XFreeCursor (dpy, x->horizontal_drag_cursor);
1041 x->horizontal_drag_cursor = horizontal_drag_cursor;
1043 XFlush (dpy);
1044 UNBLOCK_INPUT;
1046 update_face_from_frame_parameter (f, Qmouse_color, arg);
1049 void
1050 x_set_cursor_color (f, arg, oldval)
1051 struct frame *f;
1052 Lisp_Object arg, oldval;
1054 unsigned long fore_pixel, pixel;
1055 int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
1056 struct x_output *x = f->output_data.x;
1058 if (!NILP (Vx_cursor_fore_pixel))
1060 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1061 WHITE_PIX_DEFAULT (f));
1062 fore_pixel_allocated_p = 1;
1064 else
1065 fore_pixel = x->background_pixel;
1067 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1068 pixel_allocated_p = 1;
1070 /* Make sure that the cursor color differs from the background color. */
1071 if (pixel == x->background_pixel)
1073 if (pixel_allocated_p)
1075 x_free_colors (f, &pixel, 1);
1076 pixel_allocated_p = 0;
1079 pixel = x->mouse_pixel;
1080 if (pixel == fore_pixel)
1082 if (fore_pixel_allocated_p)
1084 x_free_colors (f, &fore_pixel, 1);
1085 fore_pixel_allocated_p = 0;
1087 fore_pixel = x->background_pixel;
1091 unload_color (f, x->cursor_foreground_pixel);
1092 if (!fore_pixel_allocated_p)
1093 fore_pixel = x_copy_color (f, fore_pixel);
1094 x->cursor_foreground_pixel = fore_pixel;
1096 unload_color (f, x->cursor_pixel);
1097 if (!pixel_allocated_p)
1098 pixel = x_copy_color (f, pixel);
1099 x->cursor_pixel = pixel;
1101 if (FRAME_X_WINDOW (f) != 0)
1103 BLOCK_INPUT;
1104 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1105 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1106 UNBLOCK_INPUT;
1108 if (FRAME_VISIBLE_P (f))
1110 x_update_cursor (f, 0);
1111 x_update_cursor (f, 1);
1115 update_face_from_frame_parameter (f, Qcursor_color, arg);
1118 /* Set the border-color of frame F to pixel value PIX.
1119 Note that this does not fully take effect if done before
1120 F has an x-window. */
1122 void
1123 x_set_border_pixel (f, pix)
1124 struct frame *f;
1125 int pix;
1127 unload_color (f, f->output_data.x->border_pixel);
1128 f->output_data.x->border_pixel = pix;
1130 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1132 BLOCK_INPUT;
1133 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1134 (unsigned long)pix);
1135 UNBLOCK_INPUT;
1137 if (FRAME_VISIBLE_P (f))
1138 redraw_frame (f);
1142 /* Set the border-color of frame F to value described by ARG.
1143 ARG can be a string naming a color.
1144 The border-color is used for the border that is drawn by the X server.
1145 Note that this does not fully take effect if done before
1146 F has an x-window; it must be redone when the window is created.
1148 Note: this is done in two routines because of the way X10 works.
1150 Note: under X11, this is normally the province of the window manager,
1151 and so emacs' border colors may be overridden. */
1153 void
1154 x_set_border_color (f, arg, oldval)
1155 struct frame *f;
1156 Lisp_Object arg, oldval;
1158 int pix;
1160 CHECK_STRING (arg);
1161 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1162 x_set_border_pixel (f, pix);
1163 update_face_from_frame_parameter (f, Qborder_color, arg);
1167 void
1168 x_set_cursor_type (f, arg, oldval)
1169 FRAME_PTR f;
1170 Lisp_Object arg, oldval;
1172 set_frame_cursor_types (f, arg);
1174 /* Make sure the cursor gets redrawn. */
1175 cursor_type_changed = 1;
1178 void
1179 x_set_icon_type (f, arg, oldval)
1180 struct frame *f;
1181 Lisp_Object arg, oldval;
1183 int result;
1185 if (STRINGP (arg))
1187 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1188 return;
1190 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1191 return;
1193 BLOCK_INPUT;
1194 if (NILP (arg))
1195 result = x_text_icon (f,
1196 (char *) SDATA ((!NILP (f->icon_name)
1197 ? f->icon_name
1198 : f->name)));
1199 else
1200 result = x_bitmap_icon (f, arg);
1202 if (result)
1204 UNBLOCK_INPUT;
1205 error ("No icon window available");
1208 XFlush (FRAME_X_DISPLAY (f));
1209 UNBLOCK_INPUT;
1212 void
1213 x_set_icon_name (f, arg, oldval)
1214 struct frame *f;
1215 Lisp_Object arg, oldval;
1217 int result;
1219 if (STRINGP (arg))
1221 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1222 return;
1224 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1225 return;
1227 f->icon_name = arg;
1229 if (f->output_data.x->icon_bitmap != 0)
1230 return;
1232 BLOCK_INPUT;
1234 result = x_text_icon (f,
1235 (char *) SDATA ((!NILP (f->icon_name)
1236 ? f->icon_name
1237 : !NILP (f->title)
1238 ? f->title
1239 : f->name)));
1241 if (result)
1243 UNBLOCK_INPUT;
1244 error ("No icon window available");
1247 XFlush (FRAME_X_DISPLAY (f));
1248 UNBLOCK_INPUT;
1252 void
1253 x_set_menu_bar_lines (f, value, oldval)
1254 struct frame *f;
1255 Lisp_Object value, oldval;
1257 int nlines;
1258 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1259 int olines = FRAME_MENU_BAR_LINES (f);
1260 #endif
1262 /* Right now, menu bars don't work properly in minibuf-only frames;
1263 most of the commands try to apply themselves to the minibuffer
1264 frame itself, and get an error because you can't switch buffers
1265 in or split the minibuffer window. */
1266 if (FRAME_MINIBUF_ONLY_P (f))
1267 return;
1269 if (INTEGERP (value))
1270 nlines = XINT (value);
1271 else
1272 nlines = 0;
1274 /* Make sure we redisplay all windows in this frame. */
1275 windows_or_buffers_changed++;
1277 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1278 FRAME_MENU_BAR_LINES (f) = 0;
1279 if (nlines)
1281 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1282 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1283 /* Make sure next redisplay shows the menu bar. */
1284 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1286 else
1288 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1289 free_frame_menubar (f);
1290 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1291 if (FRAME_X_P (f))
1292 f->output_data.x->menubar_widget = 0;
1294 #else /* not USE_X_TOOLKIT && not USE_GTK */
1295 FRAME_MENU_BAR_LINES (f) = nlines;
1296 change_window_heights (f->root_window, nlines - olines);
1297 #endif /* not USE_X_TOOLKIT */
1298 adjust_glyphs (f);
1302 /* Set the number of lines used for the tool bar of frame F to VALUE.
1303 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1304 is the old number of tool bar lines. This function changes the
1305 height of all windows on frame F to match the new tool bar height.
1306 The frame's height doesn't change. */
1308 void
1309 x_set_tool_bar_lines (f, value, oldval)
1310 struct frame *f;
1311 Lisp_Object value, oldval;
1313 int delta, nlines, root_height;
1314 Lisp_Object root_window;
1316 /* Treat tool bars like menu bars. */
1317 if (FRAME_MINIBUF_ONLY_P (f))
1318 return;
1320 /* Use VALUE only if an integer >= 0. */
1321 if (INTEGERP (value) && XINT (value) >= 0)
1322 nlines = XFASTINT (value);
1323 else
1324 nlines = 0;
1326 #ifdef USE_GTK
1327 FRAME_TOOL_BAR_LINES (f) = 0;
1328 if (nlines)
1330 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1331 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1332 /* Make sure next redisplay shows the tool bar. */
1333 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1334 update_frame_tool_bar (f);
1336 else
1338 if (FRAME_EXTERNAL_TOOL_BAR (f))
1339 free_frame_tool_bar (f);
1340 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1343 return;
1344 #endif
1346 /* Make sure we redisplay all windows in this frame. */
1347 ++windows_or_buffers_changed;
1349 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1351 /* Don't resize the tool-bar to more than we have room for. */
1352 root_window = FRAME_ROOT_WINDOW (f);
1353 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1354 if (root_height - delta < 1)
1356 delta = root_height - 1;
1357 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1360 FRAME_TOOL_BAR_LINES (f) = nlines;
1361 change_window_heights (root_window, delta);
1362 adjust_glyphs (f);
1364 /* We also have to make sure that the internal border at the top of
1365 the frame, below the menu bar or tool bar, is redrawn when the
1366 tool bar disappears. This is so because the internal border is
1367 below the tool bar if one is displayed, but is below the menu bar
1368 if there isn't a tool bar. The tool bar draws into the area
1369 below the menu bar. */
1370 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1372 updating_frame = f;
1373 clear_frame ();
1374 clear_current_matrices (f);
1375 updating_frame = NULL;
1378 /* If the tool bar gets smaller, the internal border below it
1379 has to be cleared. It was formerly part of the display
1380 of the larger tool bar, and updating windows won't clear it. */
1381 if (delta < 0)
1383 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1384 int width = FRAME_PIXEL_WIDTH (f);
1385 int y = nlines * FRAME_LINE_HEIGHT (f);
1387 BLOCK_INPUT;
1388 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1389 0, y, width, height, False);
1390 UNBLOCK_INPUT;
1392 if (WINDOWP (f->tool_bar_window))
1393 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1398 /* Set the foreground color for scroll bars on frame F to VALUE.
1399 VALUE should be a string, a color name. If it isn't a string or
1400 isn't a valid color name, do nothing. OLDVAL is the old value of
1401 the frame parameter. */
1403 void
1404 x_set_scroll_bar_foreground (f, value, oldval)
1405 struct frame *f;
1406 Lisp_Object value, oldval;
1408 unsigned long pixel;
1410 if (STRINGP (value))
1411 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1412 else
1413 pixel = -1;
1415 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1416 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1418 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1419 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1421 /* Remove all scroll bars because they have wrong colors. */
1422 if (condemn_scroll_bars_hook)
1423 (*condemn_scroll_bars_hook) (f);
1424 if (judge_scroll_bars_hook)
1425 (*judge_scroll_bars_hook) (f);
1427 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1428 redraw_frame (f);
1433 /* Set the background color for scroll bars on frame F to VALUE VALUE
1434 should be a string, a color name. If it isn't a string or isn't a
1435 valid color name, do nothing. OLDVAL is the old value of the frame
1436 parameter. */
1438 void
1439 x_set_scroll_bar_background (f, value, oldval)
1440 struct frame *f;
1441 Lisp_Object value, oldval;
1443 unsigned long pixel;
1445 if (STRINGP (value))
1446 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1447 else
1448 pixel = -1;
1450 if (f->output_data.x->scroll_bar_background_pixel != -1)
1451 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1453 #ifdef USE_TOOLKIT_SCROLL_BARS
1454 /* Scrollbar shadow colors. */
1455 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1457 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1458 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1460 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1462 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1463 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1465 #endif /* USE_TOOLKIT_SCROLL_BARS */
1467 f->output_data.x->scroll_bar_background_pixel = pixel;
1468 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1470 /* Remove all scroll bars because they have wrong colors. */
1471 if (condemn_scroll_bars_hook)
1472 (*condemn_scroll_bars_hook) (f);
1473 if (judge_scroll_bars_hook)
1474 (*judge_scroll_bars_hook) (f);
1476 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1477 redraw_frame (f);
1482 /* Encode Lisp string STRING as a text in a format appropriate for
1483 XICCC (X Inter Client Communication Conventions).
1485 If STRING contains only ASCII characters, do no conversion and
1486 return the string data of STRING. Otherwise, encode the text by
1487 CODING_SYSTEM, and return a newly allocated memory area which
1488 should be freed by `xfree' by a caller.
1490 SELECTIONP non-zero means the string is being encoded for an X
1491 selection, so it is safe to run pre-write conversions (which
1492 may run Lisp code).
1494 Store the byte length of resulting text in *TEXT_BYTES.
1496 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1497 which means that the `encoding' of the result can be `STRING'.
1498 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1499 the result should be `COMPOUND_TEXT'. */
1501 unsigned char *
1502 x_encode_text (string, coding_system, selectionp, text_bytes, stringp)
1503 Lisp_Object string, coding_system;
1504 int *text_bytes, *stringp;
1505 int selectionp;
1507 unsigned char *str = SDATA (string);
1508 int chars = SCHARS (string);
1509 int bytes = SBYTES (string);
1510 int charset_info;
1511 int bufsize;
1512 unsigned char *buf;
1513 struct coding_system coding;
1514 extern Lisp_Object Qcompound_text_with_extensions;
1516 charset_info = find_charset_in_text (str, chars, bytes, NULL, Qnil);
1517 if (charset_info == 0)
1519 /* No multibyte character in OBJ. We need not encode it. */
1520 *text_bytes = bytes;
1521 *stringp = 1;
1522 return str;
1525 setup_coding_system (coding_system, &coding);
1526 if (selectionp
1527 && SYMBOLP (coding.pre_write_conversion)
1528 && !NILP (Ffboundp (coding.pre_write_conversion)))
1530 string = run_pre_post_conversion_on_str (string, &coding, 1);
1531 str = SDATA (string);
1532 chars = SCHARS (string);
1533 bytes = SBYTES (string);
1535 coding.src_multibyte = 1;
1536 coding.dst_multibyte = 0;
1537 coding.mode |= CODING_MODE_LAST_BLOCK;
1538 if (coding.type == coding_type_iso2022)
1539 coding.flags |= CODING_FLAG_ISO_SAFE;
1540 /* We suppress producing escape sequences for composition. */
1541 coding.composing = COMPOSITION_DISABLED;
1542 bufsize = encoding_buffer_size (&coding, bytes);
1543 buf = (unsigned char *) xmalloc (bufsize);
1544 encode_coding (&coding, str, buf, bytes, bufsize);
1545 *text_bytes = coding.produced;
1546 *stringp = (charset_info == 1
1547 || (!EQ (coding_system, Qcompound_text)
1548 && !EQ (coding_system, Qcompound_text_with_extensions)));
1549 return buf;
1553 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1554 x_id_name.
1556 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1557 name; if NAME is a string, set F's name to NAME and set
1558 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1560 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1561 suggesting a new name, which lisp code should override; if
1562 F->explicit_name is set, ignore the new name; otherwise, set it. */
1564 void
1565 x_set_name (f, name, explicit)
1566 struct frame *f;
1567 Lisp_Object name;
1568 int explicit;
1570 /* Make sure that requests from lisp code override requests from
1571 Emacs redisplay code. */
1572 if (explicit)
1574 /* If we're switching from explicit to implicit, we had better
1575 update the mode lines and thereby update the title. */
1576 if (f->explicit_name && NILP (name))
1577 update_mode_lines = 1;
1579 f->explicit_name = ! NILP (name);
1581 else if (f->explicit_name)
1582 return;
1584 /* If NAME is nil, set the name to the x_id_name. */
1585 if (NILP (name))
1587 /* Check for no change needed in this very common case
1588 before we do any consing. */
1589 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1590 SDATA (f->name)))
1591 return;
1592 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1594 else
1595 CHECK_STRING (name);
1597 /* Don't change the name if it's already NAME. */
1598 if (! NILP (Fstring_equal (name, f->name)))
1599 return;
1601 f->name = name;
1603 /* For setting the frame title, the title parameter should override
1604 the name parameter. */
1605 if (! NILP (f->title))
1606 name = f->title;
1608 if (FRAME_X_WINDOW (f))
1610 BLOCK_INPUT;
1611 #ifdef HAVE_X11R4
1613 XTextProperty text, icon;
1614 int bytes, stringp;
1615 Lisp_Object coding_system;
1617 /* Note: Encoding strategy
1619 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1620 text.encoding. But, there are non-internationalized window
1621 managers which don't support that encoding. So, if NAME
1622 contains only ASCII and 8859-1 characters, encode it by
1623 iso-latin-1, and use "STRING" in text.encoding hoping that
1624 such window managers at least analyze this format correctly,
1625 i.e. treat 8-bit bytes as 8859-1 characters.
1627 We may also be able to use "UTF8_STRING" in text.encoding
1628 in the future which can encode all Unicode characters.
1629 But, for the moment, there's no way to know that the
1630 current window manager supports it or not. */
1631 coding_system = Qcompound_text;
1632 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
1633 text.encoding = (stringp ? XA_STRING
1634 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1635 text.format = 8;
1636 text.nitems = bytes;
1638 if (NILP (f->icon_name))
1640 icon = text;
1642 else
1644 /* See the above comment "Note: Encoding strategy". */
1645 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1646 &bytes, &stringp);
1647 icon.encoding = (stringp ? XA_STRING
1648 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1649 icon.format = 8;
1650 icon.nitems = bytes;
1652 #ifdef USE_GTK
1653 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1654 SDATA (name));
1655 #else /* not USE_GTK */
1656 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1657 #endif /* not USE_GTK */
1659 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1661 if (!NILP (f->icon_name)
1662 && icon.value != (unsigned char *) SDATA (f->icon_name))
1663 xfree (icon.value);
1664 if (text.value != (unsigned char *) SDATA (name))
1665 xfree (text.value);
1667 #else /* not HAVE_X11R4 */
1668 XSetIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1669 SDATA (name));
1670 XStoreName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1671 SDATA (name));
1672 #endif /* not HAVE_X11R4 */
1673 UNBLOCK_INPUT;
1677 /* This function should be called when the user's lisp code has
1678 specified a name for the frame; the name will override any set by the
1679 redisplay code. */
1680 void
1681 x_explicitly_set_name (f, arg, oldval)
1682 FRAME_PTR f;
1683 Lisp_Object arg, oldval;
1685 x_set_name (f, arg, 1);
1688 /* This function should be called by Emacs redisplay code to set the
1689 name; names set this way will never override names set by the user's
1690 lisp code. */
1691 void
1692 x_implicitly_set_name (f, arg, oldval)
1693 FRAME_PTR f;
1694 Lisp_Object arg, oldval;
1696 x_set_name (f, arg, 0);
1699 /* Change the title of frame F to NAME.
1700 If NAME is nil, use the frame name as the title.
1702 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1703 name; if NAME is a string, set F's name to NAME and set
1704 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1706 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1707 suggesting a new name, which lisp code should override; if
1708 F->explicit_name is set, ignore the new name; otherwise, set it. */
1710 void
1711 x_set_title (f, name, old_name)
1712 struct frame *f;
1713 Lisp_Object name, old_name;
1715 /* Don't change the title if it's already NAME. */
1716 if (EQ (name, f->title))
1717 return;
1719 update_mode_lines = 1;
1721 f->title = name;
1723 if (NILP (name))
1724 name = f->name;
1725 else
1726 CHECK_STRING (name);
1728 if (FRAME_X_WINDOW (f))
1730 BLOCK_INPUT;
1731 #ifdef HAVE_X11R4
1733 XTextProperty text, icon;
1734 int bytes, stringp;
1735 Lisp_Object coding_system;
1737 coding_system = Qcompound_text;
1738 /* See the comment "Note: Encoding strategy" in x_set_name. */
1739 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
1740 text.encoding = (stringp ? XA_STRING
1741 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1742 text.format = 8;
1743 text.nitems = bytes;
1745 if (NILP (f->icon_name))
1747 icon = text;
1749 else
1751 /* See the comment "Note: Encoding strategy" in x_set_name. */
1752 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1753 &bytes, &stringp);
1754 icon.encoding = (stringp ? XA_STRING
1755 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1756 icon.format = 8;
1757 icon.nitems = bytes;
1760 #ifdef USE_GTK
1761 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1762 SDATA (name));
1763 #else /* not USE_GTK */
1764 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1765 #endif /* not USE_GTK */
1767 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1768 &icon);
1770 if (!NILP (f->icon_name)
1771 && icon.value != (unsigned char *) SDATA (f->icon_name))
1772 xfree (icon.value);
1773 if (text.value != (unsigned char *) SDATA (name))
1774 xfree (text.value);
1776 #else /* not HAVE_X11R4 */
1777 XSetIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1778 SDATA (name));
1779 XStoreName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1780 SDATA (name));
1781 #endif /* not HAVE_X11R4 */
1782 UNBLOCK_INPUT;
1786 void
1787 x_set_scroll_bar_default_width (f)
1788 struct frame *f;
1790 int wid = FRAME_COLUMN_WIDTH (f);
1792 #ifdef USE_TOOLKIT_SCROLL_BARS
1793 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1794 int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1795 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1796 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1797 #else
1798 /* Make the actual width at least 14 pixels and a multiple of a
1799 character width. */
1800 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1802 /* Use all of that space (aside from required margins) for the
1803 scroll bar. */
1804 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1805 #endif
1809 /* Record in frame F the specified or default value according to ALIST
1810 of the parameter named PROP (a Lisp symbol). If no value is
1811 specified for PROP, look for an X default for XPROP on the frame
1812 named NAME. If that is not found either, use the value DEFLT. */
1814 static Lisp_Object
1815 x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
1816 foreground_p)
1817 struct frame *f;
1818 Lisp_Object alist;
1819 Lisp_Object prop;
1820 char *xprop;
1821 char *xclass;
1822 int foreground_p;
1824 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1825 Lisp_Object tem;
1827 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1828 if (EQ (tem, Qunbound))
1830 #ifdef USE_TOOLKIT_SCROLL_BARS
1832 /* See if an X resource for the scroll bar color has been
1833 specified. */
1834 tem = display_x_get_resource (dpyinfo,
1835 build_string (foreground_p
1836 ? "foreground"
1837 : "background"),
1838 empty_string,
1839 build_string ("verticalScrollBar"),
1840 empty_string);
1841 if (!STRINGP (tem))
1843 /* If nothing has been specified, scroll bars will use a
1844 toolkit-dependent default. Because these defaults are
1845 difficult to get at without actually creating a scroll
1846 bar, use nil to indicate that no color has been
1847 specified. */
1848 tem = Qnil;
1851 #else /* not USE_TOOLKIT_SCROLL_BARS */
1853 tem = Qnil;
1855 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1858 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1859 return tem;
1864 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
1866 Status
1867 XSetWMProtocols (dpy, w, protocols, count)
1868 Display *dpy;
1869 Window w;
1870 Atom *protocols;
1871 int count;
1873 Atom prop;
1874 prop = XInternAtom (dpy, "WM_PROTOCOLS", False);
1875 if (prop == None) return False;
1876 XChangeProperty (dpy, w, prop, XA_ATOM, 32, PropModeReplace,
1877 (unsigned char *) protocols, count);
1878 return True;
1880 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
1882 #ifdef USE_X_TOOLKIT
1884 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1885 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1886 already be present because of the toolkit (Motif adds some of them,
1887 for example, but Xt doesn't). */
1889 static void
1890 hack_wm_protocols (f, widget)
1891 FRAME_PTR f;
1892 Widget widget;
1894 Display *dpy = XtDisplay (widget);
1895 Window w = XtWindow (widget);
1896 int need_delete = 1;
1897 int need_focus = 1;
1898 int need_save = 1;
1900 BLOCK_INPUT;
1902 Atom type, *atoms = 0;
1903 int format = 0;
1904 unsigned long nitems = 0;
1905 unsigned long bytes_after;
1907 if ((XGetWindowProperty (dpy, w,
1908 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1909 (long)0, (long)100, False, XA_ATOM,
1910 &type, &format, &nitems, &bytes_after,
1911 (unsigned char **) &atoms)
1912 == Success)
1913 && format == 32 && type == XA_ATOM)
1914 while (nitems > 0)
1916 nitems--;
1917 if (atoms[nitems] == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1918 need_delete = 0;
1919 else if (atoms[nitems] == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1920 need_focus = 0;
1921 else if (atoms[nitems] == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1922 need_save = 0;
1924 if (atoms) XFree ((char *) atoms);
1927 Atom props [10];
1928 int count = 0;
1929 if (need_delete)
1930 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1931 if (need_focus)
1932 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1933 if (need_save)
1934 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1935 if (count)
1936 XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1937 XA_ATOM, 32, PropModeAppend,
1938 (unsigned char *) props, count);
1940 UNBLOCK_INPUT;
1942 #endif
1946 /* Support routines for XIC (X Input Context). */
1948 #ifdef HAVE_X_I18N
1950 static XFontSet xic_create_xfontset P_ ((struct frame *, char *));
1951 static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *));
1954 /* Supported XIM styles, ordered by preference. */
1956 static XIMStyle supported_xim_styles[] =
1958 XIMPreeditPosition | XIMStatusArea,
1959 XIMPreeditPosition | XIMStatusNothing,
1960 XIMPreeditPosition | XIMStatusNone,
1961 XIMPreeditNothing | XIMStatusArea,
1962 XIMPreeditNothing | XIMStatusNothing,
1963 XIMPreeditNothing | XIMStatusNone,
1964 XIMPreeditNone | XIMStatusArea,
1965 XIMPreeditNone | XIMStatusNothing,
1966 XIMPreeditNone | XIMStatusNone,
1971 /* Create an X fontset on frame F with base font name
1972 BASE_FONTNAME.. */
1974 static XFontSet
1975 xic_create_xfontset (f, base_fontname)
1976 struct frame *f;
1977 char *base_fontname;
1979 XFontSet xfs;
1980 char **missing_list;
1981 int missing_count;
1982 char *def_string;
1984 xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
1985 base_fontname, &missing_list,
1986 &missing_count, &def_string);
1987 if (missing_list)
1988 XFreeStringList (missing_list);
1990 /* No need to free def_string. */
1991 return xfs;
1995 /* Value is the best input style, given user preferences USER (already
1996 checked to be supported by Emacs), and styles supported by the
1997 input method XIM. */
1999 static XIMStyle
2000 best_xim_style (user, xim)
2001 XIMStyles *user;
2002 XIMStyles *xim;
2004 int i, j;
2006 for (i = 0; i < user->count_styles; ++i)
2007 for (j = 0; j < xim->count_styles; ++j)
2008 if (user->supported_styles[i] == xim->supported_styles[j])
2009 return user->supported_styles[i];
2011 /* Return the default style. */
2012 return XIMPreeditNothing | XIMStatusNothing;
2015 /* Create XIC for frame F. */
2017 static XIMStyle xic_style;
2019 void
2020 create_frame_xic (f)
2021 struct frame *f;
2023 XIM xim;
2024 XIC xic = NULL;
2025 XFontSet xfs = NULL;
2027 if (FRAME_XIC (f))
2028 return;
2030 xim = FRAME_X_XIM (f);
2031 if (xim)
2033 XRectangle s_area;
2034 XPoint spot;
2035 XVaNestedList preedit_attr;
2036 XVaNestedList status_attr;
2037 char *base_fontname;
2038 int fontset;
2040 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2041 spot.x = 0; spot.y = 1;
2042 /* Create X fontset. */
2043 fontset = FRAME_FONTSET (f);
2044 if (fontset < 0)
2045 base_fontname = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2046 else
2048 /* Determine the base fontname from the ASCII font name of
2049 FONTSET. */
2050 char *ascii_font = (char *) SDATA (fontset_ascii (fontset));
2051 char *p = ascii_font;
2052 int i;
2054 for (i = 0; *p; p++)
2055 if (*p == '-') i++;
2056 if (i != 14)
2057 /* As the font name doesn't conform to XLFD, we can't
2058 modify it to get a suitable base fontname for the
2059 frame. */
2060 base_fontname = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2061 else
2063 int len = strlen (ascii_font) + 1;
2064 char *p1 = NULL;
2066 for (i = 0, p = ascii_font; i < 8; p++)
2068 if (*p == '-')
2070 i++;
2071 if (i == 3)
2072 p1 = p + 1;
2075 base_fontname = (char *) alloca (len);
2076 bzero (base_fontname, len);
2077 strcpy (base_fontname, "-*-*-");
2078 bcopy (p1, base_fontname + 5, p - p1);
2079 strcat (base_fontname, "*-*-*-*-*-*-*");
2082 xfs = xic_create_xfontset (f, base_fontname);
2084 /* Determine XIC style. */
2085 if (xic_style == 0)
2087 XIMStyles supported_list;
2088 supported_list.count_styles = (sizeof supported_xim_styles
2089 / sizeof supported_xim_styles[0]);
2090 supported_list.supported_styles = supported_xim_styles;
2091 xic_style = best_xim_style (&supported_list,
2092 FRAME_X_XIM_STYLES (f));
2095 preedit_attr = XVaCreateNestedList (0,
2096 XNFontSet, xfs,
2097 XNForeground,
2098 FRAME_FOREGROUND_PIXEL (f),
2099 XNBackground,
2100 FRAME_BACKGROUND_PIXEL (f),
2101 (xic_style & XIMPreeditPosition
2102 ? XNSpotLocation
2103 : NULL),
2104 &spot,
2105 NULL);
2106 status_attr = XVaCreateNestedList (0,
2107 XNArea,
2108 &s_area,
2109 XNFontSet,
2110 xfs,
2111 XNForeground,
2112 FRAME_FOREGROUND_PIXEL (f),
2113 XNBackground,
2114 FRAME_BACKGROUND_PIXEL (f),
2115 NULL);
2117 xic = XCreateIC (xim,
2118 XNInputStyle, xic_style,
2119 XNClientWindow, FRAME_X_WINDOW (f),
2120 XNFocusWindow, FRAME_X_WINDOW (f),
2121 XNStatusAttributes, status_attr,
2122 XNPreeditAttributes, preedit_attr,
2123 NULL);
2124 XFree (preedit_attr);
2125 XFree (status_attr);
2128 FRAME_XIC (f) = xic;
2129 FRAME_XIC_STYLE (f) = xic_style;
2130 FRAME_XIC_FONTSET (f) = xfs;
2134 /* Destroy XIC and free XIC fontset of frame F, if any. */
2136 void
2137 free_frame_xic (f)
2138 struct frame *f;
2140 if (FRAME_XIC (f) == NULL)
2141 return;
2143 XDestroyIC (FRAME_XIC (f));
2144 if (FRAME_XIC_FONTSET (f))
2145 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2147 FRAME_XIC (f) = NULL;
2148 FRAME_XIC_FONTSET (f) = NULL;
2152 /* Place preedit area for XIC of window W's frame to specified
2153 pixel position X/Y. X and Y are relative to window W. */
2155 void
2156 xic_set_preeditarea (w, x, y)
2157 struct window *w;
2158 int x, y;
2160 struct frame *f = XFRAME (w->frame);
2161 XVaNestedList attr;
2162 XPoint spot;
2164 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2165 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2166 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2167 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2168 XFree (attr);
2172 /* Place status area for XIC in bottom right corner of frame F.. */
2174 void
2175 xic_set_statusarea (f)
2176 struct frame *f;
2178 XIC xic = FRAME_XIC (f);
2179 XVaNestedList attr;
2180 XRectangle area;
2181 XRectangle *needed;
2183 /* Negotiate geometry of status area. If input method has existing
2184 status area, use its current size. */
2185 area.x = area.y = area.width = area.height = 0;
2186 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2187 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2188 XFree (attr);
2190 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2191 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2192 XFree (attr);
2194 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2196 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2197 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2198 XFree (attr);
2201 area.width = needed->width;
2202 area.height = needed->height;
2203 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2204 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2205 - FRAME_MENUBAR_HEIGHT (f)
2206 - FRAME_TOOLBAR_HEIGHT (f)
2207 - FRAME_INTERNAL_BORDER_WIDTH (f));
2208 XFree (needed);
2210 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2211 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2212 XFree (attr);
2216 /* Set X fontset for XIC of frame F, using base font name
2217 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2219 void
2220 xic_set_xfontset (f, base_fontname)
2221 struct frame *f;
2222 char *base_fontname;
2224 XVaNestedList attr;
2225 XFontSet xfs;
2227 xfs = xic_create_xfontset (f, base_fontname);
2229 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2230 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2231 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2232 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2233 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2234 XFree (attr);
2236 if (FRAME_XIC_FONTSET (f))
2237 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2238 FRAME_XIC_FONTSET (f) = xfs;
2241 #endif /* HAVE_X_I18N */
2245 #ifdef USE_X_TOOLKIT
2247 /* Create and set up the X widget for frame F. */
2249 static void
2250 x_window (f, window_prompting, minibuffer_only)
2251 struct frame *f;
2252 long window_prompting;
2253 int minibuffer_only;
2255 XClassHint class_hints;
2256 XSetWindowAttributes attributes;
2257 unsigned long attribute_mask;
2258 Widget shell_widget;
2259 Widget pane_widget;
2260 Widget frame_widget;
2261 Arg al [25];
2262 int ac;
2264 BLOCK_INPUT;
2266 /* Use the resource name as the top-level widget name
2267 for looking up resources. Make a non-Lisp copy
2268 for the window manager, so GC relocation won't bother it.
2270 Elsewhere we specify the window name for the window manager. */
2273 char *str = (char *) SDATA (Vx_resource_name);
2274 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2275 strcpy (f->namebuf, str);
2278 ac = 0;
2279 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2280 XtSetArg (al[ac], XtNinput, 1); ac++;
2281 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2282 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2283 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2284 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2285 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2286 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2287 applicationShellWidgetClass,
2288 FRAME_X_DISPLAY (f), al, ac);
2290 f->output_data.x->widget = shell_widget;
2291 /* maybe_set_screen_title_format (shell_widget); */
2293 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2294 (widget_value *) NULL,
2295 shell_widget, False,
2296 (lw_callback) NULL,
2297 (lw_callback) NULL,
2298 (lw_callback) NULL,
2299 (lw_callback) NULL);
2301 ac = 0;
2302 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2303 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2304 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2305 XtSetValues (pane_widget, al, ac);
2306 f->output_data.x->column_widget = pane_widget;
2308 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2309 the emacs screen when changing menubar. This reduces flickering. */
2311 ac = 0;
2312 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2313 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2314 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2315 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2316 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2317 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2318 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2319 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2320 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2321 al, ac);
2323 f->output_data.x->edit_widget = frame_widget;
2325 XtManageChild (frame_widget);
2327 /* Do some needed geometry management. */
2329 int len;
2330 char *tem, shell_position[32];
2331 Arg al[10];
2332 int ac = 0;
2333 int extra_borders = 0;
2334 int menubar_size
2335 = (f->output_data.x->menubar_widget
2336 ? (f->output_data.x->menubar_widget->core.height
2337 + f->output_data.x->menubar_widget->core.border_width)
2338 : 0);
2340 #if 0 /* Experimentally, we now get the right results
2341 for -geometry -0-0 without this. 24 Aug 96, rms. */
2342 if (FRAME_EXTERNAL_MENU_BAR (f))
2344 Dimension ibw = 0;
2345 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2346 menubar_size += ibw;
2348 #endif
2350 f->output_data.x->menubar_height = menubar_size;
2352 #ifndef USE_LUCID
2353 /* Motif seems to need this amount added to the sizes
2354 specified for the shell widget. The Athena/Lucid widgets don't.
2355 Both conclusions reached experimentally. -- rms. */
2356 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2357 &extra_borders, NULL);
2358 extra_borders *= 2;
2359 #endif
2361 /* Convert our geometry parameters into a geometry string
2362 and specify it.
2363 Note that we do not specify here whether the position
2364 is a user-specified or program-specified one.
2365 We pass that information later, in x_wm_set_size_hints. */
2367 int left = f->left_pos;
2368 int xneg = window_prompting & XNegative;
2369 int top = f->top_pos;
2370 int yneg = window_prompting & YNegative;
2371 if (xneg)
2372 left = -left;
2373 if (yneg)
2374 top = -top;
2376 if (window_prompting & USPosition)
2377 sprintf (shell_position, "=%dx%d%c%d%c%d",
2378 FRAME_PIXEL_WIDTH (f) + extra_borders,
2379 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2380 (xneg ? '-' : '+'), left,
2381 (yneg ? '-' : '+'), top);
2382 else
2384 sprintf (shell_position, "=%dx%d",
2385 FRAME_PIXEL_WIDTH (f) + extra_borders,
2386 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2388 /* Setting x and y when the position is not specified in
2389 the geometry string will set program position in the WM hints.
2390 If Emacs had just one program position, we could set it in
2391 fallback resources, but since each make-frame call can specify
2392 different program positions, this is easier. */
2393 XtSetArg (al[ac], XtNx, left); ac++;
2394 XtSetArg (al[ac], XtNy, top); ac++;
2398 len = strlen (shell_position) + 1;
2399 /* We don't free this because we don't know whether
2400 it is safe to free it while the frame exists.
2401 It isn't worth the trouble of arranging to free it
2402 when the frame is deleted. */
2403 tem = (char *) xmalloc (len);
2404 strncpy (tem, shell_position, len);
2405 XtSetArg (al[ac], XtNgeometry, tem); ac++;
2406 XtSetValues (shell_widget, al, ac);
2409 XtManageChild (pane_widget);
2410 XtRealizeWidget (shell_widget);
2412 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2414 validate_x_resource_name ();
2416 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2417 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2418 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2420 #ifdef HAVE_X_I18N
2421 FRAME_XIC (f) = NULL;
2422 if (use_xim)
2423 create_frame_xic (f);
2424 #endif
2426 f->output_data.x->wm_hints.input = True;
2427 f->output_data.x->wm_hints.flags |= InputHint;
2428 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2429 &f->output_data.x->wm_hints);
2431 hack_wm_protocols (f, shell_widget);
2433 #ifdef HACK_EDITRES
2434 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2435 #endif
2437 /* Do a stupid property change to force the server to generate a
2438 PropertyNotify event so that the event_stream server timestamp will
2439 be initialized to something relevant to the time we created the window.
2441 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2442 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2443 XA_ATOM, 32, PropModeAppend,
2444 (unsigned char*) NULL, 0);
2446 /* Make all the standard events reach the Emacs frame. */
2447 attributes.event_mask = STANDARD_EVENT_SET;
2449 #ifdef HAVE_X_I18N
2450 if (FRAME_XIC (f))
2452 /* XIM server might require some X events. */
2453 unsigned long fevent = NoEventMask;
2454 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2455 attributes.event_mask |= fevent;
2457 #endif /* HAVE_X_I18N */
2459 attribute_mask = CWEventMask;
2460 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2461 attribute_mask, &attributes);
2463 XtMapWidget (frame_widget);
2465 /* x_set_name normally ignores requests to set the name if the
2466 requested name is the same as the current name. This is the one
2467 place where that assumption isn't correct; f->name is set, but
2468 the X server hasn't been told. */
2470 Lisp_Object name;
2471 int explicit = f->explicit_name;
2473 f->explicit_name = 0;
2474 name = f->name;
2475 f->name = Qnil;
2476 x_set_name (f, name, explicit);
2479 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2480 f->output_data.x->text_cursor);
2482 UNBLOCK_INPUT;
2484 /* This is a no-op, except under Motif. Make sure main areas are
2485 set to something reasonable, in case we get an error later. */
2486 lw_set_main_areas (pane_widget, 0, frame_widget);
2489 #else /* not USE_X_TOOLKIT */
2490 #ifdef USE_GTK
2491 void
2492 x_window (f)
2493 FRAME_PTR f;
2495 if (! xg_create_frame_widgets (f))
2496 error ("Unable to create window");
2498 #ifdef HAVE_X_I18N
2499 FRAME_XIC (f) = NULL;
2500 if (use_xim)
2502 BLOCK_INPUT;
2503 create_frame_xic (f);
2504 if (FRAME_XIC (f))
2506 /* XIM server might require some X events. */
2507 unsigned long fevent = NoEventMask;
2508 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2510 if (fevent != NoEventMask)
2512 XSetWindowAttributes attributes;
2513 XWindowAttributes wattr;
2514 unsigned long attribute_mask;
2516 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2517 &wattr);
2518 attributes.event_mask = wattr.your_event_mask | fevent;
2519 attribute_mask = CWEventMask;
2520 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2521 attribute_mask, &attributes);
2524 UNBLOCK_INPUT;
2526 #endif
2529 #else /*! USE_GTK */
2530 /* Create and set up the X window for frame F. */
2532 void
2533 x_window (f)
2534 struct frame *f;
2537 XClassHint class_hints;
2538 XSetWindowAttributes attributes;
2539 unsigned long attribute_mask;
2541 attributes.background_pixel = f->output_data.x->background_pixel;
2542 attributes.border_pixel = f->output_data.x->border_pixel;
2543 attributes.bit_gravity = StaticGravity;
2544 attributes.backing_store = NotUseful;
2545 attributes.save_under = True;
2546 attributes.event_mask = STANDARD_EVENT_SET;
2547 attributes.colormap = FRAME_X_COLORMAP (f);
2548 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2549 | CWColormap);
2551 BLOCK_INPUT;
2552 FRAME_X_WINDOW (f)
2553 = XCreateWindow (FRAME_X_DISPLAY (f),
2554 f->output_data.x->parent_desc,
2555 f->left_pos,
2556 f->top_pos,
2557 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2558 f->border_width,
2559 CopyFromParent, /* depth */
2560 InputOutput, /* class */
2561 FRAME_X_VISUAL (f),
2562 attribute_mask, &attributes);
2564 #ifdef HAVE_X_I18N
2565 if (use_xim)
2567 create_frame_xic (f);
2568 if (FRAME_XIC (f))
2570 /* XIM server might require some X events. */
2571 unsigned long fevent = NoEventMask;
2572 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2573 attributes.event_mask |= fevent;
2574 attribute_mask = CWEventMask;
2575 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2576 attribute_mask, &attributes);
2579 #endif /* HAVE_X_I18N */
2581 validate_x_resource_name ();
2583 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2584 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2585 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2587 /* The menubar is part of the ordinary display;
2588 it does not count in addition to the height of the window. */
2589 f->output_data.x->menubar_height = 0;
2591 /* This indicates that we use the "Passive Input" input model.
2592 Unless we do this, we don't get the Focus{In,Out} events that we
2593 need to draw the cursor correctly. Accursed bureaucrats.
2594 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2596 f->output_data.x->wm_hints.input = True;
2597 f->output_data.x->wm_hints.flags |= InputHint;
2598 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2599 &f->output_data.x->wm_hints);
2600 f->output_data.x->wm_hints.icon_pixmap = None;
2602 /* Request "save yourself" and "delete window" commands from wm. */
2604 Atom protocols[2];
2605 protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2606 protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2607 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2610 /* x_set_name normally ignores requests to set the name if the
2611 requested name is the same as the current name. This is the one
2612 place where that assumption isn't correct; f->name is set, but
2613 the X server hasn't been told. */
2615 Lisp_Object name;
2616 int explicit = f->explicit_name;
2618 f->explicit_name = 0;
2619 name = f->name;
2620 f->name = Qnil;
2621 x_set_name (f, name, explicit);
2624 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2625 f->output_data.x->text_cursor);
2627 UNBLOCK_INPUT;
2629 if (FRAME_X_WINDOW (f) == 0)
2630 error ("Unable to create window");
2633 #endif /* not USE_GTK */
2634 #endif /* not USE_X_TOOLKIT */
2636 /* Handle the icon stuff for this window. Perhaps later we might
2637 want an x_set_icon_position which can be called interactively as
2638 well. */
2640 static void
2641 x_icon (f, parms)
2642 struct frame *f;
2643 Lisp_Object parms;
2645 Lisp_Object icon_x, icon_y;
2646 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2648 /* Set the position of the icon. Note that twm groups all
2649 icons in an icon window. */
2650 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2651 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2652 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2654 CHECK_NUMBER (icon_x);
2655 CHECK_NUMBER (icon_y);
2657 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2658 error ("Both left and top icon corners of icon must be specified");
2660 BLOCK_INPUT;
2662 if (! EQ (icon_x, Qunbound))
2663 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2665 /* Start up iconic or window? */
2666 x_wm_set_window_state
2667 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2668 Qicon)
2669 ? IconicState
2670 : NormalState));
2672 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2673 ? f->icon_name
2674 : f->name)));
2676 UNBLOCK_INPUT;
2679 /* Make the GCs needed for this window, setting the
2680 background, border and mouse colors; also create the
2681 mouse cursor and the gray border tile. */
2683 static char cursor_bits[] =
2685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2691 static void
2692 x_make_gc (f)
2693 struct frame *f;
2695 XGCValues gc_values;
2697 BLOCK_INPUT;
2699 /* Create the GCs of this frame.
2700 Note that many default values are used. */
2702 /* Normal video */
2703 gc_values.font = FRAME_FONT (f)->fid;
2704 gc_values.foreground = f->output_data.x->foreground_pixel;
2705 gc_values.background = f->output_data.x->background_pixel;
2706 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2707 f->output_data.x->normal_gc
2708 = XCreateGC (FRAME_X_DISPLAY (f),
2709 FRAME_X_WINDOW (f),
2710 GCLineWidth | GCFont | GCForeground | GCBackground,
2711 &gc_values);
2713 /* Reverse video style. */
2714 gc_values.foreground = f->output_data.x->background_pixel;
2715 gc_values.background = f->output_data.x->foreground_pixel;
2716 f->output_data.x->reverse_gc
2717 = XCreateGC (FRAME_X_DISPLAY (f),
2718 FRAME_X_WINDOW (f),
2719 GCFont | GCForeground | GCBackground | GCLineWidth,
2720 &gc_values);
2722 /* Cursor has cursor-color background, background-color foreground. */
2723 gc_values.foreground = f->output_data.x->background_pixel;
2724 gc_values.background = f->output_data.x->cursor_pixel;
2725 gc_values.fill_style = FillOpaqueStippled;
2726 gc_values.stipple
2727 = XCreateBitmapFromData (FRAME_X_DISPLAY (f),
2728 FRAME_X_DISPLAY_INFO (f)->root_window,
2729 cursor_bits, 16, 16);
2730 f->output_data.x->cursor_gc
2731 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2732 (GCFont | GCForeground | GCBackground
2733 | GCFillStyle /* | GCStipple */ | GCLineWidth),
2734 &gc_values);
2736 /* Reliefs. */
2737 f->output_data.x->white_relief.gc = 0;
2738 f->output_data.x->black_relief.gc = 0;
2740 /* Create the gray border tile used when the pointer is not in
2741 the frame. Since this depends on the frame's pixel values,
2742 this must be done on a per-frame basis. */
2743 f->output_data.x->border_tile
2744 = (XCreatePixmapFromBitmapData
2745 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2746 gray_bits, gray_width, gray_height,
2747 f->output_data.x->foreground_pixel,
2748 f->output_data.x->background_pixel,
2749 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2751 UNBLOCK_INPUT;
2755 /* Free what was was allocated in x_make_gc. */
2757 void
2758 x_free_gcs (f)
2759 struct frame *f;
2761 Display *dpy = FRAME_X_DISPLAY (f);
2763 BLOCK_INPUT;
2765 if (f->output_data.x->normal_gc)
2767 XFreeGC (dpy, f->output_data.x->normal_gc);
2768 f->output_data.x->normal_gc = 0;
2771 if (f->output_data.x->reverse_gc)
2773 XFreeGC (dpy, f->output_data.x->reverse_gc);
2774 f->output_data.x->reverse_gc = 0;
2777 if (f->output_data.x->cursor_gc)
2779 XFreeGC (dpy, f->output_data.x->cursor_gc);
2780 f->output_data.x->cursor_gc = 0;
2783 if (f->output_data.x->border_tile)
2785 XFreePixmap (dpy, f->output_data.x->border_tile);
2786 f->output_data.x->border_tile = 0;
2789 UNBLOCK_INPUT;
2793 /* Handler for signals raised during x_create_frame and
2794 x_create_top_frame. FRAME is the frame which is partially
2795 constructed. */
2797 static Lisp_Object
2798 unwind_create_frame (frame)
2799 Lisp_Object frame;
2801 struct frame *f = XFRAME (frame);
2803 /* If frame is ``official'', nothing to do. */
2804 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
2806 #if GLYPH_DEBUG
2807 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2808 #endif
2810 x_free_frame_resources (f);
2812 /* Check that reference counts are indeed correct. */
2813 xassert (dpyinfo->reference_count == dpyinfo_refcount);
2814 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
2815 return Qt;
2818 return Qnil;
2822 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2823 1, 1, 0,
2824 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
2825 Returns an Emacs frame object.
2826 ALIST is an alist of frame parameters.
2827 If the parameters specify that the frame should not have a minibuffer,
2828 and do not specify a specific minibuffer window to use,
2829 then `default-minibuffer-frame' must be a frame whose minibuffer can
2830 be shared by the new frame.
2832 This function is an internal primitive--use `make-frame' instead. */)
2833 (parms)
2834 Lisp_Object parms;
2836 struct frame *f;
2837 Lisp_Object frame, tem;
2838 Lisp_Object name;
2839 int minibuffer_only = 0;
2840 long window_prompting = 0;
2841 int width, height;
2842 int count = SPECPDL_INDEX ();
2843 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2844 Lisp_Object display;
2845 struct x_display_info *dpyinfo = NULL;
2846 Lisp_Object parent;
2847 struct kboard *kb;
2849 check_x ();
2851 /* Use this general default value to start with
2852 until we know if this frame has a specified name. */
2853 Vx_resource_name = Vinvocation_name;
2855 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
2856 if (EQ (display, Qunbound))
2857 display = Qnil;
2858 dpyinfo = check_x_display_info (display);
2859 #ifdef MULTI_KBOARD
2860 kb = dpyinfo->kboard;
2861 #else
2862 kb = &the_only_kboard;
2863 #endif
2865 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
2866 if (!STRINGP (name)
2867 && ! EQ (name, Qunbound)
2868 && ! NILP (name))
2869 error ("Invalid frame name--not a string or nil");
2871 if (STRINGP (name))
2872 Vx_resource_name = name;
2874 /* See if parent window is specified. */
2875 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
2876 if (EQ (parent, Qunbound))
2877 parent = Qnil;
2878 if (! NILP (parent))
2879 CHECK_NUMBER (parent);
2881 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2882 /* No need to protect DISPLAY because that's not used after passing
2883 it to make_frame_without_minibuffer. */
2884 frame = Qnil;
2885 GCPRO4 (parms, parent, name, frame);
2886 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
2887 RES_TYPE_SYMBOL);
2888 if (EQ (tem, Qnone) || NILP (tem))
2889 f = make_frame_without_minibuffer (Qnil, kb, display);
2890 else if (EQ (tem, Qonly))
2892 f = make_minibuffer_frame ();
2893 minibuffer_only = 1;
2895 else if (WINDOWP (tem))
2896 f = make_frame_without_minibuffer (tem, kb, display);
2897 else
2898 f = make_frame (1);
2900 XSETFRAME (frame, f);
2902 /* Note that X Windows does support scroll bars. */
2903 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
2905 f->output_method = output_x_window;
2906 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
2907 bzero (f->output_data.x, sizeof (struct x_output));
2908 f->output_data.x->icon_bitmap = -1;
2909 FRAME_FONTSET (f) = -1;
2910 f->output_data.x->scroll_bar_foreground_pixel = -1;
2911 f->output_data.x->scroll_bar_background_pixel = -1;
2912 #ifdef USE_TOOLKIT_SCROLL_BARS
2913 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
2914 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
2915 #endif /* USE_TOOLKIT_SCROLL_BARS */
2916 record_unwind_protect (unwind_create_frame, frame);
2918 f->icon_name
2919 = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
2920 RES_TYPE_STRING);
2921 if (! STRINGP (f->icon_name))
2922 f->icon_name = Qnil;
2924 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
2925 #if GLYPH_DEBUG
2926 image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
2927 dpyinfo_refcount = dpyinfo->reference_count;
2928 #endif /* GLYPH_DEBUG */
2929 #ifdef MULTI_KBOARD
2930 FRAME_KBOARD (f) = kb;
2931 #endif
2933 /* These colors will be set anyway later, but it's important
2934 to get the color reference counts right, so initialize them! */
2936 Lisp_Object black;
2937 struct gcpro gcpro1;
2939 /* Function x_decode_color can signal an error. Make
2940 sure to initialize color slots so that we won't try
2941 to free colors we haven't allocated. */
2942 f->output_data.x->foreground_pixel = -1;
2943 f->output_data.x->background_pixel = -1;
2944 f->output_data.x->cursor_pixel = -1;
2945 f->output_data.x->cursor_foreground_pixel = -1;
2946 f->output_data.x->border_pixel = -1;
2947 f->output_data.x->mouse_pixel = -1;
2949 black = build_string ("black");
2950 GCPRO1 (black);
2951 f->output_data.x->foreground_pixel
2952 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2953 f->output_data.x->background_pixel
2954 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2955 f->output_data.x->cursor_pixel
2956 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2957 f->output_data.x->cursor_foreground_pixel
2958 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2959 f->output_data.x->border_pixel
2960 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2961 f->output_data.x->mouse_pixel
2962 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2963 UNGCPRO;
2966 /* Specify the parent under which to make this X window. */
2968 if (!NILP (parent))
2970 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
2971 f->output_data.x->explicit_parent = 1;
2973 else
2975 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
2976 f->output_data.x->explicit_parent = 0;
2979 /* Set the name; the functions to which we pass f expect the name to
2980 be set. */
2981 if (EQ (name, Qunbound) || NILP (name))
2983 f->name = build_string (dpyinfo->x_id_name);
2984 f->explicit_name = 0;
2986 else
2988 f->name = name;
2989 f->explicit_name = 1;
2990 /* use the frame's title when getting resources for this frame. */
2991 specbind (Qx_resource_name, name);
2994 /* Extract the window parameters from the supplied values
2995 that are needed to determine window geometry. */
2997 Lisp_Object font;
2999 font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
3001 BLOCK_INPUT;
3002 /* First, try whatever font the caller has specified. */
3003 if (STRINGP (font))
3005 tem = Fquery_fontset (font, Qnil);
3006 if (STRINGP (tem))
3007 font = x_new_fontset (f, SDATA (tem));
3008 else
3009 font = x_new_font (f, SDATA (font));
3012 /* Try out a font which we hope has bold and italic variations. */
3013 if (!STRINGP (font))
3014 font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
3015 if (!STRINGP (font))
3016 font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3017 if (! STRINGP (font))
3018 font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3019 if (! STRINGP (font))
3020 /* This was formerly the first thing tried, but it finds too many fonts
3021 and takes too long. */
3022 font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3023 /* If those didn't work, look for something which will at least work. */
3024 if (! STRINGP (font))
3025 font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3026 UNBLOCK_INPUT;
3027 if (! STRINGP (font))
3028 font = build_string ("fixed");
3030 x_default_parameter (f, parms, Qfont, font,
3031 "font", "Font", RES_TYPE_STRING);
3034 #ifdef USE_LUCID
3035 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3036 whereby it fails to get any font. */
3037 xlwmenu_default_font = FRAME_FONT (f);
3038 #endif
3040 x_default_parameter (f, parms, Qborder_width, make_number (2),
3041 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3043 /* This defaults to 1 in order to match xterm. We recognize either
3044 internalBorderWidth or internalBorder (which is what xterm calls
3045 it). */
3046 if (NILP (Fassq (Qinternal_border_width, parms)))
3048 Lisp_Object value;
3050 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3051 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3052 if (! EQ (value, Qunbound))
3053 parms = Fcons (Fcons (Qinternal_border_width, value),
3054 parms);
3056 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
3057 "internalBorderWidth", "internalBorderWidth",
3058 RES_TYPE_NUMBER);
3059 x_default_parameter (f, parms, Qvertical_scroll_bars, Qleft,
3060 "verticalScrollBars", "ScrollBars",
3061 RES_TYPE_SYMBOL);
3063 /* Also do the stuff which must be set before the window exists. */
3064 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3065 "foreground", "Foreground", RES_TYPE_STRING);
3066 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3067 "background", "Background", RES_TYPE_STRING);
3068 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3069 "pointerColor", "Foreground", RES_TYPE_STRING);
3070 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3071 "cursorColor", "Foreground", RES_TYPE_STRING);
3072 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3073 "borderColor", "BorderColor", RES_TYPE_STRING);
3074 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3075 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3076 x_default_parameter (f, parms, Qline_spacing, Qnil,
3077 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3078 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3079 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3080 x_default_parameter (f, parms, Qright_fringe, Qnil,
3081 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3083 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3084 "scrollBarForeground",
3085 "ScrollBarForeground", 1);
3086 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3087 "scrollBarBackground",
3088 "ScrollBarBackground", 0);
3090 /* Init faces before x_default_parameter is called for scroll-bar
3091 parameters because that function calls x_set_scroll_bar_width,
3092 which calls change_frame_size, which calls Fset_window_buffer,
3093 which runs hooks, which call Fvertical_motion. At the end, we
3094 end up in init_iterator with a null face cache, which should not
3095 happen. */
3096 init_frame_faces (f);
3098 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
3099 "menuBar", "MenuBar", RES_TYPE_NUMBER);
3100 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
3101 "toolBar", "ToolBar", RES_TYPE_NUMBER);
3102 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3103 "bufferPredicate", "BufferPredicate",
3104 RES_TYPE_SYMBOL);
3105 x_default_parameter (f, parms, Qtitle, Qnil,
3106 "title", "Title", RES_TYPE_STRING);
3107 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3108 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3109 x_default_parameter (f, parms, Qfullscreen, Qnil,
3110 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3112 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3114 /* Compute the size of the X window. */
3115 window_prompting = x_figure_window_size (f, parms, 1);
3117 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3118 f->no_split = minibuffer_only || EQ (tem, Qt);
3120 /* Create the X widget or window. */
3121 #ifdef USE_X_TOOLKIT
3122 x_window (f, window_prompting, minibuffer_only);
3123 #else
3124 x_window (f);
3125 #endif
3127 x_icon (f, parms);
3128 x_make_gc (f);
3130 /* Now consider the frame official. */
3131 FRAME_X_DISPLAY_INFO (f)->reference_count++;
3132 Vframe_list = Fcons (frame, Vframe_list);
3134 /* We need to do this after creating the X window, so that the
3135 icon-creation functions can say whose icon they're describing. */
3136 x_default_parameter (f, parms, Qicon_type, Qnil,
3137 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
3139 x_default_parameter (f, parms, Qauto_raise, Qnil,
3140 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3141 x_default_parameter (f, parms, Qauto_lower, Qnil,
3142 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3143 x_default_parameter (f, parms, Qcursor_type, Qbox,
3144 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3145 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3146 "scrollBarWidth", "ScrollBarWidth",
3147 RES_TYPE_NUMBER);
3149 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3150 Change will not be effected unless different from the current
3151 FRAME_LINES (f). */
3152 width = FRAME_COLS (f);
3153 height = FRAME_LINES (f);
3155 SET_FRAME_COLS (f, 0);
3156 FRAME_LINES (f) = 0;
3157 change_frame_size (f, height, width, 1, 0, 0);
3159 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3160 /* Create the menu bar. */
3161 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3163 /* If this signals an error, we haven't set size hints for the
3164 frame and we didn't make it visible. */
3165 initialize_frame_menubar (f);
3167 #ifndef USE_GTK
3168 /* This is a no-op, except under Motif where it arranges the
3169 main window for the widgets on it. */
3170 lw_set_main_areas (f->output_data.x->column_widget,
3171 f->output_data.x->menubar_widget,
3172 f->output_data.x->edit_widget);
3173 #endif /* not USE_GTK */
3175 #endif /* USE_X_TOOLKIT || USE_GTK */
3177 /* Tell the server what size and position, etc, we want, and how
3178 badly we want them. This should be done after we have the menu
3179 bar so that its size can be taken into account. */
3180 BLOCK_INPUT;
3181 x_wm_set_size_hint (f, window_prompting, 0);
3182 UNBLOCK_INPUT;
3184 /* Make the window appear on the frame and enable display, unless
3185 the caller says not to. However, with explicit parent, Emacs
3186 cannot control visibility, so don't try. */
3187 if (! f->output_data.x->explicit_parent)
3189 Lisp_Object visibility;
3191 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3192 RES_TYPE_SYMBOL);
3193 if (EQ (visibility, Qunbound))
3194 visibility = Qt;
3196 if (EQ (visibility, Qicon))
3197 x_iconify_frame (f);
3198 else if (! NILP (visibility))
3199 x_make_frame_visible (f);
3200 else
3201 /* Must have been Qnil. */
3205 /* Set the WM leader property. GTK does this itself, so this is not
3206 needed when using GTK. */
3207 if (dpyinfo->client_leader_window != 0)
3209 BLOCK_INPUT;
3210 XChangeProperty (FRAME_X_DISPLAY (f),
3211 FRAME_OUTER_WINDOW (f),
3212 dpyinfo->Xatom_wm_client_leader,
3213 XA_WINDOW, 32, PropModeReplace,
3214 (char *) &dpyinfo->client_leader_window, 1);
3215 UNBLOCK_INPUT;
3218 UNGCPRO;
3220 /* Make sure windows on this frame appear in calls to next-window
3221 and similar functions. */
3222 Vwindow_list = Qnil;
3224 return unbind_to (count, frame);
3228 /* FRAME is used only to get a handle on the X display. We don't pass the
3229 display info directly because we're called from frame.c, which doesn't
3230 know about that structure. */
3232 Lisp_Object
3233 x_get_focus_frame (frame)
3234 struct frame *frame;
3236 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3237 Lisp_Object xfocus;
3238 if (! dpyinfo->x_focus_frame)
3239 return Qnil;
3241 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3242 return xfocus;
3246 /* In certain situations, when the window manager follows a
3247 click-to-focus policy, there seems to be no way around calling
3248 XSetInputFocus to give another frame the input focus .
3250 In an ideal world, XSetInputFocus should generally be avoided so
3251 that applications don't interfere with the window manager's focus
3252 policy. But I think it's okay to use when it's clearly done
3253 following a user-command. */
3255 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3256 doc: /* Set the input focus to FRAME.
3257 FRAME nil means use the selected frame. */)
3258 (frame)
3259 Lisp_Object frame;
3261 struct frame *f = check_x_frame (frame);
3262 Display *dpy = FRAME_X_DISPLAY (f);
3263 int count;
3265 BLOCK_INPUT;
3266 count = x_catch_errors (dpy);
3267 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3268 RevertToParent, CurrentTime);
3269 x_uncatch_errors (dpy, count);
3270 UNBLOCK_INPUT;
3272 return Qnil;
3276 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3277 doc: /* Internal function called by `color-defined-p', which see. */)
3278 (color, frame)
3279 Lisp_Object color, frame;
3281 XColor foo;
3282 FRAME_PTR f = check_x_frame (frame);
3284 CHECK_STRING (color);
3286 if (x_defined_color (f, SDATA (color), &foo, 0))
3287 return Qt;
3288 else
3289 return Qnil;
3292 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3293 doc: /* Internal function called by `color-values', which see. */)
3294 (color, frame)
3295 Lisp_Object color, frame;
3297 XColor foo;
3298 FRAME_PTR f = check_x_frame (frame);
3300 CHECK_STRING (color);
3302 if (x_defined_color (f, SDATA (color), &foo, 0))
3304 Lisp_Object rgb[3];
3306 rgb[0] = make_number (foo.red);
3307 rgb[1] = make_number (foo.green);
3308 rgb[2] = make_number (foo.blue);
3309 return Flist (3, rgb);
3311 else
3312 return Qnil;
3315 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3316 doc: /* Internal function called by `display-color-p', which see. */)
3317 (display)
3318 Lisp_Object display;
3320 struct x_display_info *dpyinfo = check_x_display_info (display);
3322 if (dpyinfo->n_planes <= 2)
3323 return Qnil;
3325 switch (dpyinfo->visual->class)
3327 case StaticColor:
3328 case PseudoColor:
3329 case TrueColor:
3330 case DirectColor:
3331 return Qt;
3333 default:
3334 return Qnil;
3338 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3339 0, 1, 0,
3340 doc: /* Return t if the X display supports shades of gray.
3341 Note that color displays do support shades of gray.
3342 The optional argument DISPLAY specifies which display to ask about.
3343 DISPLAY should be either a frame or a display name (a string).
3344 If omitted or nil, that stands for the selected frame's display. */)
3345 (display)
3346 Lisp_Object display;
3348 struct x_display_info *dpyinfo = check_x_display_info (display);
3350 if (dpyinfo->n_planes <= 1)
3351 return Qnil;
3353 switch (dpyinfo->visual->class)
3355 case StaticColor:
3356 case PseudoColor:
3357 case TrueColor:
3358 case DirectColor:
3359 case StaticGray:
3360 case GrayScale:
3361 return Qt;
3363 default:
3364 return Qnil;
3368 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3369 0, 1, 0,
3370 doc: /* Returns the width in pixels of the X display DISPLAY.
3371 The optional argument DISPLAY specifies which display to ask about.
3372 DISPLAY should be either a frame or a display name (a string).
3373 If omitted or nil, that stands for the selected frame's display. */)
3374 (display)
3375 Lisp_Object display;
3377 struct x_display_info *dpyinfo = check_x_display_info (display);
3379 return make_number (dpyinfo->width);
3382 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3383 Sx_display_pixel_height, 0, 1, 0,
3384 doc: /* Returns the height in pixels of the X display DISPLAY.
3385 The optional argument DISPLAY specifies which display to ask about.
3386 DISPLAY should be either a frame or a display name (a string).
3387 If omitted or nil, that stands for the selected frame's display. */)
3388 (display)
3389 Lisp_Object display;
3391 struct x_display_info *dpyinfo = check_x_display_info (display);
3393 return make_number (dpyinfo->height);
3396 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3397 0, 1, 0,
3398 doc: /* Returns the number of bitplanes of the X display DISPLAY.
3399 The optional argument DISPLAY specifies which display to ask about.
3400 DISPLAY should be either a frame or a display name (a string).
3401 If omitted or nil, that stands for the selected frame's display. */)
3402 (display)
3403 Lisp_Object display;
3405 struct x_display_info *dpyinfo = check_x_display_info (display);
3407 return make_number (dpyinfo->n_planes);
3410 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3411 0, 1, 0,
3412 doc: /* Returns the number of color cells of the X display DISPLAY.
3413 The optional argument DISPLAY specifies which display to ask about.
3414 DISPLAY should be either a frame or a display name (a string).
3415 If omitted or nil, that stands for the selected frame's display. */)
3416 (display)
3417 Lisp_Object display;
3419 struct x_display_info *dpyinfo = check_x_display_info (display);
3421 int nr_planes = DisplayPlanes (dpyinfo->display,
3422 XScreenNumberOfScreen (dpyinfo->screen));
3424 /* Truncate nr_planes to 24 to avoid integer overflow.
3425 Some displays says 32, but only 24 bits are actually significant.
3426 There are only very few and rare video cards that have more than
3427 24 significant bits. Also 24 bits is more than 16 million colors,
3428 it "should be enough for everyone". */
3429 if (nr_planes > 24) nr_planes = 24;
3431 return make_number (1 << nr_planes);
3434 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3435 Sx_server_max_request_size,
3436 0, 1, 0,
3437 doc: /* Returns the maximum request size of the X server of display DISPLAY.
3438 The optional argument DISPLAY specifies which display to ask about.
3439 DISPLAY should be either a frame or a display name (a string).
3440 If omitted or nil, that stands for the selected frame's display. */)
3441 (display)
3442 Lisp_Object display;
3444 struct x_display_info *dpyinfo = check_x_display_info (display);
3446 return make_number (MAXREQUEST (dpyinfo->display));
3449 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3450 doc: /* Returns the vendor ID string of the X server of display DISPLAY.
3451 The optional argument DISPLAY specifies which display to ask about.
3452 DISPLAY should be either a frame or a display name (a string).
3453 If omitted or nil, that stands for the selected frame's display. */)
3454 (display)
3455 Lisp_Object display;
3457 struct x_display_info *dpyinfo = check_x_display_info (display);
3458 char *vendor = ServerVendor (dpyinfo->display);
3460 if (! vendor) vendor = "";
3461 return build_string (vendor);
3464 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3465 doc: /* Returns the version numbers of the X server of display DISPLAY.
3466 The value is a list of three integers: the major and minor
3467 version numbers of the X Protocol in use, and the vendor-specific release
3468 number. See also the function `x-server-vendor'.
3470 The optional argument DISPLAY specifies which display to ask about.
3471 DISPLAY should be either a frame or a display name (a string).
3472 If omitted or nil, that stands for the selected frame's display. */)
3473 (display)
3474 Lisp_Object display;
3476 struct x_display_info *dpyinfo = check_x_display_info (display);
3477 Display *dpy = dpyinfo->display;
3479 return Fcons (make_number (ProtocolVersion (dpy)),
3480 Fcons (make_number (ProtocolRevision (dpy)),
3481 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3484 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3485 doc: /* Return the number of screens on the X server of display DISPLAY.
3486 The optional argument DISPLAY specifies which display to ask about.
3487 DISPLAY should be either a frame or a display name (a string).
3488 If omitted or nil, that stands for the selected frame's display. */)
3489 (display)
3490 Lisp_Object display;
3492 struct x_display_info *dpyinfo = check_x_display_info (display);
3494 return make_number (ScreenCount (dpyinfo->display));
3497 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3498 doc: /* Return the height in millimeters of the X display DISPLAY.
3499 The optional argument DISPLAY specifies which display to ask about.
3500 DISPLAY should be either a frame or a display name (a string).
3501 If omitted or nil, that stands for the selected frame's display. */)
3502 (display)
3503 Lisp_Object display;
3505 struct x_display_info *dpyinfo = check_x_display_info (display);
3507 return make_number (HeightMMOfScreen (dpyinfo->screen));
3510 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3511 doc: /* Return the width in millimeters of the X display DISPLAY.
3512 The optional argument DISPLAY specifies which display to ask about.
3513 DISPLAY should be either a frame or a display name (a string).
3514 If omitted or nil, that stands for the selected frame's display. */)
3515 (display)
3516 Lisp_Object display;
3518 struct x_display_info *dpyinfo = check_x_display_info (display);
3520 return make_number (WidthMMOfScreen (dpyinfo->screen));
3523 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3524 Sx_display_backing_store, 0, 1, 0,
3525 doc: /* Returns an indication of whether X display DISPLAY does backing store.
3526 The value may be `always', `when-mapped', or `not-useful'.
3527 The optional argument DISPLAY specifies which display to ask about.
3528 DISPLAY should be either a frame or a display name (a string).
3529 If omitted or nil, that stands for the selected frame's display. */)
3530 (display)
3531 Lisp_Object display;
3533 struct x_display_info *dpyinfo = check_x_display_info (display);
3534 Lisp_Object result;
3536 switch (DoesBackingStore (dpyinfo->screen))
3538 case Always:
3539 result = intern ("always");
3540 break;
3542 case WhenMapped:
3543 result = intern ("when-mapped");
3544 break;
3546 case NotUseful:
3547 result = intern ("not-useful");
3548 break;
3550 default:
3551 error ("Strange value for BackingStore parameter of screen");
3552 result = Qnil;
3555 return result;
3558 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3559 Sx_display_visual_class, 0, 1, 0,
3560 doc: /* Return the visual class of the X display DISPLAY.
3561 The value is one of the symbols `static-gray', `gray-scale',
3562 `static-color', `pseudo-color', `true-color', or `direct-color'.
3564 The optional argument DISPLAY specifies which display to ask about.
3565 DISPLAY should be either a frame or a display name (a string).
3566 If omitted or nil, that stands for the selected frame's display. */)
3567 (display)
3568 Lisp_Object display;
3570 struct x_display_info *dpyinfo = check_x_display_info (display);
3571 Lisp_Object result;
3573 switch (dpyinfo->visual->class)
3575 case StaticGray:
3576 result = intern ("static-gray");
3577 break;
3578 case GrayScale:
3579 result = intern ("gray-scale");
3580 break;
3581 case StaticColor:
3582 result = intern ("static-color");
3583 break;
3584 case PseudoColor:
3585 result = intern ("pseudo-color");
3586 break;
3587 case TrueColor:
3588 result = intern ("true-color");
3589 break;
3590 case DirectColor:
3591 result = intern ("direct-color");
3592 break;
3593 default:
3594 error ("Display has an unknown visual class");
3595 result = Qnil;
3598 return result;
3601 DEFUN ("x-display-save-under", Fx_display_save_under,
3602 Sx_display_save_under, 0, 1, 0,
3603 doc: /* Returns t if the X display DISPLAY supports the save-under feature.
3604 The optional argument DISPLAY specifies which display to ask about.
3605 DISPLAY should be either a frame or a display name (a string).
3606 If omitted or nil, that stands for the selected frame's display. */)
3607 (display)
3608 Lisp_Object display;
3610 struct x_display_info *dpyinfo = check_x_display_info (display);
3612 if (DoesSaveUnders (dpyinfo->screen) == True)
3613 return Qt;
3614 else
3615 return Qnil;
3619 x_pixel_width (f)
3620 register struct frame *f;
3622 return FRAME_PIXEL_WIDTH (f);
3626 x_pixel_height (f)
3627 register struct frame *f;
3629 return FRAME_PIXEL_HEIGHT (f);
3633 x_char_width (f)
3634 register struct frame *f;
3636 return FRAME_COLUMN_WIDTH (f);
3640 x_char_height (f)
3641 register struct frame *f;
3643 return FRAME_LINE_HEIGHT (f);
3647 x_screen_planes (f)
3648 register struct frame *f;
3650 return FRAME_X_DISPLAY_INFO (f)->n_planes;
3655 /************************************************************************
3656 X Displays
3657 ************************************************************************/
3660 /* Mapping visual names to visuals. */
3662 static struct visual_class
3664 char *name;
3665 int class;
3667 visual_classes[] =
3669 {"StaticGray", StaticGray},
3670 {"GrayScale", GrayScale},
3671 {"StaticColor", StaticColor},
3672 {"PseudoColor", PseudoColor},
3673 {"TrueColor", TrueColor},
3674 {"DirectColor", DirectColor},
3675 {NULL, 0}
3679 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3681 /* Value is the screen number of screen SCR. This is a substitute for
3682 the X function with the same name when that doesn't exist. */
3685 XScreenNumberOfScreen (scr)
3686 register Screen *scr;
3688 Display *dpy = scr->display;
3689 int i;
3691 for (i = 0; i < dpy->nscreens; ++i)
3692 if (scr == dpy->screens + i)
3693 break;
3695 return i;
3698 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3701 /* Select the visual that should be used on display DPYINFO. Set
3702 members of DPYINFO appropriately. Called from x_term_init. */
3704 void
3705 select_visual (dpyinfo)
3706 struct x_display_info *dpyinfo;
3708 Display *dpy = dpyinfo->display;
3709 Screen *screen = dpyinfo->screen;
3710 Lisp_Object value;
3712 /* See if a visual is specified. */
3713 value = display_x_get_resource (dpyinfo,
3714 build_string ("visualClass"),
3715 build_string ("VisualClass"),
3716 Qnil, Qnil);
3717 if (STRINGP (value))
3719 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
3720 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
3721 depth, a decimal number. NAME is compared with case ignored. */
3722 char *s = (char *) alloca (SBYTES (value) + 1);
3723 char *dash;
3724 int i, class = -1;
3725 XVisualInfo vinfo;
3727 strcpy (s, SDATA (value));
3728 dash = index (s, '-');
3729 if (dash)
3731 dpyinfo->n_planes = atoi (dash + 1);
3732 *dash = '\0';
3734 else
3735 /* We won't find a matching visual with depth 0, so that
3736 an error will be printed below. */
3737 dpyinfo->n_planes = 0;
3739 /* Determine the visual class. */
3740 for (i = 0; visual_classes[i].name; ++i)
3741 if (xstricmp (s, visual_classes[i].name) == 0)
3743 class = visual_classes[i].class;
3744 break;
3747 /* Look up a matching visual for the specified class. */
3748 if (class == -1
3749 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
3750 dpyinfo->n_planes, class, &vinfo))
3751 fatal ("Invalid visual specification `%s'", SDATA (value));
3753 dpyinfo->visual = vinfo.visual;
3755 else
3757 int n_visuals;
3758 XVisualInfo *vinfo, vinfo_template;
3760 dpyinfo->visual = DefaultVisualOfScreen (screen);
3762 #ifdef HAVE_X11R4
3763 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
3764 #else
3765 vinfo_template.visualid = dpyinfo->visual->visualid;
3766 #endif
3767 vinfo_template.screen = XScreenNumberOfScreen (screen);
3768 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
3769 &vinfo_template, &n_visuals);
3770 if (n_visuals != 1)
3771 fatal ("Can't get proper X visual info");
3773 dpyinfo->n_planes = vinfo->depth;
3774 XFree ((char *) vinfo);
3779 /* Return the X display structure for the display named NAME.
3780 Open a new connection if necessary. */
3782 struct x_display_info *
3783 x_display_info_for_name (name)
3784 Lisp_Object name;
3786 Lisp_Object names;
3787 struct x_display_info *dpyinfo;
3789 CHECK_STRING (name);
3791 if (! EQ (Vwindow_system, intern ("x")))
3792 error ("Not using X Windows");
3794 for (dpyinfo = x_display_list, names = x_display_name_list;
3795 dpyinfo;
3796 dpyinfo = dpyinfo->next, names = XCDR (names))
3798 Lisp_Object tem;
3799 tem = Fstring_equal (XCAR (XCAR (names)), name);
3800 if (!NILP (tem))
3801 return dpyinfo;
3804 /* Use this general default value to start with. */
3805 Vx_resource_name = Vinvocation_name;
3807 validate_x_resource_name ();
3809 dpyinfo = x_term_init (name, (char *)0,
3810 (char *) SDATA (Vx_resource_name));
3812 if (dpyinfo == 0)
3813 error ("Cannot connect to X server %s", SDATA (name));
3815 x_in_use = 1;
3816 XSETFASTINT (Vwindow_system_version, 11);
3818 return dpyinfo;
3822 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
3823 1, 3, 0,
3824 doc: /* Open a connection to an X server.
3825 DISPLAY is the name of the display to connect to.
3826 Optional second arg XRM-STRING is a string of resources in xrdb format.
3827 If the optional third arg MUST-SUCCEED is non-nil,
3828 terminate Emacs if we can't open the connection. */)
3829 (display, xrm_string, must_succeed)
3830 Lisp_Object display, xrm_string, must_succeed;
3832 unsigned char *xrm_option;
3833 struct x_display_info *dpyinfo;
3835 CHECK_STRING (display);
3836 if (! NILP (xrm_string))
3837 CHECK_STRING (xrm_string);
3839 if (! EQ (Vwindow_system, intern ("x")))
3840 error ("Not using X Windows");
3842 if (! NILP (xrm_string))
3843 xrm_option = (unsigned char *) SDATA (xrm_string);
3844 else
3845 xrm_option = (unsigned char *) 0;
3847 validate_x_resource_name ();
3849 /* This is what opens the connection and sets x_current_display.
3850 This also initializes many symbols, such as those used for input. */
3851 dpyinfo = x_term_init (display, xrm_option,
3852 (char *) SDATA (Vx_resource_name));
3854 if (dpyinfo == 0)
3856 if (!NILP (must_succeed))
3857 fatal ("Cannot connect to X server %s.\n\
3858 Check the DISPLAY environment variable or use `-d'.\n\
3859 Also use the `xauth' program to verify that you have the proper\n\
3860 authorization information needed to connect the X server.\n\
3861 An insecure way to solve the problem may be to use `xhost'.\n",
3862 SDATA (display));
3863 else
3864 error ("Cannot connect to X server %s", SDATA (display));
3867 x_in_use = 1;
3869 XSETFASTINT (Vwindow_system_version, 11);
3870 return Qnil;
3873 DEFUN ("x-close-connection", Fx_close_connection,
3874 Sx_close_connection, 1, 1, 0,
3875 doc: /* Close the connection to DISPLAY's X server.
3876 For DISPLAY, specify either a frame or a display name (a string).
3877 If DISPLAY is nil, that stands for the selected frame's display. */)
3878 (display)
3879 Lisp_Object display;
3881 struct x_display_info *dpyinfo = check_x_display_info (display);
3882 int i;
3884 if (dpyinfo->reference_count > 0)
3885 error ("Display still has frames on it");
3887 BLOCK_INPUT;
3888 /* Free the fonts in the font table. */
3889 for (i = 0; i < dpyinfo->n_fonts; i++)
3890 if (dpyinfo->font_table[i].name)
3892 XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font);
3895 x_destroy_all_bitmaps (dpyinfo);
3896 XSetCloseDownMode (dpyinfo->display, DestroyAll);
3898 #ifdef USE_X_TOOLKIT
3899 XtCloseDisplay (dpyinfo->display);
3900 #else
3901 XCloseDisplay (dpyinfo->display);
3902 #endif
3904 x_delete_display (dpyinfo);
3905 UNBLOCK_INPUT;
3907 return Qnil;
3910 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
3911 doc: /* Return the list of display names that Emacs has connections to. */)
3914 Lisp_Object tail, result;
3916 result = Qnil;
3917 for (tail = x_display_name_list; ! NILP (tail); tail = XCDR (tail))
3918 result = Fcons (XCAR (XCAR (tail)), result);
3920 return result;
3923 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
3924 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
3925 If ON is nil, allow buffering of requests.
3926 Turning on synchronization prohibits the Xlib routines from buffering
3927 requests and seriously degrades performance, but makes debugging much
3928 easier.
3929 The optional second argument DISPLAY specifies which display to act on.
3930 DISPLAY should be either a frame or a display name (a string).
3931 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
3932 (on, display)
3933 Lisp_Object display, on;
3935 struct x_display_info *dpyinfo = check_x_display_info (display);
3937 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
3939 return Qnil;
3942 /* Wait for responses to all X commands issued so far for frame F. */
3944 void
3945 x_sync (f)
3946 FRAME_PTR f;
3948 BLOCK_INPUT;
3949 XSync (FRAME_X_DISPLAY (f), False);
3950 UNBLOCK_INPUT;
3954 /***********************************************************************
3955 Window properties
3956 ***********************************************************************/
3958 DEFUN ("x-change-window-property", Fx_change_window_property,
3959 Sx_change_window_property, 2, 6, 0,
3960 doc: /* Change window property PROP to VALUE on the X window of FRAME.
3961 PROP must be a string.
3962 VALUE may be a string or a list of conses, numbers and/or strings.
3963 If an element in the list is a string, it is converted to
3964 an Atom and the value of the Atom is used. If an element is a cons,
3965 it is converted to a 32 bit number where the car is the 16 top bits and the
3966 cdr is the lower 16 bits.
3967 FRAME nil or omitted means use the selected frame.
3968 If TYPE is given and non-nil, it is the name of the type of VALUE.
3969 If TYPE is not given or nil, the type is STRING.
3970 FORMAT gives the size in bits of each element if VALUE is a list.
3971 It must be one of 8, 16 or 32.
3972 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
3973 If OUTER_P is non-nil, the property is changed for the outer X window of
3974 FRAME. Default is to change on the edit X window.
3976 Value is VALUE. */)
3977 (prop, value, frame, type, format, outer_p)
3978 Lisp_Object prop, value, frame, type, format, outer_p;
3980 struct frame *f = check_x_frame (frame);
3981 Atom prop_atom;
3982 Atom target_type = XA_STRING;
3983 int element_format = 8;
3984 unsigned char *data;
3985 int nelements;
3986 Window w;
3988 CHECK_STRING (prop);
3990 if (! NILP (format))
3992 CHECK_NUMBER (format);
3993 element_format = XFASTINT (format);
3995 if (element_format != 8 && element_format != 16
3996 && element_format != 32)
3997 error ("FORMAT must be one of 8, 16 or 32");
4000 if (CONSP (value))
4002 nelements = x_check_property_data (value);
4003 if (nelements == -1)
4004 error ("Bad data in VALUE, must be number, string or cons");
4006 if (element_format == 8)
4007 data = (unsigned char *) xmalloc (nelements);
4008 else if (element_format == 16)
4009 data = (unsigned char *) xmalloc (nelements*2);
4010 else
4011 data = (unsigned char *) xmalloc (nelements*4);
4013 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4015 else
4017 CHECK_STRING (value);
4018 data = SDATA (value);
4019 nelements = SCHARS (value);
4022 BLOCK_INPUT;
4023 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4024 if (! NILP (type))
4026 CHECK_STRING (type);
4027 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4030 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4031 else w = FRAME_X_WINDOW (f);
4033 XChangeProperty (FRAME_X_DISPLAY (f), w,
4034 prop_atom, target_type, element_format, PropModeReplace,
4035 data, nelements);
4037 if (CONSP (value)) xfree (data);
4039 /* Make sure the property is set when we return. */
4040 XFlush (FRAME_X_DISPLAY (f));
4041 UNBLOCK_INPUT;
4043 return value;
4047 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4048 Sx_delete_window_property, 1, 2, 0,
4049 doc: /* Remove window property PROP from X window of FRAME.
4050 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4051 (prop, frame)
4052 Lisp_Object prop, frame;
4054 struct frame *f = check_x_frame (frame);
4055 Atom prop_atom;
4057 CHECK_STRING (prop);
4058 BLOCK_INPUT;
4059 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4060 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4062 /* Make sure the property is removed when we return. */
4063 XFlush (FRAME_X_DISPLAY (f));
4064 UNBLOCK_INPUT;
4066 return prop;
4070 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4071 1, 6, 0,
4072 doc: /* Value is the value of window property PROP on FRAME.
4073 If FRAME is nil or omitted, use the selected frame.
4074 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4075 is the name of the Atom that denotes the type expected.
4076 If SOURCE is non-nil, get the property on that window instead of from
4077 FRAME. The number 0 denotes the root window.
4078 If DELETE_P is non-nil, delete the property after retreiving it.
4079 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4081 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4082 no value of TYPE. */)
4083 (prop, frame, type, source, delete_p, vector_ret_p)
4084 Lisp_Object prop, frame, type, source, delete_p, vector_ret_p;
4086 struct frame *f = check_x_frame (frame);
4087 Atom prop_atom;
4088 int rc;
4089 Lisp_Object prop_value = Qnil;
4090 char *tmp_data = NULL;
4091 Atom actual_type;
4092 Atom target_type = XA_STRING;
4093 int actual_format;
4094 unsigned long actual_size, bytes_remaining;
4095 Window target_window = FRAME_X_WINDOW (f);
4096 struct gcpro gcpro1;
4098 GCPRO1 (prop_value);
4099 CHECK_STRING (prop);
4101 if (! NILP (source))
4103 if (NUMBERP (source))
4105 if (FLOATP (source))
4106 target_window = (Window) XFLOAT (source);
4107 else
4108 target_window = XFASTINT (source);
4110 if (target_window == 0)
4111 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4113 else if (CONSP (source))
4114 target_window = cons_to_long (source);
4117 BLOCK_INPUT;
4118 if (STRINGP (type))
4120 if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
4121 target_type = AnyPropertyType;
4122 else
4123 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4126 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4127 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4128 prop_atom, 0, 0, False, target_type,
4129 &actual_type, &actual_format, &actual_size,
4130 &bytes_remaining, (unsigned char **) &tmp_data);
4131 if (rc == Success)
4133 int size = bytes_remaining;
4135 XFree (tmp_data);
4136 tmp_data = NULL;
4138 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4139 prop_atom, 0, bytes_remaining,
4140 ! NILP (delete_p), target_type,
4141 &actual_type, &actual_format,
4142 &actual_size, &bytes_remaining,
4143 (unsigned char **) &tmp_data);
4144 if (rc == Success && tmp_data)
4146 if (NILP (vector_ret_p))
4147 prop_value = make_string (tmp_data, size);
4148 else
4149 prop_value = x_property_data_to_lisp (f,
4150 (unsigned char *) tmp_data,
4151 actual_type,
4152 actual_format,
4153 actual_size);
4156 if (tmp_data) XFree (tmp_data);
4159 UNBLOCK_INPUT;
4160 UNGCPRO;
4161 return prop_value;
4166 /***********************************************************************
4167 Busy cursor
4168 ***********************************************************************/
4170 /* If non-null, an asynchronous timer that, when it expires, displays
4171 an hourglass cursor on all frames. */
4173 static struct atimer *hourglass_atimer;
4175 /* Non-zero means an hourglass cursor is currently shown. */
4177 static int hourglass_shown_p;
4179 /* Number of seconds to wait before displaying an hourglass cursor. */
4181 static Lisp_Object Vhourglass_delay;
4183 /* Default number of seconds to wait before displaying an hourglass
4184 cursor. */
4186 #define DEFAULT_HOURGLASS_DELAY 1
4188 /* Function prototypes. */
4190 static void show_hourglass P_ ((struct atimer *));
4191 static void hide_hourglass P_ ((void));
4194 /* Cancel a currently active hourglass timer, and start a new one. */
4196 void
4197 start_hourglass ()
4199 EMACS_TIME delay;
4200 int secs, usecs = 0;
4202 cancel_hourglass ();
4204 if (INTEGERP (Vhourglass_delay)
4205 && XINT (Vhourglass_delay) > 0)
4206 secs = XFASTINT (Vhourglass_delay);
4207 else if (FLOATP (Vhourglass_delay)
4208 && XFLOAT_DATA (Vhourglass_delay) > 0)
4210 Lisp_Object tem;
4211 tem = Ftruncate (Vhourglass_delay, Qnil);
4212 secs = XFASTINT (tem);
4213 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
4215 else
4216 secs = DEFAULT_HOURGLASS_DELAY;
4218 EMACS_SET_SECS_USECS (delay, secs, usecs);
4219 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
4220 show_hourglass, NULL);
4224 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
4225 shown. */
4227 void
4228 cancel_hourglass ()
4230 if (hourglass_atimer)
4232 cancel_atimer (hourglass_atimer);
4233 hourglass_atimer = NULL;
4236 if (hourglass_shown_p)
4237 hide_hourglass ();
4241 /* Timer function of hourglass_atimer. TIMER is equal to
4242 hourglass_atimer.
4244 Display an hourglass pointer on all frames by mapping the frames'
4245 hourglass_window. Set the hourglass_p flag in the frames'
4246 output_data.x structure to indicate that an hourglass cursor is
4247 shown on the frames. */
4249 static void
4250 show_hourglass (timer)
4251 struct atimer *timer;
4253 /* The timer implementation will cancel this timer automatically
4254 after this function has run. Set hourglass_atimer to null
4255 so that we know the timer doesn't have to be canceled. */
4256 hourglass_atimer = NULL;
4258 if (!hourglass_shown_p)
4260 Lisp_Object rest, frame;
4262 BLOCK_INPUT;
4264 FOR_EACH_FRAME (rest, frame)
4266 struct frame *f = XFRAME (frame);
4268 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4270 Display *dpy = FRAME_X_DISPLAY (f);
4272 #ifdef USE_X_TOOLKIT
4273 if (f->output_data.x->widget)
4274 #else
4275 if (FRAME_OUTER_WINDOW (f))
4276 #endif
4278 f->output_data.x->hourglass_p = 1;
4280 if (!f->output_data.x->hourglass_window)
4282 unsigned long mask = CWCursor;
4283 XSetWindowAttributes attrs;
4285 attrs.cursor = f->output_data.x->hourglass_cursor;
4287 f->output_data.x->hourglass_window
4288 = XCreateWindow (dpy, FRAME_OUTER_WINDOW (f),
4289 0, 0, 32000, 32000, 0, 0,
4290 InputOnly,
4291 CopyFromParent,
4292 mask, &attrs);
4295 XMapRaised (dpy, f->output_data.x->hourglass_window);
4296 XFlush (dpy);
4301 hourglass_shown_p = 1;
4302 UNBLOCK_INPUT;
4307 /* Hide the hourglass pointer on all frames, if it is currently
4308 shown. */
4310 static void
4311 hide_hourglass ()
4313 if (hourglass_shown_p)
4315 Lisp_Object rest, frame;
4317 BLOCK_INPUT;
4318 FOR_EACH_FRAME (rest, frame)
4320 struct frame *f = XFRAME (frame);
4322 if (FRAME_X_P (f)
4323 /* Watch out for newly created frames. */
4324 && f->output_data.x->hourglass_window)
4326 XUnmapWindow (FRAME_X_DISPLAY (f),
4327 f->output_data.x->hourglass_window);
4328 /* Sync here because XTread_socket looks at the
4329 hourglass_p flag that is reset to zero below. */
4330 XSync (FRAME_X_DISPLAY (f), False);
4331 f->output_data.x->hourglass_p = 0;
4335 hourglass_shown_p = 0;
4336 UNBLOCK_INPUT;
4342 /***********************************************************************
4343 Tool tips
4344 ***********************************************************************/
4346 static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *,
4347 Lisp_Object, Lisp_Object));
4348 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
4349 Lisp_Object, int, int, int *, int *));
4351 /* The frame of a currently visible tooltip. */
4353 Lisp_Object tip_frame;
4355 /* If non-nil, a timer started that hides the last tooltip when it
4356 fires. */
4358 Lisp_Object tip_timer;
4359 Window tip_window;
4361 /* If non-nil, a vector of 3 elements containing the last args
4362 with which x-show-tip was called. See there. */
4364 Lisp_Object last_show_tip_args;
4366 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4368 Lisp_Object Vx_max_tooltip_size;
4371 static Lisp_Object
4372 unwind_create_tip_frame (frame)
4373 Lisp_Object frame;
4375 Lisp_Object deleted;
4377 deleted = unwind_create_frame (frame);
4378 if (EQ (deleted, Qt))
4380 tip_window = None;
4381 tip_frame = Qnil;
4384 return deleted;
4388 /* Create a frame for a tooltip on the display described by DPYINFO.
4389 PARMS is a list of frame parameters. TEXT is the string to
4390 display in the tip frame. Value is the frame.
4392 Note that functions called here, esp. x_default_parameter can
4393 signal errors, for instance when a specified color name is
4394 undefined. We have to make sure that we're in a consistent state
4395 when this happens. */
4397 static Lisp_Object
4398 x_create_tip_frame (dpyinfo, parms, text)
4399 struct x_display_info *dpyinfo;
4400 Lisp_Object parms, text;
4402 struct frame *f;
4403 Lisp_Object frame, tem;
4404 Lisp_Object name;
4405 long window_prompting = 0;
4406 int width, height;
4407 int count = SPECPDL_INDEX ();
4408 struct gcpro gcpro1, gcpro2, gcpro3;
4409 struct kboard *kb;
4410 int face_change_count_before = face_change_count;
4411 Lisp_Object buffer;
4412 struct buffer *old_buffer;
4414 check_x ();
4416 /* Use this general default value to start with until we know if
4417 this frame has a specified name. */
4418 Vx_resource_name = Vinvocation_name;
4420 #ifdef MULTI_KBOARD
4421 kb = dpyinfo->kboard;
4422 #else
4423 kb = &the_only_kboard;
4424 #endif
4426 /* Get the name of the frame to use for resource lookup. */
4427 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4428 if (!STRINGP (name)
4429 && !EQ (name, Qunbound)
4430 && !NILP (name))
4431 error ("Invalid frame name--not a string or nil");
4432 Vx_resource_name = name;
4434 frame = Qnil;
4435 GCPRO3 (parms, name, frame);
4436 f = make_frame (1);
4437 XSETFRAME (frame, f);
4439 buffer = Fget_buffer_create (build_string (" *tip*"));
4440 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
4441 old_buffer = current_buffer;
4442 set_buffer_internal_1 (XBUFFER (buffer));
4443 current_buffer->truncate_lines = Qnil;
4444 specbind (Qinhibit_read_only, Qt);
4445 specbind (Qinhibit_modification_hooks, Qt);
4446 Ferase_buffer ();
4447 Finsert (1, &text);
4448 set_buffer_internal_1 (old_buffer);
4450 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4451 record_unwind_protect (unwind_create_tip_frame, frame);
4453 /* By setting the output method, we're essentially saying that
4454 the frame is live, as per FRAME_LIVE_P. If we get a signal
4455 from this point on, x_destroy_window might screw up reference
4456 counts etc. */
4457 f->output_method = output_x_window;
4458 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
4459 bzero (f->output_data.x, sizeof (struct x_output));
4460 f->output_data.x->icon_bitmap = -1;
4461 FRAME_FONTSET (f) = -1;
4462 f->output_data.x->scroll_bar_foreground_pixel = -1;
4463 f->output_data.x->scroll_bar_background_pixel = -1;
4464 #ifdef USE_TOOLKIT_SCROLL_BARS
4465 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4466 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4467 #endif /* USE_TOOLKIT_SCROLL_BARS */
4468 f->icon_name = Qnil;
4469 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4470 #if GLYPH_DEBUG
4471 image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
4472 dpyinfo_refcount = dpyinfo->reference_count;
4473 #endif /* GLYPH_DEBUG */
4474 #ifdef MULTI_KBOARD
4475 FRAME_KBOARD (f) = kb;
4476 #endif
4477 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4478 f->output_data.x->explicit_parent = 0;
4480 /* These colors will be set anyway later, but it's important
4481 to get the color reference counts right, so initialize them! */
4483 Lisp_Object black;
4484 struct gcpro gcpro1;
4486 black = build_string ("black");
4487 GCPRO1 (black);
4488 f->output_data.x->foreground_pixel
4489 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4490 f->output_data.x->background_pixel
4491 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4492 f->output_data.x->cursor_pixel
4493 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4494 f->output_data.x->cursor_foreground_pixel
4495 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4496 f->output_data.x->border_pixel
4497 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4498 f->output_data.x->mouse_pixel
4499 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4500 UNGCPRO;
4503 /* Set the name; the functions to which we pass f expect the name to
4504 be set. */
4505 if (EQ (name, Qunbound) || NILP (name))
4507 f->name = build_string (dpyinfo->x_id_name);
4508 f->explicit_name = 0;
4510 else
4512 f->name = name;
4513 f->explicit_name = 1;
4514 /* use the frame's title when getting resources for this frame. */
4515 specbind (Qx_resource_name, name);
4518 /* Extract the window parameters from the supplied values that are
4519 needed to determine window geometry. */
4521 Lisp_Object font;
4523 font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
4525 BLOCK_INPUT;
4526 /* First, try whatever font the caller has specified. */
4527 if (STRINGP (font))
4529 tem = Fquery_fontset (font, Qnil);
4530 if (STRINGP (tem))
4531 font = x_new_fontset (f, SDATA (tem));
4532 else
4533 font = x_new_font (f, SDATA (font));
4536 /* Try out a font which we hope has bold and italic variations. */
4537 if (!STRINGP (font))
4538 font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
4539 if (!STRINGP (font))
4540 font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
4541 if (! STRINGP (font))
4542 font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
4543 if (! STRINGP (font))
4544 /* This was formerly the first thing tried, but it finds too many fonts
4545 and takes too long. */
4546 font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
4547 /* If those didn't work, look for something which will at least work. */
4548 if (! STRINGP (font))
4549 font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
4550 UNBLOCK_INPUT;
4551 if (! STRINGP (font))
4552 font = build_string ("fixed");
4554 x_default_parameter (f, parms, Qfont, font,
4555 "font", "Font", RES_TYPE_STRING);
4558 x_default_parameter (f, parms, Qborder_width, make_number (2),
4559 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4561 /* This defaults to 2 in order to match xterm. We recognize either
4562 internalBorderWidth or internalBorder (which is what xterm calls
4563 it). */
4564 if (NILP (Fassq (Qinternal_border_width, parms)))
4566 Lisp_Object value;
4568 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4569 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4570 if (! EQ (value, Qunbound))
4571 parms = Fcons (Fcons (Qinternal_border_width, value),
4572 parms);
4575 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4576 "internalBorderWidth", "internalBorderWidth",
4577 RES_TYPE_NUMBER);
4579 /* Also do the stuff which must be set before the window exists. */
4580 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4581 "foreground", "Foreground", RES_TYPE_STRING);
4582 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4583 "background", "Background", RES_TYPE_STRING);
4584 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4585 "pointerColor", "Foreground", RES_TYPE_STRING);
4586 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4587 "cursorColor", "Foreground", RES_TYPE_STRING);
4588 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4589 "borderColor", "BorderColor", RES_TYPE_STRING);
4591 /* Init faces before x_default_parameter is called for scroll-bar
4592 parameters because that function calls x_set_scroll_bar_width,
4593 which calls change_frame_size, which calls Fset_window_buffer,
4594 which runs hooks, which call Fvertical_motion. At the end, we
4595 end up in init_iterator with a null face cache, which should not
4596 happen. */
4597 init_frame_faces (f);
4599 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4601 window_prompting = x_figure_window_size (f, parms, 0);
4604 XSetWindowAttributes attrs;
4605 unsigned long mask;
4607 BLOCK_INPUT;
4608 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
4609 if (DoesSaveUnders (dpyinfo->screen))
4610 mask |= CWSaveUnder;
4612 /* Window managers look at the override-redirect flag to determine
4613 whether or net to give windows a decoration (Xlib spec, chapter
4614 3.2.8). */
4615 attrs.override_redirect = True;
4616 attrs.save_under = True;
4617 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
4618 /* Arrange for getting MapNotify and UnmapNotify events. */
4619 attrs.event_mask = StructureNotifyMask;
4620 tip_window
4621 = FRAME_X_WINDOW (f)
4622 = XCreateWindow (FRAME_X_DISPLAY (f),
4623 FRAME_X_DISPLAY_INFO (f)->root_window,
4624 /* x, y, width, height */
4625 0, 0, 1, 1,
4626 /* Border. */
4628 CopyFromParent, InputOutput, CopyFromParent,
4629 mask, &attrs);
4630 UNBLOCK_INPUT;
4633 x_make_gc (f);
4635 x_default_parameter (f, parms, Qauto_raise, Qnil,
4636 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4637 x_default_parameter (f, parms, Qauto_lower, Qnil,
4638 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4639 x_default_parameter (f, parms, Qcursor_type, Qbox,
4640 "cursorType", "CursorType", RES_TYPE_SYMBOL);
4642 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4643 Change will not be effected unless different from the current
4644 FRAME_LINES (f). */
4645 width = FRAME_COLS (f);
4646 height = FRAME_LINES (f);
4647 SET_FRAME_COLS (f, 0);
4648 FRAME_LINES (f) = 0;
4649 change_frame_size (f, height, width, 1, 0, 0);
4651 /* Add `tooltip' frame parameter's default value. */
4652 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
4653 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
4654 Qnil));
4656 /* Set up faces after all frame parameters are known. This call
4657 also merges in face attributes specified for new frames.
4659 Frame parameters may be changed if .Xdefaults contains
4660 specifications for the default font. For example, if there is an
4661 `Emacs.default.attributeBackground: pink', the `background-color'
4662 attribute of the frame get's set, which let's the internal border
4663 of the tooltip frame appear in pink. Prevent this. */
4665 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
4667 /* Set tip_frame here, so that */
4668 tip_frame = frame;
4669 call1 (Qface_set_after_frame_default, frame);
4671 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
4672 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
4673 Qnil));
4676 f->no_split = 1;
4678 UNGCPRO;
4680 /* It is now ok to make the frame official even if we get an error
4681 below. And the frame needs to be on Vframe_list or making it
4682 visible won't work. */
4683 Vframe_list = Fcons (frame, Vframe_list);
4685 /* Now that the frame is official, it counts as a reference to
4686 its display. */
4687 FRAME_X_DISPLAY_INFO (f)->reference_count++;
4689 /* Setting attributes of faces of the tooltip frame from resources
4690 and similar will increment face_change_count, which leads to the
4691 clearing of all current matrices. Since this isn't necessary
4692 here, avoid it by resetting face_change_count to the value it
4693 had before we created the tip frame. */
4694 face_change_count = face_change_count_before;
4696 /* Discard the unwind_protect. */
4697 return unbind_to (count, frame);
4701 /* Compute where to display tip frame F. PARMS is the list of frame
4702 parameters for F. DX and DY are specified offsets from the current
4703 location of the mouse. WIDTH and HEIGHT are the width and height
4704 of the tooltip. Return coordinates relative to the root window of
4705 the display in *ROOT_X, and *ROOT_Y. */
4707 static void
4708 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
4709 struct frame *f;
4710 Lisp_Object parms, dx, dy;
4711 int width, height;
4712 int *root_x, *root_y;
4714 Lisp_Object left, top;
4715 int win_x, win_y;
4716 Window root, child;
4717 unsigned pmask;
4719 /* User-specified position? */
4720 left = Fcdr (Fassq (Qleft, parms));
4721 top = Fcdr (Fassq (Qtop, parms));
4723 /* Move the tooltip window where the mouse pointer is. Resize and
4724 show it. */
4725 if (!INTEGERP (left) || !INTEGERP (top))
4727 BLOCK_INPUT;
4728 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
4729 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
4730 UNBLOCK_INPUT;
4733 if (INTEGERP (top))
4734 *root_y = XINT (top);
4735 else if (*root_y + XINT (dy) - height < 0)
4736 *root_y -= XINT (dy);
4737 else
4739 *root_y -= height;
4740 *root_y += XINT (dy);
4743 if (INTEGERP (left))
4744 *root_x = XINT (left);
4745 else if (*root_x + XINT (dx) + width <= FRAME_X_DISPLAY_INFO (f)->width)
4746 /* It fits to the right of the pointer. */
4747 *root_x += XINT (dx);
4748 else if (width + XINT (dx) <= *root_x)
4749 /* It fits to the left of the pointer. */
4750 *root_x -= width + XINT (dx);
4751 else
4752 /* Put it left-justified on the screen--it ought to fit that way. */
4753 *root_x = 0;
4757 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
4758 doc: /* Show STRING in a "tooltip" window on frame FRAME.
4759 A tooltip window is a small X window displaying a string.
4761 FRAME nil or omitted means use the selected frame.
4763 PARMS is an optional list of frame parameters which can be used to
4764 change the tooltip's appearance.
4766 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
4767 means use the default timeout of 5 seconds.
4769 If the list of frame parameters PARAMS contains a `left' parameters,
4770 the tooltip is displayed at that x-position. Otherwise it is
4771 displayed at the mouse position, with offset DX added (default is 5 if
4772 DX isn't specified). Likewise for the y-position; if a `top' frame
4773 parameter is specified, it determines the y-position of the tooltip
4774 window, otherwise it is displayed at the mouse position, with offset
4775 DY added (default is -10).
4777 A tooltip's maximum size is specified by `x-max-tooltip-size'.
4778 Text larger than the specified size is clipped. */)
4779 (string, frame, parms, timeout, dx, dy)
4780 Lisp_Object string, frame, parms, timeout, dx, dy;
4782 struct frame *f;
4783 struct window *w;
4784 int root_x, root_y;
4785 struct buffer *old_buffer;
4786 struct text_pos pos;
4787 int i, width, height;
4788 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4789 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4790 int count = SPECPDL_INDEX ();
4792 specbind (Qinhibit_redisplay, Qt);
4794 GCPRO4 (string, parms, frame, timeout);
4796 CHECK_STRING (string);
4797 f = check_x_frame (frame);
4798 if (NILP (timeout))
4799 timeout = make_number (5);
4800 else
4801 CHECK_NATNUM (timeout);
4803 if (NILP (dx))
4804 dx = make_number (5);
4805 else
4806 CHECK_NUMBER (dx);
4808 if (NILP (dy))
4809 dy = make_number (-10);
4810 else
4811 CHECK_NUMBER (dy);
4813 if (NILP (last_show_tip_args))
4814 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
4816 if (!NILP (tip_frame))
4818 Lisp_Object last_string = AREF (last_show_tip_args, 0);
4819 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
4820 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
4822 if (EQ (frame, last_frame)
4823 && !NILP (Fequal (last_string, string))
4824 && !NILP (Fequal (last_parms, parms)))
4826 struct frame *f = XFRAME (tip_frame);
4828 /* Only DX and DY have changed. */
4829 if (!NILP (tip_timer))
4831 Lisp_Object timer = tip_timer;
4832 tip_timer = Qnil;
4833 call1 (Qcancel_timer, timer);
4836 BLOCK_INPUT;
4837 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
4838 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
4839 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4840 root_x, root_y);
4841 UNBLOCK_INPUT;
4842 goto start_timer;
4846 /* Hide a previous tip, if any. */
4847 Fx_hide_tip ();
4849 ASET (last_show_tip_args, 0, string);
4850 ASET (last_show_tip_args, 1, frame);
4851 ASET (last_show_tip_args, 2, parms);
4853 /* Add default values to frame parameters. */
4854 if (NILP (Fassq (Qname, parms)))
4855 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
4856 if (NILP (Fassq (Qinternal_border_width, parms)))
4857 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
4858 if (NILP (Fassq (Qborder_width, parms)))
4859 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
4860 if (NILP (Fassq (Qborder_color, parms)))
4861 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
4862 if (NILP (Fassq (Qbackground_color, parms)))
4863 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
4864 parms);
4866 /* Create a frame for the tooltip, and record it in the global
4867 variable tip_frame. */
4868 frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
4869 f = XFRAME (frame);
4871 /* Set up the frame's root window. */
4872 w = XWINDOW (FRAME_ROOT_WINDOW (f));
4873 w->left_col = w->top_line = make_number (0);
4875 if (CONSP (Vx_max_tooltip_size)
4876 && INTEGERP (XCAR (Vx_max_tooltip_size))
4877 && XINT (XCAR (Vx_max_tooltip_size)) > 0
4878 && INTEGERP (XCDR (Vx_max_tooltip_size))
4879 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
4881 w->total_cols = XCAR (Vx_max_tooltip_size);
4882 w->total_lines = XCDR (Vx_max_tooltip_size);
4884 else
4886 w->total_cols = make_number (80);
4887 w->total_lines = make_number (40);
4890 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
4891 adjust_glyphs (f);
4892 w->pseudo_window_p = 1;
4894 /* Display the tooltip text in a temporary buffer. */
4895 old_buffer = current_buffer;
4896 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
4897 current_buffer->truncate_lines = Qnil;
4898 clear_glyph_matrix (w->desired_matrix);
4899 clear_glyph_matrix (w->current_matrix);
4900 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
4901 try_window (FRAME_ROOT_WINDOW (f), pos);
4903 /* Compute width and height of the tooltip. */
4904 width = height = 0;
4905 for (i = 0; i < w->desired_matrix->nrows; ++i)
4907 struct glyph_row *row = &w->desired_matrix->rows[i];
4908 struct glyph *last;
4909 int row_width;
4911 /* Stop at the first empty row at the end. */
4912 if (!row->enabled_p || !row->displays_text_p)
4913 break;
4915 /* Let the row go over the full width of the frame. */
4916 row->full_width_p = 1;
4918 /* There's a glyph at the end of rows that is used to place
4919 the cursor there. Don't include the width of this glyph. */
4920 if (row->used[TEXT_AREA])
4922 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
4923 row_width = row->pixel_width - last->pixel_width;
4925 else
4926 row_width = row->pixel_width;
4928 height += row->height;
4929 width = max (width, row_width);
4932 /* Add the frame's internal border to the width and height the X
4933 window should have. */
4934 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
4935 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
4937 /* Move the tooltip window where the mouse pointer is. Resize and
4938 show it. */
4939 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
4941 BLOCK_INPUT;
4942 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4943 root_x, root_y, width, height);
4944 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
4945 UNBLOCK_INPUT;
4947 /* Draw into the window. */
4948 w->must_be_updated_p = 1;
4949 update_single_window (w, 1);
4951 /* Restore original current buffer. */
4952 set_buffer_internal_1 (old_buffer);
4953 windows_or_buffers_changed = old_windows_or_buffers_changed;
4955 start_timer:
4956 /* Let the tip disappear after timeout seconds. */
4957 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
4958 intern ("x-hide-tip"));
4960 UNGCPRO;
4961 return unbind_to (count, Qnil);
4965 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
4966 doc: /* Hide the current tooltip window, if there is any.
4967 Value is t if tooltip was open, nil otherwise. */)
4970 int count;
4971 Lisp_Object deleted, frame, timer;
4972 struct gcpro gcpro1, gcpro2;
4974 /* Return quickly if nothing to do. */
4975 if (NILP (tip_timer) && NILP (tip_frame))
4976 return Qnil;
4978 frame = tip_frame;
4979 timer = tip_timer;
4980 GCPRO2 (frame, timer);
4981 tip_frame = tip_timer = deleted = Qnil;
4983 count = SPECPDL_INDEX ();
4984 specbind (Qinhibit_redisplay, Qt);
4985 specbind (Qinhibit_quit, Qt);
4987 if (!NILP (timer))
4988 call1 (Qcancel_timer, timer);
4990 if (FRAMEP (frame))
4992 Fdelete_frame (frame, Qnil);
4993 deleted = Qt;
4995 #ifdef USE_LUCID
4996 /* Bloodcurdling hack alert: The Lucid menu bar widget's
4997 redisplay procedure is not called when a tip frame over menu
4998 items is unmapped. Redisplay the menu manually... */
5000 struct frame *f = SELECTED_FRAME ();
5001 Widget w = f->output_data.x->menubar_widget;
5002 extern void xlwmenu_redisplay P_ ((Widget));
5004 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5005 && w != NULL)
5007 BLOCK_INPUT;
5008 xlwmenu_redisplay (w);
5009 UNBLOCK_INPUT;
5012 #endif /* USE_LUCID */
5015 UNGCPRO;
5016 return unbind_to (count, deleted);
5021 /***********************************************************************
5022 File selection dialog
5023 ***********************************************************************/
5025 #ifdef USE_MOTIF
5027 /* Callback for "OK" and "Cancel" on file selection dialog. */
5029 static void
5030 file_dialog_cb (widget, client_data, call_data)
5031 Widget widget;
5032 XtPointer call_data, client_data;
5034 int *result = (int *) client_data;
5035 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5036 *result = cb->reason;
5040 /* Callback for unmapping a file selection dialog. This is used to
5041 capture the case where a dialog is closed via a window manager's
5042 closer button, for example. Using a XmNdestroyCallback didn't work
5043 in this case. */
5045 static void
5046 file_dialog_unmap_cb (widget, client_data, call_data)
5047 Widget widget;
5048 XtPointer call_data, client_data;
5050 int *result = (int *) client_data;
5051 *result = XmCR_CANCEL;
5055 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,
5056 doc: /* Read file name, prompting with PROMPT in directory DIR.
5057 Use a file selection dialog.
5058 Select DEFAULT-FILENAME in the dialog's file selection box, if
5059 specified. Don't let the user enter a file name in the file
5060 selection dialog's entry field, if MUSTMATCH is non-nil. */)
5061 (prompt, dir, default_filename, mustmatch)
5062 Lisp_Object prompt, dir, default_filename, mustmatch;
5064 int result;
5065 struct frame *f = SELECTED_FRAME ();
5066 Lisp_Object file = Qnil;
5067 Widget dialog, text, list, help;
5068 Arg al[10];
5069 int ac = 0;
5070 extern XtAppContext Xt_app_con;
5071 XmString dir_xmstring, pattern_xmstring;
5072 int count = SPECPDL_INDEX ();
5073 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
5075 GCPRO5 (prompt, dir, default_filename, mustmatch, file);
5076 CHECK_STRING (prompt);
5077 CHECK_STRING (dir);
5079 /* Prevent redisplay. */
5080 specbind (Qinhibit_redisplay, Qt);
5082 BLOCK_INPUT;
5084 /* Create the dialog with PROMPT as title, using DIR as initial
5085 directory and using "*" as pattern. */
5086 dir = Fexpand_file_name (dir, Qnil);
5087 dir_xmstring = XmStringCreateLocalized (SDATA (dir));
5088 pattern_xmstring = XmStringCreateLocalized ("*");
5090 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5091 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5092 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5093 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5094 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5095 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5096 "fsb", al, ac);
5097 XmStringFree (dir_xmstring);
5098 XmStringFree (pattern_xmstring);
5100 /* Add callbacks for OK and Cancel. */
5101 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5102 (XtPointer) &result);
5103 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5104 (XtPointer) &result);
5105 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5106 (XtPointer) &result);
5108 /* Disable the help button since we can't display help. */
5109 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5110 XtSetSensitive (help, False);
5112 /* Mark OK button as default. */
5113 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5114 XmNshowAsDefault, True, NULL);
5116 /* If MUSTMATCH is non-nil, disable the file entry field of the
5117 dialog, so that the user must select a file from the files list
5118 box. We can't remove it because we wouldn't have a way to get at
5119 the result file name, then. */
5120 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5121 if (!NILP (mustmatch))
5123 Widget label;
5124 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5125 XtSetSensitive (text, False);
5126 XtSetSensitive (label, False);
5129 /* Manage the dialog, so that list boxes get filled. */
5130 XtManageChild (dialog);
5132 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5133 must include the path for this to work. */
5134 list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5135 if (STRINGP (default_filename))
5137 XmString default_xmstring;
5138 int item_pos;
5140 default_xmstring
5141 = XmStringCreateLocalized (SDATA (default_filename));
5143 if (!XmListItemExists (list, default_xmstring))
5145 /* Add a new item if DEFAULT_FILENAME is not in the list. */
5146 XmListAddItem (list, default_xmstring, 0);
5147 item_pos = 0;
5149 else
5150 item_pos = XmListItemPos (list, default_xmstring);
5151 XmStringFree (default_xmstring);
5153 /* Select the item and scroll it into view. */
5154 XmListSelectPos (list, item_pos, True);
5155 XmListSetPos (list, item_pos);
5158 /* Process events until the user presses Cancel or OK. */
5159 result = 0;
5160 while (result == 0)
5162 XEvent event;
5163 XtAppNextEvent (Xt_app_con, &event);
5164 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f) );
5167 /* Get the result. */
5168 if (result == XmCR_OK)
5170 XmString text;
5171 String data;
5173 XtVaGetValues (dialog, XmNtextString, &text, NULL);
5174 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
5175 XmStringFree (text);
5176 file = build_string (data);
5177 XtFree (data);
5179 else
5180 file = Qnil;
5182 /* Clean up. */
5183 XtUnmanageChild (dialog);
5184 XtDestroyWidget (dialog);
5185 UNBLOCK_INPUT;
5186 UNGCPRO;
5188 /* Make "Cancel" equivalent to C-g. */
5189 if (NILP (file))
5190 Fsignal (Qquit, Qnil);
5192 return unbind_to (count, file);
5195 #endif /* USE_MOTIF */
5197 #ifdef USE_GTK
5199 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,
5200 "Read file name, prompting with PROMPT in directory DIR.\n\
5201 Use a file selection dialog.\n\
5202 Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
5203 specified. Don't let the user enter a file name in the file\n\
5204 selection dialog's entry field, if MUSTMATCH is non-nil.")
5205 (prompt, dir, default_filename, mustmatch)
5206 Lisp_Object prompt, dir, default_filename, mustmatch;
5208 FRAME_PTR f = SELECTED_FRAME ();
5209 char *fn;
5210 Lisp_Object file = Qnil;
5211 int count = specpdl_ptr - specpdl;
5212 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
5213 char *cdef_file;
5215 GCPRO5 (prompt, dir, default_filename, mustmatch, file);
5216 CHECK_STRING (prompt);
5217 CHECK_STRING (dir);
5219 /* Prevent redisplay. */
5220 specbind (Qinhibit_redisplay, Qt);
5222 BLOCK_INPUT;
5224 if (STRINGP (default_filename))
5225 cdef_file = SDATA (default_filename);
5226 else
5227 cdef_file = SDATA (dir);
5229 fn = xg_get_file_name (f, SDATA (prompt), cdef_file, ! NILP (mustmatch));
5231 if (fn)
5233 file = build_string (fn);
5234 xfree (fn);
5237 UNBLOCK_INPUT;
5238 UNGCPRO;
5240 /* Make "Cancel" equivalent to C-g. */
5241 if (NILP (file))
5242 Fsignal (Qquit, Qnil);
5244 return unbind_to (count, file);
5247 #endif /* USE_GTK */
5250 /***********************************************************************
5251 Keyboard
5252 ***********************************************************************/
5254 #ifdef HAVE_XKBGETKEYBOARD
5255 #include <X11/XKBlib.h>
5256 #include <X11/keysym.h>
5257 #endif
5259 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5260 Sx_backspace_delete_keys_p, 0, 1, 0,
5261 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5262 FRAME nil means use the selected frame.
5263 Value is t if we know that both keys are present, and are mapped to the
5264 usual X keysyms. */)
5265 (frame)
5266 Lisp_Object frame;
5268 #ifdef HAVE_XKBGETKEYBOARD
5269 XkbDescPtr kb;
5270 struct frame *f = check_x_frame (frame);
5271 Display *dpy = FRAME_X_DISPLAY (f);
5272 Lisp_Object have_keys;
5273 int major, minor, op, event, error;
5275 BLOCK_INPUT;
5277 /* Check library version in case we're dynamically linked. */
5278 major = XkbMajorVersion;
5279 minor = XkbMinorVersion;
5280 if (!XkbLibraryVersion (&major, &minor))
5282 UNBLOCK_INPUT;
5283 return Qnil;
5286 /* Check that the server supports XKB. */
5287 major = XkbMajorVersion;
5288 minor = XkbMinorVersion;
5289 if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
5291 UNBLOCK_INPUT;
5292 return Qnil;
5295 have_keys = Qnil;
5296 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5297 if (kb)
5299 int delete_keycode = 0, backspace_keycode = 0, i;
5301 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5303 for (i = kb->min_key_code;
5304 (i < kb->max_key_code
5305 && (delete_keycode == 0 || backspace_keycode == 0));
5306 ++i)
5308 /* The XKB symbolic key names can be seen most easily in
5309 the PS file generated by `xkbprint -label name
5310 $DISPLAY'. */
5311 if (bcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5312 delete_keycode = i;
5313 else if (bcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5314 backspace_keycode = i;
5317 XkbFreeNames (kb, 0, True);
5320 XkbFreeClientMap (kb, 0, True);
5322 if (delete_keycode
5323 && backspace_keycode
5324 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5325 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5326 have_keys = Qt;
5328 UNBLOCK_INPUT;
5329 return have_keys;
5330 #else /* not HAVE_XKBGETKEYBOARD */
5331 return Qnil;
5332 #endif /* not HAVE_XKBGETKEYBOARD */
5337 /***********************************************************************
5338 Initialization
5339 ***********************************************************************/
5341 /* Keep this list in the same order as frame_parms in frame.c.
5342 Use 0 for unsupported frame parameters. */
5344 frame_parm_handler x_frame_parm_handlers[] =
5346 x_set_autoraise,
5347 x_set_autolower,
5348 x_set_background_color,
5349 x_set_border_color,
5350 x_set_border_width,
5351 x_set_cursor_color,
5352 x_set_cursor_type,
5353 x_set_font,
5354 x_set_foreground_color,
5355 x_set_icon_name,
5356 x_set_icon_type,
5357 x_set_internal_border_width,
5358 x_set_menu_bar_lines,
5359 x_set_mouse_color,
5360 x_explicitly_set_name,
5361 x_set_scroll_bar_width,
5362 x_set_title,
5363 x_set_unsplittable,
5364 x_set_vertical_scroll_bars,
5365 x_set_visibility,
5366 x_set_tool_bar_lines,
5367 x_set_scroll_bar_foreground,
5368 x_set_scroll_bar_background,
5369 x_set_screen_gamma,
5370 x_set_line_spacing,
5371 x_set_fringe_width,
5372 x_set_fringe_width,
5373 x_set_wait_for_wm,
5374 x_set_fullscreen,
5377 void
5378 syms_of_xfns ()
5380 /* This is zero if not using X windows. */
5381 x_in_use = 0;
5383 /* The section below is built by the lisp expression at the top of the file,
5384 just above where these variables are declared. */
5385 /*&&& init symbols here &&&*/
5386 Qnone = intern ("none");
5387 staticpro (&Qnone);
5388 Qsuppress_icon = intern ("suppress-icon");
5389 staticpro (&Qsuppress_icon);
5390 Qundefined_color = intern ("undefined-color");
5391 staticpro (&Qundefined_color);
5392 Qcompound_text = intern ("compound-text");
5393 staticpro (&Qcompound_text);
5394 Qcancel_timer = intern ("cancel-timer");
5395 staticpro (&Qcancel_timer);
5396 /* This is the end of symbol initialization. */
5398 /* Text property `display' should be nonsticky by default. */
5399 Vtext_property_default_nonsticky
5400 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
5403 Fput (Qundefined_color, Qerror_conditions,
5404 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
5405 Fput (Qundefined_color, Qerror_message,
5406 build_string ("Undefined color"));
5408 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
5409 doc: /* The shape of the pointer when over text.
5410 Changing the value does not affect existing frames
5411 unless you set the mouse color. */);
5412 Vx_pointer_shape = Qnil;
5414 #if 0 /* This doesn't really do anything. */
5415 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
5416 doc: /* The shape of the pointer when not over text.
5417 This variable takes effect when you create a new frame
5418 or when you set the mouse color. */);
5419 #endif
5420 Vx_nontext_pointer_shape = Qnil;
5422 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
5423 doc: /* The shape of the pointer when Emacs is busy.
5424 This variable takes effect when you create a new frame
5425 or when you set the mouse color. */);
5426 Vx_hourglass_pointer_shape = Qnil;
5428 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
5429 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
5430 display_hourglass_p = 1;
5432 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
5433 doc: /* *Seconds to wait before displaying an hourglass pointer.
5434 Value must be an integer or float. */);
5435 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
5437 #if 0 /* This doesn't really do anything. */
5438 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
5439 doc: /* The shape of the pointer when over the mode line.
5440 This variable takes effect when you create a new frame
5441 or when you set the mouse color. */);
5442 #endif
5443 Vx_mode_pointer_shape = Qnil;
5445 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5446 &Vx_sensitive_text_pointer_shape,
5447 doc: /* The shape of the pointer when over mouse-sensitive text.
5448 This variable takes effect when you create a new frame
5449 or when you set the mouse color. */);
5450 Vx_sensitive_text_pointer_shape = Qnil;
5452 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5453 &Vx_window_horizontal_drag_shape,
5454 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
5455 This variable takes effect when you create a new frame
5456 or when you set the mouse color. */);
5457 Vx_window_horizontal_drag_shape = Qnil;
5459 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
5460 doc: /* A string indicating the foreground color of the cursor box. */);
5461 Vx_cursor_fore_pixel = Qnil;
5463 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
5464 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
5465 Text larger than this is clipped. */);
5466 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
5468 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
5469 doc: /* Non-nil if no X window manager is in use.
5470 Emacs doesn't try to figure this out; this is always nil
5471 unless you set it to something else. */);
5472 /* We don't have any way to find this out, so set it to nil
5473 and maybe the user would like to set it to t. */
5474 Vx_no_window_manager = Qnil;
5476 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5477 &Vx_pixel_size_width_font_regexp,
5478 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5480 Since Emacs gets width of a font matching with this regexp from
5481 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5482 such a font. This is especially effective for such large fonts as
5483 Chinese, Japanese, and Korean. */);
5484 Vx_pixel_size_width_font_regexp = Qnil;
5486 #ifdef USE_X_TOOLKIT
5487 Fprovide (intern ("x-toolkit"), Qnil);
5488 #ifdef USE_MOTIF
5489 Fprovide (intern ("motif"), Qnil);
5491 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
5492 doc: /* Version info for LessTif/Motif. */);
5493 Vmotif_version_string = build_string (XmVERSION_STRING);
5494 #endif /* USE_MOTIF */
5495 #endif /* USE_X_TOOLKIT */
5497 #ifdef USE_GTK
5498 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
5499 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
5500 But for a user it is a toolkit for X, and indeed, configure
5501 accepts --with-x-toolkit=gtk. */
5502 Fprovide (intern ("x-toolkit"), Qnil);
5503 Fprovide (intern ("gtk"), Qnil);
5505 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
5506 doc: /* Version info for GTK+. */);
5508 char gtk_version[40];
5509 g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
5510 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
5511 Vgtk_version_string = build_string (gtk_version);
5513 #endif /* USE_GTK */
5515 /* X window properties. */
5516 defsubr (&Sx_change_window_property);
5517 defsubr (&Sx_delete_window_property);
5518 defsubr (&Sx_window_property);
5520 defsubr (&Sxw_display_color_p);
5521 defsubr (&Sx_display_grayscale_p);
5522 defsubr (&Sxw_color_defined_p);
5523 defsubr (&Sxw_color_values);
5524 defsubr (&Sx_server_max_request_size);
5525 defsubr (&Sx_server_vendor);
5526 defsubr (&Sx_server_version);
5527 defsubr (&Sx_display_pixel_width);
5528 defsubr (&Sx_display_pixel_height);
5529 defsubr (&Sx_display_mm_width);
5530 defsubr (&Sx_display_mm_height);
5531 defsubr (&Sx_display_screens);
5532 defsubr (&Sx_display_planes);
5533 defsubr (&Sx_display_color_cells);
5534 defsubr (&Sx_display_visual_class);
5535 defsubr (&Sx_display_backing_store);
5536 defsubr (&Sx_display_save_under);
5537 defsubr (&Sx_create_frame);
5538 defsubr (&Sx_open_connection);
5539 defsubr (&Sx_close_connection);
5540 defsubr (&Sx_display_list);
5541 defsubr (&Sx_synchronize);
5542 defsubr (&Sx_focus_frame);
5543 defsubr (&Sx_backspace_delete_keys_p);
5545 /* Setting callback functions for fontset handler. */
5546 get_font_info_func = x_get_font_info;
5548 #if 0 /* This function pointer doesn't seem to be used anywhere.
5549 And the pointer assigned has the wrong type, anyway. */
5550 list_fonts_func = x_list_fonts;
5551 #endif
5553 load_font_func = x_load_font;
5554 find_ccl_program_func = x_find_ccl_program;
5555 query_font_func = x_query_font;
5556 set_frame_fontset_func = x_set_font;
5557 check_window_system_func = check_x;
5559 hourglass_atimer = NULL;
5560 hourglass_shown_p = 0;
5562 defsubr (&Sx_show_tip);
5563 defsubr (&Sx_hide_tip);
5564 tip_timer = Qnil;
5565 staticpro (&tip_timer);
5566 tip_frame = Qnil;
5567 staticpro (&tip_frame);
5569 last_show_tip_args = Qnil;
5570 staticpro (&last_show_tip_args);
5572 #ifdef USE_MOTIF
5573 defsubr (&Sx_file_dialog);
5574 #endif
5577 #endif /* HAVE_X_WINDOWS */
5579 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
5580 (do not change this comment) */