]> code.delx.au - gnu-emacs/blob - src/xfns.c
Merge changes from emacs-23 branch.
[gnu-emacs] / src / xfns.c
1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5
6 This file is part of GNU Emacs.
7
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.
12
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.
17
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/>. */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <math.h>
24 #include <setjmp.h>
25 #include <ctype.h>
26
27 #ifdef HAVE_UNISTD_H
28 #include <unistd.h>
29 #endif
30
31 /* This makes the fields of a Display accessible, in Xlib header files. */
32
33 #define XLIB_ILLEGAL_ACCESS
34
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"
54
55 #ifdef HAVE_X_WINDOWS
56
57 #include <ctype.h>
58 #include <sys/types.h>
59 #include <sys/stat.h>
60
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
66
67 #include "xsettings.h"
68
69 #ifdef USE_GTK
70 #include "gtkutil.h"
71 #endif
72
73 #ifdef USE_X_TOOLKIT
74 #include <X11/Shell.h>
75
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 */
85
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
93
94 #include "widget.h"
95
96 #include "../lwlib/lwlib.h"
97
98 #ifdef USE_MOTIF
99 #include <Xm/Xm.h>
100 #include <Xm/DialogS.h>
101 #include <Xm/FileSB.h>
102 #endif
103
104 #if !defined(NO_EDITRES)
105 #define HACK_EDITRES
106 extern void _XEditResCheckMessages ();
107 #endif /* not defined NO_EDITRES */
108
109 /* Unique id counter for widgets created by the Lucid Widget Library. */
110
111 extern LWLIB_ID widget_id_tick;
112
113 extern void free_frame_menubar ();
114 extern double atof ();
115
116 #ifdef USE_MOTIF
117
118 /* LessTif/Motif version info. */
119
120 static Lisp_Object Vmotif_version_string;
121
122 #endif /* USE_MOTIF */
123
124 #endif /* USE_X_TOOLKIT */
125
126 #ifdef USE_GTK
127
128 /* GTK+ version info */
129
130 static Lisp_Object Vgtk_version_string;
131
132 #endif /* USE_GTK */
133
134 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
135
136 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
137 it, and including `bitmaps/gray' more than once is a problem when
138 config.h defines `static' as an empty replacement string. */
139
140 int gray_bitmap_width = gray_width;
141 int gray_bitmap_height = gray_height;
142 char *gray_bitmap_bits = gray_bits;
143
144 /* Non-zero means prompt with the old GTK file selection dialog. */
145
146 int x_gtk_use_old_file_dialog;
147
148 /* If non-zero, by default show hidden files in the GTK file chooser. */
149
150 int x_gtk_show_hidden_files;
151
152 /* If non-zero, don't show additional help text in the GTK file chooser. */
153
154 int x_gtk_file_dialog_help_text;
155
156 /* If non-zero, don't collapse to tool bar when it is detached. */
157
158 int x_gtk_whole_detached_tool_bar;
159
160 /* The background and shape of the mouse pointer, and shape when not
161 over text or in the modeline. */
162
163 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
164 Lisp_Object Vx_hourglass_pointer_shape;
165
166 /* The shape when over mouse-sensitive text. */
167
168 Lisp_Object Vx_sensitive_text_pointer_shape;
169
170 /* If non-nil, the pointer shape to indicate that windows can be
171 dragged horizontally. */
172
173 Lisp_Object Vx_window_horizontal_drag_shape;
174
175 /* Color of chars displayed in cursor box. */
176
177 Lisp_Object Vx_cursor_fore_pixel;
178
179 /* Nonzero if using X. */
180
181 static int x_in_use;
182
183 /* Non nil if no window manager is in use. */
184
185 Lisp_Object Vx_no_window_manager;
186
187 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
188
189 Lisp_Object Vx_pixel_size_width_font_regexp;
190
191 Lisp_Object Qnone;
192 Lisp_Object Qsuppress_icon;
193 Lisp_Object Qundefined_color;
194 Lisp_Object Qcompound_text, Qcancel_timer;
195 Lisp_Object Qfont_param;
196
197 /* In dispnew.c */
198
199 extern Lisp_Object Vwindow_system_version;
200
201 /* In editfns.c */
202
203 extern Lisp_Object Vsystem_name;
204
205 /* The below are defined in frame.c. */
206
207 extern Lisp_Object Vmenu_bar_mode, Vtool_bar_mode;
208 extern Lisp_Object Qtooltip;
209
210 #if GLYPH_DEBUG
211 int image_cache_refcount, dpyinfo_refcount;
212 #endif
213
214 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
215 char *x_last_font_name;
216 #endif
217
218 \f
219 /* Error if we are not connected to X. */
220
221 void
222 check_x (void)
223 {
224 if (! x_in_use)
225 error ("X windows are not in use or not initialized");
226 }
227
228 /* Nonzero if we can use mouse menus.
229 You should not call this unless HAVE_MENUS is defined. */
230
231 int
232 have_menus_p (void)
233 {
234 return x_in_use;
235 }
236
237 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
238 and checking validity for X. */
239
240 FRAME_PTR
241 check_x_frame (Lisp_Object frame)
242 {
243 FRAME_PTR f;
244
245 if (NILP (frame))
246 frame = selected_frame;
247 CHECK_LIVE_FRAME (frame);
248 f = XFRAME (frame);
249 if (! FRAME_X_P (f))
250 error ("Non-X frame used");
251 return f;
252 }
253
254 /* Let the user specify an X display with a Lisp object.
255 OBJECT may be nil, a frame or a terminal object.
256 nil stands for the selected frame--or, if that is not an X frame,
257 the first X display on the list. */
258
259 struct x_display_info *
260 check_x_display_info (Lisp_Object object)
261 {
262 struct x_display_info *dpyinfo = NULL;
263
264 if (NILP (object))
265 {
266 struct frame *sf = XFRAME (selected_frame);
267
268 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
269 dpyinfo = FRAME_X_DISPLAY_INFO (sf);
270 else if (x_display_list != 0)
271 dpyinfo = x_display_list;
272 else
273 error ("X windows are not in use or not initialized");
274 }
275 else if (TERMINALP (object))
276 {
277 struct terminal *t = get_terminal (object, 1);
278
279 if (t->type != output_x_window)
280 error ("Terminal %d is not an X display", XINT (object));
281
282 dpyinfo = t->display_info.x;
283 }
284 else if (STRINGP (object))
285 dpyinfo = x_display_info_for_name (object);
286 else
287 {
288 FRAME_PTR f = check_x_frame (object);
289 dpyinfo = FRAME_X_DISPLAY_INFO (f);
290 }
291
292 return dpyinfo;
293 }
294
295 \f
296 /* Return the Emacs frame-object corresponding to an X window.
297 It could be the frame's main window or an icon window. */
298
299 /* This function can be called during GC, so use GC_xxx type test macros. */
300
301 struct frame *
302 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
303 {
304 Lisp_Object tail, frame;
305 struct frame *f;
306
307 if (wdesc == None) return 0;
308
309 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
310 {
311 frame = XCAR (tail);
312 if (!FRAMEP (frame))
313 continue;
314 f = XFRAME (frame);
315 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
316 continue;
317 if (f->output_data.x->hourglass_window == wdesc)
318 return f;
319 #ifdef USE_X_TOOLKIT
320 if ((f->output_data.x->edit_widget
321 && XtWindow (f->output_data.x->edit_widget) == wdesc)
322 /* A tooltip frame? */
323 || (!f->output_data.x->edit_widget
324 && FRAME_X_WINDOW (f) == wdesc)
325 || f->output_data.x->icon_desc == wdesc)
326 return f;
327 #else /* not USE_X_TOOLKIT */
328 #ifdef USE_GTK
329 if (f->output_data.x->edit_widget)
330 {
331 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
332 struct x_output *x = f->output_data.x;
333 if (gwdesc != 0 && gwdesc == x->edit_widget)
334 return f;
335 }
336 #endif /* USE_GTK */
337 if (FRAME_X_WINDOW (f) == wdesc
338 || f->output_data.x->icon_desc == wdesc)
339 return f;
340 #endif /* not USE_X_TOOLKIT */
341 }
342 return 0;
343 }
344
345 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
346 /* Like x_window_to_frame but also compares the window with the widget's
347 windows. */
348
349 struct frame *
350 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
351 {
352 Lisp_Object tail, frame;
353 struct frame *f, *found;
354 struct x_output *x;
355
356 if (wdesc == None) return NULL;
357
358 found = NULL;
359 for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail))
360 {
361 frame = XCAR (tail);
362 if (!FRAMEP (frame))
363 continue;
364
365 f = XFRAME (frame);
366 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
367 {
368 /* This frame matches if the window is any of its widgets. */
369 x = f->output_data.x;
370 if (x->hourglass_window == wdesc)
371 found = f;
372 else if (x->widget)
373 {
374 #ifdef USE_GTK
375 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
376 if (gwdesc != 0
377 && gtk_widget_get_toplevel (gwdesc) == x->widget)
378 found = f;
379 #else
380 if (wdesc == XtWindow (x->widget)
381 || wdesc == XtWindow (x->column_widget)
382 || wdesc == XtWindow (x->edit_widget))
383 found = f;
384 /* Match if the window is this frame's menubar. */
385 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
386 found = f;
387 #endif
388 }
389 else if (FRAME_X_WINDOW (f) == wdesc)
390 /* A tooltip frame. */
391 found = f;
392 }
393 }
394
395 return found;
396 }
397
398 /* Likewise, but consider only the menu bar widget. */
399
400 struct frame *
401 x_menubar_window_to_frame (struct x_display_info *dpyinfo, XEvent *event)
402 {
403 Window wdesc = event->xany.window;
404 Lisp_Object tail, frame;
405 struct frame *f;
406 struct x_output *x;
407
408 if (wdesc == None) return 0;
409
410 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
411 {
412 frame = XCAR (tail);
413 if (!FRAMEP (frame))
414 continue;
415 f = XFRAME (frame);
416 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
417 continue;
418 x = f->output_data.x;
419 #ifdef USE_GTK
420 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
421 return f;
422 #else
423 /* Match if the window is this frame's menubar. */
424 if (x->menubar_widget
425 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
426 return f;
427 #endif
428 }
429 return 0;
430 }
431
432 /* Return the frame whose principal (outermost) window is WDESC.
433 If WDESC is some other (smaller) window, we return 0. */
434
435 struct frame *
436 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
437 {
438 Lisp_Object tail, frame;
439 struct frame *f;
440 struct x_output *x;
441
442 if (wdesc == None) return 0;
443
444 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
445 {
446 frame = XCAR (tail);
447 if (!FRAMEP (frame))
448 continue;
449 f = XFRAME (frame);
450 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
451 continue;
452 x = f->output_data.x;
453
454 if (x->widget)
455 {
456 /* This frame matches if the window is its topmost widget. */
457 #ifdef USE_GTK
458 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
459 if (gwdesc == x->widget)
460 return f;
461 #else
462 if (wdesc == XtWindow (x->widget))
463 return f;
464 #if 0 /* I don't know why it did this,
465 but it seems logically wrong,
466 and it causes trouble for MapNotify events. */
467 /* Match if the window is this frame's menubar. */
468 if (x->menubar_widget
469 && wdesc == XtWindow (x->menubar_widget))
470 return f;
471 #endif
472 #endif
473 }
474 else if (FRAME_X_WINDOW (f) == wdesc)
475 /* Tooltip frame. */
476 return f;
477 }
478 return 0;
479 }
480 #endif /* USE_X_TOOLKIT || USE_GTK */
481
482 \f
483
484 static void x_default_font_parameter (struct frame *, Lisp_Object);
485
486 static Lisp_Object unwind_create_frame (Lisp_Object);
487 static Lisp_Object unwind_create_tip_frame (Lisp_Object);
488
489 void x_set_foreground_color (struct frame *, Lisp_Object, Lisp_Object);
490 static void x_set_wait_for_wm (struct frame *, Lisp_Object, Lisp_Object);
491 void x_set_background_color (struct frame *, Lisp_Object, Lisp_Object);
492 void x_set_mouse_color (struct frame *, Lisp_Object, Lisp_Object);
493 void x_set_cursor_color (struct frame *, Lisp_Object, Lisp_Object);
494 void x_set_border_color (struct frame *, Lisp_Object, Lisp_Object);
495 void x_set_cursor_type (struct frame *, Lisp_Object, Lisp_Object);
496 void x_set_icon_type (struct frame *, Lisp_Object, Lisp_Object);
497 void x_set_icon_name (struct frame *, Lisp_Object, Lisp_Object);
498 void x_explicitly_set_name (struct frame *, Lisp_Object, Lisp_Object);
499 void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
500 void x_set_title (struct frame *, Lisp_Object, Lisp_Object);
501 void x_set_tool_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
502 void x_set_scroll_bar_foreground (struct frame *, Lisp_Object,
503 Lisp_Object);
504 void x_set_scroll_bar_background (struct frame *, Lisp_Object,
505 Lisp_Object);
506 static Lisp_Object x_default_scroll_bar_color_parameter (struct frame *,
507 Lisp_Object,
508 Lisp_Object,
509 char *, char *,
510 int);
511 \f
512
513 /* Store the screen positions of frame F into XPTR and YPTR.
514 These are the positions of the containing window manager window,
515 not Emacs's own window. */
516
517 void
518 x_real_positions (FRAME_PTR f, int *xptr, int *yptr)
519 {
520 int win_x, win_y, outer_x, outer_y;
521 int real_x = 0, real_y = 0;
522 int had_errors = 0;
523 Window win = f->output_data.x->parent_desc;
524
525 BLOCK_INPUT;
526
527 x_catch_errors (FRAME_X_DISPLAY (f));
528
529 if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
530 win = FRAME_OUTER_WINDOW (f);
531
532 /* This loop traverses up the containment tree until we hit the root
533 window. Window managers may intersect many windows between our window
534 and the root window. The window we find just before the root window
535 should be the outer WM window. */
536 for (;;)
537 {
538 Window wm_window, rootw;
539 Window *tmp_children;
540 unsigned int tmp_nchildren;
541 int success;
542
543 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
544 &wm_window, &tmp_children, &tmp_nchildren);
545
546 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
547
548 /* Don't free tmp_children if XQueryTree failed. */
549 if (! success)
550 break;
551
552 XFree ((char *) tmp_children);
553
554 if (wm_window == rootw || had_errors)
555 break;
556
557 win = wm_window;
558 }
559
560 if (! had_errors)
561 {
562 unsigned int ign;
563 Window child, rootw;
564
565 /* Get the real coordinates for the WM window upper left corner */
566 XGetGeometry (FRAME_X_DISPLAY (f), win,
567 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
568
569 /* Translate real coordinates to coordinates relative to our
570 window. For our window, the upper left corner is 0, 0.
571 Since the upper left corner of the WM window is outside
572 our window, win_x and win_y will be negative:
573
574 ------------------ ---> x
575 | title |
576 | ----------------- v y
577 | | our window
578 */
579 XTranslateCoordinates (FRAME_X_DISPLAY (f),
580
581 /* From-window, to-window. */
582 FRAME_X_DISPLAY_INFO (f)->root_window,
583 FRAME_X_WINDOW (f),
584
585 /* From-position, to-position. */
586 real_x, real_y, &win_x, &win_y,
587
588 /* Child of win. */
589 &child);
590
591 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
592 {
593 outer_x = win_x;
594 outer_y = win_y;
595 }
596 else
597 {
598 XTranslateCoordinates (FRAME_X_DISPLAY (f),
599
600 /* From-window, to-window. */
601 FRAME_X_DISPLAY_INFO (f)->root_window,
602 FRAME_OUTER_WINDOW (f),
603
604 /* From-position, to-position. */
605 real_x, real_y, &outer_x, &outer_y,
606
607 /* Child of win. */
608 &child);
609 }
610
611 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
612 }
613
614 x_uncatch_errors ();
615
616 UNBLOCK_INPUT;
617
618 if (had_errors) return;
619
620 f->x_pixels_diff = -win_x;
621 f->y_pixels_diff = -win_y;
622
623 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
624 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
625
626 *xptr = real_x;
627 *yptr = real_y;
628 }
629
630 \f
631
632
633 /* Gamma-correct COLOR on frame F. */
634
635 void
636 gamma_correct (struct frame *f, XColor *color)
637 {
638 if (f->gamma)
639 {
640 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
641 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
642 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
643 }
644 }
645
646
647 /* Decide if color named COLOR_NAME is valid for use on frame F. If
648 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
649 allocate the color. Value is zero if COLOR_NAME is invalid, or
650 no color could be allocated. */
651
652 int
653 x_defined_color (struct frame *f, char *color_name, XColor *color, int alloc_p)
654 {
655 int success_p;
656 Display *dpy = FRAME_X_DISPLAY (f);
657 Colormap cmap = FRAME_X_COLORMAP (f);
658
659 BLOCK_INPUT;
660 success_p = XParseColor (dpy, cmap, color_name, color);
661 if (success_p && alloc_p)
662 success_p = x_alloc_nearest_color (f, cmap, color);
663 UNBLOCK_INPUT;
664
665 return success_p;
666 }
667
668
669 /* Return the pixel color value for color COLOR_NAME on frame F. If F
670 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
671 Signal an error if color can't be allocated. */
672
673 int
674 x_decode_color (FRAME_PTR f, Lisp_Object color_name, int mono_color)
675 {
676 XColor cdef;
677
678 CHECK_STRING (color_name);
679
680 #if 0 /* Don't do this. It's wrong when we're not using the default
681 colormap, it makes freeing difficult, and it's probably not
682 an important optimization. */
683 if (strcmp (SDATA (color_name), "black") == 0)
684 return BLACK_PIX_DEFAULT (f);
685 else if (strcmp (SDATA (color_name), "white") == 0)
686 return WHITE_PIX_DEFAULT (f);
687 #endif
688
689 /* Return MONO_COLOR for monochrome frames. */
690 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
691 return mono_color;
692
693 /* x_defined_color is responsible for coping with failures
694 by looking for a near-miss. */
695 if (x_defined_color (f, SDATA (color_name), &cdef, 1))
696 return cdef.pixel;
697
698 signal_error ("Undefined color", color_name);
699 }
700
701
702 \f
703 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
704 the previous value of that parameter, NEW_VALUE is the new value.
705 See also the comment of wait_for_wm in struct x_output. */
706
707 static void
708 x_set_wait_for_wm (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
709 {
710 f->output_data.x->wait_for_wm = !NILP (new_value);
711 }
712
713 #ifdef USE_GTK
714
715 /* Set icon from FILE for frame F. By using GTK functions the icon
716 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
717
718 int
719 xg_set_icon (FRAME_PTR f, Lisp_Object file)
720 {
721 int result = 0;
722 Lisp_Object found;
723
724 found = x_find_image_file (file);
725
726 if (! NILP (found))
727 {
728 GdkPixbuf *pixbuf;
729 GError *err = NULL;
730 char *filename = (char *) SDATA (found);
731 BLOCK_INPUT;
732
733 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
734
735 if (pixbuf)
736 {
737 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
738 pixbuf);
739 g_object_unref (pixbuf);
740
741 result = 1;
742 }
743 else
744 g_error_free (err);
745
746 UNBLOCK_INPUT;
747 }
748
749 return result;
750 }
751
752 int
753 xg_set_icon_from_xpm_data (FRAME_PTR f, char **data)
754 {
755 int result = 0;
756 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data);
757
758 if (!pixbuf)
759 return 0;
760
761 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
762 g_object_unref (pixbuf);
763 return 1;
764 }
765 #endif /* USE_GTK */
766
767
768 /* Functions called only from `x_set_frame_param'
769 to set individual parameters.
770
771 If FRAME_X_WINDOW (f) is 0,
772 the frame is being created and its X-window does not exist yet.
773 In that case, just record the parameter's new value
774 in the standard place; do not attempt to change the window. */
775
776 void
777 x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
778 {
779 struct x_output *x = f->output_data.x;
780 unsigned long fg, old_fg;
781
782 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
783 old_fg = FRAME_FOREGROUND_PIXEL (f);
784 FRAME_FOREGROUND_PIXEL (f) = fg;
785
786 if (FRAME_X_WINDOW (f) != 0)
787 {
788 Display *dpy = FRAME_X_DISPLAY (f);
789
790 BLOCK_INPUT;
791 XSetForeground (dpy, x->normal_gc, fg);
792 XSetBackground (dpy, x->reverse_gc, fg);
793
794 if (x->cursor_pixel == old_fg)
795 {
796 unload_color (f, x->cursor_pixel);
797 x->cursor_pixel = x_copy_color (f, fg);
798 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
799 }
800
801 UNBLOCK_INPUT;
802
803 update_face_from_frame_parameter (f, Qforeground_color, arg);
804
805 if (FRAME_VISIBLE_P (f))
806 redraw_frame (f);
807 }
808
809 unload_color (f, old_fg);
810 }
811
812 void
813 x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
814 {
815 struct x_output *x = f->output_data.x;
816 unsigned long bg;
817
818 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
819 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
820 FRAME_BACKGROUND_PIXEL (f) = bg;
821
822 if (FRAME_X_WINDOW (f) != 0)
823 {
824 Display *dpy = FRAME_X_DISPLAY (f);
825
826 BLOCK_INPUT;
827 XSetBackground (dpy, x->normal_gc, bg);
828 XSetForeground (dpy, x->reverse_gc, bg);
829 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
830 XSetForeground (dpy, x->cursor_gc, bg);
831
832 #ifdef USE_GTK
833 xg_set_background_color (f, bg);
834 #endif
835
836 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
837 toolkit scroll bars. */
838 {
839 Lisp_Object bar;
840 for (bar = FRAME_SCROLL_BARS (f);
841 !NILP (bar);
842 bar = XSCROLL_BAR (bar)->next)
843 {
844 Window window = XSCROLL_BAR (bar)->x_window;
845 XSetWindowBackground (dpy, window, bg);
846 }
847 }
848 #endif /* USE_TOOLKIT_SCROLL_BARS */
849
850 UNBLOCK_INPUT;
851 update_face_from_frame_parameter (f, Qbackground_color, arg);
852
853 if (FRAME_VISIBLE_P (f))
854 redraw_frame (f);
855 }
856 }
857
858 static Cursor
859 make_invisible_cursor (struct frame *f)
860 {
861 Display *dpy = FRAME_X_DISPLAY (f);
862 static char const no_data[] = { 0 };
863 Pixmap pix;
864 XColor col;
865 Cursor c;
866
867 x_catch_errors (dpy);
868 pix = XCreateBitmapFromData (dpy, FRAME_X_DISPLAY_INFO (f)->root_window,
869 no_data, 1, 1);
870 if (! x_had_errors_p (dpy) && pix != None)
871 {
872 col.pixel = 0;
873 col.red = col.green = col.blue = 0;
874 col.flags = DoRed | DoGreen | DoBlue;
875 c = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
876 if (x_had_errors_p (dpy) || c == None)
877 c = 0;
878 XFreePixmap (dpy, pix);
879 }
880
881 x_uncatch_errors ();
882
883 return c;
884 }
885
886 void
887 x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
888 {
889 struct x_output *x = f->output_data.x;
890 Display *dpy = FRAME_X_DISPLAY (f);
891 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
892 Cursor hourglass_cursor, horizontal_drag_cursor;
893 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
894 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
895
896 /* Don't let pointers be invisible. */
897 if (mask_color == pixel)
898 {
899 x_free_colors (f, &pixel, 1);
900 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
901 }
902
903 unload_color (f, x->mouse_pixel);
904 x->mouse_pixel = pixel;
905
906 BLOCK_INPUT;
907
908 /* It's not okay to crash if the user selects a screwy cursor. */
909 x_catch_errors (dpy);
910
911 if (!NILP (Vx_pointer_shape))
912 {
913 CHECK_NUMBER (Vx_pointer_shape);
914 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
915 }
916 else
917 cursor = XCreateFontCursor (dpy, XC_xterm);
918 x_check_errors (dpy, "bad text pointer cursor: %s");
919
920 if (!NILP (Vx_nontext_pointer_shape))
921 {
922 CHECK_NUMBER (Vx_nontext_pointer_shape);
923 nontext_cursor
924 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
925 }
926 else
927 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
928 x_check_errors (dpy, "bad nontext pointer cursor: %s");
929
930 if (!NILP (Vx_hourglass_pointer_shape))
931 {
932 CHECK_NUMBER (Vx_hourglass_pointer_shape);
933 hourglass_cursor
934 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
935 }
936 else
937 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
938 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
939
940 if (!NILP (Vx_mode_pointer_shape))
941 {
942 CHECK_NUMBER (Vx_mode_pointer_shape);
943 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
944 }
945 else
946 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
947 x_check_errors (dpy, "bad modeline pointer cursor: %s");
948
949 if (!NILP (Vx_sensitive_text_pointer_shape))
950 {
951 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
952 hand_cursor
953 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
954 }
955 else
956 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
957
958 if (!NILP (Vx_window_horizontal_drag_shape))
959 {
960 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
961 horizontal_drag_cursor
962 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
963 }
964 else
965 horizontal_drag_cursor
966 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
967
968 /* Check and report errors with the above calls. */
969 x_check_errors (dpy, "can't set cursor shape: %s");
970 x_uncatch_errors ();
971
972 {
973 XColor fore_color, back_color;
974
975 fore_color.pixel = x->mouse_pixel;
976 x_query_color (f, &fore_color);
977 back_color.pixel = mask_color;
978 x_query_color (f, &back_color);
979
980 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
981 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
982 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
983 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
984 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
985 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
986 }
987
988 if (FRAME_X_WINDOW (f) != 0)
989 XDefineCursor (dpy, FRAME_X_WINDOW (f),
990 f->output_data.x->current_cursor = cursor);
991
992 if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor == 0)
993 FRAME_X_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
994
995 if (cursor != x->text_cursor
996 && x->text_cursor != 0)
997 XFreeCursor (dpy, x->text_cursor);
998 x->text_cursor = cursor;
999
1000 if (nontext_cursor != x->nontext_cursor
1001 && x->nontext_cursor != 0)
1002 XFreeCursor (dpy, x->nontext_cursor);
1003 x->nontext_cursor = nontext_cursor;
1004
1005 if (hourglass_cursor != x->hourglass_cursor
1006 && x->hourglass_cursor != 0)
1007 XFreeCursor (dpy, x->hourglass_cursor);
1008 x->hourglass_cursor = hourglass_cursor;
1009
1010 if (mode_cursor != x->modeline_cursor
1011 && x->modeline_cursor != 0)
1012 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1013 x->modeline_cursor = mode_cursor;
1014
1015 if (hand_cursor != x->hand_cursor
1016 && x->hand_cursor != 0)
1017 XFreeCursor (dpy, x->hand_cursor);
1018 x->hand_cursor = hand_cursor;
1019
1020 if (horizontal_drag_cursor != x->horizontal_drag_cursor
1021 && x->horizontal_drag_cursor != 0)
1022 XFreeCursor (dpy, x->horizontal_drag_cursor);
1023 x->horizontal_drag_cursor = horizontal_drag_cursor;
1024
1025 XFlush (dpy);
1026 UNBLOCK_INPUT;
1027
1028 update_face_from_frame_parameter (f, Qmouse_color, arg);
1029 }
1030
1031 void
1032 x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1033 {
1034 unsigned long fore_pixel, pixel;
1035 int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
1036 struct x_output *x = f->output_data.x;
1037
1038 if (!NILP (Vx_cursor_fore_pixel))
1039 {
1040 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1041 WHITE_PIX_DEFAULT (f));
1042 fore_pixel_allocated_p = 1;
1043 }
1044 else
1045 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1046
1047 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1048 pixel_allocated_p = 1;
1049
1050 /* Make sure that the cursor color differs from the background color. */
1051 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1052 {
1053 if (pixel_allocated_p)
1054 {
1055 x_free_colors (f, &pixel, 1);
1056 pixel_allocated_p = 0;
1057 }
1058
1059 pixel = x->mouse_pixel;
1060 if (pixel == fore_pixel)
1061 {
1062 if (fore_pixel_allocated_p)
1063 {
1064 x_free_colors (f, &fore_pixel, 1);
1065 fore_pixel_allocated_p = 0;
1066 }
1067 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1068 }
1069 }
1070
1071 unload_color (f, x->cursor_foreground_pixel);
1072 if (!fore_pixel_allocated_p)
1073 fore_pixel = x_copy_color (f, fore_pixel);
1074 x->cursor_foreground_pixel = fore_pixel;
1075
1076 unload_color (f, x->cursor_pixel);
1077 if (!pixel_allocated_p)
1078 pixel = x_copy_color (f, pixel);
1079 x->cursor_pixel = pixel;
1080
1081 if (FRAME_X_WINDOW (f) != 0)
1082 {
1083 BLOCK_INPUT;
1084 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1085 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1086 UNBLOCK_INPUT;
1087
1088 if (FRAME_VISIBLE_P (f))
1089 {
1090 x_update_cursor (f, 0);
1091 x_update_cursor (f, 1);
1092 }
1093 }
1094
1095 update_face_from_frame_parameter (f, Qcursor_color, arg);
1096 }
1097 \f
1098 /* Set the border-color of frame F to pixel value PIX.
1099 Note that this does not fully take effect if done before
1100 F has an x-window. */
1101
1102 void
1103 x_set_border_pixel (struct frame *f, int pix)
1104 {
1105 unload_color (f, f->output_data.x->border_pixel);
1106 f->output_data.x->border_pixel = pix;
1107
1108 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1109 {
1110 BLOCK_INPUT;
1111 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1112 (unsigned long)pix);
1113 UNBLOCK_INPUT;
1114
1115 if (FRAME_VISIBLE_P (f))
1116 redraw_frame (f);
1117 }
1118 }
1119
1120 /* Set the border-color of frame F to value described by ARG.
1121 ARG can be a string naming a color.
1122 The border-color is used for the border that is drawn by the X server.
1123 Note that this does not fully take effect if done before
1124 F has an x-window; it must be redone when the window is created.
1125
1126 Note: this is done in two routines because of the way X10 works.
1127
1128 Note: under X11, this is normally the province of the window manager,
1129 and so emacs' border colors may be overridden. */
1130
1131 void
1132 x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1133 {
1134 int pix;
1135
1136 CHECK_STRING (arg);
1137 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1138 x_set_border_pixel (f, pix);
1139 update_face_from_frame_parameter (f, Qborder_color, arg);
1140 }
1141
1142
1143 void
1144 x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
1145 {
1146 set_frame_cursor_types (f, arg);
1147
1148 /* Make sure the cursor gets redrawn. */
1149 cursor_type_changed = 1;
1150 }
1151 \f
1152 void
1153 x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1154 {
1155 int result;
1156
1157 if (STRINGP (arg))
1158 {
1159 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1160 return;
1161 }
1162 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1163 return;
1164
1165 BLOCK_INPUT;
1166 if (NILP (arg))
1167 result = x_text_icon (f,
1168 (char *) SDATA ((!NILP (f->icon_name)
1169 ? f->icon_name
1170 : f->name)));
1171 else
1172 result = x_bitmap_icon (f, arg);
1173
1174 if (result)
1175 {
1176 UNBLOCK_INPUT;
1177 error ("No icon window available");
1178 }
1179
1180 XFlush (FRAME_X_DISPLAY (f));
1181 UNBLOCK_INPUT;
1182 }
1183
1184 void
1185 x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1186 {
1187 int result;
1188
1189 if (STRINGP (arg))
1190 {
1191 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1192 return;
1193 }
1194 else if (!NILP (arg) || NILP (oldval))
1195 return;
1196
1197 f->icon_name = arg;
1198
1199 if (f->output_data.x->icon_bitmap != 0)
1200 return;
1201
1202 BLOCK_INPUT;
1203
1204 result = x_text_icon (f,
1205 (char *) SDATA ((!NILP (f->icon_name)
1206 ? f->icon_name
1207 : !NILP (f->title)
1208 ? f->title
1209 : f->name)));
1210
1211 if (result)
1212 {
1213 UNBLOCK_INPUT;
1214 error ("No icon window available");
1215 }
1216
1217 XFlush (FRAME_X_DISPLAY (f));
1218 UNBLOCK_INPUT;
1219 }
1220
1221 \f
1222 void
1223 x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1224 {
1225 int nlines;
1226 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1227 int olines = FRAME_MENU_BAR_LINES (f);
1228 #endif
1229
1230 /* Right now, menu bars don't work properly in minibuf-only frames;
1231 most of the commands try to apply themselves to the minibuffer
1232 frame itself, and get an error because you can't switch buffers
1233 in or split the minibuffer window. */
1234 if (FRAME_MINIBUF_ONLY_P (f))
1235 return;
1236
1237 if (INTEGERP (value))
1238 nlines = XINT (value);
1239 else
1240 nlines = 0;
1241
1242 /* Make sure we redisplay all windows in this frame. */
1243 windows_or_buffers_changed++;
1244
1245 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1246 FRAME_MENU_BAR_LINES (f) = 0;
1247 if (nlines)
1248 {
1249 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1250 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1251 /* Make sure next redisplay shows the menu bar. */
1252 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1253 }
1254 else
1255 {
1256 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1257 free_frame_menubar (f);
1258 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1259 if (FRAME_X_P (f))
1260 f->output_data.x->menubar_widget = 0;
1261 }
1262 #else /* not USE_X_TOOLKIT && not USE_GTK */
1263 FRAME_MENU_BAR_LINES (f) = nlines;
1264 change_window_heights (f->root_window, nlines - olines);
1265
1266 /* If the menu bar height gets changed, the internal border below
1267 the top margin has to be cleared. Also, if the menu bar gets
1268 larger, the area for the added lines has to be cleared except for
1269 the first menu bar line that is to be drawn later. */
1270 if (nlines != olines)
1271 {
1272 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1273 int width = FRAME_PIXEL_WIDTH (f);
1274 int y;
1275
1276 /* height can be zero here. */
1277 if (height > 0 && width > 0)
1278 {
1279 y = FRAME_TOP_MARGIN_HEIGHT (f);
1280
1281 BLOCK_INPUT;
1282 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1283 0, y, width, height, False);
1284 UNBLOCK_INPUT;
1285 }
1286
1287 if (nlines > 1 && nlines > olines)
1288 {
1289 y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
1290 height = nlines * FRAME_LINE_HEIGHT (f) - y;
1291
1292 BLOCK_INPUT;
1293 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1294 0, y, width, height, False);
1295 UNBLOCK_INPUT;
1296 }
1297
1298 if (nlines == 0 && WINDOWP (f->menu_bar_window))
1299 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
1300 }
1301 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1302 adjust_glyphs (f);
1303 }
1304
1305
1306 /* Set the number of lines used for the tool bar of frame F to VALUE.
1307 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1308 is the old number of tool bar lines. This function changes the
1309 height of all windows on frame F to match the new tool bar height.
1310 The frame's height doesn't change. */
1311
1312 void
1313 x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1314 {
1315 int delta, nlines, root_height;
1316 Lisp_Object root_window;
1317
1318 /* Treat tool bars like menu bars. */
1319 if (FRAME_MINIBUF_ONLY_P (f))
1320 return;
1321
1322 /* Use VALUE only if an integer >= 0. */
1323 if (INTEGERP (value) && XINT (value) >= 0)
1324 nlines = XFASTINT (value);
1325 else
1326 nlines = 0;
1327
1328 #ifdef USE_GTK
1329 FRAME_TOOL_BAR_LINES (f) = 0;
1330 if (nlines)
1331 {
1332 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1333 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1334 /* Make sure next redisplay shows the tool bar. */
1335 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1336 update_frame_tool_bar (f);
1337 }
1338 else
1339 {
1340 if (FRAME_EXTERNAL_TOOL_BAR (f))
1341 free_frame_tool_bar (f);
1342 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1343 }
1344
1345 return;
1346 #endif
1347
1348 /* Make sure we redisplay all windows in this frame. */
1349 ++windows_or_buffers_changed;
1350
1351 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1352
1353 /* Don't resize the tool-bar to more than we have room for. */
1354 root_window = FRAME_ROOT_WINDOW (f);
1355 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1356 if (root_height - delta < 1)
1357 {
1358 delta = root_height - 1;
1359 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1360 }
1361
1362 FRAME_TOOL_BAR_LINES (f) = nlines;
1363 change_window_heights (root_window, delta);
1364 adjust_glyphs (f);
1365
1366 /* We also have to make sure that the internal border at the top of
1367 the frame, below the menu bar or tool bar, is redrawn when the
1368 tool bar disappears. This is so because the internal border is
1369 below the tool bar if one is displayed, but is below the menu bar
1370 if there isn't a tool bar. The tool bar draws into the area
1371 below the menu bar. */
1372 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1373 {
1374 clear_frame (f);
1375 clear_current_matrices (f);
1376 }
1377
1378 /* If the tool bar gets smaller, the internal border below it
1379 has to be cleared. It was formerly part of the display
1380 of the larger tool bar, and updating windows won't clear it. */
1381 if (delta < 0)
1382 {
1383 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1384 int width = FRAME_PIXEL_WIDTH (f);
1385 int y = (FRAME_MENU_BAR_LINES (f) + nlines) * FRAME_LINE_HEIGHT (f);
1386
1387 /* height can be zero here. */
1388 if (height > 0 && width > 0)
1389 {
1390 BLOCK_INPUT;
1391 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1392 0, y, width, height, False);
1393 UNBLOCK_INPUT;
1394 }
1395
1396 if (WINDOWP (f->tool_bar_window))
1397 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1398 }
1399 }
1400
1401
1402 /* Set the foreground color for scroll bars on frame F to VALUE.
1403 VALUE should be a string, a color name. If it isn't a string or
1404 isn't a valid color name, do nothing. OLDVAL is the old value of
1405 the frame parameter. */
1406
1407 void
1408 x_set_scroll_bar_foreground (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1409 {
1410 unsigned long pixel;
1411
1412 if (STRINGP (value))
1413 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1414 else
1415 pixel = -1;
1416
1417 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1418 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1419
1420 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1421 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1422 {
1423 /* Remove all scroll bars because they have wrong colors. */
1424 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1425 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1426 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1427 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1428
1429 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1430 redraw_frame (f);
1431 }
1432 }
1433
1434
1435 /* Set the background color for scroll bars on frame F to VALUE VALUE
1436 should be a string, a color name. If it isn't a string or isn't a
1437 valid color name, do nothing. OLDVAL is the old value of the frame
1438 parameter. */
1439
1440 void
1441 x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1442 {
1443 unsigned long pixel;
1444
1445 if (STRINGP (value))
1446 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1447 else
1448 pixel = -1;
1449
1450 if (f->output_data.x->scroll_bar_background_pixel != -1)
1451 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1452
1453 #ifdef USE_TOOLKIT_SCROLL_BARS
1454 /* Scrollbar shadow colors. */
1455 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1456 {
1457 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1458 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1459 }
1460 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1461 {
1462 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1463 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1464 }
1465 #endif /* USE_TOOLKIT_SCROLL_BARS */
1466
1467 f->output_data.x->scroll_bar_background_pixel = pixel;
1468 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1469 {
1470 /* Remove all scroll bars because they have wrong colors. */
1471 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1472 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1473 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1474 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1475
1476 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1477 redraw_frame (f);
1478 }
1479 }
1480
1481 \f
1482 /* Encode Lisp string STRING as a text in a format appropriate for
1483 XICCC (X Inter Client Communication Conventions).
1484
1485 This can call Lisp code, so callers must GCPRO.
1486
1487 If STRING contains only ASCII characters, do no conversion and
1488 return the string data of STRING. Otherwise, encode the text by
1489 CODING_SYSTEM, and return a newly allocated memory area which
1490 should be freed by `xfree' by a caller.
1491
1492 SELECTIONP non-zero means the string is being encoded for an X
1493 selection, so it is safe to run pre-write conversions (which
1494 may run Lisp code).
1495
1496 Store the byte length of resulting text in *TEXT_BYTES.
1497
1498 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1499 which means that the `encoding' of the result can be `STRING'.
1500 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1501 the result should be `COMPOUND_TEXT'. */
1502
1503 static unsigned char *
1504 x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, int *text_bytes, int *stringp, int *freep)
1505 {
1506 int result = string_xstring_p (string);
1507 struct coding_system coding;
1508
1509 if (result == 0)
1510 {
1511 /* No multibyte character in OBJ. We need not encode it. */
1512 *text_bytes = SBYTES (string);
1513 *stringp = 1;
1514 *freep = 0;
1515 return SDATA (string);
1516 }
1517
1518 setup_coding_system (coding_system, &coding);
1519 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1520 /* We suppress producing escape sequences for composition. */
1521 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1522 coding.dst_bytes = SCHARS (string) * 2;
1523 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
1524 encode_coding_object (&coding, string, 0, 0,
1525 SCHARS (string), SBYTES (string), Qnil);
1526 *text_bytes = coding.produced;
1527 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1528 *freep = 1;
1529 return coding.destination;
1530 }
1531
1532 \f
1533 /* Set the WM name to NAME for frame F. Also set the icon name.
1534 If the frame already has an icon name, use that, otherwise set the
1535 icon name to NAME. */
1536
1537 static void
1538 x_set_name_internal (FRAME_PTR f, Lisp_Object name)
1539 {
1540 if (FRAME_X_WINDOW (f))
1541 {
1542 BLOCK_INPUT;
1543 {
1544 XTextProperty text, icon;
1545 int bytes, stringp;
1546 int do_free_icon_value = 0, do_free_text_value = 0;
1547 Lisp_Object coding_system;
1548 Lisp_Object encoded_name;
1549 Lisp_Object encoded_icon_name;
1550 struct gcpro gcpro1;
1551
1552 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1553 we use it before x_encode_text that may return string data. */
1554 GCPRO1 (name);
1555 encoded_name = ENCODE_UTF_8 (name);
1556 UNGCPRO;
1557
1558 coding_system = Qcompound_text;
1559 /* Note: Encoding strategy
1560
1561 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1562 text.encoding. But, there are non-internationalized window
1563 managers which don't support that encoding. So, if NAME
1564 contains only ASCII and 8859-1 characters, encode it by
1565 iso-latin-1, and use "STRING" in text.encoding hoping that
1566 such window managers at least analyze this format correctly,
1567 i.e. treat 8-bit bytes as 8859-1 characters.
1568
1569 We may also be able to use "UTF8_STRING" in text.encoding
1570 in the future which can encode all Unicode characters.
1571 But, for the moment, there's no way to know that the
1572 current window manager supports it or not.
1573
1574 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1575 properties. Per the EWMH specification, those two properties
1576 are always UTF8_STRING. This matches what gtk_window_set_title()
1577 does in the USE_GTK case. */
1578 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1579 &do_free_text_value);
1580 text.encoding = (stringp ? XA_STRING
1581 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1582 text.format = 8;
1583 text.nitems = bytes;
1584
1585 if (!STRINGP (f->icon_name))
1586 {
1587 icon = text;
1588 encoded_icon_name = encoded_name;
1589 }
1590 else
1591 {
1592 /* See the above comment "Note: Encoding strategy". */
1593 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1594 &bytes, &stringp, &do_free_icon_value);
1595 icon.encoding = (stringp ? XA_STRING
1596 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1597 icon.format = 8;
1598 icon.nitems = bytes;
1599
1600 encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
1601 }
1602
1603 #ifdef USE_GTK
1604 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1605 (char *) SDATA (encoded_name));
1606 #else /* not USE_GTK */
1607 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1608 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1609 FRAME_X_DISPLAY_INFO (f)->Xatom_net_wm_name,
1610 FRAME_X_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1611 8, PropModeReplace,
1612 (char *) SDATA (encoded_name),
1613 SBYTES (encoded_name));
1614 #endif /* not USE_GTK */
1615
1616 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1617 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1618 FRAME_X_DISPLAY_INFO (f)->Xatom_net_wm_icon_name,
1619 FRAME_X_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1620 8, PropModeReplace,
1621 (char *) SDATA (encoded_icon_name),
1622 SBYTES (encoded_icon_name));
1623
1624 if (do_free_icon_value)
1625 xfree (icon.value);
1626 if (do_free_text_value)
1627 xfree (text.value);
1628 }
1629 UNBLOCK_INPUT;
1630 }
1631 }
1632
1633 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1634 x_id_name.
1635
1636 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1637 name; if NAME is a string, set F's name to NAME and set
1638 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1639
1640 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1641 suggesting a new name, which lisp code should override; if
1642 F->explicit_name is set, ignore the new name; otherwise, set it. */
1643
1644 void
1645 x_set_name (struct frame *f, Lisp_Object name, int explicit)
1646 {
1647 /* Make sure that requests from lisp code override requests from
1648 Emacs redisplay code. */
1649 if (explicit)
1650 {
1651 /* If we're switching from explicit to implicit, we had better
1652 update the mode lines and thereby update the title. */
1653 if (f->explicit_name && NILP (name))
1654 update_mode_lines = 1;
1655
1656 f->explicit_name = ! NILP (name);
1657 }
1658 else if (f->explicit_name)
1659 return;
1660
1661 /* If NAME is nil, set the name to the x_id_name. */
1662 if (NILP (name))
1663 {
1664 /* Check for no change needed in this very common case
1665 before we do any consing. */
1666 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1667 SDATA (f->name)))
1668 return;
1669 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1670 }
1671 else
1672 CHECK_STRING (name);
1673
1674 /* Don't change the name if it's already NAME. */
1675 if (! NILP (Fstring_equal (name, f->name)))
1676 return;
1677
1678 f->name = name;
1679
1680 /* For setting the frame title, the title parameter should override
1681 the name parameter. */
1682 if (! NILP (f->title))
1683 name = f->title;
1684
1685 x_set_name_internal (f, name);
1686 }
1687
1688 /* This function should be called when the user's lisp code has
1689 specified a name for the frame; the name will override any set by the
1690 redisplay code. */
1691 void
1692 x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
1693 {
1694 x_set_name (f, arg, 1);
1695 }
1696
1697 /* This function should be called by Emacs redisplay code to set the
1698 name; names set this way will never override names set by the user's
1699 lisp code. */
1700 void
1701 x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
1702 {
1703 x_set_name (f, arg, 0);
1704 }
1705 \f
1706 /* Change the title of frame F to NAME.
1707 If NAME is nil, use the frame name as the title. */
1708
1709 void
1710 x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
1711 {
1712 /* Don't change the title if it's already NAME. */
1713 if (EQ (name, f->title))
1714 return;
1715
1716 update_mode_lines = 1;
1717
1718 f->title = name;
1719
1720 if (NILP (name))
1721 name = f->name;
1722 else
1723 CHECK_STRING (name);
1724
1725 x_set_name_internal (f, name);
1726 }
1727
1728 void
1729 x_set_scroll_bar_default_width (struct frame *f)
1730 {
1731 int wid = FRAME_COLUMN_WIDTH (f);
1732
1733 #ifdef USE_TOOLKIT_SCROLL_BARS
1734 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1735 int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1736 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1737 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1738 #else
1739 /* Make the actual width at least 14 pixels and a multiple of a
1740 character width. */
1741 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1742
1743 /* Use all of that space (aside from required margins) for the
1744 scroll bar. */
1745 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1746 #endif
1747 }
1748
1749 \f
1750 /* Record in frame F the specified or default value according to ALIST
1751 of the parameter named PROP (a Lisp symbol). If no value is
1752 specified for PROP, look for an X default for XPROP on the frame
1753 named NAME. If that is not found either, use the value DEFLT. */
1754
1755 static Lisp_Object
1756 x_default_scroll_bar_color_parameter (struct frame *f,
1757 Lisp_Object alist, Lisp_Object prop,
1758 char *xprop, char *xclass,
1759 int foreground_p)
1760 {
1761 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1762 Lisp_Object tem;
1763
1764 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1765 if (EQ (tem, Qunbound))
1766 {
1767 #ifdef USE_TOOLKIT_SCROLL_BARS
1768
1769 /* See if an X resource for the scroll bar color has been
1770 specified. */
1771 tem = display_x_get_resource (dpyinfo,
1772 build_string (foreground_p
1773 ? "foreground"
1774 : "background"),
1775 empty_unibyte_string,
1776 build_string ("verticalScrollBar"),
1777 empty_unibyte_string);
1778 if (!STRINGP (tem))
1779 {
1780 /* If nothing has been specified, scroll bars will use a
1781 toolkit-dependent default. Because these defaults are
1782 difficult to get at without actually creating a scroll
1783 bar, use nil to indicate that no color has been
1784 specified. */
1785 tem = Qnil;
1786 }
1787
1788 #else /* not USE_TOOLKIT_SCROLL_BARS */
1789
1790 tem = Qnil;
1791
1792 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1793 }
1794
1795 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1796 return tem;
1797 }
1798
1799
1800
1801 \f
1802 #ifdef USE_X_TOOLKIT
1803
1804 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1805 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1806 already be present because of the toolkit (Motif adds some of them,
1807 for example, but Xt doesn't). */
1808
1809 static void
1810 hack_wm_protocols (FRAME_PTR f, Widget widget)
1811 {
1812 Display *dpy = XtDisplay (widget);
1813 Window w = XtWindow (widget);
1814 int need_delete = 1;
1815 int need_focus = 1;
1816 int need_save = 1;
1817
1818 BLOCK_INPUT;
1819 {
1820 Atom type;
1821 unsigned char *catoms;
1822 int format = 0;
1823 unsigned long nitems = 0;
1824 unsigned long bytes_after;
1825
1826 if ((XGetWindowProperty (dpy, w,
1827 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1828 (long)0, (long)100, False, XA_ATOM,
1829 &type, &format, &nitems, &bytes_after,
1830 &catoms)
1831 == Success)
1832 && format == 32 && type == XA_ATOM)
1833 {
1834 Atom *atoms = (Atom *) catoms;
1835 while (nitems > 0)
1836 {
1837 nitems--;
1838 if (atoms[nitems]
1839 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1840 need_delete = 0;
1841 else if (atoms[nitems]
1842 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1843 need_focus = 0;
1844 else if (atoms[nitems]
1845 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1846 need_save = 0;
1847 }
1848 }
1849 if (catoms)
1850 XFree (catoms);
1851 }
1852 {
1853 Atom props [10];
1854 int count = 0;
1855 if (need_delete)
1856 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1857 if (need_focus)
1858 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1859 if (need_save)
1860 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1861 if (count)
1862 XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1863 XA_ATOM, 32, PropModeAppend,
1864 (unsigned char *) props, count);
1865 }
1866 UNBLOCK_INPUT;
1867 }
1868 #endif
1869
1870
1871 \f
1872 /* Support routines for XIC (X Input Context). */
1873
1874 #ifdef HAVE_X_I18N
1875
1876 static XFontSet xic_create_xfontset (struct frame *);
1877 static XIMStyle best_xim_style (XIMStyles *, XIMStyles *);
1878
1879
1880 /* Supported XIM styles, ordered by preference. */
1881
1882 static XIMStyle supported_xim_styles[] =
1883 {
1884 XIMPreeditPosition | XIMStatusArea,
1885 XIMPreeditPosition | XIMStatusNothing,
1886 XIMPreeditPosition | XIMStatusNone,
1887 XIMPreeditNothing | XIMStatusArea,
1888 XIMPreeditNothing | XIMStatusNothing,
1889 XIMPreeditNothing | XIMStatusNone,
1890 XIMPreeditNone | XIMStatusArea,
1891 XIMPreeditNone | XIMStatusNothing,
1892 XIMPreeditNone | XIMStatusNone,
1893 0,
1894 };
1895
1896
1897 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1898
1899 char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1900
1901 /* Create an Xt fontset spec from the name of a base font.
1902 If `motif' is True use the Motif syntax. */
1903 char *
1904 xic_create_fontsetname (char *base_fontname, int motif)
1905 {
1906 const char *sep = motif ? ";" : ",";
1907 char *fontsetname;
1908
1909 /* Make a fontset name from the base font name. */
1910 if (xic_defaut_fontset == base_fontname)
1911 { /* There is no base font name, use the default. */
1912 int len = strlen (base_fontname) + 2;
1913 fontsetname = xmalloc (len);
1914 memset (fontsetname, 0, len);
1915 strcpy (fontsetname, base_fontname);
1916 }
1917 else
1918 {
1919 /* Make a fontset name from the base font name.
1920 The font set will be made of the following elements:
1921 - the base font.
1922 - the base font where the charset spec is replaced by -*-*.
1923 - the same but with the family also replaced with -*-*-. */
1924 char *p = base_fontname;
1925 int i;
1926
1927 for (i = 0; *p; p++)
1928 if (*p == '-') i++;
1929 if (i != 14)
1930 { /* As the font name doesn't conform to XLFD, we can't
1931 modify it to generalize it to allcs and allfamilies.
1932 Use the specified font plus the default. */
1933 int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3;
1934 fontsetname = xmalloc (len);
1935 memset (fontsetname, 0, len);
1936 strcpy (fontsetname, base_fontname);
1937 strcat (fontsetname, sep);
1938 strcat (fontsetname, xic_defaut_fontset);
1939 }
1940 else
1941 {
1942 int len;
1943 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
1944 char *font_allcs = NULL;
1945 char *font_allfamilies = NULL;
1946 char *font_all = NULL;
1947 char *allcs = "*-*-*-*-*-*-*";
1948 char *allfamilies = "-*-*-";
1949 char *all = "*-*-*-*-";
1950 char *base;
1951
1952 for (i = 0, p = base_fontname; i < 8; p++)
1953 {
1954 if (*p == '-')
1955 {
1956 i++;
1957 if (i == 3)
1958 p1 = p + 1;
1959 else if (i == 7)
1960 p2 = p + 1;
1961 else if (i == 6)
1962 p3 = p + 1;
1963 }
1964 }
1965 /* If base_fontname specifies ADSTYLE, make it a
1966 wildcard. */
1967 if (*p3 != '*')
1968 {
1969 int diff = (p2 - p3) - 2;
1970
1971 base = alloca (strlen (base_fontname) + 1);
1972 memcpy (base, base_fontname, p3 - base_fontname);
1973 base[p3 - base_fontname] = '*';
1974 base[(p3 - base_fontname) + 1] = '-';
1975 strcpy (base + (p3 - base_fontname) + 2, p2);
1976 p = base + (p - base_fontname) - diff;
1977 p1 = base + (p1 - base_fontname);
1978 p2 = base + (p2 - base_fontname) - diff;
1979 base_fontname = base;
1980 }
1981
1982 /* Build the font spec that matches all charsets. */
1983 len = p - base_fontname + strlen (allcs) + 1;
1984 font_allcs = (char *) alloca (len);
1985 memset (font_allcs, 0, len);
1986 memcpy (font_allcs, base_fontname, p - base_fontname);
1987 strcat (font_allcs, allcs);
1988
1989 /* Build the font spec that matches all families and
1990 add-styles. */
1991 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
1992 font_allfamilies = (char *) alloca (len);
1993 memset (font_allfamilies, 0, len);
1994 strcpy (font_allfamilies, allfamilies);
1995 memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1);
1996 strcat (font_allfamilies, allcs);
1997
1998 /* Build the font spec that matches all. */
1999 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
2000 font_all = (char *) alloca (len);
2001 memset (font_all, 0, len);
2002 strcpy (font_all, allfamilies);
2003 strcat (font_all, all);
2004 memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2);
2005 strcat (font_all, allcs);
2006
2007 /* Build the actual font set name. */
2008 len = strlen (base_fontname) + strlen (font_allcs)
2009 + strlen (font_allfamilies) + strlen (font_all) + 5;
2010 fontsetname = xmalloc (len);
2011 memset (fontsetname, 0, len);
2012 strcpy (fontsetname, base_fontname);
2013 strcat (fontsetname, sep);
2014 strcat (fontsetname, font_allcs);
2015 strcat (fontsetname, sep);
2016 strcat (fontsetname, font_allfamilies);
2017 strcat (fontsetname, sep);
2018 strcat (fontsetname, font_all);
2019 }
2020 }
2021 if (motif)
2022 strcat (fontsetname, ":");
2023 return fontsetname;
2024 }
2025
2026 #ifdef DEBUG_XIC_FONTSET
2027 static void
2028 print_fontset_result (xfs, name, missing_list, missing_count)
2029 XFontSet xfs;
2030 char *name;
2031 char **missing_list;
2032 int missing_count;
2033 {
2034 if (xfs)
2035 fprintf (stderr, "XIC Fontset created: %s\n", name);
2036 else
2037 {
2038 fprintf (stderr, "XIC Fontset failed: %s\n", name);
2039 while (missing_count-- > 0)
2040 {
2041 fprintf (stderr, " missing: %s\n", *missing_list);
2042 missing_list++;
2043 }
2044 }
2045
2046 }
2047 #endif
2048
2049 static XFontSet
2050 xic_create_xfontset (struct frame *f)
2051 {
2052 XFontSet xfs = NULL;
2053 struct font *font = FRAME_FONT (f);
2054 int pixel_size = font->pixel_size;
2055 Lisp_Object rest, frame;
2056
2057 /* See if there is another frame already using same fontset. */
2058 FOR_EACH_FRAME (rest, frame)
2059 {
2060 struct frame *cf = XFRAME (frame);
2061
2062 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2063 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2064 && FRAME_FONT (f)
2065 && FRAME_FONT (f)->pixel_size == pixel_size)
2066 {
2067 xfs = FRAME_XIC_FONTSET (cf);
2068 break;
2069 }
2070 }
2071
2072 if (! xfs)
2073 {
2074 char buf[256];
2075 char **missing_list;
2076 int missing_count;
2077 char *def_string;
2078 char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
2079
2080 sprintf (buf, xlfd_format, pixel_size);
2081 missing_list = NULL;
2082 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2083 &missing_list, &missing_count, &def_string);
2084 #ifdef DEBUG_XIC_FONTSET
2085 print_fontset_result (xfs, buf, missing_list, missing_count);
2086 #endif
2087 if (missing_list)
2088 XFreeStringList (missing_list);
2089 if (! xfs)
2090 {
2091 /* List of pixel sizes most likely available. Find one that
2092 is closest to pixel_size. */
2093 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2094 int *smaller, *larger;
2095
2096 for (smaller = sizes; smaller[1]; smaller++)
2097 if (smaller[1] >= pixel_size)
2098 break;
2099 larger = smaller + 1;
2100 if (*larger == pixel_size)
2101 larger++;
2102 while (*smaller || *larger)
2103 {
2104 int this_size;
2105
2106 if (! *larger)
2107 this_size = *smaller--;
2108 else if (! *smaller)
2109 this_size = *larger++;
2110 else if (pixel_size - *smaller < *larger - pixel_size)
2111 this_size = *smaller--;
2112 else
2113 this_size = *larger++;
2114 sprintf (buf, xlfd_format, this_size);
2115 missing_list = NULL;
2116 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2117 &missing_list, &missing_count, &def_string);
2118 #ifdef DEBUG_XIC_FONTSET
2119 print_fontset_result (xfs, buf, missing_list, missing_count);
2120 #endif
2121 if (missing_list)
2122 XFreeStringList (missing_list);
2123 if (xfs)
2124 break;
2125 }
2126 }
2127 if (! xfs)
2128 {
2129 char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
2130
2131 missing_list = NULL;
2132 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
2133 &missing_list, &missing_count, &def_string);
2134 #ifdef DEBUG_XIC_FONTSET
2135 print_fontset_result (xfs, last_resort, missing_list, missing_count);
2136 #endif
2137 if (missing_list)
2138 XFreeStringList (missing_list);
2139 }
2140
2141 }
2142
2143 return xfs;
2144 }
2145
2146 /* Free the X fontset of frame F if it is the last frame using it. */
2147
2148 void
2149 xic_free_xfontset (struct frame *f)
2150 {
2151 Lisp_Object rest, frame;
2152 int shared_p = 0;
2153
2154 if (!FRAME_XIC_FONTSET (f))
2155 return;
2156
2157 /* See if there is another frame sharing the same fontset. */
2158 FOR_EACH_FRAME (rest, frame)
2159 {
2160 struct frame *cf = XFRAME (frame);
2161 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2162 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2163 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
2164 {
2165 shared_p = 1;
2166 break;
2167 }
2168 }
2169
2170 if (!shared_p)
2171 /* The fontset is not used anymore. It is safe to free it. */
2172 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2173
2174 if (FRAME_XIC_BASE_FONTNAME (f))
2175 xfree (FRAME_XIC_BASE_FONTNAME (f));
2176 FRAME_XIC_BASE_FONTNAME (f) = NULL;
2177 FRAME_XIC_FONTSET (f) = NULL;
2178 }
2179
2180
2181 /* Value is the best input style, given user preferences USER (already
2182 checked to be supported by Emacs), and styles supported by the
2183 input method XIM. */
2184
2185 static XIMStyle
2186 best_xim_style (XIMStyles *user, XIMStyles *xim)
2187 {
2188 int i, j;
2189
2190 for (i = 0; i < user->count_styles; ++i)
2191 for (j = 0; j < xim->count_styles; ++j)
2192 if (user->supported_styles[i] == xim->supported_styles[j])
2193 return user->supported_styles[i];
2194
2195 /* Return the default style. */
2196 return XIMPreeditNothing | XIMStatusNothing;
2197 }
2198
2199 /* Create XIC for frame F. */
2200
2201 static XIMStyle xic_style;
2202
2203 void
2204 create_frame_xic (struct frame *f)
2205 {
2206 XIM xim;
2207 XIC xic = NULL;
2208 XFontSet xfs = NULL;
2209
2210 if (FRAME_XIC (f))
2211 return;
2212
2213 /* Create X fontset. */
2214 xfs = xic_create_xfontset (f);
2215 xim = FRAME_X_XIM (f);
2216 if (xim)
2217 {
2218 XRectangle s_area;
2219 XPoint spot;
2220 XVaNestedList preedit_attr;
2221 XVaNestedList status_attr;
2222
2223 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2224 spot.x = 0; spot.y = 1;
2225
2226 /* Determine XIC style. */
2227 if (xic_style == 0)
2228 {
2229 XIMStyles supported_list;
2230 supported_list.count_styles = (sizeof supported_xim_styles
2231 / sizeof supported_xim_styles[0]);
2232 supported_list.supported_styles = supported_xim_styles;
2233 xic_style = best_xim_style (&supported_list,
2234 FRAME_X_XIM_STYLES (f));
2235 }
2236
2237 preedit_attr = XVaCreateNestedList (0,
2238 XNFontSet, xfs,
2239 XNForeground,
2240 FRAME_FOREGROUND_PIXEL (f),
2241 XNBackground,
2242 FRAME_BACKGROUND_PIXEL (f),
2243 (xic_style & XIMPreeditPosition
2244 ? XNSpotLocation
2245 : NULL),
2246 &spot,
2247 NULL);
2248 status_attr = XVaCreateNestedList (0,
2249 XNArea,
2250 &s_area,
2251 XNFontSet,
2252 xfs,
2253 XNForeground,
2254 FRAME_FOREGROUND_PIXEL (f),
2255 XNBackground,
2256 FRAME_BACKGROUND_PIXEL (f),
2257 NULL);
2258
2259 xic = XCreateIC (xim,
2260 XNInputStyle, xic_style,
2261 XNClientWindow, FRAME_X_WINDOW (f),
2262 XNFocusWindow, FRAME_X_WINDOW (f),
2263 XNStatusAttributes, status_attr,
2264 XNPreeditAttributes, preedit_attr,
2265 NULL);
2266 XFree (preedit_attr);
2267 XFree (status_attr);
2268 }
2269
2270 FRAME_XIC (f) = xic;
2271 FRAME_XIC_STYLE (f) = xic_style;
2272 FRAME_XIC_FONTSET (f) = xfs;
2273 }
2274
2275
2276 /* Destroy XIC and free XIC fontset of frame F, if any. */
2277
2278 void
2279 free_frame_xic (struct frame *f)
2280 {
2281 if (FRAME_XIC (f) == NULL)
2282 return;
2283
2284 XDestroyIC (FRAME_XIC (f));
2285 xic_free_xfontset (f);
2286
2287 FRAME_XIC (f) = NULL;
2288 }
2289
2290
2291 /* Place preedit area for XIC of window W's frame to specified
2292 pixel position X/Y. X and Y are relative to window W. */
2293
2294 void
2295 xic_set_preeditarea (struct window *w, int x, int y)
2296 {
2297 struct frame *f = XFRAME (w->frame);
2298 XVaNestedList attr;
2299 XPoint spot;
2300
2301 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2302 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2303 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2304 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2305 XFree (attr);
2306 }
2307
2308
2309 /* Place status area for XIC in bottom right corner of frame F.. */
2310
2311 void
2312 xic_set_statusarea (struct frame *f)
2313 {
2314 XIC xic = FRAME_XIC (f);
2315 XVaNestedList attr;
2316 XRectangle area;
2317 XRectangle *needed;
2318
2319 /* Negotiate geometry of status area. If input method has existing
2320 status area, use its current size. */
2321 area.x = area.y = area.width = area.height = 0;
2322 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2323 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2324 XFree (attr);
2325
2326 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2327 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2328 XFree (attr);
2329
2330 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2331 {
2332 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2333 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2334 XFree (attr);
2335 }
2336
2337 area.width = needed->width;
2338 area.height = needed->height;
2339 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2340 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2341 - FRAME_MENUBAR_HEIGHT (f)
2342 - FRAME_TOOLBAR_HEIGHT (f)
2343 - FRAME_INTERNAL_BORDER_WIDTH (f));
2344 XFree (needed);
2345
2346 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2347 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2348 XFree (attr);
2349 }
2350
2351
2352 /* Set X fontset for XIC of frame F, using base font name
2353 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2354
2355 void
2356 xic_set_xfontset (struct frame *f, char *base_fontname)
2357 {
2358 XVaNestedList attr;
2359 XFontSet xfs;
2360
2361 xic_free_xfontset (f);
2362
2363 xfs = xic_create_xfontset (f);
2364
2365 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2366 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2367 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2368 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2369 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2370 XFree (attr);
2371
2372 FRAME_XIC_FONTSET (f) = xfs;
2373 }
2374
2375 #endif /* HAVE_X_I18N */
2376
2377
2378 \f
2379 #ifdef USE_X_TOOLKIT
2380
2381 /* Create and set up the X widget for frame F. */
2382
2383 static void
2384 x_window (struct frame *f, long window_prompting, int minibuffer_only)
2385 {
2386 XClassHint class_hints;
2387 XSetWindowAttributes attributes;
2388 unsigned long attribute_mask;
2389 Widget shell_widget;
2390 Widget pane_widget;
2391 Widget frame_widget;
2392 Arg al [25];
2393 int ac;
2394
2395 BLOCK_INPUT;
2396
2397 /* Use the resource name as the top-level widget name
2398 for looking up resources. Make a non-Lisp copy
2399 for the window manager, so GC relocation won't bother it.
2400
2401 Elsewhere we specify the window name for the window manager. */
2402
2403 {
2404 char *str = (char *) SDATA (Vx_resource_name);
2405 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2406 strcpy (f->namebuf, str);
2407 }
2408
2409 ac = 0;
2410 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2411 XtSetArg (al[ac], XtNinput, 1); ac++;
2412 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2413 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2414 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2415 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2416 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2417 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2418 applicationShellWidgetClass,
2419 FRAME_X_DISPLAY (f), al, ac);
2420
2421 f->output_data.x->widget = shell_widget;
2422 /* maybe_set_screen_title_format (shell_widget); */
2423
2424 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2425 (widget_value *) NULL,
2426 shell_widget, False,
2427 (lw_callback) NULL,
2428 (lw_callback) NULL,
2429 (lw_callback) NULL,
2430 (lw_callback) NULL);
2431
2432 ac = 0;
2433 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2434 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2435 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2436 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2437 XtSetValues (pane_widget, al, ac);
2438 f->output_data.x->column_widget = pane_widget;
2439
2440 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2441 the emacs screen when changing menubar. This reduces flickering. */
2442
2443 ac = 0;
2444 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2445 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2446 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2447 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2448 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2449 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2450 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2451 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2452 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2453 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2454 al, ac);
2455
2456 f->output_data.x->edit_widget = frame_widget;
2457
2458 XtManageChild (frame_widget);
2459
2460 /* Do some needed geometry management. */
2461 {
2462 int len;
2463 char *tem, shell_position[32];
2464 Arg al[10];
2465 int ac = 0;
2466 int extra_borders = 0;
2467 int menubar_size
2468 = (f->output_data.x->menubar_widget
2469 ? (f->output_data.x->menubar_widget->core.height
2470 + f->output_data.x->menubar_widget->core.border_width)
2471 : 0);
2472
2473 #if 0 /* Experimentally, we now get the right results
2474 for -geometry -0-0 without this. 24 Aug 96, rms. */
2475 if (FRAME_EXTERNAL_MENU_BAR (f))
2476 {
2477 Dimension ibw = 0;
2478 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2479 menubar_size += ibw;
2480 }
2481 #endif
2482
2483 f->output_data.x->menubar_height = menubar_size;
2484
2485 #ifndef USE_LUCID
2486 /* Motif seems to need this amount added to the sizes
2487 specified for the shell widget. The Athena/Lucid widgets don't.
2488 Both conclusions reached experimentally. -- rms. */
2489 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2490 &extra_borders, NULL);
2491 extra_borders *= 2;
2492 #endif
2493
2494 /* Convert our geometry parameters into a geometry string
2495 and specify it.
2496 Note that we do not specify here whether the position
2497 is a user-specified or program-specified one.
2498 We pass that information later, in x_wm_set_size_hints. */
2499 {
2500 int left = f->left_pos;
2501 int xneg = window_prompting & XNegative;
2502 int top = f->top_pos;
2503 int yneg = window_prompting & YNegative;
2504 if (xneg)
2505 left = -left;
2506 if (yneg)
2507 top = -top;
2508
2509 if (window_prompting & USPosition)
2510 sprintf (shell_position, "=%dx%d%c%d%c%d",
2511 FRAME_PIXEL_WIDTH (f) + extra_borders,
2512 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2513 (xneg ? '-' : '+'), left,
2514 (yneg ? '-' : '+'), top);
2515 else
2516 {
2517 sprintf (shell_position, "=%dx%d",
2518 FRAME_PIXEL_WIDTH (f) + extra_borders,
2519 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2520
2521 /* Setting x and y when the position is not specified in
2522 the geometry string will set program position in the WM hints.
2523 If Emacs had just one program position, we could set it in
2524 fallback resources, but since each make-frame call can specify
2525 different program positions, this is easier. */
2526 XtSetArg (al[ac], XtNx, left); ac++;
2527 XtSetArg (al[ac], XtNy, top); ac++;
2528 }
2529 }
2530
2531 len = strlen (shell_position) + 1;
2532 /* We don't free this because we don't know whether
2533 it is safe to free it while the frame exists.
2534 It isn't worth the trouble of arranging to free it
2535 when the frame is deleted. */
2536 tem = (char *) xmalloc (len);
2537 strncpy (tem, shell_position, len);
2538 XtSetArg (al[ac], XtNgeometry, tem); ac++;
2539 XtSetValues (shell_widget, al, ac);
2540 }
2541
2542 XtManageChild (pane_widget);
2543 XtRealizeWidget (shell_widget);
2544
2545 if (FRAME_X_EMBEDDED_P (f))
2546 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2547 f->output_data.x->parent_desc, 0, 0);
2548
2549 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2550
2551 validate_x_resource_name ();
2552
2553 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2554 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2555 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2556
2557 #ifdef HAVE_X_I18N
2558 FRAME_XIC (f) = NULL;
2559 if (use_xim)
2560 create_frame_xic (f);
2561 #endif
2562
2563 f->output_data.x->wm_hints.input = True;
2564 f->output_data.x->wm_hints.flags |= InputHint;
2565 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2566 &f->output_data.x->wm_hints);
2567
2568 hack_wm_protocols (f, shell_widget);
2569
2570 #ifdef HACK_EDITRES
2571 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2572 #endif
2573
2574 /* Do a stupid property change to force the server to generate a
2575 PropertyNotify event so that the event_stream server timestamp will
2576 be initialized to something relevant to the time we created the window.
2577 */
2578 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2579 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2580 XA_ATOM, 32, PropModeAppend,
2581 (unsigned char*) NULL, 0);
2582
2583 /* Make all the standard events reach the Emacs frame. */
2584 attributes.event_mask = STANDARD_EVENT_SET;
2585
2586 #ifdef HAVE_X_I18N
2587 if (FRAME_XIC (f))
2588 {
2589 /* XIM server might require some X events. */
2590 unsigned long fevent = NoEventMask;
2591 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2592 attributes.event_mask |= fevent;
2593 }
2594 #endif /* HAVE_X_I18N */
2595
2596 attribute_mask = CWEventMask;
2597 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2598 attribute_mask, &attributes);
2599
2600 XtMapWidget (frame_widget);
2601
2602 /* x_set_name normally ignores requests to set the name if the
2603 requested name is the same as the current name. This is the one
2604 place where that assumption isn't correct; f->name is set, but
2605 the X server hasn't been told. */
2606 {
2607 Lisp_Object name;
2608 int explicit = f->explicit_name;
2609
2610 f->explicit_name = 0;
2611 name = f->name;
2612 f->name = Qnil;
2613 x_set_name (f, name, explicit);
2614 }
2615
2616 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2617 f->output_data.x->current_cursor
2618 = f->output_data.x->text_cursor);
2619
2620 UNBLOCK_INPUT;
2621
2622 /* This is a no-op, except under Motif. Make sure main areas are
2623 set to something reasonable, in case we get an error later. */
2624 lw_set_main_areas (pane_widget, 0, frame_widget);
2625 }
2626
2627 #else /* not USE_X_TOOLKIT */
2628 #ifdef USE_GTK
2629 void
2630 x_window (FRAME_PTR f)
2631 {
2632 if (! xg_create_frame_widgets (f))
2633 error ("Unable to create window");
2634
2635 #ifdef HAVE_X_I18N
2636 FRAME_XIC (f) = NULL;
2637 if (use_xim)
2638 {
2639 BLOCK_INPUT;
2640 create_frame_xic (f);
2641 if (FRAME_XIC (f))
2642 {
2643 /* XIM server might require some X events. */
2644 unsigned long fevent = NoEventMask;
2645 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2646
2647 if (fevent != NoEventMask)
2648 {
2649 XSetWindowAttributes attributes;
2650 XWindowAttributes wattr;
2651 unsigned long attribute_mask;
2652
2653 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2654 &wattr);
2655 attributes.event_mask = wattr.your_event_mask | fevent;
2656 attribute_mask = CWEventMask;
2657 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2658 attribute_mask, &attributes);
2659 }
2660 }
2661 UNBLOCK_INPUT;
2662 }
2663 #endif
2664 }
2665
2666 #else /*! USE_GTK */
2667 /* Create and set up the X window for frame F. */
2668
2669 void
2670 x_window (struct frame *f)
2671 {
2672 XClassHint class_hints;
2673 XSetWindowAttributes attributes;
2674 unsigned long attribute_mask;
2675
2676 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2677 attributes.border_pixel = f->output_data.x->border_pixel;
2678 attributes.bit_gravity = StaticGravity;
2679 attributes.backing_store = NotUseful;
2680 attributes.save_under = True;
2681 attributes.event_mask = STANDARD_EVENT_SET;
2682 attributes.colormap = FRAME_X_COLORMAP (f);
2683 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2684 | CWColormap);
2685
2686 BLOCK_INPUT;
2687 FRAME_X_WINDOW (f)
2688 = XCreateWindow (FRAME_X_DISPLAY (f),
2689 f->output_data.x->parent_desc,
2690 f->left_pos,
2691 f->top_pos,
2692 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2693 f->border_width,
2694 CopyFromParent, /* depth */
2695 InputOutput, /* class */
2696 FRAME_X_VISUAL (f),
2697 attribute_mask, &attributes);
2698
2699 #ifdef HAVE_X_I18N
2700 if (use_xim)
2701 {
2702 create_frame_xic (f);
2703 if (FRAME_XIC (f))
2704 {
2705 /* XIM server might require some X events. */
2706 unsigned long fevent = NoEventMask;
2707 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2708 attributes.event_mask |= fevent;
2709 attribute_mask = CWEventMask;
2710 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2711 attribute_mask, &attributes);
2712 }
2713 }
2714 #endif /* HAVE_X_I18N */
2715
2716 validate_x_resource_name ();
2717
2718 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2719 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2720 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2721
2722 /* The menubar is part of the ordinary display;
2723 it does not count in addition to the height of the window. */
2724 f->output_data.x->menubar_height = 0;
2725
2726 /* This indicates that we use the "Passive Input" input model.
2727 Unless we do this, we don't get the Focus{In,Out} events that we
2728 need to draw the cursor correctly. Accursed bureaucrats.
2729 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2730
2731 f->output_data.x->wm_hints.input = True;
2732 f->output_data.x->wm_hints.flags |= InputHint;
2733 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2734 &f->output_data.x->wm_hints);
2735 f->output_data.x->wm_hints.icon_pixmap = None;
2736
2737 /* Request "save yourself" and "delete window" commands from wm. */
2738 {
2739 Atom protocols[2];
2740 protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2741 protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2742 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2743 }
2744
2745 /* x_set_name normally ignores requests to set the name if the
2746 requested name is the same as the current name. This is the one
2747 place where that assumption isn't correct; f->name is set, but
2748 the X server hasn't been told. */
2749 {
2750 Lisp_Object name;
2751 int explicit = f->explicit_name;
2752
2753 f->explicit_name = 0;
2754 name = f->name;
2755 f->name = Qnil;
2756 x_set_name (f, name, explicit);
2757 }
2758
2759 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2760 f->output_data.x->current_cursor
2761 = f->output_data.x->text_cursor);
2762
2763 UNBLOCK_INPUT;
2764
2765 if (FRAME_X_WINDOW (f) == 0)
2766 error ("Unable to create window");
2767 }
2768
2769 #endif /* not USE_GTK */
2770 #endif /* not USE_X_TOOLKIT */
2771
2772 /* Verify that the icon position args for this window are valid. */
2773
2774 static void
2775 x_icon_verify (struct frame *f, Lisp_Object parms)
2776 {
2777 Lisp_Object icon_x, icon_y;
2778
2779 /* Set the position of the icon. Note that twm groups all
2780 icons in an icon window. */
2781 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2782 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2783 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2784 {
2785 CHECK_NUMBER (icon_x);
2786 CHECK_NUMBER (icon_y);
2787 }
2788 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2789 error ("Both left and top icon corners of icon must be specified");
2790 }
2791
2792 /* Handle the icon stuff for this window. Perhaps later we might
2793 want an x_set_icon_position which can be called interactively as
2794 well. */
2795
2796 static void
2797 x_icon (struct frame *f, Lisp_Object parms)
2798 {
2799 Lisp_Object icon_x, icon_y;
2800 #if 0
2801 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2802 #endif
2803
2804 /* Set the position of the icon. Note that twm groups all
2805 icons in an icon window. */
2806 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2807 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2808 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2809 {
2810 CHECK_NUMBER (icon_x);
2811 CHECK_NUMBER (icon_y);
2812 }
2813 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2814 error ("Both left and top icon corners of icon must be specified");
2815
2816 BLOCK_INPUT;
2817
2818 if (! EQ (icon_x, Qunbound))
2819 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2820
2821 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2822 but x_create_frame still needs it. */
2823 /* Start up iconic or window? */
2824 x_wm_set_window_state
2825 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2826 Qicon)
2827 ? IconicState
2828 : NormalState));
2829 #endif
2830
2831 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2832 ? f->icon_name
2833 : f->name)));
2834
2835 UNBLOCK_INPUT;
2836 }
2837
2838 /* Make the GCs needed for this window, setting the
2839 background, border and mouse colors; also create the
2840 mouse cursor and the gray border tile. */
2841
2842 static void
2843 x_make_gc (struct frame *f)
2844 {
2845 XGCValues gc_values;
2846
2847 BLOCK_INPUT;
2848
2849 /* Create the GCs of this frame.
2850 Note that many default values are used. */
2851
2852 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2853 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2854 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2855 f->output_data.x->normal_gc
2856 = XCreateGC (FRAME_X_DISPLAY (f),
2857 FRAME_X_WINDOW (f),
2858 GCLineWidth | GCForeground | GCBackground,
2859 &gc_values);
2860
2861 /* Reverse video style. */
2862 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2863 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2864 f->output_data.x->reverse_gc
2865 = XCreateGC (FRAME_X_DISPLAY (f),
2866 FRAME_X_WINDOW (f),
2867 GCForeground | GCBackground | GCLineWidth,
2868 &gc_values);
2869
2870 /* Cursor has cursor-color background, background-color foreground. */
2871 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2872 gc_values.background = f->output_data.x->cursor_pixel;
2873 gc_values.fill_style = FillOpaqueStippled;
2874 f->output_data.x->cursor_gc
2875 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2876 (GCForeground | GCBackground
2877 | GCFillStyle | GCLineWidth),
2878 &gc_values);
2879
2880 /* Reliefs. */
2881 f->output_data.x->white_relief.gc = 0;
2882 f->output_data.x->black_relief.gc = 0;
2883
2884 /* Create the gray border tile used when the pointer is not in
2885 the frame. Since this depends on the frame's pixel values,
2886 this must be done on a per-frame basis. */
2887 f->output_data.x->border_tile
2888 = (XCreatePixmapFromBitmapData
2889 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2890 gray_bits, gray_width, gray_height,
2891 FRAME_FOREGROUND_PIXEL (f),
2892 FRAME_BACKGROUND_PIXEL (f),
2893 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2894
2895 UNBLOCK_INPUT;
2896 }
2897
2898
2899 /* Free what was allocated in x_make_gc. */
2900
2901 void
2902 x_free_gcs (struct frame *f)
2903 {
2904 Display *dpy = FRAME_X_DISPLAY (f);
2905
2906 BLOCK_INPUT;
2907
2908 if (f->output_data.x->normal_gc)
2909 {
2910 XFreeGC (dpy, f->output_data.x->normal_gc);
2911 f->output_data.x->normal_gc = 0;
2912 }
2913
2914 if (f->output_data.x->reverse_gc)
2915 {
2916 XFreeGC (dpy, f->output_data.x->reverse_gc);
2917 f->output_data.x->reverse_gc = 0;
2918 }
2919
2920 if (f->output_data.x->cursor_gc)
2921 {
2922 XFreeGC (dpy, f->output_data.x->cursor_gc);
2923 f->output_data.x->cursor_gc = 0;
2924 }
2925
2926 if (f->output_data.x->border_tile)
2927 {
2928 XFreePixmap (dpy, f->output_data.x->border_tile);
2929 f->output_data.x->border_tile = 0;
2930 }
2931
2932 UNBLOCK_INPUT;
2933 }
2934
2935
2936 /* Handler for signals raised during x_create_frame and
2937 x_create_top_frame. FRAME is the frame which is partially
2938 constructed. */
2939
2940 static Lisp_Object
2941 unwind_create_frame (Lisp_Object frame)
2942 {
2943 struct frame *f = XFRAME (frame);
2944
2945 /* If frame is already dead, nothing to do. This can happen if the
2946 display is disconnected after the frame has become official, but
2947 before x_create_frame removes the unwind protect. */
2948 if (!FRAME_LIVE_P (f))
2949 return Qnil;
2950
2951 /* If frame is ``official'', nothing to do. */
2952 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
2953 {
2954 #if GLYPH_DEBUG
2955 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2956 #endif
2957
2958 x_free_frame_resources (f);
2959
2960 #if GLYPH_DEBUG
2961 /* Check that reference counts are indeed correct. */
2962 xassert (dpyinfo->reference_count == dpyinfo_refcount);
2963 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
2964 #endif
2965 return Qt;
2966 }
2967
2968 return Qnil;
2969 }
2970
2971
2972 static void
2973 x_default_font_parameter (struct frame *f, Lisp_Object parms)
2974 {
2975 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2976 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
2977 RES_TYPE_STRING);
2978 Lisp_Object font = Qnil;
2979 if (EQ (font_param, Qunbound))
2980 font_param = Qnil;
2981
2982 if (NILP (font_param))
2983 {
2984 /* System font should take precedendce over X resources. We suggest this
2985 regardless of font-use-system-font because .emacs may not have been
2986 read yet. */
2987 const char *system_font = xsettings_get_system_font ();
2988 if (system_font)
2989 {
2990 char *name = xstrdup (system_font);
2991 font = font_open_by_name (f, name);
2992 free (name);
2993 }
2994 }
2995
2996 if (NILP (font))
2997 font = !NILP (font_param) ? font_param
2998 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
2999
3000 if (! FONTP (font) && ! STRINGP (font))
3001 {
3002 char *names[]
3003 = {
3004 #ifdef HAVE_XFT
3005 /* This will find the normal Xft font. */
3006 "monospace-10",
3007 #endif
3008 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3009 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3010 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3011 /* This was formerly the first thing tried, but it finds
3012 too many fonts and takes too long. */
3013 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3014 /* If those didn't work, look for something which will
3015 at least work. */
3016 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3017 "fixed",
3018 NULL };
3019 int i;
3020
3021 for (i = 0; names[i]; i++)
3022 {
3023 font = font_open_by_name (f, names[i]);
3024 if (! NILP (font))
3025 break;
3026 }
3027 if (NILP (font))
3028 error ("No suitable font was found");
3029 }
3030 else if (!NILP (font_param))
3031 {
3032 /* Remember the explicit font parameter, so we can re-apply it after
3033 we've applied the `default' face settings. */
3034 x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
3035 }
3036
3037 /* This call will make X resources override any system font setting. */
3038 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
3039 }
3040
3041
3042 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
3043 0, 1, 0,
3044 doc: /* Send the size hints for frame FRAME to the window manager.
3045 If FRAME is nil, use the selected frame. */)
3046 (Lisp_Object frame)
3047 {
3048 struct frame *f;
3049 if (NILP (frame))
3050 frame = selected_frame;
3051 f = XFRAME (frame);
3052 BLOCK_INPUT;
3053 if (FRAME_X_P (f))
3054 x_wm_set_size_hint (f, 0, 0);
3055 UNBLOCK_INPUT;
3056 return Qnil;
3057 }
3058
3059 static void
3060 set_machine_and_pid_properties (struct frame *f)
3061 {
3062 /* See the above comment "Note: Encoding strategy". */
3063 XTextProperty text;
3064 int bytes, stringp;
3065 int do_free_text_value = 0;
3066 long pid = (long) getpid ();
3067
3068 text.value = x_encode_text (Vsystem_name,
3069 Qcompound_text, 0, &bytes, &stringp,
3070 &do_free_text_value);
3071 text.encoding = (stringp ? XA_STRING
3072 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
3073 text.format = 8;
3074 text.nitems = bytes;
3075 XSetWMClientMachine (FRAME_X_DISPLAY (f),
3076 FRAME_OUTER_WINDOW (f),
3077 &text);
3078 if (do_free_text_value)
3079 xfree (text.value);
3080
3081 XChangeProperty (FRAME_X_DISPLAY (f),
3082 FRAME_OUTER_WINDOW (f),
3083 XInternAtom (FRAME_X_DISPLAY (f),
3084 "_NET_WM_PID",
3085 False),
3086 XA_CARDINAL, 32, PropModeReplace,
3087 (unsigned char *) &pid, 1);
3088 }
3089
3090 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3091 1, 1, 0,
3092 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
3093 Return an Emacs frame object.
3094 PARMS is an alist of frame parameters.
3095 If the parameters specify that the frame should not have a minibuffer,
3096 and do not specify a specific minibuffer window to use,
3097 then `default-minibuffer-frame' must be a frame whose minibuffer can
3098 be shared by the new frame.
3099
3100 This function is an internal primitive--use `make-frame' instead. */)
3101 (Lisp_Object parms)
3102 {
3103 struct frame *f;
3104 Lisp_Object frame, tem;
3105 Lisp_Object name;
3106 int minibuffer_only = 0;
3107 long window_prompting = 0;
3108 int width, height;
3109 int count = SPECPDL_INDEX ();
3110 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3111 Lisp_Object display;
3112 struct x_display_info *dpyinfo = NULL;
3113 Lisp_Object parent;
3114 struct kboard *kb;
3115
3116 parms = Fcopy_alist (parms);
3117
3118 /* Use this general default value to start with
3119 until we know if this frame has a specified name. */
3120 Vx_resource_name = Vinvocation_name;
3121
3122 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
3123 if (EQ (display, Qunbound))
3124 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
3125 if (EQ (display, Qunbound))
3126 display = Qnil;
3127 dpyinfo = check_x_display_info (display);
3128 kb = dpyinfo->terminal->kboard;
3129
3130 if (!dpyinfo->terminal->name)
3131 error ("Terminal is not live, can't create new frames on it");
3132
3133 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
3134 if (!STRINGP (name)
3135 && ! EQ (name, Qunbound)
3136 && ! NILP (name))
3137 error ("Invalid frame name--not a string or nil");
3138
3139 if (STRINGP (name))
3140 Vx_resource_name = name;
3141
3142 /* See if parent window is specified. */
3143 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
3144 if (EQ (parent, Qunbound))
3145 parent = Qnil;
3146 if (! NILP (parent))
3147 CHECK_NUMBER (parent);
3148
3149 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3150 /* No need to protect DISPLAY because that's not used after passing
3151 it to make_frame_without_minibuffer. */
3152 frame = Qnil;
3153 GCPRO4 (parms, parent, name, frame);
3154 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
3155 RES_TYPE_SYMBOL);
3156 if (EQ (tem, Qnone) || NILP (tem))
3157 f = make_frame_without_minibuffer (Qnil, kb, display);
3158 else if (EQ (tem, Qonly))
3159 {
3160 f = make_minibuffer_frame ();
3161 minibuffer_only = 1;
3162 }
3163 else if (WINDOWP (tem))
3164 f = make_frame_without_minibuffer (tem, kb, display);
3165 else
3166 f = make_frame (1);
3167
3168 XSETFRAME (frame, f);
3169
3170 /* Note that X Windows does support scroll bars. */
3171 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3172
3173 f->terminal = dpyinfo->terminal;
3174 f->terminal->reference_count++;
3175
3176 f->output_method = output_x_window;
3177 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
3178 memset (f->output_data.x, 0, sizeof (struct x_output));
3179 f->output_data.x->icon_bitmap = -1;
3180 FRAME_FONTSET (f) = -1;
3181 f->output_data.x->scroll_bar_foreground_pixel = -1;
3182 f->output_data.x->scroll_bar_background_pixel = -1;
3183 #ifdef USE_TOOLKIT_SCROLL_BARS
3184 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
3185 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
3186 #endif /* USE_TOOLKIT_SCROLL_BARS */
3187
3188 f->icon_name
3189 = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3190 RES_TYPE_STRING);
3191 if (! STRINGP (f->icon_name))
3192 f->icon_name = Qnil;
3193
3194 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3195
3196 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3197 record_unwind_protect (unwind_create_frame, frame);
3198 #if GLYPH_DEBUG
3199 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
3200 dpyinfo_refcount = dpyinfo->reference_count;
3201 #endif /* GLYPH_DEBUG */
3202
3203 /* These colors will be set anyway later, but it's important
3204 to get the color reference counts right, so initialize them! */
3205 {
3206 Lisp_Object black;
3207 struct gcpro gcpro1;
3208
3209 /* Function x_decode_color can signal an error. Make
3210 sure to initialize color slots so that we won't try
3211 to free colors we haven't allocated. */
3212 FRAME_FOREGROUND_PIXEL (f) = -1;
3213 FRAME_BACKGROUND_PIXEL (f) = -1;
3214 f->output_data.x->cursor_pixel = -1;
3215 f->output_data.x->cursor_foreground_pixel = -1;
3216 f->output_data.x->border_pixel = -1;
3217 f->output_data.x->mouse_pixel = -1;
3218
3219 black = build_string ("black");
3220 GCPRO1 (black);
3221 FRAME_FOREGROUND_PIXEL (f)
3222 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3223 FRAME_BACKGROUND_PIXEL (f)
3224 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3225 f->output_data.x->cursor_pixel
3226 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3227 f->output_data.x->cursor_foreground_pixel
3228 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3229 f->output_data.x->border_pixel
3230 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3231 f->output_data.x->mouse_pixel
3232 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3233 UNGCPRO;
3234 }
3235
3236 /* Specify the parent under which to make this X window. */
3237
3238 if (!NILP (parent))
3239 {
3240 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3241 f->output_data.x->explicit_parent = 1;
3242 }
3243 else
3244 {
3245 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3246 f->output_data.x->explicit_parent = 0;
3247 }
3248
3249 /* Set the name; the functions to which we pass f expect the name to
3250 be set. */
3251 if (EQ (name, Qunbound) || NILP (name))
3252 {
3253 f->name = build_string (dpyinfo->x_id_name);
3254 f->explicit_name = 0;
3255 }
3256 else
3257 {
3258 f->name = name;
3259 f->explicit_name = 1;
3260 /* use the frame's title when getting resources for this frame. */
3261 specbind (Qx_resource_name, name);
3262 }
3263
3264 f->resx = dpyinfo->resx;
3265 f->resy = dpyinfo->resy;
3266
3267 #ifdef HAVE_FREETYPE
3268 #ifdef HAVE_XFT
3269 register_font_driver (&xftfont_driver, f);
3270 #else /* not HAVE_XFT */
3271 register_font_driver (&ftxfont_driver, f);
3272 #endif /* not HAVE_XFT */
3273 #endif /* HAVE_FREETYPE */
3274 register_font_driver (&xfont_driver, f);
3275
3276 x_default_parameter (f, parms, Qfont_backend, Qnil,
3277 "fontBackend", "FontBackend", RES_TYPE_STRING);
3278
3279 /* Extract the window parameters from the supplied values
3280 that are needed to determine window geometry. */
3281 x_default_font_parameter (f, parms);
3282 if (!FRAME_FONT (f))
3283 {
3284 delete_frame (frame, Qnoelisp);
3285 error ("Invalid frame font");
3286 }
3287
3288 /* Frame contents get displaced if an embedded X window has a border. */
3289 if (! FRAME_X_EMBEDDED_P (f))
3290 x_default_parameter (f, parms, Qborder_width, make_number (0),
3291 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3292
3293 /* This defaults to 1 in order to match xterm. We recognize either
3294 internalBorderWidth or internalBorder (which is what xterm calls
3295 it). */
3296 if (NILP (Fassq (Qinternal_border_width, parms)))
3297 {
3298 Lisp_Object value;
3299
3300 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3301 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3302 if (! EQ (value, Qunbound))
3303 parms = Fcons (Fcons (Qinternal_border_width, value),
3304 parms);
3305 }
3306 x_default_parameter (f, parms, Qinternal_border_width,
3307 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3308 make_number (0),
3309 #else
3310 make_number (1),
3311 #endif
3312 "internalBorderWidth", "internalBorderWidth",
3313 RES_TYPE_NUMBER);
3314 x_default_parameter (f, parms, Qvertical_scroll_bars,
3315 #if defined(USE_GTK) && defined(USE_TOOLKIT_SCROLL_BARS)
3316 Qright,
3317 #else
3318 Qleft,
3319 #endif
3320 "verticalScrollBars", "ScrollBars",
3321 RES_TYPE_SYMBOL);
3322
3323 /* Also do the stuff which must be set before the window exists. */
3324 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3325 "foreground", "Foreground", RES_TYPE_STRING);
3326 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3327 "background", "Background", RES_TYPE_STRING);
3328 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3329 "pointerColor", "Foreground", RES_TYPE_STRING);
3330 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3331 "cursorColor", "Foreground", RES_TYPE_STRING);
3332 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3333 "borderColor", "BorderColor", RES_TYPE_STRING);
3334 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3335 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3336 x_default_parameter (f, parms, Qline_spacing, Qnil,
3337 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3338 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3339 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3340 x_default_parameter (f, parms, Qright_fringe, Qnil,
3341 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3342
3343 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3344 "scrollBarForeground",
3345 "ScrollBarForeground", 1);
3346 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3347 "scrollBarBackground",
3348 "ScrollBarBackground", 0);
3349
3350 /* Init faces before x_default_parameter is called for scroll-bar
3351 parameters because that function calls x_set_scroll_bar_width,
3352 which calls change_frame_size, which calls Fset_window_buffer,
3353 which runs hooks, which call Fvertical_motion. At the end, we
3354 end up in init_iterator with a null face cache, which should not
3355 happen. */
3356 init_frame_faces (f);
3357
3358 /* The X resources controlling the menu-bar and tool-bar are
3359 processed specially at startup, and reflected in the mode
3360 variables; ignore them here. */
3361 x_default_parameter (f, parms, Qmenu_bar_lines,
3362 NILP (Vmenu_bar_mode)
3363 ? make_number (0) : make_number (1),
3364 NULL, NULL, RES_TYPE_NUMBER);
3365 x_default_parameter (f, parms, Qtool_bar_lines,
3366 NILP (Vtool_bar_mode)
3367 ? make_number (0) : make_number (1),
3368 NULL, NULL, RES_TYPE_NUMBER);
3369
3370 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3371 "bufferPredicate", "BufferPredicate",
3372 RES_TYPE_SYMBOL);
3373 x_default_parameter (f, parms, Qtitle, Qnil,
3374 "title", "Title", RES_TYPE_STRING);
3375 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3376 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3377 x_default_parameter (f, parms, Qfullscreen, Qnil,
3378 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3379
3380 /* Compute the size of the X window. */
3381 window_prompting = x_figure_window_size (f, parms, 1);
3382
3383 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3384 f->no_split = minibuffer_only || EQ (tem, Qt);
3385
3386 x_icon_verify (f, parms);
3387
3388 /* Create the X widget or window. */
3389 #ifdef USE_X_TOOLKIT
3390 x_window (f, window_prompting, minibuffer_only);
3391 #else
3392 x_window (f);
3393 #endif
3394
3395 x_icon (f, parms);
3396 x_make_gc (f);
3397
3398 /* Now consider the frame official. */
3399 FRAME_X_DISPLAY_INFO (f)->reference_count++;
3400 Vframe_list = Fcons (frame, Vframe_list);
3401
3402 /* We need to do this after creating the X window, so that the
3403 icon-creation functions can say whose icon they're describing. */
3404 x_default_parameter (f, parms, Qicon_type, Qt,
3405 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
3406
3407 x_default_parameter (f, parms, Qauto_raise, Qnil,
3408 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3409 x_default_parameter (f, parms, Qauto_lower, Qnil,
3410 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3411 x_default_parameter (f, parms, Qcursor_type, Qbox,
3412 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3413 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3414 "scrollBarWidth", "ScrollBarWidth",
3415 RES_TYPE_NUMBER);
3416 x_default_parameter (f, parms, Qalpha, Qnil,
3417 "alpha", "Alpha", RES_TYPE_NUMBER);
3418
3419 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3420 Change will not be effected unless different from the current
3421 FRAME_LINES (f). */
3422 width = FRAME_COLS (f);
3423 height = FRAME_LINES (f);
3424
3425 SET_FRAME_COLS (f, 0);
3426 FRAME_LINES (f) = 0;
3427 change_frame_size (f, height, width, 1, 0, 0);
3428
3429 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3430 /* Create the menu bar. */
3431 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3432 {
3433 /* If this signals an error, we haven't set size hints for the
3434 frame and we didn't make it visible. */
3435 initialize_frame_menubar (f);
3436
3437 #ifndef USE_GTK
3438 /* This is a no-op, except under Motif where it arranges the
3439 main window for the widgets on it. */
3440 lw_set_main_areas (f->output_data.x->column_widget,
3441 f->output_data.x->menubar_widget,
3442 f->output_data.x->edit_widget);
3443 #endif /* not USE_GTK */
3444 }
3445 #endif /* USE_X_TOOLKIT || USE_GTK */
3446
3447 /* Tell the server what size and position, etc, we want, and how
3448 badly we want them. This should be done after we have the menu
3449 bar so that its size can be taken into account. */
3450 BLOCK_INPUT;
3451 x_wm_set_size_hint (f, window_prompting, 0);
3452 UNBLOCK_INPUT;
3453
3454 /* Make the window appear on the frame and enable display, unless
3455 the caller says not to. However, with explicit parent, Emacs
3456 cannot control visibility, so don't try. */
3457 if (! f->output_data.x->explicit_parent)
3458 {
3459 Lisp_Object visibility;
3460
3461 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3462 RES_TYPE_SYMBOL);
3463 if (EQ (visibility, Qunbound))
3464 visibility = Qt;
3465
3466 if (EQ (visibility, Qicon))
3467 x_iconify_frame (f);
3468 else if (! NILP (visibility))
3469 x_make_frame_visible (f);
3470 else
3471 /* Must have been Qnil. */
3472 ;
3473 }
3474
3475 BLOCK_INPUT;
3476
3477 /* Set machine name and pid for the purpose of window managers. */
3478 set_machine_and_pid_properties(f);
3479
3480 /* Set the WM leader property. GTK does this itself, so this is not
3481 needed when using GTK. */
3482 if (dpyinfo->client_leader_window != 0)
3483 {
3484 XChangeProperty (FRAME_X_DISPLAY (f),
3485 FRAME_OUTER_WINDOW (f),
3486 dpyinfo->Xatom_wm_client_leader,
3487 XA_WINDOW, 32, PropModeReplace,
3488 (unsigned char *) &dpyinfo->client_leader_window, 1);
3489 }
3490
3491 UNBLOCK_INPUT;
3492
3493 /* Initialize `default-minibuffer-frame' in case this is the first
3494 frame on this terminal. */
3495 if (FRAME_HAS_MINIBUF_P (f)
3496 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
3497 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
3498 kb->Vdefault_minibuffer_frame = frame;
3499
3500 /* All remaining specified parameters, which have not been "used"
3501 by x_get_arg and friends, now go in the misc. alist of the frame. */
3502 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3503 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3504 f->param_alist = Fcons (XCAR (tem), f->param_alist);
3505
3506 UNGCPRO;
3507
3508 /* Make sure windows on this frame appear in calls to next-window
3509 and similar functions. */
3510 Vwindow_list = Qnil;
3511
3512 return unbind_to (count, frame);
3513 }
3514
3515
3516 /* FRAME is used only to get a handle on the X display. We don't pass the
3517 display info directly because we're called from frame.c, which doesn't
3518 know about that structure. */
3519
3520 Lisp_Object
3521 x_get_focus_frame (struct frame *frame)
3522 {
3523 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3524 Lisp_Object xfocus;
3525 if (! dpyinfo->x_focus_frame)
3526 return Qnil;
3527
3528 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3529 return xfocus;
3530 }
3531
3532
3533 /* In certain situations, when the window manager follows a
3534 click-to-focus policy, there seems to be no way around calling
3535 XSetInputFocus to give another frame the input focus .
3536
3537 In an ideal world, XSetInputFocus should generally be avoided so
3538 that applications don't interfere with the window manager's focus
3539 policy. But I think it's okay to use when it's clearly done
3540 following a user-command. */
3541
3542 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3543 doc: /* Set the input focus to FRAME.
3544 FRAME nil means use the selected frame. */)
3545 (Lisp_Object frame)
3546 {
3547 struct frame *f = check_x_frame (frame);
3548 Display *dpy = FRAME_X_DISPLAY (f);
3549
3550 BLOCK_INPUT;
3551 x_catch_errors (dpy);
3552 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3553 RevertToParent, CurrentTime);
3554 x_ewmh_activate_frame (f);
3555 x_uncatch_errors ();
3556 UNBLOCK_INPUT;
3557
3558 return Qnil;
3559 }
3560
3561 \f
3562 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3563 doc: /* Internal function called by `color-defined-p', which see. */)
3564 (Lisp_Object color, Lisp_Object frame)
3565 {
3566 XColor foo;
3567 FRAME_PTR f = check_x_frame (frame);
3568
3569 CHECK_STRING (color);
3570
3571 if (x_defined_color (f, SDATA (color), &foo, 0))
3572 return Qt;
3573 else
3574 return Qnil;
3575 }
3576
3577 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3578 doc: /* Internal function called by `color-values', which see. */)
3579 (Lisp_Object color, Lisp_Object frame)
3580 {
3581 XColor foo;
3582 FRAME_PTR f = check_x_frame (frame);
3583
3584 CHECK_STRING (color);
3585
3586 if (x_defined_color (f, SDATA (color), &foo, 0))
3587 return list3 (make_number (foo.red),
3588 make_number (foo.green),
3589 make_number (foo.blue));
3590 else
3591 return Qnil;
3592 }
3593
3594 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3595 doc: /* Internal function called by `display-color-p', which see. */)
3596 (Lisp_Object terminal)
3597 {
3598 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3599
3600 if (dpyinfo->n_planes <= 2)
3601 return Qnil;
3602
3603 switch (dpyinfo->visual->class)
3604 {
3605 case StaticColor:
3606 case PseudoColor:
3607 case TrueColor:
3608 case DirectColor:
3609 return Qt;
3610
3611 default:
3612 return Qnil;
3613 }
3614 }
3615
3616 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3617 0, 1, 0,
3618 doc: /* Return t if the X display supports shades of gray.
3619 Note that color displays do support shades of gray.
3620 The optional argument TERMINAL specifies which display to ask about.
3621 TERMINAL should be a terminal object, a frame or a display name (a string).
3622 If omitted or nil, that stands for the selected frame's display. */)
3623 (Lisp_Object terminal)
3624 {
3625 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3626
3627 if (dpyinfo->n_planes <= 1)
3628 return Qnil;
3629
3630 switch (dpyinfo->visual->class)
3631 {
3632 case StaticColor:
3633 case PseudoColor:
3634 case TrueColor:
3635 case DirectColor:
3636 case StaticGray:
3637 case GrayScale:
3638 return Qt;
3639
3640 default:
3641 return Qnil;
3642 }
3643 }
3644
3645 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3646 0, 1, 0,
3647 doc: /* Return the width in pixels of the X display TERMINAL.
3648 The optional argument TERMINAL specifies which display to ask about.
3649 TERMINAL should be a terminal object, a frame or a display name (a string).
3650 If omitted or nil, that stands for the selected frame's display. */)
3651 (Lisp_Object terminal)
3652 {
3653 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3654
3655 return make_number (x_display_pixel_width (dpyinfo));
3656 }
3657
3658 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3659 Sx_display_pixel_height, 0, 1, 0,
3660 doc: /* Return the height in pixels of the X display TERMINAL.
3661 The optional argument TERMINAL specifies which display to ask about.
3662 TERMINAL should be a terminal object, a frame or a display name (a string).
3663 If omitted or nil, that stands for the selected frame's display. */)
3664 (Lisp_Object terminal)
3665 {
3666 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3667
3668 return make_number (x_display_pixel_height (dpyinfo));
3669 }
3670
3671 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3672 0, 1, 0,
3673 doc: /* Return the number of bitplanes of the X display TERMINAL.
3674 The optional argument TERMINAL specifies which display to ask about.
3675 TERMINAL should be a terminal object, a frame or a display name (a string).
3676 If omitted or nil, that stands for the selected frame's display. */)
3677 (Lisp_Object terminal)
3678 {
3679 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3680
3681 return make_number (dpyinfo->n_planes);
3682 }
3683
3684 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3685 0, 1, 0,
3686 doc: /* Return the number of color cells of the X display TERMINAL.
3687 The optional argument TERMINAL specifies which display to ask about.
3688 TERMINAL should be a terminal object, a frame or a display name (a string).
3689 If omitted or nil, that stands for the selected frame's display. */)
3690 (Lisp_Object terminal)
3691 {
3692 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3693
3694 int nr_planes = DisplayPlanes (dpyinfo->display,
3695 XScreenNumberOfScreen (dpyinfo->screen));
3696
3697 /* Truncate nr_planes to 24 to avoid integer overflow.
3698 Some displays says 32, but only 24 bits are actually significant.
3699 There are only very few and rare video cards that have more than
3700 24 significant bits. Also 24 bits is more than 16 million colors,
3701 it "should be enough for everyone". */
3702 if (nr_planes > 24) nr_planes = 24;
3703
3704 return make_number (1 << nr_planes);
3705 }
3706
3707 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3708 Sx_server_max_request_size,
3709 0, 1, 0,
3710 doc: /* Return the maximum request size of the X server of display TERMINAL.
3711 The optional argument TERMINAL specifies which display to ask about.
3712 TERMINAL should be a terminal object, a frame or a display name (a string).
3713 If omitted or nil, that stands for the selected frame's display. */)
3714 (Lisp_Object terminal)
3715 {
3716 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3717
3718 return make_number (MAXREQUEST (dpyinfo->display));
3719 }
3720
3721 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3722 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3723 \(Labelling every distributor as a "vendor" embodies the false assumption
3724 that operating systems cannot be developed and distributed noncommercially.)
3725 The optional argument TERMINAL specifies which display to ask about.
3726 TERMINAL should be a terminal object, a frame or a display name (a string).
3727 If omitted or nil, that stands for the selected frame's display. */)
3728 (Lisp_Object terminal)
3729 {
3730 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3731 char *vendor = ServerVendor (dpyinfo->display);
3732
3733 if (! vendor) vendor = "";
3734 return build_string (vendor);
3735 }
3736
3737 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3738 doc: /* Return the version numbers of the X server of display TERMINAL.
3739 The value is a list of three integers: the major and minor
3740 version numbers of the X Protocol in use, and the distributor-specific release
3741 number. See also the function `x-server-vendor'.
3742
3743 The optional argument TERMINAL specifies which display to ask about.
3744 TERMINAL should be a terminal object, a frame or a display name (a string).
3745 If omitted or nil, that stands for the selected frame's display. */)
3746 (Lisp_Object terminal)
3747 {
3748 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3749 Display *dpy = dpyinfo->display;
3750
3751 return Fcons (make_number (ProtocolVersion (dpy)),
3752 Fcons (make_number (ProtocolRevision (dpy)),
3753 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3754 }
3755
3756 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3757 doc: /* Return the number of screens on the X server of display TERMINAL.
3758 The optional argument TERMINAL specifies which display to ask about.
3759 TERMINAL should be a terminal object, a frame or a display name (a string).
3760 If omitted or nil, that stands for the selected frame's display. */)
3761 (Lisp_Object terminal)
3762 {
3763 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3764
3765 return make_number (ScreenCount (dpyinfo->display));
3766 }
3767
3768 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3769 doc: /* Return the height in millimeters of the X display TERMINAL.
3770 The optional argument TERMINAL specifies which display to ask about.
3771 TERMINAL should be a terminal object, a frame or a display name (a string).
3772 If omitted or nil, that stands for the selected frame's display. */)
3773 (Lisp_Object terminal)
3774 {
3775 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3776
3777 return make_number (HeightMMOfScreen (dpyinfo->screen));
3778 }
3779
3780 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3781 doc: /* Return the width in millimeters of the X display TERMINAL.
3782 The optional argument TERMINAL specifies which display to ask about.
3783 TERMINAL should be a terminal object, a frame or a display name (a string).
3784 If omitted or nil, that stands for the selected frame's display. */)
3785 (Lisp_Object terminal)
3786 {
3787 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3788
3789 return make_number (WidthMMOfScreen (dpyinfo->screen));
3790 }
3791
3792 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3793 Sx_display_backing_store, 0, 1, 0,
3794 doc: /* Return an indication of whether X display TERMINAL does backing store.
3795 The value may be `always', `when-mapped', or `not-useful'.
3796 The optional argument TERMINAL specifies which display to ask about.
3797 TERMINAL should be a terminal object, a frame or a display name (a string).
3798 If omitted or nil, that stands for the selected frame's display. */)
3799 (Lisp_Object terminal)
3800 {
3801 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3802 Lisp_Object result;
3803
3804 switch (DoesBackingStore (dpyinfo->screen))
3805 {
3806 case Always:
3807 result = intern ("always");
3808 break;
3809
3810 case WhenMapped:
3811 result = intern ("when-mapped");
3812 break;
3813
3814 case NotUseful:
3815 result = intern ("not-useful");
3816 break;
3817
3818 default:
3819 error ("Strange value for BackingStore parameter of screen");
3820 result = Qnil;
3821 }
3822
3823 return result;
3824 }
3825
3826 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3827 Sx_display_visual_class, 0, 1, 0,
3828 doc: /* Return the visual class of the X display TERMINAL.
3829 The value is one of the symbols `static-gray', `gray-scale',
3830 `static-color', `pseudo-color', `true-color', or `direct-color'.
3831
3832 The optional argument TERMINAL specifies which display to ask about.
3833 TERMINAL should 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 (Lisp_Object terminal)
3836 {
3837 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3838 Lisp_Object result;
3839
3840 switch (dpyinfo->visual->class)
3841 {
3842 case StaticGray:
3843 result = intern ("static-gray");
3844 break;
3845 case GrayScale:
3846 result = intern ("gray-scale");
3847 break;
3848 case StaticColor:
3849 result = intern ("static-color");
3850 break;
3851 case PseudoColor:
3852 result = intern ("pseudo-color");
3853 break;
3854 case TrueColor:
3855 result = intern ("true-color");
3856 break;
3857 case DirectColor:
3858 result = intern ("direct-color");
3859 break;
3860 default:
3861 error ("Display has an unknown visual class");
3862 result = Qnil;
3863 }
3864
3865 return result;
3866 }
3867
3868 DEFUN ("x-display-save-under", Fx_display_save_under,
3869 Sx_display_save_under, 0, 1, 0,
3870 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3871 The optional argument TERMINAL specifies which display to ask about.
3872 TERMINAL should be a terminal object, a frame or a display name (a string).
3873 If omitted or nil, that stands for the selected frame's display. */)
3874 (Lisp_Object terminal)
3875 {
3876 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3877
3878 if (DoesSaveUnders (dpyinfo->screen) == True)
3879 return Qt;
3880 else
3881 return Qnil;
3882 }
3883 \f
3884 int
3885 x_pixel_width (register struct frame *f)
3886 {
3887 return FRAME_PIXEL_WIDTH (f);
3888 }
3889
3890 int
3891 x_pixel_height (register struct frame *f)
3892 {
3893 return FRAME_PIXEL_HEIGHT (f);
3894 }
3895
3896 int
3897 x_char_width (register struct frame *f)
3898 {
3899 return FRAME_COLUMN_WIDTH (f);
3900 }
3901
3902 int
3903 x_char_height (register struct frame *f)
3904 {
3905 return FRAME_LINE_HEIGHT (f);
3906 }
3907
3908 int
3909 x_screen_planes (register struct frame *f)
3910 {
3911 return FRAME_X_DISPLAY_INFO (f)->n_planes;
3912 }
3913
3914
3915 \f
3916 /************************************************************************
3917 X Displays
3918 ************************************************************************/
3919
3920 \f
3921 /* Mapping visual names to visuals. */
3922
3923 static struct visual_class
3924 {
3925 char *name;
3926 int class;
3927 }
3928 visual_classes[] =
3929 {
3930 {"StaticGray", StaticGray},
3931 {"GrayScale", GrayScale},
3932 {"StaticColor", StaticColor},
3933 {"PseudoColor", PseudoColor},
3934 {"TrueColor", TrueColor},
3935 {"DirectColor", DirectColor},
3936 {NULL, 0}
3937 };
3938
3939
3940 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3941
3942 /* Value is the screen number of screen SCR. This is a substitute for
3943 the X function with the same name when that doesn't exist. */
3944
3945 int
3946 XScreenNumberOfScreen (scr)
3947 register Screen *scr;
3948 {
3949 Display *dpy = scr->display;
3950 int i;
3951
3952 for (i = 0; i < dpy->nscreens; ++i)
3953 if (scr == dpy->screens + i)
3954 break;
3955
3956 return i;
3957 }
3958
3959 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3960
3961
3962 /* Select the visual that should be used on display DPYINFO. Set
3963 members of DPYINFO appropriately. Called from x_term_init. */
3964
3965 void
3966 select_visual (struct x_display_info *dpyinfo)
3967 {
3968 Display *dpy = dpyinfo->display;
3969 Screen *screen = dpyinfo->screen;
3970 Lisp_Object value;
3971
3972 /* See if a visual is specified. */
3973 value = display_x_get_resource (dpyinfo,
3974 build_string ("visualClass"),
3975 build_string ("VisualClass"),
3976 Qnil, Qnil);
3977 if (STRINGP (value))
3978 {
3979 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
3980 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
3981 depth, a decimal number. NAME is compared with case ignored. */
3982 char *s = (char *) alloca (SBYTES (value) + 1);
3983 char *dash;
3984 int i, class = -1;
3985 XVisualInfo vinfo;
3986
3987 strcpy (s, SDATA (value));
3988 dash = strchr (s, '-');
3989 if (dash)
3990 {
3991 dpyinfo->n_planes = atoi (dash + 1);
3992 *dash = '\0';
3993 }
3994 else
3995 /* We won't find a matching visual with depth 0, so that
3996 an error will be printed below. */
3997 dpyinfo->n_planes = 0;
3998
3999 /* Determine the visual class. */
4000 for (i = 0; visual_classes[i].name; ++i)
4001 if (xstrcasecmp (s, visual_classes[i].name) == 0)
4002 {
4003 class = visual_classes[i].class;
4004 break;
4005 }
4006
4007 /* Look up a matching visual for the specified class. */
4008 if (class == -1
4009 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4010 dpyinfo->n_planes, class, &vinfo))
4011 fatal ("Invalid visual specification `%s'", SDATA (value));
4012
4013 dpyinfo->visual = vinfo.visual;
4014 }
4015 else
4016 {
4017 int n_visuals;
4018 XVisualInfo *vinfo, vinfo_template;
4019
4020 dpyinfo->visual = DefaultVisualOfScreen (screen);
4021
4022 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4023 vinfo_template.screen = XScreenNumberOfScreen (screen);
4024 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4025 &vinfo_template, &n_visuals);
4026 if (n_visuals <= 0)
4027 fatal ("Can't get proper X visual info");
4028
4029 dpyinfo->n_planes = vinfo->depth;
4030 XFree ((char *) vinfo);
4031 }
4032 }
4033
4034
4035 /* Return the X display structure for the display named NAME.
4036 Open a new connection if necessary. */
4037
4038 struct x_display_info *
4039 x_display_info_for_name (Lisp_Object name)
4040 {
4041 Lisp_Object names;
4042 struct x_display_info *dpyinfo;
4043
4044 CHECK_STRING (name);
4045
4046 #if 0
4047 if (! EQ (Vinitial_window_system, intern ("x")))
4048 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4049 #endif
4050
4051 for (dpyinfo = x_display_list, names = x_display_name_list;
4052 dpyinfo;
4053 dpyinfo = dpyinfo->next, names = XCDR (names))
4054 {
4055 Lisp_Object tem;
4056 tem = Fstring_equal (XCAR (XCAR (names)), name);
4057 if (!NILP (tem))
4058 return dpyinfo;
4059 }
4060
4061 /* Use this general default value to start with. */
4062 Vx_resource_name = Vinvocation_name;
4063
4064 validate_x_resource_name ();
4065
4066 dpyinfo = x_term_init (name, (char *)0,
4067 (char *) SDATA (Vx_resource_name));
4068
4069 if (dpyinfo == 0)
4070 error ("Cannot connect to X server %s", SDATA (name));
4071
4072 x_in_use = 1;
4073 XSETFASTINT (Vwindow_system_version, 11);
4074
4075 return dpyinfo;
4076 }
4077
4078
4079 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4080 1, 3, 0,
4081 doc: /* Open a connection to an X server.
4082 DISPLAY is the name of the display to connect to.
4083 Optional second arg XRM-STRING is a string of resources in xrdb format.
4084 If the optional third arg MUST-SUCCEED is non-nil,
4085 terminate Emacs if we can't open the connection. */)
4086 (Lisp_Object display, Lisp_Object xrm_string, Lisp_Object must_succeed)
4087 {
4088 unsigned char *xrm_option;
4089 struct x_display_info *dpyinfo;
4090
4091 CHECK_STRING (display);
4092 if (! NILP (xrm_string))
4093 CHECK_STRING (xrm_string);
4094
4095 #if 0
4096 if (! EQ (Vinitial_window_system, intern ("x")))
4097 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4098 #endif
4099
4100 if (! NILP (xrm_string))
4101 xrm_option = (unsigned char *) SDATA (xrm_string);
4102 else
4103 xrm_option = (unsigned char *) 0;
4104
4105 validate_x_resource_name ();
4106
4107 /* This is what opens the connection and sets x_current_display.
4108 This also initializes many symbols, such as those used for input. */
4109 dpyinfo = x_term_init (display, xrm_option,
4110 (char *) SDATA (Vx_resource_name));
4111
4112 if (dpyinfo == 0)
4113 {
4114 if (!NILP (must_succeed))
4115 fatal ("Cannot connect to X server %s.\n\
4116 Check the DISPLAY environment variable or use `-d'.\n\
4117 Also use the `xauth' program to verify that you have the proper\n\
4118 authorization information needed to connect the X server.\n\
4119 An insecure way to solve the problem may be to use `xhost'.\n",
4120 SDATA (display));
4121 else
4122 error ("Cannot connect to X server %s", SDATA (display));
4123 }
4124
4125 x_in_use = 1;
4126
4127 XSETFASTINT (Vwindow_system_version, 11);
4128 return Qnil;
4129 }
4130
4131 DEFUN ("x-close-connection", Fx_close_connection,
4132 Sx_close_connection, 1, 1, 0,
4133 doc: /* Close the connection to TERMINAL's X server.
4134 For TERMINAL, specify a terminal object, a frame or a display name (a
4135 string). If TERMINAL is nil, that stands for the selected frame's
4136 terminal. */)
4137 (Lisp_Object terminal)
4138 {
4139 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4140
4141 if (dpyinfo->reference_count > 0)
4142 error ("Display still has frames on it");
4143
4144 x_delete_terminal (dpyinfo->terminal);
4145
4146 return Qnil;
4147 }
4148
4149 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4150 doc: /* Return the list of display names that Emacs has connections to. */)
4151 (void)
4152 {
4153 Lisp_Object tail, result;
4154
4155 result = Qnil;
4156 for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
4157 result = Fcons (XCAR (XCAR (tail)), result);
4158
4159 return result;
4160 }
4161
4162 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4163 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4164 If ON is nil, allow buffering of requests.
4165 Turning on synchronization prohibits the Xlib routines from buffering
4166 requests and seriously degrades performance, but makes debugging much
4167 easier.
4168 The optional second argument TERMINAL specifies which display to act on.
4169 TERMINAL should be a terminal object, a frame or a display name (a string).
4170 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4171 (Lisp_Object on, Lisp_Object terminal)
4172 {
4173 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4174
4175 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4176
4177 return Qnil;
4178 }
4179
4180 /* Wait for responses to all X commands issued so far for frame F. */
4181
4182 void
4183 x_sync (FRAME_PTR f)
4184 {
4185 BLOCK_INPUT;
4186 XSync (FRAME_X_DISPLAY (f), False);
4187 UNBLOCK_INPUT;
4188 }
4189
4190 \f
4191 /***********************************************************************
4192 Window properties
4193 ***********************************************************************/
4194
4195 DEFUN ("x-change-window-property", Fx_change_window_property,
4196 Sx_change_window_property, 2, 6, 0,
4197 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4198 PROP must be a string.
4199 VALUE may be a string or a list of conses, numbers and/or strings.
4200 If an element in the list is a string, it is converted to
4201 an Atom and the value of the Atom is used. If an element is a cons,
4202 it is converted to a 32 bit number where the car is the 16 top bits and the
4203 cdr is the lower 16 bits.
4204 FRAME nil or omitted means use the selected frame.
4205 If TYPE is given and non-nil, it is the name of the type of VALUE.
4206 If TYPE is not given or nil, the type is STRING.
4207 FORMAT gives the size in bits of each element if VALUE is a list.
4208 It must be one of 8, 16 or 32.
4209 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4210 If OUTER_P is non-nil, the property is changed for the outer X window of
4211 FRAME. Default is to change on the edit X window.
4212
4213 Value is VALUE. */)
4214 (Lisp_Object prop, Lisp_Object value, Lisp_Object frame, Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
4215 {
4216 struct frame *f = check_x_frame (frame);
4217 Atom prop_atom;
4218 Atom target_type = XA_STRING;
4219 int element_format = 8;
4220 unsigned char *data;
4221 int nelements;
4222 Window w;
4223
4224 CHECK_STRING (prop);
4225
4226 if (! NILP (format))
4227 {
4228 CHECK_NUMBER (format);
4229 element_format = XFASTINT (format);
4230
4231 if (element_format != 8 && element_format != 16
4232 && element_format != 32)
4233 error ("FORMAT must be one of 8, 16 or 32");
4234 }
4235
4236 if (CONSP (value))
4237 {
4238 nelements = x_check_property_data (value);
4239 if (nelements == -1)
4240 error ("Bad data in VALUE, must be number, string or cons");
4241
4242 if (element_format == 8)
4243 data = (unsigned char *) xmalloc (nelements);
4244 else if (element_format == 16)
4245 data = (unsigned char *) xmalloc (nelements*2);
4246 else /* format == 32 */
4247 /* The man page for XChangeProperty:
4248 "If the specified format is 32, the property data must be a
4249 long array."
4250 This applies even if long is more than 64 bits. The X library
4251 converts to 32 bits before sending to the X server. */
4252 data = (unsigned char *) xmalloc (nelements * sizeof(long));
4253
4254 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4255 }
4256 else
4257 {
4258 CHECK_STRING (value);
4259 data = SDATA (value);
4260 nelements = SCHARS (value);
4261 }
4262
4263 BLOCK_INPUT;
4264 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4265 if (! NILP (type))
4266 {
4267 CHECK_STRING (type);
4268 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4269 }
4270
4271 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4272 else w = FRAME_X_WINDOW (f);
4273
4274 XChangeProperty (FRAME_X_DISPLAY (f), w,
4275 prop_atom, target_type, element_format, PropModeReplace,
4276 data, nelements);
4277
4278 if (CONSP (value)) xfree (data);
4279
4280 /* Make sure the property is set when we return. */
4281 XFlush (FRAME_X_DISPLAY (f));
4282 UNBLOCK_INPUT;
4283
4284 return value;
4285 }
4286
4287
4288 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4289 Sx_delete_window_property, 1, 2, 0,
4290 doc: /* Remove window property PROP from X window of FRAME.
4291 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4292 (Lisp_Object prop, Lisp_Object frame)
4293 {
4294 struct frame *f = check_x_frame (frame);
4295 Atom prop_atom;
4296
4297 CHECK_STRING (prop);
4298 BLOCK_INPUT;
4299 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4300 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4301
4302 /* Make sure the property is removed when we return. */
4303 XFlush (FRAME_X_DISPLAY (f));
4304 UNBLOCK_INPUT;
4305
4306 return prop;
4307 }
4308
4309
4310 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4311 1, 6, 0,
4312 doc: /* Value is the value of window property PROP on FRAME.
4313 If FRAME is nil or omitted, use the selected frame.
4314 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4315 is the name of the Atom that denotes the type expected.
4316 If SOURCE is non-nil, get the property on that window instead of from
4317 FRAME. The number 0 denotes the root window.
4318 If DELETE_P is non-nil, delete the property after retreiving it.
4319 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4320
4321 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4322 no value of TYPE. */)
4323 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type, Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
4324 {
4325 struct frame *f = check_x_frame (frame);
4326 Atom prop_atom;
4327 int rc;
4328 Lisp_Object prop_value = Qnil;
4329 unsigned char *tmp_data = NULL;
4330 Atom actual_type;
4331 Atom target_type = XA_STRING;
4332 int actual_format;
4333 unsigned long actual_size, bytes_remaining;
4334 Window target_window = FRAME_X_WINDOW (f);
4335 struct gcpro gcpro1;
4336
4337 GCPRO1 (prop_value);
4338 CHECK_STRING (prop);
4339
4340 if (! NILP (source))
4341 {
4342 if (NUMBERP (source))
4343 {
4344 if (FLOATP (source))
4345 target_window = (Window) XFLOAT (source);
4346 else
4347 target_window = XFASTINT (source);
4348
4349 if (target_window == 0)
4350 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4351 }
4352 else if (CONSP (source))
4353 target_window = cons_to_long (source);
4354 }
4355
4356 BLOCK_INPUT;
4357 if (STRINGP (type))
4358 {
4359 if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
4360 target_type = AnyPropertyType;
4361 else
4362 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4363 }
4364
4365 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4366 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4367 prop_atom, 0, 0, False, target_type,
4368 &actual_type, &actual_format, &actual_size,
4369 &bytes_remaining, &tmp_data);
4370 if (rc == Success)
4371 {
4372 int size = bytes_remaining;
4373
4374 XFree (tmp_data);
4375 tmp_data = NULL;
4376
4377 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4378 prop_atom, 0, bytes_remaining,
4379 ! NILP (delete_p), target_type,
4380 &actual_type, &actual_format,
4381 &actual_size, &bytes_remaining,
4382 &tmp_data);
4383 if (rc == Success && tmp_data)
4384 {
4385 /* The man page for XGetWindowProperty says:
4386 "If the returned format is 32, the returned data is represented
4387 as a long array and should be cast to that type to obtain the
4388 elements."
4389 This applies even if long is more than 32 bits, the X library
4390 converts from 32 bit elements received from the X server to long
4391 and passes the long array to us. Thus, for that case memcpy can not
4392 be used. We convert to a 32 bit type here, because so much code
4393 assume on that.
4394
4395 The bytes and offsets passed to XGetWindowProperty refers to the
4396 property and those are indeed in 32 bit quantities if format is
4397 32. */
4398
4399 if (actual_format == 32 && actual_format < BITS_PER_LONG)
4400 {
4401 unsigned long i;
4402 int *idata = (int *) tmp_data;
4403 long *ldata = (long *) tmp_data;
4404
4405 for (i = 0; i < actual_size; ++i)
4406 idata[i] = (int) ldata[i];
4407 }
4408
4409 if (NILP (vector_ret_p))
4410 prop_value = make_string (tmp_data, size);
4411 else
4412 prop_value = x_property_data_to_lisp (f,
4413 tmp_data,
4414 actual_type,
4415 actual_format,
4416 actual_size);
4417 }
4418
4419 if (tmp_data) XFree (tmp_data);
4420 }
4421
4422 UNBLOCK_INPUT;
4423 UNGCPRO;
4424 return prop_value;
4425 }
4426
4427
4428 \f
4429 /***********************************************************************
4430 Busy cursor
4431 ***********************************************************************/
4432
4433 /* Timer function of hourglass_atimer. TIMER is equal to
4434 hourglass_atimer.
4435
4436 Display an hourglass pointer on all frames by mapping the frames'
4437 hourglass_window. Set the hourglass_p flag in the frames'
4438 output_data.x structure to indicate that an hourglass cursor is
4439 shown on the frames. */
4440
4441 void
4442 show_hourglass (struct atimer *timer)
4443 {
4444 /* The timer implementation will cancel this timer automatically
4445 after this function has run. Set hourglass_atimer to null
4446 so that we know the timer doesn't have to be canceled. */
4447 hourglass_atimer = NULL;
4448
4449 if (!hourglass_shown_p)
4450 {
4451 Lisp_Object rest, frame;
4452
4453 BLOCK_INPUT;
4454
4455 FOR_EACH_FRAME (rest, frame)
4456 {
4457 struct frame *f = XFRAME (frame);
4458
4459 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4460 {
4461 Display *dpy = FRAME_X_DISPLAY (f);
4462
4463 #ifdef USE_X_TOOLKIT
4464 if (f->output_data.x->widget)
4465 #else
4466 if (FRAME_OUTER_WINDOW (f))
4467 #endif
4468 {
4469 f->output_data.x->hourglass_p = 1;
4470
4471 if (!f->output_data.x->hourglass_window)
4472 {
4473 unsigned long mask = CWCursor;
4474 XSetWindowAttributes attrs;
4475 #ifdef USE_GTK
4476 Window parent = FRAME_X_WINDOW (f);
4477 #else
4478 Window parent = FRAME_OUTER_WINDOW (f);
4479 #endif
4480 attrs.cursor = f->output_data.x->hourglass_cursor;
4481
4482 f->output_data.x->hourglass_window
4483 = XCreateWindow (dpy, parent,
4484 0, 0, 32000, 32000, 0, 0,
4485 InputOnly,
4486 CopyFromParent,
4487 mask, &attrs);
4488 }
4489
4490 XMapRaised (dpy, f->output_data.x->hourglass_window);
4491 XFlush (dpy);
4492 }
4493 }
4494 }
4495
4496 hourglass_shown_p = 1;
4497 UNBLOCK_INPUT;
4498 }
4499 }
4500
4501
4502 /* Hide the hourglass pointer on all frames, if it is currently
4503 shown. */
4504
4505 void
4506 hide_hourglass (void)
4507 {
4508 if (hourglass_shown_p)
4509 {
4510 Lisp_Object rest, frame;
4511
4512 BLOCK_INPUT;
4513 FOR_EACH_FRAME (rest, frame)
4514 {
4515 struct frame *f = XFRAME (frame);
4516
4517 if (FRAME_X_P (f)
4518 /* Watch out for newly created frames. */
4519 && f->output_data.x->hourglass_window)
4520 {
4521 XUnmapWindow (FRAME_X_DISPLAY (f),
4522 f->output_data.x->hourglass_window);
4523 /* Sync here because XTread_socket looks at the
4524 hourglass_p flag that is reset to zero below. */
4525 XSync (FRAME_X_DISPLAY (f), False);
4526 f->output_data.x->hourglass_p = 0;
4527 }
4528 }
4529
4530 hourglass_shown_p = 0;
4531 UNBLOCK_INPUT;
4532 }
4533 }
4534
4535
4536 \f
4537 /***********************************************************************
4538 Tool tips
4539 ***********************************************************************/
4540
4541 static Lisp_Object x_create_tip_frame (struct x_display_info *,
4542 Lisp_Object, Lisp_Object);
4543 static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
4544 Lisp_Object, int, int, int *, int *);
4545
4546 /* The frame of a currently visible tooltip. */
4547
4548 Lisp_Object tip_frame;
4549
4550 /* If non-nil, a timer started that hides the last tooltip when it
4551 fires. */
4552
4553 Lisp_Object tip_timer;
4554 Window tip_window;
4555
4556 /* If non-nil, a vector of 3 elements containing the last args
4557 with which x-show-tip was called. See there. */
4558
4559 Lisp_Object last_show_tip_args;
4560
4561 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4562
4563 Lisp_Object Vx_max_tooltip_size;
4564
4565
4566 static Lisp_Object
4567 unwind_create_tip_frame (Lisp_Object frame)
4568 {
4569 Lisp_Object deleted;
4570
4571 deleted = unwind_create_frame (frame);
4572 if (EQ (deleted, Qt))
4573 {
4574 tip_window = None;
4575 tip_frame = Qnil;
4576 }
4577
4578 return deleted;
4579 }
4580
4581
4582 /* Create a frame for a tooltip on the display described by DPYINFO.
4583 PARMS is a list of frame parameters. TEXT is the string to
4584 display in the tip frame. Value is the frame.
4585
4586 Note that functions called here, esp. x_default_parameter can
4587 signal errors, for instance when a specified color name is
4588 undefined. We have to make sure that we're in a consistent state
4589 when this happens. */
4590
4591 static Lisp_Object
4592 x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms, Lisp_Object text)
4593 {
4594 struct frame *f;
4595 Lisp_Object frame, tem;
4596 Lisp_Object name;
4597 long window_prompting = 0;
4598 int width, height;
4599 int count = SPECPDL_INDEX ();
4600 struct gcpro gcpro1, gcpro2, gcpro3;
4601 int face_change_count_before = face_change_count;
4602 Lisp_Object buffer;
4603 struct buffer *old_buffer;
4604
4605 check_x ();
4606
4607 if (!dpyinfo->terminal->name)
4608 error ("Terminal is not live, can't create new frames on it");
4609
4610 parms = Fcopy_alist (parms);
4611
4612 /* Get the name of the frame to use for resource lookup. */
4613 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4614 if (!STRINGP (name)
4615 && !EQ (name, Qunbound)
4616 && !NILP (name))
4617 error ("Invalid frame name--not a string or nil");
4618
4619 frame = Qnil;
4620 GCPRO3 (parms, name, frame);
4621 f = make_frame (1);
4622 XSETFRAME (frame, f);
4623
4624 buffer = Fget_buffer_create (build_string (" *tip*"));
4625 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
4626 old_buffer = current_buffer;
4627 set_buffer_internal_1 (XBUFFER (buffer));
4628 current_buffer->truncate_lines = Qnil;
4629 specbind (Qinhibit_read_only, Qt);
4630 specbind (Qinhibit_modification_hooks, Qt);
4631 Ferase_buffer ();
4632 Finsert (1, &text);
4633 set_buffer_internal_1 (old_buffer);
4634
4635 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4636 record_unwind_protect (unwind_create_tip_frame, frame);
4637
4638 f->terminal = dpyinfo->terminal;
4639 f->terminal->reference_count++;
4640
4641 /* By setting the output method, we're essentially saying that
4642 the frame is live, as per FRAME_LIVE_P. If we get a signal
4643 from this point on, x_destroy_window might screw up reference
4644 counts etc. */
4645 f->output_method = output_x_window;
4646 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
4647 memset (f->output_data.x, 0, sizeof (struct x_output));
4648 f->output_data.x->icon_bitmap = -1;
4649 FRAME_FONTSET (f) = -1;
4650 f->output_data.x->scroll_bar_foreground_pixel = -1;
4651 f->output_data.x->scroll_bar_background_pixel = -1;
4652 #ifdef USE_TOOLKIT_SCROLL_BARS
4653 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4654 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4655 #endif /* USE_TOOLKIT_SCROLL_BARS */
4656 f->icon_name = Qnil;
4657 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4658 #if GLYPH_DEBUG
4659 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
4660 dpyinfo_refcount = dpyinfo->reference_count;
4661 #endif /* GLYPH_DEBUG */
4662 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4663 f->output_data.x->explicit_parent = 0;
4664
4665 /* These colors will be set anyway later, but it's important
4666 to get the color reference counts right, so initialize them! */
4667 {
4668 Lisp_Object black;
4669 struct gcpro gcpro1;
4670
4671 /* Function x_decode_color can signal an error. Make
4672 sure to initialize color slots so that we won't try
4673 to free colors we haven't allocated. */
4674 FRAME_FOREGROUND_PIXEL (f) = -1;
4675 FRAME_BACKGROUND_PIXEL (f) = -1;
4676 f->output_data.x->cursor_pixel = -1;
4677 f->output_data.x->cursor_foreground_pixel = -1;
4678 f->output_data.x->border_pixel = -1;
4679 f->output_data.x->mouse_pixel = -1;
4680
4681 black = build_string ("black");
4682 GCPRO1 (black);
4683 FRAME_FOREGROUND_PIXEL (f)
4684 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4685 FRAME_BACKGROUND_PIXEL (f)
4686 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4687 f->output_data.x->cursor_pixel
4688 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4689 f->output_data.x->cursor_foreground_pixel
4690 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4691 f->output_data.x->border_pixel
4692 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4693 f->output_data.x->mouse_pixel
4694 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4695 UNGCPRO;
4696 }
4697
4698 /* Set the name; the functions to which we pass f expect the name to
4699 be set. */
4700 if (EQ (name, Qunbound) || NILP (name))
4701 {
4702 f->name = build_string (dpyinfo->x_id_name);
4703 f->explicit_name = 0;
4704 }
4705 else
4706 {
4707 f->name = name;
4708 f->explicit_name = 1;
4709 /* use the frame's title when getting resources for this frame. */
4710 specbind (Qx_resource_name, name);
4711 }
4712
4713 f->resx = dpyinfo->resx;
4714 f->resy = dpyinfo->resy;
4715
4716 register_font_driver (&xfont_driver, f);
4717 #ifdef HAVE_FREETYPE
4718 #ifdef HAVE_XFT
4719 register_font_driver (&xftfont_driver, f);
4720 #else /* not HAVE_XFT */
4721 register_font_driver (&ftxfont_driver, f);
4722 #endif /* not HAVE_XFT */
4723 #endif /* HAVE_FREETYPE */
4724
4725 x_default_parameter (f, parms, Qfont_backend, Qnil,
4726 "fontBackend", "FontBackend", RES_TYPE_STRING);
4727
4728 /* Extract the window parameters from the supplied values that are
4729 needed to determine window geometry. */
4730 x_default_font_parameter (f, parms);
4731
4732 x_default_parameter (f, parms, Qborder_width, make_number (0),
4733 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4734
4735 /* This defaults to 2 in order to match xterm. We recognize either
4736 internalBorderWidth or internalBorder (which is what xterm calls
4737 it). */
4738 if (NILP (Fassq (Qinternal_border_width, parms)))
4739 {
4740 Lisp_Object value;
4741
4742 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4743 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4744 if (! EQ (value, Qunbound))
4745 parms = Fcons (Fcons (Qinternal_border_width, value),
4746 parms);
4747 }
4748
4749 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4750 "internalBorderWidth", "internalBorderWidth",
4751 RES_TYPE_NUMBER);
4752
4753 /* Also do the stuff which must be set before the window exists. */
4754 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4755 "foreground", "Foreground", RES_TYPE_STRING);
4756 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4757 "background", "Background", RES_TYPE_STRING);
4758 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4759 "pointerColor", "Foreground", RES_TYPE_STRING);
4760 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4761 "cursorColor", "Foreground", RES_TYPE_STRING);
4762 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4763 "borderColor", "BorderColor", RES_TYPE_STRING);
4764
4765 /* Init faces before x_default_parameter is called for scroll-bar
4766 parameters because that function calls x_set_scroll_bar_width,
4767 which calls change_frame_size, which calls Fset_window_buffer,
4768 which runs hooks, which call Fvertical_motion. At the end, we
4769 end up in init_iterator with a null face cache, which should not
4770 happen. */
4771 init_frame_faces (f);
4772
4773 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4774
4775 window_prompting = x_figure_window_size (f, parms, 0);
4776
4777 {
4778 XSetWindowAttributes attrs;
4779 unsigned long mask;
4780 Atom type = FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
4781
4782 BLOCK_INPUT;
4783 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
4784 if (DoesSaveUnders (dpyinfo->screen))
4785 mask |= CWSaveUnder;
4786
4787 /* Window managers look at the override-redirect flag to determine
4788 whether or net to give windows a decoration (Xlib spec, chapter
4789 3.2.8). */
4790 attrs.override_redirect = True;
4791 attrs.save_under = True;
4792 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
4793 /* Arrange for getting MapNotify and UnmapNotify events. */
4794 attrs.event_mask = StructureNotifyMask;
4795 tip_window
4796 = FRAME_X_WINDOW (f)
4797 = XCreateWindow (FRAME_X_DISPLAY (f),
4798 FRAME_X_DISPLAY_INFO (f)->root_window,
4799 /* x, y, width, height */
4800 0, 0, 1, 1,
4801 /* Border. */
4802 f->border_width,
4803 CopyFromParent, InputOutput, CopyFromParent,
4804 mask, &attrs);
4805 XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
4806 FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type,
4807 XA_ATOM, 32, PropModeReplace,
4808 (unsigned char *)&type, 1);
4809 UNBLOCK_INPUT;
4810 }
4811
4812 x_make_gc (f);
4813
4814 x_default_parameter (f, parms, Qauto_raise, Qnil,
4815 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4816 x_default_parameter (f, parms, Qauto_lower, Qnil,
4817 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4818 x_default_parameter (f, parms, Qcursor_type, Qbox,
4819 "cursorType", "CursorType", RES_TYPE_SYMBOL);
4820
4821 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4822 Change will not be effected unless different from the current
4823 FRAME_LINES (f). */
4824 width = FRAME_COLS (f);
4825 height = FRAME_LINES (f);
4826 SET_FRAME_COLS (f, 0);
4827 FRAME_LINES (f) = 0;
4828 change_frame_size (f, height, width, 1, 0, 0);
4829
4830 /* Add `tooltip' frame parameter's default value. */
4831 if (NILP (Fframe_parameter (frame, Qtooltip)))
4832 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
4833
4834 /* FIXME - can this be done in a similar way to normal frames?
4835 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
4836
4837 /* Set the `display-type' frame parameter before setting up faces. */
4838 {
4839 Lisp_Object disptype;
4840
4841 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
4842 disptype = intern ("mono");
4843 else if (FRAME_X_DISPLAY_INFO (f)->visual->class == GrayScale
4844 || FRAME_X_DISPLAY_INFO (f)->visual->class == StaticGray)
4845 disptype = intern ("grayscale");
4846 else
4847 disptype = intern ("color");
4848
4849 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
4850 Fmodify_frame_parameters (frame, Fcons (Fcons (Qdisplay_type, disptype),
4851 Qnil));
4852 }
4853
4854 /* Set up faces after all frame parameters are known. This call
4855 also merges in face attributes specified for new frames.
4856
4857 Frame parameters may be changed if .Xdefaults contains
4858 specifications for the default font. For example, if there is an
4859 `Emacs.default.attributeBackground: pink', the `background-color'
4860 attribute of the frame get's set, which let's the internal border
4861 of the tooltip frame appear in pink. Prevent this. */
4862 {
4863 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
4864
4865 /* Set tip_frame here, so that */
4866 tip_frame = frame;
4867 call2 (Qface_set_after_frame_default, frame, Qnil);
4868
4869 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
4870 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
4871 Qnil));
4872 }
4873
4874 f->no_split = 1;
4875
4876 UNGCPRO;
4877
4878 /* It is now ok to make the frame official even if we get an error
4879 below. And the frame needs to be on Vframe_list or making it
4880 visible won't work. */
4881 Vframe_list = Fcons (frame, Vframe_list);
4882
4883 /* Now that the frame is official, it counts as a reference to
4884 its display. */
4885 FRAME_X_DISPLAY_INFO (f)->reference_count++;
4886
4887 /* Setting attributes of faces of the tooltip frame from resources
4888 and similar will increment face_change_count, which leads to the
4889 clearing of all current matrices. Since this isn't necessary
4890 here, avoid it by resetting face_change_count to the value it
4891 had before we created the tip frame. */
4892 face_change_count = face_change_count_before;
4893
4894 /* Discard the unwind_protect. */
4895 return unbind_to (count, frame);
4896 }
4897
4898
4899 /* Compute where to display tip frame F. PARMS is the list of frame
4900 parameters for F. DX and DY are specified offsets from the current
4901 location of the mouse. WIDTH and HEIGHT are the width and height
4902 of the tooltip. Return coordinates relative to the root window of
4903 the display in *ROOT_X, and *ROOT_Y. */
4904
4905 static void
4906 compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, Lisp_Object dy, int width, int height, int *root_x, int *root_y)
4907 {
4908 Lisp_Object left, top;
4909 int win_x, win_y;
4910 Window root, child;
4911 unsigned pmask;
4912
4913 /* User-specified position? */
4914 left = Fcdr (Fassq (Qleft, parms));
4915 top = Fcdr (Fassq (Qtop, parms));
4916
4917 /* Move the tooltip window where the mouse pointer is. Resize and
4918 show it. */
4919 if (!INTEGERP (left) || !INTEGERP (top))
4920 {
4921 BLOCK_INPUT;
4922 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
4923 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
4924 UNBLOCK_INPUT;
4925 }
4926
4927 if (INTEGERP (top))
4928 *root_y = XINT (top);
4929 else if (*root_y + XINT (dy) <= 0)
4930 *root_y = 0; /* Can happen for negative dy */
4931 else if (*root_y + XINT (dy) + height
4932 <= x_display_pixel_height (FRAME_X_DISPLAY_INFO (f)))
4933 /* It fits below the pointer */
4934 *root_y += XINT (dy);
4935 else if (height + XINT (dy) <= *root_y)
4936 /* It fits above the pointer. */
4937 *root_y -= height + XINT (dy);
4938 else
4939 /* Put it on the top. */
4940 *root_y = 0;
4941
4942 if (INTEGERP (left))
4943 *root_x = XINT (left);
4944 else if (*root_x + XINT (dx) <= 0)
4945 *root_x = 0; /* Can happen for negative dx */
4946 else if (*root_x + XINT (dx) + width
4947 <= x_display_pixel_width (FRAME_X_DISPLAY_INFO (f)))
4948 /* It fits to the right of the pointer. */
4949 *root_x += XINT (dx);
4950 else if (width + XINT (dx) <= *root_x)
4951 /* It fits to the left of the pointer. */
4952 *root_x -= width + XINT (dx);
4953 else
4954 /* Put it left-justified on the screen--it ought to fit that way. */
4955 *root_x = 0;
4956 }
4957
4958
4959 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
4960 doc: /* Show STRING in a "tooltip" window on frame FRAME.
4961 A tooltip window is a small X window displaying a string.
4962
4963 This is an internal function; Lisp code should call `tooltip-show'.
4964
4965 FRAME nil or omitted means use the selected frame.
4966
4967 PARMS is an optional list of frame parameters which can be used to
4968 change the tooltip's appearance.
4969
4970 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
4971 means use the default timeout of 5 seconds.
4972
4973 If the list of frame parameters PARAMS contains a `left' parameters,
4974 the tooltip is displayed at that x-position. Otherwise it is
4975 displayed at the mouse position, with offset DX added (default is 5 if
4976 DX isn't specified). Likewise for the y-position; if a `top' frame
4977 parameter is specified, it determines the y-position of the tooltip
4978 window, otherwise it is displayed at the mouse position, with offset
4979 DY added (default is -10).
4980
4981 A tooltip's maximum size is specified by `x-max-tooltip-size'.
4982 Text larger than the specified size is clipped. */)
4983 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
4984 {
4985 struct frame *f;
4986 struct window *w;
4987 int root_x, root_y;
4988 struct buffer *old_buffer;
4989 struct text_pos pos;
4990 int i, width, height;
4991 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4992 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4993 int count = SPECPDL_INDEX ();
4994
4995 specbind (Qinhibit_redisplay, Qt);
4996
4997 GCPRO4 (string, parms, frame, timeout);
4998
4999 CHECK_STRING (string);
5000 if (SCHARS (string) == 0)
5001 string = make_unibyte_string (" ", 1);
5002
5003 f = check_x_frame (frame);
5004 if (NILP (timeout))
5005 timeout = make_number (5);
5006 else
5007 CHECK_NATNUM (timeout);
5008
5009 if (NILP (dx))
5010 dx = make_number (5);
5011 else
5012 CHECK_NUMBER (dx);
5013
5014 if (NILP (dy))
5015 dy = make_number (-10);
5016 else
5017 CHECK_NUMBER (dy);
5018
5019 if (NILP (last_show_tip_args))
5020 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5021
5022 if (!NILP (tip_frame))
5023 {
5024 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5025 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5026 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5027
5028 if (EQ (frame, last_frame)
5029 && !NILP (Fequal (last_string, string))
5030 && !NILP (Fequal (last_parms, parms)))
5031 {
5032 struct frame *f = XFRAME (tip_frame);
5033
5034 /* Only DX and DY have changed. */
5035 if (!NILP (tip_timer))
5036 {
5037 Lisp_Object timer = tip_timer;
5038 tip_timer = Qnil;
5039 call1 (Qcancel_timer, timer);
5040 }
5041
5042 BLOCK_INPUT;
5043 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
5044 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
5045 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5046 root_x, root_y);
5047 UNBLOCK_INPUT;
5048 goto start_timer;
5049 }
5050 }
5051
5052 /* Hide a previous tip, if any. */
5053 Fx_hide_tip ();
5054
5055 ASET (last_show_tip_args, 0, string);
5056 ASET (last_show_tip_args, 1, frame);
5057 ASET (last_show_tip_args, 2, parms);
5058
5059 /* Add default values to frame parameters. */
5060 if (NILP (Fassq (Qname, parms)))
5061 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5062 if (NILP (Fassq (Qinternal_border_width, parms)))
5063 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5064 if (NILP (Fassq (Qborder_width, parms)))
5065 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5066 if (NILP (Fassq (Qborder_color, parms)))
5067 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5068 if (NILP (Fassq (Qbackground_color, parms)))
5069 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5070 parms);
5071
5072 /* Create a frame for the tooltip, and record it in the global
5073 variable tip_frame. */
5074 frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
5075 f = XFRAME (frame);
5076
5077 /* Set up the frame's root window. */
5078 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5079 w->left_col = w->top_line = make_number (0);
5080
5081 if (CONSP (Vx_max_tooltip_size)
5082 && INTEGERP (XCAR (Vx_max_tooltip_size))
5083 && XINT (XCAR (Vx_max_tooltip_size)) > 0
5084 && INTEGERP (XCDR (Vx_max_tooltip_size))
5085 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5086 {
5087 w->total_cols = XCAR (Vx_max_tooltip_size);
5088 w->total_lines = XCDR (Vx_max_tooltip_size);
5089 }
5090 else
5091 {
5092 w->total_cols = make_number (80);
5093 w->total_lines = make_number (40);
5094 }
5095
5096 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5097 adjust_glyphs (f);
5098 w->pseudo_window_p = 1;
5099
5100 /* Display the tooltip text in a temporary buffer. */
5101 old_buffer = current_buffer;
5102 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5103 current_buffer->truncate_lines = Qnil;
5104 clear_glyph_matrix (w->desired_matrix);
5105 clear_glyph_matrix (w->current_matrix);
5106 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5107 try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
5108
5109 /* Compute width and height of the tooltip. */
5110 width = height = 0;
5111 for (i = 0; i < w->desired_matrix->nrows; ++i)
5112 {
5113 struct glyph_row *row = &w->desired_matrix->rows[i];
5114 struct glyph *last;
5115 int row_width;
5116
5117 /* Stop at the first empty row at the end. */
5118 if (!row->enabled_p || !row->displays_text_p)
5119 break;
5120
5121 /* Let the row go over the full width of the frame. */
5122 row->full_width_p = 1;
5123
5124 row_width = row->pixel_width;
5125 /* There's a glyph at the end of rows that is used to place
5126 the cursor there. Don't include the width of this glyph. */
5127 if (row->used[TEXT_AREA])
5128 {
5129 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5130 if (INTEGERP (last->object))
5131 row_width -= last->pixel_width;
5132 }
5133
5134 height += row->height;
5135 width = max (width, row_width);
5136 }
5137
5138 /* Add the frame's internal border to the width and height the X
5139 window should have. */
5140 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5141 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5142
5143 /* Move the tooltip window where the mouse pointer is. Resize and
5144 show it. */
5145 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5146
5147 BLOCK_INPUT;
5148 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5149 root_x, root_y, width, height);
5150 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5151 UNBLOCK_INPUT;
5152
5153 /* Draw into the window. */
5154 w->must_be_updated_p = 1;
5155 update_single_window (w, 1);
5156
5157 /* Restore original current buffer. */
5158 set_buffer_internal_1 (old_buffer);
5159 windows_or_buffers_changed = old_windows_or_buffers_changed;
5160
5161 start_timer:
5162 /* Let the tip disappear after timeout seconds. */
5163 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5164 intern ("x-hide-tip"));
5165
5166 UNGCPRO;
5167 return unbind_to (count, Qnil);
5168 }
5169
5170
5171 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5172 doc: /* Hide the current tooltip window, if there is any.
5173 Value is t if tooltip was open, nil otherwise. */)
5174 (void)
5175 {
5176 int count;
5177 Lisp_Object deleted, frame, timer;
5178 struct gcpro gcpro1, gcpro2;
5179
5180 /* Return quickly if nothing to do. */
5181 if (NILP (tip_timer) && NILP (tip_frame))
5182 return Qnil;
5183
5184 frame = tip_frame;
5185 timer = tip_timer;
5186 GCPRO2 (frame, timer);
5187 tip_frame = tip_timer = deleted = Qnil;
5188
5189 count = SPECPDL_INDEX ();
5190 specbind (Qinhibit_redisplay, Qt);
5191 specbind (Qinhibit_quit, Qt);
5192
5193 if (!NILP (timer))
5194 call1 (Qcancel_timer, timer);
5195
5196 if (FRAMEP (frame))
5197 {
5198 delete_frame (frame, Qnil);
5199 deleted = Qt;
5200
5201 #ifdef USE_LUCID
5202 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5203 redisplay procedure is not called when a tip frame over menu
5204 items is unmapped. Redisplay the menu manually... */
5205 {
5206 struct frame *f = SELECTED_FRAME ();
5207 Widget w = f->output_data.x->menubar_widget;
5208 extern void xlwmenu_redisplay (Widget);
5209
5210 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5211 && w != NULL)
5212 {
5213 BLOCK_INPUT;
5214 xlwmenu_redisplay (w);
5215 UNBLOCK_INPUT;
5216 }
5217 }
5218 #endif /* USE_LUCID */
5219 }
5220
5221 UNGCPRO;
5222 return unbind_to (count, deleted);
5223 }
5224
5225
5226 \f
5227 /***********************************************************************
5228 File selection dialog
5229 ***********************************************************************/
5230
5231 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5232 Sx_uses_old_gtk_dialog,
5233 0, 0, 0,
5234 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5235 (void)
5236 {
5237 #ifdef USE_GTK
5238 extern int use_dialog_box;
5239 extern int use_file_dialog;
5240
5241 if (use_dialog_box
5242 && use_file_dialog
5243 && have_menus_p ()
5244 && xg_uses_old_file_dialog ())
5245 return Qt;
5246 #endif
5247 return Qnil;
5248 }
5249
5250
5251 #ifdef USE_MOTIF
5252 /* Callback for "OK" and "Cancel" on file selection dialog. */
5253
5254 static void
5255 file_dialog_cb (widget, client_data, call_data)
5256 Widget widget;
5257 XtPointer call_data, client_data;
5258 {
5259 int *result = (int *) client_data;
5260 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5261 *result = cb->reason;
5262 }
5263
5264
5265 /* Callback for unmapping a file selection dialog. This is used to
5266 capture the case where a dialog is closed via a window manager's
5267 closer button, for example. Using a XmNdestroyCallback didn't work
5268 in this case. */
5269
5270 static void
5271 file_dialog_unmap_cb (widget, client_data, call_data)
5272 Widget widget;
5273 XtPointer call_data, client_data;
5274 {
5275 int *result = (int *) client_data;
5276 *result = XmCR_CANCEL;
5277 }
5278
5279 static Lisp_Object
5280 clean_up_file_dialog (arg)
5281 Lisp_Object arg;
5282 {
5283 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5284 Widget dialog = (Widget) p->pointer;
5285
5286 /* Clean up. */
5287 BLOCK_INPUT;
5288 XtUnmanageChild (dialog);
5289 XtDestroyWidget (dialog);
5290 x_menu_set_in_use (0);
5291 UNBLOCK_INPUT;
5292
5293 return Qnil;
5294 }
5295
5296
5297 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5298 doc: /* Read file name, prompting with PROMPT in directory DIR.
5299 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5300 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5301 or directory must exist. ONLY-DIR-P is ignored." */)
5302 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5303 {
5304 int result;
5305 struct frame *f = SELECTED_FRAME ();
5306 Lisp_Object file = Qnil;
5307 Lisp_Object decoded_file;
5308 Widget dialog, text, help;
5309 Arg al[10];
5310 int ac = 0;
5311 extern XtAppContext Xt_app_con;
5312 XmString dir_xmstring, pattern_xmstring;
5313 int count = SPECPDL_INDEX ();
5314 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5315
5316 check_x ();
5317
5318 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5319
5320 if (popup_activated ())
5321 error ("Trying to use a menu from within a menu-entry");
5322
5323 CHECK_STRING (prompt);
5324 CHECK_STRING (dir);
5325
5326 /* Prevent redisplay. */
5327 specbind (Qinhibit_redisplay, Qt);
5328
5329 BLOCK_INPUT;
5330
5331 /* Create the dialog with PROMPT as title, using DIR as initial
5332 directory and using "*" as pattern. */
5333 dir = Fexpand_file_name (dir, Qnil);
5334 dir_xmstring = XmStringCreateLocalized (SDATA (dir));
5335 pattern_xmstring = XmStringCreateLocalized ("*");
5336
5337 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5338 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5339 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5340 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5341 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5342 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5343 "fsb", al, ac);
5344 XmStringFree (dir_xmstring);
5345 XmStringFree (pattern_xmstring);
5346
5347 /* Add callbacks for OK and Cancel. */
5348 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5349 (XtPointer) &result);
5350 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5351 (XtPointer) &result);
5352 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5353 (XtPointer) &result);
5354
5355 /* Remove the help button since we can't display help. */
5356 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5357 XtUnmanageChild (help);
5358
5359 /* Mark OK button as default. */
5360 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5361 XmNshowAsDefault, True, NULL);
5362
5363 /* If MUSTMATCH is non-nil, disable the file entry field of the
5364 dialog, so that the user must select a file from the files list
5365 box. We can't remove it because we wouldn't have a way to get at
5366 the result file name, then. */
5367 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5368 if (!NILP (mustmatch))
5369 {
5370 Widget label;
5371 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5372 XtSetSensitive (text, False);
5373 XtSetSensitive (label, False);
5374 }
5375
5376 /* Manage the dialog, so that list boxes get filled. */
5377 XtManageChild (dialog);
5378
5379 if (STRINGP (default_filename))
5380 {
5381 XmString default_xmstring;
5382 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5383 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5384
5385 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5386 XmTextFieldReplace (wtext, 0, last_pos,
5387 (SDATA (Ffile_name_nondirectory (default_filename))));
5388
5389 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5390 must include the path for this to work. */
5391
5392 default_xmstring = XmStringCreateLocalized (SDATA (default_filename));
5393
5394 if (XmListItemExists (list, default_xmstring))
5395 {
5396 int item_pos = XmListItemPos (list, default_xmstring);
5397 /* Select the item and scroll it into view. */
5398 XmListSelectPos (list, item_pos, True);
5399 XmListSetPos (list, item_pos);
5400 }
5401
5402 XmStringFree (default_xmstring);
5403 }
5404
5405 record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5406
5407 /* Process events until the user presses Cancel or OK. */
5408 x_menu_set_in_use (1);
5409 result = 0;
5410 while (result == 0)
5411 {
5412 XEvent event;
5413 x_menu_wait_for_event (0);
5414 XtAppNextEvent (Xt_app_con, &event);
5415 if (event.type == KeyPress
5416 && FRAME_X_DISPLAY (f) == event.xkey.display)
5417 {
5418 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5419
5420 /* Pop down on C-g. */
5421 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5422 XtUnmanageChild (dialog);
5423 }
5424
5425 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5426 }
5427
5428 /* Get the result. */
5429 if (result == XmCR_OK)
5430 {
5431 XmString text;
5432 String data;
5433
5434 XtVaGetValues (dialog, XmNtextString, &text, NULL);
5435 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
5436 XmStringFree (text);
5437 file = build_string (data);
5438 XtFree (data);
5439 }
5440 else
5441 file = Qnil;
5442
5443 UNBLOCK_INPUT;
5444 UNGCPRO;
5445
5446 /* Make "Cancel" equivalent to C-g. */
5447 if (NILP (file))
5448 Fsignal (Qquit, Qnil);
5449
5450 decoded_file = DECODE_FILE (file);
5451
5452 return unbind_to (count, decoded_file);
5453 }
5454
5455 #endif /* USE_MOTIF */
5456
5457 #ifdef USE_GTK
5458
5459 static Lisp_Object
5460 clean_up_dialog (Lisp_Object arg)
5461 {
5462 x_menu_set_in_use (0);
5463
5464 return Qnil;
5465 }
5466
5467 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5468 doc: /* Read file name, prompting with PROMPT in directory DIR.
5469 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5470 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5471 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5472 directories. */)
5473 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5474 {
5475 FRAME_PTR f = SELECTED_FRAME ();
5476 char *fn;
5477 Lisp_Object file = Qnil;
5478 Lisp_Object decoded_file;
5479 int count = SPECPDL_INDEX ();
5480 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5481 char *cdef_file;
5482
5483 check_x ();
5484
5485 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5486
5487 if (popup_activated ())
5488 error ("Trying to use a menu from within a menu-entry");
5489
5490 CHECK_STRING (prompt);
5491 CHECK_STRING (dir);
5492
5493 /* Prevent redisplay. */
5494 specbind (Qinhibit_redisplay, Qt);
5495 record_unwind_protect (clean_up_dialog, Qnil);
5496
5497 BLOCK_INPUT;
5498
5499 if (STRINGP (default_filename))
5500 cdef_file = SDATA (default_filename);
5501 else
5502 cdef_file = SDATA (dir);
5503
5504 fn = xg_get_file_name (f, SDATA (prompt), cdef_file,
5505 ! NILP (mustmatch),
5506 ! NILP (only_dir_p));
5507
5508 if (fn)
5509 {
5510 file = build_string (fn);
5511 xfree (fn);
5512 }
5513
5514 UNBLOCK_INPUT;
5515 UNGCPRO;
5516
5517 /* Make "Cancel" equivalent to C-g. */
5518 if (NILP (file))
5519 Fsignal (Qquit, Qnil);
5520
5521 decoded_file = DECODE_FILE (file);
5522
5523 return unbind_to (count, decoded_file);
5524 }
5525
5526
5527 #ifdef HAVE_FREETYPE
5528
5529 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5530 doc: /* Read a font name using a GTK font selection dialog.
5531 Return a GTK-style font string corresponding to the selection.
5532
5533 If FRAME is omitted or nil, it defaults to the selected frame. */)
5534 (Lisp_Object frame, Lisp_Object ignored)
5535 {
5536 FRAME_PTR f = check_x_frame (frame);
5537 char *name;
5538 Lisp_Object font;
5539 Lisp_Object font_param;
5540 char *default_name = NULL;
5541 struct gcpro gcpro1, gcpro2;
5542 int count = SPECPDL_INDEX ();
5543
5544 check_x ();
5545
5546 if (popup_activated ())
5547 error ("Trying to use a menu from within a menu-entry");
5548
5549 /* Prevent redisplay. */
5550 specbind (Qinhibit_redisplay, Qt);
5551 record_unwind_protect (clean_up_dialog, Qnil);
5552
5553 BLOCK_INPUT;
5554
5555 GCPRO2(font_param, font);
5556
5557 XSETFONT (font, FRAME_FONT (f));
5558 font_param = Ffont_get (font, intern (":name"));
5559 if (STRINGP (font_param))
5560 default_name = xstrdup (SDATA (font_param));
5561 else
5562 {
5563 font_param = Fframe_parameter (frame, Qfont_param);
5564 if (STRINGP (font_param))
5565 default_name = xstrdup (SDATA (font_param));
5566 }
5567
5568 if (default_name == NULL && x_last_font_name != NULL)
5569 default_name = xstrdup (x_last_font_name);
5570
5571 /* Convert fontconfig names to Gtk names, i.e. remove - before number */
5572 if (default_name)
5573 {
5574 char *p = strrchr (default_name, '-');
5575 if (p)
5576 {
5577 char *ep = p+1;
5578 while (isdigit (*ep))
5579 ++ep;
5580 if (*ep == '\0') *p = ' ';
5581 }
5582 }
5583
5584 name = xg_get_font_name (f, default_name);
5585 xfree (default_name);
5586
5587 if (name)
5588 {
5589 font = build_string (name);
5590 g_free (x_last_font_name);
5591 x_last_font_name = name;
5592 }
5593
5594 UNBLOCK_INPUT;
5595
5596 if (NILP (font))
5597 Fsignal (Qquit, Qnil);
5598
5599 return unbind_to (count, font);
5600 }
5601 #endif /* HAVE_FREETYPE */
5602
5603 #endif /* USE_GTK */
5604
5605 \f
5606 /***********************************************************************
5607 Keyboard
5608 ***********************************************************************/
5609
5610 #ifdef HAVE_XKBGETKEYBOARD
5611 #include <X11/XKBlib.h>
5612 #include <X11/keysym.h>
5613 #endif
5614
5615 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5616 Sx_backspace_delete_keys_p, 0, 1, 0,
5617 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5618 FRAME nil means use the selected frame.
5619 Value is t if we know that both keys are present, and are mapped to the
5620 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5621 present and mapped to the usual X keysyms. */)
5622 (Lisp_Object frame)
5623 {
5624 #ifdef HAVE_XKBGETKEYBOARD
5625 XkbDescPtr kb;
5626 struct frame *f = check_x_frame (frame);
5627 Display *dpy = FRAME_X_DISPLAY (f);
5628 Lisp_Object have_keys;
5629 int major, minor, op, event, error;
5630
5631 BLOCK_INPUT;
5632
5633 /* Check library version in case we're dynamically linked. */
5634 major = XkbMajorVersion;
5635 minor = XkbMinorVersion;
5636 if (!XkbLibraryVersion (&major, &minor))
5637 {
5638 UNBLOCK_INPUT;
5639 return Qlambda;
5640 }
5641
5642 /* Check that the server supports XKB. */
5643 major = XkbMajorVersion;
5644 minor = XkbMinorVersion;
5645 if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
5646 {
5647 UNBLOCK_INPUT;
5648 return Qlambda;
5649 }
5650
5651 /* In this code we check that the keyboard has physical keys with names
5652 that start with BKSP (Backspace) and DELE (Delete), and that they
5653 generate keysym XK_BackSpace and XK_Delete respectively.
5654 This function is used to test if normal-erase-is-backspace should be
5655 turned on.
5656 An alternative approach would be to just check if XK_BackSpace and
5657 XK_Delete are mapped to any key. But if any of those are mapped to
5658 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5659 user doesn't know about it, it is better to return false here.
5660 It is more obvious to the user what to do if she/he has two keys
5661 clearly marked with names/symbols and one key does something not
5662 expected (i.e. she/he then tries the other).
5663 The cases where Backspace/Delete is mapped to some other key combination
5664 are rare, and in those cases, normal-erase-is-backspace can be turned on
5665 manually. */
5666
5667 have_keys = Qnil;
5668 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5669 if (kb)
5670 {
5671 int delete_keycode = 0, backspace_keycode = 0, i;
5672
5673 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5674 {
5675 for (i = kb->min_key_code;
5676 (i < kb->max_key_code
5677 && (delete_keycode == 0 || backspace_keycode == 0));
5678 ++i)
5679 {
5680 /* The XKB symbolic key names can be seen most easily in
5681 the PS file generated by `xkbprint -label name
5682 $DISPLAY'. */
5683 if (memcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5684 delete_keycode = i;
5685 else if (memcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5686 backspace_keycode = i;
5687 }
5688
5689 XkbFreeNames (kb, 0, True);
5690 }
5691
5692 XkbFreeClientMap (kb, 0, True);
5693
5694 if (delete_keycode
5695 && backspace_keycode
5696 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5697 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5698 have_keys = Qt;
5699 }
5700 UNBLOCK_INPUT;
5701 return have_keys;
5702 #else /* not HAVE_XKBGETKEYBOARD */
5703 return Qlambda;
5704 #endif /* not HAVE_XKBGETKEYBOARD */
5705 }
5706
5707
5708 \f
5709 /***********************************************************************
5710 Initialization
5711 ***********************************************************************/
5712
5713 /* Keep this list in the same order as frame_parms in frame.c.
5714 Use 0 for unsupported frame parameters. */
5715
5716 frame_parm_handler x_frame_parm_handlers[] =
5717 {
5718 x_set_autoraise,
5719 x_set_autolower,
5720 x_set_background_color,
5721 x_set_border_color,
5722 x_set_border_width,
5723 x_set_cursor_color,
5724 x_set_cursor_type,
5725 x_set_font,
5726 x_set_foreground_color,
5727 x_set_icon_name,
5728 x_set_icon_type,
5729 x_set_internal_border_width,
5730 x_set_menu_bar_lines,
5731 x_set_mouse_color,
5732 x_explicitly_set_name,
5733 x_set_scroll_bar_width,
5734 x_set_title,
5735 x_set_unsplittable,
5736 x_set_vertical_scroll_bars,
5737 x_set_visibility,
5738 x_set_tool_bar_lines,
5739 x_set_scroll_bar_foreground,
5740 x_set_scroll_bar_background,
5741 x_set_screen_gamma,
5742 x_set_line_spacing,
5743 x_set_fringe_width,
5744 x_set_fringe_width,
5745 x_set_wait_for_wm,
5746 x_set_fullscreen,
5747 x_set_font_backend,
5748 x_set_alpha,
5749 x_set_sticky,
5750 };
5751
5752 void
5753 syms_of_xfns (void)
5754 {
5755 /* This is zero if not using X windows. */
5756 x_in_use = 0;
5757
5758 /* The section below is built by the lisp expression at the top of the file,
5759 just above where these variables are declared. */
5760 /*&&& init symbols here &&&*/
5761 Qnone = intern_c_string ("none");
5762 staticpro (&Qnone);
5763 Qsuppress_icon = intern_c_string ("suppress-icon");
5764 staticpro (&Qsuppress_icon);
5765 Qundefined_color = intern_c_string ("undefined-color");
5766 staticpro (&Qundefined_color);
5767 Qcompound_text = intern_c_string ("compound-text");
5768 staticpro (&Qcompound_text);
5769 Qcancel_timer = intern_c_string ("cancel-timer");
5770 staticpro (&Qcancel_timer);
5771 Qfont_param = intern_c_string ("font-parameter");
5772 staticpro (&Qfont_param);
5773 /* This is the end of symbol initialization. */
5774
5775 /* Text property `display' should be nonsticky by default. */
5776 Vtext_property_default_nonsticky
5777 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
5778
5779
5780 Fput (Qundefined_color, Qerror_conditions,
5781 pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
5782 Fput (Qundefined_color, Qerror_message,
5783 make_pure_c_string ("Undefined color"));
5784
5785 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
5786 doc: /* The shape of the pointer when over text.
5787 Changing the value does not affect existing frames
5788 unless you set the mouse color. */);
5789 Vx_pointer_shape = Qnil;
5790
5791 #if 0 /* This doesn't really do anything. */
5792 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
5793 doc: /* The shape of the pointer when not over text.
5794 This variable takes effect when you create a new frame
5795 or when you set the mouse color. */);
5796 #endif
5797 Vx_nontext_pointer_shape = Qnil;
5798
5799 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
5800 doc: /* The shape of the pointer when Emacs is busy.
5801 This variable takes effect when you create a new frame
5802 or when you set the mouse color. */);
5803 Vx_hourglass_pointer_shape = Qnil;
5804
5805 #if 0 /* This doesn't really do anything. */
5806 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
5807 doc: /* The shape of the pointer when over the mode line.
5808 This variable takes effect when you create a new frame
5809 or when you set the mouse color. */);
5810 #endif
5811 Vx_mode_pointer_shape = Qnil;
5812
5813 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5814 &Vx_sensitive_text_pointer_shape,
5815 doc: /* The shape of the pointer when over mouse-sensitive text.
5816 This variable takes effect when you create a new frame
5817 or when you set the mouse color. */);
5818 Vx_sensitive_text_pointer_shape = Qnil;
5819
5820 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5821 &Vx_window_horizontal_drag_shape,
5822 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
5823 This variable takes effect when you create a new frame
5824 or when you set the mouse color. */);
5825 Vx_window_horizontal_drag_shape = Qnil;
5826
5827 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
5828 doc: /* A string indicating the foreground color of the cursor box. */);
5829 Vx_cursor_fore_pixel = Qnil;
5830
5831 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
5832 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
5833 Text larger than this is clipped. */);
5834 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
5835
5836 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
5837 doc: /* Non-nil if no X window manager is in use.
5838 Emacs doesn't try to figure this out; this is always nil
5839 unless you set it to something else. */);
5840 /* We don't have any way to find this out, so set it to nil
5841 and maybe the user would like to set it to t. */
5842 Vx_no_window_manager = Qnil;
5843
5844 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5845 &Vx_pixel_size_width_font_regexp,
5846 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5847
5848 Since Emacs gets width of a font matching with this regexp from
5849 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5850 such a font. This is especially effective for such large fonts as
5851 Chinese, Japanese, and Korean. */);
5852 Vx_pixel_size_width_font_regexp = Qnil;
5853
5854 /* This is not ifdef:ed, so other builds than GTK can customize it. */
5855 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog,
5856 doc: /* *Non-nil means prompt with the old GTK file selection dialog.
5857 If nil or if the file selection dialog is not available, the new GTK file
5858 chooser is used instead. To turn off all file dialogs set the
5859 variable `use-file-dialog'. */);
5860 x_gtk_use_old_file_dialog = 0;
5861
5862 DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files,
5863 doc: /* *If non-nil, the GTK file chooser will by default show hidden files.
5864 Note that this is just the default, there is a toggle button on the file
5865 chooser to show or not show hidden files on a case by case basis. */);
5866 x_gtk_show_hidden_files = 0;
5867
5868 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text,
5869 doc: /* *If non-nil, the GTK file chooser will show additional help text.
5870 If more space for files in the file chooser dialog is wanted, set this to nil
5871 to turn the additional text off. */);
5872 x_gtk_file_dialog_help_text = 1;
5873
5874 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar,
5875 doc: /* *If non-nil, a detached tool bar is shown in full.
5876 The default is to just show an arrow and pressing on that arrow shows
5877 the tool bar buttons. */);
5878 x_gtk_whole_detached_tool_bar = 0;
5879
5880 Fprovide (intern_c_string ("x"), Qnil);
5881
5882 #ifdef USE_X_TOOLKIT
5883 Fprovide (intern_c_string ("x-toolkit"), Qnil);
5884 #ifdef USE_MOTIF
5885 Fprovide (intern_c_string ("motif"), Qnil);
5886
5887 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
5888 doc: /* Version info for LessTif/Motif. */);
5889 Vmotif_version_string = build_string (XmVERSION_STRING);
5890 #endif /* USE_MOTIF */
5891 #endif /* USE_X_TOOLKIT */
5892
5893 #ifdef USE_GTK
5894 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
5895 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
5896 But for a user it is a toolkit for X, and indeed, configure
5897 accepts --with-x-toolkit=gtk. */
5898 Fprovide (intern_c_string ("x-toolkit"), Qnil);
5899 Fprovide (intern_c_string ("gtk"), Qnil);
5900
5901 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
5902 doc: /* Version info for GTK+. */);
5903 {
5904 char gtk_version[40];
5905 g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
5906 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
5907 Vgtk_version_string = make_pure_string (gtk_version, strlen (gtk_version), strlen (gtk_version), 0);
5908 }
5909 #endif /* USE_GTK */
5910
5911 /* X window properties. */
5912 defsubr (&Sx_change_window_property);
5913 defsubr (&Sx_delete_window_property);
5914 defsubr (&Sx_window_property);
5915
5916 defsubr (&Sxw_display_color_p);
5917 defsubr (&Sx_display_grayscale_p);
5918 defsubr (&Sxw_color_defined_p);
5919 defsubr (&Sxw_color_values);
5920 defsubr (&Sx_server_max_request_size);
5921 defsubr (&Sx_server_vendor);
5922 defsubr (&Sx_server_version);
5923 defsubr (&Sx_display_pixel_width);
5924 defsubr (&Sx_display_pixel_height);
5925 defsubr (&Sx_display_mm_width);
5926 defsubr (&Sx_display_mm_height);
5927 defsubr (&Sx_display_screens);
5928 defsubr (&Sx_display_planes);
5929 defsubr (&Sx_display_color_cells);
5930 defsubr (&Sx_display_visual_class);
5931 defsubr (&Sx_display_backing_store);
5932 defsubr (&Sx_display_save_under);
5933 defsubr (&Sx_wm_set_size_hint);
5934 defsubr (&Sx_create_frame);
5935 defsubr (&Sx_open_connection);
5936 defsubr (&Sx_close_connection);
5937 defsubr (&Sx_display_list);
5938 defsubr (&Sx_synchronize);
5939 defsubr (&Sx_focus_frame);
5940 defsubr (&Sx_backspace_delete_keys_p);
5941
5942 /* Setting callback functions for fontset handler. */
5943 check_window_system_func = check_x;
5944
5945 defsubr (&Sx_show_tip);
5946 defsubr (&Sx_hide_tip);
5947 tip_timer = Qnil;
5948 staticpro (&tip_timer);
5949 tip_frame = Qnil;
5950 staticpro (&tip_frame);
5951
5952 last_show_tip_args = Qnil;
5953 staticpro (&last_show_tip_args);
5954
5955 defsubr (&Sx_uses_old_gtk_dialog);
5956 #if defined (USE_MOTIF) || defined (USE_GTK)
5957 defsubr (&Sx_file_dialog);
5958 #endif
5959
5960 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
5961 defsubr (&Sx_select_font);
5962 x_last_font_name = NULL;
5963 #endif
5964 }
5965
5966 #endif /* HAVE_X_WINDOWS */
5967
5968 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
5969 (do not change this comment) */