1 /* Functions for the X window system.
2 Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 01, 02, 03
3 Free Software Foundation.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
31 /* This makes the fields of a Display accessible, in Xlib header files. */
33 #define XLIB_ILLEGAL_ACCESS
40 #include "intervals.h"
41 #include "dispextern.h"
43 #include "blockinput.h"
49 #include "termhooks.h"
55 #include <sys/types.h>
59 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
60 #include "bitmaps/gray.xbm"
62 #include <X11/bitmaps/gray>
65 #include "[.bitmaps]gray.xbm"
73 #include <X11/Shell.h>
76 #include <X11/Xaw/Paned.h>
77 #include <X11/Xaw/Label.h>
78 #endif /* USE_MOTIF */
81 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
90 #include "../lwlib/lwlib.h"
94 #include <Xm/DialogS.h>
95 #include <Xm/FileSB.h>
98 /* Do the EDITRES protocol if running X11R5
99 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
101 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
103 extern void _XEditResCheckMessages ();
104 #endif /* R5 + Athena */
106 /* Unique id counter for widgets created by the Lucid Widget Library. */
108 extern LWLIB_ID widget_id_tick
;
111 /* This is part of a kludge--see lwlib/xlwmenu.c. */
112 extern XFontStruct
*xlwmenu_default_font
;
115 extern void free_frame_menubar ();
116 extern double atof ();
120 /* LessTif/Motif version info. */
122 static Lisp_Object Vmotif_version_string
;
124 #endif /* USE_MOTIF */
126 #endif /* USE_X_TOOLKIT */
129 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
131 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
134 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
135 it, and including `bitmaps/gray' more than once is a problem when
136 config.h defines `static' as an empty replacement string. */
138 int gray_bitmap_width
= gray_width
;
139 int gray_bitmap_height
= gray_height
;
140 char *gray_bitmap_bits
= gray_bits
;
142 /* Non-zero means we're allowed to display an hourglass cursor. */
144 int display_hourglass_p
;
146 /* The background and shape of the mouse pointer, and shape when not
147 over text or in the modeline. */
149 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
150 Lisp_Object Vx_hourglass_pointer_shape
;
152 /* The shape when over mouse-sensitive text. */
154 Lisp_Object Vx_sensitive_text_pointer_shape
;
156 /* If non-nil, the pointer shape to indicate that windows can be
157 dragged horizontally. */
159 Lisp_Object Vx_window_horizontal_drag_shape
;
161 /* Color of chars displayed in cursor box. */
163 Lisp_Object Vx_cursor_fore_pixel
;
165 /* Nonzero if using X. */
169 /* Non nil if no window manager is in use. */
171 Lisp_Object Vx_no_window_manager
;
173 /* Search path for bitmap files. */
175 Lisp_Object Vx_bitmap_file_path
;
177 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
179 Lisp_Object Vx_pixel_size_width_font_regexp
;
182 Lisp_Object Qsuppress_icon
;
183 Lisp_Object Qundefined_color
;
185 Lisp_Object Qcompound_text
, Qcancel_timer
;
189 extern Lisp_Object Vwindow_system_version
;
191 /* The below are defined in frame.c. */
194 int image_cache_refcount
, dpyinfo_refcount
;
199 /* Error if we are not connected to X. */
205 error ("X windows are not in use or not initialized");
208 /* Nonzero if we can use mouse menus.
209 You should not call this unless HAVE_MENUS is defined. */
217 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
218 and checking validity for X. */
221 check_x_frame (frame
)
227 frame
= selected_frame
;
228 CHECK_LIVE_FRAME (frame
);
231 error ("Non-X frame used");
235 /* Let the user specify an X display with a frame.
236 nil stands for the selected frame--or, if that is not an X frame,
237 the first X display on the list. */
239 struct x_display_info
*
240 check_x_display_info (frame
)
243 struct x_display_info
*dpyinfo
= NULL
;
247 struct frame
*sf
= XFRAME (selected_frame
);
249 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
250 dpyinfo
= FRAME_X_DISPLAY_INFO (sf
);
251 else if (x_display_list
!= 0)
252 dpyinfo
= x_display_list
;
254 error ("X windows are not in use or not initialized");
256 else if (STRINGP (frame
))
257 dpyinfo
= x_display_info_for_name (frame
);
260 FRAME_PTR f
= check_x_frame (frame
);
261 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
268 /* Return the Emacs frame-object corresponding to an X window.
269 It could be the frame's main window or an icon window. */
271 /* This function can be called during GC, so use GC_xxx type test macros. */
274 x_window_to_frame (dpyinfo
, wdesc
)
275 struct x_display_info
*dpyinfo
;
278 Lisp_Object tail
, frame
;
281 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
284 if (!GC_FRAMEP (frame
))
287 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
289 if (f
->output_data
.x
->hourglass_window
== wdesc
)
292 if ((f
->output_data
.x
->edit_widget
293 && XtWindow (f
->output_data
.x
->edit_widget
) == wdesc
)
294 /* A tooltip frame? */
295 || (!f
->output_data
.x
->edit_widget
296 && FRAME_X_WINDOW (f
) == wdesc
)
297 || f
->output_data
.x
->icon_desc
== wdesc
)
299 #else /* not USE_X_TOOLKIT */
301 if (f
->output_data
.x
->edit_widget
)
303 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
304 struct x_output
*x
= f
->output_data
.x
;
305 if (gwdesc
!= 0 && gwdesc
== x
->edit_widget
)
309 if (FRAME_X_WINDOW (f
) == wdesc
310 || f
->output_data
.x
->icon_desc
== wdesc
)
312 #endif /* not USE_X_TOOLKIT */
317 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
318 /* Like x_window_to_frame but also compares the window with the widget's
322 x_any_window_to_frame (dpyinfo
, wdesc
)
323 struct x_display_info
*dpyinfo
;
326 Lisp_Object tail
, frame
;
327 struct frame
*f
, *found
;
331 for (tail
= Vframe_list
; GC_CONSP (tail
) && !found
; tail
= XCDR (tail
))
334 if (!GC_FRAMEP (frame
))
338 if (FRAME_X_P (f
) && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
340 /* This frame matches if the window is any of its widgets. */
341 x
= f
->output_data
.x
;
342 if (x
->hourglass_window
== wdesc
)
347 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
349 && (gwdesc
== x
->widget
350 || gwdesc
== x
->edit_widget
351 || gwdesc
== x
->vbox_widget
352 || gwdesc
== x
->menubar_widget
))
355 if (wdesc
== XtWindow (x
->widget
)
356 || wdesc
== XtWindow (x
->column_widget
)
357 || wdesc
== XtWindow (x
->edit_widget
))
359 /* Match if the window is this frame's menubar. */
360 else if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
364 else if (FRAME_X_WINDOW (f
) == wdesc
)
365 /* A tooltip frame. */
373 /* Likewise, but exclude the menu bar widget. */
376 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
377 struct x_display_info
*dpyinfo
;
380 Lisp_Object tail
, frame
;
384 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
387 if (!GC_FRAMEP (frame
))
390 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
392 x
= f
->output_data
.x
;
393 /* This frame matches if the window is any of its widgets. */
394 if (x
->hourglass_window
== wdesc
)
399 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
401 && (gwdesc
== x
->widget
402 || gwdesc
== x
->edit_widget
403 || gwdesc
== x
->vbox_widget
))
406 if (wdesc
== XtWindow (x
->widget
)
407 || wdesc
== XtWindow (x
->column_widget
)
408 || wdesc
== XtWindow (x
->edit_widget
))
412 else if (FRAME_X_WINDOW (f
) == wdesc
)
413 /* A tooltip frame. */
419 /* Likewise, but consider only the menu bar widget. */
422 x_menubar_window_to_frame (dpyinfo
, wdesc
)
423 struct x_display_info
*dpyinfo
;
426 Lisp_Object tail
, frame
;
430 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
433 if (!GC_FRAMEP (frame
))
436 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
438 x
= f
->output_data
.x
;
439 /* Match if the window is this frame's menubar. */
441 if (x
->menubar_widget
)
443 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
448 && (gwdesc
== x
->menubar_widget
449 || gtk_widget_get_parent (gwdesc
) == x
->menubar_widget
))
455 if (x
->menubar_widget
456 && lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
463 /* Return the frame whose principal (outermost) window is WDESC.
464 If WDESC is some other (smaller) window, we return 0. */
467 x_top_window_to_frame (dpyinfo
, wdesc
)
468 struct x_display_info
*dpyinfo
;
471 Lisp_Object tail
, frame
;
475 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
478 if (!GC_FRAMEP (frame
))
481 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
483 x
= f
->output_data
.x
;
487 /* This frame matches if the window is its topmost widget. */
489 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
490 if (gwdesc
== x
->widget
)
493 if (wdesc
== XtWindow (x
->widget
))
495 #if 0 /* I don't know why it did this,
496 but it seems logically wrong,
497 and it causes trouble for MapNotify events. */
498 /* Match if the window is this frame's menubar. */
499 if (x
->menubar_widget
500 && wdesc
== XtWindow (x
->menubar_widget
))
505 else if (FRAME_X_WINDOW (f
) == wdesc
)
511 #endif /* USE_X_TOOLKIT || USE_GTK */
515 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
516 id, which is just an int that this section returns. Bitmaps are
517 reference counted so they can be shared among frames.
519 Bitmap indices are guaranteed to be > 0, so a negative number can
520 be used to indicate no bitmap.
522 If you use x_create_bitmap_from_data, then you must keep track of
523 the bitmaps yourself. That is, creating a bitmap from the same
524 data more than once will not be caught. */
527 /* Functions to access the contents of a bitmap, given an id. */
530 x_bitmap_height (f
, id
)
534 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
538 x_bitmap_width (f
, id
)
542 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
546 x_bitmap_pixmap (f
, id
)
550 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
554 /* Allocate a new bitmap record. Returns index of new record. */
557 x_allocate_bitmap_record (f
)
560 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
563 if (dpyinfo
->bitmaps
== NULL
)
565 dpyinfo
->bitmaps_size
= 10;
567 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
568 dpyinfo
->bitmaps_last
= 1;
572 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
573 return ++dpyinfo
->bitmaps_last
;
575 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
576 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
579 dpyinfo
->bitmaps_size
*= 2;
581 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
582 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
583 return ++dpyinfo
->bitmaps_last
;
586 /* Add one reference to the reference count of the bitmap with id ID. */
589 x_reference_bitmap (f
, id
)
593 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
596 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
599 x_create_bitmap_from_data (f
, bits
, width
, height
)
602 unsigned int width
, height
;
604 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
608 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
609 bits
, width
, height
);
616 id
= x_allocate_bitmap_record (f
);
617 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
618 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
619 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
620 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
621 dpyinfo
->bitmaps
[id
- 1].height
= height
;
622 dpyinfo
->bitmaps
[id
- 1].width
= width
;
627 /* Create bitmap from file FILE for frame F. */
630 x_create_bitmap_from_file (f
, file
)
634 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
635 unsigned int width
, height
;
637 int xhot
, yhot
, result
, id
;
642 /* Look for an existing bitmap with the same name. */
643 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
645 if (dpyinfo
->bitmaps
[id
].refcount
646 && dpyinfo
->bitmaps
[id
].file
647 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) SDATA (file
)))
649 ++dpyinfo
->bitmaps
[id
].refcount
;
654 /* Search bitmap-file-path for the file, if appropriate. */
655 fd
= openp (Vx_bitmap_file_path
, file
, Qnil
, &found
, Qnil
);
660 filename
= (char *) SDATA (found
);
662 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
663 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
664 if (result
!= BitmapSuccess
)
667 id
= x_allocate_bitmap_record (f
);
668 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
669 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
670 dpyinfo
->bitmaps
[id
- 1].file
671 = (char *) xmalloc (SBYTES (file
) + 1);
672 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
673 dpyinfo
->bitmaps
[id
- 1].height
= height
;
674 dpyinfo
->bitmaps
[id
- 1].width
= width
;
675 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
680 /* Remove reference to bitmap with id number ID. */
683 x_destroy_bitmap (f
, id
)
687 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
691 --dpyinfo
->bitmaps
[id
- 1].refcount
;
692 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
695 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
696 if (dpyinfo
->bitmaps
[id
- 1].file
)
698 xfree (dpyinfo
->bitmaps
[id
- 1].file
);
699 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
706 /* Free all the bitmaps for the display specified by DPYINFO. */
709 x_destroy_all_bitmaps (dpyinfo
)
710 struct x_display_info
*dpyinfo
;
713 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
714 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
716 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
717 if (dpyinfo
->bitmaps
[i
].file
)
718 xfree (dpyinfo
->bitmaps
[i
].file
);
720 dpyinfo
->bitmaps_last
= 0;
724 static Lisp_Object unwind_create_frame
P_ ((Lisp_Object
));
725 static Lisp_Object unwind_create_tip_frame
P_ ((Lisp_Object
));
726 static void x_disable_image
P_ ((struct frame
*, struct image
*));
728 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
729 static void x_set_wait_for_wm
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
730 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
731 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
732 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
733 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
734 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
735 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
736 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
737 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
738 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
739 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
740 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
741 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
743 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
745 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
750 static void x_edge_detection
P_ ((struct frame
*, struct image
*, Lisp_Object
,
752 static void init_color_table
P_ ((void));
753 static void free_color_table
P_ ((void));
754 static unsigned long *colors_in_color_table
P_ ((int *n
));
755 static unsigned long lookup_rgb_color
P_ ((struct frame
*f
, int r
, int g
, int b
));
756 static unsigned long lookup_pixel_color
P_ ((struct frame
*f
, unsigned long p
));
762 /* Store the screen positions of frame F into XPTR and YPTR.
763 These are the positions of the containing window manager window,
764 not Emacs's own window. */
767 x_real_positions (f
, xptr
, yptr
)
771 int win_x
, win_y
, outer_x
, outer_y
;
772 int real_x
= 0, real_y
= 0;
774 Window win
= f
->output_data
.x
->parent_desc
;
780 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
782 if (win
== FRAME_X_DISPLAY_INFO (f
)->root_window
)
783 win
= FRAME_OUTER_WINDOW (f
);
785 /* This loop traverses up the containment tree until we hit the root
786 window. Window managers may intersect many windows between our window
787 and the root window. The window we find just before the root window
788 should be the outer WM window. */
791 Window wm_window
, rootw
;
792 Window
*tmp_children
;
793 unsigned int tmp_nchildren
;
796 success
= XQueryTree (FRAME_X_DISPLAY (f
), win
, &rootw
,
797 &wm_window
, &tmp_children
, &tmp_nchildren
);
799 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
801 /* Don't free tmp_children if XQueryTree failed. */
805 XFree ((char *) tmp_children
);
807 if (wm_window
== rootw
|| had_errors
)
818 /* Get the real coordinates for the WM window upper left corner */
819 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
820 &rootw
, &real_x
, &real_y
, &ign
, &ign
, &ign
, &ign
);
822 /* Translate real coordinates to coordinates relative to our
823 window. For our window, the upper left corner is 0, 0.
824 Since the upper left corner of the WM window is outside
825 our window, win_x and win_y will be negative:
827 ------------------ ---> x
829 | ----------------- v y
832 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
834 /* From-window, to-window. */
835 FRAME_X_DISPLAY_INFO (f
)->root_window
,
838 /* From-position, to-position. */
839 real_x
, real_y
, &win_x
, &win_y
,
844 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
851 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
853 /* From-window, to-window. */
854 FRAME_X_DISPLAY_INFO (f
)->root_window
,
855 FRAME_OUTER_WINDOW (f
),
857 /* From-position, to-position. */
858 real_x
, real_y
, &outer_x
, &outer_y
,
864 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
867 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
871 if (had_errors
) return;
873 f
->x_pixels_diff
= -win_x
;
874 f
->y_pixels_diff
= -win_y
;
876 FRAME_X_OUTPUT (f
)->x_pixels_outer_diff
= -outer_x
;
877 FRAME_X_OUTPUT (f
)->y_pixels_outer_diff
= -outer_y
;
886 /* Gamma-correct COLOR on frame F. */
889 gamma_correct (f
, color
)
895 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
896 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
897 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
902 /* Decide if color named COLOR_NAME is valid for use on frame F. If
903 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
904 allocate the color. Value is zero if COLOR_NAME is invalid, or
905 no color could be allocated. */
908 x_defined_color (f
, color_name
, color
, alloc_p
)
915 Display
*dpy
= FRAME_X_DISPLAY (f
);
916 Colormap cmap
= FRAME_X_COLORMAP (f
);
919 success_p
= XParseColor (dpy
, cmap
, color_name
, color
);
920 if (success_p
&& alloc_p
)
921 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
928 /* Return the pixel color value for color COLOR_NAME on frame F. If F
929 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
930 Signal an error if color can't be allocated. */
933 x_decode_color (f
, color_name
, mono_color
)
935 Lisp_Object color_name
;
940 CHECK_STRING (color_name
);
942 #if 0 /* Don't do this. It's wrong when we're not using the default
943 colormap, it makes freeing difficult, and it's probably not
944 an important optimization. */
945 if (strcmp (SDATA (color_name
), "black") == 0)
946 return BLACK_PIX_DEFAULT (f
);
947 else if (strcmp (SDATA (color_name
), "white") == 0)
948 return WHITE_PIX_DEFAULT (f
);
951 /* Return MONO_COLOR for monochrome frames. */
952 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
955 /* x_defined_color is responsible for coping with failures
956 by looking for a near-miss. */
957 if (x_defined_color (f
, SDATA (color_name
), &cdef
, 1))
960 Fsignal (Qerror
, Fcons (build_string ("Undefined color"),
961 Fcons (color_name
, Qnil
)));
967 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
968 the previous value of that parameter, NEW_VALUE is the new value.
969 See also the comment of wait_for_wm in struct x_output. */
972 x_set_wait_for_wm (f
, new_value
, old_value
)
974 Lisp_Object new_value
, old_value
;
976 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
980 /* Functions called only from `x_set_frame_param'
981 to set individual parameters.
983 If FRAME_X_WINDOW (f) is 0,
984 the frame is being created and its X-window does not exist yet.
985 In that case, just record the parameter's new value
986 in the standard place; do not attempt to change the window. */
989 x_set_foreground_color (f
, arg
, oldval
)
991 Lisp_Object arg
, oldval
;
993 struct x_output
*x
= f
->output_data
.x
;
994 unsigned long fg
, old_fg
;
996 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
997 old_fg
= x
->foreground_pixel
;
998 x
->foreground_pixel
= fg
;
1000 if (FRAME_X_WINDOW (f
) != 0)
1002 Display
*dpy
= FRAME_X_DISPLAY (f
);
1005 XSetForeground (dpy
, x
->normal_gc
, fg
);
1006 XSetBackground (dpy
, x
->reverse_gc
, fg
);
1008 if (x
->cursor_pixel
== old_fg
)
1010 unload_color (f
, x
->cursor_pixel
);
1011 x
->cursor_pixel
= x_copy_color (f
, fg
);
1012 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
1017 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
1019 if (FRAME_VISIBLE_P (f
))
1023 unload_color (f
, old_fg
);
1027 x_set_background_color (f
, arg
, oldval
)
1029 Lisp_Object arg
, oldval
;
1031 struct x_output
*x
= f
->output_data
.x
;
1034 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1035 unload_color (f
, x
->background_pixel
);
1036 x
->background_pixel
= bg
;
1038 if (FRAME_X_WINDOW (f
) != 0)
1040 Display
*dpy
= FRAME_X_DISPLAY (f
);
1043 XSetBackground (dpy
, x
->normal_gc
, bg
);
1044 XSetForeground (dpy
, x
->reverse_gc
, bg
);
1045 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
1046 XSetForeground (dpy
, x
->cursor_gc
, bg
);
1049 xg_set_background_color (f
, bg
);
1052 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
1053 toolkit scroll bars. */
1056 for (bar
= FRAME_SCROLL_BARS (f
);
1058 bar
= XSCROLL_BAR (bar
)->next
)
1060 Window window
= SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
));
1061 XSetWindowBackground (dpy
, window
, bg
);
1064 #endif /* USE_TOOLKIT_SCROLL_BARS */
1067 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
1069 if (FRAME_VISIBLE_P (f
))
1075 x_set_mouse_color (f
, arg
, oldval
)
1077 Lisp_Object arg
, oldval
;
1079 struct x_output
*x
= f
->output_data
.x
;
1080 Display
*dpy
= FRAME_X_DISPLAY (f
);
1081 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
1082 Cursor hourglass_cursor
, horizontal_drag_cursor
;
1084 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1085 unsigned long mask_color
= x
->background_pixel
;
1087 /* Don't let pointers be invisible. */
1088 if (mask_color
== pixel
)
1090 x_free_colors (f
, &pixel
, 1);
1091 pixel
= x_copy_color (f
, x
->foreground_pixel
);
1094 unload_color (f
, x
->mouse_pixel
);
1095 x
->mouse_pixel
= pixel
;
1099 /* It's not okay to crash if the user selects a screwy cursor. */
1100 count
= x_catch_errors (dpy
);
1102 if (!NILP (Vx_pointer_shape
))
1104 CHECK_NUMBER (Vx_pointer_shape
);
1105 cursor
= XCreateFontCursor (dpy
, XINT (Vx_pointer_shape
));
1108 cursor
= XCreateFontCursor (dpy
, XC_xterm
);
1109 x_check_errors (dpy
, "bad text pointer cursor: %s");
1111 if (!NILP (Vx_nontext_pointer_shape
))
1113 CHECK_NUMBER (Vx_nontext_pointer_shape
);
1115 = XCreateFontCursor (dpy
, XINT (Vx_nontext_pointer_shape
));
1118 nontext_cursor
= XCreateFontCursor (dpy
, XC_left_ptr
);
1119 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
1121 if (!NILP (Vx_hourglass_pointer_shape
))
1123 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
1125 = XCreateFontCursor (dpy
, XINT (Vx_hourglass_pointer_shape
));
1128 hourglass_cursor
= XCreateFontCursor (dpy
, XC_watch
);
1129 x_check_errors (dpy
, "bad hourglass pointer cursor: %s");
1131 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
1132 if (!NILP (Vx_mode_pointer_shape
))
1134 CHECK_NUMBER (Vx_mode_pointer_shape
);
1135 mode_cursor
= XCreateFontCursor (dpy
, XINT (Vx_mode_pointer_shape
));
1138 mode_cursor
= XCreateFontCursor (dpy
, XC_xterm
);
1139 x_check_errors (dpy
, "bad modeline pointer cursor: %s");
1141 if (!NILP (Vx_sensitive_text_pointer_shape
))
1143 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
1145 = XCreateFontCursor (dpy
, XINT (Vx_sensitive_text_pointer_shape
));
1148 hand_cursor
= XCreateFontCursor (dpy
, XC_hand2
);
1150 if (!NILP (Vx_window_horizontal_drag_shape
))
1152 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
1153 horizontal_drag_cursor
1154 = XCreateFontCursor (dpy
, XINT (Vx_window_horizontal_drag_shape
));
1157 horizontal_drag_cursor
1158 = XCreateFontCursor (dpy
, XC_sb_h_double_arrow
);
1160 /* Check and report errors with the above calls. */
1161 x_check_errors (dpy
, "can't set cursor shape: %s");
1162 x_uncatch_errors (dpy
, count
);
1165 XColor fore_color
, back_color
;
1167 fore_color
.pixel
= x
->mouse_pixel
;
1168 x_query_color (f
, &fore_color
);
1169 back_color
.pixel
= mask_color
;
1170 x_query_color (f
, &back_color
);
1172 XRecolorCursor (dpy
, cursor
, &fore_color
, &back_color
);
1173 XRecolorCursor (dpy
, nontext_cursor
, &fore_color
, &back_color
);
1174 XRecolorCursor (dpy
, mode_cursor
, &fore_color
, &back_color
);
1175 XRecolorCursor (dpy
, hand_cursor
, &fore_color
, &back_color
);
1176 XRecolorCursor (dpy
, hourglass_cursor
, &fore_color
, &back_color
);
1177 XRecolorCursor (dpy
, horizontal_drag_cursor
, &fore_color
, &back_color
);
1180 if (FRAME_X_WINDOW (f
) != 0)
1181 XDefineCursor (dpy
, FRAME_X_WINDOW (f
), cursor
);
1183 if (cursor
!= x
->text_cursor
1184 && x
->text_cursor
!= 0)
1185 XFreeCursor (dpy
, x
->text_cursor
);
1186 x
->text_cursor
= cursor
;
1188 if (nontext_cursor
!= x
->nontext_cursor
1189 && x
->nontext_cursor
!= 0)
1190 XFreeCursor (dpy
, x
->nontext_cursor
);
1191 x
->nontext_cursor
= nontext_cursor
;
1193 if (hourglass_cursor
!= x
->hourglass_cursor
1194 && x
->hourglass_cursor
!= 0)
1195 XFreeCursor (dpy
, x
->hourglass_cursor
);
1196 x
->hourglass_cursor
= hourglass_cursor
;
1198 if (mode_cursor
!= x
->modeline_cursor
1199 && x
->modeline_cursor
!= 0)
1200 XFreeCursor (dpy
, f
->output_data
.x
->modeline_cursor
);
1201 x
->modeline_cursor
= mode_cursor
;
1203 if (hand_cursor
!= x
->hand_cursor
1204 && x
->hand_cursor
!= 0)
1205 XFreeCursor (dpy
, x
->hand_cursor
);
1206 x
->hand_cursor
= hand_cursor
;
1208 if (horizontal_drag_cursor
!= x
->horizontal_drag_cursor
1209 && x
->horizontal_drag_cursor
!= 0)
1210 XFreeCursor (dpy
, x
->horizontal_drag_cursor
);
1211 x
->horizontal_drag_cursor
= horizontal_drag_cursor
;
1216 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1220 x_set_cursor_color (f
, arg
, oldval
)
1222 Lisp_Object arg
, oldval
;
1224 unsigned long fore_pixel
, pixel
;
1225 int fore_pixel_allocated_p
= 0, pixel_allocated_p
= 0;
1226 struct x_output
*x
= f
->output_data
.x
;
1228 if (!NILP (Vx_cursor_fore_pixel
))
1230 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1231 WHITE_PIX_DEFAULT (f
));
1232 fore_pixel_allocated_p
= 1;
1235 fore_pixel
= x
->background_pixel
;
1237 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1238 pixel_allocated_p
= 1;
1240 /* Make sure that the cursor color differs from the background color. */
1241 if (pixel
== x
->background_pixel
)
1243 if (pixel_allocated_p
)
1245 x_free_colors (f
, &pixel
, 1);
1246 pixel_allocated_p
= 0;
1249 pixel
= x
->mouse_pixel
;
1250 if (pixel
== fore_pixel
)
1252 if (fore_pixel_allocated_p
)
1254 x_free_colors (f
, &fore_pixel
, 1);
1255 fore_pixel_allocated_p
= 0;
1257 fore_pixel
= x
->background_pixel
;
1261 unload_color (f
, x
->cursor_foreground_pixel
);
1262 if (!fore_pixel_allocated_p
)
1263 fore_pixel
= x_copy_color (f
, fore_pixel
);
1264 x
->cursor_foreground_pixel
= fore_pixel
;
1266 unload_color (f
, x
->cursor_pixel
);
1267 if (!pixel_allocated_p
)
1268 pixel
= x_copy_color (f
, pixel
);
1269 x
->cursor_pixel
= pixel
;
1271 if (FRAME_X_WINDOW (f
) != 0)
1274 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
1275 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
1278 if (FRAME_VISIBLE_P (f
))
1280 x_update_cursor (f
, 0);
1281 x_update_cursor (f
, 1);
1285 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1288 /* Set the border-color of frame F to pixel value PIX.
1289 Note that this does not fully take effect if done before
1290 F has an x-window. */
1293 x_set_border_pixel (f
, pix
)
1297 unload_color (f
, f
->output_data
.x
->border_pixel
);
1298 f
->output_data
.x
->border_pixel
= pix
;
1300 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
1303 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1304 (unsigned long)pix
);
1307 if (FRAME_VISIBLE_P (f
))
1312 /* Set the border-color of frame F to value described by ARG.
1313 ARG can be a string naming a color.
1314 The border-color is used for the border that is drawn by the X server.
1315 Note that this does not fully take effect if done before
1316 F has an x-window; it must be redone when the window is created.
1318 Note: this is done in two routines because of the way X10 works.
1320 Note: under X11, this is normally the province of the window manager,
1321 and so emacs' border colors may be overridden. */
1324 x_set_border_color (f
, arg
, oldval
)
1326 Lisp_Object arg
, oldval
;
1331 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1332 x_set_border_pixel (f
, pix
);
1333 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1338 x_set_cursor_type (f
, arg
, oldval
)
1340 Lisp_Object arg
, oldval
;
1342 set_frame_cursor_types (f
, arg
);
1344 /* Make sure the cursor gets redrawn. */
1345 cursor_type_changed
= 1;
1349 x_set_icon_type (f
, arg
, oldval
)
1351 Lisp_Object arg
, oldval
;
1357 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1360 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1365 result
= x_text_icon (f
,
1366 (char *) SDATA ((!NILP (f
->icon_name
)
1370 result
= x_bitmap_icon (f
, arg
);
1375 error ("No icon window available");
1378 XFlush (FRAME_X_DISPLAY (f
));
1383 x_set_icon_name (f
, arg
, oldval
)
1385 Lisp_Object arg
, oldval
;
1391 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1394 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1399 if (f
->output_data
.x
->icon_bitmap
!= 0)
1404 result
= x_text_icon (f
,
1405 (char *) SDATA ((!NILP (f
->icon_name
)
1414 error ("No icon window available");
1417 XFlush (FRAME_X_DISPLAY (f
));
1423 x_set_menu_bar_lines (f
, value
, oldval
)
1425 Lisp_Object value
, oldval
;
1428 #ifndef USE_X_TOOLKIT
1429 int olines
= FRAME_MENU_BAR_LINES (f
);
1432 /* Right now, menu bars don't work properly in minibuf-only frames;
1433 most of the commands try to apply themselves to the minibuffer
1434 frame itself, and get an error because you can't switch buffers
1435 in or split the minibuffer window. */
1436 if (FRAME_MINIBUF_ONLY_P (f
))
1439 if (INTEGERP (value
))
1440 nlines
= XINT (value
);
1444 /* Make sure we redisplay all windows in this frame. */
1445 windows_or_buffers_changed
++;
1447 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1448 FRAME_MENU_BAR_LINES (f
) = 0;
1451 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1452 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1453 /* Make sure next redisplay shows the menu bar. */
1454 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1458 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1459 free_frame_menubar (f
);
1460 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1462 f
->output_data
.x
->menubar_widget
= 0;
1464 #else /* not USE_X_TOOLKIT && not USE_GTK */
1465 FRAME_MENU_BAR_LINES (f
) = nlines
;
1466 change_window_heights (f
->root_window
, nlines
- olines
);
1467 #endif /* not USE_X_TOOLKIT */
1472 /* Set the number of lines used for the tool bar of frame F to VALUE.
1473 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1474 is the old number of tool bar lines. This function changes the
1475 height of all windows on frame F to match the new tool bar height.
1476 The frame's height doesn't change. */
1479 x_set_tool_bar_lines (f
, value
, oldval
)
1481 Lisp_Object value
, oldval
;
1483 int delta
, nlines
, root_height
;
1484 Lisp_Object root_window
;
1486 /* Treat tool bars like menu bars. */
1487 if (FRAME_MINIBUF_ONLY_P (f
))
1490 /* Use VALUE only if an integer >= 0. */
1491 if (INTEGERP (value
) && XINT (value
) >= 0)
1492 nlines
= XFASTINT (value
);
1497 FRAME_TOOL_BAR_LINES (f
) = 0;
1500 FRAME_EXTERNAL_TOOL_BAR (f
) = 1;
1501 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1502 /* Make sure next redisplay shows the tool bar. */
1503 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1504 update_frame_tool_bar (f
);
1508 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1509 free_frame_tool_bar (f
);
1510 FRAME_EXTERNAL_TOOL_BAR (f
) = 0;
1516 /* Make sure we redisplay all windows in this frame. */
1517 ++windows_or_buffers_changed
;
1519 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
1521 /* Don't resize the tool-bar to more than we have room for. */
1522 root_window
= FRAME_ROOT_WINDOW (f
);
1523 root_height
= WINDOW_TOTAL_LINES (XWINDOW (root_window
));
1524 if (root_height
- delta
< 1)
1526 delta
= root_height
- 1;
1527 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
1530 FRAME_TOOL_BAR_LINES (f
) = nlines
;
1531 change_window_heights (root_window
, delta
);
1534 /* We also have to make sure that the internal border at the top of
1535 the frame, below the menu bar or tool bar, is redrawn when the
1536 tool bar disappears. This is so because the internal border is
1537 below the tool bar if one is displayed, but is below the menu bar
1538 if there isn't a tool bar. The tool bar draws into the area
1539 below the menu bar. */
1540 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
1544 clear_current_matrices (f
);
1545 updating_frame
= NULL
;
1548 /* If the tool bar gets smaller, the internal border below it
1549 has to be cleared. It was formerly part of the display
1550 of the larger tool bar, and updating windows won't clear it. */
1553 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1554 int width
= FRAME_PIXEL_WIDTH (f
);
1555 int y
= nlines
* FRAME_LINE_HEIGHT (f
);
1558 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1559 0, y
, width
, height
, False
);
1562 if (WINDOWP (f
->tool_bar_window
))
1563 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1568 /* Set the foreground color for scroll bars on frame F to VALUE.
1569 VALUE should be a string, a color name. If it isn't a string or
1570 isn't a valid color name, do nothing. OLDVAL is the old value of
1571 the frame parameter. */
1574 x_set_scroll_bar_foreground (f
, value
, oldval
)
1576 Lisp_Object value
, oldval
;
1578 unsigned long pixel
;
1580 if (STRINGP (value
))
1581 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1585 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1586 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1588 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1589 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1591 /* Remove all scroll bars because they have wrong colors. */
1592 if (condemn_scroll_bars_hook
)
1593 (*condemn_scroll_bars_hook
) (f
);
1594 if (judge_scroll_bars_hook
)
1595 (*judge_scroll_bars_hook
) (f
);
1597 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1603 /* Set the background color for scroll bars on frame F to VALUE VALUE
1604 should be a string, a color name. If it isn't a string or isn't a
1605 valid color name, do nothing. OLDVAL is the old value of the frame
1609 x_set_scroll_bar_background (f
, value
, oldval
)
1611 Lisp_Object value
, oldval
;
1613 unsigned long pixel
;
1615 if (STRINGP (value
))
1616 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1620 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1621 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1623 #ifdef USE_TOOLKIT_SCROLL_BARS
1624 /* Scrollbar shadow colors. */
1625 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1627 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1628 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1630 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1632 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1633 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1635 #endif /* USE_TOOLKIT_SCROLL_BARS */
1637 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1638 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1640 /* Remove all scroll bars because they have wrong colors. */
1641 if (condemn_scroll_bars_hook
)
1642 (*condemn_scroll_bars_hook
) (f
);
1643 if (judge_scroll_bars_hook
)
1644 (*judge_scroll_bars_hook
) (f
);
1646 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1652 /* Encode Lisp string STRING as a text in a format appropriate for
1653 XICCC (X Inter Client Communication Conventions).
1655 If STRING contains only ASCII characters, do no conversion and
1656 return the string data of STRING. Otherwise, encode the text by
1657 CODING_SYSTEM, and return a newly allocated memory area which
1658 should be freed by `xfree' by a caller.
1660 SELECTIONP non-zero means the string is being encoded for an X
1661 selection, so it is safe to run pre-write conversions (which
1664 Store the byte length of resulting text in *TEXT_BYTES.
1666 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1667 which means that the `encoding' of the result can be `STRING'.
1668 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1669 the result should be `COMPOUND_TEXT'. */
1672 x_encode_text (string
, coding_system
, selectionp
, text_bytes
, stringp
)
1673 Lisp_Object string
, coding_system
;
1674 int *text_bytes
, *stringp
;
1677 unsigned char *str
= SDATA (string
);
1678 int chars
= SCHARS (string
);
1679 int bytes
= SBYTES (string
);
1683 struct coding_system coding
;
1684 extern Lisp_Object Qcompound_text_with_extensions
;
1686 charset_info
= find_charset_in_text (str
, chars
, bytes
, NULL
, Qnil
);
1687 if (charset_info
== 0)
1689 /* No multibyte character in OBJ. We need not encode it. */
1690 *text_bytes
= bytes
;
1695 setup_coding_system (coding_system
, &coding
);
1697 && SYMBOLP (coding
.pre_write_conversion
)
1698 && !NILP (Ffboundp (coding
.pre_write_conversion
)))
1700 string
= run_pre_post_conversion_on_str (string
, &coding
, 1);
1701 str
= SDATA (string
);
1702 chars
= SCHARS (string
);
1703 bytes
= SBYTES (string
);
1705 coding
.src_multibyte
= 1;
1706 coding
.dst_multibyte
= 0;
1707 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1708 if (coding
.type
== coding_type_iso2022
)
1709 coding
.flags
|= CODING_FLAG_ISO_SAFE
;
1710 /* We suppress producing escape sequences for composition. */
1711 coding
.composing
= COMPOSITION_DISABLED
;
1712 bufsize
= encoding_buffer_size (&coding
, bytes
);
1713 buf
= (unsigned char *) xmalloc (bufsize
);
1714 encode_coding (&coding
, str
, buf
, bytes
, bufsize
);
1715 *text_bytes
= coding
.produced
;
1716 *stringp
= (charset_info
== 1
1717 || (!EQ (coding_system
, Qcompound_text
)
1718 && !EQ (coding_system
, Qcompound_text_with_extensions
)));
1723 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1726 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1727 name; if NAME is a string, set F's name to NAME and set
1728 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1730 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1731 suggesting a new name, which lisp code should override; if
1732 F->explicit_name is set, ignore the new name; otherwise, set it. */
1735 x_set_name (f
, name
, explicit)
1740 /* Make sure that requests from lisp code override requests from
1741 Emacs redisplay code. */
1744 /* If we're switching from explicit to implicit, we had better
1745 update the mode lines and thereby update the title. */
1746 if (f
->explicit_name
&& NILP (name
))
1747 update_mode_lines
= 1;
1749 f
->explicit_name
= ! NILP (name
);
1751 else if (f
->explicit_name
)
1754 /* If NAME is nil, set the name to the x_id_name. */
1757 /* Check for no change needed in this very common case
1758 before we do any consing. */
1759 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1762 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1765 CHECK_STRING (name
);
1767 /* Don't change the name if it's already NAME. */
1768 if (! NILP (Fstring_equal (name
, f
->name
)))
1773 /* For setting the frame title, the title parameter should override
1774 the name parameter. */
1775 if (! NILP (f
->title
))
1778 if (FRAME_X_WINDOW (f
))
1783 XTextProperty text
, icon
;
1785 Lisp_Object coding_system
;
1787 /* Note: Encoding strategy
1789 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1790 text.encoding. But, there are non-internationalized window
1791 managers which don't support that encoding. So, if NAME
1792 contains only ASCII and 8859-1 characters, encode it by
1793 iso-latin-1, and use "STRING" in text.encoding hoping that
1794 such window manager at least analize this format correctly,
1795 i.e. treat 8-bit bytes as 8859-1 characters.
1797 We may also be able to use "UTF8_STRING" in text.encoding
1798 in the feature which can encode all Unicode characters.
1799 But, for the moment, there's no way to know that the
1800 current window manager supports it or not. */
1801 coding_system
= Qcompound_text
;
1802 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
1803 text
.encoding
= (stringp
? XA_STRING
1804 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1806 text
.nitems
= bytes
;
1808 if (NILP (f
->icon_name
))
1814 /* See the above comment "Note: Encoding strategy". */
1815 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
1817 icon
.encoding
= (stringp
? XA_STRING
1818 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1820 icon
.nitems
= bytes
;
1823 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1825 #else /* not USE_GTK */
1826 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1827 #endif /* not USE_GTK */
1829 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1831 if (!NILP (f
->icon_name
)
1832 && icon
.value
!= (unsigned char *) SDATA (f
->icon_name
))
1834 if (text
.value
!= (unsigned char *) SDATA (name
))
1837 #else /* not HAVE_X11R4 */
1838 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1840 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1842 #endif /* not HAVE_X11R4 */
1847 /* This function should be called when the user's lisp code has
1848 specified a name for the frame; the name will override any set by the
1851 x_explicitly_set_name (f
, arg
, oldval
)
1853 Lisp_Object arg
, oldval
;
1855 x_set_name (f
, arg
, 1);
1858 /* This function should be called by Emacs redisplay code to set the
1859 name; names set this way will never override names set by the user's
1862 x_implicitly_set_name (f
, arg
, oldval
)
1864 Lisp_Object arg
, oldval
;
1866 x_set_name (f
, arg
, 0);
1869 /* Change the title of frame F to NAME.
1870 If NAME is nil, use the frame name as the title.
1872 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1873 name; if NAME is a string, set F's name to NAME and set
1874 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1876 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1877 suggesting a new name, which lisp code should override; if
1878 F->explicit_name is set, ignore the new name; otherwise, set it. */
1881 x_set_title (f
, name
, old_name
)
1883 Lisp_Object name
, old_name
;
1885 /* Don't change the title if it's already NAME. */
1886 if (EQ (name
, f
->title
))
1889 update_mode_lines
= 1;
1896 CHECK_STRING (name
);
1898 if (FRAME_X_WINDOW (f
))
1903 XTextProperty text
, icon
;
1905 Lisp_Object coding_system
;
1907 coding_system
= Qcompound_text
;
1908 /* See the comment "Note: Encoding strategy" in x_set_name. */
1909 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
1910 text
.encoding
= (stringp
? XA_STRING
1911 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1913 text
.nitems
= bytes
;
1915 if (NILP (f
->icon_name
))
1921 /* See the comment "Note: Encoding strategy" in x_set_name. */
1922 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
1924 icon
.encoding
= (stringp
? XA_STRING
1925 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1927 icon
.nitems
= bytes
;
1931 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1933 #else /* not USE_GTK */
1934 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1935 #endif /* not USE_GTK */
1937 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
1940 if (!NILP (f
->icon_name
)
1941 && icon
.value
!= (unsigned char *) SDATA (f
->icon_name
))
1943 if (text
.value
!= (unsigned char *) SDATA (name
))
1946 #else /* not HAVE_X11R4 */
1947 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1949 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1951 #endif /* not HAVE_X11R4 */
1957 x_set_scroll_bar_default_width (f
)
1960 int wid
= FRAME_COLUMN_WIDTH (f
);
1962 #ifdef USE_TOOLKIT_SCROLL_BARS
1963 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1964 int width
= 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
1965 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (width
+ wid
- 1) / wid
;
1966 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = width
;
1968 /* Make the actual width at least 14 pixels and a multiple of a
1970 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
1972 /* Use all of that space (aside from required margins) for the
1974 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = 0;
1979 /* Record in frame F the specified or default value according to ALIST
1980 of the parameter named PROP (a Lisp symbol). If no value is
1981 specified for PROP, look for an X default for XPROP on the frame
1982 named NAME. If that is not found either, use the value DEFLT. */
1985 x_default_scroll_bar_color_parameter (f
, alist
, prop
, xprop
, xclass
,
1994 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
1997 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
1998 if (EQ (tem
, Qunbound
))
2000 #ifdef USE_TOOLKIT_SCROLL_BARS
2002 /* See if an X resource for the scroll bar color has been
2004 tem
= display_x_get_resource (dpyinfo
,
2005 build_string (foreground_p
2009 build_string ("verticalScrollBar"),
2013 /* If nothing has been specified, scroll bars will use a
2014 toolkit-dependent default. Because these defaults are
2015 difficult to get at without actually creating a scroll
2016 bar, use nil to indicate that no color has been
2021 #else /* not USE_TOOLKIT_SCROLL_BARS */
2025 #endif /* not USE_TOOLKIT_SCROLL_BARS */
2028 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2034 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2037 XSetWMProtocols (dpy
, w
, protocols
, count
)
2044 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2045 if (prop
== None
) return False
;
2046 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2047 (unsigned char *) protocols
, count
);
2050 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2052 #ifdef USE_X_TOOLKIT
2054 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2055 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2056 already be present because of the toolkit (Motif adds some of them,
2057 for example, but Xt doesn't). */
2060 hack_wm_protocols (f
, widget
)
2064 Display
*dpy
= XtDisplay (widget
);
2065 Window w
= XtWindow (widget
);
2066 int need_delete
= 1;
2072 Atom type
, *atoms
= 0;
2074 unsigned long nitems
= 0;
2075 unsigned long bytes_after
;
2077 if ((XGetWindowProperty (dpy
, w
,
2078 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2079 (long)0, (long)100, False
, XA_ATOM
,
2080 &type
, &format
, &nitems
, &bytes_after
,
2081 (unsigned char **) &atoms
)
2083 && format
== 32 && type
== XA_ATOM
)
2087 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2089 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2091 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2094 if (atoms
) XFree ((char *) atoms
);
2100 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2102 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2104 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2106 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2107 XA_ATOM
, 32, PropModeAppend
,
2108 (unsigned char *) props
, count
);
2116 /* Support routines for XIC (X Input Context). */
2120 static XFontSet xic_create_xfontset
P_ ((struct frame
*, char *));
2121 static XIMStyle best_xim_style
P_ ((XIMStyles
*, XIMStyles
*));
2124 /* Supported XIM styles, ordered by preference. */
2126 static XIMStyle supported_xim_styles
[] =
2128 XIMPreeditPosition
| XIMStatusArea
,
2129 XIMPreeditPosition
| XIMStatusNothing
,
2130 XIMPreeditPosition
| XIMStatusNone
,
2131 XIMPreeditNothing
| XIMStatusArea
,
2132 XIMPreeditNothing
| XIMStatusNothing
,
2133 XIMPreeditNothing
| XIMStatusNone
,
2134 XIMPreeditNone
| XIMStatusArea
,
2135 XIMPreeditNone
| XIMStatusNothing
,
2136 XIMPreeditNone
| XIMStatusNone
,
2141 /* Create an X fontset on frame F with base font name
2145 xic_create_xfontset (f
, base_fontname
)
2147 char *base_fontname
;
2150 char **missing_list
;
2154 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
),
2155 base_fontname
, &missing_list
,
2156 &missing_count
, &def_string
);
2158 XFreeStringList (missing_list
);
2160 /* No need to free def_string. */
2165 /* Value is the best input style, given user preferences USER (already
2166 checked to be supported by Emacs), and styles supported by the
2167 input method XIM. */
2170 best_xim_style (user
, xim
)
2176 for (i
= 0; i
< user
->count_styles
; ++i
)
2177 for (j
= 0; j
< xim
->count_styles
; ++j
)
2178 if (user
->supported_styles
[i
] == xim
->supported_styles
[j
])
2179 return user
->supported_styles
[i
];
2181 /* Return the default style. */
2182 return XIMPreeditNothing
| XIMStatusNothing
;
2185 /* Create XIC for frame F. */
2187 static XIMStyle xic_style
;
2190 create_frame_xic (f
)
2195 XFontSet xfs
= NULL
;
2200 xim
= FRAME_X_XIM (f
);
2205 XVaNestedList preedit_attr
;
2206 XVaNestedList status_attr
;
2207 char *base_fontname
;
2210 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2211 spot
.x
= 0; spot
.y
= 1;
2212 /* Create X fontset. */
2213 fontset
= FRAME_FONTSET (f
);
2215 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2218 /* Determine the base fontname from the ASCII font name of
2220 char *ascii_font
= (char *) SDATA (fontset_ascii (fontset
));
2221 char *p
= ascii_font
;
2224 for (i
= 0; *p
; p
++)
2227 /* As the font name doesn't conform to XLFD, we can't
2228 modify it to get a suitable base fontname for the
2230 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2233 int len
= strlen (ascii_font
) + 1;
2236 for (i
= 0, p
= ascii_font
; i
< 8; p
++)
2245 base_fontname
= (char *) alloca (len
);
2246 bzero (base_fontname
, len
);
2247 strcpy (base_fontname
, "-*-*-");
2248 bcopy (p1
, base_fontname
+ 5, p
- p1
);
2249 strcat (base_fontname
, "*-*-*-*-*-*-*");
2252 xfs
= xic_create_xfontset (f
, base_fontname
);
2254 /* Determine XIC style. */
2257 XIMStyles supported_list
;
2258 supported_list
.count_styles
= (sizeof supported_xim_styles
2259 / sizeof supported_xim_styles
[0]);
2260 supported_list
.supported_styles
= supported_xim_styles
;
2261 xic_style
= best_xim_style (&supported_list
,
2262 FRAME_X_XIM_STYLES (f
));
2265 preedit_attr
= XVaCreateNestedList (0,
2268 FRAME_FOREGROUND_PIXEL (f
),
2270 FRAME_BACKGROUND_PIXEL (f
),
2271 (xic_style
& XIMPreeditPosition
2276 status_attr
= XVaCreateNestedList (0,
2282 FRAME_FOREGROUND_PIXEL (f
),
2284 FRAME_BACKGROUND_PIXEL (f
),
2287 xic
= XCreateIC (xim
,
2288 XNInputStyle
, xic_style
,
2289 XNClientWindow
, FRAME_X_WINDOW(f
),
2290 XNFocusWindow
, FRAME_X_WINDOW(f
),
2291 XNStatusAttributes
, status_attr
,
2292 XNPreeditAttributes
, preedit_attr
,
2294 XFree (preedit_attr
);
2295 XFree (status_attr
);
2298 FRAME_XIC (f
) = xic
;
2299 FRAME_XIC_STYLE (f
) = xic_style
;
2300 FRAME_XIC_FONTSET (f
) = xfs
;
2304 /* Destroy XIC and free XIC fontset of frame F, if any. */
2310 if (FRAME_XIC (f
) == NULL
)
2313 XDestroyIC (FRAME_XIC (f
));
2314 if (FRAME_XIC_FONTSET (f
))
2315 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2317 FRAME_XIC (f
) = NULL
;
2318 FRAME_XIC_FONTSET (f
) = NULL
;
2322 /* Place preedit area for XIC of window W's frame to specified
2323 pixel position X/Y. X and Y are relative to window W. */
2326 xic_set_preeditarea (w
, x
, y
)
2330 struct frame
*f
= XFRAME (w
->frame
);
2334 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
);
2335 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2336 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2337 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2342 /* Place status area for XIC in bottom right corner of frame F.. */
2345 xic_set_statusarea (f
)
2348 XIC xic
= FRAME_XIC (f
);
2353 /* Negotiate geometry of status area. If input method has existing
2354 status area, use its current size. */
2355 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2356 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2357 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2360 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2361 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2364 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2366 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2367 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2371 area
.width
= needed
->width
;
2372 area
.height
= needed
->height
;
2373 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2374 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2375 - FRAME_MENUBAR_HEIGHT (f
)
2376 - FRAME_TOOLBAR_HEIGHT (f
)
2377 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2380 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2381 XSetICValues(xic
, XNStatusAttributes
, attr
, NULL
);
2386 /* Set X fontset for XIC of frame F, using base font name
2387 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2390 xic_set_xfontset (f
, base_fontname
)
2392 char *base_fontname
;
2397 xfs
= xic_create_xfontset (f
, base_fontname
);
2399 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2400 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2401 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2402 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2403 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2406 if (FRAME_XIC_FONTSET (f
))
2407 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2408 FRAME_XIC_FONTSET (f
) = xfs
;
2411 #endif /* HAVE_X_I18N */
2415 #ifdef USE_X_TOOLKIT
2417 /* Create and set up the X widget for frame F. */
2420 x_window (f
, window_prompting
, minibuffer_only
)
2422 long window_prompting
;
2423 int minibuffer_only
;
2425 XClassHint class_hints
;
2426 XSetWindowAttributes attributes
;
2427 unsigned long attribute_mask
;
2428 Widget shell_widget
;
2430 Widget frame_widget
;
2436 /* Use the resource name as the top-level widget name
2437 for looking up resources. Make a non-Lisp copy
2438 for the window manager, so GC relocation won't bother it.
2440 Elsewhere we specify the window name for the window manager. */
2443 char *str
= (char *) SDATA (Vx_resource_name
);
2444 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2445 strcpy (f
->namebuf
, str
);
2449 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2450 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2451 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2452 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2453 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2454 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2455 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2456 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2457 applicationShellWidgetClass
,
2458 FRAME_X_DISPLAY (f
), al
, ac
);
2460 f
->output_data
.x
->widget
= shell_widget
;
2461 /* maybe_set_screen_title_format (shell_widget); */
2463 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2464 (widget_value
*) NULL
,
2465 shell_widget
, False
,
2469 (lw_callback
) NULL
);
2472 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2473 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2474 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2475 XtSetValues (pane_widget
, al
, ac
);
2476 f
->output_data
.x
->column_widget
= pane_widget
;
2478 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2479 the emacs screen when changing menubar. This reduces flickering. */
2482 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2483 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2484 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2485 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2486 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2487 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2488 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2489 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2490 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2493 f
->output_data
.x
->edit_widget
= frame_widget
;
2495 XtManageChild (frame_widget
);
2497 /* Do some needed geometry management. */
2500 char *tem
, shell_position
[32];
2503 int extra_borders
= 0;
2505 = (f
->output_data
.x
->menubar_widget
2506 ? (f
->output_data
.x
->menubar_widget
->core
.height
2507 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2510 #if 0 /* Experimentally, we now get the right results
2511 for -geometry -0-0 without this. 24 Aug 96, rms. */
2512 if (FRAME_EXTERNAL_MENU_BAR (f
))
2515 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2516 menubar_size
+= ibw
;
2520 f
->output_data
.x
->menubar_height
= menubar_size
;
2523 /* Motif seems to need this amount added to the sizes
2524 specified for the shell widget. The Athena/Lucid widgets don't.
2525 Both conclusions reached experimentally. -- rms. */
2526 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2527 &extra_borders
, NULL
);
2531 /* Convert our geometry parameters into a geometry string
2533 Note that we do not specify here whether the position
2534 is a user-specified or program-specified one.
2535 We pass that information later, in x_wm_set_size_hints. */
2537 int left
= f
->left_pos
;
2538 int xneg
= window_prompting
& XNegative
;
2539 int top
= f
->top_pos
;
2540 int yneg
= window_prompting
& YNegative
;
2546 if (window_prompting
& USPosition
)
2547 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2548 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2549 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2550 (xneg
? '-' : '+'), left
,
2551 (yneg
? '-' : '+'), top
);
2553 sprintf (shell_position
, "=%dx%d",
2554 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2555 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2558 len
= strlen (shell_position
) + 1;
2559 /* We don't free this because we don't know whether
2560 it is safe to free it while the frame exists.
2561 It isn't worth the trouble of arranging to free it
2562 when the frame is deleted. */
2563 tem
= (char *) xmalloc (len
);
2564 strncpy (tem
, shell_position
, len
);
2565 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2566 XtSetValues (shell_widget
, al
, ac
);
2569 XtManageChild (pane_widget
);
2570 XtRealizeWidget (shell_widget
);
2572 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2574 validate_x_resource_name ();
2576 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2577 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2578 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2581 FRAME_XIC (f
) = NULL
;
2583 create_frame_xic (f
);
2586 f
->output_data
.x
->wm_hints
.input
= True
;
2587 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2588 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2589 &f
->output_data
.x
->wm_hints
);
2591 hack_wm_protocols (f
, shell_widget
);
2594 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2597 /* Do a stupid property change to force the server to generate a
2598 PropertyNotify event so that the event_stream server timestamp will
2599 be initialized to something relevant to the time we created the window.
2601 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2602 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2603 XA_ATOM
, 32, PropModeAppend
,
2604 (unsigned char*) NULL
, 0);
2606 /* Make all the standard events reach the Emacs frame. */
2607 attributes
.event_mask
= STANDARD_EVENT_SET
;
2612 /* XIM server might require some X events. */
2613 unsigned long fevent
= NoEventMask
;
2614 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2615 attributes
.event_mask
|= fevent
;
2617 #endif /* HAVE_X_I18N */
2619 attribute_mask
= CWEventMask
;
2620 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2621 attribute_mask
, &attributes
);
2623 XtMapWidget (frame_widget
);
2625 /* x_set_name normally ignores requests to set the name if the
2626 requested name is the same as the current name. This is the one
2627 place where that assumption isn't correct; f->name is set, but
2628 the X server hasn't been told. */
2631 int explicit = f
->explicit_name
;
2633 f
->explicit_name
= 0;
2636 x_set_name (f
, name
, explicit);
2639 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2640 f
->output_data
.x
->text_cursor
);
2644 /* This is a no-op, except under Motif. Make sure main areas are
2645 set to something reasonable, in case we get an error later. */
2646 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2649 #else /* not USE_X_TOOLKIT */
2655 if (! xg_create_frame_widgets (f
))
2656 error ("Unable to create window");
2659 FRAME_XIC (f
) = NULL
;
2663 create_frame_xic (f
);
2666 /* XIM server might require some X events. */
2667 unsigned long fevent
= NoEventMask
;
2668 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2670 if (fevent
!= NoEventMask
)
2672 XSetWindowAttributes attributes
;
2673 XWindowAttributes wattr
;
2674 unsigned long attribute_mask
;
2676 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2678 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2679 attribute_mask
= CWEventMask
;
2680 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2681 attribute_mask
, &attributes
);
2689 #else /*! USE_GTK */
2690 /* Create and set up the X window for frame F. */
2697 XClassHint class_hints
;
2698 XSetWindowAttributes attributes
;
2699 unsigned long attribute_mask
;
2701 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2702 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2703 attributes
.bit_gravity
= StaticGravity
;
2704 attributes
.backing_store
= NotUseful
;
2705 attributes
.save_under
= True
;
2706 attributes
.event_mask
= STANDARD_EVENT_SET
;
2707 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2708 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2713 = XCreateWindow (FRAME_X_DISPLAY (f
),
2714 f
->output_data
.x
->parent_desc
,
2717 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2719 CopyFromParent
, /* depth */
2720 InputOutput
, /* class */
2722 attribute_mask
, &attributes
);
2727 create_frame_xic (f
);
2730 /* XIM server might require some X events. */
2731 unsigned long fevent
= NoEventMask
;
2732 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2733 attributes
.event_mask
|= fevent
;
2734 attribute_mask
= CWEventMask
;
2735 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2736 attribute_mask
, &attributes
);
2739 #endif /* HAVE_X_I18N */
2741 validate_x_resource_name ();
2743 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2744 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2745 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2747 /* The menubar is part of the ordinary display;
2748 it does not count in addition to the height of the window. */
2749 f
->output_data
.x
->menubar_height
= 0;
2751 /* This indicates that we use the "Passive Input" input model.
2752 Unless we do this, we don't get the Focus{In,Out} events that we
2753 need to draw the cursor correctly. Accursed bureaucrats.
2754 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2756 f
->output_data
.x
->wm_hints
.input
= True
;
2757 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2758 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2759 &f
->output_data
.x
->wm_hints
);
2760 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2762 /* Request "save yourself" and "delete window" commands from wm. */
2765 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2766 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2767 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2770 /* x_set_name normally ignores requests to set the name if the
2771 requested name is the same as the current name. This is the one
2772 place where that assumption isn't correct; f->name is set, but
2773 the X server hasn't been told. */
2776 int explicit = f
->explicit_name
;
2778 f
->explicit_name
= 0;
2781 x_set_name (f
, name
, explicit);
2784 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2785 f
->output_data
.x
->text_cursor
);
2789 if (FRAME_X_WINDOW (f
) == 0)
2790 error ("Unable to create window");
2793 #endif /* not USE_GTK */
2794 #endif /* not USE_X_TOOLKIT */
2796 /* Handle the icon stuff for this window. Perhaps later we might
2797 want an x_set_icon_position which can be called interactively as
2805 Lisp_Object icon_x
, icon_y
;
2806 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2808 /* Set the position of the icon. Note that twm groups all
2809 icons in an icon window. */
2810 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2811 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2812 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2814 CHECK_NUMBER (icon_x
);
2815 CHECK_NUMBER (icon_y
);
2817 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2818 error ("Both left and top icon corners of icon must be specified");
2822 if (! EQ (icon_x
, Qunbound
))
2823 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2825 /* Start up iconic or window? */
2826 x_wm_set_window_state
2827 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
2832 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
2839 /* Make the GCs needed for this window, setting the
2840 background, border and mouse colors; also create the
2841 mouse cursor and the gray border tile. */
2843 static char cursor_bits
[] =
2845 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2847 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2848 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2855 XGCValues gc_values
;
2859 /* Create the GCs of this frame.
2860 Note that many default values are used. */
2863 gc_values
.font
= FRAME_FONT (f
)->fid
;
2864 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
2865 gc_values
.background
= f
->output_data
.x
->background_pixel
;
2866 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2867 f
->output_data
.x
->normal_gc
2868 = XCreateGC (FRAME_X_DISPLAY (f
),
2870 GCLineWidth
| GCFont
| GCForeground
| GCBackground
,
2873 /* Reverse video style. */
2874 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
2875 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
2876 f
->output_data
.x
->reverse_gc
2877 = XCreateGC (FRAME_X_DISPLAY (f
),
2879 GCFont
| GCForeground
| GCBackground
| GCLineWidth
,
2882 /* Cursor has cursor-color background, background-color foreground. */
2883 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
2884 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
2885 gc_values
.fill_style
= FillOpaqueStippled
;
2887 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
2888 FRAME_X_DISPLAY_INFO (f
)->root_window
,
2889 cursor_bits
, 16, 16);
2890 f
->output_data
.x
->cursor_gc
2891 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2892 (GCFont
| GCForeground
| GCBackground
2893 | GCFillStyle
/* | GCStipple */ | GCLineWidth
),
2897 f
->output_data
.x
->white_relief
.gc
= 0;
2898 f
->output_data
.x
->black_relief
.gc
= 0;
2900 /* Create the gray border tile used when the pointer is not in
2901 the frame. Since this depends on the frame's pixel values,
2902 this must be done on a per-frame basis. */
2903 f
->output_data
.x
->border_tile
2904 = (XCreatePixmapFromBitmapData
2905 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
2906 gray_bits
, gray_width
, gray_height
,
2907 f
->output_data
.x
->foreground_pixel
,
2908 f
->output_data
.x
->background_pixel
,
2909 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
2915 /* Free what was was allocated in x_make_gc. */
2921 Display
*dpy
= FRAME_X_DISPLAY (f
);
2925 if (f
->output_data
.x
->normal_gc
)
2927 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
2928 f
->output_data
.x
->normal_gc
= 0;
2931 if (f
->output_data
.x
->reverse_gc
)
2933 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
2934 f
->output_data
.x
->reverse_gc
= 0;
2937 if (f
->output_data
.x
->cursor_gc
)
2939 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
2940 f
->output_data
.x
->cursor_gc
= 0;
2943 if (f
->output_data
.x
->border_tile
)
2945 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
2946 f
->output_data
.x
->border_tile
= 0;
2953 /* Handler for signals raised during x_create_frame and
2954 x_create_top_frame. FRAME is the frame which is partially
2958 unwind_create_frame (frame
)
2961 struct frame
*f
= XFRAME (frame
);
2963 /* If frame is ``official'', nothing to do. */
2964 if (!CONSP (Vframe_list
) || !EQ (XCAR (Vframe_list
), frame
))
2967 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2970 x_free_frame_resources (f
);
2972 /* Check that reference counts are indeed correct. */
2973 xassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
2974 xassert (dpyinfo
->image_cache
->refcount
== image_cache_refcount
);
2982 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2984 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
2985 Returns an Emacs frame object.
2986 ALIST is an alist of frame parameters.
2987 If the parameters specify that the frame should not have a minibuffer,
2988 and do not specify a specific minibuffer window to use,
2989 then `default-minibuffer-frame' must be a frame whose minibuffer can
2990 be shared by the new frame.
2992 This function is an internal primitive--use `make-frame' instead. */)
2997 Lisp_Object frame
, tem
;
2999 int minibuffer_only
= 0;
3000 long window_prompting
= 0;
3002 int count
= SPECPDL_INDEX ();
3003 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3004 Lisp_Object display
;
3005 struct x_display_info
*dpyinfo
= NULL
;
3011 /* Use this general default value to start with
3012 until we know if this frame has a specified name. */
3013 Vx_resource_name
= Vinvocation_name
;
3015 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3016 if (EQ (display
, Qunbound
))
3018 dpyinfo
= check_x_display_info (display
);
3020 kb
= dpyinfo
->kboard
;
3022 kb
= &the_only_kboard
;
3025 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3027 && ! EQ (name
, Qunbound
)
3029 error ("Invalid frame name--not a string or nil");
3032 Vx_resource_name
= name
;
3034 /* See if parent window is specified. */
3035 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3036 if (EQ (parent
, Qunbound
))
3038 if (! NILP (parent
))
3039 CHECK_NUMBER (parent
);
3041 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3042 /* No need to protect DISPLAY because that's not used after passing
3043 it to make_frame_without_minibuffer. */
3045 GCPRO4 (parms
, parent
, name
, frame
);
3046 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3048 if (EQ (tem
, Qnone
) || NILP (tem
))
3049 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3050 else if (EQ (tem
, Qonly
))
3052 f
= make_minibuffer_frame ();
3053 minibuffer_only
= 1;
3055 else if (WINDOWP (tem
))
3056 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3060 XSETFRAME (frame
, f
);
3062 /* Note that X Windows does support scroll bars. */
3063 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3065 f
->output_method
= output_x_window
;
3066 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3067 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3068 f
->output_data
.x
->icon_bitmap
= -1;
3069 FRAME_FONTSET (f
) = -1;
3070 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3071 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3072 #ifdef USE_TOOLKIT_SCROLL_BARS
3073 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3074 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3075 #endif /* USE_TOOLKIT_SCROLL_BARS */
3076 record_unwind_protect (unwind_create_frame
, frame
);
3079 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3081 if (! STRINGP (f
->icon_name
))
3082 f
->icon_name
= Qnil
;
3084 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3086 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
3087 dpyinfo_refcount
= dpyinfo
->reference_count
;
3088 #endif /* GLYPH_DEBUG */
3090 FRAME_KBOARD (f
) = kb
;
3093 /* These colors will be set anyway later, but it's important
3094 to get the color reference counts right, so initialize them! */
3097 struct gcpro gcpro1
;
3099 /* Function x_decode_color can signal an error. Make
3100 sure to initialize color slots so that we won't try
3101 to free colors we haven't allocated. */
3102 f
->output_data
.x
->foreground_pixel
= -1;
3103 f
->output_data
.x
->background_pixel
= -1;
3104 f
->output_data
.x
->cursor_pixel
= -1;
3105 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3106 f
->output_data
.x
->border_pixel
= -1;
3107 f
->output_data
.x
->mouse_pixel
= -1;
3109 black
= build_string ("black");
3111 f
->output_data
.x
->foreground_pixel
3112 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3113 f
->output_data
.x
->background_pixel
3114 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3115 f
->output_data
.x
->cursor_pixel
3116 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3117 f
->output_data
.x
->cursor_foreground_pixel
3118 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3119 f
->output_data
.x
->border_pixel
3120 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3121 f
->output_data
.x
->mouse_pixel
3122 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3126 /* Specify the parent under which to make this X window. */
3130 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3131 f
->output_data
.x
->explicit_parent
= 1;
3135 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3136 f
->output_data
.x
->explicit_parent
= 0;
3139 /* Set the name; the functions to which we pass f expect the name to
3141 if (EQ (name
, Qunbound
) || NILP (name
))
3143 f
->name
= build_string (dpyinfo
->x_id_name
);
3144 f
->explicit_name
= 0;
3149 f
->explicit_name
= 1;
3150 /* use the frame's title when getting resources for this frame. */
3151 specbind (Qx_resource_name
, name
);
3154 /* Extract the window parameters from the supplied values
3155 that are needed to determine window geometry. */
3159 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3162 /* First, try whatever font the caller has specified. */
3165 tem
= Fquery_fontset (font
, Qnil
);
3167 font
= x_new_fontset (f
, SDATA (tem
));
3169 font
= x_new_font (f
, SDATA (font
));
3172 /* Try out a font which we hope has bold and italic variations. */
3173 if (!STRINGP (font
))
3174 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
3175 if (!STRINGP (font
))
3176 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3177 if (! STRINGP (font
))
3178 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3179 if (! STRINGP (font
))
3180 /* This was formerly the first thing tried, but it finds too many fonts
3181 and takes too long. */
3182 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3183 /* If those didn't work, look for something which will at least work. */
3184 if (! STRINGP (font
))
3185 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3187 if (! STRINGP (font
))
3188 font
= build_string ("fixed");
3190 x_default_parameter (f
, parms
, Qfont
, font
,
3191 "font", "Font", RES_TYPE_STRING
);
3195 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3196 whereby it fails to get any font. */
3197 xlwmenu_default_font
= FRAME_FONT (f
);
3200 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3201 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3203 /* This defaults to 1 in order to match xterm. We recognize either
3204 internalBorderWidth or internalBorder (which is what xterm calls
3206 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3210 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3211 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3212 if (! EQ (value
, Qunbound
))
3213 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3216 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3217 "internalBorderWidth", "internalBorderWidth",
3219 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3220 "verticalScrollBars", "ScrollBars",
3223 /* Also do the stuff which must be set before the window exists. */
3224 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3225 "foreground", "Foreground", RES_TYPE_STRING
);
3226 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3227 "background", "Background", RES_TYPE_STRING
);
3228 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3229 "pointerColor", "Foreground", RES_TYPE_STRING
);
3230 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3231 "cursorColor", "Foreground", RES_TYPE_STRING
);
3232 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3233 "borderColor", "BorderColor", RES_TYPE_STRING
);
3234 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3235 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3236 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3237 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3238 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3239 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3240 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3241 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3243 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3244 "scrollBarForeground",
3245 "ScrollBarForeground", 1);
3246 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3247 "scrollBarBackground",
3248 "ScrollBarBackground", 0);
3250 /* Init faces before x_default_parameter is called for scroll-bar
3251 parameters because that function calls x_set_scroll_bar_width,
3252 which calls change_frame_size, which calls Fset_window_buffer,
3253 which runs hooks, which call Fvertical_motion. At the end, we
3254 end up in init_iterator with a null face cache, which should not
3256 init_frame_faces (f
);
3258 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3259 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
3260 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (1),
3261 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
3262 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3263 "bufferPredicate", "BufferPredicate",
3265 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3266 "title", "Title", RES_TYPE_STRING
);
3267 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3268 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3269 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3270 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3272 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3274 /* Compute the size of the X window. */
3275 window_prompting
= x_figure_window_size (f
, parms
, 1);
3277 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3278 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3280 /* Create the X widget or window. */
3281 #ifdef USE_X_TOOLKIT
3282 x_window (f
, window_prompting
, minibuffer_only
);
3290 /* Now consider the frame official. */
3291 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3292 Vframe_list
= Fcons (frame
, Vframe_list
);
3294 /* We need to do this after creating the X window, so that the
3295 icon-creation functions can say whose icon they're describing. */
3296 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3297 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
3299 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3300 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3301 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3302 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3303 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3304 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3305 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3306 "scrollBarWidth", "ScrollBarWidth",
3309 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3310 Change will not be effected unless different from the current
3312 width
= FRAME_COLS (f
);
3313 height
= FRAME_LINES (f
);
3315 SET_FRAME_COLS (f
, 0);
3316 FRAME_LINES (f
) = 0;
3317 change_frame_size (f
, height
, width
, 1, 0, 0);
3319 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3320 /* Create the menu bar. */
3321 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3323 /* If this signals an error, we haven't set size hints for the
3324 frame and we didn't make it visible. */
3325 initialize_frame_menubar (f
);
3328 /* This is a no-op, except under Motif where it arranges the
3329 main window for the widgets on it. */
3330 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3331 f
->output_data
.x
->menubar_widget
,
3332 f
->output_data
.x
->edit_widget
);
3333 #endif /* not USE_GTK */
3335 #endif /* USE_X_TOOLKIT || USE_GTK */
3337 /* Tell the server what size and position, etc, we want, and how
3338 badly we want them. This should be done after we have the menu
3339 bar so that its size can be taken into account. */
3341 x_wm_set_size_hint (f
, window_prompting
, 0);
3344 /* Make the window appear on the frame and enable display, unless
3345 the caller says not to. However, with explicit parent, Emacs
3346 cannot control visibility, so don't try. */
3347 if (! f
->output_data
.x
->explicit_parent
)
3349 Lisp_Object visibility
;
3351 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3353 if (EQ (visibility
, Qunbound
))
3356 if (EQ (visibility
, Qicon
))
3357 x_iconify_frame (f
);
3358 else if (! NILP (visibility
))
3359 x_make_frame_visible (f
);
3361 /* Must have been Qnil. */
3367 /* Make sure windows on this frame appear in calls to next-window
3368 and similar functions. */
3369 Vwindow_list
= Qnil
;
3371 return unbind_to (count
, frame
);
3375 /* FRAME is used only to get a handle on the X display. We don't pass the
3376 display info directly because we're called from frame.c, which doesn't
3377 know about that structure. */
3380 x_get_focus_frame (frame
)
3381 struct frame
*frame
;
3383 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3385 if (! dpyinfo
->x_focus_frame
)
3388 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3393 /* In certain situations, when the window manager follows a
3394 click-to-focus policy, there seems to be no way around calling
3395 XSetInputFocus to give another frame the input focus .
3397 In an ideal world, XSetInputFocus should generally be avoided so
3398 that applications don't interfere with the window manager's focus
3399 policy. But I think it's okay to use when it's clearly done
3400 following a user-command. */
3402 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 1, 0,
3403 doc
: /* Set the input focus to FRAME.
3404 FRAME nil means use the selected frame. */)
3408 struct frame
*f
= check_x_frame (frame
);
3409 Display
*dpy
= FRAME_X_DISPLAY (f
);
3413 count
= x_catch_errors (dpy
);
3414 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3415 RevertToParent
, CurrentTime
);
3416 x_uncatch_errors (dpy
, count
);
3423 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3424 doc
: /* Internal function called by `color-defined-p', which see. */)
3426 Lisp_Object color
, frame
;
3429 FRAME_PTR f
= check_x_frame (frame
);
3431 CHECK_STRING (color
);
3433 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3439 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3440 doc
: /* Internal function called by `color-values', which see. */)
3442 Lisp_Object color
, frame
;
3445 FRAME_PTR f
= check_x_frame (frame
);
3447 CHECK_STRING (color
);
3449 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3453 rgb
[0] = make_number (foo
.red
);
3454 rgb
[1] = make_number (foo
.green
);
3455 rgb
[2] = make_number (foo
.blue
);
3456 return Flist (3, rgb
);
3462 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3463 doc
: /* Internal function called by `display-color-p', which see. */)
3465 Lisp_Object display
;
3467 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3469 if (dpyinfo
->n_planes
<= 2)
3472 switch (dpyinfo
->visual
->class)
3485 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3487 doc
: /* Return t if the X display supports shades of gray.
3488 Note that color displays do support shades of gray.
3489 The optional argument DISPLAY specifies which display to ask about.
3490 DISPLAY should be either a frame or a display name (a string).
3491 If omitted or nil, that stands for the selected frame's display. */)
3493 Lisp_Object display
;
3495 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3497 if (dpyinfo
->n_planes
<= 1)
3500 switch (dpyinfo
->visual
->class)
3515 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3517 doc
: /* Returns the width in pixels of the X display DISPLAY.
3518 The optional argument DISPLAY specifies which display to ask about.
3519 DISPLAY should be either a frame or a display name (a string).
3520 If omitted or nil, that stands for the selected frame's display. */)
3522 Lisp_Object display
;
3524 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3526 return make_number (dpyinfo
->width
);
3529 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3530 Sx_display_pixel_height
, 0, 1, 0,
3531 doc
: /* Returns the height in pixels of the X display DISPLAY.
3532 The optional argument DISPLAY specifies which display to ask about.
3533 DISPLAY should be either a frame or a display name (a string).
3534 If omitted or nil, that stands for the selected frame's display. */)
3536 Lisp_Object display
;
3538 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3540 return make_number (dpyinfo
->height
);
3543 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3545 doc
: /* Returns the number of bitplanes of the X display DISPLAY.
3546 The optional argument DISPLAY specifies which display to ask about.
3547 DISPLAY should be either a frame or a display name (a string).
3548 If omitted or nil, that stands for the selected frame's display. */)
3550 Lisp_Object display
;
3552 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3554 return make_number (dpyinfo
->n_planes
);
3557 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3559 doc
: /* Returns the number of color cells of the X display DISPLAY.
3560 The optional argument DISPLAY specifies which display to ask about.
3561 DISPLAY should be either a frame or a display name (a string).
3562 If omitted or nil, that stands for the selected frame's display. */)
3564 Lisp_Object display
;
3566 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3568 return make_number (DisplayCells (dpyinfo
->display
,
3569 XScreenNumberOfScreen (dpyinfo
->screen
)));
3572 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3573 Sx_server_max_request_size
,
3575 doc
: /* Returns the maximum request size of the X server of display DISPLAY.
3576 The optional argument DISPLAY specifies which display to ask about.
3577 DISPLAY should be either a frame or a display name (a string).
3578 If omitted or nil, that stands for the selected frame's display. */)
3580 Lisp_Object display
;
3582 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3584 return make_number (MAXREQUEST (dpyinfo
->display
));
3587 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3588 doc
: /* Returns the vendor ID string of the X server of display DISPLAY.
3589 The optional argument DISPLAY specifies which display to ask about.
3590 DISPLAY should be either a frame or a display name (a string).
3591 If omitted or nil, that stands for the selected frame's display. */)
3593 Lisp_Object display
;
3595 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3596 char *vendor
= ServerVendor (dpyinfo
->display
);
3598 if (! vendor
) vendor
= "";
3599 return build_string (vendor
);
3602 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3603 doc
: /* Returns the version numbers of the X server of display DISPLAY.
3604 The value is a list of three integers: the major and minor
3605 version numbers of the X Protocol in use, and the vendor-specific release
3606 number. See also the function `x-server-vendor'.
3608 The optional argument DISPLAY specifies which display to ask about.
3609 DISPLAY should be either a frame or a display name (a string).
3610 If omitted or nil, that stands for the selected frame's display. */)
3612 Lisp_Object display
;
3614 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3615 Display
*dpy
= dpyinfo
->display
;
3617 return Fcons (make_number (ProtocolVersion (dpy
)),
3618 Fcons (make_number (ProtocolRevision (dpy
)),
3619 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3622 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3623 doc
: /* Return the number of screens on the X server of display DISPLAY.
3624 The optional argument DISPLAY specifies which display to ask about.
3625 DISPLAY should be either a frame or a display name (a string).
3626 If omitted or nil, that stands for the selected frame's display. */)
3628 Lisp_Object display
;
3630 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3632 return make_number (ScreenCount (dpyinfo
->display
));
3635 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3636 doc
: /* Return the height in millimeters of the X display DISPLAY.
3637 The optional argument DISPLAY specifies which display to ask about.
3638 DISPLAY should be either a frame or a display name (a string).
3639 If omitted or nil, that stands for the selected frame's display. */)
3641 Lisp_Object display
;
3643 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3645 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3648 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3649 doc
: /* Return the width in millimeters of the X display DISPLAY.
3650 The optional argument DISPLAY specifies which display to ask about.
3651 DISPLAY should be either a frame or a display name (a string).
3652 If omitted or nil, that stands for the selected frame's display. */)
3654 Lisp_Object display
;
3656 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3658 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3661 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3662 Sx_display_backing_store
, 0, 1, 0,
3663 doc
: /* Returns an indication of whether X display DISPLAY does backing store.
3664 The value may be `always', `when-mapped', or `not-useful'.
3665 The optional argument DISPLAY specifies which display to ask about.
3666 DISPLAY should be either a frame or a display name (a string).
3667 If omitted or nil, that stands for the selected frame's display. */)
3669 Lisp_Object display
;
3671 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3674 switch (DoesBackingStore (dpyinfo
->screen
))
3677 result
= intern ("always");
3681 result
= intern ("when-mapped");
3685 result
= intern ("not-useful");
3689 error ("Strange value for BackingStore parameter of screen");
3696 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3697 Sx_display_visual_class
, 0, 1, 0,
3698 doc
: /* Return the visual class of the X display DISPLAY.
3699 The value is one of the symbols `static-gray', `gray-scale',
3700 `static-color', `pseudo-color', `true-color', or `direct-color'.
3702 The optional argument DISPLAY specifies which display to ask about.
3703 DISPLAY should be either a frame or a display name (a string).
3704 If omitted or nil, that stands for the selected frame's display. */)
3706 Lisp_Object display
;
3708 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3711 switch (dpyinfo
->visual
->class)
3714 result
= intern ("static-gray");
3717 result
= intern ("gray-scale");
3720 result
= intern ("static-color");
3723 result
= intern ("pseudo-color");
3726 result
= intern ("true-color");
3729 result
= intern ("direct-color");
3732 error ("Display has an unknown visual class");
3739 DEFUN ("x-display-save-under", Fx_display_save_under
,
3740 Sx_display_save_under
, 0, 1, 0,
3741 doc
: /* Returns t if the X display DISPLAY supports the save-under feature.
3742 The optional argument DISPLAY specifies which display to ask about.
3743 DISPLAY should be either a frame or a display name (a string).
3744 If omitted or nil, that stands for the selected frame's display. */)
3746 Lisp_Object display
;
3748 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3750 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3758 register struct frame
*f
;
3760 return FRAME_PIXEL_WIDTH (f
);
3765 register struct frame
*f
;
3767 return FRAME_PIXEL_HEIGHT (f
);
3772 register struct frame
*f
;
3774 return FRAME_COLUMN_WIDTH (f
);
3779 register struct frame
*f
;
3781 return FRAME_LINE_HEIGHT (f
);
3786 register struct frame
*f
;
3788 return FRAME_X_DISPLAY_INFO (f
)->n_planes
;
3793 /************************************************************************
3795 ************************************************************************/
3798 /* Mapping visual names to visuals. */
3800 static struct visual_class
3807 {"StaticGray", StaticGray
},
3808 {"GrayScale", GrayScale
},
3809 {"StaticColor", StaticColor
},
3810 {"PseudoColor", PseudoColor
},
3811 {"TrueColor", TrueColor
},
3812 {"DirectColor", DirectColor
},
3817 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3819 /* Value is the screen number of screen SCR. This is a substitute for
3820 the X function with the same name when that doesn't exist. */
3823 XScreenNumberOfScreen (scr
)
3824 register Screen
*scr
;
3826 Display
*dpy
= scr
->display
;
3829 for (i
= 0; i
< dpy
->nscreens
; ++i
)
3830 if (scr
== dpy
->screens
+ i
)
3836 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3839 /* Select the visual that should be used on display DPYINFO. Set
3840 members of DPYINFO appropriately. Called from x_term_init. */
3843 select_visual (dpyinfo
)
3844 struct x_display_info
*dpyinfo
;
3846 Display
*dpy
= dpyinfo
->display
;
3847 Screen
*screen
= dpyinfo
->screen
;
3850 /* See if a visual is specified. */
3851 value
= display_x_get_resource (dpyinfo
,
3852 build_string ("visualClass"),
3853 build_string ("VisualClass"),
3855 if (STRINGP (value
))
3857 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
3858 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
3859 depth, a decimal number. NAME is compared with case ignored. */
3860 char *s
= (char *) alloca (SBYTES (value
) + 1);
3865 strcpy (s
, SDATA (value
));
3866 dash
= index (s
, '-');
3869 dpyinfo
->n_planes
= atoi (dash
+ 1);
3873 /* We won't find a matching visual with depth 0, so that
3874 an error will be printed below. */
3875 dpyinfo
->n_planes
= 0;
3877 /* Determine the visual class. */
3878 for (i
= 0; visual_classes
[i
].name
; ++i
)
3879 if (xstricmp (s
, visual_classes
[i
].name
) == 0)
3881 class = visual_classes
[i
].class;
3885 /* Look up a matching visual for the specified class. */
3887 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
3888 dpyinfo
->n_planes
, class, &vinfo
))
3889 fatal ("Invalid visual specification `%s'", SDATA (value
));
3891 dpyinfo
->visual
= vinfo
.visual
;
3896 XVisualInfo
*vinfo
, vinfo_template
;
3898 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
3901 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
3903 vinfo_template
.visualid
= dpyinfo
->visual
->visualid
;
3905 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
3906 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
3907 &vinfo_template
, &n_visuals
);
3909 fatal ("Can't get proper X visual info");
3911 dpyinfo
->n_planes
= vinfo
->depth
;
3912 XFree ((char *) vinfo
);
3917 /* Return the X display structure for the display named NAME.
3918 Open a new connection if necessary. */
3920 struct x_display_info
*
3921 x_display_info_for_name (name
)
3925 struct x_display_info
*dpyinfo
;
3927 CHECK_STRING (name
);
3929 if (! EQ (Vwindow_system
, intern ("x")))
3930 error ("Not using X Windows");
3932 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
3934 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
3937 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
3942 /* Use this general default value to start with. */
3943 Vx_resource_name
= Vinvocation_name
;
3945 validate_x_resource_name ();
3947 dpyinfo
= x_term_init (name
, (char *)0,
3948 (char *) SDATA (Vx_resource_name
));
3951 error ("Cannot connect to X server %s", SDATA (name
));
3954 XSETFASTINT (Vwindow_system_version
, 11);
3960 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
3962 doc
: /* Open a connection to an X server.
3963 DISPLAY is the name of the display to connect to.
3964 Optional second arg XRM-STRING is a string of resources in xrdb format.
3965 If the optional third arg MUST-SUCCEED is non-nil,
3966 terminate Emacs if we can't open the connection. */)
3967 (display
, xrm_string
, must_succeed
)
3968 Lisp_Object display
, xrm_string
, must_succeed
;
3970 unsigned char *xrm_option
;
3971 struct x_display_info
*dpyinfo
;
3973 CHECK_STRING (display
);
3974 if (! NILP (xrm_string
))
3975 CHECK_STRING (xrm_string
);
3977 if (! EQ (Vwindow_system
, intern ("x")))
3978 error ("Not using X Windows");
3980 if (! NILP (xrm_string
))
3981 xrm_option
= (unsigned char *) SDATA (xrm_string
);
3983 xrm_option
= (unsigned char *) 0;
3985 validate_x_resource_name ();
3987 /* This is what opens the connection and sets x_current_display.
3988 This also initializes many symbols, such as those used for input. */
3989 dpyinfo
= x_term_init (display
, xrm_option
,
3990 (char *) SDATA (Vx_resource_name
));
3994 if (!NILP (must_succeed
))
3995 fatal ("Cannot connect to X server %s.\n\
3996 Check the DISPLAY environment variable or use `-d'.\n\
3997 Also use the `xauth' program to verify that you have the proper\n\
3998 authorization information needed to connect the X server.\n\
3999 An insecure way to solve the problem may be to use `xhost'.\n",
4002 error ("Cannot connect to X server %s", SDATA (display
));
4007 XSETFASTINT (Vwindow_system_version
, 11);
4011 DEFUN ("x-close-connection", Fx_close_connection
,
4012 Sx_close_connection
, 1, 1, 0,
4013 doc
: /* Close the connection to DISPLAY's X server.
4014 For DISPLAY, specify either a frame or a display name (a string).
4015 If DISPLAY is nil, that stands for the selected frame's display. */)
4017 Lisp_Object display
;
4019 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4022 if (dpyinfo
->reference_count
> 0)
4023 error ("Display still has frames on it");
4026 /* Free the fonts in the font table. */
4027 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4028 if (dpyinfo
->font_table
[i
].name
)
4030 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
4031 xfree (dpyinfo
->font_table
[i
].full_name
);
4032 xfree (dpyinfo
->font_table
[i
].name
);
4033 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4036 x_destroy_all_bitmaps (dpyinfo
);
4037 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4039 #ifdef USE_X_TOOLKIT
4040 XtCloseDisplay (dpyinfo
->display
);
4042 XCloseDisplay (dpyinfo
->display
);
4045 x_delete_display (dpyinfo
);
4051 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4052 doc
: /* Return the list of display names that Emacs has connections to. */)
4055 Lisp_Object tail
, result
;
4058 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
4059 result
= Fcons (XCAR (XCAR (tail
)), result
);
4064 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4065 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4066 If ON is nil, allow buffering of requests.
4067 Turning on synchronization prohibits the Xlib routines from buffering
4068 requests and seriously degrades performance, but makes debugging much
4070 The optional second argument DISPLAY specifies which display to act on.
4071 DISPLAY should be either a frame or a display name (a string).
4072 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4074 Lisp_Object display
, on
;
4076 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4078 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4083 /* Wait for responses to all X commands issued so far for frame F. */
4090 XSync (FRAME_X_DISPLAY (f
), False
);
4095 /***********************************************************************
4097 ***********************************************************************/
4099 /* Value is the number of elements of vector VECTOR. */
4101 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
4103 /* List of supported image types. Use define_image_type to add new
4104 types. Use lookup_image_type to find a type for a given symbol. */
4106 static struct image_type
*image_types
;
4108 /* The symbol `image' which is the car of the lists used to represent
4111 extern Lisp_Object Qimage
;
4113 /* The symbol `xbm' which is used as the type symbol for XBM images. */
4119 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
4120 extern Lisp_Object QCdata
, QCtype
;
4121 Lisp_Object QCascent
, QCmargin
, QCrelief
;
4122 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
4123 Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
;
4125 /* Other symbols. */
4127 Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
4129 /* Time in seconds after which images should be removed from the cache
4130 if not displayed. */
4132 Lisp_Object Vimage_cache_eviction_delay
;
4134 /* Function prototypes. */
4136 static void define_image_type
P_ ((struct image_type
*type
));
4137 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
4138 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
4139 static void x_laplace
P_ ((struct frame
*, struct image
*));
4140 static void x_emboss
P_ ((struct frame
*, struct image
*));
4141 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
4145 /* Define a new image type from TYPE. This adds a copy of TYPE to
4146 image_types and adds the symbol *TYPE->type to Vimage_types. */
4149 define_image_type (type
)
4150 struct image_type
*type
;
4152 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
4153 The initialized data segment is read-only. */
4154 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
4155 bcopy (type
, p
, sizeof *p
);
4156 p
->next
= image_types
;
4158 Vimage_types
= Fcons (*p
->type
, Vimage_types
);
4162 /* Look up image type SYMBOL, and return a pointer to its image_type
4163 structure. Value is null if SYMBOL is not a known image type. */
4165 static INLINE
struct image_type
*
4166 lookup_image_type (symbol
)
4169 struct image_type
*type
;
4171 for (type
= image_types
; type
; type
= type
->next
)
4172 if (EQ (symbol
, *type
->type
))
4179 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
4180 valid image specification is a list whose car is the symbol
4181 `image', and whose rest is a property list. The property list must
4182 contain a value for key `:type'. That value must be the name of a
4183 supported image type. The rest of the property list depends on the
4187 valid_image_p (object
)
4192 if (CONSP (object
) && EQ (XCAR (object
), Qimage
))
4196 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
4197 if (EQ (XCAR (tem
), QCtype
))
4200 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
4202 struct image_type
*type
;
4203 type
= lookup_image_type (XCAR (tem
));
4205 valid_p
= type
->valid_p (object
);
4216 /* Log error message with format string FORMAT and argument ARG.
4217 Signaling an error, e.g. when an image cannot be loaded, is not a
4218 good idea because this would interrupt redisplay, and the error
4219 message display would lead to another redisplay. This function
4220 therefore simply displays a message. */
4223 image_error (format
, arg1
, arg2
)
4225 Lisp_Object arg1
, arg2
;
4227 add_to_log (format
, arg1
, arg2
);
4232 /***********************************************************************
4233 Image specifications
4234 ***********************************************************************/
4236 enum image_value_type
4238 IMAGE_DONT_CHECK_VALUE_TYPE
,
4240 IMAGE_STRING_OR_NIL_VALUE
,
4242 IMAGE_POSITIVE_INTEGER_VALUE
,
4243 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
4244 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
4246 IMAGE_INTEGER_VALUE
,
4247 IMAGE_FUNCTION_VALUE
,
4252 /* Structure used when parsing image specifications. */
4254 struct image_keyword
4256 /* Name of keyword. */
4259 /* The type of value allowed. */
4260 enum image_value_type type
;
4262 /* Non-zero means key must be present. */
4265 /* Used to recognize duplicate keywords in a property list. */
4268 /* The value that was found. */
4273 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
4275 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
4278 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
4279 has the format (image KEYWORD VALUE ...). One of the keyword/
4280 value pairs must be `:type TYPE'. KEYWORDS is a vector of
4281 image_keywords structures of size NKEYWORDS describing other
4282 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
4285 parse_image_spec (spec
, keywords
, nkeywords
, type
)
4287 struct image_keyword
*keywords
;
4294 if (!CONSP (spec
) || !EQ (XCAR (spec
), Qimage
))
4297 plist
= XCDR (spec
);
4298 while (CONSP (plist
))
4300 Lisp_Object key
, value
;
4302 /* First element of a pair must be a symbol. */
4304 plist
= XCDR (plist
);
4308 /* There must follow a value. */
4311 value
= XCAR (plist
);
4312 plist
= XCDR (plist
);
4314 /* Find key in KEYWORDS. Error if not found. */
4315 for (i
= 0; i
< nkeywords
; ++i
)
4316 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
4322 /* Record that we recognized the keyword. If a keywords
4323 was found more than once, it's an error. */
4324 keywords
[i
].value
= value
;
4325 ++keywords
[i
].count
;
4327 if (keywords
[i
].count
> 1)
4330 /* Check type of value against allowed type. */
4331 switch (keywords
[i
].type
)
4333 case IMAGE_STRING_VALUE
:
4334 if (!STRINGP (value
))
4338 case IMAGE_STRING_OR_NIL_VALUE
:
4339 if (!STRINGP (value
) && !NILP (value
))
4343 case IMAGE_SYMBOL_VALUE
:
4344 if (!SYMBOLP (value
))
4348 case IMAGE_POSITIVE_INTEGER_VALUE
:
4349 if (!INTEGERP (value
) || XINT (value
) <= 0)
4353 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
4354 if (INTEGERP (value
) && XINT (value
) >= 0)
4357 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
4358 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
4362 case IMAGE_ASCENT_VALUE
:
4363 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
4365 else if (INTEGERP (value
)
4366 && XINT (value
) >= 0
4367 && XINT (value
) <= 100)
4371 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
4372 if (!INTEGERP (value
) || XINT (value
) < 0)
4376 case IMAGE_DONT_CHECK_VALUE_TYPE
:
4379 case IMAGE_FUNCTION_VALUE
:
4380 value
= indirect_function (value
);
4382 || COMPILEDP (value
)
4383 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
4387 case IMAGE_NUMBER_VALUE
:
4388 if (!INTEGERP (value
) && !FLOATP (value
))
4392 case IMAGE_INTEGER_VALUE
:
4393 if (!INTEGERP (value
))
4397 case IMAGE_BOOL_VALUE
:
4398 if (!NILP (value
) && !EQ (value
, Qt
))
4407 if (EQ (key
, QCtype
) && !EQ (type
, value
))
4411 /* Check that all mandatory fields are present. */
4412 for (i
= 0; i
< nkeywords
; ++i
)
4413 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
4416 return NILP (plist
);
4420 /* Return the value of KEY in image specification SPEC. Value is nil
4421 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
4422 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
4425 image_spec_value (spec
, key
, found
)
4426 Lisp_Object spec
, key
;
4431 xassert (valid_image_p (spec
));
4433 for (tail
= XCDR (spec
);
4434 CONSP (tail
) && CONSP (XCDR (tail
));
4435 tail
= XCDR (XCDR (tail
)))
4437 if (EQ (XCAR (tail
), key
))
4441 return XCAR (XCDR (tail
));
4451 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
4452 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
4453 PIXELS non-nil means return the size in pixels, otherwise return the
4454 size in canonical character units.
4455 FRAME is the frame on which the image will be displayed. FRAME nil
4456 or omitted means use the selected frame. */)
4457 (spec
, pixels
, frame
)
4458 Lisp_Object spec
, pixels
, frame
;
4463 if (valid_image_p (spec
))
4465 struct frame
*f
= check_x_frame (frame
);
4466 int id
= lookup_image (f
, spec
);
4467 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4468 int width
= img
->width
+ 2 * img
->hmargin
;
4469 int height
= img
->height
+ 2 * img
->vmargin
;
4472 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
4473 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
4475 size
= Fcons (make_number (width
), make_number (height
));
4478 error ("Invalid image specification");
4484 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
4485 doc
: /* Return t if image SPEC has a mask bitmap.
4486 FRAME is the frame on which the image will be displayed. FRAME nil
4487 or omitted means use the selected frame. */)
4489 Lisp_Object spec
, frame
;
4494 if (valid_image_p (spec
))
4496 struct frame
*f
= check_x_frame (frame
);
4497 int id
= lookup_image (f
, spec
);
4498 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4503 error ("Invalid image specification");
4510 /***********************************************************************
4511 Image type independent image structures
4512 ***********************************************************************/
4514 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
4515 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
4518 /* Allocate and return a new image structure for image specification
4519 SPEC. SPEC has a hash value of HASH. */
4521 static struct image
*
4522 make_image (spec
, hash
)
4526 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
4528 xassert (valid_image_p (spec
));
4529 bzero (img
, sizeof *img
);
4530 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
4531 xassert (img
->type
!= NULL
);
4533 img
->data
.lisp_val
= Qnil
;
4534 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
4540 /* Free image IMG which was used on frame F, including its resources. */
4549 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4551 /* Remove IMG from the hash table of its cache. */
4553 img
->prev
->next
= img
->next
;
4555 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
4558 img
->next
->prev
= img
->prev
;
4560 c
->images
[img
->id
] = NULL
;
4562 /* Free resources, then free IMG. */
4563 img
->type
->free (f
, img
);
4569 /* Prepare image IMG for display on frame F. Must be called before
4570 drawing an image. */
4573 prepare_image_for_display (f
, img
)
4579 /* We're about to display IMG, so set its timestamp to `now'. */
4581 img
->timestamp
= EMACS_SECS (t
);
4583 /* If IMG doesn't have a pixmap yet, load it now, using the image
4584 type dependent loader function. */
4585 if (img
->pixmap
== None
&& !img
->load_failed_p
)
4586 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
4590 /* Value is the number of pixels for the ascent of image IMG when
4591 drawn in face FACE. */
4594 image_ascent (img
, face
)
4598 int height
= img
->height
+ img
->vmargin
;
4601 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
4604 /* This expression is arranged so that if the image can't be
4605 exactly centered, it will be moved slightly up. This is
4606 because a typical font is `top-heavy' (due to the presence
4607 uppercase letters), so the image placement should err towards
4608 being top-heavy too. It also just generally looks better. */
4609 ascent
= (height
+ face
->font
->ascent
- face
->font
->descent
+ 1) / 2;
4611 ascent
= height
/ 2;
4614 ascent
= height
* img
->ascent
/ 100.0;
4620 /* Image background colors. */
4622 static unsigned long
4623 four_corners_best (ximg
, width
, height
)
4625 unsigned long width
, height
;
4627 unsigned long corners
[4], best
;
4630 /* Get the colors at the corners of ximg. */
4631 corners
[0] = XGetPixel (ximg
, 0, 0);
4632 corners
[1] = XGetPixel (ximg
, width
- 1, 0);
4633 corners
[2] = XGetPixel (ximg
, width
- 1, height
- 1);
4634 corners
[3] = XGetPixel (ximg
, 0, height
- 1);
4636 /* Choose the most frequently found color as background. */
4637 for (i
= best_count
= 0; i
< 4; ++i
)
4641 for (j
= n
= 0; j
< 4; ++j
)
4642 if (corners
[i
] == corners
[j
])
4646 best
= corners
[i
], best_count
= n
;
4652 /* Return the `background' field of IMG. If IMG doesn't have one yet,
4653 it is guessed heuristically. If non-zero, XIMG is an existing XImage
4654 object to use for the heuristic. */
4657 image_background (img
, f
, ximg
)
4662 if (! img
->background_valid
)
4663 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4665 int free_ximg
= !ximg
;
4668 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4669 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4671 img
->background
= four_corners_best (ximg
, img
->width
, img
->height
);
4674 XDestroyImage (ximg
);
4676 img
->background_valid
= 1;
4679 return img
->background
;
4682 /* Return the `background_transparent' field of IMG. If IMG doesn't
4683 have one yet, it is guessed heuristically. If non-zero, MASK is an
4684 existing XImage object to use for the heuristic. */
4687 image_background_transparent (img
, f
, mask
)
4692 if (! img
->background_transparent_valid
)
4693 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4697 int free_mask
= !mask
;
4700 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
4701 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4703 img
->background_transparent
4704 = !four_corners_best (mask
, img
->width
, img
->height
);
4707 XDestroyImage (mask
);
4710 img
->background_transparent
= 0;
4712 img
->background_transparent_valid
= 1;
4715 return img
->background_transparent
;
4719 /***********************************************************************
4720 Helper functions for X image types
4721 ***********************************************************************/
4723 static void x_clear_image_1
P_ ((struct frame
*, struct image
*, int,
4725 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
4726 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
4728 Lisp_Object color_name
,
4729 unsigned long dflt
));
4732 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
4733 free the pixmap if any. MASK_P non-zero means clear the mask
4734 pixmap if any. COLORS_P non-zero means free colors allocated for
4735 the image, if any. */
4738 x_clear_image_1 (f
, img
, pixmap_p
, mask_p
, colors_p
)
4741 int pixmap_p
, mask_p
, colors_p
;
4743 if (pixmap_p
&& img
->pixmap
)
4745 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
4747 img
->background_valid
= 0;
4750 if (mask_p
&& img
->mask
)
4752 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4754 img
->background_transparent_valid
= 0;
4757 if (colors_p
&& img
->ncolors
)
4759 x_free_colors (f
, img
->colors
, img
->ncolors
);
4760 xfree (img
->colors
);
4766 /* Free X resources of image IMG which is used on frame F. */
4769 x_clear_image (f
, img
)
4774 x_clear_image_1 (f
, img
, 1, 1, 1);
4779 /* Allocate color COLOR_NAME for image IMG on frame F. If color
4780 cannot be allocated, use DFLT. Add a newly allocated color to
4781 IMG->colors, so that it can be freed again. Value is the pixel
4784 static unsigned long
4785 x_alloc_image_color (f
, img
, color_name
, dflt
)
4788 Lisp_Object color_name
;
4792 unsigned long result
;
4794 xassert (STRINGP (color_name
));
4796 if (x_defined_color (f
, SDATA (color_name
), &color
, 1))
4798 /* This isn't called frequently so we get away with simply
4799 reallocating the color vector to the needed size, here. */
4802 (unsigned long *) xrealloc (img
->colors
,
4803 img
->ncolors
* sizeof *img
->colors
);
4804 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
4805 result
= color
.pixel
;
4815 /***********************************************************************
4817 ***********************************************************************/
4819 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
4820 static void postprocess_image
P_ ((struct frame
*, struct image
*));
4823 /* Return a new, initialized image cache that is allocated from the
4824 heap. Call free_image_cache to free an image cache. */
4826 struct image_cache
*
4829 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
4832 bzero (c
, sizeof *c
);
4834 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
4835 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
4836 c
->buckets
= (struct image
**) xmalloc (size
);
4837 bzero (c
->buckets
, size
);
4842 /* Free image cache of frame F. Be aware that X frames share images
4846 free_image_cache (f
)
4849 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4854 /* Cache should not be referenced by any frame when freed. */
4855 xassert (c
->refcount
== 0);
4857 for (i
= 0; i
< c
->used
; ++i
)
4858 free_image (f
, c
->images
[i
]);
4862 FRAME_X_IMAGE_CACHE (f
) = NULL
;
4867 /* Clear image cache of frame F. FORCE_P non-zero means free all
4868 images. FORCE_P zero means clear only images that haven't been
4869 displayed for some time. Should be called from time to time to
4870 reduce the number of loaded images. If image-eviction-seconds is
4871 non-nil, this frees images in the cache which weren't displayed for
4872 at least that many seconds. */
4875 clear_image_cache (f
, force_p
)
4879 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4881 if (c
&& INTEGERP (Vimage_cache_eviction_delay
))
4888 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
4890 /* Block input so that we won't be interrupted by a SIGIO
4891 while being in an inconsistent state. */
4894 for (i
= nfreed
= 0; i
< c
->used
; ++i
)
4896 struct image
*img
= c
->images
[i
];
4898 && (force_p
|| img
->timestamp
< old
))
4900 free_image (f
, img
);
4905 /* We may be clearing the image cache because, for example,
4906 Emacs was iconified for a longer period of time. In that
4907 case, current matrices may still contain references to
4908 images freed above. So, clear these matrices. */
4911 Lisp_Object tail
, frame
;
4913 FOR_EACH_FRAME (tail
, frame
)
4915 struct frame
*f
= XFRAME (frame
);
4917 && FRAME_X_IMAGE_CACHE (f
) == c
)
4918 clear_current_matrices (f
);
4921 ++windows_or_buffers_changed
;
4929 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
4931 doc
: /* Clear the image cache of FRAME.
4932 FRAME nil or omitted means use the selected frame.
4933 FRAME t means clear the image caches of all frames. */)
4941 FOR_EACH_FRAME (tail
, frame
)
4942 if (FRAME_X_P (XFRAME (frame
)))
4943 clear_image_cache (XFRAME (frame
), 1);
4946 clear_image_cache (check_x_frame (frame
), 1);
4952 /* Compute masks and transform image IMG on frame F, as specified
4953 by the image's specification, */
4956 postprocess_image (f
, img
)
4960 /* Manipulation of the image's mask. */
4963 Lisp_Object conversion
, spec
;
4968 /* `:heuristic-mask t'
4970 means build a mask heuristically.
4971 `:heuristic-mask (R G B)'
4972 `:mask (heuristic (R G B))'
4973 means build a mask from color (R G B) in the
4976 means remove a mask, if any. */
4978 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
4980 x_build_heuristic_mask (f
, img
, mask
);
4985 mask
= image_spec_value (spec
, QCmask
, &found_p
);
4987 if (EQ (mask
, Qheuristic
))
4988 x_build_heuristic_mask (f
, img
, Qt
);
4989 else if (CONSP (mask
)
4990 && EQ (XCAR (mask
), Qheuristic
))
4992 if (CONSP (XCDR (mask
)))
4993 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
4995 x_build_heuristic_mask (f
, img
, XCDR (mask
));
4997 else if (NILP (mask
) && found_p
&& img
->mask
)
4999 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
5005 /* Should we apply an image transformation algorithm? */
5006 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
5007 if (EQ (conversion
, Qdisabled
))
5008 x_disable_image (f
, img
);
5009 else if (EQ (conversion
, Qlaplace
))
5011 else if (EQ (conversion
, Qemboss
))
5013 else if (CONSP (conversion
)
5014 && EQ (XCAR (conversion
), Qedge_detection
))
5017 tem
= XCDR (conversion
);
5019 x_edge_detection (f
, img
,
5020 Fplist_get (tem
, QCmatrix
),
5021 Fplist_get (tem
, QCcolor_adjustment
));
5027 /* Return the id of image with Lisp specification SPEC on frame F.
5028 SPEC must be a valid Lisp image specification (see valid_image_p). */
5031 lookup_image (f
, spec
)
5035 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5039 struct gcpro gcpro1
;
5042 /* F must be a window-system frame, and SPEC must be a valid image
5044 xassert (FRAME_WINDOW_P (f
));
5045 xassert (valid_image_p (spec
));
5049 /* Look up SPEC in the hash table of the image cache. */
5050 hash
= sxhash (spec
, 0);
5051 i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5053 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
5054 if (img
->hash
== hash
&& !NILP (Fequal (img
->spec
, spec
)))
5057 /* If not found, create a new image and cache it. */
5060 extern Lisp_Object Qpostscript
;
5063 img
= make_image (spec
, hash
);
5064 cache_image (f
, img
);
5065 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5067 /* If we can't load the image, and we don't have a width and
5068 height, use some arbitrary width and height so that we can
5069 draw a rectangle for it. */
5070 if (img
->load_failed_p
)
5074 value
= image_spec_value (spec
, QCwidth
, NULL
);
5075 img
->width
= (INTEGERP (value
)
5076 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
5077 value
= image_spec_value (spec
, QCheight
, NULL
);
5078 img
->height
= (INTEGERP (value
)
5079 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
5083 /* Handle image type independent image attributes
5084 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
5085 `:background COLOR'. */
5086 Lisp_Object ascent
, margin
, relief
, bg
;
5088 ascent
= image_spec_value (spec
, QCascent
, NULL
);
5089 if (INTEGERP (ascent
))
5090 img
->ascent
= XFASTINT (ascent
);
5091 else if (EQ (ascent
, Qcenter
))
5092 img
->ascent
= CENTERED_IMAGE_ASCENT
;
5094 margin
= image_spec_value (spec
, QCmargin
, NULL
);
5095 if (INTEGERP (margin
) && XINT (margin
) >= 0)
5096 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
5097 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
5098 && INTEGERP (XCDR (margin
)))
5100 if (XINT (XCAR (margin
)) > 0)
5101 img
->hmargin
= XFASTINT (XCAR (margin
));
5102 if (XINT (XCDR (margin
)) > 0)
5103 img
->vmargin
= XFASTINT (XCDR (margin
));
5106 relief
= image_spec_value (spec
, QCrelief
, NULL
);
5107 if (INTEGERP (relief
))
5109 img
->relief
= XINT (relief
);
5110 img
->hmargin
+= abs (img
->relief
);
5111 img
->vmargin
+= abs (img
->relief
);
5114 if (! img
->background_valid
)
5116 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
5120 = x_alloc_image_color (f
, img
, bg
,
5121 FRAME_BACKGROUND_PIXEL (f
));
5122 img
->background_valid
= 1;
5126 /* Do image transformations and compute masks, unless we
5127 don't have the image yet. */
5128 if (!EQ (*img
->type
->type
, Qpostscript
))
5129 postprocess_image (f
, img
);
5133 xassert (!interrupt_input_blocked
);
5136 /* We're using IMG, so set its timestamp to `now'. */
5137 EMACS_GET_TIME (now
);
5138 img
->timestamp
= EMACS_SECS (now
);
5142 /* Value is the image id. */
5147 /* Cache image IMG in the image cache of frame F. */
5150 cache_image (f
, img
)
5154 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5157 /* Find a free slot in c->images. */
5158 for (i
= 0; i
< c
->used
; ++i
)
5159 if (c
->images
[i
] == NULL
)
5162 /* If no free slot found, maybe enlarge c->images. */
5163 if (i
== c
->used
&& c
->used
== c
->size
)
5166 c
->images
= (struct image
**) xrealloc (c
->images
,
5167 c
->size
* sizeof *c
->images
);
5170 /* Add IMG to c->images, and assign IMG an id. */
5176 /* Add IMG to the cache's hash table. */
5177 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5178 img
->next
= c
->buckets
[i
];
5180 img
->next
->prev
= img
;
5182 c
->buckets
[i
] = img
;
5186 /* Call FN on every image in the image cache of frame F. Used to mark
5187 Lisp Objects in the image cache. */
5190 forall_images_in_image_cache (f
, fn
)
5192 void (*fn
) P_ ((struct image
*img
));
5194 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
))
5196 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5200 for (i
= 0; i
< c
->used
; ++i
)
5209 /***********************************************************************
5211 ***********************************************************************/
5213 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
5214 XImage
**, Pixmap
*));
5215 static void x_destroy_x_image
P_ ((XImage
*));
5216 static void x_put_x_image
P_ ((struct frame
*, XImage
*, Pixmap
, int, int));
5219 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
5220 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
5221 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
5222 via xmalloc. Print error messages via image_error if an error
5223 occurs. Value is non-zero if successful. */
5226 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
5228 int width
, height
, depth
;
5232 Display
*display
= FRAME_X_DISPLAY (f
);
5233 Screen
*screen
= FRAME_X_SCREEN (f
);
5234 Window window
= FRAME_X_WINDOW (f
);
5236 xassert (interrupt_input_blocked
);
5239 depth
= DefaultDepthOfScreen (screen
);
5240 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
5241 depth
, ZPixmap
, 0, NULL
, width
, height
,
5242 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
5245 image_error ("Unable to allocate X image", Qnil
, Qnil
);
5249 /* Allocate image raster. */
5250 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
5252 /* Allocate a pixmap of the same size. */
5253 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
5254 if (*pixmap
== None
)
5256 x_destroy_x_image (*ximg
);
5258 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
5266 /* Destroy XImage XIMG. Free XIMG->data. */
5269 x_destroy_x_image (ximg
)
5272 xassert (interrupt_input_blocked
);
5277 XDestroyImage (ximg
);
5282 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
5283 are width and height of both the image and pixmap. */
5286 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
5294 xassert (interrupt_input_blocked
);
5295 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
5296 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
5297 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
5302 /***********************************************************************
5304 ***********************************************************************/
5306 static Lisp_Object x_find_image_file
P_ ((Lisp_Object
));
5307 static char *slurp_file
P_ ((char *, int *));
5310 /* Find image file FILE. Look in data-directory, then
5311 x-bitmap-file-path. Value is the full name of the file found, or
5312 nil if not found. */
5315 x_find_image_file (file
)
5318 Lisp_Object file_found
, search_path
;
5319 struct gcpro gcpro1
, gcpro2
;
5323 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
5324 GCPRO2 (file_found
, search_path
);
5326 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
5327 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
5339 /* Read FILE into memory. Value is a pointer to a buffer allocated
5340 with xmalloc holding FILE's contents. Value is null if an error
5341 occurred. *SIZE is set to the size of the file. */
5344 slurp_file (file
, size
)
5352 if (stat (file
, &st
) == 0
5353 && (fp
= fopen (file
, "r")) != NULL
5354 && (buf
= (char *) xmalloc (st
.st_size
),
5355 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5376 /***********************************************************************
5378 ***********************************************************************/
5380 static int xbm_scan
P_ ((char **, char *, char *, int *));
5381 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
5382 static int xbm_load_image
P_ ((struct frame
*f
, struct image
*img
,
5384 static int xbm_image_p
P_ ((Lisp_Object object
));
5385 static int xbm_read_bitmap_data
P_ ((char *, char *, int *, int *,
5387 static int xbm_file_p
P_ ((Lisp_Object
));
5390 /* Indices of image specification fields in xbm_format, below. */
5392 enum xbm_keyword_index
5410 /* Vector of image_keyword structures describing the format
5411 of valid XBM image specifications. */
5413 static struct image_keyword xbm_format
[XBM_LAST
] =
5415 {":type", IMAGE_SYMBOL_VALUE
, 1},
5416 {":file", IMAGE_STRING_VALUE
, 0},
5417 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5418 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5419 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5420 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
5421 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
5422 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5423 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5424 {":relief", IMAGE_INTEGER_VALUE
, 0},
5425 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5426 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5427 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5430 /* Structure describing the image type XBM. */
5432 static struct image_type xbm_type
=
5441 /* Tokens returned from xbm_scan. */
5450 /* Return non-zero if OBJECT is a valid XBM-type image specification.
5451 A valid specification is a list starting with the symbol `image'
5452 The rest of the list is a property list which must contain an
5455 If the specification specifies a file to load, it must contain
5456 an entry `:file FILENAME' where FILENAME is a string.
5458 If the specification is for a bitmap loaded from memory it must
5459 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
5460 WIDTH and HEIGHT are integers > 0. DATA may be:
5462 1. a string large enough to hold the bitmap data, i.e. it must
5463 have a size >= (WIDTH + 7) / 8 * HEIGHT
5465 2. a bool-vector of size >= WIDTH * HEIGHT
5467 3. a vector of strings or bool-vectors, one for each line of the
5470 4. A string containing an in-memory XBM file. WIDTH and HEIGHT
5471 may not be specified in this case because they are defined in the
5474 Both the file and data forms may contain the additional entries
5475 `:background COLOR' and `:foreground COLOR'. If not present,
5476 foreground and background of the frame on which the image is
5477 displayed is used. */
5480 xbm_image_p (object
)
5483 struct image_keyword kw
[XBM_LAST
];
5485 bcopy (xbm_format
, kw
, sizeof kw
);
5486 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
5489 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
5491 if (kw
[XBM_FILE
].count
)
5493 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
5496 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
5498 /* In-memory XBM file. */
5499 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
5507 /* Entries for `:width', `:height' and `:data' must be present. */
5508 if (!kw
[XBM_WIDTH
].count
5509 || !kw
[XBM_HEIGHT
].count
5510 || !kw
[XBM_DATA
].count
)
5513 data
= kw
[XBM_DATA
].value
;
5514 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
5515 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
5517 /* Check type of data, and width and height against contents of
5523 /* Number of elements of the vector must be >= height. */
5524 if (XVECTOR (data
)->size
< height
)
5527 /* Each string or bool-vector in data must be large enough
5528 for one line of the image. */
5529 for (i
= 0; i
< height
; ++i
)
5531 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
5536 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
5539 else if (BOOL_VECTOR_P (elt
))
5541 if (XBOOL_VECTOR (elt
)->size
< width
)
5548 else if (STRINGP (data
))
5551 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
5554 else if (BOOL_VECTOR_P (data
))
5556 if (XBOOL_VECTOR (data
)->size
< width
* height
)
5567 /* Scan a bitmap file. FP is the stream to read from. Value is
5568 either an enumerator from enum xbm_token, or a character for a
5569 single-character token, or 0 at end of file. If scanning an
5570 identifier, store the lexeme of the identifier in SVAL. If
5571 scanning a number, store its value in *IVAL. */
5574 xbm_scan (s
, end
, sval
, ival
)
5583 /* Skip white space. */
5584 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5589 else if (isdigit (c
))
5591 int value
= 0, digit
;
5593 if (c
== '0' && *s
< end
)
5596 if (c
== 'x' || c
== 'X')
5603 else if (c
>= 'a' && c
<= 'f')
5604 digit
= c
- 'a' + 10;
5605 else if (c
>= 'A' && c
<= 'F')
5606 digit
= c
- 'A' + 10;
5609 value
= 16 * value
+ digit
;
5612 else if (isdigit (c
))
5616 && (c
= *(*s
)++, isdigit (c
)))
5617 value
= 8 * value
+ c
- '0';
5624 && (c
= *(*s
)++, isdigit (c
)))
5625 value
= 10 * value
+ c
- '0';
5633 else if (isalpha (c
) || c
== '_')
5637 && (c
= *(*s
)++, (isalnum (c
) || c
== '_')))
5644 else if (c
== '/' && **s
== '*')
5646 /* C-style comment. */
5648 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
5661 /* Replacement for XReadBitmapFileData which isn't available under old
5662 X versions. CONTENTS is a pointer to a buffer to parse; END is the
5663 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
5664 the image. Return in *DATA the bitmap data allocated with xmalloc.
5665 Value is non-zero if successful. DATA null means just test if
5666 CONTENTS looks like an in-memory XBM file. */
5669 xbm_read_bitmap_data (contents
, end
, width
, height
, data
)
5670 char *contents
, *end
;
5671 int *width
, *height
;
5672 unsigned char **data
;
5675 char buffer
[BUFSIZ
];
5678 int bytes_per_line
, i
, nbytes
;
5684 LA1 = xbm_scan (&s, end, buffer, &value)
5686 #define expect(TOKEN) \
5687 if (LA1 != (TOKEN)) \
5692 #define expect_ident(IDENT) \
5693 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
5698 *width
= *height
= -1;
5701 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
5703 /* Parse defines for width, height and hot-spots. */
5707 expect_ident ("define");
5708 expect (XBM_TK_IDENT
);
5710 if (LA1
== XBM_TK_NUMBER
);
5712 char *p
= strrchr (buffer
, '_');
5713 p
= p
? p
+ 1 : buffer
;
5714 if (strcmp (p
, "width") == 0)
5716 else if (strcmp (p
, "height") == 0)
5719 expect (XBM_TK_NUMBER
);
5722 if (*width
< 0 || *height
< 0)
5724 else if (data
== NULL
)
5727 /* Parse bits. Must start with `static'. */
5728 expect_ident ("static");
5729 if (LA1
== XBM_TK_IDENT
)
5731 if (strcmp (buffer
, "unsigned") == 0)
5734 expect_ident ("char");
5736 else if (strcmp (buffer
, "short") == 0)
5740 if (*width
% 16 && *width
% 16 < 9)
5743 else if (strcmp (buffer
, "char") == 0)
5751 expect (XBM_TK_IDENT
);
5757 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
5758 nbytes
= bytes_per_line
* *height
;
5759 p
= *data
= (char *) xmalloc (nbytes
);
5763 for (i
= 0; i
< nbytes
; i
+= 2)
5766 expect (XBM_TK_NUMBER
);
5769 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
5772 if (LA1
== ',' || LA1
== '}')
5780 for (i
= 0; i
< nbytes
; ++i
)
5783 expect (XBM_TK_NUMBER
);
5787 if (LA1
== ',' || LA1
== '}')
5812 /* Load XBM image IMG which will be displayed on frame F from buffer
5813 CONTENTS. END is the end of the buffer. Value is non-zero if
5817 xbm_load_image (f
, img
, contents
, end
)
5820 char *contents
, *end
;
5823 unsigned char *data
;
5826 rc
= xbm_read_bitmap_data (contents
, end
, &img
->width
, &img
->height
, &data
);
5829 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
5830 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
5831 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
5834 xassert (img
->width
> 0 && img
->height
> 0);
5836 /* Get foreground and background colors, maybe allocate colors. */
5837 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
5839 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
5840 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
5843 background
= x_alloc_image_color (f
, img
, value
, background
);
5844 img
->background
= background
;
5845 img
->background_valid
= 1;
5849 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
5852 img
->width
, img
->height
,
5853 foreground
, background
,
5857 if (img
->pixmap
== None
)
5859 x_clear_image (f
, img
);
5860 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
5866 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
5872 /* Value is non-zero if DATA looks like an in-memory XBM file. */
5879 return (STRINGP (data
)
5880 && xbm_read_bitmap_data (SDATA (data
),
5887 /* Fill image IMG which is used on frame F with pixmap data. Value is
5888 non-zero if successful. */
5896 Lisp_Object file_name
;
5898 xassert (xbm_image_p (img
->spec
));
5900 /* If IMG->spec specifies a file name, create a non-file spec from it. */
5901 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
5902 if (STRINGP (file_name
))
5907 struct gcpro gcpro1
;
5909 file
= x_find_image_file (file_name
);
5911 if (!STRINGP (file
))
5913 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
5918 contents
= slurp_file (SDATA (file
), &size
);
5919 if (contents
== NULL
)
5921 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
5926 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
5931 struct image_keyword fmt
[XBM_LAST
];
5934 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
5935 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
5938 int in_memory_file_p
= 0;
5940 /* See if data looks like an in-memory XBM file. */
5941 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5942 in_memory_file_p
= xbm_file_p (data
);
5944 /* Parse the image specification. */
5945 bcopy (xbm_format
, fmt
, sizeof fmt
);
5946 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
5949 /* Get specified width, and height. */
5950 if (!in_memory_file_p
)
5952 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
5953 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
5954 xassert (img
->width
> 0 && img
->height
> 0);
5957 /* Get foreground and background colors, maybe allocate colors. */
5958 if (fmt
[XBM_FOREGROUND
].count
5959 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
5960 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
5962 if (fmt
[XBM_BACKGROUND
].count
5963 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
5964 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
5967 if (in_memory_file_p
)
5968 success_p
= xbm_load_image (f
, img
, SDATA (data
),
5977 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
5979 p
= bits
= (char *) alloca (nbytes
* img
->height
);
5980 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
5982 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
5984 bcopy (SDATA (line
), p
, nbytes
);
5986 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
5989 else if (STRINGP (data
))
5990 bits
= SDATA (data
);
5992 bits
= XBOOL_VECTOR (data
)->data
;
5994 /* Create the pixmap. */
5995 depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
5997 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
6000 img
->width
, img
->height
,
6001 foreground
, background
,
6007 image_error ("Unable to create pixmap for XBM image `%s'",
6009 x_clear_image (f
, img
);
6019 /***********************************************************************
6021 ***********************************************************************/
6025 static int xpm_image_p
P_ ((Lisp_Object object
));
6026 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
6027 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
6029 #include "X11/xpm.h"
6031 /* The symbol `xpm' identifying XPM-format images. */
6035 /* Indices of image specification fields in xpm_format, below. */
6037 enum xpm_keyword_index
6053 /* Vector of image_keyword structures describing the format
6054 of valid XPM image specifications. */
6056 static struct image_keyword xpm_format
[XPM_LAST
] =
6058 {":type", IMAGE_SYMBOL_VALUE
, 1},
6059 {":file", IMAGE_STRING_VALUE
, 0},
6060 {":data", IMAGE_STRING_VALUE
, 0},
6061 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6062 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6063 {":relief", IMAGE_INTEGER_VALUE
, 0},
6064 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6065 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6066 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6067 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6068 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6071 /* Structure describing the image type XBM. */
6073 static struct image_type xpm_type
=
6083 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
6084 functions for allocating image colors. Our own functions handle
6085 color allocation failures more gracefully than the ones on the XPM
6088 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
6089 #define ALLOC_XPM_COLORS
6092 #ifdef ALLOC_XPM_COLORS
6094 static void xpm_init_color_cache
P_ ((struct frame
*, XpmAttributes
*));
6095 static void xpm_free_color_cache
P_ ((void));
6096 static int xpm_lookup_color
P_ ((struct frame
*, char *, XColor
*));
6097 static int xpm_color_bucket
P_ ((char *));
6098 static struct xpm_cached_color
*xpm_cache_color
P_ ((struct frame
*, char *,
6101 /* An entry in a hash table used to cache color definitions of named
6102 colors. This cache is necessary to speed up XPM image loading in
6103 case we do color allocations ourselves. Without it, we would need
6104 a call to XParseColor per pixel in the image. */
6106 struct xpm_cached_color
6108 /* Next in collision chain. */
6109 struct xpm_cached_color
*next
;
6111 /* Color definition (RGB and pixel color). */
6118 /* The hash table used for the color cache, and its bucket vector
6121 #define XPM_COLOR_CACHE_BUCKETS 1001
6122 struct xpm_cached_color
**xpm_color_cache
;
6124 /* Initialize the color cache. */
6127 xpm_init_color_cache (f
, attrs
)
6129 XpmAttributes
*attrs
;
6131 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
6132 xpm_color_cache
= (struct xpm_cached_color
**) xmalloc (nbytes
);
6133 memset (xpm_color_cache
, 0, nbytes
);
6134 init_color_table ();
6136 if (attrs
->valuemask
& XpmColorSymbols
)
6141 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
6142 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6143 attrs
->colorsymbols
[i
].value
, &color
))
6145 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
6147 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
6153 /* Free the color cache. */
6156 xpm_free_color_cache ()
6158 struct xpm_cached_color
*p
, *next
;
6161 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
6162 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
6168 xfree (xpm_color_cache
);
6169 xpm_color_cache
= NULL
;
6170 free_color_table ();
6174 /* Return the bucket index for color named COLOR_NAME in the color
6178 xpm_color_bucket (color_name
)
6184 for (s
= color_name
; *s
; ++s
)
6186 return h
%= XPM_COLOR_CACHE_BUCKETS
;
6190 /* On frame F, cache values COLOR for color with name COLOR_NAME.
6191 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
6194 static struct xpm_cached_color
*
6195 xpm_cache_color (f
, color_name
, color
, bucket
)
6202 struct xpm_cached_color
*p
;
6205 bucket
= xpm_color_bucket (color_name
);
6207 nbytes
= sizeof *p
+ strlen (color_name
);
6208 p
= (struct xpm_cached_color
*) xmalloc (nbytes
);
6209 strcpy (p
->name
, color_name
);
6211 p
->next
= xpm_color_cache
[bucket
];
6212 xpm_color_cache
[bucket
] = p
;
6217 /* Look up color COLOR_NAME for frame F in the color cache. If found,
6218 return the cached definition in *COLOR. Otherwise, make a new
6219 entry in the cache and allocate the color. Value is zero if color
6220 allocation failed. */
6223 xpm_lookup_color (f
, color_name
, color
)
6228 struct xpm_cached_color
*p
;
6229 int h
= xpm_color_bucket (color_name
);
6231 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
6232 if (strcmp (p
->name
, color_name
) == 0)
6237 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6240 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
6242 p
= xpm_cache_color (f
, color_name
, color
, h
);
6244 /* You get `opaque' at least from ImageMagick converting pbm to xpm
6245 with transparency, and it's useful. */
6246 else if (strcmp ("opaque", color_name
) == 0)
6248 bzero (color
, sizeof (XColor
)); /* Is this necessary/correct? */
6249 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
6250 p
= xpm_cache_color (f
, color_name
, color
, h
);
6257 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
6258 CLOSURE is a pointer to the frame on which we allocate the
6259 color. Return in *COLOR the allocated color. Value is non-zero
6263 xpm_alloc_color (dpy
, cmap
, color_name
, color
, closure
)
6270 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
6274 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
6275 is a pointer to the frame on which we allocate the color. Value is
6276 non-zero if successful. */
6279 xpm_free_colors (dpy
, cmap
, pixels
, npixels
, closure
)
6289 #endif /* ALLOC_XPM_COLORS */
6292 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
6293 for XPM images. Such a list must consist of conses whose car and
6297 xpm_valid_color_symbols_p (color_symbols
)
6298 Lisp_Object color_symbols
;
6300 while (CONSP (color_symbols
))
6302 Lisp_Object sym
= XCAR (color_symbols
);
6304 || !STRINGP (XCAR (sym
))
6305 || !STRINGP (XCDR (sym
)))
6307 color_symbols
= XCDR (color_symbols
);
6310 return NILP (color_symbols
);
6314 /* Value is non-zero if OBJECT is a valid XPM image specification. */
6317 xpm_image_p (object
)
6320 struct image_keyword fmt
[XPM_LAST
];
6321 bcopy (xpm_format
, fmt
, sizeof fmt
);
6322 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
6323 /* Either `:file' or `:data' must be present. */
6324 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
6325 /* Either no `:color-symbols' or it's a list of conses
6326 whose car and cdr are strings. */
6327 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
6328 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
6332 /* Load image IMG which will be displayed on frame F. Value is
6333 non-zero if successful. */
6341 XpmAttributes attrs
;
6342 Lisp_Object specified_file
, color_symbols
;
6344 /* Configure the XPM lib. Use the visual of frame F. Allocate
6345 close colors. Return colors allocated. */
6346 bzero (&attrs
, sizeof attrs
);
6347 attrs
.visual
= FRAME_X_VISUAL (f
);
6348 attrs
.colormap
= FRAME_X_COLORMAP (f
);
6349 attrs
.valuemask
|= XpmVisual
;
6350 attrs
.valuemask
|= XpmColormap
;
6352 #ifdef ALLOC_XPM_COLORS
6353 /* Allocate colors with our own functions which handle
6354 failing color allocation more gracefully. */
6355 attrs
.color_closure
= f
;
6356 attrs
.alloc_color
= xpm_alloc_color
;
6357 attrs
.free_colors
= xpm_free_colors
;
6358 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
6359 #else /* not ALLOC_XPM_COLORS */
6360 /* Let the XPM lib allocate colors. */
6361 attrs
.valuemask
|= XpmReturnAllocPixels
;
6362 #ifdef XpmAllocCloseColors
6363 attrs
.alloc_close_colors
= 1;
6364 attrs
.valuemask
|= XpmAllocCloseColors
;
6365 #else /* not XpmAllocCloseColors */
6366 attrs
.closeness
= 600;
6367 attrs
.valuemask
|= XpmCloseness
;
6368 #endif /* not XpmAllocCloseColors */
6369 #endif /* ALLOC_XPM_COLORS */
6371 /* If image specification contains symbolic color definitions, add
6372 these to `attrs'. */
6373 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
6374 if (CONSP (color_symbols
))
6377 XpmColorSymbol
*xpm_syms
;
6380 attrs
.valuemask
|= XpmColorSymbols
;
6382 /* Count number of symbols. */
6383 attrs
.numsymbols
= 0;
6384 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
6387 /* Allocate an XpmColorSymbol array. */
6388 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
6389 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
6390 bzero (xpm_syms
, size
);
6391 attrs
.colorsymbols
= xpm_syms
;
6393 /* Fill the color symbol array. */
6394 for (tail
= color_symbols
, i
= 0;
6396 ++i
, tail
= XCDR (tail
))
6398 Lisp_Object name
= XCAR (XCAR (tail
));
6399 Lisp_Object color
= XCDR (XCAR (tail
));
6400 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
6401 strcpy (xpm_syms
[i
].name
, SDATA (name
));
6402 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
6403 strcpy (xpm_syms
[i
].value
, SDATA (color
));
6407 /* Create a pixmap for the image, either from a file, or from a
6408 string buffer containing data in the same format as an XPM file. */
6409 #ifdef ALLOC_XPM_COLORS
6410 xpm_init_color_cache (f
, &attrs
);
6413 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6414 if (STRINGP (specified_file
))
6416 Lisp_Object file
= x_find_image_file (specified_file
);
6417 if (!STRINGP (file
))
6419 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6423 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6424 SDATA (file
), &img
->pixmap
, &img
->mask
,
6429 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
6430 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6432 &img
->pixmap
, &img
->mask
,
6436 if (rc
== XpmSuccess
)
6438 #ifdef ALLOC_XPM_COLORS
6439 img
->colors
= colors_in_color_table (&img
->ncolors
);
6440 #else /* not ALLOC_XPM_COLORS */
6443 img
->ncolors
= attrs
.nalloc_pixels
;
6444 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
6445 * sizeof *img
->colors
);
6446 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
6448 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
6449 #ifdef DEBUG_X_COLORS
6450 register_color (img
->colors
[i
]);
6453 #endif /* not ALLOC_XPM_COLORS */
6455 img
->width
= attrs
.width
;
6456 img
->height
= attrs
.height
;
6457 xassert (img
->width
> 0 && img
->height
> 0);
6459 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
6460 XpmFreeAttributes (&attrs
);
6467 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
6470 case XpmFileInvalid
:
6471 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
6475 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
6478 case XpmColorFailed
:
6479 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
6483 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
6488 #ifdef ALLOC_XPM_COLORS
6489 xpm_free_color_cache ();
6491 return rc
== XpmSuccess
;
6494 #endif /* HAVE_XPM != 0 */
6497 /***********************************************************************
6499 ***********************************************************************/
6501 /* An entry in the color table mapping an RGB color to a pixel color. */
6506 unsigned long pixel
;
6508 /* Next in color table collision list. */
6509 struct ct_color
*next
;
6512 /* The bucket vector size to use. Must be prime. */
6516 /* Value is a hash of the RGB color given by R, G, and B. */
6518 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
6520 /* The color hash table. */
6522 struct ct_color
**ct_table
;
6524 /* Number of entries in the color table. */
6526 int ct_colors_allocated
;
6528 /* Initialize the color table. */
6533 int size
= CT_SIZE
* sizeof (*ct_table
);
6534 ct_table
= (struct ct_color
**) xmalloc (size
);
6535 bzero (ct_table
, size
);
6536 ct_colors_allocated
= 0;
6540 /* Free memory associated with the color table. */
6546 struct ct_color
*p
, *next
;
6548 for (i
= 0; i
< CT_SIZE
; ++i
)
6549 for (p
= ct_table
[i
]; p
; p
= next
)
6560 /* Value is a pixel color for RGB color R, G, B on frame F. If an
6561 entry for that color already is in the color table, return the
6562 pixel color of that entry. Otherwise, allocate a new color for R,
6563 G, B, and make an entry in the color table. */
6565 static unsigned long
6566 lookup_rgb_color (f
, r
, g
, b
)
6570 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
6571 int i
= hash
% CT_SIZE
;
6574 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6575 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
6588 cmap
= FRAME_X_COLORMAP (f
);
6589 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6593 ++ct_colors_allocated
;
6595 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6599 p
->pixel
= color
.pixel
;
6600 p
->next
= ct_table
[i
];
6604 return FRAME_FOREGROUND_PIXEL (f
);
6611 /* Look up pixel color PIXEL which is used on frame F in the color
6612 table. If not already present, allocate it. Value is PIXEL. */
6614 static unsigned long
6615 lookup_pixel_color (f
, pixel
)
6617 unsigned long pixel
;
6619 int i
= pixel
% CT_SIZE
;
6622 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6623 if (p
->pixel
== pixel
)
6632 cmap
= FRAME_X_COLORMAP (f
);
6633 color
.pixel
= pixel
;
6634 x_query_color (f
, &color
);
6635 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6639 ++ct_colors_allocated
;
6641 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6646 p
->next
= ct_table
[i
];
6650 return FRAME_FOREGROUND_PIXEL (f
);
6657 /* Value is a vector of all pixel colors contained in the color table,
6658 allocated via xmalloc. Set *N to the number of colors. */
6660 static unsigned long *
6661 colors_in_color_table (n
)
6666 unsigned long *colors
;
6668 if (ct_colors_allocated
== 0)
6675 colors
= (unsigned long *) xmalloc (ct_colors_allocated
6677 *n
= ct_colors_allocated
;
6679 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
6680 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6681 colors
[j
++] = p
->pixel
;
6689 /***********************************************************************
6691 ***********************************************************************/
6693 static XColor
*x_to_xcolors
P_ ((struct frame
*, struct image
*, int));
6694 static void x_from_xcolors
P_ ((struct frame
*, struct image
*, XColor
*));
6695 static void x_detect_edges
P_ ((struct frame
*, struct image
*, int[9], int));
6697 /* Non-zero means draw a cross on images having `:conversion
6700 int cross_disabled_images
;
6702 /* Edge detection matrices for different edge-detection
6705 static int emboss_matrix
[9] = {
6707 2, -1, 0, /* y - 1 */
6709 0, 1, -2 /* y + 1 */
6712 static int laplace_matrix
[9] = {
6714 1, 0, 0, /* y - 1 */
6716 0, 0, -1 /* y + 1 */
6719 /* Value is the intensity of the color whose red/green/blue values
6722 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
6725 /* On frame F, return an array of XColor structures describing image
6726 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
6727 non-zero means also fill the red/green/blue members of the XColor
6728 structures. Value is a pointer to the array of XColors structures,
6729 allocated with xmalloc; it must be freed by the caller. */
6732 x_to_xcolors (f
, img
, rgb_p
)
6741 colors
= (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *colors
);
6743 /* Get the X image IMG->pixmap. */
6744 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
6745 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
6747 /* Fill the `pixel' members of the XColor array. I wished there
6748 were an easy and portable way to circumvent XGetPixel. */
6750 for (y
= 0; y
< img
->height
; ++y
)
6754 for (x
= 0; x
< img
->width
; ++x
, ++p
)
6755 p
->pixel
= XGetPixel (ximg
, x
, y
);
6758 x_query_colors (f
, row
, img
->width
);
6761 XDestroyImage (ximg
);
6766 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
6767 RGB members are set. F is the frame on which this all happens.
6768 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
6771 x_from_xcolors (f
, img
, colors
)
6781 init_color_table ();
6783 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
6786 for (y
= 0; y
< img
->height
; ++y
)
6787 for (x
= 0; x
< img
->width
; ++x
, ++p
)
6789 unsigned long pixel
;
6790 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
6791 XPutPixel (oimg
, x
, y
, pixel
);
6795 x_clear_image_1 (f
, img
, 1, 0, 1);
6797 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
6798 x_destroy_x_image (oimg
);
6799 img
->pixmap
= pixmap
;
6800 img
->colors
= colors_in_color_table (&img
->ncolors
);
6801 free_color_table ();
6805 /* On frame F, perform edge-detection on image IMG.
6807 MATRIX is a nine-element array specifying the transformation
6808 matrix. See emboss_matrix for an example.
6810 COLOR_ADJUST is a color adjustment added to each pixel of the
6814 x_detect_edges (f
, img
, matrix
, color_adjust
)
6817 int matrix
[9], color_adjust
;
6819 XColor
*colors
= x_to_xcolors (f
, img
, 1);
6823 for (i
= sum
= 0; i
< 9; ++i
)
6824 sum
+= abs (matrix
[i
]);
6826 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
6828 new = (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *new);
6830 for (y
= 0; y
< img
->height
; ++y
)
6832 p
= COLOR (new, 0, y
);
6833 p
->red
= p
->green
= p
->blue
= 0xffff/2;
6834 p
= COLOR (new, img
->width
- 1, y
);
6835 p
->red
= p
->green
= p
->blue
= 0xffff/2;
6838 for (x
= 1; x
< img
->width
- 1; ++x
)
6840 p
= COLOR (new, x
, 0);
6841 p
->red
= p
->green
= p
->blue
= 0xffff/2;
6842 p
= COLOR (new, x
, img
->height
- 1);
6843 p
->red
= p
->green
= p
->blue
= 0xffff/2;
6846 for (y
= 1; y
< img
->height
- 1; ++y
)
6848 p
= COLOR (new, 1, y
);
6850 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
6852 int r
, g
, b
, y1
, x1
;
6855 for (y1
= y
- 1; y1
< y
+ 2; ++y1
)
6856 for (x1
= x
- 1; x1
< x
+ 2; ++x1
, ++i
)
6859 XColor
*t
= COLOR (colors
, x1
, y1
);
6860 r
+= matrix
[i
] * t
->red
;
6861 g
+= matrix
[i
] * t
->green
;
6862 b
+= matrix
[i
] * t
->blue
;
6865 r
= (r
/ sum
+ color_adjust
) & 0xffff;
6866 g
= (g
/ sum
+ color_adjust
) & 0xffff;
6867 b
= (b
/ sum
+ color_adjust
) & 0xffff;
6868 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
6873 x_from_xcolors (f
, img
, new);
6879 /* Perform the pre-defined `emboss' edge-detection on image IMG
6887 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
6891 /* Perform the pre-defined `laplace' edge-detection on image IMG
6899 x_detect_edges (f
, img
, laplace_matrix
, 45000);
6903 /* Perform edge-detection on image IMG on frame F, with specified
6904 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
6906 MATRIX must be either
6908 - a list of at least 9 numbers in row-major form
6909 - a vector of at least 9 numbers
6911 COLOR_ADJUST nil means use a default; otherwise it must be a
6915 x_edge_detection (f
, img
, matrix
, color_adjust
)
6918 Lisp_Object matrix
, color_adjust
;
6926 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
6927 ++i
, matrix
= XCDR (matrix
))
6928 trans
[i
] = XFLOATINT (XCAR (matrix
));
6930 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
6932 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
6933 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
6936 if (NILP (color_adjust
))
6937 color_adjust
= make_number (0xffff / 2);
6939 if (i
== 9 && NUMBERP (color_adjust
))
6940 x_detect_edges (f
, img
, trans
, (int) XFLOATINT (color_adjust
));
6944 /* Transform image IMG on frame F so that it looks disabled. */
6947 x_disable_image (f
, img
)
6951 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6953 if (dpyinfo
->n_planes
>= 2)
6955 /* Color (or grayscale). Convert to gray, and equalize. Just
6956 drawing such images with a stipple can look very odd, so
6957 we're using this method instead. */
6958 XColor
*colors
= x_to_xcolors (f
, img
, 1);
6960 const int h
= 15000;
6961 const int l
= 30000;
6963 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
6967 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
6968 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
6969 p
->red
= p
->green
= p
->blue
= i2
;
6972 x_from_xcolors (f
, img
, colors
);
6975 /* Draw a cross over the disabled image, if we must or if we
6977 if (dpyinfo
->n_planes
< 2 || cross_disabled_images
)
6979 Display
*dpy
= FRAME_X_DISPLAY (f
);
6982 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
6983 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
6984 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
6985 img
->width
- 1, img
->height
- 1);
6986 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
6992 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
6993 XSetForeground (dpy
, gc
, WHITE_PIX_DEFAULT (f
));
6994 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
6995 img
->width
- 1, img
->height
- 1);
6996 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
7004 /* Build a mask for image IMG which is used on frame F. FILE is the
7005 name of an image file, for error messages. HOW determines how to
7006 determine the background color of IMG. If it is a list '(R G B)',
7007 with R, G, and B being integers >= 0, take that as the color of the
7008 background. Otherwise, determine the background color of IMG
7009 heuristically. Value is non-zero if successful. */
7012 x_build_heuristic_mask (f
, img
, how
)
7017 Display
*dpy
= FRAME_X_DISPLAY (f
);
7018 XImage
*ximg
, *mask_img
;
7019 int x
, y
, rc
, use_img_background
;
7020 unsigned long bg
= 0;
7024 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
7026 img
->background_transparent_valid
= 0;
7029 /* Create an image and pixmap serving as mask. */
7030 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
7031 &mask_img
, &img
->mask
);
7035 /* Get the X image of IMG->pixmap. */
7036 ximg
= XGetImage (dpy
, img
->pixmap
, 0, 0, img
->width
, img
->height
,
7039 /* Determine the background color of ximg. If HOW is `(R G B)'
7040 take that as color. Otherwise, use the image's background color. */
7041 use_img_background
= 1;
7047 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
7049 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
7053 if (i
== 3 && NILP (how
))
7055 char color_name
[30];
7056 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
7057 bg
= x_alloc_image_color (f
, img
, build_string (color_name
), 0);
7058 use_img_background
= 0;
7062 if (use_img_background
)
7063 bg
= four_corners_best (ximg
, img
->width
, img
->height
);
7065 /* Set all bits in mask_img to 1 whose color in ximg is different
7066 from the background color bg. */
7067 for (y
= 0; y
< img
->height
; ++y
)
7068 for (x
= 0; x
< img
->width
; ++x
)
7069 XPutPixel (mask_img
, x
, y
, XGetPixel (ximg
, x
, y
) != bg
);
7071 /* Fill in the background_transparent field while we have the mask handy. */
7072 image_background_transparent (img
, f
, mask_img
);
7074 /* Put mask_img into img->mask. */
7075 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
7076 x_destroy_x_image (mask_img
);
7077 XDestroyImage (ximg
);
7084 /***********************************************************************
7085 PBM (mono, gray, color)
7086 ***********************************************************************/
7088 static int pbm_image_p
P_ ((Lisp_Object object
));
7089 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
7090 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
7092 /* The symbol `pbm' identifying images of this type. */
7096 /* Indices of image specification fields in gs_format, below. */
7098 enum pbm_keyword_index
7114 /* Vector of image_keyword structures describing the format
7115 of valid user-defined image specifications. */
7117 static struct image_keyword pbm_format
[PBM_LAST
] =
7119 {":type", IMAGE_SYMBOL_VALUE
, 1},
7120 {":file", IMAGE_STRING_VALUE
, 0},
7121 {":data", IMAGE_STRING_VALUE
, 0},
7122 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7123 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7124 {":relief", IMAGE_INTEGER_VALUE
, 0},
7125 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7126 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7127 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7128 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
7129 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7132 /* Structure describing the image type `pbm'. */
7134 static struct image_type pbm_type
=
7144 /* Return non-zero if OBJECT is a valid PBM image specification. */
7147 pbm_image_p (object
)
7150 struct image_keyword fmt
[PBM_LAST
];
7152 bcopy (pbm_format
, fmt
, sizeof fmt
);
7154 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
7157 /* Must specify either :data or :file. */
7158 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
7162 /* Scan a decimal number from *S and return it. Advance *S while
7163 reading the number. END is the end of the string. Value is -1 at
7167 pbm_scan_number (s
, end
)
7168 unsigned char **s
, *end
;
7170 int c
= 0, val
= -1;
7174 /* Skip white-space. */
7175 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
7180 /* Skip comment to end of line. */
7181 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
7184 else if (isdigit (c
))
7186 /* Read decimal number. */
7188 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
7189 val
= 10 * val
+ c
- '0';
7200 /* Load PBM image IMG for use on frame F. */
7208 int width
, height
, max_color_idx
= 0;
7210 Lisp_Object file
, specified_file
;
7211 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
7212 struct gcpro gcpro1
;
7213 unsigned char *contents
= NULL
;
7214 unsigned char *end
, *p
;
7217 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7221 if (STRINGP (specified_file
))
7223 file
= x_find_image_file (specified_file
);
7224 if (!STRINGP (file
))
7226 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7231 contents
= slurp_file (SDATA (file
), &size
);
7232 if (contents
== NULL
)
7234 image_error ("Error reading `%s'", file
, Qnil
);
7240 end
= contents
+ size
;
7245 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7247 end
= p
+ SBYTES (data
);
7250 /* Check magic number. */
7251 if (end
- p
< 2 || *p
++ != 'P')
7253 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7263 raw_p
= 0, type
= PBM_MONO
;
7267 raw_p
= 0, type
= PBM_GRAY
;
7271 raw_p
= 0, type
= PBM_COLOR
;
7275 raw_p
= 1, type
= PBM_MONO
;
7279 raw_p
= 1, type
= PBM_GRAY
;
7283 raw_p
= 1, type
= PBM_COLOR
;
7287 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7291 /* Read width, height, maximum color-component. Characters
7292 starting with `#' up to the end of a line are ignored. */
7293 width
= pbm_scan_number (&p
, end
);
7294 height
= pbm_scan_number (&p
, end
);
7296 if (type
!= PBM_MONO
)
7298 max_color_idx
= pbm_scan_number (&p
, end
);
7299 if (raw_p
&& max_color_idx
> 255)
7300 max_color_idx
= 255;
7305 || (type
!= PBM_MONO
&& max_color_idx
< 0))
7308 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7309 &ximg
, &img
->pixmap
))
7312 /* Initialize the color hash table. */
7313 init_color_table ();
7315 if (type
== PBM_MONO
)
7318 struct image_keyword fmt
[PBM_LAST
];
7319 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
7320 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
7322 /* Parse the image specification. */
7323 bcopy (pbm_format
, fmt
, sizeof fmt
);
7324 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
7326 /* Get foreground and background colors, maybe allocate colors. */
7327 if (fmt
[PBM_FOREGROUND
].count
7328 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
7329 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
7330 if (fmt
[PBM_BACKGROUND
].count
7331 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
7333 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
7334 img
->background
= bg
;
7335 img
->background_valid
= 1;
7338 for (y
= 0; y
< height
; ++y
)
7339 for (x
= 0; x
< width
; ++x
)
7349 g
= pbm_scan_number (&p
, end
);
7351 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
7356 for (y
= 0; y
< height
; ++y
)
7357 for (x
= 0; x
< width
; ++x
)
7361 if (type
== PBM_GRAY
)
7362 r
= g
= b
= raw_p
? *p
++ : pbm_scan_number (&p
, end
);
7371 r
= pbm_scan_number (&p
, end
);
7372 g
= pbm_scan_number (&p
, end
);
7373 b
= pbm_scan_number (&p
, end
);
7376 if (r
< 0 || g
< 0 || b
< 0)
7380 XDestroyImage (ximg
);
7381 image_error ("Invalid pixel value in image `%s'",
7386 /* RGB values are now in the range 0..max_color_idx.
7387 Scale this to the range 0..0xffff supported by X. */
7388 r
= (double) r
* 65535 / max_color_idx
;
7389 g
= (double) g
* 65535 / max_color_idx
;
7390 b
= (double) b
* 65535 / max_color_idx
;
7391 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7395 /* Store in IMG->colors the colors allocated for the image, and
7396 free the color table. */
7397 img
->colors
= colors_in_color_table (&img
->ncolors
);
7398 free_color_table ();
7400 /* Maybe fill in the background field while we have ximg handy. */
7401 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7402 IMAGE_BACKGROUND (img
, f
, ximg
);
7404 /* Put the image into a pixmap. */
7405 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7406 x_destroy_x_image (ximg
);
7409 img
->height
= height
;
7418 /***********************************************************************
7420 ***********************************************************************/
7426 /* Function prototypes. */
7428 static int png_image_p
P_ ((Lisp_Object object
));
7429 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
7431 /* The symbol `png' identifying images of this type. */
7435 /* Indices of image specification fields in png_format, below. */
7437 enum png_keyword_index
7452 /* Vector of image_keyword structures describing the format
7453 of valid user-defined image specifications. */
7455 static struct image_keyword png_format
[PNG_LAST
] =
7457 {":type", IMAGE_SYMBOL_VALUE
, 1},
7458 {":data", IMAGE_STRING_VALUE
, 0},
7459 {":file", IMAGE_STRING_VALUE
, 0},
7460 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7461 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7462 {":relief", IMAGE_INTEGER_VALUE
, 0},
7463 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7464 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7465 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7466 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7469 /* Structure describing the image type `png'. */
7471 static struct image_type png_type
=
7481 /* Return non-zero if OBJECT is a valid PNG image specification. */
7484 png_image_p (object
)
7487 struct image_keyword fmt
[PNG_LAST
];
7488 bcopy (png_format
, fmt
, sizeof fmt
);
7490 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
7493 /* Must specify either the :data or :file keyword. */
7494 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
7498 /* Error and warning handlers installed when the PNG library
7502 my_png_error (png_ptr
, msg
)
7503 png_struct
*png_ptr
;
7506 xassert (png_ptr
!= NULL
);
7507 image_error ("PNG error: %s", build_string (msg
), Qnil
);
7508 longjmp (png_ptr
->jmpbuf
, 1);
7513 my_png_warning (png_ptr
, msg
)
7514 png_struct
*png_ptr
;
7517 xassert (png_ptr
!= NULL
);
7518 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
7521 /* Memory source for PNG decoding. */
7523 struct png_memory_storage
7525 unsigned char *bytes
; /* The data */
7526 size_t len
; /* How big is it? */
7527 int index
; /* Where are we? */
7531 /* Function set as reader function when reading PNG image from memory.
7532 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
7533 bytes from the input to DATA. */
7536 png_read_from_memory (png_ptr
, data
, length
)
7537 png_structp png_ptr
;
7541 struct png_memory_storage
*tbr
7542 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
7544 if (length
> tbr
->len
- tbr
->index
)
7545 png_error (png_ptr
, "Read error");
7547 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
7548 tbr
->index
= tbr
->index
+ length
;
7551 /* Load PNG image IMG for use on frame F. Value is non-zero if
7559 Lisp_Object file
, specified_file
;
7560 Lisp_Object specified_data
;
7562 XImage
*ximg
, *mask_img
= NULL
;
7563 struct gcpro gcpro1
;
7564 png_struct
*png_ptr
= NULL
;
7565 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
7566 FILE *volatile fp
= NULL
;
7568 png_byte
* volatile pixels
= NULL
;
7569 png_byte
** volatile rows
= NULL
;
7570 png_uint_32 width
, height
;
7571 int bit_depth
, color_type
, interlace_type
;
7573 png_uint_32 row_bytes
;
7575 double screen_gamma
;
7576 struct png_memory_storage tbr
; /* Data to be read */
7578 /* Find out what file to load. */
7579 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7580 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7584 if (NILP (specified_data
))
7586 file
= x_find_image_file (specified_file
);
7587 if (!STRINGP (file
))
7589 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7594 /* Open the image file. */
7595 fp
= fopen (SDATA (file
), "rb");
7598 image_error ("Cannot open image file `%s'", file
, Qnil
);
7604 /* Check PNG signature. */
7605 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
7606 || !png_check_sig (sig
, sizeof sig
))
7608 image_error ("Not a PNG file: `%s'", file
, Qnil
);
7616 /* Read from memory. */
7617 tbr
.bytes
= SDATA (specified_data
);
7618 tbr
.len
= SBYTES (specified_data
);
7621 /* Check PNG signature. */
7622 if (tbr
.len
< sizeof sig
7623 || !png_check_sig (tbr
.bytes
, sizeof sig
))
7625 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
7630 /* Need to skip past the signature. */
7631 tbr
.bytes
+= sizeof (sig
);
7634 /* Initialize read and info structs for PNG lib. */
7635 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
7636 my_png_error
, my_png_warning
);
7639 if (fp
) fclose (fp
);
7644 info_ptr
= png_create_info_struct (png_ptr
);
7647 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
7648 if (fp
) fclose (fp
);
7653 end_info
= png_create_info_struct (png_ptr
);
7656 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
7657 if (fp
) fclose (fp
);
7662 /* Set error jump-back. We come back here when the PNG library
7663 detects an error. */
7664 if (setjmp (png_ptr
->jmpbuf
))
7668 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7671 if (fp
) fclose (fp
);
7676 /* Read image info. */
7677 if (!NILP (specified_data
))
7678 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
7680 png_init_io (png_ptr
, fp
);
7682 png_set_sig_bytes (png_ptr
, sizeof sig
);
7683 png_read_info (png_ptr
, info_ptr
);
7684 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
7685 &interlace_type
, NULL
, NULL
);
7687 /* If image contains simply transparency data, we prefer to
7688 construct a clipping mask. */
7689 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
7694 /* This function is easier to write if we only have to handle
7695 one data format: RGB or RGBA with 8 bits per channel. Let's
7696 transform other formats into that format. */
7698 /* Strip more than 8 bits per channel. */
7699 if (bit_depth
== 16)
7700 png_set_strip_16 (png_ptr
);
7702 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
7704 png_set_expand (png_ptr
);
7706 /* Convert grayscale images to RGB. */
7707 if (color_type
== PNG_COLOR_TYPE_GRAY
7708 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
7709 png_set_gray_to_rgb (png_ptr
);
7711 screen_gamma
= (f
->gamma
? 1 / f
->gamma
/ 0.45455 : 2.2);
7713 #if 0 /* Avoid double gamma correction for PNG images. */
7714 { /* Tell the PNG lib to handle gamma correction for us. */
7717 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
7718 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
7719 /* The libpng documentation says this is right in this case. */
7720 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7723 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
7724 /* Image contains gamma information. */
7725 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
7727 /* Use the standard default for the image gamma. */
7728 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7732 /* Handle alpha channel by combining the image with a background
7733 color. Do this only if a real alpha channel is supplied. For
7734 simple transparency, we prefer a clipping mask. */
7737 png_color_16
*image_bg
;
7738 Lisp_Object specified_bg
7739 = image_spec_value (img
->spec
, QCbackground
, NULL
);
7741 if (STRINGP (specified_bg
))
7742 /* The user specified `:background', use that. */
7745 if (x_defined_color (f
, SDATA (specified_bg
), &color
, 0))
7747 png_color_16 user_bg
;
7749 bzero (&user_bg
, sizeof user_bg
);
7750 user_bg
.red
= color
.red
;
7751 user_bg
.green
= color
.green
;
7752 user_bg
.blue
= color
.blue
;
7754 png_set_background (png_ptr
, &user_bg
,
7755 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7758 else if (png_get_bKGD (png_ptr
, info_ptr
, &image_bg
))
7759 /* Image contains a background color with which to
7760 combine the image. */
7761 png_set_background (png_ptr
, image_bg
,
7762 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
7765 /* Image does not contain a background color with which
7766 to combine the image data via an alpha channel. Use
7767 the frame's background instead. */
7770 png_color_16 frame_background
;
7772 cmap
= FRAME_X_COLORMAP (f
);
7773 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7774 x_query_color (f
, &color
);
7776 bzero (&frame_background
, sizeof frame_background
);
7777 frame_background
.red
= color
.red
;
7778 frame_background
.green
= color
.green
;
7779 frame_background
.blue
= color
.blue
;
7781 png_set_background (png_ptr
, &frame_background
,
7782 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7786 /* Update info structure. */
7787 png_read_update_info (png_ptr
, info_ptr
);
7789 /* Get number of channels. Valid values are 1 for grayscale images
7790 and images with a palette, 2 for grayscale images with transparency
7791 information (alpha channel), 3 for RGB images, and 4 for RGB
7792 images with alpha channel, i.e. RGBA. If conversions above were
7793 sufficient we should only have 3 or 4 channels here. */
7794 channels
= png_get_channels (png_ptr
, info_ptr
);
7795 xassert (channels
== 3 || channels
== 4);
7797 /* Number of bytes needed for one row of the image. */
7798 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
7800 /* Allocate memory for the image. */
7801 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
7802 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
7803 for (i
= 0; i
< height
; ++i
)
7804 rows
[i
] = pixels
+ i
* row_bytes
;
7806 /* Read the entire image. */
7807 png_read_image (png_ptr
, rows
);
7808 png_read_end (png_ptr
, info_ptr
);
7815 /* Create the X image and pixmap. */
7816 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
7820 /* Create an image and pixmap serving as mask if the PNG image
7821 contains an alpha channel. */
7824 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
7825 &mask_img
, &img
->mask
))
7827 x_destroy_x_image (ximg
);
7828 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
7833 /* Fill the X image and mask from PNG data. */
7834 init_color_table ();
7836 for (y
= 0; y
< height
; ++y
)
7838 png_byte
*p
= rows
[y
];
7840 for (x
= 0; x
< width
; ++x
)
7847 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7849 /* An alpha channel, aka mask channel, associates variable
7850 transparency with an image. Where other image formats
7851 support binary transparency---fully transparent or fully
7852 opaque---PNG allows up to 254 levels of partial transparency.
7853 The PNG library implements partial transparency by combining
7854 the image with a specified background color.
7856 I'm not sure how to handle this here nicely: because the
7857 background on which the image is displayed may change, for
7858 real alpha channel support, it would be necessary to create
7859 a new image for each possible background.
7861 What I'm doing now is that a mask is created if we have
7862 boolean transparency information. Otherwise I'm using
7863 the frame's background color to combine the image with. */
7868 XPutPixel (mask_img
, x
, y
, *p
> 0);
7874 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7875 /* Set IMG's background color from the PNG image, unless the user
7879 if (png_get_bKGD (png_ptr
, info_ptr
, &bg
))
7881 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
7882 img
->background_valid
= 1;
7886 /* Remember colors allocated for this image. */
7887 img
->colors
= colors_in_color_table (&img
->ncolors
);
7888 free_color_table ();
7891 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7896 img
->height
= height
;
7898 /* Maybe fill in the background field while we have ximg handy. */
7899 IMAGE_BACKGROUND (img
, f
, ximg
);
7901 /* Put the image into the pixmap, then free the X image and its buffer. */
7902 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7903 x_destroy_x_image (ximg
);
7905 /* Same for the mask. */
7908 /* Fill in the background_transparent field while we have the mask
7910 image_background_transparent (img
, f
, mask_img
);
7912 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
7913 x_destroy_x_image (mask_img
);
7920 #endif /* HAVE_PNG != 0 */
7924 /***********************************************************************
7926 ***********************************************************************/
7930 /* Work around a warning about HAVE_STDLIB_H being redefined in
7932 #ifdef HAVE_STDLIB_H
7933 #define HAVE_STDLIB_H_1
7934 #undef HAVE_STDLIB_H
7935 #endif /* HAVE_STLIB_H */
7937 #include <jpeglib.h>
7941 #ifdef HAVE_STLIB_H_1
7942 #define HAVE_STDLIB_H 1
7945 static int jpeg_image_p
P_ ((Lisp_Object object
));
7946 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
7948 /* The symbol `jpeg' identifying images of this type. */
7952 /* Indices of image specification fields in gs_format, below. */
7954 enum jpeg_keyword_index
7963 JPEG_HEURISTIC_MASK
,
7969 /* Vector of image_keyword structures describing the format
7970 of valid user-defined image specifications. */
7972 static struct image_keyword jpeg_format
[JPEG_LAST
] =
7974 {":type", IMAGE_SYMBOL_VALUE
, 1},
7975 {":data", IMAGE_STRING_VALUE
, 0},
7976 {":file", IMAGE_STRING_VALUE
, 0},
7977 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7978 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7979 {":relief", IMAGE_INTEGER_VALUE
, 0},
7980 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7981 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7982 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7983 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7986 /* Structure describing the image type `jpeg'. */
7988 static struct image_type jpeg_type
=
7998 /* Return non-zero if OBJECT is a valid JPEG image specification. */
8001 jpeg_image_p (object
)
8004 struct image_keyword fmt
[JPEG_LAST
];
8006 bcopy (jpeg_format
, fmt
, sizeof fmt
);
8008 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
8011 /* Must specify either the :data or :file keyword. */
8012 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
8016 struct my_jpeg_error_mgr
8018 struct jpeg_error_mgr pub
;
8019 jmp_buf setjmp_buffer
;
8024 my_error_exit (cinfo
)
8027 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
8028 longjmp (mgr
->setjmp_buffer
, 1);
8032 /* Init source method for JPEG data source manager. Called by
8033 jpeg_read_header() before any data is actually read. See
8034 libjpeg.doc from the JPEG lib distribution. */
8037 our_init_source (cinfo
)
8038 j_decompress_ptr cinfo
;
8043 /* Fill input buffer method for JPEG data source manager. Called
8044 whenever more data is needed. We read the whole image in one step,
8045 so this only adds a fake end of input marker at the end. */
8048 our_fill_input_buffer (cinfo
)
8049 j_decompress_ptr cinfo
;
8051 /* Insert a fake EOI marker. */
8052 struct jpeg_source_mgr
*src
= cinfo
->src
;
8053 static JOCTET buffer
[2];
8055 buffer
[0] = (JOCTET
) 0xFF;
8056 buffer
[1] = (JOCTET
) JPEG_EOI
;
8058 src
->next_input_byte
= buffer
;
8059 src
->bytes_in_buffer
= 2;
8064 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
8065 is the JPEG data source manager. */
8068 our_skip_input_data (cinfo
, num_bytes
)
8069 j_decompress_ptr cinfo
;
8072 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8076 if (num_bytes
> src
->bytes_in_buffer
)
8077 ERREXIT (cinfo
, JERR_INPUT_EOF
);
8079 src
->bytes_in_buffer
-= num_bytes
;
8080 src
->next_input_byte
+= num_bytes
;
8085 /* Method to terminate data source. Called by
8086 jpeg_finish_decompress() after all data has been processed. */
8089 our_term_source (cinfo
)
8090 j_decompress_ptr cinfo
;
8095 /* Set up the JPEG lib for reading an image from DATA which contains
8096 LEN bytes. CINFO is the decompression info structure created for
8097 reading the image. */
8100 jpeg_memory_src (cinfo
, data
, len
)
8101 j_decompress_ptr cinfo
;
8105 struct jpeg_source_mgr
*src
;
8107 if (cinfo
->src
== NULL
)
8109 /* First time for this JPEG object? */
8110 cinfo
->src
= (struct jpeg_source_mgr
*)
8111 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
8112 sizeof (struct jpeg_source_mgr
));
8113 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8114 src
->next_input_byte
= data
;
8117 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8118 src
->init_source
= our_init_source
;
8119 src
->fill_input_buffer
= our_fill_input_buffer
;
8120 src
->skip_input_data
= our_skip_input_data
;
8121 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
8122 src
->term_source
= our_term_source
;
8123 src
->bytes_in_buffer
= len
;
8124 src
->next_input_byte
= data
;
8128 /* Load image IMG for use on frame F. Patterned after example.c
8129 from the JPEG lib. */
8136 struct jpeg_decompress_struct cinfo
;
8137 struct my_jpeg_error_mgr mgr
;
8138 Lisp_Object file
, specified_file
;
8139 Lisp_Object specified_data
;
8140 FILE * volatile fp
= NULL
;
8142 int row_stride
, x
, y
;
8143 XImage
*ximg
= NULL
;
8145 unsigned long *colors
;
8147 struct gcpro gcpro1
;
8149 /* Open the JPEG file. */
8150 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8151 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8155 if (NILP (specified_data
))
8157 file
= x_find_image_file (specified_file
);
8158 if (!STRINGP (file
))
8160 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8165 fp
= fopen (SDATA (file
), "r");
8168 image_error ("Cannot open `%s'", file
, Qnil
);
8174 /* Customize libjpeg's error handling to call my_error_exit when an
8175 error is detected. This function will perform a longjmp. */
8176 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
8177 mgr
.pub
.error_exit
= my_error_exit
;
8179 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
8183 /* Called from my_error_exit. Display a JPEG error. */
8184 char buffer
[JMSG_LENGTH_MAX
];
8185 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
8186 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
8187 build_string (buffer
));
8190 /* Close the input file and destroy the JPEG object. */
8192 fclose ((FILE *) fp
);
8193 jpeg_destroy_decompress (&cinfo
);
8195 /* If we already have an XImage, free that. */
8196 x_destroy_x_image (ximg
);
8198 /* Free pixmap and colors. */
8199 x_clear_image (f
, img
);
8205 /* Create the JPEG decompression object. Let it read from fp.
8206 Read the JPEG image header. */
8207 jpeg_create_decompress (&cinfo
);
8209 if (NILP (specified_data
))
8210 jpeg_stdio_src (&cinfo
, (FILE *) fp
);
8212 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
8213 SBYTES (specified_data
));
8215 jpeg_read_header (&cinfo
, TRUE
);
8217 /* Customize decompression so that color quantization will be used.
8218 Start decompression. */
8219 cinfo
.quantize_colors
= TRUE
;
8220 jpeg_start_decompress (&cinfo
);
8221 width
= img
->width
= cinfo
.output_width
;
8222 height
= img
->height
= cinfo
.output_height
;
8224 /* Create X image and pixmap. */
8225 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8226 longjmp (mgr
.setjmp_buffer
, 2);
8228 /* Allocate colors. When color quantization is used,
8229 cinfo.actual_number_of_colors has been set with the number of
8230 colors generated, and cinfo.colormap is a two-dimensional array
8231 of color indices in the range 0..cinfo.actual_number_of_colors.
8232 No more than 255 colors will be generated. */
8236 if (cinfo
.out_color_components
> 2)
8237 ir
= 0, ig
= 1, ib
= 2;
8238 else if (cinfo
.out_color_components
> 1)
8239 ir
= 0, ig
= 1, ib
= 0;
8241 ir
= 0, ig
= 0, ib
= 0;
8243 /* Use the color table mechanism because it handles colors that
8244 cannot be allocated nicely. Such colors will be replaced with
8245 a default color, and we don't have to care about which colors
8246 can be freed safely, and which can't. */
8247 init_color_table ();
8248 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
8251 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
8253 /* Multiply RGB values with 255 because X expects RGB values
8254 in the range 0..0xffff. */
8255 int r
= cinfo
.colormap
[ir
][i
] << 8;
8256 int g
= cinfo
.colormap
[ig
][i
] << 8;
8257 int b
= cinfo
.colormap
[ib
][i
] << 8;
8258 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8261 /* Remember those colors actually allocated. */
8262 img
->colors
= colors_in_color_table (&img
->ncolors
);
8263 free_color_table ();
8267 row_stride
= width
* cinfo
.output_components
;
8268 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
8270 for (y
= 0; y
< height
; ++y
)
8272 jpeg_read_scanlines (&cinfo
, buffer
, 1);
8273 for (x
= 0; x
< cinfo
.output_width
; ++x
)
8274 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
8278 jpeg_finish_decompress (&cinfo
);
8279 jpeg_destroy_decompress (&cinfo
);
8281 fclose ((FILE *) fp
);
8283 /* Maybe fill in the background field while we have ximg handy. */
8284 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8285 IMAGE_BACKGROUND (img
, f
, ximg
);
8287 /* Put the image into the pixmap. */
8288 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8289 x_destroy_x_image (ximg
);
8294 #endif /* HAVE_JPEG */
8298 /***********************************************************************
8300 ***********************************************************************/
8306 static int tiff_image_p
P_ ((Lisp_Object object
));
8307 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
8309 /* The symbol `tiff' identifying images of this type. */
8313 /* Indices of image specification fields in tiff_format, below. */
8315 enum tiff_keyword_index
8324 TIFF_HEURISTIC_MASK
,
8330 /* Vector of image_keyword structures describing the format
8331 of valid user-defined image specifications. */
8333 static struct image_keyword tiff_format
[TIFF_LAST
] =
8335 {":type", IMAGE_SYMBOL_VALUE
, 1},
8336 {":data", IMAGE_STRING_VALUE
, 0},
8337 {":file", IMAGE_STRING_VALUE
, 0},
8338 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8339 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8340 {":relief", IMAGE_INTEGER_VALUE
, 0},
8341 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8342 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8343 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8344 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8347 /* Structure describing the image type `tiff'. */
8349 static struct image_type tiff_type
=
8359 /* Return non-zero if OBJECT is a valid TIFF image specification. */
8362 tiff_image_p (object
)
8365 struct image_keyword fmt
[TIFF_LAST
];
8366 bcopy (tiff_format
, fmt
, sizeof fmt
);
8368 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
8371 /* Must specify either the :data or :file keyword. */
8372 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
8376 /* Reading from a memory buffer for TIFF images Based on the PNG
8377 memory source, but we have to provide a lot of extra functions.
8380 We really only need to implement read and seek, but I am not
8381 convinced that the TIFF library is smart enough not to destroy
8382 itself if we only hand it the function pointers we need to
8387 unsigned char *bytes
;
8395 tiff_read_from_memory (data
, buf
, size
)
8400 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8402 if (size
> src
->len
- src
->index
)
8404 bcopy (src
->bytes
+ src
->index
, buf
, size
);
8411 tiff_write_from_memory (data
, buf
, size
)
8421 tiff_seek_in_memory (data
, off
, whence
)
8426 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8431 case SEEK_SET
: /* Go from beginning of source. */
8435 case SEEK_END
: /* Go from end of source. */
8436 idx
= src
->len
+ off
;
8439 case SEEK_CUR
: /* Go from current position. */
8440 idx
= src
->index
+ off
;
8443 default: /* Invalid `whence'. */
8447 if (idx
> src
->len
|| idx
< 0)
8456 tiff_close_memory (data
)
8465 tiff_mmap_memory (data
, pbase
, psize
)
8470 /* It is already _IN_ memory. */
8476 tiff_unmap_memory (data
, base
, size
)
8481 /* We don't need to do this. */
8486 tiff_size_of_memory (data
)
8489 return ((tiff_memory_source
*) data
)->len
;
8494 tiff_error_handler (title
, format
, ap
)
8495 const char *title
, *format
;
8501 len
= sprintf (buf
, "TIFF error: %s ", title
);
8502 vsprintf (buf
+ len
, format
, ap
);
8503 add_to_log (buf
, Qnil
, Qnil
);
8508 tiff_warning_handler (title
, format
, ap
)
8509 const char *title
, *format
;
8515 len
= sprintf (buf
, "TIFF warning: %s ", title
);
8516 vsprintf (buf
+ len
, format
, ap
);
8517 add_to_log (buf
, Qnil
, Qnil
);
8521 /* Load TIFF image IMG for use on frame F. Value is non-zero if
8529 Lisp_Object file
, specified_file
;
8530 Lisp_Object specified_data
;
8532 int width
, height
, x
, y
;
8536 struct gcpro gcpro1
;
8537 tiff_memory_source memsrc
;
8539 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8540 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8544 TIFFSetErrorHandler (tiff_error_handler
);
8545 TIFFSetWarningHandler (tiff_warning_handler
);
8547 if (NILP (specified_data
))
8549 /* Read from a file */
8550 file
= x_find_image_file (specified_file
);
8551 if (!STRINGP (file
))
8553 image_error ("Cannot find image file `%s'", file
, Qnil
);
8558 /* Try to open the image file. */
8559 tiff
= TIFFOpen (SDATA (file
), "r");
8562 image_error ("Cannot open `%s'", file
, Qnil
);
8569 /* Memory source! */
8570 memsrc
.bytes
= SDATA (specified_data
);
8571 memsrc
.len
= SBYTES (specified_data
);
8574 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
8575 (TIFFReadWriteProc
) tiff_read_from_memory
,
8576 (TIFFReadWriteProc
) tiff_write_from_memory
,
8577 tiff_seek_in_memory
,
8579 tiff_size_of_memory
,
8585 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
8591 /* Get width and height of the image, and allocate a raster buffer
8592 of width x height 32-bit values. */
8593 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
8594 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
8595 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
8597 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
8601 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
8607 /* Create the X image and pixmap. */
8608 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8615 /* Initialize the color table. */
8616 init_color_table ();
8618 /* Process the pixel raster. Origin is in the lower-left corner. */
8619 for (y
= 0; y
< height
; ++y
)
8621 uint32
*row
= buf
+ y
* width
;
8623 for (x
= 0; x
< width
; ++x
)
8625 uint32 abgr
= row
[x
];
8626 int r
= TIFFGetR (abgr
) << 8;
8627 int g
= TIFFGetG (abgr
) << 8;
8628 int b
= TIFFGetB (abgr
) << 8;
8629 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
8633 /* Remember the colors allocated for the image. Free the color table. */
8634 img
->colors
= colors_in_color_table (&img
->ncolors
);
8635 free_color_table ();
8638 img
->height
= height
;
8640 /* Maybe fill in the background field while we have ximg handy. */
8641 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8642 IMAGE_BACKGROUND (img
, f
, ximg
);
8644 /* Put the image into the pixmap, then free the X image and its buffer. */
8645 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8646 x_destroy_x_image (ximg
);
8653 #endif /* HAVE_TIFF != 0 */
8657 /***********************************************************************
8659 ***********************************************************************/
8663 #include <gif_lib.h>
8665 static int gif_image_p
P_ ((Lisp_Object object
));
8666 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
8668 /* The symbol `gif' identifying images of this type. */
8672 /* Indices of image specification fields in gif_format, below. */
8674 enum gif_keyword_index
8690 /* Vector of image_keyword structures describing the format
8691 of valid user-defined image specifications. */
8693 static struct image_keyword gif_format
[GIF_LAST
] =
8695 {":type", IMAGE_SYMBOL_VALUE
, 1},
8696 {":data", IMAGE_STRING_VALUE
, 0},
8697 {":file", IMAGE_STRING_VALUE
, 0},
8698 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8699 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8700 {":relief", IMAGE_INTEGER_VALUE
, 0},
8701 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8702 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8703 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8704 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8705 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8708 /* Structure describing the image type `gif'. */
8710 static struct image_type gif_type
=
8720 /* Return non-zero if OBJECT is a valid GIF image specification. */
8723 gif_image_p (object
)
8726 struct image_keyword fmt
[GIF_LAST
];
8727 bcopy (gif_format
, fmt
, sizeof fmt
);
8729 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
8732 /* Must specify either the :data or :file keyword. */
8733 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
8737 /* Reading a GIF image from memory
8738 Based on the PNG memory stuff to a certain extent. */
8742 unsigned char *bytes
;
8749 /* Make the current memory source available to gif_read_from_memory.
8750 It's done this way because not all versions of libungif support
8751 a UserData field in the GifFileType structure. */
8752 static gif_memory_source
*current_gif_memory_src
;
8755 gif_read_from_memory (file
, buf
, len
)
8760 gif_memory_source
*src
= current_gif_memory_src
;
8762 if (len
> src
->len
- src
->index
)
8765 bcopy (src
->bytes
+ src
->index
, buf
, len
);
8771 /* Load GIF image IMG for use on frame F. Value is non-zero if
8779 Lisp_Object file
, specified_file
;
8780 Lisp_Object specified_data
;
8781 int rc
, width
, height
, x
, y
, i
;
8783 ColorMapObject
*gif_color_map
;
8784 unsigned long pixel_colors
[256];
8786 struct gcpro gcpro1
;
8788 int ino
, image_left
, image_top
, image_width
, image_height
;
8789 gif_memory_source memsrc
;
8790 unsigned char *raster
;
8792 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8793 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8797 if (NILP (specified_data
))
8799 file
= x_find_image_file (specified_file
);
8800 if (!STRINGP (file
))
8802 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8807 /* Open the GIF file. */
8808 gif
= DGifOpenFileName (SDATA (file
));
8811 image_error ("Cannot open `%s'", file
, Qnil
);
8818 /* Read from memory! */
8819 current_gif_memory_src
= &memsrc
;
8820 memsrc
.bytes
= SDATA (specified_data
);
8821 memsrc
.len
= SBYTES (specified_data
);
8824 gif
= DGifOpen(&memsrc
, gif_read_from_memory
);
8827 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
8833 /* Read entire contents. */
8834 rc
= DGifSlurp (gif
);
8835 if (rc
== GIF_ERROR
)
8837 image_error ("Error reading `%s'", img
->spec
, Qnil
);
8838 DGifCloseFile (gif
);
8843 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
8844 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
8845 if (ino
>= gif
->ImageCount
)
8847 image_error ("Invalid image number `%s' in image `%s'",
8849 DGifCloseFile (gif
);
8854 width
= img
->width
= max (gif
->SWidth
, gif
->Image
.Left
+ gif
->Image
.Width
);
8855 height
= img
->height
= max (gif
->SHeight
, gif
->Image
.Top
+ gif
->Image
.Height
);
8857 /* Create the X image and pixmap. */
8858 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8860 DGifCloseFile (gif
);
8865 /* Allocate colors. */
8866 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
8868 gif_color_map
= gif
->SColorMap
;
8869 init_color_table ();
8870 bzero (pixel_colors
, sizeof pixel_colors
);
8872 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
8874 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
8875 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
8876 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
8877 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8880 img
->colors
= colors_in_color_table (&img
->ncolors
);
8881 free_color_table ();
8883 /* Clear the part of the screen image that are not covered by
8884 the image from the GIF file. Full animated GIF support
8885 requires more than can be done here (see the gif89 spec,
8886 disposal methods). Let's simply assume that the part
8887 not covered by a sub-image is in the frame's background color. */
8888 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
8889 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
8890 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
8891 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
8893 for (y
= 0; y
< image_top
; ++y
)
8894 for (x
= 0; x
< width
; ++x
)
8895 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8897 for (y
= image_top
+ image_height
; y
< height
; ++y
)
8898 for (x
= 0; x
< width
; ++x
)
8899 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8901 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
8903 for (x
= 0; x
< image_left
; ++x
)
8904 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8905 for (x
= image_left
+ image_width
; x
< width
; ++x
)
8906 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
8909 /* Read the GIF image into the X image. We use a local variable
8910 `raster' here because RasterBits below is a char *, and invites
8911 problems with bytes >= 0x80. */
8912 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
8914 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
8916 static int interlace_start
[] = {0, 4, 2, 1};
8917 static int interlace_increment
[] = {8, 8, 4, 2};
8919 int row
= interlace_start
[0];
8923 for (y
= 0; y
< image_height
; y
++)
8925 if (row
>= image_height
)
8927 row
= interlace_start
[++pass
];
8928 while (row
>= image_height
)
8929 row
= interlace_start
[++pass
];
8932 for (x
= 0; x
< image_width
; x
++)
8934 int i
= raster
[(y
* image_width
) + x
];
8935 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
8939 row
+= interlace_increment
[pass
];
8944 for (y
= 0; y
< image_height
; ++y
)
8945 for (x
= 0; x
< image_width
; ++x
)
8947 int i
= raster
[y
* image_width
+ x
];
8948 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
8952 DGifCloseFile (gif
);
8954 /* Maybe fill in the background field while we have ximg handy. */
8955 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8956 IMAGE_BACKGROUND (img
, f
, ximg
);
8958 /* Put the image into the pixmap, then free the X image and its buffer. */
8959 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8960 x_destroy_x_image (ximg
);
8966 #endif /* HAVE_GIF != 0 */
8970 /***********************************************************************
8972 ***********************************************************************/
8974 static int gs_image_p
P_ ((Lisp_Object object
));
8975 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
8976 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
8978 /* The symbol `postscript' identifying images of this type. */
8980 Lisp_Object Qpostscript
;
8982 /* Keyword symbols. */
8984 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
8986 /* Indices of image specification fields in gs_format, below. */
8988 enum gs_keyword_index
9006 /* Vector of image_keyword structures describing the format
9007 of valid user-defined image specifications. */
9009 static struct image_keyword gs_format
[GS_LAST
] =
9011 {":type", IMAGE_SYMBOL_VALUE
, 1},
9012 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9013 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9014 {":file", IMAGE_STRING_VALUE
, 1},
9015 {":loader", IMAGE_FUNCTION_VALUE
, 0},
9016 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
9017 {":ascent", IMAGE_ASCENT_VALUE
, 0},
9018 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
9019 {":relief", IMAGE_INTEGER_VALUE
, 0},
9020 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9021 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9022 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9023 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
9026 /* Structure describing the image type `ghostscript'. */
9028 static struct image_type gs_type
=
9038 /* Free X resources of Ghostscript image IMG which is used on frame F. */
9041 gs_clear_image (f
, img
)
9045 /* IMG->data.ptr_val may contain a recorded colormap. */
9046 xfree (img
->data
.ptr_val
);
9047 x_clear_image (f
, img
);
9051 /* Return non-zero if OBJECT is a valid Ghostscript image
9058 struct image_keyword fmt
[GS_LAST
];
9062 bcopy (gs_format
, fmt
, sizeof fmt
);
9064 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
9067 /* Bounding box must be a list or vector containing 4 integers. */
9068 tem
= fmt
[GS_BOUNDING_BOX
].value
;
9071 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
9072 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
9077 else if (VECTORP (tem
))
9079 if (XVECTOR (tem
)->size
!= 4)
9081 for (i
= 0; i
< 4; ++i
)
9082 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
9092 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
9101 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
9102 struct gcpro gcpro1
, gcpro2
;
9104 double in_width
, in_height
;
9105 Lisp_Object pixel_colors
= Qnil
;
9107 /* Compute pixel size of pixmap needed from the given size in the
9108 image specification. Sizes in the specification are in pt. 1 pt
9109 = 1/72 in, xdpi and ydpi are stored in the frame's X display
9111 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
9112 in_width
= XFASTINT (pt_width
) / 72.0;
9113 img
->width
= in_width
* FRAME_X_DISPLAY_INFO (f
)->resx
;
9114 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
9115 in_height
= XFASTINT (pt_height
) / 72.0;
9116 img
->height
= in_height
* FRAME_X_DISPLAY_INFO (f
)->resy
;
9118 /* Create the pixmap. */
9119 xassert (img
->pixmap
== None
);
9120 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9121 img
->width
, img
->height
,
9122 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
9126 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
9130 /* Call the loader to fill the pixmap. It returns a process object
9131 if successful. We do not record_unwind_protect here because
9132 other places in redisplay like calling window scroll functions
9133 don't either. Let the Lisp loader use `unwind-protect' instead. */
9134 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
9136 sprintf (buffer
, "%lu %lu",
9137 (unsigned long) FRAME_X_WINDOW (f
),
9138 (unsigned long) img
->pixmap
);
9139 window_and_pixmap_id
= build_string (buffer
);
9141 sprintf (buffer
, "%lu %lu",
9142 FRAME_FOREGROUND_PIXEL (f
),
9143 FRAME_BACKGROUND_PIXEL (f
));
9144 pixel_colors
= build_string (buffer
);
9146 XSETFRAME (frame
, f
);
9147 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
9149 loader
= intern ("gs-load-image");
9151 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
9152 make_number (img
->width
),
9153 make_number (img
->height
),
9154 window_and_pixmap_id
,
9157 return PROCESSP (img
->data
.lisp_val
);
9161 /* Kill the Ghostscript process that was started to fill PIXMAP on
9162 frame F. Called from XTread_socket when receiving an event
9163 telling Emacs that Ghostscript has finished drawing. */
9166 x_kill_gs_process (pixmap
, f
)
9170 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
9174 /* Find the image containing PIXMAP. */
9175 for (i
= 0; i
< c
->used
; ++i
)
9176 if (c
->images
[i
]->pixmap
== pixmap
)
9179 /* Should someone in between have cleared the image cache, for
9180 instance, give up. */
9184 /* Kill the GS process. We should have found PIXMAP in the image
9185 cache and its image should contain a process object. */
9187 xassert (PROCESSP (img
->data
.lisp_val
));
9188 Fkill_process (img
->data
.lisp_val
, Qnil
);
9189 img
->data
.lisp_val
= Qnil
;
9191 /* On displays with a mutable colormap, figure out the colors
9192 allocated for the image by looking at the pixels of an XImage for
9194 class = FRAME_X_VISUAL (f
)->class;
9195 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
9201 /* Try to get an XImage for img->pixmep. */
9202 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
9203 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
9208 /* Initialize the color table. */
9209 init_color_table ();
9211 /* For each pixel of the image, look its color up in the
9212 color table. After having done so, the color table will
9213 contain an entry for each color used by the image. */
9214 for (y
= 0; y
< img
->height
; ++y
)
9215 for (x
= 0; x
< img
->width
; ++x
)
9217 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
9218 lookup_pixel_color (f
, pixel
);
9221 /* Record colors in the image. Free color table and XImage. */
9222 img
->colors
= colors_in_color_table (&img
->ncolors
);
9223 free_color_table ();
9224 XDestroyImage (ximg
);
9226 #if 0 /* This doesn't seem to be the case. If we free the colors
9227 here, we get a BadAccess later in x_clear_image when
9228 freeing the colors. */
9229 /* We have allocated colors once, but Ghostscript has also
9230 allocated colors on behalf of us. So, to get the
9231 reference counts right, free them once. */
9233 x_free_colors (f
, img
->colors
, img
->ncolors
);
9237 image_error ("Cannot get X image of `%s'; colors will not be freed",
9243 /* Now that we have the pixmap, compute mask and transform the
9244 image if requested. */
9246 postprocess_image (f
, img
);
9252 /***********************************************************************
9254 ***********************************************************************/
9256 DEFUN ("x-change-window-property", Fx_change_window_property
,
9257 Sx_change_window_property
, 2, 3, 0,
9258 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
9259 PROP and VALUE must be strings. FRAME nil or omitted means use the
9260 selected frame. Value is VALUE. */)
9261 (prop
, value
, frame
)
9262 Lisp_Object frame
, prop
, value
;
9264 struct frame
*f
= check_x_frame (frame
);
9267 CHECK_STRING (prop
);
9268 CHECK_STRING (value
);
9271 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9272 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9273 prop_atom
, XA_STRING
, 8, PropModeReplace
,
9274 SDATA (value
), SCHARS (value
));
9276 /* Make sure the property is set when we return. */
9277 XFlush (FRAME_X_DISPLAY (f
));
9284 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
9285 Sx_delete_window_property
, 1, 2, 0,
9286 doc
: /* Remove window property PROP from X window of FRAME.
9287 FRAME nil or omitted means use the selected frame. Value is PROP. */)
9289 Lisp_Object prop
, frame
;
9291 struct frame
*f
= check_x_frame (frame
);
9294 CHECK_STRING (prop
);
9296 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9297 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
9299 /* Make sure the property is removed when we return. */
9300 XFlush (FRAME_X_DISPLAY (f
));
9307 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
9309 doc
: /* Value is the value of window property PROP on FRAME.
9310 If FRAME is nil or omitted, use the selected frame. Value is nil
9311 if FRAME hasn't a property with name PROP or if PROP has no string
9314 Lisp_Object prop
, frame
;
9316 struct frame
*f
= check_x_frame (frame
);
9319 Lisp_Object prop_value
= Qnil
;
9320 char *tmp_data
= NULL
;
9323 unsigned long actual_size
, bytes_remaining
;
9325 CHECK_STRING (prop
);
9327 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9328 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9329 prop_atom
, 0, 0, False
, XA_STRING
,
9330 &actual_type
, &actual_format
, &actual_size
,
9331 &bytes_remaining
, (unsigned char **) &tmp_data
);
9334 int size
= bytes_remaining
;
9339 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9340 prop_atom
, 0, bytes_remaining
,
9342 &actual_type
, &actual_format
,
9343 &actual_size
, &bytes_remaining
,
9344 (unsigned char **) &tmp_data
);
9345 if (rc
== Success
&& tmp_data
)
9346 prop_value
= make_string (tmp_data
, size
);
9357 /***********************************************************************
9359 ***********************************************************************/
9361 /* If non-null, an asynchronous timer that, when it expires, displays
9362 an hourglass cursor on all frames. */
9364 static struct atimer
*hourglass_atimer
;
9366 /* Non-zero means an hourglass cursor is currently shown. */
9368 static int hourglass_shown_p
;
9370 /* Number of seconds to wait before displaying an hourglass cursor. */
9372 static Lisp_Object Vhourglass_delay
;
9374 /* Default number of seconds to wait before displaying an hourglass
9377 #define DEFAULT_HOURGLASS_DELAY 1
9379 /* Function prototypes. */
9381 static void show_hourglass
P_ ((struct atimer
*));
9382 static void hide_hourglass
P_ ((void));
9385 /* Cancel a currently active hourglass timer, and start a new one. */
9391 int secs
, usecs
= 0;
9393 cancel_hourglass ();
9395 if (INTEGERP (Vhourglass_delay
)
9396 && XINT (Vhourglass_delay
) > 0)
9397 secs
= XFASTINT (Vhourglass_delay
);
9398 else if (FLOATP (Vhourglass_delay
)
9399 && XFLOAT_DATA (Vhourglass_delay
) > 0)
9402 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
9403 secs
= XFASTINT (tem
);
9404 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
9407 secs
= DEFAULT_HOURGLASS_DELAY
;
9409 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
9410 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
9411 show_hourglass
, NULL
);
9415 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
9421 if (hourglass_atimer
)
9423 cancel_atimer (hourglass_atimer
);
9424 hourglass_atimer
= NULL
;
9427 if (hourglass_shown_p
)
9432 /* Timer function of hourglass_atimer. TIMER is equal to
9435 Display an hourglass pointer on all frames by mapping the frames'
9436 hourglass_window. Set the hourglass_p flag in the frames'
9437 output_data.x structure to indicate that an hourglass cursor is
9438 shown on the frames. */
9441 show_hourglass (timer
)
9442 struct atimer
*timer
;
9444 /* The timer implementation will cancel this timer automatically
9445 after this function has run. Set hourglass_atimer to null
9446 so that we know the timer doesn't have to be canceled. */
9447 hourglass_atimer
= NULL
;
9449 if (!hourglass_shown_p
)
9451 Lisp_Object rest
, frame
;
9455 FOR_EACH_FRAME (rest
, frame
)
9457 struct frame
*f
= XFRAME (frame
);
9459 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
) && FRAME_X_DISPLAY (f
))
9461 Display
*dpy
= FRAME_X_DISPLAY (f
);
9463 #ifdef USE_X_TOOLKIT
9464 if (f
->output_data
.x
->widget
)
9466 if (FRAME_OUTER_WINDOW (f
))
9469 f
->output_data
.x
->hourglass_p
= 1;
9471 if (!f
->output_data
.x
->hourglass_window
)
9473 unsigned long mask
= CWCursor
;
9474 XSetWindowAttributes attrs
;
9476 attrs
.cursor
= f
->output_data
.x
->hourglass_cursor
;
9478 f
->output_data
.x
->hourglass_window
9479 = XCreateWindow (dpy
, FRAME_OUTER_WINDOW (f
),
9480 0, 0, 32000, 32000, 0, 0,
9486 XMapRaised (dpy
, f
->output_data
.x
->hourglass_window
);
9492 hourglass_shown_p
= 1;
9498 /* Hide the hourglass pointer on all frames, if it is currently
9504 if (hourglass_shown_p
)
9506 Lisp_Object rest
, frame
;
9509 FOR_EACH_FRAME (rest
, frame
)
9511 struct frame
*f
= XFRAME (frame
);
9514 /* Watch out for newly created frames. */
9515 && f
->output_data
.x
->hourglass_window
)
9517 XUnmapWindow (FRAME_X_DISPLAY (f
),
9518 f
->output_data
.x
->hourglass_window
);
9519 /* Sync here because XTread_socket looks at the
9520 hourglass_p flag that is reset to zero below. */
9521 XSync (FRAME_X_DISPLAY (f
), False
);
9522 f
->output_data
.x
->hourglass_p
= 0;
9526 hourglass_shown_p
= 0;
9533 /***********************************************************************
9535 ***********************************************************************/
9537 static Lisp_Object x_create_tip_frame
P_ ((struct x_display_info
*,
9538 Lisp_Object
, Lisp_Object
));
9539 static void compute_tip_xy
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
9540 Lisp_Object
, int, int, int *, int *));
9542 /* The frame of a currently visible tooltip. */
9544 Lisp_Object tip_frame
;
9546 /* If non-nil, a timer started that hides the last tooltip when it
9549 Lisp_Object tip_timer
;
9552 /* If non-nil, a vector of 3 elements containing the last args
9553 with which x-show-tip was called. See there. */
9555 Lisp_Object last_show_tip_args
;
9557 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
9559 Lisp_Object Vx_max_tooltip_size
;
9563 unwind_create_tip_frame (frame
)
9566 Lisp_Object deleted
;
9568 deleted
= unwind_create_frame (frame
);
9569 if (EQ (deleted
, Qt
))
9579 /* Create a frame for a tooltip on the display described by DPYINFO.
9580 PARMS is a list of frame parameters. TEXT is the string to
9581 display in the tip frame. Value is the frame.
9583 Note that functions called here, esp. x_default_parameter can
9584 signal errors, for instance when a specified color name is
9585 undefined. We have to make sure that we're in a consistent state
9586 when this happens. */
9589 x_create_tip_frame (dpyinfo
, parms
, text
)
9590 struct x_display_info
*dpyinfo
;
9591 Lisp_Object parms
, text
;
9594 Lisp_Object frame
, tem
;
9596 long window_prompting
= 0;
9598 int count
= SPECPDL_INDEX ();
9599 struct gcpro gcpro1
, gcpro2
, gcpro3
;
9601 int face_change_count_before
= face_change_count
;
9603 struct buffer
*old_buffer
;
9607 /* Use this general default value to start with until we know if
9608 this frame has a specified name. */
9609 Vx_resource_name
= Vinvocation_name
;
9612 kb
= dpyinfo
->kboard
;
9614 kb
= &the_only_kboard
;
9617 /* Get the name of the frame to use for resource lookup. */
9618 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
9620 && !EQ (name
, Qunbound
)
9622 error ("Invalid frame name--not a string or nil");
9623 Vx_resource_name
= name
;
9626 GCPRO3 (parms
, name
, frame
);
9628 XSETFRAME (frame
, f
);
9630 buffer
= Fget_buffer_create (build_string (" *tip*"));
9631 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
9632 old_buffer
= current_buffer
;
9633 set_buffer_internal_1 (XBUFFER (buffer
));
9634 current_buffer
->truncate_lines
= Qnil
;
9637 set_buffer_internal_1 (old_buffer
);
9639 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
9640 record_unwind_protect (unwind_create_tip_frame
, frame
);
9642 /* By setting the output method, we're essentially saying that
9643 the frame is live, as per FRAME_LIVE_P. If we get a signal
9644 from this point on, x_destroy_window might screw up reference
9646 f
->output_method
= output_x_window
;
9647 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
9648 bzero (f
->output_data
.x
, sizeof (struct x_output
));
9649 f
->output_data
.x
->icon_bitmap
= -1;
9650 FRAME_FONTSET (f
) = -1;
9651 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
9652 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
9653 #ifdef USE_TOOLKIT_SCROLL_BARS
9654 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
9655 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
9656 #endif /* USE_TOOLKIT_SCROLL_BARS */
9657 f
->icon_name
= Qnil
;
9658 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
9660 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
9661 dpyinfo_refcount
= dpyinfo
->reference_count
;
9662 #endif /* GLYPH_DEBUG */
9664 FRAME_KBOARD (f
) = kb
;
9666 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
9667 f
->output_data
.x
->explicit_parent
= 0;
9669 /* These colors will be set anyway later, but it's important
9670 to get the color reference counts right, so initialize them! */
9673 struct gcpro gcpro1
;
9675 black
= build_string ("black");
9677 f
->output_data
.x
->foreground_pixel
9678 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9679 f
->output_data
.x
->background_pixel
9680 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9681 f
->output_data
.x
->cursor_pixel
9682 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9683 f
->output_data
.x
->cursor_foreground_pixel
9684 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9685 f
->output_data
.x
->border_pixel
9686 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9687 f
->output_data
.x
->mouse_pixel
9688 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9692 /* Set the name; the functions to which we pass f expect the name to
9694 if (EQ (name
, Qunbound
) || NILP (name
))
9696 f
->name
= build_string (dpyinfo
->x_id_name
);
9697 f
->explicit_name
= 0;
9702 f
->explicit_name
= 1;
9703 /* use the frame's title when getting resources for this frame. */
9704 specbind (Qx_resource_name
, name
);
9707 /* Extract the window parameters from the supplied values that are
9708 needed to determine window geometry. */
9712 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
9715 /* First, try whatever font the caller has specified. */
9718 tem
= Fquery_fontset (font
, Qnil
);
9720 font
= x_new_fontset (f
, SDATA (tem
));
9722 font
= x_new_font (f
, SDATA (font
));
9725 /* Try out a font which we hope has bold and italic variations. */
9726 if (!STRINGP (font
))
9727 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
9728 if (!STRINGP (font
))
9729 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9730 if (! STRINGP (font
))
9731 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9732 if (! STRINGP (font
))
9733 /* This was formerly the first thing tried, but it finds too many fonts
9734 and takes too long. */
9735 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
9736 /* If those didn't work, look for something which will at least work. */
9737 if (! STRINGP (font
))
9738 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
9740 if (! STRINGP (font
))
9741 font
= build_string ("fixed");
9743 x_default_parameter (f
, parms
, Qfont
, font
,
9744 "font", "Font", RES_TYPE_STRING
);
9747 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
9748 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
9750 /* This defaults to 2 in order to match xterm. We recognize either
9751 internalBorderWidth or internalBorder (which is what xterm calls
9753 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9757 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
9758 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
9759 if (! EQ (value
, Qunbound
))
9760 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
9764 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
9765 "internalBorderWidth", "internalBorderWidth",
9768 /* Also do the stuff which must be set before the window exists. */
9769 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
9770 "foreground", "Foreground", RES_TYPE_STRING
);
9771 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
9772 "background", "Background", RES_TYPE_STRING
);
9773 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
9774 "pointerColor", "Foreground", RES_TYPE_STRING
);
9775 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
9776 "cursorColor", "Foreground", RES_TYPE_STRING
);
9777 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
9778 "borderColor", "BorderColor", RES_TYPE_STRING
);
9780 /* Init faces before x_default_parameter is called for scroll-bar
9781 parameters because that function calls x_set_scroll_bar_width,
9782 which calls change_frame_size, which calls Fset_window_buffer,
9783 which runs hooks, which call Fvertical_motion. At the end, we
9784 end up in init_iterator with a null face cache, which should not
9786 init_frame_faces (f
);
9788 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
9790 window_prompting
= x_figure_window_size (f
, parms
, 0);
9793 XSetWindowAttributes attrs
;
9797 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
9798 if (DoesSaveUnders (dpyinfo
->screen
))
9799 mask
|= CWSaveUnder
;
9801 /* Window managers look at the override-redirect flag to determine
9802 whether or net to give windows a decoration (Xlib spec, chapter
9804 attrs
.override_redirect
= True
;
9805 attrs
.save_under
= True
;
9806 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
9807 /* Arrange for getting MapNotify and UnmapNotify events. */
9808 attrs
.event_mask
= StructureNotifyMask
;
9810 = FRAME_X_WINDOW (f
)
9811 = XCreateWindow (FRAME_X_DISPLAY (f
),
9812 FRAME_X_DISPLAY_INFO (f
)->root_window
,
9813 /* x, y, width, height */
9817 CopyFromParent
, InputOutput
, CopyFromParent
,
9824 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
9825 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9826 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
9827 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9828 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
9829 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
9831 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
9832 Change will not be effected unless different from the current
9834 width
= FRAME_COLS (f
);
9835 height
= FRAME_LINES (f
);
9836 SET_FRAME_COLS (f
, 0);
9837 FRAME_LINES (f
) = 0;
9838 change_frame_size (f
, height
, width
, 1, 0, 0);
9840 /* Add `tooltip' frame parameter's default value. */
9841 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
9842 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
9845 /* Set up faces after all frame parameters are known. This call
9846 also merges in face attributes specified for new frames.
9848 Frame parameters may be changed if .Xdefaults contains
9849 specifications for the default font. For example, if there is an
9850 `Emacs.default.attributeBackground: pink', the `background-color'
9851 attribute of the frame get's set, which let's the internal border
9852 of the tooltip frame appear in pink. Prevent this. */
9854 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
9856 /* Set tip_frame here, so that */
9858 call1 (Qface_set_after_frame_default
, frame
);
9860 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
9861 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qbackground_color
, bg
),
9869 /* It is now ok to make the frame official even if we get an error
9870 below. And the frame needs to be on Vframe_list or making it
9871 visible won't work. */
9872 Vframe_list
= Fcons (frame
, Vframe_list
);
9874 /* Now that the frame is official, it counts as a reference to
9876 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
9878 /* Setting attributes of faces of the tooltip frame from resources
9879 and similar will increment face_change_count, which leads to the
9880 clearing of all current matrices. Since this isn't necessary
9881 here, avoid it by resetting face_change_count to the value it
9882 had before we created the tip frame. */
9883 face_change_count
= face_change_count_before
;
9885 /* Discard the unwind_protect. */
9886 return unbind_to (count
, frame
);
9890 /* Compute where to display tip frame F. PARMS is the list of frame
9891 parameters for F. DX and DY are specified offsets from the current
9892 location of the mouse. WIDTH and HEIGHT are the width and height
9893 of the tooltip. Return coordinates relative to the root window of
9894 the display in *ROOT_X, and *ROOT_Y. */
9897 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, root_x
, root_y
)
9899 Lisp_Object parms
, dx
, dy
;
9901 int *root_x
, *root_y
;
9903 Lisp_Object left
, top
;
9908 /* User-specified position? */
9909 left
= Fcdr (Fassq (Qleft
, parms
));
9910 top
= Fcdr (Fassq (Qtop
, parms
));
9912 /* Move the tooltip window where the mouse pointer is. Resize and
9914 if (!INTEGERP (left
) || !INTEGERP (top
))
9917 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
9918 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
9923 *root_y
= XINT (top
);
9924 else if (*root_y
+ XINT (dy
) - height
< 0)
9925 *root_y
-= XINT (dy
);
9929 *root_y
+= XINT (dy
);
9932 if (INTEGERP (left
))
9933 *root_x
= XINT (left
);
9934 else if (*root_x
+ XINT (dx
) + width
<= FRAME_X_DISPLAY_INFO (f
)->width
)
9935 /* It fits to the right of the pointer. */
9936 *root_x
+= XINT (dx
);
9937 else if (width
+ XINT (dx
) <= *root_x
)
9938 /* It fits to the left of the pointer. */
9939 *root_x
-= width
+ XINT (dx
);
9941 /* Put it left-justified on the screen--it ought to fit that way. */
9946 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
9947 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
9948 A tooltip window is a small X window displaying a string.
9950 FRAME nil or omitted means use the selected frame.
9952 PARMS is an optional list of frame parameters which can be used to
9953 change the tooltip's appearance.
9955 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
9956 means use the default timeout of 5 seconds.
9958 If the list of frame parameters PARAMS contains a `left' parameters,
9959 the tooltip is displayed at that x-position. Otherwise it is
9960 displayed at the mouse position, with offset DX added (default is 5 if
9961 DX isn't specified). Likewise for the y-position; if a `top' frame
9962 parameter is specified, it determines the y-position of the tooltip
9963 window, otherwise it is displayed at the mouse position, with offset
9964 DY added (default is -10).
9966 A tooltip's maximum size is specified by `x-max-tooltip-size'.
9967 Text larger than the specified size is clipped. */)
9968 (string
, frame
, parms
, timeout
, dx
, dy
)
9969 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
9974 struct buffer
*old_buffer
;
9975 struct text_pos pos
;
9976 int i
, width
, height
;
9977 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
9978 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
9979 int count
= SPECPDL_INDEX ();
9981 specbind (Qinhibit_redisplay
, Qt
);
9983 GCPRO4 (string
, parms
, frame
, timeout
);
9985 CHECK_STRING (string
);
9986 f
= check_x_frame (frame
);
9988 timeout
= make_number (5);
9990 CHECK_NATNUM (timeout
);
9993 dx
= make_number (5);
9998 dy
= make_number (-10);
10002 if (NILP (last_show_tip_args
))
10003 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
10005 if (!NILP (tip_frame
))
10007 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
10008 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
10009 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
10011 if (EQ (frame
, last_frame
)
10012 && !NILP (Fequal (last_string
, string
))
10013 && !NILP (Fequal (last_parms
, parms
)))
10015 struct frame
*f
= XFRAME (tip_frame
);
10017 /* Only DX and DY have changed. */
10018 if (!NILP (tip_timer
))
10020 Lisp_Object timer
= tip_timer
;
10022 call1 (Qcancel_timer
, timer
);
10026 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
10027 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
10028 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10035 /* Hide a previous tip, if any. */
10038 ASET (last_show_tip_args
, 0, string
);
10039 ASET (last_show_tip_args
, 1, frame
);
10040 ASET (last_show_tip_args
, 2, parms
);
10042 /* Add default values to frame parameters. */
10043 if (NILP (Fassq (Qname
, parms
)))
10044 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
10045 if (NILP (Fassq (Qinternal_border_width
, parms
)))
10046 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
10047 if (NILP (Fassq (Qborder_width
, parms
)))
10048 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
10049 if (NILP (Fassq (Qborder_color
, parms
)))
10050 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
10051 if (NILP (Fassq (Qbackground_color
, parms
)))
10052 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
10055 /* Create a frame for the tooltip, and record it in the global
10056 variable tip_frame. */
10057 frame
= x_create_tip_frame (FRAME_X_DISPLAY_INFO (f
), parms
, string
);
10058 f
= XFRAME (frame
);
10060 /* Set up the frame's root window. */
10061 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
10062 w
->left_col
= w
->top_line
= make_number (0);
10064 if (CONSP (Vx_max_tooltip_size
)
10065 && INTEGERP (XCAR (Vx_max_tooltip_size
))
10066 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
10067 && INTEGERP (XCDR (Vx_max_tooltip_size
))
10068 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
10070 w
->total_cols
= XCAR (Vx_max_tooltip_size
);
10071 w
->total_lines
= XCDR (Vx_max_tooltip_size
);
10075 w
->total_cols
= make_number (80);
10076 w
->total_lines
= make_number (40);
10079 FRAME_TOTAL_COLS (f
) = XINT (w
->total_cols
);
10081 w
->pseudo_window_p
= 1;
10083 /* Display the tooltip text in a temporary buffer. */
10084 old_buffer
= current_buffer
;
10085 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->buffer
));
10086 current_buffer
->truncate_lines
= Qnil
;
10087 clear_glyph_matrix (w
->desired_matrix
);
10088 clear_glyph_matrix (w
->current_matrix
);
10089 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
10090 try_window (FRAME_ROOT_WINDOW (f
), pos
);
10092 /* Compute width and height of the tooltip. */
10093 width
= height
= 0;
10094 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
10096 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
10097 struct glyph
*last
;
10100 /* Stop at the first empty row at the end. */
10101 if (!row
->enabled_p
|| !row
->displays_text_p
)
10104 /* Let the row go over the full width of the frame. */
10105 row
->full_width_p
= 1;
10107 /* There's a glyph at the end of rows that is used to place
10108 the cursor there. Don't include the width of this glyph. */
10109 if (row
->used
[TEXT_AREA
])
10111 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
10112 row_width
= row
->pixel_width
- last
->pixel_width
;
10115 row_width
= row
->pixel_width
;
10117 height
+= row
->height
;
10118 width
= max (width
, row_width
);
10121 /* Add the frame's internal border to the width and height the X
10122 window should have. */
10123 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10124 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10126 /* Move the tooltip window where the mouse pointer is. Resize and
10128 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
10131 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10132 root_x
, root_y
, width
, height
);
10133 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
10136 /* Draw into the window. */
10137 w
->must_be_updated_p
= 1;
10138 update_single_window (w
, 1);
10140 /* Restore original current buffer. */
10141 set_buffer_internal_1 (old_buffer
);
10142 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
10145 /* Let the tip disappear after timeout seconds. */
10146 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
10147 intern ("x-hide-tip"));
10150 return unbind_to (count
, Qnil
);
10154 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
10155 doc
: /* Hide the current tooltip window, if there is any.
10156 Value is t if tooltip was open, nil otherwise. */)
10160 Lisp_Object deleted
, frame
, timer
;
10161 struct gcpro gcpro1
, gcpro2
;
10163 /* Return quickly if nothing to do. */
10164 if (NILP (tip_timer
) && NILP (tip_frame
))
10169 GCPRO2 (frame
, timer
);
10170 tip_frame
= tip_timer
= deleted
= Qnil
;
10172 count
= SPECPDL_INDEX ();
10173 specbind (Qinhibit_redisplay
, Qt
);
10174 specbind (Qinhibit_quit
, Qt
);
10177 call1 (Qcancel_timer
, timer
);
10179 if (FRAMEP (frame
))
10181 Fdelete_frame (frame
, Qnil
);
10185 /* Bloodcurdling hack alert: The Lucid menu bar widget's
10186 redisplay procedure is not called when a tip frame over menu
10187 items is unmapped. Redisplay the menu manually... */
10189 struct frame
*f
= SELECTED_FRAME ();
10190 Widget w
= f
->output_data
.x
->menubar_widget
;
10191 extern void xlwmenu_redisplay
P_ ((Widget
));
10193 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f
)->screen
)
10197 xlwmenu_redisplay (w
);
10201 #endif /* USE_LUCID */
10205 return unbind_to (count
, deleted
);
10210 /***********************************************************************
10211 File selection dialog
10212 ***********************************************************************/
10216 /* Callback for "OK" and "Cancel" on file selection dialog. */
10219 file_dialog_cb (widget
, client_data
, call_data
)
10221 XtPointer call_data
, client_data
;
10223 int *result
= (int *) client_data
;
10224 XmAnyCallbackStruct
*cb
= (XmAnyCallbackStruct
*) call_data
;
10225 *result
= cb
->reason
;
10229 /* Callback for unmapping a file selection dialog. This is used to
10230 capture the case where a dialog is closed via a window manager's
10231 closer button, for example. Using a XmNdestroyCallback didn't work
10235 file_dialog_unmap_cb (widget
, client_data
, call_data
)
10237 XtPointer call_data
, client_data
;
10239 int *result
= (int *) client_data
;
10240 *result
= XmCR_CANCEL
;
10244 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10245 doc
: /* Read file name, prompting with PROMPT in directory DIR.
10246 Use a file selection dialog.
10247 Select DEFAULT-FILENAME in the dialog's file selection box, if
10248 specified. Don't let the user enter a file name in the file
10249 selection dialog's entry field, if MUSTMATCH is non-nil. */)
10250 (prompt
, dir
, default_filename
, mustmatch
)
10251 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10254 struct frame
*f
= SELECTED_FRAME ();
10255 Lisp_Object file
= Qnil
;
10256 Widget dialog
, text
, list
, help
;
10259 extern XtAppContext Xt_app_con
;
10260 XmString dir_xmstring
, pattern_xmstring
;
10261 int count
= SPECPDL_INDEX ();
10262 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10264 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10265 CHECK_STRING (prompt
);
10266 CHECK_STRING (dir
);
10268 /* Prevent redisplay. */
10269 specbind (Qinhibit_redisplay
, Qt
);
10273 /* Create the dialog with PROMPT as title, using DIR as initial
10274 directory and using "*" as pattern. */
10275 dir
= Fexpand_file_name (dir
, Qnil
);
10276 dir_xmstring
= XmStringCreateLocalized (SDATA (dir
));
10277 pattern_xmstring
= XmStringCreateLocalized ("*");
10279 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
10280 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
10281 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
10282 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
10283 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
10284 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
10286 XmStringFree (dir_xmstring
);
10287 XmStringFree (pattern_xmstring
);
10289 /* Add callbacks for OK and Cancel. */
10290 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
10291 (XtPointer
) &result
);
10292 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
10293 (XtPointer
) &result
);
10294 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
10295 (XtPointer
) &result
);
10297 /* Disable the help button since we can't display help. */
10298 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
10299 XtSetSensitive (help
, False
);
10301 /* Mark OK button as default. */
10302 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
10303 XmNshowAsDefault
, True
, NULL
);
10305 /* If MUSTMATCH is non-nil, disable the file entry field of the
10306 dialog, so that the user must select a file from the files list
10307 box. We can't remove it because we wouldn't have a way to get at
10308 the result file name, then. */
10309 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
10310 if (!NILP (mustmatch
))
10313 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
10314 XtSetSensitive (text
, False
);
10315 XtSetSensitive (label
, False
);
10318 /* Manage the dialog, so that list boxes get filled. */
10319 XtManageChild (dialog
);
10321 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
10322 must include the path for this to work. */
10323 list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
10324 if (STRINGP (default_filename
))
10326 XmString default_xmstring
;
10330 = XmStringCreateLocalized (SDATA (default_filename
));
10332 if (!XmListItemExists (list
, default_xmstring
))
10334 /* Add a new item if DEFAULT_FILENAME is not in the list. */
10335 XmListAddItem (list
, default_xmstring
, 0);
10339 item_pos
= XmListItemPos (list
, default_xmstring
);
10340 XmStringFree (default_xmstring
);
10342 /* Select the item and scroll it into view. */
10343 XmListSelectPos (list
, item_pos
, True
);
10344 XmListSetPos (list
, item_pos
);
10347 /* Process events until the user presses Cancel or OK. */
10349 while (result
== 0)
10352 XtAppNextEvent (Xt_app_con
, &event
);
10353 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
) );
10356 /* Get the result. */
10357 if (result
== XmCR_OK
)
10362 XtVaGetValues (dialog
, XmNtextString
, &text
, NULL
);
10363 XmStringGetLtoR (text
, XmFONTLIST_DEFAULT_TAG
, &data
);
10364 XmStringFree (text
);
10365 file
= build_string (data
);
10372 XtUnmanageChild (dialog
);
10373 XtDestroyWidget (dialog
);
10377 /* Make "Cancel" equivalent to C-g. */
10379 Fsignal (Qquit
, Qnil
);
10381 return unbind_to (count
, file
);
10384 #endif /* USE_MOTIF */
10388 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10389 "Read file name, prompting with PROMPT in directory DIR.\n\
10390 Use a file selection dialog.\n\
10391 Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
10392 specified. Don't let the user enter a file name in the file\n\
10393 selection dialog's entry field, if MUSTMATCH is non-nil.")
10394 (prompt
, dir
, default_filename
, mustmatch
)
10395 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10397 FRAME_PTR f
= SELECTED_FRAME ();
10399 Lisp_Object file
= Qnil
;
10400 int count
= specpdl_ptr
- specpdl
;
10401 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10405 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10406 CHECK_STRING (prompt
);
10407 CHECK_STRING (dir
);
10409 /* Prevent redisplay. */
10410 specbind (Qinhibit_redisplay
, Qt
);
10414 if (STRINGP (default_filename
))
10415 cdef_file
= SDATA (default_filename
);
10417 cdef_file
= SDATA (dir
);
10419 fn
= xg_get_file_name (f
, SDATA (prompt
), cdef_file
, ! NILP (mustmatch
));
10423 file
= build_string (fn
);
10430 /* Make "Cancel" equivalent to C-g. */
10432 Fsignal (Qquit
, Qnil
);
10434 return unbind_to (count
, file
);
10437 #endif /* USE_GTK */
10440 /***********************************************************************
10442 ***********************************************************************/
10444 #ifdef HAVE_XKBGETKEYBOARD
10445 #include <X11/XKBlib.h>
10446 #include <X11/keysym.h>
10449 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
10450 Sx_backspace_delete_keys_p
, 0, 1, 0,
10451 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
10452 FRAME nil means use the selected frame.
10453 Value is t if we know that both keys are present, and are mapped to the
10454 usual X keysyms. */)
10458 #ifdef HAVE_XKBGETKEYBOARD
10460 struct frame
*f
= check_x_frame (frame
);
10461 Display
*dpy
= FRAME_X_DISPLAY (f
);
10462 Lisp_Object have_keys
;
10463 int major
, minor
, op
, event
, error
;
10467 /* Check library version in case we're dynamically linked. */
10468 major
= XkbMajorVersion
;
10469 minor
= XkbMinorVersion
;
10470 if (!XkbLibraryVersion (&major
, &minor
))
10476 /* Check that the server supports XKB. */
10477 major
= XkbMajorVersion
;
10478 minor
= XkbMinorVersion
;
10479 if (!XkbQueryExtension (dpy
, &op
, &event
, &error
, &major
, &minor
))
10486 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
10489 int delete_keycode
= 0, backspace_keycode
= 0, i
;
10491 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
10493 for (i
= kb
->min_key_code
;
10494 (i
< kb
->max_key_code
10495 && (delete_keycode
== 0 || backspace_keycode
== 0));
10498 /* The XKB symbolic key names can be seen most easily in
10499 the PS file generated by `xkbprint -label name
10501 if (bcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
10502 delete_keycode
= i
;
10503 else if (bcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
10504 backspace_keycode
= i
;
10507 XkbFreeNames (kb
, 0, True
);
10510 XkbFreeClientMap (kb
, 0, True
);
10513 && backspace_keycode
10514 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
10515 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
10520 #else /* not HAVE_XKBGETKEYBOARD */
10522 #endif /* not HAVE_XKBGETKEYBOARD */
10527 /***********************************************************************
10529 ***********************************************************************/
10531 /* Keep this list in the same order as frame_parms in frame.c.
10532 Use 0 for unsupported frame parameters. */
10534 frame_parm_handler x_frame_parm_handlers
[] =
10538 x_set_background_color
,
10539 x_set_border_color
,
10540 x_set_border_width
,
10541 x_set_cursor_color
,
10544 x_set_foreground_color
,
10547 x_set_internal_border_width
,
10548 x_set_menu_bar_lines
,
10550 x_explicitly_set_name
,
10551 x_set_scroll_bar_width
,
10553 x_set_unsplittable
,
10554 x_set_vertical_scroll_bars
,
10556 x_set_tool_bar_lines
,
10557 x_set_scroll_bar_foreground
,
10558 x_set_scroll_bar_background
,
10559 x_set_screen_gamma
,
10560 x_set_line_spacing
,
10561 x_set_fringe_width
,
10562 x_set_fringe_width
,
10570 /* This is zero if not using X windows. */
10573 /* The section below is built by the lisp expression at the top of the file,
10574 just above where these variables are declared. */
10575 /*&&& init symbols here &&&*/
10576 Qnone
= intern ("none");
10577 staticpro (&Qnone
);
10578 Qsuppress_icon
= intern ("suppress-icon");
10579 staticpro (&Qsuppress_icon
);
10580 Qundefined_color
= intern ("undefined-color");
10581 staticpro (&Qundefined_color
);
10582 Qcenter
= intern ("center");
10583 staticpro (&Qcenter
);
10584 Qcompound_text
= intern ("compound-text");
10585 staticpro (&Qcompound_text
);
10586 Qcancel_timer
= intern ("cancel-timer");
10587 staticpro (&Qcancel_timer
);
10588 /* This is the end of symbol initialization. */
10590 /* Text property `display' should be nonsticky by default. */
10591 Vtext_property_default_nonsticky
10592 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
10595 Qlaplace
= intern ("laplace");
10596 staticpro (&Qlaplace
);
10597 Qemboss
= intern ("emboss");
10598 staticpro (&Qemboss
);
10599 Qedge_detection
= intern ("edge-detection");
10600 staticpro (&Qedge_detection
);
10601 Qheuristic
= intern ("heuristic");
10602 staticpro (&Qheuristic
);
10603 QCmatrix
= intern (":matrix");
10604 staticpro (&QCmatrix
);
10605 QCcolor_adjustment
= intern (":color-adjustment");
10606 staticpro (&QCcolor_adjustment
);
10607 QCmask
= intern (":mask");
10608 staticpro (&QCmask
);
10610 Fput (Qundefined_color
, Qerror_conditions
,
10611 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
10612 Fput (Qundefined_color
, Qerror_message
,
10613 build_string ("Undefined color"));
10615 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images
,
10616 doc
: /* Non-nil means always draw a cross over disabled images.
10617 Disabled images are those having an `:conversion disabled' property.
10618 A cross is always drawn on black & white displays. */);
10619 cross_disabled_images
= 0;
10621 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
10622 doc
: /* List of directories to search for window system bitmap files. */);
10623 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
10625 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
10626 doc
: /* The shape of the pointer when over text.
10627 Changing the value does not affect existing frames
10628 unless you set the mouse color. */);
10629 Vx_pointer_shape
= Qnil
;
10631 #if 0 /* This doesn't really do anything. */
10632 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
10633 doc
: /* The shape of the pointer when not over text.
10634 This variable takes effect when you create a new frame
10635 or when you set the mouse color. */);
10637 Vx_nontext_pointer_shape
= Qnil
;
10639 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
10640 doc
: /* The shape of the pointer when Emacs is busy.
10641 This variable takes effect when you create a new frame
10642 or when you set the mouse color. */);
10643 Vx_hourglass_pointer_shape
= Qnil
;
10645 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
10646 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
10647 display_hourglass_p
= 1;
10649 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
10650 doc
: /* *Seconds to wait before displaying an hourglass pointer.
10651 Value must be an integer or float. */);
10652 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
10654 #if 0 /* This doesn't really do anything. */
10655 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
10656 doc
: /* The shape of the pointer when over the mode line.
10657 This variable takes effect when you create a new frame
10658 or when you set the mouse color. */);
10660 Vx_mode_pointer_shape
= Qnil
;
10662 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
10663 &Vx_sensitive_text_pointer_shape
,
10664 doc
: /* The shape of the pointer when over mouse-sensitive text.
10665 This variable takes effect when you create a new frame
10666 or when you set the mouse color. */);
10667 Vx_sensitive_text_pointer_shape
= Qnil
;
10669 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
10670 &Vx_window_horizontal_drag_shape
,
10671 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
10672 This variable takes effect when you create a new frame
10673 or when you set the mouse color. */);
10674 Vx_window_horizontal_drag_shape
= Qnil
;
10676 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
10677 doc
: /* A string indicating the foreground color of the cursor box. */);
10678 Vx_cursor_fore_pixel
= Qnil
;
10680 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size
,
10681 doc
: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
10682 Text larger than this is clipped. */);
10683 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
10685 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
10686 doc
: /* Non-nil if no X window manager is in use.
10687 Emacs doesn't try to figure this out; this is always nil
10688 unless you set it to something else. */);
10689 /* We don't have any way to find this out, so set it to nil
10690 and maybe the user would like to set it to t. */
10691 Vx_no_window_manager
= Qnil
;
10693 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
10694 &Vx_pixel_size_width_font_regexp
,
10695 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
10697 Since Emacs gets width of a font matching with this regexp from
10698 PIXEL_SIZE field of the name, font finding mechanism gets faster for
10699 such a font. This is especially effective for such large fonts as
10700 Chinese, Japanese, and Korean. */);
10701 Vx_pixel_size_width_font_regexp
= Qnil
;
10703 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
10704 doc
: /* Time after which cached images are removed from the cache.
10705 When an image has not been displayed this many seconds, remove it
10706 from the image cache. Value must be an integer or nil with nil
10707 meaning don't clear the cache. */);
10708 Vimage_cache_eviction_delay
= make_number (30 * 60);
10710 #ifdef USE_X_TOOLKIT
10711 Fprovide (intern ("x-toolkit"), Qnil
);
10713 Fprovide (intern ("motif"), Qnil
);
10715 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
,
10716 doc
: /* Version info for LessTif/Motif. */);
10717 Vmotif_version_string
= build_string (XmVERSION_STRING
);
10718 #endif /* USE_MOTIF */
10719 #endif /* USE_X_TOOLKIT */
10721 /* X window properties. */
10722 defsubr (&Sx_change_window_property
);
10723 defsubr (&Sx_delete_window_property
);
10724 defsubr (&Sx_window_property
);
10726 defsubr (&Sxw_display_color_p
);
10727 defsubr (&Sx_display_grayscale_p
);
10728 defsubr (&Sxw_color_defined_p
);
10729 defsubr (&Sxw_color_values
);
10730 defsubr (&Sx_server_max_request_size
);
10731 defsubr (&Sx_server_vendor
);
10732 defsubr (&Sx_server_version
);
10733 defsubr (&Sx_display_pixel_width
);
10734 defsubr (&Sx_display_pixel_height
);
10735 defsubr (&Sx_display_mm_width
);
10736 defsubr (&Sx_display_mm_height
);
10737 defsubr (&Sx_display_screens
);
10738 defsubr (&Sx_display_planes
);
10739 defsubr (&Sx_display_color_cells
);
10740 defsubr (&Sx_display_visual_class
);
10741 defsubr (&Sx_display_backing_store
);
10742 defsubr (&Sx_display_save_under
);
10743 defsubr (&Sx_create_frame
);
10744 defsubr (&Sx_open_connection
);
10745 defsubr (&Sx_close_connection
);
10746 defsubr (&Sx_display_list
);
10747 defsubr (&Sx_synchronize
);
10748 defsubr (&Sx_focus_frame
);
10749 defsubr (&Sx_backspace_delete_keys_p
);
10751 /* Setting callback functions for fontset handler. */
10752 get_font_info_func
= x_get_font_info
;
10754 #if 0 /* This function pointer doesn't seem to be used anywhere.
10755 And the pointer assigned has the wrong type, anyway. */
10756 list_fonts_func
= x_list_fonts
;
10759 load_font_func
= x_load_font
;
10760 find_ccl_program_func
= x_find_ccl_program
;
10761 query_font_func
= x_query_font
;
10762 set_frame_fontset_func
= x_set_font
;
10763 check_window_system_func
= check_x
;
10766 Qxbm
= intern ("xbm");
10768 QCconversion
= intern (":conversion");
10769 staticpro (&QCconversion
);
10770 QCheuristic_mask
= intern (":heuristic-mask");
10771 staticpro (&QCheuristic_mask
);
10772 QCcolor_symbols
= intern (":color-symbols");
10773 staticpro (&QCcolor_symbols
);
10774 QCascent
= intern (":ascent");
10775 staticpro (&QCascent
);
10776 QCmargin
= intern (":margin");
10777 staticpro (&QCmargin
);
10778 QCrelief
= intern (":relief");
10779 staticpro (&QCrelief
);
10780 Qpostscript
= intern ("postscript");
10781 staticpro (&Qpostscript
);
10782 QCloader
= intern (":loader");
10783 staticpro (&QCloader
);
10784 QCbounding_box
= intern (":bounding-box");
10785 staticpro (&QCbounding_box
);
10786 QCpt_width
= intern (":pt-width");
10787 staticpro (&QCpt_width
);
10788 QCpt_height
= intern (":pt-height");
10789 staticpro (&QCpt_height
);
10790 QCindex
= intern (":index");
10791 staticpro (&QCindex
);
10792 Qpbm
= intern ("pbm");
10796 Qxpm
= intern ("xpm");
10801 Qjpeg
= intern ("jpeg");
10802 staticpro (&Qjpeg
);
10806 Qtiff
= intern ("tiff");
10807 staticpro (&Qtiff
);
10811 Qgif
= intern ("gif");
10816 Qpng
= intern ("png");
10820 defsubr (&Sclear_image_cache
);
10821 defsubr (&Simage_size
);
10822 defsubr (&Simage_mask_p
);
10824 hourglass_atimer
= NULL
;
10825 hourglass_shown_p
= 0;
10827 defsubr (&Sx_show_tip
);
10828 defsubr (&Sx_hide_tip
);
10830 staticpro (&tip_timer
);
10832 staticpro (&tip_frame
);
10834 last_show_tip_args
= Qnil
;
10835 staticpro (&last_show_tip_args
);
10838 defsubr (&Sx_file_dialog
);
10846 image_types
= NULL
;
10847 Vimage_types
= Qnil
;
10849 define_image_type (&xbm_type
);
10850 define_image_type (&gs_type
);
10851 define_image_type (&pbm_type
);
10854 define_image_type (&xpm_type
);
10858 define_image_type (&jpeg_type
);
10862 define_image_type (&tiff_type
);
10866 define_image_type (&gif_type
);
10870 define_image_type (&png_type
);
10874 #endif /* HAVE_X_WINDOWS */