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