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"
45 #include "character.h"
50 #include "termhooks.h"
56 #include <sys/types.h>
60 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
61 #include "bitmaps/gray.xbm"
63 #include <X11/bitmaps/gray>
66 #include "[.bitmaps]gray.xbm"
74 #include <X11/Shell.h>
77 #include <X11/Xaw/Paned.h>
78 #include <X11/Xaw/Label.h>
79 #endif /* USE_MOTIF */
82 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
91 #include "../lwlib/lwlib.h"
95 #include <Xm/DialogS.h>
96 #include <Xm/FileSB.h>
99 /* Do the EDITRES protocol if running X11R5
100 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
102 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
104 extern void _XEditResCheckMessages ();
105 #endif /* R5 + Athena */
107 /* Unique id counter for widgets created by the Lucid Widget Library. */
109 extern LWLIB_ID widget_id_tick
;
112 /* This is part of a kludge--see lwlib/xlwmenu.c. */
113 extern XFontStruct
*xlwmenu_default_font
;
116 extern void free_frame_menubar ();
117 extern double atof ();
121 /* LessTif/Motif version info. */
123 static Lisp_Object Vmotif_version_string
;
125 #endif /* USE_MOTIF */
127 #endif /* USE_X_TOOLKIT */
130 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
132 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
135 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
136 it, and including `bitmaps/gray' more than once is a problem when
137 config.h defines `static' as an empty replacement string. */
139 int gray_bitmap_width
= gray_width
;
140 int gray_bitmap_height
= gray_height
;
141 char *gray_bitmap_bits
= gray_bits
;
143 /* Non-zero means we're allowed to display an hourglass cursor. */
145 int display_hourglass_p
;
147 /* The background and shape of the mouse pointer, and shape when not
148 over text or in the modeline. */
150 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
151 Lisp_Object Vx_hourglass_pointer_shape
;
153 /* The shape when over mouse-sensitive text. */
155 Lisp_Object Vx_sensitive_text_pointer_shape
;
157 /* If non-nil, the pointer shape to indicate that windows can be
158 dragged horizontally. */
160 Lisp_Object Vx_window_horizontal_drag_shape
;
162 /* Color of chars displayed in cursor box. */
164 Lisp_Object Vx_cursor_fore_pixel
;
166 /* Nonzero if using X. */
170 /* Non nil if no window manager is in use. */
172 Lisp_Object Vx_no_window_manager
;
174 /* Search path for bitmap files. */
176 Lisp_Object Vx_bitmap_file_path
;
178 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
180 Lisp_Object Vx_pixel_size_width_font_regexp
;
183 Lisp_Object Qsuppress_icon
;
184 Lisp_Object Qundefined_color
;
186 Lisp_Object Qcompound_text
, Qcancel_timer
;
190 extern Lisp_Object Vwindow_system_version
;
192 /* The below are defined in frame.c. */
195 int image_cache_refcount
, dpyinfo_refcount
;
200 /* Error if we are not connected to X. */
206 error ("X windows are not in use or not initialized");
209 /* Nonzero if we can use mouse menus.
210 You should not call this unless HAVE_MENUS is defined. */
218 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
219 and checking validity for X. */
222 check_x_frame (frame
)
228 frame
= selected_frame
;
229 CHECK_LIVE_FRAME (frame
);
232 error ("Non-X frame used");
236 /* Let the user specify an X display with a frame.
237 nil stands for the selected frame--or, if that is not an X frame,
238 the first X display on the list. */
240 struct x_display_info
*
241 check_x_display_info (frame
)
244 struct x_display_info
*dpyinfo
= NULL
;
248 struct frame
*sf
= XFRAME (selected_frame
);
250 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
251 dpyinfo
= FRAME_X_DISPLAY_INFO (sf
);
252 else if (x_display_list
!= 0)
253 dpyinfo
= x_display_list
;
255 error ("X windows are not in use or not initialized");
257 else if (STRINGP (frame
))
258 dpyinfo
= x_display_info_for_name (frame
);
261 FRAME_PTR f
= check_x_frame (frame
);
262 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
269 /* Return the Emacs frame-object corresponding to an X window.
270 It could be the frame's main window or an icon window. */
272 /* This function can be called during GC, so use GC_xxx type test macros. */
275 x_window_to_frame (dpyinfo
, wdesc
)
276 struct x_display_info
*dpyinfo
;
279 Lisp_Object tail
, frame
;
282 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
285 if (!GC_FRAMEP (frame
))
288 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
290 if (f
->output_data
.x
->hourglass_window
== wdesc
)
293 if ((f
->output_data
.x
->edit_widget
294 && XtWindow (f
->output_data
.x
->edit_widget
) == wdesc
)
295 /* A tooltip frame? */
296 || (!f
->output_data
.x
->edit_widget
297 && FRAME_X_WINDOW (f
) == wdesc
)
298 || f
->output_data
.x
->icon_desc
== wdesc
)
300 #else /* not USE_X_TOOLKIT */
302 if (f
->output_data
.x
->edit_widget
)
304 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
305 struct x_output
*x
= f
->output_data
.x
;
306 if (gwdesc
!= 0 && gwdesc
== x
->edit_widget
)
310 if (FRAME_X_WINDOW (f
) == wdesc
311 || f
->output_data
.x
->icon_desc
== wdesc
)
313 #endif /* not USE_X_TOOLKIT */
318 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
319 /* Like x_window_to_frame but also compares the window with the widget's
323 x_any_window_to_frame (dpyinfo
, wdesc
)
324 struct x_display_info
*dpyinfo
;
327 Lisp_Object tail
, frame
;
328 struct frame
*f
, *found
;
332 for (tail
= Vframe_list
; GC_CONSP (tail
) && !found
; tail
= XCDR (tail
))
335 if (!GC_FRAMEP (frame
))
339 if (FRAME_X_P (f
) && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
341 /* This frame matches if the window is any of its widgets. */
342 x
= f
->output_data
.x
;
343 if (x
->hourglass_window
== wdesc
)
348 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
350 && (gwdesc
== x
->widget
351 || gwdesc
== x
->edit_widget
352 || gwdesc
== x
->vbox_widget
353 || gwdesc
== x
->menubar_widget
))
356 if (wdesc
== XtWindow (x
->widget
)
357 || wdesc
== XtWindow (x
->column_widget
)
358 || wdesc
== XtWindow (x
->edit_widget
))
360 /* Match if the window is this frame's menubar. */
361 else if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
365 else if (FRAME_X_WINDOW (f
) == wdesc
)
366 /* A tooltip frame. */
374 /* Likewise, but exclude the menu bar widget. */
377 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
378 struct x_display_info
*dpyinfo
;
381 Lisp_Object tail
, frame
;
385 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
388 if (!GC_FRAMEP (frame
))
391 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
393 x
= f
->output_data
.x
;
394 /* This frame matches if the window is any of its widgets. */
395 if (x
->hourglass_window
== wdesc
)
400 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
402 && (gwdesc
== x
->widget
403 || gwdesc
== x
->edit_widget
404 || gwdesc
== x
->vbox_widget
))
407 if (wdesc
== XtWindow (x
->widget
)
408 || wdesc
== XtWindow (x
->column_widget
)
409 || wdesc
== XtWindow (x
->edit_widget
))
413 else if (FRAME_X_WINDOW (f
) == wdesc
)
414 /* A tooltip frame. */
420 /* Likewise, but consider only the menu bar widget. */
423 x_menubar_window_to_frame (dpyinfo
, wdesc
)
424 struct x_display_info
*dpyinfo
;
427 Lisp_Object tail
, frame
;
431 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
434 if (!GC_FRAMEP (frame
))
437 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
439 x
= f
->output_data
.x
;
440 /* Match if the window is this frame's menubar. */
442 if (x
->menubar_widget
)
444 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
449 && (gwdesc
== x
->menubar_widget
450 || gtk_widget_get_parent (gwdesc
) == x
->menubar_widget
))
456 if (x
->menubar_widget
457 && lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
464 /* Return the frame whose principal (outermost) window is WDESC.
465 If WDESC is some other (smaller) window, we return 0. */
468 x_top_window_to_frame (dpyinfo
, wdesc
)
469 struct x_display_info
*dpyinfo
;
472 Lisp_Object tail
, frame
;
476 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
479 if (!GC_FRAMEP (frame
))
482 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
484 x
= f
->output_data
.x
;
488 /* This frame matches if the window is its topmost widget. */
490 GtkWidget
*gwdesc
= xg_win_to_widget (wdesc
);
491 if (gwdesc
== x
->widget
)
494 if (wdesc
== XtWindow (x
->widget
))
496 #if 0 /* I don't know why it did this,
497 but it seems logically wrong,
498 and it causes trouble for MapNotify events. */
499 /* Match if the window is this frame's menubar. */
500 if (x
->menubar_widget
501 && wdesc
== XtWindow (x
->menubar_widget
))
506 else if (FRAME_X_WINDOW (f
) == wdesc
)
512 #endif /* USE_X_TOOLKIT || USE_GTK */
516 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
517 id, which is just an int that this section returns. Bitmaps are
518 reference counted so they can be shared among frames.
520 Bitmap indices are guaranteed to be > 0, so a negative number can
521 be used to indicate no bitmap.
523 If you use x_create_bitmap_from_data, then you must keep track of
524 the bitmaps yourself. That is, creating a bitmap from the same
525 data more than once will not be caught. */
528 /* Functions to access the contents of a bitmap, given an id. */
531 x_bitmap_height (f
, id
)
535 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
539 x_bitmap_width (f
, id
)
543 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
547 x_bitmap_pixmap (f
, id
)
551 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
555 x_bitmap_mask (f
, id
)
559 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].mask
;
563 /* Allocate a new bitmap record. Returns index of new record. */
566 x_allocate_bitmap_record (f
)
569 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
572 if (dpyinfo
->bitmaps
== NULL
)
574 dpyinfo
->bitmaps_size
= 10;
576 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
577 dpyinfo
->bitmaps_last
= 1;
581 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
582 return ++dpyinfo
->bitmaps_last
;
584 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
585 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
588 dpyinfo
->bitmaps_size
*= 2;
590 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
591 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
592 return ++dpyinfo
->bitmaps_last
;
595 /* Add one reference to the reference count of the bitmap with id ID. */
598 x_reference_bitmap (f
, id
)
602 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
605 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
608 x_create_bitmap_from_data (f
, bits
, width
, height
)
611 unsigned int width
, height
;
613 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
617 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
618 bits
, width
, height
);
625 id
= x_allocate_bitmap_record (f
);
626 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
627 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
628 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
629 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
630 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
631 dpyinfo
->bitmaps
[id
- 1].height
= height
;
632 dpyinfo
->bitmaps
[id
- 1].width
= width
;
637 /* Create bitmap from file FILE for frame F. */
640 x_create_bitmap_from_file (f
, file
)
644 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
645 unsigned int width
, height
;
647 int xhot
, yhot
, result
, id
;
652 /* Look for an existing bitmap with the same name. */
653 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
655 if (dpyinfo
->bitmaps
[id
].refcount
656 && dpyinfo
->bitmaps
[id
].file
657 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) SDATA (file
)))
659 ++dpyinfo
->bitmaps
[id
].refcount
;
664 /* Search bitmap-file-path for the file, if appropriate. */
665 fd
= openp (Vx_bitmap_file_path
, file
, Qnil
, &found
, Qnil
);
670 filename
= (char *) SDATA (found
);
672 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
673 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
674 if (result
!= BitmapSuccess
)
677 id
= x_allocate_bitmap_record (f
);
678 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
679 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
680 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
681 dpyinfo
->bitmaps
[id
- 1].file
682 = (char *) xmalloc (SBYTES (file
) + 1);
683 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
684 dpyinfo
->bitmaps
[id
- 1].height
= height
;
685 dpyinfo
->bitmaps
[id
- 1].width
= width
;
686 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
691 /* Remove reference to bitmap with id number ID. */
694 x_destroy_bitmap (f
, id
)
698 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
702 --dpyinfo
->bitmaps
[id
- 1].refcount
;
703 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
706 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
707 if (dpyinfo
->bitmaps
[id
- 1].have_mask
)
708 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].mask
);
709 if (dpyinfo
->bitmaps
[id
- 1].file
)
711 xfree (dpyinfo
->bitmaps
[id
- 1].file
);
712 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
719 /* Free all the bitmaps for the display specified by DPYINFO. */
722 x_destroy_all_bitmaps (dpyinfo
)
723 struct x_display_info
*dpyinfo
;
726 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
727 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
729 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
730 if (dpyinfo
->bitmaps
[i
].have_mask
)
731 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].mask
);
732 if (dpyinfo
->bitmaps
[i
].file
)
733 xfree (dpyinfo
->bitmaps
[i
].file
);
735 dpyinfo
->bitmaps_last
= 0;
741 /* Useful functions defined in the section
742 `Image type independent image structures' below. */
744 static unsigned long four_corners_best
P_ ((XImage
*ximg
, unsigned long width
,
745 unsigned long height
));
747 static int x_create_x_image_and_pixmap
P_ ((struct frame
*f
, int width
, int height
,
748 int depth
, XImage
**ximg
,
751 static void x_destroy_x_image
P_ ((XImage
*ximg
));
754 /* Create a mask of a bitmap. Note is this not a perfect mask.
755 It's nicer with some borders in this context */
758 x_create_bitmap_mask(f
, id
)
763 XImage
*ximg
, *mask_img
;
764 unsigned long width
, height
;
767 unsigned long x
, y
, xp
, xm
, yp
, ym
;
770 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
771 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
776 pixmap
= x_bitmap_pixmap(f
, id
);
777 width
= x_bitmap_width(f
, id
);
778 height
= x_bitmap_height(f
, id
);
781 ximg
= XGetImage (FRAME_X_DISPLAY (f
), pixmap
, 0, 0, width
, height
,
790 result
= x_create_x_image_and_pixmap (f
, width
, height
, 1, &mask_img
, &mask
);
799 bg
= four_corners_best (ximg
, width
, height
);
801 for (y
= 0; y
< ximg
->height
; ++y
)
803 for (x
= 0; x
< ximg
->width
; ++x
)
805 xp
= x
!= ximg
->width
- 1 ? x
+ 1 : 0;
806 xm
= x
!= 0 ? x
- 1 : ximg
->width
- 1;
807 yp
= y
!= ximg
->height
- 1 ? y
+ 1 : 0;
808 ym
= y
!= 0 ? y
- 1 : ximg
->height
- 1;
809 if (XGetPixel (ximg
, x
, y
) == bg
810 && XGetPixel (ximg
, x
, yp
) == bg
811 && XGetPixel (ximg
, x
, ym
) == bg
812 && XGetPixel (ximg
, xp
, y
) == bg
813 && XGetPixel (ximg
, xp
, yp
) == bg
814 && XGetPixel (ximg
, xp
, ym
) == bg
815 && XGetPixel (ximg
, xm
, y
) == bg
816 && XGetPixel (ximg
, xm
, yp
) == bg
817 && XGetPixel (ximg
, xm
, ym
) == bg
)
818 XPutPixel (mask_img
, x
, y
, 0);
820 XPutPixel (mask_img
, x
, y
, 1);
824 xassert (interrupt_input_blocked
);
825 gc
= XCreateGC (FRAME_X_DISPLAY (f
), mask
, 0, NULL
);
826 XPutImage (FRAME_X_DISPLAY (f
), mask
, gc
, mask_img
, 0, 0, 0, 0,
828 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
830 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
831 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
833 XDestroyImage (ximg
);
834 x_destroy_x_image(mask_img
);
839 static Lisp_Object unwind_create_frame
P_ ((Lisp_Object
));
840 static Lisp_Object unwind_create_tip_frame
P_ ((Lisp_Object
));
841 static void x_disable_image
P_ ((struct frame
*, struct image
*));
843 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
844 static void x_set_wait_for_wm
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
845 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
846 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
847 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
848 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
849 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
850 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
851 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
852 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
853 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
854 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
855 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
856 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
858 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
860 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
865 static void x_edge_detection
P_ ((struct frame
*, struct image
*, Lisp_Object
,
867 static void init_color_table
P_ ((void));
868 static void free_color_table
P_ ((void));
869 static unsigned long *colors_in_color_table
P_ ((int *n
));
870 static unsigned long lookup_rgb_color
P_ ((struct frame
*f
, int r
, int g
, int b
));
871 static unsigned long lookup_pixel_color
P_ ((struct frame
*f
, unsigned long p
));
877 /* Store the screen positions of frame F into XPTR and YPTR.
878 These are the positions of the containing window manager window,
879 not Emacs's own window. */
882 x_real_positions (f
, xptr
, yptr
)
886 int win_x
, win_y
, outer_x
, outer_y
;
887 int real_x
= 0, real_y
= 0;
889 Window win
= f
->output_data
.x
->parent_desc
;
895 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
897 if (win
== FRAME_X_DISPLAY_INFO (f
)->root_window
)
898 win
= FRAME_OUTER_WINDOW (f
);
900 /* This loop traverses up the containment tree until we hit the root
901 window. Window managers may intersect many windows between our window
902 and the root window. The window we find just before the root window
903 should be the outer WM window. */
906 Window wm_window
, rootw
;
907 Window
*tmp_children
;
908 unsigned int tmp_nchildren
;
911 success
= XQueryTree (FRAME_X_DISPLAY (f
), win
, &rootw
,
912 &wm_window
, &tmp_children
, &tmp_nchildren
);
914 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
916 /* Don't free tmp_children if XQueryTree failed. */
920 XFree ((char *) tmp_children
);
922 if (wm_window
== rootw
|| had_errors
)
933 /* Get the real coordinates for the WM window upper left corner */
934 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
935 &rootw
, &real_x
, &real_y
, &ign
, &ign
, &ign
, &ign
);
937 /* Translate real coordinates to coordinates relative to our
938 window. For our window, the upper left corner is 0, 0.
939 Since the upper left corner of the WM window is outside
940 our window, win_x and win_y will be negative:
942 ------------------ ---> x
944 | ----------------- v y
947 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
949 /* From-window, to-window. */
950 FRAME_X_DISPLAY_INFO (f
)->root_window
,
953 /* From-position, to-position. */
954 real_x
, real_y
, &win_x
, &win_y
,
959 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
966 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
968 /* From-window, to-window. */
969 FRAME_X_DISPLAY_INFO (f
)->root_window
,
970 FRAME_OUTER_WINDOW (f
),
972 /* From-position, to-position. */
973 real_x
, real_y
, &outer_x
, &outer_y
,
979 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
982 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
986 if (had_errors
) return;
988 f
->x_pixels_diff
= -win_x
;
989 f
->y_pixels_diff
= -win_y
;
991 FRAME_X_OUTPUT (f
)->x_pixels_outer_diff
= -outer_x
;
992 FRAME_X_OUTPUT (f
)->y_pixels_outer_diff
= -outer_y
;
1001 /* Gamma-correct COLOR on frame F. */
1004 gamma_correct (f
, color
)
1010 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
1011 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
1012 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
1017 /* Decide if color named COLOR_NAME is valid for use on frame F. If
1018 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
1019 allocate the color. Value is zero if COLOR_NAME is invalid, or
1020 no color could be allocated. */
1023 x_defined_color (f
, color_name
, color
, alloc_p
)
1030 Display
*dpy
= FRAME_X_DISPLAY (f
);
1031 Colormap cmap
= FRAME_X_COLORMAP (f
);
1034 success_p
= XParseColor (dpy
, cmap
, color_name
, color
);
1035 if (success_p
&& alloc_p
)
1036 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
1043 /* Return the pixel color value for color COLOR_NAME on frame F. If F
1044 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
1045 Signal an error if color can't be allocated. */
1048 x_decode_color (f
, color_name
, mono_color
)
1050 Lisp_Object color_name
;
1055 CHECK_STRING (color_name
);
1057 #if 0 /* Don't do this. It's wrong when we're not using the default
1058 colormap, it makes freeing difficult, and it's probably not
1059 an important optimization. */
1060 if (strcmp (SDATA (color_name
), "black") == 0)
1061 return BLACK_PIX_DEFAULT (f
);
1062 else if (strcmp (SDATA (color_name
), "white") == 0)
1063 return WHITE_PIX_DEFAULT (f
);
1066 /* Return MONO_COLOR for monochrome frames. */
1067 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1070 /* x_defined_color is responsible for coping with failures
1071 by looking for a near-miss. */
1072 if (x_defined_color (f
, SDATA (color_name
), &cdef
, 1))
1075 Fsignal (Qerror
, Fcons (build_string ("Undefined color"),
1076 Fcons (color_name
, Qnil
)));
1082 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
1083 the previous value of that parameter, NEW_VALUE is the new value.
1084 See also the comment of wait_for_wm in struct x_output. */
1087 x_set_wait_for_wm (f
, new_value
, old_value
)
1089 Lisp_Object new_value
, old_value
;
1091 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
1096 static Lisp_Object x_find_image_file
P_ ((Lisp_Object file
));
1098 /* Set icon from FILE for frame F. By using GTK functions the icon
1099 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
1102 xg_set_icon(f
, file
)
1106 struct gcpro gcpro1
;
1112 found
= x_find_image_file (file
);
1120 filename
= SDATA (found
);
1123 pixbuf
= gdk_pixbuf_new_from_file (filename
, &err
);
1127 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1129 g_object_unref (pixbuf
);
1142 #endif /* USE_GTK */
1145 /* Functions called only from `x_set_frame_param'
1146 to set individual parameters.
1148 If FRAME_X_WINDOW (f) is 0,
1149 the frame is being created and its X-window does not exist yet.
1150 In that case, just record the parameter's new value
1151 in the standard place; do not attempt to change the window. */
1154 x_set_foreground_color (f
, arg
, oldval
)
1156 Lisp_Object arg
, oldval
;
1158 struct x_output
*x
= f
->output_data
.x
;
1159 unsigned long fg
, old_fg
;
1161 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1162 old_fg
= x
->foreground_pixel
;
1163 x
->foreground_pixel
= fg
;
1165 if (FRAME_X_WINDOW (f
) != 0)
1167 Display
*dpy
= FRAME_X_DISPLAY (f
);
1170 XSetForeground (dpy
, x
->normal_gc
, fg
);
1171 XSetBackground (dpy
, x
->reverse_gc
, fg
);
1173 if (x
->cursor_pixel
== old_fg
)
1175 unload_color (f
, x
->cursor_pixel
);
1176 x
->cursor_pixel
= x_copy_color (f
, fg
);
1177 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
1182 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
1184 if (FRAME_VISIBLE_P (f
))
1188 unload_color (f
, old_fg
);
1192 x_set_background_color (f
, arg
, oldval
)
1194 Lisp_Object arg
, oldval
;
1196 struct x_output
*x
= f
->output_data
.x
;
1199 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1200 unload_color (f
, x
->background_pixel
);
1201 x
->background_pixel
= bg
;
1203 if (FRAME_X_WINDOW (f
) != 0)
1205 Display
*dpy
= FRAME_X_DISPLAY (f
);
1208 XSetBackground (dpy
, x
->normal_gc
, bg
);
1209 XSetForeground (dpy
, x
->reverse_gc
, bg
);
1210 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
1211 XSetForeground (dpy
, x
->cursor_gc
, bg
);
1214 xg_set_background_color (f
, bg
);
1217 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
1218 toolkit scroll bars. */
1221 for (bar
= FRAME_SCROLL_BARS (f
);
1223 bar
= XSCROLL_BAR (bar
)->next
)
1225 Window window
= SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
));
1226 XSetWindowBackground (dpy
, window
, bg
);
1229 #endif /* USE_TOOLKIT_SCROLL_BARS */
1232 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
1234 if (FRAME_VISIBLE_P (f
))
1240 x_set_mouse_color (f
, arg
, oldval
)
1242 Lisp_Object arg
, oldval
;
1244 struct x_output
*x
= f
->output_data
.x
;
1245 Display
*dpy
= FRAME_X_DISPLAY (f
);
1246 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
1247 Cursor hourglass_cursor
, horizontal_drag_cursor
;
1249 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1250 unsigned long mask_color
= x
->background_pixel
;
1252 /* Don't let pointers be invisible. */
1253 if (mask_color
== pixel
)
1255 x_free_colors (f
, &pixel
, 1);
1256 pixel
= x_copy_color (f
, x
->foreground_pixel
);
1259 unload_color (f
, x
->mouse_pixel
);
1260 x
->mouse_pixel
= pixel
;
1264 /* It's not okay to crash if the user selects a screwy cursor. */
1265 count
= x_catch_errors (dpy
);
1267 if (!NILP (Vx_pointer_shape
))
1269 CHECK_NUMBER (Vx_pointer_shape
);
1270 cursor
= XCreateFontCursor (dpy
, XINT (Vx_pointer_shape
));
1273 cursor
= XCreateFontCursor (dpy
, XC_xterm
);
1274 x_check_errors (dpy
, "bad text pointer cursor: %s");
1276 if (!NILP (Vx_nontext_pointer_shape
))
1278 CHECK_NUMBER (Vx_nontext_pointer_shape
);
1280 = XCreateFontCursor (dpy
, XINT (Vx_nontext_pointer_shape
));
1283 nontext_cursor
= XCreateFontCursor (dpy
, XC_left_ptr
);
1284 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
1286 if (!NILP (Vx_hourglass_pointer_shape
))
1288 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
1290 = XCreateFontCursor (dpy
, XINT (Vx_hourglass_pointer_shape
));
1293 hourglass_cursor
= XCreateFontCursor (dpy
, XC_watch
);
1294 x_check_errors (dpy
, "bad hourglass pointer cursor: %s");
1296 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
1297 if (!NILP (Vx_mode_pointer_shape
))
1299 CHECK_NUMBER (Vx_mode_pointer_shape
);
1300 mode_cursor
= XCreateFontCursor (dpy
, XINT (Vx_mode_pointer_shape
));
1303 mode_cursor
= XCreateFontCursor (dpy
, XC_xterm
);
1304 x_check_errors (dpy
, "bad modeline pointer cursor: %s");
1306 if (!NILP (Vx_sensitive_text_pointer_shape
))
1308 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
1310 = XCreateFontCursor (dpy
, XINT (Vx_sensitive_text_pointer_shape
));
1313 hand_cursor
= XCreateFontCursor (dpy
, XC_hand2
);
1315 if (!NILP (Vx_window_horizontal_drag_shape
))
1317 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
1318 horizontal_drag_cursor
1319 = XCreateFontCursor (dpy
, XINT (Vx_window_horizontal_drag_shape
));
1322 horizontal_drag_cursor
1323 = XCreateFontCursor (dpy
, XC_sb_h_double_arrow
);
1325 /* Check and report errors with the above calls. */
1326 x_check_errors (dpy
, "can't set cursor shape: %s");
1327 x_uncatch_errors (dpy
, count
);
1330 XColor fore_color
, back_color
;
1332 fore_color
.pixel
= x
->mouse_pixel
;
1333 x_query_color (f
, &fore_color
);
1334 back_color
.pixel
= mask_color
;
1335 x_query_color (f
, &back_color
);
1337 XRecolorCursor (dpy
, cursor
, &fore_color
, &back_color
);
1338 XRecolorCursor (dpy
, nontext_cursor
, &fore_color
, &back_color
);
1339 XRecolorCursor (dpy
, mode_cursor
, &fore_color
, &back_color
);
1340 XRecolorCursor (dpy
, hand_cursor
, &fore_color
, &back_color
);
1341 XRecolorCursor (dpy
, hourglass_cursor
, &fore_color
, &back_color
);
1342 XRecolorCursor (dpy
, horizontal_drag_cursor
, &fore_color
, &back_color
);
1345 if (FRAME_X_WINDOW (f
) != 0)
1346 XDefineCursor (dpy
, FRAME_X_WINDOW (f
), cursor
);
1348 if (cursor
!= x
->text_cursor
1349 && x
->text_cursor
!= 0)
1350 XFreeCursor (dpy
, x
->text_cursor
);
1351 x
->text_cursor
= cursor
;
1353 if (nontext_cursor
!= x
->nontext_cursor
1354 && x
->nontext_cursor
!= 0)
1355 XFreeCursor (dpy
, x
->nontext_cursor
);
1356 x
->nontext_cursor
= nontext_cursor
;
1358 if (hourglass_cursor
!= x
->hourglass_cursor
1359 && x
->hourglass_cursor
!= 0)
1360 XFreeCursor (dpy
, x
->hourglass_cursor
);
1361 x
->hourglass_cursor
= hourglass_cursor
;
1363 if (mode_cursor
!= x
->modeline_cursor
1364 && x
->modeline_cursor
!= 0)
1365 XFreeCursor (dpy
, f
->output_data
.x
->modeline_cursor
);
1366 x
->modeline_cursor
= mode_cursor
;
1368 if (hand_cursor
!= x
->hand_cursor
1369 && x
->hand_cursor
!= 0)
1370 XFreeCursor (dpy
, x
->hand_cursor
);
1371 x
->hand_cursor
= hand_cursor
;
1373 if (horizontal_drag_cursor
!= x
->horizontal_drag_cursor
1374 && x
->horizontal_drag_cursor
!= 0)
1375 XFreeCursor (dpy
, x
->horizontal_drag_cursor
);
1376 x
->horizontal_drag_cursor
= horizontal_drag_cursor
;
1381 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1385 x_set_cursor_color (f
, arg
, oldval
)
1387 Lisp_Object arg
, oldval
;
1389 unsigned long fore_pixel
, pixel
;
1390 int fore_pixel_allocated_p
= 0, pixel_allocated_p
= 0;
1391 struct x_output
*x
= f
->output_data
.x
;
1393 if (!NILP (Vx_cursor_fore_pixel
))
1395 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1396 WHITE_PIX_DEFAULT (f
));
1397 fore_pixel_allocated_p
= 1;
1400 fore_pixel
= x
->background_pixel
;
1402 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1403 pixel_allocated_p
= 1;
1405 /* Make sure that the cursor color differs from the background color. */
1406 if (pixel
== x
->background_pixel
)
1408 if (pixel_allocated_p
)
1410 x_free_colors (f
, &pixel
, 1);
1411 pixel_allocated_p
= 0;
1414 pixel
= x
->mouse_pixel
;
1415 if (pixel
== fore_pixel
)
1417 if (fore_pixel_allocated_p
)
1419 x_free_colors (f
, &fore_pixel
, 1);
1420 fore_pixel_allocated_p
= 0;
1422 fore_pixel
= x
->background_pixel
;
1426 unload_color (f
, x
->cursor_foreground_pixel
);
1427 if (!fore_pixel_allocated_p
)
1428 fore_pixel
= x_copy_color (f
, fore_pixel
);
1429 x
->cursor_foreground_pixel
= fore_pixel
;
1431 unload_color (f
, x
->cursor_pixel
);
1432 if (!pixel_allocated_p
)
1433 pixel
= x_copy_color (f
, pixel
);
1434 x
->cursor_pixel
= pixel
;
1436 if (FRAME_X_WINDOW (f
) != 0)
1439 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
1440 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
1443 if (FRAME_VISIBLE_P (f
))
1445 x_update_cursor (f
, 0);
1446 x_update_cursor (f
, 1);
1450 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1453 /* Set the border-color of frame F to pixel value PIX.
1454 Note that this does not fully take effect if done before
1455 F has an x-window. */
1458 x_set_border_pixel (f
, pix
)
1462 unload_color (f
, f
->output_data
.x
->border_pixel
);
1463 f
->output_data
.x
->border_pixel
= pix
;
1465 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
1468 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1469 (unsigned long)pix
);
1472 if (FRAME_VISIBLE_P (f
))
1477 /* Set the border-color of frame F to value described by ARG.
1478 ARG can be a string naming a color.
1479 The border-color is used for the border that is drawn by the X server.
1480 Note that this does not fully take effect if done before
1481 F has an x-window; it must be redone when the window is created.
1483 Note: this is done in two routines because of the way X10 works.
1485 Note: under X11, this is normally the province of the window manager,
1486 and so emacs' border colors may be overridden. */
1489 x_set_border_color (f
, arg
, oldval
)
1491 Lisp_Object arg
, oldval
;
1496 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1497 x_set_border_pixel (f
, pix
);
1498 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1503 x_set_cursor_type (f
, arg
, oldval
)
1505 Lisp_Object arg
, oldval
;
1507 set_frame_cursor_types (f
, arg
);
1509 /* Make sure the cursor gets redrawn. */
1510 cursor_type_changed
= 1;
1514 x_set_icon_type (f
, arg
, oldval
)
1516 Lisp_Object arg
, oldval
;
1522 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1525 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1530 result
= x_text_icon (f
,
1531 (char *) SDATA ((!NILP (f
->icon_name
)
1535 result
= x_bitmap_icon (f
, arg
);
1540 error ("No icon window available");
1543 XFlush (FRAME_X_DISPLAY (f
));
1548 x_set_icon_name (f
, arg
, oldval
)
1550 Lisp_Object arg
, oldval
;
1556 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1559 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1564 if (f
->output_data
.x
->icon_bitmap
!= 0)
1569 result
= x_text_icon (f
,
1570 (char *) SDATA ((!NILP (f
->icon_name
)
1579 error ("No icon window available");
1582 XFlush (FRAME_X_DISPLAY (f
));
1588 x_set_menu_bar_lines (f
, value
, oldval
)
1590 Lisp_Object value
, oldval
;
1593 #ifndef USE_X_TOOLKIT
1594 int olines
= FRAME_MENU_BAR_LINES (f
);
1597 /* Right now, menu bars don't work properly in minibuf-only frames;
1598 most of the commands try to apply themselves to the minibuffer
1599 frame itself, and get an error because you can't switch buffers
1600 in or split the minibuffer window. */
1601 if (FRAME_MINIBUF_ONLY_P (f
))
1604 if (INTEGERP (value
))
1605 nlines
= XINT (value
);
1609 /* Make sure we redisplay all windows in this frame. */
1610 windows_or_buffers_changed
++;
1612 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1613 FRAME_MENU_BAR_LINES (f
) = 0;
1616 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1617 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1618 /* Make sure next redisplay shows the menu bar. */
1619 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1623 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1624 free_frame_menubar (f
);
1625 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1627 f
->output_data
.x
->menubar_widget
= 0;
1629 #else /* not USE_X_TOOLKIT && not USE_GTK */
1630 FRAME_MENU_BAR_LINES (f
) = nlines
;
1631 change_window_heights (f
->root_window
, nlines
- olines
);
1632 #endif /* not USE_X_TOOLKIT */
1637 /* Set the number of lines used for the tool bar of frame F to VALUE.
1638 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1639 is the old number of tool bar lines. This function changes the
1640 height of all windows on frame F to match the new tool bar height.
1641 The frame's height doesn't change. */
1644 x_set_tool_bar_lines (f
, value
, oldval
)
1646 Lisp_Object value
, oldval
;
1648 int delta
, nlines
, root_height
;
1649 Lisp_Object root_window
;
1651 /* Treat tool bars like menu bars. */
1652 if (FRAME_MINIBUF_ONLY_P (f
))
1655 /* Use VALUE only if an integer >= 0. */
1656 if (INTEGERP (value
) && XINT (value
) >= 0)
1657 nlines
= XFASTINT (value
);
1662 FRAME_TOOL_BAR_LINES (f
) = 0;
1665 FRAME_EXTERNAL_TOOL_BAR (f
) = 1;
1666 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1667 /* Make sure next redisplay shows the tool bar. */
1668 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1669 update_frame_tool_bar (f
);
1673 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1674 free_frame_tool_bar (f
);
1675 FRAME_EXTERNAL_TOOL_BAR (f
) = 0;
1681 /* Make sure we redisplay all windows in this frame. */
1682 ++windows_or_buffers_changed
;
1684 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
1686 /* Don't resize the tool-bar to more than we have room for. */
1687 root_window
= FRAME_ROOT_WINDOW (f
);
1688 root_height
= WINDOW_TOTAL_LINES (XWINDOW (root_window
));
1689 if (root_height
- delta
< 1)
1691 delta
= root_height
- 1;
1692 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
1695 FRAME_TOOL_BAR_LINES (f
) = nlines
;
1696 change_window_heights (root_window
, delta
);
1699 /* We also have to make sure that the internal border at the top of
1700 the frame, below the menu bar or tool bar, is redrawn when the
1701 tool bar disappears. This is so because the internal border is
1702 below the tool bar if one is displayed, but is below the menu bar
1703 if there isn't a tool bar. The tool bar draws into the area
1704 below the menu bar. */
1705 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
1709 clear_current_matrices (f
);
1710 updating_frame
= NULL
;
1713 /* If the tool bar gets smaller, the internal border below it
1714 has to be cleared. It was formerly part of the display
1715 of the larger tool bar, and updating windows won't clear it. */
1718 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1719 int width
= FRAME_PIXEL_WIDTH (f
);
1720 int y
= nlines
* FRAME_LINE_HEIGHT (f
);
1723 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1724 0, y
, width
, height
, False
);
1727 if (WINDOWP (f
->tool_bar_window
))
1728 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1733 /* Set the foreground color for scroll bars on frame F to VALUE.
1734 VALUE should be a string, a color name. If it isn't a string or
1735 isn't a valid color name, do nothing. OLDVAL is the old value of
1736 the frame parameter. */
1739 x_set_scroll_bar_foreground (f
, value
, oldval
)
1741 Lisp_Object value
, oldval
;
1743 unsigned long pixel
;
1745 if (STRINGP (value
))
1746 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1750 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1751 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1753 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1754 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1756 /* Remove all scroll bars because they have wrong colors. */
1757 if (condemn_scroll_bars_hook
)
1758 (*condemn_scroll_bars_hook
) (f
);
1759 if (judge_scroll_bars_hook
)
1760 (*judge_scroll_bars_hook
) (f
);
1762 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1768 /* Set the background color for scroll bars on frame F to VALUE VALUE
1769 should be a string, a color name. If it isn't a string or isn't a
1770 valid color name, do nothing. OLDVAL is the old value of the frame
1774 x_set_scroll_bar_background (f
, value
, oldval
)
1776 Lisp_Object value
, oldval
;
1778 unsigned long pixel
;
1780 if (STRINGP (value
))
1781 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1785 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1786 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1788 #ifdef USE_TOOLKIT_SCROLL_BARS
1789 /* Scrollbar shadow colors. */
1790 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1792 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1793 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1795 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1797 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1798 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1800 #endif /* USE_TOOLKIT_SCROLL_BARS */
1802 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1803 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1805 /* Remove all scroll bars because they have wrong colors. */
1806 if (condemn_scroll_bars_hook
)
1807 (*condemn_scroll_bars_hook
) (f
);
1808 if (judge_scroll_bars_hook
)
1809 (*judge_scroll_bars_hook
) (f
);
1811 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1817 /* Encode Lisp string STRING as a text in a format appropriate for
1818 XICCC (X Inter Client Communication Conventions).
1820 If STRING contains only ASCII characters, do no conversion and
1821 return the string data of STRING. Otherwise, encode the text by
1822 CODING_SYSTEM, and return a newly allocated memory area which
1823 should be freed by `xfree' by a caller.
1825 SELECTIONP non-zero means the string is being encoded for an X
1826 selection, so it is safe to run pre-write conversions (which
1829 Store the byte length of resulting text in *TEXT_BYTES.
1831 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1832 which means that the `encoding' of the result can be `STRING'.
1833 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1834 the result should be `COMPOUND_TEXT'. */
1837 x_encode_text (string
, coding_system
, selectionp
, text_bytes
, stringp
)
1838 Lisp_Object string
, coding_system
;
1839 int *text_bytes
, *stringp
;
1842 int result
= string_xstring_p (string
);
1843 struct coding_system coding
;
1844 extern Lisp_Object Qcompound_text_with_extensions
;
1848 /* No multibyte character in OBJ. We need not encode it. */
1849 *text_bytes
= SBYTES (string
);
1851 return SDATA (string
);
1854 setup_coding_system (coding_system
, &coding
);
1855 coding
.mode
|= (CODING_MODE_SAFE_ENCODING
| CODING_MODE_LAST_BLOCK
);
1856 /* We suppress producing escape sequences for composition. */
1857 coding
.common_flags
&= ~CODING_ANNOTATION_MASK
;
1858 coding
.dst_bytes
= SCHARS (string
) * 2;
1859 coding
.destination
= (unsigned char *) xmalloc (coding
.dst_bytes
);
1860 encode_coding_object (&coding
, string
, 0, 0,
1861 SCHARS (string
), SBYTES (string
), Qnil
);
1862 *text_bytes
= coding
.produced
;
1863 *stringp
= (result
== 1 || !EQ (coding_system
, Qcompound_text
));
1864 return coding
.destination
;
1868 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1871 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1872 name; if NAME is a string, set F's name to NAME and set
1873 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1875 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1876 suggesting a new name, which lisp code should override; if
1877 F->explicit_name is set, ignore the new name; otherwise, set it. */
1880 x_set_name (f
, name
, explicit)
1885 /* Make sure that requests from lisp code override requests from
1886 Emacs redisplay code. */
1889 /* If we're switching from explicit to implicit, we had better
1890 update the mode lines and thereby update the title. */
1891 if (f
->explicit_name
&& NILP (name
))
1892 update_mode_lines
= 1;
1894 f
->explicit_name
= ! NILP (name
);
1896 else if (f
->explicit_name
)
1899 /* If NAME is nil, set the name to the x_id_name. */
1902 /* Check for no change needed in this very common case
1903 before we do any consing. */
1904 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1907 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1910 CHECK_STRING (name
);
1912 /* Don't change the name if it's already NAME. */
1913 if (! NILP (Fstring_equal (name
, f
->name
)))
1918 /* For setting the frame title, the title parameter should override
1919 the name parameter. */
1920 if (! NILP (f
->title
))
1923 if (FRAME_X_WINDOW (f
))
1928 XTextProperty text
, icon
;
1930 Lisp_Object coding_system
;
1932 /* Note: Encoding strategy
1934 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1935 text.encoding. But, there are non-internationalized window
1936 managers which don't support that encoding. So, if NAME
1937 contains only ASCII and 8859-1 characters, encode it by
1938 iso-latin-1, and use "STRING" in text.encoding hoping that
1939 such window managers at least analyze this format correctly,
1940 i.e. treat 8-bit bytes as 8859-1 characters.
1942 We may also be able to use "UTF8_STRING" in text.encoding
1943 in the future which can encode all Unicode characters.
1944 But, for the moment, there's no way to know that the
1945 current window manager supports it or not. */
1946 coding_system
= Qcompound_text
;
1947 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
1948 text
.encoding
= (stringp
? XA_STRING
1949 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1951 text
.nitems
= bytes
;
1953 if (NILP (f
->icon_name
))
1959 /* See the above comment "Note: Encoding strategy". */
1960 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
1962 icon
.encoding
= (stringp
? XA_STRING
1963 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1965 icon
.nitems
= bytes
;
1968 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1970 #else /* not USE_GTK */
1971 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1972 #endif /* not USE_GTK */
1974 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1976 if (!NILP (f
->icon_name
)
1977 && icon
.value
!= (unsigned char *) SDATA (f
->icon_name
))
1979 if (text
.value
!= (unsigned char *) SDATA (name
))
1982 #else /* not HAVE_X11R4 */
1983 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1985 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1987 #endif /* not HAVE_X11R4 */
1992 /* This function should be called when the user's lisp code has
1993 specified a name for the frame; the name will override any set by the
1996 x_explicitly_set_name (f
, arg
, oldval
)
1998 Lisp_Object arg
, oldval
;
2000 x_set_name (f
, arg
, 1);
2003 /* This function should be called by Emacs redisplay code to set the
2004 name; names set this way will never override names set by the user's
2007 x_implicitly_set_name (f
, arg
, oldval
)
2009 Lisp_Object arg
, oldval
;
2011 x_set_name (f
, arg
, 0);
2014 /* Change the title of frame F to NAME.
2015 If NAME is nil, use the frame name as the title.
2017 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2018 name; if NAME is a string, set F's name to NAME and set
2019 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2021 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2022 suggesting a new name, which lisp code should override; if
2023 F->explicit_name is set, ignore the new name; otherwise, set it. */
2026 x_set_title (f
, name
, old_name
)
2028 Lisp_Object name
, old_name
;
2030 /* Don't change the title if it's already NAME. */
2031 if (EQ (name
, f
->title
))
2034 update_mode_lines
= 1;
2041 CHECK_STRING (name
);
2043 if (FRAME_X_WINDOW (f
))
2048 XTextProperty text
, icon
;
2050 Lisp_Object coding_system
;
2052 coding_system
= Qcompound_text
;
2053 /* See the comment "Note: Encoding strategy" in x_set_name. */
2054 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
);
2055 text
.encoding
= (stringp
? XA_STRING
2056 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
2058 text
.nitems
= bytes
;
2060 if (NILP (f
->icon_name
))
2066 /* See the comment "Note: Encoding strategy" in x_set_name. */
2067 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
2069 icon
.encoding
= (stringp
? XA_STRING
2070 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
2072 icon
.nitems
= bytes
;
2076 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
2078 #else /* not USE_GTK */
2079 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
2080 #endif /* not USE_GTK */
2082 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
2085 if (!NILP (f
->icon_name
)
2086 && icon
.value
!= (unsigned char *) SDATA (f
->icon_name
))
2088 if (text
.value
!= (unsigned char *) SDATA (name
))
2091 #else /* not HAVE_X11R4 */
2092 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2094 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2096 #endif /* not HAVE_X11R4 */
2102 x_set_scroll_bar_default_width (f
)
2105 int wid
= FRAME_COLUMN_WIDTH (f
);
2107 #ifdef USE_TOOLKIT_SCROLL_BARS
2108 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
2109 int width
= 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
2110 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (width
+ wid
- 1) / wid
;
2111 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = width
;
2113 /* Make the actual width at least 14 pixels and a multiple of a
2115 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
2117 /* Use all of that space (aside from required margins) for the
2119 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = 0;
2124 /* Record in frame F the specified or default value according to ALIST
2125 of the parameter named PROP (a Lisp symbol). If no value is
2126 specified for PROP, look for an X default for XPROP on the frame
2127 named NAME. If that is not found either, use the value DEFLT. */
2130 x_default_scroll_bar_color_parameter (f
, alist
, prop
, xprop
, xclass
,
2139 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2142 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
2143 if (EQ (tem
, Qunbound
))
2145 #ifdef USE_TOOLKIT_SCROLL_BARS
2147 /* See if an X resource for the scroll bar color has been
2149 tem
= display_x_get_resource (dpyinfo
,
2150 build_string (foreground_p
2154 build_string ("verticalScrollBar"),
2158 /* If nothing has been specified, scroll bars will use a
2159 toolkit-dependent default. Because these defaults are
2160 difficult to get at without actually creating a scroll
2161 bar, use nil to indicate that no color has been
2166 #else /* not USE_TOOLKIT_SCROLL_BARS */
2170 #endif /* not USE_TOOLKIT_SCROLL_BARS */
2173 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2179 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2182 XSetWMProtocols (dpy
, w
, protocols
, count
)
2189 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2190 if (prop
== None
) return False
;
2191 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2192 (unsigned char *) protocols
, count
);
2195 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2197 #ifdef USE_X_TOOLKIT
2199 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2200 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2201 already be present because of the toolkit (Motif adds some of them,
2202 for example, but Xt doesn't). */
2205 hack_wm_protocols (f
, widget
)
2209 Display
*dpy
= XtDisplay (widget
);
2210 Window w
= XtWindow (widget
);
2211 int need_delete
= 1;
2217 Atom type
, *atoms
= 0;
2219 unsigned long nitems
= 0;
2220 unsigned long bytes_after
;
2222 if ((XGetWindowProperty (dpy
, w
,
2223 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2224 (long)0, (long)100, False
, XA_ATOM
,
2225 &type
, &format
, &nitems
, &bytes_after
,
2226 (unsigned char **) &atoms
)
2228 && format
== 32 && type
== XA_ATOM
)
2232 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2234 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2236 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2239 if (atoms
) XFree ((char *) atoms
);
2245 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2247 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2249 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2251 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2252 XA_ATOM
, 32, PropModeAppend
,
2253 (unsigned char *) props
, count
);
2261 /* Support routines for XIC (X Input Context). */
2265 static XFontSet xic_create_xfontset
P_ ((struct frame
*, char *));
2266 static XIMStyle best_xim_style
P_ ((XIMStyles
*, XIMStyles
*));
2269 /* Supported XIM styles, ordered by preference. */
2271 static XIMStyle supported_xim_styles
[] =
2273 XIMPreeditPosition
| XIMStatusArea
,
2274 XIMPreeditPosition
| XIMStatusNothing
,
2275 XIMPreeditPosition
| XIMStatusNone
,
2276 XIMPreeditNothing
| XIMStatusArea
,
2277 XIMPreeditNothing
| XIMStatusNothing
,
2278 XIMPreeditNothing
| XIMStatusNone
,
2279 XIMPreeditNone
| XIMStatusArea
,
2280 XIMPreeditNone
| XIMStatusNothing
,
2281 XIMPreeditNone
| XIMStatusNone
,
2286 /* Create an X fontset on frame F with base font name
2290 xic_create_xfontset (f
, base_fontname
)
2292 char *base_fontname
;
2295 char **missing_list
;
2299 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
),
2300 base_fontname
, &missing_list
,
2301 &missing_count
, &def_string
);
2303 XFreeStringList (missing_list
);
2305 /* No need to free def_string. */
2310 /* Value is the best input style, given user preferences USER (already
2311 checked to be supported by Emacs), and styles supported by the
2312 input method XIM. */
2315 best_xim_style (user
, xim
)
2321 for (i
= 0; i
< user
->count_styles
; ++i
)
2322 for (j
= 0; j
< xim
->count_styles
; ++j
)
2323 if (user
->supported_styles
[i
] == xim
->supported_styles
[j
])
2324 return user
->supported_styles
[i
];
2326 /* Return the default style. */
2327 return XIMPreeditNothing
| XIMStatusNothing
;
2330 /* Create XIC for frame F. */
2332 static XIMStyle xic_style
;
2335 create_frame_xic (f
)
2340 XFontSet xfs
= NULL
;
2345 xim
= FRAME_X_XIM (f
);
2350 XVaNestedList preedit_attr
;
2351 XVaNestedList status_attr
;
2352 char *base_fontname
;
2355 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2356 spot
.x
= 0; spot
.y
= 1;
2357 /* Create X fontset. */
2358 fontset
= FRAME_FONTSET (f
);
2360 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2363 /* Determine the base fontname from the ASCII font name of
2365 char *ascii_font
= (char *) SDATA (fontset_ascii (fontset
));
2366 char *p
= ascii_font
;
2369 for (i
= 0; *p
; p
++)
2372 /* As the font name doesn't conform to XLFD, we can't
2373 modify it to get a suitable base fontname for the
2375 base_fontname
= "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2378 int len
= strlen (ascii_font
) + 1;
2381 for (i
= 0, p
= ascii_font
; i
< 8; p
++)
2390 base_fontname
= (char *) alloca (len
);
2391 bzero (base_fontname
, len
);
2392 strcpy (base_fontname
, "-*-*-");
2393 bcopy (p1
, base_fontname
+ 5, p
- p1
);
2394 strcat (base_fontname
, "*-*-*-*-*-*-*");
2397 xfs
= xic_create_xfontset (f
, base_fontname
);
2399 /* Determine XIC style. */
2402 XIMStyles supported_list
;
2403 supported_list
.count_styles
= (sizeof supported_xim_styles
2404 / sizeof supported_xim_styles
[0]);
2405 supported_list
.supported_styles
= supported_xim_styles
;
2406 xic_style
= best_xim_style (&supported_list
,
2407 FRAME_X_XIM_STYLES (f
));
2410 preedit_attr
= XVaCreateNestedList (0,
2413 FRAME_FOREGROUND_PIXEL (f
),
2415 FRAME_BACKGROUND_PIXEL (f
),
2416 (xic_style
& XIMPreeditPosition
2421 status_attr
= XVaCreateNestedList (0,
2427 FRAME_FOREGROUND_PIXEL (f
),
2429 FRAME_BACKGROUND_PIXEL (f
),
2432 xic
= XCreateIC (xim
,
2433 XNInputStyle
, xic_style
,
2434 XNClientWindow
, FRAME_X_WINDOW(f
),
2435 XNFocusWindow
, FRAME_X_WINDOW(f
),
2436 XNStatusAttributes
, status_attr
,
2437 XNPreeditAttributes
, preedit_attr
,
2439 XFree (preedit_attr
);
2440 XFree (status_attr
);
2443 FRAME_XIC (f
) = xic
;
2444 FRAME_XIC_STYLE (f
) = xic_style
;
2445 FRAME_XIC_FONTSET (f
) = xfs
;
2449 /* Destroy XIC and free XIC fontset of frame F, if any. */
2455 if (FRAME_XIC (f
) == NULL
)
2458 XDestroyIC (FRAME_XIC (f
));
2459 if (FRAME_XIC_FONTSET (f
))
2460 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2462 FRAME_XIC (f
) = NULL
;
2463 FRAME_XIC_FONTSET (f
) = NULL
;
2467 /* Place preedit area for XIC of window W's frame to specified
2468 pixel position X/Y. X and Y are relative to window W. */
2471 xic_set_preeditarea (w
, x
, y
)
2475 struct frame
*f
= XFRAME (w
->frame
);
2479 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2480 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2481 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2482 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2487 /* Place status area for XIC in bottom right corner of frame F.. */
2490 xic_set_statusarea (f
)
2493 XIC xic
= FRAME_XIC (f
);
2498 /* Negotiate geometry of status area. If input method has existing
2499 status area, use its current size. */
2500 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2501 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2502 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2505 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2506 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2509 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2511 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2512 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2516 area
.width
= needed
->width
;
2517 area
.height
= needed
->height
;
2518 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2519 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2520 - FRAME_MENUBAR_HEIGHT (f
)
2521 - FRAME_TOOLBAR_HEIGHT (f
)
2522 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2525 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2526 XSetICValues(xic
, XNStatusAttributes
, attr
, NULL
);
2531 /* Set X fontset for XIC of frame F, using base font name
2532 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2535 xic_set_xfontset (f
, base_fontname
)
2537 char *base_fontname
;
2542 xfs
= xic_create_xfontset (f
, base_fontname
);
2544 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2545 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2546 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2547 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2548 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2551 if (FRAME_XIC_FONTSET (f
))
2552 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2553 FRAME_XIC_FONTSET (f
) = xfs
;
2556 #endif /* HAVE_X_I18N */
2560 #ifdef USE_X_TOOLKIT
2562 /* Create and set up the X widget for frame F. */
2565 x_window (f
, window_prompting
, minibuffer_only
)
2567 long window_prompting
;
2568 int minibuffer_only
;
2570 XClassHint class_hints
;
2571 XSetWindowAttributes attributes
;
2572 unsigned long attribute_mask
;
2573 Widget shell_widget
;
2575 Widget frame_widget
;
2581 /* Use the resource name as the top-level widget name
2582 for looking up resources. Make a non-Lisp copy
2583 for the window manager, so GC relocation won't bother it.
2585 Elsewhere we specify the window name for the window manager. */
2588 char *str
= (char *) SDATA (Vx_resource_name
);
2589 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2590 strcpy (f
->namebuf
, str
);
2594 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2595 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2596 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2597 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2598 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2599 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2600 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2601 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2602 applicationShellWidgetClass
,
2603 FRAME_X_DISPLAY (f
), al
, ac
);
2605 f
->output_data
.x
->widget
= shell_widget
;
2606 /* maybe_set_screen_title_format (shell_widget); */
2608 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2609 (widget_value
*) NULL
,
2610 shell_widget
, False
,
2614 (lw_callback
) NULL
);
2617 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2618 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2619 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2620 XtSetValues (pane_widget
, al
, ac
);
2621 f
->output_data
.x
->column_widget
= pane_widget
;
2623 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2624 the emacs screen when changing menubar. This reduces flickering. */
2627 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2628 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2629 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2630 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2631 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2632 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2633 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2634 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2635 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2638 f
->output_data
.x
->edit_widget
= frame_widget
;
2640 XtManageChild (frame_widget
);
2642 /* Do some needed geometry management. */
2645 char *tem
, shell_position
[32];
2648 int extra_borders
= 0;
2650 = (f
->output_data
.x
->menubar_widget
2651 ? (f
->output_data
.x
->menubar_widget
->core
.height
2652 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2655 #if 0 /* Experimentally, we now get the right results
2656 for -geometry -0-0 without this. 24 Aug 96, rms. */
2657 if (FRAME_EXTERNAL_MENU_BAR (f
))
2660 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2661 menubar_size
+= ibw
;
2665 f
->output_data
.x
->menubar_height
= menubar_size
;
2668 /* Motif seems to need this amount added to the sizes
2669 specified for the shell widget. The Athena/Lucid widgets don't.
2670 Both conclusions reached experimentally. -- rms. */
2671 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2672 &extra_borders
, NULL
);
2676 /* Convert our geometry parameters into a geometry string
2678 Note that we do not specify here whether the position
2679 is a user-specified or program-specified one.
2680 We pass that information later, in x_wm_set_size_hints. */
2682 int left
= f
->left_pos
;
2683 int xneg
= window_prompting
& XNegative
;
2684 int top
= f
->top_pos
;
2685 int yneg
= window_prompting
& YNegative
;
2691 if (window_prompting
& USPosition
)
2692 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2693 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2694 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2695 (xneg
? '-' : '+'), left
,
2696 (yneg
? '-' : '+'), top
);
2698 sprintf (shell_position
, "=%dx%d",
2699 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2700 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2703 len
= strlen (shell_position
) + 1;
2704 /* We don't free this because we don't know whether
2705 it is safe to free it while the frame exists.
2706 It isn't worth the trouble of arranging to free it
2707 when the frame is deleted. */
2708 tem
= (char *) xmalloc (len
);
2709 strncpy (tem
, shell_position
, len
);
2710 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2711 XtSetValues (shell_widget
, al
, ac
);
2714 XtManageChild (pane_widget
);
2715 XtRealizeWidget (shell_widget
);
2717 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2719 validate_x_resource_name ();
2721 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2722 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2723 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2726 FRAME_XIC (f
) = NULL
;
2728 create_frame_xic (f
);
2731 f
->output_data
.x
->wm_hints
.input
= True
;
2732 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2733 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2734 &f
->output_data
.x
->wm_hints
);
2736 hack_wm_protocols (f
, shell_widget
);
2739 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2742 /* Do a stupid property change to force the server to generate a
2743 PropertyNotify event so that the event_stream server timestamp will
2744 be initialized to something relevant to the time we created the window.
2746 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2747 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2748 XA_ATOM
, 32, PropModeAppend
,
2749 (unsigned char*) NULL
, 0);
2751 /* Make all the standard events reach the Emacs frame. */
2752 attributes
.event_mask
= STANDARD_EVENT_SET
;
2757 /* XIM server might require some X events. */
2758 unsigned long fevent
= NoEventMask
;
2759 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2760 attributes
.event_mask
|= fevent
;
2762 #endif /* HAVE_X_I18N */
2764 attribute_mask
= CWEventMask
;
2765 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2766 attribute_mask
, &attributes
);
2768 XtMapWidget (frame_widget
);
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 /* This is a no-op, except under Motif. Make sure main areas are
2790 set to something reasonable, in case we get an error later. */
2791 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2794 #else /* not USE_X_TOOLKIT */
2800 if (! xg_create_frame_widgets (f
))
2801 error ("Unable to create window");
2804 FRAME_XIC (f
) = NULL
;
2808 create_frame_xic (f
);
2811 /* XIM server might require some X events. */
2812 unsigned long fevent
= NoEventMask
;
2813 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2815 if (fevent
!= NoEventMask
)
2817 XSetWindowAttributes attributes
;
2818 XWindowAttributes wattr
;
2819 unsigned long attribute_mask
;
2821 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2823 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2824 attribute_mask
= CWEventMask
;
2825 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2826 attribute_mask
, &attributes
);
2834 #else /*! USE_GTK */
2835 /* Create and set up the X window for frame F. */
2842 XClassHint class_hints
;
2843 XSetWindowAttributes attributes
;
2844 unsigned long attribute_mask
;
2846 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2847 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2848 attributes
.bit_gravity
= StaticGravity
;
2849 attributes
.backing_store
= NotUseful
;
2850 attributes
.save_under
= True
;
2851 attributes
.event_mask
= STANDARD_EVENT_SET
;
2852 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2853 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2858 = XCreateWindow (FRAME_X_DISPLAY (f
),
2859 f
->output_data
.x
->parent_desc
,
2862 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2864 CopyFromParent
, /* depth */
2865 InputOutput
, /* class */
2867 attribute_mask
, &attributes
);
2872 create_frame_xic (f
);
2875 /* XIM server might require some X events. */
2876 unsigned long fevent
= NoEventMask
;
2877 XGetICValues(FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2878 attributes
.event_mask
|= fevent
;
2879 attribute_mask
= CWEventMask
;
2880 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2881 attribute_mask
, &attributes
);
2884 #endif /* HAVE_X_I18N */
2886 validate_x_resource_name ();
2888 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2889 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2890 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2892 /* The menubar is part of the ordinary display;
2893 it does not count in addition to the height of the window. */
2894 f
->output_data
.x
->menubar_height
= 0;
2896 /* This indicates that we use the "Passive Input" input model.
2897 Unless we do this, we don't get the Focus{In,Out} events that we
2898 need to draw the cursor correctly. Accursed bureaucrats.
2899 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2901 f
->output_data
.x
->wm_hints
.input
= True
;
2902 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2903 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2904 &f
->output_data
.x
->wm_hints
);
2905 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2907 /* Request "save yourself" and "delete window" commands from wm. */
2910 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2911 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2912 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2915 /* x_set_name normally ignores requests to set the name if the
2916 requested name is the same as the current name. This is the one
2917 place where that assumption isn't correct; f->name is set, but
2918 the X server hasn't been told. */
2921 int explicit = f
->explicit_name
;
2923 f
->explicit_name
= 0;
2926 x_set_name (f
, name
, explicit);
2929 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2930 f
->output_data
.x
->text_cursor
);
2934 if (FRAME_X_WINDOW (f
) == 0)
2935 error ("Unable to create window");
2938 #endif /* not USE_GTK */
2939 #endif /* not USE_X_TOOLKIT */
2941 /* Handle the icon stuff for this window. Perhaps later we might
2942 want an x_set_icon_position which can be called interactively as
2950 Lisp_Object icon_x
, icon_y
;
2951 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2953 /* Set the position of the icon. Note that twm groups all
2954 icons in an icon window. */
2955 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2956 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2957 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2959 CHECK_NUMBER (icon_x
);
2960 CHECK_NUMBER (icon_y
);
2962 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2963 error ("Both left and top icon corners of icon must be specified");
2967 if (! EQ (icon_x
, Qunbound
))
2968 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2970 /* Start up iconic or window? */
2971 x_wm_set_window_state
2972 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
2977 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
2984 /* Make the GCs needed for this window, setting the
2985 background, border and mouse colors; also create the
2986 mouse cursor and the gray border tile. */
2988 static char cursor_bits
[] =
2990 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2992 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2993 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3000 XGCValues gc_values
;
3004 /* Create the GCs of this frame.
3005 Note that many default values are used. */
3008 gc_values
.font
= FRAME_FONT (f
)->fid
;
3009 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
3010 gc_values
.background
= f
->output_data
.x
->background_pixel
;
3011 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
3012 f
->output_data
.x
->normal_gc
3013 = XCreateGC (FRAME_X_DISPLAY (f
),
3015 GCLineWidth
| GCFont
| GCForeground
| GCBackground
,
3018 /* Reverse video style. */
3019 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3020 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
3021 f
->output_data
.x
->reverse_gc
3022 = XCreateGC (FRAME_X_DISPLAY (f
),
3024 GCFont
| GCForeground
| GCBackground
| GCLineWidth
,
3027 /* Cursor has cursor-color background, background-color foreground. */
3028 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3029 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
3030 gc_values
.fill_style
= FillOpaqueStippled
;
3032 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
3033 FRAME_X_DISPLAY_INFO (f
)->root_window
,
3034 cursor_bits
, 16, 16);
3035 f
->output_data
.x
->cursor_gc
3036 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3037 (GCFont
| GCForeground
| GCBackground
3038 | GCFillStyle
/* | GCStipple */ | GCLineWidth
),
3042 f
->output_data
.x
->white_relief
.gc
= 0;
3043 f
->output_data
.x
->black_relief
.gc
= 0;
3045 /* Create the gray border tile used when the pointer is not in
3046 the frame. Since this depends on the frame's pixel values,
3047 this must be done on a per-frame basis. */
3048 f
->output_data
.x
->border_tile
3049 = (XCreatePixmapFromBitmapData
3050 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
3051 gray_bits
, gray_width
, gray_height
,
3052 f
->output_data
.x
->foreground_pixel
,
3053 f
->output_data
.x
->background_pixel
,
3054 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
3060 /* Free what was was allocated in x_make_gc. */
3066 Display
*dpy
= FRAME_X_DISPLAY (f
);
3070 if (f
->output_data
.x
->normal_gc
)
3072 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
3073 f
->output_data
.x
->normal_gc
= 0;
3076 if (f
->output_data
.x
->reverse_gc
)
3078 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
3079 f
->output_data
.x
->reverse_gc
= 0;
3082 if (f
->output_data
.x
->cursor_gc
)
3084 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
3085 f
->output_data
.x
->cursor_gc
= 0;
3088 if (f
->output_data
.x
->border_tile
)
3090 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
3091 f
->output_data
.x
->border_tile
= 0;
3098 /* Handler for signals raised during x_create_frame and
3099 x_create_top_frame. FRAME is the frame which is partially
3103 unwind_create_frame (frame
)
3106 struct frame
*f
= XFRAME (frame
);
3108 /* If frame is ``official'', nothing to do. */
3109 if (!CONSP (Vframe_list
) || !EQ (XCAR (Vframe_list
), frame
))
3112 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3115 x_free_frame_resources (f
);
3117 /* Check that reference counts are indeed correct. */
3118 xassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
3119 xassert (dpyinfo
->image_cache
->refcount
== image_cache_refcount
);
3127 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3129 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
3130 Returns an Emacs frame object.
3131 ALIST is an alist of frame parameters.
3132 If the parameters specify that the frame should not have a minibuffer,
3133 and do not specify a specific minibuffer window to use,
3134 then `default-minibuffer-frame' must be a frame whose minibuffer can
3135 be shared by the new frame.
3137 This function is an internal primitive--use `make-frame' instead. */)
3142 Lisp_Object frame
, tem
;
3144 int minibuffer_only
= 0;
3145 long window_prompting
= 0;
3147 int count
= SPECPDL_INDEX ();
3148 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3149 Lisp_Object display
;
3150 struct x_display_info
*dpyinfo
= NULL
;
3156 /* Use this general default value to start with
3157 until we know if this frame has a specified name. */
3158 Vx_resource_name
= Vinvocation_name
;
3160 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3161 if (EQ (display
, Qunbound
))
3163 dpyinfo
= check_x_display_info (display
);
3165 kb
= dpyinfo
->kboard
;
3167 kb
= &the_only_kboard
;
3170 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3172 && ! EQ (name
, Qunbound
)
3174 error ("Invalid frame name--not a string or nil");
3177 Vx_resource_name
= name
;
3179 /* See if parent window is specified. */
3180 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3181 if (EQ (parent
, Qunbound
))
3183 if (! NILP (parent
))
3184 CHECK_NUMBER (parent
);
3186 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3187 /* No need to protect DISPLAY because that's not used after passing
3188 it to make_frame_without_minibuffer. */
3190 GCPRO4 (parms
, parent
, name
, frame
);
3191 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3193 if (EQ (tem
, Qnone
) || NILP (tem
))
3194 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3195 else if (EQ (tem
, Qonly
))
3197 f
= make_minibuffer_frame ();
3198 minibuffer_only
= 1;
3200 else if (WINDOWP (tem
))
3201 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3205 XSETFRAME (frame
, f
);
3207 /* Note that X Windows does support scroll bars. */
3208 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3210 f
->output_method
= output_x_window
;
3211 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3212 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3213 f
->output_data
.x
->icon_bitmap
= -1;
3214 FRAME_FONTSET (f
) = -1;
3215 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3216 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3217 #ifdef USE_TOOLKIT_SCROLL_BARS
3218 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3219 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3220 #endif /* USE_TOOLKIT_SCROLL_BARS */
3221 record_unwind_protect (unwind_create_frame
, frame
);
3224 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3226 if (! STRINGP (f
->icon_name
))
3227 f
->icon_name
= Qnil
;
3229 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3231 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
3232 dpyinfo_refcount
= dpyinfo
->reference_count
;
3233 #endif /* GLYPH_DEBUG */
3235 FRAME_KBOARD (f
) = kb
;
3238 /* These colors will be set anyway later, but it's important
3239 to get the color reference counts right, so initialize them! */
3242 struct gcpro gcpro1
;
3244 /* Function x_decode_color can signal an error. Make
3245 sure to initialize color slots so that we won't try
3246 to free colors we haven't allocated. */
3247 f
->output_data
.x
->foreground_pixel
= -1;
3248 f
->output_data
.x
->background_pixel
= -1;
3249 f
->output_data
.x
->cursor_pixel
= -1;
3250 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3251 f
->output_data
.x
->border_pixel
= -1;
3252 f
->output_data
.x
->mouse_pixel
= -1;
3254 black
= build_string ("black");
3256 f
->output_data
.x
->foreground_pixel
3257 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3258 f
->output_data
.x
->background_pixel
3259 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3260 f
->output_data
.x
->cursor_pixel
3261 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3262 f
->output_data
.x
->cursor_foreground_pixel
3263 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3264 f
->output_data
.x
->border_pixel
3265 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3266 f
->output_data
.x
->mouse_pixel
3267 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3271 /* Specify the parent under which to make this X window. */
3275 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3276 f
->output_data
.x
->explicit_parent
= 1;
3280 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3281 f
->output_data
.x
->explicit_parent
= 0;
3284 /* Set the name; the functions to which we pass f expect the name to
3286 if (EQ (name
, Qunbound
) || NILP (name
))
3288 f
->name
= build_string (dpyinfo
->x_id_name
);
3289 f
->explicit_name
= 0;
3294 f
->explicit_name
= 1;
3295 /* use the frame's title when getting resources for this frame. */
3296 specbind (Qx_resource_name
, name
);
3299 /* Extract the window parameters from the supplied values
3300 that are needed to determine window geometry. */
3304 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3306 /* If the caller has specified no font, try out fonts which we
3307 hope have bold and italic variations. */
3308 if (!STRINGP (font
))
3311 = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3312 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3313 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3314 /* This was formerly the first thing tried, but it finds
3315 too many fonts and takes too long. */
3316 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3317 /* If those didn't work, look for something which will
3319 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3324 for (i
= 0; names
[i
]; i
++)
3328 list
= x_list_fonts (f
, build_string (names
[i
]), 0, 1);
3336 if (! STRINGP (font
))
3337 font
= build_string ("fixed");
3339 x_default_parameter (f
, parms
, Qfont
, font
,
3340 "font", "Font", RES_TYPE_STRING
);
3344 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3345 whereby it fails to get any font. */
3346 xlwmenu_default_font
= FRAME_FONT (f
);
3349 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3350 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3352 /* This defaults to 1 in order to match xterm. We recognize either
3353 internalBorderWidth or internalBorder (which is what xterm calls
3355 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3359 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3360 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3361 if (! EQ (value
, Qunbound
))
3362 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3365 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3366 "internalBorderWidth", "internalBorderWidth",
3368 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3369 "verticalScrollBars", "ScrollBars",
3372 /* Also do the stuff which must be set before the window exists. */
3373 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3374 "foreground", "Foreground", RES_TYPE_STRING
);
3375 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3376 "background", "Background", RES_TYPE_STRING
);
3377 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3378 "pointerColor", "Foreground", RES_TYPE_STRING
);
3379 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3380 "cursorColor", "Foreground", RES_TYPE_STRING
);
3381 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3382 "borderColor", "BorderColor", RES_TYPE_STRING
);
3383 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3384 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3385 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3386 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3387 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3388 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3389 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3390 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3392 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3393 "scrollBarForeground",
3394 "ScrollBarForeground", 1);
3395 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3396 "scrollBarBackground",
3397 "ScrollBarBackground", 0);
3399 /* Init faces before x_default_parameter is called for scroll-bar
3400 parameters because that function calls x_set_scroll_bar_width,
3401 which calls change_frame_size, which calls Fset_window_buffer,
3402 which runs hooks, which call Fvertical_motion. At the end, we
3403 end up in init_iterator with a null face cache, which should not
3405 init_frame_faces (f
);
3407 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3408 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
3409 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (1),
3410 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
3411 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3412 "bufferPredicate", "BufferPredicate",
3414 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3415 "title", "Title", RES_TYPE_STRING
);
3416 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3417 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3418 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3419 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3421 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3423 /* Compute the size of the X window. */
3424 window_prompting
= x_figure_window_size (f
, parms
, 1);
3426 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3427 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3429 /* Create the X widget or window. */
3430 #ifdef USE_X_TOOLKIT
3431 x_window (f
, window_prompting
, minibuffer_only
);
3439 /* Now consider the frame official. */
3440 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3441 Vframe_list
= Fcons (frame
, Vframe_list
);
3443 /* We need to do this after creating the X window, so that the
3444 icon-creation functions can say whose icon they're describing. */
3445 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3446 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
3448 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3449 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3450 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3451 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3452 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3453 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3454 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3455 "scrollBarWidth", "ScrollBarWidth",
3458 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3459 Change will not be effected unless different from the current
3461 width
= FRAME_COLS (f
);
3462 height
= FRAME_LINES (f
);
3464 SET_FRAME_COLS (f
, 0);
3465 FRAME_LINES (f
) = 0;
3466 change_frame_size (f
, height
, width
, 1, 0, 0);
3468 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3469 /* Create the menu bar. */
3470 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3472 /* If this signals an error, we haven't set size hints for the
3473 frame and we didn't make it visible. */
3474 initialize_frame_menubar (f
);
3477 /* This is a no-op, except under Motif where it arranges the
3478 main window for the widgets on it. */
3479 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3480 f
->output_data
.x
->menubar_widget
,
3481 f
->output_data
.x
->edit_widget
);
3482 #endif /* not USE_GTK */
3484 #endif /* USE_X_TOOLKIT || USE_GTK */
3486 /* Tell the server what size and position, etc, we want, and how
3487 badly we want them. This should be done after we have the menu
3488 bar so that its size can be taken into account. */
3490 x_wm_set_size_hint (f
, window_prompting
, 0);
3493 /* Make the window appear on the frame and enable display, unless
3494 the caller says not to. However, with explicit parent, Emacs
3495 cannot control visibility, so don't try. */
3496 if (! f
->output_data
.x
->explicit_parent
)
3498 Lisp_Object visibility
;
3500 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3502 if (EQ (visibility
, Qunbound
))
3505 if (EQ (visibility
, Qicon
))
3506 x_iconify_frame (f
);
3507 else if (! NILP (visibility
))
3508 x_make_frame_visible (f
);
3510 /* Must have been Qnil. */
3516 /* Make sure windows on this frame appear in calls to next-window
3517 and similar functions. */
3518 Vwindow_list
= Qnil
;
3520 return unbind_to (count
, frame
);
3524 /* FRAME is used only to get a handle on the X display. We don't pass the
3525 display info directly because we're called from frame.c, which doesn't
3526 know about that structure. */
3529 x_get_focus_frame (frame
)
3530 struct frame
*frame
;
3532 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3534 if (! dpyinfo
->x_focus_frame
)
3537 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3542 /* In certain situations, when the window manager follows a
3543 click-to-focus policy, there seems to be no way around calling
3544 XSetInputFocus to give another frame the input focus .
3546 In an ideal world, XSetInputFocus should generally be avoided so
3547 that applications don't interfere with the window manager's focus
3548 policy. But I think it's okay to use when it's clearly done
3549 following a user-command. */
3551 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 1, 0,
3552 doc
: /* Set the input focus to FRAME.
3553 FRAME nil means use the selected frame. */)
3557 struct frame
*f
= check_x_frame (frame
);
3558 Display
*dpy
= FRAME_X_DISPLAY (f
);
3562 count
= x_catch_errors (dpy
);
3563 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3564 RevertToParent
, CurrentTime
);
3565 x_uncatch_errors (dpy
, count
);
3572 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3573 doc
: /* Internal function called by `color-defined-p', which see. */)
3575 Lisp_Object color
, frame
;
3578 FRAME_PTR f
= check_x_frame (frame
);
3580 CHECK_STRING (color
);
3582 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3588 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3589 doc
: /* Internal function called by `color-values', which see. */)
3591 Lisp_Object color
, frame
;
3594 FRAME_PTR f
= check_x_frame (frame
);
3596 CHECK_STRING (color
);
3598 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3602 rgb
[0] = make_number (foo
.red
);
3603 rgb
[1] = make_number (foo
.green
);
3604 rgb
[2] = make_number (foo
.blue
);
3605 return Flist (3, rgb
);
3611 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3612 doc
: /* Internal function called by `display-color-p', which see. */)
3614 Lisp_Object display
;
3616 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3618 if (dpyinfo
->n_planes
<= 2)
3621 switch (dpyinfo
->visual
->class)
3634 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3636 doc
: /* Return t if the X display supports shades of gray.
3637 Note that color displays do support shades of gray.
3638 The optional argument DISPLAY specifies which display to ask about.
3639 DISPLAY should be either a frame or a display name (a string).
3640 If omitted or nil, that stands for the selected frame's display. */)
3642 Lisp_Object display
;
3644 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3646 if (dpyinfo
->n_planes
<= 1)
3649 switch (dpyinfo
->visual
->class)
3664 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3666 doc
: /* Returns the width in pixels of the X display DISPLAY.
3667 The optional argument DISPLAY specifies which display to ask about.
3668 DISPLAY should be either a frame or a display name (a string).
3669 If omitted or nil, that stands for the selected frame's display. */)
3671 Lisp_Object display
;
3673 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3675 return make_number (dpyinfo
->width
);
3678 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3679 Sx_display_pixel_height
, 0, 1, 0,
3680 doc
: /* Returns the height in pixels of the X display DISPLAY.
3681 The optional argument DISPLAY specifies which display to ask about.
3682 DISPLAY should be either a frame or a display name (a string).
3683 If omitted or nil, that stands for the selected frame's display. */)
3685 Lisp_Object display
;
3687 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3689 return make_number (dpyinfo
->height
);
3692 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3694 doc
: /* Returns the number of bitplanes of the X display DISPLAY.
3695 The optional argument DISPLAY specifies which display to ask about.
3696 DISPLAY should be either a frame or a display name (a string).
3697 If omitted or nil, that stands for the selected frame's display. */)
3699 Lisp_Object display
;
3701 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3703 return make_number (dpyinfo
->n_planes
);
3706 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3708 doc
: /* Returns the number of color cells of the X display DISPLAY.
3709 The optional argument DISPLAY specifies which display to ask about.
3710 DISPLAY should be either a frame or a display name (a string).
3711 If omitted or nil, that stands for the selected frame's display. */)
3713 Lisp_Object display
;
3715 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3717 return make_number (DisplayCells (dpyinfo
->display
,
3718 XScreenNumberOfScreen (dpyinfo
->screen
)));
3721 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3722 Sx_server_max_request_size
,
3724 doc
: /* Returns the maximum request size of the X server of display DISPLAY.
3725 The optional argument DISPLAY specifies which display to ask about.
3726 DISPLAY should be either a frame or a display name (a string).
3727 If omitted or nil, that stands for the selected frame's display. */)
3729 Lisp_Object display
;
3731 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3733 return make_number (MAXREQUEST (dpyinfo
->display
));
3736 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3737 doc
: /* Returns the vendor ID string of the X server of display DISPLAY.
3738 The optional argument DISPLAY specifies which display to ask about.
3739 DISPLAY should be either a frame or a display name (a string).
3740 If omitted or nil, that stands for the selected frame's display. */)
3742 Lisp_Object display
;
3744 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3745 char *vendor
= ServerVendor (dpyinfo
->display
);
3747 if (! vendor
) vendor
= "";
3748 return build_string (vendor
);
3751 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3752 doc
: /* Returns the version numbers of the X server of display DISPLAY.
3753 The value is a list of three integers: the major and minor
3754 version numbers of the X Protocol in use, and the vendor-specific release
3755 number. See also the function `x-server-vendor'.
3757 The optional argument DISPLAY specifies which display to ask about.
3758 DISPLAY should be either a frame or a display name (a string).
3759 If omitted or nil, that stands for the selected frame's display. */)
3761 Lisp_Object display
;
3763 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3764 Display
*dpy
= dpyinfo
->display
;
3766 return Fcons (make_number (ProtocolVersion (dpy
)),
3767 Fcons (make_number (ProtocolRevision (dpy
)),
3768 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3771 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3772 doc
: /* Return the number of screens on the X server of display DISPLAY.
3773 The optional argument DISPLAY specifies which display to ask about.
3774 DISPLAY should be either a frame or a display name (a string).
3775 If omitted or nil, that stands for the selected frame's display. */)
3777 Lisp_Object display
;
3779 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3781 return make_number (ScreenCount (dpyinfo
->display
));
3784 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3785 doc
: /* Return the height in millimeters of the X display DISPLAY.
3786 The optional argument DISPLAY specifies which display to ask about.
3787 DISPLAY should be either a frame or a display name (a string).
3788 If omitted or nil, that stands for the selected frame's display. */)
3790 Lisp_Object display
;
3792 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3794 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3797 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3798 doc
: /* Return the width in millimeters of the X display DISPLAY.
3799 The optional argument DISPLAY specifies which display to ask about.
3800 DISPLAY should be either a frame or a display name (a string).
3801 If omitted or nil, that stands for the selected frame's display. */)
3803 Lisp_Object display
;
3805 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3807 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3810 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3811 Sx_display_backing_store
, 0, 1, 0,
3812 doc
: /* Returns an indication of whether X display DISPLAY does backing store.
3813 The value may be `always', `when-mapped', or `not-useful'.
3814 The optional argument DISPLAY specifies which display to ask about.
3815 DISPLAY should be either a frame or a display name (a string).
3816 If omitted or nil, that stands for the selected frame's display. */)
3818 Lisp_Object display
;
3820 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3823 switch (DoesBackingStore (dpyinfo
->screen
))
3826 result
= intern ("always");
3830 result
= intern ("when-mapped");
3834 result
= intern ("not-useful");
3838 error ("Strange value for BackingStore parameter of screen");
3845 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3846 Sx_display_visual_class
, 0, 1, 0,
3847 doc
: /* Return the visual class of the X display DISPLAY.
3848 The value is one of the symbols `static-gray', `gray-scale',
3849 `static-color', `pseudo-color', `true-color', or `direct-color'.
3851 The optional argument DISPLAY specifies which display to ask about.
3852 DISPLAY should be either a frame or a display name (a string).
3853 If omitted or nil, that stands for the selected frame's display. */)
3855 Lisp_Object display
;
3857 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3860 switch (dpyinfo
->visual
->class)
3863 result
= intern ("static-gray");
3866 result
= intern ("gray-scale");
3869 result
= intern ("static-color");
3872 result
= intern ("pseudo-color");
3875 result
= intern ("true-color");
3878 result
= intern ("direct-color");
3881 error ("Display has an unknown visual class");
3888 DEFUN ("x-display-save-under", Fx_display_save_under
,
3889 Sx_display_save_under
, 0, 1, 0,
3890 doc
: /* Returns t if the X display DISPLAY supports the save-under feature.
3891 The optional argument DISPLAY specifies which display to ask about.
3892 DISPLAY should be either a frame or a display name (a string).
3893 If omitted or nil, that stands for the selected frame's display. */)
3895 Lisp_Object display
;
3897 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3899 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3907 register struct frame
*f
;
3909 return FRAME_PIXEL_WIDTH (f
);
3914 register struct frame
*f
;
3916 return FRAME_PIXEL_HEIGHT (f
);
3921 register struct frame
*f
;
3923 return FRAME_COLUMN_WIDTH (f
);
3928 register struct frame
*f
;
3930 return FRAME_LINE_HEIGHT (f
);
3935 register struct frame
*f
;
3937 return FRAME_X_DISPLAY_INFO (f
)->n_planes
;
3942 /************************************************************************
3944 ************************************************************************/
3947 /* Mapping visual names to visuals. */
3949 static struct visual_class
3956 {"StaticGray", StaticGray
},
3957 {"GrayScale", GrayScale
},
3958 {"StaticColor", StaticColor
},
3959 {"PseudoColor", PseudoColor
},
3960 {"TrueColor", TrueColor
},
3961 {"DirectColor", DirectColor
},
3966 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3968 /* Value is the screen number of screen SCR. This is a substitute for
3969 the X function with the same name when that doesn't exist. */
3972 XScreenNumberOfScreen (scr
)
3973 register Screen
*scr
;
3975 Display
*dpy
= scr
->display
;
3978 for (i
= 0; i
< dpy
->nscreens
; ++i
)
3979 if (scr
== dpy
->screens
+ i
)
3985 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3988 /* Select the visual that should be used on display DPYINFO. Set
3989 members of DPYINFO appropriately. Called from x_term_init. */
3992 select_visual (dpyinfo
)
3993 struct x_display_info
*dpyinfo
;
3995 Display
*dpy
= dpyinfo
->display
;
3996 Screen
*screen
= dpyinfo
->screen
;
3999 /* See if a visual is specified. */
4000 value
= display_x_get_resource (dpyinfo
,
4001 build_string ("visualClass"),
4002 build_string ("VisualClass"),
4004 if (STRINGP (value
))
4006 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4007 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4008 depth, a decimal number. NAME is compared with case ignored. */
4009 char *s
= (char *) alloca (SBYTES (value
) + 1);
4014 strcpy (s
, SDATA (value
));
4015 dash
= index (s
, '-');
4018 dpyinfo
->n_planes
= atoi (dash
+ 1);
4022 /* We won't find a matching visual with depth 0, so that
4023 an error will be printed below. */
4024 dpyinfo
->n_planes
= 0;
4026 /* Determine the visual class. */
4027 for (i
= 0; visual_classes
[i
].name
; ++i
)
4028 if (xstricmp (s
, visual_classes
[i
].name
) == 0)
4030 class = visual_classes
[i
].class;
4034 /* Look up a matching visual for the specified class. */
4036 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
4037 dpyinfo
->n_planes
, class, &vinfo
))
4038 fatal ("Invalid visual specification `%s'", SDATA (value
));
4040 dpyinfo
->visual
= vinfo
.visual
;
4045 XVisualInfo
*vinfo
, vinfo_template
;
4047 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4050 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4052 vinfo_template
.visualid
= dpyinfo
->visual
->visualid
;
4054 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4055 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4056 &vinfo_template
, &n_visuals
);
4058 fatal ("Can't get proper X visual info");
4060 dpyinfo
->n_planes
= vinfo
->depth
;
4061 XFree ((char *) vinfo
);
4066 /* Return the X display structure for the display named NAME.
4067 Open a new connection if necessary. */
4069 struct x_display_info
*
4070 x_display_info_for_name (name
)
4074 struct x_display_info
*dpyinfo
;
4076 CHECK_STRING (name
);
4078 if (! EQ (Vwindow_system
, intern ("x")))
4079 error ("Not using X Windows");
4081 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4083 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
4086 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
4091 /* Use this general default value to start with. */
4092 Vx_resource_name
= Vinvocation_name
;
4094 validate_x_resource_name ();
4096 dpyinfo
= x_term_init (name
, (char *)0,
4097 (char *) SDATA (Vx_resource_name
));
4100 error ("Cannot connect to X server %s", SDATA (name
));
4103 XSETFASTINT (Vwindow_system_version
, 11);
4109 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4111 doc
: /* Open a connection to an X server.
4112 DISPLAY is the name of the display to connect to.
4113 Optional second arg XRM-STRING is a string of resources in xrdb format.
4114 If the optional third arg MUST-SUCCEED is non-nil,
4115 terminate Emacs if we can't open the connection. */)
4116 (display
, xrm_string
, must_succeed
)
4117 Lisp_Object display
, xrm_string
, must_succeed
;
4119 unsigned char *xrm_option
;
4120 struct x_display_info
*dpyinfo
;
4122 CHECK_STRING (display
);
4123 if (! NILP (xrm_string
))
4124 CHECK_STRING (xrm_string
);
4126 if (! EQ (Vwindow_system
, intern ("x")))
4127 error ("Not using X Windows");
4129 if (! NILP (xrm_string
))
4130 xrm_option
= (unsigned char *) SDATA (xrm_string
);
4132 xrm_option
= (unsigned char *) 0;
4134 validate_x_resource_name ();
4136 /* This is what opens the connection and sets x_current_display.
4137 This also initializes many symbols, such as those used for input. */
4138 dpyinfo
= x_term_init (display
, xrm_option
,
4139 (char *) SDATA (Vx_resource_name
));
4143 if (!NILP (must_succeed
))
4144 fatal ("Cannot connect to X server %s.\n\
4145 Check the DISPLAY environment variable or use `-d'.\n\
4146 Also use the `xauth' program to verify that you have the proper\n\
4147 authorization information needed to connect the X server.\n\
4148 An insecure way to solve the problem may be to use `xhost'.\n",
4151 error ("Cannot connect to X server %s", SDATA (display
));
4156 XSETFASTINT (Vwindow_system_version
, 11);
4160 DEFUN ("x-close-connection", Fx_close_connection
,
4161 Sx_close_connection
, 1, 1, 0,
4162 doc
: /* Close the connection to DISPLAY's X server.
4163 For DISPLAY, specify either a frame or a display name (a string).
4164 If DISPLAY is nil, that stands for the selected frame's display. */)
4166 Lisp_Object display
;
4168 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4171 if (dpyinfo
->reference_count
> 0)
4172 error ("Display still has frames on it");
4175 /* Free the fonts in the font table. */
4176 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4177 if (dpyinfo
->font_table
[i
].name
)
4179 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
4180 xfree (dpyinfo
->font_table
[i
].full_name
);
4181 xfree (dpyinfo
->font_table
[i
].name
);
4182 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4185 x_destroy_all_bitmaps (dpyinfo
);
4186 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4188 #ifdef USE_X_TOOLKIT
4189 XtCloseDisplay (dpyinfo
->display
);
4191 XCloseDisplay (dpyinfo
->display
);
4194 x_delete_display (dpyinfo
);
4200 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4201 doc
: /* Return the list of display names that Emacs has connections to. */)
4204 Lisp_Object tail
, result
;
4207 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCDR (tail
))
4208 result
= Fcons (XCAR (XCAR (tail
)), result
);
4213 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4214 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4215 If ON is nil, allow buffering of requests.
4216 Turning on synchronization prohibits the Xlib routines from buffering
4217 requests and seriously degrades performance, but makes debugging much
4219 The optional second argument DISPLAY specifies which display to act on.
4220 DISPLAY should be either a frame or a display name (a string).
4221 If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
4223 Lisp_Object display
, on
;
4225 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4227 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4232 /* Wait for responses to all X commands issued so far for frame F. */
4239 XSync (FRAME_X_DISPLAY (f
), False
);
4244 /***********************************************************************
4246 ***********************************************************************/
4248 /* Value is the number of elements of vector VECTOR. */
4250 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
4252 /* List of supported image types. Use define_image_type to add new
4253 types. Use lookup_image_type to find a type for a given symbol. */
4255 static struct image_type
*image_types
;
4257 /* The symbol `image' which is the car of the lists used to represent
4260 extern Lisp_Object Qimage
;
4262 /* The symbol `xbm' which is used as the type symbol for XBM images. */
4268 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
4269 extern Lisp_Object QCdata
, QCtype
;
4270 Lisp_Object QCascent
, QCmargin
, QCrelief
;
4271 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
4272 Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
;
4274 /* Other symbols. */
4276 Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
4278 /* Time in seconds after which images should be removed from the cache
4279 if not displayed. */
4281 Lisp_Object Vimage_cache_eviction_delay
;
4283 /* Function prototypes. */
4285 static void define_image_type
P_ ((struct image_type
*type
));
4286 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
4287 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
4288 static void x_laplace
P_ ((struct frame
*, struct image
*));
4289 static void x_emboss
P_ ((struct frame
*, struct image
*));
4290 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
4294 /* Define a new image type from TYPE. This adds a copy of TYPE to
4295 image_types and adds the symbol *TYPE->type to Vimage_types. */
4298 define_image_type (type
)
4299 struct image_type
*type
;
4301 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
4302 The initialized data segment is read-only. */
4303 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
4304 bcopy (type
, p
, sizeof *p
);
4305 p
->next
= image_types
;
4307 Vimage_types
= Fcons (*p
->type
, Vimage_types
);
4311 /* Look up image type SYMBOL, and return a pointer to its image_type
4312 structure. Value is null if SYMBOL is not a known image type. */
4314 static INLINE
struct image_type
*
4315 lookup_image_type (symbol
)
4318 struct image_type
*type
;
4320 for (type
= image_types
; type
; type
= type
->next
)
4321 if (EQ (symbol
, *type
->type
))
4328 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
4329 valid image specification is a list whose car is the symbol
4330 `image', and whose rest is a property list. The property list must
4331 contain a value for key `:type'. That value must be the name of a
4332 supported image type. The rest of the property list depends on the
4336 valid_image_p (object
)
4341 if (CONSP (object
) && EQ (XCAR (object
), Qimage
))
4345 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
4346 if (EQ (XCAR (tem
), QCtype
))
4349 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
4351 struct image_type
*type
;
4352 type
= lookup_image_type (XCAR (tem
));
4354 valid_p
= type
->valid_p (object
);
4365 /* Log error message with format string FORMAT and argument ARG.
4366 Signaling an error, e.g. when an image cannot be loaded, is not a
4367 good idea because this would interrupt redisplay, and the error
4368 message display would lead to another redisplay. This function
4369 therefore simply displays a message. */
4372 image_error (format
, arg1
, arg2
)
4374 Lisp_Object arg1
, arg2
;
4376 add_to_log (format
, arg1
, arg2
);
4381 /***********************************************************************
4382 Image specifications
4383 ***********************************************************************/
4385 enum image_value_type
4387 IMAGE_DONT_CHECK_VALUE_TYPE
,
4389 IMAGE_STRING_OR_NIL_VALUE
,
4391 IMAGE_POSITIVE_INTEGER_VALUE
,
4392 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
4393 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
4395 IMAGE_INTEGER_VALUE
,
4396 IMAGE_FUNCTION_VALUE
,
4401 /* Structure used when parsing image specifications. */
4403 struct image_keyword
4405 /* Name of keyword. */
4408 /* The type of value allowed. */
4409 enum image_value_type type
;
4411 /* Non-zero means key must be present. */
4414 /* Used to recognize duplicate keywords in a property list. */
4417 /* The value that was found. */
4422 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
4424 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
4427 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
4428 has the format (image KEYWORD VALUE ...). One of the keyword/
4429 value pairs must be `:type TYPE'. KEYWORDS is a vector of
4430 image_keywords structures of size NKEYWORDS describing other
4431 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
4434 parse_image_spec (spec
, keywords
, nkeywords
, type
)
4436 struct image_keyword
*keywords
;
4443 if (!CONSP (spec
) || !EQ (XCAR (spec
), Qimage
))
4446 plist
= XCDR (spec
);
4447 while (CONSP (plist
))
4449 Lisp_Object key
, value
;
4451 /* First element of a pair must be a symbol. */
4453 plist
= XCDR (plist
);
4457 /* There must follow a value. */
4460 value
= XCAR (plist
);
4461 plist
= XCDR (plist
);
4463 /* Find key in KEYWORDS. Error if not found. */
4464 for (i
= 0; i
< nkeywords
; ++i
)
4465 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
4471 /* Record that we recognized the keyword. If a keywords
4472 was found more than once, it's an error. */
4473 keywords
[i
].value
= value
;
4474 ++keywords
[i
].count
;
4476 if (keywords
[i
].count
> 1)
4479 /* Check type of value against allowed type. */
4480 switch (keywords
[i
].type
)
4482 case IMAGE_STRING_VALUE
:
4483 if (!STRINGP (value
))
4487 case IMAGE_STRING_OR_NIL_VALUE
:
4488 if (!STRINGP (value
) && !NILP (value
))
4492 case IMAGE_SYMBOL_VALUE
:
4493 if (!SYMBOLP (value
))
4497 case IMAGE_POSITIVE_INTEGER_VALUE
:
4498 if (!INTEGERP (value
) || XINT (value
) <= 0)
4502 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
4503 if (INTEGERP (value
) && XINT (value
) >= 0)
4506 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
4507 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
4511 case IMAGE_ASCENT_VALUE
:
4512 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
4514 else if (INTEGERP (value
)
4515 && XINT (value
) >= 0
4516 && XINT (value
) <= 100)
4520 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
4521 if (!INTEGERP (value
) || XINT (value
) < 0)
4525 case IMAGE_DONT_CHECK_VALUE_TYPE
:
4528 case IMAGE_FUNCTION_VALUE
:
4529 value
= indirect_function (value
);
4531 || COMPILEDP (value
)
4532 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
4536 case IMAGE_NUMBER_VALUE
:
4537 if (!INTEGERP (value
) && !FLOATP (value
))
4541 case IMAGE_INTEGER_VALUE
:
4542 if (!INTEGERP (value
))
4546 case IMAGE_BOOL_VALUE
:
4547 if (!NILP (value
) && !EQ (value
, Qt
))
4556 if (EQ (key
, QCtype
) && !EQ (type
, value
))
4560 /* Check that all mandatory fields are present. */
4561 for (i
= 0; i
< nkeywords
; ++i
)
4562 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
4565 return NILP (plist
);
4569 /* Return the value of KEY in image specification SPEC. Value is nil
4570 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
4571 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
4574 image_spec_value (spec
, key
, found
)
4575 Lisp_Object spec
, key
;
4580 xassert (valid_image_p (spec
));
4582 for (tail
= XCDR (spec
);
4583 CONSP (tail
) && CONSP (XCDR (tail
));
4584 tail
= XCDR (XCDR (tail
)))
4586 if (EQ (XCAR (tail
), key
))
4590 return XCAR (XCDR (tail
));
4600 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
4601 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
4602 PIXELS non-nil means return the size in pixels, otherwise return the
4603 size in canonical character units.
4604 FRAME is the frame on which the image will be displayed. FRAME nil
4605 or omitted means use the selected frame. */)
4606 (spec
, pixels
, frame
)
4607 Lisp_Object spec
, pixels
, frame
;
4612 if (valid_image_p (spec
))
4614 struct frame
*f
= check_x_frame (frame
);
4615 int id
= lookup_image (f
, spec
);
4616 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4617 int width
= img
->width
+ 2 * img
->hmargin
;
4618 int height
= img
->height
+ 2 * img
->vmargin
;
4621 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
4622 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
4624 size
= Fcons (make_number (width
), make_number (height
));
4627 error ("Invalid image specification");
4633 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
4634 doc
: /* Return t if image SPEC has a mask bitmap.
4635 FRAME is the frame on which the image will be displayed. FRAME nil
4636 or omitted means use the selected frame. */)
4638 Lisp_Object spec
, frame
;
4643 if (valid_image_p (spec
))
4645 struct frame
*f
= check_x_frame (frame
);
4646 int id
= lookup_image (f
, spec
);
4647 struct image
*img
= IMAGE_FROM_ID (f
, id
);
4652 error ("Invalid image specification");
4659 /***********************************************************************
4660 Image type independent image structures
4661 ***********************************************************************/
4663 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
4664 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
4667 /* Allocate and return a new image structure for image specification
4668 SPEC. SPEC has a hash value of HASH. */
4670 static struct image
*
4671 make_image (spec
, hash
)
4675 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
4677 xassert (valid_image_p (spec
));
4678 bzero (img
, sizeof *img
);
4679 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
4680 xassert (img
->type
!= NULL
);
4682 img
->data
.lisp_val
= Qnil
;
4683 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
4689 /* Free image IMG which was used on frame F, including its resources. */
4698 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
4700 /* Remove IMG from the hash table of its cache. */
4702 img
->prev
->next
= img
->next
;
4704 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
4707 img
->next
->prev
= img
->prev
;
4709 c
->images
[img
->id
] = NULL
;
4711 /* Free resources, then free IMG. */
4712 img
->type
->free (f
, img
);
4718 /* Prepare image IMG for display on frame F. Must be called before
4719 drawing an image. */
4722 prepare_image_for_display (f
, img
)
4728 /* We're about to display IMG, so set its timestamp to `now'. */
4730 img
->timestamp
= EMACS_SECS (t
);
4732 /* If IMG doesn't have a pixmap yet, load it now, using the image
4733 type dependent loader function. */
4734 if (img
->pixmap
== None
&& !img
->load_failed_p
)
4735 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
4739 /* Value is the number of pixels for the ascent of image IMG when
4740 drawn in face FACE. */
4743 image_ascent (img
, face
)
4747 int height
= img
->height
+ img
->vmargin
;
4750 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
4753 /* This expression is arranged so that if the image can't be
4754 exactly centered, it will be moved slightly up. This is
4755 because a typical font is `top-heavy' (due to the presence
4756 uppercase letters), so the image placement should err towards
4757 being top-heavy too. It also just generally looks better. */
4758 ascent
= (height
+ face
->font
->ascent
- face
->font
->descent
+ 1) / 2;
4760 ascent
= height
/ 2;
4763 ascent
= height
* img
->ascent
/ 100.0;
4769 /* Image background colors. */
4771 static unsigned long
4772 four_corners_best (ximg
, width
, height
)
4774 unsigned long width
, height
;
4776 unsigned long corners
[4], best
;
4779 /* Get the colors at the corners of ximg. */
4780 corners
[0] = XGetPixel (ximg
, 0, 0);
4781 corners
[1] = XGetPixel (ximg
, width
- 1, 0);
4782 corners
[2] = XGetPixel (ximg
, width
- 1, height
- 1);
4783 corners
[3] = XGetPixel (ximg
, 0, height
- 1);
4785 /* Choose the most frequently found color as background. */
4786 for (i
= best_count
= 0; i
< 4; ++i
)
4790 for (j
= n
= 0; j
< 4; ++j
)
4791 if (corners
[i
] == corners
[j
])
4795 best
= corners
[i
], best_count
= n
;
4801 /* Return the `background' field of IMG. If IMG doesn't have one yet,
4802 it is guessed heuristically. If non-zero, XIMG is an existing XImage
4803 object to use for the heuristic. */
4806 image_background (img
, f
, ximg
)
4811 if (! img
->background_valid
)
4812 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4814 int free_ximg
= !ximg
;
4817 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4818 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4820 img
->background
= four_corners_best (ximg
, img
->width
, img
->height
);
4823 XDestroyImage (ximg
);
4825 img
->background_valid
= 1;
4828 return img
->background
;
4831 /* Return the `background_transparent' field of IMG. If IMG doesn't
4832 have one yet, it is guessed heuristically. If non-zero, MASK is an
4833 existing XImage object to use for the heuristic. */
4836 image_background_transparent (img
, f
, mask
)
4841 if (! img
->background_transparent_valid
)
4842 /* IMG doesn't have a background yet, try to guess a reasonable value. */
4846 int free_mask
= !mask
;
4849 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
4850 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4852 img
->background_transparent
4853 = !four_corners_best (mask
, img
->width
, img
->height
);
4856 XDestroyImage (mask
);
4859 img
->background_transparent
= 0;
4861 img
->background_transparent_valid
= 1;
4864 return img
->background_transparent
;
4868 /***********************************************************************
4869 Helper functions for X image types
4870 ***********************************************************************/
4872 static void x_clear_image_1
P_ ((struct frame
*, struct image
*, int,
4874 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
4875 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
4877 Lisp_Object color_name
,
4878 unsigned long dflt
));
4881 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
4882 free the pixmap if any. MASK_P non-zero means clear the mask
4883 pixmap if any. COLORS_P non-zero means free colors allocated for
4884 the image, if any. */
4887 x_clear_image_1 (f
, img
, pixmap_p
, mask_p
, colors_p
)
4890 int pixmap_p
, mask_p
, colors_p
;
4892 if (pixmap_p
&& img
->pixmap
)
4894 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
4896 img
->background_valid
= 0;
4899 if (mask_p
&& img
->mask
)
4901 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4903 img
->background_transparent_valid
= 0;
4906 if (colors_p
&& img
->ncolors
)
4908 x_free_colors (f
, img
->colors
, img
->ncolors
);
4909 xfree (img
->colors
);
4915 /* Free X resources of image IMG which is used on frame F. */
4918 x_clear_image (f
, img
)
4923 x_clear_image_1 (f
, img
, 1, 1, 1);
4928 /* Allocate color COLOR_NAME for image IMG on frame F. If color
4929 cannot be allocated, use DFLT. Add a newly allocated color to
4930 IMG->colors, so that it can be freed again. Value is the pixel
4933 static unsigned long
4934 x_alloc_image_color (f
, img
, color_name
, dflt
)
4937 Lisp_Object color_name
;
4941 unsigned long result
;
4943 xassert (STRINGP (color_name
));
4945 if (x_defined_color (f
, SDATA (color_name
), &color
, 1))
4947 /* This isn't called frequently so we get away with simply
4948 reallocating the color vector to the needed size, here. */
4951 (unsigned long *) xrealloc (img
->colors
,
4952 img
->ncolors
* sizeof *img
->colors
);
4953 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
4954 result
= color
.pixel
;
4964 /***********************************************************************
4966 ***********************************************************************/
4968 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
4969 static void postprocess_image
P_ ((struct frame
*, struct image
*));
4972 /* Return a new, initialized image cache that is allocated from the
4973 heap. Call free_image_cache to free an image cache. */
4975 struct image_cache
*
4978 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
4981 bzero (c
, sizeof *c
);
4983 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
4984 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
4985 c
->buckets
= (struct image
**) xmalloc (size
);
4986 bzero (c
->buckets
, size
);
4991 /* Free image cache of frame F. Be aware that X frames share images
4995 free_image_cache (f
)
4998 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5003 /* Cache should not be referenced by any frame when freed. */
5004 xassert (c
->refcount
== 0);
5006 for (i
= 0; i
< c
->used
; ++i
)
5007 free_image (f
, c
->images
[i
]);
5011 FRAME_X_IMAGE_CACHE (f
) = NULL
;
5016 /* Clear image cache of frame F. FORCE_P non-zero means free all
5017 images. FORCE_P zero means clear only images that haven't been
5018 displayed for some time. Should be called from time to time to
5019 reduce the number of loaded images. If image-eviction-seconds is
5020 non-nil, this frees images in the cache which weren't displayed for
5021 at least that many seconds. */
5024 clear_image_cache (f
, force_p
)
5028 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5030 if (c
&& INTEGERP (Vimage_cache_eviction_delay
))
5037 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
5039 /* Block input so that we won't be interrupted by a SIGIO
5040 while being in an inconsistent state. */
5043 for (i
= nfreed
= 0; i
< c
->used
; ++i
)
5045 struct image
*img
= c
->images
[i
];
5047 && (force_p
|| img
->timestamp
< old
))
5049 free_image (f
, img
);
5054 /* We may be clearing the image cache because, for example,
5055 Emacs was iconified for a longer period of time. In that
5056 case, current matrices may still contain references to
5057 images freed above. So, clear these matrices. */
5060 Lisp_Object tail
, frame
;
5062 FOR_EACH_FRAME (tail
, frame
)
5064 struct frame
*f
= XFRAME (frame
);
5066 && FRAME_X_IMAGE_CACHE (f
) == c
)
5067 clear_current_matrices (f
);
5070 ++windows_or_buffers_changed
;
5078 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
5080 doc
: /* Clear the image cache of FRAME.
5081 FRAME nil or omitted means use the selected frame.
5082 FRAME t means clear the image caches of all frames. */)
5090 FOR_EACH_FRAME (tail
, frame
)
5091 if (FRAME_X_P (XFRAME (frame
)))
5092 clear_image_cache (XFRAME (frame
), 1);
5095 clear_image_cache (check_x_frame (frame
), 1);
5101 /* Compute masks and transform image IMG on frame F, as specified
5102 by the image's specification, */
5105 postprocess_image (f
, img
)
5109 /* Manipulation of the image's mask. */
5112 Lisp_Object conversion
, spec
;
5117 /* `:heuristic-mask t'
5119 means build a mask heuristically.
5120 `:heuristic-mask (R G B)'
5121 `:mask (heuristic (R G B))'
5122 means build a mask from color (R G B) in the
5125 means remove a mask, if any. */
5127 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
5129 x_build_heuristic_mask (f
, img
, mask
);
5134 mask
= image_spec_value (spec
, QCmask
, &found_p
);
5136 if (EQ (mask
, Qheuristic
))
5137 x_build_heuristic_mask (f
, img
, Qt
);
5138 else if (CONSP (mask
)
5139 && EQ (XCAR (mask
), Qheuristic
))
5141 if (CONSP (XCDR (mask
)))
5142 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
5144 x_build_heuristic_mask (f
, img
, XCDR (mask
));
5146 else if (NILP (mask
) && found_p
&& img
->mask
)
5148 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
5154 /* Should we apply an image transformation algorithm? */
5155 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
5156 if (EQ (conversion
, Qdisabled
))
5157 x_disable_image (f
, img
);
5158 else if (EQ (conversion
, Qlaplace
))
5160 else if (EQ (conversion
, Qemboss
))
5162 else if (CONSP (conversion
)
5163 && EQ (XCAR (conversion
), Qedge_detection
))
5166 tem
= XCDR (conversion
);
5168 x_edge_detection (f
, img
,
5169 Fplist_get (tem
, QCmatrix
),
5170 Fplist_get (tem
, QCcolor_adjustment
));
5176 /* Return the id of image with Lisp specification SPEC on frame F.
5177 SPEC must be a valid Lisp image specification (see valid_image_p). */
5180 lookup_image (f
, spec
)
5184 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5188 struct gcpro gcpro1
;
5191 /* F must be a window-system frame, and SPEC must be a valid image
5193 xassert (FRAME_WINDOW_P (f
));
5194 xassert (valid_image_p (spec
));
5198 /* Look up SPEC in the hash table of the image cache. */
5199 hash
= sxhash (spec
, 0);
5200 i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5202 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
5203 if (img
->hash
== hash
&& !NILP (Fequal (img
->spec
, spec
)))
5206 /* If not found, create a new image and cache it. */
5209 extern Lisp_Object Qpostscript
;
5212 img
= make_image (spec
, hash
);
5213 cache_image (f
, img
);
5214 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
5216 /* If we can't load the image, and we don't have a width and
5217 height, use some arbitrary width and height so that we can
5218 draw a rectangle for it. */
5219 if (img
->load_failed_p
)
5223 value
= image_spec_value (spec
, QCwidth
, NULL
);
5224 img
->width
= (INTEGERP (value
)
5225 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
5226 value
= image_spec_value (spec
, QCheight
, NULL
);
5227 img
->height
= (INTEGERP (value
)
5228 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
5232 /* Handle image type independent image attributes
5233 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
5234 `:background COLOR'. */
5235 Lisp_Object ascent
, margin
, relief
, bg
;
5237 ascent
= image_spec_value (spec
, QCascent
, NULL
);
5238 if (INTEGERP (ascent
))
5239 img
->ascent
= XFASTINT (ascent
);
5240 else if (EQ (ascent
, Qcenter
))
5241 img
->ascent
= CENTERED_IMAGE_ASCENT
;
5243 margin
= image_spec_value (spec
, QCmargin
, NULL
);
5244 if (INTEGERP (margin
) && XINT (margin
) >= 0)
5245 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
5246 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
5247 && INTEGERP (XCDR (margin
)))
5249 if (XINT (XCAR (margin
)) > 0)
5250 img
->hmargin
= XFASTINT (XCAR (margin
));
5251 if (XINT (XCDR (margin
)) > 0)
5252 img
->vmargin
= XFASTINT (XCDR (margin
));
5255 relief
= image_spec_value (spec
, QCrelief
, NULL
);
5256 if (INTEGERP (relief
))
5258 img
->relief
= XINT (relief
);
5259 img
->hmargin
+= abs (img
->relief
);
5260 img
->vmargin
+= abs (img
->relief
);
5263 if (! img
->background_valid
)
5265 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
5269 = x_alloc_image_color (f
, img
, bg
,
5270 FRAME_BACKGROUND_PIXEL (f
));
5271 img
->background_valid
= 1;
5275 /* Do image transformations and compute masks, unless we
5276 don't have the image yet. */
5277 if (!EQ (*img
->type
->type
, Qpostscript
))
5278 postprocess_image (f
, img
);
5282 xassert (!interrupt_input_blocked
);
5285 /* We're using IMG, so set its timestamp to `now'. */
5286 EMACS_GET_TIME (now
);
5287 img
->timestamp
= EMACS_SECS (now
);
5291 /* Value is the image id. */
5296 /* Cache image IMG in the image cache of frame F. */
5299 cache_image (f
, img
)
5303 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5306 /* Find a free slot in c->images. */
5307 for (i
= 0; i
< c
->used
; ++i
)
5308 if (c
->images
[i
] == NULL
)
5311 /* If no free slot found, maybe enlarge c->images. */
5312 if (i
== c
->used
&& c
->used
== c
->size
)
5315 c
->images
= (struct image
**) xrealloc (c
->images
,
5316 c
->size
* sizeof *c
->images
);
5319 /* Add IMG to c->images, and assign IMG an id. */
5325 /* Add IMG to the cache's hash table. */
5326 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
5327 img
->next
= c
->buckets
[i
];
5329 img
->next
->prev
= img
;
5331 c
->buckets
[i
] = img
;
5335 /* Call FN on every image in the image cache of frame F. Used to mark
5336 Lisp Objects in the image cache. */
5339 forall_images_in_image_cache (f
, fn
)
5341 void (*fn
) P_ ((struct image
*img
));
5343 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
))
5345 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
5349 for (i
= 0; i
< c
->used
; ++i
)
5358 /***********************************************************************
5360 ***********************************************************************/
5362 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
5363 XImage
**, Pixmap
*));
5364 static void x_destroy_x_image
P_ ((XImage
*));
5365 static void x_put_x_image
P_ ((struct frame
*, XImage
*, Pixmap
, int, int));
5368 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
5369 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
5370 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
5371 via xmalloc. Print error messages via image_error if an error
5372 occurs. Value is non-zero if successful. */
5375 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
5377 int width
, height
, depth
;
5381 Display
*display
= FRAME_X_DISPLAY (f
);
5382 Screen
*screen
= FRAME_X_SCREEN (f
);
5383 Window window
= FRAME_X_WINDOW (f
);
5385 xassert (interrupt_input_blocked
);
5388 depth
= DefaultDepthOfScreen (screen
);
5389 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
5390 depth
, ZPixmap
, 0, NULL
, width
, height
,
5391 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
5394 image_error ("Unable to allocate X image", Qnil
, Qnil
);
5398 /* Allocate image raster. */
5399 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
5401 /* Allocate a pixmap of the same size. */
5402 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
5403 if (*pixmap
== None
)
5405 x_destroy_x_image (*ximg
);
5407 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
5415 /* Destroy XImage XIMG. Free XIMG->data. */
5418 x_destroy_x_image (ximg
)
5421 xassert (interrupt_input_blocked
);
5426 XDestroyImage (ximg
);
5431 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
5432 are width and height of both the image and pixmap. */
5435 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
5443 xassert (interrupt_input_blocked
);
5444 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
5445 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
5446 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
5451 /***********************************************************************
5453 ***********************************************************************/
5455 static Lisp_Object x_find_image_file
P_ ((Lisp_Object
));
5456 static char *slurp_file
P_ ((char *, int *));
5459 /* Find image file FILE. Look in data-directory, then
5460 x-bitmap-file-path. Value is the full name of the file found, or
5461 nil if not found. */
5464 x_find_image_file (file
)
5467 Lisp_Object file_found
, search_path
;
5468 struct gcpro gcpro1
, gcpro2
;
5472 search_path
= Fcons (Vdata_directory
, Vx_bitmap_file_path
);
5473 GCPRO2 (file_found
, search_path
);
5475 /* Try to find FILE in data-directory, then x-bitmap-file-path. */
5476 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
5488 /* Read FILE into memory. Value is a pointer to a buffer allocated
5489 with xmalloc holding FILE's contents. Value is null if an error
5490 occurred. *SIZE is set to the size of the file. */
5493 slurp_file (file
, size
)
5501 if (stat (file
, &st
) == 0
5502 && (fp
= fopen (file
, "r")) != NULL
5503 && (buf
= (char *) xmalloc (st
.st_size
),
5504 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5525 /***********************************************************************
5527 ***********************************************************************/
5529 static int xbm_scan
P_ ((char **, char *, char *, int *));
5530 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
5531 static int xbm_load_image
P_ ((struct frame
*f
, struct image
*img
,
5533 static int xbm_image_p
P_ ((Lisp_Object object
));
5534 static int xbm_read_bitmap_data
P_ ((char *, char *, int *, int *,
5536 static int xbm_file_p
P_ ((Lisp_Object
));
5539 /* Indices of image specification fields in xbm_format, below. */
5541 enum xbm_keyword_index
5559 /* Vector of image_keyword structures describing the format
5560 of valid XBM image specifications. */
5562 static struct image_keyword xbm_format
[XBM_LAST
] =
5564 {":type", IMAGE_SYMBOL_VALUE
, 1},
5565 {":file", IMAGE_STRING_VALUE
, 0},
5566 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5567 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
5568 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5569 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
5570 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
5571 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5572 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5573 {":relief", IMAGE_INTEGER_VALUE
, 0},
5574 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5575 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5576 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
5579 /* Structure describing the image type XBM. */
5581 static struct image_type xbm_type
=
5590 /* Tokens returned from xbm_scan. */
5599 /* Return non-zero if OBJECT is a valid XBM-type image specification.
5600 A valid specification is a list starting with the symbol `image'
5601 The rest of the list is a property list which must contain an
5604 If the specification specifies a file to load, it must contain
5605 an entry `:file FILENAME' where FILENAME is a string.
5607 If the specification is for a bitmap loaded from memory it must
5608 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
5609 WIDTH and HEIGHT are integers > 0. DATA may be:
5611 1. a string large enough to hold the bitmap data, i.e. it must
5612 have a size >= (WIDTH + 7) / 8 * HEIGHT
5614 2. a bool-vector of size >= WIDTH * HEIGHT
5616 3. a vector of strings or bool-vectors, one for each line of the
5619 4. A string containing an in-memory XBM file. WIDTH and HEIGHT
5620 may not be specified in this case because they are defined in the
5623 Both the file and data forms may contain the additional entries
5624 `:background COLOR' and `:foreground COLOR'. If not present,
5625 foreground and background of the frame on which the image is
5626 displayed is used. */
5629 xbm_image_p (object
)
5632 struct image_keyword kw
[XBM_LAST
];
5634 bcopy (xbm_format
, kw
, sizeof kw
);
5635 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
5638 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
5640 if (kw
[XBM_FILE
].count
)
5642 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
5645 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
5647 /* In-memory XBM file. */
5648 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
5656 /* Entries for `:width', `:height' and `:data' must be present. */
5657 if (!kw
[XBM_WIDTH
].count
5658 || !kw
[XBM_HEIGHT
].count
5659 || !kw
[XBM_DATA
].count
)
5662 data
= kw
[XBM_DATA
].value
;
5663 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
5664 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
5666 /* Check type of data, and width and height against contents of
5672 /* Number of elements of the vector must be >= height. */
5673 if (XVECTOR (data
)->size
< height
)
5676 /* Each string or bool-vector in data must be large enough
5677 for one line of the image. */
5678 for (i
= 0; i
< height
; ++i
)
5680 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
5685 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
5688 else if (BOOL_VECTOR_P (elt
))
5690 if (XBOOL_VECTOR (elt
)->size
< width
)
5697 else if (STRINGP (data
))
5700 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
5703 else if (BOOL_VECTOR_P (data
))
5705 if (XBOOL_VECTOR (data
)->size
< width
* height
)
5716 /* Scan a bitmap file. FP is the stream to read from. Value is
5717 either an enumerator from enum xbm_token, or a character for a
5718 single-character token, or 0 at end of file. If scanning an
5719 identifier, store the lexeme of the identifier in SVAL. If
5720 scanning a number, store its value in *IVAL. */
5723 xbm_scan (s
, end
, sval
, ival
)
5732 /* Skip white space. */
5733 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5738 else if (isdigit (c
))
5740 int value
= 0, digit
;
5742 if (c
== '0' && *s
< end
)
5745 if (c
== 'x' || c
== 'X')
5752 else if (c
>= 'a' && c
<= 'f')
5753 digit
= c
- 'a' + 10;
5754 else if (c
>= 'A' && c
<= 'F')
5755 digit
= c
- 'A' + 10;
5758 value
= 16 * value
+ digit
;
5761 else if (isdigit (c
))
5765 && (c
= *(*s
)++, isdigit (c
)))
5766 value
= 8 * value
+ c
- '0';
5773 && (c
= *(*s
)++, isdigit (c
)))
5774 value
= 10 * value
+ c
- '0';
5782 else if (isalpha (c
) || c
== '_')
5786 && (c
= *(*s
)++, (isalnum (c
) || c
== '_')))
5793 else if (c
== '/' && **s
== '*')
5795 /* C-style comment. */
5797 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
5810 /* Replacement for XReadBitmapFileData which isn't available under old
5811 X versions. CONTENTS is a pointer to a buffer to parse; END is the
5812 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
5813 the image. Return in *DATA the bitmap data allocated with xmalloc.
5814 Value is non-zero if successful. DATA null means just test if
5815 CONTENTS looks like an in-memory XBM file. */
5818 xbm_read_bitmap_data (contents
, end
, width
, height
, data
)
5819 char *contents
, *end
;
5820 int *width
, *height
;
5821 unsigned char **data
;
5824 char buffer
[BUFSIZ
];
5827 int bytes_per_line
, i
, nbytes
;
5833 LA1 = xbm_scan (&s, end, buffer, &value)
5835 #define expect(TOKEN) \
5836 if (LA1 != (TOKEN)) \
5841 #define expect_ident(IDENT) \
5842 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
5847 *width
= *height
= -1;
5850 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
5852 /* Parse defines for width, height and hot-spots. */
5856 expect_ident ("define");
5857 expect (XBM_TK_IDENT
);
5859 if (LA1
== XBM_TK_NUMBER
);
5861 char *p
= strrchr (buffer
, '_');
5862 p
= p
? p
+ 1 : buffer
;
5863 if (strcmp (p
, "width") == 0)
5865 else if (strcmp (p
, "height") == 0)
5868 expect (XBM_TK_NUMBER
);
5871 if (*width
< 0 || *height
< 0)
5873 else if (data
== NULL
)
5876 /* Parse bits. Must start with `static'. */
5877 expect_ident ("static");
5878 if (LA1
== XBM_TK_IDENT
)
5880 if (strcmp (buffer
, "unsigned") == 0)
5883 expect_ident ("char");
5885 else if (strcmp (buffer
, "short") == 0)
5889 if (*width
% 16 && *width
% 16 < 9)
5892 else if (strcmp (buffer
, "char") == 0)
5900 expect (XBM_TK_IDENT
);
5906 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
5907 nbytes
= bytes_per_line
* *height
;
5908 p
= *data
= (char *) xmalloc (nbytes
);
5912 for (i
= 0; i
< nbytes
; i
+= 2)
5915 expect (XBM_TK_NUMBER
);
5918 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
5921 if (LA1
== ',' || LA1
== '}')
5929 for (i
= 0; i
< nbytes
; ++i
)
5932 expect (XBM_TK_NUMBER
);
5936 if (LA1
== ',' || LA1
== '}')
5961 /* Load XBM image IMG which will be displayed on frame F from buffer
5962 CONTENTS. END is the end of the buffer. Value is non-zero if
5966 xbm_load_image (f
, img
, contents
, end
)
5969 char *contents
, *end
;
5972 unsigned char *data
;
5975 rc
= xbm_read_bitmap_data (contents
, end
, &img
->width
, &img
->height
, &data
);
5978 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
5979 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
5980 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
5983 xassert (img
->width
> 0 && img
->height
> 0);
5985 /* Get foreground and background colors, maybe allocate colors. */
5986 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
5988 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
5989 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
5992 background
= x_alloc_image_color (f
, img
, value
, background
);
5993 img
->background
= background
;
5994 img
->background_valid
= 1;
5998 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
6001 img
->width
, img
->height
,
6002 foreground
, background
,
6006 if (img
->pixmap
== None
)
6008 x_clear_image (f
, img
);
6009 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
6015 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6021 /* Value is non-zero if DATA looks like an in-memory XBM file. */
6028 return (STRINGP (data
)
6029 && xbm_read_bitmap_data (SDATA (data
),
6036 /* Fill image IMG which is used on frame F with pixmap data. Value is
6037 non-zero if successful. */
6045 Lisp_Object file_name
;
6047 xassert (xbm_image_p (img
->spec
));
6049 /* If IMG->spec specifies a file name, create a non-file spec from it. */
6050 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
6051 if (STRINGP (file_name
))
6056 struct gcpro gcpro1
;
6058 file
= x_find_image_file (file_name
);
6060 if (!STRINGP (file
))
6062 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
6067 contents
= slurp_file (SDATA (file
), &size
);
6068 if (contents
== NULL
)
6070 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
6075 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
6080 struct image_keyword fmt
[XBM_LAST
];
6083 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
6084 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
6087 int in_memory_file_p
= 0;
6089 /* See if data looks like an in-memory XBM file. */
6090 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6091 in_memory_file_p
= xbm_file_p (data
);
6093 /* Parse the image specification. */
6094 bcopy (xbm_format
, fmt
, sizeof fmt
);
6095 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
6098 /* Get specified width, and height. */
6099 if (!in_memory_file_p
)
6101 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
6102 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
6103 xassert (img
->width
> 0 && img
->height
> 0);
6106 /* Get foreground and background colors, maybe allocate colors. */
6107 if (fmt
[XBM_FOREGROUND
].count
6108 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
6109 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
6111 if (fmt
[XBM_BACKGROUND
].count
6112 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
6113 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
6116 if (in_memory_file_p
)
6117 success_p
= xbm_load_image (f
, img
, SDATA (data
),
6126 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
6128 p
= bits
= (char *) alloca (nbytes
* img
->height
);
6129 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
6131 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
6133 bcopy (SDATA (line
), p
, nbytes
);
6135 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
6138 else if (STRINGP (data
))
6139 bits
= SDATA (data
);
6141 bits
= XBOOL_VECTOR (data
)->data
;
6143 /* Create the pixmap. */
6144 depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
6146 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
6149 img
->width
, img
->height
,
6150 foreground
, background
,
6156 image_error ("Unable to create pixmap for XBM image `%s'",
6158 x_clear_image (f
, img
);
6168 /***********************************************************************
6170 ***********************************************************************/
6174 static int xpm_image_p
P_ ((Lisp_Object object
));
6175 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
6176 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
6178 #include "X11/xpm.h"
6180 /* The symbol `xpm' identifying XPM-format images. */
6184 /* Indices of image specification fields in xpm_format, below. */
6186 enum xpm_keyword_index
6202 /* Vector of image_keyword structures describing the format
6203 of valid XPM image specifications. */
6205 static struct image_keyword xpm_format
[XPM_LAST
] =
6207 {":type", IMAGE_SYMBOL_VALUE
, 1},
6208 {":file", IMAGE_STRING_VALUE
, 0},
6209 {":data", IMAGE_STRING_VALUE
, 0},
6210 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6211 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6212 {":relief", IMAGE_INTEGER_VALUE
, 0},
6213 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6214 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6215 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6216 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6217 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6220 /* Structure describing the image type XBM. */
6222 static struct image_type xpm_type
=
6232 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
6233 functions for allocating image colors. Our own functions handle
6234 color allocation failures more gracefully than the ones on the XPM
6237 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
6238 #define ALLOC_XPM_COLORS
6241 #ifdef ALLOC_XPM_COLORS
6243 static void xpm_init_color_cache
P_ ((struct frame
*, XpmAttributes
*));
6244 static void xpm_free_color_cache
P_ ((void));
6245 static int xpm_lookup_color
P_ ((struct frame
*, char *, XColor
*));
6246 static int xpm_color_bucket
P_ ((char *));
6247 static struct xpm_cached_color
*xpm_cache_color
P_ ((struct frame
*, char *,
6250 /* An entry in a hash table used to cache color definitions of named
6251 colors. This cache is necessary to speed up XPM image loading in
6252 case we do color allocations ourselves. Without it, we would need
6253 a call to XParseColor per pixel in the image. */
6255 struct xpm_cached_color
6257 /* Next in collision chain. */
6258 struct xpm_cached_color
*next
;
6260 /* Color definition (RGB and pixel color). */
6267 /* The hash table used for the color cache, and its bucket vector
6270 #define XPM_COLOR_CACHE_BUCKETS 1001
6271 struct xpm_cached_color
**xpm_color_cache
;
6273 /* Initialize the color cache. */
6276 xpm_init_color_cache (f
, attrs
)
6278 XpmAttributes
*attrs
;
6280 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
6281 xpm_color_cache
= (struct xpm_cached_color
**) xmalloc (nbytes
);
6282 memset (xpm_color_cache
, 0, nbytes
);
6283 init_color_table ();
6285 if (attrs
->valuemask
& XpmColorSymbols
)
6290 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
6291 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6292 attrs
->colorsymbols
[i
].value
, &color
))
6294 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
6296 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
6302 /* Free the color cache. */
6305 xpm_free_color_cache ()
6307 struct xpm_cached_color
*p
, *next
;
6310 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
6311 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
6317 xfree (xpm_color_cache
);
6318 xpm_color_cache
= NULL
;
6319 free_color_table ();
6323 /* Return the bucket index for color named COLOR_NAME in the color
6327 xpm_color_bucket (color_name
)
6333 for (s
= color_name
; *s
; ++s
)
6335 return h
%= XPM_COLOR_CACHE_BUCKETS
;
6339 /* On frame F, cache values COLOR for color with name COLOR_NAME.
6340 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
6343 static struct xpm_cached_color
*
6344 xpm_cache_color (f
, color_name
, color
, bucket
)
6351 struct xpm_cached_color
*p
;
6354 bucket
= xpm_color_bucket (color_name
);
6356 nbytes
= sizeof *p
+ strlen (color_name
);
6357 p
= (struct xpm_cached_color
*) xmalloc (nbytes
);
6358 strcpy (p
->name
, color_name
);
6360 p
->next
= xpm_color_cache
[bucket
];
6361 xpm_color_cache
[bucket
] = p
;
6366 /* Look up color COLOR_NAME for frame F in the color cache. If found,
6367 return the cached definition in *COLOR. Otherwise, make a new
6368 entry in the cache and allocate the color. Value is zero if color
6369 allocation failed. */
6372 xpm_lookup_color (f
, color_name
, color
)
6377 struct xpm_cached_color
*p
;
6378 int h
= xpm_color_bucket (color_name
);
6380 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
6381 if (strcmp (p
->name
, color_name
) == 0)
6386 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
6389 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
6391 p
= xpm_cache_color (f
, color_name
, color
, h
);
6393 /* You get `opaque' at least from ImageMagick converting pbm to xpm
6394 with transparency, and it's useful. */
6395 else if (strcmp ("opaque", color_name
) == 0)
6397 bzero (color
, sizeof (XColor
)); /* Is this necessary/correct? */
6398 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
6399 p
= xpm_cache_color (f
, color_name
, color
, h
);
6406 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
6407 CLOSURE is a pointer to the frame on which we allocate the
6408 color. Return in *COLOR the allocated color. Value is non-zero
6412 xpm_alloc_color (dpy
, cmap
, color_name
, color
, closure
)
6419 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
6423 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
6424 is a pointer to the frame on which we allocate the color. Value is
6425 non-zero if successful. */
6428 xpm_free_colors (dpy
, cmap
, pixels
, npixels
, closure
)
6438 #endif /* ALLOC_XPM_COLORS */
6441 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
6442 for XPM images. Such a list must consist of conses whose car and
6446 xpm_valid_color_symbols_p (color_symbols
)
6447 Lisp_Object color_symbols
;
6449 while (CONSP (color_symbols
))
6451 Lisp_Object sym
= XCAR (color_symbols
);
6453 || !STRINGP (XCAR (sym
))
6454 || !STRINGP (XCDR (sym
)))
6456 color_symbols
= XCDR (color_symbols
);
6459 return NILP (color_symbols
);
6463 /* Value is non-zero if OBJECT is a valid XPM image specification. */
6466 xpm_image_p (object
)
6469 struct image_keyword fmt
[XPM_LAST
];
6470 bcopy (xpm_format
, fmt
, sizeof fmt
);
6471 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
6472 /* Either `:file' or `:data' must be present. */
6473 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
6474 /* Either no `:color-symbols' or it's a list of conses
6475 whose car and cdr are strings. */
6476 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
6477 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
6481 /* Load image IMG which will be displayed on frame F. Value is
6482 non-zero if successful. */
6490 XpmAttributes attrs
;
6491 Lisp_Object specified_file
, color_symbols
;
6493 /* Configure the XPM lib. Use the visual of frame F. Allocate
6494 close colors. Return colors allocated. */
6495 bzero (&attrs
, sizeof attrs
);
6496 attrs
.visual
= FRAME_X_VISUAL (f
);
6497 attrs
.colormap
= FRAME_X_COLORMAP (f
);
6498 attrs
.valuemask
|= XpmVisual
;
6499 attrs
.valuemask
|= XpmColormap
;
6501 #ifdef ALLOC_XPM_COLORS
6502 /* Allocate colors with our own functions which handle
6503 failing color allocation more gracefully. */
6504 attrs
.color_closure
= f
;
6505 attrs
.alloc_color
= xpm_alloc_color
;
6506 attrs
.free_colors
= xpm_free_colors
;
6507 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
6508 #else /* not ALLOC_XPM_COLORS */
6509 /* Let the XPM lib allocate colors. */
6510 attrs
.valuemask
|= XpmReturnAllocPixels
;
6511 #ifdef XpmAllocCloseColors
6512 attrs
.alloc_close_colors
= 1;
6513 attrs
.valuemask
|= XpmAllocCloseColors
;
6514 #else /* not XpmAllocCloseColors */
6515 attrs
.closeness
= 600;
6516 attrs
.valuemask
|= XpmCloseness
;
6517 #endif /* not XpmAllocCloseColors */
6518 #endif /* ALLOC_XPM_COLORS */
6520 /* If image specification contains symbolic color definitions, add
6521 these to `attrs'. */
6522 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
6523 if (CONSP (color_symbols
))
6526 XpmColorSymbol
*xpm_syms
;
6529 attrs
.valuemask
|= XpmColorSymbols
;
6531 /* Count number of symbols. */
6532 attrs
.numsymbols
= 0;
6533 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
6536 /* Allocate an XpmColorSymbol array. */
6537 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
6538 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
6539 bzero (xpm_syms
, size
);
6540 attrs
.colorsymbols
= xpm_syms
;
6542 /* Fill the color symbol array. */
6543 for (tail
= color_symbols
, i
= 0;
6545 ++i
, tail
= XCDR (tail
))
6547 Lisp_Object name
= XCAR (XCAR (tail
));
6548 Lisp_Object color
= XCDR (XCAR (tail
));
6549 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
6550 strcpy (xpm_syms
[i
].name
, SDATA (name
));
6551 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
6552 strcpy (xpm_syms
[i
].value
, SDATA (color
));
6556 /* Create a pixmap for the image, either from a file, or from a
6557 string buffer containing data in the same format as an XPM file. */
6558 #ifdef ALLOC_XPM_COLORS
6559 xpm_init_color_cache (f
, &attrs
);
6562 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6563 if (STRINGP (specified_file
))
6565 Lisp_Object file
= x_find_image_file (specified_file
);
6566 if (!STRINGP (file
))
6568 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6572 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6573 SDATA (file
), &img
->pixmap
, &img
->mask
,
6578 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
6579 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6581 &img
->pixmap
, &img
->mask
,
6585 if (rc
== XpmSuccess
)
6587 #ifdef ALLOC_XPM_COLORS
6588 img
->colors
= colors_in_color_table (&img
->ncolors
);
6589 #else /* not ALLOC_XPM_COLORS */
6592 img
->ncolors
= attrs
.nalloc_pixels
;
6593 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
6594 * sizeof *img
->colors
);
6595 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
6597 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
6598 #ifdef DEBUG_X_COLORS
6599 register_color (img
->colors
[i
]);
6602 #endif /* not ALLOC_XPM_COLORS */
6604 img
->width
= attrs
.width
;
6605 img
->height
= attrs
.height
;
6606 xassert (img
->width
> 0 && img
->height
> 0);
6608 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
6609 XpmFreeAttributes (&attrs
);
6616 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
6619 case XpmFileInvalid
:
6620 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
6624 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
6627 case XpmColorFailed
:
6628 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
6632 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
6637 #ifdef ALLOC_XPM_COLORS
6638 xpm_free_color_cache ();
6640 return rc
== XpmSuccess
;
6643 #endif /* HAVE_XPM != 0 */
6646 /***********************************************************************
6648 ***********************************************************************/
6650 /* An entry in the color table mapping an RGB color to a pixel color. */
6655 unsigned long pixel
;
6657 /* Next in color table collision list. */
6658 struct ct_color
*next
;
6661 /* The bucket vector size to use. Must be prime. */
6665 /* Value is a hash of the RGB color given by R, G, and B. */
6667 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
6669 /* The color hash table. */
6671 struct ct_color
**ct_table
;
6673 /* Number of entries in the color table. */
6675 int ct_colors_allocated
;
6677 /* Initialize the color table. */
6682 int size
= CT_SIZE
* sizeof (*ct_table
);
6683 ct_table
= (struct ct_color
**) xmalloc (size
);
6684 bzero (ct_table
, size
);
6685 ct_colors_allocated
= 0;
6689 /* Free memory associated with the color table. */
6695 struct ct_color
*p
, *next
;
6697 for (i
= 0; i
< CT_SIZE
; ++i
)
6698 for (p
= ct_table
[i
]; p
; p
= next
)
6709 /* Value is a pixel color for RGB color R, G, B on frame F. If an
6710 entry for that color already is in the color table, return the
6711 pixel color of that entry. Otherwise, allocate a new color for R,
6712 G, B, and make an entry in the color table. */
6714 static unsigned long
6715 lookup_rgb_color (f
, r
, g
, b
)
6719 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
6720 int i
= hash
% CT_SIZE
;
6723 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6724 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
6737 cmap
= FRAME_X_COLORMAP (f
);
6738 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6742 ++ct_colors_allocated
;
6744 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6748 p
->pixel
= color
.pixel
;
6749 p
->next
= ct_table
[i
];
6753 return FRAME_FOREGROUND_PIXEL (f
);
6760 /* Look up pixel color PIXEL which is used on frame F in the color
6761 table. If not already present, allocate it. Value is PIXEL. */
6763 static unsigned long
6764 lookup_pixel_color (f
, pixel
)
6766 unsigned long pixel
;
6768 int i
= pixel
% CT_SIZE
;
6771 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6772 if (p
->pixel
== pixel
)
6781 cmap
= FRAME_X_COLORMAP (f
);
6782 color
.pixel
= pixel
;
6783 x_query_color (f
, &color
);
6784 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
6788 ++ct_colors_allocated
;
6790 p
= (struct ct_color
*) xmalloc (sizeof *p
);
6795 p
->next
= ct_table
[i
];
6799 return FRAME_FOREGROUND_PIXEL (f
);
6806 /* Value is a vector of all pixel colors contained in the color table,
6807 allocated via xmalloc. Set *N to the number of colors. */
6809 static unsigned long *
6810 colors_in_color_table (n
)
6815 unsigned long *colors
;
6817 if (ct_colors_allocated
== 0)
6824 colors
= (unsigned long *) xmalloc (ct_colors_allocated
6826 *n
= ct_colors_allocated
;
6828 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
6829 for (p
= ct_table
[i
]; p
; p
= p
->next
)
6830 colors
[j
++] = p
->pixel
;
6838 /***********************************************************************
6840 ***********************************************************************/
6842 static XColor
*x_to_xcolors
P_ ((struct frame
*, struct image
*, int));
6843 static void x_from_xcolors
P_ ((struct frame
*, struct image
*, XColor
*));
6844 static void x_detect_edges
P_ ((struct frame
*, struct image
*, int[9], int));
6846 /* Non-zero means draw a cross on images having `:conversion
6849 int cross_disabled_images
;
6851 /* Edge detection matrices for different edge-detection
6854 static int emboss_matrix
[9] = {
6856 2, -1, 0, /* y - 1 */
6858 0, 1, -2 /* y + 1 */
6861 static int laplace_matrix
[9] = {
6863 1, 0, 0, /* y - 1 */
6865 0, 0, -1 /* y + 1 */
6868 /* Value is the intensity of the color whose red/green/blue values
6871 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
6874 /* On frame F, return an array of XColor structures describing image
6875 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
6876 non-zero means also fill the red/green/blue members of the XColor
6877 structures. Value is a pointer to the array of XColors structures,
6878 allocated with xmalloc; it must be freed by the caller. */
6881 x_to_xcolors (f
, img
, rgb_p
)
6890 colors
= (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *colors
);
6892 /* Get the X image IMG->pixmap. */
6893 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
6894 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
6896 /* Fill the `pixel' members of the XColor array. I wished there
6897 were an easy and portable way to circumvent XGetPixel. */
6899 for (y
= 0; y
< img
->height
; ++y
)
6903 for (x
= 0; x
< img
->width
; ++x
, ++p
)
6904 p
->pixel
= XGetPixel (ximg
, x
, y
);
6907 x_query_colors (f
, row
, img
->width
);
6910 XDestroyImage (ximg
);
6915 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
6916 RGB members are set. F is the frame on which this all happens.
6917 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
6920 x_from_xcolors (f
, img
, colors
)
6930 init_color_table ();
6932 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
6935 for (y
= 0; y
< img
->height
; ++y
)
6936 for (x
= 0; x
< img
->width
; ++x
, ++p
)
6938 unsigned long pixel
;
6939 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
6940 XPutPixel (oimg
, x
, y
, pixel
);
6944 x_clear_image_1 (f
, img
, 1, 0, 1);
6946 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
6947 x_destroy_x_image (oimg
);
6948 img
->pixmap
= pixmap
;
6949 img
->colors
= colors_in_color_table (&img
->ncolors
);
6950 free_color_table ();
6954 /* On frame F, perform edge-detection on image IMG.
6956 MATRIX is a nine-element array specifying the transformation
6957 matrix. See emboss_matrix for an example.
6959 COLOR_ADJUST is a color adjustment added to each pixel of the
6963 x_detect_edges (f
, img
, matrix
, color_adjust
)
6966 int matrix
[9], color_adjust
;
6968 XColor
*colors
= x_to_xcolors (f
, img
, 1);
6972 for (i
= sum
= 0; i
< 9; ++i
)
6973 sum
+= abs (matrix
[i
]);
6975 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
6977 new = (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *new);
6979 for (y
= 0; y
< img
->height
; ++y
)
6981 p
= COLOR (new, 0, y
);
6982 p
->red
= p
->green
= p
->blue
= 0xffff/2;
6983 p
= COLOR (new, img
->width
- 1, y
);
6984 p
->red
= p
->green
= p
->blue
= 0xffff/2;
6987 for (x
= 1; x
< img
->width
- 1; ++x
)
6989 p
= COLOR (new, x
, 0);
6990 p
->red
= p
->green
= p
->blue
= 0xffff/2;
6991 p
= COLOR (new, x
, img
->height
- 1);
6992 p
->red
= p
->green
= p
->blue
= 0xffff/2;
6995 for (y
= 1; y
< img
->height
- 1; ++y
)
6997 p
= COLOR (new, 1, y
);
6999 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
7001 int r
, g
, b
, y1
, x1
;
7004 for (y1
= y
- 1; y1
< y
+ 2; ++y1
)
7005 for (x1
= x
- 1; x1
< x
+ 2; ++x1
, ++i
)
7008 XColor
*t
= COLOR (colors
, x1
, y1
);
7009 r
+= matrix
[i
] * t
->red
;
7010 g
+= matrix
[i
] * t
->green
;
7011 b
+= matrix
[i
] * t
->blue
;
7014 r
= (r
/ sum
+ color_adjust
) & 0xffff;
7015 g
= (g
/ sum
+ color_adjust
) & 0xffff;
7016 b
= (b
/ sum
+ color_adjust
) & 0xffff;
7017 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
7022 x_from_xcolors (f
, img
, new);
7028 /* Perform the pre-defined `emboss' edge-detection on image IMG
7036 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
7040 /* Perform the pre-defined `laplace' edge-detection on image IMG
7048 x_detect_edges (f
, img
, laplace_matrix
, 45000);
7052 /* Perform edge-detection on image IMG on frame F, with specified
7053 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
7055 MATRIX must be either
7057 - a list of at least 9 numbers in row-major form
7058 - a vector of at least 9 numbers
7060 COLOR_ADJUST nil means use a default; otherwise it must be a
7064 x_edge_detection (f
, img
, matrix
, color_adjust
)
7067 Lisp_Object matrix
, color_adjust
;
7075 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
7076 ++i
, matrix
= XCDR (matrix
))
7077 trans
[i
] = XFLOATINT (XCAR (matrix
));
7079 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
7081 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
7082 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
7085 if (NILP (color_adjust
))
7086 color_adjust
= make_number (0xffff / 2);
7088 if (i
== 9 && NUMBERP (color_adjust
))
7089 x_detect_edges (f
, img
, trans
, (int) XFLOATINT (color_adjust
));
7093 /* Transform image IMG on frame F so that it looks disabled. */
7096 x_disable_image (f
, img
)
7100 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7102 if (dpyinfo
->n_planes
>= 2)
7104 /* Color (or grayscale). Convert to gray, and equalize. Just
7105 drawing such images with a stipple can look very odd, so
7106 we're using this method instead. */
7107 XColor
*colors
= x_to_xcolors (f
, img
, 1);
7109 const int h
= 15000;
7110 const int l
= 30000;
7112 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
7116 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
7117 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
7118 p
->red
= p
->green
= p
->blue
= i2
;
7121 x_from_xcolors (f
, img
, colors
);
7124 /* Draw a cross over the disabled image, if we must or if we
7126 if (dpyinfo
->n_planes
< 2 || cross_disabled_images
)
7128 Display
*dpy
= FRAME_X_DISPLAY (f
);
7131 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
7132 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
7133 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
7134 img
->width
- 1, img
->height
- 1);
7135 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
7141 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
7142 XSetForeground (dpy
, gc
, WHITE_PIX_DEFAULT (f
));
7143 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
7144 img
->width
- 1, img
->height
- 1);
7145 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
7153 /* Build a mask for image IMG which is used on frame F. FILE is the
7154 name of an image file, for error messages. HOW determines how to
7155 determine the background color of IMG. If it is a list '(R G B)',
7156 with R, G, and B being integers >= 0, take that as the color of the
7157 background. Otherwise, determine the background color of IMG
7158 heuristically. Value is non-zero if successful. */
7161 x_build_heuristic_mask (f
, img
, how
)
7166 Display
*dpy
= FRAME_X_DISPLAY (f
);
7167 XImage
*ximg
, *mask_img
;
7168 int x
, y
, rc
, use_img_background
;
7169 unsigned long bg
= 0;
7173 XFreePixmap (FRAME_X_DISPLAY (f
), img
->mask
);
7175 img
->background_transparent_valid
= 0;
7178 /* Create an image and pixmap serving as mask. */
7179 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
7180 &mask_img
, &img
->mask
);
7184 /* Get the X image of IMG->pixmap. */
7185 ximg
= XGetImage (dpy
, img
->pixmap
, 0, 0, img
->width
, img
->height
,
7188 /* Determine the background color of ximg. If HOW is `(R G B)'
7189 take that as color. Otherwise, use the image's background color. */
7190 use_img_background
= 1;
7196 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
7198 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
7202 if (i
== 3 && NILP (how
))
7204 char color_name
[30];
7205 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
7206 bg
= x_alloc_image_color (f
, img
, build_string (color_name
), 0);
7207 use_img_background
= 0;
7211 if (use_img_background
)
7212 bg
= four_corners_best (ximg
, img
->width
, img
->height
);
7214 /* Set all bits in mask_img to 1 whose color in ximg is different
7215 from the background color bg. */
7216 for (y
= 0; y
< img
->height
; ++y
)
7217 for (x
= 0; x
< img
->width
; ++x
)
7218 XPutPixel (mask_img
, x
, y
, XGetPixel (ximg
, x
, y
) != bg
);
7220 /* Fill in the background_transparent field while we have the mask handy. */
7221 image_background_transparent (img
, f
, mask_img
);
7223 /* Put mask_img into img->mask. */
7224 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
7225 x_destroy_x_image (mask_img
);
7226 XDestroyImage (ximg
);
7233 /***********************************************************************
7234 PBM (mono, gray, color)
7235 ***********************************************************************/
7237 static int pbm_image_p
P_ ((Lisp_Object object
));
7238 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
7239 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
7241 /* The symbol `pbm' identifying images of this type. */
7245 /* Indices of image specification fields in gs_format, below. */
7247 enum pbm_keyword_index
7263 /* Vector of image_keyword structures describing the format
7264 of valid user-defined image specifications. */
7266 static struct image_keyword pbm_format
[PBM_LAST
] =
7268 {":type", IMAGE_SYMBOL_VALUE
, 1},
7269 {":file", IMAGE_STRING_VALUE
, 0},
7270 {":data", IMAGE_STRING_VALUE
, 0},
7271 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7272 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7273 {":relief", IMAGE_INTEGER_VALUE
, 0},
7274 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7275 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7276 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7277 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
7278 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7281 /* Structure describing the image type `pbm'. */
7283 static struct image_type pbm_type
=
7293 /* Return non-zero if OBJECT is a valid PBM image specification. */
7296 pbm_image_p (object
)
7299 struct image_keyword fmt
[PBM_LAST
];
7301 bcopy (pbm_format
, fmt
, sizeof fmt
);
7303 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
7306 /* Must specify either :data or :file. */
7307 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
7311 /* Scan a decimal number from *S and return it. Advance *S while
7312 reading the number. END is the end of the string. Value is -1 at
7316 pbm_scan_number (s
, end
)
7317 unsigned char **s
, *end
;
7319 int c
= 0, val
= -1;
7323 /* Skip white-space. */
7324 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
7329 /* Skip comment to end of line. */
7330 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
7333 else if (isdigit (c
))
7335 /* Read decimal number. */
7337 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
7338 val
= 10 * val
+ c
- '0';
7349 /* Load PBM image IMG for use on frame F. */
7357 int width
, height
, max_color_idx
= 0;
7359 Lisp_Object file
, specified_file
;
7360 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
7361 struct gcpro gcpro1
;
7362 unsigned char *contents
= NULL
;
7363 unsigned char *end
, *p
;
7366 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7370 if (STRINGP (specified_file
))
7372 file
= x_find_image_file (specified_file
);
7373 if (!STRINGP (file
))
7375 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7380 contents
= slurp_file (SDATA (file
), &size
);
7381 if (contents
== NULL
)
7383 image_error ("Error reading `%s'", file
, Qnil
);
7389 end
= contents
+ size
;
7394 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7396 end
= p
+ SBYTES (data
);
7399 /* Check magic number. */
7400 if (end
- p
< 2 || *p
++ != 'P')
7402 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7412 raw_p
= 0, type
= PBM_MONO
;
7416 raw_p
= 0, type
= PBM_GRAY
;
7420 raw_p
= 0, type
= PBM_COLOR
;
7424 raw_p
= 1, type
= PBM_MONO
;
7428 raw_p
= 1, type
= PBM_GRAY
;
7432 raw_p
= 1, type
= PBM_COLOR
;
7436 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
7440 /* Read width, height, maximum color-component. Characters
7441 starting with `#' up to the end of a line are ignored. */
7442 width
= pbm_scan_number (&p
, end
);
7443 height
= pbm_scan_number (&p
, end
);
7445 if (type
!= PBM_MONO
)
7447 max_color_idx
= pbm_scan_number (&p
, end
);
7448 if (raw_p
&& max_color_idx
> 255)
7449 max_color_idx
= 255;
7454 || (type
!= PBM_MONO
&& max_color_idx
< 0))
7457 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7458 &ximg
, &img
->pixmap
))
7461 /* Initialize the color hash table. */
7462 init_color_table ();
7464 if (type
== PBM_MONO
)
7467 struct image_keyword fmt
[PBM_LAST
];
7468 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
7469 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
7471 /* Parse the image specification. */
7472 bcopy (pbm_format
, fmt
, sizeof fmt
);
7473 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
7475 /* Get foreground and background colors, maybe allocate colors. */
7476 if (fmt
[PBM_FOREGROUND
].count
7477 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
7478 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
7479 if (fmt
[PBM_BACKGROUND
].count
7480 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
7482 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
7483 img
->background
= bg
;
7484 img
->background_valid
= 1;
7487 for (y
= 0; y
< height
; ++y
)
7488 for (x
= 0; x
< width
; ++x
)
7498 g
= pbm_scan_number (&p
, end
);
7500 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
7505 for (y
= 0; y
< height
; ++y
)
7506 for (x
= 0; x
< width
; ++x
)
7510 if (type
== PBM_GRAY
)
7511 r
= g
= b
= raw_p
? *p
++ : pbm_scan_number (&p
, end
);
7520 r
= pbm_scan_number (&p
, end
);
7521 g
= pbm_scan_number (&p
, end
);
7522 b
= pbm_scan_number (&p
, end
);
7525 if (r
< 0 || g
< 0 || b
< 0)
7529 XDestroyImage (ximg
);
7530 image_error ("Invalid pixel value in image `%s'",
7535 /* RGB values are now in the range 0..max_color_idx.
7536 Scale this to the range 0..0xffff supported by X. */
7537 r
= (double) r
* 65535 / max_color_idx
;
7538 g
= (double) g
* 65535 / max_color_idx
;
7539 b
= (double) b
* 65535 / max_color_idx
;
7540 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
7544 /* Store in IMG->colors the colors allocated for the image, and
7545 free the color table. */
7546 img
->colors
= colors_in_color_table (&img
->ncolors
);
7547 free_color_table ();
7549 /* Maybe fill in the background field while we have ximg handy. */
7550 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7551 IMAGE_BACKGROUND (img
, f
, ximg
);
7553 /* Put the image into a pixmap. */
7554 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7555 x_destroy_x_image (ximg
);
7558 img
->height
= height
;
7567 /***********************************************************************
7569 ***********************************************************************/
7573 #if defined HAVE_LIBPNG_PNG_H
7574 # include <libpng/png.h>
7579 /* Function prototypes. */
7581 static int png_image_p
P_ ((Lisp_Object object
));
7582 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
7584 /* The symbol `png' identifying images of this type. */
7588 /* Indices of image specification fields in png_format, below. */
7590 enum png_keyword_index
7605 /* Vector of image_keyword structures describing the format
7606 of valid user-defined image specifications. */
7608 static struct image_keyword png_format
[PNG_LAST
] =
7610 {":type", IMAGE_SYMBOL_VALUE
, 1},
7611 {":data", IMAGE_STRING_VALUE
, 0},
7612 {":file", IMAGE_STRING_VALUE
, 0},
7613 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7614 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7615 {":relief", IMAGE_INTEGER_VALUE
, 0},
7616 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7617 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7618 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7619 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7622 /* Structure describing the image type `png'. */
7624 static struct image_type png_type
=
7634 /* Return non-zero if OBJECT is a valid PNG image specification. */
7637 png_image_p (object
)
7640 struct image_keyword fmt
[PNG_LAST
];
7641 bcopy (png_format
, fmt
, sizeof fmt
);
7643 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
7646 /* Must specify either the :data or :file keyword. */
7647 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
7651 /* Error and warning handlers installed when the PNG library
7655 my_png_error (png_ptr
, msg
)
7656 png_struct
*png_ptr
;
7659 xassert (png_ptr
!= NULL
);
7660 image_error ("PNG error: %s", build_string (msg
), Qnil
);
7661 longjmp (png_ptr
->jmpbuf
, 1);
7666 my_png_warning (png_ptr
, msg
)
7667 png_struct
*png_ptr
;
7670 xassert (png_ptr
!= NULL
);
7671 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
7674 /* Memory source for PNG decoding. */
7676 struct png_memory_storage
7678 unsigned char *bytes
; /* The data */
7679 size_t len
; /* How big is it? */
7680 int index
; /* Where are we? */
7684 /* Function set as reader function when reading PNG image from memory.
7685 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
7686 bytes from the input to DATA. */
7689 png_read_from_memory (png_ptr
, data
, length
)
7690 png_structp png_ptr
;
7694 struct png_memory_storage
*tbr
7695 = (struct png_memory_storage
*) png_get_io_ptr (png_ptr
);
7697 if (length
> tbr
->len
- tbr
->index
)
7698 png_error (png_ptr
, "Read error");
7700 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
7701 tbr
->index
= tbr
->index
+ length
;
7704 /* Load PNG image IMG for use on frame F. Value is non-zero if
7712 Lisp_Object file
, specified_file
;
7713 Lisp_Object specified_data
;
7715 XImage
*ximg
, *mask_img
= NULL
;
7716 struct gcpro gcpro1
;
7717 png_struct
*png_ptr
= NULL
;
7718 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
7719 FILE *volatile fp
= NULL
;
7721 png_byte
* volatile pixels
= NULL
;
7722 png_byte
** volatile rows
= NULL
;
7723 png_uint_32 width
, height
;
7724 int bit_depth
, color_type
, interlace_type
;
7726 png_uint_32 row_bytes
;
7728 double screen_gamma
;
7729 struct png_memory_storage tbr
; /* Data to be read */
7731 /* Find out what file to load. */
7732 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7733 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7737 if (NILP (specified_data
))
7739 file
= x_find_image_file (specified_file
);
7740 if (!STRINGP (file
))
7742 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7747 /* Open the image file. */
7748 fp
= fopen (SDATA (file
), "rb");
7751 image_error ("Cannot open image file `%s'", file
, Qnil
);
7757 /* Check PNG signature. */
7758 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
7759 || !png_check_sig (sig
, sizeof sig
))
7761 image_error ("Not a PNG file: `%s'", file
, Qnil
);
7769 /* Read from memory. */
7770 tbr
.bytes
= SDATA (specified_data
);
7771 tbr
.len
= SBYTES (specified_data
);
7774 /* Check PNG signature. */
7775 if (tbr
.len
< sizeof sig
7776 || !png_check_sig (tbr
.bytes
, sizeof sig
))
7778 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
7783 /* Need to skip past the signature. */
7784 tbr
.bytes
+= sizeof (sig
);
7787 /* Initialize read and info structs for PNG lib. */
7788 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
, NULL
,
7789 my_png_error
, my_png_warning
);
7792 if (fp
) fclose (fp
);
7797 info_ptr
= png_create_info_struct (png_ptr
);
7800 png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
7801 if (fp
) fclose (fp
);
7806 end_info
= png_create_info_struct (png_ptr
);
7809 png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
7810 if (fp
) fclose (fp
);
7815 /* Set error jump-back. We come back here when the PNG library
7816 detects an error. */
7817 if (setjmp (png_ptr
->jmpbuf
))
7821 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
7824 if (fp
) fclose (fp
);
7829 /* Read image info. */
7830 if (!NILP (specified_data
))
7831 png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
7833 png_init_io (png_ptr
, fp
);
7835 png_set_sig_bytes (png_ptr
, sizeof sig
);
7836 png_read_info (png_ptr
, info_ptr
);
7837 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
7838 &interlace_type
, NULL
, NULL
);
7840 /* If image contains simply transparency data, we prefer to
7841 construct a clipping mask. */
7842 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
7847 /* This function is easier to write if we only have to handle
7848 one data format: RGB or RGBA with 8 bits per channel. Let's
7849 transform other formats into that format. */
7851 /* Strip more than 8 bits per channel. */
7852 if (bit_depth
== 16)
7853 png_set_strip_16 (png_ptr
);
7855 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
7857 png_set_expand (png_ptr
);
7859 /* Convert grayscale images to RGB. */
7860 if (color_type
== PNG_COLOR_TYPE_GRAY
7861 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
7862 png_set_gray_to_rgb (png_ptr
);
7864 screen_gamma
= (f
->gamma
? 1 / f
->gamma
/ 0.45455 : 2.2);
7866 #if 0 /* Avoid double gamma correction for PNG images. */
7867 { /* Tell the PNG lib to handle gamma correction for us. */
7870 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
7871 if (png_get_sRGB (png_ptr
, info_ptr
, &intent
))
7872 /* The libpng documentation says this is right in this case. */
7873 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7876 if (png_get_gAMA (png_ptr
, info_ptr
, &image_gamma
))
7877 /* Image contains gamma information. */
7878 png_set_gamma (png_ptr
, screen_gamma
, image_gamma
);
7880 /* Use the standard default for the image gamma. */
7881 png_set_gamma (png_ptr
, screen_gamma
, 0.45455);
7885 /* Handle alpha channel by combining the image with a background
7886 color. Do this only if a real alpha channel is supplied. For
7887 simple transparency, we prefer a clipping mask. */
7890 png_color_16
*image_bg
;
7891 Lisp_Object specified_bg
7892 = image_spec_value (img
->spec
, QCbackground
, NULL
);
7894 if (STRINGP (specified_bg
))
7895 /* The user specified `:background', use that. */
7898 if (x_defined_color (f
, SDATA (specified_bg
), &color
, 0))
7900 png_color_16 user_bg
;
7902 bzero (&user_bg
, sizeof user_bg
);
7903 user_bg
.red
= color
.red
;
7904 user_bg
.green
= color
.green
;
7905 user_bg
.blue
= color
.blue
;
7907 png_set_background (png_ptr
, &user_bg
,
7908 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7911 else if (png_get_bKGD (png_ptr
, info_ptr
, &image_bg
))
7912 /* Image contains a background color with which to
7913 combine the image. */
7914 png_set_background (png_ptr
, image_bg
,
7915 PNG_BACKGROUND_GAMMA_FILE
, 1, 1.0);
7918 /* Image does not contain a background color with which
7919 to combine the image data via an alpha channel. Use
7920 the frame's background instead. */
7923 png_color_16 frame_background
;
7925 cmap
= FRAME_X_COLORMAP (f
);
7926 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7927 x_query_color (f
, &color
);
7929 bzero (&frame_background
, sizeof frame_background
);
7930 frame_background
.red
= color
.red
;
7931 frame_background
.green
= color
.green
;
7932 frame_background
.blue
= color
.blue
;
7934 png_set_background (png_ptr
, &frame_background
,
7935 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
7939 /* Update info structure. */
7940 png_read_update_info (png_ptr
, info_ptr
);
7942 /* Get number of channels. Valid values are 1 for grayscale images
7943 and images with a palette, 2 for grayscale images with transparency
7944 information (alpha channel), 3 for RGB images, and 4 for RGB
7945 images with alpha channel, i.e. RGBA. If conversions above were
7946 sufficient we should only have 3 or 4 channels here. */
7947 channels
= png_get_channels (png_ptr
, info_ptr
);
7948 xassert (channels
== 3 || channels
== 4);
7950 /* Number of bytes needed for one row of the image. */
7951 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
7953 /* Allocate memory for the image. */
7954 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
7955 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
7956 for (i
= 0; i
< height
; ++i
)
7957 rows
[i
] = pixels
+ i
* row_bytes
;
7959 /* Read the entire image. */
7960 png_read_image (png_ptr
, rows
);
7961 png_read_end (png_ptr
, info_ptr
);
7968 /* Create the X image and pixmap. */
7969 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
7973 /* Create an image and pixmap serving as mask if the PNG image
7974 contains an alpha channel. */
7977 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
7978 &mask_img
, &img
->mask
))
7980 x_destroy_x_image (ximg
);
7981 XFreePixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
7986 /* Fill the X image and mask from PNG data. */
7987 init_color_table ();
7989 for (y
= 0; y
< height
; ++y
)
7991 png_byte
*p
= rows
[y
];
7993 for (x
= 0; x
< width
; ++x
)
8000 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
8002 /* An alpha channel, aka mask channel, associates variable
8003 transparency with an image. Where other image formats
8004 support binary transparency---fully transparent or fully
8005 opaque---PNG allows up to 254 levels of partial transparency.
8006 The PNG library implements partial transparency by combining
8007 the image with a specified background color.
8009 I'm not sure how to handle this here nicely: because the
8010 background on which the image is displayed may change, for
8011 real alpha channel support, it would be necessary to create
8012 a new image for each possible background.
8014 What I'm doing now is that a mask is created if we have
8015 boolean transparency information. Otherwise I'm using
8016 the frame's background color to combine the image with. */
8021 XPutPixel (mask_img
, x
, y
, *p
> 0);
8027 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8028 /* Set IMG's background color from the PNG image, unless the user
8032 if (png_get_bKGD (png_ptr
, info_ptr
, &bg
))
8034 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
8035 img
->background_valid
= 1;
8039 /* Remember colors allocated for this image. */
8040 img
->colors
= colors_in_color_table (&img
->ncolors
);
8041 free_color_table ();
8044 png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
8049 img
->height
= height
;
8051 /* Maybe fill in the background field while we have ximg handy. */
8052 IMAGE_BACKGROUND (img
, f
, ximg
);
8054 /* Put the image into the pixmap, then free the X image and its buffer. */
8055 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8056 x_destroy_x_image (ximg
);
8058 /* Same for the mask. */
8061 /* Fill in the background_transparent field while we have the mask
8063 image_background_transparent (img
, f
, mask_img
);
8065 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
8066 x_destroy_x_image (mask_img
);
8073 #endif /* HAVE_PNG != 0 */
8077 /***********************************************************************
8079 ***********************************************************************/
8083 /* Work around a warning about HAVE_STDLIB_H being redefined in
8085 #ifdef HAVE_STDLIB_H
8086 #define HAVE_STDLIB_H_1
8087 #undef HAVE_STDLIB_H
8088 #endif /* HAVE_STLIB_H */
8090 #include <jpeglib.h>
8094 #ifdef HAVE_STLIB_H_1
8095 #define HAVE_STDLIB_H 1
8098 static int jpeg_image_p
P_ ((Lisp_Object object
));
8099 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
8101 /* The symbol `jpeg' identifying images of this type. */
8105 /* Indices of image specification fields in gs_format, below. */
8107 enum jpeg_keyword_index
8116 JPEG_HEURISTIC_MASK
,
8122 /* Vector of image_keyword structures describing the format
8123 of valid user-defined image specifications. */
8125 static struct image_keyword jpeg_format
[JPEG_LAST
] =
8127 {":type", IMAGE_SYMBOL_VALUE
, 1},
8128 {":data", IMAGE_STRING_VALUE
, 0},
8129 {":file", IMAGE_STRING_VALUE
, 0},
8130 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8131 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8132 {":relief", IMAGE_INTEGER_VALUE
, 0},
8133 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8134 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8135 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8136 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8139 /* Structure describing the image type `jpeg'. */
8141 static struct image_type jpeg_type
=
8151 /* Return non-zero if OBJECT is a valid JPEG image specification. */
8154 jpeg_image_p (object
)
8157 struct image_keyword fmt
[JPEG_LAST
];
8159 bcopy (jpeg_format
, fmt
, sizeof fmt
);
8161 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
8164 /* Must specify either the :data or :file keyword. */
8165 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
8169 struct my_jpeg_error_mgr
8171 struct jpeg_error_mgr pub
;
8172 jmp_buf setjmp_buffer
;
8177 my_error_exit (cinfo
)
8180 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
8181 longjmp (mgr
->setjmp_buffer
, 1);
8185 /* Init source method for JPEG data source manager. Called by
8186 jpeg_read_header() before any data is actually read. See
8187 libjpeg.doc from the JPEG lib distribution. */
8190 our_init_source (cinfo
)
8191 j_decompress_ptr cinfo
;
8196 /* Fill input buffer method for JPEG data source manager. Called
8197 whenever more data is needed. We read the whole image in one step,
8198 so this only adds a fake end of input marker at the end. */
8201 our_fill_input_buffer (cinfo
)
8202 j_decompress_ptr cinfo
;
8204 /* Insert a fake EOI marker. */
8205 struct jpeg_source_mgr
*src
= cinfo
->src
;
8206 static JOCTET buffer
[2];
8208 buffer
[0] = (JOCTET
) 0xFF;
8209 buffer
[1] = (JOCTET
) JPEG_EOI
;
8211 src
->next_input_byte
= buffer
;
8212 src
->bytes_in_buffer
= 2;
8217 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
8218 is the JPEG data source manager. */
8221 our_skip_input_data (cinfo
, num_bytes
)
8222 j_decompress_ptr cinfo
;
8225 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8229 if (num_bytes
> src
->bytes_in_buffer
)
8230 ERREXIT (cinfo
, JERR_INPUT_EOF
);
8232 src
->bytes_in_buffer
-= num_bytes
;
8233 src
->next_input_byte
+= num_bytes
;
8238 /* Method to terminate data source. Called by
8239 jpeg_finish_decompress() after all data has been processed. */
8242 our_term_source (cinfo
)
8243 j_decompress_ptr cinfo
;
8248 /* Set up the JPEG lib for reading an image from DATA which contains
8249 LEN bytes. CINFO is the decompression info structure created for
8250 reading the image. */
8253 jpeg_memory_src (cinfo
, data
, len
)
8254 j_decompress_ptr cinfo
;
8258 struct jpeg_source_mgr
*src
;
8260 if (cinfo
->src
== NULL
)
8262 /* First time for this JPEG object? */
8263 cinfo
->src
= (struct jpeg_source_mgr
*)
8264 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
8265 sizeof (struct jpeg_source_mgr
));
8266 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8267 src
->next_input_byte
= data
;
8270 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
8271 src
->init_source
= our_init_source
;
8272 src
->fill_input_buffer
= our_fill_input_buffer
;
8273 src
->skip_input_data
= our_skip_input_data
;
8274 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
8275 src
->term_source
= our_term_source
;
8276 src
->bytes_in_buffer
= len
;
8277 src
->next_input_byte
= data
;
8281 /* Load image IMG for use on frame F. Patterned after example.c
8282 from the JPEG lib. */
8289 struct jpeg_decompress_struct cinfo
;
8290 struct my_jpeg_error_mgr mgr
;
8291 Lisp_Object file
, specified_file
;
8292 Lisp_Object specified_data
;
8293 FILE * volatile fp
= NULL
;
8295 int row_stride
, x
, y
;
8296 XImage
*ximg
= NULL
;
8298 unsigned long *colors
;
8300 struct gcpro gcpro1
;
8302 /* Open the JPEG file. */
8303 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8304 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8308 if (NILP (specified_data
))
8310 file
= x_find_image_file (specified_file
);
8311 if (!STRINGP (file
))
8313 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8318 fp
= fopen (SDATA (file
), "r");
8321 image_error ("Cannot open `%s'", file
, Qnil
);
8327 /* Customize libjpeg's error handling to call my_error_exit when an
8328 error is detected. This function will perform a longjmp. */
8329 cinfo
.err
= jpeg_std_error (&mgr
.pub
);
8330 mgr
.pub
.error_exit
= my_error_exit
;
8332 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
8336 /* Called from my_error_exit. Display a JPEG error. */
8337 char buffer
[JMSG_LENGTH_MAX
];
8338 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
8339 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
8340 build_string (buffer
));
8343 /* Close the input file and destroy the JPEG object. */
8345 fclose ((FILE *) fp
);
8346 jpeg_destroy_decompress (&cinfo
);
8348 /* If we already have an XImage, free that. */
8349 x_destroy_x_image (ximg
);
8351 /* Free pixmap and colors. */
8352 x_clear_image (f
, img
);
8358 /* Create the JPEG decompression object. Let it read from fp.
8359 Read the JPEG image header. */
8360 jpeg_create_decompress (&cinfo
);
8362 if (NILP (specified_data
))
8363 jpeg_stdio_src (&cinfo
, (FILE *) fp
);
8365 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
8366 SBYTES (specified_data
));
8368 jpeg_read_header (&cinfo
, TRUE
);
8370 /* Customize decompression so that color quantization will be used.
8371 Start decompression. */
8372 cinfo
.quantize_colors
= TRUE
;
8373 jpeg_start_decompress (&cinfo
);
8374 width
= img
->width
= cinfo
.output_width
;
8375 height
= img
->height
= cinfo
.output_height
;
8377 /* Create X image and pixmap. */
8378 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8379 longjmp (mgr
.setjmp_buffer
, 2);
8381 /* Allocate colors. When color quantization is used,
8382 cinfo.actual_number_of_colors has been set with the number of
8383 colors generated, and cinfo.colormap is a two-dimensional array
8384 of color indices in the range 0..cinfo.actual_number_of_colors.
8385 No more than 255 colors will be generated. */
8389 if (cinfo
.out_color_components
> 2)
8390 ir
= 0, ig
= 1, ib
= 2;
8391 else if (cinfo
.out_color_components
> 1)
8392 ir
= 0, ig
= 1, ib
= 0;
8394 ir
= 0, ig
= 0, ib
= 0;
8396 /* Use the color table mechanism because it handles colors that
8397 cannot be allocated nicely. Such colors will be replaced with
8398 a default color, and we don't have to care about which colors
8399 can be freed safely, and which can't. */
8400 init_color_table ();
8401 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
8404 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
8406 /* Multiply RGB values with 255 because X expects RGB values
8407 in the range 0..0xffff. */
8408 int r
= cinfo
.colormap
[ir
][i
] << 8;
8409 int g
= cinfo
.colormap
[ig
][i
] << 8;
8410 int b
= cinfo
.colormap
[ib
][i
] << 8;
8411 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
8414 /* Remember those colors actually allocated. */
8415 img
->colors
= colors_in_color_table (&img
->ncolors
);
8416 free_color_table ();
8420 row_stride
= width
* cinfo
.output_components
;
8421 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
8423 for (y
= 0; y
< height
; ++y
)
8425 jpeg_read_scanlines (&cinfo
, buffer
, 1);
8426 for (x
= 0; x
< cinfo
.output_width
; ++x
)
8427 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
8431 jpeg_finish_decompress (&cinfo
);
8432 jpeg_destroy_decompress (&cinfo
);
8434 fclose ((FILE *) fp
);
8436 /* Maybe fill in the background field while we have ximg handy. */
8437 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8438 IMAGE_BACKGROUND (img
, f
, ximg
);
8440 /* Put the image into the pixmap. */
8441 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8442 x_destroy_x_image (ximg
);
8447 #endif /* HAVE_JPEG */
8451 /***********************************************************************
8453 ***********************************************************************/
8459 static int tiff_image_p
P_ ((Lisp_Object object
));
8460 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
8462 /* The symbol `tiff' identifying images of this type. */
8466 /* Indices of image specification fields in tiff_format, below. */
8468 enum tiff_keyword_index
8477 TIFF_HEURISTIC_MASK
,
8483 /* Vector of image_keyword structures describing the format
8484 of valid user-defined image specifications. */
8486 static struct image_keyword tiff_format
[TIFF_LAST
] =
8488 {":type", IMAGE_SYMBOL_VALUE
, 1},
8489 {":data", IMAGE_STRING_VALUE
, 0},
8490 {":file", IMAGE_STRING_VALUE
, 0},
8491 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8492 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8493 {":relief", IMAGE_INTEGER_VALUE
, 0},
8494 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8495 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8496 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8497 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8500 /* Structure describing the image type `tiff'. */
8502 static struct image_type tiff_type
=
8512 /* Return non-zero if OBJECT is a valid TIFF image specification. */
8515 tiff_image_p (object
)
8518 struct image_keyword fmt
[TIFF_LAST
];
8519 bcopy (tiff_format
, fmt
, sizeof fmt
);
8521 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
8524 /* Must specify either the :data or :file keyword. */
8525 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
8529 /* Reading from a memory buffer for TIFF images Based on the PNG
8530 memory source, but we have to provide a lot of extra functions.
8533 We really only need to implement read and seek, but I am not
8534 convinced that the TIFF library is smart enough not to destroy
8535 itself if we only hand it the function pointers we need to
8540 unsigned char *bytes
;
8548 tiff_read_from_memory (data
, buf
, size
)
8553 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8555 if (size
> src
->len
- src
->index
)
8557 bcopy (src
->bytes
+ src
->index
, buf
, size
);
8564 tiff_write_from_memory (data
, buf
, size
)
8574 tiff_seek_in_memory (data
, off
, whence
)
8579 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
8584 case SEEK_SET
: /* Go from beginning of source. */
8588 case SEEK_END
: /* Go from end of source. */
8589 idx
= src
->len
+ off
;
8592 case SEEK_CUR
: /* Go from current position. */
8593 idx
= src
->index
+ off
;
8596 default: /* Invalid `whence'. */
8600 if (idx
> src
->len
|| idx
< 0)
8609 tiff_close_memory (data
)
8618 tiff_mmap_memory (data
, pbase
, psize
)
8623 /* It is already _IN_ memory. */
8629 tiff_unmap_memory (data
, base
, size
)
8634 /* We don't need to do this. */
8639 tiff_size_of_memory (data
)
8642 return ((tiff_memory_source
*) data
)->len
;
8647 tiff_error_handler (title
, format
, ap
)
8648 const char *title
, *format
;
8654 len
= sprintf (buf
, "TIFF error: %s ", title
);
8655 vsprintf (buf
+ len
, format
, ap
);
8656 add_to_log (buf
, Qnil
, Qnil
);
8661 tiff_warning_handler (title
, format
, ap
)
8662 const char *title
, *format
;
8668 len
= sprintf (buf
, "TIFF warning: %s ", title
);
8669 vsprintf (buf
+ len
, format
, ap
);
8670 add_to_log (buf
, Qnil
, Qnil
);
8674 /* Load TIFF image IMG for use on frame F. Value is non-zero if
8682 Lisp_Object file
, specified_file
;
8683 Lisp_Object specified_data
;
8685 int width
, height
, x
, y
;
8689 struct gcpro gcpro1
;
8690 tiff_memory_source memsrc
;
8692 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8693 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8697 TIFFSetErrorHandler (tiff_error_handler
);
8698 TIFFSetWarningHandler (tiff_warning_handler
);
8700 if (NILP (specified_data
))
8702 /* Read from a file */
8703 file
= x_find_image_file (specified_file
);
8704 if (!STRINGP (file
))
8706 image_error ("Cannot find image file `%s'", file
, Qnil
);
8711 /* Try to open the image file. */
8712 tiff
= TIFFOpen (SDATA (file
), "r");
8715 image_error ("Cannot open `%s'", file
, Qnil
);
8722 /* Memory source! */
8723 memsrc
.bytes
= SDATA (specified_data
);
8724 memsrc
.len
= SBYTES (specified_data
);
8727 tiff
= TIFFClientOpen ("memory_source", "r", &memsrc
,
8728 (TIFFReadWriteProc
) tiff_read_from_memory
,
8729 (TIFFReadWriteProc
) tiff_write_from_memory
,
8730 tiff_seek_in_memory
,
8732 tiff_size_of_memory
,
8738 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
8744 /* Get width and height of the image, and allocate a raster buffer
8745 of width x height 32-bit values. */
8746 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
8747 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
8748 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
8750 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
8754 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
8760 /* Create the X image and pixmap. */
8761 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8768 /* Initialize the color table. */
8769 init_color_table ();
8771 /* Process the pixel raster. Origin is in the lower-left corner. */
8772 for (y
= 0; y
< height
; ++y
)
8774 uint32
*row
= buf
+ y
* width
;
8776 for (x
= 0; x
< width
; ++x
)
8778 uint32 abgr
= row
[x
];
8779 int r
= TIFFGetR (abgr
) << 8;
8780 int g
= TIFFGetG (abgr
) << 8;
8781 int b
= TIFFGetB (abgr
) << 8;
8782 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
8786 /* Remember the colors allocated for the image. Free the color table. */
8787 img
->colors
= colors_in_color_table (&img
->ncolors
);
8788 free_color_table ();
8791 img
->height
= height
;
8793 /* Maybe fill in the background field while we have ximg handy. */
8794 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8795 IMAGE_BACKGROUND (img
, f
, ximg
);
8797 /* Put the image into the pixmap, then free the X image and its buffer. */
8798 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8799 x_destroy_x_image (ximg
);
8806 #endif /* HAVE_TIFF != 0 */
8810 /***********************************************************************
8812 ***********************************************************************/
8816 #include <gif_lib.h>
8818 static int gif_image_p
P_ ((Lisp_Object object
));
8819 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
8821 /* The symbol `gif' identifying images of this type. */
8825 /* Indices of image specification fields in gif_format, below. */
8827 enum gif_keyword_index
8843 /* Vector of image_keyword structures describing the format
8844 of valid user-defined image specifications. */
8846 static struct image_keyword gif_format
[GIF_LAST
] =
8848 {":type", IMAGE_SYMBOL_VALUE
, 1},
8849 {":data", IMAGE_STRING_VALUE
, 0},
8850 {":file", IMAGE_STRING_VALUE
, 0},
8851 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8852 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8853 {":relief", IMAGE_INTEGER_VALUE
, 0},
8854 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8855 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8856 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8857 {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
8858 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8861 /* Structure describing the image type `gif'. */
8863 static struct image_type gif_type
=
8873 /* Return non-zero if OBJECT is a valid GIF image specification. */
8876 gif_image_p (object
)
8879 struct image_keyword fmt
[GIF_LAST
];
8880 bcopy (gif_format
, fmt
, sizeof fmt
);
8882 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
8885 /* Must specify either the :data or :file keyword. */
8886 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
8890 /* Reading a GIF image from memory
8891 Based on the PNG memory stuff to a certain extent. */
8895 unsigned char *bytes
;
8902 /* Make the current memory source available to gif_read_from_memory.
8903 It's done this way because not all versions of libungif support
8904 a UserData field in the GifFileType structure. */
8905 static gif_memory_source
*current_gif_memory_src
;
8908 gif_read_from_memory (file
, buf
, len
)
8913 gif_memory_source
*src
= current_gif_memory_src
;
8915 if (len
> src
->len
- src
->index
)
8918 bcopy (src
->bytes
+ src
->index
, buf
, len
);
8924 /* Load GIF image IMG for use on frame F. Value is non-zero if
8932 Lisp_Object file
, specified_file
;
8933 Lisp_Object specified_data
;
8934 int rc
, width
, height
, x
, y
, i
;
8936 ColorMapObject
*gif_color_map
;
8937 unsigned long pixel_colors
[256];
8939 struct gcpro gcpro1
;
8941 int ino
, image_left
, image_top
, image_width
, image_height
;
8942 gif_memory_source memsrc
;
8943 unsigned char *raster
;
8945 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
8946 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8950 if (NILP (specified_data
))
8952 file
= x_find_image_file (specified_file
);
8953 if (!STRINGP (file
))
8955 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
8960 /* Open the GIF file. */
8961 gif
= DGifOpenFileName (SDATA (file
));
8964 image_error ("Cannot open `%s'", file
, Qnil
);
8971 /* Read from memory! */
8972 current_gif_memory_src
= &memsrc
;
8973 memsrc
.bytes
= SDATA (specified_data
);
8974 memsrc
.len
= SBYTES (specified_data
);
8977 gif
= DGifOpen(&memsrc
, gif_read_from_memory
);
8980 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
8986 /* Read entire contents. */
8987 rc
= DGifSlurp (gif
);
8988 if (rc
== GIF_ERROR
)
8990 image_error ("Error reading `%s'", img
->spec
, Qnil
);
8991 DGifCloseFile (gif
);
8996 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
8997 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
8998 if (ino
>= gif
->ImageCount
)
9000 image_error ("Invalid image number `%s' in image `%s'",
9002 DGifCloseFile (gif
);
9007 width
= img
->width
= max (gif
->SWidth
, gif
->Image
.Left
+ gif
->Image
.Width
);
9008 height
= img
->height
= max (gif
->SHeight
, gif
->Image
.Top
+ gif
->Image
.Height
);
9010 /* Create the X image and pixmap. */
9011 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
9013 DGifCloseFile (gif
);
9018 /* Allocate colors. */
9019 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
9021 gif_color_map
= gif
->SColorMap
;
9022 init_color_table ();
9023 bzero (pixel_colors
, sizeof pixel_colors
);
9025 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
9027 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
9028 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
9029 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
9030 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
9033 img
->colors
= colors_in_color_table (&img
->ncolors
);
9034 free_color_table ();
9036 /* Clear the part of the screen image that are not covered by
9037 the image from the GIF file. Full animated GIF support
9038 requires more than can be done here (see the gif89 spec,
9039 disposal methods). Let's simply assume that the part
9040 not covered by a sub-image is in the frame's background color. */
9041 image_top
= gif
->SavedImages
[ino
].ImageDesc
.Top
;
9042 image_left
= gif
->SavedImages
[ino
].ImageDesc
.Left
;
9043 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
9044 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
9046 for (y
= 0; y
< image_top
; ++y
)
9047 for (x
= 0; x
< width
; ++x
)
9048 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9050 for (y
= image_top
+ image_height
; y
< height
; ++y
)
9051 for (x
= 0; x
< width
; ++x
)
9052 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9054 for (y
= image_top
; y
< image_top
+ image_height
; ++y
)
9056 for (x
= 0; x
< image_left
; ++x
)
9057 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9058 for (x
= image_left
+ image_width
; x
< width
; ++x
)
9059 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
9062 /* Read the GIF image into the X image. We use a local variable
9063 `raster' here because RasterBits below is a char *, and invites
9064 problems with bytes >= 0x80. */
9065 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
9067 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
9069 static int interlace_start
[] = {0, 4, 2, 1};
9070 static int interlace_increment
[] = {8, 8, 4, 2};
9072 int row
= interlace_start
[0];
9076 for (y
= 0; y
< image_height
; y
++)
9078 if (row
>= image_height
)
9080 row
= interlace_start
[++pass
];
9081 while (row
>= image_height
)
9082 row
= interlace_start
[++pass
];
9085 for (x
= 0; x
< image_width
; x
++)
9087 int i
= raster
[(y
* image_width
) + x
];
9088 XPutPixel (ximg
, x
+ image_left
, row
+ image_top
,
9092 row
+= interlace_increment
[pass
];
9097 for (y
= 0; y
< image_height
; ++y
)
9098 for (x
= 0; x
< image_width
; ++x
)
9100 int i
= raster
[y
* image_width
+ x
];
9101 XPutPixel (ximg
, x
+ image_left
, y
+ image_top
, pixel_colors
[i
]);
9105 DGifCloseFile (gif
);
9107 /* Maybe fill in the background field while we have ximg handy. */
9108 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
9109 IMAGE_BACKGROUND (img
, f
, ximg
);
9111 /* Put the image into the pixmap, then free the X image and its buffer. */
9112 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
9113 x_destroy_x_image (ximg
);
9119 #endif /* HAVE_GIF != 0 */
9123 /***********************************************************************
9125 ***********************************************************************/
9127 static int gs_image_p
P_ ((Lisp_Object object
));
9128 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
9129 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
9131 /* The symbol `postscript' identifying images of this type. */
9133 Lisp_Object Qpostscript
;
9135 /* Keyword symbols. */
9137 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
9139 /* Indices of image specification fields in gs_format, below. */
9141 enum gs_keyword_index
9159 /* Vector of image_keyword structures describing the format
9160 of valid user-defined image specifications. */
9162 static struct image_keyword gs_format
[GS_LAST
] =
9164 {":type", IMAGE_SYMBOL_VALUE
, 1},
9165 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9166 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9167 {":file", IMAGE_STRING_VALUE
, 1},
9168 {":loader", IMAGE_FUNCTION_VALUE
, 0},
9169 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
9170 {":ascent", IMAGE_ASCENT_VALUE
, 0},
9171 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
9172 {":relief", IMAGE_INTEGER_VALUE
, 0},
9173 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9174 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9175 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9176 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
9179 /* Structure describing the image type `ghostscript'. */
9181 static struct image_type gs_type
=
9191 /* Free X resources of Ghostscript image IMG which is used on frame F. */
9194 gs_clear_image (f
, img
)
9198 /* IMG->data.ptr_val may contain a recorded colormap. */
9199 xfree (img
->data
.ptr_val
);
9200 x_clear_image (f
, img
);
9204 /* Return non-zero if OBJECT is a valid Ghostscript image
9211 struct image_keyword fmt
[GS_LAST
];
9215 bcopy (gs_format
, fmt
, sizeof fmt
);
9217 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
9220 /* Bounding box must be a list or vector containing 4 integers. */
9221 tem
= fmt
[GS_BOUNDING_BOX
].value
;
9224 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
9225 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
9230 else if (VECTORP (tem
))
9232 if (XVECTOR (tem
)->size
!= 4)
9234 for (i
= 0; i
< 4; ++i
)
9235 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
9245 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
9254 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
9255 struct gcpro gcpro1
, gcpro2
;
9257 double in_width
, in_height
;
9258 Lisp_Object pixel_colors
= Qnil
;
9260 /* Compute pixel size of pixmap needed from the given size in the
9261 image specification. Sizes in the specification are in pt. 1 pt
9262 = 1/72 in, xdpi and ydpi are stored in the frame's X display
9264 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
9265 in_width
= XFASTINT (pt_width
) / 72.0;
9266 img
->width
= in_width
* FRAME_X_DISPLAY_INFO (f
)->resx
;
9267 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
9268 in_height
= XFASTINT (pt_height
) / 72.0;
9269 img
->height
= in_height
* FRAME_X_DISPLAY_INFO (f
)->resy
;
9271 /* Create the pixmap. */
9272 xassert (img
->pixmap
== None
);
9273 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9274 img
->width
, img
->height
,
9275 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
9279 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
9283 /* Call the loader to fill the pixmap. It returns a process object
9284 if successful. We do not record_unwind_protect here because
9285 other places in redisplay like calling window scroll functions
9286 don't either. Let the Lisp loader use `unwind-protect' instead. */
9287 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
9289 sprintf (buffer
, "%lu %lu",
9290 (unsigned long) FRAME_X_WINDOW (f
),
9291 (unsigned long) img
->pixmap
);
9292 window_and_pixmap_id
= build_string (buffer
);
9294 sprintf (buffer
, "%lu %lu",
9295 FRAME_FOREGROUND_PIXEL (f
),
9296 FRAME_BACKGROUND_PIXEL (f
));
9297 pixel_colors
= build_string (buffer
);
9299 XSETFRAME (frame
, f
);
9300 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
9302 loader
= intern ("gs-load-image");
9304 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
9305 make_number (img
->width
),
9306 make_number (img
->height
),
9307 window_and_pixmap_id
,
9310 return PROCESSP (img
->data
.lisp_val
);
9314 /* Kill the Ghostscript process that was started to fill PIXMAP on
9315 frame F. Called from XTread_socket when receiving an event
9316 telling Emacs that Ghostscript has finished drawing. */
9319 x_kill_gs_process (pixmap
, f
)
9323 struct image_cache
*c
= FRAME_X_IMAGE_CACHE (f
);
9327 /* Find the image containing PIXMAP. */
9328 for (i
= 0; i
< c
->used
; ++i
)
9329 if (c
->images
[i
]->pixmap
== pixmap
)
9332 /* Should someone in between have cleared the image cache, for
9333 instance, give up. */
9337 /* Kill the GS process. We should have found PIXMAP in the image
9338 cache and its image should contain a process object. */
9340 xassert (PROCESSP (img
->data
.lisp_val
));
9341 Fkill_process (img
->data
.lisp_val
, Qnil
);
9342 img
->data
.lisp_val
= Qnil
;
9344 /* On displays with a mutable colormap, figure out the colors
9345 allocated for the image by looking at the pixels of an XImage for
9347 class = FRAME_X_VISUAL (f
)->class;
9348 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
9354 /* Try to get an XImage for img->pixmep. */
9355 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
9356 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
9361 /* Initialize the color table. */
9362 init_color_table ();
9364 /* For each pixel of the image, look its color up in the
9365 color table. After having done so, the color table will
9366 contain an entry for each color used by the image. */
9367 for (y
= 0; y
< img
->height
; ++y
)
9368 for (x
= 0; x
< img
->width
; ++x
)
9370 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
9371 lookup_pixel_color (f
, pixel
);
9374 /* Record colors in the image. Free color table and XImage. */
9375 img
->colors
= colors_in_color_table (&img
->ncolors
);
9376 free_color_table ();
9377 XDestroyImage (ximg
);
9379 #if 0 /* This doesn't seem to be the case. If we free the colors
9380 here, we get a BadAccess later in x_clear_image when
9381 freeing the colors. */
9382 /* We have allocated colors once, but Ghostscript has also
9383 allocated colors on behalf of us. So, to get the
9384 reference counts right, free them once. */
9386 x_free_colors (f
, img
->colors
, img
->ncolors
);
9390 image_error ("Cannot get X image of `%s'; colors will not be freed",
9396 /* Now that we have the pixmap, compute mask and transform the
9397 image if requested. */
9399 postprocess_image (f
, img
);
9405 /***********************************************************************
9407 ***********************************************************************/
9409 DEFUN ("x-change-window-property", Fx_change_window_property
,
9410 Sx_change_window_property
, 2, 3, 0,
9411 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
9412 PROP and VALUE must be strings. FRAME nil or omitted means use the
9413 selected frame. Value is VALUE. */)
9414 (prop
, value
, frame
)
9415 Lisp_Object frame
, prop
, value
;
9417 struct frame
*f
= check_x_frame (frame
);
9420 CHECK_STRING (prop
);
9421 CHECK_STRING (value
);
9424 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9425 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9426 prop_atom
, XA_STRING
, 8, PropModeReplace
,
9427 SDATA (value
), SCHARS (value
));
9429 /* Make sure the property is set when we return. */
9430 XFlush (FRAME_X_DISPLAY (f
));
9437 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
9438 Sx_delete_window_property
, 1, 2, 0,
9439 doc
: /* Remove window property PROP from X window of FRAME.
9440 FRAME nil or omitted means use the selected frame. Value is PROP. */)
9442 Lisp_Object prop
, frame
;
9444 struct frame
*f
= check_x_frame (frame
);
9447 CHECK_STRING (prop
);
9449 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9450 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
9452 /* Make sure the property is removed when we return. */
9453 XFlush (FRAME_X_DISPLAY (f
));
9460 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
9462 doc
: /* Value is the value of window property PROP on FRAME.
9463 If FRAME is nil or omitted, use the selected frame. Value is nil
9464 if FRAME hasn't a property with name PROP or if PROP has no string
9467 Lisp_Object prop
, frame
;
9469 struct frame
*f
= check_x_frame (frame
);
9472 Lisp_Object prop_value
= Qnil
;
9473 char *tmp_data
= NULL
;
9476 unsigned long actual_size
, bytes_remaining
;
9478 CHECK_STRING (prop
);
9480 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
9481 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9482 prop_atom
, 0, 0, False
, XA_STRING
,
9483 &actual_type
, &actual_format
, &actual_size
,
9484 &bytes_remaining
, (unsigned char **) &tmp_data
);
9487 int size
= bytes_remaining
;
9492 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9493 prop_atom
, 0, bytes_remaining
,
9495 &actual_type
, &actual_format
,
9496 &actual_size
, &bytes_remaining
,
9497 (unsigned char **) &tmp_data
);
9498 if (rc
== Success
&& tmp_data
)
9499 prop_value
= make_string (tmp_data
, size
);
9510 /***********************************************************************
9512 ***********************************************************************/
9514 /* If non-null, an asynchronous timer that, when it expires, displays
9515 an hourglass cursor on all frames. */
9517 static struct atimer
*hourglass_atimer
;
9519 /* Non-zero means an hourglass cursor is currently shown. */
9521 static int hourglass_shown_p
;
9523 /* Number of seconds to wait before displaying an hourglass cursor. */
9525 static Lisp_Object Vhourglass_delay
;
9527 /* Default number of seconds to wait before displaying an hourglass
9530 #define DEFAULT_HOURGLASS_DELAY 1
9532 /* Function prototypes. */
9534 static void show_hourglass
P_ ((struct atimer
*));
9535 static void hide_hourglass
P_ ((void));
9538 /* Cancel a currently active hourglass timer, and start a new one. */
9544 int secs
, usecs
= 0;
9546 cancel_hourglass ();
9548 if (INTEGERP (Vhourglass_delay
)
9549 && XINT (Vhourglass_delay
) > 0)
9550 secs
= XFASTINT (Vhourglass_delay
);
9551 else if (FLOATP (Vhourglass_delay
)
9552 && XFLOAT_DATA (Vhourglass_delay
) > 0)
9555 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
9556 secs
= XFASTINT (tem
);
9557 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
9560 secs
= DEFAULT_HOURGLASS_DELAY
;
9562 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
9563 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
9564 show_hourglass
, NULL
);
9568 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
9574 if (hourglass_atimer
)
9576 cancel_atimer (hourglass_atimer
);
9577 hourglass_atimer
= NULL
;
9580 if (hourglass_shown_p
)
9585 /* Timer function of hourglass_atimer. TIMER is equal to
9588 Display an hourglass pointer on all frames by mapping the frames'
9589 hourglass_window. Set the hourglass_p flag in the frames'
9590 output_data.x structure to indicate that an hourglass cursor is
9591 shown on the frames. */
9594 show_hourglass (timer
)
9595 struct atimer
*timer
;
9597 /* The timer implementation will cancel this timer automatically
9598 after this function has run. Set hourglass_atimer to null
9599 so that we know the timer doesn't have to be canceled. */
9600 hourglass_atimer
= NULL
;
9602 if (!hourglass_shown_p
)
9604 Lisp_Object rest
, frame
;
9608 FOR_EACH_FRAME (rest
, frame
)
9610 struct frame
*f
= XFRAME (frame
);
9612 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
) && FRAME_X_DISPLAY (f
))
9614 Display
*dpy
= FRAME_X_DISPLAY (f
);
9616 #ifdef USE_X_TOOLKIT
9617 if (f
->output_data
.x
->widget
)
9619 if (FRAME_OUTER_WINDOW (f
))
9622 f
->output_data
.x
->hourglass_p
= 1;
9624 if (!f
->output_data
.x
->hourglass_window
)
9626 unsigned long mask
= CWCursor
;
9627 XSetWindowAttributes attrs
;
9629 attrs
.cursor
= f
->output_data
.x
->hourglass_cursor
;
9631 f
->output_data
.x
->hourglass_window
9632 = XCreateWindow (dpy
, FRAME_OUTER_WINDOW (f
),
9633 0, 0, 32000, 32000, 0, 0,
9639 XMapRaised (dpy
, f
->output_data
.x
->hourglass_window
);
9645 hourglass_shown_p
= 1;
9651 /* Hide the hourglass pointer on all frames, if it is currently
9657 if (hourglass_shown_p
)
9659 Lisp_Object rest
, frame
;
9662 FOR_EACH_FRAME (rest
, frame
)
9664 struct frame
*f
= XFRAME (frame
);
9667 /* Watch out for newly created frames. */
9668 && f
->output_data
.x
->hourglass_window
)
9670 XUnmapWindow (FRAME_X_DISPLAY (f
),
9671 f
->output_data
.x
->hourglass_window
);
9672 /* Sync here because XTread_socket looks at the
9673 hourglass_p flag that is reset to zero below. */
9674 XSync (FRAME_X_DISPLAY (f
), False
);
9675 f
->output_data
.x
->hourglass_p
= 0;
9679 hourglass_shown_p
= 0;
9686 /***********************************************************************
9688 ***********************************************************************/
9690 static Lisp_Object x_create_tip_frame
P_ ((struct x_display_info
*,
9691 Lisp_Object
, Lisp_Object
));
9692 static void compute_tip_xy
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
9693 Lisp_Object
, int, int, int *, int *));
9695 /* The frame of a currently visible tooltip. */
9697 Lisp_Object tip_frame
;
9699 /* If non-nil, a timer started that hides the last tooltip when it
9702 Lisp_Object tip_timer
;
9705 /* If non-nil, a vector of 3 elements containing the last args
9706 with which x-show-tip was called. See there. */
9708 Lisp_Object last_show_tip_args
;
9710 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
9712 Lisp_Object Vx_max_tooltip_size
;
9716 unwind_create_tip_frame (frame
)
9719 Lisp_Object deleted
;
9721 deleted
= unwind_create_frame (frame
);
9722 if (EQ (deleted
, Qt
))
9732 /* Create a frame for a tooltip on the display described by DPYINFO.
9733 PARMS is a list of frame parameters. TEXT is the string to
9734 display in the tip frame. Value is the frame.
9736 Note that functions called here, esp. x_default_parameter can
9737 signal errors, for instance when a specified color name is
9738 undefined. We have to make sure that we're in a consistent state
9739 when this happens. */
9742 x_create_tip_frame (dpyinfo
, parms
, text
)
9743 struct x_display_info
*dpyinfo
;
9744 Lisp_Object parms
, text
;
9747 Lisp_Object frame
, tem
;
9749 long window_prompting
= 0;
9751 int count
= SPECPDL_INDEX ();
9752 struct gcpro gcpro1
, gcpro2
, gcpro3
;
9754 int face_change_count_before
= face_change_count
;
9756 struct buffer
*old_buffer
;
9760 /* Use this general default value to start with until we know if
9761 this frame has a specified name. */
9762 Vx_resource_name
= Vinvocation_name
;
9765 kb
= dpyinfo
->kboard
;
9767 kb
= &the_only_kboard
;
9770 /* Get the name of the frame to use for resource lookup. */
9771 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
9773 && !EQ (name
, Qunbound
)
9775 error ("Invalid frame name--not a string or nil");
9776 Vx_resource_name
= name
;
9779 GCPRO3 (parms
, name
, frame
);
9781 XSETFRAME (frame
, f
);
9783 buffer
= Fget_buffer_create (build_string (" *tip*"));
9784 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
9785 old_buffer
= current_buffer
;
9786 set_buffer_internal_1 (XBUFFER (buffer
));
9787 current_buffer
->truncate_lines
= Qnil
;
9790 set_buffer_internal_1 (old_buffer
);
9792 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
9793 record_unwind_protect (unwind_create_tip_frame
, frame
);
9795 /* By setting the output method, we're essentially saying that
9796 the frame is live, as per FRAME_LIVE_P. If we get a signal
9797 from this point on, x_destroy_window might screw up reference
9799 f
->output_method
= output_x_window
;
9800 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
9801 bzero (f
->output_data
.x
, sizeof (struct x_output
));
9802 f
->output_data
.x
->icon_bitmap
= -1;
9803 FRAME_FONTSET (f
) = -1;
9804 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
9805 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
9806 #ifdef USE_TOOLKIT_SCROLL_BARS
9807 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
9808 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
9809 #endif /* USE_TOOLKIT_SCROLL_BARS */
9810 f
->icon_name
= Qnil
;
9811 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
9813 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
9814 dpyinfo_refcount
= dpyinfo
->reference_count
;
9815 #endif /* GLYPH_DEBUG */
9817 FRAME_KBOARD (f
) = kb
;
9819 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
9820 f
->output_data
.x
->explicit_parent
= 0;
9822 /* These colors will be set anyway later, but it's important
9823 to get the color reference counts right, so initialize them! */
9826 struct gcpro gcpro1
;
9828 black
= build_string ("black");
9830 f
->output_data
.x
->foreground_pixel
9831 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9832 f
->output_data
.x
->background_pixel
9833 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9834 f
->output_data
.x
->cursor_pixel
9835 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9836 f
->output_data
.x
->cursor_foreground_pixel
9837 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9838 f
->output_data
.x
->border_pixel
9839 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9840 f
->output_data
.x
->mouse_pixel
9841 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
9845 /* Set the name; the functions to which we pass f expect the name to
9847 if (EQ (name
, Qunbound
) || NILP (name
))
9849 f
->name
= build_string (dpyinfo
->x_id_name
);
9850 f
->explicit_name
= 0;
9855 f
->explicit_name
= 1;
9856 /* use the frame's title when getting resources for this frame. */
9857 specbind (Qx_resource_name
, name
);
9860 /* Extract the window parameters from the supplied values that are
9861 needed to determine window geometry. */
9865 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
9868 /* First, try whatever font the caller has specified. */
9871 tem
= Fquery_fontset (font
, Qnil
);
9873 font
= x_new_fontset (f
, tem
);
9875 font
= x_new_font (f
, SDATA (font
));
9878 /* Try out a font which we hope has bold and italic variations. */
9879 if (!STRINGP (font
))
9880 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
9881 if (!STRINGP (font
))
9882 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9883 if (! STRINGP (font
))
9884 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
9885 if (! STRINGP (font
))
9886 /* This was formerly the first thing tried, but it finds too many fonts
9887 and takes too long. */
9888 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
9889 /* If those didn't work, look for something which will at least work. */
9890 if (! STRINGP (font
))
9891 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
9893 if (! STRINGP (font
))
9894 font
= build_string ("fixed");
9896 x_default_parameter (f
, parms
, Qfont
, font
,
9897 "font", "Font", RES_TYPE_STRING
);
9900 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
9901 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
9903 /* This defaults to 2 in order to match xterm. We recognize either
9904 internalBorderWidth or internalBorder (which is what xterm calls
9906 if (NILP (Fassq (Qinternal_border_width
, parms
)))
9910 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
9911 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
9912 if (! EQ (value
, Qunbound
))
9913 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
9917 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
9918 "internalBorderWidth", "internalBorderWidth",
9921 /* Also do the stuff which must be set before the window exists. */
9922 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
9923 "foreground", "Foreground", RES_TYPE_STRING
);
9924 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
9925 "background", "Background", RES_TYPE_STRING
);
9926 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
9927 "pointerColor", "Foreground", RES_TYPE_STRING
);
9928 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
9929 "cursorColor", "Foreground", RES_TYPE_STRING
);
9930 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
9931 "borderColor", "BorderColor", RES_TYPE_STRING
);
9933 /* Init faces before x_default_parameter is called for scroll-bar
9934 parameters because that function calls x_set_scroll_bar_width,
9935 which calls change_frame_size, which calls Fset_window_buffer,
9936 which runs hooks, which call Fvertical_motion. At the end, we
9937 end up in init_iterator with a null face cache, which should not
9939 init_frame_faces (f
);
9941 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
9943 window_prompting
= x_figure_window_size (f
, parms
, 0);
9946 XSetWindowAttributes attrs
;
9950 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
9951 if (DoesSaveUnders (dpyinfo
->screen
))
9952 mask
|= CWSaveUnder
;
9954 /* Window managers look at the override-redirect flag to determine
9955 whether or net to give windows a decoration (Xlib spec, chapter
9957 attrs
.override_redirect
= True
;
9958 attrs
.save_under
= True
;
9959 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
9960 /* Arrange for getting MapNotify and UnmapNotify events. */
9961 attrs
.event_mask
= StructureNotifyMask
;
9963 = FRAME_X_WINDOW (f
)
9964 = XCreateWindow (FRAME_X_DISPLAY (f
),
9965 FRAME_X_DISPLAY_INFO (f
)->root_window
,
9966 /* x, y, width, height */
9970 CopyFromParent
, InputOutput
, CopyFromParent
,
9977 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
9978 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9979 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
9980 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
9981 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
9982 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
9984 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
9985 Change will not be effected unless different from the current
9987 width
= FRAME_COLS (f
);
9988 height
= FRAME_LINES (f
);
9989 SET_FRAME_COLS (f
, 0);
9990 FRAME_LINES (f
) = 0;
9991 change_frame_size (f
, height
, width
, 1, 0, 0);
9993 /* Add `tooltip' frame parameter's default value. */
9994 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
9995 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
9998 /* Set up faces after all frame parameters are known. This call
9999 also merges in face attributes specified for new frames.
10001 Frame parameters may be changed if .Xdefaults contains
10002 specifications for the default font. For example, if there is an
10003 `Emacs.default.attributeBackground: pink', the `background-color'
10004 attribute of the frame get's set, which let's the internal border
10005 of the tooltip frame appear in pink. Prevent this. */
10007 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
10009 /* Set tip_frame here, so that */
10011 call1 (Qface_set_after_frame_default
, frame
);
10013 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
10014 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qbackground_color
, bg
),
10022 /* It is now ok to make the frame official even if we get an error
10023 below. And the frame needs to be on Vframe_list or making it
10024 visible won't work. */
10025 Vframe_list
= Fcons (frame
, Vframe_list
);
10027 /* Now that the frame is official, it counts as a reference to
10029 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
10031 /* Setting attributes of faces of the tooltip frame from resources
10032 and similar will increment face_change_count, which leads to the
10033 clearing of all current matrices. Since this isn't necessary
10034 here, avoid it by resetting face_change_count to the value it
10035 had before we created the tip frame. */
10036 face_change_count
= face_change_count_before
;
10038 /* Discard the unwind_protect. */
10039 return unbind_to (count
, frame
);
10043 /* Compute where to display tip frame F. PARMS is the list of frame
10044 parameters for F. DX and DY are specified offsets from the current
10045 location of the mouse. WIDTH and HEIGHT are the width and height
10046 of the tooltip. Return coordinates relative to the root window of
10047 the display in *ROOT_X, and *ROOT_Y. */
10050 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, root_x
, root_y
)
10052 Lisp_Object parms
, dx
, dy
;
10054 int *root_x
, *root_y
;
10056 Lisp_Object left
, top
;
10058 Window root
, child
;
10061 /* User-specified position? */
10062 left
= Fcdr (Fassq (Qleft
, parms
));
10063 top
= Fcdr (Fassq (Qtop
, parms
));
10065 /* Move the tooltip window where the mouse pointer is. Resize and
10067 if (!INTEGERP (left
) || !INTEGERP (top
))
10070 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
10071 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
10075 if (INTEGERP (top
))
10076 *root_y
= XINT (top
);
10077 else if (*root_y
+ XINT (dy
) - height
< 0)
10078 *root_y
-= XINT (dy
);
10082 *root_y
+= XINT (dy
);
10085 if (INTEGERP (left
))
10086 *root_x
= XINT (left
);
10087 else if (*root_x
+ XINT (dx
) + width
<= FRAME_X_DISPLAY_INFO (f
)->width
)
10088 /* It fits to the right of the pointer. */
10089 *root_x
+= XINT (dx
);
10090 else if (width
+ XINT (dx
) <= *root_x
)
10091 /* It fits to the left of the pointer. */
10092 *root_x
-= width
+ XINT (dx
);
10094 /* Put it left-justified on the screen--it ought to fit that way. */
10099 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
10100 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
10101 A tooltip window is a small X window displaying a string.
10103 FRAME nil or omitted means use the selected frame.
10105 PARMS is an optional list of frame parameters which can be used to
10106 change the tooltip's appearance.
10108 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
10109 means use the default timeout of 5 seconds.
10111 If the list of frame parameters PARAMS contains a `left' parameters,
10112 the tooltip is displayed at that x-position. Otherwise it is
10113 displayed at the mouse position, with offset DX added (default is 5 if
10114 DX isn't specified). Likewise for the y-position; if a `top' frame
10115 parameter is specified, it determines the y-position of the tooltip
10116 window, otherwise it is displayed at the mouse position, with offset
10117 DY added (default is -10).
10119 A tooltip's maximum size is specified by `x-max-tooltip-size'.
10120 Text larger than the specified size is clipped. */)
10121 (string
, frame
, parms
, timeout
, dx
, dy
)
10122 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
10126 int root_x
, root_y
;
10127 struct buffer
*old_buffer
;
10128 struct text_pos pos
;
10129 int i
, width
, height
;
10130 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
10131 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
10132 int count
= SPECPDL_INDEX ();
10134 specbind (Qinhibit_redisplay
, Qt
);
10136 GCPRO4 (string
, parms
, frame
, timeout
);
10138 CHECK_STRING (string
);
10139 f
= check_x_frame (frame
);
10140 if (NILP (timeout
))
10141 timeout
= make_number (5);
10143 CHECK_NATNUM (timeout
);
10146 dx
= make_number (5);
10151 dy
= make_number (-10);
10155 if (NILP (last_show_tip_args
))
10156 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
10158 if (!NILP (tip_frame
))
10160 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
10161 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
10162 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
10164 if (EQ (frame
, last_frame
)
10165 && !NILP (Fequal (last_string
, string
))
10166 && !NILP (Fequal (last_parms
, parms
)))
10168 struct frame
*f
= XFRAME (tip_frame
);
10170 /* Only DX and DY have changed. */
10171 if (!NILP (tip_timer
))
10173 Lisp_Object timer
= tip_timer
;
10175 call1 (Qcancel_timer
, timer
);
10179 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
10180 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
10181 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10188 /* Hide a previous tip, if any. */
10191 ASET (last_show_tip_args
, 0, string
);
10192 ASET (last_show_tip_args
, 1, frame
);
10193 ASET (last_show_tip_args
, 2, parms
);
10195 /* Add default values to frame parameters. */
10196 if (NILP (Fassq (Qname
, parms
)))
10197 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
10198 if (NILP (Fassq (Qinternal_border_width
, parms
)))
10199 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
10200 if (NILP (Fassq (Qborder_width
, parms
)))
10201 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
10202 if (NILP (Fassq (Qborder_color
, parms
)))
10203 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
10204 if (NILP (Fassq (Qbackground_color
, parms
)))
10205 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
10208 /* Create a frame for the tooltip, and record it in the global
10209 variable tip_frame. */
10210 frame
= x_create_tip_frame (FRAME_X_DISPLAY_INFO (f
), parms
, string
);
10211 f
= XFRAME (frame
);
10213 /* Set up the frame's root window. */
10214 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
10215 w
->left_col
= w
->top_line
= make_number (0);
10217 if (CONSP (Vx_max_tooltip_size
)
10218 && INTEGERP (XCAR (Vx_max_tooltip_size
))
10219 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
10220 && INTEGERP (XCDR (Vx_max_tooltip_size
))
10221 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
10223 w
->total_cols
= XCAR (Vx_max_tooltip_size
);
10224 w
->total_lines
= XCDR (Vx_max_tooltip_size
);
10228 w
->total_cols
= make_number (80);
10229 w
->total_lines
= make_number (40);
10232 FRAME_TOTAL_COLS (f
) = XINT (w
->total_cols
);
10234 w
->pseudo_window_p
= 1;
10236 /* Display the tooltip text in a temporary buffer. */
10237 old_buffer
= current_buffer
;
10238 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->buffer
));
10239 current_buffer
->truncate_lines
= Qnil
;
10240 clear_glyph_matrix (w
->desired_matrix
);
10241 clear_glyph_matrix (w
->current_matrix
);
10242 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
10243 try_window (FRAME_ROOT_WINDOW (f
), pos
);
10245 /* Compute width and height of the tooltip. */
10246 width
= height
= 0;
10247 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
10249 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
10250 struct glyph
*last
;
10253 /* Stop at the first empty row at the end. */
10254 if (!row
->enabled_p
|| !row
->displays_text_p
)
10257 /* Let the row go over the full width of the frame. */
10258 row
->full_width_p
= 1;
10260 /* There's a glyph at the end of rows that is used to place
10261 the cursor there. Don't include the width of this glyph. */
10262 if (row
->used
[TEXT_AREA
])
10264 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
10265 row_width
= row
->pixel_width
- last
->pixel_width
;
10268 row_width
= row
->pixel_width
;
10270 height
+= row
->height
;
10271 width
= max (width
, row_width
);
10274 /* Add the frame's internal border to the width and height the X
10275 window should have. */
10276 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10277 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
10279 /* Move the tooltip window where the mouse pointer is. Resize and
10281 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
10284 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10285 root_x
, root_y
, width
, height
);
10286 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
10289 /* Draw into the window. */
10290 w
->must_be_updated_p
= 1;
10291 update_single_window (w
, 1);
10293 /* Restore original current buffer. */
10294 set_buffer_internal_1 (old_buffer
);
10295 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
10298 /* Let the tip disappear after timeout seconds. */
10299 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
10300 intern ("x-hide-tip"));
10303 return unbind_to (count
, Qnil
);
10307 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
10308 doc
: /* Hide the current tooltip window, if there is any.
10309 Value is t if tooltip was open, nil otherwise. */)
10313 Lisp_Object deleted
, frame
, timer
;
10314 struct gcpro gcpro1
, gcpro2
;
10316 /* Return quickly if nothing to do. */
10317 if (NILP (tip_timer
) && NILP (tip_frame
))
10322 GCPRO2 (frame
, timer
);
10323 tip_frame
= tip_timer
= deleted
= Qnil
;
10325 count
= SPECPDL_INDEX ();
10326 specbind (Qinhibit_redisplay
, Qt
);
10327 specbind (Qinhibit_quit
, Qt
);
10330 call1 (Qcancel_timer
, timer
);
10332 if (FRAMEP (frame
))
10334 Fdelete_frame (frame
, Qnil
);
10338 /* Bloodcurdling hack alert: The Lucid menu bar widget's
10339 redisplay procedure is not called when a tip frame over menu
10340 items is unmapped. Redisplay the menu manually... */
10342 struct frame
*f
= SELECTED_FRAME ();
10343 Widget w
= f
->output_data
.x
->menubar_widget
;
10344 extern void xlwmenu_redisplay
P_ ((Widget
));
10346 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f
)->screen
)
10350 xlwmenu_redisplay (w
);
10354 #endif /* USE_LUCID */
10358 return unbind_to (count
, deleted
);
10363 /***********************************************************************
10364 File selection dialog
10365 ***********************************************************************/
10369 /* Callback for "OK" and "Cancel" on file selection dialog. */
10372 file_dialog_cb (widget
, client_data
, call_data
)
10374 XtPointer call_data
, client_data
;
10376 int *result
= (int *) client_data
;
10377 XmAnyCallbackStruct
*cb
= (XmAnyCallbackStruct
*) call_data
;
10378 *result
= cb
->reason
;
10382 /* Callback for unmapping a file selection dialog. This is used to
10383 capture the case where a dialog is closed via a window manager's
10384 closer button, for example. Using a XmNdestroyCallback didn't work
10388 file_dialog_unmap_cb (widget
, client_data
, call_data
)
10390 XtPointer call_data
, client_data
;
10392 int *result
= (int *) client_data
;
10393 *result
= XmCR_CANCEL
;
10397 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10398 doc
: /* Read file name, prompting with PROMPT in directory DIR.
10399 Use a file selection dialog.
10400 Select DEFAULT-FILENAME in the dialog's file selection box, if
10401 specified. Don't let the user enter a file name in the file
10402 selection dialog's entry field, if MUSTMATCH is non-nil. */)
10403 (prompt
, dir
, default_filename
, mustmatch
)
10404 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10407 struct frame
*f
= SELECTED_FRAME ();
10408 Lisp_Object file
= Qnil
;
10409 Widget dialog
, text
, list
, help
;
10412 extern XtAppContext Xt_app_con
;
10413 XmString dir_xmstring
, pattern_xmstring
;
10414 int count
= SPECPDL_INDEX ();
10415 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10417 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10418 CHECK_STRING (prompt
);
10419 CHECK_STRING (dir
);
10421 /* Prevent redisplay. */
10422 specbind (Qinhibit_redisplay
, Qt
);
10426 /* Create the dialog with PROMPT as title, using DIR as initial
10427 directory and using "*" as pattern. */
10428 dir
= Fexpand_file_name (dir
, Qnil
);
10429 dir_xmstring
= XmStringCreateLocalized (SDATA (dir
));
10430 pattern_xmstring
= XmStringCreateLocalized ("*");
10432 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
10433 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
10434 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
10435 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
10436 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
10437 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
10439 XmStringFree (dir_xmstring
);
10440 XmStringFree (pattern_xmstring
);
10442 /* Add callbacks for OK and Cancel. */
10443 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
10444 (XtPointer
) &result
);
10445 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
10446 (XtPointer
) &result
);
10447 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
10448 (XtPointer
) &result
);
10450 /* Disable the help button since we can't display help. */
10451 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
10452 XtSetSensitive (help
, False
);
10454 /* Mark OK button as default. */
10455 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
10456 XmNshowAsDefault
, True
, NULL
);
10458 /* If MUSTMATCH is non-nil, disable the file entry field of the
10459 dialog, so that the user must select a file from the files list
10460 box. We can't remove it because we wouldn't have a way to get at
10461 the result file name, then. */
10462 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
10463 if (!NILP (mustmatch
))
10466 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
10467 XtSetSensitive (text
, False
);
10468 XtSetSensitive (label
, False
);
10471 /* Manage the dialog, so that list boxes get filled. */
10472 XtManageChild (dialog
);
10474 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
10475 must include the path for this to work. */
10476 list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
10477 if (STRINGP (default_filename
))
10479 XmString default_xmstring
;
10483 = XmStringCreateLocalized (SDATA (default_filename
));
10485 if (!XmListItemExists (list
, default_xmstring
))
10487 /* Add a new item if DEFAULT_FILENAME is not in the list. */
10488 XmListAddItem (list
, default_xmstring
, 0);
10492 item_pos
= XmListItemPos (list
, default_xmstring
);
10493 XmStringFree (default_xmstring
);
10495 /* Select the item and scroll it into view. */
10496 XmListSelectPos (list
, item_pos
, True
);
10497 XmListSetPos (list
, item_pos
);
10500 /* Process events until the user presses Cancel or OK. */
10502 while (result
== 0)
10505 XtAppNextEvent (Xt_app_con
, &event
);
10506 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
) );
10509 /* Get the result. */
10510 if (result
== XmCR_OK
)
10515 XtVaGetValues (dialog
, XmNtextString
, &text
, NULL
);
10516 XmStringGetLtoR (text
, XmFONTLIST_DEFAULT_TAG
, &data
);
10517 XmStringFree (text
);
10518 file
= build_string (data
);
10525 XtUnmanageChild (dialog
);
10526 XtDestroyWidget (dialog
);
10530 /* Make "Cancel" equivalent to C-g. */
10532 Fsignal (Qquit
, Qnil
);
10534 return unbind_to (count
, file
);
10537 #endif /* USE_MOTIF */
10541 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 4, 0,
10542 "Read file name, prompting with PROMPT in directory DIR.\n\
10543 Use a file selection dialog.\n\
10544 Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
10545 specified. Don't let the user enter a file name in the file\n\
10546 selection dialog's entry field, if MUSTMATCH is non-nil.")
10547 (prompt
, dir
, default_filename
, mustmatch
)
10548 Lisp_Object prompt
, dir
, default_filename
, mustmatch
;
10550 FRAME_PTR f
= SELECTED_FRAME ();
10552 Lisp_Object file
= Qnil
;
10553 int count
= specpdl_ptr
- specpdl
;
10554 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
10558 GCPRO5 (prompt
, dir
, default_filename
, mustmatch
, file
);
10559 CHECK_STRING (prompt
);
10560 CHECK_STRING (dir
);
10562 /* Prevent redisplay. */
10563 specbind (Qinhibit_redisplay
, Qt
);
10567 if (STRINGP (default_filename
))
10568 cdef_file
= SDATA (default_filename
);
10570 cdef_file
= SDATA (dir
);
10572 fn
= xg_get_file_name (f
, SDATA (prompt
), cdef_file
, ! NILP (mustmatch
));
10576 file
= build_string (fn
);
10583 /* Make "Cancel" equivalent to C-g. */
10585 Fsignal (Qquit
, Qnil
);
10587 return unbind_to (count
, file
);
10590 #endif /* USE_GTK */
10593 /***********************************************************************
10595 ***********************************************************************/
10597 #ifdef HAVE_XKBGETKEYBOARD
10598 #include <X11/XKBlib.h>
10599 #include <X11/keysym.h>
10602 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
10603 Sx_backspace_delete_keys_p
, 0, 1, 0,
10604 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
10605 FRAME nil means use the selected frame.
10606 Value is t if we know that both keys are present, and are mapped to the
10607 usual X keysyms. */)
10611 #ifdef HAVE_XKBGETKEYBOARD
10613 struct frame
*f
= check_x_frame (frame
);
10614 Display
*dpy
= FRAME_X_DISPLAY (f
);
10615 Lisp_Object have_keys
;
10616 int major
, minor
, op
, event
, error
;
10620 /* Check library version in case we're dynamically linked. */
10621 major
= XkbMajorVersion
;
10622 minor
= XkbMinorVersion
;
10623 if (!XkbLibraryVersion (&major
, &minor
))
10629 /* Check that the server supports XKB. */
10630 major
= XkbMajorVersion
;
10631 minor
= XkbMinorVersion
;
10632 if (!XkbQueryExtension (dpy
, &op
, &event
, &error
, &major
, &minor
))
10639 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
10642 int delete_keycode
= 0, backspace_keycode
= 0, i
;
10644 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
10646 for (i
= kb
->min_key_code
;
10647 (i
< kb
->max_key_code
10648 && (delete_keycode
== 0 || backspace_keycode
== 0));
10651 /* The XKB symbolic key names can be seen most easily in
10652 the PS file generated by `xkbprint -label name
10654 if (bcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
10655 delete_keycode
= i
;
10656 else if (bcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
10657 backspace_keycode
= i
;
10660 XkbFreeNames (kb
, 0, True
);
10663 XkbFreeClientMap (kb
, 0, True
);
10666 && backspace_keycode
10667 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
10668 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
10673 #else /* not HAVE_XKBGETKEYBOARD */
10675 #endif /* not HAVE_XKBGETKEYBOARD */
10680 /***********************************************************************
10682 ***********************************************************************/
10684 /* Keep this list in the same order as frame_parms in frame.c.
10685 Use 0 for unsupported frame parameters. */
10687 frame_parm_handler x_frame_parm_handlers
[] =
10691 x_set_background_color
,
10692 x_set_border_color
,
10693 x_set_border_width
,
10694 x_set_cursor_color
,
10697 x_set_foreground_color
,
10700 x_set_internal_border_width
,
10701 x_set_menu_bar_lines
,
10703 x_explicitly_set_name
,
10704 x_set_scroll_bar_width
,
10706 x_set_unsplittable
,
10707 x_set_vertical_scroll_bars
,
10709 x_set_tool_bar_lines
,
10710 x_set_scroll_bar_foreground
,
10711 x_set_scroll_bar_background
,
10712 x_set_screen_gamma
,
10713 x_set_line_spacing
,
10714 x_set_fringe_width
,
10715 x_set_fringe_width
,
10723 /* This is zero if not using X windows. */
10726 /* The section below is built by the lisp expression at the top of the file,
10727 just above where these variables are declared. */
10728 /*&&& init symbols here &&&*/
10729 Qnone
= intern ("none");
10730 staticpro (&Qnone
);
10731 Qsuppress_icon
= intern ("suppress-icon");
10732 staticpro (&Qsuppress_icon
);
10733 Qundefined_color
= intern ("undefined-color");
10734 staticpro (&Qundefined_color
);
10735 Qcenter
= intern ("center");
10736 staticpro (&Qcenter
);
10737 Qcompound_text
= intern ("compound-text");
10738 staticpro (&Qcompound_text
);
10739 Qcancel_timer
= intern ("cancel-timer");
10740 staticpro (&Qcancel_timer
);
10741 /* This is the end of symbol initialization. */
10743 /* Text property `display' should be nonsticky by default. */
10744 Vtext_property_default_nonsticky
10745 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
10748 Qlaplace
= intern ("laplace");
10749 staticpro (&Qlaplace
);
10750 Qemboss
= intern ("emboss");
10751 staticpro (&Qemboss
);
10752 Qedge_detection
= intern ("edge-detection");
10753 staticpro (&Qedge_detection
);
10754 Qheuristic
= intern ("heuristic");
10755 staticpro (&Qheuristic
);
10756 QCmatrix
= intern (":matrix");
10757 staticpro (&QCmatrix
);
10758 QCcolor_adjustment
= intern (":color-adjustment");
10759 staticpro (&QCcolor_adjustment
);
10760 QCmask
= intern (":mask");
10761 staticpro (&QCmask
);
10763 Fput (Qundefined_color
, Qerror_conditions
,
10764 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
10765 Fput (Qundefined_color
, Qerror_message
,
10766 build_string ("Undefined color"));
10768 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images
,
10769 doc
: /* Non-nil means always draw a cross over disabled images.
10770 Disabled images are those having an `:conversion disabled' property.
10771 A cross is always drawn on black & white displays. */);
10772 cross_disabled_images
= 0;
10774 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
10775 doc
: /* List of directories to search for window system bitmap files. */);
10776 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
10778 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
10779 doc
: /* The shape of the pointer when over text.
10780 Changing the value does not affect existing frames
10781 unless you set the mouse color. */);
10782 Vx_pointer_shape
= Qnil
;
10784 #if 0 /* This doesn't really do anything. */
10785 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
10786 doc
: /* The shape of the pointer when not over text.
10787 This variable takes effect when you create a new frame
10788 or when you set the mouse color. */);
10790 Vx_nontext_pointer_shape
= Qnil
;
10792 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
10793 doc
: /* The shape of the pointer when Emacs is busy.
10794 This variable takes effect when you create a new frame
10795 or when you set the mouse color. */);
10796 Vx_hourglass_pointer_shape
= Qnil
;
10798 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
10799 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
10800 display_hourglass_p
= 1;
10802 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
10803 doc
: /* *Seconds to wait before displaying an hourglass pointer.
10804 Value must be an integer or float. */);
10805 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
10807 #if 0 /* This doesn't really do anything. */
10808 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
10809 doc
: /* The shape of the pointer when over the mode line.
10810 This variable takes effect when you create a new frame
10811 or when you set the mouse color. */);
10813 Vx_mode_pointer_shape
= Qnil
;
10815 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
10816 &Vx_sensitive_text_pointer_shape
,
10817 doc
: /* The shape of the pointer when over mouse-sensitive text.
10818 This variable takes effect when you create a new frame
10819 or when you set the mouse color. */);
10820 Vx_sensitive_text_pointer_shape
= Qnil
;
10822 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
10823 &Vx_window_horizontal_drag_shape
,
10824 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
10825 This variable takes effect when you create a new frame
10826 or when you set the mouse color. */);
10827 Vx_window_horizontal_drag_shape
= Qnil
;
10829 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
10830 doc
: /* A string indicating the foreground color of the cursor box. */);
10831 Vx_cursor_fore_pixel
= Qnil
;
10833 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size
,
10834 doc
: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
10835 Text larger than this is clipped. */);
10836 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
10838 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
10839 doc
: /* Non-nil if no X window manager is in use.
10840 Emacs doesn't try to figure this out; this is always nil
10841 unless you set it to something else. */);
10842 /* We don't have any way to find this out, so set it to nil
10843 and maybe the user would like to set it to t. */
10844 Vx_no_window_manager
= Qnil
;
10846 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
10847 &Vx_pixel_size_width_font_regexp
,
10848 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
10850 Since Emacs gets width of a font matching with this regexp from
10851 PIXEL_SIZE field of the name, font finding mechanism gets faster for
10852 such a font. This is especially effective for such large fonts as
10853 Chinese, Japanese, and Korean. */);
10854 Vx_pixel_size_width_font_regexp
= Qnil
;
10856 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
10857 doc
: /* Time after which cached images are removed from the cache.
10858 When an image has not been displayed this many seconds, remove it
10859 from the image cache. Value must be an integer or nil with nil
10860 meaning don't clear the cache. */);
10861 Vimage_cache_eviction_delay
= make_number (30 * 60);
10863 #ifdef USE_X_TOOLKIT
10864 Fprovide (intern ("x-toolkit"), Qnil
);
10866 Fprovide (intern ("motif"), Qnil
);
10868 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
,
10869 doc
: /* Version info for LessTif/Motif. */);
10870 Vmotif_version_string
= build_string (XmVERSION_STRING
);
10871 #endif /* USE_MOTIF */
10872 #endif /* USE_X_TOOLKIT */
10874 /* X window properties. */
10875 defsubr (&Sx_change_window_property
);
10876 defsubr (&Sx_delete_window_property
);
10877 defsubr (&Sx_window_property
);
10879 defsubr (&Sxw_display_color_p
);
10880 defsubr (&Sx_display_grayscale_p
);
10881 defsubr (&Sxw_color_defined_p
);
10882 defsubr (&Sxw_color_values
);
10883 defsubr (&Sx_server_max_request_size
);
10884 defsubr (&Sx_server_vendor
);
10885 defsubr (&Sx_server_version
);
10886 defsubr (&Sx_display_pixel_width
);
10887 defsubr (&Sx_display_pixel_height
);
10888 defsubr (&Sx_display_mm_width
);
10889 defsubr (&Sx_display_mm_height
);
10890 defsubr (&Sx_display_screens
);
10891 defsubr (&Sx_display_planes
);
10892 defsubr (&Sx_display_color_cells
);
10893 defsubr (&Sx_display_visual_class
);
10894 defsubr (&Sx_display_backing_store
);
10895 defsubr (&Sx_display_save_under
);
10896 defsubr (&Sx_create_frame
);
10897 defsubr (&Sx_open_connection
);
10898 defsubr (&Sx_close_connection
);
10899 defsubr (&Sx_display_list
);
10900 defsubr (&Sx_synchronize
);
10901 defsubr (&Sx_focus_frame
);
10902 defsubr (&Sx_backspace_delete_keys_p
);
10904 /* Setting callback functions for fontset handler. */
10905 get_font_info_func
= x_get_font_info
;
10907 #if 0 /* This function pointer doesn't seem to be used anywhere.
10908 And the pointer assigned has the wrong type, anyway. */
10909 list_fonts_func
= x_list_fonts
;
10912 load_font_func
= x_load_font
;
10913 find_ccl_program_func
= x_find_ccl_program
;
10914 query_font_func
= x_query_font
;
10915 set_frame_fontset_func
= x_set_font
;
10916 get_font_repertory_func
= x_get_font_repertory
;
10917 check_window_system_func
= check_x
;
10920 Qxbm
= intern ("xbm");
10922 QCconversion
= intern (":conversion");
10923 staticpro (&QCconversion
);
10924 QCheuristic_mask
= intern (":heuristic-mask");
10925 staticpro (&QCheuristic_mask
);
10926 QCcolor_symbols
= intern (":color-symbols");
10927 staticpro (&QCcolor_symbols
);
10928 QCascent
= intern (":ascent");
10929 staticpro (&QCascent
);
10930 QCmargin
= intern (":margin");
10931 staticpro (&QCmargin
);
10932 QCrelief
= intern (":relief");
10933 staticpro (&QCrelief
);
10934 Qpostscript
= intern ("postscript");
10935 staticpro (&Qpostscript
);
10936 QCloader
= intern (":loader");
10937 staticpro (&QCloader
);
10938 QCbounding_box
= intern (":bounding-box");
10939 staticpro (&QCbounding_box
);
10940 QCpt_width
= intern (":pt-width");
10941 staticpro (&QCpt_width
);
10942 QCpt_height
= intern (":pt-height");
10943 staticpro (&QCpt_height
);
10944 QCindex
= intern (":index");
10945 staticpro (&QCindex
);
10946 Qpbm
= intern ("pbm");
10950 Qxpm
= intern ("xpm");
10955 Qjpeg
= intern ("jpeg");
10956 staticpro (&Qjpeg
);
10960 Qtiff
= intern ("tiff");
10961 staticpro (&Qtiff
);
10965 Qgif
= intern ("gif");
10970 Qpng
= intern ("png");
10974 defsubr (&Sclear_image_cache
);
10975 defsubr (&Simage_size
);
10976 defsubr (&Simage_mask_p
);
10978 hourglass_atimer
= NULL
;
10979 hourglass_shown_p
= 0;
10981 defsubr (&Sx_show_tip
);
10982 defsubr (&Sx_hide_tip
);
10984 staticpro (&tip_timer
);
10986 staticpro (&tip_frame
);
10988 last_show_tip_args
= Qnil
;
10989 staticpro (&last_show_tip_args
);
10992 defsubr (&Sx_file_dialog
);
11000 image_types
= NULL
;
11001 Vimage_types
= Qnil
;
11003 define_image_type (&xbm_type
);
11004 define_image_type (&gs_type
);
11005 define_image_type (&pbm_type
);
11008 define_image_type (&xpm_type
);
11012 define_image_type (&jpeg_type
);
11016 define_image_type (&tiff_type
);
11020 define_image_type (&gif_type
);
11024 define_image_type (&png_type
);
11028 #endif /* HAVE_X_WINDOWS */