Backport 2010-04-10T10:39:16Z!mituharu@math.s.chiba-u.ac.jp from trunk
[emacs.git] / src / xfns.c
blob635264ea862f46cf807972bd4b76dc9bbeedb888
1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 #include <config.h>
22 #include <stdio.h>
23 #include <math.h>
24 #include <setjmp.h>
25 #include <ctype.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 "character.h"
46 #include "charset.h"
47 #include "coding.h"
48 #include "fontset.h"
49 #include "systime.h"
50 #include "termhooks.h"
51 #include "atimer.h"
52 #include "termchar.h"
53 #include "font.h"
55 #ifdef HAVE_X_WINDOWS
57 #include <ctype.h>
58 #include <sys/types.h>
59 #include <sys/stat.h>
61 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
62 #include "bitmaps/gray.xbm"
63 #else
64 #include <X11/bitmaps/gray>
65 #endif
67 #include "xsettings.h"
69 #ifdef USE_GTK
70 #include "gtkutil.h"
71 #endif
73 #ifdef USE_X_TOOLKIT
74 #include <X11/Shell.h>
76 #ifndef USE_MOTIF
77 #ifdef HAVE_XAW3D
78 #include <X11/Xaw3d/Paned.h>
79 #include <X11/Xaw3d/Label.h>
80 #else /* !HAVE_XAW3D */
81 #include <X11/Xaw/Paned.h>
82 #include <X11/Xaw/Label.h>
83 #endif /* HAVE_XAW3D */
84 #endif /* USE_MOTIF */
86 #ifdef USG
87 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
88 #include <X11/Xos.h>
89 #define USG
90 #else
91 #include <X11/Xos.h>
92 #endif
94 #include "widget.h"
96 #include "../lwlib/lwlib.h"
98 #ifdef USE_MOTIF
99 #include <Xm/Xm.h>
100 #include <Xm/DialogS.h>
101 #include <Xm/FileSB.h>
102 #endif
104 #if !defined(NO_EDITRES)
105 #define HACK_EDITRES
106 extern void _XEditResCheckMessages ();
107 #endif /* not defined NO_EDITRES */
109 /* Unique id counter for widgets created by the Lucid Widget Library. */
111 extern LWLIB_ID widget_id_tick;
113 #ifdef USE_LUCID
114 /* This is part of a kludge--see lwlib/xlwmenu.c. */
115 extern XFontStruct *xlwmenu_default_font;
116 #endif
118 extern void free_frame_menubar ();
119 extern double atof ();
121 #ifdef USE_MOTIF
123 /* LessTif/Motif version info. */
125 static Lisp_Object Vmotif_version_string;
127 #endif /* USE_MOTIF */
129 #endif /* USE_X_TOOLKIT */
131 #ifdef USE_GTK
133 /* GTK+ version info */
135 static Lisp_Object Vgtk_version_string;
137 #endif /* USE_GTK */
139 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
141 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
142 it, and including `bitmaps/gray' more than once is a problem when
143 config.h defines `static' as an empty replacement string. */
145 int gray_bitmap_width = gray_width;
146 int gray_bitmap_height = gray_height;
147 char *gray_bitmap_bits = gray_bits;
149 /* Non-zero means prompt with the old GTK file selection dialog. */
151 int x_gtk_use_old_file_dialog;
153 /* If non-zero, by default show hidden files in the GTK file chooser. */
155 int x_gtk_show_hidden_files;
157 /* If non-zero, don't show additional help text in the GTK file chooser. */
159 int x_gtk_file_dialog_help_text;
161 /* If non-zero, don't collapse to tool bar when it is detached. */
163 int x_gtk_whole_detached_tool_bar;
165 /* The background and shape of the mouse pointer, and shape when not
166 over text or in the modeline. */
168 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
169 Lisp_Object Vx_hourglass_pointer_shape;
171 /* The shape when over mouse-sensitive text. */
173 Lisp_Object Vx_sensitive_text_pointer_shape;
175 /* If non-nil, the pointer shape to indicate that windows can be
176 dragged horizontally. */
178 Lisp_Object Vx_window_horizontal_drag_shape;
180 /* Color of chars displayed in cursor box. */
182 Lisp_Object Vx_cursor_fore_pixel;
184 /* Nonzero if using X. */
186 static int x_in_use;
188 /* Non nil if no window manager is in use. */
190 Lisp_Object Vx_no_window_manager;
192 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
194 Lisp_Object Vx_pixel_size_width_font_regexp;
196 Lisp_Object Qnone;
197 Lisp_Object Qsuppress_icon;
198 Lisp_Object Qundefined_color;
199 Lisp_Object Qcompound_text, Qcancel_timer;
200 Lisp_Object Qfont_param;
202 /* In dispnew.c */
204 extern Lisp_Object Vwindow_system_version;
206 /* The below are defined in frame.c. */
208 extern Lisp_Object Qtooltip;
210 #if GLYPH_DEBUG
211 int image_cache_refcount, dpyinfo_refcount;
212 #endif
214 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
215 char *x_last_font_name;
216 #endif
219 /* Error if we are not connected to X. */
221 void
222 check_x ()
224 if (! x_in_use)
225 error ("X windows are not in use or not initialized");
228 /* Nonzero if we can use mouse menus.
229 You should not call this unless HAVE_MENUS is defined. */
232 have_menus_p ()
234 return x_in_use;
237 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
238 and checking validity for X. */
240 FRAME_PTR
241 check_x_frame (frame)
242 Lisp_Object frame;
244 FRAME_PTR f;
246 if (NILP (frame))
247 frame = selected_frame;
248 CHECK_LIVE_FRAME (frame);
249 f = XFRAME (frame);
250 if (! FRAME_X_P (f))
251 error ("Non-X frame used");
252 return f;
255 /* Let the user specify an X display with a Lisp object.
256 OBJECT may be nil, a frame or a terminal object.
257 nil stands for the selected frame--or, if that is not an X frame,
258 the first X display on the list. */
260 struct x_display_info *
261 check_x_display_info (object)
262 Lisp_Object object;
264 struct x_display_info *dpyinfo = NULL;
266 if (NILP (object))
268 struct frame *sf = XFRAME (selected_frame);
270 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
271 dpyinfo = FRAME_X_DISPLAY_INFO (sf);
272 else if (x_display_list != 0)
273 dpyinfo = x_display_list;
274 else
275 error ("X windows are not in use or not initialized");
277 else if (TERMINALP (object))
279 struct terminal *t = get_terminal (object, 1);
281 if (t->type != output_x_window)
282 error ("Terminal %d is not an X display", XINT (object));
284 dpyinfo = t->display_info.x;
286 else if (STRINGP (object))
287 dpyinfo = x_display_info_for_name (object);
288 else
290 FRAME_PTR f = check_x_frame (object);
291 dpyinfo = FRAME_X_DISPLAY_INFO (f);
294 return dpyinfo;
298 /* Return the Emacs frame-object corresponding to an X window.
299 It could be the frame's main window or an icon window. */
301 /* This function can be called during GC, so use GC_xxx type test macros. */
303 struct frame *
304 x_window_to_frame (dpyinfo, wdesc)
305 struct x_display_info *dpyinfo;
306 int wdesc;
308 Lisp_Object tail, frame;
309 struct frame *f;
311 if (wdesc == None) return 0;
313 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
315 frame = XCAR (tail);
316 if (!FRAMEP (frame))
317 continue;
318 f = XFRAME (frame);
319 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
320 continue;
321 if (f->output_data.x->hourglass_window == wdesc)
322 return f;
323 #ifdef USE_X_TOOLKIT
324 if ((f->output_data.x->edit_widget
325 && XtWindow (f->output_data.x->edit_widget) == wdesc)
326 /* A tooltip frame? */
327 || (!f->output_data.x->edit_widget
328 && FRAME_X_WINDOW (f) == wdesc)
329 || f->output_data.x->icon_desc == wdesc)
330 return f;
331 #else /* not USE_X_TOOLKIT */
332 #ifdef USE_GTK
333 if (f->output_data.x->edit_widget)
335 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
336 struct x_output *x = f->output_data.x;
337 if (gwdesc != 0 && gwdesc == x->edit_widget)
338 return f;
340 #endif /* USE_GTK */
341 if (FRAME_X_WINDOW (f) == wdesc
342 || f->output_data.x->icon_desc == wdesc)
343 return f;
344 #endif /* not USE_X_TOOLKIT */
346 return 0;
349 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
350 /* Like x_window_to_frame but also compares the window with the widget's
351 windows. */
353 struct frame *
354 x_any_window_to_frame (dpyinfo, wdesc)
355 struct x_display_info *dpyinfo;
356 int wdesc;
358 Lisp_Object tail, frame;
359 struct frame *f, *found;
360 struct x_output *x;
362 if (wdesc == None) return NULL;
364 found = NULL;
365 for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail))
367 frame = XCAR (tail);
368 if (!FRAMEP (frame))
369 continue;
371 f = XFRAME (frame);
372 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
374 /* This frame matches if the window is any of its widgets. */
375 x = f->output_data.x;
376 if (x->hourglass_window == wdesc)
377 found = f;
378 else if (x->widget)
380 #ifdef USE_GTK
381 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
382 if (gwdesc != 0
383 && gtk_widget_get_toplevel (gwdesc) == x->widget)
384 found = f;
385 #else
386 if (wdesc == XtWindow (x->widget)
387 || wdesc == XtWindow (x->column_widget)
388 || wdesc == XtWindow (x->edit_widget))
389 found = f;
390 /* Match if the window is this frame's menubar. */
391 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
392 found = f;
393 #endif
395 else if (FRAME_X_WINDOW (f) == wdesc)
396 /* A tooltip frame. */
397 found = f;
401 return found;
404 /* Likewise, but consider only the menu bar widget. */
406 struct frame *
407 x_menubar_window_to_frame (dpyinfo, event)
408 struct x_display_info *dpyinfo;
409 XEvent *event;
411 Window wdesc = event->xany.window;
412 Lisp_Object tail, frame;
413 struct frame *f;
414 struct x_output *x;
416 if (wdesc == None) return 0;
418 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
420 frame = XCAR (tail);
421 if (!FRAMEP (frame))
422 continue;
423 f = XFRAME (frame);
424 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
425 continue;
426 x = f->output_data.x;
427 #ifdef USE_GTK
428 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
429 return f;
430 #else
431 /* Match if the window is this frame's menubar. */
432 if (x->menubar_widget
433 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
434 return f;
435 #endif
437 return 0;
440 /* Return the frame whose principal (outermost) window is WDESC.
441 If WDESC is some other (smaller) window, we return 0. */
443 struct frame *
444 x_top_window_to_frame (dpyinfo, wdesc)
445 struct x_display_info *dpyinfo;
446 int wdesc;
448 Lisp_Object tail, frame;
449 struct frame *f;
450 struct x_output *x;
452 if (wdesc == None) return 0;
454 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
456 frame = XCAR (tail);
457 if (!FRAMEP (frame))
458 continue;
459 f = XFRAME (frame);
460 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
461 continue;
462 x = f->output_data.x;
464 if (x->widget)
466 /* This frame matches if the window is its topmost widget. */
467 #ifdef USE_GTK
468 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
469 if (gwdesc == x->widget)
470 return f;
471 #else
472 if (wdesc == XtWindow (x->widget))
473 return f;
474 #if 0 /* I don't know why it did this,
475 but it seems logically wrong,
476 and it causes trouble for MapNotify events. */
477 /* Match if the window is this frame's menubar. */
478 if (x->menubar_widget
479 && wdesc == XtWindow (x->menubar_widget))
480 return f;
481 #endif
482 #endif
484 else if (FRAME_X_WINDOW (f) == wdesc)
485 /* Tooltip frame. */
486 return f;
488 return 0;
490 #endif /* USE_X_TOOLKIT || USE_GTK */
494 static void x_default_font_parameter P_ ((struct frame *, Lisp_Object));
496 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
497 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
499 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
500 static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object));
501 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
502 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
503 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
504 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
505 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
506 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
507 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
508 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
509 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
510 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
511 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
512 void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object,
513 Lisp_Object));
514 void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object,
515 Lisp_Object));
516 static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
517 Lisp_Object,
518 Lisp_Object,
519 char *, char *,
520 int));
523 /* Store the screen positions of frame F into XPTR and YPTR.
524 These are the positions of the containing window manager window,
525 not Emacs's own window. */
527 void
528 x_real_positions (f, xptr, yptr)
529 FRAME_PTR f;
530 int *xptr, *yptr;
532 int win_x, win_y, outer_x, outer_y;
533 int real_x = 0, real_y = 0;
534 int had_errors = 0;
535 Window win = f->output_data.x->parent_desc;
536 Atom actual_type;
537 unsigned long actual_size, bytes_remaining;
538 int i, rc, actual_format;
539 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
540 long max_len = 400;
541 Display *dpy = FRAME_X_DISPLAY (f);
542 unsigned char *tmp_data = NULL;
543 Atom target_type = XA_CARDINAL;
545 BLOCK_INPUT;
547 x_catch_errors (dpy);
549 if (win == dpyinfo->root_window)
550 win = FRAME_OUTER_WINDOW (f);
552 /* This loop traverses up the containment tree until we hit the root
553 window. Window managers may intersect many windows between our window
554 and the root window. The window we find just before the root window
555 should be the outer WM window. */
556 for (;;)
558 Window wm_window, rootw;
559 Window *tmp_children;
560 unsigned int tmp_nchildren;
561 int success;
563 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
564 &wm_window, &tmp_children, &tmp_nchildren);
566 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
568 /* Don't free tmp_children if XQueryTree failed. */
569 if (! success)
570 break;
572 XFree ((char *) tmp_children);
574 if (wm_window == rootw || had_errors)
575 break;
577 win = wm_window;
580 if (! had_errors)
582 unsigned int ign;
583 Window child, rootw;
585 /* Get the real coordinates for the WM window upper left corner */
586 XGetGeometry (FRAME_X_DISPLAY (f), win,
587 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
589 /* Translate real coordinates to coordinates relative to our
590 window. For our window, the upper left corner is 0, 0.
591 Since the upper left corner of the WM window is outside
592 our window, win_x and win_y will be negative:
594 ------------------ ---> x
595 | title |
596 | ----------------- v y
597 | | our window
599 XTranslateCoordinates (FRAME_X_DISPLAY (f),
601 /* From-window, to-window. */
602 FRAME_X_DISPLAY_INFO (f)->root_window,
603 FRAME_X_WINDOW (f),
605 /* From-position, to-position. */
606 real_x, real_y, &win_x, &win_y,
608 /* Child of win. */
609 &child);
611 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
613 outer_x = win_x;
614 outer_y = win_y;
616 else
618 XTranslateCoordinates (FRAME_X_DISPLAY (f),
620 /* From-window, to-window. */
621 FRAME_X_DISPLAY_INFO (f)->root_window,
622 FRAME_OUTER_WINDOW (f),
624 /* From-position, to-position. */
625 real_x, real_y, &outer_x, &outer_y,
627 /* Child of win. */
628 &child);
631 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
635 if (dpyinfo->root_window == f->output_data.x->parent_desc)
637 /* Try _NET_FRAME_EXTENTS if our parent is the root window. */
638 rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_frame_extents,
639 0, max_len, False, target_type,
640 &actual_type, &actual_format, &actual_size,
641 &bytes_remaining, &tmp_data);
643 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
644 && actual_size == 4 && actual_format == 32)
646 int ign;
647 Window rootw;
649 XGetGeometry (FRAME_X_DISPLAY (f), win,
650 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
651 long *fe = (long *)tmp_data;
653 outer_x = -fe[0];
654 outer_y = -fe[2];
655 real_x -= fe[0];
656 real_y -= fe[2];
660 if (tmp_data) XFree (tmp_data);
662 x_uncatch_errors ();
664 UNBLOCK_INPUT;
666 if (had_errors) return;
668 f->x_pixels_diff = -win_x;
669 f->y_pixels_diff = -win_y;
671 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
672 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
674 *xptr = real_x;
675 *yptr = real_y;
681 /* Gamma-correct COLOR on frame F. */
683 void
684 gamma_correct (f, color)
685 struct frame *f;
686 XColor *color;
688 if (f->gamma)
690 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
691 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
692 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
697 /* Decide if color named COLOR_NAME is valid for use on frame F. If
698 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
699 allocate the color. Value is zero if COLOR_NAME is invalid, or
700 no color could be allocated. */
703 x_defined_color (f, color_name, color, alloc_p)
704 struct frame *f;
705 char *color_name;
706 XColor *color;
707 int alloc_p;
709 int success_p;
710 Display *dpy = FRAME_X_DISPLAY (f);
711 Colormap cmap = FRAME_X_COLORMAP (f);
713 BLOCK_INPUT;
714 success_p = XParseColor (dpy, cmap, color_name, color);
715 if (success_p && alloc_p)
716 success_p = x_alloc_nearest_color (f, cmap, color);
717 UNBLOCK_INPUT;
719 return success_p;
723 /* Return the pixel color value for color COLOR_NAME on frame F. If F
724 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
725 Signal an error if color can't be allocated. */
728 x_decode_color (f, color_name, mono_color)
729 FRAME_PTR f;
730 Lisp_Object color_name;
731 int mono_color;
733 XColor cdef;
735 CHECK_STRING (color_name);
737 #if 0 /* Don't do this. It's wrong when we're not using the default
738 colormap, it makes freeing difficult, and it's probably not
739 an important optimization. */
740 if (strcmp (SDATA (color_name), "black") == 0)
741 return BLACK_PIX_DEFAULT (f);
742 else if (strcmp (SDATA (color_name), "white") == 0)
743 return WHITE_PIX_DEFAULT (f);
744 #endif
746 /* Return MONO_COLOR for monochrome frames. */
747 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
748 return mono_color;
750 /* x_defined_color is responsible for coping with failures
751 by looking for a near-miss. */
752 if (x_defined_color (f, SDATA (color_name), &cdef, 1))
753 return cdef.pixel;
755 signal_error ("Undefined color", color_name);
760 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
761 the previous value of that parameter, NEW_VALUE is the new value.
762 See also the comment of wait_for_wm in struct x_output. */
764 static void
765 x_set_wait_for_wm (f, new_value, old_value)
766 struct frame *f;
767 Lisp_Object new_value, old_value;
769 f->output_data.x->wait_for_wm = !NILP (new_value);
772 #ifdef USE_GTK
774 /* Set icon from FILE for frame F. By using GTK functions the icon
775 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
778 xg_set_icon (f, file)
779 FRAME_PTR f;
780 Lisp_Object file;
782 int result = 0;
783 Lisp_Object found;
785 found = x_find_image_file (file);
787 if (! NILP (found))
789 GdkPixbuf *pixbuf;
790 GError *err = NULL;
791 char *filename = (char *) SDATA (found);
792 BLOCK_INPUT;
794 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
796 if (pixbuf)
798 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
799 pixbuf);
800 g_object_unref (pixbuf);
802 result = 1;
804 else
805 g_error_free (err);
807 UNBLOCK_INPUT;
810 return result;
814 xg_set_icon_from_xpm_data (f, data)
815 FRAME_PTR f;
816 char **data;
818 int result = 0;
819 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data);
821 if (!pixbuf)
822 return 0;
824 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
825 g_object_unref (pixbuf);
826 return 1;
828 #endif /* USE_GTK */
831 /* Functions called only from `x_set_frame_param'
832 to set individual parameters.
834 If FRAME_X_WINDOW (f) is 0,
835 the frame is being created and its X-window does not exist yet.
836 In that case, just record the parameter's new value
837 in the standard place; do not attempt to change the window. */
839 void
840 x_set_foreground_color (f, arg, oldval)
841 struct frame *f;
842 Lisp_Object arg, oldval;
844 struct x_output *x = f->output_data.x;
845 unsigned long fg, old_fg;
847 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
848 old_fg = FRAME_FOREGROUND_PIXEL (f);
849 FRAME_FOREGROUND_PIXEL (f) = fg;
851 if (FRAME_X_WINDOW (f) != 0)
853 Display *dpy = FRAME_X_DISPLAY (f);
855 BLOCK_INPUT;
856 XSetForeground (dpy, x->normal_gc, fg);
857 XSetBackground (dpy, x->reverse_gc, fg);
859 if (x->cursor_pixel == old_fg)
861 unload_color (f, x->cursor_pixel);
862 x->cursor_pixel = x_copy_color (f, fg);
863 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
866 UNBLOCK_INPUT;
868 update_face_from_frame_parameter (f, Qforeground_color, arg);
870 if (FRAME_VISIBLE_P (f))
871 redraw_frame (f);
874 unload_color (f, old_fg);
877 void
878 x_set_background_color (f, arg, oldval)
879 struct frame *f;
880 Lisp_Object arg, oldval;
882 struct x_output *x = f->output_data.x;
883 unsigned long bg;
885 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
886 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
887 FRAME_BACKGROUND_PIXEL (f) = bg;
889 if (FRAME_X_WINDOW (f) != 0)
891 Display *dpy = FRAME_X_DISPLAY (f);
893 BLOCK_INPUT;
894 XSetBackground (dpy, x->normal_gc, bg);
895 XSetForeground (dpy, x->reverse_gc, bg);
896 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
897 XSetForeground (dpy, x->cursor_gc, bg);
899 #ifdef USE_GTK
900 xg_set_background_color (f, bg);
901 #endif
903 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
904 toolkit scroll bars. */
906 Lisp_Object bar;
907 for (bar = FRAME_SCROLL_BARS (f);
908 !NILP (bar);
909 bar = XSCROLL_BAR (bar)->next)
911 Window window = XSCROLL_BAR (bar)->x_window;
912 XSetWindowBackground (dpy, window, bg);
915 #endif /* USE_TOOLKIT_SCROLL_BARS */
917 UNBLOCK_INPUT;
918 update_face_from_frame_parameter (f, Qbackground_color, arg);
920 if (FRAME_VISIBLE_P (f))
921 redraw_frame (f);
925 static Cursor
926 make_invisible_cursor (f)
927 struct frame *f;
929 Display *dpy = FRAME_X_DISPLAY (f);
930 static char const no_data[] = { 0 };
931 Pixmap pix;
932 XColor col;
933 Cursor c;
935 x_catch_errors (dpy);
936 pix = XCreateBitmapFromData (dpy, FRAME_X_DISPLAY_INFO (f)->root_window,
937 no_data, 1, 1);
938 if (! x_had_errors_p (dpy) && pix != None)
940 col.pixel = 0;
941 col.red = col.green = col.blue = 0;
942 col.flags = DoRed | DoGreen | DoBlue;
943 c = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
944 if (x_had_errors_p (dpy) || c == None)
945 c = 0;
946 XFreePixmap (dpy, pix);
949 x_uncatch_errors ();
951 return c;
954 void
955 x_set_mouse_color (f, arg, oldval)
956 struct frame *f;
957 Lisp_Object arg, oldval;
959 struct x_output *x = f->output_data.x;
960 Display *dpy = FRAME_X_DISPLAY (f);
961 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
962 Cursor hourglass_cursor, horizontal_drag_cursor;
963 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
964 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
966 /* Don't let pointers be invisible. */
967 if (mask_color == pixel)
969 x_free_colors (f, &pixel, 1);
970 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
973 unload_color (f, x->mouse_pixel);
974 x->mouse_pixel = pixel;
976 BLOCK_INPUT;
978 /* It's not okay to crash if the user selects a screwy cursor. */
979 x_catch_errors (dpy);
981 if (!NILP (Vx_pointer_shape))
983 CHECK_NUMBER (Vx_pointer_shape);
984 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
986 else
987 cursor = XCreateFontCursor (dpy, XC_xterm);
988 x_check_errors (dpy, "bad text pointer cursor: %s");
990 if (!NILP (Vx_nontext_pointer_shape))
992 CHECK_NUMBER (Vx_nontext_pointer_shape);
993 nontext_cursor
994 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
996 else
997 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
998 x_check_errors (dpy, "bad nontext pointer cursor: %s");
1000 if (!NILP (Vx_hourglass_pointer_shape))
1002 CHECK_NUMBER (Vx_hourglass_pointer_shape);
1003 hourglass_cursor
1004 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
1006 else
1007 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
1008 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
1010 if (!NILP (Vx_mode_pointer_shape))
1012 CHECK_NUMBER (Vx_mode_pointer_shape);
1013 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
1015 else
1016 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
1017 x_check_errors (dpy, "bad modeline pointer cursor: %s");
1019 if (!NILP (Vx_sensitive_text_pointer_shape))
1021 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1022 hand_cursor
1023 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
1025 else
1026 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
1028 if (!NILP (Vx_window_horizontal_drag_shape))
1030 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1031 horizontal_drag_cursor
1032 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
1034 else
1035 horizontal_drag_cursor
1036 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
1038 /* Check and report errors with the above calls. */
1039 x_check_errors (dpy, "can't set cursor shape: %s");
1040 x_uncatch_errors ();
1043 XColor fore_color, back_color;
1045 fore_color.pixel = x->mouse_pixel;
1046 x_query_color (f, &fore_color);
1047 back_color.pixel = mask_color;
1048 x_query_color (f, &back_color);
1050 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1051 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1052 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1053 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1054 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1055 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1058 if (FRAME_X_WINDOW (f) != 0)
1059 XDefineCursor (dpy, FRAME_X_WINDOW (f),
1060 f->output_data.x->current_cursor = cursor);
1062 if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor == 0)
1063 FRAME_X_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
1065 if (cursor != x->text_cursor
1066 && x->text_cursor != 0)
1067 XFreeCursor (dpy, x->text_cursor);
1068 x->text_cursor = cursor;
1070 if (nontext_cursor != x->nontext_cursor
1071 && x->nontext_cursor != 0)
1072 XFreeCursor (dpy, x->nontext_cursor);
1073 x->nontext_cursor = nontext_cursor;
1075 if (hourglass_cursor != x->hourglass_cursor
1076 && x->hourglass_cursor != 0)
1077 XFreeCursor (dpy, x->hourglass_cursor);
1078 x->hourglass_cursor = hourglass_cursor;
1080 if (mode_cursor != x->modeline_cursor
1081 && x->modeline_cursor != 0)
1082 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1083 x->modeline_cursor = mode_cursor;
1085 if (hand_cursor != x->hand_cursor
1086 && x->hand_cursor != 0)
1087 XFreeCursor (dpy, x->hand_cursor);
1088 x->hand_cursor = hand_cursor;
1090 if (horizontal_drag_cursor != x->horizontal_drag_cursor
1091 && x->horizontal_drag_cursor != 0)
1092 XFreeCursor (dpy, x->horizontal_drag_cursor);
1093 x->horizontal_drag_cursor = horizontal_drag_cursor;
1095 XFlush (dpy);
1096 UNBLOCK_INPUT;
1098 update_face_from_frame_parameter (f, Qmouse_color, arg);
1101 void
1102 x_set_cursor_color (f, arg, oldval)
1103 struct frame *f;
1104 Lisp_Object arg, oldval;
1106 unsigned long fore_pixel, pixel;
1107 int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
1108 struct x_output *x = f->output_data.x;
1110 if (!NILP (Vx_cursor_fore_pixel))
1112 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1113 WHITE_PIX_DEFAULT (f));
1114 fore_pixel_allocated_p = 1;
1116 else
1117 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1119 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1120 pixel_allocated_p = 1;
1122 /* Make sure that the cursor color differs from the background color. */
1123 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1125 if (pixel_allocated_p)
1127 x_free_colors (f, &pixel, 1);
1128 pixel_allocated_p = 0;
1131 pixel = x->mouse_pixel;
1132 if (pixel == fore_pixel)
1134 if (fore_pixel_allocated_p)
1136 x_free_colors (f, &fore_pixel, 1);
1137 fore_pixel_allocated_p = 0;
1139 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1143 unload_color (f, x->cursor_foreground_pixel);
1144 if (!fore_pixel_allocated_p)
1145 fore_pixel = x_copy_color (f, fore_pixel);
1146 x->cursor_foreground_pixel = fore_pixel;
1148 unload_color (f, x->cursor_pixel);
1149 if (!pixel_allocated_p)
1150 pixel = x_copy_color (f, pixel);
1151 x->cursor_pixel = pixel;
1153 if (FRAME_X_WINDOW (f) != 0)
1155 BLOCK_INPUT;
1156 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1157 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1158 UNBLOCK_INPUT;
1160 if (FRAME_VISIBLE_P (f))
1162 x_update_cursor (f, 0);
1163 x_update_cursor (f, 1);
1167 update_face_from_frame_parameter (f, Qcursor_color, arg);
1170 /* Set the border-color of frame F to pixel value PIX.
1171 Note that this does not fully take effect if done before
1172 F has an x-window. */
1174 void
1175 x_set_border_pixel (f, pix)
1176 struct frame *f;
1177 int pix;
1179 unload_color (f, f->output_data.x->border_pixel);
1180 f->output_data.x->border_pixel = pix;
1182 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1184 BLOCK_INPUT;
1185 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1186 (unsigned long)pix);
1187 UNBLOCK_INPUT;
1189 if (FRAME_VISIBLE_P (f))
1190 redraw_frame (f);
1194 /* Set the border-color of frame F to value described by ARG.
1195 ARG can be a string naming a color.
1196 The border-color is used for the border that is drawn by the X server.
1197 Note that this does not fully take effect if done before
1198 F has an x-window; it must be redone when the window is created.
1200 Note: this is done in two routines because of the way X10 works.
1202 Note: under X11, this is normally the province of the window manager,
1203 and so emacs' border colors may be overridden. */
1205 void
1206 x_set_border_color (f, arg, oldval)
1207 struct frame *f;
1208 Lisp_Object arg, oldval;
1210 int pix;
1212 CHECK_STRING (arg);
1213 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1214 x_set_border_pixel (f, pix);
1215 update_face_from_frame_parameter (f, Qborder_color, arg);
1219 void
1220 x_set_cursor_type (f, arg, oldval)
1221 FRAME_PTR f;
1222 Lisp_Object arg, oldval;
1224 set_frame_cursor_types (f, arg);
1226 /* Make sure the cursor gets redrawn. */
1227 cursor_type_changed = 1;
1230 void
1231 x_set_icon_type (f, arg, oldval)
1232 struct frame *f;
1233 Lisp_Object arg, oldval;
1235 int result;
1237 if (STRINGP (arg))
1239 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1240 return;
1242 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1243 return;
1245 BLOCK_INPUT;
1246 if (NILP (arg))
1247 result = x_text_icon (f,
1248 (char *) SDATA ((!NILP (f->icon_name)
1249 ? f->icon_name
1250 : f->name)));
1251 else
1252 result = x_bitmap_icon (f, arg);
1254 if (result)
1256 UNBLOCK_INPUT;
1257 error ("No icon window available");
1260 XFlush (FRAME_X_DISPLAY (f));
1261 UNBLOCK_INPUT;
1264 void
1265 x_set_icon_name (f, arg, oldval)
1266 struct frame *f;
1267 Lisp_Object arg, oldval;
1269 int result;
1271 if (STRINGP (arg))
1273 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1274 return;
1276 else if (!NILP (arg) || NILP (oldval))
1277 return;
1279 f->icon_name = arg;
1281 if (f->output_data.x->icon_bitmap != 0)
1282 return;
1284 BLOCK_INPUT;
1286 result = x_text_icon (f,
1287 (char *) SDATA ((!NILP (f->icon_name)
1288 ? f->icon_name
1289 : !NILP (f->title)
1290 ? f->title
1291 : f->name)));
1293 if (result)
1295 UNBLOCK_INPUT;
1296 error ("No icon window available");
1299 XFlush (FRAME_X_DISPLAY (f));
1300 UNBLOCK_INPUT;
1304 void
1305 x_set_menu_bar_lines (f, value, oldval)
1306 struct frame *f;
1307 Lisp_Object value, oldval;
1309 int nlines;
1310 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1311 int olines = FRAME_MENU_BAR_LINES (f);
1312 #endif
1314 /* Right now, menu bars don't work properly in minibuf-only frames;
1315 most of the commands try to apply themselves to the minibuffer
1316 frame itself, and get an error because you can't switch buffers
1317 in or split the minibuffer window. */
1318 if (FRAME_MINIBUF_ONLY_P (f))
1319 return;
1321 if (INTEGERP (value))
1322 nlines = XINT (value);
1323 else
1324 nlines = 0;
1326 /* Make sure we redisplay all windows in this frame. */
1327 windows_or_buffers_changed++;
1329 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1330 FRAME_MENU_BAR_LINES (f) = 0;
1331 if (nlines)
1333 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1334 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1335 /* Make sure next redisplay shows the menu bar. */
1336 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1338 else
1340 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1341 free_frame_menubar (f);
1342 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1343 if (FRAME_X_P (f))
1344 f->output_data.x->menubar_widget = 0;
1346 #else /* not USE_X_TOOLKIT && not USE_GTK */
1347 FRAME_MENU_BAR_LINES (f) = nlines;
1348 change_window_heights (f->root_window, nlines - olines);
1350 /* If the menu bar height gets changed, the internal border below
1351 the top margin has to be cleared. Also, if the menu bar gets
1352 larger, the area for the added lines has to be cleared except for
1353 the first menu bar line that is to be drawn later. */
1354 if (nlines != olines)
1356 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1357 int width = FRAME_PIXEL_WIDTH (f);
1358 int y;
1360 /* height can be zero here. */
1361 if (height > 0 && width > 0)
1363 y = FRAME_TOP_MARGIN_HEIGHT (f);
1365 BLOCK_INPUT;
1366 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1367 0, y, width, height, False);
1368 UNBLOCK_INPUT;
1371 if (nlines > 1 && nlines > olines)
1373 y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
1374 height = nlines * FRAME_LINE_HEIGHT (f) - y;
1376 BLOCK_INPUT;
1377 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1378 0, y, width, height, False);
1379 UNBLOCK_INPUT;
1382 if (nlines == 0 && WINDOWP (f->menu_bar_window))
1383 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
1385 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1386 adjust_glyphs (f);
1390 /* Set the number of lines used for the tool bar of frame F to VALUE.
1391 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1392 is the old number of tool bar lines. This function changes the
1393 height of all windows on frame F to match the new tool bar height.
1394 The frame's height doesn't change. */
1396 void
1397 x_set_tool_bar_lines (f, value, oldval)
1398 struct frame *f;
1399 Lisp_Object value, oldval;
1401 int delta, nlines, root_height;
1402 Lisp_Object root_window;
1404 /* Treat tool bars like menu bars. */
1405 if (FRAME_MINIBUF_ONLY_P (f))
1406 return;
1408 /* Use VALUE only if an integer >= 0. */
1409 if (INTEGERP (value) && XINT (value) >= 0)
1410 nlines = XFASTINT (value);
1411 else
1412 nlines = 0;
1414 #ifdef USE_GTK
1415 FRAME_TOOL_BAR_LINES (f) = 0;
1416 if (nlines)
1418 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1419 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1420 /* Make sure next redisplay shows the tool bar. */
1421 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1422 update_frame_tool_bar (f);
1424 else
1426 if (FRAME_EXTERNAL_TOOL_BAR (f))
1427 free_frame_tool_bar (f);
1428 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1431 return;
1432 #endif
1434 /* Make sure we redisplay all windows in this frame. */
1435 ++windows_or_buffers_changed;
1437 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1439 /* Don't resize the tool-bar to more than we have room for. */
1440 root_window = FRAME_ROOT_WINDOW (f);
1441 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1442 if (root_height - delta < 1)
1444 delta = root_height - 1;
1445 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1448 FRAME_TOOL_BAR_LINES (f) = nlines;
1449 change_window_heights (root_window, delta);
1450 adjust_glyphs (f);
1452 /* We also have to make sure that the internal border at the top of
1453 the frame, below the menu bar or tool bar, is redrawn when the
1454 tool bar disappears. This is so because the internal border is
1455 below the tool bar if one is displayed, but is below the menu bar
1456 if there isn't a tool bar. The tool bar draws into the area
1457 below the menu bar. */
1458 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1460 clear_frame (f);
1461 clear_current_matrices (f);
1464 /* If the tool bar gets smaller, the internal border below it
1465 has to be cleared. It was formerly part of the display
1466 of the larger tool bar, and updating windows won't clear it. */
1467 if (delta < 0)
1469 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1470 int width = FRAME_PIXEL_WIDTH (f);
1471 int y = (FRAME_MENU_BAR_LINES (f) + nlines) * FRAME_LINE_HEIGHT (f);
1473 /* height can be zero here. */
1474 if (height > 0 && width > 0)
1476 BLOCK_INPUT;
1477 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1478 0, y, width, height, False);
1479 UNBLOCK_INPUT;
1482 if (WINDOWP (f->tool_bar_window))
1483 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1488 /* Set the foreground color for scroll bars on frame F to VALUE.
1489 VALUE should be a string, a color name. If it isn't a string or
1490 isn't a valid color name, do nothing. OLDVAL is the old value of
1491 the frame parameter. */
1493 void
1494 x_set_scroll_bar_foreground (f, value, oldval)
1495 struct frame *f;
1496 Lisp_Object value, oldval;
1498 unsigned long pixel;
1500 if (STRINGP (value))
1501 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1502 else
1503 pixel = -1;
1505 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1506 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1508 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1509 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1511 /* Remove all scroll bars because they have wrong colors. */
1512 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1513 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1514 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1515 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1517 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1518 redraw_frame (f);
1523 /* Set the background color for scroll bars on frame F to VALUE VALUE
1524 should be a string, a color name. If it isn't a string or isn't a
1525 valid color name, do nothing. OLDVAL is the old value of the frame
1526 parameter. */
1528 void
1529 x_set_scroll_bar_background (f, value, oldval)
1530 struct frame *f;
1531 Lisp_Object value, oldval;
1533 unsigned long pixel;
1535 if (STRINGP (value))
1536 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1537 else
1538 pixel = -1;
1540 if (f->output_data.x->scroll_bar_background_pixel != -1)
1541 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1543 #ifdef USE_TOOLKIT_SCROLL_BARS
1544 /* Scrollbar shadow colors. */
1545 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1547 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1548 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1550 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1552 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1553 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1555 #endif /* USE_TOOLKIT_SCROLL_BARS */
1557 f->output_data.x->scroll_bar_background_pixel = pixel;
1558 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1560 /* Remove all scroll bars because they have wrong colors. */
1561 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1562 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1563 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1564 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1566 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1567 redraw_frame (f);
1572 /* Encode Lisp string STRING as a text in a format appropriate for
1573 XICCC (X Inter Client Communication Conventions).
1575 This can call Lisp code, so callers must GCPRO.
1577 If STRING contains only ASCII characters, do no conversion and
1578 return the string data of STRING. Otherwise, encode the text by
1579 CODING_SYSTEM, and return a newly allocated memory area which
1580 should be freed by `xfree' by a caller.
1582 SELECTIONP non-zero means the string is being encoded for an X
1583 selection, so it is safe to run pre-write conversions (which
1584 may run Lisp code).
1586 Store the byte length of resulting text in *TEXT_BYTES.
1588 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1589 which means that the `encoding' of the result can be `STRING'.
1590 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1591 the result should be `COMPOUND_TEXT'. */
1593 static unsigned char *
1594 x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep)
1595 Lisp_Object string, coding_system;
1596 int *text_bytes, *stringp;
1597 int selectionp;
1598 int *freep;
1600 int result = string_xstring_p (string);
1601 struct coding_system coding;
1603 if (result == 0)
1605 /* No multibyte character in OBJ. We need not encode it. */
1606 *text_bytes = SBYTES (string);
1607 *stringp = 1;
1608 *freep = 0;
1609 return SDATA (string);
1612 setup_coding_system (coding_system, &coding);
1613 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1614 /* We suppress producing escape sequences for composition. */
1615 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1616 coding.dst_bytes = SCHARS (string) * 2;
1617 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
1618 encode_coding_object (&coding, string, 0, 0,
1619 SCHARS (string), SBYTES (string), Qnil);
1620 *text_bytes = coding.produced;
1621 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1622 *freep = 1;
1623 return coding.destination;
1627 /* Set the WM name to NAME for frame F. Also set the icon name.
1628 If the frame already has an icon name, use that, otherwise set the
1629 icon name to NAME. */
1631 static void
1632 x_set_name_internal (f, name)
1633 FRAME_PTR f;
1634 Lisp_Object name;
1636 if (FRAME_X_WINDOW (f))
1638 BLOCK_INPUT;
1640 XTextProperty text, icon;
1641 int bytes, stringp;
1642 int do_free_icon_value = 0, do_free_text_value = 0;
1643 Lisp_Object coding_system;
1644 #ifdef USE_GTK
1645 Lisp_Object encoded_name;
1646 struct gcpro gcpro1;
1648 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1649 we use it before x_encode_text that may return string data. */
1650 GCPRO1 (name);
1651 encoded_name = ENCODE_UTF_8 (name);
1652 UNGCPRO;
1653 #endif
1655 coding_system = Qcompound_text;
1656 /* Note: Encoding strategy
1658 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1659 text.encoding. But, there are non-internationalized window
1660 managers which don't support that encoding. So, if NAME
1661 contains only ASCII and 8859-1 characters, encode it by
1662 iso-latin-1, and use "STRING" in text.encoding hoping that
1663 such window managers at least analyze this format correctly,
1664 i.e. treat 8-bit bytes as 8859-1 characters.
1666 We may also be able to use "UTF8_STRING" in text.encoding
1667 in the future which can encode all Unicode characters.
1668 But, for the moment, there's no way to know that the
1669 current window manager supports it or not. */
1670 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1671 &do_free_text_value);
1672 text.encoding = (stringp ? XA_STRING
1673 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1674 text.format = 8;
1675 text.nitems = bytes;
1677 if (!STRINGP (f->icon_name))
1679 icon = text;
1681 else
1683 /* See the above comment "Note: Encoding strategy". */
1684 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1685 &bytes, &stringp, &do_free_icon_value);
1686 icon.encoding = (stringp ? XA_STRING
1687 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1688 icon.format = 8;
1689 icon.nitems = bytes;
1692 #ifdef USE_GTK
1693 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1694 (char *) SDATA (encoded_name));
1695 #else /* not USE_GTK */
1696 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1697 #endif /* not USE_GTK */
1699 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1701 if (do_free_icon_value)
1702 xfree (icon.value);
1703 if (do_free_text_value)
1704 xfree (text.value);
1706 UNBLOCK_INPUT;
1710 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1711 x_id_name.
1713 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1714 name; if NAME is a string, set F's name to NAME and set
1715 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1717 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1718 suggesting a new name, which lisp code should override; if
1719 F->explicit_name is set, ignore the new name; otherwise, set it. */
1721 void
1722 x_set_name (f, name, explicit)
1723 struct frame *f;
1724 Lisp_Object name;
1725 int explicit;
1727 /* Make sure that requests from lisp code override requests from
1728 Emacs redisplay code. */
1729 if (explicit)
1731 /* If we're switching from explicit to implicit, we had better
1732 update the mode lines and thereby update the title. */
1733 if (f->explicit_name && NILP (name))
1734 update_mode_lines = 1;
1736 f->explicit_name = ! NILP (name);
1738 else if (f->explicit_name)
1739 return;
1741 /* If NAME is nil, set the name to the x_id_name. */
1742 if (NILP (name))
1744 /* Check for no change needed in this very common case
1745 before we do any consing. */
1746 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1747 SDATA (f->name)))
1748 return;
1749 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1751 else
1752 CHECK_STRING (name);
1754 /* Don't change the name if it's already NAME. */
1755 if (! NILP (Fstring_equal (name, f->name)))
1756 return;
1758 f->name = name;
1760 /* For setting the frame title, the title parameter should override
1761 the name parameter. */
1762 if (! NILP (f->title))
1763 name = f->title;
1765 x_set_name_internal (f, name);
1768 /* This function should be called when the user's lisp code has
1769 specified a name for the frame; the name will override any set by the
1770 redisplay code. */
1771 void
1772 x_explicitly_set_name (f, arg, oldval)
1773 FRAME_PTR f;
1774 Lisp_Object arg, oldval;
1776 x_set_name (f, arg, 1);
1779 /* This function should be called by Emacs redisplay code to set the
1780 name; names set this way will never override names set by the user's
1781 lisp code. */
1782 void
1783 x_implicitly_set_name (f, arg, oldval)
1784 FRAME_PTR f;
1785 Lisp_Object arg, oldval;
1787 x_set_name (f, arg, 0);
1790 /* Change the title of frame F to NAME.
1791 If NAME is nil, use the frame name as the title. */
1793 void
1794 x_set_title (f, name, old_name)
1795 struct frame *f;
1796 Lisp_Object name, old_name;
1798 /* Don't change the title if it's already NAME. */
1799 if (EQ (name, f->title))
1800 return;
1802 update_mode_lines = 1;
1804 f->title = name;
1806 if (NILP (name))
1807 name = f->name;
1808 else
1809 CHECK_STRING (name);
1811 x_set_name_internal (f, name);
1814 void
1815 x_set_scroll_bar_default_width (f)
1816 struct frame *f;
1818 int wid = FRAME_COLUMN_WIDTH (f);
1820 #ifdef USE_TOOLKIT_SCROLL_BARS
1821 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1822 int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1823 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1824 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1825 #else
1826 /* Make the actual width at least 14 pixels and a multiple of a
1827 character width. */
1828 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1830 /* Use all of that space (aside from required margins) for the
1831 scroll bar. */
1832 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1833 #endif
1837 /* Record in frame F the specified or default value according to ALIST
1838 of the parameter named PROP (a Lisp symbol). If no value is
1839 specified for PROP, look for an X default for XPROP on the frame
1840 named NAME. If that is not found either, use the value DEFLT. */
1842 static Lisp_Object
1843 x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
1844 foreground_p)
1845 struct frame *f;
1846 Lisp_Object alist;
1847 Lisp_Object prop;
1848 char *xprop;
1849 char *xclass;
1850 int foreground_p;
1852 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1853 Lisp_Object tem;
1855 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1856 if (EQ (tem, Qunbound))
1858 #ifdef USE_TOOLKIT_SCROLL_BARS
1860 /* See if an X resource for the scroll bar color has been
1861 specified. */
1862 tem = display_x_get_resource (dpyinfo,
1863 build_string (foreground_p
1864 ? "foreground"
1865 : "background"),
1866 empty_unibyte_string,
1867 build_string ("verticalScrollBar"),
1868 empty_unibyte_string);
1869 if (!STRINGP (tem))
1871 /* If nothing has been specified, scroll bars will use a
1872 toolkit-dependent default. Because these defaults are
1873 difficult to get at without actually creating a scroll
1874 bar, use nil to indicate that no color has been
1875 specified. */
1876 tem = Qnil;
1879 #else /* not USE_TOOLKIT_SCROLL_BARS */
1881 tem = Qnil;
1883 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1886 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1887 return tem;
1893 #ifdef USE_X_TOOLKIT
1895 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1896 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1897 already be present because of the toolkit (Motif adds some of them,
1898 for example, but Xt doesn't). */
1900 static void
1901 hack_wm_protocols (f, widget)
1902 FRAME_PTR f;
1903 Widget widget;
1905 Display *dpy = XtDisplay (widget);
1906 Window w = XtWindow (widget);
1907 int need_delete = 1;
1908 int need_focus = 1;
1909 int need_save = 1;
1911 BLOCK_INPUT;
1913 Atom type;
1914 unsigned char *catoms;
1915 int format = 0;
1916 unsigned long nitems = 0;
1917 unsigned long bytes_after;
1919 if ((XGetWindowProperty (dpy, w,
1920 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1921 (long)0, (long)100, False, XA_ATOM,
1922 &type, &format, &nitems, &bytes_after,
1923 &catoms)
1924 == Success)
1925 && format == 32 && type == XA_ATOM)
1927 Atom *atoms = (Atom *) catoms;
1928 while (nitems > 0)
1930 nitems--;
1931 if (atoms[nitems]
1932 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1933 need_delete = 0;
1934 else if (atoms[nitems]
1935 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1936 need_focus = 0;
1937 else if (atoms[nitems]
1938 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1939 need_save = 0;
1942 if (catoms)
1943 XFree (catoms);
1946 Atom props [10];
1947 int count = 0;
1948 if (need_delete)
1949 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1950 if (need_focus)
1951 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1952 if (need_save)
1953 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1954 if (count)
1955 XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1956 XA_ATOM, 32, PropModeAppend,
1957 (unsigned char *) props, count);
1959 UNBLOCK_INPUT;
1961 #endif
1965 /* Support routines for XIC (X Input Context). */
1967 #ifdef HAVE_X_I18N
1969 static XFontSet xic_create_xfontset P_ ((struct frame *));
1970 static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *));
1973 /* Supported XIM styles, ordered by preference. */
1975 static XIMStyle supported_xim_styles[] =
1977 XIMPreeditPosition | XIMStatusArea,
1978 XIMPreeditPosition | XIMStatusNothing,
1979 XIMPreeditPosition | XIMStatusNone,
1980 XIMPreeditNothing | XIMStatusArea,
1981 XIMPreeditNothing | XIMStatusNothing,
1982 XIMPreeditNothing | XIMStatusNone,
1983 XIMPreeditNone | XIMStatusArea,
1984 XIMPreeditNone | XIMStatusNothing,
1985 XIMPreeditNone | XIMStatusNone,
1990 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1992 char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1994 /* Create an Xt fontset spec from the name of a base font.
1995 If `motif' is True use the Motif syntax. */
1996 char *
1997 xic_create_fontsetname (base_fontname, motif)
1998 char *base_fontname;
1999 Bool motif;
2001 const char *sep = motif ? ";" : ",";
2002 char *fontsetname;
2004 /* Make a fontset name from the base font name. */
2005 if (xic_defaut_fontset == base_fontname)
2006 { /* There is no base font name, use the default. */
2007 int len = strlen (base_fontname) + 2;
2008 fontsetname = xmalloc (len);
2009 bzero (fontsetname, len);
2010 strcpy (fontsetname, base_fontname);
2012 else
2014 /* Make a fontset name from the base font name.
2015 The font set will be made of the following elements:
2016 - the base font.
2017 - the base font where the charset spec is replaced by -*-*.
2018 - the same but with the family also replaced with -*-*-. */
2019 char *p = base_fontname;
2020 int i;
2022 for (i = 0; *p; p++)
2023 if (*p == '-') i++;
2024 if (i != 14)
2025 { /* As the font name doesn't conform to XLFD, we can't
2026 modify it to generalize it to allcs and allfamilies.
2027 Use the specified font plus the default. */
2028 int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3;
2029 fontsetname = xmalloc (len);
2030 bzero (fontsetname, len);
2031 strcpy (fontsetname, base_fontname);
2032 strcat (fontsetname, sep);
2033 strcat (fontsetname, xic_defaut_fontset);
2035 else
2037 int len;
2038 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
2039 char *font_allcs = NULL;
2040 char *font_allfamilies = NULL;
2041 char *font_all = NULL;
2042 char *allcs = "*-*-*-*-*-*-*";
2043 char *allfamilies = "-*-*-";
2044 char *all = "*-*-*-*-";
2045 char *base;
2047 for (i = 0, p = base_fontname; i < 8; p++)
2049 if (*p == '-')
2051 i++;
2052 if (i == 3)
2053 p1 = p + 1;
2054 else if (i == 7)
2055 p2 = p + 1;
2056 else if (i == 6)
2057 p3 = p + 1;
2060 /* If base_fontname specifies ADSTYLE, make it a
2061 wildcard. */
2062 if (*p3 != '*')
2064 int diff = (p2 - p3) - 2;
2066 base = alloca (strlen (base_fontname) + 1);
2067 bcopy (base_fontname, base, p3 - base_fontname);
2068 base[p3 - base_fontname] = '*';
2069 base[(p3 - base_fontname) + 1] = '-';
2070 strcpy (base + (p3 - base_fontname) + 2, p2);
2071 p = base + (p - base_fontname) - diff;
2072 p1 = base + (p1 - base_fontname);
2073 p2 = base + (p2 - base_fontname) - diff;
2074 base_fontname = base;
2077 /* Build the font spec that matches all charsets. */
2078 len = p - base_fontname + strlen (allcs) + 1;
2079 font_allcs = (char *) alloca (len);
2080 bzero (font_allcs, len);
2081 bcopy (base_fontname, font_allcs, p - base_fontname);
2082 strcat (font_allcs, allcs);
2084 /* Build the font spec that matches all families and
2085 add-styles. */
2086 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
2087 font_allfamilies = (char *) alloca (len);
2088 bzero (font_allfamilies, len);
2089 strcpy (font_allfamilies, allfamilies);
2090 bcopy (p1, font_allfamilies + strlen (allfamilies), p - p1);
2091 strcat (font_allfamilies, allcs);
2093 /* Build the font spec that matches all. */
2094 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
2095 font_all = (char *) alloca (len);
2096 bzero (font_all, len);
2097 strcpy (font_all, allfamilies);
2098 strcat (font_all, all);
2099 bcopy (p2, font_all + strlen (all) + strlen (allfamilies), p - p2);
2100 strcat (font_all, allcs);
2102 /* Build the actual font set name. */
2103 len = strlen (base_fontname) + strlen (font_allcs)
2104 + strlen (font_allfamilies) + strlen (font_all) + 5;
2105 fontsetname = xmalloc (len);
2106 bzero (fontsetname, len);
2107 strcpy (fontsetname, base_fontname);
2108 strcat (fontsetname, sep);
2109 strcat (fontsetname, font_allcs);
2110 strcat (fontsetname, sep);
2111 strcat (fontsetname, font_allfamilies);
2112 strcat (fontsetname, sep);
2113 strcat (fontsetname, font_all);
2116 if (motif)
2117 strcat (fontsetname, ":");
2118 return fontsetname;
2121 #ifdef DEBUG_XIC_FONTSET
2122 static void
2123 print_fontset_result (xfs, name, missing_list, missing_count)
2124 XFontSet xfs;
2125 char *name;
2126 char **missing_list;
2127 int missing_count;
2129 if (xfs)
2130 fprintf (stderr, "XIC Fontset created: %s\n", name);
2131 else
2133 fprintf (stderr, "XIC Fontset failed: %s\n", name);
2134 while (missing_count-- > 0)
2136 fprintf (stderr, " missing: %s\n", *missing_list);
2137 missing_list++;
2142 #endif
2144 static XFontSet
2145 xic_create_xfontset (f)
2146 struct frame *f;
2148 XFontSet xfs = NULL;
2149 struct font *font = FRAME_FONT (f);
2150 int pixel_size = font->pixel_size;
2151 Lisp_Object rest, frame;
2153 /* See if there is another frame already using same fontset. */
2154 FOR_EACH_FRAME (rest, frame)
2156 struct frame *cf = XFRAME (frame);
2158 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2159 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2160 && FRAME_FONT (f)
2161 && FRAME_FONT (f)->pixel_size == pixel_size)
2163 xfs = FRAME_XIC_FONTSET (cf);
2164 break;
2168 if (! xfs)
2170 char buf[256];
2171 char **missing_list;
2172 int missing_count;
2173 char *def_string;
2174 char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
2176 sprintf (buf, xlfd_format, pixel_size);
2177 missing_list = NULL;
2178 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2179 &missing_list, &missing_count, &def_string);
2180 #ifdef DEBUG_XIC_FONTSET
2181 print_fontset_result (xfs, buf, missing_list, missing_count);
2182 #endif
2183 if (missing_list)
2184 XFreeStringList (missing_list);
2185 if (! xfs)
2187 /* List of pixel sizes most likely available. Find one that
2188 is closest to pixel_size. */
2189 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2190 int *smaller, *larger;
2192 for (smaller = sizes; smaller[1]; smaller++)
2193 if (smaller[1] >= pixel_size)
2194 break;
2195 larger = smaller + 1;
2196 if (*larger == pixel_size)
2197 larger++;
2198 while (*smaller || *larger)
2200 int this_size;
2202 if (! *larger)
2203 this_size = *smaller--;
2204 else if (! *smaller)
2205 this_size = *larger++;
2206 else if (pixel_size - *smaller < *larger - pixel_size)
2207 this_size = *smaller--;
2208 else
2209 this_size = *larger++;
2210 sprintf (buf, xlfd_format, this_size);
2211 missing_list = NULL;
2212 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2213 &missing_list, &missing_count, &def_string);
2214 #ifdef DEBUG_XIC_FONTSET
2215 print_fontset_result (xfs, buf, missing_list, missing_count);
2216 #endif
2217 if (missing_list)
2218 XFreeStringList (missing_list);
2219 if (xfs)
2220 break;
2223 if (! xfs)
2225 char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
2227 missing_list = NULL;
2228 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
2229 &missing_list, &missing_count, &def_string);
2230 #ifdef DEBUG_XIC_FONTSET
2231 print_fontset_result (xfs, last_resort, missing_list, missing_count);
2232 #endif
2233 if (missing_list)
2234 XFreeStringList (missing_list);
2239 return xfs;
2242 /* Free the X fontset of frame F if it is the last frame using it. */
2244 void
2245 xic_free_xfontset (f)
2246 struct frame *f;
2248 Lisp_Object rest, frame;
2249 int shared_p = 0;
2251 if (!FRAME_XIC_FONTSET (f))
2252 return;
2254 /* See if there is another frame sharing the same fontset. */
2255 FOR_EACH_FRAME (rest, frame)
2257 struct frame *cf = XFRAME (frame);
2258 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2259 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2260 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
2262 shared_p = 1;
2263 break;
2267 if (!shared_p)
2268 /* The fontset is not used anymore. It is safe to free it. */
2269 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2271 if (FRAME_XIC_BASE_FONTNAME (f))
2272 xfree (FRAME_XIC_BASE_FONTNAME (f));
2273 FRAME_XIC_BASE_FONTNAME (f) = NULL;
2274 FRAME_XIC_FONTSET (f) = NULL;
2278 /* Value is the best input style, given user preferences USER (already
2279 checked to be supported by Emacs), and styles supported by the
2280 input method XIM. */
2282 static XIMStyle
2283 best_xim_style (user, xim)
2284 XIMStyles *user;
2285 XIMStyles *xim;
2287 int i, j;
2289 for (i = 0; i < user->count_styles; ++i)
2290 for (j = 0; j < xim->count_styles; ++j)
2291 if (user->supported_styles[i] == xim->supported_styles[j])
2292 return user->supported_styles[i];
2294 /* Return the default style. */
2295 return XIMPreeditNothing | XIMStatusNothing;
2298 /* Create XIC for frame F. */
2300 static XIMStyle xic_style;
2302 void
2303 create_frame_xic (f)
2304 struct frame *f;
2306 XIM xim;
2307 XIC xic = NULL;
2308 XFontSet xfs = NULL;
2310 if (FRAME_XIC (f))
2311 return;
2313 /* Create X fontset. */
2314 xfs = xic_create_xfontset (f);
2315 xim = FRAME_X_XIM (f);
2316 if (xim)
2318 XRectangle s_area;
2319 XPoint spot;
2320 XVaNestedList preedit_attr;
2321 XVaNestedList status_attr;
2323 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2324 spot.x = 0; spot.y = 1;
2326 /* Determine XIC style. */
2327 if (xic_style == 0)
2329 XIMStyles supported_list;
2330 supported_list.count_styles = (sizeof supported_xim_styles
2331 / sizeof supported_xim_styles[0]);
2332 supported_list.supported_styles = supported_xim_styles;
2333 xic_style = best_xim_style (&supported_list,
2334 FRAME_X_XIM_STYLES (f));
2337 preedit_attr = XVaCreateNestedList (0,
2338 XNFontSet, xfs,
2339 XNForeground,
2340 FRAME_FOREGROUND_PIXEL (f),
2341 XNBackground,
2342 FRAME_BACKGROUND_PIXEL (f),
2343 (xic_style & XIMPreeditPosition
2344 ? XNSpotLocation
2345 : NULL),
2346 &spot,
2347 NULL);
2348 status_attr = XVaCreateNestedList (0,
2349 XNArea,
2350 &s_area,
2351 XNFontSet,
2352 xfs,
2353 XNForeground,
2354 FRAME_FOREGROUND_PIXEL (f),
2355 XNBackground,
2356 FRAME_BACKGROUND_PIXEL (f),
2357 NULL);
2359 xic = XCreateIC (xim,
2360 XNInputStyle, xic_style,
2361 XNClientWindow, FRAME_X_WINDOW (f),
2362 XNFocusWindow, FRAME_X_WINDOW (f),
2363 XNStatusAttributes, status_attr,
2364 XNPreeditAttributes, preedit_attr,
2365 NULL);
2366 XFree (preedit_attr);
2367 XFree (status_attr);
2370 FRAME_XIC (f) = xic;
2371 FRAME_XIC_STYLE (f) = xic_style;
2372 FRAME_XIC_FONTSET (f) = xfs;
2376 /* Destroy XIC and free XIC fontset of frame F, if any. */
2378 void
2379 free_frame_xic (f)
2380 struct frame *f;
2382 if (FRAME_XIC (f) == NULL)
2383 return;
2385 XDestroyIC (FRAME_XIC (f));
2386 xic_free_xfontset (f);
2388 FRAME_XIC (f) = NULL;
2392 /* Place preedit area for XIC of window W's frame to specified
2393 pixel position X/Y. X and Y are relative to window W. */
2395 void
2396 xic_set_preeditarea (w, x, y)
2397 struct window *w;
2398 int x, y;
2400 struct frame *f = XFRAME (w->frame);
2401 XVaNestedList attr;
2402 XPoint spot;
2404 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2405 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2406 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2407 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2408 XFree (attr);
2412 /* Place status area for XIC in bottom right corner of frame F.. */
2414 void
2415 xic_set_statusarea (f)
2416 struct frame *f;
2418 XIC xic = FRAME_XIC (f);
2419 XVaNestedList attr;
2420 XRectangle area;
2421 XRectangle *needed;
2423 /* Negotiate geometry of status area. If input method has existing
2424 status area, use its current size. */
2425 area.x = area.y = area.width = area.height = 0;
2426 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2427 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2428 XFree (attr);
2430 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2431 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2432 XFree (attr);
2434 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2436 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2437 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2438 XFree (attr);
2441 area.width = needed->width;
2442 area.height = needed->height;
2443 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2444 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2445 - FRAME_MENUBAR_HEIGHT (f)
2446 - FRAME_TOOLBAR_HEIGHT (f)
2447 - FRAME_INTERNAL_BORDER_WIDTH (f));
2448 XFree (needed);
2450 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2451 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2452 XFree (attr);
2456 /* Set X fontset for XIC of frame F, using base font name
2457 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2459 void
2460 xic_set_xfontset (f, base_fontname)
2461 struct frame *f;
2462 char *base_fontname;
2464 XVaNestedList attr;
2465 XFontSet xfs;
2467 xic_free_xfontset (f);
2469 xfs = xic_create_xfontset (f);
2471 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2472 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2473 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2474 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2475 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2476 XFree (attr);
2478 FRAME_XIC_FONTSET (f) = xfs;
2481 #endif /* HAVE_X_I18N */
2485 #ifdef USE_X_TOOLKIT
2487 /* Create and set up the X widget for frame F. */
2489 static void
2490 x_window (f, window_prompting, minibuffer_only)
2491 struct frame *f;
2492 long window_prompting;
2493 int minibuffer_only;
2495 XClassHint class_hints;
2496 XSetWindowAttributes attributes;
2497 unsigned long attribute_mask;
2498 Widget shell_widget;
2499 Widget pane_widget;
2500 Widget frame_widget;
2501 Arg al [25];
2502 int ac;
2504 BLOCK_INPUT;
2506 /* Use the resource name as the top-level widget name
2507 for looking up resources. Make a non-Lisp copy
2508 for the window manager, so GC relocation won't bother it.
2510 Elsewhere we specify the window name for the window manager. */
2513 char *str = (char *) SDATA (Vx_resource_name);
2514 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2515 strcpy (f->namebuf, str);
2518 ac = 0;
2519 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2520 XtSetArg (al[ac], XtNinput, 1); ac++;
2521 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2522 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2523 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2524 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2525 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2526 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2527 applicationShellWidgetClass,
2528 FRAME_X_DISPLAY (f), al, ac);
2530 f->output_data.x->widget = shell_widget;
2531 /* maybe_set_screen_title_format (shell_widget); */
2533 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2534 (widget_value *) NULL,
2535 shell_widget, False,
2536 (lw_callback) NULL,
2537 (lw_callback) NULL,
2538 (lw_callback) NULL,
2539 (lw_callback) NULL);
2541 ac = 0;
2542 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2543 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2544 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2545 XtSetValues (pane_widget, al, ac);
2546 f->output_data.x->column_widget = pane_widget;
2548 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2549 the emacs screen when changing menubar. This reduces flickering. */
2551 ac = 0;
2552 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2553 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2554 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2555 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2556 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2557 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2558 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2559 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2560 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2561 al, ac);
2563 f->output_data.x->edit_widget = frame_widget;
2565 XtManageChild (frame_widget);
2567 /* Do some needed geometry management. */
2569 int len;
2570 char *tem, shell_position[32];
2571 Arg al[10];
2572 int ac = 0;
2573 int extra_borders = 0;
2574 int menubar_size
2575 = (f->output_data.x->menubar_widget
2576 ? (f->output_data.x->menubar_widget->core.height
2577 + f->output_data.x->menubar_widget->core.border_width)
2578 : 0);
2580 #if 0 /* Experimentally, we now get the right results
2581 for -geometry -0-0 without this. 24 Aug 96, rms. */
2582 if (FRAME_EXTERNAL_MENU_BAR (f))
2584 Dimension ibw = 0;
2585 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2586 menubar_size += ibw;
2588 #endif
2590 f->output_data.x->menubar_height = menubar_size;
2592 #ifndef USE_LUCID
2593 /* Motif seems to need this amount added to the sizes
2594 specified for the shell widget. The Athena/Lucid widgets don't.
2595 Both conclusions reached experimentally. -- rms. */
2596 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2597 &extra_borders, NULL);
2598 extra_borders *= 2;
2599 #endif
2601 /* Convert our geometry parameters into a geometry string
2602 and specify it.
2603 Note that we do not specify here whether the position
2604 is a user-specified or program-specified one.
2605 We pass that information later, in x_wm_set_size_hints. */
2607 int left = f->left_pos;
2608 int xneg = window_prompting & XNegative;
2609 int top = f->top_pos;
2610 int yneg = window_prompting & YNegative;
2611 if (xneg)
2612 left = -left;
2613 if (yneg)
2614 top = -top;
2616 if (window_prompting & USPosition)
2617 sprintf (shell_position, "=%dx%d%c%d%c%d",
2618 FRAME_PIXEL_WIDTH (f) + extra_borders,
2619 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2620 (xneg ? '-' : '+'), left,
2621 (yneg ? '-' : '+'), top);
2622 else
2624 sprintf (shell_position, "=%dx%d",
2625 FRAME_PIXEL_WIDTH (f) + extra_borders,
2626 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2628 /* Setting x and y when the position is not specified in
2629 the geometry string will set program position in the WM hints.
2630 If Emacs had just one program position, we could set it in
2631 fallback resources, but since each make-frame call can specify
2632 different program positions, this is easier. */
2633 XtSetArg (al[ac], XtNx, left); ac++;
2634 XtSetArg (al[ac], XtNy, top); ac++;
2638 len = strlen (shell_position) + 1;
2639 /* We don't free this because we don't know whether
2640 it is safe to free it while the frame exists.
2641 It isn't worth the trouble of arranging to free it
2642 when the frame is deleted. */
2643 tem = (char *) xmalloc (len);
2644 strncpy (tem, shell_position, len);
2645 XtSetArg (al[ac], XtNgeometry, tem); ac++;
2646 XtSetValues (shell_widget, al, ac);
2649 XtManageChild (pane_widget);
2650 XtRealizeWidget (shell_widget);
2652 if (FRAME_X_EMBEDDED_P (f))
2653 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2654 f->output_data.x->parent_desc, 0, 0);
2656 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2658 validate_x_resource_name ();
2660 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2661 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2662 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2664 #ifdef HAVE_X_I18N
2665 FRAME_XIC (f) = NULL;
2666 if (use_xim)
2667 create_frame_xic (f);
2668 #endif
2670 f->output_data.x->wm_hints.input = True;
2671 f->output_data.x->wm_hints.flags |= InputHint;
2672 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2673 &f->output_data.x->wm_hints);
2675 hack_wm_protocols (f, shell_widget);
2677 #ifdef HACK_EDITRES
2678 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2679 #endif
2681 /* Do a stupid property change to force the server to generate a
2682 PropertyNotify event so that the event_stream server timestamp will
2683 be initialized to something relevant to the time we created the window.
2685 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2686 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2687 XA_ATOM, 32, PropModeAppend,
2688 (unsigned char*) NULL, 0);
2690 /* Make all the standard events reach the Emacs frame. */
2691 attributes.event_mask = STANDARD_EVENT_SET;
2693 #ifdef HAVE_X_I18N
2694 if (FRAME_XIC (f))
2696 /* XIM server might require some X events. */
2697 unsigned long fevent = NoEventMask;
2698 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2699 attributes.event_mask |= fevent;
2701 #endif /* HAVE_X_I18N */
2703 attribute_mask = CWEventMask;
2704 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2705 attribute_mask, &attributes);
2707 XtMapWidget (frame_widget);
2709 /* x_set_name normally ignores requests to set the name if the
2710 requested name is the same as the current name. This is the one
2711 place where that assumption isn't correct; f->name is set, but
2712 the X server hasn't been told. */
2714 Lisp_Object name;
2715 int explicit = f->explicit_name;
2717 f->explicit_name = 0;
2718 name = f->name;
2719 f->name = Qnil;
2720 x_set_name (f, name, explicit);
2723 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2724 f->output_data.x->current_cursor
2725 = f->output_data.x->text_cursor);
2727 UNBLOCK_INPUT;
2729 /* This is a no-op, except under Motif. Make sure main areas are
2730 set to something reasonable, in case we get an error later. */
2731 lw_set_main_areas (pane_widget, 0, frame_widget);
2734 #else /* not USE_X_TOOLKIT */
2735 #ifdef USE_GTK
2736 void
2737 x_window (f)
2738 FRAME_PTR f;
2740 if (! xg_create_frame_widgets (f))
2741 error ("Unable to create window");
2743 #ifdef HAVE_X_I18N
2744 FRAME_XIC (f) = NULL;
2745 if (use_xim)
2747 BLOCK_INPUT;
2748 create_frame_xic (f);
2749 if (FRAME_XIC (f))
2751 /* XIM server might require some X events. */
2752 unsigned long fevent = NoEventMask;
2753 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2755 if (fevent != NoEventMask)
2757 XSetWindowAttributes attributes;
2758 XWindowAttributes wattr;
2759 unsigned long attribute_mask;
2761 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2762 &wattr);
2763 attributes.event_mask = wattr.your_event_mask | fevent;
2764 attribute_mask = CWEventMask;
2765 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2766 attribute_mask, &attributes);
2769 UNBLOCK_INPUT;
2771 #endif
2774 #else /*! USE_GTK */
2775 /* Create and set up the X window for frame F. */
2777 void
2778 x_window (f)
2779 struct frame *f;
2782 XClassHint class_hints;
2783 XSetWindowAttributes attributes;
2784 unsigned long attribute_mask;
2786 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2787 attributes.border_pixel = f->output_data.x->border_pixel;
2788 attributes.bit_gravity = StaticGravity;
2789 attributes.backing_store = NotUseful;
2790 attributes.save_under = True;
2791 attributes.event_mask = STANDARD_EVENT_SET;
2792 attributes.colormap = FRAME_X_COLORMAP (f);
2793 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2794 | CWColormap);
2796 BLOCK_INPUT;
2797 FRAME_X_WINDOW (f)
2798 = XCreateWindow (FRAME_X_DISPLAY (f),
2799 f->output_data.x->parent_desc,
2800 f->left_pos,
2801 f->top_pos,
2802 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2803 f->border_width,
2804 CopyFromParent, /* depth */
2805 InputOutput, /* class */
2806 FRAME_X_VISUAL (f),
2807 attribute_mask, &attributes);
2809 #ifdef HAVE_X_I18N
2810 if (use_xim)
2812 create_frame_xic (f);
2813 if (FRAME_XIC (f))
2815 /* XIM server might require some X events. */
2816 unsigned long fevent = NoEventMask;
2817 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2818 attributes.event_mask |= fevent;
2819 attribute_mask = CWEventMask;
2820 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2821 attribute_mask, &attributes);
2824 #endif /* HAVE_X_I18N */
2826 validate_x_resource_name ();
2828 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2829 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2830 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2832 /* The menubar is part of the ordinary display;
2833 it does not count in addition to the height of the window. */
2834 f->output_data.x->menubar_height = 0;
2836 /* This indicates that we use the "Passive Input" input model.
2837 Unless we do this, we don't get the Focus{In,Out} events that we
2838 need to draw the cursor correctly. Accursed bureaucrats.
2839 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2841 f->output_data.x->wm_hints.input = True;
2842 f->output_data.x->wm_hints.flags |= InputHint;
2843 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2844 &f->output_data.x->wm_hints);
2845 f->output_data.x->wm_hints.icon_pixmap = None;
2847 /* Request "save yourself" and "delete window" commands from wm. */
2849 Atom protocols[2];
2850 protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2851 protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2852 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2855 /* x_set_name normally ignores requests to set the name if the
2856 requested name is the same as the current name. This is the one
2857 place where that assumption isn't correct; f->name is set, but
2858 the X server hasn't been told. */
2860 Lisp_Object name;
2861 int explicit = f->explicit_name;
2863 f->explicit_name = 0;
2864 name = f->name;
2865 f->name = Qnil;
2866 x_set_name (f, name, explicit);
2869 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2870 f->output_data.x->current_cursor
2871 = f->output_data.x->text_cursor);
2873 UNBLOCK_INPUT;
2875 if (FRAME_X_WINDOW (f) == 0)
2876 error ("Unable to create window");
2879 #endif /* not USE_GTK */
2880 #endif /* not USE_X_TOOLKIT */
2882 /* Verify that the icon position args for this window are valid. */
2884 static void
2885 x_icon_verify (f, parms)
2886 struct frame *f;
2887 Lisp_Object parms;
2889 Lisp_Object icon_x, icon_y;
2891 /* Set the position of the icon. Note that twm groups all
2892 icons in an icon window. */
2893 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2894 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2895 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2897 CHECK_NUMBER (icon_x);
2898 CHECK_NUMBER (icon_y);
2900 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2901 error ("Both left and top icon corners of icon must be specified");
2904 /* Handle the icon stuff for this window. Perhaps later we might
2905 want an x_set_icon_position which can be called interactively as
2906 well. */
2908 static void
2909 x_icon (f, parms)
2910 struct frame *f;
2911 Lisp_Object parms;
2913 Lisp_Object icon_x, icon_y;
2914 #if 0
2915 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2916 #endif
2918 /* Set the position of the icon. Note that twm groups all
2919 icons in an icon window. */
2920 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2921 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2922 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2924 CHECK_NUMBER (icon_x);
2925 CHECK_NUMBER (icon_y);
2927 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2928 error ("Both left and top icon corners of icon must be specified");
2930 BLOCK_INPUT;
2932 if (! EQ (icon_x, Qunbound))
2933 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2935 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2936 but x_create_frame still needs it. */
2937 /* Start up iconic or window? */
2938 x_wm_set_window_state
2939 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2940 Qicon)
2941 ? IconicState
2942 : NormalState));
2943 #endif
2945 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2946 ? f->icon_name
2947 : f->name)));
2949 UNBLOCK_INPUT;
2952 /* Make the GCs needed for this window, setting the
2953 background, border and mouse colors; also create the
2954 mouse cursor and the gray border tile. */
2956 static void
2957 x_make_gc (f)
2958 struct frame *f;
2960 XGCValues gc_values;
2962 BLOCK_INPUT;
2964 /* Create the GCs of this frame.
2965 Note that many default values are used. */
2967 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2968 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2969 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2970 f->output_data.x->normal_gc
2971 = XCreateGC (FRAME_X_DISPLAY (f),
2972 FRAME_X_WINDOW (f),
2973 GCLineWidth | GCForeground | GCBackground,
2974 &gc_values);
2976 /* Reverse video style. */
2977 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2978 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2979 f->output_data.x->reverse_gc
2980 = XCreateGC (FRAME_X_DISPLAY (f),
2981 FRAME_X_WINDOW (f),
2982 GCForeground | GCBackground | GCLineWidth,
2983 &gc_values);
2985 /* Cursor has cursor-color background, background-color foreground. */
2986 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2987 gc_values.background = f->output_data.x->cursor_pixel;
2988 gc_values.fill_style = FillOpaqueStippled;
2989 f->output_data.x->cursor_gc
2990 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2991 (GCForeground | GCBackground
2992 | GCFillStyle | GCLineWidth),
2993 &gc_values);
2995 /* Reliefs. */
2996 f->output_data.x->white_relief.gc = 0;
2997 f->output_data.x->black_relief.gc = 0;
2999 /* Create the gray border tile used when the pointer is not in
3000 the frame. Since this depends on the frame's pixel values,
3001 this must be done on a per-frame basis. */
3002 f->output_data.x->border_tile
3003 = (XCreatePixmapFromBitmapData
3004 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
3005 gray_bits, gray_width, gray_height,
3006 FRAME_FOREGROUND_PIXEL (f),
3007 FRAME_BACKGROUND_PIXEL (f),
3008 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
3010 UNBLOCK_INPUT;
3014 /* Free what was allocated in x_make_gc. */
3016 void
3017 x_free_gcs (f)
3018 struct frame *f;
3020 Display *dpy = FRAME_X_DISPLAY (f);
3022 BLOCK_INPUT;
3024 if (f->output_data.x->normal_gc)
3026 XFreeGC (dpy, f->output_data.x->normal_gc);
3027 f->output_data.x->normal_gc = 0;
3030 if (f->output_data.x->reverse_gc)
3032 XFreeGC (dpy, f->output_data.x->reverse_gc);
3033 f->output_data.x->reverse_gc = 0;
3036 if (f->output_data.x->cursor_gc)
3038 XFreeGC (dpy, f->output_data.x->cursor_gc);
3039 f->output_data.x->cursor_gc = 0;
3042 if (f->output_data.x->border_tile)
3044 XFreePixmap (dpy, f->output_data.x->border_tile);
3045 f->output_data.x->border_tile = 0;
3048 UNBLOCK_INPUT;
3052 /* Handler for signals raised during x_create_frame and
3053 x_create_top_frame. FRAME is the frame which is partially
3054 constructed. */
3056 static Lisp_Object
3057 unwind_create_frame (frame)
3058 Lisp_Object frame;
3060 struct frame *f = XFRAME (frame);
3062 /* If frame is already dead, nothing to do. This can happen if the
3063 display is disconnected after the frame has become official, but
3064 before x_create_frame removes the unwind protect. */
3065 if (!FRAME_LIVE_P (f))
3066 return Qnil;
3068 /* If frame is ``official'', nothing to do. */
3069 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
3071 #if GLYPH_DEBUG
3072 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3073 #endif
3075 x_free_frame_resources (f);
3077 #if GLYPH_DEBUG
3078 /* Check that reference counts are indeed correct. */
3079 xassert (dpyinfo->reference_count == dpyinfo_refcount);
3080 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
3081 #endif
3082 return Qt;
3085 return Qnil;
3089 static void
3090 x_default_font_parameter (f, parms)
3091 struct frame *f;
3092 Lisp_Object parms;
3094 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3095 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
3096 RES_TYPE_STRING);
3097 Lisp_Object font;
3098 int got_from_gconf = 0;
3099 if (EQ (font_param, Qunbound))
3100 font_param = Qnil;
3102 if (NILP (font_param))
3104 /* System font takes precedendce over X resources. We must suggest this
3105 regardless of font-use-system-font because .emacs may not have been
3106 read yet. */
3107 const char *system_font = xsettings_get_system_font ();
3108 if (system_font) font_param = make_string (system_font,
3109 strlen (system_font));
3112 font = !NILP (font_param) ? font_param
3113 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
3115 if (! STRINGP (font))
3117 char *names[]
3119 #ifdef HAVE_XFT
3120 /* This will find the normal Xft font. */
3121 "monospace-10",
3122 #endif
3123 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3124 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3125 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3126 /* This was formerly the first thing tried, but it finds
3127 too many fonts and takes too long. */
3128 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3129 /* If those didn't work, look for something which will
3130 at least work. */
3131 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3132 "fixed",
3133 NULL };
3134 int i;
3136 for (i = 0; names[i]; i++)
3138 font = font_open_by_name (f, names[i]);
3139 if (! NILP (font))
3140 break;
3142 if (NILP (font))
3143 error ("No suitable font was found");
3145 else if (!NILP (font_param))
3147 /* Remember the explicit font parameter, so we can re-apply it after
3148 we've applied the `default' face settings. */
3149 x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
3152 x_default_parameter (f, parms, Qfont, font,
3153 got_from_gconf ? NULL : "font",
3154 got_from_gconf ? NULL : "Font",
3155 RES_TYPE_STRING);
3159 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
3160 0, 1, 0,
3161 doc: /* Send the size hints for frame FRAME to the window manager.
3162 If FRAME is nil, use the selected frame. */)
3163 (frame)
3164 Lisp_Object frame;
3166 struct frame *f;
3167 if (NILP (frame))
3168 frame = selected_frame;
3169 f = XFRAME (frame);
3170 BLOCK_INPUT;
3171 if (FRAME_X_P (f))
3172 x_wm_set_size_hint (f, 0, 0);
3173 UNBLOCK_INPUT;
3174 return Qnil;
3177 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3178 1, 1, 0,
3179 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
3180 Return an Emacs frame object.
3181 PARMS is an alist of frame parameters.
3182 If the parameters specify that the frame should not have a minibuffer,
3183 and do not specify a specific minibuffer window to use,
3184 then `default-minibuffer-frame' must be a frame whose minibuffer can
3185 be shared by the new frame.
3187 This function is an internal primitive--use `make-frame' instead. */)
3188 (parms)
3189 Lisp_Object parms;
3191 struct frame *f;
3192 Lisp_Object frame, tem;
3193 Lisp_Object name;
3194 int minibuffer_only = 0;
3195 long window_prompting = 0;
3196 int width, height;
3197 int count = SPECPDL_INDEX ();
3198 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3199 Lisp_Object display;
3200 struct x_display_info *dpyinfo = NULL;
3201 Lisp_Object parent;
3202 struct kboard *kb;
3204 parms = Fcopy_alist (parms);
3206 /* Use this general default value to start with
3207 until we know if this frame has a specified name. */
3208 Vx_resource_name = Vinvocation_name;
3210 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
3211 if (EQ (display, Qunbound))
3212 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
3213 if (EQ (display, Qunbound))
3214 display = Qnil;
3215 dpyinfo = check_x_display_info (display);
3216 kb = dpyinfo->terminal->kboard;
3218 if (!dpyinfo->terminal->name)
3219 error ("Terminal is not live, can't create new frames on it");
3221 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
3222 if (!STRINGP (name)
3223 && ! EQ (name, Qunbound)
3224 && ! NILP (name))
3225 error ("Invalid frame name--not a string or nil");
3227 if (STRINGP (name))
3228 Vx_resource_name = name;
3230 /* See if parent window is specified. */
3231 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
3232 if (EQ (parent, Qunbound))
3233 parent = Qnil;
3234 if (! NILP (parent))
3235 CHECK_NUMBER (parent);
3237 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3238 /* No need to protect DISPLAY because that's not used after passing
3239 it to make_frame_without_minibuffer. */
3240 frame = Qnil;
3241 GCPRO4 (parms, parent, name, frame);
3242 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
3243 RES_TYPE_SYMBOL);
3244 if (EQ (tem, Qnone) || NILP (tem))
3245 f = make_frame_without_minibuffer (Qnil, kb, display);
3246 else if (EQ (tem, Qonly))
3248 f = make_minibuffer_frame ();
3249 minibuffer_only = 1;
3251 else if (WINDOWP (tem))
3252 f = make_frame_without_minibuffer (tem, kb, display);
3253 else
3254 f = make_frame (1);
3256 XSETFRAME (frame, f);
3258 /* Note that X Windows does support scroll bars. */
3259 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3261 f->terminal = dpyinfo->terminal;
3262 f->terminal->reference_count++;
3264 f->output_method = output_x_window;
3265 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
3266 bzero (f->output_data.x, sizeof (struct x_output));
3267 f->output_data.x->icon_bitmap = -1;
3268 FRAME_FONTSET (f) = -1;
3269 f->output_data.x->scroll_bar_foreground_pixel = -1;
3270 f->output_data.x->scroll_bar_background_pixel = -1;
3271 #ifdef USE_TOOLKIT_SCROLL_BARS
3272 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
3273 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
3274 #endif /* USE_TOOLKIT_SCROLL_BARS */
3276 f->icon_name
3277 = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3278 RES_TYPE_STRING);
3279 if (! STRINGP (f->icon_name))
3280 f->icon_name = Qnil;
3282 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3284 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3285 record_unwind_protect (unwind_create_frame, frame);
3286 #if GLYPH_DEBUG
3287 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
3288 dpyinfo_refcount = dpyinfo->reference_count;
3289 #endif /* GLYPH_DEBUG */
3291 /* These colors will be set anyway later, but it's important
3292 to get the color reference counts right, so initialize them! */
3294 Lisp_Object black;
3295 struct gcpro gcpro1;
3297 /* Function x_decode_color can signal an error. Make
3298 sure to initialize color slots so that we won't try
3299 to free colors we haven't allocated. */
3300 FRAME_FOREGROUND_PIXEL (f) = -1;
3301 FRAME_BACKGROUND_PIXEL (f) = -1;
3302 f->output_data.x->cursor_pixel = -1;
3303 f->output_data.x->cursor_foreground_pixel = -1;
3304 f->output_data.x->border_pixel = -1;
3305 f->output_data.x->mouse_pixel = -1;
3307 black = build_string ("black");
3308 GCPRO1 (black);
3309 FRAME_FOREGROUND_PIXEL (f)
3310 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3311 FRAME_BACKGROUND_PIXEL (f)
3312 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3313 f->output_data.x->cursor_pixel
3314 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3315 f->output_data.x->cursor_foreground_pixel
3316 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3317 f->output_data.x->border_pixel
3318 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3319 f->output_data.x->mouse_pixel
3320 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3321 UNGCPRO;
3324 /* Specify the parent under which to make this X window. */
3326 if (!NILP (parent))
3328 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3329 f->output_data.x->explicit_parent = 1;
3331 else
3333 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3334 f->output_data.x->explicit_parent = 0;
3337 /* Set the name; the functions to which we pass f expect the name to
3338 be set. */
3339 if (EQ (name, Qunbound) || NILP (name))
3341 f->name = build_string (dpyinfo->x_id_name);
3342 f->explicit_name = 0;
3344 else
3346 f->name = name;
3347 f->explicit_name = 1;
3348 /* use the frame's title when getting resources for this frame. */
3349 specbind (Qx_resource_name, name);
3352 f->resx = dpyinfo->resx;
3353 f->resy = dpyinfo->resy;
3355 #ifdef HAVE_FREETYPE
3356 #ifdef HAVE_XFT
3357 register_font_driver (&xftfont_driver, f);
3358 #else /* not HAVE_XFT */
3359 register_font_driver (&ftxfont_driver, f);
3360 #endif /* not HAVE_XFT */
3361 #endif /* HAVE_FREETYPE */
3362 register_font_driver (&xfont_driver, f);
3364 x_default_parameter (f, parms, Qfont_backend, Qnil,
3365 "fontBackend", "FontBackend", RES_TYPE_STRING);
3367 /* Extract the window parameters from the supplied values
3368 that are needed to determine window geometry. */
3369 x_default_font_parameter (f, parms);
3370 if (!FRAME_FONT (f))
3372 delete_frame (frame, Qnoelisp);
3373 error ("Invalid frame font");
3376 #ifdef USE_LUCID
3377 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3378 whereby it fails to get any font. */
3379 BLOCK_INPUT;
3380 xlwmenu_default_font = XLoadQueryFont (FRAME_X_DISPLAY (f), "fixed");
3381 UNBLOCK_INPUT;
3382 #endif
3384 /* Frame contents get displaced if an embedded X window has a border. */
3385 if (! FRAME_X_EMBEDDED_P (f))
3386 x_default_parameter (f, parms, Qborder_width, make_number (2),
3387 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3389 /* This defaults to 1 in order to match xterm. We recognize either
3390 internalBorderWidth or internalBorder (which is what xterm calls
3391 it). */
3392 if (NILP (Fassq (Qinternal_border_width, parms)))
3394 Lisp_Object value;
3396 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3397 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3398 if (! EQ (value, Qunbound))
3399 parms = Fcons (Fcons (Qinternal_border_width, value),
3400 parms);
3402 x_default_parameter (f, parms, Qinternal_border_width,
3403 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3404 make_number (0),
3405 #else
3406 make_number (1),
3407 #endif
3408 "internalBorderWidth", "internalBorderWidth",
3409 RES_TYPE_NUMBER);
3410 x_default_parameter (f, parms, Qvertical_scroll_bars, Qleft,
3411 "verticalScrollBars", "ScrollBars",
3412 RES_TYPE_SYMBOL);
3414 /* Also do the stuff which must be set before the window exists. */
3415 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3416 "foreground", "Foreground", RES_TYPE_STRING);
3417 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3418 "background", "Background", RES_TYPE_STRING);
3419 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3420 "pointerColor", "Foreground", RES_TYPE_STRING);
3421 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3422 "cursorColor", "Foreground", RES_TYPE_STRING);
3423 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3424 "borderColor", "BorderColor", RES_TYPE_STRING);
3425 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3426 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3427 x_default_parameter (f, parms, Qline_spacing, Qnil,
3428 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3429 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3430 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3431 x_default_parameter (f, parms, Qright_fringe, Qnil,
3432 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3434 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3435 "scrollBarForeground",
3436 "ScrollBarForeground", 1);
3437 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3438 "scrollBarBackground",
3439 "ScrollBarBackground", 0);
3441 /* Init faces before x_default_parameter is called for scroll-bar
3442 parameters because that function calls x_set_scroll_bar_width,
3443 which calls change_frame_size, which calls Fset_window_buffer,
3444 which runs hooks, which call Fvertical_motion. At the end, we
3445 end up in init_iterator with a null face cache, which should not
3446 happen. */
3447 init_frame_faces (f);
3449 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
3450 "menuBar", "MenuBar", RES_TYPE_BOOLEAN_NUMBER);
3451 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
3452 "toolBar", "ToolBar", RES_TYPE_NUMBER);
3453 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3454 "bufferPredicate", "BufferPredicate",
3455 RES_TYPE_SYMBOL);
3456 x_default_parameter (f, parms, Qtitle, Qnil,
3457 "title", "Title", RES_TYPE_STRING);
3458 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3459 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3460 x_default_parameter (f, parms, Qfullscreen, Qnil,
3461 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3463 /* Compute the size of the X window. */
3464 window_prompting = x_figure_window_size (f, parms, 1);
3466 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3467 f->no_split = minibuffer_only || EQ (tem, Qt);
3469 x_icon_verify (f, parms);
3471 /* Create the X widget or window. */
3472 #ifdef USE_X_TOOLKIT
3473 x_window (f, window_prompting, minibuffer_only);
3474 #else
3475 x_window (f);
3476 #endif
3478 x_icon (f, parms);
3479 x_make_gc (f);
3481 /* Now consider the frame official. */
3482 FRAME_X_DISPLAY_INFO (f)->reference_count++;
3483 Vframe_list = Fcons (frame, Vframe_list);
3485 /* We need to do this after creating the X window, so that the
3486 icon-creation functions can say whose icon they're describing. */
3487 x_default_parameter (f, parms, Qicon_type, Qt,
3488 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
3490 x_default_parameter (f, parms, Qauto_raise, Qnil,
3491 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3492 x_default_parameter (f, parms, Qauto_lower, Qnil,
3493 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3494 x_default_parameter (f, parms, Qcursor_type, Qbox,
3495 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3496 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3497 "scrollBarWidth", "ScrollBarWidth",
3498 RES_TYPE_NUMBER);
3499 x_default_parameter (f, parms, Qalpha, Qnil,
3500 "alpha", "Alpha", RES_TYPE_NUMBER);
3502 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3503 Change will not be effected unless different from the current
3504 FRAME_LINES (f). */
3505 width = FRAME_COLS (f);
3506 height = FRAME_LINES (f);
3508 SET_FRAME_COLS (f, 0);
3509 FRAME_LINES (f) = 0;
3510 change_frame_size (f, height, width, 1, 0, 0);
3512 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3513 /* Create the menu bar. */
3514 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3516 /* If this signals an error, we haven't set size hints for the
3517 frame and we didn't make it visible. */
3518 initialize_frame_menubar (f);
3520 #ifndef USE_GTK
3521 /* This is a no-op, except under Motif where it arranges the
3522 main window for the widgets on it. */
3523 lw_set_main_areas (f->output_data.x->column_widget,
3524 f->output_data.x->menubar_widget,
3525 f->output_data.x->edit_widget);
3526 #endif /* not USE_GTK */
3528 #endif /* USE_X_TOOLKIT || USE_GTK */
3530 /* Tell the server what size and position, etc, we want, and how
3531 badly we want them. This should be done after we have the menu
3532 bar so that its size can be taken into account. */
3533 BLOCK_INPUT;
3534 x_wm_set_size_hint (f, window_prompting, 0);
3535 UNBLOCK_INPUT;
3537 /* Make the window appear on the frame and enable display, unless
3538 the caller says not to. However, with explicit parent, Emacs
3539 cannot control visibility, so don't try. */
3540 if (! f->output_data.x->explicit_parent)
3542 Lisp_Object visibility;
3544 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3545 RES_TYPE_SYMBOL);
3546 if (EQ (visibility, Qunbound))
3547 visibility = Qt;
3549 if (EQ (visibility, Qicon))
3550 x_iconify_frame (f);
3551 else if (! NILP (visibility))
3552 x_make_frame_visible (f);
3553 else
3554 /* Must have been Qnil. */
3558 /* Set the WM leader property. GTK does this itself, so this is not
3559 needed when using GTK. */
3560 if (dpyinfo->client_leader_window != 0)
3562 BLOCK_INPUT;
3563 XChangeProperty (FRAME_X_DISPLAY (f),
3564 FRAME_OUTER_WINDOW (f),
3565 dpyinfo->Xatom_wm_client_leader,
3566 XA_WINDOW, 32, PropModeReplace,
3567 (unsigned char *) &dpyinfo->client_leader_window, 1);
3568 UNBLOCK_INPUT;
3571 /* Initialize `default-minibuffer-frame' in case this is the first
3572 frame on this terminal. */
3573 if (FRAME_HAS_MINIBUF_P (f)
3574 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
3575 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
3576 kb->Vdefault_minibuffer_frame = frame;
3578 /* All remaining specified parameters, which have not been "used"
3579 by x_get_arg and friends, now go in the misc. alist of the frame. */
3580 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3581 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3582 f->param_alist = Fcons (XCAR (tem), f->param_alist);
3584 UNGCPRO;
3586 /* Make sure windows on this frame appear in calls to next-window
3587 and similar functions. */
3588 Vwindow_list = Qnil;
3590 return unbind_to (count, frame);
3594 /* FRAME is used only to get a handle on the X display. We don't pass the
3595 display info directly because we're called from frame.c, which doesn't
3596 know about that structure. */
3598 Lisp_Object
3599 x_get_focus_frame (frame)
3600 struct frame *frame;
3602 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3603 Lisp_Object xfocus;
3604 if (! dpyinfo->x_focus_frame)
3605 return Qnil;
3607 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3608 return xfocus;
3612 /* In certain situations, when the window manager follows a
3613 click-to-focus policy, there seems to be no way around calling
3614 XSetInputFocus to give another frame the input focus .
3616 In an ideal world, XSetInputFocus should generally be avoided so
3617 that applications don't interfere with the window manager's focus
3618 policy. But I think it's okay to use when it's clearly done
3619 following a user-command. */
3621 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3622 doc: /* Set the input focus to FRAME.
3623 FRAME nil means use the selected frame. */)
3624 (frame)
3625 Lisp_Object frame;
3627 struct frame *f = check_x_frame (frame);
3628 Display *dpy = FRAME_X_DISPLAY (f);
3630 BLOCK_INPUT;
3631 x_catch_errors (dpy);
3632 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3633 RevertToParent, CurrentTime);
3634 x_ewmh_activate_frame (f);
3635 x_uncatch_errors ();
3636 UNBLOCK_INPUT;
3638 return Qnil;
3642 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3643 doc: /* Internal function called by `color-defined-p', which see. */)
3644 (color, frame)
3645 Lisp_Object color, frame;
3647 XColor foo;
3648 FRAME_PTR f = check_x_frame (frame);
3650 CHECK_STRING (color);
3652 if (x_defined_color (f, SDATA (color), &foo, 0))
3653 return Qt;
3654 else
3655 return Qnil;
3658 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3659 doc: /* Internal function called by `color-values', which see. */)
3660 (color, frame)
3661 Lisp_Object color, frame;
3663 XColor foo;
3664 FRAME_PTR f = check_x_frame (frame);
3666 CHECK_STRING (color);
3668 if (x_defined_color (f, SDATA (color), &foo, 0))
3669 return list3 (make_number (foo.red),
3670 make_number (foo.green),
3671 make_number (foo.blue));
3672 else
3673 return Qnil;
3676 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3677 doc: /* Internal function called by `display-color-p', which see. */)
3678 (terminal)
3679 Lisp_Object terminal;
3681 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3683 if (dpyinfo->n_planes <= 2)
3684 return Qnil;
3686 switch (dpyinfo->visual->class)
3688 case StaticColor:
3689 case PseudoColor:
3690 case TrueColor:
3691 case DirectColor:
3692 return Qt;
3694 default:
3695 return Qnil;
3699 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3700 0, 1, 0,
3701 doc: /* Return t if the X display supports shades of gray.
3702 Note that color displays do support shades of gray.
3703 The optional argument TERMINAL specifies which display to ask about.
3704 TERMINAL should be a terminal object, a frame or a display name (a string).
3705 If omitted or nil, that stands for the selected frame's display. */)
3706 (terminal)
3707 Lisp_Object terminal;
3709 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3711 if (dpyinfo->n_planes <= 1)
3712 return Qnil;
3714 switch (dpyinfo->visual->class)
3716 case StaticColor:
3717 case PseudoColor:
3718 case TrueColor:
3719 case DirectColor:
3720 case StaticGray:
3721 case GrayScale:
3722 return Qt;
3724 default:
3725 return Qnil;
3729 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3730 0, 1, 0,
3731 doc: /* Return the width in pixels of the X display TERMINAL.
3732 The optional argument TERMINAL specifies which display to ask about.
3733 TERMINAL should be a terminal object, a frame or a display name (a string).
3734 If omitted or nil, that stands for the selected frame's display. */)
3735 (terminal)
3736 Lisp_Object terminal;
3738 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3740 return make_number (x_display_pixel_width (dpyinfo));
3743 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3744 Sx_display_pixel_height, 0, 1, 0,
3745 doc: /* Return the height in pixels of the X display TERMINAL.
3746 The optional argument TERMINAL specifies which display to ask about.
3747 TERMINAL should be a terminal object, a frame or a display name (a string).
3748 If omitted or nil, that stands for the selected frame's display. */)
3749 (terminal)
3750 Lisp_Object terminal;
3752 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3754 return make_number (x_display_pixel_height (dpyinfo));
3757 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3758 0, 1, 0,
3759 doc: /* Return the number of bitplanes of the X display TERMINAL.
3760 The optional argument TERMINAL specifies which display to ask about.
3761 TERMINAL should be a terminal object, a frame or a display name (a string).
3762 If omitted or nil, that stands for the selected frame's display. */)
3763 (terminal)
3764 Lisp_Object terminal;
3766 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3768 return make_number (dpyinfo->n_planes);
3771 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3772 0, 1, 0,
3773 doc: /* Return the number of color cells of the X display TERMINAL.
3774 The optional argument TERMINAL specifies which display to ask about.
3775 TERMINAL should be a terminal object, a frame or a display name (a string).
3776 If omitted or nil, that stands for the selected frame's display. */)
3777 (terminal)
3778 Lisp_Object terminal;
3780 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3782 int nr_planes = DisplayPlanes (dpyinfo->display,
3783 XScreenNumberOfScreen (dpyinfo->screen));
3785 /* Truncate nr_planes to 24 to avoid integer overflow.
3786 Some displays says 32, but only 24 bits are actually significant.
3787 There are only very few and rare video cards that have more than
3788 24 significant bits. Also 24 bits is more than 16 million colors,
3789 it "should be enough for everyone". */
3790 if (nr_planes > 24) nr_planes = 24;
3792 return make_number (1 << nr_planes);
3795 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3796 Sx_server_max_request_size,
3797 0, 1, 0,
3798 doc: /* Return the maximum request size of the X server of display TERMINAL.
3799 The optional argument TERMINAL specifies which display to ask about.
3800 TERMINAL should be a terminal object, a frame or a display name (a string).
3801 If omitted or nil, that stands for the selected frame's display. */)
3802 (terminal)
3803 Lisp_Object terminal;
3805 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3807 return make_number (MAXREQUEST (dpyinfo->display));
3810 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3811 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3812 \(Labelling every distributor as a "vendor" embodies the false assumption
3813 that operating systems cannot be developed and distributed noncommercially.)
3814 The optional argument TERMINAL specifies which display to ask about.
3815 TERMINAL should be a terminal object, a frame or a display name (a string).
3816 If omitted or nil, that stands for the selected frame's display. */)
3817 (terminal)
3818 Lisp_Object terminal;
3820 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3821 char *vendor = ServerVendor (dpyinfo->display);
3823 if (! vendor) vendor = "";
3824 return build_string (vendor);
3827 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3828 doc: /* Return the version numbers of the X server of display TERMINAL.
3829 The value is a list of three integers: the major and minor
3830 version numbers of the X Protocol in use, and the distributor-specific release
3831 number. See also the function `x-server-vendor'.
3833 The optional argument TERMINAL specifies which display to ask about.
3834 TERMINAL should be a terminal object, a frame or a display name (a string).
3835 If omitted or nil, that stands for the selected frame's display. */)
3836 (terminal)
3837 Lisp_Object terminal;
3839 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3840 Display *dpy = dpyinfo->display;
3842 return Fcons (make_number (ProtocolVersion (dpy)),
3843 Fcons (make_number (ProtocolRevision (dpy)),
3844 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3847 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3848 doc: /* Return the number of screens on the X server of display TERMINAL.
3849 The optional argument TERMINAL specifies which display to ask about.
3850 TERMINAL should be a terminal object, a frame or a display name (a string).
3851 If omitted or nil, that stands for the selected frame's display. */)
3852 (terminal)
3853 Lisp_Object terminal;
3855 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3857 return make_number (ScreenCount (dpyinfo->display));
3860 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3861 doc: /* Return the height in millimeters of the X display TERMINAL.
3862 The optional argument TERMINAL specifies which display to ask about.
3863 TERMINAL should be a terminal object, a frame or a display name (a string).
3864 If omitted or nil, that stands for the selected frame's display. */)
3865 (terminal)
3866 Lisp_Object terminal;
3868 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3870 return make_number (HeightMMOfScreen (dpyinfo->screen));
3873 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3874 doc: /* Return the width in millimeters of the X display TERMINAL.
3875 The optional argument TERMINAL specifies which display to ask about.
3876 TERMINAL should be a terminal object, a frame or a display name (a string).
3877 If omitted or nil, that stands for the selected frame's display. */)
3878 (terminal)
3879 Lisp_Object terminal;
3881 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3883 return make_number (WidthMMOfScreen (dpyinfo->screen));
3886 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3887 Sx_display_backing_store, 0, 1, 0,
3888 doc: /* Return an indication of whether X display TERMINAL does backing store.
3889 The value may be `always', `when-mapped', or `not-useful'.
3890 The optional argument TERMINAL specifies which display to ask about.
3891 TERMINAL should be a terminal object, a frame or a display name (a string).
3892 If omitted or nil, that stands for the selected frame's display. */)
3893 (terminal)
3894 Lisp_Object terminal;
3896 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3897 Lisp_Object result;
3899 switch (DoesBackingStore (dpyinfo->screen))
3901 case Always:
3902 result = intern ("always");
3903 break;
3905 case WhenMapped:
3906 result = intern ("when-mapped");
3907 break;
3909 case NotUseful:
3910 result = intern ("not-useful");
3911 break;
3913 default:
3914 error ("Strange value for BackingStore parameter of screen");
3915 result = Qnil;
3918 return result;
3921 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3922 Sx_display_visual_class, 0, 1, 0,
3923 doc: /* Return the visual class of the X display TERMINAL.
3924 The value is one of the symbols `static-gray', `gray-scale',
3925 `static-color', `pseudo-color', `true-color', or `direct-color'.
3927 The optional argument TERMINAL specifies which display to ask about.
3928 TERMINAL should a terminal object, a frame or a display name (a string).
3929 If omitted or nil, that stands for the selected frame's display. */)
3930 (terminal)
3931 Lisp_Object terminal;
3933 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3934 Lisp_Object result;
3936 switch (dpyinfo->visual->class)
3938 case StaticGray:
3939 result = intern ("static-gray");
3940 break;
3941 case GrayScale:
3942 result = intern ("gray-scale");
3943 break;
3944 case StaticColor:
3945 result = intern ("static-color");
3946 break;
3947 case PseudoColor:
3948 result = intern ("pseudo-color");
3949 break;
3950 case TrueColor:
3951 result = intern ("true-color");
3952 break;
3953 case DirectColor:
3954 result = intern ("direct-color");
3955 break;
3956 default:
3957 error ("Display has an unknown visual class");
3958 result = Qnil;
3961 return result;
3964 DEFUN ("x-display-save-under", Fx_display_save_under,
3965 Sx_display_save_under, 0, 1, 0,
3966 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3967 The optional argument TERMINAL specifies which display to ask about.
3968 TERMINAL should be a terminal object, a frame or a display name (a string).
3969 If omitted or nil, that stands for the selected frame's display. */)
3970 (terminal)
3971 Lisp_Object terminal;
3973 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3975 if (DoesSaveUnders (dpyinfo->screen) == True)
3976 return Qt;
3977 else
3978 return Qnil;
3982 x_pixel_width (f)
3983 register struct frame *f;
3985 return FRAME_PIXEL_WIDTH (f);
3989 x_pixel_height (f)
3990 register struct frame *f;
3992 return FRAME_PIXEL_HEIGHT (f);
3996 x_char_width (f)
3997 register struct frame *f;
3999 return FRAME_COLUMN_WIDTH (f);
4003 x_char_height (f)
4004 register struct frame *f;
4006 return FRAME_LINE_HEIGHT (f);
4010 x_screen_planes (f)
4011 register struct frame *f;
4013 return FRAME_X_DISPLAY_INFO (f)->n_planes;
4018 /************************************************************************
4019 X Displays
4020 ************************************************************************/
4023 /* Mapping visual names to visuals. */
4025 static struct visual_class
4027 char *name;
4028 int class;
4030 visual_classes[] =
4032 {"StaticGray", StaticGray},
4033 {"GrayScale", GrayScale},
4034 {"StaticColor", StaticColor},
4035 {"PseudoColor", PseudoColor},
4036 {"TrueColor", TrueColor},
4037 {"DirectColor", DirectColor},
4038 {NULL, 0}
4042 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4044 /* Value is the screen number of screen SCR. This is a substitute for
4045 the X function with the same name when that doesn't exist. */
4048 XScreenNumberOfScreen (scr)
4049 register Screen *scr;
4051 Display *dpy = scr->display;
4052 int i;
4054 for (i = 0; i < dpy->nscreens; ++i)
4055 if (scr == dpy->screens + i)
4056 break;
4058 return i;
4061 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4064 /* Select the visual that should be used on display DPYINFO. Set
4065 members of DPYINFO appropriately. Called from x_term_init. */
4067 void
4068 select_visual (dpyinfo)
4069 struct x_display_info *dpyinfo;
4071 Display *dpy = dpyinfo->display;
4072 Screen *screen = dpyinfo->screen;
4073 Lisp_Object value;
4075 /* See if a visual is specified. */
4076 value = display_x_get_resource (dpyinfo,
4077 build_string ("visualClass"),
4078 build_string ("VisualClass"),
4079 Qnil, Qnil);
4080 if (STRINGP (value))
4082 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4083 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4084 depth, a decimal number. NAME is compared with case ignored. */
4085 char *s = (char *) alloca (SBYTES (value) + 1);
4086 char *dash;
4087 int i, class = -1;
4088 XVisualInfo vinfo;
4090 strcpy (s, SDATA (value));
4091 dash = index (s, '-');
4092 if (dash)
4094 dpyinfo->n_planes = atoi (dash + 1);
4095 *dash = '\0';
4097 else
4098 /* We won't find a matching visual with depth 0, so that
4099 an error will be printed below. */
4100 dpyinfo->n_planes = 0;
4102 /* Determine the visual class. */
4103 for (i = 0; visual_classes[i].name; ++i)
4104 if (xstrcasecmp (s, visual_classes[i].name) == 0)
4106 class = visual_classes[i].class;
4107 break;
4110 /* Look up a matching visual for the specified class. */
4111 if (class == -1
4112 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4113 dpyinfo->n_planes, class, &vinfo))
4114 fatal ("Invalid visual specification `%s'", SDATA (value));
4116 dpyinfo->visual = vinfo.visual;
4118 else
4120 int n_visuals;
4121 XVisualInfo *vinfo, vinfo_template;
4123 dpyinfo->visual = DefaultVisualOfScreen (screen);
4125 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4126 vinfo_template.screen = XScreenNumberOfScreen (screen);
4127 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4128 &vinfo_template, &n_visuals);
4129 if (n_visuals != 1)
4130 fatal ("Can't get proper X visual info");
4132 dpyinfo->n_planes = vinfo->depth;
4133 XFree ((char *) vinfo);
4138 /* Return the X display structure for the display named NAME.
4139 Open a new connection if necessary. */
4141 struct x_display_info *
4142 x_display_info_for_name (name)
4143 Lisp_Object name;
4145 Lisp_Object names;
4146 struct x_display_info *dpyinfo;
4148 CHECK_STRING (name);
4150 #if 0
4151 if (! EQ (Vinitial_window_system, intern ("x")))
4152 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4153 #endif
4155 for (dpyinfo = x_display_list, names = x_display_name_list;
4156 dpyinfo;
4157 dpyinfo = dpyinfo->next, names = XCDR (names))
4159 Lisp_Object tem;
4160 tem = Fstring_equal (XCAR (XCAR (names)), name);
4161 if (!NILP (tem))
4162 return dpyinfo;
4165 /* Use this general default value to start with. */
4166 Vx_resource_name = Vinvocation_name;
4168 validate_x_resource_name ();
4170 dpyinfo = x_term_init (name, (char *)0,
4171 (char *) SDATA (Vx_resource_name));
4173 if (dpyinfo == 0)
4174 error ("Cannot connect to X server %s", SDATA (name));
4176 x_in_use = 1;
4177 XSETFASTINT (Vwindow_system_version, 11);
4179 return dpyinfo;
4183 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4184 1, 3, 0,
4185 doc: /* Open a connection to an X server.
4186 DISPLAY is the name of the display to connect to.
4187 Optional second arg XRM-STRING is a string of resources in xrdb format.
4188 If the optional third arg MUST-SUCCEED is non-nil,
4189 terminate Emacs if we can't open the connection. */)
4190 (display, xrm_string, must_succeed)
4191 Lisp_Object display, xrm_string, must_succeed;
4193 unsigned char *xrm_option;
4194 struct x_display_info *dpyinfo;
4196 CHECK_STRING (display);
4197 if (! NILP (xrm_string))
4198 CHECK_STRING (xrm_string);
4200 #if 0
4201 if (! EQ (Vinitial_window_system, intern ("x")))
4202 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4203 #endif
4205 if (! NILP (xrm_string))
4206 xrm_option = (unsigned char *) SDATA (xrm_string);
4207 else
4208 xrm_option = (unsigned char *) 0;
4210 validate_x_resource_name ();
4212 /* This is what opens the connection and sets x_current_display.
4213 This also initializes many symbols, such as those used for input. */
4214 dpyinfo = x_term_init (display, xrm_option,
4215 (char *) SDATA (Vx_resource_name));
4217 if (dpyinfo == 0)
4219 if (!NILP (must_succeed))
4220 fatal ("Cannot connect to X server %s.\n\
4221 Check the DISPLAY environment variable or use `-d'.\n\
4222 Also use the `xauth' program to verify that you have the proper\n\
4223 authorization information needed to connect the X server.\n\
4224 An insecure way to solve the problem may be to use `xhost'.\n",
4225 SDATA (display));
4226 else
4227 error ("Cannot connect to X server %s", SDATA (display));
4230 x_in_use = 1;
4232 XSETFASTINT (Vwindow_system_version, 11);
4233 return Qnil;
4236 DEFUN ("x-close-connection", Fx_close_connection,
4237 Sx_close_connection, 1, 1, 0,
4238 doc: /* Close the connection to TERMINAL's X server.
4239 For TERMINAL, specify a terminal object, a frame or a display name (a
4240 string). If TERMINAL is nil, that stands for the selected frame's
4241 terminal. */)
4242 (terminal)
4243 Lisp_Object terminal;
4245 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4247 if (dpyinfo->reference_count > 0)
4248 error ("Display still has frames on it");
4250 x_delete_terminal (dpyinfo->terminal);
4252 return Qnil;
4255 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4256 doc: /* Return the list of display names that Emacs has connections to. */)
4259 Lisp_Object tail, result;
4261 result = Qnil;
4262 for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
4263 result = Fcons (XCAR (XCAR (tail)), result);
4265 return result;
4268 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4269 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4270 If ON is nil, allow buffering of requests.
4271 Turning on synchronization prohibits the Xlib routines from buffering
4272 requests and seriously degrades performance, but makes debugging much
4273 easier.
4274 The optional second argument TERMINAL specifies which display to act on.
4275 TERMINAL should be a terminal object, a frame or a display name (a string).
4276 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4277 (on, terminal)
4278 Lisp_Object terminal, on;
4280 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4282 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4284 return Qnil;
4287 /* Wait for responses to all X commands issued so far for frame F. */
4289 void
4290 x_sync (f)
4291 FRAME_PTR f;
4293 BLOCK_INPUT;
4294 XSync (FRAME_X_DISPLAY (f), False);
4295 UNBLOCK_INPUT;
4299 /***********************************************************************
4300 Window properties
4301 ***********************************************************************/
4303 DEFUN ("x-change-window-property", Fx_change_window_property,
4304 Sx_change_window_property, 2, 6, 0,
4305 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4306 PROP must be a string.
4307 VALUE may be a string or a list of conses, numbers and/or strings.
4308 If an element in the list is a string, it is converted to
4309 an Atom and the value of the Atom is used. If an element is a cons,
4310 it is converted to a 32 bit number where the car is the 16 top bits and the
4311 cdr is the lower 16 bits.
4312 FRAME nil or omitted means use the selected frame.
4313 If TYPE is given and non-nil, it is the name of the type of VALUE.
4314 If TYPE is not given or nil, the type is STRING.
4315 FORMAT gives the size in bits of each element if VALUE is a list.
4316 It must be one of 8, 16 or 32.
4317 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4318 If OUTER_P is non-nil, the property is changed for the outer X window of
4319 FRAME. Default is to change on the edit X window.
4321 Value is VALUE. */)
4322 (prop, value, frame, type, format, outer_p)
4323 Lisp_Object prop, value, frame, type, format, outer_p;
4325 struct frame *f = check_x_frame (frame);
4326 Atom prop_atom;
4327 Atom target_type = XA_STRING;
4328 int element_format = 8;
4329 unsigned char *data;
4330 int nelements;
4331 Window w;
4333 CHECK_STRING (prop);
4335 if (! NILP (format))
4337 CHECK_NUMBER (format);
4338 element_format = XFASTINT (format);
4340 if (element_format != 8 && element_format != 16
4341 && element_format != 32)
4342 error ("FORMAT must be one of 8, 16 or 32");
4345 if (CONSP (value))
4347 nelements = x_check_property_data (value);
4348 if (nelements == -1)
4349 error ("Bad data in VALUE, must be number, string or cons");
4351 if (element_format == 8)
4352 data = (unsigned char *) xmalloc (nelements);
4353 else if (element_format == 16)
4354 data = (unsigned char *) xmalloc (nelements*2);
4355 else /* format == 32 */
4356 /* The man page for XChangeProperty:
4357 "If the specified format is 32, the property data must be a
4358 long array."
4359 This applies even if long is more than 64 bits. The X library
4360 converts to 32 bits before sending to the X server. */
4361 data = (unsigned char *) xmalloc (nelements * sizeof(long));
4363 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4365 else
4367 CHECK_STRING (value);
4368 data = SDATA (value);
4369 nelements = SCHARS (value);
4372 BLOCK_INPUT;
4373 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4374 if (! NILP (type))
4376 CHECK_STRING (type);
4377 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4380 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4381 else w = FRAME_X_WINDOW (f);
4383 XChangeProperty (FRAME_X_DISPLAY (f), w,
4384 prop_atom, target_type, element_format, PropModeReplace,
4385 data, nelements);
4387 if (CONSP (value)) xfree (data);
4389 /* Make sure the property is set when we return. */
4390 XFlush (FRAME_X_DISPLAY (f));
4391 UNBLOCK_INPUT;
4393 return value;
4397 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4398 Sx_delete_window_property, 1, 2, 0,
4399 doc: /* Remove window property PROP from X window of FRAME.
4400 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4401 (prop, frame)
4402 Lisp_Object prop, frame;
4404 struct frame *f = check_x_frame (frame);
4405 Atom prop_atom;
4407 CHECK_STRING (prop);
4408 BLOCK_INPUT;
4409 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4410 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4412 /* Make sure the property is removed when we return. */
4413 XFlush (FRAME_X_DISPLAY (f));
4414 UNBLOCK_INPUT;
4416 return prop;
4420 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4421 1, 6, 0,
4422 doc: /* Value is the value of window property PROP on FRAME.
4423 If FRAME is nil or omitted, use the selected frame.
4424 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4425 is the name of the Atom that denotes the type expected.
4426 If SOURCE is non-nil, get the property on that window instead of from
4427 FRAME. The number 0 denotes the root window.
4428 If DELETE_P is non-nil, delete the property after retreiving it.
4429 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4431 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4432 no value of TYPE. */)
4433 (prop, frame, type, source, delete_p, vector_ret_p)
4434 Lisp_Object prop, frame, type, source, delete_p, vector_ret_p;
4436 struct frame *f = check_x_frame (frame);
4437 Atom prop_atom;
4438 int rc;
4439 Lisp_Object prop_value = Qnil;
4440 unsigned char *tmp_data = NULL;
4441 Atom actual_type;
4442 Atom target_type = XA_STRING;
4443 int actual_format;
4444 unsigned long actual_size, bytes_remaining;
4445 Window target_window = FRAME_X_WINDOW (f);
4446 struct gcpro gcpro1;
4448 GCPRO1 (prop_value);
4449 CHECK_STRING (prop);
4451 if (! NILP (source))
4453 if (NUMBERP (source))
4455 if (FLOATP (source))
4456 target_window = (Window) XFLOAT (source);
4457 else
4458 target_window = XFASTINT (source);
4460 if (target_window == 0)
4461 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4463 else if (CONSP (source))
4464 target_window = cons_to_long (source);
4467 BLOCK_INPUT;
4468 if (STRINGP (type))
4470 if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
4471 target_type = AnyPropertyType;
4472 else
4473 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4476 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4477 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4478 prop_atom, 0, 0, False, target_type,
4479 &actual_type, &actual_format, &actual_size,
4480 &bytes_remaining, &tmp_data);
4481 if (rc == Success)
4483 int size = bytes_remaining;
4485 XFree (tmp_data);
4486 tmp_data = NULL;
4488 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4489 prop_atom, 0, bytes_remaining,
4490 ! NILP (delete_p), target_type,
4491 &actual_type, &actual_format,
4492 &actual_size, &bytes_remaining,
4493 &tmp_data);
4494 if (rc == Success && tmp_data)
4496 /* The man page for XGetWindowProperty says:
4497 "If the returned format is 32, the returned data is represented
4498 as a long array and should be cast to that type to obtain the
4499 elements."
4500 This applies even if long is more than 32 bits, the X library
4501 converts from 32 bit elements received from the X server to long
4502 and passes the long array to us. Thus, for that case bcopy can not
4503 be used. We convert to a 32 bit type here, because so much code
4504 assume on that.
4506 The bytes and offsets passed to XGetWindowProperty refers to the
4507 property and those are indeed in 32 bit quantities if format is
4508 32. */
4510 if (actual_format == 32 && actual_format < BITS_PER_LONG)
4512 unsigned long i;
4513 int *idata = (int *) tmp_data;
4514 long *ldata = (long *) tmp_data;
4516 for (i = 0; i < actual_size; ++i)
4517 idata[i] = (int) ldata[i];
4520 if (NILP (vector_ret_p))
4521 prop_value = make_string (tmp_data, size);
4522 else
4523 prop_value = x_property_data_to_lisp (f,
4524 tmp_data,
4525 actual_type,
4526 actual_format,
4527 actual_size);
4530 if (tmp_data) XFree (tmp_data);
4533 UNBLOCK_INPUT;
4534 UNGCPRO;
4535 return prop_value;
4540 /***********************************************************************
4541 Busy cursor
4542 ***********************************************************************/
4544 /* Timer function of hourglass_atimer. TIMER is equal to
4545 hourglass_atimer.
4547 Display an hourglass pointer on all frames by mapping the frames'
4548 hourglass_window. Set the hourglass_p flag in the frames'
4549 output_data.x structure to indicate that an hourglass cursor is
4550 shown on the frames. */
4552 void
4553 show_hourglass (timer)
4554 struct atimer *timer;
4556 /* The timer implementation will cancel this timer automatically
4557 after this function has run. Set hourglass_atimer to null
4558 so that we know the timer doesn't have to be canceled. */
4559 hourglass_atimer = NULL;
4561 if (!hourglass_shown_p)
4563 Lisp_Object rest, frame;
4565 BLOCK_INPUT;
4567 FOR_EACH_FRAME (rest, frame)
4569 struct frame *f = XFRAME (frame);
4571 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4573 Display *dpy = FRAME_X_DISPLAY (f);
4575 #ifdef USE_X_TOOLKIT
4576 if (f->output_data.x->widget)
4577 #else
4578 if (FRAME_OUTER_WINDOW (f))
4579 #endif
4581 f->output_data.x->hourglass_p = 1;
4583 if (!f->output_data.x->hourglass_window)
4585 unsigned long mask = CWCursor;
4586 XSetWindowAttributes attrs;
4587 #ifdef USE_GTK
4588 Window parent = FRAME_X_WINDOW (f);
4589 #else
4590 Window parent = FRAME_OUTER_WINDOW (f);
4591 #endif
4592 attrs.cursor = f->output_data.x->hourglass_cursor;
4594 f->output_data.x->hourglass_window
4595 = XCreateWindow (dpy, parent,
4596 0, 0, 32000, 32000, 0, 0,
4597 InputOnly,
4598 CopyFromParent,
4599 mask, &attrs);
4602 XMapRaised (dpy, f->output_data.x->hourglass_window);
4603 XFlush (dpy);
4608 hourglass_shown_p = 1;
4609 UNBLOCK_INPUT;
4614 /* Hide the hourglass pointer on all frames, if it is currently
4615 shown. */
4617 void
4618 hide_hourglass ()
4620 if (hourglass_shown_p)
4622 Lisp_Object rest, frame;
4624 BLOCK_INPUT;
4625 FOR_EACH_FRAME (rest, frame)
4627 struct frame *f = XFRAME (frame);
4629 if (FRAME_X_P (f)
4630 /* Watch out for newly created frames. */
4631 && f->output_data.x->hourglass_window)
4633 XUnmapWindow (FRAME_X_DISPLAY (f),
4634 f->output_data.x->hourglass_window);
4635 /* Sync here because XTread_socket looks at the
4636 hourglass_p flag that is reset to zero below. */
4637 XSync (FRAME_X_DISPLAY (f), False);
4638 f->output_data.x->hourglass_p = 0;
4642 hourglass_shown_p = 0;
4643 UNBLOCK_INPUT;
4649 /***********************************************************************
4650 Tool tips
4651 ***********************************************************************/
4653 static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *,
4654 Lisp_Object, Lisp_Object));
4655 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
4656 Lisp_Object, int, int, int *, int *));
4658 /* The frame of a currently visible tooltip. */
4660 Lisp_Object tip_frame;
4662 /* If non-nil, a timer started that hides the last tooltip when it
4663 fires. */
4665 Lisp_Object tip_timer;
4666 Window tip_window;
4668 /* If non-nil, a vector of 3 elements containing the last args
4669 with which x-show-tip was called. See there. */
4671 Lisp_Object last_show_tip_args;
4673 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4675 Lisp_Object Vx_max_tooltip_size;
4678 static Lisp_Object
4679 unwind_create_tip_frame (frame)
4680 Lisp_Object frame;
4682 Lisp_Object deleted;
4684 deleted = unwind_create_frame (frame);
4685 if (EQ (deleted, Qt))
4687 tip_window = None;
4688 tip_frame = Qnil;
4691 return deleted;
4695 /* Create a frame for a tooltip on the display described by DPYINFO.
4696 PARMS is a list of frame parameters. TEXT is the string to
4697 display in the tip frame. Value is the frame.
4699 Note that functions called here, esp. x_default_parameter can
4700 signal errors, for instance when a specified color name is
4701 undefined. We have to make sure that we're in a consistent state
4702 when this happens. */
4704 static Lisp_Object
4705 x_create_tip_frame (dpyinfo, parms, text)
4706 struct x_display_info *dpyinfo;
4707 Lisp_Object parms, text;
4709 struct frame *f;
4710 Lisp_Object frame, tem;
4711 Lisp_Object name;
4712 long window_prompting = 0;
4713 int width, height;
4714 int count = SPECPDL_INDEX ();
4715 struct gcpro gcpro1, gcpro2, gcpro3;
4716 int face_change_count_before = face_change_count;
4717 Lisp_Object buffer;
4718 struct buffer *old_buffer;
4720 check_x ();
4722 if (!dpyinfo->terminal->name)
4723 error ("Terminal is not live, can't create new frames on it");
4725 parms = Fcopy_alist (parms);
4727 /* Get the name of the frame to use for resource lookup. */
4728 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4729 if (!STRINGP (name)
4730 && !EQ (name, Qunbound)
4731 && !NILP (name))
4732 error ("Invalid frame name--not a string or nil");
4734 frame = Qnil;
4735 GCPRO3 (parms, name, frame);
4736 f = make_frame (1);
4737 XSETFRAME (frame, f);
4739 buffer = Fget_buffer_create (build_string (" *tip*"));
4740 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
4741 old_buffer = current_buffer;
4742 set_buffer_internal_1 (XBUFFER (buffer));
4743 current_buffer->truncate_lines = Qnil;
4744 specbind (Qinhibit_read_only, Qt);
4745 specbind (Qinhibit_modification_hooks, Qt);
4746 Ferase_buffer ();
4747 Finsert (1, &text);
4748 set_buffer_internal_1 (old_buffer);
4750 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4751 record_unwind_protect (unwind_create_tip_frame, frame);
4753 f->terminal = dpyinfo->terminal;
4754 f->terminal->reference_count++;
4756 /* By setting the output method, we're essentially saying that
4757 the frame is live, as per FRAME_LIVE_P. If we get a signal
4758 from this point on, x_destroy_window might screw up reference
4759 counts etc. */
4760 f->output_method = output_x_window;
4761 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
4762 bzero (f->output_data.x, sizeof (struct x_output));
4763 f->output_data.x->icon_bitmap = -1;
4764 FRAME_FONTSET (f) = -1;
4765 f->output_data.x->scroll_bar_foreground_pixel = -1;
4766 f->output_data.x->scroll_bar_background_pixel = -1;
4767 #ifdef USE_TOOLKIT_SCROLL_BARS
4768 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4769 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4770 #endif /* USE_TOOLKIT_SCROLL_BARS */
4771 f->icon_name = Qnil;
4772 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4773 #if GLYPH_DEBUG
4774 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
4775 dpyinfo_refcount = dpyinfo->reference_count;
4776 #endif /* GLYPH_DEBUG */
4777 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4778 f->output_data.x->explicit_parent = 0;
4780 /* These colors will be set anyway later, but it's important
4781 to get the color reference counts right, so initialize them! */
4783 Lisp_Object black;
4784 struct gcpro gcpro1;
4786 /* Function x_decode_color can signal an error. Make
4787 sure to initialize color slots so that we won't try
4788 to free colors we haven't allocated. */
4789 FRAME_FOREGROUND_PIXEL (f) = -1;
4790 FRAME_BACKGROUND_PIXEL (f) = -1;
4791 f->output_data.x->cursor_pixel = -1;
4792 f->output_data.x->cursor_foreground_pixel = -1;
4793 f->output_data.x->border_pixel = -1;
4794 f->output_data.x->mouse_pixel = -1;
4796 black = build_string ("black");
4797 GCPRO1 (black);
4798 FRAME_FOREGROUND_PIXEL (f)
4799 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4800 FRAME_BACKGROUND_PIXEL (f)
4801 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4802 f->output_data.x->cursor_pixel
4803 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4804 f->output_data.x->cursor_foreground_pixel
4805 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4806 f->output_data.x->border_pixel
4807 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4808 f->output_data.x->mouse_pixel
4809 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4810 UNGCPRO;
4813 /* Set the name; the functions to which we pass f expect the name to
4814 be set. */
4815 if (EQ (name, Qunbound) || NILP (name))
4817 f->name = build_string (dpyinfo->x_id_name);
4818 f->explicit_name = 0;
4820 else
4822 f->name = name;
4823 f->explicit_name = 1;
4824 /* use the frame's title when getting resources for this frame. */
4825 specbind (Qx_resource_name, name);
4828 f->resx = dpyinfo->resx;
4829 f->resy = dpyinfo->resy;
4831 register_font_driver (&xfont_driver, f);
4832 #ifdef HAVE_FREETYPE
4833 #ifdef HAVE_XFT
4834 register_font_driver (&xftfont_driver, f);
4835 #else /* not HAVE_XFT */
4836 register_font_driver (&ftxfont_driver, f);
4837 #endif /* not HAVE_XFT */
4838 #endif /* HAVE_FREETYPE */
4840 x_default_parameter (f, parms, Qfont_backend, Qnil,
4841 "fontBackend", "FontBackend", RES_TYPE_STRING);
4843 /* Extract the window parameters from the supplied values that are
4844 needed to determine window geometry. */
4845 x_default_font_parameter (f, parms);
4847 x_default_parameter (f, parms, Qborder_width, make_number (2),
4848 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4850 /* This defaults to 2 in order to match xterm. We recognize either
4851 internalBorderWidth or internalBorder (which is what xterm calls
4852 it). */
4853 if (NILP (Fassq (Qinternal_border_width, parms)))
4855 Lisp_Object value;
4857 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4858 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4859 if (! EQ (value, Qunbound))
4860 parms = Fcons (Fcons (Qinternal_border_width, value),
4861 parms);
4864 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4865 "internalBorderWidth", "internalBorderWidth",
4866 RES_TYPE_NUMBER);
4868 /* Also do the stuff which must be set before the window exists. */
4869 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4870 "foreground", "Foreground", RES_TYPE_STRING);
4871 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4872 "background", "Background", RES_TYPE_STRING);
4873 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4874 "pointerColor", "Foreground", RES_TYPE_STRING);
4875 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4876 "cursorColor", "Foreground", RES_TYPE_STRING);
4877 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4878 "borderColor", "BorderColor", RES_TYPE_STRING);
4880 /* Init faces before x_default_parameter is called for scroll-bar
4881 parameters because that function calls x_set_scroll_bar_width,
4882 which calls change_frame_size, which calls Fset_window_buffer,
4883 which runs hooks, which call Fvertical_motion. At the end, we
4884 end up in init_iterator with a null face cache, which should not
4885 happen. */
4886 init_frame_faces (f);
4888 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4890 window_prompting = x_figure_window_size (f, parms, 0);
4893 XSetWindowAttributes attrs;
4894 unsigned long mask;
4895 Atom type = FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
4897 BLOCK_INPUT;
4898 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
4899 if (DoesSaveUnders (dpyinfo->screen))
4900 mask |= CWSaveUnder;
4902 /* Window managers look at the override-redirect flag to determine
4903 whether or net to give windows a decoration (Xlib spec, chapter
4904 3.2.8). */
4905 attrs.override_redirect = True;
4906 attrs.save_under = True;
4907 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
4908 /* Arrange for getting MapNotify and UnmapNotify events. */
4909 attrs.event_mask = StructureNotifyMask;
4910 tip_window
4911 = FRAME_X_WINDOW (f)
4912 = XCreateWindow (FRAME_X_DISPLAY (f),
4913 FRAME_X_DISPLAY_INFO (f)->root_window,
4914 /* x, y, width, height */
4915 0, 0, 1, 1,
4916 /* Border. */
4917 f->border_width,
4918 CopyFromParent, InputOutput, CopyFromParent,
4919 mask, &attrs);
4920 XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
4921 FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type,
4922 XA_ATOM, 32, PropModeReplace,
4923 (unsigned char *)&type, 1);
4924 UNBLOCK_INPUT;
4927 x_make_gc (f);
4929 x_default_parameter (f, parms, Qauto_raise, Qnil,
4930 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4931 x_default_parameter (f, parms, Qauto_lower, Qnil,
4932 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4933 x_default_parameter (f, parms, Qcursor_type, Qbox,
4934 "cursorType", "CursorType", RES_TYPE_SYMBOL);
4936 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4937 Change will not be effected unless different from the current
4938 FRAME_LINES (f). */
4939 width = FRAME_COLS (f);
4940 height = FRAME_LINES (f);
4941 SET_FRAME_COLS (f, 0);
4942 FRAME_LINES (f) = 0;
4943 change_frame_size (f, height, width, 1, 0, 0);
4945 /* Add `tooltip' frame parameter's default value. */
4946 if (NILP (Fframe_parameter (frame, Qtooltip)))
4947 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
4949 /* FIXME - can this be done in a similar way to normal frames?
4950 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
4952 /* Set the `display-type' frame parameter before setting up faces. */
4954 Lisp_Object disptype;
4956 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
4957 disptype = intern ("mono");
4958 else if (FRAME_X_DISPLAY_INFO (f)->visual->class == GrayScale
4959 || FRAME_X_DISPLAY_INFO (f)->visual->class == StaticGray)
4960 disptype = intern ("grayscale");
4961 else
4962 disptype = intern ("color");
4964 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
4965 Fmodify_frame_parameters (frame, Fcons (Fcons (Qdisplay_type, disptype),
4966 Qnil));
4969 /* Set up faces after all frame parameters are known. This call
4970 also merges in face attributes specified for new frames.
4972 Frame parameters may be changed if .Xdefaults contains
4973 specifications for the default font. For example, if there is an
4974 `Emacs.default.attributeBackground: pink', the `background-color'
4975 attribute of the frame get's set, which let's the internal border
4976 of the tooltip frame appear in pink. Prevent this. */
4978 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
4980 /* Set tip_frame here, so that */
4981 tip_frame = frame;
4982 call2 (Qface_set_after_frame_default, frame, Qnil);
4984 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
4985 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
4986 Qnil));
4989 f->no_split = 1;
4991 UNGCPRO;
4993 /* It is now ok to make the frame official even if we get an error
4994 below. And the frame needs to be on Vframe_list or making it
4995 visible won't work. */
4996 Vframe_list = Fcons (frame, Vframe_list);
4998 /* Now that the frame is official, it counts as a reference to
4999 its display. */
5000 FRAME_X_DISPLAY_INFO (f)->reference_count++;
5002 /* Setting attributes of faces of the tooltip frame from resources
5003 and similar will increment face_change_count, which leads to the
5004 clearing of all current matrices. Since this isn't necessary
5005 here, avoid it by resetting face_change_count to the value it
5006 had before we created the tip frame. */
5007 face_change_count = face_change_count_before;
5009 /* Discard the unwind_protect. */
5010 return unbind_to (count, frame);
5014 /* Compute where to display tip frame F. PARMS is the list of frame
5015 parameters for F. DX and DY are specified offsets from the current
5016 location of the mouse. WIDTH and HEIGHT are the width and height
5017 of the tooltip. Return coordinates relative to the root window of
5018 the display in *ROOT_X, and *ROOT_Y. */
5020 static void
5021 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
5022 struct frame *f;
5023 Lisp_Object parms, dx, dy;
5024 int width, height;
5025 int *root_x, *root_y;
5027 Lisp_Object left, top;
5028 int win_x, win_y;
5029 Window root, child;
5030 unsigned pmask;
5032 /* User-specified position? */
5033 left = Fcdr (Fassq (Qleft, parms));
5034 top = Fcdr (Fassq (Qtop, parms));
5036 /* Move the tooltip window where the mouse pointer is. Resize and
5037 show it. */
5038 if (!INTEGERP (left) || !INTEGERP (top))
5040 BLOCK_INPUT;
5041 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
5042 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
5043 UNBLOCK_INPUT;
5046 if (INTEGERP (top))
5047 *root_y = XINT (top);
5048 else if (*root_y + XINT (dy) <= 0)
5049 *root_y = 0; /* Can happen for negative dy */
5050 else if (*root_y + XINT (dy) + height
5051 <= x_display_pixel_height (FRAME_X_DISPLAY_INFO (f)))
5052 /* It fits below the pointer */
5053 *root_y += XINT (dy);
5054 else if (height + XINT (dy) <= *root_y)
5055 /* It fits above the pointer. */
5056 *root_y -= height + XINT (dy);
5057 else
5058 /* Put it on the top. */
5059 *root_y = 0;
5061 if (INTEGERP (left))
5062 *root_x = XINT (left);
5063 else if (*root_x + XINT (dx) <= 0)
5064 *root_x = 0; /* Can happen for negative dx */
5065 else if (*root_x + XINT (dx) + width
5066 <= x_display_pixel_width (FRAME_X_DISPLAY_INFO (f)))
5067 /* It fits to the right of the pointer. */
5068 *root_x += XINT (dx);
5069 else if (width + XINT (dx) <= *root_x)
5070 /* It fits to the left of the pointer. */
5071 *root_x -= width + XINT (dx);
5072 else
5073 /* Put it left-justified on the screen--it ought to fit that way. */
5074 *root_x = 0;
5078 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5079 doc: /* Show STRING in a "tooltip" window on frame FRAME.
5080 A tooltip window is a small X window displaying a string.
5082 This is an internal function; Lisp code should call `tooltip-show'.
5084 FRAME nil or omitted means use the selected frame.
5086 PARMS is an optional list of frame parameters which can be used to
5087 change the tooltip's appearance.
5089 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5090 means use the default timeout of 5 seconds.
5092 If the list of frame parameters PARAMS contains a `left' parameters,
5093 the tooltip is displayed at that x-position. Otherwise it is
5094 displayed at the mouse position, with offset DX added (default is 5 if
5095 DX isn't specified). Likewise for the y-position; if a `top' frame
5096 parameter is specified, it determines the y-position of the tooltip
5097 window, otherwise it is displayed at the mouse position, with offset
5098 DY added (default is -10).
5100 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5101 Text larger than the specified size is clipped. */)
5102 (string, frame, parms, timeout, dx, dy)
5103 Lisp_Object string, frame, parms, timeout, dx, dy;
5105 struct frame *f;
5106 struct window *w;
5107 int root_x, root_y;
5108 struct buffer *old_buffer;
5109 struct text_pos pos;
5110 int i, width, height;
5111 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5112 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5113 int count = SPECPDL_INDEX ();
5115 specbind (Qinhibit_redisplay, Qt);
5117 GCPRO4 (string, parms, frame, timeout);
5119 CHECK_STRING (string);
5120 if (SCHARS (string) == 0)
5121 string = make_unibyte_string (" ", 1);
5123 f = check_x_frame (frame);
5124 if (NILP (timeout))
5125 timeout = make_number (5);
5126 else
5127 CHECK_NATNUM (timeout);
5129 if (NILP (dx))
5130 dx = make_number (5);
5131 else
5132 CHECK_NUMBER (dx);
5134 if (NILP (dy))
5135 dy = make_number (-10);
5136 else
5137 CHECK_NUMBER (dy);
5139 if (NILP (last_show_tip_args))
5140 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5142 if (!NILP (tip_frame))
5144 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5145 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5146 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5148 if (EQ (frame, last_frame)
5149 && !NILP (Fequal (last_string, string))
5150 && !NILP (Fequal (last_parms, parms)))
5152 struct frame *f = XFRAME (tip_frame);
5154 /* Only DX and DY have changed. */
5155 if (!NILP (tip_timer))
5157 Lisp_Object timer = tip_timer;
5158 tip_timer = Qnil;
5159 call1 (Qcancel_timer, timer);
5162 BLOCK_INPUT;
5163 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
5164 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
5165 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5166 root_x, root_y);
5167 UNBLOCK_INPUT;
5168 goto start_timer;
5172 /* Hide a previous tip, if any. */
5173 Fx_hide_tip ();
5175 ASET (last_show_tip_args, 0, string);
5176 ASET (last_show_tip_args, 1, frame);
5177 ASET (last_show_tip_args, 2, parms);
5179 /* Add default values to frame parameters. */
5180 if (NILP (Fassq (Qname, parms)))
5181 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5182 if (NILP (Fassq (Qinternal_border_width, parms)))
5183 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5184 if (NILP (Fassq (Qborder_width, parms)))
5185 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5186 if (NILP (Fassq (Qborder_color, parms)))
5187 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5188 if (NILP (Fassq (Qbackground_color, parms)))
5189 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5190 parms);
5192 /* Create a frame for the tooltip, and record it in the global
5193 variable tip_frame. */
5194 frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
5195 f = XFRAME (frame);
5197 /* Set up the frame's root window. */
5198 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5199 w->left_col = w->top_line = make_number (0);
5201 if (CONSP (Vx_max_tooltip_size)
5202 && INTEGERP (XCAR (Vx_max_tooltip_size))
5203 && XINT (XCAR (Vx_max_tooltip_size)) > 0
5204 && INTEGERP (XCDR (Vx_max_tooltip_size))
5205 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5207 w->total_cols = XCAR (Vx_max_tooltip_size);
5208 w->total_lines = XCDR (Vx_max_tooltip_size);
5210 else
5212 w->total_cols = make_number (80);
5213 w->total_lines = make_number (40);
5216 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5217 adjust_glyphs (f);
5218 w->pseudo_window_p = 1;
5220 /* Display the tooltip text in a temporary buffer. */
5221 old_buffer = current_buffer;
5222 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5223 current_buffer->truncate_lines = Qnil;
5224 clear_glyph_matrix (w->desired_matrix);
5225 clear_glyph_matrix (w->current_matrix);
5226 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5227 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
5229 /* Compute width and height of the tooltip. */
5230 width = height = 0;
5231 for (i = 0; i < w->desired_matrix->nrows; ++i)
5233 struct glyph_row *row = &w->desired_matrix->rows[i];
5234 struct glyph *last;
5235 int row_width;
5237 /* Stop at the first empty row at the end. */
5238 if (!row->enabled_p || !row->displays_text_p)
5239 break;
5241 /* Let the row go over the full width of the frame. */
5242 row->full_width_p = 1;
5244 /* There's a glyph at the end of rows that is used to place
5245 the cursor there. Don't include the width of this glyph. */
5246 if (row->used[TEXT_AREA])
5248 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5249 row_width = row->pixel_width - last->pixel_width;
5251 else
5252 row_width = row->pixel_width;
5254 height += row->height;
5255 width = max (width, row_width);
5258 /* Add the frame's internal border to the width and height the X
5259 window should have. */
5260 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5261 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5263 /* Move the tooltip window where the mouse pointer is. Resize and
5264 show it. */
5265 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5267 BLOCK_INPUT;
5268 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5269 root_x, root_y, width, height);
5270 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5271 UNBLOCK_INPUT;
5273 /* Draw into the window. */
5274 w->must_be_updated_p = 1;
5275 update_single_window (w, 1);
5277 /* Restore original current buffer. */
5278 set_buffer_internal_1 (old_buffer);
5279 windows_or_buffers_changed = old_windows_or_buffers_changed;
5281 start_timer:
5282 /* Let the tip disappear after timeout seconds. */
5283 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5284 intern ("x-hide-tip"));
5286 UNGCPRO;
5287 return unbind_to (count, Qnil);
5291 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5292 doc: /* Hide the current tooltip window, if there is any.
5293 Value is t if tooltip was open, nil otherwise. */)
5296 int count;
5297 Lisp_Object deleted, frame, timer;
5298 struct gcpro gcpro1, gcpro2;
5300 /* Return quickly if nothing to do. */
5301 if (NILP (tip_timer) && NILP (tip_frame))
5302 return Qnil;
5304 frame = tip_frame;
5305 timer = tip_timer;
5306 GCPRO2 (frame, timer);
5307 tip_frame = tip_timer = deleted = Qnil;
5309 count = SPECPDL_INDEX ();
5310 specbind (Qinhibit_redisplay, Qt);
5311 specbind (Qinhibit_quit, Qt);
5313 if (!NILP (timer))
5314 call1 (Qcancel_timer, timer);
5316 if (FRAMEP (frame))
5318 delete_frame (frame, Qnil);
5319 deleted = Qt;
5321 #ifdef USE_LUCID
5322 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5323 redisplay procedure is not called when a tip frame over menu
5324 items is unmapped. Redisplay the menu manually... */
5326 struct frame *f = SELECTED_FRAME ();
5327 Widget w = f->output_data.x->menubar_widget;
5328 extern void xlwmenu_redisplay P_ ((Widget));
5330 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5331 && w != NULL)
5333 BLOCK_INPUT;
5334 xlwmenu_redisplay (w);
5335 UNBLOCK_INPUT;
5338 #endif /* USE_LUCID */
5341 UNGCPRO;
5342 return unbind_to (count, deleted);
5347 /***********************************************************************
5348 File selection dialog
5349 ***********************************************************************/
5351 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5352 Sx_uses_old_gtk_dialog,
5353 0, 0, 0,
5354 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5357 #ifdef USE_GTK
5358 extern int use_dialog_box;
5359 extern int use_file_dialog;
5361 if (use_dialog_box
5362 && use_file_dialog
5363 && have_menus_p ()
5364 && xg_uses_old_file_dialog ())
5365 return Qt;
5366 #endif
5367 return Qnil;
5371 #ifdef USE_MOTIF
5372 /* Callback for "OK" and "Cancel" on file selection dialog. */
5374 static void
5375 file_dialog_cb (widget, client_data, call_data)
5376 Widget widget;
5377 XtPointer call_data, client_data;
5379 int *result = (int *) client_data;
5380 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5381 *result = cb->reason;
5385 /* Callback for unmapping a file selection dialog. This is used to
5386 capture the case where a dialog is closed via a window manager's
5387 closer button, for example. Using a XmNdestroyCallback didn't work
5388 in this case. */
5390 static void
5391 file_dialog_unmap_cb (widget, client_data, call_data)
5392 Widget widget;
5393 XtPointer call_data, client_data;
5395 int *result = (int *) client_data;
5396 *result = XmCR_CANCEL;
5399 static Lisp_Object
5400 clean_up_file_dialog (arg)
5401 Lisp_Object arg;
5403 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5404 Widget dialog = (Widget) p->pointer;
5406 /* Clean up. */
5407 BLOCK_INPUT;
5408 XtUnmanageChild (dialog);
5409 XtDestroyWidget (dialog);
5410 x_menu_set_in_use (0);
5411 UNBLOCK_INPUT;
5413 return Qnil;
5417 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5418 doc: /* Read file name, prompting with PROMPT in directory DIR.
5419 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5420 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5421 or directory must exist. ONLY-DIR-P is ignored." */)
5422 (prompt, dir, default_filename, mustmatch, only_dir_p)
5423 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5425 int result;
5426 struct frame *f = SELECTED_FRAME ();
5427 Lisp_Object file = Qnil;
5428 Lisp_Object decoded_file;
5429 Widget dialog, text, help;
5430 Arg al[10];
5431 int ac = 0;
5432 extern XtAppContext Xt_app_con;
5433 XmString dir_xmstring, pattern_xmstring;
5434 int count = SPECPDL_INDEX ();
5435 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5437 check_x ();
5439 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5441 if (popup_activated ())
5442 error ("Trying to use a menu from within a menu-entry");
5444 CHECK_STRING (prompt);
5445 CHECK_STRING (dir);
5447 /* Prevent redisplay. */
5448 specbind (Qinhibit_redisplay, Qt);
5450 BLOCK_INPUT;
5452 /* Create the dialog with PROMPT as title, using DIR as initial
5453 directory and using "*" as pattern. */
5454 dir = Fexpand_file_name (dir, Qnil);
5455 dir_xmstring = XmStringCreateLocalized (SDATA (dir));
5456 pattern_xmstring = XmStringCreateLocalized ("*");
5458 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5459 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5460 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5461 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5462 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5463 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5464 "fsb", al, ac);
5465 XmStringFree (dir_xmstring);
5466 XmStringFree (pattern_xmstring);
5468 /* Add callbacks for OK and Cancel. */
5469 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5470 (XtPointer) &result);
5471 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5472 (XtPointer) &result);
5473 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5474 (XtPointer) &result);
5476 /* Remove the help button since we can't display help. */
5477 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5478 XtUnmanageChild (help);
5480 /* Mark OK button as default. */
5481 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5482 XmNshowAsDefault, True, NULL);
5484 /* If MUSTMATCH is non-nil, disable the file entry field of the
5485 dialog, so that the user must select a file from the files list
5486 box. We can't remove it because we wouldn't have a way to get at
5487 the result file name, then. */
5488 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5489 if (!NILP (mustmatch))
5491 Widget label;
5492 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5493 XtSetSensitive (text, False);
5494 XtSetSensitive (label, False);
5497 /* Manage the dialog, so that list boxes get filled. */
5498 XtManageChild (dialog);
5500 if (STRINGP (default_filename))
5502 XmString default_xmstring;
5503 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5504 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5506 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5507 XmTextFieldReplace (wtext, 0, last_pos,
5508 (SDATA (Ffile_name_nondirectory (default_filename))));
5510 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5511 must include the path for this to work. */
5513 default_xmstring = XmStringCreateLocalized (SDATA (default_filename));
5515 if (XmListItemExists (list, default_xmstring))
5517 int item_pos = XmListItemPos (list, default_xmstring);
5518 /* Select the item and scroll it into view. */
5519 XmListSelectPos (list, item_pos, True);
5520 XmListSetPos (list, item_pos);
5523 XmStringFree (default_xmstring);
5526 record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5528 /* Process events until the user presses Cancel or OK. */
5529 x_menu_set_in_use (1);
5530 result = 0;
5531 while (result == 0)
5533 XEvent event;
5534 x_menu_wait_for_event (0);
5535 XtAppNextEvent (Xt_app_con, &event);
5536 if (event.type == KeyPress
5537 && FRAME_X_DISPLAY (f) == event.xkey.display)
5539 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5541 /* Pop down on C-g. */
5542 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5543 XtUnmanageChild (dialog);
5546 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5549 /* Get the result. */
5550 if (result == XmCR_OK)
5552 XmString text;
5553 String data;
5555 XtVaGetValues (dialog, XmNtextString, &text, NULL);
5556 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
5557 XmStringFree (text);
5558 file = build_string (data);
5559 XtFree (data);
5561 else
5562 file = Qnil;
5564 UNBLOCK_INPUT;
5565 UNGCPRO;
5567 /* Make "Cancel" equivalent to C-g. */
5568 if (NILP (file))
5569 Fsignal (Qquit, Qnil);
5571 decoded_file = DECODE_FILE (file);
5573 return unbind_to (count, decoded_file);
5576 #endif /* USE_MOTIF */
5578 #ifdef USE_GTK
5580 static Lisp_Object
5581 clean_up_dialog (arg)
5582 Lisp_Object arg;
5584 x_menu_set_in_use (0);
5586 return Qnil;
5589 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5590 doc: /* Read file name, prompting with PROMPT in directory DIR.
5591 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5592 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5593 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5594 directories. */)
5595 (prompt, dir, default_filename, mustmatch, only_dir_p)
5596 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5598 FRAME_PTR f = SELECTED_FRAME ();
5599 char *fn;
5600 Lisp_Object file = Qnil;
5601 Lisp_Object decoded_file;
5602 int count = SPECPDL_INDEX ();
5603 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5604 char *cdef_file;
5606 check_x ();
5608 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5610 if (popup_activated ())
5611 error ("Trying to use a menu from within a menu-entry");
5613 CHECK_STRING (prompt);
5614 CHECK_STRING (dir);
5616 /* Prevent redisplay. */
5617 specbind (Qinhibit_redisplay, Qt);
5618 record_unwind_protect (clean_up_dialog, Qnil);
5620 BLOCK_INPUT;
5622 if (STRINGP (default_filename))
5623 cdef_file = SDATA (default_filename);
5624 else
5625 cdef_file = SDATA (dir);
5627 fn = xg_get_file_name (f, SDATA (prompt), cdef_file,
5628 ! NILP (mustmatch),
5629 ! NILP (only_dir_p));
5631 if (fn)
5633 file = build_string (fn);
5634 xfree (fn);
5637 UNBLOCK_INPUT;
5638 UNGCPRO;
5640 /* Make "Cancel" equivalent to C-g. */
5641 if (NILP (file))
5642 Fsignal (Qquit, Qnil);
5644 decoded_file = DECODE_FILE (file);
5646 return unbind_to (count, decoded_file);
5650 #ifdef HAVE_FREETYPE
5652 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5653 doc: /* Read a font name using a GTK font selection dialog.
5654 Return a GTK-style font string corresponding to the selection.
5656 If FRAME is omitted or nil, it defaults to the selected frame. */)
5657 (frame, ignored)
5658 Lisp_Object frame, ignored;
5660 FRAME_PTR f = check_x_frame (frame);
5661 char *name;
5662 Lisp_Object font;
5663 Lisp_Object font_param;
5664 char *default_name = NULL;
5665 struct gcpro gcpro1, gcpro2;
5666 int count = SPECPDL_INDEX ();
5668 check_x ();
5670 if (popup_activated ())
5671 error ("Trying to use a menu from within a menu-entry");
5673 /* Prevent redisplay. */
5674 specbind (Qinhibit_redisplay, Qt);
5675 record_unwind_protect (clean_up_dialog, Qnil);
5677 BLOCK_INPUT;
5679 GCPRO2(font_param, font);
5681 XSETFONT (font, FRAME_FONT (f));
5682 font_param = Ffont_get (font, intern (":name"));
5683 if (STRINGP (font_param))
5684 default_name = xstrdup (SDATA (font_param));
5685 else
5687 font_param = Fframe_parameter (frame, Qfont_param);
5688 if (STRINGP (font_param))
5689 default_name = xstrdup (SDATA (font_param));
5692 if (default_name == NULL && x_last_font_name != NULL)
5693 default_name = xstrdup (x_last_font_name);
5695 /* Convert fontconfig names to Gtk names, i.e. remove - before number */
5696 if (default_name)
5698 char *p = strrchr (default_name, '-');
5699 if (p)
5701 char *ep = p+1;
5702 while (isdigit (*ep))
5703 ++ep;
5704 if (*ep == '\0') *p = ' ';
5708 name = xg_get_font_name (f, default_name);
5709 xfree (default_name);
5711 if (name)
5713 font = build_string (name);
5714 g_free (x_last_font_name);
5715 x_last_font_name = name;
5718 UNBLOCK_INPUT;
5720 if (NILP (font))
5721 Fsignal (Qquit, Qnil);
5723 return unbind_to (count, font);
5725 #endif /* HAVE_FREETYPE */
5727 #endif /* USE_GTK */
5730 /***********************************************************************
5731 Keyboard
5732 ***********************************************************************/
5734 #ifdef HAVE_XKBGETKEYBOARD
5735 #include <X11/XKBlib.h>
5736 #include <X11/keysym.h>
5737 #endif
5739 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5740 Sx_backspace_delete_keys_p, 0, 1, 0,
5741 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5742 FRAME nil means use the selected frame.
5743 Value is t if we know that both keys are present, and are mapped to the
5744 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5745 present and mapped to the usual X keysyms. */)
5746 (frame)
5747 Lisp_Object frame;
5749 #ifdef HAVE_XKBGETKEYBOARD
5750 XkbDescPtr kb;
5751 struct frame *f = check_x_frame (frame);
5752 Display *dpy = FRAME_X_DISPLAY (f);
5753 Lisp_Object have_keys;
5754 int major, minor, op, event, error;
5756 BLOCK_INPUT;
5758 /* Check library version in case we're dynamically linked. */
5759 major = XkbMajorVersion;
5760 minor = XkbMinorVersion;
5761 if (!XkbLibraryVersion (&major, &minor))
5763 UNBLOCK_INPUT;
5764 return Qlambda;
5767 /* Check that the server supports XKB. */
5768 major = XkbMajorVersion;
5769 minor = XkbMinorVersion;
5770 if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
5772 UNBLOCK_INPUT;
5773 return Qlambda;
5776 /* In this code we check that the keyboard has physical keys with names
5777 that start with BKSP (Backspace) and DELE (Delete), and that they
5778 generate keysym XK_BackSpace and XK_Delete respectively.
5779 This function is used to test if normal-erase-is-backspace should be
5780 turned on.
5781 An alternative approach would be to just check if XK_BackSpace and
5782 XK_Delete are mapped to any key. But if any of those are mapped to
5783 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5784 user doesn't know about it, it is better to return false here.
5785 It is more obvious to the user what to do if she/he has two keys
5786 clearly marked with names/symbols and one key does something not
5787 expected (i.e. she/he then tries the other).
5788 The cases where Backspace/Delete is mapped to some other key combination
5789 are rare, and in those cases, normal-erase-is-backspace can be turned on
5790 manually. */
5792 have_keys = Qnil;
5793 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5794 if (kb)
5796 int delete_keycode = 0, backspace_keycode = 0, i;
5798 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5800 for (i = kb->min_key_code;
5801 (i < kb->max_key_code
5802 && (delete_keycode == 0 || backspace_keycode == 0));
5803 ++i)
5805 /* The XKB symbolic key names can be seen most easily in
5806 the PS file generated by `xkbprint -label name
5807 $DISPLAY'. */
5808 if (bcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5809 delete_keycode = i;
5810 else if (bcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5811 backspace_keycode = i;
5814 XkbFreeNames (kb, 0, True);
5817 XkbFreeClientMap (kb, 0, True);
5819 if (delete_keycode
5820 && backspace_keycode
5821 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5822 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5823 have_keys = Qt;
5825 UNBLOCK_INPUT;
5826 return have_keys;
5827 #else /* not HAVE_XKBGETKEYBOARD */
5828 return Qlambda;
5829 #endif /* not HAVE_XKBGETKEYBOARD */
5834 /***********************************************************************
5835 Initialization
5836 ***********************************************************************/
5838 /* Keep this list in the same order as frame_parms in frame.c.
5839 Use 0 for unsupported frame parameters. */
5841 frame_parm_handler x_frame_parm_handlers[] =
5843 x_set_autoraise,
5844 x_set_autolower,
5845 x_set_background_color,
5846 x_set_border_color,
5847 x_set_border_width,
5848 x_set_cursor_color,
5849 x_set_cursor_type,
5850 x_set_font,
5851 x_set_foreground_color,
5852 x_set_icon_name,
5853 x_set_icon_type,
5854 x_set_internal_border_width,
5855 x_set_menu_bar_lines,
5856 x_set_mouse_color,
5857 x_explicitly_set_name,
5858 x_set_scroll_bar_width,
5859 x_set_title,
5860 x_set_unsplittable,
5861 x_set_vertical_scroll_bars,
5862 x_set_visibility,
5863 x_set_tool_bar_lines,
5864 x_set_scroll_bar_foreground,
5865 x_set_scroll_bar_background,
5866 x_set_screen_gamma,
5867 x_set_line_spacing,
5868 x_set_fringe_width,
5869 x_set_fringe_width,
5870 x_set_wait_for_wm,
5871 x_set_fullscreen,
5872 x_set_font_backend,
5873 x_set_alpha,
5874 x_set_sticky,
5877 void
5878 syms_of_xfns ()
5880 /* This is zero if not using X windows. */
5881 x_in_use = 0;
5883 /* The section below is built by the lisp expression at the top of the file,
5884 just above where these variables are declared. */
5885 /*&&& init symbols here &&&*/
5886 Qnone = intern_c_string ("none");
5887 staticpro (&Qnone);
5888 Qsuppress_icon = intern_c_string ("suppress-icon");
5889 staticpro (&Qsuppress_icon);
5890 Qundefined_color = intern_c_string ("undefined-color");
5891 staticpro (&Qundefined_color);
5892 Qcompound_text = intern_c_string ("compound-text");
5893 staticpro (&Qcompound_text);
5894 Qcancel_timer = intern_c_string ("cancel-timer");
5895 staticpro (&Qcancel_timer);
5896 Qfont_param = intern_c_string ("font-parameter");
5897 staticpro (&Qfont_param);
5898 /* This is the end of symbol initialization. */
5900 /* Text property `display' should be nonsticky by default. */
5901 Vtext_property_default_nonsticky
5902 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
5905 Fput (Qundefined_color, Qerror_conditions,
5906 pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
5907 Fput (Qundefined_color, Qerror_message,
5908 make_pure_c_string ("Undefined color"));
5910 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
5911 doc: /* The shape of the pointer when over text.
5912 Changing the value does not affect existing frames
5913 unless you set the mouse color. */);
5914 Vx_pointer_shape = Qnil;
5916 #if 0 /* This doesn't really do anything. */
5917 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
5918 doc: /* The shape of the pointer when not over text.
5919 This variable takes effect when you create a new frame
5920 or when you set the mouse color. */);
5921 #endif
5922 Vx_nontext_pointer_shape = Qnil;
5924 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
5925 doc: /* The shape of the pointer when Emacs is busy.
5926 This variable takes effect when you create a new frame
5927 or when you set the mouse color. */);
5928 Vx_hourglass_pointer_shape = Qnil;
5930 #if 0 /* This doesn't really do anything. */
5931 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
5932 doc: /* The shape of the pointer when over the mode line.
5933 This variable takes effect when you create a new frame
5934 or when you set the mouse color. */);
5935 #endif
5936 Vx_mode_pointer_shape = Qnil;
5938 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5939 &Vx_sensitive_text_pointer_shape,
5940 doc: /* The shape of the pointer when over mouse-sensitive text.
5941 This variable takes effect when you create a new frame
5942 or when you set the mouse color. */);
5943 Vx_sensitive_text_pointer_shape = Qnil;
5945 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5946 &Vx_window_horizontal_drag_shape,
5947 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
5948 This variable takes effect when you create a new frame
5949 or when you set the mouse color. */);
5950 Vx_window_horizontal_drag_shape = Qnil;
5952 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
5953 doc: /* A string indicating the foreground color of the cursor box. */);
5954 Vx_cursor_fore_pixel = Qnil;
5956 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
5957 doc: /* Maximum size for tooltips.
5958 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
5959 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
5961 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
5962 doc: /* Non-nil if no X window manager is in use.
5963 Emacs doesn't try to figure this out; this is always nil
5964 unless you set it to something else. */);
5965 /* We don't have any way to find this out, so set it to nil
5966 and maybe the user would like to set it to t. */
5967 Vx_no_window_manager = Qnil;
5969 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5970 &Vx_pixel_size_width_font_regexp,
5971 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5973 Since Emacs gets width of a font matching with this regexp from
5974 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5975 such a font. This is especially effective for such large fonts as
5976 Chinese, Japanese, and Korean. */);
5977 Vx_pixel_size_width_font_regexp = Qnil;
5979 /* This is not ifdef:ed, so other builds than GTK can customize it. */
5980 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog,
5981 doc: /* *Non-nil means prompt with the old GTK file selection dialog.
5982 If nil or if the file selection dialog is not available, the new GTK file
5983 chooser is used instead. To turn off all file dialogs set the
5984 variable `use-file-dialog'. */);
5985 x_gtk_use_old_file_dialog = 0;
5987 DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files,
5988 doc: /* *If non-nil, the GTK file chooser will by default show hidden files.
5989 Note that this is just the default, there is a toggle button on the file
5990 chooser to show or not show hidden files on a case by case basis. */);
5991 x_gtk_show_hidden_files = 0;
5993 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text,
5994 doc: /* *If non-nil, the GTK file chooser will show additional help text.
5995 If more space for files in the file chooser dialog is wanted, set this to nil
5996 to turn the additional text off. */);
5997 x_gtk_file_dialog_help_text = 1;
5999 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar,
6000 doc: /* *If non-nil, a detached tool bar is shown in full.
6001 The default is to just show an arrow and pressing on that arrow shows
6002 the tool bar buttons. */);
6003 x_gtk_whole_detached_tool_bar = 0;
6005 Fprovide (intern_c_string ("x"), Qnil);
6007 #ifdef USE_X_TOOLKIT
6008 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6009 #ifdef USE_MOTIF
6010 Fprovide (intern_c_string ("motif"), Qnil);
6012 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
6013 doc: /* Version info for LessTif/Motif. */);
6014 Vmotif_version_string = build_string (XmVERSION_STRING);
6015 #endif /* USE_MOTIF */
6016 #endif /* USE_X_TOOLKIT */
6018 #ifdef USE_GTK
6019 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6020 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6021 But for a user it is a toolkit for X, and indeed, configure
6022 accepts --with-x-toolkit=gtk. */
6023 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6024 Fprovide (intern_c_string ("gtk"), Qnil);
6026 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
6027 doc: /* Version info for GTK+. */);
6029 char gtk_version[40];
6030 g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
6031 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
6032 Vgtk_version_string = make_pure_string (gtk_version, strlen (gtk_version), strlen (gtk_version), 0);
6034 #endif /* USE_GTK */
6036 /* X window properties. */
6037 defsubr (&Sx_change_window_property);
6038 defsubr (&Sx_delete_window_property);
6039 defsubr (&Sx_window_property);
6041 defsubr (&Sxw_display_color_p);
6042 defsubr (&Sx_display_grayscale_p);
6043 defsubr (&Sxw_color_defined_p);
6044 defsubr (&Sxw_color_values);
6045 defsubr (&Sx_server_max_request_size);
6046 defsubr (&Sx_server_vendor);
6047 defsubr (&Sx_server_version);
6048 defsubr (&Sx_display_pixel_width);
6049 defsubr (&Sx_display_pixel_height);
6050 defsubr (&Sx_display_mm_width);
6051 defsubr (&Sx_display_mm_height);
6052 defsubr (&Sx_display_screens);
6053 defsubr (&Sx_display_planes);
6054 defsubr (&Sx_display_color_cells);
6055 defsubr (&Sx_display_visual_class);
6056 defsubr (&Sx_display_backing_store);
6057 defsubr (&Sx_display_save_under);
6058 defsubr (&Sx_wm_set_size_hint);
6059 defsubr (&Sx_create_frame);
6060 defsubr (&Sx_open_connection);
6061 defsubr (&Sx_close_connection);
6062 defsubr (&Sx_display_list);
6063 defsubr (&Sx_synchronize);
6064 defsubr (&Sx_focus_frame);
6065 defsubr (&Sx_backspace_delete_keys_p);
6067 /* Setting callback functions for fontset handler. */
6068 check_window_system_func = check_x;
6070 defsubr (&Sx_show_tip);
6071 defsubr (&Sx_hide_tip);
6072 tip_timer = Qnil;
6073 staticpro (&tip_timer);
6074 tip_frame = Qnil;
6075 staticpro (&tip_frame);
6077 last_show_tip_args = Qnil;
6078 staticpro (&last_show_tip_args);
6080 defsubr (&Sx_uses_old_gtk_dialog);
6081 #if defined (USE_MOTIF) || defined (USE_GTK)
6082 defsubr (&Sx_file_dialog);
6083 #endif
6085 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6086 defsubr (&Sx_select_font);
6087 x_last_font_name = NULL;
6088 #endif
6091 #endif /* HAVE_X_WINDOWS */
6093 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
6094 (do not change this comment) */