merge emacs-23
[emacs.git] / src / xfns.c
blob44d8fb31f2e0b026676c09d7816e1a347acbb967
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, 2011
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;
648 long *fe = (long *)tmp_data;
650 XGetGeometry (FRAME_X_DISPLAY (f), win,
651 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
652 outer_x = -fe[0];
653 outer_y = -fe[2];
654 real_x -= fe[0];
655 real_y -= fe[2];
659 if (tmp_data) XFree (tmp_data);
661 x_uncatch_errors ();
663 UNBLOCK_INPUT;
665 if (had_errors) return;
667 f->x_pixels_diff = -win_x;
668 f->y_pixels_diff = -win_y;
670 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
671 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
673 *xptr = real_x;
674 *yptr = real_y;
680 /* Gamma-correct COLOR on frame F. */
682 void
683 gamma_correct (f, color)
684 struct frame *f;
685 XColor *color;
687 if (f->gamma)
689 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
690 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
691 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
696 /* Decide if color named COLOR_NAME is valid for use on frame F. If
697 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
698 allocate the color. Value is zero if COLOR_NAME is invalid, or
699 no color could be allocated. */
702 x_defined_color (f, color_name, color, alloc_p)
703 struct frame *f;
704 char *color_name;
705 XColor *color;
706 int alloc_p;
708 int success_p;
709 Display *dpy = FRAME_X_DISPLAY (f);
710 Colormap cmap = FRAME_X_COLORMAP (f);
712 BLOCK_INPUT;
713 success_p = XParseColor (dpy, cmap, color_name, color);
714 if (success_p && alloc_p)
715 success_p = x_alloc_nearest_color (f, cmap, color);
716 UNBLOCK_INPUT;
718 return success_p;
722 /* Return the pixel color value for color COLOR_NAME on frame F. If F
723 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
724 Signal an error if color can't be allocated. */
727 x_decode_color (f, color_name, mono_color)
728 FRAME_PTR f;
729 Lisp_Object color_name;
730 int mono_color;
732 XColor cdef;
734 CHECK_STRING (color_name);
736 #if 0 /* Don't do this. It's wrong when we're not using the default
737 colormap, it makes freeing difficult, and it's probably not
738 an important optimization. */
739 if (strcmp (SDATA (color_name), "black") == 0)
740 return BLACK_PIX_DEFAULT (f);
741 else if (strcmp (SDATA (color_name), "white") == 0)
742 return WHITE_PIX_DEFAULT (f);
743 #endif
745 /* Return MONO_COLOR for monochrome frames. */
746 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
747 return mono_color;
749 /* x_defined_color is responsible for coping with failures
750 by looking for a near-miss. */
751 if (x_defined_color (f, SDATA (color_name), &cdef, 1))
752 return cdef.pixel;
754 signal_error ("Undefined color", color_name);
759 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
760 the previous value of that parameter, NEW_VALUE is the new value.
761 See also the comment of wait_for_wm in struct x_output. */
763 static void
764 x_set_wait_for_wm (f, new_value, old_value)
765 struct frame *f;
766 Lisp_Object new_value, old_value;
768 f->output_data.x->wait_for_wm = !NILP (new_value);
771 #ifdef USE_GTK
773 /* Set icon from FILE for frame F. By using GTK functions the icon
774 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
777 xg_set_icon (f, file)
778 FRAME_PTR f;
779 Lisp_Object file;
781 int result = 0;
782 Lisp_Object found;
784 found = x_find_image_file (file);
786 if (! NILP (found))
788 GdkPixbuf *pixbuf;
789 GError *err = NULL;
790 char *filename = (char *) SDATA (found);
791 BLOCK_INPUT;
793 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
795 if (pixbuf)
797 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
798 pixbuf);
799 g_object_unref (pixbuf);
801 result = 1;
803 else
804 g_error_free (err);
806 UNBLOCK_INPUT;
809 return result;
813 xg_set_icon_from_xpm_data (f, data)
814 FRAME_PTR f;
815 char **data;
817 int result = 0;
818 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data);
820 if (!pixbuf)
821 return 0;
823 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
824 g_object_unref (pixbuf);
825 return 1;
827 #endif /* USE_GTK */
830 /* Functions called only from `x_set_frame_param'
831 to set individual parameters.
833 If FRAME_X_WINDOW (f) is 0,
834 the frame is being created and its X-window does not exist yet.
835 In that case, just record the parameter's new value
836 in the standard place; do not attempt to change the window. */
838 void
839 x_set_foreground_color (f, arg, oldval)
840 struct frame *f;
841 Lisp_Object arg, oldval;
843 struct x_output *x = f->output_data.x;
844 unsigned long fg, old_fg;
846 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
847 old_fg = FRAME_FOREGROUND_PIXEL (f);
848 FRAME_FOREGROUND_PIXEL (f) = fg;
850 if (FRAME_X_WINDOW (f) != 0)
852 Display *dpy = FRAME_X_DISPLAY (f);
854 BLOCK_INPUT;
855 XSetForeground (dpy, x->normal_gc, fg);
856 XSetBackground (dpy, x->reverse_gc, fg);
858 if (x->cursor_pixel == old_fg)
860 unload_color (f, x->cursor_pixel);
861 x->cursor_pixel = x_copy_color (f, fg);
862 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
865 UNBLOCK_INPUT;
867 update_face_from_frame_parameter (f, Qforeground_color, arg);
869 if (FRAME_VISIBLE_P (f))
870 redraw_frame (f);
873 unload_color (f, old_fg);
876 void
877 x_set_background_color (f, arg, oldval)
878 struct frame *f;
879 Lisp_Object arg, oldval;
881 struct x_output *x = f->output_data.x;
882 unsigned long bg;
884 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
885 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
886 FRAME_BACKGROUND_PIXEL (f) = bg;
888 if (FRAME_X_WINDOW (f) != 0)
890 Display *dpy = FRAME_X_DISPLAY (f);
892 BLOCK_INPUT;
893 XSetBackground (dpy, x->normal_gc, bg);
894 XSetForeground (dpy, x->reverse_gc, bg);
895 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
896 XSetForeground (dpy, x->cursor_gc, bg);
898 #ifdef USE_GTK
899 xg_set_background_color (f, bg);
900 #endif
902 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
903 toolkit scroll bars. */
905 Lisp_Object bar;
906 for (bar = FRAME_SCROLL_BARS (f);
907 !NILP (bar);
908 bar = XSCROLL_BAR (bar)->next)
910 Window window = XSCROLL_BAR (bar)->x_window;
911 XSetWindowBackground (dpy, window, bg);
914 #endif /* USE_TOOLKIT_SCROLL_BARS */
916 UNBLOCK_INPUT;
917 update_face_from_frame_parameter (f, Qbackground_color, arg);
919 if (FRAME_VISIBLE_P (f))
920 redraw_frame (f);
924 static Cursor
925 make_invisible_cursor (f)
926 struct frame *f;
928 Display *dpy = FRAME_X_DISPLAY (f);
929 static char const no_data[] = { 0 };
930 Pixmap pix;
931 XColor col;
932 Cursor c;
934 x_catch_errors (dpy);
935 pix = XCreateBitmapFromData (dpy, FRAME_X_DISPLAY_INFO (f)->root_window,
936 no_data, 1, 1);
937 if (! x_had_errors_p (dpy) && pix != None)
939 col.pixel = 0;
940 col.red = col.green = col.blue = 0;
941 col.flags = DoRed | DoGreen | DoBlue;
942 c = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
943 if (x_had_errors_p (dpy) || c == None)
944 c = 0;
945 XFreePixmap (dpy, pix);
948 x_uncatch_errors ();
950 return c;
953 void
954 x_set_mouse_color (f, arg, oldval)
955 struct frame *f;
956 Lisp_Object arg, oldval;
958 struct x_output *x = f->output_data.x;
959 Display *dpy = FRAME_X_DISPLAY (f);
960 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
961 Cursor hourglass_cursor, horizontal_drag_cursor;
962 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
963 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
965 /* Don't let pointers be invisible. */
966 if (mask_color == pixel)
968 x_free_colors (f, &pixel, 1);
969 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
972 unload_color (f, x->mouse_pixel);
973 x->mouse_pixel = pixel;
975 BLOCK_INPUT;
977 /* It's not okay to crash if the user selects a screwy cursor. */
978 x_catch_errors (dpy);
980 if (!NILP (Vx_pointer_shape))
982 CHECK_NUMBER (Vx_pointer_shape);
983 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
985 else
986 cursor = XCreateFontCursor (dpy, XC_xterm);
987 x_check_errors (dpy, "bad text pointer cursor: %s");
989 if (!NILP (Vx_nontext_pointer_shape))
991 CHECK_NUMBER (Vx_nontext_pointer_shape);
992 nontext_cursor
993 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
995 else
996 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
997 x_check_errors (dpy, "bad nontext pointer cursor: %s");
999 if (!NILP (Vx_hourglass_pointer_shape))
1001 CHECK_NUMBER (Vx_hourglass_pointer_shape);
1002 hourglass_cursor
1003 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
1005 else
1006 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
1007 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
1009 if (!NILP (Vx_mode_pointer_shape))
1011 CHECK_NUMBER (Vx_mode_pointer_shape);
1012 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
1014 else
1015 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
1016 x_check_errors (dpy, "bad modeline pointer cursor: %s");
1018 if (!NILP (Vx_sensitive_text_pointer_shape))
1020 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1021 hand_cursor
1022 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
1024 else
1025 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
1027 if (!NILP (Vx_window_horizontal_drag_shape))
1029 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1030 horizontal_drag_cursor
1031 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
1033 else
1034 horizontal_drag_cursor
1035 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
1037 /* Check and report errors with the above calls. */
1038 x_check_errors (dpy, "can't set cursor shape: %s");
1039 x_uncatch_errors ();
1042 XColor fore_color, back_color;
1044 fore_color.pixel = x->mouse_pixel;
1045 x_query_color (f, &fore_color);
1046 back_color.pixel = mask_color;
1047 x_query_color (f, &back_color);
1049 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1050 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1051 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1052 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1053 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1054 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1057 if (FRAME_X_WINDOW (f) != 0)
1058 XDefineCursor (dpy, FRAME_X_WINDOW (f),
1059 f->output_data.x->current_cursor = cursor);
1061 if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor == 0)
1062 FRAME_X_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
1064 if (cursor != x->text_cursor
1065 && x->text_cursor != 0)
1066 XFreeCursor (dpy, x->text_cursor);
1067 x->text_cursor = cursor;
1069 if (nontext_cursor != x->nontext_cursor
1070 && x->nontext_cursor != 0)
1071 XFreeCursor (dpy, x->nontext_cursor);
1072 x->nontext_cursor = nontext_cursor;
1074 if (hourglass_cursor != x->hourglass_cursor
1075 && x->hourglass_cursor != 0)
1076 XFreeCursor (dpy, x->hourglass_cursor);
1077 x->hourglass_cursor = hourglass_cursor;
1079 if (mode_cursor != x->modeline_cursor
1080 && x->modeline_cursor != 0)
1081 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1082 x->modeline_cursor = mode_cursor;
1084 if (hand_cursor != x->hand_cursor
1085 && x->hand_cursor != 0)
1086 XFreeCursor (dpy, x->hand_cursor);
1087 x->hand_cursor = hand_cursor;
1089 if (horizontal_drag_cursor != x->horizontal_drag_cursor
1090 && x->horizontal_drag_cursor != 0)
1091 XFreeCursor (dpy, x->horizontal_drag_cursor);
1092 x->horizontal_drag_cursor = horizontal_drag_cursor;
1094 XFlush (dpy);
1095 UNBLOCK_INPUT;
1097 update_face_from_frame_parameter (f, Qmouse_color, arg);
1100 void
1101 x_set_cursor_color (f, arg, oldval)
1102 struct frame *f;
1103 Lisp_Object arg, oldval;
1105 unsigned long fore_pixel, pixel;
1106 int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
1107 struct x_output *x = f->output_data.x;
1109 if (!NILP (Vx_cursor_fore_pixel))
1111 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1112 WHITE_PIX_DEFAULT (f));
1113 fore_pixel_allocated_p = 1;
1115 else
1116 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1118 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1119 pixel_allocated_p = 1;
1121 /* Make sure that the cursor color differs from the background color. */
1122 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1124 if (pixel_allocated_p)
1126 x_free_colors (f, &pixel, 1);
1127 pixel_allocated_p = 0;
1130 pixel = x->mouse_pixel;
1131 if (pixel == fore_pixel)
1133 if (fore_pixel_allocated_p)
1135 x_free_colors (f, &fore_pixel, 1);
1136 fore_pixel_allocated_p = 0;
1138 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1142 unload_color (f, x->cursor_foreground_pixel);
1143 if (!fore_pixel_allocated_p)
1144 fore_pixel = x_copy_color (f, fore_pixel);
1145 x->cursor_foreground_pixel = fore_pixel;
1147 unload_color (f, x->cursor_pixel);
1148 if (!pixel_allocated_p)
1149 pixel = x_copy_color (f, pixel);
1150 x->cursor_pixel = pixel;
1152 if (FRAME_X_WINDOW (f) != 0)
1154 BLOCK_INPUT;
1155 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1156 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1157 UNBLOCK_INPUT;
1159 if (FRAME_VISIBLE_P (f))
1161 x_update_cursor (f, 0);
1162 x_update_cursor (f, 1);
1166 update_face_from_frame_parameter (f, Qcursor_color, arg);
1169 /* Set the border-color of frame F to pixel value PIX.
1170 Note that this does not fully take effect if done before
1171 F has an x-window. */
1173 void
1174 x_set_border_pixel (f, pix)
1175 struct frame *f;
1176 int pix;
1178 unload_color (f, f->output_data.x->border_pixel);
1179 f->output_data.x->border_pixel = pix;
1181 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1183 BLOCK_INPUT;
1184 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1185 (unsigned long)pix);
1186 UNBLOCK_INPUT;
1188 if (FRAME_VISIBLE_P (f))
1189 redraw_frame (f);
1193 /* Set the border-color of frame F to value described by ARG.
1194 ARG can be a string naming a color.
1195 The border-color is used for the border that is drawn by the X server.
1196 Note that this does not fully take effect if done before
1197 F has an x-window; it must be redone when the window is created.
1199 Note: this is done in two routines because of the way X10 works.
1201 Note: under X11, this is normally the province of the window manager,
1202 and so emacs' border colors may be overridden. */
1204 void
1205 x_set_border_color (f, arg, oldval)
1206 struct frame *f;
1207 Lisp_Object arg, oldval;
1209 int pix;
1211 CHECK_STRING (arg);
1212 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1213 x_set_border_pixel (f, pix);
1214 update_face_from_frame_parameter (f, Qborder_color, arg);
1218 void
1219 x_set_cursor_type (f, arg, oldval)
1220 FRAME_PTR f;
1221 Lisp_Object arg, oldval;
1223 set_frame_cursor_types (f, arg);
1225 /* Make sure the cursor gets redrawn. */
1226 cursor_type_changed = 1;
1229 void
1230 x_set_icon_type (f, arg, oldval)
1231 struct frame *f;
1232 Lisp_Object arg, oldval;
1234 int result;
1236 if (STRINGP (arg))
1238 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1239 return;
1241 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1242 return;
1244 BLOCK_INPUT;
1245 if (NILP (arg))
1246 result = x_text_icon (f,
1247 (char *) SDATA ((!NILP (f->icon_name)
1248 ? f->icon_name
1249 : f->name)));
1250 else
1251 result = x_bitmap_icon (f, arg);
1253 if (result)
1255 UNBLOCK_INPUT;
1256 error ("No icon window available");
1259 XFlush (FRAME_X_DISPLAY (f));
1260 UNBLOCK_INPUT;
1263 void
1264 x_set_icon_name (f, arg, oldval)
1265 struct frame *f;
1266 Lisp_Object arg, oldval;
1268 int result;
1270 if (STRINGP (arg))
1272 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1273 return;
1275 else if (!NILP (arg) || NILP (oldval))
1276 return;
1278 f->icon_name = arg;
1280 if (f->output_data.x->icon_bitmap != 0)
1281 return;
1283 BLOCK_INPUT;
1285 result = x_text_icon (f,
1286 (char *) SDATA ((!NILP (f->icon_name)
1287 ? f->icon_name
1288 : !NILP (f->title)
1289 ? f->title
1290 : f->name)));
1292 if (result)
1294 UNBLOCK_INPUT;
1295 error ("No icon window available");
1298 XFlush (FRAME_X_DISPLAY (f));
1299 UNBLOCK_INPUT;
1303 void
1304 x_set_menu_bar_lines (f, value, oldval)
1305 struct frame *f;
1306 Lisp_Object value, oldval;
1308 int nlines;
1309 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1310 int olines = FRAME_MENU_BAR_LINES (f);
1311 #endif
1313 /* Right now, menu bars don't work properly in minibuf-only frames;
1314 most of the commands try to apply themselves to the minibuffer
1315 frame itself, and get an error because you can't switch buffers
1316 in or split the minibuffer window. */
1317 if (FRAME_MINIBUF_ONLY_P (f))
1318 return;
1320 if (INTEGERP (value))
1321 nlines = XINT (value);
1322 else
1323 nlines = 0;
1325 /* Make sure we redisplay all windows in this frame. */
1326 windows_or_buffers_changed++;
1328 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1329 FRAME_MENU_BAR_LINES (f) = 0;
1330 if (nlines)
1332 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1333 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1334 /* Make sure next redisplay shows the menu bar. */
1335 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1337 else
1339 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1340 free_frame_menubar (f);
1341 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1342 if (FRAME_X_P (f))
1343 f->output_data.x->menubar_widget = 0;
1345 #else /* not USE_X_TOOLKIT && not USE_GTK */
1346 FRAME_MENU_BAR_LINES (f) = nlines;
1347 change_window_heights (f->root_window, nlines - olines);
1349 /* If the menu bar height gets changed, the internal border below
1350 the top margin has to be cleared. Also, if the menu bar gets
1351 larger, the area for the added lines has to be cleared except for
1352 the first menu bar line that is to be drawn later. */
1353 if (nlines != olines)
1355 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1356 int width = FRAME_PIXEL_WIDTH (f);
1357 int y;
1359 /* height can be zero here. */
1360 if (height > 0 && width > 0)
1362 y = FRAME_TOP_MARGIN_HEIGHT (f);
1364 BLOCK_INPUT;
1365 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1366 0, y, width, height, False);
1367 UNBLOCK_INPUT;
1370 if (nlines > 1 && nlines > olines)
1372 y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
1373 height = nlines * FRAME_LINE_HEIGHT (f) - y;
1375 BLOCK_INPUT;
1376 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1377 0, y, width, height, False);
1378 UNBLOCK_INPUT;
1381 if (nlines == 0 && WINDOWP (f->menu_bar_window))
1382 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
1384 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1385 adjust_glyphs (f);
1389 /* Set the number of lines used for the tool bar of frame F to VALUE.
1390 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1391 is the old number of tool bar lines. This function changes the
1392 height of all windows on frame F to match the new tool bar height.
1393 The frame's height doesn't change. */
1395 void
1396 x_set_tool_bar_lines (f, value, oldval)
1397 struct frame *f;
1398 Lisp_Object value, oldval;
1400 int delta, nlines, root_height;
1401 Lisp_Object root_window;
1403 /* Treat tool bars like menu bars. */
1404 if (FRAME_MINIBUF_ONLY_P (f))
1405 return;
1407 /* Use VALUE only if an integer >= 0. */
1408 if (INTEGERP (value) && XINT (value) >= 0)
1409 nlines = XFASTINT (value);
1410 else
1411 nlines = 0;
1413 #ifdef USE_GTK
1414 FRAME_TOOL_BAR_LINES (f) = 0;
1415 if (nlines)
1417 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1418 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1419 /* Make sure next redisplay shows the tool bar. */
1420 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1421 update_frame_tool_bar (f);
1423 else
1425 if (FRAME_EXTERNAL_TOOL_BAR (f))
1426 free_frame_tool_bar (f);
1427 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1430 return;
1431 #endif
1433 /* Make sure we redisplay all windows in this frame. */
1434 ++windows_or_buffers_changed;
1436 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1438 /* Don't resize the tool-bar to more than we have room for. */
1439 root_window = FRAME_ROOT_WINDOW (f);
1440 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1441 if (root_height - delta < 1)
1443 delta = root_height - 1;
1444 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1447 FRAME_TOOL_BAR_LINES (f) = nlines;
1448 change_window_heights (root_window, delta);
1449 adjust_glyphs (f);
1451 /* We also have to make sure that the internal border at the top of
1452 the frame, below the menu bar or tool bar, is redrawn when the
1453 tool bar disappears. This is so because the internal border is
1454 below the tool bar if one is displayed, but is below the menu bar
1455 if there isn't a tool bar. The tool bar draws into the area
1456 below the menu bar. */
1457 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1459 clear_frame (f);
1460 clear_current_matrices (f);
1463 /* If the tool bar gets smaller, the internal border below it
1464 has to be cleared. It was formerly part of the display
1465 of the larger tool bar, and updating windows won't clear it. */
1466 if (delta < 0)
1468 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1469 int width = FRAME_PIXEL_WIDTH (f);
1470 int y = (FRAME_MENU_BAR_LINES (f) + nlines) * FRAME_LINE_HEIGHT (f);
1472 /* height can be zero here. */
1473 if (height > 0 && width > 0)
1475 BLOCK_INPUT;
1476 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1477 0, y, width, height, False);
1478 UNBLOCK_INPUT;
1481 if (WINDOWP (f->tool_bar_window))
1482 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1487 /* Set the foreground color for scroll bars on frame F to VALUE.
1488 VALUE should be a string, a color name. If it isn't a string or
1489 isn't a valid color name, do nothing. OLDVAL is the old value of
1490 the frame parameter. */
1492 void
1493 x_set_scroll_bar_foreground (f, value, oldval)
1494 struct frame *f;
1495 Lisp_Object value, oldval;
1497 unsigned long pixel;
1499 if (STRINGP (value))
1500 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1501 else
1502 pixel = -1;
1504 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1505 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1507 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1508 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1510 /* Remove all scroll bars because they have wrong colors. */
1511 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1512 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1513 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1514 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1516 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1517 redraw_frame (f);
1522 /* Set the background color for scroll bars on frame F to VALUE VALUE
1523 should be a string, a color name. If it isn't a string or isn't a
1524 valid color name, do nothing. OLDVAL is the old value of the frame
1525 parameter. */
1527 void
1528 x_set_scroll_bar_background (f, value, oldval)
1529 struct frame *f;
1530 Lisp_Object value, oldval;
1532 unsigned long pixel;
1534 if (STRINGP (value))
1535 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1536 else
1537 pixel = -1;
1539 if (f->output_data.x->scroll_bar_background_pixel != -1)
1540 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1542 #ifdef USE_TOOLKIT_SCROLL_BARS
1543 /* Scrollbar shadow colors. */
1544 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1546 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1547 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1549 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1551 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1552 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1554 #endif /* USE_TOOLKIT_SCROLL_BARS */
1556 f->output_data.x->scroll_bar_background_pixel = pixel;
1557 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1559 /* Remove all scroll bars because they have wrong colors. */
1560 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1561 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1562 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1563 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1565 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1566 redraw_frame (f);
1571 /* Encode Lisp string STRING as a text in a format appropriate for
1572 XICCC (X Inter Client Communication Conventions).
1574 This can call Lisp code, so callers must GCPRO.
1576 If STRING contains only ASCII characters, do no conversion and
1577 return the string data of STRING. Otherwise, encode the text by
1578 CODING_SYSTEM, and return a newly allocated memory area which
1579 should be freed by `xfree' by a caller.
1581 SELECTIONP non-zero means the string is being encoded for an X
1582 selection, so it is safe to run pre-write conversions (which
1583 may run Lisp code).
1585 Store the byte length of resulting text in *TEXT_BYTES.
1587 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1588 which means that the `encoding' of the result can be `STRING'.
1589 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1590 the result should be `COMPOUND_TEXT'. */
1592 static unsigned char *
1593 x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep)
1594 Lisp_Object string, coding_system;
1595 int *text_bytes, *stringp;
1596 int selectionp;
1597 int *freep;
1599 int result = string_xstring_p (string);
1600 struct coding_system coding;
1602 if (result == 0)
1604 /* No multibyte character in OBJ. We need not encode it. */
1605 *text_bytes = SBYTES (string);
1606 *stringp = 1;
1607 *freep = 0;
1608 return SDATA (string);
1611 setup_coding_system (coding_system, &coding);
1612 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1613 /* We suppress producing escape sequences for composition. */
1614 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1615 coding.dst_bytes = SCHARS (string) * 2;
1616 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
1617 encode_coding_object (&coding, string, 0, 0,
1618 SCHARS (string), SBYTES (string), Qnil);
1619 *text_bytes = coding.produced;
1620 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1621 *freep = 1;
1622 return coding.destination;
1626 /* Set the WM name to NAME for frame F. Also set the icon name.
1627 If the frame already has an icon name, use that, otherwise set the
1628 icon name to NAME. */
1630 static void
1631 x_set_name_internal (f, name)
1632 FRAME_PTR f;
1633 Lisp_Object name;
1635 if (FRAME_X_WINDOW (f))
1637 BLOCK_INPUT;
1639 XTextProperty text, icon;
1640 int bytes, stringp;
1641 int do_free_icon_value = 0, do_free_text_value = 0;
1642 Lisp_Object coding_system;
1643 #ifdef USE_GTK
1644 Lisp_Object encoded_name;
1645 struct gcpro gcpro1;
1647 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1648 we use it before x_encode_text that may return string data. */
1649 GCPRO1 (name);
1650 encoded_name = ENCODE_UTF_8 (name);
1651 UNGCPRO;
1652 #endif
1654 coding_system = Qcompound_text;
1655 /* Note: Encoding strategy
1657 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1658 text.encoding. But, there are non-internationalized window
1659 managers which don't support that encoding. So, if NAME
1660 contains only ASCII and 8859-1 characters, encode it by
1661 iso-latin-1, and use "STRING" in text.encoding hoping that
1662 such window managers at least analyze this format correctly,
1663 i.e. treat 8-bit bytes as 8859-1 characters.
1665 We may also be able to use "UTF8_STRING" in text.encoding
1666 in the future which can encode all Unicode characters.
1667 But, for the moment, there's no way to know that the
1668 current window manager supports it or not. */
1669 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1670 &do_free_text_value);
1671 text.encoding = (stringp ? XA_STRING
1672 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1673 text.format = 8;
1674 text.nitems = bytes;
1676 if (!STRINGP (f->icon_name))
1678 icon = text;
1680 else
1682 /* See the above comment "Note: Encoding strategy". */
1683 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1684 &bytes, &stringp, &do_free_icon_value);
1685 icon.encoding = (stringp ? XA_STRING
1686 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1687 icon.format = 8;
1688 icon.nitems = bytes;
1691 #ifdef USE_GTK
1692 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1693 (char *) SDATA (encoded_name));
1694 #else /* not USE_GTK */
1695 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1696 #endif /* not USE_GTK */
1698 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1700 if (do_free_icon_value)
1701 xfree (icon.value);
1702 if (do_free_text_value)
1703 xfree (text.value);
1705 UNBLOCK_INPUT;
1709 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1710 x_id_name.
1712 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1713 name; if NAME is a string, set F's name to NAME and set
1714 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1716 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1717 suggesting a new name, which lisp code should override; if
1718 F->explicit_name is set, ignore the new name; otherwise, set it. */
1720 void
1721 x_set_name (f, name, explicit)
1722 struct frame *f;
1723 Lisp_Object name;
1724 int explicit;
1726 /* Make sure that requests from lisp code override requests from
1727 Emacs redisplay code. */
1728 if (explicit)
1730 /* If we're switching from explicit to implicit, we had better
1731 update the mode lines and thereby update the title. */
1732 if (f->explicit_name && NILP (name))
1733 update_mode_lines = 1;
1735 f->explicit_name = ! NILP (name);
1737 else if (f->explicit_name)
1738 return;
1740 /* If NAME is nil, set the name to the x_id_name. */
1741 if (NILP (name))
1743 /* Check for no change needed in this very common case
1744 before we do any consing. */
1745 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1746 SDATA (f->name)))
1747 return;
1748 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1750 else
1751 CHECK_STRING (name);
1753 /* Don't change the name if it's already NAME. */
1754 if (! NILP (Fstring_equal (name, f->name)))
1755 return;
1757 f->name = name;
1759 /* For setting the frame title, the title parameter should override
1760 the name parameter. */
1761 if (! NILP (f->title))
1762 name = f->title;
1764 x_set_name_internal (f, name);
1767 /* This function should be called when the user's lisp code has
1768 specified a name for the frame; the name will override any set by the
1769 redisplay code. */
1770 void
1771 x_explicitly_set_name (f, arg, oldval)
1772 FRAME_PTR f;
1773 Lisp_Object arg, oldval;
1775 x_set_name (f, arg, 1);
1778 /* This function should be called by Emacs redisplay code to set the
1779 name; names set this way will never override names set by the user's
1780 lisp code. */
1781 void
1782 x_implicitly_set_name (f, arg, oldval)
1783 FRAME_PTR f;
1784 Lisp_Object arg, oldval;
1786 x_set_name (f, arg, 0);
1789 /* Change the title of frame F to NAME.
1790 If NAME is nil, use the frame name as the title. */
1792 void
1793 x_set_title (f, name, old_name)
1794 struct frame *f;
1795 Lisp_Object name, old_name;
1797 /* Don't change the title if it's already NAME. */
1798 if (EQ (name, f->title))
1799 return;
1801 update_mode_lines = 1;
1803 f->title = name;
1805 if (NILP (name))
1806 name = f->name;
1807 else
1808 CHECK_STRING (name);
1810 x_set_name_internal (f, name);
1813 void
1814 x_set_scroll_bar_default_width (f)
1815 struct frame *f;
1817 int wid = FRAME_COLUMN_WIDTH (f);
1819 #ifdef USE_TOOLKIT_SCROLL_BARS
1820 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1821 int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1822 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1823 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1824 #else
1825 /* Make the actual width at least 14 pixels and a multiple of a
1826 character width. */
1827 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1829 /* Use all of that space (aside from required margins) for the
1830 scroll bar. */
1831 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1832 #endif
1836 /* Record in frame F the specified or default value according to ALIST
1837 of the parameter named PROP (a Lisp symbol). If no value is
1838 specified for PROP, look for an X default for XPROP on the frame
1839 named NAME. If that is not found either, use the value DEFLT. */
1841 static Lisp_Object
1842 x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
1843 foreground_p)
1844 struct frame *f;
1845 Lisp_Object alist;
1846 Lisp_Object prop;
1847 char *xprop;
1848 char *xclass;
1849 int foreground_p;
1851 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1852 Lisp_Object tem;
1854 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1855 if (EQ (tem, Qunbound))
1857 #ifdef USE_TOOLKIT_SCROLL_BARS
1859 /* See if an X resource for the scroll bar color has been
1860 specified. */
1861 tem = display_x_get_resource (dpyinfo,
1862 build_string (foreground_p
1863 ? "foreground"
1864 : "background"),
1865 empty_unibyte_string,
1866 build_string ("verticalScrollBar"),
1867 empty_unibyte_string);
1868 if (!STRINGP (tem))
1870 /* If nothing has been specified, scroll bars will use a
1871 toolkit-dependent default. Because these defaults are
1872 difficult to get at without actually creating a scroll
1873 bar, use nil to indicate that no color has been
1874 specified. */
1875 tem = Qnil;
1878 #else /* not USE_TOOLKIT_SCROLL_BARS */
1880 tem = Qnil;
1882 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1885 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1886 return tem;
1892 #ifdef USE_X_TOOLKIT
1894 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1895 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1896 already be present because of the toolkit (Motif adds some of them,
1897 for example, but Xt doesn't). */
1899 static void
1900 hack_wm_protocols (f, widget)
1901 FRAME_PTR f;
1902 Widget widget;
1904 Display *dpy = XtDisplay (widget);
1905 Window w = XtWindow (widget);
1906 int need_delete = 1;
1907 int need_focus = 1;
1908 int need_save = 1;
1910 BLOCK_INPUT;
1912 Atom type;
1913 unsigned char *catoms;
1914 int format = 0;
1915 unsigned long nitems = 0;
1916 unsigned long bytes_after;
1918 if ((XGetWindowProperty (dpy, w,
1919 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1920 (long)0, (long)100, False, XA_ATOM,
1921 &type, &format, &nitems, &bytes_after,
1922 &catoms)
1923 == Success)
1924 && format == 32 && type == XA_ATOM)
1926 Atom *atoms = (Atom *) catoms;
1927 while (nitems > 0)
1929 nitems--;
1930 if (atoms[nitems]
1931 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1932 need_delete = 0;
1933 else if (atoms[nitems]
1934 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1935 need_focus = 0;
1936 else if (atoms[nitems]
1937 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1938 need_save = 0;
1941 if (catoms)
1942 XFree (catoms);
1945 Atom props [10];
1946 int count = 0;
1947 if (need_delete)
1948 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1949 if (need_focus)
1950 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1951 if (need_save)
1952 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1953 if (count)
1954 XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1955 XA_ATOM, 32, PropModeAppend,
1956 (unsigned char *) props, count);
1958 UNBLOCK_INPUT;
1960 #endif
1964 /* Support routines for XIC (X Input Context). */
1966 #ifdef HAVE_X_I18N
1968 static XFontSet xic_create_xfontset P_ ((struct frame *));
1969 static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *));
1972 /* Supported XIM styles, ordered by preference. */
1974 static XIMStyle supported_xim_styles[] =
1976 XIMPreeditPosition | XIMStatusArea,
1977 XIMPreeditPosition | XIMStatusNothing,
1978 XIMPreeditPosition | XIMStatusNone,
1979 XIMPreeditNothing | XIMStatusArea,
1980 XIMPreeditNothing | XIMStatusNothing,
1981 XIMPreeditNothing | XIMStatusNone,
1982 XIMPreeditNone | XIMStatusArea,
1983 XIMPreeditNone | XIMStatusNothing,
1984 XIMPreeditNone | XIMStatusNone,
1989 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1991 char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1993 /* Create an Xt fontset spec from the name of a base font.
1994 If `motif' is True use the Motif syntax. */
1995 char *
1996 xic_create_fontsetname (base_fontname, motif)
1997 char *base_fontname;
1998 Bool motif;
2000 const char *sep = motif ? ";" : ",";
2001 char *fontsetname;
2003 /* Make a fontset name from the base font name. */
2004 if (xic_defaut_fontset == base_fontname)
2005 { /* There is no base font name, use the default. */
2006 int len = strlen (base_fontname) + 2;
2007 fontsetname = xmalloc (len);
2008 bzero (fontsetname, len);
2009 strcpy (fontsetname, base_fontname);
2011 else
2013 /* Make a fontset name from the base font name.
2014 The font set will be made of the following elements:
2015 - the base font.
2016 - the base font where the charset spec is replaced by -*-*.
2017 - the same but with the family also replaced with -*-*-. */
2018 char *p = base_fontname;
2019 int i;
2021 for (i = 0; *p; p++)
2022 if (*p == '-') i++;
2023 if (i != 14)
2024 { /* As the font name doesn't conform to XLFD, we can't
2025 modify it to generalize it to allcs and allfamilies.
2026 Use the specified font plus the default. */
2027 int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3;
2028 fontsetname = xmalloc (len);
2029 bzero (fontsetname, len);
2030 strcpy (fontsetname, base_fontname);
2031 strcat (fontsetname, sep);
2032 strcat (fontsetname, xic_defaut_fontset);
2034 else
2036 int len;
2037 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
2038 char *font_allcs = NULL;
2039 char *font_allfamilies = NULL;
2040 char *font_all = NULL;
2041 char *allcs = "*-*-*-*-*-*-*";
2042 char *allfamilies = "-*-*-";
2043 char *all = "*-*-*-*-";
2044 char *base;
2046 for (i = 0, p = base_fontname; i < 8; p++)
2048 if (*p == '-')
2050 i++;
2051 if (i == 3)
2052 p1 = p + 1;
2053 else if (i == 7)
2054 p2 = p + 1;
2055 else if (i == 6)
2056 p3 = p + 1;
2059 /* If base_fontname specifies ADSTYLE, make it a
2060 wildcard. */
2061 if (*p3 != '*')
2063 int diff = (p2 - p3) - 2;
2065 base = alloca (strlen (base_fontname) + 1);
2066 bcopy (base_fontname, base, p3 - base_fontname);
2067 base[p3 - base_fontname] = '*';
2068 base[(p3 - base_fontname) + 1] = '-';
2069 strcpy (base + (p3 - base_fontname) + 2, p2);
2070 p = base + (p - base_fontname) - diff;
2071 p1 = base + (p1 - base_fontname);
2072 p2 = base + (p2 - base_fontname) - diff;
2073 base_fontname = base;
2076 /* Build the font spec that matches all charsets. */
2077 len = p - base_fontname + strlen (allcs) + 1;
2078 font_allcs = (char *) alloca (len);
2079 bzero (font_allcs, len);
2080 bcopy (base_fontname, font_allcs, p - base_fontname);
2081 strcat (font_allcs, allcs);
2083 /* Build the font spec that matches all families and
2084 add-styles. */
2085 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
2086 font_allfamilies = (char *) alloca (len);
2087 bzero (font_allfamilies, len);
2088 strcpy (font_allfamilies, allfamilies);
2089 bcopy (p1, font_allfamilies + strlen (allfamilies), p - p1);
2090 strcat (font_allfamilies, allcs);
2092 /* Build the font spec that matches all. */
2093 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
2094 font_all = (char *) alloca (len);
2095 bzero (font_all, len);
2096 strcpy (font_all, allfamilies);
2097 strcat (font_all, all);
2098 bcopy (p2, font_all + strlen (all) + strlen (allfamilies), p - p2);
2099 strcat (font_all, allcs);
2101 /* Build the actual font set name. */
2102 len = strlen (base_fontname) + strlen (font_allcs)
2103 + strlen (font_allfamilies) + strlen (font_all) + 5;
2104 fontsetname = xmalloc (len);
2105 bzero (fontsetname, len);
2106 strcpy (fontsetname, base_fontname);
2107 strcat (fontsetname, sep);
2108 strcat (fontsetname, font_allcs);
2109 strcat (fontsetname, sep);
2110 strcat (fontsetname, font_allfamilies);
2111 strcat (fontsetname, sep);
2112 strcat (fontsetname, font_all);
2115 if (motif)
2116 strcat (fontsetname, ":");
2117 return fontsetname;
2120 #ifdef DEBUG_XIC_FONTSET
2121 static void
2122 print_fontset_result (xfs, name, missing_list, missing_count)
2123 XFontSet xfs;
2124 char *name;
2125 char **missing_list;
2126 int missing_count;
2128 if (xfs)
2129 fprintf (stderr, "XIC Fontset created: %s\n", name);
2130 else
2132 fprintf (stderr, "XIC Fontset failed: %s\n", name);
2133 while (missing_count-- > 0)
2135 fprintf (stderr, " missing: %s\n", *missing_list);
2136 missing_list++;
2141 #endif
2143 static XFontSet
2144 xic_create_xfontset (f)
2145 struct frame *f;
2147 XFontSet xfs = NULL;
2148 struct font *font = FRAME_FONT (f);
2149 int pixel_size = font->pixel_size;
2150 Lisp_Object rest, frame;
2152 /* See if there is another frame already using same fontset. */
2153 FOR_EACH_FRAME (rest, frame)
2155 struct frame *cf = XFRAME (frame);
2157 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2158 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2159 && FRAME_FONT (f)
2160 && FRAME_FONT (f)->pixel_size == pixel_size)
2162 xfs = FRAME_XIC_FONTSET (cf);
2163 break;
2167 if (! xfs)
2169 char buf[256];
2170 char **missing_list;
2171 int missing_count;
2172 char *def_string;
2173 char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
2175 sprintf (buf, xlfd_format, pixel_size);
2176 missing_list = NULL;
2177 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2178 &missing_list, &missing_count, &def_string);
2179 #ifdef DEBUG_XIC_FONTSET
2180 print_fontset_result (xfs, buf, missing_list, missing_count);
2181 #endif
2182 if (missing_list)
2183 XFreeStringList (missing_list);
2184 if (! xfs)
2186 /* List of pixel sizes most likely available. Find one that
2187 is closest to pixel_size. */
2188 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2189 int *smaller, *larger;
2191 for (smaller = sizes; smaller[1]; smaller++)
2192 if (smaller[1] >= pixel_size)
2193 break;
2194 larger = smaller + 1;
2195 if (*larger == pixel_size)
2196 larger++;
2197 while (*smaller || *larger)
2199 int this_size;
2201 if (! *larger)
2202 this_size = *smaller--;
2203 else if (! *smaller)
2204 this_size = *larger++;
2205 else if (pixel_size - *smaller < *larger - pixel_size)
2206 this_size = *smaller--;
2207 else
2208 this_size = *larger++;
2209 sprintf (buf, xlfd_format, this_size);
2210 missing_list = NULL;
2211 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2212 &missing_list, &missing_count, &def_string);
2213 #ifdef DEBUG_XIC_FONTSET
2214 print_fontset_result (xfs, buf, missing_list, missing_count);
2215 #endif
2216 if (missing_list)
2217 XFreeStringList (missing_list);
2218 if (xfs)
2219 break;
2222 if (! xfs)
2224 char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
2226 missing_list = NULL;
2227 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
2228 &missing_list, &missing_count, &def_string);
2229 #ifdef DEBUG_XIC_FONTSET
2230 print_fontset_result (xfs, last_resort, missing_list, missing_count);
2231 #endif
2232 if (missing_list)
2233 XFreeStringList (missing_list);
2238 return xfs;
2241 /* Free the X fontset of frame F if it is the last frame using it. */
2243 void
2244 xic_free_xfontset (f)
2245 struct frame *f;
2247 Lisp_Object rest, frame;
2248 int shared_p = 0;
2250 if (!FRAME_XIC_FONTSET (f))
2251 return;
2253 /* See if there is another frame sharing the same fontset. */
2254 FOR_EACH_FRAME (rest, frame)
2256 struct frame *cf = XFRAME (frame);
2257 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2258 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2259 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
2261 shared_p = 1;
2262 break;
2266 if (!shared_p)
2267 /* The fontset is not used anymore. It is safe to free it. */
2268 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2270 if (FRAME_XIC_BASE_FONTNAME (f))
2271 xfree (FRAME_XIC_BASE_FONTNAME (f));
2272 FRAME_XIC_BASE_FONTNAME (f) = NULL;
2273 FRAME_XIC_FONTSET (f) = NULL;
2277 /* Value is the best input style, given user preferences USER (already
2278 checked to be supported by Emacs), and styles supported by the
2279 input method XIM. */
2281 static XIMStyle
2282 best_xim_style (user, xim)
2283 XIMStyles *user;
2284 XIMStyles *xim;
2286 int i, j;
2288 for (i = 0; i < user->count_styles; ++i)
2289 for (j = 0; j < xim->count_styles; ++j)
2290 if (user->supported_styles[i] == xim->supported_styles[j])
2291 return user->supported_styles[i];
2293 /* Return the default style. */
2294 return XIMPreeditNothing | XIMStatusNothing;
2297 /* Create XIC for frame F. */
2299 static XIMStyle xic_style;
2301 void
2302 create_frame_xic (f)
2303 struct frame *f;
2305 XIM xim;
2306 XIC xic = NULL;
2307 XFontSet xfs = NULL;
2309 if (FRAME_XIC (f))
2310 return;
2312 /* Create X fontset. */
2313 xfs = xic_create_xfontset (f);
2314 xim = FRAME_X_XIM (f);
2315 if (xim)
2317 XRectangle s_area;
2318 XPoint spot;
2319 XVaNestedList preedit_attr;
2320 XVaNestedList status_attr;
2322 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2323 spot.x = 0; spot.y = 1;
2325 /* Determine XIC style. */
2326 if (xic_style == 0)
2328 XIMStyles supported_list;
2329 supported_list.count_styles = (sizeof supported_xim_styles
2330 / sizeof supported_xim_styles[0]);
2331 supported_list.supported_styles = supported_xim_styles;
2332 xic_style = best_xim_style (&supported_list,
2333 FRAME_X_XIM_STYLES (f));
2336 preedit_attr = XVaCreateNestedList (0,
2337 XNFontSet, xfs,
2338 XNForeground,
2339 FRAME_FOREGROUND_PIXEL (f),
2340 XNBackground,
2341 FRAME_BACKGROUND_PIXEL (f),
2342 (xic_style & XIMPreeditPosition
2343 ? XNSpotLocation
2344 : NULL),
2345 &spot,
2346 NULL);
2347 status_attr = XVaCreateNestedList (0,
2348 XNArea,
2349 &s_area,
2350 XNFontSet,
2351 xfs,
2352 XNForeground,
2353 FRAME_FOREGROUND_PIXEL (f),
2354 XNBackground,
2355 FRAME_BACKGROUND_PIXEL (f),
2356 NULL);
2358 xic = XCreateIC (xim,
2359 XNInputStyle, xic_style,
2360 XNClientWindow, FRAME_X_WINDOW (f),
2361 XNFocusWindow, FRAME_X_WINDOW (f),
2362 XNStatusAttributes, status_attr,
2363 XNPreeditAttributes, preedit_attr,
2364 NULL);
2365 XFree (preedit_attr);
2366 XFree (status_attr);
2369 FRAME_XIC (f) = xic;
2370 FRAME_XIC_STYLE (f) = xic_style;
2371 FRAME_XIC_FONTSET (f) = xfs;
2375 /* Destroy XIC and free XIC fontset of frame F, if any. */
2377 void
2378 free_frame_xic (f)
2379 struct frame *f;
2381 if (FRAME_XIC (f) == NULL)
2382 return;
2384 XDestroyIC (FRAME_XIC (f));
2385 xic_free_xfontset (f);
2387 FRAME_XIC (f) = NULL;
2391 /* Place preedit area for XIC of window W's frame to specified
2392 pixel position X/Y. X and Y are relative to window W. */
2394 void
2395 xic_set_preeditarea (w, x, y)
2396 struct window *w;
2397 int x, y;
2399 struct frame *f = XFRAME (w->frame);
2400 XVaNestedList attr;
2401 XPoint spot;
2403 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2404 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2405 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2406 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2407 XFree (attr);
2411 /* Place status area for XIC in bottom right corner of frame F.. */
2413 void
2414 xic_set_statusarea (f)
2415 struct frame *f;
2417 XIC xic = FRAME_XIC (f);
2418 XVaNestedList attr;
2419 XRectangle area;
2420 XRectangle *needed;
2422 /* Negotiate geometry of status area. If input method has existing
2423 status area, use its current size. */
2424 area.x = area.y = area.width = area.height = 0;
2425 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2426 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2427 XFree (attr);
2429 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2430 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2431 XFree (attr);
2433 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2435 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2436 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2437 XFree (attr);
2440 area.width = needed->width;
2441 area.height = needed->height;
2442 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2443 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2444 - FRAME_MENUBAR_HEIGHT (f)
2445 - FRAME_TOOLBAR_HEIGHT (f)
2446 - FRAME_INTERNAL_BORDER_WIDTH (f));
2447 XFree (needed);
2449 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2450 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2451 XFree (attr);
2455 /* Set X fontset for XIC of frame F, using base font name
2456 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2458 void
2459 xic_set_xfontset (f, base_fontname)
2460 struct frame *f;
2461 char *base_fontname;
2463 XVaNestedList attr;
2464 XFontSet xfs;
2466 xic_free_xfontset (f);
2468 xfs = xic_create_xfontset (f);
2470 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2471 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2472 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2473 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2474 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2475 XFree (attr);
2477 FRAME_XIC_FONTSET (f) = xfs;
2480 #endif /* HAVE_X_I18N */
2484 #ifdef USE_X_TOOLKIT
2486 /* Create and set up the X widget for frame F. */
2488 static void
2489 x_window (f, window_prompting, minibuffer_only)
2490 struct frame *f;
2491 long window_prompting;
2492 int minibuffer_only;
2494 XClassHint class_hints;
2495 XSetWindowAttributes attributes;
2496 unsigned long attribute_mask;
2497 Widget shell_widget;
2498 Widget pane_widget;
2499 Widget frame_widget;
2500 Arg al [25];
2501 int ac;
2503 BLOCK_INPUT;
2505 /* Use the resource name as the top-level widget name
2506 for looking up resources. Make a non-Lisp copy
2507 for the window manager, so GC relocation won't bother it.
2509 Elsewhere we specify the window name for the window manager. */
2512 char *str = (char *) SDATA (Vx_resource_name);
2513 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2514 strcpy (f->namebuf, str);
2517 ac = 0;
2518 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2519 XtSetArg (al[ac], XtNinput, 1); ac++;
2520 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2521 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2522 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2523 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2524 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2525 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2526 applicationShellWidgetClass,
2527 FRAME_X_DISPLAY (f), al, ac);
2529 f->output_data.x->widget = shell_widget;
2530 /* maybe_set_screen_title_format (shell_widget); */
2532 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2533 (widget_value *) NULL,
2534 shell_widget, False,
2535 (lw_callback) NULL,
2536 (lw_callback) NULL,
2537 (lw_callback) NULL,
2538 (lw_callback) NULL);
2540 ac = 0;
2541 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2542 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2543 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2544 XtSetValues (pane_widget, al, ac);
2545 f->output_data.x->column_widget = pane_widget;
2547 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2548 the emacs screen when changing menubar. This reduces flickering. */
2550 ac = 0;
2551 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2552 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2553 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2554 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2555 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2556 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2557 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2558 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2559 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2560 al, ac);
2562 f->output_data.x->edit_widget = frame_widget;
2564 XtManageChild (frame_widget);
2566 /* Do some needed geometry management. */
2568 int len;
2569 char *tem, shell_position[32];
2570 Arg al[10];
2571 int ac = 0;
2572 int extra_borders = 0;
2573 int menubar_size
2574 = (f->output_data.x->menubar_widget
2575 ? (f->output_data.x->menubar_widget->core.height
2576 + f->output_data.x->menubar_widget->core.border_width)
2577 : 0);
2579 #if 0 /* Experimentally, we now get the right results
2580 for -geometry -0-0 without this. 24 Aug 96, rms. */
2581 if (FRAME_EXTERNAL_MENU_BAR (f))
2583 Dimension ibw = 0;
2584 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2585 menubar_size += ibw;
2587 #endif
2589 f->output_data.x->menubar_height = menubar_size;
2591 #ifndef USE_LUCID
2592 /* Motif seems to need this amount added to the sizes
2593 specified for the shell widget. The Athena/Lucid widgets don't.
2594 Both conclusions reached experimentally. -- rms. */
2595 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2596 &extra_borders, NULL);
2597 extra_borders *= 2;
2598 #endif
2600 /* Convert our geometry parameters into a geometry string
2601 and specify it.
2602 Note that we do not specify here whether the position
2603 is a user-specified or program-specified one.
2604 We pass that information later, in x_wm_set_size_hints. */
2606 int left = f->left_pos;
2607 int xneg = window_prompting & XNegative;
2608 int top = f->top_pos;
2609 int yneg = window_prompting & YNegative;
2610 if (xneg)
2611 left = -left;
2612 if (yneg)
2613 top = -top;
2615 if (window_prompting & USPosition)
2616 sprintf (shell_position, "=%dx%d%c%d%c%d",
2617 FRAME_PIXEL_WIDTH (f) + extra_borders,
2618 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2619 (xneg ? '-' : '+'), left,
2620 (yneg ? '-' : '+'), top);
2621 else
2623 sprintf (shell_position, "=%dx%d",
2624 FRAME_PIXEL_WIDTH (f) + extra_borders,
2625 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2627 /* Setting x and y when the position is not specified in
2628 the geometry string will set program position in the WM hints.
2629 If Emacs had just one program position, we could set it in
2630 fallback resources, but since each make-frame call can specify
2631 different program positions, this is easier. */
2632 XtSetArg (al[ac], XtNx, left); ac++;
2633 XtSetArg (al[ac], XtNy, top); ac++;
2637 len = strlen (shell_position) + 1;
2638 /* We don't free this because we don't know whether
2639 it is safe to free it while the frame exists.
2640 It isn't worth the trouble of arranging to free it
2641 when the frame is deleted. */
2642 tem = (char *) xmalloc (len);
2643 strncpy (tem, shell_position, len);
2644 XtSetArg (al[ac], XtNgeometry, tem); ac++;
2645 XtSetValues (shell_widget, al, ac);
2648 XtManageChild (pane_widget);
2649 XtRealizeWidget (shell_widget);
2651 if (FRAME_X_EMBEDDED_P (f))
2652 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2653 f->output_data.x->parent_desc, 0, 0);
2655 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2657 validate_x_resource_name ();
2659 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2660 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2661 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2663 #ifdef HAVE_X_I18N
2664 FRAME_XIC (f) = NULL;
2665 if (use_xim)
2666 create_frame_xic (f);
2667 #endif
2669 f->output_data.x->wm_hints.input = True;
2670 f->output_data.x->wm_hints.flags |= InputHint;
2671 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2672 &f->output_data.x->wm_hints);
2674 hack_wm_protocols (f, shell_widget);
2676 #ifdef HACK_EDITRES
2677 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2678 #endif
2680 /* Do a stupid property change to force the server to generate a
2681 PropertyNotify event so that the event_stream server timestamp will
2682 be initialized to something relevant to the time we created the window.
2684 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2685 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2686 XA_ATOM, 32, PropModeAppend,
2687 (unsigned char*) NULL, 0);
2689 /* Make all the standard events reach the Emacs frame. */
2690 attributes.event_mask = STANDARD_EVENT_SET;
2692 #ifdef HAVE_X_I18N
2693 if (FRAME_XIC (f))
2695 /* XIM server might require some X events. */
2696 unsigned long fevent = NoEventMask;
2697 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2698 attributes.event_mask |= fevent;
2700 #endif /* HAVE_X_I18N */
2702 attribute_mask = CWEventMask;
2703 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2704 attribute_mask, &attributes);
2706 XtMapWidget (frame_widget);
2708 /* x_set_name normally ignores requests to set the name if the
2709 requested name is the same as the current name. This is the one
2710 place where that assumption isn't correct; f->name is set, but
2711 the X server hasn't been told. */
2713 Lisp_Object name;
2714 int explicit = f->explicit_name;
2716 f->explicit_name = 0;
2717 name = f->name;
2718 f->name = Qnil;
2719 x_set_name (f, name, explicit);
2722 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2723 f->output_data.x->current_cursor
2724 = f->output_data.x->text_cursor);
2726 UNBLOCK_INPUT;
2728 /* This is a no-op, except under Motif. Make sure main areas are
2729 set to something reasonable, in case we get an error later. */
2730 lw_set_main_areas (pane_widget, 0, frame_widget);
2733 #else /* not USE_X_TOOLKIT */
2734 #ifdef USE_GTK
2735 void
2736 x_window (f)
2737 FRAME_PTR f;
2739 if (! xg_create_frame_widgets (f))
2740 error ("Unable to create window");
2742 #ifdef HAVE_X_I18N
2743 FRAME_XIC (f) = NULL;
2744 if (use_xim)
2746 BLOCK_INPUT;
2747 create_frame_xic (f);
2748 if (FRAME_XIC (f))
2750 /* XIM server might require some X events. */
2751 unsigned long fevent = NoEventMask;
2752 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2754 if (fevent != NoEventMask)
2756 XSetWindowAttributes attributes;
2757 XWindowAttributes wattr;
2758 unsigned long attribute_mask;
2760 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2761 &wattr);
2762 attributes.event_mask = wattr.your_event_mask | fevent;
2763 attribute_mask = CWEventMask;
2764 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2765 attribute_mask, &attributes);
2768 UNBLOCK_INPUT;
2770 #endif
2773 #else /*! USE_GTK */
2774 /* Create and set up the X window for frame F. */
2776 void
2777 x_window (f)
2778 struct frame *f;
2781 XClassHint class_hints;
2782 XSetWindowAttributes attributes;
2783 unsigned long attribute_mask;
2785 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2786 attributes.border_pixel = f->output_data.x->border_pixel;
2787 attributes.bit_gravity = StaticGravity;
2788 attributes.backing_store = NotUseful;
2789 attributes.save_under = True;
2790 attributes.event_mask = STANDARD_EVENT_SET;
2791 attributes.colormap = FRAME_X_COLORMAP (f);
2792 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2793 | CWColormap);
2795 BLOCK_INPUT;
2796 FRAME_X_WINDOW (f)
2797 = XCreateWindow (FRAME_X_DISPLAY (f),
2798 f->output_data.x->parent_desc,
2799 f->left_pos,
2800 f->top_pos,
2801 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2802 f->border_width,
2803 CopyFromParent, /* depth */
2804 InputOutput, /* class */
2805 FRAME_X_VISUAL (f),
2806 attribute_mask, &attributes);
2808 #ifdef HAVE_X_I18N
2809 if (use_xim)
2811 create_frame_xic (f);
2812 if (FRAME_XIC (f))
2814 /* XIM server might require some X events. */
2815 unsigned long fevent = NoEventMask;
2816 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2817 attributes.event_mask |= fevent;
2818 attribute_mask = CWEventMask;
2819 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2820 attribute_mask, &attributes);
2823 #endif /* HAVE_X_I18N */
2825 validate_x_resource_name ();
2827 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2828 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2829 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2831 /* The menubar is part of the ordinary display;
2832 it does not count in addition to the height of the window. */
2833 f->output_data.x->menubar_height = 0;
2835 /* This indicates that we use the "Passive Input" input model.
2836 Unless we do this, we don't get the Focus{In,Out} events that we
2837 need to draw the cursor correctly. Accursed bureaucrats.
2838 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2840 f->output_data.x->wm_hints.input = True;
2841 f->output_data.x->wm_hints.flags |= InputHint;
2842 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2843 &f->output_data.x->wm_hints);
2844 f->output_data.x->wm_hints.icon_pixmap = None;
2846 /* Request "save yourself" and "delete window" commands from wm. */
2848 Atom protocols[2];
2849 protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2850 protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2851 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2854 /* x_set_name normally ignores requests to set the name if the
2855 requested name is the same as the current name. This is the one
2856 place where that assumption isn't correct; f->name is set, but
2857 the X server hasn't been told. */
2859 Lisp_Object name;
2860 int explicit = f->explicit_name;
2862 f->explicit_name = 0;
2863 name = f->name;
2864 f->name = Qnil;
2865 x_set_name (f, name, explicit);
2868 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2869 f->output_data.x->current_cursor
2870 = f->output_data.x->text_cursor);
2872 UNBLOCK_INPUT;
2874 if (FRAME_X_WINDOW (f) == 0)
2875 error ("Unable to create window");
2878 #endif /* not USE_GTK */
2879 #endif /* not USE_X_TOOLKIT */
2881 /* Verify that the icon position args for this window are valid. */
2883 static void
2884 x_icon_verify (f, parms)
2885 struct frame *f;
2886 Lisp_Object parms;
2888 Lisp_Object icon_x, icon_y;
2890 /* Set the position of the icon. Note that twm groups all
2891 icons in an icon window. */
2892 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2893 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2894 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2896 CHECK_NUMBER (icon_x);
2897 CHECK_NUMBER (icon_y);
2899 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2900 error ("Both left and top icon corners of icon must be specified");
2903 /* Handle the icon stuff for this window. Perhaps later we might
2904 want an x_set_icon_position which can be called interactively as
2905 well. */
2907 static void
2908 x_icon (f, parms)
2909 struct frame *f;
2910 Lisp_Object parms;
2912 Lisp_Object icon_x, icon_y;
2913 #if 0
2914 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2915 #endif
2917 /* Set the position of the icon. Note that twm groups all
2918 icons in an icon window. */
2919 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2920 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2921 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2923 CHECK_NUMBER (icon_x);
2924 CHECK_NUMBER (icon_y);
2926 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2927 error ("Both left and top icon corners of icon must be specified");
2929 BLOCK_INPUT;
2931 if (! EQ (icon_x, Qunbound))
2932 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2934 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2935 but x_create_frame still needs it. */
2936 /* Start up iconic or window? */
2937 x_wm_set_window_state
2938 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2939 Qicon)
2940 ? IconicState
2941 : NormalState));
2942 #endif
2944 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2945 ? f->icon_name
2946 : f->name)));
2948 UNBLOCK_INPUT;
2951 /* Make the GCs needed for this window, setting the
2952 background, border and mouse colors; also create the
2953 mouse cursor and the gray border tile. */
2955 static void
2956 x_make_gc (f)
2957 struct frame *f;
2959 XGCValues gc_values;
2961 BLOCK_INPUT;
2963 /* Create the GCs of this frame.
2964 Note that many default values are used. */
2966 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2967 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2968 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2969 f->output_data.x->normal_gc
2970 = XCreateGC (FRAME_X_DISPLAY (f),
2971 FRAME_X_WINDOW (f),
2972 GCLineWidth | GCForeground | GCBackground,
2973 &gc_values);
2975 /* Reverse video style. */
2976 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2977 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2978 f->output_data.x->reverse_gc
2979 = XCreateGC (FRAME_X_DISPLAY (f),
2980 FRAME_X_WINDOW (f),
2981 GCForeground | GCBackground | GCLineWidth,
2982 &gc_values);
2984 /* Cursor has cursor-color background, background-color foreground. */
2985 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2986 gc_values.background = f->output_data.x->cursor_pixel;
2987 gc_values.fill_style = FillOpaqueStippled;
2988 f->output_data.x->cursor_gc
2989 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2990 (GCForeground | GCBackground
2991 | GCFillStyle | GCLineWidth),
2992 &gc_values);
2994 /* Reliefs. */
2995 f->output_data.x->white_relief.gc = 0;
2996 f->output_data.x->black_relief.gc = 0;
2998 /* Create the gray border tile used when the pointer is not in
2999 the frame. Since this depends on the frame's pixel values,
3000 this must be done on a per-frame basis. */
3001 f->output_data.x->border_tile
3002 = (XCreatePixmapFromBitmapData
3003 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
3004 gray_bits, gray_width, gray_height,
3005 FRAME_FOREGROUND_PIXEL (f),
3006 FRAME_BACKGROUND_PIXEL (f),
3007 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
3009 UNBLOCK_INPUT;
3013 /* Free what was allocated in x_make_gc. */
3015 void
3016 x_free_gcs (f)
3017 struct frame *f;
3019 Display *dpy = FRAME_X_DISPLAY (f);
3021 BLOCK_INPUT;
3023 if (f->output_data.x->normal_gc)
3025 XFreeGC (dpy, f->output_data.x->normal_gc);
3026 f->output_data.x->normal_gc = 0;
3029 if (f->output_data.x->reverse_gc)
3031 XFreeGC (dpy, f->output_data.x->reverse_gc);
3032 f->output_data.x->reverse_gc = 0;
3035 if (f->output_data.x->cursor_gc)
3037 XFreeGC (dpy, f->output_data.x->cursor_gc);
3038 f->output_data.x->cursor_gc = 0;
3041 if (f->output_data.x->border_tile)
3043 XFreePixmap (dpy, f->output_data.x->border_tile);
3044 f->output_data.x->border_tile = 0;
3047 UNBLOCK_INPUT;
3051 /* Handler for signals raised during x_create_frame and
3052 x_create_top_frame. FRAME is the frame which is partially
3053 constructed. */
3055 static Lisp_Object
3056 unwind_create_frame (frame)
3057 Lisp_Object frame;
3059 struct frame *f = XFRAME (frame);
3061 /* If frame is already dead, nothing to do. This can happen if the
3062 display is disconnected after the frame has become official, but
3063 before x_create_frame removes the unwind protect. */
3064 if (!FRAME_LIVE_P (f))
3065 return Qnil;
3067 /* If frame is ``official'', nothing to do. */
3068 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
3070 #if GLYPH_DEBUG
3071 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3072 #endif
3074 x_free_frame_resources (f);
3076 #if GLYPH_DEBUG
3077 /* Check that reference counts are indeed correct. */
3078 xassert (dpyinfo->reference_count == dpyinfo_refcount);
3079 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
3080 #endif
3081 return Qt;
3084 return Qnil;
3088 static void
3089 x_default_font_parameter (f, parms)
3090 struct frame *f;
3091 Lisp_Object parms;
3093 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3094 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
3095 RES_TYPE_STRING);
3096 Lisp_Object font;
3097 int got_from_gconf = 0;
3098 if (EQ (font_param, Qunbound))
3099 font_param = Qnil;
3101 if (NILP (font_param))
3103 /* System font takes precedendce over X resources. We must suggest this
3104 regardless of font-use-system-font because .emacs may not have been
3105 read yet. */
3106 const char *system_font = xsettings_get_system_font ();
3107 if (system_font) font_param = make_string (system_font,
3108 strlen (system_font));
3111 font = !NILP (font_param) ? font_param
3112 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
3114 if (! STRINGP (font))
3116 char *names[]
3118 #ifdef HAVE_XFT
3119 /* This will find the normal Xft font. */
3120 "monospace-10",
3121 #endif
3122 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3123 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3124 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3125 /* This was formerly the first thing tried, but it finds
3126 too many fonts and takes too long. */
3127 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3128 /* If those didn't work, look for something which will
3129 at least work. */
3130 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3131 "fixed",
3132 NULL };
3133 int i;
3135 for (i = 0; names[i]; i++)
3137 font = font_open_by_name (f, names[i]);
3138 if (! NILP (font))
3139 break;
3141 if (NILP (font))
3142 error ("No suitable font was found");
3144 else if (!NILP (font_param))
3146 /* Remember the explicit font parameter, so we can re-apply it after
3147 we've applied the `default' face settings. */
3148 x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
3151 x_default_parameter (f, parms, Qfont, font,
3152 got_from_gconf ? NULL : "font",
3153 got_from_gconf ? NULL : "Font",
3154 RES_TYPE_STRING);
3158 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
3159 0, 1, 0,
3160 doc: /* Send the size hints for frame FRAME to the window manager.
3161 If FRAME is nil, use the selected frame. */)
3162 (frame)
3163 Lisp_Object frame;
3165 struct frame *f;
3166 if (NILP (frame))
3167 frame = selected_frame;
3168 f = XFRAME (frame);
3169 BLOCK_INPUT;
3170 if (FRAME_X_P (f))
3171 x_wm_set_size_hint (f, 0, 0);
3172 UNBLOCK_INPUT;
3173 return Qnil;
3176 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3177 1, 1, 0,
3178 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
3179 Return an Emacs frame object.
3180 PARMS is an alist of frame parameters.
3181 If the parameters specify that the frame should not have a minibuffer,
3182 and do not specify a specific minibuffer window to use,
3183 then `default-minibuffer-frame' must be a frame whose minibuffer can
3184 be shared by the new frame.
3186 This function is an internal primitive--use `make-frame' instead. */)
3187 (parms)
3188 Lisp_Object parms;
3190 struct frame *f;
3191 Lisp_Object frame, tem;
3192 Lisp_Object name;
3193 int minibuffer_only = 0;
3194 long window_prompting = 0;
3195 int width, height;
3196 int count = SPECPDL_INDEX ();
3197 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3198 Lisp_Object display;
3199 struct x_display_info *dpyinfo = NULL;
3200 Lisp_Object parent;
3201 struct kboard *kb;
3203 parms = Fcopy_alist (parms);
3205 /* Use this general default value to start with
3206 until we know if this frame has a specified name. */
3207 Vx_resource_name = Vinvocation_name;
3209 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
3210 if (EQ (display, Qunbound))
3211 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
3212 if (EQ (display, Qunbound))
3213 display = Qnil;
3214 dpyinfo = check_x_display_info (display);
3215 kb = dpyinfo->terminal->kboard;
3217 if (!dpyinfo->terminal->name)
3218 error ("Terminal is not live, can't create new frames on it");
3220 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
3221 if (!STRINGP (name)
3222 && ! EQ (name, Qunbound)
3223 && ! NILP (name))
3224 error ("Invalid frame name--not a string or nil");
3226 if (STRINGP (name))
3227 Vx_resource_name = name;
3229 /* See if parent window is specified. */
3230 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
3231 if (EQ (parent, Qunbound))
3232 parent = Qnil;
3233 if (! NILP (parent))
3234 CHECK_NUMBER (parent);
3236 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3237 /* No need to protect DISPLAY because that's not used after passing
3238 it to make_frame_without_minibuffer. */
3239 frame = Qnil;
3240 GCPRO4 (parms, parent, name, frame);
3241 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
3242 RES_TYPE_SYMBOL);
3243 if (EQ (tem, Qnone) || NILP (tem))
3244 f = make_frame_without_minibuffer (Qnil, kb, display);
3245 else if (EQ (tem, Qonly))
3247 f = make_minibuffer_frame ();
3248 minibuffer_only = 1;
3250 else if (WINDOWP (tem))
3251 f = make_frame_without_minibuffer (tem, kb, display);
3252 else
3253 f = make_frame (1);
3255 XSETFRAME (frame, f);
3257 /* Note that X Windows does support scroll bars. */
3258 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3260 f->terminal = dpyinfo->terminal;
3261 f->terminal->reference_count++;
3263 f->output_method = output_x_window;
3264 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
3265 bzero (f->output_data.x, sizeof (struct x_output));
3266 f->output_data.x->icon_bitmap = -1;
3267 FRAME_FONTSET (f) = -1;
3268 f->output_data.x->scroll_bar_foreground_pixel = -1;
3269 f->output_data.x->scroll_bar_background_pixel = -1;
3270 #ifdef USE_TOOLKIT_SCROLL_BARS
3271 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
3272 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
3273 #endif /* USE_TOOLKIT_SCROLL_BARS */
3275 f->icon_name
3276 = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3277 RES_TYPE_STRING);
3278 if (! STRINGP (f->icon_name))
3279 f->icon_name = Qnil;
3281 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3283 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3284 record_unwind_protect (unwind_create_frame, frame);
3285 #if GLYPH_DEBUG
3286 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
3287 dpyinfo_refcount = dpyinfo->reference_count;
3288 #endif /* GLYPH_DEBUG */
3290 /* These colors will be set anyway later, but it's important
3291 to get the color reference counts right, so initialize them! */
3293 Lisp_Object black;
3294 struct gcpro gcpro1;
3296 /* Function x_decode_color can signal an error. Make
3297 sure to initialize color slots so that we won't try
3298 to free colors we haven't allocated. */
3299 FRAME_FOREGROUND_PIXEL (f) = -1;
3300 FRAME_BACKGROUND_PIXEL (f) = -1;
3301 f->output_data.x->cursor_pixel = -1;
3302 f->output_data.x->cursor_foreground_pixel = -1;
3303 f->output_data.x->border_pixel = -1;
3304 f->output_data.x->mouse_pixel = -1;
3306 black = build_string ("black");
3307 GCPRO1 (black);
3308 FRAME_FOREGROUND_PIXEL (f)
3309 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3310 FRAME_BACKGROUND_PIXEL (f)
3311 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3312 f->output_data.x->cursor_pixel
3313 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3314 f->output_data.x->cursor_foreground_pixel
3315 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3316 f->output_data.x->border_pixel
3317 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3318 f->output_data.x->mouse_pixel
3319 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3320 UNGCPRO;
3323 /* Specify the parent under which to make this X window. */
3325 if (!NILP (parent))
3327 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3328 f->output_data.x->explicit_parent = 1;
3330 else
3332 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3333 f->output_data.x->explicit_parent = 0;
3336 /* Set the name; the functions to which we pass f expect the name to
3337 be set. */
3338 if (EQ (name, Qunbound) || NILP (name))
3340 f->name = build_string (dpyinfo->x_id_name);
3341 f->explicit_name = 0;
3343 else
3345 f->name = name;
3346 f->explicit_name = 1;
3347 /* use the frame's title when getting resources for this frame. */
3348 specbind (Qx_resource_name, name);
3351 f->resx = dpyinfo->resx;
3352 f->resy = dpyinfo->resy;
3354 #ifdef HAVE_FREETYPE
3355 #ifdef HAVE_XFT
3356 register_font_driver (&xftfont_driver, f);
3357 #else /* not HAVE_XFT */
3358 register_font_driver (&ftxfont_driver, f);
3359 #endif /* not HAVE_XFT */
3360 #endif /* HAVE_FREETYPE */
3361 register_font_driver (&xfont_driver, f);
3363 x_default_parameter (f, parms, Qfont_backend, Qnil,
3364 "fontBackend", "FontBackend", RES_TYPE_STRING);
3366 /* Extract the window parameters from the supplied values
3367 that are needed to determine window geometry. */
3368 x_default_font_parameter (f, parms);
3369 if (!FRAME_FONT (f))
3371 delete_frame (frame, Qnoelisp);
3372 error ("Invalid frame font");
3375 #ifdef USE_LUCID
3376 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3377 whereby it fails to get any font. */
3378 BLOCK_INPUT;
3379 xlwmenu_default_font = XLoadQueryFont (FRAME_X_DISPLAY (f), "fixed");
3380 UNBLOCK_INPUT;
3381 #endif
3383 /* Frame contents get displaced if an embedded X window has a border. */
3384 if (! FRAME_X_EMBEDDED_P (f))
3385 x_default_parameter (f, parms, Qborder_width, make_number (2),
3386 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3388 /* This defaults to 1 in order to match xterm. We recognize either
3389 internalBorderWidth or internalBorder (which is what xterm calls
3390 it). */
3391 if (NILP (Fassq (Qinternal_border_width, parms)))
3393 Lisp_Object value;
3395 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3396 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3397 if (! EQ (value, Qunbound))
3398 parms = Fcons (Fcons (Qinternal_border_width, value),
3399 parms);
3401 x_default_parameter (f, parms, Qinternal_border_width,
3402 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3403 make_number (0),
3404 #else
3405 make_number (1),
3406 #endif
3407 "internalBorderWidth", "internalBorderWidth",
3408 RES_TYPE_NUMBER);
3409 x_default_parameter (f, parms, Qvertical_scroll_bars, Qleft,
3410 "verticalScrollBars", "ScrollBars",
3411 RES_TYPE_SYMBOL);
3413 /* Also do the stuff which must be set before the window exists. */
3414 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3415 "foreground", "Foreground", RES_TYPE_STRING);
3416 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3417 "background", "Background", RES_TYPE_STRING);
3418 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3419 "pointerColor", "Foreground", RES_TYPE_STRING);
3420 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3421 "cursorColor", "Foreground", RES_TYPE_STRING);
3422 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3423 "borderColor", "BorderColor", RES_TYPE_STRING);
3424 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3425 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3426 x_default_parameter (f, parms, Qline_spacing, Qnil,
3427 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3428 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3429 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3430 x_default_parameter (f, parms, Qright_fringe, Qnil,
3431 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3433 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3434 "scrollBarForeground",
3435 "ScrollBarForeground", 1);
3436 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3437 "scrollBarBackground",
3438 "ScrollBarBackground", 0);
3440 /* Init faces before x_default_parameter is called for scroll-bar
3441 parameters because that function calls x_set_scroll_bar_width,
3442 which calls change_frame_size, which calls Fset_window_buffer,
3443 which runs hooks, which call Fvertical_motion. At the end, we
3444 end up in init_iterator with a null face cache, which should not
3445 happen. */
3446 init_frame_faces (f);
3448 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
3449 "menuBar", "MenuBar", RES_TYPE_BOOLEAN_NUMBER);
3450 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
3451 "toolBar", "ToolBar", RES_TYPE_NUMBER);
3452 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3453 "bufferPredicate", "BufferPredicate",
3454 RES_TYPE_SYMBOL);
3455 x_default_parameter (f, parms, Qtitle, Qnil,
3456 "title", "Title", RES_TYPE_STRING);
3457 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3458 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3459 x_default_parameter (f, parms, Qfullscreen, Qnil,
3460 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3462 /* Compute the size of the X window. */
3463 window_prompting = x_figure_window_size (f, parms, 1);
3465 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3466 f->no_split = minibuffer_only || EQ (tem, Qt);
3468 x_icon_verify (f, parms);
3470 /* Create the X widget or window. */
3471 #ifdef USE_X_TOOLKIT
3472 x_window (f, window_prompting, minibuffer_only);
3473 #else
3474 x_window (f);
3475 #endif
3477 x_icon (f, parms);
3478 x_make_gc (f);
3480 /* Now consider the frame official. */
3481 FRAME_X_DISPLAY_INFO (f)->reference_count++;
3482 Vframe_list = Fcons (frame, Vframe_list);
3484 /* We need to do this after creating the X window, so that the
3485 icon-creation functions can say whose icon they're describing. */
3486 x_default_parameter (f, parms, Qicon_type, Qt,
3487 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
3489 x_default_parameter (f, parms, Qauto_raise, Qnil,
3490 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3491 x_default_parameter (f, parms, Qauto_lower, Qnil,
3492 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3493 x_default_parameter (f, parms, Qcursor_type, Qbox,
3494 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3495 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3496 "scrollBarWidth", "ScrollBarWidth",
3497 RES_TYPE_NUMBER);
3498 x_default_parameter (f, parms, Qalpha, Qnil,
3499 "alpha", "Alpha", RES_TYPE_NUMBER);
3501 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3502 Change will not be effected unless different from the current
3503 FRAME_LINES (f). */
3504 width = FRAME_COLS (f);
3505 height = FRAME_LINES (f);
3507 SET_FRAME_COLS (f, 0);
3508 FRAME_LINES (f) = 0;
3509 change_frame_size (f, height, width, 1, 0, 0);
3511 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3512 /* Create the menu bar. */
3513 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3515 /* If this signals an error, we haven't set size hints for the
3516 frame and we didn't make it visible. */
3517 initialize_frame_menubar (f);
3519 #ifndef USE_GTK
3520 /* This is a no-op, except under Motif where it arranges the
3521 main window for the widgets on it. */
3522 lw_set_main_areas (f->output_data.x->column_widget,
3523 f->output_data.x->menubar_widget,
3524 f->output_data.x->edit_widget);
3525 #endif /* not USE_GTK */
3527 #endif /* USE_X_TOOLKIT || USE_GTK */
3529 /* Tell the server what size and position, etc, we want, and how
3530 badly we want them. This should be done after we have the menu
3531 bar so that its size can be taken into account. */
3532 BLOCK_INPUT;
3533 x_wm_set_size_hint (f, window_prompting, 0);
3534 UNBLOCK_INPUT;
3536 /* Make the window appear on the frame and enable display, unless
3537 the caller says not to. However, with explicit parent, Emacs
3538 cannot control visibility, so don't try. */
3539 if (! f->output_data.x->explicit_parent)
3541 Lisp_Object visibility;
3543 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3544 RES_TYPE_SYMBOL);
3545 if (EQ (visibility, Qunbound))
3546 visibility = Qt;
3548 if (EQ (visibility, Qicon))
3549 x_iconify_frame (f);
3550 else if (! NILP (visibility))
3551 x_make_frame_visible (f);
3552 else
3553 /* Must have been Qnil. */
3557 /* Set the WM leader property. GTK does this itself, so this is not
3558 needed when using GTK. */
3559 if (dpyinfo->client_leader_window != 0)
3561 BLOCK_INPUT;
3562 XChangeProperty (FRAME_X_DISPLAY (f),
3563 FRAME_OUTER_WINDOW (f),
3564 dpyinfo->Xatom_wm_client_leader,
3565 XA_WINDOW, 32, PropModeReplace,
3566 (unsigned char *) &dpyinfo->client_leader_window, 1);
3567 UNBLOCK_INPUT;
3570 /* Initialize `default-minibuffer-frame' in case this is the first
3571 frame on this terminal. */
3572 if (FRAME_HAS_MINIBUF_P (f)
3573 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
3574 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
3575 kb->Vdefault_minibuffer_frame = frame;
3577 /* All remaining specified parameters, which have not been "used"
3578 by x_get_arg and friends, now go in the misc. alist of the frame. */
3579 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3580 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3581 f->param_alist = Fcons (XCAR (tem), f->param_alist);
3583 UNGCPRO;
3585 /* Make sure windows on this frame appear in calls to next-window
3586 and similar functions. */
3587 Vwindow_list = Qnil;
3589 return unbind_to (count, frame);
3593 /* FRAME is used only to get a handle on the X display. We don't pass the
3594 display info directly because we're called from frame.c, which doesn't
3595 know about that structure. */
3597 Lisp_Object
3598 x_get_focus_frame (frame)
3599 struct frame *frame;
3601 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3602 Lisp_Object xfocus;
3603 if (! dpyinfo->x_focus_frame)
3604 return Qnil;
3606 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3607 return xfocus;
3611 /* In certain situations, when the window manager follows a
3612 click-to-focus policy, there seems to be no way around calling
3613 XSetInputFocus to give another frame the input focus .
3615 In an ideal world, XSetInputFocus should generally be avoided so
3616 that applications don't interfere with the window manager's focus
3617 policy. But I think it's okay to use when it's clearly done
3618 following a user-command. */
3620 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3621 doc: /* Set the input focus to FRAME.
3622 FRAME nil means use the selected frame. */)
3623 (frame)
3624 Lisp_Object frame;
3626 struct frame *f = check_x_frame (frame);
3627 Display *dpy = FRAME_X_DISPLAY (f);
3629 BLOCK_INPUT;
3630 x_catch_errors (dpy);
3631 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3632 RevertToParent, CurrentTime);
3633 x_ewmh_activate_frame (f);
3634 x_uncatch_errors ();
3635 UNBLOCK_INPUT;
3637 return Qnil;
3641 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3642 doc: /* Internal function called by `color-defined-p', which see. */)
3643 (color, frame)
3644 Lisp_Object color, frame;
3646 XColor foo;
3647 FRAME_PTR f = check_x_frame (frame);
3649 CHECK_STRING (color);
3651 if (x_defined_color (f, SDATA (color), &foo, 0))
3652 return Qt;
3653 else
3654 return Qnil;
3657 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3658 doc: /* Internal function called by `color-values', which see. */)
3659 (color, frame)
3660 Lisp_Object color, frame;
3662 XColor foo;
3663 FRAME_PTR f = check_x_frame (frame);
3665 CHECK_STRING (color);
3667 if (x_defined_color (f, SDATA (color), &foo, 0))
3668 return list3 (make_number (foo.red),
3669 make_number (foo.green),
3670 make_number (foo.blue));
3671 else
3672 return Qnil;
3675 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3676 doc: /* Internal function called by `display-color-p', which see. */)
3677 (terminal)
3678 Lisp_Object terminal;
3680 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3682 if (dpyinfo->n_planes <= 2)
3683 return Qnil;
3685 switch (dpyinfo->visual->class)
3687 case StaticColor:
3688 case PseudoColor:
3689 case TrueColor:
3690 case DirectColor:
3691 return Qt;
3693 default:
3694 return Qnil;
3698 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3699 0, 1, 0,
3700 doc: /* Return t if the X display supports shades of gray.
3701 Note that color displays do support shades of gray.
3702 The optional argument TERMINAL specifies which display to ask about.
3703 TERMINAL should be a terminal object, a frame or a display name (a string).
3704 If omitted or nil, that stands for the selected frame's display. */)
3705 (terminal)
3706 Lisp_Object terminal;
3708 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3710 if (dpyinfo->n_planes <= 1)
3711 return Qnil;
3713 switch (dpyinfo->visual->class)
3715 case StaticColor:
3716 case PseudoColor:
3717 case TrueColor:
3718 case DirectColor:
3719 case StaticGray:
3720 case GrayScale:
3721 return Qt;
3723 default:
3724 return Qnil;
3728 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3729 0, 1, 0,
3730 doc: /* Return the width in pixels of the X display TERMINAL.
3731 The optional argument TERMINAL specifies which display to ask about.
3732 TERMINAL should be a terminal object, a frame or a display name (a string).
3733 If omitted or nil, that stands for the selected frame's display. */)
3734 (terminal)
3735 Lisp_Object terminal;
3737 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3739 return make_number (x_display_pixel_width (dpyinfo));
3742 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3743 Sx_display_pixel_height, 0, 1, 0,
3744 doc: /* Return the height in pixels of the X display TERMINAL.
3745 The optional argument TERMINAL specifies which display to ask about.
3746 TERMINAL should be a terminal object, a frame or a display name (a string).
3747 If omitted or nil, that stands for the selected frame's display. */)
3748 (terminal)
3749 Lisp_Object terminal;
3751 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3753 return make_number (x_display_pixel_height (dpyinfo));
3756 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3757 0, 1, 0,
3758 doc: /* Return the number of bitplanes of the X display TERMINAL.
3759 The optional argument TERMINAL specifies which display to ask about.
3760 TERMINAL should be a terminal object, a frame or a display name (a string).
3761 If omitted or nil, that stands for the selected frame's display. */)
3762 (terminal)
3763 Lisp_Object terminal;
3765 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3767 return make_number (dpyinfo->n_planes);
3770 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3771 0, 1, 0,
3772 doc: /* Return the number of color cells of the X display TERMINAL.
3773 The optional argument TERMINAL specifies which display to ask about.
3774 TERMINAL should be a terminal object, a frame or a display name (a string).
3775 If omitted or nil, that stands for the selected frame's display. */)
3776 (terminal)
3777 Lisp_Object terminal;
3779 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3781 int nr_planes = DisplayPlanes (dpyinfo->display,
3782 XScreenNumberOfScreen (dpyinfo->screen));
3784 /* Truncate nr_planes to 24 to avoid integer overflow.
3785 Some displays says 32, but only 24 bits are actually significant.
3786 There are only very few and rare video cards that have more than
3787 24 significant bits. Also 24 bits is more than 16 million colors,
3788 it "should be enough for everyone". */
3789 if (nr_planes > 24) nr_planes = 24;
3791 return make_number (1 << nr_planes);
3794 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3795 Sx_server_max_request_size,
3796 0, 1, 0,
3797 doc: /* Return the maximum request size of the X server of display TERMINAL.
3798 The optional argument TERMINAL specifies which display to ask about.
3799 TERMINAL should be a terminal object, a frame or a display name (a string).
3800 If omitted or nil, that stands for the selected frame's display. */)
3801 (terminal)
3802 Lisp_Object terminal;
3804 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3806 return make_number (MAXREQUEST (dpyinfo->display));
3809 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3810 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3811 \(Labelling every distributor as a "vendor" embodies the false assumption
3812 that operating systems cannot be developed and distributed noncommercially.)
3813 The optional argument TERMINAL specifies which display to ask about.
3814 TERMINAL should be a terminal object, a frame or a display name (a string).
3815 If omitted or nil, that stands for the selected frame's display. */)
3816 (terminal)
3817 Lisp_Object terminal;
3819 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3820 char *vendor = ServerVendor (dpyinfo->display);
3822 if (! vendor) vendor = "";
3823 return build_string (vendor);
3826 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3827 doc: /* Return the version numbers of the X server of display TERMINAL.
3828 The value is a list of three integers: the major and minor
3829 version numbers of the X Protocol in use, and the distributor-specific release
3830 number. See also the function `x-server-vendor'.
3832 The optional argument TERMINAL specifies which display to ask about.
3833 TERMINAL should be a terminal object, a frame or a display name (a string).
3834 If omitted or nil, that stands for the selected frame's display. */)
3835 (terminal)
3836 Lisp_Object terminal;
3838 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3839 Display *dpy = dpyinfo->display;
3841 return Fcons (make_number (ProtocolVersion (dpy)),
3842 Fcons (make_number (ProtocolRevision (dpy)),
3843 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3846 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3847 doc: /* Return the number of screens on the X server of display TERMINAL.
3848 The optional argument TERMINAL specifies which display to ask about.
3849 TERMINAL should be a terminal object, a frame or a display name (a string).
3850 If omitted or nil, that stands for the selected frame's display. */)
3851 (terminal)
3852 Lisp_Object terminal;
3854 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3856 return make_number (ScreenCount (dpyinfo->display));
3859 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3860 doc: /* Return the height in millimeters of the X display TERMINAL.
3861 The optional argument TERMINAL specifies which display to ask about.
3862 TERMINAL should be a terminal object, a frame or a display name (a string).
3863 If omitted or nil, that stands for the selected frame's display. */)
3864 (terminal)
3865 Lisp_Object terminal;
3867 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3869 return make_number (HeightMMOfScreen (dpyinfo->screen));
3872 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3873 doc: /* Return the width in millimeters of the X display TERMINAL.
3874 The optional argument TERMINAL specifies which display to ask about.
3875 TERMINAL should be a terminal object, a frame or a display name (a string).
3876 If omitted or nil, that stands for the selected frame's display. */)
3877 (terminal)
3878 Lisp_Object terminal;
3880 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3882 return make_number (WidthMMOfScreen (dpyinfo->screen));
3885 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3886 Sx_display_backing_store, 0, 1, 0,
3887 doc: /* Return an indication of whether X display TERMINAL does backing store.
3888 The value may be `always', `when-mapped', or `not-useful'.
3889 The optional argument TERMINAL specifies which display to ask about.
3890 TERMINAL should be a terminal object, a frame or a display name (a string).
3891 If omitted or nil, that stands for the selected frame's display. */)
3892 (terminal)
3893 Lisp_Object terminal;
3895 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3896 Lisp_Object result;
3898 switch (DoesBackingStore (dpyinfo->screen))
3900 case Always:
3901 result = intern ("always");
3902 break;
3904 case WhenMapped:
3905 result = intern ("when-mapped");
3906 break;
3908 case NotUseful:
3909 result = intern ("not-useful");
3910 break;
3912 default:
3913 error ("Strange value for BackingStore parameter of screen");
3914 result = Qnil;
3917 return result;
3920 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3921 Sx_display_visual_class, 0, 1, 0,
3922 doc: /* Return the visual class of the X display TERMINAL.
3923 The value is one of the symbols `static-gray', `gray-scale',
3924 `static-color', `pseudo-color', `true-color', or `direct-color'.
3926 The optional argument TERMINAL specifies which display to ask about.
3927 TERMINAL should a terminal object, a frame or a display name (a string).
3928 If omitted or nil, that stands for the selected frame's display. */)
3929 (terminal)
3930 Lisp_Object terminal;
3932 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3933 Lisp_Object result;
3935 switch (dpyinfo->visual->class)
3937 case StaticGray:
3938 result = intern ("static-gray");
3939 break;
3940 case GrayScale:
3941 result = intern ("gray-scale");
3942 break;
3943 case StaticColor:
3944 result = intern ("static-color");
3945 break;
3946 case PseudoColor:
3947 result = intern ("pseudo-color");
3948 break;
3949 case TrueColor:
3950 result = intern ("true-color");
3951 break;
3952 case DirectColor:
3953 result = intern ("direct-color");
3954 break;
3955 default:
3956 error ("Display has an unknown visual class");
3957 result = Qnil;
3960 return result;
3963 DEFUN ("x-display-save-under", Fx_display_save_under,
3964 Sx_display_save_under, 0, 1, 0,
3965 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3966 The optional argument TERMINAL specifies which display to ask about.
3967 TERMINAL should be a terminal object, a frame or a display name (a string).
3968 If omitted or nil, that stands for the selected frame's display. */)
3969 (terminal)
3970 Lisp_Object terminal;
3972 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3974 if (DoesSaveUnders (dpyinfo->screen) == True)
3975 return Qt;
3976 else
3977 return Qnil;
3981 x_pixel_width (f)
3982 register struct frame *f;
3984 return FRAME_PIXEL_WIDTH (f);
3988 x_pixel_height (f)
3989 register struct frame *f;
3991 return FRAME_PIXEL_HEIGHT (f);
3995 x_char_width (f)
3996 register struct frame *f;
3998 return FRAME_COLUMN_WIDTH (f);
4002 x_char_height (f)
4003 register struct frame *f;
4005 return FRAME_LINE_HEIGHT (f);
4009 x_screen_planes (f)
4010 register struct frame *f;
4012 return FRAME_X_DISPLAY_INFO (f)->n_planes;
4017 /************************************************************************
4018 X Displays
4019 ************************************************************************/
4022 /* Mapping visual names to visuals. */
4024 static struct visual_class
4026 char *name;
4027 int class;
4029 visual_classes[] =
4031 {"StaticGray", StaticGray},
4032 {"GrayScale", GrayScale},
4033 {"StaticColor", StaticColor},
4034 {"PseudoColor", PseudoColor},
4035 {"TrueColor", TrueColor},
4036 {"DirectColor", DirectColor},
4037 {NULL, 0}
4041 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4043 /* Value is the screen number of screen SCR. This is a substitute for
4044 the X function with the same name when that doesn't exist. */
4047 XScreenNumberOfScreen (scr)
4048 register Screen *scr;
4050 Display *dpy = scr->display;
4051 int i;
4053 for (i = 0; i < dpy->nscreens; ++i)
4054 if (scr == dpy->screens + i)
4055 break;
4057 return i;
4060 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4063 /* Select the visual that should be used on display DPYINFO. Set
4064 members of DPYINFO appropriately. Called from x_term_init. */
4066 void
4067 select_visual (dpyinfo)
4068 struct x_display_info *dpyinfo;
4070 Display *dpy = dpyinfo->display;
4071 Screen *screen = dpyinfo->screen;
4072 Lisp_Object value;
4074 /* See if a visual is specified. */
4075 value = display_x_get_resource (dpyinfo,
4076 build_string ("visualClass"),
4077 build_string ("VisualClass"),
4078 Qnil, Qnil);
4079 if (STRINGP (value))
4081 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4082 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4083 depth, a decimal number. NAME is compared with case ignored. */
4084 char *s = (char *) alloca (SBYTES (value) + 1);
4085 char *dash;
4086 int i, class = -1;
4087 XVisualInfo vinfo;
4089 strcpy (s, SDATA (value));
4090 dash = index (s, '-');
4091 if (dash)
4093 dpyinfo->n_planes = atoi (dash + 1);
4094 *dash = '\0';
4096 else
4097 /* We won't find a matching visual with depth 0, so that
4098 an error will be printed below. */
4099 dpyinfo->n_planes = 0;
4101 /* Determine the visual class. */
4102 for (i = 0; visual_classes[i].name; ++i)
4103 if (xstrcasecmp (s, visual_classes[i].name) == 0)
4105 class = visual_classes[i].class;
4106 break;
4109 /* Look up a matching visual for the specified class. */
4110 if (class == -1
4111 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4112 dpyinfo->n_planes, class, &vinfo))
4113 fatal ("Invalid visual specification `%s'", SDATA (value));
4115 dpyinfo->visual = vinfo.visual;
4117 else
4119 int n_visuals;
4120 XVisualInfo *vinfo, vinfo_template;
4122 dpyinfo->visual = DefaultVisualOfScreen (screen);
4124 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4125 vinfo_template.screen = XScreenNumberOfScreen (screen);
4126 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4127 &vinfo_template, &n_visuals);
4128 if (n_visuals != 1)
4129 fatal ("Can't get proper X visual info");
4131 dpyinfo->n_planes = vinfo->depth;
4132 XFree ((char *) vinfo);
4137 /* Return the X display structure for the display named NAME.
4138 Open a new connection if necessary. */
4140 struct x_display_info *
4141 x_display_info_for_name (name)
4142 Lisp_Object name;
4144 Lisp_Object names;
4145 struct x_display_info *dpyinfo;
4147 CHECK_STRING (name);
4149 #if 0
4150 if (! EQ (Vinitial_window_system, intern ("x")))
4151 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4152 #endif
4154 for (dpyinfo = x_display_list, names = x_display_name_list;
4155 dpyinfo;
4156 dpyinfo = dpyinfo->next, names = XCDR (names))
4158 Lisp_Object tem;
4159 tem = Fstring_equal (XCAR (XCAR (names)), name);
4160 if (!NILP (tem))
4161 return dpyinfo;
4164 /* Use this general default value to start with. */
4165 Vx_resource_name = Vinvocation_name;
4167 validate_x_resource_name ();
4169 dpyinfo = x_term_init (name, (char *)0,
4170 (char *) SDATA (Vx_resource_name));
4172 if (dpyinfo == 0)
4173 error ("Cannot connect to X server %s", SDATA (name));
4175 x_in_use = 1;
4176 XSETFASTINT (Vwindow_system_version, 11);
4178 return dpyinfo;
4182 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4183 1, 3, 0,
4184 doc: /* Open a connection to an X server.
4185 DISPLAY is the name of the display to connect to.
4186 Optional second arg XRM-STRING is a string of resources in xrdb format.
4187 If the optional third arg MUST-SUCCEED is non-nil,
4188 terminate Emacs if we can't open the connection. */)
4189 (display, xrm_string, must_succeed)
4190 Lisp_Object display, xrm_string, must_succeed;
4192 unsigned char *xrm_option;
4193 struct x_display_info *dpyinfo;
4195 CHECK_STRING (display);
4196 if (! NILP (xrm_string))
4197 CHECK_STRING (xrm_string);
4199 #if 0
4200 if (! EQ (Vinitial_window_system, intern ("x")))
4201 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4202 #endif
4204 if (! NILP (xrm_string))
4205 xrm_option = (unsigned char *) SDATA (xrm_string);
4206 else
4207 xrm_option = (unsigned char *) 0;
4209 validate_x_resource_name ();
4211 /* This is what opens the connection and sets x_current_display.
4212 This also initializes many symbols, such as those used for input. */
4213 dpyinfo = x_term_init (display, xrm_option,
4214 (char *) SDATA (Vx_resource_name));
4216 if (dpyinfo == 0)
4218 if (!NILP (must_succeed))
4219 fatal ("Cannot connect to X server %s.\n\
4220 Check the DISPLAY environment variable or use `-d'.\n\
4221 Also use the `xauth' program to verify that you have the proper\n\
4222 authorization information needed to connect the X server.\n\
4223 An insecure way to solve the problem may be to use `xhost'.\n",
4224 SDATA (display));
4225 else
4226 error ("Cannot connect to X server %s", SDATA (display));
4229 x_in_use = 1;
4231 XSETFASTINT (Vwindow_system_version, 11);
4232 return Qnil;
4235 DEFUN ("x-close-connection", Fx_close_connection,
4236 Sx_close_connection, 1, 1, 0,
4237 doc: /* Close the connection to TERMINAL's X server.
4238 For TERMINAL, specify a terminal object, a frame or a display name (a
4239 string). If TERMINAL is nil, that stands for the selected frame's
4240 terminal. */)
4241 (terminal)
4242 Lisp_Object terminal;
4244 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4246 if (dpyinfo->reference_count > 0)
4247 error ("Display still has frames on it");
4249 x_delete_terminal (dpyinfo->terminal);
4251 return Qnil;
4254 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4255 doc: /* Return the list of display names that Emacs has connections to. */)
4258 Lisp_Object tail, result;
4260 result = Qnil;
4261 for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
4262 result = Fcons (XCAR (XCAR (tail)), result);
4264 return result;
4267 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4268 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4269 If ON is nil, allow buffering of requests.
4270 Turning on synchronization prohibits the Xlib routines from buffering
4271 requests and seriously degrades performance, but makes debugging much
4272 easier.
4273 The optional second argument TERMINAL specifies which display to act on.
4274 TERMINAL should be a terminal object, a frame or a display name (a string).
4275 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4276 (on, terminal)
4277 Lisp_Object terminal, on;
4279 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4281 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4283 return Qnil;
4286 /* Wait for responses to all X commands issued so far for frame F. */
4288 void
4289 x_sync (f)
4290 FRAME_PTR f;
4292 BLOCK_INPUT;
4293 XSync (FRAME_X_DISPLAY (f), False);
4294 UNBLOCK_INPUT;
4298 /***********************************************************************
4299 Window properties
4300 ***********************************************************************/
4302 DEFUN ("x-change-window-property", Fx_change_window_property,
4303 Sx_change_window_property, 2, 6, 0,
4304 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4305 PROP must be a string.
4306 VALUE may be a string or a list of conses, numbers and/or strings.
4307 If an element in the list is a string, it is converted to
4308 an Atom and the value of the Atom is used. If an element is a cons,
4309 it is converted to a 32 bit number where the car is the 16 top bits and the
4310 cdr is the lower 16 bits.
4311 FRAME nil or omitted means use the selected frame.
4312 If TYPE is given and non-nil, it is the name of the type of VALUE.
4313 If TYPE is not given or nil, the type is STRING.
4314 FORMAT gives the size in bits of each element if VALUE is a list.
4315 It must be one of 8, 16 or 32.
4316 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4317 If OUTER_P is non-nil, the property is changed for the outer X window of
4318 FRAME. Default is to change on the edit X window.
4320 Value is VALUE. */)
4321 (prop, value, frame, type, format, outer_p)
4322 Lisp_Object prop, value, frame, type, format, outer_p;
4324 struct frame *f = check_x_frame (frame);
4325 Atom prop_atom;
4326 Atom target_type = XA_STRING;
4327 int element_format = 8;
4328 unsigned char *data;
4329 int nelements;
4330 Window w;
4332 CHECK_STRING (prop);
4334 if (! NILP (format))
4336 CHECK_NUMBER (format);
4337 element_format = XFASTINT (format);
4339 if (element_format != 8 && element_format != 16
4340 && element_format != 32)
4341 error ("FORMAT must be one of 8, 16 or 32");
4344 if (CONSP (value))
4346 nelements = x_check_property_data (value);
4347 if (nelements == -1)
4348 error ("Bad data in VALUE, must be number, string or cons");
4350 if (element_format == 8)
4351 data = (unsigned char *) xmalloc (nelements);
4352 else if (element_format == 16)
4353 data = (unsigned char *) xmalloc (nelements*2);
4354 else /* format == 32 */
4355 /* The man page for XChangeProperty:
4356 "If the specified format is 32, the property data must be a
4357 long array."
4358 This applies even if long is more than 64 bits. The X library
4359 converts to 32 bits before sending to the X server. */
4360 data = (unsigned char *) xmalloc (nelements * sizeof(long));
4362 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4364 else
4366 CHECK_STRING (value);
4367 data = SDATA (value);
4368 nelements = SCHARS (value);
4371 BLOCK_INPUT;
4372 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4373 if (! NILP (type))
4375 CHECK_STRING (type);
4376 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4379 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4380 else w = FRAME_X_WINDOW (f);
4382 XChangeProperty (FRAME_X_DISPLAY (f), w,
4383 prop_atom, target_type, element_format, PropModeReplace,
4384 data, nelements);
4386 if (CONSP (value)) xfree (data);
4388 /* Make sure the property is set when we return. */
4389 XFlush (FRAME_X_DISPLAY (f));
4390 UNBLOCK_INPUT;
4392 return value;
4396 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4397 Sx_delete_window_property, 1, 2, 0,
4398 doc: /* Remove window property PROP from X window of FRAME.
4399 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4400 (prop, frame)
4401 Lisp_Object prop, frame;
4403 struct frame *f = check_x_frame (frame);
4404 Atom prop_atom;
4406 CHECK_STRING (prop);
4407 BLOCK_INPUT;
4408 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4409 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4411 /* Make sure the property is removed when we return. */
4412 XFlush (FRAME_X_DISPLAY (f));
4413 UNBLOCK_INPUT;
4415 return prop;
4419 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4420 1, 6, 0,
4421 doc: /* Value is the value of window property PROP on FRAME.
4422 If FRAME is nil or omitted, use the selected frame.
4423 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4424 is the name of the Atom that denotes the type expected.
4425 If SOURCE is non-nil, get the property on that window instead of from
4426 FRAME. The number 0 denotes the root window.
4427 If DELETE_P is non-nil, delete the property after retreiving it.
4428 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4430 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4431 no value of TYPE. */)
4432 (prop, frame, type, source, delete_p, vector_ret_p)
4433 Lisp_Object prop, frame, type, source, delete_p, vector_ret_p;
4435 struct frame *f = check_x_frame (frame);
4436 Atom prop_atom;
4437 int rc;
4438 Lisp_Object prop_value = Qnil;
4439 unsigned char *tmp_data = NULL;
4440 Atom actual_type;
4441 Atom target_type = XA_STRING;
4442 int actual_format;
4443 unsigned long actual_size, bytes_remaining;
4444 Window target_window = FRAME_X_WINDOW (f);
4445 struct gcpro gcpro1;
4447 GCPRO1 (prop_value);
4448 CHECK_STRING (prop);
4450 if (! NILP (source))
4452 if (NUMBERP (source))
4454 if (FLOATP (source))
4455 target_window = (Window) XFLOAT (source);
4456 else
4457 target_window = XFASTINT (source);
4459 if (target_window == 0)
4460 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4462 else if (CONSP (source))
4463 target_window = cons_to_long (source);
4466 BLOCK_INPUT;
4467 if (STRINGP (type))
4469 if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
4470 target_type = AnyPropertyType;
4471 else
4472 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4475 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4476 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4477 prop_atom, 0, 0, False, target_type,
4478 &actual_type, &actual_format, &actual_size,
4479 &bytes_remaining, &tmp_data);
4480 if (rc == Success)
4482 int size = bytes_remaining;
4484 XFree (tmp_data);
4485 tmp_data = NULL;
4487 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4488 prop_atom, 0, bytes_remaining,
4489 ! NILP (delete_p), target_type,
4490 &actual_type, &actual_format,
4491 &actual_size, &bytes_remaining,
4492 &tmp_data);
4493 if (rc == Success && tmp_data)
4495 /* The man page for XGetWindowProperty says:
4496 "If the returned format is 32, the returned data is represented
4497 as a long array and should be cast to that type to obtain the
4498 elements."
4499 This applies even if long is more than 32 bits, the X library
4500 converts from 32 bit elements received from the X server to long
4501 and passes the long array to us. Thus, for that case bcopy can not
4502 be used. We convert to a 32 bit type here, because so much code
4503 assume on that.
4505 The bytes and offsets passed to XGetWindowProperty refers to the
4506 property and those are indeed in 32 bit quantities if format is
4507 32. */
4509 if (actual_format == 32 && actual_format < BITS_PER_LONG)
4511 unsigned long i;
4512 int *idata = (int *) tmp_data;
4513 long *ldata = (long *) tmp_data;
4515 for (i = 0; i < actual_size; ++i)
4516 idata[i] = (int) ldata[i];
4519 if (NILP (vector_ret_p))
4520 prop_value = make_string (tmp_data, size);
4521 else
4522 prop_value = x_property_data_to_lisp (f,
4523 tmp_data,
4524 actual_type,
4525 actual_format,
4526 actual_size);
4529 if (tmp_data) XFree (tmp_data);
4532 UNBLOCK_INPUT;
4533 UNGCPRO;
4534 return prop_value;
4539 /***********************************************************************
4540 Busy cursor
4541 ***********************************************************************/
4543 /* Timer function of hourglass_atimer. TIMER is equal to
4544 hourglass_atimer.
4546 Display an hourglass pointer on all frames by mapping the frames'
4547 hourglass_window. Set the hourglass_p flag in the frames'
4548 output_data.x structure to indicate that an hourglass cursor is
4549 shown on the frames. */
4551 void
4552 show_hourglass (timer)
4553 struct atimer *timer;
4555 /* The timer implementation will cancel this timer automatically
4556 after this function has run. Set hourglass_atimer to null
4557 so that we know the timer doesn't have to be canceled. */
4558 hourglass_atimer = NULL;
4560 if (!hourglass_shown_p)
4562 Lisp_Object rest, frame;
4564 BLOCK_INPUT;
4566 FOR_EACH_FRAME (rest, frame)
4568 struct frame *f = XFRAME (frame);
4570 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4572 Display *dpy = FRAME_X_DISPLAY (f);
4574 #ifdef USE_X_TOOLKIT
4575 if (f->output_data.x->widget)
4576 #else
4577 if (FRAME_OUTER_WINDOW (f))
4578 #endif
4580 f->output_data.x->hourglass_p = 1;
4582 if (!f->output_data.x->hourglass_window)
4584 unsigned long mask = CWCursor;
4585 XSetWindowAttributes attrs;
4586 #ifdef USE_GTK
4587 Window parent = FRAME_X_WINDOW (f);
4588 #else
4589 Window parent = FRAME_OUTER_WINDOW (f);
4590 #endif
4591 attrs.cursor = f->output_data.x->hourglass_cursor;
4593 f->output_data.x->hourglass_window
4594 = XCreateWindow (dpy, parent,
4595 0, 0, 32000, 32000, 0, 0,
4596 InputOnly,
4597 CopyFromParent,
4598 mask, &attrs);
4601 XMapRaised (dpy, f->output_data.x->hourglass_window);
4602 XFlush (dpy);
4607 hourglass_shown_p = 1;
4608 UNBLOCK_INPUT;
4613 /* Hide the hourglass pointer on all frames, if it is currently
4614 shown. */
4616 void
4617 hide_hourglass ()
4619 if (hourglass_shown_p)
4621 Lisp_Object rest, frame;
4623 BLOCK_INPUT;
4624 FOR_EACH_FRAME (rest, frame)
4626 struct frame *f = XFRAME (frame);
4628 if (FRAME_X_P (f)
4629 /* Watch out for newly created frames. */
4630 && f->output_data.x->hourglass_window)
4632 XUnmapWindow (FRAME_X_DISPLAY (f),
4633 f->output_data.x->hourglass_window);
4634 /* Sync here because XTread_socket looks at the
4635 hourglass_p flag that is reset to zero below. */
4636 XSync (FRAME_X_DISPLAY (f), False);
4637 f->output_data.x->hourglass_p = 0;
4641 hourglass_shown_p = 0;
4642 UNBLOCK_INPUT;
4648 /***********************************************************************
4649 Tool tips
4650 ***********************************************************************/
4652 static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *,
4653 Lisp_Object, Lisp_Object));
4654 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
4655 Lisp_Object, int, int, int *, int *));
4657 /* The frame of a currently visible tooltip. */
4659 Lisp_Object tip_frame;
4661 /* If non-nil, a timer started that hides the last tooltip when it
4662 fires. */
4664 Lisp_Object tip_timer;
4665 Window tip_window;
4667 /* If non-nil, a vector of 3 elements containing the last args
4668 with which x-show-tip was called. See there. */
4670 Lisp_Object last_show_tip_args;
4672 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4674 Lisp_Object Vx_max_tooltip_size;
4677 static Lisp_Object
4678 unwind_create_tip_frame (frame)
4679 Lisp_Object frame;
4681 Lisp_Object deleted;
4683 deleted = unwind_create_frame (frame);
4684 if (EQ (deleted, Qt))
4686 tip_window = None;
4687 tip_frame = Qnil;
4690 return deleted;
4694 /* Create a frame for a tooltip on the display described by DPYINFO.
4695 PARMS is a list of frame parameters. TEXT is the string to
4696 display in the tip frame. Value is the frame.
4698 Note that functions called here, esp. x_default_parameter can
4699 signal errors, for instance when a specified color name is
4700 undefined. We have to make sure that we're in a consistent state
4701 when this happens. */
4703 static Lisp_Object
4704 x_create_tip_frame (dpyinfo, parms, text)
4705 struct x_display_info *dpyinfo;
4706 Lisp_Object parms, text;
4708 struct frame *f;
4709 Lisp_Object frame, tem;
4710 Lisp_Object name;
4711 long window_prompting = 0;
4712 int width, height;
4713 int count = SPECPDL_INDEX ();
4714 struct gcpro gcpro1, gcpro2, gcpro3;
4715 int face_change_count_before = face_change_count;
4716 Lisp_Object buffer;
4717 struct buffer *old_buffer;
4719 check_x ();
4721 if (!dpyinfo->terminal->name)
4722 error ("Terminal is not live, can't create new frames on it");
4724 parms = Fcopy_alist (parms);
4726 /* Get the name of the frame to use for resource lookup. */
4727 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4728 if (!STRINGP (name)
4729 && !EQ (name, Qunbound)
4730 && !NILP (name))
4731 error ("Invalid frame name--not a string or nil");
4733 frame = Qnil;
4734 GCPRO3 (parms, name, frame);
4735 f = make_frame (1);
4736 XSETFRAME (frame, f);
4738 buffer = Fget_buffer_create (build_string (" *tip*"));
4739 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
4740 old_buffer = current_buffer;
4741 set_buffer_internal_1 (XBUFFER (buffer));
4742 current_buffer->truncate_lines = Qnil;
4743 specbind (Qinhibit_read_only, Qt);
4744 specbind (Qinhibit_modification_hooks, Qt);
4745 Ferase_buffer ();
4746 Finsert (1, &text);
4747 set_buffer_internal_1 (old_buffer);
4749 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4750 record_unwind_protect (unwind_create_tip_frame, frame);
4752 f->terminal = dpyinfo->terminal;
4753 f->terminal->reference_count++;
4755 /* By setting the output method, we're essentially saying that
4756 the frame is live, as per FRAME_LIVE_P. If we get a signal
4757 from this point on, x_destroy_window might screw up reference
4758 counts etc. */
4759 f->output_method = output_x_window;
4760 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
4761 bzero (f->output_data.x, sizeof (struct x_output));
4762 f->output_data.x->icon_bitmap = -1;
4763 FRAME_FONTSET (f) = -1;
4764 f->output_data.x->scroll_bar_foreground_pixel = -1;
4765 f->output_data.x->scroll_bar_background_pixel = -1;
4766 #ifdef USE_TOOLKIT_SCROLL_BARS
4767 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4768 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4769 #endif /* USE_TOOLKIT_SCROLL_BARS */
4770 f->icon_name = Qnil;
4771 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4772 #if GLYPH_DEBUG
4773 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
4774 dpyinfo_refcount = dpyinfo->reference_count;
4775 #endif /* GLYPH_DEBUG */
4776 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4777 f->output_data.x->explicit_parent = 0;
4779 /* These colors will be set anyway later, but it's important
4780 to get the color reference counts right, so initialize them! */
4782 Lisp_Object black;
4783 struct gcpro gcpro1;
4785 /* Function x_decode_color can signal an error. Make
4786 sure to initialize color slots so that we won't try
4787 to free colors we haven't allocated. */
4788 FRAME_FOREGROUND_PIXEL (f) = -1;
4789 FRAME_BACKGROUND_PIXEL (f) = -1;
4790 f->output_data.x->cursor_pixel = -1;
4791 f->output_data.x->cursor_foreground_pixel = -1;
4792 f->output_data.x->border_pixel = -1;
4793 f->output_data.x->mouse_pixel = -1;
4795 black = build_string ("black");
4796 GCPRO1 (black);
4797 FRAME_FOREGROUND_PIXEL (f)
4798 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4799 FRAME_BACKGROUND_PIXEL (f)
4800 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4801 f->output_data.x->cursor_pixel
4802 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4803 f->output_data.x->cursor_foreground_pixel
4804 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4805 f->output_data.x->border_pixel
4806 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4807 f->output_data.x->mouse_pixel
4808 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4809 UNGCPRO;
4812 /* Set the name; the functions to which we pass f expect the name to
4813 be set. */
4814 if (EQ (name, Qunbound) || NILP (name))
4816 f->name = build_string (dpyinfo->x_id_name);
4817 f->explicit_name = 0;
4819 else
4821 f->name = name;
4822 f->explicit_name = 1;
4823 /* use the frame's title when getting resources for this frame. */
4824 specbind (Qx_resource_name, name);
4827 f->resx = dpyinfo->resx;
4828 f->resy = dpyinfo->resy;
4830 register_font_driver (&xfont_driver, f);
4831 #ifdef HAVE_FREETYPE
4832 #ifdef HAVE_XFT
4833 register_font_driver (&xftfont_driver, f);
4834 #else /* not HAVE_XFT */
4835 register_font_driver (&ftxfont_driver, f);
4836 #endif /* not HAVE_XFT */
4837 #endif /* HAVE_FREETYPE */
4839 x_default_parameter (f, parms, Qfont_backend, Qnil,
4840 "fontBackend", "FontBackend", RES_TYPE_STRING);
4842 /* Extract the window parameters from the supplied values that are
4843 needed to determine window geometry. */
4844 x_default_font_parameter (f, parms);
4846 x_default_parameter (f, parms, Qborder_width, make_number (2),
4847 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4849 /* This defaults to 2 in order to match xterm. We recognize either
4850 internalBorderWidth or internalBorder (which is what xterm calls
4851 it). */
4852 if (NILP (Fassq (Qinternal_border_width, parms)))
4854 Lisp_Object value;
4856 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4857 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4858 if (! EQ (value, Qunbound))
4859 parms = Fcons (Fcons (Qinternal_border_width, value),
4860 parms);
4863 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4864 "internalBorderWidth", "internalBorderWidth",
4865 RES_TYPE_NUMBER);
4867 /* Also do the stuff which must be set before the window exists. */
4868 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4869 "foreground", "Foreground", RES_TYPE_STRING);
4870 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4871 "background", "Background", RES_TYPE_STRING);
4872 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4873 "pointerColor", "Foreground", RES_TYPE_STRING);
4874 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4875 "cursorColor", "Foreground", RES_TYPE_STRING);
4876 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4877 "borderColor", "BorderColor", RES_TYPE_STRING);
4879 /* Init faces before x_default_parameter is called for scroll-bar
4880 parameters because that function calls x_set_scroll_bar_width,
4881 which calls change_frame_size, which calls Fset_window_buffer,
4882 which runs hooks, which call Fvertical_motion. At the end, we
4883 end up in init_iterator with a null face cache, which should not
4884 happen. */
4885 init_frame_faces (f);
4887 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4889 window_prompting = x_figure_window_size (f, parms, 0);
4892 XSetWindowAttributes attrs;
4893 unsigned long mask;
4894 Atom type = FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
4896 BLOCK_INPUT;
4897 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
4898 if (DoesSaveUnders (dpyinfo->screen))
4899 mask |= CWSaveUnder;
4901 /* Window managers look at the override-redirect flag to determine
4902 whether or net to give windows a decoration (Xlib spec, chapter
4903 3.2.8). */
4904 attrs.override_redirect = True;
4905 attrs.save_under = True;
4906 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
4907 /* Arrange for getting MapNotify and UnmapNotify events. */
4908 attrs.event_mask = StructureNotifyMask;
4909 tip_window
4910 = FRAME_X_WINDOW (f)
4911 = XCreateWindow (FRAME_X_DISPLAY (f),
4912 FRAME_X_DISPLAY_INFO (f)->root_window,
4913 /* x, y, width, height */
4914 0, 0, 1, 1,
4915 /* Border. */
4916 f->border_width,
4917 CopyFromParent, InputOutput, CopyFromParent,
4918 mask, &attrs);
4919 XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
4920 FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type,
4921 XA_ATOM, 32, PropModeReplace,
4922 (unsigned char *)&type, 1);
4923 UNBLOCK_INPUT;
4926 x_make_gc (f);
4928 x_default_parameter (f, parms, Qauto_raise, Qnil,
4929 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4930 x_default_parameter (f, parms, Qauto_lower, Qnil,
4931 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4932 x_default_parameter (f, parms, Qcursor_type, Qbox,
4933 "cursorType", "CursorType", RES_TYPE_SYMBOL);
4935 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4936 Change will not be effected unless different from the current
4937 FRAME_LINES (f). */
4938 width = FRAME_COLS (f);
4939 height = FRAME_LINES (f);
4940 SET_FRAME_COLS (f, 0);
4941 FRAME_LINES (f) = 0;
4942 change_frame_size (f, height, width, 1, 0, 0);
4944 /* Add `tooltip' frame parameter's default value. */
4945 if (NILP (Fframe_parameter (frame, Qtooltip)))
4946 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
4948 /* FIXME - can this be done in a similar way to normal frames?
4949 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
4951 /* Set the `display-type' frame parameter before setting up faces. */
4953 Lisp_Object disptype;
4955 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
4956 disptype = intern ("mono");
4957 else if (FRAME_X_DISPLAY_INFO (f)->visual->class == GrayScale
4958 || FRAME_X_DISPLAY_INFO (f)->visual->class == StaticGray)
4959 disptype = intern ("grayscale");
4960 else
4961 disptype = intern ("color");
4963 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
4964 Fmodify_frame_parameters (frame, Fcons (Fcons (Qdisplay_type, disptype),
4965 Qnil));
4968 /* Set up faces after all frame parameters are known. This call
4969 also merges in face attributes specified for new frames.
4971 Frame parameters may be changed if .Xdefaults contains
4972 specifications for the default font. For example, if there is an
4973 `Emacs.default.attributeBackground: pink', the `background-color'
4974 attribute of the frame get's set, which let's the internal border
4975 of the tooltip frame appear in pink. Prevent this. */
4977 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
4979 /* Set tip_frame here, so that */
4980 tip_frame = frame;
4981 call2 (Qface_set_after_frame_default, frame, Qnil);
4983 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
4984 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
4985 Qnil));
4988 f->no_split = 1;
4990 UNGCPRO;
4992 /* It is now ok to make the frame official even if we get an error
4993 below. And the frame needs to be on Vframe_list or making it
4994 visible won't work. */
4995 Vframe_list = Fcons (frame, Vframe_list);
4997 /* Now that the frame is official, it counts as a reference to
4998 its display. */
4999 FRAME_X_DISPLAY_INFO (f)->reference_count++;
5001 /* Setting attributes of faces of the tooltip frame from resources
5002 and similar will increment face_change_count, which leads to the
5003 clearing of all current matrices. Since this isn't necessary
5004 here, avoid it by resetting face_change_count to the value it
5005 had before we created the tip frame. */
5006 face_change_count = face_change_count_before;
5008 /* Discard the unwind_protect. */
5009 return unbind_to (count, frame);
5013 /* Compute where to display tip frame F. PARMS is the list of frame
5014 parameters for F. DX and DY are specified offsets from the current
5015 location of the mouse. WIDTH and HEIGHT are the width and height
5016 of the tooltip. Return coordinates relative to the root window of
5017 the display in *ROOT_X, and *ROOT_Y. */
5019 static void
5020 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
5021 struct frame *f;
5022 Lisp_Object parms, dx, dy;
5023 int width, height;
5024 int *root_x, *root_y;
5026 Lisp_Object left, top;
5027 int win_x, win_y;
5028 Window root, child;
5029 unsigned pmask;
5031 /* User-specified position? */
5032 left = Fcdr (Fassq (Qleft, parms));
5033 top = Fcdr (Fassq (Qtop, parms));
5035 /* Move the tooltip window where the mouse pointer is. Resize and
5036 show it. */
5037 if (!INTEGERP (left) || !INTEGERP (top))
5039 BLOCK_INPUT;
5040 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
5041 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
5042 UNBLOCK_INPUT;
5045 if (INTEGERP (top))
5046 *root_y = XINT (top);
5047 else if (*root_y + XINT (dy) <= 0)
5048 *root_y = 0; /* Can happen for negative dy */
5049 else if (*root_y + XINT (dy) + height
5050 <= x_display_pixel_height (FRAME_X_DISPLAY_INFO (f)))
5051 /* It fits below the pointer */
5052 *root_y += XINT (dy);
5053 else if (height + XINT (dy) <= *root_y)
5054 /* It fits above the pointer. */
5055 *root_y -= height + XINT (dy);
5056 else
5057 /* Put it on the top. */
5058 *root_y = 0;
5060 if (INTEGERP (left))
5061 *root_x = XINT (left);
5062 else if (*root_x + XINT (dx) <= 0)
5063 *root_x = 0; /* Can happen for negative dx */
5064 else if (*root_x + XINT (dx) + width
5065 <= x_display_pixel_width (FRAME_X_DISPLAY_INFO (f)))
5066 /* It fits to the right of the pointer. */
5067 *root_x += XINT (dx);
5068 else if (width + XINT (dx) <= *root_x)
5069 /* It fits to the left of the pointer. */
5070 *root_x -= width + XINT (dx);
5071 else
5072 /* Put it left-justified on the screen--it ought to fit that way. */
5073 *root_x = 0;
5077 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5078 doc: /* Show STRING in a "tooltip" window on frame FRAME.
5079 A tooltip window is a small X window displaying a string.
5081 This is an internal function; Lisp code should call `tooltip-show'.
5083 FRAME nil or omitted means use the selected frame.
5085 PARMS is an optional list of frame parameters which can be used to
5086 change the tooltip's appearance.
5088 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5089 means use the default timeout of 5 seconds.
5091 If the list of frame parameters PARAMS contains a `left' parameters,
5092 the tooltip is displayed at that x-position. Otherwise it is
5093 displayed at the mouse position, with offset DX added (default is 5 if
5094 DX isn't specified). Likewise for the y-position; if a `top' frame
5095 parameter is specified, it determines the y-position of the tooltip
5096 window, otherwise it is displayed at the mouse position, with offset
5097 DY added (default is -10).
5099 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5100 Text larger than the specified size is clipped. */)
5101 (string, frame, parms, timeout, dx, dy)
5102 Lisp_Object string, frame, parms, timeout, dx, dy;
5104 struct frame *f;
5105 struct window *w;
5106 int root_x, root_y;
5107 struct buffer *old_buffer;
5108 struct text_pos pos;
5109 int i, width, height;
5110 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5111 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5112 int count = SPECPDL_INDEX ();
5114 specbind (Qinhibit_redisplay, Qt);
5116 GCPRO4 (string, parms, frame, timeout);
5118 CHECK_STRING (string);
5119 if (SCHARS (string) == 0)
5120 string = make_unibyte_string (" ", 1);
5122 f = check_x_frame (frame);
5123 if (NILP (timeout))
5124 timeout = make_number (5);
5125 else
5126 CHECK_NATNUM (timeout);
5128 if (NILP (dx))
5129 dx = make_number (5);
5130 else
5131 CHECK_NUMBER (dx);
5133 if (NILP (dy))
5134 dy = make_number (-10);
5135 else
5136 CHECK_NUMBER (dy);
5138 if (NILP (last_show_tip_args))
5139 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5141 if (!NILP (tip_frame))
5143 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5144 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5145 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5147 if (EQ (frame, last_frame)
5148 && !NILP (Fequal (last_string, string))
5149 && !NILP (Fequal (last_parms, parms)))
5151 struct frame *f = XFRAME (tip_frame);
5153 /* Only DX and DY have changed. */
5154 if (!NILP (tip_timer))
5156 Lisp_Object timer = tip_timer;
5157 tip_timer = Qnil;
5158 call1 (Qcancel_timer, timer);
5161 BLOCK_INPUT;
5162 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
5163 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
5164 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5165 root_x, root_y);
5166 UNBLOCK_INPUT;
5167 goto start_timer;
5171 /* Hide a previous tip, if any. */
5172 Fx_hide_tip ();
5174 ASET (last_show_tip_args, 0, string);
5175 ASET (last_show_tip_args, 1, frame);
5176 ASET (last_show_tip_args, 2, parms);
5178 /* Add default values to frame parameters. */
5179 if (NILP (Fassq (Qname, parms)))
5180 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5181 if (NILP (Fassq (Qinternal_border_width, parms)))
5182 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5183 if (NILP (Fassq (Qborder_width, parms)))
5184 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5185 if (NILP (Fassq (Qborder_color, parms)))
5186 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5187 if (NILP (Fassq (Qbackground_color, parms)))
5188 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5189 parms);
5191 /* Create a frame for the tooltip, and record it in the global
5192 variable tip_frame. */
5193 frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
5194 f = XFRAME (frame);
5196 /* Set up the frame's root window. */
5197 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5198 w->left_col = w->top_line = make_number (0);
5200 if (CONSP (Vx_max_tooltip_size)
5201 && INTEGERP (XCAR (Vx_max_tooltip_size))
5202 && XINT (XCAR (Vx_max_tooltip_size)) > 0
5203 && INTEGERP (XCDR (Vx_max_tooltip_size))
5204 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5206 w->total_cols = XCAR (Vx_max_tooltip_size);
5207 w->total_lines = XCDR (Vx_max_tooltip_size);
5209 else
5211 w->total_cols = make_number (80);
5212 w->total_lines = make_number (40);
5215 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5216 adjust_glyphs (f);
5217 w->pseudo_window_p = 1;
5219 /* Display the tooltip text in a temporary buffer. */
5220 old_buffer = current_buffer;
5221 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5222 current_buffer->truncate_lines = Qnil;
5223 clear_glyph_matrix (w->desired_matrix);
5224 clear_glyph_matrix (w->current_matrix);
5225 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5226 try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
5228 /* Compute width and height of the tooltip. */
5229 width = height = 0;
5230 for (i = 0; i < w->desired_matrix->nrows; ++i)
5232 struct glyph_row *row = &w->desired_matrix->rows[i];
5233 struct glyph *last;
5234 int row_width;
5236 /* Stop at the first empty row at the end. */
5237 if (!row->enabled_p || !row->displays_text_p)
5238 break;
5240 /* Let the row go over the full width of the frame. */
5241 row->full_width_p = 1;
5243 /* There's a glyph at the end of rows that is used to place
5244 the cursor there. Don't include the width of this glyph. */
5245 if (row->used[TEXT_AREA])
5247 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5248 row_width = row->pixel_width - last->pixel_width;
5250 else
5251 row_width = row->pixel_width;
5253 height += row->height;
5254 width = max (width, row_width);
5257 /* Add the frame's internal border to the width and height the X
5258 window should have. */
5259 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5260 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5262 /* Move the tooltip window where the mouse pointer is. Resize and
5263 show it. */
5264 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5266 BLOCK_INPUT;
5267 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5268 root_x, root_y, width, height);
5269 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5270 UNBLOCK_INPUT;
5272 /* Draw into the window. */
5273 w->must_be_updated_p = 1;
5274 update_single_window (w, 1);
5276 /* Restore original current buffer. */
5277 set_buffer_internal_1 (old_buffer);
5278 windows_or_buffers_changed = old_windows_or_buffers_changed;
5280 start_timer:
5281 /* Let the tip disappear after timeout seconds. */
5282 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5283 intern ("x-hide-tip"));
5285 UNGCPRO;
5286 return unbind_to (count, Qnil);
5290 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5291 doc: /* Hide the current tooltip window, if there is any.
5292 Value is t if tooltip was open, nil otherwise. */)
5295 int count;
5296 Lisp_Object deleted, frame, timer;
5297 struct gcpro gcpro1, gcpro2;
5299 /* Return quickly if nothing to do. */
5300 if (NILP (tip_timer) && NILP (tip_frame))
5301 return Qnil;
5303 frame = tip_frame;
5304 timer = tip_timer;
5305 GCPRO2 (frame, timer);
5306 tip_frame = tip_timer = deleted = Qnil;
5308 count = SPECPDL_INDEX ();
5309 specbind (Qinhibit_redisplay, Qt);
5310 specbind (Qinhibit_quit, Qt);
5312 if (!NILP (timer))
5313 call1 (Qcancel_timer, timer);
5315 if (FRAMEP (frame))
5317 delete_frame (frame, Qnil);
5318 deleted = Qt;
5320 #ifdef USE_LUCID
5321 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5322 redisplay procedure is not called when a tip frame over menu
5323 items is unmapped. Redisplay the menu manually... */
5325 struct frame *f = SELECTED_FRAME ();
5326 Widget w = f->output_data.x->menubar_widget;
5327 extern void xlwmenu_redisplay P_ ((Widget));
5329 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5330 && w != NULL)
5332 BLOCK_INPUT;
5333 xlwmenu_redisplay (w);
5334 UNBLOCK_INPUT;
5337 #endif /* USE_LUCID */
5340 UNGCPRO;
5341 return unbind_to (count, deleted);
5346 /***********************************************************************
5347 File selection dialog
5348 ***********************************************************************/
5350 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5351 Sx_uses_old_gtk_dialog,
5352 0, 0, 0,
5353 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5356 #ifdef USE_GTK
5357 extern int use_dialog_box;
5358 extern int use_file_dialog;
5360 if (use_dialog_box
5361 && use_file_dialog
5362 && have_menus_p ()
5363 && xg_uses_old_file_dialog ())
5364 return Qt;
5365 #endif
5366 return Qnil;
5370 #ifdef USE_MOTIF
5371 /* Callback for "OK" and "Cancel" on file selection dialog. */
5373 static void
5374 file_dialog_cb (widget, client_data, call_data)
5375 Widget widget;
5376 XtPointer call_data, client_data;
5378 int *result = (int *) client_data;
5379 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5380 *result = cb->reason;
5384 /* Callback for unmapping a file selection dialog. This is used to
5385 capture the case where a dialog is closed via a window manager's
5386 closer button, for example. Using a XmNdestroyCallback didn't work
5387 in this case. */
5389 static void
5390 file_dialog_unmap_cb (widget, client_data, call_data)
5391 Widget widget;
5392 XtPointer call_data, client_data;
5394 int *result = (int *) client_data;
5395 *result = XmCR_CANCEL;
5398 static Lisp_Object
5399 clean_up_file_dialog (arg)
5400 Lisp_Object arg;
5402 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5403 Widget dialog = (Widget) p->pointer;
5405 /* Clean up. */
5406 BLOCK_INPUT;
5407 XtUnmanageChild (dialog);
5408 XtDestroyWidget (dialog);
5409 x_menu_set_in_use (0);
5410 UNBLOCK_INPUT;
5412 return Qnil;
5416 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5417 doc: /* Read file name, prompting with PROMPT in directory DIR.
5418 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5419 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5420 or directory must exist. ONLY-DIR-P is ignored." */)
5421 (prompt, dir, default_filename, mustmatch, only_dir_p)
5422 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5424 int result;
5425 struct frame *f = SELECTED_FRAME ();
5426 Lisp_Object file = Qnil;
5427 Lisp_Object decoded_file;
5428 Widget dialog, text, help;
5429 Arg al[10];
5430 int ac = 0;
5431 extern XtAppContext Xt_app_con;
5432 XmString dir_xmstring, pattern_xmstring;
5433 int count = SPECPDL_INDEX ();
5434 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5436 check_x ();
5438 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5440 if (popup_activated ())
5441 error ("Trying to use a menu from within a menu-entry");
5443 CHECK_STRING (prompt);
5444 CHECK_STRING (dir);
5446 /* Prevent redisplay. */
5447 specbind (Qinhibit_redisplay, Qt);
5449 BLOCK_INPUT;
5451 /* Create the dialog with PROMPT as title, using DIR as initial
5452 directory and using "*" as pattern. */
5453 dir = Fexpand_file_name (dir, Qnil);
5454 dir_xmstring = XmStringCreateLocalized (SDATA (dir));
5455 pattern_xmstring = XmStringCreateLocalized ("*");
5457 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5458 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5459 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5460 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5461 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5462 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5463 "fsb", al, ac);
5464 XmStringFree (dir_xmstring);
5465 XmStringFree (pattern_xmstring);
5467 /* Add callbacks for OK and Cancel. */
5468 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5469 (XtPointer) &result);
5470 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5471 (XtPointer) &result);
5472 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5473 (XtPointer) &result);
5475 /* Remove the help button since we can't display help. */
5476 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5477 XtUnmanageChild (help);
5479 /* Mark OK button as default. */
5480 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5481 XmNshowAsDefault, True, NULL);
5483 /* If MUSTMATCH is non-nil, disable the file entry field of the
5484 dialog, so that the user must select a file from the files list
5485 box. We can't remove it because we wouldn't have a way to get at
5486 the result file name, then. */
5487 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5488 if (!NILP (mustmatch))
5490 Widget label;
5491 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5492 XtSetSensitive (text, False);
5493 XtSetSensitive (label, False);
5496 /* Manage the dialog, so that list boxes get filled. */
5497 XtManageChild (dialog);
5499 if (STRINGP (default_filename))
5501 XmString default_xmstring;
5502 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5503 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5505 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5506 XmTextFieldReplace (wtext, 0, last_pos,
5507 (SDATA (Ffile_name_nondirectory (default_filename))));
5509 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5510 must include the path for this to work. */
5512 default_xmstring = XmStringCreateLocalized (SDATA (default_filename));
5514 if (XmListItemExists (list, default_xmstring))
5516 int item_pos = XmListItemPos (list, default_xmstring);
5517 /* Select the item and scroll it into view. */
5518 XmListSelectPos (list, item_pos, True);
5519 XmListSetPos (list, item_pos);
5522 XmStringFree (default_xmstring);
5525 record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5527 /* Process events until the user presses Cancel or OK. */
5528 x_menu_set_in_use (1);
5529 result = 0;
5530 while (result == 0)
5532 XEvent event;
5533 x_menu_wait_for_event (0);
5534 XtAppNextEvent (Xt_app_con, &event);
5535 if (event.type == KeyPress
5536 && FRAME_X_DISPLAY (f) == event.xkey.display)
5538 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5540 /* Pop down on C-g. */
5541 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5542 XtUnmanageChild (dialog);
5545 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5548 /* Get the result. */
5549 if (result == XmCR_OK)
5551 XmString text;
5552 String data;
5554 XtVaGetValues (dialog, XmNtextString, &text, NULL);
5555 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
5556 XmStringFree (text);
5557 file = build_string (data);
5558 XtFree (data);
5560 else
5561 file = Qnil;
5563 UNBLOCK_INPUT;
5564 UNGCPRO;
5566 /* Make "Cancel" equivalent to C-g. */
5567 if (NILP (file))
5568 Fsignal (Qquit, Qnil);
5570 decoded_file = DECODE_FILE (file);
5572 return unbind_to (count, decoded_file);
5575 #endif /* USE_MOTIF */
5577 #ifdef USE_GTK
5579 static Lisp_Object
5580 clean_up_dialog (arg)
5581 Lisp_Object arg;
5583 x_menu_set_in_use (0);
5585 return Qnil;
5588 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5589 doc: /* Read file name, prompting with PROMPT in directory DIR.
5590 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5591 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5592 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5593 directories. */)
5594 (prompt, dir, default_filename, mustmatch, only_dir_p)
5595 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5597 FRAME_PTR f = SELECTED_FRAME ();
5598 char *fn;
5599 Lisp_Object file = Qnil;
5600 Lisp_Object decoded_file;
5601 int count = SPECPDL_INDEX ();
5602 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5603 char *cdef_file;
5605 check_x ();
5607 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5609 if (popup_activated ())
5610 error ("Trying to use a menu from within a menu-entry");
5612 CHECK_STRING (prompt);
5613 CHECK_STRING (dir);
5615 /* Prevent redisplay. */
5616 specbind (Qinhibit_redisplay, Qt);
5617 record_unwind_protect (clean_up_dialog, Qnil);
5619 BLOCK_INPUT;
5621 if (STRINGP (default_filename))
5622 cdef_file = SDATA (default_filename);
5623 else
5624 cdef_file = SDATA (dir);
5626 fn = xg_get_file_name (f, SDATA (prompt), cdef_file,
5627 ! NILP (mustmatch),
5628 ! NILP (only_dir_p));
5630 if (fn)
5632 file = build_string (fn);
5633 xfree (fn);
5636 UNBLOCK_INPUT;
5637 UNGCPRO;
5639 /* Make "Cancel" equivalent to C-g. */
5640 if (NILP (file))
5641 Fsignal (Qquit, Qnil);
5643 decoded_file = DECODE_FILE (file);
5645 return unbind_to (count, decoded_file);
5649 #ifdef HAVE_FREETYPE
5651 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5652 doc: /* Read a font name using a GTK font selection dialog.
5653 Return a GTK-style font string corresponding to the selection.
5655 If FRAME is omitted or nil, it defaults to the selected frame. */)
5656 (frame, ignored)
5657 Lisp_Object frame, ignored;
5659 FRAME_PTR f = check_x_frame (frame);
5660 char *name;
5661 Lisp_Object font;
5662 Lisp_Object font_param;
5663 char *default_name = NULL;
5664 struct gcpro gcpro1, gcpro2;
5665 int count = SPECPDL_INDEX ();
5667 check_x ();
5669 if (popup_activated ())
5670 error ("Trying to use a menu from within a menu-entry");
5672 /* Prevent redisplay. */
5673 specbind (Qinhibit_redisplay, Qt);
5674 record_unwind_protect (clean_up_dialog, Qnil);
5676 BLOCK_INPUT;
5678 GCPRO2(font_param, font);
5680 XSETFONT (font, FRAME_FONT (f));
5681 font_param = Ffont_get (font, intern (":name"));
5682 if (STRINGP (font_param))
5683 default_name = xstrdup (SDATA (font_param));
5684 else
5686 font_param = Fframe_parameter (frame, Qfont_param);
5687 if (STRINGP (font_param))
5688 default_name = xstrdup (SDATA (font_param));
5691 if (default_name == NULL && x_last_font_name != NULL)
5692 default_name = xstrdup (x_last_font_name);
5694 /* Convert fontconfig names to Gtk names, i.e. remove - before number */
5695 if (default_name)
5697 char *p = strrchr (default_name, '-');
5698 if (p)
5700 char *ep = p+1;
5701 while (isdigit (*ep))
5702 ++ep;
5703 if (*ep == '\0') *p = ' ';
5707 name = xg_get_font_name (f, default_name);
5708 xfree (default_name);
5710 if (name)
5712 font = build_string (name);
5713 g_free (x_last_font_name);
5714 x_last_font_name = name;
5717 UNBLOCK_INPUT;
5719 if (NILP (font))
5720 Fsignal (Qquit, Qnil);
5722 return unbind_to (count, font);
5724 #endif /* HAVE_FREETYPE */
5726 #endif /* USE_GTK */
5729 /***********************************************************************
5730 Keyboard
5731 ***********************************************************************/
5733 #ifdef HAVE_XKBGETKEYBOARD
5734 #include <X11/XKBlib.h>
5735 #include <X11/keysym.h>
5736 #endif
5738 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5739 Sx_backspace_delete_keys_p, 0, 1, 0,
5740 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5741 FRAME nil means use the selected frame.
5742 Value is t if we know that both keys are present, and are mapped to the
5743 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5744 present and mapped to the usual X keysyms. */)
5745 (frame)
5746 Lisp_Object frame;
5748 #ifdef HAVE_XKBGETKEYBOARD
5749 XkbDescPtr kb;
5750 struct frame *f = check_x_frame (frame);
5751 Display *dpy = FRAME_X_DISPLAY (f);
5752 Lisp_Object have_keys;
5753 int major, minor, op, event, error;
5755 BLOCK_INPUT;
5757 /* Check library version in case we're dynamically linked. */
5758 major = XkbMajorVersion;
5759 minor = XkbMinorVersion;
5760 if (!XkbLibraryVersion (&major, &minor))
5762 UNBLOCK_INPUT;
5763 return Qlambda;
5766 /* Check that the server supports XKB. */
5767 major = XkbMajorVersion;
5768 minor = XkbMinorVersion;
5769 if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
5771 UNBLOCK_INPUT;
5772 return Qlambda;
5775 /* In this code we check that the keyboard has physical keys with names
5776 that start with BKSP (Backspace) and DELE (Delete), and that they
5777 generate keysym XK_BackSpace and XK_Delete respectively.
5778 This function is used to test if normal-erase-is-backspace should be
5779 turned on.
5780 An alternative approach would be to just check if XK_BackSpace and
5781 XK_Delete are mapped to any key. But if any of those are mapped to
5782 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5783 user doesn't know about it, it is better to return false here.
5784 It is more obvious to the user what to do if she/he has two keys
5785 clearly marked with names/symbols and one key does something not
5786 expected (i.e. she/he then tries the other).
5787 The cases where Backspace/Delete is mapped to some other key combination
5788 are rare, and in those cases, normal-erase-is-backspace can be turned on
5789 manually. */
5791 have_keys = Qnil;
5792 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5793 if (kb)
5795 int delete_keycode = 0, backspace_keycode = 0, i;
5797 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5799 for (i = kb->min_key_code;
5800 (i < kb->max_key_code
5801 && (delete_keycode == 0 || backspace_keycode == 0));
5802 ++i)
5804 /* The XKB symbolic key names can be seen most easily in
5805 the PS file generated by `xkbprint -label name
5806 $DISPLAY'. */
5807 if (bcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5808 delete_keycode = i;
5809 else if (bcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5810 backspace_keycode = i;
5813 XkbFreeNames (kb, 0, True);
5816 XkbFreeClientMap (kb, 0, True);
5818 if (delete_keycode
5819 && backspace_keycode
5820 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5821 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5822 have_keys = Qt;
5824 UNBLOCK_INPUT;
5825 return have_keys;
5826 #else /* not HAVE_XKBGETKEYBOARD */
5827 return Qlambda;
5828 #endif /* not HAVE_XKBGETKEYBOARD */
5833 /***********************************************************************
5834 Initialization
5835 ***********************************************************************/
5837 /* Keep this list in the same order as frame_parms in frame.c.
5838 Use 0 for unsupported frame parameters. */
5840 frame_parm_handler x_frame_parm_handlers[] =
5842 x_set_autoraise,
5843 x_set_autolower,
5844 x_set_background_color,
5845 x_set_border_color,
5846 x_set_border_width,
5847 x_set_cursor_color,
5848 x_set_cursor_type,
5849 x_set_font,
5850 x_set_foreground_color,
5851 x_set_icon_name,
5852 x_set_icon_type,
5853 x_set_internal_border_width,
5854 x_set_menu_bar_lines,
5855 x_set_mouse_color,
5856 x_explicitly_set_name,
5857 x_set_scroll_bar_width,
5858 x_set_title,
5859 x_set_unsplittable,
5860 x_set_vertical_scroll_bars,
5861 x_set_visibility,
5862 x_set_tool_bar_lines,
5863 x_set_scroll_bar_foreground,
5864 x_set_scroll_bar_background,
5865 x_set_screen_gamma,
5866 x_set_line_spacing,
5867 x_set_fringe_width,
5868 x_set_fringe_width,
5869 x_set_wait_for_wm,
5870 x_set_fullscreen,
5871 x_set_font_backend,
5872 x_set_alpha,
5873 x_set_sticky,
5876 void
5877 syms_of_xfns ()
5879 /* This is zero if not using X windows. */
5880 x_in_use = 0;
5882 /* The section below is built by the lisp expression at the top of the file,
5883 just above where these variables are declared. */
5884 /*&&& init symbols here &&&*/
5885 Qnone = intern_c_string ("none");
5886 staticpro (&Qnone);
5887 Qsuppress_icon = intern_c_string ("suppress-icon");
5888 staticpro (&Qsuppress_icon);
5889 Qundefined_color = intern_c_string ("undefined-color");
5890 staticpro (&Qundefined_color);
5891 Qcompound_text = intern_c_string ("compound-text");
5892 staticpro (&Qcompound_text);
5893 Qcancel_timer = intern_c_string ("cancel-timer");
5894 staticpro (&Qcancel_timer);
5895 Qfont_param = intern_c_string ("font-parameter");
5896 staticpro (&Qfont_param);
5897 /* This is the end of symbol initialization. */
5899 /* Text property `display' should be nonsticky by default. */
5900 Vtext_property_default_nonsticky
5901 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
5904 Fput (Qundefined_color, Qerror_conditions,
5905 pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
5906 Fput (Qundefined_color, Qerror_message,
5907 make_pure_c_string ("Undefined color"));
5909 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
5910 doc: /* The shape of the pointer when over text.
5911 Changing the value does not affect existing frames
5912 unless you set the mouse color. */);
5913 Vx_pointer_shape = Qnil;
5915 #if 0 /* This doesn't really do anything. */
5916 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
5917 doc: /* The shape of the pointer when not over text.
5918 This variable takes effect when you create a new frame
5919 or when you set the mouse color. */);
5920 #endif
5921 Vx_nontext_pointer_shape = Qnil;
5923 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
5924 doc: /* The shape of the pointer when Emacs is busy.
5925 This variable takes effect when you create a new frame
5926 or when you set the mouse color. */);
5927 Vx_hourglass_pointer_shape = Qnil;
5929 #if 0 /* This doesn't really do anything. */
5930 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
5931 doc: /* The shape of the pointer when over the mode line.
5932 This variable takes effect when you create a new frame
5933 or when you set the mouse color. */);
5934 #endif
5935 Vx_mode_pointer_shape = Qnil;
5937 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5938 &Vx_sensitive_text_pointer_shape,
5939 doc: /* The shape of the pointer when over mouse-sensitive text.
5940 This variable takes effect when you create a new frame
5941 or when you set the mouse color. */);
5942 Vx_sensitive_text_pointer_shape = Qnil;
5944 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5945 &Vx_window_horizontal_drag_shape,
5946 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
5947 This variable takes effect when you create a new frame
5948 or when you set the mouse color. */);
5949 Vx_window_horizontal_drag_shape = Qnil;
5951 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
5952 doc: /* A string indicating the foreground color of the cursor box. */);
5953 Vx_cursor_fore_pixel = Qnil;
5955 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
5956 doc: /* Maximum size for tooltips.
5957 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
5958 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
5960 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
5961 doc: /* Non-nil if no X window manager is in use.
5962 Emacs doesn't try to figure this out; this is always nil
5963 unless you set it to something else. */);
5964 /* We don't have any way to find this out, so set it to nil
5965 and maybe the user would like to set it to t. */
5966 Vx_no_window_manager = Qnil;
5968 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5969 &Vx_pixel_size_width_font_regexp,
5970 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5972 Since Emacs gets width of a font matching with this regexp from
5973 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5974 such a font. This is especially effective for such large fonts as
5975 Chinese, Japanese, and Korean. */);
5976 Vx_pixel_size_width_font_regexp = Qnil;
5978 /* This is not ifdef:ed, so other builds than GTK can customize it. */
5979 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog,
5980 doc: /* *Non-nil means prompt with the old GTK file selection dialog.
5981 If nil or if the file selection dialog is not available, the new GTK file
5982 chooser is used instead. To turn off all file dialogs set the
5983 variable `use-file-dialog'. */);
5984 x_gtk_use_old_file_dialog = 0;
5986 DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files,
5987 doc: /* *If non-nil, the GTK file chooser will by default show hidden files.
5988 Note that this is just the default, there is a toggle button on the file
5989 chooser to show or not show hidden files on a case by case basis. */);
5990 x_gtk_show_hidden_files = 0;
5992 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text,
5993 doc: /* *If non-nil, the GTK file chooser will show additional help text.
5994 If more space for files in the file chooser dialog is wanted, set this to nil
5995 to turn the additional text off. */);
5996 x_gtk_file_dialog_help_text = 1;
5998 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar,
5999 doc: /* *If non-nil, a detached tool bar is shown in full.
6000 The default is to just show an arrow and pressing on that arrow shows
6001 the tool bar buttons. */);
6002 x_gtk_whole_detached_tool_bar = 0;
6004 Fprovide (intern_c_string ("x"), Qnil);
6006 #ifdef USE_X_TOOLKIT
6007 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6008 #ifdef USE_MOTIF
6009 Fprovide (intern_c_string ("motif"), Qnil);
6011 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
6012 doc: /* Version info for LessTif/Motif. */);
6013 Vmotif_version_string = build_string (XmVERSION_STRING);
6014 #endif /* USE_MOTIF */
6015 #endif /* USE_X_TOOLKIT */
6017 #ifdef USE_GTK
6018 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6019 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6020 But for a user it is a toolkit for X, and indeed, configure
6021 accepts --with-x-toolkit=gtk. */
6022 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6023 Fprovide (intern_c_string ("gtk"), Qnil);
6025 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
6026 doc: /* Version info for GTK+. */);
6028 char gtk_version[40];
6029 g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
6030 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
6031 Vgtk_version_string = make_pure_string (gtk_version, strlen (gtk_version), strlen (gtk_version), 0);
6033 #endif /* USE_GTK */
6035 /* X window properties. */
6036 defsubr (&Sx_change_window_property);
6037 defsubr (&Sx_delete_window_property);
6038 defsubr (&Sx_window_property);
6040 defsubr (&Sxw_display_color_p);
6041 defsubr (&Sx_display_grayscale_p);
6042 defsubr (&Sxw_color_defined_p);
6043 defsubr (&Sxw_color_values);
6044 defsubr (&Sx_server_max_request_size);
6045 defsubr (&Sx_server_vendor);
6046 defsubr (&Sx_server_version);
6047 defsubr (&Sx_display_pixel_width);
6048 defsubr (&Sx_display_pixel_height);
6049 defsubr (&Sx_display_mm_width);
6050 defsubr (&Sx_display_mm_height);
6051 defsubr (&Sx_display_screens);
6052 defsubr (&Sx_display_planes);
6053 defsubr (&Sx_display_color_cells);
6054 defsubr (&Sx_display_visual_class);
6055 defsubr (&Sx_display_backing_store);
6056 defsubr (&Sx_display_save_under);
6057 defsubr (&Sx_wm_set_size_hint);
6058 defsubr (&Sx_create_frame);
6059 defsubr (&Sx_open_connection);
6060 defsubr (&Sx_close_connection);
6061 defsubr (&Sx_display_list);
6062 defsubr (&Sx_synchronize);
6063 defsubr (&Sx_focus_frame);
6064 defsubr (&Sx_backspace_delete_keys_p);
6066 /* Setting callback functions for fontset handler. */
6067 check_window_system_func = check_x;
6069 defsubr (&Sx_show_tip);
6070 defsubr (&Sx_hide_tip);
6071 tip_timer = Qnil;
6072 staticpro (&tip_timer);
6073 tip_frame = Qnil;
6074 staticpro (&tip_frame);
6076 last_show_tip_args = Qnil;
6077 staticpro (&last_show_tip_args);
6079 defsubr (&Sx_uses_old_gtk_dialog);
6080 #if defined (USE_MOTIF) || defined (USE_GTK)
6081 defsubr (&Sx_file_dialog);
6082 #endif
6084 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6085 defsubr (&Sx_select_font);
6086 x_last_font_name = NULL;
6087 #endif
6090 #endif /* HAVE_X_WINDOWS */
6092 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
6093 (do not change this comment) */